merge r6434-6447 from trunk
authorDana Jansens <danakj@orodu.net>
Sun, 13 May 2007 17:54:46 +0000 (17:54 +0000)
committerDana Jansens <danakj@orodu.net>
Sun, 13 May 2007 17:54:46 +0000 (17:54 +0000)
17 files changed:
AUTHORS
COMPLIANCE
openbox/client.c
openbox/client.h
openbox/client_list_combined_menu.c
openbox/client_list_menu.c
openbox/client_menu.c
openbox/event.c
openbox/focus.c
openbox/keyboard.c
openbox/keyboard.h
openbox/mainloop.c
openbox/menu.c
openbox/moveresize.c
openbox/prop.c
openbox/prop.h
openbox/screen.c

diff --git a/AUTHORS b/AUTHORS
index e4df36e0c06961d407480bea26ce2323403d7eee..4bc674dba2a386ead4f2421ad82433503fcf76c1 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -16,3 +16,5 @@ Mike Bacso (smakwel@yahoo.com)
  - Themes
 John McKnight (jmcknight@gmail.com)
  - Clearlooks Themes
+David Barr (david@chalkskeletons.com)
+ - Bear2 Theme
index fdc40d1d66a7481ee059f3ebfb9f6afcea41f664..3873a8fd821739a1e50b69568023819078425a59 100644 (file)
@@ -63,3 +63,16 @@ the version of the spec which Openbox is compliant up to for the hint.
 + _NET_WM_FULL_PLACEMENT (1.4)
 + _NET_WM_MOVERESIZE_CANCEL (1.4)
 + _NET_REQUEST_FRAME_EXTENTS (1.3)
++ _NET_WM_ACTION_MOVE (1.3)
++ _NET_WM_ACTION_RESIZE (1.3)
++ _NET_WM_ACTION_MINIMIZE (1.3)
++ _NET_WM_ACTION_SHADE (1.3)
+- _NET_WM_ACTION_STICK (1.3)
+       Openbox does not do large desktops, so no sticky state is needed.
++ _NET_WM_ACTION_MAXIMIZE_HORZ (1.3)
++ _NET_WM_ACTION_MAXIMIZE_VERT (1.3)
++ _NET_WM_ACTION_FULLSCREEN (1.3)
++ _NET_WM_ACTION_CHANGE_DESKTOP (1.3)
++ _NET_WM_ACTION_CLOSE (1.3)
++ _NET_WM_ACTION_ABOVE (1.4?)
++ _NET_WM_ACTION_BELOW (1.4?)
index 208024cf92ebf1c8eeb8629ec776bf34182d89fe..39bd94d5e530917a8eb056fc8c33da2eca73fded 100644 (file)
@@ -64,7 +64,8 @@ typedef struct
 
 GList            *client_list          = NULL;
 
-static GSList *client_destructors      = NULL;
+static GSList *client_destroy_notifies = NULL;
+static GSList *client_hide_notifies    = NULL;
 
 static void client_get_all(ObClient *self, gboolean real);
 static void client_toggle_border(ObClient *self, gboolean show);
@@ -79,7 +80,7 @@ static void client_get_colormap(ObClient *self);
 static void client_change_allowed_actions(ObClient *self);
 static void client_change_state(ObClient *self);
 static void client_change_wm_state(ObClient *self);
-static void client_apply_startup_state(ObClient *self, gint x, gint y);
+static void client_apply_startup_state(ObClient *self);
 static void client_restore_session_state(ObClient *self);
 static gboolean client_restore_session_stacking(ObClient *self);
 static ObAppSettings *client_get_settings_state(ObClient *self);
@@ -91,6 +92,7 @@ static void client_present(ObClient *self, gboolean here, gboolean raise);
 static GSList *client_search_all_top_parents_internal(ObClient *self,
                                                       gboolean bylayer,
                                                       ObStackingLayer layer);
+static void client_call_notifies(ObClient *self, GSList *list);
 
 void client_startup(gboolean reconfig)
 {
@@ -104,23 +106,57 @@ void client_shutdown(gboolean reconfig)
     if (reconfig) return;
 }
 
-void client_add_destructor(ObClientCallback func, gpointer data)
+static void client_call_notifies(ObClient *self, GSList *list)
+{
+    GSList *it;
+
+    for (it = list; it; it = g_slist_next(it)) {
+        ClientCallback *d = it->data;
+        d->func(self, d->data);
+    }
+}
+
+void client_add_destroy_notify(ObClientCallback func, gpointer data)
+{
+    ClientCallback *d = g_new(ClientCallback, 1);
+    d->func = func;
+    d->data = data;
+    client_destroy_notifies = g_slist_prepend(client_destroy_notifies, d);
+}
+
+void client_remove_destroy_notify(ObClientCallback func)
+{
+    GSList *it;
+
+    for (it = client_destroy_notifies; it; it = g_slist_next(it)) {
+        ClientCallback *d = it->data;
+        if (d->func == func) {
+            g_free(d);
+            client_destroy_notifies =
+                g_slist_delete_link(client_destroy_notifies, it);
+            break;
+        }
+    }
+}
+
+void client_add_hide_notify(ObClientCallback func, gpointer data)
 {
     ClientCallback *d = g_new(ClientCallback, 1);
     d->func = func;
     d->data = data;
-    client_destructors = g_slist_prepend(client_destructors, d);
+    client_hide_notifies = g_slist_prepend(client_hide_notifies, d);
 }
 
-void client_remove_destructor(ObClientCallback func)
+void client_remove_hide_notify(ObClientCallback func)
 {
     GSList *it;
 
-    for (it = client_destructors; it; it = g_slist_next(it)) {
+    for (it = client_hide_notifies; it; it = g_slist_next(it)) {
         ClientCallback *d = it->data;
         if (d->func == func) {
             g_free(d);
-            client_destructors = g_slist_delete_link(client_destructors, it);
+            client_hide_notifies =
+                g_slist_delete_link(client_hide_notifies, it);
             break;
         }
     }
@@ -229,7 +265,6 @@ void client_manage(Window window)
     XWMHints *wmhint;
     gboolean activate = FALSE;
     ObAppSettings *settings;
-    gint newx, newy;
 
     grab_server(TRUE);
 
@@ -347,20 +382,21 @@ void client_manage(Window window)
         activate = TRUE;
     }
 
-    /* get the current position */
-    newx = self->area.x;
-    newy = self->area.y;
-
     /* figure out placement for the window */
     if (ob_state() == OB_STATE_RUNNING) {
         gboolean transient;
 
-        transient = place_client(self, &newx, &newy, settings);
+        ob_debug("Positioned: %s @ %d %d\n",
+                 (!self->positioned ? "no" :
+                  (self->positioned == PPosition ? "program specified" :
+                   (self->positioned == USPosition ? "user specified" :
+                    "BADNESS !?"))), self->area.x, self->area.y);
+
+        transient = place_client(self, &self->area.x, &self->area.y, settings);
 
         /* make sure the window is visible. */
-        client_find_onscreen(self, &newx, &newy,
-                             self->area.width,
-                             self->area.height,
+        client_find_onscreen(self, &self->area.x, &self->area.y,
+                             self->area.width, self->area.height,
                              /* non-normal clients has less rules, and
                                 windows that are being restored from a
                                 session do also. we can assume you want
@@ -383,12 +419,18 @@ void client_manage(Window window)
        also, this moves the window to the position where it has been placed
     */
     ob_debug("placing window 0x%x at %d, %d with size %d x %d\n",
-             self->window, newx, newy, self->area.width, self->area.height);
+             self->window, self->area.x, self->area.y,
+             self->area.width, self->area.height);
     if (self->session)
-        ob_debug("session requested %d %d\n",
+        ob_debug("  but session requested %d %d instead, overriding\n",
                  self->session->x, self->session->y);
 
-    client_apply_startup_state(self, newx, newy);
+    /* generate a ConfigureNotify telling the client where it is */
+    client_configure_full(self, self->area.x, self->area.y,
+                          self->area.width, self->area.height,
+                          FALSE, TRUE);
+
+    client_apply_startup_state(self);
 
     mouse_grab_for_client(self, TRUE);
 
@@ -460,6 +502,7 @@ void client_manage(Window window)
 
     /* adjust the frame to the client's size before showing the window */
     frame_adjust_area(self->frame, FALSE, TRUE, FALSE);
+    frame_adjust_client_area(self->frame);
 
     /* this has to happen before we try focus the window, but we want it to
        happen after the client's stacking has been determined or it looks bad
@@ -565,10 +608,7 @@ void client_unmanage(ObClient *self)
     if (STRUT_EXISTS(self->strut))
         screen_update_areas();
 
-    for (it = client_destructors; it; it = g_slist_next(it)) {
-        ClientCallback *d = it->data;
-        d->func(self, d->data);
-    }
+    client_call_notifies(self, client_destroy_notifies);
 
     /* tell our parent(s) that we're gone */
     if (self->transient_for == OB_TRAN_GROUP) { /* transient of group */
@@ -1560,7 +1600,9 @@ void client_setup_decor_and_functions(ObClient *self)
          OB_CLIENT_FUNC_ICONIFY |
          OB_CLIENT_FUNC_MAXIMIZE |
          OB_CLIENT_FUNC_SHADE |
-         OB_CLIENT_FUNC_CLOSE);
+         OB_CLIENT_FUNC_CLOSE |
+         OB_CLIENT_FUNC_BELOW |
+         OB_CLIENT_FUNC_ABOVE);
 
     if (!(self->min_size.width < self->max_size.width ||
           self->min_size.height < self->max_size.height))
@@ -1592,10 +1634,15 @@ void client_setup_decor_and_functions(ObClient *self)
         self->functions = OB_CLIENT_FUNC_MOVE;
 
     case OB_CLIENT_TYPE_DESKTOP:
-    case OB_CLIENT_TYPE_DOCK:
         /* these windows are not manipulated by the window manager */
         self->decorations = 0;
         self->functions = 0;
+
+    case OB_CLIENT_TYPE_DOCK:
+        /* these windows are not manipulated by the window manager, but they
+           can set below layer which has a special meaning */
+        self->decorations = 0;
+        self->functions = OB_CLIENT_FUNC_BELOW;
         break;
     }
 
@@ -1685,7 +1732,7 @@ void client_setup_decor_and_functions(ObClient *self)
 
 static void client_change_allowed_actions(ObClient *self)
 {
-    gulong actions[9];
+    gulong actions[11];
     gint num = 0;
 
     /* desktop windows are kept on all desktops */
@@ -1708,6 +1755,10 @@ static void client_change_allowed_actions(ObClient *self)
         actions[num++] = prop_atoms.net_wm_action_maximize_horz;
         actions[num++] = prop_atoms.net_wm_action_maximize_vert;
     }
+    if (self->functions & OB_CLIENT_FUNC_ABOVE)
+        actions[num++] = prop_atoms.net_wm_action_above;
+    if (self->functions & OB_CLIENT_FUNC_BELOW)
+        actions[num++] = prop_atoms.net_wm_action_below;
 
     PROP_SETA32(self->window, net_wm_allowed_actions, atom, actions, num);
 
@@ -2383,6 +2434,8 @@ void client_hide(ObClient *self)
 {
     if (!client_should_show(self)) {
         frame_hide(self->frame);
+
+        client_call_notifies(self, client_hide_notifies);
     }
 
     /* According to the ICCCM (sec 4.1.3.1) when a window is not visible, it
@@ -2400,6 +2453,8 @@ void client_showhide(ObClient *self)
     }
     else {
         frame_hide(self->frame);
+
+        client_call_notifies(self, client_hide_notifies);
     }
 
     /* According to the ICCCM (sec 4.1.3.1) when a window is not visible, it
@@ -2438,17 +2493,8 @@ gboolean client_enter_focusable(ObClient *self)
 }
 
 
-static void client_apply_startup_state(ObClient *self, gint x, gint y)
+static void client_apply_startup_state(ObClient *self)
 {
-    gboolean pos = FALSE; /* has the window's position been configured? */
-    gint ox, oy;
-
-    /* save the position, and set self->area for these to use */
-    ox = self->area.x;
-    oy = self->area.y;
-    self->area.x = x;
-    self->area.y = y;
-
     /* set the desktop hint, to make sure that it always exists */
     PROP_SET32(self->window, net_wm_desktop, cardinal, self->desktop);
 
@@ -2461,7 +2507,6 @@ static void client_apply_startup_state(ObClient *self, gint x, gint y)
     if (self->fullscreen) {
         self->fullscreen = FALSE;
         client_fullscreen(self, TRUE);
-        pos = TRUE;
     }
     if (self->undecorated) {
         self->undecorated = FALSE;
@@ -2479,27 +2524,12 @@ static void client_apply_startup_state(ObClient *self, gint x, gint y)
     if (self->max_vert && self->max_horz) {
         self->max_vert = self->max_horz = FALSE;
         client_maximize(self, TRUE, 0);
-        pos = TRUE;
     } else if (self->max_vert) {
         self->max_vert = FALSE;
         client_maximize(self, TRUE, 2);
-        pos = TRUE;
     } else if (self->max_horz) {
         self->max_horz = FALSE;
         client_maximize(self, TRUE, 1);
-        pos = TRUE;
-    }
-
-    /* if the client didn't get positioned yet, then do so now.
-       call client_move even if the window is not being moved anywhere, because
-       when we reparent it and decorate it, it is getting moved and we need to
-       be telling it so with a ConfigureNotify event.
-    */
-    if (!pos) {
-        /* use the saved position */
-        self->area.x = ox;
-        self->area.y = oy;
-        client_move(self, x, y);
     }
 
     /* nothing to do for the other states:
@@ -2713,8 +2743,9 @@ void client_configure_full(ObClient *self, gint x, gint y, gint w, gint h,
                                     (resized && config_resize_redraw))));
 
     /* if the client is enlarging, then resize the client before the frame */
-    if (send_resize_client && user && (w > oldw || h > oldh)) {
-        XResizeWindow(ob_display, self->window, MAX(w, oldw), MAX(h, oldh));
+    if (send_resize_client && (w > oldw || h > oldh)) {
+        XResizeWindow(ob_display, self->window,
+                      MAX(w, oldw), MAX(h, oldh));
         /* resize the plate to show the client padding color underneath */
         frame_adjust_client_area(self->frame);
     }
@@ -2756,11 +2787,12 @@ void client_configure_full(ObClient *self, gint x, gint y, gint w, gint h,
     }
 
     /* if the client is shrinking, then resize the frame before the client */
-    if (send_resize_client && (!user || (w <= oldw || h <= oldh))) {
+    if (send_resize_client && (w <= oldw || h <= oldh)) {
         /* resize the plate to show the client padding color underneath */
         frame_adjust_client_area(self->frame);
 
-        XResizeWindow(ob_display, self->window, w, h);
+        if (send_resize_client)
+            XResizeWindow(ob_display, self->window, w, h);
     }
 
     XFlush(ob_display);
@@ -3360,6 +3392,16 @@ gboolean client_focus(ObClient *self)
                   "Focusing client \"%s\" at time %u\n",
                   self->title, event_curtime);
 
+    /* if there is a grab going on, then we need to cancel it. if we move
+       focus during the grab, applications will get NotifyWhileGrabbed events
+       and ignore them !
+
+       actions should not rely on being able to move focus during an
+       interactive grab.
+    */
+    if (keyboard_interactively_grabbed())
+        keyboard_interactive_cancel();
+
     if (self->can_focus) {
         /* This can cause a BadMatch error with CurrentTime, or if an app
            passed in a bad time for _NET_WM_ACTIVE_WINDOW. */
index bc7c32e8473913a1eb46749caf4f537ce409c515..c4815d4c83e0cfb56b796d5b4a7b771798caa215 100644 (file)
@@ -71,7 +71,9 @@ typedef enum
     OB_CLIENT_FUNC_MAXIMIZE   = 1 << 3, /*!< Allow to be maximized */
     OB_CLIENT_FUNC_SHADE      = 1 << 4, /*!< Allow to be shaded */
     OB_CLIENT_FUNC_FULLSCREEN = 1 << 5, /*!< Allow to be made fullscreen */
-    OB_CLIENT_FUNC_CLOSE      = 1 << 6  /*!< Allow to be closed */
+    OB_CLIENT_FUNC_CLOSE      = 1 << 6, /*!< Allow to be closed */
+    OB_CLIENT_FUNC_ABOVE      = 1 << 7, /*!< Allow to be put in lower layer */
+    OB_CLIENT_FUNC_BELOW      = 1 << 8  /*!< Allow to be put in higher layer */
 } ObFunctions;
 
 struct _ObClient
@@ -309,8 +311,12 @@ typedef void (*ObClientCallback)(ObClient *client, gpointer data);
 /* Callback functions */
 
 /*! Get notified when the client is unmanaged */
-void client_add_destructor(ObClientCallback func, gpointer data);
-void client_remove_destructor(ObClientCallback func);
+void client_add_destroy_notify(ObClientCallback func, gpointer data);
+void client_remove_destroy_notify(ObClientCallback func);
+
+/*! Get notified when the client is hidden */
+void client_add_hide_notify(ObClientCallback func, gpointer data);
+void client_remove_hide_notify(ObClientCallback func);
 
 /*! Manages all existing windows */
 void client_manage_all();
index 26430f35e05c0ccebbeb58e15b0188103a986766..52ebce43b28a336e0a0ad3c505d928f1c6a705fb 100644 (file)
@@ -143,7 +143,7 @@ static void client_dest(ObClient *client, gpointer data)
 void client_list_combined_menu_startup(gboolean reconfig)
 {
     if (!reconfig)
-        client_add_destructor(client_dest, NULL);
+        client_add_destroy_notify(client_dest, NULL);
 
     combined_menu = menu_new(MENU_NAME, _("Windows"), TRUE, NULL);
     menu_set_update_func(combined_menu, self_update);
@@ -153,5 +153,5 @@ void client_list_combined_menu_startup(gboolean reconfig)
 void client_list_combined_menu_shutdown(gboolean reconfig)
 {
     if (!reconfig)
-        client_remove_destructor(client_dest);
+        client_remove_destroy_notify(client_dest);
 }
index 351790be7b9c14e3932551443c7b413980e81b89..77cfc1933121a0e31ce744a3434cc09274b715d4 100644 (file)
@@ -194,7 +194,7 @@ void client_list_menu_startup(gboolean reconfig)
     ObMenu *menu;
 
     if (!reconfig)
-        client_add_destructor(client_dest, NULL);
+        client_add_destroy_notify(client_dest, NULL);
 
     menu = menu_new(MENU_NAME, _("Desktops"), TRUE, NULL);
     menu_set_update_func(menu, self_update);
@@ -203,5 +203,5 @@ void client_list_menu_startup(gboolean reconfig)
 void client_list_menu_shutdown(gboolean reconfig)
 {
     if (!reconfig)
-        client_remove_destructor(client_dest);
+        client_remove_destroy_notify(client_dest);
 }
index 3699e2128dc07f7e7f3d14c52b9d54f212c7c8b3..758b6a7b3f4025d9c31095a2e44ba4867416b25d 100644 (file)
@@ -176,13 +176,13 @@ static gboolean layer_menu_update(ObMenuFrame *frame, gpointer data)
         if (e->type == OB_MENU_ENTRY_TYPE_NORMAL) {
             switch (e->id) {
             case LAYER_TOP:
-                *en = !c->above;
+                *en = !c->above && (c->functions & OB_CLIENT_FUNC_ABOVE);
                 break;
             case LAYER_NORMAL:
                 *en = c->above || c->below;
                 break;
             case LAYER_BOTTOM:
-                *en = !c->below;
+                *en = !c->below && (c->functions & OB_CLIENT_FUNC_BELOW);
                 break;
             default:
                 *en = TRUE;
index 15a8e1281fb28db5ad1a64710efa427c4a0109d7..9e72408db951a40cc9f381b4541ce0c49036e620 100644 (file)
@@ -131,7 +131,7 @@ void event_startup(gboolean reconfig)
     IceAddConnectionWatch(ice_watch, NULL);
 #endif
 
-    client_add_destructor(focus_delay_client_dest, NULL);
+    client_add_destroy_notify(focus_delay_client_dest, NULL);
 }
 
 void event_shutdown(gboolean reconfig)
@@ -142,7 +142,7 @@ void event_shutdown(gboolean reconfig)
     IceRemoveConnectionWatch(ice_watch, NULL);
 #endif
 
-    client_remove_destructor(focus_delay_client_dest);
+    client_remove_destroy_notify(focus_delay_client_dest);
 }
 
 static Window event_get_window(XEvent *e)
@@ -356,8 +356,13 @@ static Bool event_look_for_focusin(Display *d, XEvent *e, XPointer arg)
 
 Bool event_look_for_focusin_client(Display *d, XEvent *e, XPointer arg)
 {
+    ObWindow *w;
+
+    /* It is possible to get FocusIn events or unmanaged windows, meaning
+       they won't be for any known client */
     return e->type == FocusIn && wanted_focusevent(e, TRUE) &&
-        e->xfocus.window != screen_support_win;
+        (w = g_hash_table_lookup(window_map, &e->xfocus.window)) &&
+        WINDOW_IS_CLIENT(w);
 }
 
 static void print_focusevent(XEvent *e)
@@ -508,7 +513,19 @@ static void event_process(const XEvent *ec, gpointer data)
                 if (!focus_left_screen)
                     focus_fallback(TRUE);
             }
-        } else if (client && client != focus_client) {
+        }
+        else if (!client) {
+            /* It is possible to get FocusIn events or unmanaged windows,
+               meaning they won't be for any known client
+
+               If this happens, set the client to NULL so we know focus
+               has wandered off, and we'll get a focus out for it
+               shortly.
+            */
+            ob_debug_type(OB_DEBUG_FOCUS, "Focus went to an invalid target\n");
+            focus_set_client(NULL);
+        }
+        else if (client != focus_client) {
             focus_left_screen = FALSE;
             frame_adjust_focus(client->frame, TRUE);
             focus_set_client(client);
index 92cd76626fa9b0ce114a79a92bb5ba4fe30912fd..b084d35721fc08629854e84ca229e75afd10cf29 100644 (file)
@@ -67,8 +67,8 @@ static gboolean valid_focus_target(ObClient *ft,
                                    gboolean all_desktops,
                                    gboolean dock_windows,
                                    gboolean desktop_windows);
-static void focus_cycle_destructor(ObClient *client, gpointer data);
-static void focus_tried_destructor(ObClient *client, gpointer data);
+static void focus_cycle_destroy_notify(ObClient *client, gpointer data);
+static void focus_tried_hide_notify(ObClient *client, gpointer data);
 
 static Window createWindow(Window parent, gulong mask,
                            XSetWindowAttributes *attrib)
@@ -86,8 +86,9 @@ void focus_startup(gboolean reconfig)
     if (!reconfig) {
         XSetWindowAttributes attr;
 
-        client_add_destructor(focus_cycle_destructor, NULL);
-        client_add_destructor(focus_tried_destructor, NULL);
+        client_add_destroy_notify(focus_cycle_destroy_notify, NULL);
+        client_add_destroy_notify(focus_tried_hide_notify, NULL);
+        client_add_hide_notify(focus_tried_hide_notify, NULL);
 
         /* start with nothing focused */
         focus_nothing();
@@ -140,8 +141,9 @@ void focus_shutdown(gboolean reconfig)
     icon_popup_free(focus_cycle_popup);
 
     if (!reconfig) {
-        client_remove_destructor(focus_cycle_destructor);
-        client_remove_destructor(focus_tried_destructor);
+        client_remove_destroy_notify(focus_cycle_destroy_notify);
+        client_remove_destroy_notify(focus_tried_hide_notify);
+        client_remove_hide_notify(focus_tried_hide_notify);
 
         /* reset focus to root */
         XSetInputFocus(ob_display, PointerRoot, RevertToNone, CurrentTime);
@@ -415,7 +417,7 @@ static void popup_cycle(ObClient *c, gboolean show,
     g_free(showtext);
 }
 
-static void focus_cycle_destructor(ObClient *client, gpointer data)
+static void focus_cycle_destroy_notify(ObClient *client, gpointer data)
 {
     /* end cycling if the target disappears. CurrentTime is fine, time won't
        be used
@@ -741,10 +743,13 @@ static ObClient *focus_find_directional(ObClient *c, ObDirection dir,
         /* the currently selected window isn't interesting */
         if(cur == c)
             continue;
-        if (!dock_windows && !desktop_windows && !client_normal(cur))
+        if (cur->type == OB_CLIENT_TYPE_DOCK && !dock_windows)
             continue;
-        if (!(dock_windows && cur->type == OB_CLIENT_TYPE_DOCK) ||
-            (desktop_windows && cur->type == OB_CLIENT_TYPE_DESKTOP))
+        if (cur->type == OB_CLIENT_TYPE_DESKTOP && !desktop_windows)
+            continue;
+        if (!client_normal(cur) &&
+            cur->type != OB_CLIENT_TYPE_DOCK &&
+            cur->type != OB_CLIENT_TYPE_DESKTOP)
             continue;
         /* using c->desktop instead of screen_desktop doesn't work if the
          * current window was omnipresent, hope this doesn't have any other
@@ -942,7 +947,7 @@ ObClient *focus_order_find_first(guint desktop)
     return NULL;
 }
 
-static void focus_tried_destructor(ObClient *client, gpointer data)
+static void focus_tried_hide_notify(ObClient *client, gpointer data)
 {
     XEvent ce;
 
index d758b3869e29cc8868d7b90a9d13102319d06715..5cfd45713dbdff021d5f870be52e3cbcc90ce877 100644 (file)
@@ -199,11 +199,13 @@ static void keyboard_interactive_end(guint state, gboolean cancel, Time time,
     if (ungrab)
         grab_keyboard(FALSE);
 
+    /* set this before running the actions so they know the keyboard is not
+       grabbed */
+    istate.active = FALSE;
+
     alist = g_slist_append(NULL, istate.action);
     action_run_interactive(alist, istate.client, state, time, cancel, TRUE);
     g_slist_free(alist);
-
-    istate.active = FALSE;
 }
 
 static void keyboard_interactive_end_client(ObClient *client, gpointer data)
@@ -212,6 +214,12 @@ static void keyboard_interactive_end_client(ObClient *client, gpointer data)
         istate.client = NULL;
 }
 
+
+void keyboard_interactive_cancel()
+{
+    keyboard_interactive_end(0, TRUE, event_curtime, TRUE);
+}
+
 gboolean keyboard_interactive_grab(guint state, ObClient *client,
                                    ObAction *action)
 {
@@ -324,16 +332,16 @@ void keyboard_startup(gboolean reconfig)
     popup = popup_new(FALSE);
 
     if (!reconfig)
-        client_add_destructor(keyboard_interactive_end_client, NULL);
+        client_add_destroy_notify(keyboard_interactive_end_client, NULL);
 }
 
 void keyboard_shutdown(gboolean reconfig)
 {
     if (!reconfig)
-        client_remove_destructor(keyboard_interactive_end_client);
+        client_remove_destroy_notify(keyboard_interactive_end_client);
 
     if (istate.active)
-        keyboard_interactive_end(0, TRUE, 0, TRUE);
+        keyboard_interactive_cancel();
 
     ob_main_loop_timeout_remove(ob_main_loop, chain_timeout);
 
index 4c6f3bb59ec1c830a7e7b84cf7760d61f5016831..3d70448f4655c9215421087a6cede97a0b3c0b52 100644 (file)
@@ -49,4 +49,6 @@ gboolean keyboard_process_interactive_grab(const XEvent *e,
                                            struct _ObClient **client);
 gboolean keyboard_interactively_grabbed();
 
+void keyboard_interactive_cancel();
+
 #endif
index 2af81629e429cc6abeb880c8e59dc0d883f09435..0e7b0b3cf81efca140bc7405533f3a79a2778ab8 100644 (file)
@@ -282,7 +282,7 @@ void ob_main_loop_run(ObMainLoop *loop)
     loop->run = TRUE;
     loop->running = TRUE;
 
-    client_add_destructor(ob_main_loop_client_destroy, loop);
+    client_add_destroy_notify(ob_main_loop_client_destroy, loop);
 
     while (loop->run) {
         if (loop->signal_fired) {
@@ -365,7 +365,7 @@ void ob_main_loop_run(ObMainLoop *loop)
         }
     }
 
-    client_remove_destructor(ob_main_loop_client_destroy);
+    client_remove_destroy_notify(ob_main_loop_client_destroy);
 
     loop->running = FALSE;
 }
index c6e986b970af1f97f5f65ed8e4bd167370fc5b2d..dbb0c70129417f54213ee9abd775c6cdcee44038 100644 (file)
@@ -110,13 +110,13 @@ void menu_startup(gboolean reconfig)
     g_assert(menu_parse_state.parent == NULL);
 
     if (!reconfig)
-        client_add_destructor(client_dest, NULL);
+        client_add_destroy_notify(client_dest, NULL);
 }
 
 void menu_shutdown(gboolean reconfig)
 {
     if (!reconfig)
-        client_remove_destructor(client_dest);
+        client_remove_destroy_notify(client_dest);
 
     parse_shutdown(menu_parse_inst);
     menu_parse_inst = NULL;
index 6a1e235421be94245bd65f399c9987e91eea58c0..ac51f8b6e83399675dbb24cae379f6cbeba37b1d 100644 (file)
@@ -70,7 +70,7 @@ void moveresize_startup(gboolean reconfig)
     popup = popup_new(FALSE);
 
     if (!reconfig)
-        client_add_destructor(client_dest, NULL);
+        client_add_destroy_notify(client_dest, NULL);
 }
 
 void moveresize_shutdown(gboolean reconfig)
@@ -78,7 +78,7 @@ void moveresize_shutdown(gboolean reconfig)
     if (!reconfig) {
         if (moveresize_in_progress)
             moveresize_end(FALSE);
-        client_remove_destructor(client_dest);
+        client_remove_destroy_notify(client_dest);
     }
 
     popup_free(popup);
index e055906879bb73fcf8c81fbfbd3e531f6ed847c1..5b611f2d417722e30c5fe05a795f27a795ed9039 100644 (file)
@@ -135,6 +135,9 @@ void prop_startup()
     CREATE(net_wm_action_fullscreen, "_NET_WM_ACTION_FULLSCREEN");
     CREATE(net_wm_action_change_desktop, "_NET_WM_ACTION_CHANGE_DESKTOP");
     CREATE(net_wm_action_close, "_NET_WM_ACTION_CLOSE");
+    CREATE(net_wm_action_above, "_NET_WM_ACTION_ABOVE");
+    CREATE(net_wm_action_below, "_NET_WM_ACTION_BELOW");
+
     CREATE(net_wm_state_modal, "_NET_WM_STATE_MODAL");
 /*    CREATE(net_wm_state_sticky, "_NET_WM_STATE_STICKY");*/
     CREATE(net_wm_state_maximized_vert, "_NET_WM_STATE_MAXIMIZED_VERT");
index d1d6a5169e027130fae4e59ba4702e82fcae8846..8f81eff0ebea7c34b0e72d4ecd74cbb608f72d87 100644 (file)
@@ -155,11 +155,14 @@ typedef struct Atoms {
     Atom net_wm_action_resize;
     Atom net_wm_action_minimize;
     Atom net_wm_action_shade;
+/*    Atom net_wm_action_stick;*/
     Atom net_wm_action_maximize_horz;
     Atom net_wm_action_maximize_vert;
     Atom net_wm_action_fullscreen;
     Atom net_wm_action_change_desktop;
     Atom net_wm_action_close;
+    Atom net_wm_action_above;
+    Atom net_wm_action_below;
 
     Atom net_wm_state_modal;
 /*    Atom net_wm_state_sticky;*/
index 73cc4f14b2bb253f852fc6726096a658fe2d420c..1cbb2a5ec2ecceb765442b593dab7ad14d24b428 100644 (file)
@@ -258,6 +258,8 @@ gboolean screen_annex(const gchar *program_name)
     supported[i++] = prop_atoms.net_wm_action_fullscreen;
     supported[i++] = prop_atoms.net_wm_action_change_desktop;
     supported[i++] = prop_atoms.net_wm_action_close;
+    supported[i++] = prop_atoms.net_wm_action_above;
+    supported[i++] = prop_atoms.net_wm_action_below;
     supported[i++] = prop_atoms.net_wm_state;
     supported[i++] = prop_atoms.net_wm_state_modal;
     supported[i++] = prop_atoms.net_wm_state_maximized_vert;
@@ -310,8 +312,13 @@ void screen_startup(gboolean reconfig)
     desktop_cycle_popup = pager_popup_new(FALSE);
     pager_popup_height(desktop_cycle_popup, POPUP_HEIGHT);
 
-    if (reconfig)
+    if (reconfig) {
+        /* update the pager popup's width */
+        pager_popup_text_width_to_strings(desktop_cycle_popup,
+                                          screen_desktop_names,
+                                          screen_num_desktops);
         return;
+    }
 
     /* get the initial size */
     screen_resize();