]> Dogcows Code - chaz/openbox/commitdiff
add the _NET_WM_USER_TIME property support. When focus_new is enabled, don't focus...
authorDana Jansens <danakj@orodu.net>
Sun, 11 Mar 2007 02:06:34 +0000 (02:06 +0000)
committerDana Jansens <danakj@orodu.net>
Sun, 11 Mar 2007 02:06:34 +0000 (02:06 +0000)
openbox/client.c
openbox/client.h
openbox/event.c
openbox/prop.c
openbox/prop.h
openbox/screen.c
openbox/startupnotify.c
openbox/startupnotify.h

index 27e63292931b0ed422149c7a40e900f0f02f2aaa..bfb9f790169f6e39eccd05e634f92d3de0b8544b 100644 (file)
@@ -57,8 +57,10 @@ typedef struct
     gpointer data;
 } Destructor;
 
-GList      *client_list        = NULL;
-GSList     *client_destructors = NULL;
+GList         *client_list           = NULL;
+
+static GSList *client_destructors    = NULL;
+static Time    client_last_user_time = CurrentTime;
 
 static void client_get_all(ObClient *self);
 static void client_toggle_border(ObClient *self, gboolean show);
@@ -298,7 +300,7 @@ void client_manage(Window window)
     client_get_all(self);
     client_restore_session_state(self);
 
-    sn_app_started(self->startup_id, self->class);
+    self->user_time = sn_app_started(self->startup_id, self->class);
 
     /* update the focus lists, do this before the call to change_state or
        it can end up in the list twice! */
@@ -459,15 +461,26 @@ void client_manage(Window window)
        clicking a window to activate is. so keep the new window out of the way
        but do focus it. */
     if (activate) {
-        /* if using focus_delay, stop the timer now so that focus doesn't go
-           moving on us */
-        event_halt_focus_delay();
-
-        client_focus(self);
-        /* since focus can change the stacking orders, if we focus the window
-           then the standard raise it gets is not enough, we need to queue one
-           for after the focus change takes place */
-        client_raise(self);
+        /* This is focus stealing prevention, if a user_time has been set */
+        if (self->user_time == CurrentTime ||
+            self->user_time > client_last_user_time)
+        {
+            /* if using focus_delay, stop the timer now so that focus doesn't
+               go moving on us */
+            event_halt_focus_delay();
+
+            client_focus(self);
+            /* since focus can change the stacking orders, if we focus the
+               window then the standard raise it gets is not enough, we need
+               to queue one for after the focus change takes place */
+            client_raise(self);
+        } else {
+            ob_debug("Focus stealing prevention activated for %s\n",
+                     self->title);
+            /* if the client isn't focused, then hilite it so the user
+               knows it is there */
+            client_hilite(self, TRUE);
+        }
     }
 
     /* client_activate does this but we aret using it so we have to do it
@@ -857,6 +870,7 @@ static void client_get_all(ObClient *self)
     client_update_sm_client_id(self);
     client_update_strut(self);
     client_update_icons(self);
+    client_update_user_time(self, FALSE);
 }
 
 static void client_get_startup_id(ObClient *self)
@@ -1804,6 +1818,26 @@ void client_update_icons(ObClient *self)
         frame_adjust_icon(self->frame);
 }
 
+void client_update_user_time(ObClient *self, gboolean new_event)
+{
+    guint32 time;
+
+    if (PROP_GET32(self->window, net_wm_user_time, cardinal, &time)) {
+        self->user_time = time;
+        /* we set this every time, not just when it grows, because in practice
+           sometimes time goes backwards! (ntpdate.. yay....) so.. if it goes
+           backward we don't want all windows to stop focusing. we'll just
+           assume noone is setting times older than the last one, cuz that
+           would be pretty stupid anyways
+           However! This is called when a window is mapped to get its user time
+           but it's an old number, it's not changing it from new user
+           interaction, so in that case, don't change the last user time.
+        */
+        if (new_event)
+            client_last_user_time = time;
+    }
+}
+
 static void client_change_state(ObClient *self)
 {
     gulong state[2];
index a5011cb6bfbe60f329afaf87ccacfff0c310aae4..cb6eed53e7ae4d9e5b7ab02308f724f1f2071e13 100644 (file)
@@ -269,6 +269,8 @@ struct _ObClient
     ObClientIcon *icons;
     /*! The number of icons in icons */
     guint nicons;
+
+    guint32 user_time;
 };
 
 struct _ObAppSettings
@@ -530,6 +532,8 @@ void client_update_class(ObClient *self);
 void client_update_strut(ObClient *self);
 /*! Updates the window's icons */
 void client_update_icons(ObClient *self);
+/*! Updates the window's user time */
+void client_update_user_time(ObClient *self, gboolean new_event);
 
 /*! Set up what decor should be shown on the window and what functions should
   be allowed (ObClient::decorations and ObClient::functions).
index 558872e85784b26e7a8fae24a62a69598c9f0ea7..9faf9403e6f4a6d328e6f056377eb9cebb8636f1 100644 (file)
@@ -1148,6 +1148,9 @@ static void event_handle_client(ObClient *client, XEvent *e)
         else if (msgtype == prop_atoms.net_wm_icon) {
             client_update_icons(client);
         }
+        else if (msgtype == prop_atoms.net_wm_user_time) {
+            client_update_user_time(client, TRUE);
+        }
         else if (msgtype == prop_atoms.sm_client_id) {
             client_update_sm_client_id(client);
         }
index 977dbe957e6af204988c2bed44643b5bb88aff37..686404d43889986851d8ceb1c88f6a58b37e91d4 100644 (file)
@@ -84,6 +84,7 @@ void prop_startup()
     CREATE(net_wm_icon, "_NET_WM_ICON");
 /*   CREATE(net_wm_pid, "_NET_WM_PID"); */
     CREATE(net_wm_allowed_actions, "_NET_WM_ALLOWED_ACTIONS");
+    CREATE(net_wm_user_time, "_NET_WM_USER_TIME");
     CREATE(net_frame_extents, "_NET_FRAME_EXTENTS");
 
 /*   CREATE(net_wm_ping, "_NET_WM_PING"); */
index 2c36b624f2b71d81410a3a09dfc03241864e0cfc..1931cb658dbf23776d054f8e24573ea232b9a9e1 100644 (file)
@@ -92,6 +92,7 @@ typedef struct Atoms {
     Atom net_wm_icon;
 /*  Atom net_wm_pid; */
     Atom net_wm_allowed_actions;
+    Atom net_wm_user_time;
     Atom net_frame_extents;
 
     /* application protocols */
index c1c61ed5b7ce476501ffce3136d2c8deadb50c49..a4dfb76eb02f1efd9a50e34789ecc1636f2a2744 100644 (file)
@@ -204,7 +204,7 @@ gboolean screen_annex()
                window, screen_support_win);
 
     /* set the _NET_SUPPORTED_ATOMS hint */
-    num_support = 53;
+    num_support = 54;
     i = 0;
     supported = g_new(gulong, num_support);
     supported[i++] = prop_atoms.net_current_desktop;
@@ -258,6 +258,7 @@ gboolean screen_annex()
     supported[i++] = prop_atoms.net_wm_state_demands_attention;
     supported[i++] = prop_atoms.net_moveresize_window;
     supported[i++] = prop_atoms.net_wm_moveresize;
+    supported[i++] = prop_atoms.net_wm_user_time;
     supported[i++] = prop_atoms.net_frame_extents;
     supported[i++] = prop_atoms.ob_wm_state_undecorated;
     g_assert(i == num_support);
index dbb633ef17c4cafb65256669e4018bd0a8f93c10..1e5c45a8dc4a21860a84de93686b72e90d399936 100644 (file)
 void sn_startup(gboolean reconfig) {}
 void sn_shutdown(gboolean reconfig) {}
 gboolean sn_app_starting() { return FALSE; }
-void sn_app_started(gchar *wmclass) {}
+Time sn_app_started(const gchar *id, const gchar *wmclass)
+{
+    return CurrentTime;
+}
 gboolean sn_get_desktop(gchar *id, guint *desktop) { return FALSE; }
 
 #else
@@ -188,9 +191,10 @@ static void sn_event_func(SnMonitorEvent *ev, gpointer data)
         screen_set_root_cursor();
 }
 
-void sn_app_started(const gchar *id, const gchar *wmclass)
+Time sn_app_started(const gchar *id, const gchar *wmclass)
 {
     GSList *it;
+    Time t = CurrentTime;
 
     for (it = sn_waits; it; it = g_slist_next(it)) {
         ObWaitData *d = it->data;
@@ -201,9 +205,11 @@ void sn_app_started(const gchar *id, const gchar *wmclass)
             (seqclass && wmclass && !strcmp(seqclass, wmclass)))
         {
             sn_startup_sequence_complete(d->seq);
+            t = sn_startup_sequence_get_timestamp(d->seq);
             break;
         }
     }
+    return t;
 }
 
 gboolean sn_get_desktop(gchar *id, guint *desktop)
index 1a6d47a14b29d149ad0414e16689012c35eade20..cf23835476c09268a7b90192d80f0667e20068c3 100644 (file)
@@ -20,6 +20,7 @@
 #define ob__startupnotify_h
 
 #include <glib.h>
+#include <X11/Xlib.h>
 
 void sn_startup(gboolean reconfig);
 void sn_shutdown(gboolean reconfig);
@@ -27,7 +28,7 @@ void sn_shutdown(gboolean reconfig);
 gboolean sn_app_starting();
 
 /*! Notify that an app has started */
-void sn_app_started(const gchar *id, const gchar *wmclass);
+Time sn_app_started(const gchar *id, const gchar *wmclass);
 
 /*! Get the desktop requested via the startup-notiication protocol if one
   was requested */
This page took 0.035973 seconds and 4 git commands to generate.