all repos — openbox @ 845833226b7d65019d41eb3afce6fad7ae3d30a2

openbox fork - make it a bit more like ryudo

add the --replace command line option, and support for the WM_Sn selection
Dana Jansens danakj@orodu.net
commit

845833226b7d65019d41eb3afce6fad7ae3d30a2

parent

6a7d4de7899fb90f8b93cb8c7facfc8273b0d1b4

4 files changed, 138 insertions(+), 31 deletions(-)

jump to
M openbox/event.copenbox/event.c

@@ -186,6 +186,9 @@ Window window;

/* pick a window */ switch (e->type) { + case SelectionClear: + window = RootWindow(ob_display, ob_screen); + break; case MapRequest: window = e->xmap.window; break;

@@ -548,6 +551,11 @@ {

Atom msgtype; switch(e->type) { + case SelectionClear: + g_message("Another WM has requested to replace us. Exiting."); + ob_exit(); + break; + case ClientMessage: if (e->xclient.format != 32) break;
M openbox/openbox.copenbox/openbox.c

@@ -59,14 +59,15 @@ RrInstance *ob_rr_inst;

RrTheme *ob_rr_theme; Display *ob_display; gint ob_screen; -Cursor ob_cursors[OB_NUM_CURSORS]; -KeyCode ob_keys[OB_NUM_KEYS]; +gboolean ob_replace_wm; static ObState state; static gboolean xsync; static gboolean shutdown; static gboolean restart; static char *restart_path; +static Cursor cursors[OB_NUM_CURSORS]; +static KeyCode keys[OB_NUM_KEYS]; static void signal_handler(const ObEvent *e, void *data); static void parse_args(int argc, char **argv);

@@ -169,41 +170,41 @@ display we're using, so they open in the right place. */

putenv(g_strdup_printf("DISPLAY=%s", DisplayString(ob_display))); /* create available cursors */ - ob_cursors[OB_CURSOR_POINTER] = + cursors[OB_CURSOR_POINTER] = XCreateFontCursor(ob_display, XC_left_ptr); - ob_cursors[OB_CURSOR_BUSY] = + cursors[OB_CURSOR_BUSY] = XCreateFontCursor(ob_display, XC_watch); - ob_cursors[OB_CURSOR_MOVE] = + cursors[OB_CURSOR_MOVE] = XCreateFontCursor(ob_display, XC_fleur); - ob_cursors[OB_CURSOR_NORTH] = + cursors[OB_CURSOR_NORTH] = XCreateFontCursor(ob_display, XC_top_side); - ob_cursors[OB_CURSOR_NORTHEAST] = + cursors[OB_CURSOR_NORTHEAST] = XCreateFontCursor(ob_display, XC_top_right_corner); - ob_cursors[OB_CURSOR_EAST] = + cursors[OB_CURSOR_EAST] = XCreateFontCursor(ob_display, XC_right_side); - ob_cursors[OB_CURSOR_SOUTHEAST] = + cursors[OB_CURSOR_SOUTHEAST] = XCreateFontCursor(ob_display, XC_bottom_right_corner); - ob_cursors[OB_CURSOR_SOUTH] = + cursors[OB_CURSOR_SOUTH] = XCreateFontCursor(ob_display, XC_bottom_side); - ob_cursors[OB_CURSOR_SOUTHWEST] = + cursors[OB_CURSOR_SOUTHWEST] = XCreateFontCursor(ob_display, XC_bottom_left_corner); - ob_cursors[OB_CURSOR_WEST] = + cursors[OB_CURSOR_WEST] = XCreateFontCursor(ob_display, XC_left_side); - ob_cursors[OB_CURSOR_NORTHWEST] = + cursors[OB_CURSOR_NORTHWEST] = XCreateFontCursor(ob_display, XC_top_left_corner); /* create available keycodes */ - ob_keys[OB_KEY_RETURN] = + keys[OB_KEY_RETURN] = XKeysymToKeycode(ob_display, XStringToKeysym("Return")); - ob_keys[OB_KEY_ESCAPE] = + keys[OB_KEY_ESCAPE] = XKeysymToKeycode(ob_display, XStringToKeysym("Escape")); - ob_keys[OB_KEY_LEFT] = + keys[OB_KEY_LEFT] = XKeysymToKeycode(ob_display, XStringToKeysym("Left")); - ob_keys[OB_KEY_RIGHT] = + keys[OB_KEY_RIGHT] = XKeysymToKeycode(ob_display, XStringToKeysym("Right")); - ob_keys[OB_KEY_UP] = + keys[OB_KEY_UP] = XKeysymToKeycode(ob_display, XStringToKeysym("Up")); - ob_keys[OB_KEY_DOWN] = + keys[OB_KEY_DOWN] = XKeysymToKeycode(ob_display, XStringToKeysym("Down")); prop_startup(); /* get atoms values for the display */

@@ -503,6 +504,8 @@ #ifdef USE_SM

g_print(" --sm-client-id ID Specify session management ID\n"); g_print(" --sm-disable Disable connection to session manager\n"); #endif + g_print(" --replace Replace the currently running window " + "manager\n"); g_print(" --help Display this help and exit\n"); g_print(" --version Display the version and exit\n"); g_print(" --sync Run in synchronous mode (this is slow and\n"

@@ -523,6 +526,8 @@ print_help();

exit(0); } else if (!strcmp(argv[i], "--g-fatal-warnings")) { g_log_set_always_fatal(G_LOG_LEVEL_CRITICAL); + } else if (!strcmp(argv[i], "--replace")) { + ob_replace_wm = TRUE; } else if (!strcmp(argv[i], "--sync")) { xsync = TRUE; #ifdef USE_SM

@@ -594,13 +599,13 @@

Cursor ob_cursor(ObCursor cursor) { g_assert(cursor < OB_NUM_CURSORS); - return ob_cursors[cursor]; + return cursors[cursor]; } KeyCode ob_keycode(ObKey key) { g_assert(key < OB_NUM_KEYS); - return ob_keys[key]; + return keys[key]; } ObState ob_state()
M openbox/openbox.hopenbox/openbox.h

@@ -27,6 +27,8 @@

/*! The number of the screen on which we're running */ extern gint ob_screen; +extern gboolean ob_replace_wm; + /* The state of execution of the window manager */ ObState ob_state();
M openbox/screen.copenbox/screen.c

@@ -52,6 +52,91 @@ #endif

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_message("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_message("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_message("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,6 +144,21 @@ pid_t pid;

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),

@@ -67,6 +167,8 @@ xerror_set_ignore(FALSE);

if (xerror_occured) { g_message("A window manager is already running on screen %d", ob_screen); + + XDestroyWindow(ob_display, screen_support_win); return FALSE; }

@@ -79,16 +181,6 @@ /* set the OPENBOX_PID hint */

pid = getpid(); 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),