]> Dogcows Code - chaz/openbox/blobdiff - openbox/client.c
make an event queue for X events. the queue's min size is 16 XEvents (~3k)
[chaz/openbox] / openbox / client.c
index e64fd49c2e0b4a890f852cca627f40e5fabeae85..0a32621e38cfc5382ff89ed07266456e0f4997c6 100644 (file)
@@ -42,6 +42,7 @@
 #include "obrender/render.h"
 #include "gettext.h"
 #include "obt/display.h"
+#include "obt/xqueue.h"
 #include "obt/prop.h"
 
 #ifdef HAVE_UNISTD_H
@@ -203,14 +204,12 @@ void client_manage(Window window, ObPrompt *prompt)
     ObAppSettings *settings;
     gboolean transient = FALSE;
     Rect place;
-    Time launch_time, map_time;
+    Time launch_time;
     guint32 user_time;
     gboolean obplaced;
 
     ob_debug("Managing window: 0x%lx", window);
 
-    map_time = event_get_server_time();
-
     /* choose the events we want to receive on the CLIENT window
        (ObPrompt windows can request events too) */
     attrib_set.event_mask = CLIENT_EVENTMASK |
@@ -272,7 +271,7 @@ void client_manage(Window window, ObPrompt *prompt)
     launch_time = sn_app_started(self->startup_id, self->class, self->name);
 
     if (!OBT_PROP_GET32(self->window, NET_WM_USER_TIME, CARDINAL, &user_time))
-        user_time = map_time;
+        user_time = event_time();
 
     /* do this after we have a frame.. it uses the frame to help determine the
        WM_STATE to apply. */
@@ -295,7 +294,7 @@ void client_manage(Window window, ObPrompt *prompt)
         /* this checks for focus=false for the window */
         (!settings || settings->focus != 0) &&
         focus_valid_target(self, self->desktop,
-                           FALSE, FALSE, TRUE, FALSE, FALSE,
+                           FALSE, FALSE, TRUE, TRUE, FALSE, FALSE,
                            settings->focus == 1))
     {
         activate = TRUE;
@@ -335,6 +334,8 @@ void client_manage(Window window, ObPrompt *prompt)
         /* watch for buggy apps that ask to be placed at (0,0) when there is
            a strut there */
         if (!obplaced && place.x == 0 && place.y == 0 &&
+            /* non-normal windows are allowed */
+            client_normal(self) &&
             /* oldschool fullscreen windows are allowed */
             !client_is_oldfullscreen(self, &place))
         {
@@ -439,7 +440,7 @@ void client_manage(Window window, ObPrompt *prompt)
     ob_debug_type(OB_DEBUG_FOCUS, "Going to try activate new window? %s",
                   activate ? "yes" : "no");
     if (activate) {
-        activate = client_can_steal_focus(self, map_time, launch_time);
+        activate = client_can_steal_focus(self, event_time(), launch_time);
 
         if (!activate) {
             /* if the client isn't stealing focus, then hilite it so the user
@@ -723,8 +724,9 @@ static gboolean client_can_steal_focus(ObClient *self, Time steal_time,
     if (!(self->desktop == screen_desktop ||
           self->desktop == DESKTOP_ALL) &&
         /* the timestamp is from before you changed desktops */
-        launch_time && screen_desktop_user_time &&
-        !event_time_after(launch_time, screen_desktop_user_time))
+        (!launch_time ||
+         (screen_desktop_user_time &&
+          !event_time_after(launch_time, screen_desktop_user_time))))
     {
         steal = FALSE;
         ob_debug_type(OB_DEBUG_FOCUS,
@@ -2040,7 +2042,7 @@ void client_update_strut(ObClient *self)
     if (!got &&
         OBT_PROP_GETA32(self->window, NET_WM_STRUT, CARDINAL, &data, &num)) {
         if (num == 4) {
-            Rect const *a;
+            const Rect *a;
 
             got = TRUE;
 
@@ -2465,10 +2467,10 @@ gboolean client_has_parent(ObClient *self)
     return self->parents != NULL;
 }
 
-gboolean client_is_oldfullscreen(const ObClient const *self,
-                                 const Rect const *area)
+gboolean client_is_oldfullscreen(const ObClient *self,
+                                 const Rect *area)
 {
-    Rect const *monitor, *allmonitors;
+    const Rect *monitor, *allmonitors;
 
     /* No decorations and fills the monitor = oldskool fullscreen.
        But not for maximized windows.
@@ -2486,7 +2488,7 @@ gboolean client_is_oldfullscreen(const ObClient const *self,
 static ObStackingLayer calc_layer(ObClient *self)
 {
     ObStackingLayer l;
-    Rect const *monitor, *allmonitors;
+    const Rect *monitor, *allmonitors;
 
     monitor = screen_physical_area_monitor(client_monitor(self));
     allmonitors = screen_physical_area_all_monitors();
@@ -2839,7 +2841,7 @@ void client_try_configure(ObClient *self, gint *x, gint *y, gint *w, gint *h,
 
     /* set the size and position if fullscreen */
     if (self->fullscreen) {
-        Rect const *a;
+        const Rect *a;
         guint i;
 
         i = screen_find_monitor(&desired);
@@ -3127,11 +3129,16 @@ void client_configure(ObClient *self, gint x, gint y, gint w, gint h,
     /* if it moved between monitors, then this can affect the stacking
        layer of this window or others - for fullscreen windows.
        also if it changed to/from oldschool fullscreen then its layer may
-       change */
-    if (screen_find_monitor(&self->frame->area) !=
-        screen_find_monitor(&oldframe) ||
-        (final && (client_is_oldfullscreen(self, &oldclient) !=
-                   client_is_oldfullscreen(self, &self->area))))
+       change
+
+       watch out tho, don't try change stacking stuff if the window is no
+       longer being managed !
+    */
+    if (self->managed &&
+        (screen_find_monitor(&self->frame->area) !=
+         screen_find_monitor(&oldframe) ||
+         (final && (client_is_oldfullscreen(self, &oldclient) !=
+                    client_is_oldfullscreen(self, &self->area)))))
     {
         client_calc_layer(self);
     }
@@ -3396,7 +3403,7 @@ void client_close(ObClient *self)
     else {
         /* request the client to close with WM_DELETE_WINDOW */
         OBT_PROP_MSG_TO(self->window, self->window, WM_PROTOCOLS,
-                        OBT_PROP_ATOM(WM_DELETE_WINDOW), event_curtime,
+                        OBT_PROP_ATOM(WM_DELETE_WINDOW), event_time(),
                         0, 0, 0, NoEventMask);
 
         /* we're trying to close the window, so see if it is responding. if it
@@ -3614,36 +3621,31 @@ ObClient *client_search_modal_child(ObClient *self)
     return NULL;
 }
 
-static gboolean client_validate_unmap(ObClient *self, int n)
-{
-    XEvent e;
-    gboolean ret = TRUE;
-
-    if (XCheckTypedWindowEvent(obt_display, self->window, UnmapNotify, &e)) {
-        if (n < self->ignore_unmaps) // ignore this one, but look for more
-            ret = client_validate_unmap(self, n+1);
-        else
-            ret = FALSE; // the window is going to become unmanaged
-
-        /* put them back on the event stack so they end up in the same order */
-        XPutBackEvent(obt_display, &e);
-    }
+struct ObClientFindDestroyUnmap {
+    Window window;
+    gint ignore_unmaps;
+};
 
-    return ret;
+static gboolean find_destroy_unmap(XEvent *e, gpointer data)
+{
+    struct ObClientFindDestroyUnmap *find = data;
+    if (e->type == DestroyNotify)
+        return e->xdestroywindow.window == find->window;
+    if (e->type == UnmapNotify && e->xunmap.window == find->window)
+        /* ignore the first $find->ignore_unmaps$ many unmap events */
+        return --find->ignore_unmaps < 0;
+    return FALSE;
 }
 
 gboolean client_validate(ObClient *self)
 {
-    XEvent e;
+    struct ObClientFindDestroyUnmap find;
 
     XSync(obt_display, FALSE); /* get all events on the server */
 
-    if (XCheckTypedWindowEvent(obt_display, self->window, DestroyNotify, &e)) {
-        XPutBackEvent(obt_display, &e);
-        return FALSE;
-    }
-
-    if (!client_validate_unmap(self, 0))
+    find.window = self->window;
+    find.ignore_unmaps = self->ignore_unmaps;
+    if (xqueue_exists_local(find_destroy_unmap, &find))
         return FALSE;
 
     return TRUE;
@@ -3835,6 +3837,8 @@ gboolean client_can_focus(ObClient *self)
 
 gboolean client_focus(ObClient *self)
 {
+    if (!client_validate(self)) return FALSE;
+
     /* we might not focus this window, so if we have modal children which would
        be focused instead, bring them to this desktop */
     client_bring_modal_windows(self);
@@ -3850,7 +3854,7 @@ gboolean client_focus(ObClient *self)
 
     ob_debug_type(OB_DEBUG_FOCUS,
                   "Focusing client \"%s\" (0x%x) at time %u",
-                  self->title, self->window, event_curtime);
+                  self->title, self->window, event_time());
 
     /* if using focus_delay, stop the timer now so that focus doesn't
        go moving on us */
@@ -3862,7 +3866,7 @@ gboolean client_focus(ObClient *self)
         /* This can cause a BadMatch error with CurrentTime, or if an app
            passed in a bad time for _NET_WM_ACTIVE_WINDOW. */
         XSetInputFocus(obt_display, self->window, RevertToPointerRoot,
-                       event_curtime);
+                       event_time());
     }
 
     if (self->focus_notify) {
@@ -3873,7 +3877,7 @@ gboolean client_focus(ObClient *self)
         ce.xclient.window = self->window;
         ce.xclient.format = 32;
         ce.xclient.data.l[0] = OBT_PROP_ATOM(WM_TAKE_FOCUS);
-        ce.xclient.data.l[1] = event_curtime;
+        ce.xclient.data.l[1] = event_time();
         ce.xclient.data.l[2] = 0l;
         ce.xclient.data.l[3] = 0l;
         ce.xclient.data.l[4] = 0l;
@@ -3921,7 +3925,7 @@ void client_activate(ObClient *self, gboolean desktop,
     if ((user && (desktop ||
                   self->desktop == DESKTOP_ALL ||
                   self->desktop == screen_desktop)) ||
-        client_can_steal_focus(self, event_curtime, CurrentTime))
+        client_can_steal_focus(self, event_time(), CurrentTime))
     {
         client_present(self, here, raise, unshade);
     }
This page took 0.029436 seconds and 4 git commands to generate.