diff options
author | Richard Hughes <richard@hughsie.com> | 2014-06-18 14:17:15 +0100 |
---|---|---|
committer | Richard Hughes <richard@hughsie.com> | 2014-06-18 14:17:15 +0100 |
commit | d77e3e4f571e2a3bce10e3cfc9859a2157848d9c (patch) | |
tree | 1c06117cb6820be92fda7c6dae1977572b378a54 | |
parent | f4d0e3cec2f61f00b168bf60a173c36890795710 (diff) | |
download | metacity-d77e3e4f571e2a3bce10e3cfc9859a2157848d9c.tar.gz metacity-d77e3e4f571e2a3bce10e3cfc9859a2157848d9c.tar.xz metacity-d77e3e4f571e2a3bce10e3cfc9859a2157848d9c.zip |
Update to 3.12.0
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | 0001-doc-Update-man-pages.patch | 94 | ||||
-rw-r--r-- | Add-a-newwindowsalwaysontop-preference.patch | 160 | ||||
-rw-r--r-- | Add-nofocuswindows-preference-to-list-windows-that.patch | 881 | ||||
-rw-r--r-- | Allow-breaking-out-from-maximization-during-mouse.patch | 414 | ||||
-rw-r--r-- | Apply-new_windows_always_on_top-to-newly-raised-acti.patch | 113 | ||||
-rw-r--r-- | Exclude-the-current-application-from-no_focus_window.patch | 69 | ||||
-rw-r--r-- | For-mouse-and-sloppy-focus-return-to-mouse-mode-on.patch | 396 | ||||
-rw-r--r-- | Stop-confusing-GDK-s-grab-tracking.patch | 200 | ||||
-rw-r--r-- | dnd-keynav.patch | 11 | ||||
-rw-r--r-- | fresh-tooltips.patch | 287 | ||||
-rw-r--r-- | metacity-2.28-xioerror-unknown-display.patch | 58 | ||||
-rw-r--r-- | metacity.spec | 41 | ||||
-rw-r--r-- | sources | 2 |
14 files changed, 8 insertions, 2719 deletions
@@ -7,3 +7,4 @@ metacity-2.30.0.tar.bz2 /metacity-2.34.3.tar.xz /metacity-2.34.8.tar.xz /metacity-2.34.13.tar.xz +/metacity-3.12.0.tar.xz diff --git a/0001-doc-Update-man-pages.patch b/0001-doc-Update-man-pages.patch deleted file mode 100644 index 9b7adcb..0000000 --- a/0001-doc-Update-man-pages.patch +++ /dev/null @@ -1,94 +0,0 @@ -From 90dc810b9f501136c6f1cf94bc4f4c1f626412b9 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org> -Date: Thu, 16 May 2013 15:37:43 +0200 -Subject: [PATCH] doc: Update man pages - -Metacity is not the fastest moving project, however there were -a view additions in the last nine years, document those. ---- - doc/man/metacity-message.1 | 13 +++++++++++-- - doc/man/metacity.1 | 16 ++++++++++++++-- - 2 files changed, 25 insertions(+), 4 deletions(-) - -diff --git a/doc/man/metacity-message.1 b/doc/man/metacity-message.1 -index 80041f5..13839f8 100644 ---- a/doc/man/metacity-message.1 -+++ b/doc/man/metacity-message.1 -@@ -12,7 +12,7 @@ - .\" > Right I know. any licenses that is DFSG-free, I'm ok with whatever, - .\" > since I have contributed that for Debian. so GPL is no problem for me. - .\" ----- --.TH METACITY\-MESSAGE 1 "28 August 2002" -+.TH METACITY\-MESSAGE 1 "16 May 2013" - .\" Please adjust this date whenever revising the manpage. - .\" - .\" Some roff macros, for reference: -@@ -29,7 +29,7 @@ - METACITY\-MESSAGE \- a command to send a message to Metacity - .SH SYNOPSIS - .B METACITY\-MESSAGE --[restart|reload\-theme|enable\-keybindings|disable\-keybindings] -+[restart|reload\-theme|enable\-keybindings|disable\-keybindings|enable\-mouse\-button\-modifiers|disable\-mouse\-button\-modifiers|toggle\-verbose] - .SH DESCRIPTION - This manual page documents briefly the - .B metacity\-message\fP. -@@ -53,6 +53,15 @@ Enable all of keybindings which is specified on gsettings database. - .TP - .B disable-keybindings - Disable all of keybindings which is specified on gsettings database. -+.TP -+.B enable-mouse-button-modifiers -+Enable move/resize operations while pressing a modifier key -+.TP -+.B disable-mouse-button-modifiers -+Disable move/resize operations while pressing a modifier key -+.TP -+.B toggle-verbose -+Turn debug messages on or off - .SH SEE ALSO - .BR metacity (1) - .SH AUTHOR -diff --git a/doc/man/metacity.1 b/doc/man/metacity.1 -index 0a4c347..eaf75b5 100644 ---- a/doc/man/metacity.1 -+++ b/doc/man/metacity.1 -@@ -2,7 +2,7 @@ - .\" First parameter, NAME, should be all caps - .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection - .\" other parameters are allowed: see man(7), man(1) --.TH METACITY 1 "11 February 2006" -+.TH METACITY 1 "16 May 2013" - .\" Please adjust this date whenever revising the manpage. - .\" - .\" Some roff macros, for reference: -@@ -19,7 +19,7 @@ - METACITY \- minimal GTK2 Window Manager - .SH SYNOPSIS - .B metacity --[\-\-display=\fIDISPLAY\fP] [\-\-replace] [\-\-sm\-client\-id=\fIID\fP] [\-\-sm\-disable] [\-\-sm\-save\-file=\fIFILENAME\fP] [\-\-version] [\-\-help] -+[\-\-display=\fIDISPLAY\fP] [\-\-replace] [\-\-sm\-client\-id=\fIID\fP] [\-\-sm\-disable] [\-\-sm\-save\-file=\fIFILENAME\fP] [\-\-sync] [\-\-composite] [\-\-no-composite] [\-\-no-force-fullscreen] [\-\-version] [\-\-help] - .SH DESCRIPTION - This manual page documents briefly - .B metacity\fP. -@@ -45,6 +45,18 @@ Disable the session management. - .B \-\-sm\-save\-file=FILENAME - Load a session from \fIFILENAME\fP. - .TP -+.B \-\-sync -+Make X calls synchronous -+.TP -+.B \-\-composite -+Turn compositing on -+.TP -+.B \-\-no-composite -+Turn compositing off -+.TP -+.B \-\-no-force-fullscreen -+Don't make fullscreen windows that are maximized and have no decorations -+.TP - .B \-\-version - Print the version number. - .TP --- -1.8.2.1 - diff --git a/Add-a-newwindowsalwaysontop-preference.patch b/Add-a-newwindowsalwaysontop-preference.patch deleted file mode 100644 index f3bf1b1..0000000 --- a/Add-a-newwindowsalwaysontop-preference.patch +++ /dev/null @@ -1,160 +0,0 @@ -From 861a3efb0f531eae767926d18c4d690366306bfe Mon Sep 17 00:00:00 2001 -From: "Owen W. Taylor" <otaylor@fishsoup.net> -Date: Wed, 21 Oct 2009 19:22:35 -0400 -Subject: [PATCH] Add a new-windows-always-on-top preference - -Add a new-windows-always-on-top preference. When set, new windows -are always placed on top, even if they are denied focus. - -This is useful on large screens and multihead setups where the -tasklist can be hard to notice and difficult to mouse to, so the -normal behavior of flashing in the tasklist is less effective. ---- - src/core/prefs.c | 20 +++++++++++++++++++- - src/core/window.c | 6 +++++- - src/include/prefs.h | 2 ++ - src/metacity-schemas.convert | 1 + - src/org.gnome.metacity.gschema.xml.in | 22 ++++++++++++++++++++++ - 5 files changed, 49 insertions(+), 2 deletions(-) - -diff --git a/src/core/prefs.c b/src/core/prefs.c -index 24a98cd..949f6ed 100644 ---- a/src/core/prefs.c -+++ b/src/core/prefs.c -@@ -73,6 +73,7 @@ static GDesktopFocusMode focus_mode = G_DESKTOP_FOCUS_MODE_CLICK; - static GDesktopFocusNewWindows focus_new_windows = G_DESKTOP_FOCUS_NEW_WINDOWS_SMART; - static GSList *no_focus_windows = NULL; - static gboolean raise_on_click = TRUE; -+static gboolean new_windows_always_on_top = TRUE; - static char* current_theme = NULL; - static int num_workspaces = 4; - static GDesktopTitlebarAction action_double_click_titlebar = G_DESKTOP_TITLEBAR_ACTION_TOGGLE_MAXIMIZE; -@@ -261,6 +262,14 @@ static MetaBoolPreference preferences_bool[] = - TRUE, - }, - { -+ { "new-windows-always-on-top", -+ SCHEMA_METACITY, -+ META_PREF_NEW_WINDOWS_ALWAYS_ON_TOP, -+ }, -+ &new_windows_always_on_top, -+ TRUE, -+ }, -+ { - { "titlebar-uses-system-font", - SCHEMA_GENERAL, - META_PREF_TITLEBAR_FONT, /* note! shares a pref */ -@@ -920,6 +929,12 @@ meta_prefs_get_raise_on_click (void) - return raise_on_click || focus_mode == G_DESKTOP_FOCUS_MODE_CLICK; - } - -+gboolean -+meta_prefs_get_new_windows_always_on_top (void) -+{ -+ return new_windows_always_on_top; -+} -+ - const char* - meta_prefs_get_theme (void) - { -@@ -1386,7 +1401,10 @@ meta_preference_to_string (MetaPreference pref) - - case META_PREF_RAISE_ON_CLICK: - return "RAISE_ON_CLICK"; -- -+ -+ case META_PREF_NEW_WINDOWS_ALWAYS_ON_TOP: -+ return "NEW_WINDOWS_ALWAYS_ON_TOP"; -+ - case META_PREF_THEME: - return "THEME"; - -diff --git a/src/core/window.c b/src/core/window.c -index 6f5c280..b6a69b0 100644 ---- a/src/core/window.c -+++ b/src/core/window.c -@@ -2008,7 +2008,7 @@ window_state_on_map (MetaWindow *window, - if (!(window->input || window->take_focus)) - { - *takes_focus = FALSE; -- return; -+ goto out; - } - - /* Terminal usage may be different; some users intend to launch -@@ -2055,6 +2055,10 @@ window_state_on_map (MetaWindow *window, - /* The default is correct for these */ - break; - } -+ -+ out: -+ if (meta_prefs_get_new_windows_always_on_top ()) -+ *places_on_top = TRUE; - } - - static gboolean -diff --git a/src/include/prefs.h b/src/include/prefs.h -index b86843c..c49e93d 100644 ---- a/src/include/prefs.h -+++ b/src/include/prefs.h -@@ -37,6 +37,7 @@ typedef enum - META_PREF_FOCUS_MODE, - META_PREF_FOCUS_NEW_WINDOWS, - META_PREF_RAISE_ON_CLICK, -+ META_PREF_NEW_WINDOWS_ALWAYS_ON_TOP, - META_PREF_ACTION_DOUBLE_CLICK_TITLEBAR, - META_PREF_ACTION_MIDDLE_CLICK_TITLEBAR, - META_PREF_ACTION_RIGHT_CLICK_TITLEBAR, -@@ -81,6 +82,7 @@ guint meta_prefs_get_mouse_button_menu (void); - GDesktopFocusMode meta_prefs_get_focus_mode (void); - GDesktopFocusNewWindows meta_prefs_get_focus_new_windows (void); - gboolean meta_prefs_get_raise_on_click (void); -+gboolean meta_prefs_get_new_windows_always_on_top (void); - const char* meta_prefs_get_theme (void); - /* returns NULL if GTK default should be used */ - const PangoFontDescription* meta_prefs_get_titlebar_font (void); -diff --git a/src/metacity-schemas.convert b/src/metacity-schemas.convert -index 9c271c6..f1fce08 100644 ---- a/src/metacity-schemas.convert -+++ b/src/metacity-schemas.convert -@@ -2,3 +2,4 @@ - compositing-manager = /apps/metacity/general/compositing_manager - reduced-resources = /apps/metacity/general/reduced_resources - no-focus-windows = /apps/metacity/general/no_focus_windows -+new-windows-always-on-top = /apps/metacity/general/new_windows_always_on_top -diff --git a/src/org.gnome.metacity.gschema.xml.in b/src/org.gnome.metacity.gschema.xml.in -index e4f86bd..d69d525 100644 ---- a/src/org.gnome.metacity.gschema.xml.in -+++ b/src/org.gnome.metacity.gschema.xml.in -@@ -46,6 +46,28 @@ - this setting. - </_description> - </key> -+ <key name="new-windows-always-on-top" type="b"> -+ <default>false</default> -+ <_summary>Whether new windows should always be placed on top</_summary> -+ <_description> -+ The normal behavior is that if a new window is not given the -+ focus (since, for example, the user has interacted with another -+ window after launching an application), then if the window would -+ be stacked on top of the focus window, the window is instead -+ stacked beneath and flashed in the taskbar. This behavior can -+ be annoying on large screens and multihead setups where the -+ taskbar is hard to notice and difficult to get to, so this option, -+ if set, disables this behavior, and new windows are always placed -+ on top, whether or not they get focus. -+ -+ Note that if this option is set, a new window may completely hide -+ the focus window but not get focus itself, which can be quite confusing -+ to users. Also, note that setting this option breaks the normal -+ invariant in the 'click' focus mode that the topmost window always -+ has focus, so its most suitable for use with the 'mouse' and -+ 'sloppy' focus modes. -+ </_description> -+ </key> - </schema> - - </schemalist> --- -1.7.9 - diff --git a/Add-nofocuswindows-preference-to-list-windows-that.patch b/Add-nofocuswindows-preference-to-list-windows-that.patch deleted file mode 100644 index bca6f10..0000000 --- a/Add-nofocuswindows-preference-to-list-windows-that.patch +++ /dev/null @@ -1,881 +0,0 @@ -From 60d38a7c6683001ee2beb72b8f0b0beee4f04bb4 Mon Sep 17 00:00:00 2001 -From: "Owen W. Taylor" <otaylor@fishsoup.net> -Date: Wed, 21 Oct 2009 18:07:12 -0400 -Subject: [PATCH] Add no-focus-windows preference to list windows that - shouldn't be focused - -Notification windows from legacy software that don't set _NET_WM_USER_TIME -can be a huge annoyance for users, since they will pop up and steal focus. - -Add: - - no-focus-windows - -which is a list of expressions identifying new windows that shouldn't ever -be focused. For example: - - (and (eq class 'Mylegacyapp') (glob name 'New mail*')) - -https://bugzilla.gnome.org/show_bug.cgi?id=599248 ---- - src/Makefile.am | 2 + - src/core/prefs.c | 55 +++ - src/core/window-matcher.c | 582 +++++++++++++++++++++++++++++++++ - src/core/window-matcher.h | 46 +++ - src/core/window.c | 9 +- - src/include/prefs.h | 6 +- - src/metacity-schemas.convert | 1 + - src/org.gnome.metacity.gschema.xml.in | 21 ++ - 8 files changed, 720 insertions(+), 2 deletions(-) - create mode 100644 src/core/window-matcher.c - create mode 100644 src/core/window-matcher.h - -diff --git a/src/Makefile.am b/src/Makefile.am -index 4d405bf..2befe33 100644 ---- a/src/Makefile.am -+++ b/src/Makefile.am -@@ -66,6 +66,8 @@ metacity_SOURCES= \ - core/stack.h \ - core/util.c \ - include/util.h \ -+ core/window-matcher.c \ -+ core/window-matcher.h \ - core/window-props.c \ - core/window-props.h \ - core/window.c \ -diff --git a/src/core/prefs.c b/src/core/prefs.c -index 58f11e9..24a98cd 100644 ---- a/src/core/prefs.c -+++ b/src/core/prefs.c -@@ -26,6 +26,7 @@ - - #include <config.h> - #include "prefs.h" -+#include "window-matcher.h" - #include "ui.h" - #include "util.h" - #include <glib.h> -@@ -70,6 +71,7 @@ static PangoFontDescription *titlebar_font = NULL; - static MetaVirtualModifier mouse_button_mods = Mod1Mask; - static GDesktopFocusMode focus_mode = G_DESKTOP_FOCUS_MODE_CLICK; - static GDesktopFocusNewWindows focus_new_windows = G_DESKTOP_FOCUS_NEW_WINDOWS_SMART; -+static GSList *no_focus_windows = NULL; - static gboolean raise_on_click = TRUE; - static char* current_theme = NULL; - static int num_workspaces = 4; -@@ -120,6 +122,7 @@ static void maybe_give_disable_workarounds_warning (void); - - static gboolean titlebar_handler (GVariant*, gpointer*, gpointer); - static gboolean theme_name_handler (GVariant*, gpointer*, gpointer); -+static gboolean no_focus_windows_handler (GVariant*, gpointer*, gpointer); - static gboolean mouse_button_mods_handler (GVariant*, gpointer*, gpointer); - static gboolean button_layout_handler (GVariant*, gpointer*, gpointer); - -@@ -367,6 +370,14 @@ static MetaStringPreference preferences_string[] = - NULL, - }, - { -+ { "no-focus-windows", -+ SCHEMA_METACITY, -+ META_PREF_NO_FOCUS_WINDOWS, -+ }, -+ no_focus_windows_handler, -+ NULL -+ }, -+ { - { KEY_TITLEBAR_FONT, - SCHEMA_GENERAL, - META_PREF_TITLEBAR_FONT, -@@ -998,6 +1009,39 @@ theme_name_handler (GVariant *value, - } - - static gboolean -+no_focus_windows_handler (GVariant *value, -+ gpointer *result, -+ gpointer data) -+{ -+ const gchar *string_value; -+ -+ *result = NULL; /* ignored */ -+ string_value = g_variant_get_string (value, NULL); -+ -+ if (no_focus_windows) -+ { -+ meta_window_matcher_list_free (no_focus_windows); -+ no_focus_windows = NULL; -+ } -+ -+ if (string_value) -+ { -+ GError *error = NULL; -+ no_focus_windows = meta_window_matcher_list_from_string (string_value, &error); -+ if (error != NULL) -+ { -+ meta_warning ("Error parsing no_focus_windows='%s': %s\n", -+ string_value, error->message); -+ g_error_free (error); -+ -+ return FALSE; -+ } -+ } -+ -+ return TRUE; -+} -+ -+static gboolean - mouse_button_mods_handler (GVariant *value, - gpointer *result, - gpointer data) -@@ -1414,6 +1458,9 @@ meta_preference_to_string (MetaPreference pref) - - case META_PREF_FORCE_FULLSCREEN: - return "FORCE_FULLSCREEN"; -+ -+ case META_PREF_NO_FOCUS_WINDOWS: -+ return "NO_FOCUS_WINDOWS"; - } - - return "(unknown)"; -@@ -1710,6 +1757,14 @@ meta_prefs_get_action_right_click_titlebar (void) - } - - gboolean -+meta_prefs_window_is_no_focus (const char *window_name, -+ const char *window_class) -+{ -+ return meta_window_matcher_list_matches (no_focus_windows, -+ window_name, window_class); -+} -+ -+gboolean - meta_prefs_get_auto_raise (void) - { - return auto_raise; -diff --git a/src/core/window-matcher.c b/src/core/window-matcher.c -new file mode 100644 -index 0000000..df889eb ---- /dev/null -+++ b/src/core/window-matcher.c -@@ -0,0 +1,582 @@ -+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -+ -+/* Tiny language for matching against windows */ -+ -+/* -+ * Copyright (C) 2009 Red Hat, Inc. -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of the -+ * License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -+ * 02111-1307, USA. -+ */ -+ -+#include <glib.h> -+#include <string.h> -+ -+#include "window-matcher.h" -+ -+typedef struct _MetaWindowMatcher MetaWindowMatcher; -+ -+typedef enum { -+ MATCHER_OPERAND_CLASS, -+ MATCHER_OPERAND_NAME -+} MatcherOperand; -+ -+typedef enum { -+ MATCHER_TOKEN_AND = G_TOKEN_LAST + 1, -+ MATCHER_TOKEN_OR, -+ MATCHER_TOKEN_NOT, -+ MATCHER_TOKEN_EQ, -+ MATCHER_TOKEN_GLOB, -+ MATCHER_TOKEN_NAME, -+ MATCHER_TOKEN_CLASS -+} MatcherToken; -+ -+struct _MetaWindowMatcher { -+ enum { -+ MATCHER_AND, -+ MATCHER_OR, -+ MATCHER_NOT, -+ MATCHER_EQ, -+ MATCHER_GLOB -+ } type; -+ -+ union { -+ struct { -+ MetaWindowMatcher *a; -+ MetaWindowMatcher *b; -+ } and; -+ struct { -+ MetaWindowMatcher *a; -+ MetaWindowMatcher *b; -+ } or; -+ struct { -+ MetaWindowMatcher *a; -+ } not; -+ struct { -+ MatcherOperand operand; -+ char *str; -+ } eq; -+ struct { -+ MatcherOperand operand; -+ char *str; -+ GPatternSpec *pattern; -+ } glob; -+ } u; -+}; -+ -+static void -+meta_window_matcher_free (MetaWindowMatcher *matcher) -+{ -+ switch (matcher->type) -+ { -+ case MATCHER_AND: -+ meta_window_matcher_free (matcher->u.and.a); -+ meta_window_matcher_free (matcher->u.and.b); -+ break; -+ case MATCHER_OR: -+ meta_window_matcher_free (matcher->u.or.a); -+ meta_window_matcher_free (matcher->u.or.b); -+ break; -+ case MATCHER_NOT: -+ meta_window_matcher_free (matcher->u.or.a); -+ break; -+ case MATCHER_EQ: -+ g_free (matcher->u.eq.str); -+ break; -+ case MATCHER_GLOB: -+ g_free (matcher->u.glob.str); -+ g_pattern_spec_free (matcher->u.glob.pattern); -+ break; -+ } -+ -+ g_slice_free (MetaWindowMatcher, matcher); -+} -+ -+void -+meta_window_matcher_list_free (GSList *list) -+{ -+ g_slist_foreach (list, (GFunc)meta_window_matcher_free, NULL); -+ g_slist_free (list); -+} -+ -+static gboolean -+meta_window_matcher_matches (MetaWindowMatcher *matcher, -+ const char *window_name, -+ const char *window_class) -+{ -+ switch (matcher->type) -+ { -+ case MATCHER_AND: -+ return (meta_window_matcher_matches (matcher->u.and.a, window_name, window_class) && -+ meta_window_matcher_matches (matcher->u.and.b, window_name, window_class)); -+ case MATCHER_OR: -+ return (meta_window_matcher_matches (matcher->u.or.a, window_name, window_class) || -+ meta_window_matcher_matches(matcher->u.or.b, window_name, window_class)); -+ case MATCHER_NOT: -+ return !meta_window_matcher_matches (matcher->u.not.a, window_name, window_class); -+ case MATCHER_EQ: -+ if (matcher->u.eq.operand == MATCHER_OPERAND_NAME) -+ return window_name && strcmp (matcher->u.eq.str, window_name) == 0; -+ else -+ return window_class && strcmp (matcher->u.eq.str, window_class) == 0; -+ case MATCHER_GLOB: -+ if (matcher->u.glob.operand == MATCHER_OPERAND_NAME) -+ return window_name && g_pattern_match_string (matcher->u.glob.pattern, window_name); -+ else -+ return window_class && g_pattern_match_string (matcher->u.glob.pattern, window_class); -+ } -+ -+ g_assert_not_reached(); -+ return FALSE; -+} -+ -+gboolean -+meta_window_matcher_list_matches (GSList *list, -+ const char *window_name, -+ const char *window_class) -+{ -+ GSList *l; -+ -+ for (l = list; l; l = l->next) -+ { -+ if (meta_window_matcher_matches (l->data, window_name, window_class)) -+ return TRUE; -+ } -+ -+ return FALSE; -+} -+ -+static const GScannerConfig scanner_config = -+{ -+ " \t\r\n" /* cset_skip_characters */, -+ ( -+ G_CSET_a_2_z -+ "_" -+ G_CSET_A_2_Z -+ ) /* cset_identifier_first */, -+ ( -+ G_CSET_a_2_z -+ "_" -+ G_CSET_A_2_Z -+ G_CSET_DIGITS -+ G_CSET_LATINS -+ G_CSET_LATINC -+ ) /* cset_identifier_nth */, -+ NULL /* cpair_comment_single */, -+ TRUE /* case_sensitive */, -+ TRUE /* skip_comment_multi */, -+ FALSE /* skip_comment_single */, -+ TRUE /* scan_comment_multi */, -+ TRUE /* scan_identifier */, -+ TRUE /* scan_identifier_1char */, -+ FALSE /* scan_identifier_NULL */, -+ TRUE /* scan_symbols */, -+ FALSE /* scan_binary */, -+ TRUE /* scan_octal */, -+ TRUE /* scan_float */, -+ TRUE /* scan_hex */, -+ FALSE /* scan_hex_dollar */, -+ TRUE /* scan_string_sq */, -+ TRUE /* scan_string_dq */, -+ TRUE /* numbers_2_int */, -+ FALSE /* int_2_float */, -+ FALSE /* identifier_2_string */, -+ TRUE /* char_2_token */, -+ TRUE /* symbol_2_token */, -+ FALSE /* scope_0_fallback */, -+ FALSE /* store_int64 */, -+}; -+ -+static void -+set_error (GScanner *scanner, -+ GError **error, -+ const char *message) -+{ -+ g_set_error (error, 0, 0, -+ "Parse error at %d:%d: %s", -+ g_scanner_cur_line (scanner), -+ g_scanner_cur_position (scanner), -+ message); -+} -+ -+static MetaWindowMatcher * -+meta_window_matcher_new_and (MetaWindowMatcher *a, -+ MetaWindowMatcher *b) -+{ -+ MetaWindowMatcher *matcher = g_slice_new0 (MetaWindowMatcher); -+ -+ matcher->type = MATCHER_AND; -+ matcher->u.and.a = a; -+ matcher->u.and.b = b; -+ -+ return matcher; -+} -+ -+static MetaWindowMatcher * -+meta_window_matcher_new_or (MetaWindowMatcher *a, -+ MetaWindowMatcher *b) -+{ -+ MetaWindowMatcher *matcher = g_slice_new0 (MetaWindowMatcher); -+ -+ matcher->type = MATCHER_OR; -+ matcher->u.or.a = a; -+ matcher->u.or.b = b; -+ -+ return matcher; -+} -+ -+static MetaWindowMatcher * -+meta_window_matcher_new_not (MetaWindowMatcher *a) -+{ -+ MetaWindowMatcher *matcher = g_slice_new0 (MetaWindowMatcher); -+ -+ matcher->type = MATCHER_NOT; -+ matcher->u.not.a = a; -+ -+ return matcher; -+} -+ -+static MetaWindowMatcher * -+meta_window_matcher_new_eq (MatcherOperand operand, -+ const char *str) -+{ -+ MetaWindowMatcher *matcher = g_slice_new0 (MetaWindowMatcher); -+ -+ matcher->type = MATCHER_EQ; -+ matcher->u.eq.operand = operand; -+ matcher->u.eq.str = g_strdup (str); -+ -+ return matcher; -+} -+ -+static MetaWindowMatcher * -+meta_window_matcher_new_glob (MatcherOperand operand, -+ const char *str) -+{ -+ MetaWindowMatcher *matcher = g_slice_new0 (MetaWindowMatcher); -+ -+ matcher->type = MATCHER_GLOB; -+ matcher->u.glob.operand = operand; -+ matcher->u.glob.str = g_strdup (str); -+ matcher->u.glob.pattern = g_pattern_spec_new (str); -+ -+ return matcher; -+} -+ -+static MetaWindowMatcher * -+meta_window_matcher_from_scanner (GScanner *scanner, -+ GError **error) -+{ -+ MetaWindowMatcher *matcher = NULL; -+ GTokenType token; -+ GTokenValue value; -+ -+ token = g_scanner_get_next_token (scanner); -+ if (token != G_TOKEN_LEFT_PAREN) -+ { -+ set_error (scanner, error, "expected '('"); -+ return NULL; -+ } -+ -+ token = g_scanner_get_next_token (scanner); -+ switch ((MatcherToken) token) -+ { -+ case MATCHER_TOKEN_AND: -+ case MATCHER_TOKEN_OR: -+ case MATCHER_TOKEN_NOT: -+ { -+ MetaWindowMatcher *a, *b; -+ -+ a = meta_window_matcher_from_scanner (scanner, error); -+ if (!a) -+ return NULL; -+ -+ if ((MatcherToken) token != MATCHER_TOKEN_NOT) -+ { -+ b = meta_window_matcher_from_scanner (scanner, error); -+ if (!b) -+ { -+ meta_window_matcher_free (a); -+ return NULL; -+ } -+ } -+ -+ switch ((MatcherToken) token) -+ { -+ case MATCHER_TOKEN_AND: -+ matcher = meta_window_matcher_new_and (a, b); -+ break; -+ case MATCHER_TOKEN_OR: -+ matcher = meta_window_matcher_new_or (a, b); -+ break; -+ case MATCHER_TOKEN_NOT: -+ matcher = meta_window_matcher_new_not (a); -+ break; -+ default: -+ g_assert_not_reached(); -+ break; -+ } -+ } -+ break; -+ case MATCHER_TOKEN_EQ: -+ case MATCHER_TOKEN_GLOB: -+ { -+ MatcherOperand operand; -+ -+ switch ((MatcherToken) g_scanner_get_next_token (scanner)) -+ { -+ case MATCHER_TOKEN_NAME: -+ operand = MATCHER_OPERAND_NAME; -+ break; -+ case MATCHER_TOKEN_CLASS: -+ operand = MATCHER_OPERAND_CLASS; -+ break; -+ default: -+ set_error (scanner, error, "expected name/class"); -+ return NULL; -+ } -+ -+ if (g_scanner_get_next_token (scanner) != G_TOKEN_STRING) -+ { -+ set_error (scanner, error, "expected string"); -+ return NULL; -+ } -+ -+ value = g_scanner_cur_value (scanner); -+ -+ switch ((MatcherToken) token) -+ { -+ case MATCHER_TOKEN_EQ: -+ matcher = meta_window_matcher_new_eq (operand, value.v_string); -+ break; -+ case MATCHER_TOKEN_GLOB: -+ matcher = meta_window_matcher_new_glob (operand, value.v_string); -+ break; -+ default: -+ g_assert_not_reached(); -+ } -+ } -+ break; -+ default: -+ set_error (scanner, error, "expected and/or/not/eq/glob"); -+ return NULL; -+ } -+ -+ if (g_scanner_get_next_token (scanner) != G_TOKEN_RIGHT_PAREN) -+ { -+ set_error (scanner, error, "expected ')'"); -+ return NULL; -+ } -+ -+ return matcher; -+} -+ -+GSList * -+meta_window_matcher_list_from_string (const char *str, -+ GError **error) -+{ -+ GScanner *scanner = g_scanner_new (&scanner_config); -+ GSList *result = NULL; -+ -+ g_scanner_scope_add_symbol (scanner, 0, "and", GINT_TO_POINTER (MATCHER_TOKEN_AND)); -+ g_scanner_scope_add_symbol (scanner, 0, "or", GINT_TO_POINTER (MATCHER_TOKEN_OR)); -+ g_scanner_scope_add_symbol (scanner, 0, "not", GINT_TO_POINTER (MATCHER_TOKEN_NOT)); -+ g_scanner_scope_add_symbol (scanner, 0, "eq", GINT_TO_POINTER (MATCHER_TOKEN_EQ)); -+ g_scanner_scope_add_symbol (scanner, 0, "glob", GINT_TO_POINTER (MATCHER_TOKEN_GLOB)); -+ g_scanner_scope_add_symbol (scanner, 0, "name", GINT_TO_POINTER (MATCHER_TOKEN_NAME)); -+ g_scanner_scope_add_symbol (scanner, 0, "class", GINT_TO_POINTER (MATCHER_TOKEN_CLASS)); -+ -+ g_scanner_input_text (scanner, str, strlen (str)); -+ -+ while (g_scanner_peek_next_token (scanner) != G_TOKEN_EOF) -+ { -+ MetaWindowMatcher *matcher = meta_window_matcher_from_scanner (scanner, error); -+ if (!matcher) -+ { -+ meta_window_matcher_list_free (result); -+ return NULL; -+ } -+ -+ result = g_slist_prepend (result, matcher); -+ } -+ -+ g_scanner_destroy (scanner); -+ -+ return g_slist_reverse (result); -+} -+ -+#ifdef BUILD_MATCHER_TESTS -+ -+static void -+append_operand_to_string (GString *string, -+ MatcherOperand operand) -+{ -+ if (operand == MATCHER_OPERAND_NAME) -+ g_string_append (string, "name"); -+ else -+ g_string_append (string, "class"); -+} -+ -+static void -+append_string_to_string (GString *str, -+ const char *to_append) -+{ -+ const char *p; -+ -+ g_string_append_c (str, '"'); -+ for (p = to_append; *p; p++) -+ { -+ if (*p == '"') -+ g_string_append (str, "\\\""); -+ else -+ g_string_append_c (str, *p); -+ } -+ g_string_append_c (str, '"'); -+} -+ -+static void -+append_matcher_to_string (GString *str, -+ MetaWindowMatcher *matcher) -+{ -+ switch (matcher->type) -+ { -+ case MATCHER_AND: -+ g_string_append (str, "(and "); -+ append_matcher_to_string (str, matcher->u.and.a); -+ g_string_append_c (str, ' '); -+ append_matcher_to_string (str, matcher->u.and.b); -+ break; -+ case MATCHER_OR: -+ g_string_append (str, "(or "); -+ append_matcher_to_string (str, matcher->u.or.a); -+ g_string_append_c (str, ' '); -+ append_matcher_to_string (str, matcher->u.or.b); -+ break; -+ case MATCHER_NOT: -+ g_string_append (str, "(not "); -+ append_matcher_to_string (str, matcher->u.not.a); -+ break; -+ case MATCHER_EQ: -+ g_string_append (str, "(eq "); -+ append_operand_to_string (str, matcher->u.eq.operand); -+ g_string_append_c (str, ' '); -+ append_string_to_string (str, matcher->u.eq.str); -+ break; -+ case MATCHER_GLOB: -+ g_string_append (str, "(glob "); -+ append_operand_to_string (str, matcher->u.glob.operand); -+ g_string_append_c (str, ' '); -+ append_string_to_string (str, matcher->u.glob.str); -+ break; -+ } -+ -+ g_string_append_c (str, ')'); -+} -+ -+static char * -+meta_window_matcher_list_to_string (GSList *list) -+{ -+ GSList *l; -+ GString *str = g_string_new (NULL); -+ -+ for (l = list; l; l = l->next) -+ { -+ if (str->len > 0) -+ g_string_append_c (str, ' '); -+ -+ append_matcher_to_string (str, l->data); -+ } -+ -+ return g_string_free (str, FALSE); -+} -+ -+static void -+test_roundtrip (const char *str) -+{ -+ GError *error = NULL; -+ GSList *list = meta_window_matcher_list_from_string (str, &error); -+ char *result; -+ -+ if (error != NULL) -+ g_error ("Failed to parse '%s': %s\n", str, error->message); -+ -+ result = meta_window_matcher_list_to_string (list); -+ if (strcmp (result, str) != 0) -+ g_error ("Round-trip conversion of '%s' gave '%s'\n", str, result); -+ -+ g_free (result); -+ meta_window_matcher_list_free (list); -+} -+ -+static void -+test_matches (const char *str, -+ const char *window_name, -+ const char *window_class, -+ gboolean expected) -+{ -+ GError *error = NULL; -+ GSList *list = meta_window_matcher_list_from_string (str, &error); -+ gboolean matches; -+ -+ if (error != NULL) -+ g_error ("Failed to parse '%s': %s\n", str, error->message); -+ -+ matches = meta_window_matcher_list_matches (list, window_name, window_class)) -+ if (matches != expected) -+ { -+ g_error ("Tested '%s' against name=%s, class=%s, expected %s, got %s\n", -+ str, window_name, window_class, -+ expected ? "true" : "false", -+ matches ? "true" : "false"); -+ } -+ -+ -+ meta_window_matcher_list_free (list); -+} -+ -+int main (int argc, char **argv) -+{ -+ test_roundtrip ("(eq name \"foo\")"); -+ test_roundtrip ("(eq name \"fo\\\"o\")"); -+ test_roundtrip ("(glob class \"*bar?baz\")"); -+ test_roundtrip ("(and (eq name \"foo\") (glob class \"*bar?baz\"))"); -+ test_roundtrip ("(or (eq name \"foo\") (glob class \"*bar?baz\"))"); -+ test_roundtrip ("(not (eq name \"foo\"))"); -+ -+ test_roundtrip ("(eq name \"foo\") (glob class \"*bar?baz\")"); -+ -+ test_matches ("(eq name 'foo')", "foo", NULL, TRUE); -+ test_matches ("(eq name 'foo')", "foob", NULL, FALSE); -+ test_matches ("(eq name 'foo')", NULL, NULL, FALSE); -+ test_matches ("(eq class 'bar')", "foo", "bar", TRUE); -+ test_matches ("(eq class 'bar')", NULL, NULL, FALSE); -+ -+ test_matches ("(glob name 'foo*')", "foooo", NULL, TRUE); -+ test_matches ("(glob name 'foo*')", NULL, NULL, FALSE); -+ test_matches ("(glob class 'b*r')", "foooo", "baaaar", TRUE); -+ test_matches ("(glob class 'b*r')", NULL, NULL, FALSE); -+ -+ test_matches ("(and (eq name 'foo') (eq class 'bar'))", "foo", "bar", TRUE); -+ test_matches ("(and (eq name 'foo') (eq class 'bar'))", "foo", "baz", FALSE); -+ test_matches ("(and (eq name 'foo') (not (eq class 'bar')))", "foo", "bar", FALSE); -+ test_matches ("(and (eq name 'foo') (not (eq class 'bar')))", "foo", "baz", TRUE); -+ -+ test_matches ("(or (eq name 'foo') (eq class 'bar'))", "foo", "baz", TRUE); -+ test_matches ("(or (eq name 'foo') (eq class 'bar'))", "fof", "baz", FALSE); -+ -+ return 0; -+} -+ -+#endif /* BUILD_MATCHER_TESTS */ -diff --git a/src/core/window-matcher.h b/src/core/window-matcher.h -new file mode 100644 -index 0000000..7fc7826 ---- /dev/null -+++ b/src/core/window-matcher.h -@@ -0,0 +1,46 @@ -+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -+ -+/* Tiny language for matching against windows -+ * -+ * Expression Syntax: -+ * -+ * (and <expr> <expr>) -+ * (or <expr> <expr>) -+ * (not <expr>) -+ * (eq [name|class] "<value>") -+ * (glob [name|class] "<glob>") -+ * -+ * A "matcher list" is a whitespace-separated list of expressions that are -+ * implicitly or'ed together. Globs are shell style patterns with -+ * matching 0 or more characters and ? matching one character. -+ */ -+ -+/* -+ * Copyright (C) 2009 Red Hat, Inc. -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of the -+ * License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -+ * 02111-1307, USA. -+ */ -+ -+#ifndef META_WINDOW_MATCHER_H -+#define META_WINDOW_MATCHER_H -+ -+GSList * meta_window_matcher_list_from_string (const char *str, -+ GError **error); -+void meta_window_matcher_list_free (GSList *list); -+gboolean meta_window_matcher_list_matches (GSList *list, -+ const char *window_name, -+ const char *window_class); -+#endif /* META_WINDOW_MATCHER_H */ -diff --git a/src/core/window.c b/src/core/window.c -index 2f2f800..5440160 100644 ---- a/src/core/window.c -+++ b/src/core/window.c -@@ -1981,7 +1981,14 @@ window_state_on_map (MetaWindow *window, - { - gboolean intervening_events; - -- intervening_events = intervening_user_event_occurred (window); -+ /* A 'no focus' window is a window that has been configured in GConf -+ * to never take focus on map; typically it will be a notification -+ * window from a legacy app that doesn't support _NET_WM_USER_TIME. -+ */ -+ if (meta_prefs_window_is_no_focus (window->title, window->res_class)) -+ intervening_events = TRUE; -+ else -+ intervening_events = intervening_user_event_occurred (window); - - *takes_focus = !intervening_events; - *places_on_top = *takes_focus; -diff --git a/src/include/prefs.h b/src/include/prefs.h -index 673cb36..b86843c 100644 ---- a/src/include/prefs.h -+++ b/src/include/prefs.h -@@ -60,7 +60,8 @@ typedef enum - META_PREF_CURSOR_SIZE, - META_PREF_COMPOSITING_MANAGER, - META_PREF_RESIZE_WITH_RIGHT_BUTTON, -- META_PREF_FORCE_FULLSCREEN -+ META_PREF_FORCE_FULLSCREEN, -+ META_PREF_NO_FOCUS_WINDOWS - } MetaPreference; - - typedef void (* MetaPrefsChangedFunc) (MetaPreference pref, -@@ -105,6 +106,9 @@ GDesktopTitlebarAction meta_prefs_get_action_double_click_titlebar (void); - GDesktopTitlebarAction meta_prefs_get_action_middle_click_titlebar (void); - GDesktopTitlebarAction meta_prefs_get_action_right_click_titlebar (void); - -+gboolean meta_prefs_window_is_no_focus (const char *window_name, -+ const char *window_class); -+ - void meta_prefs_set_num_workspaces (int n_workspaces); - - const char* meta_prefs_get_workspace_name (int i); -diff --git a/src/metacity-schemas.convert b/src/metacity-schemas.convert -index 46f3104..9c271c6 100644 ---- a/src/metacity-schemas.convert -+++ b/src/metacity-schemas.convert -@@ -1,3 +1,4 @@ - [org.gnome.metacity] - compositing-manager = /apps/metacity/general/compositing_manager - reduced-resources = /apps/metacity/general/reduced_resources -+no-focus-windows = /apps/metacity/general/no_focus_windows -diff --git a/src/org.gnome.metacity.gschema.xml.in b/src/org.gnome.metacity.gschema.xml.in -index 8fcdd7c..6900fa6 100644 ---- a/src/org.gnome.metacity.gschema.xml.in -+++ b/src/org.gnome.metacity.gschema.xml.in -@@ -22,6 +22,27 @@ - However, the wireframe feature is disabled when accessibility is on. - </_description> - </key> -+ <key name="no-focus-windows" type="s"> -+ <default>''</default> -+ <_summary>New windows that shouldn't get focus</_summary> -+ <_description> -+ This option provides a way to specify new windows that shouldn't get -+ focus. Normally an application specifies whether or not it gets focus -+ by setting the _NET_WM_USER_TIME property, but legacy applications -+ may not set this, which can cause unwanted focus stealing. -+ -+ The contents of this property is a space-separated list of expressions -+ to match against windows. If any of the expressions match a window -+ then the window will not get focus. The syntax of expressions is: -+ -+ (eq [name|class] "<value>"): window name (title) or the class from -+ WM_CLASS matches <value> exactly. -+ (glob [name|class] "<glob>"): window name (title) or the class from -+ WM_CLASS matches the shell-style glob pattern <glob>. -+ (and <expr> <expr>) (or <expr> <expr>) (not <expr): Boolean combinations -+ of expressions. -+ </_description> -+ </key> - </schema> - - </schemalist> --- -1.7.9 - diff --git a/Allow-breaking-out-from-maximization-during-mouse.patch b/Allow-breaking-out-from-maximization-during-mouse.patch deleted file mode 100644 index 286c873..0000000 --- a/Allow-breaking-out-from-maximization-during-mouse.patch +++ /dev/null @@ -1,414 +0,0 @@ -From 00d291927a59b6bca164fc5cd2d4729604b40d1c Mon Sep 17 00:00:00 2001 -From: "Owen W. Taylor" <otaylor@fishsoup.net> -Date: Wed, 23 Jun 2010 15:08:38 -0400 -Subject: [PATCH] Allow breaking out from maximization during a mouse - resize - -A maximized window can't be resized from the screen edges (preserves -Fitts law goodness for the application), but it's still possible -to start a resize drag with alt-middle-button. Currently we just -don't let the user resize the window, while showing drag feedback; -it's more useful to let the user "break" out from the resize. - -This provides a fast way to get a window partially aligned with -the screen edges - maximize, then alt-drag it out from one edge. - -Behavior choices in this patch: - - - You can drag out a window out of maximization in both directions - - smaller and larger. This can be potentilaly useful in multihead. - - - Dragging a window in only one direction unmaximizes the window - fully, rather than leaving it in a horizontally/vertically - maximized state. This is done because the horizontally/vertically - maximzed states don't have clear visual representation and can - be confusing to the user. - - - If you drag back to the maximized state after breaking out, - maximization is restored, but you can't maximize a window by - dragging to the full size if it didn't start out that way. - -A new internal function meta_window_unmaximize_with_gravity() is -added for implementing this; it's a hybrid of -meta_window_unmaximize() and meta_window_resize_with_gravity(). - -https://bugzilla.gnome.org/show_bug.cgi?id=622517 ---- - src/core/display-private.h | 3 + - src/core/display.c | 20 +++- - src/core/window-private.h | 5 + - src/core/window.c | 224 ++++++++++++++++++++++++++++++++++++++++---- - 4 files changed, 228 insertions(+), 24 deletions(-) - -diff --git a/src/core/display-private.h b/src/core/display-private.h -index 7f779fd..bb6ba8a 100644 ---- a/src/core/display-private.h -+++ b/src/core/display-private.h -@@ -178,6 +178,9 @@ struct _MetaDisplay - guint grab_wireframe_active : 1; - guint grab_was_cancelled : 1; /* Only used in wireframe mode */ - guint grab_frame_action : 1; -+ /* During a resize operation, the directions in which we've broken -+ * out of the initial maximization state */ -+ guint grab_resize_unmaximize : 2; /* MetaMaximizeFlags */ - MetaRectangle grab_wireframe_rect; - MetaRectangle grab_wireframe_last_xor_rect; - MetaRectangle grab_initial_window_pos; -diff --git a/src/core/display.c b/src/core/display.c -index 0c5f61d..25cf857 100644 ---- a/src/core/display.c -+++ b/src/core/display.c -@@ -3470,6 +3470,7 @@ meta_display_begin_grab_op (MetaDisplay *display, - #endif - display->grab_was_cancelled = FALSE; - display->grab_frame_action = frame_action; -+ display->grab_resize_unmaximize = 0; - - if (display->grab_resize_timeout_id) - { -@@ -3700,11 +3701,20 @@ meta_display_end_grab_op (MetaDisplay *display, - display->grab_wireframe_rect.x, - display->grab_wireframe_rect.y); - if (meta_grab_op_is_resizing (display->grab_op)) -- meta_window_resize_with_gravity (display->grab_window, -- TRUE, -- display->grab_wireframe_rect.width, -- display->grab_wireframe_rect.height, -- meta_resize_gravity_from_grab_op (display->grab_op)); -+ { -+ if (display->grab_resize_unmaximize != 0) -+ meta_window_unmaximize_with_gravity (display->grab_window, -+ display->grab_resize_unmaximize, -+ display->grab_wireframe_rect.width, -+ display->grab_wireframe_rect.height, -+ meta_resize_gravity_from_grab_op (display->grab_op)); -+ else -+ meta_window_resize_with_gravity (display->grab_window, -+ TRUE, -+ display->grab_wireframe_rect.width, -+ display->grab_wireframe_rect.height, -+ meta_resize_gravity_from_grab_op (display->grab_op)); -+ } - } - meta_window_calc_showing (display->grab_window); - } -diff --git a/src/core/window-private.h b/src/core/window-private.h -index 7cf5b04..2c07e85 100644 ---- a/src/core/window-private.h -+++ b/src/core/window-private.h -@@ -412,6 +412,11 @@ void meta_window_maximize_internal (MetaWindow *window, - MetaRectangle *saved_rect); - void meta_window_unmaximize (MetaWindow *window, - MetaMaximizeFlags directions); -+void meta_window_unmaximize_with_gravity (MetaWindow *window, -+ MetaMaximizeFlags directions, -+ int new_width, -+ int new_height, -+ int gravity); - void meta_window_make_above (MetaWindow *window); - void meta_window_unmake_above (MetaWindow *window); - void meta_window_shade (MetaWindow *window, -diff --git a/src/core/window.c b/src/core/window.c -index 897161e..427f91f 100644 ---- a/src/core/window.c -+++ b/src/core/window.c -@@ -2693,9 +2693,11 @@ unmaximize_window_before_freeing (MetaWindow *window) - } - } - --void --meta_window_unmaximize (MetaWindow *window, -- MetaMaximizeFlags directions) -+static void -+meta_window_unmaximize_internal (MetaWindow *window, -+ MetaMaximizeFlags directions, -+ MetaRectangle *desired_rect, -+ int gravity) - { - /* At least one of the two directions ought to be set */ - gboolean unmaximize_horizontally, unmaximize_vertically; -@@ -2729,13 +2731,13 @@ meta_window_unmaximize (MetaWindow *window, - meta_window_get_client_root_coords (window, &target_rect); - if (unmaximize_horizontally) - { -- target_rect.x = window->saved_rect.x; -- target_rect.width = window->saved_rect.width; -+ target_rect.x = desired_rect->x; -+ target_rect.width = desired_rect->width; - } - if (unmaximize_vertically) - { -- target_rect.y = window->saved_rect.y; -- target_rect.height = window->saved_rect.height; -+ target_rect.y = desired_rect->y; -+ target_rect.height = desired_rect->height; - } - - /* Window's size hints may have changed while maximized, making -@@ -2754,12 +2756,13 @@ meta_window_unmaximize (MetaWindow *window, - window->display->grab_anchor_window_pos = target_rect; - } - -- meta_window_move_resize (window, -- FALSE, -- target_rect.x, -- target_rect.y, -- target_rect.width, -- target_rect.height); -+ meta_window_move_resize_internal (window, -+ META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION, -+ gravity, -+ target_rect.x, -+ target_rect.y, -+ target_rect.width, -+ target_rect.height); - - /* Make sure user_rect is current. - */ -@@ -2776,6 +2779,36 @@ meta_window_unmaximize (MetaWindow *window, - } - - void -+meta_window_unmaximize (MetaWindow *window, -+ MetaMaximizeFlags directions) -+{ -+ meta_window_unmaximize_internal (window, directions, &window->saved_rect, -+ NorthWestGravity); -+} -+ -+/* Like meta_window_unmaximize(), but instead of unmaximizing to the -+ * saved position, we give the new desired size, and the gravity that -+ * determines the positioning relationship between the area occupied -+ * maximized and the new are. The arguments are similar to -+ * meta_window_resize_with_gravity(). -+ */ -+void -+meta_window_unmaximize_with_gravity (MetaWindow *window, -+ MetaMaximizeFlags directions, -+ int new_width, -+ int new_height, -+ int gravity) -+{ -+ MetaRectangle desired_rect; -+ -+ meta_window_get_position (window, &desired_rect.x, &desired_rect.y); -+ desired_rect.width = new_width; -+ desired_rect.height = new_height; -+ -+ meta_window_unmaximize_internal (window, directions, &desired_rect, gravity); -+} -+ -+void - meta_window_make_above (MetaWindow *window) - { - window->wm_state_above = TRUE; -@@ -7124,6 +7157,112 @@ update_resize_timeout (gpointer data) - return FALSE; - } - -+/* When resizing a maximized window by using alt-middle-drag (resizing -+ * with the grips or the menu for a maximized window is not enabled), -+ * the user can "break" out of the maximized state. This checks for -+ * that possibility. During such a break-out resize the user can also -+ * return to the previous maximization state by resizing back to near -+ * the original size. -+ */ -+static MetaMaximizeFlags -+check_resize_unmaximize(MetaWindow *window, -+ int dx, -+ int dy) -+{ -+ int threshold; -+ MetaMaximizeFlags new_unmaximize; -+ -+#define DRAG_THRESHOLD_TO_RESIZE_THRESHOLD_FACTOR 3 -+ -+ threshold = meta_ui_get_drag_threshold (window->screen->ui) * -+ DRAG_THRESHOLD_TO_RESIZE_THRESHOLD_FACTOR; -+ new_unmaximize = 0; -+ -+ if (window->maximized_horizontally || -+ (window->display->grab_resize_unmaximize & META_MAXIMIZE_HORIZONTAL) != 0) -+ { -+ int x_amount; -+ -+ /* We allow breaking out of maximization in either direction, to make -+ * the window larger than the monitor as well as smaller than the -+ * monitor. If we wanted to only allow resizing smaller than the -+ * monitor, we'd use - dx for NE/E/SE and dx for SW/W/NW. -+ */ -+ switch (window->display->grab_op) -+ { -+ case META_GRAB_OP_RESIZING_NE: -+ case META_GRAB_OP_KEYBOARD_RESIZING_NE: -+ case META_GRAB_OP_RESIZING_E: -+ case META_GRAB_OP_KEYBOARD_RESIZING_E: -+ case META_GRAB_OP_RESIZING_SE: -+ case META_GRAB_OP_KEYBOARD_RESIZING_SE: -+ case META_GRAB_OP_RESIZING_SW: -+ case META_GRAB_OP_KEYBOARD_RESIZING_SW: -+ case META_GRAB_OP_RESIZING_W: -+ case META_GRAB_OP_KEYBOARD_RESIZING_W: -+ case META_GRAB_OP_RESIZING_NW: -+ case META_GRAB_OP_KEYBOARD_RESIZING_NW: -+ x_amount = dx < 0 ? - dx : dx; -+ break; -+ default: -+ x_amount = 0; -+ break; -+ } -+ -+ if (x_amount > threshold) -+ new_unmaximize |= META_MAXIMIZE_HORIZONTAL; -+ } -+ -+ if (window->maximized_vertically || -+ (window->display->grab_resize_unmaximize & META_MAXIMIZE_VERTICAL) != 0) -+ { -+ int y_amount; -+ -+ switch (window->display->grab_op) -+ { -+ case META_GRAB_OP_RESIZING_N: -+ case META_GRAB_OP_KEYBOARD_RESIZING_N: -+ case META_GRAB_OP_RESIZING_NE: -+ case META_GRAB_OP_KEYBOARD_RESIZING_NE: -+ case META_GRAB_OP_RESIZING_NW: -+ case META_GRAB_OP_KEYBOARD_RESIZING_NW: -+ case META_GRAB_OP_RESIZING_SE: -+ case META_GRAB_OP_KEYBOARD_RESIZING_SE: -+ case META_GRAB_OP_RESIZING_S: -+ case META_GRAB_OP_KEYBOARD_RESIZING_S: -+ case META_GRAB_OP_RESIZING_SW: -+ case META_GRAB_OP_KEYBOARD_RESIZING_SW: -+ y_amount = dy < 0 ? - dy : dy; -+ break; -+ default: -+ y_amount = 0; -+ break; -+ } -+ -+ if (y_amount > threshold) -+ new_unmaximize |= META_MAXIMIZE_VERTICAL; -+ } -+ -+ /* Metacity doesn't have a full user interface for only horizontally or -+ * vertically maximized, so while only unmaximizing in the direction drags -+ * has some advantages, it will also confuse the user. So, we always -+ * unmaximize both ways if possible. -+ */ -+ if (new_unmaximize != 0) -+ { -+ new_unmaximize = 0; -+ -+ if (window->maximized_horizontally || -+ (window->display->grab_resize_unmaximize & META_MAXIMIZE_HORIZONTAL) != 0) -+ new_unmaximize |= META_MAXIMIZE_HORIZONTAL; -+ if (window->maximized_vertically || -+ (window->display->grab_resize_unmaximize & META_MAXIMIZE_VERTICAL) != 0) -+ new_unmaximize |= META_MAXIMIZE_VERTICAL; -+ } -+ -+ return new_unmaximize; -+} -+ - static void - update_resize (MetaWindow *window, - gboolean snap, -@@ -7136,6 +7275,7 @@ update_resize (MetaWindow *window, - MetaRectangle old; - int new_x, new_y; - double remaining; -+ MetaMaximizeFlags new_unmaximize; - - window->display->grab_latest_motion_x = x; - window->display->grab_latest_motion_y = y; -@@ -7200,7 +7340,9 @@ update_resize (MetaWindow *window, - meta_window_update_keyboard_resize (window, TRUE); - } - } -- -+ -+ new_unmaximize = check_resize_unmaximize (window, dx, dy); -+ - /* FIXME: This stupidity only needed because of wireframe mode and - * the fact that wireframe isn't making use of - * meta_rectangle_resize_with_gravity(). If we were to use that, we -@@ -7324,6 +7466,8 @@ update_resize (MetaWindow *window, - - if (window->display->grab_wireframe_active) - { -+ MetaRectangle root_coords; -+ - if ((new_x + new_w <= new_x) || (new_y + new_h <= new_y)) - return; - -@@ -7333,18 +7477,60 @@ update_resize (MetaWindow *window, - * wireframe, but still resize it; however, that probably - * confuses broken clients that have problems with opaque - * resize, they probably don't track their visibility. -+ * -+ * We handle the basic constraints on maximized windows here -+ * to give the user feedback. - */ -+ -+ if (window->maximized_horizontally && (new_unmaximize & META_MAXIMIZE_HORIZONTAL) == 0) -+ { -+ meta_window_get_client_root_coords (window, &root_coords); -+ new_x = root_coords.x; -+ new_w = root_coords.width; -+ } -+ if (window->maximized_vertically && (new_unmaximize & META_MAXIMIZE_VERTICAL) == 0) -+ { -+ meta_window_get_client_root_coords (window, &root_coords); -+ new_y = root_coords.y; -+ new_h = root_coords.height; -+ } -+ - meta_window_update_wireframe (window, new_x, new_y, new_w, new_h); - } - else - { -- /* We don't need to update unless the specified width and height -- * are actually different from what we had before. -- */ -- if (old.width != new_w || old.height != new_h) -- meta_window_resize_with_gravity (window, TRUE, new_w, new_h, gravity); -+ if (new_unmaximize == window->display->grab_resize_unmaximize) -+ { -+ /* We don't need to update unless the specified width and height -+ * are actually different from what we had before. -+ */ -+ if (old.width != new_w || old.height != new_h) -+ { -+ if ((window->display->grab_resize_unmaximize == new_unmaximize)) -+ meta_window_resize_with_gravity (window, TRUE, new_w, new_h, gravity); -+ } -+ } -+ else -+ { -+ if ((new_unmaximize & ~window->display->grab_resize_unmaximize) != 0) -+ { -+ meta_window_unmaximize_with_gravity (window, -+ (new_unmaximize & ~window->display->grab_resize_unmaximize), -+ new_w, new_h, gravity); -+ } -+ -+ if ((window->display->grab_resize_unmaximize & ~new_unmaximize)) -+ { -+ MetaRectangle saved_rect = window->saved_rect; -+ meta_window_maximize (window, -+ (window->display->grab_resize_unmaximize & ~new_unmaximize)); -+ window->saved_rect = saved_rect; -+ } -+ } - } - -+ window->display->grab_resize_unmaximize = new_unmaximize; -+ - /* Store the latest resize time, if we actually resized. */ - if (window->rect.width != old.width || window->rect.height != old.height) - g_get_current_time (&window->display->grab_last_moveresize_time); --- -1.7.9 - diff --git a/Apply-new_windows_always_on_top-to-newly-raised-acti.patch b/Apply-new_windows_always_on_top-to-newly-raised-acti.patch deleted file mode 100644 index 93378bf..0000000 --- a/Apply-new_windows_always_on_top-to-newly-raised-acti.patch +++ /dev/null @@ -1,113 +0,0 @@ -From 2bd938c957b27c1055f7f235939c9b8b338d5cbf Mon Sep 17 00:00:00 2001 -From: "Owen W. Taylor" <otaylor@fishsoup.net> -Date: Wed, 23 Jun 2010 19:45:05 -0400 -Subject: [PATCH] Apply new-windows-always-on-top to newly - raised/activated windows - -A window that raises itself or activates itself is in many ways -like a completely new window. (Once a window is out of the user's -site, they really have no idea if it's mapped or has been withdrawn -by the user.) - -If the user has set the new-windows-always-on-top key to make the -behavior for a focus-stealing-prevented *new* window "raise but not -focus", then they'll want the same behavior in the case of -windows that attempt to raise or activate themselves as well. - -https://bugzilla.gnome.org/show_bug.cgi?id=599261 ---- - src/core/window.c | 35 +++++++++++++++++++++++++++++--- - src/org.gnome.metacity.gschema.xml.in | 6 +++++ - 2 files changed, 37 insertions(+), 4 deletions(-) - -diff --git a/src/core/window.c b/src/core/window.c -index b6a69b0..897161e 100644 ---- a/src/core/window.c -+++ b/src/core/window.c -@@ -2970,6 +2970,8 @@ window_activate (MetaWindow *window, - MetaWorkspace *workspace) - { - gboolean can_ignore_outdated_timestamps; -+ gboolean only_raise = FALSE; -+ - meta_topic (META_DEBUG_FOCUS, - "_NET_ACTIVE_WINDOW message sent for %s at time %u " - "by client type %u.\n", -@@ -2991,8 +2993,28 @@ window_activate (MetaWindow *window, - "last_user_time (%u) is more recent; ignoring " - " _NET_ACTIVE_WINDOW message.\n", - window->display->last_user_time); -- meta_window_set_demands_attention(window); -- return; -+ if (meta_prefs_get_new_windows_always_on_top () && -+ meta_prefs_get_raise_on_click ()) -+ { -+ /* The new_windows_only_on_top preference causes new -+ * focus-denied windows to get raised but not focused -+ * instead of set to demands attention. For consistency, we -+ * do the same here with windows that are "new to the user" -+ * - that self activate and are focus-stealing prevented. We -+ * can't just raise the window and return here because the -+ * window might be on a different workspace, so we need the -+ * handling below. The check for meta_prefs_get_raise_on_click () -+ * is because that preference, if off, somewhat unexpectedl -+ * akes windows not raise on self-activation. If that is changed -+ * than the test should be removed here. -+ */ -+ only_raise = TRUE; -+ } -+ else -+ { -+ meta_window_set_demands_attention (window); -+ return; -+ } - } - - /* For those stupid pagers, get a valid timestamp and show a warning */ -@@ -3041,7 +3063,8 @@ window_activate (MetaWindow *window, - meta_topic (META_DEBUG_FOCUS, - "Focusing window %s due to activation\n", - window->desc); -- meta_window_focus (window, timestamp); -+ if (!only_raise) -+ meta_window_focus (window, timestamp); - } - - /* This function exists since most of the functionality in window_activate -@@ -4759,11 +4782,15 @@ meta_window_configure_request (MetaWindow *window, - "broken behavior and the request is being ignored.\n", - window->desc); - } -+ /* the new_windows_always_on_top check is because a window that -+ * spontaneously restacks itself to the top is a lot like a new -+ * window that doesn't get focus */ - else if (active_window && - !meta_window_same_application (window, active_window) && - !meta_window_same_client (window, active_window) && - XSERVER_TIME_IS_BEFORE (window->net_wm_user_time, -- active_window->net_wm_user_time)) -+ active_window->net_wm_user_time) && -+ !meta_prefs_get_new_windows_always_on_top ()) - { - meta_topic (META_DEBUG_STACK, - "Ignoring xconfigure stacking request from %s (with " -diff --git a/src/org.gnome.metacity.gschema.xml.in b/src/org.gnome.metacity.gschema.xml.in -index d69d525..edc1b70 100644 ---- a/src/org.gnome.metacity.gschema.xml.in -+++ b/src/org.gnome.metacity.gschema.xml.in -@@ -66,6 +66,12 @@ - invariant in the 'click' focus mode that the topmost window always - has focus, so its most suitable for use with the 'mouse' and - 'sloppy' focus modes. -+ -+ This key also affects windows that try to activate or raise themselves -+ themselves but don't succeed in getting the the focus. Without -+ this key being set, such windows are flashed in the taskbar. With -+ this key set they, like entirely new windows, are raised but not -+ focused. - </_description> - </key> - </schema> --- -1.7.9 - diff --git a/Exclude-the-current-application-from-no_focus_window.patch b/Exclude-the-current-application-from-no_focus_window.patch deleted file mode 100644 index b2a4577..0000000 --- a/Exclude-the-current-application-from-no_focus_window.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 3a8164d5ddf688db9cb00657861351febf013e72 Mon Sep 17 00:00:00 2001 -From: "Owen W. Taylor" <otaylor@fishsoup.net> -Date: Wed, 23 Jun 2010 16:49:37 -0400 -Subject: [PATCH] Exclude the current application from no-focus-windows - setting - -The idea of the no-focus-windows setting is to allow identifying -legacy application windows that are stealing focus from other -applications and suppress that behavior. Sometimes its not possible to -identify specific problem windows of an application and its -necessary to blanket add all windows of the application. In this -case no-focus-windows can disrupt the internal flow of focus -within the application. - -On the assumption that apps internally handle focus correctly -and have been tested not to steal focus from themselves at -annoying times, we exclude windows of the the current application -from no-focus-windows. - -https://bugzilla.gnome.org/show_bug.cgi?id=599248 ---- - src/core/window.c | 11 ++++++++++- - src/org.gnome.metacity.gschema.xml.in | 3 +++ - 2 files changed, 13 insertions(+), 1 deletions(-) - -diff --git a/src/core/window.c b/src/core/window.c -index 5440160..6f5c280 100644 ---- a/src/core/window.c -+++ b/src/core/window.c -@@ -1980,12 +1980,21 @@ window_state_on_map (MetaWindow *window, - gboolean *places_on_top) - { - gboolean intervening_events; -+ MetaWindow *focus_window; - - /* A 'no focus' window is a window that has been configured in GConf - * to never take focus on map; typically it will be a notification - * window from a legacy app that doesn't support _NET_WM_USER_TIME. -+ * -+ * This doesn't apply to applications taking focus from themselves; -+ * the assumption is applications have been properly tested to internally -+ * handle focus properly. - */ -- if (meta_prefs_window_is_no_focus (window->title, window->res_class)) -+ focus_window = window->display->focus_window; -+ if (focus_window && -+ !meta_window_same_application (window, focus_window) && -+ !meta_window_same_client (window, focus_window) && -+ meta_prefs_window_is_no_focus (window->title, window->res_class)) - intervening_events = TRUE; - else - intervening_events = intervening_user_event_occurred (window); -diff --git a/src/org.gnome.metacity.gschema.xml.in b/src/org.gnome.metacity.gschema.xml.in -index 6900fa6..e4f86bd 100644 ---- a/src/org.gnome.metacity.gschema.xml.in -+++ b/src/org.gnome.metacity.gschema.xml.in -@@ -41,6 +41,9 @@ - WM_CLASS matches the shell-style glob pattern <glob>. - (and <expr> <expr>) (or <expr> <expr>) (not <expr): Boolean combinations - of expressions. -+ -+ New windows from the current active application are unaffected by -+ this setting. - </_description> - </key> - </schema> --- -1.7.9 - diff --git a/For-mouse-and-sloppy-focus-return-to-mouse-mode-on.patch b/For-mouse-and-sloppy-focus-return-to-mouse-mode-on.patch deleted file mode 100644 index 6fbd49e..0000000 --- a/For-mouse-and-sloppy-focus-return-to-mouse-mode-on.patch +++ /dev/null @@ -1,396 +0,0 @@ -From a24b336303c50e74f7d5e8582049dfae0d70329d Mon Sep 17 00:00:00 2001 -From: "Owen W. Taylor" <otaylor@fishsoup.net> -Date: Tue, 20 Oct 2009 15:13:45 -0400 -Subject: [PATCH] For mouse and sloppy focus, return to "mouse mode" on - motion - -For mouse and sloppy focus, there are various cases where the focus -window can be moved away from the focus window. Mostly these relate -to "display->mouse_mode = FALSE", which we enter when the user -starts keynav'ing, but it can also occur if a window is focus-denied -mapped and mapped under the pointer. - -Prior to this patch, there was no fast way for the user to start -interacting with the window - if they just clicked on the window, -the click would be passed through, and could disturb the windows -contents, so the user had to either mouse out and then mouse back -in, or go up and click on the titlebar. - -With this patch, when we get into this state, we add a timeout -and poll for pointer motion with XQueryPointer. If the user then -moves the pointer (more than a single pixel to handle jitter), -we focus the window under the pointer and return to mouse mode. - -https://bugzilla.gnome.org/show_bug.cgi?id=599097 ---- - src/core/display-private.h | 11 ++ - src/core/display.c | 239 +++++++++++++++++++++++++++++++++++-------- - src/core/keybindings.c | 10 +- - 3 files changed, 210 insertions(+), 50 deletions(-) - -diff --git a/src/core/display-private.h b/src/core/display-private.h -index feee851..fee321c 100644 ---- a/src/core/display-private.h -+++ b/src/core/display-private.h -@@ -150,6 +150,14 @@ struct _MetaDisplay - guint autoraise_timeout_id; - MetaWindow* autoraise_window; - -+ /* When we ignore an enter due to !display->mouse_mode, a timeout -+ * to check if the mouse is moved, in which case we should focus -+ * the pointer window and return to mouse mode */ -+ guint focus_on_motion_timeout_id; -+ Window focus_on_motion_start_root_window; -+ int focus_on_motion_start_x; -+ int focus_on_motion_start_y; -+ - /* Alt+click button grabs */ - unsigned int window_grab_modifiers; - -@@ -501,4 +509,7 @@ void meta_display_remove_autoraise_callback (MetaDisplay *display); - /* In above-tab-keycode.c */ - guint meta_display_get_above_tab_keycode (MetaDisplay *display); - -+void meta_display_disable_mouse_mode (MetaDisplay *display); -+void meta_display_enable_mouse_mode (MetaDisplay *display); -+ - #endif -diff --git a/src/core/display.c b/src/core/display.c -index 2e959b6..5bcf025 100644 ---- a/src/core/display.c -+++ b/src/core/display.c -@@ -165,6 +165,9 @@ static void sanity_check_timestamps (MetaDisplay *display, - - MetaGroup* get_focussed_group (MetaDisplay *display); - -+static void start_focus_on_motion (MetaDisplay *display); -+static void stop_focus_on_motion (MetaDisplay *display); -+ - /** - * Destructor for MetaPingData structs. Will destroy the - * event source for the struct as well. -@@ -876,6 +879,7 @@ meta_display_close (MetaDisplay *display, - meta_prefs_remove_listener (prefs_changed_callback, display); - - meta_display_remove_autoraise_callback (display); -+ stop_focus_on_motion (display); - - if (display->grab_old_window_stacking) - g_list_free (display->grab_old_window_stacking); -@@ -1778,67 +1782,86 @@ event_callback (XEvent *event, - if (window && !serial_is_ignored (display, event->xany.serial) && - event->xcrossing.mode != NotifyGrab && - event->xcrossing.mode != NotifyUngrab && -- event->xcrossing.detail != NotifyInferior && -- meta_display_focus_sentinel_clear (display)) -+ event->xcrossing.detail != NotifyInferior) - { - switch (meta_prefs_get_focus_mode ()) - { - case G_DESKTOP_FOCUS_MODE_SLOPPY: - case G_DESKTOP_FOCUS_MODE_MOUSE: -- display->mouse_mode = TRUE; -- if (window->type != META_WINDOW_DOCK && -- window->type != META_WINDOW_DESKTOP) -+ if (!meta_display_focus_sentinel_clear (display)) - { -- meta_topic (META_DEBUG_FOCUS, -- "Focusing %s due to enter notify with serial %lu " -- "at time %lu, and setting display->mouse_mode to " -- "TRUE.\n", -- window->desc, -- event->xany.serial, -- event->xcrossing.time); -- -- meta_window_focus (window, event->xcrossing.time); -- -- /* stop ignoring stuff */ -- reset_ignores (display); -- -- if (meta_prefs_get_auto_raise ()) -+ /* There was an enter event that we want to ignore because -+ * we're in "keynav mode" or because we are mapping -+ * a focus-denied window; the next time the mouse is moved -+ * we want to focus the window so the user doesn't have -+ * to click (possibly messing up window contents) or -+ * enter/leave to get focus to the window. -+ * -+ * (This check will also trigger for visual bell flashes -+ * but it doesn't really do any harm to check for motion -+ * in that case, since the next motion will just result in -+ * the current window being focused.) -+ */ -+ start_focus_on_motion (display); -+ } -+ else -+ { -+ meta_display_enable_mouse_mode (display); -+ if (window->type != META_WINDOW_DOCK && -+ window->type != META_WINDOW_DESKTOP) - { -- meta_display_queue_autoraise_callback (display, window); -+ meta_topic (META_DEBUG_FOCUS, -+ "Focusing %s due to enter notify with serial %lu " -+ "at time %lu, and setting display->mouse_mode to " -+ "TRUE.\n", -+ window->desc, -+ event->xany.serial, -+ event->xcrossing.time); -+ -+ meta_window_focus (window, event->xcrossing.time); -+ -+ /* stop ignoring stuff */ -+ reset_ignores (display); -+ -+ if (meta_prefs_get_auto_raise ()) -+ { -+ meta_display_queue_autoraise_callback (display, window); -+ } -+ else -+ { -+ meta_topic (META_DEBUG_FOCUS, -+ "Auto raise is disabled\n"); -+ } - } -- else -+ /* In mouse focus mode, we defocus when the mouse *enters* -+ * the DESKTOP window, instead of defocusing on LeaveNotify. -+ * This is because having the mouse enter override-redirect -+ * child windows unfortunately causes LeaveNotify events that -+ * we can't distinguish from the mouse actually leaving the -+ * toplevel window as we expect. But, since we filter out -+ * EnterNotify events on override-redirect windows, this -+ * alternative mechanism works great. -+ */ -+ if (window->type == META_WINDOW_DESKTOP && -+ meta_prefs_get_focus_mode() == G_DESKTOP_FOCUS_MODE_MOUSE && -+ display->expected_focus_window != NULL) - { - meta_topic (META_DEBUG_FOCUS, -- "Auto raise is disabled\n"); -+ "Unsetting focus from %s due to mouse entering " -+ "the DESKTOP window\n", -+ display->expected_focus_window->desc); -+ meta_display_focus_the_no_focus_window (display, -+ window->screen, -+ event->xcrossing.time); - } - } -- /* In mouse focus mode, we defocus when the mouse *enters* -- * the DESKTOP window, instead of defocusing on LeaveNotify. -- * This is because having the mouse enter override-redirect -- * child windows unfortunately causes LeaveNotify events that -- * we can't distinguish from the mouse actually leaving the -- * toplevel window as we expect. But, since we filter out -- * EnterNotify events on override-redirect windows, this -- * alternative mechanism works great. -- */ -- if (window->type == META_WINDOW_DESKTOP && -- meta_prefs_get_focus_mode() == G_DESKTOP_FOCUS_MODE_MOUSE && -- display->expected_focus_window != NULL) -- { -- meta_topic (META_DEBUG_FOCUS, -- "Unsetting focus from %s due to mouse entering " -- "the DESKTOP window\n", -- display->expected_focus_window->desc); -- meta_display_focus_the_no_focus_window (display, -- window->screen, -- event->xcrossing.time); -- } - break; - case G_DESKTOP_FOCUS_MODE_CLICK: - break; - } -- -- if (window->type == META_WINDOW_DOCK) -+ -+ if (window->type == META_WINDOW_DOCK && -+ meta_display_focus_sentinel_clear (display)) - meta_window_raise (window); - } - break; -@@ -5095,6 +5118,132 @@ meta_display_remove_autoraise_callback (MetaDisplay *display) - } - } - -+#define FOCUS_ON_MOTION_CHECK_INTERVAL 200 /* 0.2 seconds */ -+#define FOCUS_ON_MOTION_THRESHOLD 2 /* Must move 2 pixels */ -+ -+static gboolean -+check_focus_on_motion (gpointer data) -+{ -+ MetaDisplay *display = data; -+ Window root, child; -+ int root_x, root_y; -+ int window_x, window_y; -+ guint mask; -+ -+ XQueryPointer (display->xdisplay, -+ DefaultRootWindow (display->xdisplay), -+ &root, &child, -+ &root_x, &root_y, -+ &window_x, &window_y, -+ &mask); -+ -+ if (root != display->focus_on_motion_start_root_window || -+ MAX (ABS (root_x - display->focus_on_motion_start_x), -+ ABS (root_y - display->focus_on_motion_start_y)) >= FOCUS_ON_MOTION_THRESHOLD) -+ { -+ MetaScreen *screen; -+ -+ meta_topic (META_DEBUG_FOCUS, -+ "Returning to mouse mode on mouse motion\n"); -+ -+ meta_display_enable_mouse_mode (display); -+ -+ screen = meta_display_screen_for_root (display, root); -+ if (screen != NULL) -+ { -+ MetaWindow *window = meta_screen_get_mouse_window (screen, NULL); -+ guint32 timestamp = meta_display_get_current_time_roundtrip (display); -+ -+ if (window && -+ window->type != META_WINDOW_DOCK && -+ window->type != META_WINDOW_DESKTOP) -+ { -+ meta_topic (META_DEBUG_FOCUS, -+ "Focusing mouse window %s\n", window->desc); -+ -+ meta_window_focus (window, timestamp); -+ -+ if (display->autoraise_window != window && -+ meta_prefs_get_auto_raise ()) -+ { -+ meta_display_queue_autoraise_callback (display, window); -+ } -+ } -+ else if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_MOUSE) -+ { -+ meta_topic (META_DEBUG_FOCUS, -+ "Setting focus to no_focus_windowm, since no mouse window.\n"); -+ meta_display_focus_the_no_focus_window (display, screen, timestamp); -+ } -+ -+ /* for G_DESKTOP_FOCUS_MODE_SLOPPY, if the pointer isn't over a window, we just -+ * leave the last window focused */ -+ } -+ } -+ -+ return TRUE; -+} -+ -+static void -+start_focus_on_motion (MetaDisplay *display) -+{ -+ if (!display->focus_on_motion_timeout_id) -+ { -+ Window child; -+ guint mask; -+ int window_x, window_y; -+ -+ XQueryPointer (display->xdisplay, -+ DefaultRootWindow (display->xdisplay), -+ &display->focus_on_motion_start_root_window, -+ &child, -+ &display->focus_on_motion_start_x, -+ &display->focus_on_motion_start_y, -+ &window_x, &window_y, -+ &mask); -+ -+ display->focus_on_motion_timeout_id = -+ g_timeout_add (FOCUS_ON_MOTION_CHECK_INTERVAL, -+ check_focus_on_motion, -+ display); -+ } -+} -+ -+static void -+stop_focus_on_motion (MetaDisplay *display) -+{ -+ if (display->focus_on_motion_timeout_id) -+ { -+ g_source_remove (display->focus_on_motion_timeout_id); -+ display->focus_on_motion_timeout_id = 0; -+ } -+} -+ -+void -+meta_display_disable_mouse_mode (MetaDisplay *display) -+{ -+ display->mouse_mode = FALSE; -+ -+ /* mouse_mode disabled means that we are now allowing the -+ * mouse window to be different from the focus window; -+ * that discrepancy might not come until we ignore some -+ * enter event, but in a case like tabbing away from the -+ * mouse window, it occurs immediately, so we need to -+ * start checking for motion events to see if we should -+ * focus the mouse window and return to mouse mode. -+ */ -+ if (meta_prefs_get_focus_mode () != G_DESKTOP_FOCUS_MODE_CLICK) -+ start_focus_on_motion (display); -+} -+ -+void -+meta_display_enable_mouse_mode (MetaDisplay *display) -+{ -+ display->mouse_mode = TRUE; -+ -+ stop_focus_on_motion (display); -+} -+ - #ifdef HAVE_COMPOSITE_EXTENSIONS - void - meta_display_get_compositor_version (MetaDisplay *display, -diff --git a/src/core/keybindings.c b/src/core/keybindings.c -index 08d861e..3c0ef95 100644 ---- a/src/core/keybindings.c -+++ b/src/core/keybindings.c -@@ -2082,7 +2082,7 @@ process_tab_grab (MetaDisplay *display, - meta_topic (META_DEBUG_FOCUS, "Activating %s due to tab popup " - "selection and turning mouse_mode off\n", - target_window->desc); -- display->mouse_mode = FALSE; -+ meta_display_disable_mouse_mode (display); - meta_window_activate (target_window, event->xkey.time); - - meta_topic (META_DEBUG_KEYBINDINGS, -@@ -2686,7 +2686,7 @@ handle_panel (MetaDisplay *display, - meta_topic (META_DEBUG_KEYBINDINGS, - "Sending panel message with timestamp %lu, and turning mouse_mode " - "off due to keybinding press\n", event->xkey.time); -- display->mouse_mode = FALSE; -+ meta_display_disable_mouse_mode (display); - - meta_error_trap_push (display); - -@@ -2809,7 +2809,7 @@ do_choose_window (MetaDisplay *display, - "Activating %s and turning off mouse_mode due to " - "switch/cycle windows with no modifiers\n", - initial_selection->desc); -- display->mouse_mode = FALSE; -+ meta_display_disable_mouse_mode (display); - meta_window_activate (initial_selection, event->xkey.time); - } - else if (meta_display_begin_grab_op (display, -@@ -2838,7 +2838,7 @@ do_choose_window (MetaDisplay *display, - "modifier was released prior to grab\n", - initial_selection->desc); - meta_display_end_grab_op (display, event->xkey.time); -- display->mouse_mode = FALSE; -+ meta_display_disable_mouse_mode (display); - meta_window_activate (initial_selection, event->xkey.time); - } - else -@@ -3079,7 +3079,7 @@ handle_move_to_workspace (MetaDisplay *display, - meta_topic (META_DEBUG_FOCUS, - "Resetting mouse_mode to FALSE due to " - "handle_move_to_workspace() call with flip set.\n"); -- workspace->screen->display->mouse_mode = FALSE; -+ meta_display_disable_mouse_mode (display); - meta_workspace_activate_with_focus (workspace, - window, - event->xkey.time); --- -1.7.9 - diff --git a/Stop-confusing-GDK-s-grab-tracking.patch b/Stop-confusing-GDK-s-grab-tracking.patch deleted file mode 100644 index c289453..0000000 --- a/Stop-confusing-GDK-s-grab-tracking.patch +++ /dev/null @@ -1,200 +0,0 @@ -From ab0428a82f8233829c36e2a3ac0ed0848571c59d Mon Sep 17 00:00:00 2001 -From: "Owen W. Taylor" <otaylor@fishsoup.net> -Date: Wed, 9 Jun 2010 19:38:35 -0400 -Subject: [PATCH] Stop confusing GDK's grab tracking - -With client side windows, mixing GDK event delivery with explicit calls -to XUngrabPointer() can result in GDK losing button release events -it expects to get. This means that GDK thinks there is an implicit -grab in effect when there is none and send events to the wrong window. - -Avoid this by bypassing GDK's event handling for most mouse events. -We do a simplified conversion of the X event into a GdkEvent and send -it to directly to libgtk for delivery. - -We make an exception when a GDK grab is already in effect - this is -needed for the correct operation of menus. - -http://bugzilla.gnome.org/show_bug.cgi?id=599181 ---- - src/core/display-private.h | 7 ++ - src/core/display.c | 131 ++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 138 insertions(+), 0 deletions(-) - -diff --git a/src/core/display-private.h b/src/core/display-private.h -index fee321c..7f779fd 100644 ---- a/src/core/display-private.h -+++ b/src/core/display-private.h -@@ -232,6 +232,13 @@ struct _MetaDisplay - /* Closing down the display */ - int closing; - -+ /* To detect double clicks */ -+ guint button_click_number; -+ Window button_click_window; -+ int button_click_x; -+ int button_click_y; -+ guint32 button_click_time; -+ - /* Managed by group.c */ - GHashTable *groups_by_leader; - -diff --git a/src/core/display.c b/src/core/display.c -index 5bcf025..0c5f61d 100644 ---- a/src/core/display.c -+++ b/src/core/display.c -@@ -77,6 +77,7 @@ - #include <X11/extensions/Xfixes.h> - #endif - #include <string.h> -+#include <gtk/gtk.h> - - #define GRAB_OP_IS_WINDOW_SWITCH(g) \ - (g == META_GRAB_OP_KEYBOARD_TABBING_NORMAL || \ -@@ -1362,6 +1363,133 @@ meta_display_queue_autoraise_callback (MetaDisplay *display, - display->autoraise_window = window; - } - -+/* We do some of our event handling in core/frames.c, which expects -+ * GDK events delivered by GTK+. However, since the transition to -+ * client side windows, we can't let GDK see button events, since the -+ * client-side tracking of implicit and explicit grabs it does will -+ * get confused by our direct use of X grabs. -+ * -+ * So we do a very minimal GDK => GTK event conversion here and send on the -+ * events we care about, and then filter them out so they don't go -+ * through the normal GDK event handling. -+ * -+ * To reduce the amount of code, the only events fields filled out -+ * below are the ones that frames.c uses. If frames.c is modified to -+ * use more fields, more fields need to be filled out below. -+ */ -+ -+static gboolean -+maybe_send_event_to_gtk (MetaDisplay *display, -+ XEvent *xevent) -+{ -+ /* We're always using the default display */ -+ GdkDisplay *gdk_display = gdk_display_get_default (); -+ GdkEvent gdk_event; -+ GdkWindow *gdk_window; -+ Window window; -+ -+ switch (xevent->type) -+ { -+ case ButtonPress: -+ case ButtonRelease: -+ window = xevent->xbutton.window; -+ break; -+ case MotionNotify: -+ window = xevent->xmotion.window; -+ break; -+ case EnterNotify: -+ case LeaveNotify: -+ window = xevent->xcrossing.window; -+ break; -+ default: -+ return FALSE; -+ } -+ -+ gdk_window = gdk_window_lookup_for_display (gdk_display, window); -+ if (gdk_window == NULL) -+ return FALSE; -+ -+ /* If GDK already things it has a grab, we better let it see events; this -+ * is the menu-navigation case and events need to get sent to the appropriate -+ * (client-side) subwindow for individual menu items. -+ */ -+ if (gdk_display_pointer_is_grabbed (gdk_display)) -+ return FALSE; -+ -+ memset (&gdk_event, 0, sizeof (gdk_event)); -+ -+ switch (xevent->type) -+ { -+ case ButtonPress: -+ case ButtonRelease: -+ if (xevent->type == ButtonPress) -+ { -+ GtkSettings *settings = gtk_settings_get_default (); -+ int double_click_time; -+ int double_click_distance; -+ -+ g_object_get (settings, -+ "gtk-double-click-time", &double_click_time, -+ "gtk-double-click-distance", &double_click_distance, -+ NULL); -+ -+ if (xevent->xbutton.button == display->button_click_number && -+ xevent->xbutton.window == display->button_click_window && -+ xevent->xbutton.time < display->button_click_time + double_click_time && -+ ABS (xevent->xbutton.x - display->button_click_x) <= double_click_distance && -+ ABS (xevent->xbutton.y - display->button_click_y) <= double_click_distance) -+ { -+ gdk_event.button.type = GDK_2BUTTON_PRESS; -+ -+ display->button_click_number = 0; -+ } -+ else -+ { -+ gdk_event.button.type = GDK_BUTTON_PRESS; -+ display->button_click_number = xevent->xbutton.button; -+ display->button_click_window = xevent->xbutton.window; -+ display->button_click_time = xevent->xbutton.time; -+ display->button_click_x = xevent->xbutton.x; -+ display->button_click_y = xevent->xbutton.y; -+ } -+ } -+ else -+ { -+ gdk_event.button.type = GDK_BUTTON_RELEASE; -+ } -+ -+ gdk_event.button.window = gdk_window; -+ gdk_event.button.button = xevent->xbutton.button; -+ gdk_event.button.time = xevent->xbutton.time; -+ gdk_event.button.x = xevent->xbutton.x; -+ gdk_event.button.y = xevent->xbutton.y; -+ gdk_event.button.x_root = xevent->xbutton.x_root; -+ gdk_event.button.y_root = xevent->xbutton.y_root; -+ -+ break; -+ case MotionNotify: -+ gdk_event.motion.type = GDK_MOTION_NOTIFY; -+ gdk_event.motion.window = gdk_window; -+ break; -+ case EnterNotify: -+ case LeaveNotify: -+ gdk_event.crossing.type = xevent->type == EnterNotify ? GDK_ENTER_NOTIFY : GDK_LEAVE_NOTIFY; -+ gdk_event.crossing.window = gdk_window; -+ gdk_event.crossing.x = xevent->xcrossing.x; -+ gdk_event.crossing.y = xevent->xcrossing.y; -+ break; -+ default: -+ g_assert_not_reached (); -+ break; -+ } -+ -+ /* If we've gotten here, we've filled in the gdk_event and should send it on */ -+ -+ gtk_main_do_event (&gdk_event); -+ -+ return TRUE; -+} -+ - /** - * This is the most important function in the whole program. It is the heart, - * it is the nexus, it is the Grand Central Station of Metacity's world. -@@ -2387,6 +2515,9 @@ event_callback (XEvent *event, - event, - window); - } -+ -+ if (maybe_send_event_to_gtk (display, event)) -+ filter_out_event = TRUE; - - display->current_time = CurrentTime; - return filter_out_event; --- -1.7.9 - diff --git a/dnd-keynav.patch b/dnd-keynav.patch deleted file mode 100644 index 32f86cf..0000000 --- a/dnd-keynav.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- metacity-2.27.0/src/core/display.c 2009-06-07 21:35:13.623787399 -0400 -+++ hacked/src/core/display.c 2009-06-06 00:20:58.889278832 -0400 -@@ -3307,7 +3307,7 @@ - meta_display_set_grab_op_cursor (display, screen, op, FALSE, grab_xwindow, - timestamp); - -- if (!display->grab_have_pointer) -+ if (!display->grab_have_pointer && !grab_op_is_keyboard (op)) - { - meta_topic (META_DEBUG_WINDOW_OPS, - "XGrabPointer() failed\n"); diff --git a/fresh-tooltips.patch b/fresh-tooltips.patch deleted file mode 100644 index aaa9ab7..0000000 --- a/fresh-tooltips.patch +++ /dev/null @@ -1,287 +0,0 @@ -diff -up metacity-2.30.2/src/ui/fixedtip.c.fresh-tooltips metacity-2.30.2/src/ui/fixedtip.c ---- metacity-2.30.2/src/ui/fixedtip.c.fresh-tooltips 2010-09-04 12:09:53.000000000 -0400 -+++ metacity-2.30.2/src/ui/fixedtip.c 2010-09-29 13:27:27.931194002 -0400 -@@ -50,23 +50,214 @@ static int screen_right_edge = 0; - */ - static int screen_bottom_edge = 0; - -+static void -+draw_round_rect (cairo_t *cr, -+ gdouble aspect, -+ gdouble x, -+ gdouble y, -+ gdouble corner_radius, -+ gdouble width, -+ gdouble height) -+{ -+ gdouble radius = corner_radius / aspect; -+ -+ cairo_move_to (cr, x + radius, y); -+ -+ /* top-right, left of the corner */ -+ cairo_line_to (cr, x + width - radius, y); -+ -+ /* top-right, below the corner */ -+ cairo_arc (cr, -+ x + width - radius, y + radius, radius, -+ -90.0f * G_PI / 180.0f, 0.0f * G_PI / 180.0f); -+ -+ /* bottom-right, above the corner */ -+ cairo_line_to (cr, x + width, y + height - radius); -+ -+ /* bottom-right, left of the corner */ -+ cairo_arc (cr, -+ x + width - radius, y + height - radius, radius, -+ 0.0f * G_PI / 180.0f, 90.0f * G_PI / 180.0f); -+ -+ /* bottom-left, right of the corner */ -+ cairo_line_to (cr, x + radius, y + height); -+ -+ /* bottom-left, above the corner */ -+ cairo_arc (cr, -+ x + radius, y + height - radius, radius, -+ 90.0f * G_PI / 180.0f, 180.0f * G_PI / 180.0f); -+ -+ /* top-left, below the corner */ -+ cairo_line_to (cr, x, y + radius); -+ -+ /* top-left, right of the corner */ -+ cairo_arc (cr, -+ x + radius, y + radius, radius, -+ 180.0f * G_PI / 180.0f, 270.0f * G_PI / 180.0f); -+ -+ cairo_close_path (cr); -+} -+ -+ -+static void -+fill_background (GtkWidget *widget, -+ cairo_t *cr) -+{ -+ GdkColor color; -+ gdouble r, g, b; -+ gint radius; -+ gdouble background_alpha; -+ -+ if (gdk_screen_is_composited (gtk_widget_get_screen (widget))) -+ background_alpha = 0.90; -+ else -+ background_alpha = 1.0; -+ -+ radius = MIN (widget->style->xthickness, widget->style->ythickness); -+ radius = MAX (radius, 1); -+ -+ cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); -+ cairo_paint (cr); -+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER); -+ -+ draw_round_rect (cr, -+ 1.0, 0.5, 0.5, radius, -+ widget->allocation.width - 1, -+ widget->allocation.height - 1); -+ -+ color = widget->style->bg [GTK_STATE_NORMAL]; -+ r = (float)color.red / 65535.0; -+ g = (float)color.green / 65535.0; -+ b = (float)color.blue / 65535.0; -+ cairo_set_source_rgba (cr, r, g, b, background_alpha); -+ cairo_fill_preserve (cr); -+ -+ color = widget->style->bg [GTK_STATE_SELECTED]; -+ r = (float) color.red / 65535.0; -+ g = (float) color.green / 65535.0; -+ b = (float) color.blue / 65535.0; -+ -+ cairo_set_source_rgba (cr, r, g, b, background_alpha); -+ cairo_set_line_width (cr, 1.0); -+ cairo_stroke (cr); -+} -+ -+static void -+update_shape (GtkWidget *window) -+{ -+ GdkBitmap *mask; -+ cairo_t *cr; -+ gint width, height; -+ gint radius; -+ gboolean new_style; -+ -+ gtk_widget_style_get (window, "new-tooltip-style", &new_style, NULL); -+ -+ if (!new_style) -+ { -+ gtk_widget_shape_combine_mask (window, NULL, 0, 0); -+ return; -+ } -+ -+ gtk_window_get_size (GTK_WINDOW (window), &width, &height); -+ -+ if (gdk_screen_is_composited (gtk_widget_get_screen (window))) -+ { -+ gtk_widget_shape_combine_mask (window, NULL, 0, 0); -+ return; -+ } -+ -+ radius = MIN (window->style->xthickness, window->style->ythickness); -+ radius = MAX (radius, 1); -+ -+ mask = (GdkBitmap *) gdk_pixmap_new (NULL, width, height, 1); -+ cr = gdk_cairo_create (mask); -+ if (cairo_status (cr) == CAIRO_STATUS_SUCCESS) -+ { -+ cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); -+ cairo_paint (cr); -+ -+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER); -+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); -+ draw_round_rect (cr, 1.0, 0, 0, radius + 1, width, height); -+ cairo_fill (cr); -+ -+ gtk_widget_shape_combine_mask (window, mask, 0, 0); -+ } -+ cairo_destroy (cr); -+ -+ g_object_unref (mask); -+} -+ - static gint --expose_handler (GtkTooltip *tooltips) -+expose_handler (GtkWidget *window) - { -- gtk_paint_flat_box (gtk_widget_get_style (tip), gtk_widget_get_window (tip), -- GTK_STATE_NORMAL, GTK_SHADOW_OUT, -- NULL, tip, "tooltip", -- 0, 0, -1, -1); -+ cairo_t *context; -+ cairo_surface_t *surface; -+ cairo_t *cr; -+ gboolean new_style; -+ -+ gtk_widget_style_get (window, "new-tooltip-style", &new_style, NULL); -+ -+ if (new_style) -+ { -+ context = gdk_cairo_create (window->window); -+ -+ cairo_set_operator (context, CAIRO_OPERATOR_SOURCE); -+ surface = cairo_surface_create_similar (cairo_get_target (context), -+ CAIRO_CONTENT_COLOR_ALPHA, -+ window->allocation.width, -+ window->allocation.height); -+ cr = cairo_create (surface); -+ -+ fill_background (window, cr); -+ -+ cairo_destroy (cr); -+ cairo_set_source_surface (context, surface, 0, 0); -+ cairo_paint (context); -+ cairo_surface_destroy (surface); -+ cairo_destroy (context); -+ -+ update_shape (window); -+ } -+ else -+ { -+ gtk_paint_flat_box (window->style, -+ window->window, -+ GTK_STATE_NORMAL, -+ GTK_SHADOW_OUT, -+ NULL, -+ window, -+ "tooltip", -+ 0, 0, -+ window->allocation.width, -+ window->allocation.height); -+ } - - return FALSE; - } - -+static void -+on_style_set (GtkWidget *widget, GtkStyle *prev) -+{ -+ GtkWidget *alignment; -+ -+ alignment = gtk_bin_get_child (GTK_BIN (widget)); -+ gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), -+ widget->style->ythickness, -+ widget->style->ythickness, -+ widget->style->xthickness, -+ widget->style->xthickness); -+ gtk_widget_queue_draw (widget); -+} -+ - void - meta_fixed_tip_show (Display *xdisplay, int screen_number, - int root_x, int root_y, - const char *markup_text) - { - int w, h; -+ GtkWidget *alignment; - - if (tip == NULL) - { -@@ -77,6 +268,7 @@ meta_fixed_tip_show (Display *xdisplay, - GdkScreen *gdk_screen; - GdkRectangle monitor; - gint mon_num; -+ GdkColormap *rgba; - - gdk_screen = gdk_display_get_screen (gdk_display_get_default (), - screen_number); -@@ -86,25 +278,47 @@ meta_fixed_tip_show (Display *xdisplay, - gdk_screen_get_monitor_geometry (gdk_screen, mon_num, &monitor); - screen_right_edge = monitor.x + monitor.width; - screen_bottom_edge = monitor.y + monitor.height; -+ -+ rgba = gdk_screen_get_rgba_colormap (gdk_screen); -+ if (rgba) -+ gtk_widget_set_colormap (tip, rgba); -+ -+#if 0 -+ g_signal_connect (tip, "composited-changed", -+ G_CALLBACK (on_composited_changed), NULL); -+ g_signal_connect (tip, "realize", -+ G_CALLBACK (on_realized), NULL); -+#endif - } -- -+ - gtk_widget_set_app_paintable (tip, TRUE); - gtk_window_set_resizable (GTK_WINDOW (tip), FALSE); -- gtk_widget_set_name (tip, "gtk-tooltips"); -- gtk_container_set_border_width (GTK_CONTAINER (tip), 4); -+ gtk_widget_set_name (tip, "gtk-tooltip"); -+ gtk_widget_realize (tip); - -- g_signal_connect_swapped (tip, "expose_event", -- G_CALLBACK (expose_handler), NULL); -+ g_signal_connect (tip, "expose_event", -+ G_CALLBACK (expose_handler), NULL); -+ -+ alignment = gtk_alignment_new (0.5, 0.5, 1.0, 1.0); -+ gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), -+ tip->style->ythickness, -+ tip->style->ythickness, -+ tip->style->xthickness, -+ tip->style->xthickness); -+ gtk_widget_show (alignment); -+ gtk_container_add (GTK_CONTAINER (tip), alignment); - - label = gtk_label_new (NULL); - gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); -- gtk_misc_set_alignment (GTK_MISC (label), 0.5, 0.5); - gtk_widget_show (label); -- -- gtk_container_add (GTK_CONTAINER (tip), label); -+ -+ gtk_container_add (GTK_CONTAINER (alignment), label); - - g_signal_connect (tip, "destroy", - G_CALLBACK (gtk_widget_destroyed), &tip); -+ -+ g_signal_connect (tip, "style-set", -+ G_CALLBACK (on_style_set), NULL); - } - - gtk_label_set_markup (GTK_LABEL (label), markup_text); diff --git a/metacity-2.28-xioerror-unknown-display.patch b/metacity-2.28-xioerror-unknown-display.patch deleted file mode 100644 index 5de5f8d..0000000 --- a/metacity-2.28-xioerror-unknown-display.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 04f775d77d53bca92faee883258d787b89255ef8 Mon Sep 17 00:00:00 2001 -From: "Owen W. Taylor" <otaylor@fishsoup.net> -Date: Fri, 20 Nov 2009 10:42:07 -0500 -Subject: [PATCH] Handle XError and XIOError for unknown displays - -The atk-bridge GTK+ module opens its own display; if we get an -XIOError on that display, we shouldn't abort with a meta_bug() -but just exit normally. Also fix a segfault if we got an XError -for that display. ---- - src/core/errors.c | 13 +++++-------- - 1 files changed, 5 insertions(+), 8 deletions(-) - -diff --git a/src/core/errors.c b/src/core/errors.c -index 8de4608..59f9c71 100644 ---- a/src/core/errors.c -+++ b/src/core/errors.c -@@ -222,10 +222,10 @@ x_error_handler (Display *xdisplay, - - display = meta_display_for_x_display (xdisplay); - -- /* Display can be NULL here because the compositing manager -- * has its own Display, but Xlib only has one global error handler -+ /* Display can be NULL here Xlib only has one global error handler; and -+ * there might be other displays open in the process. - */ -- if (display->error_traps > 0) -+ if (display && display->error_traps > 0) - { - /* we're in an error trap, chain to the trap handler - * saved from GDK -@@ -264,21 +264,18 @@ x_io_error_handler (Display *xdisplay) - - display = meta_display_for_x_display (xdisplay); - -- if (display == NULL) -- meta_bug ("IO error received for unknown display?\n"); -- - if (errno == EPIPE) - { - meta_warning (_("Lost connection to the display '%s';\n" - "most likely the X server was shut down or you killed/destroyed\n" - "the window manager.\n"), -- display->name); -+ display ? display->name : DisplayString (xdisplay)); - } - else - { - meta_warning (_("Fatal IO error %d (%s) on display '%s'.\n"), - errno, g_strerror (errno), -- display->name); -+ display ? display->name : DisplayString (xdisplay)); - } - - /* Xlib would force an exit anyhow */ --- -1.7.9 - diff --git a/metacity.spec b/metacity.spec index 497c9af..a6d421f 100644 --- a/metacity.spec +++ b/metacity.spec @@ -1,37 +1,16 @@ Summary: Unobtrusive window manager Name: metacity -Version: 2.34.13 -Release: 7%{?dist} +Version: 3.12.0 +Release: 1%{?dist} URL: http://download.gnome.org/sources/metacity/ -Source0: http://download.gnome.org/sources/metacity/2.34/metacity-%{version}.tar.xz +Source0: http://download.gnome.org/sources/metacity/3.12/metacity-%{version}.tar.xz # http://bugzilla.gnome.org/show_bug.cgi?id=558723 Patch4: stop-spamming-xsession-errors.patch -# http://bugzilla.gnome.org/show_bug.cgi?id=135056 -Patch5: dnd-keynav.patch - -# fedora specific patches -Patch12: fresh-tooltips.patch # https://bugzilla.gnome.org/show_bug.cgi?id=598995 Patch16: Dont-focus-ancestor-window-on-a-different-workspac.patch -# https://bugzilla.gnome.org/show_bug.cgi?id=599097 -Patch18: For-mouse-and-sloppy-focus-return-to-mouse-mode-on.patch -# https://bugzilla.gnome.org/show_bug.cgi?id=599248 -Patch19: Add-nofocuswindows-preference-to-list-windows-that.patch -Patch119: Exclude-the-current-application-from-no_focus_window.patch -# https://bugzilla.gnome.org/show_bug.cgi?id=599261 -Patch20: Add-a-newwindowsalwaysontop-preference.patch -Patch120: Apply-new_windows_always_on_top-to-newly-raised-acti.patch # https://bugzilla.gnome.org/show_bug.cgi?id=559816 Patch24: metacity-2.28-empty-keybindings.patch -# https://bugzilla.gnome.org/show_bug.cgi?id=604319 -Patch25: metacity-2.28-xioerror-unknown-display.patch -# https://bugzilla.gnome.org/show_bug.cgi?id=599181 -Patch28: Stop-confusing-GDK-s-grab-tracking.patch -# https://bugzilla.gnome.org/show_bug.cgi?id=622517 -Patch29: Allow-breaking-out-from-maximization-during-mouse.patch - -Patch40: 0001-doc-Update-man-pages.patch License: GPLv2+ Group: User Interface/Desktops @@ -86,20 +65,9 @@ API. This package exists purely for technical reasons. %prep %setup -q %patch4 -p1 -b .stop-spamming-xsession-errors -%patch5 -p1 -b .dnd-keynav -%patch12 -p1 -b .fresh-tooltips %patch16 -p1 -b .focus-different-workspace -%patch18 -p1 -b .focus-on-motion -%patch19 -p1 -b .no-focus-windows -%patch119 -p1 -b .no-focus-windows-current-app -%patch20 -p1 -b .always-on-top -%patch120 -p1 -b .always-on-top-activate %patch24 -p1 -b .empty-keybindings -%patch25 -p1 -b .xioerror-unknown-display -%patch28 -p1 -b .grab-tracking -%patch29 -p1 -b .mouse-unmaximize -%patch40 -p1 -b .man-page # force regeneration rm -f src/org.gnome.metacity.gschema.valid @@ -177,6 +145,9 @@ fi %{_mandir}/man1/metacity-window-demo.1.gz %changelog +* Wed Jun 18 2014 Richard Hughes <rhughes@redhat.com> - 3.12.0-1 +- Update to 3.12.0 + * Sat Jun 07 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.34.13-7 - Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild @@ -1 +1 @@ -6d89b71672d4fa49fc87f83d610d0ef6 metacity-2.34.13.tar.xz +30637f6e564ef66db9bbc31fce99652c metacity-3.12.0.tar.xz |