Patch from Ron Yorston to add a focus_new_windows option. Default is

2006-04-12  Elijah Newren  <newren gmail com>

	Patch from Ron Yorston to add a focus_new_windows option.  Default
	is 'smart' (focus by default but normal focus-stealing-prevention
	can kick in); 'strict' is current other choice (like 'smart'
	except that programs launched by the terminal will not be
	focused).  Fixes remainder of #326159.  Should also close #152004
	and a bunch of others.

	* src/common.h:
	Add a MetaFocusNewWindows enum giving the current types allowed

	* src/display.h:
	Update docs on allow_terminal_deactivation to note that it is only
	relevant when focus_new_windows is 'strict'

	* src/prefs.c:
	* src/prefs.h:

	* src/metacity.schemas.in: add the new gconf key and explanation

	* src/prefs.[ch] (#define KEY_FOCUS_NEW_WINDOWS, static gboolean
	  focus_new_windows, update_focus_new_windows, meta_prefs_init,
	  change_notify, meta_prefs_get_focus_new_windows,
	  meta_preference_to_string):
	Add all the normal preference handling stuff for this new
	focus-new-windows option.

	* src/window.c (window_state_on_map, meta_window_set_user_time):
	Don't focus windows launched from a terminal
This commit is contained in:
Elijah Newren 2006-04-12 18:01:20 +00:00 committed by Elijah Newren
parent 4b683fdbf2
commit 59d99fb9d1
7 changed files with 123 additions and 8 deletions

View File

@ -1,3 +1,34 @@
2006-04-12 Elijah Newren <newren gmail com>
Patch from Ron Yorston to add a focus_new_windows option. Default
is 'smart' (focus by default but normal focus-stealing-prevention
can kick in); 'strict' is current other choice (like 'smart'
except that programs launched by the terminal will not be
focused). Fixes remainder of #326159. Should also close #152004
and a bunch of others.
* src/common.h:
Add a MetaFocusNewWindows enum giving the current types allowed
* src/display.h:
Update docs on allow_terminal_deactivation to note that it is only
relevant when focus_new_windows is 'strict'
* src/prefs.c:
* src/prefs.h:
* src/metacity.schemas.in: add the new gconf key and explanation
* src/prefs.[ch] (#define KEY_FOCUS_NEW_WINDOWS, static gboolean
focus_new_windows, update_focus_new_windows, meta_prefs_init,
change_notify, meta_prefs_get_focus_new_windows,
meta_preference_to_string):
Add all the normal preference handling stuff for this new
focus-new-windows option.
* src/window.c (window_state_on_map, meta_window_set_user_time):
Don't focus windows launched from a terminal
Mon Apr 10 16:44:51 2006 Søren Sandmann <sandmann@redhat.com> Mon Apr 10 16:44:51 2006 Søren Sandmann <sandmann@redhat.com>
* src/c-screen.c (is_menu): Check if the window is a menu and make * src/c-screen.c (is_menu): Check if the window is a menu and make

View File

@ -151,6 +151,12 @@ typedef enum
META_FOCUS_MODE_MOUSE META_FOCUS_MODE_MOUSE
} MetaFocusMode; } MetaFocusMode;
typedef enum
{
META_FOCUS_NEW_WINDOWS_SMART,
META_FOCUS_NEW_WINDOWS_STRICT
} MetaFocusNewWindows;
typedef enum typedef enum
{ {
META_ACTION_DOUBLE_CLICK_TITLEBAR_TOGGLE_SHADE, META_ACTION_DOUBLE_CLICK_TITLEBAR_TOGGLE_SHADE,

View File

@ -204,11 +204,12 @@ struct _MetaDisplay
*/ */
guint mouse_mode : 1; guint mouse_mode : 1;
/* Helper var for strict focus for terminals; only relevant if the focus /* Helper var used when focus_new_windows setting is 'strict'; only
* window is a terminal. Typically, we don't allow new windows to take * relevant in 'strict' mode and if the focus window is a terminal.
* focus away from a terminal, but if the user explicitly did something * In that case, we don't allow new windows to take focus away from
* that should allow a different window to gain focus (e.g. global * a terminal, but if the user explicitly did something that should
* keybinding or clicking on a dock), then we will allow the transfer. * allow a different window to gain focus (e.g. global keybinding or
* clicking on a dock), then we will allow the transfer.
*/ */
guint allow_terminal_deactivation : 1; guint allow_terminal_deactivation : 1;

View File

@ -66,6 +66,23 @@
</locale> </locale>
</schema> </schema>
<schema>
<key>/schemas/apps/metacity/general/focus_new_windows</key>
<applyto>/apps/metacity/general/focus_new_windows</applyto>
<owner>metacity</owner>
<type>string</type>
<default>smart</default>
<locale name="C">
<short>Control how new windows get focus</short>
<long>
This option provides additional control over how newly created
windows get focus. It has two possible values; "smart" applies
the user's normal focus mode, and "strict" results in windows
started from a terminal not being given focus.
</long>
</locale>
</schema>
<schema> <schema>
<key>/schemas/apps/metacity/general/raise_on_click</key> <key>/schemas/apps/metacity/general/raise_on_click</key>
<applyto>/apps/metacity/general/raise_on_click</applyto> <applyto>/apps/metacity/general/raise_on_click</applyto>

View File

@ -42,6 +42,7 @@
*/ */
#define KEY_MOUSE_BUTTON_MODS "/apps/metacity/general/mouse_button_modifier" #define KEY_MOUSE_BUTTON_MODS "/apps/metacity/general/mouse_button_modifier"
#define KEY_FOCUS_MODE "/apps/metacity/general/focus_mode" #define KEY_FOCUS_MODE "/apps/metacity/general/focus_mode"
#define KEY_FOCUS_NEW_WINDOWS "/apps/metacity/general/focus_new_windows"
#define KEY_RAISE_ON_CLICK "/apps/metacity/general/raise_on_click" #define KEY_RAISE_ON_CLICK "/apps/metacity/general/raise_on_click"
#define KEY_ACTION_DOUBLE_CLICK_TITLEBAR "/apps/metacity/general/action_double_click_titlebar" #define KEY_ACTION_DOUBLE_CLICK_TITLEBAR "/apps/metacity/general/action_double_click_titlebar"
#define KEY_AUTO_RAISE "/apps/metacity/general/auto_raise" #define KEY_AUTO_RAISE "/apps/metacity/general/auto_raise"
@ -83,6 +84,7 @@ static gboolean use_system_font = FALSE;
static PangoFontDescription *titlebar_font = NULL; static PangoFontDescription *titlebar_font = NULL;
static MetaVirtualModifier mouse_button_mods = Mod1Mask; static MetaVirtualModifier mouse_button_mods = Mod1Mask;
static MetaFocusMode focus_mode = META_FOCUS_MODE_CLICK; static MetaFocusMode focus_mode = META_FOCUS_MODE_CLICK;
static MetaFocusNewWindows focus_new_windows = META_FOCUS_NEW_WINDOWS_SMART;
static gboolean raise_on_click = TRUE; static gboolean raise_on_click = TRUE;
static char* current_theme = NULL; static char* current_theme = NULL;
static int num_workspaces = 4; static int num_workspaces = 4;
@ -128,6 +130,7 @@ static gboolean update_use_system_font (gboolean value);
static gboolean update_titlebar_font (const char *value); static gboolean update_titlebar_font (const char *value);
static gboolean update_mouse_button_mods (const char *value); static gboolean update_mouse_button_mods (const char *value);
static gboolean update_focus_mode (const char *value); static gboolean update_focus_mode (const char *value);
static gboolean update_focus_new_windows (const char *value);
static gboolean update_raise_on_click (gboolean value); static gboolean update_raise_on_click (gboolean value);
static gboolean update_theme (const char *value); static gboolean update_theme (const char *value);
static gboolean update_visual_bell (gboolean v1, gboolean v2); static gboolean update_visual_bell (gboolean v1, gboolean v2);
@ -378,6 +381,12 @@ meta_prefs_init (void)
update_focus_mode (str_val); update_focus_mode (str_val);
g_free (str_val); g_free (str_val);
str_val = gconf_client_get_string (default_client, KEY_FOCUS_NEW_WINDOWS,
&err);
cleanup_error (&err);
update_focus_new_windows (str_val);
g_free (str_val);
if (get_bool (KEY_RAISE_ON_CLICK, &bool_val)) if (get_bool (KEY_RAISE_ON_CLICK, &bool_val))
update_raise_on_click (bool_val); update_raise_on_click (bool_val);
@ -570,6 +579,22 @@ change_notify (GConfClient *client,
if (update_focus_mode (str)) if (update_focus_mode (str))
queue_changed (META_PREF_FOCUS_MODE); queue_changed (META_PREF_FOCUS_MODE);
} }
else if (strcmp (key, KEY_FOCUS_NEW_WINDOWS) == 0)
{
const char *str;
if (value && value->type != GCONF_VALUE_STRING)
{
meta_warning (_("GConf key \"%s\" is set to an invalid type\n"),
KEY_FOCUS_NEW_WINDOWS);
goto out;
}
str = value ? gconf_value_get_string (value) : NULL;
if (update_focus_new_windows (str))
queue_changed (META_PREF_FOCUS_NEW_WINDOWS);
}
else if (strcmp (key, KEY_RAISE_ON_CLICK) == 0) else if (strcmp (key, KEY_RAISE_ON_CLICK) == 0)
{ {
gboolean b; gboolean b;
@ -1023,6 +1048,27 @@ update_focus_mode (const char *value)
} }
#endif /* HAVE_GCONF */ #endif /* HAVE_GCONF */
#ifdef HAVE_GCONF
static gboolean
update_focus_new_windows (const char *value)
{
MetaFocusNewWindows old_mode = focus_new_windows;
if (value != NULL)
{
if (g_ascii_strcasecmp (value, "smart") == 0)
focus_new_windows = META_FOCUS_NEW_WINDOWS_SMART;
else if (g_ascii_strcasecmp (value, "strict") == 0)
focus_new_windows = META_FOCUS_NEW_WINDOWS_STRICT;
else
meta_warning (_("GConf key '%s' is set to an invalid value\n"),
KEY_FOCUS_NEW_WINDOWS);
}
return (old_mode != focus_new_windows);
}
#endif /* HAVE_GCONF */
#ifdef HAVE_GCONF #ifdef HAVE_GCONF
static gboolean static gboolean
update_raise_on_click (gboolean value) update_raise_on_click (gboolean value)
@ -1081,6 +1127,12 @@ meta_prefs_get_focus_mode (void)
return focus_mode; return focus_mode;
} }
MetaFocusNewWindows
meta_prefs_get_focus_new_windows (void)
{
return focus_new_windows;
}
gboolean gboolean
meta_prefs_get_raise_on_click (void) meta_prefs_get_raise_on_click (void)
{ {
@ -1576,6 +1628,9 @@ meta_preference_to_string (MetaPreference pref)
case META_PREF_FOCUS_MODE: case META_PREF_FOCUS_MODE:
return "FOCUS_MODE"; return "FOCUS_MODE";
case META_PREF_FOCUS_NEW_WINDOWS:
return "FOCUS_NEW_WINDOWS";
case META_PREF_RAISE_ON_CLICK: case META_PREF_RAISE_ON_CLICK:
return "RAISE_ON_CLICK"; return "RAISE_ON_CLICK";

View File

@ -31,6 +31,7 @@ typedef enum
{ {
META_PREF_MOUSE_BUTTON_MODS, META_PREF_MOUSE_BUTTON_MODS,
META_PREF_FOCUS_MODE, META_PREF_FOCUS_MODE,
META_PREF_FOCUS_NEW_WINDOWS,
META_PREF_RAISE_ON_CLICK, META_PREF_RAISE_ON_CLICK,
META_PREF_ACTION_DOUBLE_CLICK_TITLEBAR, META_PREF_ACTION_DOUBLE_CLICK_TITLEBAR,
META_PREF_AUTO_RAISE, META_PREF_AUTO_RAISE,
@ -69,6 +70,7 @@ const char* meta_preference_to_string (MetaPreference pref);
MetaVirtualModifier meta_prefs_get_mouse_button_mods (void); MetaVirtualModifier meta_prefs_get_mouse_button_mods (void);
MetaFocusMode meta_prefs_get_focus_mode (void); MetaFocusMode meta_prefs_get_focus_mode (void);
MetaFocusNewWindows meta_prefs_get_focus_new_windows (void);
gboolean meta_prefs_get_raise_on_click (void); gboolean meta_prefs_get_raise_on_click (void);
const char* meta_prefs_get_theme (void); const char* meta_prefs_get_theme (void);
/* returns NULL if GTK default should be used */ /* returns NULL if GTK default should be used */

View File

@ -1774,15 +1774,16 @@ window_state_on_map (MetaWindow *window,
return; return;
} }
/* Terminal usage is different; users typically intend to launch /* Terminal usage may be different; some users intend to launch
* many apps in quick succession or to just view things in the new * many apps in quick succession or to just view things in the new
* window while still interacting with the terminal. Therefore, * window while still interacting with the terminal. In that case,
* apps launched from the terminal should not take focus. This * apps launched from the terminal should not take focus. This
* isn't quite the same as not allowing focus to transfer from * isn't quite the same as not allowing focus to transfer from
* terminals due to new window map, but the latter is a much easier * terminals due to new window map, but the latter is a much easier
* approximation to enforce so we do that. * approximation to enforce so we do that.
*/ */
if (*takes_focus && if (*takes_focus &&
meta_prefs_get_focus_new_windows () == META_FOCUS_NEW_WINDOWS_STRICT &&
!window->display->allow_terminal_deactivation && !window->display->allow_terminal_deactivation &&
__window_is_terminal (window->display->focus_window) && __window_is_terminal (window->display->focus_window) &&
!meta_window_is_ancestor_of_transient (window->display->focus_window, !meta_window_is_ancestor_of_transient (window->display->focus_window,
@ -7658,7 +7659,9 @@ meta_window_set_user_time (MetaWindow *window,
/* If this is a terminal, user interaction with it means the user likely /* If this is a terminal, user interaction with it means the user likely
* doesn't want to have focus transferred for now due to new windows. * doesn't want to have focus transferred for now due to new windows.
*/ */
if (__window_is_terminal (window)) if (meta_prefs_get_focus_new_windows () ==
META_FOCUS_NEW_WINDOWS_STRICT &&
__window_is_terminal (window))
window->display->allow_terminal_deactivation = FALSE; window->display->allow_terminal_deactivation = FALSE;
} }
} }