]> Dogcows Code - chaz/openbox/commitdiff
add the --replace command line option, and support for the WM_Sn selection
authorDana Jansens <danakj@orodu.net>
Tue, 22 Jul 2003 18:09:41 +0000 (18:09 +0000)
committerDana Jansens <danakj@orodu.net>
Tue, 22 Jul 2003 18:09:41 +0000 (18:09 +0000)
openbox/event.c
openbox/openbox.c
openbox/openbox.h
openbox/screen.c

index 35d3472d7faac7994dc310fcf976018c4f2f1646..018218fcef61dbf08951187127add37559385b27 100644 (file)
@@ -186,6 +186,9 @@ static Window event_get_window(XEvent *e)
 
     /* 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 @@ static void event_handle_root(XEvent *e)
     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;
 
index 234764178ea6df7bdd948c88feff242e42397a9a..4b248a0c4d561ff0c10b241baedf4e822e47627e 100644 (file)
@@ -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 @@ int main(int argc, char **argv)
     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 @@ static void print_help()
     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 @@ static void parse_args(int argc, char **argv)
             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 @@ void ob_exit()
 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()
index f5129ecce92a01dfc9734e8dab46ef0b96be38cf..a9d32688ee9c64f8c4a32d09b0e16dded50f377a 100644 (file)
@@ -27,6 +27,8 @@ SnDisplay *ob_sn_display;
 /*! 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();
 
index 58c5b2e5943754bf050f18cdc086a1a94f1adc9d..3e3b9632d50ede9169864fb03a6a251b0c5aa0ef 100644 (file)
@@ -52,6 +52,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_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 @@ 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),
@@ -67,6 +167,8 @@ gboolean screen_annex()
     if (xerror_occured) {
         g_message("A window manager is already running on screen %d",
                   ob_screen);
+
+        XDestroyWindow(ob_display, screen_support_win);
        return FALSE;
     }
 
@@ -80,16 +182,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);
This page took 0.039595 seconds and 4 git commands to generate.