all repos — openbox @ 34e819738b344a992a1dbfd6cdd165e0c8ddb3a9

openbox fork - make it a bit more like ryudo

xinerama support
Dana Jansens danakj@orodu.net
commit

34e819738b344a992a1dbfd6cdd165e0c8ddb3a9

parent

d0abbec2e522119c0865f668b094c60a1712e24f

M openbox/client.copenbox/client.c

@@ -288,12 +288,12 @@ } else {

stacking_add(CLIENT_AS_WINDOW(self)); } - screen_update_struts(); - dispatch_client(Event_Client_New, self, 0, 0); /* make sure the window is visible */ client_move_onscreen(self); + + screen_update_areas(); client_showhide(self);

@@ -347,7 +347,7 @@ focus_order_remove(self);

/* once the client is out of the list, update the struts to remove it's influence */ - screen_update_struts(); + screen_update_areas(); /* tell our parent(s) that we're gone */ if (self->transient_for == TRAN_GROUP) { /* transient of group */

@@ -440,6 +440,7 @@ {

Rect *a; int x = self->frame->area.x, y = self->frame->area.y; + /* XXX watch for xinerama dead areas */ a = screen_area(self->desktop); if (x >= a->x + a->width - 1) x = a->x + a->width - self->frame->area.width;

@@ -1297,7 +1298,7 @@

/* updating here is pointless while we're being mapped cuz we're not in the client list yet */ if (self->frame) - screen_update_struts(); + screen_update_areas(); } void client_update_icons(Client *self)

@@ -1620,35 +1621,47 @@ if (self->fullscreen) {

#ifdef VIDMODE int dot; XF86VidModeModeLine mode; +#endif + Rect *a; + guint i; - if (extensions_vidmode && + i = client_xinerama_area(self); + a = screen_physical_area_xinerama(i); + +#ifdef VIDMODE + if (i == 0 && /* primary head */ + extensions_vidmode && + XF86VidModeGetViewPort(ob_display, ob_screen, &x, &y) && + /* get the mode last so the mode.privsize isnt freed incorrectly */ XF86VidModeGetModeLine(ob_display, ob_screen, &dot, &mode)) { + x += a->x; + y += a->y; w = mode.hdisplay; h = mode.vdisplay; if (mode.privsize) XFree(mode.private); - } else { -#else - w = screen_physical_size.width; - h = screen_physical_size.height; + } else #endif -#ifdef VIDMODE + { + x = a->x; + y = a->y; + w = a->width; + h = a->height; } - if (!(extensions_vidmode && - XF86VidModeGetViewPort(ob_display, ob_screen, &x, &y))) { - x = y = 0; -#endif - } + user = FALSE; /* ignore that increment etc shit when in fullscreen */ } else { + Rect *a; + + a = screen_area_xinerama(self->desktop, client_xinerama_area(self)); + /* set the size and position if maximized */ if (self->max_horz) { - x = screen_area(self->desktop)->x - self->frame->size.left; - w = screen_area(self->desktop)->width; + x = a->x - self->frame->size.left; + w = a->width; } if (self->max_vert) { - y = screen_area(self->desktop)->y; - h = screen_area(self->desktop)->height - - self->frame->size.top - self->frame->size.bottom; + y = a->y; + h = a->height - self->frame->size.top - self->frame->size.bottom; } }

@@ -1841,14 +1854,14 @@ x = y = w = h = 0;

} else { guint num; gint32 *dimensions; + Rect *a; /* pick some fallbacks... */ - x = screen_area(self->desktop)->x + - screen_area(self->desktop)->width / 4; - y = screen_area(self->desktop)->y + - screen_area(self->desktop)->height / 4; - w = screen_area(self->desktop)->width / 2; - h = screen_area(self->desktop)->height / 2; + a = screen_area_xinerama(self->desktop, 0); + x = a->x + a->width / 4; + y = a->y + a->height / 4; + w = a->width / 2; + h = a->height / 2; if (PROP_GETA32(self->window, openbox_premax, cardinal, (guint32**)&dimensions, &num)) {

@@ -1930,7 +1943,7 @@ client_reconfigure(self);

} client_change_state(self); client_showhide(self); - screen_update_struts(); + screen_update_areas(); dispatch_client(iconic ? Event_Client_Unmapped : Event_Client_Mapped, self, 0, 0);

@@ -1998,17 +2011,17 @@ }

} else { guint num; gint32 *dimensions; + Rect *a; /* pick some fallbacks... */ + a = screen_area_xinerama(self->desktop, 0); if (dir == 0 || dir == 1) { /* horz */ - x = screen_area(self->desktop)->x + - screen_area(self->desktop)->width / 4; - w = screen_area(self->desktop)->width / 2; + x = a->x + a->width / 4; + w = a->width / 2; } if (dir == 0 || dir == 2) { /* vert */ - y = screen_area(self->desktop)->y + - screen_area(self->desktop)->height / 4; - h = screen_area(self->desktop)->height / 2; + y = a->y + a->height / 4; + h = a->height / 2; } if (PROP_GETA32(self->window, openbox_premax, cardinal,

@@ -2112,7 +2125,7 @@ client_showhide(self);

/* raise if it was not already on the desktop */ if (old != DESKTOP_ALL) stacking_raise(CLIENT_AS_WINDOW(self)); - screen_update_struts(); + screen_update_areas(); /* add to the new desktop(s) */ if (config_focus_new)

@@ -2548,3 +2561,17 @@ }

client_calc_layer(self); client_change_state(self); /* reflect this in the state hints */ } + +guint client_xinerama_area(Client *self) +{ + guint i; + + for (i = 0; i < screen_num_xin_areas; ++i) { + Rect *area = screen_physical_area_xinerama(i); + if (RECT_INTERSECTS_RECT(*area, self->frame->area)) + break; + } + if (i == screen_num_xin_areas) i = 0; + g_assert(i < screen_num_xin_areas); + return i; +}
M openbox/client.hopenbox/client.h

@@ -506,4 +506,6 @@ > 0 indicates the client should be placed above other clients.

*/ void client_set_layer(Client *self, int layer); +guint client_xinerama_area(Client *self); + #endif
M openbox/dock.copenbox/dock.c

@@ -151,6 +151,7 @@ GList *it;

int spot; int gravity; int minw, minh; + Rect *a; RrMinsize(dock->a_frame, &minw, &minh);

@@ -190,6 +191,8 @@ /* used for calculating offsets */

dock->w += ob_rr_theme->bwidth * 2; dock->h += ob_rr_theme->bwidth * 2; + a = screen_physical_area(); + /* calculate position */ switch (config_dock_pos) { case DockPos_Floating:

@@ -203,38 +206,38 @@ dock->y = 0;

gravity = NorthWestGravity; break; case DockPos_Top: - dock->x = screen_physical_size.width / 2; + dock->x = a->width / 2; dock->y = 0; gravity = NorthGravity; break; case DockPos_TopRight: - dock->x = screen_physical_size.width; + dock->x = a->width; dock->y = 0; gravity = NorthEastGravity; break; case DockPos_Left: dock->x = 0; - dock->y = screen_physical_size.height / 2; + dock->y = a->height / 2; gravity = WestGravity; break; case DockPos_Right: - dock->x = screen_physical_size.width; - dock->y = screen_physical_size.height / 2; + dock->x = a->width; + dock->y = a->height / 2; gravity = EastGravity; break; case DockPos_BottomLeft: dock->x = 0; - dock->y = screen_physical_size.height; + dock->y = a->height; gravity = SouthWestGravity; break; case DockPos_Bottom: - dock->x = screen_physical_size.width / 2; - dock->y = screen_physical_size.height; + dock->x = a->width / 2; + dock->y = a->height; gravity = SouthGravity; break; case DockPos_BottomRight: - dock->x = screen_physical_size.width; - dock->y = screen_physical_size.height; + dock->x = a->width; + dock->y = a->height; gravity = SouthEastGravity; break; }

@@ -370,7 +373,7 @@ /* but they are useful outside of this function! */

dock->w += ob_rr_theme->bwidth * 2; dock->h += ob_rr_theme->bwidth * 2; - screen_update_struts(); + screen_update_areas(); } void dock_app_configure(DockApp *app, int w, int h)
M openbox/extensions.copenbox/extensions.c

@@ -1,5 +1,7 @@

#include "openbox.h" +#include "geom.h" #include "extensions.h" +#include "screen.h" gboolean extensions_xkb = FALSE; int extensions_xkb_event_basep;

@@ -7,6 +9,7 @@ gboolean extensions_shape = FALSE;

int extensions_shape_event_basep; gboolean extensions_xinerama = FALSE; int extensions_xinerama_event_basep; +gboolean extensions_xinerama_active = FALSE; gboolean extensions_randr = FALSE; int extensions_randr_event_basep; gboolean extensions_vidmode = FALSE;

@@ -33,6 +36,7 @@ #ifdef XINERAMA

extensions_xinerama = XineramaQueryExtension(ob_display, &extensions_xinerama_event_basep, &junk); + extensions_xinerama_active = XineramaIsActive(ob_display); #endif #ifdef XRANDR

@@ -47,3 +51,40 @@ XF86VidModeQueryExtension(ob_display, &extensions_vidmode_event_basep,

&junk); #endif } + +void extensions_xinerama_screens(Rect **xin_areas, guint *nxin) +{ + guint i; + gint l, r, t, b; +#ifdef XINERAMA + if (extensions_xinerama_active) { + guint i; + gint n; + XineramaScreenInfo *info = XineramaQueryScreens(ob_display, &n); + *nxin = n; + *xin_areas = g_new(Rect, *nxin + 1); + for (i = 0; i < *nxin; ++i) + RECT_SET((*xin_areas)[i], info[i].x_org, info[i].y_org, + info[i].width, info[i].height); + } else +#endif + { + *nxin = 1; + *xin_areas = g_new(Rect, *nxin + 1); + RECT_SET((*xin_areas)[0], 0, 0, + screen_physical_size.width, screen_physical_size.height); + } + + /* returns one extra with the total area in it */ + l = (*xin_areas)[0].x; + t = (*xin_areas)[0].y; + r = (*xin_areas)[0].x + (*xin_areas)[0].width - 1; + b = (*xin_areas)[0].y + (*xin_areas)[0].height - 1; + for (i = 1; i < *nxin; ++i) { + l = MIN(l, (*xin_areas)[i].x); + t = MIN(l, (*xin_areas)[i].y); + r = MIN(r, (*xin_areas)[0].x + (*xin_areas)[0].width - 1); + b = MIN(b, (*xin_areas)[0].y + (*xin_areas)[0].height - 1); + } + RECT_SET((*xin_areas)[*nxin], l, t, r - l + 1, b - t + 1); +}
M openbox/extensions.hopenbox/extensions.h

@@ -33,6 +33,8 @@ /*! Does the display have the Xinerama extension? */

extern gboolean extensions_xinerama; /*! Base for events for the Xinerama extension */ extern int extensions_xinerama_event_basep; +/*! Is Xinerama enabled? */ +extern gboolean extensions_xinerama_active; /*! Does the display have the RandR extension? */ extern gboolean extensions_randr;

@@ -45,5 +47,7 @@ /*! Base for events for the VidMode extension */

extern int extensions_vidmode_event_basep; void extensions_query_all(); - + +void extensions_xinerama_screens(Rect **xin_areas, guint *nxin); + #endif
M openbox/focus.copenbox/focus.c

@@ -247,7 +247,7 @@ Rect *a;

Client *p = c; char *title; - a = screen_area(c->desktop); + a = screen_physical_area_xinerama(0); popup_position(focus_cycle_popup, CenterGravity, a->x + a->width / 2, a->y + a->height / 2); /* popup_size(focus_cycle_popup, a->height/2, a->height/16);
M openbox/geom.hopenbox/geom.h

@@ -34,8 +34,14 @@ (r1).width == (r2).width && \

(r1).height == (r2).height) #define RECT_CONTAINS(r, x, y) \ - (x >= (r).x && x < (r).x + (r).width && \ - y >= (r).y && y < (r).y + (r).height) + ((x) >= (r).x && (x) < (r).x + (r).width && \ + (y) >= (r).y && (y) < (r).y + (r).height) +#define RECT_CONTAINS_RECT(r, o) \ + ((o).x >= (r).x && (o).x + (o).width <= (r).x + (r).width && \ + (o).y >= (r).y && (o).y + (o).height <= (r).y + (r).height) +#define RECT_INTERSECTS_RECT(r, o) \ + ((o).x < (r).x + (r).width && (o).x + (o).width > (r).x && \ + (o).y < (r).y + (r).height && (o).y + (o).height > (r).y) typedef struct Strut { int left;
M openbox/menu.copenbox/menu.c

@@ -398,11 +398,22 @@ Default menu controller action for showing.

*/ void menu_control_show(Menu *self, int x, int y, Client *client) { + guint i; + Rect *a = NULL; + g_assert(!self->invalid); - POINT_SET(self->location, - MIN(x, screen_physical_size.width - self->size.width), - MIN(y, screen_physical_size.height - self->size.height)); + for (i = 0; i < screen_num_xin_areas; ++i) { + a = screen_physical_area_xinerama(i); + if (RECT_CONTAINS(*a, x, y)) + break; + } + g_assert(a != NULL); + self->xin_area = i; + + POINT_SET(self->location, + MIN(x, a->x + a->width - 1 - self->size.width), + MIN(y, a->y + a->height - 1 - self->size.height)); XMoveWindow(ob_display, self->frame, self->location.x, self->location.y); if (!self->shown) {

@@ -416,6 +427,8 @@ }

void menu_control_mouseover(MenuEntry *self, gboolean enter) { int x; + Rect *a; + self->hilite = enter; if (enter) {

@@ -436,7 +449,9 @@

/* need to get the width. is this bad?*/ menu_render(self->submenu); - if (self->submenu->size.width + x >= screen_physical_size.width) + a = screen_physical_area_xinerama(self->parent->xin_area); + + if (self->submenu->size.width + x >= a->x + a->width) x = self->parent->location.x - self->submenu->size.width - ob_rr_theme->bwidth;
M openbox/menu.hopenbox/menu.h

@@ -55,6 +55,7 @@ int bullet_w;

int item_h; Point location; Size size; + guint xin_area; /* index of the xinerama head/area */ /* plugin stuff */ char *plugin;
M openbox/moveresize.copenbox/moveresize.c

@@ -49,7 +49,6 @@ button_down = XKeysymToKeycode(ob_display, XStringToKeysym("Down"));

popup = popup_new(FALSE); popup_size_to_string(popup, "W: 0000 W: 0000"); - popup_position(popup, NorthWestGravity, POPUP_X, POPUP_Y); attrib.save_under = True; opaque_window.win = XCreateWindow(ob_display, ob_root, 0, 0, 1, 1, 0,

@@ -80,8 +79,12 @@

static void popup_coords(char *format, int a, int b) { char *text; + Rect *area; text = g_strdup_printf(format, a, b); + area = screen_physical_area_xinerama(0); + popup_position(popup, NorthWestGravity, + POPUP_X + area->x, POPUP_Y + area->y); popup_show(popup, text, NULL); g_free(text); }

@@ -89,6 +92,7 @@

void moveresize_start(Client *c, int x, int y, guint b, guint32 cnr) { Cursor cur; + Rect *a; g_assert(!moveresize_in_progress);

@@ -147,8 +151,10 @@

grab_pointer(TRUE, cur); grab_keyboard(TRUE); - XResizeWindow(ob_display, opaque_window.win, screen_physical_size.width, - screen_physical_size.height); + a = screen_physical_area(); + + XMoveResizeWindow(ob_display, opaque_window.win, + a->x, a->y, a->width, a->height); stacking_raise(INTERNAL_AS_WINDOW(&opaque_window)); if (corner == prop_atoms.net_wm_moveresize_move || corner == prop_atoms.net_wm_moveresize_move_keyboard) {
M openbox/screen.copenbox/screen.c

@@ -31,14 +31,16 @@ SubstructureNotifyMask | SubstructureRedirectMask | \

ButtonPressMask | ButtonReleaseMask | ButtonMotionMask) guint screen_num_desktops = 0; +guint screen_num_xin_areas = 0; guint screen_desktop = 0; Size screen_physical_size; gboolean screen_showing_desktop; DesktopLayout screen_desktop_layout; char **screen_desktop_names = NULL; -static Rect *area = NULL; -static Strut *strut = NULL; +static Rect **area = NULL; /* array of desktop holding array of + xinerama areas */ +static Rect *xin_areas = NULL; static Window support_window = None; #ifdef USE_LIBSN

@@ -49,7 +51,6 @@

static void sn_event_func(SnMonitorEvent *event, void *data); #endif -static void screen_update_area(); static void set_root_cursor(); static gboolean running;

@@ -212,6 +213,8 @@ }

void screen_shutdown() { + Rect **r; + XSelectInput(ob_display, ob_root, NoEventMask); PROP_ERASE(ob_root, openbox_pid); /* we're not running here no more! */

@@ -221,7 +224,8 @@

XDestroyWindow(ob_display, support_window); g_strfreev(screen_desktop_names); - g_free(strut); + for (r = area; *r; ++r) + g_free(*r); g_free(area); }

@@ -231,17 +235,15 @@ GList *it;

guint32 geometry[2]; /* Set the _NET_DESKTOP_GEOMETRY hint */ - geometry[0] = w; - geometry[1] = h; + screen_physical_size.width = geometry[0] = w; + screen_physical_size.height = geometry[1] = h; PROP_SETA32(ob_root, net_desktop_geometry, cardinal, geometry, 2); - screen_physical_size.width = geometry[0]; - screen_physical_size.height = geometry[1]; if (ob_state == State_Starting) return; dock_configure(); - screen_update_struts(); + screen_update_areas(); for (it = client_list; it; it = it->next) client_move_onscreen(it->data);

@@ -288,7 +290,7 @@ client_set_desktop(c, num - 1, FALSE);

} /* change our struts/area to match (after moving windows) */ - screen_update_struts(); + screen_update_areas(); dispatch_ob(Event_Ob_NumDesktops, num, old);

@@ -500,129 +502,205 @@ }

} } -void screen_update_struts() +void screen_update_areas() { + guint i, x; + guint32 *dims; + Rect **old_area = area; + Rect **rit; GList *it; - guint i; + + g_free(xin_areas); + extensions_xinerama_screens(&xin_areas, &screen_num_xin_areas); + + if (area) { + for (i = 0; area[i]; ++i) + g_free(area[i]); + g_free(area); + } + + area = g_new(Rect*, screen_num_desktops + 2); + for (i = 0; i < screen_num_desktops + 1; ++i) + area[i] = g_new(Rect, screen_num_xin_areas + 1); + area[i] = NULL; - g_free(strut); - strut = g_new0(Strut, screen_num_desktops + 1); + dims = g_new(guint32, 4 * screen_num_desktops); - for (it = client_list; it != NULL; it = it->next) { - Client *c = it->data; - if (c->iconic) continue; /* these dont count in the strut */ - - if (c->desktop == 0xffffffff) { - for (i = 0; i < screen_num_desktops; ++i) - STRUT_ADD(strut[i], c->strut); - } else { - g_assert(c->desktop < screen_num_desktops); - STRUT_ADD(strut[c->desktop], c->strut); - } - /* apply to the 'all desktops' strut */ - STRUT_ADD(strut[screen_num_desktops], c->strut); - } + rit = old_area; + for (i = 0; i < screen_num_desktops + 1; ++i) { + Strut s; + int l, r, t, b; - for (i = 0; i < screen_num_desktops; ++i) - STRUT_ADD(strut[i], dock_strut); + /* calc the xinerama areas */ + for (x = 0; x < screen_num_xin_areas; ++x) { + area[i][x] = xin_areas[x]; + if (x == 0) { + l = xin_areas[x].x; + t = xin_areas[x].y; + r = xin_areas[x].x + xin_areas[x].width - 1; + b = xin_areas[x].y + xin_areas[x].height - 1; + } else { + l = MIN(l, xin_areas[x].x); + t = MIN(t, xin_areas[x].y); + r = MAX(r, xin_areas[x].x + xin_areas[x].width - 1); + b = MAX(b, xin_areas[x].y + xin_areas[x].height - 1); + } + } + RECT_SET(area[i][x], l, t, r - l + 1, b - t + 1); - screen_update_area(); -} + /* apply struts */ + STRUT_SET(s, 0, 0, 0, 0); + for (it = client_list; it; it = it->next) + STRUT_ADD(s, ((Client*)it->data)->strut); + STRUT_ADD(s, dock_strut); -static void screen_update_area() -{ - guint i; - guint32 *dims; + if (s.left) { + int o; - g_free(area); - area = g_new0(Rect, screen_num_desktops + 1); - - dims = g_new(guint32, 4 * screen_num_desktops); - for (i = 0; i < screen_num_desktops + 1; ++i) { - Rect old_area = area[i]; -/* - #ifdef XINERAMA - // reset to the full areas - if (isXineramaActive()) - xineramaUsableArea = getXineramaAreas(); - #endif // XINERAMA -*/ + /* find the left-most xin heads, i do this in 2 loops :| */ + o = area[i][0].x; + for (x = 1; x < screen_num_xin_areas; ++x) + o = MIN(o, area[i][x].x); - RECT_SET(area[i], strut[i].left, strut[i].top, - screen_physical_size.width - (strut[i].left + - strut[i].right), - screen_physical_size.height - (strut[i].top + - strut[i].bottom)); - -/* - #ifdef XINERAMA - if (isXineramaActive()) { - // keep each of the ximerama-defined areas inside the strut - RectList::iterator xit, xend = xineramaUsableArea.end(); - for (xit = xineramaUsableArea.begin(); xit != xend; ++xit) { - if (xit->x() < usableArea.x()) { - xit->setX(usableArea.x()); - xit->setWidth(xit->width() - usableArea.x()); - } - if (xit->y() < usableArea.y()) { - xit->setY(usableArea.y()); - xit->setHeight(xit->height() - usableArea.y()); - } - if (xit->x() + xit->width() > usableArea.width()) - xit->setWidth(usableArea.width() - xit->x()); - if (xit->y() + xit->height() > usableArea.height()) - xit->setHeight(usableArea.height() - xit->y()); - } - } - #endif // XINERAMA -*/ - if (!RECT_EQUAL(old_area, area[i])) { - /* the area has changed, adjust all the maximized windows */ + for (x = 0; x < screen_num_xin_areas; ++x) { + int edge = o + s.left - area[i][x].x; + if (edge > 0) { + area[i][x].x += edge; + area[i][x].width -= edge; + } + } + + area[i][screen_num_xin_areas].x += s.left; + area[i][screen_num_xin_areas].width -= s.left; + } + if (s.top) { + int o; + + /* find the left-most xin heads, i do this in 2 loops :| */ + o = area[i][0].y; + for (x = 1; x < screen_num_xin_areas; ++x) + o = MIN(o, area[i][x].y); + + for (x = 0; x < screen_num_xin_areas; ++x) { + int edge = o + s.top - area[i][x].y; + if (edge > 0) { + area[i][x].y += edge; + area[i][x].height -= edge; + } + } + + area[i][screen_num_xin_areas].y += s.top; + area[i][screen_num_xin_areas].height -= s.top; + } + if (s.right) { + int o; + + /* find the bottom-most xin heads, i do this in 2 loops :| */ + o = area[i][0].x + area[i][0].width - 1; + for (x = 1; x < screen_num_xin_areas; ++x) + o = MAX(o, area[i][x].x + area[i][x].width - 1); + + for (x = 0; x < screen_num_xin_areas; ++x) { + int edge = (area[i][x].x + area[i][x].width - 1) - + (o - s.right); + if (edge > 0) + area[i][x].width -= edge; + } + + area[i][screen_num_xin_areas].width -= s.right; + } + if (s.bottom) { + int o; + + /* find the bottom-most xin heads, i do this in 2 loops :| */ + o = area[i][0].y + area[i][0].height - 1; + for (x = 1; x < screen_num_xin_areas; ++x) + o = MAX(o, area[i][x].y + area[i][x].height - 1); + + for (x = 0; x < screen_num_xin_areas; ++x) { + int edge = (area[i][x].y + area[i][x].height - 1) - + (o - s.bottom); + if (edge > 0) + area[i][x].height -= edge; + } + + area[i][screen_num_xin_areas].height -= s.bottom; + } + + /* XXX when dealing with partial struts, if its in a single + xinerama area, then only subtract it from that area's space + for (x = 0; x < screen_num_xin_areas; ++x) { GList *it; + + + do something smart with it for the 'all xinerama areas' one... + for (it = client_list; it; it = it->next) { - Client *c = it->data; - if (i < screen_num_desktops) { - if (c->desktop == i) - client_reconfigure(c); - } else { - /* the 'all desktops' size */ - if (c->desktop == DESKTOP_ALL) - client_reconfigure(c); - } - } - } + + XXX if gunna test this shit, then gotta worry about when + the client moves between xinerama heads.. + + if (RECT_CONTAINS_RECT(((Client*)it->data)->frame->area, + area[i][x])) { - /* don't set these for the 'all desktops' area */ - if (i < screen_num_desktops) { - dims[(i * 4) + 0] = area[i].x; - dims[(i * 4) + 1] = area[i].y; - dims[(i * 4) + 2] = area[i].width; - dims[(i * 4) + 3] = area[i].height; - } + } + } + } + */ + + /* XXX optimize when this is run? */ + + /* the area has changed, adjust all the maximized + windows */ + for (it = client_list; it; it = it->next) { + Client *c = it->data; + if (i < screen_num_desktops) { + if (c->desktop == i) + client_reconfigure(c); + } else if (c->desktop == DESKTOP_ALL) + client_reconfigure(c); + } + if (i < screen_num_desktops) { + /* don't set these for the 'all desktops' area */ + dims[(i * 4) + 0] = area[i][screen_num_xin_areas].x; + dims[(i * 4) + 1] = area[i][screen_num_xin_areas].y; + dims[(i * 4) + 2] = area[i][screen_num_xin_areas].width; + dims[(i * 4) + 3] = area[i][screen_num_xin_areas].height; + } } PROP_SETA32(ob_root, net_workarea, cardinal, dims, 4 * screen_num_desktops); + g_free(dims); } Rect *screen_area(guint desktop) { - if (desktop >= screen_num_desktops) { - if (desktop == DESKTOP_ALL) - return &area[screen_num_desktops]; - return NULL; - } - return &area[desktop]; + return screen_area_xinerama(desktop, screen_num_xin_areas); } -Strut *screen_strut(guint desktop) +Rect *screen_area_xinerama(guint desktop, guint head) { + if (head > screen_num_xin_areas) + return NULL; if (desktop >= screen_num_desktops) { if (desktop == DESKTOP_ALL) - return &strut[screen_num_desktops]; + return &area[screen_num_desktops][head]; return NULL; } - return &strut[desktop]; + return &area[desktop][head]; +} + +Rect *screen_physical_area() +{ + return screen_physical_area_xinerama(screen_num_xin_areas); +} + +Rect *screen_physical_area_xinerama(guint head) +{ + if (head > screen_num_xin_areas) + return NULL; + return &xin_areas[head]; } static void set_root_cursor()
M openbox/screen.hopenbox/screen.h

@@ -10,6 +10,8 @@ #define DESKTOP_ALL (0xffffffff)

/*! The number of available desktops */ extern guint screen_num_desktops; +/*! The number of virtual "xinerama" screens/heads */ +extern guint screen_num_xin_areas; /*! The current desktop */ extern guint screen_desktop; /*! The size of the screen */

@@ -64,10 +66,14 @@ /*! Installs or uninstalls a colormap for a client. If client is NULL, then

it handles the root colormap. */ void screen_install_colormap(struct Client *client, gboolean install); -void screen_update_struts(); +void screen_update_areas(); + +Rect *screen_physical_area(); + +Rect *screen_physical_area_xinerama(guint head); Rect *screen_area(guint desktop); -Strut *screen_strut(guint desktop); +Rect *screen_area_xinerama(guint desktop, guint head); #endif
M plugins/menu/client_menu.cplugins/menu/client_menu.c

@@ -50,6 +50,8 @@

newy = MAX(client->frame->area.y + client->frame->size.top, y); newy -= ob_rr_theme->bwidth; + /* XXX do xinerama shit like in menu.c! im not coding it now because + this function isnt even being used right now... */ POINT_SET(self->location, MIN(x, screen_physical_size.width - self->size.width - ob_rr_theme->bwidth * 2),
M plugins/placement/placement.cplugins/placement/placement.c

@@ -32,7 +32,8 @@ Rect *area;

if (ob_state == State_Starting) return; - area = screen_area(c->desktop); + area = screen_area_xinerama(c->desktop, + g_random_int_range(0, screen_num_xin_areas)); l = area->x; t = area->y;
M plugins/resistance/resistance.cplugins/resistance/resistance.c

@@ -32,6 +32,7 @@ static void resist_move(Client *c, int *x, int *y)

{ GList *it; Rect *area; + guint i; int l, t, r, b; /* requested edges */ int al, at, ar, ab; /* screen area edges */ int cl, ct, cr, cb; /* current edges */

@@ -107,7 +108,8 @@ if (snapx && snapy) break;

} /* get the screen boundaries */ - area = screen_area(c->desktop); + area = screen_area_xinerama(c->desktop, client_xinerama_area(c)); + al = area->x; at = area->y; ar = al + area->width - 1;

@@ -117,7 +119,7 @@ /* snap to screen edges */

if (cl >= al && l < al && l >= al - resistance) *x = al; else if (cr <= ar && r > ar && r <= ar + resistance) - *x = ar - w + 1; + *x = ar - w + 1; if (ct >= at && t < at && t >= at - resistance) *y = at; else if (cb <= ab && b > ab && b < ab + resistance)