]> Dogcows Code - chaz/openbox/blobdiff - openbox/client.c
use simple pattern matching for per-app settings. all rules that match are applied...
[chaz/openbox] / openbox / client.c
index 379342f48578efb074fcba9eba417f0fcd480cf7..9b89b10356cd4b947ebc1053692ce8f0bb9e5d5e 100644 (file)
@@ -65,7 +65,6 @@ typedef struct
 GList            *client_list          = 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);
@@ -139,29 +138,6 @@ void client_remove_destroy_notify(ObClientCallback func)
     }
 }
 
-void client_add_hide_notify(ObClientCallback func, gpointer data)
-{
-    ClientCallback *d = g_new(ClientCallback, 1);
-    d->func = func;
-    d->data = data;
-    client_hide_notifies = g_slist_prepend(client_hide_notifies, d);
-}
-
-void client_remove_hide_notify(ObClientCallback func)
-{
-    GSList *it;
-
-    for (it = client_hide_notifies; it; it = g_slist_next(it)) {
-        ClientCallback *d = it->data;
-        if (d->func == func) {
-            g_free(d);
-            client_hide_notifies =
-                g_slist_delete_link(client_hide_notifies, it);
-            break;
-        }
-    }
-}
-
 void client_set_list()
 {
     Window *windows, *win_it;
@@ -338,7 +314,8 @@ void client_manage(Window window)
     grab_server(FALSE);
 
     /* per-app settings override stuff from client_get_all, and return the
-       settings for other uses too */
+       settings for other uses too. the returned settings is a shallow copy,
+       that needs to be freed with g_free(). */
     settings = client_get_settings_state(self);
     /* the session should get the last say thought */
     client_restore_session_state(self);
@@ -386,6 +363,12 @@ void client_manage(Window window)
     if (ob_state() == OB_STATE_RUNNING) {
         gboolean transient;
 
+        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. */
@@ -408,10 +391,6 @@ void client_manage(Window window)
                               !self->session));
     }
 
-    /* do this after the window is placed, so the premax/prefullscreen numbers
-       won't be all wacko!!
-       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, self->area.x, self->area.y,
              self->area.width, self->area.height);
@@ -419,14 +398,25 @@ void client_manage(Window window)
         ob_debug("  but session requested %d %d instead, overriding\n",
                  self->session->x, self->session->y);
 
-    /* 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);
+    /* 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);
 
-    client_apply_startup_state(self);
 
-    mouse_grab_for_client(self, TRUE);
+    /* move the client to its placed position, or it it's already there,
+       generate a ConfigureNotify telling the client where it is.
+
+       do this after adjusting the frame. otherwise it gets all weird and
+       clients don't work right */
+    client_configure(self, self->area.x, self->area.y,
+                     self->area.width, self->area.height,
+                     FALSE, TRUE);
+
+    /* do this after the window is placed, so the premax/prefullscreen numbers
+       won't be all wacko!!
+       also, this moves the window to the position where it has been placed
+    */
+    client_apply_startup_state(self);
 
     if (activate) {
         guint32 last_time = focus_client ?
@@ -494,9 +484,7 @@ void client_manage(Window window)
             stacking_raise(CLIENT_AS_WINDOW(self));
     }
 
-    /* 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);
+    mouse_grab_for_client(self, TRUE);
 
     /* 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
@@ -519,7 +507,11 @@ void client_manage(Window window)
     /* update the list hints */
     client_set_list();
 
-    ob_debug("Managed window 0x%lx (%s)\n", window, self->class);
+    /* free the ObAppSettings shallow copy */
+    g_free(settings);
+
+    ob_debug("Managed window 0x%lx plate 0x%x (%s)\n",
+             window, self->frame->plate, self->class);
 
     return;
 }
@@ -539,7 +531,7 @@ ObClient *client_fake_manage(Window window)
 
     client_get_all(self, FALSE);
     /* per-app settings override stuff, and return the settings for other
-       uses too */
+       uses too. this returns a shallow copy that needs to be freed */
     settings = client_get_settings_state(self);
 
     client_setup_decor_and_functions(self);
@@ -547,6 +539,10 @@ ObClient *client_fake_manage(Window window)
     /* create the decoration frame for the client window and adjust its size */
     self->frame = frame_new(self);
     frame_adjust_area(self->frame, FALSE, TRUE, TRUE);
+
+    /* free the ObAppSettings shallow copy */
+    g_free(settings);
+
     return self;
 }
 
@@ -561,7 +557,8 @@ void client_unmanage(ObClient *self)
     guint j;
     GSList *it;
 
-    ob_debug("Unmanaging window: %lx (%s) (%s)\n", self->window,
+    ob_debug("Unmanaging window: 0x%x plate 0x%x (%s) (%s)\n",
+             self->window, self->frame->plate,
              self->class, self->title ? self->title : "");
 
     g_assert(self != NULL);
@@ -576,7 +573,7 @@ void client_unmanage(ObClient *self)
 
     /* ignore enter events from the unmap so it doesnt mess with the
        focus */
-    event_ignore_queued_enters();
+    event_ignore_all_queued_enters();
 
     mouse_grab_for_client(self, FALSE);
 
@@ -705,30 +702,39 @@ void client_fake_unmanage(ObClient *self)
     g_free(self);
 }
 
+/*! Returns a new structure containing the per-app settings for this client.
+  The returned structure needs to be freed with g_free. */
 static ObAppSettings *client_get_settings_state(ObClient *self)
 {
-    ObAppSettings *settings = NULL;
+    ObAppSettings *settings;
     GSList *it;
 
+    settings = config_create_app_settings();
+
     for (it = config_per_app_settings; it; it = g_slist_next(it)) {
         ObAppSettings *app = it->data;
-        
-        if ((app->name && !app->class && !strcmp(app->name, self->name))
-            || (app->class && !app->name && !strcmp(app->class, self->class))
-            || (app->class && app->name && !strcmp(app->class, self->class)
-                && !strcmp(app->name, self->name)))
-        {
-            /* Match if no role was specified in the per app setting, or if the
-             * string matches the beginning of the role, since apps like to set
-             * the role to things like browser-window-23c4b2f */
-            if (!app->role
-                || !strncmp(app->role, self->role, strlen(app->role)))
-            {
-                ob_debug("Window matching: %s\n", app->name);
-                /* use this one */
-                settings = app;
-                break;
-            }
+        gboolean match = TRUE;
+
+        g_assert(app->name != NULL || app->class != NULL);
+
+        /* we know that either name or class is not NULL so it will have to
+           match to use the rule */
+        if (app->name &&
+            !g_pattern_match(app->name, strlen(self->name), self->name, NULL))
+            match = FALSE;
+        if (app->class &&
+            !g_pattern_match(app->class, strlen(self->class),self->class,NULL))
+            match = FALSE;
+        if (app->role &&
+            !g_pattern_match(app->role, strlen(self->role), self->role, NULL))
+            match = FALSE;
+
+        if (match) {
+            ob_debug("Window matching: %s\n", app->name);
+
+            /* copy the settings to our struct, overriding the existing
+               settings if they are not defaults */
+            config_app_settings_copy_non_defaults(app, settings);
         }
     }
 
@@ -864,9 +870,11 @@ gboolean client_find_onscreen(ObClient *self, gint *x, gint *y, gint w, gint h,
     gint ox = *x, oy = *y;
     gboolean rudel = rude, ruder = rude, rudet = rude, rudeb = rude;
     gint fw, fh;
+    Rect desired;
 
+    RECT_SET(desired, *x, *y, w, h);
     all_a = screen_area(self->desktop);
-    mon_a = screen_area_monitor(self->desktop, client_monitor(self));
+    mon_a = screen_area_monitor(self->desktop, screen_find_monitor(&desired));
 
     /* get where the frame would be */
     frame_client_gravity(self->frame, x, y, w, h);
@@ -1175,7 +1183,7 @@ static void client_get_state(ObClient *self)
                 self->below = TRUE;
             else if (state[i] == prop_atoms.net_wm_state_demands_attention)
                 self->demands_attention = TRUE;
-            else if (state[i] == prop_atoms.openbox_wm_state_undecorated)
+            else if (state[i] == prop_atoms.ob_wm_state_undecorated)
                 self->undecorated = TRUE;
         }
 
@@ -1596,7 +1604,8 @@ void client_setup_decor_and_functions(ObClient *self)
          OB_CLIENT_FUNC_SHADE |
          OB_CLIENT_FUNC_CLOSE |
          OB_CLIENT_FUNC_BELOW |
-         OB_CLIENT_FUNC_ABOVE);
+         OB_CLIENT_FUNC_ABOVE |
+         OB_CLIENT_FUNC_UNDECORATE);
 
     if (!(self->min_size.width < self->max_size.width ||
           self->min_size.height < self->max_size.height))
@@ -1695,6 +1704,11 @@ void client_setup_decor_and_functions(ObClient *self)
     if (self->max_vert && self->max_horz)
         self->decorations &= ~(OB_FRAME_DECOR_HANDLE | OB_FRAME_DECOR_GRIPS);
 
+    /* If there are no decorations to remove, don't allow the user to try
+       toggle the state */
+    if (self->decorations == 0)
+        self->functions &= ~OB_CLIENT_FUNC_UNDECORATE;
+
     /* finally, the user can have requested no decorations, which overrides
        everything (but doesnt give it a border if it doesnt have one) */
     if (self->undecorated) {
@@ -1726,7 +1740,7 @@ void client_setup_decor_and_functions(ObClient *self)
 
 static void client_change_allowed_actions(ObClient *self)
 {
-    gulong actions[11];
+    gulong actions[12];
     gint num = 0;
 
     /* desktop windows are kept on all desktops */
@@ -1753,6 +1767,8 @@ static void client_change_allowed_actions(ObClient *self)
         actions[num++] = prop_atoms.net_wm_action_above;
     if (self->functions & OB_CLIENT_FUNC_BELOW)
         actions[num++] = prop_atoms.net_wm_action_below;
+    if (self->functions & OB_CLIENT_FUNC_UNDECORATE)
+        actions[num++] = prop_atoms.ob_wm_action_undecorate;
 
     PROP_SETA32(self->window, net_wm_allowed_actions, atom, actions, num);
 
@@ -2290,7 +2306,7 @@ static void client_change_state(ObClient *self)
     if (self->demands_attention)
         netstate[num++] = prop_atoms.net_wm_state_demands_attention;
     if (self->undecorated)
-        netstate[num++] = prop_atoms.openbox_wm_state_undecorated;
+        netstate[num++] = prop_atoms.ob_wm_state_undecorated;
     PROP_SETA32(self->window, net_wm_state, atom, netstate, num);
 
     if (self->frame)
@@ -2348,13 +2364,14 @@ static ObStackingLayer calc_layer(ObClient *self)
         else l = OB_STACKING_LAYER_ABOVE;
     }
     else if ((self->fullscreen ||
-              /* no decorations and fills the monitor = oldskool fullscreen */
-              (self->frame != NULL &&
-               (self->frame->size.right == 0 && self->frame->size.left == 0 &&
-                self->frame->size.bottom == 0 && self->frame->size.top == 0 &&
-                RECT_EQUAL(self->area,
-                           *screen_physical_area_monitor
-                           (client_monitor(self)))))) &&
+              /* No decorations and fills the monitor = oldskool fullscreen.
+                 But not for undecorated windows, because the user can do that
+              */
+              (self->decorations == 0 &&
+               !self->undecorated &&
+               RECT_EQUAL(self->area,
+                          *screen_physical_area_monitor
+                          (client_monitor(self))))) &&
              (client_focused(self) || client_search_focus_tree(self)))
         l = OB_STACKING_LAYER_FULLSCREEN;
     else if (self->above) l = OB_STACKING_LAYER_ABOVE;
@@ -2410,11 +2427,13 @@ gboolean client_should_show(ObClient *self)
     return FALSE;
 }
 
-void client_show(ObClient *self)
+gboolean client_show(ObClient *self)
 {
+    gboolean show = FALSE;
 
     if (client_should_show(self)) {
         frame_show(self->frame);
+        show = TRUE;
     }
 
     /* According to the ICCCM (sec 4.1.3.1) when a window is not visible, it
@@ -2422,14 +2441,28 @@ void client_show(ObClient *self)
        desktop!
     */
     client_change_wm_state(self);
+    return show;
 }
 
-void client_hide(ObClient *self)
+gboolean client_hide(ObClient *self)
 {
+    gboolean hide = FALSE;
+
     if (!client_should_show(self)) {
-        frame_hide(self->frame);
+        if (self == focus_client) {
+            /* 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();
+        }
 
-        client_call_notifies(self, client_hide_notifies);
+        frame_hide(self->frame);
+        hide = TRUE;
     }
 
     /* According to the ICCCM (sec 4.1.3.1) when a window is not visible, it
@@ -2437,19 +2470,13 @@ void client_hide(ObClient *self)
        desktop!
     */
     client_change_wm_state(self);
+    return hide;
 }
 
 void client_showhide(ObClient *self)
 {
-
-    if (client_should_show(self)) {
-        frame_show(self->frame);
-    }
-    else {
-        frame_hide(self->frame);
-
-        client_call_notifies(self, client_hide_notifies);
-    }
+    if (!client_show(self))
+        client_hide(self);
 
     /* According to the ICCCM (sec 4.1.3.1) when a window is not visible, it
        needs to be in IconicState. This includes when it is on another
@@ -2704,12 +2731,13 @@ void client_try_configure(ObClient *self, gint *x, gint *y, gint *w, gint *h,
 }
 
 
-void client_configure_full(ObClient *self, gint x, gint y, gint w, gint h,
-                           gboolean user, gboolean final)
+void client_configure(ObClient *self, gint x, gint y, gint w, gint h,
+                      gboolean user, gboolean final)
 {
     gint oldw, oldh;
     gboolean send_resize_client;
     gboolean moved = FALSE, resized = FALSE;
+    gboolean fmoved, fresized;
     guint fdecor = self->frame->decorations;
     gboolean fhorz = self->frame->max_horz;
     gint logicalw, logicalh;
@@ -2745,10 +2773,12 @@ void client_configure_full(ObClient *self, gint x, gint y, gint w, gint h,
     }
 
     /* find the frame's dimensions and move/resize it */
+    fmoved = moved;
+    fresized = resized;
     if (self->decorations != fdecor || self->max_horz != fhorz)
-        moved = resized = TRUE;
-    if (moved || resized)
-        frame_adjust_area(self->frame, moved, resized, FALSE);
+        fmoved = fresized = TRUE;
+    if (fmoved || fresized)
+        frame_adjust_area(self->frame, fmoved, fresized, FALSE);
 
     if ((!user || (user && final)) && !resized)
     {
@@ -2801,7 +2831,6 @@ void client_fullscreen(ObClient *self, gboolean fs)
 
     self->fullscreen = fs;
     client_change_state(self); /* change the state hints on the client */
-    client_calc_layer(self);   /* and adjust out layer/stacking */
 
     if (fs) {
         self->pre_fullscreen_area = self->area;
@@ -2816,36 +2845,36 @@ void client_fullscreen(ObClient *self, gboolean fs)
             self->pre_fullscreen_area.height = self->pre_max_area.height;
         }
 
-        /* these are not actually used cuz client_configure will set them
-           as appropriate when the window is fullscreened */
-        x = y = w = h = 0;
+        /* these will help configure_full figure out where to fullscreen
+           the window */
+        x = self->area.x;
+        y = self->area.y;
+        w = self->area.width;
+        h = self->area.height;
     } else {
-        Rect *a;
+        g_assert(self->pre_fullscreen_area.width > 0 &&
+                 self->pre_fullscreen_area.height > 0);
 
-        if (self->pre_fullscreen_area.width > 0 &&
-            self->pre_fullscreen_area.height > 0)
-        {
-            x = self->pre_fullscreen_area.x;
-            y = self->pre_fullscreen_area.y;
-            w = self->pre_fullscreen_area.width;
-            h = self->pre_fullscreen_area.height;
-            RECT_SET(self->pre_fullscreen_area, 0, 0, 0, 0);
-        } else {
-            /* pick some fallbacks... */
-            a = screen_area_monitor(self->desktop, 0);
-            x = a->x + a->width / 4;
-            y = a->y + a->height / 4;
-            w = a->width / 2;
-            h = a->height / 2;
-        }
+        x = self->pre_fullscreen_area.x;
+        y = self->pre_fullscreen_area.y;
+        w = self->pre_fullscreen_area.width;
+        h = self->pre_fullscreen_area.height;
+        RECT_SET(self->pre_fullscreen_area, 0, 0, 0, 0);
     }
 
     client_setup_decor_and_functions(self);
 
     client_move_resize(self, x, y, w, h);
 
-    /* try focus us when we go into fullscreen mode */
-    client_focus(self);
+    /* and adjust our layer/stacking. do this after resizing the window,
+       and applying decorations, because windows which fill the screen are
+       considered "fullscreen" and it affects their layer */
+    client_calc_layer(self);
+
+    if (fs) {
+        /* try focus us when we go into fullscreen mode */
+        client_focus(self);
+    }
 }
 
 static void client_iconify_recursive(ObClient *self,
@@ -2933,8 +2962,8 @@ void client_maximize(ObClient *self, gboolean max, gint dir)
         if (dir == 2 && !self->max_vert) return;
     }
 
-    /* we just tell it to configure in the same place and client_configure
-       worries about filling the screen with the window */
+    /* these will help configure_full figure out which screen to fill with
+       the window */
     x = self->area.x;
     y = self->area.y;
     w = self->area.width;
@@ -2952,34 +2981,23 @@ void client_maximize(ObClient *self, gboolean max, gint dir)
                      self->pre_max_area.width, self->area.height);
         }
     } else {
-        Rect *a;
-
-        a = screen_area_monitor(self->desktop, 0);
         if ((dir == 0 || dir == 1) && self->max_horz) { /* horz */
-            if (self->pre_max_area.width > 0) {
-                x = self->pre_max_area.x;
-                w = self->pre_max_area.width;
+            g_assert(self->pre_max_area.width > 0);
 
-                RECT_SET(self->pre_max_area, 0, self->pre_max_area.y,
-                         0, self->pre_max_area.height);
-            } else {
-                /* pick some fallbacks... */
-                x = a->x + a->width / 4;
-                w = a->width / 2;
-            }
+            x = self->pre_max_area.x;
+            w = self->pre_max_area.width;
+
+            RECT_SET(self->pre_max_area, 0, self->pre_max_area.y,
+                     0, self->pre_max_area.height);
         }
         if ((dir == 0 || dir == 2) && self->max_vert) { /* vert */
-            if (self->pre_max_area.height > 0) {
-                y = self->pre_max_area.y;
-                h = self->pre_max_area.height;
+            g_assert(self->pre_max_area.height > 0);
 
-                RECT_SET(self->pre_max_area, self->pre_max_area.x, 0,
-                         self->pre_max_area.width, 0);
-            } else {
-                /* pick some fallbacks... */
-                y = a->y + a->height / 4;
-                h = a->height / 2;
-            }
+            y = self->pre_max_area.y;
+            h = self->pre_max_area.height;
+
+            RECT_SET(self->pre_max_area, self->pre_max_area.x, 0,
+                     self->pre_max_area.width, 0);
         }
     }
 
@@ -3218,7 +3236,7 @@ void client_set_state(ObClient *self, Atom action, glong data1, glong data2)
                 action = self->demands_attention ?
                     prop_atoms.net_wm_state_remove :
                     prop_atoms.net_wm_state_add;
-            else if (state == prop_atoms.openbox_wm_state_undecorated)
+            else if (state == prop_atoms.ob_wm_state_undecorated)
                 action = undecorated ? prop_atoms.net_wm_state_remove :
                     prop_atoms.net_wm_state_add;
         }
@@ -3248,7 +3266,7 @@ void client_set_state(ObClient *self, Atom action, glong data1, glong data2)
                 below = TRUE;
             } else if (state == prop_atoms.net_wm_state_demands_attention) {
                 demands_attention = TRUE;
-            } else if (state == prop_atoms.openbox_wm_state_undecorated) {
+            } else if (state == prop_atoms.ob_wm_state_undecorated) {
                 undecorated = TRUE;
             }
 
@@ -3275,11 +3293,12 @@ void client_set_state(ObClient *self, Atom action, glong data1, glong data2)
                 below = FALSE;
             } else if (state == prop_atoms.net_wm_state_demands_attention) {
                 demands_attention = FALSE;
-            } else if (state == prop_atoms.openbox_wm_state_undecorated) {
+            } else if (state == prop_atoms.ob_wm_state_undecorated) {
                 undecorated = FALSE;
             }
         }
     }
+
     if (max_horz != self->max_horz || max_vert != self->max_vert) {
         if (max_horz != self->max_horz && max_vert != self->max_vert) {
             /* toggling both */
@@ -3305,24 +3324,30 @@ void client_set_state(ObClient *self, Atom action, glong data1, glong data2)
         client_shade(self, shaded);
     if (undecorated != self->undecorated)
         client_set_undecorated(self, undecorated);
+    if (above != self->above || below != self->below) {
+        self->above = above;
+        self->below = below;
+        client_calc_layer(self);
+    }
+
     if (modal != self->modal) {
         self->modal = modal;
         /* when a window changes modality, then its stacking order with its
            transients needs to change */
         stacking_raise(CLIENT_AS_WINDOW(self));
+
+        /* it also may get focused. if something is focused that shouldn't
+           be focused anymore, then move the focus */
+        if (focus_client && client_focus_target(focus_client) != focus_client)
+            client_focus(focus_client);
     }
+
     if (iconic != self->iconic)
         client_iconify(self, iconic, FALSE, FALSE);
 
     if (demands_attention != self->demands_attention)
         client_hilite(self, demands_attention);
 
-    if (above != self->above || below != self->below) {
-        self->above = above;
-        self->below = below;
-        client_calc_layer(self);
-    }
-
     client_change_state(self); /* change the hint to reflect these changes */
 }
 
@@ -3337,8 +3362,6 @@ ObClient *client_focus_target(ObClient *self)
 
 gboolean client_can_focus(ObClient *self)
 {
-    XEvent ev;
-
     /* choose the correct target */
     self = client_focus_target(self);
 
@@ -3348,24 +3371,6 @@ gboolean client_can_focus(ObClient *self)
     if (!(self->can_focus || self->focus_notify))
         return FALSE;
 
-    /* do a check to see if the window has already been unmapped or destroyed
-       do this intelligently while watching out for unmaps we've generated
-       (ignore_unmaps > 0) */
-    if (XCheckTypedWindowEvent(ob_display, self->window,
-                               DestroyNotify, &ev)) {
-        XPutBackEvent(ob_display, &ev);
-        return FALSE;
-    }
-    while (XCheckTypedWindowEvent(ob_display, self->window,
-                                  UnmapNotify, &ev)) {
-        if (self->ignore_unmaps) {
-            self->ignore_unmaps--;
-        } else {
-            XPutBackEvent(ob_display, &ev);
-            return FALSE;
-        }
-    }
-
     return TRUE;
 }
 
@@ -3396,13 +3401,14 @@ gboolean client_focus(ObClient *self)
     if (keyboard_interactively_grabbed())
         keyboard_interactive_cancel();
 
+    xerror_set_ignore(TRUE);
+    xerror_occured = FALSE;
+
     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. */
-        xerror_set_ignore(TRUE);
         XSetInputFocus(ob_display, self->window, RevertToPointerRoot,
                        event_curtime);
-        xerror_set_ignore(FALSE);
     }
 
     if (self->focus_notify) {
@@ -3420,17 +3426,9 @@ gboolean client_focus(ObClient *self)
         XSendEvent(ob_display, self->window, FALSE, NoEventMask, &ce);
     }
 
-#ifdef DEBUG_FOCUS
-    ob_debug("%sively focusing %lx at %d\n",
-             (self->can_focus ? "act" : "pass"),
-             self->window, (gint) event_curtime);
-#endif
+    xerror_set_ignore(FALSE);
 
-    /* Cause the FocusIn to come back to us. Important for desktop switches,
-       since otherwise we'll have no FocusIn on the queue and send it off to
-       the focus_backup. */
-    XSync(ob_display, FALSE);
-    return TRUE;
+    return !xerror_occured;
 }
 
 /*! Present the client to the user.
@@ -3600,16 +3598,13 @@ void client_set_layer(ObClient *self, gint layer)
 
 void client_set_undecorated(ObClient *self, gboolean undecorated)
 {
-    if (self->undecorated != undecorated) {
+    if (self->undecorated != undecorated &&
+        /* don't let it undecorate if the function is missing, but let 
+           it redecorate */
+        (self->functions & OB_CLIENT_FUNC_UNDECORATE || !undecorated))
+    {
         self->undecorated = undecorated;
         client_setup_decor_and_functions(self);
-        /* Make sure the client knows it might have moved. Maybe there is a
-         * better way of doing this so only one client_configure is sent, but
-         * since 125 of these are sent per second when moving the window (with
-         * user = FALSE) i doubt it matters much.
-         */
-        client_configure(self, self->area.x, self->area.y,
-                         self->area.width, self->area.height, TRUE, TRUE);
         client_change_state(self); /* reflect this in the state hints */
     }
 }
@@ -3740,8 +3735,6 @@ ObClient *client_search_transient(ObClient *self, ObClient *search)
             if(screen_desktop != cur->desktop && cur->desktop != DESKTOP_ALL) \
                 continue;                                                     \
             if(cur->iconic)                                                   \
-                continue;                                                     \
-            if(cur->layer == c->layer)                                        \
                 continue;
 
 #define HIT_EDGE(my_edge_start, my_edge_end, his_edge_start, his_edge_end) \
This page took 0.040701 seconds and 4 git commands to generate.