diff --git a/.gitignore b/.gitignore index 2c1fc4c..5227944 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/mutter-3.8.4.tar.xz +SOURCES/mutter-3.14.4.tar.xz diff --git a/.mutter.metadata b/.mutter.metadata index 8840c74..096c226 100644 --- a/.mutter.metadata +++ b/.mutter.metadata @@ -1 +1 @@ -16d1caf5361c1e18407ea973b6635d1df4cab24c SOURCES/mutter-3.8.4.tar.xz +6f3e63e600fae7f662a55d68dcda1ed0653e4d03 SOURCES/mutter-3.14.4.tar.xz diff --git a/SOURCES/0001-Add-a-framework-for-restarting-the-compositor-with-n.patch b/SOURCES/0001-Add-a-framework-for-restarting-the-compositor-with-n.patch deleted file mode 100644 index 7291174..0000000 --- a/SOURCES/0001-Add-a-framework-for-restarting-the-compositor-with-n.patch +++ /dev/null @@ -1,559 +0,0 @@ -From 6710b03d1ebafc15ee4e826a5281204c6441c083 Mon Sep 17 00:00:00 2001 -From: "Owen W. Taylor" -Date: Thu, 8 May 2014 18:35:49 -0400 -Subject: [PATCH 1/4] Add a framework for restarting the compositor with nice - visuals - -The current GNOME Shell Alt-F2 restart looks very messy and also -provides no indication to the user what is going on. We need to -restart the compositor to switch in and out of stereo mode, so -add a framework for doing this more cleanly: - -Additions: - - meta_restart(): restarts the compositor with a message - MetaDisplay::show-restart-message: signal the embedding - shell to show a message - MetaDisplay::restart: signal the embedding shell to restart - itself. - meta_is_restart(): indicates whether the current instance is a - restart so we can suppress login animations. - -A helper program meta-restart-helper holds the composite overlay -window up during the restart to avoid visual artifacts. - -https://bugzilla.gnome.org/show_bug.cgi?id=733026 ---- - configure.ac | 1 + - src/Makefile.am | 5 ++ - src/compositor/compositor.c | 5 ++ - src/core/display-private.h | 7 ++ - src/core/display.c | 80 +++++++++++++++++ - src/core/main.c | 3 + - src/core/restart-helper.c | 82 +++++++++++++++++ - src/core/restart.c | 212 ++++++++++++++++++++++++++++++++++++++++++++ - src/meta/main.h | 3 + - 9 files changed, 398 insertions(+) - create mode 100644 src/core/restart-helper.c - create mode 100644 src/core/restart.c - -diff --git a/configure.ac b/configure.ac -index 6e9ca8c..dcd8a54 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -69,6 +69,7 @@ CLUTTER_PACKAGE=clutter-1.0 - MUTTER_PC_MODULES=" - gtk+-3.0 >= 3.3.7 - gio-2.0 >= 2.25.10 -+ gio-unix-2.0 >= 2.25.10 - pango >= 1.2.0 - cairo >= 1.10.0 - gsettings-desktop-schemas >= 3.7.3 -diff --git a/src/Makefile.am b/src/Makefile.am -index e2cec91..d664b54 100644 ---- a/src/Makefile.am -+++ b/src/Makefile.am -@@ -119,6 +119,7 @@ libmutter_la_SOURCES = \ - core/screen-private.h \ - meta/screen.h \ - meta/types.h \ -+ core/restart.c \ - core/session.c \ - core/session.h \ - core/stack.c \ -@@ -213,6 +214,10 @@ bin_PROGRAMS=mutter mutter-theme-viewer - mutter_SOURCES = core/mutter.c - mutter_LDADD = $(MUTTER_LIBS) libmutter.la - -+libexec_PROGRAMS = mutter-restart-helper -+mutter_restart_helper_SOURCES = core/restart-helper.c -+mutter_restart_helper_LDADD = $(MUTTER_LIBS) -+ - if HAVE_INTROSPECTION - include $(INTROSPECTION_MAKEFILE) - -diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c -index 91b477f..539a7a6 100644 ---- a/src/compositor/compositor.c -+++ b/src/compositor/compositor.c -@@ -86,6 +86,7 @@ - #include "meta-window-group.h" - #include "window-private.h" /* to check window->hidden */ - #include "display-private.h" /* for meta_display_lookup_x_window() */ -+#include "util-private.h" - #include - #include - -@@ -216,6 +217,10 @@ get_output_window (MetaScreen *screen) - xroot = meta_screen_get_xroot (screen); - output = XCompositeGetOverlayWindow (xdisplay, xroot); - -+ /* Now that we've gotten taken a reference count on the COW, we -+ * can close the helper that is holding on to it */ -+ meta_restart_finish (); -+ - meta_core_add_old_event_mask (xdisplay, output, &mask); - - XISetMask (mask.mask, XI_KeyPress); -diff --git a/src/core/display-private.h b/src/core/display-private.h -index 3423fb1..d227492 100644 ---- a/src/core/display-private.h -+++ b/src/core/display-private.h -@@ -470,4 +470,11 @@ gboolean meta_display_process_barrier_event (MetaDisplay *display, - XIBarrierEvent *event); - #endif /* HAVE_XI23 */ - -+gboolean meta_display_show_restart_message (MetaDisplay *display, -+ const char *message); -+gboolean meta_display_request_restart (MetaDisplay *display); -+ -+void meta_restart_init (void); -+void meta_restart_finish (void); -+ - #endif -diff --git a/src/core/display.c b/src/core/display.c -index d611314..9ed0f6e 100644 ---- a/src/core/display.c -+++ b/src/core/display.c -@@ -146,6 +146,8 @@ enum - WINDOW_MARKED_URGENT, - GRAB_OP_BEGIN, - GRAB_OP_END, -+ SHOW_RESTART_MESSAGE, -+ RESTART, - LAST_SIGNAL - }; - -@@ -322,6 +324,59 @@ meta_display_class_init (MetaDisplayClass *klass) - META_TYPE_WINDOW, - META_TYPE_GRAB_OP); - -+ /** -+ * MetaDisplay::show-restart-message: -+ * @display: the #MetaDisplay instance -+ * @message: (allow-none): The message to display, or %NULL -+ * to clear a previous restart message. -+ * -+ * The ::show-restart-message signal will be emitted to indicate -+ * that the compositor should show a message during restart. This is -+ * emitted when meta_restart() is called, either by Mutter -+ * internally or by the embedding compositor. The message should be -+ * immediately added to the Clutter stage in its final form - -+ * ::restart will be emitted to exit the application and leave the -+ * stage contents frozen as soon as the the stage is painted again. -+ * -+ * On case of failure to restart, this signal will be emitted again -+ * with %NULL for @message. -+ * -+ * Returns: %TRUE means the message was added to the stage; %FALSE -+ * indicates that the compositor did not show the message. -+ */ -+ display_signals[SHOW_RESTART_MESSAGE] = -+ g_signal_new ("show-restart-message", -+ G_TYPE_FROM_CLASS (klass), -+ G_SIGNAL_RUN_LAST, -+ 0, -+ g_signal_accumulator_true_handled, -+ NULL, NULL, -+ G_TYPE_BOOLEAN, 1, -+ G_TYPE_STRING); -+ -+ /** -+ * MetaDisplay::restart: -+ * @display: the #MetaDisplay instance -+ * -+ * The ::restart signal is emitted to indicate that compositor -+ * should reexec the process. This is -+ * emitted when meta_restart() is called, either by Mutter -+ * internally or by the embedding compositor. See also -+ * ::show-restart-message. -+ * -+ * Returns: %FALSE to indicate that the compositor could not -+ * be restarted. When the compositor is restarted, the signal -+ * should not return. -+ */ -+ display_signals[RESTART] = -+ g_signal_new ("restart", -+ G_TYPE_FROM_CLASS (klass), -+ G_SIGNAL_RUN_LAST, -+ 0, -+ g_signal_accumulator_true_handled, -+ NULL, NULL, -+ G_TYPE_BOOLEAN, 0); -+ - g_object_class_install_property (object_class, - PROP_FOCUS_WINDOW, - g_param_spec_object ("focus-window", -@@ -5856,3 +5911,28 @@ meta_display_clear_mouse_mode (MetaDisplay *display) - { - display->mouse_mode = FALSE; - } -+ -+gboolean -+meta_display_show_restart_message (MetaDisplay *display, -+ const char *message) -+{ -+ gboolean result = FALSE; -+ -+ g_signal_emit (display, -+ display_signals[SHOW_RESTART_MESSAGE], 0, -+ message, &result); -+ -+ return result; -+} -+ -+gboolean -+meta_display_request_restart (MetaDisplay *display) -+{ -+ gboolean result = FALSE; -+ -+ g_signal_emit (display, -+ display_signals[RESTART], 0, -+ &result); -+ -+ return result; -+} -diff --git a/src/core/main.c b/src/core/main.c -index 4bec3d2..d5bde44 100644 ---- a/src/core/main.c -+++ b/src/core/main.c -@@ -53,6 +53,7 @@ - #include - #include "ui.h" - #include "session.h" -+#include "stereo.h" - #include - #include - -@@ -441,6 +442,8 @@ meta_init (void) - - meta_ui_init (); - -+ meta_restart_init (); -+ - /* - * Clutter can only be initialized after the UI. - */ -diff --git a/src/core/restart-helper.c b/src/core/restart-helper.c -new file mode 100644 -index 0000000..57a19fb ---- /dev/null -+++ b/src/core/restart-helper.c -@@ -0,0 +1,82 @@ -+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -+ -+/* -+ * SECTION:restart-helper -+ * @short_description: helper program during a restart -+ * -+ * To smoothly restart Mutter, we want to keep the composite -+ * overlay window enabled during the restart. This is done by -+ * spawning this program, which keeps a reference to the the composite -+ * overlay window until Mutter picks it back up. -+ */ -+ -+/* -+ * Copyright (C) 2014 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, see . -+ */ -+ -+#include -+#include -+#include -+#include -+ -+int -+main (int argc, -+ char **argv) -+{ -+ Display *display = XOpenDisplay (NULL); -+ Window selection_window; -+ XSetWindowAttributes xwa; -+ unsigned long mask = 0; -+ -+ xwa.override_redirect = True; -+ mask |= CWOverrideRedirect; -+ -+ -+ XCompositeGetOverlayWindow (display, DefaultRootWindow (display)); -+ -+ selection_window = XCreateWindow (display, -+ DefaultRootWindow (display), -+ -100, -100, 1, 1, 0, -+ 0, -+ InputOnly, -+ DefaultVisual (display, DefaultScreen (display)), -+ mask, &xwa); -+ -+ XSetSelectionOwner (display, -+ XInternAtom (display, "_MUTTER_RESTART_HELPER", False), -+ selection_window, -+ CurrentTime); -+ -+ /* Mutter looks for an (arbitrary) line printed to stdout to know that -+ * we have started and have a reference to the COW. XSync() so that -+ * everything is set on the X server before Mutter starts restarting. -+ */ -+ XSync (display, False); -+ -+ printf ("STARTED\n"); -+ fflush (stdout); -+ -+ while (True) -+ { -+ XEvent xev; -+ -+ XNextEvent (display, &xev); -+ /* Mutter restarted and unset the selection to indicate that -+ * it has a reference on the COW again */ -+ if (xev.xany.type == SelectionClear) -+ return 0; -+ } -+} -diff --git a/src/core/restart.c b/src/core/restart.c -new file mode 100644 -index 0000000..04ef7d5 ---- /dev/null -+++ b/src/core/restart.c -@@ -0,0 +1,212 @@ -+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -+ -+/* -+ * Copyright (C) 2014 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, see . -+ */ -+ -+/* -+ * SECTION:restart -+ * @short_description: Smoothly restart the compositor -+ * -+ * There are some cases where we need to restart Mutter in order -+ * to deal with changes in state - the particular case inspiring -+ * this is enabling or disabling stereo output. To make this -+ * fairly smooth for the user, we need to do two things: -+ * -+ * - Display a message to the user and make sure that it is -+ * actually painted before we exit. -+ * - Use a helper program so that the Composite Overlay Window -+ * isn't unmapped and mapped. -+ * -+ * This handles both of these. -+ */ -+ -+#include -+ -+#include -+#include -+ -+#include -+#include -+#include "ui.h" -+#include "display-private.h" -+ -+static gboolean restart_helper_started = FALSE; -+static gboolean restart_message_shown = FALSE; -+static gboolean is_restart = FALSE; -+ -+void -+meta_restart_init (void) -+{ -+ Display *xdisplay = meta_ui_get_display (); -+ Atom atom_restart_helper = XInternAtom (xdisplay, "_MUTTER_RESTART_HELPER", False); -+ Window restart_helper_window = NULL; -+ -+ restart_helper_window = XGetSelectionOwner (xdisplay, atom_restart_helper); -+ if (restart_helper_window) -+ is_restart = TRUE; -+} -+ -+static void -+restart_check_ready (void) -+{ -+ if (restart_helper_started && restart_message_shown) -+ meta_display_request_restart (meta_get_display ()); -+} -+ -+static void -+restart_helper_read_line_callback (GObject *source_object, -+ GAsyncResult *res, -+ gpointer user_data) -+{ -+ GError *error = NULL; -+ gsize length; -+ char *line = g_data_input_stream_read_line_finish_utf8 (G_DATA_INPUT_STREAM (source_object), -+ res, -+ &length, &error); -+ if (line == NULL) -+ { -+ meta_warning ("Failed to read output from restart helper%s%s\n", -+ error ? ": " : NULL, -+ error ? error->message : NULL); -+ } -+ else -+ g_free (line); /* We don't actually care what the restart helper outputs */ -+ -+ g_object_unref (source_object); -+ -+ restart_helper_started = TRUE; -+ restart_check_ready (); -+} -+ -+static gboolean -+restart_message_painted (gpointer data) -+{ -+ restart_message_shown = TRUE; -+ restart_check_ready (); -+ -+ return FALSE; -+} -+ -+/** -+ * meta_restart: -+ * @message: message to display to the user. -+ * -+ * Starts the process of restarting the compositor. Note that Mutter's -+ * involvement here is to make the restart visually smooth for the -+ * user - it cannot itself safely reexec a program that embeds libmuttter. -+ * So in order for this to work, the compositor must handle two -+ * signals - MetaDisplay::show-restart-message, to display the -+ * message passed here on the Clutter stage, and ::restart to actually -+ * reexec the compositor. -+ */ -+void -+meta_restart (const char *message) -+{ -+ MetaDisplay *display = meta_get_display(); -+ GInputStream *unix_stream; -+ GDataInputStream *data_stream; -+ GError *error = NULL; -+ int helper_out_fd; -+ -+ static const char * const helper_argv[] = { -+ MUTTER_LIBEXECDIR "/mutter-restart-helper", NULL -+ }; -+ -+ if (meta_display_show_restart_message (display, message)) -+ { -+ /* Wait until the stage was painted */ -+ clutter_threads_add_repaint_func_full (CLUTTER_REPAINT_FLAGS_POST_PAINT, -+ restart_message_painted, -+ NULL, NULL); -+ } -+ else -+ { -+ /* Can't show the message, show the message as soon as the -+ * restart helper starts -+ */ -+ restart_message_painted (NULL); -+ } -+ -+ /* We also need to wait for the restart helper to get its -+ * reference to the Composite Overlay Window. -+ */ -+ if (!g_spawn_async_with_pipes (NULL, /* working directory */ -+ (char **)helper_argv, -+ NULL, /* envp */ -+ 0, /* G_SPAWN_DEFAULT */ -+ NULL, NULL, /* child_setup */ -+ NULL, /* child_pid */ -+ NULL, /* standard_input */ -+ &helper_out_fd, -+ NULL, /* standard_error */ -+ &error)) -+ { -+ meta_warning ("Failed to start restart helper: %s\n", error->message); -+ goto error; -+ } -+ -+ unix_stream = g_unix_input_stream_new (helper_out_fd, TRUE); -+ data_stream = g_data_input_stream_new (unix_stream); -+ g_object_unref (unix_stream); -+ -+ g_data_input_stream_read_line_async (data_stream, G_PRIORITY_DEFAULT, -+ NULL, restart_helper_read_line_callback, -+ &error); -+ if (error != NULL) -+ { -+ meta_warning ("Failed to read from restart helper: %s\n", error->message); -+ g_object_unref (data_stream); -+ goto error; -+ } -+ -+ return; -+ -+ error: -+ /* If starting the restart helper fails, then we just go ahead and restart -+ * immediately. We won't get a smooth transition, since the overlay window -+ * will be destroyed and recreated, but otherwise it will work fine. -+ */ -+ restart_helper_started = TRUE; -+ restart_check_ready (); -+ -+ return; -+} -+ -+void -+meta_restart_finish (void) -+{ -+ if (is_restart) -+ { -+ Display *xdisplay = meta_display_get_xdisplay (meta_get_display ()); -+ Atom atom_restart_helper = XInternAtom (xdisplay, "_MUTTER_RESTART_HELPER", False); -+ XSetSelectionOwner (xdisplay, atom_restart_helper, None, CurrentTime); -+ } -+} -+ -+/** -+ * meta_is_restart: -+ * -+ * Returns %TRUE if this instance of Mutter comes from Mutter -+ * restarting itself (for example to enable/disable stereo.) -+ * See meta_restart(). If this is the case, any startup visuals -+ * or animations should be suppressed. -+ */ -+gboolean -+meta_is_restart (void) -+{ -+ return is_restart; -+} -diff --git a/src/meta/main.h b/src/meta/main.h -index dd4e7f1..af7a2c9 100644 ---- a/src/meta/main.h -+++ b/src/meta/main.h -@@ -35,6 +35,9 @@ gboolean meta_get_replace_current_wm (void); /* Actually defined in util - void meta_set_wm_name (const char *wm_name); - void meta_set_gnome_wm_keybindings (const char *wm_keybindings); - -+void meta_restart (const char *message); -+gboolean meta_is_restart (void); -+ - /** - * MetaExitCode: - * @META_EXIT_SUCCESS: Success --- -1.9.3 - diff --git a/SOURCES/0001-MetaTextureTower-actually-mark-revalidated-levels-as.patch b/SOURCES/0001-MetaTextureTower-actually-mark-revalidated-levels-as.patch deleted file mode 100644 index 27f6e35..0000000 --- a/SOURCES/0001-MetaTextureTower-actually-mark-revalidated-levels-as.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff -up mutter-3.8.4/src/compositor/meta-texture-tower.c.texture-tower mutter-3.8.4/src/compositor/meta-texture-tower.c ---- mutter-3.8.4/src/compositor/meta-texture-tower.c.texture-tower 2014-09-29 15:07:00.955634201 -0400 -+++ mutter-3.8.4/src/compositor/meta-texture-tower.c 2014-09-29 15:08:01.656005996 -0400 -@@ -562,6 +562,9 @@ texture_tower_revalidate (MetaTextureTow - { - if (!texture_tower_revalidate_fbo (tower, level)) - texture_tower_revalidate_client (tower, level); -+ -+ tower->invalid[level].x1 = tower->invalid[level].x2 = 0; -+ tower->invalid[level].y1 = tower->invalid[level].y2 = 0; - } - - /** diff --git a/SOURCES/0001-Monitor-config-Fix-a-copy-paste-error.patch b/SOURCES/0001-Monitor-config-Fix-a-copy-paste-error.patch new file mode 100644 index 0000000..6638b65 --- /dev/null +++ b/SOURCES/0001-Monitor-config-Fix-a-copy-paste-error.patch @@ -0,0 +1,31 @@ +From 1b22da00390f69fcdfd57135e10f141750e47f00 Mon Sep 17 00:00:00 2001 +From: Matthias Clasen +Date: Mon, 20 Jul 2015 17:33:28 -0400 +Subject: [PATCH 1/2] Monitor-config: Fix a copy-paste error + +The code was checking width twice, instead of width and height, +as was clearly the intention. Coverity pointed this out. + +https://bugzilla.gnome.org/show_bug.cgi?id=752551 +--- + src/backends/meta-monitor-config.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/backends/meta-monitor-config.c b/src/backends/meta-monitor-config.c +index eae142a..ba0ae57 100644 +--- a/src/backends/meta-monitor-config.c ++++ b/src/backends/meta-monitor-config.c +@@ -489,8 +489,8 @@ handle_end_element (GMarkupParseContext *context, + } + else + { +- if (parser->output.rect.width == 0 && +- parser->output.rect.width == 0) ++ if (parser->output.rect.width == 0 || ++ parser->output.rect.height == 0) + parser->output.enabled = FALSE; + else + parser->output.enabled = TRUE; +-- +2.4.5 + diff --git a/SOURCES/0001-background-Allow-using-sliced-textures-for-file-base.patch b/SOURCES/0001-background-Allow-using-sliced-textures-for-file-base.patch deleted file mode 100644 index 13bdb48..0000000 --- a/SOURCES/0001-background-Allow-using-sliced-textures-for-file-base.patch +++ /dev/null @@ -1,37 +0,0 @@ -From b7840bec7d135fec3c268b5eab1233d6c6c7cdf6 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Fri, 14 Jun 2013 14:49:13 -0400 -Subject: [PATCH] background: Allow using sliced textures for file based - backgrounds - -Some cards have 2k texture limits, which can be smaller than -commonly sized backgrounds. - -One way to get around this problem is to use Cogl's "sliced texture" -feature, that transparently uses several hardware textures under the hood. - -This commit changes background textures loaded from file to potentially -use slicing. Based on a patch by Jasper St. Pierre -. - -https://bugzilla.gnome.org/show_bug.cgi?id=702283 ---- - src/compositor/meta-background.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/compositor/meta-background.c b/src/compositor/meta-background.c -index b8e0d52..568614f 100644 ---- a/src/compositor/meta-background.c -+++ b/src/compositor/meta-background.c -@@ -1090,7 +1090,7 @@ meta_background_load_file_finish (MetaBackground *self, - - texture = cogl_texture_new_from_data (width, - height, -- COGL_TEXTURE_NO_SLICING, -+ COGL_TEXTURE_NO_ATLAS, - has_alpha ? - COGL_PIXEL_FORMAT_RGBA_8888 : - COGL_PIXEL_FORMAT_RGB_888, --- -1.8.4.2 - diff --git a/SOURCES/0001-background-don-t-save-pixbuf-in-user-data.patch b/SOURCES/0001-background-don-t-save-pixbuf-in-user-data.patch deleted file mode 100644 index 3270091..0000000 --- a/SOURCES/0001-background-don-t-save-pixbuf-in-user-data.patch +++ /dev/null @@ -1,38 +0,0 @@ -From c52b30d01f0abcba397c7bfa62abb311d7ea2c8a Mon Sep 17 00:00:00 2001 -From: Tim Lunn -Date: Mon, 26 Aug 2013 11:39:38 +1000 -Subject: [PATCH] background: don't save pixbuf in user data - -https://bugzilla.gnome.org/show_bug.cgi?id=706777 ---- - src/compositor/meta-background.c | 7 ------- - 1 file changed, 7 deletions(-) - -diff --git a/src/compositor/meta-background.c b/src/compositor/meta-background.c -index 76477c8..af33f58 100644 ---- a/src/compositor/meta-background.c -+++ b/src/compositor/meta-background.c -@@ -1031,7 +1031,6 @@ meta_background_load_file_finish (MetaBackground *self, - GAsyncResult *result, - GError **error) - { -- static CoglUserDataKey key; - GTask *task; - LoadFileTaskData *task_data; - CoglTexture *texture; -@@ -1077,12 +1076,6 @@ meta_background_load_file_finish (MetaBackground *self, - goto out; - } - -- cogl_object_set_user_data (COGL_OBJECT (texture), -- &key, -- g_object_ref (pixbuf), -- (CoglUserDataDestroyCallback) -- g_object_unref); -- - ensure_pipeline (self); - unset_texture (self); - set_style (self, task_data->style); --- -1.8.5.3 - diff --git a/SOURCES/0001-core-Add-minimal-handling-of-touch-events.patch b/SOURCES/0001-core-Add-minimal-handling-of-touch-events.patch deleted file mode 100644 index ac0f8fd..0000000 --- a/SOURCES/0001-core-Add-minimal-handling-of-touch-events.patch +++ /dev/null @@ -1,245 +0,0 @@ -From 9eeb657cd98eeb198e50130b4081b2b34b1d7469 Mon Sep 17 00:00:00 2001 -From: Carlos Garnacho -Date: Tue, 11 Feb 2014 19:24:12 +0100 -Subject: [PATCH] core: Add minimal handling of touch events - -Currently touch events are ignored in the core event handler, -and hence dealt with within GDK. If those touch events were -emulating pointer events, GDK would attempt to convert back -those events to pointer events as the frame GdkWindow doesn't -have the GDK_TOUCH_MASK set. - -This results in XI_TouchBegin events being initially processed -by GDK, converted to button events, and triggering a grab op -that subverts touch events into pointer events, so the touch -is never ever seen again by GDK. This leaves GDK in an -inconsistent internal state wrt pointer grabs, so future -pointer-emulating touches will refer to the same window forever. - -Fix this by handling touch events minimally, just enough to -convert XI_TouchBegin to GDK_BUTTON_PRESS within mutter, so GDK -is bypassed for every touch event just like it is for pointer -events. This, and the XIGrabDevice() that keeps coercing pointer -events when the grab operation starts, are enough to fix window -drag and drop on touch devices. ---- - src/core/display.c | 51 +++++++++++++++++++++++++++++++++++++++------------ - src/ui/ui.c | 18 ++++++++++++++---- - 2 files changed, 53 insertions(+), 16 deletions(-) - -diff --git a/src/core/display.c b/src/core/display.c -index d611314..435d9d9 100644 ---- a/src/core/display.c -+++ b/src/core/display.c -@@ -1838,6 +1838,9 @@ get_input_event (MetaDisplay *display, - - switch (input_event->evtype) - { -+ case XI_TouchBegin: -+ case XI_TouchUpdate: -+ case XI_TouchEnd: - case XI_Motion: - case XI_ButtonPress: - case XI_ButtonRelease: -@@ -2041,6 +2044,7 @@ event_callback (XEvent *event, - { - XIDeviceEvent *device_event = (XIDeviceEvent *) input_event; - XIEnterEvent *enter_event = (XIEnterEvent *) input_event; -+ gint button = 0; - - if (window && !window->override_redirect && - ((input_event->type == XI_KeyPress) || (input_event->type == XI_ButtonPress))) -@@ -2076,19 +2080,32 @@ event_callback (XEvent *event, - if (meta_display_process_key_event (display, window, (XIDeviceEvent *) input_event)) - filter_out_event = bypass_compositor = TRUE; - break; -+ case XI_TouchBegin: -+ /* Filter out non-pointer-emulating touches */ -+ if ((((XIDeviceEvent *) input_event)->flags & XITouchEmulatingPointer) == 0) -+ break; -+ -+ /* Fall through */ - case XI_ButtonPress: - if (display->grab_op == META_GRAB_OP_COMPOSITOR) - break; - - display->overlay_key_only_pressed = FALSE; - -- if (device_event->detail == 4 || device_event->detail == 5) -- /* Scrollwheel event, do nothing and deliver event to compositor below */ -- break; -+ if (input_event->evtype == XI_ButtonPress) -+ { -+ if (device_event->detail == 4 || device_event->detail == 5) -+ /* Scrollwheel event, do nothing and deliver event to compositor below */ -+ break; -+ else -+ button = device_event->detail; -+ } -+ else if (input_event->evtype == XI_TouchBegin) -+ button = 1; - - if ((window && - meta_grab_op_is_mouse (display->grab_op) && -- display->grab_button != device_event->detail && -+ display->grab_button != button && - display->grab_window == window) || - grab_op_is_keyboard (display->grab_op)) - { -@@ -2130,8 +2147,7 @@ event_callback (XEvent *event, - */ - unmodified = (device_event->mods.effective & grab_mask) == 0; - -- if (unmodified || -- device_event->detail == 1) -+ if (unmodified || button == 1) - { - /* don't focus if frame received, will be lowered in - * frames.c or special-cased if the click was on a -@@ -2152,7 +2168,7 @@ event_callback (XEvent *event, - { - meta_topic (META_DEBUG_FOCUS, - "Focusing %s due to unmodified button %u press (display.c)\n", -- window->desc, device_event->detail); -+ window->desc, button); - meta_window_focus (window, device_event->time); - } - else -@@ -2168,7 +2184,7 @@ event_callback (XEvent *event, - if (!unmodified) - begin_move = TRUE; - } -- else if (!unmodified && device_event->detail == meta_prefs_get_mouse_button_resize()) -+ else if (!unmodified && button == meta_prefs_get_mouse_button_resize()) - { - if (window->has_resize_func) - { -@@ -2210,21 +2226,21 @@ event_callback (XEvent *event, - op, - TRUE, - FALSE, -- device_event->detail, -+ button, - 0, - device_event->time, - device_event->root_x, - device_event->root_y); - } - } -- else if (device_event->detail == meta_prefs_get_mouse_button_menu()) -+ else if (button == meta_prefs_get_mouse_button_menu()) - { - if (meta_prefs_get_raise_on_click ()) - meta_window_raise (window); - meta_window_show_menu (window, - device_event->root_x, - device_event->root_y, -- device_event->detail, -+ button, - device_event->time); - } - -@@ -2267,7 +2283,7 @@ event_callback (XEvent *event, - META_GRAB_OP_MOVING, - TRUE, - FALSE, -- device_event->detail, -+ button, - 0, - device_event->time, - device_event->root_x, -@@ -2438,6 +2454,14 @@ event_callback (XEvent *event, - filter_out_event = bypass_compositor = TRUE; - break; - #endif /* HAVE_XI23 */ -+ case XI_TouchUpdate: -+ case XI_TouchEnd: -+ /* Currently unhandled, if any grab_op is started through XI_TouchBegin, -+ * the XIGrabDevice() evmask drops touch events, so only emulated -+ * XI_Motions and XI_ButtonRelease will follow. -+ */ -+ filter_out_event = TRUE; -+ break; - } - } - else -@@ -2963,6 +2987,9 @@ event_get_modified_window (MetaDisplay *display, - case XI_ButtonRelease: - case XI_KeyPress: - case XI_KeyRelease: -+ case XI_TouchBegin: -+ case XI_TouchUpdate: -+ case XI_TouchEnd: - return ((XIDeviceEvent *) input_event)->event; - case XI_FocusIn: - case XI_FocusOut: -diff --git a/src/ui/ui.c b/src/ui/ui.c -index af28263..582fdce 100644 ---- a/src/ui/ui.c -+++ b/src/ui/ui.c -@@ -126,6 +126,7 @@ maybe_redirect_mouse_event (XEvent *xevent) - - switch (xev->evtype) - { -+ case XI_TouchBegin: - case XI_ButtonPress: - case XI_ButtonRelease: - case XI_Motion: -@@ -162,20 +163,27 @@ maybe_redirect_mouse_event (XEvent *xevent) - - switch (xev->evtype) - { -+ case XI_TouchBegin: - case XI_ButtonPress: - case XI_ButtonRelease: -- if (xev_d->evtype == XI_ButtonPress) -+ if (xev_d->evtype == XI_ButtonPress || xev_d->evtype == XI_TouchBegin) - { - GtkSettings *settings = gtk_settings_get_default (); - int double_click_time; - int double_click_distance; -+ int button; - - g_object_get (settings, - "gtk-double-click-time", &double_click_time, - "gtk-double-click-distance", &double_click_distance, - NULL); - -- if (xev_d->detail == ui->button_click_number && -+ if (xev->evtype == XI_TouchBegin) -+ button = 1; -+ else -+ button = xev_d->detail; -+ -+ if (button == ui->button_click_number && - xev_d->event == ui->button_click_window && - xev_d->time < ui->button_click_time + double_click_time && - ABS (xev_d->event_x - ui->button_click_x) <= double_click_distance && -@@ -188,20 +196,22 @@ maybe_redirect_mouse_event (XEvent *xevent) - else - { - gevent = gdk_event_new (GDK_BUTTON_PRESS); -- ui->button_click_number = xev_d->detail; -+ ui->button_click_number = button; - ui->button_click_window = xev_d->event; - ui->button_click_time = xev_d->time; - ui->button_click_x = xev_d->event_x; - ui->button_click_y = xev_d->event_y; - } -+ -+ gevent->button.button = button; - } - else - { - gevent = gdk_event_new (GDK_BUTTON_RELEASE); -+ gevent->button.button = xev_d->detail; - } - - gevent->button.window = g_object_ref (gdk_window); -- gevent->button.button = xev_d->detail; - gevent->button.time = xev_d->time; - gevent->button.x = xev_d->event_x; - gevent->button.y = xev_d->event_y; --- -1.8.5.3 - diff --git a/SOURCES/0001-events-Don-t-use-XIEvent-serial-numbers.patch b/SOURCES/0001-events-Don-t-use-XIEvent-serial-numbers.patch new file mode 100644 index 0000000..d78d8bd --- /dev/null +++ b/SOURCES/0001-events-Don-t-use-XIEvent-serial-numbers.patch @@ -0,0 +1,99 @@ +From b21bd3f820e875aa67b8f8dcb7b648eaebb7d926 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Thu, 9 Jul 2015 17:39:05 +0200 +Subject: [PATCH] events: Don't use XIEvent serial numbers + +XInput2 uses the raw sequence number for XIEvent serials, which only +matches the serial number in XEvents up to 16 bits[0]. So in order to +be able to make reliable comparisons with serials from other events or +calls to XNextRequest(), always use the field from the original XEvent +rather than the XIEvent serial. + +[0] http://cgit.freedesktop.org/xorg/lib/libX11/tree/src/XlibInt.c#n265 +--- + src/x11/events.c | 20 +++++++++++--------- + 1 file changed, 11 insertions(+), 9 deletions(-) + +diff --git a/src/x11/events.c b/src/x11/events.c +index bf2dd9b..fbfd2dd 100644 +--- a/src/x11/events.c ++++ b/src/x11/events.c +@@ -691,7 +691,8 @@ meta_spew_event_print (MetaDisplay *display, + static gboolean + handle_window_focus_event (MetaDisplay *display, + MetaWindow *window, +- XIEnterEvent *event) ++ XIEnterEvent *event, ++ unsigned long serial) + { + MetaWindow *focus_window; + #ifdef WITH_VERBOSE_MODE +@@ -726,7 +727,7 @@ handle_window_focus_event (MetaDisplay *display, + event->event, window_type, + meta_event_mode_to_string (event->mode), + meta_event_detail_to_string (event->mode), +- event->serial); ++ serial); + #endif + + /* FIXME our pointer tracking is broken; see how +@@ -770,7 +771,7 @@ handle_window_focus_event (MetaDisplay *display, + if (event->evtype == XI_FocusIn) + { + display->server_focus_window = event->event; +- display->server_focus_serial = event->serial; ++ display->server_focus_serial = serial; + focus_window = window; + } + else if (event->evtype == XI_FocusOut) +@@ -784,7 +785,7 @@ handle_window_focus_event (MetaDisplay *display, + } + + display->server_focus_window = None; +- display->server_focus_serial = event->serial; ++ display->server_focus_serial = serial; + focus_window = NULL; + } + else +@@ -834,8 +835,9 @@ crossing_serial_is_ignored (MetaDisplay *display, + } + + static gboolean +-handle_input_xevent (MetaDisplay *display, +- XIEvent *input_event) ++handle_input_xevent (MetaDisplay *display, ++ XIEvent *input_event, ++ unsigned long serial) + { + XIEnterEvent *enter_event = (XIEnterEvent *) input_event; + Window modified; +@@ -872,7 +874,7 @@ handle_input_xevent (MetaDisplay *display, + /* Check if we've entered a window; do this even if window->has_focus to + * avoid races. + */ +- if (window && !crossing_serial_is_ignored (display, input_event->serial) && ++ if (window && !crossing_serial_is_ignored (display, serial) && + enter_event->mode != XINotifyGrab && + enter_event->mode != XINotifyUngrab && + enter_event->detail != XINotifyInferior && +@@ -897,7 +899,7 @@ handle_input_xevent (MetaDisplay *display, + break; + case XI_FocusIn: + case XI_FocusOut: +- if (handle_window_focus_event (display, window, enter_event) && ++ if (handle_window_focus_event (display, window, enter_event, serial) && + enter_event->event == enter_event->root) + { + if (enter_event->evtype == XI_FocusIn && +@@ -1741,7 +1743,7 @@ meta_display_handle_xevent (MetaDisplay *display, + } + #endif /* HAVE_XI23 */ + +- if (handle_input_xevent (display, input_event)) ++ if (handle_input_xevent (display, input_event, event->xany.serial)) + { + bypass_gtk = bypass_compositor = TRUE; + goto out; +-- +2.4.3 + diff --git a/SOURCES/0001-monitor-manager-Fix-the-max-potential-number-of-logi.patch b/SOURCES/0001-monitor-manager-Fix-the-max-potential-number-of-logi.patch new file mode 100644 index 0000000..0054482 --- /dev/null +++ b/SOURCES/0001-monitor-manager-Fix-the-max-potential-number-of-logi.patch @@ -0,0 +1,36 @@ +From f7b298e717f6a891867ad3b2fb105e59d41aae12 Mon Sep 17 00:00:00 2001 +From: Rui Matos +Date: Fri, 3 Jul 2015 18:01:14 +0200 +Subject: [PATCH] monitor-manager: Fix the max potential number of logical + monitors + +The max potential number of logical monitors (i.e. MetaMonitorInfos) +is the number of CRTCs, not the number of outputs. + +In cases where we have more enabled CRTCs than connected outputs we +would end up appending more MetaMonitorInfos to the GArray than the +size it was initialized with which means the array would get +re-allocated rendering invalid some MetaCRTC->logical_monitor pointers +assigned previously and thus ending in crashes later on. + +https://bugzilla.gnome.org/show_bug.cgi?id=751638 +--- + src/backends/meta-monitor-manager.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c +index 0cb2fc7..95d81de 100644 +--- a/src/backends/meta-monitor-manager.c ++++ b/src/backends/meta-monitor-manager.c +@@ -104,7 +104,7 @@ make_logical_config (MetaMonitorManager *manager) + unsigned int i, j; + + monitor_infos = g_array_sized_new (FALSE, TRUE, sizeof (MetaMonitorInfo), +- manager->n_outputs); ++ manager->n_crtcs); + + /* Walk the list of MetaCRTCs, and build a MetaMonitorInfo + for each of them, unless they reference a rectangle that +-- +2.5.0 + diff --git a/SOURCES/0001-monitor-manager-xrandr-Be-more-robust-when-reading-X.patch b/SOURCES/0001-monitor-manager-xrandr-Be-more-robust-when-reading-X.patch new file mode 100644 index 0000000..e38dccd --- /dev/null +++ b/SOURCES/0001-monitor-manager-xrandr-Be-more-robust-when-reading-X.patch @@ -0,0 +1,91 @@ +From fe1d707a8ca1656063a1b93bf47a78ac20225d7b Mon Sep 17 00:00:00 2001 +From: Rui Matos +Date: Thu, 15 Oct 2015 19:34:40 +0200 +Subject: [PATCH 1/4] monitor-manager-xrandr: Be more robust when reading + XRROutputInfos + +We might get modes in XRROutputInfos that aren't in the +XRRScreenResources we get earlier. This always seems to be transient, +i.e. when it happens, the X server will usually send us a follow up +RRScreenChangeNotify where we then get a "stable" view of the world +again. + +In any case, when these glitches happen, we end up with NULL pointers +in the MetaOutput->modes array which makes us crash later on. This +patch ensures that doesn't happen. + +https://bugzilla.gnome.org/show_bug.cgi?id=756660 +--- + src/backends/x11/meta-monitor-manager-xrandr.c | 42 ++++++++++++++++++-------- + 1 file changed, 29 insertions(+), 13 deletions(-) + +diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c +index 9c65cab..6653b33 100644 +--- a/src/backends/x11/meta-monitor-manager-xrandr.c ++++ b/src/backends/x11/meta-monitor-manager-xrandr.c +@@ -406,6 +406,32 @@ output_get_suggested_y (MetaMonitorManagerXrandr *manager_xrandr, + return -1; + } + ++static void ++output_get_modes (MetaMonitorManager *manager, ++ MetaOutput *meta_output, ++ XRROutputInfo *output) ++{ ++ guint j, k; ++ guint n_actual_modes; ++ ++ meta_output->modes = g_new0 (MetaMonitorMode *, output->nmode); ++ ++ n_actual_modes = 0; ++ for (j = 0; j < (guint)output->nmode; j++) ++ { ++ for (k = 0; k < manager->n_modes; k++) ++ { ++ if (output->modes[j] == (XID)manager->modes[k].mode_id) ++ { ++ meta_output->modes[n_actual_modes] = &manager->modes[k]; ++ n_actual_modes += 1; ++ break; ++ } ++ } ++ } ++ meta_output->n_modes = n_actual_modes; ++} ++ + static char * + get_xmode_name (XRRModeInfo *xmode) + { +@@ -548,6 +574,8 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager) + MetaOutput *meta_output; + + output = XRRGetOutputInfo (manager_xrandr->xdisplay, resources, resources->outputs[i]); ++ if (!output) ++ continue; + + meta_output = &manager->outputs[n_actual_outputs]; + +@@ -596,19 +624,7 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager) + meta_output->suggested_x = output_get_suggested_x (manager_xrandr, meta_output); + meta_output->suggested_y = output_get_suggested_y (manager_xrandr, meta_output); + +- meta_output->n_modes = output->nmode; +- meta_output->modes = g_new0 (MetaMonitorMode *, meta_output->n_modes); +- for (j = 0; j < meta_output->n_modes; j++) +- { +- for (k = 0; k < manager->n_modes; k++) +- { +- if (output->modes[j] == (XID)manager->modes[k].mode_id) +- { +- meta_output->modes[j] = &manager->modes[k]; +- break; +- } +- } +- } ++ output_get_modes (manager, meta_output, output); + meta_output->preferred_mode = meta_output->modes[0]; + + meta_output->n_possible_crtcs = output->ncrtc; +-- +2.5.0 + diff --git a/SOURCES/0001-monitor-manager-xrandr-Use-CurrentTime-when-applying.patch b/SOURCES/0001-monitor-manager-xrandr-Use-CurrentTime-when-applying.patch new file mode 100644 index 0000000..4366be1 --- /dev/null +++ b/SOURCES/0001-monitor-manager-xrandr-Use-CurrentTime-when-applying.patch @@ -0,0 +1,64 @@ +From 016b8f5b4ac4631538061e29d7c3c4adb2122166 Mon Sep 17 00:00:00 2001 +From: Rui Matos +Date: Thu, 16 Oct 2014 13:28:46 +0200 +Subject: [PATCH] monitor-manager-xrandr: Use CurrentTime when applying + configurations + +This is what the xrandr CLI tool does and will allow us to do less +work when we get RRScreenChangeNotify events. + +https://bugzilla.gnome.org/show_bug.cgi?id=738630 +--- + src/backends/x11/meta-monitor-manager-xrandr.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c +index 4f2590e..a5251fe 100644 +--- a/src/backends/x11/meta-monitor-manager-xrandr.c ++++ b/src/backends/x11/meta-monitor-manager-xrandr.c +@@ -57,7 +57,6 @@ struct _MetaMonitorManagerXrandr + + Display *xdisplay; + XRRScreenResources *resources; +- int time; + int rr_event_base; + int rr_error_base; + }; +@@ -413,7 +412,6 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager) + return; + + manager_xrandr->resources = resources; +- manager_xrandr->time = resources->configTimestamp; + manager->n_outputs = resources->noutput; + manager->n_crtcs = resources->ncrtc; + manager->n_modes = resources->nmode; +@@ -747,7 +745,7 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager, + XRRSetCrtcConfig (manager_xrandr->xdisplay, + manager_xrandr->resources, + (XID)crtc->crtc_id, +- manager_xrandr->time, ++ CurrentTime, + 0, 0, + None, + RR_Rotate_0, +@@ -777,7 +775,7 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager, + XRRSetCrtcConfig (manager_xrandr->xdisplay, + manager_xrandr->resources, + (XID)crtc->crtc_id, +- manager_xrandr->time, ++ CurrentTime, + 0, 0, + None, + RR_Rotate_0, +@@ -860,7 +858,7 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager, + ok = XRRSetCrtcConfig (manager_xrandr->xdisplay, + manager_xrandr->resources, + (XID)crtc->crtc_id, +- manager_xrandr->time, ++ CurrentTime, + crtc_info->x, crtc_info->y, + (XID)mode->mode_id, + meta_monitor_transform_to_xrandr (crtc_info->transform), +-- +2.4.3 + diff --git a/SOURCES/0001-monitor-manager-xrandr-Work-around-spurious-hotplugs.patch b/SOURCES/0001-monitor-manager-xrandr-Work-around-spurious-hotplugs.patch new file mode 100644 index 0000000..99b89bd --- /dev/null +++ b/SOURCES/0001-monitor-manager-xrandr-Work-around-spurious-hotplugs.patch @@ -0,0 +1,61 @@ +From 073a328a3031faa82d388805c0a6890d4de001df Mon Sep 17 00:00:00 2001 +From: Rui Matos +Date: Tue, 6 Oct 2015 21:16:18 +0200 +Subject: [PATCH] monitor-manager-xrandr: Work around spurious hotplugs on Xvnc + +Xvnc turns its outputs off/on on every mode set which makes us believe +there was an hotplug when there actually wasn't. Work around this by +requiring new randr configuration timestamps to be ahead of the last +set timestamp by at least 100 ms for us to consider them an actual +hotplug. +--- + src/backends/x11/meta-monitor-manager-xrandr.c | 19 ++++++++++++++++++- + 1 file changed, 18 insertions(+), 1 deletion(-) + +diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c +index 4c1b16c..190aeac 100644 +--- a/src/backends/x11/meta-monitor-manager-xrandr.c ++++ b/src/backends/x11/meta-monitor-manager-xrandr.c +@@ -1064,6 +1064,18 @@ meta_monitor_manager_xrandr_class_init (MetaMonitorManagerXrandrClass *klass) + manager_class->set_crtc_gamma = meta_monitor_manager_xrandr_set_crtc_gamma; + } + ++static gboolean ++is_xvnc (MetaMonitorManager *manager) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < manager->n_outputs; ++i) ++ if (g_str_has_prefix (manager->outputs[i].name, "VNC-")) ++ return TRUE; ++ ++ return FALSE; ++} ++ + gboolean + meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xrandr, + XEvent *event) +@@ -1075,6 +1087,7 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xra + unsigned int n_old_outputs, n_old_modes; + gboolean new_config; + gboolean applied_config = FALSE; ++ unsigned int timestamp; + + if ((event->type - manager_xrandr->rr_event_base) != RRScreenChangeNotify) + return FALSE; +@@ -1091,7 +1104,11 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xra + manager->serial++; + meta_monitor_manager_xrandr_read_current (manager); + +- new_config = manager_xrandr->resources->timestamp >= manager_xrandr->resources->configTimestamp; ++ timestamp = manager_xrandr->resources->timestamp; ++ if (is_xvnc (manager)) ++ timestamp += 100; ++ ++ new_config = timestamp >= manager_xrandr->resources->configTimestamp; + + /* If this is the X server telling us we set a new configuration, + * we can simply short-cut to rebuilding our logical configuration. +-- +2.4.3 + diff --git a/SOURCES/0001-session-Fix-crash-when-saving-sticky-windows.patch b/SOURCES/0001-session-Fix-crash-when-saving-sticky-windows.patch new file mode 100644 index 0000000..1ac4797 --- /dev/null +++ b/SOURCES/0001-session-Fix-crash-when-saving-sticky-windows.patch @@ -0,0 +1,55 @@ +From a95ae4d178e9dba911c01de53f372f18be34df47 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Thu, 15 Oct 2015 15:35:33 +0200 +Subject: [PATCH] session: Fix crash when saving sticky windows + +Since commit 527c53a2a058, window->workspace is set to %NULL when +the window is sticky (see comment[0]), so don't try to save the +workspace index in that case. + +[0] https://git.gnome.org/browse/mutter/tree/src/core/window.c#n4307 + +https://bugzilla.gnome.org/show_bug.cgi?id=756642 +--- + src/x11/session.c | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +diff --git a/src/x11/session.c b/src/x11/session.c +index 6f68729..13cf764 100644 +--- a/src/x11/session.c ++++ b/src/x11/session.c +@@ -946,7 +946,15 @@ save_state (void) + + /* Sticky */ + if (window->on_all_workspaces_requested) +- fputs (" \n", outfile); ++ { ++ fputs (" \n", outfile); ++ } else { ++ int n; ++ n = meta_workspace_index (window->workspace); ++ fprintf (outfile, ++ " \n", n); ++ } ++ + + /* Minimized */ + if (window->minimized) +@@ -963,14 +971,6 @@ save_state (void) + window->saved_rect.height); + } + +- /* Workspaces we're on */ +- { +- int n; +- n = meta_workspace_index (window->workspace); +- fprintf (outfile, +- " \n", n); +- } +- + /* Gravity */ + { + int x, y, w, h; +-- +2.5.0 + diff --git a/SOURCES/0001-shaped-texture-Use-nearest-pixel-interpolation-if-th.patch b/SOURCES/0001-shaped-texture-Use-nearest-pixel-interpolation-if-th.patch deleted file mode 100644 index e0973fd..0000000 --- a/SOURCES/0001-shaped-texture-Use-nearest-pixel-interpolation-if-th.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 1102736013ac02280043c5ee7bc02b5b493dfb08 Mon Sep 17 00:00:00 2001 -From: Hans Petter Jansson -Date: Thu, 10 Oct 2013 02:38:52 +0200 -Subject: [PATCH] shaped-texture: Use nearest-pixel interpolation if the - texture is unscaled - -Use nearest-pixel interpolation if the texture is unscaled. This -improves performance, especially with software rendering. - -Bug: https://bugzilla.gnome.org/show_bug.cgi?id=708389 - -Conflicts: - src/compositor/meta-shaped-texture.c ---- - src/compositor/meta-shaped-texture.c | 20 ++++++++++++++++++++ - 1 file changed, 20 insertions(+) - -diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c -index c6239c9..9cb709d 100644 ---- a/src/compositor/meta-shaped-texture.c -+++ b/src/compositor/meta-shaped-texture.c -@@ -30,6 +30,7 @@ - #include - - #include -+#include "clutter-utils.h" - #include "meta-texture-tower.h" - - #include -@@ -141,6 +142,7 @@ meta_shaped_texture_paint (ClutterActor *actor) - static CoglPipeline *pipeline_unshaped_template = NULL; - - CoglPipeline *pipeline; -+ CoglPipelineFilter filter; - - if (priv->clip_region && cairo_region_is_empty (priv->clip_region)) - return; -@@ -177,6 +179,22 @@ meta_shaped_texture_paint (ClutterActor *actor) - if (tex_width == 0 || tex_height == 0) /* no contents yet */ - return; - -+ /* Use nearest-pixel interpolation if the texture is unscaled. This -+ * improves performance, especially with software rendering. -+ */ -+ -+ filter = COGL_PIPELINE_FILTER_LINEAR; -+ -+ if (!clutter_actor_is_in_clone_paint (actor)) -+ { -+ int x_origin, y_origin; -+ -+ if (meta_actor_is_untransformed (actor, -+ &x_origin, -+ &y_origin)) -+ filter = COGL_PIPELINE_FILTER_NEAREST; -+ } -+ - if (priv->mask_texture == NULL) - { - /* Use a single-layer texture if we don't have a mask. */ -@@ -210,9 +228,11 @@ meta_shaped_texture_paint (ClutterActor *actor) - pipeline = priv->pipeline; - - cogl_pipeline_set_layer_texture (pipeline, 1, priv->mask_texture); -+ cogl_pipeline_set_layer_filters (pipeline, 1, filter, filter); - } - - cogl_pipeline_set_layer_texture (pipeline, 0, paint_tex); -+ cogl_pipeline_set_layer_filters (pipeline, 0, filter, filter); - - { - CoglColor color; --- -1.8.3.1 - diff --git a/SOURCES/0001-stack-Don-t-try-to-focus-hidden-windows.patch b/SOURCES/0001-stack-Don-t-try-to-focus-hidden-windows.patch new file mode 100644 index 0000000..ae441e2 --- /dev/null +++ b/SOURCES/0001-stack-Don-t-try-to-focus-hidden-windows.patch @@ -0,0 +1,40 @@ +From 06cd7aae14cb966875d22173e653e1bb8abac747 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Mon, 29 Jun 2015 20:23:42 +0200 +Subject: [PATCH] stack: Don't try to focus hidden windows + +A window may be hidden even if not minimized itself, for instance +when an ancestor is minimized. As meta_window_focus() will refuse +to actually focus the window in that case, don't pick it in the first +place. + +https://bugzilla.gnome.org/show_bug.cgi?id=751715 +--- + src/core/stack.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +diff --git a/src/core/stack.c b/src/core/stack.c +index 037e878..f618ef2 100644 +--- a/src/core/stack.c ++++ b/src/core/stack.c +@@ -1272,16 +1272,13 @@ get_default_focus_window (MetaStack *stack, + if (window->unmaps_pending > 0) + continue; + +- if (window->minimized) +- continue; +- + if (window->unmanaging) + continue; + + if (!(window->input || window->take_focus)) + continue; + +- if (workspace != NULL && !meta_window_located_on_workspace (window, workspace)) ++ if (!meta_window_should_be_showing (window)) + continue; + + if (must_be_at_point && !window_contains_point (window, root_x, root_y)) +-- +2.4.3 + diff --git a/SOURCES/0001-window-Fix-delayed-mouse-mode-on-X.patch b/SOURCES/0001-window-Fix-delayed-mouse-mode-on-X.patch deleted file mode 100644 index 1b101f2..0000000 --- a/SOURCES/0001-window-Fix-delayed-mouse-mode-on-X.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 8c4610721a117d5d50fc72fb75e41a6727d93b2d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Florian=20M=C3=BCllner?= -Date: Wed, 7 May 2014 23:22:41 +0200 -Subject: [PATCH] window: Fix delayed mouse mode on X - -Using meta_stack_get_default_focus_window_at_point() is unreliable -when used with the overlay windows or popups. Instead, we can just -look up the MetaWindow for the client window that XIQueryPointer -returns. - -https://bugzilla.gnome.org/show_bug.cgi?id=730541 ---- - src/core/display.c | 12 +----------- - 1 file changed, 1 insertion(+), 11 deletions(-) - -diff --git a/src/core/display.c b/src/core/display.c -index 435d9d9..b7688e6 100644 ---- a/src/core/display.c -+++ b/src/core/display.c -@@ -1703,17 +1703,7 @@ window_focus_on_pointer_rest_callback (gpointer data) { - return TRUE; - } - -- /* Explicitly check for the overlay window, as get_focus_window_at_point() -- * may return windows that extend underneath the chrome (like -- * override-redirect or DESKTOP windows) -- */ -- if (child == meta_get_overlay_window (screen)) -- goto out; -- -- window = -- meta_stack_get_default_focus_window_at_point (screen->stack, -- screen->active_workspace, -- None, root_x, root_y); -+ window = meta_display_lookup_x_window (display, child); - - if (window == NULL) - goto out; --- -2.1.0 - diff --git a/SOURCES/0001-window-Remove-fullscreen_after_placement-special-cas.patch b/SOURCES/0001-window-Remove-fullscreen_after_placement-special-cas.patch new file mode 100644 index 0000000..36affe5 --- /dev/null +++ b/SOURCES/0001-window-Remove-fullscreen_after_placement-special-cas.patch @@ -0,0 +1,111 @@ +From 5d53aacdae7666887c5776888974db3973278a5e Mon Sep 17 00:00:00 2001 +From: Rui Matos +Date: Wed, 29 Jul 2015 19:02:48 +0200 +Subject: [PATCH] window: Remove fullscreen_after_placement special case + +This was introduced in commit c6793d477a324f857d31d0704f84ed9de0f1d680 +to prevent window self-maximisation. It turns out that that bug seems +to have been fixed meanwhile in a different way since the reproducer +in https://bugzilla.gnome.org/show_bug.cgi?id=461927#c37 now works +fine with this special handling removed. + +In fact, failing to set window->fullscreen immediately when loading +the initial set of X properties causes us to create a UI frame for a +window that sets _NET_WM_STATE_FULLSCREEN. + +This, in turn, might cause the fullscreen constrain code to fail if +the window also sets min_width/min_height size hints to be the monitor +size since the UI frame size added to those makes the rectangle too +big to fit the monitor. If the window doesn't set these hints, we +fullscreen it but the window will get sized such that the UI frame is +taken into account while it really shouldn't (see the reproducer +above). + +https://bugzilla.gnome.org/show_bug.cgi?id=753020 +--- + src/core/constraints.c | 16 +++------------- + src/core/window-private.h | 3 --- + src/core/window.c | 1 - + src/x11/window-props.c | 5 ++++- + 4 files changed, 7 insertions(+), 18 deletions(-) + +diff --git a/src/core/constraints.c b/src/core/constraints.c +index 1cff417..46e524f 100644 +--- a/src/core/constraints.c ++++ b/src/core/constraints.c +@@ -508,11 +508,10 @@ place_window_if_needed(MetaWindow *window, + if (window->placed || did_placement) + { + if (window->maximize_horizontally_after_placement || +- window->maximize_vertically_after_placement || +- window->fullscreen_after_placement) ++ window->maximize_vertically_after_placement) + { +- /* define a sane saved_rect so that the user can unmaximize or +- * make unfullscreen to something reasonable. ++ /* define a sane saved_rect so that the user can unmaximize to ++ * something reasonable. + */ + if (info->current.width >= info->work_area_monitor.width) + { +@@ -540,15 +539,6 @@ place_window_if_needed(MetaWindow *window, + (window->maximize_vertically_after_placement ? + META_MAXIMIZE_VERTICAL : 0), &info->current); + +- if (window->fullscreen_after_placement) +- { +- window->saved_rect = info->current; +- window->fullscreen = TRUE; +- window->fullscreen_after_placement = FALSE; +- +- g_object_notify (G_OBJECT (window), "fullscreen"); +- } +- + window->maximize_horizontally_after_placement = FALSE; + window->maximize_vertically_after_placement = FALSE; + } +diff --git a/src/core/window-private.h b/src/core/window-private.h +index 713acd3..9f98739 100644 +--- a/src/core/window-private.h ++++ b/src/core/window-private.h +@@ -174,9 +174,6 @@ struct _MetaWindow + /* Whether the window is marked as urgent */ + guint urgent : 1; + +- /* Whether we have to fullscreen after placement */ +- guint fullscreen_after_placement : 1; +- + /* Area to cover when in fullscreen mode. If _NET_WM_FULLSCREEN_MONITORS has + * been overridden (via a client message), the window will cover the union of + * these monitors. If not, this is the single monitor which the window's +diff --git a/src/core/window.c b/src/core/window.c +index 2e82741..9e2ebf5 100644 +--- a/src/core/window.c ++++ b/src/core/window.c +@@ -860,7 +860,6 @@ _meta_window_shared_new (MetaDisplay *display, + window->maximize_vertically_after_placement = FALSE; + window->minimize_after_placement = FALSE; + window->fullscreen = FALSE; +- window->fullscreen_after_placement = FALSE; + window->fullscreen_monitors[0] = -1; + window->require_fully_onscreen = TRUE; + window->require_on_single_monitor = TRUE; +diff --git a/src/x11/window-props.c b/src/x11/window-props.c +index 3164985..0851f22 100644 +--- a/src/x11/window-props.c ++++ b/src/x11/window-props.c +@@ -819,7 +819,10 @@ reload_net_wm_state (MetaWindow *window, + else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_SKIP_PAGER) + priv->wm_state_skip_pager = TRUE; + else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_FULLSCREEN) +- window->fullscreen_after_placement = TRUE; ++ { ++ window->fullscreen = TRUE; ++ g_object_notify (G_OBJECT (window), "fullscreen"); ++ } + else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_ABOVE) + window->wm_state_above = TRUE; + else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_BELOW) +-- +2.4.3 + diff --git a/SOURCES/0001-workspace-Add-missing-chain-up-for-finalize.patch b/SOURCES/0001-workspace-Add-missing-chain-up-for-finalize.patch deleted file mode 100644 index e6733f8..0000000 --- a/SOURCES/0001-workspace-Add-missing-chain-up-for-finalize.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 2a4678ecee0839f9efe12f169002c3d19c1a40fa Mon Sep 17 00:00:00 2001 -From: Pavel Vasin -Date: Sat, 14 Sep 2013 16:18:02 +0400 -Subject: [PATCH] workspace: Add missing chain-up for finalize() - -https://bugzilla.gnome.org/show_bug.cgi?id=708070 ---- - src/core/workspace.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/src/core/workspace.c b/src/core/workspace.c -index d2c1552..e5da6d2 100644 ---- a/src/core/workspace.c -+++ b/src/core/workspace.c -@@ -78,6 +78,7 @@ static void - meta_workspace_finalize (GObject *object) - { - /* Actual freeing done in meta_workspace_remove() for now */ -+ G_OBJECT_CLASS (meta_workspace_parent_class)->finalize (object); - } - - static void --- -1.9.0 - diff --git a/SOURCES/0002-Add-support-for-quad-buffer-stereo.patch b/SOURCES/0002-Add-support-for-quad-buffer-stereo.patch deleted file mode 100644 index c3d0c82..0000000 --- a/SOURCES/0002-Add-support-for-quad-buffer-stereo.patch +++ /dev/null @@ -1,909 +0,0 @@ -From 9ceccaf38295d73b729bc3a6777fa6b948fa4007 Mon Sep 17 00:00:00 2001 -From: "Owen W. Taylor" -Date: Thu, 8 May 2014 18:44:15 -0400 -Subject: [PATCH] Add support for quad-buffer stereo - -Track the stereo status of windows using the new EXT_stereo_tree -GLX extension. - -When stereo is enabled or disabled, a restart is triggered via -meta_restart() after a timeout, setting a _META_ENABLE_STEREO -property on the root window to indicate whether we should -turn on a stereo stage for clutter. The property avoids a loop, -since we need to enable stereo *before* initializing Clutter and GL, -but we need GL to figure out whether we have stereo windows. - -Stereo windows are drawn to the stage using new functionality -in Cogl to setup a stereo context, select which buffer to draw -to, and draw either the left or right buffer of a stereo -texture_from_pixmap. ---- - src/Makefile.am | 2 + - src/compositor/compositor-private.h | 10 ++ - src/compositor/compositor.c | 127 +++++++++++++++++++- - src/compositor/meta-shaped-texture-private.h | 37 ++++++ - src/compositor/meta-shaped-texture.c | 166 ++++++++++++++++++++------- - src/compositor/meta-window-actor-private.h | 7 ++ - src/compositor/meta-window-actor.c | 27 ++++- - src/core/main.c | 2 + - src/core/stereo.c | 144 +++++++++++++++++++++++ - src/core/stereo.h | 28 +++++ - src/meta/meta-shaped-texture.h | 3 +- - 11 files changed, 508 insertions(+), 45 deletions(-) - create mode 100644 src/compositor/meta-shaped-texture-private.h - create mode 100644 src/core/stereo.c - create mode 100644 src/core/stereo.h - -diff --git a/src/Makefile.am b/src/Makefile.am -index d664b54..1d2422e 100644 ---- a/src/Makefile.am -+++ b/src/Makefile.am -@@ -122,6 +122,8 @@ libmutter_la_SOURCES = \ - core/restart.c \ - core/session.c \ - core/session.h \ -+ core/stereo.c \ -+ core/stereo.h \ - core/stack.c \ - core/stack.h \ - core/stack-tracker.c \ -diff --git a/src/compositor/compositor-private.h b/src/compositor/compositor-private.h -index acb8d3c..b4c5c16 100644 ---- a/src/compositor/compositor-private.h -+++ b/src/compositor/compositor-private.h -@@ -28,6 +28,8 @@ struct _MetaCompositor - gint64 server_time_query_time; - gint64 server_time_offset; - -+ int glx_opcode; -+ - guint server_time_is_monotonic_time : 1; - guint show_redraw : 1; - guint debug : 1; -@@ -56,6 +58,9 @@ struct _MetaCompScreen - - gint switch_workspace_in_progress; - -+ guint stereo_tree_ext : 1; -+ guint have_stereo_windows : 1; -+ - MetaPluginManager *plugin_mgr; - }; - -@@ -79,4 +84,9 @@ gint64 meta_compositor_monotonic_time_to_server_time (MetaDisplay *display, - - void meta_check_end_modal (MetaScreen *screen); - -+gboolean meta_compositor_window_is_stereo (MetaScreen *screen, -+ Window xwindow); -+void meta_compositor_select_stereo_notify (MetaScreen *screen, -+ Window xwindow); -+ - #endif /* META_COMPOSITOR_PRIVATE_H */ -diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c -index 539a7a6..fd29e48 100644 ---- a/src/compositor/compositor.c -+++ b/src/compositor/compositor.c -@@ -86,7 +86,8 @@ - #include "meta-window-group.h" - #include "window-private.h" /* to check window->hidden */ - #include "display-private.h" /* for meta_display_lookup_x_window() */ --#include "util-private.h" -+#include "stack-tracker.h" -+#include "stereo.h" - #include - #include - -@@ -579,6 +580,101 @@ redirect_windows (MetaCompositor *compositor, - } - } - -+#define GLX_STEREO_TREE_EXT 0x20F5 -+#define GLX_STEREO_NOTIFY_MASK_EXT 0x00000001 -+#define GLX_STEREO_NOTIFY_EXT 0x00000000 -+ -+typedef struct { -+ int type; -+ unsigned long serial; -+ Bool send_event; -+ Display *display; -+ int extension; -+ int evtype; -+ Drawable window; -+ Bool stereo_tree; -+} StereoNotifyEvent; -+ -+static gboolean -+screen_has_stereo_tree_ext (MetaScreen *screen) -+{ -+#if 0 -+ MetaDisplay *display = meta_screen_get_display (screen); -+ Display *xdisplay = meta_display_get_xdisplay (display); -+ const char *extensions_string; -+ -+ static const char * (*query_extensions_string) (Display *display, -+ int screen); -+ -+ if (query_extensions_string == NULL) -+ query_extensions_string = -+ (const char * (*) (Display *, int)) -+ cogl_get_proc_address ("glXQueryExtensionsString"); -+ -+ extensions_string = query_extensions_string (xdisplay, -+ meta_screen_get_screen_number (screen)); -+ -+ return strstr (extensions_string, "EXT_stereo_tree") != 0; -+#else -+ return TRUE; -+#endif -+} -+ -+#include -+ -+gboolean -+meta_compositor_window_is_stereo (MetaScreen *screen, -+ Window xwindow) -+{ -+ MetaCompScreen *info = meta_screen_get_compositor_data (screen); -+ MetaDisplay *display = meta_screen_get_display (screen); -+ Display *xdisplay = meta_display_get_xdisplay (display); -+ -+ static int (*query_drawable) (Display *dpy, -+ Drawable draw, -+ int attribute, -+ unsigned int *value); -+ -+ if (info->stereo_tree_ext) -+ { -+ unsigned int stereo_tree = 0; -+ -+ if (query_drawable == NULL) -+ query_drawable = -+ (int (*) (Display *, Drawable, int, unsigned int *)) -+ cogl_get_proc_address ("glXQueryDrawable"); -+ -+ query_drawable (xdisplay, xwindow, GLX_STEREO_TREE_EXT, &stereo_tree); -+ -+ return stereo_tree != 0; -+ } -+ else -+ return FALSE; -+} -+ -+void -+meta_compositor_select_stereo_notify (MetaScreen *screen, -+ Window xwindow) -+{ -+ MetaCompScreen *info = meta_screen_get_compositor_data (screen); -+ MetaDisplay *display = meta_screen_get_display (screen); -+ Display *xdisplay = meta_display_get_xdisplay (display); -+ -+ static void (*select_event) (Display *dpy, -+ Drawable draw, -+ unsigned long event_mask); -+ -+ if (info->stereo_tree_ext) -+ { -+ if (select_event == NULL) -+ select_event = -+ (void (*) (Display *, Drawable, unsigned long)) -+ cogl_get_proc_address ("glXSelectEvent"); -+ -+ select_event (xdisplay, xwindow, GLX_STEREO_NOTIFY_MASK_EXT); -+ } -+} -+ - void - meta_compositor_manage_screen (MetaCompositor *compositor, - MetaScreen *screen) -@@ -609,6 +705,8 @@ meta_compositor_manage_screen (MetaCompositor *compositor, - info->output = None; - info->windows = NULL; - -+ info->stereo_tree_ext = screen_has_stereo_tree_ext (screen); -+ - meta_screen_set_cm_selection (screen); - - info->stage = clutter_stage_new (); -@@ -995,6 +1093,23 @@ meta_compositor_process_event (MetaCompositor *compositor, - DEBUG_TRACE ("meta_compositor_process_event (process_damage)\n"); - process_damage (compositor, (XDamageNotifyEvent *) event, window); - } -+ else if (event->type == GenericEvent && -+ event->xcookie.extension == compositor->glx_opcode) -+ { -+ if (event->xcookie.evtype == GLX_STEREO_NOTIFY_EXT) -+ { -+ StereoNotifyEvent *stereo_event = (StereoNotifyEvent *)(event->xcookie.data); -+ window = meta_display_lookup_x_window (compositor->display, stereo_event->window); -+ -+ if (window != NULL) -+ { -+ MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); -+ meta_window_actor_stereo_notify (window_actor, stereo_event->stereo_tree); -+ meta_stack_tracker_queue_sync_stack (window->screen->stack_tracker); -+ } -+ } -+ } -+ - break; - } - -@@ -1209,6 +1324,7 @@ meta_compositor_sync_stack (MetaCompositor *compositor, - { - GList *old_stack; - MetaCompScreen *info = meta_screen_get_compositor_data (screen); -+ int stereo_window_count = 0; - - DEBUG_TRACE ("meta_compositor_sync_stack\n"); - -@@ -1286,12 +1402,16 @@ meta_compositor_sync_stack (MetaCompositor *compositor, - * near the front of the other.) - */ - info->windows = g_list_prepend (info->windows, actor); -+ if (meta_window_actor_is_stereo (actor)) -+ stereo_window_count++; - - stack = g_list_remove (stack, window); - old_stack = g_list_remove (old_stack, actor); - } - - sync_actor_stacking (info); -+ -+ meta_stereo_set_have_stereo_windows (stereo_window_count > 0); - } - - void -@@ -1505,6 +1625,7 @@ meta_compositor_new (MetaDisplay *display) - Atom atoms[G_N_ELEMENTS(atom_names)]; - MetaCompositor *compositor; - Display *xdisplay = meta_display_get_xdisplay (display); -+ int glx_major_opcode, glx_first_event, glx_first_error; - - if (!composite_at_least_version (display, 0, 3)) - return NULL; -@@ -1531,6 +1652,10 @@ meta_compositor_new (MetaDisplay *display) - compositor->repaint_func_id = clutter_threads_add_repaint_func (meta_repaint_func, - compositor, - NULL); -+ if (XQueryExtension (xdisplay, -+ "GLX", -+ &glx_major_opcode, &glx_first_event, &glx_first_error)) -+ compositor->glx_opcode = glx_major_opcode; - - return compositor; - } -diff --git a/src/compositor/meta-shaped-texture-private.h b/src/compositor/meta-shaped-texture-private.h -new file mode 100644 -index 0000000..c70f6a8 ---- /dev/null -+++ b/src/compositor/meta-shaped-texture-private.h -@@ -0,0 +1,37 @@ -+/* -+ * shaped texture -+ * -+ * An actor to draw a texture clipped to a list of rectangles -+ * -+ * Authored By Neil Roberts -+ * -+ * Copyright (C) 2008 Intel Corporation -+ * 2013 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_SHAPED_TEXTURE_PRIVATE_H__ -+#define __META_SHAPED_TEXTURE_PRIVATE_H__ -+ -+#include -+ -+ClutterActor *meta_shaped_texture_new (void); -+gboolean meta_shaped_texture_get_unobscured_bounds (MetaShapedTexture *stex, -+ cairo_rectangle_int_t *unobscured_bounds); -+gboolean meta_shaped_texture_is_obscured (MetaShapedTexture *self); -+ -+#endif -diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c -index c6239c9..132cb09 100644 ---- a/src/compositor/meta-shaped-texture.c -+++ b/src/compositor/meta-shaped-texture.c -@@ -65,8 +65,10 @@ G_DEFINE_TYPE (MetaShapedTexture, meta_shaped_texture, - struct _MetaShapedTexturePrivate - { - MetaTextureTower *paint_tower; -+ MetaTextureTower *paint_tower_right; - Pixmap pixmap; - CoglTexturePixmapX11 *texture; -+ CoglTexturePixmapX11 *texture_right; - CoglTexture *mask_texture; - CoglPipeline *pipeline; - CoglPipeline *pipeline_unshaped; -@@ -75,6 +77,7 @@ struct _MetaShapedTexturePrivate - - guint tex_width, tex_height; - -+ guint stereo : 1; - guint create_mipmaps : 1; - }; - -@@ -103,7 +106,9 @@ meta_shaped_texture_init (MetaShapedTexture *self) - priv = self->priv = META_SHAPED_TEXTURE_GET_PRIVATE (self); - - priv->paint_tower = meta_texture_tower_new (); -+ priv->paint_tower_right = NULL; /* demand create */ - priv->texture = NULL; -+ priv->texture_right = NULL; - priv->mask_texture = NULL; - priv->create_mipmaps = TRUE; - } -@@ -114,13 +119,13 @@ meta_shaped_texture_dispose (GObject *object) - MetaShapedTexture *self = (MetaShapedTexture *) object; - MetaShapedTexturePrivate *priv = self->priv; - -- if (priv->paint_tower) -- meta_texture_tower_free (priv->paint_tower); -- priv->paint_tower = NULL; -+ g_clear_pointer (&priv->paint_tower, meta_texture_tower_free); -+ g_clear_pointer (&priv->paint_tower_right, meta_texture_tower_free); - - g_clear_pointer (&priv->pipeline, cogl_object_unref); - g_clear_pointer (&priv->pipeline_unshaped, cogl_object_unref); - g_clear_pointer (&priv->texture, cogl_object_unref); -+ g_clear_pointer (&priv->texture_right, cogl_object_unref); - - meta_shaped_texture_set_mask_texture (self, NULL); - meta_shaped_texture_set_clip_region (self, NULL); -@@ -129,11 +134,11 @@ meta_shaped_texture_dispose (GObject *object) - } - - static void --meta_shaped_texture_paint (ClutterActor *actor) -+paint_texture (MetaShapedTexture *stex, -+ CoglTexture *paint_tex) - { -- MetaShapedTexture *stex = (MetaShapedTexture *) actor; - MetaShapedTexturePrivate *priv = stex->priv; -- CoglTexture *paint_tex; -+ ClutterActor *actor = CLUTTER_ACTOR (stex); - guint tex_width, tex_height; - ClutterActorBox alloc; - -@@ -145,32 +150,6 @@ meta_shaped_texture_paint (ClutterActor *actor) - if (priv->clip_region && cairo_region_is_empty (priv->clip_region)) - return; - -- if (!CLUTTER_ACTOR_IS_REALIZED (CLUTTER_ACTOR (stex))) -- clutter_actor_realize (CLUTTER_ACTOR (stex)); -- -- /* The GL EXT_texture_from_pixmap extension does allow for it to be -- * used together with SGIS_generate_mipmap, however this is very -- * rarely supported. Also, even when it is supported there -- * are distinct performance implications from: -- * -- * - Updating mipmaps that we don't need -- * - Having to reallocate pixmaps on the server into larger buffers -- * -- * So, we just unconditionally use our mipmap emulation code. If we -- * wanted to use SGIS_generate_mipmap, we'd have to query COGL to -- * see if it was supported (no API currently), and then if and only -- * if that was the case, set the clutter texture quality to HIGH. -- * Setting the texture quality to high without SGIS_generate_mipmap -- * support for TFP textures will result in fallbacks to XGetImage. -- */ -- if (priv->create_mipmaps) -- paint_tex = meta_texture_tower_get_paint_texture (priv->paint_tower); -- else -- paint_tex = COGL_TEXTURE (priv->texture); -- -- if (paint_tex == NULL) -- return; -- - tex_width = priv->tex_width; - tex_height = priv->tex_height; - -@@ -279,6 +258,76 @@ meta_shaped_texture_paint (ClutterActor *actor) - } - - static void -+meta_shaped_texture_paint (ClutterActor *actor) -+{ -+ MetaShapedTexture *stex = (MetaShapedTexture *) actor; -+ MetaShapedTexturePrivate *priv = stex->priv; -+ CoglFramebuffer *fb; -+ gboolean stereo; -+ CoglTexture *paint_tex; -+ CoglTexture *paint_tex_right; -+ -+ if (priv->clip_region && cairo_region_is_empty (priv->clip_region)) -+ return; -+ -+ if (!CLUTTER_ACTOR_IS_REALIZED (CLUTTER_ACTOR (stex))) -+ clutter_actor_realize (CLUTTER_ACTOR (stex)); -+ -+ /* The GL EXT_texture_from_pixmap extension does allow for it to be -+ * used together with SGIS_generate_mipmap, however this is very -+ * rarely supported. Also, even when it is supported there -+ * are distinct performance implications from: -+ * -+ * - Updating mipmaps that we don't need -+ * - Having to reallocate pixmaps on the server into larger buffers -+ * -+ * So, we just unconditionally use our mipmap emulation code. If we -+ * wanted to use SGIS_generate_mipmap, we'd have to query COGL to -+ * see if it was supported (no API currently), and then if and only -+ * if that was the case, set the clutter texture quality to HIGH. -+ * Setting the texture quality to high without SGIS_generate_mipmap -+ * support for TFP textures will result in fallbacks to XGetImage. -+ */ -+ if (priv->create_mipmaps) -+ paint_tex = meta_texture_tower_get_paint_texture (priv->paint_tower); -+ else -+ paint_tex = COGL_TEXTURE (priv->texture); -+ -+ if (paint_tex == NULL) -+ return; -+ -+ fb = cogl_get_draw_framebuffer (); -+ -+ stereo = priv->stereo && cogl_framebuffer_get_is_stereo (fb); -+ -+ if (stereo) -+ { -+ if (priv->create_mipmaps) -+ paint_tex_right = meta_texture_tower_get_paint_texture (priv->paint_tower_right); -+ else -+ paint_tex_right = COGL_TEXTURE (priv->texture_right); -+ } -+ else -+ paint_tex_right = NULL; -+ -+ if (paint_tex != NULL) -+ { -+ if (stereo) -+ cogl_framebuffer_set_stereo_mode (fb, COGL_STEREO_LEFT); -+ paint_texture (stex, paint_tex); -+ if (stereo) -+ cogl_framebuffer_set_stereo_mode (fb, COGL_STEREO_BOTH); -+ } -+ -+ if (paint_tex_right != NULL) -+ { -+ cogl_framebuffer_set_stereo_mode (fb, COGL_STEREO_RIGHT); -+ paint_texture (stex, paint_tex_right); -+ cogl_framebuffer_set_stereo_mode (fb, COGL_STEREO_BOTH); -+ } -+} -+ -+static void - meta_shaped_texture_pick (ClutterActor *actor, - const ClutterColor *color) - { -@@ -392,6 +441,12 @@ meta_shaped_texture_set_create_mipmaps (MetaShapedTexture *stex, - base_texture = create_mipmaps ? - COGL_TEXTURE (priv->texture) : NULL; - meta_texture_tower_set_base_texture (priv->paint_tower, base_texture); -+ -+ if (priv->stereo) -+ { -+ base_texture = create_mipmaps ? COGL_TEXTURE (priv->texture_right) : NULL; -+ meta_texture_tower_set_base_texture (priv->paint_tower_right, base_texture); -+ } - } - } - -@@ -435,13 +490,16 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex, - x, y, width, height); - - meta_texture_tower_update_area (priv->paint_tower, x, y, width, height); -+ if (priv->stereo) -+ meta_texture_tower_update_area (priv->paint_tower_right, x, y, width, height); - - clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stex), &clip); - } - - static void - set_cogl_texture (MetaShapedTexture *stex, -- CoglTexturePixmapX11 *cogl_tex) -+ CoglTexturePixmapX11 *cogl_tex, -+ gboolean stereo) - { - MetaShapedTexturePrivate *priv; - guint width, height; -@@ -452,9 +510,17 @@ set_cogl_texture (MetaShapedTexture *stex, - - if (priv->texture != NULL) - cogl_object_unref (priv->texture); -+ if (priv->texture_right != NULL) -+ cogl_object_unref (priv->texture_right); - -+ priv->stereo = stereo; - priv->texture = cogl_tex; - -+ if (priv->stereo) -+ priv->texture_right = cogl_texture_pixmap_x11_new_right ((CoglTexturePixmapX11 *)cogl_tex); -+ else -+ priv->texture_right = NULL; -+ - if (priv->pipeline != NULL) - cogl_pipeline_set_layer_texture (priv->pipeline, 0, COGL_TEXTURE (cogl_tex)); - -@@ -493,7 +559,8 @@ set_cogl_texture (MetaShapedTexture *stex, - */ - void - meta_shaped_texture_set_pixmap (MetaShapedTexture *stex, -- Pixmap pixmap) -+ Pixmap pixmap, -+ gboolean stereo) - { - MetaShapedTexturePrivate *priv; - -@@ -501,23 +568,44 @@ meta_shaped_texture_set_pixmap (MetaShapedTexture *stex, - - priv = stex->priv; - -- if (priv->pixmap == pixmap) -+ if (priv->pixmap == pixmap && priv->stereo == stereo) - return; - - priv->pixmap = pixmap; -+ priv->stereo = stereo; - - if (pixmap != None) - { - CoglContext *ctx = - clutter_backend_get_cogl_context (clutter_get_default_backend ()); -- set_cogl_texture (stex, cogl_texture_pixmap_x11_new (ctx, pixmap, FALSE, NULL)); -+ CoglTexturePixmapX11 *texture; -+ if (priv->stereo) -+ texture = cogl_texture_pixmap_x11_new_left (ctx, pixmap, FALSE, NULL); -+ else -+ texture = cogl_texture_pixmap_x11_new (ctx, pixmap, FALSE, NULL); -+ set_cogl_texture (stex, texture, stereo); - } - else -- set_cogl_texture (stex, NULL); -+ set_cogl_texture (stex, NULL, stereo); -+ -+ if (priv->stereo) -+ { -+ if (priv->paint_tower_right == NULL) -+ priv->paint_tower_right = meta_texture_tower_new (); -+ } -+ else -+ { -+ g_clear_pointer (&priv->paint_tower_right, meta_texture_tower_free); -+ } - - if (priv->create_mipmaps) -- meta_texture_tower_set_base_texture (priv->paint_tower, -- COGL_TEXTURE (priv->texture)); -+ { -+ meta_texture_tower_set_base_texture (priv->paint_tower, -+ COGL_TEXTURE (priv->texture)); -+ if (priv->stereo) -+ meta_texture_tower_set_base_texture (priv->paint_tower_right, -+ COGL_TEXTURE (priv->texture_right)); -+ } - } - - /** -diff --git a/src/compositor/meta-window-actor-private.h b/src/compositor/meta-window-actor-private.h -index 90a9e35..914a8db 100644 ---- a/src/compositor/meta-window-actor-private.h -+++ b/src/compositor/meta-window-actor-private.h -@@ -66,4 +66,11 @@ void meta_window_actor_reset_visible_regions (MetaWindowActor *self); - void meta_window_actor_effect_completed (MetaWindowActor *actor, - gulong event); - -+void meta_window_actor_stereo_notify (MetaWindowActor *actor, -+ gboolean stereo_tree); -+ -+gboolean meta_window_actor_is_stereo (MetaWindowActor *actor); -+ -+void meta_window_actor_detach (MetaWindowActor *self); -+ - #endif /* META_WINDOW_ACTOR_PRIVATE_H */ -diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c -index 42d1257..1a11d0e 100644 ---- a/src/compositor/meta-window-actor.c -+++ b/src/compositor/meta-window-actor.c -@@ -108,6 +108,7 @@ struct _MetaWindowActorPrivate - guint visible : 1; - guint mapped : 1; - guint argb32 : 1; -+ guint stereo : 1; - guint disposed : 1; - guint redecorating : 1; - -@@ -175,7 +176,6 @@ static gboolean meta_window_actor_get_paint_volume (ClutterActor *actor, - ClutterPaintVolume *volume); - - --static void meta_window_actor_detach (MetaWindowActor *self); - static gboolean meta_window_actor_has_shadow (MetaWindowActor *self); - - static void meta_window_actor_handle_updates (MetaWindowActor *self); -@@ -362,6 +362,9 @@ meta_window_actor_constructed (GObject *object) - if (format && format->type == PictTypeDirect && format->direct.alphaMask) - priv->argb32 = TRUE; - -+ priv->stereo = meta_compositor_window_is_stereo (screen, xwindow); -+ meta_compositor_select_stereo_notify (screen, xwindow); -+ - if (!priv->actor) - { - priv->actor = meta_shaped_texture_new (); -@@ -1218,7 +1221,7 @@ meta_window_actor_effect_completed (MetaWindowActor *self, - * when the window is unmapped or when we want to update to a new - * pixmap for a new size. - */ --static void -+void - meta_window_actor_detach (MetaWindowActor *self) - { - MetaWindowActorPrivate *priv = self->priv; -@@ -1234,7 +1237,7 @@ meta_window_actor_detach (MetaWindowActor *self) - * pixmap, but it certainly doesn't work with current DRI/Mesa - */ - meta_shaped_texture_set_pixmap (META_SHAPED_TEXTURE (priv->actor), -- None); -+ None, FALSE); - cogl_flush(); - - XFreePixmap (xdisplay, priv->back_pixmap); -@@ -1823,7 +1826,7 @@ check_needs_pixmap (MetaWindowActor *self) - FALSE); - - meta_shaped_texture_set_pixmap (META_SHAPED_TEXTURE (priv->actor), -- priv->back_pixmap); -+ priv->back_pixmap, priv->stereo); - - texture = meta_shaped_texture_get_texture (META_SHAPED_TEXTURE (priv->actor)); - -@@ -2575,3 +2578,19 @@ meta_window_actor_set_updates_frozen (MetaWindowActor *self, - meta_window_actor_thaw (self); - } - } -+ -+void -+meta_window_actor_stereo_notify (MetaWindowActor *self, -+ gboolean stereo_tree) -+{ -+ MetaWindowActorPrivate *priv = self->priv; -+ -+ priv->stereo = stereo_tree; -+ meta_window_actor_detach (self); -+} -+ -+gboolean -+meta_window_actor_is_stereo (MetaWindowActor *self) -+{ -+ return self->priv->stereo; -+} -diff --git a/src/core/main.c b/src/core/main.c -index d5bde44..8092afc 100644 ---- a/src/core/main.c -+++ b/src/core/main.c -@@ -444,6 +444,8 @@ meta_init (void) - - meta_restart_init (); - -+ meta_stereo_init (); -+ - /* - * Clutter can only be initialized after the UI. - */ -diff --git a/src/core/stereo.c b/src/core/stereo.c -new file mode 100644 -index 0000000..d16a210 ---- /dev/null -+++ b/src/core/stereo.c -@@ -0,0 +1,144 @@ -+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -+ -+/* -+ * Copyright (C) 2014 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, see . -+ */ -+ -+/* -+ * SECTION:stereo -+ * @short_description: Keep track of whether we are a stereo compositor -+ * -+ * With GLX, we need to use a different GL context for stereo and -+ * non-stereo support. Support for multiple GL contexts is unfinished -+ * in Cogl and entirely lacking in Clutter, so it's by far easier -+ * to just restart Mutter when we detect a stereo window. -+ * -+ * A property _MUTTER_ENABLE_STEREO is maintained on the root window -+ * to know whether we should initialize clutter for stereo or not. -+ * When the presence or absence of stereo windows mismatches the -+ * stereo-enabled state for a sufficiently long period of time, -+ * we restart Mutter. -+ */ -+ -+#include -+ -+#include -+#include -+#include -+ -+#include -+#include "ui.h" -+#include -+#include "display-private.h" -+#include "stereo.h" -+ -+static guint stereo_switch_id = 0; -+static gboolean stereo_enabled = FALSE; -+/* -1 so the first time meta_stereo_set_have_stereo_windows() is called -+ * we avoid the short-circuit and set up a timeout to restart -+ * if necessary */ -+static gboolean stereo_have_windows = (gboolean)-1; -+static gboolean stereo_restart = FALSE; -+ -+#define STEREO_ENABLE_WAIT 1000 -+#define STEREO_DISABLE_WAIT 5000 -+ -+void -+meta_stereo_init (void) -+{ -+ Display *xdisplay = meta_ui_get_display (); -+ Window root = DefaultRootWindow (xdisplay); -+ Atom atom_enable_stereo = XInternAtom (xdisplay, "_MUTTER_ENABLE_STEREO", False); -+ Atom type; -+ int format; -+ unsigned long n_items, bytes_after; -+ guchar *data; -+ -+ XGetWindowProperty (xdisplay, root, atom_enable_stereo, -+ 0, 1, False, XA_INTEGER, -+ &type, &format, &n_items, &bytes_after, &data); -+ if (type == XA_INTEGER) -+ { -+ if (format == 32 && n_items == 1 && bytes_after == 0) -+ { -+ stereo_enabled = *(long *)data; -+ } -+ else -+ { -+ meta_warning ("Bad value for _MUTTER_ENABLE_STEREO property\n"); -+ } -+ -+ XFree (data); -+ } -+ else if (type != None) -+ { -+ meta_warning ("Bad type for _MUTTER_ENABLE_STEREO property\n"); -+ } -+ -+ meta_verbose ("On startup, _MUTTER_ENABLE_STEREO=%s", -+ stereo_enabled ? "yes" : "no"); -+ clutter_x11_set_use_stereo_stage (stereo_enabled); -+} -+ -+static gboolean -+meta_stereo_switch (gpointer data) -+{ -+ stereo_switch_id = 0; -+ stereo_restart = TRUE; -+ -+ meta_restart (stereo_have_windows ? -+ _("Enabling stereo...") : -+ _("Disabling stereo...")); -+ -+ return FALSE; -+} -+ -+void -+meta_stereo_set_have_stereo_windows (gboolean have_windows) -+{ -+ have_windows = have_windows != FALSE; -+ -+ if (!stereo_restart && have_windows != stereo_have_windows) -+ { -+ MetaDisplay *display = meta_get_display (); -+ Display *xdisplay = meta_display_get_xdisplay (display); -+ Window root = DefaultRootWindow (xdisplay); -+ Atom atom_enable_stereo = XInternAtom (xdisplay, "_MUTTER_ENABLE_STEREO", False); -+ long value; -+ -+ stereo_have_windows = have_windows; -+ -+ if (stereo_have_windows) -+ meta_verbose ("Detected stereo windows\n"); -+ else -+ meta_verbose ("No stereo windows detected\n"); -+ -+ value = stereo_have_windows; -+ XChangeProperty (xdisplay, root, -+ atom_enable_stereo, XA_INTEGER, 32, -+ PropModeReplace, (guchar *)&value, 1); -+ -+ if (stereo_switch_id != 0) -+ { -+ g_source_remove (stereo_switch_id); -+ stereo_switch_id = 0; -+ } -+ -+ if (stereo_have_windows != stereo_enabled) -+ stereo_switch_id = g_timeout_add (stereo_have_windows ? STEREO_ENABLE_WAIT : STEREO_DISABLE_WAIT, -+ meta_stereo_switch, NULL); -+ } -+} -diff --git a/src/core/stereo.h b/src/core/stereo.h -new file mode 100644 -index 0000000..ccd1d70 ---- /dev/null -+++ b/src/core/stereo.h -@@ -0,0 +1,28 @@ -+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -+ -+/* -+ * Copyright (C) 2014 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, see . -+ */ -+ -+#ifndef META_STEREO_H -+#define META_STEREO_H -+ -+void meta_stereo_init (void); -+void meta_stereo_set_have_stereo_windows (gboolean have_windows); -+gboolean meta_stereo_is_restart (void); -+void meta_stereo_finish_restart (void); -+ -+#endif -diff --git a/src/meta/meta-shaped-texture.h b/src/meta/meta-shaped-texture.h -index 28fb5f6..fcf33c3 100644 ---- a/src/meta/meta-shaped-texture.h -+++ b/src/meta/meta-shaped-texture.h -@@ -76,7 +76,8 @@ void meta_shaped_texture_update_area (MetaShapedTexture *stex, - int height); - - void meta_shaped_texture_set_pixmap (MetaShapedTexture *stex, -- Pixmap pixmap); -+ Pixmap pixmap, -+ gboolean stereo); - - CoglTexture * meta_shaped_texture_get_texture (MetaShapedTexture *stex); - --- -1.8.3.1 - diff --git a/SOURCES/0002-feedback-actor-Fix-a-typo.patch b/SOURCES/0002-feedback-actor-Fix-a-typo.patch new file mode 100644 index 0000000..3d6439a --- /dev/null +++ b/SOURCES/0002-feedback-actor-Fix-a-typo.patch @@ -0,0 +1,29 @@ +From ad51c52b695d5eef3de51ad687ba7346df19917f Mon Sep 17 00:00:00 2001 +From: Matthias Clasen +Date: Mon, 20 Jul 2015 17:39:09 -0400 +Subject: [PATCH 2/2] feedback actor: Fix a typo + +The code for setting an anchor was comparing apples and oranges. +This was pointed out by coverity. + +https://bugzilla.gnome.org/show_bug.cgi?id=752552 +--- + src/compositor/meta-feedback-actor.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/compositor/meta-feedback-actor.c b/src/compositor/meta-feedback-actor.c +index b162584..72658aa 100644 +--- a/src/compositor/meta-feedback-actor.c ++++ b/src/compositor/meta-feedback-actor.c +@@ -187,7 +187,7 @@ meta_feedback_actor_set_anchor (MetaFeedbackActor *self, + if (priv->anchor_x == anchor_x && priv->anchor_y == anchor_y) + return; + +- if (priv->anchor_x != anchor_y) ++ if (priv->anchor_x != anchor_x) + { + priv->anchor_x = anchor_x; + g_object_notify (G_OBJECT (self), "anchor-x"); +-- +2.4.5 + diff --git a/SOURCES/0002-monitor-manager-xrandr-Ignore-outputs-without-modes.patch b/SOURCES/0002-monitor-manager-xrandr-Ignore-outputs-without-modes.patch new file mode 100644 index 0000000..8f683c4 --- /dev/null +++ b/SOURCES/0002-monitor-manager-xrandr-Ignore-outputs-without-modes.patch @@ -0,0 +1,43 @@ +From f8c3fda5c7dbfff74a03713ae2a39dfbcd155693 Mon Sep 17 00:00:00 2001 +From: Rui Matos +Date: Tue, 20 Oct 2015 16:01:30 +0200 +Subject: [PATCH 2/4] monitor-manager-xrandr: Ignore outputs without modes + +In some cases we get outputs without any valid mode. We need to ignore +them or we'll crash later. + +https://bugzilla.gnome.org/show_bug.cgi?id=756796 +--- + src/backends/x11/meta-monitor-manager-xrandr.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c +index 6653b33..9a64bb2 100644 +--- a/src/backends/x11/meta-monitor-manager-xrandr.c ++++ b/src/backends/x11/meta-monitor-manager-xrandr.c +@@ -579,7 +579,13 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager) + + meta_output = &manager->outputs[n_actual_outputs]; + +- if (output->connection != RR_Disconnected) ++ /* Get this first so that if there are no valid modes we ++ can immediately skip to the next output without having ++ to unwind all the assignments below. */ ++ output_get_modes (manager, meta_output, output); ++ ++ if (output->connection != RR_Disconnected && ++ meta_output->n_modes > 0) + { + GBytes *edid; + MonitorInfo *parsed_edid; +@@ -624,7 +630,6 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager) + meta_output->suggested_x = output_get_suggested_x (manager_xrandr, meta_output); + meta_output->suggested_y = output_get_suggested_y (manager_xrandr, meta_output); + +- output_get_modes (manager, meta_output, output); + meta_output->preferred_mode = meta_output->modes[0]; + + meta_output->n_possible_crtcs = output->ncrtc; +-- +2.5.0 + diff --git a/SOURCES/0003-Fix-windows-walking-up-the-screen-on-restart.patch b/SOURCES/0003-Fix-windows-walking-up-the-screen-on-restart.patch deleted file mode 100644 index ba6aa84..0000000 --- a/SOURCES/0003-Fix-windows-walking-up-the-screen-on-restart.patch +++ /dev/null @@ -1,59 +0,0 @@ -From e44f0f15e945a2132912d9763cfa3e9e326e0aea Mon Sep 17 00:00:00 2001 -From: "Owen W. Taylor" -Date: Tue, 8 Jul 2014 21:08:31 -0400 -Subject: [PATCH 3/4] Fix windows walking up the screen on restart - -When a window is initially created, we need to save it's user rect -after any adjustments for gravity. Otherwise, the next time the window is -queued for a resize, it will jump back to it's initial position. - -We did that for newly created windows, but on restart, when windows -were already placed, the logic skipped saving the position. Use an -explicit flag so that we always save the position for newly created -MetaWindows. ---- - src/core/constraints.h | 4 +++- - src/core/window.c | 5 +++-- - 2 files changed, 6 insertions(+), 3 deletions(-) - -diff --git a/src/core/constraints.h b/src/core/constraints.h -index 5fa1e4e..1a59724 100644 ---- a/src/core/constraints.h -+++ b/src/core/constraints.h -@@ -35,7 +35,9 @@ typedef enum - META_DO_GRAVITY_ADJUST = 1 << 1, - META_IS_USER_ACTION = 1 << 2, - META_IS_MOVE_ACTION = 1 << 3, -- META_IS_RESIZE_ACTION = 1 << 4 -+ META_IS_RESIZE_ACTION = 1 << 4, -+ META_FORCE_STATIC_GRAVITY = 1 << 5, -+ META_IS_INITIAL_RESIZE = 1 << 6 - } MetaMoveResizeFlags; - - void meta_window_constrain (MetaWindow *window, -diff --git a/src/core/window.c b/src/core/window.c -index 60347ef..8d221e3 100644 ---- a/src/core/window.c -+++ b/src/core/window.c -@@ -1430,7 +1430,7 @@ meta_window_new_with_attrs (MetaDisplay *display, - * initial map is handled same as configure request - */ - flags = -- META_IS_CONFIGURE_REQUEST | META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION; -+ META_IS_CONFIGURE_REQUEST | META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION | META_IS_INITIAL_RESIZE; - if (!window->override_redirect) - meta_window_move_resize_internal (window, - flags, -@@ -5316,7 +5316,8 @@ meta_window_move_resize_internal (MetaWindow *window, - if (need_configure_notify) - send_configure_notify (window); - -- if (!window->placed && window->force_save_user_rect && !window->fullscreen) -+ if (((flags & META_IS_INITIAL_RESIZE) != 0 || !window->placed) && -+ window->force_save_user_rect && !window->fullscreen) - force_save_user_window_placement (window); - else if (is_user_action) - save_user_window_placement (window); --- -1.9.3 - diff --git a/SOURCES/0003-window-Properly-update-window-monitor-for-the-deskto.patch b/SOURCES/0003-window-Properly-update-window-monitor-for-the-deskto.patch new file mode 100644 index 0000000..dec8277 --- /dev/null +++ b/SOURCES/0003-window-Properly-update-window-monitor-for-the-deskto.patch @@ -0,0 +1,34 @@ +From 54771511fe477eafbb4c28e8c7ddc2455cfc7283 Mon Sep 17 00:00:00 2001 +From: Rui Matos +Date: Sat, 24 Oct 2015 18:46:12 +0200 +Subject: [PATCH 3/4] window: Properly update window->monitor for the desktop + window + +We don't want to move the desktop window but we still need to update +window->monitor or otherwise we'll be left with a pointer to invalid +memory. +--- + src/core/window.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +diff --git a/src/core/window.c b/src/core/window.c +index f9fae9e..faa0296 100644 +--- a/src/core/window.c ++++ b/src/core/window.c +@@ -3513,12 +3513,9 @@ meta_window_update_for_monitors_changed (MetaWindow *window) + { + const MetaMonitorInfo *old, *new; + +- if (window->type == META_WINDOW_DESKTOP) +- return; +- + old = window->monitor; + +- if (!old || window->screen->n_monitor_infos == 0 || window->override_redirect) ++ if (!old || window->screen->n_monitor_infos == 0 || window->override_redirect || window->type == META_WINDOW_DESKTOP) + { + meta_window_update_monitor (window, FALSE); + return; +-- +2.5.0 + diff --git a/SOURCES/0004-Leave-windows-in-place-on-a-crash-respawn.patch b/SOURCES/0004-Leave-windows-in-place-on-a-crash-respawn.patch deleted file mode 100644 index def0321..0000000 --- a/SOURCES/0004-Leave-windows-in-place-on-a-crash-respawn.patch +++ /dev/null @@ -1,162 +0,0 @@ -From 443608282901a16565ef01e70d3fb1f66beb14f5 Mon Sep 17 00:00:00 2001 -From: "Owen W. Taylor" -Date: Tue, 8 Jul 2014 21:35:47 -0400 -Subject: [PATCH 4/4] Leave windows in place on a crash respawn - -When Mutter is restarted and cleans up the window positions -cleanly, we need to add gravity adjustments. We can detect -this easily. - - - Windows started before the window manager (should add - add gravity adjustments) - - Replacing a different window manager (should add gravity - adjustments) - - A crash (no adjustments needed) - -In GNOME the first two cases shouldn't happen in normal -usage, so assume the third case (though that *shouldn't* -happen in normal usage either.) ---- - src/core/display.c | 4 ++-- - src/core/screen.c | 2 +- - src/core/window-private.h | 3 ++- - src/core/window.c | 33 ++++++++++++++++++++++++++------- - 4 files changed, 31 insertions(+), 11 deletions(-) - -diff --git a/src/core/display.c b/src/core/display.c -index 9ed0f6e..90888c5 100644 ---- a/src/core/display.c -+++ b/src/core/display.c -@@ -2613,14 +2613,14 @@ event_callback (XEvent *event, - && meta_display_screen_for_root (display, event->xmap.event)) - { - window = meta_window_new (display, event->xmap.window, -- FALSE); -+ FALSE, FALSE); - } - break; - case MapRequest: - if (window == NULL) - { - window = meta_window_new (display, event->xmaprequest.window, -- FALSE); -+ FALSE, FALSE); - } - /* if frame was receiver it's some malicious send event or something */ - else if (!frame_was_receiver && window) -diff --git a/src/core/screen.c b/src/core/screen.c -index 6db3ea3..6d8d018 100644 ---- a/src/core/screen.c -+++ b/src/core/screen.c -@@ -1093,7 +1093,7 @@ meta_screen_manage_all_windows (MetaScreen *screen) - WindowInfo *info = list->data; - - meta_window_new_with_attrs (screen->display, info->xwindow, TRUE, -- META_COMP_EFFECT_NONE, -+ TRUE, - &info->attrs); - } - meta_stack_thaw (screen->stack); -diff --git a/src/core/window-private.h b/src/core/window-private.h -index e9f935f..cc77861 100644 ---- a/src/core/window-private.h -+++ b/src/core/window-private.h -@@ -481,11 +481,12 @@ struct _MetaWindowClass - - MetaWindow* meta_window_new (MetaDisplay *display, - Window xwindow, -+ gboolean managing_screen, - gboolean must_be_viewable); - MetaWindow* meta_window_new_with_attrs (MetaDisplay *display, - Window xwindow, -+ gboolean managing_screen, - gboolean must_be_viewable, -- MetaCompEffect effect, - XWindowAttributes *attrs); - void meta_window_unmanage (MetaWindow *window, - guint32 timestamp); -diff --git a/src/core/window.c b/src/core/window.c -index 8d221e3..8a290f3 100644 ---- a/src/core/window.c -+++ b/src/core/window.c -@@ -40,6 +40,7 @@ - #include "keybindings-private.h" - #include "ui.h" - #include "place.h" -+#include - #include "session.h" - #include - #include "resizepopup.h" -@@ -659,6 +660,7 @@ maybe_leave_show_desktop_mode (MetaWindow *window) - MetaWindow* - meta_window_new (MetaDisplay *display, - Window xwindow, -+ gboolean managing_screen, - gboolean must_be_viewable) - { - XWindowAttributes attrs; -@@ -682,8 +684,8 @@ meta_window_new (MetaDisplay *display, - return NULL; - } - window = meta_window_new_with_attrs (display, xwindow, -+ managing_screen, - must_be_viewable, -- META_COMP_EFFECT_CREATE, - &attrs); - } - else -@@ -815,8 +817,8 @@ meta_window_should_attach_to_parent (MetaWindow *window) - MetaWindow* - meta_window_new_with_attrs (MetaDisplay *display, - Window xwindow, -+ gboolean managing_screen, - gboolean must_be_viewable, -- MetaCompEffect effect, - XWindowAttributes *attrs) - { - MetaWindow *window; -@@ -827,6 +829,8 @@ meta_window_new_with_attrs (MetaDisplay *display, - MetaMoveResizeFlags flags; - gboolean has_shape; - MetaScreen *screen; -+ MetaCompEffect effect = -+ managing_screen ? META_COMP_EFFECT_NONE : META_COMP_EFFECT_CREATE; - - g_assert (attrs != NULL); - -@@ -1425,12 +1429,27 @@ meta_window_new_with_attrs (MetaDisplay *display, - else - window->layer = META_LAYER_OVERRIDE_REDIRECT; /* otherwise set by MetaStack */ - -- /* Put our state back where it should be, -- * passing TRUE for is_configure_request, ICCCM says -- * initial map is handled same as configure request -- */ - flags = -- META_IS_CONFIGURE_REQUEST | META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION | META_IS_INITIAL_RESIZE; -+ META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION | META_IS_INITIAL_RESIZE; -+ -+ /* ICCCM says initial map is handled same as configure request. When -+ * we are initially managing the screen, we distinguish two cases: -+ * -+ * Restart: in this case, we put the windows back to the unframed -+ * position before exiting, so we need to give them gravity -+ * adjustments. -+ * Something else: (perhaps a crash) if we didn't exit cleanly, then -+ * windows will be reparented by the X server so that the client -+ * origin stays the same, and no frame adjustment is needed. -+ * -+ * We don't have any way to distinguish replacing a different window -+ * manager from respawning on crash, so when we replace a different -+ * window manager, windows will shift onscreen, but this is expected -+ * to only happen in development. -+ */ -+ if (!managing_screen || meta_is_restart()) -+ flags |= META_IS_CONFIGURE_REQUEST; -+ - if (!window->override_redirect) - meta_window_move_resize_internal (window, - flags, --- -1.9.3 - diff --git a/SOURCES/0004-monitor-manager-xrandr-Force-an-update-when-resuming.patch b/SOURCES/0004-monitor-manager-xrandr-Force-an-update-when-resuming.patch new file mode 100644 index 0000000..5bbbe6c --- /dev/null +++ b/SOURCES/0004-monitor-manager-xrandr-Force-an-update-when-resuming.patch @@ -0,0 +1,277 @@ +From 0a205c86df3422c4918d225c29adc0a06bc4e2d5 Mon Sep 17 00:00:00 2001 +From: Rui Matos +Date: Sun, 25 Oct 2015 16:14:58 +0100 +Subject: [PATCH 4/4] monitor-manager-xrandr: Force an update when resuming + from suspend + +The stack below us isn't as reliable as we'd like and in some cases +doesn't generate RRScreenChangeNotify events when e.g. resuming a +laptop on a dock, meaning that we'd miss newly attached outputs. +--- + src/backends/x11/meta-monitor-manager-xrandr.c | 215 +++++++++++++++++-------- + 1 file changed, 151 insertions(+), 64 deletions(-) + +diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c +index 9a64bb2..d2a5df2 100644 +--- a/src/backends/x11/meta-monitor-manager-xrandr.c ++++ b/src/backends/x11/meta-monitor-manager-xrandr.c +@@ -59,6 +59,11 @@ struct _MetaMonitorManagerXrandr + XRRScreenResources *resources; + int rr_event_base; + int rr_error_base; ++ ++ guint logind_watch_id; ++ guint logind_signal_sub_id; ++ ++ gboolean need_hardware_poll; + }; + + struct _MetaMonitorManagerXrandrClass +@@ -506,8 +511,15 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager) + manager->screen_width = WidthOfScreen (screen); + manager->screen_height = HeightOfScreen (screen); + +- resources = XRRGetScreenResourcesCurrent (manager_xrandr->xdisplay, +- DefaultRootWindow (manager_xrandr->xdisplay)); ++ if (manager_xrandr->need_hardware_poll) ++ { ++ resources = XRRGetScreenResources (manager_xrandr->xdisplay, ++ DefaultRootWindow (manager_xrandr->xdisplay)); ++ manager_xrandr->need_hardware_poll = FALSE; ++ } ++ else ++ resources = XRRGetScreenResourcesCurrent (manager_xrandr->xdisplay, ++ DefaultRootWindow (manager_xrandr->xdisplay)); + if (!resources) + return; + +@@ -1083,60 +1095,6 @@ meta_monitor_manager_xrandr_rebuild_derived (MetaMonitorManager *manager) + meta_monitor_manager_rebuild_derived (manager); + } + +-static void +-meta_monitor_manager_xrandr_init (MetaMonitorManagerXrandr *manager_xrandr) +-{ +- MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ()); +- +- manager_xrandr->xdisplay = meta_backend_x11_get_xdisplay (backend); +- +- if (!XRRQueryExtension (manager_xrandr->xdisplay, +- &manager_xrandr->rr_event_base, +- &manager_xrandr->rr_error_base)) +- { +- return; +- } +- else +- { +- /* We only use ScreenChangeNotify, but GDK uses the others, +- and we don't want to step on its toes */ +- XRRSelectInput (manager_xrandr->xdisplay, +- DefaultRootWindow (manager_xrandr->xdisplay), +- RRScreenChangeNotifyMask +- | RRCrtcChangeNotifyMask +- | RROutputPropertyNotifyMask); +- } +-} +- +-static void +-meta_monitor_manager_xrandr_finalize (GObject *object) +-{ +- MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (object); +- +- if (manager_xrandr->resources) +- XRRFreeScreenResources (manager_xrandr->resources); +- manager_xrandr->resources = NULL; +- +- G_OBJECT_CLASS (meta_monitor_manager_xrandr_parent_class)->finalize (object); +-} +- +-static void +-meta_monitor_manager_xrandr_class_init (MetaMonitorManagerXrandrClass *klass) +-{ +- MetaMonitorManagerClass *manager_class = META_MONITOR_MANAGER_CLASS (klass); +- GObjectClass *object_class = G_OBJECT_CLASS (klass); +- +- object_class->finalize = meta_monitor_manager_xrandr_finalize; +- +- manager_class->read_current = meta_monitor_manager_xrandr_read_current; +- manager_class->read_edid = meta_monitor_manager_xrandr_read_edid; +- manager_class->apply_configuration = meta_monitor_manager_xrandr_apply_configuration; +- manager_class->set_power_save_mode = meta_monitor_manager_xrandr_set_power_save_mode; +- manager_class->change_backlight = meta_monitor_manager_xrandr_change_backlight; +- manager_class->get_crtc_gamma = meta_monitor_manager_xrandr_get_crtc_gamma; +- manager_class->set_crtc_gamma = meta_monitor_manager_xrandr_set_crtc_gamma; +-} +- + static gboolean + is_xvnc (MetaMonitorManager *manager) + { +@@ -1149,9 +1107,8 @@ is_xvnc (MetaMonitorManager *manager) + return FALSE; + } + +-gboolean +-meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xrandr, +- XEvent *event) ++static void ++meta_monitor_manager_xrandr_update (MetaMonitorManagerXrandr *manager_xrandr) + { + MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_xrandr); + MetaOutput *old_outputs; +@@ -1162,11 +1119,6 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xra + gboolean applied_config = FALSE; + unsigned int timestamp; + +- if ((event->type - manager_xrandr->rr_event_base) != RRScreenChangeNotify) +- return FALSE; +- +- XRRUpdateConfiguration (event); +- + /* Save the old structures, so they stay valid during the update */ + old_outputs = manager->outputs; + n_old_outputs = manager->n_outputs; +@@ -1210,6 +1162,141 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xra + meta_monitor_manager_free_output_array (old_outputs, n_old_outputs); + meta_monitor_manager_free_mode_array (old_modes, n_old_modes); + g_free (old_crtcs); ++} ++ ++static void ++logind_signal_handler (GDBusConnection *connection, ++ const gchar *sender_name, ++ const gchar *object_path, ++ const gchar *interface_name, ++ const gchar *signal_name, ++ GVariant *parameters, ++ gpointer user_data) ++{ ++ MetaMonitorManagerXrandr *manager_xrandr = user_data; ++ gboolean suspending; ++ ++ if (!g_str_equal (signal_name, "PrepareForSleep")) ++ return; ++ ++ g_variant_get (parameters, "(b)", &suspending); ++ if (!suspending) ++ { ++ manager_xrandr->need_hardware_poll = TRUE; ++ meta_monitor_manager_xrandr_update (manager_xrandr); ++ } ++} ++ ++static void ++logind_appeared (GDBusConnection *connection, ++ const gchar *name, ++ const gchar *name_owner, ++ gpointer user_data) ++{ ++ MetaMonitorManagerXrandr *manager_xrandr = user_data; ++ ++ manager_xrandr->logind_signal_sub_id = g_dbus_connection_signal_subscribe (connection, ++ "org.freedesktop.login1", ++ "org.freedesktop.login1.Manager", ++ "PrepareForSleep", ++ "/org/freedesktop/login1", ++ NULL, ++ G_DBUS_SIGNAL_FLAGS_NONE, ++ logind_signal_handler, ++ manager_xrandr, ++ NULL); ++} ++ ++static void ++logind_vanished (GDBusConnection *connection, ++ const gchar *name, ++ gpointer user_data) ++{ ++ MetaMonitorManagerXrandr *manager_xrandr = user_data; ++ ++ if (connection && manager_xrandr->logind_signal_sub_id > 0) ++ g_dbus_connection_signal_unsubscribe (connection, manager_xrandr->logind_signal_sub_id); ++ ++ manager_xrandr->logind_signal_sub_id = 0; ++} ++ ++static void ++meta_monitor_manager_xrandr_init (MetaMonitorManagerXrandr *manager_xrandr) ++{ ++ MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ()); ++ ++ manager_xrandr->xdisplay = meta_backend_x11_get_xdisplay (backend); ++ ++ if (!XRRQueryExtension (manager_xrandr->xdisplay, ++ &manager_xrandr->rr_event_base, ++ &manager_xrandr->rr_error_base)) ++ { ++ return; ++ } ++ else ++ { ++ /* We only use ScreenChangeNotify, but GDK uses the others, ++ and we don't want to step on its toes */ ++ XRRSelectInput (manager_xrandr->xdisplay, ++ DefaultRootWindow (manager_xrandr->xdisplay), ++ RRScreenChangeNotifyMask ++ | RRCrtcChangeNotifyMask ++ | RROutputPropertyNotifyMask); ++ } ++ ++ manager_xrandr->logind_watch_id = g_bus_watch_name (G_BUS_TYPE_SYSTEM, ++ "org.freedesktop.login1", ++ G_BUS_NAME_WATCHER_FLAGS_NONE, ++ logind_appeared, ++ logind_vanished, ++ manager_xrandr, ++ NULL); ++ manager_xrandr->need_hardware_poll = TRUE; ++} ++ ++static void ++meta_monitor_manager_xrandr_finalize (GObject *object) ++{ ++ MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (object); ++ ++ if (manager_xrandr->resources) ++ XRRFreeScreenResources (manager_xrandr->resources); ++ manager_xrandr->resources = NULL; ++ ++ if (manager_xrandr->logind_watch_id > 0) ++ g_bus_unwatch_name (manager_xrandr->logind_watch_id); ++ manager_xrandr->logind_watch_id = 0; ++ ++ G_OBJECT_CLASS (meta_monitor_manager_xrandr_parent_class)->finalize (object); ++} ++ ++static void ++meta_monitor_manager_xrandr_class_init (MetaMonitorManagerXrandrClass *klass) ++{ ++ MetaMonitorManagerClass *manager_class = META_MONITOR_MANAGER_CLASS (klass); ++ GObjectClass *object_class = G_OBJECT_CLASS (klass); ++ ++ object_class->finalize = meta_monitor_manager_xrandr_finalize; ++ ++ manager_class->read_current = meta_monitor_manager_xrandr_read_current; ++ manager_class->read_edid = meta_monitor_manager_xrandr_read_edid; ++ manager_class->apply_configuration = meta_monitor_manager_xrandr_apply_configuration; ++ manager_class->set_power_save_mode = meta_monitor_manager_xrandr_set_power_save_mode; ++ manager_class->change_backlight = meta_monitor_manager_xrandr_change_backlight; ++ manager_class->get_crtc_gamma = meta_monitor_manager_xrandr_get_crtc_gamma; ++ manager_class->set_crtc_gamma = meta_monitor_manager_xrandr_set_crtc_gamma; ++} ++ ++gboolean ++meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xrandr, ++ XEvent *event) ++{ ++ if ((event->type - manager_xrandr->rr_event_base) != RRScreenChangeNotify) ++ return FALSE; ++ ++ XRRUpdateConfiguration (event); ++ ++ meta_monitor_manager_xrandr_update (manager_xrandr); + + return TRUE; + } +-- +2.5.0 + diff --git a/SOURCES/MetaWindowGroup-fix-paint-volume.patch b/SOURCES/MetaWindowGroup-fix-paint-volume.patch deleted file mode 100644 index c685323..0000000 --- a/SOURCES/MetaWindowGroup-fix-paint-volume.patch +++ /dev/null @@ -1,54 +0,0 @@ -From a796938b3991535ac9b5e79436ce1dbf1da72904 Mon Sep 17 00:00:00 2001 -From: "Owen W. Taylor" -Date: Tue, 3 Dec 2013 00:27:03 -0500 -Subject: [PATCH] MetaWindowGroup: fix paint volume - -In the past, MetaWindowGroup was allocated the size of the screen and -painted the size of the screen because it contained the screen background, -but now we also have the "top window group" which contains only popup -windows, so the allocation doesn't properly reflect the paint bounds -of the window group. Compute the paint bounds accurately from the -children. - -https://bugzilla.gnome.org/show_bug.cgi?id=719669 ---- - src/compositor/meta-window-group.c | 23 +++++++++++++++++++++-- - 1 file changed, 21 insertions(+), 2 deletions(-) - - -diff -up mutter-3.8.4/src/compositor/meta-window-group.c.window-group-paint-volume mutter-3.8.4/src/compositor/meta-window-group.c ---- mutter-3.8.4/src/compositor/meta-window-group.c.window-group-paint-volume 2014-02-11 11:36:22.448065800 -0500 -+++ mutter-3.8.4/src/compositor/meta-window-group.c 2014-02-11 11:40:28.723506360 -0500 -@@ -250,11 +250,30 @@ meta_window_group_paint (ClutterActor *a - g_list_free (children); - } - -+/* Adapted from clutter_actor_update_default_paint_volume() */ - static gboolean --meta_window_group_get_paint_volume (ClutterActor *actor, -+meta_window_group_get_paint_volume (ClutterActor *self, - ClutterPaintVolume *volume) - { -- return clutter_paint_volume_set_from_allocation (volume, actor); -+ ClutterActorIter iter; -+ ClutterActor *child; -+ -+ clutter_actor_iter_init (&iter, self); -+ while (clutter_actor_iter_next (&iter, &child)) -+ { -+ const ClutterPaintVolume *child_volume; -+ -+ if (!CLUTTER_ACTOR_IS_MAPPED (child)) -+ continue; -+ -+ child_volume = clutter_actor_get_transformed_paint_volume (child, self); -+ if (child_volume == NULL) -+ return FALSE; -+ -+ clutter_paint_volume_union (volume, child_volume); -+ } -+ -+ return TRUE; - } - - static void diff --git a/SOURCES/deal-more-gracefully-with-oversized-windows.patch b/SOURCES/deal-more-gracefully-with-oversized-windows.patch index ff248ce..f5caaad 100644 --- a/SOURCES/deal-more-gracefully-with-oversized-windows.patch +++ b/SOURCES/deal-more-gracefully-with-oversized-windows.patch @@ -1,52 +1,19 @@ -From 45b76b121a6f7fd01742b78f9c44a48a3caffbf0 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Florian=20M=C3=BCllner?= -Date: Fri, 10 Jan 2014 06:26:57 -0500 -Subject: [PATCH 1/2] window-actor: Guard against %NULL frame mask - -Creating a new cogl texture may fail, in which case the intent to -free it will crash. While something is clearly wrong (insanely -large window, oom, ...), crashing the WM is harsh and we should -try to avoid it if at all possible, so carry on. - -https://bugzilla.gnome.org/show_bug.cgi?id=722266 ---- - src/compositor/meta-window-actor.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c -index 42d1257..055b413 100644 ---- a/src/compositor/meta-window-actor.c -+++ b/src/compositor/meta-window-actor.c -@@ -2181,7 +2181,8 @@ build_and_scan_frame_mask (MetaWindowActor *self, - - meta_shaped_texture_set_mask_texture (META_SHAPED_TEXTURE (priv->actor), - mask_texture); -- cogl_object_unref (mask_texture); -+ if (mask_texture) -+ cogl_object_unref (mask_texture); - - g_free (mask_data); - } --- -1.9.0 - - -From bd6fa34598b774de36c4c65d2cfa577c24f18722 Mon Sep 17 00:00:00 2001 +From 7db4306b3ca67f651466f26302f013504f70a464 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 12 Mar 2014 02:04:13 +0100 -Subject: [PATCH 2/2] constraints: Enforce X11 size limits +Subject: [PATCH] constraints: Enforce X11 size limits X11 limits windows to a maximum of 32767x32767, enforce that restriction to keep insanely huge windows from crashing the WM. --- - src/core/constraints.c | 39 +++++++++++++++++++++++++++++++++++++++ - 1 file changed, 39 insertions(+) + src/core/constraints.c | 42 ++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 42 insertions(+) diff --git a/src/core/constraints.c b/src/core/constraints.c -index 606baea..2a510e0 100644 +index d0ac4fa..9f5f127 100644 --- a/src/core/constraints.c +++ b/src/core/constraints.c -@@ -104,6 +104,7 @@ typedef enum +@@ -102,6 +102,7 @@ typedef enum PRIORITY_SIZE_HINTS_LIMITS = 3, PRIORITY_TITLEBAR_VISIBLE = 4, PRIORITY_PARTIALLY_VISIBLE_ON_WORKAREA = 4, @@ -54,7 +21,7 @@ index 606baea..2a510e0 100644 PRIORITY_MAXIMUM = 4 /* Dummy value used for loop end = max(all priorities) */ } ConstraintPriority; -@@ -192,6 +193,10 @@ static gboolean constrain_partially_onscreen (MetaWindow *window, +@@ -188,6 +189,10 @@ static gboolean constrain_partially_onscreen (MetaWindow *window, ConstraintInfo *info, ConstraintPriority priority, gboolean check_only); @@ -65,7 +32,7 @@ index 606baea..2a510e0 100644 static void setup_constraint_info (ConstraintInfo *info, MetaWindow *window, -@@ -236,6 +241,7 @@ static const Constraint all_constraints[] = { +@@ -222,6 +227,7 @@ static const Constraint all_constraints[] = { {constrain_fully_onscreen, "constrain_fully_onscreen"}, {constrain_titlebar_visible, "constrain_titlebar_visible"}, {constrain_partially_onscreen, "constrain_partially_onscreen"}, @@ -73,7 +40,7 @@ index 606baea..2a510e0 100644 {NULL, NULL} }; -@@ -1518,3 +1524,36 @@ constrain_partially_onscreen (MetaWindow *window, +@@ -1429,3 +1435,39 @@ constrain_partially_onscreen (MetaWindow *window, return retval; } @@ -93,13 +60,16 @@ index 606baea..2a510e0 100644 + if (priority > PRIORITY_XLIMITS) + return TRUE; + -+ max_w = MAX_WINDOW_SIZE; -+ if (window->frame) -+ max_w -= (info->borders->total.left + info->borders->total.right); ++ max_w = max_h = MAX_WINDOW_SIZE; + -+ max_h = MAX_WINDOW_SIZE; + if (window->frame) -+ max_h -= (info->borders->total.top + info->borders->total.bottom); ++ { ++ MetaFrameBorders borders; ++ meta_frame_calc_borders (window->frame, &borders); ++ ++ max_w -= (borders.total.left + borders.total.right); ++ max_h -= (borders.total.top + borders.total.bottom); ++ } + + constraint_already_satisfied = info->current.width < max_w && info->current.height < max_h; + if (check_only || constraint_already_satisfied) @@ -111,5 +81,5 @@ index 606baea..2a510e0 100644 + return TRUE; +} -- -1.9.0 +2.3.3 diff --git a/SOURCES/fix-nvidia-screen-flickering.patch b/SOURCES/fix-nvidia-screen-flickering.patch new file mode 100644 index 0000000..98667a0 --- /dev/null +++ b/SOURCES/fix-nvidia-screen-flickering.patch @@ -0,0 +1,1160 @@ +From e13f43987b9cd3320441816de0b6b570be95c01f Mon Sep 17 00:00:00 2001 +From: Calvin Walton +Date: Tue, 24 Mar 2015 11:21:25 -0400 +Subject: [PATCH 1/5] Include libXrender as a dependency, link it to libmutter + +Mutter uses a function from libXrender (XRenderFindStandardFormat in +src/x11/iconcache.c), but doesn't link to libXrender. This causes +link issues on systems using the gold linker, particularly with +-Wl,--as-needed. + +Since mutter is using a function from libXrender, adding 'xrender' +as a dependency seems appropriate, and fixes the issue. + +https://bugzilla.gnome.org/show_bug.cgi?id=746692 +--- + configure.ac | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/configure.ac b/configure.ac +index 74f4eeb..d193606 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -88,6 +88,7 @@ MUTTER_PC_MODULES=" + xi >= 1.6.0 + xkbfile + xkeyboard-config ++ xrender + xcb-randr + " + +-- +2.5.0 + + +From 04173777a23549eea3823516483909112ac77303 Mon Sep 17 00:00:00 2001 +From: Rui Matos +Date: Fri, 18 Apr 2014 20:21:20 +0200 +Subject: [PATCH 2/5] compositor: Add support for GL_EXT_x11_sync_object + +If GL advertises this extension we'll use it to synchronize X with GL +rendering instead of relying on the XSync() behavior with open source +drivers. + +Some driver bugs were uncovered while working on this so if we have +had to reboot the ring a few times, something is probably wrong and +we're likely to just make things worse by continuing to try. Let's +err on the side of caution, disable ourselves and fallback to the +XSync() path in the compositor. + +https://bugzilla.gnome.org/show_bug.cgi?id=728464 +--- + configure.ac | 5 + + src/Makefile.am | 2 + + src/backends/x11/meta-backend-x11.c | 3 + + src/compositor/compositor-private.h | 4 +- + src/compositor/compositor.c | 71 +++-- + src/compositor/meta-sync-ring.c | 566 ++++++++++++++++++++++++++++++++++++ + src/compositor/meta-sync-ring.h | 14 + + 7 files changed, 641 insertions(+), 24 deletions(-) + create mode 100644 src/compositor/meta-sync-ring.c + create mode 100644 src/compositor/meta-sync-ring.h + +diff --git a/configure.ac b/configure.ac +index d193606..fe1c1eb 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -312,6 +312,11 @@ fi + + GTK_DOC_CHECK([1.15], [--flavour no-tmpl]) + ++AC_CHECK_DECL([GL_EXT_x11_sync_object], ++ [], ++ [AC_MSG_ERROR([GL_EXT_x11_sync_object definition not found, please update your GL headers])], ++ [#include ]) ++ + #### Warnings (last since -Werror can disturb other tests) + + # Stay command-line compatible with the gnome-common configure option. Here +diff --git a/src/Makefile.am b/src/Makefile.am +index e73a053..d7a44bc 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -126,6 +126,8 @@ libmutter_la_SOURCES = \ + compositor/meta-surface-actor.h \ + compositor/meta-surface-actor-x11.c \ + compositor/meta-surface-actor-x11.h \ ++ compositor/meta-sync-ring.c \ ++ compositor/meta-sync-ring.h \ + compositor/meta-texture-rectangle.c \ + compositor/meta-texture-rectangle.h \ + compositor/meta-texture-tower.c \ +diff --git a/src/backends/x11/meta-backend-x11.c b/src/backends/x11/meta-backend-x11.c +index 586f991..d77365d 100644 +--- a/src/backends/x11/meta-backend-x11.c ++++ b/src/backends/x11/meta-backend-x11.c +@@ -43,6 +43,7 @@ + #include + #include "display-private.h" + #include "compositor/compositor-private.h" ++#include "compositor/meta-sync-ring.h" + + struct _MetaBackendX11Private + { +@@ -183,6 +184,8 @@ handle_host_xevent (MetaBackend *backend, + MetaCompositor *compositor = display->compositor; + if (meta_plugin_manager_xevent_filter (compositor->plugin_mgr, event)) + bypass_clutter = TRUE; ++ if (compositor->have_x11_sync_object) ++ meta_sync_ring_handle_event (event); + } + } + +diff --git a/src/compositor/compositor-private.h b/src/compositor/compositor-private.h +index 80fb4e2..9e3e73d 100644 +--- a/src/compositor/compositor-private.h ++++ b/src/compositor/compositor-private.h +@@ -15,7 +15,8 @@ struct _MetaCompositor + { + MetaDisplay *display; + +- guint repaint_func_id; ++ guint pre_paint_func_id; ++ guint post_paint_func_id; + + gint64 server_time_query_time; + gint64 server_time_offset; +@@ -40,6 +41,7 @@ struct _MetaCompositor + MetaPluginManager *plugin_mgr; + + gboolean frame_has_updated_xsurfaces; ++ gboolean have_x11_sync_object; + }; + + /* Wait 2ms after vblank before starting to draw next frame */ +diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c +index 8bf469f..554faa1 100644 +--- a/src/compositor/compositor.c ++++ b/src/compositor/compositor.c +@@ -79,6 +79,7 @@ + #include "frame.h" + #include + #include ++#include "meta-sync-ring.h" + + #include "backends/x11/meta-backend-x11.h" + +@@ -125,7 +126,11 @@ meta_switch_workspace_completed (MetaCompositor *compositor) + void + meta_compositor_destroy (MetaCompositor *compositor) + { +- clutter_threads_remove_repaint_func (compositor->repaint_func_id); ++ clutter_threads_remove_repaint_func (compositor->pre_paint_func_id); ++ clutter_threads_remove_repaint_func (compositor->post_paint_func_id); ++ ++ if (compositor->have_x11_sync_object) ++ meta_sync_ring_destroy (); + } + + static void +@@ -468,13 +473,11 @@ meta_compositor_manage (MetaCompositor *compositor) + MetaDisplay *display = compositor->display; + Display *xdisplay = display->xdisplay; + MetaScreen *screen = display->screen; ++ MetaBackend *backend = meta_get_backend (); + + meta_screen_set_cm_selection (display->screen); + +- { +- MetaBackend *backend = meta_get_backend (); +- compositor->stage = meta_backend_get_stage (backend); +- } ++ compositor->stage = meta_backend_get_stage (backend); + + /* We use connect_after() here to accomodate code in GNOME Shell that, + * when benchmarking drawing performance, connects to ::after-paint +@@ -510,7 +513,7 @@ meta_compositor_manage (MetaCompositor *compositor) + + compositor->output = screen->composite_overlay_window; + +- xwin = meta_backend_x11_get_xwindow (META_BACKEND_X11 (meta_get_backend ())); ++ xwin = meta_backend_x11_get_xwindow (META_BACKEND_X11 (backend)); + + XReparentWindow (xdisplay, xwin, compositor->output, 0, 0); + +@@ -530,6 +533,9 @@ meta_compositor_manage (MetaCompositor *compositor) + * contents until we show the stage. + */ + XMapWindow (xdisplay, compositor->output); ++ ++ compositor->have_x11_sync_object = ++ meta_sync_ring_init (meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend))); + } + + redirect_windows (display->screen); +@@ -1044,11 +1050,12 @@ frame_callback (CoglOnscreen *onscreen, + } + } + +-static void +-pre_paint_windows (MetaCompositor *compositor) ++static gboolean ++meta_pre_paint_func (gpointer data) + { + GList *l; + MetaWindowActor *top_window; ++ MetaCompositor *compositor = data; + + if (compositor->onscreen == NULL) + { +@@ -1060,7 +1067,7 @@ pre_paint_windows (MetaCompositor *compositor) + } + + if (compositor->windows == NULL) +- return; ++ return TRUE; + + top_window = g_list_last (compositor->windows)->data; + +@@ -1077,10 +1084,12 @@ pre_paint_windows (MetaCompositor *compositor) + { + /* We need to make sure that any X drawing that happens before + * the XDamageSubtract() for each window above is visible to +- * subsequent GL rendering; the only standardized way to do this +- * is EXT_x11_sync_object, which isn't yet widely available. For +- * now, we count on details of Xorg and the open source drivers, +- * and hope for the best otherwise. ++ * subsequent GL rendering; the standardized way to do this is ++ * GL_EXT_X11_sync_object. Since this isn't implemented yet in ++ * mesa, we also have a path that relies on the implementation ++ * of the open source drivers. ++ * ++ * Anything else, we just hope for the best. + * + * Xorg and open source driver specifics: + * +@@ -1095,18 +1104,28 @@ pre_paint_windows (MetaCompositor *compositor) + * round trip request at this point is sufficient to flush the + * GLX buffers. + */ +- XSync (compositor->display->xdisplay, False); +- +- compositor->frame_has_updated_xsurfaces = FALSE; ++ if (compositor->have_x11_sync_object) ++ compositor->have_x11_sync_object = meta_sync_ring_insert_wait (); ++ else ++ XSync (compositor->display->xdisplay, False); + } ++ ++ return TRUE; + } + + static gboolean +-meta_repaint_func (gpointer data) ++meta_post_paint_func (gpointer data) + { + MetaCompositor *compositor = data; +- if (meta_screen_get_n_monitors (compositor->display->screen) > 0) +- pre_paint_windows (compositor); ++ ++ if (compositor->frame_has_updated_xsurfaces) ++ { ++ if (compositor->have_x11_sync_object) ++ compositor->have_x11_sync_object = meta_sync_ring_after_frame (); ++ ++ compositor->frame_has_updated_xsurfaces = FALSE; ++ } ++ + return TRUE; + } + +@@ -1141,10 +1160,16 @@ meta_compositor_new (MetaDisplay *display) + G_CALLBACK (on_shadow_factory_changed), + compositor); + +- compositor->repaint_func_id = clutter_threads_add_repaint_func (meta_repaint_func, +- compositor, +- NULL); +- ++ compositor->pre_paint_func_id = ++ clutter_threads_add_repaint_func_full (CLUTTER_REPAINT_FLAGS_PRE_PAINT, ++ meta_pre_paint_func, ++ compositor, ++ NULL); ++ compositor->post_paint_func_id = ++ clutter_threads_add_repaint_func_full (CLUTTER_REPAINT_FLAGS_POST_PAINT, ++ meta_post_paint_func, ++ compositor, ++ NULL); + return compositor; + } + +diff --git a/src/compositor/meta-sync-ring.c b/src/compositor/meta-sync-ring.c +new file mode 100644 +index 0000000..4ee61f8 +--- /dev/null ++++ b/src/compositor/meta-sync-ring.c +@@ -0,0 +1,566 @@ ++/* ++ * This is based on an original C++ implementation for compiz that ++ * carries the following copyright notice: ++ * ++ * ++ * Copyright © 2011 NVIDIA Corporation ++ * ++ * Permission to use, copy, modify, distribute, and sell this software ++ * and its documentation for any purpose is hereby granted without ++ * fee, provided that the above copyright notice appear in all copies ++ * and that both that copyright notice and this permission notice ++ * appear in supporting documentation, and that the name of NVIDIA ++ * Corporation not be used in advertising or publicity pertaining to ++ * distribution of the software without specific, written prior ++ * permission. NVIDIA Corporation makes no representations about the ++ * suitability of this software for any purpose. It is provided "as ++ * is" without express or implied warranty. ++ * ++ * NVIDIA CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS ++ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND ++ * FITNESS, IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY ++ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN ++ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING ++ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS ++ * SOFTWARE. ++ * ++ * Authors: James Jones ++ */ ++ ++#include ++ ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include ++ ++#include "meta-sync-ring.h" ++ ++/* Theory of operation: ++ * ++ * We use a ring of NUM_SYNCS fence objects. On each frame we advance ++ * to the next fence in the ring. For each fence we do: ++ * ++ * 1. fence is XSyncTriggerFence()'d and glWaitSync()'d ++ * 2. NUM_SYNCS / 2 frames later, fence should be triggered ++ * 3. fence is XSyncResetFence()'d ++ * 4. NUM_SYNCS / 2 frames later, fence should be reset ++ * 5. go back to 1 and re-use fence ++ * ++ * glClientWaitSync() and XAlarms are used in steps 2 and 4, ++ * respectively, to double-check the expectections. ++ */ ++ ++#define NUM_SYNCS 10 ++#define MAX_SYNC_WAIT_TIME (1 * 1000 * 1000 * 1000) /* one sec */ ++#define MAX_REBOOT_ATTEMPTS 2 ++ ++typedef enum ++{ ++ META_SYNC_STATE_READY, ++ META_SYNC_STATE_WAITING, ++ META_SYNC_STATE_DONE, ++ META_SYNC_STATE_RESET_PENDING, ++} MetaSyncState; ++ ++typedef struct ++{ ++ Display *xdisplay; ++ ++ XSyncFence xfence; ++ GLsync glsync; ++ ++ XSyncCounter xcounter; ++ XSyncAlarm xalarm; ++ XSyncValue next_counter_value; ++ ++ MetaSyncState state; ++} MetaSync; ++ ++typedef struct ++{ ++ Display *xdisplay; ++ int xsync_event_base; ++ int xsync_error_base; ++ ++ GHashTable *alarm_to_sync; ++ ++ MetaSync *syncs_array[NUM_SYNCS]; ++ guint current_sync_idx; ++ MetaSync *current_sync; ++ guint warmup_syncs; ++ ++ guint reboots; ++} MetaSyncRing; ++ ++static MetaSyncRing meta_sync_ring = { 0 }; ++ ++static XSyncValue SYNC_VALUE_ZERO; ++static XSyncValue SYNC_VALUE_ONE; ++ ++static const char* (*meta_gl_get_string) (GLenum name); ++static void (*meta_gl_get_integerv) (GLenum pname, ++ GLint *params); ++static const char* (*meta_gl_get_stringi) (GLenum name, ++ GLuint index); ++static void (*meta_gl_delete_sync) (GLsync sync); ++static GLenum (*meta_gl_client_wait_sync) (GLsync sync, ++ GLbitfield flags, ++ GLuint64 timeout); ++static void (*meta_gl_wait_sync) (GLsync sync, ++ GLbitfield flags, ++ GLuint64 timeout); ++static GLsync (*meta_gl_import_sync) (GLenum external_sync_type, ++ GLintptr external_sync, ++ GLbitfield flags); ++ ++static MetaSyncRing * ++meta_sync_ring_get (void) ++{ ++ if (meta_sync_ring.reboots > MAX_REBOOT_ATTEMPTS) ++ return NULL; ++ ++ return &meta_sync_ring; ++} ++ ++static gboolean ++load_gl_symbol (const char *name, ++ void **func) ++{ ++ *func = cogl_get_proc_address (name); ++ if (!*func) ++ { ++ meta_verbose ("MetaSyncRing: failed to resolve required GL symbol \"%s\"\n", name); ++ return FALSE; ++ } ++ return TRUE; ++} ++ ++static gboolean ++check_gl_extensions (void) ++{ ++ ClutterBackend *backend; ++ CoglContext *cogl_context; ++ CoglDisplay *cogl_display; ++ CoglRenderer *cogl_renderer; ++ ++ backend = clutter_get_default_backend (); ++ cogl_context = clutter_backend_get_cogl_context (backend); ++ cogl_display = cogl_context_get_display (cogl_context); ++ cogl_renderer = cogl_display_get_renderer (cogl_display); ++ ++ switch (cogl_renderer_get_driver (cogl_renderer)) ++ { ++ case COGL_DRIVER_GL3: ++ { ++ int num_extensions, i; ++ gboolean arb_sync = FALSE; ++ gboolean x11_sync_object = FALSE; ++ ++ meta_gl_get_integerv (GL_NUM_EXTENSIONS, &num_extensions); ++ ++ for (i = 0; i < num_extensions; ++i) ++ { ++ const char *ext = meta_gl_get_stringi (GL_EXTENSIONS, i); ++ ++ if (g_strcmp0 ("GL_ARB_sync", ext) == 0) ++ arb_sync = TRUE; ++ else if (g_strcmp0 ("GL_EXT_x11_sync_object", ext) == 0) ++ x11_sync_object = TRUE; ++ } ++ ++ return arb_sync && x11_sync_object; ++ } ++ case COGL_DRIVER_GL: ++ { ++ const char *extensions = meta_gl_get_string (GL_EXTENSIONS); ++ return (extensions != NULL && ++ strstr (extensions, "GL_ARB_sync") != NULL && ++ strstr (extensions, "GL_EXT_x11_sync_object") != NULL); ++ } ++ default: ++ break; ++ } ++ ++ return FALSE; ++} ++ ++static gboolean ++load_required_symbols (void) ++{ ++ static gboolean success = FALSE; ++ ++ if (success) ++ return TRUE; ++ ++ /* We don't link against libGL directly because cogl may want to ++ * use something else. This assumes that cogl has been initialized ++ * and dynamically loaded libGL at this point. ++ */ ++ ++ if (!load_gl_symbol ("glGetString", (void **) &meta_gl_get_string)) ++ goto out; ++ if (!load_gl_symbol ("glGetIntegerv", (void **) &meta_gl_get_integerv)) ++ goto out; ++ if (!load_gl_symbol ("glGetStringi", (void **) &meta_gl_get_stringi)) ++ goto out; ++ ++ if (!check_gl_extensions ()) ++ { ++ meta_verbose ("MetaSyncRing: couldn't find required GL extensions\n"); ++ goto out; ++ } ++ ++ if (!load_gl_symbol ("glDeleteSync", (void **) &meta_gl_delete_sync)) ++ goto out; ++ if (!load_gl_symbol ("glClientWaitSync", (void **) &meta_gl_client_wait_sync)) ++ goto out; ++ if (!load_gl_symbol ("glWaitSync", (void **) &meta_gl_wait_sync)) ++ goto out; ++ if (!load_gl_symbol ("glImportSyncEXT", (void **) &meta_gl_import_sync)) ++ goto out; ++ ++ success = TRUE; ++ out: ++ return success; ++} ++ ++static void ++meta_sync_insert (MetaSync *self) ++{ ++ g_return_if_fail (self->state == META_SYNC_STATE_READY); ++ ++ XSyncTriggerFence (self->xdisplay, self->xfence); ++ XFlush (self->xdisplay); ++ ++ meta_gl_wait_sync (self->glsync, 0, GL_TIMEOUT_IGNORED); ++ ++ self->state = META_SYNC_STATE_WAITING; ++} ++ ++static GLenum ++meta_sync_check_update_finished (MetaSync *self, ++ GLuint64 timeout) ++{ ++ GLenum status = GL_WAIT_FAILED; ++ ++ switch (self->state) ++ { ++ case META_SYNC_STATE_DONE: ++ status = GL_ALREADY_SIGNALED; ++ break; ++ case META_SYNC_STATE_WAITING: ++ status = meta_gl_client_wait_sync (self->glsync, 0, timeout); ++ if (status == GL_ALREADY_SIGNALED || status == GL_CONDITION_SATISFIED) ++ self->state = META_SYNC_STATE_DONE; ++ break; ++ default: ++ break; ++ } ++ ++ g_warn_if_fail (status != GL_WAIT_FAILED); ++ ++ return status; ++} ++ ++static void ++meta_sync_reset (MetaSync *self) ++{ ++ XSyncAlarmAttributes attrs; ++ int overflow; ++ ++ g_return_if_fail (self->state == META_SYNC_STATE_DONE); ++ ++ XSyncResetFence (self->xdisplay, self->xfence); ++ ++ attrs.trigger.wait_value = self->next_counter_value; ++ ++ XSyncChangeAlarm (self->xdisplay, self->xalarm, XSyncCAValue, &attrs); ++ XSyncSetCounter (self->xdisplay, self->xcounter, self->next_counter_value); ++ ++ XSyncValueAdd (&self->next_counter_value, ++ self->next_counter_value, ++ SYNC_VALUE_ONE, ++ &overflow); ++ ++ self->state = META_SYNC_STATE_RESET_PENDING; ++} ++ ++static void ++meta_sync_handle_event (MetaSync *self, ++ XSyncAlarmNotifyEvent *event) ++{ ++ g_return_if_fail (event->alarm == self->xalarm); ++ g_return_if_fail (self->state == META_SYNC_STATE_RESET_PENDING); ++ ++ self->state = META_SYNC_STATE_READY; ++} ++ ++static MetaSync * ++meta_sync_new (Display *xdisplay) ++{ ++ MetaSync *self; ++ XSyncAlarmAttributes attrs; ++ ++ self = g_malloc0 (sizeof (MetaSync)); ++ ++ self->xdisplay = xdisplay; ++ ++ self->xfence = XSyncCreateFence (xdisplay, DefaultRootWindow (xdisplay), FALSE); ++ self->glsync = meta_gl_import_sync (GL_SYNC_X11_FENCE_EXT, self->xfence, 0); ++ ++ self->xcounter = XSyncCreateCounter (xdisplay, SYNC_VALUE_ZERO); ++ ++ attrs.trigger.counter = self->xcounter; ++ attrs.trigger.value_type = XSyncAbsolute; ++ attrs.trigger.wait_value = SYNC_VALUE_ONE; ++ attrs.trigger.test_type = XSyncPositiveTransition; ++ attrs.events = TRUE; ++ self->xalarm = XSyncCreateAlarm (xdisplay, ++ XSyncCACounter | ++ XSyncCAValueType | ++ XSyncCAValue | ++ XSyncCATestType | ++ XSyncCAEvents, ++ &attrs); ++ ++ XSyncIntToValue (&self->next_counter_value, 1); ++ ++ self->state = META_SYNC_STATE_READY; ++ ++ return self; ++} ++ ++static Bool ++alarm_event_predicate (Display *dpy, ++ XEvent *event, ++ XPointer data) ++{ ++ MetaSyncRing *ring = meta_sync_ring_get (); ++ ++ if (!ring) ++ return False; ++ ++ if (event->type == ring->xsync_event_base + XSyncAlarmNotify) ++ { ++ if (((MetaSync *) data)->xalarm == ((XSyncAlarmNotifyEvent *) event)->alarm) ++ return True; ++ } ++ return False; ++} ++ ++static void ++meta_sync_free (MetaSync *self) ++{ ++ /* When our assumptions don't hold, something has gone wrong but we ++ * don't know what, so we reboot the ring. While doing that, we ++ * trigger fences before deleting them to try to get ourselves out ++ * of a potentially stuck GPU state. ++ */ ++ switch (self->state) ++ { ++ case META_SYNC_STATE_WAITING: ++ case META_SYNC_STATE_DONE: ++ /* nothing to do */ ++ break; ++ case META_SYNC_STATE_RESET_PENDING: ++ { ++ XEvent event; ++ XIfEvent (self->xdisplay, &event, alarm_event_predicate, (XPointer) self); ++ meta_sync_handle_event (self, (XSyncAlarmNotifyEvent *) &event); ++ } ++ /* fall through */ ++ case META_SYNC_STATE_READY: ++ XSyncTriggerFence (self->xdisplay, self->xfence); ++ XFlush (self->xdisplay); ++ break; ++ default: ++ break; ++ } ++ ++ meta_gl_delete_sync (self->glsync); ++ XSyncDestroyFence (self->xdisplay, self->xfence); ++ XSyncDestroyCounter (self->xdisplay, self->xcounter); ++ XSyncDestroyAlarm (self->xdisplay, self->xalarm); ++ ++ g_free (self); ++} ++ ++gboolean ++meta_sync_ring_init (Display *xdisplay) ++{ ++ gint major, minor; ++ guint i; ++ MetaSyncRing *ring = meta_sync_ring_get (); ++ ++ if (!ring) ++ return FALSE; ++ ++ g_return_val_if_fail (xdisplay != NULL, FALSE); ++ g_return_val_if_fail (ring->xdisplay == NULL, FALSE); ++ ++ if (!load_required_symbols ()) ++ return FALSE; ++ ++ if (!XSyncQueryExtension (xdisplay, &ring->xsync_event_base, &ring->xsync_error_base) || ++ !XSyncInitialize (xdisplay, &major, &minor)) ++ return FALSE; ++ ++ XSyncIntToValue (&SYNC_VALUE_ZERO, 0); ++ XSyncIntToValue (&SYNC_VALUE_ONE, 1); ++ ++ ring->xdisplay = xdisplay; ++ ++ ring->alarm_to_sync = g_hash_table_new (NULL, NULL); ++ ++ for (i = 0; i < NUM_SYNCS; ++i) ++ { ++ MetaSync *sync = meta_sync_new (ring->xdisplay); ++ ring->syncs_array[i] = sync; ++ g_hash_table_replace (ring->alarm_to_sync, (gpointer) sync->xalarm, sync); ++ } ++ ++ ring->current_sync_idx = 0; ++ ring->current_sync = ring->syncs_array[0]; ++ ring->warmup_syncs = 0; ++ ++ return TRUE; ++} ++ ++void ++meta_sync_ring_destroy (void) ++{ ++ guint i; ++ MetaSyncRing *ring = meta_sync_ring_get (); ++ ++ if (!ring) ++ return; ++ ++ g_return_if_fail (ring->xdisplay != NULL); ++ ++ ring->current_sync_idx = 0; ++ ring->current_sync = NULL; ++ ring->warmup_syncs = 0; ++ ++ for (i = 0; i < NUM_SYNCS; ++i) ++ meta_sync_free (ring->syncs_array[i]); ++ ++ g_hash_table_destroy (ring->alarm_to_sync); ++ ++ ring->xsync_event_base = 0; ++ ring->xsync_error_base = 0; ++ ring->xdisplay = NULL; ++} ++ ++static gboolean ++meta_sync_ring_reboot (Display *xdisplay) ++{ ++ MetaSyncRing *ring = meta_sync_ring_get (); ++ ++ if (!ring) ++ return FALSE; ++ ++ meta_sync_ring_destroy (); ++ ++ ring->reboots += 1; ++ ++ if (!meta_sync_ring_get ()) ++ { ++ meta_warning ("MetaSyncRing: Too many reboots -- disabling\n"); ++ return FALSE; ++ } ++ ++ return meta_sync_ring_init (xdisplay); ++} ++ ++gboolean ++meta_sync_ring_after_frame (void) ++{ ++ MetaSyncRing *ring = meta_sync_ring_get (); ++ ++ if (!ring) ++ return FALSE; ++ ++ g_return_if_fail (ring->xdisplay != NULL); ++ ++ if (ring->warmup_syncs >= NUM_SYNCS / 2) ++ { ++ guint reset_sync_idx = (ring->current_sync_idx + NUM_SYNCS - (NUM_SYNCS / 2)) % NUM_SYNCS; ++ MetaSync *sync_to_reset = ring->syncs_array[reset_sync_idx]; ++ ++ GLenum status = meta_sync_check_update_finished (sync_to_reset, 0); ++ if (status == GL_TIMEOUT_EXPIRED) ++ { ++ meta_warning ("MetaSyncRing: We should never wait for a sync -- add more syncs?\n"); ++ status = meta_sync_check_update_finished (sync_to_reset, MAX_SYNC_WAIT_TIME); ++ } ++ ++ if (status != GL_ALREADY_SIGNALED && status != GL_CONDITION_SATISFIED) ++ { ++ meta_warning ("MetaSyncRing: Timed out waiting for sync object.\n"); ++ return meta_sync_ring_reboot (ring->xdisplay); ++ } ++ ++ meta_sync_reset (sync_to_reset); ++ } ++ else ++ { ++ ring->warmup_syncs += 1; ++ } ++ ++ ring->current_sync_idx += 1; ++ ring->current_sync_idx %= NUM_SYNCS; ++ ++ ring->current_sync = ring->syncs_array[ring->current_sync_idx]; ++ ++ return TRUE; ++} ++ ++gboolean ++meta_sync_ring_insert_wait (void) ++{ ++ MetaSyncRing *ring = meta_sync_ring_get (); ++ ++ if (!ring) ++ return FALSE; ++ ++ g_return_if_fail (ring->xdisplay != NULL); ++ ++ if (ring->current_sync->state != META_SYNC_STATE_READY) ++ { ++ meta_warning ("MetaSyncRing: Sync object is not ready -- were events handled properly?\n"); ++ if (!meta_sync_ring_reboot (ring->xdisplay)) ++ return FALSE; ++ } ++ ++ meta_sync_insert (ring->current_sync); ++ ++ return TRUE; ++} ++ ++void ++meta_sync_ring_handle_event (XEvent *xevent) ++{ ++ XSyncAlarmNotifyEvent *event; ++ MetaSync *sync; ++ MetaSyncRing *ring = meta_sync_ring_get (); ++ ++ if (!ring) ++ return; ++ ++ g_return_if_fail (ring->xdisplay != NULL); ++ ++ if (xevent->type != (ring->xsync_event_base + XSyncAlarmNotify)) ++ return; ++ ++ event = (XSyncAlarmNotifyEvent *) xevent; ++ ++ sync = g_hash_table_lookup (ring->alarm_to_sync, (gpointer) event->alarm); ++ if (sync) ++ meta_sync_handle_event (sync, event); ++} +diff --git a/src/compositor/meta-sync-ring.h b/src/compositor/meta-sync-ring.h +new file mode 100644 +index 0000000..6dca8ef +--- /dev/null ++++ b/src/compositor/meta-sync-ring.h +@@ -0,0 +1,14 @@ ++#ifndef _META_SYNC_RING_H_ ++#define _META_SYNC_RING_H_ ++ ++#include ++ ++#include ++ ++gboolean meta_sync_ring_init (Display *dpy); ++void meta_sync_ring_destroy (void); ++gboolean meta_sync_ring_after_frame (void); ++gboolean meta_sync_ring_insert_wait (void); ++void meta_sync_ring_handle_event (XEvent *event); ++ ++#endif /* _META_SYNC_RING_H_ */ +-- +2.5.0 + + +From 8b889d6ff46971edd4af7f412275e116e293e72a Mon Sep 17 00:00:00 2001 +From: Aaron Plattner +Date: Mon, 3 Aug 2015 21:15:15 -0700 +Subject: [PATCH 3/5] compositor: Fix GL_EXT_x11_sync_object race condition + +The compositor maintains a ring of shared fences with the X server in order to +properly synchronize rendering between the X server and the compositor's GPU +channel. When all of the fences have been used, the compositor needs to reset +one so that it can be reused. It does this by first waiting on the CPU for the +fence to become triggered, and then sending a request to the X server to reset +the fence. + +If the compositor's GPU channel is busy processing other work (e.g. the desktop +switcher animation), then the X server may process the reset request before the +GPU has consumed the fence. This causes the GPU channel to hang. + +Fix the problem by having the compositor's GPU channel trigger its own fence +after waiting for the X server's fence. Wait for that fence on the CPU before +sending the reset request to the X server. This ensures that the GPU has +consumed the X11 fence before the server resets it. + +Signed-off-by: Aaron Plattner + +https://bugzilla.gnome.org/show_bug.cgi?id=728464 +--- + src/compositor/meta-sync-ring.c | 25 +++++++++++++++++++------ + 1 file changed, 19 insertions(+), 6 deletions(-) + +diff --git a/src/compositor/meta-sync-ring.c b/src/compositor/meta-sync-ring.c +index 4ee61f8..44b1c41 100644 +--- a/src/compositor/meta-sync-ring.c ++++ b/src/compositor/meta-sync-ring.c +@@ -73,7 +73,8 @@ typedef struct + Display *xdisplay; + + XSyncFence xfence; +- GLsync glsync; ++ GLsync gl_x11_sync; ++ GLsync gpu_fence; + + XSyncCounter xcounter; + XSyncAlarm xalarm; +@@ -118,6 +119,8 @@ static void (*meta_gl_wait_sync) (GLsync sync, + static GLsync (*meta_gl_import_sync) (GLenum external_sync_type, + GLintptr external_sync, + GLbitfield flags); ++static GLsync (*meta_gl_fence_sync) (GLenum condition, ++ GLbitfield flags); + + static MetaSyncRing * + meta_sync_ring_get (void) +@@ -224,6 +227,8 @@ load_required_symbols (void) + goto out; + if (!load_gl_symbol ("glImportSyncEXT", (void **) &meta_gl_import_sync)) + goto out; ++ if (!load_gl_symbol ("glFenceSync", (void **) &meta_gl_fence_sync)) ++ goto out; + + success = TRUE; + out: +@@ -238,7 +243,8 @@ meta_sync_insert (MetaSync *self) + XSyncTriggerFence (self->xdisplay, self->xfence); + XFlush (self->xdisplay); + +- meta_gl_wait_sync (self->glsync, 0, GL_TIMEOUT_IGNORED); ++ meta_gl_wait_sync (self->gl_x11_sync, 0, GL_TIMEOUT_IGNORED); ++ self->gpu_fence = meta_gl_fence_sync (GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + + self->state = META_SYNC_STATE_WAITING; + } +@@ -255,9 +261,13 @@ meta_sync_check_update_finished (MetaSync *self, + status = GL_ALREADY_SIGNALED; + break; + case META_SYNC_STATE_WAITING: +- status = meta_gl_client_wait_sync (self->glsync, 0, timeout); ++ status = meta_gl_client_wait_sync (self->gpu_fence, 0, timeout); + if (status == GL_ALREADY_SIGNALED || status == GL_CONDITION_SATISFIED) +- self->state = META_SYNC_STATE_DONE; ++ { ++ self->state = META_SYNC_STATE_DONE; ++ meta_gl_delete_sync (self->gpu_fence); ++ self->gpu_fence = 0; ++ } + break; + default: + break; +@@ -312,7 +322,8 @@ meta_sync_new (Display *xdisplay) + self->xdisplay = xdisplay; + + self->xfence = XSyncCreateFence (xdisplay, DefaultRootWindow (xdisplay), FALSE); +- self->glsync = meta_gl_import_sync (GL_SYNC_X11_FENCE_EXT, self->xfence, 0); ++ self->gl_x11_sync = meta_gl_import_sync (GL_SYNC_X11_FENCE_EXT, self->xfence, 0); ++ self->gpu_fence = 0; + + self->xcounter = XSyncCreateCounter (xdisplay, SYNC_VALUE_ZERO); + +@@ -365,6 +376,8 @@ meta_sync_free (MetaSync *self) + switch (self->state) + { + case META_SYNC_STATE_WAITING: ++ meta_gl_delete_sync (self->gpu_fence); ++ break; + case META_SYNC_STATE_DONE: + /* nothing to do */ + break; +@@ -383,7 +396,7 @@ meta_sync_free (MetaSync *self) + break; + } + +- meta_gl_delete_sync (self->glsync); ++ meta_gl_delete_sync (self->gl_x11_sync); + XSyncDestroyFence (self->xdisplay, self->xfence); + XSyncDestroyCounter (self->xdisplay, self->xcounter); + XSyncDestroyAlarm (self->xdisplay, self->xalarm); +-- +2.5.0 + + +From 271b864a3a5fe2a59523a0ead0667072170e7bbe Mon Sep 17 00:00:00 2001 +From: Ting-Wei Lan +Date: Sat, 8 Aug 2015 20:12:09 +0800 +Subject: [PATCH 4/5] build: Fix return value in meta-sync-ring.c + +https://bugzilla.gnome.org/show_bug.cgi?id=753380 +--- + src/compositor/meta-sync-ring.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/compositor/meta-sync-ring.c b/src/compositor/meta-sync-ring.c +index 44b1c41..217ebe5 100644 +--- a/src/compositor/meta-sync-ring.c ++++ b/src/compositor/meta-sync-ring.c +@@ -499,7 +499,7 @@ meta_sync_ring_after_frame (void) + if (!ring) + return FALSE; + +- g_return_if_fail (ring->xdisplay != NULL); ++ g_return_val_if_fail (ring->xdisplay != NULL, FALSE); + + if (ring->warmup_syncs >= NUM_SYNCS / 2) + { +@@ -542,7 +542,7 @@ meta_sync_ring_insert_wait (void) + if (!ring) + return FALSE; + +- g_return_if_fail (ring->xdisplay != NULL); ++ g_return_val_if_fail (ring->xdisplay != NULL, FALSE); + + if (ring->current_sync->state != META_SYNC_STATE_READY) + { +-- +2.5.0 + + +From 4d4bd1fb39cf396733de4dff4f3041b5266b803a Mon Sep 17 00:00:00 2001 +From: Rui Matos +Date: Wed, 12 Aug 2015 15:26:34 +0200 +Subject: [PATCH 5/5] compositor: Handle fences in the frontend X connection + +Since mutter has two X connections and does damage handling on the +frontend while fence triggering is done on the backend, we have a race +between XDamageSubtract() and XSyncFenceTrigger() causing missed +redraws in the GL_EXT_X11_sync_object path. + +If the fence trigger gets processed first by the server, any client +drawing that happens between that and the damage subtract being +processed and is completely contained in the last damage event box +that mutter got, won't be included in the current frame nor will it +cause a new damage event. + +A simple fix for this would be XSync()ing on the frontend connection +after doing all the damage subtracts but that would add a round trip +on every frame again which defeats the asynchronous design of X +fences. + +Instead, if we move fence handling to the frontend we automatically +get the right ordering between damage subtracts and fence triggers. + +https://bugzilla.gnome.org/show_bug.cgi?id=728464 +--- + src/backends/x11/meta-backend-x11.c | 3 --- + src/compositor/compositor.c | 6 ++++-- + src/compositor/meta-sync-ring.c | 15 ++++++++++++++- + 3 files changed, 18 insertions(+), 6 deletions(-) + +diff --git a/src/backends/x11/meta-backend-x11.c b/src/backends/x11/meta-backend-x11.c +index d77365d..586f991 100644 +--- a/src/backends/x11/meta-backend-x11.c ++++ b/src/backends/x11/meta-backend-x11.c +@@ -43,7 +43,6 @@ + #include + #include "display-private.h" + #include "compositor/compositor-private.h" +-#include "compositor/meta-sync-ring.h" + + struct _MetaBackendX11Private + { +@@ -184,8 +183,6 @@ handle_host_xevent (MetaBackend *backend, + MetaCompositor *compositor = display->compositor; + if (meta_plugin_manager_xevent_filter (compositor->plugin_mgr, event)) + bypass_clutter = TRUE; +- if (compositor->have_x11_sync_object) +- meta_sync_ring_handle_event (event); + } + } + +diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c +index 554faa1..2e182c2 100644 +--- a/src/compositor/compositor.c ++++ b/src/compositor/compositor.c +@@ -534,8 +534,7 @@ meta_compositor_manage (MetaCompositor *compositor) + */ + XMapWindow (xdisplay, compositor->output); + +- compositor->have_x11_sync_object = +- meta_sync_ring_init (meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend))); ++ compositor->have_x11_sync_object = meta_sync_ring_init (xdisplay); + } + + redirect_windows (display->screen); +@@ -737,6 +736,9 @@ meta_compositor_process_event (MetaCompositor *compositor, + process_damage (compositor, (XDamageNotifyEvent *) event, window); + } + ++ if (compositor->have_x11_sync_object) ++ meta_sync_ring_handle_event (event); ++ + /* Clutter needs to know about MapNotify events otherwise it will + think the stage is invisible */ + if (!meta_is_wayland_compositor () && event->type == MapNotify) +diff --git a/src/compositor/meta-sync-ring.c b/src/compositor/meta-sync-ring.c +index 217ebe5..336ccd4 100644 +--- a/src/compositor/meta-sync-ring.c ++++ b/src/compositor/meta-sync-ring.c +@@ -322,7 +322,7 @@ meta_sync_new (Display *xdisplay) + self->xdisplay = xdisplay; + + self->xfence = XSyncCreateFence (xdisplay, DefaultRootWindow (xdisplay), FALSE); +- self->gl_x11_sync = meta_gl_import_sync (GL_SYNC_X11_FENCE_EXT, self->xfence, 0); ++ self->gl_x11_sync = 0; + self->gpu_fence = 0; + + self->xcounter = XSyncCreateCounter (xdisplay, SYNC_VALUE_ZERO); +@@ -347,6 +347,13 @@ meta_sync_new (Display *xdisplay) + return self; + } + ++static void ++meta_sync_import (MetaSync *self) ++{ ++ g_return_if_fail (self->gl_x11_sync == 0); ++ self->gl_x11_sync = meta_gl_import_sync (GL_SYNC_X11_FENCE_EXT, self->xfence, 0); ++} ++ + static Bool + alarm_event_predicate (Display *dpy, + XEvent *event, +@@ -437,6 +444,12 @@ meta_sync_ring_init (Display *xdisplay) + ring->syncs_array[i] = sync; + g_hash_table_replace (ring->alarm_to_sync, (gpointer) sync->xalarm, sync); + } ++ /* Since the connection we create the X fences on isn't the same as ++ * the one used for the GLX context, we need to XSync() here to ++ * ensure glImportSync() succeeds. */ ++ XSync (xdisplay, False); ++ for (i = 0; i < NUM_SYNCS; ++i) ++ meta_sync_import (ring->syncs_array[i]); + + ring->current_sync_idx = 0; + ring->current_sync = ring->syncs_array[0]; +-- +2.5.0 + diff --git a/SOURCES/mutter-translation-updates.patch b/SOURCES/mutter-translation-updates.patch deleted file mode 100644 index 4af0bae..0000000 --- a/SOURCES/mutter-translation-updates.patch +++ /dev/null @@ -1,12703 +0,0 @@ ---- a/mutter-3.8.4/po/bn_IN.po 2013-11-28 17:15:31.984866743 +0530 -+++ a/mutter-3.8.4/po/bn_IN.po 2013-11-28 17:17:23.036871335 +0530 -@@ -2,54 +2,236 @@ - # Bengali India Translation for Metacity 2.4 - # Copyright (C) 2003 Free Software Foundation - # This file is distributed under the same license as the METACITY package. --# -+# - # Dr Anirban Mitra , 2003. - # Mahay Alam Khan , 2005. - # Samia Niamatullah , 2005. - # Runa Bhattacharjee , 2006. - # Runa Bhattacharjee , 2009. - # Sayak Sarkar , 2012. -+# sray , 2013. #zanata - msgid "" - msgstr "" - "Project-Id-Version: bn_IN\n" --"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" --"product=mutter&keywords=I18N+L10N&component=general\n" -+"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=" -+"mutter&keywords=I18N+L10N&component=general\n" - "POT-Creation-Date: 2012-10-11 20:02+0000\n" --"PO-Revision-Date: 2012-10-12 05:01+0530\n" --"Last-Translator: Sayak Sarkar \n" -+"PO-Revision-Date: 2013-10-22 03:37-0400\n" -+"Last-Translator: sray \n" - "Language-Team: Bengali (India) \n" --"Language: bn_IN\n" - "MIME-Version: 1.0\n" - "Content-Type: text/plain; charset=UTF-8\n" - "Content-Transfer-Encoding: 8bit\n" --"X-Generator: Lokalize 1.4\n" -+"Language: bn-IN\n" - "Plural-Forms: nplurals=2; plural=(n != 1);\n" - "\n" - "\n" -+"X-Generator: Zanata 3.1.2\n" -+ -+#: ../src/50-mutter-navigation.xml.in.h:1 -+msgid "Navigation" -+msgstr "ন্যাভিগেশন" -+ -+#: ../src/50-mutter-navigation.xml.in.h:2 -+msgid "Move window to workspace 1" -+msgstr "উইন্ডো কর্মক্ষেত্র ১ এ সরান" -+ -+#: ../src/50-mutter-navigation.xml.in.h:3 -+msgid "Move window to workspace 2" -+msgstr "উইন্ডো কর্মক্ষেত্র ২ এ সরান" -+ -+#: ../src/50-mutter-navigation.xml.in.h:4 -+msgid "Move window to workspace 3" -+msgstr "উইন্ডো কর্মক্ষেত্র ৩ এ সরান" -+ -+#: ../src/50-mutter-navigation.xml.in.h:5 -+msgid "Move window to workspace 4" -+msgstr "উইন্ডো কর্মক্ষেত্র ৪ এ সরান" -+ -+#: ../src/50-mutter-navigation.xml.in.h:6 -+msgid "Move window one workspace to the left" -+msgstr "উইন্ডো বাম দিকে এক কর্মক্ষেত্র সরান" -+ -+#: ../src/50-mutter-navigation.xml.in.h:7 -+msgid "Move window one workspace to the right" -+msgstr "উইন্ডো ডান দিকে এক কর্মক্ষেত্র সরান" -+ -+#: ../src/50-mutter-navigation.xml.in.h:8 -+msgid "Move window one workspace up" -+msgstr "উইন্ডো এক কর্মক্ষেত্র উপরে সরান" -+ -+#: ../src/50-mutter-navigation.xml.in.h:9 -+msgid "Move window one workspace down" -+msgstr "উইন্ডো এক কর্মক্ষেত্র নীচে সরান" -+ -+#: ../src/50-mutter-navigation.xml.in.h:10 -+msgid "Switch applications" -+msgstr "অ্যাপ্লিকেশনগুলি স্যুইচ করুন" -+ -+#: ../src/50-mutter-navigation.xml.in.h:11 -+msgid "Switch windows" -+msgstr "উইন্ডোগুলি স্যুইচ করুন" -+ -+#: ../src/50-mutter-navigation.xml.in.h:12 -+msgid "Switch windows of an application" -+msgstr "কোনো অ্যাপ্লিকেশনের উইন্ডোগুলি স্যুইচ করুন" -+ -+#: ../src/50-mutter-navigation.xml.in.h:13 -+msgid "Switch system controls" -+msgstr "সিস্টেম কন্ট্রোলগুলি স্যুইচ করুন" -+ -+#: ../src/50-mutter-navigation.xml.in.h:14 -+msgid "Switch windows directly" -+msgstr "উইন্ডোগুলি সরাসরি স্যুইচ করুন" -+ -+#: ../src/50-mutter-navigation.xml.in.h:15 -+msgid "Switch windows of an app directly" -+msgstr "কোনো অ্যাপ্লিকেশনের উইন্ডোগুলি সরাসরি স্যুইচ করুন" -+ -+#: ../src/50-mutter-navigation.xml.in.h:16 -+msgid "Switch system controls directly" -+msgstr "সিস্টেম কন্ট্রোলগুলি সরাসরি স্যুইচ করুন" -+ -+#: ../src/50-mutter-navigation.xml.in.h:17 -+msgid "Hide all normal windows" -+msgstr "সমস্ত সাধারণ উইন্ডো লুকান" -+ -+#: ../src/50-mutter-navigation.xml.in.h:18 -+msgid "Switch to workspace 1" -+msgstr "কর্মক্ষেত্র ১ এ স্যুইচ করুন" -+ -+#: ../src/50-mutter-navigation.xml.in.h:19 -+msgid "Switch to workspace 2" -+msgstr "কর্মক্ষেত্র ২ এ স্যুইচ করুন" -+ -+#: ../src/50-mutter-navigation.xml.in.h:20 -+msgid "Switch to workspace 3" -+msgstr "কর্মক্ষেত্র ৩ এ স্যুইচ করুন" -+ -+#: ../src/50-mutter-navigation.xml.in.h:21 -+msgid "Switch to workspace 4" -+msgstr "কর্মক্ষেত্র ৪ এ স্যুইচ করুন" -+ -+#: ../src/50-mutter-navigation.xml.in.h:22 -+msgid "Move to workspace left" -+msgstr "বাম দিকের কর্মক্ষেত্রে সরান" -+ -+#: ../src/50-mutter-navigation.xml.in.h:23 -+msgid "Move to workspace right" -+msgstr "ডান দিকের কর্মক্ষেত্রে সরান" -+ -+#: ../src/50-mutter-navigation.xml.in.h:24 -+msgid "Move to workspace above" -+msgstr "উপরের দিকের কর্মক্ষেত্রে সরান" -+ -+#: ../src/50-mutter-navigation.xml.in.h:25 -+msgid "Move to workspace below" -+msgstr "নীচের দিকের কর্মক্ষেত্রে সরান" -+ -+#: ../src/50-mutter-system.xml.in.h:1 -+msgid "System" -+msgstr "সিস্টেম" -+ -+#: ../src/50-mutter-system.xml.in.h:2 -+msgid "Show the run command prompt" -+msgstr "চালনা কম্যান্ড প্রমপ্ট দেখান" -+ -+#: ../src/50-mutter-system.xml.in.h:3 -+msgid "Show the activities overview" -+msgstr "ক্রিয়াকলাপের পূর্বরূপ দেখান" - - #: ../src/50-mutter-windows.xml.in.h:1 - msgid "Windows" - msgstr "উইন্ডোগুলি" - - #: ../src/50-mutter-windows.xml.in.h:2 -+msgid "Activate the window menu" -+msgstr "উইন্ডো মেনু সক্রিয় করুন" -+ -+#: ../src/50-mutter-windows.xml.in.h:3 -+msgid "Toggle fullscreen mode" -+msgstr "সম্পূর্ণ পর্দা মোড টগল করুন" -+ -+#: ../src/50-mutter-windows.xml.in.h:4 -+msgid "Toggle maximization state" -+msgstr "বড় করার অবস্থা টগল করুন" -+ -+#: ../src/50-mutter-windows.xml.in.h:5 -+msgid "Maximize window" -+msgstr "উইন্ডো বড় করুন" -+ -+#: ../src/50-mutter-windows.xml.in.h:6 -+msgid "Restore window" -+msgstr "উইন্ডো পূর্বাবস্থা করুন" -+ -+#: ../src/50-mutter-windows.xml.in.h:7 -+msgid "Toggle shaded state" -+msgstr "ছায়াবৃত অবস্থা টগল করুন" -+ -+#: ../src/50-mutter-windows.xml.in.h:8 -+msgid "Close window" -+msgstr "উইন্ডো বন্ধ করুন" -+ -+#: ../src/50-mutter-windows.xml.in.h:9 -+msgid "Hide window" -+msgstr "উইন্ডো লুকান" -+ -+#: ../src/50-mutter-windows.xml.in.h:10 -+msgid "Move window" -+msgstr "উইন্ডো সরান" -+ -+#: ../src/50-mutter-windows.xml.in.h:11 -+msgid "Resize window" -+msgstr "উইন্ডোর মাপ পরিবর্তন করুন" -+ -+#: ../src/50-mutter-windows.xml.in.h:12 -+msgid "Toggle window on all workspaces or one" -+msgstr "সমস্ত কর্মক্ষেত্রে বা একটিতে উইন্ডো টগল করুন" -+ -+#: ../src/50-mutter-windows.xml.in.h:13 -+msgid "Raise window if covered, otherwise lower it" -+msgstr "ঢাকা থাকলে উইন্ডো ওঠান অথবা এটিকে নামান" -+ -+#: ../src/50-mutter-windows.xml.in.h:14 -+msgid "Raise window above other windows" -+msgstr "উইন্ডো অন্যান্য উইন্ডোর উপরে ওঠান" -+ -+#: ../src/50-mutter-windows.xml.in.h:15 -+msgid "Lower window below other windows" -+msgstr "উইন্ডো অন্যান্য উইন্ডোর নীচে নামান" -+ -+#: ../src/50-mutter-windows.xml.in.h:16 -+msgid "Maximize window vertically" -+msgstr "উইন্ডো উল্লম্বভাবে বড় করুন" -+ -+#: ../src/50-mutter-windows.xml.in.h:17 -+msgid "Maximize window horizontally" -+msgstr "উইন্ডো অনুভূমিক ভাবে বড় করুন" -+ -+#: ../src/50-mutter-windows.xml.in.h:18 - msgid "View split on left" - msgstr "বাম বিভক্ত দেখুন" - --#: ../src/50-mutter-windows.xml.in.h:3 -+#: ../src/50-mutter-windows.xml.in.h:19 - msgid "View split on right" - msgstr "ডান বিভক্ত দেখুন" - - #. This probably means that a non-WM compositor like xcompmgr is running; - #. * we have no way to get it to exit --#: ../src/compositor/compositor.c:492 -+#: ../src/compositor/compositor.c:568 - #, c-format - msgid "" --"Another compositing manager is already running on screen %i on display \"%s" --"\"." -+"Another compositing manager is already running on screen %i on display " -+"\"%s\"." - msgstr "" --"অন্য কম্পোসিটিং পরিচালককে পর্দা %i-তে ইতিমধ্যেই চলমান প্রদর্শন করা হয়েছে \"%s\"।" -+"অন্য কম্পোসিটিং পরিচালককে পর্দা %i-তে ইতিমধ্যেই চলমান প্রদর্শন করা হয়েছে " -+"\"%s\"।" -+ -+#: ../src/compositor/meta-background.c:1076 -+msgid "background texture could not be created from file" -+msgstr "ফাইল থেকে ব্যাকগ্রাউন্ড পরিকাঠামো তৈরি করা যায়নি" - --#: ../src/core/bell.c:320 -+#: ../src/core/bell.c:322 - msgid "Bell event" - msgstr "বেল ইভেন্ট" - -@@ -58,85 +240,91 @@ - msgid "Unknown window information request: %d" - msgstr "উইন্ডোর তথ্য সম্বন্ধে অজানা অনুরোধ: %d" - --#: ../src/core/delete.c:113 -+#: ../src/core/delete.c:111 - #, c-format --msgid "%s is not responding." --msgstr "%s থেকে প্রতিক্রিয়া পাওয়া যাচ্ছে না।" -+msgid "“%s” is not responding." -+msgstr "“%s” সাড়া দিচ্ছে না।" - --#: ../src/core/delete.c:117 -+#: ../src/core/delete.c:113 - msgid "Application is not responding." - msgstr "অ্যাপ্লিকেশনটির থেকে প্রতিক্রিয়া পাওয়া যাচ্ছে না।" - --#: ../src/core/delete.c:122 -+#: ../src/core/delete.c:118 - msgid "" - "You may choose to wait a short while for it to continue or force the " - "application to quit entirely." - msgstr "" --"এটি চালু হওয়ার জন্য আপনি একটি সংক্ষিপ্ত সময় অপেক্ষা করতে পারেন বাঅ্যাপ্লিকেশনটিকে " --"সম্পূর্ণরূপে বন্ধ হতে বাধ্য করতে পারেন‌।" -+"এটি চালু হওয়ার জন্য আপনি একটি সংক্ষিপ্ত সময় অপেক্ষা করতে পারেন " -+"বাঅ্যাপ্লিকেশনটিকে সম্পূর্ণরূপে বন্ধ হতে বাধ্য করতে পারেন‌।" - --#: ../src/core/delete.c:129 -+#: ../src/core/delete.c:125 - msgid "_Wait" - msgstr "অপেক্ষা করা হবে (_W)" - --#: ../src/core/delete.c:129 -+#: ../src/core/delete.c:125 - msgid "_Force Quit" - msgstr "বলপূর্বক বন্ধ করুন (_F)" - --#: ../src/core/display.c:396 -+#: ../src/core/display.c:421 - #, c-format - msgid "Missing %s extension required for compositing" - msgstr "কম্পোসিটিং-র জন্য আবশ্যক %s এক্সটেনশন অনুপস্থিত" - --#: ../src/core/display.c:492 -+#: ../src/core/display.c:513 - #, c-format - msgid "Failed to open X Window System display '%s'\n" - msgstr "X উইন্ডো সিস্টেম প্রদর্শন খুলতে ব্যর্থ '%s'\n" - - # " উইন্ডো অবৃহদায়ত কর" --#: ../src/core/keybindings.c:853 -+#: ../src/core/keybindings.c:1138 - #, c-format - msgid "" - "Some other program is already using the key %s with modifiers %x as a " - "binding\n" --msgstr "একটি পৃথক প্রোগ্রাম দ্বারা বর্তমানে %s-কি, %x বাইন্ডিং সহ ব্যবহৃত হচ্ছে\n" -+msgstr "" -+"একটি পৃথক প্রোগ্রাম দ্বারা বর্তমানে %s-কি, %x বাইন্ডিং সহ ব্যবহৃত হচ্ছে\n" -+ -+#: ../src/core/keybindings.c:1335 -+#, c-format -+msgid "\"%s\" is not a valid accelerator\n" -+msgstr "\"%s\" একটি বৈধ অ্যাকসিলেটর নয়\n" - --#: ../src/core/main.c:196 -+#: ../src/core/main.c:197 - msgid "Disable connection to session manager" - msgstr "সেশান পরিচালন ব্যবস্থার সাথে সংযোগ বিচ্ছিন্ন করা হবে" - --#: ../src/core/main.c:202 -+#: ../src/core/main.c:203 - msgid "Replace the running window manager" - msgstr "চলমান উইন্ডো পরিচালন ব্যবস্থা প্রতিস্থাপন করুন" - --#: ../src/core/main.c:208 -+#: ../src/core/main.c:209 - msgid "Specify session management ID" - msgstr "সেশান পরিচালনার ID উল্লেখ করুন" - --#: ../src/core/main.c:213 -+#: ../src/core/main.c:214 - msgid "X Display to use" - msgstr "ব্যবহারের জন্য এক্স ডিসপ্লে" - --#: ../src/core/main.c:219 -+#: ../src/core/main.c:220 - msgid "Initialize session from savefile" - msgstr "সংরক্ষণ ফাইল থেকে সেশন চালু করো" - --#: ../src/core/main.c:225 -+#: ../src/core/main.c:226 - msgid "Make X calls synchronous" - msgstr "X-র কল সিঙ্ক্রোনাস করা হবে" - --#: ../src/core/main.c:494 -+#: ../src/core/main.c:534 - #, c-format - msgid "Failed to scan themes directory: %s\n" - msgstr "থীম এর ডিরেক্টরি স্ক্যান করতে ব্যর্থ: %s\n" - --#: ../src/core/main.c:510 -+#: ../src/core/main.c:550 - #, c-format - msgid "" - "Could not find a theme! Be sure %s exists and contains the usual themes.\n" - msgstr "" --"কোনো থিম খুঁজে পাওয়া যায়নি! অনুগ্রহ করে পরীক্ষা করুন %s উপস্থিত আছে কি না ও এর মধ্যে " --"সাধারণ থিমগুলি অন্তর্ভুক্ত কি না।\n" -+"কোনো থিম খুঁজে পাওয়া যায়নি! অনুগ্রহ করে পরীক্ষা করুন %s উপস্থিত আছে কি না ও " -+"এর মধ্যে সাধারণ থিমগুলি অন্তর্ভুক্ত কি না।\n" - - #: ../src/core/mutter.c:40 - #, c-format -@@ -149,9 +337,10 @@ - msgstr "" - "mutter %s\n" - "স্বত্বাধিকার (C) ২০০১-%d হ্যাভক পেনিংটন, Red Hat, Inc., ও অন্যান্যদের\n" --"এটি একটি মুক্ত সফ্টওয়্যার; পুনব্যবহারের নিয়মাবলীর জন্য সোর্সের মধ্যে উপলব্ধ নথিপত্র " --"দেখুন।\n" --"এর কোনো ওয়ারেন্টি উপলব্ধ নেই; বাণিজ্যিক ও কোনো সুনির্দিষ্ট কর্ম সাধনের জন্যও নয়।\n" -+"এটি একটি মুক্ত সফ্টওয়্যার; পুনব্যবহারের নিয়মাবলীর জন্য সোর্সের মধ্যে উপলব্ধ " -+"নথিপত্র দেখুন।\n" -+"এর কোনো ওয়ারেন্টি উপলব্ধ নেই; বাণিজ্যিক ও কোনো সুনির্দিষ্ট কর্ম সাধনের জন্যও " -+"নয়।\n" - - #: ../src/core/mutter.c:54 - msgid "Print version" -@@ -161,75 +350,78 @@ - msgid "Mutter plugin to use" - msgstr "Mutter-এর ব্যবহারযোগ্য প্লাগইন" - --#: ../src/core/prefs.c:1079 -+#: ../src/core/prefs.c:1210 - msgid "" - "Workarounds for broken applications disabled. Some applications may not " - "behave properly.\n" - msgstr "" --"ক্ষতিগ্রস্ত অ্যাপ্লিকেশনের ত্রুটি অগ্রাহ্য করার প্রণালী নিষ্ক্রিয় করা হয়েছে। কয়েকটি " --"অ্যাপ্লিকেশন সম্ভবত সঠিকরূপে চালানো সম্ভব হবে না।\n" -+"ক্ষতিগ্রস্ত অ্যাপ্লিকেশনের ত্রুটি অগ্রাহ্য করার প্রণালী নিষ্ক্রিয় করা হয়েছে। " -+"কয়েকটি অ্যাপ্লিকেশন সম্ভবত সঠিকরূপে চালানো সম্ভব হবে না।\n" - --#: ../src/core/prefs.c:1154 -+#: ../src/core/prefs.c:1285 - #, c-format - msgid "Could not parse font description \"%s\" from GSettings key %s\n" - msgstr "\"%s\" ফন্টের বিবরণ GSettings-কি %s থেকে পার্স করতে ব্যর্থ\n" - --#: ../src/core/prefs.c:1220 -+#: ../src/core/prefs.c:1351 - #, c-format - msgid "" - "\"%s\" found in configuration database is not a valid value for mouse button " - "modifier\n" - msgstr "" --"কনফিগারেশন ডাটাবেসের মধ্যে উপস্থিত \"%s\" মাউস বাটন পরিবর্তকের জন্য বৈধ মান নয়\n" -+"কনফিগারেশন ডাটাবেসের মধ্যে উপস্থিত \"%s\" মাউস বাটন পরিবর্তকের জন্য বৈধ মান " -+"নয়\n" - --#: ../src/core/prefs.c:1747 -+#: ../src/core/prefs.c:1928 - #, c-format - msgid "" - "\"%s\" found in configuration database is not a valid value for keybinding " - "\"%s\"\n" - msgstr "" --"কনফিগারেশন ডাটাবেসের মধ্যে উপলব্ধ \"%s\", \"%s\" কি-বাইন্ডিং'র ক্ষেত্রে বৈধ মান " --"নয়\n" -+"কনফিগারেশন ডাটাবেসের মধ্যে উপলব্ধ \"%s\", \"%s\" কি-বাইন্ডিং'র ক্ষেত্রে বৈধ " -+"মান নয়\n" - --#: ../src/core/prefs.c:1844 -+#: ../src/core/prefs.c:2018 - #, c-format - msgid "Workspace %d" - msgstr "কর্মক্ষেত্র %d" - --#: ../src/core/screen.c:652 -+#: ../src/core/screen.c:691 - #, c-format - msgid "Screen %d on display '%s' is invalid\n" - msgstr "পর্দা %d (ডিসপ্লে '%s') বৈধ নয়\n" - --#: ../src/core/screen.c:668 -+#: ../src/core/screen.c:707 - #, c-format - msgid "" - "Screen %d on display \"%s\" already has a window manager; try using the --" - "replace option to replace the current window manager.\n" - msgstr "" --"পর্দা %d'র (\"%s\" ডিসপ্লে) ক্ষেত্রে একটি উইন্ডো পরিচালনব্যবস্থা বর্তমানে উপস্তিত " --"রয়েছে; বর্তমানে উইন্ডো পরিচালন ব্যবস্থা পরিবর্তন করতে --replace বিকল্প প্রয়োগ করুন।\n" -+"পর্দা %d'র (\"%s\" ডিসপ্লে) ক্ষেত্রে একটি উইন্ডো পরিচালনব্যবস্থা বর্তমানে " -+"উপস্তিত রয়েছে; বর্তমানে উইন্ডো পরিচালন ব্যবস্থা পরিবর্তন করতে --replace " -+"বিকল্প প্রয়োগ করুন।\n" - --#: ../src/core/screen.c:695 -+#: ../src/core/screen.c:734 - #, c-format --msgid "" --"Could not acquire window manager selection on screen %d display \"%s\"\n" -+msgid "Could not acquire window manager selection on screen %d display \"%s\"\n" - msgstr "" --"পর্দা %d (ডিসপ্লে \"%s\")'র মধ্যে উইন্ডো পরিচালন ব্যবস্থার নির্বাচিত অংশ গ্রহণ করতে " --"ব্যর্থ\n" -+"পর্দা %d (ডিসপ্লে \"%s\")'র মধ্যে উইন্ডো পরিচালন ব্যবস্থার নির্বাচিত অংশ " -+"গ্রহণ করতে ব্যর্থ\n" - --#: ../src/core/screen.c:750 -+#: ../src/core/screen.c:812 - #, c-format - msgid "Screen %d on display \"%s\" already has a window manager\n" - msgstr "" --"পর্দা %d'র ( \"%s\" ডিসপ্লে) ক্ষেত্রে একটি উইন্ডো পরিচালন ব্যবস্থা উপস্থিত রয়েছে\n" -+"পর্দা %d'র ( \"%s\" ডিসপ্লে) ক্ষেত্রে একটি উইন্ডো পরিচালন ব্যবস্থা উপস্থিত " -+"রয়েছে\n" - --#: ../src/core/screen.c:935 -+#: ../src/core/screen.c:998 - #, c-format - msgid "Could not release screen %d on display \"%s\"\n" - msgstr "পর্দা %d (ডিসপ্লে \"%s\") মুক্ত করতে ব্যর্থ\n" - --#: ../src/core/session.c:843 ../src/core/session.c:850 -+#: ../src/core/session.c:843 -+#: ../src/core/session.c:850 - #, c-format - msgid "Could not create directory '%s': %s\n" - msgstr "ডিরেক্টরি '%s' নির্মাণ করতে ব্যর্থ: %s\n" -@@ -257,10 +449,13 @@ - #: ../src/core/session.c:1185 - #, c-format - msgid " attribute seen but we already have the session ID" --msgstr " বৈশিষ্ট্য প্রদর্শিত কিন্তু সেশান ID বর্তমানে উপস্থিত রয়েছে" -+msgstr "" -+" বৈশিষ্ট্য প্রদর্শিত কিন্তু সেশান ID বর্তমানে উপস্থিত রয়েছে" - --#: ../src/core/session.c:1198 ../src/core/session.c:1273 --#: ../src/core/session.c:1305 ../src/core/session.c:1377 -+#: ../src/core/session.c:1198 -+#: ../src/core/session.c:1273 -+#: ../src/core/session.c:1305 -+#: ../src/core/session.c:1377 - #: ../src/core/session.c:1437 - #, c-format - msgid "Unknown attribute %s on <%s> element" -@@ -281,54 +476,55 @@ - "These windows do not support "save current setup" and will have to " - "be restarted manually next time you log in." - msgstr "" --"এই উইন্ডোগুলির দ্বারা \"save current setup\" বৈশিষ্ট্য সমর্থিত হয় না এবং পরবর্তীবার " --"লগ-ইন করা হলে ব্যবহারকারীর দ্বারা পুনরায় আরম্ভীত করা প্রয়োজন।" -+"এই উইন্ডোগুলির দ্বারা \"save current setup\" বৈশিষ্ট্য সমর্থিত হয় না এবং " -+"পরবর্তীবার লগ-ইন করা হলে ব্যবহারকারীর দ্বারা পুনরায় আরম্ভীত করা প্রয়োজন।" - --#: ../src/core/util.c:80 -+#: ../src/core/util.c:84 - #, c-format - msgid "Failed to open debug log: %s\n" - msgstr "ডিবাগ লগ খুলতে ব্যর্থ: %s\n" - --#: ../src/core/util.c:90 -+#: ../src/core/util.c:94 - #, c-format - msgid "Failed to fdopen() log file %s: %s\n" - msgstr "fdopen() লগ ফাইল %s খুলতে ব্যর্থ: %s\n" - --#: ../src/core/util.c:96 -+#: ../src/core/util.c:100 - #, c-format - msgid "Opened log file %s\n" - msgstr "লগ ফাইল %s খোলা হয়েছে\n" - --#: ../src/core/util.c:115 ../src/tools/mutter-message.c:149 -+#: ../src/core/util.c:119 -+#: ../src/tools/mutter-message.c:149 - #, c-format - msgid "Mutter was compiled without support for verbose mode\n" - msgstr "ভার্বোস মোডের সমর্থন অন্তর্ভুক্ত না করে Mutter কম্পাইল করা হয়েছে\n" - --#: ../src/core/util.c:259 -+#: ../src/core/util.c:264 - msgid "Window manager: " - msgstr "উইন্ডো পরিচালন ব্যবস্থা: " - --#: ../src/core/util.c:407 -+#: ../src/core/util.c:412 - msgid "Bug in window manager: " - msgstr "উইন্ডো পরিচালনব্যবস্থা সংক্রান্ত সমস্যা: " - --#: ../src/core/util.c:438 -+#: ../src/core/util.c:443 - msgid "Window manager warning: " - msgstr "উইন্ডো পরিচালন ব্যবস্থা সংক্রান্ত সতর্কবার্তা: " - --#: ../src/core/util.c:466 -+#: ../src/core/util.c:471 - msgid "Window manager error: " - msgstr "উইন্ডো পরিচালন ব্যবস্থা সংক্রান্ত ত্রুটি: " - - #. first time through --#: ../src/core/window.c:7237 -+#: ../src/core/window.c:7643 - #, c-format - msgid "" - "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " - "window as specified in the ICCCM.\n" - msgstr "" --"উইন্ডো %s দ্বারা ICCCM'এ নির্ধারিত WM_CLIENT_LEADER উইন্ডোর পরিবর্তে নিজের উপর " --"SM_CLIENT_ID নির্ধারিত হয়েছে।\n" -+"উইন্ডো %s দ্বারা ICCCM'এ নির্ধারিত WM_CLIENT_LEADER উইন্ডোর পরিবর্তে নিজের " -+"উপর SM_CLIENT_ID নির্ধারিত হয়েছে।\n" - - #. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the - #. * authoritative source for that info. Some apps such as mplayer or -@@ -336,34 +532,35 @@ - #. * leads to e.g. us not fullscreening their windows. Apps that set - #. * MWM but not WM_NORMAL_HINTS are basically broken. We complain - #. * about these apps but make them work. --#. --#: ../src/core/window.c:7902 -+#: ../src/core/window.c:8367 - #, c-format - msgid "" - "Window %s sets an MWM hint indicating it isn't resizable, but sets min size " - "%d x %d and max size %d x %d; this doesn't make much sense.\n" - msgstr "" -+"উইন্ডো %s একটি MWM হিন্ট করে যা সূচিত করে যে এটির মাপ পরিবর্তন করা যায় না, " -+"তবে সর্বনিম্ন মাপ %d x %d এবং সর্বাধিক মাপ %d x %d সেট করে; যার খুব বেশি " -+"গুরুত্ব নেই।\n" - --#: ../src/core/window-props.c:274 -+#: ../src/core/window-props.c:318 - #, c-format - msgid "Application set a bogus _NET_WM_PID %lu\n" - msgstr "অ্যাপ্লিকেশন দ্বারা ভুল _NET_WM_PID %lu নির্ধারিত হয়েছে\n" - --#: ../src/core/window-props.c:393 -+#: ../src/core/window-props.c:434 - #, c-format - msgid "%s (on %s)" - msgstr "%s (%s'র উপর)" - --#: ../src/core/window-props.c:1448 -+#: ../src/core/window-props.c:1517 - #, c-format - msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" - msgstr "অবৈধ WM_TRANSIENT_FOR উইন্ডো 0x%lx, %s'র জন্য নির্ধারিত হয়েছে।\n" - --#: ../src/core/window-props.c:1459 --#, fuzzy, c-format --#| msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -+#: ../src/core/window-props.c:1528 -+#, c-format - msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" --msgstr "অবৈধ WM_TRANSIENT_FOR উইন্ডো 0x%lx, %s'র জন্য নির্ধারিত হয়েছে।\n" -+msgstr "WM_TRANSIENT_FOR উইন্ডো 0x%lx %s এর জন্য লুপ তৈরি করবে।\n" - - #: ../src/core/xprops.c:155 - #, c-format -@@ -374,32 +571,37 @@ - "This is most likely an application bug, not a window manager bug.\n" - "The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" - msgstr "" -+"উইন্ডো 0x%lx এর বিশিষ্টতা হল %s\n" -+"যার প্রত্যাশিত ধরন হল %s ফর্ম্যাট %d\n" -+"এবং বাস্তবিক ধরন হল %s ফর্ম্যাট %d n_items %d।\n" -+"খুব সম্ভবতঃ এটি একটি অ্যাপ্লিকেশন বাগ, এবং উইন্ডো ম্যানেজার বাগ নয়।\n" -+"উইন্ডোর টাইটেল=\"%s\" ক্লাস=\"%s\" নাম=\"%s\"\n" - - #: ../src/core/xprops.c:411 - #, c-format - msgid "Property %s on window 0x%lx contained invalid UTF-8\n" - msgstr "" --"%s বৈশিষ্ট্যটি 0x%lx উইন্ডোর উপর উপস্থিত ও এর মধ্যে অবৈধ UTF-8 অক্ষর অন্তর্ভুক্ত " --"রয়েছে\n" -+"%s বৈশিষ্ট্যটি 0x%lx উইন্ডোর উপর উপস্থিত ও এর মধ্যে অবৈধ UTF-8 অক্ষর " -+"অন্তর্ভুক্ত রয়েছে\n" - - # FIXME msgstr "%s বিশেষত্বটি জানালা 0x%lx -তে অন্যায্য UTF-8 আছে\n - #: ../src/core/xprops.c:494 - #, c-format - msgid "" --"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -+"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the " -+"list\n" - msgstr "" --"%s বৈশিষ্ট্যটি 0x%lx উইন্ডোর উপর উপস্থিত ও এর তালিকায় %d সংখ্যক বস্তুর মধ্যে অবৈধ " --"UTF-8 অক্ষর অন্তর্ভুক্ত রয়েছে\n" -+"%s বৈশিষ্ট্যটি 0x%lx উইন্ডোর উপর উপস্থিত ও এর তালিকায় %d সংখ্যক বস্তুর মধ্যে " -+"অবৈধ UTF-8 অক্ষর অন্তর্ভুক্ত রয়েছে\n" - --#: ../src/mutter.desktop.in.h:1 ../src/mutter-wm.desktop.in.h:1 -+#: ../src/mutter.desktop.in.h:1 -+#: ../src/mutter-wm.desktop.in.h:1 - msgid "Mutter" - msgstr "Mutter" - - #: ../src/org.gnome.mutter.gschema.xml.in.h:1 --#, fuzzy --#| msgid "Modifier to use for modified window click actions" - msgid "Modifier to use for extended window management operations" --msgstr "পরিবর্তিত উইন্ডো ক্লিক কর্মের ফলে ব্যবহারযোগ্য পরিবর্তক" -+msgstr "বর্ধিত উইন্ডো পরিচালনা কাজের জন্য ব্যবহার করার সংশোধক" - - #: ../src/org.gnome.mutter.gschema.xml.in.h:2 - msgid "" -@@ -408,10 +610,13 @@ - "\"Windows key\" on PC hardware. It's expected that this binding either the " - "default or set to the empty string." - msgstr "" -+"এই কী \"ওভারলে\" এর সূচনা করবে, যা হল এক সমন্বয় উইন্ডো পূর্বরূপ এবং " -+"অ্যাপ্লিকেশন লঞ্চিং সিস্টেম। অভিপ্রেত ডিফল্ট হল PC হার্ডওয়্যারে \"Windows " -+"কী\"। প্রত্যাশিত হল, এই বন্ধন হয় ডিফল্ট বা খালি স্ট্রীঙে সেট করা।" - - #: ../src/org.gnome.mutter.gschema.xml.in.h:3 - msgid "Attach modal dialogs" --msgstr "" -+msgstr "মোডেল ডায়ালগ সংযুক্ত করুন" - - #: ../src/org.gnome.mutter.gschema.xml.in.h:4 - msgid "" -@@ -419,21 +624,28 @@ - "attached to the titlebar of the parent window and are moved together with " - "the parent window." - msgstr "" -+"সত্য হলে, স্বতন্ত্র টাইটেলবার থাকার পরিবর্তে, মোডেল ডায়ালগ পেরেন্ট উইন্ডোর " -+"টাইটেল বারে সংযুক্ত অবস্থায় অাসে এবং পেরেন্ট উইন্ডোর সাথে একসাথে অবস্থান " -+"পরিবর্তন করে।" - - #: ../src/org.gnome.mutter.gschema.xml.in.h:5 - msgid "Enable edge tiling when dropping windows on screen edges" --msgstr "" -+msgstr "উইন্ডো স্ক্রীন কিনারায় অানার সময়ে কিনারা টাইল পরিবৃত করা সক্ষম করুন" - - #: ../src/org.gnome.mutter.gschema.xml.in.h:6 - msgid "" - "If enabled, dropping windows on vertical screen edges maximizes them " --"vertically and resizes them horizontally to cover half of the available " --"area. Dropping windows on the top screen edge maximizes them completely." -+"vertically and resizes them horizontally to cover half of the available area." -+" Dropping windows on the top screen edge maximizes them completely." - msgstr "" -+"সক্রিয় করা হলে, উইন্ডো উল্লম্ব স্ক্রীন কিনারায় রাখা হলে, তা উল্লম্ব ভাবে " -+"বর্ধিত হয় এবং উপলব্ধ অঞ্চলের অর্ধেক অাবৃত করতে তাদের মাপ অনুভূমিক ভাবে " -+"পরিবর্তন করে। উইন্ডো উপরের স্ক্রীন কিনারায় ছাড়া হলে তা তাদের সম্পূর্ণ ভাবে " -+"বড় করে।" - - #: ../src/org.gnome.mutter.gschema.xml.in.h:7 - msgid "Workspaces are managed dynamically" --msgstr "" -+msgstr "কর্মক্ষেত্রগুলি ডায়নামিক ভাবে ব্যবস্থাপনা করা হয়" - - #: ../src/org.gnome.mutter.gschema.xml.in.h:8 - msgid "" -@@ -441,67 +653,79 @@ - "static number of workspaces (determined by the num-workspaces key in org." - "gnome.desktop.wm.preferences)." - msgstr "" -+"কর্মক্ষেত্রগুলি ডায়নামিক ভাবে পরিচালিত হয় নাকি কর্মক্ষেত্রের সংখ্যা স্থির তা " -+"নির্ধারণ করে (এখানে num-workspaces কী দ্বারা নির্ধারিত হয় org.gnome.desktop." -+"wm.preferences)।" - - #: ../src/org.gnome.mutter.gschema.xml.in.h:9 - msgid "Workspaces only on primary" --msgstr "" -+msgstr "কর্মক্ষেত্রগুলি শুধুমাত্র প্রাথমিকে" - - #: ../src/org.gnome.mutter.gschema.xml.in.h:10 - msgid "" - "Determines whether workspace switching should happen for windows on all " - "monitors or only for windows on the primary monitor." - msgstr "" -+"কর্মক্ষেত্র একটি থেকে অন্যটিতে পাল্টানো সমস্ত মনিটরের উইন্ডোর জন্য নাকি " -+"শুধুমাত্র প্রাথমিক মনিটরের উইন্ডোর জন্য ঘটবে তা নির্ধারণ করে।" - - #: ../src/org.gnome.mutter.gschema.xml.in.h:11 - msgid "No tab popup" --msgstr "" -+msgstr "কোনো ট্যাব পপ-অাপ নেই" - - #: ../src/org.gnome.mutter.gschema.xml.in.h:12 - msgid "" - "Determines whether the use of popup and highlight frame should be disabled " - "for window cycling." - msgstr "" -+"উইন্ডো অাবর্তনের ক্ষেত্রে পপ-অাপ এবং ফ্রেম হাইলাইট ব্যবহার করা হবে কিনা তা " -+"নির্ধারণ করে।" - - #: ../src/org.gnome.mutter.gschema.xml.in.h:13 - msgid "Delay focus changes until the pointer stops moving" --msgstr "" -+msgstr "ফোকাসে বিলম্ব পয়েন্টার অবস্থান পরিবর্তন করা পর্যন্ত পরিবর্তিত হয়" - - #: ../src/org.gnome.mutter.gschema.xml.in.h:14 --#, fuzzy --#| msgid "" --#| "If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " --#| "the focused window will be automatically raised after a delay specified " --#| "by the auto_raise_delay key. This is not related to clicking on a window " --#| "to raise it, nor to entering a window during drag-and-drop." - msgid "" - "If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " - "the focus will not be changed immediately when entering a window, but only " - "after the pointer stops moving." - msgstr "" --"মান true ধার্য করা হলে ও উজ্জ্বল করার মোড \"sloppy\" অথবা \"mouse\" হয়ে থাকলে " --"auto_raise_delay কি দ্বারা চিহ্নিত মিলিসেকেন্ড পরে উজ্জ্বলিত উইন্ডোটি স্বয়ংক্রিয়রূপে " --"বড় করা হবে। উইন্ডোর উপর ক্লিক করে উইন্ডো বড় করার বৈশিষ্ট্য অথবা ড্র্যাগ-ড্রপ কর্ম " --"সঞ্চালনকালে উইন্ডোর মধ্যে প্রবেশের সাথে এর কোনো সম্পর্ক নেই।" -+"সত্য হিসাবে সেট করা হলে, এবং ফোকাস মোড \"sloppy\" বা \"mouse\" হলে একটি " -+"উইন্ডোতে প্রবেশ করার সময়ে ফোকাস সংগে সংগে পরিবর্তিত হবে না, তবে তা ঘটবে " -+"পয়েন্টার অবস্থান পরিবর্তন করা থামালে তবেই।" - - #: ../src/org.gnome.mutter.gschema.xml.in.h:15 - msgid "Draggable border width" --msgstr "" -+msgstr "টানা যায় এমন কিনারার প্রস্থ" - - #: ../src/org.gnome.mutter.gschema.xml.in.h:16 - msgid "" - "The amount of total draggable borders. If the theme's visible borders are " - "not enough, invisible borders will be added to meet this value." - msgstr "" -+"টানা যায় এমন সর্বমোট কিনারার পরিমাণ। থিমের দৃশ্যমান কিনারা পর্যাপ্ত না হলে, " -+"এই মান পূরণ করতে অদৃশ্যমান কিনারা যোগ করা হবে।" - - #: ../src/org.gnome.mutter.gschema.xml.in.h:17 --#, fuzzy --#| msgid "Remove Window From Top" --msgid "Select window from tab popup" --msgstr "উইন্ডো সর্বোচ্চ স্তর থেকে সরিয়ে ফেলা হবে" -+msgid "Auto maximize nearly monitor sized windows" -+msgstr "প্রায় মনিটরের মাপের উইন্ডো স্বয়ংক্রিয় ভাবে বড় করুন" - - #: ../src/org.gnome.mutter.gschema.xml.in.h:18 --msgid "Cancel tab popup" -+msgid "" -+"If enabled, new windows that are initially the size of the monitor " -+"automatically get maximized." - msgstr "" -+"সক্রিয় করা হলে, প্রাথমিক ভাবে মনিটরের সমান মাপের নতুন উইন্ডোগুলি স্বয়ংক্রিয় " -+"ভাবে বড় হয়।" -+ -+#: ../src/org.gnome.mutter.gschema.xml.in.h:19 -+msgid "Select window from tab popup" -+msgstr "উইন্ডো ট্যাব পপ-অাপ থেকে নির্বাচন করুন" -+ -+#: ../src/org.gnome.mutter.gschema.xml.in.h:20 -+msgid "Cancel tab popup" -+msgstr "ট্যাব পপ-অাপ বাতিল করুন" - - #: ../src/tools/mutter-message.c:123 - #, c-format -@@ -550,7 +774,8 @@ - - #. separator - #. Translators: Translate this string the same way as you do in libwnck! --#: ../src/ui/menu.c:86 ../src/ui/menu.c:88 -+#: ../src/ui/menu.c:86 -+#: ../src/ui/menu.c:88 - msgid "Always on _Top" - msgstr "সর্বদা উপরে (_T)" - -@@ -613,7 +838,6 @@ - #. * that use the shift key. If the text on this key isn't typically - #. * translated on keyboards used for your language, don't translate - #. * this. --#. - #: ../src/ui/metaaccellabel.c:77 - msgid "Shift" - msgstr "Shift" -@@ -622,7 +846,6 @@ - #. * that use the control key. If the text on this key isn't typically - #. * translated on keyboards used for your language, don't translate - #. * this. --#. - #: ../src/ui/metaaccellabel.c:83 - msgid "Ctrl" - msgstr "Ctrl" -@@ -631,7 +854,6 @@ - #. * that use the alt key. If the text on this key isn't typically - #. * translated on keyboards used for your language, don't translate - #. * this. --#. - #: ../src/ui/metaaccellabel.c:89 - msgid "Alt" - msgstr "Alt" -@@ -640,7 +862,6 @@ - #. * that use the meta key. If the text on this key isn't typically - #. * translated on keyboards used for your language, don't translate - #. * this. --#. - #: ../src/ui/metaaccellabel.c:95 - msgid "Meta" - msgstr "মিটা" -@@ -649,7 +870,6 @@ - #. * that use the super key. If the text on this key isn't typically - #. * translated on keyboards used for your language, don't translate - #. * this. --#. - #: ../src/ui/metaaccellabel.c:101 - msgid "Super" - msgstr "Super" -@@ -658,7 +878,6 @@ - #. * that use the hyper key. If the text on this key isn't typically - #. * translated on keyboards used for your language, don't translate - #. * this. --#. - #: ../src/ui/metaaccellabel.c:107 - msgid "Hyper" - msgstr "Hyper" -@@ -667,7 +886,6 @@ - #. * that use the mod2 key. If the text on this key isn't typically - #. * translated on keyboards used for your language, don't translate - #. * this. --#. - #: ../src/ui/metaaccellabel.c:113 - msgid "Mod2" - msgstr "Mod2" -@@ -676,7 +894,6 @@ - #. * that use the mod3 key. If the text on this key isn't typically - #. * translated on keyboards used for your language, don't translate - #. * this. --#. - #: ../src/ui/metaaccellabel.c:119 - msgid "Mod3" - msgstr "Mod3" -@@ -685,7 +902,6 @@ - #. * that use the mod4 key. If the text on this key isn't typically - #. * translated on keyboards used for your language, don't translate - #. * this. --#. - #: ../src/ui/metaaccellabel.c:125 - msgid "Mod4" - msgstr "Mod4" -@@ -694,256 +910,279 @@ - #. * that use the mod5 key. If the text on this key isn't typically - #. * translated on keyboards used for your language, don't translate - #. * this. --#. - #: ../src/ui/metaaccellabel.c:131 - msgid "Mod5" - msgstr "Mod5" - - #. Translators: This represents the size of a window. The first number is - #. * the width of the window and the second is the height. --#. --#: ../src/ui/resizepopup.c:113 -+#: ../src/ui/resizepopup.c:136 - #, c-format - msgid "%d x %d" - msgstr "%d x %d" - --#: ../src/ui/theme.c:234 -+#: ../src/ui/theme.c:236 - msgid "top" - msgstr "উপরে" - --#: ../src/ui/theme.c:236 -+#: ../src/ui/theme.c:238 - msgid "bottom" - msgstr "নীচে" - --#: ../src/ui/theme.c:238 -+#: ../src/ui/theme.c:240 - msgid "left" - msgstr "বাঁদিকে" - --#: ../src/ui/theme.c:240 -+#: ../src/ui/theme.c:242 - msgid "right" - msgstr "ডানদিকে" - --#: ../src/ui/theme.c:268 -+#: ../src/ui/theme.c:270 - #, c-format - msgid "frame geometry does not specify \"%s\" dimension" - msgstr "ফ্রেম জ্যামিতি দ্বারা \"%s\" পরিমাপ নির্ধারিত হয়নি" - --#: ../src/ui/theme.c:287 -+#: ../src/ui/theme.c:289 - #, c-format - msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" - msgstr "ফ্রেম জ্যামিতি দ্বারা \"%s\" পরিমাপ \"%s\" প্রান্তের জন্য নির্ধারিত হয়নি" - --#: ../src/ui/theme.c:324 -+#: ../src/ui/theme.c:326 - #, c-format - msgid "Button aspect ratio %g is not reasonable" - msgstr "বাটনের অ্যাপেক্ট অনুপাত %g যথাযথ নয়" - --#: ../src/ui/theme.c:336 -+#: ../src/ui/theme.c:338 - #, c-format - msgid "Frame geometry does not specify size of buttons" - msgstr "ফ্রেম জ্যামিতি দ্বারা বাটনের মাপ নির্ধারিত হয়নি" - --#: ../src/ui/theme.c:1049 -+#: ../src/ui/theme.c:1051 - #, c-format - msgid "Gradients should have at least two colors" - msgstr "গ্রেডিয়েন্টের ক্ষেত্রে দুটি রং নির্ধারিত হওয়া আবশ্যক" - --#: ../src/ui/theme.c:1201 -+#: ../src/ui/theme.c:1203 - #, c-format - msgid "" - "GTK custom color specification must have color name and fallback in " - "parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" - msgstr "" -+"GTK কাস্টম রঙ বিশেষীকরণে অবশ্যই বন্ধনীর মধ্যে রঙের নাম এবং ফলব্যাকের উল্লেখ " -+"রাখতে হবে, উদাঃ gtk:custom(foo,bar); \"%s\" পার্জ করা যায়নি" - --#: ../src/ui/theme.c:1217 -+#: ../src/ui/theme.c:1219 - #, c-format - msgid "" - "Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" - "_ are valid" - msgstr "" -+"অবৈধ অক্ষর '%c' color_name প্যারামিটারে gtk:custom এর, শুধুমাত্র A-Za-z0-9-_ " -+"বৈধ" - --#: ../src/ui/theme.c:1231 --#, fuzzy, c-format --#| msgid "" --#| "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the " --#| "format" -+#: ../src/ui/theme.c:1233 -+#, c-format - msgid "" - "Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " - "fit the format" - msgstr "" --"ছায়ার বিন্যাস \"shade/base_color/factor\", \"%s\" বিন্যাসের সাথে সুসংগত নয়" -+"Gtk:কাস্টম ফর্ম্যাট হল \"gtk:custom(color_name,fallback)\", \"%s\" ফর্ম্যাটে " -+"মানানসই নয়" - --#: ../src/ui/theme.c:1276 -+#: ../src/ui/theme.c:1278 - #, c-format - msgid "" - "GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " - "where NORMAL is the state; could not parse \"%s\"" - msgstr "" -+"GTK রঙের বিশেষীকরণে অবশ্যই বন্ধনীর মধ্যে অবস্থার উল্লেখ করতে হবে, উদাঃ gtk:" -+"fg[NORMAL] যেখানে NORMAL হল অবস্থা; \"%s\" পার্জ করা যায়নি" - --#: ../src/ui/theme.c:1290 -+#: ../src/ui/theme.c:1292 - #, c-format - msgid "" - "GTK color specification must have a close bracket after the state, e.g. gtk:" - "fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" - msgstr "" -+"GTK রঙ বিশেষীকরণে অবশ্যই অবস্থার পরে একটি সমাপ্তি বন্ধনী থাকতে হবে, উদাঃ gtk:" -+"fg[NORMAL] যেখানে NORMAL হল অবস্থা; \"%s\" পার্জ করা যায়নি" - --#: ../src/ui/theme.c:1301 -+#: ../src/ui/theme.c:1303 - #, c-format - msgid "Did not understand state \"%s\" in color specification" - msgstr "রং নির্ধারণের জন্য state \"%s\" বোধগম্য হয়নি" - --#: ../src/ui/theme.c:1314 -+#: ../src/ui/theme.c:1316 - #, c-format - msgid "Did not understand color component \"%s\" in color specification" - msgstr "রং নির্ধারণের জন্য রং'র বিষয়বস্তু \"%s\" বোধগম্য হয়নি" - --#: ../src/ui/theme.c:1343 -+#: ../src/ui/theme.c:1345 - #, c-format - msgid "" - "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " - "format" - msgstr "" --"ব্লেন্ড বিন্যাস \"blend/bg_color/fg_color/alpha\", \"%s\" বিন্যাসের সাথে সুসংগত নয়" -+"ব্লেন্ড বিন্যাস \"blend/bg_color/fg_color/alpha\", \"%s\" বিন্যাসের সাথে " -+"সুসংগত নয়" - --#: ../src/ui/theme.c:1354 -+#: ../src/ui/theme.c:1356 - #, c-format - msgid "Could not parse alpha value \"%s\" in blended color" - msgstr "ব্লেন্ড করা রং'এ আল্ফা মান \"%s\" পার্স করতে ব্যর্থ" - --#: ../src/ui/theme.c:1364 -+#: ../src/ui/theme.c:1366 - #, c-format - msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" - msgstr "ব্লেন্ড করা রং'এ আল্ফা মান \"%s\" 0.0 ও1.0 সীমারেখার মধ্যে নয়" - --#: ../src/ui/theme.c:1411 -+#: ../src/ui/theme.c:1413 - #, c-format - msgid "" - "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" - msgstr "" - "ছায়ার বিন্যাস \"shade/base_color/factor\", \"%s\" বিন্যাসের সাথে সুসংগত নয়" - --#: ../src/ui/theme.c:1422 -+#: ../src/ui/theme.c:1424 - #, c-format - msgid "Could not parse shade factor \"%s\" in shaded color" - msgstr "ছায়াযুক্ত রং'র ক্ষেত্রে ছায়ার মাপ \"%s\" পার্স করতে ব্যর্থ" - --#: ../src/ui/theme.c:1432 -+#: ../src/ui/theme.c:1434 - #, c-format - msgid "Shade factor \"%s\" in shaded color is negative" - msgstr "ছায়াযুক্ত রং'র ক্ষেত্রে ছায়ার মান \"%s\" শূণ্যের কম" - --#: ../src/ui/theme.c:1461 -+#: ../src/ui/theme.c:1463 - #, c-format - msgid "Could not parse color \"%s\"" - msgstr "\"%s\" রং পার্স করতে ব্যর্থ" - --#: ../src/ui/theme.c:1778 -+#: ../src/ui/theme.c:1780 - #, c-format - msgid "Coordinate expression contains character '%s' which is not allowed" --msgstr "কো-ওর্ডিনেট এক্সপ্রেশনের মধ্যে '%s' অক্ষর উপস্থিত এবং এর ব্যবহার অনুমোদিত নয়" -+msgstr "" -+"কো-ওর্ডিনেট এক্সপ্রেশনের মধ্যে '%s' অক্ষর উপস্থিত এবং এর ব্যবহার অনুমোদিত নয়" - - # what is bengali for Coordinate expression ? অবস্থানের মান or অবস্থানের সমীকরণ? --#: ../src/ui/theme.c:1805 -+#: ../src/ui/theme.c:1807 - #, c-format - msgid "" - "Coordinate expression contains floating point number '%s' which could not be " - "parsed" - msgstr "" --"কো-ওর্ডিনেট এক্সপ্রেশনের মধ্যে '%s' ফ্লোটিং পয়েন্ট সংখ্যা উপস্থিত যা পার্স করা সম্ভব " --"হয়নি" -+"কো-ওর্ডিনেট এক্সপ্রেশনের মধ্যে '%s' ফ্লোটিং পয়েন্ট সংখ্যা উপস্থিত যা পার্স " -+"করা সম্ভব হয়নি" - --#: ../src/ui/theme.c:1819 -+#: ../src/ui/theme.c:1821 - #, c-format - msgid "Coordinate expression contains integer '%s' which could not be parsed" - msgstr "" --"কো-ওর্ডিনেট এক্সপ্রেশনের মধ্যে '%s' ইন্টিজার সংখ্যা উপস্থিত যা পার্স করা সম্ভব হয়নি" -+"কো-ওর্ডিনেট এক্সপ্রেশনের মধ্যে '%s' ইন্টিজার সংখ্যা উপস্থিত যা পার্স করা " -+"সম্ভব হয়নি" - --#: ../src/ui/theme.c:1940 -+#: ../src/ui/theme.c:1942 - #, c-format - msgid "" - "Coordinate expression contained unknown operator at the start of this text: " - "\"%s\"" - msgstr "" --"কো-ওর্ডিনেট এক্সপ্রেশনের মধ্যে টেক্সটের প্রারম্ভিক স্থানে অজানা অপারেটর: \"%s\"" -+"কো-ওর্ডিনেট এক্সপ্রেশনের মধ্যে টেক্সটের প্রারম্ভিক স্থানে অজানা অপারেটর: " -+"\"%s\"" - --#: ../src/ui/theme.c:1997 -+#: ../src/ui/theme.c:1999 - #, c-format - msgid "Coordinate expression was empty or not understood" - msgstr "কো-ওর্ডিনেট এক্সপ্রেশন ফাঁকা অথবা বোধগম্য নয়" - --#: ../src/ui/theme.c:2110 ../src/ui/theme.c:2120 ../src/ui/theme.c:2154 -+#: ../src/ui/theme.c:2112 -+#: ../src/ui/theme.c:2122 -+#: ../src/ui/theme.c:2156 - #, c-format - msgid "Coordinate expression results in division by zero" --msgstr "কো-ওর্ডিনেট এক্সপ্রেশনের ফলাফলে শূণ্য দ্বারা ভাগ করার অবস্থা উৎপন্ন হয়" -+msgstr "" -+"কো-ওর্ডিনেট এক্সপ্রেশনের ফলাফলে শূণ্য দ্বারা ভাগ করার অবস্থা উৎপন্ন হয়" - --#: ../src/ui/theme.c:2162 -+#: ../src/ui/theme.c:2164 - #, c-format - msgid "" - "Coordinate expression tries to use mod operator on a floating-point number" - msgstr "" --"কো-ওর্ডিনেট এক্সপ্রেশন দ্বারা ফ্লোটিং পয়েন্ট সংখ্যার উপর mod অপারেটর ব্যবহারের প্রয়াস " --"করা হয়েছে" -+"কো-ওর্ডিনেট এক্সপ্রেশন দ্বারা ফ্লোটিং পয়েন্ট সংখ্যার উপর mod অপারেটর " -+"ব্যবহারের প্রয়াস করা হয়েছে" - --#: ../src/ui/theme.c:2218 -+#: ../src/ui/theme.c:2220 - #, c-format - msgid "" - "Coordinate expression has an operator \"%s\" where an operand was expected" - msgstr "" --"কো-ওর্ডিনেট এক্সপ্রেশনের মধ্যে \"%s\" অপারেটর উপস্থিত কিন্তু অপারেন্ড প্রত্যাশিত" -+"কো-ওর্ডিনেট এক্সপ্রেশনের মধ্যে \"%s\" অপারেটর উপস্থিত কিন্তু অপারেন্ড " -+"প্রত্যাশিত" - --#: ../src/ui/theme.c:2227 -+#: ../src/ui/theme.c:2229 - #, c-format - msgid "Coordinate expression had an operand where an operator was expected" --msgstr "কো-ওর্ডিনেট এক্সপ্রেশনের মধ্যে প্রত্যাশিত অপারেন্ডের পরিবর্তে অপারেটর উপস্থিত" -+msgstr "" -+"কো-ওর্ডিনেট এক্সপ্রেশনের মধ্যে প্রত্যাশিত অপারেন্ডের পরিবর্তে অপারেটর " -+"উপস্থিত" - --#: ../src/ui/theme.c:2235 -+#: ../src/ui/theme.c:2237 - #, c-format - msgid "Coordinate expression ended with an operator instead of an operand" --msgstr "কো-ওর্ডিনেট এক্সপ্রেশনের অন্তে প্রত্যাশিত অপারেন্ডের পরিবর্তে অপারেটর উপস্থিত" -+msgstr "" -+"কো-ওর্ডিনেট এক্সপ্রেশনের অন্তে প্রত্যাশিত অপারেন্ডের পরিবর্তে অপারেটর " -+"উপস্থিত" - --#: ../src/ui/theme.c:2245 -+#: ../src/ui/theme.c:2247 - #, c-format - msgid "" - "Coordinate expression has operator \"%c\" following operator \"%c\" with no " - "operand in between" - msgstr "" --"কো-ওর্ডিনেট এক্সপ্রেশনের ক্ষেত্রে \"%c\" অপারেটরের পরে \"%c\" অপারেটর উপস্থিত এবং " --"দুটির মধ্যে কোনো অপারেন্ড উপস্থিত নেই" -+"কো-ওর্ডিনেট এক্সপ্রেশনের ক্ষেত্রে \"%c\" অপারেটরের পরে \"%c\" অপারেটর " -+"উপস্থিত এবং দুটির মধ্যে কোনো অপারেন্ড উপস্থিত নেই" - --#: ../src/ui/theme.c:2396 ../src/ui/theme.c:2441 -+#: ../src/ui/theme.c:2398 -+#: ../src/ui/theme.c:2443 - #, c-format - msgid "Coordinate expression had unknown variable or constant \"%s\"" --msgstr "কো-ওর্ডিনেট এক্সপ্রেশনের মধ্যে অজানা ভেরিয়েবল অথবা কনস্ট্যান্ট \"%s\" উপস্থিত" -+msgstr "" -+"কো-ওর্ডিনেট এক্সপ্রেশনের মধ্যে অজানা ভেরিয়েবল অথবা কনস্ট্যান্ট \"%s\" " -+"উপস্থিত" - --#: ../src/ui/theme.c:2495 -+#: ../src/ui/theme.c:2497 - #, c-format - msgid "Coordinate expression parser overflowed its buffer." - msgstr "কো-ওর্ডিনেট এক্সপ্রেশনের পার্সারের বাফারের সীমা অতিক্রান্ত হয়েছে।" - --#: ../src/ui/theme.c:2524 -+#: ../src/ui/theme.c:2526 - #, c-format - msgid "Coordinate expression had a close parenthesis with no open parenthesis" - msgstr "" --"কো-ওর্ডিনেট এক্সপ্রেশনের মধ্যে শেষের বন্ধনী চিহ্ন উপস্থিত, প্রারম্ভিক চিহ্ন অনুপস্থিত" -+"কো-ওর্ডিনেট এক্সপ্রেশনের মধ্যে শেষের বন্ধনী চিহ্ন উপস্থিত, প্রারম্ভিক চিহ্ন " -+"অনুপস্থিত" - --#: ../src/ui/theme.c:2588 -+#: ../src/ui/theme.c:2590 - #, c-format --msgid "Coordinate expression had an open parenthesis with no close parenthesis" -+msgid "" -+"Coordinate expression had an open parenthesis with no close parenthesis" - msgstr "" --"কো-ওর্ডিনেট এক্সপ্রেশনের মধ্যে প্রারম্ভিক বন্ধনী চিহ্ন উপস্থিত শেষের বন্ধনী চিহ্ন " --"অনুপস্থিত" -+"কো-ওর্ডিনেট এক্সপ্রেশনের মধ্যে প্রারম্ভিক বন্ধনী চিহ্ন উপস্থিত শেষের বন্ধনী " -+"চিহ্ন অনুপস্থিত" - --#: ../src/ui/theme.c:2599 -+#: ../src/ui/theme.c:2601 - #, c-format - msgid "Coordinate expression doesn't seem to have any operators or operands" - msgstr "কো-ওর্ডিনেট এক্সপ্রেশনের মধ্যে কোনো অপারেটর অথবা অপারেন্ড উপস্থিত নেই" - --#: ../src/ui/theme.c:2812 ../src/ui/theme.c:2832 ../src/ui/theme.c:2852 -+#: ../src/ui/theme.c:2814 -+#: ../src/ui/theme.c:2834 -+#: ../src/ui/theme.c:2854 - #, c-format - msgid "Theme contained an expression that resulted in an error: %s\n" - msgstr "থিমের মধ্যে উপস্থিত এক্সপ্রেশনের ফলে সমস্যা উৎপন্ন হয়েছে: %s\n" - --#: ../src/ui/theme.c:4498 -+#: ../src/ui/theme.c:4500 - #, c-format - msgid "" - "