summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Hughes <richard@hughsie.com>2014-06-18 14:17:15 +0100
committerRichard Hughes <richard@hughsie.com>2014-06-18 14:17:15 +0100
commitd77e3e4f571e2a3bce10e3cfc9859a2157848d9c (patch)
tree1c06117cb6820be92fda7c6dae1977572b378a54
parentf4d0e3cec2f61f00b168bf60a173c36890795710 (diff)
downloadmetacity-d77e3e4f571e2a3bce10e3cfc9859a2157848d9c.zip
metacity-d77e3e4f571e2a3bce10e3cfc9859a2157848d9c.tar.gz
metacity-d77e3e4f571e2a3bce10e3cfc9859a2157848d9c.tar.xz
Update to 3.12.0
-rw-r--r--.gitignore1
-rw-r--r--0001-doc-Update-man-pages.patch94
-rw-r--r--Add-a-newwindowsalwaysontop-preference.patch160
-rw-r--r--Add-nofocuswindows-preference-to-list-windows-that.patch881
-rw-r--r--Allow-breaking-out-from-maximization-during-mouse.patch414
-rw-r--r--Apply-new_windows_always_on_top-to-newly-raised-acti.patch113
-rw-r--r--Exclude-the-current-application-from-no_focus_window.patch69
-rw-r--r--For-mouse-and-sloppy-focus-return-to-mouse-mode-on.patch396
-rw-r--r--Stop-confusing-GDK-s-grab-tracking.patch200
-rw-r--r--dnd-keynav.patch11
-rw-r--r--fresh-tooltips.patch287
-rw-r--r--metacity-2.28-xioerror-unknown-display.patch58
-rw-r--r--metacity.spec41
-rw-r--r--sources2
14 files changed, 8 insertions, 2719 deletions
diff --git a/.gitignore b/.gitignore
index d06716c..053bba9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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] "&lt;value&gt;"): window name (title) or the class from
-+ WM_CLASS matches &lt;value&gt; exactly.
-+ (glob [name|class] "&lt;glob&gt;"): window name (title) or the class from
-+ WM_CLASS matches the shell-style glob pattern &lt;glob&gt;.
-+ (and &lt;expr&gt; &lt;expr&gt;) (or &lt;expr&gt; &lt;expr&gt;) (not &lt;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 &lt;glob&gt;.
- (and &lt;expr&gt; &lt;expr&gt;) (or &lt;expr&gt; &lt;expr&gt;) (not &lt;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
diff --git a/sources b/sources
index 0cf2837..d063212 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-6d89b71672d4fa49fc87f83d610d0ef6 metacity-2.34.13.tar.xz
+30637f6e564ef66db9bbc31fce99652c metacity-3.12.0.tar.xz