xfwm4 : focus delay when "focus follows mouse"

May THO thobouli at yahoo.fr
Mon Mar 5 22:25:33 CET 2007


Hi.

I attached a patch for xfwm4. It adds a "focus delay" behaviour to the window manager similar to KDE. It only works with "focus follows mouse" : this adds a delay before the window under the mouse receives focus.

I wrote this patch to resolve a annoyance I had with gimp. I prefer the "focus follows mouse" mode with gimp because I'm using a lot the keyboard shortcuts and find it very useful to activate a picture without clicking into it. But with many opened pictures, when I work with layers, I often move the mouse from the active picture to the "layer dialog" window : if the mouse moves accidentally on any other piture in a lower z-order, this change the layer view to the wrong picture.

I don't know if someone will find this useful.

Sorry for my bad english.

Regards.

------------------------------------------------------------------------
diff -U 3 -r xfwm4-4.4.0/mcs-plugin/xfwm4_plugin.c work/mcs-plugin/xfwm4_plugin.c
--- xfwm4-4.4.0/mcs-plugin/xfwm4_plugin.c    2007-01-20 19:20:22.000000000 +0100
+++ work/mcs-plugin/xfwm4_plugin.c    2007-03-05 16:44:29.000000000 +0100
@@ -111,6 +111,7 @@
 static gboolean box_move = FALSE;
 static gboolean box_resize = FALSE;
 static int raise_delay;
+static int focus_delay;
 static int snap_width;
 static int wrap_resistance;
 gchar *xfwm4_plugin_current_key_theme = NULL;
@@ -1125,7 +1126,8 @@
     McsPlugin *mcs_plugin = itf->mcs_plugin;
 
     click_to_focus = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (itf->click_focus_radio));
-
+    gtk_widget_set_sensitive (itf->focus_delay_scale, !click_to_focus);
+   
     mcs_manager_set_int (mcs_plugin->manager, "Xfwm/ClickToFocus", CHANNEL1,
         click_to_focus ? 1 : 0);
     mcs_manager_notify (mcs_plugin->manager, CHANNEL1);
@@ -1172,6 +1174,18 @@
 }
 
 static void
+cb_focus_delay_changed (GtkWidget * dialog, gpointer user_data)
+{
+    Itf *itf = (Itf *) user_data;
+    McsPlugin *mcs_plugin = itf->mcs_plugin;
+
+    focus_delay = (int) gtk_range_get_value (GTK_RANGE (itf->focus_delay_scale));
+    mcs_manager_set_int (mcs_plugin->manager, "Xfwm/FocusDelay", CHANNEL1, focus_delay);
+    mcs_manager_notify (mcs_plugin->manager, CHANNEL1);
+    xfwm4_plugin_write_options (mcs_plugin);
+}
+
+static void
 cb_raise_on_click_changed (GtkWidget * dialog, gpointer user_data)
 {
     Itf *itf = (Itf *) user_data;
@@ -1606,7 +1620,46 @@
         gtk_radio_button_get_group (GTK_RADIO_BUTTON (dialog->focus_follow_mouse_radio));
     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->focus_follow_mouse_radio),
         !click_to_focus);
+   
+    vbox = gtk_vbox_new (FALSE, BORDER);
+    gtk_widget_show (vbox);
+   
+    frame = xfce_create_framebox_with_content (_("Delay before window receives focus"), vbox);
+    gtk_widget_show (frame);
+    gtk_box_pack_start (GTK_BOX (vbox_page), frame, TRUE, TRUE, 0);
+   
+    table = gtk_table_new (1, 3, FALSE);
+    gtk_widget_show (table);
+    gtk_box_pack_start (GTK_BOX (vbox), table, TRUE, TRUE, 0);
+    gtk_container_set_border_width (GTK_CONTAINER (table), BORDER);
+   
+    label = xfce_create_small_label (_("Slow"));
+    gtk_widget_show (label);
+    gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, (GtkAttachOptions) (GTK_FILL),
+        (GtkAttachOptions) (0), 0, 0);
+    gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
+    gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
+
+    label = xfce_create_small_label (_("Fast"));
+    gtk_widget_show (label);
+    gtk_table_attach (GTK_TABLE (table), label, 2, 3, 0, 1, (GtkAttachOptions) (GTK_FILL),
+        (GtkAttachOptions) (0), 0, 0);
+    gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
+    gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+
+    dialog->focus_delay_scale =
+        gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (focus_delay, 100, 2000, 10, 100, 0)));
+    gtk_widget_show (dialog->focus_delay_scale);
 
+    gtk_table_attach (GTK_TABLE (table), dialog->focus_delay_scale, 1, 2, 0,
+        1, (GtkAttachOptions) (GTK_EXPAND | GTK_SHRINK | GTK_FILL), (GtkAttachOptions) (GTK_FILL),
+        0, 0);
+    gtk_scale_set_draw_value (GTK_SCALE (dialog->focus_delay_scale), FALSE);
+    gtk_scale_set_digits (GTK_SCALE (dialog->focus_delay_scale), 0);
+    gtk_range_set_update_policy (GTK_RANGE (dialog->focus_delay_scale), GTK_UPDATE_DISCONTINUOUS);
+    gtk_range_set_inverted (GTK_RANGE (dialog->focus_delay_scale), TRUE);
+    gtk_widget_set_sensitive (dialog->focus_delay_scale, !click_to_focus);
+   
     dialog->focus_new_check =
         create_check_button_with_mnemonic (_("Automatically give focus to newly created windows"));
     gtk_widget_show (dialog->focus_new_check);
@@ -1938,6 +1991,8 @@
         G_CALLBACK (cb_raise_on_focus_changed), itf);
     g_signal_connect (G_OBJECT (itf->raise_delay_scale), "value_changed",
         (GCallback) cb_raise_delay_changed, itf);
+    g_signal_connect (G_OBJECT (itf->focus_delay_scale), "value_changed",
+        (GCallback) cb_focus_delay_changed, itf);
     g_signal_connect (G_OBJECT (itf->click_raise_check), "toggled",
         G_CALLBACK (cb_raise_on_click_changed), itf);
     g_signal_connect (G_OBJECT (itf->snap_to_border_check), "toggled",
@@ -2130,6 +2185,17 @@
         mcs_manager_set_int (mcs_plugin->manager, "Xfwm/RaiseDelay", CHANNEL1, raise_delay);
     }
 
+    setting = mcs_manager_setting_lookup (mcs_plugin->manager, "Xfwm/FocusDelay", CHANNEL1);
+    if (setting)
+    {
+        focus_delay = setting->data.v_int;
+    }
+    else
+    {
+        focus_delay = 0;
+        mcs_manager_set_int (mcs_plugin->manager, "Xfwm/FocusDelay", CHANNEL1, raise_delay);
+    }
+   
     setting = mcs_manager_setting_lookup (mcs_plugin->manager, "Xfwm/RaiseOnClick", CHANNEL1);
     if (setting)
     {
diff -U 3 -r xfwm4-4.4.0/mcs-plugin/xfwm4_plugin.h work/mcs-plugin/xfwm4_plugin.h
--- xfwm4-4.4.0/mcs-plugin/xfwm4_plugin.h    2007-01-20 19:20:22.000000000 +0100
+++ work/mcs-plugin/xfwm4_plugin.h    2007-03-05 15:09:30.000000000 +0100
@@ -85,6 +85,7 @@
     GtkWidget *frame_layout;
     GtkWidget *frame_align;
     GtkWidget *raise_delay_scale;
+    GtkWidget *focus_delay_scale;
     GtkWidget *raise_on_focus_check;
     GtkWidget *scrolledwindow1;
     GtkWidget *scrolledwindow2;
Les fichiers xfwm4-4.4.0/po/fr.gmo et work/po/fr.gmo sont différents.
diff -U 3 -r xfwm4-4.4.0/po/fr.po work/po/fr.po
--- xfwm4-4.4.0/po/fr.po    2007-01-20 19:20:24.000000000 +0100
+++ work/po/fr.po    2007-03-05 16:45:04.000000000 +0100
@@ -97,6 +97,10 @@
 msgid "Focus"
 msgstr "Focalisation"
 
+#: ../mcs-plugin/xfwm4_plugin.c:1690
+msgid "Delay before window receives focus"
+msgstr "Délai avant que la fenêtre reçoive le focus"
+
 #: ../mcs-plugin/wmtweaks_plugin.c:452
 msgid "Key used to grab and move windows"
 msgstr "Touche utilisée pour saisir et déplacer les fenêtres"
Seulement dans work/po: Makefile.in
Seulement dans work/src: .deps
diff -U 3 -r xfwm4-4.4.0/src/events.c work/src/events.c
--- xfwm4-4.4.0/src/events.c    2007-01-20 19:20:18.000000000 +0100
+++ work/src/events.c    2007-03-05 16:02:29.000000000 +0100
@@ -80,11 +80,19 @@
                                  HyperMask)
 
 static guint raise_timeout = 0;
+static guint focus_timeout = 0; // Focus time-out
 static GdkAtom atom_rcfiles = GDK_NONE;
 static xfwmWindow menu_event_window;
 static int edge_scroll_x = 0;
 static int edge_scroll_y = 0;
 
+static struct _focus_info
+{
+    ScreenInfo *screen_info;
+    Client *c;
+    Time timestamp;
+} focus_info;
+
 /* Forward decl. */
 
 static void handleEvent         (DisplayInfo *display_info,
@@ -311,6 +319,30 @@
 }
 
 static void
+clear_focus_timeout (void)
+{
+    if(focus_timeout)
+    {
+        g_source_remove (focus_timeout);
+        focus_timeout = 0;
+    }
+}
+
+static gboolean
+focus_cb (gpointer data)
+{
+    Client *c;
+   
+    TRACE ("entering focus_cb");
+
+    clear_focus_timeout();
+   
+    clientSetFocus (focus_info.screen_info, focus_info.c, focus_info.timestamp, NO_FOCUS_FLAG);
+   
+    return (TRUE);
+}
+
+static void
 moveRequest (Client * c, XEvent * ev)
 {
     if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_HAS_MOVE)
@@ -1499,8 +1531,23 @@
             TRACE ("EnterNotify window is \"%s\"", c->name);
             if (!(c->type & (WINDOW_DOCK | WINDOW_DESKTOP)))
             {
-                clientSetFocus (c->screen_info, c, ev->time, NO_FOCUS_FLAG);
-            }
+        if(screen_info->params->focus_delay)
+        {
+            clear_focus_timeout();
+            focus_info.screen_info = c->screen_info;
+            focus_info.c = c;
+            focus_info.timestamp = ev->time;
+                focus_timeout = g_timeout_add_full (G_PRIORITY_DEFAULT,
+                                        screen_info->params->focus_delay,
+                                        (GtkFunction) focus_cb,
+                                        NULL, NULL);
+        }
+        else
+        {
+            clientSetFocus (c->screen_info, c, ev->time, NO_FOCUS_FLAG);
+        }
+            } else
+            clear_focus_timeout();
         }
 
         /* No need to process the event any further */
diff -U 3 -r xfwm4-4.4.0/src/settings.c work/src/settings.c
--- xfwm4-4.4.0/src/settings.c    2007-01-20 19:20:18.000000000 +0100
+++ work/src/settings.c    2007-03-05 16:03:54.000000000 +0100
@@ -202,6 +202,10 @@
                     {
                         screen_info->params->raise_delay = setting->data.v_int;
                     }
+            else if (!strcmp (name, "Xfwm/FocusDelay"))
+                    {
+                        screen_info->params->focus_delay = setting->data.v_int;
+                    }
                     else if (!strcmp (name, "Xfwm/RaiseOnClick"))
                     {
                         screen_info->params->raise_on_click = setting->data.v_int;
@@ -591,6 +595,12 @@
             setIntValueFromInt ("raise_delay", setting->data.v_int, rc);
             mcs_setting_free (setting);
         }
+        if (mcs_client_get_setting (screen_info->mcs_client, "Xfwm/FocusDelay", CHANNEL1,
+                &setting) == MCS_SUCCESS)
+        {
+            setIntValueFromInt ("focus_delay", setting->data.v_int, rc);
+            mcs_setting_free (setting);
+        }
         if (mcs_client_get_setting (screen_info->mcs_client, "Xfwm/RaiseOnClick", CHANNEL1,
                 &setting) == MCS_SUCCESS)
         {
@@ -1297,6 +1307,7 @@
         {"button_offset", NULL, TRUE},
         {"button_spacing", NULL, TRUE},
         {"click_to_focus", NULL, TRUE},
+    {"focus_delay", NULL, TRUE},
         {"cycle_hidden", NULL, TRUE},
         {"cycle_minimum", NULL, TRUE},
         {"cycle_workspaces", NULL, TRUE},
@@ -1453,6 +1464,8 @@
         !g_ascii_strcasecmp ("true", getValue ("prevent_focus_stealing", rc));
     screen_info->params->raise_delay =
         abs (TOINT (getValue ("raise_delay", rc)));
+    screen_info->params->focus_delay =
+        abs (TOINT (getValue ("focus_delay", rc)));
     screen_info->params->raise_on_click =
         !g_ascii_strcasecmp ("true", getValue ("raise_on_click", rc));
     screen_info->params->raise_with_any_button =
diff -U 3 -r xfwm4-4.4.0/src/settings.h work/src/settings.h
--- xfwm4-4.4.0/src/settings.h    2007-01-20 19:20:18.000000000 +0100
+++ work/src/settings.h    2007-03-05 11:19:37.000000000 +0100
@@ -183,6 +183,7 @@
     int placement_ratio;
     int popup_opacity;
     int raise_delay;
+    int focus_delay;
     int resize_opacity;
     int restore_on_move;
     int shadow_delta_height;
------------------------------------------------------------------------




	

	
		
___________________________________________________________________________ 
Nouveau : téléphonez moins cher avec Yahoo! Messenger ! Découvez les tarifs exceptionnels pour appeler la France et l'international.
Téléchargez sur http://fr.messenger.yahoo.com



More information about the Xfce4-dev mailing list