]> Dogcows Code - chaz/openbox/blobdiff - openbox/screen.c
new popups with subclasses, added an ObIconPopup for popups with icons, and ObPagerPo...
[chaz/openbox] / openbox / screen.c
index 53ba27024f56a2b1887835bd49f49392fe369342..b1b1a561c1da8678044757f4fe9529dc883f1a49 100644 (file)
@@ -1,28 +1,26 @@
+#include "debug.h"
 #include "openbox.h"
 #include "dock.h"
 #include "xerror.h"
 #include "prop.h"
 #include "openbox.h"
 #include "dock.h"
 #include "xerror.h"
 #include "prop.h"
-#include "startup.h"
-#include "timer.h"
+#include "grab.h"
+#include "startupnotify.h"
+#include "moveresize.h"
 #include "config.h"
 #include "screen.h"
 #include "client.h"
 #include "frame.h"
 #include "focus.h"
 #include "config.h"
 #include "screen.h"
 #include "client.h"
 #include "frame.h"
 #include "focus.h"
-#include "dispatch.h"
+#include "popup.h"
 #include "extensions.h"
 #include "render/render.h"
 
 #include "extensions.h"
 #include "render/render.h"
 
-#ifdef USE_LIBSN
-#  define SN_API_NOT_YET_FROZEN
-#  include <libsn/sn.h>
-#endif
-
 #include <X11/Xlib.h>
 #ifdef HAVE_UNISTD_H
 #  include <sys/types.h>
 #  include <unistd.h>
 #endif
 #include <X11/Xlib.h>
 #ifdef HAVE_UNISTD_H
 #  include <sys/types.h>
 #  include <unistd.h>
 #endif
+#include <assert.h>
 
 /*! The event mask to grab on the root window */
 #define ROOT_EVENTMASK (StructureNotifyMask | PropertyChangeMask | \
 
 /*! The event mask to grab on the root window */
 #define ROOT_EVENTMASK (StructureNotifyMask | PropertyChangeMask | \
                        SubstructureNotifyMask | SubstructureRedirectMask | \
                        ButtonPressMask | ButtonReleaseMask | ButtonMotionMask)
 
                        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;
+guint    screen_last_desktop;
 Size     screen_physical_size;
 gboolean screen_showing_desktop;
 DesktopLayout screen_desktop_layout;
 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 ObPagerPopup *desktop_cycle_popup;
 
 
-static void sn_event_func(SnMonitorEvent *event, void *data);
-#endif
+static gboolean replace_wm()
+{
+    char *wm_sn;
+    Atom wm_sn_atom;
+    Window current_wm_sn_owner;
+    Time timestamp;
+
+    wm_sn = g_strdup_printf("WM_S%d", ob_screen);
+    wm_sn_atom = XInternAtom(ob_display, wm_sn, FALSE);
+    g_free(wm_sn);
+
+    current_wm_sn_owner = XGetSelectionOwner(ob_display, wm_sn_atom);
+    if (current_wm_sn_owner) {
+        if (!ob_replace_wm) {
+            g_warning("A window manager is already running on screen %d",
+                      ob_screen);
+            return FALSE;
+        }
+        xerror_set_ignore(TRUE);
+        xerror_occured = FALSE;
 
 
-static void set_root_cursor();
+        /* We want to find out when the current selection owner dies */
+        XSelectInput(ob_display, current_wm_sn_owner, StructureNotifyMask);
+        XSync(ob_display, FALSE);
 
 
-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;
+        xerror_set_ignore(FALSE);
+        if (xerror_occured)
+            current_wm_sn_owner = None;
+    }
+
+    {
+        /* Generate a timestamp */
+        XEvent event;
+
+        XSelectInput(ob_display, screen_support_win, PropertyChangeMask);
+
+        XChangeProperty(ob_display, screen_support_win,
+                        prop_atoms.wm_class, prop_atoms.string,
+                        8, PropModeAppend, NULL, 0);
+        XWindowEvent(ob_display, screen_support_win,
+                     PropertyChangeMask, &event);
+
+        XSelectInput(ob_display, screen_support_win, NoEventMask);
+
+        timestamp = event.xproperty.time;
+    }
+
+    XSetSelectionOwner(ob_display, wm_sn_atom, screen_support_win,
+                       timestamp);
+
+    if (XGetSelectionOwner(ob_display, wm_sn_atom) != screen_support_win) {
+        g_warning("Could not acquire window manager selection on screen %d",
+                  ob_screen);
+        return FALSE;
+    }
+
+    /* Wait for old window manager to go away */
+    if (current_wm_sn_owner) {
+      XEvent event;
+      gulong wait = 0;
+      const gulong timeout = G_USEC_PER_SEC * 15; /* wait for 15s max */
+
+      while (wait < timeout) {
+          if (XCheckWindowEvent(ob_display, current_wm_sn_owner,
+                                StructureNotifyMask, &event) &&
+              event.type == DestroyNotify)
+              break;
+          g_usleep(G_USEC_PER_SEC / 10);
+          wait += G_USEC_PER_SEC / 10;
+      }
+
+      if (wait >= timeout) {
+          g_warning("Timeout expired while waiting for the current WM to die "
+                    "on screen %d", ob_screen);
+          return FALSE;
+      }
+    }
+
+    /* Send client message indicating that we are now the WM */
+    prop_message(RootWindow(ob_display, ob_screen), prop_atoms.manager,
+                 timestamp, wm_sn_atom, 0, 0, SubstructureNotifyMask);
+
+
+    return TRUE;
 }
 
 gboolean screen_annex()
 {
 }
 
 gboolean screen_annex()
 {
-    XErrorHandler old;
+    XSetWindowAttributes attrib;
     pid_t pid;
     pid_t pid;
-    int i, num_support;
+    gint i, num_support;
     guint32 *supported;
 
     guint32 *supported;
 
-    running = FALSE;
-    old = XSetErrorHandler(another_running);
-    XSelectInput(ob_display, ob_root, ROOT_EVENTMASK);
-    XSync(ob_display, FALSE);
-    XSetErrorHandler(old);
-    if (running)
+    /* create the netwm support window */
+    attrib.override_redirect = TRUE;
+    screen_support_win = XCreateWindow(ob_display,
+                                       RootWindow(ob_display, ob_screen),
+                                       -100, -100, 1, 1, 0,
+                                       CopyFromParent, InputOutput,
+                                       CopyFromParent,
+                                       CWOverrideRedirect, &attrib);
+    XMapRaised(ob_display, screen_support_win);
+
+    if (!replace_wm()) {
+        XDestroyWindow(ob_display, screen_support_win);
+        return FALSE;
+    }
+
+    xerror_set_ignore(TRUE);
+    xerror_occured = FALSE;
+    XSelectInput(ob_display, RootWindow(ob_display, ob_screen),
+                 ROOT_EVENTMASK);
+    xerror_set_ignore(FALSE);
+    if (xerror_occured) {
+        g_warning("A window manager is already running on screen %d",
+                  ob_screen);
+
+        XDestroyWindow(ob_display, screen_support_win);
        return FALSE;
        return FALSE;
+    }
 
 
-    g_message("Managing screen %d", ob_screen);
 
 
-    set_root_cursor();
+    screen_set_root_cursor();
 
     /* set the OPENBOX_PID hint */
     pid = getpid();
 
     /* set the OPENBOX_PID hint */
     pid = getpid();
-    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);
+    PROP_SET32(RootWindow(ob_display, ob_screen),
+               openbox_pid, cardinal, pid);
 
     /* set supporting window */
 
     /* set supporting window */
-    PROP_SET32(ob_root, net_supporting_wm_check, window, support_window);
+    PROP_SET32(RootWindow(ob_display, ob_screen),
+               net_supporting_wm_check, window, screen_support_win);
 
     /* set properties on the supporting window */
 
     /* set properties on the supporting window */
-    PROP_SETS(support_window, net_wm_name, "Openbox3");
-    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 */
 
     /* set the _NET_SUPPORTED_ATOMS hint */
-    num_support = 61;
+    num_support = 50;
     i = 0;
     supported = g_new(guint32, num_support);
     supported[i++] = prop_atoms.net_current_desktop;
     i = 0;
     supported = g_new(guint32, num_support);
     supported[i++] = prop_atoms.net_current_desktop;
@@ -150,36 +235,28 @@ gboolean screen_annex()
     supported[i++] = prop_atoms.net_wm_state_below;
     supported[i++] = prop_atoms.net_moveresize_window;
     supported[i++] = prop_atoms.net_wm_moveresize;
     supported[i++] = prop_atoms.net_wm_state_below;
     supported[i++] = prop_atoms.net_moveresize_window;
     supported[i++] = prop_atoms.net_wm_moveresize;
-    supported[i++] = prop_atoms.net_wm_moveresize_size_topleft;
-    supported[i++] = prop_atoms.net_wm_moveresize_size_top;
-    supported[i++] = prop_atoms.net_wm_moveresize_size_topright;
-    supported[i++] = prop_atoms.net_wm_moveresize_size_right;
-    supported[i++] = prop_atoms.net_wm_moveresize_size_bottomright;
-    supported[i++] = prop_atoms.net_wm_moveresize_size_bottom;
-    supported[i++] = prop_atoms.net_wm_moveresize_size_bottomleft;
-    supported[i++] = prop_atoms.net_wm_moveresize_size_left;
-    supported[i++] = prop_atoms.net_wm_moveresize_move;
-    supported[i++] = prop_atoms.net_wm_moveresize_size_keyboard;
-    supported[i++] = prop_atoms.net_wm_moveresize_move_keyboard;
     g_assert(i == num_support);
 /*
   supported[] = prop_atoms.net_wm_action_stick;
 */
 
     g_assert(i == num_support);
 /*
   supported[] = prop_atoms.net_wm_action_stick;
 */
 
-    PROP_SETA32(ob_root, net_supported, atom, supported, num_support);
+    PROP_SETA32(RootWindow(ob_display, ob_screen),
+                net_supported, atom, supported, num_support);
     g_free(supported);
 
     return TRUE;
 }
 
     g_free(supported);
 
     return TRUE;
 }
 
-void screen_startup()
+void screen_startup(gboolean reconfig)
 {
     GSList *it;
     guint i;
 
 {
     GSList *it;
     guint i;
 
-    /* get the initial size */
-    screen_resize(WidthOfScreen(ScreenOfDisplay(ob_display, ob_screen)),
-                  HeightOfScreen(ScreenOfDisplay(ob_display, ob_screen)));
+    desktop_cycle_popup = pager_popup_new(FALSE);
+
+    if (!reconfig)
+        /* get the initial size */
+        screen_resize();
 
     /* set the names */
     screen_desktop_names = g_new(char*,
 
     /* set the names */
     screen_desktop_names = g_new(char*,
@@ -187,66 +264,82 @@ void screen_startup()
     for (i = 0, it = config_desktops_names; it; ++i, it = it->next)
         screen_desktop_names[i] = it->data; /* dont strdup */
     screen_desktop_names[i] = NULL;
     for (i = 0, it = config_desktops_names; it; ++i, it = it->next)
         screen_desktop_names[i] = it->data; /* dont strdup */
     screen_desktop_names[i] = NULL;
-    PROP_SETSS(ob_root, net_desktop_names, screen_desktop_names);
+    PROP_SETSS(RootWindow(ob_display, ob_screen),
+               net_desktop_names, screen_desktop_names);
     g_free(screen_desktop_names); /* dont free the individual strings */
     screen_desktop_names = NULL;
 
     g_free(screen_desktop_names); /* dont free the individual strings */
     screen_desktop_names = NULL;
 
-    screen_num_desktops = 0;
+    if (!reconfig)
+        screen_num_desktops = 0;
     screen_set_num_desktops(config_desktops_num);
     screen_set_num_desktops(config_desktops_num);
-    if (startup_desktop >= screen_num_desktops)
-        startup_desktop = 0;
-    screen_desktop = startup_desktop;
-    screen_set_desktop(startup_desktop);
-
-    /* don't start in showing-desktop mode */
-    screen_showing_desktop = FALSE;
-    PROP_SET32(ob_root, net_showing_desktop, cardinal, screen_showing_desktop);
+    if (!reconfig) {
+        screen_set_desktop(0);
 
 
-    screen_update_layout();
+        /* don't start in showing-desktop mode */
+        screen_showing_desktop = FALSE;
+        PROP_SET32(RootWindow(ob_display, ob_screen),
+                   net_showing_desktop, cardinal, screen_showing_desktop);
 
 
-#ifdef USE_LIBSN
-    sn_context = sn_monitor_context_new(ob_sn_display, ob_screen,
-                                        sn_event_func, NULL, NULL);
-    sn_busy_cnt = 0;
-#endif
+        screen_update_layout();
+    }
 }
 
 }
 
-void screen_shutdown()
+void screen_shutdown(gboolean reconfig)
 {
     Rect **r;
 
 {
     Rect **r;
 
-    XSelectInput(ob_display, ob_root, NoEventMask);
+    pager_popup_free(desktop_cycle_popup);
+
+    if (!reconfig) {
+        XSelectInput(ob_display, RootWindow(ob_display, ob_screen),
+                     NoEventMask);
 
 
-    PROP_ERASE(ob_root, openbox_pid); /* we're not running here no more! */
-    PROP_ERASE(ob_root, net_supported); /* not without us */
-    PROP_ERASE(ob_root, net_showing_desktop); /* don't keep this mode */
+        /* we're not running here no more! */
+        PROP_ERASE(RootWindow(ob_display, ob_screen), openbox_pid);
+        /* not without us */
+        PROP_ERASE(RootWindow(ob_display, ob_screen), net_supported);
+        /* don't keep this mode */
+        PROP_ERASE(RootWindow(ob_display, ob_screen), net_showing_desktop);
 
 
-    XDestroyWindow(ob_display, support_window);
+        XDestroyWindow(ob_display, screen_support_win);
+    }
 
     g_strfreev(screen_desktop_names);
 
     g_strfreev(screen_desktop_names);
+    screen_desktop_names = NULL;
     for (r = area; *r; ++r)
         g_free(*r);
     g_free(area);
     for (r = area; *r; ++r)
         g_free(*r);
     g_free(area);
+    area = NULL;
 }
 
 }
 
-void screen_resize(int w, int h)
+void screen_resize()
 {
 {
+    static int oldw = 0, oldh = 0;
+    int w, h;
     GList *it;
     guint32 geometry[2];
 
     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;
     /* 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);
+    PROP_SETA32(RootWindow(ob_display, ob_screen),
+                net_desktop_geometry, cardinal, geometry, 2);
 
 
-    if (ob_state == State_Starting)
+    if (ob_state() == OB_STATE_STARTING)
        return;
 
        return;
 
-    dock_configure();
     screen_update_areas();
     screen_update_areas();
+    dock_configure();
 
     for (it = client_list; it; it = it->next)
 
     for (it = client_list; it; it = it->next)
-        client_move_onscreen(it->data);
+        client_move_onscreen(it->data, FALSE);
 }
 
 void screen_set_num_desktops(guint num)
 }
 
 void screen_set_num_desktops(guint num)
@@ -259,11 +352,13 @@ void screen_set_num_desktops(guint num)
 
     old = screen_num_desktops;
     screen_num_desktops = num;
 
     old = screen_num_desktops;
     screen_num_desktops = num;
-    PROP_SET32(ob_root, net_number_of_desktops, cardinal, num);
+    PROP_SET32(RootWindow(ob_display, ob_screen),
+               net_number_of_desktops, cardinal, num);
 
     /* set the viewport hint */
     viewport = g_new0(guint32, num * 2);
 
     /* set the viewport hint */
     viewport = g_new0(guint32, num * 2);
-    PROP_SETA32(ob_root, net_desktop_viewport, cardinal, viewport, num * 2);
+    PROP_SETA32(RootWindow(ob_display, ob_screen),
+                net_desktop_viewport, cardinal, viewport, num * 2);
     g_free(viewport);
 
     /* the number of rows/columns will differ */
     g_free(viewport);
 
     /* the number of rows/columns will differ */
@@ -272,31 +367,29 @@ void screen_set_num_desktops(guint num)
     /* may be some unnamed desktops that we need to fill in with names */
     screen_update_desktop_names();
 
     /* may be some unnamed desktops that we need to fill in with names */
     screen_update_desktop_names();
 
-    /* update the focus lists */
-    /* free our lists for the desktops which have disappeared */
-    for (i = num; i < old; ++i)
-        g_list_free(focus_order[i]);
-    /* realloc the array */
-    focus_order = g_renew(GList*, focus_order, num);
-    /* set the new lists to be empty */
-    for (i = old; i < num; ++i)
-        focus_order[i] = NULL;
-
     /* move windows on desktops that will no longer exist! */
     for (it = client_list; it != NULL; it = it->next) {
     /* 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);
     }
         if (c->desktop >= num && c->desktop != DESKTOP_ALL)
             client_set_desktop(c, num - 1, FALSE);
     }
-
     /* change our struts/area to match (after moving windows) */
     screen_update_areas();
 
     /* change our struts/area to match (after moving windows) */
     screen_update_areas();
 
-    dispatch_ob(Event_Ob_NumDesktops, num, old);
-
     /* change our desktop if we're on one that no longer exists! */
     if (screen_desktop >= screen_num_desktops)
        screen_set_desktop(num - 1);
     /* change our desktop if we're on one that no longer exists! */
     if (screen_desktop >= screen_num_desktops)
        screen_set_desktop(num - 1);
+
+   /* update the focus lists */
+    /* free our lists for the desktops which have disappeared */
+    for (i = num; i < old; ++i)
+        g_list_free(focus_order[i]);
+    /* realloc the array */
+    focus_order = g_renew(GList*, focus_order, num);
+    /* set the new lists to be empty */
+    for (i = old; i < num; ++i)
+        focus_order[i] = NULL;
 }
 
 void screen_set_desktop(guint num)
 }
 
 void screen_set_desktop(guint num)
@@ -309,18 +402,24 @@ void screen_set_desktop(guint num)
 
     old = screen_desktop;
     screen_desktop = num;
 
     old = screen_desktop;
     screen_desktop = num;
-    PROP_SET32(ob_root, net_current_desktop, cardinal, num);
+    PROP_SET32(RootWindow(ob_display, ob_screen),
+               net_current_desktop, cardinal, num);
 
     if (old == num) return;
 
 
     if (old == num) return;
 
-    g_message("Moving to desktop %d", num+1);
+    screen_last_desktop = old;
+
+    ob_debug("Moving to desktop %d\n", num+1);
+
+    if (moveresize_client)
+        client_set_desktop(moveresize_client, num, TRUE);
 
     /* show windows before hiding the rest to lessen the enter/leave events */
 
     /* show windows from top to bottom */
     for (it = stacking_list; it != NULL; it = it->next) {
         if (WINDOW_IS_CLIENT(it->data)) {
 
     /* show windows before hiding the rest to lessen the enter/leave events */
 
     /* 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);
         }
             if (!c->frame->visible && client_should_show(c))
                 frame_show(c->frame);
         }
@@ -329,90 +428,353 @@ 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)) {
     /* 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);
         }
     }
 
             if (c->frame->visible && !client_should_show(c))
                 frame_hide(c->frame);
         }
     }
 
+    XSync(ob_display, FALSE);
     /* 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));
     /* 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));
-    g_message("switch fallback");
-    focus_fallback(Fallback_Desktop);
-    g_message("/switch fallback");
+#ifdef DEBUG_FOCUS
+    ob_debug("switch fallback\n");
+#endif
+    focus_fallback(OB_FOCUS_FALLBACK_DESKTOP);
+#ifdef DEBUG_FOCUS
+    ob_debug("/switch fallback\n");
+#endif
+}
+
+static void get_row_col(guint d, guint *r, guint *c)
+{
+    switch (screen_desktop_layout.orientation) {
+    case OB_ORIENTATION_HORZ:
+        switch (screen_desktop_layout.start_corner) {
+        case OB_CORNER_TOPLEFT:
+            *r = d / screen_desktop_layout.columns;
+            *c = d % screen_desktop_layout.columns;
+            break;
+        case OB_CORNER_BOTTOMLEFT:
+            *r = screen_desktop_layout.rows - 1 -
+                d / screen_desktop_layout.columns;
+            *c = d % screen_desktop_layout.columns;
+            break;
+        case OB_CORNER_TOPRIGHT:
+            *r = d / screen_desktop_layout.columns;
+            *c = screen_desktop_layout.columns - 1 -
+                d % screen_desktop_layout.columns;
+            break;
+        case OB_CORNER_BOTTOMRIGHT:
+            *r = screen_desktop_layout.rows - 1 -
+                d / screen_desktop_layout.columns;
+            *c = screen_desktop_layout.columns - 1 -
+                d % screen_desktop_layout.columns;
+            break;
+        }
+        break;
+    case OB_ORIENTATION_VERT:
+        switch (screen_desktop_layout.start_corner) {
+        case OB_CORNER_TOPLEFT:
+            *r = d % screen_desktop_layout.rows;
+            *c = d / screen_desktop_layout.rows;
+            break;
+        case OB_CORNER_BOTTOMLEFT:
+            *r = screen_desktop_layout.rows - 1 -
+                d % screen_desktop_layout.rows;
+            *c = d / screen_desktop_layout.rows;
+            break;
+        case OB_CORNER_TOPRIGHT:
+            *r = d % screen_desktop_layout.rows;
+            *c = screen_desktop_layout.columns - 1 -
+                d / screen_desktop_layout.rows;
+            break;
+        case OB_CORNER_BOTTOMRIGHT:
+            *r = screen_desktop_layout.rows - 1 -
+                d % screen_desktop_layout.rows;
+            *c = screen_desktop_layout.columns - 1 -
+                d / screen_desktop_layout.rows;
+            break;
+        }
+        break;
+    }
+}
+
+static guint translate_row_col(guint r, guint c)
+{
+    switch (screen_desktop_layout.orientation) {
+    case OB_ORIENTATION_HORZ:
+        switch (screen_desktop_layout.start_corner) {
+        case OB_CORNER_TOPLEFT:
+            return r % screen_desktop_layout.rows *
+                screen_desktop_layout.columns +
+                c % screen_desktop_layout.columns;
+        case OB_CORNER_BOTTOMLEFT:
+            return (screen_desktop_layout.rows - 1 -
+                    r % screen_desktop_layout.rows) *
+                screen_desktop_layout.columns +
+                c % screen_desktop_layout.columns;
+        case OB_CORNER_TOPRIGHT:
+            return r % screen_desktop_layout.rows *
+                screen_desktop_layout.columns +
+                (screen_desktop_layout.columns - 1 -
+                 c % screen_desktop_layout.columns);
+        case OB_CORNER_BOTTOMRIGHT:
+            return (screen_desktop_layout.rows - 1 -
+                    r % screen_desktop_layout.rows) *
+                screen_desktop_layout.columns +
+                (screen_desktop_layout.columns - 1 -
+                 c % screen_desktop_layout.columns);
+        }
+    case OB_ORIENTATION_VERT:
+        switch (screen_desktop_layout.start_corner) {
+        case OB_CORNER_TOPLEFT:
+            return c % screen_desktop_layout.columns *
+                screen_desktop_layout.rows +
+                r % screen_desktop_layout.rows;
+        case OB_CORNER_BOTTOMLEFT:
+            return c % screen_desktop_layout.columns *
+                screen_desktop_layout.rows +
+                (screen_desktop_layout.rows - 1 -
+                 r % screen_desktop_layout.rows);
+        case OB_CORNER_TOPRIGHT:
+            return (screen_desktop_layout.columns - 1 -
+                    c % screen_desktop_layout.columns) *
+                screen_desktop_layout.rows +
+                r % screen_desktop_layout.rows;
+        case OB_CORNER_BOTTOMRIGHT:
+            return (screen_desktop_layout.columns - 1 -
+                    c % screen_desktop_layout.columns) *
+                screen_desktop_layout.rows +
+                (screen_desktop_layout.rows - 1 -
+                 r % screen_desktop_layout.rows);
+        }
+    }
+    g_assert_not_reached();
+    return 0;
+}
+
+static void popup_cycle(guint d, gboolean show)
+{
+    Rect *a;
+
+    if (!show) {
+        pager_popup_hide(desktop_cycle_popup);
+    } else {
+        a = screen_physical_area_monitor(0);
+        pager_popup_position(desktop_cycle_popup, CenterGravity,
+                             a->x + a->width / 2, a->y + a->height / 2);
+        /* XXX the size and the font extents need to be related on some level
+         */
+        pager_popup_size(desktop_cycle_popup, POPUP_WIDTH, POPUP_HEIGHT);
 
 
-    dispatch_ob(Event_Ob_Desktop, num, old);
+        pager_popup_set_text_align(desktop_cycle_popup, RR_JUSTIFY_CENTER);
+
+        pager_popup_show(desktop_cycle_popup, screen_desktop_names[d], d);
+    }
+}
+
+guint screen_cycle_desktop(ObDirection dir, gboolean wrap, gboolean linear,
+                           gboolean dialog, gboolean done, gboolean cancel)
+{
+    static gboolean first = TRUE;
+    static gboolean lin;
+    static guint origd, d;
+    guint r, c;
+
+    if (cancel) {
+        d = origd;
+        goto done_cycle;
+    } else if (done && dialog) {
+        goto done_cycle;
+    }
+    if (first) {
+        first = FALSE;
+        lin = linear;
+        d = origd = screen_desktop;
+    }
+
+    get_row_col(d, &r, &c);
+
+    if (lin) {
+        switch (dir) {
+        case OB_DIRECTION_EAST:
+            if (d < screen_num_desktops - 1)
+                ++d;
+            else if (wrap)
+                d = 0;
+            break;
+        case OB_DIRECTION_WEST:
+            if (d > 0)
+                --d;
+            else if (wrap)
+                d = screen_num_desktops - 1;
+            break;
+        default:
+            assert(0);
+            return screen_desktop;
+        }
+    } else {
+        switch (dir) {
+        case OB_DIRECTION_EAST:
+            ++c;
+            if (c >= screen_desktop_layout.columns) {
+                if (!wrap) return d = screen_desktop;
+                c = 0;
+            }
+            d = translate_row_col(r, c);
+            if (d >= screen_num_desktops) {
+                if (!wrap) return d = screen_desktop;
+                ++c;
+            }
+            break;
+        case OB_DIRECTION_WEST:
+            --c;
+            if (c >= screen_desktop_layout.columns) {
+                if (!wrap) return d = screen_desktop;
+                c = screen_desktop_layout.columns - 1;
+            }
+            d = translate_row_col(r, c);
+            if (d >= screen_num_desktops) {
+                if (!wrap) return d = screen_desktop;
+                --c;
+            }
+            break;
+        case OB_DIRECTION_SOUTH:
+            ++r;
+            if (r >= screen_desktop_layout.rows) {
+                if (!wrap) return d = screen_desktop;
+                r = 0;
+            }
+            d = translate_row_col(r, c);
+            if (d >= screen_num_desktops) {
+                if (!wrap) return d = screen_desktop;
+                ++r;
+            }
+            break;
+        case OB_DIRECTION_NORTH:
+            --r;
+            if (r >= screen_desktop_layout.rows) {
+                if (!wrap) return d = screen_desktop;
+                r = screen_desktop_layout.rows - 1;
+            }
+            d = translate_row_col(r, c);
+            if (d >= screen_num_desktops) {
+                if (!wrap) return d = screen_desktop;
+                --r;
+            }
+            break;
+        default:
+            assert(0);
+            return d = screen_desktop;
+        }
+
+        d = translate_row_col(r, c);
+    }
+
+    if (dialog) {
+        popup_cycle(d, TRUE);
+        return d;
+    }
+
+done_cycle:
+    first = TRUE;
+
+    popup_cycle(0, FALSE);
+
+    return d;
 }
 
 void screen_update_layout()
 {
 }
 
 void screen_update_layout()
 {
-    guint32 *data = NULL;
+    ObOrientation orient;
+    ObCorner corner;
+    guint rows;
+    guint cols;
+    guint32 *data;
     guint num;
     guint num;
+    gboolean valid = FALSE;
 
 
-    /* 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;
-
-    if (PROP_GETA32(ob_root, net_desktop_layout, cardinal, &data, &num)) {
+    if (PROP_GETA32(RootWindow(ob_display, ob_screen),
+                    net_desktop_layout, cardinal, &data, &num)) {
         if (num == 3 || num == 4) {
         if (num == 3 || num == 4) {
+
             if (data[0] == prop_atoms.net_wm_orientation_vert)
             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 {
             else {
-                if (data[3] == prop_atoms.net_wm_topright)
-                    screen_desktop_layout.start_corner = data[3];
+                if (data[3] == prop_atoms.net_wm_topleft)
+                    corner = OB_CORNER_TOPLEFT;
+                else if (data[3] == prop_atoms.net_wm_topright)
+                    corner = OB_CORNER_TOPRIGHT;
                 else if (data[3] == prop_atoms.net_wm_bottomright)
                 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)
                 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;
             }
 
             }
 
+            cols = data[1];
+            rows = data[2];
+
             /* fill in a zero rows/columns */
             /* fill in a zero rows/columns */
-            if (!(data[1] == 0 && data[2] == 0)) { /* both 0's is bad data.. */
-                if (data[1] == 0) {
-                    data[1] = (screen_num_desktops +
-                               screen_num_desktops % data[2]) / data[2];
-                } else if (data[2] == 0) {
-                    data[2] = (screen_num_desktops +
-                               screen_num_desktops % data[1]) / data[1];
+            if ((cols == 0 && rows == 0)) { /* both 0's is bad data.. */
+                goto screen_update_layout_bail;
+            } else {
+                if (cols == 0) {
+                    cols = screen_num_desktops / rows;
+                    if (rows * cols < screen_num_desktops)
+                        cols++;
+                    if (rows * cols >= screen_num_desktops + cols)
+                        rows--;
+                } else if (rows == 0) {
+                    rows = screen_num_desktops / rows;
+                    if (cols * rows < screen_num_desktops)
+                        rows++;
+                    if (cols * rows >= screen_num_desktops + rows)
+                        cols--;
                 }
                 }
-                screen_desktop_layout.columns = data[1];
-                screen_desktop_layout.rows = data[2];
             }
 
             /* bounds checking */
             }
 
             /* 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) {
+                cols = MIN(screen_num_desktops, cols);
+                rows = MIN(rows, (screen_num_desktops + cols - 1) / cols);
+                cols = screen_num_desktops / rows +
+                    !!(screen_num_desktops % rows);
             } else {
             } 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;
+                rows = MIN(screen_num_desktops, rows);
+                cols = MIN(cols, (screen_num_desktops + rows - 1) / rows);
+                rows = screen_num_desktops / cols +
+                    !!(screen_num_desktops % 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()
 }
 
 void screen_update_desktop_names()
@@ -423,7 +785,8 @@ void screen_update_desktop_names()
     g_strfreev(screen_desktop_names);
     screen_desktop_names = NULL;
 
     g_strfreev(screen_desktop_names);
     screen_desktop_names = NULL;
 
-    if (PROP_GETSS(ob_root, net_desktop_names, utf8, &screen_desktop_names))
+    if (PROP_GETSS(RootWindow(ob_display, ob_screen),
+                   net_desktop_names, utf8, &screen_desktop_names))
         for (i = 0; screen_desktop_names[i] && i <= screen_num_desktops; ++i);
     else
         i = 0;
         for (i = 0; screen_desktop_names[i] && i <= screen_num_desktops; ++i);
     else
         i = 0;
@@ -448,7 +811,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)) {
        /* 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);
             }
                 if (client->frame->visible && !client_should_show(client))
                     frame_hide(client->frame);
             }
@@ -457,7 +820,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)) {
         /* 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);
             }
                 if (!client->frame->visible && client_should_show(client))
                     frame_show(client->frame);
             }
@@ -467,20 +830,19 @@ void screen_show_desktop(gboolean show)
     if (show) {
         /* focus desktop */
         for (it = focus_order[screen_desktop]; it; it = it->next)
     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 {
                 client_focus(it->data))
                 break;
     } else {
-        focus_fallback(Fallback_NoFocus);
+        focus_fallback(OB_FOCUS_FALLBACK_NOFOCUS);
     }
 
     show = !!show; /* make it boolean */
     }
 
     show = !!show; /* make it boolean */
-    PROP_SET32(ob_root, net_showing_desktop, cardinal, show);
-
-    dispatch_ob(Event_Ob_ShowDesktop, show, 0);
+    PROP_SET32(RootWindow(ob_display, ob_screen),
+               net_showing_desktop, cardinal, show);
 }
 
 }
 
-void screen_install_colormap(Client *client, gboolean install)
+void screen_install_colormap(ObClient *client, gboolean install)
 {
     XWindowAttributes wa;
 
 {
     XWindowAttributes wa;
 
@@ -506,12 +868,10 @@ void screen_update_areas()
 {
     guint i, x;
     guint32 *dims;
 {
     guint i, x;
     guint32 *dims;
-    Rect **old_area = area;
-    Rect **rit;
     GList *it;
 
     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)
 
     if (area) {
         for (i = 0; area[i]; ++i)
@@ -521,29 +881,28 @@ void screen_update_areas()
 
     area = g_new(Rect*, screen_num_desktops + 2);
     for (i = 0; i < screen_num_desktops + 1; ++i)
 
     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);
 
     area[i] = NULL;
      
     dims = g_new(guint32, 4 * screen_num_desktops);
 
-    rit = old_area;
     for (i = 0; i < screen_num_desktops + 1; ++i) {
         Strut s;
         int l, r, t, b;
 
         /* calc the xinerama areas */
     for (i = 0; i < screen_num_desktops + 1; ++i) {
         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];
+        for (x = 0; x < screen_num_monitors; ++x) {
+            area[i][x] = monitor_area[x];
             if (x == 0) {
             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 {
             } 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);
             }
         }
         RECT_SET(area[i][x], l, t, r - l + 1, b - t + 1);
@@ -551,7 +910,7 @@ void screen_update_areas()
         /* apply struts */
         STRUT_SET(s, 0, 0, 0, 0);
         for (it = client_list; it; it = it->next)
         /* 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) {
         STRUT_ADD(s, dock_strut);
 
         if (s.left) {
@@ -559,10 +918,10 @@ void screen_update_areas()
 
             /* find the left-most xin heads, i do this in 2 loops :| */
             o = area[i][0].x;
 
             /* 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);
 
                 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;
                 int edge = o + s.left - area[i][x].x;
                 if (edge > 0) {
                     area[i][x].x += edge;
@@ -570,18 +929,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;
         }
         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);
 
                 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;
                 int edge = o + s.top - area[i][x].y;
                 if (edge > 0) {
                     area[i][x].y += edge;
@@ -589,47 +948,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;
         }
         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);
 
                 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;
             }
 
                 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;
         }
         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);
 
                 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;
             }
 
                 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
         }
 
         /* 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;
 
 
            GList *it;
 
 
@@ -640,7 +999,7 @@ void screen_update_areas()
                 XXX if gunna test this shit, then gotta worry about when
                 the client moves between xinerama heads..
 
                 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])) {
 
                 }            
                                        area[i][x])) {
 
                 }            
@@ -653,7 +1012,7 @@ void screen_update_areas()
         /* the area has changed, adjust all the maximized 
            windows */
         for (it = client_list; it; it = it->next) {
         /* 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);
             if (i < screen_num_desktops) {
                 if (c->desktop == i)
                     client_reconfigure(c);
@@ -662,26 +1021,26 @@ void screen_update_areas()
         }
         if (i < screen_num_desktops) {
             /* don't set these for the 'all desktops' area */
         }
         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,
-               dims, 4 * screen_num_desktops);
+    PROP_SETA32(RootWindow(ob_display, ob_screen), net_workarea, cardinal,
+                dims, 4 * screen_num_desktops);
 
     g_free(dims);
 }
 
 Rect *screen_area(guint desktop)
 {
 
     g_free(dims);
 }
 
 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)
         return NULL;
     if (desktop >= screen_num_desktops) {
        if (desktop == DESKTOP_ALL)
@@ -693,77 +1052,32 @@ Rect *screen_area_xinerama(guint desktop, guint head)
 
 Rect *screen_physical_area()
 {
 
 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 NULL;
-    return &xin_areas[head];
-}
-
-static void set_root_cursor()
-{
-#ifdef USE_LIBSN
-        if (sn_busy_cnt)
-            XDefineCursor(ob_display, ob_root, ob_cursors.busy);
-        else
-#endif
-            XDefineCursor(ob_display, ob_root, ob_cursors.ptr);
+    return &monitor_area[head];
 }
 
 }
 
-#ifdef USE_LIBSN
-static void sn_timeout(void *data)
+void screen_set_root_cursor()
 {
 {
-    timer_stop(sn_timer);
-    sn_timer = NULL;
-    sn_busy_cnt = 0;
-
-    set_root_cursor();
+    if (sn_app_starting())
+        XDefineCursor(ob_display, RootWindow(ob_display, ob_screen),
+                      ob_cursor(OB_CURSOR_BUSY));
+    else
+        XDefineCursor(ob_display, RootWindow(ob_display, ob_screen),
+                      ob_cursor(OB_CURSOR_POINTER));
 }
 
 }
 
-static void sn_event_func(SnMonitorEvent *ev, void *data)
+gboolean screen_pointer_pos(int *x, int *y)
 {
 {
-    SnStartupSequence *seq;
-    const char *seq_id, *bin_name;
-    int cnt = sn_busy_cnt;
-
-    if (!(seq = sn_monitor_event_get_startup_sequence(ev)))
-        return;
-
-    seq_id = sn_startup_sequence_get_id(seq);
-    bin_name = sn_startup_sequence_get_binary_name(seq);
-    
-    if (!(seq_id && bin_name))
-        return;
-
-    switch (sn_monitor_event_get_type(ev)) {
-    case SN_MONITOR_EVENT_INITIATED:
-        ++sn_busy_cnt;
-        if (sn_timer)
-            timer_stop(sn_timer);
-        /* 30 second timeout for apps to start */
-        sn_timer = timer_start(30 * 1000000, sn_timeout, NULL);
-        break;
-    case SN_MONITOR_EVENT_CHANGED:
-        break;
-    case SN_MONITOR_EVENT_COMPLETED:
-        if (sn_busy_cnt) --sn_busy_cnt;
-        if (sn_timer) {
-            timer_stop(sn_timer);
-            sn_timer = NULL;
-        }
-        break;
-    case SN_MONITOR_EVENT_CANCELED:
-        if (sn_busy_cnt) --sn_busy_cnt;
-        if (sn_timer) {
-            timer_stop(sn_timer);
-            sn_timer = NULL;
-        }
-    };
+    Window w;
+    int i;
+    guint u;
 
 
-    if (sn_busy_cnt != cnt)
-        set_root_cursor();
+    return !!XQueryPointer(ob_display, RootWindow(ob_display, ob_screen),
+                           &w, &w, x, y, &i, &i, &u);
 }
 }
-#endif
This page took 0.050119 seconds and 4 git commands to generate.