]> Dogcows Code - chaz/openbox/commitdiff
xinerama support
authorDana Jansens <danakj@orodu.net>
Fri, 27 Jun 2003 04:20:30 +0000 (04:20 +0000)
committerDana Jansens <danakj@orodu.net>
Fri, 27 Jun 2003 04:20:30 +0000 (04:20 +0000)
15 files changed:
openbox/client.c
openbox/client.h
openbox/dock.c
openbox/extensions.c
openbox/extensions.h
openbox/focus.c
openbox/geom.h
openbox/menu.c
openbox/menu.h
openbox/moveresize.c
openbox/screen.c
openbox/screen.h
plugins/menu/client_menu.c
plugins/placement/placement.c
plugins/resistance/resistance.c

index e704237f55d07207fbf2b3a60a80b889f4d0e47f..11e42a0eb9a6cd48b30cd2ef518c42f29645268c 100644 (file)
@@ -288,13 +288,13 @@ void client_manage(Window window)
         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);
 
     if (activate) client_activate(self);
@@ -347,7 +347,7 @@ void client_unmanage(Client *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 @@ void client_move_onscreen(Client *self)
     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 @@ void client_update_strut(Client *self)
     /* 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 @@ void client_configure(Client *self, Corner anchor, int x, int y, int w, int h,
 #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;
-#endif
-#ifdef VIDMODE
-        }
-        if (!(extensions_vidmode &&
-              XF86VidModeGetViewPort(ob_display, ob_screen, &x, &y))) {
-            x = y = 0;
+        } else
 #endif
+        {
+            x = a->x;
+            y = a->y;
+            w = a->width;
+            h = a->height;
         }
+
         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 @@ void client_fullscreen(Client *self, gboolean fs, gboolean savearea)
     } 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 @@ void client_iconify(Client *self, gboolean iconic, gboolean curdesk)
     }
     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 @@ void client_maximize(Client *self, gboolean max, int dir, gboolean savearea)
     } 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 @@ void client_set_desktop(Client *self, guint target, gboolean donthide)
     /* 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 @@ void client_set_layer(Client *self, int layer)
     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;
+}
index ff7f67c7fcdf3f73f13bf0eb4e45aca5b4358fd6..495eef81b82d0f755383cb3ecd917f60e6d61f75 100644 (file)
@@ -506,4 +506,6 @@ Client *client_find_directional(Client *c, Direction dir);
 */
 void client_set_layer(Client *self, int layer);
 
+guint client_xinerama_area(Client *self);
+
 #endif
index d46f76745cb33076a8c022bd92af17432fd451fb..4166ba220b032d3cb3fa2defa7dae68b239a7d65 100644 (file)
@@ -151,6 +151,7 @@ void dock_configure()
     int spot;
     int gravity;
     int minw, minh;
+    Rect *a;
 
     RrMinsize(dock->a_frame, &minw, &minh);
 
@@ -190,6 +191,8 @@ void dock_configure()
     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 @@ void dock_configure()
         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 @@ void dock_configure()
     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)
index be1ac5470679d3cb8247a21694c511e93d0e2d3e..ddcb83bbf8c70976914550c26777ddcb21bf69c6 100644 (file)
@@ -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 @@ void extensions_query_all()
     extensions_xinerama =
        XineramaQueryExtension(ob_display, &extensions_xinerama_event_basep,
                               &junk);
+    extensions_xinerama_active = XineramaIsActive(ob_display);
 #endif
 
 #ifdef XRANDR
@@ -47,3 +51,40 @@ void extensions_query_all()
                                   &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);
+}
index cda1bf7e1990062e3594bd46d5444f630cf6b62f..c07076e787cd8527f9230a1ab48e6db708286af1 100644 (file)
@@ -33,6 +33,8 @@ extern int extensions_shape_event_basep;
 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 @@ extern gboolean extensions_vidmode;
 extern int extensions_vidmode_event_basep;
 
 void extensions_query_all();
-  
+
+void extensions_xinerama_screens(Rect **xin_areas, guint *nxin);
+
 #endif
index 0a88865aa8736846775d102ddab443b5b93e7066..ad18d9748aea81f8a0e18c1893826393790aed05 100644 (file)
@@ -247,7 +247,7 @@ static void popup_cycle(Client *c, gboolean show)
         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);
index a4c1752aaffb7db9d7e93bc57d9a0caff462dc49..5f2c030c381a6217ad2cb1677a30a498260fa89f 100644 (file)
@@ -34,8 +34,14 @@ typedef struct Rect {
                             (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;
index 15a6cc502964168fc5338ebf4c3072d59a100516..9993b35085650f2645cab2f5fff965f155c28ef9 100644 (file)
@@ -398,11 +398,22 @@ void menu_entry_fire(MenuEntry *self)
 */
 
 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_show(Menu *self, int x, int y, Client *client) {
 
 void menu_control_mouseover(MenuEntry *self, gboolean enter) {
     int x;
+    Rect *a;
+
     self->hilite = enter;
   
     if (enter) {
@@ -436,7 +449,9 @@ void menu_control_mouseover(MenuEntry *self, gboolean enter) {
            /* 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;
            
index ea5d7454e714c1631daaaf5d3ca58cf33039cb1a..9ca78880a5c5acccad9a9b674db3bf2b6f7858d6 100644 (file)
@@ -55,6 +55,7 @@ typedef struct Menu {
     int item_h;
     Point location;
     Size size;
+    guint xin_area; /* index of the xinerama head/area */
 
     /* plugin stuff */
     char *plugin;
index 287d4ec0337fc6e63809e6173410daa0d251312d..570283c43ab827f969f887e572bdf12b9fd9eeed 100644 (file)
@@ -49,7 +49,6 @@ void moveresize_startup()
 
     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 @@ void moveresize_shutdown()
 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 @@ static void popup_coords(char *format, int a, int b)
 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 @@ void moveresize_start(Client *c, int x, int y, guint b, guint32 cnr)
     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) {
index a1bf55fada21c71a28d822aa348848a32e41b594..53ba27024f56a2b1887835bd49f49392fe369342 100644 (file)
                        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 Timer *sn_timer = NULL;
 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_startup()
 
 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 @@ void screen_shutdown()
     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 @@ void screen_resize(int w, int h)
     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 @@ void screen_set_num_desktops(guint num)
     }
 
     /* 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_install_colormap(Client *client, gboolean install)
     }
 }
 
-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(strut);
-    strut = g_new0(Strut, screen_num_desktops + 1);
-
-    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);
-    }
-
-    for (i = 0; i < screen_num_desktops; ++i)
-        STRUT_ADD(strut[i], dock_strut);
 
-    screen_update_area();
-}
+    g_free(xin_areas);
+    extensions_xinerama_screens(&xin_areas, &screen_num_xin_areas);
 
-static void screen_update_area()
-{
-    guint i;
-    guint32 *dims;
+    if (area) {
+        for (i = 0; area[i]; ++i)
+            g_free(area[i]);
+        g_free(area);
+    }
 
-    g_free(area);
-    area = g_new0(Rect, screen_num_desktops + 1);
+    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;
      
     dims = g_new(guint32, 4 * screen_num_desktops);
+
+    rit = old_area;
     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
-*/
+        Strut s;
+        int l, r, t, b;
+
+        /* 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);
+
+        /* 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);
+
+        if (s.left) {
+            int o;
+
+            /* 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);
+
+            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;
+                }
+            }
 
-       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 */
+            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);
-               }
-           }
-       }
 
-       /* 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 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])) {
+
+                }            
+            }
+        }
+        */
+
+        /* 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()
index f493bd82f3cd5fc1ba955dd6d5970e6991e33d9d..21d05e474534dee9f4742c6486c9793e26d9a6d9 100644 (file)
@@ -10,6 +10,8 @@ struct Client;
 
 /*! 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 @@ void screen_update_desktop_names();
   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
index 50ebc7cf6fa379bad2f1f81b3b3af55e3d10381f..aa09495ba5bd7fed3f5e5f8c8176914a7d04d249 100644 (file)
@@ -50,6 +50,8 @@ void client_menu_show(Menu *self, int x, int y, Client *client)
     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), 
index 889168b941f49e68aff6c8b33c865fff10b4af34..5f962e47c2bf74823994a9799f5217d16aa5c587 100644 (file)
@@ -32,7 +32,8 @@ static void place_random(Client *c)
 
     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;
index 91c10c0e54d468856b16e13661d06e8c31f80c97..8d49363782f924ecd3f402cd3fbfe1b7d2e0ba52 100644 (file)
@@ -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 @@ static void resist_move(Client *c, int *x, int *y)
         }
 
     /* 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 @@ static void resist_move(Client *c, int *x, int *y)
     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)
This page took 0.056135 seconds and 4 git commands to generate.