xinerama support like crazy for struts and everything else too. this probably crashes but its been way too long without a commit.
This commit is contained in:
parent
97d4f66cd8
commit
eb6a2e9c4b
13 changed files with 278 additions and 161 deletions
|
@ -1430,7 +1430,7 @@ void action_move_to_center(union ActionData *data)
|
|||
{
|
||||
ObClient *c = data->client.any.c;
|
||||
Rect *area;
|
||||
area = screen_area_monitor(c->desktop, 0, NULL);
|
||||
area = screen_area(c->desktop, client_monitor(c), NULL);
|
||||
client_action_start(data);
|
||||
client_move(c, area->width / 2 - c->area.width / 2,
|
||||
area->height / 2 - c->area.height / 2);
|
||||
|
@ -1898,7 +1898,7 @@ void action_growtoedge(union ActionData *data)
|
|||
ObClient *c = data->diraction.any.c;
|
||||
Rect *a;
|
||||
|
||||
a = screen_area(c->desktop, NULL);
|
||||
a = screen_area(c->desktop, SCREEN_AREA_ALL_MONITORS, &c->frame->area);
|
||||
x = c->frame->area.x;
|
||||
y = c->frame->area.y;
|
||||
/* get the unshaded frame's dimensions..if it is shaded */
|
||||
|
|
117
openbox/client.c
117
openbox/client.c
|
@ -403,8 +403,7 @@ void client_manage(Window window)
|
|||
RECT_SET(placer, placex, placey, placew, placeh);
|
||||
frame_rect_to_frame(self->frame, &placer);
|
||||
|
||||
Rect *a = screen_area_monitor(self->desktop, client_monitor(self),
|
||||
&placer);
|
||||
Rect *a = screen_area(self->desktop, SCREEN_AREA_ONE_MONITOR, &placer);
|
||||
|
||||
/* shrink by the frame's area */
|
||||
a->width -= self->frame->size.left + self->frame->size.right;
|
||||
|
@ -923,19 +922,15 @@ void client_move_onscreen(ObClient *self, gboolean rude)
|
|||
gboolean client_find_onscreen(ObClient *self, gint *x, gint *y, gint w, gint h,
|
||||
gboolean rude)
|
||||
{
|
||||
Rect *mon_a, *all_a;
|
||||
gint ox = *x, oy = *y;
|
||||
gboolean rudel = rude, ruder = rude, rudet = rude, rudeb = rude;
|
||||
gint fw, fh;
|
||||
Rect desired;
|
||||
guint i;
|
||||
|
||||
RECT_SET(desired, *x, *y, w, h);
|
||||
frame_rect_to_frame(self->frame, &desired);
|
||||
|
||||
all_a = screen_area(self->desktop, &desired);
|
||||
mon_a = screen_area_monitor(self->desktop, screen_find_monitor(&desired),
|
||||
&desired);
|
||||
|
||||
/* get where the frame would be */
|
||||
frame_client_gravity(self->frame, x, y, w, h);
|
||||
|
||||
|
@ -943,30 +938,8 @@ gboolean client_find_onscreen(ObClient *self, gint *x, gint *y, gint w, gint h,
|
|||
fw = self->frame->size.left + w + self->frame->size.right;
|
||||
fh = self->frame->size.top + h + self->frame->size.bottom;
|
||||
|
||||
/* This makes sure windows aren't entirely outside of the screen so you
|
||||
can't see them at all.
|
||||
It makes sure 10% of the window is on the screen at least. At don't let
|
||||
it move itself off the top of the screen, which would hide the titlebar
|
||||
on you. (The user can still do this if they want too, it's only limiting
|
||||
the application.
|
||||
|
||||
XXX watch for xinerama dead areas...
|
||||
*/
|
||||
if (client_normal(self)) {
|
||||
if (!self->strut.right && *x + fw/10 >= all_a->x + all_a->width - 1)
|
||||
*x = all_a->x + all_a->width - fw/10;
|
||||
if (!self->strut.bottom && *y + fh/10 >= all_a->y + all_a->height - 1)
|
||||
*y = all_a->y + all_a->height - fh/10;
|
||||
if (!self->strut.left && *x + fw*9/10 - 1 < all_a->x)
|
||||
*x = all_a->x - fw*9/10;
|
||||
if (!self->strut.top && *y + fh*9/10 - 1 < all_a->y)
|
||||
*y = all_a->y - fw*9/10;
|
||||
}
|
||||
|
||||
/* If rudeness wasn't requested, then figure out of the client is currently
|
||||
entirely on the screen. If it is, and the position isn't changing by
|
||||
request, and it is enlarging, then be rude even though it wasn't
|
||||
requested */
|
||||
/* If rudeness wasn't requested, then still be rude in a given direction
|
||||
if the client is not moving, only resizing in that direction */
|
||||
if (!rude) {
|
||||
Point oldtl, oldtr, oldbl, oldbr;
|
||||
Point newtl, newtr, newbl, newbr;
|
||||
|
@ -1003,26 +976,52 @@ gboolean client_find_onscreen(ObClient *self, gint *x, gint *y, gint w, gint h,
|
|||
rudeb = TRUE;
|
||||
}
|
||||
|
||||
/* This here doesn't let windows even a pixel outside the struts/screen.
|
||||
* When called from client_manage, programs placing themselves are
|
||||
* forced completely onscreen, while things like
|
||||
* xterm -geometry resolution-width/2 will work fine. Trying to
|
||||
* place it completely offscreen will be handled in the above code.
|
||||
* Sorry for this confused comment, i am tired. */
|
||||
if (rudel && !self->strut.left && *x < mon_a->x) *x = mon_a->x;
|
||||
if (ruder && !self->strut.right && *x + fw > mon_a->x + mon_a->width)
|
||||
*x = mon_a->x + MAX(0, mon_a->width - fw);
|
||||
for (i = 0; i < screen_num_monitors; ++i) {
|
||||
Rect *a;
|
||||
|
||||
if (rudet && !self->strut.top && *y < mon_a->y) *y = mon_a->y;
|
||||
if (rudeb && !self->strut.bottom && *y + fh > mon_a->y + mon_a->height)
|
||||
*y = mon_a->y + MAX(0, mon_a->height - fh);
|
||||
if (!screen_physical_area_monitor_contains(i, &desired))
|
||||
continue;
|
||||
|
||||
a = screen_area(self->desktop, SCREEN_AREA_ONE_MONITOR, &desired);
|
||||
|
||||
/* This makes sure windows aren't entirely outside of the screen so you
|
||||
can't see them at all.
|
||||
It makes sure 10% of the window is on the screen at least. At don't
|
||||
let it move itself off the top of the screen, which would hide the
|
||||
titlebar on you. (The user can still do this if they want too, it's
|
||||
only limiting the application.
|
||||
*/
|
||||
if (client_normal(self)) {
|
||||
if (!self->strut.right && *x + fw/10 >= a->x + a->width - 1)
|
||||
*x = a->x + a->width - fw/10;
|
||||
if (!self->strut.bottom && *y + fh/10 >= a->y + a->height - 1)
|
||||
*y = a->y + a->height - fh/10;
|
||||
if (!self->strut.left && *x + fw*9/10 - 1 < a->x)
|
||||
*x = a->x - fw*9/10;
|
||||
if (!self->strut.top && *y + fh*9/10 - 1 < a->y)
|
||||
*y = a->y - fw*9/10;
|
||||
}
|
||||
|
||||
/* This here doesn't let windows even a pixel outside the
|
||||
struts/screen. When called from client_manage, programs placing
|
||||
themselves are forced completely onscreen, while things like
|
||||
xterm -geometry resolution-width/2 will work fine. Trying to
|
||||
place it completely offscreen will be handled in the above code.
|
||||
Sorry for this confused comment, i am tired. */
|
||||
if (rudel && !self->strut.left && *x < a->x) *x = a->x;
|
||||
if (ruder && !self->strut.right && *x + fw > a->x + a->width)
|
||||
*x = a->x + MAX(0, a->width - fw);
|
||||
|
||||
if (rudet && !self->strut.top && *y < a->y) *y = a->y;
|
||||
if (rudeb && !self->strut.bottom && *y + fh > a->y + a->height)
|
||||
*y = a->y + MAX(0, a->height - fh);
|
||||
|
||||
g_free(a);
|
||||
}
|
||||
|
||||
/* get where the client should be */
|
||||
frame_frame_gravity(self->frame, x, y, w, h);
|
||||
|
||||
g_free(all_a);
|
||||
g_free(mon_a);
|
||||
|
||||
return ox != *x || oy != *y;
|
||||
}
|
||||
|
||||
|
@ -1985,7 +1984,7 @@ void client_update_strut(ObClient *self)
|
|||
got = TRUE;
|
||||
|
||||
/* use the screen's width/height */
|
||||
a = screen_physical_area();
|
||||
a = screen_physical_area_all_monitors();
|
||||
|
||||
STRUT_PARTIAL_SET(strut,
|
||||
data[0], data[2], data[1], data[3],
|
||||
|
@ -2730,11 +2729,10 @@ void client_try_configure(ObClient *self, gint *x, gint *y, gint *w, gint *h,
|
|||
Rect *a;
|
||||
guint i;
|
||||
|
||||
i = screen_find_monitor(&desired);
|
||||
/* use all possible struts when maximizing to the full screen */
|
||||
a = screen_area_monitor(self->desktop, i,
|
||||
(self->max_horz && self->max_vert ?
|
||||
NULL : &desired));
|
||||
i = screen_find_monitor(&desired);
|
||||
a = screen_area(self->desktop, i,
|
||||
(self->max_horz && self->max_vert ? NULL : &desired));
|
||||
|
||||
/* set the size and position if maximized */
|
||||
if (self->max_horz) {
|
||||
|
@ -3876,14 +3874,13 @@ gint client_directional_edge_search(ObClient *c, ObDirection dir, gboolean hang)
|
|||
gint dest, monitor_dest;
|
||||
gint my_edge_start, my_edge_end, my_offset;
|
||||
GList *it;
|
||||
Rect *a, *monitor;
|
||||
Rect *a, *mon;
|
||||
|
||||
if(!client_list)
|
||||
return -1;
|
||||
|
||||
a = screen_area(c->desktop, &c->frame->area);
|
||||
monitor = screen_area_monitor(c->desktop, client_monitor(c),
|
||||
&c->frame->area);
|
||||
a = screen_area(c->desktop, SCREEN_AREA_ALL_MONITORS, &c->frame->area);
|
||||
mon = screen_area(c->desktop, SCREEN_AREA_ONE_MONITOR, &c->frame->area);
|
||||
|
||||
switch(dir) {
|
||||
case OB_DIRECTION_NORTH:
|
||||
|
@ -3893,7 +3890,7 @@ gint client_directional_edge_search(ObClient *c, ObDirection dir, gboolean hang)
|
|||
|
||||
/* default: top of screen */
|
||||
dest = a->y + (hang ? c->frame->area.height : 0);
|
||||
monitor_dest = monitor->y + (hang ? c->frame->area.height : 0);
|
||||
monitor_dest = mon->y + (hang ? c->frame->area.height : 0);
|
||||
/* if the monitor edge comes before the screen edge, */
|
||||
/* use that as the destination instead. (For xinerama) */
|
||||
if (monitor_dest != dest && my_offset > monitor_dest)
|
||||
|
@ -3926,7 +3923,7 @@ gint client_directional_edge_search(ObClient *c, ObDirection dir, gboolean hang)
|
|||
|
||||
/* default: bottom of screen */
|
||||
dest = a->y + a->height - (hang ? c->frame->area.height : 0);
|
||||
monitor_dest = monitor->y + monitor->height -
|
||||
monitor_dest = mon->y + mon->height -
|
||||
(hang ? c->frame->area.height : 0);
|
||||
/* if the monitor edge comes before the screen edge, */
|
||||
/* use that as the destination instead. (For xinerama) */
|
||||
|
@ -3961,7 +3958,7 @@ gint client_directional_edge_search(ObClient *c, ObDirection dir, gboolean hang)
|
|||
|
||||
/* default: leftmost egde of screen */
|
||||
dest = a->x + (hang ? c->frame->area.width : 0);
|
||||
monitor_dest = monitor->x + (hang ? c->frame->area.width : 0);
|
||||
monitor_dest = mon->x + (hang ? c->frame->area.width : 0);
|
||||
/* if the monitor edge comes before the screen edge, */
|
||||
/* use that as the destination instead. (For xinerama) */
|
||||
if (monitor_dest != dest && my_offset > monitor_dest)
|
||||
|
@ -3994,7 +3991,7 @@ gint client_directional_edge_search(ObClient *c, ObDirection dir, gboolean hang)
|
|||
|
||||
/* default: rightmost edge of screen */
|
||||
dest = a->x + a->width - (hang ? c->frame->area.width : 0);
|
||||
monitor_dest = monitor->x + monitor->width -
|
||||
monitor_dest = mon->x + mon->width -
|
||||
(hang ? c->frame->area.width : 0);
|
||||
/* if the monitor edge comes before the screen edge, */
|
||||
/* use that as the destination instead. (For xinerama) */
|
||||
|
@ -4032,7 +4029,7 @@ gint client_directional_edge_search(ObClient *c, ObDirection dir, gboolean hang)
|
|||
}
|
||||
|
||||
g_free(a);
|
||||
g_free(monitor);
|
||||
g_free(mon);
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
|
|
@ -272,7 +272,7 @@ void dock_configure()
|
|||
dock->w += ob_rr_theme->obwidth * 2;
|
||||
dock->h += ob_rr_theme->obwidth * 2;
|
||||
|
||||
a = screen_physical_area();
|
||||
a = screen_physical_area_all_monitors();
|
||||
|
||||
/* calculate position */
|
||||
if (config_dock_floating) {
|
||||
|
|
|
@ -251,7 +251,7 @@ static void popup_render(ObFocusCyclePopup *p, const ObClient *c)
|
|||
const ObFocusCyclePopupTarget *newtarget;
|
||||
gint newtargetx, newtargety;
|
||||
|
||||
screen_area = screen_physical_area_monitor_active();
|
||||
screen_area = screen_physical_area_active();
|
||||
|
||||
/* get the outside margins */
|
||||
RrMargins(p->a_bg, &ml, &mt, &mr, &mb);
|
||||
|
@ -506,7 +506,7 @@ void focus_cycle_popup_single_show(struct _ObClient *c,
|
|||
g_assert(popup.targets == NULL);
|
||||
|
||||
/* position the popup */
|
||||
a = screen_physical_area_monitor_active();
|
||||
a = screen_physical_area_active();
|
||||
icon_popup_position(single_popup, CenterGravity,
|
||||
a->x + a->width / 2, a->y + a->height / 2);
|
||||
icon_popup_height(single_popup, POPUP_HEIGHT);
|
||||
|
|
|
@ -1577,7 +1577,8 @@ static gboolean frame_animate_iconify(gpointer p)
|
|||
|
||||
if (self->client->icon_geometry.width == 0) {
|
||||
/* there is no icon geometry set so just go straight down */
|
||||
Rect *a = screen_physical_area();
|
||||
Rect *a = screen_physical_area_monitor
|
||||
(screen_find_monitor(&self->area));
|
||||
iconx = self->area.x + self->area.width / 2 + 32;
|
||||
icony = a->y + a->width;
|
||||
iconw = 64;
|
||||
|
|
|
@ -142,7 +142,7 @@ typedef struct _StrutPartial {
|
|||
(s1).bottom_start == (s2).bottom_start && \
|
||||
(s1).bottom_end == (s2).bottom_end)
|
||||
|
||||
#define RANGE_INTERSECT(r1x, r1w, r2x, r2w) \
|
||||
#define RANGES_INTERSECT(r1x, r1w, r2x, r2w) \
|
||||
(r1x < r2x + r2w && r1x + r1w > r2x)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -98,7 +98,7 @@ static void set_curpos(KeyBindingTree *newpos)
|
|||
g_free(oldtext);
|
||||
}
|
||||
|
||||
a = screen_physical_area_monitor_active();
|
||||
a = screen_physical_area_active();
|
||||
popup_position(popup, NorthWestGravity, a->x + 10, a->y + 10);
|
||||
/* 1 second delay for the popup to show */
|
||||
popup_delay_show(popup, G_USEC_PER_SEC, text);
|
||||
|
|
|
@ -210,6 +210,9 @@ void mouse_event(ObClient *client, XEvent *e)
|
|||
button = e->xbutton.button;
|
||||
state = e->xbutton.state;
|
||||
|
||||
if (CLIENT_CONTEXT(context, client))
|
||||
XAllowEvents(ob_display, ReplayPointer, event_curtime);
|
||||
|
||||
fire_binding(OB_MOUSE_ACTION_PRESS, context,
|
||||
client, e->xbutton.state,
|
||||
e->xbutton.button,
|
||||
|
|
|
@ -53,7 +53,7 @@ static Rect *pick_pointer_head(ObClient *c)
|
|||
gboolean contain = RECT_CONTAINS(*monitor, px, py);
|
||||
g_free(monitor);
|
||||
if (contain)
|
||||
return screen_area_monitor(c->desktop, i, NULL);
|
||||
return screen_area(c->desktop, i, NULL);
|
||||
}
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
@ -131,7 +131,7 @@ static Rect **pick_head(ObClient *c)
|
|||
add_choice(choice, i);
|
||||
|
||||
for (i = 0; i < screen_num_monitors; ++i)
|
||||
area[i] = screen_area_monitor(c->desktop, choice[i], NULL);
|
||||
area[i] = screen_area(c->desktop, choice[i], NULL);
|
||||
|
||||
return area;
|
||||
}
|
||||
|
@ -380,8 +380,8 @@ static gboolean place_per_app_setting(ObClient *client, gint *x, gint *y,
|
|||
screen = pick_pointer_head(client);
|
||||
else if (settings->monitor > 0 &&
|
||||
(guint)settings->monitor <= screen_num_monitors)
|
||||
screen = screen_area_monitor(client->desktop,
|
||||
(guint)settings->monitor - 1, NULL);
|
||||
screen = screen_area(client->desktop, (guint)settings->monitor - 1,
|
||||
NULL);
|
||||
else {
|
||||
Rect **areas;
|
||||
guint i;
|
||||
|
|
|
@ -154,9 +154,10 @@ void popup_delay_show(ObPopup *self, gulong usec, gchar *text)
|
|||
gint emptyx, emptyy; /* empty space between elements */
|
||||
gint textx, texty, textw, texth;
|
||||
gint iconx, icony, iconw, iconh;
|
||||
Rect *area;
|
||||
Rect *area, mon;
|
||||
|
||||
area = screen_physical_area();
|
||||
RECT_SET(mon, self->x, self->y, 1, 1);
|
||||
area = screen_physical_area_monitor(screen_find_monitor(&mon));
|
||||
|
||||
/* when there is no icon and the text is not parent relative, then
|
||||
fill the whole dialog with the text appearance, don't use the bg at all
|
||||
|
|
|
@ -152,7 +152,8 @@ void resist_move_monitors(ObClient *c, gint resist, gint *x, gint *y)
|
|||
continue;
|
||||
}
|
||||
|
||||
area = screen_area_monitor(c->desktop, i, &desired_area);
|
||||
area = screen_area(c->desktop, SCREEN_AREA_ALL_MONITORS,
|
||||
&desired_area);
|
||||
|
||||
al = RECT_LEFT(*area);
|
||||
at = RECT_TOP(*area);
|
||||
|
@ -307,7 +308,8 @@ void resist_size_monitors(ObClient *c, gint resist, gint *w, gint *h,
|
|||
continue;
|
||||
}
|
||||
|
||||
area = screen_area_monitor(c->desktop, i, &desired_area);
|
||||
area = screen_area(c->desktop, SCREEN_AREA_ALL_MONITORS,
|
||||
&desired_area);
|
||||
|
||||
/* get the screen boundaries */
|
||||
al = RECT_LEFT(*area);
|
||||
|
|
266
openbox/screen.c
266
openbox/screen.c
|
@ -67,10 +67,11 @@ Time screen_desktop_user_time = CurrentTime;
|
|||
|
||||
/*! An array of desktops, holding array of areas per monitor */
|
||||
static Rect *monitor_area;
|
||||
static GSList *struts_top;
|
||||
static GSList *struts_left;
|
||||
static GSList *struts_right;
|
||||
static GSList *struts_bottom;
|
||||
/*! An array of desktops, holding an array of struts */
|
||||
static GSList **struts_top;
|
||||
static GSList **struts_left;
|
||||
static GSList **struts_right;
|
||||
static GSList **struts_bottom;
|
||||
|
||||
static ObPagerPopup *desktop_cycle_popup;
|
||||
|
||||
|
@ -730,7 +731,7 @@ void screen_desktop_popup(guint d, gboolean show)
|
|||
if (!show) {
|
||||
pager_popup_hide(desktop_cycle_popup);
|
||||
} else {
|
||||
a = screen_physical_area_monitor_active();
|
||||
a = screen_physical_area_active();
|
||||
pager_popup_position(desktop_cycle_popup, CenterGravity,
|
||||
a->x + a->width / 2, a->y + a->height / 2);
|
||||
pager_popup_icon_size_multiplier(desktop_cycle_popup,
|
||||
|
@ -1083,6 +1084,30 @@ void screen_install_colormap(ObClient *client, gboolean install)
|
|||
}
|
||||
}
|
||||
|
||||
#define STRUT_LEFT_ON_MONITOR(s, i) \
|
||||
(RANGES_INTERSECT(s->left_start, s->left_end - s->left_start + 1, \
|
||||
monitor_area[i].y, monitor_area[i].height))
|
||||
#define STRUT_RIGHT_ON_MONITOR(s, i) \
|
||||
(RANGES_INTERSECT(s->right_start, s->right_end - s->right_start + 1, \
|
||||
monitor_area[i].y, monitor_area[i].height))
|
||||
#define STRUT_TOP_ON_MONITOR(s, i) \
|
||||
(RANGES_INTERSECT(s->top_start, s->top_end - s->top_start + 1, \
|
||||
monitor_area[i].x, monitor_area[i].width))
|
||||
#define STRUT_BOTTOM_ON_MONITOR(s, i) \
|
||||
(RANGES_INTERSECT(s->bottom_start, s->bottom_end - s->bottom_start + 1, \
|
||||
monitor_area[i].x, monitor_area[i].width))
|
||||
|
||||
#define RESET_STRUT_LIST(sl) \
|
||||
{for (i = 0; sl[i]; ++i) \
|
||||
g_slist_free(sl[i]); \
|
||||
sl = g_renew(GSList*, sl, screen_num_desktops + 1); \
|
||||
sl[screen_num_desktops] = NULL;} /* null terminated */
|
||||
|
||||
#define ADD_STRUT_TO_LIST(sl, d, s) \
|
||||
{for (i = 0; i < screen_num_desktops; ++i) \
|
||||
if (i == d || d == DESKTOP_ALL) \
|
||||
sl[i] = g_slist_prepend(sl[i], s);}
|
||||
|
||||
void screen_update_areas()
|
||||
{
|
||||
guint i, j;
|
||||
|
@ -1097,31 +1122,31 @@ void screen_update_areas()
|
|||
|
||||
dims = g_new(gulong, 4 * screen_num_desktops * screen_num_monitors);
|
||||
|
||||
g_slist_free(struts_left); struts_left = NULL;
|
||||
g_slist_free(struts_top); struts_top = NULL;
|
||||
g_slist_free(struts_right); struts_right = NULL;
|
||||
g_slist_free(struts_bottom); struts_bottom = NULL;
|
||||
RESET_STRUT_LIST(struts_left);
|
||||
RESET_STRUT_LIST(struts_top);
|
||||
RESET_STRUT_LIST(struts_right);
|
||||
RESET_STRUT_LIST(struts_bottom);
|
||||
|
||||
/* collect the struts */
|
||||
for (it = client_list; it; it = g_list_next(it)) {
|
||||
ObClient *c = it->data;
|
||||
if (c->strut.left)
|
||||
struts_left = g_slist_prepend(struts_left, &c->strut);
|
||||
ADD_STRUT_TO_LIST(struts_left, c->desktop, &c->strut);
|
||||
if (c->strut.top)
|
||||
struts_top = g_slist_prepend(struts_top, &c->strut);
|
||||
ADD_STRUT_TO_LIST(struts_top, c->desktop, &c->strut);
|
||||
if (c->strut.right)
|
||||
struts_right = g_slist_prepend(struts_right, &c->strut);
|
||||
ADD_STRUT_TO_LIST(struts_right, c->desktop, &c->strut);
|
||||
if (c->strut.bottom)
|
||||
struts_bottom = g_slist_prepend(struts_bottom, &c->strut);
|
||||
ADD_STRUT_TO_LIST(struts_bottom, c->desktop, &c->strut);
|
||||
}
|
||||
if (dock_strut.left)
|
||||
struts_left = g_slist_prepend(struts_left, &dock_strut);
|
||||
ADD_STRUT_TO_LIST(struts_left, DESKTOP_ALL, &dock_strut);
|
||||
if (dock_strut.top)
|
||||
struts_top = g_slist_prepend(struts_top, &dock_strut);
|
||||
ADD_STRUT_TO_LIST(struts_top, DESKTOP_ALL, &dock_strut);
|
||||
if (dock_strut.right)
|
||||
struts_right = g_slist_prepend(struts_right, &dock_strut);
|
||||
ADD_STRUT_TO_LIST(struts_right, DESKTOP_ALL, &dock_strut);
|
||||
if (dock_strut.bottom)
|
||||
struts_bottom = g_slist_prepend(struts_bottom, &dock_strut);
|
||||
ADD_STRUT_TO_LIST(struts_bottom, DESKTOP_ALL, &dock_strut);
|
||||
|
||||
/* set up the work areas to be full screen */
|
||||
for (i = 0; i < screen_num_monitors; ++i)
|
||||
|
@ -1139,32 +1164,24 @@ void screen_update_areas()
|
|||
|
||||
/* only add the strut to the area if it touches the monitor */
|
||||
|
||||
for (sit = struts_left; sit; sit = g_slist_next(sit)) {
|
||||
for (sit = struts_left[j]; sit; sit = g_slist_next(sit)) {
|
||||
StrutPartial *s = sit->data;
|
||||
if (RANGE_INTERSECT
|
||||
(s->left_start, s->left_end - s->left_start + 1,
|
||||
monitor_area[i].y, monitor_area[i].height))
|
||||
if (STRUT_LEFT_ON_MONITOR(s, i))
|
||||
l = MAX(l, s->left);
|
||||
}
|
||||
for (sit = struts_top; sit; sit = g_slist_next(sit)) {
|
||||
for (sit = struts_top[j]; sit; sit = g_slist_next(sit)) {
|
||||
StrutPartial *s = sit->data;
|
||||
if (RANGE_INTERSECT
|
||||
(s->top_start, s->top_end - s->top_start + 1,
|
||||
monitor_area[i].x, monitor_area[i].width))
|
||||
if (STRUT_TOP_ON_MONITOR(s, i))
|
||||
t = MAX(t, s->top);
|
||||
}
|
||||
for (sit = struts_right; sit; sit = g_slist_next(sit)) {
|
||||
for (sit = struts_right[j]; sit; sit = g_slist_next(sit)) {
|
||||
StrutPartial *s = sit->data;
|
||||
if (RANGE_INTERSECT
|
||||
(s->right_start, s->right_end - s->right_start + 1,
|
||||
monitor_area[i].y, monitor_area[i].height))
|
||||
if (STRUT_RIGHT_ON_MONITOR(s, i))
|
||||
r = MAX(r, s->right);
|
||||
}
|
||||
for (sit = struts_bottom; sit; sit = g_slist_next(sit)) {
|
||||
for (sit = struts_bottom[j]; sit; sit = g_slist_next(sit)) {
|
||||
StrutPartial *s = sit->data;
|
||||
if (RANGE_INTERSECT
|
||||
(s->bottom_start, s->bottom_end - s->bottom_start + 1,
|
||||
monitor_area[i].x, monitor_area[i].width))
|
||||
if (STRUT_BOTTOM_ON_MONITOR(s, i))
|
||||
b = MAX(b, s->bottom);
|
||||
}
|
||||
|
||||
|
@ -1198,16 +1215,17 @@ void screen_update_areas()
|
|||
g_free(dims);
|
||||
}
|
||||
|
||||
Rect* screen_area(guint desktop, Rect *search)
|
||||
#if 0
|
||||
Rect* screen_area_all_monitors(guint desktop)
|
||||
{
|
||||
guint i;
|
||||
Rect *a;
|
||||
|
||||
a = screen_area_monitor(desktop, 0, search);
|
||||
a = screen_area_monitor(desktop, 0);
|
||||
|
||||
/* combine all the monitors together */
|
||||
for (i = 0; i < screen_num_monitors; ++i) {
|
||||
Rect *m = screen_area_monitor(desktop, i, search);
|
||||
for (i = 1; i < screen_num_monitors; ++i) {
|
||||
Rect *m = screen_area_monitor(desktop, i);
|
||||
gint l, r, t, b;
|
||||
|
||||
l = MIN(RECT_LEFT(*a), RECT_LEFT(*m));
|
||||
|
@ -1222,55 +1240,134 @@ Rect* screen_area(guint desktop, Rect *search)
|
|||
|
||||
return a;
|
||||
}
|
||||
#endif
|
||||
|
||||
Rect* screen_area_monitor(guint desktop, guint head, Rect *search)
|
||||
#define STRUT_LEFT_IN_SEARCH(s, search) \
|
||||
(RANGES_INTERSECT(search->y, search->height, \
|
||||
s->left_start, s->left_end - s->left_start + 1))
|
||||
#define STRUT_RIGHT_IN_SEARCH(s, search) \
|
||||
(RANGES_INTERSECT(search->y, search->height, \
|
||||
s->right_start, s->right_end - s->right_start + 1))
|
||||
#define STRUT_TOP_IN_SEARCH(s, search) \
|
||||
(RANGES_INTERSECT(search->x, search->width, \
|
||||
s->top_start, s->top_end - s->top_start + 1))
|
||||
#define STRUT_BOTTOM_IN_SEARCH(s, search) \
|
||||
(RANGES_INTERSECT(search->x, search->width, \
|
||||
s->bottom_start, s->bottom_end - s->bottom_start + 1))
|
||||
|
||||
#define STRUT_LEFT_IGNORE(s, us, search) \
|
||||
(head != SCREEN_AREA_ALL_MONITORS || !us || \
|
||||
RECT_LEFT(monitor_area[i]) + s->left > RECT_LEFT(*search))
|
||||
#define STRUT_RIGHT_IGNORE(s, us, search) \
|
||||
(head != SCREEN_AREA_ALL_MONITORS || !us || \
|
||||
RECT_RIGHT(monitor_area[i]) - s->right < RECT_RIGHT(*search))
|
||||
#define STRUT_TOP_IGNORE(s, us, search) \
|
||||
(head != SCREEN_AREA_ALL_MONITORS || !us || \
|
||||
RECT_TOP(monitor_area[i]) + s->top > RECT_TOP(*search))
|
||||
#define STRUT_BOTTOM_IGNORE(s, us, search) \
|
||||
(head != SCREEN_AREA_ALL_MONITORS || !us || \
|
||||
RECT_BOTTOM(monitor_area[i]) - s->bottom < RECT_BOTTOM(*search))
|
||||
|
||||
Rect* screen_area(guint desktop, guint head, Rect *search)
|
||||
{
|
||||
Rect *a;
|
||||
GSList *it;
|
||||
gint l, r, t, b;
|
||||
gint l, r, t, b, al, ar, at, ab;
|
||||
guint i, d;
|
||||
gboolean us = search != NULL; /* user provided search */
|
||||
|
||||
g_assert(head < screen_num_monitors);
|
||||
g_assert(desktop < screen_num_desktops || desktop == DESKTOP_ALL);
|
||||
g_assert(head < screen_num_monitors || head == SCREEN_AREA_ONE_MONITOR ||
|
||||
head == SCREEN_AREA_ALL_MONITORS);
|
||||
g_assert(!(head == SCREEN_AREA_ONE_MONITOR && search == NULL));
|
||||
|
||||
/* find any struts for this monitor
|
||||
which will be affecting the search area.
|
||||
*/
|
||||
|
||||
/* search everything if search is null */
|
||||
if (!search) {
|
||||
if (head < screen_num_monitors) search = &monitor_area[head];
|
||||
else search = &monitor_area[screen_num_monitors];
|
||||
}
|
||||
if (head == SCREEN_AREA_ONE_MONITOR) head = screen_find_monitor(search);
|
||||
|
||||
/* al is "all left" meaning the furthest left you can get, l is our
|
||||
"working left" meaning our current strut edge which we're calculating
|
||||
*/
|
||||
|
||||
/* only include monitors which the search area lines up with */
|
||||
if (RECT_INTERSECTS_RECT(monitor_area[screen_num_monitors], *search)) {
|
||||
al = l = RECT_RIGHT(monitor_area[screen_num_monitors]);
|
||||
at = t = RECT_BOTTOM(monitor_area[screen_num_monitors]);
|
||||
ar = r = RECT_LEFT(monitor_area[screen_num_monitors]);
|
||||
ab = b = RECT_TOP(monitor_area[screen_num_monitors]);
|
||||
for (i = 0; i < screen_num_monitors; ++i) {
|
||||
if (RANGES_INTERSECT(search->x, search->width,
|
||||
monitor_area[i].x, monitor_area[i].width) ||
|
||||
RANGES_INTERSECT(search->y, search->height,
|
||||
monitor_area[i].y, monitor_area[i].height))
|
||||
{
|
||||
/* add the monitor */
|
||||
al = l = MIN(l, RECT_LEFT(monitor_area[i]));
|
||||
at = t = MIN(t, RECT_TOP(monitor_area[i]));
|
||||
ar = r = MAX(r, RECT_RIGHT(monitor_area[i]));
|
||||
ab = b = MAX(b, RECT_BOTTOM(monitor_area[i]));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
al = l = RECT_LEFT(monitor_area[screen_num_monitors]);
|
||||
at = t = RECT_TOP(monitor_area[screen_num_monitors]);
|
||||
ar = r = RECT_RIGHT(monitor_area[screen_num_monitors]);
|
||||
ab = b = RECT_BOTTOM(monitor_area[screen_num_monitors]);
|
||||
}
|
||||
|
||||
for (d = 0; d < screen_num_desktops; ++d) {
|
||||
if (d != desktop && desktop != DESKTOP_ALL) continue;
|
||||
|
||||
for (i = 0; i < screen_num_monitors; ++i) {
|
||||
if (head != SCREEN_AREA_ALL_MONITORS && head != i) continue;
|
||||
|
||||
for (it = struts_left[d]; it; it = g_slist_next(it)) {
|
||||
StrutPartial *s = it->data;
|
||||
if (STRUT_LEFT_IN_SEARCH(s, search) &&
|
||||
!STRUT_LEFT_IGNORE(s, us, search))
|
||||
l = MAX(l, al + s->left);
|
||||
}
|
||||
for (it = struts_top[d]; it; it = g_slist_next(it)) {
|
||||
StrutPartial *s = it->data;
|
||||
if (STRUT_TOP_IN_SEARCH(s, search) &&
|
||||
!STRUT_TOP_IGNORE(s, us, search))
|
||||
t = MAX(t, al + s->top);
|
||||
}
|
||||
for (it = struts_right[d]; it; it = g_slist_next(it)) {
|
||||
StrutPartial *s = it->data;
|
||||
if (STRUT_RIGHT_IN_SEARCH(s, search) &&
|
||||
!STRUT_RIGHT_IGNORE(s, us, search))
|
||||
r = MIN(r, ar - s->right);
|
||||
}
|
||||
for (it = struts_bottom[d]; it; it = g_slist_next(it)) {
|
||||
StrutPartial *s = it->data;
|
||||
if (STRUT_BOTTOM_IN_SEARCH(s, search) &&
|
||||
!STRUT_BOTTOM_IGNORE(s, us, search))
|
||||
r = MIN(r, ar - s->bottom);
|
||||
}
|
||||
|
||||
/* limit to this monitor */
|
||||
if (head == i) {
|
||||
l = MAX(l, RECT_LEFT(monitor_area[i]));
|
||||
t = MAX(t, RECT_TOP(monitor_area[i]));
|
||||
r = MIN(r, RECT_RIGHT(monitor_area[i]));
|
||||
b = MIN(b, RECT_BOTTOM(monitor_area[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* get the base area for the monitor */
|
||||
a = g_new(Rect, 1);
|
||||
*a = monitor_area[head];
|
||||
|
||||
/* remove any struts which will be affecting the search area */
|
||||
l = t = r = b = 0;
|
||||
for (it = struts_left; it; it = g_slist_next(it)) {
|
||||
StrutPartial *s = it->data;
|
||||
if (!search ||
|
||||
RANGE_INTERSECT(search->y, search->height,
|
||||
s->left_start, s->left_end - s->left_start + 1))
|
||||
l = MAX(l, s->left);
|
||||
}
|
||||
for (it = struts_right; it; it = g_slist_next(it)) {
|
||||
StrutPartial *s = it->data;
|
||||
if (!search ||
|
||||
RANGE_INTERSECT(search->y, search->height,
|
||||
s->right_start, s->right_end - s->right_start + 1))
|
||||
r = MAX(r, s->right);
|
||||
}
|
||||
for (it = struts_top; it; it = g_slist_next(it)) {
|
||||
StrutPartial *s = it->data;
|
||||
if (!search ||
|
||||
RANGE_INTERSECT(search->x, search->width,
|
||||
s->top_start, s->top_end - s->top_start + 1))
|
||||
t = MAX(t, s->top);
|
||||
}
|
||||
for (it = struts_bottom; it; it = g_slist_next(it)) {
|
||||
StrutPartial *s = it->data;
|
||||
if (!search ||
|
||||
RANGE_INTERSECT(search->x, search->width,
|
||||
s->bottom_start,
|
||||
s->bottom_end - s->bottom_start + 1))
|
||||
b = MAX(b, s->bottom);
|
||||
}
|
||||
|
||||
a->x += l;
|
||||
a->y += t;
|
||||
a->width -= l + r;
|
||||
a->height -= t + b;
|
||||
a->x = l;
|
||||
a->y = t;
|
||||
a->width = r - l + 1;
|
||||
a->height = b - t + 1;
|
||||
return a;
|
||||
}
|
||||
|
||||
|
@ -1299,7 +1396,7 @@ guint screen_find_monitor(Rect *search)
|
|||
return most;
|
||||
}
|
||||
|
||||
Rect* screen_physical_area()
|
||||
Rect* screen_physical_area_all_monitors()
|
||||
{
|
||||
return screen_physical_area_monitor(screen_num_monitors);
|
||||
}
|
||||
|
@ -1314,7 +1411,14 @@ Rect* screen_physical_area_monitor(guint head)
|
|||
return a;
|
||||
}
|
||||
|
||||
Rect* screen_physical_area_monitor_active()
|
||||
gboolean screen_physical_area_monitor_contains(guint head, Rect *search)
|
||||
{
|
||||
g_assert(head <= screen_num_monitors);
|
||||
g_assert(search);
|
||||
return RECT_INTERSECTS_RECT(monitor_area[head], *search);
|
||||
}
|
||||
|
||||
Rect* screen_physical_area_active()
|
||||
{
|
||||
Rect *a;
|
||||
gint x, y;
|
||||
|
|
|
@ -94,15 +94,24 @@ void screen_install_colormap(struct _ObClient *client, gboolean install);
|
|||
|
||||
void screen_update_areas();
|
||||
|
||||
Rect *screen_physical_area();
|
||||
Rect *screen_physical_area_all_monitors();
|
||||
|
||||
Rect *screen_physical_area_monitor(guint head);
|
||||
|
||||
Rect *screen_physical_area_monitor_active();
|
||||
Rect *screen_physical_area_active();
|
||||
|
||||
Rect *screen_area(guint desktop, Rect *search);
|
||||
/* doesn't include struts which the search area is already outside of when
|
||||
'search' is not NULL */
|
||||
#define SCREEN_AREA_ALL_MONITORS ((unsigned)-1)
|
||||
#define SCREEN_AREA_ONE_MONITOR ((unsigned)-2)
|
||||
|
||||
Rect *screen_area_monitor(guint desktop, guint head, Rect *search);
|
||||
/*! @param head is the number of the head or one of SCREEN_AREA_ALL_MONITORS,
|
||||
SCREEN_AREA_ONE_MONITOR
|
||||
@param search NULL or the whole monitor(s)
|
||||
*/
|
||||
Rect* screen_area(guint desktop, guint head, Rect *search);
|
||||
|
||||
gboolean screen_physical_area_monitor_contains(guint head, Rect *search);
|
||||
|
||||
/*! Determines which physical monitor a rectangle is on by calculating the
|
||||
area of the part of the rectable on each monitor. The number of the
|
||||
|
|
Loading…
Reference in a new issue