]> Dogcows Code - chaz/openbox/blobdiff - openbox/screen.c
replace the focus_backup with the screen_support_win, we dont need 2 offscreen windows.
[chaz/openbox] / openbox / screen.c
index deb3d3fbc31d5278959b56ceaed407eb111e399f..69082460814198ddc621d4b37fd37ba41b0cfc3e 100644 (file)
                        SubstructureNotifyMask | SubstructureRedirectMask | \
                        ButtonPressMask | ButtonReleaseMask | ButtonMotionMask)
 
-guint    screen_num_desktops    = 0;
-guint    screen_num_xin_areas   = 0;
-guint    screen_desktop         = 0;
+guint    screen_num_desktops;
+guint    screen_num_monitors;
+guint    screen_desktop;
 Size     screen_physical_size;
 gboolean screen_showing_desktop;
 DesktopLayout screen_desktop_layout;
-char   **screen_desktop_names = NULL;
+char   **screen_desktop_names;
+Window   screen_support_win;
 
-static Rect  **area = NULL; /* array of desktop holding array of
-                               xinerama areas */
-static Rect  *xin_areas = NULL;
-static Window support_window = None;
+static Rect  **area; /* array of desktop holding array of xinerama areas */
+static Rect  *monitor_area;
 
 #ifdef USE_LIBSN
 static SnMonitorContext *sn_context;
 static int sn_busy_cnt;
-static Timer *sn_timer = NULL;
+static ObTimer *sn_timer;
 
 static void sn_event_func(SnMonitorEvent *event, void *data);
 #endif
 
 static void set_root_cursor();
 
-static gboolean running;
-static int another_running(Display *d, XErrorEvent *e)
-{
-    (void)d;(void)e;
-    g_message("A window manager is already running on screen %d",
-             ob_screen);
-    running = TRUE;
-    return -1;
-}
-
 gboolean screen_annex()
 {
-    XErrorHandler old;
+    XSetWindowAttributes attrib;
     pid_t pid;
-    int i, num_support;
+    gint i, num_support;
     guint32 *supported;
 
-    running = FALSE;
-    old = XSetErrorHandler(another_running);
+    xerror_set_ignore(TRUE);
+    xerror_occured = FALSE;
     XSelectInput(ob_display, ob_root, ROOT_EVENTMASK);
-    XSync(ob_display, FALSE);
-    XSetErrorHandler(old);
-    if (running)
+    xerror_set_ignore(FALSE);
+    if (xerror_occured) {
+        g_message("A window manager is already running on screen %d",
+                  ob_screen);
        return FALSE;
+    }
+
 
     g_message("Managing screen %d", ob_screen);
 
@@ -87,14 +79,21 @@ gboolean screen_annex()
     PROP_SET32(ob_root, openbox_pid, cardinal, pid);
 
     /* create the netwm support window */
-    support_window = XCreateSimpleWindow(ob_display, ob_root, 0,0,1,1,0,0,0);
+    attrib.override_redirect = TRUE;
+    screen_support_win = XCreateWindow(ob_display, ob_root,
+                                       -100, -100, 1, 1, 0,
+                                       CopyFromParent, InputOutput,
+                                       CopyFromParent,
+                                       CWOverrideRedirect, &attrib);
+    XMapRaised(ob_display, screen_support_win);
 
     /* set supporting window */
-    PROP_SET32(ob_root, net_supporting_wm_check, window, support_window);
+    PROP_SET32(ob_root, net_supporting_wm_check, window, screen_support_win);
 
     /* set properties on the supporting window */
-    PROP_SETS(support_window, net_wm_name, "Openbox");
-    PROP_SET32(support_window, net_supporting_wm_check, window,support_window);
+    PROP_SETS(screen_support_win, net_wm_name, "Openbox");
+    PROP_SET32(screen_support_win, net_supporting_wm_check,
+               window, screen_support_win);
 
     /* set the _NET_SUPPORTED_ATOMS hint */
     num_support = 61;
@@ -178,8 +177,7 @@ void screen_startup()
     guint i;
 
     /* get the initial size */
-    screen_resize(WidthOfScreen(ScreenOfDisplay(ob_display, ob_screen)),
-                  HeightOfScreen(ScreenOfDisplay(ob_display, ob_screen)));
+    screen_resize();
 
     /* set the names */
     screen_desktop_names = g_new(char*,
@@ -221,7 +219,7 @@ void screen_shutdown()
     PROP_ERASE(ob_root, net_supported); /* not without us */
     PROP_ERASE(ob_root, net_showing_desktop); /* don't keep this mode */
 
-    XDestroyWindow(ob_display, support_window);
+    XDestroyWindow(ob_display, screen_support_win);
 
     g_strfreev(screen_desktop_names);
     for (r = area; *r; ++r)
@@ -229,17 +227,26 @@ void screen_shutdown()
     g_free(area);
 }
 
-void screen_resize(int w, int h)
+void screen_resize()
 {
+    static int oldw = 0, oldh = 0;
+    int w, h;
     GList *it;
     guint32 geometry[2];
 
+    w = WidthOfScreen(ScreenOfDisplay(ob_display, ob_screen));
+    h = HeightOfScreen(ScreenOfDisplay(ob_display, ob_screen));
+
+    if (w == oldw && h == oldh) return;
+
+    oldw = w; oldh = h;
+
     /* Set the _NET_DESKTOP_GEOMETRY hint */
     screen_physical_size.width = geometry[0] = w;
     screen_physical_size.height = geometry[1] = h;
     PROP_SETA32(ob_root, net_desktop_geometry, cardinal, geometry, 2);
 
-    if (ob_state == State_Starting)
+    if (ob_state == OB_STATE_STARTING)
        return;
 
     dock_configure();
@@ -284,7 +291,7 @@ void screen_set_num_desktops(guint num)
 
     /* move windows on desktops that will no longer exist! */
     for (it = client_list; it != NULL; it = it->next) {
-        Client *c = it->data;
+        ObClient *c = it->data;
         if (c->desktop >= num && c->desktop != DESKTOP_ALL)
             client_set_desktop(c, num - 1, FALSE);
     }
@@ -320,7 +327,7 @@ void screen_set_desktop(guint num)
     /* show windows from top to bottom */
     for (it = stacking_list; it != NULL; it = it->next) {
         if (WINDOW_IS_CLIENT(it->data)) {
-            Client *c = it->data;
+            ObClient *c = it->data;
             if (!c->frame->visible && client_should_show(c))
                 frame_show(c->frame);
         }
@@ -329,7 +336,7 @@ void screen_set_desktop(guint num)
     /* hide windows from bottom to top */
     for (it = g_list_last(stacking_list); it != NULL; it = it->prev) {
         if (WINDOW_IS_CLIENT(it->data)) {
-            Client *c = it->data;
+            ObClient *c = it->data;
             if (c->frame->visible && !client_should_show(c))
                 frame_hide(c->frame);
         }
@@ -338,42 +345,55 @@ void screen_set_desktop(guint num)
     /* focus the last focused window on the desktop, and ignore enter events
        from the switch so it doesnt mess with the focus */
     while (XCheckTypedEvent(ob_display, EnterNotify, &e));
+#ifdef DEBUG_FOCUS
     g_message("switch fallback");
-    focus_fallback(Fallback_Desktop);
+#endif
+    focus_fallback(OB_FOCUS_FALLBACK_DESKTOP);
+#ifdef DEBUG_FOCUS
     g_message("/switch fallback");
+#endif
 
     dispatch_ob(Event_Ob_Desktop, num, old);
 }
 
 void screen_update_layout()
 {
-    guint32 *data = NULL;
+    ObOrientation orient;
+    ObCorner corner;
+    guint rows;
+    guint cols;
+    guint32 *data;
     guint num;
-
-    /* defaults */
-    screen_desktop_layout.orientation = prop_atoms.net_wm_orientation_horz;
-    screen_desktop_layout.start_corner = prop_atoms.net_wm_topleft;
-    screen_desktop_layout.rows = 1;
-    screen_desktop_layout.columns = screen_num_desktops;
+    gboolean valid = FALSE;
 
     if (PROP_GETA32(ob_root, net_desktop_layout, cardinal, &data, &num)) {
         if (num == 3 || num == 4) {
+
             if (data[0] == prop_atoms.net_wm_orientation_vert)
-                screen_desktop_layout.orientation = data[0];
-            if (num == 3)
-                screen_desktop_layout.start_corner =
-                    prop_atoms.net_wm_topright;
+                orient = OB_ORIENTATION_VERT;
+            else if (data[0] == prop_atoms.net_wm_orientation_horz)
+                orient = OB_ORIENTATION_HORZ;
+            else
+                goto screen_update_layout_bail;
+
+            if (num < 4)
+                corner = OB_CORNER_TOPLEFT;
             else {
                 if (data[3] == prop_atoms.net_wm_topright)
-                    screen_desktop_layout.start_corner = data[3];
+                    corner = OB_CORNER_TOPRIGHT;
                 else if (data[3] == prop_atoms.net_wm_bottomright)
-                    screen_desktop_layout.start_corner = data[3];
+                    corner = OB_CORNER_BOTTOMRIGHT;
                 else if (data[3] == prop_atoms.net_wm_bottomleft)
-                    screen_desktop_layout.start_corner = data[3];
+                    corner = OB_CORNER_BOTTOMLEFT;
+                else
+                    goto screen_update_layout_bail;
             }
 
             /* fill in a zero rows/columns */
-            if (!(data[1] == 0 && data[2] == 0)) { /* both 0's is bad data.. */
+            if ((data[1] == 0 && data[2] == 0) || /* both 0's is bad data.. */
+                (data[1] != 0 && data[2] != 0)) { /* no 0's is bad data.. */
+                goto screen_update_layout_bail;
+            } else {
                 if (data[1] == 0) {
                     data[1] = (screen_num_desktops +
                                screen_num_desktops % data[2]) / data[2];
@@ -381,38 +401,39 @@ void screen_update_layout()
                     data[2] = (screen_num_desktops +
                                screen_num_desktops % data[1]) / data[1];
                 }
-                screen_desktop_layout.columns = data[1];
-                screen_desktop_layout.rows = data[2];
+                cols = data[1];
+                rows = data[2];
             }
 
             /* bounds checking */
-            if (screen_desktop_layout.orientation ==
-                prop_atoms.net_wm_orientation_horz) {
-                if (screen_desktop_layout.rows > screen_num_desktops)
-                    screen_desktop_layout.rows = screen_num_desktops;
-                if (screen_desktop_layout.columns >
-                    ((screen_num_desktops + screen_num_desktops %
-                      screen_desktop_layout.rows) /
-                     screen_desktop_layout.rows))
-                    screen_desktop_layout.columns =
-                        (screen_num_desktops + screen_num_desktops %
-                         screen_desktop_layout.rows) /
-                        screen_desktop_layout.rows;
+            if (orient == OB_ORIENTATION_HORZ) {
+                rows = MIN(rows, screen_num_desktops);
+                cols = MIN(cols, ((screen_num_desktops +
+                                     (screen_num_desktops % rows)) / rows));
             } else {
-                if (screen_desktop_layout.columns > screen_num_desktops)
-                    screen_desktop_layout.columns = screen_num_desktops;
-                if (screen_desktop_layout.rows >
-                    ((screen_num_desktops + screen_num_desktops %
-                      screen_desktop_layout.columns) /
-                     screen_desktop_layout.columns))
-                    screen_desktop_layout.rows =
-                        (screen_num_desktops + screen_num_desktops %
-                         screen_desktop_layout.columns) /
-                        screen_desktop_layout.columns;
+                cols = MIN(cols, screen_num_desktops);
+                rows = MIN(rows, ((screen_num_desktops +
+                                     (screen_num_desktops % cols)) / cols));
             }
+
+            valid = TRUE;
         }
-       g_free(data);
+    screen_update_layout_bail:
+        g_free(data);
+    }
+
+    if (!valid) {
+        /* defaults */
+        orient = OB_ORIENTATION_HORZ;
+        corner = OB_CORNER_TOPLEFT;
+        rows = 1;
+        cols = screen_num_desktops;
     }
+
+    screen_desktop_layout.orientation = orient;
+    screen_desktop_layout.start_corner = corner;
+    screen_desktop_layout.rows = rows;
+    screen_desktop_layout.columns = cols;
 }
 
 void screen_update_desktop_names()
@@ -448,7 +469,7 @@ void screen_show_desktop(gboolean show)
        /* bottom to top */
        for (it = g_list_last(stacking_list); it != NULL; it = it->prev) {
             if (WINDOW_IS_CLIENT(it->data)) {
-                Client *client = it->data;
+                ObClient *client = it->data;
                 if (client->frame->visible && !client_should_show(client))
                     frame_hide(client->frame);
             }
@@ -457,7 +478,7 @@ void screen_show_desktop(gboolean show)
         /* top to bottom */
        for (it = stacking_list; it != NULL; it = it->next) {
             if (WINDOW_IS_CLIENT(it->data)) {
-                Client *client = it->data;
+                ObClient *client = it->data;
                 if (!client->frame->visible && client_should_show(client))
                     frame_show(client->frame);
             }
@@ -467,11 +488,11 @@ void screen_show_desktop(gboolean show)
     if (show) {
         /* focus desktop */
         for (it = focus_order[screen_desktop]; it; it = it->next)
-            if (((Client*)it->data)->type == Type_Desktop &&
+            if (((ObClient*)it->data)->type == OB_CLIENT_TYPE_DESKTOP &&
                 client_focus(it->data))
                 break;
     } else {
-        focus_fallback(Fallback_NoFocus);
+        focus_fallback(OB_FOCUS_FALLBACK_NOFOCUS);
     }
 
     show = !!show; /* make it boolean */
@@ -480,7 +501,7 @@ void screen_show_desktop(gboolean show)
     dispatch_ob(Event_Ob_ShowDesktop, show, 0);
 }
 
-void screen_install_colormap(Client *client, gboolean install)
+void screen_install_colormap(ObClient *client, gboolean install)
 {
     XWindowAttributes wa;
 
@@ -510,8 +531,8 @@ void screen_update_areas()
     Rect **rit;
     GList *it;
 
-    g_free(xin_areas);
-    extensions_xinerama_screens(&xin_areas, &screen_num_xin_areas);
+    g_free(monitor_area);
+    extensions_xinerama_screens(&monitor_area, &screen_num_monitors);
 
     if (area) {
         for (i = 0; area[i]; ++i)
@@ -521,7 +542,7 @@ void screen_update_areas()
 
     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] = g_new(Rect, screen_num_monitors + 1);
     area[i] = NULL;
      
     dims = g_new(guint32, 4 * screen_num_desktops);
@@ -532,18 +553,18 @@ void screen_update_areas()
         int l, r, t, b;
 
         /* calc the xinerama areas */
-        for (x = 0; x < screen_num_xin_areas; ++x) {
-            area[i][x] = xin_areas[x];
+        for (x = 0; x < screen_num_monitors; ++x) {
+            area[i][x] = monitor_area[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;
+                l = monitor_area[x].x;
+                t = monitor_area[x].y;
+                r = monitor_area[x].x + monitor_area[x].width - 1;
+                b = monitor_area[x].y + monitor_area[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);
+                l = MIN(l, monitor_area[x].x);
+                t = MIN(t, monitor_area[x].y);
+                r = MAX(r, monitor_area[x].x + monitor_area[x].width - 1);
+                b = MAX(b, monitor_area[x].y + monitor_area[x].height - 1);
             }
         }
         RECT_SET(area[i][x], l, t, r - l + 1, b - t + 1);
@@ -551,7 +572,7 @@ void screen_update_areas()
         /* 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, ((ObClient*)it->data)->strut);
         STRUT_ADD(s, dock_strut);
 
         if (s.left) {
@@ -559,10 +580,10 @@ void screen_update_areas()
 
             /* 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)
+            for (x = 1; x < screen_num_monitors; ++x)
                 o = MIN(o, area[i][x].x);
 
-            for (x = 0; x < screen_num_xin_areas; ++x) {
+            for (x = 0; x < screen_num_monitors; ++x) {
                 int edge = o + s.left - area[i][x].x;
                 if (edge > 0) {
                     area[i][x].x += edge;
@@ -570,18 +591,18 @@ void screen_update_areas()
                 }
             }
 
-            area[i][screen_num_xin_areas].x += s.left;
-            area[i][screen_num_xin_areas].width -= s.left;
+            area[i][screen_num_monitors].x += s.left;
+            area[i][screen_num_monitors].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)
+            for (x = 1; x < screen_num_monitors; ++x)
                 o = MIN(o, area[i][x].y);
 
-            for (x = 0; x < screen_num_xin_areas; ++x) {
+            for (x = 0; x < screen_num_monitors; ++x) {
                 int edge = o + s.top - area[i][x].y;
                 if (edge > 0) {
                     area[i][x].y += edge;
@@ -589,47 +610,47 @@ void screen_update_areas()
                 }
             }
 
-            area[i][screen_num_xin_areas].y += s.top;
-            area[i][screen_num_xin_areas].height -= s.top;
+            area[i][screen_num_monitors].y += s.top;
+            area[i][screen_num_monitors].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)
+            for (x = 1; x < screen_num_monitors; ++x)
                 o = MAX(o, area[i][x].x + area[i][x].width - 1);
 
-            for (x = 0; x < screen_num_xin_areas; ++x) {
+            for (x = 0; x < screen_num_monitors; ++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;
+            area[i][screen_num_monitors].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)
+            for (x = 1; x < screen_num_monitors; ++x)
                 o = MAX(o, area[i][x].y + area[i][x].height - 1);
 
-            for (x = 0; x < screen_num_xin_areas; ++x) {
+            for (x = 0; x < screen_num_monitors; ++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;
+            area[i][screen_num_monitors].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) {
+        for (x = 0; x < screen_num_monitors; ++x) {
            GList *it;
 
 
@@ -640,7 +661,7 @@ void screen_update_areas()
                 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,
+                if (RECT_CONTAINS_RECT(((ObClient*)it->data)->frame->area,
                                        area[i][x])) {
 
                 }            
@@ -653,7 +674,7 @@ void screen_update_areas()
         /* the area has changed, adjust all the maximized 
            windows */
         for (it = client_list; it; it = it->next) {
-            Client *c = it->data; 
+            ObClient *c = it->data; 
             if (i < screen_num_desktops) {
                 if (c->desktop == i)
                     client_reconfigure(c);
@@ -662,10 +683,10 @@ void screen_update_areas()
         }
         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;
+            dims[(i * 4) + 0] = area[i][screen_num_monitors].x;
+            dims[(i * 4) + 1] = area[i][screen_num_monitors].y;
+            dims[(i * 4) + 2] = area[i][screen_num_monitors].width;
+            dims[(i * 4) + 3] = area[i][screen_num_monitors].height;
         }
     }
     PROP_SETA32(ob_root, net_workarea, cardinal,
@@ -676,12 +697,12 @@ void screen_update_areas()
 
 Rect *screen_area(guint desktop)
 {
-    return screen_area_xinerama(desktop, screen_num_xin_areas);
+    return screen_area_monitor(desktop, screen_num_monitors);
 }
 
-Rect *screen_area_xinerama(guint desktop, guint head)
+Rect *screen_area_monitor(guint desktop, guint head)
 {
-    if (head > screen_num_xin_areas)
+    if (head > screen_num_monitors)
         return NULL;
     if (desktop >= screen_num_desktops) {
        if (desktop == DESKTOP_ALL)
@@ -693,24 +714,24 @@ Rect *screen_area_xinerama(guint desktop, guint head)
 
 Rect *screen_physical_area()
 {
-    return screen_physical_area_xinerama(screen_num_xin_areas);
+    return screen_physical_area_monitor(screen_num_monitors);
 }
 
-Rect *screen_physical_area_xinerama(guint head)
+Rect *screen_physical_area_monitor(guint head)
 {
-    if (head > screen_num_xin_areas)
+    if (head > screen_num_monitors)
         return NULL;
-    return &xin_areas[head];
+    return &monitor_area[head];
 }
 
 static void set_root_cursor()
 {
 #ifdef USE_LIBSN
         if (sn_busy_cnt)
-            XDefineCursor(ob_display, ob_root, ob_cursors.busy);
+            XDefineCursor(ob_display, ob_root, ob_cursor(OB_CURSOR_BUSY));
         else
 #endif
-            XDefineCursor(ob_display, ob_root, ob_cursors.ptr);
+            XDefineCursor(ob_display, ob_root, ob_cursor(OB_CURSOR_POINTER));
 }
 
 #ifdef USE_LIBSN
This page took 0.036801 seconds and 4 git commands to generate.