oops... I'm combining two different things in this commit... so I'll try be clear
authorDana Jansens <danakj@orodu.net>
Sun, 4 Mar 2007 09:01:52 +0000 (09:01 +0000)
committerDana Jansens <danakj@orodu.net>
Sun, 4 Mar 2007 09:01:52 +0000 (09:01 +0000)
1. when another wm requests to replace openbox, openbox exits. but the SM will just restart openbox unless we tell it not to. so now ob_exit_replace() will change the session manager's view of openbox to not restart it. that way the new WM will be able to run.

2. allow windows to move themselves off of the screen 90% of the way, if they really want to. but only 90% to the left, right, and bottom of the screen. it won't let the app move off the top of the screen on its own at all now, since hiding the titlebar on you without you being a part of the process is pretty darn evil!

this is really to address bug # 2982 - for the tilda application. but i guess if windows really want to move off the screen, who's to say no? also, every other window manager will let them - except metacity won't let them on the left/top side of the screen.

openbox/client.c
openbox/event.c
openbox/openbox.c
openbox/openbox.h
openbox/session.c
openbox/session.h

index 797d5b8..682de02 100644 (file)
@@ -705,16 +705,23 @@ gboolean client_find_onscreen(ObClient *self, gint *x, gint *y, gint w, gint h,
 
     /* XXX watch for xinerama dead areas */
     /* This makes sure windows aren't entirely outside of the screen so you
-     * can't see them at all */
+       can't see them at all.
+       It makes sure 10% of the window is on the screen at least. At don't let
+       it move itself off the top of the screen, which would hide the titlebar
+       on you. (The user can still do this if they want too, it's only limiting
+       the application.
+    */
     if (client_normal(self)) {
         a = screen_area(self->desktop);
-        if (!self->strut.right && *x >= a->x + a->width - 1)
-            *x = a->x + a->width - self->frame->area.width;
-        if (!self->strut.bottom && *y >= a->y + a->height - 1)
-            *y = a->y + a->height - self->frame->area.height;
-        if (!self->strut.left && *x + self->frame->area.width - 1 < a->x)
-            *x = a->x;
-        if (!self->strut.top && *y + self->frame->area.height - 1 < a->y)
+        if (!self->strut.right &&
+            *x + self->frame->area.width/10 >= a->x + a->width - 1)
+            *x = a->x + a->width - self->frame->area.width/10;
+        if (!self->strut.bottom &&
+            *y + self->frame->area.height/10 >= a->y + a->height - 1)
+            *y = a->y + a->height - self->frame->area.height/10;
+        if (!self->strut.left && *x + self->frame->area.width*9/10 - 1 < a->x)
+            *x = a->x - self->frame->area.width*9/10;
+        if (!self->strut.top && *y < a->y)
             *y = a->y;
     }
 
@@ -729,7 +736,7 @@ gboolean client_find_onscreen(ObClient *self, gint *x, gint *y, gint w, gint h,
          * remember to fix the placement stuff to avoid it also and
          * then remove this XXX */
         a = screen_physical_area_monitor(client_monitor(self));
-        /* dont let windows map/move into the strut unless they
+        /* dont let windows map into the strut unless they
            are bigger than the available area */
         if (w <= a->width) {
             if (!self->strut.left && *x < a->x) *x = a->x;
index c74e15a..42fd26b 100644 (file)
@@ -579,7 +579,7 @@ static void event_handle_root(XEvent *e)
     switch(e->type) {
     case SelectionClear:
         ob_debug("Another WM has requested to replace us. Exiting.\n");
-        ob_exit(0);
+        ob_exit_replace();
         break;
 
     case ClientMessage:
@@ -854,7 +854,7 @@ static void event_handle_client(ObClient *client, XEvent *e)
                 gint fh = h +
                      client->frame->size.top + client->frame->size.bottom;
                 client_find_onscreen(client, &newx, &newy, fw, fh,
-                                     client_normal(client));
+                                     FALSE);
                 if (e->xconfigurerequest.value_mask & CWX)
                     x = newx;
                 if (e->xconfigurerequest.value_mask & CWY)
index e3309f0..1c4a870 100644 (file)
@@ -87,6 +87,7 @@ static Cursor    cursors[OB_NUM_CURSORS];
 static KeyCode   keys[OB_NUM_KEYS];
 static gint      exitcode = 0;
 static gboolean  reconfigure_and_exit = FALSE;
+static gboolean  being_replaced = FALSE;
 
 static void signal_handler(gint signal, gpointer data);
 static void parse_args(gint argc, gchar **argv);
@@ -332,7 +333,7 @@ gint main(gint argc, gchar **argv)
     RrThemeFree(ob_rr_theme);
     RrInstanceFree(ob_rr_inst);
 
-    session_shutdown();
+    session_shutdown(being_replaced);
 
     XCloseDisplay(ob_display);
 
@@ -448,7 +449,7 @@ static void parse_args(gint argc, gchar **argv)
 void ob_exit_with_error(gchar *msg)
 {
     g_critical(msg);
-    session_shutdown();
+    session_shutdown(TRUE);
     exit(EXIT_FAILURE);
 }
 
@@ -476,6 +477,13 @@ void ob_exit(gint code)
     ob_main_loop_exit(ob_main_loop);
 }
 
+void ob_exit_replace()
+{
+    exitcode = 0;
+    being_replaced = TRUE;
+    ob_main_loop_exit(ob_main_loop);
+}
+
 Cursor ob_cursor(ObCursor cursor)
 {
     g_assert(cursor < OB_NUM_CURSORS);
index 649b610..4d41020 100644 (file)
@@ -50,6 +50,7 @@ ObState ob_state();
 void ob_restart_other(const gchar *path);
 void ob_restart();
 void ob_exit(gint code);
+void ob_exit_replace();
 
 void ob_reconfigure();
 
index f44d3b4..72588ff 100644 (file)
@@ -257,7 +257,7 @@ void session_startup(gint argc, gchar **argv)
     }
 }
 
-void session_shutdown()
+void session_shutdown(gboolean permanent)
 {
     if (sm_disable)
         return;
@@ -268,6 +268,26 @@ void session_shutdown()
     g_free(sm_argv);
 
     if (sm_conn) {
+        /* if permanent is true then we will change our session state so that
+           the SM won't run us again */
+        if (permanent) {
+            SmPropValue val_hint;
+            SmProp prop_hint = { SmRestartStyleHint, SmCARD8, 1, };
+            SmProp *props[1];
+            gulong hint;
+
+            /* when we exit, we want to reset this to a more friendly state */
+            hint = SmRestartIfRunning;
+            val_hint.value = &hint;
+            val_hint.length = 1;
+
+            prop_hint.vals = &val_hint;
+
+            props[0] = &prop_hint;
+
+            SmcSetProperties(sm_conn, 1, props);
+        }
+
         SmcCloseConnection(sm_conn, 0, NULL);
 
         while (session_saved_state) {
index c314633..75198ca 100644 (file)
@@ -39,7 +39,7 @@ struct _ObSessionState {
 extern GList *session_saved_state;
 
 void session_startup(gint argc, gchar **argv);
-void session_shutdown();
+void session_shutdown(gboolean permanent);
 
 GList* session_state_find(struct _ObClient *c);
 gboolean session_state_cmp(ObSessionState *s, struct _ObClient *c);