diff --git a/SOURCES/0001-clutter-avoid-redundant-_clutter_paint_node_init_typ.patch b/SOURCES/0001-clutter-avoid-redundant-_clutter_paint_node_init_typ.patch new file mode 100644 index 0000000..7582a55 --- /dev/null +++ b/SOURCES/0001-clutter-avoid-redundant-_clutter_paint_node_init_typ.patch @@ -0,0 +1,53 @@ +From a9f9f9b36a03535480b31534547bea7c9f7cf4c1 Mon Sep 17 00:00:00 2001 +From: Christian Hergert +Date: Sun, 23 Feb 2020 17:27:08 -0800 +Subject: [PATCH 1/3] clutter: avoid redundant _clutter_paint_node_init_types() + +This only needs to be initialized once but is in the hot path of creating +new paint nodes (for which we create many). Instead, do this as part of +the clutter_init() workflow to keep it out of the hot path. + +https://gitlab.gnome.org/GNOME/mutter/merge_requests/1087 +--- + clutter/clutter/clutter-main.c | 4 ++++ + clutter/clutter/clutter-paint-node.c | 2 -- + 2 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/clutter/clutter/clutter-main.c b/clutter/clutter/clutter-main.c +index 46537f322..8a465fdc2 100644 +--- a/clutter/clutter/clutter-main.c ++++ b/clutter/clutter/clutter-main.c +@@ -63,6 +63,7 @@ + #include "clutter-main.h" + #include "clutter-master-clock.h" + #include "clutter-mutter.h" ++#include "clutter-paint-node-private.h" + #include "clutter-private.h" + #include "clutter-settings-private.h" + #include "clutter-stage-manager.h" +@@ -1390,6 +1391,9 @@ clutter_init_real (GError **error) + if (clutter_enable_accessibility) + cally_accessibility_init (); + ++ /* Initialize types required for paint nodes */ ++ _clutter_paint_node_init_types (); ++ + return CLUTTER_INIT_SUCCESS; + } + +diff --git a/clutter/clutter/clutter-paint-node.c b/clutter/clutter/clutter-paint-node.c +index 391f48398..db68b7766 100644 +--- a/clutter/clutter/clutter-paint-node.c ++++ b/clutter/clutter/clutter-paint-node.c +@@ -1113,8 +1113,6 @@ _clutter_paint_node_create (GType gtype) + { + g_return_val_if_fail (g_type_is_a (gtype, CLUTTER_TYPE_PAINT_NODE), NULL); + +- _clutter_paint_node_init_types (); +- + return (gpointer) g_type_create_instance (gtype); + } + +-- +2.26.0 + diff --git a/SOURCES/0001-screen-Expose-workspace-layout-properties.patch b/SOURCES/0001-screen-Expose-workspace-layout-properties.patch index bc7ed96..9a0eb8b 100644 --- a/SOURCES/0001-screen-Expose-workspace-layout-properties.patch +++ b/SOURCES/0001-screen-Expose-workspace-layout-properties.patch @@ -1,4 +1,4 @@ -From 6b8e2636911c79d77d95aaac62336dd4f4063f63 Mon Sep 17 00:00:00 2001 +From 5efefc0e46963749a53a8d81ff6641fd6f9e6e1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Tue, 4 Jun 2019 21:21:37 +0200 Subject: [PATCH] screen: Expose workspace layout properties @@ -13,11 +13,11 @@ workspace layouts it supports. https://gitlab.gnome.org/GNOME/mutter/merge_requests/618 --- - src/core/screen.c | 27 +++++++++++++++++++++++++++ - 1 file changed, 27 insertions(+) + src/core/screen.c | 30 ++++++++++++++++++++++++++++++ + 1 file changed, 30 insertions(+) diff --git a/src/core/screen.c b/src/core/screen.c -index c14bba0cf..4fac02cdb 100644 +index c14bba0cf..090baecda 100644 --- a/src/core/screen.c +++ b/src/core/screen.c @@ -81,6 +81,9 @@ static void on_monitors_changed (MetaMonitorManager *manager, @@ -75,6 +75,16 @@ index c14bba0cf..4fac02cdb 100644 } /** +@@ -1785,6 +1812,9 @@ meta_screen_override_workspace_layout (MetaScreen *screen, + screen->rows_of_workspaces = n_rows; + screen->columns_of_workspaces = n_columns; + ++ g_object_notify (G_OBJECT (screen), "layout-columns"); ++ g_object_notify (G_OBJECT (screen), "layout-rows"); ++ + /* In theory we should remove _NET_DESKTOP_LAYOUT from _NET_SUPPORTED at this + * point, but it's unlikely that anybody checks that, and it's unlikely that + * anybody who checks that handles changes, so we'd probably just create -- -2.21.0 +2.26.2 diff --git a/SOURCES/0001-stage-x11-Check-that-message-is-WM_PROTOCOLS-before-.patch b/SOURCES/0001-stage-x11-Check-that-message-is-WM_PROTOCOLS-before-.patch new file mode 100644 index 0000000..f8c8ae7 --- /dev/null +++ b/SOURCES/0001-stage-x11-Check-that-message-is-WM_PROTOCOLS-before-.patch @@ -0,0 +1,101 @@ +From 0f9e86c21d35c8e2760a2de6ea22ebd271810483 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jonas=20=C3=85dahl?= +Date: Thu, 18 Jun 2020 21:17:29 +0200 +Subject: [PATCH] stage/x11: Check that message is WM_PROTOCOLS before assuming + so + +When a touch sequence was rejected, we'd update the event timestamps of +incoming touch events to help with implementing grabs. This was done by +sending a ClientMessage with a counter, and comparing the counter to +decide whether we're seing a replayed event or not. + +This had the unforseen consequence that we would potentially end up +destroying all actors including the stage, since, when mutter receives a +ClientMessage event, it would assume that it's a WM_PROTOCOLS event, and +handle it as such. The problem with this approach is that it would +ignore fact that there might be other ClientMessage types sent to it, +for example the touch synchronization one. What could happen is that the +touch count value would match up with the value of the WM_DELETE_WINDOW +atom, clutter would treat this as WM_PROTOCOLS:WM_DELETE_WINDOW, which +it'd translate to clutter_actor_destroy(stage). + +Destroying the stage in such a way is not expected, and caused wierd +crashes in different places depending on what was going on. + +This commit make sure we only treat WM_PROTOCOLS client messages as +WM_PROTOCOLS client messages effectively avoiding the issue. + +This fixes crashes such as: + + #0 meta_window_get_buffer_rect (window=0x0, rect=rect@entry=0x7ffd7fc62e40) at core/window.c:4396 + #1 0x00007f1e2634837f in get_top_visible_window_actor (compositor=0x297d700, compositor=0x297d700) at compositor/compositor.c:1059 + #2 meta_compositor_sync_stack (compositor=0x297d700, stack=, stack@entry=0x26e3140) at compositor/compositor.c:1176 + #3 0x00007f1e263757ac in meta_stack_tracker_sync_stack (tracker=0x297dbc0) at core/stack-tracker.c:871 + #4 0x00007f1e26375899 in stack_tracker_sync_stack_later (data=) at core/stack-tracker.c:881 + #5 0x00007f1e26376914 in run_repaint_laters (laters_list=0x7f1e2663b7d8 ) at core/util.c:809 + #6 run_all_repaint_laters (data=) at core/util.c:826 + #7 0x00007f1e26b18325 in _clutter_run_repaint_functions (flags=flags@entry=CLUTTER_REPAINT_FLAGS_PRE_PAINT) at clutter-main.c:3448 + #8 0x00007f1e26b18fc5 in master_clock_update_stages (master_clock=0x32d6a80, stages=0x4e5a740) at clutter-master-clock-default.c:437 + #9 clutter_clock_dispatch (source=, callback=, user_data=) at clutter-master-clock-default.c:567 + #10 0x00007f1e27e48049 in g_main_dispatch (context=0x225b8d0) at gmain.c:3175 + #11 g_main_context_dispatch (context=context@entry=0x225b8d0) at gmain.c:3828 + #12 0x00007f1e27e483a8 in g_main_context_iterate (context=0x225b8d0, block=block@entry=1, dispatch=dispatch@entry=1, self=) at gmain.c:3901 + #13 0x00007f1e27e4867a in g_main_loop_run (loop=0x24e29f0) at gmain.c:4097 + #14 0x00007f1e2636a3dc in meta_run () at core/main.c:666 + #15 0x000000000040219c in main (argc=1, argv=0x7ffd7fc63238) at ../src/main.c:534 + +and + + #0 0x00007f93943c1f25 in raise () at /usr/lib/libc.so.6 + #1 0x00007f93943ab897 in abort () at /usr/lib/libc.so.6 + #2 0x00007f9393e1e062 in g_assertion_message (domain=, file=, line=, func=0x7f93933e6860 <__func__.116322> "meta_x11_get_stage_window", + #3 0x00007f9393e4ab1d in g_assertion_message_expr () + #4 0x00007f939338ecd7 in meta_x11_get_stage_window (stage=) at ../mutter/src/backends/x11/meta-stage-x11.c:923 + #5 0x00007f939339e599 in meta_backend_x11_cm_translate_device_event (x11=, device_event=0x55bc8bcfd6b0) at ../mutter/src/backends/x11/cm/meta-backend-x11-cm.c:381 + #6 0x00007f939339f2e2 in meta_backend_x11_translate_device_event (device_event=0x55bc8bcfd6b0, x11=0x55bc89dd5220) at ../mutter/src/backends/x11/meta-backend-x11.c:179 + #7 0x00007f939339f2e2 in translate_device_event (device_event=0x55bc8bcfd6b0, x11=0x55bc89dd5220) at ../mutter/src/backends/x11/meta-backend-x11.c:208 + #8 0x00007f939339f2e2 in maybe_spoof_event_as_stage_event (input_event=0x55bc8bcfd6b0, x11=0x55bc89dd5220) at ../mutter/src/backends/x11/meta-backend-x11.c:284 + #9 0x00007f939339f2e2 in handle_input_event (event=0x7fff62d60490, x11=0x55bc89dd5220) at ../mutter/src/backends/x11/meta-backend-x11.c:309 + #10 0x00007f939339f2e2 in handle_host_xevent (event=0x7fff62d60490, backend=0x55bc89dd5220) at ../mutter/src/backends/x11/meta-backend-x11.c:413 + #11 0x00007f939339f2e2 in x_event_source_dispatch (source=, callback=, user_data=) at ../mutter/src/backends/x11/meta-backend-x11.c:467 + #12 0x00007f9393e6c39e in g_main_dispatch (context=0x55bc89dd03e0) at ../glib/glib/gmain.c:3179 + #13 0x00007f9393e6c39e in g_main_context_dispatch (context=context@entry=0x55bc89dd03e0) at ../glib/glib/gmain.c:3844 + #14 0x00007f9393e6e1b1 in g_main_context_iterate (context=0x55bc89dd03e0, block=block@entry=1, dispatch=dispatch@entry=1, self=) at ../glib/glib/gmain.c:3917 + #15 0x00007f9393e6f0c3 in g_main_loop_run (loop=0x55bc8a042640) at ../glib/glib/gmain.c:4111 + #16 0x00007f9393369a0c in meta_run () at ../mutter/src/core/main.c:676 + #17 0x000055bc880f2426 in main (argc=, argv=) at ../gnome-shell/src/main.c:552 + +Related: https://gitlab.gnome.org/GNOME/mutter/-/issues/338 +Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/951 + +https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1317 +--- + clutter/clutter/x11/clutter-stage-x11.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/clutter/clutter/x11/clutter-stage-x11.c b/clutter/clutter/x11/clutter-stage-x11.c +index 1ee2f40ab0..bd5aabc884 100644 +--- a/clutter/clutter/x11/clutter-stage-x11.c ++++ b/clutter/clutter/x11/clutter-stage-x11.c +@@ -1306,11 +1306,14 @@ clutter_stage_x11_translate_event (ClutterEventTranslator *translator, + _clutter_actor_get_debug_name (CLUTTER_ACTOR (stage)), + stage, + (unsigned int) stage_xwindow); +- if (handle_wm_protocols_event (backend_x11, stage_x11, xevent)) ++ if (xevent->xclient.message_type == backend_x11->atom_WM_PROTOCOLS) + { +- event->any.type = CLUTTER_DELETE; +- event->any.stage = stage; +- res = CLUTTER_TRANSLATE_QUEUE; ++ if (handle_wm_protocols_event (backend_x11, stage_x11, xevent)) ++ { ++ event->any.type = CLUTTER_DELETE; ++ event->any.stage = stage; ++ res = CLUTTER_TRANSLATE_QUEUE; ++ } + } + break; + +-- +2.26.2 + diff --git a/SOURCES/0002-clutter-avoid-g_signal_emit_by_name-from-ClutterActo.patch b/SOURCES/0002-clutter-avoid-g_signal_emit_by_name-from-ClutterActo.patch new file mode 100644 index 0000000..5746804 --- /dev/null +++ b/SOURCES/0002-clutter-avoid-g_signal_emit_by_name-from-ClutterActo.patch @@ -0,0 +1,192 @@ +From 04e5e144ce21c811601e169c13fdef7b8edeae12 Mon Sep 17 00:00:00 2001 +From: Christian Hergert +Date: Mon, 24 Feb 2020 22:36:27 +0000 +Subject: [PATCH 2/3] clutter: avoid g_signal_emit_by_name() from ClutterActor + +g_signal_emit_by_name() is used to emit signals on ClutterContainer when +actors are removed or added. It happens to do various interface lookups +which are a bit unneccessary and can allocate memory. + +Simply using emission wrappers makes all of that go away. + +https://gitlab.gnome.org/GNOME/mutter/merge_requests/1083 +--- + clutter/clutter/cally/cally-actor.c | 5 +-- + clutter/clutter/clutter-actor.c | 17 ++++++++-- + clutter/clutter/clutter-actor.h | 5 ++- + clutter/clutter/clutter-container-private.h | 36 +++++++++++++++++++++ + clutter/clutter/clutter-container.c | 21 ++++++++++++ + 5 files changed, 78 insertions(+), 6 deletions(-) + create mode 100644 clutter/clutter/clutter-container-private.h + +diff --git a/clutter/clutter/cally/cally-actor.c b/clutter/clutter/cally/cally-actor.c +index f341d3616..77195c0b0 100644 +--- a/clutter/clutter/cally/cally-actor.c ++++ b/clutter/clutter/cally/cally-actor.c +@@ -606,10 +606,11 @@ cally_actor_real_remove_actor (ClutterActor *container, + g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), 0); + + atk_parent = ATK_OBJECT (data); +- atk_child = clutter_actor_get_accessible (actor); + +- if (atk_child) ++ if (clutter_actor_has_accessible (actor)) + { ++ atk_child = clutter_actor_get_accessible (actor); ++ + g_value_init (&values.old_value, G_TYPE_POINTER); + g_value_set_pointer (&values.old_value, atk_parent); + +diff --git a/clutter/clutter/clutter-actor.c b/clutter/clutter/clutter-actor.c +index 6954f0396..8da53d3f1 100644 +--- a/clutter/clutter/clutter-actor.c ++++ b/clutter/clutter/clutter-actor.c +@@ -624,7 +624,7 @@ + #include "clutter-color-static.h" + #include "clutter-color.h" + #include "clutter-constraint-private.h" +-#include "clutter-container.h" ++#include "clutter-container-private.h" + #include "clutter-content-private.h" + #include "clutter-debug.h" + #include "clutter-easing.h" +@@ -4310,7 +4310,7 @@ clutter_actor_remove_child_internal (ClutterActor *self, + + /* we need to emit the signal before dropping the reference */ + if (emit_actor_removed) +- g_signal_emit_by_name (self, "actor-removed", child); ++ _clutter_container_emit_actor_removed (CLUTTER_CONTAINER (self), child); + + if (notify_first_last) + { +@@ -12980,7 +12980,7 @@ clutter_actor_add_child_internal (ClutterActor *self, + } + + if (emit_actor_added) +- g_signal_emit_by_name (self, "actor-added", child); ++ _clutter_container_emit_actor_added (CLUTTER_CONTAINER (self), child); + + if (notify_first_last) + { +@@ -21150,3 +21150,14 @@ clutter_actor_create_texture_paint_node (ClutterActor *self, + + return node; + } ++ ++gboolean ++clutter_actor_has_accessible (ClutterActor *actor) ++{ ++ g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), FALSE); ++ ++ if (CLUTTER_ACTOR_GET_CLASS (actor)->has_accessible) ++ return CLUTTER_ACTOR_GET_CLASS (actor)->has_accessible (actor); ++ ++ return TRUE; ++} +diff --git a/clutter/clutter/clutter-actor.h b/clutter/clutter/clutter-actor.h +index 0c5a08c8c..9b0665c72 100644 +--- a/clutter/clutter/clutter-actor.h ++++ b/clutter/clutter/clutter-actor.h +@@ -295,10 +295,11 @@ struct _ClutterActorClass + + gboolean (* touch_event) (ClutterActor *self, + ClutterTouchEvent *event); ++ gboolean (* has_accessible) (ClutterActor *self); + + /*< private >*/ + /* padding for future expansion */ +- gpointer _padding_dummy[26]; ++ gpointer _padding_dummy[25]; + }; + + /** +@@ -368,6 +369,8 @@ CLUTTER_AVAILABLE_IN_ALL + const gchar * clutter_actor_get_name (ClutterActor *self); + CLUTTER_AVAILABLE_IN_ALL + AtkObject * clutter_actor_get_accessible (ClutterActor *self); ++CLUTTER_AVAILABLE_IN_ALL ++gboolean clutter_actor_has_accessible (ClutterActor *self); + + CLUTTER_AVAILABLE_IN_1_24 + gboolean clutter_actor_is_visible (ClutterActor *self); +diff --git a/clutter/clutter/clutter-container-private.h b/clutter/clutter/clutter-container-private.h +new file mode 100644 +index 000000000..d619a6531 +--- /dev/null ++++ b/clutter/clutter/clutter-container-private.h +@@ -0,0 +1,36 @@ ++/* ++ * Clutter. ++ * ++ * An OpenGL based 'interactive canvas' library. ++ * ++ * Copyright 2020 Red Hat, Inc. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library 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 ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library. If not, see . ++ */ ++ ++#ifndef __CLUTTER_CONTAINER_PRIVATE_H__ ++#define __CLUTTER_CONTAINER_PRIVATE_H__ ++ ++#include ++ ++G_BEGIN_DECLS ++ ++void _clutter_container_emit_actor_added (ClutterContainer *container, ++ ClutterActor *actor); ++void _clutter_container_emit_actor_removed (ClutterContainer *container, ++ ClutterActor *actor); ++ ++G_END_DECLS ++ ++#endif /* __CLUTTER_CONTAINER_PRIVATE_H__ */ +diff --git a/clutter/clutter/clutter-container.c b/clutter/clutter/clutter-container.c +index 81fe4dc2e..52942a246 100644 +--- a/clutter/clutter/clutter-container.c ++++ b/clutter/clutter/clutter-container.c +@@ -39,6 +39,7 @@ + + #include "clutter-actor-private.h" + #include "clutter-child-meta.h" ++#include "clutter-container-private.h" + #include "clutter-debug.h" + #include "clutter-main.h" + #include "clutter-marshal.h" +@@ -1448,3 +1449,23 @@ clutter_container_child_notify (ClutterContainer *container, + child, + pspec); + } ++ ++void ++_clutter_container_emit_actor_added (ClutterContainer *container, ++ ClutterActor *actor) ++{ ++ g_return_if_fail (CLUTTER_IS_CONTAINER (container)); ++ g_return_if_fail (CLUTTER_IS_ACTOR (actor)); ++ ++ g_signal_emit (container, container_signals[ACTOR_ADDED], 0, actor); ++} ++ ++void ++_clutter_container_emit_actor_removed (ClutterContainer *container, ++ ClutterActor *actor) ++{ ++ g_return_if_fail (CLUTTER_IS_CONTAINER (container)); ++ g_return_if_fail (CLUTTER_IS_ACTOR (actor)); ++ ++ g_signal_emit (container, container_signals[ACTOR_REMOVED], 0, actor); ++} +-- +2.26.0 + diff --git a/SOURCES/0003-clutter-fix-hole-in-ClutterPaintNode.patch b/SOURCES/0003-clutter-fix-hole-in-ClutterPaintNode.patch new file mode 100644 index 0000000..0440f51 --- /dev/null +++ b/SOURCES/0003-clutter-fix-hole-in-ClutterPaintNode.patch @@ -0,0 +1,167 @@ +From 6d849de8ff486be21ff931bfa63313240b212852 Mon Sep 17 00:00:00 2001 +From: Christian Hergert +Date: Fri, 21 Feb 2020 22:36:31 +0000 +Subject: [PATCH 3/3] clutter: fix hole in ClutterPaintNode + +Fixing the missalignment takes the structure from 80 bytes down to 72. + +https://gitlab.gnome.org/GNOME/mutter/merge_requests/1081 +--- + clutter/clutter/clutter-actor.c | 8 +++---- + clutter/clutter/clutter-canvas.c | 2 +- + clutter/clutter/clutter-image.c | 2 +- + clutter/clutter/clutter-paint-node-private.h | 6 ++--- + clutter/clutter/clutter-paint-node.c | 23 +++++++++++++++----- + clutter/clutter/clutter-paint-node.h | 3 +++ + 6 files changed, 30 insertions(+), 14 deletions(-) + +diff --git a/clutter/clutter/clutter-actor.c b/clutter/clutter/clutter-actor.c +index 8da53d3f1..995de8c35 100644 +--- a/clutter/clutter/clutter-actor.c ++++ b/clutter/clutter/clutter-actor.c +@@ -3692,7 +3692,7 @@ clutter_actor_paint_node (ClutterActor *actor, + clear_flags |= COGL_BUFFER_BIT_COLOR; + + node = _clutter_root_node_new (fb, &bg_color, clear_flags); +- clutter_paint_node_set_name (node, "stageClear"); ++ clutter_paint_node_set_static_name (node, "stageClear"); + clutter_paint_node_add_rectangle (node, &box); + clutter_paint_node_add_child (root, node); + clutter_paint_node_unref (node); +@@ -3707,7 +3707,7 @@ clutter_actor_paint_node (ClutterActor *actor, + / 255; + + node = clutter_color_node_new (&bg_color); +- clutter_paint_node_set_name (node, "backgroundColor"); ++ clutter_paint_node_set_static_name (node, "backgroundColor"); + clutter_paint_node_add_rectangle (node, &box); + clutter_paint_node_add_child (root, node); + clutter_paint_node_unref (node); +@@ -4014,7 +4014,7 @@ clutter_actor_continue_paint (ClutterActor *self) + * virtual function can then be called directly. + */ + dummy = _clutter_dummy_node_new (self); +- clutter_paint_node_set_name (dummy, "Root"); ++ clutter_paint_node_set_static_name (dummy, "Root"); + + /* XXX - for 1.12, we use the return value of paint_node() to + * decide whether we should emit the ::paint signal. +@@ -21129,7 +21129,7 @@ clutter_actor_create_texture_paint_node (ClutterActor *self, + color.alpha = clutter_actor_get_paint_opacity_internal (self); + + node = clutter_texture_node_new (texture, &color, priv->min_filter, priv->mag_filter); +- clutter_paint_node_set_name (node, "Texture"); ++ clutter_paint_node_set_static_name (node, "Texture"); + + if (priv->content_repeat == CLUTTER_REPEAT_NONE) + clutter_paint_node_add_rectangle (node, &box); +diff --git a/clutter/clutter/clutter-canvas.c b/clutter/clutter/clutter-canvas.c +index 42e54ce9d..512e434ed 100644 +--- a/clutter/clutter/clutter-canvas.c ++++ b/clutter/clutter/clutter-canvas.c +@@ -319,7 +319,7 @@ clutter_canvas_paint_content (ClutterContent *content, + return; + + node = clutter_actor_create_texture_paint_node (actor, priv->texture); +- clutter_paint_node_set_name (node, "Canvas Content"); ++ clutter_paint_node_set_static_name (node, "Canvas Content"); + clutter_paint_node_add_child (root, node); + clutter_paint_node_unref (node); + +diff --git a/clutter/clutter/clutter-image.c b/clutter/clutter/clutter-image.c +index 722b0375d..51e610073 100644 +--- a/clutter/clutter/clutter-image.c ++++ b/clutter/clutter/clutter-image.c +@@ -108,7 +108,7 @@ clutter_image_paint_content (ClutterContent *content, + return; + + node = clutter_actor_create_texture_paint_node (actor, priv->texture); +- clutter_paint_node_set_name (node, "Image Content"); ++ clutter_paint_node_set_static_name (node, "Image Content"); + clutter_paint_node_add_child (root, node); + clutter_paint_node_unref (node); + } +diff --git a/clutter/clutter/clutter-paint-node-private.h b/clutter/clutter/clutter-paint-node-private.h +index 2945b78a4..ea1665ada 100644 +--- a/clutter/clutter/clutter-paint-node-private.h ++++ b/clutter/clutter/clutter-paint-node-private.h +@@ -48,11 +48,11 @@ struct _ClutterPaintNode + ClutterPaintNode *next_sibling; + ClutterPaintNode *last_child; + +- guint n_children; +- + GArray *operations; + +- gchar *name; ++ const gchar *name; ++ ++ guint n_children; + + volatile int ref_count; + }; +diff --git a/clutter/clutter/clutter-paint-node.c b/clutter/clutter/clutter-paint-node.c +index db68b7766..5129e00cf 100644 +--- a/clutter/clutter/clutter-paint-node.c ++++ b/clutter/clutter/clutter-paint-node.c +@@ -173,8 +173,6 @@ clutter_paint_node_real_finalize (ClutterPaintNode *node) + { + ClutterPaintNode *iter; + +- g_free (node->name); +- + if (node->operations != NULL) + { + guint i; +@@ -296,7 +294,8 @@ clutter_paint_node_get_type (void) + * + * The @name will be used for debugging purposes. + * +- * The @node will copy the passed string. ++ * The @node will intern @name using g_intern_string(). If you have access to a ++ * static string, use clutter_paint_node_set_static_name() instead. + * + * Since: 1.10 + */ +@@ -306,8 +305,22 @@ clutter_paint_node_set_name (ClutterPaintNode *node, + { + g_return_if_fail (CLUTTER_IS_PAINT_NODE (node)); + +- g_free (node->name); +- node->name = g_strdup (name); ++ node->name = g_intern_string (name); ++} ++ ++/** ++ * clutter_paint_node_set_static_name: (skip) ++ * ++ * Like clutter_paint_node_set_name() but uses a static or interned string ++ * containing the name. ++ */ ++void ++clutter_paint_node_set_static_name (ClutterPaintNode *node, ++ const char *name) ++{ ++ g_return_if_fail (CLUTTER_IS_PAINT_NODE (node)); ++ ++ node->name = name; + } + + /** +diff --git a/clutter/clutter/clutter-paint-node.h b/clutter/clutter/clutter-paint-node.h +index 5f3e962e4..d3e4e7922 100644 +--- a/clutter/clutter/clutter-paint-node.h ++++ b/clutter/clutter/clutter-paint-node.h +@@ -52,6 +52,9 @@ void clutter_paint_node_unref (Clutter + CLUTTER_AVAILABLE_IN_1_10 + void clutter_paint_node_set_name (ClutterPaintNode *node, + const char *name); ++CLUTTER_AVAILABLE_IN_ALL ++void clutter_paint_node_set_static_name (ClutterPaintNode *node, ++ const char *name); + + CLUTTER_AVAILABLE_IN_1_10 + void clutter_paint_node_add_child (ClutterPaintNode *node, +-- +2.26.0 + diff --git a/SOURCES/fix-extended-osk-characters.patch b/SOURCES/fix-extended-osk-characters.patch new file mode 100644 index 0000000..d6a8c6b --- /dev/null +++ b/SOURCES/fix-extended-osk-characters.patch @@ -0,0 +1,272 @@ +From a9c7fb96d9d03547d53c6fdd27a1cf6f4d00b17d Mon Sep 17 00:00:00 2001 +From: Andrea Azzarone +Date: Fri, 13 Jul 2018 14:49:38 +0200 +Subject: [PATCH] clutter/x11: Implement keycode remap to keysyms on virtual + key devices + +Keycode lookup can fail for serveral reasons, e.g. if there is no combination of +modifiers and keycodes that can produce the target keysym with the current +keyboard layout. + +In case the keycode lookup fails, remap temporarily the keysym to an unused +keycodes. + +Fixes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/109 +--- + clutter/clutter/x11/clutter-keymap-x11.c | 154 ++++++++++++++++++ + clutter/clutter/x11/clutter-keymap-x11.h | 6 +- + .../x11/clutter-virtual-input-device-x11.c | 19 ++- + 3 files changed, 173 insertions(+), 6 deletions(-) + +diff --git a/clutter/clutter/x11/clutter-keymap-x11.c b/clutter/clutter/x11/clutter-keymap-x11.c +index c34e676a4..744fab979 100644 +--- a/clutter/clutter/x11/clutter-keymap-x11.c ++++ b/clutter/clutter/x11/clutter-keymap-x11.c +@@ -81,6 +81,9 @@ struct _ClutterKeymapX11 + int current_group; + #endif + ++ GHashTable *reserved_keycodes; ++ GQueue *available_keycodes; ++ + guint caps_lock_state : 1; + guint num_lock_state : 1; + guint has_direction : 1; +@@ -441,15 +444,98 @@ clutter_keymap_x11_set_property (GObject *gobject, + } + } + ++static void ++clutter_keymap_x11_refresh_reserved_keycodes (ClutterKeymapX11 *keymap_x11) ++{ ++ Display *dpy = clutter_x11_get_default_display (); ++ GHashTableIter iter; ++ gpointer key, value; ++ ++ g_hash_table_iter_init (&iter, keymap_x11->reserved_keycodes); ++ while (g_hash_table_iter_next (&iter, &key, &value)) ++ { ++ guint reserved_keycode = GPOINTER_TO_UINT (key); ++ guint reserved_keysym = GPOINTER_TO_UINT (value); ++ guint actual_keysym = XkbKeycodeToKeysym (dpy, reserved_keycode, 0, 0); ++ ++ /* If an available keycode is no longer mapped to the stored keysym, then ++ * the keycode should not be considered available anymore and should be ++ * removed both from the list of available and reserved keycodes. ++ */ ++ if (reserved_keysym != actual_keysym) ++ { ++ g_hash_table_iter_remove (&iter); ++ g_queue_remove (keymap_x11->available_keycodes, key); ++ } ++ } ++} ++ ++static gboolean ++clutter_keymap_x11_replace_keycode (ClutterKeymapX11 *keymap_x11, ++ KeyCode keycode, ++ KeySym keysym) ++{ ++ if (CLUTTER_BACKEND_X11 (keymap_x11->backend)->use_xkb) ++ { ++ Display *dpy = clutter_x11_get_default_display (); ++ XkbDescPtr xkb = get_xkb (keymap_x11); ++ XkbMapChangesRec changes; ++ ++ XFlush (dpy); ++ ++ xkb->device_spec = XkbUseCoreKbd; ++ memset (&changes, 0, sizeof(changes)); ++ ++ if (keysym != NoSymbol) ++ { ++ int types[XkbNumKbdGroups] = { XkbOneLevelIndex }; ++ XkbChangeTypesOfKey (xkb, keycode, 1, XkbGroup1Mask, types, &changes); ++ XkbKeySymEntry (xkb, keycode, 0, 0) = keysym; ++ } ++ else ++ { ++ /* Reset to NoSymbol */ ++ XkbChangeTypesOfKey (xkb, keycode, 0, XkbGroup1Mask, NULL, &changes); ++ } ++ ++ changes.changed = XkbKeySymsMask | XkbKeyTypesMask; ++ changes.first_key_sym = keycode; ++ changes.num_key_syms = 1; ++ changes.first_type = 0; ++ changes.num_types = xkb->map->num_types; ++ XkbChangeMap (dpy, xkb, &changes); ++ ++ XFlush (dpy); ++ ++ return TRUE; ++ } ++ ++ return FALSE; ++} ++ + static void + clutter_keymap_x11_finalize (GObject *gobject) + { + ClutterKeymapX11 *keymap; + ClutterEventTranslator *translator; ++ GHashTableIter iter; ++ gpointer key, value; + + keymap = CLUTTER_KEYMAP_X11 (gobject); + translator = CLUTTER_EVENT_TRANSLATOR (keymap); + ++ clutter_keymap_x11_refresh_reserved_keycodes (keymap); ++ g_hash_table_iter_init (&iter, keymap->reserved_keycodes); ++ while (g_hash_table_iter_next (&iter, &key, &value)) ++ { ++ guint keycode = GPOINTER_TO_UINT (key); ++ clutter_keymap_x11_replace_keycode (keymap, keycode, NoSymbol); ++ } ++ ++ g_hash_table_destroy (keymap->reserved_keycodes); ++ g_queue_free (keymap->available_keycodes); ++ ++ + #ifdef HAVE_XKB + _clutter_backend_remove_event_translator (keymap->backend, translator); + +@@ -483,6 +569,8 @@ clutter_keymap_x11_init (ClutterKeymapX11 *keymap) + { + keymap->current_direction = PANGO_DIRECTION_NEUTRAL; + keymap->current_group = -1; ++ keymap->reserved_keycodes = g_hash_table_new (NULL, NULL); ++ keymap->available_keycodes = g_queue_new (); + } + + static ClutterTranslateReturn +@@ -766,6 +854,72 @@ clutter_keymap_x11_get_entries_for_keyval (ClutterKeymapX11 *keymap_x11, + } + } + ++static guint ++clutter_keymap_x11_get_available_keycode (ClutterKeymapX11 *keymap_x11) ++{ ++ if (CLUTTER_BACKEND_X11 (keymap_x11->backend)->use_xkb) ++ { ++ clutter_keymap_x11_refresh_reserved_keycodes (keymap_x11); ++ ++ if (g_hash_table_size (keymap_x11->reserved_keycodes) < 5) ++ { ++ Display *dpy = clutter_x11_get_default_display (); ++ XkbDescPtr xkb = get_xkb (keymap_x11); ++ guint i; ++ ++ for (i = xkb->max_key_code; i >= xkb->min_key_code; --i) ++ { ++ if (XkbKeycodeToKeysym (dpy, i, 0, 0) == NoSymbol) ++ return i; ++ } ++ } ++ ++ return GPOINTER_TO_UINT (g_queue_pop_head (keymap_x11->available_keycodes)); ++ } ++ ++ return 0; ++} ++ ++gboolean clutter_keymap_x11_reserve_keycode (ClutterKeymapX11 *keymap_x11, ++ guint keyval, ++ guint *keycode_out) ++{ ++ g_return_val_if_fail (CLUTTER_IS_KEYMAP_X11 (keymap_x11), FALSE); ++ g_return_val_if_fail (keyval != 0, FALSE); ++ g_return_val_if_fail (keycode_out != NULL, FALSE); ++ ++ *keycode_out = clutter_keymap_x11_get_available_keycode (keymap_x11); ++ ++ if (*keycode_out == NoSymbol) ++ { ++ g_warning ("Cannot reserve a keycode for keyval %d: no available keycode", keyval); ++ return FALSE; ++ } ++ ++ if (!clutter_keymap_x11_replace_keycode (keymap_x11, *keycode_out, keyval)) ++ { ++ g_warning ("Failed to remap keycode %d to keyval %d", *keycode_out, keyval); ++ return FALSE; ++ } ++ ++ g_hash_table_insert (keymap_x11->reserved_keycodes, GUINT_TO_POINTER (*keycode_out), GUINT_TO_POINTER (keyval)); ++ g_queue_remove (keymap_x11->available_keycodes, GUINT_TO_POINTER (*keycode_out)); ++ ++ return TRUE; ++} ++ ++void clutter_keymap_x11_release_keycode_if_needed (ClutterKeymapX11 *keymap_x11, ++ guint keycode) ++{ ++ g_return_if_fail (CLUTTER_IS_KEYMAP_X11 (keymap_x11)); ++ ++ if (!g_hash_table_contains (keymap_x11->reserved_keycodes, GUINT_TO_POINTER (keycode)) || ++ g_queue_index (keymap_x11->available_keycodes, GUINT_TO_POINTER (keycode)) != -1) ++ return; ++ ++ g_queue_push_tail (keymap_x11->available_keycodes, GUINT_TO_POINTER (keycode)); ++} ++ + void + clutter_keymap_x11_latch_modifiers (ClutterKeymapX11 *keymap_x11, + uint32_t level, +diff --git a/clutter/clutter/x11/clutter-keymap-x11.h b/clutter/clutter/x11/clutter-keymap-x11.h +index 4b5b403c8..4decb44ee 100644 +--- a/clutter/clutter/x11/clutter-keymap-x11.h ++++ b/clutter/clutter/x11/clutter-keymap-x11.h +@@ -58,7 +58,11 @@ gboolean clutter_keymap_x11_keycode_for_keyval (ClutterKeymapX11 *keymap_x11, + void clutter_keymap_x11_latch_modifiers (ClutterKeymapX11 *keymap_x11, + uint32_t level, + gboolean enable); +- ++gboolean clutter_keymap_x11_reserve_keycode (ClutterKeymapX11 *keymap_x11, ++ guint keyval, ++ guint *keycode_out); ++void clutter_keymap_x11_release_keycode_if_needed (ClutterKeymapX11 *keymap_x11, ++ guint keycode); + G_END_DECLS + + #endif /* __CLUTTER_KEYMAP_X11_H__ */ +diff --git a/clutter/clutter/x11/clutter-virtual-input-device-x11.c b/clutter/clutter/x11/clutter-virtual-input-device-x11.c +index e16ba3fd0..cab26c38c 100644 +--- a/clutter/clutter/x11/clutter-virtual-input-device-x11.c ++++ b/clutter/clutter/x11/clutter-virtual-input-device-x11.c +@@ -143,8 +143,13 @@ clutter_virtual_input_device_x11_notify_keyval (ClutterVirtualInputDevice *virtu + + if (!clutter_keymap_x11_keycode_for_keyval (keymap, keyval, &keycode, &level)) + { +- g_warning ("No keycode found for keyval %x in current group", keyval); +- return; ++ level = 0; ++ ++ if (!clutter_keymap_x11_reserve_keycode (keymap, keyval, &keycode)) ++ { ++ g_warning ("No keycode found for keyval %x in current group", keyval); ++ return; ++ } + } + + if (!_clutter_keymap_x11_get_is_modifier (keymap, keycode) && +@@ -155,9 +160,13 @@ clutter_virtual_input_device_x11_notify_keyval (ClutterVirtualInputDevice *virtu + (KeyCode) keycode, + key_state == CLUTTER_KEY_STATE_PRESSED, 0); + +- if (!_clutter_keymap_x11_get_is_modifier (keymap, keycode) && +- key_state == CLUTTER_KEY_STATE_RELEASED) +- clutter_keymap_x11_latch_modifiers (keymap, level, FALSE); ++ ++ if (key_state == CLUTTER_KEY_STATE_RELEASED) ++ { ++ if (!_clutter_keymap_x11_get_is_modifier (keymap, keycode)) ++ clutter_keymap_x11_latch_modifiers (keymap, level, FALSE); ++ clutter_keymap_x11_release_keycode_if_needed (keymap, keycode); ++ } + } + + static void +-- +2.26.2 + diff --git a/SPECS/mutter.spec b/SPECS/mutter.spec index 7c8e110..964b556 100644 --- a/SPECS/mutter.spec +++ b/SPECS/mutter.spec @@ -10,7 +10,7 @@ Name: mutter Version: 3.28.3 -Release: 22%{?dist} +Release: 26%{?dist} Summary: Window and compositing manager based on Clutter License: GPLv2+ @@ -115,6 +115,17 @@ Patch284: 0001-core-Hide-close-dialog-before-destroying.patch # Add PING_TIMEOUT_DELAY to mutter MetaPreferences #1809164 Patch285: 0001-display-Make-check-alive-timeout-configureable.patch +# Improve performance under load (#1824869) +Patch290: 0001-clutter-avoid-redundant-_clutter_paint_node_init_typ.patch +Patch291: 0002-clutter-avoid-g_signal_emit_by_name-from-ClutterActo.patch +Patch292: 0003-clutter-fix-hole-in-ClutterPaintNode.patch + +# https://bugzilla.redhat.com/show_bug.cgi?id=1625306 +Patch295: fix-extended-osk-characters.patch + +# Only treat WM_PROTOCOLS messages as WM_PROTOCOL messages (#1846242) +Patch296: 0001-stage-x11-Check-that-message-is-WM_PROTOCOLS-before-.patch + BuildRequires: chrpath BuildRequires: pango-devel BuildRequires: startup-notification-devel @@ -270,6 +281,22 @@ glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || : %{_libdir}/pkgconfig/* %changelog +* Mon Jun 22 2020 Jonas Ådahl ) - 3.28.3-26 +- Only treat WM_PROTOCOLS messages as WM_PROTOCOL messages + Resolves: #1846242 + +* Wed Jun 17 2020 Florian Müllner - 3.28.3-25 +- Notify workspace layout changes + Resolves: #1848103 + +* Tue May 26 2020 Florian Müllner - 3.28.3-24 +- Fix extended OSK keys + Resolves: #1625306 + +* Fri Apr 17 2020 Florian Müllner - 3.28.3-23 +- Improve performance under IO load + Resolves: #1824869 + * Fri Mar 06 2020 Florian Müllner - 3.28.3-22 - Include one more close-dialog backport Related: #1753799