Metacity gives no option not to raise windows when clicked. This makes life hard when you would like to use DnD, as well as just using windows when you still want other windows on top. Ubuntu have patched their latest release to give their users the option to change this behaviour through gConf. Why couldn't Gentoo do the same? We could even make it a USE-flag, though i find it hard to believe that anyone would be upset if this patch gets into the Gentoo Metacity ebuild. If you don't know about it, you probably don't want it, and you will never see it, as it is only a gConf key. There is a patch on the following URL, that i have been using before. Do not remember for what version of Metacity it was written for, though. Reproducible: Always Steps to Reproduce: 1. Click on a window in Gnome. 2. 3. Actual Results: Windows gets raised on top of all other windows. Expected Results: Leave the window stack intact until i click on the window border, or choose some other way of manipulating the stack.
It seems the patch above does not work for metacity-2.8.8, but it shouldn't be too hard to make it work. Or get hold of the patch Ubuntu is using for gnome-2.10.
Created attachment 57905 [details] A fixed ebuild. Patches metacity 2.10.0, giving you the option not to raise windows when clicked, and to suspend windows. This is, using the patch from Ubuntu linux. Following patch is applied in the attached ebuild. I think it would be a good idea to include this patch in the ebuild in portage, possibly with a USE-flag.I apologize for not being the most competent ebuild author, but i tried. The thing is, it doesn't change metacity's behaviour, it just gives you another option in gconf. With this behaviour activated, it is actually possible to use DnD in gnome, which is, according to me, A Good Thing. http://www.daimi.au.dk/~pg/ubuntu/metacity/metacity-suspend-0.1.patch: diff -Nur orig/metacity-2.10.0/src/common.h metacity-2.10.0/src/common.h --- orig/metacity-2.10.0/src/common.h 2005-01-17 21:25:09.000000000 +0100 +++ metacity-2.10.0/src/common.h 2005-03-26 16:19:40.000000000 +0100 @@ -64,7 +64,8 @@ META_MENU_OP_MOVE_LEFT = 1 << 13, META_MENU_OP_MOVE_RIGHT = 1 << 14, META_MENU_OP_MOVE_UP = 1 << 15, - META_MENU_OP_MOVE_DOWN = 1 << 16 + META_MENU_OP_MOVE_DOWN = 1 << 16, + META_MENU_OP_SUSPEND = 1 << 17 } MetaMenuOp; typedef struct _MetaWindowMenu MetaWindowMenu; @@ -146,7 +147,8 @@ { META_FOCUS_MODE_CLICK, META_FOCUS_MODE_SLOPPY, - META_FOCUS_MODE_MOUSE + META_FOCUS_MODE_MOUSE, + META_FOCUS_MODE_STRICT } MetaFocusMode; typedef enum diff -Nur orig/metacity-2.10.0/src/core.c metacity-2.10.0/src/core.c --- orig/metacity-2.10.0/src/core.c 2005-01-17 21:25:09.000000000 +0100 +++ metacity-2.10.0/src/core.c 2005-03-26 16:11:29.000000000 +0100 @@ -607,6 +607,9 @@ switch (menu_op) { + case META_MENU_OP_SUSPEND: + name = META_KEYBINDING_SUSPEND; + break; case META_MENU_OP_DELETE: name = META_KEYBINDING_CLOSE; break; diff -Nur orig/metacity-2.10.0/src/display.c metacity-2.10.0/src/display.c --- orig/metacity-2.10.0/src/display.c 2005-02-28 22:29:26.000000000 +0100 +++ metacity-2.10.0/src/display.c 2005-03-26 16:19:40.000000000 +0100 @@ -1639,7 +1639,8 @@ * in click to focus mode? The debate rages. * Feel free to change TRUE to FALSE or vice versa */ - if (TRUE /* meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK */) + /* if (TRUE /* meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK )*/ + if(meta_prefs_get_raise_on_click ()) meta_window_raise (window); else meta_topic (META_DEBUG_FOCUS, @@ -1781,6 +1782,7 @@ { switch (meta_prefs_get_focus_mode ()) { + case META_FOCUS_MODE_STRICT: case META_FOCUS_MODE_SLOPPY: case META_FOCUS_MODE_MOUSE: if (window->type != META_WINDOW_DOCK && @@ -1828,6 +1830,7 @@ { switch (meta_prefs_get_focus_mode ()) { + case META_FOCUS_MODE_STRICT: case META_FOCUS_MODE_MOUSE: if ((window->frame == NULL || frame_was_receiver) && event->xcrossing.mode != NotifyGrab && diff -Nur orig/metacity-2.10.0/src/keybindings.c metacity-2.10.0/src/keybindings.c --- orig/metacity-2.10.0/src/keybindings.c 2005-02-24 23:02:44.000000000 +0100 +++ metacity-2.10.0/src/keybindings.c 2005-03-26 15:59:23.000000000 +0100 @@ -118,6 +118,11 @@ MetaWindow *window, XEvent *event, MetaKeyBinding *binding); +static void handle_suspend_window (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + XEvent *event, + MetaKeyBinding *binding); static void handle_close_window (MetaDisplay *display, MetaScreen *screen, MetaWindow *window, @@ -373,6 +378,7 @@ { META_KEYBINDING_MAXIMIZE, handle_maximize, NULL }, { META_KEYBINDING_UNMAXIMIZE, handle_unmaximize, NULL }, { META_KEYBINDING_TOGGLE_SHADE, handle_toggle_shade, NULL }, + { META_KEYBINDING_SUSPEND, handle_suspend_window, NULL }, { META_KEYBINDING_CLOSE, handle_close_window, NULL }, { META_KEYBINDING_MINIMIZE, handle_minimize_window, NULL }, { META_KEYBINDING_BEGIN_MOVE, handle_begin_move, }, @@ -3183,6 +3189,17 @@ } static void +handle_suspend_window (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + XEvent *event, + MetaKeyBinding *binding) +{ + if (window) + meta_window_suspend (window); +} + +static void handle_close_window (MetaDisplay *display, MetaScreen *screen, MetaWindow *window, diff -Nur orig/metacity-2.10.0/src/menu.c metacity-2.10.0/src/menu.c --- orig/metacity-2.10.0/src/menu.c 2005-02-24 23:02:44.000000000 +0100 +++ metacity-2.10.0/src/menu.c 2005-03-26 14:12:31.000000000 +0100 @@ -62,6 +62,7 @@ { META_MENU_OP_RESIZE, NULL, FALSE, N_("_Resize") }, { 0, NULL, FALSE, NULL }, /* separator */ { META_MENU_OP_DELETE, METACITY_STOCK_DELETE, FALSE, N_("_Close") }, + { META_MENU_OP_SUSPEND, NULL, FALSE, N_("_Suspend") }, { META_MENU_OP_WORKSPACES, NULL, FALSE, NULL }, /* separator */ { META_MENU_OP_STICK, NULL, FALSE, N_("_Always on Visible Workspace") }, { META_MENU_OP_UNSTICK, NULL, FALSE, N_("_Only on This Workspace") }, diff -Nur orig/metacity-2.10.0/src/metacity.schemas.in metacity-2.10.0/src/metacity.schemas.in --- orig/metacity-2.10.0/src/metacity.schemas.in 2005-02-24 23:02:44.000000000 +0100 +++ metacity-2.10.0/src/metacity.schemas.in 2005-03-26 16:19:40.428381792 +0100 @@ -95,6 +95,20 @@ </schema> <schema> + <key>/schemas/apps/metacity/general/raise_on_click</key> + <applyto>/apps/metacity/general/raise_on_click</applyto> + <owner>metacity</owner> + <type>bool</type> + <default>true</default> + <locale name="C"> + <short>Raise current window if click event occurs</short> + <long> + If true the focused window will be automatically raised. + </long> + </locale> + </schema> + + <schema> <key>/schemas/apps/metacity/general/auto_raise_delay</key> <applyto>/apps/metacity/general/auto_raise_delay</applyto> <owner>metacity</owner> @@ -114,7 +128,7 @@ <applyto>/apps/metacity/general/theme</applyto> <owner>metacity</owner> <type>string</type> - <default>Simple</default> + <default>Human</default> <locale name="C"> <short>Current theme</short> <long> @@ -429,6 +443,27 @@ </schema> <schema> + <key>/schemas/apps/metacity/window_keybindings/suspend</key> + <applyto>/apps/metacity/window_keybindings/suspend</applyto> + <owner>metacity</owner> + <type>string</type> + <default>disabled</default> + <locale name="C"> + <short>Suspend window</short> + <long> + The keybinding used to suspend a window. + The format looks like "<Control>a" or "<Shift><Alt>F1". + The parser is + fairly liberal and allows lower or upper case, and also + abbreviations such as "<Ctl>" and "<Ctrl>". If +you set + the option to the special string "disabled", then there + will be no keybinding for this action. + </long> + </locale> + </schema> + + <schema> <key>/schemas/apps/metacity/window_keybindings/close</key> <applyto>/apps/metacity/window_keybindings/close</applyto> <owner>metacity</owner> diff -Nur orig/metacity-2.10.0/src/prefs.c metacity-2.10.0/src/prefs.c --- orig/metacity-2.10.0/src/prefs.c 2005-02-24 23:02:44.000000000 +0100 +++ metacity-2.10.0/src/prefs.c 2005-03-26 16:19:40.000000000 +0100 @@ -53,6 +53,7 @@ #define KEY_BUTTON_LAYOUT "/apps/metacity/general/button_layout" #define KEY_REDUCED_RESOURCES "/apps/metacity/general/reduced_resources" #define KEY_GNOME_ACCESSIBILITY "/desktop/gnome/interface/accessibility" +#define KEY_RAISE_ON_CLICK "/apps/metacity/general/raise_on_click" #define KEY_COMMAND_PREFIX "/apps/metacity/keybinding_commands/command_" @@ -90,6 +91,7 @@ static gboolean bell_is_audible = TRUE; static gboolean reduced_resources = FALSE; static gboolean gnome_accessibility = FALSE; +static gboolean raise_on_click = FALSE; static MetaVisualBellType visual_bell_type = META_VISUAL_BELL_INVALID; static MetaButtonLayout button_layout = { @@ -128,6 +130,7 @@ static gboolean update_action_double_click_titlebar (const char *value); static gboolean update_auto_raise (gboolean value); static gboolean update_auto_raise_delay (int value); +static gboolean update_raise_on_click (gboolean value); static gboolean update_button_layout (const char *value); static gboolean update_window_binding (const char *name, const char *value); @@ -301,7 +304,7 @@ char *str_val; int int_val; gboolean bool_val, bool_val_2; - + if (default_client != NULL) return; @@ -352,7 +355,11 @@ cleanup_error (&err); update_auto_raise_delay (int_val); - + bool_val = gconf_client_get_bool (default_client, KEY_RAISE_ON_CLICK, + &err); + cleanup_error (&err); + update_raise_on_click (bool_val); + str_val = gconf_client_get_string (default_client, KEY_THEME, &err); cleanup_error (&err); @@ -705,6 +712,22 @@ queue_changed (META_PREF_AUTO_RAISE_DELAY); } + else if (strcmp (key, KEY_RAISE_ON_CLICK) == 0) + { + gboolean b; + + if (value && value->type != GCONF_VALUE_BOOL) + { + meta_warning (_("GConf key \"%s\" is set to an invalid type\n"), + KEY_RAISE_ON_CLICK); + goto out; + } + + b = value ? gconf_value_get_bool (value) : raise_on_click; + + if (update_raise_on_click (b)) + queue_changed (META_PREF_RAISE_ON_CLICK); + } else if (str_has_prefix (key, KEY_COMMAND_PREFIX)) { const char *str; @@ -904,6 +927,8 @@ focus_mode = META_FOCUS_MODE_SLOPPY; else if (g_ascii_strcasecmp (value, "mouse") == 0) focus_mode = META_FOCUS_MODE_MOUSE; + else if (g_ascii_strcasecmp (value, "strict") == 0) + focus_mode = META_FOCUS_MODE_STRICT; else meta_warning (_("GConf key '%s' is set to an invalid value\n"), KEY_FOCUS_MODE); @@ -1333,6 +1358,16 @@ return old != auto_raise; } +static gboolean +update_raise_on_click (gboolean value) +{ + gboolean old = raise_on_click; + + raise_on_click = value; + + return old != raise_on_click; +} + #define MAX_REASONABLE_AUTO_RAISE_DELAY 10000 static gboolean @@ -1413,6 +1448,9 @@ case META_PREF_AUTO_RAISE: return "AUTO_RAISE"; + case META_PREF_RAISE_ON_CLICK: + return "RAISE_ON_CLICK"; + case META_PREF_AUTO_RAISE_DELAY: return "AUTO_RAISE_DELAY"; @@ -1585,6 +1623,7 @@ { META_KEYBINDING_LOWER, 0, 0, FALSE }, { META_KEYBINDING_MAXIMIZE_VERTICALLY, 0, 0, FALSE }, { META_KEYBINDING_MAXIMIZE_HORIZONTALLY, 0, 0, FALSE }, + { META_KEYBINDING_SUSPEND, 0, 0, FALSE}, { NULL, 0, 0, FALSE } }; @@ -2149,6 +2188,12 @@ return auto_raise; } +gboolean +meta_prefs_get_raise_on_click () +{ + return raise_on_click; +} + int meta_prefs_get_auto_raise_delay (void) { diff -Nur orig/metacity-2.10.0/src/prefs.h metacity-2.10.0/src/prefs.h --- orig/metacity-2.10.0/src/prefs.h 2005-02-24 23:02:44.000000000 +0100 +++ metacity-2.10.0/src/prefs.h 2005-03-26 16:19:40.000000000 +0100 @@ -48,7 +48,8 @@ META_PREF_AUDIBLE_BELL, META_PREF_VISUAL_BELL_TYPE, META_PREF_REDUCED_RESOURCES, - META_PREF_GNOME_ACCESSIBILITY + META_PREF_GNOME_ACCESSIBILITY, + META_PREF_RAISE_ON_CLICK } MetaPreference; typedef void (* MetaPrefsChangedFunc) (MetaPreference pref, @@ -74,6 +75,7 @@ int meta_prefs_get_auto_raise_delay (void); gboolean meta_prefs_get_reduced_resources (void); gboolean meta_prefs_get_gnome_accessibility (void); +gboolean meta_prefs_get_raise_on_click (void); const char* meta_prefs_get_command (int i); @@ -189,6 +191,7 @@ #define META_KEYBINDING_LOWER "lower" #define META_KEYBINDING_MAXIMIZE_VERTICALLY "maximize_vertically" #define META_KEYBINDING_MAXIMIZE_HORIZONTALLY "maximize_horizontally" +#define META_KEYBINDING_SUSPEND "suspend" typedef enum _MetaKeyBindingAction { diff -Nur orig/metacity-2.10.0/src/window.c metacity-2.10.0/src/window.c --- orig/metacity-2.10.0/src/window.c 2005-02-28 22:29:26.000000000 +0100 +++ metacity-2.10.0/src/window.c 2005-03-26 16:19:40.000000000 +0100 @@ -1829,7 +1829,7 @@ if (window->showing_for_first_time) { window->showing_for_first_time = FALSE; - if (takes_focus_on_map) + if (takes_focus_on_map && meta_prefs_get_focus_mode () != META_FOCUS_MODE_STRICT) { meta_window_focus (window, meta_display_get_current_time_roundtrip (window->display)); @@ -1967,6 +1967,27 @@ queue_calc_showing_func, NULL); } + if (window->suspended) + { + kill(window->net_wm_pid, SIGCONT); + window->suspended = FALSE; + + GSList *windows = meta_display_list_windows(window->display); + GSList *tmp = windows; + + while( tmp != NULL ) { + MetaWindow *w = tmp->data; + if( w->net_wm_pid == window->net_wm_pid ) + { + w->suspended = FALSE; + if( !w->suspended_minimized ) + meta_window_unminimize(w); + } + tmp = tmp->next; + } + + g_slist_free(windows); + } } static void @@ -2137,6 +2158,35 @@ } void +meta_window_suspend (MetaWindow *window) +{ + if (window->net_wm_pid >= 1) + { + + GSList *windows = meta_display_list_windows(window->display); + GSList *tmp = windows; + + while( tmp != NULL ) + { + MetaWindow *w = tmp->data; + if( w->net_wm_pid == window->net_wm_pid ) + { + w->suspended_minimized = w->minimized; + meta_window_minimize(w); + w->suspended = TRUE; + } + + tmp = tmp->next; + } + g_slist_free(windows); + + meta_window_minimize(window); + window->suspended = TRUE; + kill(window->net_wm_pid, SIGSTOP); + } +} + +void meta_window_shade (MetaWindow *window) { meta_topic (META_DEBUG_WINDOW_OPS, @@ -5998,6 +6048,9 @@ META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN, meta_display_get_current_time (window->display)); break; + + case META_MENU_OP_SUSPEND: + meta_window_suspend (window); case 0: /* nothing */ @@ -6055,7 +6108,7 @@ ops = 0; insensitive = 0; - ops |= (META_MENU_OP_DELETE | META_MENU_OP_MINIMIZE | META_MENU_OP_MOVE | META_MENU_OP_RESIZE); + ops |= (META_MENU_OP_DELETE | META_MENU_OP_MINIMIZE | META_MENU_OP_MOVE | META_MENU_OP_RESIZE | META_MENU_OP_SUSPEND); n_workspaces = meta_screen_get_n_workspaces (window->screen); diff -Nur orig/metacity-2.10.0/src/window.h metacity-2.10.0/src/window.h --- orig/metacity-2.10.0/src/window.h 2005-02-25 22:30:02.000000000 +0100 +++ metacity-2.10.0/src/window.h 2005-03-26 15:46:12.000000000 +0100 @@ -32,6 +32,9 @@ #include <X11/Xutil.h> #include <gdk-pixbuf/gdk-pixbuf.h> +#include <sys/types.h> +#include <signal.h> + typedef struct _MetaGroup MetaGroup; typedef struct _MetaStruts MetaStruts; @@ -265,6 +268,11 @@ /* if TRUE, application is buggy and SYNC resizing is turned off */ guint disable_sync : 1; + /* if TRUE, application is suspended */ + guint suspended : 1; + /* if TRUE, the window was minimized before it was suspended */ + guint suspended_minimized : 1; + #ifdef HAVE_XSYNC /* XSync update counter */ XSyncCounter sync_request_counter; @@ -365,6 +373,7 @@ guint32 current_time); void meta_window_make_fullscreen (MetaWindow *window); void meta_window_unmake_fullscreen (MetaWindow *window); +void meta_window_suspend (MetaWindow *window); /* args to move are window pos, not frame pos */ void meta_window_move (MetaWindow *window, diff -Nur orig/metacity-2.10.0/src/workspace.c metacity-2.10.0/src/workspace.c --- orig/metacity-2.10.0/src/workspace.c 2005-02-25 18:46:49.000000000 +0100 +++ metacity-2.10.0/src/workspace.c 2005-03-26 16:19:40.000000000 +0100 @@ -841,7 +841,8 @@ } else if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_SLOPPY) focus_ancestor_or_mru_window (workspace, not_this_one, timestamp); - else if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_MOUSE) + else if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_MOUSE || + meta_prefs_get_focus_mode () == META_FOCUS_MODE_STRICT) { meta_topic (META_DEBUG_FOCUS, "Setting focus to no_focus_window, since no valid "
Hi Olof. It's nice that you take the effort to try to improve something you consider important. However, there are certain things you should know about this kind of reports: - The fact that other GNU/Linux distributions include a patch is not a valid reason for us to include it as well. You are more than welcome to suggest something, and discuss the merits of a patch, but just stating that another distribution uses a certain patch doesn't mean Gentoo should do the same. - We in Gentoo usually strive to keep our gnome-related packages as close to the original upstream releases as possible. This is not accidental. We tend to agree with most of the design decisions made in Gnome, specially when it comes to usability issues. That doesn't mean we're against offering special improvements, but in that case their rationales have to be discussed and agreed upon, and almost always it turns out to be an issue that should be handled by upstream developers. Regarding this particular patch, offering a gconf key that controls raising windows on click, there has been extensive discussion: http://bugzilla.gnome.org/show_bug.cgi?id=115753 http://bugzilla.gnome.org/show_bug.cgi?id=86108 http://ometer.com/free-software-ui.html Briefly, it comes down to this: the real issue is not providing a gconf key to customise the raise-on-click behaviour. The real issue is with handling the raise action correctly in special cases such as DnD, and the solution requires a different approach. Metacity developers are willing to receive patches that fixes the real issue and resolves the problem for everyone. All in all, this patch is not a real improvement. Moreover, your patch includes more changes, not related to the raise_on_click option. People interested in using it as a band-aid can still apply it if they want, and it's good that you have attached your work, but it doesn't look like something we would maintain in our tree. Thanks.