X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fscreen.c;h=1b9887d95ecdd529182c7919ee9fdcb90d373113;hb=62f1473c651a564391e53548e0cb7daa5303776d;hp=4b25a03565fd5d35d338cf3e25b3905d473ca3ff;hpb=bddbe9432837edccc67b76f2d29d4dbc9b02203f;p=chaz%2Fopenbox diff --git a/openbox/screen.c b/openbox/screen.c index 4b25a035..1b9887d9 100644 --- a/openbox/screen.c +++ b/openbox/screen.c @@ -1,3 +1,4 @@ +#include "debug.h" #include "openbox.h" #include "dock.h" #include "xerror.h" @@ -52,6 +53,91 @@ static void sn_event_func(SnMonitorEvent *event, void *data); static void set_root_cursor(); +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); + + 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; + + /* We want to find out when the current selection owner dies */ + XSelectInput(ob_display, current_wm_sn_owner, StructureNotifyMask); + XSync(ob_display, FALSE); + + 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() { XSetWindowAttributes attrib; @@ -59,19 +145,36 @@ gboolean screen_annex() gint i, num_support; guint32 *supported; + /* 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_message("A window manager is already running on screen %d", + g_warning("A window manager is already running on screen %d", ob_screen); + + XDestroyWindow(ob_display, screen_support_win); return FALSE; } - g_message("Managing screen %d", ob_screen); + ob_debug("Managing screen %d\n", ob_screen); set_root_cursor(); @@ -80,16 +183,6 @@ gboolean screen_annex() PROP_SET32(RootWindow(ob_display, ob_screen), openbox_pid, cardinal, pid); - /* 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); - /* set supporting window */ PROP_SET32(RootWindow(ob_display, ob_screen), net_supporting_wm_check, window, screen_support_win); @@ -260,11 +353,11 @@ void screen_resize() if (ob_state() == OB_STATE_STARTING) return; - dock_configure(); screen_update_areas(); + dock_configure(); 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) @@ -334,7 +427,7 @@ void screen_set_desktop(guint num) if (old == num) return; - g_message("Moving to desktop %d", num+1); + ob_debug("Moving to desktop %d\n", num+1); /* show windows before hiding the rest to lessen the enter/leave events */ @@ -360,11 +453,11 @@ void screen_set_desktop(guint num) from the switch so it doesnt mess with the focus */ while (XCheckTypedEvent(ob_display, EnterNotify, &e)); #ifdef DEBUG_FOCUS - g_message("switch fallback"); + ob_debug("switch fallback\n"); #endif focus_fallback(OB_FOCUS_FALLBACK_DESKTOP); #ifdef DEBUG_FOCUS - g_message("/switch fallback"); + ob_debug("/switch fallback\n"); #endif dispatch_ob(Event_Ob_Desktop, num, old); @@ -544,8 +637,6 @@ void screen_update_areas() { guint i, x; guint32 *dims; - Rect **old_area = area; - Rect **rit; GList *it; g_free(monitor_area); @@ -564,7 +655,6 @@ void screen_update_areas() 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; @@ -707,7 +797,7 @@ void screen_update_areas() } } PROP_SETA32(RootWindow(ob_display, ob_screen), net_workarea, cardinal, - dims, 4 * screen_num_desktops); + dims, 4 * screen_num_desktops); g_free(dims); } @@ -807,3 +897,13 @@ static void sn_event_func(SnMonitorEvent *ev, void *data) set_root_cursor(); } #endif + +gboolean screen_pointer_pos(int *x, int *y) +{ + Window w; + int i; + guint u; + + return !!XQueryPointer(ob_display, RootWindow(ob_display, ob_screen), + &w, &w, x, y, &i, &i, &u); +}