more focus improvements. everything seems to work!
authorDana Jansens <danakj@orodu.net>
Mon, 24 Mar 2003 04:56:46 +0000 (04:56 +0000)
committerDana Jansens <danakj@orodu.net>
Mon, 24 Mar 2003 04:56:46 +0000 (04:56 +0000)
openbox/client.c
openbox/client.h
openbox/dispatch.h
openbox/event.c
openbox/focus.c

index 7a5bc3d..7d20abb 100644 (file)
@@ -239,17 +239,6 @@ void client_unmanage(Client *client)
 
     engine_frame_hide(client->frame);
 
-    /* dispatch the unmapped event */
-    dispatch_client(Event_Client_Unmapped, client, 0, 0);
-    g_assert(client != NULL);
-
-    /* give the client its border back */
-    client_toggle_border(client, TRUE);
-
-    /* reparent the window out of the frame, and free the frame */
-    engine_frame_release_client(client->frame, client);
-    client->frame = NULL;
-     
     client_list = g_slist_remove(client_list, client);
     stacking_list = g_list_remove(stacking_list, client);
     g_hash_table_remove(client_map, (gpointer)client->window);
@@ -278,11 +267,22 @@ void client_unmanage(Client *client)
        client_calc_layer(it->data);
     }
 
+    /* dispatch the unmapped event */
+    dispatch_client(Event_Client_Unmapped, client, 0, 0);
+    g_assert(client != NULL);
+
     /* unfocus the client (dispatchs the focus event) (we're out of the
      transient lists already, so being modal doesn't matter) */
     if (client_focused(client))
        client_unfocus(client);
 
+    /* give the client its border back */
+    client_toggle_border(client, TRUE);
+
+    /* reparent the window out of the frame, and free the frame */
+    engine_frame_release_client(client->frame, client);
+    client->frame = NULL;
+     
     if (ob_state != State_Exiting) {
        /* these values should not be persisted across a window
           unmapping/mapping */
@@ -1511,6 +1511,9 @@ void client_iconify(Client *self, gboolean iconic, gboolean curdesk)
     client_change_state(self);
     client_showhide(self);
     screen_update_struts();
+
+    dispatch_client(iconic ? Event_Client_Unmapped : Event_Client_Mapped,
+                    self, 0, 0);
 }
 
 void client_maximize(Client *self, gboolean max, int dir, gboolean savearea)
@@ -1650,7 +1653,7 @@ void client_close(Client *self)
     ce.xclient.window = self->window;
     ce.xclient.format = 32;
     ce.xclient.data.l[0] = prop_atoms.wm_delete_window;
-    ce.xclient.data.l[1] = CurrentTime;
+    ce.xclient.data.l[1] = event_lasttime;
     ce.xclient.data.l[2] = 0l;
     ce.xclient.data.l[3] = 0l;
     ce.xclient.data.l[4] = 0l;
@@ -1902,11 +1905,11 @@ gboolean client_focus(Client *self)
        }
     }
 
-    if (client_focused(self))
-        return TRUE;
+    g_message("** focusing %lx", self->window);
 
     if (self->can_focus)
-       XSetInputFocus(ob_display, self->window, RevertToNone, CurrentTime);
+       XSetInputFocus(ob_display, self->window, RevertToNone,
+                       CurrentTime);
 
     if (self->focus_notify) {
        XEvent ce;
@@ -1916,7 +1919,7 @@ gboolean client_focus(Client *self)
        ce.xclient.window = self->window;
        ce.xclient.format = 32;
        ce.xclient.data.l[0] = prop_atoms.wm_take_focus;
-       ce.xclient.data.l[1] = event_lasttime;
+       ce.xclient.data.l[1] = CurrentTime;
        ce.xclient.data.l[2] = 0l;
        ce.xclient.data.l[3] = 0l;
        ce.xclient.data.l[4] = 0l;
@@ -1930,10 +1933,26 @@ gboolean client_focus(Client *self)
 void client_unfocus(Client *self)
 {
     g_assert(focus_client == self);
-    focus_set_client(NULL);
+    client_set_focused(self, FALSE);
 }
 
 gboolean client_focused(Client *self)
 {
     return self == focus_client;
 }
+
+void client_set_focused(Client *self, gboolean focused)
+{
+    if (focused) {
+        if (focus_client != self)
+            focus_set_client(self);
+    } else {
+       if (focus_client == self)
+           focus_set_client(NULL);
+    }
+
+    /* focus state can affect the stacking layer */
+    client_calc_layer(self);
+
+    engine_frame_adjust_focus(self->frame);
+}
index e51315c..808f4e5 100644 (file)
@@ -320,6 +320,11 @@ gboolean client_normal(Client *self);
 /* Returns if the window is focused */
 gboolean client_focused(Client *self);
 
+/*! Sets the client to a focused or unfocused state. This does not actually
+  change the input focus, but rather is used once focus has been moved to tell
+  the client that it is so. */
+void client_set_focused(Client *self, gboolean focused);
+
 /*! Move and/or resize the window.
   This also maintains things like the client's minsize, and size increments.
   @param anchor The corner to keep in the same position when resizing.
index 31116c5..412e135 100644 (file)
@@ -18,9 +18,11 @@ typedef enum {
     Event_X_Bell          = 1 << 7, /* an XKB bell event */
 
     Event_Client_New      = 1 << 8, /* new window, before mapping */
-    Event_Client_Mapped   = 1 << 9, /* new window, after mapping */
+    Event_Client_Mapped   = 1 << 9, /* new window, after mapping
+                                       or uniconified */
     Event_Client_Destroy  = 1 << 10, /* unmanaged */
-    Event_Client_Unmapped = 1 << 11, /* unmanaged, after unmapping */
+    Event_Client_Unmapped = 1 << 11, /* unmanaged, after unmapping
+                                        or iconified */
     Event_Client_Focus    = 1 << 12, /* focused */
     Event_Client_Unfocus  = 1 << 13, /* unfocused */
     Event_Client_Urgent   = 1 << 14, /* entered/left urgent state */
index ab0f8d8..88db5e9 100644 (file)
@@ -219,36 +219,31 @@ void event_process(XEvent *e)
        event_lasttime = e->xproperty.time;
        break;
     case FocusIn:
-       if (e->xfocus.mode == NotifyGrab) return;
-/*     if (e->type == FocusIn && window == focus_backup && focus_client != NULL) {
-*/
-            /* Something's focused but we got a focus event for the backup
-               window. this means that something unfocused before we received
-               the new FocusIn. Just ignore it, and refocus what should be
-               focused! */
-/*            client_focus(focus_client);
+       if (e->xfocus.mode == NotifyGrab ||
+            !(e->xfocus.detail == NotifyNonlinearVirtual ||
+              e->xfocus.detail == NotifyNonlinear))
             return;
-        }
-*/
+        g_message("FOCUS IN %lx", window);
         break;
     case FocusOut:
-       if (e->xfocus.mode == NotifyGrab) return;
-           /*|| e.xfocus.mode == NotifyUngrab ||*/
-           /* From Metacity, from WindowMaker, ignore all funky pointer
-              root events. Its commented out cuz I don't think we need this
-              at all. If problems arise we can look into it */
-           /*e.xfocus.detail > NotifyNonlinearVirtual) */
+       if (e->xfocus.mode == NotifyGrab ||
+            !(e->xfocus.detail == NotifyNonlinearVirtual ||
+              e->xfocus.detail == NotifyNonlinear))
+            return;
 
         /* FocusOut events just make us look for FocusIn events. They
            are mostly ignored otherwise. */
         {
             XEvent fi;
             if (XCheckTypedEvent(ob_display, FocusIn, &fi)) {
+                g_message("FOCUS OUT %lx IN %lx", e->xfocus.window, fi.xfocus.window);
                event_process(&fi);
-               /* dont unfocus the window we just focused! */
-               if (fi.xfocus.window == e->xfocus.window)
-                   return;
-           }
+
+                if (fi.xfocus.window == e->xfocus.window)
+                    return;
+           } else {
+                g_message("FOCUS OUT %lx IN 0x0", e->xfocus.window);
+            }
         }
        break;
     case EnterNotify:
@@ -334,22 +329,8 @@ static void event_handle_client(Client *client, XEvent *e)
      
     switch (e->type) {
     case FocusIn:
-        if (focus_client != client)
-            focus_set_client(client);
-
-        /* focus state can affect the stacking layer */
-        client_calc_layer(client);
-
-        engine_frame_adjust_focus(client->frame);
-       break;
     case FocusOut:
-       if (focus_client == client)
-           focus_set_client(NULL);
-
-        /* focus state can affect the stacking layer */
-        client_calc_layer(client);
-
-        engine_frame_adjust_focus(client->frame);
+        client_set_focused(client, e->type == FocusIn);
        break;
     case ConfigureRequest:
        g_message("ConfigureRequest for window %lx", client->window);
@@ -508,7 +489,7 @@ static void event_handle_client(Client *client, XEvent *e)
            client_set_desktop(client, e->xclient.data.l[0]);
        } else if (msgtype == prop_atoms.net_wm_state) {
            /* can't compress these */
-           g_message("net_wm_state %s %ld %ld for 0x%lx\n",
+           g_message("net_wm_state %s %ld %ld for 0x%lx",
                      (e->xclient.data.l[0] == 0 ? "Remove" :
                       e->xclient.data.l[0] == 1 ? "Add" :
                       e->xclient.data.l[0] == 2 ? "Toggle" : "INVALID"),
@@ -517,10 +498,10 @@ static void event_handle_client(Client *client, XEvent *e)
            client_set_state(client, e->xclient.data.l[0],
                             e->xclient.data.l[1], e->xclient.data.l[2]);
        } else if (msgtype == prop_atoms.net_close_window) {
-           g_message("net_close_window for 0x%lx\n", client->window);
+           g_message("net_close_window for 0x%lx", client->window);
            client_close(client);
        } else if (msgtype == prop_atoms.net_active_window) {
-           g_message("net_active_window for 0x%lx\n", client->window);
+           g_message("net_active_window for 0x%lx", client->window);
            if (screen_showing_desktop)
                screen_show_desktop(FALSE);
            if (client->iconic)
index 75bd6bc..9b6eead 100644 (file)
@@ -1,8 +1,10 @@
+#include "event.h"
 #include "openbox.h"
 #include "client.h"
 #include "screen.h"
 #include "prop.h"
 #include "dispatch.h"
+#include "focus.h"
 
 #include <X11/Xlib.h>
 #include <glib.h>
@@ -13,8 +15,6 @@ GList **focus_order = NULL; /* these lists are created when screen_startup
 
 Window focus_backup = None;
 
-void focus_set_client(Client *client);
-
 void focus_startup()
 {
     /* create the window which gets focus when no clients get it. Have to
@@ -62,7 +62,7 @@ void focus_set_client(Client *client)
 
     if (client == NULL) {
        /* when nothing will be focused, send focus to the backup target */
-       XSetInputFocus(ob_display, focus_backup, RevertToNone, CurrentTime);
+       XSetInputFocus(ob_display, focus_backup, RevertToNone, event_lasttime);
     }
 
     old = focus_client;