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