From f0c503b5a9700c47d3be4fc36612ea7f333f5512 Mon Sep 17 00:00:00 2001 From: Robert Bragg Date: Tue, 23 Apr 2013 21:01:07 +0100 Subject: [PATCH 001/889] hack autogen to allow automake 1.13 --- autogen.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/autogen.sh b/autogen.sh index 714bc1645..61a279690 100755 --- a/autogen.sh +++ b/autogen.sh @@ -5,7 +5,7 @@ srcdir=`dirname $0` test -z "$srcdir" && srcdir=. PKG_NAME="mutter" -REQUIRED_AUTOMAKE_VERSION=1.10 +REQUIRED_AUTOMAKE_VERSION=1.13 (test -f $srcdir/configure.ac \ && test -d $srcdir/src) || { From 531be6c413ef7113b1c50d6b6dcf661af26fcdf7 Mon Sep 17 00:00:00 2001 From: Robert Bragg Date: Thu, 19 Jan 2012 01:20:02 +0000 Subject: [PATCH 002/889] Track the X Shape input region and use it for picking We now track whether a window has an input shape specified via the X Shape extension. Intersecting that with the bounding shape (as required by the X Shape extension) we use the resulting rectangles to paint window silhouettes when picking. As well as improving the correctness of picking this should also be much more efficient because typically when only picking solid rectangles then the need to actually render and issue a read_pixels request can be optimized away and instead the picking is done on the cpu. --- src/compositor/meta-shaped-texture.c | 92 +++++++++++---- src/compositor/meta-window-actor.c | 167 ++++++++++++++++++++------- src/core/display.c | 27 +++++ src/core/window-private.h | 4 +- src/core/window.c | 26 +++++ src/meta/meta-shaped-texture.h | 2 + 6 files changed, 257 insertions(+), 61 deletions(-) diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c index c6239c9d2..c93bb473b 100644 --- a/src/compositor/meta-shaped-texture.c +++ b/src/compositor/meta-shaped-texture.c @@ -72,6 +72,7 @@ struct _MetaShapedTexturePrivate CoglPipeline *pipeline_unshaped; cairo_region_t *clip_region; + cairo_region_t *input_shape_region; guint tex_width, tex_height; @@ -285,38 +286,52 @@ meta_shaped_texture_pick (ClutterActor *actor, MetaShapedTexture *stex = (MetaShapedTexture *) actor; MetaShapedTexturePrivate *priv = stex->priv; + if (!clutter_actor_should_pick_paint (actor) || + (priv->clip_region && cairo_region_is_empty (priv->clip_region))) + return; + /* If there is no region then use the regular pick */ - if (priv->mask_texture == NULL) + if (priv->input_shape_region == NULL) CLUTTER_ACTOR_CLASS (meta_shaped_texture_parent_class) ->pick (actor, color); - else if (clutter_actor_should_pick_paint (actor)) + else { - CoglTexture *paint_tex; - ClutterActorBox alloc; - guint tex_width, tex_height; + int n_rects; + float *rectangles; + int i; - paint_tex = COGL_TEXTURE (priv->texture); + /* Note: We don't bother trying to intersect the pick and clip regions + * since needing to copy the region, do the intersection, and probably + * increase the number of rectangles seems more likely to have a negative + * effect. + * + * NB: Most of the time when just using rectangles for picking then + * picking shouldn't involve any rendering, and minimizing the number of + * rectangles has more benefit than reducing the area of the pick + * region. + */ - if (paint_tex == NULL) - return; + n_rects = cairo_region_num_rectangles (priv->input_shape_region); - tex_width = cogl_texture_get_width (paint_tex); - tex_height = cogl_texture_get_height (paint_tex); + for (i = 0; i < n_rects; i++) + { + cairo_rectangle_int_t rect; + int pos = i * 4; - if (tex_width == 0 || tex_height == 0) /* no contents yet */ - return; + cairo_region_get_rectangle (priv->input_shape_region, i, &rect); - cogl_set_source_color4ub (color->red, color->green, color->blue, - color->alpha); + rectangles[pos] = rect.x; + rectangles[pos + 1] = rect.y; + rectangles[pos + 2] = rect.x + rect.width; + rectangles[pos + 3] = rect.y + rect.height; + } - clutter_actor_get_allocation_box (actor, &alloc); + cogl_set_source_color4ub (color->red, + color->green, + color->blue, + color->alpha); - /* Paint the mask rectangle in the given color */ - cogl_set_source_texture (priv->mask_texture); - cogl_rectangle_with_texture_coords (0, 0, - alloc.x2 - alloc.x1, - alloc.y2 - alloc.y1, - 0, 0, 1, 1); + cogl_rectangles (rectangles, n_rects); } } @@ -533,6 +548,41 @@ meta_shaped_texture_get_texture (MetaShapedTexture *stex) return COGL_TEXTURE (stex->priv->texture); } +/** + * meta_shaped_texture_set_input_shape_region: + * @stex: a #MetaShapedTexture + * @shape_region: the region of the texture that should respond to + * input. + * + * Determines what region of the texture should accept input. For + * X based windows this is defined by the ShapeInput region of the + * window. + */ +void +meta_shaped_texture_set_input_shape_region (MetaShapedTexture *stex, + cairo_region_t *shape_region) +{ + MetaShapedTexturePrivate *priv; + + g_return_if_fail (META_IS_SHAPED_TEXTURE (stex)); + + priv = stex->priv; + + if (priv->input_shape_region != NULL) + { + cairo_region_destroy (priv->input_shape_region); + priv->input_shape_region = NULL; + } + + if (shape_region != NULL) + { + cairo_region_reference (shape_region); + priv->input_shape_region = shape_region; + } + + clutter_actor_queue_redraw (CLUTTER_ACTOR (stex)); +} + /** * meta_shaped_texture_set_clip_region: * @stex: a #MetaShapedTexture diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 8251432fb..34a8fa1b9 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -72,6 +72,8 @@ struct _MetaWindowActorPrivate /* A region that matches the shape of the window, including frame bounds */ cairo_region_t *shape_region; + /* If the window has an input shape, a region that matches the shape */ + cairo_region_t *input_shape_region; /* The opaque region, from _NET_WM_OPAQUE_REGION, intersected with * the shape region. */ cairo_region_t *opaque_region; @@ -413,6 +415,7 @@ meta_window_actor_dispose (GObject *object) meta_window_actor_detach (self); g_clear_pointer (&priv->shape_region, cairo_region_destroy); + g_clear_pointer (&priv->input_shape_region, cairo_region_destroy); g_clear_pointer (&priv->opaque_region, cairo_region_destroy); g_clear_pointer (&priv->shadow_clip, cairo_region_destroy); @@ -2082,39 +2085,40 @@ build_and_scan_frame_mask (MetaWindowActor *self, g_free (mask_data); } +static cairo_region_t * +region_create_from_x_rectangles (const XRectangle *rects, + int n_rects, + int dx, + int dy) +{ + int i; + cairo_rectangle_int_t *cairo_rects = g_newa (cairo_rectangle_int_t, n_rects); + + for (i = 0; i < n_rects; i ++) + { + cairo_rects[i].x = rects[i].x + dx; + cairo_rects[i].y = rects[i].y + dy; + cairo_rects[i].width = rects[i].width; + cairo_rects[i].height = rects[i].height; + } + + return cairo_region_create_rectangles (cairo_rects, n_rects); +} + static void -check_needs_reshape (MetaWindowActor *self) +meta_window_actor_update_shape_region (MetaWindowActor *self, + cairo_rectangle_int_t *client_area) { MetaWindowActorPrivate *priv = self->priv; - MetaScreen *screen = priv->screen; - MetaDisplay *display = meta_screen_get_display (screen); - MetaFrameBorders borders; cairo_region_t *region = NULL; - cairo_rectangle_int_t client_area; gboolean needs_mask; - if (!priv->mapped) - return; - - if (!priv->needs_reshape) - return; - if (priv->shadow_shape != NULL) { meta_window_shape_unref (priv->shadow_shape); priv->shadow_shape = NULL; } - meta_frame_calc_borders (priv->window->frame, &borders); - - client_area.x = borders.total.left; - client_area.y = borders.total.top; - client_area.width = priv->window->rect.width; - if (priv->window->shaded) - client_area.height = 0; - else - client_area.height = priv->window->rect.height; - meta_shaped_texture_set_mask_texture (META_SHAPED_TEXTURE (priv->actor), NULL); g_clear_pointer (&priv->shape_region, cairo_region_destroy); g_clear_pointer (&priv->opaque_region, cairo_region_destroy); @@ -2124,6 +2128,8 @@ check_needs_reshape (MetaWindowActor *self) { /* Translate the set of XShape rectangles that we * get from the X server to a cairo_region. */ + MetaScreen *screen = priv->screen; + MetaDisplay *display = meta_screen_get_display (screen); Display *xdisplay = meta_display_get_xdisplay (display); XRectangle *rects; int n_rects, ordering; @@ -2138,20 +2144,10 @@ check_needs_reshape (MetaWindowActor *self) if (rects) { - int i; - cairo_rectangle_int_t *cairo_rects = g_new (cairo_rectangle_int_t, n_rects); - - for (i = 0; i < n_rects; i ++) - { - cairo_rects[i].x = rects[i].x + client_area.x; - cairo_rects[i].y = rects[i].y + client_area.y; - cairo_rects[i].width = rects[i].width; - cairo_rects[i].height = rects[i].height; - } - + region = region_create_from_x_rectangles (rects, n_rects, + client_area->x, + client_area->y); XFree (rects); - region = cairo_region_create_rectangles (cairo_rects, n_rects); - g_free (cairo_rects); } } #endif @@ -2167,14 +2163,14 @@ check_needs_reshape (MetaWindowActor *self) * window would have gotten if it was unshaped. In our case, * this is simply the client area. */ - cairo_region_intersect_rectangle (region, &client_area); + cairo_region_intersect_rectangle (region, client_area); } else { /* If we don't have a shape on the server, that means that * we have an implicit shape of one rectangle covering the * entire window. */ - region = cairo_region_create_rectangle (&client_area); + region = cairo_region_create_rectangle (client_area); } /* The region at this point should be constrained to the @@ -2193,7 +2189,7 @@ check_needs_reshape (MetaWindowActor *self) * case, graphical glitches will occur. */ priv->opaque_region = cairo_region_copy (priv->window->opaque_region); - cairo_region_translate (priv->opaque_region, client_area.x, client_area.y); + cairo_region_translate (priv->opaque_region, client_area->x, client_area->y); cairo_region_intersect (priv->opaque_region, region); } else if (priv->argb32) @@ -2207,15 +2203,108 @@ check_needs_reshape (MetaWindowActor *self) * and scans the mask looking for all opaque pixels, * adding it to region. */ - build_and_scan_frame_mask (self, &client_area, region); + build_and_scan_frame_mask (self, client_area, region); } priv->shape_region = region; - priv->needs_reshape = FALSE; meta_window_actor_invalidate_shadow (self); } +static void +meta_window_actor_update_input_shape_region (MetaWindowActor *self, + cairo_rectangle_int_t *client_area) +{ + MetaWindowActorPrivate *priv = self->priv; + cairo_region_t *region = NULL; + + g_clear_pointer (&priv->input_shape_region, cairo_region_destroy); + +#ifdef HAVE_SHAPE + /* Note: we currently assume that mutter never sets an input region + * when there is a frame. */ + if (priv->window->frame == NULL && priv->window->has_input_shape) + { + MetaScreen *screen = priv->screen; + MetaDisplay *display = meta_screen_get_display (screen); + Display *xdisplay = meta_display_get_xdisplay (display); + XRectangle *rects; + int n_rects, ordering; + + /* Note we only actually query the ShapeInput shape of a window + * when we don't have a frame because we assume currently that + * mutter never sets an ShapeInput shape on a frame. */ + meta_error_trap_push (display); + rects = XShapeGetRectangles (xdisplay, + priv->window->xwindow, + ShapeInput, + &n_rects, + &ordering); + meta_error_trap_pop (display); + if (rects) + { + region = region_create_from_x_rectangles (rects, n_rects, + client_area->x, + client_area->y); + XFree (rects); + } + } +#endif /* HAVE_SHAPE */ + + if (region != NULL) + { + /* The X shape extension requires us to intersect the input + * region with the effective bounding shape to determine the + * effective input region. + */ + if (priv->shape_region) + cairo_region_intersect (region, priv->shape_region); + else + cairo_region_intersect_rectangle (region, client_area); + } + else + { + /* If we don't have a shape on the server, that means that we + * have an implicit shape of one rectangle covering the entire + * window. */ + region = cairo_region_create_rectangle (client_area); + } + + priv->input_shape_region = region; + + meta_shaped_texture_set_input_shape_region (META_SHAPED_TEXTURE (priv->actor), + priv->input_shape_region); +} + +static void +check_needs_reshape (MetaWindowActor *self) +{ + MetaWindowActorPrivate *priv = self->priv; + MetaFrameBorders borders; + cairo_rectangle_int_t client_area; + + if (!priv->mapped) + return; + + if (!priv->needs_reshape) + return; + + meta_frame_calc_borders (priv->window->frame, &borders); + + client_area.x = borders.total.left; + client_area.y = borders.total.top; + client_area.width = priv->window->rect.width; + if (priv->window->shaded) + client_area.height = 0; + else + client_area.height = priv->window->rect.height; + + meta_window_actor_update_shape_region (self, &client_area); + meta_window_actor_update_input_shape_region (self, &client_area); + + priv->needs_reshape = FALSE; +} + void meta_window_actor_update_shape (MetaWindowActor *self) { diff --git a/src/core/display.c b/src/core/display.c index 9d5a87cb0..9bcb5e5c7 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -2283,6 +2283,33 @@ event_callback (XEvent *event, window->desc); } + if (display->compositor) + meta_compositor_window_shape_changed (display->compositor, + window); + } + else if (sev->kind == ShapeInput) + { + if (sev->shaped && !window->has_input_shape) + { + window->has_input_shape = TRUE; + meta_topic (META_DEBUG_SHAPES, + "Window %s now has an input shape\n", + window->desc); + } + else if (!sev->shaped && window->has_input_shape) + { + window->has_input_shape = FALSE; + meta_topic (META_DEBUG_SHAPES, + "Window %s no longer has an input shape\n", + window->desc); + } + else + { + meta_topic (META_DEBUG_SHAPES, + "Window %s input shape changed\n", + window->desc); + } + if (display->compositor) meta_compositor_window_shape_changed (display->compositor, window); diff --git a/src/core/window-private.h b/src/core/window-private.h index ec94cca07..42d380f7e 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -325,8 +325,10 @@ struct _MetaWindow guint using_net_wm_icon_name : 1; /* vs. plain wm_icon_name */ guint using_net_wm_visible_icon_name : 1; /* tracked so we can clear it */ - /* has a shape mask */ + /* has a bounding shape mask */ guint has_shape : 1; + /* has an input shape mask */ + guint has_input_shape : 1; /* icon props have changed */ guint need_reread_icon : 1; diff --git a/src/core/window.c b/src/core/window.c index 9252ab22d..faa9c773d 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -826,6 +826,7 @@ meta_window_new_with_attrs (MetaDisplay *display, gulong event_mask; MetaMoveResizeFlags flags; gboolean has_shape; + gboolean has_input_shape; MetaScreen *screen; g_assert (attrs != NULL); @@ -960,12 +961,15 @@ meta_window_new_with_attrs (MetaDisplay *display, } has_shape = FALSE; + has_input_shape = FALSE; #ifdef HAVE_SHAPE if (META_DISPLAY_HAS_SHAPE (display)) { int x_bounding, y_bounding, x_clip, y_clip; unsigned w_bounding, h_bounding, w_clip, h_clip; int bounding_shaped, clip_shaped; + XRectangle *input_rectangles; + int n_rects, ordering; XShapeSelectInput (display->xdisplay, xwindow, ShapeNotifyMask); @@ -977,6 +981,27 @@ meta_window_new_with_attrs (MetaDisplay *display, has_shape = bounding_shaped != FALSE; + /* XXX: The x shape extension doesn't provide a way to only test if an + * input shape has been specified, so we have to query and throw away the + * rectangles. */ + meta_error_trap_push (display); + input_rectangles = XShapeGetRectangles (display->xdisplay, xwindow, + ShapeInput, &n_rects, &ordering); + meta_error_trap_pop (display); + if (input_rectangles) + { + if (n_rects > 1 || + (n_rects == 1 && + (input_rectangles[0].x != x_bounding || + input_rectangles[1].y != y_bounding || + input_rectangles[2].width != w_bounding || + input_rectangles[3].height != h_bounding))) + { + has_input_shape = TRUE; + } + XFree (input_rectangles); + } + meta_topic (META_DEBUG_SHAPES, "Window has_shape = %d extents %d,%d %u x %u\n", has_shape, x_bounding, y_bounding, @@ -1042,6 +1067,7 @@ meta_window_new_with_attrs (MetaDisplay *display, meta_stack_freeze (window->screen->stack); window->has_shape = has_shape; + window->has_input_shape = has_input_shape; window->rect.x = attrs->x; window->rect.y = attrs->y; diff --git a/src/meta/meta-shaped-texture.h b/src/meta/meta-shaped-texture.h index 28fb5f603..2e122843b 100644 --- a/src/meta/meta-shaped-texture.h +++ b/src/meta/meta-shaped-texture.h @@ -82,6 +82,8 @@ CoglTexture * meta_shaped_texture_get_texture (MetaShapedTexture *stex); void meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex, CoglTexture *mask_texture); +void meta_shaped_texture_set_input_shape_region (MetaShapedTexture *stex, + cairo_region_t *shape_region); /* Assumes ownership of clip_region */ void meta_shaped_texture_set_clip_region (MetaShapedTexture *stex, From 6585a5760bf894947b2a6ee5f105148b4713bb2c Mon Sep 17 00:00:00 2001 From: Robert Bragg Date: Thu, 5 Jan 2012 12:19:58 +0000 Subject: [PATCH 003/889] configure: Adds --enable-wayland config option This adds a --enable-wayland configure option to enable building mutter as a hybrid X and Wayland compositor. By default the option is disabled. If enabled then HAVE_WAYLAND is defined for C code and as an automake conditional. This copies the xserver.xml wayland protocol into a protocol/ directory since wayland support will depend on this protocol for communicating with an xwayland X server. Copying the spec like this is consistent with Weston so we don't need a configure option to locate an external spec. --- Makefile.am | 2 +- configure.ac | 46 ++++++++++++++++++++++++++++++++++++++++++++ protocol/xserver.xml | 18 +++++++++++++++++ src/Makefile.am | 9 +++++++++ 4 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 protocol/xserver.xml diff --git a/Makefile.am b/Makefile.am index 56c7c888f..979ba2573 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,5 +1,5 @@ -SUBDIRS=src po doc +SUBDIRS=src protocol po doc EXTRA_DIST = HACKING MAINTAINERS rationales.txt diff --git a/configure.ac b/configure.ac index dbb3acae2..0cfe8def9 100644 --- a/configure.ac +++ b/configure.ac @@ -113,6 +113,21 @@ AC_ARG_ENABLE(shape, [disable mutter's use of the shaped window extension]),, enable_shape=auto) +AC_ARG_ENABLE(wayland, + AC_HELP_STRING([--enable-wayland], + [Enable support for running as a hybrid X and Wayland compositor]),, + enable_wayland=no) + +## Wayland support requires the xserver.xml protocol extension found in the weston +## repository but since there aren't currently established conventions for +## installing and discovering these we simply require a location to be given +## explicitly... +AC_ARG_WITH([wayland-protocols], + [AS_HELP_STRING([--with-wayland-protocols], [Location for wayland extension protocol specs])], + [ + ], + []) + AM_GLIB_GNU_GETTEXT ## here we get the flags we'll actually use @@ -199,6 +214,34 @@ if test x$have_xcursor = xyes; then AC_DEFINE(HAVE_XCURSOR, , [Building with Xcursor support]) fi +have_wayland=no +if test x$enable_wayland = "xyes"; then + WAYLAND_VERSION=0.1 + AC_MSG_CHECKING([Wayland >= $WAYLAND_VERSION]) + if ! $PKG_CONFIG --atleast-version $WAYLAND_VERSION wayland-server; then + AC_MSG_ERROR([wayland support enabled but no suitable wayland-server package found]) + fi + AC_MSG_RESULT(yes) + + CLUTTER_WAYLAND_VERSION=1.9.3 + AC_MSG_CHECKING([Clutter Wayland Compositor >= $CLUTTER_WAYLAND_VERSION]) + if ! $PKG_CONFIG --atleast-version $CLUTTER_WAYLAND_VERSION clutter-wayland-compositor-1.0; then + AC_MSG_ERROR([wayland support enabled but no suitable clutter-wayland-compositor package found]) + fi + AC_MSG_RESULT(yes) + + AC_PATH_PROG([WAYLAND_SCANNER],[wayland-scanner],[no]) + AS_IF([test "x$WAYLAND_SCANNER" = "xno"], + AC_MSG_ERROR([Could not find wayland-scanner in your PATH, required for parsing wayland extension protocols])) + AC_SUBST([WAYLAND_SCANNER]) + + MUTTER_PC_MODULES="$MUTTER_PC_MODULES wayland-server clutter-wayland-compositor-1.0" + AC_DEFINE(HAVE_WAYLAND, , [Building with Wayland support]) + have_wayland=yes +fi + +AM_CONDITIONAL(HAVE_WAYLAND, test x$have_wayland = "xyes") + PKG_CHECK_MODULES(MUTTER, $MUTTER_PC_MODULES) PKG_CHECK_EXISTS([xi >= 1.6.99.1], @@ -444,6 +487,7 @@ src/libmutter.pc src/mutter-plugins.pc src/tools/Makefile src/compositor/plugins/Makefile +protocol/Makefile po/Makefile.in ]) @@ -465,6 +509,8 @@ mutter-$VERSION source code location: ${srcdir} compiler: ${CC} + Wayland: ${have_wayland} + Startup notification: ${have_startup_notification} libcanberra: ${have_libcanberra} Introspection: ${found_introspection} diff --git a/protocol/xserver.xml b/protocol/xserver.xml new file mode 100644 index 000000000..9e25f5c0d --- /dev/null +++ b/protocol/xserver.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/Makefile.am b/src/Makefile.am index e2cec915e..7a1192676 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -342,3 +342,12 @@ mutter-enum-types.c: stamp-mutter-enum-types.h mutter-enum-types.c.in $(libmutterinclude_base_headers) ) >> xgen-tetc && \ cp xgen-tetc mutter-enum-types.c && \ rm -f xgen-tetc + +if HAVE_WAYLAND +wayland/%-protocol.c : $(top_builddir)/protocol/%.xml + $(AM_V_GEN)$(WAYLAND_SCANNER) code < $< > $@ +wayland/%-server-protocol.h : $(top_builddir)/protocol/%.xml + $(AM_V_GEN)$(WAYLAND_SCANNER) server-header < $< > $@ +wayland/%-client-protocol.h : $(top_builddir)/protocol/%.xml + $(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@ +endif From b4d108dac6171bfa526b9d65daf9a16a739c77ca Mon Sep 17 00:00:00 2001 From: Robert Bragg Date: Tue, 10 Jan 2012 18:28:15 +0000 Subject: [PATCH 004/889] configure: Adds --with-xwayland-path option This adds a --with-xwayland-path configure option that can be used to specify the absolute path of a headless X server binary supporting the wayland xserver protocol. --- configure.ac | 7 +++++++ src/Makefile.am | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/configure.ac b/configure.ac index 0cfe8def9..deecd1faa 100644 --- a/configure.ac +++ b/configure.ac @@ -128,6 +128,11 @@ AC_ARG_WITH([wayland-protocols], ], []) +AC_ARG_WITH([xwayland-path], + [AS_HELP_STRING([--with-xwayland-path], [Absolute path for an X Wayland server])], + [XWAYLAND_PATH="$withval"], + [XWAYLAND_PATH="$bindir/Xorg"]) + AM_GLIB_GNU_GETTEXT ## here we get the flags we'll actually use @@ -235,6 +240,8 @@ if test x$enable_wayland = "xyes"; then AC_MSG_ERROR([Could not find wayland-scanner in your PATH, required for parsing wayland extension protocols])) AC_SUBST([WAYLAND_SCANNER]) + AC_SUBST(XWAYLAND_PATH) + MUTTER_PC_MODULES="$MUTTER_PC_MODULES wayland-server clutter-wayland-compositor-1.0" AC_DEFINE(HAVE_WAYLAND, , [Building with Wayland support]) have_wayland=yes diff --git a/src/Makefile.am b/src/Makefile.am index 7a1192676..c0884c58a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -29,6 +29,12 @@ INCLUDES= \ -DMUTTER_PLUGIN_DIR=\"@MUTTER_PLUGIN_DIR@\" \ -DGETTEXT_PACKAGE=\"$(GETTEXT_PACKAGE)\" +if HAVE_WAYLAND +INCLUDES += \ + -I$(srcdir)/wayland \ + -DXWAYLAND_PATH='"@XWAYLAND_PATH@"' +endif + mutter_built_sources = \ mutter-enum-types.h \ mutter-enum-types.c From bd3c35721294a040b166b94395201c65f359b5e4 Mon Sep 17 00:00:00 2001 From: Robert Bragg Date: Fri, 3 May 2013 00:57:28 +0100 Subject: [PATCH 005/889] Adds a --nested option This adds a --nested option to request that mutter no longer run as a classic X compositor with an output window mapped on the X Composite Overlay Window and also not assume it is running directly under X. The intention is that in this mode Mutter will itself launch a headless X server and display output will be handled by Clutter and Cogl. This will enable running Mutter nested as an application within an X session. This patch introduces an internal meta_is_wayland_compositor() function as a means to condition the way mutter operates when running as a traditional X compositor vs running as a wayland compositor where the compositor and display server are combined into a single process. Later we also expect to add a --kms option as another way of enabling this wayland compositor mode that will assume full control of the display hardware instead of running as a nested application. --- src/core/mutter.c | 9 +++++++++ src/core/util.c | 13 +++++++++++++ src/meta/util.h | 2 ++ 3 files changed, 24 insertions(+) diff --git a/src/core/mutter.c b/src/core/mutter.c index 3216726cf..439fccad3 100644 --- a/src/core/mutter.c +++ b/src/core/mutter.c @@ -46,8 +46,15 @@ print_version (const gchar *option_name, } static gchar *plugin = "default"; +static gboolean opt_nested = FALSE; GOptionEntry mutter_options[] = { + { + "nested", 0, 0, G_OPTION_ARG_NONE, + &opt_nested, + N_("Run nested as an application for testing"), + NULL, + }, { "version", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, print_version, @@ -77,6 +84,8 @@ main (int argc, char **argv) exit (1); } + meta_set_is_wayland_compositor (opt_nested); + if (plugin) meta_plugin_manager_load (plugin); diff --git a/src/core/util.c b/src/core/util.c index 92a33e453..c14fad736 100644 --- a/src/core/util.c +++ b/src/core/util.c @@ -55,6 +55,7 @@ static gint verbose_topics = 0; static gboolean is_debugging = FALSE; static gboolean replace_current = FALSE; static int no_prefix = 0; +static gboolean is_wayland_compositor = FALSE; #ifdef WITH_VERBOSE_MODE static FILE* logfile = NULL; @@ -194,6 +195,18 @@ meta_set_replace_current_wm (gboolean setting) replace_current = setting; } +gboolean +meta_is_wayland_compositor (void) +{ + return is_wayland_compositor; +} + +void +meta_set_is_wayland_compositor (gboolean value) +{ + is_wayland_compositor = value; +} + char * meta_g_utf8_strndup (const gchar *src, gsize n) diff --git a/src/meta/util.h b/src/meta/util.h index be87190b0..91f968ba0 100644 --- a/src/meta/util.h +++ b/src/meta/util.h @@ -37,6 +37,8 @@ void meta_set_debugging (gboolean setting); gboolean meta_is_syncing (void); void meta_set_syncing (gboolean setting); void meta_set_replace_current_wm (gboolean setting); +gboolean meta_is_wayland_compositor (void); +void meta_set_is_wayland_compositor (gboolean setting); void meta_debug_spew_real (const char *format, ...) G_GNUC_PRINTF (1, 2); From f9a11b3b18eb0637e9da20caa612b5671a04d3f8 Mon Sep 17 00:00:00 2001 From: Robert Bragg Date: Sat, 7 Jan 2012 22:21:32 +0000 Subject: [PATCH 006/889] wayland: Adds basic hybrid X + Wayland support This adds support for running mutter as a hybrid X and Wayland compositor. It runs a headless XWayland server for X applications that presents wayland surfaces back to mutter which mutter can then composite. This aims to not break Mutter's existing support for the traditional X compositing model which means a single build of Mutter can be distributed supporting the traditional model and the new Wayland based compositing model. TODO: although building with --disable-wayland has at least been tested, I still haven't actually verified that running as a traditional compositor isn't broken currently. Note: At this point no input is supported Note: multiple authors have contributed to this patch: Authored-by: Robert Bragg Authored-by: Neil Roberts Authored-by: Rico Tzschichholz. Authored-by: Giovanni Campagna --- configure.ac | 2 +- src/Makefile.am | 15 + src/compositor/compositor.c | 349 +++--- src/compositor/meta-plugin-manager.c | 14 +- src/compositor/meta-shaped-texture.c | 381 +++++-- src/compositor/meta-window-actor-private.h | 21 +- src/compositor/meta-window-actor.c | 482 +++++--- src/compositor/meta-window-group.c | 32 +- src/core/display.c | 28 +- src/core/main.c | 116 +- src/core/screen-private.h | 2 + src/core/screen.c | 31 +- src/core/window-private.h | 24 + src/core/window.c | 656 ++++++----- src/meta/compositor.h | 4 +- src/meta/meta-shaped-texture.h | 17 +- src/wayland/meta-wayland-private.h | 171 +++ src/wayland/meta-wayland.c | 1145 ++++++++++++++++++++ src/wayland/meta-xwayland-private.h | 33 + src/wayland/meta-xwayland.c | 310 ++++++ 20 files changed, 3156 insertions(+), 677 deletions(-) create mode 100644 src/wayland/meta-wayland-private.h create mode 100644 src/wayland/meta-wayland.c create mode 100644 src/wayland/meta-xwayland-private.h create mode 100644 src/wayland/meta-xwayland.c diff --git a/configure.ac b/configure.ac index deecd1faa..7c20ac5a3 100644 --- a/configure.ac +++ b/configure.ac @@ -15,7 +15,7 @@ AC_INIT([mutter], [mutter_version], AC_CONFIG_SRCDIR(src/core/display.c) AC_CONFIG_HEADERS(config.h) -AM_INIT_AUTOMAKE([1.11 no-dist-gzip dist-xz tar-ustar]) +AM_INIT_AUTOMAKE([1.11 foreign no-dist-gzip dist-xz tar-ustar]) m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])],) AM_MAINTAINER_MODE([enable]) diff --git a/src/Makefile.am b/src/Makefile.am index c0884c58a..e25d4a8ee 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -39,6 +39,13 @@ mutter_built_sources = \ mutter-enum-types.h \ mutter-enum-types.c +if HAVE_WAYLAND +mutter_built_sources += \ + wayland/xserver-protocol.c \ + wayland/xserver-server-protocol.h \ + wayland/xserver-client-protocol.h +endif + libmutter_la_SOURCES = \ core/async-getprop.c \ core/async-getprop.h \ @@ -167,6 +174,14 @@ libmutter_la_SOURCES = \ ui/preview-widget.c \ $(mutter_built_sources) +if HAVE_WAYLAND +libmutter_la_SOURCES += \ + wayland/meta-wayland.c \ + wayland/meta-wayland-private.h \ + wayland/meta-xwayland-private.h \ + wayland/meta-xwayland.c +endif + libmutter_la_LDFLAGS = -no-undefined libmutter_la_LIBADD = $(MUTTER_LIBS) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 89235e641..2d4817f68 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -84,6 +84,9 @@ #include "meta-window-group.h" #include "window-private.h" /* to check window->hidden */ #include "display-private.h" /* for meta_display_lookup_x_window() */ +#ifdef HAVE_WAYLAND +#include "meta-wayland-private.h" +#endif #include #include @@ -172,7 +175,7 @@ process_damage (MetaCompositor *compositor, if (window_actor == NULL) return; - meta_window_actor_process_damage (window_actor, event); + meta_window_actor_process_x11_damage (window_actor, event); } static void @@ -327,29 +330,37 @@ void meta_set_stage_input_region (MetaScreen *screen, XserverRegion region) { - MetaCompScreen *info = meta_screen_get_compositor_data (screen); - MetaDisplay *display = meta_screen_get_display (screen); - Display *xdpy = meta_display_get_xdisplay (display); + /* As a wayland compositor we can simply ignore all this trickery + * for setting an input region on the stage for capturing events in + * clutter since all input comes to us first and we get to choose + * who else sees them. + */ + if (!meta_is_wayland_compositor ()) + { + MetaCompScreen *info = meta_screen_get_compositor_data (screen); + MetaDisplay *display = meta_screen_get_display (screen); + Display *xdpy = meta_display_get_xdisplay (display); - if (info->stage && info->output) - { - do_set_stage_input_region (screen, region); + if (info->stage && info->output) + { + do_set_stage_input_region (screen, region); + } + else + { + /* Reset info->pending_input_region if one existed before and set the new + * one to use it later. */ + if (info->pending_input_region) + { + XFixesDestroyRegion (xdpy, info->pending_input_region); + info->pending_input_region = None; + } + if (region != None) + { + info->pending_input_region = XFixesCreateRegion (xdpy, NULL, 0); + XFixesCopyRegion (xdpy, info->pending_input_region, region); + } + } } - else - { - /* Reset info->pending_input_region if one existed before and set the new - * one to use it later. */ - if (info->pending_input_region) - { - XFixesDestroyRegion (xdpy, info->pending_input_region); - info->pending_input_region = None; - } - if (region != None) - { - info->pending_input_region = XFixesCreateRegion (xdpy, NULL, 0); - XFixesCopyRegion (xdpy, info->pending_input_region, region); - } - } } void @@ -562,6 +573,11 @@ redirect_windows (MetaCompositor *compositor, guint n_retries; guint max_retries; + /* If we're running with wayland, connected to a headless xwayland + * server then all the windows are implicitly redirected offscreen + * already and it would generate an error to try and explicitly + * redirect them via XCompositeRedirectSubwindows() */ + if (meta_get_replace_current_wm ()) max_retries = 5; else @@ -604,6 +620,9 @@ meta_compositor_manage_screen (MetaCompositor *compositor, Display *xdisplay = meta_display_get_xdisplay (display); Window xwin; gint width, height; +#ifdef HAVE_WAYLAND + MetaWaylandCompositor *wayland_compositor; +#endif /* Check if the screen is already managed */ if (meta_screen_get_compositor_data (screen)) @@ -616,7 +635,14 @@ meta_compositor_manage_screen (MetaCompositor *compositor, * We have to initialize info->pending_input_region to an empty region explicitly, * because None value is used to mean that the whole screen is an input region. */ - info->pending_input_region = XFixesCreateRegion (xdisplay, NULL, 0); + if (!meta_is_wayland_compositor ()) + info->pending_input_region = XFixesCreateRegion (xdisplay, NULL, 0); + else + { + /* Stage input region trickery isn't needed when we're running as a + * wayland compositor. */ + info->pending_input_region = None; + } info->screen = screen; @@ -627,7 +653,55 @@ meta_compositor_manage_screen (MetaCompositor *compositor, meta_screen_set_cm_selection (screen); - info->stage = clutter_stage_new (); + /* We will have already created a stage if running as a wayland + * compositor... */ +#ifdef HAVE_WAYLAND + if (meta_is_wayland_compositor ()) + { + wayland_compositor = meta_wayland_compositor_get_default (); + info->stage = wayland_compositor->stage; + } + else +#endif /* HAVE_WAYLAND */ + { + info->stage = clutter_stage_new (); + + meta_screen_get_size (screen, &width, &height); + clutter_actor_realize (info->stage); + + xwin = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage)); + + XResizeWindow (xdisplay, xwin, width, height); + + { + long event_mask; + unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; + XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits }; + XWindowAttributes attr; + + meta_core_add_old_event_mask (xdisplay, xwin, &mask); + + XISetMask (mask.mask, XI_KeyPress); + XISetMask (mask.mask, XI_KeyRelease); + XISetMask (mask.mask, XI_ButtonPress); + XISetMask (mask.mask, XI_ButtonRelease); + XISetMask (mask.mask, XI_Enter); + XISetMask (mask.mask, XI_Leave); + XISetMask (mask.mask, XI_FocusIn); + XISetMask (mask.mask, XI_FocusOut); + XISetMask (mask.mask, XI_Motion); + XIClearMask (mask.mask, XI_TouchBegin); + XIClearMask (mask.mask, XI_TouchEnd); + XIClearMask (mask.mask, XI_TouchUpdate); + XISelectEvents (xdisplay, xwin, &mask, 1); + + event_mask = ExposureMask | PropertyChangeMask | StructureNotifyMask; + if (XGetWindowAttributes (xdisplay, xwin, &attr)) + event_mask |= attr.your_event_mask; + + XSelectInput (xdisplay, xwin, event_mask); + } + } clutter_stage_set_paint_callback (CLUTTER_STAGE (info->stage), after_stage_paint, @@ -636,42 +710,6 @@ meta_compositor_manage_screen (MetaCompositor *compositor, clutter_stage_set_sync_delay (CLUTTER_STAGE (info->stage), META_SYNC_DELAY); - meta_screen_get_size (screen, &width, &height); - clutter_actor_realize (info->stage); - - xwin = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage)); - - XResizeWindow (xdisplay, xwin, width, height); - - { - long event_mask; - unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; - XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits }; - XWindowAttributes attr; - - meta_core_add_old_event_mask (xdisplay, xwin, &mask); - - XISetMask (mask.mask, XI_KeyPress); - XISetMask (mask.mask, XI_KeyRelease); - XISetMask (mask.mask, XI_ButtonPress); - XISetMask (mask.mask, XI_ButtonRelease); - XISetMask (mask.mask, XI_Enter); - XISetMask (mask.mask, XI_Leave); - XISetMask (mask.mask, XI_FocusIn); - XISetMask (mask.mask, XI_FocusOut); - XISetMask (mask.mask, XI_Motion); - XIClearMask (mask.mask, XI_TouchBegin); - XIClearMask (mask.mask, XI_TouchEnd); - XIClearMask (mask.mask, XI_TouchUpdate); - XISelectEvents (xdisplay, xwin, &mask, 1); - - event_mask = ExposureMask | PropertyChangeMask | StructureNotifyMask; - if (XGetWindowAttributes (xdisplay, xwin, &attr)) - event_mask |= attr.your_event_mask; - - XSelectInput (xdisplay, xwin, event_mask); - } - info->window_group = meta_window_group_new (screen); info->top_window_group = meta_window_group_new (screen); @@ -680,53 +718,66 @@ meta_compositor_manage_screen (MetaCompositor *compositor, info->plugin_mgr = meta_plugin_manager_new (screen); - /* - * Delay the creation of the overlay window as long as we can, to avoid - * blanking out the screen. This means that during the plugin loading, the - * overlay window is not accessible; if the plugin needs to access it - * directly, it should hook into the "show" signal on stage, and do - * its stuff there. - */ - info->output = get_output_window (screen); - XReparentWindow (xdisplay, xwin, info->output, 0, 0); - - /* Make sure there isn't any left-over output shape on the - * overlay window by setting the whole screen to be an - * output region. - * - * Note: there doesn't seem to be any real chance of that - * because the X server will destroy the overlay window - * when the last client using it exits. - */ - XFixesSetWindowShapeRegion (xdisplay, info->output, ShapeBounding, 0, 0, None); - - do_set_stage_input_region (screen, info->pending_input_region); - if (info->pending_input_region != None) + if (meta_is_wayland_compositor ()) { - XFixesDestroyRegion (xdisplay, info->pending_input_region); - info->pending_input_region = None; + /* NB: When running as a wayland compositor we don't need an X + * composite overlay window, and we don't need to play any input + * region tricks to redirect events into clutter. */ + info->output = None; } + else + { + /* + * Delay the creation of the overlay window as long as we can, to avoid + * blanking out the screen. This means that during the plugin loading, the + * overlay window is not accessible; if the plugin needs to access it + * directly, it should hook into the "show" signal on stage, and do + * its stuff there. + */ + info->output = get_output_window (screen); + XReparentWindow (xdisplay, xwin, info->output, 0, 0); - /* Map overlay window before redirecting windows offscreen so we catch their - * contents until we show the stage. - */ - XMapWindow (xdisplay, info->output); + /* Make sure there isn't any left-over output shape on the + * overlay window by setting the whole screen to be an + * output region. + * + * Note: there doesn't seem to be any real chance of that + * because the X server will destroy the overlay window + * when the last client using it exits. + */ + XFixesSetWindowShapeRegion (xdisplay, info->output, ShapeBounding, 0, 0, None); - redirect_windows (compositor, screen); + do_set_stage_input_region (screen, info->pending_input_region); + if (info->pending_input_region != None) + { + XFixesDestroyRegion (xdisplay, info->pending_input_region); + info->pending_input_region = None; + } + + /* Map overlay window before redirecting windows offscreen so we catch their + * contents until we show the stage. + */ + XMapWindow (xdisplay, info->output); + + redirect_windows (compositor, screen); + } } void meta_compositor_unmanage_screen (MetaCompositor *compositor, MetaScreen *screen) { - MetaDisplay *display = meta_screen_get_display (screen); - Display *xdisplay = meta_display_get_xdisplay (display); - Window xroot = meta_screen_get_xroot (screen); + if (!meta_is_wayland_compositor ()) + { + MetaDisplay *display = meta_screen_get_display (screen); + Display *xdisplay = meta_display_get_xdisplay (display); + Window xroot = meta_screen_get_xroot (screen); - /* This is the most important part of cleanup - we have to do this - * before giving up the window manager selection or the next - * window manager won't be able to redirect subwindows */ - XCompositeUnredirectSubwindows (xdisplay, xroot, CompositeRedirectManual); + /* This is the most important part of cleanup - we have to do this + * before giving up the window manager selection or the next + * window manager won't be able to redirect subwindows */ + XCompositeUnredirectSubwindows (xdisplay, xroot, CompositeRedirectManual); + } } /* @@ -798,15 +849,18 @@ meta_compositor_remove_window (MetaCompositor *compositor, if (!window_actor) return; - screen = meta_window_get_screen (window); - info = meta_screen_get_compositor_data (screen); - - if (window_actor == info->unredirected_window) + if (!meta_is_wayland_compositor ()) { - meta_window_actor_set_redirected (window_actor, TRUE); - meta_shape_cow_for_window (meta_window_get_screen (meta_window_actor_get_meta_window (info->unredirected_window)), - NULL); - info->unredirected_window = NULL; + screen = meta_window_get_screen (window); + info = meta_screen_get_compositor_data (screen); + + if (window_actor == info->unredirected_window) + { + meta_window_actor_set_redirected (window_actor, TRUE); + meta_shape_cow_for_window (meta_window_get_screen (meta_window_actor_get_meta_window (info->unredirected_window)), + NULL); + info->unredirected_window = NULL; + } } meta_window_actor_destroy (window_actor); @@ -866,8 +920,8 @@ is_grabbed_event (MetaDisplay *display, } void -meta_compositor_window_shape_changed (MetaCompositor *compositor, - MetaWindow *window) +meta_compositor_window_x11_shape_changed (MetaCompositor *compositor, + MetaWindow *window) { MetaWindowActor *window_actor; window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); @@ -993,7 +1047,8 @@ meta_compositor_process_event (MetaCompositor *compositor, break; default: - if (event->type == meta_display_get_damage_event_base (compositor->display) + XDamageNotify) + if (!meta_is_wayland_compositor () && + event->type == meta_display_get_damage_event_base (compositor->display) + XDamageNotify) { /* Core code doesn't handle damage events, so we need to extract the MetaWindow * ourselves @@ -1012,7 +1067,7 @@ meta_compositor_process_event (MetaCompositor *compositor, /* Clutter needs to know about MapNotify events otherwise it will think the stage is invisible */ - if (event->type == MapNotify) + if (!meta_is_wayland_compositor () && event->type == MapNotify) clutter_x11_handle_event (event); /* The above handling is basically just "observing" the events, so we return @@ -1354,22 +1409,33 @@ meta_compositor_sync_screen_size (MetaCompositor *compositor, guint width, guint height) { - MetaDisplay *display = meta_screen_get_display (screen); - MetaCompScreen *info = meta_screen_get_compositor_data (screen); - Display *xdisplay; - Window xwin; + if (meta_is_wayland_compositor ()) + { + /* It's not clear at the moment how we will be dealing with screen + * resizing as a Wayland compositor so for now just abort if we + * hit this code. */ + g_critical ("Unexpected call to meta_compositor_sync_screen_size() " + "when running as a wayland compositor"); + } + else + { + MetaDisplay *display = meta_screen_get_display (screen); + MetaCompScreen *info = meta_screen_get_compositor_data (screen); + Display *xdisplay; + Window xwin; - DEBUG_TRACE ("meta_compositor_sync_screen_size\n"); - g_return_if_fail (info); + DEBUG_TRACE ("meta_compositor_sync_screen_size\n"); + g_return_if_fail (info); - xdisplay = meta_display_get_xdisplay (display); - xwin = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage)); + xdisplay = meta_display_get_xdisplay (display); + xwin = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage)); - XResizeWindow (xdisplay, xwin, width, height); + XResizeWindow (xdisplay, xwin, width, height); - meta_verbose ("Changed size for stage on screen %d to %dx%d\n", - meta_screen_get_screen_number (screen), - width, height); + meta_verbose ("Changed size for stage on screen %d to %dx%d\n", + meta_screen_get_screen_number (screen), + width, height); + } } static void @@ -1433,29 +1499,32 @@ pre_paint_windows (MetaCompScreen *info) if (info->windows == NULL) return; - top_window = g_list_last (info->windows)->data; - - if (meta_window_actor_should_unredirect (top_window) && - info->disable_unredirect_count == 0) - expected_unredirected_window = top_window; - - if (info->unredirected_window != expected_unredirected_window) + if (!meta_is_wayland_compositor ()) { - if (info->unredirected_window != NULL) - { - meta_window_actor_set_redirected (info->unredirected_window, TRUE); - meta_shape_cow_for_window (meta_window_get_screen (meta_window_actor_get_meta_window (info->unredirected_window)), - NULL); - } + top_window = g_list_last (info->windows)->data; - if (expected_unredirected_window != NULL) - { - meta_shape_cow_for_window (meta_window_get_screen (meta_window_actor_get_meta_window (top_window)), - meta_window_actor_get_meta_window (top_window)); - meta_window_actor_set_redirected (top_window, FALSE); - } + if (meta_window_actor_should_unredirect (top_window) && + info->disable_unredirect_count == 0) + expected_unredirected_window = top_window; - info->unredirected_window = expected_unredirected_window; + if (info->unredirected_window != expected_unredirected_window) + { + if (info->unredirected_window != NULL) + { + meta_window_actor_set_redirected (info->unredirected_window, TRUE); + meta_shape_cow_for_window (meta_window_get_screen (meta_window_actor_get_meta_window (info->unredirected_window)), + NULL); + } + + if (expected_unredirected_window != NULL) + { + meta_shape_cow_for_window (meta_window_get_screen (meta_window_actor_get_meta_window (top_window)), + meta_window_actor_get_meta_window (top_window)); + meta_window_actor_set_redirected (top_window, FALSE); + } + + info->unredirected_window = expected_unredirected_window; + } } for (l = info->windows; l; l = l->next) diff --git a/src/compositor/meta-plugin-manager.c b/src/compositor/meta-plugin-manager.c index 130a82bf7..2ae100e84 100644 --- a/src/compositor/meta-plugin-manager.c +++ b/src/compositor/meta-plugin-manager.c @@ -317,6 +317,16 @@ meta_plugin_manager_xevent_filter (MetaPluginManager *plugin_mgr, */ if (klass->xevent_filter) return klass->xevent_filter (plugin, xev); - else - return clutter_x11_handle_event (xev) != CLUTTER_X11_FILTER_CONTINUE; + + /* When mutter is running as a wayland compositor, things like input + * events just come directly from clutter so it won't have disabled + * clutter's event retrieval and won't need to forward it events (if + * it did it would lead to recursion). Also when running as a + * wayland compositor we shouldn't be assuming that we're running + * with the clutter x11 backend. + */ + if (meta_is_wayland_compositor ()) + return FALSE; + + return clutter_x11_handle_event (xev) != CLUTTER_X11_FILTER_CONTINUE; } diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c index c93bb473b..cc095751b 100644 --- a/src/compositor/meta-shaped-texture.c +++ b/src/compositor/meta-shaped-texture.c @@ -30,8 +30,14 @@ #include #include +#include #include "meta-texture-tower.h" +#ifdef HAVE_WAYLAND +#include "meta-wayland-private.h" +#include +#endif + #include #include #include @@ -55,6 +61,15 @@ static void meta_shaped_texture_get_preferred_height (ClutterActor *self, static gboolean meta_shaped_texture_get_paint_volume (ClutterActor *self, ClutterPaintVolume *volume); +typedef enum _MetaShapedTextureType +{ + META_SHAPED_TEXTURE_TYPE_X11_PIXMAP, +#ifdef HAVE_WAYLAND + META_SHAPED_TEXTURE_TYPE_WAYLAND_SURFACE, +#endif +} MetaShapedTextureType; + + G_DEFINE_TYPE (MetaShapedTexture, meta_shaped_texture, CLUTTER_TYPE_ACTOR); @@ -65,8 +80,21 @@ G_DEFINE_TYPE (MetaShapedTexture, meta_shaped_texture, struct _MetaShapedTexturePrivate { MetaTextureTower *paint_tower; - Pixmap pixmap; - CoglTexturePixmapX11 *texture; + + MetaShapedTextureType type; + union { + struct { + Pixmap pixmap; + } x11; +#ifdef HAVE_WAYLAND + struct { + MetaWaylandSurface *surface; + } wayland; +#endif + }; + + CoglTexture *texture; + CoglTexture *mask_texture; CoglPipeline *pipeline; CoglPipeline *pipeline_unshaped; @@ -104,7 +132,10 @@ meta_shaped_texture_init (MetaShapedTexture *self) priv = self->priv = META_SHAPED_TEXTURE_GET_PRIVATE (self); priv->paint_tower = meta_texture_tower_new (); + + priv->type = META_SHAPED_TEXTURE_TYPE_X11_PIXMAP; priv->texture = NULL; + priv->mask_texture = NULL; priv->create_mipmaps = TRUE; } @@ -129,6 +160,56 @@ meta_shaped_texture_dispose (GObject *object) G_OBJECT_CLASS (meta_shaped_texture_parent_class)->dispose (object); } +static void +set_cogl_texture (MetaShapedTexture *stex, + CoglTexture *cogl_tex) +{ + MetaShapedTexturePrivate *priv; + guint width, height; + + g_return_if_fail (META_IS_SHAPED_TEXTURE (stex)); + + priv = stex->priv; + + if (priv->texture) + cogl_object_unref (priv->texture); + + priv->texture = cogl_tex; + + if (priv->pipeline != NULL) + cogl_pipeline_set_layer_texture (priv->pipeline, 0, COGL_TEXTURE (cogl_tex)); + + if (priv->pipeline_unshaped != NULL) + cogl_pipeline_set_layer_texture (priv->pipeline_unshaped, 0, COGL_TEXTURE (cogl_tex)); + + if (cogl_tex != NULL) + { + width = cogl_texture_get_width (COGL_TEXTURE (cogl_tex)); + height = cogl_texture_get_height (COGL_TEXTURE (cogl_tex)); + + if (width != priv->tex_width || + height != priv->tex_height) + { + priv->tex_width = width; + priv->tex_height = height; + + clutter_actor_queue_relayout (CLUTTER_ACTOR (stex)); + } + } + else + { + /* size changed to 0 going to an invalid handle */ + priv->tex_width = 0; + priv->tex_height = 0; + clutter_actor_queue_relayout (CLUTTER_ACTOR (stex)); + } + + /* NB: We don't queue a redraw of the actor here because we don't + * know how much of the buffer has changed with respect to the + * previous buffer. We only queue a redraw in response to surface + * damage. */ +} + static void meta_shaped_texture_paint (ClutterActor *actor) { @@ -312,6 +393,7 @@ meta_shaped_texture_pick (ClutterActor *actor, */ n_rects = cairo_region_num_rectangles (priv->input_shape_region); + rectangles = g_alloca (sizeof (float) * 4 * n_rects); for (i = 0; i < n_rects; i++) { @@ -380,12 +462,56 @@ meta_shaped_texture_get_paint_volume (ClutterActor *self, return clutter_paint_volume_set_from_allocation (volume, self); } +#ifdef HAVE_WAYLAND ClutterActor * -meta_shaped_texture_new (void) +meta_shaped_texture_new_with_wayland_surface (MetaWaylandSurface *surface) { - ClutterActor *self = g_object_new (META_TYPE_SHAPED_TEXTURE, NULL); + ClutterActor *actor = g_object_new (META_TYPE_SHAPED_TEXTURE, NULL); + MetaShapedTexturePrivate *priv = META_SHAPED_TEXTURE (actor)->priv; - return self; + /* XXX: it could probably be better to have a "type" construct-only + * property or create wayland/x11 subclasses */ + priv->type = META_SHAPED_TEXTURE_TYPE_WAYLAND_SURFACE; + + meta_shaped_texture_set_wayland_surface (META_SHAPED_TEXTURE (actor), + surface); + + return actor; +} + +void +meta_shaped_texture_set_wayland_surface (MetaShapedTexture *stex, + MetaWaylandSurface *surface) +{ + MetaShapedTexturePrivate *priv = stex->priv; + + priv->wayland.surface = surface; + + if (surface && surface->buffer_ref.buffer) + meta_shaped_texture_attach_wayland_buffer (stex, + surface->buffer_ref.buffer); +} + +MetaWaylandSurface * +meta_shaped_texture_get_wayland_surface (MetaShapedTexture *stex) +{ + MetaShapedTexturePrivate *priv = stex->priv; + return priv->wayland.surface; +} +#endif /* HAVE_WAYLAND */ + +ClutterActor * +meta_shaped_texture_new_with_xwindow (Window xwindow) +{ +#ifdef HAVE_WAYLAND + if (meta_is_wayland_compositor ()) + { + MetaWaylandSurface *surface = meta_wayland_lookup_surface_for_xid (xwindow); + return meta_shaped_texture_new_with_wayland_surface (surface); + } + else +#endif + return g_object_new (META_TYPE_SHAPED_TEXTURE, NULL); } void @@ -404,8 +530,7 @@ meta_shaped_texture_set_create_mipmaps (MetaShapedTexture *stex, { CoglTexture *base_texture; priv->create_mipmaps = create_mipmaps; - base_texture = create_mipmaps ? - COGL_TEXTURE (priv->texture) : NULL; + base_texture = create_mipmaps ? priv->texture : NULL; meta_texture_tower_set_base_texture (priv->paint_tower, base_texture); } } @@ -431,74 +556,146 @@ meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex, clutter_actor_queue_redraw (CLUTTER_ACTOR (stex)); } -void -meta_shaped_texture_update_area (MetaShapedTexture *stex, - int x, - int y, - int width, - int height) +#ifdef HAVE_WAYLAND +static void +wayland_surface_update_area (MetaShapedTexture *stex, + int x, + int y, + int width, + int height) +{ + MetaShapedTexturePrivate *priv; + MetaWaylandBuffer *buffer; + + priv = stex->priv; + + g_return_if_fail (priv->type == META_SHAPED_TEXTURE_TYPE_WAYLAND_SURFACE); + g_return_if_fail (priv->texture != NULL); + + buffer = priv->wayland.surface->buffer_ref.buffer; + + if (buffer) + { + struct wl_resource *resource = buffer->resource; + struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get (resource); + + if (shm_buffer) + { + CoglPixelFormat format; + + switch (wl_shm_buffer_get_format (shm_buffer)) + { +#if G_BYTE_ORDER == G_BIG_ENDIAN + case WL_SHM_FORMAT_ARGB8888: + format = COGL_PIXEL_FORMAT_ARGB_8888_PRE; + break; + case WL_SHM_FORMAT_XRGB8888: + format = COGL_PIXEL_FORMAT_ARGB_8888; + break; +#elif G_BYTE_ORDER == G_LITTLE_ENDIAN + case WL_SHM_FORMAT_ARGB8888: + format = COGL_PIXEL_FORMAT_BGRA_8888_PRE; + break; + case WL_SHM_FORMAT_XRGB8888: + format = COGL_PIXEL_FORMAT_BGRA_8888; + break; +#endif + default: + g_warn_if_reached (); + format = COGL_PIXEL_FORMAT_ARGB_8888; + } + + cogl_texture_set_region (priv->texture, + x, y, + x, y, + width, height, + width, height, + format, + wl_shm_buffer_get_stride (shm_buffer), + wl_shm_buffer_get_data (shm_buffer)); + } + } +} +#endif /* HAVE_WAYLAND */ + +static void +queue_damage_redraw_with_clip (MetaShapedTexture *stex, + int x, + int y, + int width, + int height) +{ + ClutterActor *self = CLUTTER_ACTOR (stex); + MetaShapedTexturePrivate *priv; + ClutterActorBox allocation; + float scale_x; + float scale_y; + cairo_rectangle_int_t clip; + + /* NB: clutter_actor_queue_redraw_with_clip expects a box in the actor's + * coordinate space so we need to convert from surface coordinates to + * actor coordinates... + */ + + /* Calling clutter_actor_get_allocation_box() is enormously expensive + * if the actor has an out-of-date allocation, since it triggers + * a full redraw. clutter_actor_queue_redraw_with_clip() would redraw + * the whole stage anyways in that case, so just go ahead and do + * it here. + */ + if (!clutter_actor_has_allocation (self)) + { + clutter_actor_queue_redraw (self); + return; + } + + priv = stex->priv; + + if (priv->tex_width == 0 || priv->tex_height == 0) + return; + + clutter_actor_get_allocation_box (self, &allocation); + + scale_x = (allocation.x2 - allocation.x1) / priv->tex_width; + scale_y = (allocation.y2 - allocation.y1) / priv->tex_height; + + clip.x = x * scale_x; + clip.y = y * scale_y; + clip.width = width * scale_x; + clip.height = height * scale_y; + clutter_actor_queue_redraw_with_clip (self, &clip); +} + +void +meta_shaped_texture_update_area (MetaShapedTexture *stex, + int x, + int y, + int width, + int height) { MetaShapedTexturePrivate *priv; - const cairo_rectangle_int_t clip = { x, y, width, height }; priv = stex->priv; if (priv->texture == NULL) return; - cogl_texture_pixmap_x11_update_area (priv->texture, - x, y, width, height); + switch (priv->type) + { + case META_SHAPED_TEXTURE_TYPE_X11_PIXMAP: + cogl_texture_pixmap_x11_update_area (COGL_TEXTURE_PIXMAP_X11 (priv->texture), + x, y, width, height); + break; +#ifdef HAVE_WAYLAND + case META_SHAPED_TEXTURE_TYPE_WAYLAND_SURFACE: + wayland_surface_update_area (stex, x, y, width, height); + break; +#endif + } meta_texture_tower_update_area (priv->paint_tower, x, y, width, height); - clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stex), &clip); -} - -static void -set_cogl_texture (MetaShapedTexture *stex, - CoglTexturePixmapX11 *cogl_tex) -{ - MetaShapedTexturePrivate *priv; - guint width, height; - - g_return_if_fail (META_IS_SHAPED_TEXTURE (stex)); - - priv = stex->priv; - - if (priv->texture != NULL) - cogl_object_unref (priv->texture); - - priv->texture = cogl_tex; - - if (priv->pipeline != NULL) - cogl_pipeline_set_layer_texture (priv->pipeline, 0, COGL_TEXTURE (cogl_tex)); - - if (priv->pipeline_unshaped != NULL) - cogl_pipeline_set_layer_texture (priv->pipeline_unshaped, 0, COGL_TEXTURE (cogl_tex)); - - if (cogl_tex != NULL) - { - width = cogl_texture_get_width (COGL_TEXTURE (cogl_tex)); - height = cogl_texture_get_height (COGL_TEXTURE (cogl_tex)); - - if (width != priv->tex_width || - height != priv->tex_height) - { - priv->tex_width = width; - priv->tex_height = height; - - clutter_actor_queue_relayout (CLUTTER_ACTOR (stex)); - } - } - else - { - /* size changed to 0 going to an inavlid texture */ - priv->tex_width = 0; - priv->tex_height = 0; - clutter_actor_queue_relayout (CLUTTER_ACTOR (stex)); - } - - clutter_actor_queue_redraw (CLUTTER_ACTOR (stex)); + queue_damage_redraw_with_clip (stex, x, y, width, height); } /** @@ -516,16 +713,18 @@ meta_shaped_texture_set_pixmap (MetaShapedTexture *stex, priv = stex->priv; - if (priv->pixmap == pixmap) + if (priv->x11.pixmap == pixmap) return; - priv->pixmap = pixmap; + priv->x11.pixmap = pixmap; 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)); + CoglTexture *texture = + COGL_TEXTURE (cogl_texture_pixmap_x11_new (ctx, pixmap, FALSE, NULL)); + set_cogl_texture (stex, texture); } else set_cogl_texture (stex, NULL); @@ -535,6 +734,54 @@ meta_shaped_texture_set_pixmap (MetaShapedTexture *stex, COGL_TEXTURE (priv->texture)); } +#ifdef HAVE_WAYLAND +void +meta_shaped_texture_attach_wayland_buffer (MetaShapedTexture *stex, + MetaWaylandBuffer *buffer) +{ + MetaShapedTexturePrivate *priv; + + g_return_if_fail (META_IS_SHAPED_TEXTURE (stex)); + + priv = stex->priv; + + /* TODO: we should change this api to be something like + * meta_shaped_texture_notify_buffer_attach() since we now maintain + * a reference to the MetaWaylandSurface where we can access the + * buffer without it being explicitly passed as an argument. + */ + g_return_if_fail (priv->wayland.surface->buffer_ref.buffer == buffer); + + if (buffer) + { + CoglContext *ctx = + clutter_backend_get_cogl_context (clutter_get_default_backend ()); + CoglError *catch_error = NULL; + CoglTexture *texture = + COGL_TEXTURE (cogl_wayland_texture_2d_new_from_buffer (ctx, + buffer->resource, + &catch_error)); + if (!texture) + { + cogl_error_free (catch_error); + } + else + { + buffer->width = cogl_texture_get_width (texture); + buffer->height = cogl_texture_get_height (texture); + } + + set_cogl_texture (stex, texture); + } + else + set_cogl_texture (stex, NULL); + + if (priv->create_mipmaps) + meta_texture_tower_set_base_texture (priv->paint_tower, + COGL_TEXTURE (priv->texture)); +} +#endif /* HAVE_WAYLAND */ + /** * meta_shaped_texture_get_texture: * @stex: The #MetaShapedTexture diff --git a/src/compositor/meta-window-actor-private.h b/src/compositor/meta-window-actor-private.h index 90a9e35e0..d37ee2dbb 100644 --- a/src/compositor/meta-window-actor-private.h +++ b/src/compositor/meta-window-actor-private.h @@ -5,6 +5,11 @@ #include +#ifdef HAVE_WAYLAND +#include +#include +#endif + #include #include @@ -24,8 +29,20 @@ void meta_window_actor_unmaximize (MetaWindowActor *self, MetaRectangle *old_rect, MetaRectangle *new_rect); -void meta_window_actor_process_damage (MetaWindowActor *self, - XDamageNotifyEvent *event); +void meta_window_actor_process_x11_damage (MetaWindowActor *self, + XDamageNotifyEvent *event); + +#ifdef HAVE_WAYLAND +void meta_window_actor_process_wayland_damage (MetaWindowActor *self, + int x, + int y, + int width, + int height); +void meta_window_actor_set_wayland_surface (MetaWindowActor *self, + MetaWaylandSurface *surface); +void meta_window_actor_attach_wayland_buffer (MetaWindowActor *self, + MetaWaylandBuffer *buffer); +#endif void meta_window_actor_pre_paint (MetaWindowActor *self); void meta_window_actor_post_paint (MetaWindowActor *self); diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 34a8fa1b9..54f6838aa 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -32,6 +32,9 @@ #include "meta-window-actor-private.h" #include "meta-texture-rectangle.h" #include "region-utils.h" +#ifdef HAVE_WAYLAND +#include "meta-wayland-private.h" +#endif enum { POSITION_CHANGED, @@ -64,10 +67,6 @@ struct _MetaWindowActorPrivate MetaShadow *focused_shadow; MetaShadow *unfocused_shadow; - Pixmap back_pixmap; - - Damage damage; - guint8 opacity; /* A region that matches the shape of the window, including frame bounds */ @@ -104,31 +103,41 @@ struct _MetaWindowActorPrivate /* List of FrameData for recent frames */ GList *frames; + Pixmap back_pixmap; /* Not used in wayland compositor mode */ + Damage damage; /* Not used in wayland compositor mode */ + guint visible : 1; guint mapped : 1; guint argb32 : 1; guint disposed : 1; guint redecorating : 1; - guint needs_damage_all : 1; - guint received_damage : 1; - guint repaint_scheduled : 1; - /* If set, the client needs to be sent a _NET_WM_FRAME_DRAWN * client message using the most recent frame in ->frames */ guint needs_frame_drawn : 1; + guint repaint_scheduled : 1; - guint needs_pixmap : 1; guint needs_reshape : 1; guint recompute_focused_shadow : 1; guint recompute_unfocused_shadow : 1; - guint size_changed : 1; - guint updates_frozen : 1; guint needs_destroy : 1; guint no_shadow : 1; + + /* + * None of these are used in wayland compositor mode... + */ + + guint needs_damage_all : 1; + guint received_x11_damage : 1; + + guint needs_pixmap : 1; + + guint x11_size_changed : 1; + guint updates_frozen : 1; + guint unredirected : 1; /* This is used to detect fullscreen windows that need to be unredirected */ @@ -172,7 +181,7 @@ static gboolean meta_window_actor_get_paint_volume (ClutterActor *actor, ClutterPaintVolume *volume); -static void meta_window_actor_detach (MetaWindowActor *self); +static void meta_window_actor_detach_x11_pixmap (MetaWindowActor *self); static gboolean meta_window_actor_has_shadow (MetaWindowActor *self); static void meta_window_actor_handle_updates (MetaWindowActor *self); @@ -306,18 +315,21 @@ window_decorated_notify (MetaWindow *mw, else new_xwindow = meta_window_get_xwindow (mw); - meta_window_actor_detach (self); - - /* - * First of all, clean up any resources we are currently using and will - * be replacing. - */ - if (priv->damage != None) + if (!meta_is_wayland_compositor ()) { - meta_error_trap_push (display); - XDamageDestroy (xdisplay, priv->damage); - meta_error_trap_pop (display); - priv->damage = None; + meta_window_actor_detach_x11_pixmap (self); + + /* + * First of all, clean up any resources we are currently using and will + * be replacing. + */ + if (priv->damage != None) + { + meta_error_trap_push (display); + XDamageDestroy (xdisplay, priv->damage); + meta_error_trap_pop (display); + priv->damage = None; + } } priv->xwindow = new_xwindow; @@ -348,8 +360,9 @@ meta_window_actor_constructed (GObject *object) Display *xdisplay = meta_display_get_xdisplay (display); XRenderPictFormat *format; - priv->damage = XDamageCreate (xdisplay, xwindow, - XDamageReportBoundingBox); + if (!meta_is_wayland_compositor ()) + priv->damage = XDamageCreate (xdisplay, xwindow, + XDamageReportBoundingBox); format = XRenderFindVisualFormat (xdisplay, window->xvisual); @@ -358,7 +371,12 @@ meta_window_actor_constructed (GObject *object) if (!priv->actor) { - priv->actor = meta_shaped_texture_new (); + if (window->client_type == META_WINDOW_CLIENT_TYPE_X11) + priv->actor = meta_shaped_texture_new_with_xwindow (xwindow); +#ifdef HAVE_WAYLAND + else + priv->actor = meta_shaped_texture_new_with_wayland_surface (window->surface); +#endif clutter_actor_add_child (CLUTTER_ACTOR (self), priv->actor); @@ -387,9 +405,10 @@ meta_window_actor_constructed (GObject *object) meta_window_actor_update_opacity (self); - /* Start off with an empty region to maintain the invariant that - the shape region is always set */ + /* Start off with empty regions to maintain the invariant that + these regions are always set */ priv->shape_region = cairo_region_create(); + priv->input_shape_region = cairo_region_create(); } static void @@ -408,11 +427,15 @@ meta_window_actor_dispose (GObject *object) priv->disposed = TRUE; screen = priv->screen; - display = meta_screen_get_display (screen); - xdisplay = meta_display_get_xdisplay (display); info = meta_screen_get_compositor_data (screen); - meta_window_actor_detach (self); + if (!meta_is_wayland_compositor ()) + { + display = meta_screen_get_display (screen); + xdisplay = meta_display_get_xdisplay (display); + + meta_window_actor_detach_x11_pixmap (self); + } g_clear_pointer (&priv->shape_region, cairo_region_destroy); g_clear_pointer (&priv->input_shape_region, cairo_region_destroy); @@ -424,7 +447,7 @@ meta_window_actor_dispose (GObject *object) g_clear_pointer (&priv->unfocused_shadow, meta_shadow_unref); g_clear_pointer (&priv->shadow_shape, meta_window_shape_unref); - if (priv->damage != None) + if (!meta_is_wayland_compositor () && priv->damage != None) { meta_error_trap_push (display); XDamageDestroy (xdisplay, priv->damage); @@ -896,7 +919,8 @@ meta_window_actor_showing_on_its_workspace (MetaWindowActor *self) static void meta_window_actor_freeze (MetaWindowActor *self) { - self->priv->freeze_count++; + if (!meta_is_wayland_compositor ()) + self->priv->freeze_count++; } static void @@ -925,30 +949,33 @@ meta_window_actor_damage_all (MetaWindowActor *self) static void meta_window_actor_thaw (MetaWindowActor *self) { - self->priv->freeze_count--; - - if (G_UNLIKELY (self->priv->freeze_count < 0)) + if (!meta_is_wayland_compositor ()) { - g_warning ("Error in freeze/thaw accounting."); - self->priv->freeze_count = 0; - return; + self->priv->freeze_count--; + + if (G_UNLIKELY (self->priv->freeze_count < 0)) + { + g_warning ("Error in freeze/thaw accounting."); + self->priv->freeze_count = 0; + return; + } + + if (self->priv->freeze_count) + return; + + /* We sometimes ignore moves and resizes on frozen windows */ + meta_window_actor_sync_actor_geometry (self, FALSE); + + /* We do this now since we might be going right back into the + * frozen state */ + meta_window_actor_handle_updates (self); + + /* Since we ignore damage events while a window is frozen for certain effects + * we may need to issue an update_area() covering the whole pixmap if we + * don't know what real damage has happened. */ + if (self->priv->needs_damage_all) + meta_window_actor_damage_all (self); } - - if (self->priv->freeze_count) - return; - - /* We sometimes ignore moves and resizes on frozen windows */ - meta_window_actor_sync_actor_geometry (self, FALSE); - - /* We do this now since we might be going right back into the - * frozen state */ - meta_window_actor_handle_updates (self); - - /* Since we ignore damage events while a window is frozen for certain effects - * we may need to issue an update_area() covering the whole pixmap if we - * don't know what real damage has happened. */ - if (self->priv->needs_damage_all) - meta_window_actor_damage_all (self); } void @@ -979,7 +1006,7 @@ meta_window_actor_queue_frame_drawn (MetaWindowActor *self, * send a _NET_WM_FRAME_DRAWN. We do a 1-pixel redraw to get * consistent timing with non-empty frames. */ - if (priv->mapped && !priv->needs_pixmap) + if (priv->mapped && (!meta_is_wayland_compositor () || !priv->needs_pixmap)) { const cairo_rectangle_int_t clip = { 0, 0, 1, 1 }; clutter_actor_queue_redraw_with_clip (priv->actor, &clip); @@ -1005,7 +1032,7 @@ is_frozen (MetaWindowActor *self) } static void -meta_window_actor_queue_create_pixmap (MetaWindowActor *self) +meta_window_actor_queue_create_x11_pixmap (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; @@ -1109,11 +1136,14 @@ meta_window_actor_after_effects (MetaWindowActor *self) meta_window_actor_sync_visibility (self); meta_window_actor_sync_actor_geometry (self, FALSE); - if (!meta_window_is_mapped (priv->window)) - meta_window_actor_detach (self); + if (!meta_is_wayland_compositor ()) + { + if (!meta_window_is_mapped (priv->window)) + meta_window_actor_detach_x11_pixmap (self); - if (priv->needs_pixmap) - clutter_actor_queue_redraw (priv->actor); + if (priv->needs_pixmap) + clutter_actor_queue_redraw (priv->actor); + } } void @@ -1194,7 +1224,7 @@ meta_window_actor_effect_completed (MetaWindowActor *self, * pixmap for a new size. */ static void -meta_window_actor_detach (MetaWindowActor *self) +meta_window_actor_detach_x11_pixmap (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; MetaScreen *screen = priv->screen; @@ -1215,7 +1245,7 @@ meta_window_actor_detach (MetaWindowActor *self) XFreePixmap (xdisplay, priv->back_pixmap); priv->back_pixmap = None; - meta_window_actor_queue_create_pixmap (self); + meta_window_actor_queue_create_x11_pixmap (self); } gboolean @@ -1245,7 +1275,7 @@ meta_window_actor_should_unredirect (MetaWindowActor *self) if (meta_window_is_override_redirect (metaWindow)) return TRUE; - if (priv->does_full_damage) + if (!meta_is_wayland_compositor () && priv->does_full_damage) return TRUE; return FALSE; @@ -1265,7 +1295,7 @@ meta_window_actor_set_redirected (MetaWindowActor *self, gboolean state) meta_error_trap_push (display); XCompositeRedirectWindow (xdisplay, xwin, CompositeRedirectManual); meta_error_trap_pop (display); - meta_window_actor_detach (self); + meta_window_actor_detach_x11_pixmap (self); self->priv->unredirected = FALSE; } else @@ -1338,15 +1368,21 @@ meta_window_actor_sync_actor_geometry (MetaWindowActor *self, meta_window_get_input_rect (priv->window, &window_rect); - if (priv->last_width != window_rect.width || - priv->last_height != window_rect.height) + /* When running as a display server then we instead catch size changes when + * new buffers are attached */ + if (!meta_is_wayland_compositor ()) { - priv->size_changed = TRUE; - meta_window_actor_queue_create_pixmap (self); - meta_window_actor_update_shape (self); + if (priv->last_width != window_rect.width || + priv->last_height != window_rect.height) + { + priv->x11_size_changed = TRUE; + meta_window_actor_queue_create_x11_pixmap (self); - priv->last_width = window_rect.width; - priv->last_height = window_rect.height; + meta_window_actor_update_shape (self); + + priv->last_width = window_rect.width; + priv->last_height = window_rect.height; + } } if (meta_window_actor_effect_in_progress (self)) @@ -1510,16 +1546,27 @@ meta_window_actor_new (MetaWindow *window) MetaWindowActor *self; MetaWindowActorPrivate *priv; MetaFrame *frame; - Window top_window; + Window top_window = None; ClutterActor *window_group; - frame = meta_window_get_frame (window); - if (frame) - top_window = meta_frame_get_xwindow (frame); - else - top_window = meta_window_get_xwindow (window); + if (window->client_type == META_WINDOW_CLIENT_TYPE_X11) + { + frame = meta_window_get_frame (window); + if (frame) + top_window = meta_frame_get_xwindow (frame); + else + top_window = meta_window_get_xwindow (window); - meta_verbose ("add window: Meta %p, xwin 0x%x\n", window, (guint)top_window); + meta_verbose ("add window: Meta %p, xwin 0x%x\n", window, (guint)top_window); + } +#ifdef HAVE_WAYLAND + else + { + meta_verbose ("add window: Meta %p, wayland surface %p\n", + window, window->surface); + top_window = None; + } +#endif self = g_object_new (META_TYPE_WINDOW_ACTOR, "meta-window", window, @@ -1529,21 +1576,24 @@ meta_window_actor_new (MetaWindow *window) priv = self->priv; - priv->last_width = -1; - priv->last_height = -1; + if (!meta_is_wayland_compositor ()) + { + priv->last_width = -1; + priv->last_height = -1; - priv->mapped = meta_window_toplevel_is_mapped (priv->window); - if (priv->mapped) - meta_window_actor_queue_create_pixmap (self); + priv->mapped = meta_window_toplevel_is_mapped (priv->window); + if (priv->mapped) + meta_window_actor_queue_create_x11_pixmap (self); - meta_window_actor_set_updates_frozen (self, - meta_window_updates_are_frozen (priv->window)); + meta_window_actor_set_updates_frozen (self, + meta_window_updates_are_frozen (priv->window)); - /* If a window doesn't start off with updates frozen, we should - * we should send a _NET_WM_FRAME_DRAWN immediately after the first drawn. - */ - if (priv->window->extended_sync_request_counter && !priv->updates_frozen) - meta_window_actor_queue_frame_drawn (self, FALSE); + /* If a window doesn't start off with updates frozen, we should + * we should send a _NET_WM_FRAME_DRAWN immediately after the first drawn. + */ + if (priv->window->extended_sync_request_counter && !priv->updates_frozen) + meta_window_actor_queue_frame_drawn (self, FALSE); + } meta_window_actor_sync_actor_geometry (self, priv->window->placed); @@ -1578,7 +1628,8 @@ meta_window_actor_mapped (MetaWindowActor *self) priv->mapped = TRUE; - meta_window_actor_queue_create_pixmap (self); + if (!meta_is_wayland_compositor ()) + meta_window_actor_queue_create_x11_pixmap (self); } void @@ -1593,8 +1644,11 @@ meta_window_actor_unmapped (MetaWindowActor *self) if (meta_window_actor_effect_in_progress (self)) return; - meta_window_actor_detach (self); - priv->needs_pixmap = FALSE; + if (!meta_is_wayland_compositor ()) + { + meta_window_actor_detach_x11_pixmap (self); + priv->needs_pixmap = FALSE; + } } /** @@ -1612,10 +1666,21 @@ meta_window_actor_get_obscured_region (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; - if (priv->back_pixmap && priv->opacity == 0xff && !priv->window->shaded) - return priv->opaque_region; - else - return NULL; + if (!priv->window->shaded) + { + if (meta_is_wayland_compositor ()) + { + if (priv->opacity == 0xff) + return priv->opaque_region; + } + else + { + if (priv->back_pixmap && priv->opacity == 0xff) + return priv->opaque_region; + } + } + + return NULL; } #if 0 @@ -1728,8 +1793,11 @@ meta_window_actor_reset_visible_regions (MetaWindowActor *self) g_clear_pointer (&priv->shadow_clip, cairo_region_destroy); } +/* When running as a wayland compositor we don't make requests for + * replacement pixmaps when resizing windows, we will instead be + * asked to attach replacement buffers by the clients. */ static void -check_needs_pixmap (MetaWindowActor *self) +check_needs_x11_pixmap (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; MetaScreen *screen = priv->screen; @@ -1751,10 +1819,10 @@ check_needs_pixmap (MetaWindowActor *self) compositor = meta_display_get_compositor (display); - if (priv->size_changed) + if (priv->x11_size_changed) { - meta_window_actor_detach (self); - priv->size_changed = FALSE; + meta_window_actor_detach_x11_pixmap (self); + priv->x11_size_changed = FALSE; } meta_error_trap_push (display); @@ -1886,13 +1954,13 @@ check_needs_shadow (MetaWindowActor *self) } void -meta_window_actor_process_damage (MetaWindowActor *self, - XDamageNotifyEvent *event) +meta_window_actor_process_x11_damage (MetaWindowActor *self, + XDamageNotifyEvent *event) { MetaWindowActorPrivate *priv = self->priv; MetaCompScreen *info = meta_screen_get_compositor_data (priv->screen); - priv->received_damage = TRUE; + priv->received_x11_damage = TRUE; if (meta_window_is_fullscreen (priv->window) && g_list_last (info->windows)->data == self && !priv->unredirected) { @@ -1946,6 +2014,25 @@ meta_window_actor_process_damage (MetaWindowActor *self, priv->repaint_scheduled = TRUE; } +#ifdef HAVE_WAYLAND +void +meta_window_actor_process_wayland_damage (MetaWindowActor *self, + int x, + int y, + int width, + int height) +{ + MetaWindowActorPrivate *priv = self->priv; + + if (!priv->mapped) + return; + + meta_shaped_texture_update_area (META_SHAPED_TEXTURE (priv->actor), + x, y, width, height); + priv->repaint_scheduled = TRUE; +} +#endif + void meta_window_actor_sync_visibility (MetaWindowActor *self) { @@ -2106,8 +2193,8 @@ region_create_from_x_rectangles (const XRectangle *rects, } static void -meta_window_actor_update_shape_region (MetaWindowActor *self, - cairo_rectangle_int_t *client_area) +meta_window_actor_update_x11_shape_region (MetaWindowActor *self, + cairo_rectangle_int_t *client_area) { MetaWindowActorPrivate *priv = self->priv; cairo_region_t *region = NULL; @@ -2212,8 +2299,8 @@ meta_window_actor_update_shape_region (MetaWindowActor *self, } static void -meta_window_actor_update_input_shape_region (MetaWindowActor *self, - cairo_rectangle_int_t *client_area) +meta_window_actor_update_x11_input_shape_region (MetaWindowActor *self, + cairo_rectangle_int_t *client_area) { MetaWindowActorPrivate *priv = self->priv; cairo_region_t *region = NULL; @@ -2299,8 +2386,24 @@ check_needs_reshape (MetaWindowActor *self) else client_area.height = priv->window->rect.height; - meta_window_actor_update_shape_region (self, &client_area); - meta_window_actor_update_input_shape_region (self, &client_area); + if (priv->window->client_type == META_WINDOW_CLIENT_TYPE_X11) + { + meta_window_actor_update_x11_shape_region (self, &client_area); + meta_window_actor_update_x11_input_shape_region (self, &client_area); + } + else + { + /* TODO: properly support setting an input region as specified + * via the wayland protocol */ + + g_clear_pointer (&priv->shape_region, cairo_region_destroy); + g_clear_pointer (&priv->opaque_region, cairo_region_destroy); + g_clear_pointer (&priv->input_shape_region, cairo_region_destroy); + + priv->shape_region = cairo_region_create_rectangle (&client_area); + priv->opaque_region = cairo_region_reference (priv->shape_region); + priv->input_shape_region = cairo_region_reference (priv->shape_region); + } priv->needs_reshape = FALSE; } @@ -2318,6 +2421,69 @@ meta_window_actor_update_shape (MetaWindowActor *self) clutter_actor_queue_redraw (priv->actor); } +#ifdef HAVE_WAYLAND +static void +maybe_emit_size_changed (MetaWindowActor *self, + MetaWaylandBuffer *new_buffer) +{ + MetaWindowActorPrivate *priv = self->priv; + int width = 0, height = 0; + + if (new_buffer) + { + width = new_buffer->width; + height = new_buffer->height; + } + + if (priv->last_width != width || priv->last_height != height) + { + meta_window_actor_update_shape (self); + + /* ::size-changed is supposed to refer to meta_window_get_outer_rect() + * but here we are only looking at buffer size changes. + * + * Emitting it here works pretty much OK because a new buffer size (which + * will correspond to the outer rect with the addition of invisible + * borders) also normally implies a change to the outer rect. In the rare + * case where a change to the window size was exactly balanced by a + * change to the invisible borders, we would miss emitting the signal. + */ + g_signal_emit (self, signals[SIZE_CHANGED], 0); + + priv->last_width = width; + priv->last_height = height; + } +} + +void +meta_window_actor_set_wayland_surface (MetaWindowActor *self, + MetaWaylandSurface *surface) +{ + MetaWindowActorPrivate *priv = self->priv; + + meta_shaped_texture_set_wayland_surface (META_SHAPED_TEXTURE (priv->actor), + surface); + if (surface->buffer_ref.buffer) + maybe_emit_size_changed (self, surface->buffer_ref.buffer); +} + +void +meta_window_actor_attach_wayland_buffer (MetaWindowActor *self, + MetaWaylandBuffer *buffer) +{ + MetaWindowActorPrivate *priv = self->priv; + MetaShapedTexture *stex = META_SHAPED_TEXTURE (priv->actor); + CoglTexture *prev_tex = meta_shaped_texture_get_texture (stex); + + meta_shaped_texture_attach_wayland_buffer (stex, buffer); + + if (!prev_tex) + meta_window_actor_sync_actor_geometry (self, FALSE); + + maybe_emit_size_changed (self, buffer); +} +#endif /* HAVE_WAYLAND */ + static void meta_window_actor_handle_updates (MetaWindowActor *self) { @@ -2333,42 +2499,46 @@ meta_window_actor_handle_updates (MetaWindowActor *self) return; } - if (priv->unredirected) + if (!meta_is_wayland_compositor ()) { - /* Nothing to do here until/if the window gets redirected again */ - return; + if (priv->unredirected) + { + /* Nothing to do here until/if the window gets redirected again */ + return; + } + + if (priv->received_x11_damage) + { + meta_error_trap_push (display); + XDamageSubtract (xdisplay, priv->damage, None, None); + meta_error_trap_pop (display); + + /* We need to make sure that any X drawing that happens before the + * XDamageSubtract() 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. + * + * Xorg and open source driver specifics: + * + * The X server makes sure to flush drawing to the kernel before + * sending out damage events, but since we use DamageReportBoundingBox + * there may be drawing between the last damage event and the + * XDamageSubtract() that needs to be flushed as well. + * + * Xorg always makes sure that drawing is flushed to the kernel + * before writing events or responses to the client, so any round trip + * request at this point is sufficient to flush the GLX buffers. + */ + XSync (xdisplay, False); + + priv->received_x11_damage = FALSE; + } + + check_needs_x11_pixmap (self); } - if (priv->received_damage) - { - meta_error_trap_push (display); - XDamageSubtract (xdisplay, priv->damage, None, None); - meta_error_trap_pop (display); - - /* We need to make sure that any X drawing that happens before the - * XDamageSubtract() 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. - * - * Xorg and open source driver specifics: - * - * The X server makes sure to flush drawing to the kernel before - * sending out damage events, but since we use DamageReportBoundingBox - * there may be drawing between the last damage event and the - * XDamageSubtract() that needs to be flushed as well. - * - * Xorg always makes sure that drawing is flushed to the kernel - * before writing events or responses to the client, so any round trip - * request at this point is sufficient to flush the GLX buffers. - */ - XSync (xdisplay, False); - - priv->received_damage = FALSE; - } - - check_needs_pixmap (self); check_needs_reshape (self); check_needs_shadow (self); } @@ -2547,16 +2717,20 @@ void meta_window_actor_set_updates_frozen (MetaWindowActor *self, gboolean updates_frozen) { - MetaWindowActorPrivate *priv = self->priv; - - updates_frozen = updates_frozen != FALSE; - - if (priv->updates_frozen != updates_frozen) + /* On wayland we shouldn't need to ever freeze updates... */ + if (!meta_is_wayland_compositor ()) { - priv->updates_frozen = updates_frozen; - if (updates_frozen) - meta_window_actor_freeze (self); - else - meta_window_actor_thaw (self); + MetaWindowActorPrivate *priv = self->priv; + + updates_frozen = updates_frozen != FALSE; + + if (priv->updates_frozen != updates_frozen) + { + priv->updates_frozen = updates_frozen; + if (updates_frozen) + meta_window_actor_freeze (self); + else + meta_window_actor_thaw (self); + } } } diff --git a/src/compositor/meta-window-group.c b/src/compositor/meta-window-group.c index ec22af31a..8fddc5e67 100644 --- a/src/compositor/meta-window-group.c +++ b/src/compositor/meta-window-group.c @@ -13,6 +13,7 @@ #include "meta-window-group.h" #include "meta-background-actor-private.h" #include "meta-background-group-private.h" +#include "window-private.h" struct _MetaWindowGroupClass { @@ -99,7 +100,7 @@ meta_window_group_paint (ClutterActor *actor) int paint_x_offset, paint_y_offset; MetaWindowGroup *window_group = META_WINDOW_GROUP (actor); - MetaCompScreen *info = meta_screen_get_compositor_data (window_group->screen); + MetaCompScreen *info; /* Normally we expect an actor to be drawn at it's position on the screen. * However, if we're inside the paint of a ClutterClone, that won't be the @@ -136,13 +137,17 @@ meta_window_group_paint (ClutterActor *actor) visible_region = cairo_region_create_rectangle (&visible_rect); - if (info->unredirected_window != NULL) + if (!meta_is_wayland_compositor ()) { - cairo_rectangle_int_t unredirected_rect; - MetaWindow *window = meta_window_actor_get_meta_window (info->unredirected_window); + info = meta_screen_get_compositor_data (window_group->screen); + if (info->unredirected_window != NULL) + { + cairo_rectangle_int_t unredirected_rect; + MetaWindow *window = meta_window_actor_get_meta_window (info->unredirected_window); - meta_window_get_outer_rect (window, (MetaRectangle *)&unredirected_rect); - cairo_region_subtract_rectangle (visible_region, &unredirected_rect); + meta_window_get_outer_rect (window, (MetaRectangle *)&unredirected_rect); + cairo_region_subtract_rectangle (visible_region, &unredirected_rect); + } } /* We walk the list from top to bottom (opposite of painting order), @@ -155,7 +160,8 @@ meta_window_group_paint (ClutterActor *actor) if (!CLUTTER_ACTOR_IS_VISIBLE (child)) continue; - if (info->unredirected_window != NULL && + if (!meta_is_wayland_compositor () && + info->unredirected_window != NULL && child == CLUTTER_ACTOR (info->unredirected_window)) continue; @@ -180,7 +186,8 @@ meta_window_group_paint (ClutterActor *actor) if (META_IS_WINDOW_ACTOR (child)) { - MetaWindowActor *window_actor = META_WINDOW_ACTOR (child); + MetaWindow *meta_window; + MetaWindowActor *window_actor = child; int x, y; if (!meta_actor_is_untransformed (CLUTTER_ACTOR (window_actor), &x, &y)) @@ -194,7 +201,14 @@ meta_window_group_paint (ClutterActor *actor) meta_window_actor_set_visible_region (window_actor, visible_region); - if (clutter_actor_get_paint_opacity (CLUTTER_ACTOR (window_actor)) == 0xff) + /* TODO: Track the opaque regions of wayland clients. + * Although wayland clients can report opaque window + * regions, for now we assume that all wayland clients are + * transparent... */ + meta_window = meta_window_actor_get_meta_window (window_actor); + + if (meta_window->client_type != META_WINDOW_CLIENT_TYPE_WAYLAND && + clutter_actor_get_paint_opacity (CLUTTER_ACTOR (window_actor)) == 0xff) { cairo_region_t *obscured_region = meta_window_actor_get_obscured_region (window_actor); if (obscured_region) diff --git a/src/core/display.c b/src/core/display.c index 9bcb5e5c7..5e19f1439 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -931,8 +931,24 @@ meta_display_open (void) while (tmp != NULL) { MetaScreen *screen = tmp->data; - - meta_screen_manage_all_windows (screen); + + if (meta_is_wayland_compositor ()) + { + /* Instead of explicitly enumerating all windows during + * initialization, when we run as a wayland compositor we can rely on + * xwayland notifying us of all top level windows so we create + * MetaWindows when we get those notifications. + * + * We still want a guard window so we can avoid + * unmapping/withdrawing minimized windows for live + * thumbnails... + */ + if (screen->guard_window == None) + screen->guard_window = + meta_screen_create_guard_window (screen->display->xdisplay, screen); + } + else + meta_screen_manage_all_windows (screen); tmp = tmp->next; } @@ -2284,8 +2300,8 @@ event_callback (XEvent *event, } if (display->compositor) - meta_compositor_window_shape_changed (display->compositor, - window); + meta_compositor_window_x11_shape_changed (display->compositor, + window); } else if (sev->kind == ShapeInput) { @@ -2311,8 +2327,8 @@ event_callback (XEvent *event, } if (display->compositor) - meta_compositor_window_shape_changed (display->compositor, - window); + meta_compositor_window_x11_shape_changed (display->compositor, + window); } } else diff --git a/src/core/main.c b/src/core/main.c index 4bec3d260..9dc758e7d 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -55,6 +55,9 @@ #include "session.h" #include #include +#ifdef HAVE_WAYLAND +#include "meta-wayland-private.h" +#endif #include #include @@ -346,28 +349,74 @@ meta_finalize (void) if (display) meta_display_close (display, CurrentTime); /* I doubt correct timestamps matter here */ + +#ifdef HAVE_WAYLAND + if (meta_is_wayland_compositor ()) + meta_wayland_finalize (); +#endif } -static int sigterm_pipe_fds[2] = { -1, -1 }; +static int signal_pipe_fds[2] = { -1, -1 }; static void -sigterm_handler (int signum) +signal_handler (int signum) { - if (sigterm_pipe_fds[1] >= 0) + if (signal_pipe_fds[1] >= 0) { - int G_GNUC_UNUSED dummy; - - dummy = write (sigterm_pipe_fds[1], "", 1); - close (sigterm_pipe_fds[1]); - sigterm_pipe_fds[1] = -1; + switch (signum) + { + case SIGTERM: + write (signal_pipe_fds[1], "T", 1); + break; + case SIGCHLD: + write (signal_pipe_fds[1], "C", 1); + break; + default: + break; + } } } static gboolean -on_sigterm (void) +on_signal (GIOChannel *source, + GIOCondition condition, + void *data) { - meta_quit (META_EXIT_SUCCESS); - return FALSE; + char signal; + int count; + + for (;;) + { + count = read (signal_pipe_fds[0], &signal, 1); + if (count == EINTR) + continue; + if (count < 0) + { + const char *msg = strerror (errno); + g_warning ("Error handling signal: %s", msg); + } + if (count != 1) + { + g_warning ("Unexpectedly failed to read byte from signal pipe\n"); + return TRUE; + } + break; + } + switch (signal) + { + case 'T': /* SIGTERM */ + meta_quit (META_EXIT_SUCCESS); + break; +#ifdef HAVE_WAYLAND + case 'C': /* SIGCHLD */ + meta_wayland_handle_sig_child (); + break; +#endif + default: + g_warning ("Spurious character '%c' read from signal pipe", signal); + } + + return TRUE; } /** @@ -396,21 +445,28 @@ meta_init (void) g_strerror (errno)); #endif - if (pipe (sigterm_pipe_fds) != 0) - g_printerr ("Failed to create SIGTERM pipe: %s\n", + if (pipe (signal_pipe_fds) != 0) + g_printerr ("Failed to create signal pipe: %s\n", g_strerror (errno)); - channel = g_io_channel_unix_new (sigterm_pipe_fds[0]); + channel = g_io_channel_unix_new (signal_pipe_fds[0]); g_io_channel_set_flags (channel, G_IO_FLAG_NONBLOCK, NULL); - g_io_add_watch (channel, G_IO_IN, (GIOFunc) on_sigterm, NULL); + g_io_add_watch (channel, G_IO_IN, (GIOFunc) on_signal, NULL); g_io_channel_set_close_on_unref (channel, TRUE); g_io_channel_unref (channel); - act.sa_handler = &sigterm_handler; + act.sa_handler = &signal_handler; if (sigaction (SIGTERM, &act, NULL) < 0) g_printerr ("Failed to register SIGTERM handler: %s\n", g_strerror (errno)); + if (meta_is_wayland_compositor ()) + { + if (sigaction (SIGCHLD, &act, NULL) < 0) + g_printerr ("Failed to register SIGCHLD handler: %s\n", + g_strerror (errno)); + } + if (g_getenv ("MUTTER_VERBOSE")) meta_set_verbose (TRUE); if (g_getenv ("MUTTER_DEBUG")) @@ -427,9 +483,18 @@ meta_init (void) g_irepository_prepend_search_path (MUTTER_PKGLIBDIR); #endif - meta_set_syncing (opt_sync || (g_getenv ("MUTTER_SYNC") != NULL)); +#ifdef HAVE_WAYLAND + if (meta_is_wayland_compositor ()) + { + /* NB: When running as a hybrid wayland compositor we run our own headless X + * server so the user can't control the X display to connect too. */ + meta_wayland_init (); + } + else +#endif + meta_select_display (opt_display_name); - meta_select_display (opt_display_name); + meta_set_syncing (opt_sync || (g_getenv ("MUTTER_SYNC") != NULL)); if (opt_replace_wm) meta_set_replace_current_wm (TRUE); @@ -441,10 +506,17 @@ meta_init (void) meta_ui_init (); - /* - * Clutter can only be initialized after the UI. - */ - meta_clutter_init (); + /* If we are running with wayland then we don't wait until we have + * an X connection before initializing clutter we instead initialize + * it earlier since we need to initialize the GL driver so the driver + * can register any needed wayland extensions. */ + if (!meta_is_wayland_compositor ()) + { + /* + * Clutter can only be initialized after the UI. + */ + meta_clutter_init (); + } } /** diff --git a/src/core/screen-private.h b/src/core/screen-private.h index 83adb8317..7e8a13318 100644 --- a/src/core/screen-private.h +++ b/src/core/screen-private.h @@ -257,4 +257,6 @@ void meta_screen_workspace_switched (MetaScreen *screen, void meta_screen_set_active_workspace_hint (MetaScreen *screen); +Window meta_screen_create_guard_window (Display *xdisplay, MetaScreen *screen); + #endif diff --git a/src/core/screen.c b/src/core/screen.c index 6db3ea385..e3c997eb4 100644 --- a/src/core/screen.c +++ b/src/core/screen.c @@ -45,6 +45,9 @@ #include #include "mutter-enum-types.h" #include "core.h" +#ifdef HAVE_WAYLAND +#include "meta-wayland-private.h" +#endif #include @@ -603,8 +606,8 @@ reload_monitor_infos (MetaScreen *screen) * should effectively be forwarded to events on the background actor, * providing that the scene graph is set up correctly. */ -static Window -create_guard_window (Display *xdisplay, MetaScreen *screen) +Window +meta_screen_create_guard_window (Display *xdisplay, MetaScreen *screen) { XSetWindowAttributes attributes; Window guard_window; @@ -668,6 +671,9 @@ meta_screen_new (MetaDisplay *display, char buf[128]; guint32 manager_timestamp; gulong current_workspace; +#ifdef HAVE_WAYLAND + MetaWaylandCompositor *compositor; +#endif replace_current_wm = meta_get_replace_current_wm (); @@ -826,8 +832,21 @@ meta_screen_new (MetaDisplay *display, screen->xscreen = ScreenOfDisplay (xdisplay, number); screen->xroot = xroot; screen->rect.x = screen->rect.y = 0; - screen->rect.width = WidthOfScreen (screen->xscreen); - screen->rect.height = HeightOfScreen (screen->xscreen); + +#ifdef HAVE_WAYLAND + if (meta_is_wayland_compositor ()) + { + compositor = meta_wayland_compositor_get_default (); + screen->rect.width = clutter_actor_get_width (compositor->stage); + screen->rect.height = clutter_actor_get_height (compositor->stage); + } + else +#endif + { + screen->rect.width = WidthOfScreen (screen->xscreen); + screen->rect.height = HeightOfScreen (screen->xscreen); + } + screen->current_cursor = -1; /* invalid/unset */ screen->default_xvisual = DefaultVisualOfScreen (screen->xscreen); screen->default_depth = DefaultDepthOfScreen (screen->xscreen); @@ -1082,8 +1101,8 @@ meta_screen_manage_all_windows (MetaScreen *screen) meta_display_grab (screen->display); if (screen->guard_window == None) - screen->guard_window = create_guard_window (screen->display->xdisplay, - screen); + screen->guard_window = + meta_screen_create_guard_window (screen->display->xdisplay, screen); windows = list_windows (screen); diff --git a/src/core/window-private.h b/src/core/window-private.h index 42d380f7e..044d89710 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -44,6 +44,17 @@ #include #include #include +#ifdef HAVE_WAYLAND +#include "meta-wayland-private.h" +#endif + +/* XXX: We should find a nicer approach to deal with the + * circular dependency we have with the current headers + * (meta-wayland-private.h which typedefs MetaWaylandSurface + * also includes window-private.h) */ +#ifndef HAVE_META_WAYLAND_SURFACE_TYPE +typedef struct _MetaWaylandSurface MetaWaylandSurface; +#endif typedef struct _MetaWindowQueue MetaWindowQueue; @@ -69,6 +80,11 @@ typedef enum { _NET_WM_BYPASS_COMPOSITOR_HINT_OFF = 2, } MetaBypassCompositorHintValue; +typedef enum { + META_WINDOW_CLIENT_TYPE_WAYLAND, + META_WINDOW_CLIENT_TYPE_X11 +} MetaWindowClientType; + struct _MetaWindow { GObject parent_instance; @@ -77,6 +93,10 @@ struct _MetaWindow MetaScreen *screen; const MetaMonitorInfo *monitor; MetaWorkspace *workspace; + MetaWindowClientType client_type; +#ifdef HAVE_WAYLAND + MetaWaylandSurface *surface; +#endif Window xwindow; /* may be NULL! not all windows get decorated */ MetaFrame *frame; @@ -489,6 +509,10 @@ MetaWindow* meta_window_new_with_attrs (MetaDisplay *display, gboolean must_be_viewable, MetaCompEffect effect, XWindowAttributes *attrs); +MetaWindow *meta_window_new_for_wayland (MetaDisplay *display, + int width, + int height, + MetaWaylandSurface *surface); void meta_window_unmanage (MetaWindow *window, guint32 timestamp); void meta_window_calc_showing (MetaWindow *window); diff --git a/src/core/window.c b/src/core/window.c index faa9c773d..df535289d 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -713,10 +713,10 @@ meta_window_new (MetaDisplay *display, * Returns TRUE if window has been filtered out and should be ignored. */ static gboolean -maybe_filter_window (MetaDisplay *display, - Window xwindow, - gboolean must_be_viewable, - XWindowAttributes *attrs) +maybe_filter_xwindow (MetaDisplay *display, + Window xwindow, + gboolean must_be_viewable, + XWindowAttributes *attrs) { static char **filter_wm_classes = NULL; static gboolean initialized = FALSE; @@ -812,81 +812,25 @@ meta_window_should_attach_to_parent (MetaWindow *window) } } -MetaWindow* -meta_window_new_with_attrs (MetaDisplay *display, - Window xwindow, - gboolean must_be_viewable, - MetaCompEffect effect, - XWindowAttributes *attrs) +static MetaWindow* +meta_window_new_shared (MetaDisplay *display, + MetaScreen *screen, + MetaWindowClientType client_type, + MetaWaylandSurface *surface, + Window xwindow, + gboolean must_be_viewable, + gulong existing_wm_state, + gboolean has_shape, + gboolean has_input_shape, + MetaCompEffect effect, + XWindowAttributes *attrs) { MetaWindow *window; - GSList *tmp; MetaWorkspace *space; - gulong existing_wm_state; - gulong event_mask; MetaMoveResizeFlags flags; - gboolean has_shape; - gboolean has_input_shape; - MetaScreen *screen; g_assert (attrs != NULL); - meta_verbose ("Attempting to manage 0x%lx\n", xwindow); - - if (meta_display_xwindow_is_a_no_focus_window (display, xwindow)) - { - meta_verbose ("Not managing no_focus_window 0x%lx\n", - xwindow); - return NULL; - } - - screen = NULL; - for (tmp = display->screens; tmp != NULL; tmp = tmp->next) - { - MetaScreen *scr = tmp->data; - - if (scr->xroot == attrs->root) - { - screen = tmp->data; - break; - } - } - - g_assert (screen); - - /* A black list of override redirect windows that we don't need to manage: */ - if (attrs->override_redirect && - (xwindow == screen->no_focus_window || - xwindow == screen->flash_window || - xwindow == screen->wm_sn_selection_window || - attrs->class == InputOnly || - /* any windows created via meta_create_offscreen_window: */ - (attrs->x == -100 && attrs->y == -100 - && attrs->width == 1 && attrs->height == 1) || - xwindow == screen->wm_cm_selection_window || - xwindow == screen->guard_window || - (display->compositor && - xwindow == XCompositeGetOverlayWindow (display->xdisplay, - screen->xroot) - ) - ) - ) { - meta_verbose ("Not managing our own windows\n"); - return NULL; - } - - if (maybe_filter_window (display, xwindow, must_be_viewable, attrs)) - { - meta_verbose ("Not managing filtered window\n"); - return NULL; - } - - /* Grab server */ - meta_display_grab (display); - meta_error_trap_push (display); /* Push a trap over all of window - * creation, to reduce XSync() calls - */ - meta_verbose ("must_be_viewable = %d attrs->map_state = %d (%s)\n", must_be_viewable, attrs->map_state, @@ -898,150 +842,16 @@ meta_window_new_with_attrs (MetaDisplay *display, "IsUnviewable" : "(unknown)"); - existing_wm_state = WithdrawnState; - if (must_be_viewable && attrs->map_state != IsViewable) - { - /* Only manage if WM_STATE is IconicState or NormalState */ - gulong state; - - /* WM_STATE isn't a cardinal, it's type WM_STATE, but is an int */ - if (!(meta_prop_get_cardinal_with_atom_type (display, xwindow, - display->atom_WM_STATE, - display->atom_WM_STATE, - &state) && - (state == IconicState || state == NormalState))) - { - meta_verbose ("Deciding not to manage unmapped or unviewable window 0x%lx\n", xwindow); - meta_error_trap_pop (display); - meta_display_ungrab (display); - return NULL; - } - - existing_wm_state = state; - meta_verbose ("WM_STATE of %lx = %s\n", xwindow, - wm_state_to_string (existing_wm_state)); - } - - meta_error_trap_push_with_return (display); - - /* - * XAddToSaveSet can only be called on windows created by a different client. - * with Mutter we want to be able to create manageable windows from within - * the process (such as a dummy desktop window), so we do not want this - * call failing to prevent the window from being managed -- wrap it in its - * own error trap (we use the _with_return() version here to ensure that - * XSync() is done on the pop, otherwise the error will not get caught). - */ - meta_error_trap_push_with_return (display); - XAddToSaveSet (display->xdisplay, xwindow); - meta_error_trap_pop_with_return (display); - - event_mask = PropertyChangeMask | ColormapChangeMask; - if (attrs->override_redirect) - event_mask |= StructureNotifyMask; - - /* If the window is from this client (a menu, say) we need to augment - * the event mask, not replace it. For windows from other clients, - * attrs->your_event_mask will be empty at this point. - */ - XSelectInput (display->xdisplay, xwindow, attrs->your_event_mask | event_mask); - - { - unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; - XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits }; - - meta_core_add_old_event_mask (display->xdisplay, xwindow, &mask); - - XISetMask (mask.mask, XI_Enter); - XISetMask (mask.mask, XI_Leave); - XISetMask (mask.mask, XI_FocusIn); - XISetMask (mask.mask, XI_FocusOut); - - XISelectEvents (display->xdisplay, xwindow, &mask, 1); - } - - has_shape = FALSE; - has_input_shape = FALSE; -#ifdef HAVE_SHAPE - if (META_DISPLAY_HAS_SHAPE (display)) - { - int x_bounding, y_bounding, x_clip, y_clip; - unsigned w_bounding, h_bounding, w_clip, h_clip; - int bounding_shaped, clip_shaped; - XRectangle *input_rectangles; - int n_rects, ordering; - - XShapeSelectInput (display->xdisplay, xwindow, ShapeNotifyMask); - - XShapeQueryExtents (display->xdisplay, xwindow, - &bounding_shaped, &x_bounding, &y_bounding, - &w_bounding, &h_bounding, - &clip_shaped, &x_clip, &y_clip, - &w_clip, &h_clip); - - has_shape = bounding_shaped != FALSE; - - /* XXX: The x shape extension doesn't provide a way to only test if an - * input shape has been specified, so we have to query and throw away the - * rectangles. */ - meta_error_trap_push (display); - input_rectangles = XShapeGetRectangles (display->xdisplay, xwindow, - ShapeInput, &n_rects, &ordering); - meta_error_trap_pop (display); - if (input_rectangles) - { - if (n_rects > 1 || - (n_rects == 1 && - (input_rectangles[0].x != x_bounding || - input_rectangles[1].y != y_bounding || - input_rectangles[2].width != w_bounding || - input_rectangles[3].height != h_bounding))) - { - has_input_shape = TRUE; - } - XFree (input_rectangles); - } - - meta_topic (META_DEBUG_SHAPES, - "Window has_shape = %d extents %d,%d %u x %u\n", - has_shape, x_bounding, y_bounding, - w_bounding, h_bounding); - } -#endif - - /* Get rid of any borders */ - if (attrs->border_width != 0) - XSetWindowBorderWidth (display->xdisplay, xwindow, 0); - - /* Get rid of weird gravities */ - if (attrs->win_gravity != NorthWestGravity) - { - XSetWindowAttributes set_attrs; - - set_attrs.win_gravity = NorthWestGravity; - - XChangeWindowAttributes (display->xdisplay, - xwindow, - CWWinGravity, - &set_attrs); - } - - if (meta_error_trap_pop_with_return (display) != Success) - { - meta_verbose ("Window 0x%lx disappeared just as we tried to manage it\n", - xwindow); - meta_error_trap_pop (display); - meta_display_ungrab (display); - return NULL; - } - - window = g_object_new (META_TYPE_WINDOW, NULL); window->constructing = TRUE; window->dialog_pid = -1; + window->client_type = client_type; +#ifdef HAVE_WAYLAND + window->surface = surface; +#endif window->xwindow = xwindow; /* this is in window->screen->display, but that's too annoying to @@ -1168,7 +978,11 @@ meta_window_new_with_attrs (MetaDisplay *display, window->mwm_has_move_func = TRUE; window->mwm_has_resize_func = TRUE; - window->decorated = TRUE; + if (client_type == META_WINDOW_CLIENT_TYPE_X11) + window->decorated = TRUE; + else + window->decorated = FALSE; + window->has_close_func = TRUE; window->has_minimize_func = TRUE; window->has_maximize_func = TRUE; @@ -1227,23 +1041,26 @@ meta_window_new_with_attrs (MetaDisplay *display, window->tile_match = NULL; - if (window->override_redirect) - { - window->decorated = FALSE; - window->always_sticky = TRUE; - window->has_close_func = FALSE; - window->has_shade_func = FALSE; - window->has_move_func = FALSE; - window->has_resize_func = FALSE; - } - - meta_display_register_x_window (display, &window->xwindow, window); - /* Assign this #MetaWindow a sequence number which can be used * for sorting. */ window->stable_sequence = ++display->window_sequence_counter; + if (client_type == META_WINDOW_CLIENT_TYPE_X11) + { + if (window->override_redirect) + { + window->decorated = FALSE; + window->always_sticky = TRUE; + window->has_close_func = FALSE; + window->has_shade_func = FALSE; + window->has_move_func = FALSE; + window->has_resize_func = FALSE; + } + + meta_display_register_x_window (display, &window->xwindow, window); + } + /* assign the window to its group, or create a new group if needed */ window->group = NULL; @@ -1252,7 +1069,8 @@ meta_window_new_with_attrs (MetaDisplay *display, meta_window_load_initial_properties (window); - if (!window->override_redirect) + if (!window->override_redirect && + client_type == META_WINDOW_CLIENT_TYPE_X11) { update_sm_hints (window); /* must come after transient_for */ @@ -1526,11 +1344,14 @@ meta_window_new_with_attrs (MetaDisplay *display, !window->initially_iconic) unminimize_window_and_all_transient_parents (window); - meta_error_trap_pop (display); /* pop the XSync()-reducing trap */ - meta_display_ungrab (display); - window->constructing = FALSE; + return window; +} + +static void +display_notify_window (MetaDisplay *display, MetaWindow *window) +{ meta_display_notify_window_created (display, window); if (window->wm_state_demands_attention) @@ -1538,6 +1359,309 @@ meta_window_new_with_attrs (MetaDisplay *display, if (window->wm_hints_urgent) g_signal_emit_by_name (window->display, "window-marked-urgent", window); +} + +#ifdef HAVE_WAYLAND +MetaWindow * +meta_window_new_for_wayland (MetaDisplay *display, + int width, + int height, + MetaWaylandSurface *surface) +{ + XWindowAttributes attrs; + MetaScreen *scr = display->screens->data; + MetaWindow *window; + + attrs.x = 0; + attrs.y = 0; + attrs.width = width; + attrs.height = height; + attrs.border_width = 0; + attrs.depth = 24; + attrs.visual = NULL; + attrs.root = scr->xroot; + attrs.class = InputOutput; + attrs.bit_gravity = NorthWestGravity; + attrs.win_gravity = NorthWestGravity; + attrs.backing_store = 0; + attrs.backing_planes = ~0; + attrs.backing_pixel = 0; + attrs.save_under = 0; + attrs.colormap = 0; + attrs.map_installed = 1; + attrs.map_state = IsUnmapped; + attrs.all_event_masks = ~0; + attrs.your_event_mask = 0; + attrs.do_not_propagate_mask = 0; + attrs.override_redirect = 0; + attrs.screen = scr->xscreen; + + /* XXX: Note: In the Wayland case we currently still grab the + * xserver and trap X errors while creating a MetaWindow because we + * will still be making various redundant X requests (passing a + * window xid of None) until we thoroughly audit all the code to + * make sure it knows about non X based clients... + */ + + /* Grab server */ + meta_display_grab (display); + meta_error_trap_push (display); /* Push a trap over all of window + * creation, to reduce XSync() calls + */ + + window = meta_window_new_shared (display, + scr, + META_WINDOW_CLIENT_TYPE_WAYLAND, + surface, + None, + TRUE, + WithdrawnState, + FALSE, /* has shape */ + FALSE, /* has input shape */ + META_COMP_EFFECT_NONE, + &attrs); + + meta_error_trap_pop (display); /* pop the XSync()-reducing trap */ + meta_display_ungrab (display); + + /* XXX: Maybe this could be called in meta_window_new_shared() but + * before splitting the X11 specific code out it came after the + * meta_display_ungrab() and we wanted to minimize the risk of + * breaking something. + */ + display_notify_window (window->display, window); + + return window; +} +#endif + +MetaWindow* +meta_window_new_with_attrs (MetaDisplay *display, + Window xwindow, + gboolean must_be_viewable, + MetaCompEffect effect, + XWindowAttributes *attrs) +{ + MetaScreen *screen = NULL; + GSList *tmp; + gulong existing_wm_state; + MetaWindow *window; + gulong event_mask; + gboolean has_shape = FALSE; + gboolean has_input_shape = FALSE; + + meta_verbose ("Attempting to manage 0x%lx\n", xwindow); + + if (meta_display_xwindow_is_a_no_focus_window (display, xwindow)) + { + meta_verbose ("Not managing no_focus_window 0x%lx\n", + xwindow); + return NULL; + } + + for (tmp = display->screens; tmp != NULL; tmp = tmp->next) + { + MetaScreen *scr = tmp->data; + + if (scr->xroot == attrs->root) + { + screen = tmp->data; + break; + } + } + + g_assert (screen); + + /* A black list of override redirect windows that we don't need to manage: */ + if (attrs->override_redirect && + (xwindow == screen->no_focus_window || + xwindow == screen->flash_window || + xwindow == screen->wm_sn_selection_window || + attrs->class == InputOnly || + /* any windows created via meta_create_offscreen_window: */ + (attrs->x == -100 && attrs->y == -100 + && attrs->width == 1 && attrs->height == 1) || + xwindow == screen->wm_cm_selection_window || + xwindow == screen->guard_window || + (display->compositor && + xwindow == XCompositeGetOverlayWindow (display->xdisplay, + screen->xroot) + ) + ) + ) { + meta_verbose ("Not managing our own windows\n"); + return NULL; + } + + if (maybe_filter_xwindow (display, xwindow, must_be_viewable, attrs)) + { + meta_verbose ("Not managing filtered window\n"); + return NULL; + } + + /* Grab server */ + meta_display_grab (display); + meta_error_trap_push (display); /* Push a trap over all of window + * creation, to reduce XSync() calls + */ + + existing_wm_state = WithdrawnState; + if (must_be_viewable && attrs->map_state != IsViewable) + { + /* Only manage if WM_STATE is IconicState or NormalState */ + gulong state; + + /* WM_STATE isn't a cardinal, it's type WM_STATE, but is an int */ + if (!(meta_prop_get_cardinal_with_atom_type (display, xwindow, + display->atom_WM_STATE, + display->atom_WM_STATE, + &state) && + (state == IconicState || state == NormalState))) + { + meta_verbose ("Deciding not to manage unmapped or unviewable window 0x%lx\n", xwindow); + meta_error_trap_pop (display); + meta_display_ungrab (display); + return NULL; + } + + existing_wm_state = state; + meta_verbose ("WM_STATE of %lx = %s\n", xwindow, + wm_state_to_string (existing_wm_state)); + } + + meta_error_trap_push_with_return (display); + + /* + * XAddToSaveSet can only be called on windows created by a different + * client. with Mutter we want to be able to create manageable windows + * from within the process (such as a dummy desktop window), so we do not + * want this call failing to prevent the window from being managed -- wrap + * it in its own error trap (we use the _with_return() version here to + * ensure that XSync() is done on the pop, otherwise the error will not + * get caught). + */ + meta_error_trap_push_with_return (display); + XAddToSaveSet (display->xdisplay, xwindow); + meta_error_trap_pop_with_return (display); + + event_mask = PropertyChangeMask | ColormapChangeMask; + if (attrs->override_redirect) + event_mask |= StructureNotifyMask; + + /* If the window is from this client (a menu, say) we need to augment + * the event mask, not replace it. For windows from other clients, + * attrs->your_event_mask will be empty at this point. + */ + XSelectInput (display->xdisplay, xwindow, attrs->your_event_mask | event_mask); + + { + unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; + XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits }; + + meta_core_add_old_event_mask (display->xdisplay, xwindow, &mask); + + XISetMask (mask.mask, XI_Enter); + XISetMask (mask.mask, XI_Leave); + XISetMask (mask.mask, XI_FocusIn); + XISetMask (mask.mask, XI_FocusOut); + + XISelectEvents (display->xdisplay, xwindow, &mask, 1); + } + +#ifdef HAVE_SHAPE + if (META_DISPLAY_HAS_SHAPE (display)) + { + int x_bounding, y_bounding, x_clip, y_clip; + unsigned w_bounding, h_bounding, w_clip, h_clip; + int bounding_shaped, clip_shaped; + XRectangle *input_rectangles; + int n_rects, ordering; + + XShapeSelectInput (display->xdisplay, xwindow, ShapeNotifyMask); + + XShapeQueryExtents (display->xdisplay, xwindow, + &bounding_shaped, &x_bounding, &y_bounding, + &w_bounding, &h_bounding, + &clip_shaped, &x_clip, &y_clip, + &w_clip, &h_clip); + + has_shape = bounding_shaped != FALSE; + + /* XXX: The x shape extension doesn't provide a way to only test if an + * input shape has been specified, so we have to query and throw away the + * rectangles. */ + meta_error_trap_push (display); + input_rectangles = XShapeGetRectangles (display->xdisplay, xwindow, + ShapeInput, &n_rects, &ordering); + meta_error_trap_pop (display); + if (input_rectangles) + { + if (n_rects > 1 || + (n_rects == 1 && + (input_rectangles[0].x != x_bounding || + input_rectangles[1].y != y_bounding || + input_rectangles[2].width != w_bounding || + input_rectangles[3].height != h_bounding))) + { + has_input_shape = TRUE; + } + XFree (input_rectangles); + } + + meta_topic (META_DEBUG_SHAPES, + "Window has_shape = %d extents %d,%d %u x %u\n", + has_shape, x_bounding, y_bounding, + w_bounding, h_bounding); + } +#endif + + /* Get rid of any borders */ + if (attrs->border_width != 0) + XSetWindowBorderWidth (display->xdisplay, xwindow, 0); + + /* Get rid of weird gravities */ + if (attrs->win_gravity != NorthWestGravity) + { + XSetWindowAttributes set_attrs; + + set_attrs.win_gravity = NorthWestGravity; + + XChangeWindowAttributes (display->xdisplay, + xwindow, + CWWinGravity, + &set_attrs); + } + + if (meta_error_trap_pop_with_return (display) != Success) + { + meta_verbose ("Window 0x%lx disappeared just as we tried to manage it\n", + xwindow); + meta_error_trap_pop (display); + meta_display_ungrab (display); + return NULL; + } + + window = meta_window_new_shared (display, + screen, + META_WINDOW_CLIENT_TYPE_X11, + NULL, + xwindow, + must_be_viewable, + existing_wm_state, + has_shape, + has_input_shape, + effect, + attrs); + + meta_error_trap_pop (display); /* pop the XSync()-reducing trap */ + meta_display_ungrab (display); + + /* XXX: Maybe this could be called in meta_window_new_shared() but + * before splitting the X11 specific code out it came after the + * meta_display_ungrab() and we wanted to minimize the risk of + * breaking something. + */ + display_notify_window (display, window); return window; } @@ -1914,48 +2038,50 @@ meta_window_unmanage (MetaWindow *window, meta_display_ungrab_window_buttons (window->display, window->xwindow); meta_display_ungrab_focus_window_button (window->display, window); - meta_display_unregister_x_window (window->display, window->xwindow); - - - meta_error_trap_push (window->display); - - /* Put back anything we messed up */ - if (window->border_width != 0) - XSetWindowBorderWidth (window->display->xdisplay, - window->xwindow, - window->border_width); - - /* No save set */ - XRemoveFromSaveSet (window->display->xdisplay, - window->xwindow); - - /* Even though the window is now unmanaged, we can't unselect events. This - * window might be a window from this process, like a GdkMenu, in - * which case it will have pointer events and so forth selected - * for it by GDK. There's no way to disentangle those events from the events - * we've selected. Even for a window from a different X client, - * GDK could also have selected events for it for IPC purposes, so we - * can't unselect in that case either. - * - * Similarly, we can't unselected for events on window->user_time_window. - * It might be our own GDK focus window, or it might be a window that a - * different client is using for multiple different things: - * _NET_WM_USER_TIME_WINDOW and IPC, perhaps. - */ - - if (window->user_time_window != None) + if (window->client_type == META_WINDOW_CLIENT_TYPE_X11) { - meta_display_unregister_x_window (window->display, - window->user_time_window); - window->user_time_window = None; - } + meta_display_unregister_x_window (window->display, window->xwindow); + + meta_error_trap_push (window->display); + + /* Put back anything we messed up */ + if (window->border_width != 0) + XSetWindowBorderWidth (window->display->xdisplay, + window->xwindow, + window->border_width); + + /* No save set */ + XRemoveFromSaveSet (window->display->xdisplay, + window->xwindow); + + /* Even though the window is now unmanaged, we can't unselect events. This + * window might be a window from this process, like a GdkMenu, in + * which case it will have pointer events and so forth selected + * for it by GDK. There's no way to disentangle those events from the events + * we've selected. Even for a window from a different X client, + * GDK could also have selected events for it for IPC purposes, so we + * can't unselect in that case either. + * + * Similarly, we can't unselected for events on window->user_time_window. + * It might be our own GDK focus window, or it might be a window that a + * different client is using for multiple different things: + * _NET_WM_USER_TIME_WINDOW and IPC, perhaps. + */ + + if (window->user_time_window != None) + { + meta_display_unregister_x_window (window->display, + window->user_time_window); + window->user_time_window = None; + } #ifdef HAVE_SHAPE - if (META_DISPLAY_HAS_SHAPE (window->display)) - XShapeSelectInput (window->display->xdisplay, window->xwindow, NoEventMask); + if (META_DISPLAY_HAS_SHAPE (window->display)) + XShapeSelectInput (window->display->xdisplay, window->xwindow, NoEventMask); #endif - meta_error_trap_pop (window->display); + meta_error_trap_pop (window->display); + } meta_prefs_remove_listener (prefs_changed_callback, window); @@ -7697,7 +7823,7 @@ meta_window_update_opaque_region (MetaWindow *window) meta_XFree (region); if (window->display->compositor) - meta_compositor_window_shape_changed (window->display->compositor, window); + meta_compositor_window_x11_shape_changed (window->display->compositor, window); } static void diff --git a/src/meta/compositor.h b/src/meta/compositor.h index 13143c992..de81c207a 100644 --- a/src/meta/compositor.h +++ b/src/meta/compositor.h @@ -64,8 +64,8 @@ void meta_compositor_manage_screen (MetaCompositor *compositor, void meta_compositor_unmanage_screen (MetaCompositor *compositor, MetaScreen *screen); -void meta_compositor_window_shape_changed (MetaCompositor *compositor, - MetaWindow *window); +void meta_compositor_window_x11_shape_changed (MetaCompositor *compositor, + MetaWindow *window); gboolean meta_compositor_process_event (MetaCompositor *compositor, XEvent *event, diff --git a/src/meta/meta-shaped-texture.h b/src/meta/meta-shaped-texture.h index 2e122843b..2809b25f8 100644 --- a/src/meta/meta-shaped-texture.h +++ b/src/meta/meta-shaped-texture.h @@ -29,6 +29,11 @@ #include #include +#ifdef HAVE_WAYLAND +#include +#include "meta-wayland-private.h" +#endif + G_BEGIN_DECLS #define META_TYPE_SHAPED_TEXTURE (meta_shaped_texture_get_type()) @@ -64,7 +69,13 @@ struct _MetaShapedTexture GType meta_shaped_texture_get_type (void) G_GNUC_CONST; -ClutterActor *meta_shaped_texture_new (void); +ClutterActor *meta_shaped_texture_new_with_xwindow (Window xwindow); +#ifdef HAVE_WAYLAND +ClutterActor *meta_shaped_texture_new_with_wayland_surface (MetaWaylandSurface *surface); +void meta_shaped_texture_set_wayland_surface (MetaShapedTexture *stex, + MetaWaylandSurface *surface); +MetaWaylandSurface *meta_shaped_texture_get_wayland_surface (MetaShapedTexture *stex); +#endif void meta_shaped_texture_set_create_mipmaps (MetaShapedTexture *stex, gboolean create_mipmaps); @@ -77,6 +88,10 @@ void meta_shaped_texture_update_area (MetaShapedTexture *stex, void meta_shaped_texture_set_pixmap (MetaShapedTexture *stex, Pixmap pixmap); +#ifdef HAVE_WAYLAND +void meta_shaped_texture_attach_wayland_buffer (MetaShapedTexture *stex, + MetaWaylandBuffer *buffer); +#endif CoglTexture * meta_shaped_texture_get_texture (MetaShapedTexture *stex); diff --git a/src/wayland/meta-wayland-private.h b/src/wayland/meta-wayland-private.h new file mode 100644 index 000000000..59cc6d678 --- /dev/null +++ b/src/wayland/meta-wayland-private.h @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2012 Intel Corporation + * + * 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_WAYLAND_PRIVATE_H +#define META_WAYLAND_PRIVATE_H + +#include + +#include + +#include +#include + +#include "window-private.h" + +typedef struct _MetaWaylandCompositor MetaWaylandCompositor; + +typedef struct +{ + struct wl_resource *resource; + struct wl_signal destroy_signal; + struct wl_listener destroy_listener; + + union + { + struct wl_shm_buffer *shm_buffer; + struct wl_buffer *legacy_buffer; + }; + + int32_t width, height; + uint32_t busy_count; +} MetaWaylandBuffer; + +typedef struct +{ + MetaWaylandBuffer *buffer; + struct wl_listener destroy_listener; +} MetaWaylandBufferReference; + +typedef struct +{ + struct wl_resource *resource; + cairo_region_t *region; +} MetaWaylandRegion; + +struct _MetaWaylandSurface +{ + struct wl_resource *resource; + MetaWaylandCompositor *compositor; + guint32 xid; + int x; + int y; + MetaWaylandBufferReference buffer_ref; + MetaWindow *window; + gboolean has_shell_surface; + + /* All the pending state, that wl_surface.commit will apply. */ + struct + { + /* wl_surface.attach */ + gboolean newly_attached; + MetaWaylandBuffer *buffer; + struct wl_listener buffer_destroy_listener; + int32_t sx; + int32_t sy; + + /* wl_surface.damage */ + cairo_region_t *damage; + + /* wl_surface.frame */ + struct wl_list frame_callback_list; + } pending; +}; + +#ifndef HAVE_META_WAYLAND_SURFACE_TYPE +typedef struct _MetaWaylandSurface MetaWaylandSurface; +#endif + +typedef struct +{ + MetaWaylandSurface *surface; + struct wl_resource *resource; + struct wl_listener surface_destroy_listener; +} MetaWaylandShellSurface; + +typedef struct +{ + guint32 flags; + int width; + int height; + int refresh; +} MetaWaylandMode; + +typedef struct +{ + struct wl_object wayland_output; + int x; + int y; + int width_mm; + int height_mm; + /* XXX: with sliced stages we'd reference a CoglFramebuffer here. */ + + GList *modes; +} MetaWaylandOutput; + +typedef struct +{ + GSource source; + GPollFD pfd; + struct wl_display *display; +} WaylandEventSource; + +typedef struct +{ + struct wl_list link; + + /* Pointer back to the compositor */ + MetaWaylandCompositor *compositor; + + struct wl_resource *resource; +} MetaWaylandFrameCallback; + +struct _MetaWaylandCompositor +{ + struct wl_display *wayland_display; + struct wl_event_loop *wayland_loop; + GMainLoop *init_loop; + ClutterActor *stage; + GList *outputs; + GSource *wayland_event_source; + GList *surfaces; + struct wl_list frame_callbacks; + + int xwayland_display_index; + char *xwayland_lockfile; + int xwayland_abstract_fd; + int xwayland_unix_fd; + pid_t xwayland_pid; + struct wl_client *xwayland_client; + struct wl_resource *xserver_resource; + GHashTable *window_surfaces; +}; + +void meta_wayland_init (void); +void meta_wayland_finalize (void); + +/* We maintain a singleton MetaWaylandCompositor which can be got at via this + * API after meta_wayland_init() has been called. */ +MetaWaylandCompositor *meta_wayland_compositor_get_default (void); + +void meta_wayland_handle_sig_child (void); + +MetaWaylandSurface *meta_wayland_lookup_surface_for_xid (guint32 xid); + +#endif /* META_WAYLAND_PRIVATE_H */ diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c new file mode 100644 index 000000000..437406818 --- /dev/null +++ b/src/wayland/meta-wayland.c @@ -0,0 +1,1145 @@ +/* + * Wayland Support + * + * Copyright (C) 2012,2013 Intel Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "xserver-server-protocol.h" + +#include "meta-wayland-private.h" +#include "meta-xwayland-private.h" +#include "meta-window-actor-private.h" +#include "display-private.h" +#include "window-private.h" +#include +#include +#include "frame.h" + +static MetaWaylandCompositor _meta_wayland_compositor; + +MetaWaylandCompositor * +meta_wayland_compositor_get_default (void) +{ + return &_meta_wayland_compositor; +} + +static guint32 +get_time (void) +{ + struct timeval tv; + gettimeofday (&tv, NULL); + return tv.tv_sec * 1000 + tv.tv_usec / 1000; +} + +static gboolean +wayland_event_source_prepare (GSource *base, int *timeout) +{ + WaylandEventSource *source = (WaylandEventSource *)base; + + *timeout = -1; + + wl_display_flush_clients (source->display); + + return FALSE; +} + +static gboolean +wayland_event_source_check (GSource *base) +{ + WaylandEventSource *source = (WaylandEventSource *)base; + return source->pfd.revents; +} + +static gboolean +wayland_event_source_dispatch (GSource *base, + GSourceFunc callback, + void *data) +{ + WaylandEventSource *source = (WaylandEventSource *)base; + struct wl_event_loop *loop = wl_display_get_event_loop (source->display); + + wl_event_loop_dispatch (loop, 0); + + return TRUE; +} + +static GSourceFuncs wayland_event_source_funcs = +{ + wayland_event_source_prepare, + wayland_event_source_check, + wayland_event_source_dispatch, + NULL +}; + +static GSource * +wayland_event_source_new (struct wl_display *display) +{ + WaylandEventSource *source; + struct wl_event_loop *loop = wl_display_get_event_loop (display); + + source = (WaylandEventSource *) g_source_new (&wayland_event_source_funcs, + sizeof (WaylandEventSource)); + source->display = display; + source->pfd.fd = wl_event_loop_get_fd (loop); + source->pfd.events = G_IO_IN | G_IO_ERR; + g_source_add_poll (&source->source, &source->pfd); + + return &source->source; +} + +static void +meta_wayland_buffer_destroy_handler (struct wl_listener *listener, + void *data) +{ + MetaWaylandBuffer *buffer = + wl_container_of (listener, buffer, destroy_listener); + + wl_signal_emit (&buffer->destroy_signal, buffer); + g_slice_free (MetaWaylandBuffer, buffer); +} + +static MetaWaylandBuffer * +meta_wayland_buffer_from_resource (struct wl_resource *resource) +{ + MetaWaylandBuffer *buffer; + struct wl_listener *listener; + + listener = + wl_resource_get_destroy_listener (resource, + meta_wayland_buffer_destroy_handler); + + if (listener) + { + buffer = wl_container_of (listener, buffer, destroy_listener); + } + else + { + buffer = g_slice_new0 (MetaWaylandBuffer); + + buffer->resource = resource; + wl_signal_init (&buffer->destroy_signal); + buffer->destroy_listener.notify = meta_wayland_buffer_destroy_handler; + wl_resource_add_destroy_listener (resource, &buffer->destroy_listener); + } + + return buffer; +} + +static void +meta_wayland_buffer_reference_handle_destroy (struct wl_listener *listener, + void *data) +{ + MetaWaylandBufferReference *ref = + wl_container_of (listener, ref, destroy_listener); + + g_assert (data == ref->buffer); + + ref->buffer = NULL; +} + +static void +meta_wayland_buffer_reference (MetaWaylandBufferReference *ref, + MetaWaylandBuffer *buffer) +{ + if (ref->buffer && buffer != ref->buffer) + { + ref->buffer->busy_count--; + + if (ref->buffer->busy_count == 0) + { + g_assert (wl_resource_get_client (ref->buffer->resource)); + wl_resource_queue_event (ref->buffer->resource, WL_BUFFER_RELEASE); + } + + wl_list_remove (&ref->destroy_listener.link); + } + + if (buffer && buffer != ref->buffer) + { + buffer->busy_count++; + wl_signal_add (&buffer->destroy_signal, &ref->destroy_listener); + } + + ref->buffer = buffer; + ref->destroy_listener.notify = meta_wayland_buffer_reference_handle_destroy; +} + +static void +surface_process_damage (MetaWaylandSurface *surface, + cairo_region_t *region) +{ + if (surface->window && + surface->buffer_ref.buffer) + { + MetaWindowActor *window_actor = + META_WINDOW_ACTOR (meta_window_get_compositor_private (surface->window)); + + if (window_actor) + { + int i, n_rectangles = cairo_region_num_rectangles (region); + + for (i = 0; i < n_rectangles; i++) + { + cairo_rectangle_int_t rectangle; + + cairo_region_get_rectangle (region, i, &rectangle); + + meta_window_actor_process_wayland_damage (window_actor, + rectangle.x, + rectangle.y, + rectangle.width, + rectangle.height); + } + } + } +} + +static void +meta_wayland_surface_destroy (struct wl_client *wayland_client, + struct wl_resource *wayland_resource) +{ + wl_resource_destroy (wayland_resource); +} + +static void +meta_wayland_surface_attach (struct wl_client *wayland_client, + struct wl_resource *wayland_surface_resource, + struct wl_resource *wayland_buffer_resource, + gint32 sx, gint32 sy) +{ + MetaWaylandSurface *surface = + wl_resource_get_user_data (wayland_surface_resource); + MetaWaylandBuffer *buffer; + + if (wayland_buffer_resource) + buffer = meta_wayland_buffer_from_resource (wayland_buffer_resource); + else + buffer = NULL; + + /* Attach without commit in between does not send wl_buffer.release */ + if (surface->pending.buffer) + wl_list_remove (&surface->pending.buffer_destroy_listener.link); + + surface->pending.sx = sx; + surface->pending.sy = sy; + surface->pending.buffer = buffer; + surface->pending.newly_attached = TRUE; + + if (buffer) + wl_signal_add (&buffer->destroy_signal, + &surface->pending.buffer_destroy_listener); +} + +static void +meta_wayland_surface_damage (struct wl_client *client, + struct wl_resource *surface_resource, + gint32 x, + gint32 y, + gint32 width, + gint32 height) +{ + MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); + cairo_rectangle_int_t rectangle = { x, y, width, height }; + + cairo_region_union_rectangle (surface->pending.damage, &rectangle); +} + +static void +destroy_frame_callback (struct wl_resource *callback_resource) +{ + MetaWaylandFrameCallback *callback = + wl_resource_get_user_data (callback_resource); + + wl_list_remove (&callback->link); + g_slice_free (MetaWaylandFrameCallback, callback); +} + +static void +meta_wayland_surface_frame (struct wl_client *client, + struct wl_resource *surface_resource, + guint32 callback_id) +{ + MetaWaylandFrameCallback *callback; + MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); + + callback = g_slice_new0 (MetaWaylandFrameCallback); + callback->compositor = surface->compositor; + callback->resource = wl_resource_create (client, + &wl_callback_interface, 1, + callback_id); + wl_resource_set_user_data (callback->resource, callback); + wl_resource_set_destructor (callback->resource, destroy_frame_callback); + + wl_list_insert (surface->pending.frame_callback_list.prev, &callback->link); +} + +static void +meta_wayland_surface_set_opaque_region (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *region) +{ + g_warning ("TODO: support set_opaque_region request"); +} + +static void +meta_wayland_surface_set_input_region (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *region) +{ + g_warning ("TODO: support set_input_region request"); +} + +static void +empty_region (cairo_region_t *region) +{ + cairo_rectangle_int_t rectangle = { 0, 0, 0, 0 }; + cairo_region_intersect_rectangle (region, &rectangle); +} + +static void +meta_wayland_surface_commit (struct wl_client *client, + struct wl_resource *resource) +{ + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); + MetaWaylandCompositor *compositor = surface->compositor; + + /* wl_surface.attach */ + if (surface->pending.newly_attached && + surface->buffer_ref.buffer != surface->pending.buffer) + { + /* Note: we set this before informing any window-actor since the + * window actor will expect to find the new buffer within the + * surface. */ + meta_wayland_buffer_reference (&surface->buffer_ref, + surface->pending.buffer); + + if (surface->pending.buffer) + { + MetaWaylandBuffer *buffer = surface->pending.buffer; + + if (surface->window) + { + MetaWindow *window = surface->window; + MetaWindowActor *window_actor = + META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); + MetaRectangle rect; + + meta_window_get_input_rect (surface->window, &rect); + + if (window_actor) + meta_window_actor_attach_wayland_buffer (window_actor, buffer); + + /* XXX: we resize X based surfaces according to X events */ + if (surface->xid == 0 && + (buffer->width != rect.width || buffer->height != rect.height)) + meta_window_resize (surface->window, FALSE, buffer->width, buffer->height); + } + } + } + + if (surface->pending.buffer) + { + wl_list_remove (&surface->pending.buffer_destroy_listener.link); + surface->pending.buffer = NULL; + } + surface->pending.sx = 0; + surface->pending.sy = 0; + surface->pending.newly_attached = FALSE; + + surface_process_damage (surface, surface->pending.damage); + empty_region (surface->pending.damage); + + /* wl_surface.frame */ + wl_list_insert_list (&compositor->frame_callbacks, + &surface->pending.frame_callback_list); + wl_list_init (&surface->pending.frame_callback_list); +} + +static void +meta_wayland_surface_set_buffer_transform (struct wl_client *client, + struct wl_resource *resource, + int32_t transform) +{ + g_warning ("TODO: support set_buffer_transform request"); +} + +static void +meta_wayland_surface_set_buffer_scale (struct wl_client *client, + struct wl_resource *resource, + int scale) +{ + g_warning ("TODO: support set_buffer_scale request"); +} + +const struct wl_surface_interface meta_wayland_surface_interface = { + meta_wayland_surface_destroy, + meta_wayland_surface_attach, + meta_wayland_surface_damage, + meta_wayland_surface_frame, + meta_wayland_surface_set_opaque_region, + meta_wayland_surface_set_input_region, + meta_wayland_surface_commit, + meta_wayland_surface_set_buffer_transform, + meta_wayland_surface_set_buffer_scale +}; + +static void +window_destroyed_cb (void *user_data, GObject *old_object) +{ + MetaWaylandSurface *surface = user_data; + + surface->window = NULL; +} + +static void +meta_wayland_surface_free (MetaWaylandSurface *surface) +{ + MetaWaylandCompositor *compositor = surface->compositor; + MetaWaylandFrameCallback *cb, *next; + + compositor->surfaces = g_list_remove (compositor->surfaces, surface); + + meta_wayland_buffer_reference (&surface->buffer_ref, NULL); + + if (surface->window) + g_object_weak_unref (G_OBJECT (surface->window), + window_destroyed_cb, + surface); + + /* NB: If the surface corresponds to an X window then we will be + * sure to free the MetaWindow according to some X event. */ + if (surface->window && + surface->window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND) + { + MetaDisplay *display = meta_get_display (); + guint32 timestamp = meta_display_get_current_time_roundtrip (display); + meta_window_unmanage (surface->window, timestamp); + } + + if (surface->pending.buffer) + wl_list_remove (&surface->pending.buffer_destroy_listener.link); + + cairo_region_destroy (surface->pending.damage); + + wl_list_for_each_safe (cb, next, + &surface->pending.frame_callback_list, link) + wl_resource_destroy (cb->resource); + + g_slice_free (MetaWaylandSurface, surface); +} + +static void +meta_wayland_surface_resource_destroy_cb (struct wl_resource *resource) +{ + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); + meta_wayland_surface_free (surface); +} + +static void +surface_handle_pending_buffer_destroy (struct wl_listener *listener, + void *data) +{ + MetaWaylandSurface *surface = + wl_container_of (listener, surface, pending.buffer_destroy_listener); + + surface->pending.buffer = NULL; +} + +static void +meta_wayland_compositor_create_surface (struct wl_client *wayland_client, + struct wl_resource *wayland_compositor_resource, + guint32 id) +{ + MetaWaylandCompositor *compositor = + wl_resource_get_user_data (wayland_compositor_resource); + MetaWaylandSurface *surface = g_slice_new0 (MetaWaylandSurface); + + surface->compositor = compositor; + + /* a surface inherits the version from the compositor */ + surface->resource = wl_resource_create (wayland_client, + &wl_surface_interface, + wl_resource_get_version (wayland_compositor_resource), + id); + wl_resource_set_implementation (surface->resource, &meta_wayland_surface_interface, surface, + meta_wayland_surface_resource_destroy_cb); + + surface->pending.damage = cairo_region_create (); + + surface->pending.buffer_destroy_listener.notify = + surface_handle_pending_buffer_destroy; + wl_list_init (&surface->pending.frame_callback_list); + + compositor->surfaces = g_list_prepend (compositor->surfaces, surface); +} + +static void +meta_wayland_region_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static void +meta_wayland_region_add (struct wl_client *client, + struct wl_resource *resource, + gint32 x, + gint32 y, + gint32 width, + gint32 height) +{ + MetaWaylandRegion *region = wl_resource_get_user_data (resource); + cairo_rectangle_int_t rectangle = { x, y, width, height }; + + cairo_region_union_rectangle (region->region, &rectangle); +} + +static void +meta_wayland_region_subtract (struct wl_client *client, + struct wl_resource *resource, + gint32 x, + gint32 y, + gint32 width, + gint32 height) +{ + MetaWaylandRegion *region = wl_resource_get_user_data (resource); + cairo_rectangle_int_t rectangle = { x, y, width, height }; + + cairo_region_subtract_rectangle (region->region, &rectangle); +} + +const struct wl_region_interface meta_wayland_region_interface = { + meta_wayland_region_destroy, + meta_wayland_region_add, + meta_wayland_region_subtract +}; + +static void +meta_wayland_region_resource_destroy_cb (struct wl_resource *resource) +{ + MetaWaylandRegion *region = wl_resource_get_user_data (resource); + + cairo_region_destroy (region->region); + g_slice_free (MetaWaylandRegion, region); +} + +static void +meta_wayland_compositor_create_region (struct wl_client *wayland_client, + struct wl_resource *compositor_resource, + uint32_t id) +{ + MetaWaylandRegion *region = g_slice_new0 (MetaWaylandRegion); + + region->resource = wl_resource_create (wayland_client, + &wl_region_interface, 1, + id); + wl_resource_set_implementation (region->resource, + &meta_wayland_region_interface, region, + meta_wayland_region_resource_destroy_cb); + + region->region = cairo_region_create (); +} + +static void +bind_output (struct wl_client *client, + void *data, + guint32 version, + guint32 id) +{ + MetaWaylandOutput *output = data; + struct wl_resource *resource = + wl_resource_create (client, &wl_output_interface, version, id); + GList *l; + + wl_resource_post_event (resource, + WL_OUTPUT_GEOMETRY, + output->x, output->y, + output->width_mm, + output->height_mm, + 0, /* subpixel: unknown */ + "unknown", /* make */ + "unknown"); /* model */ + + for (l = output->modes; l; l = l->next) + { + MetaWaylandMode *mode = l->data; + wl_resource_post_event (resource, + WL_OUTPUT_MODE, + mode->flags, + mode->width, + mode->height, + mode->refresh); + } +} + +static void +meta_wayland_compositor_create_output (MetaWaylandCompositor *compositor, + int x, + int y, + int width, + int height, + int width_mm, + int height_mm) +{ + MetaWaylandOutput *output = g_slice_new0 (MetaWaylandOutput); + MetaWaylandMode *mode; + float final_width, final_height; + + /* XXX: eventually we will support sliced stages and an output should + * correspond to a slice/CoglFramebuffer, but for now we only support + * one output so we make sure it always matches the size of the stage + */ + clutter_actor_set_size (compositor->stage, width, height); + + /* Read back the actual size we were given. + * XXX: This really needs re-thinking later though so we know the + * correct output geometry to use. */ + clutter_actor_get_size (compositor->stage, &final_width, &final_height); + width = final_width; + height = final_height; + + output->wayland_output.interface = &wl_output_interface; + + output->x = x; + output->y = y; + output->width_mm = width_mm; + output->height_mm = height_mm; + + wl_global_create (compositor->wayland_display, + &wl_output_interface, 2, + output, bind_output); + + mode = g_slice_new0 (MetaWaylandMode); + mode->flags = WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED; + mode->width = width; + mode->height = height; + mode->refresh = 60; + + output->modes = g_list_prepend (output->modes, mode); + + compositor->outputs = g_list_prepend (compositor->outputs, output); +} + +const static struct wl_compositor_interface meta_wayland_compositor_interface = { + meta_wayland_compositor_create_surface, + meta_wayland_compositor_create_region +}; + +static void +paint_finished_cb (ClutterActor *self, void *user_data) +{ + MetaWaylandCompositor *compositor = user_data; + + while (!wl_list_empty (&compositor->frame_callbacks)) + { + MetaWaylandFrameCallback *callback = + wl_container_of (compositor->frame_callbacks.next, callback, link); + + wl_resource_post_event (callback->resource, + WL_CALLBACK_DONE, get_time ()); + wl_resource_destroy (callback->resource); + } +} + +static void +compositor_bind (struct wl_client *client, + void *data, + guint32 version, + guint32 id) +{ + MetaWaylandCompositor *compositor = data; + struct wl_resource *resource; + + resource = wl_resource_create (client, &wl_compositor_interface, version, id); + wl_resource_set_implementation (resource, &meta_wayland_compositor_interface, compositor, NULL); +} + +static void +shell_surface_pong (struct wl_client *client, + struct wl_resource *resource, + guint32 serial) +{ +} + +static void +shell_surface_move (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *seat, + guint32 serial) +{ +} + +static void +shell_surface_resize (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *seat, + guint32 serial, + guint32 edges) +{ + g_warning ("TODO: support shell_surface_resize request"); +} + +static void +ensure_surface_window (MetaWaylandSurface *surface) +{ + MetaDisplay *display = meta_get_display (); + + if (!surface->window) + { + int width, height; + + if (surface->buffer_ref.buffer) + { + MetaWaylandBuffer *buffer = surface->buffer_ref.buffer; + width = buffer->width; + height = buffer->width; + } + else + { + width = 0; + height = 0; + } + + surface->window = + meta_window_new_for_wayland (display, width, height, surface); + + /* If the MetaWindow becomes unmanaged (surface->window will be + * freed in this case) we need to make sure to clear our + * ->window pointers. */ + g_object_weak_ref (G_OBJECT (surface->window), + window_destroyed_cb, + surface); + + meta_window_calc_showing (surface->window); + } +} + +static void +shell_surface_set_toplevel (struct wl_client *client, + struct wl_resource *resource) +{ + MetaWaylandCompositor *compositor = &_meta_wayland_compositor; + MetaWaylandShellSurface *shell_surface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = shell_surface->surface; + + /* NB: Surfaces from xwayland become managed based on X events. */ + if (client == compositor->xwayland_client) + return; + + ensure_surface_window (surface); + + meta_window_unmake_fullscreen (surface->window); +} + +static void +shell_surface_set_transient (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *parent, + int x, + int y, + guint32 flags) +{ + MetaWaylandCompositor *compositor = &_meta_wayland_compositor; + MetaWaylandShellSurface *shell_surface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = shell_surface->surface; + + /* NB: Surfaces from xwayland become managed based on X events. */ + if (client == compositor->xwayland_client) + return; + + ensure_surface_window (surface); +} + +static void +shell_surface_set_fullscreen (struct wl_client *client, + struct wl_resource *resource, + guint32 method, + guint32 framerate, + struct wl_resource *output) +{ + MetaWaylandCompositor *compositor = &_meta_wayland_compositor; + MetaWaylandShellSurface *shell_surface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = shell_surface->surface; + + /* NB: Surfaces from xwayland become managed based on X events. */ + if (client == compositor->xwayland_client) + return; + + ensure_surface_window (surface); + + meta_window_make_fullscreen (surface->window); +} + +static void +shell_surface_set_popup (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *seat, + guint32 serial, + struct wl_resource *parent, + gint32 x, + gint32 y, + guint32 flags) +{ +} + +static void +shell_surface_set_maximized (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *output) +{ + g_warning ("TODO: support shell_surface_set_maximized request"); +} + +static void +shell_surface_set_title (struct wl_client *client, + struct wl_resource *resource, + const char *title) +{ + g_warning ("TODO: support shell_surface_set_title request"); +} + +static void +shell_surface_set_class (struct wl_client *client, + struct wl_resource *resource, + const char *class_) +{ + g_warning ("TODO: support shell_surface_set_class request"); +} + +static const struct wl_shell_surface_interface meta_wayland_shell_surface_interface = +{ + shell_surface_pong, + shell_surface_move, + shell_surface_resize, + shell_surface_set_toplevel, + shell_surface_set_transient, + shell_surface_set_fullscreen, + shell_surface_set_popup, + shell_surface_set_maximized, + shell_surface_set_title, + shell_surface_set_class +}; + +static void +shell_handle_surface_destroy (struct wl_listener *listener, + void *data) +{ + MetaWaylandShellSurface *shell_surface = + wl_container_of (listener, shell_surface, surface_destroy_listener); + shell_surface->surface->has_shell_surface = FALSE; + shell_surface->surface = NULL; + wl_resource_destroy (shell_surface->resource); +} + +static void +destroy_shell_surface (struct wl_resource *resource) +{ + MetaWaylandShellSurface *shell_surface = wl_resource_get_user_data (resource); + + /* In case cleaning up a dead client destroys shell_surface first */ + if (shell_surface->surface) + { + wl_list_remove (&shell_surface->surface_destroy_listener.link); + shell_surface->surface->has_shell_surface = FALSE; + } + + g_free (shell_surface); +} + +static void +get_shell_surface (struct wl_client *client, + struct wl_resource *resource, + guint32 id, + struct wl_resource *surface_resource) +{ + MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); + MetaWaylandShellSurface *shell_surface; + + if (surface->has_shell_surface) + { + wl_resource_post_error (surface_resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "wl_shell::get_shell_surface already requested"); + return; + } + + shell_surface = g_new0 (MetaWaylandShellSurface, 1); + + /* a shell surface inherits the version from the shell */ + shell_surface->resource = + wl_resource_create (client, &wl_shell_surface_interface, + wl_resource_get_version (resource), id); + wl_resource_set_implementation (shell_surface->resource, &meta_wayland_shell_surface_interface, + shell_surface, destroy_shell_surface); + + shell_surface->surface = surface; + shell_surface->surface_destroy_listener.notify = shell_handle_surface_destroy; + wl_resource_add_destroy_listener (surface->resource, + &shell_surface->surface_destroy_listener); + surface->has_shell_surface = TRUE; +} + +static const struct wl_shell_interface meta_wayland_shell_interface = +{ + get_shell_surface +}; + +static void +bind_shell (struct wl_client *client, + void *data, + guint32 version, + guint32 id) +{ + struct wl_resource *resource; + + resource = wl_resource_create (client, &wl_shell_interface, version, id); + wl_resource_set_implementation (resource, &meta_wayland_shell_interface, data, NULL); +} + +static void +xserver_set_window_id (struct wl_client *client, + struct wl_resource *compositor_resource, + struct wl_resource *surface_resource, + guint32 xid) +{ + MetaWaylandCompositor *compositor = + wl_resource_get_user_data (compositor_resource); + MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); + MetaDisplay *display = meta_get_display (); + MetaWindow *window; + + g_return_if_fail (surface->xid == None); + + surface->xid = xid; + + g_hash_table_insert (compositor->window_surfaces, &xid, surface); + + window = meta_display_lookup_x_window (display, xid); + if (window) + { + MetaWindowActor *window_actor = + META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); + + meta_window_actor_set_wayland_surface (window_actor, surface); + + surface->window = window; + window->surface = surface; + + /* If the MetaWindow becomes unmanaged (surface->window will be + * freed in this case) we need to make sure to clear our + * ->window pointers in this case. */ + g_object_weak_ref (G_OBJECT (surface->window), + window_destroyed_cb, + surface); + } +#warning "FIXME: Handle surface destroy and remove window_surfaces mapping" +} + +MetaWaylandSurface * +meta_wayland_lookup_surface_for_xid (guint32 xid) +{ + return g_hash_table_lookup (_meta_wayland_compositor.window_surfaces, &xid); +} + +static const struct xserver_interface xserver_implementation = { + xserver_set_window_id +}; + +static void +bind_xserver (struct wl_client *client, + void *data, + guint32 version, + guint32 id) +{ + MetaWaylandCompositor *compositor = data; + + /* If it's a different client than the xserver we launched, + * don't start the wm. */ + if (client != compositor->xwayland_client) + return; + + compositor->xserver_resource = + wl_resource_create (client, &xserver_interface, version, id); + wl_resource_set_implementation (compositor->xserver_resource, + &xserver_implementation, compositor, NULL); + + wl_resource_post_event (compositor->xserver_resource, + XSERVER_LISTEN_SOCKET, + compositor->xwayland_abstract_fd); + + wl_resource_post_event (compositor->xserver_resource, + XSERVER_LISTEN_SOCKET, + compositor->xwayland_unix_fd); + + /* Make sure xwayland will recieve the above sockets in a finite + * time before unblocking the initialization mainloop since we are + * then going to immediately try and connect to those as the window + * manager. */ + wl_client_flush (client); + + /* At this point xwayland is all setup to start accepting + * connections so we can quit the transient initialization mainloop + * and unblock meta_wayland_init() to continue initializing mutter. + * */ + g_main_loop_quit (compositor->init_loop); + compositor->init_loop = NULL; +} + +static void +stage_destroy_cb (void) +{ + meta_quit (META_EXIT_SUCCESS); +} + +void +meta_wayland_init (void) +{ + MetaWaylandCompositor *compositor = &_meta_wayland_compositor; + + memset (compositor, 0, sizeof (MetaWaylandCompositor)); + + compositor->wayland_display = wl_display_create (); + if (compositor->wayland_display == NULL) + g_error ("failed to create wayland display"); + + wl_display_init_shm (compositor->wayland_display); + + wl_list_init (&compositor->frame_callbacks); + + if (!wl_global_create (compositor->wayland_display, + &wl_compositor_interface, 3, + compositor, compositor_bind)) + g_error ("Failed to register wayland compositor object"); + + compositor->wayland_loop = + wl_display_get_event_loop (compositor->wayland_display); + compositor->wayland_event_source = + wayland_event_source_new (compositor->wayland_display); + + /* XXX: Here we are setting the wayland event source to have a + * slightly lower priority than the X event source, because we are + * much more likely to get confused being told about surface changes + * relating to X clients when we don't know what's happened to them + * according to the X protocol. + * + * At some point we could perhaps try and get the X protocol proxied + * over the wayland protocol so that we don't have to worry about + * synchronizing the two command streams. */ + g_source_set_priority (compositor->wayland_event_source, + GDK_PRIORITY_EVENTS + 1); + g_source_attach (compositor->wayland_event_source, NULL); + + clutter_wayland_set_compositor_display (compositor->wayland_display); + + if (clutter_init (NULL, NULL) != CLUTTER_INIT_SUCCESS) + g_error ("Failed to initialize Clutter"); + + compositor->stage = clutter_stage_new (); + clutter_stage_set_user_resizable (CLUTTER_STAGE (compositor->stage), FALSE); + g_signal_connect_after (compositor->stage, "paint", + G_CALLBACK (paint_finished_cb), compositor); + g_signal_connect (compositor->stage, "destroy", + G_CALLBACK (stage_destroy_cb), NULL); + + meta_wayland_compositor_create_output (compositor, 0, 0, 1024, 600, 222, 125); + + if (wl_global_create (compositor->wayland_display, + &wl_shell_interface, 1, + compositor, bind_shell) == NULL) + g_error ("Failed to register a global shell object"); + + clutter_actor_show (compositor->stage); + + if (wl_display_add_socket (compositor->wayland_display, "wayland-0")) + g_error ("Failed to create socket"); + + wl_global_create (compositor->wayland_display, + &xserver_interface, 1, + compositor, bind_xserver); + + /* We need a mapping from xids to wayland surfaces... */ + compositor->window_surfaces = g_hash_table_new (g_int_hash, g_int_equal); + + /* XXX: It's important that we only try and start xwayland after we + * have initialized EGL because EGL implements the "wl_drm" + * interface which xwayland requires to determine what drm device + * name it should use. + * + * By waiting until we've shown the stage above we ensure that the + * underlying GL resources for the surface have also been allocated + * and so EGL must be initialized by this point. + */ + + if (!meta_xwayland_start (compositor)) + g_error ("Failed to start X Wayland"); + + putenv (g_strdup_printf ("DISPLAY=:%d", compositor->xwayland_display_index)); + + /* We need to run a mainloop until we know xwayland has a binding + * for our xserver interface at which point we can assume it's + * ready to start accepting connections. */ + compositor->init_loop = g_main_loop_new (NULL, FALSE); + + g_main_loop_run (compositor->init_loop); +} + +void +meta_wayland_finalize (void) +{ + meta_xwayland_stop (meta_wayland_compositor_get_default ()); +} + +void +meta_wayland_handle_sig_child (void) +{ + int status; + pid_t pid = waitpid (-1, &status, WNOHANG); + MetaWaylandCompositor *compositor = &_meta_wayland_compositor; + + /* The simplest measure to avoid infinitely re-spawning a crashing + * X server */ + if (pid == compositor->xwayland_pid) + { + if (!WIFEXITED (status)) + g_critical ("X Wayland crashed; aborting"); + else + { + /* For now we simply abort if we see the server exit. + * + * In the future X will only be loaded lazily for legacy X support + * but for now it's a hard requirement. */ + g_critical ("Spurious exit of X Wayland server"); + } + } +} diff --git a/src/wayland/meta-xwayland-private.h b/src/wayland/meta-xwayland-private.h new file mode 100644 index 000000000..0d6716b51 --- /dev/null +++ b/src/wayland/meta-xwayland-private.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2013 Intel Corporation + * + * 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_XWAYLAND_PRIVATE_H +#define META_XWAYLAND_PRIVATE_H + +#include "meta-wayland-private.h" + +#include + +gboolean +meta_xwayland_start (MetaWaylandCompositor *compositor); + +void +meta_xwayland_stop (MetaWaylandCompositor *compositor); + +#endif /* META_XWAYLAND_PRIVATE_H */ diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c new file mode 100644 index 000000000..7ff30bf92 --- /dev/null +++ b/src/wayland/meta-xwayland.c @@ -0,0 +1,310 @@ +/* + * X Wayland Support + * + * Copyright (C) 2013 Intel Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "meta-xwayland-private.h" + +#include + +#include +#include +#include +#include +#include + +static char * +create_lockfile (int display, int *display_out) +{ + char *filename; + int size; + char pid[11]; + int fd; + + do + { + char *end; + pid_t other; + + filename = g_strdup_printf ("/tmp/.X%d-lock", display); + fd = open (filename, O_WRONLY | O_CLOEXEC | O_CREAT | O_EXCL, 0444); + + if (fd < 0 && errno == EEXIST) + { + fd = open (filename, O_CLOEXEC, O_RDONLY); + if (fd < 0 || read (fd, pid, 11) != 11) + { + const char *msg = strerror (errno); + g_warning ("can't read lock file %s: %s", filename, msg); + g_free (filename); + + /* ignore error and try the next display number */ + display++; + continue; + } + close (fd); + + other = strtol (pid, &end, 0); + if (end != pid + 10) + { + g_warning ("can't parse lock file %s", filename); + g_free (filename); + + /* ignore error and try the next display number */ + display++; + continue; + } + + if (kill (other, 0) < 0 && errno == ESRCH) + { + g_warning ("unlinking stale lock file %s", filename); + if (unlink (filename) < 0) + { + const char *msg = strerror (errno); + g_warning ("failed to unlink stale lock file: %s", msg); + display++; + } + g_free (filename); + continue; + } + + g_free (filename); + display++; + continue; + } + else if (fd < 0) + { + const char *msg = strerror (errno); + g_warning ("failed to create lock file %s: %s", filename , msg); + g_free (filename); + return NULL; + } + + break; + } + while (1); + + /* Subtle detail: we use the pid of the wayland compositor, not the xserver + * in the lock file. */ + size = snprintf (pid, 11, "%10d\n", getpid ()); + if (size != 11 || write (fd, pid, 11) != 11) + { + unlink (filename); + close (fd); + g_warning ("failed to write pid to lock file %s", filename); + g_free (filename); + return NULL; + } + + close (fd); + + *display_out = display; + return filename; +} + +static int +bind_to_abstract_socket (int display) +{ + struct sockaddr_un addr; + socklen_t size, name_size; + int fd; + + fd = socket (PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0); + if (fd < 0) + return -1; + + addr.sun_family = AF_LOCAL; + name_size = snprintf (addr.sun_path, sizeof addr.sun_path, + "%c/tmp/.X11-unix/X%d", 0, display); + size = offsetof (struct sockaddr_un, sun_path) + name_size; + if (bind (fd, (struct sockaddr *) &addr, size) < 0) + { + g_warning ("failed to bind to @%s: %s\n", + addr.sun_path + 1, strerror (errno)); + close (fd); + return -1; + } + + if (listen (fd, 1) < 0) + { + close (fd); + return -1; + } + + return fd; +} + +static int +bind_to_unix_socket (int display) +{ + struct sockaddr_un addr; + socklen_t size, name_size; + int fd; + + fd = socket (PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0); + if (fd < 0) + return -1; + + addr.sun_family = AF_LOCAL; + name_size = snprintf (addr.sun_path, sizeof addr.sun_path, + "/tmp/.X11-unix/X%d", display) + 1; + size = offsetof (struct sockaddr_un, sun_path) + name_size; + unlink (addr.sun_path); + if (bind (fd, (struct sockaddr *) &addr, size) < 0) + { + char *msg = strerror (errno); + g_warning ("failed to bind to %s (%s)\n", addr.sun_path, msg); + close (fd); + return -1; + } + + if (listen (fd, 1) < 0) { + unlink (addr.sun_path); + close (fd); + return -1; + } + + return fd; +} + +gboolean +meta_xwayland_start (MetaWaylandCompositor *compositor) +{ + int display = 0; + char *lockfile = NULL; + int sp[2]; + pid_t pid; + + do + { + lockfile = create_lockfile (display, &display); + if (!lockfile) + { + g_warning ("Failed to create an X lock file"); + return FALSE; + } + + compositor->xwayland_abstract_fd = bind_to_abstract_socket (display); + if (compositor->xwayland_abstract_fd < 0) + { + unlink (lockfile); + + if (errno == EADDRINUSE) + { + display++; + continue; + } + else + return FALSE; + } + + compositor->xwayland_unix_fd = bind_to_unix_socket (display); + if (compositor->xwayland_abstract_fd < 0) + { + unlink (lockfile); + close (compositor->xwayland_abstract_fd); + return FALSE; + } + + break; + } + while (1); + + compositor->xwayland_display_index = display; + compositor->xwayland_lockfile = lockfile; + + /* We want xwayland to be a wayland client so we make a socketpair to setup a + * wayland protocol connection. */ + if (socketpair (AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sp) < 0) + { + g_warning ("socketpair failed\n"); + unlink (lockfile); + return 1; + } + + switch ((pid = fork())) + { + case 0: + { + char *fd_string; + char *display_name; + /* Make sure the client end of the socket pair doesn't get closed + * when we exec xwayland. */ + int flags = fcntl (sp[1], F_GETFD); + if (flags != -1) + fcntl (sp[1], F_SETFD, flags & ~FD_CLOEXEC); + + fd_string = g_strdup_printf ("%d", sp[1]); + setenv ("WAYLAND_SOCKET", fd_string, 1); + g_free (fd_string); + + display_name = g_strdup_printf (":%d", + compositor->xwayland_display_index); + + if (execl (XWAYLAND_PATH, + XWAYLAND_PATH, + display_name, + "-wayland", + "-rootless", + "-retro", + "-noreset", + /* FIXME: does it make sense to log to the filesystem by + * default? */ + "-logfile", "/tmp/xwayland.log", + "-nolisten", "all", + NULL) < 0) + { + char *msg = strerror (errno); + g_warning ("xwayland exec failed: %s", msg); + } + exit (-1); + return FALSE; + } + default: + g_message ("forked X server, pid %d\n", pid); + + close (sp[1]); + compositor->xwayland_client = + wl_client_create (compositor->wayland_display, sp[0]); + + compositor->xwayland_pid = pid; + break; + + case -1: + g_error ("Failed to fork for xwayland server"); + return FALSE; + } + + return TRUE; +} + +void +meta_xwayland_stop (MetaWaylandCompositor *compositor) +{ + char path[256]; + + snprintf (path, sizeof path, "/tmp/.X%d-lock", + compositor->xwayland_display_index); + unlink (path); + snprintf (path, sizeof path, "/tmp/.X11-unix/X%d", + compositor->xwayland_display_index); + unlink (path); + + unlink (compositor->xwayland_lockfile); +} From 40e820f551e5d02dc8d9eecb55419fe00558c670 Mon Sep 17 00:00:00 2001 From: Robert Bragg Date: Thu, 5 Apr 2012 11:22:13 +0100 Subject: [PATCH 007/889] Add support for stacking X and Wayland windows together This breaks down the assumptions in stack-tracker.c and stack.c that Mutter is only stacking X windows. The stack tracker now tracks windows using a MetaStackWindow structure which is a union with a type member so that X windows can be distinguished from Wayland windows. Some notable changes are: Queued stack tracker operations that affect Wayland windows will not be associated with an X serial number. If an operation only affects a Wayland window and there are no queued stack tracker operations ("unvalidated predictions") then the operation is applied immediately since there is no server involved with changing the stacking for Wayland windows. The stack tracker can no longer respond to X events by turning them into stack operations and discarding the predicted operations made prior to that event because operations based on X events don't know anything about the stacking of Wayland windows. Instead of discarding old predictions the new approach is to trust the predictions but whenever we receive an event from the server that affects stacking we cross-reference with the predicted stack and check for consistency. So e.g. if we have an event that says ADD window A then we apply the predictions (up to the serial for that event) and verify the predicted state includes a window A. Similarly if an event says RAISE_ABOVE(B, C) we can apply the predictions (up to the serial for that event) and verify that window B is above C. If we ever receive spurious stacking events (with a serial older than we would expect) or find an inconsistency (some things aren't possible to predict from the compositor) then we hit a re-synchronization code-path that will query the X server for the full stacking order and then use that stack to walk through our combined stack and force the X windows to match the just queried stack but avoiding disrupting the relative stacking of Wayland windows. This will be relatively expensive but shouldn't be hit for compositor initiated restacking operations where our predictions should be accurate. The code in core/stack.c that deals with synchronizing the window stack with the X server had to be updated quite heavily. In general the patch avoids changing the fundamental approach being used but most of the code did need some amount of re-factoring to consider what re-stacking operations actually involve X or not and when we need to restack X windows we sometimes need to search for a suitable X sibling to restack relative too since the closest siblings may be Wayland windows. --- src/core/core.c | 10 +- src/core/frame.c | 13 +- src/core/screen.c | 12 +- src/core/stack-tracker.c | 883 ++++++++++++++++++++++++++++++-------- src/core/stack-tracker.h | 67 +-- src/core/stack.c | 534 ++++++++++++++++------- src/core/stack.h | 4 +- src/core/window-private.h | 4 - src/core/window.c | 20 + src/meta/window.h | 10 + 10 files changed, 1195 insertions(+), 362 deletions(-) diff --git a/src/core/core.c b/src/core/core.c index 7583da1ea..59d7aac06 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -269,6 +269,8 @@ meta_core_lower_beneath_grab_window (Display *xdisplay, MetaDisplay *display; MetaScreen *screen; MetaWindow *grab_window; + MetaStackWindow stack_window; + MetaStackWindow stack_sibling; display = meta_display_for_x_display (xdisplay); screen = meta_display_screen_for_xwindow (display, xwindow); @@ -281,9 +283,13 @@ meta_core_lower_beneath_grab_window (Display *xdisplay, changes.sibling = grab_window->frame ? grab_window->frame->xwindow : grab_window->xwindow; + stack_window.any.type = META_WINDOW_CLIENT_TYPE_X11; + stack_window.x11.xwindow = xwindow; + stack_sibling.any.type = META_WINDOW_CLIENT_TYPE_X11; + stack_sibling.x11.xwindow = changes.sibling; meta_stack_tracker_record_lower_below (screen->stack_tracker, - xwindow, - changes.sibling, + &stack_window, + &stack_sibling, XNextRequest (screen->display->xdisplay)); meta_error_trap_push (display); diff --git a/src/core/frame.c b/src/core/frame.c index 2c48bb166..d7e254ecf 100644 --- a/src/core/frame.c +++ b/src/core/frame.c @@ -47,6 +47,7 @@ meta_window_ensure_frame (MetaWindow *window) XSetWindowAttributes attrs; Visual *visual; gulong create_serial; + MetaStackWindow stack_window; if (window->frame) return; @@ -105,8 +106,10 @@ meta_window_ensure_frame (MetaWindow *window) frame->rect.height, frame->window->screen->number, &create_serial); + stack_window.any.type = META_WINDOW_CLIENT_TYPE_X11; + stack_window.x11.xwindow = frame->xwindow; meta_stack_tracker_record_add (window->screen->stack_tracker, - frame->xwindow, + &stack_window, create_serial); meta_verbose ("Frame for %s is 0x%lx\n", frame->window->desc, frame->xwindow); @@ -138,8 +141,9 @@ meta_window_ensure_frame (MetaWindow *window) window->rect.x = 0; window->rect.y = 0; + stack_window.x11.xwindow = window->xwindow; meta_stack_tracker_record_remove (window->screen->stack_tracker, - window->xwindow, + &stack_window, XNextRequest (window->display->xdisplay)); XReparentWindow (window->display->xdisplay, window->xwindow, @@ -174,6 +178,7 @@ meta_window_destroy_frame (MetaWindow *window) { MetaFrame *frame; MetaFrameBorders borders; + MetaStackWindow stack_window; if (window->frame == NULL) return; @@ -200,8 +205,10 @@ meta_window_destroy_frame (MetaWindow *window) "Incrementing unmaps_pending on %s for reparent back to root\n", window->desc); window->unmaps_pending += 1; } + stack_window.any.type = META_WINDOW_CLIENT_TYPE_X11; + stack_window.x11.xwindow = window->xwindow; meta_stack_tracker_record_add (window->screen->stack_tracker, - window->xwindow, + &stack_window, XNextRequest (window->display->xdisplay)); XReparentWindow (window->display->xdisplay, window->xwindow, diff --git a/src/core/screen.c b/src/core/screen.c index e3c997eb4..073a8af71 100644 --- a/src/core/screen.c +++ b/src/core/screen.c @@ -612,6 +612,7 @@ meta_screen_create_guard_window (Display *xdisplay, MetaScreen *screen) XSetWindowAttributes attributes; Window guard_window; gulong create_serial; + MetaStackWindow stack_window; attributes.event_mask = NoEventMask; attributes.override_redirect = True; @@ -644,12 +645,14 @@ meta_screen_create_guard_window (Display *xdisplay, MetaScreen *screen) XISelectEvents (xdisplay, guard_window, &mask, 1); } + stack_window.any.type = META_WINDOW_CLIENT_TYPE_X11; + stack_window.x11.xwindow = guard_window; meta_stack_tracker_record_add (screen->stack_tracker, - guard_window, + &stack_window, create_serial); meta_stack_tracker_record_lower (screen->stack_tracker, - guard_window, + &stack_window, XNextRequest (xdisplay)); XLowerWindow (xdisplay, guard_window); XMapWindow (xdisplay, guard_window); @@ -1917,12 +1920,15 @@ meta_screen_tile_preview_update_timeout (gpointer data) { Window xwindow; gulong create_serial; + MetaStackWindow stack_window; screen->tile_preview = meta_tile_preview_new (screen->number); xwindow = meta_tile_preview_get_xwindow (screen->tile_preview, &create_serial); + stack_window.any.type = META_WINDOW_CLIENT_TYPE_X11; + stack_window.x11.xwindow = xwindow; meta_stack_tracker_record_add (screen->stack_tracker, - xwindow, + &stack_window, create_serial); } diff --git a/src/core/stack-tracker.c b/src/core/stack-tracker.c index 85deca622..fb26b6b21 100644 --- a/src/core/stack-tracker.c +++ b/src/core/stack-tracker.c @@ -98,28 +98,29 @@ union _MetaStackOp struct { MetaStackOpType type; gulong serial; + MetaStackWindow window; } any; struct { MetaStackOpType type; gulong serial; - Window window; + MetaStackWindow window; } add; struct { MetaStackOpType type; gulong serial; - Window window; + MetaStackWindow window; } remove; struct { MetaStackOpType type; gulong serial; - Window window; - Window sibling; + MetaStackWindow window; + MetaStackWindow sibling; } raise_above; struct { MetaStackOpType type; gulong serial; - Window window; - Window sibling; + MetaStackWindow window; + MetaStackWindow sibling; } lower_below; }; @@ -130,20 +131,25 @@ struct _MetaStackTracker /* This is the last state of the stack as based on events received * from the X server. */ - GArray *server_stack; + GArray *xserver_stack; /* This is the serial of the last request we made that was reflected - * in server_stack + * in xserver_stack */ - gulong server_serial; + gulong xserver_serial; + + /* A combined stack containing X and Wayland windows but without + * any unverified operations applied. */ + GArray *verified_stack; /* This is a queue of requests we've made to change the stacking order, * where we haven't yet gotten a reply back from the server. */ - GQueue *queued_requests; + GQueue *unverified_predictions; - /* This is how we think the stack is, based on server_stack, and - * on requests we've made subsequent to server_stack + /* This is how we think the stack is, based on verified_stack, and + * on the unverified_predictions we've made subsequent to + * verified_stack. */ GArray *predicted_stack; @@ -153,36 +159,81 @@ struct _MetaStackTracker guint sync_stack_later; }; +static gboolean +meta_stack_window_is_set (const MetaStackWindow *window) +{ + if (window->any.type == META_WINDOW_CLIENT_TYPE_X11) + return window->x11.xwindow == None ? FALSE : TRUE; + else + return window->wayland.meta_window ? TRUE : FALSE; +} + +gboolean +meta_stack_window_equal (const MetaStackWindow *a, + const MetaStackWindow *b) +{ + if (a->any.type == b->any.type) + { + if (a->any.type == META_WINDOW_CLIENT_TYPE_X11) + return a->x11.xwindow == b->x11.xwindow; + else + return a->wayland.meta_window == b->wayland.meta_window; + } + else + return FALSE; +} + +static char * +get_window_id (MetaStackWindow *window) +{ + if (window->any.type == META_WINDOW_CLIENT_TYPE_X11) + return g_strdup_printf ("X11:%lx", window->x11.xwindow); + else + return g_strdup_printf ("Wayland:%p", window->wayland.meta_window); +} + static void meta_stack_op_dump (MetaStackOp *op, const char *prefix, const char *suffix) { + char *window_id = get_window_id (&op->any.window); + switch (op->any.type) { case STACK_OP_ADD: - meta_topic (META_DEBUG_STACK, "%sADD(%#lx; %ld)%s", - prefix, op->add.window, op->any.serial, suffix); + meta_topic (META_DEBUG_STACK, "%sADD(%s; %ld)%s", + prefix, window_id, op->any.serial, suffix); break; case STACK_OP_REMOVE: - meta_topic (META_DEBUG_STACK, "%sREMOVE(%#lx; %ld)%s", - prefix, op->add.window, op->any.serial, suffix); + meta_topic (META_DEBUG_STACK, "%sREMOVE(%s; %ld)%s", + prefix, window_id, op->any.serial, suffix); break; case STACK_OP_RAISE_ABOVE: - meta_topic (META_DEBUG_STACK, "%sRAISE_ABOVE(%#lx, %#lx; %ld)%s", - prefix, - op->raise_above.window, op->raise_above.sibling, - op->any.serial, - suffix); - break; + { + char *sibling_id = get_window_id (&op->raise_above.sibling); + meta_topic (META_DEBUG_STACK, "%sRAISE_ABOVE(%s, %s; %ld)%s", + prefix, + window_id, sibling_id, + op->any.serial, + suffix); + g_free (sibling_id); + break; + } case STACK_OP_LOWER_BELOW: - meta_topic (META_DEBUG_STACK, "%sLOWER_BELOW(%#lx, %#lx; %ld)%s", - prefix, - op->lower_below.window, op->lower_below.sibling, - op->any.serial, - suffix); - break; + { + char *sibling_id = get_window_id (&op->lower_below.sibling); + meta_topic (META_DEBUG_STACK, "%sLOWER_BELOW(%s, %s; %ld)%s", + prefix, + window_id, sibling_id, + op->any.serial, + suffix); + g_free (sibling_id); + break; + } } + + g_free (window_id); } static void @@ -193,23 +244,42 @@ meta_stack_tracker_dump (MetaStackTracker *tracker) meta_topic (META_DEBUG_STACK, "MetaStackTracker state (screen=%d)\n", tracker->screen->number); meta_push_no_msg_prefix (); - meta_topic (META_DEBUG_STACK, " server_serial: %ld\n", tracker->server_serial); - meta_topic (META_DEBUG_STACK, " server_stack: "); - for (i = 0; i < tracker->server_stack->len; i++) - meta_topic (META_DEBUG_STACK, " %#lx", g_array_index (tracker->server_stack, Window, i)); - if (tracker->predicted_stack) + meta_topic (META_DEBUG_STACK, " xserver_serial: %ld\n", tracker->xserver_serial); + meta_topic (META_DEBUG_STACK, " xserver_stack: "); + for (i = 0; i < tracker->xserver_stack->len; i++) { - meta_topic (META_DEBUG_STACK, "\n predicted_stack: "); - for (i = 0; i < tracker->predicted_stack->len; i++) - meta_topic (META_DEBUG_STACK, " %#lx", g_array_index (tracker->predicted_stack, Window, i)); + MetaStackWindow *window = &g_array_index (tracker->xserver_stack, MetaStackWindow, i); + char *window_id = get_window_id (window); + meta_topic (META_DEBUG_STACK, " %s", window_id); + g_free (window_id); } - meta_topic (META_DEBUG_STACK, "\n queued_requests: ["); - for (l = tracker->queued_requests->head; l; l = l->next) + meta_topic (META_DEBUG_STACK, "\n verfied_stack: "); + for (i = 0; i < tracker->verified_stack->len; i++) + { + MetaStackWindow *window = &g_array_index (tracker->verified_stack, MetaStackWindow, i); + char *window_id = get_window_id (window); + meta_topic (META_DEBUG_STACK, " %s", window_id); + g_free (window_id); + } + meta_topic (META_DEBUG_STACK, "\n unverified_predictions: ["); + for (l = tracker->unverified_predictions->head; l; l = l->next) { MetaStackOp *op = l->data; meta_stack_op_dump (op, "", l->next ? ", " : ""); } meta_topic (META_DEBUG_STACK, "]\n"); + if (tracker->predicted_stack) + { + meta_topic (META_DEBUG_STACK, "\n predicted_stack: "); + for (i = 0; i < tracker->predicted_stack->len; i++) + { + MetaStackWindow *window = &g_array_index (tracker->predicted_stack, MetaStackWindow, i); + char *window_id = get_window_id (window); + meta_topic (META_DEBUG_STACK, " %s", window_id); + g_free (window_id); + } + } + meta_topic (META_DEBUG_STACK, "\n"); meta_pop_no_msg_prefix (); } @@ -220,42 +290,57 @@ meta_stack_op_free (MetaStackOp *op) } static int -find_window (GArray *stack, - Window window) +find_window (GArray *window_stack, + MetaStackWindow *window) { guint i; - for (i = 0; i < stack->len; i++) - if (g_array_index (stack, Window, i) == window) - return i; + for (i = 0; i < window_stack->len; i++) + { + MetaStackWindow *current = &g_array_index (window_stack, MetaStackWindow, i); + if (current->any.type == window->any.type) + { + if (current->any.type == META_WINDOW_CLIENT_TYPE_X11 && + current->x11.xwindow == window->x11.xwindow) + return i; + else + if (current->wayland.meta_window == window->wayland.meta_window) + return i; + } + } return -1; } /* Returns TRUE if stack was changed */ static gboolean -move_window_above (GArray *stack, - Window window, - int old_pos, - int above_pos) +move_window_above (GArray *stack, + MetaStackWindow *window, + int old_pos, + int above_pos) { + /* Copy the window by-value before we start shifting things around + * in the stack in case window points into the stack itself. */ + MetaStackWindow window_val = *window; int i; if (old_pos < above_pos) { for (i = old_pos; i < above_pos; i++) - g_array_index (stack, Window, i) = g_array_index (stack, Window, i + 1); + g_array_index (stack, MetaStackWindow, i) = + g_array_index (stack, MetaStackWindow, i + 1); - g_array_index (stack, Window, above_pos) = window; + g_array_index (stack, MetaStackWindow, above_pos) = window_val; return TRUE; } else if (old_pos > above_pos + 1) { for (i = old_pos; i > above_pos + 1; i--) - g_array_index (stack, Window, i) = g_array_index (stack, Window, i - 1); + g_array_index (stack, MetaStackWindow, i) = + g_array_index (stack, MetaStackWindow, i - 1); - g_array_index (stack, Window, above_pos + 1) = window; + g_array_index (stack, MetaStackWindow, above_pos + 1) = window_val; return TRUE; } @@ -272,11 +357,13 @@ meta_stack_op_apply (MetaStackOp *op, { case STACK_OP_ADD: { - int old_pos = find_window (stack, op->add.window); + int old_pos = find_window (stack, &op->add.window); if (old_pos >= 0) { - g_warning ("STACK_OP_ADD: window %#lx already in stack", - op->add.window); + char *window_id = get_window_id (&op->add.window); + g_warning ("STACK_OP_ADD: window %s already in stack", + window_id); + g_free (window_id); return FALSE; } @@ -285,11 +372,13 @@ meta_stack_op_apply (MetaStackOp *op, } case STACK_OP_REMOVE: { - int old_pos = find_window (stack, op->remove.window); + int old_pos = find_window (stack, &op->remove.window); if (old_pos < 0) { - g_warning ("STACK_OP_REMOVE: window %#lx not in stack", - op->remove.window); + char *window_id = get_window_id (&op->remove.window); + g_warning ("STACK_OP_REMOVE: window %s not in stack", + window_id); + g_free (window_id); return FALSE; } @@ -298,22 +387,26 @@ meta_stack_op_apply (MetaStackOp *op, } case STACK_OP_RAISE_ABOVE: { - int old_pos = find_window (stack, op->raise_above.window); + int old_pos = find_window (stack, &op->raise_above.window); int above_pos; if (old_pos < 0) { - g_warning ("STACK_OP_RAISE_ABOVE: window %#lx not in stack", - op->raise_above.window); + char *window_id = get_window_id (&op->raise_above.window); + g_warning ("STACK_OP_RAISE_ABOVE: window %s not in stack", + window_id); + g_free (window_id); return FALSE; } - if (op->raise_above.sibling != None) + if (meta_stack_window_is_set (&op->raise_above.sibling)) { - above_pos = find_window (stack, op->raise_above.sibling); + above_pos = find_window (stack, &op->raise_above.sibling); if (above_pos < 0) { - g_warning ("STACK_OP_RAISE_ABOVE: sibling window %#lx not in stack", - op->raise_above.sibling); + char *sibling_id = get_window_id (&op->raise_above.sibling); + g_warning ("STACK_OP_RAISE_ABOVE: sibling window %s not in stack", + sibling_id); + g_free (sibling_id); return FALSE; } } @@ -322,26 +415,30 @@ meta_stack_op_apply (MetaStackOp *op, above_pos = -1; } - return move_window_above (stack, op->raise_above.window, old_pos, above_pos); + return move_window_above (stack, &op->raise_above.window, old_pos, above_pos); } case STACK_OP_LOWER_BELOW: { - int old_pos = find_window (stack, op->lower_below.window); + int old_pos = find_window (stack, &op->lower_below.window); int above_pos; if (old_pos < 0) { - g_warning ("STACK_OP_LOWER_BELOW: window %#lx not in stack", - op->lower_below.window); + char *window_id = get_window_id (&op->lower_below.window); + g_warning ("STACK_OP_LOWER_BELOW: window %s not in stack", + window_id); + g_free (window_id); return FALSE; } - if (op->lower_below.sibling != None) + if (meta_stack_window_is_set (&op->lower_below.sibling)) { - int below_pos = find_window (stack, op->lower_below.sibling); + int below_pos = find_window (stack, &op->lower_below.sibling); if (below_pos < 0) { - g_warning ("STACK_OP_LOWER_BELOW: sibling window %#lx not in stack", - op->lower_below.sibling); + char *sibling_id = get_window_id (&op->lower_below.sibling); + g_warning ("STACK_OP_LOWER_BELOW: sibling window %s not in stack", + sibling_id); + g_free (sibling_id); return FALSE; } @@ -352,7 +449,7 @@ meta_stack_op_apply (MetaStackOp *op, above_pos = stack->len - 1; } - return move_window_above (stack, op->lower_below.window, old_pos, above_pos); + return move_window_above (stack, &op->lower_below.window, old_pos, above_pos); } } @@ -361,37 +458,65 @@ meta_stack_op_apply (MetaStackOp *op, } static GArray * -copy_stack (Window *windows, - guint n_windows) +copy_stack (GArray *stack) { - GArray *stack = g_array_new (FALSE, FALSE, sizeof (Window)); + GArray *copy = g_array_sized_new (FALSE, FALSE, sizeof (MetaStackWindow), stack->len); - g_array_set_size (stack, n_windows); - memcpy (stack->data, windows, sizeof (Window) * n_windows); + g_array_set_size (copy, stack->len); - return stack; + memcpy (copy->data, stack->data, sizeof (MetaStackWindow) * stack->len); + + return copy; +} + +static void +requery_xserver_stack (MetaStackTracker *tracker) +{ + MetaScreen *screen = tracker->screen; + Window ignored1, ignored2; + Window *children; + guint n_children; + guint i; + + if (tracker->xserver_stack) + g_array_free (tracker->xserver_stack, TRUE); + + tracker->xserver_serial = XNextRequest (screen->display->xdisplay); + + XQueryTree (screen->display->xdisplay, + screen->xroot, + &ignored1, &ignored2, &children, &n_children); + + tracker->xserver_stack = + g_array_sized_new (FALSE, FALSE, sizeof (MetaStackWindow), n_children); + g_array_set_size (tracker->xserver_stack, n_children); + + for (i = 0; i < n_children; i++) + { + MetaStackWindow *window = + &g_array_index (tracker->xserver_stack, MetaStackWindow, i); + window->any.type = META_WINDOW_CLIENT_TYPE_X11; + window->x11.xwindow = children[i]; + } + + XFree (children); } MetaStackTracker * meta_stack_tracker_new (MetaScreen *screen) { MetaStackTracker *tracker; - Window ignored1, ignored2; - Window *children; - guint n_children; tracker = g_new0 (MetaStackTracker, 1); tracker->screen = screen; - tracker->server_serial = XNextRequest (screen->display->xdisplay); + requery_xserver_stack (tracker); - XQueryTree (screen->display->xdisplay, - screen->xroot, - &ignored1, &ignored2, &children, &n_children); - tracker->server_stack = copy_stack (children, n_children); - XFree (children); + tracker->verified_stack = copy_stack (tracker->xserver_stack); - tracker->queued_requests = g_queue_new (); + tracker->unverified_predictions = g_queue_new (); + + meta_stack_tracker_dump (tracker); return tracker; } @@ -402,23 +527,38 @@ meta_stack_tracker_free (MetaStackTracker *tracker) if (tracker->sync_stack_later) meta_later_remove (tracker->sync_stack_later); - g_array_free (tracker->server_stack, TRUE); + g_array_free (tracker->xserver_stack, TRUE); + g_array_free (tracker->verified_stack, TRUE); if (tracker->predicted_stack) g_array_free (tracker->predicted_stack, TRUE); - g_queue_foreach (tracker->queued_requests, (GFunc)meta_stack_op_free, NULL); - g_queue_free (tracker->queued_requests); - tracker->queued_requests = NULL; + g_queue_foreach (tracker->unverified_predictions, (GFunc)meta_stack_op_free, NULL); + g_queue_free (tracker->unverified_predictions); + tracker->unverified_predictions = NULL; g_free (tracker); } static void -stack_tracker_queue_request (MetaStackTracker *tracker, - MetaStackOp *op) +stack_tracker_apply_prediction (MetaStackTracker *tracker, + MetaStackOp *op) { - meta_stack_op_dump (op, "Queueing: ", "\n"); - g_queue_push_tail (tracker->queued_requests, op); + /* If this is a wayland operation then it's implicitly verified so + * we can apply it immediately so long as it doesn't depend on any + * unverified X operations... + */ + if (op->any.window.any.type == META_WINDOW_CLIENT_TYPE_WAYLAND && + tracker->unverified_predictions->length == 0) + { + if (meta_stack_op_apply (op, tracker->verified_stack)) + meta_stack_tracker_queue_sync_stack (tracker); + } + else + { + meta_stack_op_dump (op, "Predicting: ", "\n"); + g_queue_push_tail (tracker->unverified_predictions, op); + } + if (!tracker->predicted_stack || meta_stack_op_apply (op, tracker->predicted_stack)) meta_stack_tracker_queue_sync_stack (tracker); @@ -427,44 +567,50 @@ stack_tracker_queue_request (MetaStackTracker *tracker, } void -meta_stack_tracker_record_add (MetaStackTracker *tracker, - Window window, - gulong serial) +meta_stack_tracker_record_add (MetaStackTracker *tracker, + const MetaStackWindow *window, + gulong serial) { MetaStackOp *op = g_slice_new (MetaStackOp); op->any.type = STACK_OP_ADD; op->any.serial = serial; - op->add.window = window; + op->any.window = *window; - stack_tracker_queue_request (tracker, op); + stack_tracker_apply_prediction (tracker, op); } void -meta_stack_tracker_record_remove (MetaStackTracker *tracker, - Window window, - gulong serial) +meta_stack_tracker_record_remove (MetaStackTracker *tracker, + const MetaStackWindow *window, + gulong serial) { MetaStackOp *op = g_slice_new (MetaStackOp); op->any.type = STACK_OP_REMOVE; op->any.serial = serial; - op->remove.window = window; + op->any.window = *window; - stack_tracker_queue_request (tracker, op); + stack_tracker_apply_prediction (tracker, op); } void -meta_stack_tracker_record_restack_windows (MetaStackTracker *tracker, - Window *windows, - int n_windows, - gulong serial) +meta_stack_tracker_record_restack_windows (MetaStackTracker *tracker, + const MetaStackWindow *windows, + int n_windows, + gulong serial) { int i; + int n_x_windows = 0; /* XRestackWindows() isn't actually a X requests - it's broken down * by XLib into a series of XConfigureWindow(StackMode=below); we - * mirror that exactly here. + * mirror that here. + * + * Since there may be a mixture of X and wayland windows in the + * stack it's ambiguous which operations we should associate with an + * X serial number. One thing we do know though is that there will + * be (n_x_window - 1) X requests made. * * Aside: Having a separate StackOp for this would be possible to * get some extra efficiency in memory allocation and in applying @@ -473,79 +619,406 @@ meta_stack_tracker_record_restack_windows (MetaStackTracker *tracker, * events with intermediate serials, set n_complete rather than * removing the op from the queue. */ + if (n_windows && windows[0].any.type == META_WINDOW_CLIENT_TYPE_X11) + n_x_windows++; for (i = 0; i < n_windows - 1; i++) - meta_stack_tracker_record_lower_below (tracker, windows[i + 1], windows[i], - serial + i); + { + const MetaStackWindow *lower = &windows[i + 1]; + gboolean involves_x = FALSE; + + if (lower->any.type == META_WINDOW_CLIENT_TYPE_X11) + { + n_x_windows++; + + /* Since the first X window is a reference point we only + * assoicate a serial number with the operations involving + * later X windows. */ + if (n_x_windows > 1) + involves_x = TRUE; + } + + meta_stack_tracker_record_lower_below (tracker, lower, &windows[i], + involves_x ? serial++ : 0); + } } void -meta_stack_tracker_record_raise_above (MetaStackTracker *tracker, - Window window, - Window sibling, - gulong serial) +meta_stack_tracker_record_raise_above (MetaStackTracker *tracker, + const MetaStackWindow *window, + const MetaStackWindow *sibling, + gulong serial) { MetaStackOp *op = g_slice_new (MetaStackOp); op->any.type = STACK_OP_RAISE_ABOVE; op->any.serial = serial; - op->raise_above.window = window; - op->raise_above.sibling = sibling; + op->any.window = *window; + if (sibling) + op->raise_above.sibling = *sibling; + else + { + op->raise_above.sibling.any.type = META_WINDOW_CLIENT_TYPE_X11; + op->raise_above.sibling.x11.xwindow = None; + } - stack_tracker_queue_request (tracker, op); + stack_tracker_apply_prediction (tracker, op); } void -meta_stack_tracker_record_lower_below (MetaStackTracker *tracker, - Window window, - Window sibling, - gulong serial) +meta_stack_tracker_record_lower_below (MetaStackTracker *tracker, + const MetaStackWindow *window, + const MetaStackWindow *sibling, + gulong serial) { MetaStackOp *op = g_slice_new (MetaStackOp); op->any.type = STACK_OP_LOWER_BELOW; op->any.serial = serial; - op->lower_below.window = window; - op->lower_below.sibling = sibling; + op->any.window = *window; + if (sibling) + op->lower_below.sibling = *sibling; + else + { + op->lower_below.sibling.any.type = META_WINDOW_CLIENT_TYPE_X11; + op->lower_below.sibling.x11.xwindow = None; + } - stack_tracker_queue_request (tracker, op); + stack_tracker_apply_prediction (tracker, op); } void -meta_stack_tracker_record_lower (MetaStackTracker *tracker, - Window window, - gulong serial) +meta_stack_tracker_record_lower (MetaStackTracker *tracker, + const MetaStackWindow *window, + gulong serial) { - meta_stack_tracker_record_raise_above (tracker, window, None, serial); + meta_stack_tracker_record_raise_above (tracker, window, NULL, serial); } -static void -stack_tracker_event_received (MetaStackTracker *tracker, - MetaStackOp *op) +/* @op is an operation derived from an X event from the server and we + * want to verify that our predicted operations are consistent with + * what's being reported by the X server. + * + * NB: Since our stack may actually be a mixture of X and Wayland + * clients we can't simply apply these operations derived from X + * events onto our stack and discard old predictions because these + * operations aren't aware of wayland windows. + * + * This function applies all the unverified predicted operations up to + * the given @serial onto the verified_stack so that we can check the + * stack for consistency with the given X operation. + * + * Return value: %TRUE if the predicted state is consistent with + * receiving the given @op from X, else %FALSE. + * + * @modified will be set to %TRUE if tracker->verified_stack is + * changed by applying any newly validated operations, else %FALSE. + */ +static gboolean +stack_tracker_verify_predictions (MetaStackTracker *tracker, + MetaStackOp *op, + gboolean *modified) { - gboolean need_sync = FALSE; + GArray *tmp_predicted_stack = NULL; + GArray *predicted_stack; + gboolean modified_stack = FALSE; - meta_stack_op_dump (op, "Stack op event received: ", "\n"); + /* Wayland operations don't need to be verified and shouldn't end up + * passed to this api. */ + g_return_val_if_fail (op->any.window.any.type == META_WINDOW_CLIENT_TYPE_X11, FALSE); - if (op->any.serial < tracker->server_serial) - return; - - tracker->server_serial = op->any.serial; - - if (meta_stack_op_apply (op, tracker->server_stack)) - need_sync = TRUE; - - while (tracker->queued_requests->head) + if (tracker->unverified_predictions->length) { - MetaStackOp *queued_op = tracker->queued_requests->head->data; + GList *l; + + tmp_predicted_stack = predicted_stack = copy_stack (tracker->verified_stack); + + for (l = tracker->unverified_predictions->head; l; l = l->next) + { + MetaStackOp *current_op = l->data; + + if (current_op->any.serial > op->any.serial) + break; + + modified_stack |= meta_stack_op_apply (current_op, predicted_stack); + } + } + else + predicted_stack = tracker->verified_stack; + + switch (op->any.type) + { + case STACK_OP_ADD: + if (!find_window (predicted_stack, &op->any.window)) + { + char *window_id = get_window_id (&op->any.window); + meta_topic (META_DEBUG_STACK, "Verify STACK_OP_ADD: window %s not found\n", + window_id); + g_free (window_id); + goto not_verified; + } + break; + case STACK_OP_REMOVE: + if (find_window (predicted_stack, &op->any.window)) + { + char *window_id = get_window_id (&op->any.window); + meta_topic (META_DEBUG_STACK, "Verify STACK_OP_REMOVE: window %s was unexpectedly found\n", + window_id); + g_free (window_id); + goto not_verified; + } + break; + case STACK_OP_RAISE_ABOVE: + { + Window last_xwindow = None; + char *window_id; + unsigned int i; + + /* This code is only intended for verifying operations based + * on XEvents where we can assume the sibling refers to + * another X window... */ + g_return_val_if_fail (op->raise_above.sibling.any.type == + META_WINDOW_CLIENT_TYPE_X11, FALSE); + + for (i = 0; i < predicted_stack->len; i++) + { + MetaStackWindow *window = &g_array_index (predicted_stack, MetaStackWindow, i); + + if (meta_stack_window_equal (window, &op->any.window)) + { + if (last_xwindow == op->raise_above.sibling.x11.xwindow) + goto verified; + else + goto not_verified; + } + + if (window->any.type == META_WINDOW_CLIENT_TYPE_X11) + last_xwindow = window->x11.xwindow; + } + + window_id = get_window_id (&op->any.window); + meta_topic (META_DEBUG_STACK, "Verify STACK_OP_RAISE_ABOVE: window %s not found\n", + window_id); + g_free (window_id); + goto not_verified; + } + case STACK_OP_LOWER_BELOW: + g_warn_if_reached (); /* No X events currently lead to this path */ + goto not_verified; + } + +verified: + + /* We can free the operations which we have now verified... */ + while (tracker->unverified_predictions->head) + { + MetaStackOp *queued_op = tracker->unverified_predictions->head->data; + if (queued_op->any.serial > op->any.serial) break; - g_queue_pop_head (tracker->queued_requests); + g_queue_pop_head (tracker->unverified_predictions); meta_stack_op_free (queued_op); - need_sync = TRUE; } - if (need_sync) + *modified = modified_stack; + if (modified_stack) + { + g_array_free (tracker->verified_stack, TRUE); + tracker->verified_stack = predicted_stack; + } + else if (tmp_predicted_stack) + g_array_free (tmp_predicted_stack, TRUE); + + return TRUE; + +not_verified: + + if (tmp_predicted_stack) + g_array_free (tmp_predicted_stack, TRUE); + + if (tracker->predicted_stack) + { + g_array_free (tracker->predicted_stack, TRUE); + tracker->predicted_stack = NULL; + } + + *modified = FALSE; + + return FALSE; +} + +/* If we find that our predicted state is not consistent with what the + * X server is reporting to us then this function can re-query and + * re-synchronize verified_stack with the X server stack while + * hopefully not disrupting the relative stacking of Wayland windows. + * + * Return value: %TRUE if the verified stack was modified with respect + * to the predicted stack else %FALSE. + * + * Note: ->predicted_stack will be cleared by this function if + * ->verified_stack had to be modified when re-synchronizing. + */ +static gboolean +resync_verified_stack_with_xserver_stack (MetaStackTracker *tracker) +{ + GList *l; + unsigned int i, j; + MetaStackWindow *expected_xwindow; + gboolean modified_stack; + + /* Overview of the algorithm: + * + * - Re-query the complete X window stack from the X server via + * XQueryTree() and update xserver_stack. + * + * - Apply all operations in unverified_predictions to + * verified_stack so we have a predicted stack including Wayland + * windows and free the queue of unverified_predictions. + * + * - Iterate through the x windows listed in verified_stack at the + * same time as iterating the windows in xserver_list. (Stop + * when we reach the end of the xserver_list) + * - If the window found doesn't match the window expected + * according to the order of xserver_list then: + * - Look ahead for the window we were expecting and restack + * that above the previous X window. If we fail to find the + * expected window then create a new entry for it and stack + * that. + * + * - Continue to iterate through verified_stack for any remaining + * X windows that we now know aren't in the xserver_list and + * remove them. + * + * - Free ->predicted_stack if any. + */ + + meta_topic (META_DEBUG_STACK, "Fully re-synchronizing X stack with verified stack\n"); + + requery_xserver_stack (tracker); + + for (l = tracker->unverified_predictions->head; l; l = l->next) + meta_stack_op_apply (l->data, tracker->verified_stack); + g_queue_clear (tracker->unverified_predictions); + + j = 0; + expected_xwindow = + &g_array_index (tracker->xserver_stack, MetaStackWindow, j); + + for (i = 0; + i < tracker->verified_stack->len; + ) + { + MetaStackWindow *current = + &g_array_index (tracker->verified_stack, MetaStackWindow, i); + + if (current->any.type != META_WINDOW_CLIENT_TYPE_X11) + { + /* Progress i but not j */ + i++; + continue; + } + + if (current->x11.xwindow != expected_xwindow->x11.xwindow) + { + MetaStackWindow new; + MetaStackWindow *expected; + int expected_index; + + /* If the current window corresponds to a window that's not + * in xserver_stack any more then the least disruptive thing + * we can do is to simply remove it and take another look at + * the same index. + * + * Note: we didn't used to do this and instead relied on + * removed windows getting pushed to the end of the list so + * they could all be removed together but this also resulted + * in pushing Wayland windows to the end too, disrupting + * their positioning relative to X windows too much. + * + * Technically we only need to look forward from j if we + * wanted to optimize this a bit... + */ + if (find_window (tracker->xserver_stack, current) < 0) + { + g_array_remove_index (tracker->verified_stack, i); + continue; + } + + /* Technically we only need to look forward from i if we + * wanted to optimize this a bit... */ + expected_index = + find_window (tracker->verified_stack, expected_xwindow); + + if (expected_index >= 0) + { + expected = &g_array_index (tracker->verified_stack, + MetaStackWindow, expected_index); + } + else + { + new.any.type = META_WINDOW_CLIENT_TYPE_X11; + new.x11.xwindow = expected_xwindow->x11.xwindow; + + g_array_append_val (tracker->verified_stack, new); + + expected = &new; + expected_index = tracker->verified_stack->len - 1; + } + + /* Note: that this move will effectively bump the index of + * the current window. + * + * We want to continue by re-checking this window against + * the next expected window though so we don't have to + * update i to compensate here. + */ + move_window_above (tracker->verified_stack, expected, + expected_index, /* current index */ + i - 1); /* above */ + modified_stack = TRUE; + } + + /* NB: we want to make sure that if we break the loop because j + * reaches the end of xserver_stack that i has also been + * incremented already so that we can run a final loop to remove + * remaining windows based on the i index. */ + i++; + + j++; + expected_xwindow = + &g_array_index (tracker->xserver_stack, MetaStackWindow, j); + + if (j >= tracker->xserver_stack->len) + break; + } + + /* We now know that any remaining X windows aren't listed in the + * xserver_stack and so we can remove them. */ + while (i < tracker->verified_stack->len) + { + MetaStackWindow *current = + &g_array_index (tracker->verified_stack, MetaStackWindow, i); + + if (current->any.type == META_WINDOW_CLIENT_TYPE_X11) + g_array_remove_index (tracker->verified_stack, i); + else + i++; + + modified_stack = TRUE; + } + + /* If we get to the end of verified_list and there are any remaining + * entries in xserver_list then append them all to the end */ + for (; j < tracker->xserver_stack->len; j++) + { + MetaStackWindow *current = + &g_array_index (tracker->xserver_stack, MetaStackWindow, j); + g_array_append_val (tracker->verified_stack, *current); + + modified_stack = TRUE; + } + + if (modified_stack) { if (tracker->predicted_stack) { @@ -556,6 +1029,48 @@ stack_tracker_event_received (MetaStackTracker *tracker, meta_stack_tracker_queue_sync_stack (tracker); } + return modified_stack; +} + +static void +stack_tracker_event_received (MetaStackTracker *tracker, + MetaStackOp *op) +{ + gboolean need_sync = FALSE; + gboolean verified; + + meta_stack_op_dump (op, "Stack op event received: ", "\n"); + + if (op->any.serial < tracker->xserver_serial) + { + g_warning ("Spurious X event received affecting stack; doing full re-query"); + resync_verified_stack_with_xserver_stack (tracker); + meta_stack_tracker_dump (tracker); + return; + } + + tracker->xserver_serial = op->any.serial; + +#warning "TODO: remove unused tracker->xserver_stack" + /* XXX: With the design we have ended up with it looks like we've + * ended up making it unnecessary to maintain tracker->xserver_stack + * since we only need an xserver_stack during the + * resync_verified_stack_with_xserver_stack() at which point we are + * going to query the full stack from the X server using + * XQueryTree() anyway. + * + * TODO: remove tracker->xserver_stack. + */ + meta_stack_op_apply (op, tracker->xserver_stack); + + verified = stack_tracker_verify_predictions (tracker, op, &need_sync); + if (!verified) + { + resync_verified_stack_with_xserver_stack (tracker); + meta_stack_tracker_dump (tracker); + return; + } + meta_stack_tracker_dump (tracker); } @@ -567,7 +1082,8 @@ meta_stack_tracker_create_event (MetaStackTracker *tracker, op.any.type = STACK_OP_ADD; op.any.serial = event->serial; - op.add.window = event->window; + op.add.window.any.type = META_WINDOW_CLIENT_TYPE_X11; + op.add.window.x11.xwindow = event->window; stack_tracker_event_received (tracker, &op); } @@ -580,7 +1096,8 @@ meta_stack_tracker_destroy_event (MetaStackTracker *tracker, op.any.type = STACK_OP_REMOVE; op.any.serial = event->serial; - op.remove.window = event->window; + op.remove.window.any.type = META_WINDOW_CLIENT_TYPE_X11; + op.remove.window.x11.xwindow = event->window; stack_tracker_event_received (tracker, &op); } @@ -595,7 +1112,8 @@ meta_stack_tracker_reparent_event (MetaStackTracker *tracker, op.any.type = STACK_OP_ADD; op.any.serial = event->serial; - op.add.window = event->window; + op.add.window.any.type = META_WINDOW_CLIENT_TYPE_X11; + op.add.window.x11.xwindow = event->window; stack_tracker_event_received (tracker, &op); } @@ -605,7 +1123,8 @@ meta_stack_tracker_reparent_event (MetaStackTracker *tracker, op.any.type = STACK_OP_REMOVE; op.any.serial = event->serial; - op.remove.window = event->window; + op.remove.window.any.type = META_WINDOW_CLIENT_TYPE_X11; + op.remove.window.x11.xwindow = event->window; stack_tracker_event_received (tracker, &op); } @@ -619,8 +1138,10 @@ meta_stack_tracker_configure_event (MetaStackTracker *tracker, op.any.type = STACK_OP_RAISE_ABOVE; op.any.serial = event->serial; - op.raise_above.window = event->window; - op.raise_above.sibling = event->above; + op.raise_above.window.any.type = META_WINDOW_CLIENT_TYPE_X11; + op.raise_above.window.x11.xwindow = event->window; + op.raise_above.sibling.any.type = META_WINDOW_CLIENT_TYPE_X11; + op.raise_above.sibling.x11.xwindow = event->above; stack_tracker_event_received (tracker, &op); } @@ -644,14 +1165,14 @@ meta_stack_tracker_configure_event (MetaStackTracker *tracker, */ void meta_stack_tracker_get_stack (MetaStackTracker *tracker, - Window **windows, + MetaStackWindow **windows, int *n_windows) { GArray *stack; - if (tracker->queued_requests->length == 0) + if (tracker->unverified_predictions->length == 0) { - stack = tracker->server_stack; + stack = tracker->verified_stack; } else { @@ -659,9 +1180,8 @@ meta_stack_tracker_get_stack (MetaStackTracker *tracker, { GList *l; - tracker->predicted_stack = copy_stack ((Window *)tracker->server_stack->data, - tracker->server_stack->len); - for (l = tracker->queued_requests->head; l; l = l->next) + tracker->predicted_stack = copy_stack (tracker->verified_stack); + for (l = tracker->unverified_predictions->head; l; l = l->next) { MetaStackOp *op = l->data; meta_stack_op_apply (op, tracker->predicted_stack); @@ -671,8 +1191,11 @@ meta_stack_tracker_get_stack (MetaStackTracker *tracker, stack = tracker->predicted_stack; } + meta_topic (META_DEBUG_STACK, "Get Stack\n"); + meta_stack_tracker_dump (tracker); + if (windows) - *windows = (Window *)stack->data; + *windows = (MetaStackWindow *)stack->data; if (n_windows) *n_windows = stack->len; } @@ -687,8 +1210,8 @@ meta_stack_tracker_get_stack (MetaStackTracker *tracker, void meta_stack_tracker_sync_stack (MetaStackTracker *tracker) { + MetaStackWindow *windows; GList *meta_windows; - Window *windows; int n_windows; int i; @@ -703,20 +1226,26 @@ meta_stack_tracker_sync_stack (MetaStackTracker *tracker) meta_windows = NULL; for (i = 0; i < n_windows; i++) { - MetaWindow *meta_window; + MetaStackWindow *window = &windows[i]; - meta_window = meta_display_lookup_x_window (tracker->screen->display, - windows[i]); - /* When mapping back from xwindow to MetaWindow we have to be a bit careful; - * children of the root could include unmapped windows created by toolkits - * for internal purposes, including ones that we have registered in our - * XID => window table. (Wine uses a toplevel for _NET_WM_USER_TIME_WINDOW; - * see window-prop.c:reload_net_wm_user_time_window() for registration.) - */ - if (meta_window && - (windows[i] == meta_window->xwindow || - (meta_window->frame && windows[i] == meta_window->frame->xwindow))) - meta_windows = g_list_prepend (meta_windows, meta_window); + if (window->any.type == META_WINDOW_CLIENT_TYPE_X11) + { + MetaWindow *meta_window = + meta_display_lookup_x_window (tracker->screen->display, windows[i].x11.xwindow); + + /* When mapping back from xwindow to MetaWindow we have to be a bit careful; + * children of the root could include unmapped windows created by toolkits + * for internal purposes, including ones that we have registered in our + * XID => window table. (Wine uses a toplevel for _NET_WM_USER_TIME_WINDOW; + * see window-prop.c:reload_net_wm_user_time_window() for registration.) + */ + if (meta_window && + (windows[i].x11.xwindow == meta_window->xwindow || + (meta_window->frame && windows[i].x11.xwindow == meta_window->frame->xwindow))) + meta_windows = g_list_prepend (meta_windows, meta_window); + } + else + meta_windows = g_list_prepend (meta_windows, window->wayland.meta_window); } if (tracker->screen->display->compositor) diff --git a/src/core/stack-tracker.h b/src/core/stack-tracker.h index cb12dcd00..4b7b1bfd7 100644 --- a/src/core/stack-tracker.h +++ b/src/core/stack-tracker.h @@ -37,36 +37,55 @@ #define META_STACK_TRACKER_H #include +#include typedef struct _MetaStackTracker MetaStackTracker; +typedef union _MetaStackWindow +{ + struct { + MetaWindowClientType type; + } any; + struct { + MetaWindowClientType type; + Window xwindow; + } x11; + struct { + MetaWindowClientType type; + MetaWindow *meta_window; + } wayland; +} MetaStackWindow; + +gboolean meta_stack_window_equal (const MetaStackWindow *a, + const MetaStackWindow *b); + MetaStackTracker *meta_stack_tracker_new (MetaScreen *screen); void meta_stack_tracker_free (MetaStackTracker *tracker); /* These functions are called when we make an X call that changes the * stacking order; this allows MetaStackTracker to predict stacking * order before it receives events back from the X server */ -void meta_stack_tracker_record_add (MetaStackTracker *tracker, - Window window, - gulong serial); -void meta_stack_tracker_record_remove (MetaStackTracker *tracker, - Window window, - gulong serial); -void meta_stack_tracker_record_restack_windows (MetaStackTracker *tracker, - Window *windows, - int n_windows, - gulong serial); -void meta_stack_tracker_record_raise_above (MetaStackTracker *tracker, - Window window, - Window sibling, - gulong serial); -void meta_stack_tracker_record_lower_below (MetaStackTracker *tracker, - Window window, - Window sibling, - gulong serial); -void meta_stack_tracker_record_lower (MetaStackTracker *tracker, - Window window, - gulong serial); +void meta_stack_tracker_record_add (MetaStackTracker *tracker, + const MetaStackWindow *window, + gulong serial); +void meta_stack_tracker_record_remove (MetaStackTracker *tracker, + const MetaStackWindow *window, + gulong serial); +void meta_stack_tracker_record_restack_windows (MetaStackTracker *tracker, + const MetaStackWindow *windows, + int n_windows, + gulong serial); +void meta_stack_tracker_record_raise_above (MetaStackTracker *tracker, + const MetaStackWindow *window, + const MetaStackWindow *sibling, + gulong serial); +void meta_stack_tracker_record_lower_below (MetaStackTracker *tracker, + const MetaStackWindow *window, + const MetaStackWindow *sibling, + gulong serial); +void meta_stack_tracker_record_lower (MetaStackTracker *tracker, + const MetaStackWindow *window, + gulong serial); /* These functions are used to update the stack when we get events * reflecting changes to the stacking order */ @@ -79,9 +98,9 @@ void meta_stack_tracker_reparent_event (MetaStackTracker *tracker, void meta_stack_tracker_configure_event (MetaStackTracker *tracker, XConfigureEvent *event); -void meta_stack_tracker_get_stack (MetaStackTracker *tracker, - Window **windows, - int *n_windows); +void meta_stack_tracker_get_stack (MetaStackTracker *tracker, + MetaStackWindow **windows, + int *n_entries); void meta_stack_tracker_sync_stack (MetaStackTracker *tracker); void meta_stack_tracker_queue_sync_stack (MetaStackTracker *tracker); diff --git a/src/core/stack.c b/src/core/stack.c index 3b05cdbd3..85b0f35dd 100644 --- a/src/core/stack.c +++ b/src/core/stack.c @@ -52,7 +52,7 @@ #define WINDOW_IN_STACK(w) (w->stack_position >= 0) -static void stack_sync_to_server (MetaStack *stack); +static void stack_sync_to_xserver (MetaStack *stack); static void meta_window_set_stack_position_no_sync (MetaWindow *window, int position); static void stack_do_window_deletions (MetaStack *stack); @@ -71,14 +71,14 @@ meta_stack_new (MetaScreen *screen) stack = g_new (MetaStack, 1); stack->screen = screen; - stack->windows = g_array_new (FALSE, FALSE, sizeof (Window)); + stack->xwindows = g_array_new (FALSE, FALSE, sizeof (Window)); stack->sorted = NULL; stack->added = NULL; stack->removed = NULL; stack->freeze_count = 0; - stack->last_root_children_stacked = NULL; + stack->last_all_root_children_stacked = NULL; stack->n_positions = 0; @@ -89,17 +89,34 @@ meta_stack_new (MetaScreen *screen) return stack; } +static void +free_last_all_root_children_stacked_cache (MetaStack *stack) +{ + unsigned int i; + + for (i = 0; i < stack->last_all_root_children_stacked->len; i++) + { + MetaStackWindow *window = &g_array_index (stack->last_all_root_children_stacked, MetaStackWindow, i); + if (window->any.type == META_WINDOW_CLIENT_TYPE_WAYLAND) + g_object_remove_weak_pointer (G_OBJECT (window->wayland.meta_window), + (gpointer *)&window->wayland.meta_window); + } + + g_array_free (stack->last_all_root_children_stacked, TRUE); + stack->last_all_root_children_stacked = NULL; +} + void meta_stack_free (MetaStack *stack) { - g_array_free (stack->windows, TRUE); + g_array_free (stack->xwindows, TRUE); g_list_free (stack->sorted); g_list_free (stack->added); g_list_free (stack->removed); - if (stack->last_root_children_stacked) - g_array_free (stack->last_root_children_stacked, TRUE); + if (stack->last_all_root_children_stacked) + free_last_all_root_children_stacked_cache (stack); g_free (stack); } @@ -121,7 +138,7 @@ meta_stack_add (MetaStack *stack, "Window %s has stack_position initialized to %d\n", window->desc, window->stack_position); - stack_sync_to_server (stack); + stack_sync_to_xserver (stack); meta_stack_update_window_tile_matches (stack, window->screen->active_workspace); } @@ -157,7 +174,7 @@ meta_stack_remove (MetaStack *stack, stack->removed = g_list_prepend (stack->removed, GUINT_TO_POINTER (window->frame->xwindow)); - stack_sync_to_server (stack); + stack_sync_to_xserver (stack); meta_stack_update_window_tile_matches (stack, window->screen->active_workspace); } @@ -167,7 +184,7 @@ meta_stack_update_layer (MetaStack *stack, { stack->need_relayer = TRUE; - stack_sync_to_server (stack); + stack_sync_to_xserver (stack); meta_stack_update_window_tile_matches (stack, window->screen->active_workspace); } @@ -177,7 +194,7 @@ meta_stack_update_transient (MetaStack *stack, { stack->need_constrain = TRUE; - stack_sync_to_server (stack); + stack_sync_to_xserver (stack); meta_stack_update_window_tile_matches (stack, window->screen->active_workspace); } @@ -206,7 +223,7 @@ meta_stack_raise (MetaStack *stack, meta_window_set_stack_position_no_sync (window, max_stack_position); - stack_sync_to_server (stack); + stack_sync_to_xserver (stack); meta_stack_update_window_tile_matches (stack, window->screen->active_workspace); } @@ -234,7 +251,7 @@ meta_stack_lower (MetaStack *stack, meta_window_set_stack_position_no_sync (window, min_stack_position); - stack_sync_to_server (stack); + stack_sync_to_xserver (stack); meta_stack_update_window_tile_matches (stack, window->screen->active_workspace); } @@ -250,7 +267,7 @@ meta_stack_thaw (MetaStack *stack) g_return_if_fail (stack->freeze_count > 0); stack->freeze_count -= 1; - stack_sync_to_server (stack); + stack_sync_to_xserver (stack); meta_stack_update_window_tile_matches (stack, NULL); } @@ -829,7 +846,7 @@ stack_do_window_deletions (MetaStack *stack) /* We go from the end figuring removals are more * likely to be recent. */ - i = stack->windows->len; + i = stack->xwindows->len; while (i > 0) { --i; @@ -840,9 +857,9 @@ stack_do_window_deletions (MetaStack *stack) * both the window->xwindow and window->frame->xwindow * in the removal list. */ - if (xwindow == g_array_index (stack->windows, Window, i)) + if (xwindow == g_array_index (stack->xwindows, Window, i)) { - g_array_remove_index (stack->windows, i); + g_array_remove_index (stack->xwindows, i); goto next; } } @@ -871,10 +888,10 @@ stack_do_window_additions (MetaStack *stack) "Adding %d windows to sorted list\n", n_added); - old_size = stack->windows->len; - g_array_set_size (stack->windows, old_size + n_added); + old_size = stack->xwindows->len; + g_array_set_size (stack->xwindows, old_size + n_added); - end = &g_array_index (stack->windows, Window, old_size); + end = &g_array_index (stack->xwindows, Window, old_size); /* stack->added has the most recent additions at the * front of the list, so we need to reverse it @@ -1029,6 +1046,102 @@ stack_ensure_sorted (MetaStack *stack) stack_do_resort (stack); } +static MetaStackWindow * +find_top_most_managed_window (MetaScreen *screen, + const MetaStackWindow *ignore) +{ + MetaStackTracker *stack_tracker = screen->stack_tracker; + MetaStackWindow *windows; + int n_windows; + int i; + + meta_stack_tracker_get_stack (stack_tracker, + &windows, &n_windows); + + /* Children are in order from bottom to top. We want to + * find the topmost managed child, then configure + * our window to be above it. + */ + for (i = n_windows -1; i >= 0; i--) + { + MetaStackWindow *other_window = &windows[i]; + + if (other_window->any.type == ignore->any.type && + ((other_window->any.type == META_WINDOW_CLIENT_TYPE_X11 && + other_window->x11.xwindow == ignore->x11.xwindow) || + other_window->wayland.meta_window == ignore->wayland.meta_window)) + { + /* Do nothing. This means we're already the topmost managed + * window, but it DOES NOT mean we are already just above + * the topmost managed window. This is important because if + * an override redirect window is up, and we map a new + * managed window, the new window is probably above the old + * popup by default, and we want to push it below that + * popup. So keep looking for a sibling managed window + * to be moved below. + */ + } + else + { + if (other_window->any.type == META_WINDOW_CLIENT_TYPE_X11) + { + MetaWindow *other = meta_display_lookup_x_window (screen->display, + other_window->x11.xwindow); + + if (other != NULL && !other->override_redirect) + return other_window; + } + else + { + /* All wayland windows are currently considered "managed" + * TODO: consider wayland pop-up windows like override + * redirect windows here. */ + return other_window; + } + } + } + + return NULL; +} + +/* When moving an X window we sometimes need an X based sibling. + * + * If the given sibling is X based this function returns it back + * otherwise it searches downwards looking for the nearest X window. + * + * If no X based sibling could be found return NULL. */ +static MetaStackWindow * +find_x11_sibling_downwards (MetaScreen *screen, + MetaStackWindow *sibling) +{ + MetaStackTracker *stack_tracker = screen->stack_tracker; + MetaStackWindow *windows; + int n_windows; + int i; + + if (sibling->any.type == META_WINDOW_CLIENT_TYPE_X11) + return sibling; + + meta_stack_tracker_get_stack (stack_tracker, + &windows, &n_windows); + + /* NB: Children are in order from bottom to top and we + * want to search downwards for the nearest X window. + */ + + for (i = n_windows - 1; i >= 0; i--) + if (meta_stack_window_equal (&windows[i], sibling)) + break; + + for (; i >= 0; i--) + { + if (windows[i].any.type == META_WINDOW_CLIENT_TYPE_X11) + return &windows[i]; + } + + return NULL; +} + /** * raise_window_relative_to_managed_windows: * @@ -1053,84 +1166,74 @@ stack_ensure_sorted (MetaStack *stack) */ static void raise_window_relative_to_managed_windows (MetaScreen *screen, - Window xwindow) + const MetaStackWindow *window) { + gulong serial = 0; + MetaStackWindow *sibling; - Window *children; - int n_children; - int i; - - meta_stack_tracker_get_stack (screen->stack_tracker, - &children, &n_children); - - /* Children are in order from bottom to top. We want to - * find the topmost managed child, then configure - * our window to be above it. - */ - i = n_children - 1; - while (i >= 0) + sibling = find_top_most_managed_window (screen, window); + if (!sibling) { - if (children[i] == xwindow) + if (window->any.type == META_WINDOW_CLIENT_TYPE_X11) { - /* Do nothing. This means we're already the topmost managed - * window, but it DOES NOT mean we are already just above - * the topmost managed window. This is important because if - * an override redirect window is up, and we map a new - * managed window, the new window is probably above the old - * popup by default, and we want to push it below that - * popup. So keep looking for a sibling managed window - * to be moved below. - */ + serial = XNextRequest (screen->display->xdisplay); + meta_error_trap_push (screen->display); + XLowerWindow (screen->display->xdisplay, + window->x11.xwindow); + meta_error_trap_pop (screen->display); } - else - { - MetaWindow *other = meta_display_lookup_x_window (screen->display, - children[i]); - if (other != NULL && !other->override_redirect) - { - XWindowChanges changes; - /* children[i] is the topmost managed child */ + /* No sibling to use, just lower ourselves to the bottom + * to be sure we're below any override redirect windows. + */ + meta_stack_tracker_record_lower (screen->stack_tracker, + window, + serial); + return; + } + + /* window is the topmost managed child */ meta_topic (META_DEBUG_STACK, "Moving 0x%lx above topmost managed child window 0x%lx\n", - xwindow, children[i]); + window->any.type == META_WINDOW_CLIENT_TYPE_X11 ? window->x11.xwindow: 0, + sibling->any.type == META_WINDOW_CLIENT_TYPE_X11 ? sibling->x11.xwindow: 0); - changes.sibling = children[i]; + if (window->any.type == META_WINDOW_CLIENT_TYPE_X11) + { + XWindowChanges changes; + MetaStackWindow *x11_sibling = find_x11_sibling_downwards (screen, sibling); + serial = XNextRequest (screen->display->xdisplay); + + if (x11_sibling) + { + changes.sibling = x11_sibling->x11.xwindow; changes.stack_mode = Above; meta_error_trap_push (screen->display); - meta_stack_tracker_record_raise_above (screen->stack_tracker, - xwindow, - children[i], - XNextRequest (screen->display->xdisplay)); XConfigureWindow (screen->display->xdisplay, - xwindow, + window->x11.xwindow, CWSibling | CWStackMode, &changes); meta_error_trap_pop (screen->display); - - break; - } } - - --i; - } - - if (i < 0) + else { /* No sibling to use, just lower ourselves to the bottom * to be sure we're below any override redirect windows. */ meta_error_trap_push (screen->display); - meta_stack_tracker_record_lower (screen->stack_tracker, - xwindow, - XNextRequest (screen->display->xdisplay)); XLowerWindow (screen->display->xdisplay, - xwindow); + window->x11.xwindow); meta_error_trap_pop (screen->display); } } + meta_stack_tracker_record_raise_above (screen->stack_tracker, + window, + sibling, + serial); +} + /** * stack_sync_to_server: * @@ -1145,13 +1248,16 @@ raise_window_relative_to_managed_windows (MetaScreen *screen, * job of computing the minimal set of stacking requests needed. */ static void -stack_sync_to_server (MetaStack *stack) +stack_sync_to_xserver (MetaStack *stack) { - GArray *stacked; - GArray *root_children_stacked; + GArray *x11_stacked; + GArray *x11_root_children_stacked; + GArray *all_root_children_stacked; /* wayland OR x11 */ GList *tmp; - GArray *all_hidden; + GArray *x11_hidden; + GArray *x11_hidden_stack_windows; int n_override_redirect = 0; + MetaStackWindow guard_stack_window; /* Bail out if frozen */ if (stack->freeze_count > 0) @@ -1166,13 +1272,17 @@ stack_sync_to_server (MetaStack *stack) * _NET hints, and "root_children_stacked" is in top-to-bottom * order for XRestackWindows() */ - stacked = g_array_new (FALSE, FALSE, sizeof (Window)); - root_children_stacked = g_array_new (FALSE, FALSE, sizeof (Window)); - all_hidden = g_array_new (FALSE, FALSE, sizeof (Window)); + x11_stacked = g_array_new (FALSE, FALSE, sizeof (Window)); + + all_root_children_stacked = g_array_new (FALSE, FALSE, sizeof (MetaStackWindow)); + x11_root_children_stacked = g_array_new (FALSE, FALSE, sizeof (Window)); + + x11_hidden_stack_windows = g_array_new (FALSE, FALSE, sizeof (MetaStackWindow)); + x11_hidden = g_array_new (FALSE, FALSE, sizeof (Window)); /* The screen guard window sits above all hidden windows and acts as * a barrier to input reaching these windows. */ - g_array_append_val (all_hidden, stack->screen->guard_window); + g_array_append_val (x11_hidden, stack->screen->guard_window); meta_topic (META_DEBUG_STACK, "Top to bottom: "); meta_push_no_msg_prefix (); @@ -1181,6 +1291,9 @@ stack_sync_to_server (MetaStack *stack) { MetaWindow *w = tmp->data; Window top_level_window; + MetaStackWindow stack_window; + + stack_window.any.type = w->client_type; meta_topic (META_DEBUG_STACK, "%u:%d - %s ", w->layer, w->stack_position, w->desc); @@ -1189,60 +1302,93 @@ stack_sync_to_server (MetaStack *stack) if (w->override_redirect) n_override_redirect++; else - g_array_prepend_val (stacked, w->xwindow); + g_array_prepend_val (x11_stacked, w->xwindow); if (w->frame) top_level_window = w->frame->xwindow; else top_level_window = w->xwindow; + if (w->client_type == META_WINDOW_CLIENT_TYPE_X11) + stack_window.x11.xwindow = top_level_window; + else + stack_window.wayland.meta_window = w; + /* We don't restack hidden windows along with the rest, though they are * reflected in the _NET hints. Hidden windows all get pushed below * the screens fullscreen guard_window. */ if (w->hidden) { - g_array_append_val (all_hidden, top_level_window); + if (w->client_type == META_WINDOW_CLIENT_TYPE_X11) + { + MetaStackWindow stack_window; + + stack_window.any.type = META_WINDOW_CLIENT_TYPE_X11; + stack_window.x11.xwindow = top_level_window; + + g_array_append_val (x11_hidden_stack_windows, stack_window); + g_array_append_val (x11_hidden, top_level_window); + } continue; } + g_array_append_val (all_root_children_stacked, stack_window); + /* build XRestackWindows() array from top to bottom */ - g_array_append_val (root_children_stacked, top_level_window); + if (w->client_type == META_WINDOW_CLIENT_TYPE_X11) + g_array_append_val (x11_root_children_stacked, top_level_window); + else + { + MetaStackWindow *new; + + /* So we can determine later if a cached stack window is + * stale because the corresponding window has been freed we + * associate a weak pointer with the new window. */ + new = &g_array_index (all_root_children_stacked, MetaStackWindow, all_root_children_stacked->len - 1); + g_object_add_weak_pointer (G_OBJECT (new->wayland.meta_window), + (gpointer *)&new->wayland.meta_window); + } } meta_topic (META_DEBUG_STACK, "\n"); meta_pop_no_msg_prefix (); - /* All windows should be in some stacking order */ - if (stacked->len != stack->windows->len - n_override_redirect) + /* All X windows should be in some stacking order */ + if (x11_stacked->len != stack->xwindows->len - n_override_redirect) meta_bug ("%u windows stacked, %u windows exist in stack\n", - stacked->len, stack->windows->len); + x11_stacked->len, stack->xwindows->len); /* Sync to server */ meta_topic (META_DEBUG_STACK, "Restacking %u windows\n", - root_children_stacked->len); + all_root_children_stacked->len); meta_error_trap_push (stack->screen->display); - if (stack->last_root_children_stacked == NULL) + if (stack->last_all_root_children_stacked == NULL) { /* Just impose our stack, we don't know the previous state. * This involves a ton of circulate requests and may flicker. */ meta_topic (META_DEBUG_STACK, "Don't know last stack state, restacking everything\n"); - if (root_children_stacked->len > 0) + if (all_root_children_stacked->len > 1) { - meta_stack_tracker_record_restack_windows (stack->screen->stack_tracker, - (Window *) root_children_stacked->data, - root_children_stacked->len, - XNextRequest (stack->screen->display->xdisplay)); + gulong serial = 0; + if (x11_root_children_stacked->len > 1) + { + serial = XNextRequest (stack->screen->display->xdisplay); XRestackWindows (stack->screen->display->xdisplay, - (Window *) root_children_stacked->data, - root_children_stacked->len); + (Window *) x11_root_children_stacked->data, + x11_root_children_stacked->len); + } + meta_stack_tracker_record_restack_windows (stack->screen->stack_tracker, + (MetaStackWindow *) all_root_children_stacked->data, + all_root_children_stacked->len, + serial); } } - else if (root_children_stacked->len > 0) + else if (all_root_children_stacked->len > 0) { /* Try to do minimal window moves to get the stack in order */ /* A point of note: these arrays include frames not client windows, @@ -1250,28 +1396,34 @@ stack_sync_to_server (MetaStack *stack) * was saved, then we may have inefficiency, but I don't think things * break... */ - const Window *old_stack = (Window *) stack->last_root_children_stacked->data; - const Window *new_stack = (Window *) root_children_stacked->data; - const int old_len = stack->last_root_children_stacked->len; - const int new_len = root_children_stacked->len; - const Window *oldp = old_stack; - const Window *newp = new_stack; - const Window *old_end = old_stack + old_len; - const Window *new_end = new_stack + new_len; - Window last_window = None; - + const MetaStackWindow *old_stack = (MetaStackWindow *) stack->last_all_root_children_stacked->data; + const MetaStackWindow *new_stack = (MetaStackWindow *) all_root_children_stacked->data; + const int old_len = stack->last_all_root_children_stacked->len; + const int new_len = all_root_children_stacked->len; + const MetaStackWindow *oldp = old_stack; + const MetaStackWindow *newp = new_stack; + const MetaStackWindow *old_end = old_stack + old_len; + const MetaStackWindow *new_end = new_stack + new_len; + Window last_xwindow = None; + const MetaStackWindow *last_window = NULL; + while (oldp != old_end && newp != new_end) { - if (*oldp == *newp) + if (meta_stack_window_equal (oldp, newp)) { /* Stacks are the same here, move on */ ++oldp; - last_window = *newp; + if (newp->any.type == META_WINDOW_CLIENT_TYPE_X11) + last_xwindow = newp->x11.xwindow; + last_window = newp; ++newp; } - else if (meta_display_lookup_x_window (stack->screen->display, - *oldp) == NULL) + else if ((oldp->any.type == META_WINDOW_CLIENT_TYPE_X11 && + meta_display_lookup_x_window (stack->screen->display, + oldp->x11.xwindow) == NULL) || + (oldp->any.type == META_WINDOW_CLIENT_TYPE_WAYLAND && + oldp->wayland.meta_window == NULL)) { /* *oldp is no longer known to us (probably destroyed), * so we can just skip it @@ -1280,75 +1432,161 @@ stack_sync_to_server (MetaStack *stack) } else { - /* Move *newp below last_window */ - if (last_window == None) + /* Move *newp below the last_window */ + if (!last_window) { - meta_topic (META_DEBUG_STACK, "Using window 0x%lx as topmost (but leaving it in-place)\n", *newp); + meta_topic (META_DEBUG_STACK, "Using window 0x%lx as topmost (but leaving it in-place)\n", + newp->x11.xwindow); - raise_window_relative_to_managed_windows (stack->screen, - *newp); + raise_window_relative_to_managed_windows (stack->screen, newp); + } + else if (newp->any.type == META_WINDOW_CLIENT_TYPE_X11 && + last_xwindow == None) + { + /* In this case we have an X window that we need to + * put below a wayland window and this is the + * topmost X window. */ + + /* In X terms (because this is the topmost X window) + * we want to + * raise_window_relative_to_managed_windows() to + * ensure the X window is below override-redirect + * pop-up windows. + * + * In Wayland terms we just want to ensure + * newp is lowered below last_window (which + * notably doesn't require an X request because we + * know last_window isn't an X window). + */ + + raise_window_relative_to_managed_windows (stack->screen, newp); + + meta_stack_tracker_record_lower_below (stack->screen->stack_tracker, + newp, last_window, + 0); /* no x request serial */ } else { - /* This means that if last_window is dead, but not + gulong serial = 0; + + /* This means that if last_xwindow is dead, but not * *newp, then we fail to restack *newp; but on - * unmanaging last_window, we'll fix it up. + * unmanaging last_xwindow, we'll fix it up. */ - XWindowChanges changes; + meta_topic (META_DEBUG_STACK, "Placing window 0x%lx below 0x%lx\n", + newp->any.type == META_WINDOW_CLIENT_TYPE_X11 ? newp->x11.xwindow : 0, + last_xwindow); - changes.sibling = last_window; + if (newp->any.type == META_WINDOW_CLIENT_TYPE_X11) + { + XWindowChanges changes; + serial = XNextRequest (stack->screen->display->xdisplay); + + changes.sibling = last_xwindow; changes.stack_mode = Below; - meta_topic (META_DEBUG_STACK, "Placing window 0x%lx below 0x%lx\n", - *newp, last_window); - - meta_stack_tracker_record_lower_below (stack->screen->stack_tracker, - *newp, last_window, - XNextRequest (stack->screen->display->xdisplay)); XConfigureWindow (stack->screen->display->xdisplay, - *newp, + newp->x11.xwindow, CWSibling | CWStackMode, &changes); } - last_window = *newp; + meta_stack_tracker_record_lower_below (stack->screen->stack_tracker, + newp, last_window, + serial); + } + + if (newp->any.type == META_WINDOW_CLIENT_TYPE_X11) + last_xwindow = newp->x11.xwindow; + last_window = newp; ++newp; } } if (newp != new_end) { + const MetaStackWindow *x_ref; + unsigned long serial = 0; + /* Restack remaining windows */ meta_topic (META_DEBUG_STACK, "Restacking remaining %d windows\n", (int) (new_end - newp)); + + /* rewind until we find the last stacked X window that we can use + * as a reference point for re-stacking remaining X windows */ + if (newp != new_stack) + for (x_ref = newp - 1; + x_ref->any.type != META_WINDOW_CLIENT_TYPE_X11 && x_ref > new_stack; + x_ref--) + ; + else + x_ref = new_stack; + + /* If we didn't find an X window looking backwards then walk forwards + * through the remaining windows to find the first remaining X window + * instead. */ + if (x_ref->any.type != META_WINDOW_CLIENT_TYPE_X11) + { + for (x_ref = newp; + x_ref->any.type != META_WINDOW_CLIENT_TYPE_X11 && x_ref > new_stack; + x_ref++) + ; + } + + /* If there are any X windows remaining unstacked then restack them */ + if (x_ref->any.type == META_WINDOW_CLIENT_TYPE_X11) + { + int i; + + for (i = x11_root_children_stacked->len - 1; i; i--) + { + Window *reference = &g_array_index (x11_root_children_stacked, Window, i); + + if (*reference == x_ref->x11.xwindow) + { + int n = x11_root_children_stacked->len - i; + + /* There's no point restacking if there's only one X window */ + if (n == 1) + break; + + serial = XNextRequest (stack->screen->display->xdisplay); + XRestackWindows (stack->screen->display->xdisplay, + reference, n); + break; + } + } + } + /* We need to include an already-stacked window * in the restack call, so we get in the proper position * with respect to it. */ if (newp != new_stack) - --newp; + newp = MIN (newp - 1, x_ref); meta_stack_tracker_record_restack_windows (stack->screen->stack_tracker, - (Window *) newp, new_end - newp, - XNextRequest (stack->screen->display->xdisplay)); - XRestackWindows (stack->screen->display->xdisplay, - (Window *) newp, new_end - newp); + newp, new_end - newp, + serial); } } - /* Push hidden windows to the bottom of the stack under the guard window */ + /* Push hidden X windows to the bottom of the stack under the guard window */ + guard_stack_window.any.type = META_WINDOW_CLIENT_TYPE_X11; + guard_stack_window.x11.xwindow = stack->screen->guard_window; meta_stack_tracker_record_lower (stack->screen->stack_tracker, - stack->screen->guard_window, + &guard_stack_window, XNextRequest (stack->screen->display->xdisplay)); XLowerWindow (stack->screen->display->xdisplay, stack->screen->guard_window); meta_stack_tracker_record_restack_windows (stack->screen->stack_tracker, - (Window *)all_hidden->data, - all_hidden->len, + (MetaStackWindow *)x11_hidden_stack_windows->data, + x11_hidden_stack_windows->len, XNextRequest (stack->screen->display->xdisplay)); XRestackWindows (stack->screen->display->xdisplay, - (Window *)all_hidden->data, - all_hidden->len); - g_array_free (all_hidden, TRUE); + (Window *)x11_hidden->data, + x11_hidden->len); + g_array_free (x11_hidden, TRUE); + g_array_free (x11_hidden_stack_windows, TRUE); meta_error_trap_pop (stack->screen->display); /* on error, a window was destroyed; it should eventually @@ -1363,21 +1601,23 @@ stack_sync_to_server (MetaStack *stack) stack->screen->display->atom__NET_CLIENT_LIST, XA_WINDOW, 32, PropModeReplace, - (unsigned char *)stack->windows->data, - stack->windows->len); + (unsigned char *)stack->xwindows->data, + stack->xwindows->len); XChangeProperty (stack->screen->display->xdisplay, stack->screen->xroot, stack->screen->display->atom__NET_CLIENT_LIST_STACKING, XA_WINDOW, 32, PropModeReplace, - (unsigned char *)stacked->data, - stacked->len); + (unsigned char *)x11_stacked->data, + x11_stacked->len); - g_array_free (stacked, TRUE); + g_array_free (x11_stacked, TRUE); - if (stack->last_root_children_stacked) - g_array_free (stack->last_root_children_stacked, TRUE); - stack->last_root_children_stacked = root_children_stacked; + if (stack->last_all_root_children_stacked) + free_last_all_root_children_stacked_cache (stack); + stack->last_all_root_children_stacked = all_root_children_stacked; + + g_array_free (x11_root_children_stacked, TRUE); /* That was scary... */ } @@ -1738,7 +1978,7 @@ meta_stack_set_positions (MetaStack *stack, meta_topic (META_DEBUG_STACK, "Reset the stack positions of (nearly) all windows\n"); - stack_sync_to_server (stack); + stack_sync_to_xserver (stack); meta_stack_update_window_tile_matches (stack, NULL); } @@ -1801,7 +2041,7 @@ meta_window_set_stack_position (MetaWindow *window, int position) { meta_window_set_stack_position_no_sync (window, position); - stack_sync_to_server (window->screen->stack); + stack_sync_to_xserver (window->screen->stack); meta_stack_update_window_tile_matches (window->screen->stack, window->screen->active_workspace); } diff --git a/src/core/stack.h b/src/core/stack.h index fb54e2df0..423672b32 100644 --- a/src/core/stack.h +++ b/src/core/stack.h @@ -60,7 +60,7 @@ struct _MetaStack * A sequence of all the Windows (X handles, not MetaWindows) of the windows * we manage, sorted in order. Suitable to be passed into _NET_CLIENT_LIST. */ - GArray *windows; + GArray *xwindows; /** The MetaWindows of the windows we manage, sorted in order. */ GList *sorted; @@ -99,7 +99,7 @@ struct _MetaStack * The last-known stack of all windows, bottom to top. We cache it here * so that subsequent times we'll be able to do incremental moves. */ - GArray *last_root_children_stacked; + GArray *last_all_root_children_stacked; /** * Number of stack positions; same as the length of added, but diff --git a/src/core/window-private.h b/src/core/window-private.h index 044d89710..4827e58d5 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -80,10 +80,6 @@ typedef enum { _NET_WM_BYPASS_COMPOSITOR_HINT_OFF = 2, } MetaBypassCompositorHintValue; -typedef enum { - META_WINDOW_CLIENT_TYPE_WAYLAND, - META_WINDOW_CLIENT_TYPE_X11 -} MetaWindowClientType; struct _MetaWindow { diff --git a/src/core/window.c b/src/core/window.c index df535289d..599965a51 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -1144,6 +1144,16 @@ meta_window_new_shared (MetaDisplay *display, if (window->decorated) meta_window_ensure_frame (window); + if (window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND) + { + MetaStackWindow stack_window; + stack_window.any.type = META_WINDOW_CLIENT_TYPE_WAYLAND; + stack_window.wayland.meta_window = window; + meta_stack_tracker_record_add (window->screen->stack_tracker, + &stack_window, + 0); + } + meta_window_grab_keys (window); if (window->type != META_WINDOW_DOCK && !window->override_redirect) { @@ -1832,6 +1842,16 @@ meta_window_unmanage (MetaWindow *window, meta_verbose ("Unmanaging 0x%lx\n", window->xwindow); + if (window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND) + { + MetaStackWindow stack_window; + stack_window.any.type = META_WINDOW_CLIENT_TYPE_WAYLAND; + stack_window.wayland.meta_window = window; + meta_stack_tracker_record_remove (window->screen->stack_tracker, + &stack_window, + 0); + } + if (window->display->compositor) { if (window->visible_to_compositor) diff --git a/src/meta/window.h b/src/meta/window.h index 9679454ad..0b49c0343 100644 --- a/src/meta/window.h +++ b/src/meta/window.h @@ -81,6 +81,16 @@ typedef enum META_MAXIMIZE_VERTICAL = 1 << 1 } MetaMaximizeFlags; +/** + * MetaWindowClientType: + * @META_WINDOW_CLIENT_TYPE_WAYLAND: A Wayland based window + * @META_WINDOW_CLIENT_TYPE_X11: An X11 based window + */ +typedef enum { + META_WINDOW_CLIENT_TYPE_WAYLAND, + META_WINDOW_CLIENT_TYPE_X11 +} MetaWindowClientType; + #define META_TYPE_WINDOW (meta_window_get_type ()) #define META_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_WINDOW, MetaWindow)) #define META_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_WINDOW, MetaWindowClass)) From 268ebb1b18c7dccb292c9cab4e5aea574c2e5f59 Mon Sep 17 00:00:00 2001 From: Neil Roberts Date: Fri, 3 May 2013 18:51:22 +0100 Subject: [PATCH 008/889] wayland: Add basic input support This copies the basic input support from the Clayland demo compositor. It adds a basic wl_seat implementation which can convert Clutter mouse events to Wayland events. For this to work all of the wayland surface actors need to be made reactive. The wayland keyboard input focus surface is updated whenever Mutter sees a FocusIn event so that it will stay in synch with whatever surface Mutter wants as the focus. Wayland surfaces don't get this event so for now it will just give them focus whenever they are clicked as a hack to test the code. Authored-by: Neil Roberts Authored-by: Giovanni Campagna --- src/Makefile.am | 10 +- src/compositor/meta-window-actor.c | 3 + src/core/display-private.h | 3 + src/core/display.c | 49 ++- src/wayland/meta-wayland-data-device.c | 548 +++++++++++++++++++++++++ src/wayland/meta-wayland-data-device.h | 42 ++ src/wayland/meta-wayland-keyboard.c | 512 +++++++++++++++++++++++ src/wayland/meta-wayland-keyboard.h | 75 ++++ src/wayland/meta-wayland-pointer.c | 260 ++++++++++++ src/wayland/meta-wayland-pointer.h | 49 +++ src/wayland/meta-wayland-private.h | 203 ++++++++- src/wayland/meta-wayland-seat.c | 503 +++++++++++++++++++++++ src/wayland/meta-wayland-seat.h | 47 +++ src/wayland/meta-wayland.c | 280 +++++++++++++ 14 files changed, 2568 insertions(+), 16 deletions(-) create mode 100644 src/wayland/meta-wayland-data-device.c create mode 100644 src/wayland/meta-wayland-data-device.h create mode 100644 src/wayland/meta-wayland-keyboard.c create mode 100644 src/wayland/meta-wayland-keyboard.h create mode 100644 src/wayland/meta-wayland-pointer.c create mode 100644 src/wayland/meta-wayland-pointer.h create mode 100644 src/wayland/meta-wayland-seat.c create mode 100644 src/wayland/meta-wayland-seat.h diff --git a/src/Makefile.am b/src/Makefile.am index e25d4a8ee..a323a207e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -179,7 +179,15 @@ libmutter_la_SOURCES += \ wayland/meta-wayland.c \ wayland/meta-wayland-private.h \ wayland/meta-xwayland-private.h \ - wayland/meta-xwayland.c + wayland/meta-xwayland.c \ + wayland/meta-wayland-data-device.c \ + wayland/meta-wayland-data-device.h \ + wayland/meta-wayland-keyboard.c \ + wayland/meta-wayland-keyboard.h \ + wayland/meta-wayland-pointer.c \ + wayland/meta-wayland-pointer.h \ + wayland/meta-wayland-seat.c \ + wayland/meta-wayland-seat.h endif libmutter_la_LDFLAGS = -no-undefined diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 54f6838aa..c905fbd77 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -380,6 +380,9 @@ meta_window_actor_constructed (GObject *object) clutter_actor_add_child (CLUTTER_ACTOR (self), priv->actor); + if (meta_is_wayland_compositor ()) + clutter_actor_set_reactive (priv->actor, TRUE); + /* * Since we are holding a pointer to this actor independently of the * ClutterContainer internals, and provide a public API to access it, diff --git a/src/core/display-private.h b/src/core/display-private.h index 86284fe10..2ca9c6759 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -467,6 +467,9 @@ gboolean meta_display_modifiers_accelerator_activate (MetaDisplay *display); /* In above-tab-keycode.c */ guint meta_display_get_above_tab_keycode (MetaDisplay *display); +gboolean meta_display_handle_event (MetaDisplay *display, + XEvent *event); + #ifdef HAVE_XI23 gboolean meta_display_process_barrier_event (MetaDisplay *display, XIBarrierEvent *event); diff --git a/src/core/display.c b/src/core/display.c index 5e19f1439..53693685d 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -2137,10 +2137,9 @@ handle_window_focus_event (MetaDisplay *display, } /** - * event_callback: + * meta_display_handle_event: + * @display: The MetaDisplay that events are coming from * @event: The event that just happened - * @data: The #MetaDisplay that events are coming from, cast to a gpointer - * so that it can be sent to a callback * * This is the most important function in the whole program. It is the heart, * it is the nexus, it is the Grand Central Station of Mutter's world. @@ -2150,21 +2149,18 @@ handle_window_focus_event (MetaDisplay *display, * busy around here. Most of this function is a ginormous switch statement * dealing with all the kinds of events that might turn up. */ -static gboolean -event_callback (XEvent *event, - gpointer data) +gboolean +meta_display_handle_event (MetaDisplay *display, + XEvent *event) { MetaWindow *window; MetaWindow *property_for_window; - MetaDisplay *display; Window modified; gboolean frame_was_receiver; gboolean bypass_compositor; gboolean filter_out_event; XIEvent *input_event; - display = data; - #ifdef WITH_VERBOSE_MODE if (dump_events) meta_spew_event (display, event); @@ -2655,6 +2651,15 @@ event_callback (XEvent *event, } break; case XI_FocusIn: +#ifdef HAVE_WAYLAND + if (meta_is_wayland_compositor ()) + { + MetaWaylandCompositor *compositor = + meta_wayland_compositor_get_default (); + meta_wayland_compositor_set_input_focus (compositor, window); + } +#endif + /* fall through */ case XI_FocusOut: /* libXi does not properly copy the serial to the XIEnterEvent, so pull it * from the parent XAnyEvent. @@ -3202,6 +3207,32 @@ event_callback (XEvent *event, return filter_out_event; } +static gboolean +event_callback (XEvent *event, + gpointer data) +{ + MetaDisplay *display = data; + + /* Under Wayland we want to filter out mouse motion events so we can + synthesize them from the Clutter events instead. This is + necessary because the position in the mouse events is passed to + the X server relative to the position of the surface. The X + server then translates these back to screen coordinates based on + the window position. If we rely on this translatation when + dragging a window around then the window will jump around + erratically because of the lag between updating the window + position from the surface position. Instead we bypass the + translation altogether by directly using the Clutter events */ +#ifdef HAVE_WAYLAND + if (meta_is_wayland_compositor () && + event->type == GenericEvent && + event->xcookie.evtype == XI_Motion) + return FALSE; +#endif + + return meta_display_handle_event (display, event); +} + /* Return the window this has to do with, if any, rather * than the frame or root window that was selecting * for substructure diff --git a/src/wayland/meta-wayland-data-device.c b/src/wayland/meta-wayland-data-device.c new file mode 100644 index 000000000..d976352df --- /dev/null +++ b/src/wayland/meta-wayland-data-device.c @@ -0,0 +1,548 @@ +/* + * Copyright © 2011 Kristian Høgsberg + * + * 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 the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS 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. + */ + +/* The file is based on src/data-device.c from Weston */ + +#include "config.h" + +#include +#include +#include +#include +#include + +#include "meta-wayland-data-device.h" +#include "meta-wayland-seat.h" +#include "meta-wayland-pointer.h" + +static void +data_offer_accept (struct wl_client *client, + struct wl_resource *resource, + guint32 serial, + const char *mime_type) +{ + MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource); + + /* FIXME: Check that client is currently focused by the input + * device that is currently dragging this data source. Should + * this be a wl_data_device request? */ + + if (offer->source) + offer->source->accept (offer->source, serial, mime_type); +} + +static void +data_offer_receive (struct wl_client *client, struct wl_resource *resource, + const char *mime_type, int32_t fd) +{ + MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource); + + if (offer->source) + offer->source->send (offer->source, mime_type, fd); + else + close (fd); +} + +static void +data_offer_destroy (struct wl_client *client, struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static const struct wl_data_offer_interface data_offer_interface = { + data_offer_accept, + data_offer_receive, + data_offer_destroy, +}; + +static void +destroy_data_offer (struct wl_resource *resource) +{ + MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource); + + if (offer->source) + wl_list_remove (&offer->source_destroy_listener.link); + free (offer); +} + +static void +destroy_offer_data_source (struct wl_listener *listener, void *data) +{ + MetaWaylandDataOffer *offer; + + offer = wl_container_of (listener, offer, source_destroy_listener); + + offer->source = NULL; +} + +static struct wl_resource * +meta_wayland_data_source_send_offer (MetaWaylandDataSource *source, + struct wl_resource *target) +{ + MetaWaylandDataOffer *offer; + char **p; + + offer = malloc (sizeof *offer); + if (offer == NULL) + return NULL; + + offer->source = source; + offer->source_destroy_listener.notify = destroy_offer_data_source; + + offer->resource = wl_client_add_object (wl_resource_get_client (target), + &wl_data_offer_interface, + &data_offer_interface, + 0, + offer); + wl_resource_set_destructor (offer->resource, destroy_data_offer); + wl_resource_add_destroy_listener (source->resource, + &offer->source_destroy_listener); + + wl_data_device_send_data_offer (target, offer->resource); + + wl_array_for_each (p, &source->mime_types) + wl_data_offer_send_offer (offer->resource, *p); + + return offer->resource; +} + +static void +data_source_offer (struct wl_client *client, + struct wl_resource *resource, const char *type) +{ + MetaWaylandDataSource *source = wl_resource_get_user_data (resource); + char **p; + + p = wl_array_add (&source->mime_types, sizeof *p); + if (p) + *p = strdup (type); + if (!p || !*p) + wl_resource_post_no_memory (resource); +} + +static void +data_source_destroy (struct wl_client *client, struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static struct wl_data_source_interface data_source_interface = { + data_source_offer, + data_source_destroy +}; + +static void +destroy_drag_focus (struct wl_listener *listener, void *data) +{ + MetaWaylandSeat *seat = wl_container_of (listener, seat, drag_focus_listener); + + seat->drag_focus_resource = NULL; +} + +static void +drag_grab_focus (MetaWaylandPointerGrab *grab, + MetaWaylandSurface *surface, + wl_fixed_t x, + wl_fixed_t y) +{ + MetaWaylandSeat *seat = wl_container_of (grab, seat, drag_grab); + struct wl_resource *resource, *offer = NULL; + struct wl_display *display; + guint32 serial; + + if (seat->drag_focus_resource) + { + wl_data_device_send_leave (seat->drag_focus_resource); + wl_list_remove (&seat->drag_focus_listener.link); + seat->drag_focus_resource = NULL; + seat->drag_focus = NULL; + } + + if (!surface) + return; + + if (!seat->drag_data_source && + wl_resource_get_client (surface->resource) != seat->drag_client) + return; + + resource = + wl_resource_find_for_client (&seat->drag_resource_list, + wl_resource_get_client (surface->resource)); + if (!resource) + return; + + display = wl_client_get_display (wl_resource_get_client (resource)); + serial = wl_display_next_serial (display); + + if (seat->drag_data_source) + offer = meta_wayland_data_source_send_offer (seat->drag_data_source, + resource); + + wl_data_device_send_enter (resource, serial, surface->resource, + x, y, offer); + + seat->drag_focus = surface; + seat->drag_focus_listener.notify = destroy_drag_focus; + wl_resource_add_destroy_listener (resource, &seat->drag_focus_listener); + seat->drag_focus_resource = resource; + grab->focus = surface; +} + +static void +drag_grab_motion (MetaWaylandPointerGrab *grab, + guint32 time, wl_fixed_t x, wl_fixed_t y) +{ + MetaWaylandSeat *seat = wl_container_of (grab, seat, drag_grab); + + if (seat->drag_focus_resource) + wl_data_device_send_motion (seat->drag_focus_resource, time, x, y); +} + +static void +data_device_end_drag_grab (MetaWaylandSeat *seat) +{ + if (seat->drag_surface) + { + seat->drag_surface = NULL; + wl_signal_emit (&seat->drag_icon_signal, NULL); + wl_list_remove (&seat->drag_icon_listener.link); + } + + drag_grab_focus (&seat->drag_grab, NULL, + wl_fixed_from_int (0), wl_fixed_from_int (0)); + + meta_wayland_pointer_end_grab (&seat->pointer); + + seat->drag_data_source = NULL; + seat->drag_client = NULL; +} + +static void +drag_grab_button (MetaWaylandPointerGrab *grab, + guint32 time, guint32 button, guint32 state_w) +{ + MetaWaylandSeat *seat = wl_container_of (grab, seat, drag_grab); + enum wl_pointer_button_state state = state_w; + + if (seat->drag_focus_resource && + seat->pointer.grab_button == button && + state == WL_POINTER_BUTTON_STATE_RELEASED) + wl_data_device_send_drop (seat->drag_focus_resource); + + if (seat->pointer.button_count == 0 && + state == WL_POINTER_BUTTON_STATE_RELEASED) + { + if (seat->drag_data_source) + wl_list_remove (&seat->drag_data_source_listener.link); + data_device_end_drag_grab (seat); + } +} + +static const MetaWaylandPointerGrabInterface drag_grab_interface = { + drag_grab_focus, + drag_grab_motion, + drag_grab_button, +}; + +static void +destroy_data_device_source (struct wl_listener *listener, void *data) +{ + MetaWaylandSeat *seat = + wl_container_of (listener, seat, drag_data_source_listener); + + data_device_end_drag_grab (seat); +} + +static void +destroy_data_device_icon (struct wl_listener *listener, void *data) +{ + MetaWaylandSeat *seat = + wl_container_of (listener, seat, drag_icon_listener); + + seat->drag_surface = NULL; +} + +static void +data_device_start_drag (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *source_resource, + struct wl_resource *origin_resource, + struct wl_resource *icon_resource, guint32 serial) +{ + MetaWaylandSeat *seat = wl_resource_get_user_data (resource); + + /* FIXME: Check that client has implicit grab on the origin + * surface that matches the given time. */ + + /* FIXME: Check that the data source type array isn't empty. */ + + seat->drag_grab.interface = &drag_grab_interface; + + seat->drag_client = client; + seat->drag_data_source = NULL; + + if (source_resource) + { + seat->drag_data_source = wl_resource_get_user_data (source_resource); + seat->drag_data_source_listener.notify = destroy_data_device_source; + wl_resource_add_destroy_listener (source_resource, + &seat->drag_data_source_listener); + } + + if (icon_resource) + { + seat->drag_surface = wl_resource_get_user_data (icon_resource); + seat->drag_icon_listener.notify = destroy_data_device_icon; + wl_resource_add_destroy_listener (icon_resource, + &seat->drag_icon_listener); + wl_signal_emit (&seat->drag_icon_signal, icon_resource); + } + + meta_wayland_pointer_set_focus (&seat->pointer, NULL, + wl_fixed_from_int (0), + wl_fixed_from_int (0)); + meta_wayland_pointer_start_grab (&seat->pointer, &seat->drag_grab); +} + +static void +destroy_selection_data_source (struct wl_listener *listener, void *data) +{ + MetaWaylandSeat *seat = + wl_container_of (listener, seat, selection_data_source_listener); + struct wl_resource *data_device; + struct wl_resource *focus = NULL; + + seat->selection_data_source = NULL; + + focus = seat->keyboard.focus_resource; + + if (focus) + { + data_device = + wl_resource_find_for_client (&seat->drag_resource_list, + wl_resource_get_client (focus)); + if (data_device) + wl_data_device_send_selection (data_device, NULL); + } + + wl_signal_emit (&seat->selection_signal, seat); +} + +void +meta_wayland_seat_set_selection (MetaWaylandSeat *seat, + MetaWaylandDataSource *source, + guint32 serial) +{ + struct wl_resource *data_device, *offer; + struct wl_resource *focus = NULL; + + if (seat->selection_data_source && + seat->selection_serial - serial < UINT32_MAX / 2) + return; + + if (seat->selection_data_source) + { + seat->selection_data_source->cancel (seat->selection_data_source); + wl_list_remove (&seat->selection_data_source_listener.link); + seat->selection_data_source = NULL; + } + + seat->selection_data_source = source; + seat->selection_serial = serial; + + focus = seat->keyboard.focus_resource; + + if (focus) + { + data_device = + wl_resource_find_for_client (&seat->drag_resource_list, + wl_resource_get_client (focus)); + if (data_device && source) + { + offer = + meta_wayland_data_source_send_offer (seat->selection_data_source, + data_device); + wl_data_device_send_selection (data_device, offer); + } + else if (data_device) + { + wl_data_device_send_selection (data_device, NULL); + } + } + + wl_signal_emit (&seat->selection_signal, seat); + + if (source) + { + seat->selection_data_source_listener.notify = + destroy_selection_data_source; + wl_resource_add_destroy_listener (source->resource, + &seat->selection_data_source_listener); + } +} + +static void +data_device_set_selection (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *source_resource, + guint32 serial) +{ + if (!source_resource) + return; + + /* FIXME: Store serial and check against incoming serial here. */ + meta_wayland_seat_set_selection (wl_resource_get_user_data (resource), + wl_resource_get_user_data (source_resource), + serial); +} + +static const struct wl_data_device_interface data_device_interface = { + data_device_start_drag, + data_device_set_selection, +}; + +static void +destroy_data_source (struct wl_resource *resource) +{ + MetaWaylandDataSource *source = wl_container_of (resource, source, resource); + char **p; + + wl_array_for_each (p, &source->mime_types) free (*p); + + wl_array_release (&source->mime_types); +} + +static void +client_source_accept (MetaWaylandDataSource *source, + guint32 time, const char *mime_type) +{ + wl_data_source_send_target (source->resource, mime_type); +} + +static void +client_source_send (MetaWaylandDataSource *source, + const char *mime_type, int32_t fd) +{ + wl_data_source_send_send (source->resource, mime_type, fd); + close (fd); +} + +static void +client_source_cancel (MetaWaylandDataSource *source) +{ + wl_data_source_send_cancelled (source->resource); +} + +static void +create_data_source (struct wl_client *client, + struct wl_resource *resource, guint32 id) +{ + MetaWaylandDataSource *source; + + source = malloc (sizeof *source); + if (source == NULL) + { + wl_resource_post_no_memory (resource); + return; + } + + source->resource = wl_client_add_object (client, + &wl_data_source_interface, + &data_source_interface, + id, + source); + wl_resource_set_destructor (source->resource, destroy_data_source); + + source->accept = client_source_accept; + source->send = client_source_send; + source->cancel = client_source_cancel; + + wl_array_init (&source->mime_types); +} + +static void +unbind_data_device (struct wl_resource *resource) +{ + wl_list_remove (wl_resource_get_link (resource)); +} + +static void +get_data_device (struct wl_client *client, + struct wl_resource *manager_resource, + guint32 id, struct wl_resource *seat_resource) +{ + MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); + struct wl_resource *resource; + + resource = wl_client_add_object (client, &wl_data_device_interface, + &data_device_interface, id, seat); + + wl_list_insert (&seat->drag_resource_list, wl_resource_get_link (resource)); + wl_resource_set_destructor (resource, unbind_data_device); +} + +static const struct wl_data_device_manager_interface manager_interface = { + create_data_source, + get_data_device +}; + +static void +bind_manager (struct wl_client *client, + void *data, guint32 version, guint32 id) +{ + wl_client_add_object (client, &wl_data_device_manager_interface, + &manager_interface, id, NULL); +} + +void +meta_wayland_data_device_set_keyboard_focus (MetaWaylandSeat *seat) +{ + struct wl_resource *data_device, *focus, *offer; + MetaWaylandDataSource *source; + + focus = seat->keyboard.focus_resource; + if (!focus) + return; + + data_device = wl_resource_find_for_client (&seat->drag_resource_list, + wl_resource_get_client (focus)); + if (!data_device) + return; + + source = seat->selection_data_source; + if (source) + { + offer = meta_wayland_data_source_send_offer (source, data_device); + wl_data_device_send_selection (data_device, offer); + } +} + +int +meta_wayland_data_device_manager_init (struct wl_display *display) +{ + if (wl_display_add_global (display, + &wl_data_device_manager_interface, + NULL, bind_manager) == NULL) + return -1; + + return 0; +} diff --git a/src/wayland/meta-wayland-data-device.h b/src/wayland/meta-wayland-data-device.h new file mode 100644 index 000000000..58635531c --- /dev/null +++ b/src/wayland/meta-wayland-data-device.h @@ -0,0 +1,42 @@ +/* + * Copyright © 2008 Kristian Høgsberg + * + * 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 the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS 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. + */ + +#ifndef __META_WAYLAND_DATA_DEVICE_H__ +#define __META_WAYLAND_DATA_DEVICE_H__ + +#include + +#include "meta-wayland-seat.h" + +void +meta_wayland_data_device_set_keyboard_focus (MetaWaylandSeat *seat); + +int +meta_wayland_data_device_manager_init (struct wl_display *display); + +void +meta_wayland_seat_set_selection (MetaWaylandSeat *seat, + MetaWaylandDataSource *source, + uint32_t serial); + + +#endif /* __META_WAYLAND_DATA_DEVICE_H__ */ diff --git a/src/wayland/meta-wayland-keyboard.c b/src/wayland/meta-wayland-keyboard.c new file mode 100644 index 000000000..c43de914e --- /dev/null +++ b/src/wayland/meta-wayland-keyboard.c @@ -0,0 +1,512 @@ +/* + * Wayland Support + * + * Copyright (C) 2013 Intel Corporation + * + * 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. + */ + +/* + * Copyright © 2010-2011 Intel Corporation + * Copyright © 2008-2011 Kristian Høgsberg + * Copyright © 2012 Collabora, Ltd. + * + * 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 the copyright holders not be used in + * advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. The copyright holders make + * no representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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. + */ + +/* The file is based on src/input.c from Weston */ + +#define _GNU_SOURCE + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "meta-wayland-keyboard.h" + +static MetaWaylandSeat * +meta_wayland_keyboard_get_seat (MetaWaylandKeyboard *keyboard) +{ + MetaWaylandSeat *seat = wl_container_of (keyboard, seat, keyboard); + + return seat; +} + +static int +create_anonymous_file (off_t size, + GError **error) +{ + static const char template[] = "mutter-shared-XXXXXX"; + char *path; + int fd, flags; + + fd = g_file_open_tmp (template, &path, error); + + if (fd == -1) + return -1; + + unlink (path); + g_free (path); + + flags = fcntl (fd, F_GETFD); + if (flags == -1) + goto err; + + if (fcntl (fd, F_SETFD, flags | FD_CLOEXEC) == -1) + goto err; + + if (ftruncate (fd, size) < 0) + goto err; + + return fd; + + err: + g_set_error_literal (error, + G_FILE_ERROR, + g_file_error_from_errno (errno), + strerror (errno)); + close (fd); + + return -1; +} + +static gboolean +meta_wayland_xkb_info_new_keymap (MetaWaylandXkbInfo *xkb_info) +{ + GError *error = NULL; + char *keymap_str; + + xkb_info->shift_mod = + xkb_map_mod_get_index (xkb_info->keymap, XKB_MOD_NAME_SHIFT); + xkb_info->caps_mod = + xkb_map_mod_get_index (xkb_info->keymap, XKB_MOD_NAME_CAPS); + xkb_info->ctrl_mod = + xkb_map_mod_get_index (xkb_info->keymap, XKB_MOD_NAME_CTRL); + xkb_info->alt_mod = + xkb_map_mod_get_index (xkb_info->keymap, XKB_MOD_NAME_ALT); + xkb_info->mod2_mod = xkb_map_mod_get_index (xkb_info->keymap, "Mod2"); + xkb_info->mod3_mod = xkb_map_mod_get_index (xkb_info->keymap, "Mod3"); + xkb_info->super_mod = + xkb_map_mod_get_index (xkb_info->keymap, XKB_MOD_NAME_LOGO); + xkb_info->mod5_mod = xkb_map_mod_get_index (xkb_info->keymap, "Mod5"); + + keymap_str = xkb_map_get_as_string (xkb_info->keymap); + if (keymap_str == NULL) + { + g_warning ("failed to get string version of keymap\n"); + return FALSE; + } + xkb_info->keymap_size = strlen (keymap_str) + 1; + + xkb_info->keymap_fd = create_anonymous_file (xkb_info->keymap_size, &error); + if (xkb_info->keymap_fd < 0) + { + g_warning ("creating a keymap file for %lu bytes failed: %s\n", + (unsigned long) xkb_info->keymap_size, + error->message); + g_clear_error (&error); + goto err_keymap_str; + } + + xkb_info->keymap_area = mmap (NULL, xkb_info->keymap_size, + PROT_READ | PROT_WRITE, + MAP_SHARED, xkb_info->keymap_fd, 0); + if (xkb_info->keymap_area == MAP_FAILED) + { + g_warning ("failed to mmap() %lu bytes\n", + (unsigned long) xkb_info->keymap_size); + goto err_dev_zero; + } + strcpy (xkb_info->keymap_area, keymap_str); + free (keymap_str); + + return TRUE; + +err_dev_zero: + close (xkb_info->keymap_fd); + xkb_info->keymap_fd = -1; +err_keymap_str: + free (keymap_str); + return FALSE; +} + +static gboolean +meta_wayland_keyboard_build_global_keymap (struct xkb_context *xkb_context, + struct xkb_rule_names *xkb_names, + MetaWaylandXkbInfo *xkb_info) +{ + xkb_info->keymap = xkb_map_new_from_names (xkb_context, + xkb_names, + 0 /* flags */); + if (xkb_info->keymap == NULL) + { + g_warning ("failed to compile global XKB keymap\n" + " tried rules %s, model %s, layout %s, variant %s, " + "options %s\n", + xkb_names->rules, + xkb_names->model, + xkb_names->layout, + xkb_names->variant, + xkb_names->options); + return FALSE; + } + + if (!meta_wayland_xkb_info_new_keymap (xkb_info)) + return FALSE; + + return TRUE; +} + +static void +lose_keyboard_focus (struct wl_listener *listener, void *data) +{ + MetaWaylandKeyboard *keyboard = + wl_container_of (listener, keyboard, focus_listener); + + keyboard->focus_resource = NULL; +} + +static void +default_grab_key (MetaWaylandKeyboardGrab *grab, + uint32_t time, uint32_t key, uint32_t state) +{ + MetaWaylandKeyboard *keyboard = grab->keyboard; + struct wl_resource *resource; + uint32_t serial; + + resource = keyboard->focus_resource; + if (resource) + { + struct wl_client *client = wl_resource_get_client (resource); + struct wl_display *display = wl_client_get_display (client); + serial = wl_display_next_serial (display); + wl_keyboard_send_key (resource, serial, time, key, state); + } +} + +static struct wl_resource * +find_resource_for_surface (struct wl_list *list, MetaWaylandSurface *surface) +{ + struct wl_client *client; + + if (!surface) + return NULL; + + if (!surface->resource) + return NULL; + + client = wl_resource_get_client (surface->resource); + + return wl_resource_find_for_client (list, client); +} + +static void +default_grab_modifiers (MetaWaylandKeyboardGrab *grab, uint32_t serial, + uint32_t mods_depressed, uint32_t mods_latched, + uint32_t mods_locked, uint32_t group) +{ + MetaWaylandKeyboard *keyboard = grab->keyboard; + MetaWaylandSeat *seat = meta_wayland_keyboard_get_seat (keyboard); + MetaWaylandPointer *pointer = &seat->pointer; + struct wl_resource *resource, *pr; + + resource = keyboard->focus_resource; + if (!resource) + return; + + wl_keyboard_send_modifiers (resource, serial, mods_depressed, + mods_latched, mods_locked, group); + + if (pointer && pointer->focus && pointer->focus != keyboard->focus) + { + pr = find_resource_for_surface (&keyboard->resource_list, + pointer->focus); + if (pr) + { + wl_keyboard_send_modifiers (pr, + serial, + keyboard->modifiers.mods_depressed, + keyboard->modifiers.mods_latched, + keyboard->modifiers.mods_locked, + keyboard->modifiers.group); + } + } +} + +static const MetaWaylandKeyboardGrabInterface + default_keyboard_grab_interface = { + default_grab_key, + default_grab_modifiers, +}; + +gboolean +meta_wayland_keyboard_init (MetaWaylandKeyboard *keyboard, + struct wl_display *display) +{ + memset (keyboard, 0, sizeof *keyboard); + + wl_list_init (&keyboard->resource_list); + wl_array_init (&keyboard->keys); + keyboard->focus_listener.notify = lose_keyboard_focus; + keyboard->default_grab.interface = &default_keyboard_grab_interface; + keyboard->default_grab.keyboard = keyboard; + keyboard->grab = &keyboard->default_grab; + wl_signal_init (&keyboard->focus_signal); + + keyboard->display = display; + + keyboard->xkb_context = xkb_context_new (0 /* flags */); + + meta_wayland_keyboard_build_global_keymap (keyboard->xkb_context, + &keyboard->xkb_names, + &keyboard->xkb_info); + + return TRUE; +} + +static void +meta_wayland_xkb_info_destroy (MetaWaylandXkbInfo *xkb_info) +{ + if (xkb_info->keymap) + xkb_map_unref (xkb_info->keymap); + + if (xkb_info->keymap_area) + munmap (xkb_info->keymap_area, xkb_info->keymap_size); + if (xkb_info->keymap_fd >= 0) + close (xkb_info->keymap_fd); +} + +static void +set_modifiers (MetaWaylandKeyboard *keyboard, + guint32 serial, + ClutterModifierType modifier_state) +{ + MetaWaylandKeyboardGrab *grab = keyboard->grab; + uint32_t depressed_mods = 0; + uint32_t locked_mods = 0; + + if (keyboard->last_modifier_state == modifier_state) + return; + + if ((modifier_state & CLUTTER_SHIFT_MASK) && + keyboard->xkb_info.shift_mod != XKB_MOD_INVALID) + depressed_mods |= (1 << keyboard->xkb_info.shift_mod); + + if ((modifier_state & CLUTTER_LOCK_MASK) && + keyboard->xkb_info.caps_mod != XKB_MOD_INVALID) + locked_mods |= (1 << keyboard->xkb_info.caps_mod); + + if ((modifier_state & CLUTTER_CONTROL_MASK) && + keyboard->xkb_info.ctrl_mod != XKB_MOD_INVALID) + depressed_mods |= (1 << keyboard->xkb_info.ctrl_mod); + + if ((modifier_state & CLUTTER_MOD1_MASK) && + keyboard->xkb_info.alt_mod != XKB_MOD_INVALID) + depressed_mods |= (1 << keyboard->xkb_info.alt_mod); + + if ((modifier_state & CLUTTER_MOD2_MASK) && + keyboard->xkb_info.mod2_mod != XKB_MOD_INVALID) + depressed_mods |= (1 << keyboard->xkb_info.mod2_mod); + + if ((modifier_state & CLUTTER_MOD3_MASK) && + keyboard->xkb_info.mod3_mod != XKB_MOD_INVALID) + depressed_mods |= (1 << keyboard->xkb_info.mod3_mod); + + if ((modifier_state & CLUTTER_SUPER_MASK) && + keyboard->xkb_info.super_mod != XKB_MOD_INVALID) + depressed_mods |= (1 << keyboard->xkb_info.super_mod); + + if ((modifier_state & CLUTTER_MOD5_MASK) && + keyboard->xkb_info.mod5_mod != XKB_MOD_INVALID) + depressed_mods |= (1 << keyboard->xkb_info.mod5_mod); + + keyboard->last_modifier_state = modifier_state; + + grab->interface->modifiers (grab, + serial, + depressed_mods, + 0, /* latched_modes */ + locked_mods, + 0 /* group */); +} + +void +meta_wayland_keyboard_handle_event (MetaWaylandKeyboard *keyboard, + const ClutterKeyEvent *event) +{ + gboolean state = event->type == CLUTTER_KEY_PRESS; + guint evdev_code; + uint32_t serial; + + /* We can't do anything with the event if we can't get an evdev + keycode for it */ + if (event->device == NULL || + !clutter_input_device_keycode_to_evdev (event->device, + event->hardware_keycode, + &evdev_code)) + return; + + /* We want to ignore events that are sent because of auto-repeat. In + the Clutter event stream these appear as a single key press + event. We can detect that because the key will already have been + pressed */ + if (state) + { + uint32_t *end = (void *) ((char *) keyboard->keys.data + + keyboard->keys.size); + uint32_t *k; + + /* Ignore the event if the key is already down */ + for (k = keyboard->keys.data; k < end; k++) + if (*k == evdev_code) + return; + + /* Otherwise add the key to the list of pressed keys */ + k = wl_array_add (&keyboard->keys, sizeof (*k)); + *k = evdev_code; + } + else + { + uint32_t *end = (void *) ((char *) keyboard->keys.data + + keyboard->keys.size); + uint32_t *k; + + /* Remove the key from the array */ + for (k = keyboard->keys.data; k < end; k++) + if (*k == evdev_code) + { + *k = *(end - 1); + keyboard->keys.size -= sizeof (*k); + + goto found; + } + + g_warning ("unexpected key release event for key 0x%x", evdev_code); + + found: + (void) 0; + } + + serial = wl_display_next_serial (keyboard->display); + + set_modifiers (keyboard, serial, event->modifier_state); + + keyboard->grab->interface->key (keyboard->grab, + event->time, + evdev_code, + state); +} + +void +meta_wayland_keyboard_set_focus (MetaWaylandKeyboard *keyboard, + MetaWaylandSurface *surface) +{ + struct wl_resource *resource; + uint32_t serial; + + if (keyboard->focus_resource && keyboard->focus != surface) + { + struct wl_display *display; + struct wl_client *client; + + resource = keyboard->focus_resource; + client = wl_resource_get_client (resource); + display = wl_client_get_display (client); + serial = wl_display_next_serial (display); + wl_keyboard_send_leave (resource, serial, keyboard->focus->resource); + wl_list_remove (&keyboard->focus_listener.link); + } + + resource = find_resource_for_surface (&keyboard->resource_list, surface); + if (resource && + (keyboard->focus != surface || keyboard->focus_resource != resource)) + { + struct wl_client *client = wl_resource_get_client (resource); + struct wl_display *display; + + display = wl_client_get_display (client); + serial = wl_display_next_serial (display); + wl_keyboard_send_modifiers (resource, serial, + keyboard->modifiers.mods_depressed, + keyboard->modifiers.mods_latched, + keyboard->modifiers.mods_locked, + keyboard->modifiers.group); + wl_keyboard_send_enter (resource, serial, surface->resource, + &keyboard->keys); + wl_resource_add_destroy_listener (resource, &keyboard->focus_listener); + keyboard->focus_serial = serial; + } + + keyboard->focus_resource = resource; + keyboard->focus = surface; + wl_signal_emit (&keyboard->focus_signal, keyboard); +} + +void +meta_wayland_keyboard_start_grab (MetaWaylandKeyboard *keyboard, + MetaWaylandKeyboardGrab *grab) +{ + keyboard->grab = grab; + grab->keyboard = keyboard; + + /* XXX focus? */ +} + +void +meta_wayland_keyboard_end_grab (MetaWaylandKeyboard *keyboard) +{ + keyboard->grab = &keyboard->default_grab; +} + +void +meta_wayland_keyboard_release (MetaWaylandKeyboard *keyboard) +{ + g_free ((char *) keyboard->xkb_names.rules); + g_free ((char *) keyboard->xkb_names.model); + g_free ((char *) keyboard->xkb_names.layout); + g_free ((char *) keyboard->xkb_names.variant); + g_free ((char *) keyboard->xkb_names.options); + + meta_wayland_xkb_info_destroy (&keyboard->xkb_info); + xkb_context_unref (keyboard->xkb_context); + + /* XXX: What about keyboard->resource_list? */ + if (keyboard->focus_resource) + wl_list_remove (&keyboard->focus_listener.link); + wl_array_release (&keyboard->keys); +} diff --git a/src/wayland/meta-wayland-keyboard.h b/src/wayland/meta-wayland-keyboard.h new file mode 100644 index 000000000..fd0d0b3c0 --- /dev/null +++ b/src/wayland/meta-wayland-keyboard.h @@ -0,0 +1,75 @@ +/* + * Wayland Support + * + * Copyright (C) 2013 Intel Corporation + * + * 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. + */ + +/* + * Copyright © 2008-2011 Kristian Høgsberg + * Copyright © 2012 Collabora, Ltd. + * + * 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 the copyright holders not be used in + * advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. The copyright holders make + * no representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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. + */ + +#ifndef __META_WAYLAND_KEYBOARD_H__ +#define __META_WAYLAND_KEYBOARD_H__ + +#include +#include + +#include "meta-wayland-seat.h" + +gboolean +meta_wayland_keyboard_init (MetaWaylandKeyboard *keyboard, + struct wl_display *display); + +void +meta_wayland_keyboard_handle_event (MetaWaylandKeyboard *keyboard, + const ClutterKeyEvent *event); + +void +meta_wayland_keyboard_set_focus (MetaWaylandKeyboard *keyboard, + MetaWaylandSurface *surface); + +void +meta_wayland_keyboard_start_grab (MetaWaylandKeyboard *device, + MetaWaylandKeyboardGrab *grab); + +void +meta_wayland_keyboard_end_grab (MetaWaylandKeyboard *keyboard); + +void +meta_wayland_keyboard_release (MetaWaylandKeyboard *keyboard); + +#endif /* __META_WAYLAND_KEYBOARD_H__ */ diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c new file mode 100644 index 000000000..52a81ad7e --- /dev/null +++ b/src/wayland/meta-wayland-pointer.c @@ -0,0 +1,260 @@ +/* + * Wayland Support + * + * Copyright (C) 2013 Intel Corporation + * + * 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 . + */ + +/* + * Copyright © 2008 Kristian Høgsberg + * + * 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 the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS 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. + */ + +/* The file is based on src/input.c from Weston */ + +#include "config.h" + +#include "meta-wayland-pointer.h" + +static MetaWaylandSeat * +meta_wayland_pointer_get_seat (MetaWaylandPointer *pointer) +{ + MetaWaylandSeat *seat = wl_container_of (pointer, seat, pointer); + + return seat; +} + +static void +lose_pointer_focus (struct wl_listener *listener, void *data) +{ + MetaWaylandPointer *pointer = + wl_container_of (listener, pointer, focus_listener); + + pointer->focus_resource = NULL; +} + +static void +default_grab_focus (MetaWaylandPointerGrab *grab, + MetaWaylandSurface *surface, + wl_fixed_t x, + wl_fixed_t y) +{ + MetaWaylandPointer *pointer = grab->pointer; + + if (pointer->button_count > 0) + return; + + meta_wayland_pointer_set_focus (pointer, surface, x, y); +} + +static void +default_grab_motion (MetaWaylandPointerGrab *grab, + uint32_t time, wl_fixed_t x, wl_fixed_t y) +{ + struct wl_resource *resource; + + resource = grab->pointer->focus_resource; + if (resource) + wl_pointer_send_motion (resource, time, x, y); +} + +static void +default_grab_button (MetaWaylandPointerGrab *grab, + uint32_t time, uint32_t button, uint32_t state_w) +{ + MetaWaylandPointer *pointer = grab->pointer; + struct wl_resource *resource; + uint32_t serial; + enum wl_pointer_button_state state = state_w; + + resource = pointer->focus_resource; + if (resource) + { + struct wl_client *client = wl_resource_get_client (resource); + struct wl_display *display = wl_client_get_display (client); + serial = wl_display_next_serial (display); + wl_pointer_send_button (resource, serial, time, button, state_w); + } + + if (pointer->button_count == 0 && state == WL_POINTER_BUTTON_STATE_RELEASED) + meta_wayland_pointer_set_focus (pointer, pointer->current, + pointer->current_x, pointer->current_y); +} + +static const MetaWaylandPointerGrabInterface default_pointer_grab_interface = { + default_grab_focus, + default_grab_motion, + default_grab_button +}; + +void +meta_wayland_pointer_init (MetaWaylandPointer *pointer) +{ + memset (pointer, 0, sizeof *pointer); + wl_list_init (&pointer->resource_list); + pointer->focus_listener.notify = lose_pointer_focus; + pointer->default_grab.interface = &default_pointer_grab_interface; + pointer->default_grab.pointer = pointer; + pointer->grab = &pointer->default_grab; + wl_signal_init (&pointer->focus_signal); + + /* FIXME: Pick better co-ords. */ + pointer->x = wl_fixed_from_int (100); + pointer->y = wl_fixed_from_int (100); +} + +void +meta_wayland_pointer_release (MetaWaylandPointer *pointer) +{ + /* XXX: What about pointer->resource_list? */ + if (pointer->focus_resource) + wl_list_remove (&pointer->focus_listener.link); +} + +static struct wl_resource * +find_resource_for_surface (struct wl_list *list, MetaWaylandSurface *surface) +{ + struct wl_client *client; + + if (!surface) + return NULL; + + if (!surface->resource) + return NULL; + + client = wl_resource_get_client (surface->resource); + + return wl_resource_find_for_client (list, client); +} + +void +meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer, + MetaWaylandSurface *surface, + wl_fixed_t sx, wl_fixed_t sy) +{ + MetaWaylandSeat *seat = meta_wayland_pointer_get_seat (pointer); + MetaWaylandKeyboard *kbd = &seat->keyboard; + struct wl_resource *resource, *kr; + uint32_t serial; + + resource = pointer->focus_resource; + if (resource && pointer->focus != surface) + { + struct wl_client *client = wl_resource_get_client (resource); + struct wl_display *display = wl_client_get_display (client); + serial = wl_display_next_serial (display); + wl_pointer_send_leave (resource, serial, pointer->focus->resource); + wl_list_remove (&pointer->focus_listener.link); + } + + resource = find_resource_for_surface (&pointer->resource_list, surface); + if (resource && + (pointer->focus != surface || pointer->focus_resource != resource)) + { + struct wl_client *client = wl_resource_get_client (resource); + struct wl_display *display = wl_client_get_display (client); + serial = wl_display_next_serial (display); + if (kbd) + { + kr = find_resource_for_surface (&kbd->resource_list, surface); + if (kr) + { + wl_keyboard_send_modifiers (kr, + serial, + kbd->modifiers.mods_depressed, + kbd->modifiers.mods_latched, + kbd->modifiers.mods_locked, + kbd->modifiers.group); + } + } + wl_pointer_send_enter (resource, serial, surface->resource, sx, sy); + wl_resource_add_destroy_listener (resource, &pointer->focus_listener); + pointer->focus_serial = serial; + } + + pointer->focus_resource = resource; + pointer->focus = surface; + pointer->default_grab.focus = surface; + wl_signal_emit (&pointer->focus_signal, pointer); +} + +void +meta_wayland_pointer_start_grab (MetaWaylandPointer *pointer, + MetaWaylandPointerGrab *grab) +{ + const MetaWaylandPointerGrabInterface *interface; + + pointer->grab = grab; + interface = pointer->grab->interface; + grab->pointer = pointer; + + if (pointer->current) + interface->focus (pointer->grab, pointer->current, + pointer->current_x, pointer->current_y); +} + +void +meta_wayland_pointer_end_grab (MetaWaylandPointer *pointer) +{ + const MetaWaylandPointerGrabInterface *interface; + + pointer->grab = &pointer->default_grab; + interface = pointer->grab->interface; + interface->focus (pointer->grab, pointer->current, + pointer->current_x, pointer->current_y); +} + +static void +current_surface_destroy (struct wl_listener *listener, void *data) +{ + MetaWaylandPointer *pointer = + wl_container_of (listener, pointer, current_listener); + + pointer->current = NULL; +} + +void +meta_wayland_pointer_set_current (MetaWaylandPointer *pointer, + MetaWaylandSurface *surface) +{ + if (pointer->current) + wl_list_remove (&pointer->current_listener.link); + + pointer->current = surface; + + if (!surface) + return; + + wl_resource_add_destroy_listener (surface->resource, + &pointer->current_listener); + pointer->current_listener.notify = current_surface_destroy; +} diff --git a/src/wayland/meta-wayland-pointer.h b/src/wayland/meta-wayland-pointer.h new file mode 100644 index 000000000..a1e5f3854 --- /dev/null +++ b/src/wayland/meta-wayland-pointer.h @@ -0,0 +1,49 @@ +/* + * Wayland Support + * + * Copyright (C) 2013 Intel Corporation + * + * 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 __META_WAYLAND_POINTER_H__ +#define __META_WAYLAND_POINTER_H__ + +#include + +#include "meta-wayland-seat.h" + +void +meta_wayland_pointer_init (MetaWaylandPointer *pointer); + +void +meta_wayland_pointer_release (MetaWaylandPointer *pointer); + +void +meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer, + MetaWaylandSurface *surface, + wl_fixed_t sx, + wl_fixed_t sy); +void +meta_wayland_pointer_start_grab (MetaWaylandPointer *pointer, + MetaWaylandPointerGrab *grab); + +void +meta_wayland_pointer_end_grab (MetaWaylandPointer *pointer); + +void +meta_wayland_pointer_set_current (MetaWaylandPointer *pointer, + MetaWaylandSurface *surface); + +#endif /* __META_WAYLAND_POINTER_H__ */ diff --git a/src/wayland/meta-wayland-private.h b/src/wayland/meta-wayland-private.h index 59cc6d678..c33f7f943 100644 --- a/src/wayland/meta-wayland-private.h +++ b/src/wayland/meta-wayland-private.h @@ -21,7 +21,7 @@ #define META_WAYLAND_PRIVATE_H #include - +#include #include #include @@ -31,6 +31,16 @@ typedef struct _MetaWaylandCompositor MetaWaylandCompositor; +typedef struct _MetaWaylandSeat MetaWaylandSeat; +typedef struct _MetaWaylandPointer MetaWaylandPointer; +typedef struct _MetaWaylandPointerGrab MetaWaylandPointerGrab; +typedef struct _MetaWaylandPointerGrabInterface MetaWaylandPointerGrabInterface; +typedef struct _MetaWaylandKeyboard MetaWaylandKeyboard; +typedef struct _MetaWaylandKeyboardGrab MetaWaylandKeyboardGrab; +typedef struct _MetaWaylandKeyboardGrabInterface MetaWaylandKeyboardGrabInterface; +typedef struct _MetaWaylandDataOffer MetaWaylandDataOffer; +typedef struct _MetaWaylandDataSource MetaWaylandDataSource; + typedef struct { struct wl_resource *resource; @@ -155,17 +165,198 @@ struct _MetaWaylandCompositor struct wl_client *xwayland_client; struct wl_resource *xserver_resource; GHashTable *window_surfaces; + + MetaWaylandSeat *seat; + + /* This surface is only used to keep drag of the implicit grab when + synthesizing XEvents for Mutter */ + MetaWaylandSurface *implicit_grab_surface; + /* Button that was pressed to initiate an implicit grab. The + implicit grab will only be released when this button is + released */ + guint32 implicit_grab_button; }; -void meta_wayland_init (void); -void meta_wayland_finalize (void); +struct _MetaWaylandPointerGrabInterface +{ + void (*focus) (MetaWaylandPointerGrab * grab, + MetaWaylandSurface * surface, wl_fixed_t x, wl_fixed_t y); + void (*motion) (MetaWaylandPointerGrab * grab, + uint32_t time, wl_fixed_t x, wl_fixed_t y); + void (*button) (MetaWaylandPointerGrab * grab, + uint32_t time, uint32_t button, uint32_t state); +}; + +struct _MetaWaylandPointerGrab +{ + const MetaWaylandPointerGrabInterface *interface; + MetaWaylandPointer *pointer; + MetaWaylandSurface *focus; + wl_fixed_t x, y; +}; + +struct _MetaWaylandPointer +{ + struct wl_list resource_list; + MetaWaylandSurface *focus; + struct wl_resource *focus_resource; + struct wl_listener focus_listener; + guint32 focus_serial; + struct wl_signal focus_signal; + + MetaWaylandPointerGrab *grab; + MetaWaylandPointerGrab default_grab; + wl_fixed_t grab_x, grab_y; + guint32 grab_button; + guint32 grab_serial; + guint32 grab_time; + + wl_fixed_t x, y; + MetaWaylandSurface *current; + struct wl_listener current_listener; + wl_fixed_t current_x, current_y; + + guint32 button_count; +}; + +struct _MetaWaylandKeyboardGrabInterface +{ + void (*key) (MetaWaylandKeyboardGrab * grab, uint32_t time, + uint32_t key, uint32_t state); + void (*modifiers) (MetaWaylandKeyboardGrab * grab, uint32_t serial, + uint32_t mods_depressed, uint32_t mods_latched, + uint32_t mods_locked, uint32_t group); +}; + +struct _MetaWaylandKeyboardGrab +{ + const MetaWaylandKeyboardGrabInterface *interface; + MetaWaylandKeyboard *keyboard; + MetaWaylandSurface *focus; + uint32_t key; +}; + +typedef struct +{ + struct xkb_keymap *keymap; + int keymap_fd; + size_t keymap_size; + char *keymap_area; + xkb_mod_index_t shift_mod; + xkb_mod_index_t caps_mod; + xkb_mod_index_t ctrl_mod; + xkb_mod_index_t alt_mod; + xkb_mod_index_t mod2_mod; + xkb_mod_index_t mod3_mod; + xkb_mod_index_t super_mod; + xkb_mod_index_t mod5_mod; +} MetaWaylandXkbInfo; + +struct _MetaWaylandKeyboard +{ + struct wl_list resource_list; + MetaWaylandSurface *focus; + struct wl_resource *focus_resource; + struct wl_listener focus_listener; + uint32_t focus_serial; + struct wl_signal focus_signal; + + MetaWaylandKeyboardGrab *grab; + MetaWaylandKeyboardGrab default_grab; + uint32_t grab_key; + uint32_t grab_serial; + uint32_t grab_time; + + struct wl_array keys; + + struct + { + uint32_t mods_depressed; + uint32_t mods_latched; + uint32_t mods_locked; + uint32_t group; + } modifiers; + + struct wl_display *display; + + struct xkb_context *xkb_context; + + MetaWaylandXkbInfo xkb_info; + struct xkb_rule_names xkb_names; + + MetaWaylandKeyboardGrab input_method_grab; + struct wl_resource *input_method_resource; + + ClutterModifierType last_modifier_state; +}; + +struct _MetaWaylandDataOffer +{ + struct wl_resource *resource; + MetaWaylandDataSource *source; + struct wl_listener source_destroy_listener; +}; + +struct _MetaWaylandDataSource +{ + struct wl_resource *resource; + struct wl_array mime_types; + + void (*accept) (MetaWaylandDataSource * source, + uint32_t serial, const char *mime_type); + void (*send) (MetaWaylandDataSource * source, + const char *mime_type, int32_t fd); + void (*cancel) (MetaWaylandDataSource * source); +}; + +struct _MetaWaylandSeat +{ + struct wl_list base_resource_list; + struct wl_signal destroy_signal; + + uint32_t selection_serial; + MetaWaylandDataSource *selection_data_source; + struct wl_listener selection_data_source_listener; + struct wl_signal selection_signal; + + struct wl_list drag_resource_list; + struct wl_client *drag_client; + MetaWaylandDataSource *drag_data_source; + struct wl_listener drag_data_source_listener; + MetaWaylandSurface *drag_focus; + struct wl_resource *drag_focus_resource; + struct wl_listener drag_focus_listener; + MetaWaylandPointerGrab drag_grab; + MetaWaylandSurface *drag_surface; + struct wl_listener drag_icon_listener; + struct wl_signal drag_icon_signal; + + MetaWaylandPointer pointer; + MetaWaylandKeyboard keyboard; + + struct wl_display *display; + + MetaWaylandSurface *sprite; + int hotspot_x, hotspot_y; + struct wl_listener sprite_destroy_listener; + + ClutterActor *current_stage; +}; + +void meta_wayland_init (void); +void meta_wayland_finalize (void); /* We maintain a singleton MetaWaylandCompositor which can be got at via this * API after meta_wayland_init() has been called. */ -MetaWaylandCompositor *meta_wayland_compositor_get_default (void); +MetaWaylandCompositor *meta_wayland_compositor_get_default (void); -void meta_wayland_handle_sig_child (void); +void meta_wayland_handle_sig_child (void); -MetaWaylandSurface *meta_wayland_lookup_surface_for_xid (guint32 xid); +MetaWaylandSurface *meta_wayland_lookup_surface_for_xid (guint32 xid); + +void meta_wayland_compositor_repick (MetaWaylandCompositor *compositor); + +void meta_wayland_compositor_set_input_focus (MetaWaylandCompositor *compositor, + MetaWindow *window); #endif /* META_WAYLAND_PRIVATE_H */ diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c new file mode 100644 index 000000000..fb78d0920 --- /dev/null +++ b/src/wayland/meta-wayland-seat.c @@ -0,0 +1,503 @@ +/* + * Wayland Support + * + * Copyright (C) 2013 Intel Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include "meta-wayland-seat.h" +#include "meta-wayland-private.h" +#include "meta-wayland-keyboard.h" +#include "meta-wayland-pointer.h" +#include "meta-wayland-data-device.h" +#include "meta-window-actor-private.h" +#include "meta/meta-shaped-texture.h" + +#define DEFAULT_AXIS_STEP_DISTANCE wl_fixed_from_int (10) + +static void +unbind_resource (struct wl_resource *resource) +{ + wl_list_remove (wl_resource_get_link (resource)); +} + +static void +transform_stage_point_fixed (MetaWaylandSurface *surface, + wl_fixed_t x, + wl_fixed_t y, + wl_fixed_t *sx, + wl_fixed_t *sy) +{ + float xf = 0.0f, yf = 0.0f; + + if (surface->window) + { + ClutterActor *actor = + CLUTTER_ACTOR (meta_window_get_compositor_private (surface->window)); + + if (actor) + clutter_actor_transform_stage_point (actor, + wl_fixed_to_double (x), + wl_fixed_to_double (y), + &xf, &yf); + } + + *sx = wl_fixed_from_double (xf); + *sy = wl_fixed_from_double (yf); +} + +static void +pointer_unmap_sprite (MetaWaylandSeat *seat) +{ + if (seat->sprite) + { + if (seat->sprite->window) + { + GObject *window_actor_object = + meta_window_get_compositor_private (seat->sprite->window); + ClutterActor *window_actor = CLUTTER_ACTOR (window_actor_object); + + if (window_actor) + clutter_actor_hide (window_actor); + } + + wl_list_remove (&seat->sprite_destroy_listener.link); + seat->sprite = NULL; + } +} + +static void +pointer_set_cursor (struct wl_client *client, + struct wl_resource *resource, + uint32_t serial, + struct wl_resource *surface_resource, + int32_t x, int32_t y) +{ + MetaWaylandSeat *seat = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface; + + surface = (surface_resource ? + wl_resource_get_user_data (surface_resource) : + NULL); + + if (seat->pointer.focus == NULL) + return; + if (wl_resource_get_client (seat->pointer.focus->resource) != client) + return; + if (seat->pointer.focus_serial - serial > G_MAXUINT32 / 2) + return; + + pointer_unmap_sprite (seat); + + if (!surface) + return; + + wl_resource_add_destroy_listener (surface->resource, + &seat->sprite_destroy_listener); + + seat->sprite = surface; + seat->hotspot_x = x; + seat->hotspot_y = y; +} + +static const struct wl_pointer_interface +pointer_interface = + { + pointer_set_cursor + }; + +static void +seat_get_pointer (struct wl_client *client, + struct wl_resource *resource, + uint32_t id) +{ + MetaWaylandSeat *seat = wl_resource_get_user_data (resource); + struct wl_resource *cr; + + cr = wl_client_add_object (client, &wl_pointer_interface, + &pointer_interface, id, seat); + wl_list_insert (&seat->pointer.resource_list, wl_resource_get_link (cr)); + wl_resource_set_destructor (cr, unbind_resource); + + if (seat->pointer.focus && + wl_resource_get_client (seat->pointer.focus->resource) == client) + { + MetaWaylandSurface *surface; + wl_fixed_t sx, sy; + + surface = (MetaWaylandSurface *) seat->pointer.focus; + transform_stage_point_fixed (surface, + seat->pointer.x, + seat->pointer.y, + &sx, &sy); + meta_wayland_pointer_set_focus (&seat->pointer, + seat->pointer.focus, + sx, sy); + } +} + +static void +seat_get_keyboard (struct wl_client *client, + struct wl_resource *resource, + uint32_t id) +{ + MetaWaylandSeat *seat = wl_resource_get_user_data (resource); + struct wl_resource *cr; + + cr = wl_client_add_object (client, &wl_keyboard_interface, NULL, id, seat); + wl_list_insert (&seat->keyboard.resource_list, wl_resource_get_link (cr)); + wl_resource_set_destructor (cr, unbind_resource); + + wl_keyboard_send_keymap (cr, + WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, + seat->keyboard.xkb_info.keymap_fd, + seat->keyboard.xkb_info.keymap_size); + + if (seat->keyboard.focus && + wl_resource_get_client (seat->keyboard.focus->resource) == client) + { + meta_wayland_keyboard_set_focus (&seat->keyboard, + seat->keyboard.focus); + meta_wayland_data_device_set_keyboard_focus (seat); + } +} + +static void +seat_get_touch (struct wl_client *client, + struct wl_resource *resource, + uint32_t id) +{ + /* Touch not supported */ +} + +static const struct wl_seat_interface +seat_interface = + { + seat_get_pointer, + seat_get_keyboard, + seat_get_touch + }; + +static void +bind_seat (struct wl_client *client, + void *data, + guint32 version, + guint32 id) +{ + MetaWaylandSeat *seat = data; + struct wl_resource *resource; + + resource = wl_client_add_object (client, + &wl_seat_interface, + &seat_interface, + id, + data); + wl_list_insert (&seat->base_resource_list, wl_resource_get_link (resource)); + wl_resource_set_destructor (resource, unbind_resource); + + wl_seat_send_capabilities (resource, + WL_SEAT_CAPABILITY_POINTER | + WL_SEAT_CAPABILITY_KEYBOARD); +} + +static void +pointer_handle_sprite_destroy (struct wl_listener *listener, void *data) +{ + MetaWaylandSeat *seat = + wl_container_of (listener, seat, sprite_destroy_listener); + + seat->sprite = NULL; +} + +MetaWaylandSeat * +meta_wayland_seat_new (struct wl_display *display) +{ + MetaWaylandSeat *seat = g_new0 (MetaWaylandSeat, 1); + + wl_signal_init (&seat->destroy_signal); + + seat->selection_data_source = NULL; + wl_list_init (&seat->base_resource_list); + wl_signal_init (&seat->selection_signal); + wl_list_init (&seat->drag_resource_list); + wl_signal_init (&seat->drag_icon_signal); + + meta_wayland_pointer_init (&seat->pointer); + + meta_wayland_keyboard_init (&seat->keyboard, display); + + seat->display = display; + + seat->current_stage = 0; + + seat->sprite = NULL; + seat->sprite_destroy_listener.notify = pointer_handle_sprite_destroy; + seat->hotspot_x = 16; + seat->hotspot_y = 16; + + wl_display_add_global (display, &wl_seat_interface, seat, bind_seat); + + return seat; +} + +static void +notify_motion (MetaWaylandSeat *seat, + const ClutterEvent *event) +{ + MetaWaylandPointer *pointer = &seat->pointer; + float x, y; + + clutter_event_get_coords (event, &x, &y); + pointer->x = wl_fixed_from_double (x); + pointer->y = wl_fixed_from_double (y); + + meta_wayland_seat_repick (seat, + clutter_event_get_time (event), + clutter_event_get_source (event)); + + pointer->grab->interface->motion (pointer->grab, + clutter_event_get_time (event), + pointer->grab->x, + pointer->grab->y); +} + +static void +handle_motion_event (MetaWaylandSeat *seat, + const ClutterMotionEvent *event) +{ + notify_motion (seat, (const ClutterEvent *) event); +} + +static void +handle_button_event (MetaWaylandSeat *seat, + const ClutterButtonEvent *event) +{ + MetaWaylandPointer *pointer = &seat->pointer; + gboolean state = event->type == CLUTTER_BUTTON_PRESS; + uint32_t button; + + notify_motion (seat, (const ClutterEvent *) event); + + switch (event->button) + { + /* The evdev input right and middle button numbers are swapped + relative to how Clutter numbers them */ + case 2: + button = BTN_MIDDLE; + break; + + case 3: + button = BTN_RIGHT; + break; + + default: + button = event->button + BTN_LEFT - 1; + break; + } + + if (state) + { + if (pointer->button_count == 0) + { + pointer->grab_button = button; + pointer->grab_time = event->time; + pointer->grab_x = pointer->x; + pointer->grab_y = pointer->y; + } + + pointer->button_count++; + } + else + pointer->button_count--; + + pointer->grab->interface->button (pointer->grab, event->time, button, state); + + if (pointer->button_count == 1) + pointer->grab_serial = wl_display_get_serial (seat->display); +} + +static void +handle_scroll_event (MetaWaylandSeat *seat, + const ClutterScrollEvent *event) +{ + enum wl_pointer_axis axis; + wl_fixed_t value; + + notify_motion (seat, (const ClutterEvent *) event); + + switch (event->direction) + { + case CLUTTER_SCROLL_UP: + axis = WL_POINTER_AXIS_VERTICAL_SCROLL; + value = -DEFAULT_AXIS_STEP_DISTANCE; + break; + + case CLUTTER_SCROLL_DOWN: + axis = WL_POINTER_AXIS_VERTICAL_SCROLL; + value = DEFAULT_AXIS_STEP_DISTANCE; + break; + + case CLUTTER_SCROLL_LEFT: + axis = WL_POINTER_AXIS_HORIZONTAL_SCROLL; + value = -DEFAULT_AXIS_STEP_DISTANCE; + break; + + case CLUTTER_SCROLL_RIGHT: + axis = WL_POINTER_AXIS_HORIZONTAL_SCROLL; + value = DEFAULT_AXIS_STEP_DISTANCE; + break; + + default: + return; + } + + if (seat->pointer.focus_resource) + wl_pointer_send_axis (seat->pointer.focus_resource, + event->time, + axis, + value); +} + +void +meta_wayland_seat_handle_event (MetaWaylandSeat *seat, + const ClutterEvent *event) +{ + switch (event->type) + { + case CLUTTER_MOTION: + handle_motion_event (seat, + (const ClutterMotionEvent *) event); + break; + + case CLUTTER_BUTTON_PRESS: + case CLUTTER_BUTTON_RELEASE: + handle_button_event (seat, + (const ClutterButtonEvent *) event); + break; + + case CLUTTER_KEY_PRESS: + case CLUTTER_KEY_RELEASE: + meta_wayland_keyboard_handle_event (&seat->keyboard, + (const ClutterKeyEvent *) event); + break; + + case CLUTTER_SCROLL: + handle_scroll_event (seat, (const ClutterScrollEvent *) event); + break; + + default: + break; + } +} + +static void +update_pointer_position_for_actor (MetaWaylandPointer *pointer, + ClutterActor *actor) +{ + float ax, ay; + + clutter_actor_transform_stage_point (actor, + wl_fixed_to_double (pointer->x), + wl_fixed_to_double (pointer->y), + &ax, &ay); + pointer->current_x = wl_fixed_from_double (ax); + pointer->current_y = wl_fixed_from_double (ay); +} + +/* The actor argument can be NULL in which case a Clutter pick will be + performed to determine the right actor. An actor should only be + passed if the repick is being performed due to an event in which + case Clutter will have already performed a pick so we can avoid + redundantly doing another one */ +void +meta_wayland_seat_repick (MetaWaylandSeat *seat, + uint32_t time, + ClutterActor *actor) +{ + MetaWaylandPointer *pointer = &seat->pointer; + MetaWaylandSurface *surface = NULL; + + if (actor == NULL && seat->current_stage) + { + ClutterStage *stage = CLUTTER_STAGE (seat->current_stage); + actor = clutter_stage_get_actor_at_pos (stage, + CLUTTER_PICK_REACTIVE, + wl_fixed_to_double (pointer->x), + wl_fixed_to_double (pointer->y)); + } + + if (actor) + seat->current_stage = clutter_actor_get_stage (actor); + else + seat->current_stage = NULL; + + if (META_IS_WINDOW_ACTOR (actor)) + { + MetaWindow *window = + meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor)); + + update_pointer_position_for_actor (pointer, actor); + + surface = window->surface; + } + else if (META_IS_SHAPED_TEXTURE (actor)) + { + MetaShapedTexture *shaped_texture = META_SHAPED_TEXTURE (actor); + + update_pointer_position_for_actor (pointer, actor); + + surface = meta_shaped_texture_get_wayland_surface (shaped_texture); + } + + if (surface != pointer->current) + { + const MetaWaylandPointerGrabInterface *interface = + pointer->grab->interface; + interface->focus (pointer->grab, + surface, + pointer->current_x, pointer->current_y); + pointer->current = surface; + } + + if (pointer->grab->focus) + transform_stage_point_fixed (pointer->grab->focus, + pointer->x, + pointer->y, + &pointer->grab->x, + &pointer->grab->y); +} + +void +meta_wayland_seat_free (MetaWaylandSeat *seat) +{ + pointer_unmap_sprite (seat); + + meta_wayland_pointer_release (&seat->pointer); + meta_wayland_keyboard_release (&seat->keyboard); + + wl_signal_emit (&seat->destroy_signal, seat); + + g_slice_free (MetaWaylandSeat, seat); +} diff --git a/src/wayland/meta-wayland-seat.h b/src/wayland/meta-wayland-seat.h new file mode 100644 index 000000000..ee567785e --- /dev/null +++ b/src/wayland/meta-wayland-seat.h @@ -0,0 +1,47 @@ +/* + * Wayland Support + * + * Copyright (C) 2012 Intel Corporation + * + * 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_WAYLAND_SEAT_H__ +#define __META_WAYLAND_SEAT_H__ + +#include +#include +#include +#include + +#include "meta-wayland-private.h" + +MetaWaylandSeat * +meta_wayland_seat_new (struct wl_display *display); + +void +meta_wayland_seat_handle_event (MetaWaylandSeat *seat, + const ClutterEvent *event); + +void +meta_wayland_seat_repick (MetaWaylandSeat *seat, + uint32_t time, + ClutterActor *actor); + +void +meta_wayland_seat_free (MetaWaylandSeat *seat); + +#endif /* __META_WAYLAND_SEAT_H__ */ diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index 437406818..c364de0e4 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -40,6 +40,9 @@ #include "meta-wayland-private.h" #include "meta-xwayland-private.h" #include "meta-window-actor-private.h" +#include "meta-wayland-seat.h" +#include "meta-wayland-keyboard.h" +#include "meta-wayland-data-device.h" #include "display-private.h" #include "window-private.h" #include @@ -414,6 +417,17 @@ const struct wl_surface_interface meta_wayland_surface_interface = { meta_wayland_surface_set_buffer_scale }; +void +meta_wayland_compositor_set_input_focus (MetaWaylandCompositor *compositor, + MetaWindow *window) +{ + MetaWaylandSurface *surface = window ? window->surface : NULL; + + meta_wayland_keyboard_set_focus (&compositor->seat->keyboard, + surface); + meta_wayland_data_device_set_keyboard_focus (compositor->seat); +} + static void window_destroyed_cb (void *user_data, GObject *old_object) { @@ -422,6 +436,14 @@ window_destroyed_cb (void *user_data, GObject *old_object) surface->window = NULL; } +void +meta_wayland_compositor_repick (MetaWaylandCompositor *compositor) +{ + meta_wayland_seat_repick (compositor->seat, + get_time (), + NULL); +} + static void meta_wayland_surface_free (MetaWaylandSurface *surface) { @@ -457,6 +479,11 @@ meta_wayland_surface_free (MetaWaylandSurface *surface) wl_resource_destroy (cb->resource); g_slice_free (MetaWaylandSurface, surface); + + meta_wayland_compositor_repick (compositor); + + if (compositor->implicit_grab_surface == surface) + compositor->implicit_grab_surface = compositor->seat->pointer.current; } static void @@ -962,6 +989,14 @@ xserver_set_window_id (struct wl_client *client, g_object_weak_ref (G_OBJECT (surface->window), window_destroyed_cb, surface); + + /* If the window is already meant to have focus then the + * original attempt to call this in response to the FocusIn + * event will have been lost because there was no surface + * yet. */ + if (window->has_focus) + meta_wayland_compositor_set_input_focus (compositor, window); + } #warning "FIXME: Handle surface destroy and remove window_surfaces mapping" } @@ -1022,10 +1057,236 @@ stage_destroy_cb (void) meta_quit (META_EXIT_SUCCESS); } +#define N_BUTTONS 5 + +static void +synthesize_motion_event (MetaWaylandCompositor *compositor, + const ClutterEvent *event) +{ + /* We want to synthesize X events for mouse motion events so that we + don't have to rely on the X server's window position being + synched with the surface position. See the comment in + event_callback() in display.c */ + MetaWaylandSeat *seat = compositor->seat; + MetaWaylandPointer *pointer = &seat->pointer; + MetaWaylandSurface *surface; + XGenericEventCookie generic_event; + XIDeviceEvent device_event; + unsigned char button_mask[(N_BUTTONS + 7) / 8] = { 0 }; + MetaDisplay *display = meta_get_display (); + ClutterModifierType state; + int i; + + generic_event.type = GenericEvent; + generic_event.serial = 0; + generic_event.send_event = False; + generic_event.display = display->xdisplay; + generic_event.extension = display->xinput_opcode; + generic_event.evtype = XI_Motion; + /* Mutter assumes the data for the event is already retrieved by GDK + * so we don't need the cookie */ + generic_event.cookie = 0; + generic_event.data = &device_event; + + memcpy (&device_event, &generic_event, sizeof (XGenericEvent)); + + device_event.time = clutter_event_get_time (event); + device_event.deviceid = clutter_event_get_device_id (event); + device_event.sourceid = 0; /* not used, not sure what this should be */ + device_event.detail = 0; + device_event.root = DefaultRootWindow (display->xdisplay); + device_event.flags = 0 /* not used for motion events */; + + if (compositor->implicit_grab_surface) + surface = compositor->implicit_grab_surface; + else + surface = pointer->current; + + if (surface == pointer->current) + { + device_event.event_x = wl_fixed_to_int (pointer->current_x); + device_event.event_y = wl_fixed_to_int (pointer->current_y); + } + else if (surface && surface->window) + { + ClutterActor *window_actor = + CLUTTER_ACTOR (meta_window_get_compositor_private (surface->window)); + + if (window_actor) + { + float ax, ay; + + clutter_actor_transform_stage_point (window_actor, + wl_fixed_to_double (pointer->x), + wl_fixed_to_double (pointer->y), + &ax, &ay); + + device_event.event_x = ax; + device_event.event_y = ay; + } + else + { + device_event.event_x = wl_fixed_to_double (pointer->x); + device_event.event_y = wl_fixed_to_double (pointer->y); + } + } + else + { + device_event.event_x = wl_fixed_to_double (pointer->x); + device_event.event_y = wl_fixed_to_double (pointer->y); + } + + if (surface && surface->xid != None) + device_event.event = surface->xid; + else + device_event.event = device_event.root; + + /* Mutter doesn't really know about the sub-windows. This assumes it + doesn't care either */ + device_event.child = device_event.event; + device_event.root_x = wl_fixed_to_double (pointer->x); + device_event.root_y = wl_fixed_to_double (pointer->y); + + state = clutter_event_get_state (event); + + for (i = 0; i < N_BUTTONS; i++) + if ((state & (CLUTTER_BUTTON1_MASK << i))) + XISetMask (button_mask, i + 1); + device_event.buttons.mask_len = N_BUTTONS + 1; + device_event.buttons.mask = button_mask; + + device_event.valuators.mask_len = 0; + device_event.valuators.mask = NULL; + device_event.valuators.values = NULL; + + memset (&device_event.mods, 0, sizeof (device_event.mods)); + device_event.mods.effective = + state & (CLUTTER_MODIFIER_MASK & + ~(((CLUTTER_BUTTON1_MASK << N_BUTTONS) - 1) ^ + (CLUTTER_BUTTON1_MASK - 1))); + + memset (&device_event.group, 0, sizeof (device_event.group)); + + meta_display_handle_event (display, (XEvent *) &generic_event); +} + +static gboolean +event_cb (ClutterActor *stage, + const ClutterEvent *event, + MetaWaylandCompositor *compositor) +{ + MetaWaylandSeat *seat = compositor->seat; + MetaWaylandPointer *pointer = &seat->pointer; + MetaWaylandSurface *surface; + MetaDisplay *display; + + meta_wayland_seat_handle_event (compositor->seat, event); + + /* HACK: for now, the surfaces from Wayland clients aren't + integrated into Mutter's stacking and Mutter won't give them + focus on mouse clicks. As a hack to work around this we can just + give them input focus on mouse clicks so we can at least test the + keyboard support */ + if (event->type == CLUTTER_BUTTON_PRESS) + { + surface = pointer->current; + + /* Only focus surfaces that wouldn't be handled by the + corresponding X events */ + if (surface && surface->xid == 0) + { + meta_wayland_keyboard_set_focus (&seat->keyboard, surface); + meta_wayland_data_device_set_keyboard_focus (seat); + } + } + + display = meta_get_display (); + if (!display) + return FALSE; + + switch (event->type) + { + case CLUTTER_BUTTON_PRESS: + if (compositor->implicit_grab_surface == NULL) + { + compositor->implicit_grab_button = event->button.button; + compositor->implicit_grab_surface = pointer->current; + } + return FALSE; + + case CLUTTER_BUTTON_RELEASE: + if (event->type == CLUTTER_BUTTON_RELEASE && + compositor->implicit_grab_surface && + event->button.button == compositor->implicit_grab_button) + compositor->implicit_grab_surface = NULL; + return FALSE; + + case CLUTTER_MOTION: + synthesize_motion_event (compositor, event); + return FALSE; + + default: + return FALSE; + } +} + +static gboolean +event_emission_hook_cb (GSignalInvocationHint *ihint, + guint n_param_values, + const GValue *param_values, + gpointer data) +{ + MetaWaylandCompositor *compositor = data; + ClutterActor *actor; + ClutterEvent *event; + + g_return_val_if_fail (n_param_values == 2, FALSE); + + actor = g_value_get_object (param_values + 0); + event = g_value_get_boxed (param_values + 1); + + if (actor == NULL) + return TRUE /* stay connected */; + + /* If this event belongs to the corresponding grab for this event + * type then the captured-event signal won't be emitted so we have + * to manually forward it on */ + + switch (event->type) + { + /* Pointer events */ + case CLUTTER_MOTION: + case CLUTTER_ENTER: + case CLUTTER_LEAVE: + case CLUTTER_BUTTON_PRESS: + case CLUTTER_BUTTON_RELEASE: + case CLUTTER_SCROLL: + if (actor == clutter_get_pointer_grab ()) + event_cb (clutter_actor_get_stage (actor), + event, + compositor); + break; + + /* Keyboard events */ + case CLUTTER_KEY_PRESS: + case CLUTTER_KEY_RELEASE: + if (actor == clutter_get_keyboard_grab ()) + event_cb (clutter_actor_get_stage (actor), + event, + compositor); + + default: + break; + } + + return TRUE /* stay connected */; +} + void meta_wayland_init (void) { MetaWaylandCompositor *compositor = &_meta_wayland_compositor; + guint event_signal; memset (compositor, 0, sizeof (MetaWaylandCompositor)); @@ -1072,6 +1333,25 @@ meta_wayland_init (void) g_signal_connect (compositor->stage, "destroy", G_CALLBACK (stage_destroy_cb), NULL); + meta_wayland_data_device_manager_init (compositor->wayland_display); + + compositor->seat = meta_wayland_seat_new (compositor->wayland_display); + + g_signal_connect (compositor->stage, + "captured-event", + G_CALLBACK (event_cb), + compositor); + /* If something sets a grab on an actor then the captured event + * signal won't get emitted but we still want to see these events so + * we can update the cursor position. To make sure we see all events + * we also install an emission hook on the event signal */ + event_signal = g_signal_lookup ("event", CLUTTER_TYPE_STAGE); + g_signal_add_emission_hook (event_signal, + 0 /* detail */, + event_emission_hook_cb, + compositor, /* hook_data */ + NULL /* data_destroy */); + meta_wayland_compositor_create_output (compositor, 0, 0, 1024, 600, 222, 125); if (wl_global_create (compositor->wayland_display, From a5585327dc35f0aace52a827dcdb7450eee74bf9 Mon Sep 17 00:00:00 2001 From: Neil Roberts Date: Wed, 18 Jan 2012 23:03:23 +0000 Subject: [PATCH 009/889] wayland: Add an actor for the cursor When running Mutter under Cogl's KMS backend no cursor will be provided so instead this makes it so the cursor will be painted as a CoglTexture that gets moved in response to mouse motion events. The painting is done in a subclass of ClutterStage so that we can guarantee that the cursor will be painted on top of everything else. This patch adds support for the set_cursor method on the pointer interface so that clients can change the cursor image. The set_pointer method sets a surface and a hotspot position to use for the cursor image. The surface's buffer is converted to a CoglTexture and attached to a pipeline to paint directly via Cogl. If a new buffer is attached to the surface the image will be updated. The cursor reverts back to the default image whenever to the pointer focus is moved off of any surface. The image for the pointer is taken from X. It gets installed into a fixed data location for mutter. --- Makefile.am | 2 +- configure.ac | 1 + data/Makefile.am | 7 + data/left_ptr.png | Bin 0 -> 736 bytes src/Makefile.am | 4 +- src/wayland/meta-wayland-seat.c | 66 ++++++--- src/wayland/meta-wayland-seat.h | 3 + src/wayland/meta-wayland-stage.c | 243 +++++++++++++++++++++++++++++++ src/wayland/meta-wayland-stage.h | 111 ++++++++++++++ src/wayland/meta-wayland.c | 12 +- 10 files changed, 426 insertions(+), 23 deletions(-) create mode 100644 data/Makefile.am create mode 100644 data/left_ptr.png create mode 100644 src/wayland/meta-wayland-stage.c create mode 100644 src/wayland/meta-wayland-stage.h diff --git a/Makefile.am b/Makefile.am index 979ba2573..18afe05c7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,5 +1,5 @@ -SUBDIRS=src protocol po doc +SUBDIRS=src protocol data po doc EXTRA_DIST = HACKING MAINTAINERS rationales.txt diff --git a/configure.ac b/configure.ac index 7c20ac5a3..4a4d2dad2 100644 --- a/configure.ac +++ b/configure.ac @@ -495,6 +495,7 @@ src/mutter-plugins.pc src/tools/Makefile src/compositor/plugins/Makefile protocol/Makefile +data/Makefile po/Makefile.in ]) diff --git a/data/Makefile.am b/data/Makefile.am new file mode 100644 index 000000000..0fbff4569 --- /dev/null +++ b/data/Makefile.am @@ -0,0 +1,7 @@ +defaultcursordir = $(datadir)/mutter/cursors + +dist_defaultcursor_DATA = + +if HAVE_WAYLAND +dist_defaultcursor_DATA += left_ptr.png +endif diff --git a/data/left_ptr.png b/data/left_ptr.png new file mode 100644 index 0000000000000000000000000000000000000000..d3818ccfb7cbad66fe321f1ff1a3bfa2e5ddd35b GIT binary patch literal 736 zcmV<60w4W}P)m2~@wG(y}3WZMq)zrX((fYNG2 zCdo)7!mFz*?(FP*1mJHaB9o-o>*d761a)2K=H_M&z=KvHGD%93#6TdxSS&`vFqp|? zvH*OoKxC41I2`o(d<=y`OeT{wO_R&Z%kKf)hy9fA1^}SPTnDg`V6hbhSO0B`pNmIxl003oKW=~HK2L}f^Ha5n^ z#YGAsI6FK08bDVw$Th&_a#2wf_Vx8~baa%_Xq2m~s}w>okx0A(;JFEL+(xr3>)NbV zt2jD3g4^vzHk-}F<8d>e&wl_=u5YTb4ggS+BnE>)7K=p+At;1krBY$7R-pEvc#r{dVXYNBn{v(0Qdh2-6VI^=kFZ+z3!^R1YiKD;+ElR%lHM&^I8OL S #include #include #include @@ -34,6 +35,7 @@ #include "meta-wayland-data-device.h" #include "meta-window-actor-private.h" #include "meta/meta-shaped-texture.h" +#include "meta-wayland-stage.h" #define DEFAULT_AXIS_STEP_DISTANCE wl_fixed_from_int (10) @@ -71,23 +73,40 @@ transform_stage_point_fixed (MetaWaylandSurface *surface, static void pointer_unmap_sprite (MetaWaylandSeat *seat) { + if (seat->current_stage) + { + MetaWaylandStage *stage = META_WAYLAND_STAGE (seat->current_stage); + meta_wayland_stage_set_invisible_cursor (stage); + } + if (seat->sprite) { - if (seat->sprite->window) - { - GObject *window_actor_object = - meta_window_get_compositor_private (seat->sprite->window); - ClutterActor *window_actor = CLUTTER_ACTOR (window_actor_object); - - if (window_actor) - clutter_actor_hide (window_actor); - } - wl_list_remove (&seat->sprite_destroy_listener.link); seat->sprite = NULL; } } +void +meta_wayland_seat_update_sprite (MetaWaylandSeat *seat) +{ + if (seat->current_stage) + { + MetaWaylandStage *stage = META_WAYLAND_STAGE (seat->current_stage); + ClutterBackend *backend = clutter_get_default_backend (); + CoglContext *context = clutter_backend_get_cogl_context (backend); + struct wl_resource *buffer = seat->sprite->buffer_ref.buffer->resource; + CoglTexture2D *texture = + cogl_wayland_texture_2d_new_from_buffer (context, buffer, NULL); + + meta_wayland_stage_set_cursor_from_texture (stage, + COGL_TEXTURE (texture), + seat->hotspot_x, + seat->hotspot_y); + + cogl_object_unref (texture); + } +} + static void pointer_set_cursor (struct wl_client *client, struct wl_resource *resource, @@ -109,17 +128,24 @@ pointer_set_cursor (struct wl_client *client, if (seat->pointer.focus_serial - serial > G_MAXUINT32 / 2) return; - pointer_unmap_sprite (seat); - - if (!surface) - return; - - wl_resource_add_destroy_listener (surface->resource, - &seat->sprite_destroy_listener); - - seat->sprite = surface; seat->hotspot_x = x; seat->hotspot_y = y; + + if (seat->sprite != surface) + { + pointer_unmap_sprite (seat); + + if (!surface) + return; + + wl_resource_add_destroy_listener (surface->resource, + &seat->sprite_destroy_listener); + + seat->sprite = surface; + + if (seat->sprite->buffer_ref.buffer) + meta_wayland_seat_update_sprite (seat); + } } static const struct wl_pointer_interface @@ -228,7 +254,7 @@ pointer_handle_sprite_destroy (struct wl_listener *listener, void *data) MetaWaylandSeat *seat = wl_container_of (listener, seat, sprite_destroy_listener); - seat->sprite = NULL; + pointer_unmap_sprite (seat); } MetaWaylandSeat * diff --git a/src/wayland/meta-wayland-seat.h b/src/wayland/meta-wayland-seat.h index ee567785e..89bcd76cc 100644 --- a/src/wayland/meta-wayland-seat.h +++ b/src/wayland/meta-wayland-seat.h @@ -41,6 +41,9 @@ meta_wayland_seat_repick (MetaWaylandSeat *seat, uint32_t time, ClutterActor *actor); +void +meta_wayland_seat_update_sprite (MetaWaylandSeat *seat); + void meta_wayland_seat_free (MetaWaylandSeat *seat); diff --git a/src/wayland/meta-wayland-stage.c b/src/wayland/meta-wayland-stage.c new file mode 100644 index 000000000..c3036084d --- /dev/null +++ b/src/wayland/meta-wayland-stage.c @@ -0,0 +1,243 @@ +/* + * Wayland Support + * + * Copyright (C) 2012 Intel Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include + +#include +#include +#include + +#include "meta-wayland-stage.h" +#include "meta/meta-window-actor.h" +#include "meta/meta-shaped-texture.h" + +#define META_WAYLAND_DEFAULT_CURSOR_HOTSPOT_X 7 +#define META_WAYLAND_DEFAULT_CURSOR_HOTSPOT_Y 4 + +G_DEFINE_TYPE (MetaWaylandStage, meta_wayland_stage, CLUTTER_TYPE_STAGE); + +static void +meta_wayland_stage_finalize (GObject *object) +{ + MetaWaylandStage *self = (MetaWaylandStage *) object; + + cogl_object_unref (self->default_cursor_pipeline); + cogl_object_unref (self->texture_cursor_pipeline); + + G_OBJECT_CLASS (meta_wayland_stage_parent_class)->finalize (object); +} + +static void +get_cursor_draw_position (MetaWaylandStage *self, + cairo_rectangle_int_t *rect) +{ + rect->x = self->cursor_x - self->cursor_hotspot_x; + rect->y = self->cursor_y - self->cursor_hotspot_y; + rect->width = self->cursor_width; + rect->height = self->cursor_height; +} + +static void +draw_cursor_pipeline (MetaWaylandStage *self, + CoglPipeline *pipeline) +{ + cairo_rectangle_int_t rect; + + get_cursor_draw_position (self, &rect); + + cogl_framebuffer_draw_rectangle (cogl_get_draw_framebuffer (), + pipeline, + rect.x, rect.y, + rect.x + rect.width, + rect.y + rect.height); + + self->has_last_cursor_position = TRUE; + self->last_cursor_position = rect; +} + +static void +meta_wayland_stage_paint (ClutterActor *actor) +{ + MetaWaylandStage *self = META_WAYLAND_STAGE (actor); + + CLUTTER_ACTOR_CLASS (meta_wayland_stage_parent_class)->paint (actor); + + /* Make sure the cursor is always painted on top of all of the other + actors */ + + switch (self->cursor_type) + { + case META_WAYLAND_STAGE_CURSOR_INVISIBLE: + break; + + case META_WAYLAND_STAGE_CURSOR_DEFAULT: + draw_cursor_pipeline (self, self->default_cursor_pipeline); + break; + + case META_WAYLAND_STAGE_CURSOR_TEXTURE: + draw_cursor_pipeline (self, self->texture_cursor_pipeline); + break; + } +} + +static void +update_cursor_position (MetaWaylandStage *self) +{ + cairo_rectangle_int_t rect; + + if (self->has_last_cursor_position) + { + clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (self), + &self->last_cursor_position); + self->has_last_cursor_position = FALSE; + } + + get_cursor_draw_position (self, &rect); + if (rect.width != 0 && rect.height != 0) + clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (self), &rect); +} + +static void +meta_wayland_stage_class_init (MetaWaylandStageClass *klass) +{ + GObjectClass *gobject_class = (GObjectClass *) klass; + ClutterActorClass *actor_class = (ClutterActorClass *) klass; + + gobject_class->finalize = meta_wayland_stage_finalize; + + actor_class->paint = meta_wayland_stage_paint; +} + +static void +load_default_cursor_pipeline (MetaWaylandStage *self) +{ + CoglContext *context = + clutter_backend_get_cogl_context (clutter_get_default_backend ()); + CoglTexture *texture; + CoglError *error = NULL; + char *filename; + + filename = g_build_filename (MUTTER_DATADIR, + "mutter/cursors/left_ptr.png", + NULL); + + texture = cogl_texture_new_from_file (filename, + COGL_TEXTURE_NONE, + COGL_PIXEL_FORMAT_ANY, + &error); + + g_free (filename); + + self->default_cursor_pipeline = cogl_pipeline_new (context); + cogl_pipeline_set_layer_filters (self->default_cursor_pipeline, + 0, /* layer */ + COGL_PIPELINE_FILTER_NEAREST, + COGL_PIPELINE_FILTER_NEAREST); + + if (texture == NULL) + { + g_warning ("Failed to load default cursor: %s", + error->message); + cogl_error_free (error); + } + else + { + self->default_cursor_width = cogl_texture_get_width (texture); + self->default_cursor_height = cogl_texture_get_height (texture); + + cogl_pipeline_set_layer_texture (self->default_cursor_pipeline, + 0, /* layer */ + texture); + cogl_object_unref (texture); + } +} + +static void +meta_wayland_stage_init (MetaWaylandStage *self) +{ + load_default_cursor_pipeline (self); + + self->texture_cursor_pipeline = + cogl_pipeline_copy (self->default_cursor_pipeline); + + meta_wayland_stage_set_default_cursor (self); +} + +ClutterActor * +meta_wayland_stage_new (void) +{ + return g_object_new (META_WAYLAND_TYPE_STAGE, + "cursor-visible", FALSE, + NULL); +} + +void +meta_wayland_stage_set_cursor_position (MetaWaylandStage *self, + int x, + int y) +{ + self->cursor_x = x; + self->cursor_y = y; + update_cursor_position (self); +} + +void +meta_wayland_stage_set_cursor_from_texture (MetaWaylandStage *self, + CoglTexture *texture, + int hotspot_x, + int hotspot_y) +{ + CoglPipeline *pipeline; + + self->cursor_hotspot_x = hotspot_x; + self->cursor_hotspot_y = hotspot_y; + self->cursor_type = META_WAYLAND_STAGE_CURSOR_TEXTURE; + + pipeline = cogl_pipeline_copy (self->texture_cursor_pipeline); + cogl_pipeline_set_layer_texture (pipeline, 0, texture); + cogl_object_unref (self->texture_cursor_pipeline); + self->texture_cursor_pipeline = pipeline; + + self->cursor_width = cogl_texture_get_width (texture); + self->cursor_height = cogl_texture_get_height (texture); + + update_cursor_position (self); +} + +void +meta_wayland_stage_set_invisible_cursor (MetaWaylandStage *self) +{ + self->cursor_type = META_WAYLAND_STAGE_CURSOR_INVISIBLE; + self->cursor_width = 0; + self->cursor_height = 0; + update_cursor_position (self); +} + +void +meta_wayland_stage_set_default_cursor (MetaWaylandStage *self) +{ + self->cursor_type = META_WAYLAND_STAGE_CURSOR_DEFAULT; + self->cursor_hotspot_x = META_WAYLAND_DEFAULT_CURSOR_HOTSPOT_X; + self->cursor_hotspot_y = META_WAYLAND_DEFAULT_CURSOR_HOTSPOT_Y; + self->cursor_width = self->default_cursor_width; + self->cursor_height = self->default_cursor_height; + update_cursor_position (self); +} diff --git a/src/wayland/meta-wayland-stage.h b/src/wayland/meta-wayland-stage.h new file mode 100644 index 000000000..d25f2707f --- /dev/null +++ b/src/wayland/meta-wayland-stage.h @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2012 Intel Corporation + * + * 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_WAYLAND_STAGE_H +#define META_WAYLAND_STAGE_H + +#include +#include + +#include "window-private.h" + +G_BEGIN_DECLS + +#define META_WAYLAND_TYPE_STAGE \ + (meta_wayland_stage_get_type()) +#define META_WAYLAND_STAGE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + META_WAYLAND_TYPE_STAGE, \ + MetaWaylandStage)) +#define META_WAYLAND_STAGE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), \ + META_WAYLAND_TYPE_STAGE, \ + MetaWaylandStageClass)) +#define META_WAYLAND_IS_STAGE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + META_WAYLAND_TYPE_STAGE)) +#define META_WAYLAND_IS_STAGE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + META_WAYLAND_TYPE_STAGE)) +#define META_WAYLAND_STAGE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + META_WAYLAND_STAGE, \ + MetaWaylandStageClass)) + +typedef struct _MetaWaylandStage MetaWaylandStage; +typedef struct _MetaWaylandStageClass MetaWaylandStageClass; + +struct _MetaWaylandStageClass +{ + ClutterStageClass parent_class; +}; + +struct _MetaWaylandStage +{ + ClutterStage parent; + + /* A pipeline containing the cursor texture that will be used when + the cursor is not over a surface */ + CoglPipeline *default_cursor_pipeline; + int default_cursor_width; + int default_cursor_height; + + CoglPipeline *texture_cursor_pipeline; + + int cursor_x; + int cursor_y; + int cursor_width; + int cursor_height; + int cursor_hotspot_x; + int cursor_hotspot_y; + + enum + { + /* No cursor will be drawn */ + META_WAYLAND_STAGE_CURSOR_INVISIBLE, + /* The cursor will be drawn from our default cursor image */ + META_WAYLAND_STAGE_CURSOR_DEFAULT, + /* The cursor will be drawn using a custom texture */ + META_WAYLAND_STAGE_CURSOR_TEXTURE + } cursor_type; + + gboolean has_last_cursor_position; + cairo_rectangle_int_t last_cursor_position; +}; + +GType meta_wayland_stage_get_type (void) G_GNUC_CONST; + +ClutterActor *meta_wayland_stage_new (void); + +void meta_wayland_stage_set_cursor_position (MetaWaylandStage *stage, + int x, + int y); + +void meta_wayland_stage_set_default_cursor (MetaWaylandStage *self); + +void meta_wayland_stage_set_cursor_from_texture (MetaWaylandStage *self, + CoglTexture *texture, + int hotspot_x, + int hotspot_y); + +void meta_wayland_stage_set_invisible_cursor (MetaWaylandStage *self); + +G_END_DECLS + +#endif /* META_WAYLAND_STAGE_H */ diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index c364de0e4..dfd5fa8fd 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -39,6 +39,7 @@ #include "meta-wayland-private.h" #include "meta-xwayland-private.h" +#include "meta-wayland-stage.h" #include "meta-window-actor-private.h" #include "meta-wayland-seat.h" #include "meta-wayland-keyboard.h" @@ -368,6 +369,8 @@ meta_wayland_surface_commit (struct wl_client *client, (buffer->width != rect.width || buffer->height != rect.height)) meta_window_resize (surface->window, FALSE, buffer->width, buffer->height); } + else if (surface == compositor->seat->sprite) + meta_wayland_seat_update_sprite (compositor->seat); } } @@ -1200,6 +1203,13 @@ event_cb (ClutterActor *stage, } } + meta_wayland_stage_set_cursor_position (META_WAYLAND_STAGE (stage), + wl_fixed_to_int (pointer->x), + wl_fixed_to_int (pointer->y)); + + if (pointer->current == NULL) + meta_wayland_stage_set_default_cursor (META_WAYLAND_STAGE (stage)); + display = meta_get_display (); if (!display) return FALSE; @@ -1326,7 +1336,7 @@ meta_wayland_init (void) if (clutter_init (NULL, NULL) != CLUTTER_INIT_SUCCESS) g_error ("Failed to initialize Clutter"); - compositor->stage = clutter_stage_new (); + compositor->stage = meta_wayland_stage_new (); clutter_stage_set_user_resizable (CLUTTER_STAGE (compositor->stage), FALSE); g_signal_connect_after (compositor->stage, "paint", G_CALLBACK (paint_finished_cb), compositor); From 85e66f69fa2dd52589a6875e003c4e467623ddff Mon Sep 17 00:00:00 2001 From: Robert Bragg Date: Sat, 15 Jun 2013 23:05:31 +0100 Subject: [PATCH 010/889] wayland: support left click to raise wayland surfaces This adds support for raising wayland surfaces when clicked with the left mouse button. --- src/wayland/meta-wayland-seat.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c index 960b6138f..9fb285abf 100644 --- a/src/wayland/meta-wayland-seat.c +++ b/src/wayland/meta-wayland-seat.c @@ -347,10 +347,20 @@ handle_button_event (MetaWaylandSeat *seat, { if (pointer->button_count == 0) { + MetaWaylandSurface *surface = pointer->current; + pointer->grab_button = button; pointer->grab_time = event->time; pointer->grab_x = pointer->x; pointer->grab_y = pointer->y; + + if (button == BTN_LEFT && + surface && + surface->window && + surface->window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND) + { + meta_window_raise (surface->window); + } } pointer->button_count++; From 2c901cc015aefb97538217d817333f71ae625a54 Mon Sep 17 00:00:00 2001 From: Robert Bragg Date: Sun, 16 Jun 2013 01:49:03 +0100 Subject: [PATCH 011/889] wayland: implement shell surface move interface This implements the shell surface move interface so now it's possible to use the mouse to interactively move wayland based windows around the screen. --- src/wayland/meta-wayland.c | 182 ++++++++++++++++++++++++++++++++++++- 1 file changed, 181 insertions(+), 1 deletion(-) diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index dfd5fa8fd..b35420188 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -43,6 +43,7 @@ #include "meta-window-actor-private.h" #include "meta-wayland-seat.h" #include "meta-wayland-keyboard.h" +#include "meta-wayland-pointer.h" #include "meta-wayland-data-device.h" #include "display-private.h" #include "window-private.h" @@ -722,12 +723,191 @@ shell_surface_pong (struct wl_client *client, { } +/* TODO: consider adding this to window.c */ +static void +meta_window_get_surface_rect (const MetaWindow *window, + MetaRectangle *rect) +{ + if (window->frame) + { + MetaFrameBorders borders; + *rect = window->frame->rect; + meta_frame_calc_borders (window->frame, &borders); + } + else + *rect = window->rect; +} + +typedef struct _MetaWaylandGrab +{ + MetaWaylandPointerGrab grab; + MetaWaylandShellSurface *shell_surface; + struct wl_listener shell_surface_destroy_listener; + MetaWaylandPointer *pointer; +} MetaWaylandGrab; + +typedef struct _MetaWaylandMoveGrab +{ + MetaWaylandGrab base; + wl_fixed_t dx, dy; +} MetaWaylandMoveGrab; + +static void +destroy_shell_surface_grab_listener (struct wl_listener *listener, + void *data) +{ + MetaWaylandGrab *grab = wl_container_of (listener, grab, + shell_surface_destroy_listener); + grab->shell_surface = NULL; + + /* XXX: Could we perhaps just stop the grab here so we don't have + * to consider grab->shell_surface becoming NULL in grab interface + * callbacks? */ +} + +typedef enum _GrabCursor +{ + GRAB_CURSOR_MOVE, +} GrabCursor; + +static void +grab_pointer (MetaWaylandGrab *grab, + const MetaWaylandPointerGrabInterface *interface, + MetaWaylandShellSurface *shell_surface, + MetaWaylandPointer *pointer, + GrabCursor cursor) +{ + /* TODO: popup_grab_end (pointer); */ + + grab->grab.interface = interface; + grab->shell_surface = shell_surface; + grab->shell_surface_destroy_listener.notify = + destroy_shell_surface_grab_listener; + wl_resource_add_destroy_listener (shell_surface->resource, + &grab->shell_surface_destroy_listener); + + grab->pointer = pointer; + grab->grab.focus = shell_surface->surface; + + meta_wayland_pointer_start_grab (pointer, &grab->grab); + + /* TODO: send_grab_cursor (cursor); */ + + /* XXX: In Weston there is a desktop shell protocol which has + * a set_grab_surface request that's used to specify the surface + * that's focused here. + * + * TODO: understand why. + * + * XXX: For now we just focus the surface directly associated with + * the grab. + */ + meta_wayland_pointer_set_focus (pointer, + grab->shell_surface->surface, + wl_fixed_from_int (0), + wl_fixed_from_int (0)); +} + +static void +release_pointer (MetaWaylandGrab *grab) +{ + if (grab->shell_surface) + wl_list_remove (&grab->shell_surface_destroy_listener.link); + + meta_wayland_pointer_end_grab (grab->pointer); +} + +static void +noop_grab_focus (MetaWaylandPointerGrab *grab, + MetaWaylandSurface *surface, + wl_fixed_t x, + wl_fixed_t y) +{ + grab->focus = NULL; +} + +static void +move_grab_motion (MetaWaylandPointerGrab *grab, + uint32_t time, + wl_fixed_t x, + wl_fixed_t y) +{ + MetaWaylandMoveGrab *move = (MetaWaylandMoveGrab *)grab; + MetaWaylandPointer *pointer = move->base.pointer; + MetaWaylandShellSurface *shell_surface = move->base.shell_surface; + + if (!shell_surface) + return; + + meta_window_move (shell_surface->surface->window, + TRUE, + wl_fixed_to_int (pointer->x + move->dx), + wl_fixed_to_int (pointer->y + move->dy)); +} + +static void +move_grab_button (MetaWaylandPointerGrab *pointer_grab, + uint32_t time, + uint32_t button, + uint32_t state_w) +{ + MetaWaylandGrab *grab = + wl_container_of (pointer_grab, grab, grab); + MetaWaylandMoveGrab *move = (MetaWaylandMoveGrab *)grab; + MetaWaylandPointer *pointer = grab->pointer; + enum wl_pointer_button_state state = state_w; + + if (pointer->button_count == 0 && state == WL_POINTER_BUTTON_STATE_RELEASED) + { + release_pointer (grab); + g_slice_free (MetaWaylandMoveGrab, move); + } +} + +static const MetaWaylandPointerGrabInterface move_grab_interface = { + noop_grab_focus, + move_grab_motion, + move_grab_button, +}; + +static void +start_surface_move (MetaWaylandShellSurface *shell_surface, + MetaWaylandSeat *seat) +{ + MetaWaylandMoveGrab *move; + MetaRectangle rect; + + g_return_if_fail (shell_surface != NULL); + + /* TODO: check if the surface is fullscreen when we support fullscreen */ + + move = g_slice_new (MetaWaylandMoveGrab); + + meta_window_get_surface_rect (shell_surface->surface->window, + &rect); + + move->dx = wl_fixed_from_int (rect.x) - seat->pointer.grab_x; + move->dy = wl_fixed_from_int (rect.y) - seat->pointer.grab_y; + + grab_pointer (&move->base, &move_grab_interface, shell_surface, + &seat->pointer, GRAB_CURSOR_MOVE); +} + static void shell_surface_move (struct wl_client *client, struct wl_resource *resource, - struct wl_resource *seat, + struct wl_resource *seat_resource, guint32 serial) { + MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); + MetaWaylandShellSurface *shell_surface = wl_resource_get_user_data (resource); + + if (seat->pointer.button_count == 0 || + seat->pointer.grab_serial != serial || + seat->pointer.focus != shell_surface->surface) + return; + + start_surface_move (shell_surface, seat); } static void From 8c0779a9dba74d251ec6e85d4ab2b0ff19a95142 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Mon, 12 Aug 2013 09:45:49 +0200 Subject: [PATCH 012/889] wayland: add missing file A Makefile.am is required for the protocol/ directory https://bugzilla.gnome.org/show_bug.cgi?id=705815 --- protocol/Makefile.am | 1 + 1 file changed, 1 insertion(+) create mode 100644 protocol/Makefile.am diff --git a/protocol/Makefile.am b/protocol/Makefile.am new file mode 100644 index 000000000..4d3a8153a --- /dev/null +++ b/protocol/Makefile.am @@ -0,0 +1 @@ +EXTRA_DIST = xserver.xml From 9b966561c4031302d6f9bb0a2e337f7b649ad148 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 12 Aug 2013 12:08:49 -0400 Subject: [PATCH 013/889] configure.ac: Remove clutter-wayland-compositor dependency It's not necessary. --- configure.ac | 7 ------- 1 file changed, 7 deletions(-) diff --git a/configure.ac b/configure.ac index 4a4d2dad2..3b97b5c79 100644 --- a/configure.ac +++ b/configure.ac @@ -228,13 +228,6 @@ if test x$enable_wayland = "xyes"; then fi AC_MSG_RESULT(yes) - CLUTTER_WAYLAND_VERSION=1.9.3 - AC_MSG_CHECKING([Clutter Wayland Compositor >= $CLUTTER_WAYLAND_VERSION]) - if ! $PKG_CONFIG --atleast-version $CLUTTER_WAYLAND_VERSION clutter-wayland-compositor-1.0; then - AC_MSG_ERROR([wayland support enabled but no suitable clutter-wayland-compositor package found]) - fi - AC_MSG_RESULT(yes) - AC_PATH_PROG([WAYLAND_SCANNER],[wayland-scanner],[no]) AS_IF([test "x$WAYLAND_SCANNER" = "xno"], AC_MSG_ERROR([Could not find wayland-scanner in your PATH, required for parsing wayland extension protocols])) From 0ee2c21da712fc3c72e81df5087e072c5d4bea77 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 12 Aug 2013 12:13:45 -0400 Subject: [PATCH 014/889] meta-wayland: Remove get_surface_rect It's the same as get_input_rect, which we already have in window. --- src/wayland/meta-wayland.c | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index b35420188..b260c0d2d 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -723,21 +723,6 @@ shell_surface_pong (struct wl_client *client, { } -/* TODO: consider adding this to window.c */ -static void -meta_window_get_surface_rect (const MetaWindow *window, - MetaRectangle *rect) -{ - if (window->frame) - { - MetaFrameBorders borders; - *rect = window->frame->rect; - meta_frame_calc_borders (window->frame, &borders); - } - else - *rect = window->rect; -} - typedef struct _MetaWaylandGrab { MetaWaylandPointerGrab grab; @@ -883,8 +868,8 @@ start_surface_move (MetaWaylandShellSurface *shell_surface, move = g_slice_new (MetaWaylandMoveGrab); - meta_window_get_surface_rect (shell_surface->surface->window, - &rect); + meta_window_get_input_rect (shell_surface->surface->window, + &rect); move->dx = wl_fixed_from_int (rect.x) - seat->pointer.grab_x; move->dy = wl_fixed_from_int (rect.y) - seat->pointer.grab_y; From ef9ef87d91726cd733534f75c2d358c29dcd3925 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 12 Aug 2013 14:43:23 -0400 Subject: [PATCH 015/889] configure: Complete fix for removing clutter-wayland-compositor --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 3b97b5c79..993c775ae 100644 --- a/configure.ac +++ b/configure.ac @@ -235,7 +235,7 @@ if test x$enable_wayland = "xyes"; then AC_SUBST(XWAYLAND_PATH) - MUTTER_PC_MODULES="$MUTTER_PC_MODULES wayland-server clutter-wayland-compositor-1.0" + MUTTER_PC_MODULES="$MUTTER_PC_MODULES wayland-server" AC_DEFINE(HAVE_WAYLAND, , [Building with Wayland support]) have_wayland=yes fi From 03f55b9485ee8ad33e66be6d5211d39130dcbac3 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Mon, 12 Aug 2013 10:16:20 +0200 Subject: [PATCH 016/889] wayland: fix a #warning Remove window_surfaces, as the FIXME asks for. We don't need it because we can obtain the surface from the MetaWindow, and follow the wayland compositor path for both types of clients. https://bugzilla.gnome.org/show_bug.cgi?id=705818 --- src/compositor/meta-shaped-texture.c | 10 +--------- src/compositor/meta-window-actor.c | 6 +++--- src/wayland/meta-wayland-private.h | 3 --- src/wayland/meta-wayland.c | 12 ------------ 4 files changed, 4 insertions(+), 27 deletions(-) diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c index cc095751b..f0279f95c 100644 --- a/src/compositor/meta-shaped-texture.c +++ b/src/compositor/meta-shaped-texture.c @@ -503,15 +503,7 @@ meta_shaped_texture_get_wayland_surface (MetaShapedTexture *stex) ClutterActor * meta_shaped_texture_new_with_xwindow (Window xwindow) { -#ifdef HAVE_WAYLAND - if (meta_is_wayland_compositor ()) - { - MetaWaylandSurface *surface = meta_wayland_lookup_surface_for_xid (xwindow); - return meta_shaped_texture_new_with_wayland_surface (surface); - } - else -#endif - return g_object_new (META_TYPE_SHAPED_TEXTURE, NULL); + return g_object_new (META_TYPE_SHAPED_TEXTURE, NULL); } void diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index c905fbd77..d738947a9 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -371,12 +371,12 @@ meta_window_actor_constructed (GObject *object) if (!priv->actor) { - if (window->client_type == META_WINDOW_CLIENT_TYPE_X11) - priv->actor = meta_shaped_texture_new_with_xwindow (xwindow); #ifdef HAVE_WAYLAND - else + if (meta_is_wayland_compositor ()) priv->actor = meta_shaped_texture_new_with_wayland_surface (window->surface); + else #endif + priv->actor = meta_shaped_texture_new_with_xwindow (xwindow); clutter_actor_add_child (CLUTTER_ACTOR (self), priv->actor); diff --git a/src/wayland/meta-wayland-private.h b/src/wayland/meta-wayland-private.h index c33f7f943..b4ba57d51 100644 --- a/src/wayland/meta-wayland-private.h +++ b/src/wayland/meta-wayland-private.h @@ -164,7 +164,6 @@ struct _MetaWaylandCompositor pid_t xwayland_pid; struct wl_client *xwayland_client; struct wl_resource *xserver_resource; - GHashTable *window_surfaces; MetaWaylandSeat *seat; @@ -352,8 +351,6 @@ MetaWaylandCompositor *meta_wayland_compositor_get_default (void); void meta_wayland_handle_sig_child (void); -MetaWaylandSurface *meta_wayland_lookup_surface_for_xid (guint32 xid); - void meta_wayland_compositor_repick (MetaWaylandCompositor *compositor); void meta_wayland_compositor_set_input_focus (MetaWaylandCompositor *compositor, diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index b260c0d2d..b01c60bad 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -1138,8 +1138,6 @@ xserver_set_window_id (struct wl_client *client, surface->xid = xid; - g_hash_table_insert (compositor->window_surfaces, &xid, surface); - window = meta_display_lookup_x_window (display, xid); if (window) { @@ -1166,13 +1164,6 @@ xserver_set_window_id (struct wl_client *client, meta_wayland_compositor_set_input_focus (compositor, window); } -#warning "FIXME: Handle surface destroy and remove window_surfaces mapping" -} - -MetaWaylandSurface * -meta_wayland_lookup_surface_for_xid (guint32 xid) -{ - return g_hash_table_lookup (_meta_wayland_compositor.window_surfaces, &xid); } static const struct xserver_interface xserver_implementation = { @@ -1543,9 +1534,6 @@ meta_wayland_init (void) &xserver_interface, 1, compositor, bind_xserver); - /* We need a mapping from xids to wayland surfaces... */ - compositor->window_surfaces = g_hash_table_new (g_int_hash, g_int_equal); - /* XXX: It's important that we only try and start xwayland after we * have initialized EGL because EGL implements the "wl_drm" * interface which xwayland requires to determine what drm device From 9a5f243f73f4f93cce5d69bd1d8fccd674ac1f77 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Mon, 12 Aug 2013 18:04:34 +0200 Subject: [PATCH 017/889] wayland: refactor window destruction and focus The previous code was leaving focus fields dirty in MetaWaylandPointer and MetaWaylandKeyboard at time (which could crash the X server because of invalid object IDs) The new code is more tighly integrated in the normal X11 code for handling keyboard focus (meaning that the core idea of input focus is also correct now), so that meta_window_unmanage() can do the right thing. As a side benefit, clicking on wayland clients now unfocus X11 clients. For the mouse focus, we need to clear the surface pointer when the metawindowactor is destroyed (even if the actual actor is kept alive for effects), so that a repick finds a different pointer focus. https://bugzilla.gnome.org/show_bug.cgi?id=705859 --- src/compositor/meta-window-actor.c | 7 +- src/core/display.c | 37 ++++++---- src/core/window.c | 9 +++ src/wayland/meta-wayland-pointer.c | 8 ++- src/wayland/meta-wayland-private.h | 2 + src/wayland/meta-wayland.c | 110 ++++++++++++++++------------- 6 files changed, 108 insertions(+), 65 deletions(-) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index d738947a9..6949fcc73 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -1320,6 +1320,11 @@ meta_window_actor_destroy (MetaWindowActor *self) priv = self->priv; +#ifdef HAVE_WAYLAND + if (meta_is_wayland_compositor ()) + meta_shaped_texture_set_wayland_surface (META_SHAPED_TEXTURE (priv->actor), NULL); +#endif + window = priv->window; window_type = meta_window_get_window_type (window); meta_window_set_compositor_private (window, NULL); @@ -2466,7 +2471,7 @@ meta_window_actor_set_wayland_surface (MetaWindowActor *self, meta_shaped_texture_set_wayland_surface (META_SHAPED_TEXTURE (priv->actor), surface); - if (surface->buffer_ref.buffer) + if (surface && surface->buffer_ref.buffer) maybe_emit_size_changed (self, surface->buffer_ref.buffer); } diff --git a/src/core/display.c b/src/core/display.c index 53693685d..d633af3fd 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -1902,9 +1902,14 @@ update_focus_window (MetaDisplay *display, Window xwindow, gulong serial) { +#ifdef HAVE_WAYLAND + MetaWaylandCompositor *compositor; +#endif + display->focus_serial = serial; - if (display->focus_xwindow == xwindow) + if (display->focus_xwindow == xwindow && + display->focus_window == window) return; if (display->focus_window) @@ -1938,6 +1943,20 @@ update_focus_window (MetaDisplay *display, else meta_topic (META_DEBUG_FOCUS, "* Focus --> NULL with serial %lu\n", serial); +#ifdef HAVE_WAYLAND + if (meta_is_wayland_compositor ()) + { + compositor = meta_wayland_compositor_get_default (); + + if (meta_display_xwindow_is_a_no_focus_window (display, xwindow)) + meta_wayland_compositor_set_input_focus (compositor, NULL); + else if (window && window->surface) + meta_wayland_compositor_set_input_focus (compositor, window); + else + meta_topic (META_DEBUG_FOCUS, "Focus change has no effect, because there is no matching wayland surface"); + } +#endif + g_object_notify (G_OBJECT (display), "focus-window"); meta_display_update_active_window_hint (display); } @@ -1974,17 +1993,15 @@ timestamp_too_old (MetaDisplay *display, static void request_xserver_input_focus_change (MetaDisplay *display, MetaScreen *screen, + MetaWindow *meta_window, Window xwindow, guint32 timestamp) { - MetaWindow *meta_window; gulong serial; if (timestamp_too_old (display, ×tamp)) return; - meta_window = meta_display_lookup_x_window (display, xwindow); - meta_error_trap_push (display); /* In order for mutter to know that the focus request succeeded, we track @@ -2651,15 +2668,6 @@ meta_display_handle_event (MetaDisplay *display, } break; case XI_FocusIn: -#ifdef HAVE_WAYLAND - if (meta_is_wayland_compositor ()) - { - MetaWaylandCompositor *compositor = - meta_wayland_compositor_get_default (); - meta_wayland_compositor_set_input_focus (compositor, window); - } -#endif - /* fall through */ case XI_FocusOut: /* libXi does not properly copy the serial to the XIEnterEvent, so pull it * from the parent XAnyEvent. @@ -5884,6 +5892,7 @@ meta_display_set_input_focus_window (MetaDisplay *display, { request_xserver_input_focus_change (display, window->screen, + window, focus_frame ? window->frame->xwindow : window->xwindow, timestamp); } @@ -5931,6 +5940,7 @@ meta_display_set_input_focus_xwindow (MetaDisplay *display, { request_xserver_input_focus_change (display, screen, + NULL, window, timestamp); } @@ -5942,6 +5952,7 @@ meta_display_focus_the_no_focus_window (MetaDisplay *display, { request_xserver_input_focus_change (display, screen, + NULL, screen->no_focus_window, timestamp); } diff --git a/src/core/window.c b/src/core/window.c index 599965a51..efb4f74b4 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -62,6 +62,10 @@ #include +#ifdef HAVE_WAYLAND +#include "meta-wayland-private.h" +#endif + /* Windows that unmaximize to a size bigger than that fraction of the workarea * will be scaled down to that size (while maintaining aspect ratio). * Windows that cover an area greater then this size are automaximized on map. @@ -2103,6 +2107,11 @@ meta_window_unmanage (MetaWindow *window, meta_error_trap_pop (window->display); } +#ifdef HAVE_WAYLAND + if (window->surface) + meta_wayland_surface_free (window->surface); +#endif + meta_prefs_remove_listener (prefs_changed_callback, window); meta_screen_queue_check_fullscreen (window->screen); diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index 52a81ad7e..fd0efed2f 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -60,6 +60,7 @@ lose_pointer_focus (struct wl_listener *listener, void *data) wl_container_of (listener, pointer, focus_listener); pointer->focus_resource = NULL; + pointer->focus = NULL; } static void @@ -138,6 +139,9 @@ meta_wayland_pointer_release (MetaWaylandPointer *pointer) /* XXX: What about pointer->resource_list? */ if (pointer->focus_resource) wl_list_remove (&pointer->focus_listener.link); + + pointer->focus = NULL; + pointer->focus_resource = NULL; } static struct wl_resource * @@ -148,9 +152,7 @@ find_resource_for_surface (struct wl_list *list, MetaWaylandSurface *surface) if (!surface) return NULL; - if (!surface->resource) - return NULL; - + g_assert (surface->resource); client = wl_resource_get_client (surface->resource); return wl_resource_find_for_client (list, client); diff --git a/src/wayland/meta-wayland-private.h b/src/wayland/meta-wayland-private.h index b4ba57d51..92f5d83e1 100644 --- a/src/wayland/meta-wayland-private.h +++ b/src/wayland/meta-wayland-private.h @@ -356,4 +356,6 @@ void meta_wayland_compositor_repick (MetaWaylandComp void meta_wayland_compositor_set_input_focus (MetaWaylandCompositor *compositor, MetaWindow *window); +void meta_wayland_surface_free (MetaWaylandSurface *surface); + #endif /* META_WAYLAND_PRIVATE_H */ diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index b01c60bad..7c41c217d 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -247,6 +247,10 @@ meta_wayland_surface_attach (struct wl_client *wayland_client, wl_resource_get_user_data (wayland_surface_resource); MetaWaylandBuffer *buffer; + /* X11 unmanaged window */ + if (!surface) + return; + if (wayland_buffer_resource) buffer = meta_wayland_buffer_from_resource (wayland_buffer_resource); else @@ -277,6 +281,10 @@ meta_wayland_surface_damage (struct wl_client *client, MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); cairo_rectangle_int_t rectangle = { x, y, width, height }; + /* X11 unmanaged window */ + if (!surface) + return; + cairo_region_union_rectangle (surface->pending.damage, &rectangle); } @@ -298,6 +306,10 @@ meta_wayland_surface_frame (struct wl_client *client, MetaWaylandFrameCallback *callback; MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); + /* X11 unmanaged window */ + if (!surface) + return; + callback = g_slice_new0 (MetaWaylandFrameCallback); callback->compositor = surface->compositor; callback->resource = wl_resource_create (client, @@ -337,7 +349,13 @@ meta_wayland_surface_commit (struct wl_client *client, struct wl_resource *resource) { MetaWaylandSurface *surface = wl_resource_get_user_data (resource); - MetaWaylandCompositor *compositor = surface->compositor; + MetaWaylandCompositor *compositor; + + /* X11 unmanaged window */ + if (!surface) + return; + + compositor = surface->compositor; /* wl_surface.attach */ if (surface->pending.newly_attached && @@ -432,14 +450,6 @@ meta_wayland_compositor_set_input_focus (MetaWaylandCompositor *compositor, meta_wayland_data_device_set_keyboard_focus (compositor->seat); } -static void -window_destroyed_cb (void *user_data, GObject *old_object) -{ - MetaWaylandSurface *surface = user_data; - - surface->window = NULL; -} - void meta_wayland_compositor_repick (MetaWaylandCompositor *compositor) { @@ -448,7 +458,7 @@ meta_wayland_compositor_repick (MetaWaylandCompositor *compositor) NULL); } -static void +void meta_wayland_surface_free (MetaWaylandSurface *surface) { MetaWaylandCompositor *compositor = surface->compositor; @@ -458,21 +468,6 @@ meta_wayland_surface_free (MetaWaylandSurface *surface) meta_wayland_buffer_reference (&surface->buffer_ref, NULL); - if (surface->window) - g_object_weak_unref (G_OBJECT (surface->window), - window_destroyed_cb, - surface); - - /* NB: If the surface corresponds to an X window then we will be - * sure to free the MetaWindow according to some X event. */ - if (surface->window && - surface->window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND) - { - MetaDisplay *display = meta_get_display (); - guint32 timestamp = meta_display_get_current_time_roundtrip (display); - meta_window_unmanage (surface->window, timestamp); - } - if (surface->pending.buffer) wl_list_remove (&surface->pending.buffer_destroy_listener.link); @@ -482,19 +477,51 @@ meta_wayland_surface_free (MetaWaylandSurface *surface) &surface->pending.frame_callback_list, link) wl_resource_destroy (cb->resource); - g_slice_free (MetaWaylandSurface, surface); - meta_wayland_compositor_repick (compositor); + /* Check that repick didn't pick the freed surface */ + g_assert (surface != compositor->seat->pointer.focus); + g_assert (surface != compositor->seat->keyboard.focus); + if (compositor->implicit_grab_surface == surface) compositor->implicit_grab_surface = compositor->seat->pointer.current; + + if (surface->resource) + wl_resource_set_user_data (surface->resource, NULL); + g_slice_free (MetaWaylandSurface, surface); } static void meta_wayland_surface_resource_destroy_cb (struct wl_resource *resource) { MetaWaylandSurface *surface = wl_resource_get_user_data (resource); - meta_wayland_surface_free (surface); + + /* There are four cases here: + - An X11 unmanaged window -> surface is NULL, nothing to do + - An X11 unmanaged window, but we got the wayland event first -> + just clear the resource pointer + - A wayland surface without window (destroyed before set_toplevel) -> + need to free the surface itself + - A wayland window -> need to unmanage + */ + + if (surface) + { + surface->resource = NULL; + + /* NB: If the surface corresponds to an X window then we will be + * sure to free the MetaWindow according to some X event. */ + if (surface->window && + surface->window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND) + { + MetaDisplay *display = meta_get_display (); + guint32 timestamp = meta_display_get_current_time_roundtrip (display); + + meta_window_unmanage (surface->window, timestamp); + } + else + meta_wayland_surface_free (surface); + } } static void @@ -929,13 +956,6 @@ ensure_surface_window (MetaWaylandSurface *surface) surface->window = meta_window_new_for_wayland (display, width, height, surface); - /* If the MetaWindow becomes unmanaged (surface->window will be - * freed in this case) we need to make sure to clear our - * ->window pointers. */ - g_object_weak_ref (G_OBJECT (surface->window), - window_destroyed_cb, - surface); - meta_window_calc_showing (surface->window); } } @@ -1149,13 +1169,6 @@ xserver_set_window_id (struct wl_client *client, surface->window = window; window->surface = surface; - /* If the MetaWindow becomes unmanaged (surface->window will be - * freed in this case) we need to make sure to clear our - * ->window pointers in this case. */ - g_object_weak_ref (G_OBJECT (surface->window), - window_destroyed_cb, - surface); - /* If the window is already meant to have focus then the * original attempt to call this in response to the FocusIn * event will have been lost because there was no surface @@ -1342,7 +1355,7 @@ event_cb (ClutterActor *stage, meta_wayland_seat_handle_event (compositor->seat, event); /* HACK: for now, the surfaces from Wayland clients aren't - integrated into Mutter's stacking and Mutter won't give them + integrated into Mutter's event handling and Mutter won't give them focus on mouse clicks. As a hack to work around this we can just give them input focus on mouse clicks so we can at least test the keyboard support */ @@ -1350,12 +1363,13 @@ event_cb (ClutterActor *stage, { surface = pointer->current; - /* Only focus surfaces that wouldn't be handled by the - corresponding X events */ - if (surface && surface->xid == 0) + if (surface && surface->window && + surface->window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND) { - meta_wayland_keyboard_set_focus (&seat->keyboard, surface); - meta_wayland_data_device_set_keyboard_focus (seat); + MetaDisplay *display = meta_get_display (); + guint32 timestamp = meta_display_get_current_time_roundtrip (display); + + meta_window_focus (surface->window, timestamp); } } From 2f3a5f200143d4641e5c5021557b2cb1ba8d813f Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Wed, 14 Aug 2013 16:29:09 +0200 Subject: [PATCH 018/889] MetaWaylandSeat: correct logic to set the current / focused surface The current surface refers to the surface right below the pointer (according to the pick performed by clutter), while the focus surface is the one receiving events. They can be out of sync in case of grabs, in which case we should keep trying to focus the current surface. https://bugzilla.gnome.org/show_bug.cgi?id=706077 --- src/wayland/meta-wayland-seat.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c index 9fb285abf..0d2b729e5 100644 --- a/src/wayland/meta-wayland-seat.c +++ b/src/wayland/meta-wayland-seat.c @@ -507,14 +507,14 @@ meta_wayland_seat_repick (MetaWaylandSeat *seat, surface = meta_shaped_texture_get_wayland_surface (shaped_texture); } - if (surface != pointer->current) + pointer->current = surface; + if (surface != pointer->focus) { const MetaWaylandPointerGrabInterface *interface = pointer->grab->interface; interface->focus (pointer->grab, surface, pointer->current_x, pointer->current_y); - pointer->current = surface; } if (pointer->grab->focus) From 152d896f755ef191695e359ef77be94591bdadbf Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Thu, 15 Aug 2013 16:45:54 +0200 Subject: [PATCH 019/889] MetaWindowActor/wayland: make sure the mapped bit is correctly set Otherwise it stays FALSE for OR windows, causing the shape region to be empty and the actor culled from drawing. https://bugzilla.gnome.org/show_bug.cgi?id=706078 --- src/compositor/meta-window-actor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 6949fcc73..0e233db62 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -1583,13 +1583,13 @@ meta_window_actor_new (MetaWindow *window) NULL); priv = self->priv; + priv->mapped = meta_window_toplevel_is_mapped (priv->window); if (!meta_is_wayland_compositor ()) { priv->last_width = -1; priv->last_height = -1; - priv->mapped = meta_window_toplevel_is_mapped (priv->window); if (priv->mapped) meta_window_actor_queue_create_x11_pixmap (self); From 3803fd9511eb5341412507fa706f8098a37e4897 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Mon, 12 Aug 2013 09:46:07 +0200 Subject: [PATCH 020/889] wayland: don't use fork() and SIGCHLD to spawn processes It is a very bad idea in a glib program (especially one heavily using glib child watching facilities, like gnome-shell) to handle SIGCHLD. While we're there, let's also use g_spawn_async, which solves some malloc-after-fork problems and makes the code generally cleaner. https://bugzilla.gnome.org/show_bug.cgi?id=705816 --- src/core/main.c | 15 ---- src/wayland/meta-wayland-private.h | 2 - src/wayland/meta-wayland.c | 24 ------ src/wayland/meta-xwayland.c | 123 +++++++++++++++++++---------- 4 files changed, 80 insertions(+), 84 deletions(-) diff --git a/src/core/main.c b/src/core/main.c index 276dba582..0326d8ec3 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -368,9 +368,6 @@ signal_handler (int signum) case SIGTERM: write (signal_pipe_fds[1], "T", 1); break; - case SIGCHLD: - write (signal_pipe_fds[1], "C", 1); - break; default: break; } @@ -407,11 +404,6 @@ on_signal (GIOChannel *source, case 'T': /* SIGTERM */ meta_quit (META_EXIT_SUCCESS); break; -#ifdef HAVE_WAYLAND - case 'C': /* SIGCHLD */ - meta_wayland_handle_sig_child (); - break; -#endif default: g_warning ("Spurious character '%c' read from signal pipe", signal); } @@ -460,13 +452,6 @@ meta_init (void) g_printerr ("Failed to register SIGTERM handler: %s\n", g_strerror (errno)); - if (meta_is_wayland_compositor ()) - { - if (sigaction (SIGCHLD, &act, NULL) < 0) - g_printerr ("Failed to register SIGCHLD handler: %s\n", - g_strerror (errno)); - } - if (g_getenv ("MUTTER_VERBOSE")) meta_set_verbose (TRUE); if (g_getenv ("MUTTER_DEBUG")) diff --git a/src/wayland/meta-wayland-private.h b/src/wayland/meta-wayland-private.h index 92f5d83e1..a859378c1 100644 --- a/src/wayland/meta-wayland-private.h +++ b/src/wayland/meta-wayland-private.h @@ -349,8 +349,6 @@ void meta_wayland_finalize (void); * API after meta_wayland_init() has been called. */ MetaWaylandCompositor *meta_wayland_compositor_get_default (void); -void meta_wayland_handle_sig_child (void); - void meta_wayland_compositor_repick (MetaWaylandCompositor *compositor); void meta_wayland_compositor_set_input_focus (MetaWaylandCompositor *compositor, diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index 7c41c217d..159499e1c 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -1576,27 +1576,3 @@ meta_wayland_finalize (void) { meta_xwayland_stop (meta_wayland_compositor_get_default ()); } - -void -meta_wayland_handle_sig_child (void) -{ - int status; - pid_t pid = waitpid (-1, &status, WNOHANG); - MetaWaylandCompositor *compositor = &_meta_wayland_compositor; - - /* The simplest measure to avoid infinitely re-spawning a crashing - * X server */ - if (pid == compositor->xwayland_pid) - { - if (!WIFEXITED (status)) - g_critical ("X Wayland crashed; aborting"); - else - { - /* For now we simply abort if we see the server exit. - * - * In the future X will only be loaded lazily for legacy X support - * but for now it's a hard requirement. */ - g_critical ("Spurious exit of X Wayland server"); - } - } -} diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index 7ff30bf92..56d3b7152 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -28,6 +28,8 @@ #include #include #include +#include +#include static char * create_lockfile (int display, int *display_out) @@ -183,6 +185,39 @@ bind_to_unix_socket (int display) return fd; } +static void +uncloexec_and_setpgid (gpointer user_data) +{ + int fd = GPOINTER_TO_INT (user_data); + + /* Make sure the client end of the socket pair doesn't get closed + * when we exec xwayland. */ + int flags = fcntl (fd, F_GETFD); + if (flags != -1) + fcntl (fd, F_SETFD, flags & ~FD_CLOEXEC); + + /* Put this process in a background process group, so that Ctrl-C + goes to mutter only */ + setpgid (0, 0); +} + +static void +xserver_died (GPid pid, + gint status, + gpointer user_data) +{ + if (!WIFEXITED (status)) + g_error ("X Wayland crashed; aborting"); + else + { + /* For now we simply abort if we see the server exit. + * + * In the future X will only be loaded lazily for legacy X support + * but for now it's a hard requirement. */ + g_error ("Spurious exit of X Wayland server"); + } +} + gboolean meta_xwayland_start (MetaWaylandCompositor *compositor) { @@ -190,6 +225,11 @@ meta_xwayland_start (MetaWaylandCompositor *compositor) char *lockfile = NULL; int sp[2]; pid_t pid; + char **env; + char *fd_string; + char *display_name; + char *args[11]; + GError *error; do { @@ -238,45 +278,39 @@ meta_xwayland_start (MetaWaylandCompositor *compositor) return 1; } - switch ((pid = fork())) + env = g_get_environ (); + fd_string = g_strdup_printf ("%d", sp[1]); + env = g_environ_setenv (env, "WAYLAND_SOCKET", fd_string, TRUE); + g_free (fd_string); + + display_name = g_strdup_printf (":%d", + compositor->xwayland_display_index); + + args[0] = XWAYLAND_PATH; + args[1] = display_name; + args[2] = "-wayland"; + args[3] = "-rootless"; + args[4] = "-retro"; + args[5] = "-noreset"; + args[6] = "-logfile"; + args[7] = g_build_filename (g_get_user_cache_dir (), "xwayland.log", NULL); + args[8] = "-nolisten"; + args[9] = "all"; + args[10] = NULL; + + error = NULL; + if (g_spawn_async (NULL, /* cwd */ + args, + env, + G_SPAWN_LEAVE_DESCRIPTORS_OPEN | + G_SPAWN_DO_NOT_REAP_CHILD | + G_SPAWN_STDOUT_TO_DEV_NULL | + G_SPAWN_STDERR_TO_DEV_NULL, + uncloexec_and_setpgid, + GINT_TO_POINTER (sp[1]), + &pid, + &error)) { - case 0: - { - char *fd_string; - char *display_name; - /* Make sure the client end of the socket pair doesn't get closed - * when we exec xwayland. */ - int flags = fcntl (sp[1], F_GETFD); - if (flags != -1) - fcntl (sp[1], F_SETFD, flags & ~FD_CLOEXEC); - - fd_string = g_strdup_printf ("%d", sp[1]); - setenv ("WAYLAND_SOCKET", fd_string, 1); - g_free (fd_string); - - display_name = g_strdup_printf (":%d", - compositor->xwayland_display_index); - - if (execl (XWAYLAND_PATH, - XWAYLAND_PATH, - display_name, - "-wayland", - "-rootless", - "-retro", - "-noreset", - /* FIXME: does it make sense to log to the filesystem by - * default? */ - "-logfile", "/tmp/xwayland.log", - "-nolisten", "all", - NULL) < 0) - { - char *msg = strerror (errno); - g_warning ("xwayland exec failed: %s", msg); - } - exit (-1); - return FALSE; - } - default: g_message ("forked X server, pid %d\n", pid); close (sp[1]); @@ -284,12 +318,15 @@ meta_xwayland_start (MetaWaylandCompositor *compositor) wl_client_create (compositor->wayland_display, sp[0]); compositor->xwayland_pid = pid; - break; - - case -1: - g_error ("Failed to fork for xwayland server"); - return FALSE; + g_child_watch_add (pid, xserver_died, NULL); } + else + { + g_error ("Failed to fork for xwayland server: %s", error->message); + } + + g_strfreev (env); + g_free (display_name); return TRUE; } From 18a21b67c271c75f8f2cb0e0035ee1f08e74fa92 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Mon, 12 Aug 2013 10:06:13 +0200 Subject: [PATCH 021/889] wayland: move XWayland support code to its own file Given that xwayland code is already split in meta-xwayland, it makes sense to have there the implementation of the private xserver protocol too. https://bugzilla.gnome.org/show_bug.cgi?id=705816 --- src/wayland/meta-wayland.c | 94 ----------------------------------- src/wayland/meta-xwayland.c | 98 ++++++++++++++++++++++++++++++++++++- 2 files changed, 96 insertions(+), 96 deletions(-) diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index 159499e1c..5b62e8967 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -35,8 +35,6 @@ #include -#include "xserver-server-protocol.h" - #include "meta-wayland-private.h" #include "meta-xwayland-private.h" #include "meta-wayland-stage.h" @@ -1142,87 +1140,6 @@ bind_shell (struct wl_client *client, wl_resource_set_implementation (resource, &meta_wayland_shell_interface, data, NULL); } -static void -xserver_set_window_id (struct wl_client *client, - struct wl_resource *compositor_resource, - struct wl_resource *surface_resource, - guint32 xid) -{ - MetaWaylandCompositor *compositor = - wl_resource_get_user_data (compositor_resource); - MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); - MetaDisplay *display = meta_get_display (); - MetaWindow *window; - - g_return_if_fail (surface->xid == None); - - surface->xid = xid; - - window = meta_display_lookup_x_window (display, xid); - if (window) - { - MetaWindowActor *window_actor = - META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - - meta_window_actor_set_wayland_surface (window_actor, surface); - - surface->window = window; - window->surface = surface; - - /* If the window is already meant to have focus then the - * original attempt to call this in response to the FocusIn - * event will have been lost because there was no surface - * yet. */ - if (window->has_focus) - meta_wayland_compositor_set_input_focus (compositor, window); - - } -} - -static const struct xserver_interface xserver_implementation = { - xserver_set_window_id -}; - -static void -bind_xserver (struct wl_client *client, - void *data, - guint32 version, - guint32 id) -{ - MetaWaylandCompositor *compositor = data; - - /* If it's a different client than the xserver we launched, - * don't start the wm. */ - if (client != compositor->xwayland_client) - return; - - compositor->xserver_resource = - wl_resource_create (client, &xserver_interface, version, id); - wl_resource_set_implementation (compositor->xserver_resource, - &xserver_implementation, compositor, NULL); - - wl_resource_post_event (compositor->xserver_resource, - XSERVER_LISTEN_SOCKET, - compositor->xwayland_abstract_fd); - - wl_resource_post_event (compositor->xserver_resource, - XSERVER_LISTEN_SOCKET, - compositor->xwayland_unix_fd); - - /* Make sure xwayland will recieve the above sockets in a finite - * time before unblocking the initialization mainloop since we are - * then going to immediately try and connect to those as the window - * manager. */ - wl_client_flush (client); - - /* At this point xwayland is all setup to start accepting - * connections so we can quit the transient initialization mainloop - * and unblock meta_wayland_init() to continue initializing mutter. - * */ - g_main_loop_quit (compositor->init_loop); - compositor->init_loop = NULL; -} - static void stage_destroy_cb (void) { @@ -1544,10 +1461,6 @@ meta_wayland_init (void) if (wl_display_add_socket (compositor->wayland_display, "wayland-0")) g_error ("Failed to create socket"); - wl_global_create (compositor->wayland_display, - &xserver_interface, 1, - compositor, bind_xserver); - /* XXX: It's important that we only try and start xwayland after we * have initialized EGL because EGL implements the "wl_drm" * interface which xwayland requires to determine what drm device @@ -1562,13 +1475,6 @@ meta_wayland_init (void) g_error ("Failed to start X Wayland"); putenv (g_strdup_printf ("DISPLAY=:%d", compositor->xwayland_display_index)); - - /* We need to run a mainloop until we know xwayland has a binding - * for our xserver interface at which point we can assume it's - * ready to start accepting connections. */ - compositor->init_loop = g_main_loop_new (NULL, FALSE); - - g_main_loop_run (compositor->init_loop); } void diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index 56d3b7152..d78b199bc 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -19,8 +19,6 @@ * 02111-1307, USA. */ -#include "meta-xwayland-private.h" - #include #include @@ -31,6 +29,91 @@ #include #include +#include "meta-xwayland-private.h" +#include "meta-window-actor-private.h" +#include "xserver-server-protocol.h" + +static void +xserver_set_window_id (struct wl_client *client, + struct wl_resource *compositor_resource, + struct wl_resource *surface_resource, + guint32 xid) +{ + MetaWaylandCompositor *compositor = + wl_resource_get_user_data (compositor_resource); + MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); + MetaDisplay *display = meta_get_display (); + MetaWindow *window; + + g_return_if_fail (surface->xid == None); + + surface->xid = xid; + + window = meta_display_lookup_x_window (display, xid); + if (window) + { + MetaWindowActor *window_actor = + META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); + + meta_window_actor_set_wayland_surface (window_actor, surface); + + surface->window = window; + window->surface = surface; + + /* If the window is already meant to have focus then the + * original attempt to call this in response to the FocusIn + * event will have been lost because there was no surface + * yet. */ + if (window->has_focus) + meta_wayland_compositor_set_input_focus (compositor, window); + + } +} + +static const struct xserver_interface xserver_implementation = { + xserver_set_window_id +}; + +static void +bind_xserver (struct wl_client *client, + void *data, + guint32 version, + guint32 id) +{ + MetaWaylandCompositor *compositor = data; + + /* If it's a different client than the xserver we launched, + * don't start the wm. */ + if (client != compositor->xwayland_client) + return; + + compositor->xserver_resource = + wl_resource_create (client, &xserver_interface, version, id); + wl_resource_set_implementation (compositor->xserver_resource, + &xserver_implementation, compositor, NULL); + + wl_resource_post_event (compositor->xserver_resource, + XSERVER_LISTEN_SOCKET, + compositor->xwayland_abstract_fd); + + wl_resource_post_event (compositor->xserver_resource, + XSERVER_LISTEN_SOCKET, + compositor->xwayland_unix_fd); + + /* Make sure xwayland will recieve the above sockets in a finite + * time before unblocking the initialization mainloop since we are + * then going to immediately try and connect to those as the window + * manager. */ + wl_client_flush (client); + + /* At this point xwayland is all setup to start accepting + * connections so we can quit the transient initialization mainloop + * and unblock meta_wayland_init() to continue initializing mutter. + * */ + g_main_loop_quit (compositor->init_loop); + compositor->init_loop = NULL; +} + static char * create_lockfile (int display, int *display_out) { @@ -231,6 +314,10 @@ meta_xwayland_start (MetaWaylandCompositor *compositor) char *args[11]; GError *error; + wl_global_create (compositor->wayland_display, + &xserver_interface, 1, + compositor, bind_xserver); + do { lockfile = create_lockfile (display, &display); @@ -328,6 +415,13 @@ meta_xwayland_start (MetaWaylandCompositor *compositor) g_strfreev (env); g_free (display_name); + /* We need to run a mainloop until we know xwayland has a binding + * for our xserver interface at which point we can assume it's + * ready to start accepting connections. */ + compositor->init_loop = g_main_loop_new (NULL, FALSE); + + g_main_loop_run (compositor->init_loop); + return TRUE; } From 24564c77d61d429649110c751c65ba2aa161303c Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sat, 17 Aug 2013 17:50:07 -0400 Subject: [PATCH 022/889] build: Fix srcdir != builddir Need to ensure the wayland/ directory exists in $(builddir), and find the headers there too. --- src/Makefile.am | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Makefile.am b/src/Makefile.am index 1c0ac255a..491e78445 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -32,6 +32,7 @@ INCLUDES= \ if HAVE_WAYLAND INCLUDES += \ -I$(srcdir)/wayland \ + -I$(builddir)/wayland \ -DXWAYLAND_PATH='"@XWAYLAND_PATH@"' endif @@ -357,9 +358,12 @@ mutter-enum-types.c: stamp-mutter-enum-types.h mutter-enum-types.c.in if HAVE_WAYLAND wayland/%-protocol.c : $(top_builddir)/protocol/%.xml + mkdir -p wayland $(AM_V_GEN)$(WAYLAND_SCANNER) code < $< > $@ wayland/%-server-protocol.h : $(top_builddir)/protocol/%.xml + mkdir -p wayland $(AM_V_GEN)$(WAYLAND_SCANNER) server-header < $< > $@ wayland/%-client-protocol.h : $(top_builddir)/protocol/%.xml + mkdir -p wayland $(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@ endif From bfc87d13cb0e101ffc351e535a3565a97f2282b5 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Sat, 17 Aug 2013 15:51:33 +0200 Subject: [PATCH 023/889] MetaWindowActor: fix reference counting issue We need to use g_signal_connect_object(), rather than g_signal_connect(), because the window actor can be destroyed before the window emits the final notify::appears-focused inside unmanage, if the plugin decides that it doesn't want to animate the destruction (which happens with dialogs and the default plugin) https://bugzilla.gnome.org/show_bug.cgi?id=706207 --- src/compositor/meta-window-actor.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 0e233db62..f7d61f6ef 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -392,10 +392,10 @@ meta_window_actor_constructed (GObject *object) */ g_object_ref (priv->actor); - g_signal_connect (window, "notify::decorated", - G_CALLBACK (window_decorated_notify), self); - g_signal_connect (window, "notify::appears-focused", - G_CALLBACK (window_appears_focused_notify), self); + g_signal_connect_object (window, "notify::decorated", + G_CALLBACK (window_decorated_notify), self, 0); + g_signal_connect_object (window, "notify::appears-focused", + G_CALLBACK (window_appears_focused_notify), self, 0); } else { From 4fd3c63da9b68b47ad74534e2fec18399657e03a Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Mon, 19 Aug 2013 13:01:55 +0200 Subject: [PATCH 024/889] ui: restrict gtk to only use the x11 backend We use GTK as a way to get the X11 connection for our internal use, so we need it to keep using X. https://bugzilla.gnome.org/show_bug.cgi?id=706303 --- src/ui/ui.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ui/ui.c b/src/ui/ui.c index fc6fb4dc2..ed2c66d13 100644 --- a/src/ui/ui.c +++ b/src/ui/ui.c @@ -56,6 +56,8 @@ struct _MetaUI void meta_ui_init (void) { + gdk_set_allowed_backends ("x11"); + if (!gtk_init_check (NULL, NULL)) meta_fatal ("Unable to open X display %s\n", XDisplayName (NULL)); } From 2ae7454f36bb5b73732ac3a01244a5862e3e8f1c Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Tue, 13 Aug 2013 12:57:41 +0200 Subject: [PATCH 025/889] Add MetaCursorTracker, a new helper for tracking the cursor sprite Under X, we need to use XFixes to watch the cursor changing, while on wayland, we're in charge of setting and painting the cursor. MetaCursorTracker provides the abstraction layer for gnome-shell, which can thus drop ShellXFixesCursor. In the future, it may grow the ability to watch for pointer position too, especially if CursorEvents are added to the next version of XInput2, and thus it would also replace the PointerWatcher we use for gnome-shell's magnifier. https://bugzilla.gnome.org/show_bug.cgi?id=705911 --- src/Makefile.am | 3 + src/core/display.c | 8 + src/core/meta-cursor-tracker-private.h | 46 +++ src/core/meta-cursor-tracker.c | 451 +++++++++++++++++++++++++ src/core/screen-private.h | 4 + src/core/screen.c | 31 +- src/meta/meta-cursor-tracker.h | 49 +++ src/meta/types.h | 1 + src/wayland/meta-wayland-private.h | 2 + src/wayland/meta-wayland-seat.c | 46 ++- src/wayland/meta-wayland-stage.c | 187 +--------- src/wayland/meta-wayland-stage.h | 41 --- src/wayland/meta-wayland.c | 16 +- 13 files changed, 625 insertions(+), 260 deletions(-) create mode 100644 src/core/meta-cursor-tracker-private.h create mode 100644 src/core/meta-cursor-tracker.c create mode 100644 src/meta/meta-cursor-tracker.h diff --git a/src/Makefile.am b/src/Makefile.am index 491e78445..8c1b393e1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -124,6 +124,8 @@ libmutter_la_SOURCES = \ core/keybindings.c \ core/keybindings-private.h \ core/main.c \ + core/meta-cursor-tracker.c \ + core/meta-cursor-tracker-private.h \ core/mutter-Xatomtype.h \ core/place.c \ core/place.h \ @@ -210,6 +212,7 @@ libmutterinclude_base_headers = \ meta/meta-background-actor.h \ meta/meta-background-group.h \ meta/meta-background.h \ + meta/meta-cursor-tracker.h \ meta/meta-plugin.h \ meta/meta-shaped-texture.h \ meta/meta-shadow-factory.h \ diff --git a/src/core/display.c b/src/core/display.c index c71b8c34a..316748d8a 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -2177,6 +2177,7 @@ meta_display_handle_event (MetaDisplay *display, gboolean bypass_compositor; gboolean filter_out_event; XIEvent *input_event; + MetaScreen *screen; #ifdef WITH_VERBOSE_MODE if (dump_events) @@ -2204,6 +2205,13 @@ meta_display_handle_event (MetaDisplay *display, display->server_focus_serial); } + screen = meta_display_screen_for_root (display, event->xany.window); + if (screen) + { + if (meta_screen_handle_xevent (screen, event)) + return TRUE; + } + modified = event_get_modified_window (display, event); input_event = get_input_event (display, event); diff --git a/src/core/meta-cursor-tracker-private.h b/src/core/meta-cursor-tracker-private.h new file mode 100644 index 000000000..773ac0020 --- /dev/null +++ b/src/core/meta-cursor-tracker-private.h @@ -0,0 +1,46 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright 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. + * + * Author: Giovanni Campagna + */ + +#ifndef META_CURSOR_TRACKER_PRIVATE_H +#define META_CURSOR_TRACKER_PRIVATE_H + +#include + +gboolean meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker, + XEvent *xevent); + +void meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker, + MetaCursor cursor); +void meta_cursor_tracker_revert_root (MetaCursorTracker *tracker); +void meta_cursor_tracker_set_sprite (MetaCursorTracker *tracker, + CoglTexture2D *texture, + int hot_x, + int hot_y); + +void meta_cursor_tracker_update_position (MetaCursorTracker *tracker, + int new_x, + int new_y); +void meta_cursor_tracker_paint (MetaCursorTracker *tracker); +void meta_cursor_tracker_queue_redraw (MetaCursorTracker *tracker, + ClutterActor *stage); +#endif diff --git a/src/core/meta-cursor-tracker.c b/src/core/meta-cursor-tracker.c new file mode 100644 index 000000000..4a374d54d --- /dev/null +++ b/src/core/meta-cursor-tracker.c @@ -0,0 +1,451 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright 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. + * + * Author: Giovanni Campagna + */ + +/** + * SECTION:cursor-tracker + * @title: MetaCursorTracker + * @short_description: Mutter cursor tracking helper + */ + +#include +#include +#include +#include + +#include +#include + +#include + +#include "meta-cursor-tracker-private.h" +#include "screen-private.h" +#include "meta-wayland-private.h" + +#define META_WAYLAND_DEFAULT_CURSOR_HOTSPOT_X 7 +#define META_WAYLAND_DEFAULT_CURSOR_HOTSPOT_Y 4 + +struct _MetaCursorTracker { + GObject parent_instance; + + MetaScreen *screen; + + gboolean is_showing; + + CoglTexture2D *sprite; + int hot_x, hot_y; + + CoglTexture2D *root_cursor; + int root_hot_x, root_hot_y; + + CoglTexture2D *default_cursor; + + int current_x, current_y; + cairo_rectangle_int_t current_rect; + cairo_rectangle_int_t previous_rect; + gboolean previous_is_valid; + + CoglPipeline *pipeline; +}; + +struct _MetaCursorTrackerClass { + GObjectClass parent_class; +}; + +G_DEFINE_TYPE (MetaCursorTracker, meta_cursor_tracker, G_TYPE_OBJECT); + +enum { + CURSOR_CHANGED, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL]; + +static void +meta_cursor_tracker_init (MetaCursorTracker *self) +{ + /* (JS) Best (?) that can be assumed since XFixes doesn't provide a way of + detecting if the system mouse cursor is showing or not. + + On wayland we start with the cursor showing + */ + self->is_showing = TRUE; +} + +static void +meta_cursor_tracker_finalize (GObject *object) +{ + MetaCursorTracker *self = META_CURSOR_TRACKER (object); + + if (self->sprite) + cogl_object_unref (self->sprite); + if (self->root_cursor) + cogl_object_unref (self->root_cursor); + if (self->default_cursor) + cogl_object_unref (self->default_cursor); + if (self->pipeline) + cogl_object_unref (self->pipeline); + + G_OBJECT_CLASS (meta_cursor_tracker_parent_class)->finalize (object); +} + +static void +meta_cursor_tracker_class_init (MetaCursorTrackerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_cursor_tracker_finalize; + + signals[CURSOR_CHANGED] = g_signal_new ("cursor-changed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); +} + +static MetaCursorTracker * +make_wayland_cursor_tracker (MetaScreen *screen) +{ + MetaWaylandCompositor *compositor; + CoglContext *ctx; + MetaCursorTracker *self = g_object_new (META_TYPE_CURSOR_TRACKER, NULL); + self->screen = screen; + + ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ()); + self->pipeline = cogl_pipeline_new (ctx); + + compositor = meta_wayland_compositor_get_default (); + compositor->seat->cursor_tracker = self; + + return self; +} + +static MetaCursorTracker * +make_x11_cursor_tracker (MetaScreen *screen) +{ + MetaCursorTracker *self = g_object_new (META_TYPE_CURSOR_TRACKER, NULL); + self->screen = screen; + + XFixesSelectCursorInput (screen->display->xdisplay, + screen->xroot, + XFixesDisplayCursorNotifyMask); + + return self; +} + +/** + * meta_cursor_tracker_get_for_screen: + * @screen: the #MetaScreen + * + * Retrieves the cursor tracker object for @screen. + * + * Returns: (transfer none): + */ +MetaCursorTracker * +meta_cursor_tracker_get_for_screen (MetaScreen *screen) +{ + MetaCursorTracker *self; + + if (screen->cursor_tracker) + return screen->cursor_tracker; + + if (meta_is_wayland_compositor ()) + self = make_wayland_cursor_tracker (screen); + else + self = make_x11_cursor_tracker (screen); + + screen->cursor_tracker = self; + return self; +} + +gboolean +meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker, + XEvent *xevent) +{ + XFixesCursorNotifyEvent *notify_event; + + if (meta_is_wayland_compositor ()) + return FALSE; + + if (xevent->xany.type != tracker->screen->display->xfixes_event_base + XFixesCursorNotify) + return FALSE; + + notify_event = (XFixesCursorNotifyEvent *)xevent; + if (notify_event->subtype != XFixesDisplayCursorNotify) + return FALSE; + + g_clear_pointer (&tracker->sprite, cogl_object_unref); + g_signal_emit (tracker, signals[CURSOR_CHANGED], 0); + + return TRUE; +} + +static void +ensure_xfixes_cursor (MetaCursorTracker *tracker) +{ + XFixesCursorImage *cursor_image; + CoglTexture2D *sprite; + guint8 *cursor_data; + gboolean free_cursor_data; + CoglContext *ctx; + + if (tracker->sprite) + return; + + cursor_image = XFixesGetCursorImage (tracker->screen->display->xdisplay); + if (!cursor_image) + return; + + /* Like all X APIs, XFixesGetCursorImage() returns arrays of 32-bit + * quantities as arrays of long; we need to convert on 64 bit */ + if (sizeof(long) == 4) + { + cursor_data = (guint8 *)cursor_image->pixels; + free_cursor_data = FALSE; + } + else + { + int i, j; + guint32 *cursor_words; + gulong *p; + guint32 *q; + + cursor_words = g_new (guint32, cursor_image->width * cursor_image->height); + cursor_data = (guint8 *)cursor_words; + + p = cursor_image->pixels; + q = cursor_words; + for (j = 0; j < cursor_image->height; j++) + for (i = 0; i < cursor_image->width; i++) + *(q++) = *(p++); + + free_cursor_data = TRUE; + } + + ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ()); + sprite = cogl_texture_2d_new_from_data (ctx, + cursor_image->width, + cursor_image->height, + CLUTTER_CAIRO_FORMAT_ARGB32, + COGL_PIXEL_FORMAT_ANY, + cursor_image->width * 4, /* stride */ + cursor_data, + NULL); + + if (free_cursor_data) + g_free (cursor_data); + + if (sprite != NULL) + { + tracker->sprite = sprite; + tracker->hot_x = cursor_image->xhot; + tracker->hot_y = cursor_image->yhot; + } + XFree (cursor_image); +} + +/** + * meta_cursor_tracker_get_sprite: + * + * Returns: (transfer none): + */ +CoglTexture * +meta_cursor_tracker_get_sprite (MetaCursorTracker *tracker) +{ + g_return_val_if_fail (META_IS_CURSOR_TRACKER (tracker), NULL); + + if (!meta_is_wayland_compositor ()) + ensure_xfixes_cursor (tracker); + + return COGL_TEXTURE (tracker->sprite); +} + +/** + * meta_cursor_tracker_get_hot: + * @tracker: + * @x: (out): + * @y: (out): + * + */ +void +meta_cursor_tracker_get_hot (MetaCursorTracker *tracker, + int *x, + int *y) +{ + g_return_if_fail (META_IS_CURSOR_TRACKER (tracker)); + + if (!meta_is_wayland_compositor ()) + ensure_xfixes_cursor (tracker); + + if (x) + *x = tracker->hot_x; + if (y) + *y = tracker->hot_y; +} + +static void +ensure_wayland_cursor (MetaCursorTracker *tracker) +{ + CoglBitmap *bitmap; + char *filename; + + if (tracker->default_cursor) + return; + + filename = g_build_filename (MUTTER_PKGDATADIR, + "cursors/left_ptr.png", + NULL); + + bitmap = cogl_bitmap_new_from_file (filename, NULL); + tracker->default_cursor = cogl_texture_2d_new_from_bitmap (bitmap, + COGL_PIXEL_FORMAT_ANY, + NULL); + + cogl_object_unref (bitmap); + g_free (filename); +} + +void +meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker, + MetaCursor cursor) +{ + Cursor xcursor; + MetaDisplay *display = tracker->screen->display; + + /* First create a cursor for X11 applications that don't specify their own */ + xcursor = meta_display_create_x_cursor (display, cursor); + + XDefineCursor (display->xdisplay, tracker->screen->xroot, xcursor); + XFlush (display->xdisplay); + XFreeCursor (display->xdisplay, xcursor); + + /* Now update the real root cursor */ + if (meta_is_wayland_compositor ()) + { + /* FIXME! We need to load all the other cursors too */ + ensure_wayland_cursor (tracker); + + g_clear_pointer (&tracker->root_cursor, cogl_object_unref); + tracker->root_cursor = cogl_object_ref (tracker->default_cursor); + tracker->root_hot_x = META_WAYLAND_DEFAULT_CURSOR_HOTSPOT_X; + tracker->root_hot_y = META_WAYLAND_DEFAULT_CURSOR_HOTSPOT_Y; + } +} + +void +meta_cursor_tracker_revert_root (MetaCursorTracker *tracker) +{ + meta_cursor_tracker_set_sprite (tracker, + tracker->root_cursor, + tracker->root_hot_x, + tracker->root_hot_y); +} + +void +meta_cursor_tracker_set_sprite (MetaCursorTracker *tracker, + CoglTexture2D *sprite, + int hot_x, + int hot_y) +{ + g_assert (meta_is_wayland_compositor ()); + + g_clear_pointer (&tracker->sprite, cogl_object_unref); + + if (sprite) + { + tracker->sprite = cogl_object_ref (sprite); + tracker->hot_x = hot_x; + tracker->hot_y = hot_y; + cogl_pipeline_set_layer_texture (tracker->pipeline, 0, COGL_TEXTURE (tracker->sprite)); + } + else + cogl_pipeline_set_layer_texture (tracker->pipeline, 0, NULL); + + g_signal_emit (tracker, signals[CURSOR_CHANGED], 0); + + meta_cursor_tracker_update_position (tracker, tracker->current_x, tracker->current_y); +} + +void +meta_cursor_tracker_update_position (MetaCursorTracker *tracker, + int new_x, + int new_y) +{ + g_assert (meta_is_wayland_compositor ()); + + tracker->current_x = new_x; + tracker->current_y = new_y; + tracker->current_rect.x = tracker->current_x - tracker->hot_x; + tracker->current_rect.y = tracker->current_y - tracker->hot_y; + + if (tracker->sprite) + { + tracker->current_rect.width = cogl_texture_get_width (COGL_TEXTURE (tracker->sprite)); + tracker->current_rect.height = cogl_texture_get_height (COGL_TEXTURE (tracker->sprite)); + } + else + { + tracker->current_rect.width = 0; + tracker->current_rect.height = 0; + } +} + +void +meta_cursor_tracker_paint (MetaCursorTracker *tracker) +{ + g_assert (meta_is_wayland_compositor ()); + + if (tracker->sprite == NULL) + return; + + /* FIXME: try to use a DRM cursor when possible */ + cogl_framebuffer_draw_rectangle (cogl_get_draw_framebuffer (), + tracker->pipeline, + tracker->current_rect.x, + tracker->current_rect.y, + tracker->current_rect.x + + tracker->current_rect.width, + tracker->current_rect.y + + tracker->current_rect.height); + + tracker->previous_rect = tracker->current_rect; + tracker->previous_is_valid = TRUE; +} + +void +meta_cursor_tracker_queue_redraw (MetaCursorTracker *tracker, + ClutterActor *stage) +{ + g_assert (meta_is_wayland_compositor ()); + + if (tracker->previous_is_valid) + { + clutter_actor_queue_redraw_with_clip (stage, &tracker->previous_rect); + tracker->previous_is_valid = FALSE; + } + + if (tracker->sprite == NULL) + return; + + clutter_actor_queue_redraw_with_clip (stage, &tracker->current_rect); +} diff --git a/src/core/screen-private.h b/src/core/screen-private.h index 7e8a13318..6bb32f16d 100644 --- a/src/core/screen-private.h +++ b/src/core/screen-private.h @@ -93,6 +93,7 @@ struct _MetaScreen MetaStack *stack; MetaStackTracker *stack_tracker; + MetaCursorTracker *cursor_tracker; MetaCursor current_cursor; Window flash_window; @@ -259,4 +260,7 @@ void meta_screen_set_active_workspace_hint (MetaScreen *screen); Window meta_screen_create_guard_window (Display *xdisplay, MetaScreen *screen); +gboolean meta_screen_handle_xevent (MetaScreen *screen, + XEvent *xevent); + #endif diff --git a/src/core/screen.c b/src/core/screen.c index 073a8af71..3706d94c0 100644 --- a/src/core/screen.c +++ b/src/core/screen.c @@ -48,6 +48,7 @@ #ifdef HAVE_WAYLAND #include "meta-wayland-private.h" #endif +#include "meta-cursor-tracker-private.h" #include @@ -879,7 +880,8 @@ meta_screen_new (MetaDisplay *display, screen->last_monitor_index = 0; reload_monitor_infos (screen); - + + meta_cursor_tracker_get_for_screen (screen); meta_screen_set_cursor (screen, META_CURSOR_DEFAULT); /* Handle creating a no_focus_window for this screen */ @@ -1635,29 +1637,18 @@ void meta_screen_set_cursor (MetaScreen *screen, MetaCursor cursor) { - Cursor xcursor; - if (cursor == screen->current_cursor) return; screen->current_cursor = cursor; - - xcursor = meta_display_create_x_cursor (screen->display, cursor); - XDefineCursor (screen->display->xdisplay, screen->xroot, xcursor); - XFlush (screen->display->xdisplay); - XFreeCursor (screen->display->xdisplay, xcursor); + meta_cursor_tracker_set_root_cursor (screen->cursor_tracker, cursor); } void meta_screen_update_cursor (MetaScreen *screen) { - Cursor xcursor; - - xcursor = meta_display_create_x_cursor (screen->display, - screen->current_cursor); - XDefineCursor (screen->display->xdisplay, screen->xroot, xcursor); - XFlush (screen->display->xdisplay); - XFreeCursor (screen->display->xdisplay, xcursor); + meta_cursor_tracker_set_root_cursor (screen->cursor_tracker, + screen->current_cursor); } void @@ -3869,3 +3860,13 @@ meta_screen_get_monitor_in_fullscreen (MetaScreen *screen, /* We use -1 as a flag to mean "not known yet" for notification purposes */ return screen->monitor_infos[monitor].in_fullscreen == TRUE; } + +gboolean +meta_screen_handle_xevent (MetaScreen *screen, + XEvent *xevent) +{ + if (meta_cursor_tracker_handle_xevent (screen->cursor_tracker, xevent)) + return TRUE; + + return FALSE; +} diff --git a/src/meta/meta-cursor-tracker.h b/src/meta/meta-cursor-tracker.h new file mode 100644 index 000000000..75199d666 --- /dev/null +++ b/src/meta/meta-cursor-tracker.h @@ -0,0 +1,49 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 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. + * + * Author: Giovanni Campagna + */ + +#ifndef META_CURSOR_TRACKER_H +#define META_CURSOR_TRACKER_H + +#include +#include +#include + +#define META_TYPE_CURSOR_TRACKER (meta_cursor_tracker_get_type ()) +#define META_CURSOR_TRACKER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_CURSOR_TRACKER, MetaCursorTracker)) +#define META_CURSOR_TRACKER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_CURSOR_TRACKER, MetaCursorTrackerClass)) +#define META_IS_CURSOR_TRACKER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_CURSOR_TRACKER)) +#define META_IS_CURSOR_TRACKER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_CURSOR_TRACKER)) +#define META_CURSOR_TRACKER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_CURSOR_TRACKER, MetaCursorTrackerClass)) + +typedef struct _MetaCursorTrackerClass MetaCursorTrackerClass; + +GType meta_cursor_tracker_get_type (void); + +MetaCursorTracker *meta_cursor_tracker_get_for_screen (MetaScreen *screen); + +void meta_cursor_tracker_get_hot (MetaCursorTracker *tracker, + int *x, + int *y); +CoglTexture *meta_cursor_tracker_get_sprite (MetaCursorTracker *tracker); + +#endif diff --git a/src/meta/types.h b/src/meta/types.h index 25833207d..f13471146 100644 --- a/src/meta/types.h +++ b/src/meta/types.h @@ -38,5 +38,6 @@ typedef struct _MetaWorkspace MetaWorkspace; */ typedef struct _MetaGroup MetaGroup; typedef struct _MetaKeyBinding MetaKeyBinding; +typedef struct _MetaCursorTracker MetaCursorTracker; #endif diff --git a/src/wayland/meta-wayland-private.h b/src/wayland/meta-wayland-private.h index a859378c1..89c145d0c 100644 --- a/src/wayland/meta-wayland-private.h +++ b/src/wayland/meta-wayland-private.h @@ -28,6 +28,7 @@ #include #include "window-private.h" +#include typedef struct _MetaWaylandCompositor MetaWaylandCompositor; @@ -335,6 +336,7 @@ struct _MetaWaylandSeat struct wl_display *display; + MetaCursorTracker *cursor_tracker; MetaWaylandSurface *sprite; int hotspot_x, hotspot_y; struct wl_listener sprite_destroy_listener; diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c index 0d2b729e5..3ea739919 100644 --- a/src/wayland/meta-wayland-seat.c +++ b/src/wayland/meta-wayland-seat.c @@ -36,6 +36,7 @@ #include "meta-window-actor-private.h" #include "meta/meta-shaped-texture.h" #include "meta-wayland-stage.h" +#include "meta-cursor-tracker-private.h" #define DEFAULT_AXIS_STEP_DISTANCE wl_fixed_from_int (10) @@ -73,10 +74,14 @@ transform_stage_point_fixed (MetaWaylandSurface *surface, static void pointer_unmap_sprite (MetaWaylandSeat *seat) { - if (seat->current_stage) + if (seat->cursor_tracker) { - MetaWaylandStage *stage = META_WAYLAND_STAGE (seat->current_stage); - meta_wayland_stage_set_invisible_cursor (stage); + meta_cursor_tracker_set_sprite (seat->cursor_tracker, + NULL, 0, 0); + + if (seat->current_stage) + meta_cursor_tracker_queue_redraw (seat->cursor_tracker, + CLUTTER_ACTOR (seat->current_stage)); } if (seat->sprite) @@ -89,22 +94,29 @@ pointer_unmap_sprite (MetaWaylandSeat *seat) void meta_wayland_seat_update_sprite (MetaWaylandSeat *seat) { + ClutterBackend *backend; + CoglContext *context; + struct wl_resource *buffer; + CoglTexture2D *texture; + + if (seat->cursor_tracker == NULL) + return; + + backend = clutter_get_default_backend (); + context = clutter_backend_get_cogl_context (backend); + buffer = seat->sprite->buffer_ref.buffer->resource; + texture = cogl_wayland_texture_2d_new_from_buffer (context, buffer, NULL); + + meta_cursor_tracker_set_sprite (seat->cursor_tracker, + texture, + seat->hotspot_x, + seat->hotspot_y); + if (seat->current_stage) - { - MetaWaylandStage *stage = META_WAYLAND_STAGE (seat->current_stage); - ClutterBackend *backend = clutter_get_default_backend (); - CoglContext *context = clutter_backend_get_cogl_context (backend); - struct wl_resource *buffer = seat->sprite->buffer_ref.buffer->resource; - CoglTexture2D *texture = - cogl_wayland_texture_2d_new_from_buffer (context, buffer, NULL); + meta_cursor_tracker_queue_redraw (seat->cursor_tracker, + CLUTTER_ACTOR (seat->current_stage)); - meta_wayland_stage_set_cursor_from_texture (stage, - COGL_TEXTURE (texture), - seat->hotspot_x, - seat->hotspot_y); - - cogl_object_unref (texture); - } + cogl_object_unref (texture); } static void diff --git a/src/wayland/meta-wayland-stage.c b/src/wayland/meta-wayland-stage.c index c3036084d..f7d28d419 100644 --- a/src/wayland/meta-wayland-stage.c +++ b/src/wayland/meta-wayland-stage.c @@ -28,157 +28,33 @@ #include "meta-wayland-stage.h" #include "meta/meta-window-actor.h" #include "meta/meta-shaped-texture.h" - -#define META_WAYLAND_DEFAULT_CURSOR_HOTSPOT_X 7 -#define META_WAYLAND_DEFAULT_CURSOR_HOTSPOT_Y 4 +#include "meta-cursor-tracker-private.h" G_DEFINE_TYPE (MetaWaylandStage, meta_wayland_stage, CLUTTER_TYPE_STAGE); -static void -meta_wayland_stage_finalize (GObject *object) -{ - MetaWaylandStage *self = (MetaWaylandStage *) object; - - cogl_object_unref (self->default_cursor_pipeline); - cogl_object_unref (self->texture_cursor_pipeline); - - G_OBJECT_CLASS (meta_wayland_stage_parent_class)->finalize (object); -} - -static void -get_cursor_draw_position (MetaWaylandStage *self, - cairo_rectangle_int_t *rect) -{ - rect->x = self->cursor_x - self->cursor_hotspot_x; - rect->y = self->cursor_y - self->cursor_hotspot_y; - rect->width = self->cursor_width; - rect->height = self->cursor_height; -} - -static void -draw_cursor_pipeline (MetaWaylandStage *self, - CoglPipeline *pipeline) -{ - cairo_rectangle_int_t rect; - - get_cursor_draw_position (self, &rect); - - cogl_framebuffer_draw_rectangle (cogl_get_draw_framebuffer (), - pipeline, - rect.x, rect.y, - rect.x + rect.width, - rect.y + rect.height); - - self->has_last_cursor_position = TRUE; - self->last_cursor_position = rect; -} - static void meta_wayland_stage_paint (ClutterActor *actor) { - MetaWaylandStage *self = META_WAYLAND_STAGE (actor); + MetaWaylandCompositor *compositor; CLUTTER_ACTOR_CLASS (meta_wayland_stage_parent_class)->paint (actor); - /* Make sure the cursor is always painted on top of all of the other - actors */ - - switch (self->cursor_type) - { - case META_WAYLAND_STAGE_CURSOR_INVISIBLE: - break; - - case META_WAYLAND_STAGE_CURSOR_DEFAULT: - draw_cursor_pipeline (self, self->default_cursor_pipeline); - break; - - case META_WAYLAND_STAGE_CURSOR_TEXTURE: - draw_cursor_pipeline (self, self->texture_cursor_pipeline); - break; - } -} - -static void -update_cursor_position (MetaWaylandStage *self) -{ - cairo_rectangle_int_t rect; - - if (self->has_last_cursor_position) - { - clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (self), - &self->last_cursor_position); - self->has_last_cursor_position = FALSE; - } - - get_cursor_draw_position (self, &rect); - if (rect.width != 0 && rect.height != 0) - clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (self), &rect); + compositor = meta_wayland_compositor_get_default (); + if (compositor->seat->cursor_tracker) + meta_cursor_tracker_paint (compositor->seat->cursor_tracker); } static void meta_wayland_stage_class_init (MetaWaylandStageClass *klass) { - GObjectClass *gobject_class = (GObjectClass *) klass; ClutterActorClass *actor_class = (ClutterActorClass *) klass; - gobject_class->finalize = meta_wayland_stage_finalize; - actor_class->paint = meta_wayland_stage_paint; } -static void -load_default_cursor_pipeline (MetaWaylandStage *self) -{ - CoglContext *context = - clutter_backend_get_cogl_context (clutter_get_default_backend ()); - CoglTexture *texture; - CoglError *error = NULL; - char *filename; - - filename = g_build_filename (MUTTER_DATADIR, - "mutter/cursors/left_ptr.png", - NULL); - - texture = cogl_texture_new_from_file (filename, - COGL_TEXTURE_NONE, - COGL_PIXEL_FORMAT_ANY, - &error); - - g_free (filename); - - self->default_cursor_pipeline = cogl_pipeline_new (context); - cogl_pipeline_set_layer_filters (self->default_cursor_pipeline, - 0, /* layer */ - COGL_PIPELINE_FILTER_NEAREST, - COGL_PIPELINE_FILTER_NEAREST); - - if (texture == NULL) - { - g_warning ("Failed to load default cursor: %s", - error->message); - cogl_error_free (error); - } - else - { - self->default_cursor_width = cogl_texture_get_width (texture); - self->default_cursor_height = cogl_texture_get_height (texture); - - cogl_pipeline_set_layer_texture (self->default_cursor_pipeline, - 0, /* layer */ - texture); - cogl_object_unref (texture); - } -} - static void meta_wayland_stage_init (MetaWaylandStage *self) { - load_default_cursor_pipeline (self); - - self->texture_cursor_pipeline = - cogl_pipeline_copy (self->default_cursor_pipeline); - - meta_wayland_stage_set_default_cursor (self); } ClutterActor * @@ -188,56 +64,3 @@ meta_wayland_stage_new (void) "cursor-visible", FALSE, NULL); } - -void -meta_wayland_stage_set_cursor_position (MetaWaylandStage *self, - int x, - int y) -{ - self->cursor_x = x; - self->cursor_y = y; - update_cursor_position (self); -} - -void -meta_wayland_stage_set_cursor_from_texture (MetaWaylandStage *self, - CoglTexture *texture, - int hotspot_x, - int hotspot_y) -{ - CoglPipeline *pipeline; - - self->cursor_hotspot_x = hotspot_x; - self->cursor_hotspot_y = hotspot_y; - self->cursor_type = META_WAYLAND_STAGE_CURSOR_TEXTURE; - - pipeline = cogl_pipeline_copy (self->texture_cursor_pipeline); - cogl_pipeline_set_layer_texture (pipeline, 0, texture); - cogl_object_unref (self->texture_cursor_pipeline); - self->texture_cursor_pipeline = pipeline; - - self->cursor_width = cogl_texture_get_width (texture); - self->cursor_height = cogl_texture_get_height (texture); - - update_cursor_position (self); -} - -void -meta_wayland_stage_set_invisible_cursor (MetaWaylandStage *self) -{ - self->cursor_type = META_WAYLAND_STAGE_CURSOR_INVISIBLE; - self->cursor_width = 0; - self->cursor_height = 0; - update_cursor_position (self); -} - -void -meta_wayland_stage_set_default_cursor (MetaWaylandStage *self) -{ - self->cursor_type = META_WAYLAND_STAGE_CURSOR_DEFAULT; - self->cursor_hotspot_x = META_WAYLAND_DEFAULT_CURSOR_HOTSPOT_X; - self->cursor_hotspot_y = META_WAYLAND_DEFAULT_CURSOR_HOTSPOT_Y; - self->cursor_width = self->default_cursor_width; - self->cursor_height = self->default_cursor_height; - update_cursor_position (self); -} diff --git a/src/wayland/meta-wayland-stage.h b/src/wayland/meta-wayland-stage.h index d25f2707f..c242fbd60 100644 --- a/src/wayland/meta-wayland-stage.h +++ b/src/wayland/meta-wayland-stage.h @@ -59,53 +59,12 @@ struct _MetaWaylandStageClass struct _MetaWaylandStage { ClutterStage parent; - - /* A pipeline containing the cursor texture that will be used when - the cursor is not over a surface */ - CoglPipeline *default_cursor_pipeline; - int default_cursor_width; - int default_cursor_height; - - CoglPipeline *texture_cursor_pipeline; - - int cursor_x; - int cursor_y; - int cursor_width; - int cursor_height; - int cursor_hotspot_x; - int cursor_hotspot_y; - - enum - { - /* No cursor will be drawn */ - META_WAYLAND_STAGE_CURSOR_INVISIBLE, - /* The cursor will be drawn from our default cursor image */ - META_WAYLAND_STAGE_CURSOR_DEFAULT, - /* The cursor will be drawn using a custom texture */ - META_WAYLAND_STAGE_CURSOR_TEXTURE - } cursor_type; - - gboolean has_last_cursor_position; - cairo_rectangle_int_t last_cursor_position; }; GType meta_wayland_stage_get_type (void) G_GNUC_CONST; ClutterActor *meta_wayland_stage_new (void); -void meta_wayland_stage_set_cursor_position (MetaWaylandStage *stage, - int x, - int y); - -void meta_wayland_stage_set_default_cursor (MetaWaylandStage *self); - -void meta_wayland_stage_set_cursor_from_texture (MetaWaylandStage *self, - CoglTexture *texture, - int hotspot_x, - int hotspot_y); - -void meta_wayland_stage_set_invisible_cursor (MetaWaylandStage *self); - G_END_DECLS #endif /* META_WAYLAND_STAGE_H */ diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index 5b62e8967..600db9368 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -43,6 +43,7 @@ #include "meta-wayland-keyboard.h" #include "meta-wayland-pointer.h" #include "meta-wayland-data-device.h" +#include "meta-cursor-tracker-private.h" #include "display-private.h" #include "window-private.h" #include @@ -1290,12 +1291,17 @@ event_cb (ClutterActor *stage, } } - meta_wayland_stage_set_cursor_position (META_WAYLAND_STAGE (stage), - wl_fixed_to_int (pointer->x), - wl_fixed_to_int (pointer->y)); + if (seat->cursor_tracker) + { + meta_cursor_tracker_update_position (seat->cursor_tracker, + wl_fixed_to_int (pointer->x), + wl_fixed_to_int (pointer->y)); - if (pointer->current == NULL) - meta_wayland_stage_set_default_cursor (META_WAYLAND_STAGE (stage)); + if (pointer->current == NULL) + meta_cursor_tracker_revert_root (seat->cursor_tracker); + + meta_cursor_tracker_queue_redraw (seat->cursor_tracker, stage); + } display = meta_get_display (); if (!display) From e66db2eab3c189e6ec53d562b1f1a27beb8e6a8a Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Mon, 19 Aug 2013 17:37:24 +0200 Subject: [PATCH 026/889] MonitorManager: extend the API with physical sizes These will be needed in the new display panel designs to show the diagonal length and physical aspect ratio. https://bugzilla.gnome.org/show_bug.cgi?id=706322 --- src/core/monitor.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/core/monitor.c b/src/core/monitor.c index d81ff1509..d1a128320 100644 --- a/src/core/monitor.c +++ b/src/core/monitor.c @@ -813,6 +813,10 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton, g_variant_new_string (output->product)); g_variant_builder_add (&properties, "{sv}", "serial", g_variant_new_string (output->serial)); + g_variant_builder_add (&properties, "{sv}", "width-mm", + g_variant_new_int32 (output->width_mm)); + g_variant_builder_add (&properties, "{sv}", "height-mm", + g_variant_new_int32 (output->height_mm)); g_variant_builder_add (&properties, "{sv}", "display-name", g_variant_new_take_string (make_display_name (manager, output))); g_variant_builder_add (&properties, "{sv}", "backlight", From eeb3dfc991711d2b601e1c99df2001f4d013d697 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Tue, 20 Aug 2013 13:25:42 +0200 Subject: [PATCH 027/889] MonitorManager: emit a DBus signal when we change the display configuration Using out-of-band notifications from the wayland protocol or from X is racy, in that the client could ask for the new resources before we have them. Instead, with a signal, we are sure that when the client asks for it, it will get the right values. https://bugzilla.gnome.org/show_bug.cgi?id=706382 --- src/core/monitor.c | 11 +---------- src/xrandr.xml | 9 +++++++++ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/core/monitor.c b/src/core/monitor.c index d1a128320..e3e81ab0c 100644 --- a/src/core/monitor.c +++ b/src/core/monitor.c @@ -42,7 +42,6 @@ #define ALL_WL_TRANSFORMS ((1 << (WL_OUTPUT_TRANSFORM_FLIPPED_270 + 1)) - 1) enum { - MONITORS_CHANGED, CONFIRM_DISPLAY_CHANGE, SIGNALS_LAST }; @@ -660,14 +659,6 @@ meta_monitor_manager_class_init (MetaMonitorManagerClass *klass) klass->get_edid_file = get_edid_file_dummy; klass->read_edid = read_edid_dummy; - signals[MONITORS_CHANGED] = - g_signal_new ("monitors-changed", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, NULL, - G_TYPE_NONE, 0); - signals[CONFIRM_DISPLAY_CHANGE] = g_signal_new ("confirm-display-change", G_TYPE_FROM_CLASS (object_class), @@ -1497,7 +1488,7 @@ invalidate_logical_config (MetaMonitorManager *manager) make_logical_config (manager); - g_signal_emit (manager, signals[MONITORS_CHANGED], 0); + g_signal_emit_by_name (manager, "monitors-changed"); g_free (old_monitor_infos); } diff --git a/src/xrandr.xml b/src/xrandr.xml index aa07464d2..d8574ad7c 100644 --- a/src/xrandr.xml +++ b/src/xrandr.xml @@ -277,5 +277,14 @@ XRandR interface directly). --> + + + From d26f248b0f8e93076710015ac3497e85d4db7a30 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Wed, 17 Jul 2013 10:44:29 +0200 Subject: [PATCH 028/889] wayland: fix a compiler warning Implicit declaration of memset https://bugzilla.gnome.org/show_bug.cgi?id=706363 --- src/wayland/meta-wayland-pointer.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index fd0efed2f..7564a5c37 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -45,6 +45,8 @@ #include "meta-wayland-pointer.h" +#include + static MetaWaylandSeat * meta_wayland_pointer_get_seat (MetaWaylandPointer *pointer) { From 75f3ae14b5c738976f693c6691e36562cbe5ec3f Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Fri, 16 Aug 2013 15:03:03 +0200 Subject: [PATCH 029/889] MetaPlugin: simplify the modal API Remove grab window and cursor from the API, and just grab always on the stage window with no cursor. This is mainly to remove the X11 usage in the public API, in preparation for implementing this in wayland. https://bugzilla.gnome.org/show_bug.cgi?id=705917 --- src/compositor/compositor-private.h | 2 -- src/compositor/compositor.c | 11 +++++++++-- src/compositor/meta-plugin.c | 8 +------- src/meta/meta-plugin.h | 2 -- 4 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/compositor/compositor-private.h b/src/compositor/compositor-private.h index acb8d3c22..0ebf3a439 100644 --- a/src/compositor/compositor-private.h +++ b/src/compositor/compositor-private.h @@ -66,8 +66,6 @@ void meta_switch_workspace_completed (MetaScreen *screen); gboolean meta_begin_modal_for_plugin (MetaScreen *screen, MetaPlugin *plugin, - Window grab_window, - Cursor cursor, MetaModalOptions options, guint32 timestamp); void meta_end_modal_for_plugin (MetaScreen *screen, diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 2d4817f68..565cb1123 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -423,8 +423,6 @@ meta_stage_is_focused (MetaScreen *screen) gboolean meta_begin_modal_for_plugin (MetaScreen *screen, MetaPlugin *plugin, - Window grab_window, - Cursor cursor, MetaModalOptions options, guint32 timestamp) { @@ -435,10 +433,19 @@ meta_begin_modal_for_plugin (MetaScreen *screen, MetaDisplay *display = meta_screen_get_display (screen); Display *xdpy = meta_display_get_xdisplay (display); MetaCompositor *compositor = display->compositor; + ClutterStage *stage; + Window grab_window; + Cursor cursor = None; gboolean pointer_grabbed = FALSE; gboolean keyboard_grabbed = FALSE; int result; + stage = CLUTTER_STAGE (meta_get_stage_for_screen (screen)); + if (!stage) + return FALSE; + + grab_window = clutter_x11_get_stage_window (stage); + if (compositor->modal_plugin != NULL || display->grab_op != META_GRAB_OP_NONE) return FALSE; diff --git a/src/compositor/meta-plugin.c b/src/compositor/meta-plugin.c index a7ee1137b..af50cab47 100644 --- a/src/compositor/meta-plugin.c +++ b/src/compositor/meta-plugin.c @@ -266,10 +266,6 @@ meta_plugin_destroy_completed (MetaPlugin *plugin, /** * meta_plugin_begin_modal: * @plugin: a #MetaPlugin - * @grab_window: the X window to grab the keyboard and mouse on - * @cursor: the cursor to use for the pointer grab, or None, - * to use the normal cursor for the grab window and - * its descendants. * @options: flags that modify the behavior of the modal grab * @timestamp: the timestamp used for establishing grabs * @@ -290,15 +286,13 @@ meta_plugin_destroy_completed (MetaPlugin *plugin, */ gboolean meta_plugin_begin_modal (MetaPlugin *plugin, - Window grab_window, - Cursor cursor, MetaModalOptions options, guint32 timestamp) { MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv; return meta_begin_modal_for_plugin (priv->screen, plugin, - grab_window, cursor, options, timestamp); + options, timestamp); } /** diff --git a/src/meta/meta-plugin.h b/src/meta/meta-plugin.h index 3ea3435b1..8999b133e 100644 --- a/src/meta/meta-plugin.h +++ b/src/meta/meta-plugin.h @@ -376,8 +376,6 @@ typedef enum { gboolean meta_plugin_begin_modal (MetaPlugin *plugin, - Window grab_window, - Cursor cursor, MetaModalOptions options, guint32 timestamp); From 876f81db12d122ce2be69395c809d9835eebea39 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Tue, 13 Aug 2013 14:54:55 +0200 Subject: [PATCH 030/889] compositor: fix focusing the stage window We can't use the X11 stage window, if clutter is not using the X11 backend (and even if it was, it would be bogus when the xwayland server is not the one clutter is talking to). Instead, we introduce the concept of "focus type", which we use to differentiate the various meanings of None in the focus_xwindow field. https://bugzilla.gnome.org/show_bug.cgi?id=706364 --- src/compositor/compositor.c | 34 +++++++++++++--------- src/core/display-private.h | 18 +++++++++--- src/core/display.c | 58 +++++++++++++++++++++++++++---------- 3 files changed, 77 insertions(+), 33 deletions(-) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 565cb1123..771fa2d75 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -391,33 +391,39 @@ meta_focus_stage_window (MetaScreen *screen, if (!stage) return; - window = clutter_x11_get_stage_window (stage); + if (!meta_is_wayland_compositor ()) + { + window = clutter_x11_get_stage_window (stage); - if (window == None) - return; + if (window == None) + return; - meta_display_set_input_focus_xwindow (screen->display, - screen, - window, - timestamp); + meta_display_set_input_focus_xwindow (screen->display, + screen, + META_FOCUS_STAGE, + window, + timestamp); + } + else + { + meta_display_set_input_focus_xwindow (screen->display, + screen, + META_FOCUS_STAGE, + None, + timestamp); + } } gboolean meta_stage_is_focused (MetaScreen *screen) { ClutterStage *stage; - Window window; stage = CLUTTER_STAGE (meta_get_stage_for_screen (screen)); if (!stage) return FALSE; - window = clutter_x11_get_stage_window (stage); - - if (window == None) - return FALSE; - - return (screen->display->focus_xwindow == window); + return (screen->display->focus_type == META_FOCUS_STAGE); } gboolean diff --git a/src/core/display-private.h b/src/core/display-private.h index 2ca9c6759..e9d590d8d 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -86,6 +86,14 @@ typedef enum { META_TILE_MAXIMIZED } MetaTileMode; +typedef enum { + META_FOCUS_NONE = 0, + META_FOCUS_X_CLIENT = 1, + META_FOCUS_WAYLAND_CLIENT = 2, + META_FOCUS_NO_FOCUS_WINDOW = 3, + META_FOCUS_STAGE = 4 +} MetaFocusType; + struct _MetaDisplay { GObject parent_instance; @@ -117,6 +125,7 @@ struct _MetaDisplay * like the no_focus_window or the stage X window. */ Window focus_xwindow; gulong focus_serial; + MetaFocusType focus_type; /* last timestamp passed to XSetInputFocus */ guint32 last_focus_time; @@ -475,9 +484,10 @@ gboolean meta_display_process_barrier_event (MetaDisplay *display, XIBarrierEvent *event); #endif /* HAVE_XI23 */ -void meta_display_set_input_focus_xwindow (MetaDisplay *display, - MetaScreen *screen, - Window window, - guint32 timestamp); +void meta_display_set_input_focus_xwindow (MetaDisplay *display, + MetaScreen *screen, + MetaFocusType type, + Window window, + guint32 timestamp); #endif diff --git a/src/core/display.c b/src/core/display.c index 316748d8a..66061c671 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -1897,10 +1897,11 @@ get_input_event (MetaDisplay *display, } static void -update_focus_window (MetaDisplay *display, - MetaWindow *window, - Window xwindow, - gulong serial) +update_focus_window (MetaDisplay *display, + MetaFocusType type, + MetaWindow *window, + Window xwindow, + gulong serial) { #ifdef HAVE_WAYLAND MetaWaylandCompositor *compositor; @@ -1909,6 +1910,7 @@ update_focus_window (MetaDisplay *display, display->focus_serial = serial; if (display->focus_xwindow == xwindow && + display->focus_type == type && display->focus_window == window) return; @@ -1931,6 +1933,7 @@ update_focus_window (MetaDisplay *display, meta_window_set_focused_internal (previous, FALSE); } + display->focus_type = type; display->focus_window = window; display->focus_xwindow = xwindow; @@ -1948,7 +1951,8 @@ update_focus_window (MetaDisplay *display, { compositor = meta_wayland_compositor_get_default (); - if (meta_display_xwindow_is_a_no_focus_window (display, xwindow)) + if (display->focus_type == META_FOCUS_NO_FOCUS_WINDOW || + display->focus_type == META_FOCUS_STAGE) meta_wayland_compositor_set_input_focus (compositor, NULL); else if (window && window->surface) meta_wayland_compositor_set_input_focus (compositor, window); @@ -1991,11 +1995,12 @@ timestamp_too_old (MetaDisplay *display, } static void -request_xserver_input_focus_change (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *meta_window, - Window xwindow, - guint32 timestamp) +request_xserver_input_focus_change (MetaDisplay *display, + MetaScreen *screen, + MetaFocusType type, + MetaWindow *meta_window, + Window xwindow, + guint32 timestamp) { gulong serial; @@ -2028,6 +2033,7 @@ request_xserver_input_focus_change (MetaDisplay *display, meta_display_ungrab (display); update_focus_window (display, + type, meta_window, xwindow, serial); @@ -2048,9 +2054,12 @@ handle_window_focus_event (MetaDisplay *display, unsigned long serial) { MetaWindow *focus_window; + MetaFocusType type; #ifdef WITH_VERBOSE_MODE const char *window_type; + type = META_FOCUS_NONE; + /* Note the event can be on either the window or the frame, * we focus the frame for shaded windows */ @@ -2062,14 +2071,26 @@ handle_window_focus_event (MetaDisplay *display, window_type = "frame window"; else window_type = "unknown client window"; + + if (window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND) + type = META_FOCUS_WAYLAND_CLIENT; + else + type = META_FOCUS_X_CLIENT; } else if (meta_display_xwindow_is_a_no_focus_window (display, event->event)) - window_type = "no_focus_window"; + { + window_type = "no_focus_window"; + type = META_FOCUS_NO_FOCUS_WINDOW; + } else if (meta_display_screen_for_root (display, event->event)) window_type = "root window"; else window_type = "unknown window"; + /* Don't change type if we don't know the new window */ + if (type == META_FOCUS_NONE) + type = display->focus_type; + meta_topic (META_DEBUG_FOCUS, "Focus %s event received on %s 0x%lx (%s) " "mode %s detail %s serial %lu\n", @@ -2147,6 +2168,7 @@ handle_window_focus_event (MetaDisplay *display, if (display->server_focus_serial > display->focus_serial) { update_focus_window (display, + type, focus_window, focus_window ? focus_window->xwindow : None, display->server_focus_serial); @@ -2200,6 +2222,7 @@ meta_display_handle_event (MetaDisplay *display, meta_topic (META_DEBUG_FOCUS, "Earlier attempt to focus %s failed\n", display->focus_window->desc); update_focus_window (display, + META_FOCUS_NONE, meta_display_lookup_x_window (display, display->server_focus_window), display->server_focus_window, display->server_focus_serial); @@ -5879,6 +5902,8 @@ meta_display_set_input_focus_window (MetaDisplay *display, { request_xserver_input_focus_change (display, window->screen, + window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND ? + META_FOCUS_WAYLAND_CLIENT : META_FOCUS_X_CLIENT, window, focus_frame ? window->frame->xwindow : window->xwindow, timestamp); @@ -5920,13 +5945,15 @@ meta_display_request_take_focus (MetaDisplay *display, } void -meta_display_set_input_focus_xwindow (MetaDisplay *display, - MetaScreen *screen, - Window window, - guint32 timestamp) +meta_display_set_input_focus_xwindow (MetaDisplay *display, + MetaScreen *screen, + MetaFocusType type, + Window window, + guint32 timestamp) { request_xserver_input_focus_change (display, screen, + type, NULL, window, timestamp); @@ -5939,6 +5966,7 @@ meta_display_focus_the_no_focus_window (MetaDisplay *display, { request_xserver_input_focus_change (display, screen, + META_FOCUS_NO_FOCUS_WINDOW, NULL, screen->no_focus_window, timestamp); From 77290b67369b66b19c9d6039247aa8ca11bd7cee Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 20 Aug 2013 17:04:01 -0400 Subject: [PATCH 031/889] Update .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 0c8cddf85..664990506 100644 --- a/.gitignore +++ b/.gitignore @@ -74,6 +74,7 @@ src/mutter-enum-types.[ch] src/stamp-mutter-enum-types.h src/mutter-marshal.[ch] src/stamp-mutter-marshal.h +src/meta-dbus-xrandr.[ch] src/mutter-plugins.pc doc/reference/*.args doc/reference/*.bak From 2c1b20e15fab5c3ac9d16d9fe872d3c660310710 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Wed, 14 Aug 2013 12:50:48 +0200 Subject: [PATCH 032/889] Add a new helper for tracking user idle activity When running as a wayland compositor, we can't use the xserver's IDLETIME, because that's updated only in response to X events. But we have all the events ourselves, so we can just run the timer in process. https://bugzilla.gnome.org/show_bug.cgi?id=706005 --- src/Makefile.am | 3 + src/core/display.c | 3 + src/core/meta-idle-monitor-private.h | 29 ++ src/core/meta-idle-monitor.c | 598 +++++++++++++++++++++++++++ src/meta/meta-idle-monitor.h | 62 +++ 5 files changed, 695 insertions(+) create mode 100644 src/core/meta-idle-monitor-private.h create mode 100644 src/core/meta-idle-monitor.c create mode 100644 src/meta/meta-idle-monitor.h diff --git a/src/Makefile.am b/src/Makefile.am index 8c1b393e1..68b1d1874 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -126,6 +126,8 @@ libmutter_la_SOURCES = \ core/main.c \ core/meta-cursor-tracker.c \ core/meta-cursor-tracker-private.h \ + core/meta-idle-monitor.c \ + core/meta-idle-monitor-private.h \ core/mutter-Xatomtype.h \ core/place.c \ core/place.h \ @@ -213,6 +215,7 @@ libmutterinclude_base_headers = \ meta/meta-background-group.h \ meta/meta-background.h \ meta/meta-cursor-tracker.h \ + meta/meta-idle-monitor.h \ meta/meta-plugin.h \ meta/meta-shaped-texture.h \ meta/meta-shadow-factory.h \ diff --git a/src/core/display.c b/src/core/display.c index 66061c671..0bf16e02e 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -53,6 +53,7 @@ #include #include #include "mutter-enum-types.h" +#include "meta-idle-monitor-private.h" #ifdef HAVE_RANDR #include @@ -2307,6 +2308,8 @@ meta_display_handle_event (MetaDisplay *display, meta_window_update_sync_request_counter (alarm_window, new_counter_value); filter_out_event = TRUE; /* GTK doesn't want to see this really */ } + + meta_idle_monitor_handle_xevent_all (event); } #endif /* HAVE_XSYNC */ diff --git a/src/core/meta-idle-monitor-private.h b/src/core/meta-idle-monitor-private.h new file mode 100644 index 000000000..39f3c8e76 --- /dev/null +++ b/src/core/meta-idle-monitor-private.h @@ -0,0 +1,29 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright 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. + * + * Adapted from gnome-session/gnome-session/gs-idle-monitor.c and + * from gnome-desktop/libgnome-desktop/gnome-idle-monitor.c + */ + +#include + +void meta_idle_monitor_handle_xevent_all (XEvent *xevent); + + diff --git a/src/core/meta-idle-monitor.c b/src/core/meta-idle-monitor.c new file mode 100644 index 000000000..eace00b39 --- /dev/null +++ b/src/core/meta-idle-monitor.c @@ -0,0 +1,598 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright 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. + * + * Adapted from gnome-session/gnome-session/gs-idle-monitor.c and + * from gnome-desktop/libgnome-desktop/gnome-idle-monitor.c + */ + +/** + * SECTION:idle-monitor + * @title: MetaIdleMonitor + * @short_description: Mutter idle counter (similar to X's IDLETIME) + */ + +#include "config.h" + +#include +#include +#include +#include + +#include +#include +#include +#include "display-private.h" +#include "meta-idle-monitor-private.h" + +G_STATIC_ASSERT(sizeof(unsigned long) == sizeof(gpointer)); + +struct _MetaIdleMonitor +{ + GObject parent_instance; + + GHashTable *watches; + GHashTable *alarms; + int device_id; + + /* X11 implementation */ + Display *display; + int sync_event_base; + XSyncCounter counter; + XSyncAlarm user_active_alarm; +}; + +struct _MetaIdleMonitorClass +{ + GObjectClass parent_class; +}; + +typedef struct +{ + MetaIdleMonitor *monitor; + guint id; + MetaIdleMonitorWatchFunc callback; + gpointer user_data; + GDestroyNotify notify; + guint64 timeout_msec; + + /* x11 */ + XSyncAlarm xalarm; +} MetaIdleMonitorWatch; + +enum +{ + PROP_0, + PROP_DEVICE_ID, + PROP_LAST, +}; + +static GParamSpec *obj_props[PROP_LAST]; + +G_DEFINE_TYPE (MetaIdleMonitor, meta_idle_monitor, G_TYPE_OBJECT) + +static MetaIdleMonitor *device_monitors[256]; +static int device_id_max; + +static gint64 +_xsyncvalue_to_int64 (XSyncValue value) +{ + return ((guint64) XSyncValueHigh32 (value)) << 32 + | (guint64) XSyncValueLow32 (value); +} + +#define GUINT64_TO_XSYNCVALUE(value, ret) XSyncIntsToValue (ret, (value) & 0xFFFFFFFF, ((guint64)(value)) >> 32) + +static void +fire_watch (MetaIdleMonitorWatch *watch) +{ + MetaIdleMonitor *monitor; + + monitor = watch->monitor; + g_object_ref (monitor); + + if (watch->callback) + { + watch->callback (watch->monitor, + watch->id, + watch->user_data); + } + + if (watch->timeout_msec == 0) + meta_idle_monitor_remove_watch (watch->monitor, watch->id); + + g_object_unref (monitor); +} + +static XSyncAlarm +_xsync_alarm_set (MetaIdleMonitor *monitor, + XSyncTestType test_type, + guint64 interval, + gboolean want_events) +{ + XSyncAlarmAttributes attr; + XSyncValue delta; + guint flags; + + flags = XSyncCACounter | XSyncCAValueType | XSyncCATestType | + XSyncCAValue | XSyncCADelta | XSyncCAEvents; + + XSyncIntToValue (&delta, 0); + attr.trigger.counter = monitor->counter; + attr.trigger.value_type = XSyncAbsolute; + attr.delta = delta; + attr.events = want_events; + + GUINT64_TO_XSYNCVALUE (interval, &attr.trigger.wait_value); + attr.trigger.test_type = test_type; + return XSyncCreateAlarm (monitor->display, flags, &attr); +} + +static void +ensure_alarm_rescheduled (Display *dpy, + XSyncAlarm alarm) +{ + XSyncAlarmAttributes attr; + + /* Some versions of Xorg have an issue where alarms aren't + * always rescheduled. Calling XSyncChangeAlarm, even + * without any attributes, will reschedule the alarm. */ + XSyncChangeAlarm (dpy, alarm, 0, &attr); +} + +static void +set_alarm_enabled (Display *dpy, + XSyncAlarm alarm, + gboolean enabled) +{ + XSyncAlarmAttributes attr; + attr.events = enabled; + XSyncChangeAlarm (dpy, alarm, XSyncCAEvents, &attr); +} + +static void +check_x11_watch (gpointer data, + gpointer user_data) +{ + MetaIdleMonitorWatch *watch = data; + XSyncAlarm alarm = (XSyncAlarm) user_data; + + if (watch->xalarm != alarm) + return; + + fire_watch (watch); +} + +static void +meta_idle_monitor_handle_xevent (MetaIdleMonitor *monitor, + XSyncAlarmNotifyEvent *alarm_event) +{ + XSyncAlarm alarm; + GList *watches; + gboolean has_alarm; + + if (alarm_event->state != XSyncAlarmActive) + return; + + alarm = alarm_event->alarm; + + has_alarm = FALSE; + + if (alarm == monitor->user_active_alarm) + { + set_alarm_enabled (monitor->display, + alarm, + FALSE); + has_alarm = TRUE; + } + else if (g_hash_table_contains (monitor->alarms, (gpointer) alarm)) + { + ensure_alarm_rescheduled (monitor->display, + alarm); + has_alarm = TRUE; + } + + if (has_alarm) + { + watches = g_hash_table_get_values (monitor->watches); + + g_list_foreach (watches, check_x11_watch, (gpointer) alarm); + g_list_free (watches); + } +} + +void +meta_idle_monitor_handle_xevent_all (XEvent *xevent) +{ + int i; + + for (i = 0; i < device_id_max; i++) + if (device_monitors[i]) + meta_idle_monitor_handle_xevent (device_monitors[i], (XSyncAlarmNotifyEvent*)xevent); +} + +static char * +counter_name_for_device (int device_id) +{ + if (device_id > 0) + return g_strdup_printf ("DEVICEIDLETIME %d", device_id); + + return g_strdup ("IDLETIME"); +} + +static XSyncCounter +find_idletime_counter (MetaIdleMonitor *monitor) +{ + int i; + int ncounters; + XSyncSystemCounter *counters; + XSyncCounter counter = None; + char *counter_name; + + counter_name = counter_name_for_device (monitor->device_id); + counters = XSyncListSystemCounters (monitor->display, &ncounters); + for (i = 0; i < ncounters; i++) + { + if (counters[i].name != NULL && strcmp (counters[i].name, counter_name) == 0) + { + counter = counters[i].counter; + break; + } + } + XSyncFreeSystemCounterList (counters); + g_free (counter_name); + + return counter; +} + +static guint32 +get_next_watch_serial (void) +{ + static guint32 serial = 0; + g_atomic_int_inc (&serial); + return serial; +} + +static void +idle_monitor_watch_free (MetaIdleMonitorWatch *watch) +{ + MetaIdleMonitor *monitor; + + if (watch == NULL) + return; + + monitor = watch->monitor; + + if (watch->notify != NULL) + watch->notify (watch->user_data); + + if (watch->xalarm != monitor->user_active_alarm && + watch->xalarm != None) + { + XSyncDestroyAlarm (monitor->display, watch->xalarm); + g_hash_table_remove (monitor->alarms, (gpointer) watch->xalarm); + } + + g_slice_free (MetaIdleMonitorWatch, watch); +} + +static void +init_xsync (MetaIdleMonitor *monitor) +{ + monitor->counter = find_idletime_counter (monitor); + /* IDLETIME counter not found? */ + if (monitor->counter == None) + { + meta_warning ("IDLETIME counter not found\n"); + return; + } + + monitor->user_active_alarm = _xsync_alarm_set (monitor, XSyncNegativeTransition, 1, FALSE); +} + +static void +meta_idle_monitor_dispose (GObject *object) +{ + MetaIdleMonitor *monitor; + + monitor = META_IDLE_MONITOR (object); + + g_clear_pointer (&monitor->watches, g_hash_table_destroy); + g_clear_pointer (&monitor->alarms, g_hash_table_destroy); + + if (monitor->user_active_alarm != None) + { + XSyncDestroyAlarm (monitor->display, monitor->user_active_alarm); + monitor->user_active_alarm = None; + } + + G_OBJECT_CLASS (meta_idle_monitor_parent_class)->dispose (object); +} + +static void +meta_idle_monitor_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaIdleMonitor *monitor = META_IDLE_MONITOR (object); + + switch (prop_id) + { + case PROP_DEVICE_ID: + g_value_set_int (value, monitor->device_id); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +meta_idle_monitor_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MetaIdleMonitor *monitor = META_IDLE_MONITOR (object); + switch (prop_id) + { + case PROP_DEVICE_ID: + monitor->device_id = g_value_get_int (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +meta_idle_monitor_constructed (GObject *object) +{ + MetaIdleMonitor *monitor = META_IDLE_MONITOR (object); + + monitor->display = meta_get_display ()->xdisplay; + init_xsync (monitor); +} + +static void +meta_idle_monitor_class_init (MetaIdleMonitorClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = meta_idle_monitor_dispose; + object_class->constructed = meta_idle_monitor_constructed; + object_class->get_property = meta_idle_monitor_get_property; + object_class->set_property = meta_idle_monitor_set_property; + + /** + * MetaIdleMonitor:device_id: + * + * The device to listen to idletime on. + */ + obj_props[PROP_DEVICE_ID] = + g_param_spec_int ("device-id", + "Device ID", + "The device to listen to idletime on", + 0, 255, 0, + G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property (object_class, PROP_DEVICE_ID, obj_props[PROP_DEVICE_ID]); +} + +static void +meta_idle_monitor_init (MetaIdleMonitor *monitor) +{ + monitor->watches = g_hash_table_new_full (NULL, + NULL, + NULL, + (GDestroyNotify)idle_monitor_watch_free); + + monitor->alarms = g_hash_table_new (NULL, NULL); +} + +static void +ensure_device_monitor (int device_id) +{ + if (device_monitors[device_id]) + return; + + device_monitors[device_id] = g_object_new (META_TYPE_IDLE_MONITOR, "device-id", device_id, NULL); + device_id_max = MAX (device_id_max, device_id); +} + +/** + * meta_idle_monitor_get_core: + * + * Returns: (transfer none): the #MetaIdleMonitor that tracks the server-global + * idletime for all devices. To track device-specific idletime, + * use meta_idle_monitor_get_for_device(). + */ +MetaIdleMonitor * +meta_idle_monitor_get_core (void) +{ + ensure_device_monitor (0); + return device_monitors[0]; +} + +/** + * meta_idle_monitor_get_for_device: + * @device_id: the device to get the idle time for. + * + * Returns: (transfer none): a new #MetaIdleMonitor that tracks the + * device-specific idletime for @device. To track server-global idletime + * for all devices, use meta_idle_monitor_get_core(). + */ +MetaIdleMonitor * +meta_idle_monitor_get_for_device (int device_id) +{ + g_return_val_if_fail (device_id > 0 && device_id < 256, NULL); + + ensure_device_monitor (device_id); + return device_monitors[device_id]; +} + +static MetaIdleMonitorWatch * +make_watch (MetaIdleMonitor *monitor, + guint64 timeout_msec, + MetaIdleMonitorWatchFunc callback, + gpointer user_data, + GDestroyNotify notify) +{ + MetaIdleMonitorWatch *watch; + + watch = g_slice_new0 (MetaIdleMonitorWatch); + watch->monitor = monitor; + watch->id = get_next_watch_serial (); + watch->callback = callback; + watch->user_data = user_data; + watch->notify = notify; + watch->timeout_msec = timeout_msec; + + if (timeout_msec != 0) + { + watch->xalarm = _xsync_alarm_set (monitor, XSyncPositiveTransition, timeout_msec, TRUE); + + g_hash_table_add (monitor->alarms, (gpointer) watch->xalarm); + } + else + { + watch->xalarm = monitor->user_active_alarm; + + set_alarm_enabled (monitor->display, monitor->user_active_alarm, TRUE); + } + + g_hash_table_insert (monitor->watches, + GUINT_TO_POINTER (watch->id), + watch); + return watch; +} + +/** + * meta_idle_monitor_add_idle_watch: + * @monitor: A #MetaIdleMonitor + * @interval_msec: The idletime interval, in milliseconds + * @callback: (allow-none): The callback to call when the user has + * accumulated @interval_msec milliseconds of idle time. + * @user_data: (allow-none): The user data to pass to the callback + * @notify: A #GDestroyNotify + * + * Returns: a watch id + * + * Adds a watch for a specific idle time. The callback will be called + * when the user has accumulated @interval_msec milliseconds of idle time. + * This function will return an ID that can either be passed to + * meta_idle_monitor_remove_watch(), or can be used to tell idle time + * watches apart if you have more than one. + * + * Also note that this function will only care about positive transitions + * (user's idle time exceeding a certain time). If you want to know about + * when the user has become active, use + * meta_idle_monitor_add_user_active_watch(). + */ +guint +meta_idle_monitor_add_idle_watch (MetaIdleMonitor *monitor, + guint64 interval_msec, + MetaIdleMonitorWatchFunc callback, + gpointer user_data, + GDestroyNotify notify) +{ + MetaIdleMonitorWatch *watch; + + g_return_val_if_fail (META_IS_IDLE_MONITOR (monitor), 0); + g_return_val_if_fail (interval_msec > 0, 0); + + watch = make_watch (monitor, + interval_msec, + callback, + user_data, + notify); + + return watch->id; +} + +/** + * meta_idle_monitor_add_user_active_watch: + * @monitor: A #MetaIdleMonitor + * @callback: (allow-none): The callback to call when the user is + * active again. + * @user_data: (allow-none): The user data to pass to the callback + * @notify: A #GDestroyNotify + * + * Returns: a watch id + * + * Add a one-time watch to know when the user is active again. + * Note that this watch is one-time and will de-activate after the + * function is called, for efficiency purposes. It's most convenient + * to call this when an idle watch, as added by + * meta_idle_monitor_add_idle_watch(), has triggered. + */ +guint +meta_idle_monitor_add_user_active_watch (MetaIdleMonitor *monitor, + MetaIdleMonitorWatchFunc callback, + gpointer user_data, + GDestroyNotify notify) +{ + MetaIdleMonitorWatch *watch; + + g_return_val_if_fail (META_IS_IDLE_MONITOR (monitor), 0); + + watch = make_watch (monitor, + 0, + callback, + user_data, + notify); + + return watch->id; +} + +/** + * meta_idle_monitor_remove_watch: + * @monitor: A #MetaIdleMonitor + * @id: A watch ID + * + * Removes an idle time watcher, previously added by + * meta_idle_monitor_add_idle_watch() or + * meta_idle_monitor_add_user_active_watch(). + */ +void +meta_idle_monitor_remove_watch (MetaIdleMonitor *monitor, + guint id) +{ + g_return_if_fail (META_IS_IDLE_MONITOR (monitor)); + + g_hash_table_remove (monitor->watches, + GUINT_TO_POINTER (id)); +} + +/** + * meta_idle_monitor_get_idletime: + * @monitor: A #MetaIdleMonitor + * + * Returns: The current idle time, in milliseconds, or -1 for not supported + */ +gint64 +meta_idle_monitor_get_idletime (MetaIdleMonitor *monitor) +{ + XSyncValue value; + + if (!XSyncQueryCounter (monitor->display, monitor->counter, &value)) + return -1; + + return _xsyncvalue_to_int64 (value); +} diff --git a/src/meta/meta-idle-monitor.h b/src/meta/meta-idle-monitor.h new file mode 100644 index 000000000..883827373 --- /dev/null +++ b/src/meta/meta-idle-monitor.h @@ -0,0 +1,62 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright 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_IDLE_MONITOR_H +#define META_IDLE_MONITOR_H + +#include +#include + +#define META_TYPE_IDLE_MONITOR (meta_idle_monitor_get_type ()) +#define META_IDLE_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_IDLE_MONITOR, MetaIdleMonitor)) +#define META_IDLE_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_IDLE_MONITOR, MetaIdleMonitorClass)) +#define META_IS_IDLE_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_IDLE_MONITOR)) +#define META_IS_IDLE_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_IDLE_MONITOR)) +#define META_IDLE_MONITOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_IDLE_MONITOR, MetaIdleMonitorClass)) + +typedef struct _MetaIdleMonitor MetaIdleMonitor; +typedef struct _MetaIdleMonitorClass MetaIdleMonitorClass; + +GType meta_idle_monitor_get_type (void); + +typedef void (*MetaIdleMonitorWatchFunc) (MetaIdleMonitor *monitor, + guint watch_id, + gpointer user_data); + +MetaIdleMonitor *meta_idle_monitor_get_core (void); +MetaIdleMonitor *meta_idle_monitor_get_for_device (int device_id); + +guint meta_idle_monitor_add_idle_watch (MetaIdleMonitor *monitor, + guint64 interval_msec, + MetaIdleMonitorWatchFunc callback, + gpointer user_data, + GDestroyNotify notify); + +guint meta_idle_monitor_add_user_active_watch (MetaIdleMonitor *monitor, + MetaIdleMonitorWatchFunc callback, + gpointer user_data, + GDestroyNotify notify); + +void meta_idle_monitor_remove_watch (MetaIdleMonitor *monitor, + guint id); +gint64 meta_idle_monitor_get_idletime (MetaIdleMonitor *monitor); + +#endif From c0acf3ae6da8e29e774632eed0433f226ccfb598 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Wed, 14 Aug 2013 13:51:05 +0200 Subject: [PATCH 033/889] MetaIdleMonitor: add a DBus interface for the idle monitor To allow other clients (gnome-session, gnome-settings-daemon) to monitor user activity, introduce a DBus interface for the idle monitor inside mutter. https://bugzilla.gnome.org/show_bug.cgi?id=706005 --- src/Makefile.am | 15 +- src/core/display.c | 10 +- src/core/meta-idle-monitor-private.h | 1 + src/core/meta-idle-monitor.c | 259 +++++++++++++++++++++++++++ src/idle-monitor.xml | 35 ++++ 5 files changed, 315 insertions(+), 5 deletions(-) create mode 100644 src/idle-monitor.xml diff --git a/src/Makefile.am b/src/Makefile.am index 68b1d1874..686d6627f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -37,7 +37,8 @@ INCLUDES += \ endif mutter_built_sources = \ - mutter-enum-types.h \ + $(dbus_idle_built_sources) \ + mutter-enum-types.h \ mutter-enum-types.c if HAVE_WAYLAND @@ -306,6 +307,8 @@ xml_in_files = \ 50-mutter-windows.xml.in xml_DATA = $(xml_in_files:.xml.in=.xml) +dbus_idle_built_sources = meta-dbus-idle-monitor.c meta-dbus-idle-monitor.h + gsettings_SCHEMAS = org.gnome.mutter.gschema.xml @INTLTOOL_XML_NOMERGE_RULE@ @GSETTINGS_RULES@ @@ -362,6 +365,16 @@ mutter-enum-types.c: stamp-mutter-enum-types.h mutter-enum-types.c.in cp xgen-tetc mutter-enum-types.c && \ rm -f xgen-tetc +dbus_idle_built_sources = meta-dbus-idle-monitor.c meta-dbus-idle-monitor.h + +$(dbus_idle_built_sources) : Makefile.am idle-monitor.xml + $(AM_V_GEN)gdbus-codegen \ + --interface-prefix org.gnome.Mutter \ + --c-namespace MetaDBus \ + --generate-c-code meta-dbus-idle-monitor \ + --c-generate-object-manager \ + $(srcdir)/idle-monitor.xml + if HAVE_WAYLAND wayland/%-protocol.c : $(top_builddir)/protocol/%.xml mkdir -p wayland diff --git a/src/core/display.c b/src/core/display.c index 0bf16e02e..3a6827e25 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -991,8 +991,10 @@ meta_display_open (void) meta_error_trap_pop (the_display); } - - meta_display_ungrab (the_display); + + meta_idle_monitor_init_dbus (); + + meta_display_ungrab (the_display); /* Done opening new display */ the_display->display_opening = FALSE; @@ -2308,8 +2310,8 @@ meta_display_handle_event (MetaDisplay *display, meta_window_update_sync_request_counter (alarm_window, new_counter_value); filter_out_event = TRUE; /* GTK doesn't want to see this really */ } - - meta_idle_monitor_handle_xevent_all (event); + else + meta_idle_monitor_handle_xevent_all (event); } #endif /* HAVE_XSYNC */ diff --git a/src/core/meta-idle-monitor-private.h b/src/core/meta-idle-monitor-private.h index 39f3c8e76..f301e4fd6 100644 --- a/src/core/meta-idle-monitor-private.h +++ b/src/core/meta-idle-monitor-private.h @@ -27,3 +27,4 @@ void meta_idle_monitor_handle_xevent_all (XEvent *xevent); +void meta_idle_monitor_init_dbus (void); diff --git a/src/core/meta-idle-monitor.c b/src/core/meta-idle-monitor.c index eace00b39..568e6db72 100644 --- a/src/core/meta-idle-monitor.c +++ b/src/core/meta-idle-monitor.c @@ -40,6 +40,7 @@ #include #include "display-private.h" #include "meta-idle-monitor-private.h" +#include "meta-dbus-idle-monitor.h" G_STATIC_ASSERT(sizeof(unsigned long) == sizeof(gpointer)); @@ -596,3 +597,261 @@ meta_idle_monitor_get_idletime (MetaIdleMonitor *monitor) return _xsyncvalue_to_int64 (value); } + +static gboolean +handle_get_idletime (MetaDBusIdleMonitor *skeleton, + GDBusMethodInvocation *invocation, + MetaIdleMonitor *monitor) +{ + guint64 idletime; + + idletime = meta_idle_monitor_get_idletime (monitor); + meta_dbus_idle_monitor_complete_get_idletime (skeleton, invocation, idletime); + + return TRUE; +} + +typedef struct { + MetaDBusIdleMonitor *dbus_monitor; + MetaIdleMonitor *monitor; + char *dbus_name; + guint watch_id; + guint name_watcher_id; +} DBusWatch; + +static void +destroy_dbus_watch (gpointer data) +{ + DBusWatch *watch = data; + + g_object_unref (watch->dbus_monitor); + g_object_unref (watch->monitor); + g_free (watch->dbus_name); + g_bus_unwatch_name (watch->name_watcher_id); + + g_slice_free (DBusWatch, watch); +} + +static void +dbus_idle_callback (MetaIdleMonitor *monitor, + guint watch_id, + gpointer user_data) +{ + DBusWatch *watch = user_data; + GDBusInterfaceSkeleton *skeleton = G_DBUS_INTERFACE_SKELETON (watch->dbus_monitor); + + g_dbus_connection_emit_signal (g_dbus_interface_skeleton_get_connection (skeleton), + watch->dbus_name, + g_dbus_interface_skeleton_get_object_path (skeleton), + "org.gnome.Mutter.IdleMonitor", + "WatchFired", + g_variant_new ("(u)", watch_id), + NULL); +} + +static void +name_vanished_callback (GDBusConnection *connection, + const char *name, + gpointer user_data) +{ + DBusWatch *watch = user_data; + + meta_idle_monitor_remove_watch (watch->monitor, watch->watch_id); +} + +static DBusWatch * +make_dbus_watch (MetaDBusIdleMonitor *skeleton, + GDBusMethodInvocation *invocation, + MetaIdleMonitor *monitor) +{ + DBusWatch *watch; + + watch = g_slice_new (DBusWatch); + watch->dbus_monitor = g_object_ref (skeleton); + watch->monitor = g_object_ref (monitor); + watch->dbus_name = g_strdup (g_dbus_method_invocation_get_sender (invocation)); + watch->name_watcher_id = g_bus_watch_name_on_connection (g_dbus_method_invocation_get_connection (invocation), + watch->dbus_name, + G_BUS_NAME_WATCHER_FLAGS_NONE, + NULL, /* appeared */ + name_vanished_callback, + watch, NULL); + + return watch; +} + +static gboolean +handle_add_idle_watch (MetaDBusIdleMonitor *skeleton, + GDBusMethodInvocation *invocation, + guint64 interval, + MetaIdleMonitor *monitor) +{ + DBusWatch *watch; + + watch = make_dbus_watch (skeleton, invocation, monitor); + watch->watch_id = meta_idle_monitor_add_idle_watch (monitor, interval, + dbus_idle_callback, watch, destroy_dbus_watch); + + meta_dbus_idle_monitor_complete_add_idle_watch (skeleton, invocation, watch->watch_id); + + return TRUE; +} + +static gboolean +handle_add_user_active_watch (MetaDBusIdleMonitor *skeleton, + GDBusMethodInvocation *invocation, + MetaIdleMonitor *monitor) +{ + DBusWatch *watch; + + watch = make_dbus_watch (skeleton, invocation, monitor); + watch->watch_id = meta_idle_monitor_add_user_active_watch (monitor, + dbus_idle_callback, watch, + destroy_dbus_watch); + + meta_dbus_idle_monitor_complete_add_user_active_watch (skeleton, invocation, watch->watch_id); + + return TRUE; +} + +static gboolean +handle_remove_watch (MetaDBusIdleMonitor *skeleton, + GDBusMethodInvocation *invocation, + guint id, + MetaIdleMonitor *monitor) +{ + meta_idle_monitor_remove_watch (monitor, id); + meta_dbus_idle_monitor_complete_remove_watch (skeleton, invocation); + + return TRUE; +} + +static void +create_monitor_skeleton (GDBusObjectManagerServer *manager, + MetaIdleMonitor *monitor, + const char *path) +{ + MetaDBusIdleMonitor *skeleton; + MetaDBusObjectSkeleton *object; + + skeleton = meta_dbus_idle_monitor_skeleton_new (); + g_signal_connect_object (skeleton, "handle-add-idle-watch", + G_CALLBACK (handle_add_idle_watch), monitor, 0); + g_signal_connect_object (skeleton, "handle-add-user-active-watch", + G_CALLBACK (handle_add_user_active_watch), monitor, 0); + g_signal_connect_object (skeleton, "handle-remove-watch", + G_CALLBACK (handle_remove_watch), monitor, 0); + g_signal_connect_object (skeleton, "handle-get-idletime", + G_CALLBACK (handle_get_idletime), monitor, 0); + + object = meta_dbus_object_skeleton_new (path); + meta_dbus_object_skeleton_set_idle_monitor (object, skeleton); + + g_dbus_object_manager_server_export (manager, G_DBUS_OBJECT_SKELETON (object)); +} + +static void +on_device_added (ClutterDeviceManager *device_manager, + ClutterInputDevice *device, + GDBusObjectManagerServer *manager) +{ + + MetaIdleMonitor *monitor; + int device_id; + char *path; + + device_id = clutter_input_device_get_device_id (device); + monitor = meta_idle_monitor_get_for_device (device_id); + path = g_strdup_printf ("/org/gnome/Mutter/IdleMonitor/Device%d", device_id); + + create_monitor_skeleton (manager, monitor, path); + g_free (path); +} + +static void +on_device_removed (ClutterDeviceManager *device_manager, + ClutterInputDevice *device, + GDBusObjectManagerServer *manager) +{ + int device_id; + char *path; + + device_id = clutter_input_device_get_device_id (device); + path = g_strdup_printf ("/org/gnome/Mutter/IdleMonitor/Device%d", device_id); + g_dbus_object_manager_server_unexport (manager, path); + g_free (path); + + g_clear_object (&device_monitors[device_id]); + if (device_id == device_id_max) + device_id_max--; +} + +static void +on_bus_acquired (GDBusConnection *connection, + const char *name, + gpointer user_data) +{ + GDBusObjectManagerServer *manager; + ClutterDeviceManager *device_manager; + MetaIdleMonitor *monitor; + GSList *devices, *iter; + char *path; + + manager = g_dbus_object_manager_server_new ("/org/gnome/Mutter/IdleMonitor"); + + /* We never clear the core monitor, as that's supposed to cumulate idle times from + all devices */ + monitor = meta_idle_monitor_get_core (); + path = g_strdup ("/org/gnome/Mutter/IdleMonitor/Core"); + create_monitor_skeleton (manager, monitor, path); + g_free (path); + + device_manager = clutter_device_manager_get_default (); + devices = clutter_device_manager_list_devices (device_manager); + + for (iter = devices; iter; iter = iter->next) + on_device_added (device_manager, iter->data, manager); + + g_signal_connect_object (device_manager, "device-added", + G_CALLBACK (on_device_added), manager, 0); + g_signal_connect_object (device_manager, "device-removed", + G_CALLBACK (on_device_removed), manager, 0); + + g_dbus_object_manager_server_set_connection (manager, connection); +} + +static void +on_name_acquired (GDBusConnection *connection, + const char *name, + gpointer user_data) +{ + meta_verbose ("Acquired name %s\n", name); +} + +static void +on_name_lost (GDBusConnection *connection, + const char *name, + gpointer user_data) +{ + meta_verbose ("Lost or failed to acquire name %s\n", name); +} + +void +meta_idle_monitor_init_dbus (void) +{ + static int dbus_name_id; + + if (dbus_name_id > 0) + return; + + dbus_name_id = g_bus_own_name (G_BUS_TYPE_SESSION, + "org.gnome.Mutter.IdleMonitor", + G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT | + (meta_get_replace_current_wm () ? + G_BUS_NAME_OWNER_FLAGS_REPLACE : 0), + on_bus_acquired, + on_name_acquired, + on_name_lost, + NULL, NULL); +} + diff --git a/src/idle-monitor.xml b/src/idle-monitor.xml new file mode 100644 index 000000000..34a26dd93 --- /dev/null +++ b/src/idle-monitor.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + From 9affbf10a6ae675107a6295af7d38cc9abefa2a4 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Fri, 23 Aug 2013 15:07:57 +0200 Subject: [PATCH 034/889] MetaIdleMonitor: add wayland support Keep a timer source that we reset when we capture an event in MetaWayland, and fire watches accordingly. https://bugzilla.gnome.org/show_bug.cgi?id=706005 --- src/core/meta-idle-monitor-private.h | 1 + src/core/meta-idle-monitor.c | 127 ++++++++++++++++++++++++--- src/wayland/meta-wayland.c | 28 ++++++ 3 files changed, 146 insertions(+), 10 deletions(-) diff --git a/src/core/meta-idle-monitor-private.h b/src/core/meta-idle-monitor-private.h index f301e4fd6..40608ffd9 100644 --- a/src/core/meta-idle-monitor-private.h +++ b/src/core/meta-idle-monitor-private.h @@ -26,5 +26,6 @@ void meta_idle_monitor_handle_xevent_all (XEvent *xevent); +void meta_idle_monitor_reset_idletime (MetaIdleMonitor *monitor); void meta_idle_monitor_init_dbus (void); diff --git a/src/core/meta-idle-monitor.c b/src/core/meta-idle-monitor.c index 568e6db72..cc3e8f707 100644 --- a/src/core/meta-idle-monitor.c +++ b/src/core/meta-idle-monitor.c @@ -57,6 +57,9 @@ struct _MetaIdleMonitor int sync_event_base; XSyncCounter counter; XSyncAlarm user_active_alarm; + + /* Wayland implementation */ + guint64 last_event_time; }; struct _MetaIdleMonitorClass @@ -75,6 +78,9 @@ typedef struct /* x11 */ XSyncAlarm xalarm; + + /* wayland */ + GSource *timeout_source; } MetaIdleMonitorWatch; enum @@ -290,6 +296,9 @@ idle_monitor_watch_free (MetaIdleMonitorWatch *watch) g_hash_table_remove (monitor->alarms, (gpointer) watch->xalarm); } + if (watch->timeout_source != NULL) + g_source_destroy (watch->timeout_source); + g_slice_free (MetaIdleMonitorWatch, watch); } @@ -368,8 +377,11 @@ meta_idle_monitor_constructed (GObject *object) { MetaIdleMonitor *monitor = META_IDLE_MONITOR (object); - monitor->display = meta_get_display ()->xdisplay; - init_xsync (monitor); + if (!meta_is_wayland_compositor ()) + { + monitor->display = meta_get_display ()->xdisplay; + init_xsync (monitor); + } } static void @@ -448,6 +460,25 @@ meta_idle_monitor_get_for_device (int device_id) return device_monitors[device_id]; } +static gboolean +wayland_dispatch_timeout (GSource *source, + GSourceFunc callback, + gpointer user_data) +{ + MetaIdleMonitorWatch *watch = user_data; + + fire_watch (watch); + g_source_set_ready_time (watch->timeout_source, -1); + return TRUE; +} + +static GSourceFuncs wayland_source_funcs = { + NULL, /* prepare */ + NULL, /* check */ + wayland_dispatch_timeout, + NULL, /* finalize */ +}; + static MetaIdleMonitorWatch * make_watch (MetaIdleMonitor *monitor, guint64 timeout_msec, @@ -465,17 +496,34 @@ make_watch (MetaIdleMonitor *monitor, watch->notify = notify; watch->timeout_msec = timeout_msec; - if (timeout_msec != 0) + if (meta_is_wayland_compositor ()) { - watch->xalarm = _xsync_alarm_set (monitor, XSyncPositiveTransition, timeout_msec, TRUE); + if (timeout_msec != 0) + { + GSource *source = g_source_new (&wayland_source_funcs, sizeof (GSource)); - g_hash_table_add (monitor->alarms, (gpointer) watch->xalarm); + g_source_set_callback (source, NULL, watch, NULL); + g_source_set_ready_time (source, monitor->last_event_time + timeout_msec * 1000); + g_source_attach (source, NULL); + g_source_unref (source); + + watch->timeout_source = source; + } } else { - watch->xalarm = monitor->user_active_alarm; + if (timeout_msec != 0) + { + watch->xalarm = _xsync_alarm_set (monitor, XSyncPositiveTransition, timeout_msec, TRUE); - set_alarm_enabled (monitor->display, monitor->user_active_alarm, TRUE); + g_hash_table_add (monitor->alarms, (gpointer) watch->xalarm); + } + else + { + watch->xalarm = monitor->user_active_alarm; + + set_alarm_enabled (monitor->display, monitor->user_active_alarm, TRUE); + } } g_hash_table_insert (monitor->watches, @@ -592,10 +640,69 @@ meta_idle_monitor_get_idletime (MetaIdleMonitor *monitor) { XSyncValue value; - if (!XSyncQueryCounter (monitor->display, monitor->counter, &value)) - return -1; + if (meta_is_wayland_compositor ()) + { + return (g_get_monotonic_time () - monitor->last_event_time) / 1000; + } + else + { + if (!XSyncQueryCounter (monitor->display, monitor->counter, &value)) + return -1; - return _xsyncvalue_to_int64 (value); + return _xsyncvalue_to_int64 (value); + } +} + +typedef struct { + MetaIdleMonitor *monitor; + GList *fired_watches; +} CheckWaylandClosure; + +static gboolean +check_wayland_watch (gpointer key, + gpointer value, + gpointer user_data) +{ + MetaIdleMonitorWatch *watch = value; + CheckWaylandClosure *closure = user_data; + gboolean steal; + + if (watch->timeout_msec == 0) + { + closure->fired_watches = g_list_prepend (closure->fired_watches, watch); + steal = TRUE; + } + else + { + g_source_set_ready_time (watch->timeout_source, + closure->monitor->last_event_time + + watch->timeout_msec * 1000); + steal = FALSE; + } + + return steal; +} + +static void +fire_wayland_watch (gpointer watch, + gpointer data) +{ + fire_watch (watch); +} + +void +meta_idle_monitor_reset_idletime (MetaIdleMonitor *monitor) +{ + CheckWaylandClosure closure; + + monitor->last_event_time = g_get_monotonic_time (); + + closure.monitor = monitor; + closure.fired_watches = NULL; + g_hash_table_foreach_steal (monitor->watches, check_wayland_watch, &closure); + + g_list_foreach (closure.fired_watches, fire_wayland_watch, NULL); + g_list_free (closure.fired_watches); } static gboolean diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index 600db9368..0452bc601 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -49,6 +49,7 @@ #include #include #include "frame.h" +#include "meta-idle-monitor-private.h" static MetaWaylandCompositor _meta_wayland_compositor; @@ -1260,6 +1261,31 @@ synthesize_motion_event (MetaWaylandCompositor *compositor, meta_display_handle_event (display, (XEvent *) &generic_event); } +static void +reset_idletimes (const ClutterEvent *event) +{ + ClutterInputDevice *device, *source_device; + MetaIdleMonitor *core_monitor, *device_monitor; + int device_id; + + device = clutter_event_get_device (event); + device_id = clutter_input_device_get_device_id (device); + + core_monitor = meta_idle_monitor_get_core (); + device_monitor = meta_idle_monitor_get_for_device (device_id); + + meta_idle_monitor_reset_idletime (core_monitor); + meta_idle_monitor_reset_idletime (device_monitor); + + source_device = clutter_event_get_source_device (event); + if (source_device != device) + { + device_id = clutter_input_device_get_device_id (device); + device_monitor = meta_idle_monitor_get_for_device (device_id); + meta_idle_monitor_reset_idletime (device_monitor); + } +} + static gboolean event_cb (ClutterActor *stage, const ClutterEvent *event, @@ -1270,6 +1296,8 @@ event_cb (ClutterActor *stage, MetaWaylandSurface *surface; MetaDisplay *display; + reset_idletimes (event); + meta_wayland_seat_handle_event (compositor->seat, event); /* HACK: for now, the surfaces from Wayland clients aren't From 2af20b77b6c8243292872e034947eb48f429c1b1 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Wed, 21 Aug 2013 19:07:01 +0200 Subject: [PATCH 035/889] MonitorXrandr: fix reading the current DPMS level Add missing break statements, to avoid falling always through to the invalid case. https://bugzilla.gnome.org/show_bug.cgi?id=706582 --- src/core/monitor-xrandr.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/core/monitor-xrandr.c b/src/core/monitor-xrandr.c index 37dd4ca0b..1a66c13ce 100644 --- a/src/core/monitor-xrandr.c +++ b/src/core/monitor-xrandr.c @@ -337,18 +337,23 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager) dpms_enabled) { switch (dpms_state) - { - case DPMSModeOn: - manager->power_save_mode = META_POWER_SAVE_ON; - case DPMSModeStandby: - manager->power_save_mode = META_POWER_SAVE_STANDBY; - case DPMSModeSuspend: - manager->power_save_mode = META_POWER_SAVE_SUSPEND; - case DPMSModeOff: - manager->power_save_mode = META_POWER_SAVE_OFF; - default: - manager->power_save_mode = META_POWER_SAVE_UNKNOWN; - } + { + case DPMSModeOn: + manager->power_save_mode = META_POWER_SAVE_ON; + break; + case DPMSModeStandby: + manager->power_save_mode = META_POWER_SAVE_STANDBY; + break; + case DPMSModeSuspend: + manager->power_save_mode = META_POWER_SAVE_SUSPEND; + break; + case DPMSModeOff: + manager->power_save_mode = META_POWER_SAVE_OFF; + break; + default: + manager->power_save_mode = META_POWER_SAVE_UNKNOWN; + break; + } } else { From 5de346bfef73c3dc60218a2f5b892aa2de33d92e Mon Sep 17 00:00:00 2001 From: Colin Guthrie Date: Thu, 22 Aug 2013 17:39:56 +0100 Subject: [PATCH 036/889] MonitorXrandr: Fix segv when accessing possible_clones This code requires a double pass and the segv happens later when trying to iterate over the array. https://bugzilla.gnome.org/show_bug.cgi?id=706598 --- src/core/monitor-xrandr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/monitor-xrandr.c b/src/core/monitor-xrandr.c index 1a66c13ce..0a7dc0b38 100644 --- a/src/core/monitor-xrandr.c +++ b/src/core/monitor-xrandr.c @@ -532,7 +532,7 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager) */ for (j = 0; j < (unsigned)output->nclone; j++) { - meta_output->possible_clones = GINT_TO_POINTER (output->clones[j]); + meta_output->possible_clones[j] = GINT_TO_POINTER (output->clones[j]); } meta_output->is_primary = ((XID)meta_output->output_id == primary_output); From 9bd366f2a6860415d9812ab011b00da218be0f28 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Fri, 23 Aug 2013 17:25:44 +0200 Subject: [PATCH 037/889] MonitorXrandr: skip CRTC reconfigurations that have no effect If we're attempting to reconfigure the CRTCs to the same parameter, skip the X call, as in some drivers a modeset can take time and cause flicker. https://bugzilla.gnome.org/show_bug.cgi?id=706672 --- src/core/monitor-xrandr.c | 53 ++++++++++++++++++++++++++++----------- 1 file changed, 39 insertions(+), 14 deletions(-) diff --git a/src/core/monitor-xrandr.c b/src/core/monitor-xrandr.c index 0a7dc0b38..bcceff80f 100644 --- a/src/core/monitor-xrandr.c +++ b/src/core/monitor-xrandr.c @@ -777,17 +777,51 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager, { MetaMonitorMode *mode; XID *outputs; - int j, n_outputs; + unsigned int j, n_outputs; int width, height; Status ok; + unsigned long old_controlled_mask; + unsigned long new_controlled_mask; mode = crtc_info->mode; n_outputs = crtc_info->outputs->len; outputs = g_new (XID, n_outputs); + old_controlled_mask = 0; + for (j = 0; j < manager->n_outputs; j++) + { + MetaOutput *output; + + output = &manager->outputs[j]; + + if (output->crtc == crtc) + old_controlled_mask |= 1UL << j; + } + + new_controlled_mask = 0; for (j = 0; j < n_outputs; j++) - outputs[j] = ((MetaOutput**)crtc_info->outputs->pdata)[j]->output_id; + { + MetaOutput *output; + + output = ((MetaOutput**)crtc_info->outputs->pdata)[j]; + + output->is_dirty = TRUE; + output->crtc = crtc; + new_controlled_mask |= 1UL << j; + + outputs[j] = output->output_id; + } + + if (crtc->current_mode == mode && + crtc->rect.x == crtc_info->x && + crtc->rect.y == crtc_info->y && + crtc->transform == crtc_info->transform && + old_controlled_mask == new_controlled_mask) + { + /* No change */ + goto next; + } meta_error_trap_push (meta_get_display ()); ok = XRRSetCrtcConfig (manager_xrandr->xdisplay, @@ -806,11 +840,9 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager, (unsigned)(crtc->crtc_id), (unsigned)(mode->mode_id), mode->width, mode->height, (float)mode->refresh_rate, crtc_info->x, crtc_info->y, crtc_info->transform); - continue; + goto next; } - g_free (outputs); - if (meta_monitor_transform_is_rotated (crtc_info->transform)) { width = mode->height; @@ -829,15 +861,8 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager, crtc->current_mode = mode; crtc->transform = crtc_info->transform; - for (j = 0; j < n_outputs; j++) - { - MetaOutput *output; - - output = ((MetaOutput**)crtc_info->outputs->pdata)[j]; - - output->is_dirty = TRUE; - output->crtc = crtc; - } + next: + g_free (outputs); } } From 13312527deff6f96ff47f9ad7800722dc2d5258d Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 23 Aug 2013 18:23:01 -0400 Subject: [PATCH 038/889] Update .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 664990506..ec57c27de 100644 --- a/.gitignore +++ b/.gitignore @@ -75,6 +75,7 @@ src/stamp-mutter-enum-types.h src/mutter-marshal.[ch] src/stamp-mutter-marshal.h src/meta-dbus-xrandr.[ch] +src/meta-dbus-idle-monitor.[ch] src/mutter-plugins.pc doc/reference/*.args doc/reference/*.bak From aa6d88721453a3f478f9e289a02e1826adc13fff Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 23 Aug 2013 21:54:16 -0400 Subject: [PATCH 039/889] wayland-private: Ignore deprecations around legacy_buffer yes, it's deprecated, that's why it's marked legacy. now shush. --- src/wayland/meta-wayland-private.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/wayland/meta-wayland-private.h b/src/wayland/meta-wayland-private.h index 89c145d0c..6db549133 100644 --- a/src/wayland/meta-wayland-private.h +++ b/src/wayland/meta-wayland-private.h @@ -51,7 +51,9 @@ typedef struct union { struct wl_shm_buffer *shm_buffer; +G_GNUC_BEGIN_IGNORE_DEPRECATIONS; struct wl_buffer *legacy_buffer; +G_GNUC_END_IGNORE_DEPRECATIONS; }; int32_t width, height; From c9fbb5177572b66a0c318aa39c88f2afe15dea3a Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 23 Aug 2013 22:05:11 -0400 Subject: [PATCH 040/889] wayland: Fix build when building without Wayland --- src/core/meta-cursor-tracker-private.h | 1 + src/core/meta-cursor-tracker.c | 7 +++++++ src/meta/meta-cursor-tracker.h | 1 + 3 files changed, 9 insertions(+) diff --git a/src/core/meta-cursor-tracker-private.h b/src/core/meta-cursor-tracker-private.h index 773ac0020..7b92c6aa5 100644 --- a/src/core/meta-cursor-tracker-private.h +++ b/src/core/meta-cursor-tracker-private.h @@ -25,6 +25,7 @@ #define META_CURSOR_TRACKER_PRIVATE_H #include +#include gboolean meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker, XEvent *xevent); diff --git a/src/core/meta-cursor-tracker.c b/src/core/meta-cursor-tracker.c index 4a374d54d..41ecb69f0 100644 --- a/src/core/meta-cursor-tracker.c +++ b/src/core/meta-cursor-tracker.c @@ -39,7 +39,10 @@ #include "meta-cursor-tracker-private.h" #include "screen-private.h" + +#ifdef HAVE_WAYLAND #include "meta-wayland-private.h" +#endif #define META_WAYLAND_DEFAULT_CURSOR_HOTSPOT_X 7 #define META_WAYLAND_DEFAULT_CURSOR_HOTSPOT_Y 4 @@ -123,6 +126,7 @@ meta_cursor_tracker_class_init (MetaCursorTrackerClass *klass) G_TYPE_NONE, 0); } +#ifdef HAVE_WAYLAND static MetaCursorTracker * make_wayland_cursor_tracker (MetaScreen *screen) { @@ -139,6 +143,7 @@ make_wayland_cursor_tracker (MetaScreen *screen) return self; } +#endif static MetaCursorTracker * make_x11_cursor_tracker (MetaScreen *screen) @@ -169,9 +174,11 @@ meta_cursor_tracker_get_for_screen (MetaScreen *screen) if (screen->cursor_tracker) return screen->cursor_tracker; +#ifdef HAVE_WAYLAND if (meta_is_wayland_compositor ()) self = make_wayland_cursor_tracker (screen); else +#endif self = make_x11_cursor_tracker (screen); screen->cursor_tracker = self; diff --git a/src/meta/meta-cursor-tracker.h b/src/meta/meta-cursor-tracker.h index 75199d666..c59c6cefb 100644 --- a/src/meta/meta-cursor-tracker.h +++ b/src/meta/meta-cursor-tracker.h @@ -27,6 +27,7 @@ #include #include #include +#include #define META_TYPE_CURSOR_TRACKER (meta_cursor_tracker_get_type ()) #define META_CURSOR_TRACKER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_CURSOR_TRACKER, MetaCursorTracker)) From 9682a2aea42d52e37487e28d3ae04f88320ae5fb Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 23 Aug 2013 22:11:37 -0400 Subject: [PATCH 041/889] window-group: Fix compiler warning --- src/compositor/meta-window-group.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compositor/meta-window-group.c b/src/compositor/meta-window-group.c index 8fddc5e67..fe65f3950 100644 --- a/src/compositor/meta-window-group.c +++ b/src/compositor/meta-window-group.c @@ -187,7 +187,7 @@ meta_window_group_paint (ClutterActor *actor) if (META_IS_WINDOW_ACTOR (child)) { MetaWindow *meta_window; - MetaWindowActor *window_actor = child; + MetaWindowActor *window_actor = META_WINDOW_ACTOR (child); int x, y; if (!meta_actor_is_untransformed (CLUTTER_ACTOR (window_actor), &x, &y)) From bbf9358eba241d6f985c8ecc5efad7115f51f8ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 21 Aug 2013 00:32:23 +0200 Subject: [PATCH 042/889] window: Fix a compiler warning --- src/core/window.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/window.c b/src/core/window.c index e56b0d65e..036c839b5 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -6007,7 +6007,7 @@ meta_window_get_outer_rect (const MetaWindow *window, if (window->has_custom_frame_extents) { - GtkBorder *extents = &window->custom_frame_extents; + const GtkBorder *extents = &window->custom_frame_extents; rect->x += extents->left; rect->y += extents->top; rect->width -= extents->left + extents->right; From 1617323dca15d793591e454a39f6b2aa8f900ed0 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Fri, 16 Aug 2013 14:23:40 +0200 Subject: [PATCH 043/889] MetaShapedTexture: don't include private headers in public ones Private headers are not installed, so they can't be referenced from public ones. https://bugzilla.gnome.org/show_bug.cgi?id=705497 --- src/Makefile.am | 1 + src/compositor/meta-shaped-texture-private.h | 50 ++++++++++++++++++++ src/compositor/meta-shaped-texture.c | 1 + src/compositor/meta-window-actor.c | 1 + src/meta/meta-shaped-texture.h | 20 -------- src/wayland/meta-wayland-seat.c | 1 + 6 files changed, 54 insertions(+), 20 deletions(-) create mode 100644 src/compositor/meta-shaped-texture-private.h diff --git a/src/Makefile.am b/src/Makefile.am index 686d6627f..d28316961 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -77,6 +77,7 @@ libmutter_la_SOURCES = \ compositor/meta-shadow-factory.c \ compositor/meta-shadow-factory-private.h \ compositor/meta-shaped-texture.c \ + compositor/meta-shaped-texture-private.h \ compositor/meta-texture-rectangle.c \ compositor/meta-texture-rectangle.h \ compositor/meta-texture-tower.c \ diff --git a/src/compositor/meta-shaped-texture-private.h b/src/compositor/meta-shaped-texture-private.h new file mode 100644 index 000000000..907596a1e --- /dev/null +++ b/src/compositor/meta-shaped-texture-private.h @@ -0,0 +1,50 @@ +/* + * 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 +#ifdef HAVE_WAYLAND +#include "meta-wayland-private.h" +#endif + +ClutterActor *meta_shaped_texture_new_with_xwindow (Window xwindow); +#ifdef HAVE_WAYLAND +ClutterActor *meta_shaped_texture_new_with_wayland_surface (MetaWaylandSurface *surface); +void meta_shaped_texture_set_wayland_surface (MetaShapedTexture *stex, + MetaWaylandSurface *surface); +MetaWaylandSurface *meta_shaped_texture_get_wayland_surface (MetaShapedTexture *stex); +#endif + +void meta_shaped_texture_set_pixmap (MetaShapedTexture *stex, + Pixmap pixmap); +#ifdef HAVE_WAYLAND +void meta_shaped_texture_attach_wayland_buffer (MetaShapedTexture *stex, + MetaWaylandBuffer *buffer); +#endif + +#endif diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c index f0279f95c..4af53ff21 100644 --- a/src/compositor/meta-shaped-texture.c +++ b/src/compositor/meta-shaped-texture.c @@ -33,6 +33,7 @@ #include #include "meta-texture-tower.h" +#include "meta-shaped-texture-private.h" #ifdef HAVE_WAYLAND #include "meta-wayland-private.h" #include diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index f7d61f6ef..5ff27f1d9 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -28,6 +28,7 @@ #include "xprops.h" #include "compositor-private.h" +#include "meta-shaped-texture-private.h" #include "meta-shadow-factory-private.h" #include "meta-window-actor-private.h" #include "meta-texture-rectangle.h" diff --git a/src/meta/meta-shaped-texture.h b/src/meta/meta-shaped-texture.h index 2809b25f8..080554198 100644 --- a/src/meta/meta-shaped-texture.h +++ b/src/meta/meta-shaped-texture.h @@ -29,11 +29,6 @@ #include #include -#ifdef HAVE_WAYLAND -#include -#include "meta-wayland-private.h" -#endif - G_BEGIN_DECLS #define META_TYPE_SHAPED_TEXTURE (meta_shaped_texture_get_type()) @@ -69,14 +64,6 @@ struct _MetaShapedTexture GType meta_shaped_texture_get_type (void) G_GNUC_CONST; -ClutterActor *meta_shaped_texture_new_with_xwindow (Window xwindow); -#ifdef HAVE_WAYLAND -ClutterActor *meta_shaped_texture_new_with_wayland_surface (MetaWaylandSurface *surface); -void meta_shaped_texture_set_wayland_surface (MetaShapedTexture *stex, - MetaWaylandSurface *surface); -MetaWaylandSurface *meta_shaped_texture_get_wayland_surface (MetaShapedTexture *stex); -#endif - void meta_shaped_texture_set_create_mipmaps (MetaShapedTexture *stex, gboolean create_mipmaps); @@ -86,13 +73,6 @@ void meta_shaped_texture_update_area (MetaShapedTexture *stex, int width, int height); -void meta_shaped_texture_set_pixmap (MetaShapedTexture *stex, - Pixmap pixmap); -#ifdef HAVE_WAYLAND -void meta_shaped_texture_attach_wayland_buffer (MetaShapedTexture *stex, - MetaWaylandBuffer *buffer); -#endif - CoglTexture * meta_shaped_texture_get_texture (MetaShapedTexture *stex); void meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex, diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c index 3ea739919..82dcb20b0 100644 --- a/src/wayland/meta-wayland-seat.c +++ b/src/wayland/meta-wayland-seat.c @@ -35,6 +35,7 @@ #include "meta-wayland-data-device.h" #include "meta-window-actor-private.h" #include "meta/meta-shaped-texture.h" +#include "meta-shaped-texture-private.h" #include "meta-wayland-stage.h" #include "meta-cursor-tracker-private.h" From 91cdfab495606a5c541f8ad090ad0b9369380a40 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Fri, 16 Aug 2013 13:49:03 +0200 Subject: [PATCH 044/889] build: make wayland support unconditional In the wayland branch of mutter, we want to build a wayland version of the mutter libraries, and that's much easier if we just build wayland support unconditionally. The define is kept to avoid a huge diff, but should be removed in a later patch. Also, wayland support can still be disable at runtime, by launching mutter without the --nested switch. https://bugzilla.gnome.org/show_bug.cgi?id=705497 --- configure.ac | 38 +++++++++----------------------------- data/Makefile.am | 6 +----- src/Makefile.am | 16 +++------------- 3 files changed, 13 insertions(+), 47 deletions(-) diff --git a/configure.ac b/configure.ac index fd3c45579..dfaf23f02 100644 --- a/configure.ac +++ b/configure.ac @@ -113,11 +113,6 @@ AC_ARG_ENABLE(shape, [disable mutter's use of the shaped window extension]),, enable_shape=auto) -AC_ARG_ENABLE(wayland, - AC_HELP_STRING([--enable-wayland], - [Enable support for running as a hybrid X and Wayland compositor]),, - enable_wayland=no) - ## Wayland support requires the xserver.xml protocol extension found in the weston ## repository but since there aren't currently established conventions for ## installing and discovering these we simply require a location to be given @@ -216,29 +211,16 @@ if test x$have_xcursor = xyes; then AC_DEFINE(HAVE_XCURSOR, , [Building with Xcursor support]) fi -have_wayland=no -if test x$enable_wayland = "xyes"; then - WAYLAND_VERSION=0.1 - AC_MSG_CHECKING([Wayland >= $WAYLAND_VERSION]) - if ! $PKG_CONFIG --atleast-version $WAYLAND_VERSION wayland-server; then - AC_MSG_ERROR([wayland support enabled but no suitable wayland-server package found]) - fi - AC_MSG_RESULT(yes) +# We always build with wayland enabled +AC_DEFINE(HAVE_WAYLAND, , [Building with Wayland support]) - AC_PATH_PROG([WAYLAND_SCANNER],[wayland-scanner],[no]) - AS_IF([test "x$WAYLAND_SCANNER" = "xno"], - AC_MSG_ERROR([Could not find wayland-scanner in your PATH, required for parsing wayland extension protocols])) - AC_SUBST([WAYLAND_SCANNER]) - - AC_SUBST(XWAYLAND_PATH) - - MUTTER_PC_MODULES="$MUTTER_PC_MODULES wayland-server" - AC_DEFINE(HAVE_WAYLAND, , [Building with Wayland support]) - have_wayland=yes -fi - -AM_CONDITIONAL(HAVE_WAYLAND, test x$have_wayland = "xyes") +AC_PATH_PROG([WAYLAND_SCANNER],[wayland-scanner],[no]) +AS_IF([test "x$WAYLAND_SCANNER" = "xno"], + AC_MSG_ERROR([Could not find wayland-scanner in your PATH, required for parsing wayland extension protocols])) +AC_SUBST([WAYLAND_SCANNER]) +AC_SUBST(XWAYLAND_PATH) +MUTTER_PC_MODULES="$MUTTER_PC_MODULES wayland-server" PKG_CHECK_MODULES(MUTTER, $MUTTER_PC_MODULES) PKG_CHECK_EXISTS([xi >= 1.6.99.1], @@ -496,14 +478,12 @@ fi dnl ========================================================================== echo " -mutter-$VERSION +mutter-wayland-$VERSION prefix: ${prefix} source code location: ${srcdir} compiler: ${CC} - Wayland: ${have_wayland} - Startup notification: ${have_startup_notification} libcanberra: ${have_libcanberra} Introspection: ${found_introspection} diff --git a/data/Makefile.am b/data/Makefile.am index 0fbff4569..3ad550e5a 100644 --- a/data/Makefile.am +++ b/data/Makefile.am @@ -1,7 +1,3 @@ defaultcursordir = $(datadir)/mutter/cursors -dist_defaultcursor_DATA = - -if HAVE_WAYLAND -dist_defaultcursor_DATA += left_ptr.png -endif +dist_defaultcursor_DATA = left_ptr.png diff --git a/src/Makefile.am b/src/Makefile.am index d28316961..7d9af02dd 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -29,24 +29,18 @@ INCLUDES= \ -DMUTTER_PLUGIN_DIR=\"@MUTTER_PLUGIN_DIR@\" \ -DGETTEXT_PACKAGE=\"$(GETTEXT_PACKAGE)\" -if HAVE_WAYLAND INCLUDES += \ -I$(srcdir)/wayland \ -I$(builddir)/wayland \ -DXWAYLAND_PATH='"@XWAYLAND_PATH@"' -endif mutter_built_sources = \ - $(dbus_idle_built_sources) \ - mutter-enum-types.h \ - mutter-enum-types.c - -if HAVE_WAYLAND -mutter_built_sources += \ + $(dbus_idle_built_sources) \ + mutter-enum-types.h \ + mutter-enum-types.c \ wayland/xserver-protocol.c \ wayland/xserver-server-protocol.h \ wayland/xserver-client-protocol.h -endif libmutter_la_SOURCES = \ core/async-getprop.c \ @@ -178,7 +172,6 @@ libmutter_la_SOURCES = \ ui/ui.c \ $(mutter_built_sources) -if HAVE_WAYLAND libmutter_la_SOURCES += \ wayland/meta-wayland.c \ wayland/meta-wayland-private.h \ @@ -194,7 +187,6 @@ libmutter_la_SOURCES += \ wayland/meta-wayland-seat.h \ wayland/meta-wayland-stage.h \ wayland/meta-wayland-stage.c -endif libmutter_la_LDFLAGS = -no-undefined libmutter_la_LIBADD = $(MUTTER_LIBS) @@ -376,7 +368,6 @@ $(dbus_idle_built_sources) : Makefile.am idle-monitor.xml --c-generate-object-manager \ $(srcdir)/idle-monitor.xml -if HAVE_WAYLAND wayland/%-protocol.c : $(top_builddir)/protocol/%.xml mkdir -p wayland $(AM_V_GEN)$(WAYLAND_SCANNER) code < $< > $@ @@ -386,4 +377,3 @@ wayland/%-server-protocol.h : $(top_builddir)/protocol/%.xml wayland/%-client-protocol.h : $(top_builddir)/protocol/%.xml mkdir -p wayland $(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@ -endif From bd3d5df9ce26d9be8f201afd16805575bd460118 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Fri, 16 Aug 2013 13:54:42 +0200 Subject: [PATCH 045/889] Remove HAVE_WAYLAND ifdefs Wayland support is always enabled now. https://bugzilla.gnome.org/show_bug.cgi?id=705497 --- src/compositor/compositor.c | 6 ------ src/compositor/meta-shaped-texture-private.h | 6 ------ src/compositor/meta-shaped-texture.c | 14 -------------- src/compositor/meta-window-actor-private.h | 4 ---- src/compositor/meta-window-actor.c | 12 ------------ src/core/display.c | 6 ------ src/core/main.c | 6 ------ src/core/screen.c | 6 ------ src/core/window-private.h | 2 -- src/core/window.c | 8 -------- 10 files changed, 70 deletions(-) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 771fa2d75..41b3b6a17 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -84,9 +84,7 @@ #include "meta-window-group.h" #include "window-private.h" /* to check window->hidden */ #include "display-private.h" /* for meta_display_lookup_x_window() */ -#ifdef HAVE_WAYLAND #include "meta-wayland-private.h" -#endif #include #include @@ -633,9 +631,7 @@ meta_compositor_manage_screen (MetaCompositor *compositor, Display *xdisplay = meta_display_get_xdisplay (display); Window xwin; gint width, height; -#ifdef HAVE_WAYLAND MetaWaylandCompositor *wayland_compositor; -#endif /* Check if the screen is already managed */ if (meta_screen_get_compositor_data (screen)) @@ -668,14 +664,12 @@ meta_compositor_manage_screen (MetaCompositor *compositor, /* We will have already created a stage if running as a wayland * compositor... */ -#ifdef HAVE_WAYLAND if (meta_is_wayland_compositor ()) { wayland_compositor = meta_wayland_compositor_get_default (); info->stage = wayland_compositor->stage; } else -#endif /* HAVE_WAYLAND */ { info->stage = clutter_stage_new (); diff --git a/src/compositor/meta-shaped-texture-private.h b/src/compositor/meta-shaped-texture-private.h index 907596a1e..ec4f08137 100644 --- a/src/compositor/meta-shaped-texture-private.h +++ b/src/compositor/meta-shaped-texture-private.h @@ -28,23 +28,17 @@ #define __META_SHAPED_TEXTURE_PRIVATE_H__ #include -#ifdef HAVE_WAYLAND #include "meta-wayland-private.h" -#endif ClutterActor *meta_shaped_texture_new_with_xwindow (Window xwindow); -#ifdef HAVE_WAYLAND ClutterActor *meta_shaped_texture_new_with_wayland_surface (MetaWaylandSurface *surface); void meta_shaped_texture_set_wayland_surface (MetaShapedTexture *stex, MetaWaylandSurface *surface); MetaWaylandSurface *meta_shaped_texture_get_wayland_surface (MetaShapedTexture *stex); -#endif void meta_shaped_texture_set_pixmap (MetaShapedTexture *stex, Pixmap pixmap); -#ifdef HAVE_WAYLAND void meta_shaped_texture_attach_wayland_buffer (MetaShapedTexture *stex, MetaWaylandBuffer *buffer); -#endif #endif diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c index 4af53ff21..856f28475 100644 --- a/src/compositor/meta-shaped-texture.c +++ b/src/compositor/meta-shaped-texture.c @@ -34,10 +34,8 @@ #include "meta-texture-tower.h" #include "meta-shaped-texture-private.h" -#ifdef HAVE_WAYLAND #include "meta-wayland-private.h" #include -#endif #include #include @@ -65,9 +63,7 @@ static gboolean meta_shaped_texture_get_paint_volume (ClutterActor *self, Clutte typedef enum _MetaShapedTextureType { META_SHAPED_TEXTURE_TYPE_X11_PIXMAP, -#ifdef HAVE_WAYLAND META_SHAPED_TEXTURE_TYPE_WAYLAND_SURFACE, -#endif } MetaShapedTextureType; @@ -87,11 +83,9 @@ struct _MetaShapedTexturePrivate struct { Pixmap pixmap; } x11; -#ifdef HAVE_WAYLAND struct { MetaWaylandSurface *surface; } wayland; -#endif }; CoglTexture *texture; @@ -463,7 +457,6 @@ meta_shaped_texture_get_paint_volume (ClutterActor *self, return clutter_paint_volume_set_from_allocation (volume, self); } -#ifdef HAVE_WAYLAND ClutterActor * meta_shaped_texture_new_with_wayland_surface (MetaWaylandSurface *surface) { @@ -499,7 +492,6 @@ meta_shaped_texture_get_wayland_surface (MetaShapedTexture *stex) MetaShapedTexturePrivate *priv = stex->priv; return priv->wayland.surface; } -#endif /* HAVE_WAYLAND */ ClutterActor * meta_shaped_texture_new_with_xwindow (Window xwindow) @@ -549,7 +541,6 @@ meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex, clutter_actor_queue_redraw (CLUTTER_ACTOR (stex)); } -#ifdef HAVE_WAYLAND static void wayland_surface_update_area (MetaShapedTexture *stex, int x, @@ -609,7 +600,6 @@ wayland_surface_update_area (MetaShapedTexture *stex, } } } -#endif /* HAVE_WAYLAND */ static void queue_damage_redraw_with_clip (MetaShapedTexture *stex, @@ -679,11 +669,9 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex, cogl_texture_pixmap_x11_update_area (COGL_TEXTURE_PIXMAP_X11 (priv->texture), x, y, width, height); break; -#ifdef HAVE_WAYLAND case META_SHAPED_TEXTURE_TYPE_WAYLAND_SURFACE: wayland_surface_update_area (stex, x, y, width, height); break; -#endif } meta_texture_tower_update_area (priv->paint_tower, x, y, width, height); @@ -727,7 +715,6 @@ meta_shaped_texture_set_pixmap (MetaShapedTexture *stex, COGL_TEXTURE (priv->texture)); } -#ifdef HAVE_WAYLAND void meta_shaped_texture_attach_wayland_buffer (MetaShapedTexture *stex, MetaWaylandBuffer *buffer) @@ -773,7 +760,6 @@ meta_shaped_texture_attach_wayland_buffer (MetaShapedTexture *stex, meta_texture_tower_set_base_texture (priv->paint_tower, COGL_TEXTURE (priv->texture)); } -#endif /* HAVE_WAYLAND */ /** * meta_shaped_texture_get_texture: diff --git a/src/compositor/meta-window-actor-private.h b/src/compositor/meta-window-actor-private.h index d37ee2dbb..cfe6c9dd2 100644 --- a/src/compositor/meta-window-actor-private.h +++ b/src/compositor/meta-window-actor-private.h @@ -5,10 +5,8 @@ #include -#ifdef HAVE_WAYLAND #include #include -#endif #include #include @@ -32,7 +30,6 @@ void meta_window_actor_unmaximize (MetaWindowActor *self, void meta_window_actor_process_x11_damage (MetaWindowActor *self, XDamageNotifyEvent *event); -#ifdef HAVE_WAYLAND void meta_window_actor_process_wayland_damage (MetaWindowActor *self, int x, int y, @@ -42,7 +39,6 @@ void meta_window_actor_set_wayland_surface (MetaWindowActor *self, MetaWaylandSurface *surface); void meta_window_actor_attach_wayland_buffer (MetaWindowActor *self, MetaWaylandBuffer *buffer); -#endif void meta_window_actor_pre_paint (MetaWindowActor *self); void meta_window_actor_post_paint (MetaWindowActor *self); diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 5ff27f1d9..499960276 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -33,9 +33,7 @@ #include "meta-window-actor-private.h" #include "meta-texture-rectangle.h" #include "region-utils.h" -#ifdef HAVE_WAYLAND #include "meta-wayland-private.h" -#endif enum { POSITION_CHANGED, @@ -372,11 +370,9 @@ meta_window_actor_constructed (GObject *object) if (!priv->actor) { -#ifdef HAVE_WAYLAND if (meta_is_wayland_compositor ()) priv->actor = meta_shaped_texture_new_with_wayland_surface (window->surface); else -#endif priv->actor = meta_shaped_texture_new_with_xwindow (xwindow); clutter_actor_add_child (CLUTTER_ACTOR (self), priv->actor); @@ -1321,10 +1317,8 @@ meta_window_actor_destroy (MetaWindowActor *self) priv = self->priv; -#ifdef HAVE_WAYLAND if (meta_is_wayland_compositor ()) meta_shaped_texture_set_wayland_surface (META_SHAPED_TEXTURE (priv->actor), NULL); -#endif window = priv->window; window_type = meta_window_get_window_type (window); @@ -1568,14 +1562,12 @@ meta_window_actor_new (MetaWindow *window) meta_verbose ("add window: Meta %p, xwin 0x%x\n", window, (guint)top_window); } -#ifdef HAVE_WAYLAND else { meta_verbose ("add window: Meta %p, wayland surface %p\n", window, window->surface); top_window = None; } -#endif self = g_object_new (META_TYPE_WINDOW_ACTOR, "meta-window", window, @@ -2023,7 +2015,6 @@ meta_window_actor_process_x11_damage (MetaWindowActor *self, priv->repaint_scheduled = TRUE; } -#ifdef HAVE_WAYLAND void meta_window_actor_process_wayland_damage (MetaWindowActor *self, int x, @@ -2040,7 +2031,6 @@ meta_window_actor_process_wayland_damage (MetaWindowActor *self, x, y, width, height); priv->repaint_scheduled = TRUE; } -#endif void meta_window_actor_sync_visibility (MetaWindowActor *self) @@ -2430,7 +2420,6 @@ meta_window_actor_update_shape (MetaWindowActor *self) clutter_actor_queue_redraw (priv->actor); } -#ifdef HAVE_WAYLAND static void maybe_emit_size_changed (MetaWindowActor *self, MetaWaylandBuffer *new_buffer) @@ -2491,7 +2480,6 @@ meta_window_actor_attach_wayland_buffer (MetaWindowActor *self, maybe_emit_size_changed (self, buffer); } -#endif /* HAVE_WAYLAND */ static void meta_window_actor_handle_updates (MetaWindowActor *self) diff --git a/src/core/display.c b/src/core/display.c index 3a6827e25..118e60ebf 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -1906,9 +1906,7 @@ update_focus_window (MetaDisplay *display, Window xwindow, gulong serial) { -#ifdef HAVE_WAYLAND MetaWaylandCompositor *compositor; -#endif display->focus_serial = serial; @@ -1949,7 +1947,6 @@ update_focus_window (MetaDisplay *display, else meta_topic (META_DEBUG_FOCUS, "* Focus --> NULL with serial %lu\n", serial); -#ifdef HAVE_WAYLAND if (meta_is_wayland_compositor ()) { compositor = meta_wayland_compositor_get_default (); @@ -1962,7 +1959,6 @@ update_focus_window (MetaDisplay *display, else meta_topic (META_DEBUG_FOCUS, "Focus change has no effect, because there is no matching wayland surface"); } -#endif g_object_notify (G_OBJECT (display), "focus-window"); meta_display_update_active_window_hint (display); @@ -3246,12 +3242,10 @@ event_callback (XEvent *event, erratically because of the lag between updating the window position from the surface position. Instead we bypass the translation altogether by directly using the Clutter events */ -#ifdef HAVE_WAYLAND if (meta_is_wayland_compositor () && event->type == GenericEvent && event->xcookie.evtype == XI_Motion) return FALSE; -#endif return meta_display_handle_event (display, event); } diff --git a/src/core/main.c b/src/core/main.c index 0326d8ec3..c4620a175 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -55,9 +55,7 @@ #include "session.h" #include #include -#ifdef HAVE_WAYLAND #include "meta-wayland-private.h" -#endif #include #include @@ -350,10 +348,8 @@ meta_finalize (void) meta_display_close (display, CurrentTime); /* I doubt correct timestamps matter here */ -#ifdef HAVE_WAYLAND if (meta_is_wayland_compositor ()) meta_wayland_finalize (); -#endif } static int signal_pipe_fds[2] = { -1, -1 }; @@ -468,7 +464,6 @@ meta_init (void) g_irepository_prepend_search_path (MUTTER_PKGLIBDIR); #endif -#ifdef HAVE_WAYLAND if (meta_is_wayland_compositor ()) { /* NB: When running as a hybrid wayland compositor we run our own headless X @@ -476,7 +471,6 @@ meta_init (void) meta_wayland_init (); } else -#endif meta_select_display (opt_display_name); meta_set_syncing (opt_sync || (g_getenv ("MUTTER_SYNC") != NULL)); diff --git a/src/core/screen.c b/src/core/screen.c index 3706d94c0..eb3d5264f 100644 --- a/src/core/screen.c +++ b/src/core/screen.c @@ -45,9 +45,7 @@ #include #include "mutter-enum-types.h" #include "core.h" -#ifdef HAVE_WAYLAND #include "meta-wayland-private.h" -#endif #include "meta-cursor-tracker-private.h" #include @@ -675,9 +673,7 @@ meta_screen_new (MetaDisplay *display, char buf[128]; guint32 manager_timestamp; gulong current_workspace; -#ifdef HAVE_WAYLAND MetaWaylandCompositor *compositor; -#endif replace_current_wm = meta_get_replace_current_wm (); @@ -837,7 +833,6 @@ meta_screen_new (MetaDisplay *display, screen->xroot = xroot; screen->rect.x = screen->rect.y = 0; -#ifdef HAVE_WAYLAND if (meta_is_wayland_compositor ()) { compositor = meta_wayland_compositor_get_default (); @@ -845,7 +840,6 @@ meta_screen_new (MetaDisplay *display, screen->rect.height = clutter_actor_get_height (compositor->stage); } else -#endif { screen->rect.width = WidthOfScreen (screen->xscreen); screen->rect.height = HeightOfScreen (screen->xscreen); diff --git a/src/core/window-private.h b/src/core/window-private.h index 0f32752ef..c498aa417 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -44,9 +44,7 @@ #include #include #include -#ifdef HAVE_WAYLAND #include "meta-wayland-private.h" -#endif /* XXX: We should find a nicer approach to deal with the * circular dependency we have with the current headers diff --git a/src/core/window.c b/src/core/window.c index 036c839b5..aa48551a2 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -62,9 +62,7 @@ #include -#ifdef HAVE_WAYLAND #include "meta-wayland-private.h" -#endif /* Windows that unmaximize to a size bigger than that fraction of the workarea * will be scaled down to that size (while maintaining aspect ratio). @@ -853,9 +851,7 @@ meta_window_new_shared (MetaDisplay *display, window->dialog_pid = -1; window->client_type = client_type; -#ifdef HAVE_WAYLAND window->surface = surface; -#endif window->xwindow = xwindow; /* this is in window->screen->display, but that's too annoying to @@ -1375,7 +1371,6 @@ display_notify_window (MetaDisplay *display, MetaWindow *window) g_signal_emit_by_name (window->display, "window-marked-urgent", window); } -#ifdef HAVE_WAYLAND MetaWindow * meta_window_new_for_wayland (MetaDisplay *display, int width, @@ -1447,7 +1442,6 @@ meta_window_new_for_wayland (MetaDisplay *display, return window; } -#endif MetaWindow* meta_window_new_with_attrs (MetaDisplay *display, @@ -2107,10 +2101,8 @@ meta_window_unmanage (MetaWindow *window, meta_error_trap_pop (window->display); } -#ifdef HAVE_WAYLAND if (window->surface) meta_wayland_surface_free (window->surface); -#endif meta_prefs_remove_listener (prefs_changed_callback, window); From 542a0886cf14cec3995ada289e25f16aac772fd3 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Fri, 16 Aug 2013 14:07:46 +0200 Subject: [PATCH 046/889] Remove files no one cares about anymore mutter-plugins.pc has been replaced by libmutter.pc, and the wm properties in the control center are long gone. https://bugzilla.gnome.org/show_bug.cgi?id=705497 --- configure.ac | 1 - src/Makefile.am | 7 +------ src/mutter-plugins.pc.in | 17 ----------------- src/mutter-wm.desktop.in | 20 -------------------- 4 files changed, 1 insertion(+), 44 deletions(-) delete mode 100644 src/mutter-plugins.pc.in delete mode 100644 src/mutter-wm.desktop.in diff --git a/configure.ac b/configure.ac index dfaf23f02..92febfb4e 100644 --- a/configure.ac +++ b/configure.ac @@ -459,7 +459,6 @@ doc/reference/Makefile doc/reference/meta-docs.sgml src/Makefile src/libmutter.pc -src/mutter-plugins.pc src/compositor/plugins/Makefile protocol/Makefile data/Makefile diff --git a/src/Makefile.am b/src/Makefile.am index 7d9af02dd..133c411bb 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -288,11 +288,6 @@ desktopfiles_in_files=mutter.desktop.in desktopfiles_files=$(desktopfiles_in_files:.desktop.in=.desktop) desktopfiles_DATA = $(desktopfiles_files) -wmpropertiesdir=$(datadir)/gnome/wm-properties -wmproperties_in_files=mutter-wm.desktop.in -wmproperties_files=$(wmproperties_in_files:.desktop.in=.desktop) -wmproperties_DATA = $(wmproperties_files) - xmldir = @GNOME_KEYBINDINGS_KEYSDIR@ xml_in_files = \ 50-mutter-navigation.xml.in \ @@ -320,7 +315,7 @@ CLEANFILES = \ pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = libmutter.pc mutter-plugins.pc +pkgconfig_DATA = libmutter.pc EXTRA_DIST=$(desktopfiles_files) \ $(wmproperties_files) \ diff --git a/src/mutter-plugins.pc.in b/src/mutter-plugins.pc.in deleted file mode 100644 index 5d42232ee..000000000 --- a/src/mutter-plugins.pc.in +++ /dev/null @@ -1,17 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ -plugindir=@MUTTER_PLUGIN_DIR@ -libgnome_serverdir=@libexecdir@ -mutter_major_version=@MUTTER_MAJOR_VERSION@ -mutter_minor_version=@MUTTER_MINOR_VERSION@ -mutter_micro_version=@MUTTER_MICRO_VERSION@ -mutter_plugin_api_version=@MUTTER_PLUGIN_API_VERSION@ - -Name: mutter-plugins -Description: Dev parameters for mutter plugins -Requires: @CLUTTER_PACKAGE@ -Version: @VERSION@ -Libs: @CLUTTER_LIBS@ -Cflags: @CLUTTER_CFLAGS@ -DWITH_CLUTTER -I${includedir}/mutter/mutter-private -DMUTTER_MAJOR_VERSION=${mutter_major_version} -DMUTTER_MINOR_VERSION=${mutter_minor_version} -DMUTTER_MICRO_VERSION=${mutter_micro_version} -DMUTTER_PLUGIN_API_VERSION=${mutter_plugin_api_version} -DMUTTER_PLUGIN_DIR=\"${plugindir}\" diff --git a/src/mutter-wm.desktop.in b/src/mutter-wm.desktop.in deleted file mode 100644 index 2b60c7e0f..000000000 --- a/src/mutter-wm.desktop.in +++ /dev/null @@ -1,20 +0,0 @@ -[Desktop Entry] -Type=Application -_Name=Mutter -Exec=mutter -# name of loadable control center module -X-GNOME-WMSettingsModule=metacity -# name we put on the WM spec check window -X-GNOME-WMName=Mutter -# back compat only -X-GnomeWMSettingsLibrary=metacity -X-GNOME-Bugzilla-Bugzilla=GNOME -X-GNOME-Bugzilla-Product=mutter -X-GNOME-Bugzilla-Component=general -X-GNOME-Autostart-Phase=WindowManager -X-GNOME-Provides=windowmanager -X-GNOME-Autostart-Notify=true - -[Window Manager] -SessionManaged=true - From ea3d2b4759524345c89fe08ad0c159d7136dbdf1 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Fri, 16 Aug 2013 14:15:08 +0200 Subject: [PATCH 047/889] wayland: make parallel installable with regular mutter Modify all visible instances of mutter with mutter-wayland (libraries, folders, pkgconfig, etc.), so that the wayland branch can be installed alongside the usual X11 mutter. https://bugzilla.gnome.org/show_bug.cgi?id=705497 --- .gitignore | 8 ++-- configure.ac | 8 +++- data/Makefile.am | 2 +- doc/reference/Makefile.am | 2 +- src/Makefile.am | 42 +++++++++---------- src/libmutter-wayland.pc.in | 18 ++++++++ src/libmutter.pc.in | 18 -------- ...r.desktop.in => mutter-wayland.desktop.in} | 7 ++-- 8 files changed, 54 insertions(+), 51 deletions(-) create mode 100644 src/libmutter-wayland.pc.in delete mode 100644 src/libmutter.pc.in rename src/{mutter.desktop.in => mutter-wayland.desktop.in} (77%) diff --git a/.gitignore b/.gitignore index ec57c27de..3630c72cf 100644 --- a/.gitignore +++ b/.gitignore @@ -23,7 +23,7 @@ src/50-mutter-navigation.xml src/50-mutter-system.xml src/50-mutter-windows.xml src/mutter-wm.desktop -src/mutter.desktop +src/mutter-wayland.desktop *.o *.a *.lo @@ -46,10 +46,10 @@ POTFILES po/*.pot 50-metacity-desktop-key.xml 50-metacity-key.xml -libmutter.pc -mutter +libmutter-wayland.pc +mutter-wayland mutter-theme-viewer -mutter.desktop +mutter-wayland.desktop org.gnome.mutter.gschema.valid org.gnome.mutter.gschema.xml testasyncgetprop diff --git a/configure.ac b/configure.ac index 92febfb4e..b22793731 100644 --- a/configure.ac +++ b/configure.ac @@ -19,6 +19,10 @@ AM_INIT_AUTOMAKE([1.11 foreign no-dist-gzip dist-xz tar-ustar]) m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])],) AM_MAINTAINER_MODE([enable]) +# Change pkglibdir and pkgdatadir to mutter-wayland instead of mutter +PACKAGE="mutter-wayland" +AC_SUBST([PACKAGE], [$PACKAGE]) + MUTTER_MAJOR_VERSION=mutter_major_version MUTTER_MINOR_VERSION=mutter_minor_version MUTTER_MICRO_VERSION=mutter_micro_version @@ -34,7 +38,7 @@ AC_SUBST(MUTTER_PLUGIN_DIR) # Honor aclocal flags AC_SUBST(ACLOCAL_AMFLAGS, "\${ACLOCAL_FLAGS}") -GETTEXT_PACKAGE=mutter +GETTEXT_PACKAGE=mutter-wayland AC_SUBST(GETTEXT_PACKAGE) AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE",[Name of default gettext domain]) @@ -458,7 +462,7 @@ doc/man/Makefile doc/reference/Makefile doc/reference/meta-docs.sgml src/Makefile -src/libmutter.pc +src/libmutter-wayland.pc src/compositor/plugins/Makefile protocol/Makefile data/Makefile diff --git a/data/Makefile.am b/data/Makefile.am index 3ad550e5a..58f590006 100644 --- a/data/Makefile.am +++ b/data/Makefile.am @@ -1,3 +1,3 @@ -defaultcursordir = $(datadir)/mutter/cursors +defaultcursordir = $(pkgdatadir)/cursors dist_defaultcursor_DATA = left_ptr.png diff --git a/doc/reference/Makefile.am b/doc/reference/Makefile.am index 659eeb4d4..0776f71f9 100644 --- a/doc/reference/Makefile.am +++ b/doc/reference/Makefile.am @@ -140,7 +140,7 @@ expand_content_files= \ # e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS) # e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib) GTKDOC_CFLAGS=$(MUTTER_CFLAGS) -GTKDOC_LIBS=$(MUTTER_LIBS) $(top_builddir)/src/libmutter.la +GTKDOC_LIBS=$(MUTTER_LIBS) $(top_builddir)/src/libmutter-wayland.la # This includes the standard gtk-doc make rules, copied by gtkdocize. include $(top_srcdir)/gtk-doc.make diff --git a/src/Makefile.am b/src/Makefile.am index 133c411bb..0dbd77887 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,7 +1,7 @@ # Flag build for parallelism; see https://savannah.gnu.org/patch/?6905 .AUTOPARALLEL: -lib_LTLIBRARIES = libmutter.la +lib_LTLIBRARIES = libmutter-wayland.la SUBDIRS=compositor/plugins @@ -10,6 +10,7 @@ INCLUDES= \ -DCOGL_ENABLE_EXPERIMENTAL_API \ -DCOGL_ENABLE_EXPERIMENTAL_2_0_API \ $(MUTTER_CFLAGS) \ + -I$(top_builddir) \ -I$(srcdir) \ -I$(srcdir)/core \ -I$(srcdir)/ui \ @@ -42,7 +43,7 @@ mutter_built_sources = \ wayland/xserver-server-protocol.h \ wayland/xserver-client-protocol.h -libmutter_la_SOURCES = \ +libmutter_wayland_la_SOURCES = \ core/async-getprop.c \ core/async-getprop.h \ core/barrier.c \ @@ -172,7 +173,7 @@ libmutter_la_SOURCES = \ ui/ui.c \ $(mutter_built_sources) -libmutter_la_SOURCES += \ +libmutter_wayland_la_SOURCES += \ wayland/meta-wayland.c \ wayland/meta-wayland-private.h \ wayland/meta-xwayland-private.h \ @@ -188,8 +189,8 @@ libmutter_la_SOURCES += \ wayland/meta-wayland-stage.h \ wayland/meta-wayland-stage.c -libmutter_la_LDFLAGS = -no-undefined -libmutter_la_LIBADD = $(MUTTER_LIBS) +libmutter_wayland_la_LDFLAGS = -no-undefined +libmutter_wayland_la_LIBADD = $(MUTTER_LIBS) # Headers installed for plugins; introspected information will # be extracted into Mutter-.gir @@ -227,16 +228,16 @@ libmutterinclude_base_headers = \ libmutterinclude_extra_headers = \ meta/atomnames.h -libmutterincludedir = $(includedir)/mutter/meta +libmutterincludedir = $(includedir)/mutter-wayland/meta libmutterinclude_HEADERS = \ $(libmutterinclude_base_headers) \ $(libmutterinclude_extra_headers) -bin_PROGRAMS=mutter +bin_PROGRAMS=mutter-wayland -mutter_SOURCES = core/mutter.c -mutter_LDADD = $(MUTTER_LIBS) libmutter.la +mutter_wayland_SOURCES = core/mutter.c +mutter_wayland_LDADD = $(MUTTER_LIBS) libmutter-wayland.la if HAVE_INTROSPECTION include $(INTROSPECTION_MAKEFILE) @@ -258,15 +259,15 @@ typelib_DATA = Meta-$(api_version).typelib INTROSPECTION_GIRS = Meta-$(api_version).gir -Meta-$(api_version).gir: libmutter.la +Meta-$(api_version).gir: libmutter-wayland.la @META_GIR@_INCLUDES = GObject-2.0 GDesktopEnums-3.0 Gdk-3.0 Gtk-3.0 Clutter-1.0 xlib-2.0 xfixes-4.0 Cogl-1.0 -@META_GIR@_EXPORT_PACKAGES = libmutter +@META_GIR@_EXPORT_PACKAGES = libmutter-wayland @META_GIR@_CFLAGS = $(INCLUDES) -@META_GIR@_LIBS = libmutter.la +@META_GIR@_LIBS = libmutter-wayland.la @META_GIR@_FILES = \ mutter-enum-types.h \ $(libmutterinclude_base_headers) \ - $(filter %.c,$(libmutter_la_SOURCES)) + $(filter %.c,$(libmutter_wayland_la_SOURCES)) @META_GIR@_SCANNERFLAGS = --warn-all --warn-error endif @@ -277,14 +278,14 @@ testasyncgetprop_SOURCES = core/testasyncgetprop.c noinst_PROGRAMS=testboxes testgradient testasyncgetprop -testboxes_LDADD = $(MUTTER_LIBS) libmutter.la -testgradient_LDADD = $(MUTTER_LIBS) libmutter.la -testasyncgetprop_LDADD = $(MUTTER_LIBS) libmutter.la +testboxes_LDADD = $(MUTTER_LIBS) libmutter-wayland.la +testgradient_LDADD = $(MUTTER_LIBS) libmutter-wayland.la +testasyncgetprop_LDADD = $(MUTTER_LIBS) libmutter-wayland.la @INTLTOOL_DESKTOP_RULE@ desktopfilesdir=$(datadir)/applications -desktopfiles_in_files=mutter.desktop.in +desktopfiles_in_files=mutter-wayland.desktop.in desktopfiles_files=$(desktopfiles_in_files:.desktop.in=.desktop) desktopfiles_DATA = $(desktopfiles_files) @@ -305,7 +306,7 @@ convertdir = $(datadir)/GConf/gsettings convert_DATA = mutter-schemas.convert CLEANFILES = \ - mutter.desktop \ + mutter-wayland.desktop \ mutter-wm.desktop \ org.gnome.mutter.gschema.xml \ $(xml_DATA) \ @@ -315,7 +316,7 @@ CLEANFILES = \ pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = libmutter.pc +pkgconfig_DATA = libmutter-wayland.pc EXTRA_DIST=$(desktopfiles_files) \ $(wmproperties_files) \ @@ -325,8 +326,7 @@ EXTRA_DIST=$(desktopfiles_files) \ $(xml_in_files) \ org.gnome.mutter.gschema.xml.in \ mutter-schemas.convert \ - libmutter.pc.in \ - mutter-plugins.pc.in \ + libmutter-wayland.pc.in \ mutter-enum-types.h.in \ mutter-enum-types.c.in diff --git a/src/libmutter-wayland.pc.in b/src/libmutter-wayland.pc.in new file mode 100644 index 000000000..6537c4f75 --- /dev/null +++ b/src/libmutter-wayland.pc.in @@ -0,0 +1,18 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ +girdir=@libdir@/mutter-wayland +typelibdir=@libdir@/mutter-wayland + +mutter_major_version=@MUTTER_MAJOR_VERSION@ +mutter_minor_version=@MUTTER_MINOR_VERSION@ +mutter_micro_version=@MUTTER_MICRO_VERSION@ +mutter_plugin_api_version=@MUTTER_PLUGIN_API_VERSION@ + +Name: libmutter-wayland +Description: Mutter window manager library (Wayland branch) +Requires: gsettings-desktop-schemas gtk+-3.0 @CLUTTER_PACKAGE@ x11 wayland-server +Version: @VERSION@ +Libs: -L${libdir} -lmutter-wayland +Cflags: -I${includedir}/mutter-wayland -DMUTTER_MAJOR_VERSION=${mutter_major_version} -DMUTTER_MINOR_VERSION=${mutter_minor_version} -DMUTTER_MICRO_VERSION=${mutter_micro_version} -DMUTTER_PLUGIN_API_VERSION=${mutter_plugin_api_version} diff --git a/src/libmutter.pc.in b/src/libmutter.pc.in deleted file mode 100644 index 1f819af80..000000000 --- a/src/libmutter.pc.in +++ /dev/null @@ -1,18 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ -girdir=@libdir@/mutter -typelibdir=@libdir@/mutter - -mutter_major_version=@MUTTER_MAJOR_VERSION@ -mutter_minor_version=@MUTTER_MINOR_VERSION@ -mutter_micro_version=@MUTTER_MICRO_VERSION@ -mutter_plugin_api_version=@MUTTER_PLUGIN_API_VERSION@ - -Name: libmutter -Description: Mutter window manager library -Requires: gsettings-desktop-schemas gtk+-3.0 @CLUTTER_PACKAGE@ x11 -Version: @VERSION@ -Libs: -L${libdir} -lmutter -Cflags: -I${includedir}/mutter -DMUTTER_MAJOR_VERSION=${mutter_major_version} -DMUTTER_MINOR_VERSION=${mutter_minor_version} -DMUTTER_MICRO_VERSION=${mutter_micro_version} -DMUTTER_PLUGIN_API_VERSION=${mutter_plugin_api_version} diff --git a/src/mutter.desktop.in b/src/mutter-wayland.desktop.in similarity index 77% rename from src/mutter.desktop.in rename to src/mutter-wayland.desktop.in index 3bfb88d2d..42c517a70 100644 --- a/src/mutter.desktop.in +++ b/src/mutter-wayland.desktop.in @@ -1,7 +1,7 @@ [Desktop Entry] Type=Application -_Name=Mutter -Exec=mutter +_Name=Mutter (wayland compositor) +Exec=mutter-launch -- mutter --nested NoDisplay=true # name of loadable control center module X-GNOME-WMSettingsModule=metacity @@ -12,6 +12,5 @@ X-GnomeWMSettingsLibrary=metacity X-GNOME-Bugzilla-Bugzilla=GNOME X-GNOME-Bugzilla-Product=mutter X-GNOME-Bugzilla-Component=general -X-GNOME-Autostart-Phase=WindowManager -X-GNOME-Provides=windowmanager +X-GNOME-Autostart-Phase=DisplayServer X-GNOME-Autostart-Notify=true From 3d3ae40f79ddde5daad43f7dfc46c1560d398ca1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 21 Aug 2013 23:41:15 +0200 Subject: [PATCH 048/889] Bump version to 3.9.90 gnome-shell requires mutter and mutter-wayland at the same version to build. Also update NEWS, cherry-picked from master. --- NEWS | 26 ++++++++++++++++++++++++++ configure.ac | 2 +- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index d6fc7c8de..2da7cdc0b 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,29 @@ +3.9.90 +====== +* First release from the wayland branch, includes basic support for running + as a wayland compositor [Robert, Neil, Giovanni] +* Add support for _GTK_FRAME_EXTENTS [Jasper; #705766] +* Fix quick consecutive presses breaking keyboard input [Alban; #666101] +* Work towards running as wayland compositor [Giovanni] + - Add DBus API for display configuration + [#705670, #706231, #706233, #706322, #706382] + - Add abstraction layer for cursor tracking [#705911] + - Add support for plugin modality under wayland [#705917] +* Disable GTK+ scaling [Alexander; #706388] +* Disable blending while updating tower [Robert] +* Misc bug fixes and cleanups [Adel, Jasper, Giovanni, Colin, Rico, Florian; + #703332, #704437, #706207] + +Contributors: + Robert Bragg, Giovanni Campagna, Alban Crequy, Adel Gadllah, + Alexander Larsson, Florian Müllner, Jasper St. Pierre, Neil Roberts, + Rico Tzschichholz, Colin Walters + +Translations: + Jiro Matsuzawa [ja], Kjartan Maraas [nb], Matej Urbančič [sl], + Marek Černocký [cs], Daniel Mustieles [es], Rafael Ferreira [pt_BR], + Yaron Shahrabani [he], Ján Kyselica [sk] + 3.9.5 ===== * Don't select for touch events on the stage [Jasper; #697192] diff --git a/configure.ac b/configure.ac index b22793731..18a24b080 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ AC_PREREQ(2.50) m4_define([mutter_major_version], [3]) m4_define([mutter_minor_version], [9]) -m4_define([mutter_micro_version], [5]) +m4_define([mutter_micro_version], [90]) m4_define([mutter_version], [mutter_major_version.mutter_minor_version.mutter_micro_version]) From f09b9573f0246fc45e3ab79c63ccb1da0867324f Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Mon, 26 Aug 2013 14:47:10 +0200 Subject: [PATCH 049/889] window: ignore skip-taskbar hint on parentless dialogs Dialogs that don't have a parent should not be skip-taskbar, otherwise they get lost and there is no way to recover them (because they're not autoraised when activating the parent), but toolkits and applications set the hint anyway. https://bugzilla.gnome.org/show_bug.cgi?id=673399 --- src/core/window.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/core/window.c b/src/core/window.c index aa48551a2..1cafc5ba5 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -8559,10 +8559,13 @@ recalc_window_features (MetaWindow *window) case META_WINDOW_DIALOG: case META_WINDOW_MODAL_DIALOG: - /* only skip taskbar if we have a real transient parent */ + /* only skip taskbar if we have a real transient parent + (and ignore the application hints) */ if (window->xtransient_for != None && window->xtransient_for != window->screen->xroot) window->skip_taskbar = TRUE; + else + window->skip_taskbar = FALSE; break; case META_WINDOW_NORMAL: From ab72352c47bfdc9a41ea83b3a8e36a7572ec8f63 Mon Sep 17 00:00:00 2001 From: Tim Lunn Date: Mon, 26 Aug 2013 11:39:38 +1000 Subject: [PATCH 050/889] 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 4c615016e..830e1c67d 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); From 6526e9882b304ad24218bb5f576a35fd10100bdc Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 26 Aug 2013 16:22:08 -0400 Subject: [PATCH 051/889] idle-monitor: Fix a warning when a callback removes the user active watch The user active watch is a one-fire watch, but it is valid in the API for the callback to explicitly remove the watch itself. In that case, the watch will be invalid after the user removes it, and the memory potentially freed. So make sure to not dereference the watch after the callback is called. https://bugzilla.gnome.org/show_bug.cgi?id=706825 --- src/core/meta-idle-monitor.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/core/meta-idle-monitor.c b/src/core/meta-idle-monitor.c index cc3e8f707..4301b003e 100644 --- a/src/core/meta-idle-monitor.c +++ b/src/core/meta-idle-monitor.c @@ -110,19 +110,20 @@ static void fire_watch (MetaIdleMonitorWatch *watch) { MetaIdleMonitor *monitor; + guint id; + gboolean is_user_active_watch; monitor = watch->monitor; g_object_ref (monitor); - if (watch->callback) - { - watch->callback (watch->monitor, - watch->id, - watch->user_data); - } + id = watch->id; + is_user_active_watch = (watch->timeout_msec == 0); - if (watch->timeout_msec == 0) - meta_idle_monitor_remove_watch (watch->monitor, watch->id); + if (watch->callback) + watch->callback (monitor, id, watch->user_data); + + if (is_user_active_watch) + meta_idle_monitor_remove_watch (monitor, id); g_object_unref (monitor); } From 62d908be420e87c9d53534fbacbb5262e3572937 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Mon, 26 Aug 2013 17:27:33 +0200 Subject: [PATCH 052/889] MonitorManager: return the new backlight after changing Modify the interface of ChangeBacklight to return the new value, to account for rounding to HW limits. https://bugzilla.gnome.org/show_bug.cgi?id=706729 --- src/core/monitor.c | 2 +- src/xrandr.xml | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/core/monitor.c b/src/core/monitor.c index e3e81ab0c..c6b46496c 100644 --- a/src/core/monitor.c +++ b/src/core/monitor.c @@ -1228,7 +1228,7 @@ meta_monitor_manager_handle_change_backlight (MetaDBusDisplayConfig *skeleton, META_MONITOR_MANAGER_GET_CLASS (manager)->change_backlight (manager, output, value); - meta_dbus_display_config_complete_change_backlight (skeleton, invocation); + meta_dbus_display_config_complete_change_backlight (skeleton, invocation, output->backlight); return TRUE; } diff --git a/src/xrandr.xml b/src/xrandr.xml index d8574ad7c..06449c36a 100644 --- a/src/xrandr.xml +++ b/src/xrandr.xml @@ -205,11 +205,14 @@ Changes the backlight of @output to @value, which is expressed as a percentage and rounded to the HW limits. + + Returns the new value after rounding. --> + + From 4d01eb3a235f44587e869670bdf01d691922a6aa Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Mon, 21 Oct 2013 13:07:36 +0200 Subject: [PATCH 180/889] MonitorConfig: Use new UPower API The "changed" signal was removed. Use "notify" instead to track just the lid-is-closed state. Conflicts: configure.ac --- configure.ac | 2 +- src/core/monitor-config.c | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index fe99aed75..6e77f1889 100644 --- a/configure.ac +++ b/configure.ac @@ -79,7 +79,7 @@ MUTTER_PC_MODULES=" xcomposite >= 0.2 xfixes xrender xdamage xi >= 1.6.0 $CLUTTER_PACKAGE >= 1.15.94 cogl-1.0 >= 1.13.3 - upower-glib > 0.9.11 + upower-glib >= 0.99.0 gnome-desktop-3.0 " diff --git a/src/core/monitor-config.c b/src/core/monitor-config.c index 8fcd49608..ddda53a1a 100644 --- a/src/core/monitor-config.c +++ b/src/core/monitor-config.c @@ -99,8 +99,9 @@ static gboolean meta_monitor_config_assign_crtcs (MetaConfiguration *config, GPtrArray *crtcs, GPtrArray *outputs); -static void power_client_changed_cb (UpClient *client, - gpointer user_data); +static void power_client_changed_cb (UpClient *client, + GParamSpec *pspec, + gpointer user_data); static void free_output_key (MetaOutputKey *key) @@ -232,7 +233,7 @@ meta_monitor_config_init (MetaMonitorConfig *self) self->up_client = up_client_new (); self->lid_is_closed = up_client_get_lid_is_closed (self->up_client); - g_signal_connect_object (self->up_client, "changed", + g_signal_connect_object (self->up_client, "notify::lid-is-closed", G_CALLBACK (power_client_changed_cb), self, 0); } @@ -1335,8 +1336,9 @@ turn_off_laptop_display (MetaMonitorConfig *self, } static void -power_client_changed_cb (UpClient *client, - gpointer user_data) +power_client_changed_cb (UpClient *client, + GParamSpec *pspec, + gpointer user_data) { MetaMonitorManager *manager = meta_monitor_manager_get (); MetaMonitorConfig *self = user_data; From dc8231c2cf4bc8607484561ab336d4aa4517544c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Sat, 5 Oct 2013 23:20:16 +0900 Subject: [PATCH 181/889] MetaCursorTracker: Set hot spot when cursor buffer set from wl_buffer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When creating MetaCursorReference using a wl_resource, use the provided hotspot coordinates. This makes clients such as clickdot work more correctly. Signed-off-by: Jonas Ådahl https://bugzilla.gnome.org/show_bug.cgi?id=709593 --- src/core/meta-cursor-tracker.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/core/meta-cursor-tracker.c b/src/core/meta-cursor-tracker.c index 5898df28b..cff5f3eee 100644 --- a/src/core/meta-cursor-tracker.c +++ b/src/core/meta-cursor-tracker.c @@ -352,6 +352,8 @@ meta_cursor_reference_from_buffer (MetaCursorTracker *tracker, self = g_slice_new0 (MetaCursorReference); self->ref_count = 1; + self->hot_x = hot_x; + self->hot_y = hot_y; backend = clutter_get_default_backend (); cogl_context = clutter_backend_get_cogl_context (backend); From cd76313297c59289206c36f3e257cb77df5d4351 Mon Sep 17 00:00:00 2001 From: Asad Mehmood Date: Thu, 17 Oct 2013 16:05:59 +0100 Subject: [PATCH 182/889] monitor: expose min-backlight-step Expose min-backlight-step so that gnome-settings-daemon can support backlights with less than 10 steps without mutter normalizing the brightness back to its original value https://bugzilla.gnome.org/show_bug.cgi?id=710380 --- src/core/monitor.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/core/monitor.c b/src/core/monitor.c index 5b5093c79..999b23ec0 100644 --- a/src/core/monitor.c +++ b/src/core/monitor.c @@ -729,6 +729,9 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton, g_variant_new_take_string (make_display_name (manager, output))); g_variant_builder_add (&properties, "{sv}", "backlight", g_variant_new_int32 (output->backlight)); + g_variant_builder_add (&properties, "{sv}", "min-backlight-step", + g_variant_new_int32 ((output->backlight_max - output->backlight_min) ? + 100 / (output->backlight_max - output->backlight_min) : -1)); g_variant_builder_add (&properties, "{sv}", "primary", g_variant_new_boolean (output->is_primary)); g_variant_builder_add (&properties, "{sv}", "presentation", From 918cfdcbdadfa24ee1c8e57b05416307e32d73db Mon Sep 17 00:00:00 2001 From: Magdalen Berns Date: Mon, 28 Oct 2013 16:27:29 +0000 Subject: [PATCH 183/889] Mutter-Wayland: fix build failure Bug https://bugzilla.gnome.org/show_bug.cgi?id=710565 --- Makefile.am | 2 ++ configure.ac | 1 + 2 files changed, 3 insertions(+) diff --git a/Makefile.am b/Makefile.am index 979ba2573..19dbe9cf1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -6,3 +6,5 @@ EXTRA_DIST = HACKING MAINTAINERS rationales.txt DISTCLEANFILES = intltool-extract intltool-merge intltool-update po/stamp-it po/.intltool-merge-cache DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc + +ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS} diff --git a/configure.ac b/configure.ac index 6e77f1889..056831726 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,5 @@ AC_PREREQ(2.50) +AC_CONFIG_MACRO_DIR([m4]) m4_define([mutter_major_version], [3]) m4_define([mutter_minor_version], [10]) From 1bd3a162f8b2e66969342353fc1ff5023a7cc83e Mon Sep 17 00:00:00 2001 From: Magdalen Berns Date: Sun, 20 Oct 2013 21:06:24 +0100 Subject: [PATCH 184/889] Mutter-Wayland: Define dbus_idle_build_sources once Bug https://bugzilla.gnome.org/show_bug.cgi?id=710566 --- src/Makefile.am | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Makefile.am b/src/Makefile.am index 29172020f..b2d558421 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -395,7 +395,6 @@ $(dbus_xrandr_built_sources) : Makefile.am xrandr.xml --generate-c-code meta-dbus-xrandr \ $(srcdir)/xrandr.xml -dbus_idle_built_sources = meta-dbus-idle-monitor.c meta-dbus-idle-monitor.h $(dbus_idle_built_sources) : Makefile.am idle-monitor.xml $(AM_V_GEN)gdbus-codegen \ From 78fcfec5c1fa64ffe620f068bc77224d49786fb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 30 Oct 2013 17:13:40 +0100 Subject: [PATCH 185/889] Bump version to 3.11.1 Update NEWS. --- NEWS | 12 ++++++++++++ configure.ac | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index c4a0688f6..b7c5dda54 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,15 @@ +3.11.1 +====== +* Fix tile previews getting stuck on right click during drags [Lionel; #704759] +* Use new UPower API [Bastien] +* Set hot spot when cursor set from wl_buffer [Jonas; #709593] +* Expose min-backlight-step [Asad; #710380] +* Misc. bug fixes and cleanups [Jasper, Olav, Magdalen; #709776] + +Contributors: + Magdalen Berns, Lionel Landwerlin, Asad Mehmood, Bastien Nocera, + Jasper St. Pierre, Olav Vitters, Jonas Ådahl + 3.10.1 ====== * Don't apply fullscreen workarounds to CSD windows [Giovanni; #708718] diff --git a/configure.ac b/configure.ac index 056831726..6d7607294 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ AC_PREREQ(2.50) AC_CONFIG_MACRO_DIR([m4]) m4_define([mutter_major_version], [3]) -m4_define([mutter_minor_version], [10]) +m4_define([mutter_minor_version], [11]) m4_define([mutter_micro_version], [1]) m4_define([mutter_version], From 237d990dea5baa8769f541a294f64852332fdcd4 Mon Sep 17 00:00:00 2001 From: Andreas Heider Date: Wed, 6 Nov 2013 00:00:48 +0100 Subject: [PATCH 186/889] mutter-wl: Support setting NULL surface regions. According to the wayland spec (A.14.1.5. wl_surface::set_opaque_region), setting a NULL opaque region is possible and should cause the pending opaque region to be set to empty. This implements the required behavoir. Also fixes set_input_region, which suffered from an analogous bug. Previously the weston-simple-egl demo client caused mutter-wayland to crash with a segfault in meta_wayland_surface_set_opaque_region, with this patch it works as intended. https://bugzilla.gnome.org/show_bug.cgi?id=711518 --- src/wayland/meta-wayland-surface.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index f77f9cb3e..5f00ce34a 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -199,14 +199,17 @@ meta_wayland_surface_set_opaque_region (struct wl_client *client, struct wl_resource *region_resource) { MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); - MetaWaylandRegion *region = wl_resource_get_user_data (region_resource); /* X11 unmanaged window */ if (!surface) return; g_clear_pointer (&surface->pending.opaque_region, cairo_region_destroy); - surface->pending.opaque_region = cairo_region_copy (region->region); + if (region_resource) + { + MetaWaylandRegion *region = wl_resource_get_user_data (region_resource); + surface->pending.opaque_region = cairo_region_copy (region->region); + } } static void @@ -215,14 +218,17 @@ meta_wayland_surface_set_input_region (struct wl_client *client, struct wl_resource *region_resource) { MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); - MetaWaylandRegion *region = wl_resource_get_user_data (region_resource); /* X11 unmanaged window */ if (!surface) return; g_clear_pointer (&surface->pending.input_region, cairo_region_destroy); - surface->pending.input_region = cairo_region_copy (region->region); + if (region_resource) + { + MetaWaylandRegion *region = wl_resource_get_user_data (region_resource); + surface->pending.input_region = cairo_region_copy (region->region); + } } static void From 7908eca579fe1a3f2c4702d35afc32abdd1642f1 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 8 Nov 2013 17:03:10 -0500 Subject: [PATCH 187/889] protocol: Ship gtk-shell.xml --- protocol/Makefile.am | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/protocol/Makefile.am b/protocol/Makefile.am index 4d3a8153a..0efd1f509 100644 --- a/protocol/Makefile.am +++ b/protocol/Makefile.am @@ -1 +1,6 @@ -EXTRA_DIST = xserver.xml +NULL = + +EXTRA_DIST = \ + gtk-shell.xml \ + xserver.xml \ + $(NULL) From ad84aef7663b982a14223e8a4d254a920ae797b9 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 12 Nov 2013 15:42:31 -0500 Subject: [PATCH 188/889] wayland-seat: Fix updating the grab serial We shouldn't update the grab serial if we go from 2 buttons => 1. --- src/wayland/meta-wayland-seat.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c index 17544b353..2a0b16f1f 100644 --- a/src/wayland/meta-wayland-seat.c +++ b/src/wayland/meta-wayland-seat.c @@ -280,13 +280,14 @@ handle_button_event (MetaWaylandSeat *seat, const ClutterEvent *event) { MetaWaylandPointer *pointer = &seat->pointer; - gboolean state = event->type == CLUTTER_BUTTON_PRESS; + gboolean implicit_grab; uint32_t button; MetaWaylandSurface *surface; notify_motion (seat, event); - if (state && pointer->button_count == 1) + implicit_grab = (event->type == CLUTTER_BUTTON_PRESS) && (pointer->button_count == 1); + if (implicit_grab) { button = clutter_event_get_button (event); pointer->grab_button = button; @@ -307,7 +308,7 @@ handle_button_event (MetaWaylandSeat *seat, pointer->grab->interface->button (pointer->grab, event); - if (pointer->button_count == 1) + if (implicit_grab) pointer->grab_serial = wl_display_get_serial (seat->display); } From ab080e3e6b142ede100b92ed5db423e04f171fd8 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 8 Nov 2013 17:05:07 -0500 Subject: [PATCH 189/889] Add support for xdg-shell Replace our existing support for wl_shell with xdg_shell, the new proposal for how Wayland surfaces should work. --- .gitignore | 3 + protocol/Makefile.am | 1 + protocol/xdg-shell.xml | 385 +++++++++++++++++++++++++++ src/Makefile.am | 3 + src/wayland/meta-wayland-pointer.c | 10 +- src/wayland/meta-wayland-surface.c | 387 +++++++++++++--------------- src/wayland/meta-wayland-surface.h | 4 +- src/wayland/meta-wayland-versions.h | 4 +- 8 files changed, 585 insertions(+), 212 deletions(-) create mode 100644 protocol/xdg-shell.xml diff --git a/.gitignore b/.gitignore index 898cd5131..ae4d6b01b 100644 --- a/.gitignore +++ b/.gitignore @@ -81,6 +81,9 @@ src/mutter-plugins.pc src/wayland/gtk-shell-protocol.c src/wayland/gtk-shell-client-protocol.h src/wayland/gtk-shell-server-protocol.h +src/wayland/xdg-shell-protocol.c +src/wayland/xdg-shell-client-protocol.h +src/wayland/xdg-shell-server-protocol.h src/wayland/xserver-protocol.c src/wayland/xserver-client-protocol.h src/wayland/xserver-server-protocol.h diff --git a/protocol/Makefile.am b/protocol/Makefile.am index 0efd1f509..8ce700537 100644 --- a/protocol/Makefile.am +++ b/protocol/Makefile.am @@ -2,5 +2,6 @@ NULL = EXTRA_DIST = \ gtk-shell.xml \ + xdg-shell.xml \ xserver.xml \ $(NULL) diff --git a/protocol/xdg-shell.xml b/protocol/xdg-shell.xml new file mode 100644 index 000000000..fbd4f6da4 --- /dev/null +++ b/protocol/xdg-shell.xml @@ -0,0 +1,385 @@ + + + + + Copyright © 2008-2013 Kristian Høgsberg + Copyright © 2013 Rafael Antognolli + Copyright © 2013 Jasper St. Pierre + Copyright © 2010-2013 Intel 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 + the copyright holders not be used in advertising or publicity + pertaining to distribution of the software without specific, + written prior permission. The copyright holders make no + representations about the suitability of this software for any + purpose. It is provided "as is" without express or implied + warranty. + + THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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. + + + + + This interface is implemented by servers that provide + desktop-style user interfaces. + + It allows clients to associate a xdg_surface with + a basic surface. + + + + + Use this enum to check the protocol version, and it will be updated + automatically. + + + + + + + + Use this request in order to enable use of this interface. + + Understand and agree that one is using an unstable interface, + that will likely change in the future, breaking the API. + + + + + + + Create a shell surface for an existing surface. + + Only one shell or popup surface can be associated with a given + surface. + + + + + + + + Create a popup surface for an existing surface. + + Only one shell or popup surface can be associated with a given + surface. + + + + + + + + + + + + + + + + An interface that may be implemented by a wl_surface, for + implementations that provide a desktop-style user interface. + + It provides requests to treat surfaces like windows, allowing to set + properties like maximized, fullscreen, minimized, and to move and resize + them, and associate metadata like title and app id. + + On the server side the object is automatically destroyed when + the related wl_surface is destroyed. On client side, + xdg_surface.destroy() must be called before destroying + the wl_surface object. + + + + + The xdg_surface interface is removed from the wl_surface object + that was turned into a xdg_surface with + xdg_shell.get_xdg_surface request. The xdg_surface properties, + like maximized and fullscreen, are lost. The wl_surface loses + its role as a xdg_surface. The wl_surface is unmapped. + + + + + + Setting a surface as transient of another means that it is child + of another surface. + + Child surfaces are stacked above their parents, and will be + unmapped if the parent is unmapped too. They should not appear + on task bars and alt+tab. + + + + + + + Set a short title for the surface. + + This string may be used to identify the surface in a task bar, + window list, or other user interface elements provided by the + compositor. + + The string must be encoded in UTF-8. + + + + + + + Set an id for the surface. + + The app id identifies the general class of applications to which + the surface belongs. + + It should be the ID that appears in the new desktop entry + specification, the interface name. + + + + + + + A client must respond to a ping event with a pong request or + the client may be deemed unresponsive. + + + + + + + Ping a client to check if it is receiving events and sending + requests. A client is expected to reply with a pong request. + + + + + + + Start a pointer-driven move of the surface. + + This request must be used in response to a button press event. + The server may ignore move requests depending on the state of + the surface (e.g. fullscreen or maximized). + + + + + + + + These values are used to indicate which edge of a surface + is being dragged in a resize operation. The server may + use this information to adapt its behavior, e.g. choose + an appropriate cursor image. + + + + + + + + + + + + + + + Start a pointer-driven resizing of the surface. + + This request must be used in response to a button press event. + The server may ignore resize requests depending on the state of + the surface (e.g. fullscreen or maximized). + + + + + + + + + The configure event asks the client to resize its surface. + + The size is a hint, in the sense that the client is free to + ignore it if it doesn't resize, pick a smaller size (to + satisfy aspect ratio or resize in steps of NxM pixels). + + The edges parameter provides a hint about how the surface + was resized. The client may use this information to decide + how to adjust its content to the new size (e.g. a scrolling + area might adjust its content position to leave the viewable + content unmoved). Valid edge values are from resize_edge enum. + + The maximized parameter informs if the surface is in a maximized + state. Same for the fullscreen parameter. + + The client is free to dismiss all but the last configure + event it received. + + The width and height arguments specify the size of the window + in surface local coordinates. + + + + + + + + + + + + Set the default output used by this surface when it is first mapped. + + If this value is NULL (default), it's up to the compositor to choose + which display will be used to map this surface. + + When fullscreen or maximized state are set on this surface, and it + wasn't mapped yet, the output set with this method will be used. + Otherwise, the output where the surface is currently mapped will be + used. + + + + + + + Set the surface as fullscreen. + + The compositor must reply to this request with a configure event + with the dimensions for the output on which the surface will be + made fullscreen. + + Once the fullscreen state is set, a "fullscreen_set" event will + be sent to the client. + + Setting one state won't unset another state. Use + xdg_surface.unset_fullscreen for unsetting it. + + + + + + Unset the surface fullscreen state. + + + + + + Set the surface as maximized. + + The compositor must reply to this request with a configure event + with the dimensions for the output on which the surface will be + made maximized. + + Once the maximized state is set, a "maximized_set" event will be + sent to the client. + + Setting one state won't unset another state. Use + xdg_surface.unset_maximized for unsetting it. + + + + + + Unset the surface maximized state. + + + + + + Set the surface minimized state. + + Setting one state won't unset another state. + + + + + + The focused_set event is sent when this surface has been + activated. Window decorations should be updated accordingly. + + + + + + The focused_unset event is sent when this surface has been + deactivated, because another surface has been activated. Window + decorations should be updated accordingly. + + + + + + + An interface that may be implemented by a wl_surface, for + implementations that provide a desktop-style popups/menus. A popup + surface is a transient surface with an added pointer grab. + + An existing implicit grab will be changed to owner-events mode, + and the popup grab will continue after the implicit grab ends + (i.e. releasing the mouse button does not cause the popup to be + unmapped). + + The popup grab continues until the window is destroyed or a mouse + button is pressed in any other clients window. A click in any of + the clients surfaces is reported as normal, however, clicks in + other clients surfaces will be discarded and trigger the callback. + + The x and y arguments specify the locations of the upper left + corner of the surface relative to the upper left corner of the + parent surface, in surface local coordinates. + + xdg_popup surfaces are always transient for another surface. + + + + + The xdg_surface interface is removed from the wl_surface object + that was turned into a xdg_surface with + xdg_shell.get_xdg_surface request. The xdg_surface properties, + like maximized and fullscreen, are lost. The wl_surface loses + its role as a xdg_surface. The wl_surface is unmapped. + + + + + + A client must respond to a ping event with a pong request or + the client may be deemed unresponsive. + + + + + + + Ping a client to check if it is receiving events and sending + requests. A client is expected to reply with a pong request. + + + + + + + The popup_done event is sent out when a popup grab is broken, + that is, when the users clicks a surface that doesn't belong + to the client owning the popup surface. + + + + + + diff --git a/src/Makefile.am b/src/Makefile.am index b2d558421..a8d52bcaf 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -43,6 +43,9 @@ mutter_built_sources = \ wayland/gtk-shell-protocol.c \ wayland/gtk-shell-server-protocol.h \ wayland/gtk-shell-client-protocol.h \ + wayland/xdg-shell-protocol.c \ + wayland/xdg-shell-server-protocol.h \ + wayland/xdg-shell-client-protocol.h \ wayland/xserver-protocol.c \ wayland/xserver-server-protocol.h \ wayland/xserver-client-protocol.h diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index 2ec8c75d5..1f6962a5f 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -49,6 +49,7 @@ #include "meta-wayland-pointer.h" #include "meta-wayland-private.h" +#include "xdg-shell-server-protocol.h" #include @@ -532,9 +533,14 @@ meta_wayland_pointer_end_popup_grab (MetaWaylandPointer *pointer) wl_list_for_each_safe (popup, tmp, &popup_grab->all_popups, link) { - MetaWaylandSurfaceExtension *shell_surface = popup->surface->shell_surface; + MetaWaylandSurfaceExtension *shell_surface = popup->surface->xdg_surface; + struct wl_client *client = wl_resource_get_client (shell_surface->resource); + struct wl_display *display = wl_client_get_display (client); + uint32_t serial; - wl_shell_surface_send_popup_done (shell_surface->resource); + serial = wl_display_next_serial (display); + + xdg_popup_send_popup_done (shell_surface->resource, serial); wl_list_remove (&popup->surface_destroy_listener.link); wl_list_remove (&popup->link); g_slice_free (MetaWaylandPopup, popup); diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 5f00ce34a..0a9ebf866 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -39,6 +39,7 @@ #include #include "gtk-shell-server-protocol.h" +#include "xdg-shell-server-protocol.h" #include "meta-wayland-private.h" #include "meta-xwayland-private.h" @@ -492,9 +493,69 @@ meta_wayland_surface_create (MetaWaylandCompositor *compositor, } static void -shell_surface_pong (struct wl_client *client, - struct wl_resource *resource, - guint32 serial) +xdg_surface_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + g_warning ("TODO: support xdg_surface.destroy"); +} + +static void +xdg_surface_set_transient_for (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *parent) +{ + MetaWaylandSurfaceExtension *surface_ext = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = surface_ext->surface; + + MetaWaylandSurfaceExtension *parent_ext = wl_resource_get_user_data (parent); + MetaWaylandSurface *parent_surf = parent_ext->surface; + + if (surface->window && parent_surf->window) + meta_window_set_transient_for (surface->window, parent_surf->window); +} + +static void +xdg_surface_set_title (struct wl_client *client, + struct wl_resource *resource, + const char *title) +{ + MetaWaylandSurfaceExtension *extension = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = extension->surface; + + if (surface->window) + meta_window_set_title (surface->window, title); + else + { + ensure_initial_state (surface); + + g_free (surface->initial_state->title); + surface->initial_state->title = g_strdup (title); + } +} + +static void +xdg_surface_set_app_id (struct wl_client *client, + struct wl_resource *resource, + const char *app_id) +{ + MetaWaylandSurfaceExtension *extension = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = extension->surface; + + if (surface->window) + meta_window_set_wm_class (surface->window, app_id, app_id); + else + { + ensure_initial_state (surface); + + g_free (surface->initial_state->app_id); + surface->initial_state->app_id = g_strdup (app_id); + } +} + +static void +xdg_surface_pong (struct wl_client *client, + struct wl_resource *resource, + guint32 serial) { } @@ -568,23 +629,23 @@ static const MetaWaylandPointerGrabInterface move_grab_interface = { }; static void -shell_surface_move (struct wl_client *client, - struct wl_resource *resource, - struct wl_resource *seat_resource, - guint32 serial) +xdg_surface_move (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *seat_resource, + guint32 serial) { MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); - MetaWaylandSurfaceExtension *shell_surface = wl_resource_get_user_data (resource); + MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); MetaWindow *window; MetaWaylandMoveGrab *move_grab; MetaRectangle rect; if (seat->pointer.button_count == 0 || seat->pointer.grab_serial != serial || - seat->pointer.focus != shell_surface->surface) + seat->pointer.focus != xdg_surface->surface) return; - window = shell_surface->surface->window; + window = xdg_surface->surface->window; if (!window) return; @@ -595,15 +656,15 @@ shell_surface_move (struct wl_client *client, move_grab = g_slice_new (MetaWaylandMoveGrab); - meta_window_get_input_rect (shell_surface->surface->window, + meta_window_get_input_rect (xdg_surface->surface->window, &rect); move_grab->generic.interface = &move_grab_interface; move_grab->generic.pointer = &seat->pointer; - move_grab->surface = shell_surface->surface; + move_grab->surface = xdg_surface->surface; move_grab->surface_destroy_listener.notify = move_grab_lose_surface; - wl_resource_add_destroy_listener (shell_surface->surface->resource, + wl_resource_add_destroy_listener (xdg_surface->surface->resource, &move_grab->surface_destroy_listener); move_grab->dx = wl_fixed_from_int (rect.x) - seat->pointer.grab_x; @@ -622,209 +683,97 @@ shell_surface_move (struct wl_client *client, * XXX: For now we just focus the surface directly associated with * the grab. */ - meta_wayland_pointer_set_focus (&seat->pointer, shell_surface->surface); + meta_wayland_pointer_set_focus (&seat->pointer, xdg_surface->surface); } static void -shell_surface_resize (struct wl_client *client, +xdg_surface_resize (struct wl_client *client, struct wl_resource *resource, struct wl_resource *seat, guint32 serial, guint32 edges) { - g_warning ("TODO: support shell_surface_resize request"); + g_warning ("TODO: support xdg_surface.resize"); } static void -shell_surface_set_toplevel (struct wl_client *client, +xdg_surface_set_output (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *output) +{ + g_warning ("TODO: support xdg_surface.set_output"); +} + +static void +xdg_surface_set_fullscreen (struct wl_client *client, struct wl_resource *resource) { - MetaWaylandSurfaceExtension *shell_surface = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = shell_surface->surface; - MetaWaylandCompositor *compositor = surface->compositor; - - /* NB: Surfaces from xwayland become managed based on X events. */ - if (client == compositor->xwayland_client) - return; - - if (surface->window) - { - if (surface->window->fullscreen) - meta_window_unmake_fullscreen (surface->window); - if (meta_window_get_maximized (surface->window) != 0) - meta_window_unmaximize (surface->window, META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL); - } - else - { - ensure_initial_state (surface); - - surface->initial_state->initial_type = META_WAYLAND_SURFACE_TOPLEVEL; - } -} - -static void -shell_surface_set_transient (struct wl_client *client, - struct wl_resource *resource, - struct wl_resource *parent, - int x, - int y, - guint32 flags) -{ - MetaWaylandSurfaceExtension *shell_surface = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = shell_surface->surface; - MetaWaylandSurface *parent_surface = wl_resource_get_user_data (parent); - MetaWaylandCompositor *compositor = surface->compositor; - - /* NB: Surfaces from xwayland become managed based on X events. */ - if (client == compositor->xwayland_client) - return; - - if (surface->window) - meta_window_set_transient_for (surface->window, parent_surface->window); - else - { - ensure_initial_state (surface); - - surface->initial_state->initial_type = META_WAYLAND_SURFACE_TOPLEVEL; - surface->initial_state->transient_for = parent; - } -} - -static void -shell_surface_set_fullscreen (struct wl_client *client, - struct wl_resource *resource, - guint32 method, - guint32 framerate, - struct wl_resource *output) -{ - MetaWaylandSurfaceExtension *shell_surface = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = shell_surface->surface; - MetaWaylandCompositor *compositor = surface->compositor; - - /* NB: Surfaces from xwayland become managed based on X events. */ - if (client == compositor->xwayland_client) - return; + MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = xdg_surface->surface; if (surface->window) meta_window_make_fullscreen (surface->window); - else - { - ensure_initial_state (surface); - - surface->initial_state->initial_type = META_WAYLAND_SURFACE_FULLSCREEN; - } } static void -shell_surface_set_popup (struct wl_client *client, - struct wl_resource *resource, - struct wl_resource *seat_resource, - guint32 serial, - struct wl_resource *parent, - gint32 x, - gint32 y, - guint32 flags) +xdg_surface_unset_fullscreen (struct wl_client *client, + struct wl_resource *resource) { - MetaWaylandSurfaceExtension *shell_surface = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = shell_surface->surface; - MetaWaylandCompositor *compositor = surface->compositor; - MetaWaylandSeat *seat = compositor->seat; - - if (serial < seat->pointer.click_serial) - { - /* stale request */ - return; - } + MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = xdg_surface->surface; if (surface->window) - { - meta_warning ("Client set_popup() on an already visible window, this is not supported\n"); - } - else - { - ensure_initial_state (surface); - - surface->initial_state->initial_type = META_WAYLAND_SURFACE_POPUP; - surface->initial_state->transient_for = parent; - surface->initial_state->x = x; - surface->initial_state->y = y; - } - + meta_window_unmake_fullscreen (surface->window); } static void -shell_surface_set_maximized (struct wl_client *client, - struct wl_resource *resource, - struct wl_resource *output) +xdg_surface_set_maximized (struct wl_client *client, + struct wl_resource *resource) { - MetaWaylandSurfaceExtension *shell_surface = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = shell_surface->surface; - MetaWaylandCompositor *compositor = surface->compositor; - - /* NB: Surfaces from xwayland become managed based on X events. */ - if (client == compositor->xwayland_client) - return; + MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = xdg_surface->surface; if (surface->window) meta_window_maximize (surface->window, META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL); - else - { - ensure_initial_state (surface); - - surface->initial_state->initial_type = META_WAYLAND_SURFACE_MAXIMIZED; - } } static void -shell_surface_set_title (struct wl_client *client, - struct wl_resource *resource, - const char *title) +xdg_surface_unset_maximized (struct wl_client *client, + struct wl_resource *resource) { - MetaWaylandSurfaceExtension *extension = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = extension->surface; + MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = xdg_surface->surface; if (surface->window) - meta_window_set_title (surface->window, title); - else - { - ensure_initial_state (surface); - - g_free (surface->initial_state->title); - surface->initial_state->title = g_strdup (title); - } + meta_window_unmaximize (surface->window, META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL); } static void -shell_surface_set_class (struct wl_client *client, - struct wl_resource *resource, - const char *class_) +xdg_surface_set_minimized (struct wl_client *client, + struct wl_resource *resource) { - MetaWaylandSurfaceExtension *extension = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = extension->surface; + MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = xdg_surface->surface; if (surface->window) - meta_window_set_wm_class (surface->window, class_, class_); - else - { - ensure_initial_state (surface); - - g_free (surface->initial_state->wm_class); - surface->initial_state->wm_class = g_strdup (class_); - } + meta_window_minimize (surface->window); } -static const struct wl_shell_surface_interface meta_wayland_shell_surface_interface = +static const struct xdg_surface_interface meta_wayland_xdg_surface_interface = { - shell_surface_pong, - shell_surface_move, - shell_surface_resize, - shell_surface_set_toplevel, - shell_surface_set_transient, - shell_surface_set_fullscreen, - shell_surface_set_popup, - shell_surface_set_maximized, - shell_surface_set_title, - shell_surface_set_class + xdg_surface_destroy, + xdg_surface_set_transient_for, + xdg_surface_set_title, + xdg_surface_set_app_id, + xdg_surface_pong, + xdg_surface_move, + xdg_surface_resize, + xdg_surface_set_output, + xdg_surface_set_fullscreen, + xdg_surface_unset_fullscreen, + xdg_surface_set_maximized, + xdg_surface_unset_maximized, + xdg_surface_set_minimized, }; static void @@ -845,9 +794,7 @@ destroy_surface_extension (struct wl_resource *resource) /* In case cleaning up a dead client destroys extension first */ if (extension->surface) - { - wl_list_remove (&extension->surface_destroy_listener.link); - } + wl_list_remove (&extension->surface_destroy_listener.link); g_free (extension); } @@ -879,43 +826,69 @@ create_surface_extension (struct wl_client *client, } static void -get_shell_surface (struct wl_client *client, - struct wl_resource *resource, - guint32 id, - struct wl_resource *surface_resource) +use_unstable_version (struct wl_client *client, + struct wl_resource *resource, + int32_t version) +{ + if (version != META_XDG_SHELL_VERSION) + g_warning ("Bad xdg_shell version: %d", version); +} + +static void +get_xdg_surface (struct wl_client *client, + struct wl_resource *resource, + guint32 id, + struct wl_resource *surface_resource) { MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); - if (surface->shell_surface) + if (surface->xdg_surface) { wl_resource_post_error (surface_resource, WL_DISPLAY_ERROR_INVALID_OBJECT, - "wl_shell::get_shell_surface already requested"); + "xdg_shell::get_xdg_surface already requested"); return; } - surface->shell_surface = create_surface_extension (client, resource, id, - META_WL_SHELL_SURFACE_VERSION, surface, - &wl_shell_surface_interface, - &meta_wayland_shell_surface_interface); + surface->xdg_surface = create_surface_extension (client, resource, id, + META_XDG_SURFACE_VERSION, surface, + &xdg_surface_interface, + &meta_wayland_xdg_surface_interface); } -static const struct wl_shell_interface meta_wayland_shell_interface = +static void +get_xdg_popup (struct wl_client *client, + struct wl_resource *resource, + uint32_t id, + struct wl_resource *surface, + struct wl_resource *parent, + struct wl_resource *seat, + uint32_t serial, + int32_t x, + int32_t y, + uint32_t flags) { - get_shell_surface + g_warning ("TODO: support xdg_shell.get_xdg_popup"); +} + +static const struct xdg_shell_interface meta_wayland_xdg_shell_interface = +{ + use_unstable_version, + get_xdg_surface, + get_xdg_popup, }; static void -bind_shell (struct wl_client *client, - void *data, - guint32 version, - guint32 id) +bind_xdg_shell (struct wl_client *client, + void *data, + guint32 version, + guint32 id) { struct wl_resource *resource; - resource = wl_resource_create (client, &wl_shell_interface, - MIN (META_WL_SHELL_VERSION, version), id); - wl_resource_set_implementation (resource, &meta_wayland_shell_interface, data, NULL); + resource = wl_resource_create (client, &xdg_shell_interface, + MIN (META_XDG_SHELL_VERSION, version), id); + wl_resource_set_implementation (resource, &meta_wayland_xdg_shell_interface, data, NULL); } static void @@ -993,7 +966,7 @@ get_gtk_surface (struct wl_client *client, { wl_resource_post_error (surface_resource, WL_DISPLAY_ERROR_INVALID_OBJECT, - "wl_shell::get_gtk_surface already requested"); + "gtk_shell::get_gtk_surface already requested"); return; } @@ -1028,10 +1001,10 @@ void meta_wayland_init_shell (MetaWaylandCompositor *compositor) { if (wl_global_create (compositor->wayland_display, - &wl_shell_interface, - META_WL_SHELL_VERSION, - compositor, bind_shell) == NULL) - g_error ("Failed to register a global shell object"); + &xdg_shell_interface, + META_XDG_SHELL_VERSION, + compositor, bind_xdg_shell) == NULL) + g_error ("Failed to register a global xdg-shell object"); if (wl_global_create (compositor->wayland_display, >k_shell_interface, @@ -1072,7 +1045,7 @@ meta_wayland_surface_set_initial_state (MetaWaylandSurface *surface, window->showing_for_first_time = FALSE; window->placed = TRUE; if (!meta_wayland_pointer_start_popup_grab (&seat->pointer, surface)) - wl_shell_surface_send_popup_done (surface->shell_surface->resource); + xdg_popup_send_popup_done (surface->xdg_surface->resource); break; default: g_assert_not_reached (); @@ -1098,8 +1071,8 @@ meta_wayland_surface_set_initial_state (MetaWaylandSurface *surface, if (initial->title) meta_window_set_title (window, initial->title); - if (initial->wm_class) - meta_window_set_wm_class (window, initial->wm_class, initial->wm_class); + if (initial->app_id) + meta_window_set_wm_class (window, initial->app_id, initial->app_id); meta_window_set_gtk_dbus_properties (window, initial->gtk_application_id, @@ -1128,7 +1101,7 @@ static void free_initial_state (MetaWaylandSurfaceInitialState *initial) { g_free (initial->title); - g_free (initial->wm_class); + g_free (initial->app_id); g_free (initial->gtk_application_id); g_free (initial->gtk_unique_bus_name); @@ -1146,7 +1119,9 @@ meta_wayland_surface_configure_notify (MetaWaylandSurface *surface, int new_height, int edges) { - if (surface->shell_surface) - wl_shell_surface_send_configure (surface->shell_surface->resource, - edges, new_width, new_height); + if (surface->xdg_surface) + xdg_surface_send_configure (surface->xdg_surface->resource, + edges, new_width, new_height, + 0, 0 /* XXX: support this */); } + diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h index 1a1b3adc5..35348fe28 100644 --- a/src/wayland/meta-wayland-surface.h +++ b/src/wayland/meta-wayland-surface.h @@ -80,7 +80,7 @@ typedef struct int x, y; char *title; - char *wm_class; + char *app_id; char *gtk_application_id; char *gtk_unique_bus_name; @@ -103,7 +103,7 @@ struct _MetaWaylandSurface MetaWaylandCompositor *compositor; MetaWaylandBufferReference buffer_ref; MetaWindow *window; - MetaWaylandSurfaceExtension *shell_surface; + MetaWaylandSurfaceExtension *xdg_surface; MetaWaylandSurfaceExtension *gtk_surface; /* All the pending state, that wl_surface.commit will apply. */ diff --git a/src/wayland/meta-wayland-versions.h b/src/wayland/meta-wayland-versions.h index 1cb569b44..37aa4e3ca 100644 --- a/src/wayland/meta-wayland-versions.h +++ b/src/wayland/meta-wayland-versions.h @@ -37,23 +37,23 @@ /* Global/master objects (version exported by wl_registry and negotiated through bind) */ #define META_WL_COMPOSITOR_VERSION 3 #define META_WL_DATA_DEVICE_MANAGER_VERSION 1 -#define META_WL_SHELL_VERSION 1 #define META_WL_SEAT_VERSION 2 /* 3 not implemented yet */ #define META_WL_OUTPUT_VERSION 2 #define META_XSERVER_VERSION 1 #define META_GTK_SHELL_VERSION 1 +#define META_XDG_SHELL_VERSION 1 /* Slave objects (version inherited from a master object) */ #define META_WL_DATA_OFFER_VERSION 1 /* from wl_data_device */ #define META_WL_DATA_SOURCE_VERSION 1 /* from wl_data_device */ #define META_WL_DATA_DEVICE_VERSION 1 /* from wl_data_device_manager */ -#define META_WL_SHELL_SURFACE_VERSION 1 /* from wl_shell */ #define META_WL_SURFACE_VERSION 3 /* from wl_compositor */ #define META_WL_POINTER_VERSION 2 /* from wl_seat; 3 not implemented yet */ #define META_WL_KEYBOARD_VERSION 2 /* from wl_seat; 3 not implemented yet */ #define META_WL_TOUCH_VERSION 0 /* from wl_seat; wl_touch not supported */ #define META_WL_REGION_VERSION 1 /* from wl_compositor */ #define META_GTK_SURFACE_VERSION 1 /* from gtk_shell */ +#define META_XDG_SURFACE_VERSION 1 /* from xdg_shell */ /* The first version to implement a specific event */ #define META_WL_SEAT_HAS_NAME 2 From 7186841db0406d2e33b8dfffb51de8e40269e320 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 11 Nov 2013 17:35:56 -0500 Subject: [PATCH 190/889] wayland-surface: Remove initial_state Just put everything in the double buffered state so it all arrives at the same time; on commit. --- src/core/window.c | 2 - src/wayland/meta-wayland-surface.c | 233 ++++++++--------------------- src/wayland/meta-wayland-surface.h | 25 +--- 3 files changed, 65 insertions(+), 195 deletions(-) diff --git a/src/core/window.c b/src/core/window.c index a7517ccac..97b41bad5 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -1064,8 +1064,6 @@ meta_window_new_shared (MetaDisplay *display, if (client_type == META_WINDOW_CLIENT_TYPE_X11) meta_window_load_initial_properties (window); - else - meta_wayland_surface_set_initial_state (window->surface, window); if (window->override_redirect) { diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 0a9ebf866..3d37c3a42 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -59,9 +59,6 @@ #include "meta-weston-launch.h" #include "monitor-private.h" -static void ensure_initial_state (MetaWaylandSurface *surface); -static void free_initial_state (MetaWaylandSurfaceInitialState *surface); - static void surface_process_damage (MetaWaylandSurface *surface, cairo_region_t *region) @@ -239,6 +236,30 @@ empty_region (cairo_region_t *region) cairo_region_intersect_rectangle (region, &rectangle); } +static gboolean +surface_wants_window (MetaWaylandSurface *surface) +{ + return (surface->xdg_surface != NULL); +} + +static void +surface_ensure_window (MetaWaylandSurface *surface) +{ + MetaDisplay *display = meta_get_display (); + int width, height; + + if (surface->window) + return; + + if (!surface_wants_window (surface)) + return; + + width = surface->buffer_ref.buffer->width; + height = surface->buffer_ref.buffer->height; + + surface->window = meta_window_new_for_wayland (display, width, height, surface); +} + static void meta_wayland_surface_commit (struct wl_client *client, struct wl_resource *resource) @@ -290,18 +311,7 @@ meta_wayland_surface_commit (struct wl_client *client, return; } - if (surface->initial_state) - { - MetaDisplay *display = meta_get_display (); - int width; - int height; - - width = surface->buffer_ref.buffer->width; - height = surface->buffer_ref.buffer->height; - - /* This will free and clear initial_state */ - surface->window = meta_window_new_for_wayland (display, width, height, surface); - } + surface_ensure_window (surface); if (surface == compositor->seat->sprite) meta_wayland_seat_update_sprite (compositor->seat); @@ -336,6 +346,27 @@ meta_wayland_surface_commit (struct wl_client *client, meta_window_set_opaque_region (surface->window, surface->pending.opaque_region); meta_window_set_input_region (surface->window, surface->pending.input_region); surface_process_damage (surface, surface->pending.damage); + + meta_window_set_title (surface->window, surface->pending.title); + g_clear_pointer (&surface->pending.title, g_free); + + meta_window_set_wm_class (surface->window, surface->pending.app_id, surface->pending.app_id); + g_clear_pointer (&surface->pending.app_id, g_free); + + meta_window_set_gtk_dbus_properties (surface->window, + surface->pending.gtk_application_id, + surface->pending.gtk_unique_bus_name, + surface->pending.gtk_app_menu_path, + surface->pending.gtk_menubar_path, + surface->pending.gtk_application_object_path, + surface->pending.gtk_window_object_path); + + g_clear_pointer (&surface->pending.gtk_application_id, g_free); + g_clear_pointer (&surface->pending.gtk_unique_bus_name, g_free); + g_clear_pointer (&surface->pending.gtk_app_menu_path, g_free); + g_clear_pointer (&surface->pending.gtk_menubar_path, g_free); + g_clear_pointer (&surface->pending.gtk_application_object_path, g_free); + g_clear_pointer (&surface->pending.gtk_window_object_path, g_free); } if (surface->pending.buffer) @@ -390,9 +421,6 @@ meta_wayland_surface_free (MetaWaylandSurface *surface) MetaWaylandCompositor *compositor = surface->compositor; MetaWaylandFrameCallback *cb, *next; - if (surface->initial_state) - free_initial_state (surface->initial_state); - compositor->surfaces = g_list_remove (compositor->surfaces, surface); meta_wayland_buffer_reference (&surface->buffer_ref, NULL); @@ -522,15 +550,8 @@ xdg_surface_set_title (struct wl_client *client, MetaWaylandSurfaceExtension *extension = wl_resource_get_user_data (resource); MetaWaylandSurface *surface = extension->surface; - if (surface->window) - meta_window_set_title (surface->window, title); - else - { - ensure_initial_state (surface); - - g_free (surface->initial_state->title); - surface->initial_state->title = g_strdup (title); - } + g_clear_pointer (&surface->pending.title, g_free); + surface->pending.title = g_strdup (title); } static void @@ -541,15 +562,8 @@ xdg_surface_set_app_id (struct wl_client *client, MetaWaylandSurfaceExtension *extension = wl_resource_get_user_data (resource); MetaWaylandSurface *surface = extension->surface; - if (surface->window) - meta_window_set_wm_class (surface->window, app_id, app_id); - else - { - ensure_initial_state (surface); - - g_free (surface->initial_state->app_id); - surface->initial_state->app_id = g_strdup (app_id); - } + g_clear_pointer (&surface->pending.app_id, g_free); + surface->pending.app_id = g_strdup (app_id); } static void @@ -912,41 +926,18 @@ set_dbus_properties (struct wl_client *client, return; } - if (surface->window) - { - meta_window_set_gtk_dbus_properties (surface->window, - application_id, - unique_bus_name, - app_menu_path, - menubar_path, - application_object_path, - window_object_path); - } - else - { - MetaWaylandSurfaceInitialState *initial; - - ensure_initial_state (surface); - initial = surface->initial_state; - - g_free (initial->gtk_application_id); - initial->gtk_application_id = g_strdup (application_id); - - g_free (initial->gtk_unique_bus_name); - initial->gtk_unique_bus_name = g_strdup (unique_bus_name); - - g_free (initial->gtk_app_menu_path); - initial->gtk_app_menu_path = g_strdup (app_menu_path); - - g_free (initial->gtk_menubar_path); - initial->gtk_menubar_path = g_strdup (menubar_path); - - g_free (initial->gtk_application_object_path); - initial->gtk_application_object_path = g_strdup (application_object_path); - - g_free (initial->gtk_window_object_path); - initial->gtk_window_object_path = g_strdup (window_object_path); - } + g_clear_pointer (&surface->pending.gtk_application_id, g_free); + surface->pending.gtk_application_id = g_strdup (application_id); + g_clear_pointer (&surface->pending.gtk_unique_bus_name, g_free); + surface->pending.gtk_unique_bus_name = g_strdup (unique_bus_name); + g_clear_pointer (&surface->pending.gtk_app_menu_path, g_free); + surface->pending.gtk_app_menu_path = g_strdup (app_menu_path); + g_clear_pointer (&surface->pending.gtk_menubar_path, g_free); + surface->pending.gtk_menubar_path = g_strdup (menubar_path); + g_clear_pointer (&surface->pending.gtk_application_object_path, g_free); + surface->pending.gtk_application_object_path = g_strdup (application_object_path); + g_clear_pointer (&surface->pending.gtk_window_object_path, g_free); + surface->pending.gtk_window_object_path = g_strdup (window_object_path); } static const struct gtk_surface_interface meta_wayland_gtk_surface_interface = @@ -1013,106 +1004,6 @@ meta_wayland_init_shell (MetaWaylandCompositor *compositor) g_error ("Failed to register a global gtk-shell object"); } -void -meta_wayland_surface_set_initial_state (MetaWaylandSurface *surface, - MetaWindow *window) -{ - MetaWaylandSurfaceInitialState *initial = surface->initial_state; - MetaWaylandCompositor *compositor = surface->compositor; - MetaWaylandSeat *seat = compositor->seat; - - if (initial == NULL) - return; - - window->type = META_WINDOW_NORMAL; - - /* Note that we poke at the bits directly here, because we're - in the middle of meta_window_new_shared() */ - switch (initial->initial_type) - { - case META_WAYLAND_SURFACE_TOPLEVEL: - break; - case META_WAYLAND_SURFACE_FULLSCREEN: - window->fullscreen = TRUE; - break; - case META_WAYLAND_SURFACE_MAXIMIZED: - window->maximized_horizontally = window->maximized_vertically = TRUE; - break; - case META_WAYLAND_SURFACE_POPUP: - window->override_redirect = TRUE; - window->type = META_WINDOW_DROPDOWN_MENU; - window->mapped = TRUE; - window->showing_for_first_time = FALSE; - window->placed = TRUE; - if (!meta_wayland_pointer_start_popup_grab (&seat->pointer, surface)) - xdg_popup_send_popup_done (surface->xdg_surface->resource); - break; - default: - g_assert_not_reached (); - } - - if (initial->transient_for) - { - MetaWaylandSurface *parent = wl_resource_get_user_data (initial->transient_for); - if (parent && parent->window) - { - window->transient_for = g_object_ref (parent->window); - - if (initial->initial_type == META_WAYLAND_SURFACE_POPUP) - { - window->rect.x = parent->window->rect.x + initial->x; - window->rect.y = parent->window->rect.y + initial->y; - } - } - - window->type = META_WINDOW_DIALOG; - } - - if (initial->title) - meta_window_set_title (window, initial->title); - - if (initial->app_id) - meta_window_set_wm_class (window, initial->app_id, initial->app_id); - - meta_window_set_gtk_dbus_properties (window, - initial->gtk_application_id, - initial->gtk_unique_bus_name, - initial->gtk_app_menu_path, - initial->gtk_menubar_path, - initial->gtk_application_object_path, - initial->gtk_window_object_path); - - meta_window_type_changed (window); - - free_initial_state (initial); - surface->initial_state = NULL; -} - -static void -ensure_initial_state (MetaWaylandSurface *surface) -{ - if (surface->initial_state) - return; - - surface->initial_state = g_slice_new0 (MetaWaylandSurfaceInitialState); -} - -static void -free_initial_state (MetaWaylandSurfaceInitialState *initial) -{ - g_free (initial->title); - g_free (initial->app_id); - - g_free (initial->gtk_application_id); - g_free (initial->gtk_unique_bus_name); - g_free (initial->gtk_app_menu_path); - g_free (initial->gtk_menubar_path); - g_free (initial->gtk_application_object_path); - g_free (initial->gtk_window_object_path); - - g_slice_free (MetaWaylandSurfaceInitialState, initial); -} - void meta_wayland_surface_configure_notify (MetaWaylandSurface *surface, int new_width, diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h index 35348fe28..0287f3ec5 100644 --- a/src/wayland/meta-wayland-surface.h +++ b/src/wayland/meta-wayland-surface.h @@ -64,31 +64,19 @@ typedef struct /* wl_surface.frame */ struct wl_list frame_callback_list; -} MetaWaylandDoubleBufferedState; - -typedef enum { - META_WAYLAND_SURFACE_TOPLEVEL = 0, - META_WAYLAND_SURFACE_MAXIMIZED, - META_WAYLAND_SURFACE_FULLSCREEN, - META_WAYLAND_SURFACE_POPUP, -} MetaWaylandSurfaceType; - -typedef struct -{ - MetaWaylandSurfaceType initial_type; - struct wl_resource *transient_for; - int x, y; + /* xdg_surface */ char *title; char *app_id; + /* gtk_surface */ char *gtk_application_id; char *gtk_unique_bus_name; char *gtk_app_menu_path; char *gtk_menubar_path; char *gtk_application_object_path; char *gtk_window_object_path; -} MetaWaylandSurfaceInitialState; +} MetaWaylandDoubleBufferedState; typedef struct { @@ -108,10 +96,6 @@ struct _MetaWaylandSurface /* All the pending state, that wl_surface.commit will apply. */ MetaWaylandDoubleBufferedState pending; - - /* All the initial state, that wl_shell_surface.set_* will apply - (through meta_window_new_for_wayland) */ - MetaWaylandSurfaceInitialState *initial_state; }; void meta_wayland_init_shell (MetaWaylandCompositor *compositor); @@ -122,9 +106,6 @@ MetaWaylandSurface *meta_wayland_surface_create (MetaWaylandCompositor *composit guint32 version); void meta_wayland_surface_free (MetaWaylandSurface *surface); -void meta_wayland_surface_set_initial_state (MetaWaylandSurface *surface, - MetaWindow *window); - void meta_wayland_surface_configure_notify (MetaWaylandSurface *surface, int width, int height, From 72a900787f93cae5d153fb416c0fed3428b8bdc9 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 12 Nov 2013 15:52:03 -0500 Subject: [PATCH 191/889] wayland: Send xdg_surface_focused_set / xdg_surface_focused_unset --- src/wayland/meta-wayland-keyboard.c | 4 ++++ src/wayland/meta-wayland-surface.c | 13 +++++++++++++ src/wayland/meta-wayland-surface.h | 3 +++ 3 files changed, 20 insertions(+) diff --git a/src/wayland/meta-wayland-keyboard.c b/src/wayland/meta-wayland-keyboard.c index 944a2fbad..6e24e3656 100644 --- a/src/wayland/meta-wayland-keyboard.c +++ b/src/wayland/meta-wayland-keyboard.c @@ -498,6 +498,8 @@ meta_wayland_keyboard_set_focus (MetaWaylandKeyboard *keyboard, serial = wl_display_next_serial (display); wl_keyboard_send_leave (resource, serial, keyboard->focus->resource); wl_list_remove (&keyboard->focus_listener.link); + + meta_wayland_surface_focused_unset (keyboard->focus); } resource = find_resource_for_surface (&keyboard->resource_list, surface); @@ -534,6 +536,8 @@ meta_wayland_keyboard_set_focus (MetaWaylandKeyboard *keyboard, } wl_resource_add_destroy_listener (resource, &keyboard->focus_listener); keyboard->focus_serial = serial; + + meta_wayland_surface_focused_set (keyboard->focus); } keyboard->focus_resource = resource; diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 3d37c3a42..a754ea058 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -1016,3 +1016,16 @@ meta_wayland_surface_configure_notify (MetaWaylandSurface *surface, 0, 0 /* XXX: support this */); } +void +meta_wayland_surface_focused_set (MetaWaylandSurface *surface) +{ + if (surface->xdg_surface) + xdg_surface_send_focused_set (surface->xdg_surface->resource); +} + +void +meta_wayland_surface_focused_unset (MetaWaylandSurface *surface) +{ + if (surface->xdg_surface) + xdg_surface_send_focused_unset (surface->xdg_surface->resource); +} diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h index 0287f3ec5..a2fd75e77 100644 --- a/src/wayland/meta-wayland-surface.h +++ b/src/wayland/meta-wayland-surface.h @@ -111,4 +111,7 @@ void meta_wayland_surface_configure_notify (MetaWaylandSurface *s int height, int edges); +void meta_wayland_surface_focused_set (MetaWaylandSurface *surface); +void meta_wayland_surface_focused_unset (MetaWaylandSurface *surface); + #endif From 93ae868987edc6f73dc07bc7e2d6721a653bd1e3 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Wed, 4 Sep 2013 11:11:39 +0200 Subject: [PATCH 192/889] wayland: sync the keymap from X to wayland When X clients change the keyboard map, the also update a property on the root window. We can notice that and rebuild our data structures with the new values, as well as inform the wayland clients. This is a terrible hack, and it's not how we want to implement things in 3.12, but it's enough to have the same keyboard layout in the shell, in X clients and in wayland clients in 3.10, until we decide on the fate of the keyboard g-s-d plugin. https://bugzilla.gnome.org/show_bug.cgi?id=707446 --- src/core/display.c | 38 +++++++ src/core/xprops.c | 75 ++++++++++++++ src/core/xprops.h | 5 + src/meta/atomnames.h | 1 + src/wayland/meta-wayland-keyboard.c | 147 ++++++++++++++++++---------- src/wayland/meta-wayland-keyboard.h | 13 ++- 6 files changed, 226 insertions(+), 53 deletions(-) diff --git a/src/core/display.c b/src/core/display.c index 14ee96ef9..74193f492 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -2191,6 +2191,40 @@ handle_window_focus_event (MetaDisplay *display, } } +static void +reload_xkb_rules (MetaScreen *screen) +{ + MetaWaylandCompositor *compositor; + char **names; + int n_names; + gboolean ok; + const char *rules, *model, *layout, *variant, *options; + + compositor = meta_wayland_compositor_get_default (); + + ok = meta_prop_get_latin1_list (screen->display, screen->xroot, + screen->display->atom__XKB_RULES_NAMES, + &names, &n_names); + if (!ok) + return; + + if (n_names != 5) + goto out; + + rules = names[0]; + model = names[1]; + layout = names[2]; + variant = names[3]; + options = names[4]; + + meta_wayland_keyboard_set_keymap_names (&compositor->seat->keyboard, + rules, model, layout, variant, options, + META_WAYLAND_KEYBOARD_SKIP_XCLIENTS); + + out: + g_strfreev (names); +} + /** * meta_display_handle_event: * @display: The MetaDisplay that events are coming from @@ -2964,6 +2998,10 @@ meta_display_handle_event (MetaDisplay *display, else if (event->xproperty.atom == display->atom__NET_DESKTOP_NAMES) meta_screen_update_workspace_names (screen); + else if (meta_is_wayland_compositor () && + event->xproperty.atom == + display->atom__XKB_RULES_NAMES) + reload_xkb_rules (screen); #if 0 else if (event->xproperty.atom == display->atom__NET_RESTACK_WINDOW) diff --git a/src/core/xprops.c b/src/core/xprops.c index 844824f81..040581c53 100644 --- a/src/core/xprops.c +++ b/src/core/xprops.c @@ -536,6 +536,81 @@ meta_prop_get_utf8_list (MetaDisplay *display, return utf8_list_from_results (&results, str_p, n_str_p); } +/* this one freakishly returns g_malloc memory */ +static gboolean +latin1_list_from_results (GetPropertyResults *results, + char ***str_p, + int *n_str_p) +{ + int i; + int n_strings; + char **retval; + const char *p; + + *str_p = NULL; + *n_str_p = 0; + + if (!validate_or_free_results (results, 8, XA_STRING, FALSE)) + return FALSE; + + /* I'm not sure this is right, but I'm guessing the + * property is nul-separated + */ + i = 0; + n_strings = 0; + while (i < (int) results->n_items) + { + if (results->prop[i] == '\0') + ++n_strings; + ++i; + } + + if (results->prop[results->n_items - 1] != '\0') + ++n_strings; + + /* we're guaranteed that results->prop has a nul on the end + * by XGetWindowProperty + */ + + retval = g_new0 (char*, n_strings + 1); + + p = (char *)results->prop; + i = 0; + while (i < n_strings) + { + retval[i] = g_strdup (p); + + p = p + strlen (p) + 1; + ++i; + } + + *str_p = retval; + *n_str_p = i; + + meta_XFree (results->prop); + results->prop = NULL; + + return TRUE; +} + +gboolean +meta_prop_get_latin1_list (MetaDisplay *display, + Window xwindow, + Atom xatom, + char ***str_p, + int *n_str_p) +{ + GetPropertyResults results; + + *str_p = NULL; + + if (!get_property (display, xwindow, xatom, + XA_STRING, &results)) + return FALSE; + + return latin1_list_from_results (&results, str_p, n_str_p); +} + void meta_prop_set_utf8_string_hint (MetaDisplay *display, Window xwindow, diff --git a/src/core/xprops.h b/src/core/xprops.h index 5a799f80c..a5c4fb9a3 100644 --- a/src/core/xprops.h +++ b/src/core/xprops.h @@ -102,6 +102,11 @@ gboolean meta_prop_get_utf8_list (MetaDisplay *display, Atom xatom, char ***str_p, int *n_str_p); +gboolean meta_prop_get_latin1_list (MetaDisplay *display, + Window xwindow, + Atom xatom, + char ***str_p, + int *n_str_p); void meta_prop_set_utf8_string_hint (MetaDisplay *display, Window xwindow, diff --git a/src/meta/atomnames.h b/src/meta/atomnames.h index d7a6e7e35..43a18a9c9 100644 --- a/src/meta/atomnames.h +++ b/src/meta/atomnames.h @@ -81,6 +81,7 @@ item(TIMESTAMP) item(VERSION) item(ATOM_PAIR) item(BACKLIGHT) +item(_XKB_RULES_NAMES) /* Oddities: These are used, and we need atoms for them, * but when we need all _NET_WM hints (i.e. when we're making diff --git a/src/wayland/meta-wayland-keyboard.c b/src/wayland/meta-wayland-keyboard.c index 6e24e3656..05db151ef 100644 --- a/src/wayland/meta-wayland-keyboard.c +++ b/src/wayland/meta-wayland-keyboard.c @@ -106,11 +106,49 @@ create_anonymous_file (off_t size, return -1; } -static gboolean -meta_wayland_xkb_info_new_keymap (MetaWaylandXkbInfo *xkb_info) +static void +inform_clients_of_new_keymap (MetaWaylandKeyboard *keyboard, + int flags) { + MetaWaylandCompositor *compositor; + struct wl_client *xclient; + struct wl_resource *keyboard_resource; + + compositor = meta_wayland_compositor_get_default (); + xclient = compositor->xwayland_client; + + wl_resource_for_each (keyboard_resource, &keyboard->resource_list) + { + if ((flags & META_WAYLAND_KEYBOARD_SKIP_XCLIENTS) && + wl_resource_get_client (keyboard_resource) == xclient) + continue; + + wl_keyboard_send_keymap (keyboard_resource, + WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, + keyboard->xkb_info.keymap_fd, + keyboard->xkb_info.keymap_size); + } +} + +static void +meta_wayland_keyboard_take_keymap (MetaWaylandKeyboard *keyboard, + struct xkb_keymap *keymap, + int flags) +{ + MetaWaylandXkbInfo *xkb_info = &keyboard->xkb_info; GError *error = NULL; char *keymap_str; + size_t previous_size; + + if (keymap == NULL) + { + g_warning ("Attempting to set null keymap (compilation probably failed)"); + return; + } + + if (xkb_info->keymap) + xkb_keymap_unref (xkb_info->keymap); + xkb_info->keymap = keymap; xkb_info->shift_mod = xkb_map_mod_get_index (xkb_info->keymap, XKB_MOD_NAME_SHIFT); @@ -129,21 +167,28 @@ meta_wayland_xkb_info_new_keymap (MetaWaylandXkbInfo *xkb_info) keymap_str = xkb_map_get_as_string (xkb_info->keymap); if (keymap_str == NULL) { - g_warning ("failed to get string version of keymap\n"); - return FALSE; + g_warning ("failed to get string version of keymap"); + return; } + previous_size = xkb_info->keymap_size; xkb_info->keymap_size = strlen (keymap_str) + 1; + if (xkb_info->keymap_fd >= 0) + close (xkb_info->keymap_fd); + xkb_info->keymap_fd = create_anonymous_file (xkb_info->keymap_size, &error); if (xkb_info->keymap_fd < 0) { - g_warning ("creating a keymap file for %lu bytes failed: %s\n", + g_warning ("creating a keymap file for %lu bytes failed: %s", (unsigned long) xkb_info->keymap_size, error->message); g_clear_error (&error); goto err_keymap_str; } + if (xkb_info->keymap_area) + munmap (xkb_info->keymap_area, previous_size); + xkb_info->keymap_area = mmap (NULL, xkb_info->keymap_size, PROT_READ | PROT_WRITE, MAP_SHARED, xkb_info->keymap_fd, 0); @@ -156,41 +201,24 @@ meta_wayland_xkb_info_new_keymap (MetaWaylandXkbInfo *xkb_info) strcpy (xkb_info->keymap_area, keymap_str); free (keymap_str); - return TRUE; + if (keyboard->is_evdev) + { + ClutterDeviceManager *manager; + + manager = clutter_device_manager_get_default (); + clutter_evdev_set_keyboard_map (manager, xkb_info->keymap); + } + + inform_clients_of_new_keymap (keyboard, flags); + + return; err_dev_zero: close (xkb_info->keymap_fd); xkb_info->keymap_fd = -1; err_keymap_str: free (keymap_str); - return FALSE; -} - -static gboolean -meta_wayland_keyboard_build_global_keymap (struct xkb_context *xkb_context, - struct xkb_rule_names *xkb_names, - MetaWaylandXkbInfo *xkb_info) -{ - xkb_info->keymap = xkb_map_new_from_names (xkb_context, - xkb_names, - 0 /* flags */); - if (xkb_info->keymap == NULL) - { - g_warning ("failed to compile global XKB keymap\n" - " tried rules %s, model %s, layout %s, variant %s, " - "options %s\n", - xkb_names->rules, - xkb_names->model, - xkb_names->layout, - xkb_names->variant, - xkb_names->options); - return FALSE; - } - - if (!meta_wayland_xkb_info_new_keymap (xkb_info)) - return FALSE; - - return TRUE; + return; } static void @@ -306,9 +334,8 @@ meta_wayland_keyboard_init (MetaWaylandKeyboard *keyboard, struct wl_display *display, gboolean is_evdev) { - ClutterDeviceManager *manager; - memset (keyboard, 0, sizeof *keyboard); + keyboard->xkb_info.keymap_fd = -1; wl_list_init (&keyboard->resource_list); wl_array_init (&keyboard->keys); @@ -320,18 +347,15 @@ meta_wayland_keyboard_init (MetaWaylandKeyboard *keyboard, keyboard->display = display; keyboard->xkb_context = xkb_context_new (0 /* flags */); - - meta_wayland_keyboard_build_global_keymap (keyboard->xkb_context, - &keyboard->xkb_names, - &keyboard->xkb_info); - keyboard->is_evdev = is_evdev; - if (is_evdev) - { - manager = clutter_device_manager_get_default (); - clutter_evdev_set_keyboard_map (manager, keyboard->xkb_info.keymap); - } + /* Compute a default until gnome-settings-daemon starts and sets + the appropriate values + */ + meta_wayland_keyboard_set_keymap_names (keyboard, + "evdev", + "pc105", + "us", "", "", 0); return TRUE; } @@ -563,12 +587,6 @@ meta_wayland_keyboard_end_grab (MetaWaylandKeyboard *keyboard) void meta_wayland_keyboard_release (MetaWaylandKeyboard *keyboard) { - g_free ((char *) keyboard->xkb_names.rules); - g_free ((char *) keyboard->xkb_names.model); - g_free ((char *) keyboard->xkb_names.layout); - g_free ((char *) keyboard->xkb_names.variant); - g_free ((char *) keyboard->xkb_names.options); - meta_wayland_xkb_info_destroy (&keyboard->xkb_info); xkb_context_unref (keyboard->xkb_context); @@ -656,3 +674,28 @@ meta_wayland_keyboard_end_modal (MetaWaylandKeyboard *keyboard, meta_verbose ("Released modal keyboard grab, timestamp %d\n", timestamp); } + +void +meta_wayland_keyboard_set_keymap_names (MetaWaylandKeyboard *keyboard, + const char *rules, + const char *model, + const char *layout, + const char *variant, + const char *options, + int flags) +{ + struct xkb_rule_names xkb_names; + + xkb_names.rules = rules; + xkb_names.model = model; + xkb_names.layout = layout; + xkb_names.variant = variant; + xkb_names.options = options; + + meta_wayland_keyboard_take_keymap (keyboard, + xkb_keymap_new_from_names (keyboard->xkb_context, + &xkb_names, + 0 /* flags */), + flags); +} + diff --git a/src/wayland/meta-wayland-keyboard.h b/src/wayland/meta-wayland-keyboard.h index adb3d4428..4354faf21 100644 --- a/src/wayland/meta-wayland-keyboard.h +++ b/src/wayland/meta-wayland-keyboard.h @@ -112,7 +112,6 @@ struct _MetaWaylandKeyboard struct xkb_context *xkb_context; gboolean is_evdev; MetaWaylandXkbInfo xkb_info; - struct xkb_rule_names xkb_names; MetaWaylandKeyboardGrab input_method_grab; struct wl_resource *input_method_resource; @@ -123,6 +122,18 @@ meta_wayland_keyboard_init (MetaWaylandKeyboard *keyboard, struct wl_display *display, gboolean is_evdev); +typedef enum { + META_WAYLAND_KEYBOARD_SKIP_XCLIENTS = 1, +} MetaWaylandKeyboardSetKeymapFlags; + +void +meta_wayland_keyboard_set_keymap_names (MetaWaylandKeyboard *keyboard, + const char *rules, + const char *model, + const char *layout, + const char *variant, + const char *options, + int flags); gboolean meta_wayland_keyboard_handle_event (MetaWaylandKeyboard *keyboard, const ClutterKeyEvent *event); From 429583ae8bb8ff674fcdf81e306a5817fcc5a77a Mon Sep 17 00:00:00 2001 From: Neil Roberts Date: Thu, 29 Aug 2013 14:07:50 +0100 Subject: [PATCH 193/889] display: Rename meta_display_handle_event to meta_display_handle_xevent The plan is to make a new version of meta_display_handle_event that will accept Clutter events instead of X events and then gradually move over the events to the new function and finally remove the X version. --- src/core/display-private.h | 4 ++-- src/core/display.c | 8 ++++---- src/wayland/meta-wayland.c | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/core/display-private.h b/src/core/display-private.h index 53f8a6f07..d3427f865 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -482,8 +482,8 @@ gboolean meta_display_modifiers_accelerator_activate (MetaDisplay *display); /* In above-tab-keycode.c */ guint meta_display_get_above_tab_keycode (MetaDisplay *display); -gboolean meta_display_handle_event (MetaDisplay *display, - XEvent *event); +gboolean meta_display_handle_xevent (MetaDisplay *display, + XEvent *event); #ifdef HAVE_XI23 gboolean meta_display_process_barrier_event (MetaDisplay *display, diff --git a/src/core/display.c b/src/core/display.c index 74193f492..66ab0684c 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -2226,7 +2226,7 @@ reload_xkb_rules (MetaScreen *screen) } /** - * meta_display_handle_event: + * meta_display_handle_xevent: * @display: The MetaDisplay that events are coming from * @event: The event that just happened * @@ -2239,8 +2239,8 @@ reload_xkb_rules (MetaScreen *screen) * dealing with all the kinds of events that might turn up. */ gboolean -meta_display_handle_event (MetaDisplay *display, - XEvent *event) +meta_display_handle_xevent (MetaDisplay *display, + XEvent *event) { MetaWindow *window; MetaWindow *property_for_window; @@ -3240,7 +3240,7 @@ event_callback (XEvent *event, event->xcookie.evtype == XI_Motion) return FALSE; - return meta_display_handle_event (display, event); + return meta_display_handle_xevent (display, event); } /* Return the window this has to do with, if any, rather diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index 13bbb9a43..6577923cc 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -643,7 +643,7 @@ synthesize_motion_event (MetaWaylandCompositor *compositor, device_event.valuators.mask = NULL; device_event.valuators.values = NULL; - meta_display_handle_event (display, (XEvent *) &generic_event); + meta_display_handle_xevent (display, (XEvent *) &generic_event); } static void From 64a848fcb7eee0272eb83dcfff7085666e1b579b Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 3 Oct 2013 16:12:34 -0400 Subject: [PATCH 194/889] display: Add a quick out path to handle_xevent This makes the code flow more like the scheme we usually use, and allows us to flatten out the method somewhat. --- src/core/display.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/core/display.c b/src/core/display.c index 66ab0684c..bd0e4ac3f 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -2261,16 +2261,20 @@ meta_display_handle_xevent (MetaDisplay *display, sn_display_process_event (display->sn_display, event); #endif + bypass_compositor = FALSE; + filter_out_event = FALSE; + /* Intercept XRandR events early and don't attempt any processing for them. We still let them through to Gdk though, so it can update its own internal state. */ monitor = meta_monitor_manager_get (); if (meta_monitor_manager_handle_xevent (monitor, event)) - return FALSE; - - bypass_compositor = FALSE; - filter_out_event = FALSE; + { + bypass_compositor = TRUE; + goto out; + } + display->current_time = event_get_time (display, event); display->monitor_cache_invalidated = TRUE; @@ -2291,7 +2295,10 @@ meta_display_handle_xevent (MetaDisplay *display, if (screen) { if (meta_screen_handle_xevent (screen, event)) - return TRUE; + { + bypass_compositor = filter_out_event = TRUE; + goto out; + } } modified = event_get_modified_window (display, event); @@ -2368,6 +2375,8 @@ meta_display_handle_xevent (MetaDisplay *display, } else meta_idle_monitor_handle_xevent_all (event); + + goto out; } #endif /* HAVE_XSYNC */ @@ -2393,6 +2402,8 @@ meta_display_handle_xevent (MetaDisplay *display, window ? window->desc : "(none)", frame_was_receiver); } + + goto out; } #endif /* HAVE_SHAPE */ @@ -3207,6 +3218,7 @@ meta_display_handle_xevent (MetaDisplay *display, } } + out: if (display->compositor && !bypass_compositor) { if (meta_compositor_process_event (display->compositor, From 84d26e31f16b7fe14fff5fef9c2eac1cfcd2a97f Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 3 Oct 2013 15:22:26 -0400 Subject: [PATCH 195/889] display: Move barrier event processing to barrier.c This puts all the code that's easily ported to Clutter events in one giant switch statement, as Clutter doesn't translate barrier events. --- src/core/barrier.c | 18 ++++++++++++++++-- src/core/display-private.h | 4 ++-- src/core/display.c | 15 ++++++++------- 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/core/barrier.c b/src/core/barrier.c index 643b26ed7..b869d2ef2 100644 --- a/src/core/barrier.c +++ b/src/core/barrier.c @@ -366,11 +366,25 @@ meta_barrier_fire_event (MetaBarrier *barrier, } gboolean -meta_display_process_barrier_event (MetaDisplay *display, - XIBarrierEvent *xev) +meta_display_process_barrier_event (MetaDisplay *display, + XIEvent *event) { MetaBarrier *barrier; + XIBarrierEvent *xev; + if (event == NULL) + return FALSE; + + switch (event->evtype) + { + case XI_BarrierHit: + case XI_BarrierLeave: + break; + default: + return FALSE; + } + + xev = (XIBarrierEvent *) event; barrier = g_hash_table_lookup (display->xids, &xev->barrier); if (barrier != NULL) { diff --git a/src/core/display-private.h b/src/core/display-private.h index d3427f865..eb7569d79 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -486,8 +486,8 @@ gboolean meta_display_handle_xevent (MetaDisplay *display, XEvent *event); #ifdef HAVE_XI23 -gboolean meta_display_process_barrier_event (MetaDisplay *display, - XIBarrierEvent *event); +gboolean meta_display_process_barrier_event (MetaDisplay *display, + XIEvent *event); #endif /* HAVE_XI23 */ void meta_display_set_input_focus_xwindow (MetaDisplay *display, diff --git a/src/core/display.c b/src/core/display.c index bd0e4ac3f..6ce4028d4 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -2407,6 +2407,14 @@ meta_display_handle_xevent (MetaDisplay *display, } #endif /* HAVE_SHAPE */ +#ifdef HAVE_XI23 + if (meta_display_process_barrier_event (display, input_event)) + { + filter_out_event = bypass_compositor = TRUE; + goto out; + } +#endif /* HAVE_XI23 */ + if (input_event != NULL) { XIDeviceEvent *device_event = (XIDeviceEvent *) input_event; @@ -2763,13 +2771,6 @@ meta_display_handle_xevent (MetaDisplay *display, } break; -#ifdef HAVE_XI23 - case XI_BarrierHit: - case XI_BarrierLeave: - if (meta_display_process_barrier_event (display, (XIBarrierEvent *) input_event)) - filter_out_event = bypass_compositor = TRUE; - break; -#endif /* HAVE_XI23 */ } } else From 9c0cc664d18fb1377333a0ddb231a9a705d9f37b Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 3 Oct 2013 16:56:24 -0400 Subject: [PATCH 196/889] display: Rename filter_out_event to bypass_gtk This clarifies the intent of the variable and makes it match bypass_compositor --- src/core/display.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/core/display.c b/src/core/display.c index 6ce4028d4..a781d186a 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -2246,8 +2246,7 @@ meta_display_handle_xevent (MetaDisplay *display, MetaWindow *property_for_window; Window modified; gboolean frame_was_receiver; - gboolean bypass_compositor; - gboolean filter_out_event; + gboolean bypass_compositor = FALSE, bypass_gtk = FALSE; XIEvent *input_event; MetaMonitorManager *monitor; MetaScreen *screen; @@ -2261,9 +2260,6 @@ meta_display_handle_xevent (MetaDisplay *display, sn_display_process_event (display->sn_display, event); #endif - bypass_compositor = FALSE; - filter_out_event = FALSE; - /* Intercept XRandR events early and don't attempt any processing for them. We still let them through to Gdk though, so it can update its own internal state. @@ -2296,7 +2292,7 @@ meta_display_handle_xevent (MetaDisplay *display, { if (meta_screen_handle_xevent (screen, event)) { - bypass_compositor = filter_out_event = TRUE; + bypass_gtk = bypass_compositor = TRUE; goto out; } } @@ -2371,7 +2367,7 @@ meta_display_handle_xevent (MetaDisplay *display, gint64 new_counter_value; new_counter_value = XSyncValueLow32 (value) + ((gint64)XSyncValueHigh32 (value) << 32); meta_window_update_sync_request_counter (alarm_window, new_counter_value); - filter_out_event = TRUE; /* GTK doesn't want to see this really */ + bypass_gtk = TRUE; /* GTK doesn't want to see this really */ } else meta_idle_monitor_handle_xevent_all (event); @@ -2384,7 +2380,7 @@ meta_display_handle_xevent (MetaDisplay *display, if (META_DISPLAY_HAS_SHAPE (display) && event->type == (display->shape_event_base + ShapeNotify)) { - filter_out_event = TRUE; /* GTK doesn't want to see this really */ + bypass_gtk = TRUE; /* GTK doesn't want to see this really */ if (window && !frame_was_receiver) { @@ -2410,7 +2406,7 @@ meta_display_handle_xevent (MetaDisplay *display, #ifdef HAVE_XI23 if (meta_display_process_barrier_event (display, input_event)) { - filter_out_event = bypass_compositor = TRUE; + bypass_gtk = bypass_compositor = TRUE; goto out; } #endif /* HAVE_XI23 */ @@ -2452,7 +2448,7 @@ meta_display_handle_xevent (MetaDisplay *display, * want to pass the key event to the compositor or GTK+ at all. */ if (meta_display_process_key_event (display, window, (XIDeviceEvent *) input_event)) - filter_out_event = bypass_compositor = TRUE; + bypass_gtk = bypass_compositor = TRUE; break; case XI_ButtonPress: if (display->grab_op == META_GRAB_OP_COMPOSITOR) @@ -3148,7 +3144,7 @@ meta_display_handle_xevent (MetaDisplay *display, * the GTK+ event loop because gtk+ will treat * them as ping requests and send more replies. */ - filter_out_event = TRUE; + bypass_gtk = TRUE; } } } @@ -3225,11 +3221,11 @@ meta_display_handle_xevent (MetaDisplay *display, if (meta_compositor_process_event (display->compositor, event, window)) - filter_out_event = TRUE; + bypass_gtk = TRUE; } display->current_time = CurrentTime; - return filter_out_event; + return bypass_gtk; } static gboolean From 58f6ab0a27bf4e568e26db5f77b7be1b8ed4bfd5 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 3 Oct 2013 15:23:24 -0400 Subject: [PATCH 197/889] display: Split out input event handling This helps with git's diff code by moving all the giant indentation changes, letting us know what's going on better when we move to Clutter for event handling. --- src/core/display.c | 785 +++++++++++++++++++++++---------------------- 1 file changed, 407 insertions(+), 378 deletions(-) diff --git a/src/core/display.c b/src/core/display.c index a781d186a..ce209b294 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -178,6 +178,8 @@ static gboolean event_callback (XEvent *event, gpointer data); static Window event_get_modified_window (MetaDisplay *display, XEvent *event); +static Window xievent_get_modified_window (MetaDisplay *display, + XIEvent *input_event); static guint32 event_get_time (MetaDisplay *display, XEvent *event); static void process_request_frame_extents (MetaDisplay *display, @@ -2191,6 +2193,376 @@ handle_window_focus_event (MetaDisplay *display, } } +static gboolean +handle_input_xevent (MetaDisplay *display, + XIEvent *input_event, + gulong serial) +{ + XIDeviceEvent *device_event = (XIDeviceEvent *) input_event; + XIEnterEvent *enter_event = (XIEnterEvent *) input_event; + Window modified; + MetaWindow *window; + gboolean frame_was_receiver; + + if (input_event == NULL) + return FALSE; + + modified = xievent_get_modified_window (display, input_event); + window = modified != None ? meta_display_lookup_x_window (display, modified) : NULL; + frame_was_receiver = (window && window->frame && modified == window->frame->xwindow); + + if (window && !window->override_redirect && + ((input_event->type == XI_KeyPress) || (input_event->type == XI_ButtonPress))) + { + if (CurrentTime == display->current_time) + { + /* We can't use missing (i.e. invalid) timestamps to set user time, + * nor do we want to use them to sanity check other timestamps. + * See bug 313490 for more details. + */ + meta_warning ("Event has no timestamp! You may be using a broken " + "program such as xse. Please ask the authors of that " + "program to fix it.\n"); + } + else + { + meta_window_set_user_time (window, display->current_time); + sanity_check_timestamps (display, display->current_time); + } + } + + switch (input_event->evtype) + { + case XI_KeyPress: + case XI_KeyRelease: + + /* For key events, it's important to enforce single-handling, or + * we can get into a confused state. So if a keybinding is + * handled (because it's one of our hot-keys, or because we are + * in a keyboard-grabbed mode like moving a window, we don't + * want to pass the key event to the compositor or GTK+ at all. + */ + if (meta_display_process_key_event (display, window, (XIDeviceEvent *) input_event)) + return TRUE; + break; + 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 ((window && + meta_grab_op_is_mouse (display->grab_op) && + (device_event->mods.effective & display->window_grab_modifiers) && + display->grab_button != device_event->detail && + display->grab_window == window) || + grab_op_is_keyboard (display->grab_op)) + { + meta_topic (META_DEBUG_WINDOW_OPS, + "Ending grab op %u on window %s due to button press\n", + display->grab_op, + (display->grab_window ? + display->grab_window->desc : + "none")); + if (GRAB_OP_IS_WINDOW_SWITCH (display->grab_op)) + { + MetaScreen *screen; + meta_topic (META_DEBUG_WINDOW_OPS, + "Syncing to old stack positions.\n"); + screen = + meta_display_screen_for_root (display, device_event->event); + + if (screen!=NULL) + meta_stack_set_positions (screen->stack, + display->grab_old_window_stacking); + } + meta_display_end_grab_op (display, + device_event->time); + } + else if (window && display->grab_op == META_GRAB_OP_NONE) + { + gboolean begin_move = FALSE; + unsigned int grab_mask; + gboolean unmodified; + + grab_mask = display->window_grab_modifiers; + if (g_getenv ("MUTTER_DEBUG_BUTTON_GRABS")) + grab_mask |= ControlMask; + + /* Two possible sources of an unmodified event; one is a + * client that's letting button presses pass through to the + * frame, the other is our focus_window_grab on unmodified + * button 1. So for all such events we focus the window. + */ + unmodified = (device_event->mods.effective & grab_mask) == 0; + + if (unmodified || + device_event->detail == 1) + { + /* don't focus if frame received, will be lowered in + * frames.c or special-cased if the click was on a + * minimize/close button. + */ + if (!frame_was_receiver) + { + if (meta_prefs_get_raise_on_click ()) + meta_window_raise (window); + else + meta_topic (META_DEBUG_FOCUS, + "Not raising window on click due to don't-raise-on-click option\n"); + + /* Don't focus panels--they must explicitly request focus. + * See bug 160470 + */ + if (window->type != META_WINDOW_DOCK) + { + meta_topic (META_DEBUG_FOCUS, + "Focusing %s due to unmodified button %u press (display.c)\n", + window->desc, device_event->detail); + meta_window_focus (window, device_event->time); + } + else + /* However, do allow terminals to lose focus due to new + * window mappings after the user clicks on a panel. + */ + display->allow_terminal_deactivation = TRUE; + } + + /* you can move on alt-click but not on + * the click-to-focus + */ + if (!unmodified) + begin_move = TRUE; + } + else if (!unmodified && device_event->detail == meta_prefs_get_mouse_button_resize()) + { + if (window->has_resize_func) + { + gboolean north, south; + gboolean west, east; + int root_x, root_y; + MetaGrabOp op; + + meta_window_get_position (window, &root_x, &root_y); + + west = device_event->root_x < (root_x + 1 * window->rect.width / 3); + east = device_event->root_x > (root_x + 2 * window->rect.width / 3); + north = device_event->root_y < (root_y + 1 * window->rect.height / 3); + south = device_event->root_y > (root_y + 2 * window->rect.height / 3); + + if (north && west) + op = META_GRAB_OP_RESIZING_NW; + else if (north && east) + op = META_GRAB_OP_RESIZING_NE; + else if (south && west) + op = META_GRAB_OP_RESIZING_SW; + else if (south && east) + op = META_GRAB_OP_RESIZING_SE; + else if (north) + op = META_GRAB_OP_RESIZING_N; + else if (west) + op = META_GRAB_OP_RESIZING_W; + else if (east) + op = META_GRAB_OP_RESIZING_E; + else if (south) + op = META_GRAB_OP_RESIZING_S; + else /* Middle region is no-op to avoid user triggering wrong action */ + op = META_GRAB_OP_NONE; + + if (op != META_GRAB_OP_NONE) + meta_display_begin_grab_op (display, + window->screen, + window, + op, + TRUE, + FALSE, + device_event->detail, + 0, + device_event->time, + device_event->root_x, + device_event->root_y); + } + } + else if (device_event->detail == 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, + device_event->time); + } + + if (!frame_was_receiver && unmodified) + { + /* This is from our synchronous grab since + * it has no modifiers and was on the client window + */ + + meta_verbose ("Allowing events time %u\n", + (unsigned int)device_event->time); + + XIAllowEvents (display->xdisplay, device_event->deviceid, + XIReplayDevice, device_event->time); + } + + if (begin_move && window->has_move_func) + { + meta_display_begin_grab_op (display, + window->screen, + window, + META_GRAB_OP_MOVING, + TRUE, + FALSE, + device_event->detail, + 0, + device_event->time, + device_event->root_x, + device_event->root_y); + } + } + break; + case XI_ButtonRelease: + if (display->grab_op == META_GRAB_OP_COMPOSITOR) + break; + + display->overlay_key_only_pressed = FALSE; + + if (display->grab_window == window && + meta_grab_op_is_mouse (display->grab_op)) + meta_window_handle_mouse_grab_op_event (window, device_event); + break; + case XI_Motion: + if (display->grab_op == META_GRAB_OP_COMPOSITOR) + break; + + if (display->grab_window == window && + meta_grab_op_is_mouse (display->grab_op)) + meta_window_handle_mouse_grab_op_event (window, device_event); + break; + case XI_Enter: + if (display->grab_op == META_GRAB_OP_COMPOSITOR) + break; + + /* If the mouse switches screens, active the default window on the new + * screen; this will make keybindings and workspace-launched items + * actually appear on the right screen. + */ + { + MetaScreen *new_screen = + meta_display_screen_for_root (display, enter_event->root); + + if (new_screen != NULL && display->active_screen != new_screen) + meta_workspace_focus_default_window (new_screen->active_workspace, + NULL, + enter_event->time); + } + + /* Check if we've entered a window; do this even if window->has_focus to + * avoid races. + */ + if (window && !crossing_serial_is_ignored (display, serial) && + enter_event->mode != XINotifyGrab && + enter_event->mode != XINotifyUngrab && + enter_event->detail != XINotifyInferior && + meta_display_focus_sentinel_clear (display)) + { + switch (meta_prefs_get_focus_mode ()) + { + case G_DESKTOP_FOCUS_MODE_SLOPPY: + case G_DESKTOP_FOCUS_MODE_MOUSE: + display->mouse_mode = TRUE; + if (window->type != META_WINDOW_DOCK) + { + meta_topic (META_DEBUG_FOCUS, + "Queuing a focus change for %s due to " + "enter notify with serial %lu at time %lu, " + "and setting display->mouse_mode to TRUE.\n", + window->desc, + serial, + enter_event->time); + + if (meta_prefs_get_focus_change_on_pointer_rest()) + meta_display_queue_focus_callback (display, window, + enter_event->root_x, + enter_event->root_y); + else + meta_display_mouse_mode_focus (display, window, + enter_event->time); + + /* stop ignoring stuff */ + reset_ignored_crossing_serials (display); + } + break; + case G_DESKTOP_FOCUS_MODE_CLICK: + break; + } + + if (window->type == META_WINDOW_DOCK) + meta_window_raise (window); + } + break; + case XI_Leave: + if (display->grab_op == META_GRAB_OP_COMPOSITOR) + break; + + if (window != NULL) + { + if (window->type == META_WINDOW_DOCK && + enter_event->mode != XINotifyGrab && + enter_event->mode != XINotifyUngrab && + !window->has_focus) + meta_window_lower (window); + } + break; + case XI_FocusIn: + case XI_FocusOut: + handle_window_focus_event (display, window, enter_event, serial); + if (!window) + { + /* Check if the window is a root window. */ + MetaScreen *screen = + meta_display_screen_for_root(display, + enter_event->event); + if (screen == NULL) + break; + + if (enter_event->evtype == XI_FocusIn && + enter_event->mode == XINotifyDetailNone) + { + meta_topic (META_DEBUG_FOCUS, + "Focus got set to None, probably due to " + "brain-damage in the X protocol (see bug " + "125492). Setting the default focus window.\n"); + meta_workspace_focus_default_window (screen->active_workspace, + NULL, + meta_display_get_current_time_roundtrip (display)); + } + else if (enter_event->evtype == XI_FocusIn && + enter_event->mode == XINotifyNormal && + enter_event->detail == XINotifyInferior) + { + meta_topic (META_DEBUG_FOCUS, + "Focus got set to root window, probably due to " + "gnome-session logout dialog usage (see bug " + "153220). Setting the default focus window.\n"); + meta_workspace_focus_default_window (screen->active_workspace, + NULL, + meta_display_get_current_time_roundtrip (display)); + } + + } + break; + } + + return FALSE; +} + static void reload_xkb_rules (MetaScreen *screen) { @@ -2338,7 +2710,6 @@ meta_display_handle_xevent (MetaDisplay *display, property_for_window = window; window = NULL; } - frame_was_receiver = FALSE; if (window && @@ -2411,363 +2782,14 @@ meta_display_handle_xevent (MetaDisplay *display, } #endif /* HAVE_XI23 */ - if (input_event != NULL) + /* libXi does not properly copy the serial to XI2 events, so pull it + * from the parent XAnyEvent and pass it to handle_input_xevent. + * See: https://bugs.freedesktop.org/show_bug.cgi?id=64687 + */ + if (handle_input_xevent (display, input_event, event->xany.serial)) { - XIDeviceEvent *device_event = (XIDeviceEvent *) input_event; - XIEnterEvent *enter_event = (XIEnterEvent *) input_event; - - if (window && !window->override_redirect && - ((input_event->type == XI_KeyPress) || (input_event->type == XI_ButtonPress))) - { - if (CurrentTime == display->current_time) - { - /* We can't use missing (i.e. invalid) timestamps to set user time, - * nor do we want to use them to sanity check other timestamps. - * See bug 313490 for more details. - */ - meta_warning ("Event has no timestamp! You may be using a broken " - "program such as xse. Please ask the authors of that " - "program to fix it.\n"); - } - else - { - meta_window_set_user_time (window, display->current_time); - sanity_check_timestamps (display, display->current_time); - } - } - - switch (input_event->evtype) - { - case XI_KeyPress: - case XI_KeyRelease: - - /* For key events, it's important to enforce single-handling, or - * we can get into a confused state. So if a keybinding is - * handled (because it's one of our hot-keys, or because we are - * in a keyboard-grabbed mode like moving a window, we don't - * want to pass the key event to the compositor or GTK+ at all. - */ - if (meta_display_process_key_event (display, window, (XIDeviceEvent *) input_event)) - bypass_gtk = bypass_compositor = TRUE; - break; - 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 ((window && - meta_grab_op_is_mouse (display->grab_op) && - (device_event->mods.effective & display->window_grab_modifiers) && - display->grab_button != device_event->detail && - display->grab_window == window) || - grab_op_is_keyboard (display->grab_op)) - { - meta_topic (META_DEBUG_WINDOW_OPS, - "Ending grab op %u on window %s due to button press\n", - display->grab_op, - (display->grab_window ? - display->grab_window->desc : - "none")); - if (GRAB_OP_IS_WINDOW_SWITCH (display->grab_op)) - { - MetaScreen *screen; - meta_topic (META_DEBUG_WINDOW_OPS, - "Syncing to old stack positions.\n"); - screen = - meta_display_screen_for_root (display, device_event->event); - - if (screen!=NULL) - meta_stack_set_positions (screen->stack, - display->grab_old_window_stacking); - } - meta_display_end_grab_op (display, - device_event->time); - } - else if (window && display->grab_op == META_GRAB_OP_NONE) - { - gboolean begin_move = FALSE; - unsigned int grab_mask; - gboolean unmodified; - - grab_mask = display->window_grab_modifiers; - if (g_getenv ("MUTTER_DEBUG_BUTTON_GRABS")) - grab_mask |= ControlMask; - - /* Two possible sources of an unmodified event; one is a - * client that's letting button presses pass through to the - * frame, the other is our focus_window_grab on unmodified - * button 1. So for all such events we focus the window. - */ - unmodified = (device_event->mods.effective & grab_mask) == 0; - - if (unmodified || - device_event->detail == 1) - { - /* don't focus if frame received, will be lowered in - * frames.c or special-cased if the click was on a - * minimize/close button. - */ - if (!frame_was_receiver) - { - if (meta_prefs_get_raise_on_click ()) - meta_window_raise (window); - else - meta_topic (META_DEBUG_FOCUS, - "Not raising window on click due to don't-raise-on-click option\n"); - - /* Don't focus panels--they must explicitly request focus. - * See bug 160470 - */ - if (window->type != META_WINDOW_DOCK) - { - meta_topic (META_DEBUG_FOCUS, - "Focusing %s due to unmodified button %u press (display.c)\n", - window->desc, device_event->detail); - meta_window_focus (window, device_event->time); - } - else - /* However, do allow terminals to lose focus due to new - * window mappings after the user clicks on a panel. - */ - display->allow_terminal_deactivation = TRUE; - } - - /* you can move on alt-click but not on - * the click-to-focus - */ - if (!unmodified) - begin_move = TRUE; - } - else if (!unmodified && device_event->detail == meta_prefs_get_mouse_button_resize()) - { - if (window->has_resize_func) - { - gboolean north, south; - gboolean west, east; - int root_x, root_y; - MetaGrabOp op; - - meta_window_get_position (window, &root_x, &root_y); - - west = device_event->root_x < (root_x + 1 * window->rect.width / 3); - east = device_event->root_x > (root_x + 2 * window->rect.width / 3); - north = device_event->root_y < (root_y + 1 * window->rect.height / 3); - south = device_event->root_y > (root_y + 2 * window->rect.height / 3); - - if (north && west) - op = META_GRAB_OP_RESIZING_NW; - else if (north && east) - op = META_GRAB_OP_RESIZING_NE; - else if (south && west) - op = META_GRAB_OP_RESIZING_SW; - else if (south && east) - op = META_GRAB_OP_RESIZING_SE; - else if (north) - op = META_GRAB_OP_RESIZING_N; - else if (west) - op = META_GRAB_OP_RESIZING_W; - else if (east) - op = META_GRAB_OP_RESIZING_E; - else if (south) - op = META_GRAB_OP_RESIZING_S; - else /* Middle region is no-op to avoid user triggering wrong action */ - op = META_GRAB_OP_NONE; - - if (op != META_GRAB_OP_NONE) - meta_display_begin_grab_op (display, - window->screen, - window, - op, - TRUE, - FALSE, - device_event->detail, - 0, - device_event->time, - device_event->root_x, - device_event->root_y); - } - } - else if (device_event->detail == 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, - device_event->time); - } - - if (!frame_was_receiver && unmodified) - { - /* This is from our synchronous grab since - * it has no modifiers and was on the client window - */ - - meta_verbose ("Allowing events time %u\n", - (unsigned int)device_event->time); - - XIAllowEvents (display->xdisplay, device_event->deviceid, - XIReplayDevice, device_event->time); - } - - if (begin_move && window->has_move_func) - { - meta_display_begin_grab_op (display, - window->screen, - window, - META_GRAB_OP_MOVING, - TRUE, - FALSE, - device_event->detail, - 0, - device_event->time, - device_event->root_x, - device_event->root_y); - } - } - break; - case XI_ButtonRelease: - if (display->grab_op == META_GRAB_OP_COMPOSITOR) - break; - - display->overlay_key_only_pressed = FALSE; - - if (display->grab_window == window && - meta_grab_op_is_mouse (display->grab_op)) - meta_window_handle_mouse_grab_op_event (window, device_event); - break; - case XI_Motion: - if (display->grab_op == META_GRAB_OP_COMPOSITOR) - break; - - if (display->grab_window == window && - meta_grab_op_is_mouse (display->grab_op)) - meta_window_handle_mouse_grab_op_event (window, device_event); - break; - case XI_Enter: - if (display->grab_op == META_GRAB_OP_COMPOSITOR) - break; - - /* If the mouse switches screens, active the default window on the new - * screen; this will make keybindings and workspace-launched items - * actually appear on the right screen. - */ - { - MetaScreen *new_screen = - meta_display_screen_for_root (display, enter_event->root); - - if (new_screen != NULL && display->active_screen != new_screen) - meta_workspace_focus_default_window (new_screen->active_workspace, - NULL, - enter_event->time); - } - - /* Check if we've entered a window; do this even if window->has_focus to - * avoid races. - */ - if (window && !crossing_serial_is_ignored (display, event->xany.serial) && - enter_event->mode != XINotifyGrab && - enter_event->mode != XINotifyUngrab && - enter_event->detail != XINotifyInferior && - meta_display_focus_sentinel_clear (display)) - { - switch (meta_prefs_get_focus_mode ()) - { - case G_DESKTOP_FOCUS_MODE_SLOPPY: - case G_DESKTOP_FOCUS_MODE_MOUSE: - display->mouse_mode = TRUE; - if (window->type != META_WINDOW_DOCK) - { - meta_topic (META_DEBUG_FOCUS, - "Queuing a focus change for %s due to " - "enter notify with serial %lu at time %lu, " - "and setting display->mouse_mode to TRUE.\n", - window->desc, - event->xany.serial, - enter_event->time); - - if (meta_prefs_get_focus_change_on_pointer_rest()) - meta_display_queue_focus_callback (display, window, - enter_event->root_x, - enter_event->root_y); - else - meta_display_mouse_mode_focus (display, window, - enter_event->time); - - /* stop ignoring stuff */ - reset_ignored_crossing_serials (display); - } - break; - case G_DESKTOP_FOCUS_MODE_CLICK: - break; - } - - if (window->type == META_WINDOW_DOCK) - meta_window_raise (window); - } - break; - case XI_Leave: - if (display->grab_op == META_GRAB_OP_COMPOSITOR) - break; - - if (window != NULL) - { - if (window->type == META_WINDOW_DOCK && - enter_event->mode != XINotifyGrab && - enter_event->mode != XINotifyUngrab && - !window->has_focus) - meta_window_lower (window); - } - break; - case XI_FocusIn: - case XI_FocusOut: - /* libXi does not properly copy the serial to the XIEnterEvent, so pull it - * from the parent XAnyEvent. - * See: https://bugs.freedesktop.org/show_bug.cgi?id=64687 - */ - handle_window_focus_event (display, window, enter_event, event->xany.serial); - if (!window) - { - /* Check if the window is a root window. */ - MetaScreen *screen = - meta_display_screen_for_root(display, - enter_event->event); - if (screen == NULL) - break; - - if (enter_event->evtype == XI_FocusIn && - enter_event->mode == XINotifyDetailNone) - { - meta_topic (META_DEBUG_FOCUS, - "Focus got set to None, probably due to " - "brain-damage in the X protocol (see bug " - "125492). Setting the default focus window.\n"); - meta_workspace_focus_default_window (screen->active_workspace, - NULL, - meta_display_get_current_time_roundtrip (display)); - } - else if (enter_event->evtype == XI_FocusIn && - enter_event->mode == XINotifyNormal && - enter_event->detail == XINotifyInferior) - { - meta_topic (META_DEBUG_FOCUS, - "Focus got set to root window, probably due to " - "gnome-session logout dialog usage (see bug " - "153220). Setting the default focus window.\n"); - meta_workspace_focus_default_window (screen->active_workspace, - NULL, - meta_display_get_current_time_roundtrip (display)); - } - - } - break; - } + bypass_gtk = bypass_compositor = TRUE; + goto out; } else { @@ -3252,6 +3274,33 @@ event_callback (XEvent *event, return meta_display_handle_xevent (display, event); } +static Window +xievent_get_modified_window (MetaDisplay *display, + XIEvent *input_event) +{ + switch (input_event->evtype) + { + case XI_Motion: + case XI_ButtonPress: + case XI_ButtonRelease: + case XI_KeyPress: + case XI_KeyRelease: + return ((XIDeviceEvent *) input_event)->event; + case XI_FocusIn: + case XI_FocusOut: + case XI_Enter: + case XI_Leave: + return ((XIEnterEvent *) input_event)->event; +#ifdef HAVE_XI23 + case XI_BarrierHit: + case XI_BarrierLeave: + return ((XIBarrierEvent *) input_event)->event; +#endif /* HAVE_XI23 */ + } + + return None; +} + /* Return the window this has to do with, if any, rather * than the frame or root window that was selecting * for substructure @@ -3263,27 +3312,7 @@ event_get_modified_window (MetaDisplay *display, XIEvent *input_event = get_input_event (display, event); if (input_event) - { - switch (input_event->evtype) - { - case XI_Motion: - case XI_ButtonPress: - case XI_ButtonRelease: - case XI_KeyPress: - case XI_KeyRelease: - return ((XIDeviceEvent *) input_event)->event; - case XI_FocusIn: - case XI_FocusOut: - case XI_Enter: - case XI_Leave: - return ((XIEnterEvent *) input_event)->event; -#ifdef HAVE_XI23 - case XI_BarrierHit: - case XI_BarrierLeave: - return ((XIBarrierEvent *) input_event)->event; -#endif /* HAVE_XI23 */ - } - } + return xievent_get_modified_window (display, input_event); switch (event->type) { From 4ea4658abf22055c4b9bc47ef4deb72398b576cc Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 3 Oct 2013 17:13:48 -0400 Subject: [PATCH 198/889] display: Split out other event handling as well This vastly simplifies the code in event_callback and allows us to potentially take more of this logic and punt it to Wayland-specific backends. --- src/core/display.c | 1058 ++++++++++++++++++++++---------------------- 1 file changed, 529 insertions(+), 529 deletions(-) diff --git a/src/core/display.c b/src/core/display.c index ce209b294..54a68bf08 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -2597,6 +2597,527 @@ reload_xkb_rules (MetaScreen *screen) g_strfreev (names); } +static gboolean +handle_other_xevent (MetaDisplay *display, + XEvent *event) +{ + Window modified; + MetaWindow *window; + MetaWindow *property_for_window; + gboolean frame_was_receiver; + gboolean bypass_gtk = FALSE; + + modified = event_get_modified_window (display, event); + window = modified != None ? meta_display_lookup_x_window (display, modified) : NULL; + frame_was_receiver = (window && window->frame && modified == window->frame->xwindow); + + /* We only want to respond to _NET_WM_USER_TIME property notify + * events on _NET_WM_USER_TIME_WINDOW windows; in particular, + * responding to UnmapNotify events is kind of bad. + */ + property_for_window = NULL; + if (window && modified == window->user_time_window) + { + property_for_window = window; + window = NULL; + } + +#ifdef HAVE_XSYNC + if (META_DISPLAY_HAS_XSYNC (display) && + event->type == (display->xsync_event_base + XSyncAlarmNotify)) + { + MetaWindow *alarm_window = meta_display_lookup_sync_alarm (display, + ((XSyncAlarmNotifyEvent*)event)->alarm); + + if (alarm_window != NULL) + { + XSyncValue value = ((XSyncAlarmNotifyEvent*)event)->counter_value; + gint64 new_counter_value; + new_counter_value = XSyncValueLow32 (value) + ((gint64)XSyncValueHigh32 (value) << 32); + meta_window_update_sync_request_counter (alarm_window, new_counter_value); + bypass_gtk = TRUE; /* GTK doesn't want to see this really */ + } + else + meta_idle_monitor_handle_xevent_all (event); + + goto out; + } +#endif /* HAVE_XSYNC */ + +#ifdef HAVE_SHAPE + if (META_DISPLAY_HAS_SHAPE (display) && + event->type == (display->shape_event_base + ShapeNotify)) + { + bypass_gtk = TRUE; /* GTK doesn't want to see this really */ + + if (window && !frame_was_receiver) + { + XShapeEvent *sev = (XShapeEvent*) event; + + if (sev->kind == ShapeBounding) + meta_window_update_shape_region_x11 (window); + else if (sev->kind == ShapeInput) + meta_window_update_input_region_x11 (window); + } + else + { + meta_topic (META_DEBUG_SHAPES, + "ShapeNotify not on a client window (window %s frame_was_receiver = %d)\n", + window ? window->desc : "(none)", + frame_was_receiver); + } + + goto out; + } +#endif /* HAVE_SHAPE */ + + switch (event->type) + { + case KeymapNotify: + break; + case Expose: + break; + case GraphicsExpose: + break; + case NoExpose: + break; + case VisibilityNotify: + break; + case CreateNotify: + { + MetaScreen *screen; + + screen = meta_display_screen_for_root (display, + event->xcreatewindow.parent); + if (screen) + meta_stack_tracker_create_event (screen->stack_tracker, + &event->xcreatewindow); + } + break; + + case DestroyNotify: + { + MetaScreen *screen; + + screen = meta_display_screen_for_root (display, + event->xdestroywindow.event); + if (screen) + meta_stack_tracker_destroy_event (screen->stack_tracker, + &event->xdestroywindow); + } + if (window) + { + /* FIXME: It sucks that DestroyNotify events don't come with + * a timestamp; could we do something better here? Maybe X + * will change one day? + */ + guint32 timestamp; + timestamp = meta_display_get_current_time_roundtrip (display); + + if (display->grab_op != META_GRAB_OP_NONE && + display->grab_window == window) + meta_display_end_grab_op (display, timestamp); + + if (frame_was_receiver) + { + meta_warning ("Unexpected destruction of frame 0x%lx, not sure if this should silently fail or be considered a bug\n", + window->frame->xwindow); + meta_error_trap_push (display); + meta_window_destroy_frame (window->frame->window); + meta_error_trap_pop (display); + } + else + { + /* Unmanage destroyed window */ + meta_window_unmanage (window, timestamp); + window = NULL; + } + } + break; + case UnmapNotify: + if (window) + { + /* FIXME: It sucks that UnmapNotify events don't come with + * a timestamp; could we do something better here? Maybe X + * will change one day? + */ + guint32 timestamp; + timestamp = meta_display_get_current_time_roundtrip (display); + + if (display->grab_op != META_GRAB_OP_NONE && + display->grab_window == window && + ((window->frame == NULL) || !window->frame->mapped)) + meta_display_end_grab_op (display, timestamp); + + if (!frame_was_receiver) + { + if (window->unmaps_pending == 0) + { + meta_topic (META_DEBUG_WINDOW_STATE, + "Window %s withdrawn\n", + window->desc); + + /* Unmanage withdrawn window */ + window->withdrawn = TRUE; + meta_window_unmanage (window, timestamp); + window = NULL; + } + else + { + window->unmaps_pending -= 1; + meta_topic (META_DEBUG_WINDOW_STATE, + "Received pending unmap, %d now pending\n", + window->unmaps_pending); + } + } + } + break; + case MapNotify: + /* NB: override redirect windows wont cause a map request so we + * watch out for map notifies against any root windows too if a + * compositor is enabled: */ + if (display->compositor && window == NULL + && meta_display_screen_for_root (display, event->xmap.event)) + { + window = meta_window_new (display, event->xmap.window, + FALSE); + } + break; + case MapRequest: + if (window == NULL) + { + window = meta_window_new (display, event->xmaprequest.window, + FALSE); + } + /* if frame was receiver it's some malicious send event or something */ + else if (!frame_was_receiver && window) + { + meta_verbose ("MapRequest on %s mapped = %d minimized = %d\n", + window->desc, window->mapped, window->minimized); + if (window->minimized) + { + meta_window_unminimize (window); + if (window->workspace != window->screen->active_workspace) + { + meta_verbose ("Changing workspace due to MapRequest mapped = %d minimized = %d\n", + window->mapped, window->minimized); + meta_window_change_workspace (window, + window->screen->active_workspace); + } + } + } + break; + case ReparentNotify: + { + MetaScreen *screen; + + screen = meta_display_screen_for_root (display, + event->xconfigure.event); + if (screen) + meta_stack_tracker_reparent_event (screen->stack_tracker, + &event->xreparent); + } + break; + case ConfigureNotify: + if (event->xconfigure.event != event->xconfigure.window) + { + MetaScreen *screen; + + screen = meta_display_screen_for_root (display, + event->xconfigure.event); + if (screen) + meta_stack_tracker_configure_event (screen->stack_tracker, + &event->xconfigure); + } + + if (window && window->override_redirect) + meta_window_configure_notify (window, &event->xconfigure); + + break; + case ConfigureRequest: + /* This comment and code is found in both twm and fvwm */ + /* + * According to the July 27, 1988 ICCCM draft, we should ignore size and + * position fields in the WM_NORMAL_HINTS property when we map a window. + * Instead, we'll read the current geometry. Therefore, we should respond + * to configuration requests for windows which have never been mapped. + */ + if (window == NULL) + { + unsigned int xwcm; + XWindowChanges xwc; + + xwcm = event->xconfigurerequest.value_mask & + (CWX | CWY | CWWidth | CWHeight | CWBorderWidth); + + xwc.x = event->xconfigurerequest.x; + xwc.y = event->xconfigurerequest.y; + xwc.width = event->xconfigurerequest.width; + xwc.height = event->xconfigurerequest.height; + xwc.border_width = event->xconfigurerequest.border_width; + + meta_verbose ("Configuring withdrawn window to %d,%d %dx%d border %d (some values may not be in mask)\n", + xwc.x, xwc.y, xwc.width, xwc.height, xwc.border_width); + meta_error_trap_push (display); + XConfigureWindow (display->xdisplay, event->xconfigurerequest.window, + xwcm, &xwc); + meta_error_trap_pop (display); + } + else + { + if (!frame_was_receiver) + meta_window_configure_request (window, event); + } + break; + case GravityNotify: + break; + case ResizeRequest: + break; + case CirculateNotify: + break; + case CirculateRequest: + break; + case PropertyNotify: + { + MetaGroup *group; + MetaScreen *screen; + + if (window && !frame_was_receiver) + meta_window_property_notify (window, event); + else if (property_for_window && !frame_was_receiver) + meta_window_property_notify (property_for_window, event); + + group = meta_display_lookup_group (display, + event->xproperty.window); + if (group != NULL) + meta_group_property_notify (group, event); + + screen = NULL; + if (window == NULL && + group == NULL) /* window/group != NULL means it wasn't a root window */ + screen = meta_display_screen_for_root (display, + event->xproperty.window); + + if (screen != NULL) + { + if (event->xproperty.atom == + display->atom__NET_DESKTOP_LAYOUT) + meta_screen_update_workspace_layout (screen); + else if (event->xproperty.atom == + display->atom__NET_DESKTOP_NAMES) + meta_screen_update_workspace_names (screen); + else if (meta_is_wayland_compositor () && + event->xproperty.atom == + display->atom__XKB_RULES_NAMES) + reload_xkb_rules (screen); +#if 0 + else if (event->xproperty.atom == + display->atom__NET_RESTACK_WINDOW) + handle_net_restack_window (display, event); +#endif + + /* we just use this property as a sentinel to avoid + * certain race conditions. See the comment for the + * sentinel_counter variable declaration in display.h + */ + if (event->xproperty.atom == + display->atom__MUTTER_SENTINEL) + { + meta_display_decrement_focus_sentinel (display); + } + } + } + break; + case SelectionClear: + /* do this here instead of at end of function + * so we can return + */ + + /* FIXME: Clearing display->current_time here makes no sense to + * me; who put this here and why? + */ + display->current_time = CurrentTime; + + process_selection_clear (display, event); + /* Note that processing that may have resulted in + * closing the display... so return right away. + */ + return FALSE; + case SelectionRequest: + process_selection_request (display, event); + break; + case SelectionNotify: + break; + case ColormapNotify: + if (window && !frame_was_receiver) + window->colormap = event->xcolormap.colormap; + break; + case ClientMessage: + if (window) + { + if (!frame_was_receiver) + meta_window_client_message (window, event); + } + else + { + MetaScreen *screen; + + screen = meta_display_screen_for_root (display, + event->xclient.window); + + if (screen) + { + if (event->xclient.message_type == + display->atom__NET_CURRENT_DESKTOP) + { + int space; + MetaWorkspace *workspace; + guint32 time; + + space = event->xclient.data.l[0]; + time = event->xclient.data.l[1]; + + meta_verbose ("Request to change current workspace to %d with " + "specified timestamp of %u\n", + space, time); + + workspace = + meta_screen_get_workspace_by_index (screen, + space); + + /* Handle clients using the older version of the spec... */ + if (time == 0 && workspace) + { + meta_warning ("Received a NET_CURRENT_DESKTOP message " + "from a broken (outdated) client who sent " + "a 0 timestamp\n"); + time = meta_display_get_current_time_roundtrip (display); + } + + if (workspace) + meta_workspace_activate (workspace, time); + else + meta_verbose ("Don't know about workspace %d\n", space); + } + else if (event->xclient.message_type == + display->atom__NET_NUMBER_OF_DESKTOPS) + { + int num_spaces; + + num_spaces = event->xclient.data.l[0]; + + meta_verbose ("Request to set number of workspaces to %d\n", + num_spaces); + + meta_prefs_set_num_workspaces (num_spaces); + } + else if (event->xclient.message_type == + display->atom__NET_SHOWING_DESKTOP) + { + gboolean showing_desktop; + guint32 timestamp; + + showing_desktop = event->xclient.data.l[0] != 0; + /* FIXME: Braindead protocol doesn't have a timestamp */ + timestamp = meta_display_get_current_time_roundtrip (display); + meta_verbose ("Request to %s desktop\n", + showing_desktop ? "show" : "hide"); + + if (showing_desktop) + meta_screen_show_desktop (screen, timestamp); + else + { + meta_screen_unshow_desktop (screen); + meta_workspace_focus_default_window (screen->active_workspace, NULL, timestamp); + } + } + else if (event->xclient.message_type == + display->atom_WM_PROTOCOLS) + { + meta_verbose ("Received WM_PROTOCOLS message\n"); + + if ((Atom)event->xclient.data.l[0] == display->atom__NET_WM_PING) + { + process_pong_message (display, event); + + /* We don't want ping reply events going into + * the GTK+ event loop because gtk+ will treat + * them as ping requests and send more replies. + */ + bypass_gtk = TRUE; + } + } + } + + if (event->xclient.message_type == + display->atom__NET_REQUEST_FRAME_EXTENTS) + { + meta_verbose ("Received _NET_REQUEST_FRAME_EXTENTS message\n"); + process_request_frame_extents (display, event); + } + } + break; + case MappingNotify: + { + gboolean ignore_current; + + ignore_current = FALSE; + + /* Check whether the next event is an identical MappingNotify + * event. If it is, ignore the current event, we'll update + * when we get the next one. + */ + if (XPending (display->xdisplay)) + { + XEvent next_event; + + XPeekEvent (display->xdisplay, &next_event); + + if (next_event.type == MappingNotify && + next_event.xmapping.request == event->xmapping.request) + ignore_current = TRUE; + } + + if (!ignore_current) + { + /* Let XLib know that there is a new keyboard mapping. + */ + XRefreshKeyboardMapping (&event->xmapping); + meta_display_process_mapping_event (display, event); + } + } + break; + default: +#ifdef HAVE_XKB + if (event->type == display->xkb_base_event_type) + { + XkbAnyEvent *xkb_ev = (XkbAnyEvent *) event; + + switch (xkb_ev->xkb_type) + { + case XkbBellNotify: + if (XSERVER_TIME_IS_BEFORE(display->last_bell_time, + xkb_ev->time - 100)) + { + display->last_bell_time = xkb_ev->time; + meta_bell_notify (display, xkb_ev); + } + break; + case XkbNewKeyboardNotify: + case XkbMapNotify: + if (xkb_ev->device == META_VIRTUAL_CORE_KEYBOARD_ID) + meta_display_process_mapping_event (display, event); + break; + } + } +#endif + break; + } + + out: + return bypass_gtk; +} + /** * meta_display_handle_xevent: * @display: The MetaDisplay that events are coming from @@ -2614,10 +3135,7 @@ gboolean meta_display_handle_xevent (MetaDisplay *display, XEvent *event) { - MetaWindow *window; - MetaWindow *property_for_window; Window modified; - gboolean frame_was_receiver; gboolean bypass_compositor = FALSE, bypass_gtk = FALSE; XIEvent *input_event; MetaMonitorManager *monitor; @@ -2672,7 +3190,7 @@ meta_display_handle_xevent (MetaDisplay *display, modified = event_get_modified_window (display, event); input_event = get_input_event (display, event); - + if (event->type == UnmapNotify) { if (meta_ui_window_should_not_cause_focus (display->xdisplay, @@ -2695,85 +3213,6 @@ meta_display_handle_xevent (MetaDisplay *display, event->xany.serial); } - if (modified != None) - window = meta_display_lookup_x_window (display, modified); - else - window = NULL; - - /* We only want to respond to _NET_WM_USER_TIME property notify - * events on _NET_WM_USER_TIME_WINDOW windows; in particular, - * responding to UnmapNotify events is kind of bad. - */ - property_for_window = NULL; - if (window && modified == window->user_time_window) - { - property_for_window = window; - window = NULL; - } - - frame_was_receiver = FALSE; - if (window && - window->frame && - modified == window->frame->xwindow) - { - /* Note that if the frame and the client both have an - * XGrabButton (as is normal with our setup), the event - * goes to the frame. - */ - frame_was_receiver = TRUE; - meta_topic (META_DEBUG_EVENTS, "Frame was receiver of event for %s\n", - window->desc); - } - -#ifdef HAVE_XSYNC - if (META_DISPLAY_HAS_XSYNC (display) && - event->type == (display->xsync_event_base + XSyncAlarmNotify)) - { - MetaWindow *alarm_window = meta_display_lookup_sync_alarm (display, - ((XSyncAlarmNotifyEvent*)event)->alarm); - - if (alarm_window != NULL) - { - XSyncValue value = ((XSyncAlarmNotifyEvent*)event)->counter_value; - gint64 new_counter_value; - new_counter_value = XSyncValueLow32 (value) + ((gint64)XSyncValueHigh32 (value) << 32); - meta_window_update_sync_request_counter (alarm_window, new_counter_value); - bypass_gtk = TRUE; /* GTK doesn't want to see this really */ - } - else - meta_idle_monitor_handle_xevent_all (event); - - goto out; - } -#endif /* HAVE_XSYNC */ - -#ifdef HAVE_SHAPE - if (META_DISPLAY_HAS_SHAPE (display) && - event->type == (display->shape_event_base + ShapeNotify)) - { - bypass_gtk = TRUE; /* GTK doesn't want to see this really */ - - if (window && !frame_was_receiver) - { - XShapeEvent *sev = (XShapeEvent*) event; - - if (sev->kind == ShapeBounding) - meta_window_update_shape_region_x11 (window); - else if (sev->kind == ShapeInput) - meta_window_update_input_region_x11 (window); - } - else - { - meta_topic (META_DEBUG_SHAPES, - "ShapeNotify not on a client window (window %s frame_was_receiver = %d)\n", - window ? window->desc : "(none)", - frame_was_receiver); - } - - goto out; - } -#endif /* HAVE_SHAPE */ - #ifdef HAVE_XI23 if (meta_display_process_barrier_event (display, input_event)) { @@ -2791,458 +3230,19 @@ meta_display_handle_xevent (MetaDisplay *display, bypass_gtk = bypass_compositor = TRUE; goto out; } - else + + if (handle_other_xevent (display, event)) { - switch (event->type) - { - case KeymapNotify: - break; - case Expose: - break; - case GraphicsExpose: - break; - case NoExpose: - break; - case VisibilityNotify: - break; - case CreateNotify: - { - MetaScreen *screen; - - screen = meta_display_screen_for_root (display, - event->xcreatewindow.parent); - if (screen) - meta_stack_tracker_create_event (screen->stack_tracker, - &event->xcreatewindow); - } - break; - - case DestroyNotify: - { - MetaScreen *screen; - - screen = meta_display_screen_for_root (display, - event->xdestroywindow.event); - if (screen) - meta_stack_tracker_destroy_event (screen->stack_tracker, - &event->xdestroywindow); - } - if (window) - { - /* FIXME: It sucks that DestroyNotify events don't come with - * a timestamp; could we do something better here? Maybe X - * will change one day? - */ - guint32 timestamp; - timestamp = meta_display_get_current_time_roundtrip (display); - - if (display->grab_op != META_GRAB_OP_NONE && - display->grab_window == window) - meta_display_end_grab_op (display, timestamp); - - if (frame_was_receiver) - { - meta_warning ("Unexpected destruction of frame 0x%lx, not sure if this should silently fail or be considered a bug\n", - window->frame->xwindow); - meta_error_trap_push (display); - meta_window_destroy_frame (window->frame->window); - meta_error_trap_pop (display); - } - else - { - /* Unmanage destroyed window */ - meta_window_unmanage (window, timestamp); - window = NULL; - } - } - break; - case UnmapNotify: - if (window) - { - /* FIXME: It sucks that UnmapNotify events don't come with - * a timestamp; could we do something better here? Maybe X - * will change one day? - */ - guint32 timestamp; - timestamp = meta_display_get_current_time_roundtrip (display); - - if (display->grab_op != META_GRAB_OP_NONE && - display->grab_window == window && - ((window->frame == NULL) || !window->frame->mapped)) - meta_display_end_grab_op (display, timestamp); - - if (!frame_was_receiver) - { - if (window->unmaps_pending == 0) - { - meta_topic (META_DEBUG_WINDOW_STATE, - "Window %s withdrawn\n", - window->desc); - - /* Unmanage withdrawn window */ - window->withdrawn = TRUE; - meta_window_unmanage (window, timestamp); - window = NULL; - } - else - { - window->unmaps_pending -= 1; - meta_topic (META_DEBUG_WINDOW_STATE, - "Received pending unmap, %d now pending\n", - window->unmaps_pending); - } - } - } - break; - case MapNotify: - /* NB: override redirect windows wont cause a map request so we - * watch out for map notifies against any root windows too if a - * compositor is enabled: */ - if (display->compositor && window == NULL - && meta_display_screen_for_root (display, event->xmap.event)) - { - window = meta_window_new (display, event->xmap.window, - FALSE); - } - break; - case MapRequest: - if (window == NULL) - { - window = meta_window_new (display, event->xmaprequest.window, - FALSE); - } - /* if frame was receiver it's some malicious send event or something */ - else if (!frame_was_receiver && window) - { - meta_verbose ("MapRequest on %s mapped = %d minimized = %d\n", - window->desc, window->mapped, window->minimized); - if (window->minimized) - { - meta_window_unminimize (window); - if (window->workspace != window->screen->active_workspace) - { - meta_verbose ("Changing workspace due to MapRequest mapped = %d minimized = %d\n", - window->mapped, window->minimized); - meta_window_change_workspace (window, - window->screen->active_workspace); - } - } - } - break; - case ReparentNotify: - { - MetaScreen *screen; - - screen = meta_display_screen_for_root (display, - event->xconfigure.event); - if (screen) - meta_stack_tracker_reparent_event (screen->stack_tracker, - &event->xreparent); - } - break; - case ConfigureNotify: - if (event->xconfigure.event != event->xconfigure.window) - { - MetaScreen *screen; - - screen = meta_display_screen_for_root (display, - event->xconfigure.event); - if (screen) - meta_stack_tracker_configure_event (screen->stack_tracker, - &event->xconfigure); - } - - if (window && window->override_redirect) - meta_window_configure_notify (window, &event->xconfigure); - - break; - case ConfigureRequest: - /* This comment and code is found in both twm and fvwm */ - /* - * According to the July 27, 1988 ICCCM draft, we should ignore size and - * position fields in the WM_NORMAL_HINTS property when we map a window. - * Instead, we'll read the current geometry. Therefore, we should respond - * to configuration requests for windows which have never been mapped. - */ - if (window == NULL) - { - unsigned int xwcm; - XWindowChanges xwc; - - xwcm = event->xconfigurerequest.value_mask & - (CWX | CWY | CWWidth | CWHeight | CWBorderWidth); - - xwc.x = event->xconfigurerequest.x; - xwc.y = event->xconfigurerequest.y; - xwc.width = event->xconfigurerequest.width; - xwc.height = event->xconfigurerequest.height; - xwc.border_width = event->xconfigurerequest.border_width; - - meta_verbose ("Configuring withdrawn window to %d,%d %dx%d border %d (some values may not be in mask)\n", - xwc.x, xwc.y, xwc.width, xwc.height, xwc.border_width); - meta_error_trap_push (display); - XConfigureWindow (display->xdisplay, event->xconfigurerequest.window, - xwcm, &xwc); - meta_error_trap_pop (display); - } - else - { - if (!frame_was_receiver) - meta_window_configure_request (window, event); - } - break; - case GravityNotify: - break; - case ResizeRequest: - break; - case CirculateNotify: - break; - case CirculateRequest: - break; - case PropertyNotify: - { - MetaGroup *group; - MetaScreen *screen; - - if (window && !frame_was_receiver) - meta_window_property_notify (window, event); - else if (property_for_window && !frame_was_receiver) - meta_window_property_notify (property_for_window, event); - - group = meta_display_lookup_group (display, - event->xproperty.window); - if (group != NULL) - meta_group_property_notify (group, event); - - screen = NULL; - if (window == NULL && - group == NULL) /* window/group != NULL means it wasn't a root window */ - screen = meta_display_screen_for_root (display, - event->xproperty.window); - - if (screen != NULL) - { - if (event->xproperty.atom == - display->atom__NET_DESKTOP_LAYOUT) - meta_screen_update_workspace_layout (screen); - else if (event->xproperty.atom == - display->atom__NET_DESKTOP_NAMES) - meta_screen_update_workspace_names (screen); - else if (meta_is_wayland_compositor () && - event->xproperty.atom == - display->atom__XKB_RULES_NAMES) - reload_xkb_rules (screen); -#if 0 - else if (event->xproperty.atom == - display->atom__NET_RESTACK_WINDOW) - handle_net_restack_window (display, event); -#endif - - /* we just use this property as a sentinel to avoid - * certain race conditions. See the comment for the - * sentinel_counter variable declaration in display.h - */ - if (event->xproperty.atom == - display->atom__MUTTER_SENTINEL) - { - meta_display_decrement_focus_sentinel (display); - } - } - } - break; - case SelectionClear: - /* do this here instead of at end of function - * so we can return - */ - - /* FIXME: Clearing display->current_time here makes no sense to - * me; who put this here and why? - */ - display->current_time = CurrentTime; - - process_selection_clear (display, event); - /* Note that processing that may have resulted in - * closing the display... so return right away. - */ - return FALSE; - case SelectionRequest: - process_selection_request (display, event); - break; - case SelectionNotify: - break; - case ColormapNotify: - if (window && !frame_was_receiver) - window->colormap = event->xcolormap.colormap; - break; - case ClientMessage: - if (window) - { - if (!frame_was_receiver) - meta_window_client_message (window, event); - } - else - { - MetaScreen *screen; - - screen = meta_display_screen_for_root (display, - event->xclient.window); - - if (screen) - { - if (event->xclient.message_type == - display->atom__NET_CURRENT_DESKTOP) - { - int space; - MetaWorkspace *workspace; - guint32 time; - - space = event->xclient.data.l[0]; - time = event->xclient.data.l[1]; - - meta_verbose ("Request to change current workspace to %d with " - "specified timestamp of %u\n", - space, time); - - workspace = - meta_screen_get_workspace_by_index (screen, - space); - - /* Handle clients using the older version of the spec... */ - if (time == 0 && workspace) - { - meta_warning ("Received a NET_CURRENT_DESKTOP message " - "from a broken (outdated) client who sent " - "a 0 timestamp\n"); - time = meta_display_get_current_time_roundtrip (display); - } - - if (workspace) - meta_workspace_activate (workspace, time); - else - meta_verbose ("Don't know about workspace %d\n", space); - } - else if (event->xclient.message_type == - display->atom__NET_NUMBER_OF_DESKTOPS) - { - int num_spaces; - - num_spaces = event->xclient.data.l[0]; - - meta_verbose ("Request to set number of workspaces to %d\n", - num_spaces); - - meta_prefs_set_num_workspaces (num_spaces); - } - else if (event->xclient.message_type == - display->atom__NET_SHOWING_DESKTOP) - { - gboolean showing_desktop; - guint32 timestamp; - - showing_desktop = event->xclient.data.l[0] != 0; - /* FIXME: Braindead protocol doesn't have a timestamp */ - timestamp = meta_display_get_current_time_roundtrip (display); - meta_verbose ("Request to %s desktop\n", - showing_desktop ? "show" : "hide"); - - if (showing_desktop) - meta_screen_show_desktop (screen, timestamp); - else - { - meta_screen_unshow_desktop (screen); - meta_workspace_focus_default_window (screen->active_workspace, NULL, timestamp); - } - } - else if (event->xclient.message_type == - display->atom_WM_PROTOCOLS) - { - meta_verbose ("Received WM_PROTOCOLS message\n"); - - if ((Atom)event->xclient.data.l[0] == display->atom__NET_WM_PING) - { - process_pong_message (display, event); - - /* We don't want ping reply events going into - * the GTK+ event loop because gtk+ will treat - * them as ping requests and send more replies. - */ - bypass_gtk = TRUE; - } - } - } - - if (event->xclient.message_type == - display->atom__NET_REQUEST_FRAME_EXTENTS) - { - meta_verbose ("Received _NET_REQUEST_FRAME_EXTENTS message\n"); - process_request_frame_extents (display, event); - } - } - break; - case MappingNotify: - { - gboolean ignore_current; - - ignore_current = FALSE; - - /* Check whether the next event is an identical MappingNotify - * event. If it is, ignore the current event, we'll update - * when we get the next one. - */ - if (XPending (display->xdisplay)) - { - XEvent next_event; - - XPeekEvent (display->xdisplay, &next_event); - - if (next_event.type == MappingNotify && - next_event.xmapping.request == event->xmapping.request) - ignore_current = TRUE; - } - - if (!ignore_current) - { - /* Let XLib know that there is a new keyboard mapping. - */ - XRefreshKeyboardMapping (&event->xmapping); - meta_display_process_mapping_event (display, event); - } - } - break; - default: -#ifdef HAVE_XKB - if (event->type == display->xkb_base_event_type) - { - XkbAnyEvent *xkb_ev = (XkbAnyEvent *) event; - - switch (xkb_ev->xkb_type) - { - case XkbBellNotify: - if (XSERVER_TIME_IS_BEFORE(display->last_bell_time, - xkb_ev->time - 100)) - { - display->last_bell_time = xkb_ev->time; - meta_bell_notify (display, xkb_ev); - } - break; - case XkbNewKeyboardNotify: - case XkbMapNotify: - if (xkb_ev->device == META_VIRTUAL_CORE_KEYBOARD_ID) - meta_display_process_mapping_event (display, event); - break; - } - } -#endif - break; - } + bypass_gtk = TRUE; + goto out; } out: if (display->compositor && !bypass_compositor) { - if (meta_compositor_process_event (display->compositor, - event, - window)) + MetaWindow *window = modified != None ? meta_display_lookup_x_window (display, modified) : NULL; + + if (meta_compositor_process_event (display->compositor, event, window)) bypass_gtk = TRUE; } From e86c53230fbcfa67c789c0d4611034b587de9ef6 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 3 Oct 2013 15:29:44 -0400 Subject: [PATCH 199/889] display: Move the pointer event handling code to work in terms of Clutter events There is now a meta_display_handle_event alongside the meta_display_handle_xevent function which handles events in terms of Clutter events instead of X events. A Clutter event filter is registered so that all Clutter events will pass through this function. The pointer event handling code from the X event version has been moved into this new function and has been modified to use the details from the Clutter event instead of the X event. This is a step towards moving all of the event handling code over to use Clutter events. Based-heavily-on-a-patch-by: Neil Roberts --- src/core/display-private.h | 6 +- src/core/display.c | 493 +++++++++++++++++++++---------------- src/core/window-private.h | 5 +- src/core/window.c | 168 ++++--------- 4 files changed, 340 insertions(+), 332 deletions(-) diff --git a/src/core/display-private.h b/src/core/display-private.h index eb7569d79..a700a329e 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -39,6 +39,7 @@ #include "keybindings-private.h" #include #include +#include #ifdef HAVE_STARTUP_NOTIFICATION #include @@ -189,7 +190,7 @@ struct _MetaDisplay MetaWindow* autoraise_window; /* Alt+click button grabs */ - unsigned int window_grab_modifiers; + ClutterModifierType window_grab_modifiers; /* current window operation */ MetaGrabOp grab_op; @@ -485,6 +486,9 @@ guint meta_display_get_above_tab_keycode (MetaDisplay *display); gboolean meta_display_handle_xevent (MetaDisplay *display, XEvent *event); +gboolean meta_display_handle_event (MetaDisplay *display, + const ClutterEvent *event); + #ifdef HAVE_XI23 gboolean meta_display_process_barrier_event (MetaDisplay *display, XIEvent *event); diff --git a/src/core/display.c b/src/core/display.c index 54a68bf08..ed8f9db07 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -174,8 +174,10 @@ static void meta_spew_event (MetaDisplay *display, XEvent *event); #endif -static gboolean event_callback (XEvent *event, +static gboolean xevent_callback (XEvent *event, gpointer data); +static gboolean event_callback (const ClutterEvent *event, + gpointer data); static Window event_get_modified_window (MetaDisplay *display, XEvent *event); static Window xievent_get_modified_window (MetaDisplay *display, @@ -603,8 +605,9 @@ meta_display_open (void) /* Get events */ meta_ui_add_event_func (the_display->xdisplay, - event_callback, + xevent_callback, the_display); + clutter_event_add_filter (event_callback, the_display); the_display->xids = g_hash_table_new (meta_unsigned_long_hash, meta_unsigned_long_equal); @@ -1134,8 +1137,9 @@ meta_display_close (MetaDisplay *display, /* Stop caring about events */ meta_ui_remove_event_func (display->xdisplay, - event_callback, + xevent_callback, display); + clutter_event_remove_filter (event_callback, display); /* Free all screens */ tmp = display->screens; @@ -1866,6 +1870,32 @@ handle_net_restack_window (MetaDisplay* display, } #endif +static MetaWindow * +get_window_for_actor (ClutterActor *actor, + gboolean *frame_was_receiver) +{ + /* Look for any ancestor that is a MetaWindowActor to determine + which window the actor's event belongs to */ + + *frame_was_receiver = TRUE; + + while (actor) + { + if (META_IS_WINDOW_ACTOR (actor)) + return meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor)); + + /* If the frame is the receiver then the source will directly be + the MetaWindowActor, otherwise it will be a child of a + MetaWindowActor so if we make it here then the event isn't + referring to the frame. */ + *frame_was_receiver = FALSE; + + actor = clutter_actor_get_parent (actor); + } + + return NULL; +} + static XIEvent * get_input_event (MetaDisplay *display, XEvent *event) @@ -2193,26 +2223,260 @@ handle_window_focus_event (MetaDisplay *display, } } +gboolean +meta_display_handle_event (MetaDisplay *display, + const ClutterEvent *event) +{ + MetaWindow *window; + gboolean frame_was_receiver; + + window = get_window_for_actor (event->any.source, &frame_was_receiver); + + display->current_time = event->any.time; + + if (window && !window->override_redirect && event->type == CLUTTER_BUTTON_PRESS) + { + if (CurrentTime == display->current_time) + { + /* We can't use missing (i.e. invalid) timestamps to set user time, + * nor do we want to use them to sanity check other timestamps. + * See bug 313490 for more details. + */ + meta_warning ("Event has no timestamp! You may be using a broken " + "program such as xse. Please ask the authors of that " + "program to fix it.\n"); + } + else + { + meta_window_set_user_time (window, display->current_time); + sanity_check_timestamps (display, display->current_time); + } + } + + switch (event->type) + { + case CLUTTER_BUTTON_PRESS: + if (display->grab_op == META_GRAB_OP_COMPOSITOR) + break; + + display->overlay_key_only_pressed = FALSE; + + if ((window && + meta_grab_op_is_mouse (display->grab_op) && + (event->button.modifier_state & display->window_grab_modifiers) && + display->grab_button != (int) event->button.button && + display->grab_window == window) || + grab_op_is_keyboard (display->grab_op)) + { + meta_topic (META_DEBUG_WINDOW_OPS, + "Ending grab op %u on window %s due to button press\n", + display->grab_op, + (display->grab_window ? + display->grab_window->desc : + "none")); + if (GRAB_OP_IS_WINDOW_SWITCH (display->grab_op)) + { + meta_topic (META_DEBUG_WINDOW_OPS, + "Syncing to old stack positions.\n"); + + /* XXX: I'm not sure if this is the right thing to do. + The pre-Wayland code was only calling + meta_stack_set_positions if the modified window was a + root window */ + if (event->any.source == CLUTTER_ACTOR (event->any.stage) && window && window->screen) + meta_stack_set_positions (window->screen->stack, + display->grab_old_window_stacking); + } + meta_display_end_grab_op (display, + event->any.time); + } + else if (window && display->grab_op == META_GRAB_OP_NONE) + { + gboolean begin_move = FALSE; + ClutterModifierType grab_mask; + gboolean unmodified; + + grab_mask = display->window_grab_modifiers; + if (g_getenv ("MUTTER_DEBUG_BUTTON_GRABS")) + grab_mask |= CLUTTER_CONTROL_MASK; + + /* Two possible sources of an unmodified event; one is a + * client that's letting button presses pass through to the + * frame, the other is our focus_window_grab on unmodified + * button 1. So for all such events we focus the window. + */ + unmodified = (event->button.modifier_state & grab_mask) == 0; + + if (unmodified || + event->button.button == 1) + { + /* don't focus if frame received, will be lowered in + * frames.c or special-cased if the click was on a + * minimize/close button. + */ + if (!frame_was_receiver) + { + if (meta_prefs_get_raise_on_click ()) + meta_window_raise (window); + else + meta_topic (META_DEBUG_FOCUS, + "Not raising window on click due to don't-raise-on-click option\n"); + + /* Don't focus panels--they must explicitly request focus. + * See bug 160470 + */ + if (window->type != META_WINDOW_DOCK) + { + meta_topic (META_DEBUG_FOCUS, + "Focusing %s due to unmodified button %u press (display.c)\n", + window->desc, event->button.button); + meta_window_focus (window, event->any.time); + } + else + /* However, do allow terminals to lose focus due to new + * window mappings after the user clicks on a panel. + */ + display->allow_terminal_deactivation = TRUE; + } + + /* you can move on alt-click but not on + * the click-to-focus + */ + if (!unmodified) + begin_move = TRUE; + } + else if (!unmodified && ((int) event->button.button == meta_prefs_get_mouse_button_resize ())) + { + if (window->has_resize_func) + { + gboolean north, south; + gboolean west, east; + int root_x, root_y; + MetaGrabOp op; + + meta_window_get_position (window, &root_x, &root_y); + + west = event->button.x < (root_x + 1 * window->rect.width / 3); + east = event->button.x > (root_x + 2 * window->rect.width / 3); + north = event->button.y < (root_y + 1 * window->rect.height / 3); + south = event->button.y > (root_y + 2 * window->rect.height / 3); + + if (north && west) + op = META_GRAB_OP_RESIZING_NW; + else if (north && east) + op = META_GRAB_OP_RESIZING_NE; + else if (south && west) + op = META_GRAB_OP_RESIZING_SW; + else if (south && east) + op = META_GRAB_OP_RESIZING_SE; + else if (north) + op = META_GRAB_OP_RESIZING_N; + else if (west) + op = META_GRAB_OP_RESIZING_W; + else if (east) + op = META_GRAB_OP_RESIZING_E; + else if (south) + op = META_GRAB_OP_RESIZING_S; + else /* Middle region is no-op to avoid user triggering wrong action */ + op = META_GRAB_OP_NONE; + + if (op != META_GRAB_OP_NONE) + meta_display_begin_grab_op (display, + window->screen, + window, + op, + TRUE, + FALSE, + event->button.button, + 0, + event->any.time, + event->button.x, + event->button.y); + } + } + else if ((int) event->button.button == meta_prefs_get_mouse_button_menu ()) + { + if (meta_prefs_get_raise_on_click ()) + meta_window_raise (window); + meta_window_show_menu (window, + event->button.x, + event->button.y, + event->button.button, + event->any.time); + } + + if (!frame_was_receiver && unmodified) + { + /* This is from our synchronous grab since + * it has no modifiers and was on the client window + */ + + meta_verbose ("Allowing events time %u\n", + (unsigned int) event->any.time); + + /* XXX -- implement this in Wayland */ + XIAllowEvents (display->xdisplay, META_VIRTUAL_CORE_POINTER_ID, + XIReplayDevice, event->any.time); + } + + if (begin_move && window->has_move_func) + { + meta_display_begin_grab_op (display, + window->screen, + window, + META_GRAB_OP_MOVING, + TRUE, + FALSE, + event->button.button, + 0, + event->any.time, + event->button.x, + event->button.y); + } + } + break; + case CLUTTER_BUTTON_RELEASE: + if (display->grab_op == META_GRAB_OP_COMPOSITOR) + break; + + display->overlay_key_only_pressed = FALSE; + + if (display->grab_window == window && + meta_grab_op_is_mouse (display->grab_op)) + meta_window_handle_mouse_grab_op_event (window, event); + break; + case CLUTTER_MOTION: + if (display->grab_op == META_GRAB_OP_COMPOSITOR) + break; + + if (display->grab_window == window && + meta_grab_op_is_mouse (display->grab_op)) + meta_window_handle_mouse_grab_op_event (window, event); + break; + + default: + break; + } + + return FALSE; +} + static gboolean handle_input_xevent (MetaDisplay *display, XIEvent *input_event, gulong serial) { - XIDeviceEvent *device_event = (XIDeviceEvent *) input_event; XIEnterEvent *enter_event = (XIEnterEvent *) input_event; Window modified; MetaWindow *window; - gboolean frame_was_receiver; if (input_event == NULL) return FALSE; modified = xievent_get_modified_window (display, input_event); window = modified != None ? meta_display_lookup_x_window (display, modified) : NULL; - frame_was_receiver = (window && window->frame && modified == window->frame->xwindow); - if (window && !window->override_redirect && - ((input_event->type == XI_KeyPress) || (input_event->type == XI_ButtonPress))) + if (window && !window->override_redirect && input_event->type == XI_KeyPress) { if (CurrentTime == display->current_time) { @@ -2245,206 +2509,6 @@ handle_input_xevent (MetaDisplay *display, if (meta_display_process_key_event (display, window, (XIDeviceEvent *) input_event)) return TRUE; break; - 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 ((window && - meta_grab_op_is_mouse (display->grab_op) && - (device_event->mods.effective & display->window_grab_modifiers) && - display->grab_button != device_event->detail && - display->grab_window == window) || - grab_op_is_keyboard (display->grab_op)) - { - meta_topic (META_DEBUG_WINDOW_OPS, - "Ending grab op %u on window %s due to button press\n", - display->grab_op, - (display->grab_window ? - display->grab_window->desc : - "none")); - if (GRAB_OP_IS_WINDOW_SWITCH (display->grab_op)) - { - MetaScreen *screen; - meta_topic (META_DEBUG_WINDOW_OPS, - "Syncing to old stack positions.\n"); - screen = - meta_display_screen_for_root (display, device_event->event); - - if (screen!=NULL) - meta_stack_set_positions (screen->stack, - display->grab_old_window_stacking); - } - meta_display_end_grab_op (display, - device_event->time); - } - else if (window && display->grab_op == META_GRAB_OP_NONE) - { - gboolean begin_move = FALSE; - unsigned int grab_mask; - gboolean unmodified; - - grab_mask = display->window_grab_modifiers; - if (g_getenv ("MUTTER_DEBUG_BUTTON_GRABS")) - grab_mask |= ControlMask; - - /* Two possible sources of an unmodified event; one is a - * client that's letting button presses pass through to the - * frame, the other is our focus_window_grab on unmodified - * button 1. So for all such events we focus the window. - */ - unmodified = (device_event->mods.effective & grab_mask) == 0; - - if (unmodified || - device_event->detail == 1) - { - /* don't focus if frame received, will be lowered in - * frames.c or special-cased if the click was on a - * minimize/close button. - */ - if (!frame_was_receiver) - { - if (meta_prefs_get_raise_on_click ()) - meta_window_raise (window); - else - meta_topic (META_DEBUG_FOCUS, - "Not raising window on click due to don't-raise-on-click option\n"); - - /* Don't focus panels--they must explicitly request focus. - * See bug 160470 - */ - if (window->type != META_WINDOW_DOCK) - { - meta_topic (META_DEBUG_FOCUS, - "Focusing %s due to unmodified button %u press (display.c)\n", - window->desc, device_event->detail); - meta_window_focus (window, device_event->time); - } - else - /* However, do allow terminals to lose focus due to new - * window mappings after the user clicks on a panel. - */ - display->allow_terminal_deactivation = TRUE; - } - - /* you can move on alt-click but not on - * the click-to-focus - */ - if (!unmodified) - begin_move = TRUE; - } - else if (!unmodified && device_event->detail == meta_prefs_get_mouse_button_resize()) - { - if (window->has_resize_func) - { - gboolean north, south; - gboolean west, east; - int root_x, root_y; - MetaGrabOp op; - - meta_window_get_position (window, &root_x, &root_y); - - west = device_event->root_x < (root_x + 1 * window->rect.width / 3); - east = device_event->root_x > (root_x + 2 * window->rect.width / 3); - north = device_event->root_y < (root_y + 1 * window->rect.height / 3); - south = device_event->root_y > (root_y + 2 * window->rect.height / 3); - - if (north && west) - op = META_GRAB_OP_RESIZING_NW; - else if (north && east) - op = META_GRAB_OP_RESIZING_NE; - else if (south && west) - op = META_GRAB_OP_RESIZING_SW; - else if (south && east) - op = META_GRAB_OP_RESIZING_SE; - else if (north) - op = META_GRAB_OP_RESIZING_N; - else if (west) - op = META_GRAB_OP_RESIZING_W; - else if (east) - op = META_GRAB_OP_RESIZING_E; - else if (south) - op = META_GRAB_OP_RESIZING_S; - else /* Middle region is no-op to avoid user triggering wrong action */ - op = META_GRAB_OP_NONE; - - if (op != META_GRAB_OP_NONE) - meta_display_begin_grab_op (display, - window->screen, - window, - op, - TRUE, - FALSE, - device_event->detail, - 0, - device_event->time, - device_event->root_x, - device_event->root_y); - } - } - else if (device_event->detail == 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, - device_event->time); - } - - if (!frame_was_receiver && unmodified) - { - /* This is from our synchronous grab since - * it has no modifiers and was on the client window - */ - - meta_verbose ("Allowing events time %u\n", - (unsigned int)device_event->time); - - XIAllowEvents (display->xdisplay, device_event->deviceid, - XIReplayDevice, device_event->time); - } - - if (begin_move && window->has_move_func) - { - meta_display_begin_grab_op (display, - window->screen, - window, - META_GRAB_OP_MOVING, - TRUE, - FALSE, - device_event->detail, - 0, - device_event->time, - device_event->root_x, - device_event->root_y); - } - } - break; - case XI_ButtonRelease: - if (display->grab_op == META_GRAB_OP_COMPOSITOR) - break; - - display->overlay_key_only_pressed = FALSE; - - if (display->grab_window == window && - meta_grab_op_is_mouse (display->grab_op)) - meta_window_handle_mouse_grab_op_event (window, device_event); - break; - case XI_Motion: - if (display->grab_op == META_GRAB_OP_COMPOSITOR) - break; - - if (display->grab_window == window && - meta_grab_op_is_mouse (display->grab_op)) - meta_window_handle_mouse_grab_op_event (window, device_event); - break; case XI_Enter: if (display->grab_op == META_GRAB_OP_COMPOSITOR) break; @@ -3251,8 +3315,8 @@ meta_display_handle_xevent (MetaDisplay *display, } static gboolean -event_callback (XEvent *event, - gpointer data) +xevent_callback (XEvent *event, + gpointer data) { MetaDisplay *display = data; @@ -3274,6 +3338,15 @@ event_callback (XEvent *event, return meta_display_handle_xevent (display, event); } +static gboolean +event_callback (const ClutterEvent *event, + gpointer data) +{ + MetaDisplay *display = data; + + return meta_display_handle_event (display, event); +} + static Window xievent_get_modified_window (MetaDisplay *display, XIEvent *input_event) diff --git a/src/core/window-private.h b/src/core/window-private.h index c9e8e103f..8c125cdac 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -44,6 +44,7 @@ #include #include #include +#include #include "meta-wayland-types.h" typedef struct _MetaWindowQueue MetaWindowQueue; @@ -642,8 +643,8 @@ void meta_window_update_sync_request_counter (MetaWindow *window, gint64 new_counter_value); #endif /* HAVE_XSYNC */ -void meta_window_handle_mouse_grab_op_event (MetaWindow *window, - XIDeviceEvent *xev); +void meta_window_handle_mouse_grab_op_event (MetaWindow *window, + const ClutterEvent *event); GList* meta_window_get_workspaces (MetaWindow *window); diff --git a/src/core/window.c b/src/core/window.c index 97b41bad5..fd4ed51ce 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -63,6 +63,7 @@ #include #include "meta-wayland-private.h" +#include "meta/compositor-mutter.h" /* Windows that unmaximize to a size bigger than that fraction of the workarea * will be scaled down to that size (while maintaining aspect ratio). @@ -9899,96 +9900,20 @@ update_resize (MetaWindow *window, g_get_current_time (&window->display->grab_last_moveresize_time); } -typedef struct -{ - Window window; - int count; - guint32 last_time; -} EventScannerData; - -static Bool -find_last_time_predicate (Display *display, - XEvent *ev, - XPointer arg) -{ - EventScannerData *esd = (void*) arg; - XIEvent *xev; - - if (ev->type != GenericEvent) - return False; - - /* We are peeking into events not yet handled by GDK, - * Allocate cookie events here so we can handle XI2. - * - * GDK will handle later these events, and eventually - * free the cookie data itself. - */ - XGetEventData (display, &ev->xcookie); - xev = (XIEvent *) ev->xcookie.data; - - if (xev->evtype != XI_Motion) - return False; - - if (esd->window != ((XIDeviceEvent *) xev)->event) - return False; - - esd->count += 1; - esd->last_time = xev->time; - - return False; -} - static gboolean -check_use_this_motion_notify (MetaWindow *window, - XIDeviceEvent *xev) +check_use_this_motion_notify (MetaWindow *window, + const ClutterEvent *event) { - EventScannerData esd; - XEvent useless; - - /* This code is copied from Owen's GDK code. */ - - if (window->display->grab_motion_notify_time != 0) - { - /* == is really the right test, but I'm all for paranoia */ - if (window->display->grab_motion_notify_time <= - xev->time) - { - meta_topic (META_DEBUG_RESIZING, - "Arrived at event with time %u (waiting for %u), using it\n", - (unsigned int)xev->time, - window->display->grab_motion_notify_time); - window->display->grab_motion_notify_time = 0; - return TRUE; - } - else - return FALSE; /* haven't reached the saved timestamp yet */ - } - - esd.window = xev->event; - esd.count = 0; - esd.last_time = 0; - - /* "useless" isn't filled in because the predicate never returns True */ - XCheckIfEvent (window->display->xdisplay, - &useless, - find_last_time_predicate, - (XPointer) &esd); - - if (esd.count > 0) - meta_topic (META_DEBUG_RESIZING, - "Will skip %d motion events and use the event with time %u\n", - esd.count, (unsigned int) esd.last_time); - - if (esd.last_time == 0) - return TRUE; - else - { - /* Save this timestamp, and ignore all motion notify - * until we get to the one with this stamp. - */ - window->display->grab_motion_notify_time = esd.last_time; - return FALSE; - } + /* XXX: Previously this code would walk through the X event queue + and filter out motion events that are followed by a later motion + event. There currently isn't any API to do the equivalent + procedure with the Clutter event queue so this function does + nothing. Clutter does its own motion event squashing so it may be + the case that this function isn't necessary. If it turns out that + we do need additional motion event squashing we could add some + extra API to the Clutter event queue and implement this function + properly. */ + return TRUE; } static void @@ -10062,17 +9987,23 @@ meta_window_update_sync_request_counter (MetaWindow *window, #endif /* HAVE_XSYNC */ void -meta_window_handle_mouse_grab_op_event (MetaWindow *window, - XIDeviceEvent *xev) +meta_window_handle_mouse_grab_op_event (MetaWindow *window, + const ClutterEvent *event) { - switch (xev->evtype) + gboolean is_window_root = (event->any.stage != NULL && + window && + window->screen && + CLUTTER_ACTOR (event->any.stage) == + meta_get_stage_for_screen (window->screen)); + + switch (event->type) { - case XI_ButtonRelease: - if (xev->detail == 1) + case CLUTTER_BUTTON_RELEASE: + if (event->button.button == 1) { meta_display_check_threshold_reached (window->display, - xev->root_x, - xev->root_y); + event->button.x, + event->button.y); /* If the user was snap moving then ignore the button * release because they may have let go of shift before * releasing the mouse button and they almost certainly do @@ -10085,19 +10016,19 @@ meta_window_handle_mouse_grab_op_event (MetaWindow *window, { if (window->tile_mode != META_TILE_NONE) meta_window_tile (window); - else if (xev->root == window->screen->xroot) + else if (is_window_root) update_move (window, - xev->mods.effective & ShiftMask, - xev->root_x, - xev->root_y); + event->button.modifier_state & CLUTTER_SHIFT_MASK, + event->button.x, + event->button.y); } else if (meta_grab_op_is_resizing (window->display->grab_op)) { - if (xev->root == window->screen->xroot) + if (is_window_root) update_resize (window, - xev->mods.effective & ShiftMask, - xev->root_x, - xev->root_y, + event->button.modifier_state & CLUTTER_SHIFT_MASK, + event->button.x, + event->button.y, TRUE); /* If a tiled window has been dragged free with a @@ -10109,37 +10040,36 @@ meta_window_handle_mouse_grab_op_event (MetaWindow *window, */ update_tile_mode (window); } + + meta_display_end_grab_op (window->display, event->any.time); } - meta_display_end_grab_op (window->display, xev->time); } break; - case XI_Motion: + case CLUTTER_MOTION: meta_display_check_threshold_reached (window->display, - xev->root_x, - xev->root_y); + event->motion.x, + event->motion.y); if (meta_grab_op_is_moving (window->display->grab_op)) { - if (xev->root == window->screen->xroot) + if (is_window_root) { - if (check_use_this_motion_notify (window, - xev)) + if (check_use_this_motion_notify (window, event)) update_move (window, - xev->mods.effective & ShiftMask, - xev->root_x, - xev->root_y); + event->button.modifier_state & CLUTTER_SHIFT_MASK, + event->motion.x, + event->motion.y); } } else if (meta_grab_op_is_resizing (window->display->grab_op)) { - if (xev->root == window->screen->xroot) + if (is_window_root) { - if (check_use_this_motion_notify (window, - xev)) + if (check_use_this_motion_notify (window, event)) update_resize (window, - xev->mods.effective & ShiftMask, - xev->root_x, - xev->root_y, + event->button.modifier_state & CLUTTER_SHIFT_MASK, + event->motion.x, + event->motion.y, FALSE); } } From e6790038dd21a6c1dafab658cef6e24a77e2094f Mon Sep 17 00:00:00 2001 From: Neil Roberts Date: Thu, 5 Sep 2013 12:19:58 +0100 Subject: [PATCH 200/889] wayland: Use an event filter instead of the captured event signal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In order to see all Clutter events, Mutter was previously installing a signal handler on the ‘captured-event’ signal on the stage and additionally using a signal emission hook to cope with grabs. This changes it to use the new clutter_event_add_filter API so that we can avoid the signal emission hook hack. --- src/wayland/meta-wayland.c | 82 +++++--------------------------------- 1 file changed, 11 insertions(+), 71 deletions(-) diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index 6577923cc..4937b18be 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -654,6 +654,9 @@ reset_idletimes (const ClutterEvent *event) int device_id; device = clutter_event_get_device (event); + if (device == NULL) + return; + device_id = clutter_input_device_get_device_id (device); core_monitor = meta_idle_monitor_get_core (); @@ -672,10 +675,10 @@ reset_idletimes (const ClutterEvent *event) } static gboolean -event_cb (ClutterActor *stage, - const ClutterEvent *event, - MetaWaylandCompositor *compositor) +event_filter_cb (const ClutterEvent *event, + gpointer user_data) { + MetaWaylandCompositor *compositor = user_data; MetaWaylandSeat *seat = compositor->seat; MetaWaylandPointer *pointer = &seat->pointer; MetaWaylandSurface *surface; @@ -714,7 +717,8 @@ event_cb (ClutterActor *stage, if (pointer->current == NULL) meta_cursor_tracker_revert_root (seat->cursor_tracker); - meta_cursor_tracker_queue_redraw (seat->cursor_tracker, stage); + meta_cursor_tracker_queue_redraw (seat->cursor_tracker, + CLUTTER_ACTOR (event->any.stage)); } display = meta_get_display (); @@ -747,58 +751,6 @@ event_cb (ClutterActor *stage, } } -static gboolean -event_emission_hook_cb (GSignalInvocationHint *ihint, - guint n_param_values, - const GValue *param_values, - gpointer data) -{ - MetaWaylandCompositor *compositor = data; - ClutterActor *actor; - ClutterEvent *event; - - g_return_val_if_fail (n_param_values == 2, FALSE); - - actor = g_value_get_object (param_values + 0); - event = g_value_get_boxed (param_values + 1); - - if (actor == NULL) - return TRUE /* stay connected */; - - /* If this event belongs to the corresponding grab for this event - * type then the captured-event signal won't be emitted so we have - * to manually forward it on */ - - switch (event->type) - { - /* Pointer events */ - case CLUTTER_MOTION: - case CLUTTER_ENTER: - case CLUTTER_LEAVE: - case CLUTTER_BUTTON_PRESS: - case CLUTTER_BUTTON_RELEASE: - case CLUTTER_SCROLL: - if (actor == clutter_get_pointer_grab ()) - event_cb (clutter_actor_get_stage (actor), - event, - compositor); - break; - - /* Keyboard events */ - case CLUTTER_KEY_PRESS: - case CLUTTER_KEY_RELEASE: - if (actor == clutter_get_keyboard_grab ()) - event_cb (clutter_actor_get_stage (actor), - event, - compositor); - - default: - break; - } - - return TRUE /* stay connected */; -} - static void on_monitors_changed (MetaMonitorManager *monitors, MetaWaylandCompositor *compositor) @@ -839,7 +791,6 @@ void meta_wayland_init (void) { MetaWaylandCompositor *compositor = &_meta_wayland_compositor; - guint event_signal; MetaMonitorManager *monitors; ClutterBackend *backend; CoglContext *cogl_context; @@ -928,20 +879,7 @@ meta_wayland_init (void) compositor->seat = meta_wayland_seat_new (compositor->wayland_display, compositor->drm_fd >= 0); - g_signal_connect (compositor->stage, - "captured-event", - G_CALLBACK (event_cb), - compositor); - /* If something sets a grab on an actor then the captured event - * signal won't get emitted but we still want to see these events so - * we can update the cursor position. To make sure we see all events - * we also install an emission hook on the event signal */ - event_signal = g_signal_lookup ("event", CLUTTER_TYPE_STAGE); - g_signal_add_emission_hook (event_signal, - 0 /* detail */, - event_emission_hook_cb, - compositor, /* hook_data */ - NULL /* data_destroy */); + clutter_event_add_filter (event_filter_cb, compositor); meta_wayland_init_shell (compositor); @@ -979,6 +917,8 @@ meta_wayland_finalize (void) compositor = meta_wayland_compositor_get_default (); + clutter_event_remove_filter (event_filter_cb, compositor); + meta_xwayland_stop (compositor); g_clear_object (&compositor->launcher); } From 666e5f1f988c910f5b802ceb8e7e79918a8ba132 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 3 Oct 2013 18:03:53 -0400 Subject: [PATCH 201/889] keybindings: Port to Clutter --- src/core/display-private.h | 7 +- src/core/display.c | 56 +- src/core/keybindings-private.h | 10 +- src/core/keybindings.c | 913 ++++++++++++++++----------------- src/meta/common.h | 1 + src/meta/prefs.h | 14 +- 6 files changed, 461 insertions(+), 540 deletions(-) diff --git a/src/core/display-private.h b/src/core/display-private.h index a700a329e..c4e38d81d 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -474,10 +474,9 @@ void meta_display_queue_autoraise_callback (MetaDisplay *display, void meta_display_remove_autoraise_callback (MetaDisplay *display); void meta_display_overlay_key_activate (MetaDisplay *display); -void meta_display_accelerator_activate (MetaDisplay *display, - guint action, - guint deviceid, - guint timestamp); +void meta_display_accelerator_activate (MetaDisplay *display, + guint action, + ClutterKeyEvent *event); gboolean meta_display_modifiers_accelerator_activate (MetaDisplay *display); /* In above-tab-keycode.c */ diff --git a/src/core/display.c b/src/core/display.c index ed8f9db07..e301047a0 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -2234,7 +2234,8 @@ meta_display_handle_event (MetaDisplay *display, display->current_time = event->any.time; - if (window && !window->override_redirect && event->type == CLUTTER_BUTTON_PRESS) + if (window && !window->override_redirect && + (event->type == CLUTTER_KEY_PRESS || event->type == CLUTTER_BUTTON_PRESS)) { if (CurrentTime == display->current_time) { @@ -2454,6 +2455,17 @@ meta_display_handle_event (MetaDisplay *display, meta_window_handle_mouse_grab_op_event (window, event); break; + case CLUTTER_KEY_PRESS: + case CLUTTER_KEY_RELEASE: + /* For key events, it's important to enforce single-handling, or + * we can get into a confused state. So if a keybinding is + * handled (because it's one of our hot-keys, or because we are + * in a keyboard-grabbed mode like moving a window, we don't + * want to pass the key event to the compositor or GTK+ at all. + */ + if (meta_display_process_key_event (display, window, (ClutterKeyEvent *) event)) + return TRUE; + default: break; } @@ -2476,39 +2488,8 @@ handle_input_xevent (MetaDisplay *display, modified = xievent_get_modified_window (display, input_event); window = modified != None ? meta_display_lookup_x_window (display, modified) : NULL; - if (window && !window->override_redirect && input_event->type == XI_KeyPress) - { - if (CurrentTime == display->current_time) - { - /* We can't use missing (i.e. invalid) timestamps to set user time, - * nor do we want to use them to sanity check other timestamps. - * See bug 313490 for more details. - */ - meta_warning ("Event has no timestamp! You may be using a broken " - "program such as xse. Please ask the authors of that " - "program to fix it.\n"); - } - else - { - meta_window_set_user_time (window, display->current_time); - sanity_check_timestamps (display, display->current_time); - } - } - switch (input_event->evtype) { - case XI_KeyPress: - case XI_KeyRelease: - - /* For key events, it's important to enforce single-handling, or - * we can get into a confused state. So if a keybinding is - * handled (because it's one of our hot-keys, or because we are - * in a keyboard-grabbed mode like moving a window, we don't - * want to pass the key event to the compositor or GTK+ at all. - */ - if (meta_display_process_key_event (display, window, (XIDeviceEvent *) input_event)) - return TRUE; - break; case XI_Enter: if (display->grab_op == META_GRAB_OP_COMPOSITOR) break; @@ -6050,13 +6031,14 @@ meta_display_overlay_key_activate (MetaDisplay *display) } void -meta_display_accelerator_activate (MetaDisplay *display, - guint action, - guint deviceid, - guint timestamp) +meta_display_accelerator_activate (MetaDisplay *display, + guint action, + ClutterKeyEvent *event) { g_signal_emit (display, display_signals[ACCELERATOR_ACTIVATED], - 0, action, deviceid, timestamp); + 0, action, + clutter_input_device_get_device_id (event->device), + event->time); } gboolean diff --git a/src/core/keybindings-private.h b/src/core/keybindings-private.h index c47aacdc4..da36666fc 100644 --- a/src/core/keybindings-private.h +++ b/src/core/keybindings-private.h @@ -66,9 +66,9 @@ gboolean meta_window_grab_all_keys (MetaWindow *window, guint32 timestamp); void meta_window_ungrab_all_keys (MetaWindow *window, guint32 timestamp); -gboolean meta_display_process_key_event (MetaDisplay *display, - MetaWindow *window, - XIDeviceEvent *event); +gboolean meta_display_process_key_event (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event); void meta_display_process_mapping_event (MetaDisplay *display, XEvent *event); @@ -81,7 +81,3 @@ gboolean meta_prefs_remove_keybinding (const char *name); #endif - - - - diff --git a/src/core/keybindings.c b/src/core/keybindings.c index 226278dce..d6144f4f8 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -115,40 +115,35 @@ meta_key_binding_is_builtin (MetaKeyBinding *binding) * handler functions and have some kind of flag to say they're unbindable. */ -static void handle_workspace_switch (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XIDeviceEvent *event, - MetaKeyBinding *binding, - gpointer dummy); +static void handle_workspace_switch (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy); -static gboolean process_mouse_move_resize_grab (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XIDeviceEvent *event, - KeySym keysym); +static gboolean process_mouse_move_resize_grab (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + ClutterKeyEvent *event); -static gboolean process_keyboard_move_grab (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XIDeviceEvent *event, - KeySym keysym); +static gboolean process_keyboard_move_grab (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + ClutterKeyEvent *event); -static gboolean process_keyboard_resize_grab (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XIDeviceEvent *event, - KeySym keysym); +static gboolean process_keyboard_resize_grab (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + ClutterKeyEvent *event); -static gboolean process_tab_grab (MetaDisplay *display, - MetaScreen *screen, - XIDeviceEvent *event, - KeySym keysym); +static gboolean process_tab_grab (MetaDisplay *display, + MetaScreen *screen, + ClutterKeyEvent *event); -static gboolean process_workspace_switch_grab (MetaDisplay *display, - MetaScreen *screen, - XIDeviceEvent *event, - KeySym keysym); +static gboolean process_workspace_switch_grab (MetaDisplay *display, + MetaScreen *screen, + ClutterKeyEvent *event); static void grab_key_bindings (MetaDisplay *display); static void ungrab_key_bindings (MetaDisplay *display); @@ -1305,17 +1300,17 @@ meta_window_ungrab_keys (MetaWindow *window) } static void -handle_external_grab (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XIDeviceEvent *event, - MetaKeyBinding *binding, - gpointer user_data) +handle_external_grab (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer user_data) { guint action = meta_display_get_keybinding_action (display, binding->keycode, binding->mask); - meta_display_accelerator_activate (display, action, event->deviceid, event->time); + meta_display_accelerator_activate (display, action, event); } @@ -1802,13 +1797,12 @@ primary_modifier_still_pressed (MetaDisplay *display, } static void -invoke_handler (MetaDisplay *display, - MetaScreen *screen, - MetaKeyHandler *handler, - MetaWindow *window, - XIDeviceEvent *event, - MetaKeyBinding *binding) - +invoke_handler (MetaDisplay *display, + MetaScreen *screen, + MetaKeyHandler *handler, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding) { if (handler->func) (* handler->func) (display, screen, @@ -1827,11 +1821,11 @@ invoke_handler (MetaDisplay *display, } static void -invoke_handler_by_name (MetaDisplay *display, - MetaScreen *screen, - const char *handler_name, - MetaWindow *window, - XIDeviceEvent *event) +invoke_handler_by_name (MetaDisplay *display, + MetaScreen *screen, + const char *handler_name, + MetaWindow *window, + ClutterKeyEvent *event) { MetaKeyHandler *handler; @@ -1846,13 +1840,13 @@ process_event (MetaKeyBinding *bindings, MetaDisplay *display, MetaScreen *screen, MetaWindow *window, - XIDeviceEvent *event, + ClutterKeyEvent *event, gboolean on_window) { int i; /* we used to have release-based bindings but no longer. */ - if (event->evtype == XI_KeyRelease) + if (event->type == CLUTTER_KEY_RELEASE) return FALSE; /* @@ -1864,23 +1858,11 @@ process_event (MetaKeyBinding *bindings, MetaKeyHandler *handler = bindings[i].handler; if ((!on_window && handler->flags & META_KEY_BINDING_PER_WINDOW) || - bindings[i].keycode != event->detail || - ((event->mods.effective & 0xff & ~(display->ignored_modifier_mask)) != - bindings[i].mask) || + bindings[i].keycode != event->keyval || + (event->modifier_state != bindings[i].mask) || meta_compositor_filter_keybinding (display->compositor, screen, &bindings[i])) continue; - /* - * window must be non-NULL for on_window to be true, - * and so also window must be non-NULL if we get here and - * this is a META_KEY_BINDING_PER_WINDOW binding. - */ - - meta_topic (META_DEBUG_KEYBINDINGS, - "Binding keycode 0x%x mask 0x%x matches event 0x%x state 0x%x\n", - bindings[i].keycode, bindings[i].mask, - event->detail, event->mods.effective); - if (handler == NULL) meta_bug ("Binding %s has no handler\n", bindings[i].name); else @@ -1907,12 +1889,11 @@ process_event (MetaKeyBinding *bindings, static gboolean process_overlay_key (MetaDisplay *display, MetaScreen *screen, - XIDeviceEvent *event, - KeySym keysym) + ClutterKeyEvent *event) { if (display->overlay_key_only_pressed) { - if (event->detail != (int)display->overlay_key_combo.keycode) + if (event->hardware_keycode != (int)display->overlay_key_combo.keycode) { display->overlay_key_only_pressed = FALSE; @@ -1937,25 +1918,29 @@ process_overlay_key (MetaDisplay *display, * binding, we unfreeze the keyboard but keep the grab * (this is important for something like cycling * windows */ - XIAllowEvents (display->xdisplay, event->deviceid, + XIAllowEvents (display->xdisplay, + clutter_input_device_get_device_id (event->device), XIAsyncDevice, event->time); } else { /* Replay the event so it gets delivered to our * per-window key bindings or to the application */ - XIAllowEvents (display->xdisplay, event->deviceid, + XIAllowEvents (display->xdisplay, + clutter_input_device_get_device_id (event->device), XIReplayDevice, event->time); } } - else if (event->evtype == XI_KeyRelease) + else if (event->type == CLUTTER_KEY_RELEASE) { MetaKeyBinding *binding; display->overlay_key_only_pressed = FALSE; + /* We want to unfreeze events, but keep the grab so that if the user * starts typing into the overlay we get all the keys */ - XIAllowEvents (display->xdisplay, event->deviceid, + XIAllowEvents (display->xdisplay, + clutter_input_device_get_device_id (event->device), XIAsyncDevice, event->time); binding = display_get_keybinding (display, @@ -1981,19 +1966,21 @@ process_overlay_key (MetaDisplay *display, * * https://bugzilla.gnome.org/show_bug.cgi?id=666101 */ - XIAllowEvents (display->xdisplay, event->deviceid, + XIAllowEvents (display->xdisplay, + clutter_input_device_get_device_id (event->device), XIAsyncDevice, event->time); } return TRUE; } - else if (event->evtype == XI_KeyPress && - event->detail == (int)display->overlay_key_combo.keycode) + else if (event->type == CLUTTER_KEY_PRESS && + event->hardware_keycode == (int)display->overlay_key_combo.keycode) { display->overlay_key_only_pressed = TRUE; /* We keep the keyboard frozen - this allows us to use ReplayKeyboard * on the next event if it's not the release of the overlay key */ - XIAllowEvents (display->xdisplay, event->deviceid, + XIAllowEvents (display->xdisplay, + clutter_input_device_get_device_id (event->device), XISyncDevice, event->time); return TRUE; @@ -2005,29 +1992,27 @@ process_overlay_key (MetaDisplay *display, static gboolean process_iso_next_group (MetaDisplay *display, MetaScreen *screen, - XIDeviceEvent *event, - KeySym keysym) + ClutterKeyEvent *event) { gboolean activate; - unsigned int mods; int i; - if (event->evtype != XI_KeyPress) + if (event->type != CLUTTER_KEY_RELEASE) return FALSE; activate = FALSE; - mods = (event->mods.effective & 0xff & ~(display->ignored_modifier_mask)); for (i = 0; i < display->n_iso_next_group_combos; ++i) { - if (event->detail == (int)display->iso_next_group_combos[i].keycode && - mods == display->iso_next_group_combos[i].modifiers) + if (event->hardware_keycode == display->iso_next_group_combos[i].keycode && + event->modifier_state == (unsigned int)display->iso_next_group_combos[i].modifiers) { /* If the signal handler returns TRUE the keyboard will remain frozen. It's the signal handler's responsibility to unfreeze it. */ if (!meta_display_modifiers_accelerator_activate (display)) - XIAllowEvents (display->xdisplay, event->deviceid, + XIAllowEvents (display->xdisplay, + clutter_input_device_get_device_id (event->device), XIAsyncDevice, event->time); activate = TRUE; break; @@ -2052,57 +2037,34 @@ process_iso_next_group (MetaDisplay *display, * (and help us solve the other fixmes). */ gboolean -meta_display_process_key_event (MetaDisplay *display, - MetaWindow *window, - XIDeviceEvent *event) +meta_display_process_key_event (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event) { - KeySym keysym; gboolean keep_grab; gboolean all_keys_grabbed; gboolean handled; - const char *str; MetaScreen *screen; - /* if key event was on root window, we have a shortcut */ - screen = meta_display_screen_for_root (display, event->event); - - /* else round-trip to server */ - if (screen == NULL) - screen = meta_display_screen_for_xwindow (display, event->event); - - if (screen == NULL) - return FALSE; /* event window is destroyed */ - - /* ignore key events on popup menus and such. */ - if (meta_ui_window_is_widget (screen->ui, event->event)) - return FALSE; - /* window may be NULL */ - keysym = XKeycodeToKeysym (display->xdisplay, event->detail, 0); - - str = XKeysymToString (keysym); - - /* was topic */ - meta_topic (META_DEBUG_KEYBINDINGS, - "Processing key %s event, keysym: %s state: 0x%x window: %s\n", - event->evtype == XI_KeyPress ? "press" : "release", - str ? str : "none", event->mods.effective, - window ? window->desc : "(no window)"); + /* XXX */ + screen = display->active_screen; all_keys_grabbed = window ? window->all_keys_grabbed : screen->all_keys_grabbed; if (!all_keys_grabbed) { - handled = process_overlay_key (display, screen, event, keysym); + handled = process_overlay_key (display, screen, event); if (handled) return TRUE; - handled = process_iso_next_group (display, screen, event, keysym); + handled = process_iso_next_group (display, screen, event); if (handled) return TRUE; } - XIAllowEvents (display->xdisplay, event->deviceid, + XIAllowEvents (display->xdisplay, + clutter_input_device_get_device_id (event->device), XIAsyncDevice, event->time); keep_grab = TRUE; @@ -2131,16 +2093,14 @@ meta_display_process_key_event (MetaDisplay *display, meta_topic (META_DEBUG_KEYBINDINGS, "Processing event for mouse-only move/resize\n"); g_assert (window != NULL); - keep_grab = process_mouse_move_resize_grab (display, screen, - window, event, keysym); + keep_grab = process_mouse_move_resize_grab (display, screen, window, event); break; case META_GRAB_OP_KEYBOARD_MOVING: meta_topic (META_DEBUG_KEYBINDINGS, "Processing event for keyboard move\n"); g_assert (window != NULL); - keep_grab = process_keyboard_move_grab (display, screen, - window, event, keysym); + keep_grab = process_keyboard_move_grab (display, screen, window, event); break; case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN: @@ -2155,8 +2115,7 @@ meta_display_process_key_event (MetaDisplay *display, meta_topic (META_DEBUG_KEYBINDINGS, "Processing event for keyboard resize\n"); g_assert (window != NULL); - keep_grab = process_keyboard_resize_grab (display, screen, - window, event, keysym); + keep_grab = process_keyboard_resize_grab (display, screen, window, event); break; case META_GRAB_OP_KEYBOARD_TABBING_NORMAL: @@ -2167,13 +2126,13 @@ meta_display_process_key_event (MetaDisplay *display, case META_GRAB_OP_KEYBOARD_ESCAPING_GROUP: meta_topic (META_DEBUG_KEYBINDINGS, "Processing event for keyboard tabbing/cycling\n"); - keep_grab = process_tab_grab (display, screen, event, keysym); + keep_grab = process_tab_grab (display, screen, event); break; case META_GRAB_OP_KEYBOARD_WORKSPACE_SWITCHING: meta_topic (META_DEBUG_KEYBINDINGS, "Processing event for keyboard workspace switching\n"); - keep_grab = process_workspace_switch_grab (display, screen, event, keysym); + keep_grab = process_workspace_switch_grab (display, screen, event); break; default: @@ -2181,12 +2140,7 @@ meta_display_process_key_event (MetaDisplay *display, } } if (!keep_grab) - { - meta_topic (META_DEBUG_KEYBINDINGS, - "Ending grab op %u on key event sym %s\n", - display->grab_op, XKeysymToString (keysym)); - meta_display_end_grab_op (display, event->time); - } + meta_display_end_grab_op (display, event->time); return TRUE; } @@ -2199,17 +2153,16 @@ meta_display_process_key_event (MetaDisplay *display, } static gboolean -process_mouse_move_resize_grab (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XIDeviceEvent *event, - KeySym keysym) +process_mouse_move_resize_grab (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + ClutterKeyEvent *event) { /* don't care about releases, but eat them, don't end grab */ - if (event->evtype == XI_KeyRelease) + if (event->type == CLUTTER_KEY_RELEASE) return TRUE; - if (keysym == XK_Escape) + if (event->keyval == CLUTTER_KEY_Escape) { /* Hide the tiling preview if necessary */ if (window->tile_mode != META_TILE_NONE) @@ -2246,11 +2199,10 @@ process_mouse_move_resize_grab (MetaDisplay *display, } static gboolean -process_keyboard_move_grab (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XIDeviceEvent *event, - KeySym keysym) +process_keyboard_move_grab (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + ClutterKeyEvent *event) { gboolean handled; int x, y; @@ -2260,28 +2212,28 @@ process_keyboard_move_grab (MetaDisplay *display, handled = FALSE; /* don't care about releases, but eat them, don't end grab */ - if (event->evtype == XI_KeyRelease) + if (event->type == CLUTTER_KEY_RELEASE) return TRUE; /* don't end grab on modifier key presses */ - if (is_modifier (display, event->detail)) + if (is_modifier (display, event->hardware_keycode)) return TRUE; meta_window_get_position (window, &x, &y); - smart_snap = (event->mods.effective & ShiftMask) != 0; + smart_snap = (event->modifier_state & CLUTTER_SHIFT_MASK) != 0; #define SMALL_INCREMENT 1 #define NORMAL_INCREMENT 10 if (smart_snap) incr = 1; - else if (event->mods.effective & ControlMask) + else if (event->modifier_state & CLUTTER_CONTROL_MASK) incr = SMALL_INCREMENT; else incr = NORMAL_INCREMENT; - if (keysym == XK_Escape) + if (event->keyval == CLUTTER_KEY_Escape) { /* End move and restore to original state. If the window was a * maximized window that had been "shaken loose" we need to @@ -2306,37 +2258,37 @@ process_keyboard_move_grab (MetaDisplay *display, * Shift + arrow to snap is sort of a hidden feature. This way * people using just arrows shouldn't get too frustrated. */ - switch (keysym) + switch (event->keyval) { - case XK_KP_Home: - case XK_KP_Prior: - case XK_Up: - case XK_KP_Up: + case CLUTTER_KEY_KP_Home: + case CLUTTER_KEY_KP_Prior: + case CLUTTER_KEY_Up: + case CLUTTER_KEY_KP_Up: y -= incr; handled = TRUE; break; - case XK_KP_End: - case XK_KP_Next: - case XK_Down: - case XK_KP_Down: + case CLUTTER_KEY_KP_End: + case CLUTTER_KEY_KP_Next: + case CLUTTER_KEY_Down: + case CLUTTER_KEY_KP_Down: y += incr; handled = TRUE; break; } - switch (keysym) + switch (event->keyval) { - case XK_KP_Home: - case XK_KP_End: - case XK_Left: - case XK_KP_Left: + case CLUTTER_KEY_KP_Home: + case CLUTTER_KEY_KP_End: + case CLUTTER_KEY_Left: + case CLUTTER_KEY_KP_Left: x -= incr; handled = TRUE; break; - case XK_KP_Prior: - case XK_KP_Next: - case XK_Right: - case XK_KP_Right: + case CLUTTER_KEY_KP_Prior: + case CLUTTER_KEY_KP_Next: + case CLUTTER_KEY_Right: + case CLUTTER_KEY_KP_Right: x += incr; handled = TRUE; break; @@ -2368,11 +2320,10 @@ process_keyboard_move_grab (MetaDisplay *display, } static gboolean -process_keyboard_resize_grab_op_change (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XIDeviceEvent *event, - KeySym keysym) +process_keyboard_resize_grab_op_change (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + ClutterKeyEvent *event) { gboolean handled; @@ -2380,25 +2331,25 @@ process_keyboard_resize_grab_op_change (MetaDisplay *display, switch (display->grab_op) { case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN: - switch (keysym) + switch (event->keyval) { - case XK_Up: - case XK_KP_Up: + case CLUTTER_KEY_Up: + case CLUTTER_KEY_KP_Up: display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_N; handled = TRUE; break; - case XK_Down: - case XK_KP_Down: + case CLUTTER_KEY_Down: + case CLUTTER_KEY_KP_Down: display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_S; handled = TRUE; break; - case XK_Left: - case XK_KP_Left: + case CLUTTER_KEY_Left: + case CLUTTER_KEY_KP_Left: display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_W; handled = TRUE; break; - case XK_Right: - case XK_KP_Right: + case CLUTTER_KEY_Right: + case CLUTTER_KEY_KP_Right: display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_E; handled = TRUE; break; @@ -2406,15 +2357,15 @@ process_keyboard_resize_grab_op_change (MetaDisplay *display, break; case META_GRAB_OP_KEYBOARD_RESIZING_S: - switch (keysym) + switch (event->keyval) { - case XK_Left: - case XK_KP_Left: + case CLUTTER_KEY_Left: + case CLUTTER_KEY_KP_Left: display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_W; handled = TRUE; break; - case XK_Right: - case XK_KP_Right: + case CLUTTER_KEY_Right: + case CLUTTER_KEY_KP_Right: display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_E; handled = TRUE; break; @@ -2422,15 +2373,15 @@ process_keyboard_resize_grab_op_change (MetaDisplay *display, break; case META_GRAB_OP_KEYBOARD_RESIZING_N: - switch (keysym) + switch (event->keyval) { - case XK_Left: - case XK_KP_Left: + case CLUTTER_KEY_Left: + case CLUTTER_KEY_KP_Left: display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_W; handled = TRUE; break; - case XK_Right: - case XK_KP_Right: + case CLUTTER_KEY_Right: + case CLUTTER_KEY_KP_Right: display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_E; handled = TRUE; break; @@ -2438,15 +2389,15 @@ process_keyboard_resize_grab_op_change (MetaDisplay *display, break; case META_GRAB_OP_KEYBOARD_RESIZING_W: - switch (keysym) + switch (event->keyval) { - case XK_Up: - case XK_KP_Up: + case CLUTTER_KEY_Up: + case CLUTTER_KEY_KP_Up: display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_N; handled = TRUE; break; - case XK_Down: - case XK_KP_Down: + case CLUTTER_KEY_Down: + case CLUTTER_KEY_KP_Down: display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_S; handled = TRUE; break; @@ -2454,15 +2405,15 @@ process_keyboard_resize_grab_op_change (MetaDisplay *display, break; case META_GRAB_OP_KEYBOARD_RESIZING_E: - switch (keysym) + switch (event->keyval) { - case XK_Up: - case XK_KP_Up: + case CLUTTER_KEY_Up: + case CLUTTER_KEY_KP_Up: display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_N; handled = TRUE; break; - case XK_Down: - case XK_KP_Down: + case CLUTTER_KEY_Down: + case CLUTTER_KEY_KP_Down: display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_S; handled = TRUE; break; @@ -2490,11 +2441,10 @@ process_keyboard_resize_grab_op_change (MetaDisplay *display, } static gboolean -process_keyboard_resize_grab (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XIDeviceEvent *event, - KeySym keysym) +process_keyboard_resize_grab (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + ClutterKeyEvent *event) { gboolean handled; int height_inc; @@ -2506,14 +2456,14 @@ process_keyboard_resize_grab (MetaDisplay *display, handled = FALSE; /* don't care about releases, but eat them, don't end grab */ - if (event->evtype == XI_KeyRelease) + if (event->type == CLUTTER_KEY_RELEASE) return TRUE; /* don't end grab on modifier key presses */ - if (is_modifier (display, event->detail)) + if (is_modifier (display, event->hardware_keycode)) return TRUE; - if (keysym == XK_Escape) + if (event->keyval == CLUTTER_KEY_Escape) { /* End resize and restore to original state. */ meta_window_move_resize (display->grab_window, @@ -2526,8 +2476,7 @@ process_keyboard_resize_grab (MetaDisplay *display, return FALSE; } - if (process_keyboard_resize_grab_op_change (display, screen, window, - event, keysym)) + if (process_keyboard_resize_grab_op_change (display, screen, window, event)) return TRUE; width = window->rect.width; @@ -2535,7 +2484,7 @@ process_keyboard_resize_grab (MetaDisplay *display, gravity = meta_resize_gravity_from_grab_op (display->grab_op); - smart_snap = (event->mods.effective & ShiftMask) != 0; + smart_snap = (event->modifier_state & CLUTTER_SHIFT_MASK) != 0; #define SMALL_INCREMENT 1 #define NORMAL_INCREMENT 10 @@ -2545,7 +2494,7 @@ process_keyboard_resize_grab (MetaDisplay *display, height_inc = 1; width_inc = 1; } - else if (event->mods.effective & ControlMask) + else if (event->modifier_state & CLUTTER_CONTROL_MASK) { width_inc = SMALL_INCREMENT; height_inc = SMALL_INCREMENT; @@ -2564,10 +2513,10 @@ process_keyboard_resize_grab (MetaDisplay *display, if (window->size_hints.height_inc > 1) height_inc = window->size_hints.height_inc; - switch (keysym) + switch (event->keyval) { - case XK_Up: - case XK_KP_Up: + case CLUTTER_KEY_Up: + case CLUTTER_KEY_KP_Up: switch (gravity) { case NorthGravity: @@ -2594,8 +2543,8 @@ process_keyboard_resize_grab (MetaDisplay *display, handled = TRUE; break; - case XK_Down: - case XK_KP_Down: + case CLUTTER_KEY_Down: + case CLUTTER_KEY_KP_Down: switch (gravity) { case NorthGravity: @@ -2622,8 +2571,8 @@ process_keyboard_resize_grab (MetaDisplay *display, handled = TRUE; break; - case XK_Left: - case XK_KP_Left: + case CLUTTER_KEY_Left: + case CLUTTER_KEY_KP_Left: switch (gravity) { case EastGravity: @@ -2650,8 +2599,8 @@ process_keyboard_resize_grab (MetaDisplay *display, handled = TRUE; break; - case XK_Right: - case XK_KP_Right: + case CLUTTER_KEY_Right: + case CLUTTER_KEY_KP_Right: switch (gravity) { case EastGravity: @@ -2753,10 +2702,9 @@ end_keyboard_grab (MetaDisplay *display, } static gboolean -process_tab_grab (MetaDisplay *display, - MetaScreen *screen, - XIDeviceEvent *event, - KeySym keysym) +process_tab_grab (MetaDisplay *display, + MetaScreen *screen, + ClutterKeyEvent *event) { MetaKeyBinding *binding; MetaKeyBindingAction action; @@ -2769,8 +2717,8 @@ process_tab_grab (MetaDisplay *display, return FALSE; binding = display_get_keybinding (display, - keysym, - event->detail, + event->keyval, + event->hardware_keycode, display->grab_mask); if (binding) action = meta_prefs_get_keybinding_action (binding->name); @@ -2784,9 +2732,9 @@ process_tab_grab (MetaDisplay *display, */ if (!screen->tab_popup) { - if (event->evtype == XI_KeyRelease) + if (event->type == CLUTTER_KEY_RELEASE) { - if (end_keyboard_grab (display, event->detail)) + if (end_keyboard_grab (display, event->hardware_keycode)) { invoke_handler_by_name (display, screen, "tab-popup-select", NULL, event); @@ -2837,7 +2785,7 @@ process_tab_grab (MetaDisplay *display, * If this is simply user pressing the Shift key, we do not want * to cancel the grab. */ - if (is_modifier (display, event->detail)) + if (is_modifier (display, event->hardware_keycode)) return TRUE; } @@ -2850,8 +2798,8 @@ process_tab_grab (MetaDisplay *display, return FALSE; } - if (event->evtype == XI_KeyRelease && - end_keyboard_grab (display, event->detail)) + if (event->type == CLUTTER_KEY_RELEASE && + end_keyboard_grab (display, event->hardware_keycode)) { /* We're done, move to the new window. */ MetaWindow *target_window; @@ -2885,11 +2833,11 @@ process_tab_grab (MetaDisplay *display, } /* don't care about other releases, but eat them, don't end grab */ - if (event->evtype == XI_KeyRelease) + if (event->type == CLUTTER_KEY_RELEASE) return TRUE; /* don't end grab on modifier key presses */ - if (is_modifier (display, event->detail)) + if (is_modifier (display, event->hardware_keycode)) return TRUE; prev_window = meta_screen_tab_popup_get_selected (screen); @@ -3012,7 +2960,7 @@ process_tab_grab (MetaDisplay *display, meta_topic (META_DEBUG_KEYBINDINGS, "Key pressed, moving tab focus in popup\n"); - if (event->mods.effective & ShiftMask) + if (event->modifier_state & CLUTTER_SHIFT_MASK) backward = !backward; if (backward) @@ -3068,12 +3016,12 @@ process_tab_grab (MetaDisplay *display, } static void -handle_switch_to_workspace (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *event_window, - XIDeviceEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_switch_to_workspace (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *event_window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { gint which = binding->handler->data; MetaWorkspace *workspace; @@ -3109,12 +3057,12 @@ handle_switch_to_workspace (MetaDisplay *display, static void -handle_maximize_vertically (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XIDeviceEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_maximize_vertically (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { if (window->has_resize_func) { @@ -3126,12 +3074,12 @@ handle_maximize_vertically (MetaDisplay *display, } static void -handle_maximize_horizontally (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XIDeviceEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_maximize_horizontally (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { if (window->has_resize_func) { @@ -3190,100 +3138,100 @@ handle_move_to_corner_backend (MetaDisplay *display, } static void -handle_move_to_corner_nw (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XIDeviceEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_move_to_corner_nw (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { handle_move_to_corner_backend (display, screen, window, TRUE, TRUE, FALSE, FALSE, dummy); } static void -handle_move_to_corner_ne (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XIDeviceEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_move_to_corner_ne (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { handle_move_to_corner_backend (display, screen, window, TRUE, TRUE, TRUE, FALSE, dummy); } static void -handle_move_to_corner_sw (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XIDeviceEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_move_to_corner_sw (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { handle_move_to_corner_backend (display, screen, window, TRUE, TRUE, FALSE, TRUE, dummy); } static void -handle_move_to_corner_se (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XIDeviceEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_move_to_corner_se (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { handle_move_to_corner_backend (display, screen, window, TRUE, TRUE, TRUE, TRUE, dummy); } static void -handle_move_to_side_n (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XIDeviceEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_move_to_side_n (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { handle_move_to_corner_backend (display, screen, window, FALSE, TRUE, FALSE, FALSE, dummy); } static void -handle_move_to_side_s (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XIDeviceEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_move_to_side_s (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { handle_move_to_corner_backend (display, screen, window, FALSE, TRUE, FALSE, TRUE, dummy); } static void -handle_move_to_side_e (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XIDeviceEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_move_to_side_e (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { handle_move_to_corner_backend (display, screen, window, TRUE, FALSE, TRUE, FALSE, dummy); } static void -handle_move_to_side_w (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XIDeviceEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_move_to_side_w (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { handle_move_to_corner_backend (display, screen, window, TRUE, FALSE, FALSE, FALSE, dummy); } static void -handle_move_to_center (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XIDeviceEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_move_to_center (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { MetaRectangle work_area; MetaRectangle outer; @@ -3306,18 +3254,17 @@ handle_move_to_center (MetaDisplay *display, } static gboolean -process_workspace_switch_grab (MetaDisplay *display, - MetaScreen *screen, - XIDeviceEvent *event, - KeySym keysym) +process_workspace_switch_grab (MetaDisplay *display, + MetaScreen *screen, + ClutterKeyEvent *event) { MetaWorkspace *workspace; if (screen != display->grab_screen || !screen->ws_popup) return FALSE; - if (event->evtype == XI_KeyRelease && - end_keyboard_grab (display, event->detail)) + if (event->type == CLUTTER_KEY_RELEASE && + end_keyboard_grab (display, event->hardware_keycode)) { /* We're done, move to the new workspace. */ MetaWorkspace *target_workspace; @@ -3350,11 +3297,11 @@ process_workspace_switch_grab (MetaDisplay *display, } /* don't care about other releases, but eat them, don't end grab */ - if (event->evtype == XI_KeyRelease) + if (event->type == CLUTTER_KEY_RELEASE) return TRUE; /* don't end grab on modifier key presses */ - if (is_modifier (display, event->detail)) + if (is_modifier (display, event->hardware_keycode)) return TRUE; /* select the next workspace in the popup */ @@ -3366,7 +3313,7 @@ process_workspace_switch_grab (MetaDisplay *display, MetaKeyBindingAction action; action = meta_display_get_keybinding_action (display, - event->detail, + event->hardware_keycode, display->grab_mask); switch (action) @@ -3420,12 +3367,12 @@ process_workspace_switch_grab (MetaDisplay *display, } static void -handle_show_desktop (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XIDeviceEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_show_desktop (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { if (screen->active_workspace->showing_desktop) { @@ -3439,12 +3386,12 @@ handle_show_desktop (MetaDisplay *display, } static void -handle_panel (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XIDeviceEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_panel (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { MetaKeyBindingAction action = binding->handler->data; Atom action_atom; @@ -3472,7 +3419,7 @@ handle_panel (MetaDisplay *display, ev.data.l[1] = event->time; meta_topic (META_DEBUG_KEYBINDINGS, - "Sending panel message with timestamp %lu, and turning mouse_mode " + "Sending panel message with timestamp %u, and turning mouse_mode " "off due to keybinding press\n", event->time); display->mouse_mode = FALSE; @@ -3491,12 +3438,12 @@ handle_panel (MetaDisplay *display, } static void -handle_activate_window_menu (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *event_window, - XIDeviceEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_activate_window_menu (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *event_window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { if (display->focus_window) { @@ -3556,13 +3503,13 @@ cycle_op_from_tab_type (MetaTabList type) } static void -do_choose_window (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *event_window, - XIDeviceEvent *event, - MetaKeyBinding *binding, - gboolean backward, - gboolean show_popup) +do_choose_window (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *event_window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gboolean backward, + gboolean show_popup) { MetaTabList type = binding->handler->data; MetaWindow *initial_selection; @@ -3571,7 +3518,7 @@ do_choose_window (MetaDisplay *display, "Tab list = %u show_popup = %d\n", type, show_popup); /* reverse direction if shift is down */ - if (event->mods.effective & ShiftMask) + if (event->modifier_state & CLUTTER_SHIFT_MASK) backward = !backward; initial_selection = meta_display_get_tab_next (display, @@ -3660,12 +3607,12 @@ do_choose_window (MetaDisplay *display, } static void -handle_switch (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *event_window, - XIDeviceEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_switch (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *event_window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { gint backwards = (binding->handler->flags & META_KEY_BINDING_IS_REVERSED) != 0; @@ -3674,12 +3621,12 @@ handle_switch (MetaDisplay *display, } static void -handle_cycle (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *event_window, - XIDeviceEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_cycle (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *event_window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { gint backwards = (binding->handler->flags & META_KEY_BINDING_IS_REVERSED) != 0; @@ -3688,34 +3635,34 @@ handle_cycle (MetaDisplay *display, } static void -handle_tab_popup_select (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XIDeviceEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_tab_popup_select (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { /* Stub for custom handlers; no default implementation */ } static void -handle_tab_popup_cancel (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XIDeviceEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_tab_popup_cancel (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { /* Stub for custom handlers; no default implementation */ } static void -handle_toggle_fullscreen (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XIDeviceEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_toggle_fullscreen (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { if (window->fullscreen) meta_window_unmake_fullscreen (window); @@ -3724,12 +3671,12 @@ handle_toggle_fullscreen (MetaDisplay *display, } static void -handle_toggle_above (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XIDeviceEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_toggle_above (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { if (window->wm_state_above) meta_window_unmake_above (window); @@ -3738,12 +3685,12 @@ handle_toggle_above (MetaDisplay *display, } static void -handle_toggle_tiled (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XIDeviceEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_toggle_tiled (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { MetaTileMode mode = binding->handler->data; @@ -3778,12 +3725,12 @@ handle_toggle_tiled (MetaDisplay *display, } static void -handle_toggle_maximized (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XIDeviceEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_toggle_maximized (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { if (META_WINDOW_MAXIMIZED (window)) meta_window_unmaximize (window, @@ -3796,12 +3743,12 @@ handle_toggle_maximized (MetaDisplay *display, } static void -handle_maximize (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XIDeviceEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_maximize (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { if (window->has_maximize_func) meta_window_maximize (window, @@ -3810,12 +3757,12 @@ handle_maximize (MetaDisplay *display, } static void -handle_unmaximize (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XIDeviceEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_unmaximize (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { if (window->maximized_vertically || window->maximized_horizontally) meta_window_unmaximize (window, @@ -3824,12 +3771,12 @@ handle_unmaximize (MetaDisplay *display, } static void -handle_toggle_shaded (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XIDeviceEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_toggle_shaded (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { if (window->shaded) meta_window_unshade (window, event->time); @@ -3838,36 +3785,36 @@ handle_toggle_shaded (MetaDisplay *display, } static void -handle_close (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XIDeviceEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_close (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { if (window->has_close_func) meta_window_delete (window, event->time); } static void -handle_minimize (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XIDeviceEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_minimize (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { if (window->has_minimize_func) meta_window_minimize (window); } static void -handle_begin_move (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XIDeviceEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_begin_move (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { if (window->has_move_func) { @@ -3879,12 +3826,12 @@ handle_begin_move (MetaDisplay *display, } static void -handle_begin_resize (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XIDeviceEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_begin_resize (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { if (window->has_resize_func) { @@ -3896,12 +3843,12 @@ handle_begin_resize (MetaDisplay *display, } static void -handle_toggle_on_all_workspaces (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XIDeviceEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_toggle_on_all_workspaces (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { if (window->on_all_workspaces_requested) meta_window_unstick (window); @@ -3910,12 +3857,12 @@ handle_toggle_on_all_workspaces (MetaDisplay *display, } static void -handle_move_to_workspace (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XIDeviceEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_move_to_workspace (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { gint which = binding->handler->data; gboolean flip = (which < 0); @@ -3965,12 +3912,12 @@ handle_move_to_workspace (MetaDisplay *display, } static void -handle_raise_or_lower (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XIDeviceEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_raise_or_lower (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { /* Get window at pointer */ @@ -4012,37 +3959,36 @@ handle_raise_or_lower (MetaDisplay *display, } static void -handle_raise (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XIDeviceEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_raise (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { meta_window_raise (window); } static void -handle_lower (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XIDeviceEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_lower (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { meta_window_lower (window); } static void -handle_workspace_switch (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XIDeviceEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_workspace_switch (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { gint motion = binding->handler->data; - unsigned int grab_mask; MetaWorkspace *next; gboolean grabbed_before_release; @@ -4051,9 +3997,6 @@ handle_workspace_switch (MetaDisplay *display, meta_topic (META_DEBUG_KEYBINDINGS, "Starting tab between workspaces, showing popup\n"); - /* FIXME should we use binding->mask ? */ - grab_mask = event->mods.effective & ~(display->ignored_modifier_mask); - if (!meta_display_begin_grab_op (display, screen, NULL, @@ -4061,7 +4004,7 @@ handle_workspace_switch (MetaDisplay *display, FALSE, FALSE, 0, - grab_mask, + event->modifier_state, event->time, 0, 0)) return; @@ -4069,7 +4012,7 @@ handle_workspace_switch (MetaDisplay *display, next = meta_workspace_get_neighbor (screen->active_workspace, motion); g_assert (next); - grabbed_before_release = primary_modifier_still_pressed (display, grab_mask); + grabbed_before_release = primary_modifier_still_pressed (display, event->modifier_state); meta_topic (META_DEBUG_KEYBINDINGS, "Activating target workspace\n"); @@ -4090,24 +4033,24 @@ handle_workspace_switch (MetaDisplay *display, } static void -handle_set_spew_mark (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XIDeviceEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_set_spew_mark (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { meta_verbose ("-- MARK MARK MARK MARK --\n"); } #ifdef HAVE_WAYLAND static void -handle_switch_vt (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XIDeviceEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_switch_vt (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { gint vt = binding->handler->data; MetaWaylandCompositor *compositor; diff --git a/src/meta/common.h b/src/meta/common.h index 01c259773..e9fe62990 100644 --- a/src/meta/common.h +++ b/src/meta/common.h @@ -31,6 +31,7 @@ #include #include #include +#include #include #include diff --git a/src/meta/prefs.h b/src/meta/prefs.h index e772e7514..e98b4174a 100644 --- a/src/meta/prefs.h +++ b/src/meta/prefs.h @@ -391,17 +391,17 @@ struct _MetaKeyCombo * @display: a #MetaDisplay * @screen: a #MetaScreen * @window: a #MetaWindow - * @event: (type gpointer): a #XIDeviceEvent + * @event: a #ClutterKeyEvent * @binding: a #MetaKeyBinding * @user_data: data passed to the function * */ -typedef void (* MetaKeyHandlerFunc) (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XIDeviceEvent *event, - MetaKeyBinding *binding, - gpointer user_data); +typedef void (* MetaKeyHandlerFunc) (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer user_data); typedef struct _MetaKeyHandler MetaKeyHandler; From 875bbec949cc5a6d148f2a4b3cd91a546bdd7bae Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 3 Oct 2013 23:47:10 -0400 Subject: [PATCH 202/889] wayland: Drop old hack to synthesize motion events mutter now uses Clutter events for the source of its drag support, so we don't need to synthesize X11 events anymore. --- src/core/display.c | 15 --- src/wayland/meta-wayland-pointer.h | 1 - src/wayland/meta-wayland-private.h | 8 -- src/wayland/meta-wayland-seat.c | 18 ---- src/wayland/meta-wayland-surface.c | 3 - src/wayland/meta-wayland.c | 143 +---------------------------- 6 files changed, 1 insertion(+), 187 deletions(-) diff --git a/src/core/display.c b/src/core/display.c index e301047a0..67e3cc4cc 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -3301,21 +3301,6 @@ xevent_callback (XEvent *event, { MetaDisplay *display = data; - /* Under Wayland we want to filter out mouse motion events so we can - synthesize them from the Clutter events instead. This is - necessary because the position in the mouse events is passed to - the X server relative to the position of the surface. The X - server then translates these back to screen coordinates based on - the window position. If we rely on this translatation when - dragging a window around then the window will jump around - erratically because of the lag between updating the window - position from the surface position. Instead we bypass the - translation altogether by directly using the Clutter events */ - if (meta_is_wayland_compositor () && - event->type == GenericEvent && - event->xcookie.evtype == XI_Motion) - return FALSE; - return meta_display_handle_xevent (display, event); } diff --git a/src/wayland/meta-wayland-pointer.h b/src/wayland/meta-wayland-pointer.h index e25b0082f..bdbf1a383 100644 --- a/src/wayland/meta-wayland-pointer.h +++ b/src/wayland/meta-wayland-pointer.h @@ -62,7 +62,6 @@ struct _MetaWaylandPointer wl_fixed_t x, y; /* TODO: remove, use ClutterInputDevice instead */ MetaWaylandSurface *current; - wl_fixed_t current_x, current_y; guint32 button_count; }; diff --git a/src/wayland/meta-wayland-private.h b/src/wayland/meta-wayland-private.h index e7917e6d8..0875fa700 100644 --- a/src/wayland/meta-wayland-private.h +++ b/src/wayland/meta-wayland-private.h @@ -83,14 +83,6 @@ struct _MetaWaylandCompositor int drm_fd; MetaWaylandSeat *seat; - - /* This surface is only used to keep drag of the implicit grab when - synthesizing XEvents for Mutter */ - MetaWaylandSurface *implicit_grab_surface; - /* Button that was pressed to initiate an implicit grab. The - implicit grab will only be released when this button is - released */ - guint32 implicit_grab_button; }; void meta_wayland_init (void); diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c index 2a0b16f1f..84db89c54 100644 --- a/src/wayland/meta-wayland-seat.c +++ b/src/wayland/meta-wayland-seat.c @@ -409,20 +409,6 @@ meta_wayland_seat_handle_event (MetaWaylandSeat *seat, return FALSE; } -static void -update_pointer_position_for_actor (MetaWaylandPointer *pointer, - ClutterActor *actor) -{ - float ax, ay; - - clutter_actor_transform_stage_point (actor, - wl_fixed_to_double (pointer->x), - wl_fixed_to_double (pointer->y), - &ax, &ay); - pointer->current_x = wl_fixed_from_double (ax); - pointer->current_y = wl_fixed_from_double (ay); -} - /* The actor argument can be NULL in which case a Clutter pick will be performed to determine the right actor. An actor should only be passed if the repick is being performed due to an event in which @@ -459,16 +445,12 @@ meta_wayland_seat_repick (MetaWaylandSeat *seat, MetaWindow *window = meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor)); - update_pointer_position_for_actor (pointer, actor); - surface = window->surface; } else if (META_IS_SHAPED_TEXTURE (actor)) { MetaShapedTexture *shaped_texture = META_SHAPED_TEXTURE (actor); - update_pointer_position_for_actor (pointer, actor); - surface = meta_shaped_texture_get_wayland_surface (shaped_texture); } diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index a754ea058..c283b652e 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -444,9 +444,6 @@ meta_wayland_surface_free (MetaWaylandSurface *surface) g_assert (surface != compositor->seat->pointer.focus); } - if (compositor->implicit_grab_surface == surface) - compositor->implicit_grab_surface = compositor->seat->pointer.current; - if (surface->resource) wl_resource_set_user_data (surface->resource, NULL); g_slice_free (MetaWaylandSurface, surface); diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index 4937b18be..d32a8687e 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -533,119 +533,6 @@ stage_destroy_cb (void) meta_quit (META_EXIT_SUCCESS); } -#define N_BUTTONS 5 - -static void -synthesize_motion_event (MetaWaylandCompositor *compositor, - const ClutterEvent *event) -{ - /* We want to synthesize X events for mouse motion events so that we - don't have to rely on the X server's window position being - synched with the surface position. See the comment in - event_callback() in display.c */ - MetaWaylandSeat *seat = compositor->seat; - MetaWaylandPointer *pointer = &seat->pointer; - MetaWaylandSurface *surface; - XGenericEventCookie generic_event; - XIDeviceEvent device_event; - unsigned char button_mask[(N_BUTTONS + 7) / 8] = { 0 }; - MetaDisplay *display = meta_get_display (); - ClutterModifierType button_state; - int i; - - generic_event.type = GenericEvent; - generic_event.serial = 0; - generic_event.send_event = False; - generic_event.display = display->xdisplay; - generic_event.extension = display->xinput_opcode; - generic_event.evtype = XI_Motion; - /* Mutter assumes the data for the event is already retrieved by GDK - * so we don't need the cookie */ - generic_event.cookie = 0; - generic_event.data = &device_event; - - memcpy (&device_event, &generic_event, sizeof (XGenericEvent)); - - device_event.time = clutter_event_get_time (event); - device_event.deviceid = clutter_event_get_device_id (event); - device_event.sourceid = 0; /* not used, not sure what this should be */ - device_event.detail = 0; - device_event.root = DefaultRootWindow (display->xdisplay); - device_event.flags = 0 /* not used for motion events */; - - if (compositor->implicit_grab_surface) - surface = compositor->implicit_grab_surface; - else - surface = pointer->current; - - if (surface == pointer->current) - { - device_event.event_x = wl_fixed_to_int (pointer->current_x); - device_event.event_y = wl_fixed_to_int (pointer->current_y); - } - else if (surface && surface->window) - { - ClutterActor *window_actor = - CLUTTER_ACTOR (meta_window_get_compositor_private (surface->window)); - - if (window_actor) - { - float ax, ay; - - clutter_actor_transform_stage_point (window_actor, - wl_fixed_to_double (pointer->x), - wl_fixed_to_double (pointer->y), - &ax, &ay); - - device_event.event_x = ax; - device_event.event_y = ay; - } - else - { - device_event.event_x = wl_fixed_to_double (pointer->x); - device_event.event_y = wl_fixed_to_double (pointer->y); - } - } - else - { - device_event.event_x = wl_fixed_to_double (pointer->x); - device_event.event_y = wl_fixed_to_double (pointer->y); - } - - if (surface && surface->window != NULL) - device_event.event = surface->window->xwindow; - else - device_event.event = device_event.root; - - /* Mutter doesn't really know about the sub-windows. This assumes it - doesn't care either */ - device_event.child = device_event.event; - device_event.root_x = wl_fixed_to_double (pointer->x); - device_event.root_y = wl_fixed_to_double (pointer->y); - - clutter_event_get_state_full (event, - &button_state, - (ClutterModifierType*)&device_event.mods.base, - (ClutterModifierType*)&device_event.mods.latched, - (ClutterModifierType*)&device_event.mods.locked, - (ClutterModifierType*)&device_event.mods.effective); - device_event.mods.effective &= ~button_state; - memset (&device_event.group, 0, sizeof (device_event.group)); - device_event.group.effective = (device_event.mods.effective >> 13) & 0x3; - - for (i = 0; i < N_BUTTONS; i++) - if ((button_state & (CLUTTER_BUTTON1_MASK << i))) - XISetMask (button_mask, i + 1); - device_event.buttons.mask_len = N_BUTTONS + 1; - device_event.buttons.mask = button_mask; - - device_event.valuators.mask_len = 0; - device_event.valuators.mask = NULL; - device_event.valuators.values = NULL; - - meta_display_handle_xevent (display, (XEvent *) &generic_event); -} - static void reset_idletimes (const ClutterEvent *event) { @@ -682,7 +569,6 @@ event_filter_cb (const ClutterEvent *event, MetaWaylandSeat *seat = compositor->seat; MetaWaylandPointer *pointer = &seat->pointer; MetaWaylandSurface *surface; - MetaDisplay *display; reset_idletimes (event); @@ -721,34 +607,7 @@ event_filter_cb (const ClutterEvent *event, CLUTTER_ACTOR (event->any.stage)); } - display = meta_get_display (); - if (!display) - return FALSE; - - switch (event->type) - { - case CLUTTER_BUTTON_PRESS: - if (compositor->implicit_grab_surface == NULL) - { - compositor->implicit_grab_button = event->button.button; - compositor->implicit_grab_surface = pointer->current; - } - return FALSE; - - case CLUTTER_BUTTON_RELEASE: - if (event->type == CLUTTER_BUTTON_RELEASE && - compositor->implicit_grab_surface && - event->button.button == compositor->implicit_grab_button) - compositor->implicit_grab_surface = NULL; - return FALSE; - - case CLUTTER_MOTION: - synthesize_motion_event (compositor, event); - return FALSE; - - default: - return FALSE; - } + return FALSE; } static void From 153463790abfa9fbe8f77694cf6a46f9b5e1f586 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 4 Oct 2013 02:20:43 -0400 Subject: [PATCH 203/889] wayland: Drop focus on click The native raise-on-click works with Wayland clients through the standard Grand Central Station event handling, with MetaWindow. --- src/wayland/meta-wayland.c | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index d32a8687e..6351e4878 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -568,32 +568,12 @@ event_filter_cb (const ClutterEvent *event, MetaWaylandCompositor *compositor = user_data; MetaWaylandSeat *seat = compositor->seat; MetaWaylandPointer *pointer = &seat->pointer; - MetaWaylandSurface *surface; reset_idletimes (event); if (meta_wayland_seat_handle_event (compositor->seat, event)) return TRUE; - /* HACK: for now, the surfaces from Wayland clients aren't - integrated into Mutter's event handling and Mutter won't give them - focus on mouse clicks. As a hack to work around this we can just - give them input focus on mouse clicks so we can at least test the - keyboard support */ - if (event->type == CLUTTER_BUTTON_PRESS) - { - surface = pointer->current; - - if (surface && surface->window && - surface->window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND) - { - MetaDisplay *display = meta_get_display (); - guint32 timestamp = meta_display_get_current_time_roundtrip (display); - - meta_window_focus (surface->window, timestamp); - } - } - if (seat->cursor_tracker) { meta_cursor_tracker_update_position (seat->cursor_tracker, From b7b95123ed88f73ffb9e33109202d4f524be6dba Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 16 Oct 2013 00:06:45 -0400 Subject: [PATCH 204/889] wayland: Drop raise on click too We'll handle this through GCD as well. --- src/wayland/meta-wayland-seat.c | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c index 84db89c54..259de37ae 100644 --- a/src/wayland/meta-wayland-seat.c +++ b/src/wayland/meta-wayland-seat.c @@ -281,29 +281,16 @@ handle_button_event (MetaWaylandSeat *seat, { MetaWaylandPointer *pointer = &seat->pointer; gboolean implicit_grab; - uint32_t button; - MetaWaylandSurface *surface; notify_motion (seat, event); implicit_grab = (event->type == CLUTTER_BUTTON_PRESS) && (pointer->button_count == 1); if (implicit_grab) { - button = clutter_event_get_button (event); - pointer->grab_button = button; + pointer->grab_button = clutter_event_get_button (event); pointer->grab_time = clutter_event_get_time (event); pointer->grab_x = pointer->x; pointer->grab_y = pointer->y; - - /* FIXME: synth a XI2 event and handle in display.c */ - surface = pointer->current; - if (button == CLUTTER_BUTTON_PRIMARY && - surface && - surface->window && - surface->window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND) - { - meta_window_raise (surface->window); - } } pointer->grab->interface->button (pointer->grab, event); From 6cc014a941b0d14ae6916baab731841cf208c5b9 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 4 Oct 2013 02:33:10 -0400 Subject: [PATCH 205/889] wayland: Move cursor tracker handling code to meta_wayland_seat_handle_event --- src/wayland/meta-wayland-seat.c | 13 +++++++++++++ src/wayland/meta-wayland.c | 19 +------------------ 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c index 259de37ae..ef404faf9 100644 --- a/src/wayland/meta-wayland-seat.c +++ b/src/wayland/meta-wayland-seat.c @@ -369,6 +369,19 @@ meta_wayland_seat_handle_event (MetaWaylandSeat *seat, { seat->pointer.button_count = count_buttons (event); + if (seat->cursor_tracker) + { + meta_cursor_tracker_update_position (seat->cursor_tracker, + wl_fixed_to_int (seat->pointer.x), + wl_fixed_to_int (seat->pointer.y)); + + if (seat->pointer.current == NULL) + meta_cursor_tracker_revert_root (seat->cursor_tracker); + + meta_cursor_tracker_queue_redraw (seat->cursor_tracker, + CLUTTER_ACTOR (event->any.stage)); + } + switch (event->type) { case CLUTTER_MOTION: diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index 6351e4878..eda618adc 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -567,27 +567,10 @@ event_filter_cb (const ClutterEvent *event, { MetaWaylandCompositor *compositor = user_data; MetaWaylandSeat *seat = compositor->seat; - MetaWaylandPointer *pointer = &seat->pointer; reset_idletimes (event); - if (meta_wayland_seat_handle_event (compositor->seat, event)) - return TRUE; - - if (seat->cursor_tracker) - { - meta_cursor_tracker_update_position (seat->cursor_tracker, - wl_fixed_to_int (pointer->x), - wl_fixed_to_int (pointer->y)); - - if (pointer->current == NULL) - meta_cursor_tracker_revert_root (seat->cursor_tracker); - - meta_cursor_tracker_queue_redraw (seat->cursor_tracker, - CLUTTER_ACTOR (event->any.stage)); - } - - return FALSE; + return meta_wayland_seat_handle_event (compositor->seat, event); } static void From 648639fffe4573ae8fc93add9e5565b6faaf23a1 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 4 Oct 2013 02:29:43 -0400 Subject: [PATCH 206/889] display: Invoke Wayland from the Grand Central Station callback --- src/core/display.c | 15 +++++++++++++-- src/wayland/meta-wayland-private.h | 2 ++ src/wayland/meta-wayland.c | 13 +++---------- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/core/display.c b/src/core/display.c index 67e3cc4cc..deb20561e 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -2461,7 +2461,7 @@ meta_display_handle_event (MetaDisplay *display, * we can get into a confused state. So if a keybinding is * handled (because it's one of our hot-keys, or because we are * in a keyboard-grabbed mode like moving a window, we don't - * want to pass the key event to the compositor or GTK+ at all. + * want to pass the key event to the compositor or Wayland at all. */ if (meta_display_process_key_event (display, window, (ClutterKeyEvent *) event)) return TRUE; @@ -2470,7 +2470,18 @@ meta_display_handle_event (MetaDisplay *display, break; } - return FALSE; +#ifdef HAVE_WAYLAND + if (meta_is_wayland_compositor () && (display->grab_op == META_GRAB_OP_NONE)) + { + MetaWaylandCompositor *compositor; + compositor = meta_wayland_compositor_get_default (); + + if (meta_wayland_compositor_handle_event (compositor, event)) + return TRUE; + } +#endif /* HAVE_WAYLAND */ + + return (display->grab_op != META_GRAB_OP_COMPOSITOR); } static gboolean diff --git a/src/wayland/meta-wayland-private.h b/src/wayland/meta-wayland-private.h index 0875fa700..140ce63cf 100644 --- a/src/wayland/meta-wayland-private.h +++ b/src/wayland/meta-wayland-private.h @@ -96,6 +96,8 @@ void meta_wayland_compositor_repick (MetaWaylandComp void meta_wayland_compositor_set_input_focus (MetaWaylandCompositor *compositor, MetaWindow *window); +gboolean meta_wayland_compositor_handle_event (MetaWaylandCompositor *compositor, + const ClutterEvent *event); MetaLauncher *meta_wayland_compositor_get_launcher (MetaWaylandCompositor *compositor); gboolean meta_wayland_compositor_is_native (MetaWaylandCompositor *compositor); diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index eda618adc..ce80bfd87 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -561,13 +561,10 @@ reset_idletimes (const ClutterEvent *event) } } -static gboolean -event_filter_cb (const ClutterEvent *event, - gpointer user_data) +gboolean +meta_wayland_compositor_handle_event (MetaWaylandCompositor *compositor, + const ClutterEvent *event) { - MetaWaylandCompositor *compositor = user_data; - MetaWaylandSeat *seat = compositor->seat; - reset_idletimes (event); return meta_wayland_seat_handle_event (compositor->seat, event); @@ -701,8 +698,6 @@ meta_wayland_init (void) compositor->seat = meta_wayland_seat_new (compositor->wayland_display, compositor->drm_fd >= 0); - clutter_event_add_filter (event_filter_cb, compositor); - meta_wayland_init_shell (compositor); clutter_actor_show (compositor->stage); @@ -739,8 +734,6 @@ meta_wayland_finalize (void) compositor = meta_wayland_compositor_get_default (); - clutter_event_remove_filter (event_filter_cb, compositor); - meta_xwayland_stop (compositor); g_clear_object (&compositor->launcher); } From 08df9bf5590deb93485bf62a2d97a1a1b67bb0be Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 16 Oct 2013 00:19:33 -0400 Subject: [PATCH 207/889] display: Use MetaWindow for auto-raise callbacks This allows us to autoraise Wayland windows... well, except for the XQueryPointer, but we'll replace that soon. --- src/core/display.c | 34 ++++------------------------------ src/core/window.c | 2 ++ 2 files changed, 6 insertions(+), 30 deletions(-) diff --git a/src/core/display.c b/src/core/display.c index deb20561e..c7e86b228 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -117,12 +117,6 @@ typedef struct guint ping_timeout_id; } MetaPingData; -typedef struct -{ - MetaDisplay *display; - Window xwindow; -} MetaAutoRaiseData; - typedef struct { MetaDisplay *display; @@ -1620,23 +1614,10 @@ reset_ignored_crossing_serials (MetaDisplay *display) static gboolean window_raise_with_delay_callback (void *data) { - MetaWindow *window; - MetaAutoRaiseData *auto_raise; + MetaWindow *window = data; - auto_raise = data; - - meta_topic (META_DEBUG_FOCUS, - "In autoraise callback for window 0x%lx\n", - auto_raise->xwindow); - - auto_raise->display->autoraise_timeout_id = 0; - auto_raise->display->autoraise_window = NULL; - - window = meta_display_lookup_x_window (auto_raise->display, - auto_raise->xwindow); - - if (window == NULL) - return FALSE; + window->display->autoraise_timeout_id = 0; + window->display->autoraise_window = NULL; /* If we aren't already on top, check whether the pointer is inside * the window and raise the window if so. @@ -1778,17 +1759,11 @@ void meta_display_queue_autoraise_callback (MetaDisplay *display, MetaWindow *window) { - MetaAutoRaiseData *auto_raise_data; - meta_topic (META_DEBUG_FOCUS, "Queuing an autoraise timeout for %s with delay %d\n", window->desc, meta_prefs_get_auto_raise_delay ()); - auto_raise_data = g_new (MetaAutoRaiseData, 1); - auto_raise_data->display = window->display; - auto_raise_data->xwindow = window->xwindow; - if (display->autoraise_timeout_id != 0) g_source_remove (display->autoraise_timeout_id); @@ -1796,8 +1771,7 @@ meta_display_queue_autoraise_callback (MetaDisplay *display, g_timeout_add_full (G_PRIORITY_DEFAULT, meta_prefs_get_auto_raise_delay (), window_raise_with_delay_callback, - auto_raise_data, - g_free); + window, NULL); display->autoraise_window = window; } diff --git a/src/core/window.c b/src/core/window.c index fd4ed51ce..09a8f833c 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -2000,6 +2000,8 @@ meta_window_unmanage (MetaWindow *window, meta_window_ungrab_keys (window); meta_display_ungrab_window_buttons (window->display, window->xwindow); meta_display_ungrab_focus_window_button (window->display, window); + if (window->display->autoraise_window == window) + meta_display_remove_autoraise_callback (window->display); if (window->client_type == META_WINDOW_CLIENT_TYPE_X11) { From 23ba3e527fdb454d3aca2552f2e252a8ca814609 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 16 Oct 2013 00:06:10 -0400 Subject: [PATCH 208/889] wayland: Support alternative focus modes like focus-follows-mouse Use the existing code for MetaWindow focus-follows-mouse to support this. --- src/core/display.c | 193 +---------------------------- src/core/window-private.h | 5 + src/core/window.c | 182 +++++++++++++++++++++++++++ src/wayland/meta-wayland-pointer.c | 5 + 4 files changed, 196 insertions(+), 189 deletions(-) diff --git a/src/core/display.c b/src/core/display.c index c7e86b228..4de870ad4 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -117,15 +117,6 @@ typedef struct guint ping_timeout_id; } MetaPingData; -typedef struct -{ - MetaDisplay *display; - MetaWindow *window; - int pointer_x; - int pointer_y; -} MetaFocusData; - - G_DEFINE_TYPE(MetaDisplay, meta_display, G_TYPE_OBJECT); /* Signals */ @@ -1596,21 +1587,6 @@ crossing_serial_is_ignored (MetaDisplay *display, return FALSE; } -static void -reset_ignored_crossing_serials (MetaDisplay *display) -{ - int i; - - i = 0; - while (i < N_IGNORED_CROSSING_SERIALS) - { - display->ignored_crossing_serials[i] = 0; - ++i; - } - - display->ungrab_should_not_cause_focus_window = None; -} - static gboolean window_raise_with_delay_callback (void *data) { @@ -1651,110 +1627,6 @@ window_raise_with_delay_callback (void *data) return FALSE; } -static void -meta_display_mouse_mode_focus (MetaDisplay *display, - MetaWindow *window, - guint32 timestamp) -{ - if (window->type != META_WINDOW_DESKTOP) - { - meta_topic (META_DEBUG_FOCUS, - "Focusing %s at time %u.\n", window->desc, timestamp); - - meta_window_focus (window, timestamp); - - if (meta_prefs_get_auto_raise ()) - meta_display_queue_autoraise_callback (display, window); - else - meta_topic (META_DEBUG_FOCUS, "Auto raise is disabled\n"); - } - else - { - /* In mouse focus mode, we defocus when the mouse *enters* - * the DESKTOP window, instead of defocusing on LeaveNotify. - * This is because having the mouse enter override-redirect - * child windows unfortunately causes LeaveNotify events that - * we can't distinguish from the mouse actually leaving the - * toplevel window as we expect. But, since we filter out - * EnterNotify events on override-redirect windows, this - * alternative mechanism works great. - */ - if (meta_prefs_get_focus_mode() == G_DESKTOP_FOCUS_MODE_MOUSE && - display->focus_window != NULL) - { - meta_topic (META_DEBUG_FOCUS, - "Unsetting focus from %s due to mouse entering " - "the DESKTOP window\n", - display->focus_window->desc); - meta_display_focus_the_no_focus_window (display, - window->screen, - timestamp); - } - } -} - -static gboolean -window_focus_on_pointer_rest_callback (gpointer data) -{ - MetaFocusData *focus_data; - MetaDisplay *display; - MetaScreen *screen; - MetaWindow *window; - Window root, child; - double root_x, root_y, x, y; - guint32 timestamp; - XIButtonState buttons; - XIModifierState mods; - XIGroupState group; - - focus_data = data; - display = focus_data->display; - screen = focus_data->window->screen; - - if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK) - goto out; - - meta_error_trap_push (display); - XIQueryPointer (display->xdisplay, - META_VIRTUAL_CORE_POINTER_ID, - screen->xroot, - &root, &child, - &root_x, &root_y, &x, &y, - &buttons, &mods, &group); - meta_error_trap_pop (display); - free (buttons.mask); - - if (root_x != focus_data->pointer_x || - root_y != focus_data->pointer_y) - { - focus_data->pointer_x = root_x; - focus_data->pointer_y = root_y; - 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); - - if (window == NULL) - goto out; - - timestamp = meta_display_get_current_time_roundtrip (display); - meta_display_mouse_mode_focus (display, window, timestamp); - - out: - display->focus_timeout_id = 0; - return FALSE; -} - void meta_display_queue_autoraise_callback (MetaDisplay *display, MetaWindow *window) @@ -1775,37 +1647,6 @@ meta_display_queue_autoraise_callback (MetaDisplay *display, display->autoraise_window = window; } -/* The interval, in milliseconds, we use in focus-follows-mouse - * mode to check whether the pointer has stopped moving after a - * crossing event. - */ -#define FOCUS_TIMEOUT_DELAY 25 - -static void -meta_display_queue_focus_callback (MetaDisplay *display, - MetaWindow *window, - int pointer_x, - int pointer_y) -{ - MetaFocusData *focus_data; - - focus_data = g_new (MetaFocusData, 1); - focus_data->display = display; - focus_data->window = window; - focus_data->pointer_x = pointer_x; - focus_data->pointer_y = pointer_y; - - if (display->focus_timeout_id != 0) - g_source_remove (display->focus_timeout_id); - - display->focus_timeout_id = - g_timeout_add_full (G_PRIORITY_DEFAULT, - FOCUS_TIMEOUT_DELAY, - window_focus_on_pointer_rest_callback, - focus_data, - g_free); -} - #if 0 static void handle_net_restack_window (MetaDisplay* display, @@ -2502,36 +2343,10 @@ handle_input_xevent (MetaDisplay *display, enter_event->detail != XINotifyInferior && meta_display_focus_sentinel_clear (display)) { - switch (meta_prefs_get_focus_mode ()) - { - case G_DESKTOP_FOCUS_MODE_SLOPPY: - case G_DESKTOP_FOCUS_MODE_MOUSE: - display->mouse_mode = TRUE; - if (window->type != META_WINDOW_DOCK) - { - meta_topic (META_DEBUG_FOCUS, - "Queuing a focus change for %s due to " - "enter notify with serial %lu at time %lu, " - "and setting display->mouse_mode to TRUE.\n", - window->desc, - serial, - enter_event->time); - - if (meta_prefs_get_focus_change_on_pointer_rest()) - meta_display_queue_focus_callback (display, window, - enter_event->root_x, - enter_event->root_y); - else - meta_display_mouse_mode_focus (display, window, - enter_event->time); - - /* stop ignoring stuff */ - reset_ignored_crossing_serials (display); - } - break; - case G_DESKTOP_FOCUS_MODE_CLICK: - break; - } + meta_window_handle_enter (window, + enter_event->time, + enter_event->root_x, + enter_event->root_y); if (window->type == META_WINDOW_DOCK) meta_window_raise (window); diff --git a/src/core/window-private.h b/src/core/window-private.h index 8c125cdac..1a428030c 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -734,4 +734,9 @@ void meta_window_set_gtk_dbus_properties (MetaWindow *window, void meta_window_set_transient_for (MetaWindow *window, MetaWindow *parent); +void meta_window_handle_enter (MetaWindow *window, + guint32 timestamp, + guint root_x, + guint root_y); + #endif diff --git a/src/core/window.c b/src/core/window.c index 09a8f833c..bef47bec8 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -11667,3 +11667,185 @@ meta_window_set_transient_for (MetaWindow *window, if (meta_window_appears_focused (window) && window->transient_for != None) meta_window_propagate_focus_appearance (window, TRUE); } + +static void +reset_ignored_crossing_serials (MetaDisplay *display) +{ + int i; + + i = 0; + while (i < N_IGNORED_CROSSING_SERIALS) + { + display->ignored_crossing_serials[i] = 0; + ++i; + } + + display->ungrab_should_not_cause_focus_window = None; +} + +typedef struct +{ + MetaWindow *window; + int pointer_x; + int pointer_y; +} MetaFocusData; + +static void +mouse_mode_focus (MetaWindow *window, + guint32 timestamp) +{ + MetaDisplay *display = window->display; + + if (window->type != META_WINDOW_DESKTOP) + { + meta_topic (META_DEBUG_FOCUS, + "Focusing %s at time %u.\n", window->desc, timestamp); + + meta_window_focus (window, timestamp); + + if (meta_prefs_get_auto_raise ()) + meta_display_queue_autoraise_callback (display, window); + else + meta_topic (META_DEBUG_FOCUS, "Auto raise is disabled\n"); + } + else + { + /* In mouse focus mode, we defocus when the mouse *enters* + * the DESKTOP window, instead of defocusing on LeaveNotify. + * This is because having the mouse enter override-redirect + * child windows unfortunately causes LeaveNotify events that + * we can't distinguish from the mouse actually leaving the + * toplevel window as we expect. But, since we filter out + * EnterNotify events on override-redirect windows, this + * alternative mechanism works great. + */ + if (meta_prefs_get_focus_mode() == G_DESKTOP_FOCUS_MODE_MOUSE && + display->focus_window != NULL) + { + meta_topic (META_DEBUG_FOCUS, + "Unsetting focus from %s due to mouse entering " + "the DESKTOP window\n", + display->focus_window->desc); + meta_display_focus_the_no_focus_window (display, + window->screen, + timestamp); + } + } +} + +static gboolean +window_focus_on_pointer_rest_callback (gpointer data) +{ + MetaFocusData *focus_data = data; + MetaWindow *window = focus_data->window; + MetaDisplay *display = window->display; + MetaScreen *screen = window->screen; + Window root, child; + double root_x, root_y, x, y; + guint32 timestamp; + XIButtonState buttons; + XIModifierState mods; + XIGroupState group; + + if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK) + goto out; + + meta_error_trap_push (display); + XIQueryPointer (display->xdisplay, + META_VIRTUAL_CORE_POINTER_ID, + screen->xroot, + &root, &child, + &root_x, &root_y, &x, &y, + &buttons, &mods, &group); + meta_error_trap_pop (display); + free (buttons.mask); + + if (root_x != focus_data->pointer_x || + root_y != focus_data->pointer_y) + { + focus_data->pointer_x = root_x; + focus_data->pointer_y = root_y; + 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); + + if (window == NULL) + goto out; + + timestamp = meta_display_get_current_time_roundtrip (display); + mouse_mode_focus (window, timestamp); + + out: + display->focus_timeout_id = 0; + return FALSE; +} + +/* The interval, in milliseconds, we use in focus-follows-mouse + * mode to check whether the pointer has stopped moving after a + * crossing event. + */ +#define FOCUS_TIMEOUT_DELAY 25 + +static void +queue_focus_callback (MetaDisplay *display, + MetaWindow *window, + int pointer_x, + int pointer_y) +{ + MetaFocusData *focus_data; + + focus_data = g_new (MetaFocusData, 1); + focus_data->window = window; + focus_data->pointer_x = pointer_x; + focus_data->pointer_y = pointer_y; + + if (display->focus_timeout_id != 0) + g_source_remove (display->focus_timeout_id); + + display->focus_timeout_id = + g_timeout_add_full (G_PRIORITY_DEFAULT, + FOCUS_TIMEOUT_DELAY, + window_focus_on_pointer_rest_callback, + focus_data, + g_free); +} + +void +meta_window_handle_enter (MetaWindow *window, + guint32 timestamp, + guint root_x, + guint root_y) +{ + MetaDisplay *display = window->display; + + switch (meta_prefs_get_focus_mode ()) + { + case G_DESKTOP_FOCUS_MODE_SLOPPY: + case G_DESKTOP_FOCUS_MODE_MOUSE: + display->mouse_mode = TRUE; + if (window->type != META_WINDOW_DOCK) + { + if (meta_prefs_get_focus_change_on_pointer_rest()) + queue_focus_callback (display, window, root_x, root_y); + else + mouse_mode_focus (window, timestamp); + + /* stop ignoring stuff */ + reset_ignored_crossing_serials (display); + } + break; + case G_DESKTOP_FOCUS_MODE_CLICK: + break; + } +} diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index 1f6962a5f..2a44ac06a 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -353,6 +353,11 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer, } meta_wayland_pointer_get_relative_coordinates (pointer, surface, &sx, &sy); + meta_window_handle_enter (surface->window, + /* XXX -- can we reliably get a timestamp for setting focus? */ + clutter_get_current_event_time (), + wl_fixed_to_int (pointer->x), + wl_fixed_to_int (pointer->y)); wl_pointer_send_enter (resource, serial, surface->resource, sx, sy); wl_resource_add_destroy_listener (resource, &pointer->focus_listener); pointer->focus_serial = serial; From ae44bff0b16dfa8bf5d78bea0428fd544a44482f Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Wed, 13 Nov 2013 21:38:27 +0100 Subject: [PATCH 209/889] display: Without a grab op let events go through clutter too We want events to reach clutter no only when there a compositor modal grab but also when no grab op is in effect. https://bugzilla.gnome.org/show_bug.cgi?id=712247 --- src/core/display.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/display.c b/src/core/display.c index 4de870ad4..f49b64bd7 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -2296,7 +2296,8 @@ meta_display_handle_event (MetaDisplay *display, } #endif /* HAVE_WAYLAND */ - return (display->grab_op != META_GRAB_OP_COMPOSITOR); + return (display->grab_op != META_GRAB_OP_NONE && + display->grab_op != META_GRAB_OP_COMPOSITOR); } static gboolean From 63b9110f9324dc757d4cc150021a087f6b3217de Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Wed, 13 Nov 2013 21:41:29 +0100 Subject: [PATCH 210/889] wayland: Update internal wayland state unconditionally Things like idle times and the cursor position need to be updated even if there's a mutter grab in effect. https://bugzilla.gnome.org/show_bug.cgi?id=712247 --- src/core/display.c | 12 +++++++++--- src/wayland/meta-wayland-private.h | 2 ++ src/wayland/meta-wayland-seat.c | 22 ++++++++++++++-------- src/wayland/meta-wayland-seat.h | 4 ++++ src/wayland/meta-wayland.c | 18 ++++++++++++++---- 5 files changed, 43 insertions(+), 15 deletions(-) diff --git a/src/core/display.c b/src/core/display.c index f49b64bd7..0d437760c 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -2044,6 +2044,15 @@ meta_display_handle_event (MetaDisplay *display, { MetaWindow *window; gboolean frame_was_receiver; +#ifdef HAVE_WAYLAND + MetaWaylandCompositor *compositor; + + if (meta_is_wayland_compositor ()) + { + compositor = meta_wayland_compositor_get_default (); + meta_wayland_compositor_update (compositor, event); + } +#endif /* HAVE_WAYLAND */ window = get_window_for_actor (event->any.source, &frame_was_receiver); @@ -2288,9 +2297,6 @@ meta_display_handle_event (MetaDisplay *display, #ifdef HAVE_WAYLAND if (meta_is_wayland_compositor () && (display->grab_op == META_GRAB_OP_NONE)) { - MetaWaylandCompositor *compositor; - compositor = meta_wayland_compositor_get_default (); - if (meta_wayland_compositor_handle_event (compositor, event)) return TRUE; } diff --git a/src/wayland/meta-wayland-private.h b/src/wayland/meta-wayland-private.h index 140ce63cf..d13090bb3 100644 --- a/src/wayland/meta-wayland-private.h +++ b/src/wayland/meta-wayland-private.h @@ -107,5 +107,7 @@ MetaWaylandBuffer * meta_wayland_buffer_from_resource (struct wl_resou void meta_wayland_buffer_reference (MetaWaylandBufferReference *ref, MetaWaylandBuffer *buffer); +void meta_wayland_compositor_update (MetaWaylandCompositor *compositor, + const ClutterEvent *event); #endif /* META_WAYLAND_PRIVATE_H */ diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c index ef404faf9..0b9415a83 100644 --- a/src/wayland/meta-wayland-seat.c +++ b/src/wayland/meta-wayland-seat.c @@ -257,11 +257,6 @@ notify_motion (MetaWaylandSeat *seat, const ClutterEvent *event) { MetaWaylandPointer *pointer = &seat->pointer; - float x, y; - - clutter_event_get_coords (event, &x, &y); - pointer->x = wl_fixed_from_double (x); - pointer->y = wl_fixed_from_double (y); meta_wayland_seat_repick (seat, event); @@ -363,10 +358,16 @@ count_buttons (const ClutterEvent *event) return count; } -gboolean -meta_wayland_seat_handle_event (MetaWaylandSeat *seat, - const ClutterEvent *event) +void +meta_wayland_seat_update_pointer (MetaWaylandSeat *seat, + const ClutterEvent *event) { + float x, y; + + clutter_event_get_coords (event, &x, &y); + seat->pointer.x = wl_fixed_from_double (x); + seat->pointer.y = wl_fixed_from_double (y); + seat->pointer.button_count = count_buttons (event); if (seat->cursor_tracker) @@ -381,7 +382,12 @@ meta_wayland_seat_handle_event (MetaWaylandSeat *seat, meta_cursor_tracker_queue_redraw (seat->cursor_tracker, CLUTTER_ACTOR (event->any.stage)); } +} +gboolean +meta_wayland_seat_handle_event (MetaWaylandSeat *seat, + const ClutterEvent *event) +{ switch (event->type) { case CLUTTER_MOTION: diff --git a/src/wayland/meta-wayland-seat.h b/src/wayland/meta-wayland-seat.h index c5c88e246..dd2b85e72 100644 --- a/src/wayland/meta-wayland-seat.h +++ b/src/wayland/meta-wayland-seat.h @@ -77,6 +77,10 @@ MetaWaylandSeat * meta_wayland_seat_new (struct wl_display *display, gboolean is_native); +void +meta_wayland_seat_update_pointer (MetaWaylandSeat *seat, + const ClutterEvent *event); + gboolean meta_wayland_seat_handle_event (MetaWaylandSeat *seat, const ClutterEvent *event); diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index ce80bfd87..dabdc1ed3 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -533,8 +533,9 @@ stage_destroy_cb (void) meta_quit (META_EXIT_SUCCESS); } -static void -reset_idletimes (const ClutterEvent *event) +void +meta_wayland_compositor_update (MetaWaylandCompositor *compositor, + const ClutterEvent *event) { ClutterInputDevice *device, *source_device; MetaIdleMonitor *core_monitor, *device_monitor; @@ -559,14 +560,23 @@ reset_idletimes (const ClutterEvent *event) device_monitor = meta_idle_monitor_get_for_device (device_id); meta_idle_monitor_reset_idletime (device_monitor); } + + switch (event->type) + { + case CLUTTER_MOTION: + case CLUTTER_BUTTON_PRESS: + case CLUTTER_BUTTON_RELEASE: + case CLUTTER_SCROLL: + meta_wayland_seat_update_pointer (compositor->seat, event); + default: + break; + } } gboolean meta_wayland_compositor_handle_event (MetaWaylandCompositor *compositor, const ClutterEvent *event) { - reset_idletimes (event); - return meta_wayland_seat_handle_event (compositor->seat, event); } From cf181fe109016de72d98ec60f0c598f77974d931 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 14 Nov 2013 12:58:52 -0500 Subject: [PATCH 211/889] display: Adapt to new clutter event filter API --- src/core/display-private.h | 2 ++ src/core/display.c | 10 +++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/core/display-private.h b/src/core/display-private.h index c4e38d81d..da85ade10 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -102,6 +102,8 @@ struct _MetaDisplay char *name; Display *xdisplay; + int clutter_event_filter; + Window leader_window; Window timestamp_pinging_window; diff --git a/src/core/display.c b/src/core/display.c index 0d437760c..3d07c2080 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -592,8 +592,11 @@ meta_display_open (void) meta_ui_add_event_func (the_display->xdisplay, xevent_callback, the_display); - clutter_event_add_filter (event_callback, the_display); - + the_display->clutter_event_filter = clutter_event_add_filter (NULL, + event_callback, + NULL, + the_display); + the_display->xids = g_hash_table_new (meta_unsigned_long_hash, meta_unsigned_long_equal); the_display->wayland_windows = g_hash_table_new (NULL, NULL); @@ -1124,7 +1127,8 @@ meta_display_close (MetaDisplay *display, meta_ui_remove_event_func (display->xdisplay, xevent_callback, display); - clutter_event_remove_filter (event_callback, display); + clutter_event_remove_filter (display->clutter_event_filter); + display->clutter_event_filter = 0; /* Free all screens */ tmp = display->screens; From 1946c548bf4a3395f77521e3d89c73e10a130589 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 14 Nov 2013 14:40:39 -0500 Subject: [PATCH 212/889] Bump required Clutter version --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 6d7607294..b79289da9 100644 --- a/configure.ac +++ b/configure.ac @@ -78,7 +78,7 @@ MUTTER_PC_MODULES=" cairo >= 1.10.0 gsettings-desktop-schemas >= 3.7.3 xcomposite >= 0.2 xfixes xrender xdamage xi >= 1.6.0 - $CLUTTER_PACKAGE >= 1.15.94 + $CLUTTER_PACKAGE >= 1.17.1 cogl-1.0 >= 1.13.3 upower-glib >= 0.99.0 gnome-desktop-3.0 From 3c7cd1f38c935d913145ad44e84fee825dccfe92 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 14 Nov 2013 21:34:20 -0500 Subject: [PATCH 213/889] wayland-surface: Use begin_grab_op for move grabs --- src/core/keybindings.c | 4 + src/wayland/meta-wayland-surface.c | 117 +++-------------------------- 2 files changed, 15 insertions(+), 106 deletions(-) diff --git a/src/core/keybindings.c b/src/core/keybindings.c index d6144f4f8..873938528 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -1566,6 +1566,10 @@ meta_window_grab_all_keys (MetaWindow *window, Window grabwindow; gboolean retval; + /* We don't need to grab Wayland clients */ + if (window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND) + return TRUE; + if (window->all_keys_grabbed) return FALSE; diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index c283b652e..67583eee1 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -570,75 +570,6 @@ xdg_surface_pong (struct wl_client *client, { } -typedef struct -{ - MetaWaylandPointerGrab generic; - MetaWaylandSurface *surface; - struct wl_listener surface_destroy_listener; - wl_fixed_t dx, dy; -} MetaWaylandMoveGrab; - -static void -end_move_grab (MetaWaylandMoveGrab *move_grab) -{ - if (move_grab->surface) - { - move_grab->surface = NULL; - wl_list_remove (&move_grab->surface_destroy_listener.link); - } - - meta_wayland_pointer_end_grab (move_grab->generic.pointer); - g_slice_free (MetaWaylandMoveGrab, move_grab); -} - -static void -move_grab_lose_surface (struct wl_listener *listener, void *data) -{ - MetaWaylandMoveGrab *move_grab = - wl_container_of (listener, move_grab, surface_destroy_listener); - - move_grab->surface = NULL; - end_move_grab (move_grab); -} - -static void -move_grab_focus (MetaWaylandPointerGrab *grab, - MetaWaylandSurface *surface, - const ClutterEvent *event) -{ -} - -static void -move_grab_motion (MetaWaylandPointerGrab *grab, - const ClutterEvent *event) -{ - MetaWaylandMoveGrab *move_grab = (MetaWaylandMoveGrab *)grab; - MetaWaylandPointer *pointer = grab->pointer; - - meta_window_move (move_grab->surface->window, - TRUE, - wl_fixed_to_int (pointer->x + move_grab->dx), - wl_fixed_to_int (pointer->y + move_grab->dy)); -} - -static void -move_grab_button (MetaWaylandPointerGrab *grab, - const ClutterEvent *event) -{ - MetaWaylandMoveGrab *move_grab = (MetaWaylandMoveGrab *)grab; - MetaWaylandPointer *pointer = grab->pointer; - - if (pointer->button_count == 0 && - clutter_event_type (event) == CLUTTER_BUTTON_RELEASE) - end_move_grab (move_grab); -} - -static const MetaWaylandPointerGrabInterface move_grab_interface = { - move_grab_focus, - move_grab_motion, - move_grab_button, -}; - static void xdg_surface_move (struct wl_client *client, struct wl_resource *resource, @@ -648,8 +579,6 @@ xdg_surface_move (struct wl_client *client, MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); MetaWindow *window; - MetaWaylandMoveGrab *move_grab; - MetaRectangle rect; if (seat->pointer.button_count == 0 || seat->pointer.grab_serial != serial || @@ -660,41 +589,17 @@ xdg_surface_move (struct wl_client *client, if (!window) return; - /* small hack, this should be handled by window->shaken_loose when we - move everything to display.c */ - if (window->fullscreen) - meta_window_unmake_fullscreen (window); - - move_grab = g_slice_new (MetaWaylandMoveGrab); - - meta_window_get_input_rect (xdg_surface->surface->window, - &rect); - - move_grab->generic.interface = &move_grab_interface; - move_grab->generic.pointer = &seat->pointer; - - move_grab->surface = xdg_surface->surface; - move_grab->surface_destroy_listener.notify = move_grab_lose_surface; - wl_resource_add_destroy_listener (xdg_surface->surface->resource, - &move_grab->surface_destroy_listener); - - move_grab->dx = wl_fixed_from_int (rect.x) - seat->pointer.grab_x; - move_grab->dy = wl_fixed_from_int (rect.y) - seat->pointer.grab_y; - - meta_wayland_pointer_start_grab (&seat->pointer, (MetaWaylandPointerGrab*)move_grab); - - /* TODO: send_grab_cursor (cursor); */ - - /* XXX: In Weston there is a desktop shell protocol which has - * a set_grab_surface request that's used to specify the surface - * that's focused here. - * - * TODO: understand why. - * - * XXX: For now we just focus the surface directly associated with - * the grab. - */ - meta_wayland_pointer_set_focus (&seat->pointer, xdg_surface->surface); + meta_display_begin_grab_op (window->display, + window->screen, + window, + META_GRAB_OP_MOVING, + TRUE, /* pointer_already_grabbed */ + FALSE, /* frame_action */ + 1, /* button. XXX? */ + 0, /* modmask */ + meta_display_get_current_time_roundtrip (window->display), + wl_fixed_to_int (seat->pointer.grab_x), + wl_fixed_to_int (seat->pointer.grab_y)); } static void From b72315e27a8432037c430aa3052e06e80d26de75 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 14 Nov 2013 21:45:34 -0500 Subject: [PATCH 214/889] wayland-surface: Support xdg_surface_resize as well --- src/wayland/meta-wayland-surface.c | 86 +++++++++++++++++++++++------- 1 file changed, 66 insertions(+), 20 deletions(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 67583eee1..198b169be 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -570,6 +570,32 @@ xdg_surface_pong (struct wl_client *client, { } +static gboolean +begin_grab_op_on_surface (MetaWaylandSurface *surface, + MetaWaylandSeat *seat, + MetaGrabOp grab_op) +{ + MetaWindow *window = surface->window; + + if (!window) + return FALSE; + + if (grab_op == META_GRAB_OP_NONE) + return FALSE; + + return meta_display_begin_grab_op (window->display, + window->screen, + window, + grab_op, + TRUE, /* pointer_already_grabbed */ + FALSE, /* frame_action */ + 1, /* button. XXX? */ + 0, /* modmask */ + meta_display_get_current_time_roundtrip (window->display), + wl_fixed_to_int (seat->pointer.grab_x), + wl_fixed_to_int (seat->pointer.grab_y)); +} + static void xdg_surface_move (struct wl_client *client, struct wl_resource *resource, @@ -578,38 +604,58 @@ xdg_surface_move (struct wl_client *client, { MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); - MetaWindow *window; if (seat->pointer.button_count == 0 || seat->pointer.grab_serial != serial || seat->pointer.focus != xdg_surface->surface) return; - window = xdg_surface->surface->window; - if (!window) - return; + begin_grab_op_on_surface (xdg_surface->surface, seat, META_GRAB_OP_MOVING); +} - meta_display_begin_grab_op (window->display, - window->screen, - window, - META_GRAB_OP_MOVING, - TRUE, /* pointer_already_grabbed */ - FALSE, /* frame_action */ - 1, /* button. XXX? */ - 0, /* modmask */ - meta_display_get_current_time_roundtrip (window->display), - wl_fixed_to_int (seat->pointer.grab_x), - wl_fixed_to_int (seat->pointer.grab_y)); +static MetaGrabOp +grab_op_for_edge (int edge) +{ + switch (edge) + { + case XDG_SURFACE_RESIZE_EDGE_TOP_LEFT: + return META_GRAB_OP_RESIZING_NW; + case XDG_SURFACE_RESIZE_EDGE_TOP: + return META_GRAB_OP_RESIZING_N; + case XDG_SURFACE_RESIZE_EDGE_TOP_RIGHT: + return META_GRAB_OP_RESIZING_NE; + case XDG_SURFACE_RESIZE_EDGE_RIGHT: + return META_GRAB_OP_RESIZING_E; + case XDG_SURFACE_RESIZE_EDGE_BOTTOM_RIGHT: + return META_GRAB_OP_RESIZING_SE; + case XDG_SURFACE_RESIZE_EDGE_BOTTOM: + return META_GRAB_OP_RESIZING_S; + case XDG_SURFACE_RESIZE_EDGE_BOTTOM_LEFT: + return META_GRAB_OP_RESIZING_SW; + case XDG_SURFACE_RESIZE_EDGE_LEFT: + return META_GRAB_OP_RESIZING_W; + default: + g_warning ("invalid edge: %d", edge); + return META_GRAB_OP_NONE; + } } static void xdg_surface_resize (struct wl_client *client, - struct wl_resource *resource, - struct wl_resource *seat, - guint32 serial, - guint32 edges) + struct wl_resource *resource, + struct wl_resource *seat_resource, + guint32 serial, + guint32 edges) { - g_warning ("TODO: support xdg_surface.resize"); + MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); + MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); + + if (seat->pointer.button_count == 0 || + seat->pointer.grab_serial != serial || + seat->pointer.focus != xdg_surface->surface) + return; + + begin_grab_op_on_surface (xdg_surface->surface, seat, grab_op_for_edge (edges)); } static void From 932e913d889653e8d4df5c9efcaff77de75ef682 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 14 Nov 2013 21:49:51 -0500 Subject: [PATCH 215/889] wayland-surface: Fix formatting --- src/wayland/meta-wayland-surface.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 198b169be..50ebe850e 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -721,8 +721,7 @@ xdg_surface_set_minimized (struct wl_client *client, meta_window_minimize (surface->window); } -static const struct xdg_surface_interface meta_wayland_xdg_surface_interface = -{ +static const struct xdg_surface_interface meta_wayland_xdg_surface_interface = { xdg_surface_destroy, xdg_surface_set_transient_for, xdg_surface_set_title, @@ -833,8 +832,7 @@ get_xdg_popup (struct wl_client *client, g_warning ("TODO: support xdg_shell.get_xdg_popup"); } -static const struct xdg_shell_interface meta_wayland_xdg_shell_interface = -{ +static const struct xdg_shell_interface meta_wayland_xdg_shell_interface = { use_unstable_version, get_xdg_surface, get_xdg_popup, @@ -888,8 +886,7 @@ set_dbus_properties (struct wl_client *client, surface->pending.gtk_window_object_path = g_strdup (window_object_path); } -static const struct gtk_surface_interface meta_wayland_gtk_surface_interface = -{ +static const struct gtk_surface_interface meta_wayland_gtk_surface_interface = { set_dbus_properties }; @@ -915,8 +912,7 @@ get_gtk_surface (struct wl_client *client, &meta_wayland_gtk_surface_interface); } -static const struct gtk_shell_interface meta_wayland_gtk_shell_interface = -{ +static const struct gtk_shell_interface meta_wayland_gtk_shell_interface = { get_gtk_surface }; From 9dc6028b3daa325e8ebb667a1b0b582a4b4fdf64 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 4 Nov 2013 21:41:27 -0500 Subject: [PATCH 216/889] trivial: shaped-texture: Fix documentation typo --- src/compositor/meta-shaped-texture.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c index 552bdbbea..e47c9296c 100644 --- a/src/compositor/meta-shaped-texture.c +++ b/src/compositor/meta-shaped-texture.c @@ -770,8 +770,8 @@ get_clip (MetaShapedTexture *stex, * has a mapped clone) * * Repairs the damaged area indicated by @x, @y, @width and @height - * and queues a redraw for the intersection @visibible_region and - * the damage area. If @visibible_region is %NULL a redraw will always + * and queues a redraw for the intersection @unobscured_region and + * the damage area. If @unobscured_region is %NULL a redraw will always * get queued. * * Return value: Whether a redraw have been queued or not From 56a0dd6b2cb4c1ec835fc1a4d7c48ad3aa40d666 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 4 Nov 2013 21:44:25 -0500 Subject: [PATCH 217/889] trivial: shaped-texture: Move set_base_texture to set_cogl_texture A simple code cleanup. --- src/compositor/meta-shaped-texture.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c index e47c9296c..07b58a99e 100644 --- a/src/compositor/meta-shaped-texture.c +++ b/src/compositor/meta-shaped-texture.c @@ -266,6 +266,9 @@ set_cogl_texture (MetaShapedTexture *stex, * know how much of the buffer has changed with respect to the * previous buffer. We only queue a redraw in response to surface * damage. */ + + if (priv->create_mipmaps) + meta_texture_tower_set_base_texture (priv->paint_tower, cogl_tex); } static void @@ -872,10 +875,6 @@ meta_shaped_texture_set_pixmap (MetaShapedTexture *stex, } else set_cogl_texture (stex, NULL); - - if (priv->create_mipmaps) - meta_texture_tower_set_base_texture (priv->paint_tower, - COGL_TEXTURE (priv->texture)); } void @@ -899,10 +898,6 @@ meta_shaped_texture_attach_wayland_buffer (MetaShapedTexture *stex, set_cogl_texture (stex, buffer->texture); else set_cogl_texture (stex, NULL); - - if (priv->create_mipmaps) - meta_texture_tower_set_base_texture (priv->paint_tower, - COGL_TEXTURE (priv->texture)); } /** From 662c9729bc7518fb31864f234260db52558698d8 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 14 Nov 2013 15:44:07 -0500 Subject: [PATCH 218/889] trivial: window-actor: Fix formatting --- src/compositor/meta-window-actor.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 4dd7775a2..ade870de1 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -962,8 +962,8 @@ meta_window_actor_freeze (MetaWindowActor *self) self->priv->freeze_count++; } -static -gboolean send_frame_messages_timeout (gpointer data) +static gboolean +send_frame_messages_timeout (gpointer data) { MetaWindowActor *self = (MetaWindowActor *) data; MetaWindowActorPrivate *priv = self->priv; From 1a88176cc0967e17be0e39dfb841831eaebeb07e Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 18 Nov 2013 16:52:10 -0500 Subject: [PATCH 219/889] keyboard: Fix surface focusing Bad rebase... --- src/wayland/meta-wayland-keyboard.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wayland/meta-wayland-keyboard.c b/src/wayland/meta-wayland-keyboard.c index 05db151ef..327189a19 100644 --- a/src/wayland/meta-wayland-keyboard.c +++ b/src/wayland/meta-wayland-keyboard.c @@ -561,7 +561,7 @@ meta_wayland_keyboard_set_focus (MetaWaylandKeyboard *keyboard, wl_resource_add_destroy_listener (resource, &keyboard->focus_listener); keyboard->focus_serial = serial; - meta_wayland_surface_focused_set (keyboard->focus); + meta_wayland_surface_focused_set (surface); } keyboard->focus_resource = resource; From 1f569bef761f2a8ff30c3308e28f32e706b96f81 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 18 Nov 2013 18:36:39 -0500 Subject: [PATCH 220/889] Fix dragging on move/resize grabs We need to use the grab_window for incoming events if we have an active grab. --- src/compositor/meta-window-actor.c | 4 +--- src/core/display.c | 32 +++++++++++------------------- 2 files changed, 13 insertions(+), 23 deletions(-) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index ade870de1..2a6314cac 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -397,9 +397,7 @@ meta_window_actor_constructed (GObject *object) priv->actor = meta_shaped_texture_new_with_xwindow (xwindow); clutter_actor_add_child (CLUTTER_ACTOR (self), priv->actor); - - if (meta_is_wayland_compositor ()) - clutter_actor_set_reactive (priv->actor, TRUE); + clutter_actor_set_reactive (CLUTTER_ACTOR (self), TRUE); /* * Since we are holding a pointer to this actor independently of the diff --git a/src/core/display.c b/src/core/display.c index 3d07c2080..b54fd9db8 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -1690,27 +1690,17 @@ handle_net_restack_window (MetaDisplay* display, #endif static MetaWindow * -get_window_for_actor (ClutterActor *actor, - gboolean *frame_was_receiver) +get_window_for_event (MetaDisplay *display, + const ClutterEvent *event) { - /* Look for any ancestor that is a MetaWindowActor to determine - which window the actor's event belongs to */ + ClutterActor *source; - *frame_was_receiver = TRUE; + if (display->grab_window) + return display->grab_window; - while (actor) - { - if (META_IS_WINDOW_ACTOR (actor)) - return meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor)); - - /* If the frame is the receiver then the source will directly be - the MetaWindowActor, otherwise it will be a child of a - MetaWindowActor so if we make it here then the event isn't - referring to the frame. */ - *frame_was_receiver = FALSE; - - actor = clutter_actor_get_parent (actor); - } + source = clutter_event_get_source (event); + if (META_IS_WINDOW_ACTOR (source)) + return meta_window_actor_get_meta_window (META_WINDOW_ACTOR (source)); return NULL; } @@ -2047,7 +2037,9 @@ meta_display_handle_event (MetaDisplay *display, const ClutterEvent *event) { MetaWindow *window; - gboolean frame_was_receiver; + + /* XXX -- we need to fill this in properly at some point... */ + gboolean frame_was_receiver = FALSE; #ifdef HAVE_WAYLAND MetaWaylandCompositor *compositor; @@ -2058,7 +2050,7 @@ meta_display_handle_event (MetaDisplay *display, } #endif /* HAVE_WAYLAND */ - window = get_window_for_actor (event->any.source, &frame_was_receiver); + window = get_window_for_event (display, event); display->current_time = event->any.time; From d96b053c9d5eb602407578481bbd3b9f1af47499 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 18 Nov 2013 19:19:42 -0500 Subject: [PATCH 221/889] cursor-tracker: Use a sync methodology for the cursor image Rather than have MetaWaylandSeat do all the state management itself, put the split between the root cursor and the window cursor in the cursor tracker itself. We'll expand this to add a "grab" cursor in the next commit, allowing us to force a cursor on grab operations. --- src/core/meta-cursor-tracker-private.h | 16 +- src/core/meta-cursor-tracker.c | 281 ++++++++++++++----------- src/wayland/meta-wayland-seat.c | 26 +-- 3 files changed, 176 insertions(+), 147 deletions(-) diff --git a/src/core/meta-cursor-tracker-private.h b/src/core/meta-cursor-tracker-private.h index e18d31522..ffa08df2b 100644 --- a/src/core/meta-cursor-tracker-private.h +++ b/src/core/meta-cursor-tracker-private.h @@ -31,18 +31,16 @@ gboolean meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker, XEvent *xevent); -void meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker, - MetaCursor cursor); -void meta_cursor_tracker_revert_root (MetaCursorTracker *tracker); -void meta_cursor_tracker_set_buffer (MetaCursorTracker *tracker, - struct wl_resource *buffer, - int hot_x, - int hot_y); +void meta_cursor_tracker_set_window_cursor (MetaCursorTracker *tracker, + struct wl_resource *buffer, + int hot_x, + int hot_y); +void meta_cursor_tracker_unset_window_cursor (MetaCursorTracker *tracker); +void meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker, + MetaCursor cursor); void meta_cursor_tracker_update_position (MetaCursorTracker *tracker, int new_x, int new_y); void meta_cursor_tracker_paint (MetaCursorTracker *tracker); -void meta_cursor_tracker_queue_redraw (MetaCursorTracker *tracker, - ClutterActor *stage); #endif diff --git a/src/core/meta-cursor-tracker.c b/src/core/meta-cursor-tracker.c index cff5f3eee..e4cf92f50 100644 --- a/src/core/meta-cursor-tracker.c +++ b/src/core/meta-cursor-tracker.c @@ -68,11 +68,31 @@ struct _MetaCursorTracker { MetaScreen *screen; gboolean is_showing; - gboolean has_cursor; gboolean has_hw_cursor; - MetaCursorReference *sprite; + /* The cursor tracker stores the cursor for the window with + * pointer focus, and the cursor for the root window, which + * contains either the default arrow cursor or the 'busy' + * hourglass if we're launching an app. + * + * We choose the first one available -- if there's a window + * cursor, we choose that, otherwise we choose the root + * cursor. + * + * The displayed_cursor contains the chosen cursor. + */ + MetaCursorReference *displayed_cursor; + + /* Wayland clients can set a NULL buffer as their cursor + * explicitly, which means that we shouldn't display anything. + * So, we can't simply store a NULL in window_cursor to + * determine an unset window cursor; we need an extra boolean. + */ + gboolean has_window_cursor; + MetaCursorReference *window_cursor; + MetaCursorReference *root_cursor; + MetaCursorReference *default_cursors[META_CURSOR_LAST]; int current_x, current_y; @@ -98,9 +118,6 @@ enum { static guint signals[LAST_SIGNAL]; -static void meta_cursor_tracker_set_sprite (MetaCursorTracker *tracker, - MetaCursorReference *sprite); - static void meta_cursor_tracker_set_crtc_has_hw_cursor (MetaCursorTracker *tracker, MetaCRTC *crtc, gboolean has_hw_cursor); @@ -354,7 +371,7 @@ meta_cursor_reference_from_buffer (MetaCursorTracker *tracker, self->ref_count = 1; self->hot_x = hot_x; self->hot_y = hot_y; - + backend = clutter_get_default_backend (); cogl_context = clutter_backend_get_cogl_context (backend); @@ -520,8 +537,8 @@ meta_cursor_tracker_finalize (GObject *object) MetaCursorTracker *self = META_CURSOR_TRACKER (object); int i; - if (self->sprite) - meta_cursor_reference_unref (self->sprite); + if (self->displayed_cursor) + meta_cursor_reference_unref (self->displayed_cursor); if (self->root_cursor) meta_cursor_reference_unref (self->root_cursor); @@ -646,6 +663,17 @@ meta_cursor_tracker_get_for_screen (MetaScreen *screen) return self; } +static void +set_window_cursor (MetaCursorTracker *tracker, + gboolean has_cursor, + MetaCursorReference *cursor) +{ + g_clear_pointer (&tracker->window_cursor, meta_cursor_reference_unref); + if (cursor) + tracker->window_cursor = meta_cursor_reference_ref (cursor); + tracker->has_window_cursor = has_cursor; +} + gboolean meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker, XEvent *xevent) @@ -662,7 +690,7 @@ meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker, if (notify_event->subtype != XFixesDisplayCursorNotify) return FALSE; - g_clear_pointer (&tracker->sprite, meta_cursor_reference_unref); + set_window_cursor (tracker, FALSE, NULL); g_signal_emit (tracker, signals[CURSOR_CHANGED], 0); return TRUE; @@ -677,7 +705,7 @@ ensure_xfixes_cursor (MetaCursorTracker *tracker) gboolean free_cursor_data; CoglContext *ctx; - if (tracker->sprite) + if (tracker->has_window_cursor) return; cursor_image = XFixesGetCursorImage (tracker->screen->display->xdisplay); @@ -725,9 +753,11 @@ ensure_xfixes_cursor (MetaCursorTracker *tracker) if (sprite != NULL) { - tracker->sprite = meta_cursor_reference_take_texture (sprite); - tracker->sprite->hot_x = cursor_image->xhot; - tracker->sprite->hot_y = cursor_image->yhot; + MetaCursorReference *cursor = meta_cursor_reference_take_texture (sprite); + cursor->hot_x = cursor_image->xhot; + cursor->hot_y = cursor_image->yhot; + + set_window_cursor (tracker, TRUE, cursor); } XFree (cursor_image); } @@ -745,8 +775,8 @@ meta_cursor_tracker_get_sprite (MetaCursorTracker *tracker) if (!meta_is_wayland_compositor ()) ensure_xfixes_cursor (tracker); - if (tracker->sprite) - return COGL_TEXTURE (tracker->sprite->texture); + if (tracker->displayed_cursor) + return COGL_TEXTURE (tracker->displayed_cursor->texture); else return NULL; } @@ -768,12 +798,13 @@ meta_cursor_tracker_get_hot (MetaCursorTracker *tracker, if (!meta_is_wayland_compositor ()) ensure_xfixes_cursor (tracker); - if (tracker->sprite) + if (tracker->displayed_cursor) { + MetaCursorReference *displayed_cursor = tracker->displayed_cursor; if (x) - *x = tracker->sprite->hot_x; + *x = displayed_cursor->hot_x; if (y) - *y = tracker->sprite->hot_y; + *y = displayed_cursor->hot_y; } else { @@ -798,6 +829,28 @@ ensure_wayland_cursor (MetaCursorTracker *tracker, return tracker->default_cursors[cursor]; } +void +meta_cursor_tracker_set_window_cursor (MetaCursorTracker *tracker, + struct wl_resource *buffer, + int hot_x, + int hot_y) +{ + MetaCursorReference *cursor; + + if (buffer) + cursor = meta_cursor_reference_from_buffer (tracker, buffer, hot_x, hot_y); + else + cursor = NULL; + + set_window_cursor (tracker, TRUE, cursor); +} + +void +meta_cursor_tracker_unset_window_cursor (MetaCursorTracker *tracker) +{ + set_window_cursor (tracker, FALSE, NULL); +} + void meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker, MetaCursor cursor) @@ -824,12 +877,6 @@ meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker, } } -void -meta_cursor_tracker_revert_root (MetaCursorTracker *tracker) -{ - meta_cursor_tracker_set_sprite (tracker, tracker->root_cursor); -} - static void update_hw_cursor (MetaCursorTracker *tracker) { @@ -838,7 +885,7 @@ update_hw_cursor (MetaCursorTracker *tracker) unsigned int i, n_crtcs; gboolean enabled; - enabled = tracker->has_cursor && tracker->sprite->bo != NULL; + enabled = tracker->displayed_cursor && tracker->displayed_cursor->bo != NULL; tracker->has_hw_cursor = enabled; monitors = meta_monitor_manager_get (); @@ -884,105 +931,45 @@ move_hw_cursor (MetaCursorTracker *tracker) } } -void -meta_cursor_tracker_set_buffer (MetaCursorTracker *tracker, - struct wl_resource *buffer, - int hot_x, - int hot_y) +static MetaCursorReference * +get_displayed_cursor (MetaCursorTracker *tracker) { - MetaCursorReference *new_cursor; + if (!tracker->is_showing) + return NULL; - if (buffer) - { - new_cursor = meta_cursor_reference_from_buffer (tracker, buffer, hot_x, hot_y); - meta_cursor_tracker_set_sprite (tracker, new_cursor); - meta_cursor_reference_unref (new_cursor); - } - else - meta_cursor_tracker_set_sprite (tracker, NULL); + if (tracker->has_window_cursor) + return tracker->window_cursor; + + return tracker->root_cursor; } static void -meta_cursor_tracker_set_sprite (MetaCursorTracker *tracker, - MetaCursorReference *sprite) +sync_displayed_cursor (MetaCursorTracker *tracker) { - g_assert (meta_is_wayland_compositor ()); + MetaCursorReference *displayed_cursor = get_displayed_cursor (tracker); - if (sprite == tracker->sprite) + if (tracker->displayed_cursor == displayed_cursor) return; - g_clear_pointer (&tracker->sprite, meta_cursor_reference_unref); + g_clear_pointer (&tracker->displayed_cursor, meta_cursor_reference_unref); + if (displayed_cursor) + tracker->displayed_cursor = meta_cursor_reference_ref (displayed_cursor); - if (sprite) - { - tracker->sprite = meta_cursor_reference_ref (sprite); - cogl_pipeline_set_layer_texture (tracker->pipeline, 0, COGL_TEXTURE (tracker->sprite->texture)); - } + if (displayed_cursor) + cogl_pipeline_set_layer_texture (tracker->pipeline, 0, COGL_TEXTURE (displayed_cursor->texture)); else cogl_pipeline_set_layer_texture (tracker->pipeline, 0, NULL); - tracker->has_cursor = tracker->sprite != NULL && tracker->is_showing; update_hw_cursor (tracker); g_signal_emit (tracker, signals[CURSOR_CHANGED], 0); - - meta_cursor_tracker_update_position (tracker, tracker->current_x, tracker->current_y); } -void -meta_cursor_tracker_update_position (MetaCursorTracker *tracker, - int new_x, - int new_y) -{ - g_assert (meta_is_wayland_compositor ()); - - tracker->current_x = new_x; - tracker->current_y = new_y; - - if (tracker->sprite) - { - tracker->current_rect.x = tracker->current_x - tracker->sprite->hot_x; - tracker->current_rect.y = tracker->current_y - tracker->sprite->hot_y; - tracker->current_rect.width = cogl_texture_get_width (COGL_TEXTURE (tracker->sprite->texture)); - tracker->current_rect.height = cogl_texture_get_height (COGL_TEXTURE (tracker->sprite->texture)); - } - else - { - tracker->current_rect.x = 0; - tracker->current_rect.y = 0; - tracker->current_rect.width = 0; - tracker->current_rect.height = 0; - } - - if (tracker->has_hw_cursor) - move_hw_cursor (tracker); -} - -void -meta_cursor_tracker_paint (MetaCursorTracker *tracker) -{ - g_assert (meta_is_wayland_compositor ()); - - if (tracker->has_hw_cursor || !tracker->has_cursor) - return; - - cogl_framebuffer_draw_rectangle (cogl_get_draw_framebuffer (), - tracker->pipeline, - tracker->current_rect.x, - tracker->current_rect.y, - tracker->current_rect.x + - tracker->current_rect.width, - tracker->current_rect.y + - tracker->current_rect.height); - - tracker->previous_rect = tracker->current_rect; - tracker->previous_is_valid = TRUE; -} - -void -meta_cursor_tracker_queue_redraw (MetaCursorTracker *tracker, - ClutterActor *stage) +static void +meta_cursor_tracker_queue_redraw (MetaCursorTracker *tracker) { + MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); + ClutterActor *stage = compositor->stage; cairo_rectangle_int_t clip; g_assert (meta_is_wayland_compositor ()); @@ -999,7 +986,7 @@ meta_cursor_tracker_queue_redraw (MetaCursorTracker *tracker, tracker->previous_is_valid = FALSE; } - if (tracker->has_hw_cursor || !tracker->has_cursor) + if (tracker->has_hw_cursor || !tracker->displayed_cursor) return; clip.x = tracker->current_rect.x; @@ -1009,6 +996,69 @@ meta_cursor_tracker_queue_redraw (MetaCursorTracker *tracker, clutter_actor_queue_redraw_with_clip (stage, &clip); } +static void +sync_cursor (MetaCursorTracker *tracker) +{ + MetaCursorReference *displayed_cursor; + + sync_displayed_cursor (tracker); + displayed_cursor = tracker->displayed_cursor; + + if (displayed_cursor) + { + tracker->current_rect.x = tracker->current_x - displayed_cursor->hot_x; + tracker->current_rect.y = tracker->current_y - displayed_cursor->hot_y; + tracker->current_rect.width = cogl_texture_get_width (COGL_TEXTURE (displayed_cursor->texture)); + tracker->current_rect.height = cogl_texture_get_height (COGL_TEXTURE (displayed_cursor->texture)); + } + else + { + tracker->current_rect.x = 0; + tracker->current_rect.y = 0; + tracker->current_rect.width = 0; + tracker->current_rect.height = 0; + } + + if (tracker->has_hw_cursor) + move_hw_cursor (tracker); + else + meta_cursor_tracker_queue_redraw (tracker); +} + +void +meta_cursor_tracker_update_position (MetaCursorTracker *tracker, + int new_x, + int new_y) +{ + g_assert (meta_is_wayland_compositor ()); + + tracker->current_x = new_x; + tracker->current_y = new_y; + + sync_cursor (tracker); +} + +void +meta_cursor_tracker_paint (MetaCursorTracker *tracker) +{ + g_assert (meta_is_wayland_compositor ()); + + if (tracker->has_hw_cursor || !tracker->displayed_cursor) + return; + + cogl_framebuffer_draw_rectangle (cogl_get_draw_framebuffer (), + tracker->pipeline, + tracker->current_rect.x, + tracker->current_rect.y, + tracker->current_rect.x + + tracker->current_rect.width, + tracker->current_rect.y + + tracker->current_rect.height); + + tracker->previous_rect = tracker->current_rect; + tracker->previous_is_valid = TRUE; +} + static void meta_cursor_tracker_set_crtc_has_hw_cursor (MetaCursorTracker *tracker, MetaCRTC *crtc, @@ -1016,15 +1066,16 @@ meta_cursor_tracker_set_crtc_has_hw_cursor (MetaCursorTracker *tracker, { if (has) { + MetaCursorReference *displayed_cursor = tracker->displayed_cursor; union gbm_bo_handle handle; int width, height; int hot_x, hot_y; - handle = gbm_bo_get_handle (tracker->sprite->bo); - width = gbm_bo_get_width (tracker->sprite->bo); - height = gbm_bo_get_height (tracker->sprite->bo); - hot_x = tracker->sprite->hot_x; - hot_y = tracker->sprite->hot_y; + handle = gbm_bo_get_handle (displayed_cursor->bo); + width = gbm_bo_get_width (displayed_cursor->bo); + height = gbm_bo_get_height (displayed_cursor->bo); + hot_x = displayed_cursor->hot_x; + hot_y = displayed_cursor->hot_y; drmModeSetCursor2 (tracker->drm_fd, crtc->crtc_id, handle.u32, width, height, hot_x, hot_y); @@ -1100,13 +1151,7 @@ meta_cursor_tracker_set_pointer_visible (MetaCursorTracker *tracker, if (meta_is_wayland_compositor ()) { - MetaWaylandCompositor *compositor; - - compositor = meta_wayland_compositor_get_default (); - - tracker->has_cursor = tracker->sprite != NULL && visible; - update_hw_cursor (tracker); - meta_cursor_tracker_queue_redraw (tracker, compositor->stage); + sync_cursor (tracker); } else { diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c index 0b9415a83..377e7f2c7 100644 --- a/src/wayland/meta-wayland-seat.c +++ b/src/wayland/meta-wayland-seat.c @@ -51,14 +51,7 @@ static void pointer_unmap_sprite (MetaWaylandSeat *seat) { if (seat->cursor_tracker) - { - meta_cursor_tracker_set_buffer (seat->cursor_tracker, - NULL, 0, 0); - - if (seat->current_stage) - meta_cursor_tracker_queue_redraw (seat->cursor_tracker, - CLUTTER_ACTOR (seat->current_stage)); - } + meta_cursor_tracker_set_window_cursor (seat->cursor_tracker, NULL, 0, 0); if (seat->sprite) { @@ -76,14 +69,10 @@ meta_wayland_seat_update_sprite (MetaWaylandSeat *seat) return; buffer = seat->sprite->buffer_ref.buffer->resource; - meta_cursor_tracker_set_buffer (seat->cursor_tracker, - buffer, - seat->hotspot_x, - seat->hotspot_y); - - if (seat->current_stage) - meta_cursor_tracker_queue_redraw (seat->cursor_tracker, - CLUTTER_ACTOR (seat->current_stage)); + meta_cursor_tracker_set_window_cursor (seat->cursor_tracker, + buffer, + seat->hotspot_x, + seat->hotspot_y); } static void @@ -377,10 +366,7 @@ meta_wayland_seat_update_pointer (MetaWaylandSeat *seat, wl_fixed_to_int (seat->pointer.y)); if (seat->pointer.current == NULL) - meta_cursor_tracker_revert_root (seat->cursor_tracker); - - meta_cursor_tracker_queue_redraw (seat->cursor_tracker, - CLUTTER_ACTOR (event->any.stage)); + meta_cursor_tracker_unset_window_cursor (seat->cursor_tracker); } } From 4091f5493d275153a9f35b79e8b27c3c848c57d7 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 18 Nov 2013 19:34:04 -0500 Subject: [PATCH 222/889] cursor-tracker: Force the grab cursor on grab ops This makes window moving have a 'window move' cursor, and similar. --- src/core/display.c | 43 ++++++++++++-------------- src/core/meta-cursor-tracker-private.h | 2 ++ src/core/meta-cursor-tracker.c | 29 ++++++++++++----- 3 files changed, 43 insertions(+), 31 deletions(-) diff --git a/src/core/display.c b/src/core/display.c index b54fd9db8..a763df7fe 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -53,6 +53,7 @@ #include #include "mutter-enum-types.h" #include "meta-idle-monitor-private.h" +#include "meta-cursor-tracker-private.h" #ifdef HAVE_RANDR #include @@ -3879,59 +3880,53 @@ meta_display_xwindow_is_a_no_focus_window (MetaDisplay *display, return is_a_no_focus_window; } -static Cursor -xcursor_for_op (MetaDisplay *display, - MetaGrabOp op) +static MetaCursor +meta_cursor_for_grab_op (MetaGrabOp op) { - MetaCursor cursor = META_CURSOR_DEFAULT; - switch (op) { case META_GRAB_OP_RESIZING_SE: case META_GRAB_OP_KEYBOARD_RESIZING_SE: - cursor = META_CURSOR_SE_RESIZE; + return META_CURSOR_SE_RESIZE; break; case META_GRAB_OP_RESIZING_S: case META_GRAB_OP_KEYBOARD_RESIZING_S: - cursor = META_CURSOR_SOUTH_RESIZE; + return META_CURSOR_SOUTH_RESIZE; break; case META_GRAB_OP_RESIZING_SW: case META_GRAB_OP_KEYBOARD_RESIZING_SW: - cursor = META_CURSOR_SW_RESIZE; + return META_CURSOR_SW_RESIZE; break; case META_GRAB_OP_RESIZING_N: case META_GRAB_OP_KEYBOARD_RESIZING_N: - cursor = META_CURSOR_NORTH_RESIZE; + return META_CURSOR_NORTH_RESIZE; break; case META_GRAB_OP_RESIZING_NE: case META_GRAB_OP_KEYBOARD_RESIZING_NE: - cursor = META_CURSOR_NE_RESIZE; + return META_CURSOR_NE_RESIZE; break; case META_GRAB_OP_RESIZING_NW: case META_GRAB_OP_KEYBOARD_RESIZING_NW: - cursor = META_CURSOR_NW_RESIZE; + return META_CURSOR_NW_RESIZE; break; case META_GRAB_OP_RESIZING_W: case META_GRAB_OP_KEYBOARD_RESIZING_W: - cursor = META_CURSOR_WEST_RESIZE; + return META_CURSOR_WEST_RESIZE; break; case META_GRAB_OP_RESIZING_E: case META_GRAB_OP_KEYBOARD_RESIZING_E: - cursor = META_CURSOR_EAST_RESIZE; + return META_CURSOR_EAST_RESIZE; break; case META_GRAB_OP_MOVING: case META_GRAB_OP_KEYBOARD_MOVING: case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN: - cursor = META_CURSOR_MOVE_OR_RESIZE_WINDOW; + return META_CURSOR_MOVE_OR_RESIZE_WINDOW; break; - default: break; } - if (cursor == META_CURSOR_DEFAULT) - return None; - return meta_display_create_x_cursor (display, cursor); + return META_CURSOR_DEFAULT; } void @@ -3941,7 +3936,6 @@ meta_display_set_grab_op_cursor (MetaDisplay *display, Window grab_xwindow, guint32 timestamp) { - Cursor cursor = xcursor_for_op (display, op); unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits }; @@ -3958,7 +3952,7 @@ meta_display_set_grab_op_cursor (MetaDisplay *display, META_VIRTUAL_CORE_POINTER_ID, grab_xwindow, timestamp, - cursor, + None, XIGrabModeAsync, XIGrabModeAsync, False, /* owner_events */ &mask) == Success) @@ -3974,10 +3968,10 @@ meta_display_set_grab_op_cursor (MetaDisplay *display, "XIGrabDevice() failed time %u\n", timestamp); } + meta_error_trap_pop (display); - - if (cursor != None) - XFreeCursor (display->xdisplay, cursor); + + meta_cursor_tracker_set_grab_cursor (screen->cursor_tracker, meta_cursor_for_grab_op (op)); } gboolean @@ -4239,7 +4233,8 @@ meta_display_end_grab_op (MetaDisplay *display, meta_screen_ungrab_all_keys (display->grab_screen, timestamp); } - + meta_cursor_tracker_set_grab_cursor (display->grab_screen->cursor_tracker, META_CURSOR_DEFAULT); + display->grab_timestamp = 0; display->grab_window = NULL; display->grab_screen = NULL; diff --git a/src/core/meta-cursor-tracker-private.h b/src/core/meta-cursor-tracker-private.h index ffa08df2b..b0ad11e6a 100644 --- a/src/core/meta-cursor-tracker-private.h +++ b/src/core/meta-cursor-tracker-private.h @@ -31,6 +31,8 @@ gboolean meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker, XEvent *xevent); +void meta_cursor_tracker_set_grab_cursor (MetaCursorTracker *tracker, + MetaCursor cursor); void meta_cursor_tracker_set_window_cursor (MetaCursorTracker *tracker, struct wl_resource *buffer, int hot_x, diff --git a/src/core/meta-cursor-tracker.c b/src/core/meta-cursor-tracker.c index e4cf92f50..bbdba907a 100644 --- a/src/core/meta-cursor-tracker.c +++ b/src/core/meta-cursor-tracker.c @@ -70,19 +70,22 @@ struct _MetaCursorTracker { gboolean is_showing; gboolean has_hw_cursor; - /* The cursor tracker stores the cursor for the window with - * pointer focus, and the cursor for the root window, which - * contains either the default arrow cursor or the 'busy' - * hourglass if we're launching an app. + /* The cursor tracker stores the cursor for the current grab + * operation, the cursor for the window with pointer focus, and + * the cursor for the root window, which contains either the + * default arrow cursor or the 'busy' hourglass if we're launching + * an app. * - * We choose the first one available -- if there's a window - * cursor, we choose that, otherwise we choose the root - * cursor. + * We choose the first one available -- if there's a grab cursor, + * we choose that cursor, if there's window cursor, we choose that, + * otherwise we choose the root cursor. * * The displayed_cursor contains the chosen cursor. */ MetaCursorReference *displayed_cursor; + MetaCursorReference *grab_cursor; + /* Wayland clients can set a NULL buffer as their cursor * explicitly, which means that we shouldn't display anything. * So, we can't simply store a NULL in window_cursor to @@ -829,6 +832,15 @@ ensure_wayland_cursor (MetaCursorTracker *tracker, return tracker->default_cursors[cursor]; } +void +meta_cursor_tracker_set_grab_cursor (MetaCursorTracker *tracker, + MetaCursor cursor) +{ + g_clear_pointer (&tracker->grab_cursor, meta_cursor_reference_unref); + if (cursor != META_CURSOR_DEFAULT) + tracker->grab_cursor = ensure_wayland_cursor (tracker, cursor); +} + void meta_cursor_tracker_set_window_cursor (MetaCursorTracker *tracker, struct wl_resource *buffer, @@ -937,6 +949,9 @@ get_displayed_cursor (MetaCursorTracker *tracker) if (!tracker->is_showing) return NULL; + if (tracker->grab_cursor) + return tracker->grab_cursor; + if (tracker->has_window_cursor) return tracker->window_cursor; From 73a908206229473c0cc9a34eeb7681ffba2c03f5 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 18 Nov 2013 19:47:34 -0500 Subject: [PATCH 223/889] cursor-tracker: Make ensure_wayland_cursor take a ref This fixes a crash in the last commit because that's what I thought this would do. It also simplifies callers drastically... --- src/core/meta-cursor-tracker.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/core/meta-cursor-tracker.c b/src/core/meta-cursor-tracker.c index bbdba907a..eda4cd99d 100644 --- a/src/core/meta-cursor-tracker.c +++ b/src/core/meta-cursor-tracker.c @@ -822,14 +822,14 @@ static MetaCursorReference * ensure_wayland_cursor (MetaCursorTracker *tracker, MetaCursor cursor) { - if (tracker->default_cursors[cursor]) - return tracker->default_cursors[cursor]; - - tracker->default_cursors[cursor] = meta_cursor_reference_from_theme (tracker, cursor); if (!tracker->default_cursors[cursor]) - meta_warning ("Failed to load cursor from theme\n"); + { + tracker->default_cursors[cursor] = meta_cursor_reference_from_theme (tracker, cursor); + if (!tracker->default_cursors[cursor]) + meta_warning ("Failed to load cursor from theme\n"); + } - return tracker->default_cursors[cursor]; + return meta_cursor_reference_ref (tracker->default_cursors[cursor]); } void @@ -880,12 +880,8 @@ meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker, /* Now update the real root cursor */ if (meta_is_wayland_compositor ()) { - MetaCursorReference *ref; - - ref = ensure_wayland_cursor (tracker, cursor); - g_clear_pointer (&tracker->root_cursor, meta_cursor_reference_unref); - tracker->root_cursor = meta_cursor_reference_ref (ref); + tracker->root_cursor = ensure_wayland_cursor (tracker, cursor); } } From 8dd97b4998d91bad46e367011dba94ce2b0abcca Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 18 Nov 2013 21:18:34 -0500 Subject: [PATCH 224/889] compositor: Remove outdated comment XWayland no longer redirects windows by default. --- src/compositor/compositor.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index bd3bb305c..706650c33 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -650,11 +650,6 @@ redirect_windows (MetaCompositor *compositor, guint n_retries; guint max_retries; - /* If we're running with wayland, connected to a headless xwayland - * server then all the windows are implicitly redirected offscreen - * already and it would generate an error to try and explicitly - * redirect them via XCompositeRedirectSubwindows() */ - if (meta_get_replace_current_wm ()) max_retries = 5; else From bbbb9ac53c38e4361ddbd43f6e7f1ded16cf1c63 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 18 Nov 2013 20:50:56 -0500 Subject: [PATCH 225/889] display: Make handle_[x]event private --- src/core/display-private.h | 6 ------ src/core/display.c | 4 ++-- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/core/display-private.h b/src/core/display-private.h index da85ade10..79d281b22 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -484,12 +484,6 @@ gboolean meta_display_modifiers_accelerator_activate (MetaDisplay *display); /* In above-tab-keycode.c */ guint meta_display_get_above_tab_keycode (MetaDisplay *display); -gboolean meta_display_handle_xevent (MetaDisplay *display, - XEvent *event); - -gboolean meta_display_handle_event (MetaDisplay *display, - const ClutterEvent *event); - #ifdef HAVE_XI23 gboolean meta_display_process_barrier_event (MetaDisplay *display, XIEvent *event); diff --git a/src/core/display.c b/src/core/display.c index a763df7fe..fa5d85b31 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -2033,7 +2033,7 @@ handle_window_focus_event (MetaDisplay *display, } } -gboolean +static gboolean meta_display_handle_event (MetaDisplay *display, const ClutterEvent *event) { @@ -2980,7 +2980,7 @@ handle_other_xevent (MetaDisplay *display, * busy around here. Most of this function is a ginormous switch statement * dealing with all the kinds of events that might turn up. */ -gboolean +static gboolean meta_display_handle_xevent (MetaDisplay *display, XEvent *event) { From 735b7361103484309bf60136a6a2c6443b37ac96 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 14 Nov 2013 15:41:59 -0500 Subject: [PATCH 226/889] shaped-texture: Use the cogl helper methods for fetching shm_buffer contents Rather than doing the set_region ourselves. --- src/compositor/meta-shaped-texture.c | 37 +++------------------------- 1 file changed, 3 insertions(+), 34 deletions(-) diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c index 07b58a99e..c1ac5ff77 100644 --- a/src/compositor/meta-shaped-texture.c +++ b/src/compositor/meta-shaped-texture.c @@ -678,40 +678,9 @@ wayland_surface_update_area (MetaShapedTexture *stex, struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get (resource); if (shm_buffer) - { - CoglPixelFormat format; - - switch (wl_shm_buffer_get_format (shm_buffer)) - { -#if G_BYTE_ORDER == G_BIG_ENDIAN - case WL_SHM_FORMAT_ARGB8888: - format = COGL_PIXEL_FORMAT_ARGB_8888_PRE; - break; - case WL_SHM_FORMAT_XRGB8888: - format = COGL_PIXEL_FORMAT_ARGB_8888; - break; -#elif G_BYTE_ORDER == G_LITTLE_ENDIAN - case WL_SHM_FORMAT_ARGB8888: - format = COGL_PIXEL_FORMAT_BGRA_8888_PRE; - break; - case WL_SHM_FORMAT_XRGB8888: - format = COGL_PIXEL_FORMAT_BGRA_8888; - break; -#endif - default: - g_warn_if_reached (); - format = COGL_PIXEL_FORMAT_ARGB_8888; - } - - cogl_texture_set_region (priv->texture, - x, y, - x, y, - width, height, - width, height, - format, - wl_shm_buffer_get_stride (shm_buffer), - wl_shm_buffer_get_data (shm_buffer)); - } + cogl_wayland_texture_2d_update_area (COGL_TEXTURE_2D (priv->texture), + shm_buffer, + x, y, width, height); } } From a02d734243e11043861f2958fb6d3e744f780933 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 4 Nov 2013 22:13:33 -0500 Subject: [PATCH 227/889] window-actor: Move all buffer management and damage correction here We want ShapedTexture to be a dumb actor that knows how to pick/paint fairly easily, without any "platform knowledge", so to say... --- src/compositor/meta-shaped-texture-private.h | 14 +- src/compositor/meta-shaped-texture.c | 167 ++----------------- src/compositor/meta-window-actor-private.h | 2 - src/compositor/meta-window-actor.c | 81 +++++---- src/wayland/meta-wayland-seat.c | 6 - src/wayland/meta-xwayland.c | 5 - 6 files changed, 59 insertions(+), 216 deletions(-) diff --git a/src/compositor/meta-shaped-texture-private.h b/src/compositor/meta-shaped-texture-private.h index ec4f08137..18d61a728 100644 --- a/src/compositor/meta-shaped-texture-private.h +++ b/src/compositor/meta-shaped-texture-private.h @@ -28,17 +28,9 @@ #define __META_SHAPED_TEXTURE_PRIVATE_H__ #include -#include "meta-wayland-private.h" -ClutterActor *meta_shaped_texture_new_with_xwindow (Window xwindow); -ClutterActor *meta_shaped_texture_new_with_wayland_surface (MetaWaylandSurface *surface); -void meta_shaped_texture_set_wayland_surface (MetaShapedTexture *stex, - MetaWaylandSurface *surface); -MetaWaylandSurface *meta_shaped_texture_get_wayland_surface (MetaShapedTexture *stex); - -void meta_shaped_texture_set_pixmap (MetaShapedTexture *stex, - Pixmap pixmap); -void meta_shaped_texture_attach_wayland_buffer (MetaShapedTexture *stex, - MetaWaylandBuffer *buffer); +ClutterActor *meta_shaped_texture_new (void); +void meta_shaped_texture_set_texture (MetaShapedTexture *stex, + CoglTexture *texture); #endif diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c index c1ac5ff77..546204250 100644 --- a/src/compositor/meta-shaped-texture.c +++ b/src/compositor/meta-shaped-texture.c @@ -35,12 +35,9 @@ #include "meta-texture-tower.h" #include "meta-shaped-texture-private.h" -#include "meta-wayland-private.h" -#include #include #include -#include #include /* for gdk_rectangle_intersect() */ static void meta_shaped_texture_dispose (GObject *object); @@ -61,15 +58,7 @@ static void meta_shaped_texture_get_preferred_height (ClutterActor *self, static gboolean meta_shaped_texture_get_paint_volume (ClutterActor *self, ClutterPaintVolume *volume); -typedef enum _MetaShapedTextureType -{ - META_SHAPED_TEXTURE_TYPE_X11_PIXMAP, - META_SHAPED_TEXTURE_TYPE_WAYLAND_SURFACE, -} MetaShapedTextureType; - - -G_DEFINE_TYPE (MetaShapedTexture, meta_shaped_texture, - CLUTTER_TYPE_ACTOR); +G_DEFINE_TYPE (MetaShapedTexture, meta_shaped_texture, CLUTTER_TYPE_ACTOR); #define META_SHAPED_TEXTURE_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), META_TYPE_SHAPED_TEXTURE, \ @@ -79,18 +68,7 @@ struct _MetaShapedTexturePrivate { MetaTextureTower *paint_tower; - MetaShapedTextureType type; - union { - struct { - Pixmap pixmap; - } x11; - struct { - MetaWaylandSurface *surface; - } wayland; - }; - CoglTexture *texture; - CoglTexture *mask_texture; cairo_region_t *clip_region; @@ -128,9 +106,7 @@ meta_shaped_texture_init (MetaShapedTexture *self) priv->paint_tower = meta_texture_tower_new (); - priv->type = META_SHAPED_TEXTURE_TYPE_X11_PIXMAP; priv->texture = NULL; - priv->mask_texture = NULL; priv->create_mipmaps = TRUE; } @@ -220,10 +196,8 @@ paint_clipped_rectangle (CoglFramebuffer *fb, cogl_framebuffer_draw_multitextured_rectangle (fb, pipeline, x1, y1, x2, y2, &coords[0], 8); - } - static void set_cogl_texture (MetaShapedTexture *stex, CoglTexture *cogl_tex) @@ -571,48 +545,6 @@ meta_shaped_texture_get_paint_volume (ClutterActor *self, return clutter_paint_volume_set_from_allocation (volume, self); } -ClutterActor * -meta_shaped_texture_new_with_wayland_surface (MetaWaylandSurface *surface) -{ - ClutterActor *actor = g_object_new (META_TYPE_SHAPED_TEXTURE, NULL); - MetaShapedTexturePrivate *priv = META_SHAPED_TEXTURE (actor)->priv; - - /* XXX: it could probably be better to have a "type" construct-only - * property or create wayland/x11 subclasses */ - priv->type = META_SHAPED_TEXTURE_TYPE_WAYLAND_SURFACE; - - meta_shaped_texture_set_wayland_surface (META_SHAPED_TEXTURE (actor), - surface); - - return actor; -} - -void -meta_shaped_texture_set_wayland_surface (MetaShapedTexture *stex, - MetaWaylandSurface *surface) -{ - MetaShapedTexturePrivate *priv = stex->priv; - - priv->wayland.surface = surface; - - if (surface && surface->buffer_ref.buffer) - meta_shaped_texture_attach_wayland_buffer (stex, - surface->buffer_ref.buffer); -} - -MetaWaylandSurface * -meta_shaped_texture_get_wayland_surface (MetaShapedTexture *stex) -{ - MetaShapedTexturePrivate *priv = stex->priv; - return priv->wayland.surface; -} - -ClutterActor * -meta_shaped_texture_new_with_xwindow (Window xwindow) -{ - return g_object_new (META_TYPE_SHAPED_TEXTURE, NULL); -} - void meta_shaped_texture_set_create_mipmaps (MetaShapedTexture *stex, gboolean create_mipmaps) @@ -655,35 +587,6 @@ meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex, clutter_actor_queue_redraw (CLUTTER_ACTOR (stex)); } -static void -wayland_surface_update_area (MetaShapedTexture *stex, - int x, - int y, - int width, - int height) -{ - MetaShapedTexturePrivate *priv; - MetaWaylandBuffer *buffer; - - priv = stex->priv; - - g_return_if_fail (priv->type == META_SHAPED_TEXTURE_TYPE_WAYLAND_SURFACE); - g_return_if_fail (priv->texture != NULL); - - buffer = priv->wayland.surface->buffer_ref.buffer; - - if (buffer) - { - struct wl_resource *resource = buffer->resource; - struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get (resource); - - if (shm_buffer) - cogl_wayland_texture_2d_update_area (COGL_TEXTURE_2D (priv->texture), - shm_buffer, - x, y, width, height); - } -} - static gboolean get_clip (MetaShapedTexture *stex, int x, @@ -765,17 +668,6 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex, if (priv->texture == NULL) return FALSE; - switch (priv->type) - { - case META_SHAPED_TEXTURE_TYPE_X11_PIXMAP: - cogl_texture_pixmap_x11_update_area (COGL_TEXTURE_PIXMAP_X11 (priv->texture), - x, y, width, height); - break; - case META_SHAPED_TEXTURE_TYPE_WAYLAND_SURFACE: - wayland_surface_update_area (stex, x, y, width, height); - break; - } - meta_texture_tower_update_area (priv->paint_tower, x, y, width, height); has_clip = get_clip (stex, x, y, width, height, &clip); @@ -815,58 +707,17 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex, } /** - * meta_shaped_texture_set_pixmap: + * meta_shaped_texture_set_texture: * @stex: The #MetaShapedTexture - * @pixmap: The pixmap you want the stex to assume + * @pixmap: The #CoglTexture to display */ void -meta_shaped_texture_set_pixmap (MetaShapedTexture *stex, - Pixmap pixmap) +meta_shaped_texture_set_texture (MetaShapedTexture *stex, + CoglTexture *texture) { - MetaShapedTexturePrivate *priv; - g_return_if_fail (META_IS_SHAPED_TEXTURE (stex)); - priv = stex->priv; - - if (priv->x11.pixmap == pixmap) - return; - - priv->x11.pixmap = pixmap; - - if (pixmap != None) - { - CoglContext *ctx = - clutter_backend_get_cogl_context (clutter_get_default_backend ()); - CoglTexture *texture = - COGL_TEXTURE (cogl_texture_pixmap_x11_new (ctx, pixmap, FALSE, NULL)); - set_cogl_texture (stex, texture); - } - else - set_cogl_texture (stex, NULL); -} - -void -meta_shaped_texture_attach_wayland_buffer (MetaShapedTexture *stex, - MetaWaylandBuffer *buffer) -{ - MetaShapedTexturePrivate *priv; - - g_return_if_fail (META_IS_SHAPED_TEXTURE (stex)); - - priv = stex->priv; - - /* TODO: we should change this api to be something like - * meta_shaped_texture_notify_buffer_attach() since we now maintain - * a reference to the MetaWaylandSurface where we can access the - * buffer without it being explicitly passed as an argument. - */ - g_return_if_fail (priv->wayland.surface->buffer_ref.buffer == buffer); - - if (buffer) - set_cogl_texture (stex, buffer->texture); - else - set_cogl_texture (stex, NULL); + set_cogl_texture (stex, texture); } /** @@ -1077,3 +928,9 @@ meta_shaped_texture_get_image (MetaShapedTexture *stex, return surface; } + +ClutterActor * +meta_shaped_texture_new (void) +{ + return g_object_new (META_TYPE_SHAPED_TEXTURE, NULL); +} diff --git a/src/compositor/meta-window-actor-private.h b/src/compositor/meta-window-actor-private.h index 9f601b592..050b7ad78 100644 --- a/src/compositor/meta-window-actor-private.h +++ b/src/compositor/meta-window-actor-private.h @@ -35,8 +35,6 @@ void meta_window_actor_process_wayland_damage (MetaWindowActor *self, int y, int width, int height); -void meta_window_actor_set_wayland_surface (MetaWindowActor *self, - MetaWaylandSurface *surface); void meta_window_actor_attach_wayland_buffer (MetaWindowActor *self, MetaWaylandBuffer *buffer); diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 2a6314cac..b0959af57 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -16,6 +16,7 @@ #include #include +#include #include /* for gdk_rectangle_union() */ #include @@ -52,6 +53,8 @@ struct _MetaWindowActorPrivate ClutterActor *actor; + MetaWaylandBuffer *buffer; + /* MetaShadowFactory only caches shadows that are actually in use; * to avoid unnecessary recomputation we do two things: 1) we store * both a focused and unfocused shadow for the window. If the window @@ -391,10 +394,7 @@ meta_window_actor_constructed (GObject *object) if (!priv->actor) { - if (meta_is_wayland_compositor ()) - priv->actor = meta_shaped_texture_new_with_wayland_surface (window->surface); - else - priv->actor = meta_shaped_texture_new_with_xwindow (xwindow); + priv->actor = meta_shaped_texture_new (); clutter_actor_add_child (CLUTTER_ACTOR (self), priv->actor); clutter_actor_set_reactive (CLUTTER_ACTOR (self), TRUE); @@ -1014,6 +1014,35 @@ queue_send_frame_messages_timeout (MetaWindowActor *self) priv->send_frame_messages_timer = g_timeout_add_full (META_PRIORITY_REDRAW, offset, send_frame_messages_timeout, self, NULL); } +static void +wayland_surface_update_area (MetaWindowActor *self, + int x, int y, int width, int height) +{ + MetaWindowActorPrivate *priv = self->priv; + struct wl_resource *resource = priv->buffer->resource; + struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get (resource); + + if (shm_buffer) + cogl_wayland_texture_2d_update_area (COGL_TEXTURE_2D (priv->buffer->texture), + shm_buffer, x, y, width, height); +} + +static void +update_area (MetaWindowActor *self, + int x, int y, int width, int height) +{ + MetaWindowActorPrivate *priv = self->priv; + CoglTexture *texture; + + texture = meta_shaped_texture_get_texture (META_SHAPED_TEXTURE (priv->actor)); + + if (meta_is_wayland_compositor ()) + wayland_surface_update_area (self, x, y, width, height); + else + cogl_texture_pixmap_x11_update_area (COGL_TEXTURE_PIXMAP_X11 (texture), + x, y, width, height); +} + static void meta_window_actor_damage_all (MetaWindowActor *self) { @@ -1029,6 +1058,7 @@ meta_window_actor_damage_all (MetaWindowActor *self) if (!priv->mapped || priv->needs_pixmap) return; + update_area (self, 0, 0, cogl_texture_get_width (texture), cogl_texture_get_height (texture)); redraw_queued = meta_shaped_texture_update_area (META_SHAPED_TEXTURE (priv->actor), 0, 0, cogl_texture_get_width (texture), @@ -1350,8 +1380,7 @@ meta_window_actor_detach_x11_pixmap (MetaWindowActor *self) * you are supposed to be able to free a GLXPixmap after freeing the underlying * pixmap, but it certainly doesn't work with current DRI/Mesa */ - meta_shaped_texture_set_pixmap (META_SHAPED_TEXTURE (priv->actor), - None); + meta_shaped_texture_set_texture (META_SHAPED_TEXTURE (priv->actor), NULL); cogl_flush(); XFreePixmap (xdisplay, priv->back_pixmap); @@ -1429,9 +1458,6 @@ meta_window_actor_destroy (MetaWindowActor *self) priv = self->priv; - if (meta_is_wayland_compositor ()) - meta_shaped_texture_set_wayland_surface (META_SHAPED_TEXTURE (priv->actor), NULL); - window = priv->window; window_type = meta_window_get_window_type (window); meta_window_set_compositor_private (window, NULL); @@ -1975,6 +2001,7 @@ check_needs_x11_pixmap (MetaWindowActor *self) if (priv->back_pixmap == None) { + CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ()); CoglTexture *texture; meta_error_trap_push (display); @@ -2003,19 +2030,12 @@ check_needs_x11_pixmap (MetaWindowActor *self) meta_shaped_texture_set_create_mipmaps (META_SHAPED_TEXTURE (priv->actor), FALSE); - meta_shaped_texture_set_pixmap (META_SHAPED_TEXTURE (priv->actor), - priv->back_pixmap); - - texture = meta_shaped_texture_get_texture (META_SHAPED_TEXTURE (priv->actor)); - - /* - * This only works *after* actually setting the pixmap, so we have to - * do it here. - * See: http://bugzilla.clutter-project.org/show_bug.cgi?id=2236 - */ + texture = COGL_TEXTURE (cogl_texture_pixmap_x11_new (ctx, priv->back_pixmap, FALSE, NULL)); if (G_UNLIKELY (!cogl_texture_pixmap_x11_is_using_tfp_extension (COGL_TEXTURE_PIXMAP_X11 (texture)))) g_warning ("NOTE: Not using GLX TFP!\n"); + meta_shaped_texture_set_texture (META_SHAPED_TEXTURE (priv->actor), texture); + /* ::size-changed is supposed to refer to meta_window_get_outer_rect(). * Emitting it here works pretty much OK because a new value of the * *input* rect (which is the outer rect with the addition of invisible @@ -2153,6 +2173,7 @@ meta_window_actor_process_x11_damage (MetaWindowActor *self, if (!priv->mapped || priv->needs_pixmap) return; + update_area (self, event->area.x, event->area.y, event->area.width, event->area.height); redraw_queued = meta_shaped_texture_update_area (META_SHAPED_TEXTURE (priv->actor), event->area.x, event->area.y, @@ -2178,11 +2199,11 @@ meta_window_actor_process_wayland_damage (MetaWindowActor *self, if (!priv->mapped) return; + update_area (self, x, y, width, height); redraw_queued = meta_shaped_texture_update_area (META_SHAPED_TEXTURE (priv->actor), x, y, width, height, clutter_actor_has_mapped_clones (priv->actor) ? NULL : priv->unobscured_region); - priv->repaint_scheduled = priv->repaint_scheduled || redraw_queued; } @@ -2509,31 +2530,17 @@ maybe_emit_size_changed (MetaWindowActor *self, } } -void -meta_window_actor_set_wayland_surface (MetaWindowActor *self, - MetaWaylandSurface *surface) -{ - MetaWindowActorPrivate *priv = self->priv; - - meta_shaped_texture_set_wayland_surface (META_SHAPED_TEXTURE (priv->actor), - surface); - if (surface && surface->buffer_ref.buffer) - maybe_emit_size_changed (self, surface->buffer_ref.buffer); -} - void meta_window_actor_attach_wayland_buffer (MetaWindowActor *self, MetaWaylandBuffer *buffer) { MetaWindowActorPrivate *priv = self->priv; MetaShapedTexture *stex = META_SHAPED_TEXTURE (priv->actor); - CoglTexture *prev_tex = meta_shaped_texture_get_texture (stex); - meta_shaped_texture_attach_wayland_buffer (stex, buffer); - - if (!prev_tex) - meta_window_actor_sync_actor_geometry (self, FALSE); + priv->buffer = buffer; + meta_shaped_texture_set_texture (stex, buffer->texture); + meta_window_actor_sync_actor_geometry (self, FALSE); maybe_emit_size_changed (self, buffer); } diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c index 377e7f2c7..012cd00bf 100644 --- a/src/wayland/meta-wayland-seat.c +++ b/src/wayland/meta-wayland-seat.c @@ -439,12 +439,6 @@ meta_wayland_seat_repick (MetaWaylandSeat *seat, surface = window->surface; } - else if (META_IS_SHAPED_TEXTURE (actor)) - { - MetaShapedTexture *shaped_texture = META_SHAPED_TEXTURE (actor); - - surface = meta_shaped_texture_get_wayland_surface (shaped_texture); - } pointer->current = surface; if (surface != pointer->focus) diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index 0e2244872..0207c7dc8 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -48,11 +48,6 @@ xserver_set_window_id (struct wl_client *client, window = meta_display_lookup_x_window (display, xid); if (window) { - MetaWindowActor *window_actor = - META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - - meta_window_actor_set_wayland_surface (window_actor, surface); - surface->window = window; window->surface = surface; From ea916b6c49b14de3cc92378a9e87747168035bb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Sun, 13 Oct 2013 13:47:53 +0200 Subject: [PATCH 228/889] Introduce MetaSurfaceActor for drawing MetaWindowActor content MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of having MetaWindowActor only have one single MetaShapedTexture as actor drawing its content, introduce a new abstract MetaSurfaceActor that takes care of drawing. This is one step in the direction to decouple MetaWaylandSurface with a MetaWindow and MetaWindowActor (except for shell/xdg surfaces) in order to finally support subsurfaces like features, or any feature where window is not drawn using a single texture. The first step, implemented in this patch, is to not have MetaWindowActor work directly with a shaped texture. There are still some cases where it simply gets the texture and goes on as before, but this should be changed by either removing the need of going via MetaWindowActor or by adding some generic interface to MetaSurfaceActor that doesn't limit its functionality to one shaped texture. There should be no visible difference nor after this patch, but meta_window_actor_get_texture() and meta_surface_actor_get_texture() should be deprecated when equivalent functionality has been introduced. Signed-off-by: Jonas Ådahl https://bugzilla.gnome.org/show_bug.cgi?id=705502 --- src/Makefile.am | 2 + src/compositor/meta-surface-actor.c | 149 +++++++++++++++ src/compositor/meta-surface-actor.h | 66 +++++++ src/compositor/meta-window-actor-private.h | 3 + src/compositor/meta-window-actor.c | 204 ++++++++------------- 5 files changed, 295 insertions(+), 129 deletions(-) create mode 100644 src/compositor/meta-surface-actor.c create mode 100644 src/compositor/meta-surface-actor.h diff --git a/src/Makefile.am b/src/Makefile.am index a8d52bcaf..c50ce1c9f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -80,6 +80,8 @@ libmutter_wayland_la_SOURCES = \ compositor/meta-shadow-factory-private.h \ compositor/meta-shaped-texture.c \ compositor/meta-shaped-texture-private.h \ + compositor/meta-surface-actor.c \ + compositor/meta-surface-actor.h \ compositor/meta-texture-rectangle.c \ compositor/meta-texture-rectangle.h \ compositor/meta-texture-tower.c \ diff --git a/src/compositor/meta-surface-actor.c b/src/compositor/meta-surface-actor.c new file mode 100644 index 000000000..40177ad17 --- /dev/null +++ b/src/compositor/meta-surface-actor.c @@ -0,0 +1,149 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/** + * SECTION:meta-surface-actor + * @title: MetaSurfaceActor + * @short_description: An actor representing a surface in the scene graph + * + * A surface can be either a shaped texture, or a group of shaped texture, + * used to draw the content of a window. + */ + +#include +#include +#include +#include +#include +#include "meta-surface-actor.h" + +#include "meta-shaped-texture-private.h" + +struct _MetaSurfaceActorPrivate +{ + MetaShapedTexture *texture; + MetaWaylandBuffer *buffer; + Pixmap pixmap; +}; + +G_DEFINE_TYPE (MetaSurfaceActor, meta_surface_actor, CLUTTER_TYPE_ACTOR); + +static void +meta_surface_actor_class_init (MetaSurfaceActorClass *klass) +{ + g_type_class_add_private (klass, sizeof (MetaSurfaceActorPrivate)); +} + +static void +meta_surface_actor_init (MetaSurfaceActor *self) +{ + MetaSurfaceActorPrivate *priv; + + priv = self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, + META_TYPE_SURFACE_ACTOR, + MetaSurfaceActorPrivate); + + priv->texture = NULL; +} + +MetaSurfaceActor * +meta_surface_actor_new (void) +{ + MetaSurfaceActor *self = g_object_new (META_TYPE_SURFACE_ACTOR, NULL); + MetaShapedTexture *stex; + + stex = META_SHAPED_TEXTURE (meta_shaped_texture_new ()); + self->priv->texture = stex; + + clutter_actor_add_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (stex)); + + return self; +} + +cairo_surface_t * +meta_surface_actor_get_image (MetaSurfaceActor *self, + cairo_rectangle_int_t *clip) +{ + return meta_shaped_texture_get_image (self->priv->texture, clip); +} + +MetaShapedTexture * +meta_surface_actor_get_texture (MetaSurfaceActor *self) +{ + return self->priv->texture; +} + +void +meta_surface_actor_set_clip_region (MetaSurfaceActor *self, + cairo_region_t *clip_region) +{ + meta_shaped_texture_set_clip_region (self->priv->texture, clip_region); +} + +static void +update_area (MetaSurfaceActor *self, + int x, int y, int width, int height) +{ + MetaSurfaceActorPrivate *priv = self->priv; + + if (meta_is_wayland_compositor ()) + { + struct wl_resource *resource = priv->buffer->resource; + struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get (resource); + + if (shm_buffer) + { + CoglTexture2D *texture = COGL_TEXTURE_2D (priv->buffer->texture); + cogl_wayland_texture_2d_update_area (texture, shm_buffer, x, y, width, height); + } + } + else + { + CoglTexturePixmapX11 *texture = COGL_TEXTURE_PIXMAP_X11 (meta_shaped_texture_get_texture (priv->texture)); + cogl_texture_pixmap_x11_update_area (texture, x, y, width, height); + } +} + +gboolean +meta_surface_actor_damage_all (MetaSurfaceActor *self, + cairo_region_t *unobscured_region) +{ + MetaSurfaceActorPrivate *priv = self->priv; + CoglTexture *texture = meta_shaped_texture_get_texture (priv->texture); + + update_area (self, 0, 0, cogl_texture_get_width (texture), cogl_texture_get_height (texture)); + return meta_shaped_texture_update_area (self->priv->texture, + 0, 0, + cogl_texture_get_width (texture), + cogl_texture_get_height (texture), + unobscured_region); +} + +gboolean +meta_surface_actor_damage_area (MetaSurfaceActor *self, + int x, + int y, + int width, + int height, + cairo_region_t *unobscured_region) +{ + update_area (self, x, y, width, height); + return meta_shaped_texture_update_area (self->priv->texture, + x, y, width, height, + unobscured_region); +} + +void +meta_surface_actor_attach_wayland_buffer (MetaSurfaceActor *self, + MetaWaylandBuffer *buffer) +{ + MetaSurfaceActorPrivate *priv = self->priv; + priv->buffer = buffer; + meta_shaped_texture_set_texture (self->priv->texture, buffer->texture); +} + +void +meta_surface_actor_set_texture (MetaSurfaceActor *self, + CoglTexture *texture) +{ + meta_shaped_texture_set_texture (self->priv->texture, texture); +} diff --git a/src/compositor/meta-surface-actor.h b/src/compositor/meta-surface-actor.h new file mode 100644 index 000000000..a02ea3ce6 --- /dev/null +++ b/src/compositor/meta-surface-actor.h @@ -0,0 +1,66 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +#ifndef META_SURFACE_ACTOR_PRIVATE_H +#define META_SURFACE_ACTOR_PRIVATE_H + +#include + +#include +#include "meta-wayland-private.h" + +G_BEGIN_DECLS + +#define META_TYPE_SURFACE_ACTOR (meta_surface_actor_get_type()) +#define META_SURFACE_ACTOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_SURFACE_ACTOR, MetaSurfaceActor)) +#define META_SURFACE_ACTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_SURFACE_ACTOR, MetaSurfaceActorClass)) +#define META_IS_SURFACE_ACTOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_SURFACE_ACTOR)) +#define META_IS_SURFACE_ACTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_SURFACE_ACTOR)) +#define META_SURFACE_ACTOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_SURFACE_ACTOR, MetaSurfaceActorClass)) + +typedef struct _MetaSurfaceActor MetaSurfaceActor; +typedef struct _MetaSurfaceActorClass MetaSurfaceActorClass; +typedef struct _MetaSurfaceActorPrivate MetaSurfaceActorPrivate; + +struct _MetaSurfaceActorClass +{ + /*< private >*/ + ClutterActorClass parent_class; +}; + +struct _MetaSurfaceActor +{ + ClutterActor parent; + + MetaSurfaceActorPrivate *priv; +}; + +GType meta_surface_actor_get_type (void); + +MetaSurfaceActor *meta_surface_actor_new (void); + +cairo_surface_t *meta_surface_actor_get_image (MetaSurfaceActor *self, + cairo_rectangle_int_t *clip); + +MetaShapedTexture *meta_surface_actor_get_texture (MetaSurfaceActor *self); + +void meta_surface_actor_set_clip_region (MetaSurfaceActor *self, + cairo_region_t *clip_region); + +gboolean meta_surface_actor_damage_all (MetaSurfaceActor *self, + cairo_region_t *unobscured_region); + +gboolean meta_surface_actor_damage_area (MetaSurfaceActor *self, + int x, + int y, + int width, + int height, + cairo_region_t *unobscured_region); + +void meta_surface_actor_set_texture (MetaSurfaceActor *self, + CoglTexture *texture); +void meta_surface_actor_attach_wayland_buffer (MetaSurfaceActor *self, + MetaWaylandBuffer *buffer); + +G_END_DECLS + +#endif /* META_SURFACE_ACTOR_PRIVATE_H */ diff --git a/src/compositor/meta-window-actor-private.h b/src/compositor/meta-window-actor-private.h index 050b7ad78..b9f88c4ca 100644 --- a/src/compositor/meta-window-actor-private.h +++ b/src/compositor/meta-window-actor-private.h @@ -10,6 +10,7 @@ #include #include +#include "meta-surface-actor.h" MetaWindowActor *meta_window_actor_new (MetaWindow *window); @@ -80,4 +81,6 @@ void meta_window_actor_set_unobscured_region (MetaWindowActor *self, void meta_window_actor_effect_completed (MetaWindowActor *actor, gulong event); +MetaSurfaceActor *meta_window_actor_get_surface (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 b0959af57..019c1bc63 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -16,7 +16,6 @@ #include #include -#include #include /* for gdk_rectangle_union() */ #include @@ -31,6 +30,7 @@ #include "meta-shaped-texture-private.h" #include "meta-shadow-factory-private.h" #include "meta-window-actor-private.h" +#include "meta-surface-actor.h" #include "meta-texture-rectangle.h" #include "region-utils.h" #include "meta-wayland-private.h" @@ -51,9 +51,7 @@ struct _MetaWindowActorPrivate Window xwindow; MetaScreen *screen; - ClutterActor *actor; - - MetaWaylandBuffer *buffer; + MetaSurfaceActor *surface; /* MetaShadowFactory only caches shadows that are actually in use; * to avoid unnecessary recomputation we do two things: 1) we store @@ -392,11 +390,11 @@ meta_window_actor_constructed (GObject *object) priv->argb32 = TRUE; } - if (!priv->actor) + if (!priv->surface) { - priv->actor = meta_shaped_texture_new (); + priv->surface = meta_surface_actor_new (); - clutter_actor_add_child (CLUTTER_ACTOR (self), priv->actor); + clutter_actor_add_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface)); clutter_actor_set_reactive (CLUTTER_ACTOR (self), TRUE); /* @@ -406,7 +404,7 @@ meta_window_actor_constructed (GObject *object) * via the container interface, we do not end up with a dangling pointer. * We will release it in dispose(). */ - g_object_ref (priv->actor); + g_object_ref (priv->surface); g_signal_connect_object (window, "notify::decorated", G_CALLBACK (window_decorated_notify), self, 0); @@ -419,7 +417,7 @@ meta_window_actor_constructed (GObject *object) * This is the case where existing window is gaining/loosing frame. * Just ensure the actor is top most (i.e., above shadow). */ - clutter_actor_set_child_above_sibling (CLUTTER_ACTOR (self), priv->actor, NULL); + clutter_actor_set_child_above_sibling (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface), NULL); } meta_window_actor_update_opacity (self); @@ -487,7 +485,7 @@ meta_window_actor_dispose (GObject *object) /* * Release the extra reference we took on the actor. */ - g_clear_object (&priv->actor); + g_clear_object (&priv->surface); G_OBJECT_CLASS (meta_window_actor_parent_class)->dispose (object); } @@ -883,7 +881,21 @@ meta_window_actor_get_meta_window (MetaWindowActor *self) ClutterActor * meta_window_actor_get_texture (MetaWindowActor *self) { - return self->priv->actor; + return CLUTTER_ACTOR (meta_surface_actor_get_texture (self->priv->surface)); +} + +/** + * meta_window_actor_get_surface: + * @self: a #MetaWindowActor + * + * Gets the MetaSurfaceActor that draws the content of this window + * + * Return value: (transfer none): the #MetaSurfaceActor for the contents + */ +MetaSurfaceActor * +meta_window_actor_get_surface (MetaWindowActor *self) +{ + return self->priv->surface; } /** @@ -1014,60 +1026,26 @@ queue_send_frame_messages_timeout (MetaWindowActor *self) priv->send_frame_messages_timer = g_timeout_add_full (META_PRIORITY_REDRAW, offset, send_frame_messages_timeout, self, NULL); } -static void -wayland_surface_update_area (MetaWindowActor *self, - int x, int y, int width, int height) -{ - MetaWindowActorPrivate *priv = self->priv; - struct wl_resource *resource = priv->buffer->resource; - struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get (resource); - - if (shm_buffer) - cogl_wayland_texture_2d_update_area (COGL_TEXTURE_2D (priv->buffer->texture), - shm_buffer, x, y, width, height); -} - -static void -update_area (MetaWindowActor *self, - int x, int y, int width, int height) -{ - MetaWindowActorPrivate *priv = self->priv; - CoglTexture *texture; - - texture = meta_shaped_texture_get_texture (META_SHAPED_TEXTURE (priv->actor)); - - if (meta_is_wayland_compositor ()) - wayland_surface_update_area (self, x, y, width, height); - else - cogl_texture_pixmap_x11_update_area (COGL_TEXTURE_PIXMAP_X11 (texture), - x, y, width, height); -} - static void meta_window_actor_damage_all (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; - CoglTexture *texture; + cairo_region_t *unobscured_region; gboolean redraw_queued; if (!priv->needs_damage_all) return; - texture = meta_shaped_texture_get_texture (META_SHAPED_TEXTURE (priv->actor)); - if (!priv->mapped || priv->needs_pixmap) return; - update_area (self, 0, 0, cogl_texture_get_width (texture), cogl_texture_get_height (texture)); - redraw_queued = meta_shaped_texture_update_area (META_SHAPED_TEXTURE (priv->actor), - 0, 0, - cogl_texture_get_width (texture), - cogl_texture_get_height (texture), - clutter_actor_has_mapped_clones (priv->actor) ? - NULL : priv->unobscured_region); + unobscured_region = + clutter_actor_has_mapped_clones (CLUTTER_ACTOR (priv->surface)) + ? NULL : priv->unobscured_region; - priv->repaint_scheduled = priv->repaint_scheduled || redraw_queued; + redraw_queued = meta_surface_actor_damage_all (priv->surface, unobscured_region); + priv->repaint_scheduled = priv->repaint_scheduled || redraw_queued; priv->needs_damage_all = FALSE; } @@ -1151,7 +1129,7 @@ meta_window_actor_queue_frame_drawn (MetaWindowActor *self, else if (priv->mapped && (!meta_is_wayland_compositor () || !priv->needs_pixmap)) { const cairo_rectangle_int_t clip = { 0, 0, 1, 1 }; - clutter_actor_queue_redraw_with_clip (priv->actor, &clip); + clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (priv->surface), &clip); priv->repaint_scheduled = TRUE; } } @@ -1194,7 +1172,7 @@ meta_window_actor_queue_create_x11_pixmap (MetaWindowActor *self) * * The compositor paint function repairs all windows. */ - clutter_actor_queue_redraw (priv->actor); + clutter_actor_queue_redraw (CLUTTER_ACTOR (priv->surface)); } static gboolean @@ -1284,7 +1262,7 @@ meta_window_actor_after_effects (MetaWindowActor *self) meta_window_actor_detach_x11_pixmap (self); if (priv->needs_pixmap) - clutter_actor_queue_redraw (priv->actor); + clutter_actor_queue_redraw (CLUTTER_ACTOR (priv->surface)); } } @@ -1380,7 +1358,7 @@ meta_window_actor_detach_x11_pixmap (MetaWindowActor *self) * you are supposed to be able to free a GLXPixmap after freeing the underlying * pixmap, but it certainly doesn't work with current DRI/Mesa */ - meta_shaped_texture_set_texture (META_SHAPED_TEXTURE (priv->actor), NULL); + meta_surface_actor_set_texture (priv->surface, NULL); cogl_flush(); XFreePixmap (xdisplay, priv->back_pixmap); @@ -1912,8 +1890,7 @@ meta_window_actor_set_clip_region (MetaWindowActor *self, { MetaWindowActorPrivate *priv = self->priv; - meta_shaped_texture_set_clip_region (META_SHAPED_TEXTURE (priv->actor), - clip_region); + meta_surface_actor_set_clip_region (priv->surface, clip_region); } /** @@ -1960,8 +1937,7 @@ meta_window_actor_reset_clip_regions (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; - meta_shaped_texture_set_clip_region (META_SHAPED_TEXTURE (priv->actor), - NULL); + meta_surface_actor_set_clip_region (priv->surface, NULL); g_clear_pointer (&priv->shadow_clip, cairo_region_destroy); } @@ -1976,7 +1952,6 @@ check_needs_x11_pixmap (MetaWindowActor *self) MetaDisplay *display = meta_screen_get_display (screen); Display *xdisplay = meta_display_get_xdisplay (display); MetaCompScreen *info = meta_screen_get_compositor_data (screen); - MetaCompositor *compositor; Window xwindow = priv->xwindow; if (!priv->needs_pixmap) @@ -1989,8 +1964,6 @@ check_needs_x11_pixmap (MetaWindowActor *self) xwindow == clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage))) return; - compositor = meta_display_get_compositor (display); - if (priv->x11_size_changed) { meta_window_actor_detach_x11_pixmap (self); @@ -2026,15 +1999,11 @@ check_needs_x11_pixmap (MetaWindowActor *self) goto out; } - if (compositor->no_mipmaps) - meta_shaped_texture_set_create_mipmaps (META_SHAPED_TEXTURE (priv->actor), - FALSE); - texture = COGL_TEXTURE (cogl_texture_pixmap_x11_new (ctx, priv->back_pixmap, FALSE, NULL)); if (G_UNLIKELY (!cogl_texture_pixmap_x11_is_using_tfp_extension (COGL_TEXTURE_PIXMAP_X11 (texture)))) g_warning ("NOTE: Not using GLX TFP!\n"); - meta_shaped_texture_set_texture (META_SHAPED_TEXTURE (priv->actor), texture); + meta_surface_actor_set_texture (META_SURFACE_ACTOR (priv->surface), texture); /* ::size-changed is supposed to refer to meta_window_get_outer_rect(). * Emitting it here works pretty much OK because a new value of the @@ -2126,6 +2095,7 @@ meta_window_actor_process_x11_damage (MetaWindowActor *self, MetaWindowActorPrivate *priv = self->priv; MetaCompScreen *info = meta_screen_get_compositor_data (priv->screen); gboolean redraw_queued; + cairo_region_t *unobscured_region; priv->received_x11_damage = TRUE; @@ -2173,14 +2143,15 @@ meta_window_actor_process_x11_damage (MetaWindowActor *self, if (!priv->mapped || priv->needs_pixmap) return; - update_area (self, event->area.x, event->area.y, event->area.width, event->area.height); - redraw_queued = meta_shaped_texture_update_area (META_SHAPED_TEXTURE (priv->actor), - event->area.x, - event->area.y, - event->area.width, - event->area.height, - clutter_actor_has_mapped_clones (priv->actor) ? - NULL : priv->unobscured_region); + unobscured_region = + clutter_actor_has_mapped_clones (CLUTTER_ACTOR (priv->surface)) + ? NULL : priv->unobscured_region; + redraw_queued = meta_surface_actor_damage_area (priv->surface, + event->area.x, + event->area.y, + event->area.width, + event->area.height, + unobscured_region); priv->repaint_scheduled = priv->repaint_scheduled || redraw_queued; @@ -2194,16 +2165,19 @@ meta_window_actor_process_wayland_damage (MetaWindowActor *self, int height) { MetaWindowActorPrivate *priv = self->priv; + cairo_region_t *unobscured_region; gboolean redraw_queued; if (!priv->mapped) return; - update_area (self, x, y, width, height); - redraw_queued = meta_shaped_texture_update_area (META_SHAPED_TEXTURE (priv->actor), - x, y, width, height, - clutter_actor_has_mapped_clones (priv->actor) ? - NULL : priv->unobscured_region); + unobscured_region = + clutter_actor_has_mapped_clones (CLUTTER_ACTOR (priv->surface)) + ? NULL : priv->unobscured_region; + redraw_queued = meta_surface_actor_damage_area (priv->surface, + x, y, width, height, + unobscured_region); + priv->repaint_scheduled = priv->repaint_scheduled || redraw_queued; } @@ -2266,12 +2240,18 @@ build_and_scan_frame_mask (MetaWindowActor *self, MetaWindowActorPrivate *priv = self->priv; guchar *mask_data; guint tex_width, tex_height; + MetaShapedTexture *stex; CoglTexture *paint_tex, *mask_texture; int stride; cairo_t *cr; cairo_surface_t *surface; - paint_tex = meta_shaped_texture_get_texture (META_SHAPED_TEXTURE (priv->actor)); + stex = meta_surface_actor_get_texture (priv->surface); + g_return_if_fail (stex); + + meta_shaped_texture_set_mask_texture (stex, NULL); + + paint_tex = meta_shaped_texture_get_texture (stex); if (paint_tex == NULL) return; @@ -2339,8 +2319,7 @@ build_and_scan_frame_mask (MetaWindowActor *self, mask_data); } - meta_shaped_texture_set_mask_texture (META_SHAPED_TEXTURE (priv->actor), - mask_texture); + meta_shaped_texture_set_mask_texture (stex, mask_texture); cogl_object_unref (mask_texture); g_free (mask_data); @@ -2370,7 +2349,6 @@ meta_window_actor_update_shape_region (MetaWindowActor *self, region = cairo_region_create_rectangle (client_area); } - meta_shaped_texture_set_mask_texture (META_SHAPED_TEXTURE (priv->actor), NULL); if ((priv->window->shape_region != NULL) || (priv->window->frame != NULL)) build_and_scan_frame_mask (self, client_area, region); @@ -2387,9 +2365,12 @@ meta_window_actor_update_input_region (MetaWindowActor *self, cairo_rectangle_int_t *client_area) { MetaWindowActorPrivate *priv = self->priv; - MetaShapedTexture *stex = META_SHAPED_TEXTURE (priv->actor); + MetaShapedTexture *stex = meta_surface_actor_get_texture (priv->surface); cairo_region_t *region = NULL; + if (!stex) + return; + if (priv->window->frame != NULL && priv->window->input_region != NULL) { region = meta_frame_get_frame_bounds (priv->window->frame); @@ -2422,6 +2403,11 @@ static void meta_window_actor_update_opaque_region (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; + MetaShapedTexture *stex; + + stex = meta_surface_actor_get_texture (priv->surface); + if (!stex) + return; g_clear_pointer (&priv->opaque_region, cairo_region_destroy); @@ -2450,8 +2436,7 @@ meta_window_actor_update_opaque_region (MetaWindowActor *self) else priv->opaque_region = cairo_region_reference (priv->shape_region); - meta_shaped_texture_set_opaque_region (META_SHAPED_TEXTURE (priv->actor), - priv->opaque_region); + meta_shaped_texture_set_opaque_region (stex, priv->opaque_region); } static void @@ -2494,40 +2479,7 @@ meta_window_actor_update_shape (MetaWindowActor *self) if (is_frozen (self)) return; - clutter_actor_queue_redraw (priv->actor); -} - -static void -maybe_emit_size_changed (MetaWindowActor *self, - MetaWaylandBuffer *new_buffer) -{ - MetaWindowActorPrivate *priv = self->priv; - int width = 0, height = 0; - - if (new_buffer) - { - width = new_buffer->width; - height = new_buffer->height; - } - - if (priv->last_width != width || priv->last_height != height) - { - meta_window_actor_update_shape (self); - - /* ::size-changed is supposed to refer to meta_window_get_outer_rect() - * but here we are only looking at buffer size changes. - * - * Emitting it here works pretty much OK because a new buffer size (which - * will correspond to the outer rect with the addition of invisible - * borders) also normally implies a change to the outer rect. In the rare - * case where a change to the window size was exactly balanced by a - * change to the invisible borders, we would miss emitting the signal. - */ - g_signal_emit (self, signals[SIZE_CHANGED], 0); - - priv->last_width = width; - priv->last_height = height; - } + clutter_actor_queue_redraw (CLUTTER_ACTOR (priv->surface)); } void @@ -2535,13 +2487,7 @@ meta_window_actor_attach_wayland_buffer (MetaWindowActor *self, MetaWaylandBuffer *buffer) { MetaWindowActorPrivate *priv = self->priv; - MetaShapedTexture *stex = META_SHAPED_TEXTURE (priv->actor); - - priv->buffer = buffer; - - meta_shaped_texture_set_texture (stex, buffer->texture); - meta_window_actor_sync_actor_geometry (self, FALSE); - maybe_emit_size_changed (self, buffer); + meta_surface_actor_attach_wayland_buffer (priv->surface, buffer); } static void @@ -2793,7 +2739,7 @@ meta_window_actor_update_opacity (MetaWindowActor *self) opacity = 255; self->priv->opacity = opacity; - clutter_actor_set_opacity (self->priv->actor, opacity); + clutter_actor_set_opacity (CLUTTER_ACTOR (self->priv->surface), opacity); } void From 7c45d6594c3878fe1be463c3ab0358b7a3cbb32f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Sun, 13 Oct 2013 18:59:30 +0200 Subject: [PATCH 229/889] MetaWindowActor: Use allocation changes signals for size changed signals MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a Wayland compositor, simply rely on the clutter actor allocation changed signal to sync geometry and emit window actor size changed signals. Attaching a wl_buffer to a MetaShapedTexture will signal allocation changed on the corresponding MetaSurfaceActor, which the MetaWindowActor is listening to. Signed-off-by: Jonas Ådahl https://bugzilla.gnome.org/show_bug.cgi?id=705502 --- src/compositor/meta-window-actor.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 019c1bc63..a03f84f52 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -53,6 +53,8 @@ struct _MetaWindowActorPrivate MetaSurfaceActor *surface; + guint surface_allocation_changed_id; + /* MetaShadowFactory only caches shadows that are actually in use; * to avoid unnecessary recomputation we do two things: 1) we store * both a focused and unfocused shadow for the window. If the window @@ -299,6 +301,8 @@ meta_window_actor_init (MetaWindowActor *self) priv = self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, META_TYPE_WINDOW_ACTOR, MetaWindowActorPrivate); + + priv->surface_allocation_changed_id = 0; priv->opacity = 0xff; priv->shadow_class = NULL; } @@ -360,6 +364,17 @@ window_appears_focused_notify (MetaWindow *mw, clutter_actor_queue_redraw (CLUTTER_ACTOR (data)); } +static void +surface_allocation_changed_notify (ClutterActor *actor, + const ClutterActorBox *allocation, + ClutterAllocationFlags flags, + MetaWindowActor *self) +{ + meta_window_actor_sync_actor_geometry (self, FALSE); + + g_signal_emit (self, signals[SIZE_CHANGED], 0); +} + static void meta_window_actor_constructed (GObject *object) { @@ -397,6 +412,12 @@ meta_window_actor_constructed (GObject *object) clutter_actor_add_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface)); clutter_actor_set_reactive (CLUTTER_ACTOR (self), TRUE); + priv->surface_allocation_changed_id = + g_signal_connect (CLUTTER_ACTOR (priv->surface), + "allocation-changed", + G_CALLBACK (surface_allocation_changed_notify), + self); + /* * Since we are holding a pointer to this actor independently of the * ClutterContainer internals, and provide a public API to access it, @@ -482,6 +503,11 @@ meta_window_actor_dispose (GObject *object) g_clear_object (&priv->window); + if (priv->surface != NULL && priv->surface_allocation_changed_id != 0) + g_signal_handler_disconnect (priv->surface, + priv->surface_allocation_changed_id); + priv->surface_allocation_changed_id = 0; + /* * Release the extra reference we took on the actor. */ From 74462133ca7e85aabaac634517dbd5dd0a7742c2 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 18 Nov 2013 21:35:30 -0500 Subject: [PATCH 230/889] ff --- src/compositor/meta-surface-actor.c | 4 +--- src/compositor/meta-surface-content-wayland.c | 13 +++++++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 src/compositor/meta-surface-content-wayland.c diff --git a/src/compositor/meta-surface-actor.c b/src/compositor/meta-surface-actor.c index 40177ad17..536b83d58 100644 --- a/src/compositor/meta-surface-actor.c +++ b/src/compositor/meta-surface-actor.c @@ -20,9 +20,7 @@ struct _MetaSurfaceActorPrivate { - MetaShapedTexture *texture; - MetaWaylandBuffer *buffer; - Pixmap pixmap; + MetaSurfaceContentWayland *main_content; }; G_DEFINE_TYPE (MetaSurfaceActor, meta_surface_actor, CLUTTER_TYPE_ACTOR); diff --git a/src/compositor/meta-surface-content-wayland.c b/src/compositor/meta-surface-content-wayland.c new file mode 100644 index 000000000..50330b0cf --- /dev/null +++ b/src/compositor/meta-surface-content-wayland.c @@ -0,0 +1,13 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +#include "config.h" + +struct _MetaSurfaceContentWayland { + MetaShapedTexture *texture; + MetaWaylandSurface *surface; +}; + +MetaSurfaceContentWayland * +meta_surface_content_wayland_new (MetaWaylandSurface *surface) +{ +} From c749f7b6fb9ba270a99a7568f85dfd495ab62e30 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 19 Nov 2013 11:22:49 -0500 Subject: [PATCH 231/889] Revert "ff" This reverts commit 74462133ca7e85aabaac634517dbd5dd0a7742c2. Pushed by accident, if it wasn't obvious... --- src/compositor/meta-surface-actor.c | 4 +++- src/compositor/meta-surface-content-wayland.c | 13 ------------- 2 files changed, 3 insertions(+), 14 deletions(-) delete mode 100644 src/compositor/meta-surface-content-wayland.c diff --git a/src/compositor/meta-surface-actor.c b/src/compositor/meta-surface-actor.c index 536b83d58..40177ad17 100644 --- a/src/compositor/meta-surface-actor.c +++ b/src/compositor/meta-surface-actor.c @@ -20,7 +20,9 @@ struct _MetaSurfaceActorPrivate { - MetaSurfaceContentWayland *main_content; + MetaShapedTexture *texture; + MetaWaylandBuffer *buffer; + Pixmap pixmap; }; G_DEFINE_TYPE (MetaSurfaceActor, meta_surface_actor, CLUTTER_TYPE_ACTOR); diff --git a/src/compositor/meta-surface-content-wayland.c b/src/compositor/meta-surface-content-wayland.c deleted file mode 100644 index 50330b0cf..000000000 --- a/src/compositor/meta-surface-content-wayland.c +++ /dev/null @@ -1,13 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -#include "config.h" - -struct _MetaSurfaceContentWayland { - MetaShapedTexture *texture; - MetaWaylandSurface *surface; -}; - -MetaSurfaceContentWayland * -meta_surface_content_wayland_new (MetaWaylandSurface *surface) -{ -} From f0280a88685deaab17e3fce8b95c537883f9d55e Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 19 Nov 2013 12:47:50 -0500 Subject: [PATCH 232/889] wayland-surface: Allow setting a NULL buffer to effectively unmap --- src/wayland/meta-wayland-surface.c | 60 +++++++++++++++--------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 50ebe850e..0bfd7b160 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -260,6 +260,28 @@ surface_ensure_window (MetaWaylandSurface *surface) surface->window = meta_window_new_for_wayland (display, width, height, surface); } +static void +ensure_buffer_texture (MetaWaylandBuffer *buffer) +{ + CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ()); + CoglError *catch_error = NULL; + CoglTexture *texture; + + texture = COGL_TEXTURE (cogl_wayland_texture_2d_new_from_buffer (ctx, + buffer->resource, + &catch_error)); + if (!texture) + { + cogl_error_free (catch_error); + meta_warning ("Could not import pending buffer, ignoring commit\n"); + return; + } + + buffer->texture = texture; + buffer->width = cogl_texture_get_width (texture); + buffer->height = cogl_texture_get_height (texture); +} + static void meta_wayland_surface_commit (struct wl_client *client, struct wl_resource *resource) @@ -278,37 +300,15 @@ meta_wayland_surface_commit (struct wl_client *client, surface->buffer_ref.buffer != surface->pending.buffer) { MetaWaylandBuffer *buffer = surface->pending.buffer; - CoglContext *ctx = - clutter_backend_get_cogl_context (clutter_get_default_backend ()); - CoglError *catch_error = NULL; - CoglTexture *texture = - COGL_TEXTURE (cogl_wayland_texture_2d_new_from_buffer (ctx, - buffer->resource, - &catch_error)); - if (!texture) - { - cogl_error_free (catch_error); - meta_warning ("Could not import pending buffer, ignoring commit\n"); - return; - } - else - { - buffer->texture = texture; - buffer->width = cogl_texture_get_width (texture); - buffer->height = cogl_texture_get_height (texture); - } - /* Note: we set this before informing any window-actor since the - * window actor will expect to find the new buffer within the - * surface. */ - meta_wayland_buffer_reference (&surface->buffer_ref, - surface->pending.buffer); - } - - if (!surface->buffer_ref.buffer) - { - meta_warning ("Commit without a buffer? Ignoring\n"); - return; + if (buffer) + { + /* Note: we set this before informing any window-actor since the + * window actor will expect to find the new buffer within the + * surface. */ + ensure_buffer_texture (buffer); + meta_wayland_buffer_reference (&surface->buffer_ref, buffer); + } } surface_ensure_window (surface); From 9461c612dea0c1f1328947f99f31998ba28872e8 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 19 Nov 2013 13:00:34 -0500 Subject: [PATCH 233/889] wayland-surface: Only spew about set_buffer_scale if it's not 1 ... to stop the GTK+ spam on my system. --- src/wayland/meta-wayland-surface.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 0bfd7b160..1df898182 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -400,7 +400,8 @@ meta_wayland_surface_set_buffer_scale (struct wl_client *client, struct wl_resource *resource, int scale) { - g_warning ("TODO: support set_buffer_scale request"); + if (scale != 1) + g_warning ("TODO: support set_buffer_scale request"); } const struct wl_surface_interface meta_wayland_surface_interface = { From 2b2b2d319191f5e2af725b6d3a1e24384ca7781b Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 19 Nov 2013 13:08:34 -0500 Subject: [PATCH 234/889] stack: Don't take a weak pointer Since this is stored in an array full of data that will be copied around, we can't rely on pointer addresses for every item in a stack not changing. I don't see any reason that we even have a weak pointer, either. This code looks safe to me without it. --- src/core/stack.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/core/stack.c b/src/core/stack.c index 96e88e715..911dc35fb 100644 --- a/src/core/stack.c +++ b/src/core/stack.c @@ -92,16 +92,6 @@ meta_stack_new (MetaScreen *screen) static void free_last_all_root_children_stacked_cache (MetaStack *stack) { - unsigned int i; - - for (i = 0; i < stack->last_all_root_children_stacked->len; i++) - { - MetaStackWindow *window = &g_array_index (stack->last_all_root_children_stacked, MetaStackWindow, i); - if (window->any.type == META_WINDOW_CLIENT_TYPE_WAYLAND) - g_object_remove_weak_pointer (G_OBJECT (window->wayland.meta_window), - (gpointer *)&window->wayland.meta_window); - } - g_array_free (stack->last_all_root_children_stacked, TRUE); stack->last_all_root_children_stacked = NULL; } @@ -1345,8 +1335,6 @@ stack_sync_to_xserver (MetaStack *stack) * stale because the corresponding window has been freed we * associate a weak pointer with the new window. */ new = &g_array_index (all_root_children_stacked, MetaStackWindow, all_root_children_stacked->len - 1); - g_object_add_weak_pointer (G_OBJECT (new->wayland.meta_window), - (gpointer *)&new->wayland.meta_window); } } From f3e52d5b18f3e2ad7697ad74bd9ccab90fb21d9e Mon Sep 17 00:00:00 2001 From: Rico Tzschichholz Date: Wed, 30 Oct 2013 23:42:12 +0100 Subject: [PATCH 235/889] build: Do not ship generated source-files in tarball --- src/Makefile.am | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Makefile.am b/src/Makefile.am index c50ce1c9f..81ed2d259 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -188,7 +188,9 @@ libmutter_wayland_la_SOURCES = \ ui/theme.c \ meta/theme.h \ ui/theme-private.h \ - ui/ui.c \ + ui/ui.c + +nodist_libmutter_wayland_la_SOURCES = \ $(mutter_built_sources) libmutter_wayland_la_SOURCES += \ From 68eb87cc585bdae922fab2bf20c030afe8cec75e Mon Sep 17 00:00:00 2001 From: Rico Tzschichholz Date: Thu, 31 Oct 2013 00:09:15 +0100 Subject: [PATCH 236/889] build: Make sure built-sources are introspected as needed --- src/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Makefile.am b/src/Makefile.am index 81ed2d259..1833d24e6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -305,6 +305,7 @@ Meta-$(api_version).gir: libmutter-wayland.la mutter-enum-types.h \ $(libmutterinclude_base_headers) \ $(filter %.c,$(libmutter_wayland_la_SOURCES)) + $(filter %.c,$(libmutter_wayland_la_SOURCES) $(nodist_libmutter_wayland_la_SOURCES)) @META_GIR@_SCANNERFLAGS = --warn-all --warn-error endif From 82cb4e8267050c26b54e1ebbea17d28bd0aa14f6 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 16 Oct 2013 22:33:47 -0400 Subject: [PATCH 237/889] display: Don't focus the no-focus-window when sending WM_TAKE_FOCUS to a globally active window Clients like on-screen keyboards try not to take focus when the user clicks on their window by setting the Input hint to false. However, due to GTK+ and GDK bugs, the public API for setting the Input hint to false don't remove WM_TAKE_FOCUS from WM_PROTOCOLS, unintentionally putting them into Globally Active mode. These clients also expect that since they don't want to take focus, they want the focus to remain on the existing window. In this case, for clients like on-screen keyboards, it's so they can send synthesized keyboard events to the focused window. https://bugzilla.gnome.org/show_bug.cgi?id=710296 --- src/core/display.c | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/src/core/display.c b/src/core/display.c index fa5d85b31..5649f9a5a 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -5744,25 +5744,6 @@ meta_display_request_take_focus (MetaDisplay *display, meta_topic (META_DEBUG_FOCUS, "WM_TAKE_FOCUS(%s, %u)\n", window->desc, timestamp); - if (window != display->focus_window) - { - /* The "Globally Active Input" window case, where the window - * doesn't want us to call XSetInputFocus on it, but does - * want us to send a WM_TAKE_FOCUS. - * - * We can't just set display->focus_window to @window, since we - * we don't know when (or even if) the window will actually take - * focus, so we could end up being wrong for arbitrarily long. - * But we also can't leave it set to the current window, or else - * bug #597352 would come back. So we focus the no_focus_window - * now (and set display->focus_window to that), send the - * WM_TAKE_FOCUS, and then just forget about @window - * until/unless we get a FocusIn. - */ - meta_display_focus_the_no_focus_window (display, - window->screen, - timestamp); - } meta_window_send_icccm_message (window, display->atom_WM_TAKE_FOCUS, timestamp); From e91268a250a772759dc29c0660cecffd2b8d9c77 Mon Sep 17 00:00:00 2001 From: Sindhu S Date: Thu, 25 Jul 2013 00:25:23 +0530 Subject: [PATCH 238/889] Add keyboard shortcut for Always on Top, bug 704831 --- src/core/keybindings.c | 21 +++++++++++++++++++++ src/meta/prefs.h | 2 ++ 2 files changed, 23 insertions(+) diff --git a/src/core/keybindings.c b/src/core/keybindings.c index 873938528..6d93a8089 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -3094,6 +3094,20 @@ handle_maximize_horizontally (MetaDisplay *display, } } +static void +handle_always_on_top (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + XIDeviceEvent *event, + MetaKeyBinding *binding, + gpointer dummy) +{ + if (window->wm_state_above == FALSE) + meta_window_make_above (window); + else + meta_window_unmake_above (window); +} + /* Move a window to a corner; to_bottom/to_right are FALSE for the * top or left edge, or TRUE for the bottom/right edge. xchange/ychange * are FALSE if that dimension is not to be changed, TRUE otherwise. @@ -4691,6 +4705,13 @@ init_builtin_key_bindings (MetaDisplay *display) META_KEYBINDING_ACTION_MAXIMIZE_HORIZONTALLY, handle_maximize_horizontally, 0); + add_builtin_keybinding (display, + "always-on-top", + common_keybindings, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_ALWAYS_ON_TOP, + handle_always_on_top, 0); + add_builtin_keybinding (display, "move-to-corner-nw", common_keybindings, diff --git a/src/meta/prefs.h b/src/meta/prefs.h index e98b4174a..41399684b 100644 --- a/src/meta/prefs.h +++ b/src/meta/prefs.h @@ -248,6 +248,7 @@ void meta_prefs_set_ignore_request_hide_titlebar (gboolean whether); * @META_KEYBINDING_ACTION_LOWER: FILLME * @META_KEYBINDING_ACTION_MAXIMIZE_VERTICALLY: FILLME * @META_KEYBINDING_ACTION_MAXIMIZE_HORIZONTALLY: FILLME + * @META_KEYBINDING_ACTION_ALWAYS_ON_TOP: FILLME * @META_KEYBINDING_ACTION_MOVE_TO_CORNER_NW: FILLME * @META_KEYBINDING_ACTION_MOVE_TO_CORNER_NE: FILLME * @META_KEYBINDING_ACTION_MOVE_TO_CORNER_SW: FILLME @@ -339,6 +340,7 @@ typedef enum _MetaKeyBindingAction META_KEYBINDING_ACTION_RAISE, META_KEYBINDING_ACTION_LOWER, META_KEYBINDING_ACTION_MAXIMIZE_VERTICALLY, + META_KEYBINDING_ACTION_ALWAYS_ON_TOP, META_KEYBINDING_ACTION_MAXIMIZE_HORIZONTALLY, META_KEYBINDING_ACTION_MOVE_TO_CORNER_NW, META_KEYBINDING_ACTION_MOVE_TO_CORNER_NE, From 17fd25e21643534e12c376d5fc69bbc9bd1aca25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 13 Nov 2013 20:47:48 +0100 Subject: [PATCH 239/889] doc: Fix file globs Any files matching the previously used globs are no longer distributed, breaking distcheck. Match the actual sources in compositor/, core/, meta/ and ui/ instead. --- doc/reference/Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/reference/Makefile.am b/doc/reference/Makefile.am index 0776f71f9..e0e702e58 100644 --- a/doc/reference/Makefile.am +++ b/doc/reference/Makefile.am @@ -49,8 +49,8 @@ FIXXREF_OPTIONS= # Used for dependencies. The docs will be rebuilt if any of these change. # e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h # e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c -HFILE_GLOB=$(top_srcdir)/src/*.h -CFILE_GLOB=$(top_srcdir)/src/*.c +HFILE_GLOB=$(top_srcdir)/src/*/*.h +CFILE_GLOB=$(top_srcdir)/src/*/*.c # Extra header to include when scanning, which are not under DOC_SOURCE_DIR # e.g. EXTRA_HFILES=$(top_srcdir}/contrib/extra.h From 957513242c26be458be7a101b83180e3f59f6a44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Thu, 31 Oct 2013 14:37:44 +0100 Subject: [PATCH 240/889] xrandr: use "hotplug_mode_update" property Use the "hotplug_mode_update" connector property indicating that the screen settings should be updated: get a new preferred mode on hotplug events to handle dynamic guest resizing (where you resize the host window and the guest resizes with it). https://bugzilla.gnome.org/show_bug.cgi?id=711216 --- src/core/monitor-config.c | 16 ++++++++ src/core/monitor-private.h | 4 ++ src/core/monitor-xrandr.c | 81 ++++++++++++++++++++++++++++---------- src/meta/atomnames.h | 1 + 4 files changed, 82 insertions(+), 20 deletions(-) diff --git a/src/core/monitor-config.c b/src/core/monitor-config.c index ddda53a1a..e5aee4d00 100644 --- a/src/core/monitor-config.c +++ b/src/core/monitor-config.c @@ -817,6 +817,22 @@ meta_monitor_config_match_current (MetaMonitorConfig *self, return ok; } +gboolean +meta_monitor_manager_has_hotplug_mode_update (MetaMonitorManager *manager) +{ + MetaOutput *outputs; + unsigned n_outputs; + unsigned int i; + + outputs = meta_monitor_manager_get_outputs (manager, &n_outputs); + + for (i = 0; i < n_outputs; i++) + if (outputs[i].hotplug_mode_update) + return TRUE; + + return FALSE; +} + static MetaConfiguration * meta_monitor_config_get_stored (MetaMonitorConfig *self, MetaOutput *outputs, diff --git a/src/core/monitor-private.h b/src/core/monitor-private.h index a8eeb678f..fdb11a7ec 100644 --- a/src/core/monitor-private.h +++ b/src/core/monitor-private.h @@ -119,6 +119,9 @@ struct _MetaOutput gpointer driver_private; GDestroyNotify driver_notify; + + /* get a new preferred mode on hotplug events, to handle dynamic guest resizing */ + gboolean hotplug_mode_update; }; struct _MetaCRTC @@ -407,6 +410,7 @@ void meta_monitor_manager_free_output_array (MetaOutput *old_outpu int n_old_outputs); void meta_monitor_manager_free_mode_array (MetaMonitorMode *old_modes, int n_old_modes); +gboolean meta_monitor_manager_has_hotplug_mode_update (MetaMonitorManager *manager); /* Returns true if transform causes width and height to be inverted This is true for the odd transforms in the enum */ diff --git a/src/core/monitor-xrandr.c b/src/core/monitor-xrandr.c index ab1cf1139..e723c1c51 100644 --- a/src/core/monitor-xrandr.c +++ b/src/core/monitor-xrandr.c @@ -311,6 +311,29 @@ read_output_edid (MetaMonitorManagerXrandr *manager_xrandr, return NULL; } +static gboolean +output_get_hotplug_mode_update (MetaMonitorManagerXrandr *manager_xrandr, + XID output_id) +{ + MetaDisplay *display = meta_get_display (); + XRRPropertyInfo *info; + gboolean result = FALSE; + + meta_error_trap_push (display); + info = XRRQueryOutputProperty (manager_xrandr->xdisplay, output_id, + display->atom_hotplug_mode_update); + meta_error_trap_pop (display); + + if (info) + { + result = TRUE; + XFree (info); + } + + return result; +} + + static void meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager) { @@ -484,6 +507,8 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager) meta_output->width_mm = output->mm_width; meta_output->height_mm = output->mm_height; meta_output->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN; + meta_output->hotplug_mode_update = + output_get_hotplug_mode_update (manager_xrandr, meta_output->output_id); meta_output->n_modes = output->nmode; meta_output->modes = g_new0 (MetaMonitorMode *, meta_output->n_modes); @@ -969,6 +994,16 @@ meta_monitor_manager_xrandr_set_crtc_gamma (MetaMonitorManager *manager, XRRFreeGamma (gamma); } +static void +meta_monitor_manager_xrandr_rebuild_derived (MetaMonitorManager *manager) +{ + /* This will be a no-op if the change was from our side, as + we already called it in the DBus method handler */ + meta_monitor_config_update_current (manager->config, manager); + + meta_monitor_manager_rebuild_derived (manager); +} + static gboolean meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManager *manager, XEvent *event) @@ -978,6 +1013,7 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManager *manager, MetaCRTC *old_crtcs; MetaMonitorMode *old_modes; unsigned int n_old_outputs, n_old_modes; + gboolean new_config; if ((event->type - manager_xrandr->rr_event_base) != RRScreenChangeNotify) return FALSE; @@ -994,31 +1030,36 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManager *manager, manager->serial++; meta_monitor_manager_xrandr_read_current (manager); - /* Check if the current intended configuration has the same outputs - as the new real one, or if the event is a result of an XRandR call. - If so, we can go straight to rebuild the logical config and tell - the outside world. - Otherwise, this event was caused by hotplug, so give a chance to - MetaMonitorConfig. + new_config = manager_xrandr->resources->timestamp >= + manager_xrandr->resources->configTimestamp; + if (meta_monitor_manager_has_hotplug_mode_update (manager)) - Note that we need to check both the timestamps and the list of - outputs, because the X server might emit spurious events with - new configTimestamps (bug 702804), and the driver may have - changed the EDID for some other reason (old broken qxl and vbox - drivers...). - */ - if (manager_xrandr->resources->timestamp >= manager_xrandr->resources->configTimestamp || - meta_monitor_config_match_current (manager->config, manager)) { - /* This will be a no-op if the change was from our side, as - we already called it in the DBus method handler */ - meta_monitor_config_update_current (manager->config, manager); - - meta_monitor_manager_rebuild_derived (manager); + /* Check if the current intended configuration is a result of an + XRandR call. Otherwise, hotplug_mode_update tells us to get + a new preferred mode on hotplug events to handle dynamic + guest resizing. */ + if (new_config) + meta_monitor_manager_xrandr_rebuild_derived (manager); + else + meta_monitor_config_make_default (manager->config, manager); } else { - if (!meta_monitor_config_apply_stored (manager->config, manager)) + /* Check if the current intended configuration has the same outputs + as the new real one, or if the event is a result of an XRandR call. + If so, we can go straight to rebuild the logical config and tell + the outside world. + Otherwise, this event was caused by hotplug, so give a chance to + MetaMonitorConfig. + + Note that we need to check both the timestamps and the list of + outputs, because the X server might emit spurious events with new + configTimestamps (bug 702804), and the driver may have changed + the EDID for some other reason (old qxl and vbox drivers). */ + if (new_config || meta_monitor_config_match_current (manager->config, manager)) + meta_monitor_manager_xrandr_rebuild_derived (manager); + else if (!meta_monitor_config_apply_stored (manager->config, manager)) meta_monitor_config_make_default (manager->config, manager); } diff --git a/src/meta/atomnames.h b/src/meta/atomnames.h index 43a18a9c9..e90b0abe4 100644 --- a/src/meta/atomnames.h +++ b/src/meta/atomnames.h @@ -82,6 +82,7 @@ item(VERSION) item(ATOM_PAIR) item(BACKLIGHT) item(_XKB_RULES_NAMES) +item(hotplug_mode_update) /* Oddities: These are used, and we need atoms for them, * but when we need all _NET_WM hints (i.e. when we're making From f6144082b1cd7a3da0389f714a47d3c508099f81 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 4 Nov 2013 10:32:42 -0500 Subject: [PATCH 241/889] compositor: Initialize the plugin manager after initializing the output window Plugins like gnome-shell may want to grab the output window immediately before bouncing back to the mainloop. --- src/compositor/compositor.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 706650c33..e7140c6f9 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -787,8 +787,6 @@ meta_compositor_manage_screen (MetaCompositor *compositor, clutter_actor_add_child (info->stage, info->window_group); clutter_actor_add_child (info->stage, info->top_window_group); - info->plugin_mgr = meta_plugin_manager_new (screen); - if (meta_is_wayland_compositor ()) { /* NB: When running as a wayland compositor we don't need an X @@ -825,6 +823,8 @@ meta_compositor_manage_screen (MetaCompositor *compositor, info->pending_input_region = None; } + info->plugin_mgr = meta_plugin_manager_new (screen); + /* Map overlay window before redirecting windows offscreen so we catch their * contents until we show the stage. */ From 26aa10a974f3b43b2226fe538ceedf256d236d53 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 5 Nov 2013 09:15:05 -0500 Subject: [PATCH 242/889] compositor: Clean up comment So it seems that we were intentionally delaying the output window, although I wonder why... --- src/compositor/compositor.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index e7140c6f9..f7312a4ba 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -796,13 +796,6 @@ meta_compositor_manage_screen (MetaCompositor *compositor, } else { - /* - * Delay the creation of the overlay window as long as we can, to avoid - * blanking out the screen. This means that during the plugin loading, the - * overlay window is not accessible; if the plugin needs to access it - * directly, it should hook into the "show" signal on stage, and do - * its stuff there. - */ info->output = get_output_window (screen); XReparentWindow (xdisplay, xwin, info->output, 0, 0); From a841fff2acd5493d5ee9b794db5d614cc594a411 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sat, 9 Nov 2013 11:06:53 -0500 Subject: [PATCH 243/889] screen: Laters are not GSources This warns with the new GLib when we destroy the screen. https://bugzilla.gnome.org/show_bug.cgi?id=711731 --- src/core/screen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/screen.c b/src/core/screen.c index c69a5fda1..5ade5df20 100644 --- a/src/core/screen.c +++ b/src/core/screen.c @@ -859,9 +859,9 @@ meta_screen_free (MetaScreen *screen, screen->wm_sn_selection_window); if (screen->work_area_later != 0) - g_source_remove (screen->work_area_later); + meta_later_remove (screen->work_area_later); if (screen->check_fullscreen_later != 0) - g_source_remove (screen->check_fullscreen_later); + meta_later_remove (screen->check_fullscreen_later); if (screen->monitor_infos) g_free (screen->monitor_infos); From 6867d44573563cc2f18b079286651fa66ea61a1f Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Wed, 16 Oct 2013 21:29:54 +0100 Subject: [PATCH 244/889] window: don't ignore resize button release event for move/resize actions https://bugzilla.gnome.org/show_bug.cgi?id=710251 --- src/core/window.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/window.c b/src/core/window.c index bef47bec8..583cbcc2e 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -10001,7 +10001,8 @@ meta_window_handle_mouse_grab_op_event (MetaWindow *window, switch (event->type) { case CLUTTER_BUTTON_RELEASE: - if (event->button.button == 1) + if (event->button.button == 1 || + event->button.button == meta_prefs_get_mouse_button_resize ()) { meta_display_check_threshold_reached (window->display, event->button.x, From 392e22483158be484cc5772616656b245370880e Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 7 Oct 2013 15:37:45 -0400 Subject: [PATCH 245/889] Fix build Forgot to delete the line above it when cherry-picking... oops. --- src/Makefile.am | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Makefile.am b/src/Makefile.am index 1833d24e6..20bea802e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -304,7 +304,6 @@ Meta-$(api_version).gir: libmutter-wayland.la @META_GIR@_FILES = \ mutter-enum-types.h \ $(libmutterinclude_base_headers) \ - $(filter %.c,$(libmutter_wayland_la_SOURCES)) $(filter %.c,$(libmutter_wayland_la_SOURCES) $(nodist_libmutter_wayland_la_SOURCES)) @META_GIR@_SCANNERFLAGS = --warn-all --warn-error From f0397eab9432fd234eb0e08bfe283fc467aaee21 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 19 Nov 2013 14:02:42 -0500 Subject: [PATCH 246/889] keybindings: Fix warning keybinding handlers now take a ClutterEvent, not an XIDeviceEvent --- src/core/keybindings.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/core/keybindings.c b/src/core/keybindings.c index 6d93a8089..526efc36f 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -3095,12 +3095,12 @@ handle_maximize_horizontally (MetaDisplay *display, } static void -handle_always_on_top (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XIDeviceEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_always_on_top (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { if (window->wm_state_above == FALSE) meta_window_make_above (window); From aad275b9a2fe52bf887af4a8fb37855d777dd91b Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 19 Nov 2013 14:03:09 -0500 Subject: [PATCH 247/889] window: Fix signedness warning --- src/core/window.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/window.c b/src/core/window.c index 583cbcc2e..e92932aa4 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -10002,7 +10002,7 @@ meta_window_handle_mouse_grab_op_event (MetaWindow *window, { case CLUTTER_BUTTON_RELEASE: if (event->button.button == 1 || - event->button.button == meta_prefs_get_mouse_button_resize ()) + event->button.button == (unsigned int) meta_prefs_get_mouse_button_resize ()) { meta_display_check_threshold_reached (window->display, event->button.x, From a1087c3f3058efb99191211260b67f7e9b1e9819 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Mon, 2 Sep 2013 11:22:11 +0200 Subject: [PATCH 248/889] constraints: account for decorations when positioning modal dialogs What we want to achieve is that the dialog is visually centered on the parent, including the decorations for both, and making sure that CSD/frame_extents are respected. https://bugzilla.gnome.org/show_bug.cgi?id=707194 --- src/core/constraints.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/core/constraints.c b/src/core/constraints.c index 20a918b69..bc23a7220 100644 --- a/src/core/constraints.c +++ b/src/core/constraints.c @@ -765,18 +765,28 @@ constrain_modal_dialog (MetaWindow *window, { int x, y; MetaWindow *parent = meta_window_get_transient_for (window); + MetaRectangle child_rect, parent_rect; gboolean constraint_already_satisfied; if (!meta_window_is_attached_dialog (window)) return TRUE; - x = parent->rect.x + (parent->rect.width / 2 - info->current.width / 2); - y = parent->rect.y + (parent->rect.height / 2 - info->current.height / 2); - if (parent->frame) - { - x += parent->frame->rect.x; - y += parent->frame->rect.y; - } + /* We want to center the dialog on the parent, including the decorations + for both of them. info->current is in client X window coordinates, so we need + to convert them to frame coordinates, apply the centering and then + convert back to client. + */ + + child_rect = info->current; + extend_by_frame (&child_rect, info->borders); + + meta_window_get_outer_rect (parent, &parent_rect); + + child_rect.x = parent_rect.x + (parent_rect.width / 2 - child_rect.width / 2); + child_rect.y = parent_rect.y + (parent_rect.height / 2 - child_rect.height / 2); + unextend_by_frame (&child_rect, info->borders); + x = child_rect.x; + y = child_rect.y; constraint_already_satisfied = (x == info->current.x) && (y == info->current.y); From f36a62733098d8ef416d627c20f50c64bc7f0a4b Mon Sep 17 00:00:00 2001 From: "Owen W. Taylor" Date: Fri, 15 Nov 2013 16:11:20 -0500 Subject: [PATCH 249/889] Use utility functions to convert between frame and client rectangles There are extensive places in the code where we convert between the client rectangle and the frame rectangle. Instead of manually doing it use new helper functions on MetaWindow and the existing meta_window_get_outer_rect(). This fixes a number of bugs where the computation was being done incorrectly, most of these bugs are with the recently added custom frame extents, but some relate to invisible borders or even simply to confusion between the window and frame rectangle. Switch the placement code to place the frame rectangle rather than the client window - this simplifies things considerably. https://bugzilla.gnome.org/show_bug.cgi?id=707194 --- doc/reference/meta-sections.txt | 2 + src/core/constraints.c | 50 ++++---- src/core/display.c | 17 +-- src/core/place.c | 214 ++++++++++++-------------------- src/core/window.c | 142 ++++++++++++++------- src/meta/window.h | 8 ++ 6 files changed, 222 insertions(+), 211 deletions(-) diff --git a/doc/reference/meta-sections.txt b/doc/reference/meta-sections.txt index 08e8f7c16..b87cbfed1 100644 --- a/doc/reference/meta-sections.txt +++ b/doc/reference/meta-sections.txt @@ -542,6 +542,8 @@ meta_window_is_skip_taskbar meta_window_get_rect meta_window_get_input_rect meta_window_get_outer_rect +meta_window_client_rect_to_frame_rect +meta_window_frame_rect_to_client_rect meta_window_get_screen meta_window_get_display meta_window_get_xwindow diff --git a/src/core/constraints.c b/src/core/constraints.c index bc23a7220..a60595fb4 100644 --- a/src/core/constraints.c +++ b/src/core/constraints.c @@ -204,10 +204,10 @@ static void place_window_if_needed (MetaWindow *window, ConstraintInfo *info); static void update_onscreen_requirements (MetaWindow *window, ConstraintInfo *info); -static void extend_by_frame (MetaRectangle *rect, - const MetaFrameBorders *borders); -static void unextend_by_frame (MetaRectangle *rect, - const MetaFrameBorders *borders); +static void extend_by_frame (MetaWindow *window, + MetaRectangle *rect); +static void unextend_by_frame (MetaWindow *window, + MetaRectangle *rect); static inline void get_size_limits (const MetaWindow *window, const MetaFrameBorders *borders, gboolean include_frame, @@ -519,10 +519,11 @@ place_window_if_needed(MetaWindow *window, !window->minimized && !window->fullscreen) { - MetaRectangle placed_rect = info->orig; + MetaRectangle placed_rect; MetaWorkspace *cur_workspace; const MetaMonitorInfo *monitor_info; + meta_window_get_outer_rect (window, &placed_rect); meta_window_place (window, info->borders, info->orig.x, info->orig.y, &placed_rect.x, &placed_rect.y); did_placement = TRUE; @@ -541,6 +542,7 @@ place_window_if_needed(MetaWindow *window, meta_workspace_get_onmonitor_region (cur_workspace, monitor_info->number); + meta_window_frame_rect_to_client_rect (window, &placed_rect, &placed_rect); info->current.x = placed_rect.x; info->current.y = placed_rect.y; @@ -649,7 +651,7 @@ update_onscreen_requirements (MetaWindow *window, /* The require onscreen/on-single-monitor and titlebar_visible * stuff is relative to the outer window, not the inner */ - extend_by_frame (&info->current, info->borders); + extend_by_frame (window, &info->current); /* Update whether we want future constraint runs to require the * window to be on fully onscreen. @@ -698,27 +700,21 @@ update_onscreen_requirements (MetaWindow *window, } /* Don't forget to restore the position of the window */ - unextend_by_frame (&info->current, info->borders); + unextend_by_frame (window, &info->current); } static void -extend_by_frame (MetaRectangle *rect, - const MetaFrameBorders *borders) +extend_by_frame (MetaWindow *window, + MetaRectangle *rect) { - rect->x -= borders->visible.left; - rect->y -= borders->visible.top; - rect->width += borders->visible.left + borders->visible.right; - rect->height += borders->visible.top + borders->visible.bottom; + meta_window_client_rect_to_frame_rect (window, rect, rect); } static void -unextend_by_frame (MetaRectangle *rect, - const MetaFrameBorders *borders) +unextend_by_frame (MetaWindow *window, + MetaRectangle *rect) { - rect->x += borders->visible.left; - rect->y += borders->visible.top; - rect->width -= borders->visible.left + borders->visible.right; - rect->height -= borders->visible.top + borders->visible.bottom; + meta_window_frame_rect_to_client_rect (window, rect, rect); } static inline void @@ -778,13 +774,13 @@ constrain_modal_dialog (MetaWindow *window, */ child_rect = info->current; - extend_by_frame (&child_rect, info->borders); + extend_by_frame (window, &child_rect); meta_window_get_outer_rect (parent, &parent_rect); child_rect.x = parent_rect.x + (parent_rect.width / 2 - child_rect.width / 2); child_rect.y = parent_rect.y + (parent_rect.height / 2 - child_rect.height / 2); - unextend_by_frame (&child_rect, info->borders); + unextend_by_frame (window, &child_rect); x = child_rect.x; y = child_rect.y; @@ -851,14 +847,14 @@ constrain_maximization (MetaWindow *window, active_workspace_struts = window->screen->active_workspace->all_struts; target_size = info->current; - extend_by_frame (&target_size, info->borders); + extend_by_frame (window, &target_size); meta_rectangle_expand_to_avoiding_struts (&target_size, &info->entire_monitor, direction, active_workspace_struts); } /* Now make target_size = maximized size of client window */ - unextend_by_frame (&target_size, info->borders); + unextend_by_frame (window, &target_size); /* Check min size constraints; max size constraints are ignored for maximized * windows, as per bug 327543. @@ -917,7 +913,7 @@ constrain_tiling (MetaWindow *window, * use an external function for the actual calculation */ meta_window_get_current_tile_area (window, &target_size); - unextend_by_frame (&target_size, info->borders); + unextend_by_frame (window, &target_size); /* Check min size constraints; max size constraints are ignored as for * maximized windows. @@ -1267,7 +1263,7 @@ do_screen_and_monitor_relative_constraints ( /* Determine whether constraint applies; exit if it doesn't */ how_far_it_can_be_smushed = info->current; get_size_limits (window, info->borders, TRUE, &min_size, &max_size); - extend_by_frame (&info->current, info->borders); + extend_by_frame (window, &info->current); if (info->action_type != ACTION_MOVE) { @@ -1287,7 +1283,7 @@ do_screen_and_monitor_relative_constraints ( &info->current); if (exit_early || constraint_satisfied || check_only) { - unextend_by_frame (&info->current, info->borders); + unextend_by_frame (window, &info->current); return constraint_satisfied; } @@ -1311,7 +1307,7 @@ do_screen_and_monitor_relative_constraints ( info->fixed_directions, &info->current); - unextend_by_frame (&info->current, info->borders); + unextend_by_frame (window, &info->current); return TRUE; } diff --git a/src/core/display.c b/src/core/display.c index 5649f9a5a..525f9bd04 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -1607,6 +1607,7 @@ window_raise_with_delay_callback (void *data) { int x, y, root_x, root_y; Window root, child; + MetaRectangle frame_rect; unsigned int mask; gboolean same_screen; gboolean point_in_window; @@ -1618,9 +1619,8 @@ window_raise_with_delay_callback (void *data) &root_x, &root_y, &x, &y, &mask); meta_error_trap_pop (window->display); - point_in_window = - (window->frame && POINT_IN_RECT (root_x, root_y, window->frame->rect)) || - (window->frame == NULL && POINT_IN_RECT (root_x, root_y, window->rect)); + meta_window_get_outer_rect (window, &frame_rect); + point_in_window = POINT_IN_RECT (root_x, root_y, frame_rect); if (same_screen && point_in_window) meta_window_raise (window); else @@ -2173,15 +2173,16 @@ meta_display_handle_event (MetaDisplay *display, { gboolean north, south; gboolean west, east; + MetaRectangle frame_rect; int root_x, root_y; MetaGrabOp op; - meta_window_get_position (window, &root_x, &root_y); + meta_window_get_outer_rect (window, &frame_rect); - west = event->button.x < (root_x + 1 * window->rect.width / 3); - east = event->button.x > (root_x + 2 * window->rect.width / 3); - north = event->button.y < (root_y + 1 * window->rect.height / 3); - south = event->button.y > (root_y + 2 * window->rect.height / 3); + west = event->button.x < (frame_rect.x + 1 * frame_rect.width / 3); + east = event->button.x > (frame_rect.x + 2 * frame_rect.width / 3); + north = event->button.y < (frame_rect.y + 1 * frame_rect.height / 3); + south = event->button.y > (frame_rect.y + 2 * frame_rect.height / 3); if (north && west) op = META_GRAB_OP_RESIZING_NW; diff --git a/src/core/place.c b/src/core/place.c index 70171cb05..7835deeef 100644 --- a/src/core/place.c +++ b/src/core/place.c @@ -47,34 +47,18 @@ northwestcmp (gconstpointer a, gconstpointer b) { MetaWindow *aw = (gpointer) a; MetaWindow *bw = (gpointer) b; + MetaRectangle a_frame; + MetaRectangle b_frame; int from_origin_a; int from_origin_b; int ax, ay, bx, by; - /* we're interested in the frame position for cascading, - * not meta_window_get_position() - */ - if (aw->frame) - { - ax = aw->frame->rect.x; - ay = aw->frame->rect.y; - } - else - { - ax = aw->rect.x; - ay = aw->rect.y; - } - - if (bw->frame) - { - bx = bw->frame->rect.x; - by = bw->frame->rect.y; - } - else - { - bx = bw->rect.x; - by = bw->rect.y; - } + meta_window_get_outer_rect (aw, &a_frame); + meta_window_get_outer_rect (bw, &b_frame); + ax = a_frame.x; + ay = a_frame.y; + bx = b_frame.x; + by = b_frame.y; /* probably there's a fast good-enough-guess we could use here. */ from_origin_a = sqrt (ax * ax + ay * ay); @@ -102,6 +86,7 @@ find_next_cascade (MetaWindow *window, GList *sorted; int cascade_x, cascade_y; int x_threshold, y_threshold; + MetaRectangle frame_rect; int window_width, window_height; int cascade_stage; MetaRectangle work_area; @@ -143,30 +128,25 @@ find_next_cascade (MetaWindow *window, cascade_y = MAX (0, work_area.y); /* Find first cascade position that's not used. */ - - window_width = window->frame ? window->frame->rect.width : window->rect.width; - window_height = window->frame ? window->frame->rect.height : window->rect.height; + + meta_window_get_outer_rect (window, &frame_rect); + window_width = frame_rect.width; + window_height = frame_rect.height; cascade_stage = 0; tmp = sorted; while (tmp != NULL) { MetaWindow *w; + MetaRectangle w_frame_rect; int wx, wy; w = tmp->data; /* we want frame position, not window position */ - if (w->frame) - { - wx = w->frame->rect.x; - wy = w->frame->rect.y; - } - else - { - wx = w->rect.x; - wy = w->rect.y; - } + meta_window_get_outer_rect (w, &w_frame_rect); + wx = w_frame_rect.x; + wy = w_frame_rect.y; if (ABS (wx - cascade_x) < x_threshold && ABS (wy - cascade_y) < y_threshold) @@ -223,17 +203,8 @@ find_next_cascade (MetaWindow *window, g_list_free (sorted); - /* Convert coords to position of window, not position of frame. */ - if (borders == NULL) - { - *new_x = cascade_x; - *new_y = cascade_y; - } - else - { - *new_x = cascade_x + borders->visible.left; - *new_y = cascade_y + borders->visible.top; - } + *new_x = cascade_x; + *new_y = cascade_y; } static void @@ -250,14 +221,10 @@ find_most_freespace (MetaWindow *window, int max_area; int max_width, max_height, left, right, top, bottom; int left_space, right_space, top_space, bottom_space; - int frame_size_left, frame_size_top; MetaRectangle work_area; MetaRectangle avoid; MetaRectangle outer; - frame_size_left = borders ? borders->visible.left : 0; - frame_size_top = borders ? borders->visible.top : 0; - meta_window_get_work_area_current_monitor (focus_window, &work_area); meta_window_get_outer_rect (focus_window, &avoid); meta_window_get_outer_rect (window, &outer); @@ -304,36 +271,54 @@ find_most_freespace (MetaWindow *window, switch (side) { case META_LEFT: - *new_y = avoid.y + frame_size_top; + *new_y = avoid.y; if (left_space > outer.width) - *new_x = avoid.x - outer.width + frame_size_left; + *new_x = avoid.x - outer.width; else - *new_x = work_area.x + frame_size_left; + *new_x = work_area.x; break; case META_RIGHT: - *new_y = avoid.y + frame_size_top; + *new_y = avoid.y; if (right_space > outer.width) - *new_x = avoid.x + avoid.width + frame_size_left; + *new_x = avoid.x + avoid.width; else - *new_x = work_area.x + work_area.width - outer.width + frame_size_left; + *new_x = work_area.x + work_area.width - outer.width; break; case META_TOP: - *new_x = avoid.x + frame_size_left; + *new_x = avoid.x; if (top_space > outer.height) - *new_y = avoid.y - outer.height + frame_size_top; + *new_y = avoid.y - outer.height; else - *new_y = work_area.y + frame_size_top; + *new_y = work_area.y; break; case META_BOTTOM: - *new_x = avoid.x + frame_size_left; + *new_x = avoid.x; if (bottom_space > outer.height) - *new_y = avoid.y + avoid.height + frame_size_top; + *new_y = avoid.y + avoid.height; else - *new_y = work_area.y + work_area.height - outer.height + frame_size_top; + *new_y = work_area.y + work_area.height - outer.height; break; } } +static gboolean +window_overlaps_focus_window (MetaWindow *window) +{ + MetaWindow *focus_window; + MetaRectangle window_frame, focus_frame, overlap; + + focus_window = window->display->focus_window; + if (focus_window == NULL) + return FALSE; + + meta_window_get_outer_rect (window, &window_frame); + meta_window_get_outer_rect (focus_window, &focus_frame); + + return meta_rectangle_intersect (&window_frame, + &focus_frame, + &overlap); +} + static void avoid_being_obscured_as_second_modal_dialog (MetaWindow *window, MetaFrameBorders *borders, @@ -355,16 +340,15 @@ avoid_being_obscured_as_second_modal_dialog (MetaWindow *window, */ MetaWindow *focus_window; - MetaRectangle overlap; focus_window = window->display->focus_window; + /* denied_focus_and_not_transient is only set when focus_window != NULL */ + if (window->denied_focus_and_not_transient && window->wm_state_modal && /* FIXME: Maybe do this for all transients? */ meta_window_same_application (window, focus_window) && - meta_rectangle_intersect (&window->rect, - &focus_window->rect, - &overlap)) + window_overlaps_focus_window (window)) { find_most_freespace (window, borders, focus_window, *x, *y, x, y); meta_topic (META_DEBUG_PLACEMENT, @@ -427,20 +411,14 @@ leftmost_cmp (gconstpointer a, gconstpointer b) { MetaWindow *aw = (gpointer) a; MetaWindow *bw = (gpointer) b; + MetaRectangle a_frame; + MetaRectangle b_frame; int ax, bx; - /* we're interested in the frame position for cascading, - * not meta_window_get_position() - */ - if (aw->frame) - ax = aw->frame->rect.x; - else - ax = aw->rect.x; - - if (bw->frame) - bx = bw->frame->rect.x; - else - bx = bw->rect.x; + meta_window_get_outer_rect (aw, &a_frame); + meta_window_get_outer_rect (bw, &b_frame); + ax = a_frame.x; + bx = b_frame.x; if (ax < bx) return -1; @@ -455,20 +433,14 @@ topmost_cmp (gconstpointer a, gconstpointer b) { MetaWindow *aw = (gpointer) a; MetaWindow *bw = (gpointer) b; + MetaRectangle a_frame; + MetaRectangle b_frame; int ay, by; - /* we're interested in the frame position for cascading, - * not meta_window_get_position() - */ - if (aw->frame) - ay = aw->frame->rect.y; - else - ay = aw->rect.y; - - if (bw->frame) - by = bw->frame->rect.y; - else - by = bw->rect.y; + meta_window_get_outer_rect (aw, &a_frame); + meta_window_get_outer_rect (bw, &b_frame); + ay = a_frame.y; + by = b_frame.y; if (ay < by) return -1; @@ -540,15 +512,8 @@ find_first_fit (MetaWindow *window, right_sorted = g_list_copy (windows); right_sorted = g_list_sort (right_sorted, topmost_cmp); right_sorted = g_list_sort (right_sorted, leftmost_cmp); - - rect.width = window->rect.width; - rect.height = window->rect.height; - - if (borders) - { - rect.width += borders->visible.left + borders->visible.right; - rect.height += borders->visible.top + borders->visible.bottom; - } + + meta_window_get_outer_rect (window, &rect); #ifdef WITH_VERBOSE_MODE { @@ -570,11 +535,6 @@ find_first_fit (MetaWindow *window, { *new_x = rect.x; *new_y = rect.y; - if (borders) - { - *new_x += borders->visible.left; - *new_y += borders->visible.top; - } retval = TRUE; @@ -598,11 +558,6 @@ find_first_fit (MetaWindow *window, { *new_x = rect.x; *new_y = rect.y; - if (borders) - { - *new_x += borders->visible.left; - *new_y += borders->visible.top; - } retval = TRUE; @@ -629,11 +584,6 @@ find_first_fit (MetaWindow *window, { *new_x = rect.x; *new_y = rect.y; - if (borders) - { - *new_x += borders->visible.left; - *new_y += borders->visible.top; - } retval = TRUE; @@ -775,24 +725,22 @@ meta_window_place (MetaWindow *window, if (parent) { - int w; + MetaRectangle frame_rect, parent_frame_rect; - meta_window_get_position (parent, &x, &y); - w = parent->rect.width; + meta_window_get_outer_rect (window, &frame_rect); + meta_window_get_outer_rect (parent, &parent_frame_rect); + + y = parent_frame_rect.y; /* center of parent */ - x = x + w / 2; + x = parent_frame_rect.x + parent_frame_rect.width / 2; /* center of child over center of parent */ - x -= window->rect.width / 2; + x -= frame_rect.width / 2; /* "visually" center window over parent, leaving twice as * much space below as on top. */ - y += (parent->rect.height - window->rect.height)/3; - - /* put top of child's frame, not top of child's client */ - if (borders) - y += borders->visible.top; + y += (parent_frame_rect.height - frame_rect.height)/3; meta_topic (META_DEBUG_PLACEMENT, "Centered window %s over transient parent\n", window->desc); @@ -813,6 +761,9 @@ meta_window_place (MetaWindow *window, { /* Center on current monitor */ int w, h; + MetaRectangle frame_rect; + + meta_window_get_outer_rect (window, &frame_rect); /* Warning, this function is a round trip! */ xi = meta_screen_get_current_monitor_info (window->screen); @@ -820,8 +771,8 @@ meta_window_place (MetaWindow *window, w = xi->rect.width; h = xi->rect.height; - x = (w - window->rect.width) / 2; - y = (h - window->rect.height) / 2; + x = (w - frame_rect.width) / 2; + y = (h - frame_rect.height) / 2; x += xi->rect.x; y += xi->rect.y; @@ -909,17 +860,14 @@ meta_window_place (MetaWindow *window, */ if (window->denied_focus_and_not_transient) { - gboolean found_fit; MetaWindow *focus_window; - MetaRectangle overlap; + gboolean found_fit; focus_window = window->display->focus_window; g_assert (focus_window != NULL); /* No need to do anything if the window doesn't overlap at all */ - found_fit = !meta_rectangle_intersect (&window->rect, - &focus_window->rect, - &overlap); + found_fit = !window_overlaps_focus_window (window); /* Try to do a first fit again, this time only taking into account the * focus window. diff --git a/src/core/window.c b/src/core/window.c index e92932aa4..c993d2df2 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -3959,7 +3959,7 @@ meta_window_can_tile_side_by_side (MetaWindow *window) { int monitor; MetaRectangle tile_area; - MetaFrameBorders borders; + MetaRectangle client_rect; if (!meta_window_can_tile_maximized (window)) return FALSE; @@ -3973,13 +3973,10 @@ meta_window_can_tile_side_by_side (MetaWindow *window) tile_area.width /= 2; - meta_frame_calc_borders (window->frame, &borders); + meta_window_frame_rect_to_client_rect (window, &tile_area, &client_rect); - tile_area.width -= (borders.visible.left + borders.visible.right); - tile_area.height -= (borders.visible.top + borders.visible.bottom); - - return tile_area.width >= window->size_hints.min_width && - tile_area.height >= window->size_hints.min_height; + return client_rect.width >= window->size_hints.min_width && + client_rect.height >= window->size_hints.min_height; } static void @@ -5670,23 +5667,10 @@ meta_window_move_frame (MetaWindow *window, int root_x_nw, int root_y_nw) { - int x = root_x_nw; - int y = root_y_nw; + MetaRectangle rect = { root_x_nw, root_y_nw, 0, 0 }; - if (window->frame) - { - MetaFrameBorders borders; - meta_frame_calc_borders (window->frame, &borders); - - /* root_x_nw and root_y_nw correspond to where the top of - * the visible frame should be. Offset by the distance between - * the origin of the window and the origin of the enclosing - * window decorations. - */ - x += window->frame->child_x - borders.invisible.left; - y += window->frame->child_y - borders.invisible.top; - } - meta_window_move (window, user_op, x, y); + meta_window_frame_rect_to_client_rect (window, &rect, &rect); + meta_window_move (window, user_op, rect.x, rect.y); } static void @@ -5734,18 +5718,10 @@ meta_window_move_resize_frame (MetaWindow *window, int w, int h) { - MetaFrameBorders borders; + MetaRectangle rect = { root_x_nw, root_y_nw, w, h }; + meta_window_frame_rect_to_client_rect (window, &rect, &rect); - meta_frame_calc_borders (window->frame, &borders); - /* offset by the distance between the origin of the window - * and the origin of the enclosing window decorations ( + border) - */ - root_x_nw += borders.visible.left; - root_y_nw += borders.visible.top; - w -= borders.visible.left + borders.visible.right; - h -= borders.visible.top + borders.visible.bottom; - - meta_window_move_resize (window, user_op, root_x_nw, root_y_nw, w, h); + meta_window_move_resize (window, user_op, rect.x, rect.y, rect.width, rect.height); } /** @@ -6057,6 +6033,91 @@ meta_window_get_input_rect (const MetaWindow *window, *rect = window->rect; } +/** + * meta_window_client_rect_to_frame_rect: + * @window: a #MetaWindow + * @frame_rect: client rectangle in root coordinates + * @client_rect: (out): location to store the computed corresponding frame bounds. + * + * Converts a desired bounds of the client window - what is passed to meta_window_move_resize() - + * into the corresponding bounds of the window frame (excluding invisible borders + * and client side shadows.) + */ +void +meta_window_client_rect_to_frame_rect (MetaWindow *window, + MetaRectangle *frame_rect, + MetaRectangle *client_rect) +{ + if (!client_rect) + return; + + *client_rect = *frame_rect; + + if (window->frame) + { + MetaFrameBorders borders; + meta_frame_calc_borders (window->frame, &borders); + + client_rect->x -= borders.visible.left; + client_rect->y -= borders.visible.top; + client_rect->width += borders.visible.left + borders.visible.right; + client_rect->height += borders.visible.top + borders.visible.bottom; + } + else + { + if (window->has_custom_frame_extents) + { + const GtkBorder *extents = &window->custom_frame_extents; + client_rect->x += extents->left; + client_rect->y += extents->top; + client_rect->width -= extents->left + extents->right; + client_rect->height -= extents->top + extents->bottom; + } + } +} + +/** + * meta_window_frame_rect_to_client_rect: + * @window: a #MetaWindow + * @frame_rect: desired frame bounds for the window + * @client_rect: (out): location to store the computed corresponding client rectangle. + * + * Converts a desired frame bounds for a window into the bounds of the client + * window - what is passed to meta_window_move_resize(). + */ +void +meta_window_frame_rect_to_client_rect (MetaWindow *window, + MetaRectangle *frame_rect, + MetaRectangle *client_rect) +{ + if (!client_rect) + return; + + *client_rect = *frame_rect; + + if (window->frame) + { + MetaFrameBorders borders; + meta_frame_calc_borders (window->frame, &borders); + + client_rect->x += borders.visible.left; + client_rect->y += borders.visible.top; + client_rect->width -= borders.visible.left + borders.visible.right; + client_rect->height -= borders.visible.top + borders.visible.bottom; + } + else + { + if (window->has_custom_frame_extents) + { + const GtkBorder *extents = &window->custom_frame_extents; + client_rect->x -= extents->left; + client_rect->y -= extents->top; + client_rect->width += extents->left + extents->right; + client_rect->height += extents->top + extents->bottom; + } + } +} + /** * meta_window_get_outer_rect: * @window: a #MetaWindow @@ -8784,18 +8845,13 @@ recalc_window_features (MetaWindow *window) if (window->has_maximize_func) { - MetaRectangle work_area; - MetaFrameBorders borders; - int min_frame_width, min_frame_height; + MetaRectangle work_area, client_rect; meta_window_get_work_area_current_monitor (window, &work_area); - meta_frame_calc_borders (window->frame, &borders); + meta_window_frame_rect_to_client_rect (window, &work_area, &client_rect); - min_frame_width = window->size_hints.min_width + borders.visible.left + borders.visible.right; - min_frame_height = window->size_hints.min_height + borders.visible.top + borders.visible.bottom; - - if (min_frame_width >= work_area.width || - min_frame_height >= work_area.height) + if (window->size_hints.min_width >= client_rect.width || + window->size_hints.min_height >= client_rect.height) window->has_maximize_func = FALSE; } diff --git a/src/meta/window.h b/src/meta/window.h index bc03cf055..da4448923 100644 --- a/src/meta/window.h +++ b/src/meta/window.h @@ -111,6 +111,14 @@ gboolean meta_window_is_skip_taskbar (MetaWindow *window); MetaRectangle *meta_window_get_rect (MetaWindow *window); void meta_window_get_input_rect (const MetaWindow *window, MetaRectangle *rect); void meta_window_get_outer_rect (const MetaWindow *window, MetaRectangle *rect); + +void meta_window_client_rect_to_frame_rect (MetaWindow *window, + MetaRectangle *frame_rect, + MetaRectangle *client_rect); +void meta_window_frame_rect_to_client_rect (MetaWindow *window, + MetaRectangle *frame_rect, + MetaRectangle *client_rect); + MetaScreen *meta_window_get_screen (MetaWindow *window); MetaDisplay *meta_window_get_display (MetaWindow *window); Window meta_window_get_xwindow (MetaWindow *window); From a4a8f1f863640262b7f3491be0205b272b455f5a Mon Sep 17 00:00:00 2001 From: "Owen W. Taylor" Date: Fri, 15 Nov 2013 17:37:50 -0500 Subject: [PATCH 250/889] MetaFrame: Cache borders Cache the computed border size so we can fetch the border size at any time without worrying that we'll be spending too much time in the theme code (in some cases we might allocate a PangoFontDescription or do other significant work.) The main effort here is clearing the cache when various bits of window state change that could potentially affect the computed borders. https://bugzilla.gnome.org/show_bug.cgi?id=707194 --- src/core/core.c | 1 + src/core/display.c | 1 + src/core/frame.c | 21 ++++++++++++++++++--- src/core/frame.h | 5 +++++ src/core/window-private.h | 3 +++ src/core/window.c | 15 +++++++++++++++ 6 files changed, 43 insertions(+), 3 deletions(-) diff --git a/src/core/core.c b/src/core/core.c index 3a96cde43..b1ba70dc1 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -172,6 +172,7 @@ meta_core_queue_frame_resize (Display *xdisplay, MetaWindow *window = get_window (xdisplay, frame_xwindow); meta_window_queue (window, META_QUEUE_MOVE_RESIZE); + meta_window_frame_size_changed (window); } void diff --git a/src/core/display.c b/src/core/display.c index 525f9bd04..2915c3aa2 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -4564,6 +4564,7 @@ meta_display_queue_retheme_all_windows (MetaDisplay *display) MetaWindow *window = tmp->data; meta_window_queue (window, META_QUEUE_MOVE_RESIZE); + meta_window_frame_size_changed (window); if (window->frame) { meta_frame_queue_draw (window->frame); diff --git a/src/core/frame.c b/src/core/frame.c index d7e254ecf..a2a4fbf63 100644 --- a/src/core/frame.c +++ b/src/core/frame.c @@ -69,6 +69,7 @@ meta_window_ensure_frame (MetaWindow *window) frame->mapped = FALSE; frame->is_flashing = FALSE; + frame->borders_cached = FALSE; meta_verbose ("Framing window %s: visual %s default, depth %d default depth %d\n", window->desc, @@ -334,9 +335,23 @@ meta_frame_calc_borders (MetaFrame *frame, if (frame == NULL) meta_frame_borders_clear (borders); else - meta_ui_get_frame_borders (frame->window->screen->ui, - frame->xwindow, - borders); + { + if (!frame->borders_cached) + { + meta_ui_get_frame_borders (frame->window->screen->ui, + frame->xwindow, + &frame->cached_borders); + frame->borders_cached = TRUE; + } + + *borders = frame->cached_borders; + } +} + +void +meta_frame_clear_cached_borders (MetaFrame *frame) +{ + frame->borders_cached = FALSE; } gboolean diff --git a/src/core/frame.h b/src/core/frame.h index cff9cb25c..d633adc25 100644 --- a/src/core/frame.h +++ b/src/core/frame.h @@ -41,6 +41,8 @@ struct _MetaFrame */ MetaRectangle rect; + MetaFrameBorders cached_borders; /* valid if borders_cached is set */ + /* position of client, size of frame */ int child_x; int child_y; @@ -50,6 +52,7 @@ struct _MetaFrame guint mapped : 1; guint need_reapply_frame_shape : 1; guint is_flashing : 1; /* used by the visual bell flash */ + guint borders_cached : 1; }; void meta_window_ensure_frame (MetaWindow *window); @@ -68,6 +71,8 @@ gboolean meta_frame_sync_to_window (MetaFrame *frame, gboolean need_move, gboolean need_resize); +void meta_frame_clear_cached_borders (MetaFrame *frame); + cairo_region_t *meta_frame_get_frame_bounds (MetaFrame *frame); void meta_frame_get_mask (MetaFrame *frame, diff --git a/src/core/window-private.h b/src/core/window-private.h index 1a428030c..cc2faa424 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -533,6 +533,7 @@ void meta_window_update_fullscreen_monitors (MetaWindow *window, unsigned long left, unsigned long right); + /* args to move are window pos, not frame pos */ void meta_window_move (MetaWindow *window, gboolean user_op, @@ -683,6 +684,8 @@ void meta_window_recalc_features (MetaWindow *window); void meta_window_recalc_window_type (MetaWindow *window); void meta_window_type_changed (MetaWindow *window); +void meta_window_frame_size_changed (MetaWindow *window); + void meta_window_stack_just_below (MetaWindow *window, MetaWindow *below_this_one); diff --git a/src/core/window.c b/src/core/window.c index c993d2df2..f7b62841e 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -4213,6 +4213,7 @@ meta_window_set_above (MetaWindow *window, window->wm_state_above = new_value; meta_window_update_layer (window); set_net_wm_state (window); + meta_window_frame_size_changed (window); g_object_notify (G_OBJECT (window), "above"); } @@ -4352,6 +4353,7 @@ meta_window_shade (MetaWindow *window, window->shaded = TRUE; meta_window_queue(window, META_QUEUE_MOVE_RESIZE | META_QUEUE_CALC_SHOWING); + meta_window_frame_size_changed (window); /* After queuing the calc showing, since _focus flushes it, * and we need to focus the frame @@ -4377,6 +4379,7 @@ meta_window_unshade (MetaWindow *window, { window->shaded = FALSE; meta_window_queue(window, META_QUEUE_MOVE_RESIZE | META_QUEUE_CALC_SHOWING); + meta_window_frame_size_changed (window); /* focus the window */ meta_topic (META_DEBUG_FOCUS, @@ -6378,6 +6381,7 @@ window_stick_impl (MetaWindow *window) * toggled back off. */ window->on_all_workspaces_requested = TRUE; + meta_window_frame_size_changed (window); meta_window_update_on_all_workspaces (window); meta_window_queue(window, META_QUEUE_CALC_SHOWING); @@ -6392,6 +6396,7 @@ window_unstick_impl (MetaWindow *window) /* Revert to window->workspaces */ window->on_all_workspaces_requested = FALSE; + meta_window_frame_size_changed (window); meta_window_update_on_all_workspaces (window); /* We change ourselves to the active workspace, since otherwise you'd get @@ -7467,6 +7472,7 @@ static void meta_window_appears_focused_changed (MetaWindow *window) { set_net_wm_state (window); + meta_window_frame_size_changed (window); g_object_notify (G_OBJECT (window), "appears-focused"); @@ -8643,6 +8649,13 @@ meta_window_type_changed (MetaWindow *window) g_object_thaw_notify (object); } +void +meta_window_frame_size_changed (MetaWindow *window) +{ + if (window->frame) + meta_frame_clear_cached_borders (window->frame); +} + static void set_allowed_actions_hint (MetaWindow *window) { @@ -8943,6 +8956,8 @@ recalc_window_features (MetaWindow *window) if (window->has_resize_func != old_has_resize_func) g_object_notify (G_OBJECT (window), "resizeable"); + meta_window_frame_size_changed (window); + /* FIXME perhaps should ensure if we don't have a shade func, * we aren't shaded, etc. */ From 097ee776c7073c7e5dc9e23666f24f894716177f Mon Sep 17 00:00:00 2001 From: "Owen W. Taylor" Date: Fri, 15 Nov 2013 18:03:50 -0500 Subject: [PATCH 251/889] Stop passing around MetaFrameBorders Instead of passing around MetaFrameBorders, compute it when we need it. This also allows us to know that we are using MetaFrameBorders only for windows with frames (where it is meaningful) and not for frameless windows, which can have custom borders which we need to interpret differently. https://bugzilla.gnome.org/show_bug.cgi?id=707194 --- src/core/constraints.c | 89 +++++++++++++----------------------------- src/core/constraints.h | 1 - src/core/place.c | 35 ++++++----------- src/core/place.h | 1 - src/core/window.c | 17 +++++--- 5 files changed, 52 insertions(+), 91 deletions(-) diff --git a/src/core/constraints.c b/src/core/constraints.c index a60595fb4..97e1e79de 100644 --- a/src/core/constraints.c +++ b/src/core/constraints.c @@ -118,8 +118,6 @@ typedef struct { MetaRectangle orig; MetaRectangle current; - MetaFrameBorders *borders; - gboolean must_free_borders; ActionType action_type; gboolean is_user_action; @@ -195,7 +193,6 @@ static gboolean constrain_partially_onscreen (MetaWindow *window, static void setup_constraint_info (ConstraintInfo *info, MetaWindow *window, - MetaFrameBorders *orig_borders, MetaMoveResizeFlags flags, int resize_gravity, const MetaRectangle *orig, @@ -208,9 +205,8 @@ static void extend_by_frame (MetaWindow *window, MetaRectangle *rect); static void unextend_by_frame (MetaWindow *window, MetaRectangle *rect); -static inline void get_size_limits (const MetaWindow *window, - const MetaFrameBorders *borders, - gboolean include_frame, +static inline void get_size_limits (MetaWindow *window, + gboolean include_frame, MetaRectangle *min_size, MetaRectangle *max_size); @@ -280,7 +276,6 @@ do_all_constraints (MetaWindow *window, void meta_window_constrain (MetaWindow *window, - MetaFrameBorders *orig_borders, MetaMoveResizeFlags flags, int resize_gravity, const MetaRectangle *orig, @@ -303,7 +298,6 @@ meta_window_constrain (MetaWindow *window, setup_constraint_info (&info, window, - orig_borders, flags, resize_gravity, orig, @@ -333,19 +327,11 @@ meta_window_constrain (MetaWindow *window, * if this was a user move or user move-and-resize operation. */ update_onscreen_requirements (window, &info); - - /* Ew, what an ugly way to do things. Destructors (in a real OOP language, - * not gobject-style--gobject would be more pain than it's worth) or - * smart pointers would be so much nicer here. *shrug* - */ - if (info.must_free_borders) - g_free (info.borders); } static void setup_constraint_info (ConstraintInfo *info, MetaWindow *window, - MetaFrameBorders *orig_borders, MetaMoveResizeFlags flags, int resize_gravity, const MetaRectangle *orig, @@ -357,18 +343,6 @@ setup_constraint_info (ConstraintInfo *info, info->orig = *orig; info->current = *new; - /* Create a fake frame geometry if none really exists */ - if (orig_borders && !window->fullscreen) - { - info->borders = orig_borders; - info->must_free_borders = FALSE; - } - else - { - info->borders = g_new0 (MetaFrameBorders, 1); - info->must_free_borders = TRUE; - } - if (flags & META_IS_MOVE_ACTION && flags & META_IS_RESIZE_ACTION) info->action_type = ACTION_MOVE_AND_RESIZE; else if (flags & META_IS_RESIZE_ACTION) @@ -524,7 +498,7 @@ place_window_if_needed(MetaWindow *window, const MetaMonitorInfo *monitor_info; meta_window_get_outer_rect (window, &placed_rect); - meta_window_place (window, info->borders, info->orig.x, info->orig.y, + meta_window_place (window, info->orig.x, info->orig.y, &placed_rect.x, &placed_rect.y); did_placement = TRUE; @@ -588,10 +562,6 @@ place_window_if_needed(MetaWindow *window, (window->maximize_vertically_after_placement ? META_MAXIMIZE_VERTICAL : 0), &info->current); - /* maximization may have changed frame geometry */ - if (!window->fullscreen) - meta_frame_calc_borders (window->frame, info->borders); - if (window->fullscreen_after_placement) { window->saved_rect = info->current; @@ -684,10 +654,13 @@ update_onscreen_requirements (MetaWindow *window, */ if (window->frame && window->decorated) { + MetaFrameBorders borders; MetaRectangle titlebar_rect; + meta_frame_calc_borders (window->frame, &borders); + titlebar_rect = info->current; - titlebar_rect.height = info->borders->visible.top; + titlebar_rect.height = borders.visible.top; old = window->require_titlebar_visible; window->require_titlebar_visible = meta_rectangle_overlaps_with_region (info->usable_screen_region, @@ -718,15 +691,15 @@ unextend_by_frame (MetaWindow *window, } static inline void -get_size_limits (const MetaWindow *window, - const MetaFrameBorders *borders, - gboolean include_frame, +get_size_limits (MetaWindow *window, + gboolean include_frame, MetaRectangle *min_size, MetaRectangle *max_size) { /* We pack the results into MetaRectangle structs just for convienience; we * don't actually use the position of those rects. */ + min_size->x = min_size->y = max_size->x = max_size->y = 0; min_size->width = window->size_hints.min_width; min_size->height = window->size_hints.min_height; max_size->width = window->size_hints.max_width; @@ -734,22 +707,8 @@ get_size_limits (const MetaWindow *window, if (include_frame) { - int fw = borders->visible.left + borders->visible.right; - int fh = borders->visible.top + borders->visible.bottom; - - min_size->width += fw; - min_size->height += fh; - /* Do check to avoid overflow (e.g. max_size->width & max_size->height - * may be set to G_MAXINT by meta_set_normal_hints()). - */ - if (max_size->width < (G_MAXINT - fw)) - max_size->width += fw; - else - max_size->width = G_MAXINT; - if (max_size->height < (G_MAXINT - fh)) - max_size->height += fh; - else - max_size->height = G_MAXINT; + meta_window_client_rect_to_outer_rect (window, min_size, min_size); + meta_window_client_rect_to_outer_rect (window, max_size, max_size); } } @@ -859,7 +818,7 @@ constrain_maximization (MetaWindow *window, /* Check min size constraints; max size constraints are ignored for maximized * windows, as per bug 327543. */ - get_size_limits (window, info->borders, FALSE, &min_size, &max_size); + get_size_limits (window, FALSE, &min_size, &max_size); hminbad = target_size.width < min_size.width && window->maximized_horizontally; vminbad = target_size.height < min_size.height && window->maximized_vertically; if (hminbad || vminbad) @@ -918,7 +877,7 @@ constrain_tiling (MetaWindow *window, /* Check min size constraints; max size constraints are ignored as for * maximized windows. */ - get_size_limits (window, info->borders, FALSE, &min_size, &max_size); + get_size_limits (window, FALSE, &min_size, &max_size); hminbad = target_size.width < min_size.width; vminbad = target_size.height < min_size.height; if (hminbad || vminbad) @@ -961,7 +920,7 @@ constrain_fullscreen (MetaWindow *window, monitor = info->entire_monitor; - get_size_limits (window, info->borders, FALSE, &min_size, &max_size); + get_size_limits (window, FALSE, &min_size, &max_size); too_big = !meta_rectangle_could_fit_rect (&monitor, &min_size); too_small = !meta_rectangle_could_fit_rect (&max_size, &monitor); if (too_big || too_small) @@ -1070,7 +1029,7 @@ constrain_size_limits (MetaWindow *window, return TRUE; /* Determine whether constraint is already satisfied; exit if it is */ - get_size_limits (window, info->borders, FALSE, &min_size, &max_size); + get_size_limits (window, FALSE, &min_size, &max_size); /* We ignore max-size limits for maximized windows; see #327543 */ if (window->maximized_horizontally) max_size.width = MAX (max_size.width, info->current.width); @@ -1262,7 +1221,7 @@ do_screen_and_monitor_relative_constraints ( /* Determine whether constraint applies; exit if it doesn't */ how_far_it_can_be_smushed = info->current; - get_size_limits (window, info->borders, TRUE, &min_size, &max_size); + get_size_limits (window, TRUE, &min_size, &max_size); extend_by_frame (window, &info->current); if (info->action_type != ACTION_MOVE) @@ -1420,8 +1379,11 @@ constrain_titlebar_visible (MetaWindow *window, */ if (window->frame) { - bottom_amount = info->current.height + info->borders->visible.bottom; - vert_amount_onscreen = info->borders->visible.top; + MetaFrameBorders borders; + meta_frame_calc_borders (window->frame, &borders); + + bottom_amount = info->current.height + borders.visible.bottom; + vert_amount_onscreen = borders.visible.top; } else bottom_amount = vert_amount_offscreen; @@ -1495,8 +1457,11 @@ constrain_partially_onscreen (MetaWindow *window, */ if (window->frame) { - bottom_amount = info->current.height + info->borders->visible.bottom; - vert_amount_onscreen = info->borders->visible.top; + MetaFrameBorders borders; + meta_frame_calc_borders (window->frame, &borders); + + bottom_amount = info->current.height + borders.visible.bottom; + vert_amount_onscreen = borders.visible.top; } else bottom_amount = vert_amount_offscreen; diff --git a/src/core/constraints.h b/src/core/constraints.h index 0bea43d11..07c65290c 100644 --- a/src/core/constraints.h +++ b/src/core/constraints.h @@ -40,7 +40,6 @@ typedef enum } MetaMoveResizeFlags; void meta_window_constrain (MetaWindow *window, - MetaFrameBorders *orig_borders, MetaMoveResizeFlags flags, int resize_gravity, const MetaRectangle *orig, diff --git a/src/core/place.c b/src/core/place.c index 7835deeef..a2c7df3c7 100644 --- a/src/core/place.c +++ b/src/core/place.c @@ -74,7 +74,6 @@ northwestcmp (gconstpointer a, gconstpointer b) static void find_next_cascade (MetaWindow *window, - MetaFrameBorders *borders, /* visible windows on relevant workspaces */ GList *windows, int x, @@ -105,10 +104,13 @@ find_next_cascade (MetaWindow *window, * manually cascade. */ #define CASCADE_FUZZ 15 - if (borders) + if (window->frame) { - x_threshold = MAX (borders->visible.left, CASCADE_FUZZ); - y_threshold = MAX (borders->visible.top, CASCADE_FUZZ); + MetaFrameBorders borders; + + meta_frame_calc_borders (window->frame, &borders); + x_threshold = MAX (borders.visible.left, CASCADE_FUZZ); + y_threshold = MAX (borders.visible.top, CASCADE_FUZZ); } else { @@ -209,7 +211,6 @@ find_next_cascade (MetaWindow *window, static void find_most_freespace (MetaWindow *window, - MetaFrameBorders *borders, /* visible windows on relevant workspaces */ MetaWindow *focus_window, int x, @@ -321,7 +322,6 @@ window_overlaps_focus_window (MetaWindow *window) static void avoid_being_obscured_as_second_modal_dialog (MetaWindow *window, - MetaFrameBorders *borders, int *x, int *y) { @@ -350,7 +350,7 @@ avoid_being_obscured_as_second_modal_dialog (MetaWindow *window, meta_window_same_application (window, focus_window) && window_overlaps_focus_window (window)) { - find_most_freespace (window, borders, focus_window, *x, *y, x, y); + find_most_freespace (window, focus_window, *x, *y, x, y); meta_topic (META_DEBUG_PLACEMENT, "Dialog window %s was denied focus but may be modal " "to the focus window; had to move it to avoid the " @@ -478,7 +478,6 @@ center_tile_rect_in_area (MetaRectangle *rect, */ static gboolean find_first_fit (MetaWindow *window, - MetaFrameBorders *borders, /* visible windows on relevant workspaces */ GList *windows, int monitor, @@ -602,7 +601,6 @@ find_first_fit (MetaWindow *window, void meta_window_place (MetaWindow *window, - MetaFrameBorders *borders, int x, int y, int *new_x, @@ -611,13 +609,6 @@ meta_window_place (MetaWindow *window, GList *windows; const MetaMonitorInfo *xi; - /* frame member variables should NEVER be used in here, only - * MetaFrameBorders. But remember borders == NULL - * for undecorated windows. Also, this function should - * NEVER have side effects other than computing the - * placement coordinates. - */ - meta_topic (META_DEBUG_PLACEMENT, "Placing window %s\n", window->desc); windows = NULL; @@ -706,7 +697,7 @@ meta_window_place (MetaWindow *window, { meta_topic (META_DEBUG_PLACEMENT, "Not placing window with PPosition or USPosition set\n"); - avoid_being_obscured_as_second_modal_dialog (window, borders, &x, &y); + avoid_being_obscured_as_second_modal_dialog (window, &x, &y); goto done_no_constraints; } } @@ -745,7 +736,7 @@ meta_window_place (MetaWindow *window, meta_topic (META_DEBUG_PLACEMENT, "Centered window %s over transient parent\n", window->desc); - avoid_being_obscured_as_second_modal_dialog (window, borders, &x, &y); + avoid_being_obscured_as_second_modal_dialog (window, &x, &y); goto done; } @@ -816,7 +807,7 @@ meta_window_place (MetaWindow *window, x = xi->rect.x; y = xi->rect.y; - if (find_first_fit (window, borders, windows, + if (find_first_fit (window, windows, xi->number, x, y, &x, &y)) goto done_check_denied_focus; @@ -850,7 +841,7 @@ meta_window_place (MetaWindow *window, * fully overlapping window (e.g. starting multiple terminals) * */ if (x == xi->rect.x && y == xi->rect.y) - find_next_cascade (window, borders, windows, x, y, &x, &y); + find_next_cascade (window, windows, x, y, &x, &y); done_check_denied_focus: /* If the window is being denied focus and isn't a transient of the @@ -881,7 +872,7 @@ meta_window_place (MetaWindow *window, x = xi->rect.x; y = xi->rect.y; - found_fit = find_first_fit (window, borders, focus_window_list, + found_fit = find_first_fit (window, focus_window_list, xi->number, x, y, &x, &y); g_list_free (focus_window_list); @@ -891,7 +882,7 @@ meta_window_place (MetaWindow *window, * as possible. */ if (!found_fit) - find_most_freespace (window, borders, focus_window, x, y, &x, &y); + find_most_freespace (window, focus_window, x, y, &x, &y); } done: diff --git a/src/core/place.h b/src/core/place.h index 7a8c12699..d9647e25b 100644 --- a/src/core/place.h +++ b/src/core/place.h @@ -28,7 +28,6 @@ #include "frame.h" void meta_window_place (MetaWindow *window, - MetaFrameBorders *borders, int x, int y, int *new_x, diff --git a/src/core/window.c b/src/core/window.c index f7b62841e..e98aa843e 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -5118,7 +5118,6 @@ meta_window_move_resize_internal (MetaWindow *window, if (flags & (META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION)) { meta_window_constrain (window, - window->frame ? &borders : NULL, flags, gravity, &old_rect, @@ -6056,6 +6055,10 @@ meta_window_client_rect_to_frame_rect (MetaWindow *window, *client_rect = *frame_rect; + /* The support for G_MAXINT here to mean infinity is a convenience for + * constraints.c:get_size_limits() and not something that we provide + * in other locations or document. + */ if (window->frame) { MetaFrameBorders borders; @@ -6063,8 +6066,10 @@ meta_window_client_rect_to_frame_rect (MetaWindow *window, client_rect->x -= borders.visible.left; client_rect->y -= borders.visible.top; - client_rect->width += borders.visible.left + borders.visible.right; - client_rect->height += borders.visible.top + borders.visible.bottom; + if (client_rect->width != G_MAXINT) + client_rect->width += borders.visible.left + borders.visible.right; + if (client_rect->height != G_MAXINT) + client_rect->height += borders.visible.top + borders.visible.bottom; } else { @@ -6073,8 +6078,10 @@ meta_window_client_rect_to_frame_rect (MetaWindow *window, const GtkBorder *extents = &window->custom_frame_extents; client_rect->x += extents->left; client_rect->y += extents->top; - client_rect->width -= extents->left + extents->right; - client_rect->height -= extents->top + extents->bottom; + if (client_rect->width != G_MAXINT) + client_rect->width -= extents->left + extents->right; + if (client_rect->height != G_MAXINT) + client_rect->height -= extents->top + extents->bottom; } } } From b9da43b753d13d7f82b762f42109c34354eef334 Mon Sep 17 00:00:00 2001 From: "Owen W. Taylor" Date: Tue, 19 Nov 2013 12:24:45 -0500 Subject: [PATCH 252/889] Rename meta_window_get_outer_rect() to meta_window_get_frame_rect() For clarity, rename meta_window_get_outer_rect() to match terminology we use elsewhere. The old function is left as a deprecated compatibility wrapper. --- doc/reference/meta-sections.txt | 1 + src/compositor/compositor.c | 2 +- src/compositor/meta-window-actor.c | 4 +- src/compositor/meta-window-group.c | 2 +- src/core/constraints.c | 8 +-- src/core/display.c | 4 +- src/core/edge-resistance.c | 8 +-- src/core/keybindings.c | 20 +++---- src/core/place.c | 86 +++++++++++++++--------------- src/core/screen.c | 4 +- src/core/stack.c | 2 +- src/core/window.c | 80 ++++++++++++++++----------- src/meta/window.h | 4 +- 13 files changed, 124 insertions(+), 101 deletions(-) diff --git a/doc/reference/meta-sections.txt b/doc/reference/meta-sections.txt index b87cbfed1..90f815249 100644 --- a/doc/reference/meta-sections.txt +++ b/doc/reference/meta-sections.txt @@ -541,6 +541,7 @@ meta_window_is_override_redirect meta_window_is_skip_taskbar meta_window_get_rect meta_window_get_input_rect +meta_window_get_frame_rect meta_window_get_outer_rect meta_window_client_rect_to_frame_rect meta_window_frame_rect_to_client_rect diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index f7312a4ba..d4e7ebd7f 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -864,7 +864,7 @@ meta_shape_cow_for_window (MetaScreen *screen, int width, height; MetaRectangle rect; - meta_window_get_outer_rect (metaWindow, &rect); + meta_window_get_frame_rect (metaWindow, &rect); window_bounds.x = rect.x; window_bounds.y = rect.y; diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index a03f84f52..d68bb0ab9 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -2031,7 +2031,7 @@ check_needs_x11_pixmap (MetaWindowActor *self) meta_surface_actor_set_texture (META_SURFACE_ACTOR (priv->surface), texture); - /* ::size-changed is supposed to refer to meta_window_get_outer_rect(). + /* ::size-changed is supposed to refer to meta_window_get_frame_rect(). * Emitting it here works pretty much OK because a new value of the * *input* rect (which is the outer rect with the addition of invisible * borders) forces a new pixmap and we get here. In the rare case where @@ -2128,7 +2128,7 @@ meta_window_actor_process_x11_damage (MetaWindowActor *self, if (meta_window_is_fullscreen (priv->window) && g_list_last (info->windows)->data == self && !priv->unredirected) { MetaRectangle window_rect; - meta_window_get_outer_rect (priv->window, &window_rect); + meta_window_get_frame_rect (priv->window, &window_rect); if (window_rect.x == event->area.x && window_rect.y == event->area.y && diff --git a/src/compositor/meta-window-group.c b/src/compositor/meta-window-group.c index 3a280a733..46d710b92 100644 --- a/src/compositor/meta-window-group.c +++ b/src/compositor/meta-window-group.c @@ -163,7 +163,7 @@ meta_window_group_paint (ClutterActor *actor) cairo_rectangle_int_t unredirected_rect; MetaWindow *window = meta_window_actor_get_meta_window (info->unredirected_window); - meta_window_get_outer_rect (window, (MetaRectangle *)&unredirected_rect); + meta_window_get_frame_rect (window, (MetaRectangle *)&unredirected_rect); cairo_region_subtract_rectangle (unobscured_region, &unredirected_rect); cairo_region_subtract_rectangle (clip_region, &unredirected_rect); } diff --git a/src/core/constraints.c b/src/core/constraints.c index 97e1e79de..302267fac 100644 --- a/src/core/constraints.c +++ b/src/core/constraints.c @@ -497,7 +497,7 @@ place_window_if_needed(MetaWindow *window, MetaWorkspace *cur_workspace; const MetaMonitorInfo *monitor_info; - meta_window_get_outer_rect (window, &placed_rect); + meta_window_get_frame_rect (window, &placed_rect); meta_window_place (window, info->orig.x, info->orig.y, &placed_rect.x, &placed_rect.y); did_placement = TRUE; @@ -707,8 +707,8 @@ get_size_limits (MetaWindow *window, if (include_frame) { - meta_window_client_rect_to_outer_rect (window, min_size, min_size); - meta_window_client_rect_to_outer_rect (window, max_size, max_size); + meta_window_client_rect_to_frame_rect (window, min_size, min_size); + meta_window_client_rect_to_frame_rect (window, max_size, max_size); } } @@ -735,7 +735,7 @@ constrain_modal_dialog (MetaWindow *window, child_rect = info->current; extend_by_frame (window, &child_rect); - meta_window_get_outer_rect (parent, &parent_rect); + meta_window_get_frame_rect (parent, &parent_rect); child_rect.x = parent_rect.x + (parent_rect.width / 2 - child_rect.width / 2); child_rect.y = parent_rect.y + (parent_rect.height / 2 - child_rect.height / 2); diff --git a/src/core/display.c b/src/core/display.c index 2915c3aa2..8e90af094 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -1619,7 +1619,7 @@ window_raise_with_delay_callback (void *data) &root_x, &root_y, &x, &y, &mask); meta_error_trap_pop (window->display); - meta_window_get_outer_rect (window, &frame_rect); + meta_window_get_frame_rect (window, &frame_rect); point_in_window = POINT_IN_RECT (root_x, root_y, frame_rect); if (same_screen && point_in_window) meta_window_raise (window); @@ -2177,7 +2177,7 @@ meta_display_handle_event (MetaDisplay *display, int root_x, root_y; MetaGrabOp op; - meta_window_get_outer_rect (window, &frame_rect); + meta_window_get_frame_rect (window, &frame_rect); west = event->button.x < (frame_rect.x + 1 * frame_rect.width / 3); east = event->button.x > (frame_rect.x + 2 * frame_rect.width / 3); diff --git a/src/core/edge-resistance.c b/src/core/edge-resistance.c index 597200216..17cde421f 100644 --- a/src/core/edge-resistance.c +++ b/src/core/edge-resistance.c @@ -985,7 +985,7 @@ compute_resistance_and_snapping_edges (MetaDisplay *display) { MetaRectangle *new_rect; new_rect = g_new (MetaRectangle, 1); - meta_window_get_outer_rect (cur_window, new_rect); + meta_window_get_frame_rect (cur_window, new_rect); obscuring_windows = g_slist_prepend (obscuring_windows, new_rect); window_stacking = g_slist_prepend (window_stacking, GINT_TO_POINTER (stack_position)); @@ -1010,7 +1010,7 @@ compute_resistance_and_snapping_edges (MetaDisplay *display) { MetaRectangle cur_rect; MetaWindow *cur_window = cur_window_iter->data; - meta_window_get_outer_rect (cur_window, &cur_rect); + meta_window_get_frame_rect (cur_window, &cur_rect); /* Check if we want to use this window's edges for edge * resistance (note that dock edges are considered screen edges @@ -1151,7 +1151,7 @@ meta_window_edge_resistance_for_move (MetaWindow *window, MetaRectangle old_outer, proposed_outer, new_outer; gboolean is_resize; - meta_window_get_outer_rect (window, &old_outer); + meta_window_get_frame_rect (window, &old_outer); proposed_outer = old_outer; proposed_outer.x += (*new_x - old_x); @@ -1237,7 +1237,7 @@ meta_window_edge_resistance_for_resize (MetaWindow *window, int proposed_outer_width, proposed_outer_height; gboolean is_resize; - meta_window_get_outer_rect (window, &old_outer); + meta_window_get_frame_rect (window, &old_outer); proposed_outer_width = old_outer.width + (*new_width - old_width); proposed_outer_height = old_outer.height + (*new_height - old_height); meta_rectangle_resize_with_gravity (&old_outer, diff --git a/src/core/keybindings.c b/src/core/keybindings.c index 526efc36f..23539a89b 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -3125,17 +3125,17 @@ handle_move_to_corner_backend (MetaDisplay *display, gpointer dummy) { MetaRectangle work_area; - MetaRectangle outer; + MetaRectangle frame_rect; int orig_x, orig_y; int new_x, new_y; meta_window_get_work_area_all_monitors (window, &work_area); - meta_window_get_outer_rect (window, &outer); + meta_window_get_frame_rect (window, &frame_rect); meta_window_get_position (window, &orig_x, &orig_y); if (xchange) { new_x = work_area.x + (to_right ? - work_area.width - outer.width : + work_area.width - frame_rect.width : 0); } else { new_x = orig_x; @@ -3143,7 +3143,7 @@ handle_move_to_corner_backend (MetaDisplay *display, if (ychange) { new_y = work_area.y + (to_bottom ? - work_area.height - outer.height : + work_area.height - frame_rect.height : 0); } else { new_y = orig_y; @@ -3252,12 +3252,12 @@ handle_move_to_center (MetaDisplay *display, gpointer dummy) { MetaRectangle work_area; - MetaRectangle outer; + MetaRectangle frame_rect; int orig_x, orig_y; int frame_width, frame_height; meta_window_get_work_area_all_monitors (window, &work_area); - meta_window_get_outer_rect (window, &outer); + meta_window_get_frame_rect (window, &frame_rect); meta_window_get_position (window, &orig_x, &orig_y); frame_width = (window->frame ? window->frame->child_x : 0); @@ -3265,8 +3265,8 @@ handle_move_to_center (MetaDisplay *display, meta_window_move_resize (window, TRUE, - work_area.x + (work_area.width +frame_width -outer.width )/2, - work_area.y + (work_area.height+frame_height-outer.height)/2, + work_area.x + (work_area.width +frame_width -frame_rect.width )/2, + work_area.y + (work_area.height+frame_height-frame_rect.height)/2, window->rect.width, window->rect.height); } @@ -3958,8 +3958,8 @@ handle_raise_or_lower (MetaDisplay *display, if (above->mapped) { - meta_window_get_outer_rect (window, &win_rect); - meta_window_get_outer_rect (above, &above_rect); + meta_window_get_frame_rect (window, &win_rect); + meta_window_get_frame_rect (above, &above_rect); /* Check if obscured */ if (meta_rectangle_intersect (&win_rect, &above_rect, &tmp)) diff --git a/src/core/place.c b/src/core/place.c index a2c7df3c7..821fca039 100644 --- a/src/core/place.c +++ b/src/core/place.c @@ -53,8 +53,8 @@ northwestcmp (gconstpointer a, gconstpointer b) int from_origin_b; int ax, ay, bx, by; - meta_window_get_outer_rect (aw, &a_frame); - meta_window_get_outer_rect (bw, &b_frame); + meta_window_get_frame_rect (aw, &a_frame); + meta_window_get_frame_rect (bw, &b_frame); ax = a_frame.x; ay = a_frame.y; bx = b_frame.x; @@ -131,7 +131,7 @@ find_next_cascade (MetaWindow *window, /* Find first cascade position that's not used. */ - meta_window_get_outer_rect (window, &frame_rect); + meta_window_get_frame_rect (window, &frame_rect); window_width = frame_rect.width; window_height = frame_rect.height; @@ -146,7 +146,7 @@ find_next_cascade (MetaWindow *window, w = tmp->data; /* we want frame position, not window position */ - meta_window_get_outer_rect (w, &w_frame_rect); + meta_window_get_frame_rect (w, &w_frame_rect); wx = w_frame_rect.x; wy = w_frame_rect.y; @@ -224,23 +224,23 @@ find_most_freespace (MetaWindow *window, int left_space, right_space, top_space, bottom_space; MetaRectangle work_area; MetaRectangle avoid; - MetaRectangle outer; + MetaRectangle frame_rect; meta_window_get_work_area_current_monitor (focus_window, &work_area); - meta_window_get_outer_rect (focus_window, &avoid); - meta_window_get_outer_rect (window, &outer); + meta_window_get_frame_rect (focus_window, &avoid); + meta_window_get_frame_rect (window, &frame_rect); /* Find the areas of choosing the various sides of the focus window */ - max_width = MIN (avoid.width, outer.width); - max_height = MIN (avoid.height, outer.height); + max_width = MIN (avoid.width, frame_rect.width); + max_height = MIN (avoid.height, frame_rect.height); left_space = avoid.x - work_area.x; right_space = work_area.width - (avoid.x + avoid.width - work_area.x); top_space = avoid.y - work_area.y; bottom_space = work_area.height - (avoid.y + avoid.height - work_area.y); - left = MIN (left_space, outer.width); - right = MIN (right_space, outer.width); - top = MIN (top_space, outer.height); - bottom = MIN (bottom_space, outer.height); + left = MIN (left_space, frame_rect.width); + right = MIN (right_space, frame_rect.width); + top = MIN (top_space, frame_rect.height); + bottom = MIN (bottom_space, frame_rect.height); /* Find out which side of the focus_window can show the most of the window */ side = META_LEFT; @@ -273,31 +273,31 @@ find_most_freespace (MetaWindow *window, { case META_LEFT: *new_y = avoid.y; - if (left_space > outer.width) - *new_x = avoid.x - outer.width; + if (left_space > frame_rect.width) + *new_x = avoid.x - frame_rect.width; else *new_x = work_area.x; break; case META_RIGHT: *new_y = avoid.y; - if (right_space > outer.width) + if (right_space > frame_rect.width) *new_x = avoid.x + avoid.width; else - *new_x = work_area.x + work_area.width - outer.width; + *new_x = work_area.x + work_area.width - frame_rect.width; break; case META_TOP: *new_x = avoid.x; - if (top_space > outer.height) - *new_y = avoid.y - outer.height; + if (top_space > frame_rect.height) + *new_y = avoid.y - frame_rect.height; else *new_y = work_area.y; break; case META_BOTTOM: *new_x = avoid.x; - if (bottom_space > outer.height) + if (bottom_space > frame_rect.height) *new_y = avoid.y + avoid.height; else - *new_y = work_area.y + work_area.height - outer.height; + *new_y = work_area.y + work_area.height - frame_rect.height; break; } } @@ -312,8 +312,8 @@ window_overlaps_focus_window (MetaWindow *window) if (focus_window == NULL) return FALSE; - meta_window_get_outer_rect (window, &window_frame); - meta_window_get_outer_rect (focus_window, &focus_frame); + meta_window_get_frame_rect (window, &window_frame); + meta_window_get_frame_rect (focus_window, &focus_frame); return meta_rectangle_intersect (&window_frame, &focus_frame, @@ -393,7 +393,7 @@ rectangle_overlaps_some_window (MetaRectangle *rect, case META_WINDOW_UTILITY: case META_WINDOW_TOOLBAR: case META_WINDOW_MENU: - meta_window_get_outer_rect (other, &other_rect); + meta_window_get_frame_rect (other, &other_rect); if (meta_rectangle_intersect (rect, &other_rect, &dest)) return TRUE; @@ -415,8 +415,8 @@ leftmost_cmp (gconstpointer a, gconstpointer b) MetaRectangle b_frame; int ax, bx; - meta_window_get_outer_rect (aw, &a_frame); - meta_window_get_outer_rect (bw, &b_frame); + meta_window_get_frame_rect (aw, &a_frame); + meta_window_get_frame_rect (bw, &b_frame); ax = a_frame.x; bx = b_frame.x; @@ -437,8 +437,8 @@ topmost_cmp (gconstpointer a, gconstpointer b) MetaRectangle b_frame; int ay, by; - meta_window_get_outer_rect (aw, &a_frame); - meta_window_get_outer_rect (bw, &b_frame); + meta_window_get_frame_rect (aw, &a_frame); + meta_window_get_frame_rect (bw, &b_frame); ay = a_frame.y; by = b_frame.y; @@ -512,7 +512,7 @@ find_first_fit (MetaWindow *window, right_sorted = g_list_sort (right_sorted, topmost_cmp); right_sorted = g_list_sort (right_sorted, leftmost_cmp); - meta_window_get_outer_rect (window, &rect); + meta_window_get_frame_rect (window, &rect); #ifdef WITH_VERBOSE_MODE { @@ -545,12 +545,12 @@ find_first_fit (MetaWindow *window, while (tmp != NULL) { MetaWindow *w = tmp->data; - MetaRectangle outer_rect; + MetaRectangle frame_rect; - meta_window_get_outer_rect (w, &outer_rect); + meta_window_get_frame_rect (w, &frame_rect); - rect.x = outer_rect.x; - rect.y = outer_rect.y + outer_rect.height; + rect.x = frame_rect.x; + rect.y = frame_rect.y + frame_rect.height; if (meta_rectangle_contains_rect (&work_area, &rect) && !rectangle_overlaps_some_window (&rect, below_sorted)) @@ -571,12 +571,12 @@ find_first_fit (MetaWindow *window, while (tmp != NULL) { MetaWindow *w = tmp->data; - MetaRectangle outer_rect; + MetaRectangle frame_rect; - meta_window_get_outer_rect (w, &outer_rect); + meta_window_get_frame_rect (w, &frame_rect); - rect.x = outer_rect.x + outer_rect.width; - rect.y = outer_rect.y; + rect.x = frame_rect.x + frame_rect.width; + rect.y = frame_rect.y; if (meta_rectangle_contains_rect (&work_area, &rect) && !rectangle_overlaps_some_window (&rect, right_sorted)) @@ -718,8 +718,8 @@ meta_window_place (MetaWindow *window, { MetaRectangle frame_rect, parent_frame_rect; - meta_window_get_outer_rect (window, &frame_rect); - meta_window_get_outer_rect (parent, &parent_frame_rect); + meta_window_get_frame_rect (window, &frame_rect); + meta_window_get_frame_rect (parent, &parent_frame_rect); y = parent_frame_rect.y; @@ -754,7 +754,7 @@ meta_window_place (MetaWindow *window, int w, h; MetaRectangle frame_rect; - meta_window_get_outer_rect (window, &frame_rect); + meta_window_get_frame_rect (window, &frame_rect); /* Warning, this function is a round trip! */ xi = meta_screen_get_current_monitor_info (window->screen); @@ -820,17 +820,17 @@ meta_window_place (MetaWindow *window, !window->fullscreen) { MetaRectangle workarea; - MetaRectangle outer; + MetaRectangle frame_rect; meta_window_get_work_area_for_monitor (window, xi->number, &workarea); - meta_window_get_outer_rect (window, &outer); + meta_window_get_frame_rect (window, &frame_rect); /* If the window is bigger than the screen, then automaximize. Do NOT * auto-maximize the directions independently. See #419810. */ - if (outer.width >= workarea.width && outer.height >= workarea.height) + if (frame_rect.width >= workarea.width && frame_rect.height >= workarea.height) { window->maximize_horizontally_after_placement = TRUE; window->maximize_vertically_after_placement = TRUE; diff --git a/src/core/screen.c b/src/core/screen.c index 5ade5df20..90083ecbb 100644 --- a/src/core/screen.c +++ b/src/core/screen.c @@ -1528,7 +1528,7 @@ meta_screen_tab_popup_create (MetaScreen *screen, if (show_type == META_TAB_SHOW_INSTANTLY || !entries[i].hidden || !meta_window_get_icon_geometry (window, &r)) - meta_window_get_outer_rect (window, &r); + meta_window_get_frame_rect (window, &r); entries[i].rect = r; @@ -1914,7 +1914,7 @@ meta_screen_get_monitor_for_window (MetaScreen *screen, { MetaRectangle window_rect; - meta_window_get_outer_rect (window, &window_rect); + meta_window_get_frame_rect (window, &window_rect); return meta_screen_get_monitor_for_rect (screen, &window_rect); } diff --git a/src/core/stack.c b/src/core/stack.c index 911dc35fb..0e89e1918 100644 --- a/src/core/stack.c +++ b/src/core/stack.c @@ -1693,7 +1693,7 @@ window_contains_point (MetaWindow *window, { MetaRectangle rect; - meta_window_get_outer_rect (window, &rect); + meta_window_get_frame_rect (window, &rect); return POINT_IN_RECT (root_x, root_y, rect); } diff --git a/src/core/window.c b/src/core/window.c index e98aa843e..86f284d81 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -2931,8 +2931,8 @@ static gboolean windows_overlap (const MetaWindow *w1, const MetaWindow *w2) { MetaRectangle w1rect, w2rect; - meta_window_get_outer_rect (w1, &w1rect); - meta_window_get_outer_rect (w2, &w2rect); + meta_window_get_frame_rect (w1, &w1rect); + meta_window_get_frame_rect (w2, &w2rect); return meta_rectangle_overlap (&w1rect, &w2rect); } @@ -3733,11 +3733,11 @@ meta_window_maximize (MetaWindow *window, MetaRectangle old_rect; MetaRectangle new_rect; - meta_window_get_outer_rect (window, &old_rect); + meta_window_get_frame_rect (window, &old_rect); meta_window_move_resize_now (window); - meta_window_get_outer_rect (window, &new_rect); + meta_window_get_frame_rect (window, &new_rect); meta_compositor_maximize_window (window->display->compositor, window, &old_rect, @@ -3796,7 +3796,7 @@ meta_window_get_all_monitors (MetaWindow *window, gsize *length) int i; monitors = g_array_new (FALSE, FALSE, sizeof (int)); - meta_window_get_outer_rect (window, &window_rect); + meta_window_get_frame_rect (window, &window_rect); for (i = 0; i < window->screen->n_monitor_infos; i++) { @@ -3829,7 +3829,7 @@ meta_window_is_screen_sized (MetaWindow *window) int screen_width, screen_height; meta_screen_get_size (window->screen, &screen_width, &screen_height); - meta_window_get_outer_rect (window, &window_rect); + meta_window_get_frame_rect (window, &window_rect); if (window_rect.x == 0 && window_rect.y == 0 && window_rect.width == screen_width && window_rect.height == screen_height) @@ -3858,7 +3858,7 @@ meta_window_is_monitor_sized (MetaWindow *window) { MetaRectangle window_rect, monitor_rect; - meta_window_get_outer_rect (window, &window_rect); + meta_window_get_frame_rect (window, &window_rect); meta_screen_get_monitor_geometry (window->screen, window->monitor->number, &monitor_rect); if (meta_rectangle_equal (&window_rect, &monitor_rect)) @@ -3926,11 +3926,11 @@ meta_window_tile (MetaWindow *window) MetaRectangle old_rect; MetaRectangle new_rect; - meta_window_get_outer_rect (window, &old_rect); + meta_window_get_frame_rect (window, &old_rect); meta_window_move_resize_now (window); - meta_window_get_outer_rect (window, &new_rect); + meta_window_get_frame_rect (window, &new_rect); meta_compositor_maximize_window (window->display->compositor, window, &old_rect, @@ -4098,7 +4098,7 @@ meta_window_unmaximize_internal (MetaWindow *window, { MetaRectangle old_rect, new_rect; - meta_window_get_outer_rect (window, &old_rect); + meta_window_get_frame_rect (window, &old_rect); meta_window_move_resize_internal (window, META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION, @@ -4108,7 +4108,7 @@ meta_window_unmaximize_internal (MetaWindow *window, target_rect.width, target_rect.height); - meta_window_get_outer_rect (window, &new_rect); + meta_window_get_frame_rect (window, &new_rect); meta_compositor_unmaximize_window (window->display->compositor, window, &old_rect, @@ -6129,16 +6129,17 @@ meta_window_frame_rect_to_client_rect (MetaWindow *window, } /** - * meta_window_get_outer_rect: + * meta_window_get_frame_rect: * @window: a #MetaWindow * @rect: (out): pointer to an allocated #MetaRectangle * - * Gets the rectangle that bounds @window that is responsive to mouse events. - * This includes only what is visible; it doesn't include any extra reactive - * area we add to the edges of windows. + * Gets the rectangle that bounds @window that is what the user thinks of + * as the edge of the window. This doesn't include any extra reactive + * area that we or the client adds to the window, or any area that the + * client adds to draw a client-side shadow. */ void -meta_window_get_outer_rect (const MetaWindow *window, +meta_window_get_frame_rect (const MetaWindow *window, MetaRectangle *rect) { if (window->frame) @@ -6167,6 +6168,25 @@ meta_window_get_outer_rect (const MetaWindow *window, } } +/** + * meta_window_get_outer_rect: + * @window: a #MetaWindow + * @rect: (out): pointer to an allocated #MetaRectangle + * + * Gets the rectangle that bounds @window that is what the user thinks of + * as the edge of the window. This doesn't include any extra reactive + * area that we or the client adds to the window, or any area that the + * client adds to draw a client-side shadow. + * + * Deprecated: 3.10: Use meta_window_get_frame_rect() instead. + */ +void +meta_window_get_outer_rect (const MetaWindow *window, + MetaRectangle *rect) +{ + meta_window_get_frame_rect (window, rect); +} + const char* meta_window_get_startup_id (MetaWindow *window) { @@ -9241,7 +9261,7 @@ meta_window_show_menu (MetaWindow *window, void meta_window_shove_titlebar_onscreen (MetaWindow *window) { - MetaRectangle outer_rect; + MetaRectangle frame_rect; GList *onscreen_region; int horiz_amount, vert_amount; int newx, newy; @@ -9253,15 +9273,15 @@ meta_window_shove_titlebar_onscreen (MetaWindow *window) return; /* Get the basic info we need */ - meta_window_get_outer_rect (window, &outer_rect); + meta_window_get_frame_rect (window, &frame_rect); onscreen_region = window->screen->active_workspace->screen_region; /* Extend the region (just in case the window is too big to fit on the * screen), then shove the window on screen, then return the region to * normal. */ - horiz_amount = outer_rect.width; - vert_amount = outer_rect.height; + horiz_amount = frame_rect.width; + vert_amount = frame_rect.height; meta_rectangle_expand_region (onscreen_region, horiz_amount, horiz_amount, @@ -9269,15 +9289,15 @@ meta_window_shove_titlebar_onscreen (MetaWindow *window) vert_amount); meta_rectangle_shove_into_region(onscreen_region, FIXED_DIRECTION_X, - &outer_rect); + &frame_rect); meta_rectangle_expand_region (onscreen_region, -horiz_amount, -horiz_amount, 0, -vert_amount); - newx = outer_rect.x + window->frame->child_x; - newy = outer_rect.y + window->frame->child_y; + newx = frame_rect.x + window->frame->child_x; + newy = frame_rect.y + window->frame->child_y; meta_window_move_resize (window, FALSE, newx, @@ -9302,7 +9322,7 @@ meta_window_titlebar_is_onscreen (MetaWindow *window) return FALSE; /* Get the rectangle corresponding to the titlebar */ - meta_window_get_outer_rect (window, &titlebar_rect); + meta_window_get_frame_rect (window, &titlebar_rect); titlebar_rect.height = window->frame->child_y; /* Run through the spanning rectangles for the screen and see if one of @@ -10532,7 +10552,7 @@ warp_grab_pointer (MetaWindow *window, /* We may not have done begin_grab_op yet, i.e. may not be in a grab */ - meta_window_get_outer_rect (window, &rect); + meta_window_get_frame_rect (window, &rect); switch (grab_op) { @@ -10871,7 +10891,7 @@ meta_window_set_demands_attention (MetaWindow *window) } else { - meta_window_get_outer_rect (window, &candidate_rect); + meta_window_get_frame_rect (window, &candidate_rect); /* The stack is sorted with the top windows first. */ @@ -10882,7 +10902,7 @@ meta_window_set_demands_attention (MetaWindow *window) if (meta_window_located_on_workspace (other_window, window->workspace)) { - meta_window_get_outer_rect (other_window, &other_rect); + meta_window_get_frame_rect (other_window, &other_rect); if (meta_rectangle_overlap (&candidate_rect, &other_rect)) { @@ -11588,8 +11608,8 @@ meta_window_compute_tile_match (MetaWindow *window) bottommost = match; } - meta_window_get_outer_rect (bottommost, &bottommost_rect); - meta_window_get_outer_rect (topmost, &topmost_rect); + meta_window_get_frame_rect (bottommost, &bottommost_rect); + meta_window_get_frame_rect (topmost, &topmost_rect); /* * If there's a window stacked in between which is partially visible * behind the topmost tile we don't consider the tiles to match. @@ -11603,7 +11623,7 @@ meta_window_compute_tile_match (MetaWindow *window) meta_window_get_workspace (above) != meta_window_get_workspace (window)) continue; - meta_window_get_outer_rect (above, &above_rect); + meta_window_get_frame_rect (above, &above_rect); if (meta_rectangle_overlap (&above_rect, &bottommost_rect) && meta_rectangle_overlap (&above_rect, &topmost_rect)) diff --git a/src/meta/window.h b/src/meta/window.h index da4448923..c7ccc358b 100644 --- a/src/meta/window.h +++ b/src/meta/window.h @@ -110,7 +110,9 @@ gboolean meta_window_is_override_redirect (MetaWindow *window); gboolean meta_window_is_skip_taskbar (MetaWindow *window); MetaRectangle *meta_window_get_rect (MetaWindow *window); void meta_window_get_input_rect (const MetaWindow *window, MetaRectangle *rect); -void meta_window_get_outer_rect (const MetaWindow *window, MetaRectangle *rect); + +void meta_window_get_frame_rect (const MetaWindow *window, MetaRectangle *rect); +void meta_window_get_outer_rect (const MetaWindow *window, MetaRectangle *rect) G_GNUC_DEPRECATED; void meta_window_client_rect_to_frame_rect (MetaWindow *window, MetaRectangle *frame_rect, From 333661a9d8851ce31d54f4aadb7cefcbc0a2f05e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Tue, 19 Nov 2013 19:50:58 +0100 Subject: [PATCH 253/889] stack: Drop unused code Since commit 2b2b2d319191f5 the code is unused and triggers a compiler error with -Werror=unused-but-set-variable. --- src/core/stack.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/core/stack.c b/src/core/stack.c index 0e89e1918..ed1d6d8d4 100644 --- a/src/core/stack.c +++ b/src/core/stack.c @@ -1327,15 +1327,6 @@ stack_sync_to_xserver (MetaStack *stack) /* build XRestackWindows() array from top to bottom */ if (w->client_type == META_WINDOW_CLIENT_TYPE_X11) g_array_append_val (x11_root_children_stacked, top_level_window); - else - { - MetaStackWindow *new; - - /* So we can determine later if a cached stack window is - * stale because the corresponding window has been freed we - * associate a weak pointer with the new window. */ - new = &g_array_index (all_root_children_stacked, MetaStackWindow, all_root_children_stacked->len - 1); - } } meta_topic (META_DEBUG_STACK, "\n"); From 17f48baf3a08b96cb1cb9a4147aa41ee2e0f73cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Tue, 19 Nov 2013 19:44:30 +0100 Subject: [PATCH 254/889] display: Tweak code to work around a compiler warning The compiler is not quite smart enough to figure out that the condition for setting the "compositor" variable matches a later condition for accessing it, so express this in a way the compiler will understand. --- src/core/display.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/display.c b/src/core/display.c index 8e90af094..2a6779d9c 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -2042,7 +2042,7 @@ meta_display_handle_event (MetaDisplay *display, /* XXX -- we need to fill this in properly at some point... */ gboolean frame_was_receiver = FALSE; #ifdef HAVE_WAYLAND - MetaWaylandCompositor *compositor; + MetaWaylandCompositor *compositor = NULL; if (meta_is_wayland_compositor ()) { @@ -2293,7 +2293,7 @@ meta_display_handle_event (MetaDisplay *display, } #ifdef HAVE_WAYLAND - if (meta_is_wayland_compositor () && (display->grab_op == META_GRAB_OP_NONE)) + if (compositor && (display->grab_op == META_GRAB_OP_NONE)) { if (meta_wayland_compositor_handle_event (compositor, event)) return TRUE; From 3025cb7c48e4e0b09b330e625a2d69990b713b51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Tue, 19 Nov 2013 20:12:36 +0100 Subject: [PATCH 255/889] display: Remove unused variables --- src/core/display.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/display.c b/src/core/display.c index 2a6779d9c..6d1b24533 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -2174,7 +2174,6 @@ meta_display_handle_event (MetaDisplay *display, gboolean north, south; gboolean west, east; MetaRectangle frame_rect; - int root_x, root_y; MetaGrabOp op; meta_window_get_frame_rect (window, &frame_rect); From a6ebc70170c87924325d7e07d28bef4c6c730ccf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Tue, 19 Nov 2013 19:10:12 +0100 Subject: [PATCH 256/889] Bump version to 3.11.2 Update NEWS. --- NEWS | 16 ++++++++++++++++ configure.ac | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index b7c5dda54..b4d0e9011 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,19 @@ +3.11.2 +====== +* Support setting a NULL opaque region [Andreas; #711518] +* Sync keymap from X to wayland [Giovanni; #707446] +* Implement support for subsurfaces [Jonas; #705502] +* Don't focus the no-focus-window for globally active windows [Jasper; #710296] +* Support "hotplug_mode_update" property [Marc-André; #711216] +* Fix resize operations using mouse-button-modifier [Lionel; #710251] +* Fix position of attached modals for CSD windows [Giovanni, Owen; #707194] +* Misc. bug fixes [Rui, Jasper, Neil, Florian; #712247, #711731] + +Contributors: + Giovanni Campagna, Andreas Heider, Lionel Landwerlin, Marc-André Lureau, + Rui Matos, Florian Müllner, Neil Roberts, Sindhu S, Jasper St. Pierre, + Rico Tzschichholz, Owen W. Taylor, Jonas Ådahl + 3.11.1 ====== * Fix tile previews getting stuck on right click during drags [Lionel; #704759] diff --git a/configure.ac b/configure.ac index b79289da9..7969a71e2 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ AC_CONFIG_MACRO_DIR([m4]) m4_define([mutter_major_version], [3]) m4_define([mutter_minor_version], [11]) -m4_define([mutter_micro_version], [1]) +m4_define([mutter_micro_version], [2]) m4_define([mutter_version], [mutter_major_version.mutter_minor_version.mutter_micro_version]) From 4326d0bf3af57dca6be74d4eb53f411d318d1aa1 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 19 Nov 2013 15:37:31 -0500 Subject: [PATCH 257/889] compositor: Make sure to construct plugin_mgr in Wayland as well... --- src/compositor/compositor.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index d4e7ebd7f..6c9c1376e 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -816,8 +816,6 @@ meta_compositor_manage_screen (MetaCompositor *compositor, info->pending_input_region = None; } - info->plugin_mgr = meta_plugin_manager_new (screen); - /* Map overlay window before redirecting windows offscreen so we catch their * contents until we show the stage. */ @@ -825,6 +823,8 @@ meta_compositor_manage_screen (MetaCompositor *compositor, redirect_windows (compositor, screen); } + + info->plugin_mgr = meta_plugin_manager_new (screen); } void From ca342c45733541344d9f93bdadaf93377ee3944c Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 19 Nov 2013 14:42:50 -0500 Subject: [PATCH 258/889] window: Remove unused parameter from meta_window_new_shared() --- src/core/window.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/core/window.c b/src/core/window.c index 86f284d81..e5013213d 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -827,7 +827,6 @@ meta_window_new_shared (MetaDisplay *display, MetaWindowClientType client_type, MetaWaylandSurface *surface, Window xwindow, - gboolean must_be_viewable, gulong existing_wm_state, MetaCompEffect effect, XWindowAttributes *attrs) @@ -838,8 +837,7 @@ meta_window_new_shared (MetaDisplay *display, g_assert (attrs != NULL); - meta_verbose ("must_be_viewable = %d attrs->map_state = %d (%s)\n", - must_be_viewable, + meta_verbose ("attrs->map_state = %d (%s)\n", attrs->map_state, (attrs->map_state == IsUnmapped) ? "IsUnmapped" : @@ -1421,7 +1419,6 @@ meta_window_new_for_wayland (MetaDisplay *display, META_WINDOW_CLIENT_TYPE_WAYLAND, surface, None, - TRUE, WithdrawnState, META_COMP_EFFECT_NONE, &attrs); @@ -1601,7 +1598,6 @@ meta_window_new_with_attrs (MetaDisplay *display, META_WINDOW_CLIENT_TYPE_X11, NULL, xwindow, - must_be_viewable, existing_wm_state, effect, attrs); From d945501be6cee1d1abaedd3ecff627d624e68a9c Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 19 Nov 2013 15:32:33 -0500 Subject: [PATCH 259/889] window: Remove width/height from meta_window_new_for_wayland --- src/core/window-private.h | 2 -- src/core/window.c | 6 ++---- src/wayland/meta-wayland-surface.c | 6 +----- 3 files changed, 3 insertions(+), 11 deletions(-) diff --git a/src/core/window-private.h b/src/core/window-private.h index cc2faa424..82d68fd18 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -508,8 +508,6 @@ MetaWindow* meta_window_new_with_attrs (MetaDisplay *display, MetaCompEffect effect, XWindowAttributes *attrs); MetaWindow *meta_window_new_for_wayland (MetaDisplay *display, - int width, - int height, MetaWaylandSurface *surface); void meta_window_unmanage (MetaWindow *window, guint32 timestamp); diff --git a/src/core/window.c b/src/core/window.c index e5013213d..6d0c295a3 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -1369,8 +1369,6 @@ display_notify_window (MetaDisplay *display, MetaWindow *window) MetaWindow * meta_window_new_for_wayland (MetaDisplay *display, - int width, - int height, MetaWaylandSurface *surface) { XWindowAttributes attrs; @@ -1379,8 +1377,8 @@ meta_window_new_for_wayland (MetaDisplay *display, attrs.x = 0; attrs.y = 0; - attrs.width = width; - attrs.height = height; + attrs.width = 1; + attrs.height = 1; attrs.border_width = 0; attrs.depth = 24; attrs.visual = NULL; diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 1df898182..226a2afc7 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -246,7 +246,6 @@ static void surface_ensure_window (MetaWaylandSurface *surface) { MetaDisplay *display = meta_get_display (); - int width, height; if (surface->window) return; @@ -254,10 +253,7 @@ surface_ensure_window (MetaWaylandSurface *surface) if (!surface_wants_window (surface)) return; - width = surface->buffer_ref.buffer->width; - height = surface->buffer_ref.buffer->height; - - surface->window = meta_window_new_for_wayland (display, width, height, surface); + surface->window = meta_window_new_for_wayland (display, surface); } static void From 0824eb7c965a05a2acc0d81e4ef3b11fefc502dc Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 19 Nov 2013 15:43:46 -0500 Subject: [PATCH 260/889] cursor-tracker: Make sure to sync after we change the cursor So the cursor changes immediately... --- src/core/meta-cursor-tracker.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/core/meta-cursor-tracker.c b/src/core/meta-cursor-tracker.c index eda4cd99d..e045841a1 100644 --- a/src/core/meta-cursor-tracker.c +++ b/src/core/meta-cursor-tracker.c @@ -124,6 +124,7 @@ static guint signals[LAST_SIGNAL]; static void meta_cursor_tracker_set_crtc_has_hw_cursor (MetaCursorTracker *tracker, MetaCRTC *crtc, gboolean has_hw_cursor); +static void sync_cursor (MetaCursorTracker *tracker); static MetaCursorReference * meta_cursor_reference_ref (MetaCursorReference *self) @@ -675,6 +676,7 @@ set_window_cursor (MetaCursorTracker *tracker, if (cursor) tracker->window_cursor = meta_cursor_reference_ref (cursor); tracker->has_window_cursor = has_cursor; + sync_cursor (tracker); } gboolean @@ -839,6 +841,7 @@ meta_cursor_tracker_set_grab_cursor (MetaCursorTracker *tracker, g_clear_pointer (&tracker->grab_cursor, meta_cursor_reference_unref); if (cursor != META_CURSOR_DEFAULT) tracker->grab_cursor = ensure_wayland_cursor (tracker, cursor); + sync_cursor (tracker); } void @@ -882,6 +885,7 @@ meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker, { g_clear_pointer (&tracker->root_cursor, meta_cursor_reference_unref); tracker->root_cursor = ensure_wayland_cursor (tracker, cursor); + sync_cursor (tracker); } } From 5959457c730f17b7837aa2bcf8d963343c122f26 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 19 Nov 2013 17:32:59 -0500 Subject: [PATCH 261/889] wayland-surface: Embed MetaWaylandSurfaceExtension in MetaWaylandSurface This makes it easier to support xdg_surface.destroy, which we're going to add support for next commit... --- src/wayland/meta-wayland-pointer.c | 2 +- src/wayland/meta-wayland-surface.c | 202 +++++++++++++---------------- src/wayland/meta-wayland-surface.h | 5 +- 3 files changed, 95 insertions(+), 114 deletions(-) diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index 2a44ac06a..3540f747c 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -538,7 +538,7 @@ meta_wayland_pointer_end_popup_grab (MetaWaylandPointer *pointer) wl_list_for_each_safe (popup, tmp, &popup_grab->all_popups, link) { - MetaWaylandSurfaceExtension *shell_surface = popup->surface->xdg_surface; + MetaWaylandSurfaceExtension *shell_surface = &popup->surface->xdg_surface; struct wl_client *client = wl_resource_get_client (shell_surface->resource); struct wl_display *display = wl_client_get_display (client); uint32_t serial; diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 226a2afc7..75a5d1b0d 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -239,7 +239,7 @@ empty_region (cairo_region_t *region) static gboolean surface_wants_window (MetaWaylandSurface *surface) { - return (surface->xdg_surface != NULL); + return (surface->xdg_surface.resource != NULL); } static void @@ -514,6 +514,54 @@ meta_wayland_surface_create (MetaWaylandCompositor *compositor, return surface; } +static void +destroy_surface_extension (struct wl_resource *resource) +{ + MetaWaylandSurfaceExtension *extension = wl_resource_get_user_data (resource); + wl_list_remove (&extension->surface_destroy_listener.link); + extension->surface_destroy_listener.notify = NULL; + extension->resource = NULL; +} + +static void +extension_handle_surface_destroy (struct wl_listener *listener, + void *data) +{ + MetaWaylandSurfaceExtension *extension = wl_container_of (listener, extension, surface_destroy_listener); + wl_resource_destroy (extension->resource); +} + +static int +get_resource_version (struct wl_resource *master_resource, + int max_version) +{ + return MIN (max_version, wl_resource_get_version (master_resource)); +} + +static gboolean +create_surface_extension (MetaWaylandSurfaceExtension *extension, + struct wl_client *client, + struct wl_resource *master_resource, + struct wl_resource *surface_resource, + guint32 id, + int max_version, + const struct wl_interface *interface, + const void *implementation) +{ + struct wl_resource *resource; + + if (extension->resource != NULL) + return FALSE; + + resource = wl_resource_create (client, interface, get_resource_version (master_resource, max_version), id); + wl_resource_set_implementation (resource, implementation, extension, destroy_surface_extension); + + extension->resource = resource; + extension->surface_destroy_listener.notify = extension_handle_surface_destroy; + wl_resource_add_destroy_listener (surface_resource, &extension->surface_destroy_listener); + return TRUE; +} + static void xdg_surface_destroy (struct wl_client *client, struct wl_resource *resource) @@ -526,14 +574,13 @@ xdg_surface_set_transient_for (struct wl_client *client, struct wl_resource *resource, struct wl_resource *parent) { - MetaWaylandSurfaceExtension *surface_ext = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = surface_ext->surface; + MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface); + MetaWaylandSurfaceExtension *parent_xdg_surface = wl_resource_get_user_data (parent); + MetaWaylandSurface *parent_surface = wl_container_of (parent_xdg_surface, surface, xdg_surface); - MetaWaylandSurfaceExtension *parent_ext = wl_resource_get_user_data (parent); - MetaWaylandSurface *parent_surf = parent_ext->surface; - - if (surface->window && parent_surf->window) - meta_window_set_transient_for (surface->window, parent_surf->window); + if (surface->window && parent_surface->window) + meta_window_set_transient_for (surface->window, parent_surface->window); } static void @@ -541,8 +588,8 @@ xdg_surface_set_title (struct wl_client *client, struct wl_resource *resource, const char *title) { - MetaWaylandSurfaceExtension *extension = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = extension->surface; + MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface); g_clear_pointer (&surface->pending.title, g_free); surface->pending.title = g_strdup (title); @@ -553,8 +600,8 @@ xdg_surface_set_app_id (struct wl_client *client, struct wl_resource *resource, const char *app_id) { - MetaWaylandSurfaceExtension *extension = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = extension->surface; + MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface); g_clear_pointer (&surface->pending.app_id, g_free); surface->pending.app_id = g_strdup (app_id); @@ -601,13 +648,14 @@ xdg_surface_move (struct wl_client *client, { MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface); if (seat->pointer.button_count == 0 || seat->pointer.grab_serial != serial || - seat->pointer.focus != xdg_surface->surface) + seat->pointer.focus != surface) return; - begin_grab_op_on_surface (xdg_surface->surface, seat, META_GRAB_OP_MOVING); + begin_grab_op_on_surface (surface, seat, META_GRAB_OP_MOVING); } static MetaGrabOp @@ -646,13 +694,14 @@ xdg_surface_resize (struct wl_client *client, { MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface); if (seat->pointer.button_count == 0 || seat->pointer.grab_serial != serial || - seat->pointer.focus != xdg_surface->surface) + seat->pointer.focus != surface) return; - begin_grab_op_on_surface (xdg_surface->surface, seat, grab_op_for_edge (edges)); + begin_grab_op_on_surface (surface, seat, grab_op_for_edge (edges)); } static void @@ -668,7 +717,7 @@ xdg_surface_set_fullscreen (struct wl_client *client, struct wl_resource *resource) { MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = xdg_surface->surface; + MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface); if (surface->window) meta_window_make_fullscreen (surface->window); @@ -679,7 +728,7 @@ xdg_surface_unset_fullscreen (struct wl_client *client, struct wl_resource *resource) { MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = xdg_surface->surface; + MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface); if (surface->window) meta_window_unmake_fullscreen (surface->window); @@ -690,7 +739,7 @@ xdg_surface_set_maximized (struct wl_client *client, struct wl_resource *resource) { MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = xdg_surface->surface; + MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface); if (surface->window) meta_window_maximize (surface->window, META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL); @@ -701,7 +750,7 @@ xdg_surface_unset_maximized (struct wl_client *client, struct wl_resource *resource) { MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = xdg_surface->surface; + MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface); if (surface->window) meta_window_unmaximize (surface->window, META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL); @@ -712,7 +761,7 @@ xdg_surface_set_minimized (struct wl_client *client, struct wl_resource *resource) { MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = xdg_surface->surface; + MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface); if (surface->window) meta_window_minimize (surface->window); @@ -734,55 +783,6 @@ static const struct xdg_surface_interface meta_wayland_xdg_surface_interface = { xdg_surface_set_minimized, }; -static void -extension_handle_surface_destroy (struct wl_listener *listener, - void *data) -{ - MetaWaylandSurfaceExtension *extension = - wl_container_of (listener, extension, surface_destroy_listener); - - extension->surface = NULL; - wl_resource_destroy (extension->resource); -} - -static void -destroy_surface_extension (struct wl_resource *resource) -{ - MetaWaylandSurfaceExtension *extension = wl_resource_get_user_data (resource); - - /* In case cleaning up a dead client destroys extension first */ - if (extension->surface) - wl_list_remove (&extension->surface_destroy_listener.link); - - g_free (extension); -} - -static MetaWaylandSurfaceExtension * -create_surface_extension (struct wl_client *client, - struct wl_resource *master_resource, - guint32 id, - int max_version, - MetaWaylandSurface *surface, - const struct wl_interface *interface, - const void *implementation) -{ - MetaWaylandSurfaceExtension *extension; - - extension = g_new0 (MetaWaylandSurfaceExtension, 1); - - extension->resource = wl_resource_create (client, interface, - MIN (max_version, wl_resource_get_version (master_resource)), id); - wl_resource_set_implementation (extension->resource, implementation, - extension, destroy_surface_extension); - - extension->surface = surface; - extension->surface_destroy_listener.notify = extension_handle_surface_destroy; - wl_resource_add_destroy_listener (surface->resource, - &extension->surface_destroy_listener); - - return extension; -} - static void use_unstable_version (struct wl_client *client, struct wl_resource *resource, @@ -800,18 +800,13 @@ get_xdg_surface (struct wl_client *client, { MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); - if (surface->xdg_surface) - { - wl_resource_post_error (surface_resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "xdg_shell::get_xdg_surface already requested"); - return; - } - - surface->xdg_surface = create_surface_extension (client, resource, id, - META_XDG_SURFACE_VERSION, surface, - &xdg_surface_interface, - &meta_wayland_xdg_surface_interface); + if (!create_surface_extension (&surface->xdg_surface, client, surface_resource, resource, id, + META_XDG_SURFACE_VERSION, + &xdg_surface_interface, + &meta_wayland_xdg_surface_interface)) + wl_resource_post_error (surface_resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "xdg_shell::get_xdg_surface already requested"); } static void @@ -858,16 +853,8 @@ set_dbus_properties (struct wl_client *client, const char *application_object_path, const char *unique_bus_name) { - MetaWaylandSurfaceExtension *extension = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = extension->surface; - - if (surface == NULL) - { - wl_resource_post_error (resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "object is not associated with a toplevel surface"); - return; - } + MetaWaylandSurfaceExtension *gtk_surface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = wl_container_of (gtk_surface, surface, gtk_surface); g_clear_pointer (&surface->pending.gtk_application_id, g_free); surface->pending.gtk_application_id = g_strdup (application_id); @@ -895,18 +882,13 @@ get_gtk_surface (struct wl_client *client, { MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); - if (surface->gtk_surface) - { - wl_resource_post_error (surface_resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "gtk_shell::get_gtk_surface already requested"); - return; - } - - surface->gtk_surface = create_surface_extension (client, resource, id, - META_GTK_SURFACE_VERSION, surface, - >k_surface_interface, - &meta_wayland_gtk_surface_interface); + if (!create_surface_extension (&surface->gtk_surface, client, surface_resource, resource, id, + META_GTK_SURFACE_VERSION, + >k_surface_interface, + &meta_wayland_gtk_surface_interface)) + wl_resource_post_error (surface_resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "gtk_shell::get_gtk_surface already requested"); } static const struct gtk_shell_interface meta_wayland_gtk_shell_interface = { @@ -951,8 +933,8 @@ meta_wayland_surface_configure_notify (MetaWaylandSurface *surface, int new_height, int edges) { - if (surface->xdg_surface) - xdg_surface_send_configure (surface->xdg_surface->resource, + if (surface->xdg_surface.resource) + xdg_surface_send_configure (surface->xdg_surface.resource, edges, new_width, new_height, 0, 0 /* XXX: support this */); } @@ -960,13 +942,13 @@ meta_wayland_surface_configure_notify (MetaWaylandSurface *surface, void meta_wayland_surface_focused_set (MetaWaylandSurface *surface) { - if (surface->xdg_surface) - xdg_surface_send_focused_set (surface->xdg_surface->resource); + if (surface->xdg_surface.resource) + xdg_surface_send_focused_set (surface->xdg_surface.resource); } void meta_wayland_surface_focused_unset (MetaWaylandSurface *surface) { - if (surface->xdg_surface) - xdg_surface_send_focused_unset (surface->xdg_surface->resource); + if (surface->xdg_surface.resource) + xdg_surface_send_focused_unset (surface->xdg_surface.resource); } diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h index a2fd75e77..e29aa0cb8 100644 --- a/src/wayland/meta-wayland-surface.h +++ b/src/wayland/meta-wayland-surface.h @@ -80,7 +80,6 @@ typedef struct typedef struct { - MetaWaylandSurface *surface; struct wl_resource *resource; struct wl_listener surface_destroy_listener; } MetaWaylandSurfaceExtension; @@ -91,8 +90,8 @@ struct _MetaWaylandSurface MetaWaylandCompositor *compositor; MetaWaylandBufferReference buffer_ref; MetaWindow *window; - MetaWaylandSurfaceExtension *xdg_surface; - MetaWaylandSurfaceExtension *gtk_surface; + MetaWaylandSurfaceExtension xdg_surface; + MetaWaylandSurfaceExtension gtk_surface; /* All the pending state, that wl_surface.commit will apply. */ MetaWaylandDoubleBufferedState pending; From be744775c15a9a0c51ba87f8016e178a18962be2 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 19 Nov 2013 17:39:51 -0500 Subject: [PATCH 262/889] wayland-surface: Support xdg_surface.destroy Cool. --- src/wayland/meta-wayland-surface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 75a5d1b0d..c7c2eb797 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -566,7 +566,7 @@ static void xdg_surface_destroy (struct wl_client *client, struct wl_resource *resource) { - g_warning ("TODO: support xdg_surface.destroy"); + destroy_surface_extension (resource); } static void From 153d8efcf5827c3d444088801cb5de7a5c241d4b Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 19 Nov 2013 17:33:57 -0500 Subject: [PATCH 263/889] window: Create a backing MetaWindow for unmapped Wayland surfaces We require a MetaWindow to properly implement some of the requests for xdg_surface, so add a way to have an unmapped MetaWindow that we can store properties on, that we later map when the client attaches a buffer... --- src/core/window-private.h | 9 +++++- src/core/window.c | 18 ++++++++++++ src/wayland/meta-wayland-surface.c | 47 +++++++----------------------- 3 files changed, 36 insertions(+), 38 deletions(-) diff --git a/src/core/window-private.h b/src/core/window-private.h index 82d68fd18..49dbfc7c3 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -102,7 +102,7 @@ struct _MetaWindow MetaWindowType type; Atom type_atom; - + /* NOTE these five are not in UTF-8, we just treat them as random * binary data */ @@ -351,6 +351,10 @@ struct _MetaWindow /* whether or not the window is from a program running on another machine */ guint is_remote : 1; + /* Used for Wayland -- surfaces can behave as if they were unmapped if + * they have a NULL buffer attached... */ + guint surface_mapped; + /* if non-NULL, the bounds of the window frame */ cairo_region_t *frame_bounds; @@ -740,4 +744,7 @@ void meta_window_handle_enter (MetaWindow *window, guint root_x, guint root_y); +void meta_window_set_surface_mapped (MetaWindow *window, + gboolean surface_mapped); + #endif diff --git a/src/core/window.c b/src/core/window.c index 6d0c295a3..f8823b68b 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -827,6 +827,7 @@ meta_window_new_shared (MetaDisplay *display, MetaWindowClientType client_type, MetaWaylandSurface *surface, Window xwindow, + gboolean surface_mapped, gulong existing_wm_state, MetaCompEffect effect, XWindowAttributes *attrs) @@ -856,6 +857,7 @@ meta_window_new_shared (MetaDisplay *display, window->client_type = client_type; window->surface = surface; window->xwindow = xwindow; + window->surface_mapped = surface_mapped; /* this is in window->screen->display, but that's too annoying to * type @@ -1417,6 +1419,7 @@ meta_window_new_for_wayland (MetaDisplay *display, META_WINDOW_CLIENT_TYPE_WAYLAND, surface, None, + FALSE, WithdrawnState, META_COMP_EFFECT_NONE, &attrs); @@ -1596,6 +1599,7 @@ meta_window_new_with_attrs (MetaDisplay *display, META_WINDOW_CLIENT_TYPE_X11, NULL, xwindow, + TRUE, existing_wm_state, effect, attrs); @@ -2347,6 +2351,9 @@ meta_window_should_be_showing (MetaWindow *window) { gboolean on_workspace; + if (!window->surface_mapped) + return FALSE; + meta_verbose ("Should be showing for window %s\n", window->desc); /* See if we're on the workspace */ @@ -11942,3 +11949,14 @@ meta_window_handle_enter (MetaWindow *window, break; } } + +void +meta_window_set_surface_mapped (MetaWindow *window, + gboolean surface_mapped) +{ + if (window->surface_mapped == (guint) surface_mapped) + return; + + window->surface_mapped = surface_mapped; + meta_window_queue (window, META_QUEUE_CALC_SHOWING); +} diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index c7c2eb797..af951795b 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -236,26 +236,6 @@ empty_region (cairo_region_t *region) cairo_region_intersect_rectangle (region, &rectangle); } -static gboolean -surface_wants_window (MetaWaylandSurface *surface) -{ - return (surface->xdg_surface.resource != NULL); -} - -static void -surface_ensure_window (MetaWaylandSurface *surface) -{ - MetaDisplay *display = meta_get_display (); - - if (surface->window) - return; - - if (!surface_wants_window (surface)) - return; - - surface->window = meta_window_new_for_wayland (display, surface); -} - static void ensure_buffer_texture (MetaWaylandBuffer *buffer) { @@ -307,14 +287,14 @@ meta_wayland_surface_commit (struct wl_client *client, } } - surface_ensure_window (surface); - if (surface == compositor->seat->sprite) meta_wayland_seat_update_sprite (compositor->seat); else if (surface->window) { MetaWindow *window = surface->window; + meta_window_set_surface_mapped (window, surface->pending.buffer != NULL); + if (surface->pending.buffer) { MetaWaylandBuffer *buffer = surface->pending.buffer; @@ -579,8 +559,7 @@ xdg_surface_set_transient_for (struct wl_client *client, MetaWaylandSurfaceExtension *parent_xdg_surface = wl_resource_get_user_data (parent); MetaWaylandSurface *parent_surface = wl_container_of (parent_xdg_surface, surface, xdg_surface); - if (surface->window && parent_surface->window) - meta_window_set_transient_for (surface->window, parent_surface->window); + meta_window_set_transient_for (surface->window, parent_surface->window); } static void @@ -621,9 +600,6 @@ begin_grab_op_on_surface (MetaWaylandSurface *surface, { MetaWindow *window = surface->window; - if (!window) - return FALSE; - if (grab_op == META_GRAB_OP_NONE) return FALSE; @@ -719,8 +695,7 @@ xdg_surface_set_fullscreen (struct wl_client *client, MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface); - if (surface->window) - meta_window_make_fullscreen (surface->window); + meta_window_make_fullscreen (surface->window); } static void @@ -730,8 +705,7 @@ xdg_surface_unset_fullscreen (struct wl_client *client, MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface); - if (surface->window) - meta_window_unmake_fullscreen (surface->window); + meta_window_unmake_fullscreen (surface->window); } static void @@ -741,8 +715,7 @@ xdg_surface_set_maximized (struct wl_client *client, MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface); - if (surface->window) - meta_window_maximize (surface->window, META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL); + meta_window_maximize (surface->window, META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL); } static void @@ -752,8 +725,7 @@ xdg_surface_unset_maximized (struct wl_client *client, MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface); - if (surface->window) - meta_window_unmaximize (surface->window, META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL); + meta_window_unmaximize (surface->window, META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL); } static void @@ -763,8 +735,7 @@ xdg_surface_set_minimized (struct wl_client *client, MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface); - if (surface->window) - meta_window_minimize (surface->window); + meta_window_minimize (surface->window); } static const struct xdg_surface_interface meta_wayland_xdg_surface_interface = { @@ -807,6 +778,8 @@ get_xdg_surface (struct wl_client *client, wl_resource_post_error (surface_resource, WL_DISPLAY_ERROR_INVALID_OBJECT, "xdg_shell::get_xdg_surface already requested"); + + surface->window = meta_window_new_for_wayland (meta_get_display (), surface); } static void From 0cc5cf940b8f4759281ccceafda4896100734ecb Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 19 Nov 2013 16:04:14 -0500 Subject: [PATCH 264/889] wayland-surface: Remove some properties from the double-buffered state Now that we can always set them on the MetaWindow... --- src/wayland/meta-wayland-surface.c | 46 ++++++------------------------ src/wayland/meta-wayland-surface.h | 12 -------- 2 files changed, 9 insertions(+), 49 deletions(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index af951795b..83560511e 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -322,27 +322,6 @@ meta_wayland_surface_commit (struct wl_client *client, meta_window_set_opaque_region (surface->window, surface->pending.opaque_region); meta_window_set_input_region (surface->window, surface->pending.input_region); surface_process_damage (surface, surface->pending.damage); - - meta_window_set_title (surface->window, surface->pending.title); - g_clear_pointer (&surface->pending.title, g_free); - - meta_window_set_wm_class (surface->window, surface->pending.app_id, surface->pending.app_id); - g_clear_pointer (&surface->pending.app_id, g_free); - - meta_window_set_gtk_dbus_properties (surface->window, - surface->pending.gtk_application_id, - surface->pending.gtk_unique_bus_name, - surface->pending.gtk_app_menu_path, - surface->pending.gtk_menubar_path, - surface->pending.gtk_application_object_path, - surface->pending.gtk_window_object_path); - - g_clear_pointer (&surface->pending.gtk_application_id, g_free); - g_clear_pointer (&surface->pending.gtk_unique_bus_name, g_free); - g_clear_pointer (&surface->pending.gtk_app_menu_path, g_free); - g_clear_pointer (&surface->pending.gtk_menubar_path, g_free); - g_clear_pointer (&surface->pending.gtk_application_object_path, g_free); - g_clear_pointer (&surface->pending.gtk_window_object_path, g_free); } if (surface->pending.buffer) @@ -570,8 +549,7 @@ xdg_surface_set_title (struct wl_client *client, MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface); - g_clear_pointer (&surface->pending.title, g_free); - surface->pending.title = g_strdup (title); + meta_window_set_title (surface->window, title); } static void @@ -582,8 +560,7 @@ xdg_surface_set_app_id (struct wl_client *client, MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface); - g_clear_pointer (&surface->pending.app_id, g_free); - surface->pending.app_id = g_strdup (app_id); + meta_window_set_wm_class (surface->window, app_id, app_id); } static void @@ -829,18 +806,13 @@ set_dbus_properties (struct wl_client *client, MetaWaylandSurfaceExtension *gtk_surface = wl_resource_get_user_data (resource); MetaWaylandSurface *surface = wl_container_of (gtk_surface, surface, gtk_surface); - g_clear_pointer (&surface->pending.gtk_application_id, g_free); - surface->pending.gtk_application_id = g_strdup (application_id); - g_clear_pointer (&surface->pending.gtk_unique_bus_name, g_free); - surface->pending.gtk_unique_bus_name = g_strdup (unique_bus_name); - g_clear_pointer (&surface->pending.gtk_app_menu_path, g_free); - surface->pending.gtk_app_menu_path = g_strdup (app_menu_path); - g_clear_pointer (&surface->pending.gtk_menubar_path, g_free); - surface->pending.gtk_menubar_path = g_strdup (menubar_path); - g_clear_pointer (&surface->pending.gtk_application_object_path, g_free); - surface->pending.gtk_application_object_path = g_strdup (application_object_path); - g_clear_pointer (&surface->pending.gtk_window_object_path, g_free); - surface->pending.gtk_window_object_path = g_strdup (window_object_path); + meta_window_set_gtk_dbus_properties (surface->window, + application_id, + unique_bus_name, + app_menu_path, + menubar_path, + application_object_path, + window_object_path); } static const struct gtk_surface_interface meta_wayland_gtk_surface_interface = { diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h index e29aa0cb8..62d2fdeb3 100644 --- a/src/wayland/meta-wayland-surface.h +++ b/src/wayland/meta-wayland-surface.h @@ -64,18 +64,6 @@ typedef struct /* wl_surface.frame */ struct wl_list frame_callback_list; - - /* xdg_surface */ - char *title; - char *app_id; - - /* gtk_surface */ - char *gtk_application_id; - char *gtk_unique_bus_name; - char *gtk_app_menu_path; - char *gtk_menubar_path; - char *gtk_application_object_path; - char *gtk_window_object_path; } MetaWaylandDoubleBufferedState; typedef struct From bbe36418447f8d69d5beb8b1b9c5c9bf0f1f709a Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 14 Nov 2013 21:55:37 -0500 Subject: [PATCH 265/889] wayland-surface: Add support for xdg_popup --- src/wayland/meta-wayland-pointer.c | 8 ++--- src/wayland/meta-wayland-surface.c | 54 ++++++++++++++++++++++++++--- src/wayland/meta-wayland-surface.h | 1 + src/wayland/meta-wayland-versions.h | 1 + 4 files changed, 56 insertions(+), 8 deletions(-) diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index 3540f747c..37748f129 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -538,14 +538,14 @@ meta_wayland_pointer_end_popup_grab (MetaWaylandPointer *pointer) wl_list_for_each_safe (popup, tmp, &popup_grab->all_popups, link) { - MetaWaylandSurfaceExtension *shell_surface = &popup->surface->xdg_surface; - struct wl_client *client = wl_resource_get_client (shell_surface->resource); + MetaWaylandSurfaceExtension *xdg_popup = &popup->surface->xdg_popup; + struct wl_client *client = wl_resource_get_client (xdg_popup->resource); struct wl_display *display = wl_client_get_display (client); uint32_t serial; serial = wl_display_next_serial (display); - xdg_popup_send_popup_done (shell_surface->resource, serial); + xdg_popup_send_popup_done (xdg_popup->resource, serial); wl_list_remove (&popup->surface_destroy_listener.link); wl_list_remove (&popup->link); g_slice_free (MetaWaylandPopup, popup); @@ -607,7 +607,7 @@ meta_wayland_pointer_start_popup_grab (MetaWaylandPointer *pointer, popup->grab = grab; popup->surface = surface; popup->surface_destroy_listener.notify = on_popup_surface_destroy; - wl_resource_add_destroy_listener (surface->resource, &popup->surface_destroy_listener); + wl_resource_add_destroy_listener (surface->xdg_popup.resource, &popup->surface_destroy_listener); wl_list_insert (&grab->all_popups, &popup->link); diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 83560511e..0f318e273 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -329,6 +329,7 @@ meta_wayland_surface_commit (struct wl_client *client, wl_list_remove (&surface->pending.buffer_destroy_listener.link); surface->pending.buffer = NULL; } + surface->pending.dx = 0; surface->pending.dy = 0; surface->pending.newly_attached = FALSE; @@ -759,19 +760,64 @@ get_xdg_surface (struct wl_client *client, surface->window = meta_window_new_for_wayland (meta_get_display (), surface); } +static void +xdg_popup_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + destroy_surface_extension (resource); +} + +static void +xdg_popup_pong (struct wl_client *client, + struct wl_resource *resource, + uint32_t serial) +{ +} + +static const struct xdg_popup_interface meta_wayland_xdg_popup_interface = { + xdg_popup_destroy, + xdg_popup_pong, +}; + static void get_xdg_popup (struct wl_client *client, struct wl_resource *resource, uint32_t id, - struct wl_resource *surface, - struct wl_resource *parent, - struct wl_resource *seat, + struct wl_resource *surface_resource, + struct wl_resource *parent_resource, + struct wl_resource *seat_resource, uint32_t serial, int32_t x, int32_t y, uint32_t flags) { - g_warning ("TODO: support xdg_shell.get_xdg_popup"); + MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); + MetaWaylandSurface *parent_surf = wl_resource_get_user_data (parent_resource); + MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); + MetaRectangle parent_rect; + + if (parent_surf == NULL || parent_surf->window == NULL) + return; + + meta_window_get_frame_rect (parent_surf->window, &parent_rect); + + if (!create_surface_extension (&surface->xdg_popup, client, surface_resource, resource, id, + META_XDG_POPUP_VERSION, + &xdg_popup_interface, + &meta_wayland_xdg_popup_interface)) + wl_resource_post_error (surface_resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "xdg_shell::get_xdg_surface already requested"); + + surface->window = meta_window_new_for_wayland (meta_get_display (), surface); + surface->window->type = META_WINDOW_DROPDOWN_MENU; + surface->window->override_redirect = TRUE; + surface->window->showing_for_first_time = FALSE; + surface->window->rect.x = parent_rect.x + x; + surface->window->rect.y = parent_rect.y + y; + surface->window->placed = TRUE; + + meta_wayland_pointer_start_popup_grab (&seat->pointer, surface); } static const struct xdg_shell_interface meta_wayland_xdg_shell_interface = { diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h index 62d2fdeb3..3d043cd12 100644 --- a/src/wayland/meta-wayland-surface.h +++ b/src/wayland/meta-wayland-surface.h @@ -79,6 +79,7 @@ struct _MetaWaylandSurface MetaWaylandBufferReference buffer_ref; MetaWindow *window; MetaWaylandSurfaceExtension xdg_surface; + MetaWaylandSurfaceExtension xdg_popup; MetaWaylandSurfaceExtension gtk_surface; /* All the pending state, that wl_surface.commit will apply. */ diff --git a/src/wayland/meta-wayland-versions.h b/src/wayland/meta-wayland-versions.h index 37aa4e3ca..7e85f8b29 100644 --- a/src/wayland/meta-wayland-versions.h +++ b/src/wayland/meta-wayland-versions.h @@ -54,6 +54,7 @@ #define META_WL_REGION_VERSION 1 /* from wl_compositor */ #define META_GTK_SURFACE_VERSION 1 /* from gtk_shell */ #define META_XDG_SURFACE_VERSION 1 /* from xdg_shell */ +#define META_XDG_POPUP_VERSION 1 /* from xdg_shell */ /* The first version to implement a specific event */ #define META_WL_SEAT_HAS_NAME 2 From 594b15abf17625caebf1df3f275992c02b866b57 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 19 Nov 2013 18:48:18 -0500 Subject: [PATCH 266/889] pointer: Fix crash when we have the pointer over nothing during a popup grab --- src/wayland/meta-wayland-pointer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index 37748f129..04b464bf1 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -488,7 +488,7 @@ popup_grab_focus (MetaWaylandPointerGrab *grab, /* Popup grabs are in owner-events mode (ie, events for the same client are reported as normal) */ - if (wl_resource_get_client (surface->resource) == popup_grab->grab_client) + if (surface && wl_resource_get_client (surface->resource) == popup_grab->grab_client) default_grab_focus (grab, surface, event); else meta_wayland_pointer_set_focus (grab->pointer, NULL); From 71496c8909f071c3624593a4919a892e9d420003 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 19 Nov 2013 19:00:06 -0500 Subject: [PATCH 267/889] Update xdg-shell.xml --- protocol/xdg-shell.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocol/xdg-shell.xml b/protocol/xdg-shell.xml index fbd4f6da4..6765f9841 100644 --- a/protocol/xdg-shell.xml +++ b/protocol/xdg-shell.xml @@ -1,5 +1,5 @@ - + Copyright © 2008-2013 Kristian Høgsberg From 02144d17e9282719d31bbbb84678c889a002396a Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 19 Nov 2013 19:01:03 -0500 Subject: [PATCH 268/889] wayland-surface: Fill in the maximized/fullscreen hints to the configure event --- src/wayland/meta-wayland-surface.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 0f318e273..317f4fb75 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -927,7 +927,8 @@ meta_wayland_surface_configure_notify (MetaWaylandSurface *surface, if (surface->xdg_surface.resource) xdg_surface_send_configure (surface->xdg_surface.resource, edges, new_width, new_height, - 0, 0 /* XXX: support this */); + meta_window_get_maximized (surface->window), + meta_window_is_fullscreen (surface->window)); } void From 2ebecc5370eb61668feff2fd8742891ca40f30fc Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 19 Nov 2013 19:27:04 -0500 Subject: [PATCH 269/889] wayland-surface: Allow extension resources to be double-destroyed As they will be on shutdown... I'm not sure if this is a wayland-server bug or not, but we should guard against it anyway. --- src/wayland/meta-wayland-surface.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 317f4fb75..ebcd9642e 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -478,6 +478,10 @@ static void destroy_surface_extension (struct wl_resource *resource) { MetaWaylandSurfaceExtension *extension = wl_resource_get_user_data (resource); + + if (extension->resource == NULL) + return; + wl_list_remove (&extension->surface_destroy_listener.link); extension->surface_destroy_listener.notify = NULL; extension->resource = NULL; From 1b5ace8256266acdfbac20bbbb18da6f6ec75900 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 19 Nov 2013 19:33:13 -0500 Subject: [PATCH 270/889] window-actor: Don't set ourselves as reactive twice --- src/compositor/meta-window-actor.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index d68bb0ab9..8931b5d0b 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -410,7 +410,6 @@ meta_window_actor_constructed (GObject *object) priv->surface = meta_surface_actor_new (); clutter_actor_add_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface)); - clutter_actor_set_reactive (CLUTTER_ACTOR (self), TRUE); priv->surface_allocation_changed_id = g_signal_connect (CLUTTER_ACTOR (priv->surface), From 2952d3671d75240d2facd5d3d96a10b8213fb615 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 19 Nov 2013 19:34:04 -0500 Subject: [PATCH 271/889] window-actor: Set as unreactive when hiding This means that we should never pick the actor when it's being destroyed. --- src/compositor/meta-window-actor.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 8931b5d0b..4bab98fd9 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -1602,6 +1602,7 @@ meta_window_actor_hide (MetaWindowActor *self, g_return_if_fail (priv->visible); priv->visible = FALSE; + clutter_actor_set_reactive (CLUTTER_ACTOR (self), FALSE); /* If a plugin is animating a workspace transition, we have to * hold off on hiding the window, and do it after the workspace From 2930612e64b7f3d9ee441d5e1e2c0beb922d6493 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 19 Nov 2013 19:35:29 -0500 Subject: [PATCH 272/889] pointer: Remove dead and incorrect code Now that we can never pick a destroying actor, we can remove these bad asserts. --- src/wayland/meta-wayland-pointer.c | 18 ------------------ src/wayland/meta-wayland-pointer.h | 2 -- src/wayland/meta-wayland-surface.c | 8 -------- 3 files changed, 28 deletions(-) diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index 04b464bf1..9fb19bfc6 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -446,24 +446,6 @@ meta_wayland_pointer_end_modal (MetaWaylandPointer *pointer) g_slice_free (MetaWaylandPointerGrab, grab); } -/* Called when the focused resource is destroyed */ -void -meta_wayland_pointer_destroy_focus (MetaWaylandPointer *pointer) -{ - if (pointer->grab == &pointer->default_grab) - { - /* The surface was destroyed, but had the implicit pointer grab. - Bypass the grab interface. */ - g_assert (pointer->button_count > 0); - - /* Note: we focus the NULL interface, not the current one, because - we have button down, and the clients would be confused if the - pointer enters the surface. - */ - meta_wayland_pointer_set_focus (pointer, NULL); - } -} - typedef struct { MetaWaylandPointerGrab generic; diff --git a/src/wayland/meta-wayland-pointer.h b/src/wayland/meta-wayland-pointer.h index bdbf1a383..95a4b5e13 100644 --- a/src/wayland/meta-wayland-pointer.h +++ b/src/wayland/meta-wayland-pointer.h @@ -76,8 +76,6 @@ meta_wayland_pointer_release (MetaWaylandPointer *pointer); void meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer, MetaWaylandSurface *surface); -void -meta_wayland_pointer_destroy_focus (MetaWaylandPointer *pointer); void meta_wayland_pointer_start_grab (MetaWaylandPointer *pointer, diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index ebcd9642e..78f54a2b4 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -393,14 +393,6 @@ meta_wayland_surface_free (MetaWaylandSurface *surface) meta_wayland_compositor_repick (compositor); - g_assert (surface != compositor->seat->keyboard.focus); - if (surface == compositor->seat->pointer.focus) - { - meta_wayland_pointer_destroy_focus (&compositor->seat->pointer); - - g_assert (surface != compositor->seat->pointer.focus); - } - if (surface->resource) wl_resource_set_user_data (surface->resource, NULL); g_slice_free (MetaWaylandSurface, surface); From 2f14b5cc3f065a7c03c1238f5d09d69e60827b55 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 19 Nov 2013 20:04:49 -0500 Subject: [PATCH 273/889] wayland: Set a log handler To see error messages and such --- src/wayland/meta-wayland.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index dabdc1ed3..061aa0e60 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -616,6 +616,15 @@ set_gnome_env (const char *name, } } +static void +meta_wayland_log_func (const char *fmt, + va_list arg) +{ + char *str = g_strdup_vprintf (fmt, arg); + g_warning ("WL: %s", str); + g_free (str); +} + void meta_wayland_init (void) { @@ -633,6 +642,7 @@ meta_wayland_init (void) g_error ("failed to create wayland display"); wl_display_init_shm (compositor->wayland_display); + wl_log_set_handler_server(meta_wayland_log_func); wl_list_init (&compositor->frame_callbacks); From a8ac2cc27543ef4afe762e8a0675cceef7afdf91 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 19 Nov 2013 20:16:28 -0500 Subject: [PATCH 274/889] pointer: Remove focus listener It's added too late to matter -- by the time we've destroyed the resource, we've already repicked and re-set the focus. --- src/wayland/meta-wayland-pointer.c | 17 ----------------- src/wayland/meta-wayland-pointer.h | 1 - 2 files changed, 18 deletions(-) diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index 9fb19bfc6..beb85c83d 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -63,16 +63,6 @@ meta_wayland_pointer_get_seat (MetaWaylandPointer *pointer) return seat; } -static void -lose_pointer_focus (struct wl_listener *listener, void *data) -{ - MetaWaylandPointer *pointer = - wl_container_of (listener, pointer, focus_listener); - - pointer->focus_resource = NULL; - pointer->focus = NULL; -} - static void default_grab_focus (MetaWaylandPointerGrab *grab, MetaWaylandSurface *surface, @@ -267,7 +257,6 @@ meta_wayland_pointer_init (MetaWaylandPointer *pointer, memset (pointer, 0, sizeof *pointer); wl_list_init (&pointer->resource_list); - pointer->focus_listener.notify = lose_pointer_focus; pointer->default_grab.interface = &default_pointer_grab_interface; pointer->default_grab.pointer = pointer; pointer->grab = &pointer->default_grab; @@ -287,10 +276,6 @@ meta_wayland_pointer_init (MetaWaylandPointer *pointer, void meta_wayland_pointer_release (MetaWaylandPointer *pointer) { - /* XXX: What about pointer->resource_list? */ - if (pointer->focus_resource) - wl_list_remove (&pointer->focus_listener.link); - pointer->focus = NULL; pointer->focus_resource = NULL; } @@ -325,7 +310,6 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer, struct wl_display *display = wl_client_get_display (client); serial = wl_display_next_serial (display); wl_pointer_send_leave (resource, serial, pointer->focus->resource); - wl_list_remove (&pointer->focus_listener.link); } resource = find_resource_for_surface (&pointer->resource_list, surface); @@ -359,7 +343,6 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer, wl_fixed_to_int (pointer->x), wl_fixed_to_int (pointer->y)); wl_pointer_send_enter (resource, serial, surface->resource, sx, sy); - wl_resource_add_destroy_listener (resource, &pointer->focus_listener); pointer->focus_serial = serial; } diff --git a/src/wayland/meta-wayland-pointer.h b/src/wayland/meta-wayland-pointer.h index 95a4b5e13..a31d609c4 100644 --- a/src/wayland/meta-wayland-pointer.h +++ b/src/wayland/meta-wayland-pointer.h @@ -48,7 +48,6 @@ struct _MetaWaylandPointer struct wl_list resource_list; MetaWaylandSurface *focus; struct wl_resource *focus_resource; - struct wl_listener focus_listener; guint32 focus_serial; guint32 click_serial; From abd368be0066e7e0d3162a7a781bb1b6099323ec Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 19 Nov 2013 20:20:13 -0500 Subject: [PATCH 275/889] pointer: Don't send leave events to dying surfaces It's invalid and will crash the client. --- src/wayland/meta-wayland-pointer.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index beb85c83d..9a5680e74 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -303,8 +303,11 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer, struct wl_resource *resource, *kr; uint32_t serial; + if (pointer->focus == surface) + return; + resource = pointer->focus_resource; - if (resource && pointer->focus != surface) + if (resource && pointer->focus->resource) { struct wl_client *client = wl_resource_get_client (resource); struct wl_display *display = wl_client_get_display (client); @@ -313,8 +316,7 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer, } resource = find_resource_for_surface (&pointer->resource_list, surface); - if (resource && - (pointer->focus != surface || pointer->focus_resource != resource)) + if (resource) { struct wl_client *client = wl_resource_get_client (resource); struct wl_display *display = wl_client_get_display (client); From 0ac142d39e27e2692cbe0b18136a41bee424a6b0 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 19 Nov 2013 20:24:11 -0500 Subject: [PATCH 276/889] keyboard: Remove focus listener --- src/wayland/meta-wayland-keyboard.c | 16 ---------------- src/wayland/meta-wayland-keyboard.h | 1 - 2 files changed, 17 deletions(-) diff --git a/src/wayland/meta-wayland-keyboard.c b/src/wayland/meta-wayland-keyboard.c index 327189a19..670c7bc46 100644 --- a/src/wayland/meta-wayland-keyboard.c +++ b/src/wayland/meta-wayland-keyboard.c @@ -221,15 +221,6 @@ err_keymap_str: return; } -static void -lose_keyboard_focus (struct wl_listener *listener, void *data) -{ - MetaWaylandKeyboard *keyboard = - wl_container_of (listener, keyboard, focus_listener); - - keyboard->focus_resource = NULL; -} - static gboolean default_grab_key (MetaWaylandKeyboardGrab *grab, uint32_t time, uint32_t key, uint32_t state) @@ -339,7 +330,6 @@ meta_wayland_keyboard_init (MetaWaylandKeyboard *keyboard, wl_list_init (&keyboard->resource_list); wl_array_init (&keyboard->keys); - keyboard->focus_listener.notify = lose_keyboard_focus; keyboard->default_grab.interface = &default_keyboard_grab_interface; keyboard->default_grab.keyboard = keyboard; keyboard->grab = &keyboard->default_grab; @@ -521,7 +511,6 @@ meta_wayland_keyboard_set_focus (MetaWaylandKeyboard *keyboard, display = wl_client_get_display (client); serial = wl_display_next_serial (display); wl_keyboard_send_leave (resource, serial, keyboard->focus->resource); - wl_list_remove (&keyboard->focus_listener.link); meta_wayland_surface_focused_unset (keyboard->focus); } @@ -558,7 +547,6 @@ meta_wayland_keyboard_set_focus (MetaWaylandKeyboard *keyboard, wl_keyboard_send_enter (resource, serial, surface->resource, &keyboard->keys); } - wl_resource_add_destroy_listener (resource, &keyboard->focus_listener); keyboard->focus_serial = serial; meta_wayland_surface_focused_set (surface); @@ -589,10 +577,6 @@ meta_wayland_keyboard_release (MetaWaylandKeyboard *keyboard) { meta_wayland_xkb_info_destroy (&keyboard->xkb_info); xkb_context_unref (keyboard->xkb_context); - - /* XXX: What about keyboard->resource_list? */ - if (keyboard->focus_resource) - wl_list_remove (&keyboard->focus_listener.link); wl_array_release (&keyboard->keys); } diff --git a/src/wayland/meta-wayland-keyboard.h b/src/wayland/meta-wayland-keyboard.h index 4354faf21..f0a793cca 100644 --- a/src/wayland/meta-wayland-keyboard.h +++ b/src/wayland/meta-wayland-keyboard.h @@ -94,7 +94,6 @@ struct _MetaWaylandKeyboard struct wl_list resource_list; MetaWaylandSurface *focus; struct wl_resource *focus_resource; - struct wl_listener focus_listener; uint32_t focus_serial; MetaWaylandKeyboardGrab *grab; From 600a0f836f315f84a999777df645d355fcfaac91 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 19 Nov 2013 20:25:52 -0500 Subject: [PATCH 277/889] keyboard: Don't send leave events to dying surfaces --- src/wayland/meta-wayland-keyboard.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/wayland/meta-wayland-keyboard.c b/src/wayland/meta-wayland-keyboard.c index 670c7bc46..a003ea531 100644 --- a/src/wayland/meta-wayland-keyboard.c +++ b/src/wayland/meta-wayland-keyboard.c @@ -501,14 +501,14 @@ meta_wayland_keyboard_set_focus (MetaWaylandKeyboard *keyboard, struct wl_resource *resource; uint32_t serial; - if (keyboard->focus_resource && keyboard->focus != surface) - { - struct wl_display *display; - struct wl_client *client; + if (keyboard->focus == surface) + return; - resource = keyboard->focus_resource; - client = wl_resource_get_client (resource); - display = wl_client_get_display (client); + resource = keyboard->focus_resource; + if (keyboard->focus_resource && keyboard->focus->resource) + { + struct wl_client *client = wl_resource_get_client (resource); + struct wl_display *display = wl_client_get_display (client); serial = wl_display_next_serial (display); wl_keyboard_send_leave (resource, serial, keyboard->focus->resource); @@ -516,13 +516,11 @@ meta_wayland_keyboard_set_focus (MetaWaylandKeyboard *keyboard, } resource = find_resource_for_surface (&keyboard->resource_list, surface); - if (resource && - (keyboard->focus != surface || keyboard->focus_resource != resource)) + if (resource) { struct wl_client *client = wl_resource_get_client (resource); - struct wl_display *display; + struct wl_display *display = wl_client_get_display (client); - display = wl_client_get_display (client); serial = wl_display_next_serial (display); /* If we're in a modal grab, the client is focused but doesn't see From a8632c2546f2e18a3a7cec49b25b804cc242ea01 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 19 Nov 2013 23:32:50 -0500 Subject: [PATCH 278/889] Revert "wayland-surface: Allow extension resources to be double-destroyed" This reverts commit 2ebecc5370eb61668feff2fd8742891ca40f30fc. --- src/wayland/meta-wayland-surface.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 78f54a2b4..f208da880 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -470,10 +470,6 @@ static void destroy_surface_extension (struct wl_resource *resource) { MetaWaylandSurfaceExtension *extension = wl_resource_get_user_data (resource); - - if (extension->resource == NULL) - return; - wl_list_remove (&extension->surface_destroy_listener.link); extension->surface_destroy_listener.notify = NULL; extension->resource = NULL; From f4fc498e65f12e2b9fe01611f9e51e38eac60682 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 19 Nov 2013 23:33:46 -0500 Subject: [PATCH 279/889] wayland-surface: Properly destroy extension resources on the destroy request Otherwise, the resource IDs will linger around and be destroyed again on client close... --- src/wayland/meta-wayland-surface.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index f208da880..3d4b8f85b 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -518,7 +518,7 @@ static void xdg_surface_destroy (struct wl_client *client, struct wl_resource *resource) { - destroy_surface_extension (resource); + wl_resource_destroy (resource); } static void @@ -756,7 +756,7 @@ static void xdg_popup_destroy (struct wl_client *client, struct wl_resource *resource) { - destroy_surface_extension (resource); + wl_resource_destroy (resource); } static void From 1c0e6f26e2f5fe2561ca09a1edf12bb3458392eb Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 20 Nov 2013 13:12:38 -0500 Subject: [PATCH 280/889] mutter-launch: Don't test the argument name to validate launching things Somebody could do: $ mv my-evil-program mutter-wayland $ PATH=.:$PATH mutter-launch mutter-wayland It's not secure, and it's hard to test with, so just drop it for now We'll be relying on logind to hand us permissions in the future. --- src/wayland/weston-launch.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/wayland/weston-launch.c b/src/wayland/weston-launch.c index d81164835..773eea4bd 100644 --- a/src/wayland/weston-launch.c +++ b/src/wayland/weston-launch.c @@ -738,9 +738,6 @@ main(int argc, char *argv[]) if (optind >= argc) error(1, 0, "Expected program argument"); - if (strcmp (argv[optind], "mutter-wayland") && - strcmp (argv[optind], "gnome-shell-wayland")) - error(1, 0, "mutter-launch can only be used to launch mutter or gnome-shell"); wl.pw = getpwuid(getuid()); if (wl.pw == NULL) From 40b1e7312d1dce8d71bc685622ca4909cb9c18cc Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 21 Nov 2013 13:00:37 -0500 Subject: [PATCH 281/889] Update xdg-shell.xml --- protocol/xdg-shell.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocol/xdg-shell.xml b/protocol/xdg-shell.xml index 6765f9841..e1249b06e 100644 --- a/protocol/xdg-shell.xml +++ b/protocol/xdg-shell.xml @@ -121,7 +121,7 @@ unmapped if the parent is unmapped too. They should not appear on task bars and alt+tab. - + From 6c0e16c482c4904880c3ea9792d8788521460608 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 20 Nov 2013 17:22:40 -0500 Subject: [PATCH 282/889] keybindings: Properly interpret keybindings We need to compare against the keysym, not the keycode. --- src/core/keybindings.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/keybindings.c b/src/core/keybindings.c index 23539a89b..e3289639c 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -1862,7 +1862,7 @@ process_event (MetaKeyBinding *bindings, MetaKeyHandler *handler = bindings[i].handler; if ((!on_window && handler->flags & META_KEY_BINDING_PER_WINDOW) || - bindings[i].keycode != event->keyval || + (event->keyval != bindings[i].keysym) || (event->modifier_state != bindings[i].mask) || meta_compositor_filter_keybinding (display->compositor, screen, &bindings[i])) continue; From ebf6862a10e61b5f0ec84bb03b50e5a3522ca9a8 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 21 Nov 2013 11:51:15 -0500 Subject: [PATCH 283/889] wayland-surface: Don't mark popup windows as override-redirect --- src/wayland/meta-wayland-surface.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 3d4b8f85b..3a2858498 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -803,7 +803,6 @@ get_xdg_popup (struct wl_client *client, surface->window = meta_window_new_for_wayland (meta_get_display (), surface); surface->window->type = META_WINDOW_DROPDOWN_MENU; - surface->window->override_redirect = TRUE; surface->window->showing_for_first_time = FALSE; surface->window->rect.x = parent_rect.x + x; surface->window->rect.y = parent_rect.y + y; From a37a8c64972f392013b6101bcd6205a6ceb6a14f Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 21 Nov 2013 13:09:13 -0500 Subject: [PATCH 284/889] wayland-surface: Fix transient_for It takes a wl_surface resource, not an xdg_shell_surface resource, and the argument is allowed to be NULL. --- src/wayland/meta-wayland-surface.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 3a2858498..71e3512a1 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -524,14 +524,19 @@ xdg_surface_destroy (struct wl_client *client, static void xdg_surface_set_transient_for (struct wl_client *client, struct wl_resource *resource, - struct wl_resource *parent) + struct wl_resource *parent_resource) { MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface); - MetaWaylandSurfaceExtension *parent_xdg_surface = wl_resource_get_user_data (parent); - MetaWaylandSurface *parent_surface = wl_container_of (parent_xdg_surface, surface, xdg_surface); + MetaWindow *transient_for = NULL; - meta_window_set_transient_for (surface->window, parent_surface->window); + if (parent_resource) + { + MetaWaylandSurface *parent_surface = wl_resource_get_user_data (parent_resource); + transient_for = parent_surface->window; + } + + meta_window_set_transient_for (surface->window, transient_for); } static void From 5ea443eb4bb2731ce1f18fa6b3cceb09bdcbef8c Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Thu, 21 Nov 2013 11:56:37 +0100 Subject: [PATCH 285/889] idle-monitor: Fix a GSList leak https://bugzilla.gnome.org/show_bug.cgi?id=712833 --- src/core/meta-idle-monitor.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/core/meta-idle-monitor.c b/src/core/meta-idle-monitor.c index 24e789407..ac38b04c0 100644 --- a/src/core/meta-idle-monitor.c +++ b/src/core/meta-idle-monitor.c @@ -949,6 +949,8 @@ on_bus_acquired (GDBusConnection *connection, for (iter = devices; iter; iter = iter->next) on_device_added (device_manager, iter->data, manager); + g_slist_free (devices); + g_signal_connect_object (device_manager, "device-added", G_CALLBACK (on_device_added), manager, 0); g_signal_connect_object (device_manager, "device-removed", From 8a3501ffe13e91a679bb9f37cb60ddf4c9021a33 Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Thu, 21 Nov 2013 11:57:22 +0100 Subject: [PATCH 286/889] xwayland: Fix a couple of small leaks https://bugzilla.gnome.org/show_bug.cgi?id=712833 --- src/wayland/meta-xwayland.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index 0207c7dc8..cf78a59f7 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -102,7 +102,7 @@ bind_xserver (struct wl_client *client, * and unblock meta_wayland_init() to continue initializing mutter. * */ g_main_loop_quit (compositor->init_loop); - compositor->init_loop = NULL; + g_clear_pointer (&compositor->init_loop, g_main_loop_unref); } static char * @@ -306,6 +306,7 @@ meta_xwayland_start (MetaWaylandCompositor *compositor) char **env; char *fd_string; char *display_name; + char *log_path; char *args[11]; GError *error; @@ -368,6 +369,7 @@ meta_xwayland_start (MetaWaylandCompositor *compositor) display_name = g_strdup_printf (":%d", compositor->xwayland_display_index); + log_path = g_build_filename (g_get_user_cache_dir (), "xwayland.log", NULL); args[0] = XWAYLAND_PATH; args[1] = display_name; @@ -376,7 +378,7 @@ meta_xwayland_start (MetaWaylandCompositor *compositor) args[4] = "-retro"; args[5] = "-noreset"; args[6] = "-logfile"; - args[7] = g_build_filename (g_get_user_cache_dir (), "xwayland.log", NULL); + args[7] = log_path; args[8] = "-nolisten"; args[9] = "all"; args[10] = NULL; @@ -410,6 +412,7 @@ meta_xwayland_start (MetaWaylandCompositor *compositor) g_strfreev (env); g_free (display_name); + g_free (log_path); /* We need to run a mainloop until we know xwayland has a binding * for our xserver interface at which point we can assume it's From aa3643cdde4277a26e5730a0f6335c76a1a22d4f Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 21 Nov 2013 14:01:40 -0500 Subject: [PATCH 287/889] Move window pings to MetaWindow This will make it possible to use on Wayland as well... --- src/core/delete.c | 22 +-- src/core/display-private.h | 16 +- src/core/display.c | 306 ++----------------------------------- src/core/window-private.h | 14 ++ src/core/window.c | 213 ++++++++++++++++++++++++++ 5 files changed, 245 insertions(+), 326 deletions(-) diff --git a/src/core/delete.c b/src/core/delete.c index bd4e96e96..90a35f33b 100644 --- a/src/core/delete.c +++ b/src/core/delete.c @@ -43,14 +43,11 @@ static void meta_window_present_delete_dialog (MetaWindow *window, guint32 timestamp); static void -delete_ping_reply_func (MetaDisplay *display, - Window xwindow, +delete_ping_reply_func (MetaWindow *window, guint32 timestamp, void *user_data) { - meta_topic (META_DEBUG_PING, - "Got reply to delete ping for %s\n", - ((MetaWindow*)user_data)->desc); + meta_topic (META_DEBUG_PING, "Got reply to delete ping for %s\n", window->desc); /* we do nothing */ } @@ -68,12 +65,10 @@ dialog_exited (GPid pid, int status, gpointer user_data) } static void -delete_ping_timeout_func (MetaDisplay *display, - Window xwindow, +delete_ping_timeout_func (MetaWindow *window, guint32 timestamp, void *user_data) { - MetaWindow *window = user_data; char *window_title; gchar *window_content, *tmp; GPid dialog_pid; @@ -137,12 +132,11 @@ void meta_window_check_alive (MetaWindow *window, guint32 timestamp) { - meta_display_ping_window (window->display, - window, - timestamp, - delete_ping_reply_func, - delete_ping_timeout_func, - window); + meta_window_ping (window, + timestamp, + delete_ping_reply_func, + delete_ping_timeout_func, + NULL); } void diff --git a/src/core/display-private.h b/src/core/display-private.h index 79d281b22..169682ee8 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -57,11 +57,6 @@ typedef struct _MetaWindowPropHooks MetaWindowPropHooks; typedef struct MetaEdgeResistanceData MetaEdgeResistanceData; -typedef void (* MetaWindowPingFunc) (MetaDisplay *display, - Window xwindow, - guint32 timestamp, - gpointer user_data); - typedef enum { META_LIST_DEFAULT = 0, /* normal windows */ META_LIST_INCLUDE_OVERRIDE_REDIRECT = 1 << 0, /* normal and O-R */ @@ -182,7 +177,7 @@ struct _MetaDisplay guint32 window_sequence_counter; /* Pings which we're waiting for a reply from */ - GSList *pending_pings; + GHashTable *pending_pings; /* Pending focus change */ guint focus_timeout_id; @@ -448,15 +443,6 @@ void meta_display_retheme_all (void); void meta_display_set_cursor_theme (const char *theme, int size); -void meta_display_ping_window (MetaDisplay *display, - MetaWindow *window, - guint32 timestamp, - MetaWindowPingFunc ping_reply_func, - MetaWindowPingFunc ping_timeout_func, - void *user_data); -gboolean meta_display_window_has_pending_pings (MetaDisplay *display, - MetaWindow *window); - int meta_resize_gravity_from_grab_op (MetaGrabOp op); gboolean meta_grab_op_is_moving (MetaGrabOp op); diff --git a/src/core/display.c b/src/core/display.c index 6d1b24533..2989648be 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -83,41 +83,6 @@ g == META_GRAB_OP_KEYBOARD_ESCAPING_DOCK || \ g == META_GRAB_OP_KEYBOARD_ESCAPING_GROUP) -/* - * SECTION:pings - * - * Sometimes we want to see whether a window is responding, - * so we send it a "ping" message and see whether it sends us back a "pong" - * message within a reasonable time. Here we have a system which lets us - * nominate one function to be called if we get the pong in time and another - * function if we don't. The system is rather more complicated than it needs - * to be, since we only ever use it to destroy windows which are asked to - * close themselves and don't do so within a reasonable amount of time, and - * therefore we always use the same callbacks. It's possible that we might - * use it for other things in future, or on the other hand we might decide - * that we're never going to do so and simplify it a bit. - */ - -/** - * MetaPingData: - * - * Describes a ping on a window. When we send a ping to a window, we build - * one of these structs, and it eventually gets passed to the timeout function - * or to the function which handles the response from the window. If the window - * does or doesn't respond to the ping, we use this information to deal with - * these facts; we have a handler function for each. - */ -typedef struct -{ - MetaDisplay *display; - Window xwindow; - guint32 timestamp; - MetaWindowPingFunc ping_reply_func; - MetaWindowPingFunc ping_timeout_func; - void *user_data; - guint ping_timeout_id; -} MetaPingData; - G_DEFINE_TYPE(MetaDisplay, meta_display, G_TYPE_OBJECT); /* Signals */ @@ -172,8 +137,6 @@ static guint32 event_get_time (MetaDisplay *display, XEvent *event); static void process_request_frame_extents (MetaDisplay *display, XEvent *event); -static void process_pong_message (MetaDisplay *display, - XEvent *event); static void process_selection_request (MetaDisplay *display, XEvent *event); static void process_selection_clear (MetaDisplay *display, @@ -321,62 +284,6 @@ meta_display_class_init (MetaDisplayClass *klass) G_PARAM_READABLE)); } - -/** - * ping_data_free: - * - * Destructor for #MetaPingData structs. Will destroy the - * event source for the struct as well. - */ -static void -ping_data_free (MetaPingData *ping_data) -{ - /* Remove the timeout */ - if (ping_data->ping_timeout_id != 0) - g_source_remove (ping_data->ping_timeout_id); - - g_free (ping_data); -} - -/** - * remove_pending_pings_for_window: - * @display: The display the window appears on - * @xwindow: The X ID of the window whose pings we should remove - * - * Frees every pending ping structure for the given X window on the - * given display. This means that we also destroy the timeouts. - */ -static void -remove_pending_pings_for_window (MetaDisplay *display, Window xwindow) -{ - GSList *tmp; - GSList *dead; - - /* could obviously be more efficient, don't care */ - - /* build list to be removed */ - dead = NULL; - for (tmp = display->pending_pings; tmp; tmp = tmp->next) - { - MetaPingData *ping_data = tmp->data; - - if (ping_data->xwindow == xwindow) - dead = g_slist_prepend (dead, ping_data); - } - - /* remove what we found */ - for (tmp = dead; tmp; tmp = tmp->next) - { - MetaPingData *ping_data = tmp->data; - - display->pending_pings = g_slist_remove (display->pending_pings, ping_data); - ping_data_free (ping_data); - } - - g_slist_free (dead); -} - - #ifdef HAVE_STARTUP_NOTIFICATION static void sn_error_trap_push (SnDisplay *sn_display, @@ -528,7 +435,6 @@ meta_display_open (void) the_display->server_grab_count = 0; the_display->display_opening = TRUE; - the_display->pending_pings = NULL; the_display->autoraise_timeout_id = 0; the_display->autoraise_window = NULL; the_display->focus_window = NULL; @@ -600,6 +506,8 @@ meta_display_open (void) the_display->xids = g_hash_table_new (meta_unsigned_long_hash, meta_unsigned_long_equal); + the_display->pending_pings = g_hash_table_new (meta_unsigned_long_hash, + meta_unsigned_long_equal); the_display->wayland_windows = g_hash_table_new (NULL, NULL); i = 0; @@ -2887,7 +2795,13 @@ handle_other_xevent (MetaDisplay *display, if ((Atom)event->xclient.data.l[0] == display->atom__NET_WM_PING) { - process_pong_message (display, event); + guint32 timestamp = event->xclient.data.l[1]; + window = g_hash_table_lookup (display->pending_pings, ×tamp); + + if (window) + meta_window_pong (window, timestamp); + else + meta_verbose ("Received invalid _NET_WM_PING for unknown timestamp %d\n", timestamp); /* We don't want ping reply events going into * the GTK+ event loop because gtk+ will treat @@ -3794,9 +3708,6 @@ meta_display_unregister_x_window (MetaDisplay *display, g_return_if_fail (g_hash_table_lookup (display->xids, &xwindow) != NULL); g_hash_table_remove (display->xids, &xwindow); - - /* Remove any pending pings */ - remove_pending_pings_for_window (display, xwindow); } void @@ -4644,120 +4555,6 @@ meta_set_syncing (gboolean setting) } } -/* - * How long, in milliseconds, we should wait after pinging a window - * before deciding it's not going to get back to us. - */ -#define PING_TIMEOUT_DELAY 5000 - -/** - * meta_display_ping_timeout: - * @data: All the information about this ping. It is a #MetaPingData - * cast to a #gpointer in order to be passable to a timeout function. - * This function will also free this parameter. - * - * Does whatever it is we decided to do when a window didn't respond - * to a ping. We also remove the ping from the display's list of - * pending pings. This function is called by the event loop when the timeout - * times out which we created at the start of the ping. - * - * Returns: Always returns %FALSE, because this function is called as a - * timeout and we don't want to run the timer again. - */ -static gboolean -meta_display_ping_timeout (gpointer data) -{ - MetaPingData *ping_data; - - ping_data = data; - - ping_data->ping_timeout_id = 0; - - meta_topic (META_DEBUG_PING, - "Ping %u on window %lx timed out\n", - ping_data->timestamp, ping_data->xwindow); - - (* ping_data->ping_timeout_func) (ping_data->display, ping_data->xwindow, - ping_data->timestamp, ping_data->user_data); - - ping_data->display->pending_pings = - g_slist_remove (ping_data->display->pending_pings, - ping_data); - ping_data_free (ping_data); - - return FALSE; -} - -/** - * meta_display_ping_window: - * @display: The #MetaDisplay that the window is on - * @window: The #MetaWindow to send the ping to - * @timestamp: The timestamp of the ping. Used for uniqueness. - * Cannot be CurrentTime; use a real timestamp! - * @ping_reply_func: The callback to call if we get a response. - * @ping_timeout_func: The callback to call if we don't get a response. - * @user_data: Arbitrary data that will be passed to the callback - * function. (In practice it's often a pointer to - * the window.) - * - * Sends a ping request to a window. The window must respond to - * the request within a certain amount of time. If it does, we - * will call one callback; if the time passes and we haven't had - * a response, we call a different callback. The window must have - * the hint showing that it can respond to a ping; if it doesn't, - * we call the "got a response" callback immediately and return. - * This function returns straight away after setting things up; - * the callbacks will be called from the event loop. - * - * FIXME: This should probably be a method on windows, rather than displays - * for one of their windows. - * - */ -void -meta_display_ping_window (MetaDisplay *display, - MetaWindow *window, - guint32 timestamp, - MetaWindowPingFunc ping_reply_func, - MetaWindowPingFunc ping_timeout_func, - gpointer user_data) -{ - MetaPingData *ping_data; - - if (timestamp == CurrentTime) - { - meta_warning ("Tried to ping a window with CurrentTime! Not allowed.\n"); - return; - } - - if (!window->net_wm_ping) - { - if (ping_reply_func) - (* ping_reply_func) (display, window->xwindow, timestamp, user_data); - - return; - } - - ping_data = g_new (MetaPingData, 1); - ping_data->display = display; - ping_data->xwindow = window->xwindow; - ping_data->timestamp = timestamp; - ping_data->ping_reply_func = ping_reply_func; - ping_data->ping_timeout_func = ping_timeout_func; - ping_data->user_data = user_data; - ping_data->ping_timeout_id = g_timeout_add (PING_TIMEOUT_DELAY, - meta_display_ping_timeout, - ping_data); - - display->pending_pings = g_slist_prepend (display->pending_pings, ping_data); - - meta_topic (META_DEBUG_PING, - "Sending ping with timestamp %u to window %s\n", - timestamp, window->desc); - meta_window_send_icccm_message (window, - display->atom__NET_WM_PING, - timestamp); -} - static void process_request_frame_extents (MetaDisplay *display, XEvent *event) @@ -4818,91 +4615,6 @@ process_request_frame_extents (MetaDisplay *display, meta_XFree (hints); } -/** - * process_pong_message: - * @display: the display we got the pong from - * @event: the #XEvent which is a pong; we can tell which - * ping it corresponds to because it bears the - * same timestamp. - * - * Process the pong (the response message) from the ping we sent - * to the window. This involves removing the timeout, calling the - * reply handler function, and freeing memory. - */ -static void -process_pong_message (MetaDisplay *display, - XEvent *event) -{ - GSList *tmp; - guint32 timestamp = event->xclient.data.l[1]; - - meta_topic (META_DEBUG_PING, "Received a pong with timestamp %u\n", - timestamp); - - for (tmp = display->pending_pings; tmp; tmp = tmp->next) - { - MetaPingData *ping_data = tmp->data; - - if (timestamp == ping_data->timestamp) - { - meta_topic (META_DEBUG_PING, - "Matching ping found for pong %u\n", - ping_data->timestamp); - - /* Remove the ping data from the list */ - display->pending_pings = g_slist_remove (display->pending_pings, - ping_data); - - /* Remove the timeout */ - if (ping_data->ping_timeout_id != 0) - { - g_source_remove (ping_data->ping_timeout_id); - ping_data->ping_timeout_id = 0; - } - - /* Call callback */ - (* ping_data->ping_reply_func) (display, - ping_data->xwindow, - ping_data->timestamp, - ping_data->user_data); - - ping_data_free (ping_data); - - break; - } - } -} - -/** - * meta_display_window_has_pending_pings: - * @display: The #MetaDisplay of the window. - * @window: The #MetaWindow whose pings we want to know about. - * - * Finds whether a window has any pings waiting on it. - * - * FIXME: This should probably be a method on windows, rather than displays - * for one of their windows. - * - * Returns: %TRUE if there is at least one ping which has been sent - * to the window without getting a response; %FALSE otherwise. - */ -gboolean -meta_display_window_has_pending_pings (MetaDisplay *display, - MetaWindow *window) -{ - GSList *tmp; - - for (tmp = display->pending_pings; tmp; tmp = tmp->next) - { - MetaPingData *ping_data = tmp->data; - - if (ping_data->xwindow == window->xwindow) - return TRUE; - } - - return FALSE; -} - MetaGroup* get_focussed_group (MetaDisplay *display) { diff --git a/src/core/window-private.h b/src/core/window-private.h index 49dbfc7c3..d67af673b 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -466,6 +466,8 @@ struct _MetaWindow /* Bypass compositor hints */ guint bypass_compositor; + + GSList *pending_pings; }; struct _MetaWindowClass @@ -747,4 +749,16 @@ void meta_window_handle_enter (MetaWindow *window, void meta_window_set_surface_mapped (MetaWindow *window, gboolean surface_mapped); +typedef void (* MetaWindowPingFunc) (MetaWindow *window, + guint32 timestamp, + gpointer user_data); + +void meta_window_ping (MetaWindow *window, + guint32 timestamp, + MetaWindowPingFunc ping_reply_func, + MetaWindowPingFunc ping_timeout_func, + void *user_data); +void meta_window_pong (MetaWindow *window, + guint32 timestamp); + #endif diff --git a/src/core/window.c b/src/core/window.c index f8823b68b..532ae0c06 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -73,6 +73,26 @@ static int destroying_windows_disallowed = 0; +/** + * MetaPingData: + * + * Describes a ping on a window. When we send a ping to a window, we build + * one of these structs, and it eventually gets passed to the timeout function + * or to the function which handles the response from the window. If the window + * does or doesn't respond to the ping, we use this information to deal with + * these facts; we have a handler function for each. + */ +typedef struct +{ + MetaWindow *window; + guint32 timestamp; + MetaWindowPingFunc ping_reply_func; + MetaWindowPingFunc ping_timeout_func; + void *user_data; + guint ping_timeout_id; +} MetaPingData; + +static void ping_data_free (MetaPingData *ping_data); static void update_sm_hints (MetaWindow *window); static void update_net_frame_extents (MetaWindow *window); @@ -2051,6 +2071,8 @@ meta_window_unmanage (MetaWindow *window, if (window->surface) meta_wayland_surface_free (window->surface); + g_slist_free_full (window->pending_pings, (GDestroyNotify) ping_data_free); + meta_prefs_remove_listener (prefs_changed_callback, window); meta_screen_queue_check_fullscreen (window->screen); @@ -11960,3 +11982,194 @@ meta_window_set_surface_mapped (MetaWindow *window, window->surface_mapped = surface_mapped; meta_window_queue (window, META_QUEUE_CALC_SHOWING); } + +/* + * SECTION:pings + * + * Sometimes we want to see whether a window is responding, + * so we send it a "ping" message and see whether it sends us back a "pong" + * message within a reasonable time. Here we have a system which lets us + * nominate one function to be called if we get the pong in time and another + * function if we don't. The system is rather more complicated than it needs + * to be, since we only ever use it to destroy windows which are asked to + * close themselves and don't do so within a reasonable amount of time, and + * therefore we always use the same callbacks. It's possible that we might + * use it for other things in future, or on the other hand we might decide + * that we're never going to do so and simplify it a bit. + */ + +/** + * ping_data_free: + * + * Destructor for #MetaPingData structs. Will destroy the + * event source for the struct as well. + */ +static void +ping_data_free (MetaPingData *ping_data) +{ + MetaWindow *window = ping_data->window; + MetaDisplay *display = window->display; + + /* Remove the timeout */ + if (ping_data->ping_timeout_id != 0) + g_source_remove (ping_data->ping_timeout_id); + + g_hash_table_remove (display->pending_pings, &ping_data->timestamp); + + g_free (ping_data); +} + +/** + * meta_window_pong: + * @window: the window we got the pong on + * @timestamp: the timestamp that the client sent back + * + * Process the pong (the response message) from the ping we sent + * to the window. This involves removing the timeout, calling the + * reply handler function, and freeing memory. + */ +void +meta_window_pong (MetaWindow *window, + guint32 timestamp) +{ + GSList *tmp; + + meta_topic (META_DEBUG_PING, "Received a pong with timestamp %u\n", + timestamp); + + for (tmp = window->pending_pings; tmp; tmp = tmp->next) + { + MetaPingData *ping_data = tmp->data; + + if (timestamp == ping_data->timestamp) + { + meta_topic (META_DEBUG_PING, + "Matching ping found for pong %u\n", + ping_data->timestamp); + + /* Remove the ping data from the list */ + window->pending_pings = g_slist_remove (window->pending_pings, ping_data); + + /* Remove the timeout */ + if (ping_data->ping_timeout_id != 0) + { + g_source_remove (ping_data->ping_timeout_id); + ping_data->ping_timeout_id = 0; + } + + /* Call callback */ + (* ping_data->ping_reply_func) (window, + ping_data->timestamp, + ping_data->user_data); + + /* Remove the ping data from the list */ + window->pending_pings = g_slist_remove (window->pending_pings, ping_data); + + ping_data_free (ping_data); + + break; + } + } +} + +/* + * How long, in milliseconds, we should wait after pinging a window + * before deciding it's not going to get back to us. + */ +#define PING_TIMEOUT_DELAY 5000 + +/** + * ping_timeout: + * @data: All the information about this ping. It is a #MetaPingData + * cast to a #gpointer in order to be passable to a timeout function. + * This function will also free this parameter. + * + * Does whatever it is we decided to do when a window didn't respond + * to a ping. We also remove the ping from the display's list of + * pending pings. This function is called by the event loop when the timeout + * times out which we created at the start of the ping. + * + * Returns: Always returns %FALSE, because this function is called as a + * timeout and we don't want to run the timer again. + */ +static gboolean +ping_timeout (gpointer data) +{ + MetaPingData *ping_data; + + ping_data = data; + + ping_data->ping_timeout_id = 0; + + meta_topic (META_DEBUG_PING, + "Ping %u on window %s timed out\n", + ping_data->timestamp, ping_data->window->desc); + + (* ping_data->ping_timeout_func) (ping_data->window, ping_data->timestamp, ping_data->user_data); + + ping_data_free (ping_data); + + return FALSE; +} + +/** + * meta_window_ping: + * @window: The #MetaWindow to send the ping to + * @timestamp: The timestamp of the ping. Used for uniqueness. + * Cannot be CurrentTime; use a real timestamp! + * @ping_reply_func: The callback to call if we get a response. + * @ping_timeout_func: The callback to call if we don't get a response. + * @user_data: Arbitrary data that will be passed to the callback + * function. (In practice it's often a pointer to + * the window.) + * + * Sends a ping request to a window. The window must respond to + * the request within a certain amount of time. If it does, we + * will call one callback; if the time passes and we haven't had + * a response, we call a different callback. The window must have + * the hint showing that it can respond to a ping; if it doesn't, + * we call the "got a response" callback immediately and return. + * This function returns straight away after setting things up; + * the callbacks will be called from the event loop. + */ +void +meta_window_ping (MetaWindow *window, + guint32 timestamp, + MetaWindowPingFunc ping_reply_func, + MetaWindowPingFunc ping_timeout_func, + gpointer user_data) +{ + MetaPingData *ping_data; + MetaDisplay *display = window->display; + + if (timestamp == CurrentTime) + { + meta_warning ("Tried to ping a window with CurrentTime! Not allowed.\n"); + return; + } + + if (!window->net_wm_ping) + { + if (ping_reply_func) + (* ping_reply_func) (window, timestamp, user_data); + + return; + } + + ping_data = g_new (MetaPingData, 1); + ping_data->window = window; + ping_data->timestamp = timestamp; + ping_data->ping_reply_func = ping_reply_func; + ping_data->ping_timeout_func = ping_timeout_func; + ping_data->user_data = user_data; + ping_data->ping_timeout_id = g_timeout_add (PING_TIMEOUT_DELAY, ping_timeout, ping_data); + + g_hash_table_insert (display->pending_pings, &ping_data->timestamp, window); + + meta_topic (META_DEBUG_PING, + "Sending ping with timestamp %u to window %s\n", + timestamp, window->desc); + meta_window_send_icccm_message (window, + display->atom__NET_WM_PING, + timestamp); +} From 6d639ac528570c6d88c1cf9049e1d237d46fe0f6 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 21 Nov 2013 14:20:52 -0500 Subject: [PATCH 288/889] window: Support pinging Wayland surfaces as well --- src/core/window.c | 8 +++++--- src/wayland/meta-wayland-surface.c | 18 ++++++++++++++++++ src/wayland/meta-wayland-surface.h | 3 +++ 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/core/window.c b/src/core/window.c index 532ae0c06..622168a36 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -12169,7 +12169,9 @@ meta_window_ping (MetaWindow *window, meta_topic (META_DEBUG_PING, "Sending ping with timestamp %u to window %s\n", timestamp, window->desc); - meta_window_send_icccm_message (window, - display->atom__NET_WM_PING, - timestamp); + + if (window->client_type == META_WINDOW_CLIENT_TYPE_X11) + meta_window_send_icccm_message (window, display->atom__NET_WM_PING, timestamp); + else + meta_wayland_surface_ping (window->surface, timestamp); } diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 71e3512a1..597ee03d7 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -566,6 +566,10 @@ xdg_surface_pong (struct wl_client *client, struct wl_resource *resource, guint32 serial) { + MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface); + + meta_window_pong (surface->window, serial); } static gboolean @@ -769,6 +773,10 @@ xdg_popup_pong (struct wl_client *client, struct wl_resource *resource, uint32_t serial) { + MetaWaylandSurfaceExtension *xdg_popup = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = wl_container_of (xdg_popup, surface, xdg_popup); + + meta_window_pong (surface->window, serial); } static const struct xdg_popup_interface meta_wayland_xdg_popup_interface = { @@ -940,3 +948,13 @@ meta_wayland_surface_focused_unset (MetaWaylandSurface *surface) if (surface->xdg_surface.resource) xdg_surface_send_focused_unset (surface->xdg_surface.resource); } + +void +meta_wayland_surface_ping (MetaWaylandSurface *surface, + guint32 timestamp) +{ + if (surface->xdg_surface.resource) + xdg_surface_send_ping (surface->xdg_surface.resource, timestamp); + else if (surface->xdg_popup.resource) + xdg_popup_send_ping (surface->xdg_popup.resource, timestamp); +} diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h index 3d043cd12..25b493927 100644 --- a/src/wayland/meta-wayland-surface.h +++ b/src/wayland/meta-wayland-surface.h @@ -102,4 +102,7 @@ void meta_wayland_surface_configure_notify (MetaWaylandSurface *s void meta_wayland_surface_focused_set (MetaWaylandSurface *surface); void meta_wayland_surface_focused_unset (MetaWaylandSurface *surface); +void meta_wayland_surface_ping (MetaWaylandSurface *surface, + guint32 serial); + #endif From e5e35e5a7f3d4cfc201199904d3cb6db655fd883 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 18 Nov 2013 22:15:47 -0500 Subject: [PATCH 289/889] background-group: Remove some unnecessary cruft --- src/compositor/meta-background-group.c | 28 -------------------------- 1 file changed, 28 deletions(-) diff --git a/src/compositor/meta-background-group.c b/src/compositor/meta-background-group.c index 51d1685fa..1dae14f43 100644 --- a/src/compositor/meta-background-group.c +++ b/src/compositor/meta-background-group.c @@ -23,42 +23,14 @@ G_DEFINE_TYPE (MetaBackgroundGroup, meta_background_group, CLUTTER_TYPE_ACTOR); -struct _MetaBackgroundGroupPrivate -{ - gpointer dummy; -}; - -static void -meta_background_group_dispose (GObject *object) -{ - G_OBJECT_CLASS (meta_background_group_parent_class)->dispose (object); -} - -static gboolean -meta_background_group_get_paint_volume (ClutterActor *actor, - ClutterPaintVolume *volume) -{ - return clutter_paint_volume_set_from_allocation (volume, actor); -} - static void meta_background_group_class_init (MetaBackgroundGroupClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); - - actor_class->get_paint_volume = meta_background_group_get_paint_volume; - object_class->dispose = meta_background_group_dispose; - - g_type_class_add_private (klass, sizeof (MetaBackgroundGroupPrivate)); } static void meta_background_group_init (MetaBackgroundGroup *self) { - self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, - META_TYPE_BACKGROUND_GROUP, - MetaBackgroundGroupPrivate); } /** From 5af7f619c8040d00298329eda86a0e36c9432973 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 18 Nov 2013 22:16:52 -0500 Subject: [PATCH 290/889] background-group: Use the Clutter iteration APIs --- src/compositor/meta-background-group.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/compositor/meta-background-group.c b/src/compositor/meta-background-group.c index 1dae14f43..3d680de1b 100644 --- a/src/compositor/meta-background-group.c +++ b/src/compositor/meta-background-group.c @@ -45,30 +45,27 @@ void meta_background_group_set_clip_region (MetaBackgroundGroup *self, cairo_region_t *region) { - GList *children, *l; - - children = clutter_actor_get_children (CLUTTER_ACTOR (self)); - for (l = children; l; l = l->next) + ClutterActor *child; + for (child = clutter_actor_get_first_child (self); + child != NULL; + child = clutter_actor_get_next_sibling (child)) { - ClutterActor *actor = l->data; - - if (META_IS_BACKGROUND_ACTOR (actor)) + if (META_IS_BACKGROUND_ACTOR (child)) { - meta_background_actor_set_clip_region (META_BACKGROUND_ACTOR (actor), region); + meta_background_actor_set_clip_region (META_BACKGROUND_ACTOR (child), region); } - else if (META_IS_BACKGROUND_GROUP (actor)) + else if (META_IS_BACKGROUND_GROUP (child)) { int x, y; - if (!meta_actor_is_untransformed (actor, &x, &y)) + if (!meta_actor_is_untransformed (child, &x, &y)) continue; cairo_region_translate (region, -x, -y); - meta_background_group_set_clip_region (META_BACKGROUND_GROUP (actor), region); + meta_background_group_set_clip_region (META_BACKGROUND_GROUP (child), region); cairo_region_translate (region, x, y); } } - g_list_free (children); } ClutterActor * From 858db7081aa05790cdd6afbf0725d91b42586c78 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 21 Nov 2013 15:14:40 -0500 Subject: [PATCH 291/889] background-group: Fix cast warning --- src/compositor/meta-background-group.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compositor/meta-background-group.c b/src/compositor/meta-background-group.c index 3d680de1b..092dd1889 100644 --- a/src/compositor/meta-background-group.c +++ b/src/compositor/meta-background-group.c @@ -46,7 +46,7 @@ meta_background_group_set_clip_region (MetaBackgroundGroup *self, cairo_region_t *region) { ClutterActor *child; - for (child = clutter_actor_get_first_child (self); + for (child = clutter_actor_get_first_child (CLUTTER_ACTOR (self)); child != NULL; child = clutter_actor_get_next_sibling (child)) { From 7d88b3593bec4fea3c00fe35b72fc61848a58197 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 21 Nov 2013 17:29:38 -0500 Subject: [PATCH 292/889] surface-actor: Remove unused field --- src/compositor/meta-surface-actor.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/compositor/meta-surface-actor.c b/src/compositor/meta-surface-actor.c index 40177ad17..690cd87c7 100644 --- a/src/compositor/meta-surface-actor.c +++ b/src/compositor/meta-surface-actor.c @@ -22,7 +22,6 @@ struct _MetaSurfaceActorPrivate { MetaShapedTexture *texture; MetaWaylandBuffer *buffer; - Pixmap pixmap; }; G_DEFINE_TYPE (MetaSurfaceActor, meta_surface_actor, CLUTTER_TYPE_ACTOR); From 0be57b621b3382f347c3a4fb0b6865c5bf3d7bee Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 21 Nov 2013 17:35:49 -0500 Subject: [PATCH 293/889] window-actor: Fix a copy/paste typo --- src/compositor/meta-window-actor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 4bab98fd9..8956f810d 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -2409,7 +2409,7 @@ meta_window_actor_update_input_region (MetaWindowActor *self, cairo_region_union (region, priv->window->input_region); cairo_region_translate (region, client_area->x, client_area->y); } - else if (priv->window->shape_region != NULL) + else if (priv->window->input_region != NULL) { region = cairo_region_reference (priv->window->input_region); } From 762fa0e116b8d997d5fb95969c2c48cee8de1d67 Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Mon, 25 Nov 2013 12:00:55 +0100 Subject: [PATCH 294/889] compositor: Also redirect windows in wayland compositor mode XWayland was doing this for us but now it isn't anymore. --- src/compositor/compositor.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 6c9c1376e..93464e1f1 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -820,10 +820,10 @@ meta_compositor_manage_screen (MetaCompositor *compositor, * contents until we show the stage. */ XMapWindow (xdisplay, info->output); - - redirect_windows (compositor, screen); } + redirect_windows (compositor, screen); + info->plugin_mgr = meta_plugin_manager_new (screen); } From ba3968a8225a23ede6e6d91d9a0948bf451c443e Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Mon, 25 Nov 2013 14:06:10 +0100 Subject: [PATCH 295/889] keybindings: Fix typo in port to Clutter events We always want to trigger on key press. --- src/core/keybindings.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/keybindings.c b/src/core/keybindings.c index e3289639c..e69910842 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -2001,7 +2001,7 @@ process_iso_next_group (MetaDisplay *display, gboolean activate; int i; - if (event->type != CLUTTER_KEY_RELEASE) + if (event->type == CLUTTER_KEY_RELEASE) return FALSE; activate = FALSE; From eec0f5df4752d95b0ff5788e782fc5a7a4708b42 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 25 Nov 2013 15:13:48 -0500 Subject: [PATCH 296/889] display: Fix logic for determining whether our focus was successful In some cases, we can focus the frame window instead of the client window, so make sure that our checks include that as well. https://bugzilla.gnome.org/show_bug.cgi?id=715030 --- src/core/display.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/core/display.c b/src/core/display.c index 2989648be..49aea52d5 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -1941,6 +1941,19 @@ handle_window_focus_event (MetaDisplay *display, } } +static gboolean +window_has_xwindow (MetaWindow *window, + Window xwindow) +{ + if (window->xwindow == xwindow) + return TRUE; + + if (window->frame && window->frame->xwindow == xwindow) + return TRUE; + + return FALSE; +} + static gboolean meta_display_handle_event (MetaDisplay *display, const ClutterEvent *event) @@ -2929,7 +2942,7 @@ meta_display_handle_xevent (MetaDisplay *display, if (event->xany.serial > display->focus_serial && display->focus_window && - display->focus_window->xwindow != display->server_focus_window) + !window_has_xwindow (display->focus_window, display->server_focus_window)) { meta_topic (META_DEBUG_FOCUS, "Earlier attempt to focus %s failed\n", display->focus_window->desc); From 7a787d79468ef6fbfdcf35b0866af41bc15b5e64 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 25 Nov 2013 15:17:14 -0500 Subject: [PATCH 297/889] window-group: Decompose culling operations into two methods This also fixes a bug in the translation of clip_region. We will add an interface for this soon, so we can recursively cull like this... https://bugzilla.gnome.org/show_bug.cgi?id=714706 --- src/compositor/meta-window-group.c | 194 ++++++++++++++++------------- 1 file changed, 105 insertions(+), 89 deletions(-) diff --git a/src/compositor/meta-window-group.c b/src/compositor/meta-window-group.c index 46d710b92..44b35c820 100644 --- a/src/compositor/meta-window-group.c +++ b/src/compositor/meta-window-group.c @@ -88,86 +88,12 @@ painting_untransformed (MetaWindowGroup *window_group, } static void -meta_window_group_paint (ClutterActor *actor) +meta_window_group_cull_out (MetaWindowGroup *group, + cairo_region_t *unobscured_region, + cairo_region_t *clip_region) { - cairo_region_t *clip_region; - cairo_region_t *unobscured_region; - ClutterActorIter iter; + ClutterActor *actor = CLUTTER_ACTOR (group); ClutterActor *child; - cairo_rectangle_int_t visible_rect, clip_rect; - int paint_x_origin, paint_y_origin; - int actor_x_origin, actor_y_origin; - int paint_x_offset, paint_y_offset; - - MetaWindowGroup *window_group = META_WINDOW_GROUP (actor); - MetaCompScreen *info = meta_screen_get_compositor_data (window_group->screen); - ClutterActor *stage = clutter_actor_get_stage (actor); - - /* Start off by treating all windows as completely unobscured, so damage anywhere - * in a window queues redraws, but confine it more below. */ - clutter_actor_iter_init (&iter, actor); - while (clutter_actor_iter_next (&iter, &child)) - { - if (META_IS_WINDOW_ACTOR (child)) - { - MetaWindowActor *window_actor = META_WINDOW_ACTOR (child); - meta_window_actor_set_unobscured_region (window_actor, NULL); - } - } - - /* Normally we expect an actor to be drawn at it's position on the screen. - * However, if we're inside the paint of a ClutterClone, that won't be the - * case and we need to compensate. We look at the position of the window - * group under the current model-view matrix and the position of the actor. - * If they are both simply integer translations, then we can compensate - * easily, otherwise we give up. - * - * Possible cleanup: work entirely in paint space - we can compute the - * combination of the model-view matrix with the local matrix for each child - * actor and get a total transformation for that actor for how we are - * painting currently, and never worry about how actors are positioned - * on the stage. - */ - if (!painting_untransformed (window_group, &paint_x_origin, &paint_y_origin) || - !meta_actor_is_untransformed (actor, &actor_x_origin, &actor_y_origin)) - { - CLUTTER_ACTOR_CLASS (meta_window_group_parent_class)->paint (actor); - return; - } - - paint_x_offset = paint_x_origin - actor_x_origin; - paint_y_offset = paint_y_origin - actor_y_origin; - - visible_rect.x = visible_rect.y = 0; - visible_rect.width = clutter_actor_get_width (CLUTTER_ACTOR (stage)); - visible_rect.height = clutter_actor_get_height (CLUTTER_ACTOR (stage)); - - unobscured_region = cairo_region_create_rectangle (&visible_rect); - - /* Get the clipped redraw bounds from Clutter so that we can avoid - * painting shadows on windows that don't need to be painted in this - * frame. In the case of a multihead setup with mismatched monitor - * sizes, we could intersect this with an accurate union of the - * monitors to avoid painting shadows that are visible only in the - * holes. */ - clutter_stage_get_redraw_clip_bounds (CLUTTER_STAGE (stage), - &clip_rect); - - clip_region = cairo_region_create_rectangle (&clip_rect); - - if (!meta_is_wayland_compositor ()) - { - info = meta_screen_get_compositor_data (window_group->screen); - if (info->unredirected_window != NULL) - { - cairo_rectangle_int_t unredirected_rect; - MetaWindow *window = meta_window_actor_get_meta_window (info->unredirected_window); - - meta_window_get_frame_rect (window, (MetaRectangle *)&unredirected_rect); - cairo_region_subtract_rectangle (unobscured_region, &unredirected_rect); - cairo_region_subtract_rectangle (clip_region, &unredirected_rect); - } - } /* We walk the list from top to bottom (opposite of painting order), * and subtract the opaque area of each window out of the visible @@ -176,6 +102,8 @@ meta_window_group_paint (ClutterActor *actor) clutter_actor_iter_init (&iter, actor); while (clutter_actor_iter_prev (&iter, &child)) { + MetaCompScreen *info = meta_screen_get_compositor_data (group->screen); + if (!CLUTTER_ACTOR_IS_VISIBLE (child)) continue; @@ -211,10 +139,6 @@ meta_window_group_paint (ClutterActor *actor) if (!meta_actor_is_untransformed (CLUTTER_ACTOR (window_actor), &x, &y)) continue; - x += paint_x_offset; - y += paint_y_offset; - - /* Temporarily move to the coordinate system of the actor */ cairo_region_translate (unobscured_region, - x, - y); cairo_region_translate (clip_region, - x, - y); @@ -245,9 +169,6 @@ meta_window_group_paint (ClutterActor *actor) if (!meta_actor_is_untransformed (child, &x, &y)) continue; - x += paint_x_offset; - y += paint_y_offset; - cairo_region_translate (clip_region, - x, - y); if (META_IS_BACKGROUND_GROUP (child)) @@ -257,11 +178,14 @@ meta_window_group_paint (ClutterActor *actor) cairo_region_translate (clip_region, x, y); } } +} - cairo_region_destroy (unobscured_region); - cairo_region_destroy (clip_region); - - CLUTTER_ACTOR_CLASS (meta_window_group_parent_class)->paint (actor); +static void +meta_window_group_reset_culling (MetaWindowGroup *group) +{ + ClutterActor *actor = CLUTTER_ACTOR (group); + ClutterActor *child; + ClutterActorIter iter; /* Now that we are done painting, unset the visible regions (they will * mess up painting clones of our actors) @@ -282,6 +206,98 @@ meta_window_group_paint (ClutterActor *actor) } } +static void +meta_window_group_paint (ClutterActor *actor) +{ + cairo_region_t *clip_region; + cairo_region_t *unobscured_region; + ClutterActorIter iter; + ClutterActor *child; + cairo_rectangle_int_t visible_rect, clip_rect; + int paint_x_offset, paint_y_offset; + int paint_x_origin, paint_y_origin; + int actor_x_origin, actor_y_origin; + + MetaWindowGroup *window_group = META_WINDOW_GROUP (actor); + ClutterActor *stage = clutter_actor_get_stage (actor); + + /* Start off by treating all windows as completely unobscured, so damage anywhere + * in a window queues redraws, but confine it more below. */ + clutter_actor_iter_init (&iter, actor); + while (clutter_actor_iter_next (&iter, &child)) + { + if (META_IS_WINDOW_ACTOR (child)) + { + MetaWindowActor *window_actor = META_WINDOW_ACTOR (child); + meta_window_actor_set_unobscured_region (window_actor, NULL); + } + } + + /* Normally we expect an actor to be drawn at it's position on the screen. + * However, if we're inside the paint of a ClutterClone, that won't be the + * case and we need to compensate. We look at the position of the window + * group under the current model-view matrix and the position of the actor. + * If they are both simply integer translations, then we can compensate + * easily, otherwise we give up. + * + * Possible cleanup: work entirely in paint space - we can compute the + * combination of the model-view matrix with the local matrix for each child + * actor and get a total transformation for that actor for how we are + * painting currently, and never worry about how actors are positioned + * on the stage. + */ + if (!painting_untransformed (window_group, &paint_x_origin, &paint_y_origin) || + !meta_actor_is_untransformed (actor, &actor_x_origin, &actor_y_origin)) + { + CLUTTER_ACTOR_CLASS (meta_window_group_parent_class)->paint (actor); + return; + } + + visible_rect.x = visible_rect.y = 0; + visible_rect.width = clutter_actor_get_width (CLUTTER_ACTOR (stage)); + visible_rect.height = clutter_actor_get_height (CLUTTER_ACTOR (stage)); + + unobscured_region = cairo_region_create_rectangle (&visible_rect); + + /* Get the clipped redraw bounds from Clutter so that we can avoid + * painting shadows on windows that don't need to be painted in this + * frame. In the case of a multihead setup with mismatched monitor + * sizes, we could intersect this with an accurate union of the + * monitors to avoid painting shadows that are visible only in the + * holes. */ + clutter_stage_get_redraw_clip_bounds (CLUTTER_STAGE (stage), + &clip_rect); + + clip_region = cairo_region_create_rectangle (&clip_rect); + + paint_x_offset = paint_x_origin - actor_x_origin; + paint_y_offset = paint_y_origin - actor_y_origin; + cairo_region_translate (clip_region, -paint_x_offset, -paint_y_offset); + + if (!meta_is_wayland_compositor ()) + { + MetaCompScreen *info = meta_screen_get_compositor_data (window_group->screen); + if (info->unredirected_window != NULL) + { + cairo_rectangle_int_t unredirected_rect; + MetaWindow *window = meta_window_actor_get_meta_window (info->unredirected_window); + + meta_window_get_frame_rect (window, (MetaRectangle *)&unredirected_rect); + cairo_region_subtract_rectangle (unobscured_region, &unredirected_rect); + cairo_region_subtract_rectangle (clip_region, &unredirected_rect); + } + } + + meta_window_group_cull_out (window_group, unobscured_region, clip_region); + + cairo_region_destroy (unobscured_region); + cairo_region_destroy (clip_region); + + CLUTTER_ACTOR_CLASS (meta_window_group_parent_class)->paint (actor); + + meta_window_group_reset_culling (window_group); +} + static gboolean meta_window_group_get_paint_volume (ClutterActor *actor, ClutterPaintVolume *volume) From 0764b2058ad3686ffd910065d8accfa6ecccddc7 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 21 Nov 2013 15:13:18 -0500 Subject: [PATCH 298/889] window-actor: Move the operations we need to do when we cull out here Soon, we'll move this into a generic MetaCullable interface, but for now, just put hardcoded knowledge in MetaWindowGroup. https://bugzilla.gnome.org/show_bug.cgi?id=714706 --- src/compositor/meta-window-actor-private.h | 11 +++--- src/compositor/meta-window-actor.c | 40 +++++++++++++++++++--- src/compositor/meta-window-group.c | 27 ++------------- 3 files changed, 42 insertions(+), 36 deletions(-) diff --git a/src/compositor/meta-window-actor-private.h b/src/compositor/meta-window-actor-private.h index b9f88c4ca..2b9cb4138 100644 --- a/src/compositor/meta-window-actor-private.h +++ b/src/compositor/meta-window-actor-private.h @@ -67,13 +67,10 @@ void meta_window_actor_set_updates_frozen (MetaWindowActor *self, void meta_window_actor_queue_frame_drawn (MetaWindowActor *self, gboolean no_delay_frame); -cairo_region_t *meta_window_actor_get_obscured_region (MetaWindowActor *self); - -void meta_window_actor_set_clip_region (MetaWindowActor *self, - cairo_region_t *clip_region); -void meta_window_actor_set_clip_region_beneath (MetaWindowActor *self, - cairo_region_t *beneath_region); -void meta_window_actor_reset_clip_regions (MetaWindowActor *self); +void meta_window_actor_cull_out (MetaWindowActor *self, + cairo_region_t *unobscured_region, + cairo_region_t *clip_region); +void meta_window_actor_reset_culling (MetaWindowActor *self); void meta_window_actor_set_unobscured_region (MetaWindowActor *self, cairo_region_t *unobscured_region); diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 8956f810d..1bbb2255f 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -1810,7 +1810,7 @@ meta_window_actor_unmapped (MetaWindowActor *self) * Return value: (transfer none): the area obscured by the window, * %NULL is the same as an empty region. */ -cairo_region_t * +static cairo_region_t * meta_window_actor_get_obscured_region (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; @@ -1910,7 +1910,7 @@ meta_window_actor_set_unobscured_region (MetaWindowActor *self, * not drawn in this frame. * This will be set before painting then unset afterwards. */ -void +static void meta_window_actor_set_clip_region (MetaWindowActor *self, cairo_region_t *clip_region) { @@ -1931,7 +1931,7 @@ meta_window_actor_set_clip_region (MetaWindowActor *self, * shadow hid by the window itself. This will be set before painting * then unset afterwards. */ -void +static void meta_window_actor_set_clip_region_beneath (MetaWindowActor *self, cairo_region_t *beneath_region) { @@ -1951,15 +1951,45 @@ meta_window_actor_set_clip_region_beneath (MetaWindowActor *self, } } +void +meta_window_actor_cull_out (MetaWindowActor *self, + cairo_region_t *unobscured_region, + cairo_region_t *clip_region) +{ + if (!meta_is_wayland_compositor ()) + { + MetaCompScreen *info = meta_screen_get_compositor_data (self->priv->screen); + + /* Don't do any culling for the unredirected window */ + if (self == info->unredirected_window) + return; + } + + meta_window_actor_set_unobscured_region (self, unobscured_region); + meta_window_actor_set_clip_region (self, clip_region); + + if (clutter_actor_get_paint_opacity (CLUTTER_ACTOR (self)) == 0xff) + { + cairo_region_t *obscured_region = meta_window_actor_get_obscured_region (self); + if (obscured_region) + { + cairo_region_subtract (unobscured_region, obscured_region); + cairo_region_subtract (clip_region, obscured_region); + } + } + + meta_window_actor_set_clip_region_beneath (self, clip_region); +} + /** - * meta_window_actor_reset_clip_regions: + * meta_window_actor_reset_culling: * @self: a #MetaWindowActor * * Unsets the regions set by meta_window_actor_set_clip_region() and * meta_window_actor_set_clip_region_beneath() */ void -meta_window_actor_reset_clip_regions (MetaWindowActor *self) +meta_window_actor_reset_culling (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; diff --git a/src/compositor/meta-window-group.c b/src/compositor/meta-window-group.c index 44b35c820..be1b54462 100644 --- a/src/compositor/meta-window-group.c +++ b/src/compositor/meta-window-group.c @@ -102,16 +102,9 @@ meta_window_group_cull_out (MetaWindowGroup *group, clutter_actor_iter_init (&iter, actor); while (clutter_actor_iter_prev (&iter, &child)) { - MetaCompScreen *info = meta_screen_get_compositor_data (group->screen); - if (!CLUTTER_ACTOR_IS_VISIBLE (child)) continue; - if (!meta_is_wayland_compositor () && - info->unredirected_window != NULL && - child == CLUTTER_ACTOR (info->unredirected_window)) - continue; - /* If an actor has effects applied, then that can change the area * it paints and the opacity, so we no longer can figure out what * portion of the actor is obscured and what portion of the screen @@ -133,30 +126,16 @@ meta_window_group_cull_out (MetaWindowGroup *group, if (META_IS_WINDOW_ACTOR (child)) { - MetaWindowActor *window_actor = META_WINDOW_ACTOR (child); int x, y; - if (!meta_actor_is_untransformed (CLUTTER_ACTOR (window_actor), &x, &y)) + if (!meta_actor_is_untransformed (child, &x, &y)) continue; /* Temporarily move to the coordinate system of the actor */ cairo_region_translate (unobscured_region, - x, - y); cairo_region_translate (clip_region, - x, - y); - meta_window_actor_set_unobscured_region (window_actor, unobscured_region); - meta_window_actor_set_clip_region (window_actor, clip_region); - - if (clutter_actor_get_paint_opacity (CLUTTER_ACTOR (window_actor)) == 0xff) - { - cairo_region_t *obscured_region = meta_window_actor_get_obscured_region (window_actor); - if (obscured_region) - { - cairo_region_subtract (unobscured_region, obscured_region); - cairo_region_subtract (clip_region, obscured_region); - } - } - - meta_window_actor_set_clip_region_beneath (window_actor, clip_region); + meta_window_actor_cull_out (META_WINDOW_ACTOR (child), unobscured_region, clip_region); cairo_region_translate (unobscured_region, x, y); cairo_region_translate (clip_region, x, y); @@ -196,7 +175,7 @@ meta_window_group_reset_culling (MetaWindowGroup *group) if (META_IS_WINDOW_ACTOR (child)) { MetaWindowActor *window_actor = META_WINDOW_ACTOR (child); - meta_window_actor_reset_clip_regions (window_actor); + meta_window_actor_reset_culling (window_actor); } else if (META_IS_BACKGROUND_ACTOR (child)) { From 74e43a470268e16f2ee1e3bd69cf39e10c65cc0a Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 21 Nov 2013 15:25:08 -0500 Subject: [PATCH 299/889] cullable: Turn cull_out / reset_culling into a separate interface Instead of hardcoded knowledge of certain classes in MetaWindowGroup, create a generic interface that all actors can implement to get parts of their regions culled out during redraw, without needing any special knowledge of how to handle a specific actor. The names now are a bit suspect. MetaBackgroundGroup is a simple MetaCullable that knows how to cull children, and MetaWindowGroup is the "toplevel" cullable that computes the initial two regions. A future cleanup here could be to merge MetaWindowGroup / MetaBackgroundGroup so that we only have a generic MetaSimpleCullable, and move the "toplevel" cullability to be a MetaCullableToplevel. https://bugzilla.gnome.org/show_bug.cgi?id=714706 --- doc/reference/meta-sections.txt | 17 ++ src/Makefile.am | 3 +- .../meta-background-actor-private.h | 3 - src/compositor/meta-background-actor.c | 59 +++--- .../meta-background-group-private.h | 11 - src/compositor/meta-background-group.c | 59 +++--- src/compositor/meta-cullable.c | 191 ++++++++++++++++++ src/compositor/meta-cullable.h | 68 +++++++ src/compositor/meta-window-actor-private.h | 5 - src/compositor/meta-window-actor.c | 35 ++-- src/compositor/meta-window-group.c | 113 ++--------- src/compositor/meta-window-group.h | 26 +-- 12 files changed, 379 insertions(+), 211 deletions(-) delete mode 100644 src/compositor/meta-background-group-private.h create mode 100644 src/compositor/meta-cullable.c create mode 100644 src/compositor/meta-cullable.h diff --git a/doc/reference/meta-sections.txt b/doc/reference/meta-sections.txt index 90f815249..7aa893177 100644 --- a/doc/reference/meta-sections.txt +++ b/doc/reference/meta-sections.txt @@ -388,6 +388,23 @@ MetaWindowActorPrivate meta_window_actor_get_type +
+meta-cullable +MetaCullable +MetaCullable +MetaCullableInterface +meta_cullable_cull_out +meta_cullable_reset_culling +meta_cullable_cull_out_children +meta_cullable_reset_culling_children + +META_TYPE_CULLABLE +META_CULLABLE +META_IS_CULLABLE +META_CULLABLE_GET_IFACE +meta_cullable_get_type +
+
prefs MetaPreference diff --git a/src/Makefile.am b/src/Makefile.am index 20bea802e..b81c6ec51 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -70,7 +70,8 @@ libmutter_wayland_la_SOURCES = \ compositor/meta-background-actor.c \ compositor/meta-background-actor-private.h \ compositor/meta-background-group.c \ - compositor/meta-background-group-private.h \ + compositor/meta-cullable.c \ + compositor/meta-cullable.h \ compositor/meta-module.c \ compositor/meta-module.h \ compositor/meta-plugin.c \ diff --git a/src/compositor/meta-background-actor-private.h b/src/compositor/meta-background-actor-private.h index 9ab074ebd..d48fb03d4 100644 --- a/src/compositor/meta-background-actor-private.h +++ b/src/compositor/meta-background-actor-private.h @@ -6,9 +6,6 @@ #include #include -void meta_background_actor_set_clip_region (MetaBackgroundActor *self, - cairo_region_t *clip_region); - cairo_region_t *meta_background_actor_get_clip_region (MetaBackgroundActor *self); #endif /* META_BACKGROUND_ACTOR_PRIVATE_H */ diff --git a/src/compositor/meta-background-actor.c b/src/compositor/meta-background-actor.c index 32b6007b3..20744587a 100644 --- a/src/compositor/meta-background-actor.c +++ b/src/compositor/meta-background-actor.c @@ -41,20 +41,35 @@ #include #include #include "meta-background-actor-private.h" +#include "meta-cullable.h" struct _MetaBackgroundActorPrivate { cairo_region_t *clip_region; }; -G_DEFINE_TYPE (MetaBackgroundActor, meta_background_actor, CLUTTER_TYPE_ACTOR); +static void cullable_iface_init (MetaCullableInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (MetaBackgroundActor, meta_background_actor, CLUTTER_TYPE_ACTOR, + G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init)); + +static void +set_clip_region (MetaBackgroundActor *self, + cairo_region_t *clip_region) +{ + MetaBackgroundActorPrivate *priv = self->priv; + + g_clear_pointer (&priv->clip_region, (GDestroyNotify) cairo_region_destroy); + if (clip_region) + priv->clip_region = cairo_region_copy (clip_region); +} static void meta_background_actor_dispose (GObject *object) { MetaBackgroundActor *self = META_BACKGROUND_ACTOR (object); - meta_background_actor_set_clip_region (self, NULL); + set_clip_region (self, NULL); G_OBJECT_CLASS (meta_background_actor_parent_class)->dispose (object); } @@ -166,31 +181,27 @@ meta_background_actor_new (void) return CLUTTER_ACTOR (self); } -/** - * meta_background_actor_set_clip_region: - * @self: a #MetaBackgroundActor - * @clip_region: (allow-none): the area of the actor (in allocate-relative - * coordinates) that is visible. - * - * Sets the area of the background that is unobscured by overlapping windows. - * This is used to optimize and only paint the visible portions. - */ -void -meta_background_actor_set_clip_region (MetaBackgroundActor *self, - cairo_region_t *clip_region) +static void +meta_background_actor_cull_out (MetaCullable *cullable, + cairo_region_t *unobscured_region, + cairo_region_t *clip_region) { - MetaBackgroundActorPrivate *priv; + MetaBackgroundActor *self = META_BACKGROUND_ACTOR (cullable); + set_clip_region (self, clip_region); +} - g_return_if_fail (META_IS_BACKGROUND_ACTOR (self)); +static void +meta_background_actor_reset_culling (MetaCullable *cullable) +{ + MetaBackgroundActor *self = META_BACKGROUND_ACTOR (cullable); + set_clip_region (self, NULL); +} - priv = self->priv; - - g_clear_pointer (&priv->clip_region, - (GDestroyNotify) - cairo_region_destroy); - - if (clip_region) - priv->clip_region = cairo_region_copy (clip_region); +static void +cullable_iface_init (MetaCullableInterface *iface) +{ + iface->cull_out = meta_background_actor_cull_out; + iface->reset_culling = meta_background_actor_reset_culling; } /** diff --git a/src/compositor/meta-background-group-private.h b/src/compositor/meta-background-group-private.h deleted file mode 100644 index 1ee7a6737..000000000 --- a/src/compositor/meta-background-group-private.h +++ /dev/null @@ -1,11 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -#ifndef META_BACKGROUND_GROUP_PRIVATE_H -#define META_BACKGROUND_GROUP_PRIVATE_H - -#include -#include - -void meta_background_group_set_clip_region (MetaBackgroundGroup *self, - cairo_region_t *visible_region); -#endif /* META_BACKGROUND_GROUP_PRIVATE_H */ diff --git a/src/compositor/meta-background-group.c b/src/compositor/meta-background-group.c index 092dd1889..2ff01d3d9 100644 --- a/src/compositor/meta-background-group.c +++ b/src/compositor/meta-background-group.c @@ -16,12 +16,13 @@ #include -#include "compositor-private.h" -#include "clutter-utils.h" -#include "meta-background-actor-private.h" -#include "meta-background-group-private.h" +#include +#include "meta-cullable.h" -G_DEFINE_TYPE (MetaBackgroundGroup, meta_background_group, CLUTTER_TYPE_ACTOR); +static void cullable_iface_init (MetaCullableInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (MetaBackgroundGroup, meta_background_group, CLUTTER_TYPE_ACTOR, + G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init)); static void meta_background_group_class_init (MetaBackgroundGroupClass *klass) @@ -29,43 +30,29 @@ meta_background_group_class_init (MetaBackgroundGroupClass *klass) } static void -meta_background_group_init (MetaBackgroundGroup *self) +meta_background_group_cull_out (MetaCullable *cullable, + cairo_region_t *unobscured_region, + cairo_region_t *clip_region) { + meta_cullable_cull_out_children (cullable, unobscured_region, clip_region); } -/** - * meta_background_group_set_clip_region: - * @self: a #MetaBackgroundGroup - * @region: (allow-none): the parts of the background to paint - * - * Sets the area of the backgrounds that is unobscured by overlapping windows. - * This is used to optimize and only paint the visible portions. - */ -void -meta_background_group_set_clip_region (MetaBackgroundGroup *self, - cairo_region_t *region) +static void +meta_background_group_reset_culling (MetaCullable *cullable) { - ClutterActor *child; - for (child = clutter_actor_get_first_child (CLUTTER_ACTOR (self)); - child != NULL; - child = clutter_actor_get_next_sibling (child)) - { - if (META_IS_BACKGROUND_ACTOR (child)) - { - meta_background_actor_set_clip_region (META_BACKGROUND_ACTOR (child), region); - } - else if (META_IS_BACKGROUND_GROUP (child)) - { - int x, y; + meta_cullable_reset_culling_children (cullable); +} - if (!meta_actor_is_untransformed (child, &x, &y)) - continue; +static void +cullable_iface_init (MetaCullableInterface *iface) +{ + iface->cull_out = meta_background_group_cull_out; + iface->reset_culling = meta_background_group_reset_culling; +} - cairo_region_translate (region, -x, -y); - meta_background_group_set_clip_region (META_BACKGROUND_GROUP (child), region); - cairo_region_translate (region, x, y); - } - } +static void +meta_background_group_init (MetaBackgroundGroup *self) +{ } ClutterActor * diff --git a/src/compositor/meta-cullable.c b/src/compositor/meta-cullable.c new file mode 100644 index 000000000..a139166b5 --- /dev/null +++ b/src/compositor/meta-cullable.c @@ -0,0 +1,191 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* + * Copyright (C) 2013 Red Hat + * + * 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. + * + * Written by: + * Owen Taylor + * Ray Strode + * Jasper St. Pierre + */ + +#include "config.h" +#include "meta-cullable.h" +#include "clutter-utils.h" + +G_DEFINE_INTERFACE (MetaCullable, meta_cullable, CLUTTER_TYPE_ACTOR); + +/** + * SECTION:meta-cullable + * @title: MetaCullable + * @short_description: CPU culling operations for efficient drawing + * + * When we are painting a stack of 5-10 large actors, the standard + * bottom-to-top method of drawing every actor results in a tremendous + * amount of overdraw. If these actors are painting textures like + * windows, it can easily max out the available memory bandwidth on a + * low-end graphics chipset. It's even worse if window textures are + * being accessed over the AGP bus. + * + * #MetaCullable is our solution. The basic technique applied here is to + * do a pre-pass before painting where we walk each actor from top to bottom + * and ask each actor to "cull itself out". We pass in a region it can copy + * to clip its drawing to, and the actor can subtract its fully opaque pixels + * so that actors underneath know not to draw there as well. + */ + +/** + * meta_cullable_cull_out_children: + * @cullable: The #MetaCullable + * @unobscured_region: The unobscured region, as passed into cull_out() + * @clip_region: The clip region, as passed into cull_out() + * + * This is a helper method for actors that want to recurse over their + * child actors, and cull them out. + * + * See #MetaCullable and meta_cullable_cull_out() for more details. + */ +void +meta_cullable_cull_out_children (MetaCullable *cullable, + cairo_region_t *unobscured_region, + cairo_region_t *clip_region) +{ + ClutterActor *actor = CLUTTER_ACTOR (cullable); + ClutterActor *child; + ClutterActorIter iter; + + clutter_actor_iter_init (&iter, actor); + while (clutter_actor_iter_prev (&iter, &child)) + { + int x, y; + + if (!CLUTTER_ACTOR_IS_VISIBLE (child)) + continue; + + /* If an actor has effects applied, then that can change the area + * it paints and the opacity, so we no longer can figure out what + * portion of the actor is obscured and what portion of the screen + * it obscures, so we skip the actor. + * + * This has a secondary beneficial effect: if a ClutterOffscreenEffect + * is applied to an actor, then our clipped redraws interfere with the + * caching of the FBO - even if we only need to draw a small portion + * of the window right now, ClutterOffscreenEffect may use other portions + * of the FBO later. So, skipping actors with effects applied also + * prevents these bugs. + * + * Theoretically, we should check clutter_actor_get_offscreen_redirect() + * as well for the same reason, but omitted for simplicity in the + * hopes that no-one will do that. + */ + if (clutter_actor_has_effects (child)) + continue; + + if (!META_IS_CULLABLE (child)) + continue; + + if (!meta_actor_is_untransformed (child, &x, &y)) + continue; + + /* Temporarily move to the coordinate system of the actor */ + cairo_region_translate (unobscured_region, - x, - y); + cairo_region_translate (clip_region, - x, - y); + + meta_cullable_cull_out (META_CULLABLE (child), unobscured_region, clip_region); + + cairo_region_translate (unobscured_region, x, y); + cairo_region_translate (clip_region, x, y); + } +} + +/** + * meta_cullable_reset_culling_children: + * @cullable: The #MetaCullable + * + * This is a helper method for actors that want to recurse over their + * child actors, and cull them out. + * + * See #MetaCullable and meta_cullable_reset_culling() for more details. + */ +void +meta_cullable_reset_culling_children (MetaCullable *cullable) +{ + ClutterActor *actor = CLUTTER_ACTOR (cullable); + ClutterActor *child; + ClutterActorIter iter; + + clutter_actor_iter_init (&iter, actor); + while (clutter_actor_iter_next (&iter, &child)) + { + if (!META_IS_CULLABLE (child)) + continue; + + meta_cullable_reset_culling (META_CULLABLE (child)); + } +} + +static void +meta_cullable_default_init (MetaCullableInterface *iface) +{ +} + +/** + * meta_cullable_cull_out: + * @cullable: The #MetaCullable + * @unobscured_region: The unobscured region, in @cullable's space. + * @clip_region: The clip region, in @cullable's space. + * + * When #MetaWindowGroup is painted, we walk over its direct cullable + * children from top to bottom and ask themselves to "cull out". Cullables + * can use @unobscured_region and @clip_region to clip their drawing. Actors + * interested in eliminating overdraw should copy the @clip_region and only + * paint those parts, as everything else has been obscured by actors above it. + * + * Actors that may have fully opaque parts should also subtract out a region + * that is fully opaque from @unobscured_region and @clip_region. + * + * @unobscured_region and @clip_region are extremely similar. The difference + * is that @clip_region starts off with the stage's clip, if Clutter detects + * that we're doing a clipped redraw. @unobscured_region, however, starts off + * with the full stage size, so actors that may want to record what parts of + * their window are unobscured for e.g. scheduling repaints can do so. + * + * Actors that have children can also use the meta_cullable_cull_out_children() + * helper method to do a simple cull across all their children. + */ +void +meta_cullable_cull_out (MetaCullable *cullable, + cairo_region_t *unobscured_region, + cairo_region_t *clip_region) +{ + META_CULLABLE_GET_IFACE (cullable)->cull_out (cullable, unobscured_region, clip_region); +} + +/** + * meta_cullable_reset_culling: + * @cullable: The #MetaCullable + * + * Actors that copied data in their cull_out() implementation can now + * reset their data, as the paint is now over. Additional paints may be + * done by #ClutterClone or similar, and they should not be affected by + * the culling operation. + */ +void +meta_cullable_reset_culling (MetaCullable *cullable) +{ + META_CULLABLE_GET_IFACE (cullable)->reset_culling (cullable); +} diff --git a/src/compositor/meta-cullable.h b/src/compositor/meta-cullable.h new file mode 100644 index 000000000..5a8c215f1 --- /dev/null +++ b/src/compositor/meta-cullable.h @@ -0,0 +1,68 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2013 Red Hat + * + * 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. + * + * Written by: + * Owen Taylor + * Ray Strode + * Jasper St. Pierre + */ + +#ifndef __META_CULLABLE_H__ +#define __META_CULLABLE_H__ + +#include + +G_BEGIN_DECLS + +#define META_TYPE_CULLABLE (meta_cullable_get_type ()) +#define META_CULLABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_CULLABLE, MetaCullable)) +#define META_IS_CULLABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_CULLABLE)) +#define META_CULLABLE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), META_TYPE_CULLABLE, MetaCullableInterface)) + +typedef struct _MetaCullable MetaCullable; +typedef struct _MetaCullableInterface MetaCullableInterface; + +struct _MetaCullableInterface +{ + GTypeInterface g_iface; + + void (* cull_out) (MetaCullable *cullable, + cairo_region_t *unobscured_region, + cairo_region_t *clip_region); + void (* reset_culling) (MetaCullable *cullable); +}; + +GType meta_cullable_get_type (void); + +void meta_cullable_cull_out (MetaCullable *cullable, + cairo_region_t *unobscured_region, + cairo_region_t *clip_region); +void meta_cullable_reset_culling (MetaCullable *cullable); + +/* Utility methods for implementations */ +void meta_cullable_cull_out_children (MetaCullable *cullable, + cairo_region_t *unobscured_region, + cairo_region_t *clip_region); +void meta_cullable_reset_culling_children (MetaCullable *cullable); + +G_END_DECLS + +#endif /* __META_CULLABLE_H__ */ + diff --git a/src/compositor/meta-window-actor-private.h b/src/compositor/meta-window-actor-private.h index 2b9cb4138..e37d8e81e 100644 --- a/src/compositor/meta-window-actor-private.h +++ b/src/compositor/meta-window-actor-private.h @@ -67,11 +67,6 @@ void meta_window_actor_set_updates_frozen (MetaWindowActor *self, void meta_window_actor_queue_frame_drawn (MetaWindowActor *self, gboolean no_delay_frame); -void meta_window_actor_cull_out (MetaWindowActor *self, - cairo_region_t *unobscured_region, - cairo_region_t *clip_region); -void meta_window_actor_reset_culling (MetaWindowActor *self); - void meta_window_actor_set_unobscured_region (MetaWindowActor *self, cairo_region_t *unobscured_region); diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 1bbb2255f..bc4fc9cb5 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -35,6 +35,7 @@ #include "region-utils.h" #include "meta-wayland-private.h" #include "monitor-private.h" +#include "meta-cullable.h" enum { POSITION_CHANGED, @@ -202,7 +203,10 @@ static void do_send_frame_timings (MetaWindowActor *self, gint refresh_interval, gint64 presentation_time); -G_DEFINE_TYPE (MetaWindowActor, meta_window_actor, CLUTTER_TYPE_ACTOR); +static void cullable_iface_init (MetaCullableInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (MetaWindowActor, meta_window_actor, CLUTTER_TYPE_ACTOR, + G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init)); static void frame_data_free (FrameData *frame) @@ -1951,11 +1955,13 @@ meta_window_actor_set_clip_region_beneath (MetaWindowActor *self, } } -void -meta_window_actor_cull_out (MetaWindowActor *self, - cairo_region_t *unobscured_region, - cairo_region_t *clip_region) +static void +meta_window_actor_cull_out (MetaCullable *cullable, + cairo_region_t *unobscured_region, + cairo_region_t *clip_region) { + MetaWindowActor *self = META_WINDOW_ACTOR (cullable); + if (!meta_is_wayland_compositor ()) { MetaCompScreen *info = meta_screen_get_compositor_data (self->priv->screen); @@ -1981,22 +1987,23 @@ meta_window_actor_cull_out (MetaWindowActor *self, meta_window_actor_set_clip_region_beneath (self, clip_region); } -/** - * meta_window_actor_reset_culling: - * @self: a #MetaWindowActor - * - * Unsets the regions set by meta_window_actor_set_clip_region() and - * meta_window_actor_set_clip_region_beneath() - */ -void -meta_window_actor_reset_culling (MetaWindowActor *self) +static void +meta_window_actor_reset_culling (MetaCullable *cullable) { + MetaWindowActor *self = META_WINDOW_ACTOR (cullable); MetaWindowActorPrivate *priv = self->priv; meta_surface_actor_set_clip_region (priv->surface, NULL); g_clear_pointer (&priv->shadow_clip, cairo_region_destroy); } +static void +cullable_iface_init (MetaCullableInterface *iface) +{ + iface->cull_out = meta_window_actor_cull_out; + iface->reset_culling = meta_window_actor_reset_culling; +} + /* When running as a wayland compositor we don't make requests for * replacement pixmaps when resizing windows, we will instead be * asked to attach replacement buffers by the clients. */ diff --git a/src/compositor/meta-window-group.c b/src/compositor/meta-window-group.c index be1b54462..f76b2e0a5 100644 --- a/src/compositor/meta-window-group.c +++ b/src/compositor/meta-window-group.c @@ -11,9 +11,8 @@ #include "compositor-private.h" #include "meta-window-actor-private.h" #include "meta-window-group.h" -#include "meta-background-actor-private.h" -#include "meta-background-group-private.h" #include "window-private.h" +#include "meta-cullable.h" struct _MetaWindowGroupClass { @@ -27,7 +26,10 @@ struct _MetaWindowGroup MetaScreen *screen; }; -G_DEFINE_TYPE (MetaWindowGroup, meta_window_group, CLUTTER_TYPE_ACTOR); +static void cullable_iface_init (MetaCullableInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (MetaWindowGroup, meta_window_group, CLUTTER_TYPE_ACTOR, + G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init)); /* Help macros to scale from OpenGL <-1,1> coordinates system to * window coordinates ranging [0,window-size]. Borrowed from clutter-utils.c @@ -88,101 +90,24 @@ painting_untransformed (MetaWindowGroup *window_group, } static void -meta_window_group_cull_out (MetaWindowGroup *group, - cairo_region_t *unobscured_region, - cairo_region_t *clip_region) +meta_window_group_cull_out (MetaCullable *cullable, + cairo_region_t *unobscured_region, + cairo_region_t *clip_region) { - ClutterActor *actor = CLUTTER_ACTOR (group); - ClutterActor *child; - - /* We walk the list from top to bottom (opposite of painting order), - * and subtract the opaque area of each window out of the visible - * region that we pass to the windows below. - */ - clutter_actor_iter_init (&iter, actor); - while (clutter_actor_iter_prev (&iter, &child)) - { - if (!CLUTTER_ACTOR_IS_VISIBLE (child)) - continue; - - /* If an actor has effects applied, then that can change the area - * it paints and the opacity, so we no longer can figure out what - * portion of the actor is obscured and what portion of the screen - * it obscures, so we skip the actor. - * - * This has a secondary beneficial effect: if a ClutterOffscreenEffect - * is applied to an actor, then our clipped redraws interfere with the - * caching of the FBO - even if we only need to draw a small portion - * of the window right now, ClutterOffscreenEffect may use other portions - * of the FBO later. So, skipping actors with effects applied also - * prevents these bugs. - * - * Theoretically, we should check clutter_actor_get_offscreen_redirect() - * as well for the same reason, but omitted for simplicity in the - * hopes that no-one will do that. - */ - if (clutter_actor_has_effects (child)) - continue; - - if (META_IS_WINDOW_ACTOR (child)) - { - int x, y; - - if (!meta_actor_is_untransformed (child, &x, &y)) - continue; - - /* Temporarily move to the coordinate system of the actor */ - cairo_region_translate (unobscured_region, - x, - y); - cairo_region_translate (clip_region, - x, - y); - - meta_window_actor_cull_out (META_WINDOW_ACTOR (child), unobscured_region, clip_region); - - cairo_region_translate (unobscured_region, x, y); - cairo_region_translate (clip_region, x, y); - } - else if (META_IS_BACKGROUND_ACTOR (child) || - META_IS_BACKGROUND_GROUP (child)) - { - int x, y; - - if (!meta_actor_is_untransformed (child, &x, &y)) - continue; - - cairo_region_translate (clip_region, - x, - y); - - if (META_IS_BACKGROUND_GROUP (child)) - meta_background_group_set_clip_region (META_BACKGROUND_GROUP (child), clip_region); - else - meta_background_actor_set_clip_region (META_BACKGROUND_ACTOR (child), clip_region); - cairo_region_translate (clip_region, x, y); - } - } + meta_cullable_cull_out_children (cullable, unobscured_region, clip_region); } static void -meta_window_group_reset_culling (MetaWindowGroup *group) +meta_window_group_reset_culling (MetaCullable *cullable) { - ClutterActor *actor = CLUTTER_ACTOR (group); - ClutterActor *child; - ClutterActorIter iter; + meta_cullable_reset_culling_children (cullable); +} - /* Now that we are done painting, unset the visible regions (they will - * mess up painting clones of our actors) - */ - clutter_actor_iter_init (&iter, actor); - while (clutter_actor_iter_next (&iter, &child)) - { - if (META_IS_WINDOW_ACTOR (child)) - { - MetaWindowActor *window_actor = META_WINDOW_ACTOR (child); - meta_window_actor_reset_culling (window_actor); - } - else if (META_IS_BACKGROUND_ACTOR (child)) - { - MetaBackgroundActor *background_actor = META_BACKGROUND_ACTOR (child); - meta_background_actor_set_clip_region (background_actor, NULL); - } - } +static void +cullable_iface_init (MetaCullableInterface *iface) +{ + iface->cull_out = meta_window_group_cull_out; + iface->reset_culling = meta_window_group_reset_culling; } static void @@ -267,14 +192,14 @@ meta_window_group_paint (ClutterActor *actor) } } - meta_window_group_cull_out (window_group, unobscured_region, clip_region); + meta_cullable_cull_out (META_CULLABLE (window_group), unobscured_region, clip_region); cairo_region_destroy (unobscured_region); cairo_region_destroy (clip_region); CLUTTER_ACTOR_CLASS (meta_window_group_parent_class)->paint (actor); - meta_window_group_reset_culling (window_group); + meta_cullable_reset_culling (META_CULLABLE (window_group)); } static gboolean diff --git a/src/compositor/meta-window-group.h b/src/compositor/meta-window-group.h index 1c3eebf5c..d624ac68c 100644 --- a/src/compositor/meta-window-group.h +++ b/src/compositor/meta-window-group.h @@ -11,29 +11,9 @@ * MetaWindowGroup: * * This class is a subclass of ClutterActor with special handling for - * MetaWindowActor/MetaBackgroundActor/MetaBackgroundGroup when painting - * children. - * - * When we are painting a stack of 5-10 maximized windows, the - * standard bottom-to-top method of drawing every actor results in a - * tremendous amount of overdraw and can easily max out the available - * memory bandwidth on a low-end graphics chipset. It's even worse if - * window textures are being accessed over the AGP bus. - * - * The basic technique applied here is to do a pre-pass before painting - * where we walk window from top to bottom and compute the visible area - * at each step by subtracting out the windows above it. The visible - * area is passed to MetaWindowActor which uses it to clip the portion of - * the window which drawn and avoid redrawing the shadow if it is completely - * obscured. - * - * A caveat is that this is ineffective if applications are using ARGB - * visuals, since we have no way of knowing whether a window obscures - * the windows behind it or not. Alternate approaches using the depth - * or stencil buffer rather than client side regions might be able to - * handle alpha windows, but the combination of glAlphaFunc and stenciling - * tends not to be efficient except on newer cards. (And on newer cards - * we have lots of memory and bandwidth.) + * #MetaCullable when painting children. It uses code similar to + * meta_cullable_cull_out_children(), but also has additional special + * cases for the undirected window, and similar. */ #define META_TYPE_WINDOW_GROUP (meta_window_group_get_type ()) From d3bc7570d04c825343c5b0087f681b5381d9e56e Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 25 Nov 2013 17:18:22 -0500 Subject: [PATCH 300/889] window-actor: Update the shape region when the surface actor changes size --- src/compositor/meta-window-actor.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index bc4fc9cb5..dc352a5c2 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -375,6 +375,7 @@ surface_allocation_changed_notify (ClutterActor *actor, MetaWindowActor *self) { meta_window_actor_sync_actor_geometry (self, FALSE); + meta_window_actor_update_shape (self); g_signal_emit (self, signals[SIZE_CHANGED], 0); } From 57866fb2677c7bf436ed2a27ae74c7bb0ad0ea19 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 25 Nov 2013 15:46:06 -0500 Subject: [PATCH 301/889] wayland-surface: Don't rewrite input/opaque regions if the client doesn't attach any --- src/wayland/meta-wayland-surface.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 597ee03d7..f5007cf81 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -319,8 +319,11 @@ meta_wayland_surface_commit (struct wl_client *client, surface->pending.dx, surface->pending.dy); } - meta_window_set_opaque_region (surface->window, surface->pending.opaque_region); - meta_window_set_input_region (surface->window, surface->pending.input_region); + if (surface->pending.opaque_region) + meta_window_set_opaque_region (surface->window, surface->pending.opaque_region); + if (surface->pending.input_region) + meta_window_set_input_region (surface->window, surface->pending.input_region); + surface_process_damage (surface, surface->pending.damage); } From 4780f74a4043346c098940a1fdb2eb855b8fe63b Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 25 Nov 2013 16:03:25 -0500 Subject: [PATCH 302/889] wayland-surface: Properly allow setting the cursor to a NULL buffer --- src/wayland/meta-wayland-seat.c | 6 +++++- src/wayland/meta-wayland-surface.c | 16 ++++++++-------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c index 012cd00bf..9b853e13d 100644 --- a/src/wayland/meta-wayland-seat.c +++ b/src/wayland/meta-wayland-seat.c @@ -68,7 +68,11 @@ meta_wayland_seat_update_sprite (MetaWaylandSeat *seat) if (seat->cursor_tracker == NULL) return; - buffer = seat->sprite->buffer_ref.buffer->resource; + if (seat->sprite->buffer_ref.buffer) + buffer = seat->sprite->buffer_ref.buffer->resource; + else + buffer = NULL; + meta_cursor_tracker_set_window_cursor (seat->cursor_tracker, buffer, seat->hotspot_x, diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index f5007cf81..ebc215444 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -243,6 +243,9 @@ ensure_buffer_texture (MetaWaylandBuffer *buffer) CoglError *catch_error = NULL; CoglTexture *texture; + if (!buffer) + return; + texture = COGL_TEXTURE (cogl_wayland_texture_2d_new_from_buffer (ctx, buffer->resource, &catch_error)); @@ -277,14 +280,11 @@ meta_wayland_surface_commit (struct wl_client *client, { MetaWaylandBuffer *buffer = surface->pending.buffer; - if (buffer) - { - /* Note: we set this before informing any window-actor since the - * window actor will expect to find the new buffer within the - * surface. */ - ensure_buffer_texture (buffer); - meta_wayland_buffer_reference (&surface->buffer_ref, buffer); - } + /* Note: we set this before informing any window-actor since the + * window actor will expect to find the new buffer within the + * surface. */ + ensure_buffer_texture (buffer); + meta_wayland_buffer_reference (&surface->buffer_ref, buffer); } if (surface == compositor->seat->sprite) From 0ccef8178976d488297f22b9ff0c7d7d3eff929e Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 25 Nov 2013 15:50:05 -0500 Subject: [PATCH 303/889] wayland-surface: Rework flow control for wl_surface_commit --- src/wayland/meta-wayland-surface.c | 112 ++++++++++++++++------------- 1 file changed, 62 insertions(+), 50 deletions(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index ebc215444..deee0212d 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -261,6 +261,66 @@ ensure_buffer_texture (MetaWaylandBuffer *buffer) buffer->height = cogl_texture_get_height (texture); } +static void +cursor_surface_commit (MetaWaylandSurface *surface) +{ + MetaWaylandBuffer *buffer = surface->pending.buffer; + + if (surface->pending.newly_attached && buffer != surface->buffer_ref.buffer) + { + ensure_buffer_texture (buffer); + meta_wayland_buffer_reference (&surface->buffer_ref, buffer); + } + + meta_wayland_seat_update_sprite (surface->compositor->seat); +} + +static void +toplevel_surface_commit (MetaWaylandSurface *surface) +{ + MetaWindow *window = surface->window; + MetaWaylandBuffer *buffer = surface->pending.buffer; + + /* wl_surface.attach */ + if (surface->pending.newly_attached && buffer != surface->buffer_ref.buffer) + { + ensure_buffer_texture (buffer); + meta_wayland_buffer_reference (&surface->buffer_ref, buffer); + + meta_window_set_surface_mapped (window, buffer != NULL); + + if (buffer != NULL) + { + MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); + + meta_window_actor_attach_wayland_buffer (window_actor, buffer); + + /* We resize X based surfaces according to X events */ + if (window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND) + { + int new_width; + int new_height; + + new_width = surface->buffer_ref.buffer->width; + new_height = surface->buffer_ref.buffer->height; + if (new_width != window->rect.width || + new_height != window->rect.height || + surface->pending.dx != 0 || + surface->pending.dy != 0) + meta_window_move_resize_wayland (window, new_width, new_height, + surface->pending.dx, surface->pending.dy); + } + } + } + + surface_process_damage (surface, surface->pending.damage); + + if (surface->pending.opaque_region) + meta_window_set_opaque_region (window, surface->pending.opaque_region); + if (surface->pending.input_region) + meta_window_set_input_region (window, surface->pending.input_region); +} + static void meta_wayland_surface_commit (struct wl_client *client, struct wl_resource *resource) @@ -274,58 +334,10 @@ meta_wayland_surface_commit (struct wl_client *client, compositor = surface->compositor; - /* wl_surface.attach */ - if (surface->pending.newly_attached && - surface->buffer_ref.buffer != surface->pending.buffer) - { - MetaWaylandBuffer *buffer = surface->pending.buffer; - - /* Note: we set this before informing any window-actor since the - * window actor will expect to find the new buffer within the - * surface. */ - ensure_buffer_texture (buffer); - meta_wayland_buffer_reference (&surface->buffer_ref, buffer); - } - if (surface == compositor->seat->sprite) - meta_wayland_seat_update_sprite (compositor->seat); + cursor_surface_commit (surface); else if (surface->window) - { - MetaWindow *window = surface->window; - - meta_window_set_surface_mapped (window, surface->pending.buffer != NULL); - - if (surface->pending.buffer) - { - MetaWaylandBuffer *buffer = surface->pending.buffer; - MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - - meta_window_actor_attach_wayland_buffer (window_actor, buffer); - } - - /* We resize X based surfaces according to X events */ - if (window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND) - { - int new_width; - int new_height; - - new_width = surface->buffer_ref.buffer->width; - new_height = surface->buffer_ref.buffer->height; - if (new_width != window->rect.width || - new_height != window->rect.height || - surface->pending.dx != 0 || - surface->pending.dy != 0) - meta_window_move_resize_wayland (surface->window, new_width, new_height, - surface->pending.dx, surface->pending.dy); - } - - if (surface->pending.opaque_region) - meta_window_set_opaque_region (surface->window, surface->pending.opaque_region); - if (surface->pending.input_region) - meta_window_set_input_region (surface->window, surface->pending.input_region); - - surface_process_damage (surface, surface->pending.damage); - } + toplevel_surface_commit (surface); if (surface->pending.buffer) { From 1011331cafc725ffded2223f4f8333799fd980bb Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 25 Nov 2013 15:27:48 -0500 Subject: [PATCH 304/889] cullable: Use relative actor coordinates for culling This ensures that nested cullables work fine. --- src/compositor/clutter-utils.c | 6 ++++-- src/compositor/meta-cullable.c | 6 ++++-- src/compositor/meta-shaped-texture.c | 11 ++--------- 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/compositor/clutter-utils.c b/src/compositor/clutter-utils.c index dd910364b..7bca7c54e 100644 --- a/src/compositor/clutter-utils.c +++ b/src/compositor/clutter-utils.c @@ -95,8 +95,10 @@ meta_actor_vertices_are_untransformed (ClutterVertex *verts, v3x != v1x || v3y != v2y) return FALSE; - *x_origin = x; - *y_origin = y; + if (x_origin) + *x_origin = x; + if (y_origin) + *y_origin = y; return TRUE; } diff --git a/src/compositor/meta-cullable.c b/src/compositor/meta-cullable.c index a139166b5..691014052 100644 --- a/src/compositor/meta-cullable.c +++ b/src/compositor/meta-cullable.c @@ -71,7 +71,7 @@ meta_cullable_cull_out_children (MetaCullable *cullable, clutter_actor_iter_init (&iter, actor); while (clutter_actor_iter_prev (&iter, &child)) { - int x, y; + float x, y; if (!CLUTTER_ACTOR_IS_VISIBLE (child)) continue; @@ -98,9 +98,11 @@ meta_cullable_cull_out_children (MetaCullable *cullable, if (!META_IS_CULLABLE (child)) continue; - if (!meta_actor_is_untransformed (child, &x, &y)) + if (!meta_actor_is_untransformed (child, NULL, NULL)) continue; + clutter_actor_get_position (child, &x, &y); + /* Temporarily move to the coordinate system of the actor */ cairo_region_translate (unobscured_region, - x, - y); cairo_region_translate (clip_region, - x, - y); diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c index 546204250..6f6422dd2 100644 --- a/src/compositor/meta-shaped-texture.c +++ b/src/compositor/meta-shaped-texture.c @@ -301,15 +301,8 @@ meta_shaped_texture_paint (ClutterActor *actor) 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 (!clutter_actor_is_in_clone_paint (actor) && meta_actor_is_untransformed (actor, NULL, NULL)) + filter = COGL_PIPELINE_FILTER_NEAREST; ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ()); fb = cogl_get_draw_framebuffer (); From a27744503b7235d02870481ec16e1b420dbfb9e0 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 21 Nov 2013 16:25:20 -0500 Subject: [PATCH 305/889] shaped-texture: Make Cullable Make MetaWindowActor chain up to the generic default MetaCullable implementation, and remove the helper methods for MetaSurfaceActor and MetaShapedTexture. --- src/compositor/meta-shaped-texture.c | 86 ++++++++++++++---------- src/compositor/meta-surface-actor.c | 34 +++++++--- src/compositor/meta-surface-actor.h | 3 - src/compositor/meta-window-actor.c | 98 ++++------------------------ src/meta/meta-shaped-texture.h | 3 - 5 files changed, 90 insertions(+), 134 deletions(-) diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c index 6f6422dd2..9a5e18386 100644 --- a/src/compositor/meta-shaped-texture.c +++ b/src/compositor/meta-shaped-texture.c @@ -39,6 +39,7 @@ #include #include #include /* for gdk_rectangle_intersect() */ +#include "meta-cullable.h" static void meta_shaped_texture_dispose (GObject *object); @@ -58,7 +59,10 @@ static void meta_shaped_texture_get_preferred_height (ClutterActor *self, static gboolean meta_shaped_texture_get_paint_volume (ClutterActor *self, ClutterPaintVolume *volume); -G_DEFINE_TYPE (MetaShapedTexture, meta_shaped_texture, CLUTTER_TYPE_ACTOR); +static void cullable_iface_init (MetaCullableInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (MetaShapedTexture, meta_shaped_texture, CLUTTER_TYPE_ACTOR, + G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init)); #define META_SHAPED_TEXTURE_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), META_TYPE_SHAPED_TEXTURE, \ @@ -111,6 +115,17 @@ meta_shaped_texture_init (MetaShapedTexture *self) priv->create_mipmaps = TRUE; } +static void +set_clip_region (MetaShapedTexture *self, + cairo_region_t *clip_region) +{ + MetaShapedTexturePrivate *priv = self->priv; + + g_clear_pointer (&priv->clip_region, (GDestroyNotify) cairo_region_destroy); + if (clip_region) + priv->clip_region = cairo_region_copy (clip_region); +} + static void meta_shaped_texture_dispose (GObject *object) { @@ -125,7 +140,7 @@ meta_shaped_texture_dispose (GObject *object) g_clear_pointer (&priv->opaque_region, cairo_region_destroy); meta_shaped_texture_set_mask_texture (self, NULL); - meta_shaped_texture_set_clip_region (self, NULL); + set_clip_region (self, NULL); G_OBJECT_CLASS (meta_shaped_texture_parent_class)->dispose (object); } @@ -761,39 +776,6 @@ meta_shaped_texture_set_input_shape_region (MetaShapedTexture *stex, clutter_actor_queue_redraw (CLUTTER_ACTOR (stex)); } -/** - * meta_shaped_texture_set_clip_region: - * @stex: a #MetaShapedTexture - * @clip_region: the region of the texture that is visible and - * should be painted. - * - * Provides a hint to the texture about what areas of the texture - * are not completely obscured and thus need to be painted. This - * is an optimization and is not supposed to have any effect on - * the output. - * - * Typically a parent container will set the clip region before - * painting its children, and then unset it afterwards. - */ -void -meta_shaped_texture_set_clip_region (MetaShapedTexture *stex, - cairo_region_t *clip_region) -{ - MetaShapedTexturePrivate *priv; - - g_return_if_fail (META_IS_SHAPED_TEXTURE (stex)); - - priv = stex->priv; - - if (priv->clip_region) - cairo_region_destroy (priv->clip_region); - - if (clip_region) - priv->clip_region = cairo_region_copy (clip_region); - else - priv->clip_region = NULL; -} - /** * meta_shaped_texture_set_opaque_region: * @stex: a #MetaShapedTexture @@ -922,6 +904,40 @@ meta_shaped_texture_get_image (MetaShapedTexture *stex, return surface; } +static void +meta_shaped_texture_cull_out (MetaCullable *cullable, + cairo_region_t *unobscured_region, + cairo_region_t *clip_region) +{ + MetaShapedTexture *self = META_SHAPED_TEXTURE (cullable); + MetaShapedTexturePrivate *priv = self->priv; + + set_clip_region (self, clip_region); + + if (clutter_actor_get_paint_opacity (CLUTTER_ACTOR (self)) == 0xff) + { + if (priv->opaque_region) + { + cairo_region_subtract (unobscured_region, priv->opaque_region); + cairo_region_subtract (clip_region, priv->opaque_region); + } + } +} + +static void +meta_shaped_texture_reset_culling (MetaCullable *cullable) +{ + MetaShapedTexture *self = META_SHAPED_TEXTURE (cullable); + set_clip_region (self, NULL); +} + +static void +cullable_iface_init (MetaCullableInterface *iface) +{ + iface->cull_out = meta_shaped_texture_cull_out; + iface->reset_culling = meta_shaped_texture_reset_culling; +} + ClutterActor * meta_shaped_texture_new (void) { diff --git a/src/compositor/meta-surface-actor.c b/src/compositor/meta-surface-actor.c index 690cd87c7..af599607b 100644 --- a/src/compositor/meta-surface-actor.c +++ b/src/compositor/meta-surface-actor.c @@ -15,6 +15,7 @@ #include #include #include "meta-surface-actor.h" +#include "meta-cullable.h" #include "meta-shaped-texture-private.h" @@ -24,7 +25,10 @@ struct _MetaSurfaceActorPrivate MetaWaylandBuffer *buffer; }; -G_DEFINE_TYPE (MetaSurfaceActor, meta_surface_actor, CLUTTER_TYPE_ACTOR); +static void cullable_iface_init (MetaCullableInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (MetaSurfaceActor, meta_surface_actor, CLUTTER_TYPE_ACTOR, + G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init)); static void meta_surface_actor_class_init (MetaSurfaceActorClass *klass) @@ -32,6 +36,27 @@ meta_surface_actor_class_init (MetaSurfaceActorClass *klass) g_type_class_add_private (klass, sizeof (MetaSurfaceActorPrivate)); } +static void +meta_surface_actor_cull_out (MetaCullable *cullable, + cairo_region_t *unobscured_region, + cairo_region_t *clip_region) +{ + meta_cullable_cull_out_children (cullable, unobscured_region, clip_region); +} + +static void +meta_surface_actor_reset_culling (MetaCullable *cullable) +{ + meta_cullable_reset_culling_children (cullable); +} + +static void +cullable_iface_init (MetaCullableInterface *iface) +{ + iface->cull_out = meta_surface_actor_cull_out; + iface->reset_culling = meta_surface_actor_reset_culling; +} + static void meta_surface_actor_init (MetaSurfaceActor *self) { @@ -71,13 +96,6 @@ meta_surface_actor_get_texture (MetaSurfaceActor *self) return self->priv->texture; } -void -meta_surface_actor_set_clip_region (MetaSurfaceActor *self, - cairo_region_t *clip_region) -{ - meta_shaped_texture_set_clip_region (self->priv->texture, clip_region); -} - static void update_area (MetaSurfaceActor *self, int x, int y, int width, int height) diff --git a/src/compositor/meta-surface-actor.h b/src/compositor/meta-surface-actor.h index a02ea3ce6..287b230a3 100644 --- a/src/compositor/meta-surface-actor.h +++ b/src/compositor/meta-surface-actor.h @@ -43,9 +43,6 @@ cairo_surface_t *meta_surface_actor_get_image (MetaSurfaceActor *self, MetaShapedTexture *meta_surface_actor_get_texture (MetaSurfaceActor *self); -void meta_surface_actor_set_clip_region (MetaSurfaceActor *self, - cairo_region_t *clip_region); - gboolean meta_surface_actor_damage_all (MetaSurfaceActor *self, cairo_region_t *unobscured_region); diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index dc352a5c2..44ec25367 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -74,11 +74,6 @@ struct _MetaWindowActorPrivate /* A region that matches the shape of the window, including frame bounds */ cairo_region_t *shape_region; - /* If the window has an input shape, a region that matches the shape */ - cairo_region_t *input_region; - /* The opaque region, from _NET_WM_OPAQUE_REGION, intersected with - * the shape region. */ - cairo_region_t *opaque_region; /* The region we should clip to when painting the shadow */ cairo_region_t *shadow_clip; @@ -447,10 +442,9 @@ meta_window_actor_constructed (GObject *object) meta_window_actor_update_opacity (self); - /* Start off with empty regions to maintain the invariant that - these regions are always set */ + /* Start off with an empty shape region to maintain the invariant + * that it's always set */ priv->shape_region = cairo_region_create (); - priv->input_region = cairo_region_create (); } static void @@ -482,8 +476,6 @@ meta_window_actor_dispose (GObject *object) g_clear_pointer (&priv->unobscured_region, cairo_region_destroy); g_clear_pointer (&priv->shape_region, cairo_region_destroy); - g_clear_pointer (&priv->input_region, cairo_region_destroy); - g_clear_pointer (&priv->opaque_region, cairo_region_destroy); g_clear_pointer (&priv->shadow_clip, cairo_region_destroy); g_clear_pointer (&priv->shadow_class, g_free); @@ -1805,38 +1797,6 @@ meta_window_actor_unmapped (MetaWindowActor *self) } } -/** - * meta_window_actor_get_obscured_region: - * @self: a #MetaWindowActor - * - * Gets the region that is completely obscured by the window. Coordinates - * are relative to the upper-left of the window. - * - * Return value: (transfer none): the area obscured by the window, - * %NULL is the same as an empty region. - */ -static cairo_region_t * -meta_window_actor_get_obscured_region (MetaWindowActor *self) -{ - MetaWindowActorPrivate *priv = self->priv; - - if (!priv->window->shaded) - { - if (meta_is_wayland_compositor ()) - { - if (priv->opacity == 0xff) - return priv->opaque_region; - } - else - { - if (priv->back_pixmap && priv->opacity == 0xff) - return priv->opaque_region; - } - } - - return NULL; -} - #if 0 /* Print out a region; useful for debugging */ static void @@ -1886,8 +1846,6 @@ see_region (cairo_region_t *region, * * Provides a hint as to what areas of the window need to queue * redraws when damaged. Regions not in @unobscured_region are completely obscured. - * Unlike meta_window_actor_set_clip_region(), the region here - * doesn't take into account any clipping that is in effect while drawing. */ void meta_window_actor_set_unobscured_region (MetaWindowActor *self, @@ -1904,26 +1862,6 @@ meta_window_actor_set_unobscured_region (MetaWindowActor *self, priv->unobscured_region = NULL; } -/** - * meta_window_actor_set_clip_region: - * @self: a #MetaWindowActor - * @clip_region: the region of the screen that isn't completely - * obscured. - * - * Provides a hint as to what areas of the window need to be - * drawn. Regions not in @clip_region are completely obscured or - * not drawn in this frame. - * This will be set before painting then unset afterwards. - */ -static void -meta_window_actor_set_clip_region (MetaWindowActor *self, - cairo_region_t *clip_region) -{ - MetaWindowActorPrivate *priv = self->priv; - - meta_surface_actor_set_clip_region (priv->surface, clip_region); -} - /** * meta_window_actor_set_clip_region_beneath: * @self: a #MetaWindowActor @@ -1973,18 +1911,7 @@ meta_window_actor_cull_out (MetaCullable *cullable, } meta_window_actor_set_unobscured_region (self, unobscured_region); - meta_window_actor_set_clip_region (self, clip_region); - - if (clutter_actor_get_paint_opacity (CLUTTER_ACTOR (self)) == 0xff) - { - cairo_region_t *obscured_region = meta_window_actor_get_obscured_region (self); - if (obscured_region) - { - cairo_region_subtract (unobscured_region, obscured_region); - cairo_region_subtract (clip_region, obscured_region); - } - } - + meta_cullable_cull_out_children (cullable, unobscured_region, clip_region); meta_window_actor_set_clip_region_beneath (self, clip_region); } @@ -1994,8 +1921,9 @@ meta_window_actor_reset_culling (MetaCullable *cullable) MetaWindowActor *self = META_WINDOW_ACTOR (cullable); MetaWindowActorPrivate *priv = self->priv; - meta_surface_actor_set_clip_region (priv->surface, NULL); g_clear_pointer (&priv->shadow_clip, cairo_region_destroy); + + meta_cullable_reset_culling_children (cullable); } static void @@ -2468,13 +2396,12 @@ meta_window_actor_update_opaque_region (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; MetaShapedTexture *stex; + cairo_region_t *opaque_region; stex = meta_surface_actor_get_texture (priv->surface); if (!stex) return; - g_clear_pointer (&priv->opaque_region, cairo_region_destroy); - if (priv->argb32 && priv->window->opaque_region != NULL) { MetaFrameBorders borders; @@ -2491,16 +2418,17 @@ meta_window_actor_update_opaque_region (MetaWindowActor *self) * to be undefined, and considered a client bug. In mutter's * case, graphical glitches will occur. */ - priv->opaque_region = cairo_region_copy (priv->window->opaque_region); - cairo_region_translate (priv->opaque_region, borders.total.left, borders.total.top); - cairo_region_intersect (priv->opaque_region, priv->shape_region); + opaque_region = cairo_region_copy (priv->window->opaque_region); + cairo_region_translate (opaque_region, borders.total.left, borders.total.top); + cairo_region_intersect (opaque_region, priv->shape_region); } else if (priv->argb32) - priv->opaque_region = NULL; + opaque_region = NULL; else - priv->opaque_region = cairo_region_reference (priv->shape_region); + opaque_region = cairo_region_reference (priv->shape_region); - meta_shaped_texture_set_opaque_region (stex, priv->opaque_region); + meta_shaped_texture_set_opaque_region (stex, opaque_region); + cairo_region_destroy (opaque_region); } static void diff --git a/src/meta/meta-shaped-texture.h b/src/meta/meta-shaped-texture.h index c7091d705..dac4ccc25 100644 --- a/src/meta/meta-shaped-texture.h +++ b/src/meta/meta-shaped-texture.h @@ -81,9 +81,6 @@ void meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex, void meta_shaped_texture_set_input_shape_region (MetaShapedTexture *stex, cairo_region_t *shape_region); -void meta_shaped_texture_set_clip_region (MetaShapedTexture *stex, - cairo_region_t *clip_region); - void meta_shaped_texture_set_opaque_region (MetaShapedTexture *stex, cairo_region_t *opaque_region); From 025ab35af7c22f97d29539f3d1c6793c88fd9061 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 21 Nov 2013 17:45:05 -0500 Subject: [PATCH 306/889] surface-actor: Add setters for set_input_region / set_opaque_region Subsurfaces won't have a MetaWindow or MetaWindowActor to fetch these from, so they need to be tied directly to the MetaSurfaceActor. --- src/compositor/meta-surface-actor.c | 14 ++++++++++++++ src/compositor/meta-surface-actor.h | 4 ++++ src/compositor/meta-window-actor.c | 13 ++----------- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/compositor/meta-surface-actor.c b/src/compositor/meta-surface-actor.c index af599607b..b046d239f 100644 --- a/src/compositor/meta-surface-actor.c +++ b/src/compositor/meta-surface-actor.c @@ -164,3 +164,17 @@ meta_surface_actor_set_texture (MetaSurfaceActor *self, { meta_shaped_texture_set_texture (self->priv->texture, texture); } + +void +meta_surface_actor_set_input_region (MetaSurfaceActor *self, + cairo_region_t *region) +{ + meta_shaped_texture_set_input_shape_region (self->priv->texture, region); +} + +void +meta_surface_actor_set_opaque_region (MetaSurfaceActor *self, + cairo_region_t *region) +{ + meta_shaped_texture_set_opaque_region (self->priv->texture, region); +} diff --git a/src/compositor/meta-surface-actor.h b/src/compositor/meta-surface-actor.h index 287b230a3..45284f6f2 100644 --- a/src/compositor/meta-surface-actor.h +++ b/src/compositor/meta-surface-actor.h @@ -57,6 +57,10 @@ void meta_surface_actor_set_texture (MetaSurfaceActor *self, CoglTexture *texture); void meta_surface_actor_attach_wayland_buffer (MetaSurfaceActor *self, MetaWaylandBuffer *buffer); +void meta_surface_actor_set_input_region (MetaSurfaceActor *self, + cairo_region_t *region); +void meta_surface_actor_set_opaque_region (MetaSurfaceActor *self, + cairo_region_t *region); G_END_DECLS diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 44ec25367..7a3b78653 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -2357,12 +2357,8 @@ meta_window_actor_update_input_region (MetaWindowActor *self, cairo_rectangle_int_t *client_area) { MetaWindowActorPrivate *priv = self->priv; - MetaShapedTexture *stex = meta_surface_actor_get_texture (priv->surface); cairo_region_t *region = NULL; - if (!stex) - return; - if (priv->window->frame != NULL && priv->window->input_region != NULL) { region = meta_frame_get_frame_bounds (priv->window->frame); @@ -2387,7 +2383,7 @@ meta_window_actor_update_input_region (MetaWindowActor *self, region = cairo_region_create_rectangle (client_area); } - meta_shaped_texture_set_input_shape_region (stex, region); + meta_surface_actor_set_input_region (priv->surface, region); cairo_region_destroy (region); } @@ -2395,13 +2391,8 @@ static void meta_window_actor_update_opaque_region (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; - MetaShapedTexture *stex; cairo_region_t *opaque_region; - stex = meta_surface_actor_get_texture (priv->surface); - if (!stex) - return; - if (priv->argb32 && priv->window->opaque_region != NULL) { MetaFrameBorders borders; @@ -2427,7 +2418,7 @@ meta_window_actor_update_opaque_region (MetaWindowActor *self) else opaque_region = cairo_region_reference (priv->shape_region); - meta_shaped_texture_set_opaque_region (stex, opaque_region); + meta_surface_actor_set_opaque_region (priv->surface, opaque_region); cairo_region_destroy (opaque_region); } From 304005e04f1dcb783cebe766fb17493090d7c867 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 22 Nov 2013 15:24:06 -0500 Subject: [PATCH 307/889] wayland-surface: Replace MetaWindowActor with MetaSurfaceActor Since subsurfaces won't have toplevel MetaWindowActors, we need to use MetaSurfaceActor instead. These are embedded in the MetaWindowActor, just like MetaShapedTexture was (in fact, MetaSurfaceActor now contains a MetaShapedTexture) --- src/compositor/meta-surface-actor.c | 1 + src/compositor/meta-surface-actor.h | 2 +- src/compositor/meta-window-actor-private.h | 8 ---- src/compositor/meta-window-actor.c | 43 +++++----------------- src/wayland/meta-wayland-surface.c | 26 ++++++------- src/wayland/meta-wayland-surface.h | 2 + 6 files changed, 25 insertions(+), 57 deletions(-) diff --git a/src/compositor/meta-surface-actor.c b/src/compositor/meta-surface-actor.c index b046d239f..6697ff1b2 100644 --- a/src/compositor/meta-surface-actor.c +++ b/src/compositor/meta-surface-actor.c @@ -15,6 +15,7 @@ #include #include #include "meta-surface-actor.h" +#include "meta-wayland-private.h" #include "meta-cullable.h" #include "meta-shaped-texture-private.h" diff --git a/src/compositor/meta-surface-actor.h b/src/compositor/meta-surface-actor.h index 45284f6f2..484877b73 100644 --- a/src/compositor/meta-surface-actor.h +++ b/src/compositor/meta-surface-actor.h @@ -6,7 +6,7 @@ #include #include -#include "meta-wayland-private.h" +#include "meta-wayland-types.h" G_BEGIN_DECLS diff --git a/src/compositor/meta-window-actor-private.h b/src/compositor/meta-window-actor-private.h index e37d8e81e..82326d29b 100644 --- a/src/compositor/meta-window-actor-private.h +++ b/src/compositor/meta-window-actor-private.h @@ -31,14 +31,6 @@ void meta_window_actor_unmaximize (MetaWindowActor *self, void meta_window_actor_process_x11_damage (MetaWindowActor *self, XDamageNotifyEvent *event); -void meta_window_actor_process_wayland_damage (MetaWindowActor *self, - int x, - int y, - int width, - int height); -void meta_window_actor_attach_wayland_buffer (MetaWindowActor *self, - MetaWaylandBuffer *buffer); - void meta_window_actor_pre_paint (MetaWindowActor *self); void meta_window_actor_post_paint (MetaWindowActor *self); void meta_window_actor_frame_complete (MetaWindowActor *self, diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 7a3b78653..6df5a36d6 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -409,6 +409,9 @@ meta_window_actor_constructed (GObject *object) { priv->surface = meta_surface_actor_new (); + if (window->surface) + window->surface->surface_actor = priv->surface; + clutter_actor_add_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface)); priv->surface_allocation_changed_id = @@ -2149,30 +2152,6 @@ meta_window_actor_process_x11_damage (MetaWindowActor *self, } -void -meta_window_actor_process_wayland_damage (MetaWindowActor *self, - int x, - int y, - int width, - int height) -{ - MetaWindowActorPrivate *priv = self->priv; - cairo_region_t *unobscured_region; - gboolean redraw_queued; - - if (!priv->mapped) - return; - - unobscured_region = - clutter_actor_has_mapped_clones (CLUTTER_ACTOR (priv->surface)) - ? NULL : priv->unobscured_region; - redraw_queued = meta_surface_actor_damage_area (priv->surface, - x, y, width, height, - unobscured_region); - - priv->repaint_scheduled = priv->repaint_scheduled || redraw_queued; -} - void meta_window_actor_sync_visibility (MetaWindowActor *self) { @@ -2446,8 +2425,12 @@ check_needs_reshape (MetaWindowActor *self) client_area.height = priv->window->rect.height; meta_window_actor_update_shape_region (self, &client_area); - meta_window_actor_update_input_region (self, &client_area); - meta_window_actor_update_opaque_region (self); + + if (priv->window->client_type == META_WINDOW_CLIENT_TYPE_X11) + { + meta_window_actor_update_input_region (self, &client_area); + meta_window_actor_update_opaque_region (self); + } priv->needs_reshape = FALSE; } @@ -2465,14 +2448,6 @@ meta_window_actor_update_shape (MetaWindowActor *self) clutter_actor_queue_redraw (CLUTTER_ACTOR (priv->surface)); } -void -meta_window_actor_attach_wayland_buffer (MetaWindowActor *self, - MetaWaylandBuffer *buffer) -{ - MetaWindowActorPrivate *priv = self->priv; - meta_surface_actor_attach_wayland_buffer (priv->surface, buffer); -} - static void meta_window_actor_handle_updates (MetaWindowActor *self) { diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index deee0212d..f6335f8ad 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -44,7 +44,7 @@ #include "meta-wayland-private.h" #include "meta-xwayland-private.h" #include "meta-wayland-stage.h" -#include "meta-window-actor-private.h" +#include "meta-surface-actor.h" #include "meta-wayland-seat.h" #include "meta-wayland-keyboard.h" #include "meta-wayland-pointer.h" @@ -67,8 +67,6 @@ surface_process_damage (MetaWaylandSurface *surface, if (surface->buffer_ref.buffer) { - MetaWindowActor *window_actor = - META_WINDOW_ACTOR (meta_window_get_compositor_private (surface->window)); MetaRectangle rect; cairo_rectangle_int_t cairo_rect; @@ -80,7 +78,7 @@ surface_process_damage (MetaWaylandSurface *surface, cairo_region_intersect_rectangle (region, &cairo_rect); - if (window_actor) + if (surface->surface_actor) { int i, n_rectangles = cairo_region_num_rectangles (region); @@ -90,11 +88,12 @@ surface_process_damage (MetaWaylandSurface *surface, cairo_region_get_rectangle (region, i, &rectangle); - meta_window_actor_process_wayland_damage (window_actor, - rectangle.x, - rectangle.y, - rectangle.width, - rectangle.height); + meta_surface_actor_damage_area (surface->surface_actor, + rectangle.x, + rectangle.y, + rectangle.width, + rectangle.height, + NULL); } } } @@ -278,6 +277,7 @@ cursor_surface_commit (MetaWaylandSurface *surface) static void toplevel_surface_commit (MetaWaylandSurface *surface) { + MetaSurfaceActor *surface_actor = surface->surface_actor; MetaWindow *window = surface->window; MetaWaylandBuffer *buffer = surface->pending.buffer; @@ -291,9 +291,7 @@ toplevel_surface_commit (MetaWaylandSurface *surface) if (buffer != NULL) { - MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - - meta_window_actor_attach_wayland_buffer (window_actor, buffer); + meta_surface_actor_attach_wayland_buffer (surface_actor, buffer); /* We resize X based surfaces according to X events */ if (window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND) @@ -316,9 +314,9 @@ toplevel_surface_commit (MetaWaylandSurface *surface) surface_process_damage (surface, surface->pending.damage); if (surface->pending.opaque_region) - meta_window_set_opaque_region (window, surface->pending.opaque_region); + meta_surface_actor_set_opaque_region (surface_actor, surface->pending.opaque_region); if (surface->pending.input_region) - meta_window_set_input_region (window, surface->pending.input_region); + meta_surface_actor_set_input_region (surface_actor, surface->pending.input_region); } static void diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h index 25b493927..4edab8770 100644 --- a/src/wayland/meta-wayland-surface.h +++ b/src/wayland/meta-wayland-surface.h @@ -29,6 +29,7 @@ #include #include "meta-wayland-types.h" +#include "meta-surface-actor.h" struct _MetaWaylandBuffer { @@ -77,6 +78,7 @@ struct _MetaWaylandSurface struct wl_resource *resource; MetaWaylandCompositor *compositor; MetaWaylandBufferReference buffer_ref; + MetaSurfaceActor *surface_actor; MetaWindow *window; MetaWaylandSurfaceExtension xdg_surface; MetaWaylandSurfaceExtension xdg_popup; From 644f3e1275934e254f3037a5ea356af82c470dfa Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 25 Nov 2013 17:24:22 -0500 Subject: [PATCH 308/889] window: Make setters for shape/input/opaque regions private again Wayland now pushes these to the surface actor rather than the toplevel MetaWindow... --- src/core/window-private.h | 8 -------- src/core/window.c | 6 +++--- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/src/core/window-private.h b/src/core/window-private.h index d67af673b..0f1630adb 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -713,16 +713,8 @@ void meta_window_compute_tile_match (MetaWindow *window); gboolean meta_window_updates_are_frozen (MetaWindow *window); -void meta_window_set_opaque_region (MetaWindow *window, - cairo_region_t *region); void meta_window_update_opaque_region_x11 (MetaWindow *window); - -void meta_window_set_input_region (MetaWindow *window, - cairo_region_t *region); void meta_window_update_input_region_x11 (MetaWindow *window); - -void meta_window_set_shape_region (MetaWindow *window, - cairo_region_t *region); void meta_window_update_shape_region_x11 (MetaWindow *window); void meta_window_set_title (MetaWindow *window, diff --git a/src/core/window.c b/src/core/window.c index 622168a36..d2c3ef73f 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -8004,7 +8004,7 @@ meta_window_update_net_wm_type (MetaWindow *window) meta_window_recalc_window_type (window); } -void +static void meta_window_set_opaque_region (MetaWindow *window, cairo_region_t *region) { @@ -8090,7 +8090,7 @@ region_create_from_x_rectangles (const XRectangle *rects, return cairo_region_create_rectangles (cairo_rects, n_rects); } -void +static void meta_window_set_input_region (MetaWindow *window, cairo_region_t *region) { @@ -8175,7 +8175,7 @@ meta_window_update_input_region_x11 (MetaWindow *window) cairo_region_destroy (region); } -void +static void meta_window_set_shape_region (MetaWindow *window, cairo_region_t *region) { From 52b48cfbef880fd3f7da3f83d7b3fa9ca287d058 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 25 Nov 2013 18:15:03 -0500 Subject: [PATCH 309/889] wayland-surface: Return after posting errors back to the client --- src/wayland/meta-wayland-surface.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index f6335f8ad..5edb6feff 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -767,9 +767,12 @@ get_xdg_surface (struct wl_client *client, META_XDG_SURFACE_VERSION, &xdg_surface_interface, &meta_wayland_xdg_surface_interface)) - wl_resource_post_error (surface_resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "xdg_shell::get_xdg_surface already requested"); + { + wl_resource_post_error (surface_resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "xdg_shell::get_xdg_surface already requested"); + return; + } surface->window = meta_window_new_for_wayland (meta_get_display (), surface); } @@ -823,9 +826,12 @@ get_xdg_popup (struct wl_client *client, META_XDG_POPUP_VERSION, &xdg_popup_interface, &meta_wayland_xdg_popup_interface)) - wl_resource_post_error (surface_resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "xdg_shell::get_xdg_surface already requested"); + { + wl_resource_post_error (surface_resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "xdg_shell::get_xdg_surface already requested"); + return; + } surface->window = meta_window_new_for_wayland (meta_get_display (), surface); surface->window->type = META_WINDOW_DROPDOWN_MENU; @@ -894,9 +900,12 @@ get_gtk_surface (struct wl_client *client, META_GTK_SURFACE_VERSION, >k_surface_interface, &meta_wayland_gtk_surface_interface)) - wl_resource_post_error (surface_resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "gtk_shell::get_gtk_surface already requested"); + { + wl_resource_post_error (surface_resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "gtk_shell::get_gtk_surface already requested"); + return; + } } static const struct gtk_shell_interface meta_wayland_gtk_shell_interface = { From ea1b8cdc220438ffd6d434e577535eb1e5f696d0 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 25 Nov 2013 18:15:19 -0500 Subject: [PATCH 310/889] wayland-surface: Fix copy/paste typo --- src/wayland/meta-wayland-surface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 5edb6feff..7ee6f21e3 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -829,7 +829,7 @@ get_xdg_popup (struct wl_client *client, { wl_resource_post_error (surface_resource, WL_DISPLAY_ERROR_INVALID_OBJECT, - "xdg_shell::get_xdg_surface already requested"); + "xdg_shell::get_xdg_popup already requested"); return; } From 7841042a85361923ecfe0100456fca33cace6559 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 25 Nov 2013 17:35:44 -0500 Subject: [PATCH 311/889] wayland-surface: Restructure code flow in wl_surface_attach a bit more... --- src/compositor/meta-surface-actor.c | 6 +++++- src/wayland/meta-wayland-surface.c | 33 ++++++++++++----------------- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/src/compositor/meta-surface-actor.c b/src/compositor/meta-surface-actor.c index 6697ff1b2..ff71b4618 100644 --- a/src/compositor/meta-surface-actor.c +++ b/src/compositor/meta-surface-actor.c @@ -156,7 +156,11 @@ meta_surface_actor_attach_wayland_buffer (MetaSurfaceActor *self, { MetaSurfaceActorPrivate *priv = self->priv; priv->buffer = buffer; - meta_shaped_texture_set_texture (self->priv->texture, buffer->texture); + + if (buffer) + meta_shaped_texture_set_texture (self->priv->texture, buffer->texture); + else + meta_shaped_texture_set_texture (self->priv->texture, NULL); } void diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 7ee6f21e3..23b816e90 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -286,33 +286,28 @@ toplevel_surface_commit (MetaWaylandSurface *surface) { ensure_buffer_texture (buffer); meta_wayland_buffer_reference (&surface->buffer_ref, buffer); + meta_surface_actor_attach_wayland_buffer (surface_actor, buffer); + surface_process_damage (surface, surface->pending.damage); meta_window_set_surface_mapped (window, buffer != NULL); - if (buffer != NULL) + /* We resize X based surfaces according to X events */ + if (buffer != NULL && window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND) { - meta_surface_actor_attach_wayland_buffer (surface_actor, buffer); + int new_width; + int new_height; - /* We resize X based surfaces according to X events */ - if (window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND) - { - int new_width; - int new_height; - - new_width = surface->buffer_ref.buffer->width; - new_height = surface->buffer_ref.buffer->height; - if (new_width != window->rect.width || - new_height != window->rect.height || - surface->pending.dx != 0 || - surface->pending.dy != 0) - meta_window_move_resize_wayland (window, new_width, new_height, - surface->pending.dx, surface->pending.dy); - } + new_width = surface->buffer_ref.buffer->width; + new_height = surface->buffer_ref.buffer->height; + if (new_width != window->rect.width || + new_height != window->rect.height || + surface->pending.dx != 0 || + surface->pending.dy != 0) + meta_window_move_resize_wayland (window, new_width, new_height, + surface->pending.dx, surface->pending.dy); } } - surface_process_damage (surface, surface->pending.damage); - if (surface->pending.opaque_region) meta_surface_actor_set_opaque_region (surface_actor, surface->pending.opaque_region); if (surface->pending.input_region) From f9a2c644602962cb4e399b3eac4644d677f3ad97 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 25 Nov 2013 17:40:21 -0500 Subject: [PATCH 312/889] wayland-surface: Don't require a MetaWindow to process damage... and ClutterActor will clip to the actor bounds, anyway... --- src/wayland/meta-wayland-surface.c | 41 ++++++++---------------------- 1 file changed, 10 insertions(+), 31 deletions(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 23b816e90..39dc2bbb7 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -63,39 +63,18 @@ static void surface_process_damage (MetaWaylandSurface *surface, cairo_region_t *region) { - g_assert (surface->window); + int i, n_rectangles = cairo_region_num_rectangles (region); - if (surface->buffer_ref.buffer) + for (i = 0; i < n_rectangles; i++) { - MetaRectangle rect; - cairo_rectangle_int_t cairo_rect; - - meta_window_get_input_rect (surface->window, &rect); - cairo_rect.x = 0; - cairo_rect.y = 0; - cairo_rect.width = rect.width; - cairo_rect.height = rect.height; - - cairo_region_intersect_rectangle (region, &cairo_rect); - - if (surface->surface_actor) - { - int i, n_rectangles = cairo_region_num_rectangles (region); - - for (i = 0; i < n_rectangles; i++) - { - cairo_rectangle_int_t rectangle; - - cairo_region_get_rectangle (region, i, &rectangle); - - meta_surface_actor_damage_area (surface->surface_actor, - rectangle.x, - rectangle.y, - rectangle.width, - rectangle.height, - NULL); - } - } + cairo_rectangle_int_t rect; + cairo_region_get_rectangle (region, i, &rect); + meta_surface_actor_damage_area (surface->surface_actor, + rect.x, + rect.y, + rect.width, + rect.height, + NULL); } } From 5089a63d7662df97aa370b2ff0ad2dfd51d3ef90 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 25 Nov 2013 18:25:48 -0500 Subject: [PATCH 313/889] wayland-surface: Create the surface actor ourselves Otherwise, we can't rely on a surface_actor being around to add ourselves to... --- src/compositor/meta-window-actor.c | 16 ++++------------ src/wayland/meta-wayland-surface.c | 1 + 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 6df5a36d6..ab260fa21 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -407,10 +407,11 @@ meta_window_actor_constructed (GObject *object) if (!priv->surface) { - priv->surface = meta_surface_actor_new (); - if (window->surface) - window->surface->surface_actor = priv->surface; + priv->surface = window->surface->surface_actor; + else + priv->surface = meta_surface_actor_new (); + g_object_ref_sink (priv->surface); clutter_actor_add_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface)); @@ -420,15 +421,6 @@ meta_window_actor_constructed (GObject *object) G_CALLBACK (surface_allocation_changed_notify), self); - /* - * Since we are holding a pointer to this actor independently of the - * ClutterContainer internals, and provide a public API to access it, - * add a reference here, so that if someone is messing about with us - * via the container interface, we do not end up with a dangling pointer. - * We will release it in dispose(). - */ - g_object_ref (priv->surface); - g_signal_connect_object (window, "notify::decorated", G_CALLBACK (window_decorated_notify), self, 0); g_signal_connect_object (window, "notify::appears-focused", diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 39dc2bbb7..b2c4c907d 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -450,6 +450,7 @@ meta_wayland_surface_create (MetaWaylandCompositor *compositor, surface_handle_pending_buffer_destroy; wl_list_init (&surface->pending.frame_callback_list); + surface->surface_actor = meta_surface_actor_new (); return surface; } From a9424255a52fe22656cae5f3f96307f9b9ffa570 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 25 Nov 2013 16:26:02 -0500 Subject: [PATCH 314/889] wayland-surface: Add support for subsurfaces The state for a subsurface isn't double-buffered yet, though... --- src/wayland/meta-wayland-surface.c | 183 ++++++++++++++++++++++++++-- src/wayland/meta-wayland-surface.h | 1 + src/wayland/meta-wayland-versions.h | 2 + 3 files changed, 178 insertions(+), 8 deletions(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index b2c4c907d..2a2402a0f 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -253,12 +253,12 @@ cursor_surface_commit (MetaWaylandSurface *surface) meta_wayland_seat_update_sprite (surface->compositor->seat); } -static void -toplevel_surface_commit (MetaWaylandSurface *surface) +static gboolean +actor_surface_commit (MetaWaylandSurface *surface) { MetaSurfaceActor *surface_actor = surface->surface_actor; - MetaWindow *window = surface->window; MetaWaylandBuffer *buffer = surface->pending.buffer; + gboolean changed = FALSE; /* wl_surface.attach */ if (surface->pending.newly_attached && buffer != surface->buffer_ref.buffer) @@ -267,9 +267,26 @@ toplevel_surface_commit (MetaWaylandSurface *surface) meta_wayland_buffer_reference (&surface->buffer_ref, buffer); meta_surface_actor_attach_wayland_buffer (surface_actor, buffer); surface_process_damage (surface, surface->pending.damage); + changed = TRUE; + } + + if (surface->pending.opaque_region) + meta_surface_actor_set_opaque_region (surface_actor, surface->pending.opaque_region); + if (surface->pending.input_region) + meta_surface_actor_set_input_region (surface_actor, surface->pending.input_region); + + return changed; +} + +static void +toplevel_surface_commit (MetaWaylandSurface *surface) +{ + if (actor_surface_commit (surface)) + { + MetaWindow *window = surface->window; + MetaWaylandBuffer *buffer = surface->pending.buffer; meta_window_set_surface_mapped (window, buffer != NULL); - /* We resize X based surfaces according to X events */ if (buffer != NULL && window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND) { @@ -286,11 +303,27 @@ toplevel_surface_commit (MetaWaylandSurface *surface) surface->pending.dx, surface->pending.dy); } } +} - if (surface->pending.opaque_region) - meta_surface_actor_set_opaque_region (surface_actor, surface->pending.opaque_region); - if (surface->pending.input_region) - meta_surface_actor_set_input_region (surface_actor, surface->pending.input_region); +static void +subsurface_surface_commit (MetaWaylandSurface *surface) +{ + if (actor_surface_commit (surface)) + { + MetaSurfaceActor *surface_actor = surface->surface_actor; + MetaWaylandBuffer *buffer = surface->pending.buffer; + float x, y; + + if (buffer != NULL) + clutter_actor_show (CLUTTER_ACTOR (surface_actor)); + else + clutter_actor_hide (CLUTTER_ACTOR (surface_actor)); + + clutter_actor_get_position (CLUTTER_ACTOR (surface_actor), &x, &y); + x += surface->pending.dx; + y += surface->pending.dy; + clutter_actor_set_position (CLUTTER_ACTOR (surface_actor), x, y); + } } static void @@ -310,6 +343,8 @@ meta_wayland_surface_commit (struct wl_client *client, cursor_surface_commit (surface); else if (surface->window) toplevel_surface_commit (surface); + else if (surface->subsurface.resource) + subsurface_surface_commit (surface); if (surface->pending.buffer) { @@ -903,6 +938,132 @@ bind_gtk_shell (struct wl_client *client, gtk_shell_send_capabilities (resource, GTK_SHELL_CAPABILITY_GLOBAL_APP_MENU); } +static void +wl_subsurface_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static void +wl_subsurface_set_position (struct wl_client *client, + struct wl_resource *resource, + int32_t x, + int32_t y) +{ + MetaWaylandSurfaceExtension *subsurface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = wl_container_of (subsurface, surface, subsurface); + + clutter_actor_set_position (CLUTTER_ACTOR (surface->surface_actor), x, y); +} + +static void +wl_subsurface_place_above (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *sibling_resource) +{ + ClutterActor *parent_actor; + MetaWaylandSurfaceExtension *subsurface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = wl_container_of (subsurface, surface, subsurface); + MetaWaylandSurface *sibling = wl_resource_get_user_data (sibling_resource); + + parent_actor = clutter_actor_get_parent (CLUTTER_ACTOR (surface->surface_actor)); + + clutter_actor_set_child_above_sibling (parent_actor, + CLUTTER_ACTOR (surface->surface_actor), + CLUTTER_ACTOR (sibling->surface_actor)); +} + +static void +wl_subsurface_place_below (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *sibling_resource) +{ + ClutterActor *parent_actor; + MetaWaylandSurfaceExtension *subsurface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = wl_container_of (subsurface, surface, subsurface); + MetaWaylandSurface *sibling = wl_resource_get_user_data (sibling_resource); + + parent_actor = clutter_actor_get_parent (CLUTTER_ACTOR (surface->surface_actor)); + + clutter_actor_set_child_below_sibling (parent_actor, + CLUTTER_ACTOR (surface->surface_actor), + CLUTTER_ACTOR (sibling->surface_actor)); +} + +static void +wl_subsurface_set_sync (struct wl_client *client, + struct wl_resource *resource) +{ + g_warning ("TODO: support wl_subsurface.set_sync"); +} + +static void +wl_subsurface_set_desync (struct wl_client *client, + struct wl_resource *resource) +{ + g_warning ("TODO: support wl_subsurface.set_desync"); +} + +static const struct wl_subsurface_interface meta_wayland_subsurface_interface = { + wl_subsurface_destroy, + wl_subsurface_set_position, + wl_subsurface_place_above, + wl_subsurface_place_below, + wl_subsurface_set_sync, + wl_subsurface_set_desync, +}; + +static void +wl_subcompositor_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static void +wl_subcompositor_get_subsurface (struct wl_client *client, + struct wl_resource *resource, + guint32 id, + struct wl_resource *surface_resource, + struct wl_resource *parent_resource) +{ + MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); + MetaWaylandSurface *parent = wl_resource_get_user_data (parent_resource); + + if (!create_surface_extension (&surface->subsurface, client, surface_resource, resource, id, + META_GTK_SURFACE_VERSION, + &wl_subsurface_interface, + &meta_wayland_subsurface_interface)) + { + wl_resource_post_error (surface_resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "wl_subcompositor::get_subsurface already requested"); + return; + } + + clutter_actor_add_child (CLUTTER_ACTOR (parent->surface_actor), + CLUTTER_ACTOR (surface->surface_actor)); +} + +static const struct wl_subcompositor_interface meta_wayland_subcompositor_interface = { + wl_subcompositor_destroy, + wl_subcompositor_get_subsurface, +}; + +static void +bind_subcompositor (struct wl_client *client, + void *data, + guint32 version, + guint32 id) +{ + struct wl_resource *resource; + + resource = wl_resource_create (client, &wl_subcompositor_interface, + MIN (META_WL_SUBCOMPOSITOR_VERSION, version), id); + wl_resource_set_implementation (resource, &meta_wayland_subcompositor_interface, data, NULL); +} + void meta_wayland_init_shell (MetaWaylandCompositor *compositor) { @@ -917,6 +1078,12 @@ meta_wayland_init_shell (MetaWaylandCompositor *compositor) META_GTK_SHELL_VERSION, compositor, bind_gtk_shell) == NULL) g_error ("Failed to register a global gtk-shell object"); + + if (wl_global_create (compositor->wayland_display, + &wl_subcompositor_interface, + META_WL_SUBCOMPOSITOR_VERSION, + compositor, bind_subcompositor) == NULL) + g_error ("Failed to register a global wl-subcompositor object"); } void diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h index 4edab8770..28dfa1483 100644 --- a/src/wayland/meta-wayland-surface.h +++ b/src/wayland/meta-wayland-surface.h @@ -83,6 +83,7 @@ struct _MetaWaylandSurface MetaWaylandSurfaceExtension xdg_surface; MetaWaylandSurfaceExtension xdg_popup; MetaWaylandSurfaceExtension gtk_surface; + MetaWaylandSurfaceExtension subsurface; /* All the pending state, that wl_surface.commit will apply. */ MetaWaylandDoubleBufferedState pending; diff --git a/src/wayland/meta-wayland-versions.h b/src/wayland/meta-wayland-versions.h index 7e85f8b29..531cbd4b9 100644 --- a/src/wayland/meta-wayland-versions.h +++ b/src/wayland/meta-wayland-versions.h @@ -42,6 +42,7 @@ #define META_XSERVER_VERSION 1 #define META_GTK_SHELL_VERSION 1 #define META_XDG_SHELL_VERSION 1 +#define META_WL_SUBCOMPOSITOR_VERSION 1 /* Slave objects (version inherited from a master object) */ #define META_WL_DATA_OFFER_VERSION 1 /* from wl_data_device */ @@ -55,6 +56,7 @@ #define META_GTK_SURFACE_VERSION 1 /* from gtk_shell */ #define META_XDG_SURFACE_VERSION 1 /* from xdg_shell */ #define META_XDG_POPUP_VERSION 1 /* from xdg_shell */ +#define META_WL_SUBSURFACE_VERSION 1 /* from wl_subcompositor */ /* The first version to implement a specific event */ #define META_WL_SEAT_HAS_NAME 2 From d44574f738765297768c21d0cdaba4c18da23495 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 26 Nov 2013 12:32:41 -0500 Subject: [PATCH 315/889] wayland-surface: Process damage even if the buffer didn't change --- src/wayland/meta-wayland-surface.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 2a2402a0f..81b45fbbf 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -266,10 +266,11 @@ actor_surface_commit (MetaWaylandSurface *surface) ensure_buffer_texture (buffer); meta_wayland_buffer_reference (&surface->buffer_ref, buffer); meta_surface_actor_attach_wayland_buffer (surface_actor, buffer); - surface_process_damage (surface, surface->pending.damage); changed = TRUE; } + surface_process_damage (surface, surface->pending.damage); + if (surface->pending.opaque_region) meta_surface_actor_set_opaque_region (surface_actor, surface->pending.opaque_region); if (surface->pending.input_region) From c46af91d542ce64b38a2b821b6de76088633bdfb Mon Sep 17 00:00:00 2001 From: Rico Tzschichholz Date: Fri, 29 Nov 2013 09:12:16 +0100 Subject: [PATCH 316/889] window: Fix deprecated version of get_outer_rect (cherry picked from commit 59168b2c64565bf1c439a2f2a0bc4103839c3285) --- src/core/window.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/window.c b/src/core/window.c index d2c3ef73f..ba642dc73 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -6201,7 +6201,7 @@ meta_window_get_frame_rect (const MetaWindow *window, * area that we or the client adds to the window, or any area that the * client adds to draw a client-side shadow. * - * Deprecated: 3.10: Use meta_window_get_frame_rect() instead. + * Deprecated: 3.12: Use meta_window_get_frame_rect() instead. */ void meta_window_get_outer_rect (const MetaWindow *window, From 21d8b8310a1e526bc7c71f38a1a9a2b661d1a210 Mon Sep 17 00:00:00 2001 From: Rico Tzschichholz Date: Fri, 29 Nov 2013 13:52:18 +0100 Subject: [PATCH 317/889] window: Proper argument naming for meta_window_client_rect_to_frame_rect (cherry picked from commit 9b88059e55a0d4c8eea89518388116e88dc4c240) --- src/core/window.c | 36 ++++++++++++++++++------------------ src/meta/window.h | 4 ++-- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/core/window.c b/src/core/window.c index ba642dc73..92ffc747a 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -6061,8 +6061,8 @@ meta_window_get_input_rect (const MetaWindow *window, /** * meta_window_client_rect_to_frame_rect: * @window: a #MetaWindow - * @frame_rect: client rectangle in root coordinates - * @client_rect: (out): location to store the computed corresponding frame bounds. + * @client_rect: client rectangle in root coordinates + * @frame_rect: (out): location to store the computed corresponding frame bounds. * * Converts a desired bounds of the client window - what is passed to meta_window_move_resize() - * into the corresponding bounds of the window frame (excluding invisible borders @@ -6070,13 +6070,13 @@ meta_window_get_input_rect (const MetaWindow *window, */ void meta_window_client_rect_to_frame_rect (MetaWindow *window, - MetaRectangle *frame_rect, - MetaRectangle *client_rect) + MetaRectangle *client_rect, + MetaRectangle *frame_rect) { - if (!client_rect) + if (!frame_rect) return; - *client_rect = *frame_rect; + *frame_rect = *client_rect; /* The support for G_MAXINT here to mean infinity is a convenience for * constraints.c:get_size_limits() and not something that we provide @@ -6087,24 +6087,24 @@ meta_window_client_rect_to_frame_rect (MetaWindow *window, MetaFrameBorders borders; meta_frame_calc_borders (window->frame, &borders); - client_rect->x -= borders.visible.left; - client_rect->y -= borders.visible.top; - if (client_rect->width != G_MAXINT) - client_rect->width += borders.visible.left + borders.visible.right; - if (client_rect->height != G_MAXINT) - client_rect->height += borders.visible.top + borders.visible.bottom; + frame_rect->x -= borders.visible.left; + frame_rect->y -= borders.visible.top; + if (frame_rect->width != G_MAXINT) + frame_rect->width += borders.visible.left + borders.visible.right; + if (frame_rect->height != G_MAXINT) + frame_rect->height += borders.visible.top + borders.visible.bottom; } else { if (window->has_custom_frame_extents) { const GtkBorder *extents = &window->custom_frame_extents; - client_rect->x += extents->left; - client_rect->y += extents->top; - if (client_rect->width != G_MAXINT) - client_rect->width -= extents->left + extents->right; - if (client_rect->height != G_MAXINT) - client_rect->height -= extents->top + extents->bottom; + frame_rect->x += extents->left; + frame_rect->y += extents->top; + if (frame_rect->width != G_MAXINT) + frame_rect->width -= extents->left + extents->right; + if (frame_rect->height != G_MAXINT) + frame_rect->height -= extents->top + extents->bottom; } } } diff --git a/src/meta/window.h b/src/meta/window.h index c7ccc358b..d2fb3a740 100644 --- a/src/meta/window.h +++ b/src/meta/window.h @@ -115,8 +115,8 @@ void meta_window_get_frame_rect (const MetaWindow *window, MetaRectangle *rect); void meta_window_get_outer_rect (const MetaWindow *window, MetaRectangle *rect) G_GNUC_DEPRECATED; void meta_window_client_rect_to_frame_rect (MetaWindow *window, - MetaRectangle *frame_rect, - MetaRectangle *client_rect); + MetaRectangle *client_rect, + MetaRectangle *frame_rect); void meta_window_frame_rect_to_client_rect (MetaWindow *window, MetaRectangle *frame_rect, MetaRectangle *client_rect); From 9c5733caf0cbdf73c9c9536ad2e56e6b0d83d366 Mon Sep 17 00:00:00 2001 From: Rico Tzschichholz Date: Fri, 29 Nov 2013 13:53:15 +0100 Subject: [PATCH 318/889] prefs: Properly add new META_KEYBINDING_ACTION_* value In addition to 4373916d9db88c2b6d8b09190cc51e2cfc0f8de4 (cherry picked from commit 3b2506851c7a491fd918fbfea87939601fb7ad25) --- src/meta/prefs.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/meta/prefs.h b/src/meta/prefs.h index 41399684b..3205ea3b4 100644 --- a/src/meta/prefs.h +++ b/src/meta/prefs.h @@ -248,7 +248,6 @@ void meta_prefs_set_ignore_request_hide_titlebar (gboolean whether); * @META_KEYBINDING_ACTION_LOWER: FILLME * @META_KEYBINDING_ACTION_MAXIMIZE_VERTICALLY: FILLME * @META_KEYBINDING_ACTION_MAXIMIZE_HORIZONTALLY: FILLME - * @META_KEYBINDING_ACTION_ALWAYS_ON_TOP: FILLME * @META_KEYBINDING_ACTION_MOVE_TO_CORNER_NW: FILLME * @META_KEYBINDING_ACTION_MOVE_TO_CORNER_NE: FILLME * @META_KEYBINDING_ACTION_MOVE_TO_CORNER_SW: FILLME @@ -259,6 +258,7 @@ void meta_prefs_set_ignore_request_hide_titlebar (gboolean whether); * @META_KEYBINDING_ACTION_MOVE_TO_SIDE_W: FILLME * @META_KEYBINDING_ACTION_MOVE_TO_CENTER: FILLME * @META_KEYBINDING_ACTION_OVERLAY_KEY: FILLME + * @META_KEYBINDING_ACTION_ALWAYS_ON_TOP: FILLME * @META_KEYBINDING_ACTION_LAST: FILLME */ /* XXX FIXME This should be x-macroed, but isn't yet because it would be @@ -340,7 +340,6 @@ typedef enum _MetaKeyBindingAction META_KEYBINDING_ACTION_RAISE, META_KEYBINDING_ACTION_LOWER, META_KEYBINDING_ACTION_MAXIMIZE_VERTICALLY, - META_KEYBINDING_ACTION_ALWAYS_ON_TOP, META_KEYBINDING_ACTION_MAXIMIZE_HORIZONTALLY, META_KEYBINDING_ACTION_MOVE_TO_CORNER_NW, META_KEYBINDING_ACTION_MOVE_TO_CORNER_NE, @@ -353,6 +352,7 @@ typedef enum _MetaKeyBindingAction META_KEYBINDING_ACTION_MOVE_TO_CENTER, META_KEYBINDING_ACTION_OVERLAY_KEY, META_KEYBINDING_ACTION_ISO_NEXT_GROUP, + META_KEYBINDING_ACTION_ALWAYS_ON_TOP, META_KEYBINDING_ACTION_LAST } MetaKeyBindingAction; From 6c12c928df2f21db646380d28f3a79b44c76b385 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 29 Nov 2013 09:42:50 -0500 Subject: [PATCH 319/889] compositor: Update to latest cogl API See https://git.gnome.org/browse/cogl/commit/?id=c76c1d136d2cac7f3d1331a4d1dc0dd0f06e812c https://bugzilla.gnome.org/show_bug.cgi?id=719557 --- src/compositor/meta-surface-actor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compositor/meta-surface-actor.c b/src/compositor/meta-surface-actor.c index ff71b4618..ccc10adcc 100644 --- a/src/compositor/meta-surface-actor.c +++ b/src/compositor/meta-surface-actor.c @@ -111,7 +111,7 @@ update_area (MetaSurfaceActor *self, if (shm_buffer) { CoglTexture2D *texture = COGL_TEXTURE_2D (priv->buffer->texture); - cogl_wayland_texture_2d_update_area (texture, shm_buffer, x, y, width, height); + cogl_wayland_texture_set_region_from_shm_buffer (texture, x, y, width, height, shm_buffer, 0, 0, 0, NULL); } } else From 37ba264190b52c54ebe60824f6868a22b219b8af Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Mon, 2 Dec 2013 16:13:46 +0000 Subject: [PATCH 320/889] compositor: meta-surface-actor: upload texture changes at the correct position https://bugzilla.gnome.org/show_bug.cgi?id=719695 --- src/compositor/meta-surface-actor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compositor/meta-surface-actor.c b/src/compositor/meta-surface-actor.c index ccc10adcc..540c7f49c 100644 --- a/src/compositor/meta-surface-actor.c +++ b/src/compositor/meta-surface-actor.c @@ -111,7 +111,7 @@ update_area (MetaSurfaceActor *self, if (shm_buffer) { CoglTexture2D *texture = COGL_TEXTURE_2D (priv->buffer->texture); - cogl_wayland_texture_set_region_from_shm_buffer (texture, x, y, width, height, shm_buffer, 0, 0, 0, NULL); + cogl_wayland_texture_set_region_from_shm_buffer (texture, x, y, width, height, shm_buffer, x, y, 0, NULL); } } else From 0850da44d734496c873385fb0169f9e891d7edeb Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 26 Nov 2013 12:35:12 -0500 Subject: [PATCH 321/889] shaped-texture: Prevent a critical when setting a NULL cogl texture --- src/compositor/meta-shaped-texture.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c index 9a5e18386..8d45d9bf0 100644 --- a/src/compositor/meta-shaped-texture.c +++ b/src/compositor/meta-shaped-texture.c @@ -227,10 +227,11 @@ set_cogl_texture (MetaShapedTexture *stex, if (priv->texture) cogl_object_unref (priv->texture); - priv->texture = cogl_object_ref (cogl_tex); + priv->texture = cogl_tex; if (cogl_tex != NULL) { + cogl_object_ref (cogl_tex); width = cogl_texture_get_width (COGL_TEXTURE (cogl_tex)); height = cogl_texture_get_height (COGL_TEXTURE (cogl_tex)); From 20e92c5a72aac65b0ca9a36a310169088babe9aa Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Mon, 25 Nov 2013 17:44:07 +0100 Subject: [PATCH 322/889] wayland: Set the clutter stage focus when we focus a window Otherwise clutter events don't have their source actor properly set and we aren't able to determine the MetaWindow to which a given keybinding applies. https://bugzilla.gnome.org/show_bug.cgi?id=719724 --- src/wayland/meta-wayland.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index 061aa0e60..3d1961a81 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -210,10 +210,13 @@ meta_wayland_compositor_set_input_focus (MetaWaylandCompositor *compositor, MetaWindow *window) { MetaWaylandSurface *surface = window ? window->surface : NULL; + ClutterActor *window_actor = window ? CLUTTER_ACTOR (meta_window_get_compositor_private (window)) : NULL; meta_wayland_keyboard_set_focus (&compositor->seat->keyboard, surface); meta_wayland_data_device_set_keyboard_focus (compositor->seat); + + clutter_stage_set_key_focus (CLUTTER_STAGE (compositor->stage), window_actor); } void From 3f022ca963f2a55d17cec3aa77e63a166b7e98dd Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Tue, 3 Dec 2013 15:47:10 +0100 Subject: [PATCH 323/889] window: Possibly set the pointer focus on newly mapped wayland windows Windows showing up under the pointer must get the pointer focus. https://bugzilla.gnome.org/show_bug.cgi?id=719725 --- src/core/window.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/core/window.c b/src/core/window.c index 92ffc747a..7435c83c1 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -3369,6 +3369,9 @@ meta_window_show (MetaWindow *window) if (did_show) meta_screen_queue_check_fullscreen (window->screen); + if (did_show && window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND) + meta_wayland_compositor_repick (meta_wayland_compositor_get_default ()); + /* * Now that we have shown the window, we no longer want to consider the * initial timestamp in any subsequent deliberations whether to focus this From 461f74ef18ed512e0b77bae3896ef6e881e922de Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Mon, 2 Dec 2013 22:04:44 +0100 Subject: [PATCH 324/889] wayland: Fix setting keyboard/pointer focus for new clients When we have a new client, we potentially set the focus on one of its surfaces when we map it but the client might not have called wl_seat.get_keyboard/pointer yet. When it finally calls get_keyboard/pointer we must then register its resource as the focus_resource which means that we can only return early if focus_resource is already set. https://bugzilla.gnome.org/show_bug.cgi?id=719725 --- src/wayland/meta-wayland-keyboard.c | 2 +- src/wayland/meta-wayland-pointer.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wayland/meta-wayland-keyboard.c b/src/wayland/meta-wayland-keyboard.c index a003ea531..ec769e7f4 100644 --- a/src/wayland/meta-wayland-keyboard.c +++ b/src/wayland/meta-wayland-keyboard.c @@ -501,7 +501,7 @@ meta_wayland_keyboard_set_focus (MetaWaylandKeyboard *keyboard, struct wl_resource *resource; uint32_t serial; - if (keyboard->focus == surface) + if (keyboard->focus == surface && keyboard->focus_resource != NULL) return; resource = keyboard->focus_resource; diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index 9a5680e74..62468727e 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -303,7 +303,7 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer, struct wl_resource *resource, *kr; uint32_t serial; - if (pointer->focus == surface) + if (pointer->focus == surface && pointer->focus_resource != NULL) return; resource = pointer->focus_resource; From 1e211722c7897b50c84a7c870603ab4d77c3cffd Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 3 Dec 2013 10:53:48 -0500 Subject: [PATCH 325/889] wayland-surface: Set popups transient to their parents --- src/wayland/meta-wayland-surface.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 81b45fbbf..d8822cc46 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -850,6 +850,7 @@ get_xdg_popup (struct wl_client *client, surface->window->rect.x = parent_rect.x + x; surface->window->rect.y = parent_rect.y + y; surface->window->placed = TRUE; + meta_window_set_transient_for (surface->window, parent_surf->window); meta_wayland_pointer_start_popup_grab (&seat->pointer, surface); } From b2c18c4a7846bf5e358b18e10b1bb7f2bfa67402 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 3 Dec 2013 10:46:57 -0500 Subject: [PATCH 326/889] Revert "keyboard: Remove focus listener" This reverts commit 0ac142d39e27e2692cbe0b18136a41bee424a6b0. --- src/wayland/meta-wayland-keyboard.c | 17 +++++++++++++++++ src/wayland/meta-wayland-keyboard.h | 1 + 2 files changed, 18 insertions(+) diff --git a/src/wayland/meta-wayland-keyboard.c b/src/wayland/meta-wayland-keyboard.c index ec769e7f4..af164241a 100644 --- a/src/wayland/meta-wayland-keyboard.c +++ b/src/wayland/meta-wayland-keyboard.c @@ -221,6 +221,16 @@ err_keymap_str: return; } +static void +lose_keyboard_focus (struct wl_listener *listener, void *data) +{ + MetaWaylandKeyboard *keyboard = + wl_container_of (listener, keyboard, focus_listener); + + keyboard->focus_resource = NULL; + keyboard->focus = NULL; +} + static gboolean default_grab_key (MetaWaylandKeyboardGrab *grab, uint32_t time, uint32_t key, uint32_t state) @@ -330,6 +340,7 @@ meta_wayland_keyboard_init (MetaWaylandKeyboard *keyboard, wl_list_init (&keyboard->resource_list); wl_array_init (&keyboard->keys); + keyboard->focus_listener.notify = lose_keyboard_focus; keyboard->default_grab.interface = &default_keyboard_grab_interface; keyboard->default_grab.keyboard = keyboard; keyboard->grab = &keyboard->default_grab; @@ -511,6 +522,7 @@ meta_wayland_keyboard_set_focus (MetaWaylandKeyboard *keyboard, struct wl_display *display = wl_client_get_display (client); serial = wl_display_next_serial (display); wl_keyboard_send_leave (resource, serial, keyboard->focus->resource); + wl_list_remove (&keyboard->focus_listener.link); meta_wayland_surface_focused_unset (keyboard->focus); } @@ -545,6 +557,7 @@ meta_wayland_keyboard_set_focus (MetaWaylandKeyboard *keyboard, wl_keyboard_send_enter (resource, serial, surface->resource, &keyboard->keys); } + wl_resource_add_destroy_listener (resource, &keyboard->focus_listener); keyboard->focus_serial = serial; meta_wayland_surface_focused_set (surface); @@ -575,6 +588,10 @@ meta_wayland_keyboard_release (MetaWaylandKeyboard *keyboard) { meta_wayland_xkb_info_destroy (&keyboard->xkb_info); xkb_context_unref (keyboard->xkb_context); + + /* XXX: What about keyboard->resource_list? */ + if (keyboard->focus_resource) + wl_list_remove (&keyboard->focus_listener.link); wl_array_release (&keyboard->keys); } diff --git a/src/wayland/meta-wayland-keyboard.h b/src/wayland/meta-wayland-keyboard.h index f0a793cca..4354faf21 100644 --- a/src/wayland/meta-wayland-keyboard.h +++ b/src/wayland/meta-wayland-keyboard.h @@ -94,6 +94,7 @@ struct _MetaWaylandKeyboard struct wl_list resource_list; MetaWaylandSurface *focus; struct wl_resource *focus_resource; + struct wl_listener focus_listener; uint32_t focus_serial; MetaWaylandKeyboardGrab *grab; From 602307e694dbafcb58f929b1b68b527f77b48118 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 3 Dec 2013 10:50:35 -0500 Subject: [PATCH 327/889] Revert "pointer: Remove focus listener" This reverts commit a8ac2cc27543ef4afe762e8a0675cceef7afdf91. --- src/wayland/meta-wayland-pointer.c | 17 +++++++++++++++++ src/wayland/meta-wayland-pointer.h | 1 + 2 files changed, 18 insertions(+) diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index 62468727e..193cd4d51 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -63,6 +63,16 @@ meta_wayland_pointer_get_seat (MetaWaylandPointer *pointer) return seat; } +static void +lose_pointer_focus (struct wl_listener *listener, void *data) +{ + MetaWaylandPointer *pointer = + wl_container_of (listener, pointer, focus_listener); + + pointer->focus_resource = NULL; + pointer->focus = NULL; +} + static void default_grab_focus (MetaWaylandPointerGrab *grab, MetaWaylandSurface *surface, @@ -257,6 +267,7 @@ meta_wayland_pointer_init (MetaWaylandPointer *pointer, memset (pointer, 0, sizeof *pointer); wl_list_init (&pointer->resource_list); + pointer->focus_listener.notify = lose_pointer_focus; pointer->default_grab.interface = &default_pointer_grab_interface; pointer->default_grab.pointer = pointer; pointer->grab = &pointer->default_grab; @@ -276,6 +287,10 @@ meta_wayland_pointer_init (MetaWaylandPointer *pointer, void meta_wayland_pointer_release (MetaWaylandPointer *pointer) { + /* XXX: What about pointer->resource_list? */ + if (pointer->focus_resource) + wl_list_remove (&pointer->focus_listener.link); + pointer->focus = NULL; pointer->focus_resource = NULL; } @@ -313,6 +328,7 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer, struct wl_display *display = wl_client_get_display (client); serial = wl_display_next_serial (display); wl_pointer_send_leave (resource, serial, pointer->focus->resource); + wl_list_remove (&pointer->focus_listener.link); } resource = find_resource_for_surface (&pointer->resource_list, surface); @@ -345,6 +361,7 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer, wl_fixed_to_int (pointer->x), wl_fixed_to_int (pointer->y)); wl_pointer_send_enter (resource, serial, surface->resource, sx, sy); + wl_resource_add_destroy_listener (resource, &pointer->focus_listener); pointer->focus_serial = serial; } diff --git a/src/wayland/meta-wayland-pointer.h b/src/wayland/meta-wayland-pointer.h index a31d609c4..95a4b5e13 100644 --- a/src/wayland/meta-wayland-pointer.h +++ b/src/wayland/meta-wayland-pointer.h @@ -48,6 +48,7 @@ struct _MetaWaylandPointer struct wl_list resource_list; MetaWaylandSurface *focus; struct wl_resource *focus_resource; + struct wl_listener focus_listener; guint32 focus_serial; guint32 click_serial; From fe26cb59893100c52f34ca323b723b18ea62f215 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 26 Nov 2013 13:04:37 -0500 Subject: [PATCH 328/889] wayland-surface: Unmanage the window when destroying xdg_surface/xdg_popup Also, unparent the actor when destroying a subsurface, as well, and don't free the surface when we destroy the MetaWindow. --- src/core/window.c | 3 - src/wayland/meta-wayland-surface.c | 101 +++++++++++++++++++++++------ src/wayland/meta-wayland-surface.h | 2 - 3 files changed, 82 insertions(+), 24 deletions(-) diff --git a/src/core/window.c b/src/core/window.c index 7435c83c1..5b1490d86 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -2068,9 +2068,6 @@ meta_window_unmanage (MetaWindow *window, else meta_display_unregister_wayland_window (window->display, window); - if (window->surface) - meta_wayland_surface_free (window->surface); - g_slist_free_full (window->pending_pings, (GDestroyNotify) ping_data_free); meta_prefs_remove_listener (prefs_changed_callback, window); diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index d8822cc46..cbad045aa 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -395,7 +395,7 @@ const struct wl_surface_interface meta_wayland_surface_interface = { meta_wayland_surface_set_buffer_scale }; -void +static void meta_wayland_surface_free (MetaWaylandSurface *surface) { MetaWaylandCompositor *compositor = surface->compositor; @@ -416,11 +416,37 @@ meta_wayland_surface_free (MetaWaylandSurface *surface) meta_wayland_compositor_repick (compositor); + g_object_unref (surface->surface_actor); + if (surface->resource) wl_resource_set_user_data (surface->resource, NULL); g_slice_free (MetaWaylandSurface, surface); } +static void +unparent_actor (MetaWaylandSurface *surface) +{ + ClutterActor *parent_actor; + + parent_actor = clutter_actor_get_parent (CLUTTER_ACTOR (surface->surface_actor)); + clutter_actor_remove_child (parent_actor, CLUTTER_ACTOR (surface->surface_actor)); +} + +static void +destroy_window (MetaWaylandSurface *surface) +{ + MetaDisplay *display = meta_get_display (); + guint32 timestamp = meta_display_get_current_time_roundtrip (display); + + /* Remove our actor from the parent, so it doesn't get destroyed when + * the MetaWindowActor is destroyed. */ + unparent_actor (surface); + + g_assert (surface->window != NULL); + meta_window_unmanage (surface->window, timestamp); + surface->window = NULL; +} + static void meta_wayland_surface_resource_destroy_cb (struct wl_resource *resource) { @@ -441,16 +467,10 @@ meta_wayland_surface_resource_destroy_cb (struct wl_resource *resource) /* NB: If the surface corresponds to an X window then we will be * sure to free the MetaWindow according to some X event. */ - if (surface->window && - surface->window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND) - { - MetaDisplay *display = meta_get_display (); - guint32 timestamp = meta_display_get_current_time_roundtrip (display); + if (surface->window && surface->window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND) + destroy_window (surface); - meta_window_unmanage (surface->window, timestamp); - } - else if (!surface->window) - meta_wayland_surface_free (surface); + meta_wayland_surface_free (surface); } } @@ -486,14 +506,13 @@ meta_wayland_surface_create (MetaWaylandCompositor *compositor, surface_handle_pending_buffer_destroy; wl_list_init (&surface->pending.frame_callback_list); - surface->surface_actor = meta_surface_actor_new (); + surface->surface_actor = g_object_ref_sink (meta_surface_actor_new ()); return surface; } static void -destroy_surface_extension (struct wl_resource *resource) +destroy_surface_extension (MetaWaylandSurfaceExtension *extension) { - MetaWaylandSurfaceExtension *extension = wl_resource_get_user_data (resource); wl_list_remove (&extension->surface_destroy_listener.link); extension->surface_destroy_listener.notify = NULL; extension->resource = NULL; @@ -522,7 +541,8 @@ create_surface_extension (MetaWaylandSurfaceExtension *extension, guint32 id, int max_version, const struct wl_interface *interface, - const void *implementation) + const void *implementation, + wl_resource_destroy_func_t destructor) { struct wl_resource *resource; @@ -530,7 +550,7 @@ create_surface_extension (MetaWaylandSurfaceExtension *extension, return FALSE; resource = wl_resource_create (client, interface, get_resource_version (master_resource, max_version), id); - wl_resource_set_implementation (resource, implementation, extension, destroy_surface_extension); + wl_resource_set_implementation (resource, implementation, extension, destructor); extension->resource = resource; extension->surface_destroy_listener.notify = extension_handle_surface_destroy; @@ -538,6 +558,16 @@ create_surface_extension (MetaWaylandSurfaceExtension *extension, return TRUE; } +static void +xdg_surface_destructor (struct wl_resource *resource) +{ + MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface); + + destroy_window (surface); + destroy_surface_extension (xdg_surface); +} + static void xdg_surface_destroy (struct wl_client *client, struct wl_resource *resource) @@ -777,7 +807,8 @@ get_xdg_surface (struct wl_client *client, if (!create_surface_extension (&surface->xdg_surface, client, surface_resource, resource, id, META_XDG_SURFACE_VERSION, &xdg_surface_interface, - &meta_wayland_xdg_surface_interface)) + &meta_wayland_xdg_surface_interface, + xdg_surface_destructor)) { wl_resource_post_error (surface_resource, WL_DISPLAY_ERROR_INVALID_OBJECT, @@ -788,6 +819,16 @@ get_xdg_surface (struct wl_client *client, surface->window = meta_window_new_for_wayland (meta_get_display (), surface); } +static void +xdg_popup_destructor (struct wl_resource *resource) +{ + MetaWaylandSurfaceExtension *xdg_popup = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = wl_container_of (xdg_popup, surface, xdg_popup); + + destroy_window (surface); + destroy_surface_extension (xdg_popup); +} + static void xdg_popup_destroy (struct wl_client *client, struct wl_resource *resource) @@ -836,7 +877,8 @@ get_xdg_popup (struct wl_client *client, if (!create_surface_extension (&surface->xdg_popup, client, surface_resource, resource, id, META_XDG_POPUP_VERSION, &xdg_popup_interface, - &meta_wayland_xdg_popup_interface)) + &meta_wayland_xdg_popup_interface, + xdg_popup_destructor)) { wl_resource_post_error (surface_resource, WL_DISPLAY_ERROR_INVALID_OBJECT, @@ -874,6 +916,15 @@ bind_xdg_shell (struct wl_client *client, wl_resource_set_implementation (resource, &meta_wayland_xdg_shell_interface, data, NULL); } +static void +gtk_surface_destructor (struct wl_resource *resource) +{ + MetaWaylandSurfaceExtension *gtk_surface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = wl_container_of (gtk_surface, surface, gtk_surface); + + destroy_surface_extension (gtk_surface); +} + static void set_dbus_properties (struct wl_client *client, struct wl_resource *resource, @@ -911,7 +962,8 @@ get_gtk_surface (struct wl_client *client, if (!create_surface_extension (&surface->gtk_surface, client, surface_resource, resource, id, META_GTK_SURFACE_VERSION, >k_surface_interface, - &meta_wayland_gtk_surface_interface)) + &meta_wayland_gtk_surface_interface, + gtk_surface_destructor)) { wl_resource_post_error (surface_resource, WL_DISPLAY_ERROR_INVALID_OBJECT, @@ -940,6 +992,16 @@ bind_gtk_shell (struct wl_client *client, gtk_shell_send_capabilities (resource, GTK_SHELL_CAPABILITY_GLOBAL_APP_MENU); } +static void +wl_subsurface_destructor (struct wl_resource *resource) +{ + MetaWaylandSurfaceExtension *subsurface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = wl_container_of (subsurface, surface, subsurface); + + unparent_actor (surface); + destroy_surface_extension (subsurface); +} + static void wl_subsurface_destroy (struct wl_client *client, struct wl_resource *resource) @@ -1036,7 +1098,8 @@ wl_subcompositor_get_subsurface (struct wl_client *client, if (!create_surface_extension (&surface->subsurface, client, surface_resource, resource, id, META_GTK_SURFACE_VERSION, &wl_subsurface_interface, - &meta_wayland_subsurface_interface)) + &meta_wayland_subsurface_interface, + wl_subsurface_destructor)) { wl_resource_post_error (surface_resource, WL_DISPLAY_ERROR_INVALID_OBJECT, diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h index 28dfa1483..9533731a6 100644 --- a/src/wayland/meta-wayland-surface.h +++ b/src/wayland/meta-wayland-surface.h @@ -95,8 +95,6 @@ MetaWaylandSurface *meta_wayland_surface_create (MetaWaylandCompositor *composit struct wl_client *client, guint32 id, guint32 version); -void meta_wayland_surface_free (MetaWaylandSurface *surface); - void meta_wayland_surface_configure_notify (MetaWaylandSurface *surface, int width, int height, From 2746608eb22529d5f91d633c483f3e1701e5877e Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 3 Dec 2013 14:32:21 -0500 Subject: [PATCH 329/889] background-actor: Remove custom get_paint_volume The paint volume should be based on what we paint, not what the content wants to be painted as. Thus, it should be the allocation. --- src/compositor/meta-background-actor.c | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/src/compositor/meta-background-actor.c b/src/compositor/meta-background-actor.c index 20744587a..b5270c5eb 100644 --- a/src/compositor/meta-background-actor.c +++ b/src/compositor/meta-background-actor.c @@ -119,26 +119,6 @@ meta_background_actor_get_preferred_height (ClutterActor *actor, *natural_height_p = height; } -static gboolean -meta_background_actor_get_paint_volume (ClutterActor *actor, - ClutterPaintVolume *volume) -{ - ClutterContent *content; - gfloat width, height; - - content = clutter_actor_get_content (actor); - - if (!content) - return FALSE; - - clutter_content_get_preferred_size (content, &width, &height); - - clutter_paint_volume_set_width (volume, width); - clutter_paint_volume_set_height (volume, height); - - return TRUE; -} - static void meta_background_actor_class_init (MetaBackgroundActorClass *klass) { @@ -151,7 +131,6 @@ meta_background_actor_class_init (MetaBackgroundActorClass *klass) actor_class->get_preferred_width = meta_background_actor_get_preferred_width; actor_class->get_preferred_height = meta_background_actor_get_preferred_height; - actor_class->get_paint_volume = meta_background_actor_get_paint_volume; } static void From 0924c7d61b4ca1b81a9d95c9b5460a0334852437 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 3 Dec 2013 14:43:53 -0500 Subject: [PATCH 330/889] wayland: Use a stage paint callback instead of a signal handler on "paint" This is much more appropriate... --- src/compositor/compositor.c | 2 ++ src/wayland/meta-wayland-private.h | 1 + src/wayland/meta-wayland.c | 8 ++------ 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 93464e1f1..325a4ecbb 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -637,6 +637,8 @@ after_stage_paint (ClutterStage *stage, for (l = info->windows; l; l = l->next) meta_window_actor_post_paint (l->data); + + meta_wayland_compositor_paint_finished (meta_wayland_compositor_get_default ()); } static void diff --git a/src/wayland/meta-wayland-private.h b/src/wayland/meta-wayland-private.h index d13090bb3..e444ae596 100644 --- a/src/wayland/meta-wayland-private.h +++ b/src/wayland/meta-wayland-private.h @@ -109,5 +109,6 @@ void meta_wayland_buffer_reference (MetaWaylandBuff void meta_wayland_compositor_update (MetaWaylandCompositor *compositor, const ClutterEvent *event); +void meta_wayland_compositor_paint_finished (MetaWaylandCompositor *compositor); #endif /* META_WAYLAND_PRIVATE_H */ diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index 3d1961a81..f67af7e60 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -500,11 +500,9 @@ const static struct wl_compositor_interface meta_wayland_compositor_interface = meta_wayland_compositor_create_region }; -static void -paint_finished_cb (ClutterActor *self, void *user_data) +void +meta_wayland_compositor_paint_finished (MetaWaylandCompositor *compositor) { - MetaWaylandCompositor *compositor = user_data; - while (!wl_list_empty (&compositor->frame_callbacks)) { MetaWaylandFrameCallback *callback = @@ -711,8 +709,6 @@ meta_wayland_init (void) compositor->outputs = meta_wayland_compositor_update_outputs (compositor, monitors); compositor->stage = meta_wayland_stage_new (); - g_signal_connect_after (compositor->stage, "paint", - G_CALLBACK (paint_finished_cb), compositor); g_signal_connect (compositor->stage, "destroy", G_CALLBACK (stage_destroy_cb), NULL); From 4d2d2f285bfa49e9f70b07e163a1f28135aec6f4 Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Wed, 4 Dec 2013 11:14:15 +0000 Subject: [PATCH 331/889] core: window: enable create effect for new wayland windows https://bugzilla.gnome.org/show_bug.cgi?id=719833 --- src/core/window.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/window.c b/src/core/window.c index 5b1490d86..10141b07b 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -1441,7 +1441,7 @@ meta_window_new_for_wayland (MetaDisplay *display, None, FALSE, WithdrawnState, - META_COMP_EFFECT_NONE, + META_COMP_EFFECT_CREATE, &attrs); meta_error_trap_pop (display); /* pop the XSync()-reducing trap */ From 622c7a021bad8ea0c5256e72156a3a512ba847de Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 4 Dec 2013 09:50:17 -0500 Subject: [PATCH 332/889] window-actor: Update shape at construction time When we attach an existing surface actor, the allocation may not change, so we need to ensure that the shape region and geometry is valid... --- src/compositor/meta-window-actor.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index ab260fa21..325ec2135 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -420,6 +420,7 @@ meta_window_actor_constructed (GObject *object) "allocation-changed", G_CALLBACK (surface_allocation_changed_notify), self); + meta_window_actor_update_shape (self); g_signal_connect_object (window, "notify::decorated", G_CALLBACK (window_decorated_notify), self, 0); From 1be117e430b99215e57567612cacebf1af0a24f0 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 4 Dec 2013 10:41:30 -0500 Subject: [PATCH 333/889] wayland-surface: Properly set the window type We need to make sure to call meta_window_type_changed after updating the type... --- src/wayland/meta-wayland-surface.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index cbad045aa..832c700b2 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -887,13 +887,15 @@ get_xdg_popup (struct wl_client *client, } surface->window = meta_window_new_for_wayland (meta_get_display (), surface); - surface->window->type = META_WINDOW_DROPDOWN_MENU; - surface->window->showing_for_first_time = FALSE; surface->window->rect.x = parent_rect.x + x; surface->window->rect.y = parent_rect.y + y; + surface->window->showing_for_first_time = FALSE; surface->window->placed = TRUE; meta_window_set_transient_for (surface->window, parent_surf->window); + surface->window->type = META_WINDOW_DROPDOWN_MENU; + meta_window_type_changed (surface->window); + meta_wayland_pointer_start_popup_grab (&seat->pointer, surface); } From 3813113f1a3dea959113b5ee7e656c4e66552295 Mon Sep 17 00:00:00 2001 From: "Owen W. Taylor" Date: Fri, 22 Nov 2013 08:57:44 -0500 Subject: [PATCH 334/889] window-props.c: React to changes to _GTK_FRAME_EXTENTS When _GTK_FRAME_EXTENTS changes, we need to redo constraints on the window - this matters in particular if the toolkit removes invisible borders when a window is maximized, since otherwise the maximized window will be positioned as if it still has invisible borders. https://bugzilla.gnome.org/show_bug.cgi?id=714707 --- src/core/window-props.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/core/window-props.c b/src/core/window-props.c index 1c7992988..cd4d012ae 100644 --- a/src/core/window-props.c +++ b/src/core/window-props.c @@ -317,6 +317,9 @@ reload_gtk_frame_extents (MetaWindow *window, { window->has_custom_frame_extents = FALSE; } + + if (!initial) + meta_window_queue(window, META_QUEUE_MOVE_RESIZE); } static void From a796938b3991535ac9b5e79436ce1dbf1da72904 Mon Sep 17 00:00:00 2001 From: "Owen W. Taylor" Date: Tue, 3 Dec 2013 00:27:03 -0500 Subject: [PATCH 335/889] 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 --git a/src/compositor/meta-window-group.c b/src/compositor/meta-window-group.c index f76b2e0a5..9554571b0 100644 --- a/src/compositor/meta-window-group.c +++ b/src/compositor/meta-window-group.c @@ -202,11 +202,30 @@ meta_window_group_paint (ClutterActor *actor) meta_cullable_reset_culling (META_CULLABLE (window_group)); } +/* 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 From 8d5ab6b5b34a3dbeaba6033c31d06090579ed574 Mon Sep 17 00:00:00 2001 From: "Owen W. Taylor" Date: Thu, 5 Dec 2013 08:27:28 -0500 Subject: [PATCH 336/889] Use the correct frame size during unmaximize When unmaximizing, we changed bits of window state, then called out to code that used the frame extents *before* we cleared old cached extents. Clear the cache up-front as soon as we change the window state. https://bugzilla.gnome.org/show_bug.cgi?id=714707 --- src/core/window.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/core/window.c b/src/core/window.c index 10141b07b..bb334f39e 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -4060,8 +4060,10 @@ meta_window_unmaximize_internal (MetaWindow *window, { MetaRectangle target_rect; MetaRectangle work_area; + MetaRectangle old_rect; meta_window_get_work_area_for_monitor (window, window->monitor->number, &work_area); + meta_window_get_frame_rect (window, &old_rect); meta_topic (META_DEBUG_WINDOW_OPS, "Unmaximizing %s%s\n", @@ -4075,6 +4077,12 @@ meta_window_unmaximize_internal (MetaWindow *window, window->maximized_vertically = window->maximized_vertically && !unmaximize_vertically; + /* recalc_window_features() will eventually clear the cached frame + * extents, but we need the correct frame extents in the code below, + * so invalidate the old frame extents manually up front. + */ + meta_window_frame_size_changed (window); + /* Unmaximize to the saved_rect position in the direction(s) * being unmaximized. */ @@ -4119,9 +4127,7 @@ meta_window_unmaximize_internal (MetaWindow *window, if (window->display->compositor) { - MetaRectangle old_rect, new_rect; - - meta_window_get_frame_rect (window, &old_rect); + MetaRectangle new_rect; meta_window_move_resize_internal (window, META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION, From 29197d40c66f5beee1b40ba86029efc5ae199ce2 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 5 Dec 2013 15:39:40 -0500 Subject: [PATCH 337/889] compositor: Don't assume we're a Wayland compositor --- src/compositor/compositor.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 325a4ecbb..a7d69b480 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -638,7 +638,8 @@ after_stage_paint (ClutterStage *stage, for (l = info->windows; l; l = l->next) meta_window_actor_post_paint (l->data); - meta_wayland_compositor_paint_finished (meta_wayland_compositor_get_default ()); + if (meta_is_wayland_compositor ()) + meta_wayland_compositor_paint_finished (meta_wayland_compositor_get_default ()); } static void From c36aa5e6967ae5dd4fcd0adfac4b58ab631229ba Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 5 Dec 2013 15:36:46 -0500 Subject: [PATCH 338/889] cursor-tracker: Don't assume we're a Wayland compositor --- src/core/meta-cursor-tracker.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/core/meta-cursor-tracker.c b/src/core/meta-cursor-tracker.c index e045841a1..67528c2e7 100644 --- a/src/core/meta-cursor-tracker.c +++ b/src/core/meta-cursor-tracker.c @@ -696,7 +696,6 @@ meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker, return FALSE; set_window_cursor (tracker, FALSE, NULL); - g_signal_emit (tracker, signals[CURSOR_CHANGED], 0); return TRUE; } @@ -970,12 +969,15 @@ sync_displayed_cursor (MetaCursorTracker *tracker) if (displayed_cursor) tracker->displayed_cursor = meta_cursor_reference_ref (displayed_cursor); - if (displayed_cursor) - cogl_pipeline_set_layer_texture (tracker->pipeline, 0, COGL_TEXTURE (displayed_cursor->texture)); - else - cogl_pipeline_set_layer_texture (tracker->pipeline, 0, NULL); + if (meta_is_wayland_compositor ()) + { + if (displayed_cursor) + cogl_pipeline_set_layer_texture (tracker->pipeline, 0, COGL_TEXTURE (displayed_cursor->texture)); + else + cogl_pipeline_set_layer_texture (tracker->pipeline, 0, NULL); - update_hw_cursor (tracker); + update_hw_cursor (tracker); + } g_signal_emit (tracker, signals[CURSOR_CHANGED], 0); } @@ -1034,10 +1036,13 @@ sync_cursor (MetaCursorTracker *tracker) tracker->current_rect.height = 0; } - if (tracker->has_hw_cursor) - move_hw_cursor (tracker); - else - meta_cursor_tracker_queue_redraw (tracker); + if (meta_is_wayland_compositor ()) + { + if (tracker->has_hw_cursor) + move_hw_cursor (tracker); + else + meta_cursor_tracker_queue_redraw (tracker); + } } void From 82066e02c558a6d95a707b255ba4ffb2a719463d Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 5 Dec 2013 16:45:29 -0500 Subject: [PATCH 339/889] display: Set the cursor when calling XIGrabDevice again --- src/core/display.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/display.c b/src/core/display.c index 49aea52d5..8959aa0e3 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -3862,6 +3862,7 @@ meta_display_set_grab_op_cursor (MetaDisplay *display, { unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits }; + MetaCursor cursor = meta_cursor_for_grab_op (op); XISetMask (mask.mask, XI_ButtonPress); XISetMask (mask.mask, XI_ButtonRelease); @@ -3876,7 +3877,7 @@ meta_display_set_grab_op_cursor (MetaDisplay *display, META_VIRTUAL_CORE_POINTER_ID, grab_xwindow, timestamp, - None, + meta_display_create_x_cursor (display, cursor), XIGrabModeAsync, XIGrabModeAsync, False, /* owner_events */ &mask) == Success) @@ -3895,7 +3896,7 @@ meta_display_set_grab_op_cursor (MetaDisplay *display, meta_error_trap_pop (display); - meta_cursor_tracker_set_grab_cursor (screen->cursor_tracker, meta_cursor_for_grab_op (op)); + meta_cursor_tracker_set_grab_cursor (screen->cursor_tracker, cursor); } gboolean From 58b39233f5164d49e58a6fc6efc6f0fd8569262a Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 5 Dec 2013 17:14:48 -0500 Subject: [PATCH 340/889] display: Correct the detection of a grab The grab_window might be NULL, in which case we have a full-screen grab, but we might still in a grab. Correct the check by asking whether we're in a grab op or not. --- src/core/display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/display.c b/src/core/display.c index 8959aa0e3..5f9a53638 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -1604,7 +1604,7 @@ get_window_for_event (MetaDisplay *display, { ClutterActor *source; - if (display->grab_window) + if (display->grab_op != META_GRAB_OP_NONE) return display->grab_window; source = clutter_event_get_source (event); From fa65c380dbdd79f9849b3c70a5037743f8f88341 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 5 Dec 2013 16:13:03 -0500 Subject: [PATCH 341/889] Support X button events again Do this by duplicating the current code and porting it to use X again. A better approach would involve our own event structures, and I really don't want to do that right now. We can clean this up later. --- src/core/display.c | 236 ++++++++++++++++++++++++++++++++++++++ src/core/window-private.h | 6 +- src/core/window.c | 217 ++++++++++++++++++++++++++++++----- 3 files changed, 430 insertions(+), 29 deletions(-) diff --git a/src/core/display.c b/src/core/display.c index 5f9a53638..f809caa19 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -2229,9 +2229,11 @@ handle_input_xevent (MetaDisplay *display, XIEvent *input_event, gulong serial) { + XIDeviceEvent *device_event = (XIDeviceEvent *) input_event; XIEnterEvent *enter_event = (XIEnterEvent *) input_event; Window modified; MetaWindow *window; + gboolean frame_was_receiver; if (input_event == NULL) return FALSE; @@ -2239,8 +2241,242 @@ handle_input_xevent (MetaDisplay *display, modified = xievent_get_modified_window (display, input_event); window = modified != None ? meta_display_lookup_x_window (display, modified) : NULL; + frame_was_receiver = FALSE; + if (window && + window->frame && + modified == window->frame->xwindow) + { + /* Note that if the frame and the client both have an + * XGrabButton (as is normal with our setup), the event + * goes to the frame. + */ + frame_was_receiver = TRUE; + meta_topic (META_DEBUG_EVENTS, "Frame was receiver of event for %s\n", + window->desc); + } + + if (window && !window->override_redirect && + (input_event->evtype == XI_KeyPress || input_event->evtype == XI_ButtonPress)) + { + if (CurrentTime == display->current_time) + { + /* We can't use missing (i.e. invalid) timestamps to set user time, + * nor do we want to use them to sanity check other timestamps. + * See bug 313490 for more details. + */ + meta_warning ("Event has no timestamp! You may be using a broken " + "program such as xse. Please ask the authors of that " + "program to fix it.\n"); + } + else + { + meta_window_set_user_time (window, display->current_time); + sanity_check_timestamps (display, display->current_time); + } + } + switch (input_event->evtype) { + 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 ((window && + meta_grab_op_is_mouse (display->grab_op) && + (device_event->mods.effective & display->window_grab_modifiers) && + display->grab_button != device_event->detail && + display->grab_window == window) || + grab_op_is_keyboard (display->grab_op)) + { + meta_topic (META_DEBUG_WINDOW_OPS, + "Ending grab op %u on window %s due to button press\n", + display->grab_op, + (display->grab_window ? + display->grab_window->desc : + "none")); + if (GRAB_OP_IS_WINDOW_SWITCH (display->grab_op)) + { + MetaScreen *screen; + meta_topic (META_DEBUG_WINDOW_OPS, + "Syncing to old stack positions.\n"); + screen = + meta_display_screen_for_root (display, device_event->event); + + if (screen!=NULL) + meta_stack_set_positions (screen->stack, + display->grab_old_window_stacking); + } + meta_display_end_grab_op (display, + device_event->time); + } + else if (window && display->grab_op == META_GRAB_OP_NONE) + { + gboolean begin_move = FALSE; + unsigned int grab_mask; + gboolean unmodified; + + grab_mask = display->window_grab_modifiers; + if (g_getenv ("MUTTER_DEBUG_BUTTON_GRABS")) + grab_mask |= ControlMask; + + /* Two possible sources of an unmodified event; one is a + * client that's letting button presses pass through to the + * frame, the other is our focus_window_grab on unmodified + * button 1. So for all such events we focus the window. + */ + unmodified = (device_event->mods.effective & grab_mask) == 0; + + if (unmodified || + device_event->detail == 1) + { + /* don't focus if frame received, will be lowered in + * frames.c or special-cased if the click was on a + * minimize/close button. + */ + if (!frame_was_receiver) + { + if (meta_prefs_get_raise_on_click ()) + meta_window_raise (window); + else + meta_topic (META_DEBUG_FOCUS, + "Not raising window on click due to don't-raise-on-click option\n"); + + /* Don't focus panels--they must explicitly request focus. + * See bug 160470 + */ + if (window->type != META_WINDOW_DOCK) + { + meta_topic (META_DEBUG_FOCUS, + "Focusing %s due to unmodified button %u press (display.c)\n", + window->desc, device_event->detail); + meta_window_focus (window, device_event->time); + } + else + /* However, do allow terminals to lose focus due to new + * window mappings after the user clicks on a panel. + */ + display->allow_terminal_deactivation = TRUE; + } + + /* you can move on alt-click but not on + * the click-to-focus + */ + if (!unmodified) + begin_move = TRUE; + } + else if (!unmodified && device_event->detail == meta_prefs_get_mouse_button_resize()) + { + if (window->has_resize_func) + { + gboolean north, south; + gboolean west, east; + MetaRectangle frame_rect; + MetaGrabOp op; + + meta_window_get_frame_rect (window, &frame_rect); + + west = device_event->root_x < (frame_rect.x + 1 * frame_rect.width / 3); + east = device_event->root_x > (frame_rect.x + 2 * frame_rect.width / 3); + north = device_event->root_y < (frame_rect.y + 1 * frame_rect.height / 3); + south = device_event->root_y > (frame_rect.y + 2 * frame_rect.height / 3); + + if (north && west) + op = META_GRAB_OP_RESIZING_NW; + else if (north && east) + op = META_GRAB_OP_RESIZING_NE; + else if (south && west) + op = META_GRAB_OP_RESIZING_SW; + else if (south && east) + op = META_GRAB_OP_RESIZING_SE; + else if (north) + op = META_GRAB_OP_RESIZING_N; + else if (west) + op = META_GRAB_OP_RESIZING_W; + else if (east) + op = META_GRAB_OP_RESIZING_E; + else if (south) + op = META_GRAB_OP_RESIZING_S; + else /* Middle region is no-op to avoid user triggering wrong action */ + op = META_GRAB_OP_NONE; + + if (op != META_GRAB_OP_NONE) + meta_display_begin_grab_op (display, + window->screen, + window, + op, + TRUE, + FALSE, + device_event->detail, + 0, + device_event->time, + device_event->root_x, + device_event->root_y); + } + } + else if (device_event->detail == 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, + device_event->time); + } + + if (!frame_was_receiver && unmodified) + { + /* This is from our synchronous grab since + * it has no modifiers and was on the client window + */ + + meta_verbose ("Allowing events time %u\n", + (unsigned int)device_event->time); + + XIAllowEvents (display->xdisplay, device_event->deviceid, + XIReplayDevice, device_event->time); + } + + if (begin_move && window->has_move_func) + { + meta_display_begin_grab_op (display, + window->screen, + window, + META_GRAB_OP_MOVING, + TRUE, + FALSE, + device_event->detail, + 0, + device_event->time, + device_event->root_x, + device_event->root_y); + } + } + break; + case XI_ButtonRelease: + if (display->grab_op == META_GRAB_OP_COMPOSITOR) + break; + + display->overlay_key_only_pressed = FALSE; + + if (display->grab_window == window && + meta_grab_op_is_mouse (display->grab_op)) + meta_window_handle_mouse_grab_op_xevent (window, device_event); + break; + case XI_Motion: + if (display->grab_op == META_GRAB_OP_COMPOSITOR) + break; + + if (display->grab_window == window && + meta_grab_op_is_mouse (display->grab_op)) + meta_window_handle_mouse_grab_op_xevent (window, device_event); + break; case XI_Enter: if (display->grab_op == META_GRAB_OP_COMPOSITOR) break; diff --git a/src/core/window-private.h b/src/core/window-private.h index 0f1630adb..307129c9b 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -648,8 +648,10 @@ void meta_window_update_sync_request_counter (MetaWindow *window, gint64 new_counter_value); #endif /* HAVE_XSYNC */ -void meta_window_handle_mouse_grab_op_event (MetaWindow *window, - const ClutterEvent *event); +void meta_window_handle_mouse_grab_op_event (MetaWindow *window, + const ClutterEvent *event); +void meta_window_handle_mouse_grab_op_xevent (MetaWindow *window, + XIDeviceEvent *xevent); GList* meta_window_get_workspaces (MetaWindow *window); diff --git a/src/core/window.c b/src/core/window.c index bb334f39e..3a3fde008 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -10029,20 +10029,96 @@ update_resize (MetaWindow *window, g_get_current_time (&window->display->grab_last_moveresize_time); } -static gboolean -check_use_this_motion_notify (MetaWindow *window, - const ClutterEvent *event) +typedef struct { - /* XXX: Previously this code would walk through the X event queue - and filter out motion events that are followed by a later motion - event. There currently isn't any API to do the equivalent - procedure with the Clutter event queue so this function does - nothing. Clutter does its own motion event squashing so it may be - the case that this function isn't necessary. If it turns out that - we do need additional motion event squashing we could add some - extra API to the Clutter event queue and implement this function - properly. */ - return TRUE; + Window window; + int count; + guint32 last_time; +} EventScannerData; + +static Bool +find_last_time_predicate (Display *display, + XEvent *ev, + XPointer arg) +{ + EventScannerData *esd = (void*) arg; + XIEvent *xev; + + if (ev->type != GenericEvent) + return False; + + /* We are peeking into events not yet handled by GDK, + * Allocate cookie events here so we can handle XI2. + * + * GDK will handle later these events, and eventually + * free the cookie data itself. + */ + XGetEventData (display, &ev->xcookie); + xev = (XIEvent *) ev->xcookie.data; + + if (xev->evtype != XI_Motion) + return False; + + if (esd->window != ((XIDeviceEvent *) xev)->event) + return False; + + esd->count += 1; + esd->last_time = xev->time; + + return False; +} + +static gboolean +check_use_this_motion_notify (MetaWindow *window, + XIDeviceEvent *xev) +{ + EventScannerData esd; + XEvent useless; + + /* This code is copied from Owen's GDK code. */ + + if (window->display->grab_motion_notify_time != 0) + { + /* == is really the right test, but I'm all for paranoia */ + if (window->display->grab_motion_notify_time <= + xev->time) + { + meta_topic (META_DEBUG_RESIZING, + "Arrived at event with time %u (waiting for %u), using it\n", + (unsigned int)xev->time, + window->display->grab_motion_notify_time); + window->display->grab_motion_notify_time = 0; + return TRUE; + } + else + return FALSE; /* haven't reached the saved timestamp yet */ + } + + esd.window = xev->event; + esd.count = 0; + esd.last_time = 0; + + /* "useless" isn't filled in because the predicate never returns True */ + XCheckIfEvent (window->display->xdisplay, + &useless, + find_last_time_predicate, + (XPointer) &esd); + + if (esd.count > 0) + meta_topic (META_DEBUG_RESIZING, + "Will skip %d motion events and use the event with time %u\n", + esd.count, (unsigned int) esd.last_time); + + if (esd.last_time == 0) + return TRUE; + else + { + /* Save this timestamp, and ignore all motion notify + * until we get to the one with this stamp. + */ + window->display->grab_motion_notify_time = esd.last_time; + return FALSE; + } } static void @@ -10116,8 +10192,98 @@ meta_window_update_sync_request_counter (MetaWindow *window, #endif /* HAVE_XSYNC */ void -meta_window_handle_mouse_grab_op_event (MetaWindow *window, - const ClutterEvent *event) +meta_window_handle_mouse_grab_op_xevent (MetaWindow *window, + XIDeviceEvent *xevent) +{ + gboolean is_window_root = (xevent->root == window->screen->xroot); + + switch (xevent->evtype) + { + case XI_ButtonRelease: + if (xevent->detail == 1 || + xevent->detail == meta_prefs_get_mouse_button_resize ()) + { + meta_display_check_threshold_reached (window->display, + xevent->root_x, + xevent->root_y); + /* If the user was snap moving then ignore the button + * release because they may have let go of shift before + * releasing the mouse button and they almost certainly do + * not want a non-snapped movement to occur from the button + * release. + */ + if (!window->display->grab_last_user_action_was_snap) + { + if (meta_grab_op_is_moving (window->display->grab_op)) + { + if (window->tile_mode != META_TILE_NONE) + meta_window_tile (window); + else if (is_window_root) + update_move (window, + xevent->mods.effective & ShiftMask, + xevent->root_x, + xevent->root_y); + } + else if (meta_grab_op_is_resizing (window->display->grab_op)) + { + if (is_window_root) + update_resize (window, + xevent->mods.effective & ShiftMask, + xevent->root_x, + xevent->root_y, + TRUE); + + /* If a tiled window has been dragged free with a + * mouse resize without snapping back to the tiled + * state, it will end up with an inconsistent tile + * mode on mouse release; cleaning the mode earlier + * would break the ability to snap back to the tiled + * state, so we wait until mouse release. + */ + update_tile_mode (window); + } + meta_display_end_grab_op (window->display, xevent->time); + } + } + break; + + case XI_Motion: + meta_display_check_threshold_reached (window->display, + xevent->root_x, + xevent->root_y); + if (meta_grab_op_is_moving (window->display->grab_op)) + { + if (is_window_root) + { + if (check_use_this_motion_notify (window, xevent)) + update_move (window, + xevent->mods.effective & ShiftMask, + xevent->root_x, + xevent->root_y); + } + } + else if (meta_grab_op_is_resizing (window->display->grab_op)) + { + if (is_window_root) + { + if (check_use_this_motion_notify (window, xevent)) + update_resize (window, + xevent->mods.effective & ShiftMask, + xevent->root_x, + xevent->root_y, + FALSE); + } + } + break; + + default: + break; + } +} + +void +meta_window_handle_mouse_grab_op_event (MetaWindow *window, + const ClutterEvent *event) { gboolean is_window_root = (event->any.stage != NULL && window && @@ -10170,7 +10336,6 @@ meta_window_handle_mouse_grab_op_event (MetaWindow *window, */ update_tile_mode (window); } - meta_display_end_grab_op (window->display, event->any.time); } } @@ -10184,23 +10349,21 @@ meta_window_handle_mouse_grab_op_event (MetaWindow *window, { if (is_window_root) { - if (check_use_this_motion_notify (window, event)) - update_move (window, - event->button.modifier_state & CLUTTER_SHIFT_MASK, - event->motion.x, - event->motion.y); + update_move (window, + event->button.modifier_state & CLUTTER_SHIFT_MASK, + event->motion.x, + event->motion.y); } } else if (meta_grab_op_is_resizing (window->display->grab_op)) { if (is_window_root) { - if (check_use_this_motion_notify (window, event)) - update_resize (window, - event->button.modifier_state & CLUTTER_SHIFT_MASK, - event->motion.x, - event->motion.y, - FALSE); + update_resize (window, + event->button.modifier_state & CLUTTER_SHIFT_MASK, + event->motion.x, + event->motion.y, + FALSE); } } break; From 283649b8d784311bc94013c57dff71f48da9f766 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 5 Dec 2013 16:36:40 -0500 Subject: [PATCH 342/889] Support keybindings again, too --- src/compositor/compositor.c | 32 +++++++++++++++----------------- src/core/display.c | 10 ++++++++++ src/wayland/meta-wayland.c | 2 -- 3 files changed, 25 insertions(+), 19 deletions(-) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index a7d69b480..eaefa3250 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -1003,18 +1003,13 @@ meta_compositor_window_shape_changed (MetaCompositor *compositor, * application toolkit. As such, it will ignore any events sent * to the a stage that isn't its X window. * - * When a user clicks on what she thinks is the wallpaper, she - * is actually clicking on the guard window, which is an entirely - * separate top-level override-redirect window in the hierarchy. - * We want to recieve events on this guard window so that users - * can right-click on the background actor. We do this by telling - * Clutter a little white lie, by transforming clicks on the guard - * window to become clicks on the stage window, allowing Clutter - * to process the event normally. + * When running as an X window manager, we need to respond to + * events from lots of windows. Trick Clutter into translating + * these events by pretending we got an event on the stage window. */ static void -maybe_spoof_guard_window_event_as_stage_event (MetaCompScreen *info, - XEvent *event) +maybe_spoof_event_as_stage_event (MetaCompScreen *info, + XEvent *event) { MetaDisplay *display = meta_screen_get_display (info->screen); @@ -1023,19 +1018,22 @@ maybe_spoof_guard_window_event_as_stage_event (MetaCompScreen *info, { XIEvent *input_event = (XIEvent *) event->xcookie.data; - /* Only care about pointer events for now. */ switch (input_event->evtype) { case XI_Motion: case XI_ButtonPress: case XI_ButtonRelease: + case XI_KeyPress: + case XI_KeyRelease: { XIDeviceEvent *device_event = ((XIDeviceEvent *) input_event); - if (device_event->event == info->screen->guard_window) - { - Window xwin = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage)); - device_event->event = xwin; - } + + /* If this is a GTK+ widget, like a window menu, let GTK+ handle + * it as-is without mangling. */ + if (meta_ui_window_is_widget (info->screen->ui, device_event->event)) + break; + + device_event->event = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage)); } break; default: @@ -1092,7 +1090,7 @@ meta_compositor_process_event (MetaCompositor *compositor, info = meta_screen_get_compositor_data (screen); - maybe_spoof_guard_window_event_as_stage_event (info, event); + maybe_spoof_event_as_stage_event (info, event); if (meta_plugin_manager_xevent_filter (info->plugin_mgr, event)) { diff --git a/src/core/display.c b/src/core/display.c index f809caa19..2ae9a5daf 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -1707,9 +1707,19 @@ update_focus_window (MetaDisplay *display, if (display->focus_window) { + ClutterActor *window_actor; + meta_topic (META_DEBUG_FOCUS, "* Focus --> %s with serial %lu\n", display->focus_window->desc, serial); meta_window_set_focused_internal (display->focus_window, TRUE); + + /* XXX -- this is sort of a layer violation, but because we + * rely on the compositor for event delivery anyway, I don't + * think it's too bad... */ + + window_actor = CLUTTER_ACTOR (display->focus_window->compositor_private); + if (window_actor) + clutter_actor_grab_key_focus (window_actor); } else meta_topic (META_DEBUG_FOCUS, "* Focus --> NULL with serial %lu\n", serial); diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index f67af7e60..a6b24368e 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -215,8 +215,6 @@ meta_wayland_compositor_set_input_focus (MetaWaylandCompositor *compositor, meta_wayland_keyboard_set_focus (&compositor->seat->keyboard, surface); meta_wayland_data_device_set_keyboard_focus (compositor->seat); - - clutter_stage_set_key_focus (CLUTTER_STAGE (compositor->stage), window_actor); } void From 65b39212d54c5650dde2aa263f568a011d7f3d13 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 5 Dec 2013 18:32:11 -0500 Subject: [PATCH 343/889] meta-wayland: Remove undefined variable --- src/wayland/meta-wayland.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index a6b24368e..4cee683cc 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -210,7 +210,6 @@ meta_wayland_compositor_set_input_focus (MetaWaylandCompositor *compositor, MetaWindow *window) { MetaWaylandSurface *surface = window ? window->surface : NULL; - ClutterActor *window_actor = window ? CLUTTER_ACTOR (meta_window_get_compositor_private (window)) : NULL; meta_wayland_keyboard_set_focus (&compositor->seat->keyboard, surface); From 643645938141e8564d9c1a0e728c7b1be6b57876 Mon Sep 17 00:00:00 2001 From: Alberto Milone Date: Tue, 3 Dec 2013 18:16:22 +0100 Subject: [PATCH 344/889] xrandr: ignore the error if setting the primary output fails Some drivers which support RandR 1.4 may not support setting or getting the primary output, therefore mutter should trap and ignore any relevant errors. The modesetting driver exposes this problem when used in combination with the nvidia binary driver using RandR 1.4 offloading. Also use a local display variable instead of calling meta_get_display () every time. --- src/core/monitor-xrandr.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/core/monitor-xrandr.c b/src/core/monitor-xrandr.c index e723c1c51..167b94c54 100644 --- a/src/core/monitor-xrandr.c +++ b/src/core/monitor-xrandr.c @@ -453,8 +453,10 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager) XRRFreeCrtcInfo (crtc); } + meta_error_trap_push (meta_get_display ()); primary_output = XRRGetOutputPrimary (manager_xrandr->xdisplay, DefaultRootWindow (manager_xrandr->xdisplay)); + meta_error_trap_pop (meta_get_display ()); n_actual_outputs = 0; for (i = 0; i < (unsigned)resources->noutput; i++) @@ -691,10 +693,11 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager, unsigned int n_outputs) { MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (manager); + MetaDisplay *display = meta_get_display (); unsigned i; int width, height, width_mm, height_mm; - meta_display_grab (meta_get_display ()); + meta_display_grab (display); /* First compute the new size of the screen (framebuffer) */ width = 0; height = 0; @@ -788,10 +791,10 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager, */ width_mm = (width / DPI_FALLBACK) * 25.4 + 0.5; height_mm = (height / DPI_FALLBACK) * 25.4 + 0.5; - meta_error_trap_push (meta_get_display ()); + meta_error_trap_push (display); XRRSetScreenSize (manager_xrandr->xdisplay, DefaultRootWindow (manager_xrandr->xdisplay), width, height, width_mm, height_mm); - meta_error_trap_pop (meta_get_display ()); + meta_error_trap_pop (display); for (i = 0; i < n_crtcs; i++) { @@ -848,7 +851,7 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager, goto next; } - meta_error_trap_push (meta_get_display ()); + meta_error_trap_push (display); ok = XRRSetCrtcConfig (manager_xrandr->xdisplay, manager_xrandr->resources, (XID)crtc->crtc_id, @@ -857,7 +860,7 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager, (XID)mode->mode_id, wl_transform_to_xrandr (crtc_info->transform), outputs, n_outputs); - meta_error_trap_pop (meta_get_display ()); + meta_error_trap_pop (display); if (ok != Success) { @@ -898,9 +901,11 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager, if (output_info->is_primary) { + meta_error_trap_push (display); XRRSetOutputPrimary (manager_xrandr->xdisplay, DefaultRootWindow (manager_xrandr->xdisplay), (XID)output_info->output->output_id); + meta_error_trap_pop (display); } output_set_presentation_xrandr (manager_xrandr, @@ -926,7 +931,7 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager, output->is_primary = FALSE; } - meta_display_ungrab (meta_get_display ()); + meta_display_ungrab (display); } static void From 309f78ff52658f4e8ceda2024963b7b121033fbf Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 6 Dec 2013 20:03:46 -0500 Subject: [PATCH 345/889] display: Fix window pings These are 32-bit values, not longs. Treat them as such. --- src/core/display.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/core/display.c b/src/core/display.c index 2ae9a5daf..b0874af37 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -506,8 +506,7 @@ meta_display_open (void) the_display->xids = g_hash_table_new (meta_unsigned_long_hash, meta_unsigned_long_equal); - the_display->pending_pings = g_hash_table_new (meta_unsigned_long_hash, - meta_unsigned_long_equal); + the_display->pending_pings = g_hash_table_new (g_int_hash, g_int_equal); the_display->wayland_windows = g_hash_table_new (NULL, NULL); i = 0; From 1481836ed649b58de085e0a621bf6d19a7d728ab Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 6 Dec 2013 14:19:32 -0500 Subject: [PATCH 346/889] surface-actor: Move work out of _new constructor If we want to have any chance at creating subclasses of MetaSurfaceActor, we can't do work in the constructor... --- src/compositor/meta-surface-actor.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/src/compositor/meta-surface-actor.c b/src/compositor/meta-surface-actor.c index 540c7f49c..486e94eba 100644 --- a/src/compositor/meta-surface-actor.c +++ b/src/compositor/meta-surface-actor.c @@ -67,21 +67,8 @@ meta_surface_actor_init (MetaSurfaceActor *self) META_TYPE_SURFACE_ACTOR, MetaSurfaceActorPrivate); - priv->texture = NULL; -} - -MetaSurfaceActor * -meta_surface_actor_new (void) -{ - MetaSurfaceActor *self = g_object_new (META_TYPE_SURFACE_ACTOR, NULL); - MetaShapedTexture *stex; - - stex = META_SHAPED_TEXTURE (meta_shaped_texture_new ()); - self->priv->texture = stex; - - clutter_actor_add_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (stex)); - - return self; + priv->texture = META_SHAPED_TEXTURE (meta_shaped_texture_new ()); + clutter_actor_add_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->texture)); } cairo_surface_t * @@ -183,3 +170,9 @@ meta_surface_actor_set_opaque_region (MetaSurfaceActor *self, { meta_shaped_texture_set_opaque_region (self->priv->texture, region); } + +MetaSurfaceActor * +meta_surface_actor_new (void) +{ + return g_object_new (META_TYPE_SURFACE_ACTOR, NULL); +} From 57602adfe746e76c2808905c2caa75410174a6c3 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 6 Dec 2013 12:00:13 -0500 Subject: [PATCH 347/889] surface-actor: Don't use self->priv->foo directly I don't like it... --- src/compositor/meta-surface-actor.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/compositor/meta-surface-actor.c b/src/compositor/meta-surface-actor.c index 486e94eba..55520862e 100644 --- a/src/compositor/meta-surface-actor.c +++ b/src/compositor/meta-surface-actor.c @@ -116,7 +116,7 @@ meta_surface_actor_damage_all (MetaSurfaceActor *self, CoglTexture *texture = meta_shaped_texture_get_texture (priv->texture); update_area (self, 0, 0, cogl_texture_get_width (texture), cogl_texture_get_height (texture)); - return meta_shaped_texture_update_area (self->priv->texture, + return meta_shaped_texture_update_area (priv->texture, 0, 0, cogl_texture_get_width (texture), cogl_texture_get_height (texture), @@ -131,8 +131,10 @@ meta_surface_actor_damage_area (MetaSurfaceActor *self, int height, cairo_region_t *unobscured_region) { + MetaSurfaceActorPrivate *priv = self->priv; + update_area (self, x, y, width, height); - return meta_shaped_texture_update_area (self->priv->texture, + return meta_shaped_texture_update_area (priv->texture, x, y, width, height, unobscured_region); } @@ -145,30 +147,33 @@ meta_surface_actor_attach_wayland_buffer (MetaSurfaceActor *self, priv->buffer = buffer; if (buffer) - meta_shaped_texture_set_texture (self->priv->texture, buffer->texture); + meta_shaped_texture_set_texture (priv->texture, buffer->texture); else - meta_shaped_texture_set_texture (self->priv->texture, NULL); + meta_shaped_texture_set_texture (priv->texture, NULL); } void meta_surface_actor_set_texture (MetaSurfaceActor *self, CoglTexture *texture) { - meta_shaped_texture_set_texture (self->priv->texture, texture); + MetaSurfaceActorPrivate *priv = self->priv; + meta_shaped_texture_set_texture (priv->texture, texture); } void meta_surface_actor_set_input_region (MetaSurfaceActor *self, cairo_region_t *region) { - meta_shaped_texture_set_input_shape_region (self->priv->texture, region); + MetaSurfaceActorPrivate *priv = self->priv; + meta_shaped_texture_set_input_shape_region (priv->texture, region); } void meta_surface_actor_set_opaque_region (MetaSurfaceActor *self, cairo_region_t *region) { - meta_shaped_texture_set_opaque_region (self->priv->texture, region); + MetaSurfaceActorPrivate *priv = self->priv; + meta_shaped_texture_set_opaque_region (priv->texture, region); } MetaSurfaceActor * From ee683ff187463350cf794ff77e2c3809b13ccbcd Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 6 Dec 2013 20:23:00 -0500 Subject: [PATCH 348/889] window: Fix meta_window_ping some more Make sure to actually add the pings to the list... and don't remove it from the list twice. --- src/core/window.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/core/window.c b/src/core/window.c index 3a3fde008..e13e0a70f 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -12231,9 +12231,6 @@ meta_window_pong (MetaWindow *window, ping_data->timestamp, ping_data->user_data); - /* Remove the ping data from the list */ - window->pending_pings = g_slist_remove (window->pending_pings, ping_data); - ping_data_free (ping_data); break; @@ -12333,6 +12330,8 @@ meta_window_ping (MetaWindow *window, ping_data->user_data = user_data; ping_data->ping_timeout_id = g_timeout_add (PING_TIMEOUT_DELAY, ping_timeout, ping_data); + window->pending_pings = g_slist_prepend (window->pending_pings, ping_data); + g_hash_table_insert (display->pending_pings, &ping_data->timestamp, window); meta_topic (META_DEBUG_PING, From ca5b5e6bc4db3c9682469774908dbbcc4dba204d Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 6 Dec 2013 20:28:39 -0500 Subject: [PATCH 349/889] surface-actor: Reindent --- src/compositor/meta-surface-actor.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compositor/meta-surface-actor.c b/src/compositor/meta-surface-actor.c index 55520862e..37b87b03a 100644 --- a/src/compositor/meta-surface-actor.c +++ b/src/compositor/meta-surface-actor.c @@ -39,8 +39,8 @@ meta_surface_actor_class_init (MetaSurfaceActorClass *klass) static void meta_surface_actor_cull_out (MetaCullable *cullable, - cairo_region_t *unobscured_region, - cairo_region_t *clip_region) + cairo_region_t *unobscured_region, + cairo_region_t *clip_region) { meta_cullable_cull_out_children (cullable, unobscured_region, clip_region); } From fd8cc9b7a8dfdb7715e91564b0978f6beb4a0f91 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 9 Dec 2013 13:48:58 -0500 Subject: [PATCH 350/889] xwayland: Remove outdated code Now that focus management goes through the central display.c, we don't need to do this separately. Wayland and X clients should just behave as one. --- src/wayland/meta-xwayland.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index cf78a59f7..02c5b7bc3 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -39,25 +39,15 @@ xserver_set_window_id (struct wl_client *client, struct wl_resource *surface_resource, guint32 xid) { - MetaWaylandCompositor *compositor = - wl_resource_get_user_data (compositor_resource); MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); MetaDisplay *display = meta_get_display (); MetaWindow *window; - window = meta_display_lookup_x_window (display, xid); + window = meta_display_lookup_x_window (display, xid); if (window) { surface->window = window; window->surface = surface; - - /* If the window is already meant to have focus then the - * original attempt to call this in response to the FocusIn - * event will have been lost because there was no surface - * yet. */ - if (window->has_focus) - meta_wayland_compositor_set_input_focus (compositor, window); - } } From 1b600f5867ed6fc06a21dcef35831242ca6d0314 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 9 Dec 2013 13:47:01 -0500 Subject: [PATCH 351/889] window-actor: Use g_signal_connect_object To make our signal connections a bit more manageable... --- src/compositor/meta-window-actor.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 325ec2135..309193bcf 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -54,8 +54,6 @@ struct _MetaWindowActorPrivate MetaSurfaceActor *surface; - guint surface_allocation_changed_id; - /* MetaShadowFactory only caches shadows that are actually in use; * to avoid unnecessary recomputation we do two things: 1) we store * both a focused and unfocused shadow for the window. If the window @@ -300,8 +298,6 @@ meta_window_actor_init (MetaWindowActor *self) priv = self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, META_TYPE_WINDOW_ACTOR, MetaWindowActorPrivate); - - priv->surface_allocation_changed_id = 0; priv->opacity = 0xff; priv->shadow_class = NULL; } @@ -415,11 +411,8 @@ meta_window_actor_constructed (GObject *object) clutter_actor_add_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface)); - priv->surface_allocation_changed_id = - g_signal_connect (CLUTTER_ACTOR (priv->surface), - "allocation-changed", - G_CALLBACK (surface_allocation_changed_notify), - self); + g_signal_connect_object (priv->surface, "allocation-changed", + G_CALLBACK (surface_allocation_changed_notify), self, 0); meta_window_actor_update_shape (self); g_signal_connect_object (window, "notify::decorated", @@ -495,11 +488,6 @@ meta_window_actor_dispose (GObject *object) g_clear_object (&priv->window); - if (priv->surface != NULL && priv->surface_allocation_changed_id != 0) - g_signal_handler_disconnect (priv->surface, - priv->surface_allocation_changed_id); - priv->surface_allocation_changed_id = 0; - /* * Release the extra reference we took on the actor. */ From f0fa4d831ac744682747a12fe3827efea69e84be Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 6 Dec 2013 00:57:11 -0500 Subject: [PATCH 352/889] window: Add a simple meta_window_get_toplevel_xwindow utility To replace all the places where we do: window->frame ? window->frame->xwindow : window->xwindow or similar... --- src/compositor/meta-window-actor.c | 19 +++---------------- src/core/core.c | 3 +-- src/core/display.c | 2 +- src/core/keybindings.c | 4 ++-- src/core/window-private.h | 1 + src/core/window.c | 6 ++++++ 6 files changed, 14 insertions(+), 21 deletions(-) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 309193bcf..788b6d91f 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -309,11 +309,9 @@ window_decorated_notify (MetaWindow *mw, { MetaWindowActor *self = META_WINDOW_ACTOR (data); MetaWindowActorPrivate *priv = self->priv; - MetaFrame *frame = meta_window_get_frame (mw); MetaScreen *screen = priv->screen; MetaDisplay *display = meta_screen_get_display (screen); Display *xdisplay = meta_display_get_xdisplay (display); - Window new_xwindow; /* * Basically, we have to reconstruct the the internals of this object @@ -321,11 +319,6 @@ window_decorated_notify (MetaWindow *mw, */ priv->redecorating = TRUE; - if (frame) - new_xwindow = meta_frame_get_xwindow (frame); - else - new_xwindow = meta_window_get_xwindow (mw); - if (!meta_is_wayland_compositor ()) { meta_window_actor_detach_x11_pixmap (self); @@ -343,7 +336,7 @@ window_decorated_notify (MetaWindow *mw, } } - priv->xwindow = new_xwindow; + priv->xwindow = meta_window_get_toplevel_xwindow (priv->window); /* * Recreate the contents. @@ -1677,18 +1670,12 @@ meta_window_actor_new (MetaWindow *window) MetaCompScreen *info = meta_screen_get_compositor_data (screen); MetaWindowActor *self; MetaWindowActorPrivate *priv; - MetaFrame *frame; - Window top_window = None; + Window top_window; ClutterActor *window_group; if (window->client_type == META_WINDOW_CLIENT_TYPE_X11) { - frame = meta_window_get_frame (window); - if (frame) - top_window = meta_frame_get_xwindow (frame); - else - top_window = meta_window_get_xwindow (window); - + top_window = meta_window_get_toplevel_xwindow (window); meta_verbose ("add window: Meta %p, xwin 0x%x\n", window, (guint)top_window); } else diff --git a/src/core/core.c b/src/core/core.c index b1ba70dc1..6840ece87 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -283,8 +283,7 @@ meta_core_lower_beneath_grab_window (Display *xdisplay, return; changes.stack_mode = Below; - changes.sibling = grab_window->frame ? grab_window->frame->xwindow - : grab_window->xwindow; + changes.sibling = meta_window_get_toplevel_xwindow (grab_window); stack_window.any.type = META_WINDOW_CLIENT_TYPE_X11; stack_window.x11.xwindow = xwindow; diff --git a/src/core/display.c b/src/core/display.c index b0874af37..0f20d143b 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -4204,7 +4204,7 @@ meta_display_begin_grab_op (MetaDisplay *display, * key grab on the RootWindow. */ if (grab_window) - grab_xwindow = grab_window->frame ? grab_window->frame->xwindow : grab_window->xwindow; + grab_xwindow = meta_window_get_toplevel_xwindow (grab_window); else grab_xwindow = screen->xroot; diff --git a/src/core/keybindings.c b/src/core/keybindings.c index e69910842..aa137d20b 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -1277,7 +1277,7 @@ meta_window_grab_keys (MetaWindow *window) } meta_window_change_keygrabs (window, - window->frame ? window->frame->xwindow : window->xwindow, + meta_window_get_toplevel_xwindow (window), TRUE); window->keys_grabbed = TRUE; @@ -1584,7 +1584,7 @@ meta_window_grab_all_keys (MetaWindow *window, window->desc); meta_window_focus (window, timestamp); - grabwindow = window->frame ? window->frame->xwindow : window->xwindow; + grabwindow = meta_window_get_toplevel_xwindow (window); meta_topic (META_DEBUG_KEYBINDINGS, "Grabbing all keys on window %s\n", window->desc); diff --git a/src/core/window-private.h b/src/core/window-private.h index 307129c9b..485c495ed 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -754,5 +754,6 @@ void meta_window_ping (MetaWindow *window, void *user_data); void meta_window_pong (MetaWindow *window, guint32 timestamp); +Window meta_window_get_toplevel_xwindow (MetaWindow *window); #endif diff --git a/src/core/window.c b/src/core/window.c index e13e0a70f..1a65ea6a1 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -12343,3 +12343,9 @@ meta_window_ping (MetaWindow *window, else meta_wayland_surface_ping (window->surface, timestamp); } + +Window +meta_window_get_toplevel_xwindow (MetaWindow *window) +{ + return window->frame ? window->frame->xwindow : window->xwindow; +} From 422648e2eb39572fc0e24cb3ef0bd44c396147ab Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 6 Dec 2013 00:59:20 -0500 Subject: [PATCH 353/889] window-actor: Remove (private) xwindow property This should make it easier to construct a MetaWindowActor from bindings. https://bugzilla.gnome.org/show_bug.cgi?id=678989 --- src/compositor/meta-window-actor.c | 60 +++--------------------------- 1 file changed, 5 insertions(+), 55 deletions(-) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 788b6d91f..c32afacc5 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -49,7 +49,6 @@ static guint signals[LAST_SIGNAL] = {0}; struct _MetaWindowActorPrivate { MetaWindow *window; - Window xwindow; MetaScreen *screen; MetaSurfaceActor *surface; @@ -160,7 +159,6 @@ enum { PROP_META_WINDOW = 1, PROP_META_SCREEN, - PROP_X_WINDOW, PROP_NO_SHADOW, PROP_SHADOW_CLASS }; @@ -244,18 +242,6 @@ meta_window_actor_class_init (MetaWindowActorClass *klass) PROP_META_SCREEN, pspec); - pspec = g_param_spec_ulong ("x-window", - "Window", - "Window", - 0, - G_MAXULONG, - 0, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT); - - g_object_class_install_property (object_class, - PROP_X_WINDOW, - pspec); - pspec = g_param_spec_boolean ("no-shadow", "No shadow", "Do not add shaddow to this window", @@ -336,8 +322,6 @@ window_decorated_notify (MetaWindow *mw, } } - priv->xwindow = meta_window_get_toplevel_xwindow (priv->window); - /* * Recreate the contents. */ @@ -371,8 +355,8 @@ meta_window_actor_constructed (GObject *object) MetaWindowActorPrivate *priv = self->priv; MetaScreen *screen = priv->screen; MetaDisplay *display = meta_screen_get_display (screen); - Window xwindow = priv->xwindow; MetaWindow *window = priv->window; + Window xwindow = meta_window_get_toplevel_xwindow (window); Display *xdisplay = meta_display_get_xdisplay (display); if (!meta_is_wayland_compositor ()) @@ -521,9 +505,6 @@ meta_window_actor_set_property (GObject *object, case PROP_META_SCREEN: priv->screen = g_value_get_pointer (value); break; - case PROP_X_WINDOW: - priv->xwindow = g_value_get_ulong (value); - break; case PROP_NO_SHADOW: { gboolean newv = g_value_get_boolean (value); @@ -571,9 +552,6 @@ meta_window_actor_get_property (GObject *object, case PROP_META_SCREEN: g_value_set_pointer (value, priv->screen); break; - case PROP_X_WINDOW: - g_value_set_ulong (value, priv->xwindow); - break; case PROP_NO_SHADOW: g_value_set_boolean (value, priv->no_shadow); break; @@ -841,20 +819,6 @@ meta_window_actor_has_shadow (MetaWindowActor *self) return FALSE; } -/** - * meta_window_actor_get_x_window: (skip) - * @self: a #MetaWindowActor - * - */ -Window -meta_window_actor_get_x_window (MetaWindowActor *self) -{ - if (!self) - return None; - - return self->priv->xwindow; -} - /** * meta_window_actor_get_meta_window: * @self: a #MetaWindowActor @@ -1406,7 +1370,7 @@ meta_window_actor_set_redirected (MetaWindowActor *self, gboolean state) MetaDisplay *display = meta_window_get_display (metaWindow); Display *xdisplay = meta_display_get_xdisplay (display); - Window xwin = meta_window_actor_get_x_window (self); + Window xwin = meta_window_get_toplevel_xwindow (metaWindow); if (state) { @@ -1670,25 +1634,11 @@ meta_window_actor_new (MetaWindow *window) MetaCompScreen *info = meta_screen_get_compositor_data (screen); MetaWindowActor *self; MetaWindowActorPrivate *priv; - Window top_window; ClutterActor *window_group; - if (window->client_type == META_WINDOW_CLIENT_TYPE_X11) - { - top_window = meta_window_get_toplevel_xwindow (window); - meta_verbose ("add window: Meta %p, xwin 0x%x\n", window, (guint)top_window); - } - else - { - meta_verbose ("add window: Meta %p, wayland surface %p\n", - window, window->surface); - top_window = None; - } - self = g_object_new (META_TYPE_WINDOW_ACTOR, - "meta-window", window, - "x-window", top_window, - "meta-screen", screen, + "meta-window", window, + "meta-screen", screen, NULL); priv = self->priv; @@ -1915,7 +1865,7 @@ check_needs_x11_pixmap (MetaWindowActor *self) MetaDisplay *display = meta_screen_get_display (screen); Display *xdisplay = meta_display_get_xdisplay (display); MetaCompScreen *info = meta_screen_get_compositor_data (screen); - Window xwindow = priv->xwindow; + Window xwindow = meta_window_get_toplevel_xwindow (priv->window); if (!priv->needs_pixmap) return; From 98dbba1e17a93d4cd0fc2f6ca5a36aab08677c7d Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 6 Dec 2013 17:18:56 -0500 Subject: [PATCH 354/889] window-actor: Remove meta-screen property This can be inferred from the window. Don't allow anybody to set it. https://bugzilla.gnome.org/show_bug.cgi?id=678989 --- src/compositor/meta-window-actor.c | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index c32afacc5..a2984311d 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -158,7 +158,6 @@ struct _FrameData enum { PROP_META_WINDOW = 1, - PROP_META_SCREEN, PROP_NO_SHADOW, PROP_SHADOW_CLASS }; @@ -233,15 +232,6 @@ meta_window_actor_class_init (MetaWindowActorClass *klass) PROP_META_WINDOW, pspec); - pspec = g_param_spec_pointer ("meta-screen", - "MetaScreen", - "MetaScreen", - G_PARAM_READWRITE | G_PARAM_CONSTRUCT); - - g_object_class_install_property (object_class, - PROP_META_SCREEN, - pspec); - pspec = g_param_spec_boolean ("no-shadow", "No shadow", "Do not add shaddow to this window", @@ -353,12 +343,14 @@ meta_window_actor_constructed (GObject *object) { MetaWindowActor *self = META_WINDOW_ACTOR (object); MetaWindowActorPrivate *priv = self->priv; - MetaScreen *screen = priv->screen; - MetaDisplay *display = meta_screen_get_display (screen); MetaWindow *window = priv->window; Window xwindow = meta_window_get_toplevel_xwindow (window); + MetaScreen *screen = meta_window_get_screen (window); + MetaDisplay *display = meta_screen_get_display (screen); Display *xdisplay = meta_display_get_xdisplay (display); + priv->screen = screen; + if (!meta_is_wayland_compositor ()) priv->damage = XDamageCreate (xdisplay, xwindow, XDamageReportBoundingBox); @@ -502,9 +494,6 @@ meta_window_actor_set_property (GObject *object, priv->window = g_value_dup_object (value); } break; - case PROP_META_SCREEN: - priv->screen = g_value_get_pointer (value); - break; case PROP_NO_SHADOW: { gboolean newv = g_value_get_boolean (value); @@ -549,9 +538,6 @@ meta_window_actor_get_property (GObject *object, case PROP_META_WINDOW: g_value_set_object (value, priv->window); break; - case PROP_META_SCREEN: - g_value_set_pointer (value, priv->screen); - break; case PROP_NO_SHADOW: g_value_set_boolean (value, priv->no_shadow); break; @@ -1638,7 +1624,6 @@ meta_window_actor_new (MetaWindow *window) self = g_object_new (META_TYPE_WINDOW_ACTOR, "meta-window", window, - "meta-screen", screen, NULL); priv = self->priv; From 65f2e2937544c7de68c3b3e4dfbe60c2be1e3286 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 23 Apr 2012 18:54:46 -0400 Subject: [PATCH 355/889] window-actor: Make the meta-window property construct-only We don't deal with setting this property at all, and it's unlikely to come up in future settings, so just don't allow setting it at all. https://bugzilla.gnome.org/show_bug.cgi?id=678989 --- src/compositor/meta-window-actor.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index a2984311d..42d202031 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -226,7 +226,7 @@ meta_window_actor_class_init (MetaWindowActorClass *klass) "MetaWindow", "The displayed MetaWindow", META_TYPE_WINDOW, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (object_class, PROP_META_WINDOW, @@ -488,11 +488,7 @@ meta_window_actor_set_property (GObject *object, switch (prop_id) { case PROP_META_WINDOW: - { - if (priv->window) - g_object_unref (priv->window); - priv->window = g_value_dup_object (value); - } + priv->window = g_value_dup_object (value); break; case PROP_NO_SHADOW: { From e30be380dde48c99b85a5782aa87bd2105db00d5 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 9 Dec 2013 13:45:12 -0500 Subject: [PATCH 356/889] window-actor: Move signal handler connections to the meta-window setter --- src/compositor/meta-window-actor.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 42d202031..8ea582982 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -383,11 +383,6 @@ meta_window_actor_constructed (GObject *object) g_signal_connect_object (priv->surface, "allocation-changed", G_CALLBACK (surface_allocation_changed_notify), self, 0); meta_window_actor_update_shape (self); - - g_signal_connect_object (window, "notify::decorated", - G_CALLBACK (window_decorated_notify), self, 0); - g_signal_connect_object (window, "notify::appears-focused", - G_CALLBACK (window_appears_focused_notify), self, 0); } else { @@ -489,6 +484,11 @@ meta_window_actor_set_property (GObject *object, { case PROP_META_WINDOW: priv->window = g_value_dup_object (value); + + g_signal_connect_object (priv->window, "notify::decorated", + G_CALLBACK (window_decorated_notify), self, 0); + g_signal_connect_object (priv->window, "notify::appears-focused", + G_CALLBACK (window_appears_focused_notify), self, 0); break; case PROP_NO_SHADOW: { From 66af41f4a9fe1bb92b122629a954061e529e396a Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 6 Dec 2013 01:01:26 -0500 Subject: [PATCH 357/889] window-actor: Remove outdated code path The shadow is added in the paint step, not as a separate actor, so the raise is a no-op. It also gets rid of an annoying misspelling that's driving me crazy. --- src/compositor/meta-window-actor.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 8ea582982..b15cc8fe4 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -384,14 +384,6 @@ meta_window_actor_constructed (GObject *object) G_CALLBACK (surface_allocation_changed_notify), self, 0); meta_window_actor_update_shape (self); } - else - { - /* - * This is the case where existing window is gaining/loosing frame. - * Just ensure the actor is top most (i.e., above shadow). - */ - clutter_actor_set_child_above_sibling (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface), NULL); - } meta_window_actor_update_opacity (self); From bad48ea8155d94af7b62bf4ff42d747f27c7464c Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Mon, 9 Dec 2013 21:24:35 +0100 Subject: [PATCH 358/889] introspection: Make MetaKeyHandlerFunc compatible with master This allows gnome-shell's JS handlers work on the wayland branch. --- src/meta/prefs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/meta/prefs.h b/src/meta/prefs.h index 3205ea3b4..93dcfbdf9 100644 --- a/src/meta/prefs.h +++ b/src/meta/prefs.h @@ -393,7 +393,7 @@ struct _MetaKeyCombo * @display: a #MetaDisplay * @screen: a #MetaScreen * @window: a #MetaWindow - * @event: a #ClutterKeyEvent + * @event: (type gpointer): a #ClutterKeyEvent * @binding: a #MetaKeyBinding * @user_data: data passed to the function * From f29241d90ef48de4218237d7b7bbec8881f59f5c Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 6 Dec 2013 13:34:08 -0500 Subject: [PATCH 359/889] compositor: Remove atom_x_root_pixmap It's unused --- src/compositor/compositor-private.h | 1 - src/compositor/compositor.c | 4 +--- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/compositor/compositor-private.h b/src/compositor/compositor-private.h index 0ebf3a439..494a77b06 100644 --- a/src/compositor/compositor-private.h +++ b/src/compositor/compositor-private.h @@ -17,7 +17,6 @@ struct _MetaCompositor { MetaDisplay *display; - Atom atom_x_root_pixmap; Atom atom_net_wm_window_opacity; guint repaint_func_id; diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index eaefa3250..83feb4330 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -1650,7 +1650,6 @@ MetaCompositor * meta_compositor_new (MetaDisplay *display) { char *atom_names[] = { - "_XROOTPMAP_ID", "_NET_WM_WINDOW_OPACITY", }; Atom atoms[G_N_ELEMENTS(atom_names)]; @@ -1676,8 +1675,7 @@ meta_compositor_new (MetaDisplay *display) G_CALLBACK (on_shadow_factory_changed), compositor); - compositor->atom_x_root_pixmap = atoms[0]; - compositor->atom_net_wm_window_opacity = atoms[1]; + compositor->atom_net_wm_window_opacity = atoms[0]; compositor->repaint_func_id = clutter_threads_add_repaint_func (meta_repaint_func, compositor, From 8131f34eb641f01cfc9a5cd82e1c744d04b81861 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 6 Dec 2013 13:44:31 -0500 Subject: [PATCH 360/889] Move _NET_WM_WINDOW_OPACITY handling to the standard window-props interface --- src/compositor/compositor-private.h | 1 - src/compositor/compositor.c | 79 +++++++++-------------------- src/compositor/meta-window-actor.c | 43 +++++++--------- src/core/window-private.h | 6 +++ src/core/window-props.c | 15 ++++++ src/core/window.c | 12 +++++ src/meta/atomnames.h | 1 + src/meta/compositor.h | 2 + 8 files changed, 77 insertions(+), 82 deletions(-) diff --git a/src/compositor/compositor-private.h b/src/compositor/compositor-private.h index 494a77b06..2e8d85fd9 100644 --- a/src/compositor/compositor-private.h +++ b/src/compositor/compositor-private.h @@ -17,7 +17,6 @@ struct _MetaCompositor { MetaDisplay *display; - Atom atom_net_wm_window_opacity; guint repaint_func_id; ClutterActor *shadow_src; diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 83feb4330..d2598f48b 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -179,31 +179,6 @@ process_damage (MetaCompositor *compositor, meta_window_actor_process_x11_damage (window_actor, event); } -static void -process_property_notify (MetaCompositor *compositor, - XPropertyEvent *event, - MetaWindow *window) -{ - MetaWindowActor *window_actor; - - if (window == NULL) - return; - - window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - if (window_actor == NULL) - return; - - /* Check for the opacity changing */ - if (event->atom == compositor->atom_net_wm_window_opacity) - { - meta_window_actor_update_opacity (window_actor); - DEBUG_TRACE ("process_property_notify: net_wm_window_opacity\n"); - return; - } - - DEBUG_TRACE ("process_property_notify: unknown\n"); -} - static Window get_output_window (MetaScreen *screen) { @@ -998,6 +973,18 @@ meta_compositor_window_shape_changed (MetaCompositor *compositor, meta_window_actor_update_shape (window_actor); } +void +meta_compositor_window_opacity_changed (MetaCompositor *compositor, + MetaWindow *window) +{ + MetaWindowActor *window_actor; + window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); + if (!window_actor) + return; + + meta_window_actor_update_opacity (window_actor); +} + /* Clutter makes the assumption that there is only one X window * per stage, which is a valid assumption to make for a generic * application toolkit. As such, it will ignore any events sent @@ -1102,29 +1089,20 @@ meta_compositor_process_event (MetaCompositor *compositor, } } - switch (event->type) + if (!meta_is_wayland_compositor () && + event->type == meta_display_get_damage_event_base (compositor->display) + XDamageNotify) { - case PropertyNotify: - process_property_notify (compositor, (XPropertyEvent *) event, window); - break; - - default: - if (!meta_is_wayland_compositor () && - event->type == meta_display_get_damage_event_base (compositor->display) + XDamageNotify) + /* Core code doesn't handle damage events, so we need to extract the MetaWindow + * ourselves + */ + if (window == NULL) { - /* Core code doesn't handle damage events, so we need to extract the MetaWindow - * ourselves - */ - if (window == NULL) - { - Window xwin = ((XDamageNotifyEvent *) event)->drawable; - window = meta_display_lookup_x_window (compositor->display, xwin); - } - - DEBUG_TRACE ("meta_compositor_process_event (process_damage)\n"); - process_damage (compositor, (XDamageNotifyEvent *) event, window); + Window xwin = ((XDamageNotifyEvent *) event)->drawable; + window = meta_display_lookup_x_window (compositor->display, xwin); } - break; + + DEBUG_TRACE ("meta_compositor_process_event (process_damage)\n"); + process_damage (compositor, (XDamageNotifyEvent *) event, window); } /* Clutter needs to know about MapNotify events otherwise it will @@ -1649,12 +1627,7 @@ on_shadow_factory_changed (MetaShadowFactory *factory, MetaCompositor * meta_compositor_new (MetaDisplay *display) { - char *atom_names[] = { - "_NET_WM_WINDOW_OPACITY", - }; - Atom atoms[G_N_ELEMENTS(atom_names)]; MetaCompositor *compositor; - Display *xdisplay = meta_display_get_xdisplay (display); if (!composite_at_least_version (display, 0, 3)) return NULL; @@ -1666,17 +1639,11 @@ meta_compositor_new (MetaDisplay *display) if (g_getenv("META_DISABLE_MIPMAPS")) compositor->no_mipmaps = TRUE; - meta_verbose ("Creating %d atoms\n", (int) G_N_ELEMENTS (atom_names)); - XInternAtoms (xdisplay, atom_names, G_N_ELEMENTS (atom_names), - False, atoms); - g_signal_connect (meta_shadow_factory_get_default (), "changed", G_CALLBACK (on_shadow_factory_changed), compositor); - compositor->atom_net_wm_window_opacity = atoms[0]; - compositor->repaint_func_id = clutter_threads_add_repaint_func (meta_repaint_func, compositor, NULL); diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index b15cc8fe4..be54ec23f 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -67,8 +67,6 @@ struct _MetaWindowActorPrivate MetaShadow *focused_shadow; MetaShadow *unfocused_shadow; - guint8 opacity; - /* A region that matches the shape of the window, including frame bounds */ cairo_region_t *shape_region; /* The region we should clip to when painting the shadow */ @@ -274,7 +272,6 @@ meta_window_actor_init (MetaWindowActor *self) priv = self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, META_TYPE_WINDOW_ACTOR, MetaWindowActorPrivate); - priv->opacity = 0xff; priv->shadow_class = NULL; } @@ -338,6 +335,15 @@ surface_allocation_changed_notify (ClutterActor *actor, g_signal_emit (self, signals[SIZE_CHANGED], 0); } +static gboolean +is_non_opaque (MetaWindowActor *self) +{ + MetaWindowActorPrivate *priv = self->priv; + MetaWindow *window = priv->window; + + return priv->argb32 || (window->opacity != 0xFF); +} + static void meta_window_actor_constructed (GObject *object) { @@ -623,7 +629,7 @@ clip_shadow_under_window (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; - return (priv->argb32 || priv->opacity != 0xff) && priv->window->frame; + return is_non_opaque (self) && priv->window->frame; } static void @@ -649,6 +655,7 @@ meta_window_actor_paint (ClutterActor *actor) MetaShadowParams params; cairo_rectangle_int_t shape_bounds; cairo_region_t *clip = priv->shadow_clip; + MetaWindow *window = priv->window; meta_window_actor_get_shape_bounds (self, &shape_bounds); meta_window_actor_get_shadow_params (self, appears_focused, ¶ms); @@ -672,7 +679,7 @@ meta_window_actor_paint (ClutterActor *actor) params.y_offset + shape_bounds.y, shape_bounds.width, shape_bounds.height, - (clutter_actor_get_paint_opacity (actor) * params.opacity * priv->opacity) / (255 * 255), + (clutter_actor_get_paint_opacity (actor) * params.opacity * window->opacity) / (255 * 255), clip, clip_shadow_under_window (self)); /* clip_strictly - not just as an optimization */ @@ -759,10 +766,10 @@ meta_window_actor_has_shadow (MetaWindowActor *self) return TRUE; /* - * Do not add shadows to ARGB windows; eventually we should generate a - * shadow from the input shape for such windows. + * Do not add shadows to non-opaque windows; eventually we should generate + * a shadow from the input shape for such windows. */ - if (priv->argb32 || priv->opacity != 0xff) + if (is_non_opaque (self)) return FALSE; /* @@ -1313,7 +1320,7 @@ meta_window_actor_should_unredirect (MetaWindowActor *self) if (meta_window_requested_dont_bypass_compositor (metaWindow)) return FALSE; - if (priv->opacity != 0xff) + if (metaWindow->opacity != 0xFF) return FALSE; if (metaWindow->shape_region != NULL) @@ -2572,23 +2579,9 @@ void meta_window_actor_update_opacity (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; - MetaDisplay *display = meta_screen_get_display (priv->screen); - MetaCompositor *compositor = meta_display_get_compositor (display); - Window xwin = meta_window_get_xwindow (priv->window); - gulong value; - guint8 opacity; + MetaWindow *window = priv->window; - if (meta_prop_get_cardinal (display, xwin, - compositor->atom_net_wm_window_opacity, - &value)) - { - opacity = (guint8)((gfloat)value * 255.0 / ((gfloat)0xffffffff)); - } - else - opacity = 255; - - self->priv->opacity = opacity; - clutter_actor_set_opacity (CLUTTER_ACTOR (self->priv->surface), opacity); + clutter_actor_set_opacity (CLUTTER_ACTOR (self->priv->surface), window->opacity); } void diff --git a/src/core/window-private.h b/src/core/window-private.h index 485c495ed..0e0631aff 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -367,6 +367,9 @@ struct _MetaWindow /* the input shape region for picking */ cairo_region_t *input_region; + /* _NET_WM_WINDOW_OPACITY */ + guint opacity; + /* if TRUE, the we have the new form of sync request counter which * also handles application frames */ guint extended_sync_request_counter : 1; @@ -735,6 +738,9 @@ void meta_window_set_gtk_dbus_properties (MetaWindow *window, void meta_window_set_transient_for (MetaWindow *window, MetaWindow *parent); +void meta_window_set_opacity (MetaWindow *window, + guint opacity); + void meta_window_handle_enter (MetaWindow *window, guint32 timestamp, guint root_x, diff --git a/src/core/window-props.c b/src/core/window-props.c index cd4d012ae..447ac3e92 100644 --- a/src/core/window-props.c +++ b/src/core/window-props.c @@ -1655,6 +1655,20 @@ reload_bypass_compositor (MetaWindow *window, window->bypass_compositor = requested_value; } +static void +reload_window_opacity (MetaWindow *window, + MetaPropValue *value, + gboolean initial) + +{ + int requested_value = 0xFF; + + if (value->type != META_PROP_VALUE_INVALID) + requested_value = (int) value->v.cardinal; + + meta_window_set_opacity (window, requested_value); +} + #define RELOAD_STRING(var_name, propname) \ static void \ reload_ ## var_name (MetaWindow *window, \ @@ -1757,6 +1771,7 @@ meta_display_init_window_prop_hooks (MetaDisplay *display) { display->atom__NET_WM_STRUT, META_PROP_VALUE_INVALID, reload_struts, FALSE, FALSE }, { display->atom__NET_WM_STRUT_PARTIAL, META_PROP_VALUE_INVALID, reload_struts, FALSE, FALSE }, { display->atom__NET_WM_BYPASS_COMPOSITOR, META_PROP_VALUE_CARDINAL, reload_bypass_compositor, FALSE, FALSE }, + { display->atom__NET_WM_WINDOW_OPACITY, META_PROP_VALUE_CARDINAL, reload_window_opacity, TRUE, TRUE }, { 0 }, }; diff --git a/src/core/window.c b/src/core/window.c index 1a65ea6a1..f000c3feb 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -1077,6 +1077,8 @@ meta_window_new_shared (MetaDisplay *display, else meta_display_register_wayland_window (display, window); + window->opacity = 0xFF; + /* assign the window to its group, or create a new group if needed */ window->group = NULL; @@ -11959,6 +11961,16 @@ meta_window_set_transient_for (MetaWindow *window, meta_window_propagate_focus_appearance (window, TRUE); } +void +meta_window_set_opacity (MetaWindow *window, + guint opacity) +{ + window->opacity = opacity; + + if (window->display->compositor) + meta_compositor_window_opacity_changed (window->display->compositor, window); +} + static void reset_ignored_crossing_serials (MetaDisplay *display) { diff --git a/src/meta/atomnames.h b/src/meta/atomnames.h index e90b0abe4..f83ff8cbe 100644 --- a/src/meta/atomnames.h +++ b/src/meta/atomnames.h @@ -180,6 +180,7 @@ item(_NET_WM_BYPASS_COMPOSITOR) item(_NET_WM_OPAQUE_REGION) item(_NET_WM_FRAME_DRAWN) item(_NET_WM_FRAME_TIMINGS) +item(_NET_WM_WINDOW_OPACITY) #if 0 /* We apparently never use: */ diff --git a/src/meta/compositor.h b/src/meta/compositor.h index 13143c992..b0e54550d 100644 --- a/src/meta/compositor.h +++ b/src/meta/compositor.h @@ -66,6 +66,8 @@ void meta_compositor_unmanage_screen (MetaCompositor *compositor, void meta_compositor_window_shape_changed (MetaCompositor *compositor, MetaWindow *window); +void meta_compositor_window_opacity_changed (MetaCompositor *compositor, + MetaWindow *window); gboolean meta_compositor_process_event (MetaCompositor *compositor, XEvent *event, From c54a19825b8fd8620925e7b500c646be51432685 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 11 Dec 2013 17:57:45 +0100 Subject: [PATCH 361/889] keybinding: Implement keybindings for moving windows between monitors Currently the only way to move a window to another monitor via keyboard is to start a move operation and move it manually using arrow keys. We do have all the bits of a dedicated keybinding in place already, so offer it as a more comfortable alternative. https://bugzilla.gnome.org/show_bug.cgi?id=671054 --- src/core/keybindings.c | 49 ++++++++++++++++++++++++++++++++++++++++++ src/meta/prefs.h | 8 +++++++ 2 files changed, 57 insertions(+) diff --git a/src/core/keybindings.c b/src/core/keybindings.c index aa137d20b..1f40c6841 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -41,6 +41,7 @@ #include "ui.h" #include "frame.h" #include "place.h" +#include "screen-private.h" #include #include "util-private.h" @@ -3929,6 +3930,26 @@ handle_move_to_workspace (MetaDisplay *display, } } +static void +handle_move_to_monitor (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) +{ + gint which = binding->handler->data; + const MetaMonitorInfo *current, *new; + + current = meta_screen_get_monitor_for_window (screen, window); + new = meta_screen_get_monitor_neighbor (screen, current->number, which); + + if (new == NULL) + return; + + meta_window_move_to_monitor (window, new->number); +} + static void handle_raise_or_lower (MetaDisplay *display, MetaScreen *screen, @@ -4670,6 +4691,34 @@ init_builtin_key_bindings (MetaDisplay *display) META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_DOWN, handle_move_to_workspace, META_MOTION_DOWN); + add_builtin_keybinding (display, + "move-to-monitor-left", + common_keybindings, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_MOVE_TO_MONITOR_LEFT, + handle_move_to_monitor, META_SCREEN_LEFT); + + add_builtin_keybinding (display, + "move-to-monitor-right", + common_keybindings, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_MOVE_TO_MONITOR_RIGHT, + handle_move_to_monitor, META_SCREEN_RIGHT); + + add_builtin_keybinding (display, + "move-to-monitor-down", + common_keybindings, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_MOVE_TO_MONITOR_DOWN, + handle_move_to_monitor, META_SCREEN_DOWN); + + add_builtin_keybinding (display, + "move-to-monitor-up", + common_keybindings, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_MOVE_TO_MONITOR_UP, + handle_move_to_monitor, META_SCREEN_UP); + add_builtin_keybinding (display, "raise-or-lower", common_keybindings, diff --git a/src/meta/prefs.h b/src/meta/prefs.h index 93dcfbdf9..3ccaddb20 100644 --- a/src/meta/prefs.h +++ b/src/meta/prefs.h @@ -243,6 +243,10 @@ void meta_prefs_set_ignore_request_hide_titlebar (gboolean whether); * @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_RIGHT: FILLME * @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_UP: FILLME * @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_DOWN: FILLME + * @META_KEYBINDING_ACTION_MOVE_TO_MONITOR_LEFT: FILLME + * @META_KEYBINDING_ACTION_MOVE_TO_MONITOR_RIGHT: FILLME + * @META_KEYBINDING_ACTION_MOVE_TO_MONITOR_UP: FILLME + * @META_KEYBINDING_ACTION_MOVE_TO_MONITOR_DOWN: FILLME * @META_KEYBINDING_ACTION_RAISE_OR_LOWER: FILLME * @META_KEYBINDING_ACTION_RAISE: FILLME * @META_KEYBINDING_ACTION_LOWER: FILLME @@ -336,6 +340,10 @@ typedef enum _MetaKeyBindingAction META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_RIGHT, META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_UP, META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_DOWN, + META_KEYBINDING_ACTION_MOVE_TO_MONITOR_LEFT, + META_KEYBINDING_ACTION_MOVE_TO_MONITOR_RIGHT, + META_KEYBINDING_ACTION_MOVE_TO_MONITOR_UP, + META_KEYBINDING_ACTION_MOVE_TO_MONITOR_DOWN, META_KEYBINDING_ACTION_RAISE_OR_LOWER, META_KEYBINDING_ACTION_RAISE, META_KEYBINDING_ACTION_LOWER, From 7009d1e470d7cf6df9763b725e70036322c88372 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 17 Dec 2013 15:04:16 -0500 Subject: [PATCH 362/889] wayland: Update to latest xdg-shell We don't use the new maximize / fullscreen request system yet, leading to broken maximization / fullscreen. This will be fixed in a followup. --- protocol/xdg-shell.xml | 83 ++++++++++++++++++++++++------ src/wayland/meta-wayland-surface.c | 4 +- 2 files changed, 69 insertions(+), 18 deletions(-) diff --git a/protocol/xdg-shell.xml b/protocol/xdg-shell.xml index e1249b06e..4e5cff8df 100644 --- a/protocol/xdg-shell.xml +++ b/protocol/xdg-shell.xml @@ -223,9 +223,6 @@ area might adjust its content position to leave the viewable content unmoved). Valid edge values are from resize_edge enum. - The maximized parameter informs if the surface is in a maximized - state. Same for the fullscreen parameter. - The client is free to dismiss all but the last configure event it received. @@ -236,8 +233,6 @@ - - @@ -255,16 +250,43 @@ + + + Event sent from the compositor to the client requesting that the client + goes to a fullscreen state. It's the client job to call set_fullscreen + and really trigger the fullscreen state. + + + + + + Event sent from the compositor to the client requesting that the client + leaves the fullscreen state. It's the client job to call + unset_fullscreen and really leave the fullscreen state. + + + Set the surface as fullscreen. - The compositor must reply to this request with a configure event - with the dimensions for the output on which the surface will be - made fullscreen. + After this request, the compositor should send a configure event + informing the output size. - Once the fullscreen state is set, a "fullscreen_set" event will - be sent to the client. + This request informs the compositor that the next attached buffer + committed will be in a fullscreen state. The buffer size should be the + same size as the size informed in the configure event, if the client + doesn't want to leave any empty area. + + In other words: the next attached buffer after set_maximized is the new + maximized buffer. And the surface will be positioned at the maximized + position on commit. + + A simple way to synchronize and wait for the correct configure event is + to use a wl_display.sync request right after the set_fullscreen + request. When the sync callback returns, the last configure event + received just before it will be the correct one, and should contain the + right size for the surface to maximize. Setting one state won't unset another state. Use xdg_surface.unset_fullscreen for unsetting it. @@ -274,19 +296,48 @@ Unset the surface fullscreen state. + + Same negotiation as set_fullscreen must be used. + + + Event sent from the compositor to the client requesting that the client + goes to a maximized state. It's the client job to call set_maximized + and really trigger the maximized state. + + + + + + Event sent from the compositor to the client requesting that the client + leaves the maximized state. It's the client job to call unset_maximized + and really leave the maximized state. + + + Set the surface as maximized. - The compositor must reply to this request with a configure event - with the dimensions for the output on which the surface will be - made maximized. + After this request, the compositor will send a configure event + informing the output size minus panel and other MW decorations. - Once the maximized state is set, a "maximized_set" event will be - sent to the client. + This request informs the compositor that the next attached buffer + committed will be in a maximized state. The buffer size should be the + same size as the size informed in the configure event, if the client + doesn't want to leave any empty area. + + In other words: the next attached buffer after set_maximized is the new + maximized buffer. And the surface will be positioned at the maximized + position on commit. + + A simple way to synchronize and wait for the correct configure event is + to use a wl_display.sync request right after the set_maximized request. + When the sync callback returns, the last configure event received just + before it will be the correct one, and should contain the right size + for the surface to maximize. Setting one state won't unset another state. Use xdg_surface.unset_maximized for unsetting it. @@ -296,6 +347,8 @@ Unset the surface maximized state. + + Same negotiation as set_maximized must be used. diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 832c700b2..7452c42bf 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -1161,9 +1161,7 @@ meta_wayland_surface_configure_notify (MetaWaylandSurface *surface, { if (surface->xdg_surface.resource) xdg_surface_send_configure (surface->xdg_surface.resource, - edges, new_width, new_height, - meta_window_get_maximized (surface->window), - meta_window_is_fullscreen (surface->window)); + edges, new_width, new_height); } void From cb33e1942ad47eb5dbbd682362ced5e06fb768c4 Mon Sep 17 00:00:00 2001 From: "Owen W. Taylor" Date: Fri, 13 Dec 2013 13:53:54 -0500 Subject: [PATCH 363/889] meta_window_move_resize_internal: handle border size changes Initial placement during meta_window_constrain() can result in changes to the borders, so we need to recompute our border sizes after constraining. This fixes incorrect window borders on initially maximized windows. https://bugzilla.gnome.org/show_bug.cgi?id=720417 --- src/core/window.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/core/window.c b/src/core/window.c index f000c3feb..0f9e24147 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -5245,6 +5245,11 @@ meta_window_move_resize_internal (MetaWindow *window, * the interaction with frames and the synthetic configure notifies. */ + /* meta_window_constrain() might have maximized the window after placement, + * changing the borders. + */ + meta_frame_calc_borders (window->frame, &borders); + root_x_nw = new_rect.x; root_y_nw = new_rect.y; w = new_rect.width; From 9c1b972ca15dafc8899e96c1425805248f0a4b40 Mon Sep 17 00:00:00 2001 From: "Owen W. Taylor" Date: Mon, 16 Dec 2013 16:01:04 -0500 Subject: [PATCH 364/889] Fix problems with focus tracking When a client spontaneously focuses their window, perhaps in response to WM_TAKE_FOCUS we'll get a FocusOut/FocusIn pair with same serial. Updating display->focus_serial in response to FocusOut then was causing us to ignore FocusIn and think that the focus was not on any window. We need to distinguish this spontaneous case from the case where we set the focus ourselves - when we set the focus ourselves, we're careful to combine the SetFocus with a property change so that we know definitively what focus events we have already accounted for. https://bugzilla.gnome.org/show_bug.cgi?id=720558 --- src/core/display-private.h | 8 ++++++++ src/core/display.c | 25 +++++++++++++++++++------ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/core/display-private.h b/src/core/display-private.h index 169682ee8..a8fa75363 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -145,6 +145,14 @@ struct _MetaDisplay */ guint allow_terminal_deactivation : 1; + /* If true, server->focus_serial refers to us changing the focus; in + * this case, we can ignore focus events that have exactly focus_serial, + * since we take care to make another request immediately afterwards. + * But if focus is being changed by another client, we have to accept + * multiple events with the same serial. + */ + guint focused_by_us : 1; + guint static_gravity_works : 1; /*< private-ish >*/ diff --git a/src/core/display.c b/src/core/display.c index 0f20d143b..455db3120 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -1670,11 +1670,13 @@ update_focus_window (MetaDisplay *display, MetaFocusType type, MetaWindow *window, Window xwindow, - gulong serial) + gulong serial, + gboolean focused_by_us) { MetaWaylandCompositor *compositor; display->focus_serial = serial; + display->focused_by_us = focused_by_us; if (display->focus_xwindow == xwindow && display->focus_type == type && @@ -1811,7 +1813,8 @@ request_xserver_input_focus_change (MetaDisplay *display, type, meta_window, xwindow, - serial); + serial, + TRUE); meta_error_trap_pop (display); @@ -1940,13 +1943,21 @@ handle_window_focus_event (MetaDisplay *display, else g_return_if_reached (); - if (display->server_focus_serial > display->focus_serial) + /* If display->focused_by_us, then the focus_serial will be used only + * for a focus change we made and have already accounted for. + * (See request_xserver_input_focus_change().) Otherwise, we can get + * multiple focus events with the same serial. + */ + if (display->server_focus_serial > display->focus_serial || + (!display->focused_by_us && + display->server_focus_serial == display->focus_serial)) { update_focus_window (display, type, focus_window, focus_window ? focus_window->xwindow : None, - display->server_focus_serial); + display->server_focus_serial, + FALSE); } } @@ -3185,7 +3196,8 @@ meta_display_handle_xevent (MetaDisplay *display, display->current_time = event_get_time (display, event); display->monitor_cache_invalidated = TRUE; - if (event->xany.serial > display->focus_serial && + if (display->focused_by_us && + event->xany.serial > display->focus_serial && display->focus_window && !window_has_xwindow (display->focus_window, display->server_focus_window)) { @@ -3195,7 +3207,8 @@ meta_display_handle_xevent (MetaDisplay *display, META_FOCUS_NONE, meta_display_lookup_x_window (display, display->server_focus_window), display->server_focus_window, - display->server_focus_serial); + display->server_focus_serial, + FALSE); } screen = meta_display_screen_for_root (display, event->xany.window); From ef2b6e7d008cb1a3a80b12b70c27af4c44edd6c5 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 6 Dec 2013 11:44:42 -0500 Subject: [PATCH 365/889] window-actor: Fix optimization in get_paint_volume We need to clip the paint volume to the unobscured region, not the other way around... https://bugzilla.gnome.org/show_bug.cgi?id=720630 --- src/compositor/meta-window-actor.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index be54ec23f..c5a2af43d 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -722,7 +722,11 @@ meta_window_actor_get_paint_volume (ClutterActor *actor, } if (priv->unobscured_region) - cairo_region_intersect_rectangle (priv->unobscured_region, &bounds); + { + cairo_rectangle_int_t unobscured_bounds; + cairo_region_get_extents (priv->unobscured_region, &unobscured_bounds); + gdk_rectangle_intersect (&bounds, &unobscured_bounds, &bounds); + } origin.x = bounds.x; origin.y = bounds.y; From 732c0592356811dbaa0e68ad9b00e78e07a2ed96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Thu, 19 Dec 2013 19:34:06 +0100 Subject: [PATCH 366/889] Bump version to 3.11.3 Update NEWS. --- NEWS | 17 +++++++++++++++++ configure.ac | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index b4d0e9011..cda6cf287 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,20 @@ +3.11.3 +====== +* Fix focus issues with external OSKs[Jasper; #715030] +* Add a MetaCullable interface [Jasper; #714706] +* Fix window keybindings [Rui; #719724] +* Fix settings keyboard/pointer focus for new clients [Rui; #719725] +* Fix window group paint volume [Owen; #719669] +* Fix frame extents problems [Owen; #714707] +* Add shortcut to move windows between monitors [Florian; #671054] +* Fix problems with focus tracking [Owen; #720558] +* Misc. bug fixes and cleanups: [Rui, Colin, Lionel, Jasper, Owen; #712833, + #719557, #719695, #719833, #678989, #720417, #720630] + +Contributors: + Lionel Landwerlin, Rui Matos, Alberto Milone, Florian Müllner, + Jasper St. Pierre, Rico Tzschichholz, Owen W. Taylor, Colin Walters + 3.11.2 ====== * Support setting a NULL opaque region [Andreas; #711518] diff --git a/configure.ac b/configure.ac index 7969a71e2..dad1e2ce9 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ AC_CONFIG_MACRO_DIR([m4]) m4_define([mutter_major_version], [3]) m4_define([mutter_minor_version], [11]) -m4_define([mutter_micro_version], [2]) +m4_define([mutter_micro_version], [3]) m4_define([mutter_version], [mutter_major_version.mutter_minor_version.mutter_micro_version]) From a42305edaba81ccd01e4ef2634c40543d2517245 Mon Sep 17 00:00:00 2001 From: "Owen W. Taylor" Date: Wed, 18 Dec 2013 09:23:08 -0500 Subject: [PATCH 367/889] Be willing to unfocus the grab window when we are unmanaging it When we are unmanaging the grab window, we /need/ to unfocus it, so we shouldn't bail out early from meta_window_focus(). https://bugzilla.gnome.org/show_bug.cgi?id=711618 --- src/core/window.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/window.c b/src/core/window.c index 0f9e24147..96d62bff5 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -6291,7 +6291,8 @@ meta_window_focus (MetaWindow *window, window->desc, window->input, window->take_focus); if (window->display->grab_window && - window->display->grab_window->all_keys_grabbed) + window->display->grab_window->all_keys_grabbed && + !window->display->grab_window->unmanaging) { meta_topic (META_DEBUG_FOCUS, "Current focus window %s has global keygrab, not focusing window %s after all\n", From 0caf7381bbfe67fcdc4589773890bff9b58637d2 Mon Sep 17 00:00:00 2001 From: "Owen W. Taylor" Date: Mon, 16 Dec 2013 12:20:02 -0500 Subject: [PATCH 368/889] display: Don't leave focus on a window we are unmanaging when sending WM_TAKE_FOCUS When we move focus elsewhere when unmanaging a window, we *need* to move the focus, so if the target is globally active, move the focus to the no-focus-window in anticipation that the focus will normally get moved to the right window when the target window responds to WM_TAKE_FOCUS. If the window doesn't respond to WM_TAKE_FOCUS, then focus will be left on the no-focus-window, but there's no way to distinguish whether the app will respond or not. https://bugzilla.gnome.org/show_bug.cgi?id=711618 --- src/core/window.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/core/window.c b/src/core/window.c index 96d62bff5..6152d518a 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -6363,6 +6363,25 @@ meta_window_focus (MetaWindow *window, "Sending WM_TAKE_FOCUS to %s since take_focus = true\n", window->desc); + if (!window->input) + { + /* The "Globally Active Input" window case, where the window + * doesn't want us to call XSetInputFocus on it, but does + * want us to send a WM_TAKE_FOCUS. + * + * Normally, we want to just leave the focus undisturbed until + * the window respnds to WM_TAKE_FOCUS, but if we're unmanaging + * the current focus window we *need* to move the focus away, so + * we focus the no_focus_window now (and set + * display->focus_window to that) before sending WM_TAKE_FOCUS. + */ + if (window->display->focus_window != NULL && + window->display->focus_window->unmanaging) + meta_display_focus_the_no_focus_window (window->display, + window->screen, + timestamp); + } + meta_display_request_take_focus (window->display, window, timestamp); From a3de799939e377cca5f9818d48438938d1e6c89f Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 31 Dec 2013 19:20:58 -0500 Subject: [PATCH 369/889] wayland-surface: Remove inappropriate meta-weston-launch.h include --- src/wayland/meta-wayland-surface.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 7452c42bf..1ca38e564 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -56,7 +56,6 @@ #include #include "frame.h" #include "meta-idle-monitor-private.h" -#include "meta-weston-launch.h" #include "monitor-private.h" static void From ebe6e3180ed842445c5145c6947aae9c3fa270a5 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 31 Dec 2013 17:44:35 -0500 Subject: [PATCH 370/889] meta-weston-launch: Call VT_ACTIVATE ourselves We don't need any special permissions, so we don't need to go through weston-launch to do so... --- src/core/keybindings.c | 39 ++++++++++++++---------------- src/wayland/meta-wayland-private.h | 1 - src/wayland/meta-wayland.c | 6 ----- src/wayland/meta-weston-launch.c | 14 ----------- src/wayland/meta-weston-launch.h | 4 --- src/wayland/weston-launch.c | 37 ---------------------------- src/wayland/weston-launch.h | 3 +-- 7 files changed, 19 insertions(+), 85 deletions(-) diff --git a/src/core/keybindings.c b/src/core/keybindings.c index 1f40c6841..515e591d1 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -56,6 +56,9 @@ #ifdef HAVE_WAYLAND #include "meta-wayland-private.h" +#include +#include +#include #endif #define SCHEMA_COMMON_KEYBINDINGS "org.gnome.desktop.wm.keybindings" @@ -4083,6 +4086,18 @@ handle_set_spew_mark (MetaDisplay *display, } #ifdef HAVE_WAYLAND +static gboolean +activate_vt (int vt) +{ + int tty, reply; + + tty = open ("/dev/tty", O_RDWR | O_NOCTTY | O_CLOEXEC); + reply = ioctl (tty, VT_ACTIVATE, vt); + close (tty); + + return (reply == 0); +} + static void handle_switch_vt (MetaDisplay *display, MetaScreen *screen, @@ -4091,28 +4106,10 @@ handle_switch_vt (MetaDisplay *display, MetaKeyBinding *binding, gpointer dummy) { - gint vt = binding->handler->data; - MetaWaylandCompositor *compositor; - MetaLauncher *launcher; + gint vt = binding->handler->data; - compositor = meta_wayland_compositor_get_default (); - launcher = meta_wayland_compositor_get_launcher (compositor); - - if (launcher) - { - GError *error; - - error = NULL; - if (!meta_launcher_activate_vt (launcher, vt, &error)) - { - g_warning ("Failed to switch VT: %s", error->message); - g_error_free (error); - } - } - else - { - g_debug ("Ignoring VT switch keybinding, not running as VT manager"); - } + if (!activate_vt (vt)) + g_warning ("Failed to switch VT"); } #endif diff --git a/src/wayland/meta-wayland-private.h b/src/wayland/meta-wayland-private.h index e444ae596..353303456 100644 --- a/src/wayland/meta-wayland-private.h +++ b/src/wayland/meta-wayland-private.h @@ -99,7 +99,6 @@ void meta_wayland_compositor_set_input_focus (MetaWaylandComp gboolean meta_wayland_compositor_handle_event (MetaWaylandCompositor *compositor, const ClutterEvent *event); -MetaLauncher *meta_wayland_compositor_get_launcher (MetaWaylandCompositor *compositor); gboolean meta_wayland_compositor_is_native (MetaWaylandCompositor *compositor); MetaWaylandBuffer * meta_wayland_buffer_from_resource (struct wl_resource *resource); diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index 4cee683cc..20d0dcd28 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -754,12 +754,6 @@ meta_wayland_finalize (void) g_clear_object (&compositor->launcher); } -MetaLauncher * -meta_wayland_compositor_get_launcher (MetaWaylandCompositor *compositor) -{ - return compositor->launcher; -} - gboolean meta_wayland_compositor_is_native (MetaWaylandCompositor *compositor) { diff --git a/src/wayland/meta-weston-launch.c b/src/wayland/meta-weston-launch.c index 709eacc5a..184a48d94 100644 --- a/src/wayland/meta-weston-launch.c +++ b/src/wayland/meta-weston-launch.c @@ -437,17 +437,3 @@ meta_launcher_new (void) { return g_object_new (META_TYPE_LAUNCHER, NULL); } - -gboolean -meta_launcher_activate_vt (MetaLauncher *launcher, - int vt, - GError **error) -{ - struct weston_launcher_activate_vt message; - - message.header.opcode = WESTON_LAUNCHER_ACTIVATE_VT; - message.vt = vt; - - return send_message_to_wl (launcher, &message, sizeof (message), NULL, NULL, error); -} - diff --git a/src/wayland/meta-weston-launch.h b/src/wayland/meta-weston-launch.h index 19d3756a2..ea4530871 100644 --- a/src/wayland/meta-weston-launch.h +++ b/src/wayland/meta-weston-launch.h @@ -37,10 +37,6 @@ GType meta_launcher_get_type (void) G_GNUC_CONST; MetaLauncher *meta_launcher_new (void); -gboolean meta_launcher_activate_vt (MetaLauncher *self, - int number, - GError **error); - gboolean meta_launcher_set_drm_fd (MetaLauncher *self, int drm_fd, GError **error); diff --git a/src/wayland/weston-launch.c b/src/wayland/weston-launch.c index 773eea4bd..cbd7c9e67 100644 --- a/src/wayland/weston-launch.c +++ b/src/wayland/weston-launch.c @@ -269,40 +269,6 @@ out: return 0; } -static int -handle_activate_vt(struct weston_launch *wl, struct msghdr *msg, ssize_t len) -{ - struct weston_launcher_reply reply; - struct weston_launcher_activate_vt *message; - - reply.header.opcode = WESTON_LAUNCHER_ACTIVATE_VT; - reply.ret = -1; - - if (len != sizeof(*message)) { - error(0, 0, "missing value in activate_vt request"); - goto out; - } - - message = msg->msg_iov->iov_base; - - reply.ret = ioctl(wl->tty, VT_ACTIVATE, message->vt); - if (reply.ret < 0) - reply.ret = -errno; - - if (wl->verbose) - fprintf(stderr, "mutter-launch: activate VT, ret: %d\n", reply.ret); - -out: - do { - len = send(wl->sock[0], &reply, sizeof reply, 0); - } while (len < 0 && errno == EINTR); - if (len < 0) - return -1; - - return 0; -} - - static int handle_open(struct weston_launch *wl, struct msghdr *msg, ssize_t len) { @@ -419,9 +385,6 @@ handle_socket_msg(struct weston_launch *wl) case WESTON_LAUNCHER_CONFIRM_VT_SWITCH: ret = handle_confirm_vt_switch(wl, &msg, len); break; - case WESTON_LAUNCHER_ACTIVATE_VT: - ret = handle_activate_vt(wl, &msg, len); - break; } return ret; diff --git a/src/wayland/weston-launch.h b/src/wayland/weston-launch.h index 74e6c3be6..63e28098c 100644 --- a/src/wayland/weston-launch.h +++ b/src/wayland/weston-launch.h @@ -32,8 +32,7 @@ enum weston_launcher_message_type { enum weston_launcher_opcode { WESTON_LAUNCHER_OPEN = (1 << 1 | WESTON_LAUNCHER_REQUEST), WESTON_LAUNCHER_DRM_SET_FD = (2 << 1 | WESTON_LAUNCHER_REQUEST), - WESTON_LAUNCHER_ACTIVATE_VT = (3 << 1 | WESTON_LAUNCHER_REQUEST), - WESTON_LAUNCHER_CONFIRM_VT_SWITCH = (4 << 1 | WESTON_LAUNCHER_REQUEST), + WESTON_LAUNCHER_CONFIRM_VT_SWITCH = (3 << 1 | WESTON_LAUNCHER_REQUEST), }; enum weston_launcher_server_opcode { From 1d3dbea20ce363d7b3e4bf4671c35268d948ff51 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 31 Dec 2013 18:03:31 -0500 Subject: [PATCH 371/889] meta-weston-launch: Don't use a GObject here We don't need a complicated API anymore. --- src/wayland/meta-wayland.c | 2 +- src/wayland/meta-weston-launch.c | 82 ++++++-------------------------- src/wayland/meta-weston-launch.h | 13 +---- 3 files changed, 18 insertions(+), 79 deletions(-) diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index 20d0dcd28..74e709ac7 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -751,7 +751,7 @@ meta_wayland_finalize (void) compositor = meta_wayland_compositor_get_default (); meta_xwayland_stop (compositor); - g_clear_object (&compositor->launcher); + meta_launcher_free (compositor->launcher); } gboolean diff --git a/src/wayland/meta-weston-launch.c b/src/wayland/meta-weston-launch.c index 184a48d94..c86185a88 100644 --- a/src/wayland/meta-weston-launch.c +++ b/src/wayland/meta-weston-launch.c @@ -43,18 +43,8 @@ #include "meta-weston-launch.h" -struct _MetaLauncherClass -{ - GObjectClass parent_class; - - void (*enter) (MetaLauncher *); - void (*leave) (MetaLauncher *); -}; - struct _MetaLauncher { - GObject parent; - GSocket *weston_launch; gboolean vt_switched; @@ -66,16 +56,6 @@ struct _MetaLauncher GSource *outer_source; }; -enum { - SIGNAL_ENTER, - SIGNAL_LEAVE, - SIGNAL_LAST -}; - -static int signals[SIGNAL_LAST]; - -G_DEFINE_TYPE (MetaLauncher, meta_launcher, G_TYPE_OBJECT); - static void handle_request_vt_switch (MetaLauncher *self); static gboolean @@ -239,22 +219,6 @@ meta_launcher_open_input_device (MetaLauncher *self, return ret; } -static void -meta_launcher_finalize (GObject *object) -{ - MetaLauncher *launcher = META_LAUNCHER (object); - - g_source_destroy (launcher->outer_source); - g_source_destroy (launcher->inner_source); - - g_main_loop_unref (launcher->nested_loop); - g_main_context_unref (launcher->nested_context); - - g_object_unref (launcher->weston_launch); - - G_OBJECT_CLASS (meta_launcher_parent_class)->finalize (object); -} - static void meta_launcher_enter (MetaLauncher *launcher) { @@ -302,7 +266,7 @@ handle_request_vt_switch (MetaLauncher *launcher) GError *error; gboolean ok; - g_signal_emit (launcher, signals[SIGNAL_LEAVE], 0); + meta_launcher_leave (launcher); message.opcode = WESTON_LAUNCHER_CONFIRM_VT_SWITCH; @@ -326,7 +290,7 @@ handle_request_vt_switch (MetaLauncher *launcher) g_assert (launcher->vt_switched); launcher->vt_switched = FALSE; - g_signal_emit (launcher, signals[SIGNAL_ENTER], 0); + meta_launcher_enter (launcher); } static gboolean @@ -378,9 +342,10 @@ env_get_fd (const char *env) return g_ascii_strtoll (value, NULL, 10); } -static void -meta_launcher_init (MetaLauncher *self) +MetaLauncher * +meta_launcher_new (void) { + MetaLauncher *self = g_slice_new0 (MetaLauncher); int launch_fd; launch_fd = env_get_fd ("WESTON_LAUNCHER_SOCK"); @@ -403,37 +368,20 @@ meta_launcher_init (MetaLauncher *self) g_source_set_callback (self->inner_source, (GSourceFunc)on_socket_readable, self, NULL); g_source_attach (self->inner_source, self->nested_context); g_source_unref (self->inner_source); + + return self; } -static void -meta_launcher_class_init (MetaLauncherClass *klass) +void +meta_launcher_free (MetaLauncher *launcher) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); + g_source_destroy (launcher->outer_source); + g_source_destroy (launcher->inner_source); - object_class->finalize = meta_launcher_finalize; + g_main_loop_unref (launcher->nested_loop); + g_main_context_unref (launcher->nested_context); - klass->enter = meta_launcher_enter; - klass->leave = meta_launcher_leave; + g_object_unref (launcher->weston_launch); - signals[SIGNAL_ENTER] = g_signal_new ("enter", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (MetaLauncherClass, enter), - NULL, NULL, /* accumulator */ - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[SIGNAL_LEAVE] = g_signal_new ("leave", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (MetaLauncherClass, leave), - NULL, NULL, /* accumulator */ - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); -} - -MetaLauncher * -meta_launcher_new (void) -{ - return g_object_new (META_TYPE_LAUNCHER, NULL); + g_slice_free (MetaLauncher, launcher); } diff --git a/src/wayland/meta-weston-launch.h b/src/wayland/meta-weston-launch.h index ea4530871..498edbb7f 100644 --- a/src/wayland/meta-weston-launch.h +++ b/src/wayland/meta-weston-launch.h @@ -23,19 +23,10 @@ #include #include "weston-launch.h" -#define META_TYPE_LAUNCHER (meta_launcher_get_type()) -#define META_LAUNCHER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_LAUNCHER, MetaLauncher)) -#define META_LAUNCHER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_LAUNCHER, MetaLauncherClass)) -#define META_IS_LAUNCHER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_LAUNCHER)) -#define META_IS_LAUNCHER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_LAUNCHER)) -#define META_LAUNCHER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_LAUNCHER, MetaLauncherClass)) - -typedef struct _MetaLauncher MetaLauncher; -typedef struct _MetaLauncherClass MetaLauncherClass; - -GType meta_launcher_get_type (void) G_GNUC_CONST; +typedef struct _MetaLauncher MetaLauncher; MetaLauncher *meta_launcher_new (void); +void meta_launcher_free (MetaLauncher *self); gboolean meta_launcher_set_drm_fd (MetaLauncher *self, int drm_fd, From 002c5b8f876fb16eaf2342503e8123e649651de3 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 31 Dec 2013 19:12:44 -0500 Subject: [PATCH 372/889] wayland: Don't keep track of the drm FD in the WaylandCompositor As logind can give us a new FD at any time when it resumes. Theoretically, this is still technically wrong, as the MetaCursorTracker holds onto it. We'll fix this after we port to logind. --- src/core/meta-cursor-tracker.c | 9 ++++-- src/wayland/meta-wayland-private.h | 2 +- src/wayland/meta-wayland.c | 50 ++++++++++++++++++------------ 3 files changed, 37 insertions(+), 24 deletions(-) diff --git a/src/core/meta-cursor-tracker.c b/src/core/meta-cursor-tracker.c index 67528c2e7..550abff83 100644 --- a/src/core/meta-cursor-tracker.c +++ b/src/core/meta-cursor-tracker.c @@ -616,9 +616,12 @@ make_wayland_cursor_tracker (MetaScreen *screen) compositor = meta_wayland_compositor_get_default (); compositor->seat->cursor_tracker = self; - self->drm_fd = compositor->drm_fd; - if (self->drm_fd >= 0) - self->gbm = gbm_create_device (compositor->drm_fd); + if (meta_wayland_compositor_is_native (compositor)) + { + CoglRenderer *cogl_renderer = cogl_display_get_renderer (cogl_context_get_display (ctx)); + self->drm_fd = cogl_kms_renderer_get_kms_fd (cogl_renderer); + self->gbm = gbm_create_device (self->drm_fd); + } monitors = meta_monitor_manager_get (); g_signal_connect_object (monitors, "monitors-changed", diff --git a/src/wayland/meta-wayland-private.h b/src/wayland/meta-wayland-private.h index 353303456..26cd88ee0 100644 --- a/src/wayland/meta-wayland-private.h +++ b/src/wayland/meta-wayland-private.h @@ -80,7 +80,7 @@ struct _MetaWaylandCompositor struct wl_resource *xserver_resource; MetaLauncher *launcher; - int drm_fd; + gboolean native; MetaWaylandSeat *seat; }; diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index 74e709ac7..84b51edfe 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -623,15 +623,31 @@ meta_wayland_log_func (const char *fmt, g_free (str); } +static gboolean +are_we_native (int *out_drm_fd) +{ + ClutterBackend *backend = clutter_get_default_backend (); + CoglContext *cogl_context = clutter_backend_get_cogl_context (backend); + CoglRenderer *cogl_renderer = cogl_display_get_renderer (cogl_context_get_display (cogl_context)); + + if (cogl_renderer_get_winsys_id (cogl_renderer) == COGL_WINSYS_ID_EGL_KMS) + { + *out_drm_fd = cogl_kms_renderer_get_kms_fd (cogl_renderer); + return TRUE; + } + else + { + return FALSE; + } +} + void meta_wayland_init (void) { MetaWaylandCompositor *compositor = &_meta_wayland_compositor; MetaMonitorManager *monitors; - ClutterBackend *backend; - CoglContext *cogl_context; - CoglRenderer *cogl_renderer; char *display_name; + int drm_fd; memset (compositor, 0, sizeof (MetaWaylandCompositor)); @@ -676,25 +692,20 @@ meta_wayland_init (void) if (clutter_init (NULL, NULL) != CLUTTER_INIT_SUCCESS) g_error ("Failed to initialize Clutter"); - backend = clutter_get_default_backend (); - cogl_context = clutter_backend_get_cogl_context (backend); - cogl_renderer = cogl_display_get_renderer (cogl_context_get_display (cogl_context)); - - if (cogl_renderer_get_winsys_id (cogl_renderer) == COGL_WINSYS_ID_EGL_KMS) - compositor->drm_fd = cogl_kms_renderer_get_kms_fd (cogl_renderer); - else - compositor->drm_fd = -1; - - if (compositor->drm_fd >= 0) + if (are_we_native (&drm_fd)) { - GError *error; - - error = NULL; - if (!meta_launcher_set_drm_fd (compositor->launcher, compositor->drm_fd, &error)) + GError *error = NULL; + if (!meta_launcher_set_drm_fd (compositor->launcher, drm_fd, &error)) { g_error ("Failed to set DRM fd to weston-launch and become DRM master: %s", error->message); g_error_free (error); } + + compositor->native = TRUE; + } + else + { + compositor->native = FALSE; } meta_monitor_manager_initialize (); @@ -711,8 +722,7 @@ meta_wayland_init (void) meta_wayland_data_device_manager_init (compositor->wayland_display); - compositor->seat = meta_wayland_seat_new (compositor->wayland_display, - compositor->drm_fd >= 0); + compositor->seat = meta_wayland_seat_new (compositor->wayland_display, compositor->native); meta_wayland_init_shell (compositor); @@ -757,5 +767,5 @@ meta_wayland_finalize (void) gboolean meta_wayland_compositor_is_native (MetaWaylandCompositor *compositor) { - return compositor->drm_fd >= 0; + return compositor->native; } From 384a34c27d3f65a7be209ebf65178752ba4ded85 Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Thu, 19 Dec 2013 10:51:49 -0600 Subject: [PATCH 373/889] Remove meta_window_new_with_attrs The compositor code used to handle X windows that didn't have a corresponding MetaWindow (see commit d538690b), which is why the attribute query is separated. As that doesn't happen any more, we can clean up. No functional changes. Suggested by Owen Taylor. https://bugzilla.gnome.org/show_bug.cgi?id=721345 --- src/core/display.c | 4 +- src/core/screen.c | 74 +++++------------------ src/core/window-private.h | 8 +-- src/core/window.c | 122 ++++++++++++++++---------------------- 4 files changed, 69 insertions(+), 139 deletions(-) diff --git a/src/core/display.c b/src/core/display.c index 455db3120..ce33923b2 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -2806,14 +2806,14 @@ handle_other_xevent (MetaDisplay *display, && meta_display_screen_for_root (display, event->xmap.event)) { window = meta_window_new (display, event->xmap.window, - FALSE); + FALSE, META_COMP_EFFECT_CREATE); } break; case MapRequest: if (window == NULL) { window = meta_window_new (display, event->xmaprequest.window, - FALSE); + FALSE, META_COMP_EFFECT_CREATE); } /* 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 90083ecbb..d006b4349 100644 --- a/src/core/screen.c +++ b/src/core/screen.c @@ -880,59 +880,12 @@ meta_screen_free (MetaScreen *screen, meta_display_ungrab (display); } -typedef struct -{ - Window xwindow; - XWindowAttributes attrs; -} WindowInfo; - -static GList * -list_windows (MetaScreen *screen) +void +meta_screen_manage_all_windows (MetaScreen *screen) { Window ignored1, ignored2; Window *children; guint n_children, i; - GList *result; - - XQueryTree (screen->display->xdisplay, - screen->xroot, - &ignored1, &ignored2, &children, &n_children); - - result = NULL; - for (i = 0; i < n_children; ++i) - { - WindowInfo *info = g_new0 (WindowInfo, 1); - - meta_error_trap_push_with_return (screen->display); - - XGetWindowAttributes (screen->display->xdisplay, - children[i], &info->attrs); - - if (meta_error_trap_pop_with_return (screen->display)) - { - meta_verbose ("Failed to get attributes for window 0x%lx\n", - children[i]); - g_free (info); - } - else - { - info->xwindow = children[i]; - } - - result = g_list_prepend (result, info); - } - - if (children) - XFree (children); - - return g_list_reverse (result); -} - -void -meta_screen_manage_all_windows (MetaScreen *screen) -{ - GList *windows; - GList *list; meta_display_grab (screen->display); @@ -940,21 +893,22 @@ meta_screen_manage_all_windows (MetaScreen *screen) screen->guard_window = meta_screen_create_guard_window (screen->display->xdisplay, screen); - windows = list_windows (screen); - meta_stack_freeze (screen->stack); - for (list = windows; list != NULL; list = list->next) + + XQueryTree (screen->display->xdisplay, + screen->xroot, + &ignored1, &ignored2, &children, &n_children); + + for (i = 0; i < n_children; ++i) { - WindowInfo *info = list->data; - - meta_window_new_with_attrs (screen->display, info->xwindow, TRUE, - META_COMP_EFFECT_NONE, - &info->attrs); + meta_window_new (screen->display, children[i], TRUE, + META_COMP_EFFECT_NONE); } - meta_stack_thaw (screen->stack); - g_list_foreach (windows, (GFunc)g_free, NULL); - g_list_free (windows); + if (children) + XFree (children); + + meta_stack_thaw (screen->stack); meta_display_ungrab (screen->display); } diff --git a/src/core/window-private.h b/src/core/window-private.h index 0e0631aff..ef4c83df8 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -510,12 +510,8 @@ struct _MetaWindowClass MetaWindow* meta_window_new (MetaDisplay *display, Window xwindow, - gboolean must_be_viewable); -MetaWindow* meta_window_new_with_attrs (MetaDisplay *display, - Window xwindow, - gboolean must_be_viewable, - MetaCompEffect effect, - XWindowAttributes *attrs); + gboolean must_be_viewable, + MetaCompEffect effect); MetaWindow *meta_window_new_for_wayland (MetaDisplay *display, MetaWaylandSurface *surface); void meta_window_unmanage (MetaWindow *window, diff --git a/src/core/window.c b/src/core/window.c index 6152d518a..45fdb8cde 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -685,53 +685,6 @@ maybe_leave_show_desktop_mode (MetaWindow *window) } } -MetaWindow* -meta_window_new (MetaDisplay *display, - Window xwindow, - gboolean must_be_viewable) -{ - XWindowAttributes attrs; - MetaWindow *window; - - meta_display_grab (display); - meta_error_trap_push (display); /* Push a trap over all of window - * creation, to reduce XSync() calls - */ - - meta_error_trap_push_with_return (display); - - if (XGetWindowAttributes (display->xdisplay,xwindow, &attrs)) - { - if(meta_error_trap_pop_with_return (display) != Success) - { - meta_verbose ("Failed to get attributes for window 0x%lx\n", - xwindow); - meta_error_trap_pop (display); - meta_display_ungrab (display); - return NULL; - } - window = meta_window_new_with_attrs (display, xwindow, - must_be_viewable, - META_COMP_EFFECT_CREATE, - &attrs); - } - else - { - meta_error_trap_pop_with_return (display); - meta_verbose ("Failed to get attributes for window 0x%lx\n", - xwindow); - meta_error_trap_pop (display); - meta_display_ungrab (display); - return NULL; - } - - - meta_error_trap_pop (display); - meta_display_ungrab (display); - - return window; -} - /* The MUTTER_WM_CLASS_FILTER environment variable is designed for * performance and regression testing environments where we want to do * tests with only a limited set of windows and ignore all other windows @@ -1460,12 +1413,12 @@ meta_window_new_for_wayland (MetaDisplay *display, } MetaWindow* -meta_window_new_with_attrs (MetaDisplay *display, - Window xwindow, - gboolean must_be_viewable, - MetaCompEffect effect, - XWindowAttributes *attrs) +meta_window_new (MetaDisplay *display, + Window xwindow, + gboolean must_be_viewable, + MetaCompEffect effect) { + XWindowAttributes attrs; MetaScreen *screen = NULL; GSList *tmp; gulong existing_wm_state; @@ -1481,11 +1434,40 @@ meta_window_new_with_attrs (MetaDisplay *display, return NULL; } + /* Grab server */ + meta_display_grab (display); + meta_error_trap_push (display); /* Push a trap over all of window + * creation, to reduce XSync() calls + */ + + meta_error_trap_push_with_return (display); + + if (XGetWindowAttributes (display->xdisplay, xwindow, &attrs)) + { + if(meta_error_trap_pop_with_return (display) != Success) + { + meta_verbose ("Failed to get attributes for window 0x%lx\n", + xwindow); + meta_error_trap_pop (display); + meta_display_ungrab (display); + return NULL; + } + } + else + { + meta_error_trap_pop_with_return (display); + meta_verbose ("Failed to get attributes for window 0x%lx\n", + xwindow); + meta_error_trap_pop (display); + meta_display_ungrab (display); + return NULL; + } + for (tmp = display->screens; tmp != NULL; tmp = tmp->next) { MetaScreen *scr = tmp->data; - if (scr->xroot == attrs->root) + if (scr->xroot == attrs.root) { screen = tmp->data; break; @@ -1495,14 +1477,14 @@ meta_window_new_with_attrs (MetaDisplay *display, g_assert (screen); /* A black list of override redirect windows that we don't need to manage: */ - if (attrs->override_redirect && + if (attrs.override_redirect && (xwindow == screen->no_focus_window || xwindow == screen->flash_window || xwindow == screen->wm_sn_selection_window || - attrs->class == InputOnly || + attrs.class == InputOnly || /* any windows created via meta_create_offscreen_window: */ - (attrs->x == -100 && attrs->y == -100 - && attrs->width == 1 && attrs->height == 1) || + (attrs.x == -100 && attrs.y == -100 + && attrs.width == 1 && attrs.height == 1) || xwindow == screen->wm_cm_selection_window || xwindow == screen->guard_window || (display->compositor && @@ -1512,23 +1494,21 @@ meta_window_new_with_attrs (MetaDisplay *display, ) ) { meta_verbose ("Not managing our own windows\n"); + meta_error_trap_pop (display); + meta_display_ungrab (display); return NULL; } - if (maybe_filter_xwindow (display, xwindow, must_be_viewable, attrs)) + if (maybe_filter_xwindow (display, xwindow, must_be_viewable, &attrs)) { meta_verbose ("Not managing filtered window\n"); + meta_error_trap_pop (display); + meta_display_ungrab (display); return NULL; } - /* Grab server */ - meta_display_grab (display); - meta_error_trap_push (display); /* Push a trap over all of window - * creation, to reduce XSync() calls - */ - existing_wm_state = WithdrawnState; - if (must_be_viewable && attrs->map_state != IsViewable) + if (must_be_viewable && attrs.map_state != IsViewable) { /* Only manage if WM_STATE is IconicState or NormalState */ gulong state; @@ -1567,14 +1547,14 @@ meta_window_new_with_attrs (MetaDisplay *display, meta_error_trap_pop_with_return (display); event_mask = PropertyChangeMask | ColormapChangeMask; - if (attrs->override_redirect) + if (attrs.override_redirect) event_mask |= StructureNotifyMask; /* If the window is from this client (a menu, say) we need to augment * the event mask, not replace it. For windows from other clients, - * attrs->your_event_mask will be empty at this point. + * attrs.your_event_mask will be empty at this point. */ - XSelectInput (display->xdisplay, xwindow, attrs->your_event_mask | event_mask); + XSelectInput (display->xdisplay, xwindow, attrs.your_event_mask | event_mask); { unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; @@ -1591,11 +1571,11 @@ meta_window_new_with_attrs (MetaDisplay *display, } /* Get rid of any borders */ - if (attrs->border_width != 0) + if (attrs.border_width != 0) XSetWindowBorderWidth (display->xdisplay, xwindow, 0); /* Get rid of weird gravities */ - if (attrs->win_gravity != NorthWestGravity) + if (attrs.win_gravity != NorthWestGravity) { XSetWindowAttributes set_attrs; @@ -1624,7 +1604,7 @@ meta_window_new_with_attrs (MetaDisplay *display, TRUE, existing_wm_state, effect, - attrs); + &attrs); meta_error_trap_pop (display); /* pop the XSync()-reducing trap */ meta_display_ungrab (display); From becbad56ef8e3621f451bf9def42c7de0c9d0bf0 Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Mon, 30 Dec 2013 16:52:14 -0600 Subject: [PATCH 374/889] Discourage server grabs Server grabs are not as evil as you might expect, but there is agreement in that their usage should be limited. Server grabs can cause things to go rather wrong when mutter emits a signal while it has grabbed the server. If the receiver of that signal waits for a synchronous action performed by another client, then you have a deadlock. This happens with Mali binary GLESv2 drivers :( https://bugzilla.gnome.org/show_bug.cgi?id=721345 --- src/core/display.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/core/display.c b/src/core/display.c index ce33923b2..eced28740 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -1155,7 +1155,18 @@ meta_display_screen_for_x_screen (MetaDisplay *display, return NULL; } -/* Grab/ungrab routines taken from fvwm */ +/* Grab/ungrab routines taken from fvwm. + * Calling this function will cause X to ignore all other clients until + * you ungrab. This may not be quite as bad as it sounds, yet there is + * agreement that avoiding server grabs except when they are clearly needed + * is a good thing. + * + * If you do use such grabs, please clearly explain the necessity for their + * usage in a comment. Try to keep their scope extremely limited. In + * particular, try to avoid emitting any signals or notifications while + * a grab is active (if the signal receiver tries to block on an X request + * from another client at this point, you will have a deadlock). + */ void meta_display_grab (MetaDisplay *display) { From 7bfc9109f732daa8ce602df99acb4ca39ad91ab1 Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Thu, 2 Jan 2014 09:49:10 -0600 Subject: [PATCH 375/889] frame: remove unnecessary server grab meta_window_ensure_frame() creates its own grab and has a comment claiming that it must be called under a grab too. But the reasoning given in the comment does not seem relevant here. We only frame non-override-redirect windows, so we are creating the frame in response to MapRequest. There is no way that the child could receive a MapNotify at this point, since that only happens much later, once we go through the CALC_SHOWING queue and call XMapWindow() from meta_window_show(). Remove the unnecessary grab. https://bugzilla.gnome.org/show_bug.cgi?id=721345 --- src/core/frame.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/core/frame.c b/src/core/frame.c index a2a4fbf63..fa4359697 100644 --- a/src/core/frame.c +++ b/src/core/frame.c @@ -52,9 +52,6 @@ meta_window_ensure_frame (MetaWindow *window) if (window->frame) return; - /* See comment below for why this is required. */ - meta_display_grab (window->display); - frame = g_new (MetaFrame, 1); frame->window = window; @@ -120,14 +117,6 @@ meta_window_ensure_frame (MetaWindow *window) meta_display_register_x_window (window->display, &frame->xwindow, window); - /* Reparent the client window; it may be destroyed, - * thus the error trap. We'll get a destroy notify later - * and free everything. Comment in FVWM source code says - * we need a server grab or the child can get its MapNotify - * before we've finished reparenting and getting the decoration - * window onscreen, so ensure_frame must be called with - * a grab. - */ meta_error_trap_push (window->display); if (window->mapped) { @@ -170,8 +159,6 @@ meta_window_ensure_frame (MetaWindow *window) /* Move keybindings to frame instead of window */ meta_window_grab_keys (window); - - meta_display_ungrab (window->display); } void From 39d26be94159f5c03ebdeeb27006f9b69f3867dd Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Mon, 30 Dec 2013 14:26:10 -0600 Subject: [PATCH 376/889] screen: use stack tracker for initial window query In meta_screen_manage_all_windows() we can use our own stack tracker to get the list of windows - no need to query X again. A copy is needed because the stack gets modified as part of the loop. Specifically, meta_stack_tracker_get_stack() at this time returns the predicted stack, and meta_window_new() performs a few operations (e.g. framing) which cause immediate changes to the predicted stack. https://bugzilla.gnome.org/show_bug.cgi?id=721345 --- src/core/screen.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/core/screen.c b/src/core/screen.c index d006b4349..2fc9bfef2 100644 --- a/src/core/screen.c +++ b/src/core/screen.c @@ -883,9 +883,9 @@ meta_screen_free (MetaScreen *screen, void meta_screen_manage_all_windows (MetaScreen *screen) { - Window ignored1, ignored2; - Window *children; - guint n_children, i; + MetaStackWindow *_children; + MetaStackWindow *children; + int n_children, i; meta_display_grab (screen->display); @@ -894,20 +894,18 @@ meta_screen_manage_all_windows (MetaScreen *screen) meta_screen_create_guard_window (screen->display->xdisplay, screen); meta_stack_freeze (screen->stack); + meta_stack_tracker_get_stack (screen->stack_tracker, &_children, &n_children); - XQueryTree (screen->display->xdisplay, - screen->xroot, - &ignored1, &ignored2, &children, &n_children); + /* Copy the stack as it will be modified as part of the loop */ + children = g_memdup (_children, sizeof (MetaStackWindow) * n_children); for (i = 0; i < n_children; ++i) { - meta_window_new (screen->display, children[i], TRUE, + meta_window_new (screen->display, children[i].x11.xwindow, TRUE, META_COMP_EFFECT_NONE); } - if (children) - XFree (children); - + g_free (children); meta_stack_thaw (screen->stack); meta_display_ungrab (screen->display); From af46ef3b962b43c23b3b546fcdaef3ca27d843a3 Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Mon, 6 Jan 2014 13:09:44 -0600 Subject: [PATCH 377/889] meta_window_new: clean up error handling The return code of XGetWindowAttributes() indicates whether an error was encountered or not. There is no need to specifically check the error trap. The trap around XAddToSaveSet() was superfluous. We have a global error trap to ignore any errors here, and there is no need to XSync() as GDK will later ignore the error asynchronously if one is raised. Also move common error exit path to an error label. https://bugzilla.gnome.org/show_bug.cgi?id=721345 --- src/core/window.c | 61 ++++++++++++++++------------------------------- 1 file changed, 20 insertions(+), 41 deletions(-) diff --git a/src/core/window.c b/src/core/window.c index 45fdb8cde..db34afe89 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -1440,28 +1440,12 @@ meta_window_new (MetaDisplay *display, * creation, to reduce XSync() calls */ - meta_error_trap_push_with_return (display); - - if (XGetWindowAttributes (display->xdisplay, xwindow, &attrs)) - { - if(meta_error_trap_pop_with_return (display) != Success) - { - meta_verbose ("Failed to get attributes for window 0x%lx\n", - xwindow); - meta_error_trap_pop (display); - meta_display_ungrab (display); - return NULL; - } - } - else - { - meta_error_trap_pop_with_return (display); - meta_verbose ("Failed to get attributes for window 0x%lx\n", - xwindow); - meta_error_trap_pop (display); - meta_display_ungrab (display); - return NULL; - } + if (!XGetWindowAttributes (display->xdisplay, xwindow, &attrs)) + { + meta_verbose ("Failed to get attributes for window 0x%lx\n", + xwindow); + goto error; + } for (tmp = display->screens; tmp != NULL; tmp = tmp->next) { @@ -1494,17 +1478,13 @@ meta_window_new (MetaDisplay *display, ) ) { meta_verbose ("Not managing our own windows\n"); - meta_error_trap_pop (display); - meta_display_ungrab (display); - return NULL; + goto error; } if (maybe_filter_xwindow (display, xwindow, must_be_viewable, &attrs)) { meta_verbose ("Not managing filtered window\n"); - meta_error_trap_pop (display); - meta_display_ungrab (display); - return NULL; + goto error; } existing_wm_state = WithdrawnState; @@ -1521,9 +1501,7 @@ meta_window_new (MetaDisplay *display, (state == IconicState || state == NormalState))) { meta_verbose ("Deciding not to manage unmapped or unviewable window 0x%lx\n", xwindow); - meta_error_trap_pop (display); - meta_display_ungrab (display); - return NULL; + goto error; } existing_wm_state = state; @@ -1536,15 +1514,13 @@ meta_window_new (MetaDisplay *display, /* * XAddToSaveSet can only be called on windows created by a different * client. with Mutter we want to be able to create manageable windows - * from within the process (such as a dummy desktop window), so we do not - * want this call failing to prevent the window from being managed -- wrap - * it in its own error trap (we use the _with_return() version here to - * ensure that XSync() is done on the pop, otherwise the error will not - * get caught). + * from within the process (such as a dummy desktop window). As we do not + * want this call failing to prevent the window from being managed, we + * call this before creating the return-checked error trap. */ - meta_error_trap_push_with_return (display); XAddToSaveSet (display->xdisplay, xwindow); - meta_error_trap_pop_with_return (display); + + meta_error_trap_push_with_return (display); event_mask = PropertyChangeMask | ColormapChangeMask; if (attrs.override_redirect) @@ -1591,9 +1567,7 @@ meta_window_new (MetaDisplay *display, { meta_verbose ("Window 0x%lx disappeared just as we tried to manage it\n", xwindow); - meta_error_trap_pop (display); - meta_display_ungrab (display); - return NULL; + goto error; } window = meta_window_new_shared (display, @@ -1617,6 +1591,11 @@ meta_window_new (MetaDisplay *display, display_notify_window (display, window); return window; + +error: + meta_error_trap_pop (display); + meta_display_ungrab (display); + return NULL; } /* This function should only be called from the end of meta_window_new_with_attrs () */ From 577624adefc73d8f724a9e7319ac8087d9bae825 Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Mon, 30 Dec 2013 13:01:28 -0600 Subject: [PATCH 378/889] Reduce server grabs during window creation Remove some obvious server grabs from the window creation codepath, also ones that are taken at startup. During startup, there is no need to grab: we install the event handlers before querying for the already-existing windows, so there is no danger that we will 'lose' some window. We might try to create a window twice (if it comes back in the original query and then we get an event for it) but the code is already protected against such conditions. When windows are created later, we also do not need grabs, we just need appropriate error checking as the window may be destroyed at any time (or it may have already been destroyed). The stack tracker is unaffected here - as it listens to CreateNotify and DestroyNotify events and responds directly, the internal stack representation will always be consistent even if the window goes away while we are processing MapRequest or similar. Now that there are no grabs we don't have to worry about explicitly calling display_notify_window after grabs have been dropped. Fold that into meta_window_new_shared(). https://bugzilla.gnome.org/show_bug.cgi?id=721345 --- src/core/display.c | 4 ---- src/core/screen.c | 4 ---- src/core/window.c | 39 ++++++++++++--------------------------- 3 files changed, 12 insertions(+), 35 deletions(-) diff --git a/src/core/display.c b/src/core/display.c index eced28740..2313c8823 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -825,8 +825,6 @@ meta_display_open (void) enable_compositor (the_display); - meta_display_grab (the_display); - /* Now manage all existing windows */ tmp = the_display->screens; while (tmp != NULL) @@ -894,8 +892,6 @@ meta_display_open (void) meta_idle_monitor_init_dbus (); - meta_display_ungrab (the_display); - /* Done opening new display */ the_display->display_opening = FALSE; diff --git a/src/core/screen.c b/src/core/screen.c index 2fc9bfef2..939412544 100644 --- a/src/core/screen.c +++ b/src/core/screen.c @@ -887,8 +887,6 @@ meta_screen_manage_all_windows (MetaScreen *screen) MetaStackWindow *children; int n_children, i; - meta_display_grab (screen->display); - if (screen->guard_window == None) screen->guard_window = meta_screen_create_guard_window (screen->display->xdisplay, screen); @@ -907,8 +905,6 @@ meta_screen_manage_all_windows (MetaScreen *screen) g_free (children); meta_stack_thaw (screen->stack); - - meta_display_ungrab (screen->display); } /** diff --git a/src/core/window.c b/src/core/window.c index db34afe89..5739367de 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -1329,12 +1329,6 @@ meta_window_new_shared (MetaDisplay *display, window->constructing = FALSE; - return window; -} - -static void -display_notify_window (MetaDisplay *display, MetaWindow *window) -{ meta_display_notify_window_created (display, window); if (window->wm_state_demands_attention) @@ -1342,6 +1336,8 @@ display_notify_window (MetaDisplay *display, MetaWindow *window) if (window->wm_hints_urgent) g_signal_emit_by_name (window->display, "window-marked-urgent", window); + + return window; } MetaWindow * @@ -1376,15 +1372,12 @@ meta_window_new_for_wayland (MetaDisplay *display, attrs.override_redirect = 0; attrs.screen = scr->xscreen; - /* XXX: Note: In the Wayland case we currently still grab the - * xserver and trap X errors while creating a MetaWindow because we - * will still be making various redundant X requests (passing a - * window xid of None) until we thoroughly audit all the code to - * make sure it knows about non X based clients... + /* XXX: Note: In the Wayland case we currently still trap X errors while + * creating a MetaWindow because we will still be making various redundant + * X requests (passing a window xid of None) until we thoroughly audit all + * the code to make sure it knows about non X based clients... */ - /* Grab server */ - meta_display_grab (display); meta_error_trap_push (display); /* Push a trap over all of window * creation, to reduce XSync() calls */ @@ -1400,14 +1393,12 @@ meta_window_new_for_wayland (MetaDisplay *display, &attrs); meta_error_trap_pop (display); /* pop the XSync()-reducing trap */ - meta_display_ungrab (display); /* XXX: Maybe this could be called in meta_window_new_shared() but * before splitting the X11 specific code out it came after the - * meta_display_ungrab() and we wanted to minimize the risk of + * meta_error_trap_pop() and we wanted to minimize the risk of * breaking something. */ - display_notify_window (window->display, window); return window; } @@ -1434,11 +1425,14 @@ meta_window_new (MetaDisplay *display, return NULL; } - /* Grab server */ - meta_display_grab (display); meta_error_trap_push (display); /* Push a trap over all of window * creation, to reduce XSync() calls */ + /* + * This function executes without any server grabs held. This means that + * the window could have already gone away, or could go away at any point, + * so we must be careful with X error handling. + */ if (!XGetWindowAttributes (display->xdisplay, xwindow, &attrs)) { @@ -1581,20 +1575,11 @@ meta_window_new (MetaDisplay *display, &attrs); meta_error_trap_pop (display); /* pop the XSync()-reducing trap */ - meta_display_ungrab (display); - - /* XXX: Maybe this could be called in meta_window_new_shared() but - * before splitting the X11 specific code out it came after the - * meta_display_ungrab() and we wanted to minimize the risk of - * breaking something. - */ - display_notify_window (display, window); return window; error: meta_error_trap_pop (display); - meta_display_ungrab (display); return NULL; } From a5f0db5ecb98f967e31ff337e4c81b2dc597e2cc Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Tue, 7 Jan 2014 10:12:31 -0600 Subject: [PATCH 379/889] window: don't grab server during calc_showing This grab was added in commit caf43a123f40d3a68599ac5453a79759b828e8f0 https://bugzilla.gnome.org/show_bug.cgi?id=381127 to minimize window flickering when switching workspaces. While this grab is held, some signals are emitted to the shell, which can lead to deadlocks (reproduced under Mali binary OpenGLESv2 drivers). Now that we are a compositing window manager, we do not have to worry about flickers, this grab should no longer be necessary. https://bugzilla.gnome.org/show_bug.cgi?id=721709 --- src/core/window.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/core/window.c b/src/core/window.c index 5739367de..1ff6e0e3d 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -2398,7 +2398,6 @@ idle_calc_showing (gpointer data) GSList *should_hide; GSList *unplaced; GSList *displays; - MetaWindow *first_window; guint queue_index = GPOINTER_TO_INT (data); g_return_val_if_fail (queue_pending[queue_index] != NULL, FALSE); @@ -2451,10 +2450,6 @@ idle_calc_showing (gpointer data) should_show = g_slist_sort (should_show, stackcmp); should_show = g_slist_reverse (should_show); - first_window = copy->data; - - meta_display_grab (first_window->display); - tmp = unplaced; while (tmp != NULL) { @@ -2527,8 +2522,6 @@ idle_calc_showing (gpointer data) } } - meta_display_ungrab (first_window->display); - g_slist_free (copy); g_slist_free (unplaced); From 7a4adce44f2fe8cf51a61eb984c62ca0a9fb3793 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 13 Jan 2014 09:27:46 -0500 Subject: [PATCH 380/889] window: Atomically unmaximize both directions from a _NET_WM_STATE ClientMessage When GDK sends an unmaximize _NET_WM_STATE ClientMessage, it tells us to remove the _NET_WM_STATE_MAXIMIZED_HORZ and _NET_WM_STATE_MAXIMIZED_VERT states. Before this time, it would independently call: meta_window_unmaximize (window, META_MAXIMIZE_HORIZONTAL); meta_window_unmaximize (window, META_MAXIMIZE_VERTICAL); Which, besides being foolishly inefficient, would also mess up our saved_rect tracking, causing the window to only look like it was unmaximized vertically. Make this code more intelligent, so it causes us to unmaximize in one call. https://bugzilla.gnome.org/show_bug.cgi?id=722108 --- src/core/window.c | 40 +++++++++++++++------------------------- 1 file changed, 15 insertions(+), 25 deletions(-) diff --git a/src/core/window.c b/src/core/window.c index 1ff6e0e3d..4b05d4e3f 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -7143,46 +7143,36 @@ meta_window_client_message (MetaWindow *window, } if (first == display->atom__NET_WM_STATE_MAXIMIZED_HORZ || - second == display->atom__NET_WM_STATE_MAXIMIZED_HORZ) + second == display->atom__NET_WM_STATE_MAXIMIZED_HORZ || + first == display->atom__NET_WM_STATE_MAXIMIZED_VERT || + second == display->atom__NET_WM_STATE_MAXIMIZED_VERT) { gboolean max; + MetaMaximizeFlags directions = 0; max = (action == _NET_WM_STATE_ADD || (action == _NET_WM_STATE_TOGGLE && !window->maximized_horizontally)); + + if (first == display->atom__NET_WM_STATE_MAXIMIZED_HORZ || + second == display->atom__NET_WM_STATE_MAXIMIZED_HORZ) + directions |= META_MAXIMIZE_HORIZONTAL; + + if (first == display->atom__NET_WM_STATE_MAXIMIZED_VERT || + second == display->atom__NET_WM_STATE_MAXIMIZED_VERT) + directions |= META_MAXIMIZE_VERTICAL; + if (max && window->has_maximize_func) { if (meta_prefs_get_raise_on_click ()) meta_window_raise (window); - meta_window_maximize (window, META_MAXIMIZE_HORIZONTAL); + meta_window_maximize (window, directions); } else { if (meta_prefs_get_raise_on_click ()) meta_window_raise (window); - meta_window_unmaximize (window, META_MAXIMIZE_HORIZONTAL); - } - } - - if (first == display->atom__NET_WM_STATE_MAXIMIZED_VERT || - second == display->atom__NET_WM_STATE_MAXIMIZED_VERT) - { - gboolean max; - - max = (action == _NET_WM_STATE_ADD || - (action == _NET_WM_STATE_TOGGLE && - !window->maximized_vertically)); - if (max && window->has_maximize_func) - { - if (meta_prefs_get_raise_on_click ()) - meta_window_raise (window); - meta_window_maximize (window, META_MAXIMIZE_VERTICAL); - } - else - { - if (meta_prefs_get_raise_on_click ()) - meta_window_raise (window); - meta_window_unmaximize (window, META_MAXIMIZE_VERTICAL); + meta_window_unmaximize (window, directions); } } From 7b597b8c622e93f7c45b97c69373f90bdf896525 Mon Sep 17 00:00:00 2001 From: Cosimo Cecchi Date: Mon, 6 Jan 2014 18:26:03 -0800 Subject: [PATCH 381/889] monitor: improve heuristic to determine display output name Under some circumstances, for example when the display controller driver doesn't report back the correct EDID, or under VirtualBox, Mutter returns suboptimal strings for an output display name, leading to funny labels like 'Unknown 0"', or '(null) 0"' in the Settings panel. This commit improves our heuristic in three ways: - we now avoid putting inches in the display name if either dimension is zero - we use the vendor name in case we're not able to lookup its PnP id from the database. Previously we would have passed over '(null)' - as a special edge-case, when neither inches nor vendor are known, we use the string 'Unknown Display' Finally, we make the combined vendor + inches string translatable, as different languages might want to move the size part of the string to a position different than the end. https://bugzilla.gnome.org/show_bug.cgi?id=721674 --- src/core/monitor.c | 69 ++++++++++++++++++++++++++++------------------ 1 file changed, 42 insertions(+), 27 deletions(-) diff --git a/src/core/monitor.c b/src/core/monitor.c index 999b23ec0..75462e786 100644 --- a/src/core/monitor.c +++ b/src/core/monitor.c @@ -614,46 +614,61 @@ static char * make_display_name (MetaMonitorManager *manager, MetaOutput *output) { + char *inches = NULL; + char *vendor_name = NULL; + char *ret; + gboolean is_unknown = FALSE; + if (g_str_has_prefix (output->name, "LVDS") || g_str_has_prefix (output->name, "eDP")) - return g_strdup (_("Built-in display")); + { + ret = g_strdup (_("Built-in display")); + goto out; + } - if (output->width_mm != -1 && output->height_mm != -1) + if (output->width_mm > 0 && output->height_mm > 0) { double d = sqrt (output->width_mm * output->width_mm + output->height_mm * output->height_mm); - char *inches = diagonal_to_str (d / 25.4); - char *vendor_name; - char *ret; + inches = diagonal_to_str (d / 25.4); + } - if (g_strcmp0 (output->vendor, "unknown") != 0) - { - if (!manager->pnp_ids) - manager->pnp_ids = gnome_pnp_ids_new (); + if (g_strcmp0 (output->vendor, "unknown") != 0) + { + if (!manager->pnp_ids) + manager->pnp_ids = gnome_pnp_ids_new (); - vendor_name = gnome_pnp_ids_get_pnp_id (manager->pnp_ids, - output->vendor); + vendor_name = gnome_pnp_ids_get_pnp_id (manager->pnp_ids, + output->vendor); - ret = g_strdup_printf ("%s %s", vendor_name, inches); - - g_free (vendor_name); - } - else - { - /* TRANSLATORS: this is a monitor name (in case we don't know - the vendor), it's Unknown followed by a size in inches, - like 'Unknown 15"' - */ - ret = g_strdup_printf (_("Unknown %s"), inches); - } - - g_free (inches); - return ret; + if (!vendor_name) + vendor_name = g_strdup (output->vendor); } else { - return g_strdup (output->vendor); + if (inches != NULL) + vendor_name = g_strdup (_("Unknown")); + else + vendor_name = g_strdup (_("Unknown Display")); } + + if (inches != NULL) + { + /* TRANSLATORS: this is a monitor vendor name, followed by a + * size in inches, like 'Dell 15"' + */ + ret = g_strdup_printf (_("%s %s"), vendor_name, inches); + } + else + { + ret = g_strdup (vendor_name); + } + + out: + g_free (inches); + g_free (vendor_name); + + return ret; } static gboolean From 7b15d21e40fba2a4160d722c963ad3ebddbcbddf Mon Sep 17 00:00:00 2001 From: Debarshi Ray Date: Thu, 9 Jan 2014 11:53:29 +0100 Subject: [PATCH 382/889] monitor: Suppress -Werror=unused-variable Fallout from 477acddf642d735ef036a95fda6f4d7f6b522fd1 https://bugzilla.gnome.org/show_bug.cgi?id=721674 --- src/core/monitor.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/monitor.c b/src/core/monitor.c index 75462e786..db47899c9 100644 --- a/src/core/monitor.c +++ b/src/core/monitor.c @@ -617,7 +617,6 @@ make_display_name (MetaMonitorManager *manager, char *inches = NULL; char *vendor_name = NULL; char *ret; - gboolean is_unknown = FALSE; if (g_str_has_prefix (output->name, "LVDS") || g_str_has_prefix (output->name, "eDP")) From 9b21346427cfb9432b2727350f3af6129c1eb47a Mon Sep 17 00:00:00 2001 From: Andika Triwidada Date: Sun, 12 Jan 2014 08:42:06 +0700 Subject: [PATCH 383/889] Changed obsolete FSF postal address into generic URL. Fix https://bugzilla.gnome.org/show_bug.cgi?id=721517 #2 --- src/compositor/clutter-utils.c | 4 +--- src/compositor/clutter-utils.h | 4 +--- src/compositor/cogl-utils.c | 4 +--- src/compositor/cogl-utils.h | 4 +--- src/compositor/meta-background-actor.c | 4 +--- src/compositor/meta-background.c | 4 +--- src/compositor/meta-cullable.c | 4 +--- src/compositor/meta-cullable.h | 4 +--- src/compositor/meta-module.c | 4 +--- src/compositor/meta-module.h | 4 +--- src/compositor/meta-plugin-manager.c | 4 +--- src/compositor/meta-plugin-manager.h | 4 +--- src/compositor/meta-plugin.c | 4 +--- src/compositor/meta-shadow-factory-private.h | 4 +--- src/compositor/meta-shadow-factory.c | 4 +--- src/compositor/meta-shaped-texture.c | 4 +--- src/compositor/meta-texture-rectangle.c | 4 +--- src/compositor/meta-texture-rectangle.h | 4 +--- src/compositor/meta-texture-tower.c | 4 +--- src/compositor/meta-texture-tower.h | 4 +--- src/compositor/meta-window-shape.c | 4 +--- src/compositor/meta-window-shape.h | 4 +--- src/compositor/plugins/default.c | 4 +--- src/compositor/region-utils.c | 4 +--- src/compositor/region-utils.h | 4 +--- src/core/above-tab-keycode.c | 4 +--- src/core/bell.c | 4 +--- src/core/bell.h | 4 +--- src/core/boxes-private.h | 4 +--- src/core/boxes.c | 4 +--- src/core/constraints.c | 4 +--- src/core/constraints.h | 4 +--- src/core/core.c | 4 +--- src/core/core.h | 4 +--- src/core/delete.c | 4 +--- src/core/display-private.h | 4 +--- src/core/display.c | 4 +--- src/core/edge-resistance.c | 4 +--- src/core/edge-resistance.h | 4 +--- src/core/errors.c | 4 +--- src/core/frame.c | 4 +--- src/core/frame.h | 4 +--- src/core/group-private.h | 4 +--- src/core/group-props.c | 4 +--- src/core/group-props.h | 4 +--- src/core/group.c | 4 +--- src/core/iconcache.c | 4 +--- src/core/iconcache.h | 4 +--- src/core/keybindings-private.h | 4 +--- src/core/keybindings.c | 4 +--- src/core/main.c | 4 +--- src/core/meta-cursor-tracker-private.h | 4 +--- src/core/meta-cursor-tracker.c | 4 +--- src/core/meta-idle-monitor-private.h | 4 +--- src/core/meta-idle-monitor.c | 4 +--- src/core/meta-xrandr-shared.h | 4 +--- src/core/monitor-config.c | 4 +--- src/core/monitor-private.h | 4 +--- src/core/monitor-xrandr.c | 4 +--- src/core/monitor.c | 4 +--- src/core/mutter.c | 4 +--- src/core/place.c | 4 +--- src/core/place.h | 4 +--- src/core/prefs.c | 4 +--- src/core/screen-private.h | 4 +--- src/core/screen.c | 4 +--- src/core/session.c | 4 +--- src/core/session.h | 4 +--- src/core/stack-tracker.c | 4 +--- src/core/stack-tracker.h | 4 +--- src/core/stack.c | 4 +--- src/core/stack.h | 4 +--- src/core/testboxes.c | 4 +--- src/core/util.c | 4 +--- src/core/window-private.h | 4 +--- src/core/window-props.c | 4 +--- src/core/window-props.h | 4 +--- src/core/window.c | 4 +--- src/core/workspace-private.h | 4 +--- src/core/workspace.c | 4 +--- src/core/xprops.c | 4 +--- src/core/xprops.h | 4 +--- src/meta/atomnames.h | 4 +--- src/meta/boxes.h | 4 +--- src/meta/common.h | 4 +--- src/meta/compositor-mutter.h | 4 +--- src/meta/compositor.h | 4 +--- src/meta/display.h | 4 +--- src/meta/errors.h | 4 +--- src/meta/gradient.h | 4 +--- src/meta/group.h | 4 +--- src/meta/keybindings.h | 4 +--- src/meta/main.h | 4 +--- src/meta/meta-background-actor.h | 4 +--- src/meta/meta-background.h | 4 +--- src/meta/meta-cursor-tracker.h | 4 +--- src/meta/meta-idle-monitor.h | 4 +--- src/meta/meta-plugin.h | 4 +--- src/meta/meta-shadow-factory.h | 4 +--- src/meta/meta-shaped-texture.h | 4 +--- src/meta/meta-window-actor.h | 4 +--- src/meta/prefs.h | 4 +--- src/meta/screen.h | 4 +--- src/meta/theme.h | 4 +--- src/meta/types.h | 4 +--- src/meta/util.h | 4 +--- src/meta/window.h | 4 +--- src/meta/workspace.h | 4 +--- src/ui/draw-workspace.c | 4 +--- src/ui/draw-workspace.h | 4 +--- src/ui/frames.c | 4 +--- src/ui/frames.h | 4 +--- src/ui/gradient.c | 4 +--- src/ui/menu.c | 4 +--- src/ui/menu.h | 4 +--- src/ui/metaaccellabel.c | 4 +--- src/ui/metaaccellabel.h | 4 +--- src/ui/resizepopup.c | 4 +--- src/ui/resizepopup.h | 4 +--- src/ui/tabpopup.c | 4 +--- src/ui/tabpopup.h | 4 +--- src/ui/testgradient.c | 4 +--- src/ui/theme-parser.c | 4 +--- src/ui/theme-private.h | 4 +--- src/ui/theme.c | 4 +--- src/ui/tile-preview.c | 4 +--- src/ui/tile-preview.h | 4 +--- src/ui/ui.c | 4 +--- src/ui/ui.h | 4 +--- test/mutter-test | 4 +--- test/tokentest/get-tokens.py | 4 +--- test/tokentest/tokentest.c | 4 +--- test/tokentest/tokentest.ini | 4 +--- tools/commit-wrangler.py | 4 +--- tools/patch-wrangler.py | 4 +--- tools/ppa-magic.py | 7 ++----- tools/release-wrangler.py | 4 +--- 137 files changed, 138 insertions(+), 413 deletions(-) diff --git a/src/compositor/clutter-utils.c b/src/compositor/clutter-utils.c index 7bca7c54e..6b2fb7328 100644 --- a/src/compositor/clutter-utils.c +++ b/src/compositor/clutter-utils.c @@ -16,9 +16,7 @@ * 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. + * along with this program; if not, see . */ #include "clutter-utils.h" diff --git a/src/compositor/clutter-utils.h b/src/compositor/clutter-utils.h index 862b6efe6..a6d76ce21 100644 --- a/src/compositor/clutter-utils.h +++ b/src/compositor/clutter-utils.h @@ -15,9 +15,7 @@ * 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. + * along with this program; if not, see . */ #ifndef __META_CLUTTER_UTILS_H__ diff --git a/src/compositor/cogl-utils.c b/src/compositor/cogl-utils.c index f158fdea4..fe4893cd3 100644 --- a/src/compositor/cogl-utils.c +++ b/src/compositor/cogl-utils.c @@ -16,9 +16,7 @@ * 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. + * along with this program; if not, see . */ #include diff --git a/src/compositor/cogl-utils.h b/src/compositor/cogl-utils.h index fb9b4c2d8..8184818c7 100644 --- a/src/compositor/cogl-utils.h +++ b/src/compositor/cogl-utils.h @@ -15,9 +15,7 @@ * 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. + * along with this program; if not, see . */ #ifndef __META_COGL_UTILS_H__ diff --git a/src/compositor/meta-background-actor.c b/src/compositor/meta-background-actor.c index b5270c5eb..ff0dc2117 100644 --- a/src/compositor/meta-background-actor.c +++ b/src/compositor/meta-background-actor.c @@ -14,9 +14,7 @@ * 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. + * along with this program; if not, see . * * Portions adapted from gnome-shell/src/shell-global.c */ diff --git a/src/compositor/meta-background.c b/src/compositor/meta-background.c index 244602c5e..4337f7053 100644 --- a/src/compositor/meta-background.c +++ b/src/compositor/meta-background.c @@ -14,9 +14,7 @@ * 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. + * along with this program; if not, see . */ /** diff --git a/src/compositor/meta-cullable.c b/src/compositor/meta-cullable.c index 691014052..5eb19026a 100644 --- a/src/compositor/meta-cullable.c +++ b/src/compositor/meta-cullable.c @@ -13,9 +13,7 @@ * 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. + * along with this program; if not, see . * * Written by: * Owen Taylor diff --git a/src/compositor/meta-cullable.h b/src/compositor/meta-cullable.h index 5a8c215f1..c1b886d2c 100644 --- a/src/compositor/meta-cullable.h +++ b/src/compositor/meta-cullable.h @@ -14,9 +14,7 @@ * 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. + * along with this program; if not, see . * * Written by: * Owen Taylor diff --git a/src/compositor/meta-module.c b/src/compositor/meta-module.c index 7badc8cd9..1369b8086 100644 --- a/src/compositor/meta-module.c +++ b/src/compositor/meta-module.c @@ -16,9 +16,7 @@ * 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. + * along with this program; if not, see . */ #include diff --git a/src/compositor/meta-module.h b/src/compositor/meta-module.h index 7e94ae680..dd6d5a685 100644 --- a/src/compositor/meta-module.h +++ b/src/compositor/meta-module.h @@ -16,9 +16,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_MODULE_H_ diff --git a/src/compositor/meta-plugin-manager.c b/src/compositor/meta-plugin-manager.c index dee1b0801..1d6d373ce 100644 --- a/src/compositor/meta-plugin-manager.c +++ b/src/compositor/meta-plugin-manager.c @@ -16,9 +16,7 @@ * 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. + * along with this program; if not, see . */ #include "config.h" diff --git a/src/compositor/meta-plugin-manager.h b/src/compositor/meta-plugin-manager.h index f39f5cada..b24059ffc 100644 --- a/src/compositor/meta-plugin-manager.h +++ b/src/compositor/meta-plugin-manager.h @@ -16,9 +16,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_PLUGIN_MANAGER_H_ diff --git a/src/compositor/meta-plugin.c b/src/compositor/meta-plugin.c index 95aec5c58..8cdc0ed63 100644 --- a/src/compositor/meta-plugin.c +++ b/src/compositor/meta-plugin.c @@ -16,9 +16,7 @@ * 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. + * along with this program; if not, see . */ /** diff --git a/src/compositor/meta-shadow-factory-private.h b/src/compositor/meta-shadow-factory-private.h index c4a1bbd96..8a24b5fd1 100644 --- a/src/compositor/meta-shadow-factory-private.h +++ b/src/compositor/meta-shadow-factory-private.h @@ -17,9 +17,7 @@ * 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. + * along with this program; if not, see . */ #ifndef __META_SHADOW_FACTORY_PRIVATE_H__ diff --git a/src/compositor/meta-shadow-factory.c b/src/compositor/meta-shadow-factory.c index 3af62fc96..c9f8786c3 100644 --- a/src/compositor/meta-shadow-factory.c +++ b/src/compositor/meta-shadow-factory.c @@ -13,9 +13,7 @@ * 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. + * along with this program; if not, see . */ /** diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c index 8d45d9bf0..b37770e4e 100644 --- a/src/compositor/meta-shaped-texture.c +++ b/src/compositor/meta-shaped-texture.c @@ -16,9 +16,7 @@ * 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. + * along with this program; if not, see . */ /** diff --git a/src/compositor/meta-texture-rectangle.c b/src/compositor/meta-texture-rectangle.c index 168e09b4c..3fc9430b5 100644 --- a/src/compositor/meta-texture-rectangle.c +++ b/src/compositor/meta-texture-rectangle.c @@ -18,9 +18,7 @@ * 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. + * along with this program; if not, see . */ #include diff --git a/src/compositor/meta-texture-rectangle.h b/src/compositor/meta-texture-rectangle.h index 7372b29e3..30f60d3df 100644 --- a/src/compositor/meta-texture-rectangle.h +++ b/src/compositor/meta-texture-rectangle.h @@ -18,9 +18,7 @@ * 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. + * along with this program; if not, see . */ #ifndef __META_TEXTURE_RECTANGLE_H__ diff --git a/src/compositor/meta-texture-tower.c b/src/compositor/meta-texture-tower.c index 9afed601d..207abb279 100644 --- a/src/compositor/meta-texture-tower.c +++ b/src/compositor/meta-texture-tower.c @@ -17,9 +17,7 @@ * 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. + * along with this program; if not, see . */ #include diff --git a/src/compositor/meta-texture-tower.h b/src/compositor/meta-texture-tower.h index e135d8056..b1228c604 100644 --- a/src/compositor/meta-texture-tower.h +++ b/src/compositor/meta-texture-tower.h @@ -17,9 +17,7 @@ * 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. + * along with this program; if not, see . */ #ifndef __META_TEXTURE_TOWER_H__ diff --git a/src/compositor/meta-window-shape.c b/src/compositor/meta-window-shape.c index 258079339..a41ed6ad1 100644 --- a/src/compositor/meta-window-shape.c +++ b/src/compositor/meta-window-shape.c @@ -17,9 +17,7 @@ * 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. + * along with this program; if not, see . */ #include diff --git a/src/compositor/meta-window-shape.h b/src/compositor/meta-window-shape.h index 1dd6c70fe..da23e5e9d 100644 --- a/src/compositor/meta-window-shape.h +++ b/src/compositor/meta-window-shape.h @@ -17,9 +17,7 @@ * 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. + * along with this program; if not, see . */ #ifndef __META_WINDOW_SHAPE_H__ diff --git a/src/compositor/plugins/default.c b/src/compositor/plugins/default.c index b6cccf1ae..91b30c039 100644 --- a/src/compositor/plugins/default.c +++ b/src/compositor/plugins/default.c @@ -16,9 +16,7 @@ * 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. + * along with this program; if not, see . */ #include diff --git a/src/compositor/region-utils.c b/src/compositor/region-utils.c index 34e1d4d58..486245532 100644 --- a/src/compositor/region-utils.c +++ b/src/compositor/region-utils.c @@ -15,9 +15,7 @@ * 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. + * along with this program; if not, see . */ #include "region-utils.h" diff --git a/src/compositor/region-utils.h b/src/compositor/region-utils.h index c494e97c5..16304dc70 100644 --- a/src/compositor/region-utils.h +++ b/src/compositor/region-utils.h @@ -15,9 +15,7 @@ * 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. + * along with this program; if not, see . */ #ifndef __META_REGION_UTILS_H__ diff --git a/src/core/above-tab-keycode.c b/src/core/above-tab-keycode.c index 856afe5d9..e980f5228 100644 --- a/src/core/above-tab-keycode.c +++ b/src/core/above-tab-keycode.c @@ -15,9 +15,7 @@ * 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. + * along with this program; if not, see . */ /* The standard cycle-windows keybinding should be the key above the diff --git a/src/core/bell.c b/src/core/bell.c index 5b40c2ed9..cc25a27ec 100644 --- a/src/core/bell.c +++ b/src/core/bell.c @@ -17,9 +17,7 @@ * 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. + * along with this program; if not, see . */ /* diff --git a/src/core/bell.h b/src/core/bell.h index 0065be9d4..ef2328f85 100644 --- a/src/core/bell.h +++ b/src/core/bell.h @@ -14,9 +14,7 @@ * 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. + * along with this program; if not, see . */ #include diff --git a/src/core/boxes-private.h b/src/core/boxes-private.h index 8e402b0dd..6b2abde6d 100644 --- a/src/core/boxes-private.h +++ b/src/core/boxes-private.h @@ -16,9 +16,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_BOXES_PRIVATE_H diff --git a/src/core/boxes.c b/src/core/boxes.c index 3c4f4446d..7f916cb5a 100644 --- a/src/core/boxes.c +++ b/src/core/boxes.c @@ -25,9 +25,7 @@ * 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. + * along with this program; if not, see . */ #include "boxes-private.h" diff --git a/src/core/constraints.c b/src/core/constraints.c index 302267fac..3634bffa9 100644 --- a/src/core/constraints.c +++ b/src/core/constraints.c @@ -18,9 +18,7 @@ * 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. + * along with this program; if not, see . */ #include diff --git a/src/core/constraints.h b/src/core/constraints.h index 07c65290c..52a6f209f 100644 --- a/src/core/constraints.h +++ b/src/core/constraints.h @@ -17,9 +17,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_CONSTRAINTS_H diff --git a/src/core/core.c b/src/core/core.c index 6840ece87..cb2a747e5 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -18,9 +18,7 @@ * 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. + * along with this program; if not, see . */ #include diff --git a/src/core/core.h b/src/core/core.h index 7b861da7e..a3321531b 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -17,9 +17,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_CORE_H diff --git a/src/core/delete.c b/src/core/delete.c index 90a35f33b..437becf1e 100644 --- a/src/core/delete.c +++ b/src/core/delete.c @@ -17,9 +17,7 @@ * 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. + * along with this program; if not, see . */ #define _XOPEN_SOURCE /* for kill() */ diff --git a/src/core/display-private.h b/src/core/display-private.h index a8fa75363..4d86eae65 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -19,9 +19,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_DISPLAY_PRIVATE_H diff --git a/src/core/display.c b/src/core/display.c index 2313c8823..8a98cf5ab 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -17,9 +17,7 @@ * 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. + * along with this program; if not, see . */ /** diff --git a/src/core/edge-resistance.c b/src/core/edge-resistance.c index 17cde421f..6a2648a0a 100644 --- a/src/core/edge-resistance.c +++ b/src/core/edge-resistance.c @@ -16,9 +16,7 @@ * 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. + * along with this program; if not, see . */ #include diff --git a/src/core/edge-resistance.h b/src/core/edge-resistance.h index 14ba17a09..c85849020 100644 --- a/src/core/edge-resistance.h +++ b/src/core/edge-resistance.h @@ -16,9 +16,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_EDGE_RESISTANCE_H diff --git a/src/core/errors.c b/src/core/errors.c index 4028133c1..56a7bd423 100644 --- a/src/core/errors.c +++ b/src/core/errors.c @@ -15,9 +15,7 @@ * 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. + * along with this program; if not, see . */ /** diff --git a/src/core/frame.c b/src/core/frame.c index fa4359697..5fa7bee17 100644 --- a/src/core/frame.c +++ b/src/core/frame.c @@ -18,9 +18,7 @@ * 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. + * along with this program; if not, see . */ #include diff --git a/src/core/frame.h b/src/core/frame.h index d633adc25..0f1ebea4f 100644 --- a/src/core/frame.h +++ b/src/core/frame.h @@ -16,9 +16,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_FRAME_PRIVATE_H diff --git a/src/core/group-private.h b/src/core/group-private.h index 6f56b1b16..72e6cd275 100644 --- a/src/core/group-private.h +++ b/src/core/group-private.h @@ -16,9 +16,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_GROUP_PRIVATE_H diff --git a/src/core/group-props.c b/src/core/group-props.c index 05e829003..521ffbd60 100644 --- a/src/core/group-props.c +++ b/src/core/group-props.c @@ -16,9 +16,7 @@ * 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. + * along with this program; if not, see . */ #include diff --git a/src/core/group-props.h b/src/core/group-props.h index a0fb70f6b..1fb49ea1a 100644 --- a/src/core/group-props.h +++ b/src/core/group-props.h @@ -16,9 +16,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_GROUP_PROPS_H diff --git a/src/core/group.c b/src/core/group.c index 8655d48a1..8965735c2 100644 --- a/src/core/group.c +++ b/src/core/group.c @@ -15,9 +15,7 @@ * 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. + * along with this program; if not, see . */ /** diff --git a/src/core/iconcache.c b/src/core/iconcache.c index cb3924b16..30018d22e 100644 --- a/src/core/iconcache.c +++ b/src/core/iconcache.c @@ -16,9 +16,7 @@ * 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. + * along with this program; if not, see . */ #include diff --git a/src/core/iconcache.h b/src/core/iconcache.h index 22a241bef..84143a61c 100644 --- a/src/core/iconcache.h +++ b/src/core/iconcache.h @@ -16,9 +16,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_ICON_CACHE_H diff --git a/src/core/keybindings-private.h b/src/core/keybindings-private.h index da36666fc..07889220e 100644 --- a/src/core/keybindings-private.h +++ b/src/core/keybindings-private.h @@ -21,9 +21,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_KEYBINDINGS_PRIVATE_H diff --git a/src/core/keybindings.c b/src/core/keybindings.c index 515e591d1..727a63a8f 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -18,9 +18,7 @@ * 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. + * along with this program; if not, see . */ /** diff --git a/src/core/main.c b/src/core/main.c index 2cba35ce2..89a9d06fd 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -17,9 +17,7 @@ * 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. + * along with this program; if not, see . */ /** diff --git a/src/core/meta-cursor-tracker-private.h b/src/core/meta-cursor-tracker-private.h index b0ad11e6a..b089f0f80 100644 --- a/src/core/meta-cursor-tracker-private.h +++ b/src/core/meta-cursor-tracker-private.h @@ -14,9 +14,7 @@ * 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. + * along with this program; if not, see . * * Author: Giovanni Campagna */ diff --git a/src/core/meta-cursor-tracker.c b/src/core/meta-cursor-tracker.c index 550abff83..a603d95a5 100644 --- a/src/core/meta-cursor-tracker.c +++ b/src/core/meta-cursor-tracker.c @@ -14,9 +14,7 @@ * 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. + * along with this program; if not, see . * * Author: Giovanni Campagna */ diff --git a/src/core/meta-idle-monitor-private.h b/src/core/meta-idle-monitor-private.h index 40608ffd9..05289782f 100644 --- a/src/core/meta-idle-monitor-private.h +++ b/src/core/meta-idle-monitor-private.h @@ -14,9 +14,7 @@ * 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. + * along with this program; if not, see . * * Adapted from gnome-session/gnome-session/gs-idle-monitor.c and * from gnome-desktop/libgnome-desktop/gnome-idle-monitor.c diff --git a/src/core/meta-idle-monitor.c b/src/core/meta-idle-monitor.c index ac38b04c0..7712cc78d 100644 --- a/src/core/meta-idle-monitor.c +++ b/src/core/meta-idle-monitor.c @@ -14,9 +14,7 @@ * 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. + * along with this program; if not, see . * * Adapted from gnome-session/gnome-session/gs-idle-monitor.c and * from gnome-desktop/libgnome-desktop/gnome-idle-monitor.c diff --git a/src/core/meta-xrandr-shared.h b/src/core/meta-xrandr-shared.h index 827876a66..99e3d9825 100644 --- a/src/core/meta-xrandr-shared.h +++ b/src/core/meta-xrandr-shared.h @@ -13,9 +13,7 @@ * 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. + * along with this program; if not, see . */ /* This file is shared between mutter (src/core/meta-xrandr-shared.h) diff --git a/src/core/monitor-config.c b/src/core/monitor-config.c index e5aee4d00..5d69a5d52 100644 --- a/src/core/monitor-config.c +++ b/src/core/monitor-config.c @@ -20,9 +20,7 @@ * 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. + * along with this program; if not, see . */ /* diff --git a/src/core/monitor-private.h b/src/core/monitor-private.h index fdb11a7ec..2b0ef422c 100644 --- a/src/core/monitor-private.h +++ b/src/core/monitor-private.h @@ -29,9 +29,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_MONITOR_PRIVATE_H diff --git a/src/core/monitor-xrandr.c b/src/core/monitor-xrandr.c index 167b94c54..66d89539d 100644 --- a/src/core/monitor-xrandr.c +++ b/src/core/monitor-xrandr.c @@ -20,9 +20,7 @@ * 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. + * along with this program; if not, see . */ #include "config.h" diff --git a/src/core/monitor.c b/src/core/monitor.c index db47899c9..daca82a70 100644 --- a/src/core/monitor.c +++ b/src/core/monitor.c @@ -20,9 +20,7 @@ * 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. + * along with this program; if not, see . */ #include "config.h" diff --git a/src/core/mutter.c b/src/core/mutter.c index 08f833b65..00164c15c 100644 --- a/src/core/mutter.c +++ b/src/core/mutter.c @@ -14,9 +14,7 @@ * 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. + * along with this program; if not, see . */ #include "config.h" diff --git a/src/core/place.c b/src/core/place.c index 821fca039..8894114d6 100644 --- a/src/core/place.c +++ b/src/core/place.c @@ -19,9 +19,7 @@ * 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. + * along with this program; if not, see . */ #include diff --git a/src/core/place.h b/src/core/place.h index d9647e25b..250f2045d 100644 --- a/src/core/place.h +++ b/src/core/place.h @@ -16,9 +16,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_PLACE_H diff --git a/src/core/prefs.c b/src/core/prefs.c index 3a4909fea..7534210b8 100644 --- a/src/core/prefs.c +++ b/src/core/prefs.c @@ -17,9 +17,7 @@ * 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. + * along with this program; if not, see . */ /** diff --git a/src/core/screen-private.h b/src/core/screen-private.h index 36c7a38ef..3d02e1827 100644 --- a/src/core/screen-private.h +++ b/src/core/screen-private.h @@ -25,9 +25,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_SCREEN_PRIVATE_H diff --git a/src/core/screen.c b/src/core/screen.c index 939412544..cc3c13419 100644 --- a/src/core/screen.c +++ b/src/core/screen.c @@ -19,9 +19,7 @@ * 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. + * along with this program; if not, see . */ /** diff --git a/src/core/session.c b/src/core/session.c index 6d435fd5c..269d4d0c3 100644 --- a/src/core/session.c +++ b/src/core/session.c @@ -18,9 +18,7 @@ * 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. + * along with this program; if not, see . */ #include diff --git a/src/core/session.h b/src/core/session.h index 62a9370d1..c032ff10c 100644 --- a/src/core/session.h +++ b/src/core/session.h @@ -23,9 +23,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_SESSION_H diff --git a/src/core/stack-tracker.c b/src/core/stack-tracker.c index 63044a2d8..5d88a46da 100644 --- a/src/core/stack-tracker.c +++ b/src/core/stack-tracker.c @@ -29,9 +29,7 @@ * 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. + * along with this program; if not, see . */ #include diff --git a/src/core/stack-tracker.h b/src/core/stack-tracker.h index 4b7b1bfd7..f74400efa 100644 --- a/src/core/stack-tracker.h +++ b/src/core/stack-tracker.h @@ -28,9 +28,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_STACK_TRACKER_H diff --git a/src/core/stack.c b/src/core/stack.c index ed1d6d8d4..6cf078c52 100644 --- a/src/core/stack.c +++ b/src/core/stack.c @@ -22,9 +22,7 @@ * 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. + * along with this program; if not, see . */ #include diff --git a/src/core/stack.h b/src/core/stack.h index 423672b32..f9555a981 100644 --- a/src/core/stack.h +++ b/src/core/stack.h @@ -15,9 +15,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_STACK_H diff --git a/src/core/testboxes.c b/src/core/testboxes.c index 128efac77..19def8cf5 100644 --- a/src/core/testboxes.c +++ b/src/core/testboxes.c @@ -16,9 +16,7 @@ * 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. + * along with this program; if not, see . */ #include "boxes-private.h" diff --git a/src/core/util.c b/src/core/util.c index 48d6e56a0..3ac907fd4 100644 --- a/src/core/util.c +++ b/src/core/util.c @@ -15,9 +15,7 @@ * 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. + * along with this program; if not, see . */ /** diff --git a/src/core/window-private.h b/src/core/window-private.h index ef4c83df8..7c09e6835 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -26,9 +26,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_WINDOW_PRIVATE_H diff --git a/src/core/window-props.c b/src/core/window-props.c index 447ac3e92..a9145eefa 100644 --- a/src/core/window-props.c +++ b/src/core/window-props.c @@ -31,9 +31,7 @@ * 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. + * along with this program; if not, see . */ #define _GNU_SOURCE diff --git a/src/core/window-props.h b/src/core/window-props.h index 16db50b9e..4ea42719f 100644 --- a/src/core/window-props.h +++ b/src/core/window-props.h @@ -25,9 +25,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_WINDOW_PROPS_H diff --git a/src/core/window.c b/src/core/window.c index 4b05d4e3f..b4a845d6a 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -17,9 +17,7 @@ * 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. + * along with this program; if not, see . */ /** diff --git a/src/core/workspace-private.h b/src/core/workspace-private.h index 4e94fa052..4228a9b6e 100644 --- a/src/core/workspace-private.h +++ b/src/core/workspace-private.h @@ -25,9 +25,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_WORKSPACE_PRIVATE_H diff --git a/src/core/workspace.c b/src/core/workspace.c index e5da6d226..f1e2527a1 100644 --- a/src/core/workspace.c +++ b/src/core/workspace.c @@ -16,9 +16,7 @@ * 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. + * along with this program; if not, see . */ /** diff --git a/src/core/xprops.c b/src/core/xprops.c index 040581c53..33278ab07 100644 --- a/src/core/xprops.c +++ b/src/core/xprops.c @@ -22,9 +22,7 @@ * 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. + * along with this program; if not, see . */ /*********************************************************** diff --git a/src/core/xprops.h b/src/core/xprops.h index a5c4fb9a3..241557ff7 100644 --- a/src/core/xprops.h +++ b/src/core/xprops.h @@ -16,9 +16,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_XPROPS_H diff --git a/src/meta/atomnames.h b/src/meta/atomnames.h index f83ff8cbe..d5e8a47ff 100644 --- a/src/meta/atomnames.h +++ b/src/meta/atomnames.h @@ -18,9 +18,7 @@ * 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. + * along with this program; if not, see . */ /* diff --git a/src/meta/boxes.h b/src/meta/boxes.h index 0adcfcb37..489ce04b3 100644 --- a/src/meta/boxes.h +++ b/src/meta/boxes.h @@ -16,9 +16,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_BOXES_H diff --git a/src/meta/common.h b/src/meta/common.h index e9fe62990..ffccb2d92 100644 --- a/src/meta/common.h +++ b/src/meta/common.h @@ -19,9 +19,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_COMMON_H diff --git a/src/meta/compositor-mutter.h b/src/meta/compositor-mutter.h index a0f5140fd..ee120edd1 100644 --- a/src/meta/compositor-mutter.h +++ b/src/meta/compositor-mutter.h @@ -17,9 +17,7 @@ * 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. + * along with this program; if not, see . */ #ifndef MUTTER_H_ diff --git a/src/meta/compositor.h b/src/meta/compositor.h index b0e54550d..42ff0dd8e 100644 --- a/src/meta/compositor.h +++ b/src/meta/compositor.h @@ -14,9 +14,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_COMPOSITOR_H diff --git a/src/meta/display.h b/src/meta/display.h index 09f95e9cc..60e9ab14d 100644 --- a/src/meta/display.h +++ b/src/meta/display.h @@ -14,9 +14,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_DISPLAY_H diff --git a/src/meta/errors.h b/src/meta/errors.h index 6ac141722..d2aa27b6b 100644 --- a/src/meta/errors.h +++ b/src/meta/errors.h @@ -16,9 +16,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_ERRORS_H diff --git a/src/meta/gradient.h b/src/meta/gradient.h index bcf5521b2..1c9ac242f 100644 --- a/src/meta/gradient.h +++ b/src/meta/gradient.h @@ -17,9 +17,7 @@ * 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. */ + * along with this program; if not, see . */ #ifndef META_GRADIENT_H #define META_GRADIENT_H diff --git a/src/meta/group.h b/src/meta/group.h index 3f16edd6c..2ec647806 100644 --- a/src/meta/group.h +++ b/src/meta/group.h @@ -16,9 +16,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_GROUP_H diff --git a/src/meta/keybindings.h b/src/meta/keybindings.h index b89619512..55216c243 100644 --- a/src/meta/keybindings.h +++ b/src/meta/keybindings.h @@ -12,9 +12,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_KEYBINDINGS_H diff --git a/src/meta/main.h b/src/meta/main.h index dd4e7f1d9..35eb73da7 100644 --- a/src/meta/main.h +++ b/src/meta/main.h @@ -16,9 +16,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_MAIN_H diff --git a/src/meta/meta-background-actor.h b/src/meta/meta-background-actor.h index 96fe1c636..56e97688f 100644 --- a/src/meta/meta-background-actor.h +++ b/src/meta/meta-background-actor.h @@ -15,9 +15,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_BACKGROUND_ACTOR_H diff --git a/src/meta/meta-background.h b/src/meta/meta-background.h index 0295d4e94..c171df326 100644 --- a/src/meta/meta-background.h +++ b/src/meta/meta-background.h @@ -15,9 +15,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_BACKGROUND_H diff --git a/src/meta/meta-cursor-tracker.h b/src/meta/meta-cursor-tracker.h index 39202951a..e045fa51f 100644 --- a/src/meta/meta-cursor-tracker.h +++ b/src/meta/meta-cursor-tracker.h @@ -14,9 +14,7 @@ * 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. + * along with this program; if not, see . * * Author: Giovanni Campagna */ diff --git a/src/meta/meta-idle-monitor.h b/src/meta/meta-idle-monitor.h index 883827373..b77d8e250 100644 --- a/src/meta/meta-idle-monitor.h +++ b/src/meta/meta-idle-monitor.h @@ -14,9 +14,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_IDLE_MONITOR_H diff --git a/src/meta/meta-plugin.h b/src/meta/meta-plugin.h index 0587551c8..00fe77989 100644 --- a/src/meta/meta-plugin.h +++ b/src/meta/meta-plugin.h @@ -16,9 +16,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_PLUGIN_H_ diff --git a/src/meta/meta-shadow-factory.h b/src/meta/meta-shadow-factory.h index b95ec49f8..466264e93 100644 --- a/src/meta/meta-shadow-factory.h +++ b/src/meta/meta-shadow-factory.h @@ -17,9 +17,7 @@ * 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. + * along with this program; if not, see . */ #ifndef __META_SHADOW_FACTORY_H__ diff --git a/src/meta/meta-shaped-texture.h b/src/meta/meta-shaped-texture.h index dac4ccc25..9eea4b8d9 100644 --- a/src/meta/meta-shaped-texture.h +++ b/src/meta/meta-shaped-texture.h @@ -18,9 +18,7 @@ * 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. + * along with this program; if not, see . */ #ifndef __META_SHAPED_TEXTURE_H__ diff --git a/src/meta/meta-window-actor.h b/src/meta/meta-window-actor.h index ce6c64022..9f808a9ac 100644 --- a/src/meta/meta-window-actor.h +++ b/src/meta/meta-window-actor.h @@ -17,9 +17,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_WINDOW_ACTOR_H_ diff --git a/src/meta/prefs.h b/src/meta/prefs.h index 3ccaddb20..cc07d292c 100644 --- a/src/meta/prefs.h +++ b/src/meta/prefs.h @@ -17,9 +17,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_PREFS_H diff --git a/src/meta/screen.h b/src/meta/screen.h index 88a3481a4..6e0cde7ee 100644 --- a/src/meta/screen.h +++ b/src/meta/screen.h @@ -14,9 +14,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_SCREEN_H diff --git a/src/meta/theme.h b/src/meta/theme.h index 5ecb76c3f..c813ee299 100644 --- a/src/meta/theme.h +++ b/src/meta/theme.h @@ -16,9 +16,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_THEME_H diff --git a/src/meta/types.h b/src/meta/types.h index f13471146..cd6af2b63 100644 --- a/src/meta/types.h +++ b/src/meta/types.h @@ -14,9 +14,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_TYPES_H diff --git a/src/meta/util.h b/src/meta/util.h index 091f4f9c7..4644de5a1 100644 --- a/src/meta/util.h +++ b/src/meta/util.h @@ -17,9 +17,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_UTIL_H diff --git a/src/meta/window.h b/src/meta/window.h index d2fb3a740..ff2d037d3 100644 --- a/src/meta/window.h +++ b/src/meta/window.h @@ -14,9 +14,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_WINDOW_H diff --git a/src/meta/workspace.h b/src/meta/workspace.h index 972177060..54b3858a0 100644 --- a/src/meta/workspace.h +++ b/src/meta/workspace.h @@ -15,9 +15,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_WORKSPACE_H diff --git a/src/ui/draw-workspace.c b/src/ui/draw-workspace.c index 58cff001a..2d5662993 100644 --- a/src/ui/draw-workspace.c +++ b/src/ui/draw-workspace.c @@ -20,9 +20,7 @@ * 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. + * along with this program; if not, see . */ #include "draw-workspace.h" diff --git a/src/ui/draw-workspace.h b/src/ui/draw-workspace.h index 7aa04918f..5c3a5359e 100644 --- a/src/ui/draw-workspace.h +++ b/src/ui/draw-workspace.h @@ -20,9 +20,7 @@ * 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. + * along with this program; if not, see . */ #ifndef WNCK_DRAW_WORKSPACE_H diff --git a/src/ui/frames.c b/src/ui/frames.c index 63f18379d..d69224ece 100644 --- a/src/ui/frames.c +++ b/src/ui/frames.c @@ -18,9 +18,7 @@ * 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. + * along with this program; if not, see . */ #include diff --git a/src/ui/frames.h b/src/ui/frames.h index 3298fc2cf..c0618f399 100644 --- a/src/ui/frames.h +++ b/src/ui/frames.h @@ -16,9 +16,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_FRAMES_H diff --git a/src/ui/gradient.c b/src/ui/gradient.c index 6017f65a6..e3ce60bb5 100644 --- a/src/ui/gradient.c +++ b/src/ui/gradient.c @@ -16,9 +16,7 @@ * 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. */ + * along with this program; if not, see . */ /** * SECTION:gradient diff --git a/src/ui/menu.c b/src/ui/menu.c index 34ceeb7a0..d59e24211 100644 --- a/src/ui/menu.c +++ b/src/ui/menu.c @@ -18,9 +18,7 @@ * 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. + * along with this program; if not, see . */ #include diff --git a/src/ui/menu.h b/src/ui/menu.h index adcf32813..ab42a8ba9 100644 --- a/src/ui/menu.h +++ b/src/ui/menu.h @@ -16,9 +16,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_MENU_H diff --git a/src/ui/metaaccellabel.c b/src/ui/metaaccellabel.c index affec99d8..be65b3537 100644 --- a/src/ui/metaaccellabel.c +++ b/src/ui/metaaccellabel.c @@ -19,9 +19,7 @@ * 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, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * License along with this library; if not, see . */ /* diff --git a/src/ui/metaaccellabel.h b/src/ui/metaaccellabel.h index c90c47a90..cebd6eb77 100644 --- a/src/ui/metaaccellabel.h +++ b/src/ui/metaaccellabel.h @@ -19,9 +19,7 @@ * 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, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * License along with this library; if not, see . */ /* diff --git a/src/ui/resizepopup.c b/src/ui/resizepopup.c index bcce02d8a..ed793cde0 100644 --- a/src/ui/resizepopup.c +++ b/src/ui/resizepopup.c @@ -16,9 +16,7 @@ * 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. + * along with this program; if not, see . */ #include diff --git a/src/ui/resizepopup.h b/src/ui/resizepopup.h index 0e307dac4..e5096387f 100644 --- a/src/ui/resizepopup.h +++ b/src/ui/resizepopup.h @@ -16,9 +16,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_RESIZEPOPUP_H diff --git a/src/ui/tabpopup.c b/src/ui/tabpopup.c index c8dbeeaa4..285e29573 100644 --- a/src/ui/tabpopup.c +++ b/src/ui/tabpopup.c @@ -18,9 +18,7 @@ * 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. + * along with this program; if not, see . */ #include diff --git a/src/ui/tabpopup.h b/src/ui/tabpopup.h index ee609d9c8..ba324964a 100644 --- a/src/ui/tabpopup.h +++ b/src/ui/tabpopup.h @@ -17,9 +17,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_TABPOPUP_H diff --git a/src/ui/testgradient.c b/src/ui/testgradient.c index c66c9e52f..fdc9576f9 100644 --- a/src/ui/testgradient.c +++ b/src/ui/testgradient.c @@ -16,9 +16,7 @@ * 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. */ + * along with this program; if not, see . */ #include #include diff --git a/src/ui/theme-parser.c b/src/ui/theme-parser.c index 00942b03a..e9ce02827 100644 --- a/src/ui/theme-parser.c +++ b/src/ui/theme-parser.c @@ -16,9 +16,7 @@ * 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. + * along with this program; if not, see . */ #include diff --git a/src/ui/theme-private.h b/src/ui/theme-private.h index 7e521e0f3..269f30e3e 100644 --- a/src/ui/theme-private.h +++ b/src/ui/theme-private.h @@ -16,9 +16,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_THEME_PRIVATE_H diff --git a/src/ui/theme.c b/src/ui/theme.c index 17eee4728..51255ee92 100644 --- a/src/ui/theme.c +++ b/src/ui/theme.c @@ -14,9 +14,7 @@ * 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. + * along with this program; if not, see . */ /* diff --git a/src/ui/tile-preview.c b/src/ui/tile-preview.c index 61a438578..8fbf46884 100644 --- a/src/ui/tile-preview.c +++ b/src/ui/tile-preview.c @@ -16,9 +16,7 @@ * 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. + * along with this program; if not, see . */ #include diff --git a/src/ui/tile-preview.h b/src/ui/tile-preview.h index 8152a60ee..352483fa3 100644 --- a/src/ui/tile-preview.h +++ b/src/ui/tile-preview.h @@ -16,9 +16,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_TILE_PREVIEW_H #define META_TILE_PREVIEW_H diff --git a/src/ui/ui.c b/src/ui/ui.c index ed2c66d13..50f9071f1 100644 --- a/src/ui/ui.c +++ b/src/ui/ui.c @@ -16,9 +16,7 @@ * 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. + * along with this program; if not, see . */ #include diff --git a/src/ui/ui.h b/src/ui/ui.h index e397c43d0..07bf77edd 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -16,9 +16,7 @@ * 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. + * along with this program; if not, see . */ #ifndef META_UI_H diff --git a/test/mutter-test b/test/mutter-test index 463e0ba91..2266c2f34 100644 --- a/test/mutter-test +++ b/test/mutter-test @@ -15,9 +15,7 @@ # 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. +# along with this program; if not, see . # # --------------------- # diff --git a/test/tokentest/get-tokens.py b/test/tokentest/get-tokens.py index 728fa7c3a..42a8844e6 100644 --- a/test/tokentest/get-tokens.py +++ b/test/tokentest/get-tokens.py @@ -12,9 +12,7 @@ # 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. +# along with this program; if not, see . import os diff --git a/test/tokentest/tokentest.c b/test/tokentest/tokentest.c index fbfbdefd8..107d9ee4a 100644 --- a/test/tokentest/tokentest.c +++ b/test/tokentest/tokentest.c @@ -14,9 +14,7 @@ * 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. + * along with this program; if not, see . */ /* Still under heavy development. */ diff --git a/test/tokentest/tokentest.ini b/test/tokentest/tokentest.ini index a5187873e..edfc58764 100644 --- a/test/tokentest/tokentest.ini +++ b/test/tokentest/tokentest.ini @@ -14,9 +14,7 @@ # 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. +# along with this program; if not, see . ########################### diff --git a/tools/commit-wrangler.py b/tools/commit-wrangler.py index f3e15ea12..0ec68b71d 100644 --- a/tools/commit-wrangler.py +++ b/tools/commit-wrangler.py @@ -17,9 +17,7 @@ # 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. +# along with this program; if not, see . import time import commands diff --git a/tools/patch-wrangler.py b/tools/patch-wrangler.py index f1bb65b0d..c5e80c62f 100644 --- a/tools/patch-wrangler.py +++ b/tools/patch-wrangler.py @@ -15,9 +15,7 @@ # 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. +# along with this program; if not, see . import os diff --git a/tools/ppa-magic.py b/tools/ppa-magic.py index 5a7e32667..3971cbca2 100644 --- a/tools/ppa-magic.py +++ b/tools/ppa-magic.py @@ -16,9 +16,7 @@ # 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. +# along with this program; if not, see . import time import os @@ -123,8 +121,7 @@ License: GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this package; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + along with this package; if not, see . On Debian systems, the complete text of the GNU General Public License can be found in `/usr/share/common-licenses/GPL'. diff --git a/tools/release-wrangler.py b/tools/release-wrangler.py index 548af7fe2..1dcd5fe33 100644 --- a/tools/release-wrangler.py +++ b/tools/release-wrangler.py @@ -17,9 +17,7 @@ # 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. +# along with this program; if not, see . import os import posixpath From b4535f26225779a3e131860421077dbd0f56c24a Mon Sep 17 00:00:00 2001 From: Andika Triwidada Date: Sun, 12 Jan 2014 08:44:30 +0700 Subject: [PATCH 384/889] Updated obsolete FSF postal address in COPYING Fixed https://bugzilla.gnome.org/show_bug.cgi?id=721517 #1 --- COPYING | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/COPYING b/COPYING index d60c31a97..d159169d1 100644 --- a/COPYING +++ b/COPYING @@ -1,12 +1,12 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. - Preamble + Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public @@ -15,7 +15,7 @@ software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to +the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not @@ -55,8 +55,8 @@ patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. - - GNU GENERAL PUBLIC LICENSE + + GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains @@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions: License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) - + These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in @@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. - + 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is @@ -225,7 +225,7 @@ impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. - + 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License @@ -255,7 +255,7 @@ make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. - NO WARRANTY + NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN @@ -277,9 +277,9 @@ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it @@ -303,17 +303,16 @@ the "copyright" line and a pointer to where the full notice is found. 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 - + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: - Gnomovision version 69, Copyright (C) year name of author + Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. @@ -336,5 +335,5 @@ necessary. Here is a sample; alter the names: This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General +library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. From 419dfd333af2aab0924aaf2bf6f66a156df9d1f2 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 13 Jan 2014 13:03:19 -0500 Subject: [PATCH 385/889] Update for Cogl API breaks --- configure.ac | 2 +- src/compositor/meta-texture-rectangle.c | 9 ++------- src/compositor/meta-texture-rectangle.h | 4 +--- src/compositor/meta-texture-tower.c | 4 ---- src/compositor/meta-window-actor.c | 5 +---- src/core/meta-cursor-tracker.c | 1 - 6 files changed, 5 insertions(+), 20 deletions(-) diff --git a/configure.ac b/configure.ac index dad1e2ce9..87aff64d6 100644 --- a/configure.ac +++ b/configure.ac @@ -79,7 +79,7 @@ MUTTER_PC_MODULES=" gsettings-desktop-schemas >= 3.7.3 xcomposite >= 0.2 xfixes xrender xdamage xi >= 1.6.0 $CLUTTER_PACKAGE >= 1.17.1 - cogl-1.0 >= 1.13.3 + cogl-1.0 >= 1.17.1 upower-glib >= 0.99.0 gnome-desktop-3.0 " diff --git a/src/compositor/meta-texture-rectangle.c b/src/compositor/meta-texture-rectangle.c index 3fc9430b5..450155d95 100644 --- a/src/compositor/meta-texture-rectangle.c +++ b/src/compositor/meta-texture-rectangle.c @@ -30,10 +30,8 @@ CoglTexture * meta_texture_rectangle_new (unsigned int width, unsigned int height, CoglPixelFormat format, - CoglPixelFormat internal_format, unsigned int rowstride, - const guint8 *data, - GError **error) + const guint8 *data) { ClutterBackend *backend = clutter_get_default_backend (); @@ -41,10 +39,7 @@ meta_texture_rectangle_new (unsigned int width, clutter_backend_get_cogl_context (backend); CoglTextureRectangle *tex_rect; - tex_rect = cogl_texture_rectangle_new_with_size (context, - width, height, - internal_format, - error); + tex_rect = cogl_texture_rectangle_new_with_size (context, width, height); if (tex_rect == NULL) return NULL; diff --git a/src/compositor/meta-texture-rectangle.h b/src/compositor/meta-texture-rectangle.h index 30f60d3df..7b84229f5 100644 --- a/src/compositor/meta-texture-rectangle.h +++ b/src/compositor/meta-texture-rectangle.h @@ -32,10 +32,8 @@ CoglTexture * meta_texture_rectangle_new (unsigned int width, unsigned int height, CoglPixelFormat format, - CoglPixelFormat internal_format, unsigned int rowstride, - const guint8 *data, - GError **error); + const guint8 *data); gboolean meta_texture_rectangle_check (CoglTexture *texture); diff --git a/src/compositor/meta-texture-tower.c b/src/compositor/meta-texture-tower.c index 207abb279..a53147f3f 100644 --- a/src/compositor/meta-texture-tower.c +++ b/src/compositor/meta-texture-tower.c @@ -359,13 +359,9 @@ texture_tower_create_texture (MetaTextureTower *tower, meta_texture_rectangle_new (width, height, /* data format */ TEXTURE_FORMAT, - /* internal cogl format */ - TEXTURE_FORMAT, /* rowstride */ width * 4, /* data */ - NULL, - /* error */ NULL); } else diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index c5a2af43d..d5c1a4e8b 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -2174,10 +2174,7 @@ build_and_scan_frame_mask (MetaWindowActor *self, { mask_texture = meta_texture_rectangle_new (tex_width, tex_height, COGL_PIXEL_FORMAT_A_8, - COGL_PIXEL_FORMAT_A_8, - stride, - mask_data, - NULL /* error */); + stride, mask_data); } else { diff --git a/src/core/meta-cursor-tracker.c b/src/core/meta-cursor-tracker.c index a603d95a5..df8de3d0d 100644 --- a/src/core/meta-cursor-tracker.c +++ b/src/core/meta-cursor-tracker.c @@ -748,7 +748,6 @@ ensure_xfixes_cursor (MetaCursorTracker *tracker) cursor_image->width, cursor_image->height, CLUTTER_CAIRO_FORMAT_ARGB32, - COGL_PIXEL_FORMAT_ANY, cursor_image->width * 4, /* stride */ cursor_data, NULL); From 7155d7e043e8d855ffe62bc844af6bacea21f851 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 13 Jan 2014 13:24:30 -0500 Subject: [PATCH 386/889] Properly set the number of components on the CoglTextureRectangle We need to set the number of components on the CoglTextureRectangle to prevent wasting too much GPU memory. As we need to do this before we call cogl_texture_set_region, just remove the meta_texture_rectangle_new wrapper, and make callers call cogl_texture_rectangle_new_with_size directly. --- src/compositor/meta-texture-rectangle.c | 30 ------------------------- src/compositor/meta-texture-rectangle.h | 7 ------ src/compositor/meta-texture-tower.c | 12 ++++------ src/compositor/meta-window-actor.c | 15 ++++++++++--- 4 files changed, 16 insertions(+), 48 deletions(-) diff --git a/src/compositor/meta-texture-rectangle.c b/src/compositor/meta-texture-rectangle.c index 450155d95..cd585b51f 100644 --- a/src/compositor/meta-texture-rectangle.c +++ b/src/compositor/meta-texture-rectangle.c @@ -26,36 +26,6 @@ #include #include "meta-texture-rectangle.h" -CoglTexture * -meta_texture_rectangle_new (unsigned int width, - unsigned int height, - CoglPixelFormat format, - unsigned int rowstride, - const guint8 *data) -{ - ClutterBackend *backend = - clutter_get_default_backend (); - CoglContext *context = - clutter_backend_get_cogl_context (backend); - CoglTextureRectangle *tex_rect; - - tex_rect = cogl_texture_rectangle_new_with_size (context, width, height); - if (tex_rect == NULL) - return NULL; - - if (data) - cogl_texture_set_region (COGL_TEXTURE (tex_rect), - 0, 0, /* src_x/y */ - 0, 0, /* dst_x/y */ - width, height, /* dst_width/height */ - width, height, /* width/height */ - format, - rowstride, - data); - - return COGL_TEXTURE (tex_rect); -} - static void texture_rectangle_check_cb (CoglTexture *sub_texture, const float *sub_texture_coords, diff --git a/src/compositor/meta-texture-rectangle.h b/src/compositor/meta-texture-rectangle.h index 7b84229f5..ba2624f52 100644 --- a/src/compositor/meta-texture-rectangle.h +++ b/src/compositor/meta-texture-rectangle.h @@ -28,13 +28,6 @@ G_BEGIN_DECLS -CoglTexture * -meta_texture_rectangle_new (unsigned int width, - unsigned int height, - CoglPixelFormat format, - unsigned int rowstride, - const guint8 *data); - gboolean meta_texture_rectangle_check (CoglTexture *texture); diff --git a/src/compositor/meta-texture-tower.c b/src/compositor/meta-texture-tower.c index a53147f3f..0fd5f5f70 100644 --- a/src/compositor/meta-texture-tower.c +++ b/src/compositor/meta-texture-tower.c @@ -355,14 +355,10 @@ texture_tower_create_texture (MetaTextureTower *tower, if ((!is_power_of_two (width) || !is_power_of_two (height)) && meta_texture_rectangle_check (tower->textures[level - 1])) { - tower->textures[level] = - meta_texture_rectangle_new (width, height, - /* data format */ - TEXTURE_FORMAT, - /* rowstride */ - width * 4, - /* data */ - NULL); + ClutterBackend *backend = clutter_get_default_backend (); + CoglContext *context = clutter_backend_get_cogl_context (backend); + + tower->textures[level] = cogl_texture_rectangle_new_with_size (context, width, height); } else { diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index d5c1a4e8b..f45bd53ad 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -2172,9 +2172,18 @@ build_and_scan_frame_mask (MetaWindowActor *self, if (meta_texture_rectangle_check (paint_tex)) { - mask_texture = meta_texture_rectangle_new (tex_width, tex_height, - COGL_PIXEL_FORMAT_A_8, - stride, mask_data); + ClutterBackend *backend = clutter_get_default_backend (); + CoglContext *context = clutter_backend_get_cogl_context (backend); + + mask_texture = COGL_TEXTURE (cogl_texture_rectangle_new_with_size (context, tex_width, tex_height)); + cogl_texture_set_components (mask_texture, COGL_TEXTURE_COMPONENTS_A); + cogl_texture_set_region (mask_texture, + 0, 0, /* src_x/y */ + 0, 0, /* dst_x/y */ + tex_width, tex_height, /* dst_width/height */ + tex_width, tex_height, /* width/height */ + COGL_PIXEL_FORMAT_A_8, + stride, mask_data); } else { From 2391606cc52847288eeed49e14443361bfb704a1 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 13 Jan 2014 13:55:53 -0500 Subject: [PATCH 387/889] cursor-tracker: Update for Cogl APIs as well --- src/core/meta-cursor-tracker.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/core/meta-cursor-tracker.c b/src/core/meta-cursor-tracker.c index df8de3d0d..b3e1b5907 100644 --- a/src/core/meta-cursor-tracker.c +++ b/src/core/meta-cursor-tracker.c @@ -305,7 +305,6 @@ meta_cursor_reference_from_theme (MetaCursorTracker *tracker, self->texture = cogl_texture_2d_new_from_data (cogl_context, width, height, cogl_format, - COGL_PIXEL_FORMAT_ANY, rowstride, (uint8_t*)image->pixels, NULL); @@ -365,7 +364,7 @@ meta_cursor_reference_from_buffer (MetaCursorTracker *tracker, ClutterBackend *backend; CoglContext *cogl_context; MetaCursorReference *self; - CoglPixelFormat cogl_format, cogl_internal_format; + CoglPixelFormat cogl_format; struct wl_shm_buffer *shm_buffer; uint32_t gbm_format; @@ -389,37 +388,31 @@ meta_cursor_reference_from_buffer (MetaCursorTracker *tracker, #if G_BYTE_ORDER == G_BIG_ENDIAN case WL_SHM_FORMAT_ARGB8888: cogl_format = COGL_PIXEL_FORMAT_ARGB_8888_PRE; - cogl_internal_format = COGL_PIXEL_FORMAT_ANY; gbm_format = GBM_FORMAT_ARGB8888; break; case WL_SHM_FORMAT_XRGB8888: cogl_format = COGL_PIXEL_FORMAT_ARGB_8888; - cogl_internal_format = COGL_PIXEL_FORMAT_RGB_888; gbm_format = GBM_FORMAT_XRGB8888; break; #else case WL_SHM_FORMAT_ARGB8888: cogl_format = COGL_PIXEL_FORMAT_BGRA_8888_PRE; - cogl_internal_format = COGL_PIXEL_FORMAT_ANY; gbm_format = GBM_FORMAT_ARGB8888; break; case WL_SHM_FORMAT_XRGB8888: cogl_format = COGL_PIXEL_FORMAT_BGRA_8888; - cogl_internal_format = COGL_PIXEL_FORMAT_BGR_888; gbm_format = GBM_FORMAT_XRGB8888; break; #endif default: g_warn_if_reached (); cogl_format = COGL_PIXEL_FORMAT_ARGB_8888; - cogl_internal_format = COGL_PIXEL_FORMAT_ANY; gbm_format = GBM_FORMAT_ARGB8888; } self->texture = cogl_texture_2d_new_from_data (cogl_context, width, height, cogl_format, - cogl_internal_format, rowstride, wl_shm_buffer_get_data (shm_buffer), NULL); From 788bd59857a6b2d56738d01e1d66e270f5f0c80f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Thu, 16 Jan 2014 10:10:21 -0500 Subject: [PATCH 388/889] cursor-tracker: Rely on gbm_bo_imports()'s buffer validation cogl_texture_get_format() has been deprecated, so rather than using it to figure out beforehand whether the buffer format is supported, just rely on the import failing if it isn't. https://bugzilla.gnome.org/show_bug.cgi?id=722347 --- src/core/meta-cursor-tracker.c | 45 +++------------------------------- 1 file changed, 4 insertions(+), 41 deletions(-) diff --git a/src/core/meta-cursor-tracker.c b/src/core/meta-cursor-tracker.c index b3e1b5907..a7842f682 100644 --- a/src/core/meta-cursor-tracker.c +++ b/src/core/meta-cursor-tracker.c @@ -468,47 +468,10 @@ meta_cursor_reference_from_buffer (MetaCursorTracker *tracker, if (tracker->gbm) { - cogl_format = cogl_texture_get_format (COGL_TEXTURE (self->texture)); - switch (cogl_format) - { -#if G_BYTE_ORDER == G_LITTLE_ENDIAN - case COGL_PIXEL_FORMAT_ARGB_8888_PRE: - case COGL_PIXEL_FORMAT_ARGB_8888: - gbm_format = GBM_FORMAT_BGRA8888; - break; - case COGL_PIXEL_FORMAT_BGRA_8888_PRE: - case COGL_PIXEL_FORMAT_BGRA_8888: - break; - case COGL_PIXEL_FORMAT_RGB_888: - break; -#else - case COGL_PIXEL_FORMAT_ARGB_8888_PRE: - case COGL_PIXEL_FORMAT_ARGB_8888: - gbm_format = GBM_FORMAT_ARGB8888; - break; - case COGL_PIXEL_FORMAT_BGRA_8888_PRE: - case COGL_PIXEL_FORMAT_BGRA_8888: - gbm_format = GBM_FORMAT_BGRA8888; - break; - case COGL_PIXEL_FORMAT_RGB_888: - gbm_format = GBM_FORMAT_RGB888; - break; -#endif - default: - meta_warning ("Unknown cogl format %d\n", cogl_format); - return self; - } - - if (gbm_device_is_format_supported (tracker->gbm, gbm_format, - GBM_BO_USE_CURSOR_64X64)) - { - self->bo = gbm_bo_import (tracker->gbm, GBM_BO_IMPORT_WL_BUFFER, - buffer, GBM_BO_USE_CURSOR_64X64); - if (!self->bo) - meta_warning ("Importing HW cursor from wl_buffer failed\n"); - } - else - meta_warning ("HW cursor for format %d not supported\n", gbm_format); + self->bo = gbm_bo_import (tracker->gbm, GBM_BO_IMPORT_WL_BUFFER, + buffer, GBM_BO_USE_CURSOR_64X64); + if (!self->bo) + meta_warning ("Importing HW cursor from wl_buffer failed\n"); } } From 1d61a0f9b583b7eabc4440693d421d2a384b760c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 15 Jan 2014 23:00:20 +0100 Subject: [PATCH 389/889] Bump version to 3.11.4 Update NEWS. --- NEWS | 12 ++++++++++++ configure.ac | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index cda6cf287..ed12bcf22 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,15 @@ +3.11.4 +====== +* Don't leave focus on windows that are being unmanaged [Owen; #711618] +* Reduce server grabs [Daniel Drake; #721345, #721709] +* Improve heuristic to determine display output name [Cosimo Cecchi; #721674] +* Atomically unmaximize both directions [Jasper; #722108] +* Misc bug fixes [Debarshi, Andika, Florian; #721517, #721674, #722347] + +Contributors: + Cosimo Cecchi, Daniel Drake, Florian Müllner, Debarshi Ray, Jasper St. Pierre, + Andika Triwidada, Owen W. Taylor + 3.11.3 ====== * Fix focus issues with external OSKs[Jasper; #715030] diff --git a/configure.ac b/configure.ac index 87aff64d6..83562439e 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ AC_CONFIG_MACRO_DIR([m4]) m4_define([mutter_major_version], [3]) m4_define([mutter_minor_version], [11]) -m4_define([mutter_micro_version], [3]) +m4_define([mutter_micro_version], [4]) m4_define([mutter_version], [mutter_major_version.mutter_minor_version.mutter_micro_version]) From be698b597b53527c3d873b293c9c12113bfb582d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Sun, 12 Jan 2014 19:36:28 +0100 Subject: [PATCH 390/889] shaped-texture: Use a double when calculating clip MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For x defined below, x == -INT32_MAX assuming that the arithmetic expression actually uses the fpu. float f = 1.0f; int32_t x = INT32_MAX * f; This would result in the calculated clip width/height to be -INT_MAX if the damage width/height is INT_MAX. To solve this, use a double variable instead. Signed-off-by: Jonas Ådahl https://bugzilla.gnome.org/show_bug.cgi?id=705502 --- src/compositor/meta-shaped-texture.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c index b37770e4e..293958438 100644 --- a/src/compositor/meta-shaped-texture.c +++ b/src/compositor/meta-shaped-texture.c @@ -605,8 +605,8 @@ get_clip (MetaShapedTexture *stex, ClutterActor *self = CLUTTER_ACTOR (stex); MetaShapedTexturePrivate *priv; ClutterActorBox allocation; - float scale_x; - float scale_y; + double scale_x; + double scale_y; /* NB: clutter_actor_queue_redraw_with_clip expects a box in the actor's * coordinate space so we need to convert from surface coordinates to From 8cb9cfb7b8e3493687c55cbe37dbb6da89808280 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 16 Jan 2014 13:40:41 -0500 Subject: [PATCH 391/889] Revert "meta-weston-launch: Call VT_ACTIVATE ourselves" This reverts commit ebe6e3180ed842445c5145c6947aae9c3fa270a5. This is wrong, as mutter's controlling TTY may not be the same as the active VT, and in fact won't be in the case of systemd spawning us. The "correct" API for this is to use David Herrmann's "Session Positions" system to switch to another VT: http://lists.freedesktop.org/archives/systemd-devel/2013-December/014956.html --- src/core/keybindings.c | 39 ++++++++++++++++-------------- src/wayland/meta-wayland-private.h | 1 + src/wayland/meta-wayland.c | 6 +++++ src/wayland/meta-weston-launch.c | 14 +++++++++++ src/wayland/meta-weston-launch.h | 4 +++ src/wayland/weston-launch.c | 37 ++++++++++++++++++++++++++++ src/wayland/weston-launch.h | 3 ++- 7 files changed, 85 insertions(+), 19 deletions(-) diff --git a/src/core/keybindings.c b/src/core/keybindings.c index 727a63a8f..01788c2cb 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -54,9 +54,6 @@ #ifdef HAVE_WAYLAND #include "meta-wayland-private.h" -#include -#include -#include #endif #define SCHEMA_COMMON_KEYBINDINGS "org.gnome.desktop.wm.keybindings" @@ -4084,18 +4081,6 @@ handle_set_spew_mark (MetaDisplay *display, } #ifdef HAVE_WAYLAND -static gboolean -activate_vt (int vt) -{ - int tty, reply; - - tty = open ("/dev/tty", O_RDWR | O_NOCTTY | O_CLOEXEC); - reply = ioctl (tty, VT_ACTIVATE, vt); - close (tty); - - return (reply == 0); -} - static void handle_switch_vt (MetaDisplay *display, MetaScreen *screen, @@ -4104,10 +4089,28 @@ handle_switch_vt (MetaDisplay *display, MetaKeyBinding *binding, gpointer dummy) { - gint vt = binding->handler->data; + gint vt = binding->handler->data; + MetaWaylandCompositor *compositor; + MetaLauncher *launcher; - if (!activate_vt (vt)) - g_warning ("Failed to switch VT"); + compositor = meta_wayland_compositor_get_default (); + launcher = meta_wayland_compositor_get_launcher (compositor); + + if (launcher) + { + GError *error; + + error = NULL; + if (!meta_launcher_activate_vt (launcher, vt, &error)) + { + g_warning ("Failed to switch VT: %s", error->message); + g_error_free (error); + } + } + else + { + g_debug ("Ignoring VT switch keybinding, not running as VT manager"); + } } #endif diff --git a/src/wayland/meta-wayland-private.h b/src/wayland/meta-wayland-private.h index 26cd88ee0..6dc9620f0 100644 --- a/src/wayland/meta-wayland-private.h +++ b/src/wayland/meta-wayland-private.h @@ -99,6 +99,7 @@ void meta_wayland_compositor_set_input_focus (MetaWaylandComp gboolean meta_wayland_compositor_handle_event (MetaWaylandCompositor *compositor, const ClutterEvent *event); +MetaLauncher *meta_wayland_compositor_get_launcher (MetaWaylandCompositor *compositor); gboolean meta_wayland_compositor_is_native (MetaWaylandCompositor *compositor); MetaWaylandBuffer * meta_wayland_buffer_from_resource (struct wl_resource *resource); diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index 84b51edfe..1db2fceb4 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -764,6 +764,12 @@ meta_wayland_finalize (void) meta_launcher_free (compositor->launcher); } +MetaLauncher * +meta_wayland_compositor_get_launcher (MetaWaylandCompositor *compositor) +{ + return compositor->launcher; +} + gboolean meta_wayland_compositor_is_native (MetaWaylandCompositor *compositor) { diff --git a/src/wayland/meta-weston-launch.c b/src/wayland/meta-weston-launch.c index c86185a88..f24221d1c 100644 --- a/src/wayland/meta-weston-launch.c +++ b/src/wayland/meta-weston-launch.c @@ -385,3 +385,17 @@ meta_launcher_free (MetaLauncher *launcher) g_slice_free (MetaLauncher, launcher); } + +gboolean +meta_launcher_activate_vt (MetaLauncher *launcher, + int vt, + GError **error) +{ + struct weston_launcher_activate_vt message; + + message.header.opcode = WESTON_LAUNCHER_ACTIVATE_VT; + message.vt = vt; + + return send_message_to_wl (launcher, &message, sizeof (message), NULL, NULL, error); +} + diff --git a/src/wayland/meta-weston-launch.h b/src/wayland/meta-weston-launch.h index 498edbb7f..96bc13bf7 100644 --- a/src/wayland/meta-weston-launch.h +++ b/src/wayland/meta-weston-launch.h @@ -28,6 +28,10 @@ typedef struct _MetaLauncher MetaLauncher; MetaLauncher *meta_launcher_new (void); void meta_launcher_free (MetaLauncher *self); +gboolean meta_launcher_activate_vt (MetaLauncher *self, + int number, + GError **error); + gboolean meta_launcher_set_drm_fd (MetaLauncher *self, int drm_fd, GError **error); diff --git a/src/wayland/weston-launch.c b/src/wayland/weston-launch.c index cbd7c9e67..773eea4bd 100644 --- a/src/wayland/weston-launch.c +++ b/src/wayland/weston-launch.c @@ -269,6 +269,40 @@ out: return 0; } +static int +handle_activate_vt(struct weston_launch *wl, struct msghdr *msg, ssize_t len) +{ + struct weston_launcher_reply reply; + struct weston_launcher_activate_vt *message; + + reply.header.opcode = WESTON_LAUNCHER_ACTIVATE_VT; + reply.ret = -1; + + if (len != sizeof(*message)) { + error(0, 0, "missing value in activate_vt request"); + goto out; + } + + message = msg->msg_iov->iov_base; + + reply.ret = ioctl(wl->tty, VT_ACTIVATE, message->vt); + if (reply.ret < 0) + reply.ret = -errno; + + if (wl->verbose) + fprintf(stderr, "mutter-launch: activate VT, ret: %d\n", reply.ret); + +out: + do { + len = send(wl->sock[0], &reply, sizeof reply, 0); + } while (len < 0 && errno == EINTR); + if (len < 0) + return -1; + + return 0; +} + + static int handle_open(struct weston_launch *wl, struct msghdr *msg, ssize_t len) { @@ -385,6 +419,9 @@ handle_socket_msg(struct weston_launch *wl) case WESTON_LAUNCHER_CONFIRM_VT_SWITCH: ret = handle_confirm_vt_switch(wl, &msg, len); break; + case WESTON_LAUNCHER_ACTIVATE_VT: + ret = handle_activate_vt(wl, &msg, len); + break; } return ret; diff --git a/src/wayland/weston-launch.h b/src/wayland/weston-launch.h index 63e28098c..74e6c3be6 100644 --- a/src/wayland/weston-launch.h +++ b/src/wayland/weston-launch.h @@ -32,7 +32,8 @@ enum weston_launcher_message_type { enum weston_launcher_opcode { WESTON_LAUNCHER_OPEN = (1 << 1 | WESTON_LAUNCHER_REQUEST), WESTON_LAUNCHER_DRM_SET_FD = (2 << 1 | WESTON_LAUNCHER_REQUEST), - WESTON_LAUNCHER_CONFIRM_VT_SWITCH = (3 << 1 | WESTON_LAUNCHER_REQUEST), + WESTON_LAUNCHER_ACTIVATE_VT = (3 << 1 | WESTON_LAUNCHER_REQUEST), + WESTON_LAUNCHER_CONFIRM_VT_SWITCH = (4 << 1 | WESTON_LAUNCHER_REQUEST), }; enum weston_launcher_server_opcode { From 56207ddb6ac6c188c676d9233c68926ea94bff72 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 6 Dec 2013 12:28:52 -0500 Subject: [PATCH 392/889] window-actor: Never unredirect when under Wayland https://bugzilla.gnome.org/show_bug.cgi?id=720631 --- src/compositor/meta-window-actor.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index f45bd53ad..e7a922025 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -1321,6 +1321,9 @@ meta_window_actor_should_unredirect (MetaWindowActor *self) MetaWindow *metaWindow = meta_window_actor_get_meta_window (self); MetaWindowActorPrivate *priv = self->priv; + if (meta_is_wayland_compositor ()) + return FALSE; + if (meta_window_requested_dont_bypass_compositor (metaWindow)) return FALSE; @@ -1342,7 +1345,7 @@ meta_window_actor_should_unredirect (MetaWindowActor *self) if (meta_window_is_override_redirect (metaWindow)) return TRUE; - if (!meta_is_wayland_compositor () && priv->does_full_damage) + if (priv->does_full_damage) return TRUE; return FALSE; From 8e6f8087e8371204a61e1500faeb47cfbb5db8a4 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 21 Jan 2014 15:51:46 -0500 Subject: [PATCH 393/889] Always map the client and frame windows Traditionally, WMs unmap windows when minimizing them, and map them when restoring them or wanting to show them for other reasons, like upon creation. However, as metacity morphed into mutter, we optionally chose to keep windows mapped for the lifetime of the window under the user option "live-window-previews", which makes the code keep windows mapped so it can show window preview for minimized windows in other places, like Alt-Tab and Expose. I removed this preference two years ago mechanically, by removing all the if statements, but never went through and cleaned up the code so that windows are simply mapped for the lifetime of the window -- the "architecture" of the old code that maps and unmaps on show/hide was still there. Remove this now. The one case we still need to be careful of is shaded windows, in which we do still unmap the client window. Theoretically, we might want to show previews of shaded windows in the overview and Alt-Tab, so we remove the complex unmap tracking for this later. --- src/compositor/meta-window-actor.c | 7 +- src/core/display.c | 2 +- src/core/frame.c | 3 +- src/core/frame.h | 1 - src/core/window.c | 200 +++++++---------------------- src/meta/window.h | 2 - 6 files changed, 56 insertions(+), 159 deletions(-) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index e7a922025..8fcb7ea0a 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -1206,7 +1206,7 @@ meta_window_actor_after_effects (MetaWindowActor *self) if (!meta_is_wayland_compositor ()) { - if (!meta_window_is_mapped (priv->window)) + if (!priv->mapped) meta_window_actor_detach_x11_pixmap (self); if (priv->needs_pixmap) @@ -1629,7 +1629,10 @@ meta_window_actor_new (MetaWindow *window) NULL); priv = self->priv; - priv->mapped = meta_window_toplevel_is_mapped (priv->window); + + /* We know that when the compositor first adds our window, it will + * be before the toplevel window is mapped. */ + priv->mapped = FALSE; if (!meta_is_wayland_compositor ()) { diff --git a/src/core/display.c b/src/core/display.c index 8a98cf5ab..a11836c57 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -2777,7 +2777,7 @@ handle_other_xevent (MetaDisplay *display, if (display->grab_op != META_GRAB_OP_NONE && display->grab_window == window && - ((window->frame == NULL) || !window->frame->mapped)) + window->frame == NULL) meta_display_end_grab_op (display, timestamp); if (!frame_was_receiver) diff --git a/src/core/frame.c b/src/core/frame.c index 5fa7bee17..e54e86210 100644 --- a/src/core/frame.c +++ b/src/core/frame.c @@ -62,7 +62,6 @@ meta_window_ensure_frame (MetaWindow *window) frame->right_width = 0; frame->current_cursor = 0; - frame->mapped = FALSE; frame->is_flashing = FALSE; frame->borders_cached = FALSE; @@ -157,6 +156,8 @@ meta_window_ensure_frame (MetaWindow *window) /* Move keybindings to frame instead of window */ meta_window_grab_keys (window); + + meta_ui_map_frame (frame->window->screen->ui, frame->xwindow); } void diff --git a/src/core/frame.h b/src/core/frame.h index 0f1ebea4f..8ac1c261e 100644 --- a/src/core/frame.h +++ b/src/core/frame.h @@ -47,7 +47,6 @@ struct _MetaFrame int right_width; int bottom_height; - guint mapped : 1; guint need_reapply_frame_shape : 1; guint is_flashing : 1; /* used by the visual bell flash */ guint borders_cached : 1; diff --git a/src/core/window.c b/src/core/window.c index b4a845d6a..0ac94fa93 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -792,6 +792,41 @@ meta_window_should_attach_to_parent (MetaWindow *window) } } +static gboolean +client_window_should_be_mapped (MetaWindow *window) +{ + return !window->shaded; +} + +static void +sync_client_window_mapped (MetaWindow *window) +{ + gboolean should_be_mapped = client_window_should_be_mapped (window); + + if (window->mapped == should_be_mapped) + return; + + window->mapped = should_be_mapped; + + meta_error_trap_push (window->display); + if (should_be_mapped) + { + XMapWindow (window->display->xdisplay, window->xwindow); + + if (window->display->compositor) + meta_compositor_window_mapped (window->display->compositor, window); + } + else + { + XUnmapWindow (window->display->xdisplay, window->xwindow); + window->unmaps_pending ++; + + if (window->display->compositor) + meta_compositor_window_unmapped (window->display->compositor, window); + } + meta_error_trap_pop (window->display); +} + static MetaWindow* meta_window_new_shared (MetaDisplay *display, MetaScreen *screen, @@ -1303,6 +1338,8 @@ meta_window_new_shared (MetaDisplay *display, /* disable show desktop mode unless we're a desktop component */ maybe_leave_show_desktop_mode (window); + sync_client_window_mapped (window); + meta_window_queue (window, META_QUEUE_CALC_SHOWING); /* See bug 303284; a transient of the given window can already exist, in which * case we think it should probably be shown. @@ -2346,6 +2383,8 @@ implement_showing (MetaWindow *window, meta_verbose ("Implement showing = %d for window %s\n", showing, window->desc); + sync_client_window_mapped (window); + if (!showing) { /* When we manage a new window, we normally delay placing it @@ -2934,94 +2973,6 @@ window_would_be_covered (const MetaWindow *newbie) return FALSE; /* none found */ } -static gboolean -map_frame (MetaWindow *window) -{ - if (window->frame && !window->frame->mapped) - { - meta_topic (META_DEBUG_WINDOW_STATE, - "Frame actually needs map\n"); - window->frame->mapped = TRUE; - meta_ui_map_frame (window->screen->ui, window->frame->xwindow); - return TRUE; - } - else - return FALSE; -} - -static gboolean -map_client_window (MetaWindow *window) -{ - if (!window->mapped) - { - meta_topic (META_DEBUG_WINDOW_STATE, - "%s actually needs map\n", window->desc); - window->mapped = TRUE; - meta_error_trap_push (window->display); - XMapWindow (window->display->xdisplay, window->xwindow); - meta_error_trap_pop (window->display); - - return TRUE; - } - else - return FALSE; -} - -static gboolean -unmap_client_window (MetaWindow *window, - const char *reason) -{ - if (window->mapped) - { - meta_topic (META_DEBUG_WINDOW_STATE, - "%s actually needs unmap%s\n", - window->desc, reason); - meta_topic (META_DEBUG_WINDOW_STATE, - "Incrementing unmaps_pending on %s%s\n", - window->desc, reason); - window->mapped = FALSE; - window->unmaps_pending += 1; - meta_error_trap_push (window->display); - XUnmapWindow (window->display->xdisplay, window->xwindow); - meta_error_trap_pop (window->display); - - return TRUE; - } - else - return FALSE; -} - -/** - * meta_window_is_mapped: - * @window: a #MetaWindow - * - * Determines whether the X window for the MetaWindow is mapped. - */ -gboolean -meta_window_is_mapped (MetaWindow *window) -{ - return window->mapped; -} - -/** - * meta_window_toplevel_is_mapped: - * @window: a #MetaWindow - * - * Determines whether the toplevel X window for the MetaWindow is - * mapped. (The frame window is mapped even without the client window - * when a window is shaded.) - * - * Return Value: %TRUE if the toplevel is mapped. - */ -gboolean -meta_window_toplevel_is_mapped (MetaWindow *window) -{ - /* The frame is mapped but not the client window when the window - * is shaded. - */ - return window->mapped || (window->frame && window->frame->mapped); -} - static void meta_window_force_placement (MetaWindow *window) { @@ -3060,16 +3011,12 @@ meta_window_show (MetaWindow *window) gboolean place_on_top_on_map; gboolean needs_stacking_adjustment; MetaWindow *focus_window; - gboolean toplevel_was_mapped; - gboolean toplevel_now_mapped; gboolean notify_demands_attention = FALSE; meta_topic (META_DEBUG_WINDOW_STATE, "Showing window %s, shaded: %d iconic: %d placed: %d\n", window->desc, window->shaded, window->iconic, window->placed); - toplevel_was_mapped = meta_window_toplevel_is_mapped (window); - focus_window = window->display->focus_window; /* May be NULL! */ did_show = FALSE; window_state_on_map (window, &takes_focus_on_map, &place_on_top_on_map); @@ -3196,46 +3143,18 @@ meta_window_show (MetaWindow *window) } } - /* Shaded means the frame is mapped but the window is not */ - - if (map_frame (window)) - did_show = TRUE; - - if (window->shaded) + if (window->hidden) { - unmap_client_window (window, " (shading)"); - - if (!window->iconic) - { - window->iconic = TRUE; - set_wm_state (window, IconicState); - } - } - else - { - if (map_client_window (window)) - did_show = TRUE; - - if (window->hidden) - { - meta_stack_freeze (window->screen->stack); - window->hidden = FALSE; - meta_stack_thaw (window->screen->stack); - did_show = TRUE; - } - - if (window->iconic) - { - window->iconic = FALSE; - set_wm_state (window, NormalState); - } + meta_stack_freeze (window->screen->stack); + window->hidden = FALSE; + meta_stack_thaw (window->screen->stack); + did_show = TRUE; } - toplevel_now_mapped = meta_window_toplevel_is_mapped (window); - if (toplevel_now_mapped != toplevel_was_mapped) + if (window->iconic) { - if (window->display->compositor) - meta_compositor_window_mapped (window->display->compositor, window); + window->iconic = FALSE; + set_wm_state (window, NormalState); } if (!window->visible_to_compositor) @@ -3327,14 +3246,10 @@ static void meta_window_hide (MetaWindow *window) { gboolean did_hide; - gboolean toplevel_was_mapped; - gboolean toplevel_now_mapped; meta_topic (META_DEBUG_WINDOW_STATE, "Hiding window %s\n", window->desc); - toplevel_was_mapped = meta_window_toplevel_is_mapped (window); - if (window->visible_to_compositor) { window->visible_to_compositor = FALSE; @@ -3362,12 +3277,6 @@ meta_window_hide (MetaWindow *window) did_hide = FALSE; - /* If this is the first time that we've calculating the showing - * state of the window, the frame and client window might not - * yet be mapped, so we need to map them now */ - map_frame (window); - map_client_window (window); - if (!window->hidden) { meta_stack_freeze (window->screen->stack); @@ -3383,19 +3292,6 @@ meta_window_hide (MetaWindow *window) set_wm_state (window, IconicState); } - toplevel_now_mapped = meta_window_toplevel_is_mapped (window); - if (toplevel_now_mapped != toplevel_was_mapped) - { - if (window->display->compositor) - { - /* As above, we may be *mapping* live hidden windows */ - if (toplevel_now_mapped) - meta_compositor_window_mapped (window->display->compositor, window); - else - meta_compositor_window_unmapped (window->display->compositor, window); - } - } - set_net_wm_state (window); if (did_hide && window->struts) @@ -8217,7 +8113,7 @@ redraw_icon (MetaWindow *window) /* We could probably be smart and just redraw the icon here, * instead of the whole frame. */ - if (window->frame && (window->mapped || window->frame->mapped)) + if (window->frame) meta_ui_queue_frame_draw (window->screen->ui, window->frame->xwindow); } diff --git a/src/meta/window.h b/src/meta/window.h index ff2d037d3..430dc6bd9 100644 --- a/src/meta/window.h +++ b/src/meta/window.h @@ -189,8 +189,6 @@ gboolean meta_window_requested_bypass_compositor (MetaWindow *window); gboolean meta_window_requested_dont_bypass_compositor (MetaWindow *window); gint *meta_window_get_all_monitors (MetaWindow *window, gsize *length); -gboolean meta_window_is_mapped (MetaWindow *window); -gboolean meta_window_toplevel_is_mapped (MetaWindow *window); gboolean meta_window_get_icon_geometry (MetaWindow *window, MetaRectangle *rect); void meta_window_set_icon_geometry (MetaWindow *window, From bfc906cbc4ed83c7926527c2205c0ae3a2174656 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 21 Jan 2014 15:58:12 -0500 Subject: [PATCH 394/889] compositor: Remove meta_compositor_window_[un]mapped We no longer unmap the toplevel windows during normal operation. The toplevel state is tied to the window's lifetime. Call meta_compositor_add_window / meta_compositor_remove_window instead... --- doc/reference/meta-sections.txt | 2 - src/compositor/compositor.c | 33 ---------------- src/compositor/meta-window-actor.c | 61 ++---------------------------- src/core/window.c | 25 +++++------- src/meta/compositor.h | 13 ++----- 5 files changed, 16 insertions(+), 118 deletions(-) diff --git a/doc/reference/meta-sections.txt b/doc/reference/meta-sections.txt index 7aa893177..22d435034 100644 --- a/doc/reference/meta-sections.txt +++ b/doc/reference/meta-sections.txt @@ -96,8 +96,6 @@ meta_compositor_hide_window meta_compositor_switch_workspace meta_compositor_maximize_window meta_compositor_unmaximize_window -meta_compositor_window_mapped -meta_compositor_window_unmapped meta_compositor_sync_window_geometry meta_compositor_set_updates_frozen meta_compositor_queue_frame_drawn diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index d2598f48b..10f925f8b 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -42,15 +42,6 @@ * the call, so it may be necessary to readjust the display based on the * old_rect to start the animation. * - * meta_compositor_window_mapped() and meta_compositor_window_unmapped() are - * notifications when the toplevel window (frame or client window) is mapped or - * unmapped. That is, when the result of meta_window_toplevel_is_mapped() - * changes. The main use of this is to drop resources when a window is unmapped. - * A window will always be mapped before meta_compositor_show_window() - * is called and will not be unmapped until after meta_compositor_hide_window() - * is called. If the live_hidden_windows preference is set, windows will never - * be unmapped. - * * # Containers # * * There's two containers in the stage that are used to place window actors, here @@ -1402,30 +1393,6 @@ meta_compositor_sync_stack (MetaCompositor *compositor, sync_actor_stacking (info); } -void -meta_compositor_window_mapped (MetaCompositor *compositor, - MetaWindow *window) -{ - MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - DEBUG_TRACE ("meta_compositor_window_mapped\n"); - if (!window_actor) - return; - - meta_window_actor_mapped (window_actor); -} - -void -meta_compositor_window_unmapped (MetaCompositor *compositor, - MetaWindow *window) -{ - MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - DEBUG_TRACE ("meta_compositor_window_unmapped\n"); - if (!window_actor) - return; - - meta_window_actor_unmapped (window_actor); -} - void meta_compositor_sync_window_geometry (MetaCompositor *compositor, MetaWindow *window, diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 8fcb7ea0a..e9cecfc2c 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -106,7 +106,6 @@ struct _MetaWindowActorPrivate Damage damage; /* Not used in wayland compositor mode */ guint visible : 1; - guint mapped : 1; guint argb32 : 1; guint disposed : 1; guint redecorating : 1; @@ -984,7 +983,7 @@ meta_window_actor_damage_all (MetaWindowActor *self) if (!priv->needs_damage_all) return; - if (!priv->mapped || priv->needs_pixmap) + if (priv->needs_pixmap) return; unobscured_region = @@ -1074,7 +1073,7 @@ meta_window_actor_queue_frame_drawn (MetaWindowActor *self, { queue_send_frame_messages_timeout (self); } - else if (priv->mapped && (!meta_is_wayland_compositor () || !priv->needs_pixmap)) + else { const cairo_rectangle_int_t clip = { 0, 0, 1, 1 }; clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (priv->surface), &clip); @@ -1106,9 +1105,6 @@ meta_window_actor_queue_create_x11_pixmap (MetaWindowActor *self) priv->needs_pixmap = TRUE; - if (!priv->mapped) - return; - if (is_frozen (self)) return; @@ -1206,9 +1202,6 @@ meta_window_actor_after_effects (MetaWindowActor *self) if (!meta_is_wayland_compositor ()) { - if (!priv->mapped) - meta_window_actor_detach_x11_pixmap (self); - if (priv->needs_pixmap) clutter_actor_queue_redraw (CLUTTER_ACTOR (priv->surface)); } @@ -1630,18 +1623,11 @@ meta_window_actor_new (MetaWindow *window) priv = self->priv; - /* We know that when the compositor first adds our window, it will - * be before the toplevel window is mapped. */ - priv->mapped = FALSE; - if (!meta_is_wayland_compositor ()) { priv->last_width = -1; priv->last_height = -1; - if (priv->mapped) - meta_window_actor_queue_create_x11_pixmap (self); - meta_window_actor_set_updates_frozen (self, meta_window_updates_are_frozen (priv->window)); @@ -1676,38 +1662,6 @@ meta_window_actor_new (MetaWindow *window) return self; } -void -meta_window_actor_mapped (MetaWindowActor *self) -{ - MetaWindowActorPrivate *priv = self->priv; - - g_return_if_fail (!priv->mapped); - - priv->mapped = TRUE; - - if (!meta_is_wayland_compositor ()) - meta_window_actor_queue_create_x11_pixmap (self); -} - -void -meta_window_actor_unmapped (MetaWindowActor *self) -{ - MetaWindowActorPrivate *priv = self->priv; - - g_return_if_fail (priv->mapped); - - priv->mapped = FALSE; - - if (meta_window_actor_effect_in_progress (self)) - return; - - if (!meta_is_wayland_compositor ()) - { - meta_window_actor_detach_x11_pixmap (self); - priv->needs_pixmap = FALSE; - } -} - #if 0 /* Print out a region; useful for debugging */ static void @@ -1860,9 +1814,6 @@ check_needs_x11_pixmap (MetaWindowActor *self) if (!priv->needs_pixmap) return; - if (!priv->mapped) - return; - if (xwindow == meta_screen_get_xroot (screen) || xwindow == clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage))) return; @@ -1936,9 +1887,6 @@ check_needs_shadow (MetaWindowActor *self) gboolean should_have_shadow; gboolean appears_focused; - if (!priv->mapped) - return; - /* Calling meta_window_actor_has_shadow() here at every pre-paint is cheap * and avoids the need to explicitly handle window type changes, which * we would do if tried to keep track of when we might be adding or removing @@ -2043,7 +1991,7 @@ meta_window_actor_process_x11_damage (MetaWindowActor *self, return; } - if (!priv->mapped || priv->needs_pixmap) + if (priv->needs_pixmap) return; unobscured_region = @@ -2322,9 +2270,6 @@ check_needs_reshape (MetaWindowActor *self) MetaFrameBorders borders; cairo_rectangle_int_t client_area; - if (!priv->mapped) - return; - if (!priv->needs_reshape) return; diff --git a/src/core/window.c b/src/core/window.c index 0ac94fa93..5ac4b195a 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -812,17 +812,11 @@ sync_client_window_mapped (MetaWindow *window) if (should_be_mapped) { XMapWindow (window->display->xdisplay, window->xwindow); - - if (window->display->compositor) - meta_compositor_window_mapped (window->display->compositor, window); } else { XUnmapWindow (window->display->xdisplay, window->xwindow); window->unmaps_pending ++; - - if (window->display->compositor) - meta_compositor_window_unmapped (window->display->compositor, window); } meta_error_trap_pop (window->display); } @@ -1322,9 +1316,6 @@ meta_window_new_shared (MetaDisplay *display, set_net_wm_state (window); } - if (screen->display->compositor) - meta_compositor_add_window (screen->display->compositor, window); - /* Sync stack changes */ meta_stack_thaw (window->screen->stack); @@ -1797,10 +1788,13 @@ meta_window_unmanage (MetaWindow *window, if (window->display->compositor) { if (window->visible_to_compositor) - meta_compositor_hide_window (window->display->compositor, window, - META_COMP_EFFECT_DESTROY); + { + meta_compositor_hide_window (window->display->compositor, window, + META_COMP_EFFECT_DESTROY); - meta_compositor_remove_window (window->display->compositor, window); + /* XXX - support destroy effects better */ + meta_compositor_remove_window (window->display->compositor, window); + } } if (window->display->window_with_menu == window) @@ -3177,8 +3171,8 @@ meta_window_show (MetaWindow *window) break; } - meta_compositor_show_window (window->display->compositor, - window, effect); + meta_compositor_add_window (window->display->compositor, window); + meta_compositor_show_window (window->display->compositor, window, effect); } } @@ -3270,8 +3264,7 @@ meta_window_hide (MetaWindow *window) break; } - meta_compositor_hide_window (window->display->compositor, - window, effect); + meta_compositor_hide_window (window->display->compositor, window, effect); } } diff --git a/src/meta/compositor.h b/src/meta/compositor.h index 42ff0dd8e..45c8b09dd 100644 --- a/src/meta/compositor.h +++ b/src/meta/compositor.h @@ -75,11 +75,10 @@ gboolean meta_compositor_filter_keybinding (MetaCompositor *compositor, MetaScreen *screen, MetaKeyBinding *binding); -void meta_compositor_add_window (MetaCompositor *compositor, - MetaWindow *window); -void meta_compositor_remove_window (MetaCompositor *compositor, - MetaWindow *window); - +void meta_compositor_add_window (MetaCompositor *compositor, + MetaWindow *window); +void meta_compositor_remove_window (MetaCompositor *compositor, + MetaWindow *window); void meta_compositor_show_window (MetaCompositor *compositor, MetaWindow *window, MetaCompEffect effect); @@ -101,10 +100,6 @@ void meta_compositor_unmaximize_window (MetaCompositor *compositor, MetaRectangle *old_rect, MetaRectangle *new_rect); -void meta_compositor_window_mapped (MetaCompositor *compositor, - MetaWindow *window); -void meta_compositor_window_unmapped (MetaCompositor *compositor, - MetaWindow *window); void meta_compositor_sync_window_geometry (MetaCompositor *compositor, MetaWindow *window, gboolean did_placement); From 0e5f365d5546247e07b67286ecf295865c72a7c9 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 16 Jan 2014 15:27:58 -0500 Subject: [PATCH 395/889] compositor: Remove pending_input_region Ever since the change to create the output window synchronously at startup, there hasn't been any time where somebody could set a stage region the output window was ready, so this was effectively dead code. --- src/compositor/compositor-private.h | 3 -- src/compositor/compositor.c | 77 ++++++----------------------- 2 files changed, 14 insertions(+), 66 deletions(-) diff --git a/src/compositor/compositor-private.h b/src/compositor/compositor-private.h index 2e8d85fd9..f3b7afb22 100644 --- a/src/compositor/compositor-private.h +++ b/src/compositor/compositor-private.h @@ -49,9 +49,6 @@ struct _MetaCompScreen guint disable_unredirect_count; MetaWindowActor *unredirected_window; - /* Before we create the output window */ - XserverRegion pending_input_region; - gint switch_workspace_in_progress; MetaPluginManager *plugin_mgr; diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 10f925f8b..14512d648 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -274,25 +274,6 @@ meta_get_window_actors (MetaScreen *screen) return info->windows; } -static void -do_set_stage_input_region (MetaScreen *screen, - XserverRegion region) -{ - MetaCompScreen *info = meta_screen_get_compositor_data (screen); - MetaDisplay *display = meta_screen_get_display (screen); - Display *xdpy = meta_display_get_xdisplay (display); - Window xstage = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage)); - - XFixesSetWindowShapeRegion (xdpy, xstage, ShapeInput, 0, 0, region); - - /* It's generally a good heuristic that when a crossing event is generated because - * we reshape the overlay, we don't want it to affect focus-follows-mouse focus - - * it's not the user doing something, it's the environment changing under the user. - */ - meta_display_add_ignored_crossing_serial (display, XNextRequest (xdpy)); - XFixesSetWindowShapeRegion (xdpy, info->output, ShapeInput, 0, 0, region); -} - void meta_set_stage_input_region (MetaScreen *screen, XserverRegion region) @@ -304,29 +285,19 @@ meta_set_stage_input_region (MetaScreen *screen, */ if (!meta_is_wayland_compositor ()) { - MetaCompScreen *info = meta_screen_get_compositor_data (screen); - MetaDisplay *display = meta_screen_get_display (screen); - Display *xdpy = meta_display_get_xdisplay (display); + MetaCompScreen *info = meta_screen_get_compositor_data (screen); + MetaDisplay *display = meta_screen_get_display (screen); + Display *xdpy = meta_display_get_xdisplay (display); + Window xstage = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage)); - if (info->stage && info->output) - { - do_set_stage_input_region (screen, region); - } - else - { - /* Reset info->pending_input_region if one existed before and set the new - * one to use it later. */ - if (info->pending_input_region) - { - XFixesDestroyRegion (xdpy, info->pending_input_region); - info->pending_input_region = None; - } - if (region != None) - { - info->pending_input_region = XFixesCreateRegion (xdpy, NULL, 0); - XFixesCopyRegion (xdpy, info->pending_input_region, region); - } - } + XFixesSetWindowShapeRegion (xdpy, xstage, ShapeInput, 0, 0, region); + + /* It's generally a good heuristic that when a crossing event is generated because + * we reshape the overlay, we don't want it to affect focus-follows-mouse focus - + * it's not the user doing something, it's the environment changing under the user. + */ + meta_display_add_ignored_crossing_serial (display, XNextRequest (xdpy)); + XFixesSetWindowShapeRegion (xdpy, info->output, ShapeInput, 0, 0, region); } } @@ -668,21 +639,6 @@ meta_compositor_manage_screen (MetaCompositor *compositor, return; info = g_new0 (MetaCompScreen, 1); - /* - * We use an empty input region for Clutter as a default because that allows - * the user to interact with all the windows displayed on the screen. - * We have to initialize info->pending_input_region to an empty region explicitly, - * because None value is used to mean that the whole screen is an input region. - */ - if (!meta_is_wayland_compositor ()) - info->pending_input_region = XFixesCreateRegion (xdisplay, NULL, 0); - else - { - /* Stage input region trickery isn't needed when we're running as a - * wayland compositor. */ - info->pending_input_region = None; - } - info->screen = screen; meta_screen_set_compositor_data (screen, info); @@ -768,6 +724,8 @@ meta_compositor_manage_screen (MetaCompositor *compositor, info->output = get_output_window (screen); XReparentWindow (xdisplay, xwin, info->output, 0, 0); + meta_empty_stage_input_region (screen); + /* Make sure there isn't any left-over output shape on the * overlay window by setting the whole screen to be an * output region. @@ -778,13 +736,6 @@ meta_compositor_manage_screen (MetaCompositor *compositor, */ XFixesSetWindowShapeRegion (xdisplay, info->output, ShapeBounding, 0, 0, None); - do_set_stage_input_region (screen, info->pending_input_region); - if (info->pending_input_region != None) - { - XFixesDestroyRegion (xdisplay, info->pending_input_region); - info->pending_input_region = None; - } - /* Map overlay window before redirecting windows offscreen so we catch their * contents until we show the stage. */ From a0fe3926657611f687c3befffce3c07f17071444 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 6 Dec 2013 11:57:40 -0500 Subject: [PATCH 396/889] surface-actor: Move unobscured_region processing here https://bugzilla.gnome.org/show_bug.cgi?id=720631 --- src/compositor/meta-surface-actor.c | 105 +++++++++++++++++++-- src/compositor/meta-surface-actor.h | 9 +- src/compositor/meta-window-actor-private.h | 3 - src/compositor/meta-window-actor.c | 70 +++----------- src/compositor/meta-window-group.c | 14 --- src/wayland/meta-wayland-surface.c | 6 +- 6 files changed, 116 insertions(+), 91 deletions(-) diff --git a/src/compositor/meta-surface-actor.c b/src/compositor/meta-surface-actor.c index 37b87b03a..8d3f5b4d5 100644 --- a/src/compositor/meta-surface-actor.c +++ b/src/compositor/meta-surface-actor.c @@ -24,6 +24,9 @@ struct _MetaSurfaceActorPrivate { MetaShapedTexture *texture; MetaWaylandBuffer *buffer; + + /* The region that is visible, used to optimize out redraws */ + cairo_region_t *unobscured_region; }; static void cullable_iface_init (MetaCullableInterface *iface); @@ -31,23 +34,96 @@ static void cullable_iface_init (MetaCullableInterface *iface); G_DEFINE_TYPE_WITH_CODE (MetaSurfaceActor, meta_surface_actor, CLUTTER_TYPE_ACTOR, G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init)); +static gboolean +meta_surface_actor_get_paint_volume (ClutterActor *actor, + ClutterPaintVolume *volume) +{ + MetaSurfaceActor *self = META_SURFACE_ACTOR (actor); + MetaSurfaceActorPrivate *priv = self->priv; + + if (!CLUTTER_ACTOR_CLASS (meta_surface_actor_parent_class)->get_paint_volume (actor, volume)) + return FALSE; + + if (priv->unobscured_region) + { + ClutterVertex origin; + cairo_rectangle_int_t bounds, unobscured_bounds; + + /* I hate ClutterPaintVolume so much... */ + clutter_paint_volume_get_origin (volume, &origin); + bounds.x = origin.x; + bounds.y = origin.y; + bounds.width = clutter_paint_volume_get_width (volume); + bounds.height = clutter_paint_volume_get_height (volume); + + cairo_region_get_extents (priv->unobscured_region, &unobscured_bounds); + gdk_rectangle_intersect (&bounds, &unobscured_bounds, &bounds); + + origin.x = bounds.x; + origin.y = bounds.y; + clutter_paint_volume_set_origin (volume, &origin); + clutter_paint_volume_set_width (volume, bounds.width); + clutter_paint_volume_set_height (volume, bounds.height); + } + + return TRUE; +} + +static void +meta_surface_actor_dispose (GObject *object) +{ + MetaSurfaceActor *self = META_SURFACE_ACTOR (object); + MetaSurfaceActorPrivate *priv = self->priv; + + g_clear_pointer (&priv->unobscured_region, cairo_region_destroy); + + G_OBJECT_CLASS (meta_surface_actor_parent_class)->dispose (object); +} + static void meta_surface_actor_class_init (MetaSurfaceActorClass *klass) { + ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + actor_class->get_paint_volume = meta_surface_actor_get_paint_volume; + object_class->dispose = meta_surface_actor_dispose; + g_type_class_add_private (klass, sizeof (MetaSurfaceActorPrivate)); } +static void +set_unobscured_region (MetaSurfaceActor *self, + cairo_region_t *unobscured_region) +{ + MetaSurfaceActorPrivate *priv = self->priv; + + if (priv->unobscured_region) + cairo_region_destroy (priv->unobscured_region); + + if (unobscured_region) + priv->unobscured_region = cairo_region_copy (unobscured_region); + else + priv->unobscured_region = NULL; +} + static void meta_surface_actor_cull_out (MetaCullable *cullable, cairo_region_t *unobscured_region, cairo_region_t *clip_region) { + MetaSurfaceActor *self = META_SURFACE_ACTOR (cullable); + + set_unobscured_region (self, unobscured_region); meta_cullable_cull_out_children (cullable, unobscured_region, clip_region); } static void meta_surface_actor_reset_culling (MetaCullable *cullable) { + MetaSurfaceActor *self = META_SURFACE_ACTOR (cullable); + + set_unobscured_region (self, NULL); meta_cullable_reset_culling_children (cullable); } @@ -108,9 +184,16 @@ update_area (MetaSurfaceActor *self, } } +static cairo_region_t * +effective_unobscured_region (MetaSurfaceActor *self) +{ + MetaSurfaceActorPrivate *priv = self->priv; + + return clutter_actor_has_mapped_clones (CLUTTER_ACTOR (self)) ? NULL : priv->unobscured_region; +} + gboolean -meta_surface_actor_damage_all (MetaSurfaceActor *self, - cairo_region_t *unobscured_region) +meta_surface_actor_damage_all (MetaSurfaceActor *self) { MetaSurfaceActorPrivate *priv = self->priv; CoglTexture *texture = meta_shaped_texture_get_texture (priv->texture); @@ -120,7 +203,7 @@ meta_surface_actor_damage_all (MetaSurfaceActor *self, 0, 0, cogl_texture_get_width (texture), cogl_texture_get_height (texture), - unobscured_region); + effective_unobscured_region (self)); } gboolean @@ -128,15 +211,25 @@ meta_surface_actor_damage_area (MetaSurfaceActor *self, int x, int y, int width, - int height, - cairo_region_t *unobscured_region) + int height) { MetaSurfaceActorPrivate *priv = self->priv; update_area (self, x, y, width, height); return meta_shaped_texture_update_area (priv->texture, x, y, width, height, - unobscured_region); + effective_unobscured_region (self)); +} + +gboolean +meta_surface_actor_is_obscured (MetaSurfaceActor *self) +{ + MetaSurfaceActorPrivate *priv = self->priv; + + if (priv->unobscured_region) + return cairo_region_is_empty (priv->unobscured_region); + else + return FALSE; } void diff --git a/src/compositor/meta-surface-actor.h b/src/compositor/meta-surface-actor.h index 484877b73..0f5fd8f04 100644 --- a/src/compositor/meta-surface-actor.h +++ b/src/compositor/meta-surface-actor.h @@ -43,15 +43,14 @@ cairo_surface_t *meta_surface_actor_get_image (MetaSurfaceActor *self, MetaShapedTexture *meta_surface_actor_get_texture (MetaSurfaceActor *self); -gboolean meta_surface_actor_damage_all (MetaSurfaceActor *self, - cairo_region_t *unobscured_region); - +gboolean meta_surface_actor_damage_all (MetaSurfaceActor *self); gboolean meta_surface_actor_damage_area (MetaSurfaceActor *self, int x, int y, int width, - int height, - cairo_region_t *unobscured_region); + int height); + +gboolean meta_surface_actor_is_obscured (MetaSurfaceActor *self); void meta_surface_actor_set_texture (MetaSurfaceActor *self, CoglTexture *texture); diff --git a/src/compositor/meta-window-actor-private.h b/src/compositor/meta-window-actor-private.h index 82326d29b..e3d239d2e 100644 --- a/src/compositor/meta-window-actor-private.h +++ b/src/compositor/meta-window-actor-private.h @@ -59,9 +59,6 @@ void meta_window_actor_set_updates_frozen (MetaWindowActor *self, void meta_window_actor_queue_frame_drawn (MetaWindowActor *self, gboolean no_delay_frame); -void meta_window_actor_set_unobscured_region (MetaWindowActor *self, - cairo_region_t *unobscured_region); - void meta_window_actor_effect_completed (MetaWindowActor *actor, gulong event); diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index e9cecfc2c..652ce04f5 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -72,9 +72,6 @@ struct _MetaWindowActorPrivate /* The region we should clip to when painting the shadow */ cairo_region_t *shadow_clip; - /* The region that is visible, used to optimize out redraws */ - cairo_region_t *unobscured_region; - guint send_frame_messages_timer; gint64 frame_drawn_time; @@ -424,7 +421,6 @@ meta_window_actor_dispose (GObject *object) priv->send_frame_messages_timer = 0; } - g_clear_pointer (&priv->unobscured_region, cairo_region_destroy); g_clear_pointer (&priv->shape_region, cairo_region_destroy); g_clear_pointer (&priv->shadow_clip, cairo_region_destroy); @@ -720,12 +716,15 @@ meta_window_actor_get_paint_volume (ClutterActor *actor, gdk_rectangle_union (&bounds, &shadow_bounds, &bounds); } - if (priv->unobscured_region) - { - cairo_rectangle_int_t unobscured_bounds; - cairo_region_get_extents (priv->unobscured_region, &unobscured_bounds); - gdk_rectangle_intersect (&bounds, &unobscured_bounds, &bounds); - } + { + const ClutterPaintVolume *child_volume; + + child_volume = clutter_actor_get_transformed_paint_volume (CLUTTER_ACTOR (priv->surface), actor); + if (!child_volume) + return FALSE; + + clutter_paint_volume_union (volume, child_volume); + } origin.x = bounds.x; origin.y = bounds.y; @@ -977,7 +976,6 @@ static void meta_window_actor_damage_all (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; - cairo_region_t *unobscured_region; gboolean redraw_queued; if (!priv->needs_damage_all) @@ -986,11 +984,7 @@ meta_window_actor_damage_all (MetaWindowActor *self) if (priv->needs_pixmap) return; - unobscured_region = - clutter_actor_has_mapped_clones (CLUTTER_ACTOR (priv->surface)) - ? NULL : priv->unobscured_region; - - redraw_queued = meta_surface_actor_damage_all (priv->surface, unobscured_region); + redraw_queued = meta_surface_actor_damage_all (priv->surface); priv->repaint_scheduled = priv->repaint_scheduled || redraw_queued; priv->needs_damage_all = FALSE; @@ -1049,17 +1043,7 @@ meta_window_actor_queue_frame_drawn (MetaWindowActor *self, if (!priv->repaint_scheduled) { - gboolean is_obscured = FALSE; - - /* Find out whether the window is completly obscured */ - if (priv->unobscured_region) - { - cairo_region_t *unobscured_window_region; - unobscured_window_region = cairo_region_copy (priv->shape_region); - cairo_region_intersect (unobscured_window_region, priv->unobscured_region); - is_obscured = cairo_region_is_empty (unobscured_window_region); - cairo_region_destroy (unobscured_window_region); - } + gboolean is_obscured = meta_surface_actor_is_obscured (priv->surface); /* A frame was marked by the client without actually doing any * damage or any unobscured, or while we had the window frozen @@ -1703,30 +1687,6 @@ see_region (cairo_region_t *region, } #endif -/** - * meta_window_actor_set_unobscured_region: - * @self: a #MetaWindowActor - * @unobscured_region: the region of the screen that isn't completely - * obscured. - * - * Provides a hint as to what areas of the window need to queue - * redraws when damaged. Regions not in @unobscured_region are completely obscured. - */ -void -meta_window_actor_set_unobscured_region (MetaWindowActor *self, - cairo_region_t *unobscured_region) -{ - MetaWindowActorPrivate *priv = self->priv; - - if (priv->unobscured_region) - cairo_region_destroy (priv->unobscured_region); - - if (unobscured_region) - priv->unobscured_region = cairo_region_copy (unobscured_region); - else - priv->unobscured_region = NULL; -} - /** * meta_window_actor_set_clip_region_beneath: * @self: a #MetaWindowActor @@ -1775,7 +1735,6 @@ meta_window_actor_cull_out (MetaCullable *cullable, return; } - meta_window_actor_set_unobscured_region (self, unobscured_region); meta_cullable_cull_out_children (cullable, unobscured_region, clip_region); meta_window_actor_set_clip_region_beneath (self, clip_region); } @@ -1946,7 +1905,6 @@ meta_window_actor_process_x11_damage (MetaWindowActor *self, MetaWindowActorPrivate *priv = self->priv; MetaCompScreen *info = meta_screen_get_compositor_data (priv->screen); gboolean redraw_queued; - cairo_region_t *unobscured_region; priv->received_x11_damage = TRUE; @@ -1994,15 +1952,11 @@ meta_window_actor_process_x11_damage (MetaWindowActor *self, if (priv->needs_pixmap) return; - unobscured_region = - clutter_actor_has_mapped_clones (CLUTTER_ACTOR (priv->surface)) - ? NULL : priv->unobscured_region; redraw_queued = meta_surface_actor_damage_area (priv->surface, event->area.x, event->area.y, event->area.width, - event->area.height, - unobscured_region); + event->area.height); priv->repaint_scheduled = priv->repaint_scheduled || redraw_queued; diff --git a/src/compositor/meta-window-group.c b/src/compositor/meta-window-group.c index 9554571b0..11445543e 100644 --- a/src/compositor/meta-window-group.c +++ b/src/compositor/meta-window-group.c @@ -115,8 +115,6 @@ meta_window_group_paint (ClutterActor *actor) { cairo_region_t *clip_region; cairo_region_t *unobscured_region; - ClutterActorIter iter; - ClutterActor *child; cairo_rectangle_int_t visible_rect, clip_rect; int paint_x_offset, paint_y_offset; int paint_x_origin, paint_y_origin; @@ -125,18 +123,6 @@ meta_window_group_paint (ClutterActor *actor) MetaWindowGroup *window_group = META_WINDOW_GROUP (actor); ClutterActor *stage = clutter_actor_get_stage (actor); - /* Start off by treating all windows as completely unobscured, so damage anywhere - * in a window queues redraws, but confine it more below. */ - clutter_actor_iter_init (&iter, actor); - while (clutter_actor_iter_next (&iter, &child)) - { - if (META_IS_WINDOW_ACTOR (child)) - { - MetaWindowActor *window_actor = META_WINDOW_ACTOR (child); - meta_window_actor_set_unobscured_region (window_actor, NULL); - } - } - /* Normally we expect an actor to be drawn at it's position on the screen. * However, if we're inside the paint of a ClutterClone, that won't be the * case and we need to compensate. We look at the position of the window diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 1ca38e564..f31f3cef2 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -69,11 +69,7 @@ surface_process_damage (MetaWaylandSurface *surface, cairo_rectangle_int_t rect; cairo_region_get_rectangle (region, i, &rect); meta_surface_actor_damage_area (surface->surface_actor, - rect.x, - rect.y, - rect.width, - rect.height, - NULL); + rect.x, rect.y, rect.width, rect.height); } } From e3b64912b60bc7d8efcc4d9ef28d9b3f7f7699df Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 6 Dec 2013 17:42:43 -0500 Subject: [PATCH 397/889] window-actor: Simplify the unredirected check in cull_out https://bugzilla.gnome.org/show_bug.cgi?id=720631 --- src/compositor/meta-window-actor.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 652ce04f5..b9bcba609 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -1725,15 +1725,11 @@ meta_window_actor_cull_out (MetaCullable *cullable, cairo_region_t *clip_region) { MetaWindowActor *self = META_WINDOW_ACTOR (cullable); + MetaWindowActorPrivate *priv = self->priv; - if (!meta_is_wayland_compositor ()) - { - MetaCompScreen *info = meta_screen_get_compositor_data (self->priv->screen); - - /* Don't do any culling for the unredirected window */ - if (self == info->unredirected_window) - return; - } + /* Don't do any culling for the unredirected window */ + if (priv->unredirected) + return; meta_cullable_cull_out_children (cullable, unobscured_region, clip_region); meta_window_actor_set_clip_region_beneath (self, clip_region); From fa7a5782c6544021d2ab8228f39f3067cff481a3 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 6 Dec 2013 17:10:44 -0500 Subject: [PATCH 398/889] compositor: Simplify the unredirected window management code https://bugzilla.gnome.org/show_bug.cgi?id=720631 --- src/compositor/compositor-private.h | 4 +- src/compositor/compositor.c | 73 ++++++++++++++--------------- src/compositor/meta-window-group.c | 3 +- 3 files changed, 37 insertions(+), 43 deletions(-) diff --git a/src/compositor/compositor-private.h b/src/compositor/compositor-private.h index f3b7afb22..18bcff6f9 100644 --- a/src/compositor/compositor-private.h +++ b/src/compositor/compositor-private.h @@ -46,8 +46,8 @@ struct _MetaCompScreen CoglFrameClosure *frame_closure; /* Used for unredirecting fullscreen windows */ - guint disable_unredirect_count; - MetaWindowActor *unredirected_window; + guint disable_unredirect_count; + MetaWindow *unredirected_window; gint switch_workspace_in_progress; diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 14512d648..62725ec8a 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -805,6 +805,30 @@ meta_shape_cow_for_window (MetaScreen *screen, } } +static void +set_unredirected_window (MetaCompScreen *info, + MetaWindow *window) +{ + if (info->unredirected_window == window) + return; + + if (info->unredirected_window != NULL) + { + MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (info->unredirected_window)); + meta_window_actor_set_redirected (window_actor, TRUE); + } + + info->unredirected_window = window; + + if (info->unredirected_window != NULL) + { + MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (info->unredirected_window)); + meta_window_actor_set_redirected (window_actor, FALSE); + } + + meta_shape_cow_for_window (info->screen, info->unredirected_window); +} + void meta_compositor_add_window (MetaCompositor *compositor, MetaWindow *window) @@ -833,19 +857,11 @@ meta_compositor_remove_window (MetaCompositor *compositor, if (!window_actor) return; - if (!meta_is_wayland_compositor ()) - { - screen = meta_window_get_screen (window); - info = meta_screen_get_compositor_data (screen); + screen = meta_window_get_screen (window); + info = meta_screen_get_compositor_data (screen); - if (window_actor == info->unredirected_window) - { - meta_window_actor_set_redirected (window_actor, TRUE); - meta_shape_cow_for_window (meta_window_get_screen (meta_window_actor_get_meta_window (info->unredirected_window)), - NULL); - info->unredirected_window = NULL; - } - } + if (info->unredirected_window == window) + set_unredirected_window (info, NULL); meta_window_actor_destroy (window_actor); } @@ -1451,7 +1467,6 @@ pre_paint_windows (MetaCompScreen *info) { GList *l; MetaWindowActor *top_window; - MetaWindowActor *expected_unredirected_window = NULL; if (info->onscreen == NULL) { @@ -1465,33 +1480,13 @@ pre_paint_windows (MetaCompScreen *info) if (info->windows == NULL) return; - if (!meta_is_wayland_compositor ()) - { - top_window = g_list_last (info->windows)->data; + top_window = g_list_last (info->windows)->data; - if (meta_window_actor_should_unredirect (top_window) && - info->disable_unredirect_count == 0) - expected_unredirected_window = top_window; - - if (info->unredirected_window != expected_unredirected_window) - { - if (info->unredirected_window != NULL) - { - meta_window_actor_set_redirected (info->unredirected_window, TRUE); - meta_shape_cow_for_window (meta_window_get_screen (meta_window_actor_get_meta_window (info->unredirected_window)), - NULL); - } - - if (expected_unredirected_window != NULL) - { - meta_shape_cow_for_window (meta_window_get_screen (meta_window_actor_get_meta_window (top_window)), - meta_window_actor_get_meta_window (top_window)); - meta_window_actor_set_redirected (top_window, FALSE); - } - - info->unredirected_window = expected_unredirected_window; - } - } + if (meta_window_actor_should_unredirect (top_window) && + info->disable_unredirect_count == 0) + set_unredirected_window (info, meta_window_actor_get_meta_window (top_window)); + else + set_unredirected_window (info, NULL); for (l = info->windows; l; l = l->next) meta_window_actor_pre_paint (l->data); diff --git a/src/compositor/meta-window-group.c b/src/compositor/meta-window-group.c index 11445543e..542060531 100644 --- a/src/compositor/meta-window-group.c +++ b/src/compositor/meta-window-group.c @@ -170,9 +170,8 @@ meta_window_group_paint (ClutterActor *actor) if (info->unredirected_window != NULL) { cairo_rectangle_int_t unredirected_rect; - MetaWindow *window = meta_window_actor_get_meta_window (info->unredirected_window); - meta_window_get_frame_rect (window, (MetaRectangle *)&unredirected_rect); + meta_window_get_frame_rect (info->unredirected_window, (MetaRectangle *)&unredirected_rect); cairo_region_subtract_rectangle (unobscured_region, &unredirected_rect); cairo_region_subtract_rectangle (clip_region, &unredirected_rect); } From 0a81314337dce250f05c5e42e9f09df8464e7769 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 6 Dec 2013 17:36:09 -0500 Subject: [PATCH 399/889] window-actor: Flip set_redirected around I know it's confusing with the triple negative, but unredirected is how we track it elsewhere: we have an 'unredirected' flag, and 'should_unredirect'. https://bugzilla.gnome.org/show_bug.cgi?id=720631 --- src/compositor/compositor.c | 4 ++-- src/compositor/meta-window-actor-private.h | 8 ++++---- src/compositor/meta-window-actor.c | 22 +++++++++++----------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 62725ec8a..0fb8df9e3 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -815,7 +815,7 @@ set_unredirected_window (MetaCompScreen *info, if (info->unredirected_window != NULL) { MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (info->unredirected_window)); - meta_window_actor_set_redirected (window_actor, TRUE); + meta_window_actor_set_unredirected (window_actor, FALSE); } info->unredirected_window = window; @@ -823,7 +823,7 @@ set_unredirected_window (MetaCompScreen *info, if (info->unredirected_window != NULL) { MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (info->unredirected_window)); - meta_window_actor_set_redirected (window_actor, FALSE); + meta_window_actor_set_unredirected (window_actor, TRUE); } meta_shape_cow_for_window (info->screen, info->unredirected_window); diff --git a/src/compositor/meta-window-actor-private.h b/src/compositor/meta-window-actor-private.h index e3d239d2e..9c6a8476e 100644 --- a/src/compositor/meta-window-actor-private.h +++ b/src/compositor/meta-window-actor-private.h @@ -39,13 +39,13 @@ void meta_window_actor_frame_complete (MetaWindowActor *self, void meta_window_actor_invalidate_shadow (MetaWindowActor *self); -void meta_window_actor_set_redirected (MetaWindowActor *self, gboolean state); - -gboolean meta_window_actor_should_unredirect (MetaWindowActor *self); - void meta_window_actor_get_shape_bounds (MetaWindowActor *self, cairo_rectangle_int_t *bounds); +gboolean meta_window_actor_should_unredirect (MetaWindowActor *self); +void meta_window_actor_set_unredirected (MetaWindowActor *self, + gboolean unredirected); + gboolean meta_window_actor_effect_in_progress (MetaWindowActor *self); void meta_window_actor_sync_actor_geometry (MetaWindowActor *self, gboolean did_placement); diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index b9bcba609..d19234cf3 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -1329,7 +1329,8 @@ meta_window_actor_should_unredirect (MetaWindowActor *self) } void -meta_window_actor_set_redirected (MetaWindowActor *self, gboolean state) +meta_window_actor_set_unredirected (MetaWindowActor *self, + gboolean unredirected) { MetaWindow *metaWindow = meta_window_actor_get_meta_window (self); MetaDisplay *display = meta_window_get_display (metaWindow); @@ -1337,21 +1338,20 @@ meta_window_actor_set_redirected (MetaWindowActor *self, gboolean state) Display *xdisplay = meta_display_get_xdisplay (display); Window xwin = meta_window_get_toplevel_xwindow (metaWindow); - if (state) + meta_error_trap_push (display); + + if (unredirected) { - meta_error_trap_push (display); - XCompositeRedirectWindow (xdisplay, xwin, CompositeRedirectManual); - meta_error_trap_pop (display); - meta_window_actor_detach_x11_pixmap (self); - self->priv->unredirected = FALSE; + XCompositeUnredirectWindow (xdisplay, xwin, CompositeRedirectManual); } else { - meta_error_trap_push (display); - XCompositeUnredirectWindow (xdisplay, xwin, CompositeRedirectManual); - meta_error_trap_pop (display); - self->priv->unredirected = TRUE; + XCompositeRedirectWindow (xdisplay, xwin, CompositeRedirectManual); + meta_window_actor_detach_x11_pixmap (self); } + + self->priv->unredirected = unredirected; + meta_error_trap_pop (display); } void From 03146c2967c37874a8fd22e118feb570964f0f83 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 4 Nov 2013 21:17:48 -0500 Subject: [PATCH 400/889] window-actor: Remove old unused APIs https://bugzilla.gnome.org/show_bug.cgi?id=720631 --- src/compositor/meta-window-actor.c | 53 ------------------------------ src/compositor/plugins/default.c | 2 +- src/meta/meta-window-actor.h | 3 -- 3 files changed, 1 insertion(+), 57 deletions(-) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index d19234cf3..db44798f6 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -858,59 +858,6 @@ meta_window_actor_is_destroyed (MetaWindowActor *self) return self->priv->disposed; } -gboolean -meta_window_actor_is_override_redirect (MetaWindowActor *self) -{ - return meta_window_is_override_redirect (self->priv->window); -} - -/** - * meta_window_actor_get_workspace: - * @self: #MetaWindowActor - * - * Returns the index of workspace on which this window is located; if the - * window is sticky, or is not currently located on any workspace, returns -1. - * This function is deprecated and should not be used in newly written code; - * meta_window_get_workspace() instead. - * - * Return value: (transfer none): index of workspace on which this window is - * located. - */ -gint -meta_window_actor_get_workspace (MetaWindowActor *self) -{ - MetaWindowActorPrivate *priv; - MetaWorkspace *workspace; - - if (!self) - return -1; - - priv = self->priv; - - if (!priv->window || meta_window_is_on_all_workspaces (priv->window)) - return -1; - - workspace = meta_window_get_workspace (priv->window); - - if (!workspace) - return -1; - - return meta_workspace_index (workspace); -} - -gboolean -meta_window_actor_showing_on_its_workspace (MetaWindowActor *self) -{ - if (!self) - return FALSE; - - /* If override redirect: */ - if (!self->priv->window) - return TRUE; - - return meta_window_showing_on_its_workspace (self->priv->window); -} - static void meta_window_actor_freeze (MetaWindowActor *self) { diff --git a/src/compositor/plugins/default.c b/src/compositor/plugins/default.c index 91b30c039..892854b33 100644 --- a/src/compositor/plugins/default.c +++ b/src/compositor/plugins/default.c @@ -409,7 +409,7 @@ switch_workspace (MetaPlugin *plugin, ClutterActor *actor = CLUTTER_ACTOR (window_actor); gint win_workspace; - win_workspace = meta_window_actor_get_workspace (window_actor); + win_workspace = meta_window_get_workspace (meta_window_actor_get_meta_window (window_actor)); if (win_workspace == to || win_workspace == from) { diff --git a/src/meta/meta-window-actor.h b/src/meta/meta-window-actor.h index 9f808a9ac..2055ca8fc 100644 --- a/src/meta/meta-window-actor.h +++ b/src/meta/meta-window-actor.h @@ -58,11 +58,8 @@ struct _MetaWindowActor GType meta_window_actor_get_type (void); Window meta_window_actor_get_x_window (MetaWindowActor *self); -gint meta_window_actor_get_workspace (MetaWindowActor *self); MetaWindow * meta_window_actor_get_meta_window (MetaWindowActor *self); ClutterActor * meta_window_actor_get_texture (MetaWindowActor *self); -gboolean meta_window_actor_is_override_redirect (MetaWindowActor *self); -gboolean meta_window_actor_showing_on_its_workspace (MetaWindowActor *self); gboolean meta_window_actor_is_destroyed (MetaWindowActor *self); #endif /* META_WINDOW_ACTOR_H */ From 7ea537fad7fc9d62c057ff33611f6827445714bb Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 6 Dec 2013 15:39:24 -0500 Subject: [PATCH 401/889] Move position-changed / size-changed signals to the MetaWindow They fit more appropriately over here... https://bugzilla.gnome.org/show_bug.cgi?id=720631 --- src/compositor/meta-window-actor.c | 37 ------------------------------ src/core/window.c | 24 +++++++++++++++++++ 2 files changed, 24 insertions(+), 37 deletions(-) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index db44798f6..9d6500072 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -37,15 +37,6 @@ #include "monitor-private.h" #include "meta-cullable.h" -enum { - POSITION_CHANGED, - SIZE_CHANGED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = {0}; - - struct _MetaWindowActorPrivate { MetaWindow *window; @@ -245,19 +236,6 @@ meta_window_actor_class_init (MetaWindowActorClass *klass) g_object_class_install_property (object_class, PROP_SHADOW_CLASS, pspec); - - signals[POSITION_CHANGED] = - g_signal_new ("position-changed", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 0); - signals[SIZE_CHANGED] = - g_signal_new ("size-changed", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 0); } static void @@ -327,8 +305,6 @@ surface_allocation_changed_notify (ClutterActor *actor, { meta_window_actor_sync_actor_geometry (self, FALSE); meta_window_actor_update_shape (self); - - g_signal_emit (self, signals[SIZE_CHANGED], 0); } static gboolean @@ -1392,8 +1368,6 @@ meta_window_actor_sync_actor_geometry (MetaWindowActor *self, window_rect.x, window_rect.y); clutter_actor_set_size (CLUTTER_ACTOR (self), window_rect.width, window_rect.height); - - g_signal_emit (self, signals[POSITION_CHANGED], 0); } void @@ -1760,17 +1734,6 @@ check_needs_x11_pixmap (MetaWindowActor *self) g_warning ("NOTE: Not using GLX TFP!\n"); meta_surface_actor_set_texture (META_SURFACE_ACTOR (priv->surface), texture); - - /* ::size-changed is supposed to refer to meta_window_get_frame_rect(). - * Emitting it here works pretty much OK because a new value of the - * *input* rect (which is the outer rect with the addition of invisible - * borders) forces a new pixmap and we get here. In the rare case where - * a change to the window size was exactly balanced by a change to the - * invisible borders, we would miss emitting the signal. We would also - * emit spurious signals when we get a new pixmap without a new size, - * but that should be mostly harmless. - */ - g_signal_emit (self, signals[SIZE_CHANGED], 0); } priv->needs_pixmap = FALSE; diff --git a/src/core/window.c b/src/core/window.c index 5ac4b195a..dbac50751 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -215,6 +215,8 @@ enum FOCUS, RAISED, UNMANAGED, + SIZE_CHANGED, + POSITION_CHANGED, LAST_SIGNAL }; @@ -611,6 +613,22 @@ meta_window_class_init (MetaWindowClass *klass) G_STRUCT_OFFSET (MetaWindowClass, unmanaged), NULL, NULL, NULL, G_TYPE_NONE, 0); + + window_signals[POSITION_CHANGED] = + g_signal_new ("position-changed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); + + window_signals[SIZE_CHANGED] = + g_signal_new ("size-changed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); } static void @@ -5377,6 +5395,12 @@ meta_window_move_resize_internal (MetaWindow *window, else if (is_user_action) save_user_window_placement (window); + if (need_move_frame) + g_signal_emit (window, window_signals[POSITION_CHANGED], 0); + + if (need_resize_client) + g_signal_emit (window, window_signals[SIZE_CHANGED], 0); + if (need_move_frame || need_resize_frame || need_move_client || need_resize_client || did_placement || is_wayland_resize) From e6391c28969588eafc8e4367e14ab5eeb3849125 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 9 Dec 2013 16:01:07 -0500 Subject: [PATCH 402/889] surface content --- src/Makefile.am | 4 + src/compositor/meta-surface-actor-wayland.c | 159 ++++++ src/compositor/meta-surface-actor-wayland.h | 65 +++ src/compositor/meta-surface-actor-x11.c | 551 +++++++++++++++++++ src/compositor/meta-surface-actor-x11.h | 69 +++ src/compositor/meta-surface-actor.c | 137 +++-- src/compositor/meta-surface-actor.h | 45 +- src/compositor/meta-window-actor.c | 563 +++----------------- src/wayland/meta-wayland-surface.c | 13 +- 9 files changed, 1029 insertions(+), 577 deletions(-) create mode 100644 src/compositor/meta-surface-actor-wayland.c create mode 100644 src/compositor/meta-surface-actor-wayland.h create mode 100644 src/compositor/meta-surface-actor-x11.c create mode 100644 src/compositor/meta-surface-actor-x11.h diff --git a/src/Makefile.am b/src/Makefile.am index b81c6ec51..991c1aea4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -83,6 +83,10 @@ libmutter_wayland_la_SOURCES = \ compositor/meta-shaped-texture-private.h \ compositor/meta-surface-actor.c \ compositor/meta-surface-actor.h \ + compositor/meta-surface-actor-x11.c \ + compositor/meta-surface-actor-x11.h \ + compositor/meta-surface-actor-wayland.c \ + compositor/meta-surface-actor-wayland.h \ compositor/meta-texture-rectangle.c \ compositor/meta-texture-rectangle.h \ compositor/meta-texture-tower.c \ diff --git a/src/compositor/meta-surface-actor-wayland.c b/src/compositor/meta-surface-actor-wayland.c new file mode 100644 index 000000000..95ebc9020 --- /dev/null +++ b/src/compositor/meta-surface-actor-wayland.c @@ -0,0 +1,159 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2013 Red Hat + * + * 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. + * + * Written by: + * Jasper St. Pierre + */ + +#include "config.h" + +#include "meta-surface-actor-wayland.h" + +#include +#include "meta-shaped-texture-private.h" + +struct _MetaSurfaceActorWaylandPrivate +{ + MetaWaylandSurface *surface; + MetaWaylandBuffer *buffer; +}; +typedef struct _MetaSurfaceActorWaylandPrivate MetaSurfaceActorWaylandPrivate; + +G_DEFINE_TYPE_WITH_PRIVATE (MetaSurfaceActorWayland, meta_surface_actor_wayland, META_TYPE_SURFACE_ACTOR) + +static void +meta_surface_actor_wayland_process_damage (MetaSurfaceActor *actor, + int x, int y, int width, int height) +{ + MetaSurfaceActorWayland *self = META_SURFACE_ACTOR_WAYLAND (actor); + MetaSurfaceActorWaylandPrivate *priv = meta_surface_actor_wayland_get_instance_private (self); + + struct wl_resource *resource = priv->buffer->resource; + struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get (resource); + + if (shm_buffer) + { + CoglTexture2D *texture = COGL_TEXTURE_2D (priv->buffer->texture); + cogl_wayland_texture_set_region_from_shm_buffer (texture, x, y, width, height, shm_buffer, x, y, 0, NULL); + } + + meta_surface_actor_redraw_area (META_SURFACE_ACTOR (self), x, y, width, height); +} + +static void +meta_surface_actor_wayland_pre_paint (MetaSurfaceActor *actor) +{ +} + +static gboolean +meta_surface_actor_wayland_is_argb32 (MetaSurfaceActor *actor) +{ + /* TODO: look at the SHM buffer pixel format */ + return TRUE; +} + +static gboolean +meta_surface_actor_wayland_is_visible (MetaSurfaceActor *actor) +{ + /* TODO: ensure that the buffer isn't NULL, implement + * wayland mapping semantics */ + return TRUE; +} + +static void +meta_surface_actor_wayland_freeze (MetaSurfaceActor *actor) +{ +} + +static void +meta_surface_actor_wayland_thaw (MetaSurfaceActor *actor) +{ +} + +static gboolean +meta_surface_actor_wayland_is_frozen (MetaSurfaceActor *actor) +{ + return FALSE; +} + +static gboolean +meta_surface_actor_wayland_should_unredirect (MetaSurfaceActor *actor) +{ + return FALSE; +} + +static void +meta_surface_actor_wayland_set_unredirected (MetaSurfaceActor *actor, + gboolean unredirected) +{ + /* Do nothing. In the future, we'll use KMS to set this + * up as a hardware overlay or something. */ +} + +static void +meta_surface_actor_wayland_class_init (MetaSurfaceActorWaylandClass *klass) +{ + MetaSurfaceActorClass *surface_actor_class = META_SURFACE_ACTOR_CLASS (klass); + + surface_actor_class->process_damage = meta_surface_actor_wayland_process_damage; + surface_actor_class->pre_paint = meta_surface_actor_wayland_pre_paint; + surface_actor_class->is_argb32 = meta_surface_actor_wayland_is_argb32; + surface_actor_class->is_visible = meta_surface_actor_wayland_is_visible; + + surface_actor_class->freeze = meta_surface_actor_wayland_freeze; + surface_actor_class->thaw = meta_surface_actor_wayland_thaw; + surface_actor_class->is_frozen = meta_surface_actor_wayland_is_frozen; + + surface_actor_class->should_unredirect = meta_surface_actor_wayland_should_unredirect; + surface_actor_class->set_unredirected = meta_surface_actor_wayland_set_unredirected; +} + +static void +meta_surface_actor_wayland_init (MetaSurfaceActorWayland *self) +{ +} + +MetaSurfaceActor * +meta_surface_actor_wayland_new (MetaWaylandSurface *surface) +{ + MetaSurfaceActorWayland *self = g_object_new (META_TYPE_SURFACE_ACTOR_WAYLAND, NULL); + MetaSurfaceActorWaylandPrivate *priv = meta_surface_actor_wayland_get_instance_private (self); + + g_assert (meta_is_wayland_compositor ()); + + priv->surface = surface; + + return META_SURFACE_ACTOR (self); +} + +void +meta_surface_actor_wayland_set_buffer (MetaSurfaceActorWayland *self, + MetaWaylandBuffer *buffer) +{ + MetaSurfaceActorWaylandPrivate *priv = meta_surface_actor_wayland_get_instance_private (self); + MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self)); + + priv->buffer = buffer; + + if (buffer) + meta_shaped_texture_set_texture (stex, buffer->texture); + else + meta_shaped_texture_set_texture (stex, NULL); +} diff --git a/src/compositor/meta-surface-actor-wayland.h b/src/compositor/meta-surface-actor-wayland.h new file mode 100644 index 000000000..2712f9dbf --- /dev/null +++ b/src/compositor/meta-surface-actor-wayland.h @@ -0,0 +1,65 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2013 Red Hat + * + * 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. + * + * Written by: + * Jasper St. Pierre + */ + +#ifndef __META_SURFACE_ACTOR_WAYLAND_H__ +#define __META_SURFACE_ACTOR_WAYLAND_H__ + +#include + +#include "meta-surface-actor.h" + +#include "meta-wayland-private.h" + +G_BEGIN_DECLS + +#define META_TYPE_SURFACE_ACTOR_WAYLAND (meta_surface_actor_wayland_get_type ()) +#define META_SURFACE_ACTOR_WAYLAND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_SURFACE_ACTOR_WAYLAND, MetaSurfaceActorWayland)) +#define META_SURFACE_ACTOR_WAYLAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_SURFACE_ACTOR_WAYLAND, MetaSurfaceActorWaylandClass)) +#define META_IS_SURFACE_ACTOR_WAYLAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_SURFACE_ACTOR_WAYLAND)) +#define META_IS_SURFACE_ACTOR_WAYLAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_SURFACE_ACTOR_WAYLAND)) +#define META_SURFACE_ACTOR_WAYLAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_SURFACE_ACTOR_WAYLAND, MetaSurfaceActorWaylandClass)) + +typedef struct _MetaSurfaceActorWayland MetaSurfaceActorWayland; +typedef struct _MetaSurfaceActorWaylandClass MetaSurfaceActorWaylandClass; + +struct _MetaSurfaceActorWayland +{ + MetaSurfaceActor parent; +}; + +struct _MetaSurfaceActorWaylandClass +{ + MetaSurfaceActorClass parent_class; +}; + +GType meta_surface_actor_wayland_get_type (void); + +MetaSurfaceActor * meta_surface_actor_wayland_new (MetaWaylandSurface *surface); + +void meta_surface_actor_wayland_set_buffer (MetaSurfaceActorWayland *self, + MetaWaylandBuffer *buffer); + +G_END_DECLS + +#endif /* __META_SURFACE_ACTOR_WAYLAND_H__ */ diff --git a/src/compositor/meta-surface-actor-x11.c b/src/compositor/meta-surface-actor-x11.c new file mode 100644 index 000000000..8f707d7a8 --- /dev/null +++ b/src/compositor/meta-surface-actor-x11.c @@ -0,0 +1,551 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2013 Red Hat + * + * 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. + * + * Written by: + * Owen Taylor + * Jasper St. Pierre + */ + +#include "config.h" + +#include "meta-surface-actor-x11.h" + +#include +#include +#include + +#include +#include "window-private.h" +#include "meta-shaped-texture-private.h" +#include "meta-cullable.h" + +struct _MetaSurfaceActorX11Private +{ + MetaWindow *window; + + MetaDisplay *display; + + CoglTexture *texture; + Pixmap pixmap; + Damage damage; + + int last_width; + int last_height; + + /* Freeze/thaw accounting */ + guint freeze_count; + + /* This is used to detect fullscreen windows that need to be unredirected */ + guint full_damage_frames_count; + guint does_full_damage : 1; + + /* Other state... */ + guint argb32 : 1; + guint received_damage : 1; + guint size_changed : 1; + guint needs_damage_all : 1; + + guint unredirected : 1; +}; +typedef struct _MetaSurfaceActorX11Private MetaSurfaceActorX11Private; + +static void cullable_iface_init (MetaCullableInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (MetaSurfaceActorX11, meta_surface_actor_x11, META_TYPE_SURFACE_ACTOR, + G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init) + G_ADD_PRIVATE (MetaSurfaceActorX11)) + +static MetaCullableInterface *parent_cullable_iface; + +static void +meta_surface_actor_x11_cull_out (MetaCullable *cullable, + cairo_region_t *unobscured_region, + cairo_region_t *clip_region) +{ + MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (cullable); + MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); + + /* Don't do any culling for the unredirected window */ + if (priv->unredirected) + return; + + parent_cullable_iface->cull_out (cullable, unobscured_region, clip_region); +} + +static void +cullable_iface_init (MetaCullableInterface *iface) +{ + parent_cullable_iface = g_type_interface_peek_parent (iface); + iface->cull_out = meta_surface_actor_x11_cull_out; +} + +static void +free_damage (MetaSurfaceActorX11 *self) +{ + MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); + MetaDisplay *display = priv->display; + Display *xdisplay = meta_display_get_xdisplay (display); + + if (priv->damage == None) + return; + + meta_error_trap_push (display); + XDamageDestroy (xdisplay, priv->damage); + priv->damage = None; + meta_error_trap_pop (display); +} + +static void +detach_pixmap (MetaSurfaceActorX11 *self) +{ + MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); + MetaDisplay *display = priv->display; + Display *xdisplay = meta_display_get_xdisplay (display); + MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self)); + + if (priv->pixmap == None) + return; + + meta_error_trap_push (display); + XFreePixmap (xdisplay, priv->pixmap); + priv->pixmap = None; + meta_error_trap_pop (display); + + meta_shaped_texture_set_texture (stex, NULL); + + cogl_object_unref (priv->texture); + priv->texture = NULL; +} + +static void +set_pixmap (MetaSurfaceActorX11 *self, + Pixmap pixmap) +{ + MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); + + CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ()); + MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self)); + CoglTexture *texture; + + g_assert (priv->pixmap == None); + priv->pixmap = pixmap; + + texture = COGL_TEXTURE (cogl_texture_pixmap_x11_new (ctx, priv->pixmap, FALSE, NULL)); + + if (G_UNLIKELY (!cogl_texture_pixmap_x11_is_using_tfp_extension (COGL_TEXTURE_PIXMAP_X11 (texture)))) + g_warning ("NOTE: Not using GLX TFP!\n"); + + priv->texture = texture; + meta_shaped_texture_set_texture (stex, texture); +} + +static void +update_pixmap (MetaSurfaceActorX11 *self) +{ + MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); + MetaDisplay *display = priv->display; + Display *xdisplay = meta_display_get_xdisplay (display); + + if (priv->size_changed) + { + detach_pixmap (self); + priv->size_changed = FALSE; + } + + if (priv->pixmap == None) + { + Pixmap new_pixmap; + Window xwindow = meta_window_get_toplevel_xwindow (priv->window); + + meta_error_trap_push (display); + new_pixmap = XCompositeNameWindowPixmap (xdisplay, xwindow); + + if (meta_error_trap_pop_with_return (display) != Success) + { + /* Probably a BadMatch if the window isn't viewable; we could + * GrabServer/GetWindowAttributes/NameWindowPixmap/UngrabServer/Sync + * to avoid this, but there's no reason to take two round trips + * when one will do. (We need that Sync if we want to handle failures + * for any reason other than !viewable. That's unlikely, but maybe + * we'll BadAlloc or something.) + */ + new_pixmap = None; + } + + if (new_pixmap == None) + { + meta_verbose ("Unable to get named pixmap for %s\n", + meta_window_get_description (priv->window)); + return; + } + + set_pixmap (self, new_pixmap); + } +} + +static gboolean +is_frozen (MetaSurfaceActorX11 *self) +{ + MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); + return (priv->freeze_count > 0); +} + +static gboolean +is_visible (MetaSurfaceActorX11 *self) +{ + MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); + return (priv->pixmap != None) && !priv->unredirected; +} + +static void +damage_area (MetaSurfaceActorX11 *self, + int x, int y, int width, int height) +{ + MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); + + if (!is_visible (self)) + return; + + cogl_texture_pixmap_x11_update_area (priv->texture, x, y, width, height); + meta_surface_actor_redraw_area (META_SURFACE_ACTOR (self), x, y, width, height); +} + +static void +damage_all (MetaSurfaceActorX11 *self) +{ + MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); + + if (!is_visible (self)) + return; + + damage_area (self, 0, 0, cogl_texture_get_width (priv->texture), cogl_texture_get_height (priv->texture)); +} + +static void +meta_surface_actor_x11_process_damage (MetaSurfaceActor *actor, + int x, int y, int width, int height) +{ + MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor); + MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); + + priv->received_damage = TRUE; + + if (!priv->unredirected && !priv->does_full_damage) + { + MetaRectangle window_rect; + meta_window_get_frame_rect (priv->window, &window_rect); + + if (window_rect.x == x && + window_rect.y == y && + window_rect.width == width && + window_rect.height == height) + priv->full_damage_frames_count++; + else + priv->full_damage_frames_count = 0; + + if (priv->full_damage_frames_count >= 100) + priv->does_full_damage = TRUE; + } + + if (is_frozen (self)) + { + /* The window is frozen due to an effect in progress: we ignore damage + * here on the off chance that this will stop the corresponding + * texture_from_pixmap from being update. + * + * needs_damage_all tracks that some unknown damage happened while the + * window was frozen so that when the window becomes unfrozen we can + * issue a full window update to cover any lost damage. + * + * It should be noted that this is an unreliable mechanism since it's + * quite likely that drivers will aim to provide a zero-copy + * implementation of the texture_from_pixmap extension and in those cases + * any drawing done to the window is always immediately reflected in the + * texture regardless of damage event handling. + */ + priv->needs_damage_all = TRUE; + return; + } + + damage_area (self, x, y, width, height); +} + +static void +meta_surface_actor_x11_pre_paint (MetaSurfaceActor *actor) +{ + MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor); + MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); + MetaDisplay *display = priv->display; + Display *xdisplay = meta_display_get_xdisplay (display); + + if (is_frozen (self)) + return; + + if (priv->received_damage) + { + meta_error_trap_push (display); + XDamageSubtract (xdisplay, priv->damage, None, None); + meta_error_trap_pop (display); + + /* We need to make sure that any X drawing that happens before the + * XDamageSubtract() 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. + * + * Xorg and open source driver specifics: + * + * The X server makes sure to flush drawing to the kernel before + * sending out damage events, but since we use DamageReportBoundingBox + * there may be drawing between the last damage event and the + * XDamageSubtract() that needs to be flushed as well. + * + * Xorg always makes sure that drawing is flushed to the kernel + * before writing events or responses to the client, so any round trip + * request at this point is sufficient to flush the GLX buffers. + */ + XSync (xdisplay, False); + + priv->received_damage = FALSE; + } + + update_pixmap (self); +} + +static void +meta_surface_actor_x11_freeze (MetaSurfaceActor *actor) +{ + MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor); + MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); + + priv->freeze_count ++; +} + +static void +meta_surface_actor_x11_thaw (MetaSurfaceActor *actor) +{ + MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor); + MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); + + if (priv->freeze_count == 0) + { + g_critical ("Error in freeze/thaw accounting."); + return; + } + + priv->freeze_count --; + + /* Since we ignore damage events while a window is frozen for certain effects + * we may need to issue an update_area() covering the whole pixmap if we + * don't know what real damage has happened. */ + if (priv->needs_damage_all) + { + damage_all (self); + priv->needs_damage_all = FALSE; + } +} + +static gboolean +meta_surface_actor_x11_is_frozen (MetaSurfaceActor *actor) +{ + MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor); + return is_frozen (self); +} + +static void +update_is_argb32 (MetaSurfaceActorX11 *self) +{ + MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); + MetaDisplay *display = priv->display; + Display *xdisplay = meta_display_get_xdisplay (display); + + XRenderPictFormat *format; + format = XRenderFindVisualFormat (xdisplay, priv->window->xvisual); + + priv->argb32 = (format && format->type == PictTypeDirect && format->direct.alphaMask); +} + +static gboolean +meta_surface_actor_x11_is_argb32 (MetaSurfaceActor *actor) +{ + MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor); + MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); + + return priv->argb32; +} + +static gboolean +meta_surface_actor_x11_is_visible (MetaSurfaceActor *actor) +{ + MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor); + return is_visible (self); +} + +static gboolean +meta_surface_actor_x11_should_unredirect (MetaSurfaceActor *actor) +{ + MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor); + MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); + + MetaWindow *window = priv->window; + + if (meta_window_requested_dont_bypass_compositor (window)) + return FALSE; + + if (window->opacity != 0xFF) + return FALSE; + + if (window->shape_region != NULL) + return FALSE; + + if (priv->argb32 && !meta_window_requested_bypass_compositor (window)) + return FALSE; + + if (!meta_window_is_monitor_sized (window)) + return FALSE; + + if (meta_window_requested_bypass_compositor (window)) + return TRUE; + + if (meta_window_is_override_redirect (window)) + return TRUE; + + if (priv->does_full_damage) + return TRUE; + + return FALSE; +} + +static void +sync_unredirected (MetaSurfaceActorX11 *self) +{ + MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); + MetaDisplay *display = priv->display; + Display *xdisplay = meta_display_get_xdisplay (display); + Window xwindow = meta_window_get_toplevel_xwindow (priv->window); + + meta_error_trap_push (display); + + if (priv->unredirected) + { + detach_pixmap (self); + XCompositeUnredirectWindow (xdisplay, xwindow, CompositeRedirectManual); + } + else + { + XCompositeRedirectWindow (xdisplay, xwindow, CompositeRedirectManual); + } + + meta_error_trap_pop (display); +} + +static void +meta_surface_actor_x11_set_unredirected (MetaSurfaceActor *actor, + gboolean unredirected) +{ + MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor); + MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); + + if (priv->unredirected == unredirected) + return; + + priv->unredirected = unredirected; + sync_unredirected (self); +} + +static void +meta_surface_actor_x11_dispose (GObject *object) +{ + MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (object); + + detach_pixmap (self); + free_damage (self); + + G_OBJECT_CLASS (meta_surface_actor_x11_parent_class)->dispose (object); +} + +static void +meta_surface_actor_x11_class_init (MetaSurfaceActorX11Class *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + MetaSurfaceActorClass *surface_actor_class = META_SURFACE_ACTOR_CLASS (klass); + + object_class->dispose = meta_surface_actor_x11_dispose; + + surface_actor_class->process_damage = meta_surface_actor_x11_process_damage; + surface_actor_class->pre_paint = meta_surface_actor_x11_pre_paint; + surface_actor_class->is_argb32 = meta_surface_actor_x11_is_argb32; + surface_actor_class->is_visible = meta_surface_actor_x11_is_visible; + + surface_actor_class->freeze = meta_surface_actor_x11_freeze; + surface_actor_class->thaw = meta_surface_actor_x11_thaw; + surface_actor_class->is_frozen = meta_surface_actor_x11_is_frozen; + + surface_actor_class->should_unredirect = meta_surface_actor_x11_should_unredirect; + surface_actor_class->set_unredirected = meta_surface_actor_x11_set_unredirected; +} + +static void +meta_surface_actor_x11_init (MetaSurfaceActorX11 *self) +{ + MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); + + priv->last_width = -1; + priv->last_height = -1; +} + +MetaSurfaceActor * +meta_surface_actor_x11_new (MetaWindow *window) +{ + MetaSurfaceActorX11 *self = g_object_new (META_TYPE_SURFACE_ACTOR_X11, NULL); + MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); + MetaDisplay *display = meta_window_get_display (window); + Display *xdisplay = meta_display_get_xdisplay (display); + Window xwindow = meta_window_get_toplevel_xwindow (window); + + g_assert (!meta_is_wayland_compositor ()); + + priv->window = window; + priv->display = display; + + priv->damage = XDamageCreate (xdisplay, xwindow, XDamageReportBoundingBox); + update_is_argb32 (self); + + priv->unredirected = FALSE; + sync_unredirected (self); + + return META_SURFACE_ACTOR (self); +} + +void +meta_surface_actor_x11_set_size (MetaSurfaceActorX11 *self, + int width, int height) +{ + MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); + + if (priv->last_width == width && + priv->last_height == height) + return; + + priv->size_changed = TRUE; + priv->last_width = width; + priv->last_height = height; +} diff --git a/src/compositor/meta-surface-actor-x11.h b/src/compositor/meta-surface-actor-x11.h new file mode 100644 index 000000000..0e692ee0f --- /dev/null +++ b/src/compositor/meta-surface-actor-x11.h @@ -0,0 +1,69 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2013 Red Hat + * + * 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. + * + * Written by: + * Owen Taylor + * Jasper St. Pierre + */ + +#ifndef __META_SURFACE_ACTOR_X11_H__ +#define __META_SURFACE_ACTOR_X11_H__ + +#include + +#include "meta-surface-actor.h" + +#include + +#include +#include + +G_BEGIN_DECLS + +#define META_TYPE_SURFACE_ACTOR_X11 (meta_surface_actor_x11_get_type ()) +#define META_SURFACE_ACTOR_X11(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_SURFACE_ACTOR_X11, MetaSurfaceActorX11)) +#define META_SURFACE_ACTOR_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_SURFACE_ACTOR_X11, MetaSurfaceActorX11Class)) +#define META_IS_SURFACE_ACTOR_X11(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_SURFACE_ACTOR_X11)) +#define META_IS_SURFACE_ACTOR_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_SURFACE_ACTOR_X11)) +#define META_SURFACE_ACTOR_X11_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_SURFACE_ACTOR_X11, MetaSurfaceActorX11Class)) + +typedef struct _MetaSurfaceActorX11 MetaSurfaceActorX11; +typedef struct _MetaSurfaceActorX11Class MetaSurfaceActorX11Class; + +struct _MetaSurfaceActorX11 +{ + MetaSurfaceActor parent; +}; + +struct _MetaSurfaceActorX11Class +{ + MetaSurfaceActorClass parent_class; +}; + +GType meta_surface_actor_x11_get_type (void); + +MetaSurfaceActor * meta_surface_actor_x11_new (MetaWindow *window); + +void meta_surface_actor_x11_set_size (MetaSurfaceActorX11 *self, + int width, int height); + +G_END_DECLS + +#endif /* __META_SURFACE_ACTOR_X11_H__ */ diff --git a/src/compositor/meta-surface-actor.c b/src/compositor/meta-surface-actor.c index 8d3f5b4d5..9d21c749d 100644 --- a/src/compositor/meta-surface-actor.c +++ b/src/compositor/meta-surface-actor.c @@ -10,20 +10,18 @@ */ #include -#include -#include -#include -#include + #include "meta-surface-actor.h" + +#include +#include #include "meta-wayland-private.h" #include "meta-cullable.h" - #include "meta-shaped-texture-private.h" struct _MetaSurfaceActorPrivate { MetaShapedTexture *texture; - MetaWaylandBuffer *buffer; /* The region that is visible, used to optimize out redraws */ cairo_region_t *unobscured_region; @@ -31,8 +29,8 @@ struct _MetaSurfaceActorPrivate static void cullable_iface_init (MetaCullableInterface *iface); -G_DEFINE_TYPE_WITH_CODE (MetaSurfaceActor, meta_surface_actor, CLUTTER_TYPE_ACTOR, - G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init)); +G_DEFINE_ABSTRACT_TYPE_WITH_CODE (MetaSurfaceActor, meta_surface_actor, CLUTTER_TYPE_ACTOR, + G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init)); static gboolean meta_surface_actor_get_paint_volume (ClutterActor *actor, @@ -160,30 +158,6 @@ meta_surface_actor_get_texture (MetaSurfaceActor *self) return self->priv->texture; } -static void -update_area (MetaSurfaceActor *self, - int x, int y, int width, int height) -{ - MetaSurfaceActorPrivate *priv = self->priv; - - if (meta_is_wayland_compositor ()) - { - struct wl_resource *resource = priv->buffer->resource; - struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get (resource); - - if (shm_buffer) - { - CoglTexture2D *texture = COGL_TEXTURE_2D (priv->buffer->texture); - cogl_wayland_texture_set_region_from_shm_buffer (texture, x, y, width, height, shm_buffer, x, y, 0, NULL); - } - } - else - { - CoglTexturePixmapX11 *texture = COGL_TEXTURE_PIXMAP_X11 (meta_shaped_texture_get_texture (priv->texture)); - cogl_texture_pixmap_x11_update_area (texture, x, y, width, height); - } -} - static cairo_region_t * effective_unobscured_region (MetaSurfaceActor *self) { @@ -193,29 +167,11 @@ effective_unobscured_region (MetaSurfaceActor *self) } gboolean -meta_surface_actor_damage_all (MetaSurfaceActor *self) -{ - MetaSurfaceActorPrivate *priv = self->priv; - CoglTexture *texture = meta_shaped_texture_get_texture (priv->texture); - - update_area (self, 0, 0, cogl_texture_get_width (texture), cogl_texture_get_height (texture)); - return meta_shaped_texture_update_area (priv->texture, - 0, 0, - cogl_texture_get_width (texture), - cogl_texture_get_height (texture), - effective_unobscured_region (self)); -} - -gboolean -meta_surface_actor_damage_area (MetaSurfaceActor *self, - int x, - int y, - int width, - int height) +meta_surface_actor_redraw_area (MetaSurfaceActor *self, + int x, int y, int width, int height) { MetaSurfaceActorPrivate *priv = self->priv; - update_area (self, x, y, width, height); return meta_shaped_texture_update_area (priv->texture, x, y, width, height, effective_unobscured_region (self)); @@ -232,27 +188,6 @@ meta_surface_actor_is_obscured (MetaSurfaceActor *self) return FALSE; } -void -meta_surface_actor_attach_wayland_buffer (MetaSurfaceActor *self, - MetaWaylandBuffer *buffer) -{ - MetaSurfaceActorPrivate *priv = self->priv; - priv->buffer = buffer; - - if (buffer) - meta_shaped_texture_set_texture (priv->texture, buffer->texture); - else - meta_shaped_texture_set_texture (priv->texture, NULL); -} - -void -meta_surface_actor_set_texture (MetaSurfaceActor *self, - CoglTexture *texture) -{ - MetaSurfaceActorPrivate *priv = self->priv; - meta_shaped_texture_set_texture (priv->texture, texture); -} - void meta_surface_actor_set_input_region (MetaSurfaceActor *self, cairo_region_t *region) @@ -269,8 +204,58 @@ meta_surface_actor_set_opaque_region (MetaSurfaceActor *self, meta_shaped_texture_set_opaque_region (priv->texture, region); } -MetaSurfaceActor * -meta_surface_actor_new (void) +void +meta_surface_actor_process_damage (MetaSurfaceActor *actor, + int x, int y, int width, int height) { - return g_object_new (META_TYPE_SURFACE_ACTOR, NULL); + META_SURFACE_ACTOR_GET_CLASS (actor)->process_damage (actor, x, y, width, height); +} + +void +meta_surface_actor_pre_paint (MetaSurfaceActor *actor) +{ + META_SURFACE_ACTOR_GET_CLASS (actor)->pre_paint (actor); +} + +gboolean +meta_surface_actor_is_argb32 (MetaSurfaceActor *actor) +{ + return META_SURFACE_ACTOR_GET_CLASS (actor)->is_argb32 (actor); +} + +gboolean +meta_surface_actor_is_visible (MetaSurfaceActor *actor) +{ + return META_SURFACE_ACTOR_GET_CLASS (actor)->is_visible (actor); +} + +void +meta_surface_actor_freeze (MetaSurfaceActor *actor) +{ + META_SURFACE_ACTOR_GET_CLASS (actor)->freeze (actor); +} + +void +meta_surface_actor_thaw (MetaSurfaceActor *actor) +{ + META_SURFACE_ACTOR_GET_CLASS (actor)->thaw (actor); +} + +gboolean +meta_surface_actor_is_frozen (MetaSurfaceActor *actor) +{ + return META_SURFACE_ACTOR_GET_CLASS (actor)->is_frozen (actor); +} + +gboolean +meta_surface_actor_should_unredirect (MetaSurfaceActor *actor) +{ + return META_SURFACE_ACTOR_GET_CLASS (actor)->should_unredirect (actor); +} + +void +meta_surface_actor_set_unredirected (MetaSurfaceActor *actor, + gboolean unredirected) +{ + META_SURFACE_ACTOR_GET_CLASS (actor)->set_unredirected (actor, unredirected); } diff --git a/src/compositor/meta-surface-actor.h b/src/compositor/meta-surface-actor.h index 0f5fd8f04..f9d458c53 100644 --- a/src/compositor/meta-surface-actor.h +++ b/src/compositor/meta-surface-actor.h @@ -6,7 +6,6 @@ #include #include -#include "meta-wayland-types.h" G_BEGIN_DECLS @@ -25,6 +24,20 @@ struct _MetaSurfaceActorClass { /*< private >*/ ClutterActorClass parent_class; + + void (* process_damage) (MetaSurfaceActor *actor, + int x, int y, int width, int height); + void (* pre_paint) (MetaSurfaceActor *actor); + gboolean (* is_argb32) (MetaSurfaceActor *actor); + gboolean (* is_visible) (MetaSurfaceActor *actor); + + void (* freeze) (MetaSurfaceActor *actor); + void (* thaw) (MetaSurfaceActor *actor); + gboolean (* is_frozen) (MetaSurfaceActor *actor); + + gboolean (* should_unredirect) (MetaSurfaceActor *actor); + void (* set_unredirected) (MetaSurfaceActor *actor, + gboolean unredirected); }; struct _MetaSurfaceActor @@ -36,31 +49,35 @@ struct _MetaSurfaceActor GType meta_surface_actor_get_type (void); -MetaSurfaceActor *meta_surface_actor_new (void); - cairo_surface_t *meta_surface_actor_get_image (MetaSurfaceActor *self, cairo_rectangle_int_t *clip); MetaShapedTexture *meta_surface_actor_get_texture (MetaSurfaceActor *self); -gboolean meta_surface_actor_damage_all (MetaSurfaceActor *self); -gboolean meta_surface_actor_damage_area (MetaSurfaceActor *self, - int x, - int y, - int width, - int height); - gboolean meta_surface_actor_is_obscured (MetaSurfaceActor *self); -void meta_surface_actor_set_texture (MetaSurfaceActor *self, - CoglTexture *texture); -void meta_surface_actor_attach_wayland_buffer (MetaSurfaceActor *self, - MetaWaylandBuffer *buffer); void meta_surface_actor_set_input_region (MetaSurfaceActor *self, cairo_region_t *region); void meta_surface_actor_set_opaque_region (MetaSurfaceActor *self, cairo_region_t *region); +gboolean meta_surface_actor_redraw_area (MetaSurfaceActor *actor, + int x, int y, int width, int height); + +void meta_surface_actor_process_damage (MetaSurfaceActor *actor, + int x, int y, int width, int height); +void meta_surface_actor_pre_paint (MetaSurfaceActor *actor); +gboolean meta_surface_actor_is_argb32 (MetaSurfaceActor *actor); +gboolean meta_surface_actor_is_visible (MetaSurfaceActor *actor); + +void meta_surface_actor_freeze (MetaSurfaceActor *actor); +void meta_surface_actor_thaw (MetaSurfaceActor *actor); +gboolean meta_surface_actor_is_frozen (MetaSurfaceActor *actor); + +gboolean meta_surface_actor_should_unredirect (MetaSurfaceActor *actor); +void meta_surface_actor_set_unredirected (MetaSurfaceActor *actor, + gboolean unredirected); + G_END_DECLS #endif /* META_SURFACE_ACTOR_PRIVATE_H */ diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 9d6500072..fe09ace3c 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -10,10 +10,6 @@ #include -#include -#include -#include - #include #include #include /* for gdk_rectangle_union() */ @@ -30,13 +26,15 @@ #include "meta-shaped-texture-private.h" #include "meta-shadow-factory-private.h" #include "meta-window-actor-private.h" -#include "meta-surface-actor.h" #include "meta-texture-rectangle.h" #include "region-utils.h" #include "meta-wayland-private.h" #include "monitor-private.h" #include "meta-cullable.h" +#include "meta-surface-actor.h" +#include "meta-surface-actor-x11.h" + struct _MetaWindowActorPrivate { MetaWindow *window; @@ -63,19 +61,13 @@ struct _MetaWindowActorPrivate /* The region we should clip to when painting the shadow */ cairo_region_t *shadow_clip; - guint send_frame_messages_timer; - gint64 frame_drawn_time; - /* Extracted size-invariant shape used for shadows */ MetaWindowShape *shadow_shape; - - gint last_width; - gint last_height; - - gint freeze_count; - char * shadow_class; + guint send_frame_messages_timer; + gint64 frame_drawn_time; + /* * These need to be counters rather than flags, since more plugins * can implement same effect; the practicality of stacking effects @@ -90,11 +82,7 @@ struct _MetaWindowActorPrivate /* List of FrameData for recent frames */ GList *frames; - Pixmap back_pixmap; /* Not used in wayland compositor mode */ - Damage damage; /* Not used in wayland compositor mode */ - guint visible : 1; - guint argb32 : 1; guint disposed : 1; guint redecorating : 1; @@ -111,24 +99,7 @@ struct _MetaWindowActorPrivate guint no_shadow : 1; - - /* - * None of these are used in wayland compositor mode... - */ - - guint needs_damage_all : 1; - guint received_x11_damage : 1; - - guint needs_pixmap : 1; - - guint x11_size_changed : 1; guint updates_frozen : 1; - - guint unredirected : 1; - - /* This is used to detect fullscreen windows that need to be unredirected */ - guint full_damage_frames_count; - guint does_full_damage : 1; }; typedef struct _FrameData FrameData; @@ -165,7 +136,6 @@ static gboolean meta_window_actor_get_paint_volume (ClutterActor *actor, ClutterPaintVolume *volume); -static void meta_window_actor_detach_x11_pixmap (MetaWindowActor *self); static gboolean meta_window_actor_has_shadow (MetaWindowActor *self); static void meta_window_actor_handle_updates (MetaWindowActor *self); @@ -256,9 +226,6 @@ window_decorated_notify (MetaWindow *mw, { MetaWindowActor *self = META_WINDOW_ACTOR (data); MetaWindowActorPrivate *priv = self->priv; - MetaScreen *screen = priv->screen; - MetaDisplay *display = meta_screen_get_display (screen); - Display *xdisplay = meta_display_get_xdisplay (display); /* * Basically, we have to reconstruct the the internals of this object @@ -266,23 +233,6 @@ window_decorated_notify (MetaWindow *mw, */ priv->redecorating = TRUE; - if (!meta_is_wayland_compositor ()) - { - meta_window_actor_detach_x11_pixmap (self); - - /* - * First of all, clean up any resources we are currently using and will - * be replacing. - */ - if (priv->damage != None) - { - meta_error_trap_push (display); - XDamageDestroy (xdisplay, priv->damage); - meta_error_trap_pop (display); - priv->damage = None; - } - } - /* * Recreate the contents. */ @@ -307,13 +257,52 @@ surface_allocation_changed_notify (ClutterActor *actor, meta_window_actor_update_shape (self); } +static gboolean +is_argb32 (MetaWindowActor *self) +{ + MetaWindowActorPrivate *priv = self->priv; + return meta_surface_actor_is_argb32 (priv->surface); +} + static gboolean is_non_opaque (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; MetaWindow *window = priv->window; - return priv->argb32 || (window->opacity != 0xFF); + return is_argb32 (self) || (window->opacity != 0xFF); +} + +static gboolean +is_frozen (MetaWindowActor *self) +{ + MetaWindowActorPrivate *priv = self->priv; + return meta_surface_actor_is_frozen (priv->surface); +} + +static void +meta_window_actor_freeze (MetaWindowActor *self) +{ + MetaWindowActorPrivate *priv = self->priv; + meta_surface_actor_freeze (priv->surface); +} + +static void +meta_window_actor_thaw (MetaWindowActor *self) +{ + MetaWindowActorPrivate *priv = self->priv; + + meta_surface_actor_thaw (priv->surface); + + if (meta_surface_actor_is_frozen (priv->surface)) + return; + + /* We sometimes ignore moves and resizes on frozen windows */ + meta_window_actor_sync_actor_geometry (self, FALSE); + + /* We do this now since we might be going right back into the + * frozen state */ + meta_window_actor_handle_updates (self); } static void @@ -322,38 +311,15 @@ meta_window_actor_constructed (GObject *object) MetaWindowActor *self = META_WINDOW_ACTOR (object); MetaWindowActorPrivate *priv = self->priv; MetaWindow *window = priv->window; - Window xwindow = meta_window_get_toplevel_xwindow (window); - MetaScreen *screen = meta_window_get_screen (window); - MetaDisplay *display = meta_screen_get_display (screen); - Display *xdisplay = meta_display_get_xdisplay (display); - priv->screen = screen; - - if (!meta_is_wayland_compositor ()) - priv->damage = XDamageCreate (xdisplay, xwindow, - XDamageReportBoundingBox); - - if (window->client_type == META_WINDOW_CLIENT_TYPE_X11) - { - XRenderPictFormat *format; - - format = XRenderFindVisualFormat (xdisplay, window->xvisual); - - if (format && format->type == PictTypeDirect && format->direct.alphaMask) - priv->argb32 = TRUE; - } - else - { - /* XXX: parse shm formats to determine argb32 */ - priv->argb32 = TRUE; - } + priv->screen = window->screen; if (!priv->surface) { if (window->surface) priv->surface = window->surface->surface_actor; else - priv->surface = meta_surface_actor_new (); + priv->surface = meta_surface_actor_x11_new (window); g_object_ref_sink (priv->surface); clutter_actor_add_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface)); @@ -376,8 +342,6 @@ meta_window_actor_dispose (GObject *object) MetaWindowActor *self = META_WINDOW_ACTOR (object); MetaWindowActorPrivate *priv = self->priv; MetaScreen *screen; - MetaDisplay *display; - Display *xdisplay; MetaCompScreen *info; if (priv->disposed) @@ -388,9 +352,6 @@ meta_window_actor_dispose (GObject *object) screen = priv->screen; info = meta_screen_get_compositor_data (screen); - if (!meta_is_wayland_compositor ()) - meta_window_actor_detach_x11_pixmap (self); - if (priv->send_frame_messages_timer != 0) { g_source_remove (priv->send_frame_messages_timer); @@ -405,18 +366,6 @@ meta_window_actor_dispose (GObject *object) g_clear_pointer (&priv->unfocused_shadow, meta_shadow_unref); g_clear_pointer (&priv->shadow_shape, meta_window_shape_unref); - if (!meta_is_wayland_compositor () && priv->damage != None) - { - display = meta_screen_get_display (screen); - xdisplay = meta_display_get_xdisplay (display); - - meta_error_trap_push (display); - XDamageDestroy (xdisplay, priv->damage); - meta_error_trap_pop (display); - - priv->damage = None; - } - info->windows = g_list_remove (info->windows, (gconstpointer) self); g_clear_object (&priv->window); @@ -834,13 +783,6 @@ meta_window_actor_is_destroyed (MetaWindowActor *self) return self->priv->disposed; } -static void -meta_window_actor_freeze (MetaWindowActor *self) -{ - if (!meta_is_wayland_compositor ()) - self->priv->freeze_count++; -} - static gboolean send_frame_messages_timeout (gpointer data) { @@ -895,56 +837,6 @@ queue_send_frame_messages_timeout (MetaWindowActor *self) priv->send_frame_messages_timer = g_timeout_add_full (META_PRIORITY_REDRAW, offset, send_frame_messages_timeout, self, NULL); } -static void -meta_window_actor_damage_all (MetaWindowActor *self) -{ - MetaWindowActorPrivate *priv = self->priv; - gboolean redraw_queued; - - if (!priv->needs_damage_all) - return; - - if (priv->needs_pixmap) - return; - - redraw_queued = meta_surface_actor_damage_all (priv->surface); - - priv->repaint_scheduled = priv->repaint_scheduled || redraw_queued; - priv->needs_damage_all = FALSE; -} - -static void -meta_window_actor_thaw (MetaWindowActor *self) -{ - if (!meta_is_wayland_compositor ()) - { - self->priv->freeze_count--; - - if (G_UNLIKELY (self->priv->freeze_count < 0)) - { - g_warning ("Error in freeze/thaw accounting."); - self->priv->freeze_count = 0; - return; - } - - if (self->priv->freeze_count) - return; - - /* We sometimes ignore moves and resizes on frozen windows */ - meta_window_actor_sync_actor_geometry (self, FALSE); - - /* We do this now since we might be going right back into the - * frozen state */ - meta_window_actor_handle_updates (self); - - /* Since we ignore damage events while a window is frozen for certain effects - * we may need to issue an update_area() covering the whole pixmap if we - * don't know what real damage has happened. */ - if (self->priv->needs_damage_all) - meta_window_actor_damage_all (self); - } -} - void meta_window_actor_queue_frame_drawn (MetaWindowActor *self, gboolean no_delay_frame) @@ -999,33 +891,6 @@ meta_window_actor_effect_in_progress (MetaWindowActor *self) self->priv->destroy_in_progress); } -static gboolean -is_frozen (MetaWindowActor *self) -{ - return self->priv->freeze_count ? TRUE : FALSE; -} - -static void -meta_window_actor_queue_create_x11_pixmap (MetaWindowActor *self) -{ - MetaWindowActorPrivate *priv = self->priv; - - priv->needs_pixmap = TRUE; - - if (is_frozen (self)) - return; - - /* This will cause the compositor paint function to be run - * if the actor is visible or a clone of the actor is visible. - * if the actor isn't visible in any way, then we don't - * need to repair the window anyways, and can wait until - * the stage is redrawn for some other reason - * - * The compositor paint function repairs all windows. - */ - clutter_actor_queue_redraw (CLUTTER_ACTOR (priv->surface)); -} - static gboolean is_freeze_thaw_effect (gulong event) { @@ -1106,12 +971,6 @@ meta_window_actor_after_effects (MetaWindowActor *self) meta_window_actor_sync_visibility (self); meta_window_actor_sync_actor_geometry (self, FALSE); - - if (!meta_is_wayland_compositor ()) - { - if (priv->needs_pixmap) - clutter_actor_queue_redraw (CLUTTER_ACTOR (priv->surface)); - } } void @@ -1186,95 +1045,19 @@ meta_window_actor_effect_completed (MetaWindowActor *self, meta_window_actor_after_effects (self); } -/* Called to drop our reference to a window backing pixmap that we - * previously obtained with XCompositeNameWindowPixmap. We do this - * when the window is unmapped or when we want to update to a new - * pixmap for a new size. - */ -static void -meta_window_actor_detach_x11_pixmap (MetaWindowActor *self) -{ - MetaWindowActorPrivate *priv = self->priv; - MetaScreen *screen = priv->screen; - MetaDisplay *display = meta_screen_get_display (screen); - Display *xdisplay = meta_display_get_xdisplay (display); - - if (!priv->back_pixmap) - return; - - /* Get rid of all references to the pixmap before freeing it; it's unclear whether - * you are supposed to be able to free a GLXPixmap after freeing the underlying - * pixmap, but it certainly doesn't work with current DRI/Mesa - */ - meta_surface_actor_set_texture (priv->surface, NULL); - cogl_flush(); - - XFreePixmap (xdisplay, priv->back_pixmap); - priv->back_pixmap = None; - - meta_window_actor_queue_create_x11_pixmap (self); -} - gboolean meta_window_actor_should_unredirect (MetaWindowActor *self) { - MetaWindow *metaWindow = meta_window_actor_get_meta_window (self); MetaWindowActorPrivate *priv = self->priv; - - if (meta_is_wayland_compositor ()) - return FALSE; - - if (meta_window_requested_dont_bypass_compositor (metaWindow)) - return FALSE; - - if (metaWindow->opacity != 0xFF) - return FALSE; - - if (metaWindow->shape_region != NULL) - return FALSE; - - if (priv->argb32 && !meta_window_requested_bypass_compositor (metaWindow)) - return FALSE; - - if (!meta_window_is_monitor_sized (metaWindow)) - return FALSE; - - if (meta_window_requested_bypass_compositor (metaWindow)) - return TRUE; - - if (meta_window_is_override_redirect (metaWindow)) - return TRUE; - - if (priv->does_full_damage) - return TRUE; - - return FALSE; + return meta_surface_actor_should_unredirect (priv->surface); } void meta_window_actor_set_unredirected (MetaWindowActor *self, gboolean unredirected) { - MetaWindow *metaWindow = meta_window_actor_get_meta_window (self); - MetaDisplay *display = meta_window_get_display (metaWindow); - - Display *xdisplay = meta_display_get_xdisplay (display); - Window xwin = meta_window_get_toplevel_xwindow (metaWindow); - - meta_error_trap_push (display); - - if (unredirected) - { - XCompositeUnredirectWindow (xdisplay, xwin, CompositeRedirectManual); - } - else - { - XCompositeRedirectWindow (xdisplay, xwin, CompositeRedirectManual); - meta_window_actor_detach_x11_pixmap (self); - } - - self->priv->unredirected = unredirected; - meta_error_trap_pop (display); + MetaWindowActorPrivate *priv = self->priv; + meta_surface_actor_set_unredirected (priv->surface, unredirected); } void @@ -1328,19 +1111,11 @@ meta_window_actor_sync_actor_geometry (MetaWindowActor *self, meta_window_get_input_rect (priv->window, &window_rect); - /* When running as a display server we catch size changes when new - buffers are attached */ - if (!meta_is_wayland_compositor ()) - { - if (priv->last_width != window_rect.width || - priv->last_height != window_rect.height) - { - priv->x11_size_changed = TRUE; - - priv->last_width = window_rect.width; - priv->last_height = window_rect.height; - } - } + /* When running as a Wayland compositor we catch size changes when new + * buffers are attached */ + if (META_IS_SURFACE_ACTOR_X11 (priv->surface)) + meta_surface_actor_x11_set_size (META_SURFACE_ACTOR_X11 (priv->surface), + window_rect.width, window_rect.height); /* Normally we want freezing a window to also freeze its position; this allows * windows to atomically move and resize together, either under app control, @@ -1352,15 +1127,6 @@ meta_window_actor_sync_actor_geometry (MetaWindowActor *self, if (is_frozen (self) && !did_placement) return; - if (!meta_is_wayland_compositor ()) - { - if (priv->x11_size_changed) - { - meta_window_actor_queue_create_x11_pixmap (self); - meta_window_actor_update_shape (self); - } - } - if (meta_window_actor_effect_in_progress (self)) return; @@ -1528,14 +1294,10 @@ meta_window_actor_new (MetaWindow *window) priv = self->priv; - if (!meta_is_wayland_compositor ()) + meta_window_actor_set_updates_frozen (self, meta_window_updates_are_frozen (priv->window)); + + if (META_IS_SURFACE_ACTOR_X11 (priv->surface)) { - priv->last_width = -1; - priv->last_height = -1; - - meta_window_actor_set_updates_frozen (self, - meta_window_updates_are_frozen (priv->window)); - /* If a window doesn't start off with updates frozen, we should * we should send a _NET_WM_FRAME_DRAWN immediately after the first drawn. */ @@ -1646,11 +1408,6 @@ meta_window_actor_cull_out (MetaCullable *cullable, cairo_region_t *clip_region) { MetaWindowActor *self = META_WINDOW_ACTOR (cullable); - MetaWindowActorPrivate *priv = self->priv; - - /* Don't do any culling for the unredirected window */ - if (priv->unredirected) - return; meta_cullable_cull_out_children (cullable, unobscured_region, clip_region); meta_window_actor_set_clip_region_beneath (self, clip_region); @@ -1674,74 +1431,6 @@ cullable_iface_init (MetaCullableInterface *iface) iface->reset_culling = meta_window_actor_reset_culling; } -/* When running as a wayland compositor we don't make requests for - * replacement pixmaps when resizing windows, we will instead be - * asked to attach replacement buffers by the clients. */ -static void -check_needs_x11_pixmap (MetaWindowActor *self) -{ - MetaWindowActorPrivate *priv = self->priv; - MetaScreen *screen = priv->screen; - MetaDisplay *display = meta_screen_get_display (screen); - Display *xdisplay = meta_display_get_xdisplay (display); - MetaCompScreen *info = meta_screen_get_compositor_data (screen); - Window xwindow = meta_window_get_toplevel_xwindow (priv->window); - - if (!priv->needs_pixmap) - return; - - if (xwindow == meta_screen_get_xroot (screen) || - xwindow == clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage))) - return; - - if (priv->x11_size_changed) - { - meta_window_actor_detach_x11_pixmap (self); - priv->x11_size_changed = FALSE; - } - - meta_error_trap_push (display); - - if (priv->back_pixmap == None) - { - CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ()); - CoglTexture *texture; - - meta_error_trap_push (display); - - priv->back_pixmap = XCompositeNameWindowPixmap (xdisplay, xwindow); - - if (meta_error_trap_pop_with_return (display) != Success) - { - /* Probably a BadMatch if the window isn't viewable; we could - * GrabServer/GetWindowAttributes/NameWindowPixmap/UngrabServer/Sync - * to avoid this, but there's no reason to take two round trips - * when one will do. (We need that Sync if we want to handle failures - * for any reason other than !viewable. That's unlikely, but maybe - * we'll BadAlloc or something.) - */ - priv->back_pixmap = None; - } - - if (priv->back_pixmap == None) - { - meta_verbose ("Unable to get named pixmap for %p\n", self); - goto out; - } - - texture = COGL_TEXTURE (cogl_texture_pixmap_x11_new (ctx, priv->back_pixmap, FALSE, NULL)); - if (G_UNLIKELY (!cogl_texture_pixmap_x11_is_using_tfp_extension (COGL_TEXTURE_PIXMAP_X11 (texture)))) - g_warning ("NOTE: Not using GLX TFP!\n"); - - meta_surface_actor_set_texture (META_SURFACE_ACTOR (priv->surface), texture); - } - - priv->needs_pixmap = FALSE; - - out: - meta_error_trap_pop (display); -} - static void check_needs_shadow (MetaWindowActor *self) { @@ -1809,63 +1498,14 @@ meta_window_actor_process_x11_damage (MetaWindowActor *self, XDamageNotifyEvent *event) { MetaWindowActorPrivate *priv = self->priv; - MetaCompScreen *info = meta_screen_get_compositor_data (priv->screen); - gboolean redraw_queued; - priv->received_x11_damage = TRUE; - - if (meta_window_is_fullscreen (priv->window) && g_list_last (info->windows)->data == self && !priv->unredirected) - { - MetaRectangle window_rect; - meta_window_get_frame_rect (priv->window, &window_rect); - - if (window_rect.x == event->area.x && - window_rect.y == event->area.y && - window_rect.width == event->area.width && - window_rect.height == event->area.height) - priv->full_damage_frames_count++; - else - priv->full_damage_frames_count = 0; - - if (priv->full_damage_frames_count >= 100) - priv->does_full_damage = TRUE; - } - - /* Drop damage event for unredirected windows */ - if (priv->unredirected) - return; - - if (is_frozen (self)) - { - /* The window is frozen due to an effect in progress: we ignore damage - * here on the off chance that this will stop the corresponding - * texture_from_pixmap from being update. - * - * needs_damage_all tracks that some unknown damage happened while the - * window was frozen so that when the window becomes unfrozen we can - * issue a full window update to cover any lost damage. - * - * It should be noted that this is an unreliable mechanism since it's - * quite likely that drivers will aim to provide a zero-copy - * implementation of the texture_from_pixmap extension and in those cases - * any drawing done to the window is always immediately reflected in the - * texture regardless of damage event handling. - */ - priv->needs_damage_all = TRUE; - return; - } - - if (priv->needs_pixmap) - return; - - redraw_queued = meta_surface_actor_damage_area (priv->surface, - event->area.x, - event->area.y, - event->area.width, - event->area.height); - - priv->repaint_scheduled = priv->repaint_scheduled || redraw_queued; + g_assert (!meta_is_wayland_compositor ()); + meta_surface_actor_process_damage (priv->surface, + event->area.x, + event->area.y, + event->area.width, + event->area.height); } void @@ -2093,8 +1733,9 @@ meta_window_actor_update_opaque_region (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; cairo_region_t *opaque_region; + gboolean argb32 = is_argb32 (self); - if (priv->argb32 && priv->window->opaque_region != NULL) + if (argb32 && priv->window->opaque_region != NULL) { MetaFrameBorders borders; @@ -2114,7 +1755,7 @@ meta_window_actor_update_opaque_region (MetaWindowActor *self) cairo_region_translate (opaque_region, borders.total.left, borders.total.top); cairo_region_intersect (opaque_region, priv->shape_region); } - else if (priv->argb32) + else if (argb32) opaque_region = NULL; else opaque_region = cairo_region_reference (priv->shape_region); @@ -2171,9 +1812,6 @@ static void meta_window_actor_handle_updates (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; - MetaScreen *screen = priv->screen; - MetaDisplay *display = meta_screen_get_display (screen); - Display *xdisplay = meta_display_get_xdisplay (display); if (is_frozen (self)) { @@ -2182,45 +1820,10 @@ meta_window_actor_handle_updates (MetaWindowActor *self) return; } - if (!meta_is_wayland_compositor ()) - { - if (priv->unredirected) - { - /* Nothing to do here until/if the window gets redirected again */ - return; - } + meta_surface_actor_pre_paint (priv->surface); - if (priv->received_x11_damage) - { - meta_error_trap_push (display); - XDamageSubtract (xdisplay, priv->damage, None, None); - meta_error_trap_pop (display); - - /* We need to make sure that any X drawing that happens before the - * XDamageSubtract() 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. - * - * Xorg and open source driver specifics: - * - * The X server makes sure to flush drawing to the kernel before - * sending out damage events, but since we use DamageReportBoundingBox - * there may be drawing between the last damage event and the - * XDamageSubtract() that needs to be flushed as well. - * - * Xorg always makes sure that drawing is flushed to the kernel - * before writing events or responses to the client, so any round trip - * request at this point is sufficient to flush the GLX buffers. - */ - XSync (xdisplay, False); - - priv->received_x11_damage = FALSE; - } - - check_needs_x11_pixmap (self); - } + if (!meta_surface_actor_is_visible (priv->surface)) + return; check_needs_reshape (self); check_needs_shadow (self); @@ -2409,20 +2012,16 @@ void meta_window_actor_set_updates_frozen (MetaWindowActor *self, gboolean updates_frozen) { - /* On wayland we shouldn't need to ever freeze updates... */ - if (!meta_is_wayland_compositor ()) + MetaWindowActorPrivate *priv = self->priv; + + updates_frozen = updates_frozen != FALSE; + + if (priv->updates_frozen != updates_frozen) { - MetaWindowActorPrivate *priv = self->priv; - - updates_frozen = updates_frozen != FALSE; - - if (priv->updates_frozen != updates_frozen) - { - priv->updates_frozen = updates_frozen; - if (updates_frozen) - meta_window_actor_freeze (self); - else - meta_window_actor_thaw (self); - } + priv->updates_frozen = updates_frozen; + if (updates_frozen) + meta_window_actor_freeze (self); + else + meta_window_actor_thaw (self); } } diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index f31f3cef2..43ed92557 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -44,11 +44,11 @@ #include "meta-wayland-private.h" #include "meta-xwayland-private.h" #include "meta-wayland-stage.h" -#include "meta-surface-actor.h" #include "meta-wayland-seat.h" #include "meta-wayland-keyboard.h" #include "meta-wayland-pointer.h" #include "meta-wayland-data-device.h" + #include "meta-cursor-tracker-private.h" #include "display-private.h" #include "window-private.h" @@ -58,6 +58,9 @@ #include "meta-idle-monitor-private.h" #include "monitor-private.h" +#include "meta-surface-actor.h" +#include "meta-surface-actor-wayland.h" + static void surface_process_damage (MetaWaylandSurface *surface, cairo_region_t *region) @@ -68,8 +71,8 @@ surface_process_damage (MetaWaylandSurface *surface, { cairo_rectangle_int_t rect; cairo_region_get_rectangle (region, i, &rect); - meta_surface_actor_damage_area (surface->surface_actor, - rect.x, rect.y, rect.width, rect.height); + meta_surface_actor_process_damage (surface->surface_actor, + rect.x, rect.y, rect.width, rect.height); } } @@ -260,7 +263,7 @@ actor_surface_commit (MetaWaylandSurface *surface) { ensure_buffer_texture (buffer); meta_wayland_buffer_reference (&surface->buffer_ref, buffer); - meta_surface_actor_attach_wayland_buffer (surface_actor, buffer); + meta_surface_actor_wayland_set_buffer (META_SURFACE_ACTOR_WAYLAND (surface->surface_actor), buffer); changed = TRUE; } @@ -501,7 +504,7 @@ meta_wayland_surface_create (MetaWaylandCompositor *compositor, surface_handle_pending_buffer_destroy; wl_list_init (&surface->pending.frame_callback_list); - surface->surface_actor = g_object_ref_sink (meta_surface_actor_new ()); + surface->surface_actor = g_object_ref_sink (meta_surface_actor_wayland_new (surface)); return surface; } From a318198ab47d7aa5d3b78a6c7e7176f490827fb6 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 9 Dec 2013 13:47:55 -0500 Subject: [PATCH 403/889] xwayland: Update the surface actor for the window on set_window_id We need to do this for XWayland windows, since we only get the event telling us they're an XWayland window after the compositor knows about the window. --- src/compositor/meta-window-actor.c | 66 +++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 19 deletions(-) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index fe09ace3c..10df90dbb 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -305,6 +305,51 @@ meta_window_actor_thaw (MetaWindowActor *self) meta_window_actor_handle_updates (self); } +static void +set_surface_actor (MetaWindowActor *self, + MetaSurfaceActor *surface) +{ + MetaWindowActorPrivate *priv = self->priv; + + if (priv->surface) + { + g_object_unref (priv->surface); + clutter_actor_remove_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface)); + } + + priv->surface = surface; + + if (priv->surface) + { + g_object_ref_sink (priv->surface); + clutter_actor_add_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface)); + + g_signal_connect_object (priv->surface, "allocation-changed", + G_CALLBACK (surface_allocation_changed_notify), self, 0); + } + + meta_window_actor_update_shape (self); +} + +static void +meta_window_actor_sync_surface_actor (MetaWindowActor *self) +{ + MetaWindowActorPrivate *priv = self->priv; + MetaWindow *window = priv->window; + + MetaSurfaceActor *surface = NULL; + + if (window) + { + if (window->surface) + surface = window->surface->surface_actor; + else + surface = meta_surface_actor_x11_new (window); + } + + set_surface_actor (self, surface); +} + static void meta_window_actor_constructed (GObject *object) { @@ -314,21 +359,7 @@ meta_window_actor_constructed (GObject *object) priv->screen = window->screen; - if (!priv->surface) - { - if (window->surface) - priv->surface = window->surface->surface_actor; - else - priv->surface = meta_surface_actor_x11_new (window); - g_object_ref_sink (priv->surface); - - clutter_actor_add_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface)); - - g_signal_connect_object (priv->surface, "allocation-changed", - G_CALLBACK (surface_allocation_changed_notify), self, 0); - meta_window_actor_update_shape (self); - } - + meta_window_actor_sync_surface_actor (self); meta_window_actor_update_opacity (self); /* Start off with an empty shape region to maintain the invariant @@ -370,10 +401,7 @@ meta_window_actor_dispose (GObject *object) g_clear_object (&priv->window); - /* - * Release the extra reference we took on the actor. - */ - g_clear_object (&priv->surface); + meta_window_actor_sync_surface_actor (self); G_OBJECT_CLASS (meta_window_actor_parent_class)->dispose (object); } From ba484be754c931761ba6db7350b5f37b915dcb07 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 9 Dec 2013 13:59:02 -0500 Subject: [PATCH 404/889] window-actor: Don't use TFP under XWayland Simply have a NULL surface actor until the set_window_id arrives... --- src/compositor/meta-window-actor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 10df90dbb..4745d96ac 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -343,7 +343,7 @@ meta_window_actor_sync_surface_actor (MetaWindowActor *self) { if (window->surface) surface = window->surface->surface_actor; - else + else if (!meta_is_wayland_compositor ()) surface = meta_surface_actor_x11_new (window); } From ac32b9ef95609d167569aec89ffc1235d47f52d7 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 16 Jan 2014 17:48:52 -0500 Subject: [PATCH 405/889] get xwayland working again --- src/core/window.c | 3 ++- src/wayland/meta-xwayland.c | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/core/window.c b/src/core/window.c index dbac50751..13d8e2a92 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -1613,7 +1613,8 @@ meta_window_new (MetaDisplay *display, META_WINDOW_CLIENT_TYPE_X11, NULL, xwindow, - TRUE, + /* XXX */ + !meta_is_wayland_compositor (), existing_wm_state, effect, &attrs); diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index 02c5b7bc3..c9be27205 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -48,6 +48,8 @@ xserver_set_window_id (struct wl_client *client, { surface->window = window; window->surface = surface; + + meta_window_set_surface_mapped (window, TRUE); } } From 59f79e82941371f6b7b48ca23f8d0339f9b55b86 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 21 Jan 2014 12:59:51 -0500 Subject: [PATCH 406/889] constraints: CSD windows need to have their titlebar kept onscreen too GTK+ CSD windows are considered undecorated by the code, so we should not force ourselves to only run on decorated windows. https://bugzilla.gnome.org/show_bug.cgi?id=719772 --- src/core/constraints.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/constraints.c b/src/core/constraints.c index 3634bffa9..fc5dc6f86 100644 --- a/src/core/constraints.c +++ b/src/core/constraints.c @@ -1353,7 +1353,6 @@ constrain_titlebar_visible (MetaWindow *window, window->type == META_WINDOW_DOCK || window->fullscreen || !window->require_titlebar_visible || - !window->decorated || unconstrained_user_action) return TRUE; From 20545941fabf15c4f3fb96b5143340c484c6a265 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 22 Jan 2014 09:16:56 -0500 Subject: [PATCH 407/889] Revert unintentional merge from wip/surface-content to wayland This reverts a lot of commits. --- doc/reference/meta-sections.txt | 2 + src/Makefile.am | 4 - src/compositor/compositor-private.h | 7 +- src/compositor/compositor.c | 183 +++-- src/compositor/meta-surface-actor-wayland.c | 159 ---- src/compositor/meta-surface-actor-wayland.h | 65 -- src/compositor/meta-surface-actor-x11.c | 551 ------------- src/compositor/meta-surface-actor-x11.h | 69 -- src/compositor/meta-surface-actor.c | 212 ++--- src/compositor/meta-surface-actor.h | 48 +- src/compositor/meta-window-actor-private.h | 11 +- src/compositor/meta-window-actor.c | 841 ++++++++++++++++---- src/compositor/meta-window-group.c | 17 +- src/compositor/plugins/default.c | 2 +- src/core/display.c | 2 +- src/core/frame.c | 3 +- src/core/frame.h | 1 + src/core/window.c | 240 ++++-- src/meta/compositor.h | 13 +- src/meta/meta-window-actor.h | 3 + src/meta/window.h | 2 + src/wayland/meta-wayland-surface.c | 17 +- src/wayland/meta-xwayland.c | 2 - 23 files changed, 1141 insertions(+), 1313 deletions(-) delete mode 100644 src/compositor/meta-surface-actor-wayland.c delete mode 100644 src/compositor/meta-surface-actor-wayland.h delete mode 100644 src/compositor/meta-surface-actor-x11.c delete mode 100644 src/compositor/meta-surface-actor-x11.h diff --git a/doc/reference/meta-sections.txt b/doc/reference/meta-sections.txt index 22d435034..7aa893177 100644 --- a/doc/reference/meta-sections.txt +++ b/doc/reference/meta-sections.txt @@ -96,6 +96,8 @@ meta_compositor_hide_window meta_compositor_switch_workspace meta_compositor_maximize_window meta_compositor_unmaximize_window +meta_compositor_window_mapped +meta_compositor_window_unmapped meta_compositor_sync_window_geometry meta_compositor_set_updates_frozen meta_compositor_queue_frame_drawn diff --git a/src/Makefile.am b/src/Makefile.am index 991c1aea4..b81c6ec51 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -83,10 +83,6 @@ libmutter_wayland_la_SOURCES = \ compositor/meta-shaped-texture-private.h \ compositor/meta-surface-actor.c \ compositor/meta-surface-actor.h \ - compositor/meta-surface-actor-x11.c \ - compositor/meta-surface-actor-x11.h \ - compositor/meta-surface-actor-wayland.c \ - compositor/meta-surface-actor-wayland.h \ compositor/meta-texture-rectangle.c \ compositor/meta-texture-rectangle.h \ compositor/meta-texture-tower.c \ diff --git a/src/compositor/compositor-private.h b/src/compositor/compositor-private.h index 18bcff6f9..2e8d85fd9 100644 --- a/src/compositor/compositor-private.h +++ b/src/compositor/compositor-private.h @@ -46,8 +46,11 @@ struct _MetaCompScreen CoglFrameClosure *frame_closure; /* Used for unredirecting fullscreen windows */ - guint disable_unredirect_count; - MetaWindow *unredirected_window; + guint disable_unredirect_count; + MetaWindowActor *unredirected_window; + + /* Before we create the output window */ + XserverRegion pending_input_region; gint switch_workspace_in_progress; diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 0fb8df9e3..d2598f48b 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -42,6 +42,15 @@ * the call, so it may be necessary to readjust the display based on the * old_rect to start the animation. * + * meta_compositor_window_mapped() and meta_compositor_window_unmapped() are + * notifications when the toplevel window (frame or client window) is mapped or + * unmapped. That is, when the result of meta_window_toplevel_is_mapped() + * changes. The main use of this is to drop resources when a window is unmapped. + * A window will always be mapped before meta_compositor_show_window() + * is called and will not be unmapped until after meta_compositor_hide_window() + * is called. If the live_hidden_windows preference is set, windows will never + * be unmapped. + * * # Containers # * * There's two containers in the stage that are used to place window actors, here @@ -274,6 +283,25 @@ meta_get_window_actors (MetaScreen *screen) return info->windows; } +static void +do_set_stage_input_region (MetaScreen *screen, + XserverRegion region) +{ + MetaCompScreen *info = meta_screen_get_compositor_data (screen); + MetaDisplay *display = meta_screen_get_display (screen); + Display *xdpy = meta_display_get_xdisplay (display); + Window xstage = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage)); + + XFixesSetWindowShapeRegion (xdpy, xstage, ShapeInput, 0, 0, region); + + /* It's generally a good heuristic that when a crossing event is generated because + * we reshape the overlay, we don't want it to affect focus-follows-mouse focus - + * it's not the user doing something, it's the environment changing under the user. + */ + meta_display_add_ignored_crossing_serial (display, XNextRequest (xdpy)); + XFixesSetWindowShapeRegion (xdpy, info->output, ShapeInput, 0, 0, region); +} + void meta_set_stage_input_region (MetaScreen *screen, XserverRegion region) @@ -285,19 +313,29 @@ meta_set_stage_input_region (MetaScreen *screen, */ if (!meta_is_wayland_compositor ()) { - MetaCompScreen *info = meta_screen_get_compositor_data (screen); - MetaDisplay *display = meta_screen_get_display (screen); - Display *xdpy = meta_display_get_xdisplay (display); - Window xstage = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage)); + MetaCompScreen *info = meta_screen_get_compositor_data (screen); + MetaDisplay *display = meta_screen_get_display (screen); + Display *xdpy = meta_display_get_xdisplay (display); - XFixesSetWindowShapeRegion (xdpy, xstage, ShapeInput, 0, 0, region); - - /* It's generally a good heuristic that when a crossing event is generated because - * we reshape the overlay, we don't want it to affect focus-follows-mouse focus - - * it's not the user doing something, it's the environment changing under the user. - */ - meta_display_add_ignored_crossing_serial (display, XNextRequest (xdpy)); - XFixesSetWindowShapeRegion (xdpy, info->output, ShapeInput, 0, 0, region); + if (info->stage && info->output) + { + do_set_stage_input_region (screen, region); + } + else + { + /* Reset info->pending_input_region if one existed before and set the new + * one to use it later. */ + if (info->pending_input_region) + { + XFixesDestroyRegion (xdpy, info->pending_input_region); + info->pending_input_region = None; + } + if (region != None) + { + info->pending_input_region = XFixesCreateRegion (xdpy, NULL, 0); + XFixesCopyRegion (xdpy, info->pending_input_region, region); + } + } } } @@ -639,6 +677,21 @@ meta_compositor_manage_screen (MetaCompositor *compositor, return; info = g_new0 (MetaCompScreen, 1); + /* + * We use an empty input region for Clutter as a default because that allows + * the user to interact with all the windows displayed on the screen. + * We have to initialize info->pending_input_region to an empty region explicitly, + * because None value is used to mean that the whole screen is an input region. + */ + if (!meta_is_wayland_compositor ()) + info->pending_input_region = XFixesCreateRegion (xdisplay, NULL, 0); + else + { + /* Stage input region trickery isn't needed when we're running as a + * wayland compositor. */ + info->pending_input_region = None; + } + info->screen = screen; meta_screen_set_compositor_data (screen, info); @@ -724,8 +777,6 @@ meta_compositor_manage_screen (MetaCompositor *compositor, info->output = get_output_window (screen); XReparentWindow (xdisplay, xwin, info->output, 0, 0); - meta_empty_stage_input_region (screen); - /* Make sure there isn't any left-over output shape on the * overlay window by setting the whole screen to be an * output region. @@ -736,6 +787,13 @@ meta_compositor_manage_screen (MetaCompositor *compositor, */ XFixesSetWindowShapeRegion (xdisplay, info->output, ShapeBounding, 0, 0, None); + do_set_stage_input_region (screen, info->pending_input_region); + if (info->pending_input_region != None) + { + XFixesDestroyRegion (xdisplay, info->pending_input_region); + info->pending_input_region = None; + } + /* Map overlay window before redirecting windows offscreen so we catch their * contents until we show the stage. */ @@ -805,30 +863,6 @@ meta_shape_cow_for_window (MetaScreen *screen, } } -static void -set_unredirected_window (MetaCompScreen *info, - MetaWindow *window) -{ - if (info->unredirected_window == window) - return; - - if (info->unredirected_window != NULL) - { - MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (info->unredirected_window)); - meta_window_actor_set_unredirected (window_actor, FALSE); - } - - info->unredirected_window = window; - - if (info->unredirected_window != NULL) - { - MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (info->unredirected_window)); - meta_window_actor_set_unredirected (window_actor, TRUE); - } - - meta_shape_cow_for_window (info->screen, info->unredirected_window); -} - void meta_compositor_add_window (MetaCompositor *compositor, MetaWindow *window) @@ -857,11 +891,19 @@ meta_compositor_remove_window (MetaCompositor *compositor, if (!window_actor) return; - screen = meta_window_get_screen (window); - info = meta_screen_get_compositor_data (screen); + if (!meta_is_wayland_compositor ()) + { + screen = meta_window_get_screen (window); + info = meta_screen_get_compositor_data (screen); - if (info->unredirected_window == window) - set_unredirected_window (info, NULL); + if (window_actor == info->unredirected_window) + { + meta_window_actor_set_redirected (window_actor, TRUE); + meta_shape_cow_for_window (meta_window_get_screen (meta_window_actor_get_meta_window (info->unredirected_window)), + NULL); + info->unredirected_window = NULL; + } + } meta_window_actor_destroy (window_actor); } @@ -1360,6 +1402,30 @@ meta_compositor_sync_stack (MetaCompositor *compositor, sync_actor_stacking (info); } +void +meta_compositor_window_mapped (MetaCompositor *compositor, + MetaWindow *window) +{ + MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); + DEBUG_TRACE ("meta_compositor_window_mapped\n"); + if (!window_actor) + return; + + meta_window_actor_mapped (window_actor); +} + +void +meta_compositor_window_unmapped (MetaCompositor *compositor, + MetaWindow *window) +{ + MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); + DEBUG_TRACE ("meta_compositor_window_unmapped\n"); + if (!window_actor) + return; + + meta_window_actor_unmapped (window_actor); +} + void meta_compositor_sync_window_geometry (MetaCompositor *compositor, MetaWindow *window, @@ -1467,6 +1533,7 @@ pre_paint_windows (MetaCompScreen *info) { GList *l; MetaWindowActor *top_window; + MetaWindowActor *expected_unredirected_window = NULL; if (info->onscreen == NULL) { @@ -1480,13 +1547,33 @@ pre_paint_windows (MetaCompScreen *info) if (info->windows == NULL) return; - top_window = g_list_last (info->windows)->data; + if (!meta_is_wayland_compositor ()) + { + top_window = g_list_last (info->windows)->data; - if (meta_window_actor_should_unredirect (top_window) && - info->disable_unredirect_count == 0) - set_unredirected_window (info, meta_window_actor_get_meta_window (top_window)); - else - set_unredirected_window (info, NULL); + if (meta_window_actor_should_unredirect (top_window) && + info->disable_unredirect_count == 0) + expected_unredirected_window = top_window; + + if (info->unredirected_window != expected_unredirected_window) + { + if (info->unredirected_window != NULL) + { + meta_window_actor_set_redirected (info->unredirected_window, TRUE); + meta_shape_cow_for_window (meta_window_get_screen (meta_window_actor_get_meta_window (info->unredirected_window)), + NULL); + } + + if (expected_unredirected_window != NULL) + { + meta_shape_cow_for_window (meta_window_get_screen (meta_window_actor_get_meta_window (top_window)), + meta_window_actor_get_meta_window (top_window)); + meta_window_actor_set_redirected (top_window, FALSE); + } + + info->unredirected_window = expected_unredirected_window; + } + } for (l = info->windows; l; l = l->next) meta_window_actor_pre_paint (l->data); diff --git a/src/compositor/meta-surface-actor-wayland.c b/src/compositor/meta-surface-actor-wayland.c deleted file mode 100644 index 95ebc9020..000000000 --- a/src/compositor/meta-surface-actor-wayland.c +++ /dev/null @@ -1,159 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* - * Copyright (C) 2013 Red Hat - * - * 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. - * - * Written by: - * Jasper St. Pierre - */ - -#include "config.h" - -#include "meta-surface-actor-wayland.h" - -#include -#include "meta-shaped-texture-private.h" - -struct _MetaSurfaceActorWaylandPrivate -{ - MetaWaylandSurface *surface; - MetaWaylandBuffer *buffer; -}; -typedef struct _MetaSurfaceActorWaylandPrivate MetaSurfaceActorWaylandPrivate; - -G_DEFINE_TYPE_WITH_PRIVATE (MetaSurfaceActorWayland, meta_surface_actor_wayland, META_TYPE_SURFACE_ACTOR) - -static void -meta_surface_actor_wayland_process_damage (MetaSurfaceActor *actor, - int x, int y, int width, int height) -{ - MetaSurfaceActorWayland *self = META_SURFACE_ACTOR_WAYLAND (actor); - MetaSurfaceActorWaylandPrivate *priv = meta_surface_actor_wayland_get_instance_private (self); - - struct wl_resource *resource = priv->buffer->resource; - struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get (resource); - - if (shm_buffer) - { - CoglTexture2D *texture = COGL_TEXTURE_2D (priv->buffer->texture); - cogl_wayland_texture_set_region_from_shm_buffer (texture, x, y, width, height, shm_buffer, x, y, 0, NULL); - } - - meta_surface_actor_redraw_area (META_SURFACE_ACTOR (self), x, y, width, height); -} - -static void -meta_surface_actor_wayland_pre_paint (MetaSurfaceActor *actor) -{ -} - -static gboolean -meta_surface_actor_wayland_is_argb32 (MetaSurfaceActor *actor) -{ - /* TODO: look at the SHM buffer pixel format */ - return TRUE; -} - -static gboolean -meta_surface_actor_wayland_is_visible (MetaSurfaceActor *actor) -{ - /* TODO: ensure that the buffer isn't NULL, implement - * wayland mapping semantics */ - return TRUE; -} - -static void -meta_surface_actor_wayland_freeze (MetaSurfaceActor *actor) -{ -} - -static void -meta_surface_actor_wayland_thaw (MetaSurfaceActor *actor) -{ -} - -static gboolean -meta_surface_actor_wayland_is_frozen (MetaSurfaceActor *actor) -{ - return FALSE; -} - -static gboolean -meta_surface_actor_wayland_should_unredirect (MetaSurfaceActor *actor) -{ - return FALSE; -} - -static void -meta_surface_actor_wayland_set_unredirected (MetaSurfaceActor *actor, - gboolean unredirected) -{ - /* Do nothing. In the future, we'll use KMS to set this - * up as a hardware overlay or something. */ -} - -static void -meta_surface_actor_wayland_class_init (MetaSurfaceActorWaylandClass *klass) -{ - MetaSurfaceActorClass *surface_actor_class = META_SURFACE_ACTOR_CLASS (klass); - - surface_actor_class->process_damage = meta_surface_actor_wayland_process_damage; - surface_actor_class->pre_paint = meta_surface_actor_wayland_pre_paint; - surface_actor_class->is_argb32 = meta_surface_actor_wayland_is_argb32; - surface_actor_class->is_visible = meta_surface_actor_wayland_is_visible; - - surface_actor_class->freeze = meta_surface_actor_wayland_freeze; - surface_actor_class->thaw = meta_surface_actor_wayland_thaw; - surface_actor_class->is_frozen = meta_surface_actor_wayland_is_frozen; - - surface_actor_class->should_unredirect = meta_surface_actor_wayland_should_unredirect; - surface_actor_class->set_unredirected = meta_surface_actor_wayland_set_unredirected; -} - -static void -meta_surface_actor_wayland_init (MetaSurfaceActorWayland *self) -{ -} - -MetaSurfaceActor * -meta_surface_actor_wayland_new (MetaWaylandSurface *surface) -{ - MetaSurfaceActorWayland *self = g_object_new (META_TYPE_SURFACE_ACTOR_WAYLAND, NULL); - MetaSurfaceActorWaylandPrivate *priv = meta_surface_actor_wayland_get_instance_private (self); - - g_assert (meta_is_wayland_compositor ()); - - priv->surface = surface; - - return META_SURFACE_ACTOR (self); -} - -void -meta_surface_actor_wayland_set_buffer (MetaSurfaceActorWayland *self, - MetaWaylandBuffer *buffer) -{ - MetaSurfaceActorWaylandPrivate *priv = meta_surface_actor_wayland_get_instance_private (self); - MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self)); - - priv->buffer = buffer; - - if (buffer) - meta_shaped_texture_set_texture (stex, buffer->texture); - else - meta_shaped_texture_set_texture (stex, NULL); -} diff --git a/src/compositor/meta-surface-actor-wayland.h b/src/compositor/meta-surface-actor-wayland.h deleted file mode 100644 index 2712f9dbf..000000000 --- a/src/compositor/meta-surface-actor-wayland.h +++ /dev/null @@ -1,65 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* - * Copyright (C) 2013 Red Hat - * - * 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. - * - * Written by: - * Jasper St. Pierre - */ - -#ifndef __META_SURFACE_ACTOR_WAYLAND_H__ -#define __META_SURFACE_ACTOR_WAYLAND_H__ - -#include - -#include "meta-surface-actor.h" - -#include "meta-wayland-private.h" - -G_BEGIN_DECLS - -#define META_TYPE_SURFACE_ACTOR_WAYLAND (meta_surface_actor_wayland_get_type ()) -#define META_SURFACE_ACTOR_WAYLAND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_SURFACE_ACTOR_WAYLAND, MetaSurfaceActorWayland)) -#define META_SURFACE_ACTOR_WAYLAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_SURFACE_ACTOR_WAYLAND, MetaSurfaceActorWaylandClass)) -#define META_IS_SURFACE_ACTOR_WAYLAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_SURFACE_ACTOR_WAYLAND)) -#define META_IS_SURFACE_ACTOR_WAYLAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_SURFACE_ACTOR_WAYLAND)) -#define META_SURFACE_ACTOR_WAYLAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_SURFACE_ACTOR_WAYLAND, MetaSurfaceActorWaylandClass)) - -typedef struct _MetaSurfaceActorWayland MetaSurfaceActorWayland; -typedef struct _MetaSurfaceActorWaylandClass MetaSurfaceActorWaylandClass; - -struct _MetaSurfaceActorWayland -{ - MetaSurfaceActor parent; -}; - -struct _MetaSurfaceActorWaylandClass -{ - MetaSurfaceActorClass parent_class; -}; - -GType meta_surface_actor_wayland_get_type (void); - -MetaSurfaceActor * meta_surface_actor_wayland_new (MetaWaylandSurface *surface); - -void meta_surface_actor_wayland_set_buffer (MetaSurfaceActorWayland *self, - MetaWaylandBuffer *buffer); - -G_END_DECLS - -#endif /* __META_SURFACE_ACTOR_WAYLAND_H__ */ diff --git a/src/compositor/meta-surface-actor-x11.c b/src/compositor/meta-surface-actor-x11.c deleted file mode 100644 index 8f707d7a8..000000000 --- a/src/compositor/meta-surface-actor-x11.c +++ /dev/null @@ -1,551 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* - * Copyright (C) 2013 Red Hat - * - * 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. - * - * Written by: - * Owen Taylor - * Jasper St. Pierre - */ - -#include "config.h" - -#include "meta-surface-actor-x11.h" - -#include -#include -#include - -#include -#include "window-private.h" -#include "meta-shaped-texture-private.h" -#include "meta-cullable.h" - -struct _MetaSurfaceActorX11Private -{ - MetaWindow *window; - - MetaDisplay *display; - - CoglTexture *texture; - Pixmap pixmap; - Damage damage; - - int last_width; - int last_height; - - /* Freeze/thaw accounting */ - guint freeze_count; - - /* This is used to detect fullscreen windows that need to be unredirected */ - guint full_damage_frames_count; - guint does_full_damage : 1; - - /* Other state... */ - guint argb32 : 1; - guint received_damage : 1; - guint size_changed : 1; - guint needs_damage_all : 1; - - guint unredirected : 1; -}; -typedef struct _MetaSurfaceActorX11Private MetaSurfaceActorX11Private; - -static void cullable_iface_init (MetaCullableInterface *iface); - -G_DEFINE_TYPE_WITH_CODE (MetaSurfaceActorX11, meta_surface_actor_x11, META_TYPE_SURFACE_ACTOR, - G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init) - G_ADD_PRIVATE (MetaSurfaceActorX11)) - -static MetaCullableInterface *parent_cullable_iface; - -static void -meta_surface_actor_x11_cull_out (MetaCullable *cullable, - cairo_region_t *unobscured_region, - cairo_region_t *clip_region) -{ - MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (cullable); - MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); - - /* Don't do any culling for the unredirected window */ - if (priv->unredirected) - return; - - parent_cullable_iface->cull_out (cullable, unobscured_region, clip_region); -} - -static void -cullable_iface_init (MetaCullableInterface *iface) -{ - parent_cullable_iface = g_type_interface_peek_parent (iface); - iface->cull_out = meta_surface_actor_x11_cull_out; -} - -static void -free_damage (MetaSurfaceActorX11 *self) -{ - MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); - MetaDisplay *display = priv->display; - Display *xdisplay = meta_display_get_xdisplay (display); - - if (priv->damage == None) - return; - - meta_error_trap_push (display); - XDamageDestroy (xdisplay, priv->damage); - priv->damage = None; - meta_error_trap_pop (display); -} - -static void -detach_pixmap (MetaSurfaceActorX11 *self) -{ - MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); - MetaDisplay *display = priv->display; - Display *xdisplay = meta_display_get_xdisplay (display); - MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self)); - - if (priv->pixmap == None) - return; - - meta_error_trap_push (display); - XFreePixmap (xdisplay, priv->pixmap); - priv->pixmap = None; - meta_error_trap_pop (display); - - meta_shaped_texture_set_texture (stex, NULL); - - cogl_object_unref (priv->texture); - priv->texture = NULL; -} - -static void -set_pixmap (MetaSurfaceActorX11 *self, - Pixmap pixmap) -{ - MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); - - CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ()); - MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self)); - CoglTexture *texture; - - g_assert (priv->pixmap == None); - priv->pixmap = pixmap; - - texture = COGL_TEXTURE (cogl_texture_pixmap_x11_new (ctx, priv->pixmap, FALSE, NULL)); - - if (G_UNLIKELY (!cogl_texture_pixmap_x11_is_using_tfp_extension (COGL_TEXTURE_PIXMAP_X11 (texture)))) - g_warning ("NOTE: Not using GLX TFP!\n"); - - priv->texture = texture; - meta_shaped_texture_set_texture (stex, texture); -} - -static void -update_pixmap (MetaSurfaceActorX11 *self) -{ - MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); - MetaDisplay *display = priv->display; - Display *xdisplay = meta_display_get_xdisplay (display); - - if (priv->size_changed) - { - detach_pixmap (self); - priv->size_changed = FALSE; - } - - if (priv->pixmap == None) - { - Pixmap new_pixmap; - Window xwindow = meta_window_get_toplevel_xwindow (priv->window); - - meta_error_trap_push (display); - new_pixmap = XCompositeNameWindowPixmap (xdisplay, xwindow); - - if (meta_error_trap_pop_with_return (display) != Success) - { - /* Probably a BadMatch if the window isn't viewable; we could - * GrabServer/GetWindowAttributes/NameWindowPixmap/UngrabServer/Sync - * to avoid this, but there's no reason to take two round trips - * when one will do. (We need that Sync if we want to handle failures - * for any reason other than !viewable. That's unlikely, but maybe - * we'll BadAlloc or something.) - */ - new_pixmap = None; - } - - if (new_pixmap == None) - { - meta_verbose ("Unable to get named pixmap for %s\n", - meta_window_get_description (priv->window)); - return; - } - - set_pixmap (self, new_pixmap); - } -} - -static gboolean -is_frozen (MetaSurfaceActorX11 *self) -{ - MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); - return (priv->freeze_count > 0); -} - -static gboolean -is_visible (MetaSurfaceActorX11 *self) -{ - MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); - return (priv->pixmap != None) && !priv->unredirected; -} - -static void -damage_area (MetaSurfaceActorX11 *self, - int x, int y, int width, int height) -{ - MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); - - if (!is_visible (self)) - return; - - cogl_texture_pixmap_x11_update_area (priv->texture, x, y, width, height); - meta_surface_actor_redraw_area (META_SURFACE_ACTOR (self), x, y, width, height); -} - -static void -damage_all (MetaSurfaceActorX11 *self) -{ - MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); - - if (!is_visible (self)) - return; - - damage_area (self, 0, 0, cogl_texture_get_width (priv->texture), cogl_texture_get_height (priv->texture)); -} - -static void -meta_surface_actor_x11_process_damage (MetaSurfaceActor *actor, - int x, int y, int width, int height) -{ - MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor); - MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); - - priv->received_damage = TRUE; - - if (!priv->unredirected && !priv->does_full_damage) - { - MetaRectangle window_rect; - meta_window_get_frame_rect (priv->window, &window_rect); - - if (window_rect.x == x && - window_rect.y == y && - window_rect.width == width && - window_rect.height == height) - priv->full_damage_frames_count++; - else - priv->full_damage_frames_count = 0; - - if (priv->full_damage_frames_count >= 100) - priv->does_full_damage = TRUE; - } - - if (is_frozen (self)) - { - /* The window is frozen due to an effect in progress: we ignore damage - * here on the off chance that this will stop the corresponding - * texture_from_pixmap from being update. - * - * needs_damage_all tracks that some unknown damage happened while the - * window was frozen so that when the window becomes unfrozen we can - * issue a full window update to cover any lost damage. - * - * It should be noted that this is an unreliable mechanism since it's - * quite likely that drivers will aim to provide a zero-copy - * implementation of the texture_from_pixmap extension and in those cases - * any drawing done to the window is always immediately reflected in the - * texture regardless of damage event handling. - */ - priv->needs_damage_all = TRUE; - return; - } - - damage_area (self, x, y, width, height); -} - -static void -meta_surface_actor_x11_pre_paint (MetaSurfaceActor *actor) -{ - MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor); - MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); - MetaDisplay *display = priv->display; - Display *xdisplay = meta_display_get_xdisplay (display); - - if (is_frozen (self)) - return; - - if (priv->received_damage) - { - meta_error_trap_push (display); - XDamageSubtract (xdisplay, priv->damage, None, None); - meta_error_trap_pop (display); - - /* We need to make sure that any X drawing that happens before the - * XDamageSubtract() 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. - * - * Xorg and open source driver specifics: - * - * The X server makes sure to flush drawing to the kernel before - * sending out damage events, but since we use DamageReportBoundingBox - * there may be drawing between the last damage event and the - * XDamageSubtract() that needs to be flushed as well. - * - * Xorg always makes sure that drawing is flushed to the kernel - * before writing events or responses to the client, so any round trip - * request at this point is sufficient to flush the GLX buffers. - */ - XSync (xdisplay, False); - - priv->received_damage = FALSE; - } - - update_pixmap (self); -} - -static void -meta_surface_actor_x11_freeze (MetaSurfaceActor *actor) -{ - MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor); - MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); - - priv->freeze_count ++; -} - -static void -meta_surface_actor_x11_thaw (MetaSurfaceActor *actor) -{ - MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor); - MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); - - if (priv->freeze_count == 0) - { - g_critical ("Error in freeze/thaw accounting."); - return; - } - - priv->freeze_count --; - - /* Since we ignore damage events while a window is frozen for certain effects - * we may need to issue an update_area() covering the whole pixmap if we - * don't know what real damage has happened. */ - if (priv->needs_damage_all) - { - damage_all (self); - priv->needs_damage_all = FALSE; - } -} - -static gboolean -meta_surface_actor_x11_is_frozen (MetaSurfaceActor *actor) -{ - MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor); - return is_frozen (self); -} - -static void -update_is_argb32 (MetaSurfaceActorX11 *self) -{ - MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); - MetaDisplay *display = priv->display; - Display *xdisplay = meta_display_get_xdisplay (display); - - XRenderPictFormat *format; - format = XRenderFindVisualFormat (xdisplay, priv->window->xvisual); - - priv->argb32 = (format && format->type == PictTypeDirect && format->direct.alphaMask); -} - -static gboolean -meta_surface_actor_x11_is_argb32 (MetaSurfaceActor *actor) -{ - MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor); - MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); - - return priv->argb32; -} - -static gboolean -meta_surface_actor_x11_is_visible (MetaSurfaceActor *actor) -{ - MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor); - return is_visible (self); -} - -static gboolean -meta_surface_actor_x11_should_unredirect (MetaSurfaceActor *actor) -{ - MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor); - MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); - - MetaWindow *window = priv->window; - - if (meta_window_requested_dont_bypass_compositor (window)) - return FALSE; - - if (window->opacity != 0xFF) - return FALSE; - - if (window->shape_region != NULL) - return FALSE; - - if (priv->argb32 && !meta_window_requested_bypass_compositor (window)) - return FALSE; - - if (!meta_window_is_monitor_sized (window)) - return FALSE; - - if (meta_window_requested_bypass_compositor (window)) - return TRUE; - - if (meta_window_is_override_redirect (window)) - return TRUE; - - if (priv->does_full_damage) - return TRUE; - - return FALSE; -} - -static void -sync_unredirected (MetaSurfaceActorX11 *self) -{ - MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); - MetaDisplay *display = priv->display; - Display *xdisplay = meta_display_get_xdisplay (display); - Window xwindow = meta_window_get_toplevel_xwindow (priv->window); - - meta_error_trap_push (display); - - if (priv->unredirected) - { - detach_pixmap (self); - XCompositeUnredirectWindow (xdisplay, xwindow, CompositeRedirectManual); - } - else - { - XCompositeRedirectWindow (xdisplay, xwindow, CompositeRedirectManual); - } - - meta_error_trap_pop (display); -} - -static void -meta_surface_actor_x11_set_unredirected (MetaSurfaceActor *actor, - gboolean unredirected) -{ - MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor); - MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); - - if (priv->unredirected == unredirected) - return; - - priv->unredirected = unredirected; - sync_unredirected (self); -} - -static void -meta_surface_actor_x11_dispose (GObject *object) -{ - MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (object); - - detach_pixmap (self); - free_damage (self); - - G_OBJECT_CLASS (meta_surface_actor_x11_parent_class)->dispose (object); -} - -static void -meta_surface_actor_x11_class_init (MetaSurfaceActorX11Class *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - MetaSurfaceActorClass *surface_actor_class = META_SURFACE_ACTOR_CLASS (klass); - - object_class->dispose = meta_surface_actor_x11_dispose; - - surface_actor_class->process_damage = meta_surface_actor_x11_process_damage; - surface_actor_class->pre_paint = meta_surface_actor_x11_pre_paint; - surface_actor_class->is_argb32 = meta_surface_actor_x11_is_argb32; - surface_actor_class->is_visible = meta_surface_actor_x11_is_visible; - - surface_actor_class->freeze = meta_surface_actor_x11_freeze; - surface_actor_class->thaw = meta_surface_actor_x11_thaw; - surface_actor_class->is_frozen = meta_surface_actor_x11_is_frozen; - - surface_actor_class->should_unredirect = meta_surface_actor_x11_should_unredirect; - surface_actor_class->set_unredirected = meta_surface_actor_x11_set_unredirected; -} - -static void -meta_surface_actor_x11_init (MetaSurfaceActorX11 *self) -{ - MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); - - priv->last_width = -1; - priv->last_height = -1; -} - -MetaSurfaceActor * -meta_surface_actor_x11_new (MetaWindow *window) -{ - MetaSurfaceActorX11 *self = g_object_new (META_TYPE_SURFACE_ACTOR_X11, NULL); - MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); - MetaDisplay *display = meta_window_get_display (window); - Display *xdisplay = meta_display_get_xdisplay (display); - Window xwindow = meta_window_get_toplevel_xwindow (window); - - g_assert (!meta_is_wayland_compositor ()); - - priv->window = window; - priv->display = display; - - priv->damage = XDamageCreate (xdisplay, xwindow, XDamageReportBoundingBox); - update_is_argb32 (self); - - priv->unredirected = FALSE; - sync_unredirected (self); - - return META_SURFACE_ACTOR (self); -} - -void -meta_surface_actor_x11_set_size (MetaSurfaceActorX11 *self, - int width, int height) -{ - MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); - - if (priv->last_width == width && - priv->last_height == height) - return; - - priv->size_changed = TRUE; - priv->last_width = width; - priv->last_height = height; -} diff --git a/src/compositor/meta-surface-actor-x11.h b/src/compositor/meta-surface-actor-x11.h deleted file mode 100644 index 0e692ee0f..000000000 --- a/src/compositor/meta-surface-actor-x11.h +++ /dev/null @@ -1,69 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* - * Copyright (C) 2013 Red Hat - * - * 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. - * - * Written by: - * Owen Taylor - * Jasper St. Pierre - */ - -#ifndef __META_SURFACE_ACTOR_X11_H__ -#define __META_SURFACE_ACTOR_X11_H__ - -#include - -#include "meta-surface-actor.h" - -#include - -#include -#include - -G_BEGIN_DECLS - -#define META_TYPE_SURFACE_ACTOR_X11 (meta_surface_actor_x11_get_type ()) -#define META_SURFACE_ACTOR_X11(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_SURFACE_ACTOR_X11, MetaSurfaceActorX11)) -#define META_SURFACE_ACTOR_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_SURFACE_ACTOR_X11, MetaSurfaceActorX11Class)) -#define META_IS_SURFACE_ACTOR_X11(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_SURFACE_ACTOR_X11)) -#define META_IS_SURFACE_ACTOR_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_SURFACE_ACTOR_X11)) -#define META_SURFACE_ACTOR_X11_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_SURFACE_ACTOR_X11, MetaSurfaceActorX11Class)) - -typedef struct _MetaSurfaceActorX11 MetaSurfaceActorX11; -typedef struct _MetaSurfaceActorX11Class MetaSurfaceActorX11Class; - -struct _MetaSurfaceActorX11 -{ - MetaSurfaceActor parent; -}; - -struct _MetaSurfaceActorX11Class -{ - MetaSurfaceActorClass parent_class; -}; - -GType meta_surface_actor_x11_get_type (void); - -MetaSurfaceActor * meta_surface_actor_x11_new (MetaWindow *window); - -void meta_surface_actor_x11_set_size (MetaSurfaceActorX11 *self, - int width, int height); - -G_END_DECLS - -#endif /* __META_SURFACE_ACTOR_X11_H__ */ diff --git a/src/compositor/meta-surface-actor.c b/src/compositor/meta-surface-actor.c index 9d21c749d..37b87b03a 100644 --- a/src/compositor/meta-surface-actor.c +++ b/src/compositor/meta-surface-actor.c @@ -10,118 +10,44 @@ */ #include - -#include "meta-surface-actor.h" - #include +#include +#include #include +#include "meta-surface-actor.h" #include "meta-wayland-private.h" #include "meta-cullable.h" + #include "meta-shaped-texture-private.h" struct _MetaSurfaceActorPrivate { MetaShapedTexture *texture; - - /* The region that is visible, used to optimize out redraws */ - cairo_region_t *unobscured_region; + MetaWaylandBuffer *buffer; }; static void cullable_iface_init (MetaCullableInterface *iface); -G_DEFINE_ABSTRACT_TYPE_WITH_CODE (MetaSurfaceActor, meta_surface_actor, CLUTTER_TYPE_ACTOR, - G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init)); - -static gboolean -meta_surface_actor_get_paint_volume (ClutterActor *actor, - ClutterPaintVolume *volume) -{ - MetaSurfaceActor *self = META_SURFACE_ACTOR (actor); - MetaSurfaceActorPrivate *priv = self->priv; - - if (!CLUTTER_ACTOR_CLASS (meta_surface_actor_parent_class)->get_paint_volume (actor, volume)) - return FALSE; - - if (priv->unobscured_region) - { - ClutterVertex origin; - cairo_rectangle_int_t bounds, unobscured_bounds; - - /* I hate ClutterPaintVolume so much... */ - clutter_paint_volume_get_origin (volume, &origin); - bounds.x = origin.x; - bounds.y = origin.y; - bounds.width = clutter_paint_volume_get_width (volume); - bounds.height = clutter_paint_volume_get_height (volume); - - cairo_region_get_extents (priv->unobscured_region, &unobscured_bounds); - gdk_rectangle_intersect (&bounds, &unobscured_bounds, &bounds); - - origin.x = bounds.x; - origin.y = bounds.y; - clutter_paint_volume_set_origin (volume, &origin); - clutter_paint_volume_set_width (volume, bounds.width); - clutter_paint_volume_set_height (volume, bounds.height); - } - - return TRUE; -} - -static void -meta_surface_actor_dispose (GObject *object) -{ - MetaSurfaceActor *self = META_SURFACE_ACTOR (object); - MetaSurfaceActorPrivate *priv = self->priv; - - g_clear_pointer (&priv->unobscured_region, cairo_region_destroy); - - G_OBJECT_CLASS (meta_surface_actor_parent_class)->dispose (object); -} +G_DEFINE_TYPE_WITH_CODE (MetaSurfaceActor, meta_surface_actor, CLUTTER_TYPE_ACTOR, + G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init)); static void meta_surface_actor_class_init (MetaSurfaceActorClass *klass) { - ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - actor_class->get_paint_volume = meta_surface_actor_get_paint_volume; - object_class->dispose = meta_surface_actor_dispose; - g_type_class_add_private (klass, sizeof (MetaSurfaceActorPrivate)); } -static void -set_unobscured_region (MetaSurfaceActor *self, - cairo_region_t *unobscured_region) -{ - MetaSurfaceActorPrivate *priv = self->priv; - - if (priv->unobscured_region) - cairo_region_destroy (priv->unobscured_region); - - if (unobscured_region) - priv->unobscured_region = cairo_region_copy (unobscured_region); - else - priv->unobscured_region = NULL; -} - static void meta_surface_actor_cull_out (MetaCullable *cullable, cairo_region_t *unobscured_region, cairo_region_t *clip_region) { - MetaSurfaceActor *self = META_SURFACE_ACTOR (cullable); - - set_unobscured_region (self, unobscured_region); meta_cullable_cull_out_children (cullable, unobscured_region, clip_region); } static void meta_surface_actor_reset_culling (MetaCullable *cullable) { - MetaSurfaceActor *self = META_SURFACE_ACTOR (cullable); - - set_unobscured_region (self, NULL); meta_cullable_reset_culling_children (cullable); } @@ -158,34 +84,80 @@ meta_surface_actor_get_texture (MetaSurfaceActor *self) return self->priv->texture; } -static cairo_region_t * -effective_unobscured_region (MetaSurfaceActor *self) +static void +update_area (MetaSurfaceActor *self, + int x, int y, int width, int height) { MetaSurfaceActorPrivate *priv = self->priv; - return clutter_actor_has_mapped_clones (CLUTTER_ACTOR (self)) ? NULL : priv->unobscured_region; + if (meta_is_wayland_compositor ()) + { + struct wl_resource *resource = priv->buffer->resource; + struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get (resource); + + if (shm_buffer) + { + CoglTexture2D *texture = COGL_TEXTURE_2D (priv->buffer->texture); + cogl_wayland_texture_set_region_from_shm_buffer (texture, x, y, width, height, shm_buffer, x, y, 0, NULL); + } + } + else + { + CoglTexturePixmapX11 *texture = COGL_TEXTURE_PIXMAP_X11 (meta_shaped_texture_get_texture (priv->texture)); + cogl_texture_pixmap_x11_update_area (texture, x, y, width, height); + } } gboolean -meta_surface_actor_redraw_area (MetaSurfaceActor *self, - int x, int y, int width, int height) +meta_surface_actor_damage_all (MetaSurfaceActor *self, + cairo_region_t *unobscured_region) +{ + MetaSurfaceActorPrivate *priv = self->priv; + CoglTexture *texture = meta_shaped_texture_get_texture (priv->texture); + + update_area (self, 0, 0, cogl_texture_get_width (texture), cogl_texture_get_height (texture)); + return meta_shaped_texture_update_area (priv->texture, + 0, 0, + cogl_texture_get_width (texture), + cogl_texture_get_height (texture), + unobscured_region); +} + +gboolean +meta_surface_actor_damage_area (MetaSurfaceActor *self, + int x, + int y, + int width, + int height, + cairo_region_t *unobscured_region) { MetaSurfaceActorPrivate *priv = self->priv; + update_area (self, x, y, width, height); return meta_shaped_texture_update_area (priv->texture, x, y, width, height, - effective_unobscured_region (self)); + unobscured_region); } -gboolean -meta_surface_actor_is_obscured (MetaSurfaceActor *self) +void +meta_surface_actor_attach_wayland_buffer (MetaSurfaceActor *self, + MetaWaylandBuffer *buffer) { MetaSurfaceActorPrivate *priv = self->priv; + priv->buffer = buffer; - if (priv->unobscured_region) - return cairo_region_is_empty (priv->unobscured_region); + if (buffer) + meta_shaped_texture_set_texture (priv->texture, buffer->texture); else - return FALSE; + meta_shaped_texture_set_texture (priv->texture, NULL); +} + +void +meta_surface_actor_set_texture (MetaSurfaceActor *self, + CoglTexture *texture) +{ + MetaSurfaceActorPrivate *priv = self->priv; + meta_shaped_texture_set_texture (priv->texture, texture); } void @@ -204,58 +176,8 @@ meta_surface_actor_set_opaque_region (MetaSurfaceActor *self, meta_shaped_texture_set_opaque_region (priv->texture, region); } -void -meta_surface_actor_process_damage (MetaSurfaceActor *actor, - int x, int y, int width, int height) +MetaSurfaceActor * +meta_surface_actor_new (void) { - META_SURFACE_ACTOR_GET_CLASS (actor)->process_damage (actor, x, y, width, height); -} - -void -meta_surface_actor_pre_paint (MetaSurfaceActor *actor) -{ - META_SURFACE_ACTOR_GET_CLASS (actor)->pre_paint (actor); -} - -gboolean -meta_surface_actor_is_argb32 (MetaSurfaceActor *actor) -{ - return META_SURFACE_ACTOR_GET_CLASS (actor)->is_argb32 (actor); -} - -gboolean -meta_surface_actor_is_visible (MetaSurfaceActor *actor) -{ - return META_SURFACE_ACTOR_GET_CLASS (actor)->is_visible (actor); -} - -void -meta_surface_actor_freeze (MetaSurfaceActor *actor) -{ - META_SURFACE_ACTOR_GET_CLASS (actor)->freeze (actor); -} - -void -meta_surface_actor_thaw (MetaSurfaceActor *actor) -{ - META_SURFACE_ACTOR_GET_CLASS (actor)->thaw (actor); -} - -gboolean -meta_surface_actor_is_frozen (MetaSurfaceActor *actor) -{ - return META_SURFACE_ACTOR_GET_CLASS (actor)->is_frozen (actor); -} - -gboolean -meta_surface_actor_should_unredirect (MetaSurfaceActor *actor) -{ - return META_SURFACE_ACTOR_GET_CLASS (actor)->should_unredirect (actor); -} - -void -meta_surface_actor_set_unredirected (MetaSurfaceActor *actor, - gboolean unredirected) -{ - META_SURFACE_ACTOR_GET_CLASS (actor)->set_unredirected (actor, unredirected); + return g_object_new (META_TYPE_SURFACE_ACTOR, NULL); } diff --git a/src/compositor/meta-surface-actor.h b/src/compositor/meta-surface-actor.h index f9d458c53..484877b73 100644 --- a/src/compositor/meta-surface-actor.h +++ b/src/compositor/meta-surface-actor.h @@ -6,6 +6,7 @@ #include #include +#include "meta-wayland-types.h" G_BEGIN_DECLS @@ -24,20 +25,6 @@ struct _MetaSurfaceActorClass { /*< private >*/ ClutterActorClass parent_class; - - void (* process_damage) (MetaSurfaceActor *actor, - int x, int y, int width, int height); - void (* pre_paint) (MetaSurfaceActor *actor); - gboolean (* is_argb32) (MetaSurfaceActor *actor); - gboolean (* is_visible) (MetaSurfaceActor *actor); - - void (* freeze) (MetaSurfaceActor *actor); - void (* thaw) (MetaSurfaceActor *actor); - gboolean (* is_frozen) (MetaSurfaceActor *actor); - - gboolean (* should_unredirect) (MetaSurfaceActor *actor); - void (* set_unredirected) (MetaSurfaceActor *actor, - gboolean unredirected); }; struct _MetaSurfaceActor @@ -49,35 +36,32 @@ struct _MetaSurfaceActor GType meta_surface_actor_get_type (void); +MetaSurfaceActor *meta_surface_actor_new (void); + cairo_surface_t *meta_surface_actor_get_image (MetaSurfaceActor *self, cairo_rectangle_int_t *clip); MetaShapedTexture *meta_surface_actor_get_texture (MetaSurfaceActor *self); -gboolean meta_surface_actor_is_obscured (MetaSurfaceActor *self); +gboolean meta_surface_actor_damage_all (MetaSurfaceActor *self, + cairo_region_t *unobscured_region); +gboolean meta_surface_actor_damage_area (MetaSurfaceActor *self, + int x, + int y, + int width, + int height, + cairo_region_t *unobscured_region); + +void meta_surface_actor_set_texture (MetaSurfaceActor *self, + CoglTexture *texture); +void meta_surface_actor_attach_wayland_buffer (MetaSurfaceActor *self, + MetaWaylandBuffer *buffer); void meta_surface_actor_set_input_region (MetaSurfaceActor *self, cairo_region_t *region); void meta_surface_actor_set_opaque_region (MetaSurfaceActor *self, cairo_region_t *region); -gboolean meta_surface_actor_redraw_area (MetaSurfaceActor *actor, - int x, int y, int width, int height); - -void meta_surface_actor_process_damage (MetaSurfaceActor *actor, - int x, int y, int width, int height); -void meta_surface_actor_pre_paint (MetaSurfaceActor *actor); -gboolean meta_surface_actor_is_argb32 (MetaSurfaceActor *actor); -gboolean meta_surface_actor_is_visible (MetaSurfaceActor *actor); - -void meta_surface_actor_freeze (MetaSurfaceActor *actor); -void meta_surface_actor_thaw (MetaSurfaceActor *actor); -gboolean meta_surface_actor_is_frozen (MetaSurfaceActor *actor); - -gboolean meta_surface_actor_should_unredirect (MetaSurfaceActor *actor); -void meta_surface_actor_set_unredirected (MetaSurfaceActor *actor, - gboolean unredirected); - G_END_DECLS #endif /* META_SURFACE_ACTOR_PRIVATE_H */ diff --git a/src/compositor/meta-window-actor-private.h b/src/compositor/meta-window-actor-private.h index 9c6a8476e..82326d29b 100644 --- a/src/compositor/meta-window-actor-private.h +++ b/src/compositor/meta-window-actor-private.h @@ -39,13 +39,13 @@ void meta_window_actor_frame_complete (MetaWindowActor *self, void meta_window_actor_invalidate_shadow (MetaWindowActor *self); +void meta_window_actor_set_redirected (MetaWindowActor *self, gboolean state); + +gboolean meta_window_actor_should_unredirect (MetaWindowActor *self); + void meta_window_actor_get_shape_bounds (MetaWindowActor *self, cairo_rectangle_int_t *bounds); -gboolean meta_window_actor_should_unredirect (MetaWindowActor *self); -void meta_window_actor_set_unredirected (MetaWindowActor *self, - gboolean unredirected); - gboolean meta_window_actor_effect_in_progress (MetaWindowActor *self); void meta_window_actor_sync_actor_geometry (MetaWindowActor *self, gboolean did_placement); @@ -59,6 +59,9 @@ void meta_window_actor_set_updates_frozen (MetaWindowActor *self, void meta_window_actor_queue_frame_drawn (MetaWindowActor *self, gboolean no_delay_frame); +void meta_window_actor_set_unobscured_region (MetaWindowActor *self, + cairo_region_t *unobscured_region); + void meta_window_actor_effect_completed (MetaWindowActor *actor, gulong event); diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 4745d96ac..e7a922025 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -10,6 +10,10 @@ #include +#include +#include +#include + #include #include #include /* for gdk_rectangle_union() */ @@ -26,14 +30,21 @@ #include "meta-shaped-texture-private.h" #include "meta-shadow-factory-private.h" #include "meta-window-actor-private.h" +#include "meta-surface-actor.h" #include "meta-texture-rectangle.h" #include "region-utils.h" #include "meta-wayland-private.h" #include "monitor-private.h" #include "meta-cullable.h" -#include "meta-surface-actor.h" -#include "meta-surface-actor-x11.h" +enum { + POSITION_CHANGED, + SIZE_CHANGED, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = {0}; + struct _MetaWindowActorPrivate { @@ -61,13 +72,22 @@ struct _MetaWindowActorPrivate /* The region we should clip to when painting the shadow */ cairo_region_t *shadow_clip; - /* Extracted size-invariant shape used for shadows */ - MetaWindowShape *shadow_shape; - char * shadow_class; + /* The region that is visible, used to optimize out redraws */ + cairo_region_t *unobscured_region; guint send_frame_messages_timer; gint64 frame_drawn_time; + /* Extracted size-invariant shape used for shadows */ + MetaWindowShape *shadow_shape; + + gint last_width; + gint last_height; + + gint freeze_count; + + char * shadow_class; + /* * These need to be counters rather than flags, since more plugins * can implement same effect; the practicality of stacking effects @@ -82,7 +102,12 @@ struct _MetaWindowActorPrivate /* List of FrameData for recent frames */ GList *frames; + Pixmap back_pixmap; /* Not used in wayland compositor mode */ + Damage damage; /* Not used in wayland compositor mode */ + guint visible : 1; + guint mapped : 1; + guint argb32 : 1; guint disposed : 1; guint redecorating : 1; @@ -99,7 +124,24 @@ struct _MetaWindowActorPrivate guint no_shadow : 1; + + /* + * None of these are used in wayland compositor mode... + */ + + guint needs_damage_all : 1; + guint received_x11_damage : 1; + + guint needs_pixmap : 1; + + guint x11_size_changed : 1; guint updates_frozen : 1; + + guint unredirected : 1; + + /* This is used to detect fullscreen windows that need to be unredirected */ + guint full_damage_frames_count; + guint does_full_damage : 1; }; typedef struct _FrameData FrameData; @@ -136,6 +178,7 @@ static gboolean meta_window_actor_get_paint_volume (ClutterActor *actor, ClutterPaintVolume *volume); +static void meta_window_actor_detach_x11_pixmap (MetaWindowActor *self); static gboolean meta_window_actor_has_shadow (MetaWindowActor *self); static void meta_window_actor_handle_updates (MetaWindowActor *self); @@ -206,6 +249,19 @@ meta_window_actor_class_init (MetaWindowActorClass *klass) g_object_class_install_property (object_class, PROP_SHADOW_CLASS, pspec); + + signals[POSITION_CHANGED] = + g_signal_new ("position-changed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 0); + signals[SIZE_CHANGED] = + g_signal_new ("size-changed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 0); } static void @@ -226,6 +282,9 @@ window_decorated_notify (MetaWindow *mw, { MetaWindowActor *self = META_WINDOW_ACTOR (data); MetaWindowActorPrivate *priv = self->priv; + MetaScreen *screen = priv->screen; + MetaDisplay *display = meta_screen_get_display (screen); + Display *xdisplay = meta_display_get_xdisplay (display); /* * Basically, we have to reconstruct the the internals of this object @@ -233,6 +292,23 @@ window_decorated_notify (MetaWindow *mw, */ priv->redecorating = TRUE; + if (!meta_is_wayland_compositor ()) + { + meta_window_actor_detach_x11_pixmap (self); + + /* + * First of all, clean up any resources we are currently using and will + * be replacing. + */ + if (priv->damage != None) + { + meta_error_trap_push (display); + XDamageDestroy (xdisplay, priv->damage); + meta_error_trap_pop (display); + priv->damage = None; + } + } + /* * Recreate the contents. */ @@ -255,13 +331,8 @@ surface_allocation_changed_notify (ClutterActor *actor, { meta_window_actor_sync_actor_geometry (self, FALSE); meta_window_actor_update_shape (self); -} -static gboolean -is_argb32 (MetaWindowActor *self) -{ - MetaWindowActorPrivate *priv = self->priv; - return meta_surface_actor_is_argb32 (priv->surface); + g_signal_emit (self, signals[SIZE_CHANGED], 0); } static gboolean @@ -270,84 +341,7 @@ is_non_opaque (MetaWindowActor *self) MetaWindowActorPrivate *priv = self->priv; MetaWindow *window = priv->window; - return is_argb32 (self) || (window->opacity != 0xFF); -} - -static gboolean -is_frozen (MetaWindowActor *self) -{ - MetaWindowActorPrivate *priv = self->priv; - return meta_surface_actor_is_frozen (priv->surface); -} - -static void -meta_window_actor_freeze (MetaWindowActor *self) -{ - MetaWindowActorPrivate *priv = self->priv; - meta_surface_actor_freeze (priv->surface); -} - -static void -meta_window_actor_thaw (MetaWindowActor *self) -{ - MetaWindowActorPrivate *priv = self->priv; - - meta_surface_actor_thaw (priv->surface); - - if (meta_surface_actor_is_frozen (priv->surface)) - return; - - /* We sometimes ignore moves and resizes on frozen windows */ - meta_window_actor_sync_actor_geometry (self, FALSE); - - /* We do this now since we might be going right back into the - * frozen state */ - meta_window_actor_handle_updates (self); -} - -static void -set_surface_actor (MetaWindowActor *self, - MetaSurfaceActor *surface) -{ - MetaWindowActorPrivate *priv = self->priv; - - if (priv->surface) - { - g_object_unref (priv->surface); - clutter_actor_remove_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface)); - } - - priv->surface = surface; - - if (priv->surface) - { - g_object_ref_sink (priv->surface); - clutter_actor_add_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface)); - - g_signal_connect_object (priv->surface, "allocation-changed", - G_CALLBACK (surface_allocation_changed_notify), self, 0); - } - - meta_window_actor_update_shape (self); -} - -static void -meta_window_actor_sync_surface_actor (MetaWindowActor *self) -{ - MetaWindowActorPrivate *priv = self->priv; - MetaWindow *window = priv->window; - - MetaSurfaceActor *surface = NULL; - - if (window) - { - if (window->surface) - surface = window->surface->surface_actor; - else if (!meta_is_wayland_compositor ()) - surface = meta_surface_actor_x11_new (window); - } - - set_surface_actor (self, surface); + return priv->argb32 || (window->opacity != 0xFF); } static void @@ -356,10 +350,47 @@ meta_window_actor_constructed (GObject *object) MetaWindowActor *self = META_WINDOW_ACTOR (object); MetaWindowActorPrivate *priv = self->priv; MetaWindow *window = priv->window; + Window xwindow = meta_window_get_toplevel_xwindow (window); + MetaScreen *screen = meta_window_get_screen (window); + MetaDisplay *display = meta_screen_get_display (screen); + Display *xdisplay = meta_display_get_xdisplay (display); - priv->screen = window->screen; + priv->screen = screen; + + if (!meta_is_wayland_compositor ()) + priv->damage = XDamageCreate (xdisplay, xwindow, + XDamageReportBoundingBox); + + if (window->client_type == META_WINDOW_CLIENT_TYPE_X11) + { + XRenderPictFormat *format; + + format = XRenderFindVisualFormat (xdisplay, window->xvisual); + + if (format && format->type == PictTypeDirect && format->direct.alphaMask) + priv->argb32 = TRUE; + } + else + { + /* XXX: parse shm formats to determine argb32 */ + priv->argb32 = TRUE; + } + + if (!priv->surface) + { + if (window->surface) + priv->surface = window->surface->surface_actor; + else + priv->surface = meta_surface_actor_new (); + g_object_ref_sink (priv->surface); + + clutter_actor_add_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface)); + + g_signal_connect_object (priv->surface, "allocation-changed", + G_CALLBACK (surface_allocation_changed_notify), self, 0); + meta_window_actor_update_shape (self); + } - meta_window_actor_sync_surface_actor (self); meta_window_actor_update_opacity (self); /* Start off with an empty shape region to maintain the invariant @@ -373,6 +404,8 @@ meta_window_actor_dispose (GObject *object) MetaWindowActor *self = META_WINDOW_ACTOR (object); MetaWindowActorPrivate *priv = self->priv; MetaScreen *screen; + MetaDisplay *display; + Display *xdisplay; MetaCompScreen *info; if (priv->disposed) @@ -383,12 +416,16 @@ meta_window_actor_dispose (GObject *object) screen = priv->screen; info = meta_screen_get_compositor_data (screen); + if (!meta_is_wayland_compositor ()) + meta_window_actor_detach_x11_pixmap (self); + if (priv->send_frame_messages_timer != 0) { g_source_remove (priv->send_frame_messages_timer); priv->send_frame_messages_timer = 0; } + g_clear_pointer (&priv->unobscured_region, cairo_region_destroy); g_clear_pointer (&priv->shape_region, cairo_region_destroy); g_clear_pointer (&priv->shadow_clip, cairo_region_destroy); @@ -397,11 +434,26 @@ meta_window_actor_dispose (GObject *object) g_clear_pointer (&priv->unfocused_shadow, meta_shadow_unref); g_clear_pointer (&priv->shadow_shape, meta_window_shape_unref); + if (!meta_is_wayland_compositor () && priv->damage != None) + { + display = meta_screen_get_display (screen); + xdisplay = meta_display_get_xdisplay (display); + + meta_error_trap_push (display); + XDamageDestroy (xdisplay, priv->damage); + meta_error_trap_pop (display); + + priv->damage = None; + } + info->windows = g_list_remove (info->windows, (gconstpointer) self); g_clear_object (&priv->window); - meta_window_actor_sync_surface_actor (self); + /* + * Release the extra reference we took on the actor. + */ + g_clear_object (&priv->surface); G_OBJECT_CLASS (meta_window_actor_parent_class)->dispose (object); } @@ -669,15 +721,12 @@ meta_window_actor_get_paint_volume (ClutterActor *actor, gdk_rectangle_union (&bounds, &shadow_bounds, &bounds); } - { - const ClutterPaintVolume *child_volume; - - child_volume = clutter_actor_get_transformed_paint_volume (CLUTTER_ACTOR (priv->surface), actor); - if (!child_volume) - return FALSE; - - clutter_paint_volume_union (volume, child_volume); - } + if (priv->unobscured_region) + { + cairo_rectangle_int_t unobscured_bounds; + cairo_region_get_extents (priv->unobscured_region, &unobscured_bounds); + gdk_rectangle_intersect (&bounds, &unobscured_bounds, &bounds); + } origin.x = bounds.x; origin.y = bounds.y; @@ -811,6 +860,66 @@ meta_window_actor_is_destroyed (MetaWindowActor *self) return self->priv->disposed; } +gboolean +meta_window_actor_is_override_redirect (MetaWindowActor *self) +{ + return meta_window_is_override_redirect (self->priv->window); +} + +/** + * meta_window_actor_get_workspace: + * @self: #MetaWindowActor + * + * Returns the index of workspace on which this window is located; if the + * window is sticky, or is not currently located on any workspace, returns -1. + * This function is deprecated and should not be used in newly written code; + * meta_window_get_workspace() instead. + * + * Return value: (transfer none): index of workspace on which this window is + * located. + */ +gint +meta_window_actor_get_workspace (MetaWindowActor *self) +{ + MetaWindowActorPrivate *priv; + MetaWorkspace *workspace; + + if (!self) + return -1; + + priv = self->priv; + + if (!priv->window || meta_window_is_on_all_workspaces (priv->window)) + return -1; + + workspace = meta_window_get_workspace (priv->window); + + if (!workspace) + return -1; + + return meta_workspace_index (workspace); +} + +gboolean +meta_window_actor_showing_on_its_workspace (MetaWindowActor *self) +{ + if (!self) + return FALSE; + + /* If override redirect: */ + if (!self->priv->window) + return TRUE; + + return meta_window_showing_on_its_workspace (self->priv->window); +} + +static void +meta_window_actor_freeze (MetaWindowActor *self) +{ + if (!meta_is_wayland_compositor ()) + self->priv->freeze_count++; +} + static gboolean send_frame_messages_timeout (gpointer data) { @@ -865,6 +974,61 @@ queue_send_frame_messages_timeout (MetaWindowActor *self) priv->send_frame_messages_timer = g_timeout_add_full (META_PRIORITY_REDRAW, offset, send_frame_messages_timeout, self, NULL); } +static void +meta_window_actor_damage_all (MetaWindowActor *self) +{ + MetaWindowActorPrivate *priv = self->priv; + cairo_region_t *unobscured_region; + gboolean redraw_queued; + + if (!priv->needs_damage_all) + return; + + if (!priv->mapped || priv->needs_pixmap) + return; + + unobscured_region = + clutter_actor_has_mapped_clones (CLUTTER_ACTOR (priv->surface)) + ? NULL : priv->unobscured_region; + + redraw_queued = meta_surface_actor_damage_all (priv->surface, unobscured_region); + + priv->repaint_scheduled = priv->repaint_scheduled || redraw_queued; + priv->needs_damage_all = FALSE; +} + +static void +meta_window_actor_thaw (MetaWindowActor *self) +{ + if (!meta_is_wayland_compositor ()) + { + self->priv->freeze_count--; + + if (G_UNLIKELY (self->priv->freeze_count < 0)) + { + g_warning ("Error in freeze/thaw accounting."); + self->priv->freeze_count = 0; + return; + } + + if (self->priv->freeze_count) + return; + + /* We sometimes ignore moves and resizes on frozen windows */ + meta_window_actor_sync_actor_geometry (self, FALSE); + + /* We do this now since we might be going right back into the + * frozen state */ + meta_window_actor_handle_updates (self); + + /* Since we ignore damage events while a window is frozen for certain effects + * we may need to issue an update_area() covering the whole pixmap if we + * don't know what real damage has happened. */ + if (self->priv->needs_damage_all) + meta_window_actor_damage_all (self); + } +} + void meta_window_actor_queue_frame_drawn (MetaWindowActor *self, gboolean no_delay_frame) @@ -886,7 +1050,17 @@ meta_window_actor_queue_frame_drawn (MetaWindowActor *self, if (!priv->repaint_scheduled) { - gboolean is_obscured = meta_surface_actor_is_obscured (priv->surface); + gboolean is_obscured = FALSE; + + /* Find out whether the window is completly obscured */ + if (priv->unobscured_region) + { + cairo_region_t *unobscured_window_region; + unobscured_window_region = cairo_region_copy (priv->shape_region); + cairo_region_intersect (unobscured_window_region, priv->unobscured_region); + is_obscured = cairo_region_is_empty (unobscured_window_region); + cairo_region_destroy (unobscured_window_region); + } /* A frame was marked by the client without actually doing any * damage or any unobscured, or while we had the window frozen @@ -900,7 +1074,7 @@ meta_window_actor_queue_frame_drawn (MetaWindowActor *self, { queue_send_frame_messages_timeout (self); } - else + else if (priv->mapped && (!meta_is_wayland_compositor () || !priv->needs_pixmap)) { const cairo_rectangle_int_t clip = { 0, 0, 1, 1 }; clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (priv->surface), &clip); @@ -919,6 +1093,36 @@ meta_window_actor_effect_in_progress (MetaWindowActor *self) self->priv->destroy_in_progress); } +static gboolean +is_frozen (MetaWindowActor *self) +{ + return self->priv->freeze_count ? TRUE : FALSE; +} + +static void +meta_window_actor_queue_create_x11_pixmap (MetaWindowActor *self) +{ + MetaWindowActorPrivate *priv = self->priv; + + priv->needs_pixmap = TRUE; + + if (!priv->mapped) + return; + + if (is_frozen (self)) + return; + + /* This will cause the compositor paint function to be run + * if the actor is visible or a clone of the actor is visible. + * if the actor isn't visible in any way, then we don't + * need to repair the window anyways, and can wait until + * the stage is redrawn for some other reason + * + * The compositor paint function repairs all windows. + */ + clutter_actor_queue_redraw (CLUTTER_ACTOR (priv->surface)); +} + static gboolean is_freeze_thaw_effect (gulong event) { @@ -999,6 +1203,15 @@ meta_window_actor_after_effects (MetaWindowActor *self) meta_window_actor_sync_visibility (self); meta_window_actor_sync_actor_geometry (self, FALSE); + + if (!meta_is_wayland_compositor ()) + { + if (!meta_window_is_mapped (priv->window)) + meta_window_actor_detach_x11_pixmap (self); + + if (priv->needs_pixmap) + clutter_actor_queue_redraw (CLUTTER_ACTOR (priv->surface)); + } } void @@ -1073,19 +1286,95 @@ meta_window_actor_effect_completed (MetaWindowActor *self, meta_window_actor_after_effects (self); } +/* Called to drop our reference to a window backing pixmap that we + * previously obtained with XCompositeNameWindowPixmap. We do this + * when the window is unmapped or when we want to update to a new + * pixmap for a new size. + */ +static void +meta_window_actor_detach_x11_pixmap (MetaWindowActor *self) +{ + MetaWindowActorPrivate *priv = self->priv; + MetaScreen *screen = priv->screen; + MetaDisplay *display = meta_screen_get_display (screen); + Display *xdisplay = meta_display_get_xdisplay (display); + + if (!priv->back_pixmap) + return; + + /* Get rid of all references to the pixmap before freeing it; it's unclear whether + * you are supposed to be able to free a GLXPixmap after freeing the underlying + * pixmap, but it certainly doesn't work with current DRI/Mesa + */ + meta_surface_actor_set_texture (priv->surface, NULL); + cogl_flush(); + + XFreePixmap (xdisplay, priv->back_pixmap); + priv->back_pixmap = None; + + meta_window_actor_queue_create_x11_pixmap (self); +} + gboolean meta_window_actor_should_unredirect (MetaWindowActor *self) { + MetaWindow *metaWindow = meta_window_actor_get_meta_window (self); MetaWindowActorPrivate *priv = self->priv; - return meta_surface_actor_should_unredirect (priv->surface); + + if (meta_is_wayland_compositor ()) + return FALSE; + + if (meta_window_requested_dont_bypass_compositor (metaWindow)) + return FALSE; + + if (metaWindow->opacity != 0xFF) + return FALSE; + + if (metaWindow->shape_region != NULL) + return FALSE; + + if (priv->argb32 && !meta_window_requested_bypass_compositor (metaWindow)) + return FALSE; + + if (!meta_window_is_monitor_sized (metaWindow)) + return FALSE; + + if (meta_window_requested_bypass_compositor (metaWindow)) + return TRUE; + + if (meta_window_is_override_redirect (metaWindow)) + return TRUE; + + if (priv->does_full_damage) + return TRUE; + + return FALSE; } void -meta_window_actor_set_unredirected (MetaWindowActor *self, - gboolean unredirected) +meta_window_actor_set_redirected (MetaWindowActor *self, gboolean state) { - MetaWindowActorPrivate *priv = self->priv; - meta_surface_actor_set_unredirected (priv->surface, unredirected); + MetaWindow *metaWindow = meta_window_actor_get_meta_window (self); + MetaDisplay *display = meta_window_get_display (metaWindow); + + Display *xdisplay = meta_display_get_xdisplay (display); + Window xwin = meta_window_get_toplevel_xwindow (metaWindow); + + if (state) + { + meta_error_trap_push (display); + XCompositeRedirectWindow (xdisplay, xwin, CompositeRedirectManual); + meta_error_trap_pop (display); + meta_window_actor_detach_x11_pixmap (self); + self->priv->unredirected = FALSE; + } + else + { + meta_error_trap_push (display); + XCompositeUnredirectWindow (xdisplay, xwin, CompositeRedirectManual); + meta_error_trap_pop (display); + self->priv->unredirected = TRUE; + } } void @@ -1139,11 +1428,19 @@ meta_window_actor_sync_actor_geometry (MetaWindowActor *self, meta_window_get_input_rect (priv->window, &window_rect); - /* When running as a Wayland compositor we catch size changes when new - * buffers are attached */ - if (META_IS_SURFACE_ACTOR_X11 (priv->surface)) - meta_surface_actor_x11_set_size (META_SURFACE_ACTOR_X11 (priv->surface), - window_rect.width, window_rect.height); + /* When running as a display server we catch size changes when new + buffers are attached */ + if (!meta_is_wayland_compositor ()) + { + if (priv->last_width != window_rect.width || + priv->last_height != window_rect.height) + { + priv->x11_size_changed = TRUE; + + priv->last_width = window_rect.width; + priv->last_height = window_rect.height; + } + } /* Normally we want freezing a window to also freeze its position; this allows * windows to atomically move and resize together, either under app control, @@ -1155,6 +1452,15 @@ meta_window_actor_sync_actor_geometry (MetaWindowActor *self, if (is_frozen (self) && !did_placement) return; + if (!meta_is_wayland_compositor ()) + { + if (priv->x11_size_changed) + { + meta_window_actor_queue_create_x11_pixmap (self); + meta_window_actor_update_shape (self); + } + } + if (meta_window_actor_effect_in_progress (self)) return; @@ -1162,6 +1468,8 @@ meta_window_actor_sync_actor_geometry (MetaWindowActor *self, window_rect.x, window_rect.y); clutter_actor_set_size (CLUTTER_ACTOR (self), window_rect.width, window_rect.height); + + g_signal_emit (self, signals[POSITION_CHANGED], 0); } void @@ -1321,11 +1629,19 @@ meta_window_actor_new (MetaWindow *window) NULL); priv = self->priv; + priv->mapped = meta_window_toplevel_is_mapped (priv->window); - meta_window_actor_set_updates_frozen (self, meta_window_updates_are_frozen (priv->window)); - - if (META_IS_SURFACE_ACTOR_X11 (priv->surface)) + if (!meta_is_wayland_compositor ()) { + priv->last_width = -1; + priv->last_height = -1; + + if (priv->mapped) + meta_window_actor_queue_create_x11_pixmap (self); + + meta_window_actor_set_updates_frozen (self, + meta_window_updates_are_frozen (priv->window)); + /* If a window doesn't start off with updates frozen, we should * we should send a _NET_WM_FRAME_DRAWN immediately after the first drawn. */ @@ -1357,6 +1673,38 @@ meta_window_actor_new (MetaWindow *window) return self; } +void +meta_window_actor_mapped (MetaWindowActor *self) +{ + MetaWindowActorPrivate *priv = self->priv; + + g_return_if_fail (!priv->mapped); + + priv->mapped = TRUE; + + if (!meta_is_wayland_compositor ()) + meta_window_actor_queue_create_x11_pixmap (self); +} + +void +meta_window_actor_unmapped (MetaWindowActor *self) +{ + MetaWindowActorPrivate *priv = self->priv; + + g_return_if_fail (priv->mapped); + + priv->mapped = FALSE; + + if (meta_window_actor_effect_in_progress (self)) + return; + + if (!meta_is_wayland_compositor ()) + { + meta_window_actor_detach_x11_pixmap (self); + priv->needs_pixmap = FALSE; + } +} + #if 0 /* Print out a region; useful for debugging */ static void @@ -1398,6 +1746,30 @@ see_region (cairo_region_t *region, } #endif +/** + * meta_window_actor_set_unobscured_region: + * @self: a #MetaWindowActor + * @unobscured_region: the region of the screen that isn't completely + * obscured. + * + * Provides a hint as to what areas of the window need to queue + * redraws when damaged. Regions not in @unobscured_region are completely obscured. + */ +void +meta_window_actor_set_unobscured_region (MetaWindowActor *self, + cairo_region_t *unobscured_region) +{ + MetaWindowActorPrivate *priv = self->priv; + + if (priv->unobscured_region) + cairo_region_destroy (priv->unobscured_region); + + if (unobscured_region) + priv->unobscured_region = cairo_region_copy (unobscured_region); + else + priv->unobscured_region = NULL; +} + /** * meta_window_actor_set_clip_region_beneath: * @self: a #MetaWindowActor @@ -1437,6 +1809,16 @@ meta_window_actor_cull_out (MetaCullable *cullable, { MetaWindowActor *self = META_WINDOW_ACTOR (cullable); + if (!meta_is_wayland_compositor ()) + { + MetaCompScreen *info = meta_screen_get_compositor_data (self->priv->screen); + + /* Don't do any culling for the unredirected window */ + if (self == info->unredirected_window) + return; + } + + meta_window_actor_set_unobscured_region (self, unobscured_region); meta_cullable_cull_out_children (cullable, unobscured_region, clip_region); meta_window_actor_set_clip_region_beneath (self, clip_region); } @@ -1459,6 +1841,88 @@ cullable_iface_init (MetaCullableInterface *iface) iface->reset_culling = meta_window_actor_reset_culling; } +/* When running as a wayland compositor we don't make requests for + * replacement pixmaps when resizing windows, we will instead be + * asked to attach replacement buffers by the clients. */ +static void +check_needs_x11_pixmap (MetaWindowActor *self) +{ + MetaWindowActorPrivate *priv = self->priv; + MetaScreen *screen = priv->screen; + MetaDisplay *display = meta_screen_get_display (screen); + Display *xdisplay = meta_display_get_xdisplay (display); + MetaCompScreen *info = meta_screen_get_compositor_data (screen); + Window xwindow = meta_window_get_toplevel_xwindow (priv->window); + + if (!priv->needs_pixmap) + return; + + if (!priv->mapped) + return; + + if (xwindow == meta_screen_get_xroot (screen) || + xwindow == clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage))) + return; + + if (priv->x11_size_changed) + { + meta_window_actor_detach_x11_pixmap (self); + priv->x11_size_changed = FALSE; + } + + meta_error_trap_push (display); + + if (priv->back_pixmap == None) + { + CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ()); + CoglTexture *texture; + + meta_error_trap_push (display); + + priv->back_pixmap = XCompositeNameWindowPixmap (xdisplay, xwindow); + + if (meta_error_trap_pop_with_return (display) != Success) + { + /* Probably a BadMatch if the window isn't viewable; we could + * GrabServer/GetWindowAttributes/NameWindowPixmap/UngrabServer/Sync + * to avoid this, but there's no reason to take two round trips + * when one will do. (We need that Sync if we want to handle failures + * for any reason other than !viewable. That's unlikely, but maybe + * we'll BadAlloc or something.) + */ + priv->back_pixmap = None; + } + + if (priv->back_pixmap == None) + { + meta_verbose ("Unable to get named pixmap for %p\n", self); + goto out; + } + + texture = COGL_TEXTURE (cogl_texture_pixmap_x11_new (ctx, priv->back_pixmap, FALSE, NULL)); + if (G_UNLIKELY (!cogl_texture_pixmap_x11_is_using_tfp_extension (COGL_TEXTURE_PIXMAP_X11 (texture)))) + g_warning ("NOTE: Not using GLX TFP!\n"); + + meta_surface_actor_set_texture (META_SURFACE_ACTOR (priv->surface), texture); + + /* ::size-changed is supposed to refer to meta_window_get_frame_rect(). + * Emitting it here works pretty much OK because a new value of the + * *input* rect (which is the outer rect with the addition of invisible + * borders) forces a new pixmap and we get here. In the rare case where + * a change to the window size was exactly balanced by a change to the + * invisible borders, we would miss emitting the signal. We would also + * emit spurious signals when we get a new pixmap without a new size, + * but that should be mostly harmless. + */ + g_signal_emit (self, signals[SIZE_CHANGED], 0); + } + + priv->needs_pixmap = FALSE; + + out: + meta_error_trap_pop (display); +} + static void check_needs_shadow (MetaWindowActor *self) { @@ -1469,6 +1933,9 @@ check_needs_shadow (MetaWindowActor *self) gboolean should_have_shadow; gboolean appears_focused; + if (!priv->mapped) + return; + /* Calling meta_window_actor_has_shadow() here at every pre-paint is cheap * and avoids the need to explicitly handle window type changes, which * we would do if tried to keep track of when we might be adding or removing @@ -1526,14 +1993,68 @@ meta_window_actor_process_x11_damage (MetaWindowActor *self, XDamageNotifyEvent *event) { MetaWindowActorPrivate *priv = self->priv; + MetaCompScreen *info = meta_screen_get_compositor_data (priv->screen); + gboolean redraw_queued; + cairo_region_t *unobscured_region; - g_assert (!meta_is_wayland_compositor ()); + priv->received_x11_damage = TRUE; + + if (meta_window_is_fullscreen (priv->window) && g_list_last (info->windows)->data == self && !priv->unredirected) + { + MetaRectangle window_rect; + meta_window_get_frame_rect (priv->window, &window_rect); + + if (window_rect.x == event->area.x && + window_rect.y == event->area.y && + window_rect.width == event->area.width && + window_rect.height == event->area.height) + priv->full_damage_frames_count++; + else + priv->full_damage_frames_count = 0; + + if (priv->full_damage_frames_count >= 100) + priv->does_full_damage = TRUE; + } + + /* Drop damage event for unredirected windows */ + if (priv->unredirected) + return; + + if (is_frozen (self)) + { + /* The window is frozen due to an effect in progress: we ignore damage + * here on the off chance that this will stop the corresponding + * texture_from_pixmap from being update. + * + * needs_damage_all tracks that some unknown damage happened while the + * window was frozen so that when the window becomes unfrozen we can + * issue a full window update to cover any lost damage. + * + * It should be noted that this is an unreliable mechanism since it's + * quite likely that drivers will aim to provide a zero-copy + * implementation of the texture_from_pixmap extension and in those cases + * any drawing done to the window is always immediately reflected in the + * texture regardless of damage event handling. + */ + priv->needs_damage_all = TRUE; + return; + } + + if (!priv->mapped || priv->needs_pixmap) + return; + + unobscured_region = + clutter_actor_has_mapped_clones (CLUTTER_ACTOR (priv->surface)) + ? NULL : priv->unobscured_region; + redraw_queued = meta_surface_actor_damage_area (priv->surface, + event->area.x, + event->area.y, + event->area.width, + event->area.height, + unobscured_region); + + priv->repaint_scheduled = priv->repaint_scheduled || redraw_queued; - meta_surface_actor_process_damage (priv->surface, - event->area.x, - event->area.y, - event->area.width, - event->area.height); } void @@ -1761,9 +2282,8 @@ meta_window_actor_update_opaque_region (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; cairo_region_t *opaque_region; - gboolean argb32 = is_argb32 (self); - if (argb32 && priv->window->opaque_region != NULL) + if (priv->argb32 && priv->window->opaque_region != NULL) { MetaFrameBorders borders; @@ -1783,7 +2303,7 @@ meta_window_actor_update_opaque_region (MetaWindowActor *self) cairo_region_translate (opaque_region, borders.total.left, borders.total.top); cairo_region_intersect (opaque_region, priv->shape_region); } - else if (argb32) + else if (priv->argb32) opaque_region = NULL; else opaque_region = cairo_region_reference (priv->shape_region); @@ -1799,6 +2319,9 @@ check_needs_reshape (MetaWindowActor *self) MetaFrameBorders borders; cairo_rectangle_int_t client_area; + if (!priv->mapped) + return; + if (!priv->needs_reshape) return; @@ -1840,6 +2363,9 @@ static void meta_window_actor_handle_updates (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; + MetaScreen *screen = priv->screen; + MetaDisplay *display = meta_screen_get_display (screen); + Display *xdisplay = meta_display_get_xdisplay (display); if (is_frozen (self)) { @@ -1848,10 +2374,45 @@ meta_window_actor_handle_updates (MetaWindowActor *self) return; } - meta_surface_actor_pre_paint (priv->surface); + if (!meta_is_wayland_compositor ()) + { + if (priv->unredirected) + { + /* Nothing to do here until/if the window gets redirected again */ + return; + } - if (!meta_surface_actor_is_visible (priv->surface)) - return; + if (priv->received_x11_damage) + { + meta_error_trap_push (display); + XDamageSubtract (xdisplay, priv->damage, None, None); + meta_error_trap_pop (display); + + /* We need to make sure that any X drawing that happens before the + * XDamageSubtract() 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. + * + * Xorg and open source driver specifics: + * + * The X server makes sure to flush drawing to the kernel before + * sending out damage events, but since we use DamageReportBoundingBox + * there may be drawing between the last damage event and the + * XDamageSubtract() that needs to be flushed as well. + * + * Xorg always makes sure that drawing is flushed to the kernel + * before writing events or responses to the client, so any round trip + * request at this point is sufficient to flush the GLX buffers. + */ + XSync (xdisplay, False); + + priv->received_x11_damage = FALSE; + } + + check_needs_x11_pixmap (self); + } check_needs_reshape (self); check_needs_shadow (self); @@ -2040,16 +2601,20 @@ void meta_window_actor_set_updates_frozen (MetaWindowActor *self, gboolean updates_frozen) { - MetaWindowActorPrivate *priv = self->priv; - - updates_frozen = updates_frozen != FALSE; - - if (priv->updates_frozen != updates_frozen) + /* On wayland we shouldn't need to ever freeze updates... */ + if (!meta_is_wayland_compositor ()) { - priv->updates_frozen = updates_frozen; - if (updates_frozen) - meta_window_actor_freeze (self); - else - meta_window_actor_thaw (self); + MetaWindowActorPrivate *priv = self->priv; + + updates_frozen = updates_frozen != FALSE; + + if (priv->updates_frozen != updates_frozen) + { + priv->updates_frozen = updates_frozen; + if (updates_frozen) + meta_window_actor_freeze (self); + else + meta_window_actor_thaw (self); + } } } diff --git a/src/compositor/meta-window-group.c b/src/compositor/meta-window-group.c index 542060531..9554571b0 100644 --- a/src/compositor/meta-window-group.c +++ b/src/compositor/meta-window-group.c @@ -115,6 +115,8 @@ meta_window_group_paint (ClutterActor *actor) { cairo_region_t *clip_region; cairo_region_t *unobscured_region; + ClutterActorIter iter; + ClutterActor *child; cairo_rectangle_int_t visible_rect, clip_rect; int paint_x_offset, paint_y_offset; int paint_x_origin, paint_y_origin; @@ -123,6 +125,18 @@ meta_window_group_paint (ClutterActor *actor) MetaWindowGroup *window_group = META_WINDOW_GROUP (actor); ClutterActor *stage = clutter_actor_get_stage (actor); + /* Start off by treating all windows as completely unobscured, so damage anywhere + * in a window queues redraws, but confine it more below. */ + clutter_actor_iter_init (&iter, actor); + while (clutter_actor_iter_next (&iter, &child)) + { + if (META_IS_WINDOW_ACTOR (child)) + { + MetaWindowActor *window_actor = META_WINDOW_ACTOR (child); + meta_window_actor_set_unobscured_region (window_actor, NULL); + } + } + /* Normally we expect an actor to be drawn at it's position on the screen. * However, if we're inside the paint of a ClutterClone, that won't be the * case and we need to compensate. We look at the position of the window @@ -170,8 +184,9 @@ meta_window_group_paint (ClutterActor *actor) if (info->unredirected_window != NULL) { cairo_rectangle_int_t unredirected_rect; + MetaWindow *window = meta_window_actor_get_meta_window (info->unredirected_window); - meta_window_get_frame_rect (info->unredirected_window, (MetaRectangle *)&unredirected_rect); + meta_window_get_frame_rect (window, (MetaRectangle *)&unredirected_rect); cairo_region_subtract_rectangle (unobscured_region, &unredirected_rect); cairo_region_subtract_rectangle (clip_region, &unredirected_rect); } diff --git a/src/compositor/plugins/default.c b/src/compositor/plugins/default.c index 892854b33..91b30c039 100644 --- a/src/compositor/plugins/default.c +++ b/src/compositor/plugins/default.c @@ -409,7 +409,7 @@ switch_workspace (MetaPlugin *plugin, ClutterActor *actor = CLUTTER_ACTOR (window_actor); gint win_workspace; - win_workspace = meta_window_get_workspace (meta_window_actor_get_meta_window (window_actor)); + win_workspace = meta_window_actor_get_workspace (window_actor); if (win_workspace == to || win_workspace == from) { diff --git a/src/core/display.c b/src/core/display.c index a11836c57..8a98cf5ab 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -2777,7 +2777,7 @@ handle_other_xevent (MetaDisplay *display, if (display->grab_op != META_GRAB_OP_NONE && display->grab_window == window && - window->frame == NULL) + ((window->frame == NULL) || !window->frame->mapped)) meta_display_end_grab_op (display, timestamp); if (!frame_was_receiver) diff --git a/src/core/frame.c b/src/core/frame.c index e54e86210..5fa7bee17 100644 --- a/src/core/frame.c +++ b/src/core/frame.c @@ -62,6 +62,7 @@ meta_window_ensure_frame (MetaWindow *window) frame->right_width = 0; frame->current_cursor = 0; + frame->mapped = FALSE; frame->is_flashing = FALSE; frame->borders_cached = FALSE; @@ -156,8 +157,6 @@ meta_window_ensure_frame (MetaWindow *window) /* Move keybindings to frame instead of window */ meta_window_grab_keys (window); - - meta_ui_map_frame (frame->window->screen->ui, frame->xwindow); } void diff --git a/src/core/frame.h b/src/core/frame.h index 8ac1c261e..0f1ebea4f 100644 --- a/src/core/frame.h +++ b/src/core/frame.h @@ -47,6 +47,7 @@ struct _MetaFrame int right_width; int bottom_height; + guint mapped : 1; guint need_reapply_frame_shape : 1; guint is_flashing : 1; /* used by the visual bell flash */ guint borders_cached : 1; diff --git a/src/core/window.c b/src/core/window.c index 13d8e2a92..b4a845d6a 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -215,8 +215,6 @@ enum FOCUS, RAISED, UNMANAGED, - SIZE_CHANGED, - POSITION_CHANGED, LAST_SIGNAL }; @@ -613,22 +611,6 @@ meta_window_class_init (MetaWindowClass *klass) G_STRUCT_OFFSET (MetaWindowClass, unmanaged), NULL, NULL, NULL, G_TYPE_NONE, 0); - - window_signals[POSITION_CHANGED] = - g_signal_new ("position-changed", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, NULL, - G_TYPE_NONE, 0); - - window_signals[SIZE_CHANGED] = - g_signal_new ("size-changed", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, NULL, - G_TYPE_NONE, 0); } static void @@ -810,35 +792,6 @@ meta_window_should_attach_to_parent (MetaWindow *window) } } -static gboolean -client_window_should_be_mapped (MetaWindow *window) -{ - return !window->shaded; -} - -static void -sync_client_window_mapped (MetaWindow *window) -{ - gboolean should_be_mapped = client_window_should_be_mapped (window); - - if (window->mapped == should_be_mapped) - return; - - window->mapped = should_be_mapped; - - meta_error_trap_push (window->display); - if (should_be_mapped) - { - XMapWindow (window->display->xdisplay, window->xwindow); - } - else - { - XUnmapWindow (window->display->xdisplay, window->xwindow); - window->unmaps_pending ++; - } - meta_error_trap_pop (window->display); -} - static MetaWindow* meta_window_new_shared (MetaDisplay *display, MetaScreen *screen, @@ -1334,6 +1287,9 @@ meta_window_new_shared (MetaDisplay *display, set_net_wm_state (window); } + if (screen->display->compositor) + meta_compositor_add_window (screen->display->compositor, window); + /* Sync stack changes */ meta_stack_thaw (window->screen->stack); @@ -1347,8 +1303,6 @@ meta_window_new_shared (MetaDisplay *display, /* disable show desktop mode unless we're a desktop component */ maybe_leave_show_desktop_mode (window); - sync_client_window_mapped (window); - meta_window_queue (window, META_QUEUE_CALC_SHOWING); /* See bug 303284; a transient of the given window can already exist, in which * case we think it should probably be shown. @@ -1613,8 +1567,7 @@ meta_window_new (MetaDisplay *display, META_WINDOW_CLIENT_TYPE_X11, NULL, xwindow, - /* XXX */ - !meta_is_wayland_compositor (), + TRUE, existing_wm_state, effect, &attrs); @@ -1807,13 +1760,10 @@ meta_window_unmanage (MetaWindow *window, if (window->display->compositor) { if (window->visible_to_compositor) - { - meta_compositor_hide_window (window->display->compositor, window, - META_COMP_EFFECT_DESTROY); + meta_compositor_hide_window (window->display->compositor, window, + META_COMP_EFFECT_DESTROY); - /* XXX - support destroy effects better */ - meta_compositor_remove_window (window->display->compositor, window); - } + meta_compositor_remove_window (window->display->compositor, window); } if (window->display->window_with_menu == window) @@ -2396,8 +2346,6 @@ implement_showing (MetaWindow *window, meta_verbose ("Implement showing = %d for window %s\n", showing, window->desc); - sync_client_window_mapped (window); - if (!showing) { /* When we manage a new window, we normally delay placing it @@ -2986,6 +2934,94 @@ window_would_be_covered (const MetaWindow *newbie) return FALSE; /* none found */ } +static gboolean +map_frame (MetaWindow *window) +{ + if (window->frame && !window->frame->mapped) + { + meta_topic (META_DEBUG_WINDOW_STATE, + "Frame actually needs map\n"); + window->frame->mapped = TRUE; + meta_ui_map_frame (window->screen->ui, window->frame->xwindow); + return TRUE; + } + else + return FALSE; +} + +static gboolean +map_client_window (MetaWindow *window) +{ + if (!window->mapped) + { + meta_topic (META_DEBUG_WINDOW_STATE, + "%s actually needs map\n", window->desc); + window->mapped = TRUE; + meta_error_trap_push (window->display); + XMapWindow (window->display->xdisplay, window->xwindow); + meta_error_trap_pop (window->display); + + return TRUE; + } + else + return FALSE; +} + +static gboolean +unmap_client_window (MetaWindow *window, + const char *reason) +{ + if (window->mapped) + { + meta_topic (META_DEBUG_WINDOW_STATE, + "%s actually needs unmap%s\n", + window->desc, reason); + meta_topic (META_DEBUG_WINDOW_STATE, + "Incrementing unmaps_pending on %s%s\n", + window->desc, reason); + window->mapped = FALSE; + window->unmaps_pending += 1; + meta_error_trap_push (window->display); + XUnmapWindow (window->display->xdisplay, window->xwindow); + meta_error_trap_pop (window->display); + + return TRUE; + } + else + return FALSE; +} + +/** + * meta_window_is_mapped: + * @window: a #MetaWindow + * + * Determines whether the X window for the MetaWindow is mapped. + */ +gboolean +meta_window_is_mapped (MetaWindow *window) +{ + return window->mapped; +} + +/** + * meta_window_toplevel_is_mapped: + * @window: a #MetaWindow + * + * Determines whether the toplevel X window for the MetaWindow is + * mapped. (The frame window is mapped even without the client window + * when a window is shaded.) + * + * Return Value: %TRUE if the toplevel is mapped. + */ +gboolean +meta_window_toplevel_is_mapped (MetaWindow *window) +{ + /* The frame is mapped but not the client window when the window + * is shaded. + */ + return window->mapped || (window->frame && window->frame->mapped); +} + static void meta_window_force_placement (MetaWindow *window) { @@ -3024,12 +3060,16 @@ meta_window_show (MetaWindow *window) gboolean place_on_top_on_map; gboolean needs_stacking_adjustment; MetaWindow *focus_window; + gboolean toplevel_was_mapped; + gboolean toplevel_now_mapped; gboolean notify_demands_attention = FALSE; meta_topic (META_DEBUG_WINDOW_STATE, "Showing window %s, shaded: %d iconic: %d placed: %d\n", window->desc, window->shaded, window->iconic, window->placed); + toplevel_was_mapped = meta_window_toplevel_is_mapped (window); + focus_window = window->display->focus_window; /* May be NULL! */ did_show = FALSE; window_state_on_map (window, &takes_focus_on_map, &place_on_top_on_map); @@ -3156,18 +3196,46 @@ meta_window_show (MetaWindow *window) } } - if (window->hidden) + /* Shaded means the frame is mapped but the window is not */ + + if (map_frame (window)) + did_show = TRUE; + + if (window->shaded) { - meta_stack_freeze (window->screen->stack); - window->hidden = FALSE; - meta_stack_thaw (window->screen->stack); - did_show = TRUE; + unmap_client_window (window, " (shading)"); + + if (!window->iconic) + { + window->iconic = TRUE; + set_wm_state (window, IconicState); + } + } + else + { + if (map_client_window (window)) + did_show = TRUE; + + if (window->hidden) + { + meta_stack_freeze (window->screen->stack); + window->hidden = FALSE; + meta_stack_thaw (window->screen->stack); + did_show = TRUE; + } + + if (window->iconic) + { + window->iconic = FALSE; + set_wm_state (window, NormalState); + } } - if (window->iconic) + toplevel_now_mapped = meta_window_toplevel_is_mapped (window); + if (toplevel_now_mapped != toplevel_was_mapped) { - window->iconic = FALSE; - set_wm_state (window, NormalState); + if (window->display->compositor) + meta_compositor_window_mapped (window->display->compositor, window); } if (!window->visible_to_compositor) @@ -3190,8 +3258,8 @@ meta_window_show (MetaWindow *window) break; } - meta_compositor_add_window (window->display->compositor, window); - meta_compositor_show_window (window->display->compositor, window, effect); + meta_compositor_show_window (window->display->compositor, + window, effect); } } @@ -3259,10 +3327,14 @@ static void meta_window_hide (MetaWindow *window) { gboolean did_hide; + gboolean toplevel_was_mapped; + gboolean toplevel_now_mapped; meta_topic (META_DEBUG_WINDOW_STATE, "Hiding window %s\n", window->desc); + toplevel_was_mapped = meta_window_toplevel_is_mapped (window); + if (window->visible_to_compositor) { window->visible_to_compositor = FALSE; @@ -3283,12 +3355,19 @@ meta_window_hide (MetaWindow *window) break; } - meta_compositor_hide_window (window->display->compositor, window, effect); + meta_compositor_hide_window (window->display->compositor, + window, effect); } } did_hide = FALSE; + /* If this is the first time that we've calculating the showing + * state of the window, the frame and client window might not + * yet be mapped, so we need to map them now */ + map_frame (window); + map_client_window (window); + if (!window->hidden) { meta_stack_freeze (window->screen->stack); @@ -3304,6 +3383,19 @@ meta_window_hide (MetaWindow *window) set_wm_state (window, IconicState); } + toplevel_now_mapped = meta_window_toplevel_is_mapped (window); + if (toplevel_now_mapped != toplevel_was_mapped) + { + if (window->display->compositor) + { + /* As above, we may be *mapping* live hidden windows */ + if (toplevel_now_mapped) + meta_compositor_window_mapped (window->display->compositor, window); + else + meta_compositor_window_unmapped (window->display->compositor, window); + } + } + set_net_wm_state (window); if (did_hide && window->struts) @@ -5396,12 +5488,6 @@ meta_window_move_resize_internal (MetaWindow *window, else if (is_user_action) save_user_window_placement (window); - if (need_move_frame) - g_signal_emit (window, window_signals[POSITION_CHANGED], 0); - - if (need_resize_client) - g_signal_emit (window, window_signals[SIZE_CHANGED], 0); - if (need_move_frame || need_resize_frame || need_move_client || need_resize_client || did_placement || is_wayland_resize) @@ -8131,7 +8217,7 @@ redraw_icon (MetaWindow *window) /* We could probably be smart and just redraw the icon here, * instead of the whole frame. */ - if (window->frame) + if (window->frame && (window->mapped || window->frame->mapped)) meta_ui_queue_frame_draw (window->screen->ui, window->frame->xwindow); } diff --git a/src/meta/compositor.h b/src/meta/compositor.h index 45c8b09dd..42ff0dd8e 100644 --- a/src/meta/compositor.h +++ b/src/meta/compositor.h @@ -75,10 +75,11 @@ gboolean meta_compositor_filter_keybinding (MetaCompositor *compositor, MetaScreen *screen, MetaKeyBinding *binding); -void meta_compositor_add_window (MetaCompositor *compositor, - MetaWindow *window); -void meta_compositor_remove_window (MetaCompositor *compositor, - MetaWindow *window); +void meta_compositor_add_window (MetaCompositor *compositor, + MetaWindow *window); +void meta_compositor_remove_window (MetaCompositor *compositor, + MetaWindow *window); + void meta_compositor_show_window (MetaCompositor *compositor, MetaWindow *window, MetaCompEffect effect); @@ -100,6 +101,10 @@ void meta_compositor_unmaximize_window (MetaCompositor *compositor, MetaRectangle *old_rect, MetaRectangle *new_rect); +void meta_compositor_window_mapped (MetaCompositor *compositor, + MetaWindow *window); +void meta_compositor_window_unmapped (MetaCompositor *compositor, + MetaWindow *window); void meta_compositor_sync_window_geometry (MetaCompositor *compositor, MetaWindow *window, gboolean did_placement); diff --git a/src/meta/meta-window-actor.h b/src/meta/meta-window-actor.h index 2055ca8fc..9f808a9ac 100644 --- a/src/meta/meta-window-actor.h +++ b/src/meta/meta-window-actor.h @@ -58,8 +58,11 @@ struct _MetaWindowActor GType meta_window_actor_get_type (void); Window meta_window_actor_get_x_window (MetaWindowActor *self); +gint meta_window_actor_get_workspace (MetaWindowActor *self); MetaWindow * meta_window_actor_get_meta_window (MetaWindowActor *self); ClutterActor * meta_window_actor_get_texture (MetaWindowActor *self); +gboolean meta_window_actor_is_override_redirect (MetaWindowActor *self); +gboolean meta_window_actor_showing_on_its_workspace (MetaWindowActor *self); gboolean meta_window_actor_is_destroyed (MetaWindowActor *self); #endif /* META_WINDOW_ACTOR_H */ diff --git a/src/meta/window.h b/src/meta/window.h index 430dc6bd9..ff2d037d3 100644 --- a/src/meta/window.h +++ b/src/meta/window.h @@ -189,6 +189,8 @@ gboolean meta_window_requested_bypass_compositor (MetaWindow *window); gboolean meta_window_requested_dont_bypass_compositor (MetaWindow *window); gint *meta_window_get_all_monitors (MetaWindow *window, gsize *length); +gboolean meta_window_is_mapped (MetaWindow *window); +gboolean meta_window_toplevel_is_mapped (MetaWindow *window); gboolean meta_window_get_icon_geometry (MetaWindow *window, MetaRectangle *rect); void meta_window_set_icon_geometry (MetaWindow *window, diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 43ed92557..1ca38e564 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -44,11 +44,11 @@ #include "meta-wayland-private.h" #include "meta-xwayland-private.h" #include "meta-wayland-stage.h" +#include "meta-surface-actor.h" #include "meta-wayland-seat.h" #include "meta-wayland-keyboard.h" #include "meta-wayland-pointer.h" #include "meta-wayland-data-device.h" - #include "meta-cursor-tracker-private.h" #include "display-private.h" #include "window-private.h" @@ -58,9 +58,6 @@ #include "meta-idle-monitor-private.h" #include "monitor-private.h" -#include "meta-surface-actor.h" -#include "meta-surface-actor-wayland.h" - static void surface_process_damage (MetaWaylandSurface *surface, cairo_region_t *region) @@ -71,8 +68,12 @@ surface_process_damage (MetaWaylandSurface *surface, { cairo_rectangle_int_t rect; cairo_region_get_rectangle (region, i, &rect); - meta_surface_actor_process_damage (surface->surface_actor, - rect.x, rect.y, rect.width, rect.height); + meta_surface_actor_damage_area (surface->surface_actor, + rect.x, + rect.y, + rect.width, + rect.height, + NULL); } } @@ -263,7 +264,7 @@ actor_surface_commit (MetaWaylandSurface *surface) { ensure_buffer_texture (buffer); meta_wayland_buffer_reference (&surface->buffer_ref, buffer); - meta_surface_actor_wayland_set_buffer (META_SURFACE_ACTOR_WAYLAND (surface->surface_actor), buffer); + meta_surface_actor_attach_wayland_buffer (surface_actor, buffer); changed = TRUE; } @@ -504,7 +505,7 @@ meta_wayland_surface_create (MetaWaylandCompositor *compositor, surface_handle_pending_buffer_destroy; wl_list_init (&surface->pending.frame_callback_list); - surface->surface_actor = g_object_ref_sink (meta_surface_actor_wayland_new (surface)); + surface->surface_actor = g_object_ref_sink (meta_surface_actor_new ()); return surface; } diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index c9be27205..02c5b7bc3 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -48,8 +48,6 @@ xserver_set_window_id (struct wl_client *client, { surface->window = window; window->surface = surface; - - meta_window_set_surface_mapped (window, TRUE); } } From 96fc93d744602153afe1167462af1e1080812abc Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 29 Jan 2014 10:23:58 -0500 Subject: [PATCH 408/889] xwayland: Reindent --- src/wayland/meta-xwayland.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index 02c5b7bc3..ab010f051 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -52,7 +52,7 @@ xserver_set_window_id (struct wl_client *client, } static const struct xserver_interface xserver_implementation = { - xserver_set_window_id + xserver_set_window_id }; static void @@ -123,7 +123,7 @@ create_lockfile (int display, int *display_out) /* ignore error and try the next display number */ display++; continue; - } + } close (fd); other = strtol (pid, &end, 0); @@ -135,7 +135,7 @@ create_lockfile (int display, int *display_out) /* ignore error and try the next display number */ display++; continue; - } + } if (kill (other, 0) < 0 && errno == ESRCH) { @@ -148,7 +148,7 @@ create_lockfile (int display, int *display_out) } g_free (filename); continue; - } + } g_free (filename); display++; @@ -240,11 +240,12 @@ bind_to_unix_socket (int display) return -1; } - if (listen (fd, 1) < 0) { + if (listen (fd, 1) < 0) + { unlink (addr.sun_path); close (fd); return -1; - } + } return fd; } @@ -310,8 +311,8 @@ meta_xwayland_start (MetaWaylandCompositor *compositor) lockfile = create_lockfile (display, &display); if (!lockfile) { - g_warning ("Failed to create an X lock file"); - return FALSE; + g_warning ("Failed to create an X lock file"); + return FALSE; } compositor->xwayland_abstract_fd = bind_to_abstract_socket (display); From 9c876722a032caebb671c4323a5c833cb937fc60 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 29 Jan 2014 10:27:16 -0500 Subject: [PATCH 409/889] xwayland: Use server protocol wrappers instead of wl_resource_post_event --- src/wayland/meta-xwayland.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index ab010f051..44f6c41b5 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -73,13 +73,8 @@ bind_xserver (struct wl_client *client, wl_resource_set_implementation (compositor->xserver_resource, &xserver_implementation, compositor, NULL); - wl_resource_post_event (compositor->xserver_resource, - XSERVER_LISTEN_SOCKET, - compositor->xwayland_abstract_fd); - - wl_resource_post_event (compositor->xserver_resource, - XSERVER_LISTEN_SOCKET, - compositor->xwayland_unix_fd); + xserver_send_listen_socket (compositor->xserver_resource, compositor->xwayland_abstract_fd); + xserver_send_listen_socket (compositor->xserver_resource, compositor->xwayland_unix_fd); /* Make sure xwayland will recieve the above sockets in a finite * time before unblocking the initialization mainloop since we are From c3b0faec82083a5cf0a8974254d232190c07be14 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 29 Jan 2014 12:38:13 -0500 Subject: [PATCH 410/889] main: Make sure to free any events that we get from Clutter --- src/core/main.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/core/main.c b/src/core/main.c index 89a9d06fd..f22bf8e55 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -302,8 +302,12 @@ event_dispatch (GSource *source, gpointer user_data) { ClutterEvent *event = clutter_event_get (); + if (event) - clutter_do_event (event); + { + clutter_do_event (event); + clutter_event_free (event); + } return TRUE; } From 799c27484dc7ba307d6f62311a1b468e27581676 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Sun, 12 Jan 2014 22:02:09 +0100 Subject: [PATCH 411/889] wayland: Report error when trying to stack subsurface incorrectly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Don't allow a client to stack a subsurface next to a subsurface with another parent, or to a non-parent non-subsurface surface. Signed-off-by: Jonas Ådahl https://bugzilla.gnome.org/show_bug.cgi?id=705502 --- src/wayland/meta-wayland-surface.c | 56 +++++++++++++++++++++++++++++- src/wayland/meta-wayland-surface.h | 7 ++++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 1ca38e564..e96c92228 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -999,7 +999,14 @@ wl_subsurface_destructor (struct wl_resource *resource) MetaWaylandSurfaceExtension *subsurface = wl_resource_get_user_data (resource); MetaWaylandSurface *surface = wl_container_of (subsurface, surface, subsurface); - unparent_actor (surface); + if (surface->sub.parent) + { + wl_list_remove (&surface->sub.parent_destroy_listener.link); + surface->sub.parent->subsurfaces = + g_list_remove (surface->sub.parent->subsurfaces, surface); + unparent_actor (surface); + surface->sub.parent = NULL; + } destroy_surface_extension (subsurface); } @@ -1022,6 +1029,16 @@ wl_subsurface_set_position (struct wl_client *client, clutter_actor_set_position (CLUTTER_ACTOR (surface->surface_actor), x, y); } +static gboolean +is_valid_sibling (MetaWaylandSurface *surface, MetaWaylandSurface *sibling) +{ + if (surface->sub.parent == sibling) + return TRUE; + if (surface->sub.parent == sibling->sub.parent) + return TRUE; + return FALSE; +} + static void wl_subsurface_place_above (struct wl_client *client, struct wl_resource *resource, @@ -1032,6 +1049,15 @@ wl_subsurface_place_above (struct wl_client *client, MetaWaylandSurface *surface = wl_container_of (subsurface, surface, subsurface); MetaWaylandSurface *sibling = wl_resource_get_user_data (sibling_resource); + if (!is_valid_sibling (surface, sibling)) + { + wl_resource_post_error (resource, WL_SUBSURFACE_ERROR_BAD_SURFACE, + "wl_subsurface::place_above: wl_surface@%d is " + "not a valid parent or sibling", + wl_resource_get_id (sibling->resource)); + return; + } + parent_actor = clutter_actor_get_parent (CLUTTER_ACTOR (surface->surface_actor)); clutter_actor_set_child_above_sibling (parent_actor, @@ -1049,6 +1075,15 @@ wl_subsurface_place_below (struct wl_client *client, MetaWaylandSurface *surface = wl_container_of (subsurface, surface, subsurface); MetaWaylandSurface *sibling = wl_resource_get_user_data (sibling_resource); + if (!is_valid_sibling (surface, sibling)) + { + wl_resource_post_error (resource, WL_SUBSURFACE_ERROR_BAD_SURFACE, + "wl_subsurface::place_below: wl_surface@%d is " + "not a valid parent or sibling", + wl_resource_get_id (sibling->resource)); + return; + } + parent_actor = clutter_actor_get_parent (CLUTTER_ACTOR (surface->surface_actor)); clutter_actor_set_child_below_sibling (parent_actor, @@ -1086,6 +1121,18 @@ wl_subcompositor_destroy (struct wl_client *client, wl_resource_destroy (resource); } +static void +surface_handle_parent_surface_destroyed (struct wl_listener *listener, + void *data) +{ + MetaWaylandSurface *surface = wl_container_of (listener, + surface, + sub.parent_destroy_listener); + + surface->sub.parent = NULL; + unparent_actor (surface); +} + static void wl_subcompositor_get_subsurface (struct wl_client *client, struct wl_resource *resource, @@ -1108,6 +1155,13 @@ wl_subcompositor_get_subsurface (struct wl_client *client, return; } + surface->sub.parent = parent; + surface->sub.parent_destroy_listener.notify = + surface_handle_parent_surface_destroyed; + wl_resource_add_destroy_listener (parent->resource, + &surface->sub.parent_destroy_listener); + parent->subsurfaces = g_list_append (parent->subsurfaces, surface); + clutter_actor_add_child (CLUTTER_ACTOR (parent->surface_actor), CLUTTER_ACTOR (surface->surface_actor)); } diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h index 9533731a6..fe2bfea3b 100644 --- a/src/wayland/meta-wayland-surface.h +++ b/src/wayland/meta-wayland-surface.h @@ -85,6 +85,13 @@ struct _MetaWaylandSurface MetaWaylandSurfaceExtension gtk_surface; MetaWaylandSurfaceExtension subsurface; + GList *subsurfaces; + + struct { + MetaWaylandSurface *parent; + struct wl_listener parent_destroy_listener; + } sub; + /* All the pending state, that wl_surface.commit will apply. */ MetaWaylandDoubleBufferedState pending; }; From 16de7f66fba535111f6a6cf82740637e1328b625 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Sun, 12 Jan 2014 23:17:29 +0100 Subject: [PATCH 412/889] wayland: Make wl_subsurface.set_position properly synchronized MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The position set by wl_subsurface.set_position should be applied when the parent surface invokes wl_surface.commit. Signed-off-by: Jonas Ådahl https://bugzilla.gnome.org/show_bug.cgi?id=705502 --- src/wayland/meta-wayland-surface.c | 25 ++++++++++++++++++++++++- src/wayland/meta-wayland-surface.h | 4 ++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index e96c92228..bd1feeafb 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -326,6 +326,9 @@ subsurface_surface_commit (MetaWaylandSurface *surface) } } +static void +wl_subsurface_parent_surface_committed (gpointer data, gpointer user_data); + static void meta_wayland_surface_commit (struct wl_client *client, struct wl_resource *resource) @@ -346,6 +349,10 @@ meta_wayland_surface_commit (struct wl_client *client, else if (surface->subsurface.resource) subsurface_surface_commit (surface); + g_list_foreach (surface->subsurfaces, + wl_subsurface_parent_surface_committed, + NULL); + if (surface->pending.buffer) { wl_list_remove (&surface->pending.buffer_destroy_listener.link); @@ -993,6 +1000,20 @@ bind_gtk_shell (struct wl_client *client, gtk_shell_send_capabilities (resource, GTK_SHELL_CAPABILITY_GLOBAL_APP_MENU); } +static void +wl_subsurface_parent_surface_committed (gpointer data, gpointer user_data) +{ + MetaWaylandSurface *surface = data; + + if (surface->sub.pending_pos) + { + clutter_actor_set_position (CLUTTER_ACTOR (surface->surface_actor), + surface->sub.pending_x, + surface->sub.pending_y); + surface->sub.pending_pos = FALSE; + } +} + static void wl_subsurface_destructor (struct wl_resource *resource) { @@ -1026,7 +1047,9 @@ wl_subsurface_set_position (struct wl_client *client, MetaWaylandSurfaceExtension *subsurface = wl_resource_get_user_data (resource); MetaWaylandSurface *surface = wl_container_of (subsurface, surface, subsurface); - clutter_actor_set_position (CLUTTER_ACTOR (surface->surface_actor), x, y); + surface->sub.pending_x = x; + surface->sub.pending_y = y; + surface->sub.pending_pos = TRUE; } static gboolean diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h index fe2bfea3b..32fa0fd33 100644 --- a/src/wayland/meta-wayland-surface.h +++ b/src/wayland/meta-wayland-surface.h @@ -90,6 +90,10 @@ struct _MetaWaylandSurface struct { MetaWaylandSurface *parent; struct wl_listener parent_destroy_listener; + + int32_t pending_x; + int32_t pending_y; + gboolean pending_pos; } sub; /* All the pending state, that wl_surface.commit will apply. */ From 9348c9bd4bfbd1081c4d1324068a964041c07e43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Sun, 12 Jan 2014 23:24:00 +0100 Subject: [PATCH 413/889] wayland: Make wl_subsurface.place_(above|below) properly synchronized MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The placement set by either wl_subsurface.place_above or wl_subsurface.place_below should be applied when the parent surface invokes wl_surface.commit. Signed-off-by: Jonas Ådahl https://bugzilla.gnome.org/show_bug.cgi?id=705502 --- src/wayland/meta-wayland-surface.c | 97 ++++++++++++++++++++++++++---- src/wayland/meta-wayland-surface.h | 1 + 2 files changed, 86 insertions(+), 12 deletions(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index bd1feeafb..f3455bc86 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -58,6 +58,19 @@ #include "meta-idle-monitor-private.h" #include "monitor-private.h" +typedef enum +{ + META_WAYLAND_SUBSURFACE_PLACEMENT_ABOVE, + META_WAYLAND_SUBSURFACE_PLACEMENT_BELOW +} MetaWaylandSubsurfacePlacement; + +typedef struct +{ + MetaWaylandSubsurfacePlacement placement; + MetaWaylandSurface *sibling; + struct wl_listener sibling_destroy_listener; +} MetaWaylandSubsurfacePlacementOp; + static void surface_process_damage (MetaWaylandSurface *surface, cairo_region_t *region) @@ -1012,6 +1025,44 @@ wl_subsurface_parent_surface_committed (gpointer data, gpointer user_data) surface->sub.pending_y); surface->sub.pending_pos = FALSE; } + + if (surface->sub.pending_placement_ops) + { + GSList *it; + for (it = surface->sub.pending_placement_ops; it; it = it->next) + { + MetaWaylandSubsurfacePlacementOp *op = it->data; + ClutterActor *surface_actor; + ClutterActor *parent_actor; + ClutterActor *sibling_actor; + + if (!op->sibling) + { + g_slice_free (MetaWaylandSubsurfacePlacementOp, op); + continue; + } + + surface_actor = CLUTTER_ACTOR (surface->surface_actor); + parent_actor = clutter_actor_get_parent (CLUTTER_ACTOR (surface->sub.parent)); + sibling_actor = CLUTTER_ACTOR (op->sibling->surface_actor); + + switch (op->placement) + { + case META_WAYLAND_SUBSURFACE_PLACEMENT_ABOVE: + clutter_actor_set_child_above_sibling (parent_actor, surface_actor, sibling_actor); + break; + case META_WAYLAND_SUBSURFACE_PLACEMENT_BELOW: + clutter_actor_set_child_below_sibling (parent_actor, surface_actor, sibling_actor); + break; + } + + wl_list_remove (&op->sibling_destroy_listener.link); + g_slice_free (MetaWaylandSubsurfacePlacementOp, op); + } + + g_slist_free (surface->sub.pending_placement_ops); + surface->sub.pending_placement_ops = NULL; + } } static void @@ -1062,12 +1113,39 @@ is_valid_sibling (MetaWaylandSurface *surface, MetaWaylandSurface *sibling) return FALSE; } +static void +subsurface_handle_pending_sibling_destroyed (struct wl_listener *listener, void *data) +{ + MetaWaylandSubsurfacePlacementOp *op = + wl_container_of (listener, op, sibling_destroy_listener); + + op->sibling = NULL; +} + +static void +queue_subsurface_placement (MetaWaylandSurface *surface, + MetaWaylandSurface *sibling, + MetaWaylandSubsurfacePlacement placement) +{ + MetaWaylandSubsurfacePlacementOp *op = + g_slice_new (MetaWaylandSubsurfacePlacementOp); + + op->placement = placement; + op->sibling = sibling; + op->sibling_destroy_listener.notify = + subsurface_handle_pending_sibling_destroyed; + wl_resource_add_destroy_listener (sibling->resource, + &op->sibling_destroy_listener); + + surface->sub.pending_placement_ops = + g_slist_append (surface->sub.pending_placement_ops, op); +} + static void wl_subsurface_place_above (struct wl_client *client, struct wl_resource *resource, struct wl_resource *sibling_resource) { - ClutterActor *parent_actor; MetaWaylandSurfaceExtension *subsurface = wl_resource_get_user_data (resource); MetaWaylandSurface *surface = wl_container_of (subsurface, surface, subsurface); MetaWaylandSurface *sibling = wl_resource_get_user_data (sibling_resource); @@ -1081,11 +1159,9 @@ wl_subsurface_place_above (struct wl_client *client, return; } - parent_actor = clutter_actor_get_parent (CLUTTER_ACTOR (surface->surface_actor)); - - clutter_actor_set_child_above_sibling (parent_actor, - CLUTTER_ACTOR (surface->surface_actor), - CLUTTER_ACTOR (sibling->surface_actor)); + queue_subsurface_placement (surface, + sibling, + META_WAYLAND_SUBSURFACE_PLACEMENT_ABOVE); } static void @@ -1093,7 +1169,6 @@ wl_subsurface_place_below (struct wl_client *client, struct wl_resource *resource, struct wl_resource *sibling_resource) { - ClutterActor *parent_actor; MetaWaylandSurfaceExtension *subsurface = wl_resource_get_user_data (resource); MetaWaylandSurface *surface = wl_container_of (subsurface, surface, subsurface); MetaWaylandSurface *sibling = wl_resource_get_user_data (sibling_resource); @@ -1107,11 +1182,9 @@ wl_subsurface_place_below (struct wl_client *client, return; } - parent_actor = clutter_actor_get_parent (CLUTTER_ACTOR (surface->surface_actor)); - - clutter_actor_set_child_below_sibling (parent_actor, - CLUTTER_ACTOR (surface->surface_actor), - CLUTTER_ACTOR (sibling->surface_actor)); + queue_subsurface_placement (surface, + sibling, + META_WAYLAND_SUBSURFACE_PLACEMENT_BELOW); } static void diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h index 32fa0fd33..c7b617ded 100644 --- a/src/wayland/meta-wayland-surface.h +++ b/src/wayland/meta-wayland-surface.h @@ -94,6 +94,7 @@ struct _MetaWaylandSurface int32_t pending_x; int32_t pending_y; gboolean pending_pos; + GSList *pending_placement_ops; } sub; /* All the pending state, that wl_surface.commit will apply. */ From 4f4b1bfc3705933c3126e2cccd1e48647d389b99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Mon, 13 Jan 2014 23:31:25 +0100 Subject: [PATCH 414/889] wayland: Support wl_subsurface.set_sync/set_desync MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement support for synchronous subsurfaces commits. This means that the client can, by calling wl_subsurface.set_sync, cause its surface state to be commited not until its parent commits. This will mean there will be will potentially be one more surface state (regions, buffer) at the same time: the active surface state, the mutable pending surface state, and the immutable surface state that was pending on last surface commit. Signed-off-by: Jonas Ådahl https://bugzilla.gnome.org/show_bug.cgi?id=705502 --- src/wayland/meta-wayland-surface.c | 196 ++++++++++++++++++++++------- src/wayland/meta-wayland-surface.h | 3 + 2 files changed, 155 insertions(+), 44 deletions(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index f3455bc86..069d0870e 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -266,14 +266,15 @@ cursor_surface_commit (MetaWaylandSurface *surface) } static gboolean -actor_surface_commit (MetaWaylandSurface *surface) +actor_surface_commit (MetaWaylandSurface *surface, + MetaWaylandDoubleBufferedState *pending) { MetaSurfaceActor *surface_actor = surface->surface_actor; - MetaWaylandBuffer *buffer = surface->pending.buffer; + MetaWaylandBuffer *buffer = pending->buffer; gboolean changed = FALSE; /* wl_surface.attach */ - if (surface->pending.newly_attached && buffer != surface->buffer_ref.buffer) + if (pending->newly_attached && buffer != surface->buffer_ref.buffer) { ensure_buffer_texture (buffer); meta_wayland_buffer_reference (&surface->buffer_ref, buffer); @@ -281,12 +282,12 @@ actor_surface_commit (MetaWaylandSurface *surface) changed = TRUE; } - surface_process_damage (surface, surface->pending.damage); + surface_process_damage (surface, pending->damage); - if (surface->pending.opaque_region) - meta_surface_actor_set_opaque_region (surface_actor, surface->pending.opaque_region); - if (surface->pending.input_region) - meta_surface_actor_set_input_region (surface_actor, surface->pending.input_region); + if (pending->opaque_region) + meta_surface_actor_set_opaque_region (surface_actor, pending->opaque_region); + if (pending->input_region) + meta_surface_actor_set_input_region (surface_actor, pending->input_region); return changed; } @@ -294,7 +295,7 @@ actor_surface_commit (MetaWaylandSurface *surface) static void toplevel_surface_commit (MetaWaylandSurface *surface) { - if (actor_surface_commit (surface)) + if (actor_surface_commit (surface, &surface->pending)) { MetaWindow *window = surface->window; MetaWaylandBuffer *buffer = surface->pending.buffer; @@ -318,10 +319,106 @@ toplevel_surface_commit (MetaWaylandSurface *surface) } } +static void +surface_handle_pending_buffer_destroy (struct wl_listener *listener, void *data) +{ + MetaWaylandDoubleBufferedState *state = + wl_container_of (listener, state, buffer_destroy_listener); + + state->buffer = NULL; +} + +static void +double_buffered_state_init (MetaWaylandDoubleBufferedState *state) +{ + state->newly_attached = FALSE; + state->buffer = NULL; + state->dx = 0; + state->dy = 0; + + state->damage = cairo_region_create (); + state->buffer_destroy_listener.notify = + surface_handle_pending_buffer_destroy; + wl_list_init (&state->frame_callback_list); +} + +static void +double_buffered_state_destroy (MetaWaylandDoubleBufferedState *state) +{ + MetaWaylandFrameCallback *cb, *next; + + g_clear_pointer (&state->damage, cairo_region_destroy); + g_clear_pointer (&state->input_region, cairo_region_destroy); + g_clear_pointer (&state->opaque_region, cairo_region_destroy); + + if (state->buffer) + wl_list_remove (&state->buffer_destroy_listener.link); + wl_list_for_each_safe (cb, next, &state->frame_callback_list, link) + wl_resource_destroy (cb->resource); +} + +static void +double_buffered_state_reset (MetaWaylandDoubleBufferedState *state) +{ + double_buffered_state_destroy (state); + double_buffered_state_init (state); +} + +static void +move_double_buffered_state (MetaWaylandDoubleBufferedState *from, + MetaWaylandDoubleBufferedState *to) +{ + if (from->buffer) + wl_list_remove (&from->buffer_destroy_listener.link); + + to->newly_attached = from->newly_attached; + from->newly_attached = FALSE; + + to->buffer = from->buffer; + from->buffer = NULL; + if (to->buffer) + wl_signal_add (&to->buffer->destroy_signal, &to->buffer_destroy_listener); + + to->dx = from->dx; + to->dy = from->dy; + from->dx = from->dy = 0; + + empty_region (to->damage); + cairo_region_union (to->damage, from->damage); + empty_region (from->damage); + + g_clear_pointer (&to->input_region, cairo_region_destroy); + g_clear_pointer (&to->opaque_region, cairo_region_destroy); + to->input_region = from->input_region; + to->opaque_region = from->opaque_region; + from->input_region = from->opaque_region = NULL; + + wl_list_init (&to->frame_callback_list); + wl_list_insert_list (&to->frame_callback_list, &from->frame_callback_list); + wl_list_init (&from->frame_callback_list); +} + static void subsurface_surface_commit (MetaWaylandSurface *surface) { - if (actor_surface_commit (surface)) + /* + * If the sub-surface is in synchronous mode, post-pone the commit of its + * state until the sub-surface parent commits. + * + * This is done by moving the various states (damage, input region, buffer + * etc.) from the buffered state pending commit to the sub-surface's pending + * buffered state. + * + * The sub-surface's pending buffered state will be committed to the + * associated surface when its parent surface is committed, or if the user + * issues a wl_subsurface.set_desync request. + */ + if (surface->sub.synchronous) + { + move_double_buffered_state (&surface->pending, + &surface->sub.pending_surface_state); + } + else if (actor_surface_commit (surface, &surface->pending)) { MetaSurfaceActor *surface_actor = surface->surface_actor; MetaWaylandBuffer *buffer = surface->pending.buffer; @@ -340,7 +437,13 @@ subsurface_surface_commit (MetaWaylandSurface *surface) } static void -wl_subsurface_parent_surface_committed (gpointer data, gpointer user_data); +subsurface_parent_surface_commited (MetaWaylandSurface *surface); + +static void +parent_surface_committed (gpointer data, gpointer user_data) +{ + subsurface_parent_surface_commited (data); +} static void meta_wayland_surface_commit (struct wl_client *client, @@ -363,7 +466,7 @@ meta_wayland_surface_commit (struct wl_client *client, subsurface_surface_commit (surface); g_list_foreach (surface->subsurfaces, - wl_subsurface_parent_surface_committed, + parent_surface_committed, NULL); if (surface->pending.buffer) @@ -372,17 +475,12 @@ meta_wayland_surface_commit (struct wl_client *client, surface->pending.buffer = NULL; } - surface->pending.dx = 0; - surface->pending.dy = 0; - surface->pending.newly_attached = FALSE; - g_clear_pointer (&surface->pending.opaque_region, cairo_region_destroy); - g_clear_pointer (&surface->pending.input_region, cairo_region_destroy); - empty_region (surface->pending.damage); - /* wl_surface.frame */ wl_list_insert_list (&compositor->frame_callbacks, &surface->pending.frame_callback_list); wl_list_init (&surface->pending.frame_callback_list); + + double_buffered_state_reset (&surface->pending); } static void @@ -418,7 +516,6 @@ static void meta_wayland_surface_free (MetaWaylandSurface *surface) { MetaWaylandCompositor *compositor = surface->compositor; - MetaWaylandFrameCallback *cb, *next; compositor->surfaces = g_list_remove (compositor->surfaces, surface); @@ -427,11 +524,7 @@ meta_wayland_surface_free (MetaWaylandSurface *surface) if (surface->pending.buffer) wl_list_remove (&surface->pending.buffer_destroy_listener.link); - cairo_region_destroy (surface->pending.damage); - - wl_list_for_each_safe (cb, next, - &surface->pending.frame_callback_list, link) - wl_resource_destroy (cb->resource); + double_buffered_state_destroy (&surface->pending); meta_wayland_compositor_repick (compositor); @@ -493,16 +586,6 @@ meta_wayland_surface_resource_destroy_cb (struct wl_resource *resource) } } -static void -surface_handle_pending_buffer_destroy (struct wl_listener *listener, - void *data) -{ - MetaWaylandSurface *surface = - wl_container_of (listener, surface, pending.buffer_destroy_listener); - - surface->pending.buffer = NULL; -} - MetaWaylandSurface * meta_wayland_surface_create (MetaWaylandCompositor *compositor, struct wl_client *wayland_client, @@ -519,11 +602,7 @@ meta_wayland_surface_create (MetaWaylandCompositor *compositor, wl_resource_set_implementation (surface->resource, &meta_wayland_surface_interface, surface, meta_wayland_surface_resource_destroy_cb); - surface->pending.damage = cairo_region_create (); - - surface->pending.buffer_destroy_listener.notify = - surface_handle_pending_buffer_destroy; - wl_list_init (&surface->pending.frame_callback_list); + double_buffered_state_init (&surface->pending); surface->surface_actor = g_object_ref_sink (meta_surface_actor_new ()); return surface; @@ -1014,9 +1093,11 @@ bind_gtk_shell (struct wl_client *client, } static void -wl_subsurface_parent_surface_committed (gpointer data, gpointer user_data) +subsurface_parent_surface_commited (MetaWaylandSurface *surface) { - MetaWaylandSurface *surface = data; + MetaWaylandCompositor *compositor = surface->compositor; + MetaWaylandDoubleBufferedState *pending_surface_state = + &surface->sub.pending_surface_state; if (surface->sub.pending_pos) { @@ -1063,6 +1144,17 @@ wl_subsurface_parent_surface_committed (gpointer data, gpointer user_data) g_slist_free (surface->sub.pending_placement_ops); surface->sub.pending_placement_ops = NULL; } + + if (surface->sub.synchronous) + { + actor_surface_commit (surface, pending_surface_state); + + wl_list_insert_list (&compositor->frame_callbacks, + &pending_surface_state->frame_callback_list); + wl_list_init (&pending_surface_state->frame_callback_list); + } + + double_buffered_state_reset (&surface->sub.pending_surface_state); } static void @@ -1079,6 +1171,8 @@ wl_subsurface_destructor (struct wl_resource *resource) unparent_actor (surface); surface->sub.parent = NULL; } + + double_buffered_state_destroy (&surface->sub.pending_surface_state); destroy_surface_extension (subsurface); } @@ -1191,14 +1285,27 @@ static void wl_subsurface_set_sync (struct wl_client *client, struct wl_resource *resource) { - g_warning ("TODO: support wl_subsurface.set_sync"); + MetaWaylandSurfaceExtension *subsurface = + wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = + wl_container_of (subsurface, surface, subsurface); + + surface->sub.synchronous = TRUE; } static void wl_subsurface_set_desync (struct wl_client *client, struct wl_resource *resource) { - g_warning ("TODO: support wl_subsurface.set_desync"); + MetaWaylandSurfaceExtension *subsurface = + wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = + wl_container_of (subsurface, surface, subsurface); + + if (surface->sub.synchronous) + subsurface_parent_surface_commited (surface); + + surface->sub.synchronous = FALSE; } static const struct wl_subsurface_interface meta_wayland_subsurface_interface = { @@ -1251,6 +1358,7 @@ wl_subcompositor_get_subsurface (struct wl_client *client, return; } + double_buffered_state_init (&surface->sub.pending_surface_state); surface->sub.parent = parent; surface->sub.parent_destroy_listener.notify = surface_handle_parent_surface_destroyed; diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h index c7b617ded..454f5d4ce 100644 --- a/src/wayland/meta-wayland-surface.h +++ b/src/wayland/meta-wayland-surface.h @@ -91,6 +91,9 @@ struct _MetaWaylandSurface MetaWaylandSurface *parent; struct wl_listener parent_destroy_listener; + gboolean synchronous; + MetaWaylandDoubleBufferedState pending_surface_state; + int32_t pending_x; int32_t pending_y; gboolean pending_pos; From 55b18f96719e22a1ed752546c982982844dc941a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Thu, 30 Jan 2014 22:39:54 +0100 Subject: [PATCH 415/889] window: Add "skip-taskbar" property We currently only have a method to query the skip-taskbar hint. Add a corresponding property to allow listening for change notifications. https://bugzilla.gnome.org/show_bug.cgi?id=723307 --- src/core/window.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/core/window.c b/src/core/window.c index b4a845d6a..30b4c2bfb 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -196,6 +196,7 @@ enum { PROP_USER_TIME, PROP_DEMANDS_ATTENTION, PROP_URGENT, + PROP_SKIP_TASKBAR, PROP_MUTTER_HINTS, PROP_APPEARS_FOCUSED, PROP_RESIZEABLE, @@ -332,6 +333,9 @@ meta_window_get_property(GObject *object, case PROP_URGENT: g_value_set_boolean (value, win->wm_hints_urgent); break; + case PROP_SKIP_TASKBAR: + g_value_set_boolean (value, win->skip_taskbar); + break; case PROP_MUTTER_HINTS: g_value_set_string (value, win->mutter_hints); break; @@ -492,6 +496,14 @@ meta_window_class_init (MetaWindowClass *klass) FALSE, G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_SKIP_TASKBAR, + g_param_spec_boolean ("skip-taskbar", + "Skip taskbar", + "Whether the skip-taskbar flag of WM_HINTS is set", + FALSE, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_MUTTER_HINTS, g_param_spec_string ("mutter-hints", @@ -8750,6 +8762,7 @@ recalc_window_features (MetaWindow *window) gboolean old_has_resize_func; gboolean old_has_shade_func; gboolean old_always_sticky; + gboolean old_skip_taskbar; old_has_close_func = window->has_close_func; old_has_minimize_func = window->has_minimize_func; @@ -8757,6 +8770,7 @@ recalc_window_features (MetaWindow *window) old_has_resize_func = window->has_resize_func; old_has_shade_func = window->has_shade_func; old_always_sticky = window->always_sticky; + old_skip_taskbar = window->skip_taskbar; /* Use MWM hints initially */ if (window->client_type == META_WINDOW_CLIENT_TYPE_X11) @@ -8946,6 +8960,9 @@ recalc_window_features (MetaWindow *window) window->skip_taskbar, window->skip_pager); + if (old_skip_taskbar != window->skip_taskbar) + g_object_notify (G_OBJECT (window), "skip-taskbar"); + /* FIXME: * Lame workaround for recalc_window_features * being used overzealously. The fix is to From 45cb15144327bc41c8acf0ffc2432f519a3669cf Mon Sep 17 00:00:00 2001 From: Adel Gadllah Date: Fri, 31 Jan 2014 15:15:16 +0100 Subject: [PATCH 416/889] window-actor: Fix unobscured_region handling when computing paint volume We currently ignore the unobscured region when we have mapped clones in meta_window_actor_process_damage and meta_window_actor_damage_all but use it unconditionally when computing the paint volume. This is wrong. We should ignore it there as well or we will end up with empty clones if the cloned window is completly obscured (like the tray icons in gnome-shell). https://bugzilla.gnome.org/show_bug.cgi?id=721596 --- src/compositor/meta-window-actor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index e7a922025..afc4bdbd9 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -721,7 +721,7 @@ meta_window_actor_get_paint_volume (ClutterActor *actor, gdk_rectangle_union (&bounds, &shadow_bounds, &bounds); } - if (priv->unobscured_region) + if (priv->unobscured_region && !clutter_actor_has_mapped_clones (actor)) { cairo_rectangle_int_t unobscured_bounds; cairo_region_get_extents (priv->unobscured_region, &unobscured_bounds); From 1a62ac9276d4c9a80055e985bd637a4135247eec Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 31 Jan 2014 11:24:02 -0500 Subject: [PATCH 417/889] xwayland: Shuffle some code around --- src/wayland/meta-xwayland.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index 44f6c41b5..33b3b8db7 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -44,11 +44,11 @@ xserver_set_window_id (struct wl_client *client, MetaWindow *window; window = meta_display_lookup_x_window (display, xid); - if (window) - { - surface->window = window; - window->surface = surface; - } + if (!window) + return; + + surface->window = window; + window->surface = surface; } static const struct xserver_interface xserver_implementation = { From 225e20a8987c32b2ca35e5939565c2fe03c74b37 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 31 Jan 2014 11:38:37 -0500 Subject: [PATCH 418/889] wayland: Remove superfluous "wayland_" from arguments --- src/wayland/meta-wayland-surface.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 069d0870e..35d080587 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -91,28 +91,28 @@ surface_process_damage (MetaWaylandSurface *surface, } static void -meta_wayland_surface_destroy (struct wl_client *wayland_client, - struct wl_resource *wayland_resource) +meta_wayland_surface_destroy (struct wl_client *client, + struct wl_resource *resource) { - wl_resource_destroy (wayland_resource); + wl_resource_destroy (resource); } static void -meta_wayland_surface_attach (struct wl_client *wayland_client, - struct wl_resource *wayland_surface_resource, - struct wl_resource *wayland_buffer_resource, +meta_wayland_surface_attach (struct wl_client *client, + struct wl_resource *surface_resource, + struct wl_resource *buffer_resource, gint32 dx, gint32 dy) { MetaWaylandSurface *surface = - wl_resource_get_user_data (wayland_surface_resource); + wl_resource_get_user_data (surface_resource); MetaWaylandBuffer *buffer; /* X11 unmanaged window */ if (!surface) return; - if (wayland_buffer_resource) - buffer = meta_wayland_buffer_from_resource (wayland_buffer_resource); + if (buffer_resource) + buffer = meta_wayland_buffer_from_resource (buffer_resource); else buffer = NULL; @@ -588,7 +588,7 @@ meta_wayland_surface_resource_destroy_cb (struct wl_resource *resource) MetaWaylandSurface * meta_wayland_surface_create (MetaWaylandCompositor *compositor, - struct wl_client *wayland_client, + struct wl_client *client, guint32 id, guint32 version) { @@ -596,9 +596,7 @@ meta_wayland_surface_create (MetaWaylandCompositor *compositor, surface->compositor = compositor; - surface->resource = wl_resource_create (wayland_client, - &wl_surface_interface, - version, id); + surface->resource = wl_resource_create (client, &wl_surface_interface, version, id); wl_resource_set_implementation (surface->resource, &meta_wayland_surface_interface, surface, meta_wayland_surface_resource_destroy_cb); From 7d3012fd67d42068a4332c3aedb58fd6c472cb30 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 31 Jan 2014 14:09:26 -0500 Subject: [PATCH 419/889] screen: Make the guard window an InputOnly window Using a full InputOutput window causes us to make a full Wayland surface for it, and go through the X server. As the goal of the guard window is a window for us to stack minimized windows under so we can prevent them from getting input, it makes sense to use an InputOnly window here. --- src/core/screen.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/core/screen.c b/src/core/screen.c index cc3c13419..aa3628f0c 100644 --- a/src/core/screen.c +++ b/src/core/screen.c @@ -452,10 +452,9 @@ meta_screen_create_guard_window (Display *xdisplay, MetaScreen *screen) Window guard_window; gulong create_serial; MetaStackWindow stack_window; - + attributes.event_mask = NoEventMask; attributes.override_redirect = True; - attributes.background_pixel = BlackPixel (xdisplay, screen->number); /* We have to call record_add() after we have the new window ID, * so save the serial for the CreateWindow request until then */ @@ -468,10 +467,10 @@ meta_screen_create_guard_window (Display *xdisplay, MetaScreen *screen) screen->rect.width, screen->rect.height, 0, /* border width */ - CopyFromParent, /* depth */ - CopyFromParent, /* class */ + 0, /* depth */ + InputOnly, /* class */ CopyFromParent, /* visual */ - CWEventMask|CWOverrideRedirect|CWBackPixel, + CWEventMask|CWOverrideRedirect, &attributes); { From 9edff6f250eeb3f34256791459eafd497b8131e9 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 31 Jan 2014 15:49:27 -0500 Subject: [PATCH 420/889] wayland: Use wl_callback_send_done For no specific reason... --- src/wayland/meta-wayland.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index 1db2fceb4..2db93f8e9 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -505,8 +505,7 @@ meta_wayland_compositor_paint_finished (MetaWaylandCompositor *compositor) MetaWaylandFrameCallback *callback = wl_container_of (compositor->frame_callbacks.next, callback, link); - wl_resource_post_event (callback->resource, - WL_CALLBACK_DONE, get_time ()); + wl_callback_send_done (callback->resource, get_time ()); wl_resource_destroy (callback->resource); } } From a09fa3b0e463cab55c43a3888397386224f06948 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 31 Jan 2014 16:40:40 -0500 Subject: [PATCH 421/889] wayland: Clean up the parallels between creating callbacks and surface extensions --- src/wayland/meta-wayland-surface.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 35d080587..a24c7f3b6 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -172,11 +172,8 @@ meta_wayland_surface_frame (struct wl_client *client, callback = g_slice_new0 (MetaWaylandFrameCallback); callback->compositor = surface->compositor; - callback->resource = wl_resource_create (client, - &wl_callback_interface, 1, - callback_id); - wl_resource_set_user_data (callback->resource, callback); - wl_resource_set_destructor (callback->resource, destroy_frame_callback); + callback->resource = wl_resource_create (client, &wl_callback_interface, META_WL_CALLBACK_VERSION, callback_id); + wl_resource_set_implementation (callback->resource, NULL, callback, destroy_frame_callback); wl_list_insert (surface->pending.frame_callback_list.prev, &callback->link); } @@ -610,7 +607,6 @@ static void destroy_surface_extension (MetaWaylandSurfaceExtension *extension) { wl_list_remove (&extension->surface_destroy_listener.link); - extension->surface_destroy_listener.notify = NULL; extension->resource = NULL; } @@ -640,17 +636,15 @@ create_surface_extension (MetaWaylandSurfaceExtension *extension, const void *implementation, wl_resource_destroy_func_t destructor) { - struct wl_resource *resource; - if (extension->resource != NULL) return FALSE; - resource = wl_resource_create (client, interface, get_resource_version (master_resource, max_version), id); - wl_resource_set_implementation (resource, implementation, extension, destructor); + extension->resource = wl_resource_create (client, interface, get_resource_version (master_resource, max_version), id); + wl_resource_set_implementation (extension->resource, implementation, extension, destructor); - extension->resource = resource; extension->surface_destroy_listener.notify = extension_handle_surface_destroy; wl_resource_add_destroy_listener (surface_resource, &extension->surface_destroy_listener); + return TRUE; } From 60d9bee3bfafea5ae6e43c1823378e30c86630f3 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 6 Dec 2013 17:42:43 -0500 Subject: [PATCH 422/889] window-actor: Simplify the unredirected check in cull_out https://bugzilla.gnome.org/show_bug.cgi?id=720631 --- src/compositor/meta-window-actor.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index afc4bdbd9..10275c37d 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -1808,15 +1808,11 @@ meta_window_actor_cull_out (MetaCullable *cullable, cairo_region_t *clip_region) { MetaWindowActor *self = META_WINDOW_ACTOR (cullable); + MetaWindowActorPrivate *priv = self->priv; - if (!meta_is_wayland_compositor ()) - { - MetaCompScreen *info = meta_screen_get_compositor_data (self->priv->screen); - - /* Don't do any culling for the unredirected window */ - if (self == info->unredirected_window) - return; - } + /* Don't do any culling for the unredirected window */ + if (priv->unredirected) + return; meta_window_actor_set_unobscured_region (self, unobscured_region); meta_cullable_cull_out_children (cullable, unobscured_region, clip_region); From d6282716b2a64051fbb2b60705569b5f275471e3 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 6 Dec 2013 17:10:44 -0500 Subject: [PATCH 423/889] compositor: Simplify the unredirected window management code https://bugzilla.gnome.org/show_bug.cgi?id=720631 --- src/compositor/compositor-private.h | 4 +- src/compositor/compositor.c | 73 ++++++++++++++--------------- src/compositor/meta-window-group.c | 3 +- 3 files changed, 37 insertions(+), 43 deletions(-) diff --git a/src/compositor/compositor-private.h b/src/compositor/compositor-private.h index 2e8d85fd9..a5efd6ee8 100644 --- a/src/compositor/compositor-private.h +++ b/src/compositor/compositor-private.h @@ -46,8 +46,8 @@ struct _MetaCompScreen CoglFrameClosure *frame_closure; /* Used for unredirecting fullscreen windows */ - guint disable_unredirect_count; - MetaWindowActor *unredirected_window; + guint disable_unredirect_count; + MetaWindow *unredirected_window; /* Before we create the output window */ XserverRegion pending_input_region; diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index d2598f48b..73378903d 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -863,6 +863,30 @@ meta_shape_cow_for_window (MetaScreen *screen, } } +static void +set_unredirected_window (MetaCompScreen *info, + MetaWindow *window) +{ + if (info->unredirected_window == window) + return; + + if (info->unredirected_window != NULL) + { + MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (info->unredirected_window)); + meta_window_actor_set_redirected (window_actor, TRUE); + } + + info->unredirected_window = window; + + if (info->unredirected_window != NULL) + { + MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (info->unredirected_window)); + meta_window_actor_set_redirected (window_actor, FALSE); + } + + meta_shape_cow_for_window (info->screen, info->unredirected_window); +} + void meta_compositor_add_window (MetaCompositor *compositor, MetaWindow *window) @@ -891,19 +915,11 @@ meta_compositor_remove_window (MetaCompositor *compositor, if (!window_actor) return; - if (!meta_is_wayland_compositor ()) - { - screen = meta_window_get_screen (window); - info = meta_screen_get_compositor_data (screen); + screen = meta_window_get_screen (window); + info = meta_screen_get_compositor_data (screen); - if (window_actor == info->unredirected_window) - { - meta_window_actor_set_redirected (window_actor, TRUE); - meta_shape_cow_for_window (meta_window_get_screen (meta_window_actor_get_meta_window (info->unredirected_window)), - NULL); - info->unredirected_window = NULL; - } - } + if (info->unredirected_window == window) + set_unredirected_window (info, NULL); meta_window_actor_destroy (window_actor); } @@ -1533,7 +1549,6 @@ pre_paint_windows (MetaCompScreen *info) { GList *l; MetaWindowActor *top_window; - MetaWindowActor *expected_unredirected_window = NULL; if (info->onscreen == NULL) { @@ -1547,33 +1562,13 @@ pre_paint_windows (MetaCompScreen *info) if (info->windows == NULL) return; - if (!meta_is_wayland_compositor ()) - { - top_window = g_list_last (info->windows)->data; + top_window = g_list_last (info->windows)->data; - if (meta_window_actor_should_unredirect (top_window) && - info->disable_unredirect_count == 0) - expected_unredirected_window = top_window; - - if (info->unredirected_window != expected_unredirected_window) - { - if (info->unredirected_window != NULL) - { - meta_window_actor_set_redirected (info->unredirected_window, TRUE); - meta_shape_cow_for_window (meta_window_get_screen (meta_window_actor_get_meta_window (info->unredirected_window)), - NULL); - } - - if (expected_unredirected_window != NULL) - { - meta_shape_cow_for_window (meta_window_get_screen (meta_window_actor_get_meta_window (top_window)), - meta_window_actor_get_meta_window (top_window)); - meta_window_actor_set_redirected (top_window, FALSE); - } - - info->unredirected_window = expected_unredirected_window; - } - } + if (meta_window_actor_should_unredirect (top_window) && + info->disable_unredirect_count == 0) + set_unredirected_window (info, meta_window_actor_get_meta_window (top_window)); + else + set_unredirected_window (info, NULL); for (l = info->windows; l; l = l->next) meta_window_actor_pre_paint (l->data); diff --git a/src/compositor/meta-window-group.c b/src/compositor/meta-window-group.c index 9554571b0..a36d5961b 100644 --- a/src/compositor/meta-window-group.c +++ b/src/compositor/meta-window-group.c @@ -184,9 +184,8 @@ meta_window_group_paint (ClutterActor *actor) if (info->unredirected_window != NULL) { cairo_rectangle_int_t unredirected_rect; - MetaWindow *window = meta_window_actor_get_meta_window (info->unredirected_window); - meta_window_get_frame_rect (window, (MetaRectangle *)&unredirected_rect); + meta_window_get_frame_rect (info->unredirected_window, (MetaRectangle *)&unredirected_rect); cairo_region_subtract_rectangle (unobscured_region, &unredirected_rect); cairo_region_subtract_rectangle (clip_region, &unredirected_rect); } From 39fee9f5a2b8b3ba9ef3051d8a91ff556a57fa91 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 6 Dec 2013 17:36:09 -0500 Subject: [PATCH 424/889] window-actor: Flip set_redirected around I know it's confusing with the triple negative, but unredirected is how we track it elsewhere: we have an 'unredirected' flag, and 'should_unredirect'. https://bugzilla.gnome.org/show_bug.cgi?id=720631 --- src/compositor/compositor.c | 4 ++-- src/compositor/meta-window-actor-private.h | 8 ++++---- src/compositor/meta-window-actor.c | 22 +++++++++++----------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 73378903d..3936e1452 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -873,7 +873,7 @@ set_unredirected_window (MetaCompScreen *info, if (info->unredirected_window != NULL) { MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (info->unredirected_window)); - meta_window_actor_set_redirected (window_actor, TRUE); + meta_window_actor_set_unredirected (window_actor, FALSE); } info->unredirected_window = window; @@ -881,7 +881,7 @@ set_unredirected_window (MetaCompScreen *info, if (info->unredirected_window != NULL) { MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (info->unredirected_window)); - meta_window_actor_set_redirected (window_actor, FALSE); + meta_window_actor_set_unredirected (window_actor, TRUE); } meta_shape_cow_for_window (info->screen, info->unredirected_window); diff --git a/src/compositor/meta-window-actor-private.h b/src/compositor/meta-window-actor-private.h index 82326d29b..0207a88f4 100644 --- a/src/compositor/meta-window-actor-private.h +++ b/src/compositor/meta-window-actor-private.h @@ -39,13 +39,13 @@ void meta_window_actor_frame_complete (MetaWindowActor *self, void meta_window_actor_invalidate_shadow (MetaWindowActor *self); -void meta_window_actor_set_redirected (MetaWindowActor *self, gboolean state); - -gboolean meta_window_actor_should_unredirect (MetaWindowActor *self); - void meta_window_actor_get_shape_bounds (MetaWindowActor *self, cairo_rectangle_int_t *bounds); +gboolean meta_window_actor_should_unredirect (MetaWindowActor *self); +void meta_window_actor_set_unredirected (MetaWindowActor *self, + gboolean unredirected); + gboolean meta_window_actor_effect_in_progress (MetaWindowActor *self); void meta_window_actor_sync_actor_geometry (MetaWindowActor *self, gboolean did_placement); diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 10275c37d..9989f863a 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -1352,7 +1352,8 @@ meta_window_actor_should_unredirect (MetaWindowActor *self) } void -meta_window_actor_set_redirected (MetaWindowActor *self, gboolean state) +meta_window_actor_set_unredirected (MetaWindowActor *self, + gboolean unredirected) { MetaWindow *metaWindow = meta_window_actor_get_meta_window (self); MetaDisplay *display = meta_window_get_display (metaWindow); @@ -1360,21 +1361,20 @@ meta_window_actor_set_redirected (MetaWindowActor *self, gboolean state) Display *xdisplay = meta_display_get_xdisplay (display); Window xwin = meta_window_get_toplevel_xwindow (metaWindow); - if (state) + meta_error_trap_push (display); + + if (unredirected) { - meta_error_trap_push (display); - XCompositeRedirectWindow (xdisplay, xwin, CompositeRedirectManual); - meta_error_trap_pop (display); - meta_window_actor_detach_x11_pixmap (self); - self->priv->unredirected = FALSE; + XCompositeUnredirectWindow (xdisplay, xwin, CompositeRedirectManual); } else { - meta_error_trap_push (display); - XCompositeUnredirectWindow (xdisplay, xwin, CompositeRedirectManual); - meta_error_trap_pop (display); - self->priv->unredirected = TRUE; + XCompositeRedirectWindow (xdisplay, xwin, CompositeRedirectManual); + meta_window_actor_detach_x11_pixmap (self); } + + self->priv->unredirected = unredirected; + meta_error_trap_pop (display); } void From b9755ea725076d7f07eb950e26c6edc4af4c8f5a Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 4 Nov 2013 21:17:48 -0500 Subject: [PATCH 425/889] window-actor: Remove old unused APIs https://bugzilla.gnome.org/show_bug.cgi?id=720631 --- src/compositor/meta-window-actor.c | 53 ------------------------------ src/compositor/plugins/default.c | 2 +- src/meta/meta-window-actor.h | 3 -- 3 files changed, 1 insertion(+), 57 deletions(-) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 9989f863a..f961bf88b 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -860,59 +860,6 @@ meta_window_actor_is_destroyed (MetaWindowActor *self) return self->priv->disposed; } -gboolean -meta_window_actor_is_override_redirect (MetaWindowActor *self) -{ - return meta_window_is_override_redirect (self->priv->window); -} - -/** - * meta_window_actor_get_workspace: - * @self: #MetaWindowActor - * - * Returns the index of workspace on which this window is located; if the - * window is sticky, or is not currently located on any workspace, returns -1. - * This function is deprecated and should not be used in newly written code; - * meta_window_get_workspace() instead. - * - * Return value: (transfer none): index of workspace on which this window is - * located. - */ -gint -meta_window_actor_get_workspace (MetaWindowActor *self) -{ - MetaWindowActorPrivate *priv; - MetaWorkspace *workspace; - - if (!self) - return -1; - - priv = self->priv; - - if (!priv->window || meta_window_is_on_all_workspaces (priv->window)) - return -1; - - workspace = meta_window_get_workspace (priv->window); - - if (!workspace) - return -1; - - return meta_workspace_index (workspace); -} - -gboolean -meta_window_actor_showing_on_its_workspace (MetaWindowActor *self) -{ - if (!self) - return FALSE; - - /* If override redirect: */ - if (!self->priv->window) - return TRUE; - - return meta_window_showing_on_its_workspace (self->priv->window); -} - static void meta_window_actor_freeze (MetaWindowActor *self) { diff --git a/src/compositor/plugins/default.c b/src/compositor/plugins/default.c index 91b30c039..892854b33 100644 --- a/src/compositor/plugins/default.c +++ b/src/compositor/plugins/default.c @@ -409,7 +409,7 @@ switch_workspace (MetaPlugin *plugin, ClutterActor *actor = CLUTTER_ACTOR (window_actor); gint win_workspace; - win_workspace = meta_window_actor_get_workspace (window_actor); + win_workspace = meta_window_get_workspace (meta_window_actor_get_meta_window (window_actor)); if (win_workspace == to || win_workspace == from) { diff --git a/src/meta/meta-window-actor.h b/src/meta/meta-window-actor.h index 9f808a9ac..2055ca8fc 100644 --- a/src/meta/meta-window-actor.h +++ b/src/meta/meta-window-actor.h @@ -58,11 +58,8 @@ struct _MetaWindowActor GType meta_window_actor_get_type (void); Window meta_window_actor_get_x_window (MetaWindowActor *self); -gint meta_window_actor_get_workspace (MetaWindowActor *self); MetaWindow * meta_window_actor_get_meta_window (MetaWindowActor *self); ClutterActor * meta_window_actor_get_texture (MetaWindowActor *self); -gboolean meta_window_actor_is_override_redirect (MetaWindowActor *self); -gboolean meta_window_actor_showing_on_its_workspace (MetaWindowActor *self); gboolean meta_window_actor_is_destroyed (MetaWindowActor *self); #endif /* META_WINDOW_ACTOR_H */ From d5d5c2167a995727fa0ab1c6105bf960c6b8069f Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 16 Jan 2014 15:27:58 -0500 Subject: [PATCH 426/889] compositor: Remove pending_input_region Ever since the change to create the output window synchronously at startup, there hasn't been any time where somebody could set a stage region the output window was ready, so this was effectively dead code. https://bugzilla.gnome.org/show_bug.cgi?id=720631 --- src/compositor/compositor-private.h | 3 -- src/compositor/compositor.c | 77 ++++++----------------------- 2 files changed, 14 insertions(+), 66 deletions(-) diff --git a/src/compositor/compositor-private.h b/src/compositor/compositor-private.h index a5efd6ee8..18bcff6f9 100644 --- a/src/compositor/compositor-private.h +++ b/src/compositor/compositor-private.h @@ -49,9 +49,6 @@ struct _MetaCompScreen guint disable_unredirect_count; MetaWindow *unredirected_window; - /* Before we create the output window */ - XserverRegion pending_input_region; - gint switch_workspace_in_progress; MetaPluginManager *plugin_mgr; diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 3936e1452..9420ad537 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -283,25 +283,6 @@ meta_get_window_actors (MetaScreen *screen) return info->windows; } -static void -do_set_stage_input_region (MetaScreen *screen, - XserverRegion region) -{ - MetaCompScreen *info = meta_screen_get_compositor_data (screen); - MetaDisplay *display = meta_screen_get_display (screen); - Display *xdpy = meta_display_get_xdisplay (display); - Window xstage = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage)); - - XFixesSetWindowShapeRegion (xdpy, xstage, ShapeInput, 0, 0, region); - - /* It's generally a good heuristic that when a crossing event is generated because - * we reshape the overlay, we don't want it to affect focus-follows-mouse focus - - * it's not the user doing something, it's the environment changing under the user. - */ - meta_display_add_ignored_crossing_serial (display, XNextRequest (xdpy)); - XFixesSetWindowShapeRegion (xdpy, info->output, ShapeInput, 0, 0, region); -} - void meta_set_stage_input_region (MetaScreen *screen, XserverRegion region) @@ -313,29 +294,19 @@ meta_set_stage_input_region (MetaScreen *screen, */ if (!meta_is_wayland_compositor ()) { - MetaCompScreen *info = meta_screen_get_compositor_data (screen); - MetaDisplay *display = meta_screen_get_display (screen); - Display *xdpy = meta_display_get_xdisplay (display); + MetaCompScreen *info = meta_screen_get_compositor_data (screen); + MetaDisplay *display = meta_screen_get_display (screen); + Display *xdpy = meta_display_get_xdisplay (display); + Window xstage = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage)); - if (info->stage && info->output) - { - do_set_stage_input_region (screen, region); - } - else - { - /* Reset info->pending_input_region if one existed before and set the new - * one to use it later. */ - if (info->pending_input_region) - { - XFixesDestroyRegion (xdpy, info->pending_input_region); - info->pending_input_region = None; - } - if (region != None) - { - info->pending_input_region = XFixesCreateRegion (xdpy, NULL, 0); - XFixesCopyRegion (xdpy, info->pending_input_region, region); - } - } + XFixesSetWindowShapeRegion (xdpy, xstage, ShapeInput, 0, 0, region); + + /* It's generally a good heuristic that when a crossing event is generated because + * we reshape the overlay, we don't want it to affect focus-follows-mouse focus - + * it's not the user doing something, it's the environment changing under the user. + */ + meta_display_add_ignored_crossing_serial (display, XNextRequest (xdpy)); + XFixesSetWindowShapeRegion (xdpy, info->output, ShapeInput, 0, 0, region); } } @@ -677,21 +648,6 @@ meta_compositor_manage_screen (MetaCompositor *compositor, return; info = g_new0 (MetaCompScreen, 1); - /* - * We use an empty input region for Clutter as a default because that allows - * the user to interact with all the windows displayed on the screen. - * We have to initialize info->pending_input_region to an empty region explicitly, - * because None value is used to mean that the whole screen is an input region. - */ - if (!meta_is_wayland_compositor ()) - info->pending_input_region = XFixesCreateRegion (xdisplay, NULL, 0); - else - { - /* Stage input region trickery isn't needed when we're running as a - * wayland compositor. */ - info->pending_input_region = None; - } - info->screen = screen; meta_screen_set_compositor_data (screen, info); @@ -777,6 +733,8 @@ meta_compositor_manage_screen (MetaCompositor *compositor, info->output = get_output_window (screen); XReparentWindow (xdisplay, xwin, info->output, 0, 0); + meta_empty_stage_input_region (screen); + /* Make sure there isn't any left-over output shape on the * overlay window by setting the whole screen to be an * output region. @@ -787,13 +745,6 @@ meta_compositor_manage_screen (MetaCompositor *compositor, */ XFixesSetWindowShapeRegion (xdisplay, info->output, ShapeBounding, 0, 0, None); - do_set_stage_input_region (screen, info->pending_input_region); - if (info->pending_input_region != None) - { - XFixesDestroyRegion (xdisplay, info->pending_input_region); - info->pending_input_region = None; - } - /* Map overlay window before redirecting windows offscreen so we catch their * contents until we show the stage. */ From 10fead9ba14e9212aba187ff2fa4bd41e1fff9bd Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 31 Jan 2014 18:18:59 -0500 Subject: [PATCH 427/889] wayland-pointer: Fix infinite loop when leaving focus from a destroyed surface To prevent corruption, our focus listener needs to be removed even when the surface is destroyed. So, bailing out when pointer->focus->resource is NULL just isn't good enough. --- src/wayland/meta-wayland-pointer.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index 193cd4d51..ca65ececa 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -322,12 +322,16 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer, return; resource = pointer->focus_resource; - if (resource && pointer->focus->resource) + if (resource) { - struct wl_client *client = wl_resource_get_client (resource); - struct wl_display *display = wl_client_get_display (client); - serial = wl_display_next_serial (display); - wl_pointer_send_leave (resource, serial, pointer->focus->resource); + if (pointer->focus->resource) + { + struct wl_client *client = wl_resource_get_client (resource); + struct wl_display *display = wl_client_get_display (client); + serial = wl_display_next_serial (display); + wl_pointer_send_leave (resource, serial, pointer->focus->resource); + } + wl_list_remove (&pointer->focus_listener.link); } From 7a8de0c0af97135c99fe1ee94a2a9782a843f0ed Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 31 Jan 2014 18:51:28 -0500 Subject: [PATCH 428/889] wayland: Reindent --- src/wayland/meta-wayland.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index 2db93f8e9..b2bec8550 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -686,7 +686,7 @@ meta_wayland_init (void) clutter_wayland_set_compositor_display (compositor->wayland_display); if (getenv ("WESTON_LAUNCHER_SOCK")) - compositor->launcher = meta_launcher_new (); + compositor->launcher = meta_launcher_new (); if (clutter_init (NULL, NULL) != CLUTTER_INIT_SUCCESS) g_error ("Failed to initialize Clutter"); From 9567fa9c6aebb7c936b7a350503c800a652a2453 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 31 Jan 2014 18:51:45 -0500 Subject: [PATCH 429/889] wayland: Check for launcher before freeing it This prevents a segfault on shutdown. --- src/wayland/meta-wayland.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index b2bec8550..39eedc754 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -760,7 +760,9 @@ meta_wayland_finalize (void) compositor = meta_wayland_compositor_get_default (); meta_xwayland_stop (compositor); - meta_launcher_free (compositor->launcher); + + if (compositor->launcher) + meta_launcher_free (compositor->launcher); } MetaLauncher * From c8d185fc7418d641a02b5b1d5b05049e52a78a1d Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sat, 1 Feb 2014 11:54:38 -0500 Subject: [PATCH 430/889] display: Revise Wayland event handling X11 window frames use special UI grab ops, like META_GRAB_OP_CLICKING_MAXIMIZE, in order to work properly. As the frames in this case are X11 clients, we need to pass through X events in this case. So, similar to how handle_xevent works, use two variables, bypass_clutter, and bypass_wayland, and set them when we handle specific events. --- src/core/display.c | 52 ++++++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/src/core/display.c b/src/core/display.c index 8a98cf5ab..7376f0eb3 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -1984,6 +1984,7 @@ meta_display_handle_event (MetaDisplay *display, const ClutterEvent *event) { MetaWindow *window; + gboolean bypass_clutter = FALSE, bypass_wayland = FALSE; /* XXX -- we need to fill this in properly at some point... */ gboolean frame_was_receiver = FALSE; @@ -2055,8 +2056,9 @@ meta_display_handle_event (MetaDisplay *display, meta_stack_set_positions (window->screen->stack, display->grab_old_window_stacking); } - meta_display_end_grab_op (display, - event->any.time); + meta_display_end_grab_op (display, event->any.time); + bypass_clutter = TRUE; + bypass_wayland = TRUE; } else if (window && display->grab_op == META_GRAB_OP_NONE) { @@ -2171,20 +2173,8 @@ meta_display_handle_event (MetaDisplay *display, event->button.y, event->button.button, event->any.time); - } - - if (!frame_was_receiver && unmodified) - { - /* This is from our synchronous grab since - * it has no modifiers and was on the client window - */ - - meta_verbose ("Allowing events time %u\n", - (unsigned int) event->any.time); - - /* XXX -- implement this in Wayland */ - XIAllowEvents (display->xdisplay, META_VIRTUAL_CORE_POINTER_ID, - XIReplayDevice, event->any.time); + bypass_clutter = TRUE; + bypass_wayland = TRUE; } if (begin_move && window->has_move_func) @@ -2200,6 +2190,8 @@ meta_display_handle_event (MetaDisplay *display, event->any.time, event->button.x, event->button.y); + bypass_clutter = TRUE; + bypass_wayland = TRUE; } } break; @@ -2211,7 +2203,11 @@ meta_display_handle_event (MetaDisplay *display, if (display->grab_window == window && meta_grab_op_is_mouse (display->grab_op)) - meta_window_handle_mouse_grab_op_event (window, event); + { + meta_window_handle_mouse_grab_op_event (window, event); + bypass_clutter = TRUE; + bypass_wayland = TRUE; + } break; case CLUTTER_MOTION: if (display->grab_op == META_GRAB_OP_COMPOSITOR) @@ -2219,7 +2215,11 @@ meta_display_handle_event (MetaDisplay *display, if (display->grab_window == window && meta_grab_op_is_mouse (display->grab_op)) - meta_window_handle_mouse_grab_op_event (window, event); + { + meta_window_handle_mouse_grab_op_event (window, event); + bypass_clutter = TRUE; + bypass_wayland = TRUE; + } break; case CLUTTER_KEY_PRESS: @@ -2231,22 +2231,28 @@ meta_display_handle_event (MetaDisplay *display, * want to pass the key event to the compositor or Wayland at all. */ if (meta_display_process_key_event (display, window, (ClutterKeyEvent *) event)) - return TRUE; + { + bypass_clutter = TRUE; + bypass_wayland = TRUE; + } default: break; } + /* If the compositor has a grab, don't pass that through to Wayland */ + if (display->grab_op == META_GRAB_OP_COMPOSITOR) + bypass_wayland = TRUE; + #ifdef HAVE_WAYLAND - if (compositor && (display->grab_op == META_GRAB_OP_NONE)) + if (compositor && !bypass_wayland) { if (meta_wayland_compositor_handle_event (compositor, event)) - return TRUE; + bypass_clutter = TRUE; } #endif /* HAVE_WAYLAND */ - return (display->grab_op != META_GRAB_OP_NONE && - display->grab_op != META_GRAB_OP_COMPOSITOR); + return bypass_clutter; } static gboolean From 365442c1ff67cfb7e35894dab755b6e9347ab2f0 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sat, 1 Feb 2014 16:19:47 -0500 Subject: [PATCH 431/889] wayland-surface: Fix typo --- src/wayland/meta-wayland-surface.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index a24c7f3b6..c8b1a5032 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -434,12 +434,12 @@ subsurface_surface_commit (MetaWaylandSurface *surface) } static void -subsurface_parent_surface_commited (MetaWaylandSurface *surface); +subsurface_parent_surface_committed (MetaWaylandSurface *surface); static void parent_surface_committed (gpointer data, gpointer user_data) { - subsurface_parent_surface_commited (data); + subsurface_parent_surface_committed (data); } static void @@ -1085,7 +1085,7 @@ bind_gtk_shell (struct wl_client *client, } static void -subsurface_parent_surface_commited (MetaWaylandSurface *surface) +subsurface_parent_surface_committed (MetaWaylandSurface *surface) { MetaWaylandCompositor *compositor = surface->compositor; MetaWaylandDoubleBufferedState *pending_surface_state = @@ -1295,7 +1295,7 @@ wl_subsurface_set_desync (struct wl_client *client, wl_container_of (subsurface, surface, subsurface); if (surface->sub.synchronous) - subsurface_parent_surface_commited (surface); + subsurface_parent_surface_committed (surface); surface->sub.synchronous = FALSE; } From 1f7a6bf84582b860a21782275faaafa68fcf9b20 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sat, 1 Feb 2014 16:29:09 -0500 Subject: [PATCH 432/889] wayland-surface: Don't clean up the buffer_destroy_listener twice double_buffered_state_destroy will do this for us. --- src/wayland/meta-wayland-surface.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index c8b1a5032..d33b9f31b 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -517,10 +517,6 @@ meta_wayland_surface_free (MetaWaylandSurface *surface) compositor->surfaces = g_list_remove (compositor->surfaces, surface); meta_wayland_buffer_reference (&surface->buffer_ref, NULL); - - if (surface->pending.buffer) - wl_list_remove (&surface->pending.buffer_destroy_listener.link); - double_buffered_state_destroy (&surface->pending); meta_wayland_compositor_repick (compositor); From 3e35cac67a8a65e3ded85c936b942b900c1d2780 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sat, 1 Feb 2014 16:29:36 -0500 Subject: [PATCH 433/889] wayland-surface: Repick after cleaning up everything else Just a code cleanup to keep all the freeing code together. --- src/wayland/meta-wayland-surface.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index d33b9f31b..5d8fd45a7 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -518,14 +518,12 @@ meta_wayland_surface_free (MetaWaylandSurface *surface) meta_wayland_buffer_reference (&surface->buffer_ref, NULL); double_buffered_state_destroy (&surface->pending); - - meta_wayland_compositor_repick (compositor); - g_object_unref (surface->surface_actor); - if (surface->resource) wl_resource_set_user_data (surface->resource, NULL); g_slice_free (MetaWaylandSurface, surface); + + meta_wayland_compositor_repick (compositor); } static void From d74796ee80ec76befd8ef2ccbccdce955ec848cf Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sat, 1 Feb 2014 16:24:43 -0500 Subject: [PATCH 434/889] wayland-surface: Use the same commit() when commiting subsurface Refactor our commit() implementation out of wl_surface_commit(), and pass the double-buffered state around to all our implementation methods. This allows us to drop a few lines destroying and reinitializing list of frame callbacks. This is a big cleanup for the next commit, though. --- src/wayland/meta-wayland-surface.c | 96 +++++++++++++++--------------- 1 file changed, 47 insertions(+), 49 deletions(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 5d8fd45a7..7817a3101 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -249,11 +249,12 @@ ensure_buffer_texture (MetaWaylandBuffer *buffer) } static void -cursor_surface_commit (MetaWaylandSurface *surface) +cursor_surface_commit (MetaWaylandSurface *surface, + MetaWaylandDoubleBufferedState *pending) { - MetaWaylandBuffer *buffer = surface->pending.buffer; + MetaWaylandBuffer *buffer = pending->buffer; - if (surface->pending.newly_attached && buffer != surface->buffer_ref.buffer) + if (pending->newly_attached && buffer != surface->buffer_ref.buffer) { ensure_buffer_texture (buffer); meta_wayland_buffer_reference (&surface->buffer_ref, buffer); @@ -263,7 +264,7 @@ cursor_surface_commit (MetaWaylandSurface *surface) } static gboolean -actor_surface_commit (MetaWaylandSurface *surface, +actor_surface_commit (MetaWaylandSurface *surface, MetaWaylandDoubleBufferedState *pending) { MetaSurfaceActor *surface_actor = surface->surface_actor; @@ -290,12 +291,13 @@ actor_surface_commit (MetaWaylandSurface *surface, } static void -toplevel_surface_commit (MetaWaylandSurface *surface) +toplevel_surface_commit (MetaWaylandSurface *surface, + MetaWaylandDoubleBufferedState *pending) { - if (actor_surface_commit (surface, &surface->pending)) + if (actor_surface_commit (surface, pending)) { MetaWindow *window = surface->window; - MetaWaylandBuffer *buffer = surface->pending.buffer; + MetaWaylandBuffer *buffer = pending->buffer; meta_window_set_surface_mapped (window, buffer != NULL); /* We resize X based surfaces according to X events */ @@ -308,10 +310,9 @@ toplevel_surface_commit (MetaWaylandSurface *surface) new_height = surface->buffer_ref.buffer->height; if (new_width != window->rect.width || new_height != window->rect.height || - surface->pending.dx != 0 || - surface->pending.dy != 0) - meta_window_move_resize_wayland (window, new_width, new_height, - surface->pending.dx, surface->pending.dy); + pending->dx != 0 || + pending->dy != 0) + meta_window_move_resize_wayland (window, new_width, new_height, pending->dx, pending->dy); } } } @@ -396,7 +397,8 @@ move_double_buffered_state (MetaWaylandDoubleBufferedState *from, } static void -subsurface_surface_commit (MetaWaylandSurface *surface) +subsurface_surface_commit (MetaWaylandSurface *surface, + MetaWaylandDoubleBufferedState *pending) { /* * If the sub-surface is in synchronous mode, post-pone the commit of its @@ -412,13 +414,12 @@ subsurface_surface_commit (MetaWaylandSurface *surface) */ if (surface->sub.synchronous) { - move_double_buffered_state (&surface->pending, - &surface->sub.pending_surface_state); + move_double_buffered_state (pending, &surface->sub.pending_surface_state); } - else if (actor_surface_commit (surface, &surface->pending)) + else if (actor_surface_commit (surface, pending)) { MetaSurfaceActor *surface_actor = surface->surface_actor; - MetaWaylandBuffer *buffer = surface->pending.buffer; + MetaWaylandBuffer *buffer = pending->buffer; float x, y; if (buffer != NULL) @@ -427,8 +428,8 @@ subsurface_surface_commit (MetaWaylandSurface *surface) clutter_actor_hide (CLUTTER_ACTOR (surface_actor)); clutter_actor_get_position (CLUTTER_ACTOR (surface_actor), &x, &y); - x += surface->pending.dx; - y += surface->pending.dy; + x += pending->dx; + y += pending->dy; clutter_actor_set_position (CLUTTER_ACTOR (surface_actor), x, y); } } @@ -443,41 +444,46 @@ parent_surface_committed (gpointer data, gpointer user_data) } static void -meta_wayland_surface_commit (struct wl_client *client, - struct wl_resource *resource) +commit_double_buffered_state (MetaWaylandSurface *surface, + MetaWaylandDoubleBufferedState *pending) { - MetaWaylandSurface *surface = wl_resource_get_user_data (resource); - MetaWaylandCompositor *compositor; - - /* X11 unmanaged window */ - if (!surface) - return; - - compositor = surface->compositor; + MetaWaylandCompositor *compositor = surface->compositor; if (surface == compositor->seat->sprite) - cursor_surface_commit (surface); + cursor_surface_commit (surface, pending); else if (surface->window) - toplevel_surface_commit (surface); + toplevel_surface_commit (surface, pending); else if (surface->subsurface.resource) - subsurface_surface_commit (surface); + subsurface_surface_commit (surface, pending); g_list_foreach (surface->subsurfaces, parent_surface_committed, NULL); - if (surface->pending.buffer) + if (pending->buffer) { - wl_list_remove (&surface->pending.buffer_destroy_listener.link); - surface->pending.buffer = NULL; + wl_list_remove (&pending->buffer_destroy_listener.link); + pending->buffer = NULL; } /* wl_surface.frame */ - wl_list_insert_list (&compositor->frame_callbacks, - &surface->pending.frame_callback_list); - wl_list_init (&surface->pending.frame_callback_list); + wl_list_insert_list (&compositor->frame_callbacks, &pending->frame_callback_list); + wl_list_init (&pending->frame_callback_list); - double_buffered_state_reset (&surface->pending); + double_buffered_state_reset (pending); +} + +static void +meta_wayland_surface_commit (struct wl_client *client, + struct wl_resource *resource) +{ + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); + + /* X11 unmanaged window */ + if (!surface) + return; + + commit_double_buffered_state (surface, &surface->pending); } static void @@ -1081,9 +1087,7 @@ bind_gtk_shell (struct wl_client *client, static void subsurface_parent_surface_committed (MetaWaylandSurface *surface) { - MetaWaylandCompositor *compositor = surface->compositor; - MetaWaylandDoubleBufferedState *pending_surface_state = - &surface->sub.pending_surface_state; + MetaWaylandDoubleBufferedState *pending_surface_state = &surface->sub.pending_surface_state; if (surface->sub.pending_pos) { @@ -1132,15 +1136,9 @@ subsurface_parent_surface_committed (MetaWaylandSurface *surface) } if (surface->sub.synchronous) - { - actor_surface_commit (surface, pending_surface_state); + commit_double_buffered_state (surface, pending_surface_state); - wl_list_insert_list (&compositor->frame_callbacks, - &pending_surface_state->frame_callback_list); - wl_list_init (&pending_surface_state->frame_callback_list); - } - - double_buffered_state_reset (&surface->sub.pending_surface_state); + double_buffered_state_reset (pending_surface_state); } static void From 92e36e7076c85b7da5d40c947c45fdd6fd4602fa Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sat, 1 Feb 2014 17:05:14 -0500 Subject: [PATCH 435/889] wayland-surface: Attach the buffer to a surface, even if it doesn't have a role Currently, set_cursor isn't properly working. Often, the requests look like this: cursor_surface = wl_compositor.create_surface() cursor_buffer = create_cursor_buffer() cursor_surface.attach(cursor_buffer, 0, 0) cursor_surface.commit() wl_pointer.set_cursor(cursor_surface, 7, 14) But since the surface doesn't "have a role" when the commit comes in, we ignore it, and don't do anything with the pending buffer. When set_cursor is called, however, we don't immediately update anything since it doesn't have a buffer. This effectively means that set_cursor has unpredictable side effects. Weston's toy toolkit reuses the same surface for every buffer, so it only fails the first time. In clients that use a new surface for every cursor sprite, the cursor is effectively invisible. To solve this, change the code to always set the buffer for a surface, even if it doesn't have any real role. --- src/wayland/meta-wayland-surface.c | 80 ++++++++++++++++-------------- 1 file changed, 43 insertions(+), 37 deletions(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 7817a3101..7a9001734 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -250,34 +250,25 @@ ensure_buffer_texture (MetaWaylandBuffer *buffer) static void cursor_surface_commit (MetaWaylandSurface *surface, - MetaWaylandDoubleBufferedState *pending) + MetaWaylandDoubleBufferedState *pending, + gboolean buffer_changed) { - MetaWaylandBuffer *buffer = pending->buffer; - - if (pending->newly_attached && buffer != surface->buffer_ref.buffer) - { - ensure_buffer_texture (buffer); - meta_wayland_buffer_reference (&surface->buffer_ref, buffer); - } - - meta_wayland_seat_update_sprite (surface->compositor->seat); + if (buffer_changed) + meta_wayland_seat_update_sprite (surface->compositor->seat); } -static gboolean +static void actor_surface_commit (MetaWaylandSurface *surface, - MetaWaylandDoubleBufferedState *pending) + MetaWaylandDoubleBufferedState *pending, + gboolean buffer_changed) { MetaSurfaceActor *surface_actor = surface->surface_actor; MetaWaylandBuffer *buffer = pending->buffer; - gboolean changed = FALSE; - /* wl_surface.attach */ - if (pending->newly_attached && buffer != surface->buffer_ref.buffer) + if (buffer_changed) { ensure_buffer_texture (buffer); - meta_wayland_buffer_reference (&surface->buffer_ref, buffer); meta_surface_actor_attach_wayland_buffer (surface_actor, buffer); - changed = TRUE; } surface_process_damage (surface, pending->damage); @@ -286,15 +277,16 @@ actor_surface_commit (MetaWaylandSurface *surface, meta_surface_actor_set_opaque_region (surface_actor, pending->opaque_region); if (pending->input_region) meta_surface_actor_set_input_region (surface_actor, pending->input_region); - - return changed; } static void toplevel_surface_commit (MetaWaylandSurface *surface, - MetaWaylandDoubleBufferedState *pending) + MetaWaylandDoubleBufferedState *pending, + gboolean buffer_changed) { - if (actor_surface_commit (surface, pending)) + actor_surface_commit (surface, pending, buffer_changed); + + if (buffer_changed) { MetaWindow *window = surface->window; MetaWaylandBuffer *buffer = pending->buffer; @@ -398,7 +390,8 @@ move_double_buffered_state (MetaWaylandDoubleBufferedState *from, static void subsurface_surface_commit (MetaWaylandSurface *surface, - MetaWaylandDoubleBufferedState *pending) + MetaWaylandDoubleBufferedState *pending, + gboolean buffer_changed) { /* * If the sub-surface is in synchronous mode, post-pone the commit of its @@ -416,21 +409,26 @@ subsurface_surface_commit (MetaWaylandSurface *surface, { move_double_buffered_state (pending, &surface->sub.pending_surface_state); } - else if (actor_surface_commit (surface, pending)) + else { - MetaSurfaceActor *surface_actor = surface->surface_actor; - MetaWaylandBuffer *buffer = pending->buffer; - float x, y; + actor_surface_commit (surface, pending, buffer_changed); - if (buffer != NULL) - clutter_actor_show (CLUTTER_ACTOR (surface_actor)); - else - clutter_actor_hide (CLUTTER_ACTOR (surface_actor)); + if (buffer_changed) + { + MetaSurfaceActor *surface_actor = surface->surface_actor; + MetaWaylandBuffer *buffer = pending->buffer; + float x, y; - clutter_actor_get_position (CLUTTER_ACTOR (surface_actor), &x, &y); - x += pending->dx; - y += pending->dy; - clutter_actor_set_position (CLUTTER_ACTOR (surface_actor), x, y); + if (buffer != NULL) + clutter_actor_show (CLUTTER_ACTOR (surface_actor)); + else + clutter_actor_hide (CLUTTER_ACTOR (surface_actor)); + + clutter_actor_get_position (CLUTTER_ACTOR (surface_actor), &x, &y); + x += pending->dx; + y += pending->dy; + clutter_actor_set_position (CLUTTER_ACTOR (surface_actor), x, y); + } } } @@ -448,13 +446,21 @@ commit_double_buffered_state (MetaWaylandSurface *surface, MetaWaylandDoubleBufferedState *pending) { MetaWaylandCompositor *compositor = surface->compositor; + gboolean buffer_changed = FALSE; + + /* wl_surface.attach */ + if (pending->newly_attached && pending->buffer != surface->buffer_ref.buffer) + { + meta_wayland_buffer_reference (&surface->buffer_ref, pending->buffer); + buffer_changed = TRUE; + } if (surface == compositor->seat->sprite) - cursor_surface_commit (surface, pending); + cursor_surface_commit (surface, pending, buffer_changed); else if (surface->window) - toplevel_surface_commit (surface, pending); + toplevel_surface_commit (surface, pending, buffer_changed); else if (surface->subsurface.resource) - subsurface_surface_commit (surface, pending); + subsurface_surface_commit (surface, pending, buffer_changed); g_list_foreach (surface->subsurfaces, parent_surface_committed, From fdeb72224c778e0904514849a8a6ead26c67b10b Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sat, 1 Feb 2014 17:18:21 -0500 Subject: [PATCH 436/889] wayland-seat: Fix pointer issues Moving the mouse over weston-terminal, we can see several issues: * it often updates late, or not at all * the attachment of the pointer sprite is wrong These are because we willy-nilly call seat_update_sprite all over the place, and often in wrong areas. Set up a set_pointer_surface helper method that will do the right thing for us in all cases, and call it on transitions. --- src/wayland/meta-wayland-seat.c | 57 ++++++++++++--------------------- 1 file changed, 21 insertions(+), 36 deletions(-) diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c index 9b853e13d..087cbe696 100644 --- a/src/wayland/meta-wayland-seat.c +++ b/src/wayland/meta-wayland-seat.c @@ -48,16 +48,19 @@ unbind_resource (struct wl_resource *resource) } static void -pointer_unmap_sprite (MetaWaylandSeat *seat) +set_cursor_surface (MetaWaylandSeat *seat, + MetaWaylandSurface *surface) { - if (seat->cursor_tracker) - meta_cursor_tracker_set_window_cursor (seat->cursor_tracker, NULL, 0, 0); + if (seat->sprite == surface) + return; if (seat->sprite) - { - wl_list_remove (&seat->sprite_destroy_listener.link); - seat->sprite = NULL; - } + wl_list_remove (&seat->sprite_destroy_listener.link); + + seat->sprite = surface; + + if (seat->sprite) + wl_resource_add_destroy_listener (seat->sprite->resource, &seat->sprite_destroy_listener); } void @@ -68,7 +71,7 @@ meta_wayland_seat_update_sprite (MetaWaylandSeat *seat) if (seat->cursor_tracker == NULL) return; - if (seat->sprite->buffer_ref.buffer) + if (seat->sprite && seat->sprite->buffer_ref.buffer) buffer = seat->sprite->buffer_ref.buffer->resource; else buffer = NULL; @@ -89,9 +92,7 @@ pointer_set_cursor (struct wl_client *client, MetaWaylandSeat *seat = wl_resource_get_user_data (resource); MetaWaylandSurface *surface; - surface = (surface_resource ? - wl_resource_get_user_data (surface_resource) : - NULL); + surface = (surface_resource ? wl_resource_get_user_data (surface_resource) : NULL); if (seat->pointer.focus == NULL) return; @@ -102,29 +103,13 @@ pointer_set_cursor (struct wl_client *client, seat->hotspot_x = x; seat->hotspot_y = y; - - if (seat->sprite != surface) - { - pointer_unmap_sprite (seat); - - if (!surface) - return; - - wl_resource_add_destroy_listener (surface->resource, - &seat->sprite_destroy_listener); - - seat->sprite = surface; - - if (seat->sprite->buffer_ref.buffer) - meta_wayland_seat_update_sprite (seat); - } + set_cursor_surface (seat, surface); + meta_wayland_seat_update_sprite (seat); } -static const struct wl_pointer_interface -pointer_interface = - { - pointer_set_cursor - }; +static const struct wl_pointer_interface pointer_interface = { + pointer_set_cursor +}; static void seat_get_pointer (struct wl_client *client, @@ -211,10 +196,10 @@ bind_seat (struct wl_client *client, static void pointer_handle_sprite_destroy (struct wl_listener *listener, void *data) { - MetaWaylandSeat *seat = - wl_container_of (listener, seat, sprite_destroy_listener); + MetaWaylandSeat *seat = wl_container_of (listener, seat, sprite_destroy_listener); - pointer_unmap_sprite (seat); + set_cursor_surface (seat, NULL); + meta_wayland_seat_update_sprite (seat); } MetaWaylandSeat * @@ -457,7 +442,7 @@ meta_wayland_seat_repick (MetaWaylandSeat *seat, void meta_wayland_seat_free (MetaWaylandSeat *seat) { - pointer_unmap_sprite (seat); + set_cursor_surface (seat, NULL); meta_wayland_pointer_release (&seat->pointer); meta_wayland_keyboard_release (&seat->keyboard); From 13651949ed06d42fc5215a788281bae01b08d6de Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sat, 1 Feb 2014 17:55:03 -0500 Subject: [PATCH 437/889] wayland-seat: Rename sprite to cursor_surface --- src/wayland/meta-wayland-seat.c | 31 +++++++++++++++--------------- src/wayland/meta-wayland-seat.h | 6 +++--- src/wayland/meta-wayland-surface.c | 4 ++-- 3 files changed, 21 insertions(+), 20 deletions(-) diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c index 087cbe696..4baadac86 100644 --- a/src/wayland/meta-wayland-seat.c +++ b/src/wayland/meta-wayland-seat.c @@ -51,28 +51,29 @@ static void set_cursor_surface (MetaWaylandSeat *seat, MetaWaylandSurface *surface) { - if (seat->sprite == surface) + if (seat->cursor_surface == surface) return; - if (seat->sprite) - wl_list_remove (&seat->sprite_destroy_listener.link); + if (seat->cursor_surface) + wl_list_remove (&seat->cursor_surface_destroy_listener.link); - seat->sprite = surface; + seat->cursor_surface = surface; - if (seat->sprite) - wl_resource_add_destroy_listener (seat->sprite->resource, &seat->sprite_destroy_listener); + if (seat->cursor_surface) + wl_resource_add_destroy_listener (seat->cursor_surface->resource, + &seat->cursor_surface_destroy_listener); } void -meta_wayland_seat_update_sprite (MetaWaylandSeat *seat) +meta_wayland_seat_update_cursor_surface (MetaWaylandSeat *seat) { struct wl_resource *buffer; if (seat->cursor_tracker == NULL) return; - if (seat->sprite && seat->sprite->buffer_ref.buffer) - buffer = seat->sprite->buffer_ref.buffer->resource; + if (seat->cursor_surface && seat->cursor_surface->buffer_ref.buffer) + buffer = seat->cursor_surface->buffer_ref.buffer->resource; else buffer = NULL; @@ -104,7 +105,7 @@ pointer_set_cursor (struct wl_client *client, seat->hotspot_x = x; seat->hotspot_y = y; set_cursor_surface (seat, surface); - meta_wayland_seat_update_sprite (seat); + meta_wayland_seat_update_cursor_surface (seat); } static const struct wl_pointer_interface pointer_interface = { @@ -194,12 +195,12 @@ bind_seat (struct wl_client *client, } static void -pointer_handle_sprite_destroy (struct wl_listener *listener, void *data) +pointer_handle_cursor_surface_destroy (struct wl_listener *listener, void *data) { - MetaWaylandSeat *seat = wl_container_of (listener, seat, sprite_destroy_listener); + MetaWaylandSeat *seat = wl_container_of (listener, seat, cursor_surface_destroy_listener); set_cursor_surface (seat, NULL); - meta_wayland_seat_update_sprite (seat); + meta_wayland_seat_update_cursor_surface (seat); } MetaWaylandSeat * @@ -220,8 +221,8 @@ meta_wayland_seat_new (struct wl_display *display, seat->current_stage = 0; - seat->sprite = NULL; - seat->sprite_destroy_listener.notify = pointer_handle_sprite_destroy; + seat->cursor_surface = NULL; + seat->cursor_surface_destroy_listener.notify = pointer_handle_cursor_surface_destroy; seat->hotspot_x = 16; seat->hotspot_y = 16; diff --git a/src/wayland/meta-wayland-seat.h b/src/wayland/meta-wayland-seat.h index dd2b85e72..f2c7fc249 100644 --- a/src/wayland/meta-wayland-seat.h +++ b/src/wayland/meta-wayland-seat.h @@ -66,9 +66,9 @@ struct _MetaWaylandSeat struct wl_display *display; MetaCursorTracker *cursor_tracker; - MetaWaylandSurface *sprite; + MetaWaylandSurface *cursor_surface; int hotspot_x, hotspot_y; - struct wl_listener sprite_destroy_listener; + struct wl_listener cursor_surface_destroy_listener; ClutterActor *current_stage; }; @@ -90,7 +90,7 @@ meta_wayland_seat_repick (MetaWaylandSeat *seat, const ClutterEvent *for_event); void -meta_wayland_seat_update_sprite (MetaWaylandSeat *seat); +meta_wayland_seat_update_cursor_surface (MetaWaylandSeat *seat); void meta_wayland_seat_free (MetaWaylandSeat *seat); diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 7a9001734..0e8ffae35 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -254,7 +254,7 @@ cursor_surface_commit (MetaWaylandSurface *surface, gboolean buffer_changed) { if (buffer_changed) - meta_wayland_seat_update_sprite (surface->compositor->seat); + meta_wayland_seat_update_cursor_surface (surface->compositor->seat); } static void @@ -455,7 +455,7 @@ commit_double_buffered_state (MetaWaylandSurface *surface, buffer_changed = TRUE; } - if (surface == compositor->seat->sprite) + if (surface == compositor->seat->cursor_surface) cursor_surface_commit (surface, pending, buffer_changed); else if (surface->window) toplevel_surface_commit (surface, pending, buffer_changed); From 2f6f0f252c95b1990e3f23068a51e351acf92d93 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sat, 1 Feb 2014 17:45:51 -0500 Subject: [PATCH 438/889] wayland: Simply store a MetaWaylandBuffer There's no need for the MetaWaylandBufferReference abstraction... --- src/wayland/meta-wayland-private.h | 7 ++-- src/wayland/meta-wayland-seat.c | 4 +-- src/wayland/meta-wayland-surface.c | 26 +++++++++++--- src/wayland/meta-wayland-surface.h | 10 ++---- src/wayland/meta-wayland.c | 58 ++++++++++-------------------- 5 files changed, 46 insertions(+), 59 deletions(-) diff --git a/src/wayland/meta-wayland-private.h b/src/wayland/meta-wayland-private.h index 6dc9620f0..efd2e4afd 100644 --- a/src/wayland/meta-wayland-private.h +++ b/src/wayland/meta-wayland-private.h @@ -102,10 +102,9 @@ gboolean meta_wayland_compositor_handle_event (MetaWaylandComp MetaLauncher *meta_wayland_compositor_get_launcher (MetaWaylandCompositor *compositor); gboolean meta_wayland_compositor_is_native (MetaWaylandCompositor *compositor); -MetaWaylandBuffer * meta_wayland_buffer_from_resource (struct wl_resource *resource); - -void meta_wayland_buffer_reference (MetaWaylandBufferReference *ref, - MetaWaylandBuffer *buffer); +MetaWaylandBuffer * meta_wayland_buffer_from_resource (struct wl_resource *resource); +void meta_wayland_buffer_ref (MetaWaylandBuffer *buffer); +void meta_wayland_buffer_unref (MetaWaylandBuffer *buffer); void meta_wayland_compositor_update (MetaWaylandCompositor *compositor, const ClutterEvent *event); diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c index 4baadac86..83987cb08 100644 --- a/src/wayland/meta-wayland-seat.c +++ b/src/wayland/meta-wayland-seat.c @@ -72,8 +72,8 @@ meta_wayland_seat_update_cursor_surface (MetaWaylandSeat *seat) if (seat->cursor_tracker == NULL) return; - if (seat->cursor_surface && seat->cursor_surface->buffer_ref.buffer) - buffer = seat->cursor_surface->buffer_ref.buffer->resource; + if (seat->cursor_surface && seat->cursor_surface->buffer) + buffer = seat->cursor_surface->buffer->resource; else buffer = NULL; diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 0e8ffae35..764ec2c5e 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -71,6 +71,22 @@ typedef struct struct wl_listener sibling_destroy_listener; } MetaWaylandSubsurfacePlacementOp; +static void +surface_set_buffer (MetaWaylandSurface *surface, + MetaWaylandBuffer *buffer) +{ + if (surface->buffer == buffer) + return; + + if (surface->buffer) + meta_wayland_buffer_unref (surface->buffer); + + surface->buffer = buffer; + + if (surface->buffer) + meta_wayland_buffer_ref (surface->buffer); +} + static void surface_process_damage (MetaWaylandSurface *surface, cairo_region_t *region) @@ -298,8 +314,8 @@ toplevel_surface_commit (MetaWaylandSurface *surface, int new_width; int new_height; - new_width = surface->buffer_ref.buffer->width; - new_height = surface->buffer_ref.buffer->height; + new_width = surface->buffer->width; + new_height = surface->buffer->height; if (new_width != window->rect.width || new_height != window->rect.height || pending->dx != 0 || @@ -449,9 +465,9 @@ commit_double_buffered_state (MetaWaylandSurface *surface, gboolean buffer_changed = FALSE; /* wl_surface.attach */ - if (pending->newly_attached && pending->buffer != surface->buffer_ref.buffer) + if (pending->newly_attached && surface->buffer != pending->buffer) { - meta_wayland_buffer_reference (&surface->buffer_ref, pending->buffer); + surface_set_buffer (surface, pending->buffer); buffer_changed = TRUE; } @@ -528,7 +544,7 @@ meta_wayland_surface_free (MetaWaylandSurface *surface) compositor->surfaces = g_list_remove (compositor->surfaces, surface); - meta_wayland_buffer_reference (&surface->buffer_ref, NULL); + surface_set_buffer (surface, NULL); double_buffered_state_destroy (&surface->pending); g_object_unref (surface->surface_actor); if (surface->resource) diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h index 454f5d4ce..129ce8aea 100644 --- a/src/wayland/meta-wayland-surface.h +++ b/src/wayland/meta-wayland-surface.h @@ -39,13 +39,7 @@ struct _MetaWaylandBuffer CoglTexture *texture; int32_t width, height; - uint32_t busy_count; -}; - -struct _MetaWaylandBufferReference -{ - MetaWaylandBuffer *buffer; - struct wl_listener destroy_listener; + uint32_t ref_count; }; typedef struct @@ -77,7 +71,7 @@ struct _MetaWaylandSurface { struct wl_resource *resource; MetaWaylandCompositor *compositor; - MetaWaylandBufferReference buffer_ref; + MetaWaylandBuffer *buffer; MetaSurfaceActor *surface_actor; MetaWindow *window; MetaWaylandSurfaceExtension xdg_surface; diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index 39eedc754..f3e828f3f 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -138,6 +138,24 @@ meta_wayland_buffer_destroy_handler (struct wl_listener *listener, g_slice_free (MetaWaylandBuffer, buffer); } +void +meta_wayland_buffer_ref (MetaWaylandBuffer *buffer) +{ + buffer->ref_count++; +} + +void +meta_wayland_buffer_unref (MetaWaylandBuffer *buffer) +{ + buffer->ref_count--; + if (buffer->ref_count == 0) + { + g_clear_pointer (&buffer->texture, cogl_object_unref); + g_assert (wl_resource_get_client (buffer->resource)); + wl_resource_queue_event (buffer->resource, WL_BUFFER_RELEASE); + } +} + MetaWaylandBuffer * meta_wayland_buffer_from_resource (struct wl_resource *resource) { @@ -165,46 +183,6 @@ meta_wayland_buffer_from_resource (struct wl_resource *resource) return buffer; } -static void -meta_wayland_buffer_reference_handle_destroy (struct wl_listener *listener, - void *data) -{ - MetaWaylandBufferReference *ref = - wl_container_of (listener, ref, destroy_listener); - - g_assert (data == ref->buffer); - - ref->buffer = NULL; -} - -void -meta_wayland_buffer_reference (MetaWaylandBufferReference *ref, - MetaWaylandBuffer *buffer) -{ - if (ref->buffer && buffer != ref->buffer) - { - ref->buffer->busy_count--; - - if (ref->buffer->busy_count == 0) - { - g_clear_pointer (&ref->buffer->texture, cogl_object_unref); - g_assert (wl_resource_get_client (ref->buffer->resource)); - wl_resource_queue_event (ref->buffer->resource, WL_BUFFER_RELEASE); - } - - wl_list_remove (&ref->destroy_listener.link); - } - - if (buffer && buffer != ref->buffer) - { - buffer->busy_count++; - wl_signal_add (&buffer->destroy_signal, &ref->destroy_listener); - } - - ref->buffer = buffer; - ref->destroy_listener.notify = meta_wayland_buffer_reference_handle_destroy; -} - void meta_wayland_compositor_set_input_focus (MetaWaylandCompositor *compositor, MetaWindow *window) From cd35982d4ebeed68a7cceff2c8b4b8d336965a3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Thu, 30 Jan 2014 17:20:16 +0100 Subject: [PATCH 439/889] window: Remove duplicated function declaration --- src/core/window.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/window.c b/src/core/window.c index 30b4c2bfb..60b8e89fa 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -97,7 +97,6 @@ static void update_net_frame_extents (MetaWindow *window); static void recalc_window_type (MetaWindow *window); static void recalc_window_features (MetaWindow *window); static void invalidate_work_areas (MetaWindow *window); -static void recalc_window_type (MetaWindow *window); static void set_wm_state_on_xwindow (MetaDisplay *display, Window xwindow, int state); From 6a8a4bfdcd3665b8bd4e4aca572a69af07e44262 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 27 Jan 2014 10:33:14 -0500 Subject: [PATCH 440/889] window: Remove internal recalc_window_type / recalc_window_features Just use the public symbols for them. --- src/core/window.c | 36 +++++++++++------------------------- 1 file changed, 11 insertions(+), 25 deletions(-) diff --git a/src/core/window.c b/src/core/window.c index 60b8e89fa..ad8f67d19 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -94,8 +94,6 @@ static void ping_data_free (MetaPingData *ping_data); static void update_sm_hints (MetaWindow *window); static void update_net_frame_extents (MetaWindow *window); -static void recalc_window_type (MetaWindow *window); -static void recalc_window_features (MetaWindow *window); static void invalidate_work_areas (MetaWindow *window); static void set_wm_state_on_xwindow (MetaDisplay *display, Window xwindow, @@ -236,7 +234,7 @@ prefs_changed_callback (MetaPreference pref, window->type == META_WINDOW_MODAL_DIALOG) { window->attached = meta_window_should_attach_to_parent (window); - recalc_window_features (window); + meta_window_recalc_window_features (window); meta_window_queue (window, META_QUEUE_MOVE_RESIZE); } } @@ -1126,7 +1124,7 @@ meta_window_new_shared (MetaDisplay *display, window->attached = meta_window_should_attach_to_parent (window); if (window->attached) - recalc_window_features (window); + meta_window_recalc_window_features (window); if (window->decorated) meta_window_ensure_frame (window); @@ -3635,7 +3633,7 @@ meta_window_maximize_internal (MetaWindow *window, if (maximize_horizontally || maximize_vertically) window->force_save_user_rect = FALSE; - recalc_window_features (window); + meta_window_recalc_window_features (window); set_net_wm_state (window); g_object_freeze_notify (G_OBJECT (window)); @@ -4119,7 +4117,7 @@ meta_window_unmaximize_internal (MetaWindow *window, window->display->grab_anchor_window_pos = window->user_rect; } - recalc_window_features (window); + meta_window_recalc_window_features (window); set_net_wm_state (window); } @@ -4223,7 +4221,7 @@ meta_window_make_fullscreen_internal (MetaWindow *window) meta_window_raise (window); meta_stack_thaw (window->screen->stack); - recalc_window_features (window); + meta_window_recalc_window_features (window); set_net_wm_state (window); /* For the auto-minimize feature, if we fail to get focus */ @@ -4269,7 +4267,7 @@ meta_window_unmake_fullscreen (MetaWindow *window) /* Need to update window->has_resize_func before we move_resize() */ - recalc_window_features (window); + meta_window_recalc_window_features (window); set_net_wm_state (window); meta_window_move_resize (window, @@ -4947,7 +4945,7 @@ meta_window_update_monitor (MetaWindow *window) /* If we're changing monitors, we need to update the has_maximize_func flag, * as the working area has changed. */ - recalc_window_features (window); + meta_window_recalc_window_features (window); } } @@ -7192,7 +7190,7 @@ meta_window_client_message (MetaWindow *window, (action == _NET_WM_STATE_ADD) || (action == _NET_WM_STATE_TOGGLE && !window->wm_state_modal); - recalc_window_type (window); + meta_window_recalc_window_type (window); meta_window_queue(window, META_QUEUE_MOVE_RESIZE); } @@ -7203,7 +7201,7 @@ meta_window_client_message (MetaWindow *window, (action == _NET_WM_STATE_ADD) || (action == _NET_WM_STATE_TOGGLE && !window->skip_pager); - recalc_window_features (window); + meta_window_recalc_window_features (window); set_net_wm_state (window); } @@ -7214,7 +7212,7 @@ meta_window_client_message (MetaWindow *window, (action == _NET_WM_STATE_ADD) || (action == _NET_WM_STATE_TOGGLE && !window->skip_taskbar); - recalc_window_features (window); + meta_window_recalc_window_features (window); set_net_wm_state (window); } @@ -8516,12 +8514,6 @@ meta_window_update_struts (MetaWindow *window) void meta_window_recalc_window_type (MetaWindow *window) -{ - recalc_window_type (window); -} - -static void -recalc_window_type (MetaWindow *window) { MetaWindowType old_type; @@ -8642,7 +8634,7 @@ meta_window_type_changed (MetaWindow *window) GObject *object = G_OBJECT (window); window->attached = meta_window_should_attach_to_parent (window); - recalc_window_features (window); + meta_window_recalc_window_features (window); if (!window->override_redirect) set_net_wm_state (window); @@ -8748,12 +8740,6 @@ set_allowed_actions_hint (MetaWindow *window) void meta_window_recalc_features (MetaWindow *window) -{ - recalc_window_features (window); -} - -static void -recalc_window_features (MetaWindow *window) { gboolean old_has_close_func; gboolean old_has_minimize_func; From ff89f1e271e861b4df59372b8d9a6fad547891af Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 23 Jan 2014 17:10:23 -0500 Subject: [PATCH 441/889] window: Use window-props interface to load role/net_wm_type on init --- src/core/window-props.c | 4 ++-- src/core/window.c | 9 +-------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/src/core/window-props.c b/src/core/window-props.c index a9145eefa..6e07d6ef8 100644 --- a/src/core/window-props.c +++ b/src/core/window-props.c @@ -1764,8 +1764,8 @@ meta_display_init_window_prop_hooks (MetaDisplay *display) { display->atom__NET_WM_ICON_GEOMETRY, META_PROP_VALUE_CARDINAL_LIST, reload_icon_geometry, FALSE, FALSE }, { display->atom_WM_CLIENT_LEADER, META_PROP_VALUE_INVALID, complain_about_broken_client, FALSE, FALSE }, { display->atom_SM_CLIENT_ID, META_PROP_VALUE_INVALID, complain_about_broken_client, FALSE, FALSE }, - { display->atom_WM_WINDOW_ROLE, META_PROP_VALUE_INVALID, reload_wm_window_role, FALSE, FALSE }, - { display->atom__NET_WM_WINDOW_TYPE, META_PROP_VALUE_INVALID, reload_net_wm_window_type, FALSE, TRUE }, + { display->atom_WM_WINDOW_ROLE, META_PROP_VALUE_INVALID, reload_wm_window_role, TRUE, FALSE }, + { display->atom__NET_WM_WINDOW_TYPE, META_PROP_VALUE_INVALID, reload_net_wm_window_type, TRUE, TRUE }, { display->atom__NET_WM_STRUT, META_PROP_VALUE_INVALID, reload_struts, FALSE, FALSE }, { display->atom__NET_WM_STRUT_PARTIAL, META_PROP_VALUE_INVALID, reload_struts, FALSE, FALSE }, { display->atom__NET_WM_BYPASS_COMPOSITOR, META_PROP_VALUE_CARDINAL, reload_bypass_compositor, FALSE, FALSE }, diff --git a/src/core/window.c b/src/core/window.c index ad8f67d19..e1455d2ce 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -1060,14 +1060,7 @@ meta_window_new_shared (MetaDisplay *display, if (!window->override_redirect && client_type == META_WINDOW_CLIENT_TYPE_X11) - { - update_sm_hints (window); /* must come after transient_for */ - - meta_window_update_role (window); - } - - if (client_type == META_WINDOW_CLIENT_TYPE_X11) - meta_window_update_net_wm_type (window); + update_sm_hints (window); /* must come after transient_for */ if (!window->override_redirect) meta_window_update_icon_now (window); From f7097e6f66ba6d7ea41c8c7bde24926c77843848 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 23 Jan 2014 16:33:53 -0500 Subject: [PATCH 442/889] Start moving X11-specific code to window-x11.c The goal here is to make MetaWindow represent a toplevel, managed window, regardless of if it's X11 or Wayland, and build an abstraction layer up. Right now, most of the X11 code is in core/ and the wayland code in wayland/, but in the future, I want to move a lot of the X11 code to a new toplevel, x11/. --- src/Makefile.am | 2 + src/core/display.c | 15 +- src/core/window-private.h | 17 +- src/core/window-props.c | 7 +- src/core/window-x11.c | 1148 +++++++++++++++++++++++++++++++++++++ src/core/window-x11.h | 44 ++ src/core/window.c | 1131 +----------------------------------- 7 files changed, 1223 insertions(+), 1141 deletions(-) create mode 100644 src/core/window-x11.c create mode 100644 src/core/window-x11.h diff --git a/src/Makefile.am b/src/Makefile.am index b81c6ec51..53f6f7af4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -163,6 +163,8 @@ libmutter_wayland_la_SOURCES = \ core/util-private.h \ core/window-props.c \ core/window-props.h \ + core/window-x11.c \ + core/window-x11.h \ core/window.c \ core/window-private.h \ meta/window.h \ diff --git a/src/core/display.c b/src/core/display.c index 7376f0eb3..24365f3b0 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -36,6 +36,7 @@ #include #include "screen-private.h" #include "window-private.h" +#include "window-x11.h" #include "window-props.h" #include "group-props.h" #include "frame.h" @@ -1581,7 +1582,7 @@ handle_net_restack_window (MetaDisplay* display, * * Also, unconditionally following these is REALLY stupid--we should * combine this code with the stuff in - * meta_window_configure_request() which is smart about whether to + * meta_window_x11_configure_request() which is smart about whether to * follow the request or do something else (though not smart enough * and is also too stupid to handle the sibling stuff). */ @@ -2692,9 +2693,9 @@ handle_other_xevent (MetaDisplay *display, XShapeEvent *sev = (XShapeEvent*) event; if (sev->kind == ShapeBounding) - meta_window_update_shape_region_x11 (window); + meta_window_x11_update_shape_region (window); else if (sev->kind == ShapeInput) - meta_window_update_input_region_x11 (window); + meta_window_x11_update_input_region (window); } else { @@ -2903,7 +2904,7 @@ handle_other_xevent (MetaDisplay *display, else { if (!frame_was_receiver) - meta_window_configure_request (window, event); + meta_window_x11_configure_request (window, event); } break; case GravityNotify: @@ -2920,9 +2921,9 @@ handle_other_xevent (MetaDisplay *display, MetaScreen *screen; if (window && !frame_was_receiver) - meta_window_property_notify (window, event); + meta_window_x11_property_notify (window, event); else if (property_for_window && !frame_was_receiver) - meta_window_property_notify (property_for_window, event); + meta_window_x11_property_notify (property_for_window, event); group = meta_display_lookup_group (display, event->xproperty.window); @@ -2993,7 +2994,7 @@ handle_other_xevent (MetaDisplay *display, if (window) { if (!frame_was_receiver) - meta_window_client_message (window, event); + meta_window_x11_client_message (window, event); } else { diff --git a/src/core/window-private.h b/src/core/window-private.h index 7c09e6835..679719b45 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -615,12 +615,6 @@ void meta_window_move_resize_wayland (MetaWindow *window, int height, int dx, int dy); -gboolean meta_window_configure_request (MetaWindow *window, - XEvent *event); -gboolean meta_window_property_notify (MetaWindow *window, - XEvent *event); -gboolean meta_window_client_message (MetaWindow *window, - XEvent *event); void meta_window_set_focused_internal (MetaWindow *window, gboolean focused); @@ -697,8 +691,6 @@ void meta_window_set_user_time (MetaWindow *window, void meta_window_update_icon_now (MetaWindow *window); -void meta_window_update_role (MetaWindow *window); -void meta_window_update_net_wm_type (MetaWindow *window); void meta_window_update_for_monitors_changed (MetaWindow *window); void meta_window_update_on_all_workspaces (MetaWindow *window); @@ -712,10 +704,6 @@ void meta_window_compute_tile_match (MetaWindow *window); gboolean meta_window_updates_are_frozen (MetaWindow *window); -void meta_window_update_opaque_region_x11 (MetaWindow *window); -void meta_window_update_input_region_x11 (MetaWindow *window); -void meta_window_update_shape_region_x11 (MetaWindow *window); - void meta_window_set_title (MetaWindow *window, const char *title); void meta_window_set_wm_class (MetaWindow *window, @@ -756,4 +744,9 @@ void meta_window_pong (MetaWindow *window, guint32 timestamp); Window meta_window_get_toplevel_xwindow (MetaWindow *window); +void meta_window_activate_full (MetaWindow *window, + guint32 timestamp, + MetaClientType source_indication, + MetaWorkspace *workspace); + #endif diff --git a/src/core/window-props.c b/src/core/window-props.c index 6e07d6ef8..ca73bd27b 100644 --- a/src/core/window-props.c +++ b/src/core/window-props.c @@ -39,6 +39,7 @@ #include #include "window-props.h" +#include "window-x11.h" #include #include "xprops.h" #include "frame.h" @@ -229,7 +230,7 @@ reload_net_wm_window_type (MetaWindow *window, MetaPropValue *value, gboolean initial) { - meta_window_update_net_wm_type (window); + meta_window_x11_update_net_wm_type (window); } static void @@ -333,7 +334,7 @@ reload_wm_window_role (MetaWindow *window, MetaPropValue *value, gboolean initial) { - meta_window_update_role (window); + meta_window_x11_update_role (window); } static void @@ -558,7 +559,7 @@ reload_opaque_region (MetaWindow *window, MetaPropValue *value, gboolean initial) { - meta_window_update_opaque_region_x11 (window); + meta_window_x11_update_opaque_region (window); } static void diff --git a/src/core/window-x11.c b/src/core/window-x11.c new file mode 100644 index 000000000..3391a548a --- /dev/null +++ b/src/core/window-x11.c @@ -0,0 +1,1148 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2001 Havoc Pennington, Anders Carlsson + * Copyright (C) 2002, 2003 Red Hat, Inc. + * Copyright (C) 2003 Rob Adams + * Copyright (C) 2004-2006 Elijah Newren + * + * 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 "config.h" + +#include "window-x11.h" + +#include +#include +#include /* For display->resource_mask */ + +#ifdef HAVE_SHAPE +#include +#endif + +#include +#include +#include + +#include "window-private.h" +#include "window-props.h" +#include "xprops.h" + +void +meta_window_x11_set_net_wm_state (MetaWindow *window) +{ + int i; + unsigned long data[13]; + + i = 0; + if (window->shaded) + { + data[i] = window->display->atom__NET_WM_STATE_SHADED; + ++i; + } + if (window->wm_state_modal) + { + data[i] = window->display->atom__NET_WM_STATE_MODAL; + ++i; + } + if (window->skip_pager) + { + data[i] = window->display->atom__NET_WM_STATE_SKIP_PAGER; + ++i; + } + if (window->skip_taskbar) + { + data[i] = window->display->atom__NET_WM_STATE_SKIP_TASKBAR; + ++i; + } + if (window->maximized_horizontally) + { + data[i] = window->display->atom__NET_WM_STATE_MAXIMIZED_HORZ; + ++i; + } + if (window->maximized_vertically) + { + data[i] = window->display->atom__NET_WM_STATE_MAXIMIZED_VERT; + ++i; + } + if (window->fullscreen) + { + data[i] = window->display->atom__NET_WM_STATE_FULLSCREEN; + ++i; + } + if (!meta_window_showing_on_its_workspace (window) || window->shaded) + { + data[i] = window->display->atom__NET_WM_STATE_HIDDEN; + ++i; + } + if (window->wm_state_above) + { + data[i] = window->display->atom__NET_WM_STATE_ABOVE; + ++i; + } + if (window->wm_state_below) + { + data[i] = window->display->atom__NET_WM_STATE_BELOW; + ++i; + } + if (window->wm_state_demands_attention) + { + data[i] = window->display->atom__NET_WM_STATE_DEMANDS_ATTENTION; + ++i; + } + if (window->on_all_workspaces_requested) + { + data[i] = window->display->atom__NET_WM_STATE_STICKY; + ++i; + } + if (meta_window_appears_focused (window)) + { + data[i] = window->display->atom__NET_WM_STATE_FOCUSED; + ++i; + } + + meta_verbose ("Setting _NET_WM_STATE with %d atoms\n", i); + + meta_error_trap_push (window->display); + XChangeProperty (window->display->xdisplay, window->xwindow, + window->display->atom__NET_WM_STATE, + XA_ATOM, + 32, PropModeReplace, (guchar*) data, i); + meta_error_trap_pop (window->display); + + if (window->fullscreen) + { + data[0] = meta_screen_monitor_index_to_xinerama_index (window->screen, + window->fullscreen_monitors[0]); + data[1] = meta_screen_monitor_index_to_xinerama_index (window->screen, + window->fullscreen_monitors[1]); + data[2] = meta_screen_monitor_index_to_xinerama_index (window->screen, + window->fullscreen_monitors[2]); + data[3] = meta_screen_monitor_index_to_xinerama_index (window->screen, + window->fullscreen_monitors[3]); + + meta_verbose ("Setting _NET_WM_FULLSCREEN_MONITORS\n"); + meta_error_trap_push (window->display); + XChangeProperty (window->display->xdisplay, + window->xwindow, + window->display->atom__NET_WM_FULLSCREEN_MONITORS, + XA_CARDINAL, 32, PropModeReplace, + (guchar*) data, 4); + meta_error_trap_pop (window->display); + } +} + +void +meta_window_x11_update_net_wm_type (MetaWindow *window) +{ + int n_atoms; + Atom *atoms; + int i; + + window->type_atom = None; + n_atoms = 0; + atoms = NULL; + + meta_prop_get_atom_list (window->display, window->xwindow, + window->display->atom__NET_WM_WINDOW_TYPE, + &atoms, &n_atoms); + + i = 0; + while (i < n_atoms) + { + /* We break as soon as we find one we recognize, + * supposed to prefer those near the front of the list + */ + if (atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_DESKTOP || + atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_DOCK || + atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_TOOLBAR || + atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_MENU || + atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_UTILITY || + atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_SPLASH || + atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_DIALOG || + atoms[i] == + window->display->atom__NET_WM_WINDOW_TYPE_DROPDOWN_MENU || + atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_POPUP_MENU || + atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_TOOLTIP || + atoms[i] == + window->display->atom__NET_WM_WINDOW_TYPE_NOTIFICATION || + atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_COMBO || + atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_DND || + atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_NORMAL) + { + window->type_atom = atoms[i]; + break; + } + + ++i; + } + + meta_XFree (atoms); + + if (meta_is_verbose ()) + { + char *str; + + str = NULL; + if (window->type_atom != None) + { + meta_error_trap_push (window->display); + str = XGetAtomName (window->display->xdisplay, window->type_atom); + meta_error_trap_pop (window->display); + } + + meta_verbose ("Window %s type atom %s\n", window->desc, + str ? str : "(none)"); + + if (str) + meta_XFree (str); + } + + meta_window_recalc_window_type (window); +} + +void +meta_window_x11_update_role (MetaWindow *window) +{ + char *str; + + g_return_if_fail (!window->override_redirect); + + if (window->role) + g_free (window->role); + window->role = NULL; + + if (meta_prop_get_latin1_string (window->display, window->xwindow, + window->display->atom_WM_WINDOW_ROLE, + &str)) + { + window->role = g_strdup (str); + meta_XFree (str); + } + + meta_verbose ("Updated role of %s to '%s'\n", + window->desc, window->role ? window->role : "null"); +} + +static void +meta_window_set_opaque_region (MetaWindow *window, + cairo_region_t *region) +{ + g_clear_pointer (&window->opaque_region, cairo_region_destroy); + + if (region != NULL) + window->opaque_region = cairo_region_reference (region); + + if (window->display->compositor) + meta_compositor_window_shape_changed (window->display->compositor, window); +} + +void +meta_window_x11_update_opaque_region (MetaWindow *window) +{ + cairo_region_t *opaque_region = NULL; + gulong *region = NULL; + int nitems; + + if (meta_prop_get_cardinal_list (window->display, + window->xwindow, + window->display->atom__NET_WM_OPAQUE_REGION, + ®ion, &nitems)) + { + cairo_rectangle_int_t *rects; + int i, rect_index, nrects; + + if (nitems % 4 != 0) + { + meta_verbose ("_NET_WM_OPAQUE_REGION does not have a list of 4-tuples."); + goto out; + } + + /* empty region */ + if (nitems == 0) + goto out; + + nrects = nitems / 4; + + rects = g_new (cairo_rectangle_int_t, nrects); + + rect_index = 0; + i = 0; + while (i < nitems) + { + cairo_rectangle_int_t *rect = &rects[rect_index]; + + rect->x = region[i++]; + rect->y = region[i++]; + rect->width = region[i++]; + rect->height = region[i++]; + + rect_index++; + } + + opaque_region = cairo_region_create_rectangles (rects, nrects); + + g_free (rects); + } + + out: + meta_XFree (region); + + meta_window_set_opaque_region (window, opaque_region); + cairo_region_destroy (opaque_region); +} + +static cairo_region_t * +region_create_from_x_rectangles (const XRectangle *rects, + int n_rects) +{ + int i; + cairo_rectangle_int_t *cairo_rects = g_newa (cairo_rectangle_int_t, n_rects); + + for (i = 0; i < n_rects; i ++) + { + cairo_rects[i].x = rects[i].x; + cairo_rects[i].y = rects[i].y; + cairo_rects[i].width = rects[i].width; + cairo_rects[i].height = rects[i].height; + } + + return cairo_region_create_rectangles (cairo_rects, n_rects); +} + +static void +meta_window_set_input_region (MetaWindow *window, + cairo_region_t *region) +{ + g_clear_pointer (&window->input_region, cairo_region_destroy); + + if (region != NULL) + window->input_region = cairo_region_reference (region); + + if (window->display->compositor) + meta_compositor_window_shape_changed (window->display->compositor, window); +} + +void +meta_window_x11_update_input_region (MetaWindow *window) +{ + cairo_region_t *region = NULL; + +#ifdef HAVE_SHAPE + if (META_DISPLAY_HAS_SHAPE (window->display)) + { + /* Translate the set of XShape rectangles that we + * get from the X server to a cairo_region. */ + XRectangle *rects = NULL; + int n_rects, ordering; + + int x_bounding, y_bounding, x_clip, y_clip; + unsigned w_bounding, h_bounding, w_clip, h_clip; + int bounding_shaped, clip_shaped; + + meta_error_trap_push (window->display); + XShapeQueryExtents (window->display->xdisplay, window->xwindow, + &bounding_shaped, &x_bounding, &y_bounding, + &w_bounding, &h_bounding, + &clip_shaped, &x_clip, &y_clip, + &w_clip, &h_clip); + + rects = XShapeGetRectangles (window->display->xdisplay, + window->xwindow, + ShapeInput, + &n_rects, + &ordering); + meta_error_trap_pop (window->display); + + /* XXX: The x shape extension doesn't provide a way to only test if an + * input shape has been specified, so we have to query and throw away the + * rectangles. */ + if (rects) + { + if (n_rects > 1 || + (n_rects == 1 && + (rects[0].x != x_bounding || + rects[1].y != y_bounding || + rects[2].width != w_bounding || + rects[3].height != h_bounding))) + region = region_create_from_x_rectangles (rects, n_rects); + + XFree (rects); + } + } +#endif /* HAVE_SHAPE */ + + if (region != NULL) + { + cairo_rectangle_int_t client_area; + + client_area.x = 0; + client_area.y = 0; + client_area.width = window->rect.width; + client_area.height = window->rect.height; + + /* The shape we get back from the client may have coordinates + * outside of the frame. The X SHAPE Extension requires that + * the overall shape the client provides never exceeds the + * "bounding rectangle" of the window -- the shape that the + * window would have gotten if it was unshaped. In our case, + * this is simply the client area. + */ + cairo_region_intersect_rectangle (region, &client_area); + } + + meta_window_set_input_region (window, region); + cairo_region_destroy (region); +} + +static void +meta_window_set_shape_region (MetaWindow *window, + cairo_region_t *region) +{ + g_clear_pointer (&window->shape_region, cairo_region_destroy); + + if (region != NULL) + window->shape_region = cairo_region_reference (region); + + if (window->display->compositor) + meta_compositor_window_shape_changed (window->display->compositor, window); +} + +void +meta_window_x11_update_shape_region (MetaWindow *window) +{ + cairo_region_t *region = NULL; + +#ifdef HAVE_SHAPE + if (META_DISPLAY_HAS_SHAPE (window->display)) + { + /* Translate the set of XShape rectangles that we + * get from the X server to a cairo_region. */ + XRectangle *rects = NULL; + int n_rects, ordering; + + int x_bounding, y_bounding, x_clip, y_clip; + unsigned w_bounding, h_bounding, w_clip, h_clip; + int bounding_shaped, clip_shaped; + + meta_error_trap_push (window->display); + XShapeQueryExtents (window->display->xdisplay, window->xwindow, + &bounding_shaped, &x_bounding, &y_bounding, + &w_bounding, &h_bounding, + &clip_shaped, &x_clip, &y_clip, + &w_clip, &h_clip); + + if (bounding_shaped) + { + rects = XShapeGetRectangles (window->display->xdisplay, + window->xwindow, + ShapeBounding, + &n_rects, + &ordering); + } + meta_error_trap_pop (window->display); + + if (rects) + { + region = region_create_from_x_rectangles (rects, n_rects); + XFree (rects); + } + } +#endif /* HAVE_SHAPE */ + + if (region != NULL) + { + cairo_rectangle_int_t client_area; + + client_area.x = 0; + client_area.y = 0; + client_area.width = window->rect.width; + client_area.height = window->rect.height; + + /* The shape we get back from the client may have coordinates + * outside of the frame. The X SHAPE Extension requires that + * the overall shape the client provides never exceeds the + * "bounding rectangle" of the window -- the shape that the + * window would have gotten if it was unshaped. In our case, + * this is simply the client area. + */ + cairo_region_intersect_rectangle (region, &client_area); + } + + meta_window_set_shape_region (window, region); + cairo_region_destroy (region); +} + +/* Generally meta_window_same_application() is a better idea + * of "sameness", since it handles the case where multiple apps + * want to look like the same app or the same app wants to look + * like multiple apps, but in the case of workarounds for legacy + * applications (which likely aren't setting the group properly + * anyways), it may be desirable to check this as well. + */ +static gboolean +meta_window_same_client (MetaWindow *window, + MetaWindow *other_window) +{ + int resource_mask = window->display->xdisplay->resource_mask; + + return ((window->xwindow & ~resource_mask) == + (other_window->xwindow & ~resource_mask)); +} + +gboolean +meta_window_x11_configure_request (MetaWindow *window, + XEvent *event) +{ + /* Note that x, y is the corner of the window border, + * and width, height is the size of the window inside + * its border, but that we always deny border requests + * and give windows a border of 0. But we save the + * requested border here. + */ + if (event->xconfigurerequest.value_mask & CWBorderWidth) + window->border_width = event->xconfigurerequest.border_width; + + meta_window_move_resize_request(window, + event->xconfigurerequest.value_mask, + window->size_hints.win_gravity, + event->xconfigurerequest.x, + event->xconfigurerequest.y, + event->xconfigurerequest.width, + event->xconfigurerequest.height); + + /* Handle stacking. We only handle raises/lowers, mostly because + * stack.c really can't deal with anything else. I guess we'll fix + * that if a client turns up that really requires it. Only a very + * few clients even require the raise/lower (and in fact all client + * attempts to deal with stacking order are essentially broken, + * since they have no idea what other clients are involved or how + * the stack looks). + * + * I'm pretty sure no interesting client uses TopIf, BottomIf, or + * Opposite anyway, so the only possible missing thing is + * Above/Below with a sibling set. For now we just pretend there's + * never a sibling set and always do the full raise/lower instead of + * the raise-just-above/below-sibling. + */ + if (event->xconfigurerequest.value_mask & CWStackMode) + { + MetaWindow *active_window; + active_window = window->display->focus_window; + if (meta_prefs_get_disable_workarounds ()) + { + meta_topic (META_DEBUG_STACK, + "%s sent an xconfigure stacking request; this is " + "broken behavior and the request is being ignored.\n", + window->desc); + } + else if (active_window && + !meta_window_same_application (window, active_window) && + !meta_window_same_client (window, active_window) && + XSERVER_TIME_IS_BEFORE (window->net_wm_user_time, + active_window->net_wm_user_time)) + { + meta_topic (META_DEBUG_STACK, + "Ignoring xconfigure stacking request from %s (with " + "user_time %u); currently active application is %s (with " + "user_time %u).\n", + window->desc, + window->net_wm_user_time, + active_window->desc, + active_window->net_wm_user_time); + if (event->xconfigurerequest.detail == Above) + meta_window_set_demands_attention(window); + } + else + { + switch (event->xconfigurerequest.detail) + { + case Above: + meta_window_raise (window); + break; + case Below: + meta_window_lower (window); + break; + case TopIf: + case BottomIf: + case Opposite: + break; + } + } + } + + return TRUE; +} + +static gboolean +process_property_notify (MetaWindow *window, + XPropertyEvent *event) +{ + Window xid = window->xwindow; + + if (meta_is_verbose ()) /* avoid looking up the name if we don't have to */ + { + char *property_name = XGetAtomName (window->display->xdisplay, + event->atom); + + meta_verbose ("Property notify on %s for %s\n", + window->desc, property_name); + XFree (property_name); + } + + if (event->atom == window->display->atom__NET_WM_USER_TIME && + window->user_time_window) + { + xid = window->user_time_window; + } + + meta_window_reload_property_from_xwindow (window, xid, event->atom, FALSE); + + return TRUE; +} + +gboolean +meta_window_x11_property_notify (MetaWindow *window, + XEvent *event) +{ + return process_property_notify (window, &event->xproperty); +} + +#define _NET_WM_MOVERESIZE_SIZE_TOPLEFT 0 +#define _NET_WM_MOVERESIZE_SIZE_TOP 1 +#define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT 2 +#define _NET_WM_MOVERESIZE_SIZE_RIGHT 3 +#define _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT 4 +#define _NET_WM_MOVERESIZE_SIZE_BOTTOM 5 +#define _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT 6 +#define _NET_WM_MOVERESIZE_SIZE_LEFT 7 +#define _NET_WM_MOVERESIZE_MOVE 8 +#define _NET_WM_MOVERESIZE_SIZE_KEYBOARD 9 +#define _NET_WM_MOVERESIZE_MOVE_KEYBOARD 10 +#define _NET_WM_MOVERESIZE_CANCEL 11 + +static int +query_pressed_buttons (MetaWindow *window) +{ + double x, y, query_root_x, query_root_y; + Window root, child; + XIButtonState buttons; + XIModifierState mods; + XIGroupState group; + int button = 0; + + meta_error_trap_push (window->display); + XIQueryPointer (window->display->xdisplay, + META_VIRTUAL_CORE_POINTER_ID, + window->xwindow, + &root, &child, + &query_root_x, &query_root_y, + &x, &y, + &buttons, &mods, &group); + + if (meta_error_trap_pop_with_return (window->display) != Success) + goto out; + + if (XIMaskIsSet (buttons.mask, Button1)) + button |= 1 << 1; + if (XIMaskIsSet (buttons.mask, Button2)) + button |= 1 << 2; + if (XIMaskIsSet (buttons.mask, Button3)) + button |= 1 << 3; + + free (buttons.mask); + + out: + return button; +} + +gboolean +meta_window_x11_client_message (MetaWindow *window, + XEvent *event) +{ + MetaDisplay *display; + + display = window->display; + + if (window->override_redirect) + { + /* Don't warn here: we could warn on any of the messages below, + * but we might also receive other client messages that are + * part of protocols we don't know anything about. So, silently + * ignoring is simplest. + */ + return FALSE; + } + + if (event->xclient.message_type == + display->atom__NET_CLOSE_WINDOW) + { + guint32 timestamp; + + if (event->xclient.data.l[0] != 0) + timestamp = event->xclient.data.l[0]; + else + { + meta_warning ("Receiving a NET_CLOSE_WINDOW message for %s without " + "a timestamp! This means some buggy (outdated) " + "application is on the loose!\n", + window->desc); + timestamp = meta_display_get_current_time (window->display); + } + + meta_window_delete (window, timestamp); + + return TRUE; + } + else if (event->xclient.message_type == + display->atom__NET_WM_DESKTOP) + { + int space; + MetaWorkspace *workspace; + + space = event->xclient.data.l[0]; + + meta_verbose ("Request to move %s to workspace %d\n", + window->desc, space); + + workspace = + meta_screen_get_workspace_by_index (window->screen, + space); + + if (workspace) + { + if (window->on_all_workspaces_requested) + meta_window_unstick (window); + meta_window_change_workspace (window, workspace); + } + else if (space == (int) 0xFFFFFFFF) + { + meta_window_stick (window); + } + else + { + meta_verbose ("No such workspace %d for screen\n", space); + } + + meta_verbose ("Window %s now on_all_workspaces = %d\n", + window->desc, window->on_all_workspaces); + + return TRUE; + } + else if (event->xclient.message_type == + display->atom__NET_WM_STATE) + { + gulong action; + Atom first; + Atom second; + + action = event->xclient.data.l[0]; + first = event->xclient.data.l[1]; + second = event->xclient.data.l[2]; + + if (meta_is_verbose ()) + { + char *str1; + char *str2; + + meta_error_trap_push_with_return (display); + str1 = XGetAtomName (display->xdisplay, first); + if (meta_error_trap_pop_with_return (display) != Success) + str1 = NULL; + + meta_error_trap_push_with_return (display); + str2 = XGetAtomName (display->xdisplay, second); + if (meta_error_trap_pop_with_return (display) != Success) + str2 = NULL; + + meta_verbose ("Request to change _NET_WM_STATE action %lu atom1: %s atom2: %s\n", + action, + str1 ? str1 : "(unknown)", + str2 ? str2 : "(unknown)"); + + meta_XFree (str1); + meta_XFree (str2); + } + + if (first == display->atom__NET_WM_STATE_SHADED || + second == display->atom__NET_WM_STATE_SHADED) + { + gboolean shade; + guint32 timestamp; + + /* Stupid protocol has no timestamp; of course, shading + * sucks anyway so who really cares that we're forced to do + * a roundtrip here? + */ + timestamp = meta_display_get_current_time_roundtrip (window->display); + + shade = (action == _NET_WM_STATE_ADD || + (action == _NET_WM_STATE_TOGGLE && !window->shaded)); + if (shade && window->has_shade_func) + meta_window_shade (window, timestamp); + else + meta_window_unshade (window, timestamp); + } + + if (first == display->atom__NET_WM_STATE_FULLSCREEN || + second == display->atom__NET_WM_STATE_FULLSCREEN) + { + gboolean make_fullscreen; + + make_fullscreen = (action == _NET_WM_STATE_ADD || + (action == _NET_WM_STATE_TOGGLE && !window->fullscreen)); + if (make_fullscreen && window->has_fullscreen_func) + meta_window_make_fullscreen (window); + else + meta_window_unmake_fullscreen (window); + } + + if (first == display->atom__NET_WM_STATE_MAXIMIZED_HORZ || + second == display->atom__NET_WM_STATE_MAXIMIZED_HORZ || + first == display->atom__NET_WM_STATE_MAXIMIZED_VERT || + second == display->atom__NET_WM_STATE_MAXIMIZED_VERT) + { + gboolean max; + MetaMaximizeFlags directions = 0; + + max = (action == _NET_WM_STATE_ADD || + (action == _NET_WM_STATE_TOGGLE && + !window->maximized_horizontally)); + + if (first == display->atom__NET_WM_STATE_MAXIMIZED_HORZ || + second == display->atom__NET_WM_STATE_MAXIMIZED_HORZ) + directions |= META_MAXIMIZE_HORIZONTAL; + + if (first == display->atom__NET_WM_STATE_MAXIMIZED_VERT || + second == display->atom__NET_WM_STATE_MAXIMIZED_VERT) + directions |= META_MAXIMIZE_VERTICAL; + + if (max && window->has_maximize_func) + { + if (meta_prefs_get_raise_on_click ()) + meta_window_raise (window); + meta_window_maximize (window, directions); + } + else + { + if (meta_prefs_get_raise_on_click ()) + meta_window_raise (window); + meta_window_unmaximize (window, directions); + } + } + + if (first == display->atom__NET_WM_STATE_MODAL || + second == display->atom__NET_WM_STATE_MODAL) + { + window->wm_state_modal = + (action == _NET_WM_STATE_ADD) || + (action == _NET_WM_STATE_TOGGLE && !window->wm_state_modal); + + meta_window_recalc_window_type (window); + meta_window_queue(window, META_QUEUE_MOVE_RESIZE); + } + + if (first == display->atom__NET_WM_STATE_SKIP_PAGER || + second == display->atom__NET_WM_STATE_SKIP_PAGER) + { + window->wm_state_skip_pager = + (action == _NET_WM_STATE_ADD) || + (action == _NET_WM_STATE_TOGGLE && !window->skip_pager); + + meta_window_recalc_features (window); + meta_window_x11_set_net_wm_state (window); + } + + if (first == display->atom__NET_WM_STATE_SKIP_TASKBAR || + second == display->atom__NET_WM_STATE_SKIP_TASKBAR) + { + window->wm_state_skip_taskbar = + (action == _NET_WM_STATE_ADD) || + (action == _NET_WM_STATE_TOGGLE && !window->skip_taskbar); + + meta_window_recalc_features (window); + meta_window_x11_set_net_wm_state (window); + } + + if (first == display->atom__NET_WM_STATE_ABOVE || + second == display->atom__NET_WM_STATE_ABOVE) + { + if ((action == _NET_WM_STATE_ADD) || + (action == _NET_WM_STATE_TOGGLE && !window->wm_state_demands_attention)) + meta_window_make_above (window); + else + meta_window_unmake_above (window); + } + + if (first == display->atom__NET_WM_STATE_BELOW || + second == display->atom__NET_WM_STATE_BELOW) + { + window->wm_state_below = + (action == _NET_WM_STATE_ADD) || + (action == _NET_WM_STATE_TOGGLE && !window->wm_state_below); + + meta_window_update_layer (window); + meta_window_x11_set_net_wm_state (window); + } + + if (first == display->atom__NET_WM_STATE_DEMANDS_ATTENTION || + second == display->atom__NET_WM_STATE_DEMANDS_ATTENTION) + { + if ((action == _NET_WM_STATE_ADD) || + (action == _NET_WM_STATE_TOGGLE && !window->wm_state_demands_attention)) + meta_window_set_demands_attention (window); + else + meta_window_unset_demands_attention (window); + } + + if (first == display->atom__NET_WM_STATE_STICKY || + second == display->atom__NET_WM_STATE_STICKY) + { + if ((action == _NET_WM_STATE_ADD) || + (action == _NET_WM_STATE_TOGGLE && !window->on_all_workspaces_requested)) + meta_window_stick (window); + else + meta_window_unstick (window); + } + + return TRUE; + } + else if (event->xclient.message_type == + display->atom_WM_CHANGE_STATE) + { + meta_verbose ("WM_CHANGE_STATE client message, state: %ld\n", + event->xclient.data.l[0]); + if (event->xclient.data.l[0] == IconicState && + window->has_minimize_func) + meta_window_minimize (window); + + return TRUE; + } + else if (event->xclient.message_type == + display->atom__NET_WM_MOVERESIZE) + { + int x_root; + int y_root; + int action; + MetaGrabOp op; + int button; + guint32 timestamp; + + /* _NET_WM_MOVERESIZE messages are almost certainly going to come from + * clients when users click on the fake "frame" that the client has, + * thus we should also treat such messages as though it were a + * "frame action". + */ + gboolean const frame_action = TRUE; + + x_root = event->xclient.data.l[0]; + y_root = event->xclient.data.l[1]; + action = event->xclient.data.l[2]; + button = event->xclient.data.l[3]; + + /* FIXME: What a braindead protocol; no timestamp?!? */ + timestamp = meta_display_get_current_time_roundtrip (display); + meta_topic (META_DEBUG_WINDOW_OPS, + "Received _NET_WM_MOVERESIZE message on %s, %d,%d action = %d, button %d\n", + window->desc, + x_root, y_root, action, button); + + op = META_GRAB_OP_NONE; + switch (action) + { + case _NET_WM_MOVERESIZE_SIZE_TOPLEFT: + op = META_GRAB_OP_RESIZING_NW; + break; + case _NET_WM_MOVERESIZE_SIZE_TOP: + op = META_GRAB_OP_RESIZING_N; + break; + case _NET_WM_MOVERESIZE_SIZE_TOPRIGHT: + op = META_GRAB_OP_RESIZING_NE; + break; + case _NET_WM_MOVERESIZE_SIZE_RIGHT: + op = META_GRAB_OP_RESIZING_E; + break; + case _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT: + op = META_GRAB_OP_RESIZING_SE; + break; + case _NET_WM_MOVERESIZE_SIZE_BOTTOM: + op = META_GRAB_OP_RESIZING_S; + break; + case _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT: + op = META_GRAB_OP_RESIZING_SW; + break; + case _NET_WM_MOVERESIZE_SIZE_LEFT: + op = META_GRAB_OP_RESIZING_W; + break; + case _NET_WM_MOVERESIZE_MOVE: + op = META_GRAB_OP_MOVING; + break; + case _NET_WM_MOVERESIZE_SIZE_KEYBOARD: + op = META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN; + break; + case _NET_WM_MOVERESIZE_MOVE_KEYBOARD: + op = META_GRAB_OP_KEYBOARD_MOVING; + break; + case _NET_WM_MOVERESIZE_CANCEL: + /* handled below */ + break; + default: + break; + } + + if (action == _NET_WM_MOVERESIZE_CANCEL) + { + meta_display_end_grab_op (window->display, timestamp); + } + else if (op != META_GRAB_OP_NONE && + ((window->has_move_func && op == META_GRAB_OP_KEYBOARD_MOVING) || + (window->has_resize_func && op == META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN))) + { + meta_window_begin_grab_op (window, op, frame_action, timestamp); + } + else if (op != META_GRAB_OP_NONE && + ((window->has_move_func && op == META_GRAB_OP_MOVING) || + (window->has_resize_func && + (op != META_GRAB_OP_MOVING && + op != META_GRAB_OP_KEYBOARD_MOVING)))) + { + int button_mask; + + meta_topic (META_DEBUG_WINDOW_OPS, + "Beginning move/resize with button = %d\n", button); + meta_display_begin_grab_op (window->display, + window->screen, + window, + op, + FALSE, + frame_action, + button, 0, + timestamp, + x_root, + y_root); + + button_mask = query_pressed_buttons (window); + + if (button == 0) + { + /* + * the button SHOULD already be included in the message + */ + if ((button_mask & (1 << 1)) != 0) + button = 1; + else if ((button_mask & (1 << 2)) != 0) + button = 2; + else if ((button_mask & (1 << 3)) != 0) + button = 3; + + if (button != 0) + window->display->grab_button = button; + else + meta_display_end_grab_op (window->display, + timestamp); + } + else + { + /* There is a potential race here. If the user presses and + * releases their mouse button very fast, it's possible for + * both the ButtonPress and ButtonRelease to be sent to the + * client before it can get a chance to send _NET_WM_MOVERESIZE + * to us. When that happens, we'll become stuck in a grab + * state, as we haven't received a ButtonRelease to cancel the + * grab. + * + * We can solve this by querying after we take the explicit + * pointer grab -- if the button isn't pressed, we cancel the + * drag immediately. + */ + + if ((button_mask & (1 << button)) == 0) + meta_display_end_grab_op (window->display, timestamp); + } + } + + return TRUE; + } + else if (event->xclient.message_type == + display->atom__NET_MOVERESIZE_WINDOW) + { + int gravity; + guint value_mask; + + gravity = (event->xclient.data.l[0] & 0xff); + value_mask = (event->xclient.data.l[0] & 0xf00) >> 8; + /* source = (event->xclient.data.l[0] & 0xf000) >> 12; */ + + if (gravity == 0) + gravity = window->size_hints.win_gravity; + + meta_window_move_resize_request(window, + value_mask, + gravity, + event->xclient.data.l[1], /* x */ + event->xclient.data.l[2], /* y */ + event->xclient.data.l[3], /* width */ + event->xclient.data.l[4]); /* height */ + } + else if (event->xclient.message_type == + display->atom__NET_ACTIVE_WINDOW) + { + MetaClientType source_indication; + guint32 timestamp; + + meta_verbose ("_NET_ACTIVE_WINDOW request for window '%s', activating\n", + window->desc); + + source_indication = event->xclient.data.l[0]; + timestamp = event->xclient.data.l[1]; + + if (source_indication > META_CLIENT_TYPE_MAX_RECOGNIZED) + source_indication = META_CLIENT_TYPE_UNKNOWN; + + if (timestamp == 0) + { + /* Client using older EWMH _NET_ACTIVE_WINDOW without a timestamp */ + meta_warning ("Buggy client sent a _NET_ACTIVE_WINDOW message with a " + "timestamp of 0 for %s\n", + window->desc); + timestamp = meta_display_get_current_time (display); + } + + meta_window_activate_full (window, timestamp, source_indication, NULL); + return TRUE; + } + else if (event->xclient.message_type == + display->atom__NET_WM_FULLSCREEN_MONITORS) + { + gulong top, bottom, left, right; + + meta_verbose ("_NET_WM_FULLSCREEN_MONITORS request for window '%s'\n", + window->desc); + + top = meta_screen_xinerama_index_to_monitor_index (window->screen, + event->xclient.data.l[0]); + bottom = meta_screen_xinerama_index_to_monitor_index (window->screen, + event->xclient.data.l[1]); + left = meta_screen_xinerama_index_to_monitor_index (window->screen, + event->xclient.data.l[2]); + right = meta_screen_xinerama_index_to_monitor_index (window->screen, + event->xclient.data.l[3]); + /* source_indication = event->xclient.data.l[4]; */ + + meta_window_update_fullscreen_monitors (window, top, bottom, left, right); + } + + return FALSE; +} diff --git a/src/core/window-x11.h b/src/core/window-x11.h new file mode 100644 index 000000000..aea216f0e --- /dev/null +++ b/src/core/window-x11.h @@ -0,0 +1,44 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2001 Havoc Pennington + * Copyright (C) 2002 Red Hat, Inc. + * Copyright (C) 2003, 2004 Rob Adams + * Copyright (C) 2004-2006 Elijah Newren + * + * 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_WINDOW_X11_H +#define META_WINDOW_X11_H + +#include +#include + +void meta_window_x11_set_net_wm_state (MetaWindow *window); + +void meta_window_x11_update_role (MetaWindow *window); +void meta_window_x11_update_net_wm_type (MetaWindow *window); +void meta_window_x11_update_opaque_region (MetaWindow *window); +void meta_window_x11_update_input_region (MetaWindow *window); +void meta_window_x11_update_shape_region (MetaWindow *window); + +gboolean meta_window_x11_configure_request (MetaWindow *window, + XEvent *event); +gboolean meta_window_x11_property_notify (MetaWindow *window, + XEvent *event); +gboolean meta_window_x11_client_message (MetaWindow *window, + XEvent *event); + +#endif diff --git a/src/core/window.c b/src/core/window.c index e1455d2ce..db8fd4262 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -28,6 +28,7 @@ #include #include "window-private.h" +#include "window-x11.h" #include "boxes-private.h" #include "edge-resistance.h" #include "util-private.h" @@ -49,7 +50,6 @@ #include "core.h" #include -#include /* For display->resource_mask */ #include #include #include @@ -105,17 +105,12 @@ static void meta_window_set_above (MetaWindow *window, gboolean new_value); static void send_configure_notify (MetaWindow *window); -static gboolean process_property_notify (MetaWindow *window, - XPropertyEvent *event); static void meta_window_force_placement (MetaWindow *window); static void meta_window_show (MetaWindow *window); static void meta_window_hide (MetaWindow *window); -static gboolean meta_window_same_client (MetaWindow *window, - MetaWindow *other_window); - static void meta_window_save_rect (MetaWindow *window); static void save_user_window_placement (MetaWindow *window); static void force_save_user_window_placement (MetaWindow *window); @@ -1031,8 +1026,8 @@ meta_window_new_shared (MetaDisplay *display, if (client_type == META_WINDOW_CLIENT_TYPE_X11) { meta_display_register_x_window (display, &window->xwindow, window); - meta_window_update_shape_region_x11 (window); - meta_window_update_input_region_x11 (window); + meta_window_x11_update_shape_region (window); + meta_window_x11_update_input_region (window); } else meta_display_register_wayland_window (display, window); @@ -2112,105 +2107,8 @@ set_wm_state (MetaWindow *window, static void set_net_wm_state (MetaWindow *window) { - int i; - unsigned long data[13]; - - i = 0; - if (window->shaded) - { - data[i] = window->display->atom__NET_WM_STATE_SHADED; - ++i; - } - if (window->wm_state_modal) - { - data[i] = window->display->atom__NET_WM_STATE_MODAL; - ++i; - } - if (window->skip_pager) - { - data[i] = window->display->atom__NET_WM_STATE_SKIP_PAGER; - ++i; - } - if (window->skip_taskbar) - { - data[i] = window->display->atom__NET_WM_STATE_SKIP_TASKBAR; - ++i; - } - if (window->maximized_horizontally) - { - data[i] = window->display->atom__NET_WM_STATE_MAXIMIZED_HORZ; - ++i; - } - if (window->maximized_vertically) - { - data[i] = window->display->atom__NET_WM_STATE_MAXIMIZED_VERT; - ++i; - } - if (window->fullscreen) - { - data[i] = window->display->atom__NET_WM_STATE_FULLSCREEN; - ++i; - } - if (!meta_window_showing_on_its_workspace (window) || window->shaded) - { - data[i] = window->display->atom__NET_WM_STATE_HIDDEN; - ++i; - } - if (window->wm_state_above) - { - data[i] = window->display->atom__NET_WM_STATE_ABOVE; - ++i; - } - if (window->wm_state_below) - { - data[i] = window->display->atom__NET_WM_STATE_BELOW; - ++i; - } - if (window->wm_state_demands_attention) - { - data[i] = window->display->atom__NET_WM_STATE_DEMANDS_ATTENTION; - ++i; - } - if (window->on_all_workspaces_requested) - { - data[i] = window->display->atom__NET_WM_STATE_STICKY; - ++i; - } - if (meta_window_appears_focused (window)) - { - data[i] = window->display->atom__NET_WM_STATE_FOCUSED; - ++i; - } - - meta_verbose ("Setting _NET_WM_STATE with %d atoms\n", i); - - meta_error_trap_push (window->display); - XChangeProperty (window->display->xdisplay, window->xwindow, - window->display->atom__NET_WM_STATE, - XA_ATOM, - 32, PropModeReplace, (guchar*) data, i); - meta_error_trap_pop (window->display); - - if (window->fullscreen) - { - data[0] = meta_screen_monitor_index_to_xinerama_index (window->screen, - window->fullscreen_monitors[0]); - data[1] = meta_screen_monitor_index_to_xinerama_index (window->screen, - window->fullscreen_monitors[1]); - data[2] = meta_screen_monitor_index_to_xinerama_index (window->screen, - window->fullscreen_monitors[2]); - data[3] = meta_screen_monitor_index_to_xinerama_index (window->screen, - window->fullscreen_monitors[3]); - - meta_verbose ("Setting _NET_WM_FULLSCREEN_MONITORS\n"); - meta_error_trap_push (window->display); - XChangeProperty (window->display->xdisplay, - window->xwindow, - window->display->atom__NET_WM_FULLSCREEN_MONITORS, - XA_CARDINAL, 32, PropModeReplace, - (guchar*) data, 4); - meta_error_trap_pop (window->display); - } + if (window->client_type == META_WINDOW_CLIENT_TYPE_X11) + meta_window_x11_set_net_wm_state (window); } /** @@ -4374,11 +4272,11 @@ unminimize_window_and_all_transient_parents (MetaWindow *window) meta_window_foreach_ancestor (window, unminimize_func, NULL); } -static void -window_activate (MetaWindow *window, - guint32 timestamp, - MetaClientType source_indication, - MetaWorkspace *workspace) +void +meta_window_activate_full (MetaWindow *window, + guint32 timestamp, + MetaClientType source_indication, + MetaWorkspace *workspace) { gboolean can_ignore_outdated_timestamps; meta_topic (META_DEBUG_FOCUS, @@ -4471,7 +4369,7 @@ meta_window_activate (MetaWindow *window, * we were such. If we change the pager behavior later, we could revisit * this and just add extra flags to window_activate. */ - window_activate (window, timestamp, META_CLIENT_TYPE_PAGER, NULL); + meta_window_activate_full (window, timestamp, META_CLIENT_TYPE_PAGER, NULL); } void @@ -4481,11 +4379,7 @@ meta_window_activate_with_workspace (MetaWindow *window, { g_return_if_fail (!window->override_redirect); - /* We're not really a pager, but the behavior we want is the same as if - * we were such. If we change the pager behavior later, we could revisit - * this and just add extra flags to window_activate. - */ - window_activate (window, timestamp, META_CLIENT_TYPE_APPLICATION, workspace); + meta_window_activate_full (window, timestamp, META_CLIENT_TYPE_APPLICATION, workspace); } /* Manually fix all the weirdness explained in the big comment at the @@ -6825,97 +6719,6 @@ meta_window_move_resize_request (MetaWindow *window, save_user_window_placement (window); } -gboolean -meta_window_configure_request (MetaWindow *window, - XEvent *event) -{ - /* Note that x, y is the corner of the window border, - * and width, height is the size of the window inside - * its border, but that we always deny border requests - * and give windows a border of 0. But we save the - * requested border here. - */ - if (event->xconfigurerequest.value_mask & CWBorderWidth) - window->border_width = event->xconfigurerequest.border_width; - - meta_window_move_resize_request(window, - event->xconfigurerequest.value_mask, - window->size_hints.win_gravity, - event->xconfigurerequest.x, - event->xconfigurerequest.y, - event->xconfigurerequest.width, - event->xconfigurerequest.height); - - /* Handle stacking. We only handle raises/lowers, mostly because - * stack.c really can't deal with anything else. I guess we'll fix - * that if a client turns up that really requires it. Only a very - * few clients even require the raise/lower (and in fact all client - * attempts to deal with stacking order are essentially broken, - * since they have no idea what other clients are involved or how - * the stack looks). - * - * I'm pretty sure no interesting client uses TopIf, BottomIf, or - * Opposite anyway, so the only possible missing thing is - * Above/Below with a sibling set. For now we just pretend there's - * never a sibling set and always do the full raise/lower instead of - * the raise-just-above/below-sibling. - */ - if (event->xconfigurerequest.value_mask & CWStackMode) - { - MetaWindow *active_window; - active_window = window->display->focus_window; - if (meta_prefs_get_disable_workarounds ()) - { - meta_topic (META_DEBUG_STACK, - "%s sent an xconfigure stacking request; this is " - "broken behavior and the request is being ignored.\n", - window->desc); - } - else if (active_window && - !meta_window_same_application (window, active_window) && - !meta_window_same_client (window, active_window) && - XSERVER_TIME_IS_BEFORE (window->net_wm_user_time, - active_window->net_wm_user_time)) - { - meta_topic (META_DEBUG_STACK, - "Ignoring xconfigure stacking request from %s (with " - "user_time %u); currently active application is %s (with " - "user_time %u).\n", - window->desc, - window->net_wm_user_time, - active_window->desc, - active_window->net_wm_user_time); - if (event->xconfigurerequest.detail == Above) - meta_window_set_demands_attention(window); - } - else - { - switch (event->xconfigurerequest.detail) - { - case Above: - meta_window_raise (window); - break; - case Below: - meta_window_lower (window); - break; - case TopIf: - case BottomIf: - case Opposite: - break; - } - } - } - - return TRUE; -} - -gboolean -meta_window_property_notify (MetaWindow *window, - XEvent *event) -{ - return process_property_notify (window, &event->xproperty); -} - /* * Move window to the requested workspace; append controls whether new WS * should be created if one does not exist. @@ -6953,531 +6756,6 @@ meta_window_change_workspace_by_index (MetaWindow *window, } } -#define _NET_WM_MOVERESIZE_SIZE_TOPLEFT 0 -#define _NET_WM_MOVERESIZE_SIZE_TOP 1 -#define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT 2 -#define _NET_WM_MOVERESIZE_SIZE_RIGHT 3 -#define _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT 4 -#define _NET_WM_MOVERESIZE_SIZE_BOTTOM 5 -#define _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT 6 -#define _NET_WM_MOVERESIZE_SIZE_LEFT 7 -#define _NET_WM_MOVERESIZE_MOVE 8 -#define _NET_WM_MOVERESIZE_SIZE_KEYBOARD 9 -#define _NET_WM_MOVERESIZE_MOVE_KEYBOARD 10 -#define _NET_WM_MOVERESIZE_CANCEL 11 - -static int -query_pressed_buttons (MetaWindow *window) -{ - double x, y, query_root_x, query_root_y; - Window root, child; - XIButtonState buttons; - XIModifierState mods; - XIGroupState group; - int button = 0; - - meta_error_trap_push (window->display); - XIQueryPointer (window->display->xdisplay, - META_VIRTUAL_CORE_POINTER_ID, - window->xwindow, - &root, &child, - &query_root_x, &query_root_y, - &x, &y, - &buttons, &mods, &group); - - if (meta_error_trap_pop_with_return (window->display) != Success) - goto out; - - if (XIMaskIsSet (buttons.mask, Button1)) - button |= 1 << 1; - if (XIMaskIsSet (buttons.mask, Button2)) - button |= 1 << 2; - if (XIMaskIsSet (buttons.mask, Button3)) - button |= 1 << 3; - - free (buttons.mask); - - out: - return button; -} - -gboolean -meta_window_client_message (MetaWindow *window, - XEvent *event) -{ - MetaDisplay *display; - - display = window->display; - - if (window->override_redirect) - { - /* Don't warn here: we could warn on any of the messages below, - * but we might also receive other client messages that are - * part of protocols we don't know anything about. So, silently - * ignoring is simplest. - */ - return FALSE; - } - - if (event->xclient.message_type == - display->atom__NET_CLOSE_WINDOW) - { - guint32 timestamp; - - if (event->xclient.data.l[0] != 0) - timestamp = event->xclient.data.l[0]; - else - { - meta_warning ("Receiving a NET_CLOSE_WINDOW message for %s without " - "a timestamp! This means some buggy (outdated) " - "application is on the loose!\n", - window->desc); - timestamp = meta_display_get_current_time (window->display); - } - - meta_window_delete (window, timestamp); - - return TRUE; - } - else if (event->xclient.message_type == - display->atom__NET_WM_DESKTOP) - { - int space; - MetaWorkspace *workspace; - - space = event->xclient.data.l[0]; - - meta_verbose ("Request to move %s to workspace %d\n", - window->desc, space); - - workspace = - meta_screen_get_workspace_by_index (window->screen, - space); - - if (workspace) - { - if (window->on_all_workspaces_requested) - meta_window_unstick (window); - meta_window_change_workspace (window, workspace); - } - else if (space == (int) 0xFFFFFFFF) - { - meta_window_stick (window); - } - else - { - meta_verbose ("No such workspace %d for screen\n", space); - } - - meta_verbose ("Window %s now on_all_workspaces = %d\n", - window->desc, window->on_all_workspaces); - - return TRUE; - } - else if (event->xclient.message_type == - display->atom__NET_WM_STATE) - { - gulong action; - Atom first; - Atom second; - - action = event->xclient.data.l[0]; - first = event->xclient.data.l[1]; - second = event->xclient.data.l[2]; - - if (meta_is_verbose ()) - { - char *str1; - char *str2; - - meta_error_trap_push_with_return (display); - str1 = XGetAtomName (display->xdisplay, first); - if (meta_error_trap_pop_with_return (display) != Success) - str1 = NULL; - - meta_error_trap_push_with_return (display); - str2 = XGetAtomName (display->xdisplay, second); - if (meta_error_trap_pop_with_return (display) != Success) - str2 = NULL; - - meta_verbose ("Request to change _NET_WM_STATE action %lu atom1: %s atom2: %s\n", - action, - str1 ? str1 : "(unknown)", - str2 ? str2 : "(unknown)"); - - meta_XFree (str1); - meta_XFree (str2); - } - - if (first == display->atom__NET_WM_STATE_SHADED || - second == display->atom__NET_WM_STATE_SHADED) - { - gboolean shade; - guint32 timestamp; - - /* Stupid protocol has no timestamp; of course, shading - * sucks anyway so who really cares that we're forced to do - * a roundtrip here? - */ - timestamp = meta_display_get_current_time_roundtrip (window->display); - - shade = (action == _NET_WM_STATE_ADD || - (action == _NET_WM_STATE_TOGGLE && !window->shaded)); - if (shade && window->has_shade_func) - meta_window_shade (window, timestamp); - else - meta_window_unshade (window, timestamp); - } - - if (first == display->atom__NET_WM_STATE_FULLSCREEN || - second == display->atom__NET_WM_STATE_FULLSCREEN) - { - gboolean make_fullscreen; - - make_fullscreen = (action == _NET_WM_STATE_ADD || - (action == _NET_WM_STATE_TOGGLE && !window->fullscreen)); - if (make_fullscreen && window->has_fullscreen_func) - meta_window_make_fullscreen (window); - else - meta_window_unmake_fullscreen (window); - } - - if (first == display->atom__NET_WM_STATE_MAXIMIZED_HORZ || - second == display->atom__NET_WM_STATE_MAXIMIZED_HORZ || - first == display->atom__NET_WM_STATE_MAXIMIZED_VERT || - second == display->atom__NET_WM_STATE_MAXIMIZED_VERT) - { - gboolean max; - MetaMaximizeFlags directions = 0; - - max = (action == _NET_WM_STATE_ADD || - (action == _NET_WM_STATE_TOGGLE && - !window->maximized_horizontally)); - - if (first == display->atom__NET_WM_STATE_MAXIMIZED_HORZ || - second == display->atom__NET_WM_STATE_MAXIMIZED_HORZ) - directions |= META_MAXIMIZE_HORIZONTAL; - - if (first == display->atom__NET_WM_STATE_MAXIMIZED_VERT || - second == display->atom__NET_WM_STATE_MAXIMIZED_VERT) - directions |= META_MAXIMIZE_VERTICAL; - - if (max && window->has_maximize_func) - { - if (meta_prefs_get_raise_on_click ()) - meta_window_raise (window); - meta_window_maximize (window, directions); - } - else - { - if (meta_prefs_get_raise_on_click ()) - meta_window_raise (window); - meta_window_unmaximize (window, directions); - } - } - - if (first == display->atom__NET_WM_STATE_MODAL || - second == display->atom__NET_WM_STATE_MODAL) - { - window->wm_state_modal = - (action == _NET_WM_STATE_ADD) || - (action == _NET_WM_STATE_TOGGLE && !window->wm_state_modal); - - meta_window_recalc_window_type (window); - meta_window_queue(window, META_QUEUE_MOVE_RESIZE); - } - - if (first == display->atom__NET_WM_STATE_SKIP_PAGER || - second == display->atom__NET_WM_STATE_SKIP_PAGER) - { - window->wm_state_skip_pager = - (action == _NET_WM_STATE_ADD) || - (action == _NET_WM_STATE_TOGGLE && !window->skip_pager); - - meta_window_recalc_window_features (window); - set_net_wm_state (window); - } - - if (first == display->atom__NET_WM_STATE_SKIP_TASKBAR || - second == display->atom__NET_WM_STATE_SKIP_TASKBAR) - { - window->wm_state_skip_taskbar = - (action == _NET_WM_STATE_ADD) || - (action == _NET_WM_STATE_TOGGLE && !window->skip_taskbar); - - meta_window_recalc_window_features (window); - set_net_wm_state (window); - } - - if (first == display->atom__NET_WM_STATE_ABOVE || - second == display->atom__NET_WM_STATE_ABOVE) - { - meta_window_set_above(window, - (action == _NET_WM_STATE_ADD) || - (action == _NET_WM_STATE_TOGGLE && !window->wm_state_above)); - } - - if (first == display->atom__NET_WM_STATE_BELOW || - second == display->atom__NET_WM_STATE_BELOW) - { - window->wm_state_below = - (action == _NET_WM_STATE_ADD) || - (action == _NET_WM_STATE_TOGGLE && !window->wm_state_below); - - meta_window_update_layer (window); - set_net_wm_state (window); - } - - if (first == display->atom__NET_WM_STATE_DEMANDS_ATTENTION || - second == display->atom__NET_WM_STATE_DEMANDS_ATTENTION) - { - if ((action == _NET_WM_STATE_ADD) || - (action == _NET_WM_STATE_TOGGLE && !window->wm_state_demands_attention)) - meta_window_set_demands_attention (window); - else - meta_window_unset_demands_attention (window); - } - - if (first == display->atom__NET_WM_STATE_STICKY || - second == display->atom__NET_WM_STATE_STICKY) - { - if ((action == _NET_WM_STATE_ADD) || - (action == _NET_WM_STATE_TOGGLE && !window->on_all_workspaces_requested)) - meta_window_stick (window); - else - meta_window_unstick (window); - } - - return TRUE; - } - else if (event->xclient.message_type == - display->atom_WM_CHANGE_STATE) - { - meta_verbose ("WM_CHANGE_STATE client message, state: %ld\n", - event->xclient.data.l[0]); - if (event->xclient.data.l[0] == IconicState && - window->has_minimize_func) - meta_window_minimize (window); - - return TRUE; - } - else if (event->xclient.message_type == - display->atom__NET_WM_MOVERESIZE) - { - int x_root; - int y_root; - int action; - MetaGrabOp op; - int button; - guint32 timestamp; - - /* _NET_WM_MOVERESIZE messages are almost certainly going to come from - * clients when users click on the fake "frame" that the client has, - * thus we should also treat such messages as though it were a - * "frame action". - */ - gboolean const frame_action = TRUE; - - x_root = event->xclient.data.l[0]; - y_root = event->xclient.data.l[1]; - action = event->xclient.data.l[2]; - button = event->xclient.data.l[3]; - - /* FIXME: What a braindead protocol; no timestamp?!? */ - timestamp = meta_display_get_current_time_roundtrip (display); - meta_topic (META_DEBUG_WINDOW_OPS, - "Received _NET_WM_MOVERESIZE message on %s, %d,%d action = %d, button %d\n", - window->desc, - x_root, y_root, action, button); - - op = META_GRAB_OP_NONE; - switch (action) - { - case _NET_WM_MOVERESIZE_SIZE_TOPLEFT: - op = META_GRAB_OP_RESIZING_NW; - break; - case _NET_WM_MOVERESIZE_SIZE_TOP: - op = META_GRAB_OP_RESIZING_N; - break; - case _NET_WM_MOVERESIZE_SIZE_TOPRIGHT: - op = META_GRAB_OP_RESIZING_NE; - break; - case _NET_WM_MOVERESIZE_SIZE_RIGHT: - op = META_GRAB_OP_RESIZING_E; - break; - case _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT: - op = META_GRAB_OP_RESIZING_SE; - break; - case _NET_WM_MOVERESIZE_SIZE_BOTTOM: - op = META_GRAB_OP_RESIZING_S; - break; - case _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT: - op = META_GRAB_OP_RESIZING_SW; - break; - case _NET_WM_MOVERESIZE_SIZE_LEFT: - op = META_GRAB_OP_RESIZING_W; - break; - case _NET_WM_MOVERESIZE_MOVE: - op = META_GRAB_OP_MOVING; - break; - case _NET_WM_MOVERESIZE_SIZE_KEYBOARD: - op = META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN; - break; - case _NET_WM_MOVERESIZE_MOVE_KEYBOARD: - op = META_GRAB_OP_KEYBOARD_MOVING; - break; - case _NET_WM_MOVERESIZE_CANCEL: - /* handled below */ - break; - default: - break; - } - - if (action == _NET_WM_MOVERESIZE_CANCEL) - { - meta_display_end_grab_op (window->display, timestamp); - } - else if (op != META_GRAB_OP_NONE && - ((window->has_move_func && op == META_GRAB_OP_KEYBOARD_MOVING) || - (window->has_resize_func && op == META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN))) - { - meta_window_begin_grab_op (window, op, frame_action, timestamp); - } - else if (op != META_GRAB_OP_NONE && - ((window->has_move_func && op == META_GRAB_OP_MOVING) || - (window->has_resize_func && - (op != META_GRAB_OP_MOVING && - op != META_GRAB_OP_KEYBOARD_MOVING)))) - { - int button_mask; - - meta_topic (META_DEBUG_WINDOW_OPS, - "Beginning move/resize with button = %d\n", button); - meta_display_begin_grab_op (window->display, - window->screen, - window, - op, - FALSE, - frame_action, - button, 0, - timestamp, - x_root, - y_root); - - button_mask = query_pressed_buttons (window); - - if (button == 0) - { - /* - * the button SHOULD already be included in the message - */ - if ((button_mask & (1 << 1)) != 0) - button = 1; - else if ((button_mask & (1 << 2)) != 0) - button = 2; - else if ((button_mask & (1 << 3)) != 0) - button = 3; - - if (button != 0) - window->display->grab_button = button; - else - meta_display_end_grab_op (window->display, - timestamp); - } - else - { - /* There is a potential race here. If the user presses and - * releases their mouse button very fast, it's possible for - * both the ButtonPress and ButtonRelease to be sent to the - * client before it can get a chance to send _NET_WM_MOVERESIZE - * to us. When that happens, we'll become stuck in a grab - * state, as we haven't received a ButtonRelease to cancel the - * grab. - * - * We can solve this by querying after we take the explicit - * pointer grab -- if the button isn't pressed, we cancel the - * drag immediately. - */ - - if ((button_mask & (1 << button)) == 0) - meta_display_end_grab_op (window->display, timestamp); - } - } - - return TRUE; - } - else if (event->xclient.message_type == - display->atom__NET_MOVERESIZE_WINDOW) - { - int gravity; - guint value_mask; - - gravity = (event->xclient.data.l[0] & 0xff); - value_mask = (event->xclient.data.l[0] & 0xf00) >> 8; - /* source = (event->xclient.data.l[0] & 0xf000) >> 12; */ - - if (gravity == 0) - gravity = window->size_hints.win_gravity; - - meta_window_move_resize_request(window, - value_mask, - gravity, - event->xclient.data.l[1], /* x */ - event->xclient.data.l[2], /* y */ - event->xclient.data.l[3], /* width */ - event->xclient.data.l[4]); /* height */ - } - else if (event->xclient.message_type == - display->atom__NET_ACTIVE_WINDOW) - { - MetaClientType source_indication; - guint32 timestamp; - - meta_verbose ("_NET_ACTIVE_WINDOW request for window '%s', activating\n", - window->desc); - - source_indication = event->xclient.data.l[0]; - timestamp = event->xclient.data.l[1]; - - if (source_indication > META_CLIENT_TYPE_MAX_RECOGNIZED) - source_indication = META_CLIENT_TYPE_UNKNOWN; - - if (timestamp == 0) - { - /* Client using older EWMH _NET_ACTIVE_WINDOW without a timestamp */ - meta_warning ("Buggy client sent a _NET_ACTIVE_WINDOW message with a " - "timestamp of 0 for %s\n", - window->desc); - timestamp = meta_display_get_current_time (display); - } - - window_activate (window, timestamp, source_indication, NULL); - return TRUE; - } - else if (event->xclient.message_type == - display->atom__NET_WM_FULLSCREEN_MONITORS) - { - gulong top, bottom, left, right; - - meta_verbose ("_NET_WM_FULLSCREEN_MONITORS request for window '%s'\n", - window->desc); - - top = meta_screen_xinerama_index_to_monitor_index (window->screen, - event->xclient.data.l[0]); - bottom = meta_screen_xinerama_index_to_monitor_index (window->screen, - event->xclient.data.l[1]); - left = meta_screen_xinerama_index_to_monitor_index (window->screen, - event->xclient.data.l[2]); - right = meta_screen_xinerama_index_to_monitor_index (window->screen, - event->xclient.data.l[3]); - /* source_indication = event->xclient.data.l[4]; */ - - meta_window_update_fullscreen_monitors (window, top, bottom, left, right); - } - - return FALSE; -} - static void meta_window_appears_focused_changed (MetaWindow *window) { @@ -7640,33 +6918,6 @@ meta_window_set_focused_internal (MetaWindow *window, } } -static gboolean -process_property_notify (MetaWindow *window, - XPropertyEvent *event) -{ - Window xid = window->xwindow; - - if (meta_is_verbose ()) /* avoid looking up the name if we don't have to */ - { - char *property_name = XGetAtomName (window->display->xdisplay, - event->atom); - - meta_verbose ("Property notify on %s for %s\n", - window->desc, property_name); - XFree (property_name); - } - - if (event->atom == window->display->atom__NET_WM_USER_TIME && - window->user_time_window) - { - xid = window->user_time_window; - } - - meta_window_reload_property_from_xwindow (window, xid, event->atom, FALSE); - - return TRUE; -} - static void send_configure_notify (MetaWindow *window) { @@ -7872,347 +7123,6 @@ update_sm_hints (MetaWindow *window) window->sm_client_id ? window->sm_client_id : "none"); } -void -meta_window_update_role (MetaWindow *window) -{ - char *str; - - g_return_if_fail (!window->override_redirect); - - if (window->role) - g_free (window->role); - window->role = NULL; - - if (meta_prop_get_latin1_string (window->display, window->xwindow, - window->display->atom_WM_WINDOW_ROLE, - &str)) - { - window->role = g_strdup (str); - meta_XFree (str); - } - - meta_verbose ("Updated role of %s to '%s'\n", - window->desc, window->role ? window->role : "null"); -} - -void -meta_window_update_net_wm_type (MetaWindow *window) -{ - int n_atoms; - Atom *atoms; - int i; - - window->type_atom = None; - n_atoms = 0; - atoms = NULL; - - meta_prop_get_atom_list (window->display, window->xwindow, - window->display->atom__NET_WM_WINDOW_TYPE, - &atoms, &n_atoms); - - i = 0; - while (i < n_atoms) - { - /* We break as soon as we find one we recognize, - * supposed to prefer those near the front of the list - */ - if (atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_DESKTOP || - atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_DOCK || - atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_TOOLBAR || - atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_MENU || - atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_UTILITY || - atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_SPLASH || - atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_DIALOG || - atoms[i] == - window->display->atom__NET_WM_WINDOW_TYPE_DROPDOWN_MENU || - atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_POPUP_MENU || - atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_TOOLTIP || - atoms[i] == - window->display->atom__NET_WM_WINDOW_TYPE_NOTIFICATION || - atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_COMBO || - atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_DND || - atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_NORMAL) - { - window->type_atom = atoms[i]; - break; - } - - ++i; - } - - meta_XFree (atoms); - - if (meta_is_verbose ()) - { - char *str; - - str = NULL; - if (window->type_atom != None) - { - meta_error_trap_push (window->display); - str = XGetAtomName (window->display->xdisplay, window->type_atom); - meta_error_trap_pop (window->display); - } - - meta_verbose ("Window %s type atom %s\n", window->desc, - str ? str : "(none)"); - - if (str) - meta_XFree (str); - } - - meta_window_recalc_window_type (window); -} - -static void -meta_window_set_opaque_region (MetaWindow *window, - cairo_region_t *region) -{ - g_clear_pointer (&window->opaque_region, cairo_region_destroy); - - if (region != NULL) - window->opaque_region = cairo_region_reference (region); - - if (window->display->compositor) - meta_compositor_window_shape_changed (window->display->compositor, window); -} - -void -meta_window_update_opaque_region_x11 (MetaWindow *window) -{ - cairo_region_t *opaque_region = NULL; - gulong *region = NULL; - int nitems; - - if (meta_prop_get_cardinal_list (window->display, - window->xwindow, - window->display->atom__NET_WM_OPAQUE_REGION, - ®ion, &nitems)) - { - cairo_rectangle_int_t *rects; - int i, rect_index, nrects; - - if (nitems % 4 != 0) - { - meta_verbose ("_NET_WM_OPAQUE_REGION does not have a list of 4-tuples."); - goto out; - } - - /* empty region */ - if (nitems == 0) - goto out; - - nrects = nitems / 4; - - rects = g_new (cairo_rectangle_int_t, nrects); - - rect_index = 0; - i = 0; - while (i < nitems) - { - cairo_rectangle_int_t *rect = &rects[rect_index]; - - rect->x = region[i++]; - rect->y = region[i++]; - rect->width = region[i++]; - rect->height = region[i++]; - - rect_index++; - } - - opaque_region = cairo_region_create_rectangles (rects, nrects); - - g_free (rects); - } - - out: - meta_XFree (region); - - meta_window_set_opaque_region (window, opaque_region); - cairo_region_destroy (opaque_region); -} - -static cairo_region_t * -region_create_from_x_rectangles (const XRectangle *rects, - int n_rects) -{ - int i; - cairo_rectangle_int_t *cairo_rects = g_newa (cairo_rectangle_int_t, n_rects); - - for (i = 0; i < n_rects; i ++) - { - cairo_rects[i].x = rects[i].x; - cairo_rects[i].y = rects[i].y; - cairo_rects[i].width = rects[i].width; - cairo_rects[i].height = rects[i].height; - } - - return cairo_region_create_rectangles (cairo_rects, n_rects); -} - -static void -meta_window_set_input_region (MetaWindow *window, - cairo_region_t *region) -{ - g_clear_pointer (&window->input_region, cairo_region_destroy); - - if (region != NULL) - window->input_region = cairo_region_reference (region); - - if (window->display->compositor) - meta_compositor_window_shape_changed (window->display->compositor, window); -} - -void -meta_window_update_input_region_x11 (MetaWindow *window) -{ - cairo_region_t *region = NULL; - -#ifdef HAVE_SHAPE - if (META_DISPLAY_HAS_SHAPE (window->display)) - { - /* Translate the set of XShape rectangles that we - * get from the X server to a cairo_region. */ - XRectangle *rects = NULL; - int n_rects, ordering; - - int x_bounding, y_bounding, x_clip, y_clip; - unsigned w_bounding, h_bounding, w_clip, h_clip; - int bounding_shaped, clip_shaped; - - meta_error_trap_push (window->display); - XShapeQueryExtents (window->display->xdisplay, window->xwindow, - &bounding_shaped, &x_bounding, &y_bounding, - &w_bounding, &h_bounding, - &clip_shaped, &x_clip, &y_clip, - &w_clip, &h_clip); - - rects = XShapeGetRectangles (window->display->xdisplay, - window->xwindow, - ShapeInput, - &n_rects, - &ordering); - meta_error_trap_pop (window->display); - - /* XXX: The x shape extension doesn't provide a way to only test if an - * input shape has been specified, so we have to query and throw away the - * rectangles. */ - if (rects) - { - if (n_rects > 1 || - (n_rects == 1 && - (rects[0].x != x_bounding || - rects[1].y != y_bounding || - rects[2].width != w_bounding || - rects[3].height != h_bounding))) - region = region_create_from_x_rectangles (rects, n_rects); - - XFree (rects); - } - } -#endif /* HAVE_SHAPE */ - - if (region != NULL) - { - cairo_rectangle_int_t client_area; - - client_area.x = 0; - client_area.y = 0; - client_area.width = window->rect.width; - client_area.height = window->rect.height; - - /* The shape we get back from the client may have coordinates - * outside of the frame. The X SHAPE Extension requires that - * the overall shape the client provides never exceeds the - * "bounding rectangle" of the window -- the shape that the - * window would have gotten if it was unshaped. In our case, - * this is simply the client area. - */ - cairo_region_intersect_rectangle (region, &client_area); - } - - meta_window_set_input_region (window, region); - cairo_region_destroy (region); -} - -static void -meta_window_set_shape_region (MetaWindow *window, - cairo_region_t *region) -{ - g_clear_pointer (&window->shape_region, cairo_region_destroy); - - if (region != NULL) - window->shape_region = cairo_region_reference (region); - - if (window->display->compositor) - meta_compositor_window_shape_changed (window->display->compositor, window); -} - -void -meta_window_update_shape_region_x11 (MetaWindow *window) -{ - cairo_region_t *region = NULL; - -#ifdef HAVE_SHAPE - if (META_DISPLAY_HAS_SHAPE (window->display)) - { - /* Translate the set of XShape rectangles that we - * get from the X server to a cairo_region. */ - XRectangle *rects = NULL; - int n_rects, ordering; - - int x_bounding, y_bounding, x_clip, y_clip; - unsigned w_bounding, h_bounding, w_clip, h_clip; - int bounding_shaped, clip_shaped; - - meta_error_trap_push (window->display); - XShapeQueryExtents (window->display->xdisplay, window->xwindow, - &bounding_shaped, &x_bounding, &y_bounding, - &w_bounding, &h_bounding, - &clip_shaped, &x_clip, &y_clip, - &w_clip, &h_clip); - - if (bounding_shaped) - { - rects = XShapeGetRectangles (window->display->xdisplay, - window->xwindow, - ShapeBounding, - &n_rects, - &ordering); - } - meta_error_trap_pop (window->display); - - if (rects) - { - region = region_create_from_x_rectangles (rects, n_rects); - XFree (rects); - } - } -#endif /* HAVE_SHAPE */ - - if (region != NULL) - { - cairo_rectangle_int_t client_area; - - client_area.x = 0; - client_area.y = 0; - client_area.width = window->rect.width; - client_area.height = window->rect.height; - - /* The shape we get back from the client may have coordinates - * outside of the frame. The X SHAPE Extension requires that - * the overall shape the client provides never exceeds the - * "bounding rectangle" of the window -- the shape that the - * window would have gotten if it was unshaped. In our case, - * this is simply the client area. - */ - cairo_region_intersect_rectangle (region, &client_area); - } - - meta_window_set_shape_region (window, region); - cairo_region_destroy (region); -} - static void redraw_icon (MetaWindow *window) { @@ -10483,23 +9393,6 @@ meta_window_same_application (MetaWindow *window, group==other_group; } -/* Generally meta_window_same_application() is a better idea - * of "sameness", since it handles the case where multiple apps - * want to look like the same app or the same app wants to look - * like multiple apps, but in the case of workarounds for legacy - * applications (which likely aren't setting the group properly - * anyways), it may be desirable to check this as well. - */ -static gboolean -meta_window_same_client (MetaWindow *window, - MetaWindow *other_window) -{ - int resource_mask = window->display->xdisplay->resource_mask; - - return ((window->xwindow & ~resource_mask) == - (other_window->xwindow & ~resource_mask)); -} - void meta_window_refresh_resize_popup (MetaWindow *window) { From 14db280fabe541f5ae7b3d10fc4c6df43ae07c4b Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sat, 1 Feb 2014 18:58:58 -0500 Subject: [PATCH 443/889] window: Fix build The proper function name is "meta_window_recalc_features" --- src/core/window.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/core/window.c b/src/core/window.c index db8fd4262..cb47acddf 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -229,7 +229,7 @@ prefs_changed_callback (MetaPreference pref, window->type == META_WINDOW_MODAL_DIALOG) { window->attached = meta_window_should_attach_to_parent (window); - meta_window_recalc_window_features (window); + meta_window_recalc_features (window); meta_window_queue (window, META_QUEUE_MOVE_RESIZE); } } @@ -1112,7 +1112,7 @@ meta_window_new_shared (MetaDisplay *display, window->attached = meta_window_should_attach_to_parent (window); if (window->attached) - meta_window_recalc_window_features (window); + meta_window_recalc_features (window); if (window->decorated) meta_window_ensure_frame (window); @@ -3524,7 +3524,7 @@ meta_window_maximize_internal (MetaWindow *window, if (maximize_horizontally || maximize_vertically) window->force_save_user_rect = FALSE; - meta_window_recalc_window_features (window); + meta_window_recalc_features (window); set_net_wm_state (window); g_object_freeze_notify (G_OBJECT (window)); @@ -3914,7 +3914,7 @@ meta_window_unmaximize_internal (MetaWindow *window, window->maximized_vertically = window->maximized_vertically && !unmaximize_vertically; - /* recalc_window_features() will eventually clear the cached frame + /* recalc_features() will eventually clear the cached frame * extents, but we need the correct frame extents in the code below, * so invalidate the old frame extents manually up front. */ @@ -4008,7 +4008,7 @@ meta_window_unmaximize_internal (MetaWindow *window, window->display->grab_anchor_window_pos = window->user_rect; } - meta_window_recalc_window_features (window); + meta_window_recalc_features (window); set_net_wm_state (window); } @@ -4112,7 +4112,7 @@ meta_window_make_fullscreen_internal (MetaWindow *window) meta_window_raise (window); meta_stack_thaw (window->screen->stack); - meta_window_recalc_window_features (window); + meta_window_recalc_features (window); set_net_wm_state (window); /* For the auto-minimize feature, if we fail to get focus */ @@ -4158,7 +4158,7 @@ meta_window_unmake_fullscreen (MetaWindow *window) /* Need to update window->has_resize_func before we move_resize() */ - meta_window_recalc_window_features (window); + meta_window_recalc_features (window); set_net_wm_state (window); meta_window_move_resize (window, @@ -4832,7 +4832,7 @@ meta_window_update_monitor (MetaWindow *window) /* If we're changing monitors, we need to update the has_maximize_func flag, * as the working area has changed. */ - meta_window_recalc_window_features (window); + meta_window_recalc_features (window); } } @@ -7537,7 +7537,7 @@ meta_window_type_changed (MetaWindow *window) GObject *object = G_OBJECT (window); window->attached = meta_window_should_attach_to_parent (window); - meta_window_recalc_window_features (window); + meta_window_recalc_features (window); if (!window->override_redirect) set_net_wm_state (window); @@ -7852,10 +7852,9 @@ meta_window_recalc_features (MetaWindow *window) g_object_notify (G_OBJECT (window), "skip-taskbar"); /* FIXME: - * Lame workaround for recalc_window_features - * being used overzealously. The fix is to - * only recalc_window_features when something - * has actually changed. + * Lame workaround for recalc_features being used overzealously. + * The fix is to only recalc_features when something has + * actually changed. */ if (window->constructing || old_has_close_func != window->has_close_func || From 91b789c707136677e9d58be99bae7a3cc8d7d36a Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sat, 1 Feb 2014 18:43:33 -0500 Subject: [PATCH 444/889] window: Split out logic for determining whether an X window is ours --- src/core/window.c | 54 +++++++++++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/src/core/window.c b/src/core/window.c index cb47acddf..a58dc7fc6 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -771,6 +771,35 @@ maybe_filter_xwindow (MetaDisplay *display, return filtered; } +static gboolean +is_our_xwindow (MetaDisplay *display, + MetaScreen *screen + Window xwindow, + XWindowAttributes *attrs) +{ + /* A black list of override redirect windows that we don't need to manage: */ + if (attrs->override_redirect && + (xwindow == screen->no_focus_window || + xwindow == screen->flash_window || + xwindow == screen->wm_sn_selection_window || + attrs->class == InputOnly || + /* any windows created via meta_create_offscreen_window: */ + (attrs->x == -100 && attrs->y == -100 + && attrs->width == 1 && attrs->height == 1) || + xwindow == screen->wm_cm_selection_window || + xwindow == screen->guard_window || + (display->compositor && + xwindow == XCompositeGetOverlayWindow (display->xdisplay, + screen->xroot) + ) + ) + ) { + return TRUE; + } + + return FALSE; +} + gboolean meta_window_should_attach_to_parent (MetaWindow *window) { @@ -1449,26 +1478,11 @@ meta_window_new (MetaDisplay *display, g_assert (screen); - /* A black list of override redirect windows that we don't need to manage: */ - if (attrs.override_redirect && - (xwindow == screen->no_focus_window || - xwindow == screen->flash_window || - xwindow == screen->wm_sn_selection_window || - attrs.class == InputOnly || - /* any windows created via meta_create_offscreen_window: */ - (attrs.x == -100 && attrs.y == -100 - && attrs.width == 1 && attrs.height == 1) || - xwindow == screen->wm_cm_selection_window || - xwindow == screen->guard_window || - (display->compositor && - xwindow == XCompositeGetOverlayWindow (display->xdisplay, - screen->xroot) - ) - ) - ) { - meta_verbose ("Not managing our own windows\n"); - goto error; - } + if (is_our_xwindow (display, screen, xwindow, &attrs)) + { + meta_verbose ("Not managing our own windows\n"); + goto error; + } if (maybe_filter_xwindow (display, xwindow, must_be_viewable, &attrs)) { From f166240225b6ab110b091520103d0370d51899ac Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sat, 1 Feb 2014 18:45:27 -0500 Subject: [PATCH 445/889] window: Clean up is_our_xwindow --- src/core/window.c | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/src/core/window.c b/src/core/window.c index a58dc7fc6..69f28877c 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -777,25 +777,27 @@ is_our_xwindow (MetaDisplay *display, Window xwindow, XWindowAttributes *attrs) { - /* A black list of override redirect windows that we don't need to manage: */ - if (attrs->override_redirect && - (xwindow == screen->no_focus_window || - xwindow == screen->flash_window || - xwindow == screen->wm_sn_selection_window || - attrs->class == InputOnly || - /* any windows created via meta_create_offscreen_window: */ - (attrs->x == -100 && attrs->y == -100 - && attrs->width == 1 && attrs->height == 1) || - xwindow == screen->wm_cm_selection_window || - xwindow == screen->guard_window || - (display->compositor && - xwindow == XCompositeGetOverlayWindow (display->xdisplay, - screen->xroot) - ) - ) - ) { + if (xwindow == screen->no_focus_window) + return TRUE; + + if (xwindow == screen->flash_window) + return TRUE; + + if (xwindow == screen->wm_sn_selection_window) + return TRUE; + + if (xwindow == screen->wm_cm_selection_window) + return TRUE; + + if (xwindow == screen->guard_window) + return TRUE; + + if (display->compositor && xwindow == XCompositeGetOverlayWindow (display->xdisplay, screen->xroot)) + return TRUE; + + /* Any windows created via meta_create_offscreen_window */ + if (attrs->override_redirect && attrs->x == -100 && attrs->height == -100 && attrs->width == 1 && attrs->height == 1) return TRUE; - } return FALSE; } From 6dbb3fddce34cfcbe57e9fe32c2cd8893582f063 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sat, 1 Feb 2014 19:08:27 -0500 Subject: [PATCH 446/889] window: Fix build once more Bad syntax here... --- src/core/window.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/window.c b/src/core/window.c index 69f28877c..83ca163d2 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -773,7 +773,7 @@ maybe_filter_xwindow (MetaDisplay *display, static gboolean is_our_xwindow (MetaDisplay *display, - MetaScreen *screen + MetaScreen *screen, Window xwindow, XWindowAttributes *attrs) { From 59c8b949ad1b8712be7f1e90f8aaddac897da463 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sat, 1 Feb 2014 19:16:25 -0500 Subject: [PATCH 447/889] window: Delay the showing of XWayland clients until set_window_id Use our new "surface_mapped" field to delay the showing of XWayland clients until we have associated together the window's XID and the Wayland surface ID. This ensures that when we show this window to the compositor, it will properly use the Wayland surface for rendering, rather than trying to use COMPOSITE and crash. https://bugzilla.gnome.org/show_bug.cgi?id=720631 --- src/core/window.c | 12 +++++++++--- src/wayland/meta-xwayland.c | 2 ++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/core/window.c b/src/core/window.c index 83ca163d2..22a8c67fc 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -833,7 +833,6 @@ meta_window_new_shared (MetaDisplay *display, MetaWindowClientType client_type, MetaWaylandSurface *surface, Window xwindow, - gboolean surface_mapped, gulong existing_wm_state, MetaCompEffect effect, XWindowAttributes *attrs) @@ -863,7 +862,7 @@ meta_window_new_shared (MetaDisplay *display, window->client_type = client_type; window->surface = surface; window->xwindow = xwindow; - window->surface_mapped = surface_mapped; + window->surface_mapped = FALSE; /* this is in window->screen->display, but that's too annoying to * type @@ -1413,7 +1412,6 @@ meta_window_new_for_wayland (MetaDisplay *display, META_WINDOW_CLIENT_TYPE_WAYLAND, surface, None, - FALSE, WithdrawnState, META_COMP_EFFECT_CREATE, &attrs); @@ -1585,6 +1583,14 @@ meta_window_new (MetaDisplay *display, effect, &attrs); + /* When running as an X compositor, we can simply show the window now. + * + * When running as a Wayland compositor, we need to wait until we see + * the Wayland surface appear. We will later call meta_window_set_surface_mapped() + * to show the window in our in our set_surface_id implementation */ + if (!meta_is_wayland_compositor ()) + meta_window_set_surface_mapped (window, TRUE); + meta_error_trap_pop (display); /* pop the XSync()-reducing trap */ return window; diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index 33b3b8db7..e15e30882 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -49,6 +49,8 @@ xserver_set_window_id (struct wl_client *client, surface->window = window; window->surface = surface; + + meta_window_set_surface_mapped (window, TRUE); } static const struct xserver_interface xserver_implementation = { From b09e1399c0932246181b71bc45c98562ca9aee50 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sat, 1 Feb 2014 19:03:33 -0500 Subject: [PATCH 448/889] window: Centralize WM_STATE management --- src/core/window.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/core/window.c b/src/core/window.c index 22a8c67fc..74a3e199d 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -98,8 +98,7 @@ static void invalidate_work_areas (MetaWindow *window); static void set_wm_state_on_xwindow (MetaDisplay *display, Window xwindow, int state); -static void set_wm_state (MetaWindow *window, - int state); +static void set_wm_state (MetaWindow *window); static void set_net_wm_state (MetaWindow *window); static void meta_window_set_above (MetaWindow *window, gboolean new_value); @@ -1310,7 +1309,7 @@ meta_window_new_shared (MetaDisplay *display, /* FIXME we have a tendency to set this then immediately * change it again. */ - set_wm_state (window, window->iconic ? IconicState : NormalState); + set_wm_state (window); set_net_wm_state (window); } @@ -1950,7 +1949,7 @@ meta_window_unmanage (MetaWindow *window, XDeleteProperty (window->display->xdisplay, window->xwindow, window->display->atom__NET_WM_FULLSCREEN_MONITORS); - set_wm_state (window, WithdrawnState); + set_wm_state (window); meta_error_trap_pop (window->display); } else @@ -1961,7 +1960,7 @@ meta_window_unmanage (MetaWindow *window, if (!window->minimized) { meta_error_trap_push (window->display); - set_wm_state (window, NormalState); + set_wm_state (window); meta_error_trap_pop (window->display); } @@ -2117,11 +2116,16 @@ set_wm_state_on_xwindow (MetaDisplay *display, } static void -set_wm_state (MetaWindow *window, - int state) +set_wm_state (MetaWindow *window) { - meta_verbose ("Setting wm state %s on %s\n", - wm_state_to_string (state), window->desc); + int state; + + if (window->withdrawn) + state = WithdrawnState; + else if (window->iconic) + state = IconicState; + else + state = NormalState; set_wm_state_on_xwindow (window->display, window->xwindow, state); } @@ -3130,7 +3134,7 @@ meta_window_show (MetaWindow *window) if (!window->iconic) { window->iconic = TRUE; - set_wm_state (window, IconicState); + set_wm_state (window); } } else @@ -3149,7 +3153,7 @@ meta_window_show (MetaWindow *window) if (window->iconic) { window->iconic = FALSE; - set_wm_state (window, NormalState); + set_wm_state (window); } } @@ -3302,7 +3306,7 @@ meta_window_hide (MetaWindow *window) if (!window->iconic) { window->iconic = TRUE; - set_wm_state (window, IconicState); + set_wm_state (window); } toplevel_now_mapped = meta_window_toplevel_is_mapped (window); From 8905bd2280481a7ddf36e32e6eb192c52fd45418 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sat, 1 Feb 2014 19:19:22 -0500 Subject: [PATCH 449/889] window-x11: Move meta_window_new to window-x11.c and rename --- src/core/display.c | 8 +- src/core/screen.c | 4 +- src/core/window-private.h | 20 +- src/core/window-props.c | 2 +- src/core/window-x11.c | 343 ++++++++++++++++++++++++++ src/core/window-x11.h | 13 +- src/core/window.c | 382 ++--------------------------- src/wayland/meta-wayland-surface.c | 4 +- 8 files changed, 395 insertions(+), 381 deletions(-) diff --git a/src/core/display.c b/src/core/display.c index 24365f3b0..a8ed432b5 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -2817,15 +2817,15 @@ handle_other_xevent (MetaDisplay *display, if (display->compositor && window == NULL && meta_display_screen_for_root (display, event->xmap.event)) { - window = meta_window_new (display, event->xmap.window, - FALSE, META_COMP_EFFECT_CREATE); + window = meta_window_x11_new (display, event->xmap.window, + FALSE, META_COMP_EFFECT_CREATE); } break; case MapRequest: if (window == NULL) { - window = meta_window_new (display, event->xmaprequest.window, - FALSE, META_COMP_EFFECT_CREATE); + window = meta_window_x11_new (display, event->xmaprequest.window, + FALSE, META_COMP_EFFECT_CREATE); } /* 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 aa3628f0c..e1e967116 100644 --- a/src/core/screen.c +++ b/src/core/screen.c @@ -896,8 +896,8 @@ meta_screen_manage_all_windows (MetaScreen *screen) for (i = 0; i < n_children; ++i) { - meta_window_new (screen->display, children[i].x11.xwindow, TRUE, - META_COMP_EFFECT_NONE); + meta_window_x11_new (screen->display, children[i].x11.xwindow, TRUE, + META_COMP_EFFECT_NONE); } g_free (children); diff --git a/src/core/window-private.h b/src/core/window-private.h index 679719b45..c18b6a99a 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -506,12 +506,22 @@ struct _MetaWindowClass #define META_WINDOW_ALLOWS_HORIZONTAL_RESIZE(w) (META_WINDOW_ALLOWS_RESIZE_EXCEPT_HINTS (w) && (w)->size_hints.min_width < (w)->size_hints.max_width) #define META_WINDOW_ALLOWS_VERTICAL_RESIZE(w) (META_WINDOW_ALLOWS_RESIZE_EXCEPT_HINTS (w) && (w)->size_hints.min_height < (w)->size_hints.max_height) -MetaWindow* meta_window_new (MetaDisplay *display, - Window xwindow, - gboolean must_be_viewable, - MetaCompEffect effect); -MetaWindow *meta_window_new_for_wayland (MetaDisplay *display, +MetaWindow * _meta_window_shared_new (MetaDisplay *display, + MetaScreen *screen, + MetaWindowClientType client_type, + MetaWaylandSurface *surface, + Window xwindow, + gulong existing_wm_state, + MetaCompEffect effect, + XWindowAttributes *attrs); + +MetaWindow * meta_window_x11_new (MetaDisplay *display, + Window xwindow, + gboolean must_be_viewable, + MetaCompEffect effect); +MetaWindow * meta_window_wayland_new (MetaDisplay *display, MetaWaylandSurface *surface); + void meta_window_unmanage (MetaWindow *window, guint32 timestamp); void meta_window_calc_showing (MetaWindow *window); diff --git a/src/core/window-props.c b/src/core/window-props.c index ca73bd27b..6bb44e934 100644 --- a/src/core/window-props.c +++ b/src/core/window-props.c @@ -846,7 +846,7 @@ reload_mwm_hints (MetaWindow *window, meta_window_recalc_features (window); - /* We do all this anyhow at the end of meta_window_new() */ + /* We do all this anyhow at the end of meta_window_x11_new() */ if (!window->constructing) { if (window->decorated) diff --git a/src/core/window-x11.c b/src/core/window-x11.c index 3391a548a..eeabbbbd7 100644 --- a/src/core/window-x11.c +++ b/src/core/window-x11.c @@ -32,6 +32,9 @@ #include #endif +#include +#include "core.h" + #include #include #include @@ -1146,3 +1149,343 @@ meta_window_x11_client_message (MetaWindow *window, return FALSE; } + +static void +set_wm_state_on_xwindow (MetaDisplay *display, + Window xwindow, + int state) +{ + unsigned long data[2]; + + /* Mutter doesn't use icon windows, so data[1] should be None + * according to the ICCCM 2.0 Section 4.1.3.1. + */ + data[0] = state; + data[1] = None; + + meta_error_trap_push (display); + XChangeProperty (display->xdisplay, xwindow, + display->atom_WM_STATE, + display->atom_WM_STATE, + 32, PropModeReplace, (guchar*) data, 2); + meta_error_trap_pop (display); +} + +void +meta_window_x11_set_wm_state (MetaWindow *window) +{ + int state; + + if (window->withdrawn) + state = WithdrawnState; + else if (window->iconic) + state = IconicState; + else + state = NormalState; + + set_wm_state_on_xwindow (window->display, window->xwindow, state); +} + +/* The MUTTER_WM_CLASS_FILTER environment variable is designed for + * performance and regression testing environments where we want to do + * tests with only a limited set of windows and ignore all other windows + * + * When it is set to a comma separated list of WM_CLASS class names, all + * windows not matching the list will be ignored. + * + * Returns TRUE if window has been filtered out and should be ignored. + */ +static gboolean +maybe_filter_xwindow (MetaDisplay *display, + Window xwindow, + gboolean must_be_viewable, + XWindowAttributes *attrs) +{ + static char **filter_wm_classes = NULL; + static gboolean initialized = FALSE; + XClassHint class_hint; + gboolean filtered; + Status success; + int i; + + if (!initialized) + { + const char *filter_string = g_getenv ("MUTTER_WM_CLASS_FILTER"); + if (filter_string) + filter_wm_classes = g_strsplit (filter_string, ",", -1); + initialized = TRUE; + } + + if (!filter_wm_classes || !filter_wm_classes[0]) + return FALSE; + + filtered = TRUE; + + meta_error_trap_push (display); + success = XGetClassHint (display->xdisplay, xwindow, &class_hint); + + if (success) + { + for (i = 0; filter_wm_classes[i]; i++) + { + if (strcmp (class_hint.res_class, filter_wm_classes[i]) == 0) + { + filtered = FALSE; + break; + } + } + + XFree (class_hint.res_name); + XFree (class_hint.res_class); + } + + if (filtered) + { + /* We want to try and get the window managed by the next WM that come along, + * so we need to make sure that windows that are requested to be mapped while + * Mutter is running (!must_be_viewable), or windows already viewable at startup + * get a non-withdrawn WM_STATE property. Previously unmapped windows are left + * with whatever WM_STATE property they had. + */ + if (!must_be_viewable || attrs->map_state == IsViewable) + { + gulong old_state; + + if (!meta_prop_get_cardinal_with_atom_type (display, xwindow, + display->atom_WM_STATE, + display->atom_WM_STATE, + &old_state)) + old_state = WithdrawnState; + + if (old_state == WithdrawnState) + set_wm_state_on_xwindow (display, xwindow, NormalState); + } + + /* Make sure filtered windows are hidden from view */ + XUnmapWindow (display->xdisplay, xwindow); + } + + meta_error_trap_pop (display); + + return filtered; +} + +static gboolean +is_our_xwindow (MetaDisplay *display, + MetaScreen *screen, + Window xwindow, + XWindowAttributes *attrs) +{ + if (xwindow == screen->no_focus_window) + return TRUE; + + if (xwindow == screen->flash_window) + return TRUE; + + if (xwindow == screen->wm_sn_selection_window) + return TRUE; + + if (xwindow == screen->wm_cm_selection_window) + return TRUE; + + if (xwindow == screen->guard_window) + return TRUE; + + if (display->compositor && xwindow == XCompositeGetOverlayWindow (display->xdisplay, screen->xroot)) + return TRUE; + + /* Any windows created via meta_create_offscreen_window */ + if (attrs->override_redirect && attrs->x == -100 && attrs->height == -100 && attrs->width == 1 && attrs->height == 1) + return TRUE; + + return FALSE; +} + +#ifdef WITH_VERBOSE_MODE +static const char* +wm_state_to_string (int state) +{ + switch (state) + { + case NormalState: + return "NormalState"; + case IconicState: + return "IconicState"; + case WithdrawnState: + return "WithdrawnState"; + } + + return "Unknown"; +} +#endif + +MetaWindow * +meta_window_x11_new (MetaDisplay *display, + Window xwindow, + gboolean must_be_viewable, + MetaCompEffect effect) +{ + XWindowAttributes attrs; + MetaScreen *screen = NULL; + GSList *tmp; + gulong existing_wm_state; + MetaWindow *window = NULL; + gulong event_mask; + + meta_verbose ("Attempting to manage 0x%lx\n", xwindow); + + if (meta_display_xwindow_is_a_no_focus_window (display, xwindow)) + { + meta_verbose ("Not managing no_focus_window 0x%lx\n", + xwindow); + return NULL; + } + + meta_error_trap_push (display); /* Push a trap over all of window + * creation, to reduce XSync() calls + */ + /* + * This function executes without any server grabs held. This means that + * the window could have already gone away, or could go away at any point, + * so we must be careful with X error handling. + */ + + if (!XGetWindowAttributes (display->xdisplay, xwindow, &attrs)) + { + meta_verbose ("Failed to get attributes for window 0x%lx\n", + xwindow); + goto error; + } + + for (tmp = display->screens; tmp != NULL; tmp = tmp->next) + { + MetaScreen *scr = tmp->data; + + if (scr->xroot == attrs.root) + { + screen = tmp->data; + break; + } + } + + g_assert (screen); + + if (is_our_xwindow (display, screen, xwindow, &attrs)) + { + meta_verbose ("Not managing our own windows\n"); + goto error; + } + + if (maybe_filter_xwindow (display, xwindow, must_be_viewable, &attrs)) + { + meta_verbose ("Not managing filtered window\n"); + goto error; + } + + existing_wm_state = WithdrawnState; + if (must_be_viewable && attrs.map_state != IsViewable) + { + /* Only manage if WM_STATE is IconicState or NormalState */ + gulong state; + + /* WM_STATE isn't a cardinal, it's type WM_STATE, but is an int */ + if (!(meta_prop_get_cardinal_with_atom_type (display, xwindow, + display->atom_WM_STATE, + display->atom_WM_STATE, + &state) && + (state == IconicState || state == NormalState))) + { + meta_verbose ("Deciding not to manage unmapped or unviewable window 0x%lx\n", xwindow); + goto error; + } + + existing_wm_state = state; + meta_verbose ("WM_STATE of %lx = %s\n", xwindow, + wm_state_to_string (existing_wm_state)); + } + + meta_error_trap_push_with_return (display); + + /* + * XAddToSaveSet can only be called on windows created by a different + * client. with Mutter we want to be able to create manageable windows + * from within the process (such as a dummy desktop window). As we do not + * want this call failing to prevent the window from being managed, we + * call this before creating the return-checked error trap. + */ + XAddToSaveSet (display->xdisplay, xwindow); + + meta_error_trap_push_with_return (display); + + event_mask = PropertyChangeMask | ColormapChangeMask; + if (attrs.override_redirect) + event_mask |= StructureNotifyMask; + + /* If the window is from this client (a menu, say) we need to augment + * the event mask, not replace it. For windows from other clients, + * attrs.your_event_mask will be empty at this point. + */ + XSelectInput (display->xdisplay, xwindow, attrs.your_event_mask | event_mask); + + { + unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; + XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits }; + + meta_core_add_old_event_mask (display->xdisplay, xwindow, &mask); + + XISetMask (mask.mask, XI_Enter); + XISetMask (mask.mask, XI_Leave); + XISetMask (mask.mask, XI_FocusIn); + XISetMask (mask.mask, XI_FocusOut); + + XISelectEvents (display->xdisplay, xwindow, &mask, 1); + } + + /* Get rid of any borders */ + if (attrs.border_width != 0) + XSetWindowBorderWidth (display->xdisplay, xwindow, 0); + + /* Get rid of weird gravities */ + if (attrs.win_gravity != NorthWestGravity) + { + XSetWindowAttributes set_attrs; + + set_attrs.win_gravity = NorthWestGravity; + + XChangeWindowAttributes (display->xdisplay, + xwindow, + CWWinGravity, + &set_attrs); + } + + if (meta_error_trap_pop_with_return (display) != Success) + { + meta_verbose ("Window 0x%lx disappeared just as we tried to manage it\n", + xwindow); + goto error; + } + + window = _meta_window_shared_new (display, + screen, + META_WINDOW_CLIENT_TYPE_X11, + NULL, + xwindow, + existing_wm_state, + effect, + &attrs); + + /* When running as an X compositor, we can simply show the window now. + * + * When running as a Wayland compositor, we need to wait until we see + * the Wayland surface appear. We will later call meta_window_set_surface_mapped() + * to show the window in our in our set_surface_id implementation */ + if (!meta_is_wayland_compositor ()) + meta_window_set_surface_mapped (window, TRUE); + + meta_error_trap_pop (display); /* pop the XSync()-reducing trap */ + return window; + +error: + meta_error_trap_pop (display); + return NULL; +} diff --git a/src/core/window-x11.h b/src/core/window-x11.h index aea216f0e..4657c7f33 100644 --- a/src/core/window-x11.h +++ b/src/core/window-x11.h @@ -26,13 +26,14 @@ #include #include -void meta_window_x11_set_net_wm_state (MetaWindow *window); +void meta_window_x11_set_net_wm_state (MetaWindow *window); +void meta_window_x11_set_wm_state (MetaWindow *window); -void meta_window_x11_update_role (MetaWindow *window); -void meta_window_x11_update_net_wm_type (MetaWindow *window); -void meta_window_x11_update_opaque_region (MetaWindow *window); -void meta_window_x11_update_input_region (MetaWindow *window); -void meta_window_x11_update_shape_region (MetaWindow *window); +void meta_window_x11_update_role (MetaWindow *window); +void meta_window_x11_update_net_wm_type (MetaWindow *window); +void meta_window_x11_update_opaque_region (MetaWindow *window); +void meta_window_x11_update_input_region (MetaWindow *window); +void meta_window_x11_update_shape_region (MetaWindow *window); gboolean meta_window_x11_configure_request (MetaWindow *window, XEvent *event); diff --git a/src/core/window.c b/src/core/window.c index 74a3e199d..eb3035f58 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -58,8 +58,6 @@ #include #endif -#include - #include "meta-wayland-private.h" #include "meta/compositor-mutter.h" @@ -95,9 +93,6 @@ static void ping_data_free (MetaPingData *ping_data); static void update_sm_hints (MetaWindow *window); static void update_net_frame_extents (MetaWindow *window); static void invalidate_work_areas (MetaWindow *window); -static void set_wm_state_on_xwindow (MetaDisplay *display, - Window xwindow, - int state); static void set_wm_state (MetaWindow *window); static void set_net_wm_state (MetaWindow *window); static void meta_window_set_above (MetaWindow *window, @@ -622,24 +617,6 @@ meta_window_init (MetaWindow *self) meta_prefs_add_listener (prefs_changed_callback, self); } -#ifdef WITH_VERBOSE_MODE -static const char* -wm_state_to_string (int state) -{ - switch (state) - { - case NormalState: - return "NormalState"; - case IconicState: - return "IconicState"; - case WithdrawnState: - return "WithdrawnState"; - } - - return "Unknown"; -} -#endif - static gboolean is_desktop_or_dock_foreach (MetaWindow *window, void *data) @@ -686,121 +663,6 @@ maybe_leave_show_desktop_mode (MetaWindow *window) } } -/* The MUTTER_WM_CLASS_FILTER environment variable is designed for - * performance and regression testing environments where we want to do - * tests with only a limited set of windows and ignore all other windows - * - * When it is set to a comma separated list of WM_CLASS class names, all - * windows not matching the list will be ignored. - * - * Returns TRUE if window has been filtered out and should be ignored. - */ -static gboolean -maybe_filter_xwindow (MetaDisplay *display, - Window xwindow, - gboolean must_be_viewable, - XWindowAttributes *attrs) -{ - static char **filter_wm_classes = NULL; - static gboolean initialized = FALSE; - XClassHint class_hint; - gboolean filtered; - Status success; - int i; - - if (!initialized) - { - const char *filter_string = g_getenv ("MUTTER_WM_CLASS_FILTER"); - if (filter_string) - filter_wm_classes = g_strsplit (filter_string, ",", -1); - initialized = TRUE; - } - - if (!filter_wm_classes || !filter_wm_classes[0]) - return FALSE; - - filtered = TRUE; - - meta_error_trap_push (display); - success = XGetClassHint (display->xdisplay, xwindow, &class_hint); - - if (success) - { - for (i = 0; filter_wm_classes[i]; i++) - { - if (strcmp (class_hint.res_class, filter_wm_classes[i]) == 0) - { - filtered = FALSE; - break; - } - } - - XFree (class_hint.res_name); - XFree (class_hint.res_class); - } - - if (filtered) - { - /* We want to try and get the window managed by the next WM that come along, - * so we need to make sure that windows that are requested to be mapped while - * Mutter is running (!must_be_viewable), or windows already viewable at startup - * get a non-withdrawn WM_STATE property. Previously unmapped windows are left - * with whatever WM_STATE property they had. - */ - if (!must_be_viewable || attrs->map_state == IsViewable) - { - gulong old_state; - - if (!meta_prop_get_cardinal_with_atom_type (display, xwindow, - display->atom_WM_STATE, - display->atom_WM_STATE, - &old_state)) - old_state = WithdrawnState; - - if (old_state == WithdrawnState) - set_wm_state_on_xwindow (display, xwindow, NormalState); - } - - /* Make sure filtered windows are hidden from view */ - XUnmapWindow (display->xdisplay, xwindow); - } - - meta_error_trap_pop (display); - - return filtered; -} - -static gboolean -is_our_xwindow (MetaDisplay *display, - MetaScreen *screen, - Window xwindow, - XWindowAttributes *attrs) -{ - if (xwindow == screen->no_focus_window) - return TRUE; - - if (xwindow == screen->flash_window) - return TRUE; - - if (xwindow == screen->wm_sn_selection_window) - return TRUE; - - if (xwindow == screen->wm_cm_selection_window) - return TRUE; - - if (xwindow == screen->guard_window) - return TRUE; - - if (display->compositor && xwindow == XCompositeGetOverlayWindow (display->xdisplay, screen->xroot)) - return TRUE; - - /* Any windows created via meta_create_offscreen_window */ - if (attrs->override_redirect && attrs->x == -100 && attrs->height == -100 && attrs->width == 1 && attrs->height == 1) - return TRUE; - - return FALSE; -} - gboolean meta_window_should_attach_to_parent (MetaWindow *window) { @@ -826,15 +688,15 @@ meta_window_should_attach_to_parent (MetaWindow *window) } } -static MetaWindow* -meta_window_new_shared (MetaDisplay *display, - MetaScreen *screen, - MetaWindowClientType client_type, - MetaWaylandSurface *surface, - Window xwindow, - gulong existing_wm_state, - MetaCompEffect effect, - XWindowAttributes *attrs) +MetaWindow * +_meta_window_shared_new (MetaDisplay *display, + MetaScreen *screen, + MetaWindowClientType client_type, + MetaWaylandSurface *surface, + Window xwindow, + gulong existing_wm_state, + MetaCompEffect effect, + XWindowAttributes *attrs) { MetaWindow *window; MetaWorkspace *space; @@ -1365,8 +1227,8 @@ meta_window_new_shared (MetaDisplay *display, } MetaWindow * -meta_window_new_for_wayland (MetaDisplay *display, - MetaWaylandSurface *surface) +meta_window_wayland_new (MetaDisplay *display, + MetaWaylandSurface *surface) { XWindowAttributes attrs; MetaScreen *scr = display->screens->data; @@ -1406,14 +1268,14 @@ meta_window_new_for_wayland (MetaDisplay *display, * creation, to reduce XSync() calls */ - window = meta_window_new_shared (display, - scr, - META_WINDOW_CLIENT_TYPE_WAYLAND, - surface, - None, - WithdrawnState, - META_COMP_EFFECT_CREATE, - &attrs); + window = _meta_window_shared_new (display, + scr, + META_WINDOW_CLIENT_TYPE_WAYLAND, + surface, + None, + WithdrawnState, + META_COMP_EFFECT_CREATE, + &attrs); meta_error_trap_pop (display); /* pop the XSync()-reducing trap */ @@ -1426,179 +1288,6 @@ meta_window_new_for_wayland (MetaDisplay *display, return window; } -MetaWindow* -meta_window_new (MetaDisplay *display, - Window xwindow, - gboolean must_be_viewable, - MetaCompEffect effect) -{ - XWindowAttributes attrs; - MetaScreen *screen = NULL; - GSList *tmp; - gulong existing_wm_state; - MetaWindow *window; - gulong event_mask; - - meta_verbose ("Attempting to manage 0x%lx\n", xwindow); - - if (meta_display_xwindow_is_a_no_focus_window (display, xwindow)) - { - meta_verbose ("Not managing no_focus_window 0x%lx\n", - xwindow); - return NULL; - } - - meta_error_trap_push (display); /* Push a trap over all of window - * creation, to reduce XSync() calls - */ - /* - * This function executes without any server grabs held. This means that - * the window could have already gone away, or could go away at any point, - * so we must be careful with X error handling. - */ - - if (!XGetWindowAttributes (display->xdisplay, xwindow, &attrs)) - { - meta_verbose ("Failed to get attributes for window 0x%lx\n", - xwindow); - goto error; - } - - for (tmp = display->screens; tmp != NULL; tmp = tmp->next) - { - MetaScreen *scr = tmp->data; - - if (scr->xroot == attrs.root) - { - screen = tmp->data; - break; - } - } - - g_assert (screen); - - if (is_our_xwindow (display, screen, xwindow, &attrs)) - { - meta_verbose ("Not managing our own windows\n"); - goto error; - } - - if (maybe_filter_xwindow (display, xwindow, must_be_viewable, &attrs)) - { - meta_verbose ("Not managing filtered window\n"); - goto error; - } - - existing_wm_state = WithdrawnState; - if (must_be_viewable && attrs.map_state != IsViewable) - { - /* Only manage if WM_STATE is IconicState or NormalState */ - gulong state; - - /* WM_STATE isn't a cardinal, it's type WM_STATE, but is an int */ - if (!(meta_prop_get_cardinal_with_atom_type (display, xwindow, - display->atom_WM_STATE, - display->atom_WM_STATE, - &state) && - (state == IconicState || state == NormalState))) - { - meta_verbose ("Deciding not to manage unmapped or unviewable window 0x%lx\n", xwindow); - goto error; - } - - existing_wm_state = state; - meta_verbose ("WM_STATE of %lx = %s\n", xwindow, - wm_state_to_string (existing_wm_state)); - } - - meta_error_trap_push_with_return (display); - - /* - * XAddToSaveSet can only be called on windows created by a different - * client. with Mutter we want to be able to create manageable windows - * from within the process (such as a dummy desktop window). As we do not - * want this call failing to prevent the window from being managed, we - * call this before creating the return-checked error trap. - */ - XAddToSaveSet (display->xdisplay, xwindow); - - meta_error_trap_push_with_return (display); - - event_mask = PropertyChangeMask | ColormapChangeMask; - if (attrs.override_redirect) - event_mask |= StructureNotifyMask; - - /* If the window is from this client (a menu, say) we need to augment - * the event mask, not replace it. For windows from other clients, - * attrs.your_event_mask will be empty at this point. - */ - XSelectInput (display->xdisplay, xwindow, attrs.your_event_mask | event_mask); - - { - unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; - XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits }; - - meta_core_add_old_event_mask (display->xdisplay, xwindow, &mask); - - XISetMask (mask.mask, XI_Enter); - XISetMask (mask.mask, XI_Leave); - XISetMask (mask.mask, XI_FocusIn); - XISetMask (mask.mask, XI_FocusOut); - - XISelectEvents (display->xdisplay, xwindow, &mask, 1); - } - - /* Get rid of any borders */ - if (attrs.border_width != 0) - XSetWindowBorderWidth (display->xdisplay, xwindow, 0); - - /* Get rid of weird gravities */ - if (attrs.win_gravity != NorthWestGravity) - { - XSetWindowAttributes set_attrs; - - set_attrs.win_gravity = NorthWestGravity; - - XChangeWindowAttributes (display->xdisplay, - xwindow, - CWWinGravity, - &set_attrs); - } - - if (meta_error_trap_pop_with_return (display) != Success) - { - meta_verbose ("Window 0x%lx disappeared just as we tried to manage it\n", - xwindow); - goto error; - } - - window = meta_window_new_shared (display, - screen, - META_WINDOW_CLIENT_TYPE_X11, - NULL, - xwindow, - TRUE, - existing_wm_state, - effect, - &attrs); - - /* When running as an X compositor, we can simply show the window now. - * - * When running as a Wayland compositor, we need to wait until we see - * the Wayland surface appear. We will later call meta_window_set_surface_mapped() - * to show the window in our in our set_surface_id implementation */ - if (!meta_is_wayland_compositor ()) - meta_window_set_surface_mapped (window, TRUE); - - meta_error_trap_pop (display); /* pop the XSync()-reducing trap */ - - return window; - -error: - meta_error_trap_pop (display); - return NULL; -} - /* This function should only be called from the end of meta_window_new_with_attrs () */ static void meta_window_apply_session_info (MetaWindow *window, @@ -2094,40 +1783,11 @@ meta_window_update_on_all_workspaces (MetaWindow *window) } } -static void -set_wm_state_on_xwindow (MetaDisplay *display, - Window xwindow, - int state) -{ - unsigned long data[2]; - - /* Mutter doesn't use icon windows, so data[1] should be None - * according to the ICCCM 2.0 Section 4.1.3.1. - */ - data[0] = state; - data[1] = None; - - meta_error_trap_push (display); - XChangeProperty (display->xdisplay, xwindow, - display->atom_WM_STATE, - display->atom_WM_STATE, - 32, PropModeReplace, (guchar*) data, 2); - meta_error_trap_pop (display); -} - static void set_wm_state (MetaWindow *window) { - int state; - - if (window->withdrawn) - state = WithdrawnState; - else if (window->iconic) - state = IconicState; - else - state = NormalState; - - set_wm_state_on_xwindow (window->display, window->xwindow, state); + if (window->client_type == META_WINDOW_CLIENT_TYPE_X11) + meta_window_x11_set_wm_state (window); } static void diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 764ec2c5e..0dca23e0e 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -928,7 +928,7 @@ get_xdg_surface (struct wl_client *client, return; } - surface->window = meta_window_new_for_wayland (meta_get_display (), surface); + surface->window = meta_window_wayland_new (meta_get_display (), surface); } static void @@ -998,7 +998,7 @@ get_xdg_popup (struct wl_client *client, return; } - surface->window = meta_window_new_for_wayland (meta_get_display (), surface); + surface->window = meta_window_wayland_new (meta_get_display (), surface); surface->window->rect.x = parent_rect.x + x; surface->window->rect.y = parent_rect.y + y; surface->window->showing_for_first_time = FALSE; From e04a55d1a2393c52756d134671963ac781ed7253 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sat, 1 Feb 2014 19:22:56 -0500 Subject: [PATCH 450/889] keybindings: Reindent --- src/core/keybindings.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/core/keybindings.c b/src/core/keybindings.c index 01788c2cb..e6c6a885e 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -4089,28 +4089,28 @@ handle_switch_vt (MetaDisplay *display, MetaKeyBinding *binding, gpointer dummy) { - gint vt = binding->handler->data; - MetaWaylandCompositor *compositor; - MetaLauncher *launcher; + gint vt = binding->handler->data; + MetaWaylandCompositor *compositor; + MetaLauncher *launcher; - compositor = meta_wayland_compositor_get_default (); - launcher = meta_wayland_compositor_get_launcher (compositor); + compositor = meta_wayland_compositor_get_default (); + launcher = meta_wayland_compositor_get_launcher (compositor); - if (launcher) - { - GError *error; + if (launcher) + { + GError *error; - error = NULL; - if (!meta_launcher_activate_vt (launcher, vt, &error)) - { - g_warning ("Failed to switch VT: %s", error->message); - g_error_free (error); - } - } - else - { - g_debug ("Ignoring VT switch keybinding, not running as VT manager"); - } + error = NULL; + if (!meta_launcher_activate_vt (launcher, vt, &error)) + { + g_warning ("Failed to switch VT: %s", error->message); + g_error_free (error); + } + } + else + { + g_debug ("Ignoring VT switch keybinding, not running as VT manager"); + } } #endif From 7e7b671b8e11cfc4575e206ae40c031376ca95cb Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sat, 1 Feb 2014 19:34:24 -0500 Subject: [PATCH 451/889] keybindings: Simplify interface for VT switching --- src/core/keybindings.c | 23 +++++------------------ src/wayland/meta-wayland-private.h | 5 ++++- src/wayland/meta-wayland.c | 22 ++++++++++++++++------ 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/core/keybindings.c b/src/core/keybindings.c index e6c6a885e..22aa3a866 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -4090,26 +4090,13 @@ handle_switch_vt (MetaDisplay *display, gpointer dummy) { gint vt = binding->handler->data; - MetaWaylandCompositor *compositor; - MetaLauncher *launcher; + MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); + GError *error = NULL; - compositor = meta_wayland_compositor_get_default (); - launcher = meta_wayland_compositor_get_launcher (compositor); - - if (launcher) + if (!meta_wayland_compositor_activate_vt (compositor, vt, &error)) { - GError *error; - - error = NULL; - if (!meta_launcher_activate_vt (launcher, vt, &error)) - { - g_warning ("Failed to switch VT: %s", error->message); - g_error_free (error); - } - } - else - { - g_debug ("Ignoring VT switch keybinding, not running as VT manager"); + g_warning ("Failed to switch VT: %s", error->message); + g_error_free (error); } } #endif diff --git a/src/wayland/meta-wayland-private.h b/src/wayland/meta-wayland-private.h index efd2e4afd..7c860e165 100644 --- a/src/wayland/meta-wayland-private.h +++ b/src/wayland/meta-wayland-private.h @@ -99,7 +99,6 @@ void meta_wayland_compositor_set_input_focus (MetaWaylandComp gboolean meta_wayland_compositor_handle_event (MetaWaylandCompositor *compositor, const ClutterEvent *event); -MetaLauncher *meta_wayland_compositor_get_launcher (MetaWaylandCompositor *compositor); gboolean meta_wayland_compositor_is_native (MetaWaylandCompositor *compositor); MetaWaylandBuffer * meta_wayland_buffer_from_resource (struct wl_resource *resource); @@ -110,4 +109,8 @@ void meta_wayland_compositor_update (MetaWaylandComp const ClutterEvent *event); void meta_wayland_compositor_paint_finished (MetaWaylandCompositor *compositor); +gboolean meta_wayland_compositor_activate_vt (MetaWaylandCompositor *compositor, + int vt, + GError **error); + #endif /* META_WAYLAND_PRIVATE_H */ diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index f3e828f3f..ac49ad99d 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -743,14 +743,24 @@ meta_wayland_finalize (void) meta_launcher_free (compositor->launcher); } -MetaLauncher * -meta_wayland_compositor_get_launcher (MetaWaylandCompositor *compositor) -{ - return compositor->launcher; -} - gboolean meta_wayland_compositor_is_native (MetaWaylandCompositor *compositor) { return compositor->native; } + +gboolean +meta_wayland_compositor_activate_vt (MetaWaylandCompositor *compositor, + int vt, + GError **error) +{ + if (compositor->launcher) + { + return meta_launcher_activate_vt (compositor->launcher, vt, error); + } + else + { + g_debug ("Ignoring VT switch keybinding, not running as VT manager"); + return TRUE; + } +} From 6bf1a66b7cef095d8be93875cbe1c4ca6e50bb24 Mon Sep 17 00:00:00 2001 From: Adel Gadllah Date: Sun, 2 Feb 2014 11:37:25 +0100 Subject: [PATCH 452/889] window_actor: Remove the frame_messages timeout in destroy Otherwise it might fire off later and cause a crash. https://bugzilla.gnome.org/show_bug.cgi?id=723468 --- src/compositor/meta-window-actor.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index f961bf88b..609a58fdd 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -1338,6 +1338,12 @@ meta_window_actor_destroy (MetaWindowActor *self) window_type = meta_window_get_window_type (window); meta_window_set_compositor_private (window, NULL); + if (priv->send_frame_messages_timer != 0) + { + g_source_remove (priv->send_frame_messages_timer); + priv->send_frame_messages_timer = 0; + } + /* * We remove the window from internal lookup hashes and thus any other * unmap events etc fail From c9b71041177d7ec20b5835fb6d27403f0cf47368 Mon Sep 17 00:00:00 2001 From: Adel Gadllah Date: Sun, 2 Feb 2014 15:09:18 +0100 Subject: [PATCH 453/889] monitorManager: Fix logic bug in make_logical_config The code that prevents the creation of multiple MonitorInfos for clones wasn't working due to using the wrong index when getting the already created info so fix that to use the correct one. https://bugzilla.gnome.org/show_bug.cgi?id=710610 --- src/core/monitor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/monitor.c b/src/core/monitor.c index daca82a70..4f4d10587 100644 --- a/src/core/monitor.c +++ b/src/core/monitor.c @@ -288,7 +288,7 @@ make_logical_config (MetaMonitorManager *manager) for (j = 0; j < monitor_infos->len; j++) { - MetaMonitorInfo *info = &g_array_index (monitor_infos, MetaMonitorInfo, i); + MetaMonitorInfo *info = &g_array_index (monitor_infos, MetaMonitorInfo, j); if (meta_rectangle_equal (&crtc->rect, &info->rect)) { From d6396cf2c4b1bf71f51bd2b5f694c28f56d2bb9a Mon Sep 17 00:00:00 2001 From: Marek Ch Date: Thu, 19 Dec 2013 16:56:31 +0100 Subject: [PATCH 454/889] window: fix coerced value (int) 0.5 = 0, so there always was 0 instead of 50% --- src/core/window.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/window.c b/src/core/window.c index eb3035f58..ee29fd4b2 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -7885,7 +7885,7 @@ meta_window_titlebar_is_onscreen (MetaWindow *window) gboolean is_onscreen; const int min_height_needed = 8; - const int min_width_percent = 0.5; + const float min_width_percent = 0.5; const int min_width_absolute = 50; /* Titlebar can't be offscreen if there is no titlebar... */ From 66fc32ee1450e9f38de539157300792c71eab3dc Mon Sep 17 00:00:00 2001 From: Marek Ch Date: Fri, 20 Dec 2013 14:03:41 +0100 Subject: [PATCH 455/889] core: remove tautological condition unsigned number is always greater than 0 https://bugzilla.gnome.org/show_bug.cgi?id=720818 --- src/core/monitor-kms.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/core/monitor-kms.c b/src/core/monitor-kms.c index 9a1cb5036..afdd7bb1e 100644 --- a/src/core/monitor-kms.c +++ b/src/core/monitor-kms.c @@ -111,8 +111,7 @@ make_output_name (drmModeConnector *connector) }; const char *connector_type_name; - if (connector->connector_type >= 0 && - connector->connector_type < G_N_ELEMENTS (connector_type_names)) + if (connector->connector_type < G_N_ELEMENTS (connector_type_names)) connector_type_name = connector_type_names[connector->connector_type]; else connector_type_name = "unknown"; From 183ad756037abc8618e0641200f31ff07ebeadf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Mon, 3 Feb 2014 23:00:12 +0100 Subject: [PATCH 456/889] default plugin: Fix workspace switch type error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jonas Ådahl https://bugzilla.gnome.org/show_bug.cgi?id=723563 --- src/compositor/plugins/default.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/compositor/plugins/default.c b/src/compositor/plugins/default.c index 892854b33..6728daedc 100644 --- a/src/compositor/plugins/default.c +++ b/src/compositor/plugins/default.c @@ -407,9 +407,11 @@ switch_workspace (MetaPlugin *plugin, MetaWindowActor *window_actor = l->data; ActorPrivate *apriv = get_actor_private (window_actor); ClutterActor *actor = CLUTTER_ACTOR (window_actor); + MetaWorkspace *workspace; gint win_workspace; - win_workspace = meta_window_get_workspace (meta_window_actor_get_meta_window (window_actor)); + workspace = meta_window_get_workspace (meta_window_actor_get_meta_window (window_actor)); + win_workspace = meta_workspace_index (workspace); if (win_workspace == to || win_workspace == from) { From 66c4555dc7eca43bfb37a5f1c5d27295271b64f0 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sat, 1 Feb 2014 22:34:05 -0500 Subject: [PATCH 457/889] main: Use setenv() --- src/core/keybindings.c | 1 - src/core/main.c | 12 ++++-------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/core/keybindings.c b/src/core/keybindings.c index 22aa3a866..f0dca9c25 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -28,7 +28,6 @@ */ #define _GNU_SOURCE -#define _SVID_SOURCE /* for putenv() */ #include #include "keybindings-private.h" diff --git a/src/core/main.c b/src/core/main.c index f22bf8e55..a73015285 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -347,14 +347,10 @@ meta_clutter_init (void) static void meta_select_display (gchar *display_name) { - gchar *envVar = ""; - if (display_name) - envVar = g_strconcat ("DISPLAY=", display_name, NULL); - else if (g_getenv ("MUTTER_DISPLAY")) - envVar = g_strconcat ("DISPLAY=", - g_getenv ("MUTTER_DISPLAY"), NULL); - /* DO NOT FREE envVar, putenv() sucks */ - putenv (envVar); + if (!display_name) + display_name = g_getenv ("MUTTER_DISPLAY"); + + g_setenv ("DISPLAY", display_name, TRUE); } static void From 3e73babaf73a9fd2e6487540a3844e4ccfbea2e3 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sat, 1 Feb 2014 23:09:53 -0500 Subject: [PATCH 458/889] display: Clean up creation of the guard window a bit... Do it consistently in all code paths... --- src/core/display.c | 22 ++++++---------------- src/core/screen.c | 15 +++++++++------ 2 files changed, 15 insertions(+), 22 deletions(-) diff --git a/src/core/display.c b/src/core/display.c index a8ed432b5..37aab062b 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -830,22 +830,12 @@ meta_display_open (void) { MetaScreen *screen = tmp->data; - if (meta_is_wayland_compositor ()) - { - /* Instead of explicitly enumerating all windows during - * initialization, when we run as a wayland compositor we can rely on - * xwayland notifying us of all top level windows so we create - * MetaWindows when we get those notifications. - * - * We still want a guard window so we can avoid - * unmapping/withdrawing minimized windows for live - * thumbnails... - */ - if (screen->guard_window == None) - screen->guard_window = - meta_screen_create_guard_window (screen->display->xdisplay, screen); - } - else + meta_screen_create_guard_window (screen); + + /* We know that if mutter is running as a Wayland compositor, + * we start out with no windows. + */ + if (!meta_is_wayland_compositor ()) meta_screen_manage_all_windows (screen); tmp = tmp->next; diff --git a/src/core/screen.c b/src/core/screen.c index e1e967116..e8e8c56e0 100644 --- a/src/core/screen.c +++ b/src/core/screen.c @@ -445,8 +445,8 @@ reload_monitor_infos (MetaScreen *screen) * should effectively be forwarded to events on the background actor, * providing that the scene graph is set up correctly. */ -Window -meta_screen_create_guard_window (Display *xdisplay, MetaScreen *screen) +static Window +create_guard_window (Display *xdisplay, MetaScreen *screen) { XSetWindowAttributes attributes; Window guard_window; @@ -877,6 +877,13 @@ meta_screen_free (MetaScreen *screen, meta_display_ungrab (display); } +void +meta_screen_create_guard_window (MetaScreen *screen) +{ + if (screen->guard_window == None) + screen->guard_window = create_guard_window (screen->display->xdisplay, screen); +} + void meta_screen_manage_all_windows (MetaScreen *screen) { @@ -884,10 +891,6 @@ meta_screen_manage_all_windows (MetaScreen *screen) MetaStackWindow *children; int n_children, i; - if (screen->guard_window == None) - screen->guard_window = - meta_screen_create_guard_window (screen->display->xdisplay, screen); - meta_stack_freeze (screen->stack); meta_stack_tracker_get_stack (screen->stack_tracker, &_children, &n_children); From 2db9f55669de8b5677f775707c2eb23e14db61a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Mon, 3 Feb 2014 23:01:34 +0100 Subject: [PATCH 459/889] window-x11: Fix offscreen window match expression MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jonas Ådahl https://bugzilla.gnome.org/show_bug.cgi?id=723564 --- src/core/window-x11.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/window-x11.c b/src/core/window-x11.c index eeabbbbd7..4866c659d 100644 --- a/src/core/window-x11.c +++ b/src/core/window-x11.c @@ -1295,7 +1295,7 @@ is_our_xwindow (MetaDisplay *display, return TRUE; /* Any windows created via meta_create_offscreen_window */ - if (attrs->override_redirect && attrs->x == -100 && attrs->height == -100 && attrs->width == 1 && attrs->height == 1) + if (attrs->override_redirect && attrs->x == -100 && attrs->y == -100 && attrs->width == 1 && attrs->height == 1) return TRUE; return FALSE; From 965a784c8a355ddf94f3db0a38c4de1a00994d50 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 3 Feb 2014 17:59:59 -0500 Subject: [PATCH 460/889] screen: Fix build I thought I finished this patch last night... I guess not --- src/core/screen-private.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/screen-private.h b/src/core/screen-private.h index 3d02e1827..e3a3c7729 100644 --- a/src/core/screen-private.h +++ b/src/core/screen-private.h @@ -241,7 +241,7 @@ void meta_screen_workspace_switched (MetaScreen *screen, void meta_screen_set_active_workspace_hint (MetaScreen *screen); -Window meta_screen_create_guard_window (Display *xdisplay, MetaScreen *screen); +void meta_screen_create_guard_window (MetaScreen *screen); gboolean meta_screen_handle_xevent (MetaScreen *screen, XEvent *xevent); From 0a9754f305a356b1ffb7737bfaa3f285ceec9148 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 3 Feb 2014 18:02:16 -0500 Subject: [PATCH 461/889] main: Squash constness warning --- src/core/main.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/core/main.c b/src/core/main.c index a73015285..82ae4838a 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -345,9 +345,13 @@ meta_clutter_init (void) * also is %NULL, use the default - :0.0 */ static void -meta_select_display (gchar *display_name) +meta_select_display (char *display_arg) { - if (!display_name) + const char *display_name; + + if (display_arg) + display_name = (const char *) display_arg; + else display_name = g_getenv ("MUTTER_DISPLAY"); g_setenv ("DISPLAY", display_name, TRUE); From 3e98ffaf9958366b584b360ac12bbc03cd070c07 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 3 Feb 2014 18:36:46 -0500 Subject: [PATCH 462/889] wayland-surface: Don't crash if a client destroys a buffer in use This is considered "undefined" by upstream. Right now GTK+ does this a lot, so we shouldn't crash. Let's make them crash instead and send them an error instead. --- src/wayland/meta-wayland-surface.c | 23 +++++++++++++++++++++-- src/wayland/meta-wayland-surface.h | 4 +++- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 0dca23e0e..909d62425 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -71,6 +71,17 @@ typedef struct struct wl_listener sibling_destroy_listener; } MetaWaylandSubsurfacePlacementOp; +static void +surface_handle_buffer_destroy (struct wl_listener *listener, void *data) +{ + MetaWaylandSurface *surface = wl_container_of (listener, surface, buffer_destroy_listener); + + wl_resource_post_error (surface->resource, WL_DISPLAY_ERROR_INVALID_OBJECT, + "Destroyed buffer while it was attached to the surface"); + surface->buffer = NULL; + wl_list_remove (&surface->buffer_destroy_listener.link); +} + static void surface_set_buffer (MetaWaylandSurface *surface, MetaWaylandBuffer *buffer) @@ -79,12 +90,18 @@ surface_set_buffer (MetaWaylandSurface *surface, return; if (surface->buffer) - meta_wayland_buffer_unref (surface->buffer); + { + meta_wayland_buffer_unref (surface->buffer); + wl_list_remove (&surface->buffer_destroy_listener.link); + } surface->buffer = buffer; if (surface->buffer) - meta_wayland_buffer_ref (surface->buffer); + { + meta_wayland_buffer_ref (surface->buffer); + wl_signal_add (&surface->buffer->destroy_signal, &surface->buffer_destroy_listener); + } } static void @@ -621,6 +638,8 @@ meta_wayland_surface_create (MetaWaylandCompositor *compositor, double_buffered_state_init (&surface->pending); + surface->buffer_destroy_listener.notify = surface_handle_buffer_destroy; + surface->surface_actor = g_object_ref_sink (meta_surface_actor_new ()); return surface; } diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h index 129ce8aea..3e1b29737 100644 --- a/src/wayland/meta-wayland-surface.h +++ b/src/wayland/meta-wayland-surface.h @@ -71,7 +71,6 @@ struct _MetaWaylandSurface { struct wl_resource *resource; MetaWaylandCompositor *compositor; - MetaWaylandBuffer *buffer; MetaSurfaceActor *surface_actor; MetaWindow *window; MetaWaylandSurfaceExtension xdg_surface; @@ -79,6 +78,9 @@ struct _MetaWaylandSurface MetaWaylandSurfaceExtension gtk_surface; MetaWaylandSurfaceExtension subsurface; + MetaWaylandBuffer *buffer; + struct wl_listener buffer_destroy_listener; + GList *subsurfaces; struct { From b8e096db826d7691879b2cfb35ba893bb9c29946 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Tue, 4 Feb 2014 22:59:20 +0100 Subject: [PATCH 463/889] Bump version to 3.11.5 Update NEWS. --- NEWS | 13 +++++++++++++ configure.ac | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index ed12bcf22..d8b03465b 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,16 @@ +3.11.5 +====== +* Fix CSD titlebars being placed off-screen [Jasper; #719772] +* Add support for subsurfaces [Jonas; #705502] +* Expose MetaWindow:skip-taskbar property [Florian; #723307] +* Fix legacy tray icons showing up blank [Adel; #721596] +* Fix configuration of cloned monitors [Adel; #710610] +* Misc bug fixes and cleanups [Jasper, Adel, Marek, Jonas; #720631, #723468, + #720818, #723563, #723564] + +Contributors: + Jonas Ådahl, Marek Ch, Adel Gadllah, Florian Müllner, Jasper St. Pierre + 3.11.4 ====== * Don't leave focus on windows that are being unmanaged [Owen; #711618] diff --git a/configure.ac b/configure.ac index 83562439e..d7ab68c88 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ AC_CONFIG_MACRO_DIR([m4]) m4_define([mutter_major_version], [3]) m4_define([mutter_minor_version], [11]) -m4_define([mutter_micro_version], [4]) +m4_define([mutter_micro_version], [5]) m4_define([mutter_version], [mutter_major_version.mutter_minor_version.mutter_micro_version]) From a6539463beb8754ecb8cc7c600ab9977bf10f208 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 5 Feb 2014 14:05:18 -0500 Subject: [PATCH 464/889] shaped-texture: Remove get_clip It seems that this code is trying to transform from "surface coordinates" (the size of texture that's being displayed) to "actor coordinates" (the actor's allocation), but I can't find any place where the two are different. As such, let's just go back to using "surface coordinates" everywhere and see what breaks. --- src/compositor/meta-shaped-texture.c | 59 ++-------------------------- 1 file changed, 3 insertions(+), 56 deletions(-) diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c index 293958438..797693e63 100644 --- a/src/compositor/meta-shaped-texture.c +++ b/src/compositor/meta-shaped-texture.c @@ -594,52 +594,6 @@ meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex, clutter_actor_queue_redraw (CLUTTER_ACTOR (stex)); } -static gboolean -get_clip (MetaShapedTexture *stex, - int x, - int y, - int width, - int height, - cairo_rectangle_int_t *clip) -{ - ClutterActor *self = CLUTTER_ACTOR (stex); - MetaShapedTexturePrivate *priv; - ClutterActorBox allocation; - double scale_x; - double scale_y; - - /* NB: clutter_actor_queue_redraw_with_clip expects a box in the actor's - * coordinate space so we need to convert from surface coordinates to - * actor coordinates... - */ - - /* Calling clutter_actor_get_allocation_box() is enormously expensive - * if the actor has an out-of-date allocation, since it triggers - * a full redraw. clutter_actor_queue_redraw_with_clip() would redraw - * the whole stage anyways in that case, so just go ahead and do - * it here. - */ - if (!clutter_actor_has_allocation (self)) - return FALSE; - - priv = stex->priv; - - if (priv->tex_width == 0 || priv->tex_height == 0) - return FALSE; - - clutter_actor_get_allocation_box (self, &allocation); - - scale_x = (allocation.x2 - allocation.x1) / priv->tex_width; - scale_y = (allocation.y2 - allocation.y1) / priv->tex_height; - - clip->x = x * scale_x; - clip->y = y * scale_y; - clip->width = width * scale_x; - clip->height = height * scale_y; - - return TRUE; -} - /** * meta_shaped_texture_update_area: * @stex: #MetaShapedTexture @@ -667,8 +621,7 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex, cairo_region_t *unobscured_region) { MetaShapedTexturePrivate *priv; - cairo_rectangle_int_t clip; - gboolean has_clip; + cairo_rectangle_int_t clip = { x, y, width, height }; priv = stex->priv; @@ -677,8 +630,6 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex, meta_texture_tower_update_area (priv->paint_tower, x, y, width, height); - has_clip = get_clip (stex, x, y, width, height, &clip); - if (unobscured_region) { cairo_region_t *intersection; @@ -687,8 +638,7 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex, return FALSE; intersection = cairo_region_copy (unobscured_region); - if (has_clip) - cairo_region_intersect_rectangle (intersection, &clip); + cairo_region_intersect_rectangle (intersection, &clip); if (!cairo_region_is_empty (intersection)) { @@ -705,10 +655,7 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex, return FALSE; } - if (has_clip) - clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stex), &clip); - else - clutter_actor_queue_redraw (CLUTTER_ACTOR (stex)); + clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stex), &clip); return TRUE; } From 71efbf033024b5b13c16dfcb99001de0ec448215 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 5 Feb 2014 14:10:49 -0500 Subject: [PATCH 465/889] shaped-texture: Constify clip This matches upstream --- src/compositor/meta-shaped-texture.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c index 797693e63..e3c36cd05 100644 --- a/src/compositor/meta-shaped-texture.c +++ b/src/compositor/meta-shaped-texture.c @@ -621,7 +621,7 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex, cairo_region_t *unobscured_region) { MetaShapedTexturePrivate *priv; - cairo_rectangle_int_t clip = { x, y, width, height }; + const cairo_rectangle_int_t clip = { x, y, width, height }; priv = stex->priv; From 1ebaaa1950efc4f8d8c2eb13d8b94a030a751b66 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 5 Feb 2014 13:39:47 -0500 Subject: [PATCH 466/889] shaped-texture: Clean up code flow a bit This is easier for me to read. --- src/compositor/meta-shaped-texture.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c index e3c36cd05..6c11d7036 100644 --- a/src/compositor/meta-shaped-texture.c +++ b/src/compositor/meta-shaped-texture.c @@ -646,18 +646,17 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex, cairo_region_get_extents (intersection, &damage_rect); clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stex), &damage_rect); cairo_region_destroy (intersection); - return TRUE; } cairo_region_destroy (intersection); - return FALSE; } - - clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stex), &clip); - - return TRUE; + else + { + clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stex), &clip); + return TRUE; + } } /** From 9542b464bfc6521c5ad8e2725c97e819797058a3 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 5 Feb 2014 14:14:41 -0500 Subject: [PATCH 467/889] window-actor: Clean up whitespace --- src/compositor/meta-window-actor.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 609a58fdd..4084b6978 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -939,7 +939,6 @@ meta_window_actor_damage_all (MetaWindowActor *self) ? NULL : priv->unobscured_region; redraw_queued = meta_surface_actor_damage_all (priv->surface, unobscured_region); - priv->repaint_scheduled = priv->repaint_scheduled || redraw_queued; priv->needs_damage_all = FALSE; } @@ -2001,9 +2000,7 @@ meta_window_actor_process_x11_damage (MetaWindowActor *self, event->area.width, event->area.height, unobscured_region); - - priv->repaint_scheduled = priv->repaint_scheduled || redraw_queued; - + priv->repaint_scheduled = priv->repaint_scheduled || redraw_queued; } void From 27ab516f413f9688274f1f7e4f3c38f28bfa1b03 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 5 Feb 2014 13:20:18 -0500 Subject: [PATCH 468/889] cullable: Reset the culling state instead of skipping the traversal When we traversed down to reset the culling state, previously we would just skip any actors that wanted culling. In order to properly reset the unobscured_region before painting, we need to traverse down to these places as well. Do this by calling cull_out with NULL regions for both arguments, and adapt existing cull_out implementations to match. https://bugzilla.gnome.org/show_bug.cgi?id=720631 --- src/compositor/meta-cullable.c | 40 ++++++++++++++-------- src/compositor/meta-shaped-texture.c | 6 ++-- src/compositor/meta-window-actor-private.h | 3 -- src/compositor/meta-window-actor.c | 16 ++++++--- src/compositor/meta-window-group.c | 14 -------- 5 files changed, 40 insertions(+), 39 deletions(-) diff --git a/src/compositor/meta-cullable.c b/src/compositor/meta-cullable.c index 5eb19026a..801cda487 100644 --- a/src/compositor/meta-cullable.c +++ b/src/compositor/meta-cullable.c @@ -70,10 +70,16 @@ meta_cullable_cull_out_children (MetaCullable *cullable, while (clutter_actor_iter_prev (&iter, &child)) { float x, y; + gboolean needs_culling; - if (!CLUTTER_ACTOR_IS_VISIBLE (child)) + if (!META_IS_CULLABLE (child)) continue; + needs_culling = (unobscured_region != NULL && clip_region != NULL); + + if (needs_culling && !CLUTTER_ACTOR_IS_VISIBLE (child)) + needs_culling = FALSE; + /* If an actor has effects applied, then that can change the area * it paints and the opacity, so we no longer can figure out what * portion of the actor is obscured and what portion of the screen @@ -90,25 +96,29 @@ meta_cullable_cull_out_children (MetaCullable *cullable, * as well for the same reason, but omitted for simplicity in the * hopes that no-one will do that. */ - if (clutter_actor_has_effects (child)) - continue; + if (needs_culling && clutter_actor_has_effects (child)) + needs_culling = FALSE; - if (!META_IS_CULLABLE (child)) - continue; + if (needs_culling && !meta_actor_is_untransformed (child, NULL, NULL)) + needs_culling = FALSE; - if (!meta_actor_is_untransformed (child, NULL, NULL)) - continue; + if (needs_culling) + { + clutter_actor_get_position (child, &x, &y); - clutter_actor_get_position (child, &x, &y); + /* Temporarily move to the coordinate system of the actor */ + cairo_region_translate (unobscured_region, - x, - y); + cairo_region_translate (clip_region, - x, - y); - /* Temporarily move to the coordinate system of the actor */ - cairo_region_translate (unobscured_region, - x, - y); - cairo_region_translate (clip_region, - x, - y); + meta_cullable_cull_out (META_CULLABLE (child), unobscured_region, clip_region); - meta_cullable_cull_out (META_CULLABLE (child), unobscured_region, clip_region); - - cairo_region_translate (unobscured_region, x, y); - cairo_region_translate (clip_region, x, y); + cairo_region_translate (unobscured_region, x, y); + cairo_region_translate (clip_region, x, y); + } + else + { + meta_cullable_cull_out (META_CULLABLE (child), NULL, NULL); + } } } diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c index 6c11d7036..14248771a 100644 --- a/src/compositor/meta-shaped-texture.c +++ b/src/compositor/meta-shaped-texture.c @@ -863,8 +863,10 @@ meta_shaped_texture_cull_out (MetaCullable *cullable, { if (priv->opaque_region) { - cairo_region_subtract (unobscured_region, priv->opaque_region); - cairo_region_subtract (clip_region, priv->opaque_region); + if (unobscured_region) + cairo_region_subtract (unobscured_region, priv->opaque_region); + if (clip_region) + cairo_region_subtract (clip_region, priv->opaque_region); } } } diff --git a/src/compositor/meta-window-actor-private.h b/src/compositor/meta-window-actor-private.h index 0207a88f4..9c6a8476e 100644 --- a/src/compositor/meta-window-actor-private.h +++ b/src/compositor/meta-window-actor-private.h @@ -59,9 +59,6 @@ void meta_window_actor_set_updates_frozen (MetaWindowActor *self, void meta_window_actor_queue_frame_drawn (MetaWindowActor *self, gboolean no_delay_frame); -void meta_window_actor_set_unobscured_region (MetaWindowActor *self, - cairo_region_t *unobscured_region); - void meta_window_actor_effect_completed (MetaWindowActor *actor, gulong event); diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 4084b6978..97654f034 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -1707,7 +1707,7 @@ see_region (cairo_region_t *region, * Provides a hint as to what areas of the window need to queue * redraws when damaged. Regions not in @unobscured_region are completely obscured. */ -void +static void meta_window_actor_set_unobscured_region (MetaWindowActor *self, cairo_region_t *unobscured_region) { @@ -1744,13 +1744,19 @@ meta_window_actor_set_clip_region_beneath (MetaWindowActor *self, if (appears_focused ? priv->focused_shadow : priv->unfocused_shadow) { g_clear_pointer (&priv->shadow_clip, cairo_region_destroy); - priv->shadow_clip = cairo_region_copy (beneath_region); - if (clip_shadow_under_window (self)) + if (beneath_region) { - cairo_region_t *frame_bounds = meta_window_get_frame_bounds (priv->window); - cairo_region_subtract (priv->shadow_clip, frame_bounds); + priv->shadow_clip = cairo_region_copy (beneath_region); + + if (clip_shadow_under_window (self)) + { + cairo_region_t *frame_bounds = meta_window_get_frame_bounds (priv->window); + cairo_region_subtract (priv->shadow_clip, frame_bounds); + } } + else + priv->shadow_clip = NULL; } } diff --git a/src/compositor/meta-window-group.c b/src/compositor/meta-window-group.c index a36d5961b..542060531 100644 --- a/src/compositor/meta-window-group.c +++ b/src/compositor/meta-window-group.c @@ -115,8 +115,6 @@ meta_window_group_paint (ClutterActor *actor) { cairo_region_t *clip_region; cairo_region_t *unobscured_region; - ClutterActorIter iter; - ClutterActor *child; cairo_rectangle_int_t visible_rect, clip_rect; int paint_x_offset, paint_y_offset; int paint_x_origin, paint_y_origin; @@ -125,18 +123,6 @@ meta_window_group_paint (ClutterActor *actor) MetaWindowGroup *window_group = META_WINDOW_GROUP (actor); ClutterActor *stage = clutter_actor_get_stage (actor); - /* Start off by treating all windows as completely unobscured, so damage anywhere - * in a window queues redraws, but confine it more below. */ - clutter_actor_iter_init (&iter, actor); - while (clutter_actor_iter_next (&iter, &child)) - { - if (META_IS_WINDOW_ACTOR (child)) - { - MetaWindowActor *window_actor = META_WINDOW_ACTOR (child); - meta_window_actor_set_unobscured_region (window_actor, NULL); - } - } - /* Normally we expect an actor to be drawn at it's position on the screen. * However, if we're inside the paint of a ClutterClone, that won't be the * case and we need to compensate. We look at the position of the window From f6db756326e514f4ba02f4e0deb1c435f93ff01e Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 5 Feb 2014 14:06:32 -0500 Subject: [PATCH 469/889] shaped-texture: Move unobscured_region processing here We want to remove a bunch of auxilliary duties from the MetaWindowActor and MetaSurfaceActor, including some details of how culling is done. Move the unobscured region culling code to the MetaShapedTexture, which helps the actor become "more independent". https://bugzilla.gnome.org/show_bug.cgi?id=720631 --- src/compositor/meta-shaped-texture-private.h | 3 + src/compositor/meta-shaped-texture.c | 102 +++++++++++++++++-- src/compositor/meta-surface-actor.c | 31 +++--- src/compositor/meta-surface-actor.h | 11 +- src/compositor/meta-window-actor.c | 65 ++---------- src/meta/meta-shaped-texture.h | 3 +- src/wayland/meta-wayland-surface.c | 6 +- 7 files changed, 127 insertions(+), 94 deletions(-) diff --git a/src/compositor/meta-shaped-texture-private.h b/src/compositor/meta-shaped-texture-private.h index 18d61a728..48ae0dfbd 100644 --- a/src/compositor/meta-shaped-texture-private.h +++ b/src/compositor/meta-shaped-texture-private.h @@ -32,5 +32,8 @@ ClutterActor *meta_shaped_texture_new (void); void meta_shaped_texture_set_texture (MetaShapedTexture *stex, CoglTexture *texture); +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 14248771a..379683351 100644 --- a/src/compositor/meta-shaped-texture.c +++ b/src/compositor/meta-shaped-texture.c @@ -73,10 +73,15 @@ struct _MetaShapedTexturePrivate CoglTexture *texture; CoglTexture *mask_texture; - cairo_region_t *clip_region; cairo_region_t *input_shape_region; + + /* The region containing only fully opaque pixels */ cairo_region_t *opaque_region; + /* MetaCullable regions, see that documentation for more details */ + cairo_region_t *clip_region; + cairo_region_t *unobscured_region; + guint tex_width, tex_height; guint create_mipmaps : 1; @@ -113,6 +118,21 @@ meta_shaped_texture_init (MetaShapedTexture *self) priv->create_mipmaps = TRUE; } +static void +set_unobscured_region (MetaShapedTexture *self, + cairo_region_t *unobscured_region) +{ + MetaShapedTexturePrivate *priv = self->priv; + + g_clear_pointer (&priv->unobscured_region, (GDestroyNotify) cairo_region_destroy); + if (unobscured_region) + { + cairo_rectangle_int_t bounds = { 0, 0, priv->tex_width, priv->tex_height }; + priv->unobscured_region = cairo_region_copy (unobscured_region); + cairo_region_intersect_rectangle (priv->unobscured_region, &bounds); + } +} + static void set_clip_region (MetaShapedTexture *self, cairo_region_t *clip_region) @@ -138,6 +158,7 @@ meta_shaped_texture_dispose (GObject *object) g_clear_pointer (&priv->opaque_region, cairo_region_destroy); meta_shaped_texture_set_mask_texture (self, NULL); + set_unobscured_region (self, NULL); set_clip_region (self, NULL); G_OBJECT_CLASS (meta_shaped_texture_parent_class)->dispose (object); @@ -546,10 +567,37 @@ meta_shaped_texture_get_preferred_height (ClutterActor *self, } static gboolean -meta_shaped_texture_get_paint_volume (ClutterActor *self, +meta_shaped_texture_get_paint_volume (ClutterActor *actor, ClutterPaintVolume *volume) { - return clutter_paint_volume_set_from_allocation (volume, self); + MetaShapedTexture *self = META_SHAPED_TEXTURE (actor); + cairo_rectangle_int_t unobscured_bounds; + + if (!clutter_paint_volume_set_from_allocation (volume, actor)) + return FALSE; + + if (meta_shaped_texture_get_unobscured_bounds (self, &unobscured_bounds)) + { + ClutterVertex origin; + cairo_rectangle_int_t bounds; + + /* I hate ClutterPaintVolume so much... */ + clutter_paint_volume_get_origin (volume, &origin); + bounds.x = origin.x; + bounds.y = origin.y; + bounds.width = clutter_paint_volume_get_width (volume); + bounds.height = clutter_paint_volume_get_height (volume); + + gdk_rectangle_intersect (&bounds, &unobscured_bounds, &bounds); + + origin.x = bounds.x; + origin.y = bounds.y; + clutter_paint_volume_set_origin (volume, &origin); + clutter_paint_volume_set_width (volume, bounds.width); + clutter_paint_volume_set_height (volume, bounds.height); + } + + return TRUE; } void @@ -594,6 +642,41 @@ meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex, clutter_actor_queue_redraw (CLUTTER_ACTOR (stex)); } +static cairo_region_t * +effective_unobscured_region (MetaShapedTexture *self) +{ + MetaShapedTexturePrivate *priv = self->priv; + + return clutter_actor_has_mapped_clones (CLUTTER_ACTOR (self)) ? NULL : priv->unobscured_region; +} + +gboolean +meta_shaped_texture_get_unobscured_bounds (MetaShapedTexture *self, + cairo_rectangle_int_t *unobscured_bounds) +{ + cairo_region_t *unobscured_region = effective_unobscured_region (self); + + if (unobscured_region) + { + cairo_region_get_extents (unobscured_region, unobscured_bounds); + return TRUE; + } + else + return FALSE; +} + +gboolean +meta_shaped_texture_is_obscured (MetaShapedTexture *self) +{ + MetaShapedTexturePrivate *priv = self->priv; + cairo_region_t *unobscured_region = effective_unobscured_region (self); + + if (unobscured_region) + return cairo_region_is_empty (unobscured_region); + else + return FALSE; +} + /** * meta_shaped_texture_update_area: * @stex: #MetaShapedTexture @@ -601,14 +684,9 @@ meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex, * @y: the y coordinate of the damaged area * @width: the width of the damaged area * @height: the height of the damaged area - * @unobscured_region: The unobscured region of the window or %NULL if - * there is no valid one (like when the actor is transformed or - * has a mapped clone) * * Repairs the damaged area indicated by @x, @y, @width and @height - * and queues a redraw for the intersection @unobscured_region and - * the damage area. If @unobscured_region is %NULL a redraw will always - * get queued. + * and potentially queues a redraw. * * Return value: Whether a redraw have been queued or not */ @@ -617,10 +695,10 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex, int x, int y, int width, - int height, - cairo_region_t *unobscured_region) + int height) { MetaShapedTexturePrivate *priv; + cairo_region_t *unobscured_region; const cairo_rectangle_int_t clip = { x, y, width, height }; priv = stex->priv; @@ -630,6 +708,7 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex, meta_texture_tower_update_area (priv->paint_tower, x, y, width, height); + unobscured_region = effective_unobscured_region (stex); if (unobscured_region) { cairo_region_t *intersection; @@ -857,6 +936,7 @@ meta_shaped_texture_cull_out (MetaCullable *cullable, MetaShapedTexture *self = META_SHAPED_TEXTURE (cullable); MetaShapedTexturePrivate *priv = self->priv; + set_unobscured_region (self, unobscured_region); set_clip_region (self, clip_region); if (clutter_actor_get_paint_opacity (CLUTTER_ACTOR (self)) == 0xff) diff --git a/src/compositor/meta-surface-actor.c b/src/compositor/meta-surface-actor.c index 37b87b03a..541094cff 100644 --- a/src/compositor/meta-surface-actor.c +++ b/src/compositor/meta-surface-actor.c @@ -31,6 +31,14 @@ static void cullable_iface_init (MetaCullableInterface *iface); G_DEFINE_TYPE_WITH_CODE (MetaSurfaceActor, meta_surface_actor, CLUTTER_TYPE_ACTOR, G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init)); +gboolean +meta_surface_actor_get_unobscured_bounds (MetaSurfaceActor *self, + cairo_rectangle_int_t *unobscured_bounds) +{ + MetaSurfaceActorPrivate *priv = self->priv; + return meta_shaped_texture_get_unobscured_bounds (priv->texture, unobscured_bounds); +} + static void meta_surface_actor_class_init (MetaSurfaceActorClass *klass) { @@ -109,18 +117,13 @@ update_area (MetaSurfaceActor *self, } gboolean -meta_surface_actor_damage_all (MetaSurfaceActor *self, - cairo_region_t *unobscured_region) +meta_surface_actor_damage_all (MetaSurfaceActor *self) { MetaSurfaceActorPrivate *priv = self->priv; CoglTexture *texture = meta_shaped_texture_get_texture (priv->texture); update_area (self, 0, 0, cogl_texture_get_width (texture), cogl_texture_get_height (texture)); - return meta_shaped_texture_update_area (priv->texture, - 0, 0, - cogl_texture_get_width (texture), - cogl_texture_get_height (texture), - unobscured_region); + return meta_shaped_texture_update_area (priv->texture, 0, 0, cogl_texture_get_width (texture), cogl_texture_get_height (texture)); } gboolean @@ -128,15 +131,19 @@ meta_surface_actor_damage_area (MetaSurfaceActor *self, int x, int y, int width, - int height, - cairo_region_t *unobscured_region) + int height) { MetaSurfaceActorPrivate *priv = self->priv; update_area (self, x, y, width, height); - return meta_shaped_texture_update_area (priv->texture, - x, y, width, height, - unobscured_region); + return meta_shaped_texture_update_area (priv->texture, x, y, width, height); +} + +gboolean +meta_surface_actor_is_obscured (MetaSurfaceActor *self) +{ + MetaSurfaceActorPrivate *priv = self->priv; + return meta_shaped_texture_is_obscured (priv->texture); } void diff --git a/src/compositor/meta-surface-actor.h b/src/compositor/meta-surface-actor.h index 484877b73..fa7f0c307 100644 --- a/src/compositor/meta-surface-actor.h +++ b/src/compositor/meta-surface-actor.h @@ -43,15 +43,16 @@ cairo_surface_t *meta_surface_actor_get_image (MetaSurfaceActor *self, MetaShapedTexture *meta_surface_actor_get_texture (MetaSurfaceActor *self); -gboolean meta_surface_actor_damage_all (MetaSurfaceActor *self, - cairo_region_t *unobscured_region); - +gboolean meta_surface_actor_damage_all (MetaSurfaceActor *self); gboolean meta_surface_actor_damage_area (MetaSurfaceActor *self, int x, int y, int width, - int height, - cairo_region_t *unobscured_region); + int height); + +gboolean meta_surface_actor_is_obscured (MetaSurfaceActor *self); +gboolean meta_surface_actor_get_unobscured_bounds (MetaSurfaceActor *self, + cairo_rectangle_int_t *unobscured_bounds); void meta_surface_actor_set_texture (MetaSurfaceActor *self, CoglTexture *texture); diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 97654f034..60c22e318 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -72,9 +72,6 @@ struct _MetaWindowActorPrivate /* The region we should clip to when painting the shadow */ cairo_region_t *shadow_clip; - /* The region that is visible, used to optimize out redraws */ - cairo_region_t *unobscured_region; - guint send_frame_messages_timer; gint64 frame_drawn_time; @@ -425,7 +422,6 @@ meta_window_actor_dispose (GObject *object) priv->send_frame_messages_timer = 0; } - g_clear_pointer (&priv->unobscured_region, cairo_region_destroy); g_clear_pointer (&priv->shape_region, cairo_region_destroy); g_clear_pointer (&priv->shadow_clip, cairo_region_destroy); @@ -696,7 +692,7 @@ meta_window_actor_get_paint_volume (ClutterActor *actor, { MetaWindowActor *self = META_WINDOW_ACTOR (actor); MetaWindowActorPrivate *priv = self->priv; - cairo_rectangle_int_t bounds; + cairo_rectangle_int_t unobscured_bounds, bounds; gboolean appears_focused = meta_window_appears_focused (priv->window); ClutterVertex origin; @@ -721,12 +717,8 @@ meta_window_actor_get_paint_volume (ClutterActor *actor, gdk_rectangle_union (&bounds, &shadow_bounds, &bounds); } - if (priv->unobscured_region && !clutter_actor_has_mapped_clones (actor)) - { - cairo_rectangle_int_t unobscured_bounds; - cairo_region_get_extents (priv->unobscured_region, &unobscured_bounds); - gdk_rectangle_intersect (&bounds, &unobscured_bounds, &bounds); - } + if (meta_surface_actor_get_unobscured_bounds (priv->surface, &unobscured_bounds)) + gdk_rectangle_intersect (&bounds, &unobscured_bounds, &bounds); origin.x = bounds.x; origin.y = bounds.y; @@ -925,7 +917,6 @@ static void meta_window_actor_damage_all (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; - cairo_region_t *unobscured_region; gboolean redraw_queued; if (!priv->needs_damage_all) @@ -934,11 +925,7 @@ meta_window_actor_damage_all (MetaWindowActor *self) if (!priv->mapped || priv->needs_pixmap) return; - unobscured_region = - clutter_actor_has_mapped_clones (CLUTTER_ACTOR (priv->surface)) - ? NULL : priv->unobscured_region; - - redraw_queued = meta_surface_actor_damage_all (priv->surface, unobscured_region); + redraw_queued = meta_surface_actor_damage_all (priv->surface); priv->repaint_scheduled = priv->repaint_scheduled || redraw_queued; priv->needs_damage_all = FALSE; } @@ -996,17 +983,7 @@ meta_window_actor_queue_frame_drawn (MetaWindowActor *self, if (!priv->repaint_scheduled) { - gboolean is_obscured = FALSE; - - /* Find out whether the window is completly obscured */ - if (priv->unobscured_region) - { - cairo_region_t *unobscured_window_region; - unobscured_window_region = cairo_region_copy (priv->shape_region); - cairo_region_intersect (unobscured_window_region, priv->unobscured_region); - is_obscured = cairo_region_is_empty (unobscured_window_region); - cairo_region_destroy (unobscured_window_region); - } + gboolean is_obscured = meta_surface_actor_is_obscured (priv->surface); /* A frame was marked by the client without actually doing any * damage or any unobscured, or while we had the window frozen @@ -1698,30 +1675,6 @@ see_region (cairo_region_t *region, } #endif -/** - * meta_window_actor_set_unobscured_region: - * @self: a #MetaWindowActor - * @unobscured_region: the region of the screen that isn't completely - * obscured. - * - * Provides a hint as to what areas of the window need to queue - * redraws when damaged. Regions not in @unobscured_region are completely obscured. - */ -static void -meta_window_actor_set_unobscured_region (MetaWindowActor *self, - cairo_region_t *unobscured_region) -{ - MetaWindowActorPrivate *priv = self->priv; - - if (priv->unobscured_region) - cairo_region_destroy (priv->unobscured_region); - - if (unobscured_region) - priv->unobscured_region = cairo_region_copy (unobscured_region); - else - priv->unobscured_region = NULL; -} - /** * meta_window_actor_set_clip_region_beneath: * @self: a #MetaWindowActor @@ -1772,7 +1725,6 @@ meta_window_actor_cull_out (MetaCullable *cullable, if (priv->unredirected) return; - meta_window_actor_set_unobscured_region (self, unobscured_region); meta_cullable_cull_out_children (cullable, unobscured_region, clip_region); meta_window_actor_set_clip_region_beneath (self, clip_region); } @@ -1949,7 +1901,6 @@ meta_window_actor_process_x11_damage (MetaWindowActor *self, MetaWindowActorPrivate *priv = self->priv; MetaCompScreen *info = meta_screen_get_compositor_data (priv->screen); gboolean redraw_queued; - cairo_region_t *unobscured_region; priv->received_x11_damage = TRUE; @@ -1997,15 +1948,11 @@ meta_window_actor_process_x11_damage (MetaWindowActor *self, if (!priv->mapped || priv->needs_pixmap) return; - unobscured_region = - clutter_actor_has_mapped_clones (CLUTTER_ACTOR (priv->surface)) - ? NULL : priv->unobscured_region; redraw_queued = meta_surface_actor_damage_area (priv->surface, event->area.x, event->area.y, event->area.width, - event->area.height, - unobscured_region); + event->area.height); priv->repaint_scheduled = priv->repaint_scheduled || redraw_queued; } diff --git a/src/meta/meta-shaped-texture.h b/src/meta/meta-shaped-texture.h index 9eea4b8d9..b0870bf95 100644 --- a/src/meta/meta-shaped-texture.h +++ b/src/meta/meta-shaped-texture.h @@ -69,8 +69,7 @@ gboolean meta_shaped_texture_update_area (MetaShapedTexture *stex, int x, int y, int width, - int height, - cairo_region_t *unobscured_region); + int height); CoglTexture * meta_shaped_texture_get_texture (MetaShapedTexture *stex); diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 909d62425..c24645e73 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -115,11 +115,7 @@ surface_process_damage (MetaWaylandSurface *surface, cairo_rectangle_int_t rect; cairo_region_get_rectangle (region, i, &rect); meta_surface_actor_damage_area (surface->surface_actor, - rect.x, - rect.y, - rect.width, - rect.height, - NULL); + rect.x, rect.y, rect.width, rect.height); } } From a8336669a3bba4bd3ffeeccff6849260c766ebbb Mon Sep 17 00:00:00 2001 From: Rico Tzschichholz Date: Wed, 5 Feb 2014 22:50:34 +0100 Subject: [PATCH 470/889] shaped-texture: Fix unused variable warning (cherry picked from commit 101a13c86daaea0a6cd0b7421f7a186fbf4ca3f9) --- src/compositor/meta-shaped-texture.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c index 379683351..ae46b34d2 100644 --- a/src/compositor/meta-shaped-texture.c +++ b/src/compositor/meta-shaped-texture.c @@ -668,7 +668,6 @@ meta_shaped_texture_get_unobscured_bounds (MetaShapedTexture *self, gboolean meta_shaped_texture_is_obscured (MetaShapedTexture *self) { - MetaShapedTexturePrivate *priv = self->priv; cairo_region_t *unobscured_region = effective_unobscured_region (self); if (unobscured_region) From 0ce64e46e89a51dd563dd0dd2ce016bd3649fa77 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 3 Feb 2014 19:23:42 -0500 Subject: [PATCH 471/889] build: Don't build client-protocols for things We don't use these. --- .gitignore | 3 --- src/Makefile.am | 8 +------- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index ae4d6b01b..ba75840b6 100644 --- a/.gitignore +++ b/.gitignore @@ -79,13 +79,10 @@ src/meta-dbus-xrandr.[ch] src/meta-dbus-idle-monitor.[ch] src/mutter-plugins.pc src/wayland/gtk-shell-protocol.c -src/wayland/gtk-shell-client-protocol.h src/wayland/gtk-shell-server-protocol.h src/wayland/xdg-shell-protocol.c -src/wayland/xdg-shell-client-protocol.h src/wayland/xdg-shell-server-protocol.h src/wayland/xserver-protocol.c -src/wayland/xserver-client-protocol.h src/wayland/xserver-server-protocol.h doc/reference/*.args doc/reference/*.bak diff --git a/src/Makefile.am b/src/Makefile.am index 53f6f7af4..89d252107 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -42,13 +42,10 @@ mutter_built_sources = \ mutter-enum-types.c \ wayland/gtk-shell-protocol.c \ wayland/gtk-shell-server-protocol.h \ - wayland/gtk-shell-client-protocol.h \ wayland/xdg-shell-protocol.c \ wayland/xdg-shell-server-protocol.h \ - wayland/xdg-shell-client-protocol.h \ wayland/xserver-protocol.c \ - wayland/xserver-server-protocol.h \ - wayland/xserver-client-protocol.h + wayland/xserver-server-protocol.h libmutter_wayland_la_SOURCES = \ core/async-getprop.c \ @@ -420,6 +417,3 @@ wayland/%-protocol.c : $(top_builddir)/protocol/%.xml wayland/%-server-protocol.h : $(top_builddir)/protocol/%.xml mkdir -p wayland $(AM_V_GEN)$(WAYLAND_SCANNER) server-header < $< > $@ -wayland/%-client-protocol.h : $(top_builddir)/protocol/%.xml - mkdir -p wayland - $(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@ From 856656645127f8b698a50dc17495d10c9fef26d6 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 3 Feb 2014 19:37:23 -0500 Subject: [PATCH 472/889] xwayland: Split out the XWayland stuff into its own private struct --- src/wayland/meta-wayland-keyboard.c | 2 +- src/wayland/meta-wayland-private.h | 22 ++++++---- src/wayland/meta-wayland.c | 6 +-- src/wayland/meta-xwayland-private.h | 6 ++- src/wayland/meta-xwayland.c | 68 ++++++++++++++--------------- 5 files changed, 54 insertions(+), 50 deletions(-) diff --git a/src/wayland/meta-wayland-keyboard.c b/src/wayland/meta-wayland-keyboard.c index af164241a..382922295 100644 --- a/src/wayland/meta-wayland-keyboard.c +++ b/src/wayland/meta-wayland-keyboard.c @@ -115,7 +115,7 @@ inform_clients_of_new_keymap (MetaWaylandKeyboard *keyboard, struct wl_resource *keyboard_resource; compositor = meta_wayland_compositor_get_default (); - xclient = compositor->xwayland_client; + xclient = compositor->xwayland_manager.client; wl_resource_for_each (keyboard_resource, &keyboard->resource_list) { diff --git a/src/wayland/meta-wayland-private.h b/src/wayland/meta-wayland-private.h index 7c860e165..f12fff66b 100644 --- a/src/wayland/meta-wayland-private.h +++ b/src/wayland/meta-wayland-private.h @@ -59,25 +59,31 @@ typedef struct struct wl_resource *resource; } MetaWaylandFrameCallback; +typedef struct +{ + int display_index; + char *lockfile; + int abstract_fd; + int unix_fd; + pid_t pid; + struct wl_client *client; + struct wl_resource *xserver_resource; + + GMainLoop *init_loop; +} MetaXWaylandManager; + struct _MetaWaylandCompositor { struct wl_display *wayland_display; char *display_name; struct wl_event_loop *wayland_loop; - GMainLoop *init_loop; ClutterActor *stage; GHashTable *outputs; GSource *wayland_event_source; GList *surfaces; struct wl_list frame_callbacks; - int xwayland_display_index; - char *xwayland_lockfile; - int xwayland_abstract_fd; - int xwayland_unix_fd; - pid_t xwayland_pid; - struct wl_client *xwayland_client; - struct wl_resource *xserver_resource; + MetaXWaylandManager xwayland_manager; MetaLauncher *launcher; gboolean native; diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index ac49ad99d..22de96543 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -720,12 +720,10 @@ meta_wayland_init (void) * and so EGL must be initialized by this point. */ - if (!meta_xwayland_start (compositor)) + if (!meta_xwayland_start (&compositor->xwayland_manager, compositor->wayland_display, &display_name)) g_error ("Failed to start X Wayland"); - display_name = g_strdup_printf (":%d", compositor->xwayland_display_index); set_gnome_env ("DISPLAY", display_name); - g_free (display_name); set_gnome_env ("WAYLAND_DISPLAY", compositor->display_name); } @@ -737,7 +735,7 @@ meta_wayland_finalize (void) compositor = meta_wayland_compositor_get_default (); - meta_xwayland_stop (compositor); + meta_xwayland_stop (&compositor->xwayland_manager); if (compositor->launcher) meta_launcher_free (compositor->launcher); diff --git a/src/wayland/meta-xwayland-private.h b/src/wayland/meta-xwayland-private.h index d115510a4..721debfad 100644 --- a/src/wayland/meta-xwayland-private.h +++ b/src/wayland/meta-xwayland-private.h @@ -25,12 +25,14 @@ #include gboolean -meta_xwayland_start (MetaWaylandCompositor *compositor); +meta_xwayland_start (MetaXWaylandManager *manager, + struct wl_display *display, + char **display_name_out); void meta_xwayland_complete_init (void); void -meta_xwayland_stop (MetaWaylandCompositor *compositor); +meta_xwayland_stop (MetaXWaylandManager *manager); #endif /* META_XWAYLAND_PRIVATE_H */ diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index e15e30882..89025af34 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -63,20 +63,20 @@ bind_xserver (struct wl_client *client, guint32 version, guint32 id) { - MetaWaylandCompositor *compositor = data; + MetaXWaylandManager *manager = data; /* If it's a different client than the xserver we launched, - * don't start the wm. */ - if (client != compositor->xwayland_client) + * just freeze up... */ + if (client != manager->client) return; - compositor->xserver_resource = wl_resource_create (client, &xserver_interface, - MIN (META_XSERVER_VERSION, version), id); - wl_resource_set_implementation (compositor->xserver_resource, - &xserver_implementation, compositor, NULL); + manager->xserver_resource = wl_resource_create (client, &xserver_interface, + MIN (META_XSERVER_VERSION, version), id); + wl_resource_set_implementation (manager->xserver_resource, + &xserver_implementation, manager, NULL); - xserver_send_listen_socket (compositor->xserver_resource, compositor->xwayland_abstract_fd); - xserver_send_listen_socket (compositor->xserver_resource, compositor->xwayland_unix_fd); + xserver_send_listen_socket (manager->xserver_resource, manager->abstract_fd); + xserver_send_listen_socket (manager->xserver_resource, manager->unix_fd); /* Make sure xwayland will recieve the above sockets in a finite * time before unblocking the initialization mainloop since we are @@ -88,8 +88,8 @@ bind_xserver (struct wl_client *client, * connections so we can quit the transient initialization mainloop * and unblock meta_wayland_init() to continue initializing mutter. * */ - g_main_loop_quit (compositor->init_loop); - g_clear_pointer (&compositor->init_loop, g_main_loop_unref); + g_main_loop_quit (manager->init_loop); + g_clear_pointer (&manager->init_loop, g_main_loop_unref); } static char * @@ -285,7 +285,9 @@ x_io_error (Display *display) } gboolean -meta_xwayland_start (MetaWaylandCompositor *compositor) +meta_xwayland_start (MetaXWaylandManager *manager, + struct wl_display *wl_display, + char **display_name_out) { int display = 0; char *lockfile = NULL; @@ -298,10 +300,9 @@ meta_xwayland_start (MetaWaylandCompositor *compositor) char *args[11]; GError *error; - wl_global_create (compositor->wayland_display, - &xserver_interface, + wl_global_create (wl_display, &xserver_interface, META_XSERVER_VERSION, - compositor, bind_xserver); + manager, bind_xserver); do { @@ -312,8 +313,8 @@ meta_xwayland_start (MetaWaylandCompositor *compositor) return FALSE; } - compositor->xwayland_abstract_fd = bind_to_abstract_socket (display); - if (compositor->xwayland_abstract_fd < 0) + manager->abstract_fd = bind_to_abstract_socket (display); + if (manager->abstract_fd < 0) { unlink (lockfile); @@ -326,11 +327,11 @@ meta_xwayland_start (MetaWaylandCompositor *compositor) return FALSE; } - compositor->xwayland_unix_fd = bind_to_unix_socket (display); - if (compositor->xwayland_abstract_fd < 0) + manager->unix_fd = bind_to_unix_socket (display); + if (manager->abstract_fd < 0) { unlink (lockfile); - close (compositor->xwayland_abstract_fd); + close (manager->abstract_fd); return FALSE; } @@ -338,8 +339,8 @@ meta_xwayland_start (MetaWaylandCompositor *compositor) } while (1); - compositor->xwayland_display_index = display; - compositor->xwayland_lockfile = lockfile; + manager->display_index = display; + manager->lockfile = lockfile; /* We want xwayland to be a wayland client so we make a socketpair to setup a * wayland protocol connection. */ @@ -355,8 +356,7 @@ meta_xwayland_start (MetaWaylandCompositor *compositor) env = g_environ_setenv (env, "WAYLAND_SOCKET", fd_string, TRUE); g_free (fd_string); - display_name = g_strdup_printf (":%d", - compositor->xwayland_display_index); + display_name = g_strdup_printf (":%d", manager->display_index); log_path = g_build_filename (g_get_user_cache_dir (), "xwayland.log", NULL); args[0] = XWAYLAND_PATH; @@ -387,10 +387,9 @@ meta_xwayland_start (MetaWaylandCompositor *compositor) g_message ("forked X server, pid %d\n", pid); close (sp[1]); - compositor->xwayland_client = - wl_client_create (compositor->wayland_display, sp[0]); + manager->client = wl_client_create (wl_display, sp[0]); - compositor->xwayland_pid = pid; + manager->pid = pid; g_child_watch_add (pid, xserver_died, NULL); } else @@ -405,9 +404,10 @@ meta_xwayland_start (MetaWaylandCompositor *compositor) /* We need to run a mainloop until we know xwayland has a binding * for our xserver interface at which point we can assume it's * ready to start accepting connections. */ - compositor->init_loop = g_main_loop_new (NULL, FALSE); + manager->init_loop = g_main_loop_new (NULL, FALSE); + g_main_loop_run (manager->init_loop); - g_main_loop_run (compositor->init_loop); + *display_name_out = display_name; return TRUE; } @@ -425,16 +425,14 @@ meta_xwayland_complete_init (void) } void -meta_xwayland_stop (MetaWaylandCompositor *compositor) +meta_xwayland_stop (MetaXWaylandManager *manager) { char path[256]; - snprintf (path, sizeof path, "/tmp/.X%d-lock", - compositor->xwayland_display_index); + snprintf (path, sizeof path, "/tmp/.X%d-lock", manager->display_index); unlink (path); - snprintf (path, sizeof path, "/tmp/.X11-unix/X%d", - compositor->xwayland_display_index); + snprintf (path, sizeof path, "/tmp/.X11-unix/X%d", manager->display_index); unlink (path); - unlink (compositor->xwayland_lockfile); + unlink (manager->lockfile); } From d694260ad2dceeb498ff15268a75db656f5360f9 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 7 Feb 2014 19:26:35 -0500 Subject: [PATCH 473/889] xwayland: Fix xwayland Don't give us a freed pointer here. --- src/wayland/meta-wayland-private.h | 1 + src/wayland/meta-wayland.c | 6 ++---- src/wayland/meta-xwayland-private.h | 5 ++--- src/wayland/meta-xwayland.c | 13 ++++--------- 4 files changed, 9 insertions(+), 16 deletions(-) diff --git a/src/wayland/meta-wayland-private.h b/src/wayland/meta-wayland-private.h index f12fff66b..cba6ed397 100644 --- a/src/wayland/meta-wayland-private.h +++ b/src/wayland/meta-wayland-private.h @@ -68,6 +68,7 @@ typedef struct pid_t pid; struct wl_client *client; struct wl_resource *xserver_resource; + char *display_name; GMainLoop *init_loop; } MetaXWaylandManager; diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index 22de96543..254b4d09b 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -623,7 +623,6 @@ meta_wayland_init (void) { MetaWaylandCompositor *compositor = &_meta_wayland_compositor; MetaMonitorManager *monitors; - char *display_name; int drm_fd; memset (compositor, 0, sizeof (MetaWaylandCompositor)); @@ -720,11 +719,10 @@ meta_wayland_init (void) * and so EGL must be initialized by this point. */ - if (!meta_xwayland_start (&compositor->xwayland_manager, compositor->wayland_display, &display_name)) + if (!meta_xwayland_start (&compositor->xwayland_manager, compositor->wayland_display)) g_error ("Failed to start X Wayland"); - set_gnome_env ("DISPLAY", display_name); - + set_gnome_env ("DISPLAY", compositor->xwayland_manager.display_name); set_gnome_env ("WAYLAND_DISPLAY", compositor->display_name); } diff --git a/src/wayland/meta-xwayland-private.h b/src/wayland/meta-xwayland-private.h index 721debfad..83b2986d3 100644 --- a/src/wayland/meta-xwayland-private.h +++ b/src/wayland/meta-xwayland-private.h @@ -25,9 +25,8 @@ #include gboolean -meta_xwayland_start (MetaXWaylandManager *manager, - struct wl_display *display, - char **display_name_out); +meta_xwayland_start (MetaXWaylandManager *manager, + struct wl_display *display); void meta_xwayland_complete_init (void); diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index 89025af34..753af7885 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -285,9 +285,8 @@ x_io_error (Display *display) } gboolean -meta_xwayland_start (MetaXWaylandManager *manager, - struct wl_display *wl_display, - char **display_name_out) +meta_xwayland_start (MetaXWaylandManager *manager, + struct wl_display *wl_display) { int display = 0; char *lockfile = NULL; @@ -295,7 +294,6 @@ meta_xwayland_start (MetaXWaylandManager *manager, pid_t pid; char **env; char *fd_string; - char *display_name; char *log_path; char *args[11]; GError *error; @@ -356,11 +354,11 @@ meta_xwayland_start (MetaXWaylandManager *manager, env = g_environ_setenv (env, "WAYLAND_SOCKET", fd_string, TRUE); g_free (fd_string); - display_name = g_strdup_printf (":%d", manager->display_index); + manager->display_name = g_strdup_printf (":%d", manager->display_index); log_path = g_build_filename (g_get_user_cache_dir (), "xwayland.log", NULL); args[0] = XWAYLAND_PATH; - args[1] = display_name; + args[1] = manager->display_name; args[2] = "-wayland"; args[3] = "-rootless"; args[4] = "-retro"; @@ -398,7 +396,6 @@ meta_xwayland_start (MetaXWaylandManager *manager, } g_strfreev (env); - g_free (display_name); g_free (log_path); /* We need to run a mainloop until we know xwayland has a binding @@ -407,8 +404,6 @@ meta_xwayland_start (MetaXWaylandManager *manager, manager->init_loop = g_main_loop_new (NULL, FALSE); g_main_loop_run (manager->init_loop); - *display_name_out = display_name; - return TRUE; } From 912a0abd26faec0ec962892e0ead7180e1452ebc Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 7 Feb 2014 17:23:17 -0500 Subject: [PATCH 474/889] wayland: Remove edges This is an upstream change to xdg-shell. --- protocol/xdg-shell.xml | 1 - src/core/window.c | 4 +--- src/wayland/meta-wayland-surface.c | 5 ++--- src/wayland/meta-wayland-surface.h | 3 +-- 4 files changed, 4 insertions(+), 9 deletions(-) diff --git a/protocol/xdg-shell.xml b/protocol/xdg-shell.xml index 4e5cff8df..851b2cebb 100644 --- a/protocol/xdg-shell.xml +++ b/protocol/xdg-shell.xml @@ -230,7 +230,6 @@ in surface local coordinates. - diff --git a/src/core/window.c b/src/core/window.c index ee29fd4b2..984b3508a 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -4741,9 +4741,7 @@ meta_window_move_resize_internal (MetaWindow *window, need_resize_client = TRUE; meta_wayland_surface_configure_notify (window->surface, new_rect.width, - new_rect.height, - (dx != 0 ? WL_SHELL_SURFACE_RESIZE_LEFT : 0) | - (dy != 0 ? WL_SHELL_SURFACE_RESIZE_TOP : 0)); + new_rect.height); } else { diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index c24645e73..2920e2a87 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -1434,12 +1434,11 @@ meta_wayland_init_shell (MetaWaylandCompositor *compositor) void meta_wayland_surface_configure_notify (MetaWaylandSurface *surface, int new_width, - int new_height, - int edges) + int new_height) { if (surface->xdg_surface.resource) xdg_surface_send_configure (surface->xdg_surface.resource, - edges, new_width, new_height); + new_width, new_height); } void diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h index 3e1b29737..172201386 100644 --- a/src/wayland/meta-wayland-surface.h +++ b/src/wayland/meta-wayland-surface.h @@ -108,8 +108,7 @@ MetaWaylandSurface *meta_wayland_surface_create (MetaWaylandCompositor *composit guint32 version); void meta_wayland_surface_configure_notify (MetaWaylandSurface *surface, int width, - int height, - int edges); + int height); void meta_wayland_surface_focused_set (MetaWaylandSurface *surface); void meta_wayland_surface_focused_unset (MetaWaylandSurface *surface); From 0c213c8feee6c11eef19fb316f3514e2a9cb0f27 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 7 Feb 2014 17:28:33 -0500 Subject: [PATCH 475/889] wayland: Add support for the delete event --- protocol/xdg-shell.xml | 13 +++++++++++ src/core/delete.c | 35 +++++++++++++++++++----------- src/wayland/meta-wayland-surface.c | 7 ++++++ src/wayland/meta-wayland-surface.h | 1 + 4 files changed, 43 insertions(+), 13 deletions(-) diff --git a/protocol/xdg-shell.xml b/protocol/xdg-shell.xml index 851b2cebb..5c21f4ebc 100644 --- a/protocol/xdg-shell.xml +++ b/protocol/xdg-shell.xml @@ -373,6 +373,19 @@ decorations should be updated accordingly. + + + + The delete event is sent by the compositor when the user + wants the surface to be closed. This should be equivalent to + the user clicking the close button in client-side decorations, + if your application has any... + + This is only a request that the user intends to close your + window. The client may choose to ignore this request, or show + a dialog to ask the user to save their data... + + diff --git a/src/core/delete.c b/src/core/delete.c index 437becf1e..a24c1b97e 100644 --- a/src/core/delete.c +++ b/src/core/delete.c @@ -37,6 +37,8 @@ #include #include +#include "meta-wayland-surface.h" + static void meta_window_present_delete_dialog (MetaWindow *window, guint32 timestamp); @@ -141,24 +143,31 @@ void meta_window_delete (MetaWindow *window, guint32 timestamp) { - meta_error_trap_push (window->display); - if (window->delete_window) + if (window->client_type == META_WINDOW_CLIENT_TYPE_X11) { - meta_topic (META_DEBUG_WINDOW_OPS, - "Deleting %s with delete_window request\n", - window->desc); - meta_window_send_icccm_message (window, - window->display->atom_WM_DELETE_WINDOW, - timestamp); + meta_error_trap_push (window->display); + if (window->delete_window) + { + meta_topic (META_DEBUG_WINDOW_OPS, + "Deleting %s with delete_window request\n", + window->desc); + meta_window_send_icccm_message (window, + window->display->atom_WM_DELETE_WINDOW, + timestamp); + } + else + { + meta_topic (META_DEBUG_WINDOW_OPS, + "Deleting %s with explicit kill\n", + window->desc); + XKillClient (window->display->xdisplay, window->xwindow); + } + meta_error_trap_pop (window->display); } else { - meta_topic (META_DEBUG_WINDOW_OPS, - "Deleting %s with explicit kill\n", - window->desc); - XKillClient (window->display->xdisplay, window->xwindow); + meta_wayland_surface_delete (window->surface); } - meta_error_trap_pop (window->display); meta_window_check_alive (window, timestamp); diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 2920e2a87..cd7229813 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -1464,3 +1464,10 @@ meta_wayland_surface_ping (MetaWaylandSurface *surface, else if (surface->xdg_popup.resource) xdg_popup_send_ping (surface->xdg_popup.resource, timestamp); } + +void +meta_wayland_surface_delete (MetaWaylandSurface *surface) +{ + if (surface->xdg_surface.resource) + xdg_surface_send_delete (surface->xdg_surface.resource); +} diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h index 172201386..c87854bb1 100644 --- a/src/wayland/meta-wayland-surface.h +++ b/src/wayland/meta-wayland-surface.h @@ -115,5 +115,6 @@ void meta_wayland_surface_focused_unset (MetaWaylandSurface *surf void meta_wayland_surface_ping (MetaWaylandSurface *surface, guint32 serial); +void meta_wayland_surface_delete (MetaWaylandSurface *surface); #endif From def5e86673ba423a84d0a415ab93d135a76a8259 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 7 Feb 2014 17:29:35 -0500 Subject: [PATCH 476/889] wayland: Add support for the set_margin request --- protocol/xdg-shell.xml | 26 ++++++++++++++++++++++++++ src/core/window-private.h | 3 +++ src/core/window-props.c | 18 +++++++----------- src/core/window.c | 17 +++++++++++++++++ src/wayland/meta-wayland-surface.c | 21 +++++++++++++++++++++ 5 files changed, 74 insertions(+), 11 deletions(-) diff --git a/protocol/xdg-shell.xml b/protocol/xdg-shell.xml index 5c21f4ebc..f0d04aa34 100644 --- a/protocol/xdg-shell.xml +++ b/protocol/xdg-shell.xml @@ -124,6 +124,32 @@ + + + This tells the compositor what the visible size of the window + should be, so it can use it to determine what borders to use for + constrainment and alignment. + + CSD often has invisible areas for decoration purposes, like drop + shadows. These "shadow" drawings need to be subtracted out of the + normal boundaries of the window when computing where to place + windows (e.g. to set this window so it's centered on top of another, + or to put it to the left or right of the screen.) + + This value should change as little as possible at runtime, to + prevent flicker. + + This value is also ignored when the window is maximized or + fullscreen, and assumed to be 0. + + If never called, this value is assumed to be 0. + + + + + + + Set a short title for the surface. diff --git a/src/core/window-private.h b/src/core/window-private.h index c18b6a99a..27ffc9298 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -733,6 +733,9 @@ void meta_window_set_transient_for (MetaWindow *window, void meta_window_set_opacity (MetaWindow *window, guint opacity); +void meta_window_set_custom_frame_extents (MetaWindow *window, + GtkBorder *extents); + void meta_window_handle_enter (MetaWindow *window, guint32 timestamp, guint root_x, diff --git a/src/core/window-props.c b/src/core/window-props.c index 6bb44e934..eabdcfae4 100644 --- a/src/core/window-props.c +++ b/src/core/window-props.c @@ -303,22 +303,18 @@ reload_gtk_frame_extents (MetaWindow *window, } else { - GtkBorder *extents = &window->custom_frame_extents; - - window->has_custom_frame_extents = TRUE; - extents->left = (int)value->v.cardinal_list.cardinals[0]; - extents->right = (int)value->v.cardinal_list.cardinals[1]; - extents->top = (int)value->v.cardinal_list.cardinals[2]; - extents->bottom = (int)value->v.cardinal_list.cardinals[3]; + GtkBorder extents; + extents.left = (int)value->v.cardinal_list.cardinals[0]; + extents.right = (int)value->v.cardinal_list.cardinals[1]; + extents.top = (int)value->v.cardinal_list.cardinals[2]; + extents.bottom = (int)value->v.cardinal_list.cardinals[3]; + meta_window_set_custom_frame_extents (window, &extents); } } else { - window->has_custom_frame_extents = FALSE; + meta_window_set_custom_frame_extents (window, NULL); } - - if (!initial) - meta_window_queue(window, META_QUEUE_MOVE_RESIZE); } static void diff --git a/src/core/window.c b/src/core/window.c index 984b3508a..0edfbcbfd 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -10882,3 +10882,20 @@ meta_window_get_toplevel_xwindow (MetaWindow *window) { return window->frame ? window->frame->xwindow : window->xwindow; } + +void +meta_window_set_custom_frame_extents (MetaWindow *window, + GtkBorder *extents) +{ + if (extents) + { + window->has_custom_frame_extents = TRUE; + window->custom_frame_extents = *extents; + } + else + { + window->has_custom_frame_extents = FALSE; + } + + meta_window_queue (window, META_QUEUE_MOVE_RESIZE); +} diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index cd7229813..2e5201e44 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -720,6 +720,26 @@ xdg_surface_set_transient_for (struct wl_client *client, meta_window_set_transient_for (surface->window, transient_for); } +static void +xdg_surface_set_margin (struct wl_client *client, + struct wl_resource *resource, + int32_t left_margin, + int32_t right_margin, + int32_t top_margin, + int32_t bottom_margin) +{ + MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface); + GtkBorder extents; + + extents.left = left_margin; + extents.right = right_margin; + extents.top = top_margin; + extents.bottom = bottom_margin; + + meta_window_set_custom_frame_extents (surface->window, &extents); +} + static void xdg_surface_set_title (struct wl_client *client, struct wl_resource *resource, @@ -901,6 +921,7 @@ xdg_surface_set_minimized (struct wl_client *client, static const struct xdg_surface_interface meta_wayland_xdg_surface_interface = { xdg_surface_destroy, xdg_surface_set_transient_for, + xdg_surface_set_margin, xdg_surface_set_title, xdg_surface_set_app_id, xdg_surface_pong, From 6561b53346b0828823638527002fc34936691be4 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 7 Feb 2014 19:52:34 -0500 Subject: [PATCH 477/889] display: Clean up screen management code --- src/core/display.c | 32 +++++++++++--------------------- 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/src/core/display.c b/src/core/display.c index 37aab062b..e5dd43f66 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -808,12 +808,7 @@ meta_display_open (void) screen = meta_screen_new (the_display, i, timestamp); - if (screen) - screens = g_slist_prepend (screens, screen); - - the_display->screens = screens; - - if (screens == NULL) + if (!screen) { /* This would typically happen because all the screens already * have window managers. @@ -822,24 +817,19 @@ meta_display_open (void) return FALSE; } + screens = g_slist_prepend (screens, screen); + + the_display->screens = screens; + enable_compositor (the_display); - - /* Now manage all existing windows */ - tmp = the_display->screens; - while (tmp != NULL) - { - MetaScreen *screen = tmp->data; - meta_screen_create_guard_window (screen); + meta_screen_create_guard_window (screen); - /* We know that if mutter is running as a Wayland compositor, - * we start out with no windows. - */ - if (!meta_is_wayland_compositor ()) - meta_screen_manage_all_windows (screen); - - tmp = tmp->next; - } + /* We know that if mutter is running as a Wayland compositor, + * we start out with no windows. + */ + if (!meta_is_wayland_compositor ()) + meta_screen_manage_all_windows (screen); { Window focus; From 0c7a7d75275dddae58918c154cb50985c0a27e5a Mon Sep 17 00:00:00 2001 From: Adel Gadllah Date: Sun, 9 Feb 2014 16:25:37 +0100 Subject: [PATCH 478/889] Disable clutter's high dpi scaling mutter needs some work to work with high dpi scaling so disable the scaling until that is fixed. https://bugzilla.gnome.org/show_bug.cgi?id=723931 --- src/core/main.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/core/main.c b/src/core/main.c index 82ae4838a..d474ef25b 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -455,6 +455,13 @@ meta_init (void) */ meta_clutter_init (); } + + /* + * XXX: We cannot handle high dpi scaling yet, so fix the scale to 1 + * for now. + */ + clutter_settings = clutter_settings_get_default (); + g_object_set (clutter_settings, "window-scaling-factor", 1, NULL); } /** From ddaae9c923849bab80dc19e3bc01d04cd810a67e Mon Sep 17 00:00:00 2001 From: Adel Gadllah Date: Sun, 9 Feb 2014 16:39:04 +0100 Subject: [PATCH 479/889] Fix build I broke it while cherry picking the last commit. --- src/core/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/main.c b/src/core/main.c index d474ef25b..4a1f5e069 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -389,7 +389,8 @@ meta_init (void) { struct sigaction act; sigset_t empty_mask; - + ClutterSettings *clutter_settings; + sigemptyset (&empty_mask); act.sa_handler = SIG_IGN; act.sa_mask = empty_mask; From 6b665534937ac82233653179e3cf449b175617e2 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sun, 9 Feb 2014 11:45:50 -0500 Subject: [PATCH 480/889] display: Remove unused variable --- src/core/display.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/display.c b/src/core/display.c index e5dd43f66..e5da0ec7f 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -388,7 +388,6 @@ meta_display_open (void) Display *xdisplay; GSList *screens; MetaScreen *screen; - GSList *tmp; int i; guint32 timestamp; From 593db0baee63c9ded0a596fc4915fb37770fd0d6 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sun, 9 Feb 2014 11:52:55 -0500 Subject: [PATCH 481/889] default: Make the map animation more friendly --- src/compositor/plugins/default.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/compositor/plugins/default.c b/src/compositor/plugins/default.c index 6728daedc..4d51b309c 100644 --- a/src/compositor/plugins/default.c +++ b/src/compositor/plugins/default.c @@ -704,15 +704,15 @@ map (MetaPlugin *plugin, MetaWindowActor *window_actor) EffectCompleteData *data = g_new0 (EffectCompleteData, 1); ActorPrivate *apriv = get_actor_private (window_actor); - clutter_actor_move_anchor_point_from_gravity (actor, - CLUTTER_GRAVITY_CENTER); - - clutter_actor_set_scale (actor, 0.0, 0.0); + clutter_actor_set_pivot_point (actor, 0.5, 0.5); + clutter_actor_set_opacity (actor, 0); + clutter_actor_set_scale (actor, 0.5, 0.5); clutter_actor_show (actor); animation = clutter_actor_animate (actor, - CLUTTER_EASE_IN_SINE, + CLUTTER_EASE_OUT_QUAD, MAP_TIMEOUT, + "opacity", 255, "scale-x", 1.0, "scale-y", 1.0, NULL); From 87b20d7f2accb523f85924fff8a32a99d8c47357 Mon Sep 17 00:00:00 2001 From: Ryan Lortie Date: Sun, 9 Feb 2014 10:56:26 -0500 Subject: [PATCH 482/889] autogen.sh: use #!/bin/sh instead of #!/bin/bash We don't have any bashisms in this file, so we may as well use sh. https://bugzilla.gnome.org/show_bug.cgi?id=722530 --- autogen.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/autogen.sh b/autogen.sh index 61a279690..79439b56a 100755 --- a/autogen.sh +++ b/autogen.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/sh # Run this to generate all the initial makefiles, etc. srcdir=`dirname $0` From 06380938d4b1bcb9636520d837c5d27c8f9f5966 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sun, 9 Feb 2014 18:23:07 -0500 Subject: [PATCH 483/889] wayland-surface: Make set_fullscreen / set_maximized and friends double-buffered --- src/wayland/meta-wayland-surface.c | 31 ++++++++++++++++++++++++++---- src/wayland/meta-wayland-surface.h | 9 +++++++++ 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 2e5201e44..96668826f 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -336,6 +336,22 @@ toplevel_surface_commit (MetaWaylandSurface *surface, meta_window_move_resize_wayland (window, new_width, new_height, pending->dx, pending->dy); } } + + if (pending->maximized.changed) + { + if (pending->maximized.value) + meta_window_maximize (surface->window, META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL); + else + meta_window_unmaximize (surface->window, META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL); + } + + if (pending->fullscreen.changed) + { + if (pending->fullscreen.value) + meta_window_make_fullscreen (surface->window); + else + meta_window_unmake_fullscreen (surface->window); + } } static void @@ -359,6 +375,9 @@ double_buffered_state_init (MetaWaylandDoubleBufferedState *state) state->buffer_destroy_listener.notify = surface_handle_pending_buffer_destroy; wl_list_init (&state->frame_callback_list); + + state->maximized.changed = FALSE; + state->fullscreen.changed = FALSE; } static void @@ -875,7 +894,8 @@ xdg_surface_set_fullscreen (struct wl_client *client, MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface); - meta_window_make_fullscreen (surface->window); + surface->pending.fullscreen.changed = TRUE; + surface->pending.fullscreen.value = TRUE; } static void @@ -885,7 +905,8 @@ xdg_surface_unset_fullscreen (struct wl_client *client, MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface); - meta_window_unmake_fullscreen (surface->window); + surface->pending.fullscreen.changed = TRUE; + surface->pending.fullscreen.value = FALSE; } static void @@ -895,7 +916,8 @@ xdg_surface_set_maximized (struct wl_client *client, MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface); - meta_window_maximize (surface->window, META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL); + surface->pending.maximized.changed = TRUE; + surface->pending.maximized.value = TRUE; } static void @@ -905,7 +927,8 @@ xdg_surface_unset_maximized (struct wl_client *client, MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface); - meta_window_unmaximize (surface->window, META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL); + surface->pending.maximized.changed = TRUE; + surface->pending.maximized.value = FALSE; } static void diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h index c87854bb1..6b0516e38 100644 --- a/src/wayland/meta-wayland-surface.h +++ b/src/wayland/meta-wayland-surface.h @@ -42,6 +42,12 @@ struct _MetaWaylandBuffer uint32_t ref_count; }; +typedef struct +{ + guint changed : 1; + guint value : 1; +} MetaWaylandStateFlag; + typedef struct { /* wl_surface.attach */ @@ -59,6 +65,9 @@ typedef struct /* wl_surface.frame */ struct wl_list frame_callback_list; + + MetaWaylandStateFlag fullscreen; + MetaWaylandStateFlag maximized; } MetaWaylandDoubleBufferedState; typedef struct From f16e9b2ee7377ae2065e53627537276aeb75cd4d Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 10 Feb 2014 14:16:06 -0500 Subject: [PATCH 484/889] wayland-surface: Make set_margin double-buffered as well --- src/wayland/meta-wayland-surface.c | 16 +++++++++------- src/wayland/meta-wayland-surface.h | 3 +++ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 96668826f..e5995d366 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -337,6 +337,9 @@ toplevel_surface_commit (MetaWaylandSurface *surface, } } + if (pending->frame_extents_changed) + meta_window_set_custom_frame_extents (surface->window, &pending->frame_extents); + if (pending->maximized.changed) { if (pending->maximized.value) @@ -376,6 +379,7 @@ double_buffered_state_init (MetaWaylandDoubleBufferedState *state) surface_handle_pending_buffer_destroy; wl_list_init (&state->frame_callback_list); + state->frame_extents_changed = FALSE; state->maximized.changed = FALSE; state->fullscreen.changed = FALSE; } @@ -749,14 +753,12 @@ xdg_surface_set_margin (struct wl_client *client, { MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface); - GtkBorder extents; - extents.left = left_margin; - extents.right = right_margin; - extents.top = top_margin; - extents.bottom = bottom_margin; - - meta_window_set_custom_frame_extents (surface->window, &extents); + surface->pending.frame_extents_changed = TRUE; + surface->pending.frame_extents.left = left_margin; + surface->pending.frame_extents.right = right_margin; + surface->pending.frame_extents.top = top_margin; + surface->pending.frame_extents.bottom = bottom_margin; } static void diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h index 6b0516e38..df725db13 100644 --- a/src/wayland/meta-wayland-surface.h +++ b/src/wayland/meta-wayland-surface.h @@ -66,6 +66,9 @@ typedef struct /* wl_surface.frame */ struct wl_list frame_callback_list; + gboolean frame_extents_changed; + GtkBorder frame_extents; + MetaWaylandStateFlag fullscreen; MetaWaylandStateFlag maximized; } MetaWaylandDoubleBufferedState; From 2be5401b1e9c77e7ad9e2d51cfbf1454ee23a18b Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Sat, 14 Dec 2013 14:22:40 +0100 Subject: [PATCH 485/889] window: fix invalid read in computing the input shape If we are reported only one rectangle in the input shape, we should not try to read more. https://bugzilla.gnome.org/show_bug.cgi?id=724257 --- src/core/window-x11.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/window-x11.c b/src/core/window-x11.c index 4866c659d..d984a59c3 100644 --- a/src/core/window-x11.c +++ b/src/core/window-x11.c @@ -377,9 +377,9 @@ meta_window_x11_update_input_region (MetaWindow *window) if (n_rects > 1 || (n_rects == 1 && (rects[0].x != x_bounding || - rects[1].y != y_bounding || - rects[2].width != w_bounding || - rects[3].height != h_bounding))) + rects[0].y != y_bounding || + rects[0].width != w_bounding || + rects[0].height != h_bounding))) region = region_create_from_x_rectangles (rects, n_rects); XFree (rects); From 0c5a6ad775632356d6c35991ebad1b04ee0b8b68 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Sat, 14 Dec 2013 14:24:27 +0100 Subject: [PATCH 486/889] window: don't set _NET_WM_FULLSCREEN_MONITORS to bogus values Prior to the DisplayConfig merge, we would set _NET_WM_FULLSCREEN_MONITORS to (unsigned)-1 when unset. After that, we would have invalid reads inside meta_screen_monitor_index_to_xinerama_index() (called with -1). The way I read the specification, the proper way to indicate that the window is back to fullscreen on all monitors is to remove the property, so do that. Also, add an assertion that meta_screne_monitor_index_to_xinerama_index() is doing the right thing. https://bugzilla.gnome.org/show_bug.cgi?id=724258 --- src/core/screen.c | 2 ++ src/core/window-x11.c | 44 +++++++++++++++++++++++++++---------------- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/src/core/screen.c b/src/core/screen.c index e8e8c56e0..c68ee10ff 100644 --- a/src/core/screen.c +++ b/src/core/screen.c @@ -389,6 +389,8 @@ int meta_screen_monitor_index_to_xinerama_index (MetaScreen *screen, int index) { + g_return_val_if_fail (index >= 0 && index < screen->n_monitor_infos, -1); + meta_screen_ensure_xinerama_indices (screen); return screen->monitor_infos[index].xinerama_index; diff --git a/src/core/window-x11.c b/src/core/window-x11.c index d984a59c3..150390a65 100644 --- a/src/core/window-x11.c +++ b/src/core/window-x11.c @@ -127,23 +127,35 @@ meta_window_x11_set_net_wm_state (MetaWindow *window) if (window->fullscreen) { - data[0] = meta_screen_monitor_index_to_xinerama_index (window->screen, - window->fullscreen_monitors[0]); - data[1] = meta_screen_monitor_index_to_xinerama_index (window->screen, - window->fullscreen_monitors[1]); - data[2] = meta_screen_monitor_index_to_xinerama_index (window->screen, - window->fullscreen_monitors[2]); - data[3] = meta_screen_monitor_index_to_xinerama_index (window->screen, - window->fullscreen_monitors[3]); + if (window->fullscreen_monitors[0] >= 0) + { + data[0] = meta_screen_monitor_index_to_xinerama_index (window->screen, + window->fullscreen_monitors[0]); + data[1] = meta_screen_monitor_index_to_xinerama_index (window->screen, + window->fullscreen_monitors[1]); + data[2] = meta_screen_monitor_index_to_xinerama_index (window->screen, + window->fullscreen_monitors[2]); + data[3] = meta_screen_monitor_index_to_xinerama_index (window->screen, + window->fullscreen_monitors[3]); - meta_verbose ("Setting _NET_WM_FULLSCREEN_MONITORS\n"); - meta_error_trap_push (window->display); - XChangeProperty (window->display->xdisplay, - window->xwindow, - window->display->atom__NET_WM_FULLSCREEN_MONITORS, - XA_CARDINAL, 32, PropModeReplace, - (guchar*) data, 4); - meta_error_trap_pop (window->display); + meta_verbose ("Setting _NET_WM_FULLSCREEN_MONITORS\n"); + meta_error_trap_push (window->display); + XChangeProperty (window->display->xdisplay, + window->xwindow, + window->display->atom__NET_WM_FULLSCREEN_MONITORS, + XA_CARDINAL, 32, PropModeReplace, + (guchar*) data, 4); + meta_error_trap_pop (window->display); + } + else + { + meta_verbose ("Clearing _NET_WM_FULLSCREEN_MONITORS\n"); + meta_error_trap_push (window->display); + XDeleteProperty (window->display->xdisplay, + window->xwindow, + window->display->atom__NET_WM_FULLSCREEN_MONITORS); + meta_error_trap_pop (window->display); + } } } From aec3edb1cc5ae386efbb08ec7414173478ff0d89 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sat, 1 Feb 2014 19:06:51 -0500 Subject: [PATCH 487/889] Always map the client and frame windows Traditionally, WMs unmap windows when minimizing them, and map them when restoring them or wanting to show them for other reasons, like upon creation. However, as metacity morphed into mutter, we optionally chose to keep windows mapped for the lifetime of the window under the user option "live-window-previews", which makes the code keep windows mapped so it can show window preview for minimized windows in other places, like Alt-Tab and Expose. I removed this preference two years ago mechanically, by removing all the if statements, but never went through and cleaned up the code so that windows are simply mapped for the lifetime of the window -- the "architecture" of the old code that maps and unmaps on show/hide was still there. Remove this now. The one case we still need to be careful of is shaded windows, in which we do still unmap the client window. In the future, we might want to show previews of shaded windows in the overview and Alt-Tab. In that we'd also keep shaded windows mapped, and could remove all unmap logic, but we'd need a more complex method of showing the shaded titlebar, such as using a different actor. At the same time, simplify the compositor interface by removing meta_compositor_window_[un]mapped API, and instead adding/removing the window on-demand. https://bugzilla.gnome.org/show_bug.cgi?id=720631 --- doc/reference/meta-sections.txt | 2 - src/compositor/compositor.c | 33 ----- src/compositor/meta-window-actor.c | 58 +-------- src/core/display.c | 2 +- src/core/frame.c | 3 +- src/core/frame.h | 1 - src/core/window.c | 197 +++++++---------------------- src/meta/compositor.h | 13 +- src/meta/window.h | 2 - 9 files changed, 54 insertions(+), 257 deletions(-) diff --git a/doc/reference/meta-sections.txt b/doc/reference/meta-sections.txt index 7aa893177..22d435034 100644 --- a/doc/reference/meta-sections.txt +++ b/doc/reference/meta-sections.txt @@ -96,8 +96,6 @@ meta_compositor_hide_window meta_compositor_switch_workspace meta_compositor_maximize_window meta_compositor_unmaximize_window -meta_compositor_window_mapped -meta_compositor_window_unmapped meta_compositor_sync_window_geometry meta_compositor_set_updates_frozen meta_compositor_queue_frame_drawn diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 9420ad537..0fb8df9e3 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -42,15 +42,6 @@ * the call, so it may be necessary to readjust the display based on the * old_rect to start the animation. * - * meta_compositor_window_mapped() and meta_compositor_window_unmapped() are - * notifications when the toplevel window (frame or client window) is mapped or - * unmapped. That is, when the result of meta_window_toplevel_is_mapped() - * changes. The main use of this is to drop resources when a window is unmapped. - * A window will always be mapped before meta_compositor_show_window() - * is called and will not be unmapped until after meta_compositor_hide_window() - * is called. If the live_hidden_windows preference is set, windows will never - * be unmapped. - * * # Containers # * * There's two containers in the stage that are used to place window actors, here @@ -1369,30 +1360,6 @@ meta_compositor_sync_stack (MetaCompositor *compositor, sync_actor_stacking (info); } -void -meta_compositor_window_mapped (MetaCompositor *compositor, - MetaWindow *window) -{ - MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - DEBUG_TRACE ("meta_compositor_window_mapped\n"); - if (!window_actor) - return; - - meta_window_actor_mapped (window_actor); -} - -void -meta_compositor_window_unmapped (MetaCompositor *compositor, - MetaWindow *window) -{ - MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - DEBUG_TRACE ("meta_compositor_window_unmapped\n"); - if (!window_actor) - return; - - meta_window_actor_unmapped (window_actor); -} - void meta_compositor_sync_window_geometry (MetaCompositor *compositor, MetaWindow *window, diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 60c22e318..13c204a1d 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -103,7 +103,6 @@ struct _MetaWindowActorPrivate Damage damage; /* Not used in wayland compositor mode */ guint visible : 1; - guint mapped : 1; guint argb32 : 1; guint disposed : 1; guint redecorating : 1; @@ -922,7 +921,7 @@ meta_window_actor_damage_all (MetaWindowActor *self) if (!priv->needs_damage_all) return; - if (!priv->mapped || priv->needs_pixmap) + if (priv->needs_pixmap) return; redraw_queued = meta_surface_actor_damage_all (priv->surface); @@ -997,7 +996,7 @@ meta_window_actor_queue_frame_drawn (MetaWindowActor *self, { queue_send_frame_messages_timeout (self); } - else if (priv->mapped && (!meta_is_wayland_compositor () || !priv->needs_pixmap)) + else { const cairo_rectangle_int_t clip = { 0, 0, 1, 1 }; clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (priv->surface), &clip); @@ -1029,9 +1028,6 @@ meta_window_actor_queue_create_x11_pixmap (MetaWindowActor *self) priv->needs_pixmap = TRUE; - if (!priv->mapped) - return; - if (is_frozen (self)) return; @@ -1129,9 +1125,6 @@ meta_window_actor_after_effects (MetaWindowActor *self) if (!meta_is_wayland_compositor ()) { - if (!meta_window_is_mapped (priv->window)) - meta_window_actor_detach_x11_pixmap (self); - if (priv->needs_pixmap) clutter_actor_queue_redraw (CLUTTER_ACTOR (priv->surface)); } @@ -1558,15 +1551,13 @@ meta_window_actor_new (MetaWindow *window) NULL); priv = self->priv; - priv->mapped = meta_window_toplevel_is_mapped (priv->window); if (!meta_is_wayland_compositor ()) { priv->last_width = -1; priv->last_height = -1; - if (priv->mapped) - meta_window_actor_queue_create_x11_pixmap (self); + meta_window_actor_queue_create_x11_pixmap (self); meta_window_actor_set_updates_frozen (self, meta_window_updates_are_frozen (priv->window)); @@ -1602,38 +1593,6 @@ meta_window_actor_new (MetaWindow *window) return self; } -void -meta_window_actor_mapped (MetaWindowActor *self) -{ - MetaWindowActorPrivate *priv = self->priv; - - g_return_if_fail (!priv->mapped); - - priv->mapped = TRUE; - - if (!meta_is_wayland_compositor ()) - meta_window_actor_queue_create_x11_pixmap (self); -} - -void -meta_window_actor_unmapped (MetaWindowActor *self) -{ - MetaWindowActorPrivate *priv = self->priv; - - g_return_if_fail (priv->mapped); - - priv->mapped = FALSE; - - if (meta_window_actor_effect_in_progress (self)) - return; - - if (!meta_is_wayland_compositor ()) - { - meta_window_actor_detach_x11_pixmap (self); - priv->needs_pixmap = FALSE; - } -} - #if 0 /* Print out a region; useful for debugging */ static void @@ -1763,9 +1722,6 @@ check_needs_x11_pixmap (MetaWindowActor *self) if (!priv->needs_pixmap) return; - if (!priv->mapped) - return; - if (xwindow == meta_screen_get_xroot (screen) || xwindow == clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage))) return; @@ -1839,9 +1795,6 @@ check_needs_shadow (MetaWindowActor *self) gboolean should_have_shadow; gboolean appears_focused; - if (!priv->mapped) - return; - /* Calling meta_window_actor_has_shadow() here at every pre-paint is cheap * and avoids the need to explicitly handle window type changes, which * we would do if tried to keep track of when we might be adding or removing @@ -1945,7 +1898,7 @@ meta_window_actor_process_x11_damage (MetaWindowActor *self, return; } - if (!priv->mapped || priv->needs_pixmap) + if (priv->needs_pixmap) return; redraw_queued = meta_surface_actor_damage_area (priv->surface, @@ -2218,9 +2171,6 @@ check_needs_reshape (MetaWindowActor *self) MetaFrameBorders borders; cairo_rectangle_int_t client_area; - if (!priv->mapped) - return; - if (!priv->needs_reshape) return; diff --git a/src/core/display.c b/src/core/display.c index e5da0ec7f..4ecf6dbd6 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -2763,7 +2763,7 @@ handle_other_xevent (MetaDisplay *display, if (display->grab_op != META_GRAB_OP_NONE && display->grab_window == window && - ((window->frame == NULL) || !window->frame->mapped)) + window->frame == NULL) meta_display_end_grab_op (display, timestamp); if (!frame_was_receiver) diff --git a/src/core/frame.c b/src/core/frame.c index 5fa7bee17..e54e86210 100644 --- a/src/core/frame.c +++ b/src/core/frame.c @@ -62,7 +62,6 @@ meta_window_ensure_frame (MetaWindow *window) frame->right_width = 0; frame->current_cursor = 0; - frame->mapped = FALSE; frame->is_flashing = FALSE; frame->borders_cached = FALSE; @@ -157,6 +156,8 @@ meta_window_ensure_frame (MetaWindow *window) /* Move keybindings to frame instead of window */ meta_window_grab_keys (window); + + meta_ui_map_frame (frame->window->screen->ui, frame->xwindow); } void diff --git a/src/core/frame.h b/src/core/frame.h index 0f1ebea4f..8ac1c261e 100644 --- a/src/core/frame.h +++ b/src/core/frame.h @@ -47,7 +47,6 @@ struct _MetaFrame int right_width; int bottom_height; - guint mapped : 1; guint need_reapply_frame_shape : 1; guint is_flashing : 1; /* used by the visual bell flash */ guint borders_cached : 1; diff --git a/src/core/window.c b/src/core/window.c index 0edfbcbfd..e08704d92 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -688,6 +688,35 @@ meta_window_should_attach_to_parent (MetaWindow *window) } } +static gboolean +client_window_should_be_mapped (MetaWindow *window) +{ + return !window->shaded; +} + +static void +sync_client_window_mapped (MetaWindow *window) +{ + gboolean should_be_mapped = client_window_should_be_mapped (window); + + if (window->mapped == should_be_mapped) + return; + + window->mapped = should_be_mapped; + + meta_error_trap_push (window->display); + if (should_be_mapped) + { + XMapWindow (window->display->xdisplay, window->xwindow); + } + else + { + XUnmapWindow (window->display->xdisplay, window->xwindow); + window->unmaps_pending ++; + } + meta_error_trap_pop (window->display); +} + MetaWindow * _meta_window_shared_new (MetaDisplay *display, MetaScreen *screen, @@ -1191,6 +1220,8 @@ _meta_window_shared_new (MetaDisplay *display, /* disable show desktop mode unless we're a desktop component */ maybe_leave_show_desktop_mode (window); + sync_client_window_mapped (window); + meta_window_queue (window, META_QUEUE_CALC_SHOWING); /* See bug 303284; a transient of the given window can already exist, in which * case we think it should probably be shown. @@ -1932,6 +1963,8 @@ implement_showing (MetaWindow *window, meta_verbose ("Implement showing = %d for window %s\n", showing, window->desc); + sync_client_window_mapped (window); + if (!showing) { /* When we manage a new window, we normally delay placing it @@ -2520,94 +2553,6 @@ window_would_be_covered (const MetaWindow *newbie) return FALSE; /* none found */ } -static gboolean -map_frame (MetaWindow *window) -{ - if (window->frame && !window->frame->mapped) - { - meta_topic (META_DEBUG_WINDOW_STATE, - "Frame actually needs map\n"); - window->frame->mapped = TRUE; - meta_ui_map_frame (window->screen->ui, window->frame->xwindow); - return TRUE; - } - else - return FALSE; -} - -static gboolean -map_client_window (MetaWindow *window) -{ - if (!window->mapped) - { - meta_topic (META_DEBUG_WINDOW_STATE, - "%s actually needs map\n", window->desc); - window->mapped = TRUE; - meta_error_trap_push (window->display); - XMapWindow (window->display->xdisplay, window->xwindow); - meta_error_trap_pop (window->display); - - return TRUE; - } - else - return FALSE; -} - -static gboolean -unmap_client_window (MetaWindow *window, - const char *reason) -{ - if (window->mapped) - { - meta_topic (META_DEBUG_WINDOW_STATE, - "%s actually needs unmap%s\n", - window->desc, reason); - meta_topic (META_DEBUG_WINDOW_STATE, - "Incrementing unmaps_pending on %s%s\n", - window->desc, reason); - window->mapped = FALSE; - window->unmaps_pending += 1; - meta_error_trap_push (window->display); - XUnmapWindow (window->display->xdisplay, window->xwindow); - meta_error_trap_pop (window->display); - - return TRUE; - } - else - return FALSE; -} - -/** - * meta_window_is_mapped: - * @window: a #MetaWindow - * - * Determines whether the X window for the MetaWindow is mapped. - */ -gboolean -meta_window_is_mapped (MetaWindow *window) -{ - return window->mapped; -} - -/** - * meta_window_toplevel_is_mapped: - * @window: a #MetaWindow - * - * Determines whether the toplevel X window for the MetaWindow is - * mapped. (The frame window is mapped even without the client window - * when a window is shaded.) - * - * Return Value: %TRUE if the toplevel is mapped. - */ -gboolean -meta_window_toplevel_is_mapped (MetaWindow *window) -{ - /* The frame is mapped but not the client window when the window - * is shaded. - */ - return window->mapped || (window->frame && window->frame->mapped); -} - static void meta_window_force_placement (MetaWindow *window) { @@ -2646,16 +2591,12 @@ meta_window_show (MetaWindow *window) gboolean place_on_top_on_map; gboolean needs_stacking_adjustment; MetaWindow *focus_window; - gboolean toplevel_was_mapped; - gboolean toplevel_now_mapped; gboolean notify_demands_attention = FALSE; meta_topic (META_DEBUG_WINDOW_STATE, "Showing window %s, shaded: %d iconic: %d placed: %d\n", window->desc, window->shaded, window->iconic, window->placed); - toplevel_was_mapped = meta_window_toplevel_is_mapped (window); - focus_window = window->display->focus_window; /* May be NULL! */ did_show = FALSE; window_state_on_map (window, &takes_focus_on_map, &place_on_top_on_map); @@ -2782,46 +2723,18 @@ meta_window_show (MetaWindow *window) } } - /* Shaded means the frame is mapped but the window is not */ - - if (map_frame (window)) - did_show = TRUE; - - if (window->shaded) + if (window->hidden) { - unmap_client_window (window, " (shading)"); - - if (!window->iconic) - { - window->iconic = TRUE; - set_wm_state (window); - } - } - else - { - if (map_client_window (window)) - did_show = TRUE; - - if (window->hidden) - { - meta_stack_freeze (window->screen->stack); - window->hidden = FALSE; - meta_stack_thaw (window->screen->stack); - did_show = TRUE; - } - - if (window->iconic) - { - window->iconic = FALSE; - set_wm_state (window); - } + meta_stack_freeze (window->screen->stack); + window->hidden = FALSE; + meta_stack_thaw (window->screen->stack); + did_show = TRUE; } - toplevel_now_mapped = meta_window_toplevel_is_mapped (window); - if (toplevel_now_mapped != toplevel_was_mapped) + if (window->iconic) { - if (window->display->compositor) - meta_compositor_window_mapped (window->display->compositor, window); + window->iconic = FALSE; + set_wm_state (window); } if (!window->visible_to_compositor) @@ -2913,14 +2826,10 @@ static void meta_window_hide (MetaWindow *window) { gboolean did_hide; - gboolean toplevel_was_mapped; - gboolean toplevel_now_mapped; meta_topic (META_DEBUG_WINDOW_STATE, "Hiding window %s\n", window->desc); - toplevel_was_mapped = meta_window_toplevel_is_mapped (window); - if (window->visible_to_compositor) { window->visible_to_compositor = FALSE; @@ -2941,19 +2850,12 @@ meta_window_hide (MetaWindow *window) break; } - meta_compositor_hide_window (window->display->compositor, - window, effect); + meta_compositor_hide_window (window->display->compositor, window, effect); } } did_hide = FALSE; - /* If this is the first time that we've calculating the showing - * state of the window, the frame and client window might not - * yet be mapped, so we need to map them now */ - map_frame (window); - map_client_window (window); - if (!window->hidden) { meta_stack_freeze (window->screen->stack); @@ -2969,19 +2871,6 @@ meta_window_hide (MetaWindow *window) set_wm_state (window); } - toplevel_now_mapped = meta_window_toplevel_is_mapped (window); - if (toplevel_now_mapped != toplevel_was_mapped) - { - if (window->display->compositor) - { - /* As above, we may be *mapping* live hidden windows */ - if (toplevel_now_mapped) - meta_compositor_window_mapped (window->display->compositor, window); - else - meta_compositor_window_unmapped (window->display->compositor, window); - } - } - set_net_wm_state (window); if (did_hide && window->struts) @@ -6813,7 +6702,7 @@ redraw_icon (MetaWindow *window) /* We could probably be smart and just redraw the icon here, * instead of the whole frame. */ - if (window->frame && (window->mapped || window->frame->mapped)) + if (window->frame) meta_ui_queue_frame_draw (window->screen->ui, window->frame->xwindow); } diff --git a/src/meta/compositor.h b/src/meta/compositor.h index 42ff0dd8e..45c8b09dd 100644 --- a/src/meta/compositor.h +++ b/src/meta/compositor.h @@ -75,11 +75,10 @@ gboolean meta_compositor_filter_keybinding (MetaCompositor *compositor, MetaScreen *screen, MetaKeyBinding *binding); -void meta_compositor_add_window (MetaCompositor *compositor, - MetaWindow *window); -void meta_compositor_remove_window (MetaCompositor *compositor, - MetaWindow *window); - +void meta_compositor_add_window (MetaCompositor *compositor, + MetaWindow *window); +void meta_compositor_remove_window (MetaCompositor *compositor, + MetaWindow *window); void meta_compositor_show_window (MetaCompositor *compositor, MetaWindow *window, MetaCompEffect effect); @@ -101,10 +100,6 @@ void meta_compositor_unmaximize_window (MetaCompositor *compositor, MetaRectangle *old_rect, MetaRectangle *new_rect); -void meta_compositor_window_mapped (MetaCompositor *compositor, - MetaWindow *window); -void meta_compositor_window_unmapped (MetaCompositor *compositor, - MetaWindow *window); void meta_compositor_sync_window_geometry (MetaCompositor *compositor, MetaWindow *window, gboolean did_placement); diff --git a/src/meta/window.h b/src/meta/window.h index ff2d037d3..430dc6bd9 100644 --- a/src/meta/window.h +++ b/src/meta/window.h @@ -189,8 +189,6 @@ gboolean meta_window_requested_bypass_compositor (MetaWindow *window); gboolean meta_window_requested_dont_bypass_compositor (MetaWindow *window); gint *meta_window_get_all_monitors (MetaWindow *window, gsize *length); -gboolean meta_window_is_mapped (MetaWindow *window); -gboolean meta_window_toplevel_is_mapped (MetaWindow *window); gboolean meta_window_get_icon_geometry (MetaWindow *window, MetaRectangle *rect); void meta_window_set_icon_geometry (MetaWindow *window, From 4efe4483fbc7602e8358fda936074216a8e5544b Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 6 Feb 2014 15:01:59 -0500 Subject: [PATCH 488/889] compositor: Delay meta_compositor_add_window until the first show In order for the compositor to properly determine whether a client is an X11 client or not, we need to wait until XWayland calls set_window_id to mark the surface as an XWayland client. To prevent the compositor from getting tripped up over this, make sure that the window has been fully initialized by the time we call meta_compositor_add_window. https://bugzilla.gnome.org/show_bug.cgi?id=720631 --- src/compositor/compositor.c | 28 +++++++++++----------------- src/core/window.c | 7 ++----- 2 files changed, 13 insertions(+), 22 deletions(-) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 0fb8df9e3..6ed2df400 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -140,19 +140,6 @@ meta_compositor_destroy (MetaCompositor *compositor) clutter_threads_remove_repaint_func (compositor->repaint_func_id); } -static void -add_win (MetaWindow *window) -{ - MetaScreen *screen = meta_window_get_screen (window); - MetaCompScreen *info = meta_screen_get_compositor_data (screen); - - g_return_if_fail (info != NULL); - - meta_window_actor_new (window); - - sync_actor_stacking (info); -} - static void process_damage (MetaCompositor *compositor, XDamageNotifyEvent *event, @@ -835,13 +822,20 @@ meta_compositor_add_window (MetaCompositor *compositor, { MetaScreen *screen = meta_window_get_screen (window); MetaDisplay *display = meta_screen_get_display (screen); + MetaCompScreen *info = meta_screen_get_compositor_data (screen); + + g_return_if_fail (info != NULL); + + /* Window was already added previously, probably coming + * back from hiding */ + if (window->compositor_private != NULL) + return; - DEBUG_TRACE ("meta_compositor_add_window\n"); meta_error_trap_push (display); - - add_win (window); - + meta_window_actor_new (window); meta_error_trap_pop (display); + + sync_actor_stacking (info); } void diff --git a/src/core/window.c b/src/core/window.c index e08704d92..8c0f66e03 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -1204,9 +1204,6 @@ _meta_window_shared_new (MetaDisplay *display, set_net_wm_state (window); } - if (screen->display->compositor) - meta_compositor_add_window (screen->display->compositor, window); - /* Sync stack changes */ meta_stack_thaw (window->screen->stack); @@ -2757,8 +2754,8 @@ meta_window_show (MetaWindow *window) break; } - meta_compositor_show_window (window->display->compositor, - window, effect); + meta_compositor_add_window (window->display->compositor, window); + meta_compositor_show_window (window->display->compositor, window, effect); } } From a0ef7c7142557913077b398cc219665a21650b95 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 6 Dec 2013 15:39:24 -0500 Subject: [PATCH 489/889] Move position-changed / size-changed signals to the MetaWindow They fit more appropriately over here... https://bugzilla.gnome.org/show_bug.cgi?id=720631 --- src/compositor/meta-window-actor.c | 37 -------------------------- src/core/window.c | 42 ++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 37 deletions(-) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 13c204a1d..f9568f393 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -37,15 +37,6 @@ #include "monitor-private.h" #include "meta-cullable.h" -enum { - POSITION_CHANGED, - SIZE_CHANGED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = {0}; - - struct _MetaWindowActorPrivate { MetaWindow *window; @@ -245,19 +236,6 @@ meta_window_actor_class_init (MetaWindowActorClass *klass) g_object_class_install_property (object_class, PROP_SHADOW_CLASS, pspec); - - signals[POSITION_CHANGED] = - g_signal_new ("position-changed", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 0); - signals[SIZE_CHANGED] = - g_signal_new ("size-changed", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 0); } static void @@ -327,8 +305,6 @@ surface_allocation_changed_notify (ClutterActor *actor, { meta_window_actor_sync_actor_geometry (self, FALSE); meta_window_actor_update_shape (self); - - g_signal_emit (self, signals[SIZE_CHANGED], 0); } static gboolean @@ -1390,8 +1366,6 @@ meta_window_actor_sync_actor_geometry (MetaWindowActor *self, window_rect.x, window_rect.y); clutter_actor_set_size (CLUTTER_ACTOR (self), window_rect.width, window_rect.height); - - g_signal_emit (self, signals[POSITION_CHANGED], 0); } void @@ -1766,17 +1740,6 @@ check_needs_x11_pixmap (MetaWindowActor *self) g_warning ("NOTE: Not using GLX TFP!\n"); meta_surface_actor_set_texture (META_SURFACE_ACTOR (priv->surface), texture); - - /* ::size-changed is supposed to refer to meta_window_get_frame_rect(). - * Emitting it here works pretty much OK because a new value of the - * *input* rect (which is the outer rect with the addition of invisible - * borders) forces a new pixmap and we get here. In the rare case where - * a change to the window size was exactly balanced by a change to the - * invisible borders, we would miss emitting the signal. We would also - * emit spurious signals when we get a new pixmap without a new size, - * but that should be mostly harmless. - */ - g_signal_emit (self, signals[SIZE_CHANGED], 0); } priv->needs_pixmap = FALSE; diff --git a/src/core/window.c b/src/core/window.c index 8c0f66e03..07468170e 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -202,6 +202,8 @@ enum FOCUS, RAISED, UNMANAGED, + SIZE_CHANGED, + POSITION_CHANGED, LAST_SIGNAL }; @@ -609,6 +611,40 @@ meta_window_class_init (MetaWindowClass *klass) G_STRUCT_OFFSET (MetaWindowClass, unmanaged), NULL, NULL, NULL, G_TYPE_NONE, 0); + + /** + * MetaWindow::position-changed: + * @window: a #MetaWindow + * + * This is emitted when the position of a window might + * have changed. Specifically, this is emitted when the + * position of the toplevel window has changed, or when + * the position of the client window has changed. + */ + window_signals[POSITION_CHANGED] = + g_signal_new ("position-changed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); + + /** + * MetaWindow::size-changed: + * @window: a #MetaWindow + * + * This is emitted when the position of a window might + * have changed. Specifically, this is emitted when the + * size of the toplevel window has changed, or when the + * size of the client window has changed. + */ + window_signals[SIZE_CHANGED] = + g_signal_new ("size-changed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); } static void @@ -4954,6 +4990,12 @@ meta_window_move_resize_internal (MetaWindow *window, else if (is_user_action) save_user_window_placement (window); + if (need_move_client || need_move_frame) + g_signal_emit (window, window_signals[POSITION_CHANGED], 0); + + if (need_resize_client || need_resize_frame) + g_signal_emit (window, window_signals[SIZE_CHANGED], 0); + if (need_move_frame || need_resize_frame || need_move_client || need_resize_client || did_placement || is_wayland_resize) From d043d9943bb8656d855b80f60ec883606e4c0358 Mon Sep 17 00:00:00 2001 From: Ryan Lortie Date: Fri, 14 Feb 2014 10:10:20 -0500 Subject: [PATCH 490/889] idle-monitor: avoid XSyncBadAlarm X error If we fail to find the IDLETIME counter, then the alarm variable will be uninitialised. Most code paths are careful to check this before submitting XSync calls, but there is one check missing. https://bugzilla.gnome.org/show_bug.cgi?id=724364 --- src/core/meta-idle-monitor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/meta-idle-monitor.c b/src/core/meta-idle-monitor.c index 7712cc78d..c99fc1050 100644 --- a/src/core/meta-idle-monitor.c +++ b/src/core/meta-idle-monitor.c @@ -535,7 +535,7 @@ make_watch (MetaIdleMonitor *monitor, watch->timeout_source = source; } } - else + else if (monitor->user_active_alarm != None) { if (timeout_msec != 0) { From d9659d4b369d305cde3bc8b59e4df7e572df8834 Mon Sep 17 00:00:00 2001 From: Adel Gadllah Date: Sun, 16 Feb 2014 16:15:14 +0100 Subject: [PATCH 491/889] wayland-surface: Don't crash when someone tries to run a native app using old gtk This ends up calling set_dbus_properties with a NULL window, instead of segfaulting the compositor return so that the broken app dies instead. https://bugzilla.gnome.org/show_bug.cgi?id=724472 --- src/wayland/meta-wayland-surface.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index e5995d366..d2075eeac 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -1113,6 +1113,13 @@ set_dbus_properties (struct wl_client *client, MetaWaylandSurfaceExtension *gtk_surface = wl_resource_get_user_data (resource); MetaWaylandSurface *surface = wl_container_of (gtk_surface, surface, gtk_surface); + /* Broken client, let it die instead of us */ + if (!surface->window) + { + meta_warning ("meta-wayland-surface: set_dbus_properties called with invalid window!\n"); + return; + } + meta_window_set_gtk_dbus_properties (surface->window, application_id, unique_bus_name, From bd1bec561747cc4ff810107fd5dc353704dda341 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sat, 15 Feb 2014 10:02:04 -0500 Subject: [PATCH 492/889] wayland-surface: Prefix xdg-shell methods with "xdg_shell_" --- src/wayland/meta-wayland-surface.c | 52 +++++++++++++++--------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index d2075eeac..67b9551af 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -708,6 +708,15 @@ create_surface_extension (MetaWaylandSurfaceExtension *extension, return TRUE; } +static void +xdg_shell_use_unstable_version (struct wl_client *client, + struct wl_resource *resource, + int32_t version) +{ + if (version != META_XDG_SHELL_VERSION) + g_warning ("Bad xdg_shell version: %d", version); +} + static void xdg_surface_destructor (struct wl_resource *resource) { @@ -961,19 +970,10 @@ static const struct xdg_surface_interface meta_wayland_xdg_surface_interface = { }; static void -use_unstable_version (struct wl_client *client, - struct wl_resource *resource, - int32_t version) -{ - if (version != META_XDG_SHELL_VERSION) - g_warning ("Bad xdg_shell version: %d", version); -} - -static void -get_xdg_surface (struct wl_client *client, - struct wl_resource *resource, - guint32 id, - struct wl_resource *surface_resource) +xdg_shell_get_xdg_surface (struct wl_client *client, + struct wl_resource *resource, + guint32 id, + struct wl_resource *surface_resource) { MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); @@ -1026,16 +1026,16 @@ static const struct xdg_popup_interface meta_wayland_xdg_popup_interface = { }; static void -get_xdg_popup (struct wl_client *client, - struct wl_resource *resource, - uint32_t id, - struct wl_resource *surface_resource, - struct wl_resource *parent_resource, - struct wl_resource *seat_resource, - uint32_t serial, - int32_t x, - int32_t y, - uint32_t flags) +xdg_shell_get_xdg_popup (struct wl_client *client, + struct wl_resource *resource, + uint32_t id, + struct wl_resource *surface_resource, + struct wl_resource *parent_resource, + struct wl_resource *seat_resource, + uint32_t serial, + int32_t x, + int32_t y, + uint32_t flags) { MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); MetaWaylandSurface *parent_surf = wl_resource_get_user_data (parent_resource); @@ -1073,9 +1073,9 @@ get_xdg_popup (struct wl_client *client, } static const struct xdg_shell_interface meta_wayland_xdg_shell_interface = { - use_unstable_version, - get_xdg_surface, - get_xdg_popup, + xdg_shell_use_unstable_version, + xdg_shell_get_xdg_surface, + xdg_shell_get_xdg_popup, }; static void From 11aa3c030bbde41bb8cdd5ffb904739f306ecd34 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sat, 15 Feb 2014 10:02:48 -0500 Subject: [PATCH 493/889] wayland-surface: Don't require we manually bump the version for xdg-shell It's in the protocol as an enum. --- src/wayland/meta-wayland-surface.c | 14 +++++++++----- src/wayland/meta-wayland-versions.h | 1 - 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 67b9551af..39738af92 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -713,7 +713,7 @@ xdg_shell_use_unstable_version (struct wl_client *client, struct wl_resource *resource, int32_t version) { - if (version != META_XDG_SHELL_VERSION) + if (version != XDG_SHELL_VERSION_CURRENT) g_warning ("Bad xdg_shell version: %d", version); } @@ -1086,8 +1086,13 @@ bind_xdg_shell (struct wl_client *client, { struct wl_resource *resource; - resource = wl_resource_create (client, &xdg_shell_interface, - MIN (META_XDG_SHELL_VERSION, version), id); + if (version != 1) + { + g_warning ("using xdg-shell without stable version 1\n"); + return; + } + + resource = wl_resource_create (client, &xdg_shell_interface, 1, id); wl_resource_set_implementation (resource, &meta_wayland_xdg_shell_interface, data, NULL); } @@ -1466,8 +1471,7 @@ void meta_wayland_init_shell (MetaWaylandCompositor *compositor) { if (wl_global_create (compositor->wayland_display, - &xdg_shell_interface, - META_XDG_SHELL_VERSION, + &xdg_shell_interface, 1, compositor, bind_xdg_shell) == NULL) g_error ("Failed to register a global xdg-shell object"); diff --git a/src/wayland/meta-wayland-versions.h b/src/wayland/meta-wayland-versions.h index 531cbd4b9..e2d608c86 100644 --- a/src/wayland/meta-wayland-versions.h +++ b/src/wayland/meta-wayland-versions.h @@ -41,7 +41,6 @@ #define META_WL_OUTPUT_VERSION 2 #define META_XSERVER_VERSION 1 #define META_GTK_SHELL_VERSION 1 -#define META_XDG_SHELL_VERSION 1 #define META_WL_SUBCOMPOSITOR_VERSION 1 /* Slave objects (version inherited from a master object) */ From a66060e21aeb215feae57c79b4a75774482bd03e Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sat, 15 Feb 2014 11:33:12 -0500 Subject: [PATCH 494/889] Revert "Move window pings to MetaWindow" This was a bad idea, as ping/pong has moved to a client-specific request/event pair, rather than a surface-specific one. Revert the changes we made here and correct the code to make up for it. This reverts commit aa3643cdde4277a26e5730a0f6335c76a1a22d4f. --- src/core/delete.c | 10 +- src/core/display-private.h | 14 +- src/core/display.c | 260 ++++++++++++++++++++++++++++- src/core/window-private.h | 13 -- src/core/window.c | 214 ------------------------ src/wayland/meta-wayland-surface.c | 4 +- 6 files changed, 274 insertions(+), 241 deletions(-) diff --git a/src/core/delete.c b/src/core/delete.c index a24c1b97e..9cfa71534 100644 --- a/src/core/delete.c +++ b/src/core/delete.c @@ -132,11 +132,11 @@ void meta_window_check_alive (MetaWindow *window, guint32 timestamp) { - meta_window_ping (window, - timestamp, - delete_ping_reply_func, - delete_ping_timeout_func, - NULL); + meta_display_ping_window (window, + timestamp, + delete_ping_reply_func, + delete_ping_timeout_func, + NULL); } void diff --git a/src/core/display-private.h b/src/core/display-private.h index 4d86eae65..11b3a6091 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -55,6 +55,10 @@ typedef struct _MetaWindowPropHooks MetaWindowPropHooks; typedef struct MetaEdgeResistanceData MetaEdgeResistanceData; +typedef void (* MetaWindowPingFunc) (MetaWindow *window, + guint32 timestamp, + gpointer user_data); + typedef enum { META_LIST_DEFAULT = 0, /* normal windows */ META_LIST_INCLUDE_OVERRIDE_REDIRECT = 1 << 0, /* normal and O-R */ @@ -183,7 +187,7 @@ struct _MetaDisplay guint32 window_sequence_counter; /* Pings which we're waiting for a reply from */ - GHashTable *pending_pings; + GSList *pending_pings; /* Pending focus change */ guint focus_timeout_id; @@ -449,6 +453,14 @@ void meta_display_retheme_all (void); void meta_display_set_cursor_theme (const char *theme, int size); +void meta_display_ping_window (MetaWindow *window, + guint32 timestamp, + MetaWindowPingFunc ping_reply_func, + MetaWindowPingFunc ping_timeout_func, + void *user_data); +void meta_display_pong_for_serial (MetaDisplay *display, + guint32 serial); + int meta_resize_gravity_from_grab_op (MetaGrabOp op); gboolean meta_grab_op_is_moving (MetaGrabOp op); diff --git a/src/core/display.c b/src/core/display.c index 4ecf6dbd6..8854e7944 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -82,6 +82,40 @@ g == META_GRAB_OP_KEYBOARD_ESCAPING_DOCK || \ g == META_GRAB_OP_KEYBOARD_ESCAPING_GROUP) +/* + * SECTION:pings + * + * Sometimes we want to see whether a window is responding, + * so we send it a "ping" message and see whether it sends us back a "pong" + * message within a reasonable time. Here we have a system which lets us + * nominate one function to be called if we get the pong in time and another + * function if we don't. The system is rather more complicated than it needs + * to be, since we only ever use it to destroy windows which are asked to + * close themselves and don't do so within a reasonable amount of time, and + * therefore we always use the same callbacks. It's possible that we might + * use it for other things in future, or on the other hand we might decide + * that we're never going to do so and simplify it a bit. + */ + +/** + * MetaPingData: + * + * Describes a ping on a window. When we send a ping to a window, we build + * one of these structs, and it eventually gets passed to the timeout function + * or to the function which handles the response from the window. If the window + * does or doesn't respond to the ping, we use this information to deal with + * these facts; we have a handler function for each. + */ +typedef struct +{ + MetaWindow *window; + guint32 timestamp; + MetaWindowPingFunc ping_reply_func; + MetaWindowPingFunc ping_timeout_func; + void *user_data; + guint ping_timeout_id; +} MetaPingData; + G_DEFINE_TYPE(MetaDisplay, meta_display, G_TYPE_OBJECT); /* Signals */ @@ -283,6 +317,62 @@ meta_display_class_init (MetaDisplayClass *klass) G_PARAM_READABLE)); } + +/** + * ping_data_free: + * + * Destructor for #MetaPingData structs. Will destroy the + * event source for the struct as well. + */ +static void +ping_data_free (MetaPingData *ping_data) +{ + /* Remove the timeout */ + if (ping_data->ping_timeout_id != 0) + g_source_remove (ping_data->ping_timeout_id); + + g_free (ping_data); +} + +/** + * remove_pending_pings_for_window: + * @display: The display the window appears on + * @xwindow: The X ID of the window whose pings we should remove + * + * Frees every pending ping structure for the given X window on the + * given display. This means that we also destroy the timeouts. + */ +static void +remove_pending_pings_for_window (MetaDisplay *display, Window xwindow) +{ + GSList *tmp; + GSList *dead; + + /* could obviously be more efficient, don't care */ + + /* build list to be removed */ + dead = NULL; + for (tmp = display->pending_pings; tmp; tmp = tmp->next) + { + MetaPingData *ping_data = tmp->data; + + if (ping_data->window->xwindow == xwindow) + dead = g_slist_prepend (dead, ping_data); + } + + /* remove what we found */ + for (tmp = dead; tmp; tmp = tmp->next) + { + MetaPingData *ping_data = tmp->data; + + display->pending_pings = g_slist_remove (display->pending_pings, ping_data); + ping_data_free (ping_data); + } + + g_slist_free (dead); +} + + #ifdef HAVE_STARTUP_NOTIFICATION static void sn_error_trap_push (SnDisplay *sn_display, @@ -433,6 +523,7 @@ meta_display_open (void) the_display->server_grab_count = 0; the_display->display_opening = TRUE; + the_display->pending_pings = NULL; the_display->autoraise_timeout_id = 0; the_display->autoraise_window = NULL; the_display->focus_window = NULL; @@ -504,7 +595,6 @@ meta_display_open (void) the_display->xids = g_hash_table_new (meta_unsigned_long_hash, meta_unsigned_long_equal); - the_display->pending_pings = g_hash_table_new (g_int_hash, g_int_equal); the_display->wayland_windows = g_hash_table_new (NULL, NULL); i = 0; @@ -3056,12 +3146,8 @@ handle_other_xevent (MetaDisplay *display, if ((Atom)event->xclient.data.l[0] == display->atom__NET_WM_PING) { guint32 timestamp = event->xclient.data.l[1]; - window = g_hash_table_lookup (display->pending_pings, ×tamp); - if (window) - meta_window_pong (window, timestamp); - else - meta_verbose ("Received invalid _NET_WM_PING for unknown timestamp %d\n", timestamp); + meta_display_pong_for_serial (display, timestamp); /* We don't want ping reply events going into * the GTK+ event loop because gtk+ will treat @@ -3970,6 +4056,9 @@ meta_display_unregister_x_window (MetaDisplay *display, g_return_if_fail (g_hash_table_lookup (display->xids, &xwindow) != NULL); g_hash_table_remove (display->xids, &xwindow); + + /* Remove any pending pings */ + remove_pending_pings_for_window (display, xwindow); } void @@ -4818,6 +4907,115 @@ meta_set_syncing (gboolean setting) } } +/* + * How long, in milliseconds, we should wait after pinging a window + * before deciding it's not going to get back to us. + */ +#define PING_TIMEOUT_DELAY 5000 + +/** + * meta_display_ping_timeout: + * @data: All the information about this ping. It is a #MetaPingData + * cast to a #gpointer in order to be passable to a timeout function. + * This function will also free this parameter. + * + * Does whatever it is we decided to do when a window didn't respond + * to a ping. We also remove the ping from the display's list of + * pending pings. This function is called by the event loop when the timeout + * times out which we created at the start of the ping. + * + * Returns: Always returns %FALSE, because this function is called as a + * timeout and we don't want to run the timer again. + */ +static gboolean +meta_display_ping_timeout (gpointer data) +{ + MetaPingData *ping_data = data; + MetaDisplay *display = ping_data->window->display; + + ping_data->ping_timeout_id = 0; + + meta_topic (META_DEBUG_PING, + "Ping %u on window %s timed out\n", + ping_data->timestamp, ping_data->window->desc); + + (* ping_data->ping_timeout_func) (ping_data->window, ping_data->timestamp, ping_data->user_data); + + display->pending_pings = g_slist_remove (display->pending_pings, ping_data); + ping_data_free (ping_data); + + return FALSE; +} + +/** + * meta_display_ping_window: + * @display: The #MetaDisplay that the window is on + * @window: The #MetaWindow to send the ping to + * @timestamp: The timestamp of the ping. Used for uniqueness. + * Cannot be CurrentTime; use a real timestamp! + * @ping_reply_func: The callback to call if we get a response. + * @ping_timeout_func: The callback to call if we don't get a response. + * @user_data: Arbitrary data that will be passed to the callback + * function. (In practice it's often a pointer to + * the window.) + * + * Sends a ping request to a window. The window must respond to + * the request within a certain amount of time. If it does, we + * will call one callback; if the time passes and we haven't had + * a response, we call a different callback. The window must have + * the hint showing that it can respond to a ping; if it doesn't, + * we call the "got a response" callback immediately and return. + * This function returns straight away after setting things up; + * the callbacks will be called from the event loop. + */ +void +meta_display_ping_window (MetaWindow *window, + guint32 timestamp, + MetaWindowPingFunc ping_reply_func, + MetaWindowPingFunc ping_timeout_func, + gpointer user_data) +{ + MetaDisplay *display = window->display; + MetaPingData *ping_data; + + if (timestamp == CurrentTime) + { + meta_warning ("Tried to ping a window with CurrentTime! Not allowed.\n"); + return; + } + + if (!window->net_wm_ping) + { + if (ping_reply_func) + (* ping_reply_func) (window, timestamp, user_data); + + return; + } + + ping_data = g_new (MetaPingData, 1); + ping_data->window = window; + ping_data->timestamp = timestamp; + ping_data->ping_reply_func = ping_reply_func; + ping_data->ping_timeout_func = ping_timeout_func; + ping_data->user_data = user_data; + ping_data->ping_timeout_id = g_timeout_add (PING_TIMEOUT_DELAY, + meta_display_ping_timeout, + ping_data); + + display->pending_pings = g_slist_prepend (display->pending_pings, ping_data); + + meta_topic (META_DEBUG_PING, + "Sending ping with timestamp %u to window %s\n", + timestamp, window->desc); + + if (window->client_type == META_WINDOW_CLIENT_TYPE_X11) + meta_window_send_icccm_message (window, + display->atom__NET_WM_PING, + timestamp); + else + meta_wayland_surface_ping (window->surface, timestamp); +} + static void process_request_frame_extents (MetaDisplay *display, XEvent *event) @@ -4878,6 +5076,56 @@ process_request_frame_extents (MetaDisplay *display, meta_XFree (hints); } +/** + * meta_display_pong_for_serial: + * @display: the display we got the pong from + * @serial: the serial in the pong repsonse + * + * Process the pong (the response message) from the ping we sent + * to the window. This involves removing the timeout, calling the + * reply handler function, and freeing memory. + */ +void +meta_display_pong_for_serial (MetaDisplay *display, + guint32 serial) +{ + GSList *tmp; + + meta_topic (META_DEBUG_PING, "Received a pong with serial %u\n", serial); + + for (tmp = display->pending_pings; tmp; tmp = tmp->next) + { + MetaPingData *ping_data = tmp->data; + + if (serial == ping_data->timestamp) + { + meta_topic (META_DEBUG_PING, + "Matching ping found for pong %u\n", + ping_data->timestamp); + + /* Remove the ping data from the list */ + display->pending_pings = g_slist_remove (display->pending_pings, + ping_data); + + /* Remove the timeout */ + if (ping_data->ping_timeout_id != 0) + { + g_source_remove (ping_data->ping_timeout_id); + ping_data->ping_timeout_id = 0; + } + + /* Call callback */ + (* ping_data->ping_reply_func) (ping_data->window, + ping_data->timestamp, + ping_data->user_data); + + ping_data_free (ping_data); + + break; + } + } +} + MetaGroup* get_focussed_group (MetaDisplay *display) { diff --git a/src/core/window-private.h b/src/core/window-private.h index 27ffc9298..bcac505dc 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -467,8 +467,6 @@ struct _MetaWindow /* Bypass compositor hints */ guint bypass_compositor; - - GSList *pending_pings; }; struct _MetaWindowClass @@ -744,17 +742,6 @@ void meta_window_handle_enter (MetaWindow *window, void meta_window_set_surface_mapped (MetaWindow *window, gboolean surface_mapped); -typedef void (* MetaWindowPingFunc) (MetaWindow *window, - guint32 timestamp, - gpointer user_data); - -void meta_window_ping (MetaWindow *window, - guint32 timestamp, - MetaWindowPingFunc ping_reply_func, - MetaWindowPingFunc ping_timeout_func, - void *user_data); -void meta_window_pong (MetaWindow *window, - guint32 timestamp); Window meta_window_get_toplevel_xwindow (MetaWindow *window); void meta_window_activate_full (MetaWindow *window, diff --git a/src/core/window.c b/src/core/window.c index 07468170e..ccd1749e8 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -69,26 +69,6 @@ static int destroying_windows_disallowed = 0; -/** - * MetaPingData: - * - * Describes a ping on a window. When we send a ping to a window, we build - * one of these structs, and it eventually gets passed to the timeout function - * or to the function which handles the response from the window. If the window - * does or doesn't respond to the ping, we use this information to deal with - * these facts; we have a handler function for each. - */ -typedef struct -{ - MetaWindow *window; - guint32 timestamp; - MetaWindowPingFunc ping_reply_func; - MetaWindowPingFunc ping_timeout_func; - void *user_data; - guint ping_timeout_id; -} MetaPingData; - -static void ping_data_free (MetaPingData *ping_data); static void update_sm_hints (MetaWindow *window); static void update_net_frame_extents (MetaWindow *window); @@ -1783,8 +1763,6 @@ meta_window_unmanage (MetaWindow *window, else meta_display_unregister_wayland_window (window->display, window); - g_slist_free_full (window->pending_pings, (GDestroyNotify) ping_data_free); - meta_prefs_remove_listener (prefs_changed_callback, window); meta_screen_queue_check_fullscreen (window->screen); @@ -10613,198 +10591,6 @@ meta_window_set_surface_mapped (MetaWindow *window, meta_window_queue (window, META_QUEUE_CALC_SHOWING); } -/* - * SECTION:pings - * - * Sometimes we want to see whether a window is responding, - * so we send it a "ping" message and see whether it sends us back a "pong" - * message within a reasonable time. Here we have a system which lets us - * nominate one function to be called if we get the pong in time and another - * function if we don't. The system is rather more complicated than it needs - * to be, since we only ever use it to destroy windows which are asked to - * close themselves and don't do so within a reasonable amount of time, and - * therefore we always use the same callbacks. It's possible that we might - * use it for other things in future, or on the other hand we might decide - * that we're never going to do so and simplify it a bit. - */ - -/** - * ping_data_free: - * - * Destructor for #MetaPingData structs. Will destroy the - * event source for the struct as well. - */ -static void -ping_data_free (MetaPingData *ping_data) -{ - MetaWindow *window = ping_data->window; - MetaDisplay *display = window->display; - - /* Remove the timeout */ - if (ping_data->ping_timeout_id != 0) - g_source_remove (ping_data->ping_timeout_id); - - g_hash_table_remove (display->pending_pings, &ping_data->timestamp); - - g_free (ping_data); -} - -/** - * meta_window_pong: - * @window: the window we got the pong on - * @timestamp: the timestamp that the client sent back - * - * Process the pong (the response message) from the ping we sent - * to the window. This involves removing the timeout, calling the - * reply handler function, and freeing memory. - */ -void -meta_window_pong (MetaWindow *window, - guint32 timestamp) -{ - GSList *tmp; - - meta_topic (META_DEBUG_PING, "Received a pong with timestamp %u\n", - timestamp); - - for (tmp = window->pending_pings; tmp; tmp = tmp->next) - { - MetaPingData *ping_data = tmp->data; - - if (timestamp == ping_data->timestamp) - { - meta_topic (META_DEBUG_PING, - "Matching ping found for pong %u\n", - ping_data->timestamp); - - /* Remove the ping data from the list */ - window->pending_pings = g_slist_remove (window->pending_pings, ping_data); - - /* Remove the timeout */ - if (ping_data->ping_timeout_id != 0) - { - g_source_remove (ping_data->ping_timeout_id); - ping_data->ping_timeout_id = 0; - } - - /* Call callback */ - (* ping_data->ping_reply_func) (window, - ping_data->timestamp, - ping_data->user_data); - - ping_data_free (ping_data); - - break; - } - } -} - -/* - * How long, in milliseconds, we should wait after pinging a window - * before deciding it's not going to get back to us. - */ -#define PING_TIMEOUT_DELAY 5000 - -/** - * ping_timeout: - * @data: All the information about this ping. It is a #MetaPingData - * cast to a #gpointer in order to be passable to a timeout function. - * This function will also free this parameter. - * - * Does whatever it is we decided to do when a window didn't respond - * to a ping. We also remove the ping from the display's list of - * pending pings. This function is called by the event loop when the timeout - * times out which we created at the start of the ping. - * - * Returns: Always returns %FALSE, because this function is called as a - * timeout and we don't want to run the timer again. - */ -static gboolean -ping_timeout (gpointer data) -{ - MetaPingData *ping_data; - - ping_data = data; - - ping_data->ping_timeout_id = 0; - - meta_topic (META_DEBUG_PING, - "Ping %u on window %s timed out\n", - ping_data->timestamp, ping_data->window->desc); - - (* ping_data->ping_timeout_func) (ping_data->window, ping_data->timestamp, ping_data->user_data); - - ping_data_free (ping_data); - - return FALSE; -} - -/** - * meta_window_ping: - * @window: The #MetaWindow to send the ping to - * @timestamp: The timestamp of the ping. Used for uniqueness. - * Cannot be CurrentTime; use a real timestamp! - * @ping_reply_func: The callback to call if we get a response. - * @ping_timeout_func: The callback to call if we don't get a response. - * @user_data: Arbitrary data that will be passed to the callback - * function. (In practice it's often a pointer to - * the window.) - * - * Sends a ping request to a window. The window must respond to - * the request within a certain amount of time. If it does, we - * will call one callback; if the time passes and we haven't had - * a response, we call a different callback. The window must have - * the hint showing that it can respond to a ping; if it doesn't, - * we call the "got a response" callback immediately and return. - * This function returns straight away after setting things up; - * the callbacks will be called from the event loop. - */ -void -meta_window_ping (MetaWindow *window, - guint32 timestamp, - MetaWindowPingFunc ping_reply_func, - MetaWindowPingFunc ping_timeout_func, - gpointer user_data) -{ - MetaPingData *ping_data; - MetaDisplay *display = window->display; - - if (timestamp == CurrentTime) - { - meta_warning ("Tried to ping a window with CurrentTime! Not allowed.\n"); - return; - } - - if (!window->net_wm_ping) - { - if (ping_reply_func) - (* ping_reply_func) (window, timestamp, user_data); - - return; - } - - ping_data = g_new (MetaPingData, 1); - ping_data->window = window; - ping_data->timestamp = timestamp; - ping_data->ping_reply_func = ping_reply_func; - ping_data->ping_timeout_func = ping_timeout_func; - ping_data->user_data = user_data; - ping_data->ping_timeout_id = g_timeout_add (PING_TIMEOUT_DELAY, ping_timeout, ping_data); - - window->pending_pings = g_slist_prepend (window->pending_pings, ping_data); - - g_hash_table_insert (display->pending_pings, &ping_data->timestamp, window); - - meta_topic (META_DEBUG_PING, - "Sending ping with timestamp %u to window %s\n", - timestamp, window->desc); - - if (window->client_type == META_WINDOW_CLIENT_TYPE_X11) - meta_window_send_icccm_message (window, display->atom__NET_WM_PING, timestamp); - else - meta_wayland_surface_ping (window->surface, timestamp); -} - Window meta_window_get_toplevel_xwindow (MetaWindow *window) { diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 39738af92..42f937c58 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -800,7 +800,7 @@ xdg_surface_pong (struct wl_client *client, MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface); - meta_window_pong (surface->window, serial); + meta_display_pong_for_serial (surface->window->display, serial); } static gboolean @@ -1017,7 +1017,7 @@ xdg_popup_pong (struct wl_client *client, MetaWaylandSurfaceExtension *xdg_popup = wl_resource_get_user_data (resource); MetaWaylandSurface *surface = wl_container_of (xdg_popup, surface, xdg_popup); - meta_window_pong (surface->window, serial); + meta_display_pong_for_serial (surface->window->display, serial); } static const struct xdg_popup_interface meta_wayland_xdg_popup_interface = { From f27f6aab78e2964953e224e744d6aa14e57e7831 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sat, 15 Feb 2014 10:26:43 -0500 Subject: [PATCH 495/889] Update to new xdg-shell pinging standards --- protocol/xdg-shell.xml | 56 ++++++++----------- src/wayland/meta-wayland-surface.c | 87 ++++++++++++++++++++---------- 2 files changed, 81 insertions(+), 62 deletions(-) diff --git a/protocol/xdg-shell.xml b/protocol/xdg-shell.xml index f0d04aa34..ef755b720 100644 --- a/protocol/xdg-shell.xml +++ b/protocol/xdg-shell.xml @@ -43,7 +43,7 @@ Use this enum to check the protocol version, and it will be updated automatically. - + @@ -84,6 +84,28 @@ + + + + The ping event asks the client if it's still alive. Pass the + serial specified in the event back to the compositor by sending + a "pong" request back with the specified serial. + + Compositors can use this to determine if the client is still + alive. It's unspecified what will happen if the client doesn't + respond to the ping request, or in what timeframe. Clients should + try to respond in a reasonable amount of time. + + + + + + + A client must respond to a ping event with a pong request or + the client may be deemed unresponsive. + + + @@ -176,22 +198,6 @@ - - - A client must respond to a ping event with a pong request or - the client may be deemed unresponsive. - - - - - - - Ping a client to check if it is receiving events and sending - requests. A client is expected to reply with a pong request. - - - - Start a pointer-driven move of the surface. @@ -447,22 +453,6 @@ - - - A client must respond to a ping event with a pong request or - the client may be deemed unresponsive. - - - - - - - Ping a client to check if it is receiving events and sending - requests. A client is expected to reply with a pong request. - - - - The popup_done event is sent out when a popup grab is broken, diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 42f937c58..f19cc5cd3 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -717,6 +717,16 @@ xdg_shell_use_unstable_version (struct wl_client *client, g_warning ("Bad xdg_shell version: %d", version); } +static void +xdg_shell_pong (struct wl_client *client, + struct wl_resource *resource, + uint32_t serial) +{ + MetaDisplay *display = meta_get_display (); + + meta_display_pong_for_serial (display, serial); +} + static void xdg_surface_destructor (struct wl_resource *resource) { @@ -792,17 +802,6 @@ xdg_surface_set_app_id (struct wl_client *client, meta_window_set_wm_class (surface->window, app_id, app_id); } -static void -xdg_surface_pong (struct wl_client *client, - struct wl_resource *resource, - guint32 serial) -{ - MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface); - - meta_display_pong_for_serial (surface->window->display, serial); -} - static gboolean begin_grab_op_on_surface (MetaWaylandSurface *surface, MetaWaylandSeat *seat, @@ -958,7 +957,6 @@ static const struct xdg_surface_interface meta_wayland_xdg_surface_interface = { xdg_surface_set_margin, xdg_surface_set_title, xdg_surface_set_app_id, - xdg_surface_pong, xdg_surface_move, xdg_surface_resize, xdg_surface_set_output, @@ -1009,20 +1007,8 @@ xdg_popup_destroy (struct wl_client *client, wl_resource_destroy (resource); } -static void -xdg_popup_pong (struct wl_client *client, - struct wl_resource *resource, - uint32_t serial) -{ - MetaWaylandSurfaceExtension *xdg_popup = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = wl_container_of (xdg_popup, surface, xdg_popup); - - meta_display_pong_for_serial (surface->window->display, serial); -} - static const struct xdg_popup_interface meta_wayland_xdg_popup_interface = { xdg_popup_destroy, - xdg_popup_pong, }; static void @@ -1076,8 +1062,37 @@ static const struct xdg_shell_interface meta_wayland_xdg_shell_interface = { xdg_shell_use_unstable_version, xdg_shell_get_xdg_surface, xdg_shell_get_xdg_popup, + xdg_shell_pong, }; +typedef struct { + struct wl_resource *resource; + struct wl_listener client_destroy_listener; +} XdgShell; + +static void +xdg_shell_handle_client_destroy (struct wl_listener *listener, void *data) +{ + XdgShell *xdg_shell = wl_container_of (listener, xdg_shell, client_destroy_listener); + g_slice_free (XdgShell, data); +} + +static struct wl_resource * +get_xdg_shell_for_client (struct wl_client *client) +{ + struct wl_listener *listener; + XdgShell *xdg_shell; + + listener = wl_client_get_destroy_listener (client, xdg_shell_handle_client_destroy); + + /* No xdg_shell has been bound for this client */ + if (listener == NULL) + return NULL; + + xdg_shell = wl_container_of (listener, xdg_shell, client_destroy_listener); + return xdg_shell->resource; +} + static void bind_xdg_shell (struct wl_client *client, void *data, @@ -1085,6 +1100,7 @@ bind_xdg_shell (struct wl_client *client, guint32 id) { struct wl_resource *resource; + XdgShell *xdg_shell; if (version != 1) { @@ -1092,8 +1108,15 @@ bind_xdg_shell (struct wl_client *client, return; } + xdg_shell = g_slice_new (XdgShell); + resource = wl_resource_create (client, &xdg_shell_interface, 1, id); wl_resource_set_implementation (resource, &meta_wayland_xdg_shell_interface, data, NULL); + xdg_shell->resource = wl_resource_create (client, &xdg_shell_interface, 1, id); + wl_resource_set_implementation (xdg_shell->resource, &meta_wayland_xdg_shell_interface, data, NULL); + + xdg_shell->client_destroy_listener.notify = xdg_shell_handle_client_destroy; + wl_client_add_destroy_listener (client, &xdg_shell->client_destroy_listener); } static void @@ -1514,12 +1537,18 @@ meta_wayland_surface_focused_unset (MetaWaylandSurface *surface) void meta_wayland_surface_ping (MetaWaylandSurface *surface, - guint32 timestamp) + guint32 serial) { - if (surface->xdg_surface.resource) - xdg_surface_send_ping (surface->xdg_surface.resource, timestamp); - else if (surface->xdg_popup.resource) - xdg_popup_send_ping (surface->xdg_popup.resource, timestamp); + struct wl_client *client = wl_resource_get_client (surface->resource); + struct wl_resource *xdg_shell = get_xdg_shell_for_client (client); + + if (xdg_shell == NULL) + { + g_warning ("Trying to ping a surface without an xdg_shell bound. How does this happen?"); + return; + } + + xdg_shell_send_ping (xdg_shell, serial); } void From d39baeb8ad860f76341015c3ea279ecde4c1a97f Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 17 Feb 2014 12:51:44 -0500 Subject: [PATCH 496/889] wayland-surface: Destroy the right thing data is the wl_client, which we don't want to destroy. Destroy our XdgShell pointer instead. --- src/wayland/meta-wayland-surface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index f19cc5cd3..a63bc9224 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -1074,7 +1074,7 @@ static void xdg_shell_handle_client_destroy (struct wl_listener *listener, void *data) { XdgShell *xdg_shell = wl_container_of (listener, xdg_shell, client_destroy_listener); - g_slice_free (XdgShell, data); + g_slice_free (XdgShell, xdg_shell); } static struct wl_resource * From e3a0f2c546f5cc69f4ca748e48117f271debdddd Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 17 Feb 2014 13:48:01 -0500 Subject: [PATCH 497/889] default: Don't wait to show the stage We can show it immediately now... --- src/compositor/plugins/default.c | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/src/compositor/plugins/default.c b/src/compositor/plugins/default.c index 4d51b309c..1c8d741fc 100644 --- a/src/compositor/plugins/default.c +++ b/src/compositor/plugins/default.c @@ -289,20 +289,6 @@ on_switch_workspace_effect_complete (ClutterTimeline *timeline, gpointer data) meta_plugin_switch_workspace_completed (plugin); } -static gboolean -show_stage (MetaPlugin *plugin) -{ - MetaScreen *screen; - ClutterActor *stage; - - screen = meta_plugin_get_screen (plugin); - stage = meta_get_stage_for_screen (screen); - - clutter_actor_show (stage); - - return FALSE; -} - static void on_monitors_changed (MetaScreen *screen, MetaPlugin *plugin) @@ -355,10 +341,7 @@ start (MetaPlugin *plugin) G_CALLBACK (on_monitors_changed), plugin); on_monitors_changed (screen, plugin); - meta_later_add (META_LATER_BEFORE_REDRAW, - (GSourceFunc) show_stage, - plugin, - NULL); + clutter_actor_show (meta_get_stage_for_screen (screen)); } static void From 2f4563132aa8eabd824b9731b11a6c55ff592aac Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 17 Feb 2014 13:47:58 -0500 Subject: [PATCH 498/889] default: Use a consistent rand() for monitor backgrounds g_random_int() is seeded with /dev/urandom, so it's not consistent. --- src/compositor/plugins/default.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/compositor/plugins/default.c b/src/compositor/plugins/default.c index 1c8d741fc..edfb24bbb 100644 --- a/src/compositor/plugins/default.c +++ b/src/compositor/plugins/default.c @@ -295,6 +295,7 @@ on_monitors_changed (MetaScreen *screen, { MetaDefaultPlugin *self = META_DEFAULT_PLUGIN (plugin); int i, n; + GRand *rand = g_rand_new_with_seed (12345); clutter_actor_destroy_all_children (self->priv->background_group); @@ -317,14 +318,16 @@ on_monitors_changed (MetaScreen *screen, reproducible. */ clutter_color_init (&color, - g_random_int () % 255, - g_random_int () % 255, - g_random_int () % 255, + g_rand_int_range (rand, 0, 255), + g_rand_int_range (rand, 0, 255), + g_rand_int_range (rand, 0, 255), 255); clutter_actor_set_background_color (background, &color); clutter_actor_add_child (self->priv->background_group, background); } + + g_rand_free (rand); } static void From f9f2a82e1807ab7f9f1e669c6fc7ec4dd1642298 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 17 Feb 2014 17:57:14 -0500 Subject: [PATCH 499/889] xwayland: Don't -retro This means we see black instead of checkerboard for now when resizing, but that's better. --- src/wayland/meta-xwayland.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index 753af7885..b9c9de3e8 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -295,7 +295,7 @@ meta_xwayland_start (MetaXWaylandManager *manager, char **env; char *fd_string; char *log_path; - char *args[11]; + char *args[10]; GError *error; wl_global_create (wl_display, &xserver_interface, @@ -361,13 +361,12 @@ meta_xwayland_start (MetaXWaylandManager *manager, args[1] = manager->display_name; args[2] = "-wayland"; args[3] = "-rootless"; - args[4] = "-retro"; - args[5] = "-noreset"; - args[6] = "-logfile"; - args[7] = log_path; - args[8] = "-nolisten"; - args[9] = "all"; - args[10] = NULL; + args[4] = "-noreset"; + args[5] = "-logfile"; + args[6] = log_path; + args[7] = "-nolisten"; + args[8] = "all"; + args[9] = NULL; error = NULL; if (g_spawn_async (NULL, /* cwd */ From c485637a6132a86d6a6f802cfa55a8eb55d34705 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 17 Feb 2014 17:53:54 -0500 Subject: [PATCH 500/889] default: Don't use anchor points It doesn't work now that we set the pivot point. This breaks the maximize effect, but it fixes the destroy effect. The maximize effect looks bad anyway, so it's not too important to me. --- src/compositor/plugins/default.c | 26 ++------------------------ 1 file changed, 2 insertions(+), 24 deletions(-) diff --git a/src/compositor/plugins/default.c b/src/compositor/plugins/default.c index edfb24bbb..de63007ec 100644 --- a/src/compositor/plugins/default.c +++ b/src/compositor/plugins/default.c @@ -469,8 +469,6 @@ on_minimize_effect_complete (ClutterTimeline *timeline, EffectCompleteData *data /* FIXME - we shouldn't assume the original scale, it should be saved * at the start of the effect */ clutter_actor_set_scale (data->actor, 1.0, 1.0); - clutter_actor_move_anchor_point_from_gravity (data->actor, - CLUTTER_GRAVITY_NORTH_WEST); /* Now notify the manager that we are done with this effect */ meta_plugin_minimize_completed (plugin, window_actor); @@ -507,9 +505,6 @@ minimize (MetaPlugin *plugin, MetaWindowActor *window_actor) apriv->is_minimized = TRUE; - clutter_actor_move_anchor_point_from_gravity (actor, - CLUTTER_GRAVITY_CENTER); - animation = clutter_actor_animate (actor, CLUTTER_EASE_IN_SINE, MINIMIZE_TIMEOUT, @@ -548,8 +543,6 @@ on_maximize_effect_complete (ClutterTimeline *timeline, EffectCompleteData *data /* FIXME - don't assume the original scale was 1.0 */ clutter_actor_set_scale (data->actor, 1.0, 1.0); - clutter_actor_move_anchor_point_from_gravity (data->actor, - CLUTTER_GRAVITY_NORTH_WEST); /* Now notify the manager that we are done with this effect */ meta_plugin_maximize_completed (plugin, window_actor); @@ -574,10 +567,8 @@ maximize (MetaPlugin *plugin, ClutterActor *actor = CLUTTER_ACTOR (window_actor); MetaWindow *meta_window = meta_window_actor_get_meta_window (window_actor); - gdouble scale_x = 1.0; - gdouble scale_y = 1.0; - gfloat anchor_x = 0; - gfloat anchor_y = 0; + gdouble scale_x = 1.0; + gdouble scale_y = 1.0; type = meta_window_get_window_type (meta_window); @@ -601,13 +592,6 @@ maximize (MetaPlugin *plugin, scale_x = (gdouble)end_width / (gdouble) width; scale_y = (gdouble)end_height / (gdouble) height; - anchor_x = (gdouble)(x - end_x)*(gdouble)width / - ((gdouble)(end_width - width)); - anchor_y = (gdouble)(y - end_y)*(gdouble)height / - ((gdouble)(end_height - height)); - - clutter_actor_move_anchor_point (actor, anchor_x, anchor_y); - animation = clutter_actor_animate (actor, CLUTTER_EASE_IN_SINE, MAXIMIZE_TIMEOUT, @@ -662,9 +646,6 @@ on_map_effect_complete (ClutterTimeline *timeline, EffectCompleteData *data) apriv->tml_map = NULL; - clutter_actor_move_anchor_point_from_gravity (data->actor, - CLUTTER_GRAVITY_NORTH_WEST); - /* Now notify the manager that we are done with this effect */ meta_plugin_map_completed (plugin, window_actor); @@ -750,9 +731,6 @@ destroy (MetaPlugin *plugin, MetaWindowActor *window_actor) EffectCompleteData *data = g_new0 (EffectCompleteData, 1); ActorPrivate *apriv = get_actor_private (window_actor); - clutter_actor_move_anchor_point_from_gravity (actor, - CLUTTER_GRAVITY_CENTER); - animation = clutter_actor_animate (actor, CLUTTER_EASE_IN_SINE, DESTROY_TIMEOUT, From 2e7a56a28fc3596a6ec11c1d95b9676c6019941c Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 17 Feb 2014 19:10:25 -0500 Subject: [PATCH 501/889] wayland: Rename resource_destroy_cb to wl_surface_destructor So it doesn't seem like a wl_listener callback. --- src/wayland/meta-wayland-surface.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index a63bc9224..496a6bf18 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -615,7 +615,7 @@ destroy_window (MetaWaylandSurface *surface) } static void -meta_wayland_surface_resource_destroy_cb (struct wl_resource *resource) +wl_surface_destructor (struct wl_resource *resource) { MetaWaylandSurface *surface = wl_resource_get_user_data (resource); @@ -652,14 +652,13 @@ meta_wayland_surface_create (MetaWaylandCompositor *compositor, surface->compositor = compositor; surface->resource = wl_resource_create (client, &wl_surface_interface, version, id); - wl_resource_set_implementation (surface->resource, &meta_wayland_surface_interface, surface, - meta_wayland_surface_resource_destroy_cb); + wl_resource_set_implementation (surface->resource, &meta_wayland_surface_interface, surface, wl_surface_destructor); + + surface->buffer_destroy_listener.notify = surface_handle_buffer_destroy; + surface->surface_actor = g_object_ref_sink (meta_surface_actor_new ()); double_buffered_state_init (&surface->pending); - surface->buffer_destroy_listener.notify = surface_handle_buffer_destroy; - - surface->surface_actor = g_object_ref_sink (meta_surface_actor_new ()); return surface; } From 515dc08a9762ae2d5ddf485cb25eab062a88bf77 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 17 Feb 2014 19:13:16 -0500 Subject: [PATCH 502/889] pointer/keyboard: Do a series of renames to our listener as well --- src/wayland/meta-wayland-keyboard.c | 13 ++++++------- src/wayland/meta-wayland-keyboard.h | 2 +- src/wayland/meta-wayland-pointer.c | 13 ++++++------- src/wayland/meta-wayland-pointer.h | 2 +- 4 files changed, 14 insertions(+), 16 deletions(-) diff --git a/src/wayland/meta-wayland-keyboard.c b/src/wayland/meta-wayland-keyboard.c index 382922295..3c4d1ee9a 100644 --- a/src/wayland/meta-wayland-keyboard.c +++ b/src/wayland/meta-wayland-keyboard.c @@ -222,10 +222,9 @@ err_keymap_str: } static void -lose_keyboard_focus (struct wl_listener *listener, void *data) +keyboard_handle_focus_surface_destroy (struct wl_listener *listener, void *data) { - MetaWaylandKeyboard *keyboard = - wl_container_of (listener, keyboard, focus_listener); + MetaWaylandKeyboard *keyboard = wl_container_of (listener, keyboard, focus_surface_listener); keyboard->focus_resource = NULL; keyboard->focus = NULL; @@ -340,7 +339,7 @@ meta_wayland_keyboard_init (MetaWaylandKeyboard *keyboard, wl_list_init (&keyboard->resource_list); wl_array_init (&keyboard->keys); - keyboard->focus_listener.notify = lose_keyboard_focus; + keyboard->focus_surface_listener.notify = keyboard_handle_focus_surface_destroy; keyboard->default_grab.interface = &default_keyboard_grab_interface; keyboard->default_grab.keyboard = keyboard; keyboard->grab = &keyboard->default_grab; @@ -522,7 +521,7 @@ meta_wayland_keyboard_set_focus (MetaWaylandKeyboard *keyboard, struct wl_display *display = wl_client_get_display (client); serial = wl_display_next_serial (display); wl_keyboard_send_leave (resource, serial, keyboard->focus->resource); - wl_list_remove (&keyboard->focus_listener.link); + wl_list_remove (&keyboard->focus_surface_listener.link); meta_wayland_surface_focused_unset (keyboard->focus); } @@ -557,7 +556,7 @@ meta_wayland_keyboard_set_focus (MetaWaylandKeyboard *keyboard, wl_keyboard_send_enter (resource, serial, surface->resource, &keyboard->keys); } - wl_resource_add_destroy_listener (resource, &keyboard->focus_listener); + wl_resource_add_destroy_listener (resource, &keyboard->focus_surface_listener); keyboard->focus_serial = serial; meta_wayland_surface_focused_set (surface); @@ -591,7 +590,7 @@ meta_wayland_keyboard_release (MetaWaylandKeyboard *keyboard) /* XXX: What about keyboard->resource_list? */ if (keyboard->focus_resource) - wl_list_remove (&keyboard->focus_listener.link); + wl_list_remove (&keyboard->focus_surface_listener.link); wl_array_release (&keyboard->keys); } diff --git a/src/wayland/meta-wayland-keyboard.h b/src/wayland/meta-wayland-keyboard.h index 4354faf21..d528073e7 100644 --- a/src/wayland/meta-wayland-keyboard.h +++ b/src/wayland/meta-wayland-keyboard.h @@ -94,7 +94,7 @@ struct _MetaWaylandKeyboard struct wl_list resource_list; MetaWaylandSurface *focus; struct wl_resource *focus_resource; - struct wl_listener focus_listener; + struct wl_listener focus_surface_listener; uint32_t focus_serial; MetaWaylandKeyboardGrab *grab; diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index ca65ececa..a0ab56a93 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -64,10 +64,9 @@ meta_wayland_pointer_get_seat (MetaWaylandPointer *pointer) } static void -lose_pointer_focus (struct wl_listener *listener, void *data) +pointer_handle_focus_surface_destroy (struct wl_listener *listener, void *data) { - MetaWaylandPointer *pointer = - wl_container_of (listener, pointer, focus_listener); + MetaWaylandPointer *pointer = wl_container_of (listener, pointer, focus_surface_listener); pointer->focus_resource = NULL; pointer->focus = NULL; @@ -267,7 +266,7 @@ meta_wayland_pointer_init (MetaWaylandPointer *pointer, memset (pointer, 0, sizeof *pointer); wl_list_init (&pointer->resource_list); - pointer->focus_listener.notify = lose_pointer_focus; + pointer->focus_surface_listener.notify = pointer_handle_focus_surface_destroy; pointer->default_grab.interface = &default_pointer_grab_interface; pointer->default_grab.pointer = pointer; pointer->grab = &pointer->default_grab; @@ -289,7 +288,7 @@ meta_wayland_pointer_release (MetaWaylandPointer *pointer) { /* XXX: What about pointer->resource_list? */ if (pointer->focus_resource) - wl_list_remove (&pointer->focus_listener.link); + wl_list_remove (&pointer->focus_surface_listener.link); pointer->focus = NULL; pointer->focus_resource = NULL; @@ -332,7 +331,7 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer, wl_pointer_send_leave (resource, serial, pointer->focus->resource); } - wl_list_remove (&pointer->focus_listener.link); + wl_list_remove (&pointer->focus_surface_listener.link); } resource = find_resource_for_surface (&pointer->resource_list, surface); @@ -365,7 +364,7 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer, wl_fixed_to_int (pointer->x), wl_fixed_to_int (pointer->y)); wl_pointer_send_enter (resource, serial, surface->resource, sx, sy); - wl_resource_add_destroy_listener (resource, &pointer->focus_listener); + wl_resource_add_destroy_listener (resource, &pointer->focus_surface_listener); pointer->focus_serial = serial; } diff --git a/src/wayland/meta-wayland-pointer.h b/src/wayland/meta-wayland-pointer.h index 95a4b5e13..d753d5f60 100644 --- a/src/wayland/meta-wayland-pointer.h +++ b/src/wayland/meta-wayland-pointer.h @@ -48,7 +48,7 @@ struct _MetaWaylandPointer struct wl_list resource_list; MetaWaylandSurface *focus; struct wl_resource *focus_resource; - struct wl_listener focus_listener; + struct wl_listener focus_surface_listener; guint32 focus_serial; guint32 click_serial; From b65649186d8487ea3aefad5da0c1a609543e329e Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 17 Feb 2014 19:15:54 -0500 Subject: [PATCH 503/889] pointer/keyboard: Put the destroy listener on the right resource We care about when the surface is destroyed, not when the wl_pointer slash wl_keyboard resource is destroyed. --- src/wayland/meta-wayland-keyboard.c | 2 +- src/wayland/meta-wayland-pointer.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wayland/meta-wayland-keyboard.c b/src/wayland/meta-wayland-keyboard.c index 3c4d1ee9a..2787bb01d 100644 --- a/src/wayland/meta-wayland-keyboard.c +++ b/src/wayland/meta-wayland-keyboard.c @@ -556,7 +556,7 @@ meta_wayland_keyboard_set_focus (MetaWaylandKeyboard *keyboard, wl_keyboard_send_enter (resource, serial, surface->resource, &keyboard->keys); } - wl_resource_add_destroy_listener (resource, &keyboard->focus_surface_listener); + wl_resource_add_destroy_listener (surface->resource, &keyboard->focus_surface_listener); keyboard->focus_serial = serial; meta_wayland_surface_focused_set (surface); diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index a0ab56a93..189a99bd0 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -364,7 +364,7 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer, wl_fixed_to_int (pointer->x), wl_fixed_to_int (pointer->y)); wl_pointer_send_enter (resource, serial, surface->resource, sx, sy); - wl_resource_add_destroy_listener (resource, &pointer->focus_surface_listener); + wl_resource_add_destroy_listener (surface->resource, &pointer->focus_surface_listener); pointer->focus_serial = serial; } From ed185801189d8b1b5e9bd3bdda5194f81e4aa8b3 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 17 Feb 2014 19:27:18 -0500 Subject: [PATCH 504/889] default: Improve the destroy effect as well --- src/compositor/plugins/default.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/compositor/plugins/default.c b/src/compositor/plugins/default.c index de63007ec..ae3352286 100644 --- a/src/compositor/plugins/default.c +++ b/src/compositor/plugins/default.c @@ -32,7 +32,7 @@ #include #include -#define DESTROY_TIMEOUT 250 +#define DESTROY_TIMEOUT 100 #define MINIMIZE_TIMEOUT 250 #define MAXIMIZE_TIMEOUT 250 #define MAP_TIMEOUT 250 @@ -732,10 +732,11 @@ destroy (MetaPlugin *plugin, MetaWindowActor *window_actor) ActorPrivate *apriv = get_actor_private (window_actor); animation = clutter_actor_animate (actor, - CLUTTER_EASE_IN_SINE, + CLUTTER_EASE_OUT_QUAD, DESTROY_TIMEOUT, - "scale-x", 0.0, - "scale-y", 1.0, + "opacity", 0, + "scale-x", 0.8, + "scale-y", 0.8, NULL); apriv->tml_destroy = clutter_animation_get_timeline (animation); data->plugin = plugin; From f26de405ddd299604f0bb1aba8fd828876e3dc13 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 17 Feb 2014 20:41:36 -0500 Subject: [PATCH 505/889] main: Remove clutter / cogl option groups Neither of these groups are too useful, and all the switches useful for debugging can also be controlled by envvars. --- src/core/main.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/src/core/main.c b/src/core/main.c index 4a1f5e069..c4bdeee4b 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -254,19 +254,8 @@ meta_get_option_context (void) bindtextdomain (GETTEXT_PACKAGE, MUTTER_LOCALEDIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); - /* We must set the windowing backend here, because Clutter creates the backend - object when the first call is made. - - We consider running from mutter-launch equivalent to running from bare metal. - */ - if (getenv ("WESTON_LAUNCHER_SOCK")) - clutter_set_windowing_backend (CLUTTER_WINDOWING_EGL); - ctx = g_option_context_new (NULL); g_option_context_add_main_entries (ctx, meta_options, GETTEXT_PACKAGE); - g_option_context_add_group (ctx, clutter_get_option_group_without_init ()); - g_option_context_add_group (ctx, cogl_get_option_group ()); - return ctx; } @@ -411,6 +400,10 @@ meta_init (void) if (g_getenv ("MUTTER_DEBUG")) meta_set_debugging (TRUE); + /* We consider running from mutter-launch equivalent to running from bare metal. */ + if (getenv ("WESTON_LAUNCHER_SOCK")) + clutter_set_windowing_backend (CLUTTER_WINDOWING_EGL); + meta_set_is_wayland_compositor (opt_wayland); if (g_get_home_dir ()) @@ -442,7 +435,7 @@ meta_init (void) meta_fatal ("Can't specify both SM save file and SM client id\n"); meta_main_loop = g_main_loop_new (NULL, FALSE); - + meta_ui_init (); /* If we are running with wayland then we don't wait until we have From 304a525744189f8780d56b79ad15c853ea7a7cd9 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 17 Feb 2014 20:49:04 -0500 Subject: [PATCH 506/889] wayland: Remove is_native from seat We can easily do this with a Clutter backend check instead... --- src/wayland/meta-wayland-keyboard.c | 12 +++++++----- src/wayland/meta-wayland-keyboard.h | 4 +--- src/wayland/meta-wayland-pointer.c | 16 +++++++++++----- src/wayland/meta-wayland-pointer.h | 3 +-- src/wayland/meta-wayland-seat.c | 8 +++----- src/wayland/meta-wayland-seat.h | 3 +-- src/wayland/meta-wayland.c | 2 +- 7 files changed, 25 insertions(+), 23 deletions(-) diff --git a/src/wayland/meta-wayland-keyboard.c b/src/wayland/meta-wayland-keyboard.c index 2787bb01d..566a59693 100644 --- a/src/wayland/meta-wayland-keyboard.c +++ b/src/wayland/meta-wayland-keyboard.c @@ -201,13 +201,17 @@ meta_wayland_keyboard_take_keymap (MetaWaylandKeyboard *keyboard, strcpy (xkb_info->keymap_area, keymap_str); free (keymap_str); - if (keyboard->is_evdev) +#if defined(CLUTTER_WINDOWING_EGL) + /* XXX -- the evdev backend can be used regardless of the + * windowing backend. To do this properly we need a Clutter + * API to check the input backend. */ + if (clutter_check_windowing_backend (CLUTTER_WINDOWING_EGL)) { ClutterDeviceManager *manager; - manager = clutter_device_manager_get_default (); clutter_evdev_set_keyboard_map (manager, xkb_info->keymap); } +#endif inform_clients_of_new_keymap (keyboard, flags); @@ -331,8 +335,7 @@ static MetaWaylandKeyboardGrabInterface modal_grab = { gboolean meta_wayland_keyboard_init (MetaWaylandKeyboard *keyboard, - struct wl_display *display, - gboolean is_evdev) + struct wl_display *display) { memset (keyboard, 0, sizeof *keyboard); keyboard->xkb_info.keymap_fd = -1; @@ -347,7 +350,6 @@ meta_wayland_keyboard_init (MetaWaylandKeyboard *keyboard, keyboard->display = display; keyboard->xkb_context = xkb_context_new (0 /* flags */); - keyboard->is_evdev = is_evdev; /* Compute a default until gnome-settings-daemon starts and sets the appropriate values diff --git a/src/wayland/meta-wayland-keyboard.h b/src/wayland/meta-wayland-keyboard.h index d528073e7..fd87c8643 100644 --- a/src/wayland/meta-wayland-keyboard.h +++ b/src/wayland/meta-wayland-keyboard.h @@ -110,7 +110,6 @@ struct _MetaWaylandKeyboard struct wl_display *display; struct xkb_context *xkb_context; - gboolean is_evdev; MetaWaylandXkbInfo xkb_info; MetaWaylandKeyboardGrab input_method_grab; @@ -119,8 +118,7 @@ struct _MetaWaylandKeyboard gboolean meta_wayland_keyboard_init (MetaWaylandKeyboard *keyboard, - struct wl_display *display, - gboolean is_evdev); + struct wl_display *display); typedef enum { META_WAYLAND_KEYBOARD_SKIP_XCLIENTS = 1, diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index 189a99bd0..59ed0934e 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -257,8 +257,7 @@ pointer_constrain_callback (ClutterInputDevice *device, } void -meta_wayland_pointer_init (MetaWaylandPointer *pointer, - gboolean is_native) +meta_wayland_pointer_init (MetaWaylandPointer *pointer) { ClutterDeviceManager *manager; ClutterInputDevice *device; @@ -274,9 +273,16 @@ meta_wayland_pointer_init (MetaWaylandPointer *pointer, manager = clutter_device_manager_get_default (); device = clutter_device_manager_get_core_device (manager, CLUTTER_POINTER_DEVICE); - if (is_native) - clutter_evdev_set_pointer_constrain_callback (manager, pointer_constrain_callback, - pointer, NULL); +#if defined(CLUTTER_WINDOWING_EGL) + /* XXX -- the evdev backend can be used regardless of the + * windowing backend. To do this properly we need a Clutter + * API to check the input backend. */ + if (clutter_check_windowing_backend (CLUTTER_WINDOWING_EGL)) + { + clutter_evdev_set_pointer_constrain_callback (manager, pointer_constrain_callback, + pointer, NULL); + } +#endif clutter_input_device_get_coords (device, NULL, ¤t); pointer->x = wl_fixed_from_double (current.x); diff --git a/src/wayland/meta-wayland-pointer.h b/src/wayland/meta-wayland-pointer.h index d753d5f60..e5ee4c1c5 100644 --- a/src/wayland/meta-wayland-pointer.h +++ b/src/wayland/meta-wayland-pointer.h @@ -67,8 +67,7 @@ struct _MetaWaylandPointer }; void -meta_wayland_pointer_init (MetaWaylandPointer *pointer, - gboolean is_native); +meta_wayland_pointer_init (MetaWaylandPointer *pointer); void meta_wayland_pointer_release (MetaWaylandPointer *pointer); diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c index 83987cb08..9e838f90f 100644 --- a/src/wayland/meta-wayland-seat.c +++ b/src/wayland/meta-wayland-seat.c @@ -204,8 +204,7 @@ pointer_handle_cursor_surface_destroy (struct wl_listener *listener, void *data) } MetaWaylandSeat * -meta_wayland_seat_new (struct wl_display *display, - gboolean is_native) +meta_wayland_seat_new (struct wl_display *display) { MetaWaylandSeat *seat = g_new0 (MetaWaylandSeat, 1); @@ -213,9 +212,8 @@ meta_wayland_seat_new (struct wl_display *display, wl_list_init (&seat->base_resource_list); wl_list_init (&seat->data_device_resource_list); - meta_wayland_pointer_init (&seat->pointer, is_native); - - meta_wayland_keyboard_init (&seat->keyboard, display, is_native); + meta_wayland_pointer_init (&seat->pointer); + meta_wayland_keyboard_init (&seat->keyboard, display); seat->display = display; diff --git a/src/wayland/meta-wayland-seat.h b/src/wayland/meta-wayland-seat.h index f2c7fc249..cee2ea662 100644 --- a/src/wayland/meta-wayland-seat.h +++ b/src/wayland/meta-wayland-seat.h @@ -74,8 +74,7 @@ struct _MetaWaylandSeat }; MetaWaylandSeat * -meta_wayland_seat_new (struct wl_display *display, - gboolean is_native); +meta_wayland_seat_new (struct wl_display *display); void meta_wayland_seat_update_pointer (MetaWaylandSeat *seat, diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index 254b4d09b..16b0156a2 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -698,7 +698,7 @@ meta_wayland_init (void) meta_wayland_data_device_manager_init (compositor->wayland_display); - compositor->seat = meta_wayland_seat_new (compositor->wayland_display, compositor->native); + compositor->seat = meta_wayland_seat_new (compositor->wayland_display); meta_wayland_init_shell (compositor); From 4e6321c239208b39db43551fcf30d98feb348b85 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 17 Feb 2014 20:51:35 -0500 Subject: [PATCH 507/889] monitor: Kill off another use of is_native --- src/core/monitor.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/core/monitor.c b/src/core/monitor.c index 4f4d10587..110bb406f 100644 --- a/src/core/monitor.c +++ b/src/core/monitor.c @@ -356,19 +356,25 @@ make_logical_config (MetaMonitorManager *manager) static GType get_default_backend (void) { - if (meta_is_wayland_compositor ()) +#if defined(CLUTTER_WINDOWING_EGL) + if (clutter_check_windowing_backend (CLUTTER_WINDOWING_EGL)) + return META_TYPE_MONITOR_MANAGER_KMS; +#endif + +#if defined(CLUTTER_WINDOWING_X11) + if (clutter_check_windowing_backend (CLUTTER_WINDOWING_X11)) { - MetaWaylandCompositor *compositor; - - compositor = meta_wayland_compositor_get_default (); - - if (meta_wayland_compositor_is_native (compositor)) - return META_TYPE_MONITOR_MANAGER_KMS; - else + /* If we're a Wayland compositor using the X11 backend, + * we're a nested configuration, so return the dummy + * monitor setup. */ + if (meta_is_wayland_compositor ()) return META_TYPE_MONITOR_MANAGER; + else + return META_TYPE_MONITOR_MANAGER_XRANDR; } - else - return META_TYPE_MONITOR_MANAGER_XRANDR; +#endif + + g_assert_not_reached (); } static MetaMonitorManager * From 6038877c4c3b966d2d50117ffc71a154c1d56a4b Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 17 Feb 2014 21:11:57 -0500 Subject: [PATCH 508/889] cursor-tracker: Kill off the last user of is_native --- src/core/meta-cursor-tracker.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/core/meta-cursor-tracker.c b/src/core/meta-cursor-tracker.c index a7842f682..96d2b0528 100644 --- a/src/core/meta-cursor-tracker.c +++ b/src/core/meta-cursor-tracker.c @@ -570,12 +570,14 @@ make_wayland_cursor_tracker (MetaScreen *screen) compositor = meta_wayland_compositor_get_default (); compositor->seat->cursor_tracker = self; - if (meta_wayland_compositor_is_native (compositor)) +#if defined(CLUTTER_WINDOWING_EGL) + if (clutter_check_windowing_backend (CLUTTER_WINDOWING_EGL)) { CoglRenderer *cogl_renderer = cogl_display_get_renderer (cogl_context_get_display (ctx)); self->drm_fd = cogl_kms_renderer_get_kms_fd (cogl_renderer); self->gbm = gbm_create_device (self->drm_fd); } +#endif monitors = meta_monitor_manager_get (); g_signal_connect_object (monitors, "monitors-changed", From dcd628d289cdddb4bc2889392abf473c4e1b5693 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 17 Feb 2014 21:13:09 -0500 Subject: [PATCH 509/889] wayland: Kill meta_wayland_compositor_is_native It's unused. Squash the remaining functionality, setting the DRM FD, into the main path. --- src/wayland/meta-wayland-private.h | 3 -- src/wayland/meta-wayland.c | 46 ++++++------------------------ 2 files changed, 8 insertions(+), 41 deletions(-) diff --git a/src/wayland/meta-wayland-private.h b/src/wayland/meta-wayland-private.h index cba6ed397..69de1b8b8 100644 --- a/src/wayland/meta-wayland-private.h +++ b/src/wayland/meta-wayland-private.h @@ -87,7 +87,6 @@ struct _MetaWaylandCompositor MetaXWaylandManager xwayland_manager; MetaLauncher *launcher; - gboolean native; MetaWaylandSeat *seat; }; @@ -106,8 +105,6 @@ void meta_wayland_compositor_set_input_focus (MetaWaylandComp gboolean meta_wayland_compositor_handle_event (MetaWaylandCompositor *compositor, const ClutterEvent *event); -gboolean meta_wayland_compositor_is_native (MetaWaylandCompositor *compositor); - MetaWaylandBuffer * meta_wayland_buffer_from_resource (struct wl_resource *resource); void meta_wayland_buffer_ref (MetaWaylandBuffer *buffer); void meta_wayland_buffer_unref (MetaWaylandBuffer *buffer); diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index 16b0156a2..6b6c1fef1 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -600,30 +600,11 @@ meta_wayland_log_func (const char *fmt, g_free (str); } -static gboolean -are_we_native (int *out_drm_fd) -{ - ClutterBackend *backend = clutter_get_default_backend (); - CoglContext *cogl_context = clutter_backend_get_cogl_context (backend); - CoglRenderer *cogl_renderer = cogl_display_get_renderer (cogl_context_get_display (cogl_context)); - - if (cogl_renderer_get_winsys_id (cogl_renderer) == COGL_WINSYS_ID_EGL_KMS) - { - *out_drm_fd = cogl_kms_renderer_get_kms_fd (cogl_renderer); - return TRUE; - } - else - { - return FALSE; - } -} - void meta_wayland_init (void) { MetaWaylandCompositor *compositor = &_meta_wayland_compositor; MetaMonitorManager *monitors; - int drm_fd; memset (compositor, 0, sizeof (MetaWaylandCompositor)); @@ -668,21 +649,16 @@ meta_wayland_init (void) if (clutter_init (NULL, NULL) != CLUTTER_INIT_SUCCESS) g_error ("Failed to initialize Clutter"); - if (are_we_native (&drm_fd)) +#if defined(CLUTTER_WINDOWING_EGL) + if (clutter_check_windowing_backend (CLUTTER_WINDOWING_EGL)) { - GError *error = NULL; - if (!meta_launcher_set_drm_fd (compositor->launcher, drm_fd, &error)) - { - g_error ("Failed to set DRM fd to weston-launch and become DRM master: %s", error->message); - g_error_free (error); - } - - compositor->native = TRUE; - } - else - { - compositor->native = FALSE; + ClutterBackend *backend = clutter_get_default_backend (); + CoglContext *cogl_context = clutter_backend_get_cogl_context (backend); + CoglRenderer *cogl_renderer = cogl_display_get_renderer (cogl_context_get_display (cogl_context)); + int drm_fd = cogl_kms_renderer_get_kms_fd (cogl_renderer); + meta_launcher_set_drm_fd (compositor->launcher, drm_fd, NULL); } +#endif meta_monitor_manager_initialize (); monitors = meta_monitor_manager_get (); @@ -739,12 +715,6 @@ meta_wayland_finalize (void) meta_launcher_free (compositor->launcher); } -gboolean -meta_wayland_compositor_is_native (MetaWaylandCompositor *compositor) -{ - return compositor->native; -} - gboolean meta_wayland_compositor_activate_vt (MetaWaylandCompositor *compositor, int vt, From 86f057a7122fb261f6767185b7326b2c563b35ac Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 17 Feb 2014 21:49:46 -0500 Subject: [PATCH 510/889] monitor: Add a Wayland backend We shouldn't crash when trying to run nested under Wayland. Just use the dummy backend for now until we are able to run with a system compositor. --- src/core/monitor.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/core/monitor.c b/src/core/monitor.c index 110bb406f..9c22992ac 100644 --- a/src/core/monitor.c +++ b/src/core/monitor.c @@ -374,6 +374,16 @@ get_default_backend (void) } #endif +#if defined(CLUTTER_WINDOWING_WAYLAND) + if (clutter_check_windowing_backend (CLUTTER_WINDOWING_WAYLAND)) + { + /* Use the dummy implementation on Wayland for now. + * In the future, we should support wl_fullscreen_output + * which will have CRTC management in the protocol. */ + return META_TYPE_MONITOR_MANAGER; + } +#endif + g_assert_not_reached (); } From ef24fb6296132eee156e69df8e244dd08e008e8c Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 17 Feb 2014 21:23:27 -0500 Subject: [PATCH 511/889] wayland: Don't use WESTON_LAUNCHER_SOCK We can simply check the windowing backend. --- src/wayland/meta-wayland.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index 6b6c1fef1..3a32dee4b 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -643,8 +643,10 @@ meta_wayland_init (void) clutter_wayland_set_compositor_display (compositor->wayland_display); - if (getenv ("WESTON_LAUNCHER_SOCK")) +#if defined(CLUTTER_WINDOWING_EGL) + if (clutter_check_windowing_backend (CLUTTER_WINDOWING_EGL)) compositor->launcher = meta_launcher_new (); +#endif if (clutter_init (NULL, NULL) != CLUTTER_INIT_SUCCESS) g_error ("Failed to initialize Clutter"); From 57728b4322dd8875ea13db28b95c1f2810160bb4 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 17 Feb 2014 21:28:41 -0500 Subject: [PATCH 512/889] Kill HAVE_WAYLAND --- configure.ac | 3 --- src/Makefile.am | 10 ++++------ src/core/display.c | 6 +----- src/core/keybindings.c | 9 +-------- src/core/meta-cursor-tracker.c | 2 -- src/core/monitor-private.h | 15 --------------- src/core/window-private.h | 2 -- 7 files changed, 6 insertions(+), 41 deletions(-) diff --git a/configure.ac b/configure.ac index d7ab68c88..329025ad9 100644 --- a/configure.ac +++ b/configure.ac @@ -212,9 +212,6 @@ fi MUTTER_PC_MODULES="$MUTTER_PC_MODULES xcursor" -# We always build with wayland enabled -AC_DEFINE(HAVE_WAYLAND, , [Building with Wayland support]) - AC_PATH_PROG([WAYLAND_SCANNER],[wayland-scanner],[no]) AS_IF([test "x$WAYLAND_SCANNER" = "xno"], AC_MSG_ERROR([Could not find wayland-scanner in your PATH, required for parsing wayland extension protocols])) diff --git a/src/Makefile.am b/src/Makefile.am index 89d252107..ae8f7c130 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -188,12 +188,7 @@ libmutter_wayland_la_SOURCES = \ ui/theme.c \ meta/theme.h \ ui/theme-private.h \ - ui/ui.c - -nodist_libmutter_wayland_la_SOURCES = \ - $(mutter_built_sources) - -libmutter_wayland_la_SOURCES += \ + ui/ui.c \ wayland/meta-wayland.c \ wayland/meta-wayland-private.h \ wayland/meta-xwayland-private.h \ @@ -215,6 +210,9 @@ libmutter_wayland_la_SOURCES += \ wayland/meta-weston-launch.c \ wayland/meta-weston-launch.h +nodist_libmutter_wayland_la_SOURCES = \ + $(mutter_built_sources) + libmutter_wayland_la_LDFLAGS = -no-undefined libmutter_wayland_la_LIBADD = $(MUTTER_LIBS) diff --git a/src/core/display.c b/src/core/display.c index 8854e7944..34c66eff4 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -2055,18 +2055,16 @@ meta_display_handle_event (MetaDisplay *display, { MetaWindow *window; gboolean bypass_clutter = FALSE, bypass_wayland = FALSE; + MetaWaylandCompositor *compositor = NULL; /* XXX -- we need to fill this in properly at some point... */ gboolean frame_was_receiver = FALSE; -#ifdef HAVE_WAYLAND - MetaWaylandCompositor *compositor = NULL; if (meta_is_wayland_compositor ()) { compositor = meta_wayland_compositor_get_default (); meta_wayland_compositor_update (compositor, event); } -#endif /* HAVE_WAYLAND */ window = get_window_for_event (display, event); @@ -2314,13 +2312,11 @@ meta_display_handle_event (MetaDisplay *display, if (display->grab_op == META_GRAB_OP_COMPOSITOR) bypass_wayland = TRUE; -#ifdef HAVE_WAYLAND if (compositor && !bypass_wayland) { if (meta_wayland_compositor_handle_event (compositor, event)) bypass_clutter = TRUE; } -#endif /* HAVE_WAYLAND */ return bypass_clutter; } diff --git a/src/core/keybindings.c b/src/core/keybindings.c index f0dca9c25..e46d046d1 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -41,6 +41,7 @@ #include "screen-private.h" #include #include "util-private.h" +#include "meta-wayland-private.h" #include #include @@ -51,10 +52,6 @@ #include #endif -#ifdef HAVE_WAYLAND -#include "meta-wayland-private.h" -#endif - #define SCHEMA_COMMON_KEYBINDINGS "org.gnome.desktop.wm.keybindings" #define SCHEMA_MUTTER_KEYBINDINGS "org.gnome.mutter.keybindings" #define SCHEMA_MUTTER_WAYLAND_KEYBINDINGS "org.gnome.mutter.wayland.keybindings" @@ -4079,7 +4076,6 @@ handle_set_spew_mark (MetaDisplay *display, meta_verbose ("-- MARK MARK MARK MARK --\n"); } -#ifdef HAVE_WAYLAND static void handle_switch_vt (MetaDisplay *display, MetaScreen *screen, @@ -4098,7 +4094,6 @@ handle_switch_vt (MetaDisplay *display, g_error_free (error); } } -#endif /** * meta_keybindings_set_custom_handler: @@ -4403,7 +4398,6 @@ init_builtin_key_bindings (MetaDisplay *display) META_KEYBINDING_ACTION_SET_SPEW_MARK, handle_set_spew_mark, 0); -#ifdef HAVE_WAYLAND if (meta_is_wayland_compositor ()) { add_builtin_keybinding (display, @@ -4455,7 +4449,6 @@ init_builtin_key_bindings (MetaDisplay *display) META_KEYBINDING_ACTION_NONE, handle_switch_vt, 7); } -#endif #undef REVERSES_AND_REVERSED diff --git a/src/core/meta-cursor-tracker.c b/src/core/meta-cursor-tracker.c index 96d2b0528..32e860872 100644 --- a/src/core/meta-cursor-tracker.c +++ b/src/core/meta-cursor-tracker.c @@ -615,11 +615,9 @@ meta_cursor_tracker_get_for_screen (MetaScreen *screen) if (screen->cursor_tracker) return screen->cursor_tracker; -#ifdef HAVE_WAYLAND if (meta_is_wayland_compositor ()) self = make_wayland_cursor_tracker (screen); else -#endif self = make_x11_cursor_tracker (screen); screen->cursor_tracker = self; diff --git a/src/core/monitor-private.h b/src/core/monitor-private.h index 2b0ef422c..842ab97af 100644 --- a/src/core/monitor-private.h +++ b/src/core/monitor-private.h @@ -42,9 +42,7 @@ #include #include "stack-tracker.h" #include "ui.h" -#ifdef HAVE_WAYLAND #include -#endif #include "meta-xrandr-shared.h" #include "meta-dbus-xrandr.h" @@ -54,19 +52,6 @@ typedef struct _MetaMonitorManager MetaMonitorManager; typedef struct _MetaMonitorConfigClass MetaMonitorConfigClass; typedef struct _MetaMonitorConfig MetaMonitorConfig; -#ifndef HAVE_WAYLAND -enum wl_output_transform { - WL_OUTPUT_TRANSFORM_NORMAL, - WL_OUTPUT_TRANSFORM_90, - WL_OUTPUT_TRANSFORM_180, - WL_OUTPUT_TRANSFORM_270, - WL_OUTPUT_TRANSFORM_FLIPPED, - WL_OUTPUT_TRANSFORM_FLIPPED_90, - WL_OUTPUT_TRANSFORM_FLIPPED_180, - WL_OUTPUT_TRANSFORM_FLIPPED_270 -}; -#endif - typedef struct _MetaOutput MetaOutput; typedef struct _MetaCRTC MetaCRTC; typedef struct _MetaMonitorMode MetaMonitorMode; diff --git a/src/core/window-private.h b/src/core/window-private.h index bcac505dc..92c7bf635 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -79,9 +79,7 @@ struct _MetaWindow const MetaMonitorInfo *monitor; MetaWorkspace *workspace; MetaWindowClientType client_type; -#ifdef HAVE_WAYLAND MetaWaylandSurface *surface; -#endif Window xwindow; /* may be NULL! not all windows get decorated */ MetaFrame *frame; From 2a145262c7af22bf379fba69916597f5769d4c1a Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Feb 2014 16:39:23 -0500 Subject: [PATCH 513/889] wayland: Rework how surface destruction works To prevent the MetaSurfaceActor from being destroyed, we normally unparent it before we unmanage the window. However, this doesn't work for XWayland windows, which we unmanage when we get UnmapNotify or DestroyNotify, not when we get the wl_surface_destroy. To solve this, add an early hook in meta_window_unmanage that unparents the surface actor if we have one. At the same time, clean up the destruction code to remove old comments and assumptions about how wl_shell behaves. --- src/core/window.c | 3 + src/wayland/meta-wayland-surface.c | 91 +++++++++++++----------------- src/wayland/meta-wayland-surface.h | 3 + 3 files changed, 45 insertions(+), 52 deletions(-) diff --git a/src/core/window.c b/src/core/window.c index ccd1749e8..79b7cb3e9 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -1498,6 +1498,9 @@ meta_window_unmanage (MetaWindow *window, meta_verbose ("Unmanaging 0x%lx\n", window->xwindow); + if (window->surface) + meta_wayland_surface_window_unmanaged (window->surface); + if (window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND) { MetaStackWindow stack_window; diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 496a6bf18..b8fc0e793 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -574,10 +574,48 @@ const struct wl_surface_interface meta_wayland_surface_interface = { }; static void -meta_wayland_surface_free (MetaWaylandSurface *surface) +unparent_actor (MetaWaylandSurface *surface) { + ClutterActor *parent_actor; + + parent_actor = clutter_actor_get_parent (CLUTTER_ACTOR (surface->surface_actor)); + clutter_actor_remove_child (parent_actor, CLUTTER_ACTOR (surface->surface_actor)); +} + +void +meta_wayland_surface_window_unmanaged (MetaWaylandSurface *surface) +{ + /* The window is being unmanaged. Unparent our surface actor + * before the window actor is destroyed, as we need to hold + * onto it... */ + unparent_actor (surface); + + surface->window = NULL; +} + +static void +destroy_window (MetaWaylandSurface *surface) +{ + MetaDisplay *display = meta_get_display (); + guint32 timestamp = meta_display_get_current_time_roundtrip (display); + + g_assert (surface->window != NULL); + meta_window_unmanage (surface->window, timestamp); + g_assert (surface->window == NULL); +} + +static void +wl_surface_destructor (struct wl_resource *resource) +{ + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); MetaWaylandCompositor *compositor = surface->compositor; + /* At the time when the wl_surface is destroyed, we should + * no longer have a window, unless we're an XWayland window + * in which case we received the wl_surface.destroy before + * the UnmapNotify/DestroyNotify. */ + g_assert (surface->window == NULL || surface->window->client_type == META_WINDOW_CLIENT_TYPE_X11); + compositor->surfaces = g_list_remove (compositor->surfaces, surface); surface_set_buffer (surface, NULL); @@ -590,57 +628,6 @@ meta_wayland_surface_free (MetaWaylandSurface *surface) meta_wayland_compositor_repick (compositor); } -static void -unparent_actor (MetaWaylandSurface *surface) -{ - ClutterActor *parent_actor; - - parent_actor = clutter_actor_get_parent (CLUTTER_ACTOR (surface->surface_actor)); - clutter_actor_remove_child (parent_actor, CLUTTER_ACTOR (surface->surface_actor)); -} - -static void -destroy_window (MetaWaylandSurface *surface) -{ - MetaDisplay *display = meta_get_display (); - guint32 timestamp = meta_display_get_current_time_roundtrip (display); - - /* Remove our actor from the parent, so it doesn't get destroyed when - * the MetaWindowActor is destroyed. */ - unparent_actor (surface); - - g_assert (surface->window != NULL); - meta_window_unmanage (surface->window, timestamp); - surface->window = NULL; -} - -static void -wl_surface_destructor (struct wl_resource *resource) -{ - MetaWaylandSurface *surface = wl_resource_get_user_data (resource); - - /* There are four cases here: - - An X11 unmanaged window -> surface is NULL, nothing to do - - An X11 unmanaged window, but we got the wayland event first -> - just clear the resource pointer - - A wayland surface without window (destroyed before set_toplevel) -> - need to free the surface itself - - A wayland window -> need to unmanage - */ - - if (surface) - { - surface->resource = NULL; - - /* NB: If the surface corresponds to an X window then we will be - * sure to free the MetaWindow according to some X event. */ - if (surface->window && surface->window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND) - destroy_window (surface); - - meta_wayland_surface_free (surface); - } -} - MetaWaylandSurface * meta_wayland_surface_create (MetaWaylandCompositor *compositor, struct wl_client *client, diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h index df725db13..0fafb8c57 100644 --- a/src/wayland/meta-wayland-surface.h +++ b/src/wayland/meta-wayland-surface.h @@ -118,6 +118,9 @@ MetaWaylandSurface *meta_wayland_surface_create (MetaWaylandCompositor *composit struct wl_client *client, guint32 id, guint32 version); + +void meta_wayland_surface_window_unmanaged (MetaWaylandSurface *surface); + void meta_wayland_surface_configure_notify (MetaWaylandSurface *surface, int width, int height); From 283a81eac0a2012ed7b1b9e758a5c5ab166d3863 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Feb 2014 17:07:36 -0500 Subject: [PATCH 514/889] wayland: Explicitly destroy the surface actor This shouldn't change anything right now, but it's better to be careful than anything else. This is where the actor should be destroyed. --- src/wayland/meta-wayland-surface.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index b8fc0e793..050ec38c2 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -620,7 +620,10 @@ wl_surface_destructor (struct wl_resource *resource) surface_set_buffer (surface, NULL); double_buffered_state_destroy (&surface->pending); + + clutter_actor_destroy (surface->surface_actor); g_object_unref (surface->surface_actor); + if (surface->resource) wl_resource_set_user_data (surface->resource, NULL); g_slice_free (MetaWaylandSurface, surface); From 414259a7f8c6e4de9f2a5835c9cc277db241bd68 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Feb 2014 17:26:03 -0500 Subject: [PATCH 515/889] wayland: Fix cast warning It's sometimes hard to see around all the deprecation warnings. Sorry about that... --- src/wayland/meta-wayland-surface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 050ec38c2..12bb3d000 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -621,7 +621,7 @@ wl_surface_destructor (struct wl_resource *resource) surface_set_buffer (surface, NULL); double_buffered_state_destroy (&surface->pending); - clutter_actor_destroy (surface->surface_actor); + clutter_actor_destroy (CLUTTER_ACTOR (surface->surface_actor)); g_object_unref (surface->surface_actor); if (surface->resource) From a364c2a96bf77d42608b9a2ab1352efc46251785 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Feb 2014 18:00:26 -0500 Subject: [PATCH 516/889] pointer/keyboard: Make sure not to get stale on client resources as well Both the pointer/keyboard resource and surface resource can be destroyed at any point in the destruction process, so we need to have destroy listeners on both. To make the code easier to follow, rename ->focus to ->focus_surface at the same time, and rearrange the code so that the two of them are always grouped together. --- src/wayland/meta-wayland-keyboard.c | 65 +++++++++++++++++++---------- src/wayland/meta-wayland-keyboard.h | 6 ++- src/wayland/meta-wayland-pointer.c | 49 +++++++++++++++------- src/wayland/meta-wayland-pointer.h | 6 ++- src/wayland/meta-wayland-seat.c | 18 ++++---- src/wayland/meta-wayland-surface.c | 4 +- 6 files changed, 96 insertions(+), 52 deletions(-) diff --git a/src/wayland/meta-wayland-keyboard.c b/src/wayland/meta-wayland-keyboard.c index 566a59693..2159cce74 100644 --- a/src/wayland/meta-wayland-keyboard.c +++ b/src/wayland/meta-wayland-keyboard.c @@ -225,13 +225,25 @@ err_keymap_str: return; } +static void +release_focus (MetaWaylandKeyboard *keyboard) +{ + keyboard->focus_resource = NULL; + keyboard->focus_surface = NULL; +} + static void keyboard_handle_focus_surface_destroy (struct wl_listener *listener, void *data) { MetaWaylandKeyboard *keyboard = wl_container_of (listener, keyboard, focus_surface_listener); + release_focus (keyboard); +} - keyboard->focus_resource = NULL; - keyboard->focus = NULL; +static void +keyboard_handle_focus_resource_destroy (struct wl_listener *listener, void *data) +{ + MetaWaylandKeyboard *keyboard = wl_container_of (listener, keyboard, focus_resource_listener); + release_focus (keyboard); } static gboolean @@ -287,10 +299,9 @@ default_grab_modifiers (MetaWaylandKeyboardGrab *grab, uint32_t serial, wl_keyboard_send_modifiers (resource, serial, mods_depressed, mods_latched, mods_locked, group); - if (pointer && pointer->focus && pointer->focus != keyboard->focus) + if (pointer && pointer->focus_surface && pointer->focus_surface != keyboard->focus_surface) { - pr = find_resource_for_surface (&keyboard->resource_list, - pointer->focus); + pr = find_resource_for_surface (&keyboard->resource_list, pointer->focus_surface); if (pr) { wl_keyboard_send_modifiers (pr, serial, @@ -342,7 +353,10 @@ meta_wayland_keyboard_init (MetaWaylandKeyboard *keyboard, wl_list_init (&keyboard->resource_list); wl_array_init (&keyboard->keys); + keyboard->focus_surface_listener.notify = keyboard_handle_focus_surface_destroy; + keyboard->focus_resource_listener.notify = keyboard_handle_focus_resource_destroy; + keyboard->default_grab.interface = &default_keyboard_grab_interface; keyboard->default_grab.keyboard = keyboard; keyboard->grab = &keyboard->default_grab; @@ -513,19 +527,27 @@ meta_wayland_keyboard_set_focus (MetaWaylandKeyboard *keyboard, struct wl_resource *resource; uint32_t serial; - if (keyboard->focus == surface && keyboard->focus_resource != NULL) + if (keyboard->focus_surface == surface && keyboard->focus_resource != NULL) return; resource = keyboard->focus_resource; - if (keyboard->focus_resource && keyboard->focus->resource) + if (resource) { - struct wl_client *client = wl_resource_get_client (resource); - struct wl_display *display = wl_client_get_display (client); - serial = wl_display_next_serial (display); - wl_keyboard_send_leave (resource, serial, keyboard->focus->resource); + if (keyboard->focus_surface->resource) + { + struct wl_client *client = wl_resource_get_client (resource); + struct wl_display *display = wl_client_get_display (client); + serial = wl_display_next_serial (display); + wl_keyboard_send_leave (resource, serial, keyboard->focus_surface->resource); + + meta_wayland_surface_focused_unset (keyboard->focus_surface); + } + + wl_list_remove (&keyboard->focus_resource_listener.link); wl_list_remove (&keyboard->focus_surface_listener.link); - meta_wayland_surface_focused_unset (keyboard->focus); + keyboard->focus_resource = NULL; + keyboard->focus_surface = NULL; } resource = find_resource_for_surface (&keyboard->resource_list, surface); @@ -558,14 +580,17 @@ meta_wayland_keyboard_set_focus (MetaWaylandKeyboard *keyboard, wl_keyboard_send_enter (resource, serial, surface->resource, &keyboard->keys); } - wl_resource_add_destroy_listener (surface->resource, &keyboard->focus_surface_listener); - keyboard->focus_serial = serial; meta_wayland_surface_focused_set (surface); - } - keyboard->focus_resource = resource; - keyboard->focus = surface; + keyboard->focus_resource = resource; + keyboard->focus_surface = surface; + + wl_resource_add_destroy_listener (keyboard->focus_resource, &keyboard->focus_resource_listener); + wl_resource_add_destroy_listener (keyboard->focus_surface->resource, &keyboard->focus_surface_listener); + + keyboard->focus_serial = serial; + } } void @@ -591,8 +616,6 @@ meta_wayland_keyboard_release (MetaWaylandKeyboard *keyboard) xkb_context_unref (keyboard->xkb_context); /* XXX: What about keyboard->resource_list? */ - if (keyboard->focus_resource) - wl_list_remove (&keyboard->focus_surface_listener.link); wl_array_release (&keyboard->keys); } @@ -611,7 +634,7 @@ meta_wayland_keyboard_begin_modal (MetaWaylandKeyboard *keyboard, if (keyboard->grab != &keyboard->default_grab) return FALSE; - if (keyboard->focus) + if (keyboard->focus_surface) { /* Fake key release events for the focused app */ serial = wl_display_next_serial (keyboard->display); @@ -653,7 +676,7 @@ meta_wayland_keyboard_end_modal (MetaWaylandKeyboard *keyboard, meta_wayland_keyboard_end_grab (keyboard); g_slice_free (MetaWaylandKeyboardGrab, grab); - if (keyboard->focus) + if (keyboard->focus_surface) { /* Fake key press events for the focused app */ serial = wl_display_next_serial (keyboard->display); diff --git a/src/wayland/meta-wayland-keyboard.h b/src/wayland/meta-wayland-keyboard.h index fd87c8643..b51d3c02a 100644 --- a/src/wayland/meta-wayland-keyboard.h +++ b/src/wayland/meta-wayland-keyboard.h @@ -92,9 +92,11 @@ typedef struct struct _MetaWaylandKeyboard { struct wl_list resource_list; - MetaWaylandSurface *focus; - struct wl_resource *focus_resource; + + MetaWaylandSurface *focus_surface; struct wl_listener focus_surface_listener; + struct wl_resource *focus_resource; + struct wl_listener focus_resource_listener; uint32_t focus_serial; MetaWaylandKeyboardGrab *grab; diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index 59ed0934e..035ceabd9 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -63,13 +63,25 @@ meta_wayland_pointer_get_seat (MetaWaylandPointer *pointer) return seat; } +static void +release_focus (MetaWaylandPointer *pointer) +{ + pointer->focus_resource = NULL; + pointer->focus_surface = NULL; +} + static void pointer_handle_focus_surface_destroy (struct wl_listener *listener, void *data) { MetaWaylandPointer *pointer = wl_container_of (listener, pointer, focus_surface_listener); + release_focus (pointer); +} - pointer->focus_resource = NULL; - pointer->focus = NULL; +static void +pointer_handle_focus_resource_destroy (struct wl_listener *listener, void *data) +{ + MetaWaylandPointer *pointer = wl_container_of (listener, pointer, focus_resource_listener); + release_focus (pointer); } static void @@ -97,7 +109,7 @@ default_grab_motion (MetaWaylandPointerGrab *grab, wl_fixed_t sx, sy; meta_wayland_pointer_get_relative_coordinates (grab->pointer, - grab->pointer->focus, + grab->pointer->focus_surface, &sx, &sy); wl_pointer_send_motion (resource, clutter_event_get_time (event), sx, sy); } @@ -265,7 +277,10 @@ meta_wayland_pointer_init (MetaWaylandPointer *pointer) memset (pointer, 0, sizeof *pointer); wl_list_init (&pointer->resource_list); + pointer->focus_surface_listener.notify = pointer_handle_focus_surface_destroy; + pointer->focus_resource_listener.notify = pointer_handle_focus_resource_destroy; + pointer->default_grab.interface = &default_pointer_grab_interface; pointer->default_grab.pointer = pointer; pointer->grab = &pointer->default_grab; @@ -292,12 +307,7 @@ meta_wayland_pointer_init (MetaWaylandPointer *pointer) void meta_wayland_pointer_release (MetaWaylandPointer *pointer) { - /* XXX: What about pointer->resource_list? */ - if (pointer->focus_resource) - wl_list_remove (&pointer->focus_surface_listener.link); - - pointer->focus = NULL; - pointer->focus_resource = NULL; + release_focus (pointer); } static struct wl_resource * @@ -323,21 +333,25 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer, struct wl_resource *resource, *kr; uint32_t serial; - if (pointer->focus == surface && pointer->focus_resource != NULL) + if (pointer->focus_surface == surface && pointer->focus_resource != NULL) return; resource = pointer->focus_resource; if (resource) { - if (pointer->focus->resource) + if (pointer->focus_surface->resource) { struct wl_client *client = wl_resource_get_client (resource); struct wl_display *display = wl_client_get_display (client); serial = wl_display_next_serial (display); - wl_pointer_send_leave (resource, serial, pointer->focus->resource); + wl_pointer_send_leave (resource, serial, pointer->focus_surface->resource); } wl_list_remove (&pointer->focus_surface_listener.link); + wl_list_remove (&pointer->focus_resource_listener.link); + + pointer->focus_surface = NULL; + pointer->focus_resource = NULL; } resource = find_resource_for_surface (&pointer->resource_list, surface); @@ -370,12 +384,15 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer, wl_fixed_to_int (pointer->x), wl_fixed_to_int (pointer->y)); wl_pointer_send_enter (resource, serial, surface->resource, sx, sy); - wl_resource_add_destroy_listener (surface->resource, &pointer->focus_surface_listener); + + pointer->focus_resource = resource; + pointer->focus_surface = surface; + + wl_resource_add_destroy_listener (pointer->focus_resource, &pointer->focus_resource_listener); + wl_resource_add_destroy_listener (pointer->focus_surface->resource, &pointer->focus_surface_listener); + pointer->focus_serial = serial; } - - pointer->focus_resource = resource; - pointer->focus = surface; } void diff --git a/src/wayland/meta-wayland-pointer.h b/src/wayland/meta-wayland-pointer.h index e5ee4c1c5..7fa9bf583 100644 --- a/src/wayland/meta-wayland-pointer.h +++ b/src/wayland/meta-wayland-pointer.h @@ -46,9 +46,11 @@ struct _MetaWaylandPointerGrab struct _MetaWaylandPointer { struct wl_list resource_list; - MetaWaylandSurface *focus; - struct wl_resource *focus_resource; + + MetaWaylandSurface *focus_surface; struct wl_listener focus_surface_listener; + struct wl_resource *focus_resource; + struct wl_listener focus_resource_listener; guint32 focus_serial; guint32 click_serial; diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c index 9e838f90f..ff6f57de6 100644 --- a/src/wayland/meta-wayland-seat.c +++ b/src/wayland/meta-wayland-seat.c @@ -95,9 +95,9 @@ pointer_set_cursor (struct wl_client *client, surface = (surface_resource ? wl_resource_get_user_data (surface_resource) : NULL); - if (seat->pointer.focus == NULL) + if (seat->pointer.focus_surface == NULL) return; - if (wl_resource_get_client (seat->pointer.focus->resource) != client) + if (wl_resource_get_client (seat->pointer.focus_surface->resource) != client) return; if (seat->pointer.focus_serial - serial > G_MAXUINT32 / 2) return; @@ -125,9 +125,9 @@ seat_get_pointer (struct wl_client *client, wl_resource_set_implementation (cr, &pointer_interface, seat, unbind_resource); wl_list_insert (&seat->pointer.resource_list, wl_resource_get_link (cr)); - if (seat->pointer.focus && - wl_resource_get_client (seat->pointer.focus->resource) == client) - meta_wayland_pointer_set_focus (&seat->pointer, seat->pointer.focus); + if (seat->pointer.focus_surface && + wl_resource_get_client (seat->pointer.focus_surface->resource) == client) + meta_wayland_pointer_set_focus (&seat->pointer, seat->pointer.focus_surface); } static void @@ -148,10 +148,10 @@ seat_get_keyboard (struct wl_client *client, seat->keyboard.xkb_info.keymap_fd, seat->keyboard.xkb_info.keymap_size); - if (seat->keyboard.focus && - wl_resource_get_client (seat->keyboard.focus->resource) == client) + if (seat->keyboard.focus_surface && + wl_resource_get_client (seat->keyboard.focus_surface->resource) == client) { - meta_wayland_keyboard_set_focus (&seat->keyboard, seat->keyboard.focus); + meta_wayland_keyboard_set_focus (&seat->keyboard, seat->keyboard.focus_surface); meta_wayland_data_device_set_keyboard_focus (seat); } } @@ -429,7 +429,7 @@ meta_wayland_seat_repick (MetaWaylandSeat *seat, } pointer->current = surface; - if (surface != pointer->focus) + if (surface != pointer->focus_surface) { const MetaWaylandPointerGrabInterface *interface = pointer->grab->interface; diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 12bb3d000..192e6e3b6 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -826,7 +826,7 @@ xdg_surface_move (struct wl_client *client, if (seat->pointer.button_count == 0 || seat->pointer.grab_serial != serial || - seat->pointer.focus != surface) + seat->pointer.focus_surface != surface) return; begin_grab_op_on_surface (surface, seat, META_GRAB_OP_MOVING); @@ -872,7 +872,7 @@ xdg_surface_resize (struct wl_client *client, if (seat->pointer.button_count == 0 || seat->pointer.grab_serial != serial || - seat->pointer.focus != surface) + seat->pointer.focus_surface != surface) return; begin_grab_op_on_surface (surface, seat, grab_op_for_edge (edges)); From be16c2fe7198422660e8ea0c829b3738083b12ba Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Feb 2014 18:06:17 -0500 Subject: [PATCH 517/889] pointer: Reindent --- src/wayland/meta-wayland-pointer.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index 035ceabd9..f5f6cdf5f 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -590,12 +590,12 @@ meta_wayland_pointer_start_popup_grab (MetaWaylandPointer *pointer, if (pointer->grab != &pointer->default_grab) { if (pointer->grab->interface == &popup_grab_interface) - { - grab = (MetaWaylandPopupGrab*)pointer->grab; + { + grab = (MetaWaylandPopupGrab*)pointer->grab; - if (wl_resource_get_client (surface->resource) != grab->grab_client) - return FALSE; - } + if (wl_resource_get_client (surface->resource) != grab->grab_client) + return FALSE; + } return FALSE; } From 756a412436742a24588804be4ca3b6b54ad2900f Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Feb 2014 18:06:55 -0500 Subject: [PATCH 518/889] pointer: Make nested grabs work Something noticed on code inspection. If we have a popup grab, it will always return FALSE. The code here clearly meant to continue if we had an existing popup grab from an existing client. --- src/wayland/meta-wayland-pointer.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index f5f6cdf5f..d01507f54 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -589,15 +589,13 @@ meta_wayland_pointer_start_popup_grab (MetaWaylandPointer *pointer, if (pointer->grab != &pointer->default_grab) { - if (pointer->grab->interface == &popup_grab_interface) - { - grab = (MetaWaylandPopupGrab*)pointer->grab; + if (pointer->grab->interface != &popup_grab_interface) + return FALSE; - if (wl_resource_get_client (surface->resource) != grab->grab_client) - return FALSE; - } + grab = (MetaWaylandPopupGrab*)pointer->grab; - return FALSE; + if (wl_resource_get_client (surface->resource) != grab->grab_client) + return FALSE; } if (pointer->grab == &pointer->default_grab) From 4c621cc30fe62d4ca161c6ee540bade6cf1332fc Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Feb 2014 18:39:05 -0500 Subject: [PATCH 519/889] pointer/keyboard: Make sure to clean up the destroy listeners when releasing --- src/wayland/meta-wayland-keyboard.c | 3 +++ src/wayland/meta-wayland-pointer.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/wayland/meta-wayland-keyboard.c b/src/wayland/meta-wayland-keyboard.c index 2159cce74..1a02f45c3 100644 --- a/src/wayland/meta-wayland-keyboard.c +++ b/src/wayland/meta-wayland-keyboard.c @@ -228,6 +228,9 @@ err_keymap_str: static void release_focus (MetaWaylandKeyboard *keyboard) { + wl_list_remove (&keyboard->focus_surface_listener.link); + wl_list_remove (&keyboard->focus_resource_listener.link); + keyboard->focus_resource = NULL; keyboard->focus_surface = NULL; } diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index d01507f54..30a1e9ef1 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -66,6 +66,9 @@ meta_wayland_pointer_get_seat (MetaWaylandPointer *pointer) static void release_focus (MetaWaylandPointer *pointer) { + wl_list_remove (&pointer->focus_surface_listener.link); + wl_list_remove (&pointer->focus_resource_listener.link); + pointer->focus_resource = NULL; pointer->focus_surface = NULL; } From 47f4c9db7baa091f720bb26e517c5750b73b50e6 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Feb 2014 18:55:54 -0500 Subject: [PATCH 520/889] wayland-surface: Correct xdg_popup placement Now that we call set_custom_frame_extents, the frame rect corresponds to the "visible window geometry" used for constrainment, while the x/y fields in get_xdg_popup instead are relative to the surface. --- src/wayland/meta-wayland-surface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 192e6e3b6..2638aa0fe 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -1020,7 +1020,7 @@ xdg_shell_get_xdg_popup (struct wl_client *client, if (parent_surf == NULL || parent_surf->window == NULL) return; - meta_window_get_frame_rect (parent_surf->window, &parent_rect); + meta_window_get_rect (parent_surf->window, &parent_rect); if (!create_surface_extension (&surface->xdg_popup, client, surface_resource, resource, id, META_XDG_POPUP_VERSION, From cc13f8f65e30d78751d8b3c215873327fcb96763 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Feb 2014 19:01:50 -0500 Subject: [PATCH 521/889] wayland: Fix compile error I tested this with meta_window_get_input_rect and decided to change it at the last minute. Turns out meta_window_get_rect is unlike all the others. Just access window->rect directly instead. --- src/wayland/meta-wayland-surface.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 2638aa0fe..62b7d924f 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -1015,13 +1015,10 @@ xdg_shell_get_xdg_popup (struct wl_client *client, MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); MetaWaylandSurface *parent_surf = wl_resource_get_user_data (parent_resource); MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); - MetaRectangle parent_rect; if (parent_surf == NULL || parent_surf->window == NULL) return; - meta_window_get_rect (parent_surf->window, &parent_rect); - if (!create_surface_extension (&surface->xdg_popup, client, surface_resource, resource, id, META_XDG_POPUP_VERSION, &xdg_popup_interface, @@ -1035,8 +1032,8 @@ xdg_shell_get_xdg_popup (struct wl_client *client, } surface->window = meta_window_wayland_new (meta_get_display (), surface); - surface->window->rect.x = parent_rect.x + x; - surface->window->rect.y = parent_rect.y + y; + surface->window->rect.x = parent_surf->window->rect.x + x; + surface->window->rect.y = parent_surf->window->rect.y + y; surface->window->showing_for_first_time = FALSE; surface->window->placed = TRUE; meta_window_set_transient_for (surface->window, parent_surf->window); From 00c8d3c8978954ece34301fc7e3eda5aa4a7c017 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sun, 9 Feb 2014 11:41:40 -0500 Subject: [PATCH 522/889] xdg-shell: Update to latest renames for focused_set / focused_unset --- protocol/xdg-shell.xml | 31 +++++++++++++++-------------- src/wayland/meta-wayland-keyboard.c | 4 ++-- src/wayland/meta-wayland-surface.c | 8 ++++---- src/wayland/meta-wayland-surface.h | 4 ++-- 4 files changed, 24 insertions(+), 23 deletions(-) diff --git a/protocol/xdg-shell.xml b/protocol/xdg-shell.xml index ef755b720..4a1d08aba 100644 --- a/protocol/xdg-shell.xml +++ b/protocol/xdg-shell.xml @@ -249,12 +249,6 @@ ignore it if it doesn't resize, pick a smaller size (to satisfy aspect ratio or resize in steps of NxM pixels). - The edges parameter provides a hint about how the surface - was resized. The client may use this information to decide - how to adjust its content to the new size (e.g. a scrolling - area might adjust its content position to leave the viewable - content unmoved). Valid edge values are from resize_edge enum. - The client is free to dismiss all but the last configure event it received. @@ -391,18 +385,25 @@ - - - The focused_set event is sent when this surface has been - activated. Window decorations should be updated accordingly. + + + The activated_set event is sent when this surface has been + activated, which means that the surface has user attention. + Window decorations should be updated accordingly. You should + not use this event for anything but the style of decorations + you display, use wl_keyboard.enter and wl_keyboard.leave for + determining keyboard focus. - - - The focused_unset event is sent when this surface has been - deactivated, because another surface has been activated. Window - decorations should be updated accordingly. + + + The deactivate event is sent when this surface has been + deactivated, which means that the surface lost user attention. + Window decorations should be updated accordingly. You should + not use this event for anything but the style of decorations + you display, use wl_keyboard.enter and wl_keyboard.leave for + determining keyboard focus. diff --git a/src/wayland/meta-wayland-keyboard.c b/src/wayland/meta-wayland-keyboard.c index 1a02f45c3..963ad2909 100644 --- a/src/wayland/meta-wayland-keyboard.c +++ b/src/wayland/meta-wayland-keyboard.c @@ -543,7 +543,7 @@ meta_wayland_keyboard_set_focus (MetaWaylandKeyboard *keyboard, serial = wl_display_next_serial (display); wl_keyboard_send_leave (resource, serial, keyboard->focus_surface->resource); - meta_wayland_surface_focused_unset (keyboard->focus_surface); + meta_wayland_surface_deactivated (keyboard->focus_surface); } wl_list_remove (&keyboard->focus_resource_listener.link); @@ -584,7 +584,7 @@ meta_wayland_keyboard_set_focus (MetaWaylandKeyboard *keyboard, &keyboard->keys); } - meta_wayland_surface_focused_set (surface); + meta_wayland_surface_activated (surface); keyboard->focus_resource = resource; keyboard->focus_surface = surface; diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 62b7d924f..2ae212d9c 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -1508,17 +1508,17 @@ meta_wayland_surface_configure_notify (MetaWaylandSurface *surface, } void -meta_wayland_surface_focused_set (MetaWaylandSurface *surface) +meta_wayland_surface_activated (MetaWaylandSurface *surface) { if (surface->xdg_surface.resource) - xdg_surface_send_focused_set (surface->xdg_surface.resource); + xdg_surface_send_activated (surface->xdg_surface.resource); } void -meta_wayland_surface_focused_unset (MetaWaylandSurface *surface) +meta_wayland_surface_deactivated (MetaWaylandSurface *surface) { if (surface->xdg_surface.resource) - xdg_surface_send_focused_unset (surface->xdg_surface.resource); + xdg_surface_send_deactivated (surface->xdg_surface.resource); } void diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h index 0fafb8c57..8b10b31fb 100644 --- a/src/wayland/meta-wayland-surface.h +++ b/src/wayland/meta-wayland-surface.h @@ -125,8 +125,8 @@ void meta_wayland_surface_configure_notify (MetaWaylandSurface *s int width, int height); -void meta_wayland_surface_focused_set (MetaWaylandSurface *surface); -void meta_wayland_surface_focused_unset (MetaWaylandSurface *surface); +void meta_wayland_surface_activated (MetaWaylandSurface *surface); +void meta_wayland_surface_deactivated (MetaWaylandSurface *surface); void meta_wayland_surface_ping (MetaWaylandSurface *surface, guint32 serial); From 24c5290d7f03992b113581c114dae859ba916c1b Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Feb 2014 20:30:36 -0500 Subject: [PATCH 523/889] main: Kill a runtime warning g_setenv doesn't take NULL for a value. --- src/core/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/main.c b/src/core/main.c index c4bdeee4b..84da691d1 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -343,7 +343,8 @@ meta_select_display (char *display_arg) else display_name = g_getenv ("MUTTER_DISPLAY"); - g_setenv ("DISPLAY", display_name, TRUE); + if (display_name) + g_setenv ("DISPLAY", display_name, TRUE); } static void From e62fe956fdd450fed6d39fef443958cc57133cd5 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Feb 2014 20:28:23 -0500 Subject: [PATCH 524/889] window: Enable pinging on Wayland windows I implemented pinging, but never actually enabled the feature properly on Wayland surfaces by setting the net_wm_ping hint to TRUE, causing the fallback path to always be hit. Rename net_wm_ping to can_ping so it doesn't take on an implementation-specific meaning, and set it for all Wayland windows. --- src/core/display.c | 2 +- src/core/window-private.h | 2 +- src/core/window-props.c | 4 ++-- src/core/window.c | 3 ++- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/core/display.c b/src/core/display.c index 34c66eff4..749938fd8 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -4980,7 +4980,7 @@ meta_display_ping_window (MetaWindow *window, return; } - if (!window->net_wm_ping) + if (!window->can_ping) { if (ping_reply_func) (* ping_reply_func) (window, timestamp, user_data); diff --git a/src/core/window-private.h b/src/core/window-private.h index 92c7bf635..f931eac29 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -238,7 +238,7 @@ struct _MetaWindow /* These are the flags from WM_PROTOCOLS */ guint take_focus : 1; guint delete_window : 1; - guint net_wm_ping : 1; + guint can_ping : 1; /* Globally active / No input */ guint input : 1; diff --git a/src/core/window-props.c b/src/core/window-props.c index eabdcfae4..cb6e38185 100644 --- a/src/core/window-props.c +++ b/src/core/window-props.c @@ -1407,7 +1407,7 @@ reload_wm_protocols (MetaWindow *window, window->take_focus = FALSE; window->delete_window = FALSE; - window->net_wm_ping = FALSE; + window->can_ping = FALSE; if (value->type == META_PROP_VALUE_INVALID) return; @@ -1423,7 +1423,7 @@ reload_wm_protocols (MetaWindow *window, window->delete_window = TRUE; else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_PING) - window->net_wm_ping = TRUE; + window->can_ping = TRUE; ++i; } diff --git a/src/core/window.c b/src/core/window.c index 79b7cb3e9..5c57d3c7b 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -874,7 +874,7 @@ _meta_window_shared_new (MetaDisplay *display, window->user_time_window = None; window->take_focus = FALSE; window->delete_window = FALSE; - window->net_wm_ping = FALSE; + window->can_ping = FALSE; window->input = TRUE; window->calc_placement = FALSE; window->shaken_loose = FALSE; @@ -1320,6 +1320,7 @@ meta_window_wayland_new (MetaDisplay *display, WithdrawnState, META_COMP_EFFECT_CREATE, &attrs); + window->can_ping = TRUE; meta_error_trap_pop (display); /* pop the XSync()-reducing trap */ From 1e6b3faa83323943cb45f4ef1b910f87b2c30d88 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Feb 2014 21:27:20 -0500 Subject: [PATCH 525/889] Fix the input region not working properly The input region was set on the shaped texture, but the shaped texture was never picked properly, as it was never set to be reactive. Move the pick implementation and reactivity to the MetaSurfaceActor, and update the code everywhere else to expect a MetaSurfaceActor. --- src/compositor/meta-shaped-texture.c | 105 --------------------------- src/compositor/meta-surface-actor.c | 99 ++++++++++++++++++++++++- src/compositor/meta-surface-actor.h | 4 +- src/compositor/meta-window-actor.c | 5 +- src/core/display.c | 8 +- src/meta/meta-shaped-texture.h | 3 - src/wayland/meta-wayland-seat.c | 9 +-- src/wayland/meta-wayland-surface.c | 3 +- 8 files changed, 109 insertions(+), 127 deletions(-) diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c index ae46b34d2..30697ee6a 100644 --- a/src/compositor/meta-shaped-texture.c +++ b/src/compositor/meta-shaped-texture.c @@ -42,8 +42,6 @@ static void meta_shaped_texture_dispose (GObject *object); static void meta_shaped_texture_paint (ClutterActor *actor); -static void meta_shaped_texture_pick (ClutterActor *actor, - const ClutterColor *color); static void meta_shaped_texture_get_preferred_width (ClutterActor *self, gfloat for_height, @@ -73,8 +71,6 @@ struct _MetaShapedTexturePrivate CoglTexture *texture; CoglTexture *mask_texture; - cairo_region_t *input_shape_region; - /* The region containing only fully opaque pixels */ cairo_region_t *opaque_region; @@ -98,7 +94,6 @@ meta_shaped_texture_class_init (MetaShapedTextureClass *klass) actor_class->get_preferred_width = meta_shaped_texture_get_preferred_width; actor_class->get_preferred_height = meta_shaped_texture_get_preferred_height; actor_class->paint = meta_shaped_texture_paint; - actor_class->pick = meta_shaped_texture_pick; actor_class->get_paint_volume = meta_shaped_texture_get_paint_volume; g_type_class_add_private (klass, sizeof (MetaShapedTexturePrivate)); @@ -463,71 +458,6 @@ meta_shaped_texture_paint (ClutterActor *actor) cairo_region_destroy (blended_region); } -static void -meta_shaped_texture_pick (ClutterActor *actor, - const ClutterColor *color) -{ - MetaShapedTexture *stex = (MetaShapedTexture *) actor; - MetaShapedTexturePrivate *priv = stex->priv; - - if (!clutter_actor_should_pick_paint (actor) || - (priv->clip_region && cairo_region_is_empty (priv->clip_region))) - return; - - /* If there is no region then use the regular pick */ - if (priv->input_shape_region == NULL) - CLUTTER_ACTOR_CLASS (meta_shaped_texture_parent_class)->pick (actor, color); - else - { - int n_rects; - float *rectangles; - int i; - CoglPipeline *pipeline; - CoglContext *ctx; - CoglFramebuffer *fb; - CoglColor cogl_color; - - /* Note: We don't bother trying to intersect the pick and clip regions - * since needing to copy the region, do the intersection, and probably - * increase the number of rectangles seems more likely to have a negative - * effect. - * - * NB: Most of the time when just using rectangles for picking then - * picking shouldn't involve any rendering, and minimizing the number of - * rectangles has more benefit than reducing the area of the pick - * region. - */ - - n_rects = cairo_region_num_rectangles (priv->input_shape_region); - rectangles = g_alloca (sizeof (float) * 4 * n_rects); - - for (i = 0; i < n_rects; i++) - { - cairo_rectangle_int_t rect; - int pos = i * 4; - - cairo_region_get_rectangle (priv->input_shape_region, i, &rect); - - rectangles[pos] = rect.x; - rectangles[pos + 1] = rect.y; - rectangles[pos + 2] = rect.x + rect.width; - rectangles[pos + 3] = rect.y + rect.height; - } - - ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ()); - fb = cogl_get_draw_framebuffer (); - - cogl_color_init_from_4ub (&cogl_color, color->red, color->green, color->blue, color->alpha); - - pipeline = cogl_pipeline_new (ctx); - cogl_pipeline_set_color (pipeline, &cogl_color); - - cogl_framebuffer_draw_rectangles (fb, pipeline, - rectangles, n_rects); - cogl_object_unref (pipeline); - } -} - static void meta_shaped_texture_get_preferred_width (ClutterActor *self, gfloat for_height, @@ -764,41 +694,6 @@ meta_shaped_texture_get_texture (MetaShapedTexture *stex) return COGL_TEXTURE (stex->priv->texture); } -/** - * meta_shaped_texture_set_input_shape_region: - * @stex: a #MetaShapedTexture - * @shape_region: the region of the texture that should respond to - * input. - * - * Determines what region of the texture should accept input. For - * X based windows this is defined by the ShapeInput region of the - * window. - */ -void -meta_shaped_texture_set_input_shape_region (MetaShapedTexture *stex, - cairo_region_t *shape_region) -{ - MetaShapedTexturePrivate *priv; - - g_return_if_fail (META_IS_SHAPED_TEXTURE (stex)); - - priv = stex->priv; - - if (priv->input_shape_region != NULL) - { - cairo_region_destroy (priv->input_shape_region); - priv->input_shape_region = NULL; - } - - if (shape_region != NULL) - { - cairo_region_reference (shape_region); - priv->input_shape_region = shape_region; - } - - clutter_actor_queue_redraw (CLUTTER_ACTOR (stex)); -} - /** * meta_shaped_texture_set_opaque_region: * @stex: a #MetaShapedTexture diff --git a/src/compositor/meta-surface-actor.c b/src/compositor/meta-surface-actor.c index 541094cff..5afa4d70f 100644 --- a/src/compositor/meta-surface-actor.c +++ b/src/compositor/meta-surface-actor.c @@ -22,8 +22,12 @@ struct _MetaSurfaceActorPrivate { + MetaWaylandSurface *surface; + MetaShapedTexture *texture; MetaWaylandBuffer *buffer; + + cairo_region_t *input_region; }; static void cullable_iface_init (MetaCullableInterface *iface); @@ -39,9 +43,77 @@ meta_surface_actor_get_unobscured_bounds (MetaSurfaceActor *self, return meta_shaped_texture_get_unobscured_bounds (priv->texture, unobscured_bounds); } +static void +meta_surface_actor_pick (ClutterActor *actor, + const ClutterColor *color) +{ + MetaSurfaceActor *self = META_SURFACE_ACTOR (actor); + MetaSurfaceActorPrivate *priv = self->priv; + + if (!clutter_actor_should_pick_paint (actor)) + return; + + /* If there is no region then use the regular pick */ + if (priv->input_region == NULL) + CLUTTER_ACTOR_CLASS (meta_surface_actor_parent_class)->pick (actor, color); + else + { + int n_rects; + float *rectangles; + int i; + CoglPipeline *pipeline; + CoglContext *ctx; + CoglFramebuffer *fb; + CoglColor cogl_color; + + n_rects = cairo_region_num_rectangles (priv->input_region); + rectangles = g_alloca (sizeof (float) * 4 * n_rects); + + for (i = 0; i < n_rects; i++) + { + cairo_rectangle_int_t rect; + int pos = i * 4; + + cairo_region_get_rectangle (priv->input_region, i, &rect); + + rectangles[pos + 0] = rect.x; + rectangles[pos + 1] = rect.y; + rectangles[pos + 2] = rect.x + rect.width; + rectangles[pos + 3] = rect.y + rect.height; + } + + ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ()); + fb = cogl_get_draw_framebuffer (); + + cogl_color_init_from_4ub (&cogl_color, color->red, color->green, color->blue, color->alpha); + + pipeline = cogl_pipeline_new (ctx); + cogl_pipeline_set_color (pipeline, &cogl_color); + cogl_framebuffer_draw_rectangles (fb, pipeline, rectangles, n_rects); + cogl_object_unref (pipeline); + } +} + +static void +meta_surface_actor_dispose (GObject *object) +{ + MetaSurfaceActor *self = META_SURFACE_ACTOR (object); + MetaSurfaceActorPrivate *priv = self->priv; + + g_clear_pointer (&priv->input_region, cairo_region_destroy); + + G_OBJECT_CLASS (meta_surface_actor_parent_class)->dispose (object); +} + static void meta_surface_actor_class_init (MetaSurfaceActorClass *klass) { + GObjectClass *object_class = G_OBJECT_CLASS (klass); + ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); + + object_class->dispose = meta_surface_actor_dispose; + actor_class->pick = meta_surface_actor_pick; + g_type_class_add_private (klass, sizeof (MetaSurfaceActorPrivate)); } @@ -172,7 +244,14 @@ meta_surface_actor_set_input_region (MetaSurfaceActor *self, cairo_region_t *region) { MetaSurfaceActorPrivate *priv = self->priv; - meta_shaped_texture_set_input_shape_region (priv->texture, region); + + if (priv->input_region) + cairo_region_destroy (priv->input_region); + + if (region) + priv->input_region = cairo_region_reference (region); + else + priv->input_region = NULL; } void @@ -183,8 +262,20 @@ meta_surface_actor_set_opaque_region (MetaSurfaceActor *self, meta_shaped_texture_set_opaque_region (priv->texture, region); } -MetaSurfaceActor * -meta_surface_actor_new (void) +MetaWaylandSurface * +meta_surface_actor_get_surface (MetaSurfaceActor *self) { - return g_object_new (META_TYPE_SURFACE_ACTOR, NULL); + MetaSurfaceActorPrivate *priv = self->priv; + return priv->surface; +} + +MetaSurfaceActor * +meta_surface_actor_new (MetaWaylandSurface *surface) +{ + MetaSurfaceActor *self = g_object_new (META_TYPE_SURFACE_ACTOR, NULL); + MetaSurfaceActorPrivate *priv = self->priv; + + priv->surface = surface; + + return self; } diff --git a/src/compositor/meta-surface-actor.h b/src/compositor/meta-surface-actor.h index fa7f0c307..e42deb42f 100644 --- a/src/compositor/meta-surface-actor.h +++ b/src/compositor/meta-surface-actor.h @@ -36,7 +36,7 @@ struct _MetaSurfaceActor GType meta_surface_actor_get_type (void); -MetaSurfaceActor *meta_surface_actor_new (void); +MetaSurfaceActor *meta_surface_actor_new (MetaWaylandSurface *surface); cairo_surface_t *meta_surface_actor_get_image (MetaSurfaceActor *self, cairo_rectangle_int_t *clip); @@ -63,6 +63,8 @@ void meta_surface_actor_set_input_region (MetaSurfaceActor *self, void meta_surface_actor_set_opaque_region (MetaSurfaceActor *self, cairo_region_t *region); +MetaWaylandSurface *meta_surface_actor_get_surface (MetaSurfaceActor *surface); + G_END_DECLS #endif /* META_SURFACE_ACTOR_PRIVATE_H */ diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index f9568f393..c6071979c 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -353,7 +353,7 @@ meta_window_actor_constructed (GObject *object) if (window->surface) priv->surface = window->surface->surface_actor; else - priv->surface = meta_surface_actor_new (); + priv->surface = meta_surface_actor_new (NULL); g_object_ref_sink (priv->surface); clutter_actor_add_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface)); @@ -1424,7 +1424,6 @@ meta_window_actor_hide (MetaWindowActor *self, g_return_if_fail (priv->visible); priv->visible = FALSE; - clutter_actor_set_reactive (CLUTTER_ACTOR (self), FALSE); /* If a plugin is animating a workspace transition, we have to * hold off on hiding the window, and do it after the workspace @@ -1557,8 +1556,6 @@ meta_window_actor_new (MetaWindow *window) clutter_actor_hide (CLUTTER_ACTOR (self)); - clutter_actor_set_reactive (CLUTTER_ACTOR (self), TRUE); - /* Initial position in the stack is arbitrary; stacking will be synced * before we first paint. */ diff --git a/src/core/display.c b/src/core/display.c index 749938fd8..907f1a597 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -1682,8 +1682,12 @@ get_window_for_event (MetaDisplay *display, return display->grab_window; source = clutter_event_get_source (event); - if (META_IS_WINDOW_ACTOR (source)) - return meta_window_actor_get_meta_window (META_WINDOW_ACTOR (source)); + if (META_IS_SURFACE_ACTOR (source)) + { + MetaWaylandSurface *surface = meta_surface_actor_get_surface (META_SURFACE_ACTOR (source)); + g_assert (surface != NULL); + return surface->window; + } return NULL; } diff --git a/src/meta/meta-shaped-texture.h b/src/meta/meta-shaped-texture.h index b0870bf95..80b23f2ea 100644 --- a/src/meta/meta-shaped-texture.h +++ b/src/meta/meta-shaped-texture.h @@ -75,9 +75,6 @@ CoglTexture * meta_shaped_texture_get_texture (MetaShapedTexture *stex); void meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex, CoglTexture *mask_texture); -void meta_shaped_texture_set_input_shape_region (MetaShapedTexture *stex, - cairo_region_t *shape_region); - void meta_shaped_texture_set_opaque_region (MetaShapedTexture *stex, cairo_region_t *opaque_region); diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c index ff6f57de6..df8e7814f 100644 --- a/src/wayland/meta-wayland-seat.c +++ b/src/wayland/meta-wayland-seat.c @@ -420,13 +420,8 @@ meta_wayland_seat_repick (MetaWaylandSeat *seat, else seat->current_stage = NULL; - if (META_IS_WINDOW_ACTOR (actor)) - { - MetaWindow *window = - meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor)); - - surface = window->surface; - } + if (META_IS_SURFACE_ACTOR (actor)) + surface = meta_surface_actor_get_surface (META_SURFACE_ACTOR (actor)); pointer->current = surface; if (surface != pointer->focus_surface) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 2ae212d9c..10767cfff 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -645,7 +645,8 @@ meta_wayland_surface_create (MetaWaylandCompositor *compositor, wl_resource_set_implementation (surface->resource, &meta_wayland_surface_interface, surface, wl_surface_destructor); surface->buffer_destroy_listener.notify = surface_handle_buffer_destroy; - surface->surface_actor = g_object_ref_sink (meta_surface_actor_new ()); + surface->surface_actor = g_object_ref_sink (meta_surface_actor_new (surface)); + clutter_actor_set_reactive (CLUTTER_ACTOR (surface->surface_actor), TRUE); double_buffered_state_init (&surface->pending); From c251eb8ec036df6381ddc81e91e056227ded2b03 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sat, 15 Feb 2014 11:51:39 -0500 Subject: [PATCH 526/889] window-group: Don't special-case the unredirected window Since the unredirected window MetaWindowActor is stacked on top, it will naturally get culled out of the process, so we can remove the special casing here. Unfortunately, with the way that the code is currently structured, it's too difficult to actually prevent setting the clip / visible regions if the window is redirected, so just let those be set for unredirected windows for now. --- src/compositor/meta-window-actor.c | 3 ++- src/compositor/meta-window-group.c | 13 ------------- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index c6071979c..f0cbc0cb5 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -1651,11 +1651,12 @@ meta_window_actor_cull_out (MetaCullable *cullable, MetaWindowActor *self = META_WINDOW_ACTOR (cullable); MetaWindowActorPrivate *priv = self->priv; + meta_cullable_cull_out_children (cullable, unobscured_region, clip_region); + /* Don't do any culling for the unredirected window */ if (priv->unredirected) return; - meta_cullable_cull_out_children (cullable, unobscured_region, clip_region); meta_window_actor_set_clip_region_beneath (self, clip_region); } diff --git a/src/compositor/meta-window-group.c b/src/compositor/meta-window-group.c index 542060531..4096e4871 100644 --- a/src/compositor/meta-window-group.c +++ b/src/compositor/meta-window-group.c @@ -164,19 +164,6 @@ meta_window_group_paint (ClutterActor *actor) paint_y_offset = paint_y_origin - actor_y_origin; cairo_region_translate (clip_region, -paint_x_offset, -paint_y_offset); - if (!meta_is_wayland_compositor ()) - { - MetaCompScreen *info = meta_screen_get_compositor_data (window_group->screen); - if (info->unredirected_window != NULL) - { - cairo_rectangle_int_t unredirected_rect; - - meta_window_get_frame_rect (info->unredirected_window, (MetaRectangle *)&unredirected_rect); - cairo_region_subtract_rectangle (unobscured_region, &unredirected_rect); - cairo_region_subtract_rectangle (clip_region, &unredirected_rect); - } - } - meta_cullable_cull_out (META_CULLABLE (window_group), unobscured_region, clip_region); cairo_region_destroy (unobscured_region); From 7ef8d21e48438296da066111bdd4c98a5304fb14 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Feb 2014 22:21:33 -0500 Subject: [PATCH 527/889] wayland: Allow destroying the wl_surface before the xdg_surface As resource destruction can happen in any order at shutdown, we need to be flexible here. A client disconnecting without cleaning up all its resources should not assert fail. --- src/wayland/meta-wayland-surface.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 10767cfff..e8777df95 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -596,11 +596,14 @@ meta_wayland_surface_window_unmanaged (MetaWaylandSurface *surface) static void destroy_window (MetaWaylandSurface *surface) { - MetaDisplay *display = meta_get_display (); - guint32 timestamp = meta_display_get_current_time_roundtrip (display); + if (surface->window) + { + MetaDisplay *display = meta_get_display (); + guint32 timestamp = meta_display_get_current_time_roundtrip (display); + + meta_window_unmanage (surface->window, timestamp); + } - g_assert (surface->window != NULL); - meta_window_unmanage (surface->window, timestamp); g_assert (surface->window == NULL); } @@ -610,11 +613,11 @@ wl_surface_destructor (struct wl_resource *resource) MetaWaylandSurface *surface = wl_resource_get_user_data (resource); MetaWaylandCompositor *compositor = surface->compositor; - /* At the time when the wl_surface is destroyed, we should - * no longer have a window, unless we're an XWayland window - * in which case we received the wl_surface.destroy before - * the UnmapNotify/DestroyNotify. */ - g_assert (surface->window == NULL || surface->window->client_type == META_WINDOW_CLIENT_TYPE_X11); + /* If we still have a window at the time of destruction, that means that + * the client is disconnecting, as the resources are destroyed in a random + * order. Simply destroy the window in this case. */ + if (surface->window) + destroy_window (surface); compositor->surfaces = g_list_remove (compositor->surfaces, surface); From f771bb88d688b5737c32fbf12246c9d220bf14df Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Feb 2014 22:23:08 -0500 Subject: [PATCH 528/889] Revert "wayland: Explicitly destroy the surface actor" This reverts commit 283a81eac0a2012ed7b1b9e758a5c5ab166d3863. This can't be done yet, as it will crash when we try to do a destroy effect from a plugin. The surface actor needs to outlive the surface in this case. Though, the unparenting happening is wrong anyway for a destroy effect. We need to figure out a sane way of doing this unparenting only after all effects have finished. --- src/wayland/meta-wayland-surface.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index e8777df95..02ae53a6b 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -624,7 +624,6 @@ wl_surface_destructor (struct wl_resource *resource) surface_set_buffer (surface, NULL); double_buffered_state_destroy (&surface->pending); - clutter_actor_destroy (CLUTTER_ACTOR (surface->surface_actor)); g_object_unref (surface->surface_actor); if (surface->resource) From 374e30043b894dddcc89e0905a36ff69c5be1642 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Feb 2014 22:42:34 -0500 Subject: [PATCH 529/889] wayland: Remove width / height from MetaWaylandBuffer They're in the texture. --- src/wayland/meta-wayland-surface.c | 10 ++++------ src/wayland/meta-wayland-surface.h | 1 - 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 02ae53a6b..7d9257367 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -273,8 +273,6 @@ ensure_buffer_texture (MetaWaylandBuffer *buffer) } buffer->texture = texture; - buffer->width = cogl_texture_get_width (texture); - buffer->height = cogl_texture_get_height (texture); } static void @@ -324,11 +322,11 @@ toplevel_surface_commit (MetaWaylandSurface *surface, /* We resize X based surfaces according to X events */ if (buffer != NULL && window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND) { - int new_width; - int new_height; + int new_width, new_height; + + new_width = cogl_texture_get_width (buffer->texture); + new_height = cogl_texture_get_height (buffer->texture); - new_width = surface->buffer->width; - new_height = surface->buffer->height; if (new_width != window->rect.width || new_height != window->rect.height || pending->dx != 0 || diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h index 8b10b31fb..14305696c 100644 --- a/src/wayland/meta-wayland-surface.h +++ b/src/wayland/meta-wayland-surface.h @@ -38,7 +38,6 @@ struct _MetaWaylandBuffer struct wl_listener destroy_listener; CoglTexture *texture; - int32_t width, height; uint32_t ref_count; }; From 7615d17293666df495aec34981a2cd55ea023c2d Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Feb 2014 23:03:56 -0500 Subject: [PATCH 530/889] wayland: Tie activate / deactivate to appears-focused ... rather than actual focus. This makes things behave better. --- src/core/window.c | 8 ++++++++ src/wayland/meta-wayland-keyboard.c | 4 ---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/core/window.c b/src/core/window.c index 5c57d3c7b..5465e7bf6 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -6360,6 +6360,14 @@ meta_window_appears_focused_changed (MetaWindow *window) if (window->frame) meta_frame_queue_draw (window->frame); + + if (window->surface) + { + if (meta_window_appears_focused (window)) + meta_wayland_surface_activated (window->surface); + else + meta_wayland_surface_deactivated (window->surface); + } } /** diff --git a/src/wayland/meta-wayland-keyboard.c b/src/wayland/meta-wayland-keyboard.c index 963ad2909..f4ac4d8f6 100644 --- a/src/wayland/meta-wayland-keyboard.c +++ b/src/wayland/meta-wayland-keyboard.c @@ -542,8 +542,6 @@ meta_wayland_keyboard_set_focus (MetaWaylandKeyboard *keyboard, struct wl_display *display = wl_client_get_display (client); serial = wl_display_next_serial (display); wl_keyboard_send_leave (resource, serial, keyboard->focus_surface->resource); - - meta_wayland_surface_deactivated (keyboard->focus_surface); } wl_list_remove (&keyboard->focus_resource_listener.link); @@ -584,8 +582,6 @@ meta_wayland_keyboard_set_focus (MetaWaylandKeyboard *keyboard, &keyboard->keys); } - meta_wayland_surface_activated (surface); - keyboard->focus_resource = resource; keyboard->focus_surface = surface; From a5d950f453cd38a3442cc1ef49c22297a2d6335d Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Feb 2014 23:16:54 -0500 Subject: [PATCH 531/889] pointer/keyboard: Fix focus setting once again Yet another large-scale restructuring... this is some messy code. --- src/wayland/meta-wayland-keyboard.c | 97 +++++++++++++------------- src/wayland/meta-wayland-pointer.c | 101 ++++++++++++++-------------- 2 files changed, 99 insertions(+), 99 deletions(-) diff --git a/src/wayland/meta-wayland-keyboard.c b/src/wayland/meta-wayland-keyboard.c index f4ac4d8f6..9d41f98b2 100644 --- a/src/wayland/meta-wayland-keyboard.c +++ b/src/wayland/meta-wayland-keyboard.c @@ -527,68 +527,65 @@ void meta_wayland_keyboard_set_focus (MetaWaylandKeyboard *keyboard, MetaWaylandSurface *surface) { - struct wl_resource *resource; - uint32_t serial; - if (keyboard->focus_surface == surface && keyboard->focus_resource != NULL) return; - resource = keyboard->focus_resource; - if (resource) + if (keyboard->focus_surface != NULL) { - if (keyboard->focus_surface->resource) - { - struct wl_client *client = wl_resource_get_client (resource); - struct wl_display *display = wl_client_get_display (client); - serial = wl_display_next_serial (display); - wl_keyboard_send_leave (resource, serial, keyboard->focus_surface->resource); - } - - wl_list_remove (&keyboard->focus_resource_listener.link); wl_list_remove (&keyboard->focus_surface_listener.link); - - keyboard->focus_resource = NULL; keyboard->focus_surface = NULL; + + if (keyboard->focus_resource) + { + if (keyboard->focus_surface->resource) + { + struct wl_client *client = wl_resource_get_client (keyboard->focus_resource); + struct wl_display *display = wl_client_get_display (client); + uint32_t serial = wl_display_next_serial (display); + wl_keyboard_send_leave (keyboard->focus_resource, serial, keyboard->focus_surface->resource); + } + + wl_list_remove (&keyboard->focus_resource_listener.link); + keyboard->focus_resource = NULL; + } } - resource = find_resource_for_surface (&keyboard->resource_list, surface); - if (resource) + if (surface != NULL) { - struct wl_client *client = wl_resource_get_client (resource); - struct wl_display *display = wl_client_get_display (client); - - serial = wl_display_next_serial (display); - - /* If we're in a modal grab, the client is focused but doesn't see - modifiers or pressed keys (and fix that up when we exit the modal) */ - if (keyboard->grab->interface == &modal_grab) - { - struct wl_array empty; - wl_array_init (&empty); - - wl_keyboard_send_modifiers (resource, serial, - 0, 0, 0, 0); - wl_keyboard_send_enter (resource, serial, surface->resource, - &empty); - } - else - { - wl_keyboard_send_modifiers (resource, serial, - keyboard->modifier_state.mods_depressed, - keyboard->modifier_state.mods_latched, - keyboard->modifier_state.mods_locked, - keyboard->modifier_state.group); - wl_keyboard_send_enter (resource, serial, surface->resource, - &keyboard->keys); - } - - keyboard->focus_resource = resource; keyboard->focus_surface = surface; - - wl_resource_add_destroy_listener (keyboard->focus_resource, &keyboard->focus_resource_listener); wl_resource_add_destroy_listener (keyboard->focus_surface->resource, &keyboard->focus_surface_listener); - keyboard->focus_serial = serial; + keyboard->focus_resource = find_resource_for_surface (&keyboard->resource_list, surface); + if (keyboard->focus_resource) + { + struct wl_client *client = wl_resource_get_client (keyboard->focus_resource); + struct wl_display *display = wl_client_get_display (client); + uint32_t serial = wl_display_next_serial (display); + + /* If we're in a modal grab, the client is focused but doesn't see + modifiers or pressed keys (and fix that up when we exit the modal) */ + if (keyboard->grab->interface == &modal_grab) + { + struct wl_array empty; + wl_array_init (&empty); + + wl_keyboard_send_modifiers (keyboard->focus_resource, serial, 0, 0, 0, 0); + wl_keyboard_send_enter (keyboard->focus_resource, serial, keyboard->focus_surface->resource, &empty); + } + else + { + wl_keyboard_send_modifiers (keyboard->focus_resource, serial, + keyboard->modifier_state.mods_depressed, + keyboard->modifier_state.mods_latched, + keyboard->modifier_state.mods_locked, + keyboard->modifier_state.group); + wl_keyboard_send_enter (keyboard->focus_resource, serial, keyboard->focus_surface->resource, + &keyboard->keys); + } + + wl_resource_add_destroy_listener (keyboard->focus_resource, &keyboard->focus_resource_listener); + keyboard->focus_serial = serial; + } } } diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index 30a1e9ef1..b0030dd9e 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -333,68 +333,71 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer, { MetaWaylandSeat *seat = meta_wayland_pointer_get_seat (pointer); MetaWaylandKeyboard *kbd = &seat->keyboard; - struct wl_resource *resource, *kr; - uint32_t serial; if (pointer->focus_surface == surface && pointer->focus_resource != NULL) return; - resource = pointer->focus_resource; - if (resource) + if (pointer->focus_surface) { - if (pointer->focus_surface->resource) - { - struct wl_client *client = wl_resource_get_client (resource); - struct wl_display *display = wl_client_get_display (client); - serial = wl_display_next_serial (display); - wl_pointer_send_leave (resource, serial, pointer->focus_surface->resource); - } - wl_list_remove (&pointer->focus_surface_listener.link); - wl_list_remove (&pointer->focus_resource_listener.link); - pointer->focus_surface = NULL; - pointer->focus_resource = NULL; + + if (pointer->focus_resource) + { + if (pointer->focus_surface->resource) + { + struct wl_client *client = wl_resource_get_client (pointer->focus_resource); + struct wl_display *display = wl_client_get_display (client); + uint32_t serial = wl_display_next_serial (display); + wl_pointer_send_leave (pointer->focus_resource, serial, pointer->focus_surface->resource); + } + + wl_list_remove (&pointer->focus_resource_listener.link); + + pointer->focus_surface = NULL; + pointer->focus_resource = NULL; + } } - resource = find_resource_for_surface (&pointer->resource_list, surface); - if (resource) + if (surface != NULL) { - struct wl_client *client = wl_resource_get_client (resource); - struct wl_display *display = wl_client_get_display (client); - wl_fixed_t sx, sy; - - serial = wl_display_next_serial (display); - - if (kbd) - { - kr = find_resource_for_surface (&kbd->resource_list, surface); - if (kr) - { - wl_keyboard_send_modifiers (kr, - serial, - kbd->modifier_state.mods_depressed, - kbd->modifier_state.mods_latched, - kbd->modifier_state.mods_locked, - kbd->modifier_state.group); - } - } - - meta_wayland_pointer_get_relative_coordinates (pointer, surface, &sx, &sy); - meta_window_handle_enter (surface->window, - /* XXX -- can we reliably get a timestamp for setting focus? */ - clutter_get_current_event_time (), - wl_fixed_to_int (pointer->x), - wl_fixed_to_int (pointer->y)); - wl_pointer_send_enter (resource, serial, surface->resource, sx, sy); - - pointer->focus_resource = resource; pointer->focus_surface = surface; - - wl_resource_add_destroy_listener (pointer->focus_resource, &pointer->focus_resource_listener); wl_resource_add_destroy_listener (pointer->focus_surface->resource, &pointer->focus_surface_listener); - pointer->focus_serial = serial; + pointer->focus_resource = find_resource_for_surface (&pointer->resource_list, surface); + if (pointer->focus_resource) + { + struct wl_client *client = wl_resource_get_client (pointer->focus_resource); + struct wl_display *display = wl_client_get_display (client); + wl_fixed_t sx, sy; + + uint32_t serial = wl_display_next_serial (display); + + if (kbd) + { + struct wl_resource *kr = find_resource_for_surface (&kbd->resource_list, pointer->focus_surface); + if (kr) + { + wl_keyboard_send_modifiers (kr, + serial, + kbd->modifier_state.mods_depressed, + kbd->modifier_state.mods_latched, + kbd->modifier_state.mods_locked, + kbd->modifier_state.group); + } + } + + meta_wayland_pointer_get_relative_coordinates (pointer, pointer->focus_surface, &sx, &sy); + meta_window_handle_enter (pointer->focus_surface->window, + /* XXX -- can we reliably get a timestamp for setting focus? */ + clutter_get_current_event_time (), + wl_fixed_to_int (pointer->x), + wl_fixed_to_int (pointer->y)); + wl_pointer_send_enter (pointer->focus_resource, serial, pointer->focus_surface->resource, sx, sy); + + wl_resource_add_destroy_listener (pointer->focus_resource, &pointer->focus_resource_listener); + pointer->focus_serial = serial; + } } } From ff5867e4d33d195d5780560a1329b01fb51851d6 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Feb 2014 23:18:13 -0500 Subject: [PATCH 532/889] pointer: Make the code here a bit clearer --- src/wayland/meta-wayland-pointer.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index b0030dd9e..7f6a4afb7 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -369,8 +369,6 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer, { struct wl_client *client = wl_resource_get_client (pointer->focus_resource); struct wl_display *display = wl_client_get_display (client); - wl_fixed_t sx, sy; - uint32_t serial = wl_display_next_serial (display); if (kbd) @@ -387,13 +385,18 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer, } } - meta_wayland_pointer_get_relative_coordinates (pointer, pointer->focus_surface, &sx, &sy); meta_window_handle_enter (pointer->focus_surface->window, /* XXX -- can we reliably get a timestamp for setting focus? */ clutter_get_current_event_time (), wl_fixed_to_int (pointer->x), wl_fixed_to_int (pointer->y)); - wl_pointer_send_enter (pointer->focus_resource, serial, pointer->focus_surface->resource, sx, sy); + + { + wl_fixed_t sx, sy; + + meta_wayland_pointer_get_relative_coordinates (pointer, pointer->focus_surface, &sx, &sy); + wl_pointer_send_enter (pointer->focus_resource, serial, pointer->focus_surface->resource, sx, sy); + } wl_resource_add_destroy_listener (pointer->focus_resource, &pointer->focus_resource_listener); pointer->focus_serial = serial; From 48f7232492a83f6fbe0a80f0332602ac38217877 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Feb 2014 23:18:44 -0500 Subject: [PATCH 533/889] pointer: Don't send modifiers on mouse enter I talked to Kristian about this. It should be enough to simply send it when we activate the surface and give it keyboard focus. --- src/wayland/meta-wayland-keyboard.c | 31 +++-------------------------- src/wayland/meta-wayland-pointer.c | 25 ----------------------- 2 files changed, 3 insertions(+), 53 deletions(-) diff --git a/src/wayland/meta-wayland-keyboard.c b/src/wayland/meta-wayland-keyboard.c index 9d41f98b2..9b54fcbb1 100644 --- a/src/wayland/meta-wayland-keyboard.c +++ b/src/wayland/meta-wayland-keyboard.c @@ -60,14 +60,6 @@ #include "meta-wayland-private.h" -static MetaWaylandSeat * -meta_wayland_keyboard_get_seat (MetaWaylandKeyboard *keyboard) -{ - MetaWaylandSeat *seat = wl_container_of (keyboard, seat, keyboard); - - return seat; -} - static int create_anonymous_file (off_t size, GError **error) @@ -291,28 +283,11 @@ default_grab_modifiers (MetaWaylandKeyboardGrab *grab, uint32_t serial, uint32_t mods_locked, uint32_t group) { MetaWaylandKeyboard *keyboard = grab->keyboard; - MetaWaylandSeat *seat = meta_wayland_keyboard_get_seat (keyboard); - MetaWaylandPointer *pointer = &seat->pointer; - struct wl_resource *resource, *pr; - resource = keyboard->focus_resource; - if (!resource) - return; - - wl_keyboard_send_modifiers (resource, serial, mods_depressed, - mods_latched, mods_locked, group); - - if (pointer && pointer->focus_surface && pointer->focus_surface != keyboard->focus_surface) + if (keyboard->focus_resource) { - pr = find_resource_for_surface (&keyboard->resource_list, pointer->focus_surface); - if (pr) - { - wl_keyboard_send_modifiers (pr, serial, - mods_depressed, - mods_latched, - mods_locked, - group); - } + wl_keyboard_send_modifiers (keyboard->focus_resource, serial, mods_depressed, + mods_latched, mods_locked, group); } } diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index 7f6a4afb7..907003fd2 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -55,14 +55,6 @@ static void meta_wayland_pointer_end_popup_grab (MetaWaylandPointer *pointer); -static MetaWaylandSeat * -meta_wayland_pointer_get_seat (MetaWaylandPointer *pointer) -{ - MetaWaylandSeat *seat = wl_container_of (pointer, seat, pointer); - - return seat; -} - static void release_focus (MetaWaylandPointer *pointer) { @@ -331,9 +323,6 @@ void meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer, MetaWaylandSurface *surface) { - MetaWaylandSeat *seat = meta_wayland_pointer_get_seat (pointer); - MetaWaylandKeyboard *kbd = &seat->keyboard; - if (pointer->focus_surface == surface && pointer->focus_resource != NULL) return; @@ -371,20 +360,6 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer, struct wl_display *display = wl_client_get_display (client); uint32_t serial = wl_display_next_serial (display); - if (kbd) - { - struct wl_resource *kr = find_resource_for_surface (&kbd->resource_list, pointer->focus_surface); - if (kr) - { - wl_keyboard_send_modifiers (kr, - serial, - kbd->modifier_state.mods_depressed, - kbd->modifier_state.mods_latched, - kbd->modifier_state.mods_locked, - kbd->modifier_state.group); - } - } - meta_window_handle_enter (pointer->focus_surface->window, /* XXX -- can we reliably get a timestamp for setting focus? */ clutter_get_current_event_time (), From 0dccc440b692b7dc4d891295d9138892bf0d7aad Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Feb 2014 23:36:46 -0500 Subject: [PATCH 534/889] window-actor: Kill off a nonsensical edge case We can never have a window actor that represents either the X root window or the stage window, so it doesn't make sense to bail out early in case we do. I'd imagine that this came from a much earlier version of the code where the compositor was much separate and had its own MapNotify handling. --- src/compositor/meta-window-actor.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index f0cbc0cb5..be2514eb4 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -1684,20 +1684,14 @@ cullable_iface_init (MetaCullableInterface *iface) static void check_needs_x11_pixmap (MetaWindowActor *self) { - MetaWindowActorPrivate *priv = self->priv; - MetaScreen *screen = priv->screen; - MetaDisplay *display = meta_screen_get_display (screen); - Display *xdisplay = meta_display_get_xdisplay (display); - MetaCompScreen *info = meta_screen_get_compositor_data (screen); - Window xwindow = meta_window_get_toplevel_xwindow (priv->window); + MetaWindowActorPrivate *priv = self->priv; + MetaDisplay *display = meta_screen_get_display (screen); + Display *xdisplay = meta_display_get_xdisplay (display); + Window xwindow = meta_window_get_toplevel_xwindow (priv->window); if (!priv->needs_pixmap) return; - if (xwindow == meta_screen_get_xroot (screen) || - xwindow == clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage))) - return; - if (priv->x11_size_changed) { meta_window_actor_detach_x11_pixmap (self); From c964ef4e012d7ba4ce88ec23fd0ab30f722a6dc4 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 19 Feb 2014 01:11:10 -0500 Subject: [PATCH 535/889] window-actor: Fix build I'm bad. --- src/compositor/meta-window-actor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index be2514eb4..9456990cb 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -1685,7 +1685,7 @@ static void check_needs_x11_pixmap (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; - MetaDisplay *display = meta_screen_get_display (screen); + MetaDisplay *display = meta_screen_get_display (priv->screen); Display *xdisplay = meta_display_get_xdisplay (display); Window xwindow = meta_window_get_toplevel_xwindow (priv->window); From 17462c21e80991cbeb8874006fca5e876578d0d0 Mon Sep 17 00:00:00 2001 From: Marek Chalupa Date: Wed, 19 Feb 2014 13:56:56 +0100 Subject: [PATCH 536/889] pointer/keyboard: fix setting focus Set focus to NULL after using the variable --- src/wayland/meta-wayland-keyboard.c | 6 +++--- src/wayland/meta-wayland-pointer.c | 8 +++----- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/wayland/meta-wayland-keyboard.c b/src/wayland/meta-wayland-keyboard.c index 9b54fcbb1..5b98c4f6f 100644 --- a/src/wayland/meta-wayland-keyboard.c +++ b/src/wayland/meta-wayland-keyboard.c @@ -507,9 +507,6 @@ meta_wayland_keyboard_set_focus (MetaWaylandKeyboard *keyboard, if (keyboard->focus_surface != NULL) { - wl_list_remove (&keyboard->focus_surface_listener.link); - keyboard->focus_surface = NULL; - if (keyboard->focus_resource) { if (keyboard->focus_surface->resource) @@ -523,6 +520,9 @@ meta_wayland_keyboard_set_focus (MetaWaylandKeyboard *keyboard, wl_list_remove (&keyboard->focus_resource_listener.link); keyboard->focus_resource = NULL; } + + wl_list_remove (&keyboard->focus_surface_listener.link); + keyboard->focus_surface = NULL; } if (surface != NULL) diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index 907003fd2..2a72fc1a5 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -328,9 +328,6 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer, if (pointer->focus_surface) { - wl_list_remove (&pointer->focus_surface_listener.link); - pointer->focus_surface = NULL; - if (pointer->focus_resource) { if (pointer->focus_surface->resource) @@ -342,10 +339,11 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer, } wl_list_remove (&pointer->focus_resource_listener.link); - - pointer->focus_surface = NULL; pointer->focus_resource = NULL; } + + wl_list_remove (&pointer->focus_surface_listener.link); + pointer->focus_surface = NULL; } if (surface != NULL) From 4de3f7ca2994f19a23f5b073f92a4b3374faf105 Mon Sep 17 00:00:00 2001 From: Stefano Facchini Date: Sat, 24 Mar 2012 11:29:39 +0100 Subject: [PATCH 537/889] Make tile preview a compositor plugin effect https://bugzilla.gnome.org/show_bug.cgi?id=665758 --- src/Makefile.am | 2 - src/compositor/compositor.c | 28 ++++ src/compositor/meta-plugin-manager.c | 41 ++++++ src/compositor/meta-plugin-manager.h | 5 + src/compositor/plugins/default.c | 95 +++++++++++++ src/core/keybindings.c | 2 +- src/core/screen-private.h | 5 +- src/core/screen.c | 42 ++---- src/core/window-private.h | 1 + src/core/window.c | 28 ++-- src/meta/compositor.h | 8 ++ src/meta/meta-plugin.h | 5 + src/ui/tile-preview.c | 196 --------------------------- src/ui/tile-preview.h | 36 ----- src/ui/ui.h | 1 - 15 files changed, 216 insertions(+), 279 deletions(-) delete mode 100644 src/ui/tile-preview.c delete mode 100644 src/ui/tile-preview.h diff --git a/src/Makefile.am b/src/Makefile.am index ae8f7c130..ec8b2ecab 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -182,8 +182,6 @@ libmutter_wayland_la_SOURCES = \ ui/resizepopup.h \ ui/tabpopup.c \ ui/tabpopup.h \ - ui/tile-preview.c \ - ui/tile-preview.h \ ui/theme-parser.c \ ui/theme.c \ meta/theme.h \ diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 6ed2df400..88b525ffd 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -1695,3 +1695,31 @@ meta_compositor_monotonic_time_to_server_time (MetaDisplay *display, else return monotonic_time + compositor->server_time_offset; } + +void +meta_compositor_show_tile_preview (MetaCompositor *compositor, + MetaScreen *screen, + MetaWindow *window, + MetaRectangle *tile_rect, + int tile_monitor_number) +{ + MetaCompScreen *info = meta_screen_get_compositor_data (screen); + + if (!info->plugin_mgr) + return; + + meta_plugin_manager_show_tile_preview (info->plugin_mgr, + window, tile_rect, tile_monitor_number); +} + +void +meta_compositor_hide_tile_preview (MetaCompositor *compositor, + MetaScreen *screen) +{ + MetaCompScreen *info = meta_screen_get_compositor_data (screen); + + if (!info->plugin_mgr) + return; + + meta_plugin_manager_hide_tile_preview (info->plugin_mgr); +} diff --git a/src/compositor/meta-plugin-manager.c b/src/compositor/meta-plugin-manager.c index 1d6d373ce..41589a32c 100644 --- a/src/compositor/meta-plugin-manager.c +++ b/src/compositor/meta-plugin-manager.c @@ -324,3 +324,44 @@ meta_plugin_manager_confirm_display_change (MetaPluginManager *plugin_mgr) else return meta_plugin_complete_display_change (plugin, TRUE); } + +gboolean +meta_plugin_manager_show_tile_preview (MetaPluginManager *plugin_mgr, + MetaWindow *window, + MetaRectangle *tile_rect, + int tile_monitor_number) +{ + MetaPlugin *plugin = plugin_mgr->plugin; + MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin); + MetaDisplay *display = meta_screen_get_display (plugin_mgr->screen); + + if (display->display_opening) + return FALSE; + + if (klass->show_tile_preview) + { + klass->show_tile_preview (plugin, window, tile_rect, tile_monitor_number); + return TRUE; + } + + return FALSE; +} + +gboolean +meta_plugin_manager_hide_tile_preview (MetaPluginManager *plugin_mgr) +{ + MetaPlugin *plugin = plugin_mgr->plugin; + MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin); + MetaDisplay *display = meta_screen_get_display (plugin_mgr->screen); + + if (display->display_opening) + return FALSE; + + if (klass->hide_tile_preview) + { + klass->hide_tile_preview (plugin); + return TRUE; + } + + return FALSE; +} diff --git a/src/compositor/meta-plugin-manager.h b/src/compositor/meta-plugin-manager.h index b24059ffc..efc4deb52 100644 --- a/src/compositor/meta-plugin-manager.h +++ b/src/compositor/meta-plugin-manager.h @@ -75,4 +75,9 @@ gboolean _meta_plugin_xevent_filter (MetaPlugin *plugin, void meta_plugin_manager_confirm_display_change (MetaPluginManager *mgr); +gboolean meta_plugin_manager_show_tile_preview (MetaPluginManager *mgr, + MetaWindow *window, + MetaRectangle *tile_rect, + int tile_monitor_number); +gboolean meta_plugin_manager_hide_tile_preview (MetaPluginManager *mgr); #endif diff --git a/src/compositor/plugins/default.c b/src/compositor/plugins/default.c index ae3352286..1c1820fd5 100644 --- a/src/compositor/plugins/default.c +++ b/src/compositor/plugins/default.c @@ -39,6 +39,7 @@ #define SWITCH_TIMEOUT 500 #define ACTOR_DATA_KEY "MCCP-Default-actor-data" +#define SCREEN_TILE_PREVIEW_DATA_KEY "MCCP-Default-screen-tile-preview-data" #define META_TYPE_DEFAULT_PLUGIN (meta_default_plugin_get_type ()) #define META_DEFAULT_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_DEFAULT_PLUGIN, MetaDefaultPlugin)) @@ -67,6 +68,7 @@ struct _MetaDefaultPluginClass }; static GQuark actor_data_quark = 0; +static GQuark screen_tile_preview_data_quark = 0; static void start (MetaPlugin *plugin); static void minimize (MetaPlugin *plugin, @@ -97,6 +99,12 @@ static void kill_window_effects (MetaPlugin *plugin, MetaWindowActor *actor); static void kill_switch_workspace (MetaPlugin *plugin); +static void show_tile_preview (MetaPlugin *plugin, + MetaWindow *window, + MetaRectangle *tile_rect, + int tile_monitor_number); +static void hide_tile_preview (MetaPlugin *plugin); + static void confirm_display_change (MetaPlugin *plugin); static const MetaPluginInfo * plugin_info (MetaPlugin *plugin); @@ -143,6 +151,15 @@ typedef struct } EffectCompleteData; +typedef struct _ScreenTilePreview +{ + ClutterActor *actor; + + GdkRGBA *preview_color; + + MetaRectangle tile_rect; +} ScreenTilePreview; + static void meta_default_plugin_dispose (GObject *object) { @@ -203,6 +220,8 @@ meta_default_plugin_class_init (MetaDefaultPluginClass *klass) plugin_class->unmaximize = unmaximize; plugin_class->destroy = destroy; plugin_class->switch_workspace = switch_workspace; + plugin_class->show_tile_preview = show_tile_preview; + plugin_class->hide_tile_preview = hide_tile_preview; plugin_class->plugin_info = plugin_info; plugin_class->kill_window_effects = kill_window_effects; plugin_class->kill_switch_workspace = kill_switch_workspace; @@ -749,6 +768,82 @@ destroy (MetaPlugin *plugin, MetaWindowActor *window_actor) meta_plugin_destroy_completed (plugin, window_actor); } +/* + * Tile preview private data accessor + */ +static void +free_screen_tile_preview (gpointer data) +{ + ScreenTilePreview *preview = data; + + if (G_LIKELY (preview != NULL)) { + clutter_actor_destroy (preview->actor); + g_slice_free (ScreenTilePreview, preview); + } +} + +static ScreenTilePreview * +get_screen_tile_preview (MetaScreen *screen) +{ + ScreenTilePreview *preview = g_object_get_qdata (G_OBJECT (screen), screen_tile_preview_data_quark); + + if (G_UNLIKELY (screen_tile_preview_data_quark == 0)) + screen_tile_preview_data_quark = g_quark_from_static_string (SCREEN_TILE_PREVIEW_DATA_KEY); + + if (G_UNLIKELY (!preview)) + { + preview = g_slice_new0 (ScreenTilePreview); + + preview->actor = clutter_actor_new (); + clutter_actor_set_background_color (preview->actor, CLUTTER_COLOR_Blue); + clutter_actor_set_opacity (preview->actor, 100); + + clutter_actor_add_child (meta_get_window_group_for_screen (screen), preview->actor); + g_object_set_qdata_full (G_OBJECT (screen), + screen_tile_preview_data_quark, preview, + free_screen_tile_preview); + } + + return preview; +} + +static void +show_tile_preview (MetaPlugin *plugin, + MetaWindow *window, + MetaRectangle *tile_rect, + int tile_monitor_number) +{ + MetaScreen *screen = meta_plugin_get_screen (plugin); + ScreenTilePreview *preview = get_screen_tile_preview (screen); + ClutterActor *window_actor; + + if (CLUTTER_ACTOR_IS_VISIBLE (preview->actor) + && preview->tile_rect.x == tile_rect->x + && preview->tile_rect.y == tile_rect->y + && preview->tile_rect.width == tile_rect->width + && preview->tile_rect.height == tile_rect->height) + return; /* nothing to do */ + + clutter_actor_set_position (preview->actor, tile_rect->x, tile_rect->y); + clutter_actor_set_size (preview->actor, tile_rect->width, tile_rect->height); + + clutter_actor_show (preview->actor); + + window_actor = CLUTTER_ACTOR (meta_window_get_compositor_private (window)); + clutter_actor_lower (preview->actor, window_actor); + + preview->tile_rect = *tile_rect; +} + +static void +hide_tile_preview (MetaPlugin *plugin) +{ + MetaScreen *screen = meta_plugin_get_screen (plugin); + ScreenTilePreview *preview = get_screen_tile_preview (screen); + + clutter_actor_hide (preview->actor); +} + static void kill_switch_workspace (MetaPlugin *plugin) { diff --git a/src/core/keybindings.c b/src/core/keybindings.c index e46d046d1..9024410ee 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -2165,7 +2165,7 @@ process_mouse_move_resize_grab (MetaDisplay *display, { /* Hide the tiling preview if necessary */ if (window->tile_mode != META_TILE_NONE) - meta_screen_tile_preview_hide (screen); + meta_screen_hide_tile_preview (screen); /* Restore the original tile mode */ window->tile_mode = display->grab_tile_mode; diff --git a/src/core/screen-private.h b/src/core/screen-private.h index e3a3c7729..2d9c31765 100644 --- a/src/core/screen-private.h +++ b/src/core/screen-private.h @@ -65,7 +65,6 @@ struct _MetaScreen MetaRectangle rect; /* Size of screen; rect.x & rect.y are always 0 */ MetaUI *ui; MetaTabPopup *tab_popup, *ws_popup; - MetaTilePreview *tile_preview; guint tile_preview_timeout_id; @@ -167,9 +166,9 @@ void meta_screen_workspace_popup_select (MetaScreen *screen, MetaWorkspace*meta_screen_workspace_popup_get_selected (MetaScreen *screen); void meta_screen_workspace_popup_destroy (MetaScreen *screen); -void meta_screen_tile_preview_update (MetaScreen *screen, +void meta_screen_update_tile_preview (MetaScreen *screen, gboolean delay); -void meta_screen_tile_preview_hide (MetaScreen *screen); +void meta_screen_hide_tile_preview (MetaScreen *screen); MetaWindow* meta_screen_get_mouse_window (MetaScreen *screen, MetaWindow *not_this_one); diff --git a/src/core/screen.c b/src/core/screen.c index c68ee10ff..9df2a8cbe 100644 --- a/src/core/screen.c +++ b/src/core/screen.c @@ -762,7 +762,6 @@ meta_screen_new (MetaDisplay *display, screen->tab_popup = NULL; screen->ws_popup = NULL; - screen->tile_preview = NULL; screen->tile_preview_timeout_id = 0; @@ -868,9 +867,6 @@ meta_screen_free (MetaScreen *screen, if (screen->tile_preview_timeout_id) g_source_remove (screen->tile_preview_timeout_id); - if (screen->tile_preview) - meta_tile_preview_free (screen->tile_preview); - g_free (screen->screen_name); g_object_unref (screen); @@ -1680,7 +1676,7 @@ meta_screen_workspace_popup_destroy (MetaScreen *screen) } static gboolean -meta_screen_tile_preview_update_timeout (gpointer data) +meta_screen_update_tile_preview_timeout (gpointer data) { MetaScreen *screen = data; MetaWindow *window = screen->display->grab_window; @@ -1688,22 +1684,6 @@ meta_screen_tile_preview_update_timeout (gpointer data) screen->tile_preview_timeout_id = 0; - if (!screen->tile_preview) - { - Window xwindow; - gulong create_serial; - MetaStackWindow stack_window; - - screen->tile_preview = meta_tile_preview_new (screen->number); - xwindow = meta_tile_preview_get_xwindow (screen->tile_preview, - &create_serial); - stack_window.any.type = META_WINDOW_CLIENT_TYPE_X11; - stack_window.x11.xwindow = xwindow; - meta_stack_tracker_record_add (screen->stack_tracker, - &stack_window, - create_serial); - } - if (window) { switch (window->tile_mode) @@ -1728,12 +1708,16 @@ meta_screen_tile_preview_update_timeout (gpointer data) if (needs_preview) { MetaRectangle tile_rect; + int monitor; + monitor = meta_window_get_current_tile_monitor_number (window); meta_window_get_current_tile_area (window, &tile_rect); - meta_tile_preview_show (screen->tile_preview, &tile_rect); + meta_compositor_show_tile_preview (screen->display->compositor, + screen, window, &tile_rect, monitor); } else - meta_tile_preview_hide (screen->tile_preview); + meta_compositor_hide_tile_preview (screen->display->compositor, + screen); return FALSE; } @@ -1741,7 +1725,7 @@ meta_screen_tile_preview_update_timeout (gpointer data) #define TILE_PREVIEW_TIMEOUT_MS 200 void -meta_screen_tile_preview_update (MetaScreen *screen, +meta_screen_update_tile_preview (MetaScreen *screen, gboolean delay) { if (delay) @@ -1751,7 +1735,7 @@ meta_screen_tile_preview_update (MetaScreen *screen, screen->tile_preview_timeout_id = g_timeout_add (TILE_PREVIEW_TIMEOUT_MS, - meta_screen_tile_preview_update_timeout, + meta_screen_update_tile_preview_timeout, screen); } else @@ -1759,18 +1743,18 @@ meta_screen_tile_preview_update (MetaScreen *screen, if (screen->tile_preview_timeout_id > 0) g_source_remove (screen->tile_preview_timeout_id); - meta_screen_tile_preview_update_timeout ((gpointer)screen); + meta_screen_update_tile_preview_timeout ((gpointer)screen); } } void -meta_screen_tile_preview_hide (MetaScreen *screen) +meta_screen_hide_tile_preview (MetaScreen *screen) { if (screen->tile_preview_timeout_id > 0) g_source_remove (screen->tile_preview_timeout_id); - if (screen->tile_preview) - meta_tile_preview_hide (screen->tile_preview); + meta_compositor_hide_tile_preview (screen->display->compositor, + screen); } MetaWindow* diff --git a/src/core/window-private.h b/src/core/window-private.h index f931eac29..d37c27d14 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -652,6 +652,7 @@ void meta_window_handle_mouse_grab_op_xevent (MetaWindow *window, GList* meta_window_get_workspaces (MetaWindow *window); +int meta_window_get_current_tile_monitor_number (MetaWindow *window); void meta_window_get_current_tile_area (MetaWindow *window, MetaRectangle *tile_area); diff --git a/src/core/window.c b/src/core/window.c index 5465e7bf6..81ca3f8ae 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -1177,9 +1177,6 @@ _meta_window_shared_new (MetaDisplay *display, if (!window->override_redirect) meta_stack_add (window->screen->stack, window); - else if (window->screen->tile_preview != NULL && - meta_tile_preview_get_xwindow (window->screen->tile_preview, NULL) == xwindow) - window->layer = META_LAYER_NORMAL; else window->layer = META_LAYER_OVERRIDE_REDIRECT; /* otherwise set by MetaStack */ @@ -3369,7 +3366,7 @@ meta_window_tile (MetaWindow *window) directions = META_MAXIMIZE_VERTICAL; meta_window_maximize_internal (window, directions, NULL); - meta_screen_tile_preview_update (window->screen, FALSE); + meta_screen_update_tile_preview (window->screen, FALSE); if (window->display->compositor) { @@ -8108,7 +8105,7 @@ update_move (MetaWindow *window, * trigger it unwittingly, e.g. when shaking loose the window or moving * it to another monitor. */ - meta_screen_tile_preview_update (window->screen, + meta_screen_update_tile_preview (window->screen, window->tile_mode != META_TILE_NONE); meta_window_get_client_root_coords (window, &old); @@ -8956,6 +8953,20 @@ meta_window_get_work_area_all_monitors (MetaWindow *window, window->desc, area->x, area->y, area->width, area->height); } +int +meta_window_get_current_tile_monitor_number (MetaWindow *window) +{ + int tile_monitor_number = window->tile_monitor_number; + + if (tile_monitor_number < 0) + { + meta_warning ("%s called with an invalid monitor number; using 0 instead\n", G_STRFUNC); + tile_monitor_number = 0; + } + + return tile_monitor_number; +} + void meta_window_get_current_tile_area (MetaWindow *window, MetaRectangle *tile_area) @@ -8964,12 +8975,7 @@ meta_window_get_current_tile_area (MetaWindow *window, g_return_if_fail (window->tile_mode != META_TILE_NONE); - tile_monitor_number = window->tile_monitor_number; - if (tile_monitor_number < 0) - { - meta_warning ("%s called with an invalid monitor number; using 0 instead\n", G_STRFUNC); - tile_monitor_number = 0; - } + tile_monitor_number = meta_window_get_current_tile_monitor_number (window); meta_window_get_work_area_for_monitor (window, tile_monitor_number, tile_area); diff --git a/src/meta/compositor.h b/src/meta/compositor.h index 45c8b09dd..d1be47e36 100644 --- a/src/meta/compositor.h +++ b/src/meta/compositor.h @@ -121,4 +121,12 @@ void meta_compositor_sync_screen_size (MetaCompositor *compositor, void meta_compositor_flash_screen (MetaCompositor *compositor, MetaScreen *screen); +void meta_compositor_show_tile_preview (MetaCompositor *compositor, + MetaScreen *screen, + MetaWindow *window, + MetaRectangle *tile_rect, + int tile_monitor_number); +void meta_compositor_hide_tile_preview (MetaCompositor *compositor, + MetaScreen *screen); + #endif /* META_COMPOSITOR_H */ diff --git a/src/meta/meta-plugin.h b/src/meta/meta-plugin.h index 00fe77989..cef785397 100644 --- a/src/meta/meta-plugin.h +++ b/src/meta/meta-plugin.h @@ -158,6 +158,11 @@ struct _MetaPluginClass gint to, MetaMotionDirection direction); + void (*show_tile_preview) (MetaPlugin *plugin, + MetaWindow *window, + MetaRectangle *tile_rect, + int tile_monitor_number); + void (*hide_tile_preview) (MetaPlugin *plugin); /** * MetaPluginClass::kill_window_effects: diff --git a/src/ui/tile-preview.c b/src/ui/tile-preview.c deleted file mode 100644 index 8fbf46884..000000000 --- a/src/ui/tile-preview.c +++ /dev/null @@ -1,196 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* Mutter tile-preview marks the area a window will *ehm* snap to */ - -/* - * Copyright (C) 2010 Florian Müllner - * - * 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 "tile-preview.h" -#include "core.h" - -#define OUTLINE_WIDTH 5 /* frame width in non-composite case */ - - -struct _MetaTilePreview { - GtkWidget *preview_window; - gulong create_serial; - - GdkRGBA *preview_color; - - MetaRectangle tile_rect; -}; - -static gboolean -meta_tile_preview_draw (GtkWidget *widget, - cairo_t *cr, - gpointer user_data) -{ - MetaTilePreview *preview = user_data; - - cairo_set_line_width (cr, 1.0); - - /* Fill the preview area with a transparent color */ - gdk_cairo_set_source_rgba (cr, preview->preview_color); - - cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); - cairo_paint (cr); - - /* Use the opaque color for the border */ - cairo_set_source_rgb (cr, - preview->preview_color->red, - preview->preview_color->green, - preview->preview_color->blue); - - cairo_rectangle (cr, - 0.5, 0.5, - preview->tile_rect.width - 1, - preview->tile_rect.height - 1); - cairo_stroke (cr); - - return FALSE; -} - -MetaTilePreview * -meta_tile_preview_new (int screen_number) -{ - MetaTilePreview *preview; - GdkScreen *screen; - GtkStyleContext *context; - GtkWidgetPath *path; - guchar selection_alpha = 0xFF; - - screen = gdk_display_get_screen (gdk_display_get_default (), screen_number); - - preview = g_new (MetaTilePreview, 1); - - preview->preview_window = gtk_window_new (GTK_WINDOW_POPUP); - - gtk_window_set_screen (GTK_WINDOW (preview->preview_window), screen); - gtk_widget_set_app_paintable (preview->preview_window, TRUE); - - preview->preview_color = NULL; - - preview->tile_rect.x = preview->tile_rect.y = 0; - preview->tile_rect.width = preview->tile_rect.height = 0; - - gtk_widget_set_visual (preview->preview_window, - gdk_screen_get_rgba_visual (screen)); - - path = gtk_widget_path_new (); - gtk_widget_path_append_type (path, GTK_TYPE_ICON_VIEW); - - context = gtk_style_context_new (); - gtk_style_context_set_path (context, path); - gtk_style_context_add_class (context, - GTK_STYLE_CLASS_RUBBERBAND); - - gtk_widget_path_free (path); - - gtk_style_context_get (context, GTK_STATE_FLAG_SELECTED, - "background-color", &preview->preview_color, - NULL); - - /* The background-color for the .rubberband class should probably - * contain the correct alpha value - unfortunately, at least for now - * it doesn't. Hopefully the following workaround can be removed - * when GtkIconView gets ported to GtkStyleContext. - */ - gtk_style_context_get_style (context, - "selection-box-alpha", &selection_alpha, - NULL); - preview->preview_color->alpha = (double)selection_alpha / 0xFF; - - g_object_unref (context); - - /* We make an assumption that XCreateWindow will be the first operation - * when calling gtk_widget_realize() (via gdk_window_new()), or that it - * is at least "close enough". - */ - preview->create_serial = XNextRequest (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ())); - gtk_widget_realize (preview->preview_window); - g_signal_connect (preview->preview_window, "draw", - G_CALLBACK (meta_tile_preview_draw), preview); - - return preview; -} - -void -meta_tile_preview_free (MetaTilePreview *preview) -{ - gtk_widget_destroy (preview->preview_window); - - if (preview->preview_color) - gdk_rgba_free (preview->preview_color); - - g_free (preview); -} - -void -meta_tile_preview_show (MetaTilePreview *preview, - MetaRectangle *tile_rect) -{ - GdkWindow *window; - GdkRectangle old_rect; - - if (gtk_widget_get_visible (preview->preview_window) - && preview->tile_rect.x == tile_rect->x - && preview->tile_rect.y == tile_rect->y - && preview->tile_rect.width == tile_rect->width - && preview->tile_rect.height == tile_rect->height) - return; /* nothing to do */ - - gtk_widget_show (preview->preview_window); - window = gtk_widget_get_window (preview->preview_window); - meta_core_lower_beneath_grab_window (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), - GDK_WINDOW_XID (window), - gtk_get_current_event_time ()); - - old_rect.x = old_rect.y = 0; - old_rect.width = preview->tile_rect.width; - old_rect.height = preview->tile_rect.height; - - gdk_window_invalidate_rect (window, &old_rect, FALSE); - - preview->tile_rect = *tile_rect; - - gdk_window_move_resize (window, - preview->tile_rect.x, preview->tile_rect.y, - preview->tile_rect.width, preview->tile_rect.height); -} - -void -meta_tile_preview_hide (MetaTilePreview *preview) -{ - gtk_widget_hide (preview->preview_window); -} - -Window -meta_tile_preview_get_xwindow (MetaTilePreview *preview, - gulong *create_serial) -{ - GdkWindow *window = gtk_widget_get_window (preview->preview_window); - - if (create_serial) - *create_serial = preview->create_serial; - - return GDK_WINDOW_XID (window); -} diff --git a/src/ui/tile-preview.h b/src/ui/tile-preview.h deleted file mode 100644 index 352483fa3..000000000 --- a/src/ui/tile-preview.h +++ /dev/null @@ -1,36 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* Meta tile preview */ - -/* - * Copyright (C) 2010 Florian Müllner - * - * 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_TILE_PREVIEW_H -#define META_TILE_PREVIEW_H - -#include - -typedef struct _MetaTilePreview MetaTilePreview; - -MetaTilePreview *meta_tile_preview_new (int screen_number); -void meta_tile_preview_free (MetaTilePreview *preview); -void meta_tile_preview_show (MetaTilePreview *preview, - MetaRectangle *rect); -void meta_tile_preview_hide (MetaTilePreview *preview); -Window meta_tile_preview_get_xwindow (MetaTilePreview *preview, - gulong *create_serial); - -#endif /* META_TILE_PREVIEW_H */ diff --git a/src/ui/ui.h b/src/ui/ui.h index 07bf77edd..f1170797a 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -179,6 +179,5 @@ int meta_ui_get_drag_threshold (MetaUI *ui); MetaUIDirection meta_ui_get_direction (void); #include "tabpopup.h" -#include "tile-preview.h" #endif From 7499621ecb26850b2bd1b21bf61968fed1d97b0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 19 Feb 2014 21:58:42 +0100 Subject: [PATCH 538/889] Bump version to 3.11.90 Update NEWS. --- NEWS | 11 +++++++++++ configure.ac | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index d8b03465b..cf66b4132 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,14 @@ +3.11.90 +======= +* Fix double-scaling on high DPI resolutions [Adel; #723931] +* Make tile previews a compositor effect [Stefano, Florian; #665758] +* Misc. bug fixes and cleanups [Ryan, Giovanni, Jasper, Adel; #722530, #724257, + #724258, #720631, #724364, #724472] + +Contributors: + Giovanni Campagna, Marek Chalupa, Stefano Facchini, Adel Gadllah, + Ryan Lortie, Florian Müllner, Jasper St. Pierre, Rico Tzschichholz + 3.11.5 ====== * Fix CSD titlebars being placed off-screen [Jasper; #719772] diff --git a/configure.ac b/configure.ac index 329025ad9..d67d7d24a 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ AC_CONFIG_MACRO_DIR([m4]) m4_define([mutter_major_version], [3]) m4_define([mutter_minor_version], [11]) -m4_define([mutter_micro_version], [5]) +m4_define([mutter_micro_version], [90]) m4_define([mutter_version], [mutter_major_version.mutter_minor_version.mutter_micro_version]) From 7ebf5aa69a990b0713699d684303aba2f83993a9 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 20 Feb 2014 11:29:28 -0500 Subject: [PATCH 539/889] pointer/keyboard: Properly handle destruction If the client destroys the pointer resource, we shouldn't unfocus the surface, and we should regrab it when the client gets the pointer resource again. This also fixes a crash at surface destruction because of the unchecked wl_link_remove that will happen on both pointer and surface destroy. --- src/wayland/meta-wayland-keyboard.c | 18 ++++++------------ src/wayland/meta-wayland-pointer.c | 20 +++++++------------- 2 files changed, 13 insertions(+), 25 deletions(-) diff --git a/src/wayland/meta-wayland-keyboard.c b/src/wayland/meta-wayland-keyboard.c index 5b98c4f6f..e07b6f29c 100644 --- a/src/wayland/meta-wayland-keyboard.c +++ b/src/wayland/meta-wayland-keyboard.c @@ -217,28 +217,22 @@ err_keymap_str: return; } -static void -release_focus (MetaWaylandKeyboard *keyboard) -{ - wl_list_remove (&keyboard->focus_surface_listener.link); - wl_list_remove (&keyboard->focus_resource_listener.link); - - keyboard->focus_resource = NULL; - keyboard->focus_surface = NULL; -} - static void keyboard_handle_focus_surface_destroy (struct wl_listener *listener, void *data) { MetaWaylandKeyboard *keyboard = wl_container_of (listener, keyboard, focus_surface_listener); - release_focus (keyboard); + + wl_list_remove (&keyboard->focus_surface_listener.link); + keyboard->focus_surface = NULL; } static void keyboard_handle_focus_resource_destroy (struct wl_listener *listener, void *data) { MetaWaylandKeyboard *keyboard = wl_container_of (listener, keyboard, focus_resource_listener); - release_focus (keyboard); + + wl_list_remove (&keyboard->focus_resource_listener.link); + keyboard->focus_resource = NULL; } static gboolean diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index 2a72fc1a5..88ced65e1 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -55,28 +55,22 @@ static void meta_wayland_pointer_end_popup_grab (MetaWaylandPointer *pointer); -static void -release_focus (MetaWaylandPointer *pointer) -{ - wl_list_remove (&pointer->focus_surface_listener.link); - wl_list_remove (&pointer->focus_resource_listener.link); - - pointer->focus_resource = NULL; - pointer->focus_surface = NULL; -} - static void pointer_handle_focus_surface_destroy (struct wl_listener *listener, void *data) { MetaWaylandPointer *pointer = wl_container_of (listener, pointer, focus_surface_listener); - release_focus (pointer); + + wl_list_remove (&pointer->focus_surface_listener.link); + pointer->focus_surface = NULL; } static void pointer_handle_focus_resource_destroy (struct wl_listener *listener, void *data) { MetaWaylandPointer *pointer = wl_container_of (listener, pointer, focus_resource_listener); - release_focus (pointer); + + wl_list_remove (&pointer->focus_resource_listener.link); + pointer->focus_resource = NULL; } static void @@ -302,7 +296,7 @@ meta_wayland_pointer_init (MetaWaylandPointer *pointer) void meta_wayland_pointer_release (MetaWaylandPointer *pointer) { - release_focus (pointer); + /* Do nothing. */ } static struct wl_resource * From bc792593989c711eb9e6f4af456315933ecaf2c2 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Feb 2014 23:29:19 -0500 Subject: [PATCH 540/889] window-actor: Don't queue a redraw when queueing a new pixmap We guarantee ourselves that a valid pixmap will appear any time that the window is painted. The window actor will be scheduled for a repaint if it's added / removed from the scene graph, like during construction, if the size changes, or if we receive damage, which are the existing use cases where this function is called. So, I can't see any reason that we queue a redraw in here. With the split into surface actors, we don't have an easy place we can use to queue a redraw, and since it's unnecessary, we can just drop it on the floor. https://bugzilla.gnome.org/show_bug.cgi?id=720631 --- src/compositor/meta-window-actor.c | 28 +++------------------------- 1 file changed, 3 insertions(+), 25 deletions(-) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 9456990cb..6e5b80783 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -997,27 +997,6 @@ is_frozen (MetaWindowActor *self) return self->priv->freeze_count ? TRUE : FALSE; } -static void -meta_window_actor_queue_create_x11_pixmap (MetaWindowActor *self) -{ - MetaWindowActorPrivate *priv = self->priv; - - priv->needs_pixmap = TRUE; - - if (is_frozen (self)) - return; - - /* This will cause the compositor paint function to be run - * if the actor is visible or a clone of the actor is visible. - * if the actor isn't visible in any way, then we don't - * need to repair the window anyways, and can wait until - * the stage is redrawn for some other reason - * - * The compositor paint function repairs all windows. - */ - clutter_actor_queue_redraw (CLUTTER_ACTOR (priv->surface)); -} - static gboolean is_freeze_thaw_effect (gulong event) { @@ -1203,8 +1182,7 @@ meta_window_actor_detach_x11_pixmap (MetaWindowActor *self) XFreePixmap (xdisplay, priv->back_pixmap); priv->back_pixmap = None; - - meta_window_actor_queue_create_x11_pixmap (self); + priv->needs_pixmap = TRUE; } gboolean @@ -1354,7 +1332,7 @@ meta_window_actor_sync_actor_geometry (MetaWindowActor *self, { if (priv->x11_size_changed) { - meta_window_actor_queue_create_x11_pixmap (self); + priv->needs_pixmap = TRUE; meta_window_actor_update_shape (self); } } @@ -1530,7 +1508,7 @@ meta_window_actor_new (MetaWindow *window) priv->last_width = -1; priv->last_height = -1; - meta_window_actor_queue_create_x11_pixmap (self); + priv->needs_pixmap = TRUE; meta_window_actor_set_updates_frozen (self, meta_window_updates_are_frozen (priv->window)); From 0b055fae2e63babdf807d8e782550b8ad037d503 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Feb 2014 23:34:06 -0500 Subject: [PATCH 541/889] window-actor: Kill off needs_pixmap It's mostly equivalent to the case where we've already detached the pixmap, *except* for the x11_size_changed case. We can simply detach the pixmap at the time the window changes size, though. https://bugzilla.gnome.org/show_bug.cgi?id=720631 --- src/compositor/meta-window-actor.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 6e5b80783..d0e57d3d2 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -119,8 +119,6 @@ struct _MetaWindowActorPrivate guint needs_damage_all : 1; guint received_x11_damage : 1; - guint needs_pixmap : 1; - guint x11_size_changed : 1; guint updates_frozen : 1; @@ -897,7 +895,7 @@ meta_window_actor_damage_all (MetaWindowActor *self) if (!priv->needs_damage_all) return; - if (priv->needs_pixmap) + if (priv->back_pixmap == None) return; redraw_queued = meta_surface_actor_damage_all (priv->surface); @@ -1080,7 +1078,7 @@ meta_window_actor_after_effects (MetaWindowActor *self) if (!meta_is_wayland_compositor ()) { - if (priv->needs_pixmap) + if (priv->back_pixmap == None) clutter_actor_queue_redraw (CLUTTER_ACTOR (priv->surface)); } } @@ -1182,7 +1180,6 @@ meta_window_actor_detach_x11_pixmap (MetaWindowActor *self) XFreePixmap (xdisplay, priv->back_pixmap); priv->back_pixmap = None; - priv->needs_pixmap = TRUE; } gboolean @@ -1332,7 +1329,7 @@ meta_window_actor_sync_actor_geometry (MetaWindowActor *self, { if (priv->x11_size_changed) { - priv->needs_pixmap = TRUE; + meta_window_actor_detach_x11_pixmap (self); meta_window_actor_update_shape (self); } } @@ -1508,8 +1505,6 @@ meta_window_actor_new (MetaWindow *window) priv->last_width = -1; priv->last_height = -1; - priv->needs_pixmap = TRUE; - meta_window_actor_set_updates_frozen (self, meta_window_updates_are_frozen (priv->window)); @@ -1667,9 +1662,8 @@ check_needs_x11_pixmap (MetaWindowActor *self) Display *xdisplay = meta_display_get_xdisplay (display); Window xwindow = meta_window_get_toplevel_xwindow (priv->window); - if (!priv->needs_pixmap) - return; - + /* If the size changed while we were frozen, the old pixmap + * will still be attached, and we need to create a new one. */ if (priv->x11_size_changed) { meta_window_actor_detach_x11_pixmap (self); @@ -1712,8 +1706,6 @@ check_needs_x11_pixmap (MetaWindowActor *self) meta_surface_actor_set_texture (META_SURFACE_ACTOR (priv->surface), texture); } - priv->needs_pixmap = FALSE; - out: meta_error_trap_pop (display); } @@ -1831,7 +1823,7 @@ meta_window_actor_process_x11_damage (MetaWindowActor *self, return; } - if (priv->needs_pixmap) + if (priv->back_pixmap == None) return; redraw_queued = meta_surface_actor_damage_area (priv->surface, From 83aca0b53dc8706bea232cc2208c9fc1bc701607 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sat, 1 Feb 2014 17:21:11 -0500 Subject: [PATCH 542/889] window-actor: Split into two subclasses of MetaSurfaceActor The rendering logic before was somewhat complex. We had three independent cases to take into account when doing rendering: * X11 compositor. In this case, we're a traditional X11 compositor, not a Wayland compositor. We use XCompositeNameWindowPixmap to get the backing pixmap for the window, and deal with the COMPOSITE extension messiness. In this case, meta_is_wayland_compositor() is FALSE. * Wayland clients. In this case, we're a Wayland compositor managing Wayland surfaces. The rendering for this is fairly straightforward, as Cogl handles most of the complexity with EGL and SHM buffers... Wayland clients give us the input and opaque regions through wl_surface. In this case, meta_is_wayland_compositor() is TRUE and priv->window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND. * XWayland clients. In this case, we're a Wayland compositor, like above, and XWayland hands us Wayland surfaces. XWayland handles the COMPOSITE extension messiness for us, and hands us a buffer like any other Wayland client. We have to fetch the input and opaque regions from the X11 window ourselves. In this case, meta_is_wayland_compositor() is TRUE and priv->window->client_type == META_WINDOW_CLIENT_TYPE_X11. We now split the rendering logic into two subclasses, which are: * MetaSurfaceActorX11, which handles the X11 compositor case, in that it uses XCompositeNameWindowPixmap to get the backing pixmap, and deal with all the COMPOSITE extension messiness. * MetaSurfaceActorWayland, which handles the Wayland compositor case for both native Wayland clients and XWayland clients. XWayland handles COMPOSITE for us, and handles pushing a surface over through the xf86-video-wayland DDX. Frame sync is still in MetaWindowActor, as it needs to work for both the X11 compositor and XWayland client cases. When Wayland's video display protocol lands, this will need to be significantly overhauled, as it would have to work for any wl_surface, including subsurfaces, so we would need surface-level discretion. https://bugzilla.gnome.org/show_bug.cgi?id=720631 --- src/Makefile.am | 4 + src/compositor/meta-surface-actor-wayland.c | 153 ++++++ src/compositor/meta-surface-actor-wayland.h | 66 +++ src/compositor/meta-surface-actor-x11.c | 453 ++++++++++++++++ src/compositor/meta-surface-actor-x11.h | 69 +++ src/compositor/meta-surface-actor.c | 213 +++++--- src/compositor/meta-surface-actor.h | 43 +- src/compositor/meta-window-actor.c | 550 ++++---------------- src/core/display.c | 5 +- src/wayland/meta-wayland-seat.c | 5 +- src/wayland/meta-wayland-surface.c | 13 +- 11 files changed, 1016 insertions(+), 558 deletions(-) create mode 100644 src/compositor/meta-surface-actor-wayland.c create mode 100644 src/compositor/meta-surface-actor-wayland.h create mode 100644 src/compositor/meta-surface-actor-x11.c create mode 100644 src/compositor/meta-surface-actor-x11.h diff --git a/src/Makefile.am b/src/Makefile.am index ec8b2ecab..ba029b7ea 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -80,6 +80,10 @@ libmutter_wayland_la_SOURCES = \ compositor/meta-shaped-texture-private.h \ compositor/meta-surface-actor.c \ compositor/meta-surface-actor.h \ + compositor/meta-surface-actor-x11.c \ + compositor/meta-surface-actor-x11.h \ + compositor/meta-surface-actor-wayland.c \ + compositor/meta-surface-actor-wayland.h \ compositor/meta-texture-rectangle.c \ compositor/meta-texture-rectangle.h \ compositor/meta-texture-tower.c \ diff --git a/src/compositor/meta-surface-actor-wayland.c b/src/compositor/meta-surface-actor-wayland.c new file mode 100644 index 000000000..9fe1e8220 --- /dev/null +++ b/src/compositor/meta-surface-actor-wayland.c @@ -0,0 +1,153 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2013 Red Hat + * + * 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. + * + * Written by: + * Jasper St. Pierre + */ + +#include "config.h" + +#include "meta-surface-actor-wayland.h" + +#include +#include "meta-shaped-texture-private.h" + +struct _MetaSurfaceActorWaylandPrivate +{ + MetaWaylandSurface *surface; + MetaWaylandBuffer *buffer; +}; +typedef struct _MetaSurfaceActorWaylandPrivate MetaSurfaceActorWaylandPrivate; + +G_DEFINE_TYPE_WITH_PRIVATE (MetaSurfaceActorWayland, meta_surface_actor_wayland, META_TYPE_SURFACE_ACTOR) + +static void +meta_surface_actor_wayland_process_damage (MetaSurfaceActor *actor, + int x, int y, int width, int height) +{ + MetaSurfaceActorWayland *self = META_SURFACE_ACTOR_WAYLAND (actor); + MetaSurfaceActorWaylandPrivate *priv = meta_surface_actor_wayland_get_instance_private (self); + + struct wl_resource *resource = priv->buffer->resource; + struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get (resource); + + if (shm_buffer) + { + CoglTexture2D *texture = COGL_TEXTURE_2D (priv->buffer->texture); + cogl_wayland_texture_set_region_from_shm_buffer (texture, x, y, width, height, shm_buffer, x, y, 0, NULL); + } + + meta_surface_actor_update_area (META_SURFACE_ACTOR (self), x, y, width, height); +} + +static void +meta_surface_actor_wayland_pre_paint (MetaSurfaceActor *actor) +{ +} + +static gboolean +meta_surface_actor_wayland_is_argb32 (MetaSurfaceActor *actor) +{ + /* XXX -- look at the SHM buffer format. */ + return TRUE; +} + +static gboolean +meta_surface_actor_wayland_is_visible (MetaSurfaceActor *actor) +{ + /* TODO: ensure that the buffer isn't NULL, implement + * wayland mapping semantics */ + return TRUE; +} + +static gboolean +meta_surface_actor_wayland_should_unredirect (MetaSurfaceActor *actor) +{ + return FALSE; +} + +static void +meta_surface_actor_wayland_set_unredirected (MetaSurfaceActor *actor, + gboolean unredirected) +{ + /* Do nothing. In the future, we'll use KMS to set this + * up as a hardware overlay or something. */ +} + +static gboolean +meta_surface_actor_wayland_is_unredirected (MetaSurfaceActor *actor) +{ + return FALSE; +} + +static void +meta_surface_actor_wayland_class_init (MetaSurfaceActorWaylandClass *klass) +{ + MetaSurfaceActorClass *surface_actor_class = META_SURFACE_ACTOR_CLASS (klass); + + surface_actor_class->process_damage = meta_surface_actor_wayland_process_damage; + surface_actor_class->pre_paint = meta_surface_actor_wayland_pre_paint; + surface_actor_class->is_argb32 = meta_surface_actor_wayland_is_argb32; + surface_actor_class->is_visible = meta_surface_actor_wayland_is_visible; + + surface_actor_class->should_unredirect = meta_surface_actor_wayland_should_unredirect; + surface_actor_class->set_unredirected = meta_surface_actor_wayland_set_unredirected; + surface_actor_class->is_unredirected = meta_surface_actor_wayland_is_unredirected; +} + +static void +meta_surface_actor_wayland_init (MetaSurfaceActorWayland *self) +{ +} + +MetaSurfaceActor * +meta_surface_actor_wayland_new (MetaWaylandSurface *surface) +{ + MetaSurfaceActorWayland *self = g_object_new (META_TYPE_SURFACE_ACTOR_WAYLAND, NULL); + MetaSurfaceActorWaylandPrivate *priv = meta_surface_actor_wayland_get_instance_private (self); + + g_assert (meta_is_wayland_compositor ()); + + priv->surface = surface; + + return META_SURFACE_ACTOR (self); +} + +void +meta_surface_actor_wayland_set_buffer (MetaSurfaceActorWayland *self, + MetaWaylandBuffer *buffer) +{ + MetaSurfaceActorWaylandPrivate *priv = meta_surface_actor_wayland_get_instance_private (self); + MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self)); + + priv->buffer = buffer; + + if (buffer) + meta_shaped_texture_set_texture (stex, buffer->texture); + else + meta_shaped_texture_set_texture (stex, NULL); +} + +MetaWaylandSurface * +meta_surface_actor_wayland_get_surface (MetaSurfaceActorWayland *self) +{ + MetaSurfaceActorWaylandPrivate *priv = meta_surface_actor_wayland_get_instance_private (self); + return priv->surface; +} diff --git a/src/compositor/meta-surface-actor-wayland.h b/src/compositor/meta-surface-actor-wayland.h new file mode 100644 index 000000000..89c6b300f --- /dev/null +++ b/src/compositor/meta-surface-actor-wayland.h @@ -0,0 +1,66 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2013 Red Hat + * + * 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. + * + * Written by: + * Jasper St. Pierre + */ + +#ifndef __META_SURFACE_ACTOR_WAYLAND_H__ +#define __META_SURFACE_ACTOR_WAYLAND_H__ + +#include + +#include "meta-surface-actor.h" + +#include "meta-wayland-private.h" + +G_BEGIN_DECLS + +#define META_TYPE_SURFACE_ACTOR_WAYLAND (meta_surface_actor_wayland_get_type ()) +#define META_SURFACE_ACTOR_WAYLAND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_SURFACE_ACTOR_WAYLAND, MetaSurfaceActorWayland)) +#define META_SURFACE_ACTOR_WAYLAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_SURFACE_ACTOR_WAYLAND, MetaSurfaceActorWaylandClass)) +#define META_IS_SURFACE_ACTOR_WAYLAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_SURFACE_ACTOR_WAYLAND)) +#define META_IS_SURFACE_ACTOR_WAYLAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_SURFACE_ACTOR_WAYLAND)) +#define META_SURFACE_ACTOR_WAYLAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_SURFACE_ACTOR_WAYLAND, MetaSurfaceActorWaylandClass)) + +typedef struct _MetaSurfaceActorWayland MetaSurfaceActorWayland; +typedef struct _MetaSurfaceActorWaylandClass MetaSurfaceActorWaylandClass; + +struct _MetaSurfaceActorWayland +{ + MetaSurfaceActor parent; +}; + +struct _MetaSurfaceActorWaylandClass +{ + MetaSurfaceActorClass parent_class; +}; + +GType meta_surface_actor_wayland_get_type (void); + +MetaSurfaceActor * meta_surface_actor_wayland_new (MetaWaylandSurface *surface); +MetaWaylandSurface * meta_surface_actor_wayland_get_surface (MetaSurfaceActorWayland *self); + +void meta_surface_actor_wayland_set_buffer (MetaSurfaceActorWayland *self, + MetaWaylandBuffer *buffer); + +G_END_DECLS + +#endif /* __META_SURFACE_ACTOR_WAYLAND_H__ */ diff --git a/src/compositor/meta-surface-actor-x11.c b/src/compositor/meta-surface-actor-x11.c new file mode 100644 index 000000000..3eea2c31b --- /dev/null +++ b/src/compositor/meta-surface-actor-x11.c @@ -0,0 +1,453 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2013 Red Hat + * + * 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. + * + * Written by: + * Owen Taylor + * Jasper St. Pierre + */ + +#include "config.h" + +#include "meta-surface-actor-x11.h" + +#include +#include +#include + +#include +#include "window-private.h" +#include "meta-shaped-texture-private.h" +#include "meta-cullable.h" + +struct _MetaSurfaceActorX11Private +{ + MetaWindow *window; + + MetaDisplay *display; + + CoglTexture *texture; + Pixmap pixmap; + Damage damage; + + int last_width; + int last_height; + + /* This is used to detect fullscreen windows that need to be unredirected */ + guint full_damage_frames_count; + guint does_full_damage : 1; + + /* Other state... */ + guint argb32 : 1; + guint received_damage : 1; + guint size_changed : 1; + + guint unredirected : 1; +}; +typedef struct _MetaSurfaceActorX11Private MetaSurfaceActorX11Private; + +G_DEFINE_TYPE_WITH_PRIVATE (MetaSurfaceActorX11, meta_surface_actor_x11, META_TYPE_SURFACE_ACTOR) + +static void +free_damage (MetaSurfaceActorX11 *self) +{ + MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); + MetaDisplay *display = priv->display; + Display *xdisplay = meta_display_get_xdisplay (display); + + if (priv->damage == None) + return; + + meta_error_trap_push (display); + XDamageDestroy (xdisplay, priv->damage); + priv->damage = None; + meta_error_trap_pop (display); +} + +static void +detach_pixmap (MetaSurfaceActorX11 *self) +{ + MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); + MetaDisplay *display = priv->display; + Display *xdisplay = meta_display_get_xdisplay (display); + MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self)); + + if (priv->pixmap == None) + return; + + /* Get rid of all references to the pixmap before freeing it; it's unclear whether + * you are supposed to be able to free a GLXPixmap after freeing the underlying + * pixmap, but it certainly doesn't work with current DRI/Mesa + */ + meta_shaped_texture_set_texture (stex, NULL); + cogl_flush (); + + meta_error_trap_push (display); + XFreePixmap (xdisplay, priv->pixmap); + priv->pixmap = None; + meta_error_trap_pop (display); + + cogl_object_unref (priv->texture); + priv->texture = NULL; +} + +static void +set_pixmap (MetaSurfaceActorX11 *self, + Pixmap pixmap) +{ + MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); + + CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ()); + MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self)); + CoglTexture *texture; + + g_assert (priv->pixmap == None); + priv->pixmap = pixmap; + + texture = COGL_TEXTURE (cogl_texture_pixmap_x11_new (ctx, priv->pixmap, FALSE, NULL)); + + if (G_UNLIKELY (!cogl_texture_pixmap_x11_is_using_tfp_extension (COGL_TEXTURE_PIXMAP_X11 (texture)))) + g_warning ("NOTE: Not using GLX TFP!\n"); + + priv->texture = texture; + meta_shaped_texture_set_texture (stex, texture); +} + +static void +update_pixmap (MetaSurfaceActorX11 *self) +{ + MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); + MetaDisplay *display = priv->display; + Display *xdisplay = meta_display_get_xdisplay (display); + + if (priv->size_changed) + { + detach_pixmap (self); + priv->size_changed = FALSE; + } + + if (priv->pixmap == None) + { + Pixmap new_pixmap; + Window xwindow = meta_window_get_toplevel_xwindow (priv->window); + + meta_error_trap_push (display); + new_pixmap = XCompositeNameWindowPixmap (xdisplay, xwindow); + + if (meta_error_trap_pop_with_return (display) != Success) + { + /* Probably a BadMatch if the window isn't viewable; we could + * GrabServer/GetWindowAttributes/NameWindowPixmap/UngrabServer/Sync + * to avoid this, but there's no reason to take two round trips + * when one will do. (We need that Sync if we want to handle failures + * for any reason other than !viewable. That's unlikely, but maybe + * we'll BadAlloc or something.) + */ + new_pixmap = None; + } + + if (new_pixmap == None) + { + meta_verbose ("Unable to get named pixmap for %s\n", + meta_window_get_description (priv->window)); + return; + } + + set_pixmap (self, new_pixmap); + } +} + +static gboolean +is_visible (MetaSurfaceActorX11 *self) +{ + MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); + return (priv->pixmap != None) && !priv->unredirected; +} + +static void +damage_area (MetaSurfaceActorX11 *self, + int x, int y, int width, int height) +{ + MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); + + if (!is_visible (self)) + return; + + cogl_texture_pixmap_x11_update_area (priv->texture, x, y, width, height); + meta_surface_actor_update_area (META_SURFACE_ACTOR (self), x, y, width, height); +} + +static void +meta_surface_actor_x11_process_damage (MetaSurfaceActor *actor, + int x, int y, int width, int height) +{ + MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor); + MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); + + priv->received_damage = TRUE; + + if (meta_window_is_fullscreen (priv->window) && !priv->unredirected && !priv->does_full_damage) + { + MetaRectangle window_rect; + meta_window_get_frame_rect (priv->window, &window_rect); + + if (window_rect.x == x && + window_rect.y == y && + window_rect.width == width && + window_rect.height == height) + priv->full_damage_frames_count++; + else + priv->full_damage_frames_count = 0; + + if (priv->full_damage_frames_count >= 100) + priv->does_full_damage = TRUE; + } + + /* Drop damage event for unredirected windows */ + if (priv->unredirected) + return; + + damage_area (self, x, y, width, height); +} + +static void +meta_surface_actor_x11_pre_paint (MetaSurfaceActor *actor) +{ + MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor); + MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); + MetaDisplay *display = priv->display; + Display *xdisplay = meta_display_get_xdisplay (display); + + if (priv->received_damage) + { + meta_error_trap_push (display); + XDamageSubtract (xdisplay, priv->damage, None, None); + meta_error_trap_pop (display); + + /* We need to make sure that any X drawing that happens before the + * XDamageSubtract() 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. + * + * Xorg and open source driver specifics: + * + * The X server makes sure to flush drawing to the kernel before + * sending out damage events, but since we use DamageReportBoundingBox + * there may be drawing between the last damage event and the + * XDamageSubtract() that needs to be flushed as well. + * + * Xorg always makes sure that drawing is flushed to the kernel + * before writing events or responses to the client, so any round trip + * request at this point is sufficient to flush the GLX buffers. + */ + XSync (xdisplay, False); + + priv->received_damage = FALSE; + } + + update_pixmap (self); +} + +static void +update_is_argb32 (MetaSurfaceActorX11 *self) +{ + MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); + MetaDisplay *display = priv->display; + Display *xdisplay = meta_display_get_xdisplay (display); + + XRenderPictFormat *format; + format = XRenderFindVisualFormat (xdisplay, priv->window->xvisual); + + priv->argb32 = (format && format->type == PictTypeDirect && format->direct.alphaMask); +} + +static gboolean +meta_surface_actor_x11_is_argb32 (MetaSurfaceActor *actor) +{ + MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor); + MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); + + return priv->argb32; +} + +static gboolean +meta_surface_actor_x11_is_visible (MetaSurfaceActor *actor) +{ + MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor); + return is_visible (self); +} + +static gboolean +meta_surface_actor_x11_should_unredirect (MetaSurfaceActor *actor) +{ + MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor); + MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); + + MetaWindow *window = priv->window; + + if (meta_window_requested_dont_bypass_compositor (window)) + return FALSE; + + if (window->opacity != 0xFF) + return FALSE; + + if (window->shape_region != NULL) + return FALSE; + + if (priv->argb32 && !meta_window_requested_bypass_compositor (window)) + return FALSE; + + if (!meta_window_is_monitor_sized (window)) + return FALSE; + + if (meta_window_requested_bypass_compositor (window)) + return TRUE; + + if (meta_window_is_override_redirect (window)) + return TRUE; + + if (priv->does_full_damage) + return TRUE; + + return FALSE; +} + +static void +sync_unredirected (MetaSurfaceActorX11 *self) +{ + MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); + MetaDisplay *display = priv->display; + Display *xdisplay = meta_display_get_xdisplay (display); + Window xwindow = meta_window_get_toplevel_xwindow (priv->window); + + meta_error_trap_push (display); + + if (priv->unredirected) + { + detach_pixmap (self); + XCompositeUnredirectWindow (xdisplay, xwindow, CompositeRedirectManual); + } + else + { + XCompositeRedirectWindow (xdisplay, xwindow, CompositeRedirectManual); + } + + meta_error_trap_pop (display); +} + +static void +meta_surface_actor_x11_set_unredirected (MetaSurfaceActor *actor, + gboolean unredirected) +{ + MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor); + MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); + + if (priv->unredirected == unredirected) + return; + + priv->unredirected = unredirected; + sync_unredirected (self); +} + +static gboolean +meta_surface_actor_x11_is_unredirected (MetaSurfaceActor *actor) +{ + MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor); + MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); + + return priv->unredirected; +} + +static void +meta_surface_actor_x11_dispose (GObject *object) +{ + MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (object); + + detach_pixmap (self); + free_damage (self); + + G_OBJECT_CLASS (meta_surface_actor_x11_parent_class)->dispose (object); +} + +static void +meta_surface_actor_x11_class_init (MetaSurfaceActorX11Class *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + MetaSurfaceActorClass *surface_actor_class = META_SURFACE_ACTOR_CLASS (klass); + + object_class->dispose = meta_surface_actor_x11_dispose; + + surface_actor_class->process_damage = meta_surface_actor_x11_process_damage; + surface_actor_class->pre_paint = meta_surface_actor_x11_pre_paint; + surface_actor_class->is_argb32 = meta_surface_actor_x11_is_argb32; + surface_actor_class->is_visible = meta_surface_actor_x11_is_visible; + + surface_actor_class->should_unredirect = meta_surface_actor_x11_should_unredirect; + surface_actor_class->set_unredirected = meta_surface_actor_x11_set_unredirected; + surface_actor_class->is_unredirected = meta_surface_actor_x11_is_unredirected; +} + +static void +meta_surface_actor_x11_init (MetaSurfaceActorX11 *self) +{ + MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); + + priv->last_width = -1; + priv->last_height = -1; +} + +MetaSurfaceActor * +meta_surface_actor_x11_new (MetaWindow *window) +{ + MetaSurfaceActorX11 *self = g_object_new (META_TYPE_SURFACE_ACTOR_X11, NULL); + MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); + MetaDisplay *display = meta_window_get_display (window); + Display *xdisplay = meta_display_get_xdisplay (display); + Window xwindow = meta_window_get_toplevel_xwindow (window); + + g_assert (!meta_is_wayland_compositor ()); + + priv->window = window; + priv->display = display; + + priv->damage = XDamageCreate (xdisplay, xwindow, XDamageReportBoundingBox); + update_is_argb32 (self); + + priv->unredirected = FALSE; + sync_unredirected (self); + + return META_SURFACE_ACTOR (self); +} + +void +meta_surface_actor_x11_set_size (MetaSurfaceActorX11 *self, + int width, int height) +{ + MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); + + if (priv->last_width == width && + priv->last_height == height) + return; + + priv->size_changed = TRUE; + priv->last_width = width; + priv->last_height = height; +} diff --git a/src/compositor/meta-surface-actor-x11.h b/src/compositor/meta-surface-actor-x11.h new file mode 100644 index 000000000..0e692ee0f --- /dev/null +++ b/src/compositor/meta-surface-actor-x11.h @@ -0,0 +1,69 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2013 Red Hat + * + * 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. + * + * Written by: + * Owen Taylor + * Jasper St. Pierre + */ + +#ifndef __META_SURFACE_ACTOR_X11_H__ +#define __META_SURFACE_ACTOR_X11_H__ + +#include + +#include "meta-surface-actor.h" + +#include + +#include +#include + +G_BEGIN_DECLS + +#define META_TYPE_SURFACE_ACTOR_X11 (meta_surface_actor_x11_get_type ()) +#define META_SURFACE_ACTOR_X11(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_SURFACE_ACTOR_X11, MetaSurfaceActorX11)) +#define META_SURFACE_ACTOR_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_SURFACE_ACTOR_X11, MetaSurfaceActorX11Class)) +#define META_IS_SURFACE_ACTOR_X11(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_SURFACE_ACTOR_X11)) +#define META_IS_SURFACE_ACTOR_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_SURFACE_ACTOR_X11)) +#define META_SURFACE_ACTOR_X11_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_SURFACE_ACTOR_X11, MetaSurfaceActorX11Class)) + +typedef struct _MetaSurfaceActorX11 MetaSurfaceActorX11; +typedef struct _MetaSurfaceActorX11Class MetaSurfaceActorX11Class; + +struct _MetaSurfaceActorX11 +{ + MetaSurfaceActor parent; +}; + +struct _MetaSurfaceActorX11Class +{ + MetaSurfaceActorClass parent_class; +}; + +GType meta_surface_actor_x11_get_type (void); + +MetaSurfaceActor * meta_surface_actor_x11_new (MetaWindow *window); + +void meta_surface_actor_x11_set_size (MetaSurfaceActorX11 *self, + int width, int height); + +G_END_DECLS + +#endif /* __META_SURFACE_ACTOR_X11_H__ */ diff --git a/src/compositor/meta-surface-actor.c b/src/compositor/meta-surface-actor.c index 5afa4d70f..f82a6a9b8 100644 --- a/src/compositor/meta-surface-actor.c +++ b/src/compositor/meta-surface-actor.c @@ -10,30 +10,38 @@ */ #include -#include -#include -#include -#include + #include "meta-surface-actor.h" + +#include +#include #include "meta-wayland-private.h" #include "meta-cullable.h" - #include "meta-shaped-texture-private.h" struct _MetaSurfaceActorPrivate { - MetaWaylandSurface *surface; - MetaShapedTexture *texture; - MetaWaylandBuffer *buffer; cairo_region_t *input_region; + + /* Freeze/thaw accounting */ + guint freeze_count; + guint needs_damage_all : 1; }; static void cullable_iface_init (MetaCullableInterface *iface); -G_DEFINE_TYPE_WITH_CODE (MetaSurfaceActor, meta_surface_actor, CLUTTER_TYPE_ACTOR, - G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init)); +G_DEFINE_ABSTRACT_TYPE_WITH_CODE (MetaSurfaceActor, meta_surface_actor, CLUTTER_TYPE_ACTOR, + G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init)); + +enum { + REPAINT_SCHEDULED, + + LAST_SIGNAL, +}; + +static guint signals[LAST_SIGNAL]; gboolean meta_surface_actor_get_unobscured_bounds (MetaSurfaceActor *self, @@ -114,6 +122,13 @@ meta_surface_actor_class_init (MetaSurfaceActorClass *klass) object_class->dispose = meta_surface_actor_dispose; actor_class->pick = meta_surface_actor_pick; + signals[REPAINT_SCHEDULED] = g_signal_new ("repaint-scheduled", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); + g_type_class_add_private (klass, sizeof (MetaSurfaceActorPrivate)); } @@ -164,51 +179,14 @@ meta_surface_actor_get_texture (MetaSurfaceActor *self) return self->priv->texture; } -static void -update_area (MetaSurfaceActor *self, - int x, int y, int width, int height) +void +meta_surface_actor_update_area (MetaSurfaceActor *self, + int x, int y, int width, int height) { MetaSurfaceActorPrivate *priv = self->priv; - if (meta_is_wayland_compositor ()) - { - struct wl_resource *resource = priv->buffer->resource; - struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get (resource); - - if (shm_buffer) - { - CoglTexture2D *texture = COGL_TEXTURE_2D (priv->buffer->texture); - cogl_wayland_texture_set_region_from_shm_buffer (texture, x, y, width, height, shm_buffer, x, y, 0, NULL); - } - } - else - { - CoglTexturePixmapX11 *texture = COGL_TEXTURE_PIXMAP_X11 (meta_shaped_texture_get_texture (priv->texture)); - cogl_texture_pixmap_x11_update_area (texture, x, y, width, height); - } -} - -gboolean -meta_surface_actor_damage_all (MetaSurfaceActor *self) -{ - MetaSurfaceActorPrivate *priv = self->priv; - CoglTexture *texture = meta_shaped_texture_get_texture (priv->texture); - - update_area (self, 0, 0, cogl_texture_get_width (texture), cogl_texture_get_height (texture)); - return meta_shaped_texture_update_area (priv->texture, 0, 0, cogl_texture_get_width (texture), cogl_texture_get_height (texture)); -} - -gboolean -meta_surface_actor_damage_area (MetaSurfaceActor *self, - int x, - int y, - int width, - int height) -{ - MetaSurfaceActorPrivate *priv = self->priv; - - update_area (self, x, y, width, height); - return meta_shaped_texture_update_area (priv->texture, x, y, width, height); + if (meta_shaped_texture_update_area (priv->texture, x, y, width, height)) + g_signal_emit (self, signals[REPAINT_SCHEDULED], 0); } gboolean @@ -218,27 +196,6 @@ meta_surface_actor_is_obscured (MetaSurfaceActor *self) return meta_shaped_texture_is_obscured (priv->texture); } -void -meta_surface_actor_attach_wayland_buffer (MetaSurfaceActor *self, - MetaWaylandBuffer *buffer) -{ - MetaSurfaceActorPrivate *priv = self->priv; - priv->buffer = buffer; - - if (buffer) - meta_shaped_texture_set_texture (priv->texture, buffer->texture); - else - meta_shaped_texture_set_texture (priv->texture, NULL); -} - -void -meta_surface_actor_set_texture (MetaSurfaceActor *self, - CoglTexture *texture) -{ - MetaSurfaceActorPrivate *priv = self->priv; - meta_shaped_texture_set_texture (priv->texture, texture); -} - void meta_surface_actor_set_input_region (MetaSurfaceActor *self, cairo_region_t *region) @@ -262,20 +219,114 @@ meta_surface_actor_set_opaque_region (MetaSurfaceActor *self, meta_shaped_texture_set_opaque_region (priv->texture, region); } -MetaWaylandSurface * -meta_surface_actor_get_surface (MetaSurfaceActor *self) +static gboolean +is_frozen (MetaSurfaceActor *self) { MetaSurfaceActorPrivate *priv = self->priv; - return priv->surface; + return (priv->freeze_count > 0); } -MetaSurfaceActor * -meta_surface_actor_new (MetaWaylandSurface *surface) +void +meta_surface_actor_process_damage (MetaSurfaceActor *self, + int x, int y, int width, int height) { - MetaSurfaceActor *self = g_object_new (META_TYPE_SURFACE_ACTOR, NULL); MetaSurfaceActorPrivate *priv = self->priv; - priv->surface = surface; + if (is_frozen (self)) + { + /* The window is frozen due to an effect in progress: we ignore damage + * here on the off chance that this will stop the corresponding + * texture_from_pixmap from being update. + * + * needs_damage_all tracks that some unknown damage happened while the + * window was frozen so that when the window becomes unfrozen we can + * issue a full window update to cover any lost damage. + * + * It should be noted that this is an unreliable mechanism since it's + * quite likely that drivers will aim to provide a zero-copy + * implementation of the texture_from_pixmap extension and in those cases + * any drawing done to the window is always immediately reflected in the + * texture regardless of damage event handling. + */ + priv->needs_damage_all = TRUE; + return; + } - return self; + META_SURFACE_ACTOR_GET_CLASS (self)->process_damage (self, x, y, width, height); +} + +void +meta_surface_actor_pre_paint (MetaSurfaceActor *self) +{ + META_SURFACE_ACTOR_GET_CLASS (self)->pre_paint (self); +} + +gboolean +meta_surface_actor_is_argb32 (MetaSurfaceActor *self) +{ + return META_SURFACE_ACTOR_GET_CLASS (self)->is_argb32 (self); +} + +gboolean +meta_surface_actor_is_visible (MetaSurfaceActor *self) +{ + return META_SURFACE_ACTOR_GET_CLASS (self)->is_visible (self); +} + +void +meta_surface_actor_freeze (MetaSurfaceActor *self) +{ + MetaSurfaceActorPrivate *priv = self->priv; + + priv->freeze_count ++; +} + +void +meta_surface_actor_thaw (MetaSurfaceActor *self) +{ + MetaSurfaceActorPrivate *priv = self->priv; + + if (priv->freeze_count == 0) + { + g_critical ("Error in freeze/thaw accounting."); + return; + } + + priv->freeze_count --; + + /* Since we ignore damage events while a window is frozen for certain effects + * we may need to issue an update_area() covering the whole pixmap if we + * don't know what real damage has happened. */ + if (priv->needs_damage_all) + { + meta_surface_actor_process_damage (self, 0, 0, + clutter_actor_get_width (CLUTTER_ACTOR (priv->texture)), + clutter_actor_get_height (CLUTTER_ACTOR (priv->texture))); + priv->needs_damage_all = FALSE; + } +} + +gboolean +meta_surface_actor_is_frozen (MetaSurfaceActor *self) +{ + return is_frozen (self); +} + +gboolean +meta_surface_actor_should_unredirect (MetaSurfaceActor *self) +{ + return META_SURFACE_ACTOR_GET_CLASS (self)->should_unredirect (self); +} + +void +meta_surface_actor_set_unredirected (MetaSurfaceActor *self, + gboolean unredirected) +{ + META_SURFACE_ACTOR_GET_CLASS (self)->set_unredirected (self, unredirected); +} + +gboolean +meta_surface_actor_is_unredirected (MetaSurfaceActor *self) +{ + return META_SURFACE_ACTOR_GET_CLASS (self)->is_unredirected (self); } diff --git a/src/compositor/meta-surface-actor.h b/src/compositor/meta-surface-actor.h index e42deb42f..763f91d72 100644 --- a/src/compositor/meta-surface-actor.h +++ b/src/compositor/meta-surface-actor.h @@ -6,7 +6,6 @@ #include #include -#include "meta-wayland-types.h" G_BEGIN_DECLS @@ -25,6 +24,17 @@ struct _MetaSurfaceActorClass { /*< private >*/ ClutterActorClass parent_class; + + void (* process_damage) (MetaSurfaceActor *actor, + int x, int y, int width, int height); + void (* pre_paint) (MetaSurfaceActor *actor); + gboolean (* is_argb32) (MetaSurfaceActor *actor); + gboolean (* is_visible) (MetaSurfaceActor *actor); + + gboolean (* should_unredirect) (MetaSurfaceActor *actor); + void (* set_unredirected) (MetaSurfaceActor *actor, + gboolean unredirected); + gboolean (* is_unredirected) (MetaSurfaceActor *actor); }; struct _MetaSurfaceActor @@ -36,34 +46,37 @@ struct _MetaSurfaceActor GType meta_surface_actor_get_type (void); -MetaSurfaceActor *meta_surface_actor_new (MetaWaylandSurface *surface); - cairo_surface_t *meta_surface_actor_get_image (MetaSurfaceActor *self, cairo_rectangle_int_t *clip); MetaShapedTexture *meta_surface_actor_get_texture (MetaSurfaceActor *self); -gboolean meta_surface_actor_damage_all (MetaSurfaceActor *self); -gboolean meta_surface_actor_damage_area (MetaSurfaceActor *self, - int x, - int y, - int width, - int height); - gboolean meta_surface_actor_is_obscured (MetaSurfaceActor *self); gboolean meta_surface_actor_get_unobscured_bounds (MetaSurfaceActor *self, cairo_rectangle_int_t *unobscured_bounds); -void meta_surface_actor_set_texture (MetaSurfaceActor *self, - CoglTexture *texture); -void meta_surface_actor_attach_wayland_buffer (MetaSurfaceActor *self, - MetaWaylandBuffer *buffer); void meta_surface_actor_set_input_region (MetaSurfaceActor *self, cairo_region_t *region); void meta_surface_actor_set_opaque_region (MetaSurfaceActor *self, cairo_region_t *region); -MetaWaylandSurface *meta_surface_actor_get_surface (MetaSurfaceActor *surface); +void meta_surface_actor_update_area (MetaSurfaceActor *actor, + int x, int y, int width, int height); + +void meta_surface_actor_process_damage (MetaSurfaceActor *actor, + int x, int y, int width, int height); +void meta_surface_actor_pre_paint (MetaSurfaceActor *actor); +gboolean meta_surface_actor_is_argb32 (MetaSurfaceActor *actor); +gboolean meta_surface_actor_is_visible (MetaSurfaceActor *actor); + +void meta_surface_actor_freeze (MetaSurfaceActor *actor); +void meta_surface_actor_thaw (MetaSurfaceActor *actor); +gboolean meta_surface_actor_is_frozen (MetaSurfaceActor *actor); + +gboolean meta_surface_actor_should_unredirect (MetaSurfaceActor *actor); +void meta_surface_actor_set_unredirected (MetaSurfaceActor *actor, + gboolean unredirected); +gboolean meta_surface_actor_is_unredirected (MetaSurfaceActor *actor); G_END_DECLS diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index d0e57d3d2..597a2096a 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -10,10 +10,6 @@ #include -#include -#include -#include - #include #include #include /* for gdk_rectangle_union() */ @@ -30,13 +26,15 @@ #include "meta-shaped-texture-private.h" #include "meta-shadow-factory-private.h" #include "meta-window-actor-private.h" -#include "meta-surface-actor.h" #include "meta-texture-rectangle.h" #include "region-utils.h" #include "meta-wayland-private.h" #include "monitor-private.h" #include "meta-cullable.h" +#include "meta-surface-actor.h" +#include "meta-surface-actor-x11.h" + struct _MetaWindowActorPrivate { MetaWindow *window; @@ -63,19 +61,13 @@ struct _MetaWindowActorPrivate /* The region we should clip to when painting the shadow */ cairo_region_t *shadow_clip; - guint send_frame_messages_timer; - gint64 frame_drawn_time; - /* Extracted size-invariant shape used for shadows */ MetaWindowShape *shadow_shape; - - gint last_width; - gint last_height; - - gint freeze_count; - char * shadow_class; + guint send_frame_messages_timer; + gint64 frame_drawn_time; + /* * These need to be counters rather than flags, since more plugins * can implement same effect; the practicality of stacking effects @@ -90,11 +82,7 @@ struct _MetaWindowActorPrivate /* List of FrameData for recent frames */ GList *frames; - Pixmap back_pixmap; /* Not used in wayland compositor mode */ - Damage damage; /* Not used in wayland compositor mode */ - guint visible : 1; - guint argb32 : 1; guint disposed : 1; guint redecorating : 1; @@ -111,22 +99,7 @@ struct _MetaWindowActorPrivate guint no_shadow : 1; - - /* - * None of these are used in wayland compositor mode... - */ - - guint needs_damage_all : 1; - guint received_x11_damage : 1; - - guint x11_size_changed : 1; guint updates_frozen : 1; - - guint unredirected : 1; - - /* This is used to detect fullscreen windows that need to be unredirected */ - guint full_damage_frames_count; - guint does_full_damage : 1; }; typedef struct _FrameData FrameData; @@ -163,7 +136,6 @@ static gboolean meta_window_actor_get_paint_volume (ClutterActor *actor, ClutterPaintVolume *volume); -static void meta_window_actor_detach_x11_pixmap (MetaWindowActor *self); static gboolean meta_window_actor_has_shadow (MetaWindowActor *self); static void meta_window_actor_handle_updates (MetaWindowActor *self); @@ -254,9 +226,6 @@ window_decorated_notify (MetaWindow *mw, { MetaWindowActor *self = META_WINDOW_ACTOR (data); MetaWindowActorPrivate *priv = self->priv; - MetaScreen *screen = priv->screen; - MetaDisplay *display = meta_screen_get_display (screen); - Display *xdisplay = meta_display_get_xdisplay (display); /* * Basically, we have to reconstruct the the internals of this object @@ -264,23 +233,6 @@ window_decorated_notify (MetaWindow *mw, */ priv->redecorating = TRUE; - if (!meta_is_wayland_compositor ()) - { - meta_window_actor_detach_x11_pixmap (self); - - /* - * First of all, clean up any resources we are currently using and will - * be replacing. - */ - if (priv->damage != None) - { - meta_error_trap_push (display); - XDamageDestroy (xdisplay, priv->damage); - meta_error_trap_pop (display); - priv->damage = None; - } - } - /* * Recreate the contents. */ @@ -305,13 +257,62 @@ surface_allocation_changed_notify (ClutterActor *actor, meta_window_actor_update_shape (self); } +static void +surface_repaint_scheduled (MetaSurfaceActor *actor, + gpointer user_data) +{ + MetaWindowActor *self = META_WINDOW_ACTOR (user_data); + MetaWindowActorPrivate *priv = self->priv; + + priv->repaint_scheduled = TRUE; +} + +static gboolean +is_argb32 (MetaWindowActor *self) +{ + MetaWindowActorPrivate *priv = self->priv; + return meta_surface_actor_is_argb32 (priv->surface); +} + static gboolean is_non_opaque (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; MetaWindow *window = priv->window; - return priv->argb32 || (window->opacity != 0xFF); + return is_argb32 (self) || (window->opacity != 0xFF); +} + +static gboolean +is_frozen (MetaWindowActor *self) +{ + MetaWindowActorPrivate *priv = self->priv; + return meta_surface_actor_is_frozen (priv->surface); +} + +static void +meta_window_actor_freeze (MetaWindowActor *self) +{ + MetaWindowActorPrivate *priv = self->priv; + meta_surface_actor_freeze (priv->surface); +} + +static void +meta_window_actor_thaw (MetaWindowActor *self) +{ + MetaWindowActorPrivate *priv = self->priv; + + meta_surface_actor_thaw (priv->surface); + + if (is_frozen (self)) + return; + + /* We sometimes ignore moves and resizes on frozen windows */ + meta_window_actor_sync_actor_geometry (self, FALSE); + + /* We do this now since we might be going right back into the + * frozen state */ + meta_window_actor_handle_updates (self); } static void @@ -320,42 +321,21 @@ meta_window_actor_constructed (GObject *object) MetaWindowActor *self = META_WINDOW_ACTOR (object); MetaWindowActorPrivate *priv = self->priv; MetaWindow *window = priv->window; - Window xwindow = meta_window_get_toplevel_xwindow (window); - MetaScreen *screen = meta_window_get_screen (window); - MetaDisplay *display = meta_screen_get_display (screen); - Display *xdisplay = meta_display_get_xdisplay (display); - priv->screen = screen; - - if (!meta_is_wayland_compositor ()) - priv->damage = XDamageCreate (xdisplay, xwindow, - XDamageReportBoundingBox); - - if (window->client_type == META_WINDOW_CLIENT_TYPE_X11) - { - XRenderPictFormat *format; - - format = XRenderFindVisualFormat (xdisplay, window->xvisual); - - if (format && format->type == PictTypeDirect && format->direct.alphaMask) - priv->argb32 = TRUE; - } - else - { - /* XXX: parse shm formats to determine argb32 */ - priv->argb32 = TRUE; - } + priv->screen = window->screen; if (!priv->surface) { if (window->surface) priv->surface = window->surface->surface_actor; else - priv->surface = meta_surface_actor_new (NULL); + priv->surface = meta_surface_actor_x11_new (window); g_object_ref_sink (priv->surface); clutter_actor_add_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface)); + g_signal_connect_object (priv->surface, "repaint-scheduled", + G_CALLBACK (surface_repaint_scheduled), self, 0); g_signal_connect_object (priv->surface, "allocation-changed", G_CALLBACK (surface_allocation_changed_notify), self, 0); meta_window_actor_update_shape (self); @@ -374,8 +354,6 @@ meta_window_actor_dispose (GObject *object) MetaWindowActor *self = META_WINDOW_ACTOR (object); MetaWindowActorPrivate *priv = self->priv; MetaScreen *screen; - MetaDisplay *display; - Display *xdisplay; MetaCompScreen *info; if (priv->disposed) @@ -386,9 +364,6 @@ meta_window_actor_dispose (GObject *object) screen = priv->screen; info = meta_screen_get_compositor_data (screen); - if (!meta_is_wayland_compositor ()) - meta_window_actor_detach_x11_pixmap (self); - if (priv->send_frame_messages_timer != 0) { g_source_remove (priv->send_frame_messages_timer); @@ -403,18 +378,6 @@ meta_window_actor_dispose (GObject *object) g_clear_pointer (&priv->unfocused_shadow, meta_shadow_unref); g_clear_pointer (&priv->shadow_shape, meta_window_shape_unref); - if (!meta_is_wayland_compositor () && priv->damage != None) - { - display = meta_screen_get_display (screen); - xdisplay = meta_display_get_xdisplay (display); - - meta_error_trap_push (display); - XDamageDestroy (xdisplay, priv->damage); - meta_error_trap_pop (display); - - priv->damage = None; - } - info->windows = g_list_remove (info->windows, (gconstpointer) self); g_clear_object (&priv->window); @@ -825,13 +788,6 @@ meta_window_actor_is_destroyed (MetaWindowActor *self) return self->priv->disposed; } -static void -meta_window_actor_freeze (MetaWindowActor *self) -{ - if (!meta_is_wayland_compositor ()) - self->priv->freeze_count++; -} - static gboolean send_frame_messages_timeout (gpointer data) { @@ -886,55 +842,6 @@ queue_send_frame_messages_timeout (MetaWindowActor *self) priv->send_frame_messages_timer = g_timeout_add_full (META_PRIORITY_REDRAW, offset, send_frame_messages_timeout, self, NULL); } -static void -meta_window_actor_damage_all (MetaWindowActor *self) -{ - MetaWindowActorPrivate *priv = self->priv; - gboolean redraw_queued; - - if (!priv->needs_damage_all) - return; - - if (priv->back_pixmap == None) - return; - - redraw_queued = meta_surface_actor_damage_all (priv->surface); - priv->repaint_scheduled = priv->repaint_scheduled || redraw_queued; - priv->needs_damage_all = FALSE; -} - -static void -meta_window_actor_thaw (MetaWindowActor *self) -{ - if (!meta_is_wayland_compositor ()) - { - self->priv->freeze_count--; - - if (G_UNLIKELY (self->priv->freeze_count < 0)) - { - g_warning ("Error in freeze/thaw accounting."); - self->priv->freeze_count = 0; - return; - } - - if (self->priv->freeze_count) - return; - - /* We sometimes ignore moves and resizes on frozen windows */ - meta_window_actor_sync_actor_geometry (self, FALSE); - - /* We do this now since we might be going right back into the - * frozen state */ - meta_window_actor_handle_updates (self); - - /* Since we ignore damage events while a window is frozen for certain effects - * we may need to issue an update_area() covering the whole pixmap if we - * don't know what real damage has happened. */ - if (self->priv->needs_damage_all) - meta_window_actor_damage_all (self); - } -} - void meta_window_actor_queue_frame_drawn (MetaWindowActor *self, gboolean no_delay_frame) @@ -989,12 +896,6 @@ meta_window_actor_effect_in_progress (MetaWindowActor *self) self->priv->destroy_in_progress); } -static gboolean -is_frozen (MetaWindowActor *self) -{ - return self->priv->freeze_count ? TRUE : FALSE; -} - static gboolean is_freeze_thaw_effect (gulong event) { @@ -1075,12 +976,6 @@ meta_window_actor_after_effects (MetaWindowActor *self) meta_window_actor_sync_visibility (self); meta_window_actor_sync_actor_geometry (self, FALSE); - - if (!meta_is_wayland_compositor ()) - { - if (priv->back_pixmap == None) - clutter_actor_queue_redraw (CLUTTER_ACTOR (priv->surface)); - } } void @@ -1155,93 +1050,19 @@ meta_window_actor_effect_completed (MetaWindowActor *self, meta_window_actor_after_effects (self); } -/* Called to drop our reference to a window backing pixmap that we - * previously obtained with XCompositeNameWindowPixmap. We do this - * when the window is unmapped or when we want to update to a new - * pixmap for a new size. - */ -static void -meta_window_actor_detach_x11_pixmap (MetaWindowActor *self) -{ - MetaWindowActorPrivate *priv = self->priv; - MetaScreen *screen = priv->screen; - MetaDisplay *display = meta_screen_get_display (screen); - Display *xdisplay = meta_display_get_xdisplay (display); - - if (!priv->back_pixmap) - return; - - /* Get rid of all references to the pixmap before freeing it; it's unclear whether - * you are supposed to be able to free a GLXPixmap after freeing the underlying - * pixmap, but it certainly doesn't work with current DRI/Mesa - */ - meta_surface_actor_set_texture (priv->surface, NULL); - cogl_flush(); - - XFreePixmap (xdisplay, priv->back_pixmap); - priv->back_pixmap = None; -} - gboolean meta_window_actor_should_unredirect (MetaWindowActor *self) { - MetaWindow *metaWindow = meta_window_actor_get_meta_window (self); MetaWindowActorPrivate *priv = self->priv; - - if (meta_is_wayland_compositor ()) - return FALSE; - - if (meta_window_requested_dont_bypass_compositor (metaWindow)) - return FALSE; - - if (metaWindow->opacity != 0xFF) - return FALSE; - - if (metaWindow->shape_region != NULL) - return FALSE; - - if (priv->argb32 && !meta_window_requested_bypass_compositor (metaWindow)) - return FALSE; - - if (!meta_window_is_monitor_sized (metaWindow)) - return FALSE; - - if (meta_window_requested_bypass_compositor (metaWindow)) - return TRUE; - - if (meta_window_is_override_redirect (metaWindow)) - return TRUE; - - if (priv->does_full_damage) - return TRUE; - - return FALSE; + return meta_surface_actor_should_unredirect (priv->surface); } void meta_window_actor_set_unredirected (MetaWindowActor *self, gboolean unredirected) { - MetaWindow *metaWindow = meta_window_actor_get_meta_window (self); - MetaDisplay *display = meta_window_get_display (metaWindow); - - Display *xdisplay = meta_display_get_xdisplay (display); - Window xwin = meta_window_get_toplevel_xwindow (metaWindow); - - meta_error_trap_push (display); - - if (unredirected) - { - XCompositeUnredirectWindow (xdisplay, xwin, CompositeRedirectManual); - } - else - { - XCompositeRedirectWindow (xdisplay, xwin, CompositeRedirectManual); - meta_window_actor_detach_x11_pixmap (self); - } - - self->priv->unredirected = unredirected; - meta_error_trap_pop (display); + MetaWindowActorPrivate *priv = self->priv; + meta_surface_actor_set_unredirected (priv->surface, unredirected); } void @@ -1301,19 +1122,11 @@ meta_window_actor_sync_actor_geometry (MetaWindowActor *self, meta_window_get_input_rect (priv->window, &window_rect); - /* When running as a display server we catch size changes when new - buffers are attached */ - if (!meta_is_wayland_compositor ()) - { - if (priv->last_width != window_rect.width || - priv->last_height != window_rect.height) - { - priv->x11_size_changed = TRUE; - - priv->last_width = window_rect.width; - priv->last_height = window_rect.height; - } - } + /* When running as a Wayland compositor we catch size changes when new + * buffers are attached */ + if (META_IS_SURFACE_ACTOR_X11 (priv->surface)) + meta_surface_actor_x11_set_size (META_SURFACE_ACTOR_X11 (priv->surface), + window_rect.width, window_rect.height); /* Normally we want freezing a window to also freeze its position; this allows * windows to atomically move and resize together, either under app control, @@ -1325,15 +1138,6 @@ meta_window_actor_sync_actor_geometry (MetaWindowActor *self, if (is_frozen (self) && !did_placement) return; - if (!meta_is_wayland_compositor ()) - { - if (priv->x11_size_changed) - { - meta_window_actor_detach_x11_pixmap (self); - meta_window_actor_update_shape (self); - } - } - if (meta_window_actor_effect_in_progress (self)) return; @@ -1500,20 +1304,13 @@ meta_window_actor_new (MetaWindow *window) priv = self->priv; - if (!meta_is_wayland_compositor ()) - { - priv->last_width = -1; - priv->last_height = -1; + meta_window_actor_set_updates_frozen (self, meta_window_updates_are_frozen (priv->window)); - meta_window_actor_set_updates_frozen (self, - meta_window_updates_are_frozen (priv->window)); - - /* If a window doesn't start off with updates frozen, we should - * we should send a _NET_WM_FRAME_DRAWN immediately after the first drawn. - */ - if (priv->window->extended_sync_request_counter && !priv->updates_frozen) - meta_window_actor_queue_frame_drawn (self, FALSE); - } + /* If a window doesn't start off with updates frozen, we should + * we should send a _NET_WM_FRAME_DRAWN immediately after the first drawn. + */ + if (priv->window->extended_sync_request_counter && !priv->updates_frozen) + meta_window_actor_queue_frame_drawn (self, FALSE); meta_window_actor_sync_actor_geometry (self, priv->window->placed); @@ -1622,13 +1419,6 @@ meta_window_actor_cull_out (MetaCullable *cullable, cairo_region_t *clip_region) { MetaWindowActor *self = META_WINDOW_ACTOR (cullable); - MetaWindowActorPrivate *priv = self->priv; - - meta_cullable_cull_out_children (cullable, unobscured_region, clip_region); - - /* Don't do any culling for the unredirected window */ - if (priv->unredirected) - return; meta_window_actor_set_clip_region_beneath (self, clip_region); } @@ -1651,65 +1441,6 @@ cullable_iface_init (MetaCullableInterface *iface) iface->reset_culling = meta_window_actor_reset_culling; } -/* When running as a wayland compositor we don't make requests for - * replacement pixmaps when resizing windows, we will instead be - * asked to attach replacement buffers by the clients. */ -static void -check_needs_x11_pixmap (MetaWindowActor *self) -{ - MetaWindowActorPrivate *priv = self->priv; - MetaDisplay *display = meta_screen_get_display (priv->screen); - Display *xdisplay = meta_display_get_xdisplay (display); - Window xwindow = meta_window_get_toplevel_xwindow (priv->window); - - /* If the size changed while we were frozen, the old pixmap - * will still be attached, and we need to create a new one. */ - if (priv->x11_size_changed) - { - meta_window_actor_detach_x11_pixmap (self); - priv->x11_size_changed = FALSE; - } - - meta_error_trap_push (display); - - if (priv->back_pixmap == None) - { - CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ()); - CoglTexture *texture; - - meta_error_trap_push (display); - - priv->back_pixmap = XCompositeNameWindowPixmap (xdisplay, xwindow); - - if (meta_error_trap_pop_with_return (display) != Success) - { - /* Probably a BadMatch if the window isn't viewable; we could - * GrabServer/GetWindowAttributes/NameWindowPixmap/UngrabServer/Sync - * to avoid this, but there's no reason to take two round trips - * when one will do. (We need that Sync if we want to handle failures - * for any reason other than !viewable. That's unlikely, but maybe - * we'll BadAlloc or something.) - */ - priv->back_pixmap = None; - } - - if (priv->back_pixmap == None) - { - meta_verbose ("Unable to get named pixmap for %p\n", self); - goto out; - } - - texture = COGL_TEXTURE (cogl_texture_pixmap_x11_new (ctx, priv->back_pixmap, FALSE, NULL)); - if (G_UNLIKELY (!cogl_texture_pixmap_x11_is_using_tfp_extension (COGL_TEXTURE_PIXMAP_X11 (texture)))) - g_warning ("NOTE: Not using GLX TFP!\n"); - - meta_surface_actor_set_texture (META_SURFACE_ACTOR (priv->surface), texture); - } - - out: - meta_error_trap_pop (display); -} - static void check_needs_shadow (MetaWindowActor *self) { @@ -1777,61 +1508,12 @@ meta_window_actor_process_x11_damage (MetaWindowActor *self, XDamageNotifyEvent *event) { MetaWindowActorPrivate *priv = self->priv; - MetaCompScreen *info = meta_screen_get_compositor_data (priv->screen); - gboolean redraw_queued; - priv->received_x11_damage = TRUE; - - if (meta_window_is_fullscreen (priv->window) && g_list_last (info->windows)->data == self && !priv->unredirected) - { - MetaRectangle window_rect; - meta_window_get_frame_rect (priv->window, &window_rect); - - if (window_rect.x == event->area.x && - window_rect.y == event->area.y && - window_rect.width == event->area.width && - window_rect.height == event->area.height) - priv->full_damage_frames_count++; - else - priv->full_damage_frames_count = 0; - - if (priv->full_damage_frames_count >= 100) - priv->does_full_damage = TRUE; - } - - /* Drop damage event for unredirected windows */ - if (priv->unredirected) - return; - - if (is_frozen (self)) - { - /* The window is frozen due to an effect in progress: we ignore damage - * here on the off chance that this will stop the corresponding - * texture_from_pixmap from being update. - * - * needs_damage_all tracks that some unknown damage happened while the - * window was frozen so that when the window becomes unfrozen we can - * issue a full window update to cover any lost damage. - * - * It should be noted that this is an unreliable mechanism since it's - * quite likely that drivers will aim to provide a zero-copy - * implementation of the texture_from_pixmap extension and in those cases - * any drawing done to the window is always immediately reflected in the - * texture regardless of damage event handling. - */ - priv->needs_damage_all = TRUE; - return; - } - - if (priv->back_pixmap == None) - return; - - redraw_queued = meta_surface_actor_damage_area (priv->surface, - event->area.x, - event->area.y, - event->area.width, - event->area.height); - priv->repaint_scheduled = priv->repaint_scheduled || redraw_queued; + meta_surface_actor_process_damage (priv->surface, + event->area.x, + event->area.y, + event->area.width, + event->area.height); } void @@ -2059,8 +1741,9 @@ meta_window_actor_update_opaque_region (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; cairo_region_t *opaque_region; + gboolean argb32 = is_argb32 (self); - if (priv->argb32 && priv->window->opaque_region != NULL) + if (argb32 && priv->window->opaque_region != NULL) { MetaFrameBorders borders; @@ -2080,7 +1763,7 @@ meta_window_actor_update_opaque_region (MetaWindowActor *self) cairo_region_translate (opaque_region, borders.total.left, borders.total.top); cairo_region_intersect (opaque_region, priv->shape_region); } - else if (priv->argb32) + else if (argb32) opaque_region = NULL; else opaque_region = cairo_region_reference (priv->shape_region); @@ -2137,9 +1820,6 @@ static void meta_window_actor_handle_updates (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; - MetaScreen *screen = priv->screen; - MetaDisplay *display = meta_screen_get_display (screen); - Display *xdisplay = meta_display_get_xdisplay (display); if (is_frozen (self)) { @@ -2148,45 +1828,13 @@ meta_window_actor_handle_updates (MetaWindowActor *self) return; } - if (!meta_is_wayland_compositor ()) - { - if (priv->unredirected) - { - /* Nothing to do here until/if the window gets redirected again */ - return; - } + if (meta_surface_actor_is_unredirected (priv->surface)) + return; - if (priv->received_x11_damage) - { - meta_error_trap_push (display); - XDamageSubtract (xdisplay, priv->damage, None, None); - meta_error_trap_pop (display); + meta_surface_actor_pre_paint (priv->surface); - /* We need to make sure that any X drawing that happens before the - * XDamageSubtract() 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. - * - * Xorg and open source driver specifics: - * - * The X server makes sure to flush drawing to the kernel before - * sending out damage events, but since we use DamageReportBoundingBox - * there may be drawing between the last damage event and the - * XDamageSubtract() that needs to be flushed as well. - * - * Xorg always makes sure that drawing is flushed to the kernel - * before writing events or responses to the client, so any round trip - * request at this point is sufficient to flush the GLX buffers. - */ - XSync (xdisplay, False); - - priv->received_x11_damage = FALSE; - } - - check_needs_x11_pixmap (self); - } + if (!meta_surface_actor_is_visible (priv->surface)) + return; check_needs_reshape (self); check_needs_shadow (self); @@ -2375,20 +2023,16 @@ void meta_window_actor_set_updates_frozen (MetaWindowActor *self, gboolean updates_frozen) { - /* On wayland we shouldn't need to ever freeze updates... */ - if (!meta_is_wayland_compositor ()) + MetaWindowActorPrivate *priv = self->priv; + + updates_frozen = updates_frozen != FALSE; + + if (priv->updates_frozen != updates_frozen) { - MetaWindowActorPrivate *priv = self->priv; - - updates_frozen = updates_frozen != FALSE; - - if (priv->updates_frozen != updates_frozen) - { - priv->updates_frozen = updates_frozen; - if (updates_frozen) - meta_window_actor_freeze (self); - else - meta_window_actor_thaw (self); - } + priv->updates_frozen = updates_frozen; + if (updates_frozen) + meta_window_actor_freeze (self); + else + meta_window_actor_thaw (self); } } diff --git a/src/core/display.c b/src/core/display.c index 907f1a597..d3a03bd77 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -73,6 +73,7 @@ #include #include "meta-xwayland-private.h" +#include "meta-surface-actor-wayland.h" #define GRAB_OP_IS_WINDOW_SWITCH(g) \ (g == META_GRAB_OP_KEYBOARD_TABBING_NORMAL || \ @@ -1682,9 +1683,9 @@ get_window_for_event (MetaDisplay *display, return display->grab_window; source = clutter_event_get_source (event); - if (META_IS_SURFACE_ACTOR (source)) + if (META_IS_SURFACE_ACTOR_WAYLAND (source)) { - MetaWaylandSurface *surface = meta_surface_actor_get_surface (META_SURFACE_ACTOR (source)); + MetaWaylandSurface *surface = meta_surface_actor_wayland_get_surface (META_SURFACE_ACTOR_WAYLAND (source)); g_assert (surface != NULL); return surface->window; } diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c index df8e7814f..d73072925 100644 --- a/src/wayland/meta-wayland-seat.c +++ b/src/wayland/meta-wayland-seat.c @@ -38,6 +38,7 @@ #include "meta-shaped-texture-private.h" #include "meta-wayland-stage.h" #include "meta-cursor-tracker-private.h" +#include "meta-surface-actor-wayland.h" #define DEFAULT_AXIS_STEP_DISTANCE wl_fixed_from_int (10) @@ -420,8 +421,8 @@ meta_wayland_seat_repick (MetaWaylandSeat *seat, else seat->current_stage = NULL; - if (META_IS_SURFACE_ACTOR (actor)) - surface = meta_surface_actor_get_surface (META_SURFACE_ACTOR (actor)); + if (META_IS_SURFACE_ACTOR_WAYLAND (actor)) + surface = meta_surface_actor_wayland_get_surface (META_SURFACE_ACTOR_WAYLAND (actor)); pointer->current = surface; if (surface != pointer->focus_surface) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 7d9257367..0783316fe 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -44,11 +44,11 @@ #include "meta-wayland-private.h" #include "meta-xwayland-private.h" #include "meta-wayland-stage.h" -#include "meta-surface-actor.h" #include "meta-wayland-seat.h" #include "meta-wayland-keyboard.h" #include "meta-wayland-pointer.h" #include "meta-wayland-data-device.h" + #include "meta-cursor-tracker-private.h" #include "display-private.h" #include "window-private.h" @@ -58,6 +58,9 @@ #include "meta-idle-monitor-private.h" #include "monitor-private.h" +#include "meta-surface-actor.h" +#include "meta-surface-actor-wayland.h" + typedef enum { META_WAYLAND_SUBSURFACE_PLACEMENT_ABOVE, @@ -114,8 +117,8 @@ surface_process_damage (MetaWaylandSurface *surface, { cairo_rectangle_int_t rect; cairo_region_get_rectangle (region, i, &rect); - meta_surface_actor_damage_area (surface->surface_actor, - rect.x, rect.y, rect.width, rect.height); + meta_surface_actor_process_damage (surface->surface_actor, + rect.x, rect.y, rect.width, rect.height); } } @@ -295,7 +298,7 @@ actor_surface_commit (MetaWaylandSurface *surface, if (buffer_changed) { ensure_buffer_texture (buffer); - meta_surface_actor_attach_wayland_buffer (surface_actor, buffer); + meta_surface_actor_wayland_set_buffer (META_SURFACE_ACTOR_WAYLAND (surface->surface_actor), buffer); } surface_process_damage (surface, pending->damage); @@ -645,7 +648,7 @@ meta_wayland_surface_create (MetaWaylandCompositor *compositor, wl_resource_set_implementation (surface->resource, &meta_wayland_surface_interface, surface, wl_surface_destructor); surface->buffer_destroy_listener.notify = surface_handle_buffer_destroy; - surface->surface_actor = g_object_ref_sink (meta_surface_actor_new (surface)); + surface->surface_actor = g_object_ref_sink (meta_surface_actor_wayland_new (surface)); clutter_actor_set_reactive (CLUTTER_ACTOR (surface->surface_actor), TRUE); double_buffered_state_init (&surface->pending); From 020cfa7283c0d8ba9e9ee7b241f1b10600cdfa48 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 20 Feb 2014 14:49:22 -0500 Subject: [PATCH 543/889] surface-actor-x11: Recreate damage when the toplevel X window changes --- src/compositor/meta-surface-actor-x11.c | 28 ++++++++++++++++++++++--- src/compositor/meta-window-actor.c | 28 +------------------------ 2 files changed, 26 insertions(+), 30 deletions(-) diff --git a/src/compositor/meta-surface-actor-x11.c b/src/compositor/meta-surface-actor-x11.c index 3eea2c31b..020c84734 100644 --- a/src/compositor/meta-surface-actor-x11.c +++ b/src/compositor/meta-surface-actor-x11.c @@ -414,21 +414,43 @@ meta_surface_actor_x11_init (MetaSurfaceActorX11 *self) priv->last_height = -1; } +static void +create_damage (MetaSurfaceActorX11 *self) +{ + MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); + Display *xdisplay = meta_display_get_xdisplay (priv->display); + Window xwindow = meta_window_get_toplevel_xwindow (priv->window); + + priv->damage = XDamageCreate (xdisplay, xwindow, XDamageReportBoundingBox); +} + +static void +window_decorated_notify (MetaWindow *window, + GParamSpec *pspec, + gpointer user_data) +{ + MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (user_data); + + free_damage (self); + create_damage (self); +} + MetaSurfaceActor * meta_surface_actor_x11_new (MetaWindow *window) { MetaSurfaceActorX11 *self = g_object_new (META_TYPE_SURFACE_ACTOR_X11, NULL); MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); MetaDisplay *display = meta_window_get_display (window); - Display *xdisplay = meta_display_get_xdisplay (display); - Window xwindow = meta_window_get_toplevel_xwindow (window); g_assert (!meta_is_wayland_compositor ()); priv->window = window; priv->display = display; - priv->damage = XDamageCreate (xdisplay, xwindow, XDamageReportBoundingBox); + create_damage (self); + g_signal_connect_object (priv->window, "notify::decorated", + G_CALLBACK (window_decorated_notify), self, 0); + update_is_argb32 (self); priv->unredirected = FALSE; diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 597a2096a..8eaf66974 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -84,7 +84,6 @@ struct _MetaWindowActorPrivate guint visible : 1; guint disposed : 1; - guint redecorating : 1; /* If set, the client needs to be sent a _NET_WM_FRAME_DRAWN * client message using the most recent frame in ->frames */ @@ -219,26 +218,6 @@ meta_window_actor_init (MetaWindowActor *self) priv->shadow_class = NULL; } -static void -window_decorated_notify (MetaWindow *mw, - GParamSpec *arg1, - gpointer data) -{ - MetaWindowActor *self = META_WINDOW_ACTOR (data); - MetaWindowActorPrivate *priv = self->priv; - - /* - * Basically, we have to reconstruct the the internals of this object - * from scratch, as everything has changed. - */ - priv->redecorating = TRUE; - - /* - * Recreate the contents. - */ - meta_window_actor_constructed (G_OBJECT (self)); -} - static void window_appears_focused_notify (MetaWindow *mw, GParamSpec *arg1, @@ -414,9 +393,6 @@ meta_window_actor_set_property (GObject *object, { case PROP_META_WINDOW: priv->window = g_value_dup_object (value); - - g_signal_connect_object (priv->window, "notify::decorated", - G_CALLBACK (window_decorated_notify), self, 0); g_signal_connect_object (priv->window, "notify::appears-focused", G_CALLBACK (window_appears_focused_notify), self, 0); break; @@ -1179,13 +1155,11 @@ meta_window_actor_show (MetaWindowActor *self, g_assert_not_reached(); } - if (priv->redecorating || - info->switch_workspace_in_progress || + if (info->switch_workspace_in_progress || event == 0 || !start_simple_effect (self, event)) { clutter_actor_show (CLUTTER_ACTOR (self)); - priv->redecorating = FALSE; } } From 7283fb320f61581a524fe22b3905538adeef1c6b Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 21 Feb 2014 13:49:14 -0500 Subject: [PATCH 544/889] mutter-wayland: Add XKB VT switching keysyms. It turns out XKB has keysyms for these for no real reason, and I was hitting those instead of the F1 path. This is ridiculous, but key, so is the entirety of XKB. This took an embarassingly long time to figure out and debug. --- src/org.gnome.mutter.wayland.gschema.xml.in | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/org.gnome.mutter.wayland.gschema.xml.in b/src/org.gnome.mutter.wayland.gschema.xml.in index 4bb5c1dfd..baddf8e72 100644 --- a/src/org.gnome.mutter.wayland.gschema.xml.in +++ b/src/org.gnome.mutter.wayland.gschema.xml.in @@ -2,31 +2,31 @@ - F1']]]> + F1', 'XF86Switch_VT_1']]]> <_summary>Switch to VT 1 - F2']]]> + F2', 'XF86Switch_VT_2']]]> <_summary>Switch to VT 2 - F3']]]> + F3', 'XF86Switch_VT_3']]]> <_summary>Switch to VT 3 - F4']]]> + F4', 'XF86Switch_VT_4']]]> <_summary>Switch to VT 4 - F5']]]> + F5', 'XF86Switch_VT_5']]]> <_summary>Switch to VT 5 - F6']]]> + F6', 'XF86Switch_VT_6']]]> <_summary>Switch to VT 6 - F7']]]> + F7', 'XF86Switch_VT_7']]]> <_summary>Switch to VT 7 From 14841475b513cf6895a066c25533520a4b937c55 Mon Sep 17 00:00:00 2001 From: Adel Gadllah Date: Fri, 21 Feb 2014 20:39:25 +0100 Subject: [PATCH 545/889] meta-window-actor: Fix paint_volume We cannot intersect the the complete volume with the unobscured bounds because it does not include the shadows. So just intersect it with the windows's shape bounds and union it with the shadow bounds. This also matches what the comment in the code says: "We could compute an full clip region as we do for the window texture, but the shadow is relatively cheap to draw, and a little more complex to clip, so we just catch the case where the shadow is completely obscured and doesn't need to be drawn at all." --- src/compositor/meta-window-actor.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 8eaf66974..0817fbe89 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -614,6 +614,9 @@ meta_window_actor_get_paint_volume (ClutterActor *actor, meta_window_actor_get_shape_bounds (self, &bounds); + if (meta_surface_actor_get_unobscured_bounds (priv->surface, &unobscured_bounds)) + gdk_rectangle_intersect (&bounds, &unobscured_bounds, &bounds); + if (appears_focused ? priv->focused_shadow : priv->unfocused_shadow) { cairo_rectangle_int_t shadow_bounds; @@ -629,9 +632,6 @@ meta_window_actor_get_paint_volume (ClutterActor *actor, gdk_rectangle_union (&bounds, &shadow_bounds, &bounds); } - if (meta_surface_actor_get_unobscured_bounds (priv->surface, &unobscured_bounds)) - gdk_rectangle_intersect (&bounds, &unobscured_bounds, &bounds); - origin.x = bounds.x; origin.y = bounds.y; origin.z = 0.0f; From 337c69e22322713b92b074ab5b4934bdf513c00f Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sat, 22 Feb 2014 18:11:20 -0500 Subject: [PATCH 546/889] pointer/keyboard: Unset focus_resource when the surface is destroyed focus_resource is supposed to be set only if focus_surface is as well. --- src/wayland/meta-wayland-keyboard.c | 3 +++ src/wayland/meta-wayland-pointer.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/wayland/meta-wayland-keyboard.c b/src/wayland/meta-wayland-keyboard.c index e07b6f29c..198996e2b 100644 --- a/src/wayland/meta-wayland-keyboard.c +++ b/src/wayland/meta-wayland-keyboard.c @@ -224,6 +224,9 @@ keyboard_handle_focus_surface_destroy (struct wl_listener *listener, void *data) wl_list_remove (&keyboard->focus_surface_listener.link); keyboard->focus_surface = NULL; + + wl_list_remove (&keyboard->focus_resource_listener.link); + keyboard->focus_resource = NULL; } static void diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index 88ced65e1..e554cb6a2 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -62,6 +62,9 @@ pointer_handle_focus_surface_destroy (struct wl_listener *listener, void *data) wl_list_remove (&pointer->focus_surface_listener.link); pointer->focus_surface = NULL; + + wl_list_remove (&pointer->focus_resource_listener.link); + pointer->focus_resource = NULL; } static void From ff8c4b1bcf1ecb30282c3b6ebe2574a4a520265a Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sun, 23 Feb 2014 09:59:42 -0500 Subject: [PATCH 547/889] pointer/keyboard: Fix segfault once more If the resource is destroyed before the surface, then we'll kill ourselves. Why can I never seem to write these correctly... --- src/wayland/meta-wayland-keyboard.c | 7 +++++-- src/wayland/meta-wayland-pointer.c | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/wayland/meta-wayland-keyboard.c b/src/wayland/meta-wayland-keyboard.c index 198996e2b..c357b77f1 100644 --- a/src/wayland/meta-wayland-keyboard.c +++ b/src/wayland/meta-wayland-keyboard.c @@ -225,8 +225,11 @@ keyboard_handle_focus_surface_destroy (struct wl_listener *listener, void *data) wl_list_remove (&keyboard->focus_surface_listener.link); keyboard->focus_surface = NULL; - wl_list_remove (&keyboard->focus_resource_listener.link); - keyboard->focus_resource = NULL; + if (keyboard->focus_resource) + { + wl_list_remove (&keyboard->focus_resource_listener.link); + keyboard->focus_resource = NULL; + } } static void diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index e554cb6a2..21e41bb80 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -63,8 +63,11 @@ pointer_handle_focus_surface_destroy (struct wl_listener *listener, void *data) wl_list_remove (&pointer->focus_surface_listener.link); pointer->focus_surface = NULL; - wl_list_remove (&pointer->focus_resource_listener.link); - pointer->focus_resource = NULL; + if (pointer->focus_resource) + { + wl_list_remove (&pointer->focus_resource_listener.link); + pointer->focus_resource = NULL; + } } static void From f860df4b2dbd43006d65cdcf87886f2d4ebe4d63 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sun, 23 Feb 2014 12:28:51 -0500 Subject: [PATCH 548/889] Revert "compositor: fix focusing the stage window" This reverts commit 876f81db12d122ce2be69395c809d9835eebea39. This doesn't quite work properly, and is overcomplicated. --- src/compositor/compositor.c | 34 +++++++++------------ src/core/display-private.h | 18 +++-------- src/core/display.c | 60 ++++++++++--------------------------- 3 files changed, 34 insertions(+), 78 deletions(-) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 88b525ffd..a93d6c64f 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -316,39 +316,33 @@ meta_focus_stage_window (MetaScreen *screen, if (!stage) return; - if (!meta_is_wayland_compositor ()) - { - window = clutter_x11_get_stage_window (stage); + window = clutter_x11_get_stage_window (stage); - if (window == None) - return; + if (window == None) + return; - meta_display_set_input_focus_xwindow (screen->display, - screen, - META_FOCUS_STAGE, - window, - timestamp); - } - else - { - meta_display_set_input_focus_xwindow (screen->display, - screen, - META_FOCUS_STAGE, - None, - timestamp); - } + meta_display_set_input_focus_xwindow (screen->display, + screen, + window, + timestamp); } gboolean meta_stage_is_focused (MetaScreen *screen) { ClutterStage *stage; + Window window; stage = CLUTTER_STAGE (meta_get_stage_for_screen (screen)); if (!stage) return FALSE; - return (screen->display->focus_type == META_FOCUS_STAGE); + window = clutter_x11_get_stage_window (stage); + + if (window == None) + return FALSE; + + return (screen->display->focus_xwindow == window); } static gboolean diff --git a/src/core/display-private.h b/src/core/display-private.h index 11b3a6091..4bd95cb1d 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -84,14 +84,6 @@ typedef enum { META_TILE_MAXIMIZED } MetaTileMode; -typedef enum { - META_FOCUS_NONE = 0, - META_FOCUS_X_CLIENT = 1, - META_FOCUS_WAYLAND_CLIENT = 2, - META_FOCUS_NO_FOCUS_WINDOW = 3, - META_FOCUS_STAGE = 4 -} MetaFocusType; - struct _MetaDisplay { GObject parent_instance; @@ -125,7 +117,6 @@ struct _MetaDisplay * like the no_focus_window or the stage X window. */ Window focus_xwindow; gulong focus_serial; - MetaFocusType focus_type; /* last timestamp passed to XSetInputFocus */ guint32 last_focus_time; @@ -493,10 +484,9 @@ gboolean meta_display_process_barrier_event (MetaDisplay *display, XIEvent *event); #endif /* HAVE_XI23 */ -void meta_display_set_input_focus_xwindow (MetaDisplay *display, - MetaScreen *screen, - MetaFocusType type, - Window window, - guint32 timestamp); +void meta_display_set_input_focus_xwindow (MetaDisplay *display, + MetaScreen *screen, + Window window, + guint32 timestamp); #endif diff --git a/src/core/display.c b/src/core/display.c index d3a03bd77..1ea1cc728 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -1746,12 +1746,11 @@ get_input_event (MetaDisplay *display, } static void -update_focus_window (MetaDisplay *display, - MetaFocusType type, - MetaWindow *window, - Window xwindow, - gulong serial, - gboolean focused_by_us) +update_focus_window (MetaDisplay *display, + MetaWindow *window, + Window xwindow, + gulong serial, + gboolean focused_by_us) { MetaWaylandCompositor *compositor; @@ -1759,7 +1758,6 @@ update_focus_window (MetaDisplay *display, display->focused_by_us = focused_by_us; if (display->focus_xwindow == xwindow && - display->focus_type == type && display->focus_window == window) return; @@ -1782,7 +1780,6 @@ update_focus_window (MetaDisplay *display, meta_window_set_focused_internal (previous, FALSE); } - display->focus_type = type; display->focus_window = window; display->focus_xwindow = xwindow; @@ -1809,8 +1806,7 @@ update_focus_window (MetaDisplay *display, { compositor = meta_wayland_compositor_get_default (); - if (display->focus_type == META_FOCUS_NO_FOCUS_WINDOW || - display->focus_type == META_FOCUS_STAGE) + if (meta_display_xwindow_is_a_no_focus_window (display, xwindow)) meta_wayland_compositor_set_input_focus (compositor, NULL); else if (window && window->surface) meta_wayland_compositor_set_input_focus (compositor, window); @@ -1852,12 +1848,11 @@ timestamp_too_old (MetaDisplay *display, } static void -request_xserver_input_focus_change (MetaDisplay *display, - MetaScreen *screen, - MetaFocusType type, - MetaWindow *meta_window, - Window xwindow, - guint32 timestamp) +request_xserver_input_focus_change (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *meta_window, + Window xwindow, + guint32 timestamp) { gulong serial; @@ -1890,7 +1885,6 @@ request_xserver_input_focus_change (MetaDisplay *display, meta_display_ungrab (display); update_focus_window (display, - type, meta_window, xwindow, serial, @@ -1912,12 +1906,9 @@ handle_window_focus_event (MetaDisplay *display, unsigned long serial) { MetaWindow *focus_window; - MetaFocusType type; #ifdef WITH_VERBOSE_MODE const char *window_type; - type = META_FOCUS_NONE; - /* Note the event can be on either the window or the frame, * we focus the frame for shaded windows */ @@ -1929,26 +1920,14 @@ handle_window_focus_event (MetaDisplay *display, window_type = "frame window"; else window_type = "unknown client window"; - - if (window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND) - type = META_FOCUS_WAYLAND_CLIENT; - else - type = META_FOCUS_X_CLIENT; } else if (meta_display_xwindow_is_a_no_focus_window (display, event->event)) - { - window_type = "no_focus_window"; - type = META_FOCUS_NO_FOCUS_WINDOW; - } + window_type = "no_focus_window"; else if (meta_display_screen_for_root (display, event->event)) window_type = "root window"; else window_type = "unknown window"; - /* Don't change type if we don't know the new window */ - if (type == META_FOCUS_NONE) - type = display->focus_type; - meta_topic (META_DEBUG_FOCUS, "Focus %s event received on %s 0x%lx (%s) " "mode %s detail %s serial %lu\n", @@ -2033,7 +2012,6 @@ handle_window_focus_event (MetaDisplay *display, display->server_focus_serial == display->focus_serial)) { update_focus_window (display, - type, focus_window, focus_window ? focus_window->xwindow : None, display->server_focus_serial, @@ -3282,7 +3260,6 @@ meta_display_handle_xevent (MetaDisplay *display, meta_topic (META_DEBUG_FOCUS, "Earlier attempt to focus %s failed\n", display->focus_window->desc); update_focus_window (display, - META_FOCUS_NONE, meta_display_lookup_x_window (display, display->server_focus_window), display->server_focus_window, display->server_focus_serial, @@ -5951,8 +5928,6 @@ meta_display_set_input_focus_window (MetaDisplay *display, { request_xserver_input_focus_change (display, window->screen, - window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND ? - META_FOCUS_WAYLAND_CLIENT : META_FOCUS_X_CLIENT, window, focus_frame ? window->frame->xwindow : window->xwindow, timestamp); @@ -5975,15 +5950,13 @@ meta_display_request_take_focus (MetaDisplay *display, } void -meta_display_set_input_focus_xwindow (MetaDisplay *display, - MetaScreen *screen, - MetaFocusType type, - Window window, - guint32 timestamp) +meta_display_set_input_focus_xwindow (MetaDisplay *display, + MetaScreen *screen, + Window window, + guint32 timestamp) { request_xserver_input_focus_change (display, screen, - type, NULL, window, timestamp); @@ -5996,7 +5969,6 @@ meta_display_focus_the_no_focus_window (MetaDisplay *display, { request_xserver_input_focus_change (display, screen, - META_FOCUS_NO_FOCUS_WINDOW, NULL, screen->no_focus_window, timestamp); From 04b5232960553b93e70baf0335557b008073c459 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sun, 23 Feb 2014 12:29:21 -0500 Subject: [PATCH 549/889] compositor: The stage is always focused when we're a Wayland compositor gnome-shell has some complex tracking to set the X input focus correctly, assuming various things about how the stage is set up in X11. For instance, it assumes that all actors that get key focus are gnome-shell Chrome actors that will get events through the stage, so when one of them is focused, it will try to set the focus back to the stage. In Wayland, windows are considered chrome actors that will get key events through the stage, so this only has the result of unfocusing any windows that have just received key focus. We should probably move this input focus moving to mutter instead of gnome-shell so we can better use mutter's internal state and heuristics. --- src/compositor/compositor.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index a93d6c64f..a323c310c 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -333,6 +333,9 @@ meta_stage_is_focused (MetaScreen *screen) ClutterStage *stage; Window window; + if (meta_is_wayland_compositor ()) + return TRUE; + stage = CLUTTER_STAGE (meta_get_stage_for_screen (screen)); if (!stage) return FALSE; From bcd5446cdc981e6aaddfe659dad1f7341bc91c54 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Sat, 22 Feb 2014 20:16:28 +0100 Subject: [PATCH 550/889] core: prevent early MetaIdleMonitor destruction when its invoker vanishes If the last reference of a MetaIdleMonitor is held by the caller, it may happen that the last reference is lost when calling the GDestroyNotify, if this happens when the watched DBus name vanishes, the object (and the watches hashtable) are destroyed while manipulating the watches hashtable, so bad things may happen then. Fix this by wrapping the operation by a ref/unref pair, so the object would be destroyed after operating on the hashtable. https://bugzilla.gnome.org/show_bug.cgi?id=724969 --- src/core/meta-idle-monitor.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/core/meta-idle-monitor.c b/src/core/meta-idle-monitor.c index c99fc1050..4f853ea1b 100644 --- a/src/core/meta-idle-monitor.c +++ b/src/core/meta-idle-monitor.c @@ -653,8 +653,10 @@ meta_idle_monitor_remove_watch (MetaIdleMonitor *monitor, { g_return_if_fail (META_IS_IDLE_MONITOR (monitor)); + g_object_ref (monitor); g_hash_table_remove (monitor->watches, GUINT_TO_POINTER (id)); + g_object_unref (monitor); } /** From 0be4622e14af0625472123dadb0648e25501f764 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sun, 23 Feb 2014 18:50:11 -0500 Subject: [PATCH 551/889] stack-tracker: Comment out bad warning It triggers too often, making G_DEBUG=fatal-warnings quite useless. Owen is going to rewrite this code sometime in the near future, so I'm just gonna kill this warning for now. --- src/core/stack-tracker.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/stack-tracker.c b/src/core/stack-tracker.c index 5d88a46da..a323a0410 100644 --- a/src/core/stack-tracker.c +++ b/src/core/stack-tracker.c @@ -1041,7 +1041,7 @@ stack_tracker_event_received (MetaStackTracker *tracker, if (op->any.serial < tracker->xserver_serial) { - g_warning ("Spurious X event received affecting stack; doing full re-query"); + /* g_warning ("Spurious X event received affecting stack; doing full re-query"); */ resync_verified_stack_with_xserver_stack (tracker); meta_stack_tracker_dump (tracker); return; From 9b24ae2033f2b512bd955d5be02c690c389d75d2 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 24 Feb 2014 12:56:30 -0500 Subject: [PATCH 552/889] Revert "compositor: Delay meta_compositor_add_window until the first show" This reverts commit 4efe4483fbc7602e8358fda936074216a8e5544b. --- src/compositor/compositor.c | 28 +++++++++++++++++----------- src/core/window.c | 7 +++++-- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index a323c310c..dcf1136f6 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -140,6 +140,19 @@ meta_compositor_destroy (MetaCompositor *compositor) clutter_threads_remove_repaint_func (compositor->repaint_func_id); } +static void +add_win (MetaWindow *window) +{ + MetaScreen *screen = meta_window_get_screen (window); + MetaCompScreen *info = meta_screen_get_compositor_data (screen); + + g_return_if_fail (info != NULL); + + meta_window_actor_new (window); + + sync_actor_stacking (info); +} + static void process_damage (MetaCompositor *compositor, XDamageNotifyEvent *event, @@ -819,20 +832,13 @@ meta_compositor_add_window (MetaCompositor *compositor, { MetaScreen *screen = meta_window_get_screen (window); MetaDisplay *display = meta_screen_get_display (screen); - MetaCompScreen *info = meta_screen_get_compositor_data (screen); - - g_return_if_fail (info != NULL); - - /* Window was already added previously, probably coming - * back from hiding */ - if (window->compositor_private != NULL) - return; + DEBUG_TRACE ("meta_compositor_add_window\n"); meta_error_trap_push (display); - meta_window_actor_new (window); - meta_error_trap_pop (display); - sync_actor_stacking (info); + add_win (window); + + meta_error_trap_pop (display); } void diff --git a/src/core/window.c b/src/core/window.c index 81ca3f8ae..10a1b4087 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -1217,6 +1217,9 @@ _meta_window_shared_new (MetaDisplay *display, set_net_wm_state (window); } + if (screen->display->compositor) + meta_compositor_add_window (screen->display->compositor, window); + /* Sync stack changes */ meta_stack_thaw (window->screen->stack); @@ -2769,8 +2772,8 @@ meta_window_show (MetaWindow *window) break; } - meta_compositor_add_window (window->display->compositor, window); - meta_compositor_show_window (window->display->compositor, window, effect); + meta_compositor_show_window (window->display->compositor, + window, effect); } } From 1783bf20ece7708dbf63da9a9833697c53a91a16 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 24 Feb 2014 13:42:21 -0500 Subject: [PATCH 553/889] Revert "window: Delay the showing of XWayland clients until set_window_id" This reverts commit 59c8b949ad1b8712be7f1e90f8aaddac897da463. --- src/core/window-x11.c | 9 +-------- src/wayland/meta-xwayland.c | 2 -- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/src/core/window-x11.c b/src/core/window-x11.c index 150390a65..e43f4c040 100644 --- a/src/core/window-x11.c +++ b/src/core/window-x11.c @@ -1485,14 +1485,7 @@ meta_window_x11_new (MetaDisplay *display, existing_wm_state, effect, &attrs); - - /* When running as an X compositor, we can simply show the window now. - * - * When running as a Wayland compositor, we need to wait until we see - * the Wayland surface appear. We will later call meta_window_set_surface_mapped() - * to show the window in our in our set_surface_id implementation */ - if (!meta_is_wayland_compositor ()) - meta_window_set_surface_mapped (window, TRUE); + meta_window_set_surface_mapped (window, TRUE); meta_error_trap_pop (display); /* pop the XSync()-reducing trap */ return window; diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index b9c9de3e8..36b538b30 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -49,8 +49,6 @@ xserver_set_window_id (struct wl_client *client, surface->window = window; window->surface = surface; - - meta_window_set_surface_mapped (window, TRUE); } static const struct xserver_interface xserver_implementation = { From f0cd9b0687789f92e01d629980bbea95774f1b66 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 24 Feb 2014 13:32:17 -0500 Subject: [PATCH 554/889] wayland-surface: Rework construction / destruction yet again This time, to make way for MetaSurfaceActorEmpty. This also fixes destroy effects as a side effect. It still has issues if we try to re-assign an actor that's already toplevel (e.g. somebody re-popping up a menu that's already being destroyed), but this will be fixed soon. The idea here is that MetaWindowActor will do the unparenting of the surface actor when it itself is destroyed. To prevent bad issues with picking, we only make the surface actor reactive when it's toplevel. --- src/compositor/meta-window-actor.c | 76 ++++++++++++++++++++++-------- src/wayland/meta-wayland-surface.c | 27 ++++++----- src/wayland/meta-wayland-surface.h | 1 + src/wayland/meta-xwayland.c | 2 + 4 files changed, 73 insertions(+), 33 deletions(-) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 0817fbe89..d2c16b1cf 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -68,6 +68,9 @@ struct _MetaWindowActorPrivate guint send_frame_messages_timer; gint64 frame_drawn_time; + guint repaint_scheduled_id; + guint allocation_changed_id; + /* * These need to be counters rather than flags, since more plugins * can implement same effect; the practicality of stacking effects @@ -294,6 +297,57 @@ meta_window_actor_thaw (MetaWindowActor *self) meta_window_actor_handle_updates (self); } +static void +set_surface (MetaWindowActor *self, + MetaSurfaceActor *surface) +{ + MetaWindowActorPrivate *priv = self->priv; + + if (priv->surface) + { + g_signal_handler_disconnect (priv->surface, priv->repaint_scheduled_id); + priv->repaint_scheduled_id = 0; + g_signal_handler_disconnect (priv->surface, priv->allocation_changed_id); + priv->allocation_changed_id = 0; + clutter_actor_remove_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface)); + g_object_unref (priv->surface); + } + + priv->surface = surface; + + if (priv->surface) + { + g_object_ref_sink (priv->surface); + priv->repaint_scheduled_id = g_signal_connect (priv->surface, "repaint-scheduled", + G_CALLBACK (surface_repaint_scheduled), self); + priv->allocation_changed_id = g_signal_connect (priv->surface, "allocation-changed", + G_CALLBACK (surface_allocation_changed_notify), self); + clutter_actor_add_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface)); + + /* If the previous surface actor was frozen, start out + * frozen as well... */ + if (priv->updates_frozen) + meta_surface_actor_freeze (priv->surface); + + meta_window_actor_update_shape (self); + } +} + +static void +meta_window_actor_update_surface (MetaWindowActor *self) +{ + MetaWindowActorPrivate *priv = self->priv; + MetaWindow *window = priv->window; + MetaSurfaceActor *surface_actor; + + if (window->surface) + surface_actor = window->surface->surface_actor; + else + surface_actor = meta_surface_actor_x11_new (window); + + set_surface (self, surface_actor); +} + static void meta_window_actor_constructed (GObject *object) { @@ -303,22 +357,7 @@ meta_window_actor_constructed (GObject *object) priv->screen = window->screen; - if (!priv->surface) - { - if (window->surface) - priv->surface = window->surface->surface_actor; - else - priv->surface = meta_surface_actor_x11_new (window); - g_object_ref_sink (priv->surface); - - clutter_actor_add_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface)); - - g_signal_connect_object (priv->surface, "repaint-scheduled", - G_CALLBACK (surface_repaint_scheduled), self, 0); - g_signal_connect_object (priv->surface, "allocation-changed", - G_CALLBACK (surface_allocation_changed_notify), self, 0); - meta_window_actor_update_shape (self); - } + meta_window_actor_update_surface (self); meta_window_actor_update_opacity (self); @@ -361,10 +400,7 @@ meta_window_actor_dispose (GObject *object) g_clear_object (&priv->window); - /* - * Release the extra reference we took on the actor. - */ - g_clear_object (&priv->surface); + set_surface (self, NULL); G_OBJECT_CLASS (meta_window_actor_parent_class)->dispose (object); } diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 0783316fe..a7bf0504e 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -574,23 +574,16 @@ const struct wl_surface_interface meta_wayland_surface_interface = { meta_wayland_surface_set_buffer_scale }; -static void -unparent_actor (MetaWaylandSurface *surface) +void +meta_wayland_surface_make_toplevel (MetaWaylandSurface *surface) { - ClutterActor *parent_actor; - - parent_actor = clutter_actor_get_parent (CLUTTER_ACTOR (surface->surface_actor)); - clutter_actor_remove_child (parent_actor, CLUTTER_ACTOR (surface->surface_actor)); + clutter_actor_set_reactive (CLUTTER_ACTOR (surface->surface_actor), TRUE); } void meta_wayland_surface_window_unmanaged (MetaWaylandSurface *surface) { - /* The window is being unmanaged. Unparent our surface actor - * before the window actor is destroyed, as we need to hold - * onto it... */ - unparent_actor (surface); - + clutter_actor_set_reactive (CLUTTER_ACTOR (surface->surface_actor), FALSE); surface->window = NULL; } @@ -649,10 +642,8 @@ meta_wayland_surface_create (MetaWaylandCompositor *compositor, surface->buffer_destroy_listener.notify = surface_handle_buffer_destroy; surface->surface_actor = g_object_ref_sink (meta_surface_actor_wayland_new (surface)); - clutter_actor_set_reactive (CLUTTER_ACTOR (surface->surface_actor), TRUE); double_buffered_state_init (&surface->pending); - return surface; } @@ -980,6 +971,7 @@ xdg_shell_get_xdg_surface (struct wl_client *client, return; } + meta_wayland_surface_make_toplevel (surface); surface->window = meta_window_wayland_new (meta_get_display (), surface); } @@ -1035,6 +1027,7 @@ xdg_shell_get_xdg_popup (struct wl_client *client, return; } + meta_wayland_surface_make_toplevel (surface); surface->window = meta_window_wayland_new (meta_get_display (), surface); surface->window->rect.x = parent_surf->window->rect.x + x; surface->window->rect.y = parent_surf->window->rect.y + y; @@ -1249,6 +1242,14 @@ subsurface_parent_surface_committed (MetaWaylandSurface *surface) double_buffered_state_reset (pending_surface_state); } +static void +unparent_actor (MetaWaylandSurface *surface) +{ + ClutterActor *parent_actor; + parent_actor = clutter_actor_get_parent (CLUTTER_ACTOR (surface->surface_actor)); + clutter_actor_remove_child (parent_actor, CLUTTER_ACTOR (surface->surface_actor)); +} + static void wl_subsurface_destructor (struct wl_resource *resource) { diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h index 14305696c..9e12451d4 100644 --- a/src/wayland/meta-wayland-surface.h +++ b/src/wayland/meta-wayland-surface.h @@ -118,6 +118,7 @@ MetaWaylandSurface *meta_wayland_surface_create (MetaWaylandCompositor *composit guint32 id, guint32 version); +void meta_wayland_surface_make_toplevel (MetaWaylandSurface *surface); void meta_wayland_surface_window_unmanaged (MetaWaylandSurface *surface); void meta_wayland_surface_configure_notify (MetaWaylandSurface *surface, diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index 36b538b30..76ca5cb66 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -47,6 +47,8 @@ xserver_set_window_id (struct wl_client *client, if (!window) return; + meta_wayland_surface_make_toplevel (surface); + surface->window = window; window->surface = surface; } From 153f843ea68f5ec78274596da8f361f08cb9cafa Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Mon, 24 Feb 2014 22:00:12 +0100 Subject: [PATCH 555/889] MetaSurfaceActor: move freeze accounting to MetaWindowActor Turns out we only ever need to freeze/thaw whole windows, not surfaces or subsurfaces. This will allow removing the surface actor without losing the count. --- src/compositor/meta-surface-actor.c | 36 ++++++++--------------------- src/compositor/meta-surface-actor.h | 5 ++-- src/compositor/meta-window-actor.c | 21 ++++++++++++----- 3 files changed, 26 insertions(+), 36 deletions(-) diff --git a/src/compositor/meta-surface-actor.c b/src/compositor/meta-surface-actor.c index f82a6a9b8..1c795d52f 100644 --- a/src/compositor/meta-surface-actor.c +++ b/src/compositor/meta-surface-actor.c @@ -26,8 +26,8 @@ struct _MetaSurfaceActorPrivate cairo_region_t *input_region; /* Freeze/thaw accounting */ - guint freeze_count; guint needs_damage_all : 1; + guint frozen : 1; }; static void cullable_iface_init (MetaCullableInterface *iface); @@ -223,7 +223,7 @@ static gboolean is_frozen (MetaSurfaceActor *self) { MetaSurfaceActorPrivate *priv = self->priv; - return (priv->freeze_count > 0); + return priv->frozen; } void @@ -274,31 +274,19 @@ meta_surface_actor_is_visible (MetaSurfaceActor *self) } void -meta_surface_actor_freeze (MetaSurfaceActor *self) +meta_surface_actor_set_frozen (MetaSurfaceActor *self, + gboolean frozen) { MetaSurfaceActorPrivate *priv = self->priv; - priv->freeze_count ++; -} + priv->frozen = frozen; -void -meta_surface_actor_thaw (MetaSurfaceActor *self) -{ - MetaSurfaceActorPrivate *priv = self->priv; - - if (priv->freeze_count == 0) + if (!frozen && priv->needs_damage_all) { - g_critical ("Error in freeze/thaw accounting."); - return; - } + /* Since we ignore damage events while a window is frozen for certain effects + * we may need to issue an update_area() covering the whole pixmap if we + * don't know what real damage has happened. */ - priv->freeze_count --; - - /* Since we ignore damage events while a window is frozen for certain effects - * we may need to issue an update_area() covering the whole pixmap if we - * don't know what real damage has happened. */ - if (priv->needs_damage_all) - { meta_surface_actor_process_damage (self, 0, 0, clutter_actor_get_width (CLUTTER_ACTOR (priv->texture)), clutter_actor_get_height (CLUTTER_ACTOR (priv->texture))); @@ -306,12 +294,6 @@ meta_surface_actor_thaw (MetaSurfaceActor *self) } } -gboolean -meta_surface_actor_is_frozen (MetaSurfaceActor *self) -{ - return is_frozen (self); -} - gboolean meta_surface_actor_should_unredirect (MetaSurfaceActor *self) { diff --git a/src/compositor/meta-surface-actor.h b/src/compositor/meta-surface-actor.h index 763f91d72..a92f6f717 100644 --- a/src/compositor/meta-surface-actor.h +++ b/src/compositor/meta-surface-actor.h @@ -69,9 +69,8 @@ void meta_surface_actor_pre_paint (MetaSurfaceActor *actor); gboolean meta_surface_actor_is_argb32 (MetaSurfaceActor *actor); gboolean meta_surface_actor_is_visible (MetaSurfaceActor *actor); -void meta_surface_actor_freeze (MetaSurfaceActor *actor); -void meta_surface_actor_thaw (MetaSurfaceActor *actor); -gboolean meta_surface_actor_is_frozen (MetaSurfaceActor *actor); +void meta_surface_actor_set_frozen (MetaSurfaceActor *actor, + gboolean frozen); gboolean meta_surface_actor_should_unredirect (MetaSurfaceActor *actor); void meta_surface_actor_set_unredirected (MetaSurfaceActor *actor, diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index d2c16b1cf..14c12ee92 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -84,6 +84,7 @@ struct _MetaWindowActorPrivate /* List of FrameData for recent frames */ GList *frames; + guint freeze_count; guint visible : 1; guint disposed : 1; @@ -269,14 +270,19 @@ static gboolean is_frozen (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; - return meta_surface_actor_is_frozen (priv->surface); + + return priv->freeze_count > 0; } static void meta_window_actor_freeze (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; - meta_surface_actor_freeze (priv->surface); + + if (priv->freeze_count == 0) + meta_surface_actor_set_frozen (priv->surface, TRUE); + + priv->freeze_count ++; } static void @@ -284,11 +290,15 @@ meta_window_actor_thaw (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; - meta_surface_actor_thaw (priv->surface); + if (priv->freeze_count <= 0) + g_error ("Error in freeze/thaw accounting"); - if (is_frozen (self)) + priv->freeze_count--; + if (priv->freeze_count > 0) return; + meta_surface_actor_set_frozen (priv->surface, FALSE); + /* We sometimes ignore moves and resizes on frozen windows */ meta_window_actor_sync_actor_geometry (self, FALSE); @@ -326,8 +336,7 @@ set_surface (MetaWindowActor *self, /* If the previous surface actor was frozen, start out * frozen as well... */ - if (priv->updates_frozen) - meta_surface_actor_freeze (priv->surface); + meta_surface_actor_set_frozen (priv->surface, priv->freeze_count > 0); meta_window_actor_update_shape (self); } From 45624f2edfcac7a6a7816be99860d5c0a1f44d7b Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Tue, 25 Feb 2014 01:22:56 +0100 Subject: [PATCH 556/889] MetaWindowActor: survive having no MetaSurfaceActor We need a MetaWaylandSurface to build a MetaSurfaceActor, but we don't have one until we get the set_window_xid() call from XWayland. On the other hand, plugins expect to see the window actor right from when the window is created, so we need this empty state. Based on a patch by Jasper St. Pierre. --- src/compositor/compositor.c | 12 ++++ src/compositor/meta-window-actor-private.h | 1 + src/compositor/meta-window-actor.c | 78 ++++++++++++++++------ src/meta/compositor.h | 2 + src/wayland/meta-xwayland.c | 2 + 5 files changed, 73 insertions(+), 22 deletions(-) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index dcf1136f6..0fd6d6789 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -940,6 +940,18 @@ meta_compositor_window_opacity_changed (MetaCompositor *compositor, meta_window_actor_update_opacity (window_actor); } +void +meta_compositor_window_surface_changed (MetaCompositor *compositor, + MetaWindow *window) +{ + MetaWindowActor *window_actor; + window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); + if (!window_actor) + return; + + meta_window_actor_update_surface (window_actor); +} + /* Clutter makes the assumption that there is only one X window * per stage, which is a valid assumption to make for a generic * application toolkit. As such, it will ignore any events sent diff --git a/src/compositor/meta-window-actor-private.h b/src/compositor/meta-window-actor-private.h index 9c6a8476e..021ddc607 100644 --- a/src/compositor/meta-window-actor-private.h +++ b/src/compositor/meta-window-actor-private.h @@ -63,5 +63,6 @@ void meta_window_actor_effect_completed (MetaWindowActor *actor, gulong event); MetaSurfaceActor *meta_window_actor_get_surface (MetaWindowActor *self); +void meta_window_actor_update_surface (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 14c12ee92..fe29a790d 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -254,7 +254,15 @@ static gboolean is_argb32 (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; - return meta_surface_actor_is_argb32 (priv->surface); + + /* assume we're argb until we get the window (because + in practice we're drawing nothing, so we're fully + transparent) + */ + if (priv->surface) + return meta_surface_actor_is_argb32 (priv->surface); + else + return TRUE; } static gboolean @@ -271,7 +279,7 @@ is_frozen (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; - return priv->freeze_count > 0; + return priv->surface == NULL || priv->freeze_count > 0; } static void @@ -279,7 +287,7 @@ meta_window_actor_freeze (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; - if (priv->freeze_count == 0) + if (priv->freeze_count == 0 && priv->surface) meta_surface_actor_set_frozen (priv->surface, TRUE); priv->freeze_count ++; @@ -297,7 +305,8 @@ meta_window_actor_thaw (MetaWindowActor *self) if (priv->freeze_count > 0) return; - meta_surface_actor_set_frozen (priv->surface, FALSE); + if (priv->surface) + meta_surface_actor_set_frozen (priv->surface, FALSE); /* We sometimes ignore moves and resizes on frozen windows */ meta_window_actor_sync_actor_geometry (self, FALSE); @@ -342,7 +351,7 @@ set_surface (MetaWindowActor *self, } } -static void +void meta_window_actor_update_surface (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; @@ -351,8 +360,10 @@ meta_window_actor_update_surface (MetaWindowActor *self) if (window->surface) surface_actor = window->surface->surface_actor; - else + else if (!meta_is_wayland_compositor ()) surface_actor = meta_surface_actor_x11_new (window); + else + surface_actor = NULL; set_surface (self, surface_actor); } @@ -659,8 +670,11 @@ meta_window_actor_get_paint_volume (ClutterActor *actor, meta_window_actor_get_shape_bounds (self, &bounds); - if (meta_surface_actor_get_unobscured_bounds (priv->surface, &unobscured_bounds)) - gdk_rectangle_intersect (&bounds, &unobscured_bounds, &bounds); + if (priv->surface) + { + if (meta_surface_actor_get_unobscured_bounds (priv->surface, &unobscured_bounds)) + gdk_rectangle_intersect (&bounds, &unobscured_bounds, &bounds); + } if (appears_focused ? priv->focused_shadow : priv->unfocused_shadow) { @@ -771,21 +785,26 @@ meta_window_actor_get_meta_window (MetaWindowActor *self) * meta_window_actor_get_texture: * @self: a #MetaWindowActor * - * Gets the ClutterActor that is used to display the contents of the window + * Gets the ClutterActor that is used to display the contents of the window, + * or NULL if no texture is shown yet, because the window is not mapped. * * Return value: (transfer none): the #ClutterActor for the contents */ ClutterActor * meta_window_actor_get_texture (MetaWindowActor *self) { - return CLUTTER_ACTOR (meta_surface_actor_get_texture (self->priv->surface)); + if (self->priv->surface) + return CLUTTER_ACTOR (meta_surface_actor_get_texture (self->priv->surface)); + else + return NULL; } /** * meta_window_actor_get_surface: * @self: a #MetaWindowActor * - * Gets the MetaSurfaceActor that draws the content of this window + * Gets the MetaSurfaceActor that draws the content of this window, + * or NULL if there is no surface yet associated with this window. * * Return value: (transfer none): the #MetaSurfaceActor for the contents */ @@ -884,7 +903,12 @@ meta_window_actor_queue_frame_drawn (MetaWindowActor *self, if (!priv->repaint_scheduled) { - gboolean is_obscured = meta_surface_actor_is_obscured (priv->surface); + gboolean is_obscured; + + if (priv->surface) + is_obscured = meta_surface_actor_is_obscured (priv->surface); + else + is_obscured = FALSE; /* A frame was marked by the client without actually doing any * damage or any unobscured, or while we had the window frozen @@ -900,9 +924,12 @@ meta_window_actor_queue_frame_drawn (MetaWindowActor *self, } else { - const cairo_rectangle_int_t clip = { 0, 0, 1, 1 }; - clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (priv->surface), &clip); - priv->repaint_scheduled = TRUE; + if (priv->surface) + { + const cairo_rectangle_int_t clip = { 0, 0, 1, 1 }; + clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (priv->surface), &clip); + priv->repaint_scheduled = TRUE; + } } } } @@ -1075,7 +1102,10 @@ gboolean meta_window_actor_should_unredirect (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; - return meta_surface_actor_should_unredirect (priv->surface); + if (priv->surface) + return meta_surface_actor_should_unredirect (priv->surface); + else + return FALSE; } void @@ -1083,6 +1113,8 @@ meta_window_actor_set_unredirected (MetaWindowActor *self, gboolean unredirected) { MetaWindowActorPrivate *priv = self->priv; + + g_assert(priv->surface); /* because otherwise should_unredirect() is FALSE */ meta_surface_actor_set_unredirected (priv->surface, unredirected); } @@ -1528,11 +1560,12 @@ meta_window_actor_process_x11_damage (MetaWindowActor *self, { MetaWindowActorPrivate *priv = self->priv; - meta_surface_actor_process_damage (priv->surface, - event->area.x, - event->area.y, - event->area.width, - event->area.height); + if (priv->surface) + meta_surface_actor_process_damage (priv->surface, + event->area.x, + event->area.y, + event->area.width, + event->area.height); } void @@ -2035,7 +2068,8 @@ meta_window_actor_update_opacity (MetaWindowActor *self) MetaWindowActorPrivate *priv = self->priv; MetaWindow *window = priv->window; - clutter_actor_set_opacity (CLUTTER_ACTOR (self->priv->surface), window->opacity); + if (priv->surface) + clutter_actor_set_opacity (CLUTTER_ACTOR (priv->surface), window->opacity); } void diff --git a/src/meta/compositor.h b/src/meta/compositor.h index d1be47e36..76ad10ba8 100644 --- a/src/meta/compositor.h +++ b/src/meta/compositor.h @@ -66,6 +66,8 @@ void meta_compositor_window_shape_changed (MetaCompositor *compositor, MetaWindow *window); void meta_compositor_window_opacity_changed (MetaCompositor *compositor, MetaWindow *window); +void meta_compositor_window_surface_changed (MetaCompositor *compositor, + MetaWindow *window); gboolean meta_compositor_process_event (MetaCompositor *compositor, XEvent *event, diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index 76ca5cb66..f65ac5638 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -51,6 +51,8 @@ xserver_set_window_id (struct wl_client *client, surface->window = window; window->surface = surface; + + meta_compositor_window_surface_changed (display->compositor, window); } static const struct xserver_interface xserver_implementation = { From 9f5087e97d7903a02a1326f0cf75ab806f40cf2c Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Tue, 25 Feb 2014 01:22:36 +0100 Subject: [PATCH 557/889] Fix input and bounding shapes For decorated windows, we don't want to apply any input shape, because the frame is always rectangular and eats all the input. The real check is in meta-window-actor, where we consider if we need to apply the bounding shape and the input shape (or the intersection of the two) to the surface-actor, but as an optimization we avoid querying the server in meta-window. Additionally, for undecorated windows, the "has input shape" check is wrong if the window has a bounding shape but not an input shape. --- src/compositor/meta-window-actor.c | 22 ++++++++----- src/core/window-x11.c | 51 +++++++++++++++++++++--------- 2 files changed, 50 insertions(+), 23 deletions(-) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index fe29a790d..c4bf87977 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -1760,21 +1760,27 @@ meta_window_actor_update_input_region (MetaWindowActor *self, MetaWindowActorPrivate *priv = self->priv; cairo_region_t *region = NULL; - if (priv->window->frame != NULL && priv->window->input_region != NULL) + if (priv->window->frame != NULL) { region = meta_frame_get_frame_bounds (priv->window->frame); - - cairo_region_subtract_rectangle (region, client_area); - - /* input_region is in client window coordinates, so translate the + /* client area is in client window coordinates, so translate the * input region into that coordinate system and back */ cairo_region_translate (region, -client_area->x, -client_area->y); - cairo_region_union (region, priv->window->input_region); + cairo_region_union_rectangle (region, client_area); cairo_region_translate (region, client_area->x, client_area->y); } - else if (priv->window->input_region != NULL) + else if (priv->window->shape_region != NULL || + priv->window->input_region != NULL) { - region = cairo_region_reference (priv->window->input_region); + if (priv->window->shape_region != NULL) + { + region = cairo_region_copy (priv->window->shape_region); + + if (priv->window->input_region != NULL) + cairo_region_intersect (region, priv->window->input_region); + } + else + region = cairo_region_reference (priv->window->input_region); } else { diff --git a/src/core/window-x11.c b/src/core/window-x11.c index e43f4c040..8939f515a 100644 --- a/src/core/window-x11.c +++ b/src/core/window-x11.c @@ -350,11 +350,43 @@ meta_window_set_input_region (MetaWindow *window, meta_compositor_window_shape_changed (window->display->compositor, window); } +#if 0 +/* Print out a region; useful for debugging */ +static void +print_region (cairo_region_t *region) +{ + int n_rects; + int i; + + n_rects = cairo_region_num_rectangles (region); + g_print ("["); + for (i = 0; i < n_rects; i++) + { + cairo_rectangle_int_t rect; + cairo_region_get_rectangle (region, i, &rect); + g_print ("+%d+%dx%dx%d ", + rect.x, rect.y, rect.width, rect.height); + } + g_print ("]\n"); +} +#endif + void meta_window_x11_update_input_region (MetaWindow *window) { cairo_region_t *region = NULL; + /* Decorated windows don't have an input region, because + we don't shape the frame to match the client windows + (so the events are blocked by the frame anyway) + */ + if (window->decorated) + { + if (window->input_region) + meta_window_set_input_region (window, NULL); + return; + } + #ifdef HAVE_SHAPE if (META_DISPLAY_HAS_SHAPE (window->display)) { @@ -363,17 +395,6 @@ meta_window_x11_update_input_region (MetaWindow *window) XRectangle *rects = NULL; int n_rects, ordering; - int x_bounding, y_bounding, x_clip, y_clip; - unsigned w_bounding, h_bounding, w_clip, h_clip; - int bounding_shaped, clip_shaped; - - meta_error_trap_push (window->display); - XShapeQueryExtents (window->display->xdisplay, window->xwindow, - &bounding_shaped, &x_bounding, &y_bounding, - &w_bounding, &h_bounding, - &clip_shaped, &x_clip, &y_clip, - &w_clip, &h_clip); - rects = XShapeGetRectangles (window->display->xdisplay, window->xwindow, ShapeInput, @@ -388,10 +409,10 @@ meta_window_x11_update_input_region (MetaWindow *window) { if (n_rects > 1 || (n_rects == 1 && - (rects[0].x != x_bounding || - rects[0].y != y_bounding || - rects[0].width != w_bounding || - rects[0].height != h_bounding))) + (rects[0].x != 0 || + rects[0].y != 0 || + rects[0].width != window->rect.width || + rects[0].height != window->rect.height))) region = region_create_from_x_rectangles (rects, n_rects); XFree (rects); From 26cf75d5a478c761e9f0142db1607a015d6e80f0 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Tue, 25 Feb 2014 01:29:50 +0100 Subject: [PATCH 558/889] MetaWindowX11: fix listening for shape events This code was lost when support for input shapes was originally introduced. --- src/core/window-x11.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/core/window-x11.c b/src/core/window-x11.c index 8939f515a..00c7fafd9 100644 --- a/src/core/window-x11.c +++ b/src/core/window-x11.c @@ -1474,6 +1474,11 @@ meta_window_x11_new (MetaDisplay *display, XISelectEvents (display->xdisplay, xwindow, &mask, 1); } +#ifdef HAVE_SHAPE + if (META_DISPLAY_HAS_SHAPE (display)) + XShapeSelectInput (display->xdisplay, xwindow, ShapeNotifyMask); +#endif + /* Get rid of any borders */ if (attrs.border_width != 0) XSetWindowBorderWidth (display->xdisplay, xwindow, 0); From 060e60f2a0ab2e9365c4a17763bc1505b0036065 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Wed, 26 Feb 2014 00:21:52 +0100 Subject: [PATCH 559/889] window: fix loading the window type initially This code was lost in the window/window-x11 split. --- src/core/window.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/core/window.c b/src/core/window.c index 10a1b4087..aa7f28493 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -993,6 +993,9 @@ _meta_window_shared_new (MetaDisplay *display, client_type == META_WINDOW_CLIENT_TYPE_X11) update_sm_hints (window); /* must come after transient_for */ + if (client_type == META_WINDOW_CLIENT_TYPE_X11) + meta_window_x11_update_net_wm_type (window); + if (!window->override_redirect) meta_window_update_icon_now (window); From d85845426c36b82e1f60226565c9292d2ff64058 Mon Sep 17 00:00:00 2001 From: Adel Gadllah Date: Wed, 26 Feb 2014 14:50:14 +0100 Subject: [PATCH 560/889] window-actor: Fix culling At some point meta_window_actor_cull_out stopped calling meta_cullable_cull_out_children which caused the unobscured region to never be set for the stex. https://bugzilla.gnome.org/show_bug.cgi?id=725216 --- src/compositor/meta-window-actor.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index c4bf87977..5513fb385 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -1471,6 +1471,7 @@ meta_window_actor_cull_out (MetaCullable *cullable, { MetaWindowActor *self = META_WINDOW_ACTOR (cullable); + meta_cullable_cull_out_children (cullable, unobscured_region, clip_region); meta_window_actor_set_clip_region_beneath (self, clip_region); } From ac0c7df4a3c364a44ebe0ab22580754ca2e608d0 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Wed, 26 Feb 2014 00:47:11 +0100 Subject: [PATCH 561/889] keybindings: fix invalid read after a keybinding is removed The handler pointer is dangling in MetaKeyBinding until rebuild_key_binding_table() is run, so we can't dereference it. Because we only need the flags at ungrab time, store a copy in the MetaKeyBinding structure. https://bugzilla.gnome.org/show_bug.cgi?id=724402 --- src/core/keybindings-private.h | 1 + src/core/keybindings.c | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/core/keybindings-private.h b/src/core/keybindings-private.h index 07889220e..3ef3dd49c 100644 --- a/src/core/keybindings-private.h +++ b/src/core/keybindings-private.h @@ -47,6 +47,7 @@ struct _MetaKeyBinding KeyCode keycode; unsigned int mask; MetaVirtualModifier modifiers; + gint flags; MetaKeyHandler *handler; }; diff --git a/src/core/keybindings.c b/src/core/keybindings.c index 9024410ee..db2db7687 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -603,6 +603,7 @@ rebuild_binding_table (MetaDisplay *display, (*bindings_p)[i].name = pref->name; (*bindings_p)[i].handler = handler; + (*bindings_p)[i].flags = handler->flags; (*bindings_p)[i].keysym = combo->keysym; (*bindings_p)[i].keycode = combo->keycode; (*bindings_p)[i].modifiers = combo->modifiers; @@ -619,6 +620,7 @@ rebuild_binding_table (MetaDisplay *display, (*bindings_p)[i].name = pref->name; (*bindings_p)[i].handler = handler; + (*bindings_p)[i].flags = handler->flags; (*bindings_p)[i].keysym = combo->keysym; (*bindings_p)[i].keycode = combo->keycode; (*bindings_p)[i].modifiers = combo->modifiers | @@ -645,6 +647,7 @@ rebuild_binding_table (MetaDisplay *display, (*bindings_p)[i].name = grab->name; (*bindings_p)[i].handler = handler; + (*bindings_p)[i].flags = handler->flags; (*bindings_p)[i].keysym = grab->combo->keysym; (*bindings_p)[i].keycode = grab->combo->keycode; (*bindings_p)[i].modifiers = grab->combo->modifiers; @@ -1160,7 +1163,7 @@ change_binding_keygrabs (MetaKeyBinding *bindings, while (i < n_bindings) { if (!!binding_per_window == - !!(bindings[i].handler->flags & META_KEY_BINDING_PER_WINDOW) && + !!(bindings[i].flags & META_KEY_BINDING_PER_WINDOW) && bindings[i].keycode != 0) { meta_change_keygrab (display, xwindow, grab, From c5c3806a04cf2dd46e08355dd79cd3b0e8de934b Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 26 Feb 2014 19:54:07 -0500 Subject: [PATCH 562/889] window-x11: Add back missing error trap This was accidentally removed in 9f5087e. --- src/core/window-x11.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/window-x11.c b/src/core/window-x11.c index 00c7fafd9..6c1e7e215 100644 --- a/src/core/window-x11.c +++ b/src/core/window-x11.c @@ -395,6 +395,7 @@ meta_window_x11_update_input_region (MetaWindow *window) XRectangle *rects = NULL; int n_rects, ordering; + meta_error_trap_push (window->display); rects = XShapeGetRectangles (window->display->xdisplay, window->xwindow, ShapeInput, From ec2c3e1438592bdd5914c3c46dd138d7cab5e8df Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 26 Feb 2014 19:33:43 -0500 Subject: [PATCH 563/889] window: Add meta_window_get_client_area_rect --- src/compositor/meta-window-actor.c | 11 +---------- src/core/window-private.h | 3 +++ src/core/window.c | 31 ++++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 10 deletions(-) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 5513fb385..6fc5ef5df 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -1835,21 +1835,12 @@ static void check_needs_reshape (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; - MetaFrameBorders borders; cairo_rectangle_int_t client_area; if (!priv->needs_reshape) return; - meta_frame_calc_borders (priv->window->frame, &borders); - - client_area.x = borders.total.left; - client_area.y = borders.total.top; - client_area.width = priv->window->rect.width; - if (priv->window->shaded) - client_area.height = 0; - else - client_area.height = priv->window->rect.height; + meta_window_get_client_area_rect (window, &client_area); meta_window_actor_update_shape_region (self, &client_area); diff --git a/src/core/window-private.h b/src/core/window-private.h index d37c27d14..2d2f8ae2d 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -743,6 +743,9 @@ void meta_window_set_surface_mapped (MetaWindow *window, Window meta_window_get_toplevel_xwindow (MetaWindow *window); +void meta_window_get_client_area_rect (const MetaWindow *window, + cairo_rectangle_int_t *rect); + void meta_window_activate_full (MetaWindow *window, guint32 timestamp, MetaClientType source_indication, diff --git a/src/core/window.c b/src/core/window.c index aa7f28493..8bbe5c411 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -5651,6 +5651,37 @@ meta_window_get_outer_rect (const MetaWindow *window, meta_window_get_frame_rect (window, rect); } +/** + * meta_window_get_client_area_rect: + * @window: a #MetaWindow + * @rect: (out): pointer to a cairo rectangle + * + * Gets the rectangle for the boundaries of the client area, relative + * to the frame. If the window is shaded, the height of the rectangle + * is 0. + */ +void +meta_window_get_client_area_rect (const MetaWindow *window, + cairo_rectangle_int_t *rect) +{ + if (window->frame) + { + rect->x = window->frame->child_x; + rect->y = window->frame->child_y; + } + else + { + rect->x = 0; + rect->y = 0; + } + + rect->width = window->rect.width; + if (window->shaded) + rect->height = window->rect.height; + else + rect->height = 0; +} + const char* meta_window_get_startup_id (MetaWindow *window) { From 2dc7371944a7b9df58a0f5a09d799d1df30a2ea5 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 26 Feb 2014 19:35:41 -0500 Subject: [PATCH 564/889] window-actor: Don't pass around client_area To solve a performance regression, the three update_*_region calls are going to be split up, so just call get_client_area_rect in the methods itself. --- src/compositor/meta-window-actor.c | 36 ++++++++++++++++-------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 6fc5ef5df..32eda5f32 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -1720,16 +1720,18 @@ build_and_scan_frame_mask (MetaWindowActor *self, } static void -meta_window_actor_update_shape_region (MetaWindowActor *self, - cairo_rectangle_int_t *client_area) +meta_window_actor_update_shape_region (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; cairo_region_t *region = NULL; + cairo_rectangle_int_t client_area; + + meta_window_get_client_area_rect (priv->window, &client_area); if (priv->window->frame != NULL && priv->window->shape_region != NULL) { region = cairo_region_copy (priv->window->shape_region); - cairo_region_translate (region, client_area->x, client_area->y); + cairo_region_translate (region, client_area.x, client_area.y); } else if (priv->window->shape_region != NULL) { @@ -1740,11 +1742,11 @@ meta_window_actor_update_shape_region (MetaWindowActor *self, /* If we don't have a shape on the server, that means that * we have an implicit shape of one rectangle covering the * entire window. */ - region = cairo_region_create_rectangle (client_area); + region = cairo_region_create_rectangle (&client_area); } if ((priv->window->shape_region != NULL) || (priv->window->frame != NULL)) - build_and_scan_frame_mask (self, client_area, region); + build_and_scan_frame_mask (self, &client_area, region); g_clear_pointer (&priv->shape_region, cairo_region_destroy); priv->shape_region = region; @@ -1755,20 +1757,23 @@ meta_window_actor_update_shape_region (MetaWindowActor *self, } static void -meta_window_actor_update_input_region (MetaWindowActor *self, - cairo_rectangle_int_t *client_area) +meta_window_actor_update_input_region (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; cairo_region_t *region = NULL; + cairo_rectangle_int_t client_area; + + meta_window_get_client_area_rect (priv->window, &client_area); if (priv->window->frame != NULL) { region = meta_frame_get_frame_bounds (priv->window->frame); - /* client area is in client window coordinates, so translate the + + /* input_region is in client window coordinates, so translate the * input region into that coordinate system and back */ - cairo_region_translate (region, -client_area->x, -client_area->y); - cairo_region_union_rectangle (region, client_area); - cairo_region_translate (region, client_area->x, client_area->y); + cairo_region_translate (region, -client_area.x, -client_area.y); + cairo_region_union_rectangle (region, &client_area); + cairo_region_translate (region, client_area.x, client_area.y); } else if (priv->window->shape_region != NULL || priv->window->input_region != NULL) @@ -1788,7 +1793,7 @@ meta_window_actor_update_input_region (MetaWindowActor *self, /* If we don't have a shape on the server, that means that * we have an implicit shape of one rectangle covering the * entire window. */ - region = cairo_region_create_rectangle (client_area); + region = cairo_region_create_rectangle (&client_area); } meta_surface_actor_set_input_region (priv->surface, region); @@ -1835,18 +1840,15 @@ static void check_needs_reshape (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; - cairo_rectangle_int_t client_area; if (!priv->needs_reshape) return; - meta_window_get_client_area_rect (window, &client_area); - - meta_window_actor_update_shape_region (self, &client_area); + meta_window_actor_update_shape_region (self); if (priv->window->client_type == META_WINDOW_CLIENT_TYPE_X11) { - meta_window_actor_update_input_region (self, &client_area); + meta_window_actor_update_input_region (self); meta_window_actor_update_opaque_region (self); } From 41d5e69de527a2f25f716676e386fee09a56cd04 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 26 Feb 2014 19:38:11 -0500 Subject: [PATCH 565/889] window-actor: Kill off another use of MetaFrameBorders --- src/compositor/meta-window-actor.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 32eda5f32..89c6b4e93 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -1809,9 +1809,9 @@ meta_window_actor_update_opaque_region (MetaWindowActor *self) if (argb32 && priv->window->opaque_region != NULL) { - MetaFrameBorders borders; + cairo_rectangle_int_t client_area; - meta_frame_calc_borders (priv->window->frame, &borders); + meta_window_get_client_area_rect (priv->window, &client_area); /* The opaque region is defined to be a part of the * window which ARGB32 will always paint with opaque @@ -1824,7 +1824,7 @@ meta_window_actor_update_opaque_region (MetaWindowActor *self) * case, graphical glitches will occur. */ opaque_region = cairo_region_copy (priv->window->opaque_region); - cairo_region_translate (opaque_region, borders.total.left, borders.total.top); + cairo_region_translate (opaque_region, client_area.x, client_area.y); cairo_region_intersect (opaque_region, priv->shape_region); } else if (argb32) From c0d791cd6e25915a36890891940803185f7cc808 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 26 Feb 2014 19:42:31 -0500 Subject: [PATCH 566/889] window: Update the shape, input, and opaque regions immediately ... and individually. It turns out that updating the opaque region was causing the shape region to be updated, which was causing a new shape mask to be generated and uploaded to the GPU. Considering GTK+ regenerates the opaque region on pretty much any focus change, this is not good. --- src/compositor/compositor.c | 28 ++++++++++++++++++++-- src/compositor/meta-window-actor-private.h | 5 +++- src/compositor/meta-window-actor.c | 6 ++--- src/core/window-x11.c | 6 ++--- src/meta/compositor.h | 6 ++++- 5 files changed, 41 insertions(+), 10 deletions(-) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 0fd6d6789..ba3db9cb6 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -917,7 +917,31 @@ is_grabbed_event (MetaDisplay *display, } void -meta_compositor_window_shape_changed (MetaCompositor *compositor, +meta_compositor_update_shape_region (MetaCompositor *compositor, + MetaWindow *window) +{ + MetaWindowActor *window_actor; + window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); + if (!window_actor) + return; + + meta_window_actor_update_shape_region (window_actor); +} + +void +meta_compositor_update_input_region (MetaCompositor *compositor, + MetaWindow *window) +{ + MetaWindowActor *window_actor; + window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); + if (!window_actor) + return; + + meta_window_actor_update_input_region (window_actor); +} + +void +meta_compositor_update_opaque_region (MetaCompositor *compositor, MetaWindow *window) { MetaWindowActor *window_actor; @@ -925,7 +949,7 @@ meta_compositor_window_shape_changed (MetaCompositor *compositor, if (!window_actor) return; - meta_window_actor_update_shape (window_actor); + meta_window_actor_update_opaque_region (window_actor); } void diff --git a/src/compositor/meta-window-actor-private.h b/src/compositor/meta-window-actor-private.h index 021ddc607..d66f1f47d 100644 --- a/src/compositor/meta-window-actor-private.h +++ b/src/compositor/meta-window-actor-private.h @@ -50,7 +50,6 @@ gboolean meta_window_actor_effect_in_progress (MetaWindowActor *self); void meta_window_actor_sync_actor_geometry (MetaWindowActor *self, gboolean did_placement); void meta_window_actor_sync_visibility (MetaWindowActor *self); -void meta_window_actor_update_shape (MetaWindowActor *self); void meta_window_actor_update_opacity (MetaWindowActor *self); void meta_window_actor_mapped (MetaWindowActor *self); void meta_window_actor_unmapped (MetaWindowActor *self); @@ -65,4 +64,8 @@ void meta_window_actor_effect_completed (MetaWindowActor *actor, MetaSurfaceActor *meta_window_actor_get_surface (MetaWindowActor *self); void meta_window_actor_update_surface (MetaWindowActor *self); +void meta_window_actor_update_shape_region (MetaWindowActor *self); +void meta_window_actor_update_input_region (MetaWindowActor *self); +void meta_window_actor_update_opaque_region (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 89c6b4e93..3092e9451 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -1719,7 +1719,7 @@ build_and_scan_frame_mask (MetaWindowActor *self, g_free (mask_data); } -static void +void meta_window_actor_update_shape_region (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; @@ -1756,7 +1756,7 @@ meta_window_actor_update_shape_region (MetaWindowActor *self) meta_window_actor_invalidate_shadow (self); } -static void +void meta_window_actor_update_input_region (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; @@ -1800,7 +1800,7 @@ meta_window_actor_update_input_region (MetaWindowActor *self) cairo_region_destroy (region); } -static void +void meta_window_actor_update_opaque_region (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; diff --git a/src/core/window-x11.c b/src/core/window-x11.c index 6c1e7e215..318a81baf 100644 --- a/src/core/window-x11.c +++ b/src/core/window-x11.c @@ -261,7 +261,7 @@ meta_window_set_opaque_region (MetaWindow *window, window->opaque_region = cairo_region_reference (region); if (window->display->compositor) - meta_compositor_window_shape_changed (window->display->compositor, window); + meta_compositor_update_opaque_region (window->display->compositor, window); } void @@ -347,7 +347,7 @@ meta_window_set_input_region (MetaWindow *window, window->input_region = cairo_region_reference (region); if (window->display->compositor) - meta_compositor_window_shape_changed (window->display->compositor, window); + meta_compositor_update_input_region (window->display->compositor, window); } #if 0 @@ -454,7 +454,7 @@ meta_window_set_shape_region (MetaWindow *window, window->shape_region = cairo_region_reference (region); if (window->display->compositor) - meta_compositor_window_shape_changed (window->display->compositor, window); + meta_compositor_update_shape_region (window->display->compositor, window); } void diff --git a/src/meta/compositor.h b/src/meta/compositor.h index 76ad10ba8..022b47de6 100644 --- a/src/meta/compositor.h +++ b/src/meta/compositor.h @@ -62,7 +62,11 @@ void meta_compositor_manage_screen (MetaCompositor *compositor, void meta_compositor_unmanage_screen (MetaCompositor *compositor, MetaScreen *screen); -void meta_compositor_window_shape_changed (MetaCompositor *compositor, +void meta_compositor_update_shape_region (MetaCompositor *compositor, + MetaWindow *window); +void meta_compositor_update_input_region (MetaCompositor *compositor, + MetaWindow *window); +void meta_compositor_update_opaque_region (MetaCompositor *compositor, MetaWindow *window); void meta_compositor_window_opacity_changed (MetaCompositor *compositor, MetaWindow *window); From 640102c03b1e74ad481076cefe15b974ceeee052 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 26 Feb 2014 19:56:38 -0500 Subject: [PATCH 567/889] window-actor: Complete the removal of update_shape I accidentally stashed the rest of the stuff and forgot to commit it... oops. --- src/compositor/meta-window-actor.c | 39 ------------------------------ 1 file changed, 39 deletions(-) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 3092e9451..8e39be72a 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -94,7 +94,6 @@ struct _MetaWindowActorPrivate guint needs_frame_drawn : 1; guint repaint_scheduled : 1; - guint needs_reshape : 1; guint recompute_focused_shadow : 1; guint recompute_unfocused_shadow : 1; @@ -143,8 +142,6 @@ static gboolean meta_window_actor_has_shadow (MetaWindowActor *self); static void meta_window_actor_handle_updates (MetaWindowActor *self); -static void check_needs_reshape (MetaWindowActor *self); - static void do_send_frame_drawn (MetaWindowActor *self, FrameData *frame); static void do_send_frame_timings (MetaWindowActor *self, FrameData *frame, @@ -237,7 +234,6 @@ surface_allocation_changed_notify (ClutterActor *actor, MetaWindowActor *self) { meta_window_actor_sync_actor_geometry (self, FALSE); - meta_window_actor_update_shape (self); } static void @@ -346,8 +342,6 @@ set_surface (MetaWindowActor *self, /* If the previous surface actor was frozen, start out * frozen as well... */ meta_surface_actor_set_frozen (priv->surface, priv->freeze_count > 0); - - meta_window_actor_update_shape (self); } } @@ -1836,38 +1830,6 @@ meta_window_actor_update_opaque_region (MetaWindowActor *self) cairo_region_destroy (opaque_region); } -static void -check_needs_reshape (MetaWindowActor *self) -{ - MetaWindowActorPrivate *priv = self->priv; - - if (!priv->needs_reshape) - return; - - meta_window_actor_update_shape_region (self); - - if (priv->window->client_type == META_WINDOW_CLIENT_TYPE_X11) - { - meta_window_actor_update_input_region (self); - meta_window_actor_update_opaque_region (self); - } - - priv->needs_reshape = FALSE; -} - -void -meta_window_actor_update_shape (MetaWindowActor *self) -{ - MetaWindowActorPrivate *priv = self->priv; - - priv->needs_reshape = TRUE; - - if (is_frozen (self)) - return; - - clutter_actor_queue_redraw (CLUTTER_ACTOR (priv->surface)); -} - static void meta_window_actor_handle_updates (MetaWindowActor *self) { @@ -1888,7 +1850,6 @@ meta_window_actor_handle_updates (MetaWindowActor *self) if (!meta_surface_actor_is_visible (priv->surface)) return; - check_needs_reshape (self); check_needs_shadow (self); } From 98c4b82907eb0ceb888a72718756c6c05e4ced39 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 26 Feb 2014 20:45:38 -0500 Subject: [PATCH 568/889] Revert "window: Update the shape, input, and opaque regions immediately" This reverts commit c0d791cd6e25915a36890891940803185f7cc808. --- src/compositor/compositor.c | 28 ++-------------------- src/compositor/meta-window-actor-private.h | 5 +--- src/compositor/meta-window-actor.c | 6 ++--- src/core/window-x11.c | 6 ++--- src/meta/compositor.h | 6 +---- 5 files changed, 10 insertions(+), 41 deletions(-) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index ba3db9cb6..0fd6d6789 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -917,31 +917,7 @@ is_grabbed_event (MetaDisplay *display, } void -meta_compositor_update_shape_region (MetaCompositor *compositor, - MetaWindow *window) -{ - MetaWindowActor *window_actor; - window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - if (!window_actor) - return; - - meta_window_actor_update_shape_region (window_actor); -} - -void -meta_compositor_update_input_region (MetaCompositor *compositor, - MetaWindow *window) -{ - MetaWindowActor *window_actor; - window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - if (!window_actor) - return; - - meta_window_actor_update_input_region (window_actor); -} - -void -meta_compositor_update_opaque_region (MetaCompositor *compositor, +meta_compositor_window_shape_changed (MetaCompositor *compositor, MetaWindow *window) { MetaWindowActor *window_actor; @@ -949,7 +925,7 @@ meta_compositor_update_opaque_region (MetaCompositor *compositor, if (!window_actor) return; - meta_window_actor_update_opaque_region (window_actor); + meta_window_actor_update_shape (window_actor); } void diff --git a/src/compositor/meta-window-actor-private.h b/src/compositor/meta-window-actor-private.h index d66f1f47d..021ddc607 100644 --- a/src/compositor/meta-window-actor-private.h +++ b/src/compositor/meta-window-actor-private.h @@ -50,6 +50,7 @@ gboolean meta_window_actor_effect_in_progress (MetaWindowActor *self); void meta_window_actor_sync_actor_geometry (MetaWindowActor *self, gboolean did_placement); void meta_window_actor_sync_visibility (MetaWindowActor *self); +void meta_window_actor_update_shape (MetaWindowActor *self); void meta_window_actor_update_opacity (MetaWindowActor *self); void meta_window_actor_mapped (MetaWindowActor *self); void meta_window_actor_unmapped (MetaWindowActor *self); @@ -64,8 +65,4 @@ void meta_window_actor_effect_completed (MetaWindowActor *actor, MetaSurfaceActor *meta_window_actor_get_surface (MetaWindowActor *self); void meta_window_actor_update_surface (MetaWindowActor *self); -void meta_window_actor_update_shape_region (MetaWindowActor *self); -void meta_window_actor_update_input_region (MetaWindowActor *self); -void meta_window_actor_update_opaque_region (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 8e39be72a..99fcf7e60 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -1713,7 +1713,7 @@ build_and_scan_frame_mask (MetaWindowActor *self, g_free (mask_data); } -void +static void meta_window_actor_update_shape_region (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; @@ -1750,7 +1750,7 @@ meta_window_actor_update_shape_region (MetaWindowActor *self) meta_window_actor_invalidate_shadow (self); } -void +static void meta_window_actor_update_input_region (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; @@ -1794,7 +1794,7 @@ meta_window_actor_update_input_region (MetaWindowActor *self) cairo_region_destroy (region); } -void +static void meta_window_actor_update_opaque_region (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; diff --git a/src/core/window-x11.c b/src/core/window-x11.c index 318a81baf..6c1e7e215 100644 --- a/src/core/window-x11.c +++ b/src/core/window-x11.c @@ -261,7 +261,7 @@ meta_window_set_opaque_region (MetaWindow *window, window->opaque_region = cairo_region_reference (region); if (window->display->compositor) - meta_compositor_update_opaque_region (window->display->compositor, window); + meta_compositor_window_shape_changed (window->display->compositor, window); } void @@ -347,7 +347,7 @@ meta_window_set_input_region (MetaWindow *window, window->input_region = cairo_region_reference (region); if (window->display->compositor) - meta_compositor_update_input_region (window->display->compositor, window); + meta_compositor_window_shape_changed (window->display->compositor, window); } #if 0 @@ -454,7 +454,7 @@ meta_window_set_shape_region (MetaWindow *window, window->shape_region = cairo_region_reference (region); if (window->display->compositor) - meta_compositor_update_shape_region (window->display->compositor, window); + meta_compositor_window_shape_changed (window->display->compositor, window); } void diff --git a/src/meta/compositor.h b/src/meta/compositor.h index 022b47de6..76ad10ba8 100644 --- a/src/meta/compositor.h +++ b/src/meta/compositor.h @@ -62,11 +62,7 @@ void meta_compositor_manage_screen (MetaCompositor *compositor, void meta_compositor_unmanage_screen (MetaCompositor *compositor, MetaScreen *screen); -void meta_compositor_update_shape_region (MetaCompositor *compositor, - MetaWindow *window); -void meta_compositor_update_input_region (MetaCompositor *compositor, - MetaWindow *window); -void meta_compositor_update_opaque_region (MetaCompositor *compositor, +void meta_compositor_window_shape_changed (MetaCompositor *compositor, MetaWindow *window); void meta_compositor_window_opacity_changed (MetaCompositor *compositor, MetaWindow *window); From eb75306f8ad6b4a8a26636733f147a09f0d8493f Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 26 Feb 2014 20:52:44 -0500 Subject: [PATCH 569/889] Revert "window-actor: Complete the removal of update_shape" This reverts commit 640102c03b1e74ad481076cefe15b974ceeee052. --- src/compositor/meta-window-actor.c | 39 ++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 99fcf7e60..89c6b4e93 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -94,6 +94,7 @@ struct _MetaWindowActorPrivate guint needs_frame_drawn : 1; guint repaint_scheduled : 1; + guint needs_reshape : 1; guint recompute_focused_shadow : 1; guint recompute_unfocused_shadow : 1; @@ -142,6 +143,8 @@ static gboolean meta_window_actor_has_shadow (MetaWindowActor *self); static void meta_window_actor_handle_updates (MetaWindowActor *self); +static void check_needs_reshape (MetaWindowActor *self); + static void do_send_frame_drawn (MetaWindowActor *self, FrameData *frame); static void do_send_frame_timings (MetaWindowActor *self, FrameData *frame, @@ -234,6 +237,7 @@ surface_allocation_changed_notify (ClutterActor *actor, MetaWindowActor *self) { meta_window_actor_sync_actor_geometry (self, FALSE); + meta_window_actor_update_shape (self); } static void @@ -342,6 +346,8 @@ set_surface (MetaWindowActor *self, /* If the previous surface actor was frozen, start out * frozen as well... */ meta_surface_actor_set_frozen (priv->surface, priv->freeze_count > 0); + + meta_window_actor_update_shape (self); } } @@ -1830,6 +1836,38 @@ meta_window_actor_update_opaque_region (MetaWindowActor *self) cairo_region_destroy (opaque_region); } +static void +check_needs_reshape (MetaWindowActor *self) +{ + MetaWindowActorPrivate *priv = self->priv; + + if (!priv->needs_reshape) + return; + + meta_window_actor_update_shape_region (self); + + if (priv->window->client_type == META_WINDOW_CLIENT_TYPE_X11) + { + meta_window_actor_update_input_region (self); + meta_window_actor_update_opaque_region (self); + } + + priv->needs_reshape = FALSE; +} + +void +meta_window_actor_update_shape (MetaWindowActor *self) +{ + MetaWindowActorPrivate *priv = self->priv; + + priv->needs_reshape = TRUE; + + if (is_frozen (self)) + return; + + clutter_actor_queue_redraw (CLUTTER_ACTOR (priv->surface)); +} + static void meta_window_actor_handle_updates (MetaWindowActor *self) { @@ -1850,6 +1888,7 @@ meta_window_actor_handle_updates (MetaWindowActor *self) if (!meta_surface_actor_is_visible (priv->surface)) return; + check_needs_reshape (self); check_needs_shadow (self); } From 75184d4c5582ef593c56bb77f3a88a7742e91816 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 25 Feb 2014 19:48:34 -0500 Subject: [PATCH 570/889] display: Simplify checks to see if a window is the root window --- src/core/display.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/core/display.c b/src/core/display.c index 1ea1cc728..c1933158f 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -2314,10 +2314,13 @@ handle_input_xevent (MetaDisplay *display, Window modified; MetaWindow *window; gboolean frame_was_receiver; + MetaScreen *screen; if (input_event == NULL) return FALSE; + screen = meta_display_screen_for_root (display, device_event->root); + modified = xievent_get_modified_window (display, input_event); window = modified != None ? meta_display_lookup_x_window (display, modified) : NULL; @@ -2382,13 +2385,10 @@ handle_input_xevent (MetaDisplay *display, "none")); if (GRAB_OP_IS_WINDOW_SWITCH (display->grab_op)) { - MetaScreen *screen; meta_topic (META_DEBUG_WINDOW_OPS, "Syncing to old stack positions.\n"); - screen = - meta_display_screen_for_root (display, device_event->event); - if (screen!=NULL) + if (device_event->root == device_event->event) meta_stack_set_positions (screen->stack, display->grab_old_window_stacking); } @@ -2612,10 +2612,7 @@ handle_input_xevent (MetaDisplay *display, if (!window) { /* Check if the window is a root window. */ - MetaScreen *screen = - meta_display_screen_for_root(display, - enter_event->event); - if (screen == NULL) + if (enter_event->root == enter_event->event) break; if (enter_event->evtype == XI_FocusIn && From da13e3d237d6ddb48e925186c9a02fde68076b94 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 25 Feb 2014 19:41:18 -0500 Subject: [PATCH 571/889] display: Return TRUE when we've handled an X event appropriately We need to do this to make sure events aren't improperly sent to Clutter in the next commit. --- src/core/display.c | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/src/core/display.c b/src/core/display.c index c1933158f..65be8825e 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -2486,17 +2486,20 @@ handle_input_xevent (MetaDisplay *display, op = META_GRAB_OP_NONE; if (op != META_GRAB_OP_NONE) - meta_display_begin_grab_op (display, - window->screen, - window, - op, - TRUE, - FALSE, - device_event->detail, - 0, - device_event->time, - device_event->root_x, - device_event->root_y); + { + meta_display_begin_grab_op (display, + window->screen, + window, + op, + TRUE, + FALSE, + device_event->detail, + 0, + device_event->time, + device_event->root_x, + device_event->root_y); + return TRUE; + } } } else if (device_event->detail == meta_prefs_get_mouse_button_menu()) @@ -2508,6 +2511,7 @@ handle_input_xevent (MetaDisplay *display, device_event->root_y, device_event->detail, device_event->time); + return TRUE; } if (!frame_was_receiver && unmodified) @@ -2536,6 +2540,7 @@ handle_input_xevent (MetaDisplay *display, device_event->time, device_event->root_x, device_event->root_y); + return TRUE; } } break; @@ -2547,7 +2552,10 @@ handle_input_xevent (MetaDisplay *display, if (display->grab_window == window && meta_grab_op_is_mouse (display->grab_op)) - meta_window_handle_mouse_grab_op_xevent (window, device_event); + { + meta_window_handle_mouse_grab_op_xevent (window, device_event); + return TRUE; + } break; case XI_Motion: if (display->grab_op == META_GRAB_OP_COMPOSITOR) @@ -2555,7 +2563,10 @@ handle_input_xevent (MetaDisplay *display, if (display->grab_window == window && meta_grab_op_is_mouse (display->grab_op)) - meta_window_handle_mouse_grab_op_xevent (window, device_event); + { + meta_window_handle_mouse_grab_op_xevent (window, device_event); + return TRUE; + } break; case XI_Enter: if (display->grab_op == META_GRAB_OP_COMPOSITOR) @@ -2640,7 +2651,9 @@ handle_input_xevent (MetaDisplay *display, } } - break; + + /* Don't send FocusIn / FocusOut to Clutter */ + return TRUE; } return FALSE; From 7f195aec7a9f5d86464013db94f23db91abc2283 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 25 Feb 2014 19:20:45 -0500 Subject: [PATCH 572/889] display: Don't grab the window actor's key focus This breaks gnome-shell's actor tracking code. --- src/core/display.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/core/display.c b/src/core/display.c index 65be8825e..da05ca836 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -1785,19 +1785,9 @@ update_focus_window (MetaDisplay *display, if (display->focus_window) { - ClutterActor *window_actor; - meta_topic (META_DEBUG_FOCUS, "* Focus --> %s with serial %lu\n", display->focus_window->desc, serial); meta_window_set_focused_internal (display->focus_window, TRUE); - - /* XXX -- this is sort of a layer violation, but because we - * rely on the compositor for event delivery anyway, I don't - * think it's too bad... */ - - window_actor = CLUTTER_ACTOR (display->focus_window->compositor_private); - if (window_actor) - clutter_actor_grab_key_focus (window_actor); } else meta_topic (META_DEBUG_FOCUS, "* Focus --> NULL with serial %lu\n", serial); From 23b0f7be4377fdbe026edfede6e237591cc3c72d Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 25 Feb 2014 19:44:18 -0500 Subject: [PATCH 573/889] display: Always use the key focused window for key events We no longer grab the actor's key focus, so this is necessary. --- src/core/display.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/core/display.c b/src/core/display.c index da05ca836..4d5631f1a 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -1682,6 +1682,16 @@ get_window_for_event (MetaDisplay *display, if (display->grab_op != META_GRAB_OP_NONE) return display->grab_window; + /* Always use the key focused window for key events. */ + switch (event->type) + { + case CLUTTER_KEY_PRESS: + case CLUTTER_KEY_RELEASE: + return display->focus_window; + default: + break; + } + source = clutter_event_get_source (event); if (META_IS_SURFACE_ACTOR_WAYLAND (source)) { From ed6821a819bd632a8dfe9ae30b1cac94341b71cd Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Wed, 26 Feb 2014 18:56:17 +0100 Subject: [PATCH 574/889] keybindings: fix per window keybindings We must spoof events to clutter even if they are associated with a MetaWindow, because keyboard events are always associated with one (the focus window), and we must process keybindings for window togheter with the global ones if they include Super, because we're not going to see them again. --- src/compositor/compositor.c | 57 ++++++++++--------------------------- src/core/keybindings.c | 16 +++++------ 2 files changed, 22 insertions(+), 51 deletions(-) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 0fd6d6789..8982bbd08 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -971,24 +971,22 @@ maybe_spoof_event_as_stage_event (MetaCompScreen *info, event->xcookie.extension == display->xinput_opcode) { XIEvent *input_event = (XIEvent *) event->xcookie.data; + XIDeviceEvent *device_event = ((XIDeviceEvent *) input_event); switch (input_event->evtype) { case XI_Motion: case XI_ButtonPress: case XI_ButtonRelease: - case XI_KeyPress: - case XI_KeyRelease: - { - XIDeviceEvent *device_event = ((XIDeviceEvent *) input_event); - /* If this is a GTK+ widget, like a window menu, let GTK+ handle * it as-is without mangling. */ if (meta_ui_window_is_widget (info->screen->ui, device_event->event)) break; + /* fall through */ + case XI_KeyPress: + case XI_KeyRelease: device_event->event = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage)); - } break; default: break; @@ -1008,6 +1006,12 @@ meta_compositor_process_event (MetaCompositor *compositor, XEvent *event, MetaWindow *window) { + MetaDisplay *display = compositor->display; + MetaScreen *screen = display->screens->data; + MetaCompScreen *info; + + info = meta_screen_get_compositor_data (screen); + if (compositor->modal_plugin && is_grabbed_event (compositor->display, event)) { _meta_plugin_xevent_filter (compositor->modal_plugin, event); @@ -1017,43 +1021,12 @@ meta_compositor_process_event (MetaCompositor *compositor, return TRUE; } - if (window) + maybe_spoof_event_as_stage_event (info, event); + + if (meta_plugin_manager_xevent_filter (info->plugin_mgr, event)) { - MetaCompScreen *info; - MetaScreen *screen; - - screen = meta_window_get_screen (window); - info = meta_screen_get_compositor_data (screen); - - if (meta_plugin_manager_xevent_filter (info->plugin_mgr, event)) - { - DEBUG_TRACE ("meta_compositor_process_event (filtered,window==NULL)\n"); - return TRUE; - } - } - else - { - GSList *l; - - l = meta_display_get_screens (compositor->display); - - while (l) - { - MetaScreen *screen = l->data; - MetaCompScreen *info; - - info = meta_screen_get_compositor_data (screen); - - maybe_spoof_event_as_stage_event (info, event); - - if (meta_plugin_manager_xevent_filter (info->plugin_mgr, event)) - { - DEBUG_TRACE ("meta_compositor_process_event (filtered,window==NULL)\n"); - return TRUE; - } - - l = l->next; - } + DEBUG_TRACE ("meta_compositor_process_event (filtered,window==NULL)\n"); + return TRUE; } if (!meta_is_wayland_compositor () && diff --git a/src/core/keybindings.c b/src/core/keybindings.c index db2db7687..bf33587df 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -1842,8 +1842,7 @@ process_event (MetaKeyBinding *bindings, MetaDisplay *display, MetaScreen *screen, MetaWindow *window, - ClutterKeyEvent *event, - gboolean on_window) + ClutterKeyEvent *event) { int i; @@ -1859,7 +1858,7 @@ process_event (MetaKeyBinding *bindings, { MetaKeyHandler *handler = bindings[i].handler; - if ((!on_window && handler->flags & META_KEY_BINDING_PER_WINDOW) || + if ((!window && handler->flags & META_KEY_BINDING_PER_WINDOW) || (event->keyval != bindings[i].keysym) || (event->modifier_state != bindings[i].mask) || meta_compositor_filter_keybinding (display->compositor, screen, &bindings[i])) @@ -1891,7 +1890,8 @@ process_event (MetaKeyBinding *bindings, static gboolean process_overlay_key (MetaDisplay *display, MetaScreen *screen, - ClutterKeyEvent *event) + ClutterKeyEvent *event, + MetaWindow *window) { if (display->overlay_key_only_pressed) { @@ -1913,8 +1913,7 @@ process_overlay_key (MetaDisplay *display, */ if (process_event (display->key_bindings, display->n_key_bindings, - display, screen, NULL, event, - FALSE)) + display, screen, window, event)) { /* As normally, after we've handled a global key * binding, we unfreeze the keyboard but keep the grab @@ -2056,7 +2055,7 @@ meta_display_process_key_event (MetaDisplay *display, all_keys_grabbed = window ? window->all_keys_grabbed : screen->all_keys_grabbed; if (!all_keys_grabbed) { - handled = process_overlay_key (display, screen, event); + handled = process_overlay_key (display, screen, event, window); if (handled) return TRUE; @@ -2150,8 +2149,7 @@ meta_display_process_key_event (MetaDisplay *display, /* Do the normal keybindings */ return process_event (display->key_bindings, display->n_key_bindings, - display, screen, window, event, - !all_keys_grabbed && window); + display, screen, window, event); } static gboolean From 394b44a2c28f03eff410c99daecf2ee113effbe8 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Wed, 26 Feb 2014 23:46:08 +0100 Subject: [PATCH 575/889] compositor: fix mouse interactions on frames meta_ui_window_is_widget() returns FALSE for frame windows, so we must filter those explicitly (by letting the event go to gtk and from there to MetaFrames). Also, for proper gtk widgets (window menus) we want to let gtk see all events, including keyboard, otherwise we break keynav in the window menu. This means that having a window menu open disables keybindings (because the event doesn't run through clutter) --- src/compositor/compositor.c | 13 +++++++++---- src/compositor/meta-surface-actor-x11.c | 1 + 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 8982bbd08..bb2092f0d 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -76,6 +76,7 @@ #include "window-private.h" /* to check window->hidden */ #include "display-private.h" /* for meta_display_lookup_x_window() */ #include "util-private.h" +#include "frame.h" #include "meta-wayland-private.h" #include "meta-wayland-pointer.h" #include "meta-wayland-keyboard.h" @@ -963,6 +964,7 @@ meta_compositor_window_surface_changed (MetaCompositor *compositor, */ static void maybe_spoof_event_as_stage_event (MetaCompScreen *info, + MetaWindow *window, XEvent *event) { MetaDisplay *display = meta_screen_get_display (info->screen); @@ -978,14 +980,17 @@ maybe_spoof_event_as_stage_event (MetaCompScreen *info, case XI_Motion: case XI_ButtonPress: case XI_ButtonRelease: + /* If this is a window frame, let GTK+ handle it without mangling */ + if (window && window->frame && device_event->event == window->frame->xwindow) + break; + + case XI_KeyPress: + case XI_KeyRelease: /* If this is a GTK+ widget, like a window menu, let GTK+ handle * it as-is without mangling. */ if (meta_ui_window_is_widget (info->screen->ui, device_event->event)) break; - /* fall through */ - case XI_KeyPress: - case XI_KeyRelease: device_event->event = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage)); break; default: @@ -1021,7 +1026,7 @@ meta_compositor_process_event (MetaCompositor *compositor, return TRUE; } - maybe_spoof_event_as_stage_event (info, event); + maybe_spoof_event_as_stage_event (info, window, event); if (meta_plugin_manager_xevent_filter (info->plugin_mgr, event)) { diff --git a/src/compositor/meta-surface-actor-x11.c b/src/compositor/meta-surface-actor-x11.c index 020c84734..cc2f0a5ba 100644 --- a/src/compositor/meta-surface-actor-x11.c +++ b/src/compositor/meta-surface-actor-x11.c @@ -456,6 +456,7 @@ meta_surface_actor_x11_new (MetaWindow *window) priv->unredirected = FALSE; sync_unredirected (self); + clutter_actor_set_reactive (CLUTTER_ACTOR (self), TRUE); return META_SURFACE_ACTOR (self); } From 360d423faa6bea315378b9940e0a210b2dd4b749 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Thu, 27 Feb 2014 02:21:51 +0100 Subject: [PATCH 576/889] MetaSurfaceActor: add a generic hook to retrieve the MetaWindow This way we can find the window for a ClutterEvent even when running as an x11 compositor. --- src/compositor/meta-surface-actor-wayland.c | 10 ++++++++++ src/compositor/meta-surface-actor-x11.c | 10 ++++++++++ src/compositor/meta-surface-actor.c | 6 ++++++ src/compositor/meta-surface-actor.h | 4 ++++ src/core/display.c | 8 ++------ 5 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/compositor/meta-surface-actor-wayland.c b/src/compositor/meta-surface-actor-wayland.c index 9fe1e8220..c8381930c 100644 --- a/src/compositor/meta-surface-actor-wayland.c +++ b/src/compositor/meta-surface-actor-wayland.c @@ -97,6 +97,14 @@ meta_surface_actor_wayland_is_unredirected (MetaSurfaceActor *actor) return FALSE; } +static MetaWindow * +meta_surface_actor_wayland_get_window (MetaSurfaceActor *actor) +{ + MetaSurfaceActorWaylandPrivate *priv = meta_surface_actor_wayland_get_instance_private (META_SURFACE_ACTOR_WAYLAND (actor)); + + return priv->surface->window; +} + static void meta_surface_actor_wayland_class_init (MetaSurfaceActorWaylandClass *klass) { @@ -110,6 +118,8 @@ meta_surface_actor_wayland_class_init (MetaSurfaceActorWaylandClass *klass) surface_actor_class->should_unredirect = meta_surface_actor_wayland_should_unredirect; surface_actor_class->set_unredirected = meta_surface_actor_wayland_set_unredirected; surface_actor_class->is_unredirected = meta_surface_actor_wayland_is_unredirected; + + surface_actor_class->get_window = meta_surface_actor_wayland_get_window; } static void diff --git a/src/compositor/meta-surface-actor-x11.c b/src/compositor/meta-surface-actor-x11.c index cc2f0a5ba..5cab15fd7 100644 --- a/src/compositor/meta-surface-actor-x11.c +++ b/src/compositor/meta-surface-actor-x11.c @@ -387,6 +387,14 @@ meta_surface_actor_x11_dispose (GObject *object) G_OBJECT_CLASS (meta_surface_actor_x11_parent_class)->dispose (object); } +static MetaWindow * +meta_surface_actor_x11_get_window (MetaSurfaceActor *actor) +{ + MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (META_SURFACE_ACTOR_X11 (actor)); + + return priv->window; +} + static void meta_surface_actor_x11_class_init (MetaSurfaceActorX11Class *klass) { @@ -403,6 +411,8 @@ meta_surface_actor_x11_class_init (MetaSurfaceActorX11Class *klass) surface_actor_class->should_unredirect = meta_surface_actor_x11_should_unredirect; surface_actor_class->set_unredirected = meta_surface_actor_x11_set_unredirected; surface_actor_class->is_unredirected = meta_surface_actor_x11_is_unredirected; + + surface_actor_class->get_window = meta_surface_actor_x11_get_window; } static void diff --git a/src/compositor/meta-surface-actor.c b/src/compositor/meta-surface-actor.c index 1c795d52f..1d9a7ad35 100644 --- a/src/compositor/meta-surface-actor.c +++ b/src/compositor/meta-surface-actor.c @@ -312,3 +312,9 @@ meta_surface_actor_is_unredirected (MetaSurfaceActor *self) { return META_SURFACE_ACTOR_GET_CLASS (self)->is_unredirected (self); } + +MetaWindow * +meta_surface_actor_get_window (MetaSurfaceActor *self) +{ + return META_SURFACE_ACTOR_GET_CLASS (self)->get_window (self); +} diff --git a/src/compositor/meta-surface-actor.h b/src/compositor/meta-surface-actor.h index a92f6f717..c06e1836b 100644 --- a/src/compositor/meta-surface-actor.h +++ b/src/compositor/meta-surface-actor.h @@ -6,6 +6,7 @@ #include #include +#include G_BEGIN_DECLS @@ -35,6 +36,8 @@ struct _MetaSurfaceActorClass void (* set_unredirected) (MetaSurfaceActor *actor, gboolean unredirected); gboolean (* is_unredirected) (MetaSurfaceActor *actor); + + MetaWindow *(* get_window) (MetaSurfaceActor *actor); }; struct _MetaSurfaceActor @@ -50,6 +53,7 @@ cairo_surface_t *meta_surface_actor_get_image (MetaSurfaceActor *self, cairo_rectangle_int_t *clip); MetaShapedTexture *meta_surface_actor_get_texture (MetaSurfaceActor *self); +MetaWindow *meta_surface_actor_get_window (MetaSurfaceActor *self); gboolean meta_surface_actor_is_obscured (MetaSurfaceActor *self); gboolean meta_surface_actor_get_unobscured_bounds (MetaSurfaceActor *self, diff --git a/src/core/display.c b/src/core/display.c index 4d5631f1a..9c1e72d1b 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -1693,12 +1693,8 @@ get_window_for_event (MetaDisplay *display, } source = clutter_event_get_source (event); - if (META_IS_SURFACE_ACTOR_WAYLAND (source)) - { - MetaWaylandSurface *surface = meta_surface_actor_wayland_get_surface (META_SURFACE_ACTOR_WAYLAND (source)); - g_assert (surface != NULL); - return surface->window; - } + if (META_IS_SURFACE_ACTOR (source)) + return meta_surface_actor_get_window (META_SURFACE_ACTOR (source)); return NULL; } From b00fa70d91de7be3a83a0e8e1fa8be4ad49bfe65 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Thu, 27 Feb 2014 00:51:07 +0100 Subject: [PATCH 577/889] display: move more event handling to clutter Mouse event handling was duplicated, resulting in weird interactions if clutter was allowed to see certain events (for example under wayland, where it gets all events). Because now clutter sees all X events, even when running as an x11 compositor, we can handle everything using the clutter variants. At the same time, rewrite a little the passive button grab code, to make it clear what is being matched on what and why. --- src/compositor/compositor.c | 31 ++- src/core/display.c | 363 +++++++----------------------------- 2 files changed, 95 insertions(+), 299 deletions(-) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index bb2092f0d..684a953dc 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -953,6 +953,29 @@ meta_compositor_window_surface_changed (MetaCompositor *compositor, meta_window_actor_update_surface (window_actor); } +static gboolean +grab_op_is_clicking (MetaGrabOp grab_op) +{ + switch (grab_op) + { + case META_GRAB_OP_CLICKING_MINIMIZE: + case META_GRAB_OP_CLICKING_MAXIMIZE: + case META_GRAB_OP_CLICKING_UNMAXIMIZE: + case META_GRAB_OP_CLICKING_DELETE: + case META_GRAB_OP_CLICKING_MENU: + case META_GRAB_OP_CLICKING_SHADE: + case META_GRAB_OP_CLICKING_UNSHADE: + case META_GRAB_OP_CLICKING_ABOVE: + case META_GRAB_OP_CLICKING_UNABOVE: + case META_GRAB_OP_CLICKING_STICK: + case META_GRAB_OP_CLICKING_UNSTICK: + return TRUE; + + default: + return FALSE; + } +} + /* Clutter makes the assumption that there is only one X window * per stage, which is a valid assumption to make for a generic * application toolkit. As such, it will ignore any events sent @@ -980,8 +1003,10 @@ maybe_spoof_event_as_stage_event (MetaCompScreen *info, case XI_Motion: case XI_ButtonPress: case XI_ButtonRelease: - /* If this is a window frame, let GTK+ handle it without mangling */ - if (window && window->frame && device_event->event == window->frame->xwindow) + /* If this is a window frame, and we think GTK+ needs to handle the event, + let GTK+ handle it without mangling */ + if (window && window->frame && device_event->event == window->frame->xwindow && + (display->grab_op == META_GRAB_OP_NONE || grab_op_is_clicking (display->grab_op))) break; case XI_KeyPress: @@ -992,6 +1017,8 @@ maybe_spoof_event_as_stage_event (MetaCompScreen *info, break; device_event->event = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage)); + device_event->event_x = device_event->root_x; + device_event->event_y = device_event->root_y; break; default: break; diff --git a/src/core/display.c b/src/core/display.c index 9c1e72d1b..3631eebf0 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -2036,9 +2036,6 @@ meta_display_handle_event (MetaDisplay *display, gboolean bypass_clutter = FALSE, bypass_wayland = FALSE; MetaWaylandCompositor *compositor = NULL; - /* XXX -- we need to fill this in properly at some point... */ - gboolean frame_was_receiver = FALSE; - if (meta_is_wayland_compositor ()) { compositor = meta_wayland_compositor_get_default (); @@ -2109,60 +2106,70 @@ meta_display_handle_event (MetaDisplay *display, } else if (window && display->grab_op == META_GRAB_OP_NONE) { - gboolean begin_move = FALSE; ClutterModifierType grab_mask; gboolean unmodified; + gboolean fully_modified; grab_mask = display->window_grab_modifiers; if (g_getenv ("MUTTER_DEBUG_BUTTON_GRABS")) grab_mask |= CLUTTER_CONTROL_MASK; - /* Two possible sources of an unmodified event; one is a - * client that's letting button presses pass through to the - * frame, the other is our focus_window_grab on unmodified - * button 1. So for all such events we focus the window. + /* We have three passive button grabs: + * - on any button, without modifiers => focuses and maybe raises the window + * - on resize button, with modifiers => start an interactive resizing + * (normally middle) + * - on move button, with modifiers => start an interactive move + * (normally left) + * - on menu button, with modifiers => show the window menu + * (normally right) + * + * We may get here because we actually have a button + * grab on the window, or because we're a wayland + * compositor and thus we see all the events, so we + * need to check if the event is interesting. + * We want an event that is not modified, for a window + * that has (or would have, the wayland case) the + * button grab active. + * + * We may have other events on the window, for example + * a click on a frame button, but that's not for us to + * care about. Just let the event through. */ unmodified = (event->button.modifier_state & grab_mask) == 0; + fully_modified = (event->button.modifier_state & grab_mask) == grab_mask; - if (unmodified || - event->button.button == 1) + if (unmodified && window && window->have_focus_click_grab) { - /* don't focus if frame received, will be lowered in - * frames.c or special-cased if the click was on a - * minimize/close button. + if (meta_prefs_get_raise_on_click ()) + meta_window_raise (window); + else + meta_topic (META_DEBUG_FOCUS, + "Not raising window on click due to don't-raise-on-click option\n"); + + /* Don't focus panels--they must explicitly request focus. + * See bug 160470 */ - if (!frame_was_receiver) + if (window->type != META_WINDOW_DOCK) { - if (meta_prefs_get_raise_on_click ()) - meta_window_raise (window); - else - meta_topic (META_DEBUG_FOCUS, - "Not raising window on click due to don't-raise-on-click option\n"); - - /* Don't focus panels--they must explicitly request focus. - * See bug 160470 - */ - if (window->type != META_WINDOW_DOCK) - { - meta_topic (META_DEBUG_FOCUS, - "Focusing %s due to unmodified button %u press (display.c)\n", - window->desc, event->button.button); - meta_window_focus (window, event->any.time); - } - else - /* However, do allow terminals to lose focus due to new - * window mappings after the user clicks on a panel. - */ - display->allow_terminal_deactivation = TRUE; + meta_topic (META_DEBUG_FOCUS, + "Focusing %s due to unmodified button %u press (display.c)\n", + window->desc, event->button.button); + meta_window_focus (window, event->any.time); } + else + /* However, do allow terminals to lose focus due to new + * window mappings after the user clicks on a panel. + */ + display->allow_terminal_deactivation = TRUE; - /* you can move on alt-click but not on - * the click-to-focus - */ - if (!unmodified) - begin_move = TRUE; + meta_verbose ("Allowing events time %u\n", + (unsigned int)event->button.time); + + XIAllowEvents (display->xdisplay, clutter_input_device_get_device_id (event->button.device), + XIReplayDevice, event->button.time); + bypass_clutter = TRUE; } - else if (!unmodified && ((int) event->button.button == meta_prefs_get_mouse_button_resize ())) + else if (fully_modified && (int) event->button.button == meta_prefs_get_mouse_button_resize ()) { if (window->has_resize_func) { @@ -2210,8 +2217,10 @@ meta_display_handle_event (MetaDisplay *display, event->button.x, event->button.y); } + bypass_clutter = TRUE; + bypass_wayland = TRUE; } - else if ((int) event->button.button == meta_prefs_get_mouse_button_menu ()) + else if (fully_modified && (int) event->button.button == meta_prefs_get_mouse_button_menu ()) { if (meta_prefs_get_raise_on_click ()) meta_window_raise (window); @@ -2223,20 +2232,22 @@ meta_display_handle_event (MetaDisplay *display, bypass_clutter = TRUE; bypass_wayland = TRUE; } - - if (begin_move && window->has_move_func) + else if (fully_modified && (int) event->button.button == 1) { - meta_display_begin_grab_op (display, - window->screen, - window, - META_GRAB_OP_MOVING, - TRUE, - FALSE, - event->button.button, - 0, - event->any.time, - event->button.x, - event->button.y); + if (window->has_move_func) + { + meta_display_begin_grab_op (display, + window->screen, + window, + META_GRAB_OP_MOVING, + TRUE, + FALSE, + event->button.button, + 0, + event->any.time, + event->button.x, + event->button.y); + } bypass_clutter = TRUE; bypass_wayland = TRUE; } @@ -2320,250 +2331,8 @@ handle_input_xevent (MetaDisplay *display, modified = xievent_get_modified_window (display, input_event); window = modified != None ? meta_display_lookup_x_window (display, modified) : NULL; - frame_was_receiver = FALSE; - if (window && - window->frame && - modified == window->frame->xwindow) - { - /* Note that if the frame and the client both have an - * XGrabButton (as is normal with our setup), the event - * goes to the frame. - */ - frame_was_receiver = TRUE; - meta_topic (META_DEBUG_EVENTS, "Frame was receiver of event for %s\n", - window->desc); - } - - if (window && !window->override_redirect && - (input_event->evtype == XI_KeyPress || input_event->evtype == XI_ButtonPress)) - { - if (CurrentTime == display->current_time) - { - /* We can't use missing (i.e. invalid) timestamps to set user time, - * nor do we want to use them to sanity check other timestamps. - * See bug 313490 for more details. - */ - meta_warning ("Event has no timestamp! You may be using a broken " - "program such as xse. Please ask the authors of that " - "program to fix it.\n"); - } - else - { - meta_window_set_user_time (window, display->current_time); - sanity_check_timestamps (display, display->current_time); - } - } - switch (input_event->evtype) { - 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 ((window && - meta_grab_op_is_mouse (display->grab_op) && - (device_event->mods.effective & display->window_grab_modifiers) && - display->grab_button != device_event->detail && - display->grab_window == window) || - grab_op_is_keyboard (display->grab_op)) - { - meta_topic (META_DEBUG_WINDOW_OPS, - "Ending grab op %u on window %s due to button press\n", - display->grab_op, - (display->grab_window ? - display->grab_window->desc : - "none")); - if (GRAB_OP_IS_WINDOW_SWITCH (display->grab_op)) - { - meta_topic (META_DEBUG_WINDOW_OPS, - "Syncing to old stack positions.\n"); - - if (device_event->root == device_event->event) - meta_stack_set_positions (screen->stack, - display->grab_old_window_stacking); - } - meta_display_end_grab_op (display, - device_event->time); - } - else if (window && display->grab_op == META_GRAB_OP_NONE) - { - gboolean begin_move = FALSE; - unsigned int grab_mask; - gboolean unmodified; - - grab_mask = display->window_grab_modifiers; - if (g_getenv ("MUTTER_DEBUG_BUTTON_GRABS")) - grab_mask |= ControlMask; - - /* Two possible sources of an unmodified event; one is a - * client that's letting button presses pass through to the - * frame, the other is our focus_window_grab on unmodified - * button 1. So for all such events we focus the window. - */ - unmodified = (device_event->mods.effective & grab_mask) == 0; - - if (unmodified || - device_event->detail == 1) - { - /* don't focus if frame received, will be lowered in - * frames.c or special-cased if the click was on a - * minimize/close button. - */ - if (!frame_was_receiver) - { - if (meta_prefs_get_raise_on_click ()) - meta_window_raise (window); - else - meta_topic (META_DEBUG_FOCUS, - "Not raising window on click due to don't-raise-on-click option\n"); - - /* Don't focus panels--they must explicitly request focus. - * See bug 160470 - */ - if (window->type != META_WINDOW_DOCK) - { - meta_topic (META_DEBUG_FOCUS, - "Focusing %s due to unmodified button %u press (display.c)\n", - window->desc, device_event->detail); - meta_window_focus (window, device_event->time); - } - else - /* However, do allow terminals to lose focus due to new - * window mappings after the user clicks on a panel. - */ - display->allow_terminal_deactivation = TRUE; - } - - /* you can move on alt-click but not on - * the click-to-focus - */ - if (!unmodified) - begin_move = TRUE; - } - else if (!unmodified && device_event->detail == meta_prefs_get_mouse_button_resize()) - { - if (window->has_resize_func) - { - gboolean north, south; - gboolean west, east; - MetaRectangle frame_rect; - MetaGrabOp op; - - meta_window_get_frame_rect (window, &frame_rect); - - west = device_event->root_x < (frame_rect.x + 1 * frame_rect.width / 3); - east = device_event->root_x > (frame_rect.x + 2 * frame_rect.width / 3); - north = device_event->root_y < (frame_rect.y + 1 * frame_rect.height / 3); - south = device_event->root_y > (frame_rect.y + 2 * frame_rect.height / 3); - - if (north && west) - op = META_GRAB_OP_RESIZING_NW; - else if (north && east) - op = META_GRAB_OP_RESIZING_NE; - else if (south && west) - op = META_GRAB_OP_RESIZING_SW; - else if (south && east) - op = META_GRAB_OP_RESIZING_SE; - else if (north) - op = META_GRAB_OP_RESIZING_N; - else if (west) - op = META_GRAB_OP_RESIZING_W; - else if (east) - op = META_GRAB_OP_RESIZING_E; - else if (south) - op = META_GRAB_OP_RESIZING_S; - else /* Middle region is no-op to avoid user triggering wrong action */ - op = META_GRAB_OP_NONE; - - if (op != META_GRAB_OP_NONE) - { - meta_display_begin_grab_op (display, - window->screen, - window, - op, - TRUE, - FALSE, - device_event->detail, - 0, - device_event->time, - device_event->root_x, - device_event->root_y); - return TRUE; - } - } - } - else if (device_event->detail == 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, - device_event->time); - return TRUE; - } - - if (!frame_was_receiver && unmodified) - { - /* This is from our synchronous grab since - * it has no modifiers and was on the client window - */ - - meta_verbose ("Allowing events time %u\n", - (unsigned int)device_event->time); - - XIAllowEvents (display->xdisplay, device_event->deviceid, - XIReplayDevice, device_event->time); - } - - if (begin_move && window->has_move_func) - { - meta_display_begin_grab_op (display, - window->screen, - window, - META_GRAB_OP_MOVING, - TRUE, - FALSE, - device_event->detail, - 0, - device_event->time, - device_event->root_x, - device_event->root_y); - return TRUE; - } - } - break; - case XI_ButtonRelease: - if (display->grab_op == META_GRAB_OP_COMPOSITOR) - break; - - display->overlay_key_only_pressed = FALSE; - - if (display->grab_window == window && - meta_grab_op_is_mouse (display->grab_op)) - { - meta_window_handle_mouse_grab_op_xevent (window, device_event); - return TRUE; - } - break; - case XI_Motion: - if (display->grab_op == META_GRAB_OP_COMPOSITOR) - break; - - if (display->grab_window == window && - meta_grab_op_is_mouse (display->grab_op)) - { - meta_window_handle_mouse_grab_op_xevent (window, device_event); - return TRUE; - } - break; case XI_Enter: if (display->grab_op == META_GRAB_OP_COMPOSITOR) break; From 65dd54a4dba379a1fe48cb206553ead697eb2aca Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Thu, 27 Feb 2014 14:27:21 +0100 Subject: [PATCH 578/889] compositor: don't spoof events when running as a wayland compositor Weirdly, clutter stopped segfaulting when we call clutter_x11 methods and the backend is not right, but this is correct anyway, and probably fixes some BadDrawable errors in mutter-wayland on x11, caused by mixing windows of the outer X and windows of Xwayland. --- src/compositor/compositor.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 684a953dc..c7a2959fa 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -1053,7 +1053,8 @@ meta_compositor_process_event (MetaCompositor *compositor, return TRUE; } - maybe_spoof_event_as_stage_event (info, window, event); + if (!meta_is_wayland_compositor ()) + maybe_spoof_event_as_stage_event (info, window, event); if (meta_plugin_manager_xevent_filter (info->plugin_mgr, event)) { From b9a5d710b7ee0999df3e536d78ca4d7e858fbbff Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Thu, 27 Feb 2014 14:37:48 +0100 Subject: [PATCH 579/889] compositor: always redirect passive button grabs to clutter All WM events (passive button grabs and passive keyboard grabs) are handled through clutter now, so we must make sure we spoof them even if they happen on frames (because that's where we grab on) --- src/compositor/compositor.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index c7a2959fa..52c0db8c8 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -976,6 +976,28 @@ grab_op_is_clicking (MetaGrabOp grab_op) } } +static gboolean +event_is_passive_button_grab (MetaDisplay *display, + XIDeviceEvent *device_event) +{ + /* see display.c for which events are passive button + grabs (meta_display_grab_window_buttons() and + meta_display_handle_events()) + we need to filter them here because normally they + would be sent to gtk+ (they are on gtk+ frame xwindow), + but we want to redirect them to clutter + */ + + if (device_event->evtype != XI_ButtonPress) + return FALSE; + + if ((device_event->mods.effective & display->window_grab_modifiers) != + display->window_grab_modifiers) + return FALSE; + + return device_event->detail < 4; +} + /* Clutter makes the assumption that there is only one X window * per stage, which is a valid assumption to make for a generic * application toolkit. As such, it will ignore any events sent @@ -1006,7 +1028,8 @@ maybe_spoof_event_as_stage_event (MetaCompScreen *info, /* If this is a window frame, and we think GTK+ needs to handle the event, let GTK+ handle it without mangling */ if (window && window->frame && device_event->event == window->frame->xwindow && - (display->grab_op == META_GRAB_OP_NONE || grab_op_is_clicking (display->grab_op))) + (grab_op_is_clicking (display->grab_op) || + (display->grab_op == META_GRAB_OP_NONE && !event_is_passive_button_grab (display, device_event)))) break; case XI_KeyPress: From 89aa5df711693f8f382427900711bd9979b6f945 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Thu, 27 Feb 2014 14:45:10 +0100 Subject: [PATCH 580/889] display: fix inverted check from 75184d4c5582ef593c56bb77f3a88a7742e91816 I noticed it, Jasper noticed it, we agreed to change it, and then I forgot to do it before pushing... --- src/core/display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/display.c b/src/core/display.c index 3631eebf0..2ae5db457 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -2388,7 +2388,7 @@ handle_input_xevent (MetaDisplay *display, if (!window) { /* Check if the window is a root window. */ - if (enter_event->root == enter_event->event) + if (enter_event->root != enter_event->event) break; if (enter_event->evtype == XI_FocusIn && From 5c99eae8a9ca04f5e89e60a314d3e19c7ef0a715 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Thu, 27 Feb 2014 14:56:55 +0100 Subject: [PATCH 581/889] display: clean up event handling The only events we handle as XIEvents are FocusIn/Out, Enter and Leave. Motion, ButtonPress/Release, KeyPress/Release are handled through clutter instead. Among other things, this means we don't need to fake motion compression by peeking over gdk event queue... --- src/core/display-private.h | 1 - src/core/display.c | 68 +------------- src/core/window.c | 182 ------------------------------------- 3 files changed, 2 insertions(+), 249 deletions(-) diff --git a/src/core/display-private.h b/src/core/display-private.h index 4bd95cb1d..8973a59e3 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -215,7 +215,6 @@ struct _MetaDisplay gboolean grab_threshold_movement_reached; /* raise_on_click == FALSE. */ MetaResizePopup *grab_resize_popup; GTimeVal grab_last_moveresize_time; - guint32 grab_motion_notify_time; GList* grab_old_window_stacking; MetaEdgeResistanceData *grab_edge_resistance_data; unsigned int grab_last_user_action_was_snap; diff --git a/src/core/display.c b/src/core/display.c index 2ae5db457..778f54d8f 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -1715,17 +1715,6 @@ get_input_event (MetaDisplay *display, switch (input_event->evtype) { - case XI_Motion: - case XI_ButtonPress: - case XI_ButtonRelease: - if (((XIDeviceEvent *) input_event)->deviceid == META_VIRTUAL_CORE_POINTER_ID) - return input_event; - break; - case XI_KeyPress: - case XI_KeyRelease: - if (((XIDeviceEvent *) input_event)->deviceid == META_VIRTUAL_CORE_KEYBOARD_ID) - return input_event; - break; case XI_FocusIn: case XI_FocusOut: if (((XIEnterEvent *) input_event)->deviceid == META_VIRTUAL_CORE_KEYBOARD_ID) @@ -2316,18 +2305,14 @@ handle_input_xevent (MetaDisplay *display, XIEvent *input_event, gulong serial) { - XIDeviceEvent *device_event = (XIDeviceEvent *) input_event; XIEnterEvent *enter_event = (XIEnterEvent *) input_event; Window modified; MetaWindow *window; - gboolean frame_was_receiver; MetaScreen *screen; if (input_event == NULL) return FALSE; - screen = meta_display_screen_for_root (display, device_event->root); - modified = xievent_get_modified_window (display, input_event); window = modified != None ? meta_display_lookup_x_window (display, modified) : NULL; @@ -2391,6 +2376,8 @@ handle_input_xevent (MetaDisplay *display, if (enter_event->root != enter_event->event) break; + screen = meta_display_screen_for_root (display, enter_event->root); + if (enter_event->evtype == XI_FocusIn && enter_event->mode == XINotifyDetailNone) { @@ -3138,12 +3125,6 @@ xievent_get_modified_window (MetaDisplay *display, { switch (input_event->evtype) { - case XI_Motion: - case XI_ButtonPress: - case XI_ButtonRelease: - case XI_KeyPress: - case XI_KeyRelease: - return ((XIDeviceEvent *) input_event)->event; case XI_FocusIn: case XI_FocusOut: case XI_Enter: @@ -3412,26 +3393,10 @@ meta_spew_xi2_event (MetaDisplay *display, const char *name = NULL; char *extra = NULL; - XIDeviceEvent *device_event = (XIDeviceEvent *) input_event; XIEnterEvent *enter_event = (XIEnterEvent *) input_event; switch (input_event->evtype) { - case XI_Motion: - name = "XI_Motion"; - break; - case XI_ButtonPress: - name = "XI_ButtonPress"; - break; - case XI_ButtonRelease: - name = "XI_ButtonRelease"; - break; - case XI_KeyPress: - name = "XI_KeyPress"; - break; - case XI_KeyRelease: - name = "XI_KeyRelease"; - break; case XI_FocusIn: name = "XI_FocusIn"; break; @@ -3456,34 +3421,6 @@ meta_spew_xi2_event (MetaDisplay *display, switch (input_event->evtype) { - case XI_Motion: - extra = g_strdup_printf ("win: 0x%lx x: %g y: %g", - device_event->event, - device_event->root_x, - device_event->root_y); - break; - case XI_ButtonPress: - case XI_ButtonRelease: - extra = g_strdup_printf ("button %u x %g y %g root 0x%lx", - device_event->detail, - device_event->root_x, - device_event->root_y, - device_event->root); - break; - case XI_KeyPress: - case XI_KeyRelease: - { - KeySym keysym; - const char *str; - - keysym = XKeycodeToKeysym (display->xdisplay, device_event->detail, 0); - - str = XKeysymToString (keysym); - - extra = g_strdup_printf ("Key '%s' state 0x%x", - str ? str : "none", device_event->mods.effective); - } - break; case XI_FocusIn: case XI_FocusOut: extra = g_strdup_printf ("detail: %s mode: %s\n", @@ -4111,7 +4048,6 @@ meta_display_begin_grab_op (MetaDisplay *display, display->grab_latest_motion_y = root_y; display->grab_last_moveresize_time.tv_sec = 0; display->grab_last_moveresize_time.tv_usec = 0; - display->grab_motion_notify_time = 0; display->grab_old_window_stacking = NULL; #ifdef HAVE_XSYNC display->grab_last_user_action_was_snap = FALSE; diff --git a/src/core/window.c b/src/core/window.c index 8bbe5c411..d917d2437 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -8521,98 +8521,6 @@ update_resize (MetaWindow *window, g_get_current_time (&window->display->grab_last_moveresize_time); } -typedef struct -{ - Window window; - int count; - guint32 last_time; -} EventScannerData; - -static Bool -find_last_time_predicate (Display *display, - XEvent *ev, - XPointer arg) -{ - EventScannerData *esd = (void*) arg; - XIEvent *xev; - - if (ev->type != GenericEvent) - return False; - - /* We are peeking into events not yet handled by GDK, - * Allocate cookie events here so we can handle XI2. - * - * GDK will handle later these events, and eventually - * free the cookie data itself. - */ - XGetEventData (display, &ev->xcookie); - xev = (XIEvent *) ev->xcookie.data; - - if (xev->evtype != XI_Motion) - return False; - - if (esd->window != ((XIDeviceEvent *) xev)->event) - return False; - - esd->count += 1; - esd->last_time = xev->time; - - return False; -} - -static gboolean -check_use_this_motion_notify (MetaWindow *window, - XIDeviceEvent *xev) -{ - EventScannerData esd; - XEvent useless; - - /* This code is copied from Owen's GDK code. */ - - if (window->display->grab_motion_notify_time != 0) - { - /* == is really the right test, but I'm all for paranoia */ - if (window->display->grab_motion_notify_time <= - xev->time) - { - meta_topic (META_DEBUG_RESIZING, - "Arrived at event with time %u (waiting for %u), using it\n", - (unsigned int)xev->time, - window->display->grab_motion_notify_time); - window->display->grab_motion_notify_time = 0; - return TRUE; - } - else - return FALSE; /* haven't reached the saved timestamp yet */ - } - - esd.window = xev->event; - esd.count = 0; - esd.last_time = 0; - - /* "useless" isn't filled in because the predicate never returns True */ - XCheckIfEvent (window->display->xdisplay, - &useless, - find_last_time_predicate, - (XPointer) &esd); - - if (esd.count > 0) - meta_topic (META_DEBUG_RESIZING, - "Will skip %d motion events and use the event with time %u\n", - esd.count, (unsigned int) esd.last_time); - - if (esd.last_time == 0) - return TRUE; - else - { - /* Save this timestamp, and ignore all motion notify - * until we get to the one with this stamp. - */ - window->display->grab_motion_notify_time = esd.last_time; - return FALSE; - } -} - static void update_tile_mode (MetaWindow *window) { @@ -8683,96 +8591,6 @@ meta_window_update_sync_request_counter (MetaWindow *window, } #endif /* HAVE_XSYNC */ -void -meta_window_handle_mouse_grab_op_xevent (MetaWindow *window, - XIDeviceEvent *xevent) -{ - gboolean is_window_root = (xevent->root == window->screen->xroot); - - switch (xevent->evtype) - { - case XI_ButtonRelease: - if (xevent->detail == 1 || - xevent->detail == meta_prefs_get_mouse_button_resize ()) - { - meta_display_check_threshold_reached (window->display, - xevent->root_x, - xevent->root_y); - /* If the user was snap moving then ignore the button - * release because they may have let go of shift before - * releasing the mouse button and they almost certainly do - * not want a non-snapped movement to occur from the button - * release. - */ - if (!window->display->grab_last_user_action_was_snap) - { - if (meta_grab_op_is_moving (window->display->grab_op)) - { - if (window->tile_mode != META_TILE_NONE) - meta_window_tile (window); - else if (is_window_root) - update_move (window, - xevent->mods.effective & ShiftMask, - xevent->root_x, - xevent->root_y); - } - else if (meta_grab_op_is_resizing (window->display->grab_op)) - { - if (is_window_root) - update_resize (window, - xevent->mods.effective & ShiftMask, - xevent->root_x, - xevent->root_y, - TRUE); - - /* If a tiled window has been dragged free with a - * mouse resize without snapping back to the tiled - * state, it will end up with an inconsistent tile - * mode on mouse release; cleaning the mode earlier - * would break the ability to snap back to the tiled - * state, so we wait until mouse release. - */ - update_tile_mode (window); - } - meta_display_end_grab_op (window->display, xevent->time); - } - } - break; - - case XI_Motion: - meta_display_check_threshold_reached (window->display, - xevent->root_x, - xevent->root_y); - if (meta_grab_op_is_moving (window->display->grab_op)) - { - if (is_window_root) - { - if (check_use_this_motion_notify (window, xevent)) - update_move (window, - xevent->mods.effective & ShiftMask, - xevent->root_x, - xevent->root_y); - } - } - else if (meta_grab_op_is_resizing (window->display->grab_op)) - { - if (is_window_root) - { - if (check_use_this_motion_notify (window, xevent)) - update_resize (window, - xevent->mods.effective & ShiftMask, - xevent->root_x, - xevent->root_y, - FALSE); - } - } - break; - - default: - break; - } -} - void meta_window_handle_mouse_grab_op_event (MetaWindow *window, const ClutterEvent *event) From 71367e14d5d73799796f0a5de2367a4a3a535285 Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Mon, 24 Feb 2014 14:35:06 +0100 Subject: [PATCH 582/889] build: Define CLUTTER_ENABLE_COMPOSITOR_API --- configure.ac | 2 +- src/Makefile.am | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index d67d7d24a..aa5c06d45 100644 --- a/configure.ac +++ b/configure.ac @@ -78,7 +78,7 @@ MUTTER_PC_MODULES=" cairo >= 1.10.0 gsettings-desktop-schemas >= 3.7.3 xcomposite >= 0.2 xfixes xrender xdamage xi >= 1.6.0 - $CLUTTER_PACKAGE >= 1.17.1 + $CLUTTER_PACKAGE >= 1.17.5 cogl-1.0 >= 1.17.1 upower-glib >= 0.99.0 gnome-desktop-3.0 diff --git a/src/Makefile.am b/src/Makefile.am index ba029b7ea..4764814f7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -6,6 +6,7 @@ lib_LTLIBRARIES = libmutter-wayland.la SUBDIRS=compositor/plugins INCLUDES= \ + -DCLUTTER_ENABLE_COMPOSITOR_API \ -DCLUTTER_ENABLE_EXPERIMENTAL_API \ -DCOGL_ENABLE_EXPERIMENTAL_API \ -DCOGL_ENABLE_EXPERIMENTAL_2_0_API \ From 268a4c92ba73e649a2a0f92e6c37491b27098ced Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 27 Feb 2014 10:32:19 -0500 Subject: [PATCH 583/889] window: Fix meta_window_get_client_area_rect The shaded logic here was backwards. --- src/core/window.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/window.c b/src/core/window.c index d917d2437..b506634de 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -5677,9 +5677,9 @@ meta_window_get_client_area_rect (const MetaWindow *window, rect->width = window->rect.width; if (window->shaded) - rect->height = window->rect.height; - else rect->height = 0; + else + rect->height = window->rect.height; } const char* From 9e51d98f4ac81e751bc53a3b1b34cbd815b83cd9 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 23 Apr 2013 12:52:25 -0400 Subject: [PATCH 584/889] Remove tabpopup and friends These are unused in gnome-shell, and add complexity. Remove them. --- src/Makefile.am | 4 - src/core/display.c | 52 -- src/core/keybindings.c | 884 +--------------------------------- src/core/prefs.c | 32 -- src/core/screen-private.h | 17 - src/core/screen.c | 250 ---------- src/meta/common.h | 15 - src/meta/prefs.h | 9 - src/ui/draw-workspace.c | 224 --------- src/ui/draw-workspace.h | 59 --- src/ui/tabpopup.c | 963 -------------------------------------- src/ui/tabpopup.h | 65 --- src/ui/ui.h | 2 - 13 files changed, 9 insertions(+), 2567 deletions(-) delete mode 100644 src/ui/draw-workspace.c delete mode 100644 src/ui/draw-workspace.h delete mode 100644 src/ui/tabpopup.c delete mode 100644 src/ui/tabpopup.h diff --git a/src/Makefile.am b/src/Makefile.am index 4764814f7..2221a5d7d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -113,8 +113,6 @@ libmutter_wayland_la_SOURCES = \ core/display.c \ core/display-private.h \ meta/display.h \ - ui/draw-workspace.c \ - ui/draw-workspace.h \ core/edge-resistance.c \ core/edge-resistance.h \ core/edid-parse.c \ @@ -185,8 +183,6 @@ libmutter_wayland_la_SOURCES = \ ui/metaaccellabel.h \ ui/resizepopup.c \ ui/resizepopup.h \ - ui/tabpopup.c \ - ui/tabpopup.h \ ui/theme-parser.c \ ui/theme.c \ meta/theme.h \ diff --git a/src/core/display.c b/src/core/display.c index 778f54d8f..b3d21d4a1 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -75,14 +75,6 @@ #include "meta-xwayland-private.h" #include "meta-surface-actor-wayland.h" -#define GRAB_OP_IS_WINDOW_SWITCH(g) \ - (g == META_GRAB_OP_KEYBOARD_TABBING_NORMAL || \ - g == META_GRAB_OP_KEYBOARD_TABBING_DOCK || \ - g == META_GRAB_OP_KEYBOARD_TABBING_GROUP || \ - g == META_GRAB_OP_KEYBOARD_ESCAPING_NORMAL || \ - g == META_GRAB_OP_KEYBOARD_ESCAPING_DOCK || \ - g == META_GRAB_OP_KEYBOARD_ESCAPING_GROUP) - /* * SECTION:pings * @@ -1375,13 +1367,6 @@ grab_op_is_keyboard (MetaGrabOp op) case META_GRAB_OP_KEYBOARD_RESIZING_NE: case META_GRAB_OP_KEYBOARD_RESIZING_SW: case META_GRAB_OP_KEYBOARD_RESIZING_NW: - case META_GRAB_OP_KEYBOARD_TABBING_NORMAL: - case META_GRAB_OP_KEYBOARD_TABBING_DOCK: - case META_GRAB_OP_KEYBOARD_TABBING_GROUP: - case META_GRAB_OP_KEYBOARD_ESCAPING_NORMAL: - case META_GRAB_OP_KEYBOARD_ESCAPING_DOCK: - case META_GRAB_OP_KEYBOARD_ESCAPING_GROUP: - case META_GRAB_OP_KEYBOARD_WORKSPACE_SWITCHING: case META_GRAB_OP_COMPOSITOR: return TRUE; @@ -2076,19 +2061,6 @@ meta_display_handle_event (MetaDisplay *display, (display->grab_window ? display->grab_window->desc : "none")); - if (GRAB_OP_IS_WINDOW_SWITCH (display->grab_op)) - { - meta_topic (META_DEBUG_WINDOW_OPS, - "Syncing to old stack positions.\n"); - - /* XXX: I'm not sure if this is the right thing to do. - The pre-Wayland code was only calling - meta_stack_set_positions if the modified window was a - root window */ - if (event->any.source == CLUTTER_ACTOR (event->any.stage) && window && window->screen) - meta_stack_set_positions (window->screen->stack, - display->grab_old_window_stacking); - } meta_display_end_grab_op (display, event->any.time); bypass_clutter = TRUE; bypass_wayland = TRUE; @@ -4084,16 +4056,6 @@ meta_display_begin_grab_op (MetaDisplay *display, g_assert (display->grab_window != NULL || display->grab_screen != NULL); g_assert (display->grab_op != META_GRAB_OP_NONE); - /* Save the old stacking */ - if (GRAB_OP_IS_WINDOW_SWITCH (display->grab_op)) - { - meta_topic (META_DEBUG_WINDOW_OPS, - "Saving old stack positions; old pointer was %p.\n", - display->grab_old_window_stacking); - display->grab_old_window_stacking = - meta_stack_get_positions (screen->stack); - } - if (display->grab_window) { meta_window_refresh_resize_popup (display->grab_window); @@ -4135,20 +4097,6 @@ meta_display_end_grab_op (MetaDisplay *display, if (!display->grab_threshold_movement_reached) meta_window_raise (display->grab_window); } - - if (GRAB_OP_IS_WINDOW_SWITCH (display->grab_op) || - display->grab_op == META_GRAB_OP_KEYBOARD_WORKSPACE_SWITCHING) - { - if (GRAB_OP_IS_WINDOW_SWITCH (display->grab_op)) - meta_screen_tab_popup_destroy (display->grab_screen); - else - meta_screen_workspace_popup_destroy (display->grab_screen); - - /* If the ungrab here causes an EnterNotify, ignore it for - * sloppy focus - */ - display->ungrab_should_not_cause_focus_window = display->grab_xwindow; - } /* If this was a move or resize clear out the edge cache */ if (meta_grab_op_is_resizing (display->grab_op) || diff --git a/src/core/keybindings.c b/src/core/keybindings.c index bf33587df..96c34024a 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -110,13 +110,6 @@ meta_key_binding_is_builtin (MetaKeyBinding *binding) * handler functions and have some kind of flag to say they're unbindable. */ -static void handle_workspace_switch (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - ClutterKeyEvent *event, - MetaKeyBinding *binding, - gpointer dummy); - static gboolean process_mouse_move_resize_grab (MetaDisplay *display, MetaScreen *screen, MetaWindow *window, @@ -132,18 +125,9 @@ static gboolean process_keyboard_resize_grab (MetaDisplay *display, MetaWindow *window, ClutterKeyEvent *event); -static gboolean process_tab_grab (MetaDisplay *display, - MetaScreen *screen, - ClutterKeyEvent *event); - -static gboolean process_workspace_switch_grab (MetaDisplay *display, - MetaScreen *screen, - ClutterKeyEvent *event); - static void grab_key_bindings (MetaDisplay *display); static void ungrab_key_bindings (MetaDisplay *display); - static GHashTable *key_handlers; static GHashTable *external_grabs; @@ -1664,140 +1648,6 @@ is_modifier (MetaDisplay *display, return retval; } -/* Indexes: - * shift = 0 - * lock = 1 - * control = 2 - * mod1 = 3 - * mod2 = 4 - * mod3 = 5 - * mod4 = 6 - * mod5 = 7 - */ - -static gboolean -is_specific_modifier (MetaDisplay *display, - unsigned int keycode, - unsigned int mask) -{ - int i; - int end; - gboolean retval = FALSE; - int mod_index; - - g_assert (display->modmap); - - meta_topic (META_DEBUG_KEYBINDINGS, - "Checking whether code 0x%x is bound to modifier 0x%x\n", - keycode, mask); - - mod_index = 0; - mask = mask >> 1; - while (mask != 0) - { - mod_index += 1; - mask = mask >> 1; - } - - meta_topic (META_DEBUG_KEYBINDINGS, - "Modifier has index %d\n", mod_index); - - end = (mod_index + 1) * display->modmap->max_keypermod; - i = mod_index * display->modmap->max_keypermod; - while (i < end) - { - if (keycode == display->modmap->modifiermap[i]) - { - retval = TRUE; - break; - } - ++i; - } - - return retval; -} - -static unsigned int -get_primary_modifier (MetaDisplay *display, - unsigned int entire_binding_mask) -{ - /* The idea here is to see if the "main" modifier - * for Alt+Tab has been pressed/released. So if the binding - * is Alt+Shift+Tab then releasing Alt is the thing that - * ends the operation. It's pretty random how we order - * these. - */ - unsigned int masks[] = { Mod5Mask, Mod4Mask, Mod3Mask, - Mod2Mask, Mod1Mask, ControlMask, - ShiftMask, LockMask }; - - int i; - - i = 0; - while (i < (int) G_N_ELEMENTS (masks)) - { - if (entire_binding_mask & masks[i]) - return masks[i]; - ++i; - } - - return 0; -} - -static gboolean -keycode_is_primary_modifier (MetaDisplay *display, - unsigned int keycode, - unsigned int entire_binding_mask) -{ - unsigned int primary_modifier; - - meta_topic (META_DEBUG_KEYBINDINGS, - "Checking whether code 0x%x is the primary modifier of mask 0x%x\n", - keycode, entire_binding_mask); - - primary_modifier = get_primary_modifier (display, entire_binding_mask); - if (primary_modifier != 0) - return is_specific_modifier (display, keycode, primary_modifier); - else - return FALSE; -} - -static gboolean -primary_modifier_still_pressed (MetaDisplay *display, - unsigned int entire_binding_mask) -{ - unsigned int primary_modifier; - double x, y, root_x, root_y; - Window root, child; - XIButtonState buttons; - XIModifierState mods; - XIGroupState group; - MetaScreen *random_screen; - Window random_xwindow; - - primary_modifier = get_primary_modifier (display, entire_binding_mask); - - random_screen = display->screens->data; - random_xwindow = random_screen->no_focus_window; - XIQueryPointer (display->xdisplay, - META_VIRTUAL_CORE_POINTER_ID, - random_xwindow, /* some random window */ - &root, &child, - &root_x, &root_y, - &x, &y, - &buttons, &mods, &group); - free (buttons.mask); - - meta_topic (META_DEBUG_KEYBINDINGS, - "Primary modifier 0x%x full grab mask 0x%x current state 0x%x\n", - primary_modifier, entire_binding_mask, mods.effective); - - if ((mods.effective & primary_modifier) == 0) - return FALSE; - else - return TRUE; -} - static void invoke_handler (MetaDisplay *display, MetaScreen *screen, @@ -1822,20 +1672,6 @@ invoke_handler (MetaDisplay *display, NULL); } -static void -invoke_handler_by_name (MetaDisplay *display, - MetaScreen *screen, - const char *handler_name, - MetaWindow *window, - ClutterKeyEvent *event) -{ - MetaKeyHandler *handler; - - handler = HANDLER (handler_name); - if (handler) - invoke_handler (display, screen, handler, window, event, NULL); -} - static gboolean process_event (MetaKeyBinding *bindings, int n_bindings, @@ -2119,23 +1955,6 @@ meta_display_process_key_event (MetaDisplay *display, keep_grab = process_keyboard_resize_grab (display, screen, window, event); break; - case META_GRAB_OP_KEYBOARD_TABBING_NORMAL: - case META_GRAB_OP_KEYBOARD_TABBING_DOCK: - case META_GRAB_OP_KEYBOARD_TABBING_GROUP: - case META_GRAB_OP_KEYBOARD_ESCAPING_NORMAL: - case META_GRAB_OP_KEYBOARD_ESCAPING_DOCK: - case META_GRAB_OP_KEYBOARD_ESCAPING_GROUP: - meta_topic (META_DEBUG_KEYBINDINGS, - "Processing event for keyboard tabbing/cycling\n"); - keep_grab = process_tab_grab (display, screen, event); - break; - - case META_GRAB_OP_KEYBOARD_WORKSPACE_SWITCHING: - meta_topic (META_DEBUG_KEYBINDINGS, - "Processing event for keyboard workspace switching\n"); - keep_grab = process_workspace_switch_grab (display, screen, event); - break; - default: break; } @@ -2674,347 +2493,6 @@ process_keyboard_resize_grab (MetaDisplay *display, return handled; } -static gboolean -end_keyboard_grab (MetaDisplay *display, - unsigned int keycode) -{ -#ifdef HAVE_XKB - if (display->xkb_base_event_type > 0) - { - unsigned int primary_modifier; - XkbStateRec state; - - primary_modifier = get_primary_modifier (display, display->grab_mask); - - XkbGetState (display->xdisplay, XkbUseCoreKbd, &state); - - if (!(primary_modifier & state.mods)) - return TRUE; - } - else -#endif - { - if (keycode_is_primary_modifier (display, keycode, display->grab_mask)) - return TRUE; - } - - return FALSE; -} - -static gboolean -process_tab_grab (MetaDisplay *display, - MetaScreen *screen, - ClutterKeyEvent *event) -{ - MetaKeyBinding *binding; - MetaKeyBindingAction action; - gboolean popup_not_showing; - gboolean backward; - gboolean key_used; - MetaWindow *prev_window; - - if (screen != display->grab_screen) - return FALSE; - - binding = display_get_keybinding (display, - event->keyval, - event->hardware_keycode, - display->grab_mask); - if (binding) - action = meta_prefs_get_keybinding_action (binding->name); - else - action = META_KEYBINDING_ACTION_NONE; - - /* - * If there is no tab_pop up object, i.e., there is some custom handler - * implementing Alt+Tab & Co., we call this custom handler; we do not - * mess about with the grab, as that is up to the handler to deal with. - */ - if (!screen->tab_popup) - { - if (event->type == CLUTTER_KEY_RELEASE) - { - if (end_keyboard_grab (display, event->hardware_keycode)) - { - invoke_handler_by_name (display, screen, "tab-popup-select", NULL, event); - - /* We return FALSE to end the grab; if the handler ended the grab itself - * that will be a noop. If the handler didn't end the grab, then it's a - * safety measure to prevent a stuck grab. - */ - return FALSE; - } - - return TRUE; - } - - switch (action) - { - case META_KEYBINDING_ACTION_CYCLE_PANELS: - case META_KEYBINDING_ACTION_CYCLE_WINDOWS: - case META_KEYBINDING_ACTION_CYCLE_PANELS_BACKWARD: - case META_KEYBINDING_ACTION_CYCLE_WINDOWS_BACKWARD: - case META_KEYBINDING_ACTION_SWITCH_PANELS: - case META_KEYBINDING_ACTION_SWITCH_WINDOWS: - case META_KEYBINDING_ACTION_SWITCH_APPLICATIONS: - case META_KEYBINDING_ACTION_SWITCH_PANELS_BACKWARD: - case META_KEYBINDING_ACTION_SWITCH_WINDOWS_BACKWARD: - case META_KEYBINDING_ACTION_SWITCH_APPLICATIONS_BACKWARD: - case META_KEYBINDING_ACTION_CYCLE_GROUP: - case META_KEYBINDING_ACTION_CYCLE_GROUP_BACKWARD: - case META_KEYBINDING_ACTION_SWITCH_GROUP: - case META_KEYBINDING_ACTION_SWITCH_GROUP_BACKWARD: - /* These are the tab-popup bindings. If a custom Alt-Tab implementation - * is in effect, we expect it to want to handle all of these as a group - * - * If there are some of them that the custom implementation didn't - * handle, we treat them as "unbound" for the duration - running the - * normal handlers could get us into trouble. - */ - if (binding->handler && - binding->handler->func && - binding->handler->func != binding->handler->default_func) - { - invoke_handler (display, screen, binding->handler, NULL, event, binding); - return TRUE; - } - break; - case META_KEYBINDING_ACTION_NONE: - { - /* - * If this is simply user pressing the Shift key, we do not want - * to cancel the grab. - */ - if (is_modifier (display, event->hardware_keycode)) - return TRUE; - } - - default: - break; - } - - /* Some unhandled key press */ - invoke_handler_by_name (display, screen, "tab-popup-cancel", NULL, event); - return FALSE; - } - - if (event->type == CLUTTER_KEY_RELEASE && - end_keyboard_grab (display, event->hardware_keycode)) - { - /* We're done, move to the new window. */ - MetaWindow *target_window; - - target_window = meta_screen_tab_popup_get_selected (screen); - - meta_topic (META_DEBUG_KEYBINDINGS, - "Ending tab operation, primary modifier released\n"); - - if (target_window) - { - target_window->tab_unminimized = FALSE; - - meta_topic (META_DEBUG_KEYBINDINGS, - "Activating target window\n"); - - meta_topic (META_DEBUG_FOCUS, "Activating %s due to tab popup " - "selection and turning mouse_mode off\n", - target_window->desc); - display->mouse_mode = FALSE; - meta_window_activate (target_window, event->time); - - meta_topic (META_DEBUG_KEYBINDINGS, - "Ending grab early so we can focus the target window\n"); - meta_display_end_grab_op (display, event->time); - - return TRUE; /* we already ended the grab */ - } - - return FALSE; /* end grab */ - } - - /* don't care about other releases, but eat them, don't end grab */ - if (event->type == CLUTTER_KEY_RELEASE) - return TRUE; - - /* don't end grab on modifier key presses */ - if (is_modifier (display, event->hardware_keycode)) - return TRUE; - - prev_window = meta_screen_tab_popup_get_selected (screen); - - /* Cancel when alt-Escape is pressed during using alt-Tab, and vice - * versa. - */ - switch (action) - { - case META_KEYBINDING_ACTION_CYCLE_PANELS: - case META_KEYBINDING_ACTION_CYCLE_WINDOWS: - case META_KEYBINDING_ACTION_CYCLE_PANELS_BACKWARD: - case META_KEYBINDING_ACTION_CYCLE_WINDOWS_BACKWARD: - /* CYCLE_* are traditionally Escape-based actions, - * and should cancel traditionally Tab-based ones. - */ - switch (display->grab_op) - { - case META_GRAB_OP_KEYBOARD_ESCAPING_NORMAL: - case META_GRAB_OP_KEYBOARD_ESCAPING_DOCK: - /* carry on */ - break; - default: - return FALSE; - } - break; - case META_KEYBINDING_ACTION_SWITCH_PANELS: - case META_KEYBINDING_ACTION_SWITCH_WINDOWS: - case META_KEYBINDING_ACTION_SWITCH_APPLICATIONS: - case META_KEYBINDING_ACTION_SWITCH_PANELS_BACKWARD: - case META_KEYBINDING_ACTION_SWITCH_WINDOWS_BACKWARD: - case META_KEYBINDING_ACTION_SWITCH_APPLICATIONS_BACKWARD: - /* SWITCH_* are traditionally Tab-based actions, - * and should cancel traditionally Escape-based ones. - */ - switch (display->grab_op) - { - case META_GRAB_OP_KEYBOARD_TABBING_NORMAL: - case META_GRAB_OP_KEYBOARD_TABBING_DOCK: - /* carry on */ - break; - default: - /* Also, we must re-lower and re-minimize whatever window - * we'd previously raised and unminimized. - */ - meta_stack_set_positions (screen->stack, - screen->display->grab_old_window_stacking); - if (prev_window && prev_window->tab_unminimized) - { - meta_window_minimize (prev_window); - prev_window->tab_unminimized = FALSE; - } - return FALSE; - } - break; - case META_KEYBINDING_ACTION_CYCLE_GROUP: - case META_KEYBINDING_ACTION_CYCLE_GROUP_BACKWARD: - case META_KEYBINDING_ACTION_SWITCH_GROUP: - case META_KEYBINDING_ACTION_SWITCH_GROUP_BACKWARD: - switch (display->grab_op) - { - case META_GRAB_OP_KEYBOARD_ESCAPING_GROUP: - case META_GRAB_OP_KEYBOARD_TABBING_GROUP: - /* carry on */ - break; - default: - return FALSE; - } - - break; - default: - break; - } - - /* !! TO HERE !! - * alt-f6 during alt-{Tab,Escape} does not end the grab - * but does change the grab op (and redraws the window, - * of course). - * See _{SWITCH,CYCLE}_GROUP.@@@ - */ - - popup_not_showing = FALSE; - key_used = FALSE; - backward = FALSE; - - switch (action) - { - case META_KEYBINDING_ACTION_CYCLE_PANELS: - case META_KEYBINDING_ACTION_CYCLE_WINDOWS: - case META_KEYBINDING_ACTION_CYCLE_GROUP: - popup_not_showing = TRUE; - key_used = TRUE; - break; - case META_KEYBINDING_ACTION_CYCLE_PANELS_BACKWARD: - case META_KEYBINDING_ACTION_CYCLE_WINDOWS_BACKWARD: - case META_KEYBINDING_ACTION_CYCLE_GROUP_BACKWARD: - popup_not_showing = TRUE; - key_used = TRUE; - backward = TRUE; - break; - case META_KEYBINDING_ACTION_SWITCH_PANELS: - case META_KEYBINDING_ACTION_SWITCH_WINDOWS: - case META_KEYBINDING_ACTION_SWITCH_APPLICATIONS: - case META_KEYBINDING_ACTION_SWITCH_GROUP: - key_used = TRUE; - break; - case META_KEYBINDING_ACTION_SWITCH_PANELS_BACKWARD: - case META_KEYBINDING_ACTION_SWITCH_WINDOWS_BACKWARD: - case META_KEYBINDING_ACTION_SWITCH_APPLICATIONS_BACKWARD: - case META_KEYBINDING_ACTION_SWITCH_GROUP_BACKWARD: - key_used = TRUE; - backward = TRUE; - break; - default: - break; - } - - if (key_used) - { - meta_topic (META_DEBUG_KEYBINDINGS, - "Key pressed, moving tab focus in popup\n"); - - if (event->modifier_state & CLUTTER_SHIFT_MASK) - backward = !backward; - - if (backward) - meta_screen_tab_popup_backward (screen); - else - meta_screen_tab_popup_forward (screen); - - if (popup_not_showing) - { - /* We can't actually change window focus, due to the grab. - * but raise the window. - */ - MetaWindow *target_window; - - meta_stack_set_positions (screen->stack, - display->grab_old_window_stacking); - - target_window = meta_screen_tab_popup_get_selected (screen); - - if (prev_window && prev_window->tab_unminimized) - { - prev_window->tab_unminimized = FALSE; - meta_window_minimize (prev_window); - } - - if (target_window) - { - meta_window_raise (target_window); - target_window->tab_unminimized = target_window->minimized; - meta_window_unminimize (target_window); - } - } - } - else - { - /* end grab */ - meta_topic (META_DEBUG_KEYBINDINGS, - "Ending tabbing/cycling, uninteresting key pressed\n"); - - meta_topic (META_DEBUG_KEYBINDINGS, - "Syncing to old stack positions.\n"); - meta_stack_set_positions (screen->stack, - screen->display->grab_old_window_stacking); - - if (prev_window && prev_window->tab_unminimized) - { - meta_window_minimize (prev_window); - prev_window->tab_unminimized = FALSE; - } - } - - return key_used; -} - static void handle_switch_to_workspace (MetaDisplay *display, MetaScreen *screen, @@ -3026,23 +2504,6 @@ handle_switch_to_workspace (MetaDisplay *display, gint which = binding->handler->data; MetaWorkspace *workspace; - if (which < 0) - { - /* Negative workspace numbers are directions with respect to the - * current workspace. While we could insta-switch here by setting - * workspace to the result of meta_workspace_get_neighbor(), when - * people request a workspace switch to the left or right via - * the keyboard, they actually want a tab popup. So we should - * go there instead. - * - * Note that we're the only caller of that function, so perhaps - * we should merge with it. - */ - handle_workspace_switch (display, screen, event_window, event, binding, - dummy); - return; - } - workspace = meta_screen_get_workspace_by_index (screen, which); if (workspace) @@ -3267,119 +2728,6 @@ handle_move_to_center (MetaDisplay *display, window->rect.height); } -static gboolean -process_workspace_switch_grab (MetaDisplay *display, - MetaScreen *screen, - ClutterKeyEvent *event) -{ - MetaWorkspace *workspace; - - if (screen != display->grab_screen || !screen->ws_popup) - return FALSE; - - if (event->type == CLUTTER_KEY_RELEASE && - end_keyboard_grab (display, event->hardware_keycode)) - { - /* We're done, move to the new workspace. */ - MetaWorkspace *target_workspace; - - target_workspace = meta_screen_workspace_popup_get_selected (screen); - - meta_topic (META_DEBUG_KEYBINDINGS, - "Ending workspace tab operation, primary modifier released\n"); - - if (target_workspace == screen->active_workspace) - { - meta_topic (META_DEBUG_KEYBINDINGS, - "Ending grab so we can focus on the target workspace\n"); - meta_display_end_grab_op (display, event->time); - - meta_topic (META_DEBUG_KEYBINDINGS, - "Focusing default window on target workspace\n"); - - meta_workspace_focus_default_window (target_workspace, - NULL, - event->time); - - return TRUE; /* we already ended the grab */ - } - - /* Workspace switching should have already occurred on KeyPress */ - meta_warning ("target_workspace != active_workspace. Some other event must have occurred.\n"); - - return FALSE; /* end grab */ - } - - /* don't care about other releases, but eat them, don't end grab */ - if (event->type == CLUTTER_KEY_RELEASE) - return TRUE; - - /* don't end grab on modifier key presses */ - if (is_modifier (display, event->hardware_keycode)) - return TRUE; - - /* select the next workspace in the popup */ - workspace = meta_screen_workspace_popup_get_selected (screen); - - if (workspace) - { - MetaWorkspace *target_workspace; - MetaKeyBindingAction action; - - action = meta_display_get_keybinding_action (display, - event->hardware_keycode, - display->grab_mask); - - switch (action) - { - case META_KEYBINDING_ACTION_WORKSPACE_UP: - target_workspace = meta_workspace_get_neighbor (workspace, - META_MOTION_UP); - break; - - case META_KEYBINDING_ACTION_WORKSPACE_DOWN: - target_workspace = meta_workspace_get_neighbor (workspace, - META_MOTION_DOWN); - break; - - case META_KEYBINDING_ACTION_WORKSPACE_LEFT: - target_workspace = meta_workspace_get_neighbor (workspace, - META_MOTION_LEFT); - break; - - case META_KEYBINDING_ACTION_WORKSPACE_RIGHT: - target_workspace = meta_workspace_get_neighbor (workspace, - META_MOTION_RIGHT); - break; - - default: - target_workspace = NULL; - break; - } - - if (target_workspace) - { - meta_screen_workspace_popup_select (screen, target_workspace); - meta_topic (META_DEBUG_KEYBINDINGS, - "Tab key pressed, moving tab focus in popup\n"); - - meta_topic (META_DEBUG_KEYBINDINGS, - "Activating target workspace\n"); - - meta_workspace_activate (target_workspace, event->time); - - return TRUE; /* we already ended the grab */ - } - } - - /* end grab */ - meta_topic (META_DEBUG_KEYBINDINGS, - "Ending workspace tabbing & focusing default window; uninteresting key pressed\n"); - workspace = meta_screen_workspace_popup_get_selected (screen); - meta_workspace_focus_default_window (workspace, NULL, event->time); - return FALSE; -} - static void handle_show_desktop (MetaDisplay *display, MetaScreen *screen, @@ -3476,60 +2824,19 @@ handle_activate_window_menu (MetaDisplay *display, } } -static MetaGrabOp -tab_op_from_tab_type (MetaTabList type) -{ - switch (type) - { - case META_TAB_LIST_NORMAL: - return META_GRAB_OP_KEYBOARD_TABBING_NORMAL; - case META_TAB_LIST_DOCKS: - return META_GRAB_OP_KEYBOARD_TABBING_DOCK; - case META_TAB_LIST_GROUP: - return META_GRAB_OP_KEYBOARD_TABBING_GROUP; - case META_TAB_LIST_NORMAL_ALL: - break; - } - - g_assert_not_reached (); - - return 0; -} - -static MetaGrabOp -cycle_op_from_tab_type (MetaTabList type) -{ - switch (type) - { - case META_TAB_LIST_NORMAL: - return META_GRAB_OP_KEYBOARD_ESCAPING_NORMAL; - case META_TAB_LIST_DOCKS: - return META_GRAB_OP_KEYBOARD_ESCAPING_DOCK; - case META_TAB_LIST_GROUP: - return META_GRAB_OP_KEYBOARD_ESCAPING_GROUP; - case META_TAB_LIST_NORMAL_ALL: - break; - } - - g_assert_not_reached (); - - return 0; -} - static void do_choose_window (MetaDisplay *display, MetaScreen *screen, MetaWindow *event_window, ClutterKeyEvent *event, MetaKeyBinding *binding, - gboolean backward, - gboolean show_popup) + gboolean backward) { MetaTabList type = binding->handler->data; MetaWindow *initial_selection; meta_topic (META_DEBUG_KEYBINDINGS, - "Tab list = %u show_popup = %d\n", type, show_popup); + "Tab list = %u\n", type); /* reverse direction if shift is down */ if (event->modifier_state & CLUTTER_SHIFT_MASK) @@ -3542,82 +2849,7 @@ do_choose_window (MetaDisplay *display, NULL, backward); - /* Note that focus_window may not be in the tab chain, but it's OK */ - if (initial_selection == NULL) - initial_selection = meta_display_get_tab_current (display, - type, screen, - screen->active_workspace); - - meta_topic (META_DEBUG_KEYBINDINGS, - "Initially selecting window %s\n", - initial_selection ? initial_selection->desc : "(none)"); - - if (initial_selection == NULL) - return; - - if (binding->mask == 0) - { - /* If no modifiers, we can't do the "hold down modifier to keep - * moving" thing, so we just instaswitch by one window. - */ - meta_topic (META_DEBUG_FOCUS, - "Activating %s and turning off mouse_mode due to " - "switch/cycle windows with no modifiers\n", - initial_selection->desc); - display->mouse_mode = FALSE; - meta_window_activate (initial_selection, event->time); - return; - } - - if (meta_prefs_get_no_tab_popup ()) - { - /* FIXME? Shouldn't this be merged with the previous case? */ - return; - } - - if (!meta_display_begin_grab_op (display, - screen, - NULL, - show_popup ? - tab_op_from_tab_type (type) : - cycle_op_from_tab_type (type), - FALSE, - FALSE, - 0, - binding->mask, - event->time, - 0, 0)) - return; - - if (!primary_modifier_still_pressed (display, binding->mask)) - { - /* This handles a race where modifier might be released before - * we establish the grab. must end grab prior to trying to focus - * a window. - */ - meta_topic (META_DEBUG_FOCUS, - "Ending grab, activating %s, and turning off " - "mouse_mode due to switch/cycle windows where " - "modifier was released prior to grab\n", - initial_selection->desc); - meta_display_end_grab_op (display, event->time); - display->mouse_mode = FALSE; - meta_window_activate (initial_selection, event->time); - return; - } - - meta_screen_tab_popup_create (screen, type, - show_popup ? META_TAB_SHOW_ICON : - META_TAB_SHOW_INSTANTLY, - initial_selection); - - if (!show_popup) - { - meta_window_raise (initial_selection); - initial_selection->tab_unminimized = - initial_selection->minimized; - meta_window_unminimize (initial_selection); - } + meta_window_activate (initial_selection, event->time); } static void @@ -3629,9 +2861,7 @@ handle_switch (MetaDisplay *display, gpointer dummy) { gint backwards = (binding->handler->flags & META_KEY_BINDING_IS_REVERSED) != 0; - - do_choose_window (display, screen, event_window, event, binding, - backwards, TRUE); + do_choose_window (display, screen, event_window, event, binding, backwards); } static void @@ -3643,31 +2873,7 @@ handle_cycle (MetaDisplay *display, gpointer dummy) { gint backwards = (binding->handler->flags & META_KEY_BINDING_IS_REVERSED) != 0; - - do_choose_window (display, screen, event_window, event, binding, - backwards, FALSE); -} - -static void -handle_tab_popup_select (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - ClutterKeyEvent *event, - MetaKeyBinding *binding, - gpointer dummy) -{ - /* Stub for custom handlers; no default implementation */ -} - -static void -handle_tab_popup_cancel (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - ClutterKeyEvent *event, - MetaKeyBinding *binding, - gpointer dummy) -{ - /* Stub for custom handlers; no default implementation */ + do_choose_window (display, screen, event_window, event, binding, backwards); } static void @@ -4014,58 +3220,6 @@ handle_lower (MetaDisplay *display, meta_window_lower (window); } -static void -handle_workspace_switch (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - ClutterKeyEvent *event, - MetaKeyBinding *binding, - gpointer dummy) -{ - gint motion = binding->handler->data; - MetaWorkspace *next; - gboolean grabbed_before_release; - - g_assert (motion < 0); - - meta_topic (META_DEBUG_KEYBINDINGS, - "Starting tab between workspaces, showing popup\n"); - - if (!meta_display_begin_grab_op (display, - screen, - NULL, - META_GRAB_OP_KEYBOARD_WORKSPACE_SWITCHING, - FALSE, - FALSE, - 0, - event->modifier_state, - event->time, - 0, 0)) - return; - - next = meta_workspace_get_neighbor (screen->active_workspace, motion); - g_assert (next); - - grabbed_before_release = primary_modifier_still_pressed (display, event->modifier_state); - - meta_topic (META_DEBUG_KEYBINDINGS, "Activating target workspace\n"); - - if (!grabbed_before_release) - { - /* end the grab right away, modifier possibly released - * before we could establish the grab and receive the - * release event. Must end grab before we can switch - * spaces. - */ - meta_display_end_grab_op (display, event->time); - } - - meta_workspace_activate (next, event->time); - - if (grabbed_before_release && !meta_prefs_get_no_tab_popup ()) - meta_screen_workspace_popup_create (screen, next); -} - static void handle_set_spew_mark (MetaDisplay *display, MetaScreen *screen, @@ -4217,28 +3371,28 @@ init_builtin_key_bindings (MetaDisplay *display) common_keybindings, META_KEY_BINDING_NONE, META_KEYBINDING_ACTION_WORKSPACE_LEFT, - handle_switch_to_workspace, META_MOTION_LEFT); + NULL, 0); add_builtin_keybinding (display, "switch-to-workspace-right", common_keybindings, META_KEY_BINDING_NONE, META_KEYBINDING_ACTION_WORKSPACE_RIGHT, - handle_switch_to_workspace, META_MOTION_RIGHT); + NULL, 0); add_builtin_keybinding (display, "switch-to-workspace-up", common_keybindings, META_KEY_BINDING_NONE, META_KEYBINDING_ACTION_WORKSPACE_UP, - handle_switch_to_workspace, META_MOTION_UP); + NULL, 0); add_builtin_keybinding (display, "switch-to-workspace-down", common_keybindings, META_KEY_BINDING_NONE, META_KEYBINDING_ACTION_WORKSPACE_DOWN, - handle_switch_to_workspace, META_MOTION_DOWN); + NULL, 0); /* The ones which have inverses. These can't be bound to any keystroke @@ -4349,26 +3503,6 @@ init_builtin_key_bindings (MetaDisplay *display) META_KEYBINDING_ACTION_CYCLE_PANELS_BACKWARD, handle_cycle, META_TAB_LIST_DOCKS); - - /* These two are special pseudo-bindings that are provided for allowing - * custom handlers, but will never be bound to a key. While a tab - * grab is in effect, they are invoked for releasing the primary modifier - * or pressing some unbound key, respectively. - */ - add_builtin_keybinding (display, - "tab-popup-select", - mutter_keybindings, - META_KEY_BINDING_NONE, - META_KEYBINDING_ACTION_TAB_POPUP_SELECT, - handle_tab_popup_select, 0); - - add_builtin_keybinding (display, - "tab-popup-cancel", - mutter_keybindings, - META_KEY_BINDING_NONE, - META_KEYBINDING_ACTION_TAB_POPUP_CANCEL, - handle_tab_popup_cancel, 0); - /***********************************/ add_builtin_keybinding (display, diff --git a/src/core/prefs.c b/src/core/prefs.c index 7534210b8..80db6f392 100644 --- a/src/core/prefs.c +++ b/src/core/prefs.c @@ -57,7 +57,6 @@ #define KEY_OVERLAY_KEY "overlay-key" #define KEY_WORKSPACES_ONLY_ON_PRIMARY "workspaces-only-on-primary" -#define KEY_NO_TAB_POPUP "no-tab-popup" /* These are the different schemas we are keeping * a GSettings instance for */ @@ -112,8 +111,6 @@ static char **workspace_names = NULL; static gboolean workspaces_only_on_primary = FALSE; -static gboolean no_tab_popup = FALSE; - static char *iso_next_group_option = NULL; static void handle_preference_update_enum (GSettings *settings, @@ -365,13 +362,6 @@ static MetaBoolPreference preferences_bool[] = }, &workspaces_only_on_primary, }, - { - { KEY_NO_TAB_POPUP, - SCHEMA_MUTTER, - META_PREF_NO_TAB_POPUP, - }, - &no_tab_popup, - }, { { "auto-maximize", SCHEMA_MUTTER, @@ -1813,9 +1803,6 @@ meta_preference_to_string (MetaPreference pref) case META_PREF_WORKSPACES_ONLY_ON_PRIMARY: return "WORKSPACES_ONLY_ON_PRIMARY"; - case META_PREF_NO_TAB_POPUP: - return "NO_TAB_POPUP"; - case META_PREF_DRAGGABLE_BORDER_WIDTH: return "DRAGGABLE_BORDER_WIDTH"; @@ -2320,25 +2307,6 @@ meta_prefs_get_workspaces_only_on_primary (void) return workspaces_only_on_primary; } - -gboolean -meta_prefs_get_no_tab_popup (void) -{ - return no_tab_popup; -} - -void -meta_prefs_set_no_tab_popup (gboolean whether) -{ - MetaBasePreference *pref; - - if (find_pref (preferences_bool, sizeof(MetaBoolPreference), - KEY_NO_TAB_POPUP, &pref)) - { - g_settings_set_boolean (SETTINGS (pref->schema), KEY_NO_TAB_POPUP, whether); - } -} - int meta_prefs_get_draggable_border_width (void) { diff --git a/src/core/screen-private.h b/src/core/screen-private.h index 2d9c31765..427bda28f 100644 --- a/src/core/screen-private.h +++ b/src/core/screen-private.h @@ -64,7 +64,6 @@ struct _MetaScreen Visual *default_xvisual; MetaRectangle rect; /* Size of screen; rect.x & rect.y are always 0 */ MetaUI *ui; - MetaTabPopup *tab_popup, *ws_popup; guint tile_preview_timeout_id; @@ -150,22 +149,6 @@ void meta_screen_foreach_window (MetaScreen *scree void meta_screen_update_cursor (MetaScreen *screen); -void meta_screen_tab_popup_create (MetaScreen *screen, - MetaTabList list_type, - MetaTabShowType show_type, - MetaWindow *initial_window); -void meta_screen_tab_popup_forward (MetaScreen *screen); -void meta_screen_tab_popup_backward (MetaScreen *screen); -MetaWindow* meta_screen_tab_popup_get_selected (MetaScreen *screen); -void meta_screen_tab_popup_destroy (MetaScreen *screen); - -void meta_screen_workspace_popup_create (MetaScreen *screen, - MetaWorkspace *initial_selection); -void meta_screen_workspace_popup_select (MetaScreen *screen, - MetaWorkspace *workspace); -MetaWorkspace*meta_screen_workspace_popup_get_selected (MetaScreen *screen); -void meta_screen_workspace_popup_destroy (MetaScreen *screen); - void meta_screen_update_tile_preview (MetaScreen *screen, gboolean delay); void meta_screen_hide_tile_preview (MetaScreen *screen); diff --git a/src/core/screen.c b/src/core/screen.c index 9df2a8cbe..d99814b2d 100644 --- a/src/core/screen.c +++ b/src/core/screen.c @@ -760,9 +760,6 @@ meta_screen_new (MetaDisplay *display, screen->ui = meta_ui_new (screen->display->xdisplay, screen->xscreen); - screen->tab_popup = NULL; - screen->ws_popup = NULL; - screen->tile_preview_timeout_id = 0; screen->stack = meta_stack_new (screen); @@ -1428,253 +1425,6 @@ meta_screen_update_cursor (MetaScreen *screen) screen->current_cursor); } -void -meta_screen_tab_popup_create (MetaScreen *screen, - MetaTabList list_type, - MetaTabShowType show_type, - MetaWindow *initial_selection) -{ - MetaTabEntry *entries; - GList *tab_list; - GList *tmp; - int len; - int i; - - if (screen->tab_popup) - return; - - tab_list = meta_display_get_tab_list (screen->display, - list_type, - screen, - screen->active_workspace); - - len = g_list_length (tab_list); - - entries = g_new (MetaTabEntry, len + 1); - entries[len].key = NULL; - entries[len].title = NULL; - entries[len].icon = NULL; - - i = 0; - tmp = tab_list; - while (i < len) - { - MetaWindow *window; - MetaRectangle r; - - window = tmp->data; - - entries[i].key = (MetaTabEntryKey) window; - entries[i].title = window->title; - entries[i].icon = g_object_ref (window->icon); - entries[i].blank = FALSE; - entries[i].hidden = !meta_window_showing_on_its_workspace (window); - entries[i].demands_attention = window->wm_state_demands_attention; - - if (show_type == META_TAB_SHOW_INSTANTLY || - !entries[i].hidden || - !meta_window_get_icon_geometry (window, &r)) - meta_window_get_frame_rect (window, &r); - - entries[i].rect = r; - - /* Find inside of highlight rectangle to be used when window is - * outlined for tabbing. This should be the size of the - * east/west frame, and the size of the south frame, on those - * sides. On the top it should be the size of the south frame - * edge. - */ -#define OUTLINE_WIDTH 5 - /* Top side */ - if (!entries[i].hidden && - window->frame && window->frame->bottom_height > 0 && - window->frame->child_y >= window->frame->bottom_height) - entries[i].inner_rect.y = window->frame->bottom_height; - else - entries[i].inner_rect.y = OUTLINE_WIDTH; - - /* Bottom side */ - if (!entries[i].hidden && - window->frame && window->frame->bottom_height != 0) - entries[i].inner_rect.height = r.height - - entries[i].inner_rect.y - window->frame->bottom_height; - else - entries[i].inner_rect.height = r.height - - entries[i].inner_rect.y - OUTLINE_WIDTH; - - /* Left side */ - if (!entries[i].hidden && window->frame && window->frame->child_x != 0) - entries[i].inner_rect.x = window->frame->child_x; - else - entries[i].inner_rect.x = OUTLINE_WIDTH; - - /* Right side */ - if (!entries[i].hidden && - window->frame && window->frame->right_width != 0) - entries[i].inner_rect.width = r.width - - entries[i].inner_rect.x - window->frame->right_width; - else - entries[i].inner_rect.width = r.width - - entries[i].inner_rect.x - OUTLINE_WIDTH; - - ++i; - tmp = tmp->next; - } - - if (!meta_prefs_get_no_tab_popup ()) - screen->tab_popup = meta_ui_tab_popup_new (entries, - screen->number, - len, - 5, /* FIXME */ - TRUE); - - for (i = 0; i < len; i++) - g_object_unref (entries[i].icon); - - g_free (entries); - - g_list_free (tab_list); - - meta_ui_tab_popup_select (screen->tab_popup, - (MetaTabEntryKey) initial_selection); - - if (show_type != META_TAB_SHOW_INSTANTLY) - meta_ui_tab_popup_set_showing (screen->tab_popup, TRUE); -} - -void -meta_screen_tab_popup_forward (MetaScreen *screen) -{ - g_return_if_fail (screen->tab_popup != NULL); - - meta_ui_tab_popup_forward (screen->tab_popup); -} - -void -meta_screen_tab_popup_backward (MetaScreen *screen) -{ - g_return_if_fail (screen->tab_popup != NULL); - - meta_ui_tab_popup_backward (screen->tab_popup); -} - -MetaWindow * -meta_screen_tab_popup_get_selected (MetaScreen *screen) -{ - g_return_val_if_fail (screen->tab_popup != NULL, NULL); - - return (MetaWindow *) meta_ui_tab_popup_get_selected (screen->tab_popup); -} - -void -meta_screen_tab_popup_destroy (MetaScreen *screen) -{ - if (screen->tab_popup) - { - meta_ui_tab_popup_free (screen->tab_popup); - screen->tab_popup = NULL; - } -} - -void -meta_screen_workspace_popup_create (MetaScreen *screen, - MetaWorkspace *initial_selection) -{ - MetaTabEntry *entries; - int len; - int i; - MetaWorkspaceLayout layout; - int n_workspaces; - int current_workspace; - - if (screen->ws_popup || meta_prefs_get_no_tab_popup ()) - return; - - current_workspace = meta_workspace_index (screen->active_workspace); - n_workspaces = meta_screen_get_n_workspaces (screen); - - meta_screen_calc_workspace_layout (screen, n_workspaces, - current_workspace, &layout); - - len = layout.grid_area; - - entries = g_new (MetaTabEntry, len + 1); - entries[len].key = NULL; - entries[len].title = NULL; - entries[len].icon = NULL; - - i = 0; - while (i < len) - { - if (layout.grid[i] >= 0) - { - MetaWorkspace *workspace; - - workspace = meta_screen_get_workspace_by_index (screen, - layout.grid[i]); - - entries[i].key = (MetaTabEntryKey) workspace; - entries[i].title = meta_workspace_get_name (workspace); - entries[i].icon = NULL; - entries[i].blank = FALSE; - - g_assert (entries[i].title != NULL); - } - else - { - entries[i].key = NULL; - entries[i].title = NULL; - entries[i].icon = NULL; - entries[i].blank = TRUE; - } - entries[i].hidden = FALSE; - entries[i].demands_attention = FALSE; - - ++i; - } - - screen->ws_popup = meta_ui_tab_popup_new (entries, - screen->number, - len, - layout.cols, - FALSE); - - g_free (entries); - meta_screen_free_workspace_layout (&layout); - - meta_ui_tab_popup_select (screen->ws_popup, - (MetaTabEntryKey) initial_selection); - meta_ui_tab_popup_set_showing (screen->ws_popup, TRUE); -} - -void -meta_screen_workspace_popup_select (MetaScreen *screen, - MetaWorkspace *workspace) -{ - g_return_if_fail (screen->ws_popup != NULL); - - meta_ui_tab_popup_select (screen->ws_popup, - (MetaTabEntryKey) workspace); -} - -MetaWorkspace * -meta_screen_workspace_popup_get_selected (MetaScreen *screen) -{ - g_return_val_if_fail (screen->ws_popup != NULL, NULL); - - return (MetaWorkspace *) meta_ui_tab_popup_get_selected (screen->ws_popup); -} - -void -meta_screen_workspace_popup_destroy (MetaScreen *screen) -{ - if (screen->ws_popup) - { - meta_ui_tab_popup_free (screen->ws_popup); - screen->ws_popup = NULL; - } -} - static gboolean meta_screen_update_tile_preview_timeout (gpointer data) { diff --git a/src/meta/common.h b/src/meta/common.h index ffccb2d92..da9712f80 100644 --- a/src/meta/common.h +++ b/src/meta/common.h @@ -214,21 +214,6 @@ typedef enum META_GRAB_OP_KEYBOARD_RESIZING_SW, META_GRAB_OP_KEYBOARD_RESIZING_NW, - /* Alt+Tab */ - META_GRAB_OP_KEYBOARD_TABBING_NORMAL, - META_GRAB_OP_KEYBOARD_TABBING_DOCK, - - /* Alt+Esc */ - META_GRAB_OP_KEYBOARD_ESCAPING_NORMAL, - META_GRAB_OP_KEYBOARD_ESCAPING_DOCK, - - META_GRAB_OP_KEYBOARD_ESCAPING_GROUP, - - /* Alt+F6 */ - META_GRAB_OP_KEYBOARD_TABBING_GROUP, - - META_GRAB_OP_KEYBOARD_WORKSPACE_SWITCHING, - /* Frame button ops */ META_GRAB_OP_CLICKING_MINIMIZE, META_GRAB_OP_CLICKING_MAXIMIZE, diff --git a/src/meta/prefs.h b/src/meta/prefs.h index cc07d292c..c8cc540b1 100644 --- a/src/meta/prefs.h +++ b/src/meta/prefs.h @@ -62,7 +62,6 @@ * @META_PREF_EDGE_TILING: edge tiling * @META_PREF_FORCE_FULLSCREEN: force fullscreen * @META_PREF_WORKSPACES_ONLY_ON_PRIMARY: workspaces only on primary - * @META_PREF_NO_TAB_POPUP: no tab popup * @META_PREF_DRAGGABLE_BORDER_WIDTH: draggable border width * @META_PREF_AUTO_MAXIMIZE: auto-maximize */ @@ -100,7 +99,6 @@ typedef enum META_PREF_EDGE_TILING, META_PREF_FORCE_FULLSCREEN, META_PREF_WORKSPACES_ONLY_ON_PRIMARY, - META_PREF_NO_TAB_POPUP, META_PREF_DRAGGABLE_BORDER_WIDTH, META_PREF_AUTO_MAXIMIZE } MetaPreference; @@ -163,9 +161,6 @@ void meta_prefs_set_force_fullscreen (gboolean whether); gboolean meta_prefs_get_workspaces_only_on_primary (void); -gboolean meta_prefs_get_no_tab_popup (void); -void meta_prefs_set_no_tab_popup (gboolean whether); - int meta_prefs_get_draggable_border_width (void); gboolean meta_prefs_get_ignore_request_hide_titlebar (void); @@ -204,8 +199,6 @@ void meta_prefs_set_ignore_request_hide_titlebar (gboolean whether); * @META_KEYBINDING_ACTION_CYCLE_WINDOWS_BACKWARD: FILLME * @META_KEYBINDING_ACTION_CYCLE_PANELS: FILLME * @META_KEYBINDING_ACTION_CYCLE_PANELS_BACKWARD: FILLME - * @META_KEYBINDING_ACTION_TAB_POPUP_SELECT: FILLME - * @META_KEYBINDING_ACTION_TAB_POPUP_CANCEL: FILLME * @META_KEYBINDING_ACTION_SHOW_DESKTOP: FILLME * @META_KEYBINDING_ACTION_PANEL_MAIN_MENU: FILLME * @META_KEYBINDING_ACTION_PANEL_RUN_DIALOG: FILLME @@ -301,8 +294,6 @@ typedef enum _MetaKeyBindingAction META_KEYBINDING_ACTION_CYCLE_WINDOWS_BACKWARD, META_KEYBINDING_ACTION_CYCLE_PANELS, META_KEYBINDING_ACTION_CYCLE_PANELS_BACKWARD, - META_KEYBINDING_ACTION_TAB_POPUP_SELECT, - META_KEYBINDING_ACTION_TAB_POPUP_CANCEL, META_KEYBINDING_ACTION_SHOW_DESKTOP, META_KEYBINDING_ACTION_PANEL_MAIN_MENU, META_KEYBINDING_ACTION_PANEL_RUN_DIALOG, diff --git a/src/ui/draw-workspace.c b/src/ui/draw-workspace.c deleted file mode 100644 index 2d5662993..000000000 --- a/src/ui/draw-workspace.c +++ /dev/null @@ -1,224 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* Draw a workspace */ - -/* This file should not be modified to depend on other files in - * libwnck or mutter, since it's used in both of them - */ - -/* - * Copyright (C) 2002 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 "draw-workspace.h" -#include "theme-private.h" - - -static void -get_window_rect (const WnckWindowDisplayInfo *win, - int screen_width, - int screen_height, - const GdkRectangle *workspace_rect, - GdkRectangle *rect) -{ - double width_ratio, height_ratio; - int x, y, width, height; - - width_ratio = (double) workspace_rect->width / (double) screen_width; - height_ratio = (double) workspace_rect->height / (double) screen_height; - - x = win->x; - y = win->y; - width = win->width; - height = win->height; - - x *= width_ratio; - y *= height_ratio; - width *= width_ratio; - height *= height_ratio; - - x += workspace_rect->x; - y += workspace_rect->y; - - if (width < 3) - width = 3; - if (height < 3) - height = 3; - - rect->x = x; - rect->y = y; - rect->width = width; - rect->height = height; -} - -static void -draw_window (GtkWidget *widget, - cairo_t *cr, - const WnckWindowDisplayInfo *win, - const GdkRectangle *winrect, - GtkStateFlags state) -{ - GdkPixbuf *icon; - int icon_x, icon_y, icon_w, icon_h; - gboolean is_active; - GdkRGBA color; - GtkStyleContext *style; - - is_active = win->is_active; - - cairo_save (cr); - - cairo_rectangle (cr, winrect->x, winrect->y, winrect->width, winrect->height); - cairo_clip (cr); - - style = gtk_widget_get_style_context (widget); - if (is_active) - meta_gtk_style_get_light_color (style, state, &color); - else - gtk_style_context_get_background_color (style, state, &color); - gdk_cairo_set_source_rgba (cr, &color); - - cairo_rectangle (cr, - winrect->x + 1, winrect->y + 1, - MAX (0, winrect->width - 2), MAX (0, winrect->height - 2)); - cairo_fill (cr); - - - icon = win->icon; - - icon_w = icon_h = 0; - - if (icon) - { - icon_w = gdk_pixbuf_get_width (icon); - icon_h = gdk_pixbuf_get_height (icon); - - /* If the icon is too big, fall back to mini icon. - * We don't arbitrarily scale the icon, because it's - * just too slow on my Athlon 850. - */ - if (icon_w > (winrect->width - 2) || - icon_h > (winrect->height - 2)) - { - icon = win->mini_icon; - if (icon) - { - icon_w = gdk_pixbuf_get_width (icon); - icon_h = gdk_pixbuf_get_height (icon); - - /* Give up. */ - if (icon_w > (winrect->width - 2) || - icon_h > (winrect->height - 2)) - icon = NULL; - } - } - } - - if (icon) - { - icon_x = winrect->x + (winrect->width - icon_w) / 2; - icon_y = winrect->y + (winrect->height - icon_h) / 2; - - cairo_save (cr); - gdk_cairo_set_source_pixbuf (cr, icon, icon_x, icon_y); - cairo_rectangle (cr, icon_x, icon_y, icon_w, icon_h); - cairo_clip (cr); - cairo_paint (cr); - cairo_restore (cr); - } - - gtk_style_context_get_color (style, state, &color); - gdk_cairo_set_source_rgba (cr, &color); - cairo_set_line_width (cr, 1.0); - cairo_rectangle (cr, - winrect->x + 0.5, winrect->y + 0.5, - MAX (0, winrect->width - 1), MAX (0, winrect->height - 1)); - cairo_stroke (cr); - - cairo_restore (cr); -} - -void -wnck_draw_workspace (GtkWidget *widget, - cairo_t *cr, - int x, - int y, - int width, - int height, - int screen_width, - int screen_height, - GdkPixbuf *workspace_background, - gboolean is_active, - const WnckWindowDisplayInfo *windows, - int n_windows) -{ - int i; - GdkRectangle workspace_rect; - GtkStateFlags state; - GtkStyleContext *style; - - workspace_rect.x = x; - workspace_rect.y = y; - workspace_rect.width = width; - workspace_rect.height = height; - - if (is_active) - state = GTK_STATE_FLAG_SELECTED; - else if (workspace_background) - state = GTK_STATE_FLAG_PRELIGHT; - else - state = GTK_STATE_FLAG_NORMAL; - - style = gtk_widget_get_style_context (widget); - - cairo_save (cr); - - if (workspace_background) - { - gdk_cairo_set_source_pixbuf (cr, workspace_background, x, y); - cairo_paint (cr); - } - else - { - GdkRGBA color; - - meta_gtk_style_get_dark_color (style,state, &color); - gdk_cairo_set_source_rgba (cr, &color); - cairo_rectangle (cr, x, y, width, height); - cairo_fill (cr); - } - - i = 0; - while (i < n_windows) - { - const WnckWindowDisplayInfo *win = &windows[i]; - GdkRectangle winrect; - - get_window_rect (win, screen_width, - screen_height, &workspace_rect, &winrect); - - draw_window (widget, - cr, - win, - &winrect, - state); - - ++i; - } - - cairo_restore (cr); - -} diff --git a/src/ui/draw-workspace.h b/src/ui/draw-workspace.h deleted file mode 100644 index 5c3a5359e..000000000 --- a/src/ui/draw-workspace.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* Draw a workspace */ - -/* This file should not be modified to depend on other files in - * libwnck or metacity, since it's used in both of them - */ - -/* - * Copyright (C) 2002 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 WNCK_DRAW_WORKSPACE_H -#define WNCK_DRAW_WORKSPACE_H - -#include -#include -#include - -typedef struct -{ - GdkPixbuf *icon; - GdkPixbuf *mini_icon; - int x; - int y; - int width; - int height; - - guint is_active : 1; - -} WnckWindowDisplayInfo; - -void wnck_draw_workspace (GtkWidget *widget, - cairo_t *cr, - int x, - int y, - int width, - int height, - int screen_width, - int screen_height, - GdkPixbuf *workspace_background, - gboolean is_active, - const WnckWindowDisplayInfo *windows, - int n_windows); - -#endif diff --git a/src/ui/tabpopup.c b/src/ui/tabpopup.c deleted file mode 100644 index 285e29573..000000000 --- a/src/ui/tabpopup.c +++ /dev/null @@ -1,963 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* Mutter popup window thing showing windows you can tab to */ - -/* - * Copyright (C) 2001 Havoc Pennington - * Copyright (C) 2002 Red Hat, Inc. - * Copyright (C) 2005 Elijah Newren - * - * 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 "core.h" -#include "tabpopup.h" -/* FIXME these two includes are 100% broken ... - */ -#include "workspace-private.h" -#include "frame.h" -#include "draw-workspace.h" -#include -#include - -#define OUTSIDE_SELECT_RECT 2 -#define INSIDE_SELECT_RECT 2 - -typedef struct _TabEntry TabEntry; - -struct _TabEntry -{ - MetaTabEntryKey key; - char *title; - GdkPixbuf *icon, *dimmed_icon; - GtkWidget *widget; - GdkRectangle rect; - GdkRectangle inner_rect; - guint blank : 1; -}; - -struct _MetaTabPopup -{ - GtkWidget *window; - GtkWidget *label; - GList *current; - GList *entries; - TabEntry *current_selected_entry; - GtkWidget *outline_window; - gboolean outline; -}; - -static GtkWidget* selectable_image_new (GdkPixbuf *pixbuf); -static void select_image (GtkWidget *widget); -static void unselect_image (GtkWidget *widget); - -static GtkWidget* selectable_workspace_new (MetaWorkspace *workspace); -static void select_workspace (GtkWidget *widget); -static void unselect_workspace (GtkWidget *widget); - -static gboolean -outline_window_draw (GtkWidget *widget, - cairo_t *cr, - gpointer data) -{ - MetaTabPopup *popup; - TabEntry *te; - - popup = data; - - if (!popup->outline || popup->current_selected_entry == NULL) - return FALSE; - - te = popup->current_selected_entry; - - cairo_set_line_width (cr, 1.0); - cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); - - cairo_rectangle (cr, - 0.5, 0.5, - te->rect.width - 1, - te->rect.height - 1); - cairo_stroke (cr); - - cairo_rectangle (cr, - te->inner_rect.x - 0.5, te->inner_rect.y - 0.5, - te->inner_rect.width + 1, - te->inner_rect.height + 1); - cairo_stroke (cr); - - return FALSE; -} - -static GdkPixbuf* -dimm_icon (GdkPixbuf *pixbuf) -{ - int x, y, pixel_stride, row_stride; - guchar *row, *pixels; - int w, h; - GdkPixbuf *dimmed_pixbuf; - - if (gdk_pixbuf_get_has_alpha (pixbuf)) - { - dimmed_pixbuf = gdk_pixbuf_copy (pixbuf); - } - else - { - dimmed_pixbuf = gdk_pixbuf_add_alpha (pixbuf, FALSE, 0, 0, 0); - } - - w = gdk_pixbuf_get_width (dimmed_pixbuf); - h = gdk_pixbuf_get_height (dimmed_pixbuf); - - pixel_stride = 4; - - row = gdk_pixbuf_get_pixels (dimmed_pixbuf); - row_stride = gdk_pixbuf_get_rowstride (dimmed_pixbuf); - - for (y = 0; y < h; y++) - { - pixels = row; - for (x = 0; x < w; x++) - { - pixels[3] /= 2; - pixels += pixel_stride; - } - row += row_stride; - } - return dimmed_pixbuf; -} - -static TabEntry* -tab_entry_new (const MetaTabEntry *entry, - gint screen_width, - gboolean outline) -{ - TabEntry *te; - - te = g_new (TabEntry, 1); - te->key = entry->key; - te->title = NULL; - if (entry->title) - { - gchar *str; - gchar *tmp; - gchar *formatter = "%s"; - - str = meta_g_utf8_strndup (entry->title, 4096); - - if (entry->hidden) - { - formatter = "[%s]"; - } - - tmp = g_markup_printf_escaped (formatter, str); - g_free (str); - str = tmp; - - if (entry->demands_attention) - { - /* Escape the whole line of text then markup the text and - * copy it back into the original buffer. - */ - tmp = g_strdup_printf ("%s", str); - g_free (str); - str = tmp; - } - - te->title=g_strdup(str); - - g_free (str); - } - te->widget = NULL; - te->icon = entry->icon; - te->blank = entry->blank; - te->dimmed_icon = NULL; - if (te->icon) - { - g_object_ref (G_OBJECT (te->icon)); - if (entry->hidden) - te->dimmed_icon = dimm_icon (entry->icon); - } - - if (outline) - { - te->rect.x = entry->rect.x; - te->rect.y = entry->rect.y; - te->rect.width = entry->rect.width; - te->rect.height = entry->rect.height; - - te->inner_rect.x = entry->inner_rect.x; - te->inner_rect.y = entry->inner_rect.y; - te->inner_rect.width = entry->inner_rect.width; - te->inner_rect.height = entry->inner_rect.height; - } - return te; -} - -MetaTabPopup* -meta_ui_tab_popup_new (const MetaTabEntry *entries, - int screen_number, - int entry_count, - int width, - gboolean outline) -{ - MetaTabPopup *popup; - int i, left, top; - int height; - GtkWidget *grid; - GtkWidget *vbox; - GtkWidget *align; - GList *tmp; - GtkWidget *frame; - int max_label_width; /* the actual max width of the labels we create */ - AtkObject *obj; - GdkScreen *screen; - int screen_width; - - popup = g_new (MetaTabPopup, 1); - - popup->outline_window = gtk_window_new (GTK_WINDOW_POPUP); - - screen = gdk_display_get_screen (gdk_display_get_default (), - screen_number); - gtk_window_set_screen (GTK_WINDOW (popup->outline_window), - screen); - - gtk_widget_set_app_paintable (popup->outline_window, TRUE); - gtk_widget_realize (popup->outline_window); - - g_signal_connect (G_OBJECT (popup->outline_window), "draw", - G_CALLBACK (outline_window_draw), popup); - - popup->window = gtk_window_new (GTK_WINDOW_POPUP); - - gtk_window_set_screen (GTK_WINDOW (popup->window), - screen); - - gtk_window_set_position (GTK_WINDOW (popup->window), - GTK_WIN_POS_CENTER_ALWAYS); - /* enable resizing, to get never-shrink behavior */ - gtk_window_set_resizable (GTK_WINDOW (popup->window), - TRUE); - popup->current = NULL; - popup->entries = NULL; - popup->current_selected_entry = NULL; - popup->outline = outline; - - screen_width = gdk_screen_get_width (screen); - for (i = 0; i < entry_count; ++i) - { - TabEntry* new_entry = tab_entry_new (&entries[i], screen_width, outline); - popup->entries = g_list_prepend (popup->entries, new_entry); - } - - popup->entries = g_list_reverse (popup->entries); - - g_assert (width > 0); - height = i / width; - if (i % width) - height += 1; - - grid = gtk_grid_new (); - vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); - - frame = gtk_frame_new (NULL); - gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT); - gtk_container_set_border_width (GTK_CONTAINER (grid), 1); - gtk_container_add (GTK_CONTAINER (popup->window), - frame); - gtk_container_add (GTK_CONTAINER (frame), - vbox); - - align = gtk_alignment_new (0.5, 0.5, 0.0, 0.0); - - gtk_box_pack_start (GTK_BOX (vbox), align, TRUE, TRUE, 0); - - gtk_container_add (GTK_CONTAINER (align), - grid); - - popup->label = gtk_label_new (""); - - /* Set the accessible role of the label to a status bar so it - * will emit name changed events that can be used by screen - * readers. - */ - obj = gtk_widget_get_accessible (popup->label); - atk_object_set_role (obj, ATK_ROLE_STATUSBAR); - - gtk_misc_set_padding (GTK_MISC (popup->label), 3, 3); - - gtk_box_pack_end (GTK_BOX (vbox), popup->label, FALSE, FALSE, 0); - - max_label_width = 0; - top = 0; - tmp = popup->entries; - - while (tmp && top < height) - { - left = 0; - - while (tmp && left < width) - { - GtkWidget *image; - GtkRequisition req; - - TabEntry *te; - - te = tmp->data; - - if (te->blank) - { - /* just stick a widget here to avoid special cases */ - image = gtk_alignment_new (0.0, 0.0, 0.0, 0.0); - } - else if (outline) - { - if (te->dimmed_icon) - { - image = selectable_image_new (te->dimmed_icon); - } - else - { - image = selectable_image_new (te->icon); - } - - gtk_misc_set_padding (GTK_MISC (image), - INSIDE_SELECT_RECT + OUTSIDE_SELECT_RECT + 1, - INSIDE_SELECT_RECT + OUTSIDE_SELECT_RECT + 1); - gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.5); - } - else - { - image = selectable_workspace_new ((MetaWorkspace *) te->key); - } - - te->widget = image; - - gtk_grid_attach (GTK_GRID (grid), - te->widget, - left, top, 1, 1); - - /* Efficiency rules! */ - gtk_label_set_markup (GTK_LABEL (popup->label), - te->title); - gtk_widget_get_preferred_size (popup->label, &req, NULL); - max_label_width = MAX (max_label_width, req.width); - - tmp = tmp->next; - - ++left; - } - - ++top; - } - - /* remove all the temporary text */ - gtk_label_set_text (GTK_LABEL (popup->label), ""); - /* Make it so that we ellipsize if the text is too long */ - gtk_label_set_ellipsize (GTK_LABEL (popup->label), PANGO_ELLIPSIZE_END); - - /* Limit the window size to no bigger than screen_width/4 */ - if (max_label_width>(screen_width/4)) - { - max_label_width = screen_width/4; - } - - max_label_width += 20; /* add random padding */ - - gtk_window_set_default_size (GTK_WINDOW (popup->window), - max_label_width, - -1); - - return popup; -} - -static void -free_tab_entry (gpointer data, gpointer user_data) -{ - TabEntry *te; - - te = data; - - g_free (te->title); - if (te->icon) - g_object_unref (G_OBJECT (te->icon)); - if (te->dimmed_icon) - g_object_unref (G_OBJECT (te->dimmed_icon)); - - g_free (te); -} - -void -meta_ui_tab_popup_free (MetaTabPopup *popup) -{ - meta_verbose ("Destroying tab popup window\n"); - - if (!popup) - { - meta_warning ("NULL passed to meta_ui_tab_popup_free\n"); - return; - } - - gtk_widget_destroy (popup->outline_window); - gtk_widget_destroy (popup->window); - - g_list_foreach (popup->entries, free_tab_entry, NULL); - - g_list_free (popup->entries); - - g_free (popup); -} - -void -meta_ui_tab_popup_set_showing (MetaTabPopup *popup, - gboolean showing) -{ - if (showing) - { - gtk_widget_show_all (popup->window); - } - else - { - if (gtk_widget_get_visible (popup->window)) - { - meta_verbose ("Hiding tab popup window\n"); - gtk_widget_hide (popup->window); - meta_core_increment_event_serial ( - GDK_DISPLAY_XDISPLAY (gdk_display_get_default ())); - } - } -} - -static void -display_entry (MetaTabPopup *popup, - TabEntry *te) -{ - GdkRectangle rect; - GdkWindow *window; - - - if (popup->current_selected_entry) - { - if (popup->outline) - unselect_image (popup->current_selected_entry->widget); - else - unselect_workspace (popup->current_selected_entry->widget); - } - - gtk_label_set_markup (GTK_LABEL (popup->label), te->title); - - if (popup->outline) - select_image (te->widget); - else - select_workspace (te->widget); - - if (popup->outline) - { - cairo_region_t *region; - cairo_region_t *inner_region; - GdkRGBA black = { 0.0, 0.0, 0.0, 1.0 }; - - window = gtk_widget_get_window (popup->outline_window); - - /* Do stuff behind gtk's back */ - gdk_window_hide (window); - meta_core_increment_event_serial ( - GDK_DISPLAY_XDISPLAY (gdk_display_get_default ())); - - rect = te->rect; - rect.x = 0; - rect.y = 0; - - gdk_window_move_resize (window, - te->rect.x, te->rect.y, - te->rect.width, te->rect.height); - - gdk_window_set_background_rgba (window, &black); - - - region = cairo_region_create_rectangle (&rect); - inner_region = cairo_region_create_rectangle (&te->inner_rect); - cairo_region_subtract (region, inner_region); - cairo_region_destroy (inner_region); - - gdk_window_shape_combine_region (window, - region, - 0, 0); - - cairo_region_destroy (region); - - - /* This should piss off gtk a bit, but we don't want to raise - * above the tab popup. So, instead of calling gtk_widget_show, - * we manually set the window as mapped and then manually map it - * with gdk functions. - */ - gtk_widget_set_mapped (popup->outline_window, TRUE); - gdk_window_show_unraised (window); - } - - /* Must be before we handle an expose for the outline window */ - popup->current_selected_entry = te; -} - -void -meta_ui_tab_popup_forward (MetaTabPopup *popup) -{ - if (popup->current != NULL) - popup->current = popup->current->next; - - if (popup->current == NULL) - popup->current = popup->entries; - - if (popup->current != NULL) - { - TabEntry *te; - - te = popup->current->data; - - display_entry (popup, te); - } -} - -void -meta_ui_tab_popup_backward (MetaTabPopup *popup) -{ - if (popup->current != NULL) - popup->current = popup->current->prev; - - if (popup->current == NULL) - popup->current = g_list_last (popup->entries); - - if (popup->current != NULL) - { - TabEntry *te; - - te = popup->current->data; - - display_entry (popup, te); - } -} - -MetaTabEntryKey -meta_ui_tab_popup_get_selected (MetaTabPopup *popup) -{ - if (popup->current) - { - TabEntry *te; - - te = popup->current->data; - - return te->key; - } - else - return (MetaTabEntryKey)None; -} - -void -meta_ui_tab_popup_select (MetaTabPopup *popup, - MetaTabEntryKey key) -{ - GList *tmp; - - /* Note, "key" may not be in the list of entries; other code assumes - * it's OK to pass in a key that isn't. - */ - - tmp = popup->entries; - while (tmp != NULL) - { - TabEntry *te; - - te = tmp->data; - - if (te->key == key) - { - popup->current = tmp; - - display_entry (popup, te); - - return; - } - - tmp = tmp->next; - } -} - -#define META_TYPE_SELECT_IMAGE (meta_select_image_get_type ()) -#define META_SELECT_IMAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_SELECT_IMAGE, MetaSelectImage)) - -typedef struct _MetaSelectImage MetaSelectImage; -typedef struct _MetaSelectImageClass MetaSelectImageClass; - -struct _MetaSelectImage -{ - GtkImage parent_instance; - guint selected : 1; -}; - -struct _MetaSelectImageClass -{ - GtkImageClass parent_class; -}; - - -static GType meta_select_image_get_type (void) G_GNUC_CONST; - -static GtkWidget* -selectable_image_new (GdkPixbuf *pixbuf) -{ - GtkWidget *w; - - w = g_object_new (meta_select_image_get_type (), NULL); - gtk_image_set_from_pixbuf (GTK_IMAGE (w), pixbuf); - - return w; -} - -static void -select_image (GtkWidget *widget) -{ - META_SELECT_IMAGE (widget)->selected = TRUE; - gtk_widget_queue_draw (widget); -} - -static void -unselect_image (GtkWidget *widget) -{ - META_SELECT_IMAGE (widget)->selected = FALSE; - gtk_widget_queue_draw (widget); -} - -static void meta_select_image_class_init (MetaSelectImageClass *klass); -static gboolean meta_select_image_draw (GtkWidget *widget, - cairo_t *cr); - -static GtkImageClass *parent_class; - -GType -meta_select_image_get_type (void) -{ - static GType image_type = 0; - - if (!image_type) - { - static const GTypeInfo image_info = - { - sizeof (MetaSelectImageClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) meta_select_image_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (MetaSelectImage), - 16, /* n_preallocs */ - (GInstanceInitFunc) NULL, - }; - - image_type = g_type_register_static (GTK_TYPE_IMAGE, "MetaSelectImage", &image_info, 0); - } - - return image_type; -} - -static void -meta_select_image_class_init (MetaSelectImageClass *klass) -{ - GtkWidgetClass *widget_class; - - parent_class = g_type_class_peek (gtk_image_get_type ()); - - widget_class = GTK_WIDGET_CLASS (klass); - - widget_class->draw = meta_select_image_draw; -} - -static gboolean -meta_select_image_draw (GtkWidget *widget, - cairo_t *cr) -{ - GtkAllocation allocation; - - gtk_widget_get_allocation (widget, &allocation); - - if (META_SELECT_IMAGE (widget)->selected) - { - GtkMisc *misc; - GtkRequisition requisition; - GtkStyleContext *context; - GdkRGBA color; - int x, y, w, h; - gint xpad, ypad; - gfloat xalign, yalign; - - misc = GTK_MISC (widget); - - gtk_widget_get_requisition (widget, &requisition); - gtk_misc_get_alignment (misc, &xalign, &yalign); - gtk_misc_get_padding (misc, &xpad, &ypad); - - x = (allocation.width - (requisition.width - xpad * 2)) * xalign + 0.5; - y = (allocation.height - (requisition.height - ypad * 2)) * yalign + 0.5; - - x -= INSIDE_SELECT_RECT + 1; - y -= INSIDE_SELECT_RECT + 1; - - w = requisition.width - OUTSIDE_SELECT_RECT * 2 - 1; - h = requisition.height - OUTSIDE_SELECT_RECT * 2 - 1; - - context = gtk_widget_get_style_context (widget); - - gtk_style_context_set_state (context, - gtk_widget_get_state_flags (widget)); - - gtk_style_context_lookup_color (context, "color", &color); - - cairo_set_line_width (cr, 2.0); - cairo_set_source_rgb (cr, color.red, color.green, color.blue); - - cairo_rectangle (cr, x, y, w + 1, h + 1); - cairo_stroke (cr); - - cairo_set_line_width (cr, 1.0); - } - - return GTK_WIDGET_CLASS (parent_class)->draw (widget, cr); -} - -#define META_TYPE_SELECT_WORKSPACE (meta_select_workspace_get_type ()) -#define META_SELECT_WORKSPACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_SELECT_WORKSPACE, MetaSelectWorkspace)) - -typedef struct _MetaSelectWorkspace MetaSelectWorkspace; -typedef struct _MetaSelectWorkspaceClass MetaSelectWorkspaceClass; - -struct _MetaSelectWorkspace -{ - GtkDrawingArea parent_instance; - MetaWorkspace *workspace; - guint selected : 1; -}; - -struct _MetaSelectWorkspaceClass -{ - GtkDrawingAreaClass parent_class; -}; - - -static GType meta_select_workspace_get_type (void) G_GNUC_CONST; - -#define SELECT_OUTLINE_WIDTH 2 -#define MINI_WORKSPACE_WIDTH 48 - -static GtkWidget* -selectable_workspace_new (MetaWorkspace *workspace) -{ - GtkWidget *widget; - double screen_aspect; - - widget = g_object_new (meta_select_workspace_get_type (), NULL); - - screen_aspect = (double) workspace->screen->rect.height / - (double) workspace->screen->rect.width; - - /* account for select rect */ - gtk_widget_set_size_request (widget, - MINI_WORKSPACE_WIDTH + SELECT_OUTLINE_WIDTH * 2, - MINI_WORKSPACE_WIDTH * screen_aspect + SELECT_OUTLINE_WIDTH * 2); - - META_SELECT_WORKSPACE (widget)->workspace = workspace; - - return widget; -} - -static void -select_workspace (GtkWidget *widget) -{ - META_SELECT_WORKSPACE(widget)->selected = TRUE; - gtk_widget_queue_draw (widget); -} - -static void -unselect_workspace (GtkWidget *widget) -{ - META_SELECT_WORKSPACE (widget)->selected = FALSE; - gtk_widget_queue_draw (widget); -} - -static void meta_select_workspace_class_init (MetaSelectWorkspaceClass *klass); - -static gboolean meta_select_workspace_draw (GtkWidget *widget, - cairo_t *cr); - -GType -meta_select_workspace_get_type (void) -{ - static GType workspace_type = 0; - - if (!workspace_type) - { - static const GTypeInfo workspace_info = - { - sizeof (MetaSelectWorkspaceClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) meta_select_workspace_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (MetaSelectWorkspace), - 16, /* n_preallocs */ - (GInstanceInitFunc) NULL, - }; - - workspace_type = g_type_register_static (GTK_TYPE_DRAWING_AREA, - "MetaSelectWorkspace", - &workspace_info, - 0); - } - - return workspace_type; -} - -static void -meta_select_workspace_class_init (MetaSelectWorkspaceClass *klass) -{ - GtkWidgetClass *widget_class; - - widget_class = GTK_WIDGET_CLASS (klass); - - widget_class->draw = meta_select_workspace_draw; -} - -/** - * meta_convert_meta_to_wnck: - * @window: the #MetaWindow - * @screen: the #MetaScreen the window is on - * - * Converts a #MetaWindow to a #WnckWindowDisplayInfo window - * that is used to build a thumbnail of a workspace. - **/ -static WnckWindowDisplayInfo -meta_convert_meta_to_wnck (MetaWindow *window, MetaScreen *screen) -{ - WnckWindowDisplayInfo wnck_window; - wnck_window.icon = window->icon; - wnck_window.mini_icon = window->mini_icon; - wnck_window.is_active = window->has_focus; - - if (window->frame) - { - wnck_window.x = window->frame->rect.x; - wnck_window.y = window->frame->rect.y; - wnck_window.width = window->frame->rect.width; - wnck_window.height = window->frame->rect.height; - } - else - { - wnck_window.x = window->rect.x; - wnck_window.y = window->rect.y; - wnck_window.width = window->rect.width; - wnck_window.height = window->rect.height; - } - return wnck_window; -} - - -static gboolean -meta_select_workspace_draw (GtkWidget *widget, - cairo_t *cr) -{ - MetaWorkspace *workspace; - WnckWindowDisplayInfo *windows; - GtkAllocation allocation; - int i, n_windows; - GList *tmp, *list; - - workspace = META_SELECT_WORKSPACE (widget)->workspace; - - list = meta_stack_list_windows (workspace->screen->stack, workspace); - n_windows = g_list_length (list); - windows = g_new (WnckWindowDisplayInfo, n_windows); - - tmp = list; - i = 0; - while (tmp != NULL) - { - MetaWindow *window; - gboolean ignoreable_sticky; - - window = tmp->data; - - ignoreable_sticky = window->on_all_workspaces && - workspace != workspace->screen->active_workspace; - - if (window->skip_pager || - !meta_window_showing_on_its_workspace (window) || - window->unmaps_pending || - ignoreable_sticky) - { - --n_windows; - } - else - { - windows[i] = meta_convert_meta_to_wnck (window, workspace->screen); - i++; - } - tmp = tmp->next; - } - - g_list_free (list); - - gtk_widget_get_allocation (widget, &allocation); - - wnck_draw_workspace (widget, - cr, - SELECT_OUTLINE_WIDTH, - SELECT_OUTLINE_WIDTH, - allocation.width - SELECT_OUTLINE_WIDTH * 2, - allocation.height - SELECT_OUTLINE_WIDTH * 2, - workspace->screen->rect.width, - workspace->screen->rect.height, - NULL, - (workspace->screen->active_workspace == workspace), - windows, - n_windows); - - g_free (windows); - - if (META_SELECT_WORKSPACE (widget)->selected) - { - GtkStyleContext *context; - GdkRGBA color; - - context = gtk_widget_get_style_context (widget); - - gtk_style_context_set_state (context, - gtk_widget_get_state_flags (widget)); - - gtk_style_context_lookup_color (context, "color", &color); - - cairo_set_line_width (cr, SELECT_OUTLINE_WIDTH); - cairo_set_source_rgb (cr, color.red, color.green, color.blue); - - cairo_rectangle (cr, - SELECT_OUTLINE_WIDTH / 2.0, SELECT_OUTLINE_WIDTH / 2.0, - allocation.width - SELECT_OUTLINE_WIDTH, - allocation.height - SELECT_OUTLINE_WIDTH); - cairo_stroke (cr); - } - - return TRUE; -} diff --git a/src/ui/tabpopup.h b/src/ui/tabpopup.h deleted file mode 100644 index ba324964a..000000000 --- a/src/ui/tabpopup.h +++ /dev/null @@ -1,65 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* Mutter tab popup window */ - -/* - * Copyright (C) 2001 Havoc Pennington - * Copyright (C) 2005 Elijah Newren - * - * 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_TABPOPUP_H -#define META_TABPOPUP_H - -/* Don't include gtk.h or gdk.h here */ -#include -#include -#include -#include -#include - -typedef struct _MetaTabEntry MetaTabEntry; -typedef struct _MetaTabPopup MetaTabPopup; -typedef void *MetaTabEntryKey; - -struct _MetaTabEntry -{ - MetaTabEntryKey key; - const char *title; - GdkPixbuf *icon; - MetaRectangle rect; - MetaRectangle inner_rect; - guint blank : 1; - guint hidden : 1; - guint demands_attention : 1; -}; - -MetaTabPopup* meta_ui_tab_popup_new (const MetaTabEntry *entries, - int screen_number, - int entry_count, - int width, - gboolean outline); -void meta_ui_tab_popup_free (MetaTabPopup *popup); -void meta_ui_tab_popup_set_showing (MetaTabPopup *popup, - gboolean showing); -void meta_ui_tab_popup_forward (MetaTabPopup *popup); -void meta_ui_tab_popup_backward (MetaTabPopup *popup); -MetaTabEntryKey meta_ui_tab_popup_get_selected (MetaTabPopup *popup); -void meta_ui_tab_popup_select (MetaTabPopup *popup, - MetaTabEntryKey key); - - -#endif - diff --git a/src/ui/ui.h b/src/ui/ui.h index f1170797a..ca52f4c45 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -178,6 +178,4 @@ int meta_ui_get_drag_threshold (MetaUI *ui); MetaUIDirection meta_ui_get_direction (void); -#include "tabpopup.h" - #endif From 28859c604fa3cc12353c8f7b6981466195649692 Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Wed, 26 Feb 2014 19:01:52 +0100 Subject: [PATCH 585/889] keybindings: Don't use the keysym to match keybindings We don't want to match the keysym so that e.g. an accelerator specified as "a" works if the current keymap has a keysym other than 'a' for that keycode which means that the accelerator would become inaccessible in a non-latin keymap. This is inconvenient for users that often switch keyboard layouts, or even have different layouts in different windows, since they expect system-level keybindings to not be affected by the current layout. https://bugzilla.gnome.org/show_bug.cgi?id=678001 --- src/core/keybindings.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/core/keybindings.c b/src/core/keybindings.c index 96c34024a..6004829c9 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -747,7 +747,6 @@ grab_key_bindings (MetaDisplay *display) static MetaKeyBinding * display_get_keybinding (MetaDisplay *display, - unsigned int keysym, unsigned int keycode, unsigned long mask) { @@ -756,8 +755,7 @@ display_get_keybinding (MetaDisplay *display, i = display->n_key_bindings - 1; while (i >= 0) { - if (display->key_bindings[i].keysym == keysym && - display->key_bindings[i].keycode == keycode && + if (display->key_bindings[i].keycode == keycode && display->key_bindings[i].mask == mask) { return &display->key_bindings[i]; @@ -907,7 +905,6 @@ meta_display_get_keybinding_action (MetaDisplay *display, unsigned long mask) { MetaKeyBinding *binding; - KeySym keysym; /* This is much more vague than the MetaDisplay::overlay-key signal, * which is only emitted if the overlay-key is the only key pressed; @@ -918,12 +915,8 @@ meta_display_get_keybinding_action (MetaDisplay *display, if (keycode == (unsigned int)display->overlay_key_combo.keycode) return META_KEYBINDING_ACTION_OVERLAY_KEY; - keysym = XKeycodeToKeysym (display->xdisplay, keycode, 0); mask = mask & 0xff & ~display->ignored_modifier_mask; - binding = display_get_keybinding (display, keysym, keycode, mask); - - if (!binding && keycode == meta_display_get_above_tab_keycode (display)) - binding = display_get_keybinding (display, META_KEY_ABOVE_TAB, keycode, mask); + binding = display_get_keybinding (display, keycode, mask); if (binding) { @@ -1695,7 +1688,7 @@ process_event (MetaKeyBinding *bindings, MetaKeyHandler *handler = bindings[i].handler; if ((!window && handler->flags & META_KEY_BINDING_PER_WINDOW) || - (event->keyval != bindings[i].keysym) || + (event->hardware_keycode != bindings[i].keycode) || (event->modifier_state != bindings[i].mask) || meta_compositor_filter_keybinding (display->compositor, screen, &bindings[i])) continue; @@ -1781,7 +1774,6 @@ process_overlay_key (MetaDisplay *display, XIAsyncDevice, event->time); binding = display_get_keybinding (display, - display->overlay_key_combo.keysym, display->overlay_key_combo.keycode, display->grab_mask); if (binding && From b6a0d4d36821d8a7d4efebde6e3e8a0e4c8abc85 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 27 Feb 2014 15:40:39 -0500 Subject: [PATCH 586/889] Revert "mutter-wayland: Add XKB VT switching keysyms." This reverts commit 7283fb320f61581a524fe22b3905538adeef1c6b. Now that we match on keycodes, this isn't needed anymore. --- src/org.gnome.mutter.wayland.gschema.xml.in | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/org.gnome.mutter.wayland.gschema.xml.in b/src/org.gnome.mutter.wayland.gschema.xml.in index baddf8e72..4bb5c1dfd 100644 --- a/src/org.gnome.mutter.wayland.gschema.xml.in +++ b/src/org.gnome.mutter.wayland.gschema.xml.in @@ -2,31 +2,31 @@ - F1', 'XF86Switch_VT_1']]]> + F1']]]> <_summary>Switch to VT 1 - F2', 'XF86Switch_VT_2']]]> + F2']]]> <_summary>Switch to VT 2 - F3', 'XF86Switch_VT_3']]]> + F3']]]> <_summary>Switch to VT 3 - F4', 'XF86Switch_VT_4']]]> + F4']]]> <_summary>Switch to VT 4 - F5', 'XF86Switch_VT_5']]]> + F5']]]> <_summary>Switch to VT 5 - F6', 'XF86Switch_VT_6']]]> + F6']]]> <_summary>Switch to VT 6 - F7', 'XF86Switch_VT_7']]]> + F7']]]> <_summary>Switch to VT 7 From 98e3e5e50f9c51b7915af2adeef23af9831a6195 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Thu, 27 Feb 2014 23:45:49 +0100 Subject: [PATCH 587/889] Partially revert 5c99eae8a9ca04f5e89e60a314d3e19c7ef0a715 We must extract the window from XIDeviceEvent, to be able to apply our workaround to spoof the event in compositor.c --- src/core/display.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/core/display.c b/src/core/display.c index b3d21d4a1..7f59a8413 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -1700,6 +1700,17 @@ get_input_event (MetaDisplay *display, switch (input_event->evtype) { + case XI_Motion: + case XI_ButtonPress: + case XI_ButtonRelease: + if (((XIDeviceEvent *) input_event)->deviceid == META_VIRTUAL_CORE_POINTER_ID) + return input_event; + break; + case XI_KeyPress: + case XI_KeyRelease: + if (((XIDeviceEvent *) input_event)->deviceid == META_VIRTUAL_CORE_KEYBOARD_ID) + return input_event; + break; case XI_FocusIn: case XI_FocusOut: if (((XIEnterEvent *) input_event)->deviceid == META_VIRTUAL_CORE_KEYBOARD_ID) @@ -3097,6 +3108,12 @@ xievent_get_modified_window (MetaDisplay *display, { switch (input_event->evtype) { + case XI_Motion: + case XI_ButtonPress: + case XI_ButtonRelease: + case XI_KeyPress: + case XI_KeyRelease: + return ((XIDeviceEvent *) input_event)->event; case XI_FocusIn: case XI_FocusOut: case XI_Enter: From 283546b3790669e7690a1a278c87627117f4b30c Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 27 Feb 2014 23:46:56 -0500 Subject: [PATCH 588/889] wayland: Enable destroy animations for regular windows Don't set the surface actor to a new buffer if it's becoming unmapped. This is also technically wrong since we'll send out the release event, but oh well. We should probably decouple MetaWaylandBuffer from the CoglTexture at some point, so we can send out releases on-demand. --- src/wayland/meta-wayland-surface.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index a7bf0504e..0c5c7115f 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -262,9 +262,6 @@ ensure_buffer_texture (MetaWaylandBuffer *buffer) CoglError *catch_error = NULL; CoglTexture *texture; - if (!buffer) - return; - texture = COGL_TEXTURE (cogl_wayland_texture_2d_new_from_buffer (ctx, buffer->resource, &catch_error)); @@ -295,7 +292,7 @@ actor_surface_commit (MetaWaylandSurface *surface, MetaSurfaceActor *surface_actor = surface->surface_actor; MetaWaylandBuffer *buffer = pending->buffer; - if (buffer_changed) + if (buffer_changed && buffer) { ensure_buffer_texture (buffer); meta_surface_actor_wayland_set_buffer (META_SURFACE_ACTOR_WAYLAND (surface->surface_actor), buffer); From 86c1c3024526e479c2e65dee896757549d346c1e Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 28 Feb 2014 00:18:42 -0500 Subject: [PATCH 589/889] wayland: Add back wl_shell support --- src/wayland/meta-wayland-pointer.c | 15 +- src/wayland/meta-wayland-surface.c | 309 +++++++++++++++++++++++++++- src/wayland/meta-wayland-surface.h | 4 + src/wayland/meta-wayland-versions.h | 4 +- 4 files changed, 311 insertions(+), 21 deletions(-) diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index 21e41bb80..e0c9ad21a 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -49,7 +49,6 @@ #include "meta-wayland-pointer.h" #include "meta-wayland-private.h" -#include "xdg-shell-server-protocol.h" #include @@ -530,14 +529,7 @@ meta_wayland_pointer_end_popup_grab (MetaWaylandPointer *pointer) wl_list_for_each_safe (popup, tmp, &popup_grab->all_popups, link) { - MetaWaylandSurfaceExtension *xdg_popup = &popup->surface->xdg_popup; - struct wl_client *client = wl_resource_get_client (xdg_popup->resource); - struct wl_display *display = wl_client_get_display (client); - uint32_t serial; - - serial = wl_display_next_serial (display); - - xdg_popup_send_popup_done (xdg_popup->resource, serial); + meta_wayland_surface_popup_done (popup->surface); wl_list_remove (&popup->surface_destroy_listener.link); wl_list_remove (&popup->link); g_slice_free (MetaWaylandPopup, popup); @@ -597,7 +589,10 @@ meta_wayland_pointer_start_popup_grab (MetaWaylandPointer *pointer, popup->grab = grab; popup->surface = surface; popup->surface_destroy_listener.notify = on_popup_surface_destroy; - wl_resource_add_destroy_listener (surface->xdg_popup.resource, &popup->surface_destroy_listener); + if (surface->xdg_popup.resource) + wl_resource_add_destroy_listener (surface->xdg_popup.resource, &popup->surface_destroy_listener); + else if (surface->wl_shell_surface.resource) + wl_resource_add_destroy_listener (surface->wl_shell_surface.resource, &popup->surface_destroy_listener); wl_list_insert (&grab->all_popups, &popup->link); diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 0c5c7115f..0c671048f 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -825,7 +825,7 @@ xdg_surface_move (struct wl_client *client, } static MetaGrabOp -grab_op_for_edge (int edge) +grab_op_for_xdg_surface_resize_edge (int edge) { switch (edge) { @@ -867,7 +867,7 @@ xdg_surface_resize (struct wl_client *client, seat->pointer.focus_surface != surface) return; - begin_grab_op_on_surface (surface, seat, grab_op_for_edge (edges)); + begin_grab_op_on_surface (surface, seat, grab_op_for_xdg_surface_resize_edge (edges)); } static void @@ -1099,6 +1099,267 @@ bind_xdg_shell (struct wl_client *client, wl_client_add_destroy_listener (client, &xdg_shell->client_destroy_listener); } +static void +wl_shell_surface_destructor (struct wl_resource *resource) +{ + MetaWaylandSurfaceExtension *wl_shell_surface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = wl_container_of (wl_shell_surface, surface, wl_shell_surface); + + destroy_surface_extension (wl_shell_surface); +} + +static void +wl_shell_surface_pong (struct wl_client *client, + struct wl_resource *resource, + uint32_t serial) +{ + MetaDisplay *display = meta_get_display (); + + meta_display_pong_for_serial (display, serial); +} + +static void +wl_shell_surface_move (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *seat_resource, + uint32_t serial) +{ + MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); + MetaWaylandSurfaceExtension *wl_shell_surface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = wl_container_of (wl_shell_surface, surface, wl_shell_surface); + + if (seat->pointer.button_count == 0 || + seat->pointer.grab_serial != serial || + seat->pointer.focus_surface != surface) + return; + + begin_grab_op_on_surface (surface, seat, META_GRAB_OP_MOVING); +} + +static MetaGrabOp +grab_op_for_wl_shell_surface_resize_edge (int edge) +{ + switch (edge) + { + case WL_SHELL_SURFACE_RESIZE_TOP_LEFT: + return META_GRAB_OP_RESIZING_NW; + case WL_SHELL_SURFACE_RESIZE_TOP: + return META_GRAB_OP_RESIZING_N; + case WL_SHELL_SURFACE_RESIZE_TOP_RIGHT: + return META_GRAB_OP_RESIZING_NE; + case WL_SHELL_SURFACE_RESIZE_RIGHT: + return META_GRAB_OP_RESIZING_E; + case WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT: + return META_GRAB_OP_RESIZING_SE; + case WL_SHELL_SURFACE_RESIZE_BOTTOM: + return META_GRAB_OP_RESIZING_S; + case WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT: + return META_GRAB_OP_RESIZING_SW; + case WL_SHELL_SURFACE_RESIZE_LEFT: + return META_GRAB_OP_RESIZING_W; + default: + g_warning ("invalid edge: %d", edge); + return META_GRAB_OP_NONE; + } +} + +static void +wl_shell_surface_resize (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *seat_resource, + uint32_t serial, + uint32_t edges) +{ + MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); + MetaWaylandSurfaceExtension *wl_shell_surface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = wl_container_of (wl_shell_surface, surface, wl_shell_surface); + + if (seat->pointer.button_count == 0 || + seat->pointer.grab_serial != serial || + seat->pointer.focus_surface != surface) + return; + + begin_grab_op_on_surface (surface, seat, grab_op_for_wl_shell_surface_resize_edge (edges)); +} + +typedef enum { + SURFACE_STATE_TOPLEVEL, + SURFACE_STATE_FULLSCREEN, + SURFACE_STATE_MAXIMIZED, +} SurfaceState; + +static void +wl_shell_surface_set_state (MetaWaylandSurface *surface, + SurfaceState state) +{ + if (state == SURFACE_STATE_FULLSCREEN) + meta_window_make_fullscreen (surface->window); + else + meta_window_unmake_fullscreen (surface->window); + + if (state == SURFACE_STATE_MAXIMIZED) + meta_window_maximize (surface->window, META_MAXIMIZE_VERTICAL | META_MAXIMIZE_HORIZONTAL); + else + meta_window_unmaximize (surface->window, META_MAXIMIZE_VERTICAL | META_MAXIMIZE_HORIZONTAL); +} + +static void +wl_shell_surface_set_toplevel (struct wl_client *client, + struct wl_resource *resource) +{ + MetaWaylandSurfaceExtension *wl_shell_surface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = wl_container_of (wl_shell_surface, surface, wl_shell_surface); + + wl_shell_surface_set_state (surface, SURFACE_STATE_TOPLEVEL); +} + +static void +wl_shell_surface_set_transient (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *parent_resource, + int32_t x, + int32_t y, + uint32_t flags) +{ + MetaWaylandSurfaceExtension *wl_shell_surface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = wl_container_of (wl_shell_surface, surface, wl_shell_surface); + MetaWaylandSurface *parent_surf = wl_resource_get_user_data (parent_resource); + + wl_shell_surface_set_state (surface, SURFACE_STATE_TOPLEVEL); + + meta_window_set_transient_for (surface->window, parent_surf->window); + meta_window_move (surface->window, FALSE, + parent_surf->window->rect.x + x, + parent_surf->window->rect.y + y); + surface->window->placed = TRUE; +} + +static void +wl_shell_surface_set_fullscreen (struct wl_client *client, + struct wl_resource *resource, + uint32_t method, + uint32_t framerate, + struct wl_resource *output) +{ + MetaWaylandSurfaceExtension *wl_shell_surface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = wl_container_of (wl_shell_surface, surface, wl_shell_surface); + + wl_shell_surface_set_state (surface, SURFACE_STATE_FULLSCREEN); +} + +static void +wl_shell_surface_set_popup (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *seat_resource, + uint32_t serial, + struct wl_resource *parent_resource, + int32_t x, + int32_t y, + uint32_t flags) +{ + MetaWaylandSurfaceExtension *wl_shell_surface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = wl_container_of (wl_shell_surface, surface, wl_shell_surface); + MetaWaylandSurface *parent_surf = wl_resource_get_user_data (parent_resource); + MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); + + wl_shell_surface_set_state (surface, SURFACE_STATE_TOPLEVEL); + + meta_window_set_transient_for (surface->window, parent_surf->window); + meta_window_move (surface->window, FALSE, + parent_surf->window->rect.x + x, + parent_surf->window->rect.y + y); + surface->window->placed = TRUE; + + meta_wayland_pointer_start_popup_grab (&seat->pointer, surface); +} + +static void +wl_shell_surface_set_maximized (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *output) +{ + MetaWaylandSurfaceExtension *wl_shell_surface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = wl_container_of (wl_shell_surface, surface, wl_shell_surface); + + wl_shell_surface_set_state (surface, SURFACE_STATE_MAXIMIZED); +} + +static void +wl_shell_surface_set_title (struct wl_client *client, + struct wl_resource *resource, + const char *title) +{ + MetaWaylandSurfaceExtension *wl_shell_surface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = wl_container_of (wl_shell_surface, surface, wl_shell_surface); + + meta_window_set_title (surface->window, title); +} + +static void +wl_shell_surface_set_class (struct wl_client *client, + struct wl_resource *resource, + const char *class_) +{ + MetaWaylandSurfaceExtension *wl_shell_surface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = wl_container_of (wl_shell_surface, surface, wl_shell_surface); + + meta_window_set_wm_class (surface->window, class_, class_); +} + +static const struct wl_shell_surface_interface meta_wayland_wl_shell_surface_interface = { + wl_shell_surface_pong, + wl_shell_surface_move, + wl_shell_surface_resize, + wl_shell_surface_set_toplevel, + wl_shell_surface_set_transient, + wl_shell_surface_set_fullscreen, + wl_shell_surface_set_popup, + wl_shell_surface_set_maximized, + wl_shell_surface_set_title, + wl_shell_surface_set_class, +}; + +static void +wl_shell_get_shell_surface (struct wl_client *client, + struct wl_resource *resource, + uint32_t id, + struct wl_resource *surface_resource) +{ + MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); + + if (!create_surface_extension (&surface->wl_shell_surface, client, surface_resource, resource, id, + META_WL_SHELL_SURFACE_VERSION, + &wl_shell_surface_interface, + &meta_wayland_wl_shell_surface_interface, + wl_shell_surface_destructor)) + { + wl_resource_post_error (surface_resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "wl_shell::get_shell_surface already requested"); + return; + } + + meta_wayland_surface_make_toplevel (surface); + surface->window = meta_window_wayland_new (meta_get_display (), surface); +} + +static const struct wl_shell_interface meta_wayland_wl_shell_interface = { + wl_shell_get_shell_surface, +}; + +static void +bind_wl_shell (struct wl_client *client, + void *data, + uint32_t version, + uint32_t id) +{ + struct wl_resource *resource; + + resource = wl_resource_create (client, &wl_shell_interface, + MIN (META_WL_SHELL_VERSION, version), id); + wl_resource_set_implementation (resource, &meta_wayland_wl_shell_interface, data, NULL); +} + static void gtk_surface_destructor (struct wl_resource *resource) { @@ -1486,6 +1747,11 @@ meta_wayland_init_shell (MetaWaylandCompositor *compositor) compositor, bind_xdg_shell) == NULL) g_error ("Failed to register a global xdg-shell object"); + if (wl_global_create (compositor->wayland_display, + &wl_shell_interface, 1, + compositor, bind_wl_shell) == NULL) + g_error ("Failed to register a global wl-shell object"); + if (wl_global_create (compositor->wayland_display, >k_shell_interface, META_GTK_SHELL_VERSION, @@ -1507,6 +1773,9 @@ meta_wayland_surface_configure_notify (MetaWaylandSurface *surface, if (surface->xdg_surface.resource) xdg_surface_send_configure (surface->xdg_surface.resource, new_width, new_height); + else if (surface->wl_shell_surface.resource) + wl_shell_surface_send_configure (surface->wl_shell_surface.resource, + 0, new_width, new_height); } void @@ -1527,16 +1796,23 @@ void meta_wayland_surface_ping (MetaWaylandSurface *surface, guint32 serial) { - struct wl_client *client = wl_resource_get_client (surface->resource); - struct wl_resource *xdg_shell = get_xdg_shell_for_client (client); - - if (xdg_shell == NULL) + if (surface->xdg_surface.resource) { - g_warning ("Trying to ping a surface without an xdg_shell bound. How does this happen?"); - return; - } + struct wl_client *client = wl_resource_get_client (surface->resource); + struct wl_resource *xdg_shell = get_xdg_shell_for_client (client); - xdg_shell_send_ping (xdg_shell, serial); + if (xdg_shell == NULL) + { + g_warning ("Trying to ping a surface without an xdg_shell bound. How does this happen?"); + return; + } + + xdg_shell_send_ping (xdg_shell, serial); + } + else if (surface->wl_shell_surface.resource) + { + wl_shell_surface_send_ping (surface->wl_shell_surface.resource, serial); + } } void @@ -1545,3 +1821,16 @@ meta_wayland_surface_delete (MetaWaylandSurface *surface) if (surface->xdg_surface.resource) xdg_surface_send_delete (surface->xdg_surface.resource); } + +void +meta_wayland_surface_popup_done (MetaWaylandSurface *surface) +{ + struct wl_client *client = wl_resource_get_client (surface->resource); + struct wl_display *display = wl_client_get_display (client); + uint32_t serial = wl_display_next_serial (display); + + if (surface->xdg_popup.resource) + xdg_popup_send_popup_done (surface->xdg_popup.resource, serial); + else if (surface->wl_shell_surface.resource) + wl_shell_surface_send_popup_done (surface->wl_shell_surface.resource); +} diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h index 9e12451d4..e0203f58c 100644 --- a/src/wayland/meta-wayland-surface.h +++ b/src/wayland/meta-wayland-surface.h @@ -86,6 +86,7 @@ struct _MetaWaylandSurface MetaWindow *window; MetaWaylandSurfaceExtension xdg_surface; MetaWaylandSurfaceExtension xdg_popup; + MetaWaylandSurfaceExtension wl_shell_surface; MetaWaylandSurfaceExtension gtk_surface; MetaWaylandSurfaceExtension subsurface; @@ -132,4 +133,7 @@ void meta_wayland_surface_ping (MetaWaylandSurface *surface, guint32 serial); void meta_wayland_surface_delete (MetaWaylandSurface *surface); +void meta_wayland_surface_popup_done (MetaWaylandSurface *surface); + + #endif diff --git a/src/wayland/meta-wayland-versions.h b/src/wayland/meta-wayland-versions.h index e2d608c86..17d8895eb 100644 --- a/src/wayland/meta-wayland-versions.h +++ b/src/wayland/meta-wayland-versions.h @@ -37,6 +37,7 @@ /* Global/master objects (version exported by wl_registry and negotiated through bind) */ #define META_WL_COMPOSITOR_VERSION 3 #define META_WL_DATA_DEVICE_MANAGER_VERSION 1 +#define META_WL_SHELL_VERSION 1 #define META_WL_SEAT_VERSION 2 /* 3 not implemented yet */ #define META_WL_OUTPUT_VERSION 2 #define META_XSERVER_VERSION 1 @@ -52,9 +53,10 @@ #define META_WL_KEYBOARD_VERSION 2 /* from wl_seat; 3 not implemented yet */ #define META_WL_TOUCH_VERSION 0 /* from wl_seat; wl_touch not supported */ #define META_WL_REGION_VERSION 1 /* from wl_compositor */ -#define META_GTK_SURFACE_VERSION 1 /* from gtk_shell */ #define META_XDG_SURFACE_VERSION 1 /* from xdg_shell */ #define META_XDG_POPUP_VERSION 1 /* from xdg_shell */ +#define META_WL_SHELL_SURFACE_VERSION 1 /* from wl_shell */ +#define META_GTK_SURFACE_VERSION 1 /* from gtk_shell */ #define META_WL_SUBSURFACE_VERSION 1 /* from wl_subcompositor */ /* The first version to implement a specific event */ From 674bcef6da7cd9882b7e1820e1edf35bd5d48da0 Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Fri, 28 Feb 2014 14:51:52 +0100 Subject: [PATCH 590/889] Handle mouse-button-modifier being disabled In case 'mouse-button-modifier' is disabled the mask is 0 which means we would always grab. --- src/compositor/compositor.c | 3 +++ src/core/display.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 52c0db8c8..4c6f0e21d 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -991,6 +991,9 @@ event_is_passive_button_grab (MetaDisplay *display, if (device_event->evtype != XI_ButtonPress) return FALSE; + if (display->window_grab_modifiers == 0) + return FALSE; + if ((device_event->mods.effective & display->window_grab_modifiers) != display->window_grab_modifiers) return FALSE; diff --git a/src/core/display.c b/src/core/display.c index 7f59a8413..acd26c68c 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -2108,7 +2108,7 @@ meta_display_handle_event (MetaDisplay *display, * care about. Just let the event through. */ unmodified = (event->button.modifier_state & grab_mask) == 0; - fully_modified = (event->button.modifier_state & grab_mask) == grab_mask; + fully_modified = grab_mask && (event->button.modifier_state & grab_mask) == grab_mask; if (unmodified && window && window->have_focus_click_grab) { From a27fb19473b9eb768b1f62f83079df654ad6044a Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 28 Feb 2014 08:39:06 -0500 Subject: [PATCH 591/889] wayland: Do a small code cleanup Pass the surface rather than the resource / client. This will become a lot more helpful in the next commit. --- src/wayland/meta-wayland-surface.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 0c671048f..c7ca67ccf 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -668,23 +668,25 @@ get_resource_version (struct wl_resource *master_resource, static gboolean create_surface_extension (MetaWaylandSurfaceExtension *extension, - struct wl_client *client, + MetaWaylandSurface *surface, struct wl_resource *master_resource, - struct wl_resource *surface_resource, guint32 id, int max_version, const struct wl_interface *interface, const void *implementation, wl_resource_destroy_func_t destructor) { + struct wl_client *client; + if (extension->resource != NULL) return FALSE; + client = wl_resource_get_client (surface->resource); extension->resource = wl_resource_create (client, interface, get_resource_version (master_resource, max_version), id); wl_resource_set_implementation (extension->resource, implementation, extension, destructor); extension->surface_destroy_listener.notify = extension_handle_surface_destroy; - wl_resource_add_destroy_listener (surface_resource, &extension->surface_destroy_listener); + wl_resource_add_destroy_listener (surface->resource, &extension->surface_destroy_listener); return TRUE; } @@ -956,7 +958,7 @@ xdg_shell_get_xdg_surface (struct wl_client *client, { MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); - if (!create_surface_extension (&surface->xdg_surface, client, surface_resource, resource, id, + if (!create_surface_extension (&surface->xdg_surface, surface, resource, id, META_XDG_SURFACE_VERSION, &xdg_surface_interface, &meta_wayland_xdg_surface_interface, @@ -1012,7 +1014,7 @@ xdg_shell_get_xdg_popup (struct wl_client *client, if (parent_surf == NULL || parent_surf->window == NULL) return; - if (!create_surface_extension (&surface->xdg_popup, client, surface_resource, resource, id, + if (!create_surface_extension (&surface->xdg_popup, surface, resource, id, META_XDG_POPUP_VERSION, &xdg_popup_interface, &meta_wayland_xdg_popup_interface, @@ -1327,7 +1329,7 @@ wl_shell_get_shell_surface (struct wl_client *client, { MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); - if (!create_surface_extension (&surface->wl_shell_surface, client, surface_resource, resource, id, + if (!create_surface_extension (&surface->wl_shell_surface, surface, resource, id, META_WL_SHELL_SURFACE_VERSION, &wl_shell_surface_interface, &meta_wayland_wl_shell_surface_interface, @@ -1410,7 +1412,7 @@ get_gtk_surface (struct wl_client *client, { MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); - if (!create_surface_extension (&surface->gtk_surface, client, surface_resource, resource, id, + if (!create_surface_extension (&surface->gtk_surface, surface, resource, id, META_GTK_SURFACE_VERSION, >k_surface_interface, &meta_wayland_gtk_surface_interface, @@ -1697,7 +1699,7 @@ wl_subcompositor_get_subsurface (struct wl_client *client, MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); MetaWaylandSurface *parent = wl_resource_get_user_data (parent_resource); - if (!create_surface_extension (&surface->subsurface, client, surface_resource, resource, id, + if (!create_surface_extension (&surface->subsurface, surface, resource, id, META_GTK_SURFACE_VERSION, &wl_subsurface_interface, &meta_wayland_subsurface_interface, From e56cbfbd0fd909d58d4d93e17531400395c09a81 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 28 Feb 2014 08:40:42 -0500 Subject: [PATCH 592/889] wayland: Rearrange create_surface_extension a tiny bit This moves all the "uninteresting" variables we pass to the end. --- src/wayland/meta-wayland-surface.c | 33 +++++++++++++++++------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index c7ca67ccf..a70cd496b 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -668,13 +668,13 @@ get_resource_version (struct wl_resource *master_resource, static gboolean create_surface_extension (MetaWaylandSurfaceExtension *extension, - MetaWaylandSurface *surface, - struct wl_resource *master_resource, - guint32 id, int max_version, const struct wl_interface *interface, const void *implementation, - wl_resource_destroy_func_t destructor) + wl_resource_destroy_func_t destructor, + MetaWaylandSurface *surface, + struct wl_resource *master_resource, + guint32 id) { struct wl_client *client; @@ -958,11 +958,12 @@ xdg_shell_get_xdg_surface (struct wl_client *client, { MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); - if (!create_surface_extension (&surface->xdg_surface, surface, resource, id, + if (!create_surface_extension (&surface->xdg_surface, META_XDG_SURFACE_VERSION, &xdg_surface_interface, &meta_wayland_xdg_surface_interface, - xdg_surface_destructor)) + xdg_surface_destructor, + surface, resource, id)) { wl_resource_post_error (surface_resource, WL_DISPLAY_ERROR_INVALID_OBJECT, @@ -1014,11 +1015,12 @@ xdg_shell_get_xdg_popup (struct wl_client *client, if (parent_surf == NULL || parent_surf->window == NULL) return; - if (!create_surface_extension (&surface->xdg_popup, surface, resource, id, + if (!create_surface_extension (&surface->xdg_popup, META_XDG_POPUP_VERSION, &xdg_popup_interface, &meta_wayland_xdg_popup_interface, - xdg_popup_destructor)) + xdg_popup_destructor, + surface, resource, id)) { wl_resource_post_error (surface_resource, WL_DISPLAY_ERROR_INVALID_OBJECT, @@ -1329,11 +1331,12 @@ wl_shell_get_shell_surface (struct wl_client *client, { MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); - if (!create_surface_extension (&surface->wl_shell_surface, surface, resource, id, + if (!create_surface_extension (&surface->wl_shell_surface, META_WL_SHELL_SURFACE_VERSION, &wl_shell_surface_interface, &meta_wayland_wl_shell_surface_interface, - wl_shell_surface_destructor)) + wl_shell_surface_destructor, + surface, resource, id)) { wl_resource_post_error (surface_resource, WL_DISPLAY_ERROR_INVALID_OBJECT, @@ -1412,11 +1415,12 @@ get_gtk_surface (struct wl_client *client, { MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); - if (!create_surface_extension (&surface->gtk_surface, surface, resource, id, + if (!create_surface_extension (&surface->gtk_surface, META_GTK_SURFACE_VERSION, >k_surface_interface, &meta_wayland_gtk_surface_interface, - gtk_surface_destructor)) + gtk_surface_destructor, + surface, resource, id)) { wl_resource_post_error (surface_resource, WL_DISPLAY_ERROR_INVALID_OBJECT, @@ -1699,11 +1703,12 @@ wl_subcompositor_get_subsurface (struct wl_client *client, MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); MetaWaylandSurface *parent = wl_resource_get_user_data (parent_resource); - if (!create_surface_extension (&surface->subsurface, surface, resource, id, + if (!create_surface_extension (&surface->subsurface, META_GTK_SURFACE_VERSION, &wl_subsurface_interface, &meta_wayland_subsurface_interface, - wl_subsurface_destructor)) + wl_subsurface_destructor, + surface, resource, id)) { wl_resource_post_error (surface_resource, WL_DISPLAY_ERROR_INVALID_OBJECT, From 77838c2ca37d55458977172b4481e1c9c7b97df9 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 28 Feb 2014 08:45:07 -0500 Subject: [PATCH 593/889] wayland: Do a giant code cleanup This changes the user data of all surface extensions resources to be the MetaWaylandSurface instead of the MetaWaylandSurfaceExtension, which means that we no longer need all these pesky wl_container_ofs in implementations. --- src/wayland/meta-wayland-surface.c | 106 ++++++++++------------------- 1 file changed, 36 insertions(+), 70 deletions(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index a70cd496b..315393901 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -683,7 +683,7 @@ create_surface_extension (MetaWaylandSurfaceExtension *extension, client = wl_resource_get_client (surface->resource); extension->resource = wl_resource_create (client, interface, get_resource_version (master_resource, max_version), id); - wl_resource_set_implementation (extension->resource, implementation, extension, destructor); + wl_resource_set_implementation (extension->resource, implementation, surface, destructor); extension->surface_destroy_listener.notify = extension_handle_surface_destroy; wl_resource_add_destroy_listener (surface->resource, &extension->surface_destroy_listener); @@ -713,11 +713,10 @@ xdg_shell_pong (struct wl_client *client, static void xdg_surface_destructor (struct wl_resource *resource) { - MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface); + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); destroy_window (surface); - destroy_surface_extension (xdg_surface); + destroy_surface_extension (&surface->xdg_surface); } static void @@ -732,8 +731,7 @@ xdg_surface_set_transient_for (struct wl_client *client, struct wl_resource *resource, struct wl_resource *parent_resource) { - MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface); + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); MetaWindow *transient_for = NULL; if (parent_resource) @@ -753,8 +751,7 @@ xdg_surface_set_margin (struct wl_client *client, int32_t top_margin, int32_t bottom_margin) { - MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface); + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); surface->pending.frame_extents_changed = TRUE; surface->pending.frame_extents.left = left_margin; @@ -768,8 +765,7 @@ xdg_surface_set_title (struct wl_client *client, struct wl_resource *resource, const char *title) { - MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface); + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); meta_window_set_title (surface->window, title); } @@ -779,8 +775,7 @@ xdg_surface_set_app_id (struct wl_client *client, struct wl_resource *resource, const char *app_id) { - MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface); + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); meta_window_set_wm_class (surface->window, app_id, app_id); } @@ -815,8 +810,7 @@ xdg_surface_move (struct wl_client *client, guint32 serial) { MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); - MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface); + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); if (seat->pointer.button_count == 0 || seat->pointer.grab_serial != serial || @@ -861,8 +855,7 @@ xdg_surface_resize (struct wl_client *client, guint32 edges) { MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); - MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface); + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); if (seat->pointer.button_count == 0 || seat->pointer.grab_serial != serial || @@ -884,8 +877,7 @@ static void xdg_surface_set_fullscreen (struct wl_client *client, struct wl_resource *resource) { - MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface); + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); surface->pending.fullscreen.changed = TRUE; surface->pending.fullscreen.value = TRUE; @@ -906,8 +898,7 @@ static void xdg_surface_set_maximized (struct wl_client *client, struct wl_resource *resource) { - MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface); + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); surface->pending.maximized.changed = TRUE; surface->pending.maximized.value = TRUE; @@ -917,8 +908,7 @@ static void xdg_surface_unset_maximized (struct wl_client *client, struct wl_resource *resource) { - MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface); + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); surface->pending.maximized.changed = TRUE; surface->pending.maximized.value = FALSE; @@ -928,8 +918,7 @@ static void xdg_surface_set_minimized (struct wl_client *client, struct wl_resource *resource) { - MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface); + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); meta_window_minimize (surface->window); } @@ -978,11 +967,10 @@ xdg_shell_get_xdg_surface (struct wl_client *client, static void xdg_popup_destructor (struct wl_resource *resource) { - MetaWaylandSurfaceExtension *xdg_popup = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = wl_container_of (xdg_popup, surface, xdg_popup); + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); destroy_window (surface); - destroy_surface_extension (xdg_popup); + destroy_surface_extension (&surface->xdg_popup); } static void @@ -1106,10 +1094,9 @@ bind_xdg_shell (struct wl_client *client, static void wl_shell_surface_destructor (struct wl_resource *resource) { - MetaWaylandSurfaceExtension *wl_shell_surface = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = wl_container_of (wl_shell_surface, surface, wl_shell_surface); + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); - destroy_surface_extension (wl_shell_surface); + destroy_surface_extension (&surface->wl_shell_surface); } static void @@ -1129,8 +1116,7 @@ wl_shell_surface_move (struct wl_client *client, uint32_t serial) { MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); - MetaWaylandSurfaceExtension *wl_shell_surface = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = wl_container_of (wl_shell_surface, surface, wl_shell_surface); + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); if (seat->pointer.button_count == 0 || seat->pointer.grab_serial != serial || @@ -1175,8 +1161,7 @@ wl_shell_surface_resize (struct wl_client *client, uint32_t edges) { MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); - MetaWaylandSurfaceExtension *wl_shell_surface = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = wl_container_of (wl_shell_surface, surface, wl_shell_surface); + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); if (seat->pointer.button_count == 0 || seat->pointer.grab_serial != serial || @@ -1211,8 +1196,7 @@ static void wl_shell_surface_set_toplevel (struct wl_client *client, struct wl_resource *resource) { - MetaWaylandSurfaceExtension *wl_shell_surface = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = wl_container_of (wl_shell_surface, surface, wl_shell_surface); + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); wl_shell_surface_set_state (surface, SURFACE_STATE_TOPLEVEL); } @@ -1225,9 +1209,8 @@ wl_shell_surface_set_transient (struct wl_client *client, int32_t y, uint32_t flags) { - MetaWaylandSurfaceExtension *wl_shell_surface = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = wl_container_of (wl_shell_surface, surface, wl_shell_surface); MetaWaylandSurface *parent_surf = wl_resource_get_user_data (parent_resource); + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); wl_shell_surface_set_state (surface, SURFACE_STATE_TOPLEVEL); @@ -1245,8 +1228,7 @@ wl_shell_surface_set_fullscreen (struct wl_client *client, uint32_t framerate, struct wl_resource *output) { - MetaWaylandSurfaceExtension *wl_shell_surface = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = wl_container_of (wl_shell_surface, surface, wl_shell_surface); + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); wl_shell_surface_set_state (surface, SURFACE_STATE_FULLSCREEN); } @@ -1261,8 +1243,7 @@ wl_shell_surface_set_popup (struct wl_client *client, int32_t y, uint32_t flags) { - MetaWaylandSurfaceExtension *wl_shell_surface = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = wl_container_of (wl_shell_surface, surface, wl_shell_surface); + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); MetaWaylandSurface *parent_surf = wl_resource_get_user_data (parent_resource); MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); @@ -1282,8 +1263,7 @@ wl_shell_surface_set_maximized (struct wl_client *client, struct wl_resource *resource, struct wl_resource *output) { - MetaWaylandSurfaceExtension *wl_shell_surface = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = wl_container_of (wl_shell_surface, surface, wl_shell_surface); + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); wl_shell_surface_set_state (surface, SURFACE_STATE_MAXIMIZED); } @@ -1293,8 +1273,7 @@ wl_shell_surface_set_title (struct wl_client *client, struct wl_resource *resource, const char *title) { - MetaWaylandSurfaceExtension *wl_shell_surface = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = wl_container_of (wl_shell_surface, surface, wl_shell_surface); + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); meta_window_set_title (surface->window, title); } @@ -1304,8 +1283,7 @@ wl_shell_surface_set_class (struct wl_client *client, struct wl_resource *resource, const char *class_) { - MetaWaylandSurfaceExtension *wl_shell_surface = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = wl_container_of (wl_shell_surface, surface, wl_shell_surface); + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); meta_window_set_wm_class (surface->window, class_, class_); } @@ -1368,10 +1346,9 @@ bind_wl_shell (struct wl_client *client, static void gtk_surface_destructor (struct wl_resource *resource) { - MetaWaylandSurfaceExtension *gtk_surface = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = wl_container_of (gtk_surface, surface, gtk_surface); + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); - destroy_surface_extension (gtk_surface); + destroy_surface_extension (&surface->gtk_surface); } static void @@ -1384,8 +1361,7 @@ set_dbus_properties (struct wl_client *client, const char *application_object_path, const char *unique_bus_name) { - MetaWaylandSurfaceExtension *gtk_surface = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = wl_container_of (gtk_surface, surface, gtk_surface); + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); /* Broken client, let it die instead of us */ if (!surface->window) @@ -1517,8 +1493,7 @@ unparent_actor (MetaWaylandSurface *surface) static void wl_subsurface_destructor (struct wl_resource *resource) { - MetaWaylandSurfaceExtension *subsurface = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = wl_container_of (subsurface, surface, subsurface); + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); if (surface->sub.parent) { @@ -1530,7 +1505,7 @@ wl_subsurface_destructor (struct wl_resource *resource) } double_buffered_state_destroy (&surface->sub.pending_surface_state); - destroy_surface_extension (subsurface); + destroy_surface_extension (&surface->subsurface); } static void @@ -1546,8 +1521,7 @@ wl_subsurface_set_position (struct wl_client *client, int32_t x, int32_t y) { - MetaWaylandSurfaceExtension *subsurface = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = wl_container_of (subsurface, surface, subsurface); + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); surface->sub.pending_x = x; surface->sub.pending_y = y; @@ -1597,8 +1571,7 @@ wl_subsurface_place_above (struct wl_client *client, struct wl_resource *resource, struct wl_resource *sibling_resource) { - MetaWaylandSurfaceExtension *subsurface = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = wl_container_of (subsurface, surface, subsurface); + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); MetaWaylandSurface *sibling = wl_resource_get_user_data (sibling_resource); if (!is_valid_sibling (surface, sibling)) @@ -1620,8 +1593,7 @@ wl_subsurface_place_below (struct wl_client *client, struct wl_resource *resource, struct wl_resource *sibling_resource) { - MetaWaylandSurfaceExtension *subsurface = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = wl_container_of (subsurface, surface, subsurface); + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); MetaWaylandSurface *sibling = wl_resource_get_user_data (sibling_resource); if (!is_valid_sibling (surface, sibling)) @@ -1642,10 +1614,7 @@ static void wl_subsurface_set_sync (struct wl_client *client, struct wl_resource *resource) { - MetaWaylandSurfaceExtension *subsurface = - wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = - wl_container_of (subsurface, surface, subsurface); + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); surface->sub.synchronous = TRUE; } @@ -1654,10 +1623,7 @@ static void wl_subsurface_set_desync (struct wl_client *client, struct wl_resource *resource) { - MetaWaylandSurfaceExtension *subsurface = - wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = - wl_container_of (subsurface, surface, subsurface); + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); if (surface->sub.synchronous) subsurface_parent_surface_committed (surface); From 770b58b3675dd3fb863d25211be4923c819877be Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 28 Feb 2014 10:24:06 -0500 Subject: [PATCH 594/889] wayland: Move "public" Wayland API to another header file --- src/Makefile.am | 1 + src/compositor/meta-plugin.c | 1 + src/compositor/meta-surface-actor-wayland.c | 1 + src/compositor/meta-surface-actor-wayland.h | 2 +- src/compositor/meta-surface-actor.c | 1 - src/compositor/meta-window-actor-private.h | 3 -- src/compositor/meta-window-actor.c | 2 +- src/core/keybindings.c | 2 +- src/core/main.c | 2 +- src/core/monitor.c | 1 - src/core/screen.c | 2 +- src/wayland/meta-wayland-keyboard.h | 1 + src/wayland/meta-wayland-private.h | 25 +--------- src/wayland/meta-wayland.h | 51 +++++++++++++++++++++ 14 files changed, 61 insertions(+), 34 deletions(-) create mode 100644 src/wayland/meta-wayland.h diff --git a/src/Makefile.am b/src/Makefile.am index 2221a5d7d..8df85fbd7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -189,6 +189,7 @@ libmutter_wayland_la_SOURCES = \ ui/theme-private.h \ ui/ui.c \ wayland/meta-wayland.c \ + wayland/meta-wayland.h \ wayland/meta-wayland-private.h \ wayland/meta-xwayland-private.h \ wayland/meta-xwayland.c \ diff --git a/src/compositor/meta-plugin.c b/src/compositor/meta-plugin.c index 8cdc0ed63..444d81e85 100644 --- a/src/compositor/meta-plugin.c +++ b/src/compositor/meta-plugin.c @@ -30,6 +30,7 @@ #include "meta-plugin-manager.h" #include #include +#include #include #include diff --git a/src/compositor/meta-surface-actor-wayland.c b/src/compositor/meta-surface-actor-wayland.c index c8381930c..56dd8bd13 100644 --- a/src/compositor/meta-surface-actor-wayland.c +++ b/src/compositor/meta-surface-actor-wayland.c @@ -28,6 +28,7 @@ #include #include "meta-shaped-texture-private.h" +#include "meta-wayland-private.h" struct _MetaSurfaceActorWaylandPrivate { diff --git a/src/compositor/meta-surface-actor-wayland.h b/src/compositor/meta-surface-actor-wayland.h index 89c6b300f..fbca3ff4d 100644 --- a/src/compositor/meta-surface-actor-wayland.h +++ b/src/compositor/meta-surface-actor-wayland.h @@ -29,7 +29,7 @@ #include "meta-surface-actor.h" -#include "meta-wayland-private.h" +#include "meta-wayland.h" G_BEGIN_DECLS diff --git a/src/compositor/meta-surface-actor.c b/src/compositor/meta-surface-actor.c index 1d9a7ad35..7b4fc298d 100644 --- a/src/compositor/meta-surface-actor.c +++ b/src/compositor/meta-surface-actor.c @@ -15,7 +15,6 @@ #include #include -#include "meta-wayland-private.h" #include "meta-cullable.h" #include "meta-shaped-texture-private.h" diff --git a/src/compositor/meta-window-actor-private.h b/src/compositor/meta-window-actor-private.h index 021ddc607..2d2785055 100644 --- a/src/compositor/meta-window-actor-private.h +++ b/src/compositor/meta-window-actor-private.h @@ -5,9 +5,6 @@ #include -#include -#include - #include #include #include "meta-surface-actor.h" diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 89c6b4e93..cf62d998f 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -28,9 +28,9 @@ #include "meta-window-actor-private.h" #include "meta-texture-rectangle.h" #include "region-utils.h" -#include "meta-wayland-private.h" #include "monitor-private.h" #include "meta-cullable.h" +#include "meta-wayland-private.h" #include "meta-surface-actor.h" #include "meta-surface-actor-x11.h" diff --git a/src/core/keybindings.c b/src/core/keybindings.c index 6004829c9..adfa2c677 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -41,7 +41,7 @@ #include "screen-private.h" #include #include "util-private.h" -#include "meta-wayland-private.h" +#include "meta-wayland.h" #include #include diff --git a/src/core/main.c b/src/core/main.c index 84da691d1..5a8f91b66 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -53,7 +53,7 @@ #include "session.h" #include #include -#include "meta-wayland-private.h" +#include "meta-wayland.h" #include #include diff --git a/src/core/monitor.c b/src/core/monitor.c index 9c22992ac..2b2c1f781 100644 --- a/src/core/monitor.c +++ b/src/core/monitor.c @@ -34,7 +34,6 @@ #include "util-private.h" #include #include "monitor-private.h" -#include "meta-wayland-private.h" #include "meta-dbus-xrandr.h" diff --git a/src/core/screen.c b/src/core/screen.c index d99814b2d..5bcc6bf5b 100644 --- a/src/core/screen.c +++ b/src/core/screen.c @@ -43,7 +43,7 @@ #include #include "mutter-enum-types.h" #include "core.h" -#include "meta-wayland-private.h" +#include "meta-wayland.h" #include "meta-cursor-tracker-private.h" #include diff --git a/src/wayland/meta-wayland-keyboard.h b/src/wayland/meta-wayland-keyboard.h index b51d3c02a..8d2cb0609 100644 --- a/src/wayland/meta-wayland-keyboard.h +++ b/src/wayland/meta-wayland-keyboard.h @@ -47,6 +47,7 @@ #include #include +#include struct _MetaWaylandKeyboardGrabInterface { diff --git a/src/wayland/meta-wayland-private.h b/src/wayland/meta-wayland-private.h index 69de1b8b8..a2a2b90a5 100644 --- a/src/wayland/meta-wayland-private.h +++ b/src/wayland/meta-wayland-private.h @@ -21,7 +21,6 @@ #define META_WAYLAND_PRIVATE_H #include -#include #include #include @@ -31,7 +30,7 @@ #include "meta-weston-launch.h" #include -#include "meta-wayland-types.h" +#include "meta-wayland.h" #include "meta-wayland-versions.h" #include "meta-wayland-surface.h" #include "meta-wayland-seat.h" @@ -91,30 +90,8 @@ struct _MetaWaylandCompositor MetaWaylandSeat *seat; }; -void meta_wayland_init (void); -void meta_wayland_finalize (void); - -/* We maintain a singleton MetaWaylandCompositor which can be got at via this - * API after meta_wayland_init() has been called. */ -MetaWaylandCompositor *meta_wayland_compositor_get_default (void); - -void meta_wayland_compositor_repick (MetaWaylandCompositor *compositor); - -void meta_wayland_compositor_set_input_focus (MetaWaylandCompositor *compositor, - MetaWindow *window); -gboolean meta_wayland_compositor_handle_event (MetaWaylandCompositor *compositor, - const ClutterEvent *event); - MetaWaylandBuffer * meta_wayland_buffer_from_resource (struct wl_resource *resource); void meta_wayland_buffer_ref (MetaWaylandBuffer *buffer); void meta_wayland_buffer_unref (MetaWaylandBuffer *buffer); -void meta_wayland_compositor_update (MetaWaylandCompositor *compositor, - const ClutterEvent *event); -void meta_wayland_compositor_paint_finished (MetaWaylandCompositor *compositor); - -gboolean meta_wayland_compositor_activate_vt (MetaWaylandCompositor *compositor, - int vt, - GError **error); - #endif /* META_WAYLAND_PRIVATE_H */ diff --git a/src/wayland/meta-wayland.h b/src/wayland/meta-wayland.h new file mode 100644 index 000000000..481695a75 --- /dev/null +++ b/src/wayland/meta-wayland.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2014 Red Hat + * + * 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. + * + * Written by: + * Jasper St. Pierre + */ + +#ifndef META_WAYLAND_H +#define META_WAYLAND_H + +#include "meta-wayland-types.h" + +void meta_wayland_init (void); +void meta_wayland_finalize (void); + +/* We maintain a singleton MetaWaylandCompositor which can be got at via this + * API after meta_wayland_init() has been called. */ +MetaWaylandCompositor *meta_wayland_compositor_get_default (void); + +void meta_wayland_compositor_repick (MetaWaylandCompositor *compositor); + +void meta_wayland_compositor_set_input_focus (MetaWaylandCompositor *compositor, + MetaWindow *window); +gboolean meta_wayland_compositor_handle_event (MetaWaylandCompositor *compositor, + const ClutterEvent *event); + +void meta_wayland_compositor_update (MetaWaylandCompositor *compositor, + const ClutterEvent *event); +void meta_wayland_compositor_paint_finished (MetaWaylandCompositor *compositor); + +gboolean meta_wayland_compositor_activate_vt (MetaWaylandCompositor *compositor, + int vt, + GError **error); + +#endif + From d41fba6558c8964d6118e131544adb7b650f6e3e Mon Sep 17 00:00:00 2001 From: Adel Gadllah Date: Fri, 28 Feb 2014 16:38:07 +0100 Subject: [PATCH 595/889] meta-shaped-texture: Check if the parent has mapped clones as well When the WindowActor has mapped clones we should ignore the unobscured region as well, so we need to walk up and check it as well. https://bugzilla.gnome.org/show_bug.cgi?id=725180 --- src/compositor/meta-shaped-texture.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c index 30697ee6a..bbcf0f9ce 100644 --- a/src/compositor/meta-shaped-texture.c +++ b/src/compositor/meta-shaped-texture.c @@ -33,6 +33,7 @@ #include "meta-texture-tower.h" #include "meta-shaped-texture-private.h" +#include "meta-window-actor-private.h" #include #include @@ -576,8 +577,18 @@ static cairo_region_t * effective_unobscured_region (MetaShapedTexture *self) { MetaShapedTexturePrivate *priv = self->priv; + ClutterActor *parent = clutter_actor_get_parent (CLUTTER_ACTOR (self)); - return clutter_actor_has_mapped_clones (CLUTTER_ACTOR (self)) ? NULL : priv->unobscured_region; + if (clutter_actor_has_mapped_clones (CLUTTER_ACTOR (self))) + return NULL; + + while (parent && !META_IS_WINDOW_ACTOR (parent)) + parent = clutter_actor_get_parent (parent); + + if (parent && clutter_actor_has_mapped_clones (parent)) + return NULL; + + return priv->unobscured_region; } gboolean From 0313b38dd623221a34ac62ee6d06ddffd88360cd Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Fri, 28 Feb 2014 18:16:01 +0100 Subject: [PATCH 596/889] wayland: Don't try to disconnect the listener from the signal handler This is not needed since the instance is being destroyed and in fact actively harmful when code called from other handlers disconnects us for other reasons. In that case we might crash because the disconnection doesn't prevent other handlers from running in the current signal emission and thus we try to remove ourselves from an empty list. --- src/wayland/meta-wayland-keyboard.c | 2 -- src/wayland/meta-wayland-pointer.c | 2 -- src/wayland/meta-wayland-surface.c | 1 - 3 files changed, 5 deletions(-) diff --git a/src/wayland/meta-wayland-keyboard.c b/src/wayland/meta-wayland-keyboard.c index c357b77f1..477d56321 100644 --- a/src/wayland/meta-wayland-keyboard.c +++ b/src/wayland/meta-wayland-keyboard.c @@ -222,7 +222,6 @@ keyboard_handle_focus_surface_destroy (struct wl_listener *listener, void *data) { MetaWaylandKeyboard *keyboard = wl_container_of (listener, keyboard, focus_surface_listener); - wl_list_remove (&keyboard->focus_surface_listener.link); keyboard->focus_surface = NULL; if (keyboard->focus_resource) @@ -237,7 +236,6 @@ keyboard_handle_focus_resource_destroy (struct wl_listener *listener, void *data { MetaWaylandKeyboard *keyboard = wl_container_of (listener, keyboard, focus_resource_listener); - wl_list_remove (&keyboard->focus_resource_listener.link); keyboard->focus_resource = NULL; } diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index e0c9ad21a..2692c85df 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -59,7 +59,6 @@ pointer_handle_focus_surface_destroy (struct wl_listener *listener, void *data) { MetaWaylandPointer *pointer = wl_container_of (listener, pointer, focus_surface_listener); - wl_list_remove (&pointer->focus_surface_listener.link); pointer->focus_surface = NULL; if (pointer->focus_resource) @@ -74,7 +73,6 @@ pointer_handle_focus_resource_destroy (struct wl_listener *listener, void *data) { MetaWaylandPointer *pointer = wl_container_of (listener, pointer, focus_resource_listener); - wl_list_remove (&pointer->focus_resource_listener.link); pointer->focus_resource = NULL; } diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 315393901..ebf0c52f9 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -82,7 +82,6 @@ surface_handle_buffer_destroy (struct wl_listener *listener, void *data) wl_resource_post_error (surface->resource, WL_DISPLAY_ERROR_INVALID_OBJECT, "Destroyed buffer while it was attached to the surface"); surface->buffer = NULL; - wl_list_remove (&surface->buffer_destroy_listener.link); } static void From ddc171220a92b6a1ac8b73f7f256a32f3113a0cb Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 28 Feb 2014 13:18:37 -0500 Subject: [PATCH 597/889] wayland: Remove destroy listener Do to a bad mixup, the surface listener was never actually fired. This was accidentally fixed as part of a refactoring in a27fb19, but the surface listener was broken, and we started crashing. To fix, just remove the surface listener, as we've mostly been testing without it. --- src/wayland/meta-wayland-surface.c | 12 ------------ src/wayland/meta-wayland-surface.h | 1 - 2 files changed, 13 deletions(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index ebf0c52f9..15c94ea9a 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -646,18 +646,9 @@ meta_wayland_surface_create (MetaWaylandCompositor *compositor, static void destroy_surface_extension (MetaWaylandSurfaceExtension *extension) { - wl_list_remove (&extension->surface_destroy_listener.link); extension->resource = NULL; } -static void -extension_handle_surface_destroy (struct wl_listener *listener, - void *data) -{ - MetaWaylandSurfaceExtension *extension = wl_container_of (listener, extension, surface_destroy_listener); - wl_resource_destroy (extension->resource); -} - static int get_resource_version (struct wl_resource *master_resource, int max_version) @@ -684,9 +675,6 @@ create_surface_extension (MetaWaylandSurfaceExtension *extension, extension->resource = wl_resource_create (client, interface, get_resource_version (master_resource, max_version), id); wl_resource_set_implementation (extension->resource, implementation, surface, destructor); - extension->surface_destroy_listener.notify = extension_handle_surface_destroy; - wl_resource_add_destroy_listener (surface->resource, &extension->surface_destroy_listener); - return TRUE; } diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h index e0203f58c..ef9ccaa4f 100644 --- a/src/wayland/meta-wayland-surface.h +++ b/src/wayland/meta-wayland-surface.h @@ -75,7 +75,6 @@ typedef struct typedef struct { struct wl_resource *resource; - struct wl_listener surface_destroy_listener; } MetaWaylandSurfaceExtension; struct _MetaWaylandSurface From 94f39a493ffe24013d38c47ef7659218e0f91de5 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 598/889] 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 cf62d998f..a26d342bc 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -1714,7 +1714,8 @@ build_and_scan_frame_mask (MetaWindowActor *self, } meta_shaped_texture_set_mask_texture (stex, mask_texture); - cogl_object_unref (mask_texture); + if (mask_texture) + cogl_object_unref (mask_texture); g_free (mask_data); } From 701e06d55db4fabc687488709161ade00422a6c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Thu, 27 Feb 2014 18:31:33 +0100 Subject: [PATCH 599/889] keybindings: Make move-to-monitor-* bindings known to g-c-c Commit 0fe5c4f95774b85 implemented new keybindings to move windows between monitors, but did not add it to the appropriate keybinding file. https://bugzilla.gnome.org/show_bug.cgi?id=725338 --- src/50-mutter-navigation.xml.in | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/50-mutter-navigation.xml.in b/src/50-mutter-navigation.xml.in index 829bef80f..0ed73b7f6 100644 --- a/src/50-mutter-navigation.xml.in +++ b/src/50-mutter-navigation.xml.in @@ -29,6 +29,18 @@ + + + + + + + + From 4f7e2a9f3fe240d4b46cea1b740fa3df6b21697c Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Sun, 2 Mar 2014 23:16:50 +0100 Subject: [PATCH 600/889] MetaScreen: include _GTK_FRAME_EXTENTS in _NET_SUPPORTED This enables CSD for X11 clients (in XWayland and in X11) --- src/core/screen.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/core/screen.c b/src/core/screen.c index 5bcc6bf5b..cf127ac34 100644 --- a/src/core/screen.c +++ b/src/core/screen.c @@ -308,6 +308,8 @@ set_supported_hint (MetaScreen *screen) #include #undef item #undef EWMH_ATOMS_ONLY + + screen->display->atom__GTK_FRAME_EXTENTS, }; XChangeProperty (screen->display->xdisplay, screen->xroot, From 80de8ec64382a6c4096dd5038c4c2968e2432666 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 3 Mar 2014 18:43:12 -0500 Subject: [PATCH 601/889] monitor-kms: Fix copy-paste error with DPMS mode enum --- src/core/monitor-kms.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/monitor-kms.c b/src/core/monitor-kms.c index afdd7bb1e..a44df83c2 100644 --- a/src/core/monitor-kms.c +++ b/src/core/monitor-kms.c @@ -650,7 +650,7 @@ meta_monitor_manager_kms_set_power_save_mode (MetaMonitorManager *manager, state = DRM_MODE_DPMS_SUSPEND; break; case META_POWER_SAVE_OFF: - state = DRM_MODE_DPMS_SUSPEND; + state = DRM_MODE_DPMS_OFF; break; default: return; From f3b6fead4d64abb09f67766d3e7726ae2970ac8f Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Tue, 25 Feb 2014 19:07:49 +0100 Subject: [PATCH 602/889] keybindings: Make MetaKeyPref, MetaKeyCombo and MetaKeyHandler private There's no need for these to be public and keeping them all together in the same header makes it easier when reading the code. https://bugzilla.gnome.org/show_bug.cgi?id=725588 --- src/core/keybindings-private.h | 42 +++++++++++++++++++++++++++++++ src/core/prefs.c | 5 ---- src/meta/prefs.h | 45 ---------------------------------- 3 files changed, 42 insertions(+), 50 deletions(-) diff --git a/src/core/keybindings-private.h b/src/core/keybindings-private.h index 3ef3dd49c..491d41e12 100644 --- a/src/core/keybindings-private.h +++ b/src/core/keybindings-private.h @@ -30,6 +30,7 @@ #include #include +typedef struct _MetaKeyHandler MetaKeyHandler; struct _MetaKeyHandler { char *name; @@ -51,6 +52,44 @@ struct _MetaKeyBinding MetaKeyHandler *handler; }; +/** + * MetaKeyCombo: + * @keysym: keysym + * @keycode: keycode + * @modifiers: modifiers + */ +typedef struct _MetaKeyCombo MetaKeyCombo; +struct _MetaKeyCombo +{ + unsigned int keysym; + unsigned int keycode; + MetaVirtualModifier modifiers; +}; + +typedef struct +{ + char *name; + GSettings *settings; + + MetaKeyBindingAction action; + + /* + * A list of MetaKeyCombos. Each of them is bound to + * this keypref. If one has keysym==modifiers==0, it is + * ignored. + */ + GSList *bindings; + + /* for keybindings that can have shift or not like Alt+Tab */ + gboolean add_shift:1; + + /* for keybindings that apply only to a window */ + gboolean per_window:1; + + /* for keybindings not added with meta_display_add_keybinding() */ + gboolean builtin:1; +} MetaKeyPref; + void meta_display_init_keys (MetaDisplay *display); void meta_display_shutdown_keys (MetaDisplay *display); void meta_screen_grab_keys (MetaScreen *screen); @@ -78,5 +117,8 @@ gboolean meta_prefs_add_keybinding (const char *name, gboolean meta_prefs_remove_keybinding (const char *name); +GList *meta_prefs_get_keybindings (void); +void meta_prefs_get_overlay_binding (MetaKeyCombo *combo); +const char *meta_prefs_get_iso_next_group_option (void); #endif diff --git a/src/core/prefs.c b/src/core/prefs.c index 80db6f392..85ecb0c17 100644 --- a/src/core/prefs.c +++ b/src/core/prefs.c @@ -2154,11 +2154,6 @@ meta_prefs_remove_keybinding (const char *name) return TRUE; } -/** - * meta_prefs_get_keybindings: - * - * Returns: (element-type MetaKeyPref) (transfer container): - */ GList * meta_prefs_get_keybindings () { diff --git a/src/meta/prefs.h b/src/meta/prefs.h index c8cc540b1..677110a18 100644 --- a/src/meta/prefs.h +++ b/src/meta/prefs.h @@ -371,20 +371,6 @@ typedef enum META_KEY_BINDING_IS_REVERSED = 1 << 3 } MetaKeyBindingFlags; -/** - * MetaKeyCombo: - * @keysym: keysym - * @keycode: keycode - * @modifiers: modifiers - */ -typedef struct _MetaKeyCombo MetaKeyCombo; -struct _MetaKeyCombo -{ - unsigned int keysym; - unsigned int keycode; - MetaVirtualModifier modifiers; -}; - /** * MetaKeyHandlerFunc: * @display: a #MetaDisplay @@ -402,45 +388,14 @@ typedef void (* MetaKeyHandlerFunc) (MetaDisplay *display, MetaKeyBinding *binding, gpointer user_data); -typedef struct _MetaKeyHandler MetaKeyHandler; - -typedef struct -{ - char *name; - GSettings *settings; - - MetaKeyBindingAction action; - - /* - * A list of MetaKeyCombos. Each of them is bound to - * this keypref. If one has keysym==modifiers==0, it is - * ignored. - */ - GSList *bindings; - - /* for keybindings that can have shift or not like Alt+Tab */ - gboolean add_shift:1; - - /* for keybindings that apply only to a window */ - gboolean per_window:1; - - /* for keybindings not added with meta_display_add_keybinding() */ - gboolean builtin:1; -} MetaKeyPref; - GType meta_key_binding_get_type (void); -GList *meta_prefs_get_keybindings (void); - MetaKeyBindingAction meta_prefs_get_keybinding_action (const char *name); void meta_prefs_get_window_binding (const char *name, unsigned int *keysym, MetaVirtualModifier *modifiers); -void meta_prefs_get_overlay_binding (MetaKeyCombo *combo); -const char *meta_prefs_get_iso_next_group_option (void); - gboolean meta_prefs_get_visual_bell (void); gboolean meta_prefs_bell_is_audible (void); GDesktopVisualBellType meta_prefs_get_visual_bell_type (void); From 46cbd0bf4897bd53819b4a01256a44a3ea500a7b Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Tue, 25 Feb 2014 19:49:16 +0100 Subject: [PATCH 603/889] keybindings: Rename MetaKeyPref.bindings to MetaKeyPref.combos Let's call it what it really is, otherwise it's just confusing since MetaKeyBinding also exists. https://bugzilla.gnome.org/show_bug.cgi?id=725588 --- src/core/keybindings-private.h | 2 +- src/core/keybindings.c | 4 ++-- src/core/prefs.c | 22 +++++++++++----------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/core/keybindings-private.h b/src/core/keybindings-private.h index 491d41e12..15c1700bd 100644 --- a/src/core/keybindings-private.h +++ b/src/core/keybindings-private.h @@ -78,7 +78,7 @@ typedef struct * this keypref. If one has keysym==modifiers==0, it is * ignored. */ - GSList *bindings; + GSList *combos; /* for keybindings that can have shift or not like Alt+Tab */ gboolean add_shift:1; diff --git a/src/core/keybindings.c b/src/core/keybindings.c index adfa2c677..8caa02cc9 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -531,7 +531,7 @@ count_bindings (GList *prefs) while (p) { MetaKeyPref *pref = (MetaKeyPref*)p->data; - GSList *tmp = pref->bindings; + GSList *tmp = pref->combos; while (tmp) { @@ -575,7 +575,7 @@ rebuild_binding_table (MetaDisplay *display, while (p) { MetaKeyPref *pref = (MetaKeyPref*)p->data; - GSList *tmp = pref->bindings; + GSList *tmp = pref->combos; while (tmp) { diff --git a/src/core/prefs.c b/src/core/prefs.c index 85ecb0c17..a2d01deaf 100644 --- a/src/core/prefs.c +++ b/src/core/prefs.c @@ -1856,7 +1856,7 @@ init_bindings (void) pref = g_new0 (MetaKeyPref, 1); pref->name = g_strdup ("overlay-key"); pref->action = META_KEYBINDING_ACTION_OVERLAY_KEY; - pref->bindings = g_slist_prepend (pref->bindings, &overlay_key_combo); + pref->combos = g_slist_prepend (pref->combos, &overlay_key_combo); pref->builtin = 1; g_hash_table_insert (key_bindings, g_strdup ("overlay-key"), pref); @@ -1866,7 +1866,7 @@ static gboolean update_binding (MetaKeyPref *binding, gchar **strokes) { - GSList *old_bindings, *a, *b; + GSList *old_combos, *a, *b; gboolean changed; unsigned int keysym; unsigned int keycode; @@ -1878,8 +1878,8 @@ update_binding (MetaKeyPref *binding, "Binding \"%s\" has new GSettings value\n", binding->name); - old_bindings = binding->bindings; - binding->bindings = NULL; + old_combos = binding->combos; + binding->combos = NULL; for (i = 0; strokes && strokes[i]; i++) { @@ -1920,17 +1920,17 @@ update_binding (MetaKeyPref *binding, combo->keysym = keysym; combo->keycode = keycode; combo->modifiers = mods; - binding->bindings = g_slist_prepend (binding->bindings, combo); + binding->combos = g_slist_prepend (binding->combos, combo); meta_topic (META_DEBUG_KEYBINDINGS, "New keybinding for \"%s\" is keysym = 0x%x keycode = 0x%x mods = 0x%x\n", binding->name, keysym, keycode, mods); } - binding->bindings = g_slist_reverse (binding->bindings); + binding->combos = g_slist_reverse (binding->combos); - a = old_bindings; - b = binding->bindings; + a = old_combos; + b = binding->combos; while (TRUE) { if ((!a && b) || (a && !b)) @@ -1955,7 +1955,7 @@ update_binding (MetaKeyPref *binding, } } - g_slist_free_full (old_bindings, g_free); + g_slist_free_full (old_combos, g_free); return changed; } @@ -2090,7 +2090,7 @@ meta_prefs_add_keybinding (const char *name, pref->name = g_strdup (name); pref->settings = g_object_ref (settings); pref->action = action; - pref->bindings = NULL; + pref->combos = NULL; pref->add_shift = (flags & META_KEY_BINDING_REVERSES) != 0; pref->per_window = (flags & META_KEY_BINDING_PER_WINDOW) != 0; pref->builtin = (flags & META_KEY_BINDING_BUILTIN) != 0; @@ -2254,7 +2254,7 @@ meta_prefs_get_window_binding (const char *name, if (pref->per_window) { - GSList *s = pref->bindings; + GSList *s = pref->combos; while (s) { From d417c615d56f54eb194aac1ccf3da328a76e7885 Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Mon, 3 Mar 2014 19:33:08 +0100 Subject: [PATCH 604/889] keybindings: Use display_get_keybinding() instead of looping explicitly Instead of looping over an array of keybindings to find the correct binding, just use display_get_keybinding(). In the next commit, we'll change the array to be a hash map, so this helps the patch be cleaner. https://bugzilla.gnome.org/show_bug.cgi?id=725588 --- src/core/keybindings.c | 97 ++++++++++++++++++++---------------------- 1 file changed, 46 insertions(+), 51 deletions(-) diff --git a/src/core/keybindings.c b/src/core/keybindings.c index 8caa02cc9..25553a9e9 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -752,6 +752,8 @@ display_get_keybinding (MetaDisplay *display, { int i; + mask = mask & 0xff & ~display->ignored_modifier_mask; + i = display->n_key_bindings - 1; while (i >= 0) { @@ -915,7 +917,6 @@ meta_display_get_keybinding_action (MetaDisplay *display, if (keycode == (unsigned int)display->overlay_key_combo.keycode) return META_KEYBINDING_ACTION_OVERLAY_KEY; - mask = mask & 0xff & ~display->ignored_modifier_mask; binding = display_get_keybinding (display, keycode, mask); if (binding) @@ -1299,7 +1300,6 @@ meta_display_grab_accelerator (MetaDisplay *display, guint mask = 0; MetaVirtualModifier modifiers = 0; GSList *l; - int i; if (!meta_ui_parse_accelerator (accelerator, &keysym, &keycode, &modifiers)) { @@ -1316,10 +1316,8 @@ meta_display_grab_accelerator (MetaDisplay *display, if (keycode == 0) return META_KEYBINDING_ACTION_NONE; - for (i = 0; i < display->n_key_bindings; i++) - if (display->key_bindings[i].keycode == keycode && - display->key_bindings[i].mask == mask) - return META_KEYBINDING_ACTION_NONE; + if (display_get_keybinding (display, keycode, mask)) + return META_KEYBINDING_ACTION_NONE; for (l = display->screens; l; l = l->next) { @@ -1357,9 +1355,9 @@ gboolean meta_display_ungrab_accelerator (MetaDisplay *display, guint action) { + MetaKeyBinding *binding; MetaKeyGrab *grab; char *key; - int i; g_return_val_if_fail (action != META_KEYBINDING_ACTION_NONE, FALSE); @@ -1368,27 +1366,26 @@ meta_display_ungrab_accelerator (MetaDisplay *display, if (!grab) return FALSE; - for (i = 0; i < display->n_key_bindings; i++) - if (display->key_bindings[i].keysym == grab->combo->keysym && - display->key_bindings[i].keycode == grab->combo->keycode && - display->key_bindings[i].modifiers == grab->combo->modifiers) - { - GSList *l; - for (l = display->screens; l; l = l->next) - { - MetaScreen *screen = l->data; - meta_change_keygrab (display, screen->xroot, FALSE, - display->key_bindings[i].keysym, - display->key_bindings[i].keycode, - display->key_bindings[i].mask); - } + binding = display_get_keybinding (display, + grab->combo->keycode, + grab->combo->modifiers); + if (binding) + { + GSList *l; + for (l = display->screens; l; l = l->next) + { + MetaScreen *screen = l->data; + meta_change_keygrab (display, screen->xroot, FALSE, + binding->keysym, + binding->keycode, + binding->mask); + } - display->key_bindings[i].keysym = 0; - display->key_bindings[i].keycode = 0; - display->key_bindings[i].modifiers = 0; - display->key_bindings[i].mask = 0; - break; - } + binding->keysym = 0; + binding->keycode = 0; + binding->modifiers = 0; + binding->mask = 0; + } g_hash_table_remove (external_grabs, key); g_free (key); @@ -1673,7 +1670,7 @@ process_event (MetaKeyBinding *bindings, MetaWindow *window, ClutterKeyEvent *event) { - int i; + MetaKeyBinding *binding; /* we used to have release-based bindings but no longer. */ if (event->type == CLUTTER_KEY_RELEASE) @@ -1683,34 +1680,32 @@ process_event (MetaKeyBinding *bindings, * TODO: This would be better done with a hash table; * it doesn't suit to use O(n) for such a common operation. */ - for (i=0; ihardware_keycode, + event->modifier_state); + if (!binding || + (!window && binding->flags & META_KEY_BINDING_PER_WINDOW) || + meta_compositor_filter_keybinding (display->compositor, screen, binding)) + goto not_found; - if ((!window && handler->flags & META_KEY_BINDING_PER_WINDOW) || - (event->hardware_keycode != bindings[i].keycode) || - (event->modifier_state != bindings[i].mask) || - meta_compositor_filter_keybinding (display->compositor, screen, &bindings[i])) - continue; + if (binding->handler == NULL) + meta_bug ("Binding %s has no handler\n", binding->name); + else + meta_topic (META_DEBUG_KEYBINDINGS, + "Running handler for %s\n", + binding->name); - if (handler == NULL) - meta_bug ("Binding %s has no handler\n", bindings[i].name); - else - meta_topic (META_DEBUG_KEYBINDINGS, - "Running handler for %s\n", - bindings[i].name); + /* Global keybindings count as a let-the-terminal-lose-focus + * due to new window mapping until the user starts + * interacting with the terminal again. + */ + display->allow_terminal_deactivation = TRUE; - /* Global keybindings count as a let-the-terminal-lose-focus - * due to new window mapping until the user starts - * interacting with the terminal again. - */ - display->allow_terminal_deactivation = TRUE; + invoke_handler (display, screen, binding->handler, window, event, binding); - invoke_handler (display, screen, handler, window, event, &bindings[i]); - - return TRUE; - } + return TRUE; + not_found: meta_topic (META_DEBUG_KEYBINDINGS, "No handler found for this event in this binding table\n"); return FALSE; From 46af3ef9f610f7f09884804b5bb6b55da343e8cd Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Mon, 3 Mar 2014 14:08:34 +0100 Subject: [PATCH 605/889] keybindings: Keep keybindings in an hash table instead of an array This allows us to look for a match with an O(1) search instead of O(n) which is nice, particularly when running as a wayland compositor in which case we have to do this search for every key press event (as opposed to only when our passive grab triggers in the X compositor case). We actually need two hash tables. On one we keep all the keybindings themselves which allows us to add external grabs without constantly re-allocating the array we were using previously. The other hash table is an index of the keybindings in the first table by their keycodes and mask which is how we actually match the key press events. This second table thus needs to be rebuilt when the keymap changes since keycodes have to be resolved then but since we're only keeping pointers to the first table it's a fast operation. https://bugzilla.gnome.org/show_bug.cgi?id=725588 --- src/core/display-private.h | 4 +- src/core/keybindings.c | 344 ++++++++++++++++++------------------- 2 files changed, 169 insertions(+), 179 deletions(-) diff --git a/src/core/display-private.h b/src/core/display-private.h index 8973a59e3..281cc92b2 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -232,8 +232,8 @@ struct _MetaDisplay int grab_resize_timeout_id; /* Keybindings stuff */ - MetaKeyBinding *key_bindings; - int n_key_bindings; + GHashTable *key_bindings; + GHashTable *key_bindings_index; int min_keycode; int max_keycode; KeySym *keymap; diff --git a/src/core/keybindings.c b/src/core/keybindings.c index 25553a9e9..1885b38bb 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -157,6 +157,22 @@ meta_key_grab_free (MetaKeyGrab *grab) g_free (grab); } +static guint32 +key_binding_key (guint32 keycode, + guint32 mask) +{ + /* On X, keycodes are only 8 bits while libxkbcommon supports 32 bit + keycodes, but since we're using the same XKB keymaps that X uses, + we won't find keycodes bigger than 8 bits in practice. The bits + that mutter cares about in the modifier mask are also all in the + lower 8 bits both on X and clutter key events. This means that we + can use a 32 bit integer to safely concatenate both keycode and + mask and thus making it easy to use them as an index in a + GHashTable. */ + guint32 key = keycode & 0xffff; + return (key << 16) | (mask & 0xffff); +} + static void reload_keymap (MetaDisplay *display) @@ -455,6 +471,18 @@ keysym_to_keycode (MetaDisplay *display, return XKeysymToKeycode (display->xdisplay, keysym); } +static void +binding_reload_keycode_foreach (gpointer key, + gpointer value, + gpointer data) +{ + MetaDisplay *display = data; + MetaKeyBinding *binding = value; + + if (binding->keysym) + binding->keycode = keysym_to_keycode (display, binding->keysym); +} + static void reload_keycodes (MetaDisplay *display) { @@ -473,22 +501,25 @@ reload_keycodes (MetaDisplay *display) reload_iso_next_group_combos (display); - if (display->key_bindings) - { - int i; + g_hash_table_foreach (display->key_bindings, binding_reload_keycode_foreach, display); +} - i = 0; - while (i < display->n_key_bindings) - { - if (display->key_bindings[i].keysym != 0) - { - display->key_bindings[i].keycode = - keysym_to_keycode (display, display->key_bindings[i].keysym); - } +static void +binding_reload_modifiers_foreach (gpointer key, + gpointer value, + gpointer data) +{ + MetaDisplay *display = data; + MetaKeyBinding *binding = value; - ++i; - } - } + meta_display_devirtualize_modifiers (display, + binding->modifiers, + &binding->mask); + meta_topic (META_DEBUG_KEYBINDINGS, + " Devirtualized mods 0x%x -> 0x%x (%s)\n", + binding->modifiers, + binding->mask, + binding->name); } static void @@ -497,80 +528,48 @@ reload_modifiers (MetaDisplay *display) meta_topic (META_DEBUG_KEYBINDINGS, "Reloading keycodes for binding tables\n"); - if (display->key_bindings) - { - int i; - - i = 0; - while (i < display->n_key_bindings) - { - meta_display_devirtualize_modifiers (display, - display->key_bindings[i].modifiers, - &display->key_bindings[i].mask); - - meta_topic (META_DEBUG_KEYBINDINGS, - " Devirtualized mods 0x%x -> 0x%x (%s)\n", - display->key_bindings[i].modifiers, - display->key_bindings[i].mask, - display->key_bindings[i].name); - - ++i; - } - } + g_hash_table_foreach (display->key_bindings, binding_reload_modifiers_foreach, display); } - -static int -count_bindings (GList *prefs) +static void +index_binding (MetaDisplay *display, + MetaKeyBinding *binding) { - GList *p; - int count; + guint32 index_key; - count = 0; - p = prefs; - while (p) - { - MetaKeyPref *pref = (MetaKeyPref*)p->data; - GSList *tmp = pref->combos; + index_key = key_binding_key (binding->keycode, binding->mask); + g_hash_table_replace (display->key_bindings_index, + GINT_TO_POINTER (index_key), binding); +} - while (tmp) - { - MetaKeyCombo *combo = tmp->data; +static void +binding_index_foreach (gpointer key, + gpointer value, + gpointer data) +{ + MetaDisplay *display = data; + MetaKeyBinding *binding = value; - if (combo && (combo->keysym != None || combo->keycode != 0)) - { - count += 1; + index_binding (display, binding); +} - if (pref->add_shift && - (combo->modifiers & META_VIRTUAL_SHIFT_MASK) == 0) - count += 1; - } - - tmp = tmp->next; - } - - p = p->next; - } - - return count; +static void +rebuild_binding_index (MetaDisplay *display) +{ + g_hash_table_remove_all (display->key_bindings_index); + g_hash_table_foreach (display->key_bindings, binding_index_foreach, display); } static void rebuild_binding_table (MetaDisplay *display, - MetaKeyBinding **bindings_p, - int *n_bindings_p, GList *prefs, GList *grabs) { + MetaKeyBinding *b; GList *p, *g; - int n_bindings; - int i; - n_bindings = count_bindings (prefs) + g_list_length (grabs); - g_free (*bindings_p); - *bindings_p = g_new0 (MetaKeyBinding, n_bindings); + g_hash_table_remove_all (display->key_bindings); - i = 0; p = prefs; while (p) { @@ -585,15 +584,17 @@ rebuild_binding_table (MetaDisplay *display, { MetaKeyHandler *handler = HANDLER (pref->name); - (*bindings_p)[i].name = pref->name; - (*bindings_p)[i].handler = handler; - (*bindings_p)[i].flags = handler->flags; - (*bindings_p)[i].keysym = combo->keysym; - (*bindings_p)[i].keycode = combo->keycode; - (*bindings_p)[i].modifiers = combo->modifiers; - (*bindings_p)[i].mask = 0; + b = g_malloc0 (sizeof (MetaKeyBinding)); - ++i; + b->name = pref->name; + b->handler = handler; + b->flags = handler->flags; + b->keysym = combo->keysym; + b->keycode = combo->keycode; + b->modifiers = combo->modifiers; + b->mask = 0; + + g_hash_table_add (display->key_bindings, b); if (pref->add_shift && (combo->modifiers & META_VIRTUAL_SHIFT_MASK) == 0) @@ -602,16 +603,17 @@ rebuild_binding_table (MetaDisplay *display, "Binding %s also needs Shift grabbed\n", pref->name); - (*bindings_p)[i].name = pref->name; - (*bindings_p)[i].handler = handler; - (*bindings_p)[i].flags = handler->flags; - (*bindings_p)[i].keysym = combo->keysym; - (*bindings_p)[i].keycode = combo->keycode; - (*bindings_p)[i].modifiers = combo->modifiers | - META_VIRTUAL_SHIFT_MASK; - (*bindings_p)[i].mask = 0; + b = g_malloc0 (sizeof (MetaKeyBinding)); - ++i; + b->name = pref->name; + b->handler = handler; + b->flags = handler->flags; + b->keysym = combo->keysym; + b->keycode = combo->keycode; + b->modifiers = combo->modifiers | META_VIRTUAL_SHIFT_MASK; + b->mask = 0; + + g_hash_table_add (display->key_bindings, b); } } @@ -629,27 +631,25 @@ rebuild_binding_table (MetaDisplay *display, { MetaKeyHandler *handler = HANDLER ("external-grab"); - (*bindings_p)[i].name = grab->name; - (*bindings_p)[i].handler = handler; - (*bindings_p)[i].flags = handler->flags; - (*bindings_p)[i].keysym = grab->combo->keysym; - (*bindings_p)[i].keycode = grab->combo->keycode; - (*bindings_p)[i].modifiers = grab->combo->modifiers; - (*bindings_p)[i].mask = 0; + b = g_malloc0 (sizeof (MetaKeyBinding)); - ++i; + b->name = grab->name; + b->handler = handler; + b->flags = handler->flags; + b->keysym = grab->combo->keysym; + b->keycode = grab->combo->keycode; + b->modifiers = grab->combo->modifiers; + b->mask = 0; + + g_hash_table_add (display->key_bindings, b); } g = g->next; } - g_assert (i == n_bindings); - - *n_bindings_p = i; - meta_topic (META_DEBUG_KEYBINDINGS, " %d bindings in table\n", - *n_bindings_p); + g_hash_table_size (display->key_bindings)); } static void @@ -662,10 +662,7 @@ rebuild_key_binding_table (MetaDisplay *display) prefs = meta_prefs_get_keybindings (); grabs = g_hash_table_get_values (external_grabs); - rebuild_binding_table (display, - &display->key_bindings, - &display->n_key_bindings, - prefs, grabs); + rebuild_binding_table (display, prefs, grabs); g_list_free (prefs); g_list_free (grabs); } @@ -747,26 +744,15 @@ grab_key_bindings (MetaDisplay *display) static MetaKeyBinding * display_get_keybinding (MetaDisplay *display, - unsigned int keycode, - unsigned long mask) + guint32 keycode, + guint32 mask) { - int i; + guint32 key; mask = mask & 0xff & ~display->ignored_modifier_mask; + key = key_binding_key (keycode, mask); - i = display->n_key_bindings - 1; - while (i >= 0) - { - if (display->key_bindings[i].keycode == keycode && - display->key_bindings[i].mask == mask) - { - return &display->key_bindings[i]; - } - - --i; - } - - return NULL; + return g_hash_table_lookup (display->key_bindings_index, GINT_TO_POINTER (key)); } static guint @@ -985,6 +971,8 @@ meta_display_process_mapping_event (MetaDisplay *display, reload_modifiers (display); + rebuild_binding_index (display); + grab_key_bindings (display); } } @@ -1005,6 +993,7 @@ bindings_changed_callback (MetaPreference pref, rebuild_special_bindings (display); reload_keycodes (display); reload_modifiers (display); + rebuild_binding_index (display); grab_key_bindings (display); break; default: @@ -1025,7 +1014,9 @@ meta_display_shutdown_keys (MetaDisplay *display) if (display->modmap) XFreeModifiermap (display->modmap); - g_free (display->key_bindings); + + g_hash_table_destroy (display->key_bindings_index); + g_hash_table_destroy (display->key_bindings); } static const char* @@ -1123,36 +1114,48 @@ meta_change_keygrab (MetaDisplay *display, meta_error_trap_pop (display); } +typedef struct +{ + MetaDisplay *display; + Window xwindow; + gboolean binding_per_window; + gboolean grab; +} ChangeKeygrabData; + static void -change_binding_keygrabs (MetaKeyBinding *bindings, - int n_bindings, - MetaDisplay *display, +change_keygrab_foreach (gpointer key, + gpointer value, + gpointer user_data) +{ + ChangeKeygrabData *data = user_data; + MetaKeyBinding *binding = value; + + if (!!data->binding_per_window == + !!(binding->flags & META_KEY_BINDING_PER_WINDOW) && + binding->keycode != 0) + { + meta_change_keygrab (data->display, data->xwindow, data->grab, + binding->keysym, + binding->keycode, + binding->mask); + } +} + +static void +change_binding_keygrabs (MetaDisplay *display, Window xwindow, gboolean binding_per_window, gboolean grab) { - int i; + ChangeKeygrabData data; - g_assert (n_bindings == 0 || bindings != NULL); + data.display = display; + data.xwindow = xwindow; + data.binding_per_window = binding_per_window; + data.grab = grab; meta_error_trap_push (display); - - i = 0; - while (i < n_bindings) - { - if (!!binding_per_window == - !!(bindings[i].flags & META_KEY_BINDING_PER_WINDOW) && - bindings[i].keycode != 0) - { - meta_change_keygrab (display, xwindow, grab, - bindings[i].keysym, - bindings[i].keycode, - bindings[i].mask); - } - - ++i; - } - + g_hash_table_foreach (display->key_bindings, change_keygrab_foreach, &data); meta_error_trap_pop (display); } @@ -1184,10 +1187,7 @@ meta_screen_change_keygrabs (MetaScreen *screen, } } - change_binding_keygrabs (screen->display->key_bindings, - screen->display->n_key_bindings, - screen->display, screen->xroot, - FALSE, grab); + change_binding_keygrabs (screen->display, screen->xroot, FALSE, grab); } void @@ -1220,10 +1220,7 @@ meta_window_change_keygrabs (MetaWindow *window, Window xwindow, gboolean grab) { - change_binding_keygrabs (window->display->key_bindings, - window->display->n_key_bindings, - window->display, xwindow, - TRUE, grab); + change_binding_keygrabs (window->display, xwindow, TRUE, grab); } void @@ -1294,6 +1291,7 @@ guint meta_display_grab_accelerator (MetaDisplay *display, const char *accelerator) { + MetaKeyBinding *binding; MetaKeyGrab *grab; guint keysym = 0; guint keycode = 0; @@ -1335,12 +1333,7 @@ meta_display_grab_accelerator (MetaDisplay *display, g_hash_table_insert (external_grabs, grab->name, grab); - display->n_key_bindings++; - display->key_bindings = g_renew (MetaKeyBinding, - display->key_bindings, - display->n_key_bindings); - - MetaKeyBinding *binding = &display->key_bindings[display->n_key_bindings - 1]; + binding = g_malloc0 (sizeof (MetaKeyBinding)); binding->name = grab->name; binding->handler = HANDLER ("external-grab"); binding->keysym = grab->combo->keysym; @@ -1348,6 +1341,9 @@ meta_display_grab_accelerator (MetaDisplay *display, binding->modifiers = grab->combo->modifiers; binding->mask = mask; + g_hash_table_add (display->key_bindings, binding); + index_binding (display, binding); + return grab->action; } @@ -1371,7 +1367,9 @@ meta_display_ungrab_accelerator (MetaDisplay *display, grab->combo->modifiers); if (binding) { + guint32 index_key; GSList *l; + for (l = display->screens; l; l = l->next) { MetaScreen *screen = l->data; @@ -1381,10 +1379,10 @@ meta_display_ungrab_accelerator (MetaDisplay *display, binding->mask); } - binding->keysym = 0; - binding->keycode = 0; - binding->modifiers = 0; - binding->mask = 0; + index_key = key_binding_key (binding->keycode, binding->mask); + g_hash_table_remove (display->key_bindings_index, GINT_TO_POINTER (index_key)); + + g_hash_table_remove (display->key_bindings, binding); } g_hash_table_remove (external_grabs, key); @@ -1663,9 +1661,7 @@ invoke_handler (MetaDisplay *display, } static gboolean -process_event (MetaKeyBinding *bindings, - int n_bindings, - MetaDisplay *display, +process_event (MetaDisplay *display, MetaScreen *screen, MetaWindow *window, ClutterKeyEvent *event) @@ -1676,10 +1672,6 @@ process_event (MetaKeyBinding *bindings, if (event->type == CLUTTER_KEY_RELEASE) return FALSE; - /* - * TODO: This would be better done with a hash table; - * it doesn't suit to use O(n) for such a common operation. - */ binding = display_get_keybinding (display, event->hardware_keycode, event->modifier_state); @@ -1735,9 +1727,7 @@ process_overlay_key (MetaDisplay *display, * the event. Other clients with global grabs will be out of * luck. */ - if (process_event (display->key_bindings, - display->n_key_bindings, - display, screen, window, event)) + if (process_event (display, screen, window, event)) { /* As normally, after we've handled a global key * binding, we unfreeze the keyboard but keep the grab @@ -1953,9 +1943,7 @@ meta_display_process_key_event (MetaDisplay *display, } /* Do the normal keybindings */ - return process_event (display->key_bindings, - display->n_key_bindings, - display, screen, window, event); + return process_event (display, screen, window, event); } static gboolean @@ -3944,8 +3932,9 @@ meta_display_init_keys (MetaDisplay *display) display->hyper_mask = 0; display->super_mask = 0; display->meta_mask = 0; - display->key_bindings = NULL; - display->n_key_bindings = 0; + + display->key_bindings = g_hash_table_new_full (NULL, NULL, NULL, g_free); + display->key_bindings_index = g_hash_table_new (NULL, NULL); XDisplayKeycodes (display->xdisplay, &display->min_keycode, @@ -3992,6 +3981,7 @@ meta_display_init_keys (MetaDisplay *display) reload_keycodes (display); reload_modifiers (display); + rebuild_binding_index (display); /* Keys are actually grabbed in meta_screen_grab_keys() */ From 72bd5fb814370e398258ab5046ba9b4ba1a0805b Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Tue, 4 Mar 2014 20:26:49 +0100 Subject: [PATCH 606/889] keybindings: Fix external grabs not being ungrabbed Before starting to use display_get_keybinding() we could compare MetaKeyBinding.modifiers with MetaKeyCombo.modifiers directly. Now, we need to resolve the virtual modifiers to match with the mask. --- src/core/keybindings.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/core/keybindings.c b/src/core/keybindings.c index 1885b38bb..3e9cf418a 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -1354,6 +1354,7 @@ meta_display_ungrab_accelerator (MetaDisplay *display, MetaKeyBinding *binding; MetaKeyGrab *grab; char *key; + guint mask = 0; g_return_val_if_fail (action != META_KEYBINDING_ACTION_NONE, FALSE); @@ -1362,9 +1363,9 @@ meta_display_ungrab_accelerator (MetaDisplay *display, if (!grab) return FALSE; - binding = display_get_keybinding (display, - grab->combo->keycode, - grab->combo->modifiers); + meta_display_devirtualize_modifiers (display, grab->combo->modifiers, &mask); + + binding = display_get_keybinding (display, grab->combo->keycode, mask); if (binding) { guint32 index_key; From 91384a32b467b21a0dfd9c56e3d75c687da30877 Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Tue, 4 Mar 2014 20:33:56 +0100 Subject: [PATCH 607/889] keybindings: Fix ungrabs possibly failing after switching keymaps We need to resolve the keycode from the keysym again since the keycode might have changed if there was a keymap switch between the grab and the ungrab. --- src/core/keybindings.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/core/keybindings.c b/src/core/keybindings.c index 3e9cf418a..74f40b7dd 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -1355,6 +1355,7 @@ meta_display_ungrab_accelerator (MetaDisplay *display, MetaKeyGrab *grab; char *key; guint mask = 0; + guint keycode = 0; g_return_val_if_fail (action != META_KEYBINDING_ACTION_NONE, FALSE); @@ -1364,8 +1365,9 @@ meta_display_ungrab_accelerator (MetaDisplay *display, return FALSE; meta_display_devirtualize_modifiers (display, grab->combo->modifiers, &mask); + keycode = keysym_to_keycode (display, grab->combo->keysym); - binding = display_get_keybinding (display, grab->combo->keycode, mask); + binding = display_get_keybinding (display, keycode, mask); if (binding) { guint32 index_key; From bee59ec0e1bc426143f9553d0629dfe9d495775a Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Sun, 2 Mar 2014 23:27:50 +0100 Subject: [PATCH 608/889] Use MetaCursorTracker to query the pointer position Functionally equivalent in the X11 case, but also correct for Wayland (where the X server doesn't have the updated pointer position). https://bugzilla.gnome.org/show_bug.cgi?id=725525 --- src/core/meta-cursor-tracker.c | 19 ++++++++----- src/core/screen.c | 52 ++++++---------------------------- src/core/window-x11.c | 29 +++++-------------- src/core/window.c | 28 ++++++------------ 4 files changed, 35 insertions(+), 93 deletions(-) diff --git a/src/core/meta-cursor-tracker.c b/src/core/meta-cursor-tracker.c index 32e860872..250d07e78 100644 --- a/src/core/meta-cursor-tracker.c +++ b/src/core/meta-cursor-tracker.c @@ -1076,10 +1076,12 @@ get_pointer_position_gdk (int *x, gmanager = gdk_display_get_device_manager (gdk_display_get_default ()); gdevice = gdk_device_manager_get_client_pointer (gmanager); - gdk_device_get_position (gdevice, &gscreen, x, y); - gdk_device_get_state (gdevice, - gdk_screen_get_root_window (gscreen), - NULL, (GdkModifierType*)mods); + if (x || y) + gdk_device_get_position (gdevice, &gscreen, x, y); + if (mods) + gdk_device_get_state (gdevice, + gdk_screen_get_root_window (gscreen), + NULL, (GdkModifierType*)mods); } static void @@ -1095,9 +1097,12 @@ get_pointer_position_clutter (int *x, cdevice = clutter_device_manager_get_core_device (cmanager, CLUTTER_POINTER_DEVICE); clutter_input_device_get_coords (cdevice, NULL, &point); - *x = point.x; - *y = point.y; - *mods = clutter_input_device_get_modifier_state (cdevice); + if (x) + *x = point.x; + if (y) + *y = point.y; + if (mods) + *mods = clutter_input_device_get_modifier_state (cdevice); } void diff --git a/src/core/screen.c b/src/core/screen.c index cf127ac34..f1700c580 100644 --- a/src/core/screen.c +++ b/src/core/screen.c @@ -1514,38 +1514,19 @@ meta_screen_get_mouse_window (MetaScreen *screen, MetaWindow *not_this_one) { MetaWindow *window; - Window root_return, child_return; - double root_x_return, root_y_return; - double win_x_return, win_y_return; - XIButtonState buttons; - XIModifierState mods; - XIGroupState group; + int x, y; if (not_this_one) meta_topic (META_DEBUG_FOCUS, "Focusing mouse window excluding %s\n", not_this_one->desc); - meta_error_trap_push (screen->display); - XIQueryPointer (screen->display->xdisplay, - META_VIRTUAL_CORE_POINTER_ID, - screen->xroot, - &root_return, - &child_return, - &root_x_return, - &root_y_return, - &win_x_return, - &win_y_return, - &buttons, - &mods, - &group); - meta_error_trap_pop (screen->display); - free (buttons.mask); + meta_cursor_tracker_get_pointer (screen->cursor_tracker, + &x, &y, NULL); window = meta_stack_get_default_focus_window_at_point (screen->stack, screen->active_workspace, not_this_one, - root_x_return, - root_y_return); + x, y); return window; } @@ -1827,28 +1808,11 @@ meta_screen_get_current_monitor (MetaScreen *screen) if (screen->display->monitor_cache_invalidated) { - Window root_return, child_return; - double win_x_return, win_y_return; - double root_x_return, root_y_return; - XIButtonState buttons; - XIModifierState mods; - XIGroupState group; + int x, y; - XIQueryPointer (screen->display->xdisplay, - META_VIRTUAL_CORE_POINTER_ID, - screen->xroot, - &root_return, - &child_return, - &root_x_return, - &root_y_return, - &win_x_return, - &win_y_return, - &buttons, - &mods, - &group); - free (buttons.mask); - - meta_screen_get_current_monitor_for_pos (screen, root_x_return, root_y_return); + meta_cursor_tracker_get_pointer (screen->cursor_tracker, + &x, &y, NULL); + meta_screen_get_current_monitor_for_pos (screen, x, y); } return screen->last_monitor_index; diff --git a/src/core/window-x11.c b/src/core/window-x11.c index 6c1e7e215..1d473455e 100644 --- a/src/core/window-x11.c +++ b/src/core/window-x11.c @@ -38,6 +38,7 @@ #include #include #include +#include #include "window-private.h" #include "window-props.h" @@ -673,35 +674,19 @@ meta_window_x11_property_notify (MetaWindow *window, static int query_pressed_buttons (MetaWindow *window) { - double x, y, query_root_x, query_root_y; - Window root, child; - XIButtonState buttons; - XIModifierState mods; - XIGroupState group; + ClutterModifierType mods; int button = 0; - meta_error_trap_push (window->display); - XIQueryPointer (window->display->xdisplay, - META_VIRTUAL_CORE_POINTER_ID, - window->xwindow, - &root, &child, - &query_root_x, &query_root_y, - &x, &y, - &buttons, &mods, &group); + meta_cursor_tracker_get_pointer (window->screen->cursor_tracker, + NULL, NULL, &mods); - if (meta_error_trap_pop_with_return (window->display) != Success) - goto out; - - if (XIMaskIsSet (buttons.mask, Button1)) + if (mods & CLUTTER_BUTTON1_MASK) button |= 1 << 1; - if (XIMaskIsSet (buttons.mask, Button2)) + if (mods & CLUTTER_BUTTON2_MASK) button |= 1 << 2; - if (XIMaskIsSet (buttons.mask, Button3)) + if (mods & CLUTTER_BUTTON3_MASK) button |= 1 << 3; - free (buttons.mask); - - out: return button; } diff --git a/src/core/window.c b/src/core/window.c index b506634de..a530a0cfa 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -10343,25 +10343,15 @@ window_focus_on_pointer_rest_callback (gpointer data) MetaWindow *window = focus_data->window; MetaDisplay *display = window->display; MetaScreen *screen = window->screen; - Window root, child; - double root_x, root_y, x, y; + int root_x, root_y; guint32 timestamp; - XIButtonState buttons; - XIModifierState mods; - XIGroupState group; + ClutterActor *child; if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK) goto out; - meta_error_trap_push (display); - XIQueryPointer (display->xdisplay, - META_VIRTUAL_CORE_POINTER_ID, - screen->xroot, - &root, &child, - &root_x, &root_y, &x, &y, - &buttons, &mods, &group); - meta_error_trap_pop (display); - free (buttons.mask); + meta_cursor_tracker_get_pointer (screen->cursor_tracker, + &root_x, &root_y, NULL); if (root_x != focus_data->pointer_x || root_y != focus_data->pointer_y) @@ -10371,17 +10361,15 @@ 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)) + child = clutter_stage_get_actor_at_pos (CLUTTER_STAGE (clutter_stage_get_default ()), + CLUTTER_PICK_REACTIVE, root_x, root_y); + if (!META_IS_SURFACE_ACTOR (child)) goto out; window = meta_stack_get_default_focus_window_at_point (screen->stack, screen->active_workspace, - None, root_x, root_y); + NULL, root_x, root_y); if (window == NULL) goto out; From 365af53797b54044b55c6c86660fddf38c53a2e1 Mon Sep 17 00:00:00 2001 From: "Owen W. Taylor" Date: Wed, 5 Mar 2014 15:23:46 -0500 Subject: [PATCH 609/889] Fix handling of dynamic updates to colors/font/etc. Since the introduction of frame sync in GTK+, updates to titlebar font and colors haven't been working because GTK+ counts on the frame clock to do style updates, and the frame clock doesn't run for an unmapped GdkWindow. (It's possible that GtkStyleContext changes subsequent to the introduction of the frame clock were also needed to fully break things.) We actually need to map the MetaFrames GdkWindow and let the compositor code send out the frame sync messages in order to pick up style changes. Hopefully no bad side effects will occur from this - we make the window override-redirect, 1x1, and outside the bounds of the screen. https://bugzilla.gnome.org/show_bug.cgi?id=725751 --- src/ui/frames.c | 41 +++++++++++++++++------------------------ src/ui/ui.c | 9 ++++++--- 2 files changed, 23 insertions(+), 27 deletions(-) diff --git a/src/ui/frames.c b/src/ui/frames.c index d69224ece..13633c938 100644 --- a/src/ui/frames.c +++ b/src/ui/frames.c @@ -44,8 +44,6 @@ static void meta_frames_destroy (GtkWidget *object); static void meta_frames_finalize (GObject *object); static void meta_frames_style_updated (GtkWidget *widget); -static void meta_frames_map (GtkWidget *widget); -static void meta_frames_unmap (GtkWidget *widget); static void meta_frames_update_prelit_control (MetaFrames *frames, MetaUIFrame *frame, @@ -134,9 +132,6 @@ meta_frames_class_init (MetaFramesClass *class) widget_class->style_updated = meta_frames_style_updated; - widget_class->map = meta_frames_map; - widget_class->unmap = meta_frames_unmap; - widget_class->draw = meta_frames_draw; widget_class->destroy_event = meta_frames_destroy_event; widget_class->button_press_event = meta_frames_button_press_event; @@ -231,6 +226,7 @@ meta_frames_init (MetaFrames *frames) frames->style_variants = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); + update_style_contexts (frames); gtk_widget_set_double_buffered (GTK_WIDGET (frames), FALSE); @@ -522,13 +518,26 @@ MetaFrames* meta_frames_new (int screen_number) { GdkScreen *screen; + MetaFrames *frames; screen = gdk_display_get_screen (gdk_display_get_default (), screen_number); - return g_object_new (META_TYPE_FRAMES, - "screen", screen, - NULL); + frames = g_object_new (META_TYPE_FRAMES, + "screen", screen, + "type", GTK_WINDOW_POPUP, + NULL); + + /* Put the window at an arbitrary offscreen location; the one place + * it can't be is at -100x-100, since the meta_window_new() will + * mistake it for a window created via meta_create_offscreen_window() + * and ignore it, and we need this window to get frame-synchronization + * messages so that GTK+'s style change handling works. + */ + gtk_window_move (GTK_WINDOW (frames), -200, -200); + gtk_window_resize (GTK_WINDOW (frames), 1, 1); + + return frames; } /* In order to use a style with a window it has to be attached to that @@ -635,22 +644,6 @@ meta_frames_unmanage_window (MetaFrames *frames, meta_warning ("Frame 0x%lx not managed, can't unmanage\n", xwindow); } -static void -meta_frames_map (GtkWidget *widget) -{ - /* We override the parent map function to a no-op because we don't - * want to actually show the GDK window. But GTK needs to think that - * the widget is mapped or it won't deliver the events we care about. - */ - gtk_widget_set_mapped (widget, TRUE); -} - -static void -meta_frames_unmap (GtkWidget *widget) -{ - gtk_widget_set_mapped (widget, FALSE); -} - static MetaUIFrame* meta_frames_lookup_window (MetaFrames *frames, Window xwindow) diff --git a/src/ui/ui.c b/src/ui/ui.c index 50f9071f1..1a19838f4 100644 --- a/src/ui/ui.c +++ b/src/ui/ui.c @@ -295,9 +295,12 @@ meta_ui_new (Display *xdisplay, g_assert (gdisplay == gdk_display_get_default ()); ui->frames = meta_frames_new (XScreenNumberOfScreen (screen)); - /* This does not actually show any widget. MetaFrames has been hacked so - * that showing it doesn't actually do anything. But we need the flags - * set for GTK to deliver events properly. */ + /* GTK+ needs the frame-sync protocol to work in order to properly + * handle style changes. This means that the dummy widget we create + * to get the style for title bars actually needs to be mapped + * and fully tracked as a MetaWindow. Horrible, but mostly harmless - + * the window is a 1x1 overide redirect window positioned offscreen. + */ gtk_widget_show (GTK_WIDGET (ui->frames)); g_object_set_data (G_OBJECT (gdisplay), "meta-ui", ui); From b346f98eb06ceb884b228608cff09cd263c710ce Mon Sep 17 00:00:00 2001 From: "Owen W. Taylor" Date: Wed, 5 Mar 2014 17:04:50 -0500 Subject: [PATCH 610/889] Fix positioning error for manually positioned windows The "original coordinates" passed into meta_window_place() were the coordinates of the client rectangle not the frame rectangle. When meta_window_place() didn't place because the window was manually positioned (e.g., 'xterm -geometry +x+y') that resulted in a window being offset by the frame dimensions. https://bugzilla.gnome.org/show_bug.cgi?id=724049 --- src/core/constraints.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/core/constraints.c b/src/core/constraints.c index fc5dc6f86..b59aa065f 100644 --- a/src/core/constraints.c +++ b/src/core/constraints.c @@ -491,12 +491,17 @@ place_window_if_needed(MetaWindow *window, !window->minimized && !window->fullscreen) { + MetaRectangle orig_rect; MetaRectangle placed_rect; MetaWorkspace *cur_workspace; const MetaMonitorInfo *monitor_info; meta_window_get_frame_rect (window, &placed_rect); - meta_window_place (window, info->orig.x, info->orig.y, + + orig_rect = info->orig; + extend_by_frame (window, &orig_rect); + + meta_window_place (window, orig_rect.x, orig_rect.y, &placed_rect.x, &placed_rect.y); did_placement = TRUE; From 9052efb0d9ca1bc4efcb33c81e051022a564664d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 5 Mar 2014 23:06:44 +0100 Subject: [PATCH 611/889] build: Use non-deprecated feature test macros _SVID_SOURCE has been deprecated in newer versions of glibc breaking -WError; the recommended replacement of _DEFAULT_SOURCE is fairly new, so switch to _XOPEN_SOURCE instead. --- src/core/main.c | 2 +- src/core/window-props.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/main.c b/src/core/main.c index 5a8f91b66..af6f84817 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -42,7 +42,7 @@ */ #define _GNU_SOURCE -#define _SVID_SOURCE /* for putenv() and some signal-related functions */ +#define _XOPEN_SOURCE /* for putenv() and some signal-related functions */ #include #include diff --git a/src/core/window-props.c b/src/core/window-props.c index cb6e38185..f0454fe47 100644 --- a/src/core/window-props.c +++ b/src/core/window-props.c @@ -35,7 +35,7 @@ */ #define _GNU_SOURCE -#define _SVID_SOURCE /* for gethostname() */ +#define _XOPEN_SOURCE 500 /* for gethostname() */ #include #include "window-props.h" From 54df7934ea87bce9a1abc2bf709af3b425c7025d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 5 Mar 2014 23:41:22 +0100 Subject: [PATCH 612/889] Bump version to 3.11.91 Update NEWS. --- NEWS | 14 ++++++++++++++ configure.ac | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index cf66b4132..045021e56 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,17 @@ +3.11.91 +======= +* Don't use keysym to match keybindings [Rui; #678001] +* Fix message tray icons showing up blank (again) [Adel; #725180] +* Improve keybinding lookups [Rui; #725588] +* Fix dynamic updates of titlebar style properties [Owen; #725751] +* Fix positioning of manually positioned windows [Owen; #724049] +* Misc bug fixes and cleanups [Jasper, Carlos, Adel, Giovanni, Florian; #720631, + #724969, #725216, #724402, #722266, #725338, #725525] + +Contributors: + Giovanni Campagna, Adel Gadllah, Carlos Garnacho, Rui Matos, Florian Müllner, + Jasper St. Pierre, Owen W. Taylor + 3.11.90 ======= * Fix double-scaling on high DPI resolutions [Adel; #723931] diff --git a/configure.ac b/configure.ac index aa5c06d45..785d076c7 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ AC_CONFIG_MACRO_DIR([m4]) m4_define([mutter_major_version], [3]) m4_define([mutter_minor_version], [11]) -m4_define([mutter_micro_version], [90]) +m4_define([mutter_micro_version], [91]) m4_define([mutter_version], [mutter_major_version.mutter_minor_version.mutter_micro_version]) From a8f4651c725ff328be8a637a2ecce1fa2dacffeb Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Thu, 6 Mar 2014 17:20:20 +0100 Subject: [PATCH 613/889] MetaCursorTracker: fix uninitialized screen variable We must call gdk_device_get_pointer() unconditionally, because that sets the GdkScreen argument we use to obtain the root window. --- src/core/meta-cursor-tracker.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/core/meta-cursor-tracker.c b/src/core/meta-cursor-tracker.c index 250d07e78..c718dd433 100644 --- a/src/core/meta-cursor-tracker.c +++ b/src/core/meta-cursor-tracker.c @@ -1076,8 +1076,7 @@ get_pointer_position_gdk (int *x, gmanager = gdk_display_get_device_manager (gdk_display_get_default ()); gdevice = gdk_device_manager_get_client_pointer (gmanager); - if (x || y) - gdk_device_get_position (gdevice, &gscreen, x, y); + gdk_device_get_position (gdevice, &gscreen, x, y); if (mods) gdk_device_get_state (gdevice, gdk_screen_get_root_window (gscreen), From abd2abcde67cddacdda03323138f9fb130e4eb15 Mon Sep 17 00:00:00 2001 From: Adel Gadllah Date: Thu, 6 Mar 2014 17:31:00 +0100 Subject: [PATCH 614/889] cursor-tracker: Avoid unnecessary round trip --- src/core/meta-cursor-tracker.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/meta-cursor-tracker.c b/src/core/meta-cursor-tracker.c index c718dd433..e20d70ee6 100644 --- a/src/core/meta-cursor-tracker.c +++ b/src/core/meta-cursor-tracker.c @@ -1074,7 +1074,7 @@ get_pointer_position_gdk (int *x, GdkScreen *gscreen; gmanager = gdk_display_get_device_manager (gdk_display_get_default ()); - gdevice = gdk_device_manager_get_client_pointer (gmanager); + gdevice = gdk_x11_device_manager_lookup (gmanager, META_VIRTUAL_CORE_POINTER_ID); gdk_device_get_position (gdevice, &gscreen, x, y); if (mods) From 9773a879c3e8d566ab782199ebda58df3dc542f4 Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Thu, 6 Mar 2014 19:08:01 +0100 Subject: [PATCH 615/889] cursor-tracker: Include gdk/gdkx.h Needed for the call to gdk_x11_device_manager_lookup() introduced in abd2abcde67cddacdda03323138f9fb130e4eb15 . --- src/core/meta-cursor-tracker.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/meta-cursor-tracker.c b/src/core/meta-cursor-tracker.c index e20d70ee6..973aacfb9 100644 --- a/src/core/meta-cursor-tracker.c +++ b/src/core/meta-cursor-tracker.c @@ -39,6 +39,7 @@ #include #include +#include #include #include From 38e26e5cc31c8b0edea7637f9fb223bded760321 Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Tue, 25 Feb 2014 17:09:06 +0100 Subject: [PATCH 616/889] keybindings: Plug a GSettings instance leak --- src/core/keybindings.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/keybindings.c b/src/core/keybindings.c index 74f40b7dd..23b83b782 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -3916,6 +3916,7 @@ init_builtin_key_bindings (MetaDisplay *display) g_object_unref (common_keybindings); g_object_unref (mutter_keybindings); + g_object_unref (mutter_wayland_keybindings); } void From ef278eb5475ea5673aa9e1b6c507501b41d7ed1f Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Mon, 24 Feb 2014 21:34:33 +0100 Subject: [PATCH 617/889] meta-cursor-tracker: Initialize our position from MetaWaylandPointer's Clutter's input device initial position defaults to (-1, -1) on most backends but for the evdev backend we changed it to be inside the stage to prevent the pointer from wandering outside the stage until it first enters, after which our constraining callback won't let it go out. This makes us be in sync with the real position from the start. --- src/core/meta-cursor-tracker.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/core/meta-cursor-tracker.c b/src/core/meta-cursor-tracker.c index 973aacfb9..347544bc2 100644 --- a/src/core/meta-cursor-tracker.c +++ b/src/core/meta-cursor-tracker.c @@ -570,6 +570,9 @@ make_wayland_cursor_tracker (MetaScreen *screen) compositor = meta_wayland_compositor_get_default (); compositor->seat->cursor_tracker = self; + meta_cursor_tracker_update_position (self, + wl_fixed_to_int (compositor->seat->pointer.x), + wl_fixed_to_int (compositor->seat->pointer.y)); #if defined(CLUTTER_WINDOWING_EGL) if (clutter_check_windowing_backend (CLUTTER_WINDOWING_EGL)) From dfc7f7222b27e29e8ad2f7fcd4bb6a6c901d9bcd Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Wed, 5 Mar 2014 15:05:23 +0100 Subject: [PATCH 618/889] wayland-keyboard: Remove unused modifier indexes This was copied from weston where they're used for compositor keybindings. Mutter has its own keybindings code which doesn't need this. https://bugzilla.gnome.org/show_bug.cgi?id=722847 --- src/wayland/meta-wayland-keyboard.c | 14 -------------- src/wayland/meta-wayland-keyboard.h | 8 -------- 2 files changed, 22 deletions(-) diff --git a/src/wayland/meta-wayland-keyboard.c b/src/wayland/meta-wayland-keyboard.c index 477d56321..19faa8ca4 100644 --- a/src/wayland/meta-wayland-keyboard.c +++ b/src/wayland/meta-wayland-keyboard.c @@ -142,20 +142,6 @@ meta_wayland_keyboard_take_keymap (MetaWaylandKeyboard *keyboard, xkb_keymap_unref (xkb_info->keymap); xkb_info->keymap = keymap; - xkb_info->shift_mod = - xkb_map_mod_get_index (xkb_info->keymap, XKB_MOD_NAME_SHIFT); - xkb_info->caps_mod = - xkb_map_mod_get_index (xkb_info->keymap, XKB_MOD_NAME_CAPS); - xkb_info->ctrl_mod = - xkb_map_mod_get_index (xkb_info->keymap, XKB_MOD_NAME_CTRL); - xkb_info->alt_mod = - xkb_map_mod_get_index (xkb_info->keymap, XKB_MOD_NAME_ALT); - xkb_info->mod2_mod = xkb_map_mod_get_index (xkb_info->keymap, "Mod2"); - xkb_info->mod3_mod = xkb_map_mod_get_index (xkb_info->keymap, "Mod3"); - xkb_info->super_mod = - xkb_map_mod_get_index (xkb_info->keymap, XKB_MOD_NAME_LOGO); - xkb_info->mod5_mod = xkb_map_mod_get_index (xkb_info->keymap, "Mod5"); - keymap_str = xkb_map_get_as_string (xkb_info->keymap); if (keymap_str == NULL) { diff --git a/src/wayland/meta-wayland-keyboard.h b/src/wayland/meta-wayland-keyboard.h index 8d2cb0609..969e4b285 100644 --- a/src/wayland/meta-wayland-keyboard.h +++ b/src/wayland/meta-wayland-keyboard.h @@ -72,14 +72,6 @@ typedef struct int keymap_fd; size_t keymap_size; char *keymap_area; - xkb_mod_index_t shift_mod; - xkb_mod_index_t caps_mod; - xkb_mod_index_t ctrl_mod; - xkb_mod_index_t alt_mod; - xkb_mod_index_t mod2_mod; - xkb_mod_index_t mod3_mod; - xkb_mod_index_t super_mod; - xkb_mod_index_t mod5_mod; } MetaWaylandXkbInfo; typedef struct From c595a9c29f6b340fc512221e9f754823ce628999 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 10 Mar 2014 11:08:01 -0400 Subject: [PATCH 619/889] seat: Reduce indentation --- src/wayland/meta-wayland-seat.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c index d73072925..eae4e077b 100644 --- a/src/wayland/meta-wayland-seat.c +++ b/src/wayland/meta-wayland-seat.c @@ -281,6 +281,9 @@ handle_scroll_event (MetaWaylandSeat *seat, notify_motion (seat, event); + if (!seat->pointer.focus_resource) + return; + switch (clutter_event_get_scroll_direction (event)) { case CLUTTER_SCROLL_UP: @@ -307,11 +310,10 @@ handle_scroll_event (MetaWaylandSeat *seat, return; } - if (seat->pointer.focus_resource) - wl_pointer_send_axis (seat->pointer.focus_resource, - clutter_event_get_time (event), - axis, - value); + wl_pointer_send_axis (seat->pointer.focus_resource, + clutter_event_get_time (event), + axis, + value); } static int From 254e2e993c923ea1d2be4d946233d23b01127718 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 10 Mar 2014 11:09:20 -0400 Subject: [PATCH 620/889] seat: Redo scroll handling To make way for smooth scrolling --- src/wayland/meta-wayland-seat.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c index eae4e077b..47c1d5f6d 100644 --- a/src/wayland/meta-wayland-seat.c +++ b/src/wayland/meta-wayland-seat.c @@ -276,8 +276,7 @@ static void handle_scroll_event (MetaWaylandSeat *seat, const ClutterEvent *event) { - enum wl_pointer_axis axis; - wl_fixed_t value; + wl_fixed_t x_value = 0, y_value = 0; notify_motion (seat, event); @@ -287,33 +286,31 @@ handle_scroll_event (MetaWaylandSeat *seat, switch (clutter_event_get_scroll_direction (event)) { case CLUTTER_SCROLL_UP: - axis = WL_POINTER_AXIS_VERTICAL_SCROLL; - value = -DEFAULT_AXIS_STEP_DISTANCE; + y_value = -DEFAULT_AXIS_STEP_DISTANCE; break; case CLUTTER_SCROLL_DOWN: - axis = WL_POINTER_AXIS_VERTICAL_SCROLL; - value = DEFAULT_AXIS_STEP_DISTANCE; + y_value = DEFAULT_AXIS_STEP_DISTANCE; break; case CLUTTER_SCROLL_LEFT: - axis = WL_POINTER_AXIS_HORIZONTAL_SCROLL; - value = -DEFAULT_AXIS_STEP_DISTANCE; + x_value = -DEFAULT_AXIS_STEP_DISTANCE; break; case CLUTTER_SCROLL_RIGHT: - axis = WL_POINTER_AXIS_HORIZONTAL_SCROLL; - value = DEFAULT_AXIS_STEP_DISTANCE; + x_value = DEFAULT_AXIS_STEP_DISTANCE; break; default: return; } - wl_pointer_send_axis (seat->pointer.focus_resource, - clutter_event_get_time (event), - axis, - value); + if (x_value) + wl_pointer_send_axis (seat->pointer.focus_resource, clutter_event_get_time (event), + WL_POINTER_AXIS_HORIZONTAL_SCROLL, x_value); + if (y_value) + wl_pointer_send_axis (seat->pointer.focus_resource, clutter_event_get_time (event), + WL_POINTER_AXIS_VERTICAL_SCROLL, y_value); } static int From d6b6b363adcd9c9c74c8cb2f74c7d96d404bbc7b Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 10 Mar 2014 11:10:36 -0400 Subject: [PATCH 621/889] seat: Add support for smooth scrolling --- src/wayland/meta-wayland-seat.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c index 47c1d5f6d..2f4658727 100644 --- a/src/wayland/meta-wayland-seat.c +++ b/src/wayland/meta-wayland-seat.c @@ -283,6 +283,9 @@ handle_scroll_event (MetaWaylandSeat *seat, if (!seat->pointer.focus_resource) return; + if (clutter_event_is_pointer_emulated (event)) + return; + switch (clutter_event_get_scroll_direction (event)) { case CLUTTER_SCROLL_UP: @@ -301,6 +304,15 @@ handle_scroll_event (MetaWaylandSeat *seat, x_value = DEFAULT_AXIS_STEP_DISTANCE; break; + case CLUTTER_SCROLL_SMOOTH: + { + double dx, dy; + clutter_event_get_scroll_delta (event, &dx, &dy); + x_value = wl_fixed_from_double (dx); + y_value = wl_fixed_from_double (dy); + } + break; + default: return; } From dd8d8e436d703348db2a4ec64162bf4f510ff8b9 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 10 Mar 2014 14:49:41 -0400 Subject: [PATCH 622/889] wayland: Remove special code for modal grabs Since we never pass any Clutter events to Wayland, it's not needed. --- src/compositor/compositor.c | 51 +---------- src/wayland/meta-wayland-keyboard.c | 131 ++-------------------------- src/wayland/meta-wayland-keyboard.h | 7 -- src/wayland/meta-wayland-pointer.c | 55 ------------ src/wayland/meta-wayland-pointer.h | 5 -- 5 files changed, 9 insertions(+), 240 deletions(-) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 4c6f0e21d..fdbf6d604 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -436,45 +436,6 @@ begin_modal_x11 (MetaScreen *screen, return FALSE; } -static gboolean -begin_modal_wayland (MetaScreen *screen, - MetaPlugin *plugin, - MetaModalOptions options, - guint32 timestamp) -{ - MetaWaylandCompositor *compositor; - gboolean pointer_grabbed = FALSE; - gboolean keyboard_grabbed = FALSE; - - compositor = meta_wayland_compositor_get_default (); - - if ((options & META_MODAL_POINTER_ALREADY_GRABBED) == 0) - { - if (!meta_wayland_pointer_begin_modal (&compositor->seat->pointer)) - goto fail; - - pointer_grabbed = TRUE; - } - if ((options & META_MODAL_KEYBOARD_ALREADY_GRABBED) == 0) - { - if (!meta_wayland_keyboard_begin_modal (&compositor->seat->keyboard, - timestamp)) - goto fail; - - keyboard_grabbed = TRUE; - } - - return TRUE; - - fail: - if (pointer_grabbed) - meta_wayland_pointer_end_modal (&compositor->seat->pointer); - if (keyboard_grabbed) - meta_wayland_keyboard_end_modal (&compositor->seat->keyboard, timestamp); - - return FALSE; -} - gboolean meta_begin_modal_for_plugin (MetaScreen *screen, MetaPlugin *plugin, @@ -493,7 +454,7 @@ meta_begin_modal_for_plugin (MetaScreen *screen, return FALSE; if (meta_is_wayland_compositor ()) - ok = begin_modal_wayland (screen, plugin, options, timestamp); + ok = TRUE; else ok = begin_modal_x11 (screen, plugin, options, timestamp); if (!ok) @@ -521,15 +482,7 @@ meta_end_modal_for_plugin (MetaScreen *screen, g_return_if_fail (compositor->modal_plugin == plugin); - if (meta_is_wayland_compositor ()) - { - MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); - - meta_wayland_pointer_end_modal (&compositor->seat->pointer); - meta_wayland_keyboard_end_modal (&compositor->seat->keyboard, - timestamp); - } - else + if (!meta_is_wayland_compositor ()) { XIUngrabDevice (xdpy, META_VIRTUAL_CORE_POINTER_ID, timestamp); XIUngrabDevice (xdpy, META_VIRTUAL_CORE_KEYBOARD_ID, timestamp); diff --git a/src/wayland/meta-wayland-keyboard.c b/src/wayland/meta-wayland-keyboard.c index 19faa8ca4..c5c3b2a7c 100644 --- a/src/wayland/meta-wayland-keyboard.c +++ b/src/wayland/meta-wayland-keyboard.c @@ -281,31 +281,6 @@ static const MetaWaylandKeyboardGrabInterface default_grab_modifiers, }; -static gboolean -modal_key (MetaWaylandKeyboardGrab *grab, - uint32_t time, - uint32_t key, - uint32_t state) -{ - /* FALSE means: let the event through to clutter */ - return FALSE; -} - -static void -modal_modifiers (MetaWaylandKeyboardGrab *grab, - uint32_t serial, - uint32_t mods_depressed, - uint32_t mods_latched, - uint32_t mods_locked, - uint32_t group) -{ -} - -static MetaWaylandKeyboardGrabInterface modal_grab = { - modal_key, - modal_modifiers, -}; - gboolean meta_wayland_keyboard_init (MetaWaylandKeyboard *keyboard, struct wl_display *display) @@ -521,26 +496,13 @@ meta_wayland_keyboard_set_focus (MetaWaylandKeyboard *keyboard, struct wl_display *display = wl_client_get_display (client); uint32_t serial = wl_display_next_serial (display); - /* If we're in a modal grab, the client is focused but doesn't see - modifiers or pressed keys (and fix that up when we exit the modal) */ - if (keyboard->grab->interface == &modal_grab) - { - struct wl_array empty; - wl_array_init (&empty); - - wl_keyboard_send_modifiers (keyboard->focus_resource, serial, 0, 0, 0, 0); - wl_keyboard_send_enter (keyboard->focus_resource, serial, keyboard->focus_surface->resource, &empty); - } - else - { - wl_keyboard_send_modifiers (keyboard->focus_resource, serial, - keyboard->modifier_state.mods_depressed, - keyboard->modifier_state.mods_latched, - keyboard->modifier_state.mods_locked, - keyboard->modifier_state.group); - wl_keyboard_send_enter (keyboard->focus_resource, serial, keyboard->focus_surface->resource, - &keyboard->keys); - } + wl_keyboard_send_modifiers (keyboard->focus_resource, serial, + keyboard->modifier_state.mods_depressed, + keyboard->modifier_state.mods_latched, + keyboard->modifier_state.mods_locked, + keyboard->modifier_state.group); + wl_keyboard_send_enter (keyboard->focus_resource, serial, keyboard->focus_surface->resource, + &keyboard->keys); wl_resource_add_destroy_listener (keyboard->focus_resource, &keyboard->focus_resource_listener); keyboard->focus_serial = serial; @@ -574,85 +536,6 @@ meta_wayland_keyboard_release (MetaWaylandKeyboard *keyboard) wl_array_release (&keyboard->keys); } -gboolean -meta_wayland_keyboard_begin_modal (MetaWaylandKeyboard *keyboard, - guint32 timestamp) -{ - MetaWaylandKeyboardGrab *grab; - uint32_t *end = (void *) ((char *) keyboard->keys.data + - keyboard->keys.size); - uint32_t *k; - uint32_t serial; - - meta_verbose ("Asked to acquire modal keyboard grab, timestamp %d\n", timestamp); - - if (keyboard->grab != &keyboard->default_grab) - return FALSE; - - if (keyboard->focus_surface) - { - /* Fake key release events for the focused app */ - serial = wl_display_next_serial (keyboard->display); - keyboard->grab->interface->modifiers (keyboard->grab, - serial, - 0, 0, 0, 0); - - for (k = keyboard->keys.data; k < end; k++) - { - keyboard->grab->interface->key (keyboard->grab, - timestamp, - *k, 0); - } - } - - grab = g_slice_new0 (MetaWaylandKeyboardGrab); - grab->interface = &modal_grab; - meta_wayland_keyboard_start_grab (keyboard, grab); - - meta_verbose ("Acquired modal keyboard grab, timestamp %d\n", timestamp); - - return TRUE; -} - -void -meta_wayland_keyboard_end_modal (MetaWaylandKeyboard *keyboard, - guint32 timestamp) -{ - MetaWaylandKeyboardGrab *grab; - uint32_t *end = (void *) ((char *) keyboard->keys.data + - keyboard->keys.size); - uint32_t *k; - uint32_t serial; - - grab = keyboard->grab; - - g_assert (grab->interface == &modal_grab); - - meta_wayland_keyboard_end_grab (keyboard); - g_slice_free (MetaWaylandKeyboardGrab, grab); - - if (keyboard->focus_surface) - { - /* Fake key press events for the focused app */ - serial = wl_display_next_serial (keyboard->display); - keyboard->grab->interface->modifiers (keyboard->grab, - serial, - keyboard->modifier_state.mods_depressed, - keyboard->modifier_state.mods_latched, - keyboard->modifier_state.mods_locked, - keyboard->modifier_state.group); - - for (k = keyboard->keys.data; k < end; k++) - { - keyboard->grab->interface->key (keyboard->grab, - timestamp, - *k, 1); - } - } - - meta_verbose ("Released modal keyboard grab, timestamp %d\n", timestamp); -} - void meta_wayland_keyboard_set_keymap_names (MetaWaylandKeyboard *keyboard, const char *rules, diff --git a/src/wayland/meta-wayland-keyboard.h b/src/wayland/meta-wayland-keyboard.h index 969e4b285..24b36af3d 100644 --- a/src/wayland/meta-wayland-keyboard.h +++ b/src/wayland/meta-wayland-keyboard.h @@ -142,13 +142,6 @@ meta_wayland_keyboard_start_grab (MetaWaylandKeyboard *device, void meta_wayland_keyboard_end_grab (MetaWaylandKeyboard *keyboard); -gboolean -meta_wayland_keyboard_begin_modal (MetaWaylandKeyboard *keyboard, - guint32 timestamp); -void -meta_wayland_keyboard_end_modal (MetaWaylandKeyboard *keyboard, - guint32 timestamp); - void meta_wayland_keyboard_release (MetaWaylandKeyboard *keyboard); diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index 2692c85df..7d15ce4a7 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -398,61 +398,6 @@ meta_wayland_pointer_end_grab (MetaWaylandPointer *pointer) interface->focus (pointer->grab, pointer->current, NULL); } -static void -modal_focus (MetaWaylandPointerGrab *grab, - MetaWaylandSurface *surface, - const ClutterEvent *event) -{ -} - -static void -modal_motion (MetaWaylandPointerGrab *grab, - const ClutterEvent *event) -{ -} - -static void -modal_button (MetaWaylandPointerGrab *grab, - const ClutterEvent *event) -{ -} - -static MetaWaylandPointerGrabInterface modal_grab = { - modal_focus, - modal_motion, - modal_button -}; - -gboolean -meta_wayland_pointer_begin_modal (MetaWaylandPointer *pointer) -{ - MetaWaylandPointerGrab *grab; - - if (pointer->grab != &pointer->default_grab) - return FALSE; - - meta_wayland_pointer_set_focus (pointer, NULL); - - grab = g_slice_new0 (MetaWaylandPointerGrab); - grab->interface = &modal_grab; - meta_wayland_pointer_start_grab (pointer, grab); - - return TRUE; -} - -void -meta_wayland_pointer_end_modal (MetaWaylandPointer *pointer) -{ - MetaWaylandPointerGrab *grab; - - grab = pointer->grab; - - g_assert (grab->interface == &modal_grab); - - meta_wayland_pointer_end_grab (pointer); - g_slice_free (MetaWaylandPointerGrab, grab); -} - typedef struct { MetaWaylandPointerGrab generic; diff --git a/src/wayland/meta-wayland-pointer.h b/src/wayland/meta-wayland-pointer.h index 7fa9bf583..08b6988e8 100644 --- a/src/wayland/meta-wayland-pointer.h +++ b/src/wayland/meta-wayland-pointer.h @@ -85,11 +85,6 @@ meta_wayland_pointer_start_grab (MetaWaylandPointer *pointer, void meta_wayland_pointer_end_grab (MetaWaylandPointer *pointer); -gboolean -meta_wayland_pointer_begin_modal (MetaWaylandPointer *pointer); -void -meta_wayland_pointer_end_modal (MetaWaylandPointer *pointer); - gboolean meta_wayland_pointer_start_popup_grab (MetaWaylandPointer *pointer, MetaWaylandSurface *popup); From 81eb7d9537666d98a769cf89a1d85ea624b3032c Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 10 Mar 2014 15:00:59 -0400 Subject: [PATCH 623/889] Add META_GRAB_OP_WAYLAND_CLIENT Which is used for Wayland popup grabs. The issue here is that we don't want the code that raises or focuses windows based on mouse ops to run while a client has a grab. We still keep the "old" grab infrastructure in place for now, but ideally we'd replace it eventually with a better grab-op infrastructure. --- src/core/display.c | 24 +++++++++++++++++++++--- src/meta/common.h | 5 ++++- src/wayland/meta-wayland-pointer.c | 22 +++++++++++++++++++++- 3 files changed, 46 insertions(+), 5 deletions(-) diff --git a/src/core/display.c b/src/core/display.c index acd26c68c..de675578d 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -1418,6 +1418,20 @@ meta_grab_op_is_moving (MetaGrabOp op) } } +static gboolean +grab_op_should_block_mouse_events (MetaGrabOp op) +{ + switch (op) + { + case META_GRAB_OP_WAYLAND_CLIENT: + case META_GRAB_OP_COMPOSITOR: + return TRUE; + + default: + return FALSE; + } +} + /** * meta_display_xserver_time_is_before: * @display: a #MetaDisplay @@ -2054,7 +2068,7 @@ meta_display_handle_event (MetaDisplay *display, switch (event->type) { case CLUTTER_BUTTON_PRESS: - if (display->grab_op == META_GRAB_OP_COMPOSITOR) + if (grab_op_should_block_mouse_events (display->grab_op)) break; display->overlay_key_only_pressed = FALSE; @@ -2226,7 +2240,7 @@ meta_display_handle_event (MetaDisplay *display, } break; case CLUTTER_BUTTON_RELEASE: - if (display->grab_op == META_GRAB_OP_COMPOSITOR) + if (grab_op_should_block_mouse_events (display->grab_op)) break; display->overlay_key_only_pressed = FALSE; @@ -2240,7 +2254,7 @@ meta_display_handle_event (MetaDisplay *display, } break; case CLUTTER_MOTION: - if (display->grab_op == META_GRAB_OP_COMPOSITOR) + if (grab_op_should_block_mouse_events (display->grab_op)) break; if (display->grab_window == window && @@ -2274,6 +2288,10 @@ meta_display_handle_event (MetaDisplay *display, if (display->grab_op == META_GRAB_OP_COMPOSITOR) bypass_wayland = TRUE; + /* If a Wayland client has a grab, don't pass that through to Clutter */ + if (display->grab_op == META_GRAB_OP_WAYLAND_CLIENT) + bypass_clutter = TRUE; + if (compositor && !bypass_wayland) { if (meta_wayland_compositor_handle_event (compositor, event)) diff --git a/src/meta/common.h b/src/meta/common.h index da9712f80..f81d763d7 100644 --- a/src/meta/common.h +++ b/src/meta/common.h @@ -228,7 +228,10 @@ typedef enum META_GRAB_OP_CLICKING_UNSTICK, /* Special grab op when the compositor asked for a grab */ - META_GRAB_OP_COMPOSITOR + META_GRAB_OP_COMPOSITOR, + + /* For when a client takes a popup grab */ + META_GRAB_OP_WAYLAND_CLIENT, } MetaGrabOp; /** diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index 7d15ce4a7..07bd3620f 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -478,6 +478,12 @@ meta_wayland_pointer_end_popup_grab (MetaWaylandPointer *pointer) g_slice_free (MetaWaylandPopup, popup); } + { + MetaDisplay *display = meta_get_display (); + meta_display_end_grab_op (display, + meta_display_get_current_time_roundtrip (display)); + } + meta_wayland_pointer_end_grab (pointer); g_slice_free (MetaWaylandPopupGrab, popup_grab); } @@ -517,6 +523,8 @@ meta_wayland_pointer_start_popup_grab (MetaWaylandPointer *pointer, if (pointer->grab == &pointer->default_grab) { + MetaWindow *window = surface->window; + grab = g_slice_new0 (MetaWaylandPopupGrab); grab->generic.interface = &popup_grab_interface; grab->generic.pointer = pointer; @@ -524,6 +532,19 @@ meta_wayland_pointer_start_popup_grab (MetaWaylandPointer *pointer, wl_list_init (&grab->all_popups); meta_wayland_pointer_start_grab (pointer, (MetaWaylandPointerGrab*)grab); + + meta_display_begin_grab_op (window->display, + window->screen, + window, + META_GRAB_OP_WAYLAND_CLIENT, + FALSE, /* pointer_already_grabbed */ + FALSE, /* frame_action */ + 1, /* button. XXX? */ + 0, /* modmask */ + meta_display_get_current_time_roundtrip (window->display), + wl_fixed_to_int (pointer->grab_x), + wl_fixed_to_int (pointer->grab_y)); + } else grab = (MetaWaylandPopupGrab*)pointer->grab; @@ -538,7 +559,6 @@ meta_wayland_pointer_start_popup_grab (MetaWaylandPointer *pointer, wl_resource_add_destroy_listener (surface->wl_shell_surface.resource, &popup->surface_destroy_listener); wl_list_insert (&grab->all_popups, &popup->link); - return TRUE; } From 06cd669ccb1ba4ced612cb78220a0228e56f684d Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 10 Mar 2014 16:44:16 -0400 Subject: [PATCH 624/889] wayland: Fix bad copy-paste error in unset_fullscreen This was causing memory corruption and a bad crasher with simple-egl. --- src/wayland/meta-wayland-surface.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 15c94ea9a..1b0b0d4bf 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -874,8 +874,7 @@ static void xdg_surface_unset_fullscreen (struct wl_client *client, struct wl_resource *resource) { - MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface); + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); surface->pending.fullscreen.changed = TRUE; surface->pending.fullscreen.value = FALSE; From 84c6b2a3fa3e37b717dd8b4c4664f02435c6f076 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 10 Mar 2014 17:21:27 -0400 Subject: [PATCH 625/889] wayland: Remove an extra reset We already reset the double-buffered state when we commit it, so this is just superfluous. --- src/wayland/meta-wayland-surface.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 1b0b0d4bf..14010a41e 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -1464,8 +1464,6 @@ subsurface_parent_surface_committed (MetaWaylandSurface *surface) if (surface->sub.synchronous) commit_double_buffered_state (surface, pending_surface_state); - - double_buffered_state_reset (pending_surface_state); } static void From 9df8e831bea7662db1ecff4fdb45354e114ba3c8 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 11 Mar 2014 10:23:35 -0400 Subject: [PATCH 626/889] xwayland: Make sure to clear an existing surface if we have one This fixes an assert fail when redecorating an X11 client. --- src/wayland/meta-xwayland.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index f65ac5638..ae8509e19 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -47,6 +47,13 @@ xserver_set_window_id (struct wl_client *client, if (!window) return; + /* If the window has an existing surface, like if we're + * undecorating or decorating the window, then we need + * to detach the window from its old surface. + */ + if (window->surface) + window->surface->window = NULL; + meta_wayland_surface_make_toplevel (surface); surface->window = window; From 49c0be11d645267bfe32c430db73c0a169555777 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 11 Mar 2014 10:21:02 -0400 Subject: [PATCH 627/889] display: Rework event spewing Make it a compile-time flag rather than a run-time flag, because practically any time you're going to be debugging event spewing, you're going to have to recompile anyway. Remove the WITH_VERBOSE_MODE checks, too. --- src/core/display.c | 50 +++++++++++++--------------------------------- 1 file changed, 14 insertions(+), 36 deletions(-) diff --git a/src/core/display.c b/src/core/display.c index de675578d..576bf3813 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -1295,10 +1295,6 @@ meta_get_display (void) return the_display; } -#ifdef WITH_VERBOSE_MODE -static gboolean dump_events = TRUE; -#endif - static gboolean grab_op_is_mouse_only (MetaGrabOp op) { @@ -2992,9 +2988,8 @@ meta_display_handle_xevent (MetaDisplay *display, MetaMonitorManager *monitor; MetaScreen *screen; -#ifdef WITH_VERBOSE_MODE - if (dump_events) - meta_spew_event (display, event); +#if 0 + meta_spew_event (display, event); #endif #ifdef HAVE_STARTUP_NOTIFICATION @@ -3270,8 +3265,7 @@ event_get_time (MetaDisplay *display, } } -#ifdef WITH_VERBOSE_MODE -const char* +G_GNUC_UNUSED const char* meta_event_detail_to_string (int d) { const char *detail = "???"; @@ -3307,10 +3301,8 @@ meta_event_detail_to_string (int d) return detail; } -#endif /* WITH_VERBOSE_MODE */ -#ifdef WITH_VERBOSE_MODE -const char* +G_GNUC_UNUSED const char* meta_event_mode_to_string (int m) { const char *mode = "???"; @@ -3332,10 +3324,8 @@ meta_event_mode_to_string (int m) return mode; } -#endif /* WITH_VERBOSE_MODE */ -#ifdef WITH_VERBOSE_MODE -static const char* +G_GNUC_UNUSED static const char* stack_mode_to_string (int mode) { switch (mode) @@ -3354,11 +3344,9 @@ stack_mode_to_string (int mode) return "Unknown"; } -#endif /* WITH_VERBOSE_MODE */ #ifdef HAVE_XSYNC -#ifdef WITH_VERBOSE_MODE -static gint64 +G_GNUC_UNUSED static gint64 sync_value_to_64 (const XSyncValue *value) { gint64 v; @@ -3368,10 +3356,8 @@ sync_value_to_64 (const XSyncValue *value) return v; } -#endif /* WITH_VERBOSE_MODE */ -#ifdef WITH_VERBOSE_MODE -static const char* +G_GNUC_UNUSED static const char* alarm_state_to_string (XSyncAlarmState state) { switch (state) @@ -3386,12 +3372,9 @@ alarm_state_to_string (XSyncAlarmState state) return "(unknown)"; } } -#endif /* WITH_VERBOSE_MODE */ - #endif /* HAVE_XSYNC */ -#ifdef WITH_VERBOSE_MODE -static void +G_GNUC_UNUSED static void meta_spew_xi2_event (MetaDisplay *display, XIEvent *input_event, const char **name_p, @@ -3451,7 +3434,7 @@ meta_spew_xi2_event (MetaDisplay *display, *extra_p = extra; } -static void +G_GNUC_UNUSED static void meta_spew_core_event (MetaDisplay *display, XEvent *event, const char **name_p, @@ -3675,7 +3658,7 @@ meta_spew_core_event (MetaDisplay *display, *extra_p = extra; } -static void +G_GNUC_UNUSED static void meta_spew_event (MetaDisplay *display, XEvent *event) { @@ -3684,9 +3667,6 @@ meta_spew_event (MetaDisplay *display, char *winname; MetaScreen *screen; XIEvent *input_event; - - if (!meta_is_verbose()) - return; /* filter overnumerous events */ if (event->type == Expose || event->type == MotionNotify || @@ -3716,18 +3696,16 @@ meta_spew_event (MetaDisplay *display, else winname = g_strdup_printf ("0x%lx", event->xany.window); - meta_topic (META_DEBUG_EVENTS, - "%s on %s%s %s %sserial %lu\n", name, winname, - extra ? ":" : "", extra ? extra : "", - event->xany.send_event ? "SEND " : "", - event->xany.serial); + g_print ("%s on %s%s %s %sserial %lu\n", name, winname, + extra ? ":" : "", extra ? extra : "", + event->xany.send_event ? "SEND " : "", + event->xany.serial); g_free (winname); if (extra) g_free (extra); } -#endif /* WITH_VERBOSE_MODE */ MetaWindow* meta_display_lookup_x_window (MetaDisplay *display, From a8849621c9ca4c7b26c4780981a926447c4017c2 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 11 Mar 2014 12:27:44 -0400 Subject: [PATCH 628/889] window: Always save the user_rect when resizing Wayland windows The user_rect represents the unconstrainted window size, and lots of code in mutter assumes it can resize to the user_rect at any time. If we wait for an attach to ACK and save the user rect, we'll see lots of flickering as code is resizing to the old user_rect at any time. --- src/core/window.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/window.c b/src/core/window.c index a530a0cfa..40d059049 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -5082,6 +5082,7 @@ meta_window_move_resize_wayland (MetaWindow *window, meta_window_move_resize_internal (window, flags, NorthWestGravity, x, y, width, height); + save_user_window_placement (window); } /** From 40c15f6e2a5fcd66f8b0a96737eaf669da64bb84 Mon Sep 17 00:00:00 2001 From: "Owen W. Taylor" Date: Wed, 5 Mar 2014 19:40:09 -0500 Subject: [PATCH 629/889] Fix meta_window_titlebar_is_onscreen() for titlebar-less windows Make the code correspond to the comment - the titlebar can't be offscreen if there's no titlebar. https://bugzilla.gnome.org/show_bug.cgi?id=723580 --- src/core/window.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/window.c b/src/core/window.c index 40d059049..dcc272548 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -7841,7 +7841,7 @@ meta_window_titlebar_is_onscreen (MetaWindow *window) /* Titlebar can't be offscreen if there is no titlebar... */ if (!window->frame) - return FALSE; + return TRUE; /* Get the rectangle corresponding to the titlebar */ meta_window_get_frame_rect (window, &titlebar_rect); From 2cf80bc6474ad2c7f6b1ec212575c810b8b073e4 Mon Sep 17 00:00:00 2001 From: "Owen W. Taylor" Date: Wed, 5 Mar 2014 19:01:11 -0500 Subject: [PATCH 630/889] Fix identification of CSD windows when checking whether to force fullscreen We try to exempt CSD windows from being forced fullscreen if they are undecorated and the size of the screen; however, we also catch almost all windows that *do* need to be forced fullscreen in this check, since they also have decorations turned off. Identify actual CSD windows by checking whether _GTK_FRAME_EXTENTS is set - GTK+ will always set this on CSD windows even if they have no invisible borders or shadows at the current time. We explicitly turn off the legacy-fullscreen check for native wayland windows so we don't start legacy-fullscreening them if the new meta_window_is_client_decorated() is later made more accurate. https://bugzilla.gnome.org/show_bug.cgi?id=723029 --- src/core/constraints.c | 3 ++- src/core/window-private.h | 2 ++ src/core/window.c | 28 ++++++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/core/constraints.c b/src/core/constraints.c index b59aa065f..8bb9b2510 100644 --- a/src/core/constraints.c +++ b/src/core/constraints.c @@ -425,8 +425,9 @@ setup_constraint_info (ConstraintInfo *info, * the monitor. */ if (meta_prefs_get_force_fullscreen() && + window->client_type != META_WINDOW_CLIENT_TYPE_WAYLAND && !window->hide_titlebar_when_maximized && - window->decorated && + (window->decorated || !meta_window_is_client_decorated (window)) && meta_rectangle_equal (new, &monitor_info->rect) && window->has_fullscreen_func && !window->fullscreen) diff --git a/src/core/window-private.h b/src/core/window-private.h index 2d2f8ae2d..30805776d 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -751,4 +751,6 @@ void meta_window_activate_full (MetaWindow *window, MetaClientType source_indication, MetaWorkspace *workspace); +gboolean meta_window_is_client_decorated (MetaWindow *window); + #endif diff --git a/src/core/window.c b/src/core/window.c index dcc272548..01cdc6f79 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -8856,6 +8856,34 @@ meta_window_same_application (MetaWindow *window, group==other_group; } +/** + * meta_window_is_client_decorated: + * + * Check if if the window has decorations drawn by the client. + * (window->decorated refers only to whether we should add decorations) + */ +gboolean +meta_window_is_client_decorated (MetaWindow *window) +{ + if (window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND) + { + /* Assume all Wayland clients draw decorations - not strictly + * true but good enough for current purposes. + */ + return TRUE; + } + else + { + /* Currently the implementation here is hackish - + * has_custom_frame_extents() is set if _GTK_FRAME_EXTENTS is set + * to any value even 0. GTK+ always sets _GTK_FRAME_EXTENTS for + * client-side-decorated window, even if the value is 0 because + * the window is maxized and has no invisible borders or shadows. + */ + return window->has_custom_frame_extents; + } +} + void meta_window_refresh_resize_popup (MetaWindow *window) { From f1dc1a0cbc6defc7f3153d0dcfe68d330e85f1fd Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 11 Mar 2014 15:12:53 -0400 Subject: [PATCH 631/889] wayland: Fix drag grabs We need to have the seat here. This makes weston-dnd not crash when clicking on an item. --- src/wayland/meta-wayland-data-device.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/wayland/meta-wayland-data-device.c b/src/wayland/meta-wayland-data-device.c index 352448ae9..11c329e73 100644 --- a/src/wayland/meta-wayland-data-device.c +++ b/src/wayland/meta-wayland-data-device.c @@ -332,6 +332,7 @@ data_device_start_drag (struct wl_client *client, drag_grab->generic.pointer = &seat->pointer; drag_grab->drag_client = client; + drag_grab->seat = seat; if (source_resource) { From 5298cf0a3a5e42e1995f5a36a83e2d0a352a73f7 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 11 Mar 2014 15:13:15 -0400 Subject: [PATCH 632/889] wayland: Pull in a fix for a FIXME from Weston --- src/wayland/meta-wayland-data-device.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/wayland/meta-wayland-data-device.c b/src/wayland/meta-wayland-data-device.c index 11c329e73..0785c6d51 100644 --- a/src/wayland/meta-wayland-data-device.c +++ b/src/wayland/meta-wayland-data-device.c @@ -318,8 +318,12 @@ data_device_start_drag (struct wl_client *client, { MetaWaylandSeat *seat = wl_resource_get_user_data (resource); MetaWaylandDragGrab *drag_grab; - /* FIXME: Check that client has implicit grab on the origin - * surface that matches the given time. */ + + if ((seat->pointer.button_count == 0 || + seat->pointer.grab_serial != serial || + !seat->pointer.focus_surface || + seat->pointer.focus_surface != wl_resource_get_user_data (origin_resource))) + return; /* FIXME: Check that the data source type array isn't empty. */ From 55c61259d8d583e7c1418f870a27653b92673923 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 11 Mar 2014 15:18:51 -0400 Subject: [PATCH 633/889] wayland: Use g_slice_new0 And fix a leak. --- src/wayland/meta-wayland-data-device.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/src/wayland/meta-wayland-data-device.c b/src/wayland/meta-wayland-data-device.c index 0785c6d51..89823567c 100644 --- a/src/wayland/meta-wayland-data-device.c +++ b/src/wayland/meta-wayland-data-device.c @@ -82,7 +82,8 @@ destroy_data_offer (struct wl_resource *resource) if (offer->source) wl_list_remove (&offer->source_destroy_listener.link); - free (offer); + + g_slice_free (MetaWaylandDataOffer, offer); } static void @@ -99,13 +100,9 @@ static struct wl_resource * meta_wayland_data_source_send_offer (MetaWaylandDataSource *source, struct wl_resource *target) { - MetaWaylandDataOffer *offer; + MetaWaylandDataOffer *offer = g_slice_new0 (MetaWaylandDataOffer); char **p; - offer = malloc (sizeof *offer); - if (offer == NULL) - return NULL; - offer->source = source; offer->source_destroy_listener.notify = destroy_offer_data_source; @@ -460,6 +457,8 @@ destroy_data_source (struct wl_resource *resource) wl_array_for_each (p, &source->mime_types) free (*p); wl_array_release (&source->mime_types); + + g_slice_free (MetaWaylandDataSource, source); } static void @@ -487,14 +486,7 @@ static void create_data_source (struct wl_client *client, struct wl_resource *resource, guint32 id) { - MetaWaylandDataSource *source; - - source = malloc (sizeof *source); - if (source == NULL) - { - wl_resource_post_no_memory (resource); - return; - } + MetaWaylandDataSource *source = g_slice_new0 (MetaWaylandDataSource); source->resource = wl_resource_create (client, &wl_data_source_interface, MIN (META_WL_DATA_SOURCE_VERSION, From f79314d7b5a5a96b63e9a74619f5fafc3f134fdb Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 11 Mar 2014 15:29:05 -0400 Subject: [PATCH 634/889] wayland: Fix destroying data sources The resource is not embedded in the source, it's separate. We need to get the user data here to not crash. --- src/wayland/meta-wayland-data-device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wayland/meta-wayland-data-device.c b/src/wayland/meta-wayland-data-device.c index 89823567c..769021429 100644 --- a/src/wayland/meta-wayland-data-device.c +++ b/src/wayland/meta-wayland-data-device.c @@ -451,7 +451,7 @@ static const struct wl_data_device_interface data_device_interface = { static void destroy_data_source (struct wl_resource *resource) { - MetaWaylandDataSource *source = wl_container_of (resource, source, resource); + MetaWaylandDataSource *source = wl_resource_get_user_data (resource); char **p; wl_array_for_each (p, &source->mime_types) free (*p); From f397c321921fd1d64a326764d21c6f8631ea1175 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 11 Mar 2014 15:36:07 -0400 Subject: [PATCH 635/889] wayland: Make set_selection private It's unused outside of us. --- src/wayland/meta-wayland-data-device.c | 2 +- src/wayland/meta-wayland-data-device.h | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/wayland/meta-wayland-data-device.c b/src/wayland/meta-wayland-data-device.c index 769021429..696f19061 100644 --- a/src/wayland/meta-wayland-data-device.c +++ b/src/wayland/meta-wayland-data-device.c @@ -377,7 +377,7 @@ destroy_selection_data_source (struct wl_listener *listener, void *data) } } -void +static void meta_wayland_seat_set_selection (MetaWaylandSeat *seat, MetaWaylandDataSource *source, guint32 serial) diff --git a/src/wayland/meta-wayland-data-device.h b/src/wayland/meta-wayland-data-device.h index 58635531c..87f977437 100644 --- a/src/wayland/meta-wayland-data-device.h +++ b/src/wayland/meta-wayland-data-device.h @@ -33,10 +33,4 @@ meta_wayland_data_device_set_keyboard_focus (MetaWaylandSeat *seat); int meta_wayland_data_device_manager_init (struct wl_display *display); -void -meta_wayland_seat_set_selection (MetaWaylandSeat *seat, - MetaWaylandDataSource *source, - uint32_t serial); - - #endif /* __META_WAYLAND_DATA_DEVICE_H__ */ From e34792d9f0a949aa9d7f49471029e28f1bb69a21 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 11 Mar 2014 16:00:34 -0400 Subject: [PATCH 636/889] wayland: Remove needless indirection --- src/wayland/meta-wayland-data-device.c | 35 ++++---------------------- src/wayland/meta-wayland-seat.h | 6 ----- 2 files changed, 5 insertions(+), 36 deletions(-) diff --git a/src/wayland/meta-wayland-data-device.c b/src/wayland/meta-wayland-data-device.c index 696f19061..fe7b237ab 100644 --- a/src/wayland/meta-wayland-data-device.c +++ b/src/wayland/meta-wayland-data-device.c @@ -48,7 +48,7 @@ data_offer_accept (struct wl_client *client, * this be a wl_data_device request? */ if (offer->source) - offer->source->accept (offer->source, serial, mime_type); + wl_data_source_send_target (offer->source->resource, mime_type); } static void @@ -58,9 +58,9 @@ data_offer_receive (struct wl_client *client, struct wl_resource *resource, MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource); if (offer->source) - offer->source->send (offer->source, mime_type, fd); - else - close (fd); + wl_data_source_send_send (offer->source->resource, mime_type, fd); + + close (fd); } static void @@ -391,7 +391,7 @@ meta_wayland_seat_set_selection (MetaWaylandSeat *seat, if (seat->selection_data_source) { - seat->selection_data_source->cancel (seat->selection_data_source); + wl_data_source_send_cancelled (seat->selection_data_source->resource); wl_list_remove (&seat->selection_data_source_listener.link); seat->selection_data_source = NULL; } @@ -461,27 +461,6 @@ destroy_data_source (struct wl_resource *resource) g_slice_free (MetaWaylandDataSource, source); } -static void -client_source_accept (MetaWaylandDataSource *source, - guint32 time, const char *mime_type) -{ - wl_data_source_send_target (source->resource, mime_type); -} - -static void -client_source_send (MetaWaylandDataSource *source, - const char *mime_type, int32_t fd) -{ - wl_data_source_send_send (source->resource, mime_type, fd); - close (fd); -} - -static void -client_source_cancel (MetaWaylandDataSource *source) -{ - wl_data_source_send_cancelled (source->resource); -} - static void create_data_source (struct wl_client *client, struct wl_resource *resource, guint32 id) @@ -494,10 +473,6 @@ create_data_source (struct wl_client *client, wl_resource_set_implementation (source->resource, &data_source_interface, source, destroy_data_source); - source->accept = client_source_accept; - source->send = client_source_send; - source->cancel = client_source_cancel; - wl_array_init (&source->mime_types); } diff --git a/src/wayland/meta-wayland-seat.h b/src/wayland/meta-wayland-seat.h index cee2ea662..429319304 100644 --- a/src/wayland/meta-wayland-seat.h +++ b/src/wayland/meta-wayland-seat.h @@ -43,12 +43,6 @@ struct _MetaWaylandDataSource { struct wl_resource *resource; struct wl_array mime_types; - - void (*accept) (MetaWaylandDataSource * source, - uint32_t serial, const char *mime_type); - void (*send) (MetaWaylandDataSource * source, - const char *mime_type, int32_t fd); - void (*cancel) (MetaWaylandDataSource * source); }; struct _MetaWaylandSeat From fb3df5243f2ca85f6c4c0a33dba4ec46ad7c29e1 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 11 Mar 2014 16:32:44 -0400 Subject: [PATCH 637/889] main: Add a --display-server option This is an explicit option to launch mutter as a display server, rather than relying on weston-launch. --- src/core/main.c | 9 +++++++-- src/mutter-wayland.desktop.in | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/core/main.c b/src/core/main.c index af6f84817..5c0e1cc1d 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -190,6 +190,7 @@ static gboolean opt_replace_wm; static gboolean opt_disable_sm; static gboolean opt_sync; static gboolean opt_wayland; +static gboolean opt_display_server; static GOptionEntry meta_options[] = { { @@ -233,6 +234,11 @@ static GOptionEntry meta_options[] = { N_("Run as a wayland compositor"), NULL }, + { + "display-server", 0, 0, G_OPTION_ARG_NONE, + &opt_display_server, + N_("Run as a full display server, rather than nested") + }, {NULL} }; @@ -401,8 +407,7 @@ meta_init (void) if (g_getenv ("MUTTER_DEBUG")) meta_set_debugging (TRUE); - /* We consider running from mutter-launch equivalent to running from bare metal. */ - if (getenv ("WESTON_LAUNCHER_SOCK")) + if (opt_display_server) clutter_set_windowing_backend (CLUTTER_WINDOWING_EGL); meta_set_is_wayland_compositor (opt_wayland); diff --git a/src/mutter-wayland.desktop.in b/src/mutter-wayland.desktop.in index ebf144741..9f213166a 100644 --- a/src/mutter-wayland.desktop.in +++ b/src/mutter-wayland.desktop.in @@ -1,7 +1,7 @@ [Desktop Entry] Type=Application _Name=Mutter (wayland compositor) -Exec=mutter-launch -- mutter --wayland +Exec=mutter-launch -- mutter --wayland --display-server NoDisplay=true # name of loadable control center module X-GNOME-WMSettingsModule=metacity From 757b626aeeb3ccca91ca60d16ef5c24b55127867 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 11 Mar 2014 17:25:02 -0400 Subject: [PATCH 638/889] wayland: Add a few comments, rename some strings --- src/wayland/meta-wayland.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index 3a32dee4b..f1f564e0e 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -643,6 +643,8 @@ meta_wayland_init (void) clutter_wayland_set_compositor_display (compositor->wayland_display); + /* If we're running on bare metal, we're a display server, + * so start talking to weston-launch. */ #if defined(CLUTTER_WINDOWING_EGL) if (clutter_check_windowing_backend (CLUTTER_WINDOWING_EGL)) compositor->launcher = meta_launcher_new (); @@ -728,7 +730,7 @@ meta_wayland_compositor_activate_vt (MetaWaylandCompositor *compositor, } else { - g_debug ("Ignoring VT switch keybinding, not running as VT manager"); + g_debug ("Ignoring VT switch keybinding, not running as display server"); return TRUE; } } From b11c75c1c99d5e3aff139218a2cb53a40e9c2eb0 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 11 Mar 2014 16:48:52 -0400 Subject: [PATCH 639/889] weston-launch: Rearrange code slightly We need to initialize the main loops before our callback is called, so this makes it make a slight bit of more sense. --- src/wayland/meta-weston-launch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wayland/meta-weston-launch.c b/src/wayland/meta-weston-launch.c index f24221d1c..f299477e9 100644 --- a/src/wayland/meta-weston-launch.c +++ b/src/wayland/meta-weston-launch.c @@ -354,8 +354,6 @@ meta_launcher_new (void) self->weston_launch = g_socket_new_from_fd (launch_fd, NULL); - clutter_evdev_set_open_callback (on_evdev_device_open, self); - self->nested_context = g_main_context_new (); self->nested_loop = g_main_loop_new (self->nested_context, FALSE); @@ -369,6 +367,8 @@ meta_launcher_new (void) g_source_attach (self->inner_source, self->nested_context); g_source_unref (self->inner_source); + clutter_evdev_set_open_callback (on_evdev_device_open, self); + return self; } From 1bb9f1e33303f9d98b112cae2d9972ab35618bda Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 11 Mar 2014 16:50:50 -0400 Subject: [PATCH 640/889] weston-launch: Remove unused prototypes --- src/wayland/meta-weston-launch.c | 8 ++++---- src/wayland/meta-weston-launch.h | 8 -------- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/src/wayland/meta-weston-launch.c b/src/wayland/meta-weston-launch.c index f299477e9..c70a71967 100644 --- a/src/wayland/meta-weston-launch.c +++ b/src/wayland/meta-weston-launch.c @@ -179,11 +179,11 @@ meta_launcher_set_drm_fd (MetaLauncher *self, return ok; } -int +static int meta_launcher_open_input_device (MetaLauncher *self, - const char *name, - int flags, - GError **error) + const char *name, + int flags, + GError **error) { struct weston_launcher_open *message; GSocketControlMessage *cmsg; diff --git a/src/wayland/meta-weston-launch.h b/src/wayland/meta-weston-launch.h index 96bc13bf7..d341eaeac 100644 --- a/src/wayland/meta-weston-launch.h +++ b/src/wayland/meta-weston-launch.h @@ -35,12 +35,4 @@ gboolean meta_launcher_activate_vt (MetaLauncher *self, gboolean meta_launcher_set_drm_fd (MetaLauncher *self, int drm_fd, GError **error); -gboolean meta_launcher_set_master (MetaLauncher *self, - gboolean master, - GError **error); -int meta_launcher_open_input_device (MetaLauncher *self, - const char *name, - int flags, - GError **error); - #endif From 81025e37ea5f2aeacbe11b7cec628ef46c75a68b Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 11 Mar 2014 16:58:18 -0400 Subject: [PATCH 641/889] weston-launch: Stat the path before opening it --- src/wayland/weston-launch.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/wayland/weston-launch.c b/src/wayland/weston-launch.c index 773eea4bd..36394c848 100644 --- a/src/wayland/weston-launch.c +++ b/src/wayland/weston-launch.c @@ -331,6 +331,13 @@ handle_open(struct weston_launch *wl, struct msghdr *msg, ssize_t len) goto err0; } + if (major(s.st_rdev) != INPUT_MAJOR) { + fprintf(stderr, "Device %s is not an input device\n", + message->path); + reply.ret = -EPERM; + goto err0; + } + fd = open(message->path, message->flags); if (fd < 0) { fprintf(stderr, "Error opening device %s: %m\n", @@ -339,15 +346,6 @@ handle_open(struct weston_launch *wl, struct msghdr *msg, ssize_t len) goto err0; } - if (major(s.st_rdev) != INPUT_MAJOR) { - close(fd); - fd = -1; - fprintf(stderr, "Device %s is not an input device\n", - message->path); - reply.ret = -EPERM; - goto err0; - } - err0: memset(&nmsg, 0, sizeof nmsg); nmsg.msg_iov = &iov; From 7314cdac947e103a82a707a27ca3f676c0a4a823 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 11 Mar 2014 17:10:39 -0400 Subject: [PATCH 642/889] weston-launch: Always use sd_session_get_vt --- configure.ac | 5 ----- src/wayland/weston-launch.c | 44 ++++++------------------------------- 2 files changed, 7 insertions(+), 42 deletions(-) diff --git a/configure.ac b/configure.ac index 785d076c7..6bc1ab4c2 100644 --- a/configure.ac +++ b/configure.ac @@ -142,11 +142,6 @@ AM_GLIB_GNU_GETTEXT PKG_CHECK_MODULES(ALL, glib-2.0 >= 2.14.0) PKG_CHECK_MODULES(MUTTER_LAUNCH, libdrm libsystemd-login) -saved_LIBS="$LIBS" -LIBS="$LIBS $MUTTER_LAUNCH" -AC_CHECK_FUNCS([sd_session_get_vt]) -LIBS="$saved_LIBS" - # Unconditionally use this dir to avoid a circular dep with gnomecc GNOME_KEYBINDINGS_KEYSDIR="${datadir}/gnome-control-center/keybindings" AC_SUBST(GNOME_KEYBINDINGS_KEYSDIR) diff --git a/src/wayland/weston-launch.c b/src/wayland/weston-launch.c index 36394c848..16baabc50 100644 --- a/src/wayland/weston-launch.c +++ b/src/wayland/weston-launch.c @@ -552,7 +552,8 @@ setup_tty(struct weston_launch *wl) struct stat buf; struct termios raw_attributes; struct vt_mode mode = { 0 }; - char *session, *tty; + char *session; + unsigned vt; char path[PATH_MAX]; int ok; @@ -560,44 +561,13 @@ setup_tty(struct weston_launch *wl) if (ok < 0) error(1, -ok, "could not determine current session"); - ok = sd_session_get_tty(session, &tty); - if (ok == 0) { - /* Old systemd only has the tty name in the TTY - field, new one has the full char device path. - - Check what we have and fix it properly. - */ - if (strncmp(tty, "/dev", strlen("/dev")) == 0) { - strncpy(path, tty, PATH_MAX); - path[PATH_MAX-1] = 0; - } else { - snprintf(path, PATH_MAX, "/dev/%s", tty); - } - - wl->tty = open(path, O_RDWR | O_NOCTTY | O_CLOEXEC); - free(tty); -#ifdef HAVE_SD_SESSION_GET_VT - } else if (ok == -ENOENT) { - unsigned vt; - - /* Negative errnos are cool, right? - So cool that we can't distinguish "session not found" - from "key does not exist in the session file"! - Let's assume the latter, as we got the value - from sd_pid_get_session()... - */ - - ok = sd_session_get_vt(session, &vt); - if (ok < 0) - error(1, -ok, "could not determine current TTY"); - - snprintf(path, PATH_MAX, "/dev/tty%u", vt); - wl->tty = open(path, O_RDWR | O_NOCTTY | O_CLOEXEC); - free(tty); -#endif - } else + ok = sd_session_get_vt(session, &vt); + if (ok < 0) error(1, -ok, "could not determine current TTY"); + snprintf(path, PATH_MAX, "/dev/tty%u", vt); + wl->tty = open(path, O_RDWR | O_NOCTTY | O_CLOEXEC); + if (wl->tty < 0) error(1, errno, "failed to open tty"); From 394af336074045bcbbaac60991814ad8695a5c79 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 11 Mar 2014 17:12:54 -0400 Subject: [PATCH 643/889] weston-launch: Allow activating our own VT by passing a negative value This will be used to implement activate_session. --- src/wayland/weston-launch.c | 15 +++++++++++---- src/wayland/weston-launch.h | 2 +- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/wayland/weston-launch.c b/src/wayland/weston-launch.c index 16baabc50..240cfef16 100644 --- a/src/wayland/weston-launch.c +++ b/src/wayland/weston-launch.c @@ -80,6 +80,7 @@ struct weston_launch { struct termios terminal_attributes; int kb_mode; enum vt_state vt_state; + unsigned vt; int drm_fd; }; @@ -274,6 +275,7 @@ handle_activate_vt(struct weston_launch *wl, struct msghdr *msg, ssize_t len) { struct weston_launcher_reply reply; struct weston_launcher_activate_vt *message; + unsigned vt; reply.header.opcode = WESTON_LAUNCHER_ACTIVATE_VT; reply.ret = -1; @@ -285,7 +287,13 @@ handle_activate_vt(struct weston_launch *wl, struct msghdr *msg, ssize_t len) message = msg->msg_iov->iov_base; - reply.ret = ioctl(wl->tty, VT_ACTIVATE, message->vt); + /* Negative values mean that we're activating our own VT */ + if (message->vt > 0) + vt = message->vt; + else + vt = wl->vt; + + reply.ret = ioctl(wl->tty, VT_ACTIVATE, vt); if (reply.ret < 0) reply.ret = -errno; @@ -553,7 +561,6 @@ setup_tty(struct weston_launch *wl) struct termios raw_attributes; struct vt_mode mode = { 0 }; char *session; - unsigned vt; char path[PATH_MAX]; int ok; @@ -561,11 +568,11 @@ setup_tty(struct weston_launch *wl) if (ok < 0) error(1, -ok, "could not determine current session"); - ok = sd_session_get_vt(session, &vt); + ok = sd_session_get_vt(session, &wl->vt); if (ok < 0) error(1, -ok, "could not determine current TTY"); - snprintf(path, PATH_MAX, "/dev/tty%u", vt); + snprintf(path, PATH_MAX, "/dev/tty%u", wl->vt); wl->tty = open(path, O_RDWR | O_NOCTTY | O_CLOEXEC); if (wl->tty < 0) diff --git a/src/wayland/weston-launch.h b/src/wayland/weston-launch.h index 74e6c3be6..968dd7416 100644 --- a/src/wayland/weston-launch.h +++ b/src/wayland/weston-launch.h @@ -53,7 +53,7 @@ struct weston_launcher_open { struct weston_launcher_activate_vt { struct weston_launcher_message header; - int vt; + signed char vt; }; struct weston_launcher_reply { From f21312e2fd3793ff7566d9a301e6927b6840697f Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 11 Mar 2014 17:22:08 -0400 Subject: [PATCH 644/889] meta-weston-launch: Redraw and update the cursor when switching back --- src/core/meta-cursor-tracker-private.h | 3 +++ src/core/meta-cursor-tracker.c | 9 +++++++++ src/wayland/meta-weston-launch.c | 11 +++++++++++ 3 files changed, 23 insertions(+) diff --git a/src/core/meta-cursor-tracker-private.h b/src/core/meta-cursor-tracker-private.h index b089f0f80..deaa5acd1 100644 --- a/src/core/meta-cursor-tracker-private.h +++ b/src/core/meta-cursor-tracker-private.h @@ -43,4 +43,7 @@ void meta_cursor_tracker_update_position (MetaCursorTracker *tracker, int new_x, int new_y); void meta_cursor_tracker_paint (MetaCursorTracker *tracker); + +void meta_cursor_tracker_force_update (MetaCursorTracker *tracker); + #endif diff --git a/src/core/meta-cursor-tracker.c b/src/core/meta-cursor-tracker.c index 347544bc2..e98f2e72a 100644 --- a/src/core/meta-cursor-tracker.c +++ b/src/core/meta-cursor-tracker.c @@ -1147,3 +1147,12 @@ meta_cursor_tracker_set_pointer_visible (MetaCursorTracker *tracker, tracker->screen->xroot); } } + +void +meta_cursor_tracker_force_update (MetaCursorTracker *tracker) +{ + g_assert (meta_is_wayland_compositor ()); + + update_hw_cursor (tracker); + sync_cursor (tracker); +} diff --git a/src/wayland/meta-weston-launch.c b/src/wayland/meta-weston-launch.c index c70a71967..a33ed4957 100644 --- a/src/wayland/meta-weston-launch.c +++ b/src/wayland/meta-weston-launch.c @@ -232,6 +232,17 @@ meta_launcher_enter (MetaLauncher *launcher) cogl_kms_display_queue_modes_reset (cogl_display); clutter_evdev_reclaim_devices (); + + { + MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); + + /* When we mode-switch back, we need to immediately queue a redraw + * in case nothing else queued one for us, and force the cursor to + * update. */ + + clutter_actor_queue_redraw (compositor->stage); + meta_cursor_tracker_force_update (compositor->seat->cursor_tracker); + } } static void From d47b7ba0384324a588043f246f91da3b1318b887 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 11 Mar 2014 17:04:22 -0400 Subject: [PATCH 645/889] Add meta_activate_session This will be used on startup to switch to the newly activated session. --- src/core/main.c | 26 ++++++++++++++++++++++++++ src/meta/main.h | 1 + src/wayland/meta-wayland.c | 15 +++++++++++++++ src/wayland/meta-wayland.h | 2 ++ src/wayland/meta-weston-launch.c | 2 +- src/wayland/meta-weston-launch.h | 2 +- 6 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/core/main.c b/src/core/main.c index 5c0e1cc1d..84d808751 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -502,6 +502,32 @@ meta_register_with_session (void) g_free (opt_client_id); } +/** + * meta_activate_session: + * + * Tells mutter to activate the session. When mutter is a + * Wayland compositor, this tells logind to switch over to + * the new session. + */ +gboolean +meta_activate_session (void) +{ + if (meta_is_wayland_compositor ()) + { + MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); + GError *error = NULL; + + if (!meta_wayland_compositor_activate_session (compositor, &error)) + { + g_warning ("Could not activate session: %s\n", error->message); + g_error_free (error); + return FALSE; + } + } + + return TRUE; +} + /** * meta_run: (skip) * diff --git a/src/meta/main.h b/src/meta/main.h index 35eb73da7..9a748099e 100644 --- a/src/meta/main.h +++ b/src/meta/main.h @@ -28,6 +28,7 @@ GOptionContext *meta_get_option_context (void); void meta_init (void); int meta_run (void); void meta_register_with_session (void); +gboolean meta_activate_session (void); gboolean meta_get_replace_current_wm (void); /* Actually defined in util.c */ void meta_set_wm_name (const char *wm_name); diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index f1f564e0e..8cbe6cf4a 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -734,3 +734,18 @@ meta_wayland_compositor_activate_vt (MetaWaylandCompositor *compositor, return TRUE; } } + +gboolean +meta_wayland_compositor_activate_session (MetaWaylandCompositor *compositor, + GError **error) +{ + if (compositor->launcher) + { + return meta_launcher_activate_vt (compositor->launcher, -1, error); + } + else + { + g_debug ("Ignoring activate_session, not running as display server"); + return TRUE; + } +} diff --git a/src/wayland/meta-wayland.h b/src/wayland/meta-wayland.h index 481695a75..81bb2e535 100644 --- a/src/wayland/meta-wayland.h +++ b/src/wayland/meta-wayland.h @@ -46,6 +46,8 @@ void meta_wayland_compositor_paint_finished (MetaWaylandComp gboolean meta_wayland_compositor_activate_vt (MetaWaylandCompositor *compositor, int vt, GError **error); +gboolean meta_wayland_compositor_activate_session (MetaWaylandCompositor *compositor, + GError **error); #endif diff --git a/src/wayland/meta-weston-launch.c b/src/wayland/meta-weston-launch.c index a33ed4957..95321104c 100644 --- a/src/wayland/meta-weston-launch.c +++ b/src/wayland/meta-weston-launch.c @@ -399,7 +399,7 @@ meta_launcher_free (MetaLauncher *launcher) gboolean meta_launcher_activate_vt (MetaLauncher *launcher, - int vt, + signed char vt, GError **error) { struct weston_launcher_activate_vt message; diff --git a/src/wayland/meta-weston-launch.h b/src/wayland/meta-weston-launch.h index d341eaeac..7fdd03c23 100644 --- a/src/wayland/meta-weston-launch.h +++ b/src/wayland/meta-weston-launch.h @@ -29,7 +29,7 @@ MetaLauncher *meta_launcher_new (void); void meta_launcher_free (MetaLauncher *self); gboolean meta_launcher_activate_vt (MetaLauncher *self, - int number, + signed char vt, GError **error); gboolean meta_launcher_set_drm_fd (MetaLauncher *self, From a44cc9ef4700ca6475cd4e33178b5a1affa10ade Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 11 Mar 2014 18:01:17 -0400 Subject: [PATCH 646/889] wayland: Fix build --- src/wayland/meta-weston-launch.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/wayland/meta-weston-launch.c b/src/wayland/meta-weston-launch.c index 95321104c..99a444215 100644 --- a/src/wayland/meta-weston-launch.c +++ b/src/wayland/meta-weston-launch.c @@ -41,6 +41,8 @@ #include #include +#include "meta-wayland-private.h" +#include "meta-cursor-tracker-private.h" #include "meta-weston-launch.h" struct _MetaLauncher From 857561baedacba10c68004429cdf41092e52e86e Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 11 Mar 2014 16:51:24 -0400 Subject: [PATCH 647/889] weston-launch: Pass the DRM device to Cogl Open the device from weston-launch, and pass it to Cogl/Clutter. This is a preliminary cleanup for our login1 integration. --- src/wayland/meta-wayland.c | 11 ----- src/wayland/meta-weston-launch.c | 48 +++++++----------- src/wayland/meta-weston-launch.h | 4 -- src/wayland/weston-launch.c | 84 ++++++-------------------------- src/wayland/weston-launch.h | 5 +- 5 files changed, 36 insertions(+), 116 deletions(-) diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index 8cbe6cf4a..a13a920ae 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -653,17 +653,6 @@ meta_wayland_init (void) if (clutter_init (NULL, NULL) != CLUTTER_INIT_SUCCESS) g_error ("Failed to initialize Clutter"); -#if defined(CLUTTER_WINDOWING_EGL) - if (clutter_check_windowing_backend (CLUTTER_WINDOWING_EGL)) - { - ClutterBackend *backend = clutter_get_default_backend (); - CoglContext *cogl_context = clutter_backend_get_cogl_context (backend); - CoglRenderer *cogl_renderer = cogl_display_get_renderer (cogl_context_get_display (cogl_context)); - int drm_fd = cogl_kms_renderer_get_kms_fd (cogl_renderer); - meta_launcher_set_drm_fd (compositor->launcher, drm_fd, NULL); - } -#endif - meta_monitor_manager_initialize (); monitors = meta_monitor_manager_get (); g_signal_connect (monitors, "monitors-changed", diff --git a/src/wayland/meta-weston-launch.c b/src/wayland/meta-weston-launch.c index 99a444215..624d95146 100644 --- a/src/wayland/meta-weston-launch.c +++ b/src/wayland/meta-weston-launch.c @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -156,36 +157,11 @@ send_message_to_wl (MetaLauncher *self, return TRUE; } -gboolean -meta_launcher_set_drm_fd (MetaLauncher *self, - int drm_fd, - GError **error) -{ - struct weston_launcher_message message; - GSocketControlMessage *cmsg; - gboolean ok; - - message.opcode = WESTON_LAUNCHER_DRM_SET_FD; - - cmsg = g_unix_fd_message_new (); - if (g_unix_fd_message_append_fd (G_UNIX_FD_MESSAGE (cmsg), - drm_fd, error) == FALSE) - { - g_object_unref (cmsg); - return FALSE; - } - - ok = send_message_to_wl (self, &message, sizeof message, cmsg, NULL, error); - - g_object_unref (cmsg); - return ok; -} - static int -meta_launcher_open_input_device (MetaLauncher *self, - const char *name, - int flags, - GError **error) +meta_launcher_open_device (MetaLauncher *self, + const char *name, + int flags, + GError **error) { struct weston_launcher_open *message; GSocketControlMessage *cmsg; @@ -261,7 +237,7 @@ on_evdev_device_open (const char *path, { MetaLauncher *launcher = user_data; - return meta_launcher_open_input_device (launcher, path, flags, error); + return meta_launcher_open_device (launcher, path, flags, error); } static void @@ -382,6 +358,18 @@ meta_launcher_new (void) clutter_evdev_set_open_callback (on_evdev_device_open, self); +#if defined(CLUTTER_WINDOWING_EGL) + if (clutter_check_windowing_backend (CLUTTER_WINDOWING_EGL)) + { + GError *error = NULL; + int fd = meta_launcher_open_device (self, "/dev/dri/card0", O_RDWR, &error); + if (error) + g_error ("Failed to open /dev/dri/card0: %s", error->message); + + clutter_egl_native_set_kms_fd (fd); + } +#endif + return self; } diff --git a/src/wayland/meta-weston-launch.h b/src/wayland/meta-weston-launch.h index 7fdd03c23..b70faf88e 100644 --- a/src/wayland/meta-weston-launch.h +++ b/src/wayland/meta-weston-launch.h @@ -31,8 +31,4 @@ void meta_launcher_free (MetaLauncher *self); gboolean meta_launcher_activate_vt (MetaLauncher *self, signed char vt, GError **error); - -gboolean meta_launcher_set_drm_fd (MetaLauncher *self, - int drm_fd, - GError **error); #endif diff --git a/src/wayland/weston-launch.c b/src/wayland/weston-launch.c index 240cfef16..ae713ed23 100644 --- a/src/wayland/weston-launch.c +++ b/src/wayland/weston-launch.c @@ -165,69 +165,6 @@ setenv_fd(const char *env, int fd) setenv(env, buf, 1); } -static int -handle_setdrmfd(struct weston_launch *wl, struct msghdr *msg, ssize_t len) -{ - struct weston_launcher_reply reply; - struct cmsghdr *cmsg; - union cmsg_data *data; - struct stat s; - - reply.header.opcode = WESTON_LAUNCHER_DRM_SET_FD; - reply.ret = -1; - - if (wl->drm_fd != -1) { - error(0, 0, "DRM FD already set"); - reply.ret = -EINVAL; - goto out; - } - - cmsg = CMSG_FIRSTHDR(msg); - if (!cmsg || - cmsg->cmsg_level != SOL_SOCKET || - cmsg->cmsg_type != SCM_RIGHTS) { - error(0, 0, "invalid control message"); - reply.ret = -EINVAL; - goto out; - } - - data = (union cmsg_data *) CMSG_DATA(cmsg); - if (data->fd < 0) { - error(0, 0, "missing drm fd in socket request"); - reply.ret = -EINVAL; - goto out; - } - - if (fstat(data->fd, &s) < 0) { - reply.ret = -errno; - goto out; - } - - if (major(s.st_rdev) != DRM_MAJOR) { - fprintf(stderr, "FD is not for DRM\n"); - reply.ret = -EPERM; - goto out; - } - - wl->drm_fd = data->fd; - reply.ret = drmSetMaster(data->fd); - if (reply.ret < 0) - reply.ret = -errno; - - if (wl->verbose) - fprintf(stderr, "mutter-launch: set drm FD, ret: %d, fd: %d\n", - reply.ret, data->fd); - -out: - do { - len = send(wl->sock[0], &reply, sizeof reply, 0); - } while (len < 0 && errno == EINTR); - if (len < 0) - return -1; - - return 0; -} - static int handle_confirm_vt_switch(struct weston_launch *wl, struct msghdr *msg, ssize_t len) { @@ -323,6 +260,7 @@ handle_open(struct weston_launch *wl, struct msghdr *msg, ssize_t len) struct iovec iov; struct weston_launcher_open *message; union cmsg_data *data; + int dev_major; reply.header.opcode = WESTON_LAUNCHER_OPEN; reply.ret = -1; @@ -339,13 +277,22 @@ handle_open(struct weston_launch *wl, struct msghdr *msg, ssize_t len) goto err0; } - if (major(s.st_rdev) != INPUT_MAJOR) { - fprintf(stderr, "Device %s is not an input device\n", + dev_major = major(s.st_rdev); + + if (dev_major != INPUT_MAJOR || + dev_major != DRM_MAJOR) { + fprintf(stderr, "Device %s is not an input or DRM device\n", message->path); reply.ret = -EPERM; goto err0; } + if (dev_major == DRM_MAJOR && wl->drm_fd != -1) { + fprintf(stderr, "Already have a DRM device open\n"); + reply.ret = -EPERM; + goto err0; + } + fd = open(message->path, message->flags); if (fd < 0) { fprintf(stderr, "Error opening device %s: %m\n", @@ -354,6 +301,10 @@ handle_open(struct weston_launch *wl, struct msghdr *msg, ssize_t len) goto err0; } + if (dev_major == DRM_MAJOR) { + wl->drm_fd = fd; + } + err0: memset(&nmsg, 0, sizeof nmsg); nmsg.msg_iov = &iov; @@ -419,9 +370,6 @@ handle_socket_msg(struct weston_launch *wl) case WESTON_LAUNCHER_OPEN: ret = handle_open(wl, &msg, len); break; - case WESTON_LAUNCHER_DRM_SET_FD: - ret = handle_setdrmfd(wl, &msg, len); - break; case WESTON_LAUNCHER_CONFIRM_VT_SWITCH: ret = handle_confirm_vt_switch(wl, &msg, len); break; diff --git a/src/wayland/weston-launch.h b/src/wayland/weston-launch.h index 968dd7416..1e716c5ac 100644 --- a/src/wayland/weston-launch.h +++ b/src/wayland/weston-launch.h @@ -31,9 +31,8 @@ enum weston_launcher_message_type { enum weston_launcher_opcode { WESTON_LAUNCHER_OPEN = (1 << 1 | WESTON_LAUNCHER_REQUEST), - WESTON_LAUNCHER_DRM_SET_FD = (2 << 1 | WESTON_LAUNCHER_REQUEST), - WESTON_LAUNCHER_ACTIVATE_VT = (3 << 1 | WESTON_LAUNCHER_REQUEST), - WESTON_LAUNCHER_CONFIRM_VT_SWITCH = (4 << 1 | WESTON_LAUNCHER_REQUEST), + WESTON_LAUNCHER_ACTIVATE_VT = (2 << 1 | WESTON_LAUNCHER_REQUEST), + WESTON_LAUNCHER_CONFIRM_VT_SWITCH = (3 << 1 | WESTON_LAUNCHER_REQUEST), }; enum weston_launcher_server_opcode { From c1f15348a5cd9768faa32373365cf2591280859d Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Wed, 12 Mar 2014 14:48:12 -0400 Subject: [PATCH 648/889] Revert "weston-launch: Pass the DRM device to Cogl" This reverts commit 857561baedacba10c68004429cdf41092e52e86e. This broke the build, and was pushed prematurely. --- src/wayland/meta-wayland.c | 11 +++++ src/wayland/meta-weston-launch.c | 48 +++++++++++------- src/wayland/meta-weston-launch.h | 4 ++ src/wayland/weston-launch.c | 84 ++++++++++++++++++++++++++------ src/wayland/weston-launch.h | 5 +- 5 files changed, 116 insertions(+), 36 deletions(-) diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index a13a920ae..8cbe6cf4a 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -653,6 +653,17 @@ meta_wayland_init (void) if (clutter_init (NULL, NULL) != CLUTTER_INIT_SUCCESS) g_error ("Failed to initialize Clutter"); +#if defined(CLUTTER_WINDOWING_EGL) + if (clutter_check_windowing_backend (CLUTTER_WINDOWING_EGL)) + { + ClutterBackend *backend = clutter_get_default_backend (); + CoglContext *cogl_context = clutter_backend_get_cogl_context (backend); + CoglRenderer *cogl_renderer = cogl_display_get_renderer (cogl_context_get_display (cogl_context)); + int drm_fd = cogl_kms_renderer_get_kms_fd (cogl_renderer); + meta_launcher_set_drm_fd (compositor->launcher, drm_fd, NULL); + } +#endif + meta_monitor_manager_initialize (); monitors = meta_monitor_manager_get (); g_signal_connect (monitors, "monitors-changed", diff --git a/src/wayland/meta-weston-launch.c b/src/wayland/meta-weston-launch.c index 624d95146..99a444215 100644 --- a/src/wayland/meta-weston-launch.c +++ b/src/wayland/meta-weston-launch.c @@ -23,7 +23,6 @@ #include #include -#include #include #include @@ -157,11 +156,36 @@ send_message_to_wl (MetaLauncher *self, return TRUE; } +gboolean +meta_launcher_set_drm_fd (MetaLauncher *self, + int drm_fd, + GError **error) +{ + struct weston_launcher_message message; + GSocketControlMessage *cmsg; + gboolean ok; + + message.opcode = WESTON_LAUNCHER_DRM_SET_FD; + + cmsg = g_unix_fd_message_new (); + if (g_unix_fd_message_append_fd (G_UNIX_FD_MESSAGE (cmsg), + drm_fd, error) == FALSE) + { + g_object_unref (cmsg); + return FALSE; + } + + ok = send_message_to_wl (self, &message, sizeof message, cmsg, NULL, error); + + g_object_unref (cmsg); + return ok; +} + static int -meta_launcher_open_device (MetaLauncher *self, - const char *name, - int flags, - GError **error) +meta_launcher_open_input_device (MetaLauncher *self, + const char *name, + int flags, + GError **error) { struct weston_launcher_open *message; GSocketControlMessage *cmsg; @@ -237,7 +261,7 @@ on_evdev_device_open (const char *path, { MetaLauncher *launcher = user_data; - return meta_launcher_open_device (launcher, path, flags, error); + return meta_launcher_open_input_device (launcher, path, flags, error); } static void @@ -358,18 +382,6 @@ meta_launcher_new (void) clutter_evdev_set_open_callback (on_evdev_device_open, self); -#if defined(CLUTTER_WINDOWING_EGL) - if (clutter_check_windowing_backend (CLUTTER_WINDOWING_EGL)) - { - GError *error = NULL; - int fd = meta_launcher_open_device (self, "/dev/dri/card0", O_RDWR, &error); - if (error) - g_error ("Failed to open /dev/dri/card0: %s", error->message); - - clutter_egl_native_set_kms_fd (fd); - } -#endif - return self; } diff --git a/src/wayland/meta-weston-launch.h b/src/wayland/meta-weston-launch.h index b70faf88e..7fdd03c23 100644 --- a/src/wayland/meta-weston-launch.h +++ b/src/wayland/meta-weston-launch.h @@ -31,4 +31,8 @@ void meta_launcher_free (MetaLauncher *self); gboolean meta_launcher_activate_vt (MetaLauncher *self, signed char vt, GError **error); + +gboolean meta_launcher_set_drm_fd (MetaLauncher *self, + int drm_fd, + GError **error); #endif diff --git a/src/wayland/weston-launch.c b/src/wayland/weston-launch.c index ae713ed23..240cfef16 100644 --- a/src/wayland/weston-launch.c +++ b/src/wayland/weston-launch.c @@ -165,6 +165,69 @@ setenv_fd(const char *env, int fd) setenv(env, buf, 1); } +static int +handle_setdrmfd(struct weston_launch *wl, struct msghdr *msg, ssize_t len) +{ + struct weston_launcher_reply reply; + struct cmsghdr *cmsg; + union cmsg_data *data; + struct stat s; + + reply.header.opcode = WESTON_LAUNCHER_DRM_SET_FD; + reply.ret = -1; + + if (wl->drm_fd != -1) { + error(0, 0, "DRM FD already set"); + reply.ret = -EINVAL; + goto out; + } + + cmsg = CMSG_FIRSTHDR(msg); + if (!cmsg || + cmsg->cmsg_level != SOL_SOCKET || + cmsg->cmsg_type != SCM_RIGHTS) { + error(0, 0, "invalid control message"); + reply.ret = -EINVAL; + goto out; + } + + data = (union cmsg_data *) CMSG_DATA(cmsg); + if (data->fd < 0) { + error(0, 0, "missing drm fd in socket request"); + reply.ret = -EINVAL; + goto out; + } + + if (fstat(data->fd, &s) < 0) { + reply.ret = -errno; + goto out; + } + + if (major(s.st_rdev) != DRM_MAJOR) { + fprintf(stderr, "FD is not for DRM\n"); + reply.ret = -EPERM; + goto out; + } + + wl->drm_fd = data->fd; + reply.ret = drmSetMaster(data->fd); + if (reply.ret < 0) + reply.ret = -errno; + + if (wl->verbose) + fprintf(stderr, "mutter-launch: set drm FD, ret: %d, fd: %d\n", + reply.ret, data->fd); + +out: + do { + len = send(wl->sock[0], &reply, sizeof reply, 0); + } while (len < 0 && errno == EINTR); + if (len < 0) + return -1; + + return 0; +} + static int handle_confirm_vt_switch(struct weston_launch *wl, struct msghdr *msg, ssize_t len) { @@ -260,7 +323,6 @@ handle_open(struct weston_launch *wl, struct msghdr *msg, ssize_t len) struct iovec iov; struct weston_launcher_open *message; union cmsg_data *data; - int dev_major; reply.header.opcode = WESTON_LAUNCHER_OPEN; reply.ret = -1; @@ -277,22 +339,13 @@ handle_open(struct weston_launch *wl, struct msghdr *msg, ssize_t len) goto err0; } - dev_major = major(s.st_rdev); - - if (dev_major != INPUT_MAJOR || - dev_major != DRM_MAJOR) { - fprintf(stderr, "Device %s is not an input or DRM device\n", + if (major(s.st_rdev) != INPUT_MAJOR) { + fprintf(stderr, "Device %s is not an input device\n", message->path); reply.ret = -EPERM; goto err0; } - if (dev_major == DRM_MAJOR && wl->drm_fd != -1) { - fprintf(stderr, "Already have a DRM device open\n"); - reply.ret = -EPERM; - goto err0; - } - fd = open(message->path, message->flags); if (fd < 0) { fprintf(stderr, "Error opening device %s: %m\n", @@ -301,10 +354,6 @@ handle_open(struct weston_launch *wl, struct msghdr *msg, ssize_t len) goto err0; } - if (dev_major == DRM_MAJOR) { - wl->drm_fd = fd; - } - err0: memset(&nmsg, 0, sizeof nmsg); nmsg.msg_iov = &iov; @@ -370,6 +419,9 @@ handle_socket_msg(struct weston_launch *wl) case WESTON_LAUNCHER_OPEN: ret = handle_open(wl, &msg, len); break; + case WESTON_LAUNCHER_DRM_SET_FD: + ret = handle_setdrmfd(wl, &msg, len); + break; case WESTON_LAUNCHER_CONFIRM_VT_SWITCH: ret = handle_confirm_vt_switch(wl, &msg, len); break; diff --git a/src/wayland/weston-launch.h b/src/wayland/weston-launch.h index 1e716c5ac..968dd7416 100644 --- a/src/wayland/weston-launch.h +++ b/src/wayland/weston-launch.h @@ -31,8 +31,9 @@ enum weston_launcher_message_type { enum weston_launcher_opcode { WESTON_LAUNCHER_OPEN = (1 << 1 | WESTON_LAUNCHER_REQUEST), - WESTON_LAUNCHER_ACTIVATE_VT = (2 << 1 | WESTON_LAUNCHER_REQUEST), - WESTON_LAUNCHER_CONFIRM_VT_SWITCH = (3 << 1 | WESTON_LAUNCHER_REQUEST), + WESTON_LAUNCHER_DRM_SET_FD = (2 << 1 | WESTON_LAUNCHER_REQUEST), + WESTON_LAUNCHER_ACTIVATE_VT = (3 << 1 | WESTON_LAUNCHER_REQUEST), + WESTON_LAUNCHER_CONFIRM_VT_SWITCH = (4 << 1 | WESTON_LAUNCHER_REQUEST), }; enum weston_launcher_server_opcode { From b37ad66e9dc674ff728966b30058aec3ea71c919 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sun, 9 Feb 2014 11:45:09 -0500 Subject: [PATCH 649/889] xdg-shell: Update for new state change mechanism We're still not properly going through the request system. This will require a dense investigation of the code, but it will happen soon... --- protocol/xdg-shell.xml | 179 +++++++++++++---------------- src/core/window.c | 20 +++- src/wayland/meta-wayland-surface.c | 134 ++++++++++++--------- src/wayland/meta-wayland-surface.h | 15 +-- 4 files changed, 182 insertions(+), 166 deletions(-) diff --git a/protocol/xdg-shell.xml b/protocol/xdg-shell.xml index 4a1d08aba..a2913c4c0 100644 --- a/protocol/xdg-shell.xml +++ b/protocol/xdg-shell.xml @@ -40,19 +40,22 @@ - Use this enum to check the protocol version, and it will be updated - automatically. + The 'current' member of this enum gives the version of the + protocol. Implementations can compare this to the version + they implement using static_assert to ensure the protocol and + implementation versions match. - + - Use this request in order to enable use of this interface. - - Understand and agree that one is using an unstable interface, - that will likely change in the future, breaking the API. + Negotiate the unstable version of the interface. This + mechanism is in place to ensure client and server agree on the + unstable versions of the protocol that they speak or exit + cleanly if they don't agree. This request will go away once + the xdg-shell protocol is stable. @@ -275,113 +278,87 @@ - - - Event sent from the compositor to the client requesting that the client - goes to a fullscreen state. It's the client job to call set_fullscreen - and really trigger the fullscreen state. + + + The different state values used on the surface. This is designed for + state values like maximized, fullscreen. It is paired with the + request_change_state event to ensure that both the client and the + compositor setting the state can be synchronized. + + States set in this way are double-buffered. They will get applied on + the next commit. + + Desktop environments may extend this enum by taking up a range of + values and documenting the range they chose in this description. + They are not required to document the values for the range that they + chose. Ideally, any good extensions from a desktop environment should + make its way into standardization into this enum. + + The current reserved ranges are: + + 0x0000 - 0x0FFF: xdg-shell core values, documented below. + 0x1000 - 0x1FFF: GNOME - + + A non-zero value indicates the surface is maximized. Otherwise, + the surface is unmaximized. + + + A non-zero value indicates the surface is fullscreen. Otherwise, + the surface is not fullscreen. + + - - - Event sent from the compositor to the client requesting that the client - leaves the fullscreen state. It's the client job to call - unset_fullscreen and really leave the fullscreen state. - - - - - - Set the surface as fullscreen. - - After this request, the compositor should send a configure event - informing the output size. - - This request informs the compositor that the next attached buffer - committed will be in a fullscreen state. The buffer size should be the - same size as the size informed in the configure event, if the client - doesn't want to leave any empty area. - - In other words: the next attached buffer after set_maximized is the new - maximized buffer. And the surface will be positioned at the maximized - position on commit. - - A simple way to synchronize and wait for the correct configure event is - to use a wl_display.sync request right after the set_fullscreen - request. When the sync callback returns, the last configure event - received just before it will be the correct one, and should contain the - right size for the surface to maximize. - - Setting one state won't unset another state. Use - xdg_surface.unset_fullscreen for unsetting it. + + + This asks the compositor to change the state. If the compositor wants + to change the state, it will send a change_state event with the same + state_type, value, and serial, and the event flow continues as if it + it was initiated by the compositor. + + If the compositor does not want to change the state, it will send a + change_state to the client with the old value of the state. + + + + This serial is so the client can know which change_state event corresponds + to which request_change_state request it sent out. + - - - Unset the surface fullscreen state. - - Same negotiation as set_fullscreen must be used. + + + This event tells the client to change a surface's state. The client + should respond with an ack_change_state request to the compositor to + guarantee that the compositor knows that the client has seen it. - - - - Event sent from the compositor to the client requesting that the client - goes to a maximized state. It's the client job to call set_maximized - and really trigger the maximized state. - + + + - - - Event sent from the compositor to the client requesting that the client - leaves the maximized state. It's the client job to call unset_maximized - and really leave the maximized state. - - - - - - Set the surface as maximized. - - After this request, the compositor will send a configure event - informing the output size minus panel and other MW decorations. - - This request informs the compositor that the next attached buffer - committed will be in a maximized state. The buffer size should be the - same size as the size informed in the configure event, if the client - doesn't want to leave any empty area. - - In other words: the next attached buffer after set_maximized is the new - maximized buffer. And the surface will be positioned at the maximized - position on commit. - - A simple way to synchronize and wait for the correct configure event is - to use a wl_display.sync request right after the set_maximized request. - When the sync callback returns, the last configure event received just - before it will be the correct one, and should contain the right size - for the surface to maximize. - - Setting one state won't unset another state. Use - xdg_surface.unset_maximized for unsetting it. - - - - - - Unset the surface maximized state. - - Same negotiation as set_maximized must be used. + + + When a change_state event is received, a client should then ack it + using the ack_change_state request to ensure that the compositor + knows the client has seen the event. + + By this point, the state is confirmed, and the next attach should + contain the buffer drawn for the new state value. + + The values here need to be the same as the values in the cooresponding + change_state event. + + + - - Set the surface minimized state. - - Setting one state won't unset another state. + + Minimize the surface. diff --git a/src/core/window.c b/src/core/window.c index 01cdc6f79..bbce5a81d 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -3120,6 +3120,9 @@ meta_window_maximize_internal (MetaWindow *window, meta_window_recalc_features (window); set_net_wm_state (window); + if (window->surface && window->maximized_horizontally && window->maximized_vertically) + meta_wayland_surface_send_maximized (window->surface); + g_object_freeze_notify (G_OBJECT (window)); g_object_notify (G_OBJECT (window), "maximized-horizontally"); g_object_notify (G_OBJECT (window), "maximized-vertically"); @@ -3605,10 +3608,13 @@ meta_window_unmaximize_internal (MetaWindow *window, set_net_wm_state (window); } - g_object_freeze_notify (G_OBJECT (window)); - g_object_notify (G_OBJECT (window), "maximized-horizontally"); - g_object_notify (G_OBJECT (window), "maximized-vertically"); - g_object_thaw_notify (G_OBJECT (window)); + if (window->surface && !window->maximized_horizontally && !window->maximized_vertically) + meta_wayland_surface_send_unmaximized (window->surface); + + g_object_freeze_notify (G_OBJECT (window)); + g_object_notify (G_OBJECT (window), "maximized-horizontally"); + g_object_notify (G_OBJECT (window), "maximized-vertically"); + g_object_thaw_notify (G_OBJECT (window)); } void @@ -3711,6 +3717,9 @@ meta_window_make_fullscreen_internal (MetaWindow *window) /* For the auto-minimize feature, if we fail to get focus */ meta_screen_queue_check_fullscreen (window->screen); + if (window->surface) + meta_wayland_surface_send_fullscreened (window->surface); + g_object_notify (G_OBJECT (window), "fullscreen"); } } @@ -3767,6 +3776,9 @@ meta_window_unmake_fullscreen (MetaWindow *window) meta_window_update_layer (window); + if (window->surface) + meta_wayland_surface_send_unfullscreened (window->surface); + g_object_notify (G_OBJECT (window), "fullscreen"); } } diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 14010a41e..71017cab5 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -336,22 +336,6 @@ toplevel_surface_commit (MetaWaylandSurface *surface, if (pending->frame_extents_changed) meta_window_set_custom_frame_extents (surface->window, &pending->frame_extents); - - if (pending->maximized.changed) - { - if (pending->maximized.value) - meta_window_maximize (surface->window, META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL); - else - meta_window_unmaximize (surface->window, META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL); - } - - if (pending->fullscreen.changed) - { - if (pending->fullscreen.value) - meta_window_make_fullscreen (surface->window); - else - meta_window_unmake_fullscreen (surface->window); - } } static void @@ -377,8 +361,6 @@ double_buffered_state_init (MetaWaylandDoubleBufferedState *state) wl_list_init (&state->frame_callback_list); state->frame_extents_changed = FALSE; - state->maximized.changed = FALSE; - state->fullscreen.changed = FALSE; } static void @@ -861,43 +843,44 @@ xdg_surface_set_output (struct wl_client *client, } static void -xdg_surface_set_fullscreen (struct wl_client *client, - struct wl_resource *resource) +xdg_surface_request_change_state (struct wl_client *client, + struct wl_resource *resource, + uint32_t state_type, + uint32_t value, + uint32_t serial) { MetaWaylandSurface *surface = wl_resource_get_user_data (resource); - surface->pending.fullscreen.changed = TRUE; - surface->pending.fullscreen.value = TRUE; + surface->state_changed_serial = serial; + + switch (state_type) + { + case XDG_SURFACE_STATE_MAXIMIZED: + if (value) + meta_window_maximize (surface->window, META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL); + else + meta_window_unmaximize (surface->window, META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL); + break; + case XDG_SURFACE_STATE_FULLSCREEN: + if (value) + meta_window_make_fullscreen (surface->window); + else + meta_window_unmake_fullscreen (surface->window); + } } static void -xdg_surface_unset_fullscreen (struct wl_client *client, - struct wl_resource *resource) +xdg_surface_ack_change_state (struct wl_client *client, + struct wl_resource *resource, + uint32_t state_type, + uint32_t value, + uint32_t serial) { - MetaWaylandSurface *surface = wl_resource_get_user_data (resource); - - surface->pending.fullscreen.changed = TRUE; - surface->pending.fullscreen.value = FALSE; -} - -static void -xdg_surface_set_maximized (struct wl_client *client, - struct wl_resource *resource) -{ - MetaWaylandSurface *surface = wl_resource_get_user_data (resource); - - surface->pending.maximized.changed = TRUE; - surface->pending.maximized.value = TRUE; -} - -static void -xdg_surface_unset_maximized (struct wl_client *client, - struct wl_resource *resource) -{ - MetaWaylandSurface *surface = wl_resource_get_user_data (resource); - - surface->pending.maximized.changed = TRUE; - surface->pending.maximized.value = FALSE; + /* Do nothing for now. In the future, we'd imagine that + * we'd ignore attaches when we have a state pending that + * we haven't had the client ACK'd, to prevent a race + * condition when we have an in-flight attach when the + * client gets the new state. */ } static void @@ -918,10 +901,8 @@ static const struct xdg_surface_interface meta_wayland_xdg_surface_interface = { xdg_surface_move, xdg_surface_resize, xdg_surface_set_output, - xdg_surface_set_fullscreen, - xdg_surface_unset_fullscreen, - xdg_surface_set_maximized, - xdg_surface_unset_maximized, + xdg_surface_request_change_state, + xdg_surface_ack_change_state, xdg_surface_set_minimized, }; @@ -1735,6 +1716,55 @@ meta_wayland_surface_configure_notify (MetaWaylandSurface *surface, 0, new_width, new_height); } +static void +send_change_state (MetaWaylandSurface *surface, + uint32_t state_type, + uint32_t value) +{ + if (surface->xdg_surface.resource) + { + uint32_t serial; + + if (surface->state_changed_serial != 0) + { + serial = surface->state_changed_serial; + surface->state_changed_serial = 0; + } + else + { + struct wl_client *client = wl_resource_get_client (surface->xdg_surface.resource); + struct wl_display *display = wl_client_get_display (client); + serial = wl_display_next_serial (display); + } + + xdg_surface_send_change_state (surface->xdg_surface.resource, state_type, value, serial); + } +} + +void +meta_wayland_surface_send_maximized (MetaWaylandSurface *surface) +{ + send_change_state (surface, XDG_SURFACE_STATE_MAXIMIZED, TRUE); +} + +void +meta_wayland_surface_send_unmaximized (MetaWaylandSurface *surface) +{ + send_change_state (surface, XDG_SURFACE_STATE_MAXIMIZED, FALSE); +} + +void +meta_wayland_surface_send_fullscreened (MetaWaylandSurface *surface) +{ + send_change_state (surface, XDG_SURFACE_STATE_FULLSCREEN, TRUE); +} + +void +meta_wayland_surface_send_unfullscreened (MetaWaylandSurface *surface) +{ + send_change_state (surface, XDG_SURFACE_STATE_FULLSCREEN, FALSE); +} + void meta_wayland_surface_activated (MetaWaylandSurface *surface) { diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h index ef9ccaa4f..e0886536e 100644 --- a/src/wayland/meta-wayland-surface.h +++ b/src/wayland/meta-wayland-surface.h @@ -41,12 +41,6 @@ struct _MetaWaylandBuffer uint32_t ref_count; }; -typedef struct -{ - guint changed : 1; - guint value : 1; -} MetaWaylandStateFlag; - typedef struct { /* wl_surface.attach */ @@ -67,9 +61,6 @@ typedef struct gboolean frame_extents_changed; GtkBorder frame_extents; - - MetaWaylandStateFlag fullscreen; - MetaWaylandStateFlag maximized; } MetaWaylandDoubleBufferedState; typedef struct @@ -107,6 +98,8 @@ struct _MetaWaylandSurface GSList *pending_placement_ops; } sub; + uint32_t state_changed_serial; + /* All the pending state, that wl_surface.commit will apply. */ MetaWaylandDoubleBufferedState pending; }; @@ -124,6 +117,10 @@ void meta_wayland_surface_window_unmanaged (MetaWaylandSurface *s void meta_wayland_surface_configure_notify (MetaWaylandSurface *surface, int width, int height); +void meta_wayland_surface_send_maximized (MetaWaylandSurface *surface); +void meta_wayland_surface_send_unmaximized (MetaWaylandSurface *surface); +void meta_wayland_surface_send_fullscreened (MetaWaylandSurface *surface); +void meta_wayland_surface_send_unfullscreened (MetaWaylandSurface *surface); void meta_wayland_surface_activated (MetaWaylandSurface *surface); void meta_wayland_surface_deactivated (MetaWaylandSurface *surface); From d1ea17e6a41b9c9e191f110e3c7a40ddaf5309f5 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 11 Mar 2014 17:18:47 -0400 Subject: [PATCH 650/889] meta-weston-launch: Adapt to Clutter's new evdev open callback --- src/wayland/meta-weston-launch.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/wayland/meta-weston-launch.c b/src/wayland/meta-weston-launch.c index 99a444215..7d04493c2 100644 --- a/src/wayland/meta-weston-launch.c +++ b/src/wayland/meta-weston-launch.c @@ -264,6 +264,13 @@ on_evdev_device_open (const char *path, return meta_launcher_open_input_device (launcher, path, flags, error); } +static void +on_evdev_device_close (int fd, + gpointer user_data) +{ + close (fd); +} + static void handle_vt_enter (MetaLauncher *launcher) { @@ -380,7 +387,9 @@ meta_launcher_new (void) g_source_attach (self->inner_source, self->nested_context); g_source_unref (self->inner_source); - clutter_evdev_set_open_callback (on_evdev_device_open, self); + clutter_evdev_set_device_callbacks (on_evdev_device_open, + on_evdev_device_close, + self); return self; } From a5d2c51392e610911b07ad06d68b609fb5e6d395 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 13 Mar 2014 16:49:17 -0400 Subject: [PATCH 651/889] window: Move recalc_type to window-x11.c It's only used by the X11 codepath. --- src/core/window-private.h | 2 - src/core/window-props.c | 2 +- src/core/window-x11.c | 119 +++++++++++++++++++++++++++++++++++++- src/core/window-x11.h | 2 + src/core/window.c | 118 +------------------------------------ 5 files changed, 122 insertions(+), 121 deletions(-) diff --git a/src/core/window-private.h b/src/core/window-private.h index 30805776d..7906bfcaa 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -684,8 +684,6 @@ void meta_window_update_layer (MetaWindow *window); void meta_window_recalc_features (MetaWindow *window); -/* recalc_window_type is x11 only, wayland does its thing and then calls type_changed */ -void meta_window_recalc_window_type (MetaWindow *window); void meta_window_type_changed (MetaWindow *window); void meta_window_frame_size_changed (MetaWindow *window); diff --git a/src/core/window-props.c b/src/core/window-props.c index f0454fe47..dc6f9ba70 100644 --- a/src/core/window-props.c +++ b/src/core/window-props.c @@ -727,7 +727,7 @@ reload_net_wm_state (MetaWindow *window, meta_verbose ("Reloaded _NET_WM_STATE for %s\n", window->desc); - meta_window_recalc_window_type (window); + meta_window_x11_recalc_window_type (window); meta_window_recalc_features (window); } diff --git a/src/core/window-x11.c b/src/core/window-x11.c index 1d473455e..47cd85360 100644 --- a/src/core/window-x11.c +++ b/src/core/window-x11.c @@ -226,7 +226,7 @@ meta_window_x11_update_net_wm_type (MetaWindow *window) meta_XFree (str); } - meta_window_recalc_window_type (window); + meta_window_x11_recalc_window_type (window); } void @@ -872,7 +872,7 @@ meta_window_x11_client_message (MetaWindow *window, (action == _NET_WM_STATE_ADD) || (action == _NET_WM_STATE_TOGGLE && !window->wm_state_modal); - meta_window_recalc_window_type (window); + meta_window_x11_recalc_window_type (window); meta_window_queue(window, META_QUEUE_MOVE_RESIZE); } @@ -1506,3 +1506,118 @@ error: meta_error_trap_pop (display); return NULL; } + +void +meta_window_x11_recalc_window_type (MetaWindow *window) +{ + MetaWindowType old_type; + + old_type = window->type; + + if (window->type_atom != None) + { + if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DESKTOP) + window->type = META_WINDOW_DESKTOP; + else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DOCK) + window->type = META_WINDOW_DOCK; + else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_TOOLBAR) + window->type = META_WINDOW_TOOLBAR; + else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_MENU) + window->type = META_WINDOW_MENU; + else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_UTILITY) + window->type = META_WINDOW_UTILITY; + else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_SPLASH) + window->type = META_WINDOW_SPLASHSCREEN; + else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DIALOG) + window->type = META_WINDOW_DIALOG; + else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_NORMAL) + window->type = META_WINDOW_NORMAL; + /* The below are *typically* override-redirect windows, but the spec does + * not disallow using them for managed windows. + */ + else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DROPDOWN_MENU) + window->type = META_WINDOW_DROPDOWN_MENU; + else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_POPUP_MENU) + window->type = META_WINDOW_POPUP_MENU; + else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_TOOLTIP) + window->type = META_WINDOW_TOOLTIP; + else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_NOTIFICATION) + window->type = META_WINDOW_NOTIFICATION; + else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_COMBO) + window->type = META_WINDOW_COMBO; + else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DND) + window->type = META_WINDOW_DND; + else + { + char *atom_name; + + /* + * Fallback on a normal type, and print warning. Don't abort. + */ + window->type = META_WINDOW_NORMAL; + + meta_error_trap_push (window->display); + atom_name = XGetAtomName (window->display->xdisplay, + window->type_atom); + meta_error_trap_pop (window->display); + + meta_warning ("Unrecognized type atom [%s] set for %s \n", + atom_name ? atom_name : "unknown", + window->desc); + + if (atom_name) + XFree (atom_name); + } + } + else if (window->transient_for != NULL) + { + window->type = META_WINDOW_DIALOG; + } + else + { + window->type = META_WINDOW_NORMAL; + } + + if (window->type == META_WINDOW_DIALOG && + window->wm_state_modal) + window->type = META_WINDOW_MODAL_DIALOG; + + /* We don't want to allow override-redirect windows to have decorated-window + * types since that's just confusing. + */ + if (window->override_redirect) + { + switch (window->type) + { + /* Decorated types */ + case META_WINDOW_NORMAL: + case META_WINDOW_DIALOG: + case META_WINDOW_MODAL_DIALOG: + case META_WINDOW_MENU: + case META_WINDOW_UTILITY: + window->type = META_WINDOW_OVERRIDE_OTHER; + break; + /* Undecorated types, normally not override-redirect */ + case META_WINDOW_DESKTOP: + case META_WINDOW_DOCK: + case META_WINDOW_TOOLBAR: + case META_WINDOW_SPLASHSCREEN: + /* Undecorated types, normally override-redirect types */ + case META_WINDOW_DROPDOWN_MENU: + case META_WINDOW_POPUP_MENU: + case META_WINDOW_TOOLTIP: + case META_WINDOW_NOTIFICATION: + case META_WINDOW_COMBO: + case META_WINDOW_DND: + /* To complete enum */ + case META_WINDOW_OVERRIDE_OTHER: + break; + } + } + + meta_verbose ("Calculated type %u for %s, old type %u\n", + window->type, window->desc, old_type); + + if (old_type != window->type) + meta_window_type_changed (window); +} diff --git a/src/core/window-x11.h b/src/core/window-x11.h index 4657c7f33..d8f2ce2db 100644 --- a/src/core/window-x11.h +++ b/src/core/window-x11.h @@ -35,6 +35,8 @@ void meta_window_x11_update_opaque_region (MetaWindow *window); void meta_window_x11_update_input_region (MetaWindow *window); void meta_window_x11_update_shape_region (MetaWindow *window); +void meta_window_x11_recalc_window_type (MetaWindow *window); + gboolean meta_window_x11_configure_request (MetaWindow *window, XEvent *event); gboolean meta_window_x11_property_notify (MetaWindow *window, diff --git a/src/core/window.c b/src/core/window.c index bbce5a81d..f281b5774 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -7064,121 +7064,6 @@ meta_window_update_struts (MetaWindow *window) } } -void -meta_window_recalc_window_type (MetaWindow *window) -{ - MetaWindowType old_type; - - old_type = window->type; - - if (window->type_atom != None) - { - if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DESKTOP) - window->type = META_WINDOW_DESKTOP; - else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DOCK) - window->type = META_WINDOW_DOCK; - else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_TOOLBAR) - window->type = META_WINDOW_TOOLBAR; - else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_MENU) - window->type = META_WINDOW_MENU; - else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_UTILITY) - window->type = META_WINDOW_UTILITY; - else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_SPLASH) - window->type = META_WINDOW_SPLASHSCREEN; - else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DIALOG) - window->type = META_WINDOW_DIALOG; - else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_NORMAL) - window->type = META_WINDOW_NORMAL; - /* The below are *typically* override-redirect windows, but the spec does - * not disallow using them for managed windows. - */ - else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DROPDOWN_MENU) - window->type = META_WINDOW_DROPDOWN_MENU; - else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_POPUP_MENU) - window->type = META_WINDOW_POPUP_MENU; - else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_TOOLTIP) - window->type = META_WINDOW_TOOLTIP; - else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_NOTIFICATION) - window->type = META_WINDOW_NOTIFICATION; - else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_COMBO) - window->type = META_WINDOW_COMBO; - else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DND) - window->type = META_WINDOW_DND; - else - { - char *atom_name; - - /* - * Fallback on a normal type, and print warning. Don't abort. - */ - window->type = META_WINDOW_NORMAL; - - meta_error_trap_push (window->display); - atom_name = XGetAtomName (window->display->xdisplay, - window->type_atom); - meta_error_trap_pop (window->display); - - meta_warning ("Unrecognized type atom [%s] set for %s \n", - atom_name ? atom_name : "unknown", - window->desc); - - if (atom_name) - XFree (atom_name); - } - } - else if (window->transient_for != NULL) - { - window->type = META_WINDOW_DIALOG; - } - else - { - window->type = META_WINDOW_NORMAL; - } - - if (window->type == META_WINDOW_DIALOG && - window->wm_state_modal) - window->type = META_WINDOW_MODAL_DIALOG; - - /* We don't want to allow override-redirect windows to have decorated-window - * types since that's just confusing. - */ - if (window->override_redirect) - { - switch (window->type) - { - /* Decorated types */ - case META_WINDOW_NORMAL: - case META_WINDOW_DIALOG: - case META_WINDOW_MODAL_DIALOG: - case META_WINDOW_MENU: - case META_WINDOW_UTILITY: - window->type = META_WINDOW_OVERRIDE_OTHER; - break; - /* Undecorated types, normally not override-redirect */ - case META_WINDOW_DESKTOP: - case META_WINDOW_DOCK: - case META_WINDOW_TOOLBAR: - case META_WINDOW_SPLASHSCREEN: - /* Undecorated types, normally override-redirect types */ - case META_WINDOW_DROPDOWN_MENU: - case META_WINDOW_POPUP_MENU: - case META_WINDOW_TOOLTIP: - case META_WINDOW_NOTIFICATION: - case META_WINDOW_COMBO: - case META_WINDOW_DND: - /* To complete enum */ - case META_WINDOW_OVERRIDE_OTHER: - break; - } - } - - meta_verbose ("Calculated type %u for %s, old type %u\n", - window->type, window->desc, old_type); - - if (old_type != window->type) - meta_window_type_changed (window); -} - void meta_window_type_changed (MetaWindow *window) { @@ -10258,7 +10143,8 @@ meta_window_set_transient_for (MetaWindow *window, meta_window_propagate_focus_appearance (window, FALSE); /* may now be a dialog */ - meta_window_recalc_window_type (window); + if (window->client_type == META_WINDOW_CLIENT_TYPE_X11) + meta_window_x11_recalc_window_type (window); if (!window->constructing) { From a9d8107c3d60f57efe57b293f5197eb8397a3cf0 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 13 Mar 2014 16:52:31 -0400 Subject: [PATCH 652/889] window: Replace meta_window_type_changed with meta_window_set_type Which does the equality checking for us. --- src/core/window-private.h | 3 +- src/core/window-x11.c | 50 ++++++++++++++---------------- src/core/window.c | 13 +++++++- src/wayland/meta-wayland-surface.c | 3 +- 4 files changed, 38 insertions(+), 31 deletions(-) diff --git a/src/core/window-private.h b/src/core/window-private.h index 7906bfcaa..aa5525ee2 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -684,7 +684,8 @@ void meta_window_update_layer (MetaWindow *window); void meta_window_recalc_features (MetaWindow *window); -void meta_window_type_changed (MetaWindow *window); +void meta_window_set_type (MetaWindow *window, + MetaWindowType type); void meta_window_frame_size_changed (MetaWindow *window); diff --git a/src/core/window-x11.c b/src/core/window-x11.c index 47cd85360..a27a16a1f 100644 --- a/src/core/window-x11.c +++ b/src/core/window-x11.c @@ -1510,43 +1510,41 @@ error: void meta_window_x11_recalc_window_type (MetaWindow *window) { - MetaWindowType old_type; - - old_type = window->type; + MetaWindowType type; if (window->type_atom != None) { if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DESKTOP) - window->type = META_WINDOW_DESKTOP; + type = META_WINDOW_DESKTOP; else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DOCK) - window->type = META_WINDOW_DOCK; + type = META_WINDOW_DOCK; else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_TOOLBAR) - window->type = META_WINDOW_TOOLBAR; + type = META_WINDOW_TOOLBAR; else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_MENU) - window->type = META_WINDOW_MENU; + type = META_WINDOW_MENU; else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_UTILITY) - window->type = META_WINDOW_UTILITY; + type = META_WINDOW_UTILITY; else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_SPLASH) - window->type = META_WINDOW_SPLASHSCREEN; + type = META_WINDOW_SPLASHSCREEN; else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DIALOG) - window->type = META_WINDOW_DIALOG; + type = META_WINDOW_DIALOG; else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_NORMAL) - window->type = META_WINDOW_NORMAL; + type = META_WINDOW_NORMAL; /* The below are *typically* override-redirect windows, but the spec does * not disallow using them for managed windows. */ else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DROPDOWN_MENU) - window->type = META_WINDOW_DROPDOWN_MENU; + type = META_WINDOW_DROPDOWN_MENU; else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_POPUP_MENU) - window->type = META_WINDOW_POPUP_MENU; + type = META_WINDOW_POPUP_MENU; else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_TOOLTIP) - window->type = META_WINDOW_TOOLTIP; + type = META_WINDOW_TOOLTIP; else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_NOTIFICATION) - window->type = META_WINDOW_NOTIFICATION; + type = META_WINDOW_NOTIFICATION; else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_COMBO) - window->type = META_WINDOW_COMBO; + type = META_WINDOW_COMBO; else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DND) - window->type = META_WINDOW_DND; + type = META_WINDOW_DND; else { char *atom_name; @@ -1554,7 +1552,7 @@ meta_window_x11_recalc_window_type (MetaWindow *window) /* * Fallback on a normal type, and print warning. Don't abort. */ - window->type = META_WINDOW_NORMAL; + type = META_WINDOW_NORMAL; meta_error_trap_push (window->display); atom_name = XGetAtomName (window->display->xdisplay, @@ -1571,16 +1569,16 @@ meta_window_x11_recalc_window_type (MetaWindow *window) } else if (window->transient_for != NULL) { - window->type = META_WINDOW_DIALOG; + type = META_WINDOW_DIALOG; } else { - window->type = META_WINDOW_NORMAL; + type = META_WINDOW_NORMAL; } - if (window->type == META_WINDOW_DIALOG && + if (type == META_WINDOW_DIALOG && window->wm_state_modal) - window->type = META_WINDOW_MODAL_DIALOG; + type = META_WINDOW_MODAL_DIALOG; /* We don't want to allow override-redirect windows to have decorated-window * types since that's just confusing. @@ -1595,7 +1593,7 @@ meta_window_x11_recalc_window_type (MetaWindow *window) case META_WINDOW_MODAL_DIALOG: case META_WINDOW_MENU: case META_WINDOW_UTILITY: - window->type = META_WINDOW_OVERRIDE_OTHER; + type = META_WINDOW_OVERRIDE_OTHER; break; /* Undecorated types, normally not override-redirect */ case META_WINDOW_DESKTOP: @@ -1616,8 +1614,6 @@ meta_window_x11_recalc_window_type (MetaWindow *window) } meta_verbose ("Calculated type %u for %s, old type %u\n", - window->type, window->desc, old_type); - - if (old_type != window->type) - meta_window_type_changed (window); + type, window->desc, type); + meta_window_set_type (window, type); } diff --git a/src/core/window.c b/src/core/window.c index f281b5774..a0335aa46 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -7064,7 +7064,7 @@ meta_window_update_struts (MetaWindow *window) } } -void +static void meta_window_type_changed (MetaWindow *window) { gboolean old_decorated = window->decorated; @@ -7097,6 +7097,17 @@ meta_window_type_changed (MetaWindow *window) g_object_thaw_notify (object); } +void +meta_window_set_type (MetaWindow *window, + MetaWindowType type) +{ + if (window->type == type) + return; + + window->type = type; + meta_window_type_changed (window); +} + void meta_window_frame_size_changed (MetaWindow *window) { diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 71017cab5..86f3dd836 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -991,8 +991,7 @@ xdg_shell_get_xdg_popup (struct wl_client *client, surface->window->placed = TRUE; meta_window_set_transient_for (surface->window, parent_surf->window); - surface->window->type = META_WINDOW_DROPDOWN_MENU; - meta_window_type_changed (surface->window); + meta_window_set_type (surface->window, META_WINDOW_DROPDOWN_MENU); meta_wayland_pointer_start_popup_grab (&seat->pointer, surface); } From 1502d2a79f7ecd2ec2ea9caf895d5a64cc2615b9 Mon Sep 17 00:00:00 2001 From: Ryan Lortie Date: Fri, 14 Mar 2014 01:08:46 -0400 Subject: [PATCH 653/889] Revert "hack autogen to allow automake 1.13" This reverts commit f0c503b5a9700c47d3be4fc36612ea7f333f5512. 01:08 < Jasper> desrt, can you revert that mutter-wayland commit for me? My laptop with git on it is out of commission. --- autogen.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/autogen.sh b/autogen.sh index 79439b56a..8efa68349 100755 --- a/autogen.sh +++ b/autogen.sh @@ -5,7 +5,7 @@ srcdir=`dirname $0` test -z "$srcdir" && srcdir=. PKG_NAME="mutter" -REQUIRED_AUTOMAKE_VERSION=1.13 +REQUIRED_AUTOMAKE_VERSION=1.10 (test -f $srcdir/configure.ac \ && test -d $srcdir/src) || { From c539dfe0d72185720002cb5f323c93cfdf1b4186 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 11 Mar 2014 16:51:24 -0400 Subject: [PATCH 654/889] weston-launch: Pass the DRM device to Cogl Open the device from weston-launch, and pass it to Cogl/Clutter. This is a preliminary cleanup for our login1 integration. --- src/wayland/meta-wayland.c | 11 ----- src/wayland/meta-weston-launch.c | 48 +++++++----------- src/wayland/meta-weston-launch.h | 4 -- src/wayland/weston-launch.c | 84 ++++++-------------------------- src/wayland/weston-launch.h | 5 +- 5 files changed, 36 insertions(+), 116 deletions(-) diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index 8cbe6cf4a..a13a920ae 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -653,17 +653,6 @@ meta_wayland_init (void) if (clutter_init (NULL, NULL) != CLUTTER_INIT_SUCCESS) g_error ("Failed to initialize Clutter"); -#if defined(CLUTTER_WINDOWING_EGL) - if (clutter_check_windowing_backend (CLUTTER_WINDOWING_EGL)) - { - ClutterBackend *backend = clutter_get_default_backend (); - CoglContext *cogl_context = clutter_backend_get_cogl_context (backend); - CoglRenderer *cogl_renderer = cogl_display_get_renderer (cogl_context_get_display (cogl_context)); - int drm_fd = cogl_kms_renderer_get_kms_fd (cogl_renderer); - meta_launcher_set_drm_fd (compositor->launcher, drm_fd, NULL); - } -#endif - meta_monitor_manager_initialize (); monitors = meta_monitor_manager_get (); g_signal_connect (monitors, "monitors-changed", diff --git a/src/wayland/meta-weston-launch.c b/src/wayland/meta-weston-launch.c index 7d04493c2..6ef5c6908 100644 --- a/src/wayland/meta-weston-launch.c +++ b/src/wayland/meta-weston-launch.c @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -156,36 +157,11 @@ send_message_to_wl (MetaLauncher *self, return TRUE; } -gboolean -meta_launcher_set_drm_fd (MetaLauncher *self, - int drm_fd, - GError **error) -{ - struct weston_launcher_message message; - GSocketControlMessage *cmsg; - gboolean ok; - - message.opcode = WESTON_LAUNCHER_DRM_SET_FD; - - cmsg = g_unix_fd_message_new (); - if (g_unix_fd_message_append_fd (G_UNIX_FD_MESSAGE (cmsg), - drm_fd, error) == FALSE) - { - g_object_unref (cmsg); - return FALSE; - } - - ok = send_message_to_wl (self, &message, sizeof message, cmsg, NULL, error); - - g_object_unref (cmsg); - return ok; -} - static int -meta_launcher_open_input_device (MetaLauncher *self, - const char *name, - int flags, - GError **error) +meta_launcher_open_device (MetaLauncher *self, + const char *name, + int flags, + GError **error) { struct weston_launcher_open *message; GSocketControlMessage *cmsg; @@ -261,7 +237,7 @@ on_evdev_device_open (const char *path, { MetaLauncher *launcher = user_data; - return meta_launcher_open_input_device (launcher, path, flags, error); + return meta_launcher_open_device (launcher, path, flags, error); } static void @@ -391,6 +367,18 @@ meta_launcher_new (void) on_evdev_device_close, self); +#if defined(CLUTTER_WINDOWING_EGL) + if (clutter_check_windowing_backend (CLUTTER_WINDOWING_EGL)) + { + GError *error = NULL; + int fd = meta_launcher_open_device (self, "/dev/dri/card0", O_RDWR, &error); + if (error) + g_error ("Failed to open /dev/dri/card0: %s", error->message); + + clutter_egl_set_kms_fd (fd); + } +#endif + return self; } diff --git a/src/wayland/meta-weston-launch.h b/src/wayland/meta-weston-launch.h index 7fdd03c23..b70faf88e 100644 --- a/src/wayland/meta-weston-launch.h +++ b/src/wayland/meta-weston-launch.h @@ -31,8 +31,4 @@ void meta_launcher_free (MetaLauncher *self); gboolean meta_launcher_activate_vt (MetaLauncher *self, signed char vt, GError **error); - -gboolean meta_launcher_set_drm_fd (MetaLauncher *self, - int drm_fd, - GError **error); #endif diff --git a/src/wayland/weston-launch.c b/src/wayland/weston-launch.c index 240cfef16..ae713ed23 100644 --- a/src/wayland/weston-launch.c +++ b/src/wayland/weston-launch.c @@ -165,69 +165,6 @@ setenv_fd(const char *env, int fd) setenv(env, buf, 1); } -static int -handle_setdrmfd(struct weston_launch *wl, struct msghdr *msg, ssize_t len) -{ - struct weston_launcher_reply reply; - struct cmsghdr *cmsg; - union cmsg_data *data; - struct stat s; - - reply.header.opcode = WESTON_LAUNCHER_DRM_SET_FD; - reply.ret = -1; - - if (wl->drm_fd != -1) { - error(0, 0, "DRM FD already set"); - reply.ret = -EINVAL; - goto out; - } - - cmsg = CMSG_FIRSTHDR(msg); - if (!cmsg || - cmsg->cmsg_level != SOL_SOCKET || - cmsg->cmsg_type != SCM_RIGHTS) { - error(0, 0, "invalid control message"); - reply.ret = -EINVAL; - goto out; - } - - data = (union cmsg_data *) CMSG_DATA(cmsg); - if (data->fd < 0) { - error(0, 0, "missing drm fd in socket request"); - reply.ret = -EINVAL; - goto out; - } - - if (fstat(data->fd, &s) < 0) { - reply.ret = -errno; - goto out; - } - - if (major(s.st_rdev) != DRM_MAJOR) { - fprintf(stderr, "FD is not for DRM\n"); - reply.ret = -EPERM; - goto out; - } - - wl->drm_fd = data->fd; - reply.ret = drmSetMaster(data->fd); - if (reply.ret < 0) - reply.ret = -errno; - - if (wl->verbose) - fprintf(stderr, "mutter-launch: set drm FD, ret: %d, fd: %d\n", - reply.ret, data->fd); - -out: - do { - len = send(wl->sock[0], &reply, sizeof reply, 0); - } while (len < 0 && errno == EINTR); - if (len < 0) - return -1; - - return 0; -} - static int handle_confirm_vt_switch(struct weston_launch *wl, struct msghdr *msg, ssize_t len) { @@ -323,6 +260,7 @@ handle_open(struct weston_launch *wl, struct msghdr *msg, ssize_t len) struct iovec iov; struct weston_launcher_open *message; union cmsg_data *data; + int dev_major; reply.header.opcode = WESTON_LAUNCHER_OPEN; reply.ret = -1; @@ -339,13 +277,22 @@ handle_open(struct weston_launch *wl, struct msghdr *msg, ssize_t len) goto err0; } - if (major(s.st_rdev) != INPUT_MAJOR) { - fprintf(stderr, "Device %s is not an input device\n", + dev_major = major(s.st_rdev); + + if (dev_major != INPUT_MAJOR || + dev_major != DRM_MAJOR) { + fprintf(stderr, "Device %s is not an input or DRM device\n", message->path); reply.ret = -EPERM; goto err0; } + if (dev_major == DRM_MAJOR && wl->drm_fd != -1) { + fprintf(stderr, "Already have a DRM device open\n"); + reply.ret = -EPERM; + goto err0; + } + fd = open(message->path, message->flags); if (fd < 0) { fprintf(stderr, "Error opening device %s: %m\n", @@ -354,6 +301,10 @@ handle_open(struct weston_launch *wl, struct msghdr *msg, ssize_t len) goto err0; } + if (dev_major == DRM_MAJOR) { + wl->drm_fd = fd; + } + err0: memset(&nmsg, 0, sizeof nmsg); nmsg.msg_iov = &iov; @@ -419,9 +370,6 @@ handle_socket_msg(struct weston_launch *wl) case WESTON_LAUNCHER_OPEN: ret = handle_open(wl, &msg, len); break; - case WESTON_LAUNCHER_DRM_SET_FD: - ret = handle_setdrmfd(wl, &msg, len); - break; case WESTON_LAUNCHER_CONFIRM_VT_SWITCH: ret = handle_confirm_vt_switch(wl, &msg, len); break; diff --git a/src/wayland/weston-launch.h b/src/wayland/weston-launch.h index 968dd7416..1e716c5ac 100644 --- a/src/wayland/weston-launch.h +++ b/src/wayland/weston-launch.h @@ -31,9 +31,8 @@ enum weston_launcher_message_type { enum weston_launcher_opcode { WESTON_LAUNCHER_OPEN = (1 << 1 | WESTON_LAUNCHER_REQUEST), - WESTON_LAUNCHER_DRM_SET_FD = (2 << 1 | WESTON_LAUNCHER_REQUEST), - WESTON_LAUNCHER_ACTIVATE_VT = (3 << 1 | WESTON_LAUNCHER_REQUEST), - WESTON_LAUNCHER_CONFIRM_VT_SWITCH = (4 << 1 | WESTON_LAUNCHER_REQUEST), + WESTON_LAUNCHER_ACTIVATE_VT = (2 << 1 | WESTON_LAUNCHER_REQUEST), + WESTON_LAUNCHER_CONFIRM_VT_SWITCH = (3 << 1 | WESTON_LAUNCHER_REQUEST), }; enum weston_launcher_server_opcode { From 93ac0329db368b307c2c6d58308396325689c919 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 14 Mar 2014 16:04:56 -0400 Subject: [PATCH 655/889] weston-launch: Fix a typo causing mutter-launch to not work --- src/wayland/weston-launch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wayland/weston-launch.c b/src/wayland/weston-launch.c index ae713ed23..ba1ed7476 100644 --- a/src/wayland/weston-launch.c +++ b/src/wayland/weston-launch.c @@ -279,7 +279,7 @@ handle_open(struct weston_launch *wl, struct msghdr *msg, ssize_t len) dev_major = major(s.st_rdev); - if (dev_major != INPUT_MAJOR || + if (dev_major != INPUT_MAJOR && dev_major != DRM_MAJOR) { fprintf(stderr, "Device %s is not an input or DRM device\n", message->path); From 0f859863407dd976e88cf4eca842e4c07a77b22e Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 13 Mar 2014 18:32:20 -0400 Subject: [PATCH 656/889] Add a META_MAXIMIZE_BOTH Which has the value of META_MAXIMIZE_VERTICAL | META_MAXIMIZE_HORIZONTAL. This is an obvious code cleanup. --- src/compositor/meta-window-actor.c | 2 +- src/core/core.c | 24 ++++++++---------------- src/core/keybindings.c | 30 ++++++++---------------------- src/core/window.c | 28 +++++++--------------------- src/meta/window.h | 4 +++- src/wayland/meta-wayland-surface.c | 8 ++++---- 6 files changed, 31 insertions(+), 65 deletions(-) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index a26d342bc..e5d54e9f1 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -714,7 +714,7 @@ meta_window_actor_has_shadow (MetaWindowActor *self) /* Leaving out shadows for maximized and fullscreen windows is an effeciency * win and also prevents the unsightly effect of the shadow of maximized * window appearing on an adjacent window */ - if ((meta_window_get_maximized (priv->window) == (META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL)) || + if ((meta_window_get_maximized (priv->window) == META_MAXIMIZE_BOTH) || meta_window_is_fullscreen (priv->window)) return FALSE; diff --git a/src/core/core.c b/src/core/core.c index cb2a747e5..9f41a3577 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -328,8 +328,7 @@ meta_core_maximize (Display *xdisplay, if (meta_prefs_get_raise_on_click ()) meta_window_raise (window); - meta_window_maximize (window, - META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL); + meta_window_maximize (window, META_MAXIMIZE_BOTH); } void @@ -342,11 +341,9 @@ meta_core_toggle_maximize_vertically (Display *xdisplay, meta_window_raise (window); if (META_WINDOW_MAXIMIZED_VERTICALLY (window)) - meta_window_unmaximize (window, - META_MAXIMIZE_VERTICAL); + meta_window_unmaximize (window, META_MAXIMIZE_VERTICAL); else - meta_window_maximize (window, - META_MAXIMIZE_VERTICAL); + meta_window_maximize (window, META_MAXIMIZE_VERTICAL); } void @@ -359,11 +356,9 @@ meta_core_toggle_maximize_horizontally (Display *xdisplay, meta_window_raise (window); if (META_WINDOW_MAXIMIZED_HORIZONTALLY (window)) - meta_window_unmaximize (window, - META_MAXIMIZE_HORIZONTAL); + meta_window_unmaximize (window, META_MAXIMIZE_HORIZONTAL); else - meta_window_maximize (window, - META_MAXIMIZE_HORIZONTAL); + meta_window_maximize (window, META_MAXIMIZE_HORIZONTAL); } void @@ -376,11 +371,9 @@ meta_core_toggle_maximize (Display *xdisplay, meta_window_raise (window); if (META_WINDOW_MAXIMIZED (window)) - meta_window_unmaximize (window, - META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL); + meta_window_unmaximize (window, META_MAXIMIZE_BOTH); else - meta_window_maximize (window, - META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL); + meta_window_maximize (window, META_MAXIMIZE_BOTH); } void @@ -392,8 +385,7 @@ meta_core_unmaximize (Display *xdisplay, if (meta_prefs_get_raise_on_click ()) meta_window_raise (window); - meta_window_unmaximize (window, - META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL); + meta_window_unmaximize (window, META_MAXIMIZE_BOTH); } void diff --git a/src/core/keybindings.c b/src/core/keybindings.c index 23b83b782..415ccf851 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -1975,9 +1975,7 @@ process_mouse_move_resize_grab (MetaDisplay *display, * moveresize now to get the position back to the original. */ if (window->shaken_loose || window->tile_mode == META_TILE_MAXIMIZED) - meta_window_maximize (window, - META_MAXIMIZE_HORIZONTAL | - META_MAXIMIZE_VERTICAL); + meta_window_maximize (window, META_MAXIMIZE_BOTH); else if (window->tile_mode != META_TILE_NONE) meta_window_tile (window); else @@ -2038,9 +2036,7 @@ process_keyboard_move_grab (MetaDisplay *display, * now to get the position back to the original. */ if (window->shaken_loose) - meta_window_maximize (window, - META_MAXIMIZE_HORIZONTAL | - META_MAXIMIZE_VERTICAL); + meta_window_maximize (window, META_MAXIMIZE_BOTH); else meta_window_move_resize (display->grab_window, TRUE, @@ -2901,11 +2897,9 @@ handle_toggle_tiled (MetaDisplay *display, : META_TILE_NONE; if (window->saved_maximize) - meta_window_maximize (window, META_MAXIMIZE_VERTICAL | - META_MAXIMIZE_HORIZONTAL); + meta_window_maximize (window, META_MAXIMIZE_BOTH); else - meta_window_unmaximize (window, META_MAXIMIZE_VERTICAL | - META_MAXIMIZE_HORIZONTAL); + meta_window_unmaximize (window, META_MAXIMIZE_BOTH); } else if (meta_window_can_tile_side_by_side (window)) { @@ -2931,13 +2925,9 @@ handle_toggle_maximized (MetaDisplay *display, gpointer dummy) { if (META_WINDOW_MAXIMIZED (window)) - meta_window_unmaximize (window, - META_MAXIMIZE_HORIZONTAL | - META_MAXIMIZE_VERTICAL); + meta_window_unmaximize (window, META_MAXIMIZE_BOTH); else if (window->has_maximize_func) - meta_window_maximize (window, - META_MAXIMIZE_HORIZONTAL | - META_MAXIMIZE_VERTICAL); + meta_window_maximize (window, META_MAXIMIZE_BOTH); } static void @@ -2949,9 +2939,7 @@ handle_maximize (MetaDisplay *display, gpointer dummy) { if (window->has_maximize_func) - meta_window_maximize (window, - META_MAXIMIZE_HORIZONTAL | - META_MAXIMIZE_VERTICAL); + meta_window_maximize (window, META_MAXIMIZE_BOTH); } static void @@ -2963,9 +2951,7 @@ handle_unmaximize (MetaDisplay *display, gpointer dummy) { if (window->maximized_vertically || window->maximized_horizontally) - meta_window_unmaximize (window, - META_MAXIMIZE_HORIZONTAL | - META_MAXIMIZE_VERTICAL); + meta_window_unmaximize (window, META_MAXIMIZE_BOTH); } static void diff --git a/src/core/window.c b/src/core/window.c index a0335aa46..a70fe6610 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -1368,9 +1368,7 @@ meta_window_apply_session_info (MetaWindow *window, if (window->has_maximize_func && info->maximized) { - meta_window_maximize (window, - META_MAXIMIZE_HORIZONTAL | - META_MAXIMIZE_VERTICAL); + meta_window_maximize (window, META_MAXIMIZE_BOTH); if (info->saved_rect_set) { @@ -3370,7 +3368,7 @@ meta_window_tile (MetaWindow *window) return; if (window->tile_mode == META_TILE_MAXIMIZED) - directions = META_MAXIMIZE_VERTICAL | META_MAXIMIZE_HORIZONTAL; + directions = META_MAXIMIZE_BOTH; else directions = META_MAXIMIZE_VERTICAL; @@ -7456,15 +7454,11 @@ menu_callback (MetaWindowMenu *menu, break; case META_MENU_OP_UNMAXIMIZE: - meta_window_unmaximize (window, - META_MAXIMIZE_HORIZONTAL | - META_MAXIMIZE_VERTICAL); + meta_window_unmaximize (window, META_MAXIMIZE_BOTH); break; case META_MENU_OP_MAXIMIZE: - meta_window_maximize (window, - META_MAXIMIZE_HORIZONTAL | - META_MAXIMIZE_VERTICAL); + meta_window_maximize (window, META_MAXIMIZE_BOTH); break; case META_MENU_OP_UNSHADE: @@ -7981,10 +7975,7 @@ update_move (MetaWindow *window, display->grab_anchor_root_x = x; display->grab_anchor_root_y = y; - meta_window_unmaximize (window, - META_MAXIMIZE_HORIZONTAL | - META_MAXIMIZE_VERTICAL); - + meta_window_unmaximize (window, META_MAXIMIZE_BOTH); return; } @@ -8028,9 +8019,7 @@ update_move (MetaWindow *window, window->user_rect.x = window->saved_rect.x; window->user_rect.y = window->saved_rect.y; - meta_window_unmaximize (window, - META_MAXIMIZE_HORIZONTAL | - META_MAXIMIZE_VERTICAL); + meta_window_unmaximize (window, META_MAXIMIZE_BOTH); } display->grab_initial_window_pos = work_area; @@ -8038,10 +8027,7 @@ update_move (MetaWindow *window, display->grab_anchor_root_y = y; window->shaken_loose = FALSE; - meta_window_maximize (window, - META_MAXIMIZE_HORIZONTAL | - META_MAXIMIZE_VERTICAL); - + meta_window_maximize (window, META_MAXIMIZE_BOTH); return; } } diff --git a/src/meta/window.h b/src/meta/window.h index 430dc6bd9..d8871c5f9 100644 --- a/src/meta/window.h +++ b/src/meta/window.h @@ -72,11 +72,13 @@ typedef enum * MetaMaximizeFlags: * @META_MAXIMIZE_HORIZONTAL: Horizontal * @META_MAXIMIZE_VERTICAL: Vertical + * @META_MAXIMIZE_BOTH: Both */ typedef enum { META_MAXIMIZE_HORIZONTAL = 1 << 0, - META_MAXIMIZE_VERTICAL = 1 << 1 + META_MAXIMIZE_VERTICAL = 1 << 1, + META_MAXIMIZE_BOTH = (1 << 0 | 1 << 1), } MetaMaximizeFlags; /** diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 86f3dd836..940c32f0f 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -857,9 +857,9 @@ xdg_surface_request_change_state (struct wl_client *client, { case XDG_SURFACE_STATE_MAXIMIZED: if (value) - meta_window_maximize (surface->window, META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL); + meta_window_maximize (surface->window, META_MAXIMIZE_BOTH); else - meta_window_unmaximize (surface->window, META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL); + meta_window_unmaximize (surface->window, META_MAXIMIZE_BOTH); break; case XDG_SURFACE_STATE_FULLSCREEN: if (value) @@ -1153,9 +1153,9 @@ wl_shell_surface_set_state (MetaWaylandSurface *surface, meta_window_unmake_fullscreen (surface->window); if (state == SURFACE_STATE_MAXIMIZED) - meta_window_maximize (surface->window, META_MAXIMIZE_VERTICAL | META_MAXIMIZE_HORIZONTAL); + meta_window_maximize (surface->window, META_MAXIMIZE_BOTH); else - meta_window_unmaximize (surface->window, META_MAXIMIZE_VERTICAL | META_MAXIMIZE_HORIZONTAL); + meta_window_unmaximize (surface->window, META_MAXIMIZE_BOTH); } static void From 3c6dd5bf6d013997ff8c0fb463850ed0d45b2651 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 13 Mar 2014 18:15:26 -0400 Subject: [PATCH 657/889] window: Export a bunch of state flags as accessor methods This is necessary to reimplement window menus in gnome-shell. --- src/core/window.c | 54 +++++++++++++++++++++++++++++++++++++++++------ src/meta/window.h | 7 ++++++ 2 files changed, 55 insertions(+), 6 deletions(-) diff --git a/src/core/window.c b/src/core/window.c index a70fe6610..c6cf2a3b8 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -10051,12 +10051,6 @@ meta_window_compute_tile_match (MetaWindow *window) } } -gboolean -meta_window_can_close (MetaWindow *window) -{ - return window->has_close_func; -} - void meta_window_set_title (MetaWindow *window, const char *title) @@ -10398,3 +10392,51 @@ meta_window_set_custom_frame_extents (MetaWindow *window, meta_window_queue (window, META_QUEUE_MOVE_RESIZE); } + +gboolean +meta_window_can_maximize (MetaWindow *window) +{ + return window->has_maximize_func; +} + +gboolean +meta_window_can_minimize (MetaWindow *window) +{ + return window->has_minimize_func; +} + +gboolean +meta_window_can_shade (MetaWindow *window) +{ + return window->has_shade_func; +} + +gboolean +meta_window_can_close (MetaWindow *window) +{ + return window->has_close_func; +} + +gboolean +meta_window_is_always_on_all_workspaces (MetaWindow *window) +{ + return window->always_sticky; +} + +gboolean +meta_window_is_above (MetaWindow *window) +{ + return window->wm_state_above; +} + +gboolean +meta_window_allows_move (MetaWindow *window) +{ + return META_WINDOW_ALLOWS_MOVE (window); +} + +gboolean +meta_window_allows_resize (MetaWindow *window) +{ + return META_WINDOW_ALLOWS_RESIZE (window); +} diff --git a/src/meta/window.h b/src/meta/window.h index d8871c5f9..e979d7bb8 100644 --- a/src/meta/window.h +++ b/src/meta/window.h @@ -254,6 +254,13 @@ void meta_window_begin_grab_op (MetaWindow *window, gboolean frame_action, guint32 timestamp); +gboolean meta_window_can_maximize (MetaWindow *window); +gboolean meta_window_can_minimize (MetaWindow *window); +gboolean meta_window_can_shade (MetaWindow *window); gboolean meta_window_can_close (MetaWindow *window); +gboolean meta_window_is_always_on_all_workspaces (MetaWindow *window); +gboolean meta_window_is_above (MetaWindow *window); +gboolean meta_window_allows_move (MetaWindow *window); +gboolean meta_window_allows_resize (MetaWindow *window); #endif From 62e45b6d5ee5854e55983961cb47774465725864 Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Sun, 16 Mar 2014 16:50:38 +0100 Subject: [PATCH 658/889] wayland-pointer: Drop unused arg from focus grab interface method https://bugzilla.gnome.org/show_bug.cgi?id=726123 --- src/wayland/meta-wayland-data-device.c | 5 ++--- src/wayland/meta-wayland-pointer.c | 12 +++++------- src/wayland/meta-wayland-pointer.h | 3 +-- src/wayland/meta-wayland-seat.c | 3 +-- 4 files changed, 9 insertions(+), 14 deletions(-) diff --git a/src/wayland/meta-wayland-data-device.c b/src/wayland/meta-wayland-data-device.c index fe7b237ab..c45476112 100644 --- a/src/wayland/meta-wayland-data-device.c +++ b/src/wayland/meta-wayland-data-device.c @@ -175,8 +175,7 @@ destroy_drag_focus (struct wl_listener *listener, void *data) static void drag_grab_focus (MetaWaylandPointerGrab *grab, - MetaWaylandSurface *surface, - const ClutterEvent *event) + MetaWaylandSurface *surface) { MetaWaylandDragGrab *drag_grab = (MetaWaylandDragGrab*) grab; MetaWaylandSeat *seat = drag_grab->seat; @@ -257,7 +256,7 @@ data_device_end_drag_grab (MetaWaylandDragGrab *drag_grab) if (drag_grab->drag_data_source) wl_list_remove (&drag_grab->drag_data_source_listener.link); - drag_grab_focus (&drag_grab->generic, NULL, NULL); + drag_grab_focus (&drag_grab->generic, NULL); meta_wayland_pointer_end_grab (drag_grab->generic.pointer); g_slice_free (MetaWaylandDragGrab, drag_grab); diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index 07bd3620f..336cea023 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -78,8 +78,7 @@ pointer_handle_focus_resource_destroy (struct wl_listener *listener, void *data) static void default_grab_focus (MetaWaylandPointerGrab *grab, - MetaWaylandSurface *surface, - const ClutterEvent *event) + MetaWaylandSurface *surface) { MetaWaylandPointer *pointer = grab->pointer; @@ -385,7 +384,7 @@ meta_wayland_pointer_start_grab (MetaWaylandPointer *pointer, grab->pointer = pointer; if (pointer->current) - interface->focus (pointer->grab, pointer->current, NULL); + interface->focus (pointer->grab, pointer->current); } void @@ -395,7 +394,7 @@ meta_wayland_pointer_end_grab (MetaWaylandPointer *pointer) pointer->grab = &pointer->default_grab; interface = pointer->grab->interface; - interface->focus (pointer->grab, pointer->current, NULL); + interface->focus (pointer->grab, pointer->current); } typedef struct { @@ -415,15 +414,14 @@ typedef struct { static void popup_grab_focus (MetaWaylandPointerGrab *grab, - MetaWaylandSurface *surface, - const ClutterEvent *event) + MetaWaylandSurface *surface) { MetaWaylandPopupGrab *popup_grab = (MetaWaylandPopupGrab*)grab; /* Popup grabs are in owner-events mode (ie, events for the same client are reported as normal) */ if (surface && wl_resource_get_client (surface->resource) == popup_grab->grab_client) - default_grab_focus (grab, surface, event); + default_grab_focus (grab, surface); else meta_wayland_pointer_set_focus (grab->pointer, NULL); } diff --git a/src/wayland/meta-wayland-pointer.h b/src/wayland/meta-wayland-pointer.h index 08b6988e8..5eb6756e9 100644 --- a/src/wayland/meta-wayland-pointer.h +++ b/src/wayland/meta-wayland-pointer.h @@ -29,8 +29,7 @@ struct _MetaWaylandPointerGrabInterface { void (*focus) (MetaWaylandPointerGrab *grab, - MetaWaylandSurface *surface, - const ClutterEvent *event); + MetaWaylandSurface *surface); void (*motion) (MetaWaylandPointerGrab *grab, const ClutterEvent *event); void (*button) (MetaWaylandPointerGrab *grab, diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c index 2f4658727..ed2ef55be 100644 --- a/src/wayland/meta-wayland-seat.c +++ b/src/wayland/meta-wayland-seat.c @@ -440,8 +440,7 @@ meta_wayland_seat_repick (MetaWaylandSeat *seat, { const MetaWaylandPointerGrabInterface *interface = pointer->grab->interface; - interface->focus (pointer->grab, - surface, for_event); + interface->focus (pointer->grab, surface); } } From 535685742a41fd9b7e3e59ba725d621ea8a89add Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 14 Mar 2014 10:51:34 -0400 Subject: [PATCH 659/889] window: Export is_title_onscreen and shove_title_onscreen as well This was fixed in the master version of the commit, but I forgot to squash it on the Wayland branch. --- src/core/window-private.h | 3 --- src/meta/window.h | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/window-private.h b/src/core/window-private.h index aa5525ee2..52132be65 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -634,9 +634,6 @@ void meta_window_show_menu (MetaWindow *window, int button, guint32 timestamp); -gboolean meta_window_titlebar_is_onscreen (MetaWindow *window); -void meta_window_shove_titlebar_onscreen (MetaWindow *window); - void meta_window_set_gravity (MetaWindow *window, int gravity); diff --git a/src/meta/window.h b/src/meta/window.h index e979d7bb8..ca67bf0d6 100644 --- a/src/meta/window.h +++ b/src/meta/window.h @@ -263,4 +263,7 @@ gboolean meta_window_is_above (MetaWindow *window); gboolean meta_window_allows_move (MetaWindow *window); gboolean meta_window_allows_resize (MetaWindow *window); +gboolean meta_window_titlebar_is_onscreen (MetaWindow *window); +void meta_window_shove_titlebar_onscreen (MetaWindow *window); + #endif From d07d5d132882036159ac1f34b97c4a8c2d328288 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 17 Mar 2014 16:17:48 -0400 Subject: [PATCH 660/889] common: remove documentation for dead grab ops --- src/meta/common.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/meta/common.h b/src/meta/common.h index f81d763d7..6ae1d8918 100644 --- a/src/meta/common.h +++ b/src/meta/common.h @@ -163,13 +163,6 @@ typedef void (* MetaWindowMenuFunc) (MetaWindowMenu *menu, * @META_GRAB_OP_KEYBOARD_RESIZING_NE: Resizing NE with keyboard * @META_GRAB_OP_KEYBOARD_RESIZING_SW: Resizing SW with keyboard * @META_GRAB_OP_KEYBOARD_RESIZING_NW: Resizing NS with keyboard - * @META_GRAB_OP_KEYBOARD_TABBING_NORMAL: Tabbing - * @META_GRAB_OP_KEYBOARD_TABBING_DOCK: Tabbing through docks - * @META_GRAB_OP_KEYBOARD_ESCAPING_NORMAL: Escaping - * @META_GRAB_OP_KEYBOARD_ESCAPING_DOCK: Escaping through docks - * @META_GRAB_OP_KEYBOARD_ESCAPING_GROUP: Escaping through groups - * @META_GRAB_OP_KEYBOARD_TABBING_GROUP: Tabbing through groups - * @META_GRAB_OP_KEYBOARD_WORKSPACE_SWITCHING: Switch to another workspace * @META_GRAB_OP_CLICKING_MINIMIZE: Clicked minimize button * @META_GRAB_OP_CLICKING_MAXIMIZE: Clicked maximize button * @META_GRAB_OP_CLICKING_UNMAXIMIZE: Clicked unmaximize button From 8b4c5459c0e3fd0aed959331600cb6960b6263f8 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 10:06:39 -0400 Subject: [PATCH 661/889] window: Remove transient_for_as_xid It's unused, and it exposes an X11-specific property to API. --- src/core/window.c | 19 ------------------- src/meta/window.h | 1 - 2 files changed, 20 deletions(-) diff --git a/src/core/window.c b/src/core/window.c index c6cf2a3b8..9b5358463 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -9733,25 +9733,6 @@ meta_window_get_transient_for (MetaWindow *window) return NULL; } -/** - * meta_window_get_transient_for_as_xid: - * @window: a #MetaWindow - * - * Returns the XID of the window that is pointed to by the - * WM_TRANSIENT_FOR hint on this window (see XGetTransientForHint() - * or XSetTransientForHint()). Metacity keeps transient windows above their - * parents. A typical usage of this hint is for a dialog that wants to stay - * above its associated window. - * - * Return value: (transfer none): the window this window is transient for, or - * None if the WM_TRANSIENT_FOR hint is unset. - */ -Window -meta_window_get_transient_for_as_xid (MetaWindow *window) -{ - return window->xtransient_for; -} - /** * meta_window_get_pid: * @window: a #MetaWindow diff --git a/src/meta/window.h b/src/meta/window.h index ca67bf0d6..378b5d82f 100644 --- a/src/meta/window.h +++ b/src/meta/window.h @@ -205,7 +205,6 @@ void meta_window_raise (MetaWindow *window); void meta_window_lower (MetaWindow *window); const char *meta_window_get_title (MetaWindow *window); MetaWindow *meta_window_get_transient_for (MetaWindow *window); -Window meta_window_get_transient_for_as_xid (MetaWindow *window); void meta_window_delete (MetaWindow *window, guint32 timestamp); guint meta_window_get_stable_sequence (MetaWindow *window); From 1f15c85c000c9fd6b82d90c1bcdbb0f8906277b7 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 10:08:28 -0400 Subject: [PATCH 662/889] window: Make window_is_terminal private --- src/core/window-private.h | 3 --- src/core/window.c | 11 +++++------ 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/core/window-private.h b/src/core/window-private.h index 52132be65..1f2166454 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -567,9 +567,6 @@ void meta_window_change_workspace (MetaWindow *window, /* Return whether the window should be currently mapped */ gboolean meta_window_should_be_showing (MetaWindow *window); -/* See warning in window.c about this function */ -gboolean __window_is_terminal (MetaWindow *window); - void meta_window_update_struts (MetaWindow *window); /* this gets root coords */ diff --git a/src/core/window.c b/src/core/window.c index 9b5358463..a9d6e1221 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -2399,8 +2399,8 @@ intervening_user_event_occurred (MetaWindow *window) * behavior is worthwhile. The basic idea is to get more feedback about how * usage scenarios of "strict" focus users and what they expect. See #326159. */ -gboolean -__window_is_terminal (MetaWindow *window) +static gboolean +window_is_terminal (MetaWindow *window) { if (window == NULL || window->res_class == NULL) return FALSE; @@ -2476,7 +2476,7 @@ window_state_on_map (MetaWindow *window, if (*takes_focus && meta_prefs_get_focus_new_windows () == G_DESKTOP_FOCUS_NEW_WINDOWS_STRICT && !window->display->allow_terminal_deactivation && - __window_is_terminal (window->display->focus_window) && + window_is_terminal (window->display->focus_window) && !meta_window_is_ancestor_of_transient (window->display->focus_window, window)) { @@ -9252,9 +9252,8 @@ meta_window_set_user_time (MetaWindow *window, /* If this is a terminal, user interaction with it means the user likely * doesn't want to have focus transferred for now due to new windows. */ - if (meta_prefs_get_focus_new_windows () == - G_DESKTOP_FOCUS_NEW_WINDOWS_STRICT && - __window_is_terminal (window)) + if (meta_prefs_get_focus_new_windows () == G_DESKTOP_FOCUS_NEW_WINDOWS_STRICT && + window_is_terminal (window)) window->display->allow_terminal_deactivation = FALSE; } From f11bf445259913a56462cf2239e875e5e858ac98 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 10:17:34 -0400 Subject: [PATCH 663/889] stack: Flatten and simplify the default focus window logic --- src/core/stack.c | 79 ++++++++++++++++++++++++------------------------ 1 file changed, 40 insertions(+), 39 deletions(-) diff --git a/src/core/stack.c b/src/core/stack.c index 6cf078c52..4a3481120 100644 --- a/src/core/stack.c +++ b/src/core/stack.c @@ -1705,8 +1705,8 @@ get_default_focus_window (MetaStack *stack, MetaWindow *topmost_in_group; MetaWindow *topmost_overall; MetaGroup *not_this_one_group; - GList *link; - + GList *l; + transient_parent = NULL; topmost_in_group = NULL; topmost_overall = NULL; @@ -1718,49 +1718,50 @@ get_default_focus_window (MetaStack *stack, stack_ensure_sorted (stack); /* top of this layer is at the front of the list */ - link = stack->sorted; - - while (link) + for (l = stack->sorted; l != NULL; l = l->next) { - MetaWindow *window = link->data; + MetaWindow *window = l->data; - if (window && - window != not_this_one && - (window->unmaps_pending == 0) && - !window->minimized && - (window->input || window->take_focus) && - (workspace == NULL || - meta_window_located_on_workspace (window, workspace))) + if (!window) + continue; + + if (window == not_this_one) + continue; + + if (window->unmaps_pending > 0) + continue; + + if (window->minimized) + continue; + + if (!(window->input || window->take_focus)) + continue; + + if (workspace != NULL && !meta_window_located_on_workspace (window, workspace)) + continue; + + if (must_be_at_point && !window_contains_point (window, root_x, root_y)) + continue; + + if (not_this_one != NULL) { - if (not_this_one != NULL) - { - if (transient_parent == NULL && - not_this_one->xtransient_for != None && - not_this_one->xtransient_for == window->xwindow && - (!must_be_at_point || - window_contains_point (window, root_x, root_y))) - transient_parent = window; + if (transient_parent == NULL && + not_this_one->xtransient_for != None && + not_this_one->xtransient_for == window->xwindow) + transient_parent = window; - if (topmost_in_group == NULL && - not_this_one_group != NULL && - not_this_one_group == meta_window_get_group (window) && - (!must_be_at_point || - window_contains_point (window, root_x, root_y))) - topmost_in_group = window; - } - - if (topmost_overall == NULL && - window->type != META_WINDOW_DOCK && - (!must_be_at_point || - window_contains_point (window, root_x, root_y))) - topmost_overall = window; - - /* We could try to bail out early here for efficiency in - * some cases, but it's just not worth the code. - */ + if (topmost_in_group == NULL && + not_this_one_group != NULL && + not_this_one_group == meta_window_get_group (window)) + topmost_in_group = window; } - link = link->next; + if (topmost_overall == NULL && window->type != META_WINDOW_DOCK) + topmost_overall = window; + + /* We could try to bail out early here for efficiency in + * some cases, but it's just not worth the code. + */ } if (transient_parent) From ada9610e30de5bbab013c40227cdaa06f19a1ae7 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 10:12:44 -0400 Subject: [PATCH 664/889] Start hacking out use of xtransient_for It won't work under Wayland. --- src/core/delete.c | 3 +-- src/core/place.c | 19 ++++++------------- src/core/stack.c | 3 +-- 3 files changed, 8 insertions(+), 17 deletions(-) diff --git a/src/core/delete.c b/src/core/delete.c index 9cfa71534..b86dcf304 100644 --- a/src/core/delete.c +++ b/src/core/delete.c @@ -261,8 +261,7 @@ meta_window_present_delete_dialog (MetaWindow *window, guint32 timestamp) { MetaWindow *w = tmp->data; - if (w->xtransient_for == window->xwindow && - w->res_class && + if (w->transient_for == window && w->res_class && g_ascii_strcasecmp (w->res_class, "mutter-dialog") == 0) { meta_window_activate (w, timestamp); diff --git a/src/core/place.c b/src/core/place.c index 8894114d6..613f27061 100644 --- a/src/core/place.c +++ b/src/core/place.c @@ -610,7 +610,7 @@ meta_window_place (MetaWindow *window, meta_topic (META_DEBUG_PLACEMENT, "Placing window %s\n", window->desc); windows = NULL; - + switch (window->type) { /* Run placement algorithm on these. */ @@ -638,7 +638,7 @@ meta_window_place (MetaWindow *window, case META_WINDOW_OVERRIDE_OTHER: goto done_no_constraints; } - + if (meta_prefs_get_disable_workarounds ()) { switch (window->type) @@ -699,18 +699,11 @@ meta_window_place (MetaWindow *window, goto done_no_constraints; } } - - if ((window->type == META_WINDOW_DIALOG || - window->type == META_WINDOW_MODAL_DIALOG) && - window->xtransient_for != None) - { - /* Center horizontally, at top of parent vertically */ - MetaWindow *parent; - - parent = - meta_display_lookup_x_window (window->display, - window->xtransient_for); + if (window->type == META_WINDOW_DIALOG || + window->type == META_WINDOW_MODAL_DIALOG) + { + MetaWindow *parent = meta_window_get_transient_for (window); if (parent) { diff --git a/src/core/stack.c b/src/core/stack.c index 4a3481120..c9223ccd4 100644 --- a/src/core/stack.c +++ b/src/core/stack.c @@ -1746,8 +1746,7 @@ get_default_focus_window (MetaStack *stack, if (not_this_one != NULL) { if (transient_parent == NULL && - not_this_one->xtransient_for != None && - not_this_one->xtransient_for == window->xwindow) + meta_window_get_transient_for (not_this_one) == window) transient_parent = window; if (topmost_in_group == NULL && From cb549154aa1ddff177014899e77c5211933fc5fc Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 10:36:00 -0400 Subject: [PATCH 665/889] window: Move meta_window_configure_notify to window-x11 --- src/core/display.c | 2 +- src/core/window-private.h | 2 ++ src/core/window-x11.c | 34 ++++++++++++++++++++++++++++++++++ src/core/window-x11.h | 3 +++ src/core/window.c | 38 +------------------------------------- src/meta/window.h | 1 - 6 files changed, 41 insertions(+), 39 deletions(-) diff --git a/src/core/display.c b/src/core/display.c index 576bf3813..08df05102 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -2676,7 +2676,7 @@ handle_other_xevent (MetaDisplay *display, } if (window && window->override_redirect) - meta_window_configure_notify (window, &event->xconfigure); + meta_window_x11_configure_notify (window, &event->xconfigure); break; case ConfigureRequest: diff --git a/src/core/window-private.h b/src/core/window-private.h index 1f2166454..2beb8cd0f 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -746,4 +746,6 @@ void meta_window_activate_full (MetaWindow *window, gboolean meta_window_is_client_decorated (MetaWindow *window); +void meta_window_update_monitor (MetaWindow *window); + #endif diff --git a/src/core/window-x11.c b/src/core/window-x11.c index a27a16a1f..5787cb685 100644 --- a/src/core/window-x11.c +++ b/src/core/window-x11.c @@ -1617,3 +1617,37 @@ meta_window_x11_recalc_window_type (MetaWindow *window) type, window->desc, type); meta_window_set_type (window, type); } + +/** + * meta_window_x11_configure_notify: (skip) + * @window: a #MetaWindow + * @event: a #XConfigureEvent + * + * This is used to notify us of an unrequested configuration + * (only applicable to override redirect windows) + */ +void +meta_window_x11_configure_notify (MetaWindow *window, + XConfigureEvent *event) +{ + g_assert (window->override_redirect); + g_assert (window->frame == NULL); + + window->rect.x = event->x; + window->rect.y = event->y; + window->rect.width = event->width; + window->rect.height = event->height; + meta_window_update_monitor (window); + + /* Whether an override-redirect window is considered fullscreen depends + * on its geometry. + */ + if (window->override_redirect) + meta_screen_queue_check_fullscreen (window->screen); + + if (!event->override_redirect && !event->send_event) + meta_warning ("Unhandled change of windows override redirect status\n"); + + if (window->display->compositor) + meta_compositor_sync_window_geometry (window->display->compositor, window, FALSE); +} diff --git a/src/core/window-x11.h b/src/core/window-x11.h index d8f2ce2db..81debec6c 100644 --- a/src/core/window-x11.h +++ b/src/core/window-x11.h @@ -44,4 +44,7 @@ gboolean meta_window_x11_property_notify (MetaWindow *window, gboolean meta_window_x11_client_message (MetaWindow *window, XEvent *event); +void meta_window_x11_configure_notify (MetaWindow *window, + XConfigureEvent *event); + #endif diff --git a/src/core/window.c b/src/core/window.c index a9d6e1221..729872f61 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -132,8 +132,6 @@ static void meta_window_move_between_rects (MetaWindow *window, static void unmaximize_window_before_freeing (MetaWindow *window); static void unminimize_window_and_all_transient_parents (MetaWindow *window); -static void meta_window_update_monitor (MetaWindow *window); - /* Idle handlers for the three queues (run with meta_later_add()). The * "data" parameter in each case will be a GINT_TO_POINTER of the * index into the queue arrays to use. @@ -4399,7 +4397,7 @@ meta_window_update_for_monitors_changed (MetaWindow *window) &new->rect); } -static void +void meta_window_update_monitor (MetaWindow *window) { const MetaMonitorInfo *old; @@ -5325,40 +5323,6 @@ idle_move_resize (gpointer data) return FALSE; } -/** - * meta_window_configure_notify: (skip) - * @window: a #MetaWindow - * @event: a #XConfigureEvent - * - * This is used to notify us of an unrequested configuration - * (only applicable to override redirect windows) - */ -void -meta_window_configure_notify (MetaWindow *window, - XConfigureEvent *event) -{ - g_assert (window->override_redirect); - g_assert (window->frame == NULL); - - window->rect.x = event->x; - window->rect.y = event->y; - window->rect.width = event->width; - window->rect.height = event->height; - meta_window_update_monitor (window); - - /* Whether an override-redirect window is considered fullscreen depends - * on its geometry. - */ - if (window->override_redirect) - meta_screen_queue_check_fullscreen (window->screen); - - if (!event->override_redirect && !event->send_event) - meta_warning ("Unhandled change of windows override redirect status\n"); - - if (window->display->compositor) - meta_compositor_sync_window_geometry (window->display->compositor, window, FALSE); -} - void meta_window_get_position (MetaWindow *window, int *x, diff --git a/src/meta/window.h b/src/meta/window.h index 378b5d82f..09c82f9c1 100644 --- a/src/meta/window.h +++ b/src/meta/window.h @@ -165,7 +165,6 @@ void meta_window_change_workspace (MetaWindow *window, MetaWorkspace *workspace); GObject *meta_window_get_compositor_private (MetaWindow *window); void meta_window_set_compositor_private (MetaWindow *window, GObject *priv); -void meta_window_configure_notify (MetaWindow *window, XConfigureEvent *event); const char *meta_window_get_role (MetaWindow *window); MetaStackLayer meta_window_get_layer (MetaWindow *window); MetaWindow* meta_window_find_root_ancestor (MetaWindow *window); From f5bd7c5f50e250dc91e5222290a0ed261ac83bb9 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 10:44:37 -0400 Subject: [PATCH 666/889] window: Remove bogus comment These fields haven't been around for quite some time. --- src/core/window-private.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/core/window-private.h b/src/core/window-private.h index 2beb8cd0f..e2eef0bf1 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -431,8 +431,6 @@ struct _MetaWindow * gives the position and size of the client window (i.e. ignoring * the frame). * - * Position valid if user_has_moved, size valid if user_has_resized - * * Position always in root coords, unlike window->rect. */ MetaRectangle user_rect; From fcb2ab41b2e768777836c569477a00f1993e4df0 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 11:22:17 -0400 Subject: [PATCH 667/889] window: Remove another bogus comment It's not referring to anything! --- src/core/window.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/core/window.c b/src/core/window.c index 729872f61..394703e53 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -1325,12 +1325,6 @@ meta_window_wayland_new (MetaDisplay *display, meta_error_trap_pop (display); /* pop the XSync()-reducing trap */ - /* XXX: Maybe this could be called in meta_window_new_shared() but - * before splitting the X11 specific code out it came after the - * meta_error_trap_pop() and we wanted to minimize the risk of - * breaking something. - */ - return window; } From cdfc6f5b5395aed53638dbc9f9cc6fbc7501d080 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 11:21:02 -0400 Subject: [PATCH 668/889] window: Remove vfunc slots for signals These aren't used currently, and we're going to be adding more vfuncs. --- src/core/window-private.h | 5 ----- src/core/window.c | 8 ++++---- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/core/window-private.h b/src/core/window-private.h index e2eef0bf1..19246989b 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -468,11 +468,6 @@ struct _MetaWindow struct _MetaWindowClass { GObjectClass parent_class; - - void (*workspace_changed) (MetaWindow *window, int old_workspace); - void (*focus) (MetaWindow *window); - void (*raised) (MetaWindow *window); - void (*unmanaged) (MetaWindow *window); }; /* These differ from window->has_foo_func in that they consider diff --git a/src/core/window.c b/src/core/window.c index 394703e53..cb625c6a3 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -561,7 +561,7 @@ meta_window_class_init (MetaWindowClass *klass) g_signal_new ("workspace-changed", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (MetaWindowClass, workspace_changed), + 0, NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_INT); @@ -570,7 +570,7 @@ meta_window_class_init (MetaWindowClass *klass) g_signal_new ("focus", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (MetaWindowClass, focus), + 0, NULL, NULL, NULL, G_TYPE_NONE, 0); @@ -578,7 +578,7 @@ meta_window_class_init (MetaWindowClass *klass) g_signal_new ("raised", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (MetaWindowClass, raised), + 0, NULL, NULL, NULL, G_TYPE_NONE, 0); @@ -586,7 +586,7 @@ meta_window_class_init (MetaWindowClass *klass) g_signal_new ("unmanaged", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (MetaWindowClass, unmanaged), + 0, NULL, NULL, NULL, G_TYPE_NONE, 0); From cdb7947dd1e6d7d422a8628a41863531c43e6680 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 10:57:34 -0400 Subject: [PATCH 669/889] window: Remove meta_window_is_modal It relies on EWMH concepts. Wayland simply has a MODAL_DIALOG type. --- src/core/window.c | 17 ----------------- src/meta/window.h | 1 - 2 files changed, 18 deletions(-) diff --git a/src/core/window.c b/src/core/window.c index cb625c6a3..aade427a8 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -9739,23 +9739,6 @@ meta_window_is_remote (MetaWindow *window) return window->is_remote; } -/** - * meta_window_is_modal: - * @window: a #MetaWindow - * - * Queries whether the window is in a modal state as described by the - * _NET_WM_STATE protocol. - * - * Return value: (transfer none): TRUE if the window is in modal state. - */ -gboolean -meta_window_is_modal (MetaWindow *window) -{ - g_return_val_if_fail (META_IS_WINDOW (window), FALSE); - - return window->wm_state_modal; -} - /** * meta_window_get_mutter_hints: * @window: a #MetaWindow diff --git a/src/meta/window.h b/src/meta/window.h index 09c82f9c1..f79088ba1 100644 --- a/src/meta/window.h +++ b/src/meta/window.h @@ -211,7 +211,6 @@ guint32 meta_window_get_user_time (MetaWindow *window); int meta_window_get_pid (MetaWindow *window); const char *meta_window_get_client_machine (MetaWindow *window); gboolean meta_window_is_remote (MetaWindow *window); -gboolean meta_window_is_modal (MetaWindow *window); gboolean meta_window_is_attached_dialog (MetaWindow *window); const char *meta_window_get_mutter_hints (MetaWindow *window); From 7504f16e591f18764c40bfbe14db99fd1a9f3627 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 10:58:26 -0400 Subject: [PATCH 670/889] Replace wm_state_modal usage with META_WINDOW_TYPE_DIALOG --- src/core/place.c | 2 +- src/core/window.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/place.c b/src/core/place.c index 613f27061..6c0efc128 100644 --- a/src/core/place.c +++ b/src/core/place.c @@ -344,7 +344,7 @@ avoid_being_obscured_as_second_modal_dialog (MetaWindow *window, /* denied_focus_and_not_transient is only set when focus_window != NULL */ if (window->denied_focus_and_not_transient && - window->wm_state_modal && /* FIXME: Maybe do this for all transients? */ + window->type == META_WINDOW_MODAL_DIALOG && meta_window_same_application (window, focus_window) && window_overlaps_focus_window (window)) { diff --git a/src/core/window.c b/src/core/window.c index aade427a8..4a20adb97 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -5687,7 +5687,7 @@ get_modal_transient (MetaWindow *window) MetaWindow *transient = tmp->data; if (transient->transient_for == modal_transient && - transient->wm_state_modal) + transient->type == META_WINDOW_MODAL_DIALOG) { modal_transient = transient; tmp = windows; From 5270c469a3d3eb82d4928abe3efa6fbbcccaf4b5 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 10:31:17 -0400 Subject: [PATCH 671/889] window: Remove meta_window_set_gravity as "public" API --- src/core/window-private.h | 3 --- src/core/window.c | 40 +++++++++++++++++++-------------------- 2 files changed, 20 insertions(+), 23 deletions(-) diff --git a/src/core/window-private.h b/src/core/window-private.h index 19246989b..b199612a5 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -624,9 +624,6 @@ void meta_window_show_menu (MetaWindow *window, int button, guint32 timestamp); -void meta_window_set_gravity (MetaWindow *window, - int gravity); - #ifdef HAVE_XSYNC void meta_window_update_sync_request_counter (MetaWindow *window, gint64 new_counter_value); diff --git a/src/core/window.c b/src/core/window.c index 4a20adb97..2a52c8fb3 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -4431,6 +4431,26 @@ meta_window_update_monitor (MetaWindow *window) } } +static void +meta_window_set_gravity (MetaWindow *window, + int gravity) +{ + XSetWindowAttributes attrs; + + meta_verbose ("Setting gravity of %s to %d\n", window->desc, gravity); + + attrs.win_gravity = gravity; + + meta_error_trap_push (window->display); + + XChangeWindowAttributes (window->display->xdisplay, + window->xwindow, + CWWinGravity, + &attrs); + + meta_error_trap_pop (window->display); +} + static void meta_window_move_resize_internal (MetaWindow *window, MetaMoveResizeFlags flags, @@ -8536,26 +8556,6 @@ meta_window_handle_mouse_grab_op_event (MetaWindow *window, } } -void -meta_window_set_gravity (MetaWindow *window, - int gravity) -{ - XSetWindowAttributes attrs; - - meta_verbose ("Setting gravity of %s to %d\n", window->desc, gravity); - - attrs.win_gravity = gravity; - - meta_error_trap_push (window->display); - - XChangeWindowAttributes (window->display->xdisplay, - window->xwindow, - CWWinGravity, - &attrs); - - meta_error_trap_pop (window->display); -} - static void get_work_area_monitor (MetaWindow *window, MetaRectangle *area, From 3de58189c078fd20773d998456b9af8301d8f863 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 13:12:03 -0400 Subject: [PATCH 672/889] window: Remove an unused bit --- src/core/window-private.h | 3 --- src/core/window.c | 2 -- 2 files changed, 5 deletions(-) diff --git a/src/core/window-private.h b/src/core/window-private.h index b199612a5..e8eecd991 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -328,9 +328,6 @@ struct _MetaWindow guint using_net_wm_visible_name : 1; /* tracked so we can clear it */ guint using_net_wm_icon_name : 1; /* vs. plain wm_icon_name */ guint using_net_wm_visible_icon_name : 1; /* tracked so we can clear it */ - - /* icon props have changed */ - guint need_reread_icon : 1; /* if TRUE, window was maximized at start of current grab op */ guint shaken_loose : 1; diff --git a/src/core/window.c b/src/core/window.c index 2a52c8fb3..bbf4c0be8 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -939,8 +939,6 @@ _meta_window_shared_new (MetaDisplay *display, window->using_net_wm_icon_name = FALSE; window->using_net_wm_visible_icon_name = FALSE; - window->need_reread_icon = TRUE; - window->layer = META_LAYER_LAST; /* invalid value */ window->stack_position = -1; window->initial_workspace = 0; /* not used */ From 0cdf3bd38329e7d2109c9df0300dfd171f1c0acd Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 13:03:55 -0400 Subject: [PATCH 673/889] Update .gitignore --- .gitignore | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.gitignore b/.gitignore index ba75840b6..eafa0d7ec 100644 --- a/.gitignore +++ b/.gitignore @@ -101,3 +101,10 @@ doc/reference/meta-undocumented.txt doc/reference/meta-unused.txt doc/reference/meta-docs.sgml doc/reference/meta.types +gtk-doc.m4 +intltool.m4 +libtool.m4 +ltoptions.m4 +ltsugar.m4 +ltversion.m4 +lt~obsolete.m4 From ae8f21a3dc9761074f06f9ad56cfcf226979b3c4 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 13:24:52 -0400 Subject: [PATCH 674/889] wayland-keyboard: Don't use our own tracking to detect autorepeat Clutter already marks all autorepeat key events it as synthetic key events. We can simply ignore these instead of relying on custom key tracking code. --- src/wayland/meta-wayland-keyboard.c | 30 ++++++++++------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/src/wayland/meta-wayland-keyboard.c b/src/wayland/meta-wayland-keyboard.c index c5c3b2a7c..9ddf0a556 100644 --- a/src/wayland/meta-wayland-keyboard.c +++ b/src/wayland/meta-wayland-keyboard.c @@ -365,7 +365,7 @@ set_modifiers (MetaWaylandKeyboard *keyboard, new_state.group); } -static gboolean +static void update_pressed_keys (MetaWaylandKeyboard *keyboard, uint32_t evdev_code, gboolean is_press) @@ -376,13 +376,10 @@ update_pressed_keys (MetaWaylandKeyboard *keyboard, keyboard->keys.size); uint32_t *k; - /* We want to ignore events that are sent because of auto-repeat. In - the Clutter event stream these appear as a single key press - event. We can detect that because the key will already have been - pressed */ + /* Make sure we don't already have this key. */ for (k = keyboard->keys.data; k < end; k++) if (*k == evdev_code) - return TRUE; + return; /* Otherwise add the key to the list of pressed keys */ k = wl_array_add (&keyboard->keys, sizeof (*k)); @@ -400,18 +397,11 @@ update_pressed_keys (MetaWaylandKeyboard *keyboard, { *k = *(end - 1); keyboard->keys.size -= sizeof (*k); - - goto found; + return; } g_warning ("unexpected key release event for key 0x%x", evdev_code); - return FALSE; - - found: - (void) 0; } - - return FALSE; } gboolean @@ -421,7 +411,6 @@ meta_wayland_keyboard_handle_event (MetaWaylandKeyboard *keyboard, gboolean is_press = event->type == CLUTTER_KEY_PRESS; guint xkb_keycode, evdev_code; uint32_t serial; - gboolean autorepeat; gboolean handled; xkb_keycode = event->hardware_keycode; @@ -430,15 +419,16 @@ meta_wayland_keyboard_handle_event (MetaWaylandKeyboard *keyboard, xkb_keycode, &evdev_code)) evdev_code = xkb_keycode - 8; /* What everyone is doing in practice... */ - autorepeat = update_pressed_keys (keyboard, evdev_code, is_press); + /* Synthetic key events are for autorepeat. Ignore those, as + * autorepeat in Wayland is done on the client side. */ + if (event->flags & CLUTTER_EVENT_FLAG_SYNTHETIC) + return FALSE; - meta_verbose ("Handling key %s%s event code %d\n", + meta_verbose ("Handling key %s event code %d\n", is_press ? "press" : "release", - autorepeat ? " (autorepeat)" : "", xkb_keycode); - if (autorepeat) - return FALSE; + update_pressed_keys (keyboard, evdev_code, is_press); serial = wl_display_next_serial (keyboard->display); From 5cc6becb632fe963662e3cbff17c40a52bb6872a Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Thu, 6 Mar 2014 14:41:45 +0100 Subject: [PATCH 675/889] wayland-keyboard: Make sure we send an updated modifiers event Any given clutter event carries the modifier state as it was before it occured but, for the wayland modifiers event, we want the state including the current event. To fix this, we'll keep our xkb_state instance around instead of the serialized mods. https://bugzilla.gnome.org/show_bug.cgi?id=722847 --- src/wayland/meta-wayland-keyboard.c | 64 +++++++++++------------------ src/wayland/meta-wayland-keyboard.h | 11 +---- 2 files changed, 26 insertions(+), 49 deletions(-) diff --git a/src/wayland/meta-wayland-keyboard.c b/src/wayland/meta-wayland-keyboard.c index 9ddf0a556..19f208b40 100644 --- a/src/wayland/meta-wayland-keyboard.c +++ b/src/wayland/meta-wayland-keyboard.c @@ -138,10 +138,12 @@ meta_wayland_keyboard_take_keymap (MetaWaylandKeyboard *keyboard, return; } - if (xkb_info->keymap) - xkb_keymap_unref (xkb_info->keymap); + xkb_keymap_unref (xkb_info->keymap); xkb_info->keymap = keymap; + xkb_state_unref (xkb_info->state); + xkb_info->state = xkb_state_new (keymap); + keymap_str = xkb_map_get_as_string (xkb_info->keymap); if (keymap_str == NULL) { @@ -316,8 +318,8 @@ meta_wayland_keyboard_init (MetaWaylandKeyboard *keyboard, static void meta_wayland_xkb_info_destroy (MetaWaylandXkbInfo *xkb_info) { - if (xkb_info->keymap) - xkb_map_unref (xkb_info->keymap); + xkb_keymap_unref (xkb_info->keymap); + xkb_state_unref (xkb_info->state); if (xkb_info->keymap_area) munmap (xkb_info->keymap_area, xkb_info->keymap_size); @@ -325,44 +327,27 @@ meta_wayland_xkb_info_destroy (MetaWaylandXkbInfo *xkb_info) close (xkb_info->keymap_fd); } -static gboolean -state_equal (MetaWaylandXkbState *one, - MetaWaylandXkbState *two) -{ - return one->mods_depressed == two->mods_depressed && - one->mods_latched == two->mods_latched && - one->mods_locked == two->mods_locked && - one->group == two->group; -} - static void -set_modifiers (MetaWaylandKeyboard *keyboard, - guint32 serial, - ClutterEvent *event) +set_modifiers (MetaWaylandKeyboard *keyboard, + guint32 serial, + const ClutterKeyEvent *event) { MetaWaylandKeyboardGrab *grab = keyboard->grab; - MetaWaylandXkbState new_state; - guint effective_state; + struct xkb_state *state = keyboard->xkb_info.state; + enum xkb_state_component changed_state; - clutter_event_get_state_full (event, - NULL, - &new_state.mods_depressed, - &new_state.mods_latched, - &new_state.mods_locked, - &effective_state); - new_state.group = (effective_state >> 13) & 0x3; - - if (state_equal (&keyboard->modifier_state, &new_state)) + changed_state = xkb_state_update_key (state, + event->hardware_keycode, + event->type == CLUTTER_KEY_PRESS ? XKB_KEY_DOWN : XKB_KEY_UP); + if (changed_state == 0) return; - keyboard->modifier_state = new_state; - grab->interface->modifiers (grab, serial, - new_state.mods_depressed, - new_state.mods_latched, - new_state.mods_locked, - new_state.group); + xkb_state_serialize_mods (state, XKB_STATE_MODS_DEPRESSED), + xkb_state_serialize_mods (state, XKB_STATE_MODS_LATCHED), + xkb_state_serialize_mods (state, XKB_STATE_MODS_LOCKED), + xkb_state_serialize_layout (state, XKB_STATE_LAYOUT_EFFECTIVE)); } static void @@ -432,7 +417,7 @@ meta_wayland_keyboard_handle_event (MetaWaylandKeyboard *keyboard, serial = wl_display_next_serial (keyboard->display); - set_modifiers (keyboard, serial, (ClutterEvent*)event); + set_modifiers (keyboard, serial, event); handled = keyboard->grab->interface->key (keyboard->grab, event->time, @@ -484,13 +469,14 @@ meta_wayland_keyboard_set_focus (MetaWaylandKeyboard *keyboard, { struct wl_client *client = wl_resource_get_client (keyboard->focus_resource); struct wl_display *display = wl_client_get_display (client); + struct xkb_state *state = keyboard->xkb_info.state; uint32_t serial = wl_display_next_serial (display); wl_keyboard_send_modifiers (keyboard->focus_resource, serial, - keyboard->modifier_state.mods_depressed, - keyboard->modifier_state.mods_latched, - keyboard->modifier_state.mods_locked, - keyboard->modifier_state.group); + xkb_state_serialize_mods (state, XKB_STATE_MODS_DEPRESSED), + xkb_state_serialize_mods (state, XKB_STATE_MODS_LATCHED), + xkb_state_serialize_mods (state, XKB_STATE_MODS_LOCKED), + xkb_state_serialize_layout (state, XKB_STATE_LAYOUT_EFFECTIVE)); wl_keyboard_send_enter (keyboard->focus_resource, serial, keyboard->focus_surface->resource, &keyboard->keys); diff --git a/src/wayland/meta-wayland-keyboard.h b/src/wayland/meta-wayland-keyboard.h index 24b36af3d..468b9ce18 100644 --- a/src/wayland/meta-wayland-keyboard.h +++ b/src/wayland/meta-wayland-keyboard.h @@ -69,19 +69,12 @@ struct _MetaWaylandKeyboardGrab typedef struct { struct xkb_keymap *keymap; + struct xkb_state *state; int keymap_fd; size_t keymap_size; char *keymap_area; } MetaWaylandXkbInfo; -typedef struct -{ - uint32_t mods_depressed; - uint32_t mods_latched; - uint32_t mods_locked; - uint32_t group; -} MetaWaylandXkbState; - struct _MetaWaylandKeyboard { struct wl_list resource_list; @@ -100,8 +93,6 @@ struct _MetaWaylandKeyboard struct wl_array keys; - MetaWaylandXkbState modifier_state; - struct wl_display *display; struct xkb_context *xkb_context; From 3502cfba34bd0089d1c734500fe3d01e06fc91a7 Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Thu, 6 Mar 2014 15:12:25 +0100 Subject: [PATCH 676/889] wayland-keyboard: Split out a function to determine the evdev keycode We will need to use this is in another place on the next commit. https://bugzilla.gnome.org/show_bug.cgi?id=722847 --- src/wayland/meta-wayland-keyboard.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/wayland/meta-wayland-keyboard.c b/src/wayland/meta-wayland-keyboard.c index 19f208b40..7964b3fb8 100644 --- a/src/wayland/meta-wayland-keyboard.c +++ b/src/wayland/meta-wayland-keyboard.c @@ -389,21 +389,22 @@ update_pressed_keys (MetaWaylandKeyboard *keyboard, } } +static guint +evdev_code (const ClutterKeyEvent *event) +{ + /* clutter-xkb-utils.c adds a fixed offset of 8 to go into XKB's + * range, so we do the reverse here. */ + return event->hardware_keycode - 8; +} + gboolean meta_wayland_keyboard_handle_event (MetaWaylandKeyboard *keyboard, const ClutterKeyEvent *event) { gboolean is_press = event->type == CLUTTER_KEY_PRESS; - guint xkb_keycode, evdev_code; uint32_t serial; gboolean handled; - xkb_keycode = event->hardware_keycode; - if (event->device == NULL || - !clutter_input_device_keycode_to_evdev (event->device, - xkb_keycode, &evdev_code)) - evdev_code = xkb_keycode - 8; /* What everyone is doing in practice... */ - /* Synthetic key events are for autorepeat. Ignore those, as * autorepeat in Wayland is done on the client side. */ if (event->flags & CLUTTER_EVENT_FLAG_SYNTHETIC) @@ -411,7 +412,7 @@ meta_wayland_keyboard_handle_event (MetaWaylandKeyboard *keyboard, meta_verbose ("Handling key %s event code %d\n", is_press ? "press" : "release", - xkb_keycode); + event->hardware_keycode); update_pressed_keys (keyboard, evdev_code, is_press); @@ -421,7 +422,7 @@ meta_wayland_keyboard_handle_event (MetaWaylandKeyboard *keyboard, handled = keyboard->grab->interface->key (keyboard->grab, event->time, - evdev_code, + evdev_code (event), is_press); if (handled) From b3364cad3ecb3e4e0967c9177732acebc0b80462 Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Tue, 18 Mar 2014 18:00:48 +0100 Subject: [PATCH 677/889] wayland: Update keyboard state unconditionally In particular we need to know about all key events to keep the xkb state reliable even if the event is then consumed by a global shortcut or grab and never reaches any wayland client. We also need to keep track of all pressed keys at all times so that we can send an updated set or pressed keys to the focused client when a grab ends. https://bugzilla.gnome.org/show_bug.cgi?id=722847 --- src/wayland/meta-wayland-keyboard.c | 55 +++++++++++++---------------- src/wayland/meta-wayland-keyboard.h | 4 +++ src/wayland/meta-wayland-seat.c | 23 +++++++++++- src/wayland/meta-wayland-seat.h | 4 +-- src/wayland/meta-wayland.c | 29 +++++++++------ 5 files changed, 72 insertions(+), 43 deletions(-) diff --git a/src/wayland/meta-wayland-keyboard.c b/src/wayland/meta-wayland-keyboard.c index 7964b3fb8..5aac8fba7 100644 --- a/src/wayland/meta-wayland-keyboard.c +++ b/src/wayland/meta-wayland-keyboard.c @@ -327,29 +327,6 @@ meta_wayland_xkb_info_destroy (MetaWaylandXkbInfo *xkb_info) close (xkb_info->keymap_fd); } -static void -set_modifiers (MetaWaylandKeyboard *keyboard, - guint32 serial, - const ClutterKeyEvent *event) -{ - MetaWaylandKeyboardGrab *grab = keyboard->grab; - struct xkb_state *state = keyboard->xkb_info.state; - enum xkb_state_component changed_state; - - changed_state = xkb_state_update_key (state, - event->hardware_keycode, - event->type == CLUTTER_KEY_PRESS ? XKB_KEY_DOWN : XKB_KEY_UP); - if (changed_state == 0) - return; - - grab->interface->modifiers (grab, - serial, - xkb_state_serialize_mods (state, XKB_STATE_MODS_DEPRESSED), - xkb_state_serialize_mods (state, XKB_STATE_MODS_LATCHED), - xkb_state_serialize_mods (state, XKB_STATE_MODS_LOCKED), - xkb_state_serialize_layout (state, XKB_STATE_LAYOUT_EFFECTIVE)); -} - static void update_pressed_keys (MetaWaylandKeyboard *keyboard, uint32_t evdev_code, @@ -397,12 +374,36 @@ evdev_code (const ClutterKeyEvent *event) return event->hardware_keycode - 8; } +void +meta_wayland_keyboard_update (MetaWaylandKeyboard *keyboard, + const ClutterKeyEvent *event) +{ + MetaWaylandKeyboardGrab *grab = keyboard->grab; + gboolean is_press = event->type == CLUTTER_KEY_PRESS; + struct xkb_state *state = keyboard->xkb_info.state; + enum xkb_state_component changed_state; + + update_pressed_keys (keyboard, evdev_code (event), is_press); + + changed_state = xkb_state_update_key (state, + event->hardware_keycode, + is_press ? XKB_KEY_DOWN : XKB_KEY_UP); + if (changed_state == 0) + return; + + grab->interface->modifiers (grab, + wl_display_next_serial (keyboard->display), + xkb_state_serialize_mods (state, XKB_STATE_MODS_DEPRESSED), + xkb_state_serialize_mods (state, XKB_STATE_MODS_LATCHED), + xkb_state_serialize_mods (state, XKB_STATE_MODS_LOCKED), + xkb_state_serialize_layout (state, XKB_STATE_LAYOUT_EFFECTIVE)); +} + gboolean meta_wayland_keyboard_handle_event (MetaWaylandKeyboard *keyboard, const ClutterKeyEvent *event) { gboolean is_press = event->type == CLUTTER_KEY_PRESS; - uint32_t serial; gboolean handled; /* Synthetic key events are for autorepeat. Ignore those, as @@ -414,12 +415,6 @@ meta_wayland_keyboard_handle_event (MetaWaylandKeyboard *keyboard, is_press ? "press" : "release", event->hardware_keycode); - update_pressed_keys (keyboard, evdev_code, is_press); - - serial = wl_display_next_serial (keyboard->display); - - set_modifiers (keyboard, serial, event); - handled = keyboard->grab->interface->key (keyboard->grab, event->time, evdev_code (event), diff --git a/src/wayland/meta-wayland-keyboard.h b/src/wayland/meta-wayland-keyboard.h index 468b9ce18..13fbf0a0b 100644 --- a/src/wayland/meta-wayland-keyboard.h +++ b/src/wayland/meta-wayland-keyboard.h @@ -136,4 +136,8 @@ meta_wayland_keyboard_end_grab (MetaWaylandKeyboard *keyboard); void meta_wayland_keyboard_release (MetaWaylandKeyboard *keyboard); +void +meta_wayland_keyboard_update (MetaWaylandKeyboard *keyboard, + const ClutterKeyEvent *event); + #endif /* __META_WAYLAND_KEYBOARD_H__ */ diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c index ed2ef55be..85c244b30 100644 --- a/src/wayland/meta-wayland-seat.c +++ b/src/wayland/meta-wayland-seat.c @@ -347,7 +347,7 @@ count_buttons (const ClutterEvent *event) return count; } -void +static void meta_wayland_seat_update_pointer (MetaWaylandSeat *seat, const ClutterEvent *event) { @@ -370,6 +370,27 @@ meta_wayland_seat_update_pointer (MetaWaylandSeat *seat, } } +void +meta_wayland_seat_update (MetaWaylandSeat *seat, + const ClutterEvent *event) +{ + switch (event->type) + { + case CLUTTER_MOTION: + case CLUTTER_BUTTON_PRESS: + case CLUTTER_BUTTON_RELEASE: + case CLUTTER_SCROLL: + meta_wayland_seat_update_pointer (seat, event); + break; + case CLUTTER_KEY_PRESS: + case CLUTTER_KEY_RELEASE: + meta_wayland_keyboard_update (&seat->keyboard, (const ClutterKeyEvent *) event); + break; + default: + break; + } +} + gboolean meta_wayland_seat_handle_event (MetaWaylandSeat *seat, const ClutterEvent *event) diff --git a/src/wayland/meta-wayland-seat.h b/src/wayland/meta-wayland-seat.h index 429319304..a038e2e32 100644 --- a/src/wayland/meta-wayland-seat.h +++ b/src/wayland/meta-wayland-seat.h @@ -71,8 +71,8 @@ MetaWaylandSeat * meta_wayland_seat_new (struct wl_display *display); void -meta_wayland_seat_update_pointer (MetaWaylandSeat *seat, - const ClutterEvent *event); +meta_wayland_seat_update (MetaWaylandSeat *seat, + const ClutterEvent *event); gboolean meta_wayland_seat_handle_event (MetaWaylandSeat *seat, diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index a13a920ae..a01d6f971 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -508,6 +508,15 @@ stage_destroy_cb (void) meta_quit (META_EXIT_SUCCESS); } +/** + * meta_wayland_compositor_update: + * @compositor: the #MetaWaylandCompositor instance + * @event: the #ClutterEvent used to update @seat's state + * + * This is used to update display server state like updating cursor + * position and keeping track of buttons and keys pressed. It must be + * called for all input events coming from the underlying devices. + */ void meta_wayland_compositor_update (MetaWaylandCompositor *compositor, const ClutterEvent *event) @@ -536,18 +545,18 @@ meta_wayland_compositor_update (MetaWaylandCompositor *compositor, meta_idle_monitor_reset_idletime (device_monitor); } - switch (event->type) - { - case CLUTTER_MOTION: - case CLUTTER_BUTTON_PRESS: - case CLUTTER_BUTTON_RELEASE: - case CLUTTER_SCROLL: - meta_wayland_seat_update_pointer (compositor->seat, event); - default: - break; - } + meta_wayland_seat_update (compositor->seat, event); } +/** + * meta_wayland_compositor_handle_event: + * @compositor: the #MetaWaylandCompositor instance + * @event: the #ClutterEvent to be sent + * + * This method sends events to the focused wayland client, if any. + * + * Return value: whether @event was sent to a wayland client. + */ gboolean meta_wayland_compositor_handle_event (MetaWaylandCompositor *compositor, const ClutterEvent *event) From 63b158e4da8223ccd110ad85ea5c99ae31012249 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 11:10:22 -0400 Subject: [PATCH 678/889] window: Split out recalc of skip_taskbar / skip_pager This will be our first attempt for the MetaWindowX11Private --- src/core/window.c | 83 +++++++++++++++++++++++------------------------ 1 file changed, 41 insertions(+), 42 deletions(-) diff --git a/src/core/window.c b/src/core/window.c index bbf4c0be8..bffb70631 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -7160,6 +7160,46 @@ set_allowed_actions_hint (MetaWindow *window) #undef MAX_N_ACTIONS } +static void +meta_window_recalc_skip_features (MetaWindow *window) +{ + switch (window->type) + { + /* Force skip taskbar/pager on these window types */ + case META_WINDOW_DESKTOP: + case META_WINDOW_DOCK: + case META_WINDOW_TOOLBAR: + case META_WINDOW_MENU: + case META_WINDOW_UTILITY: + case META_WINDOW_SPLASHSCREEN: + case META_WINDOW_DROPDOWN_MENU: + case META_WINDOW_POPUP_MENU: + case META_WINDOW_TOOLTIP: + case META_WINDOW_NOTIFICATION: + case META_WINDOW_COMBO: + case META_WINDOW_DND: + case META_WINDOW_OVERRIDE_OTHER: + window->skip_taskbar = TRUE; + window->skip_pager = TRUE; + break; + + case META_WINDOW_DIALOG: + case META_WINDOW_MODAL_DIALOG: + /* only skip taskbar if we have a real transient parent + (and ignore the application hints) */ + if (window->transient_for != NULL) + window->skip_taskbar = TRUE; + else + window->skip_taskbar = FALSE; + break; + + case META_WINDOW_NORMAL: + window->skip_taskbar = window->wm_state_skip_taskbar; + window->skip_pager = window->wm_state_skip_pager; + break; + } +} + void meta_window_recalc_features (MetaWindow *window) { @@ -7311,48 +7351,7 @@ meta_window_recalc_features (MetaWindow *window) if (!window->decorated || window->border_only) window->has_shade_func = FALSE; - window->skip_taskbar = FALSE; - window->skip_pager = FALSE; - - if (window->wm_state_skip_taskbar) - window->skip_taskbar = TRUE; - - if (window->wm_state_skip_pager) - window->skip_pager = TRUE; - - switch (window->type) - { - /* Force skip taskbar/pager on these window types */ - case META_WINDOW_DESKTOP: - case META_WINDOW_DOCK: - case META_WINDOW_TOOLBAR: - case META_WINDOW_MENU: - case META_WINDOW_UTILITY: - case META_WINDOW_SPLASHSCREEN: - case META_WINDOW_DROPDOWN_MENU: - case META_WINDOW_POPUP_MENU: - case META_WINDOW_TOOLTIP: - case META_WINDOW_NOTIFICATION: - case META_WINDOW_COMBO: - case META_WINDOW_DND: - case META_WINDOW_OVERRIDE_OTHER: - window->skip_taskbar = TRUE; - window->skip_pager = TRUE; - break; - - case META_WINDOW_DIALOG: - case META_WINDOW_MODAL_DIALOG: - /* only skip taskbar if we have a real transient parent - (and ignore the application hints) */ - if (window->transient_for != NULL) - window->skip_taskbar = TRUE; - else - window->skip_taskbar = FALSE; - break; - - case META_WINDOW_NORMAL: - break; - } + meta_window_recalc_skip_features (window); meta_topic (META_DEBUG_WINDOW_OPS, "Window %s decorated = %d border_only = %d has_close = %d has_minimize = %d has_maximize = %d has_move = %d has_shade = %d skip_taskbar = %d skip_pager = %d\n", From 6f7023bc6b2a65c30fb4ca5b664ce73f0e2aab9d Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 11:20:22 -0400 Subject: [PATCH 679/889] Start splitting the X11-specific stuff of MetaWindow out into a subclass This is fairly simple and basic for now, with just skip_taskbar / skip_pager, but eventually a lot of "WM policy" like this, including move-resize, will be in subclasses for each individual surface. --- src/Makefile.am | 1 + src/core/window-private.h | 8 +++--- src/core/window-props.c | 12 ++++++--- src/core/window-x11-private.h | 48 +++++++++++++++++++++++++++++++++++ src/core/window-x11.c | 40 +++++++++++++++++++++++++++-- src/core/window-x11.h | 14 ++++++++++ src/core/window.c | 34 +++++++++++++++++++++---- 7 files changed, 142 insertions(+), 15 deletions(-) create mode 100644 src/core/window-x11-private.h diff --git a/src/Makefile.am b/src/Makefile.am index 8df85fbd7..25044e382 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -165,6 +165,7 @@ libmutter_wayland_la_SOURCES = \ core/window-props.h \ core/window-x11.c \ core/window-x11.h \ + core/window-x11-private.h \ core/window.c \ core/window-private.h \ meta/window.h \ diff --git a/src/core/window-private.h b/src/core/window-private.h index e8eecd991..4ef970779 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -266,10 +266,6 @@ struct _MetaWindow /* Weird "_NET_WM_STATE_MODAL" flag */ guint wm_state_modal : 1; - /* TRUE if the client forced these on */ - guint wm_state_skip_taskbar : 1; - guint wm_state_skip_pager : 1; - /* Computed whether to skip taskbar or not */ guint skip_taskbar : 1; guint skip_pager : 1; @@ -465,6 +461,10 @@ struct _MetaWindow struct _MetaWindowClass { GObjectClass parent_class; + + void (*get_default_skip_hints) (MetaWindow *window, + gboolean *skip_taskbar_out, + gboolean *skip_pager_out); }; /* These differ from window->has_foo_func in that they consider diff --git a/src/core/window-props.c b/src/core/window-props.c index dc6f9ba70..35f056920 100644 --- a/src/core/window-props.c +++ b/src/core/window-props.c @@ -40,6 +40,7 @@ #include #include "window-props.h" #include "window-x11.h" +#include "window-x11-private.h" #include #include "xprops.h" #include "frame.h" @@ -666,6 +667,9 @@ reload_net_wm_state (MetaWindow *window, MetaPropValue *value, gboolean initial) { + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = window_x11->priv; + int i; /* We know this is only an initial window creation, @@ -684,8 +688,8 @@ reload_net_wm_state (MetaWindow *window, window->maximized_vertically = FALSE; window->fullscreen = FALSE; window->wm_state_modal = FALSE; - window->wm_state_skip_taskbar = FALSE; - window->wm_state_skip_pager = FALSE; + priv->wm_state_skip_taskbar = FALSE; + priv->wm_state_skip_pager = FALSE; window->wm_state_above = FALSE; window->wm_state_below = FALSE; window->wm_state_demands_attention = FALSE; @@ -707,9 +711,9 @@ reload_net_wm_state (MetaWindow *window, else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_MODAL) window->wm_state_modal = TRUE; else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_SKIP_TASKBAR) - window->wm_state_skip_taskbar = TRUE; + priv->wm_state_skip_taskbar = TRUE; else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_SKIP_PAGER) - window->wm_state_skip_pager = TRUE; + 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; else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_ABOVE) diff --git a/src/core/window-x11-private.h b/src/core/window-x11-private.h new file mode 100644 index 000000000..25114daad --- /dev/null +++ b/src/core/window-x11-private.h @@ -0,0 +1,48 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2001 Havoc Pennington, Anders Carlsson + * Copyright (C) 2002, 2003 Red Hat, Inc. + * Copyright (C) 2003 Rob Adams + * Copyright (C) 2004-2006 Elijah Newren + * + * 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 "window-private.h" + +#ifndef META_WINDOW_X11_PRIVATE_H +#define META_WINDOW_X11_PRIVATE_H + +G_BEGIN_DECLS + +typedef struct _MetaWindowX11Private MetaWindowX11Private; + +struct _MetaWindowX11 +{ + MetaWindow parent; + + MetaWindowX11Private *priv; +}; + +struct _MetaWindowX11Private +{ + /* TRUE if the client forced these on */ + guint wm_state_skip_taskbar : 1; + guint wm_state_skip_pager : 1; +}; + +G_END_DECLS + +#endif diff --git a/src/core/window-x11.c b/src/core/window-x11.c index 5787cb685..cade6561c 100644 --- a/src/core/window-x11.c +++ b/src/core/window-x11.c @@ -23,6 +23,7 @@ #include "config.h" #include "window-x11.h" +#include "window-x11-private.h" #include #include @@ -44,6 +45,39 @@ #include "window-props.h" #include "xprops.h" +struct _MetaWindowX11Class +{ + MetaWindowClass parent_class; +}; + +G_DEFINE_TYPE_WITH_PRIVATE (MetaWindowX11, meta_window_x11, META_TYPE_WINDOW) + +static void +meta_window_x11_init (MetaWindowX11 *window_x11) +{ + window_x11->priv = meta_window_x11_get_instance_private (window_x11); +} + +static void +meta_window_x11_get_default_skip_hints (MetaWindow *window, + gboolean *skip_taskbar_out, + gboolean *skip_pager_out) +{ + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11); + + *skip_taskbar_out = priv->wm_state_skip_taskbar; + *skip_pager_out = priv->wm_state_skip_pager; +} + +static void +meta_window_x11_class_init (MetaWindowX11Class *klass) +{ + MetaWindowClass *window_class = META_WINDOW_CLASS (klass); + + window_class->get_default_skip_hints = meta_window_x11_get_default_skip_hints; +} + void meta_window_x11_set_net_wm_state (MetaWindow *window) { @@ -694,6 +728,8 @@ gboolean meta_window_x11_client_message (MetaWindow *window, XEvent *event) { + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11); MetaDisplay *display; display = window->display; @@ -879,7 +915,7 @@ meta_window_x11_client_message (MetaWindow *window, if (first == display->atom__NET_WM_STATE_SKIP_PAGER || second == display->atom__NET_WM_STATE_SKIP_PAGER) { - window->wm_state_skip_pager = + priv->wm_state_skip_pager = (action == _NET_WM_STATE_ADD) || (action == _NET_WM_STATE_TOGGLE && !window->skip_pager); @@ -890,7 +926,7 @@ meta_window_x11_client_message (MetaWindow *window, if (first == display->atom__NET_WM_STATE_SKIP_TASKBAR || second == display->atom__NET_WM_STATE_SKIP_TASKBAR) { - window->wm_state_skip_taskbar = + priv->wm_state_skip_taskbar = (action == _NET_WM_STATE_ADD) || (action == _NET_WM_STATE_TOGGLE && !window->skip_taskbar); diff --git a/src/core/window-x11.h b/src/core/window-x11.h index 81debec6c..29d95b0f5 100644 --- a/src/core/window-x11.h +++ b/src/core/window-x11.h @@ -26,6 +26,20 @@ #include #include +G_BEGIN_DECLS + +#define META_TYPE_WINDOW_X11 (meta_window_x11_get_type()) +#define META_WINDOW_X11(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_WINDOW_X11, MetaWindowX11)) +#define META_WINDOW_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_WINDOW_X11, MetaWindowX11Class)) +#define META_IS_WINDOW_X11(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_WINDOW_X11)) +#define META_IS_WINDOW_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_WINDOW_X11)) +#define META_WINDOW_X11_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_WINDOW_X11, MetaWindowX11Class)) + +GType meta_window_x11_get_type (void); + +typedef struct _MetaWindowX11 MetaWindowX11; +typedef struct _MetaWindowX11Class MetaWindowX11Class; + void meta_window_x11_set_net_wm_state (MetaWindow *window); void meta_window_x11_set_wm_state (MetaWindow *window); diff --git a/src/core/window.c b/src/core/window.c index bffb70631..8b452b42f 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -208,6 +208,15 @@ prefs_changed_callback (MetaPreference pref, } } +static void +meta_window_real_get_default_skip_hints (MetaWindow *window, + gboolean *skip_taskbar_out, + gboolean *skip_pager_out) +{ + *skip_taskbar_out = FALSE; + *skip_pager_out = FALSE; +} + static void meta_window_finalize (GObject *object) { @@ -365,6 +374,8 @@ meta_window_class_init (MetaWindowClass *klass) object_class->get_property = meta_window_get_property; object_class->set_property = meta_window_set_property; + klass->get_default_skip_hints = meta_window_real_get_default_skip_hints; + g_object_class_install_property (object_class, PROP_TITLE, g_param_spec_string ("title", @@ -757,7 +768,10 @@ _meta_window_shared_new (MetaDisplay *display, "IsUnviewable" : "(unknown)"); - window = g_object_new (META_TYPE_WINDOW, NULL); + if (client_type == META_WINDOW_CLIENT_TYPE_X11) + window = g_object_new (META_TYPE_WINDOW_X11, NULL); + else + window = g_object_new (META_TYPE_WINDOW, NULL); window->constructing = TRUE; @@ -909,8 +923,6 @@ _meta_window_shared_new (MetaDisplay *display, window->wm_state_modal = FALSE; window->skip_taskbar = FALSE; window->skip_pager = FALSE; - window->wm_state_skip_taskbar = FALSE; - window->wm_state_skip_pager = FALSE; window->wm_state_above = FALSE; window->wm_state_below = FALSE; window->wm_state_demands_attention = FALSE; @@ -7160,6 +7172,14 @@ set_allowed_actions_hint (MetaWindow *window) #undef MAX_N_ACTIONS } +static void +meta_window_get_default_skip_hints (MetaWindow *window, + gboolean *skip_taskbar_out, + gboolean *skip_pager_out) +{ + META_WINDOW_GET_CLASS (window)->get_default_skip_hints (window, skip_taskbar_out, skip_pager_out); +} + static void meta_window_recalc_skip_features (MetaWindow *window) { @@ -7194,8 +7214,12 @@ meta_window_recalc_skip_features (MetaWindow *window) break; case META_WINDOW_NORMAL: - window->skip_taskbar = window->wm_state_skip_taskbar; - window->skip_pager = window->wm_state_skip_pager; + { + gboolean skip_taskbar_hint, skip_pager_hint; + meta_window_get_default_skip_hints (window, &skip_taskbar_hint, &skip_pager_hint); + window->skip_taskbar = skip_taskbar_hint; + window->skip_pager = skip_pager_hint; + } break; } } From 8f151842fbc1adc76d9a6741ed2538139316419e Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 12:57:08 -0400 Subject: [PATCH 680/889] Start moving X11 implementation to its own subdirectory This is specifically about managing X11 windows, not necessarily running as an X11 compositor. By that I mean that this code is still used for XWayland windows, and event handling is still and modesetting / monitor management is still in core/. This is also a fairly conservative move. We don't move anything like screen.c or bell.c in here, even though those are really only for X11 clients. --- src/Makefile.am | 35 +++++++++++++------------- src/{core => x11}/async-getprop.c | 0 src/{core => x11}/async-getprop.h | 0 src/{core => x11}/group-private.h | 0 src/{core => x11}/group-props.c | 0 src/{core => x11}/group-props.h | 0 src/{core => x11}/group.c | 0 src/{core => x11}/iconcache.c | 0 src/{core => x11}/iconcache.h | 0 src/{core => x11}/window-props.c | 0 src/{core => x11}/window-props.h | 0 src/{core => x11}/window-x11-private.h | 0 src/{core => x11}/window-x11.c | 0 src/{core => x11}/window-x11.h | 0 src/{core => x11}/xprops.c | 0 src/{core => x11}/xprops.h | 0 16 files changed, 18 insertions(+), 17 deletions(-) rename src/{core => x11}/async-getprop.c (100%) rename src/{core => x11}/async-getprop.h (100%) rename src/{core => x11}/group-private.h (100%) rename src/{core => x11}/group-props.c (100%) rename src/{core => x11}/group-props.h (100%) rename src/{core => x11}/group.c (100%) rename src/{core => x11}/iconcache.c (100%) rename src/{core => x11}/iconcache.h (100%) rename src/{core => x11}/window-props.c (100%) rename src/{core => x11}/window-props.h (100%) rename src/{core => x11}/window-x11-private.h (100%) rename src/{core => x11}/window-x11.c (100%) rename src/{core => x11}/window-x11.h (100%) rename src/{core => x11}/xprops.c (100%) rename src/{core => x11}/xprops.h (100%) diff --git a/src/Makefile.am b/src/Makefile.am index 25044e382..a94f49e61 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -16,6 +16,7 @@ INCLUDES= \ -I$(srcdir)/core \ -I$(srcdir)/ui \ -I$(srcdir)/compositor \ + -I$(srcdir)/x11 \ -DMUTTER_LIBEXECDIR=\"$(libexecdir)\" \ -DHOST_ALIAS=\"@HOST_ALIAS@\" \ -DMUTTER_LOCALEDIR=\"$(prefix)/@DATADIRNAME@/locale\" \ @@ -49,8 +50,7 @@ mutter_built_sources = \ wayland/xserver-server-protocol.h libmutter_wayland_la_SOURCES = \ - core/async-getprop.c \ - core/async-getprop.h \ + core/above-tab-keycode.c \ core/barrier.c \ meta/barrier.h \ core/bell.c \ @@ -105,7 +105,6 @@ libmutter_wayland_la_SOURCES = \ meta/meta-shadow-factory.h \ meta/meta-window-actor.h \ meta/compositor-mutter.h \ - core/above-tab-keycode.c \ core/constraints.c \ core/constraints.h \ core/core.c \ @@ -123,13 +122,6 @@ libmutter_wayland_la_SOURCES = \ core/frame.h \ ui/gradient.c \ meta/gradient.h \ - core/group-private.h \ - core/group-props.c \ - core/group-props.h \ - core/group.c \ - meta/group.h \ - core/iconcache.c \ - core/iconcache.h \ core/keybindings.c \ core/keybindings-private.h \ core/main.c \ @@ -161,18 +153,11 @@ libmutter_wayland_la_SOURCES = \ core/util.c \ meta/util.h \ core/util-private.h \ - core/window-props.c \ - core/window-props.h \ - core/window-x11.c \ - core/window-x11.h \ - core/window-x11-private.h \ core/window.c \ core/window-private.h \ meta/window.h \ core/workspace.c \ core/workspace-private.h \ - core/xprops.c \ - core/xprops.h \ meta/common.h \ core/core.h \ ui/ui.h \ @@ -189,6 +174,22 @@ libmutter_wayland_la_SOURCES = \ meta/theme.h \ ui/theme-private.h \ ui/ui.c \ + x11/iconcache.c \ + x11/iconcache.h \ + x11/async-getprop.c \ + x11/async-getprop.h \ + x11/group-private.h \ + x11/group-props.c \ + x11/group-props.h \ + x11/group.c \ + meta/group.h \ + x11/window-props.c \ + x11/window-props.h \ + x11/window-x11.c \ + x11/window-x11.h \ + x11/window-x11-private.h \ + x11/xprops.c \ + x11/xprops.h \ wayland/meta-wayland.c \ wayland/meta-wayland.h \ wayland/meta-wayland-private.h \ diff --git a/src/core/async-getprop.c b/src/x11/async-getprop.c similarity index 100% rename from src/core/async-getprop.c rename to src/x11/async-getprop.c diff --git a/src/core/async-getprop.h b/src/x11/async-getprop.h similarity index 100% rename from src/core/async-getprop.h rename to src/x11/async-getprop.h diff --git a/src/core/group-private.h b/src/x11/group-private.h similarity index 100% rename from src/core/group-private.h rename to src/x11/group-private.h diff --git a/src/core/group-props.c b/src/x11/group-props.c similarity index 100% rename from src/core/group-props.c rename to src/x11/group-props.c diff --git a/src/core/group-props.h b/src/x11/group-props.h similarity index 100% rename from src/core/group-props.h rename to src/x11/group-props.h diff --git a/src/core/group.c b/src/x11/group.c similarity index 100% rename from src/core/group.c rename to src/x11/group.c diff --git a/src/core/iconcache.c b/src/x11/iconcache.c similarity index 100% rename from src/core/iconcache.c rename to src/x11/iconcache.c diff --git a/src/core/iconcache.h b/src/x11/iconcache.h similarity index 100% rename from src/core/iconcache.h rename to src/x11/iconcache.h diff --git a/src/core/window-props.c b/src/x11/window-props.c similarity index 100% rename from src/core/window-props.c rename to src/x11/window-props.c diff --git a/src/core/window-props.h b/src/x11/window-props.h similarity index 100% rename from src/core/window-props.h rename to src/x11/window-props.h diff --git a/src/core/window-x11-private.h b/src/x11/window-x11-private.h similarity index 100% rename from src/core/window-x11-private.h rename to src/x11/window-x11-private.h diff --git a/src/core/window-x11.c b/src/x11/window-x11.c similarity index 100% rename from src/core/window-x11.c rename to src/x11/window-x11.c diff --git a/src/core/window-x11.h b/src/x11/window-x11.h similarity index 100% rename from src/core/window-x11.h rename to src/x11/window-x11.h diff --git a/src/core/xprops.c b/src/x11/xprops.c similarity index 100% rename from src/core/xprops.c rename to src/x11/xprops.c diff --git a/src/core/xprops.h b/src/x11/xprops.h similarity index 100% rename from src/core/xprops.h rename to src/x11/xprops.h From d6a27195d312c34987ac95b2f650c2047c04c94d Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 13:07:50 -0400 Subject: [PATCH 681/889] Move more fields to MetaWindowX11 --- src/core/window-private.h | 9 -------- src/core/window.c | 6 ----- src/x11/window-props.c | 44 +++++++++++++++++++++++++----------- src/x11/window-x11-private.h | 9 ++++++++ src/x11/window-x11.c | 13 +++++++---- 5 files changed, 48 insertions(+), 33 deletions(-) diff --git a/src/core/window-private.h b/src/core/window-private.h index 4ef970779..e7c0d4dc2 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -262,9 +262,6 @@ struct _MetaWindow guint has_move_func : 1; guint has_resize_func : 1; guint has_fullscreen_func : 1; - - /* Weird "_NET_WM_STATE_MODAL" flag */ - guint wm_state_modal : 1; /* Computed whether to skip taskbar or not */ guint skip_taskbar : 1; @@ -318,12 +315,6 @@ struct _MetaWindow /* Transient parent is a root window */ guint transient_parent_is_root_window : 1; - - /* Info on which props we got our attributes from */ - guint using_net_wm_name : 1; /* vs. plain wm_name */ - guint using_net_wm_visible_name : 1; /* tracked so we can clear it */ - guint using_net_wm_icon_name : 1; /* vs. plain wm_icon_name */ - guint using_net_wm_visible_icon_name : 1; /* tracked so we can clear it */ /* if TRUE, window was maximized at start of current grab op */ guint shaken_loose : 1; diff --git a/src/core/window.c b/src/core/window.c index 8b452b42f..7f507f1cd 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -920,7 +920,6 @@ _meta_window_shared_new (MetaDisplay *display, window->always_sticky = FALSE; - window->wm_state_modal = FALSE; window->skip_taskbar = FALSE; window->skip_pager = FALSE; window->wm_state_above = FALSE; @@ -946,11 +945,6 @@ _meta_window_shared_new (MetaDisplay *display, window->struts = NULL; - window->using_net_wm_name = FALSE; - window->using_net_wm_visible_name = FALSE; - window->using_net_wm_icon_name = FALSE; - window->using_net_wm_visible_icon_name = FALSE; - window->layer = META_LAYER_LAST; /* invalid value */ window->stack_position = -1; window->initial_workspace = 0; /* not used */ diff --git a/src/x11/window-props.c b/src/x11/window-props.c index 35f056920..3d5476538 100644 --- a/src/x11/window-props.c +++ b/src/x11/window-props.c @@ -489,15 +489,18 @@ static void set_window_title (MetaWindow *window, const char *title) { + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = window_x11->priv; + char *new_title = NULL; - + gboolean modified = set_title_text (window, - window->using_net_wm_visible_name, + priv->using_net_wm_visible_name, title, window->display->atom__NET_WM_VISIBLE_NAME, &new_title); - window->using_net_wm_visible_name = modified; + priv->using_net_wm_visible_name = modified; meta_window_set_title (window, new_title); @@ -509,10 +512,13 @@ reload_net_wm_name (MetaWindow *window, MetaPropValue *value, gboolean initial) { + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = window_x11->priv; + if (value->type != META_PROP_VALUE_INVALID) { set_window_title (window, value->v.str); - window->using_net_wm_name = TRUE; + priv->using_net_wm_name = TRUE; meta_verbose ("Using _NET_WM_NAME for new title of %s: \"%s\"\n", window->desc, window->title); @@ -520,7 +526,7 @@ reload_net_wm_name (MetaWindow *window, else { set_window_title (window, NULL); - window->using_net_wm_name = FALSE; + priv->using_net_wm_name = FALSE; if (!initial) meta_window_reload_property (window, XA_WM_NAME, FALSE); } @@ -531,7 +537,10 @@ reload_wm_name (MetaWindow *window, MetaPropValue *value, gboolean initial) { - if (window->using_net_wm_name) + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = window_x11->priv; + + if (priv->using_net_wm_name) { meta_verbose ("Ignoring WM_NAME \"%s\" as _NET_WM_NAME is set\n", value->v.str); @@ -606,13 +615,16 @@ static void set_icon_title (MetaWindow *window, const char *title) { + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = window_x11->priv; + gboolean modified = set_title_text (window, - window->using_net_wm_visible_icon_name, + priv->using_net_wm_visible_icon_name, title, window->display->atom__NET_WM_VISIBLE_ICON_NAME, &window->icon_name); - window->using_net_wm_visible_icon_name = modified; + priv->using_net_wm_visible_icon_name = modified; } static void @@ -620,10 +632,13 @@ reload_net_wm_icon_name (MetaWindow *window, MetaPropValue *value, gboolean initial) { + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = window_x11->priv; + if (value->type != META_PROP_VALUE_INVALID) { set_icon_title (window, value->v.str); - window->using_net_wm_icon_name = TRUE; + priv->using_net_wm_icon_name = TRUE; meta_verbose ("Using _NET_WM_ICON_NAME for new title of %s: \"%s\"\n", window->desc, window->title); @@ -631,7 +646,7 @@ reload_net_wm_icon_name (MetaWindow *window, else { set_icon_title (window, NULL); - window->using_net_wm_icon_name = FALSE; + priv->using_net_wm_icon_name = FALSE; if (!initial) meta_window_reload_property (window, XA_WM_ICON_NAME, FALSE); } @@ -642,7 +657,10 @@ reload_wm_icon_name (MetaWindow *window, MetaPropValue *value, gboolean initial) { - if (window->using_net_wm_icon_name) + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = window_x11->priv; + + if (priv->using_net_wm_icon_name) { meta_verbose ("Ignoring WM_ICON_NAME \"%s\" as _NET_WM_ICON_NAME is set\n", value->v.str); @@ -687,7 +705,7 @@ reload_net_wm_state (MetaWindow *window, window->maximized_horizontally = FALSE; window->maximized_vertically = FALSE; window->fullscreen = FALSE; - window->wm_state_modal = FALSE; + priv->wm_state_modal = FALSE; priv->wm_state_skip_taskbar = FALSE; priv->wm_state_skip_pager = FALSE; window->wm_state_above = FALSE; @@ -709,7 +727,7 @@ reload_net_wm_state (MetaWindow *window, else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_HIDDEN) window->minimize_after_placement = TRUE; else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_MODAL) - window->wm_state_modal = TRUE; + priv->wm_state_modal = TRUE; else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_SKIP_TASKBAR) priv->wm_state_skip_taskbar = TRUE; else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_SKIP_PAGER) diff --git a/src/x11/window-x11-private.h b/src/x11/window-x11-private.h index 25114daad..d3ceb3ba7 100644 --- a/src/x11/window-x11-private.h +++ b/src/x11/window-x11-private.h @@ -41,6 +41,15 @@ struct _MetaWindowX11Private /* TRUE if the client forced these on */ guint wm_state_skip_taskbar : 1; guint wm_state_skip_pager : 1; + + /* Weird "_NET_WM_STATE_MODAL" flag */ + guint wm_state_modal : 1; + + /* Info on which props we got our attributes from */ + guint using_net_wm_name : 1; /* vs. plain wm_name */ + guint using_net_wm_visible_name : 1; /* tracked so we can clear it */ + guint using_net_wm_icon_name : 1; /* vs. plain wm_icon_name */ + guint using_net_wm_visible_icon_name : 1; /* tracked so we can clear it */ }; G_END_DECLS diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c index cade6561c..c8db060e5 100644 --- a/src/x11/window-x11.c +++ b/src/x11/window-x11.c @@ -81,6 +81,8 @@ meta_window_x11_class_init (MetaWindowX11Class *klass) void meta_window_x11_set_net_wm_state (MetaWindow *window) { + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11); int i; unsigned long data[13]; @@ -90,7 +92,7 @@ meta_window_x11_set_net_wm_state (MetaWindow *window) data[i] = window->display->atom__NET_WM_STATE_SHADED; ++i; } - if (window->wm_state_modal) + if (priv->wm_state_modal) { data[i] = window->display->atom__NET_WM_STATE_MODAL; ++i; @@ -904,9 +906,9 @@ meta_window_x11_client_message (MetaWindow *window, if (first == display->atom__NET_WM_STATE_MODAL || second == display->atom__NET_WM_STATE_MODAL) { - window->wm_state_modal = + priv->wm_state_modal = (action == _NET_WM_STATE_ADD) || - (action == _NET_WM_STATE_TOGGLE && !window->wm_state_modal); + (action == _NET_WM_STATE_TOGGLE && !priv->wm_state_modal); meta_window_x11_recalc_window_type (window); meta_window_queue(window, META_QUEUE_MOVE_RESIZE); @@ -1546,6 +1548,8 @@ error: void meta_window_x11_recalc_window_type (MetaWindow *window) { + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11); MetaWindowType type; if (window->type_atom != None) @@ -1612,8 +1616,7 @@ meta_window_x11_recalc_window_type (MetaWindow *window) type = META_WINDOW_NORMAL; } - if (type == META_WINDOW_DIALOG && - window->wm_state_modal) + if (type == META_WINDOW_DIALOG && priv->wm_state_modal) type = META_WINDOW_MODAL_DIALOG; /* We don't want to allow override-redirect windows to have decorated-window From 6efcf2526dac10b589d9c9edca59dc1dfe8cc0b7 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 13:51:36 -0400 Subject: [PATCH 682/889] window: Move urgency to a setter --- src/core/window-private.h | 3 +++ src/core/window.c | 17 ++++++++++++++--- src/x11/window-props.c | 22 ++++------------------ 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/core/window-private.h b/src/core/window-private.h index e7c0d4dc2..f463360c8 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -726,4 +726,7 @@ gboolean meta_window_is_client_decorated (MetaWindow *window); void meta_window_update_monitor (MetaWindow *window); +void meta_window_set_urgent (MetaWindow *window, + gboolean urgent); + #endif diff --git a/src/core/window.c b/src/core/window.c index 7f507f1cd..496226506 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -1269,9 +1269,6 @@ _meta_window_shared_new (MetaDisplay *display, if (window->wm_state_demands_attention) g_signal_emit_by_name (window->display, "window-demands-attention", window); - if (window->wm_hints_urgent) - g_signal_emit_by_name (window->display, "window-marked-urgent", window); - return window; } @@ -10376,3 +10373,17 @@ meta_window_allows_resize (MetaWindow *window) { return META_WINDOW_ALLOWS_RESIZE (window); } + +void +meta_window_set_urgent (MetaWindow *window, + gboolean urgent) +{ + if (window->wm_hints_urgent == urgent) + return; + + window->wm_hints_urgent = urgent; + g_object_notify_by_pspec (window, props[PROP_URGENT]); + + if (urgent) + g_signal_emit_by_name (window->display, "window-marked-urgent", window); +} diff --git a/src/x11/window-props.c b/src/x11/window-props.c index 3d5476538..b1bd6e1e4 100644 --- a/src/x11/window-props.c +++ b/src/x11/window-props.c @@ -1460,10 +1460,9 @@ reload_wm_hints (MetaWindow *window, gboolean initial) { Window old_group_leader; - gboolean old_urgent; + gboolean urgent; old_group_leader = window->xgroup_leader; - old_urgent = window->wm_hints_urgent; /* Fill in defaults */ window->input = TRUE; @@ -1471,7 +1470,7 @@ reload_wm_hints (MetaWindow *window, window->xgroup_leader = None; window->wm_hints_pixmap = None; window->wm_hints_mask = None; - window->wm_hints_urgent = FALSE; + urgent = FALSE; if (value->type != META_PROP_VALUE_INVALID) { @@ -1493,7 +1492,7 @@ reload_wm_hints (MetaWindow *window, window->wm_hints_mask = hints->icon_mask; if (hints->flags & XUrgencyHint) - window->wm_hints_urgent = TRUE; + urgent = TRUE; meta_verbose ("Read WM_HINTS input: %d iconic: %d group leader: 0x%lx pixmap: 0x%lx mask: 0x%lx\n", window->input, window->initially_iconic, @@ -1510,20 +1509,7 @@ reload_wm_hints (MetaWindow *window, meta_window_group_leader_changed (window); } - /* - * Do not emit urgency notification on the inital property load - */ - if (!initial && (window->wm_hints_urgent != old_urgent)) - g_object_notify (G_OBJECT (window), "urgent"); - - /* - * Do not emit signal for the initial property load, let the constructor to - * take care of it once the MetaWindow is fully constructed. - * - * Only emit if the property is both changed and set. - */ - if (!initial && window->wm_hints_urgent && !old_urgent) - g_signal_emit_by_name (window->display, "window-marked-urgent", window); + meta_window_set_urgent (window, urgent); meta_icon_cache_property_changed (&window->icon_cache, window->display, From a5f17908284f928d05b45fa0c5fc9e6c95643f39 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 13:53:42 -0400 Subject: [PATCH 683/889] window: Rename wm_hints_urgent to urgent The flag and setter is now decoupled from the WM_HINTS state. --- src/core/window-private.h | 4 ++-- src/core/window.c | 7 +++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/core/window-private.h b/src/core/window-private.h index f463360c8..e2751e5ba 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -159,8 +159,8 @@ struct _MetaWindow /* Whether we're fullscreen */ guint fullscreen : 1; - /* Whether the urgent flag of WM_HINTS is set */ - guint wm_hints_urgent : 1; + /* Whether the window is marked as urgent */ + guint urgent : 1; /* Whether we have to fullscreen after placement */ guint fullscreen_after_placement : 1; diff --git a/src/core/window.c b/src/core/window.c index 496226506..59ddab1f4 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -306,7 +306,7 @@ meta_window_get_property(GObject *object, g_value_set_boolean (value, win->wm_state_demands_attention); break; case PROP_URGENT: - g_value_set_boolean (value, win->wm_hints_urgent); + g_value_set_boolean (value, win->urgent); break; case PROP_SKIP_TASKBAR: g_value_set_boolean (value, win->skip_taskbar); @@ -833,7 +833,6 @@ _meta_window_shared_new (MetaDisplay *display, meta_icon_cache_init (&window->icon_cache); window->wm_hints_pixmap = None; window->wm_hints_mask = None; - window->wm_hints_urgent = FALSE; window->frame = NULL; window->has_focus = FALSE; @@ -10378,10 +10377,10 @@ void meta_window_set_urgent (MetaWindow *window, gboolean urgent) { - if (window->wm_hints_urgent == urgent) + if (window->urgent == urgent) return; - window->wm_hints_urgent = urgent; + window->urgent = urgent; g_object_notify_by_pspec (window, props[PROP_URGENT]); if (urgent) From da48b18188ea1cc8acb76112c85dff2b0d5a91e3 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 16:45:53 -0400 Subject: [PATCH 684/889] window: Fix build A bad rebase on top of some other GObject cleanups I had made this go sour. --- src/core/window.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/window.c b/src/core/window.c index 59ddab1f4..9aff235a3 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -10381,7 +10381,7 @@ meta_window_set_urgent (MetaWindow *window, return; window->urgent = urgent; - g_object_notify_by_pspec (window, props[PROP_URGENT]); + g_object_notify (G_OBJECT (window), "urgent"); if (urgent) g_signal_emit_by_name (window->display, "window-marked-urgent", window); From 4fdbb466e1c6ae506d203682ed290694bb0acf7b Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 17:41:22 -0400 Subject: [PATCH 685/889] meta-plugin: Remove some unused features And don't use properties for no reason. --- src/compositor/meta-plugin-manager.c | 15 +-- src/compositor/meta-plugin.c | 151 +++------------------------ src/meta/meta-plugin.h | 6 +- 3 files changed, 16 insertions(+), 156 deletions(-) diff --git a/src/compositor/meta-plugin-manager.c b/src/compositor/meta-plugin-manager.c index 41589a32c..29bac00e5 100644 --- a/src/compositor/meta-plugin-manager.c +++ b/src/compositor/meta-plugin-manager.c @@ -100,7 +100,9 @@ meta_plugin_manager_new (MetaScreen *screen) plugin_mgr = g_new0 (MetaPluginManager, 1); plugin_mgr->screen = screen; - plugin_mgr->plugin = plugin = g_object_new (plugin_type, "screen", screen, NULL); + plugin_mgr->plugin = plugin = g_object_new (plugin_type, NULL); + + _meta_plugin_set_screen (plugin, screen); klass = META_PLUGIN_GET_CLASS (plugin); @@ -165,8 +167,6 @@ meta_plugin_manager_event_simple (MetaPluginManager *plugin_mgr, retval = TRUE; meta_plugin_manager_kill_window_effects (plugin_mgr, actor); - - _meta_plugin_effect_started (plugin); klass->minimize (plugin, actor); } break; @@ -176,8 +176,6 @@ meta_plugin_manager_event_simple (MetaPluginManager *plugin_mgr, retval = TRUE; meta_plugin_manager_kill_window_effects (plugin_mgr, actor); - - _meta_plugin_effect_started (plugin); klass->map (plugin, actor); } break; @@ -185,7 +183,6 @@ meta_plugin_manager_event_simple (MetaPluginManager *plugin_mgr, if (klass->destroy) { retval = TRUE; - _meta_plugin_effect_started (plugin); klass->destroy (plugin, actor); } break; @@ -230,8 +227,6 @@ meta_plugin_manager_event_maximize (MetaPluginManager *plugin_mgr, retval = TRUE; meta_plugin_manager_kill_window_effects (plugin_mgr, actor); - - _meta_plugin_effect_started (plugin); klass->maximize (plugin, actor, target_x, target_y, target_width, target_height); @@ -243,8 +238,6 @@ meta_plugin_manager_event_maximize (MetaPluginManager *plugin_mgr, retval = TRUE; meta_plugin_manager_kill_window_effects (plugin_mgr, actor); - - _meta_plugin_effect_started (plugin); klass->unmaximize (plugin, actor, target_x, target_y, target_width, target_height); @@ -283,8 +276,6 @@ meta_plugin_manager_switch_workspace (MetaPluginManager *plugin_mgr, { retval = TRUE; meta_plugin_manager_kill_switch_workspace (plugin_mgr); - - _meta_plugin_effect_started (plugin); klass->switch_workspace (plugin, from, to, direction); } diff --git a/src/compositor/meta-plugin.c b/src/compositor/meta-plugin.c index 444d81e85..61d99d0f8 100644 --- a/src/compositor/meta-plugin.c +++ b/src/compositor/meta-plugin.c @@ -47,91 +47,15 @@ G_DEFINE_ABSTRACT_TYPE (MetaPlugin, meta_plugin, G_TYPE_OBJECT); #define META_PLUGIN_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), META_TYPE_PLUGIN, MetaPluginPrivate)) -enum -{ - PROP_0, - PROP_SCREEN, - PROP_DEBUG_MODE, -}; - struct _MetaPluginPrivate { - MetaScreen *screen; - - gint running; - gboolean debug : 1; + MetaScreen *screen; }; -static void -meta_plugin_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - MetaPluginPrivate *priv = META_PLUGIN (object)->priv; - - switch (prop_id) - { - case PROP_SCREEN: - priv->screen = g_value_get_object (value); - break; - case PROP_DEBUG_MODE: - priv->debug = g_value_get_boolean (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -meta_plugin_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - MetaPluginPrivate *priv = META_PLUGIN (object)->priv; - - switch (prop_id) - { - case PROP_SCREEN: - g_value_set_object (value, priv->screen); - break; - case PROP_DEBUG_MODE: - g_value_set_boolean (value, priv->debug); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - - static void meta_plugin_class_init (MetaPluginClass *klass) { - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - gobject_class->set_property = meta_plugin_set_property; - gobject_class->get_property = meta_plugin_get_property; - - g_object_class_install_property (gobject_class, - PROP_SCREEN, - g_param_spec_object ("screen", - "MetaScreen", - "MetaScreen", - META_TYPE_SCREEN, - G_PARAM_READWRITE)); - - g_object_class_install_property (gobject_class, - PROP_DEBUG_MODE, - g_param_spec_boolean ("debug-mode", - "Debug Mode", - "Debug Mode", - FALSE, - G_PARAM_READABLE)); - - g_type_class_add_private (gobject_class, sizeof (MetaPluginPrivate)); + g_type_class_add_private (klass, sizeof (MetaPluginPrivate)); } static void @@ -140,22 +64,6 @@ meta_plugin_init (MetaPlugin *self) self->priv = META_PLUGIN_GET_PRIVATE (self); } -gboolean -meta_plugin_running (MetaPlugin *plugin) -{ - MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv; - - return (priv->running > 0); -} - -gboolean -meta_plugin_debug_mode (MetaPlugin *plugin) -{ - MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv; - - return priv->debug; -} - const MetaPluginInfo * meta_plugin_get_info (MetaPlugin *plugin) { @@ -167,21 +75,6 @@ meta_plugin_get_info (MetaPlugin *plugin) return NULL; } -/** - * _meta_plugin_effect_started: - * @plugin: the plugin - * - * Mark that an effect has started for the plugin. This is called - * internally by MetaPluginManager. - */ -void -_meta_plugin_effect_started (MetaPlugin *plugin) -{ - MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv; - - priv->running++; -} - gboolean _meta_plugin_xevent_filter (MetaPlugin *plugin, XEvent *xev) @@ -208,15 +101,8 @@ void meta_plugin_switch_workspace_completed (MetaPlugin *plugin) { MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv; - MetaScreen *screen = priv->screen; - if (priv->running-- < 0) - { - g_warning ("Error in running effect accounting, adjusting."); - priv->running = 0; - } - meta_switch_workspace_completed (screen); } @@ -225,26 +111,6 @@ meta_plugin_window_effect_completed (MetaPlugin *plugin, MetaWindowActor *actor, unsigned long event) { - MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv; - - if (priv->running-- < 0) - { - g_warning ("Error in running effect accounting, adjusting."); - priv->running = 0; - } - - if (!actor) - { - const MetaPluginInfo *info; - const gchar *name = NULL; - - if (plugin && (info = meta_plugin_get_info (plugin))) - name = info->name; - - g_warning ("Plugin [%s] passed NULL for actor!", - name ? name : "unknown"); - } - meta_window_actor_effect_completed (actor, event); } @@ -339,9 +205,7 @@ meta_plugin_end_modal (MetaPlugin *plugin, * meta_plugin_get_screen: * @plugin: a #MetaPlugin * - * Gets the #MetaScreen corresponding to a plugin. Each plugin instance - * is associated with exactly one screen; if Metacity is managing - * multiple screens, multiple plugin instances will be created. + * Gets the #MetaScreen corresponding to a plugin. * * Return value: (transfer none): the #MetaScreen for the plugin */ @@ -353,6 +217,15 @@ meta_plugin_get_screen (MetaPlugin *plugin) return priv->screen; } +void +_meta_plugin_set_screen (MetaPlugin *plugin, + MetaScreen *screen) +{ + MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv; + + priv->screen = screen; +} + void meta_plugin_complete_display_change (MetaPlugin *plugin, gboolean ok) diff --git a/src/meta/meta-plugin.h b/src/meta/meta-plugin.h index cef785397..df42f3e34 100644 --- a/src/meta/meta-plugin.h +++ b/src/meta/meta-plugin.h @@ -254,9 +254,6 @@ struct _MetaPluginInfo GType meta_plugin_get_type (void); -gboolean meta_plugin_running (MetaPlugin *plugin); -gboolean meta_plugin_debug_mode (MetaPlugin *plugin); - const MetaPluginInfo * meta_plugin_get_info (MetaPlugin *plugin); /** @@ -408,8 +405,7 @@ meta_plugin_end_modal (MetaPlugin *plugin, MetaScreen *meta_plugin_get_screen (MetaPlugin *plugin); -void -_meta_plugin_effect_started (MetaPlugin *plugin); +void _meta_plugin_set_screen (MetaPlugin *plugin, MetaScreen *screen); /* XXX: Putting this in here so it's in the public header. */ void meta_plugin_manager_set_plugin_type (GType gtype); From 8b2b65246a8673567d2b7f07896194def990f064 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 17:06:42 -0400 Subject: [PATCH 686/889] Assume the compositor always exists At one point, it was supported to run mutter without a compositor, but we don't allow that any longer. A lot of code already assumes display->compositor exists and doesn't check for a NULL pointer, so just kill the rest of the checks. --- src/core/bell.c | 94 +------------------- src/core/display.c | 4 +- src/core/screen.c | 14 ++- src/core/stack-tracker.c | 7 +- src/core/window.c | 186 +++++++++++++++------------------------ src/x11/window-x11.c | 14 ++- 6 files changed, 87 insertions(+), 232 deletions(-) diff --git a/src/core/bell.c b/src/core/bell.c index cc25a27ec..5479142f4 100644 --- a/src/core/bell.c +++ b/src/core/bell.c @@ -58,88 +58,6 @@ #include #endif -/** - * bell_flash_screen: - * @display: The display which owns the screen (rather redundant) - * @screen: The screen to flash - * - * Flashes one entire screen. This is done by making a window the size of the - * whole screen (or reusing the old one, if it's still around), mapping it, - * painting it white and then black, and then unmapping it. We set saveunder so - * that all the windows behind it come back immediately. - * - * Unlike frame flashes, we don't do fullscreen flashes with a timeout; rather, - * we do them in one go, because we don't have to rely on the theme code - * redrawing the frame for us in order to do the flash. - */ -/* - * Bug: The way I read it, this appears not to do the flash - * the first time we flash a particular display. Am I wrong? - * - * Bug: This appears to destroy our current XSync status. - */ -static void -bell_flash_screen (MetaDisplay *display, - MetaScreen *screen) -{ - Window root = screen->xroot; - int width = screen->rect.width; - int height = screen->rect.height; - - if (screen->flash_window == None) - { - Visual *visual = (Visual *)CopyFromParent; - XSetWindowAttributes xswa; - int depth = CopyFromParent; - xswa.save_under = True; - xswa.override_redirect = True; - /* - * TODO: use XGetVisualInfo and determine which is an - * overlay, if one is present, and use the Overlay visual - * for this window (for performance reasons). - * Not sure how to tell this yet... - */ - screen->flash_window = XCreateWindow (display->xdisplay, root, - 0, 0, width, height, - 0, depth, - InputOutput, - visual, - /* note: XSun doesn't like SaveUnder here */ - CWSaveUnder | CWOverrideRedirect, - &xswa); - XSelectInput (display->xdisplay, screen->flash_window, ExposureMask); - XMapWindow (display->xdisplay, screen->flash_window); - XSync (display->xdisplay, False); - XFlush (display->xdisplay); - XUnmapWindow (display->xdisplay, screen->flash_window); - } - else - { - /* just draw something in the window */ - GC gc = XCreateGC (display->xdisplay, screen->flash_window, 0, NULL); - XMapWindow (display->xdisplay, screen->flash_window); - XSetForeground (display->xdisplay, gc, - WhitePixel (display->xdisplay, - XScreenNumberOfScreen (screen->xscreen))); - XFillRectangle (display->xdisplay, screen->flash_window, gc, - 0, 0, width, height); - XSetForeground (display->xdisplay, gc, - BlackPixel (display->xdisplay, - XScreenNumberOfScreen (screen->xscreen))); - XFillRectangle (display->xdisplay, screen->flash_window, gc, - 0, 0, width, height); - XFlush (display->xdisplay); - XSync (display->xdisplay, False); - XUnmapWindow (display->xdisplay, screen->flash_window); - XFreeGC (display->xdisplay, gc); - } - - if (meta_prefs_get_focus_mode () != G_DESKTOP_FOCUS_MODE_CLICK && - !display->mouse_mode) - meta_display_increment_focus_sentinel (display); - XFlush (display->xdisplay); -} - /** * bell_flash_fullscreen: * @display: The display the event came in on @@ -164,12 +82,7 @@ bell_flash_fullscreen (MetaDisplay *display, { screen = meta_display_screen_for_xwindow (display, xkb_bell_ev->window); if (screen) - { - if (display->compositor) - meta_compositor_flash_screen (display->compositor, screen); - else - bell_flash_screen (display, screen); - } + meta_compositor_flash_screen (display->compositor, screen); } else { @@ -177,10 +90,7 @@ bell_flash_fullscreen (MetaDisplay *display, while (screen_list) { screen = (MetaScreen *) screen_list->data; - if (display->compositor) - meta_compositor_flash_screen (display->compositor, screen); - else - bell_flash_screen (display, screen); + meta_compositor_flash_screen (display->compositor, screen); screen_list = screen_list->next; } } diff --git a/src/core/display.c b/src/core/display.c index 08df05102..f4c5946aa 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -2621,7 +2621,7 @@ handle_other_xevent (MetaDisplay *display, /* NB: override redirect windows wont cause a map request so we * watch out for map notifies against any root windows too if a * compositor is enabled: */ - if (display->compositor && window == NULL + if (window == NULL && meta_display_screen_for_root (display, event->xmap.event)) { window = meta_window_x11_new (display, event->xmap.window, @@ -3085,7 +3085,7 @@ meta_display_handle_xevent (MetaDisplay *display, } out: - if (display->compositor && !bypass_compositor) + if (!bypass_compositor) { MetaWindow *window = modified != None ? meta_display_lookup_x_window (display, modified) : NULL; diff --git a/src/core/screen.c b/src/core/screen.c index f1700c580..512a722a6 100644 --- a/src/core/screen.c +++ b/src/core/screen.c @@ -809,11 +809,8 @@ meta_screen_free (MetaScreen *screen, meta_display_grab (display); - if (screen->display->compositor) - { - meta_compositor_unmanage_screen (screen->display->compositor, - screen); - } + meta_compositor_unmanage_screen (screen->display->compositor, + screen); meta_display_unmanage_windows_for_screen (display, screen, timestamp); @@ -2523,10 +2520,9 @@ on_monitors_changed (MetaMonitorManager *manager, &changes); } - if (screen->display->compositor) - meta_compositor_sync_screen_size (screen->display->compositor, - screen, - screen->rect.width, screen->rect.height); + meta_compositor_sync_screen_size (screen->display->compositor, + screen, + screen->rect.width, screen->rect.height); /* Queue a resize on all the windows */ meta_screen_foreach_window (screen, meta_screen_resize_func, 0); diff --git a/src/core/stack-tracker.c b/src/core/stack-tracker.c index a323a0410..e87c13f1c 100644 --- a/src/core/stack-tracker.c +++ b/src/core/stack-tracker.c @@ -1245,10 +1245,9 @@ meta_stack_tracker_sync_stack (MetaStackTracker *tracker) meta_windows = g_list_prepend (meta_windows, window->wayland.meta_window); } - if (tracker->screen->display->compositor) - meta_compositor_sync_stack (tracker->screen->display->compositor, - tracker->screen, - meta_windows); + meta_compositor_sync_stack (tracker->screen->display->compositor, + tracker->screen, + meta_windows); g_list_free (meta_windows); meta_screen_restacked (tracker->screen); diff --git a/src/core/window.c b/src/core/window.c index 9aff235a3..38aaf11fd 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -1221,8 +1221,7 @@ _meta_window_shared_new (MetaDisplay *display, set_net_wm_state (window); } - if (screen->display->compositor) - meta_compositor_add_window (screen->display->compositor, window); + meta_compositor_add_window (screen->display->compositor, window); /* Sync stack changes */ meta_stack_thaw (window->screen->stack); @@ -1505,14 +1504,11 @@ meta_window_unmanage (MetaWindow *window, 0); } - if (window->display->compositor) - { - if (window->visible_to_compositor) - meta_compositor_hide_window (window->display->compositor, window, - META_COMP_EFFECT_DESTROY); + if (window->visible_to_compositor) + meta_compositor_hide_window (window->display->compositor, window, + META_COMP_EFFECT_DESTROY); - meta_compositor_remove_window (window->display->compositor, window); - } + meta_compositor_remove_window (window->display->compositor, window); if (window->display->window_with_menu == window) { @@ -2747,27 +2743,24 @@ meta_window_show (MetaWindow *window) if (!window->visible_to_compositor) { + MetaCompEffect effect = META_COMP_EFFECT_NONE; + window->visible_to_compositor = TRUE; - if (window->display->compositor) + switch (window->pending_compositor_effect) { - MetaCompEffect effect = META_COMP_EFFECT_NONE; - - switch (window->pending_compositor_effect) - { - case META_COMP_EFFECT_CREATE: - case META_COMP_EFFECT_UNMINIMIZE: - effect = window->pending_compositor_effect; - break; - case META_COMP_EFFECT_NONE: - case META_COMP_EFFECT_DESTROY: - case META_COMP_EFFECT_MINIMIZE: - break; - } - - meta_compositor_show_window (window->display->compositor, - window, effect); + case META_COMP_EFFECT_CREATE: + case META_COMP_EFFECT_UNMINIMIZE: + effect = window->pending_compositor_effect; + break; + case META_COMP_EFFECT_NONE: + case META_COMP_EFFECT_DESTROY: + case META_COMP_EFFECT_MINIMIZE: + break; } + + meta_compositor_show_window (window->display->compositor, + window, effect); } /* We don't want to worry about all cases from inside @@ -2840,26 +2833,23 @@ meta_window_hide (MetaWindow *window) if (window->visible_to_compositor) { + MetaCompEffect effect = META_COMP_EFFECT_NONE; + window->visible_to_compositor = FALSE; - if (window->display->compositor) + switch (window->pending_compositor_effect) { - MetaCompEffect effect = META_COMP_EFFECT_NONE; - - switch (window->pending_compositor_effect) - { - case META_COMP_EFFECT_CREATE: - case META_COMP_EFFECT_UNMINIMIZE: - case META_COMP_EFFECT_NONE: - break; - case META_COMP_EFFECT_DESTROY: - case META_COMP_EFFECT_MINIMIZE: - effect = window->pending_compositor_effect; - break; - } - - meta_compositor_hide_window (window->display->compositor, window, effect); + case META_COMP_EFFECT_CREATE: + case META_COMP_EFFECT_UNMINIMIZE: + case META_COMP_EFFECT_NONE: + break; + case META_COMP_EFFECT_DESTROY: + case META_COMP_EFFECT_MINIMIZE: + effect = window->pending_compositor_effect; + break; } + + meta_compositor_hide_window (window->display->compositor, window, effect); } did_hide = FALSE; @@ -3125,6 +3115,8 @@ meta_window_maximize (MetaWindow *window, { MetaRectangle *saved_rect = NULL; gboolean maximize_horizontally, maximize_vertically; + MetaRectangle old_rect; + MetaRectangle new_rect; g_return_if_fail (!window->override_redirect); @@ -3174,27 +3166,15 @@ meta_window_maximize (MetaWindow *window, directions, saved_rect); - if (window->display->compositor) - { - MetaRectangle old_rect; - MetaRectangle new_rect; + meta_window_get_frame_rect (window, &old_rect); - meta_window_get_frame_rect (window, &old_rect); + meta_window_move_resize_now (window); - meta_window_move_resize_now (window); - - meta_window_get_frame_rect (window, &new_rect); - meta_compositor_maximize_window (window->display->compositor, - window, - &old_rect, - &new_rect); - } - else - { - /* move_resize with new maximization constraints - */ - meta_window_queue(window, META_QUEUE_MOVE_RESIZE); - } + meta_window_get_frame_rect (window, &new_rect); + meta_compositor_maximize_window (window->display->compositor, + window, + &old_rect, + &new_rect); } } @@ -3354,6 +3334,8 @@ void meta_window_tile (MetaWindow *window) { MetaMaximizeFlags directions; + MetaRectangle old_rect; + MetaRectangle new_rect; /* Don't do anything if no tiling is requested */ if (window->tile_mode == META_TILE_NONE) @@ -3367,31 +3349,19 @@ meta_window_tile (MetaWindow *window) meta_window_maximize_internal (window, directions, NULL); meta_screen_update_tile_preview (window->screen, FALSE); - if (window->display->compositor) - { - MetaRectangle old_rect; - MetaRectangle new_rect; + meta_window_get_frame_rect (window, &old_rect); - meta_window_get_frame_rect (window, &old_rect); + meta_window_move_resize_now (window); - meta_window_move_resize_now (window); + meta_window_get_frame_rect (window, &new_rect); + meta_compositor_maximize_window (window->display->compositor, + window, + &old_rect, + &new_rect); - meta_window_get_frame_rect (window, &new_rect); - meta_compositor_maximize_window (window->display->compositor, - window, - &old_rect, - &new_rect); - - if (window->frame) - meta_ui_queue_frame_draw (window->screen->ui, - window->frame->xwindow); - } - else - { - /* move_resize with new tiling constraints - */ - meta_window_queue (window, META_QUEUE_MOVE_RESIZE); - } + if (window->frame) + meta_ui_queue_frame_draw (window->screen->ui, + window->frame->xwindow); } static gboolean @@ -3464,6 +3434,7 @@ meta_window_unmaximize_internal (MetaWindow *window, int gravity) { gboolean unmaximize_horizontally, unmaximize_vertically; + MetaRectangle new_rect; g_return_if_fail (!window->override_redirect); @@ -3548,34 +3519,19 @@ meta_window_unmaximize_internal (MetaWindow *window, */ ensure_size_hints_satisfied (&target_rect, &window->size_hints); - if (window->display->compositor) - { - MetaRectangle new_rect; + meta_window_move_resize_internal (window, + META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION, + gravity, + target_rect.x, + target_rect.y, + target_rect.width, + target_rect.height); - meta_window_move_resize_internal (window, - META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION, - gravity, - target_rect.x, - target_rect.y, - target_rect.width, - target_rect.height); - - meta_window_get_frame_rect (window, &new_rect); - meta_compositor_unmaximize_window (window->display->compositor, - window, - &old_rect, - &new_rect); - } - else - { - meta_window_move_resize_internal (window, - META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION, - gravity, - target_rect.x, - target_rect.y, - target_rect.width, - target_rect.height); - } + meta_window_get_frame_rect (window, &new_rect); + meta_compositor_unmaximize_window (window->display->compositor, + window, + &old_rect, + &new_rect); /* Make sure user_rect is current. */ @@ -5014,10 +4970,9 @@ meta_window_move_resize_internal (MetaWindow *window, newx, newy, window->rect.width, window->rect.height, window->user_rect.x, window->user_rect.y, window->user_rect.width, window->user_rect.height); - if (window->display->compositor) - meta_compositor_sync_window_geometry (window->display->compositor, - window, - did_placement); + meta_compositor_sync_window_geometry (window->display->compositor, + window, + did_placement); } else { @@ -10117,8 +10072,7 @@ meta_window_set_opacity (MetaWindow *window, { window->opacity = opacity; - if (window->display->compositor) - meta_compositor_window_opacity_changed (window->display->compositor, window); + meta_compositor_window_opacity_changed (window->display->compositor, window); } static void diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c index c8db060e5..5abc848a6 100644 --- a/src/x11/window-x11.c +++ b/src/x11/window-x11.c @@ -297,8 +297,7 @@ meta_window_set_opaque_region (MetaWindow *window, if (region != NULL) window->opaque_region = cairo_region_reference (region); - if (window->display->compositor) - meta_compositor_window_shape_changed (window->display->compositor, window); + meta_compositor_window_shape_changed (window->display->compositor, window); } void @@ -383,8 +382,7 @@ meta_window_set_input_region (MetaWindow *window, if (region != NULL) window->input_region = cairo_region_reference (region); - if (window->display->compositor) - meta_compositor_window_shape_changed (window->display->compositor, window); + meta_compositor_window_shape_changed (window->display->compositor, window); } #if 0 @@ -490,8 +488,7 @@ meta_window_set_shape_region (MetaWindow *window, if (region != NULL) window->shape_region = cairo_region_reference (region); - if (window->display->compositor) - meta_compositor_window_shape_changed (window->display->compositor, window); + meta_compositor_window_shape_changed (window->display->compositor, window); } void @@ -1348,7 +1345,7 @@ is_our_xwindow (MetaDisplay *display, if (xwindow == screen->guard_window) return TRUE; - if (display->compositor && xwindow == XCompositeGetOverlayWindow (display->xdisplay, screen->xroot)) + if (xwindow == XCompositeGetOverlayWindow (display->xdisplay, screen->xroot)) return TRUE; /* Any windows created via meta_create_offscreen_window */ @@ -1687,6 +1684,5 @@ meta_window_x11_configure_notify (MetaWindow *window, if (!event->override_redirect && !event->send_event) meta_warning ("Unhandled change of windows override redirect status\n"); - if (window->display->compositor) - meta_compositor_sync_window_geometry (window->display->compositor, window, FALSE); + meta_compositor_sync_window_geometry (window->display->compositor, window, FALSE); } From 9ba49358e50af93ff9e59d1ef88700750106f115 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 17:11:44 -0400 Subject: [PATCH 687/889] compositor: Remove meta_check_end_modal "This is used when reloading plugins" Yeah, no. --- src/compositor/compositor-private.h | 2 -- src/compositor/compositor.c | 19 ------------------- 2 files changed, 21 deletions(-) diff --git a/src/compositor/compositor-private.h b/src/compositor/compositor-private.h index 18bcff6f9..55f5017a9 100644 --- a/src/compositor/compositor-private.h +++ b/src/compositor/compositor-private.h @@ -70,6 +70,4 @@ void meta_end_modal_for_plugin (MetaScreen *screen, gint64 meta_compositor_monotonic_time_to_server_time (MetaDisplay *display, gint64 monotonic_time); -void meta_check_end_modal (MetaScreen *screen); - #endif /* META_COMPOSITOR_PRIVATE_H */ diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index fdbf6d604..305d8cb76 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -497,25 +497,6 @@ meta_end_modal_for_plugin (MetaScreen *screen, compositor->modal_plugin = NULL; } -/* This is used when reloading plugins to make sure we don't have - * a left-over modal grab for this screen. - */ -void -meta_check_end_modal (MetaScreen *screen) -{ - MetaDisplay *display = meta_screen_get_display (screen); - MetaCompositor *compositor = display->compositor; - - if (compositor->modal_plugin && - meta_plugin_get_screen (compositor->modal_plugin) == screen) - { - meta_end_modal_for_plugin (screen, - compositor->modal_plugin, - - CurrentTime); - } -} - static void after_stage_paint (ClutterStage *stage, gpointer data) From 33f1bd96f50227301b4562eeaa159c2eb5559ca2 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 17:11:25 -0400 Subject: [PATCH 688/889] compositor: Kill off modal_plugin We only ever have one plugin, so don't bother recording which plugin is modal, only whether we are modal or not. --- src/compositor/compositor-private.h | 2 -- src/compositor/compositor.c | 26 +++++++++++++------------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/compositor/compositor-private.h b/src/compositor/compositor-private.h index 55f5017a9..88eacc96c 100644 --- a/src/compositor/compositor-private.h +++ b/src/compositor/compositor-private.h @@ -21,8 +21,6 @@ struct _MetaCompositor ClutterActor *shadow_src; - MetaPlugin *modal_plugin; - gint64 server_time_query_time; gint64 server_time_offset; diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 305d8cb76..23b4bb548 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -83,6 +83,12 @@ #include #include +static gboolean +is_modal (MetaDisplay *display) +{ + return display->grab_op == META_GRAB_OP_COMPOSITOR; +} + /* #define DEBUG_TRACE g_print */ #define DEBUG_TRACE(X) @@ -446,11 +452,10 @@ meta_begin_modal_for_plugin (MetaScreen *screen, * are significant differences in how we handle grabs that make it difficult to * merge the two. */ - MetaDisplay *display = meta_screen_get_display (screen); - MetaCompositor *compositor = display->compositor; + MetaDisplay *display = meta_screen_get_display (screen); gboolean ok; - if (compositor->modal_plugin != NULL || display->grab_op != META_GRAB_OP_NONE) + if (is_modal (display) || display->grab_op != META_GRAB_OP_NONE) return FALSE; if (meta_is_wayland_compositor ()) @@ -466,8 +471,6 @@ meta_begin_modal_for_plugin (MetaScreen *screen, display->grab_have_pointer = TRUE; display->grab_have_keyboard = TRUE; - compositor->modal_plugin = plugin; - return TRUE; } @@ -476,11 +479,10 @@ meta_end_modal_for_plugin (MetaScreen *screen, MetaPlugin *plugin, guint32 timestamp) { - MetaDisplay *display = meta_screen_get_display (screen); - Display *xdpy = meta_display_get_xdisplay (display); - MetaCompositor *compositor = display->compositor; + MetaDisplay *display = meta_screen_get_display (screen); + Display *xdpy = meta_display_get_xdisplay (display); - g_return_if_fail (compositor->modal_plugin == plugin); + g_return_if_fail (is_modal (display)); if (!meta_is_wayland_compositor ()) { @@ -493,8 +495,6 @@ meta_end_modal_for_plugin (MetaScreen *screen, display->grab_screen = NULL; display->grab_have_pointer = FALSE; display->grab_have_keyboard = FALSE; - - compositor->modal_plugin = NULL; } static void @@ -1004,9 +1004,9 @@ meta_compositor_process_event (MetaCompositor *compositor, info = meta_screen_get_compositor_data (screen); - if (compositor->modal_plugin && is_grabbed_event (compositor->display, event)) + if (is_modal (display) && is_grabbed_event (compositor->display, event)) { - _meta_plugin_xevent_filter (compositor->modal_plugin, event); + meta_plugin_manager_xevent_filter (info->plugin_mgr, event); /* We always consume events even if the plugin says it didn't handle them; * exclusive is exclusive */ From be57308663b510686ccddb00c001e261ecf47edf Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 17:22:42 -0400 Subject: [PATCH 689/889] compositor: Clean up Remove a bunch of weird checks, random logs, unused variables and other cruft that nobody cares about today. --- src/compositor/compositor-private.h | 7 +- src/compositor/compositor.c | 106 ++++------------------------ 2 files changed, 13 insertions(+), 100 deletions(-) diff --git a/src/compositor/compositor-private.h b/src/compositor/compositor-private.h index 88eacc96c..bae233baf 100644 --- a/src/compositor/compositor-private.h +++ b/src/compositor/compositor-private.h @@ -19,14 +19,10 @@ struct _MetaCompositor guint repaint_func_id; - ClutterActor *shadow_src; - gint64 server_time_query_time; gint64 server_time_offset; guint server_time_is_monotonic_time : 1; - guint show_redraw : 1; - guint debug : 1; guint no_mipmaps : 1; }; @@ -34,10 +30,9 @@ struct _MetaCompScreen { MetaScreen *screen; - ClutterActor *stage, *window_group, *top_window_group, *overlay_group; + ClutterActor *stage, *window_group, *top_window_group; ClutterActor *background_actor; GList *windows; - GHashTable *windows_by_xid; Window output; CoglOnscreen *onscreen; diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 23b4bb548..2ce2e10bb 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -89,9 +89,6 @@ is_modal (MetaDisplay *display) return display->grab_op == META_GRAB_OP_COMPOSITOR; } -/* #define DEBUG_TRACE g_print */ -#define DEBUG_TRACE(X) - static inline gboolean composite_at_least_version (MetaDisplay *display, int maj, int min) { @@ -115,13 +112,8 @@ meta_finish_workspace_switch (MetaCompScreen *info) for (l = info->windows; l; l = l->next) meta_window_actor_sync_visibility (l->data); - /* - * Fix up stacking order in case the plugin messed it up. - */ + /* Fix up stacking order. */ sync_actor_stacking (info); - -/* printf ("... FINISHED DESKTOP SWITCH\n"); */ - } void @@ -147,33 +139,12 @@ meta_compositor_destroy (MetaCompositor *compositor) clutter_threads_remove_repaint_func (compositor->repaint_func_id); } -static void -add_win (MetaWindow *window) -{ - MetaScreen *screen = meta_window_get_screen (window); - MetaCompScreen *info = meta_screen_get_compositor_data (screen); - - g_return_if_fail (info != NULL); - - meta_window_actor_new (window); - - sync_actor_stacking (info); -} - static void process_damage (MetaCompositor *compositor, XDamageNotifyEvent *event, MetaWindow *window) { - MetaWindowActor *window_actor; - - if (window == NULL) - return; - - window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - if (window_actor == NULL) - return; - + MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); meta_window_actor_process_x11_damage (window_actor, event); } @@ -767,11 +738,12 @@ meta_compositor_add_window (MetaCompositor *compositor, { MetaScreen *screen = meta_window_get_screen (window); MetaDisplay *display = meta_screen_get_display (screen); + MetaCompScreen *info = meta_screen_get_compositor_data (screen); - DEBUG_TRACE ("meta_compositor_add_window\n"); meta_error_trap_push (display); - add_win (window); + meta_window_actor_new (window); + sync_actor_stacking (info); meta_error_trap_pop (display); } @@ -780,17 +752,9 @@ void meta_compositor_remove_window (MetaCompositor *compositor, MetaWindow *window) { - MetaWindowActor *window_actor = NULL; - MetaScreen *screen; - MetaCompScreen *info; - - DEBUG_TRACE ("meta_compositor_remove_window\n"); - window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - if (!window_actor) - return; - - screen = meta_window_get_screen (window); - info = meta_screen_get_compositor_data (screen); + MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); + MetaScreen *screen = meta_window_get_screen (window); + MetaCompScreen *info = meta_screen_get_compositor_data (screen); if (info->unredirected_window == window) set_unredirected_window (info, NULL); @@ -803,13 +767,7 @@ meta_compositor_set_updates_frozen (MetaCompositor *compositor, MetaWindow *window, gboolean updates_frozen) { - MetaWindowActor *window_actor; - - DEBUG_TRACE ("meta_compositor_set_updates_frozen\n"); - window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - if (!window_actor) - return; - + MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); meta_window_actor_set_updates_frozen (window_actor, updates_frozen); } @@ -818,13 +776,7 @@ meta_compositor_queue_frame_drawn (MetaCompositor *compositor, MetaWindow *window, gboolean no_delay_frame) { - MetaWindowActor *window_actor; - - DEBUG_TRACE ("meta_compositor_queue_frame_drawn\n"); - window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - if (!window_actor) - return; - + MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); meta_window_actor_queue_frame_drawn (window_actor, no_delay_frame); } @@ -1017,10 +969,7 @@ meta_compositor_process_event (MetaCompositor *compositor, maybe_spoof_event_as_stage_event (info, window, event); if (meta_plugin_manager_xevent_filter (info->plugin_mgr, event)) - { - DEBUG_TRACE ("meta_compositor_process_event (filtered,window==NULL)\n"); - return TRUE; - } + return TRUE; if (!meta_is_wayland_compositor () && event->type == meta_display_get_damage_event_base (compositor->display) + XDamageNotify) @@ -1034,7 +983,6 @@ meta_compositor_process_event (MetaCompositor *compositor, window = meta_display_lookup_x_window (compositor->display, xwin); } - DEBUG_TRACE ("meta_compositor_process_event (process_damage)\n"); process_damage (compositor, (XDamageNotifyEvent *) event, window); } @@ -1069,11 +1017,7 @@ meta_compositor_show_window (MetaCompositor *compositor, MetaCompEffect effect) { MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - DEBUG_TRACE ("meta_compositor_show_window\n"); - if (!window_actor) - return; - - meta_window_actor_show (window_actor, effect); + meta_window_actor_show (window_actor, effect); } void @@ -1082,10 +1026,6 @@ meta_compositor_hide_window (MetaCompositor *compositor, MetaCompEffect effect) { MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - DEBUG_TRACE ("meta_compositor_hide_window\n"); - if (!window_actor) - return; - meta_window_actor_hide (window_actor, effect); } @@ -1096,10 +1036,6 @@ meta_compositor_maximize_window (MetaCompositor *compositor, MetaRectangle *new_rect) { MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - DEBUG_TRACE ("meta_compositor_maximize_window\n"); - if (!window_actor) - return; - meta_window_actor_maximize (window_actor, old_rect, new_rect); } @@ -1110,10 +1046,6 @@ meta_compositor_unmaximize_window (MetaCompositor *compositor, MetaRectangle *new_rect) { MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - DEBUG_TRACE ("meta_compositor_unmaximize_window\n"); - if (!window_actor) - return; - meta_window_actor_unmaximize (window_actor, old_rect, new_rect); } @@ -1131,8 +1063,6 @@ meta_compositor_switch_workspace (MetaCompositor *compositor, to_indx = meta_workspace_index (to); from_indx = meta_workspace_index (from); - DEBUG_TRACE ("meta_compositor_switch_workspace\n"); - if (!info) /* During startup before manage_screen() */ return; @@ -1251,8 +1181,6 @@ meta_compositor_sync_stack (MetaCompositor *compositor, GList *old_stack; MetaCompScreen *info = meta_screen_get_compositor_data (screen); - DEBUG_TRACE ("meta_compositor_sync_stack\n"); - /* This is painful because hidden windows that we are in the process * of animating out of existence. They'll be at the bottom of the * stack of X windows, but we want to leave them in their old position @@ -1341,15 +1269,6 @@ meta_compositor_sync_window_geometry (MetaCompositor *compositor, gboolean did_placement) { MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - MetaScreen *screen = meta_window_get_screen (window); - MetaCompScreen *info = meta_screen_get_compositor_data (screen); - - DEBUG_TRACE ("meta_compositor_sync_window_geometry\n"); - g_return_if_fail (info); - - if (!window_actor) - return; - meta_window_actor_sync_actor_geometry (window_actor, did_placement); } @@ -1381,7 +1300,6 @@ meta_compositor_sync_screen_size (MetaCompositor *compositor, Display *xdisplay; Window xwin; - DEBUG_TRACE ("meta_compositor_sync_screen_size\n"); g_return_if_fail (info); xdisplay = meta_display_get_xdisplay (display); From 97872e70a546bc233e44513e05df96ff0d64d6be Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 17:34:07 -0400 Subject: [PATCH 690/889] compositor: Fix variable name style in meta_shape_cow_for_window This has bugged me forever... --- src/compositor/compositor.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 2ce2e10bb..047e351e4 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -667,18 +667,25 @@ meta_compositor_unmanage_screen (MetaCompositor *compositor, } } -/* - * Shapes the cow so that the given window is exposed, - * when metaWindow is NULL it clears the shape again +/** + * meta_shape_cow_for_window: + * @screen: A #MetaScreen + * @window: (allow-none): A #MetaWindow to shape the COW for + * + * Sets an bounding shape on the COW so that the given window + * is exposed. If @window is %NULL it clears the shape again. + * + * Used so we can unredirect windows, by shaping away the part + * of the COW, letting the raw window be seen through below. */ static void meta_shape_cow_for_window (MetaScreen *screen, - MetaWindow *metaWindow) + MetaWindow *window) { MetaCompScreen *info = meta_screen_get_compositor_data (screen); Display *xdisplay = meta_display_get_xdisplay (meta_screen_get_display (screen)); - if (metaWindow == NULL) + if (window == NULL) XFixesSetWindowShapeRegion (xdisplay, info->output, ShapeBounding, 0, 0, None); else { @@ -687,7 +694,7 @@ meta_shape_cow_for_window (MetaScreen *screen, int width, height; MetaRectangle rect; - meta_window_get_frame_rect (metaWindow, &rect); + meta_window_get_frame_rect (window, &rect); window_bounds.x = rect.x; window_bounds.y = rect.y; From 4bf6e0ae8c3d8bc4fda472ab13e114256562567e Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 17:54:04 -0400 Subject: [PATCH 691/889] compositor: Kill off an unused cursor variable --- src/compositor/compositor.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 047e351e4..c16881579 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -349,7 +349,6 @@ begin_modal_x11 (MetaScreen *screen, Display *xdpy = meta_display_get_xdisplay (display); MetaCompScreen *info = meta_screen_get_compositor_data (screen); Window grab_window = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage)); - Cursor cursor = None; int result; gboolean pointer_grabbed = FALSE; gboolean keyboard_grabbed = FALSE; @@ -369,7 +368,7 @@ begin_modal_x11 (MetaScreen *screen, META_VIRTUAL_CORE_POINTER_ID, grab_window, timestamp, - cursor, + None, XIGrabModeAsync, XIGrabModeAsync, False, /* owner_events */ &mask); From 420f322910a5d28ef7ac1ab3072df8318eed6d75 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 18:12:29 -0400 Subject: [PATCH 692/889] compositor: Assume the plugin manager always exists --- src/compositor/compositor.c | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index c16881579..e98c0c5c6 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -1010,11 +1010,7 @@ meta_compositor_filter_keybinding (MetaCompositor *compositor, MetaKeyBinding *binding) { MetaCompScreen *info = meta_screen_get_compositor_data (screen); - - if (info->plugin_mgr) - return meta_plugin_manager_filter_keybinding (info->plugin_mgr, binding); - - return FALSE; + return meta_plugin_manager_filter_keybinding (info->plugin_mgr, binding); } void @@ -1074,11 +1070,9 @@ meta_compositor_switch_workspace (MetaCompositor *compositor, info->switch_workspace_in_progress++; - if (!info->plugin_mgr || - !meta_plugin_manager_switch_workspace (info->plugin_mgr, - from_indx, - to_indx, - direction)) + if (!meta_plugin_manager_switch_workspace (info->plugin_mgr, + from_indx, to_indx, + direction)) { info->switch_workspace_in_progress--; @@ -1609,10 +1603,6 @@ meta_compositor_show_tile_preview (MetaCompositor *compositor, int tile_monitor_number) { MetaCompScreen *info = meta_screen_get_compositor_data (screen); - - if (!info->plugin_mgr) - return; - meta_plugin_manager_show_tile_preview (info->plugin_mgr, window, tile_rect, tile_monitor_number); } @@ -1622,9 +1612,5 @@ meta_compositor_hide_tile_preview (MetaCompositor *compositor, MetaScreen *screen) { MetaCompScreen *info = meta_screen_get_compositor_data (screen); - - if (!info->plugin_mgr) - return; - meta_plugin_manager_hide_tile_preview (info->plugin_mgr); } From b087fce062690f99bc7d4392a169b024dbca415d Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 18:31:07 -0400 Subject: [PATCH 693/889] window-actor: Also always assume the plugin manager exists Addendum to the above... --- src/compositor/meta-window-actor.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index e5d54e9f1..a4368356d 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -968,9 +968,6 @@ start_simple_effect (MetaWindowActor *self, gint *counter = NULL; gboolean use_freeze_thaw = FALSE; - if (!info->plugin_mgr) - return FALSE; - switch (event) { case META_PLUGIN_MINIMIZE: @@ -1299,8 +1296,7 @@ meta_window_actor_maximize (MetaWindowActor *self, self->priv->maximize_in_progress++; meta_window_actor_freeze (self); - if (!info->plugin_mgr || - !meta_plugin_manager_event_maximize (info->plugin_mgr, + if (!meta_plugin_manager_event_maximize (info->plugin_mgr, self, META_PLUGIN_MAXIMIZE, new_rect->x, new_rect->y, @@ -1328,8 +1324,7 @@ meta_window_actor_unmaximize (MetaWindowActor *self, self->priv->unmaximize_in_progress++; meta_window_actor_freeze (self); - if (!info->plugin_mgr || - !meta_plugin_manager_event_maximize (info->plugin_mgr, + if (!meta_plugin_manager_event_maximize (info->plugin_mgr, self, META_PLUGIN_UNMAXIMIZE, new_rect->x, new_rect->y, From 43a409dec4092f41c6eb0ded55853e2d9980f3d4 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 18:55:32 -0400 Subject: [PATCH 694/889] window: Don't sync window geometry when we haven't shown it yet --- src/core/window.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/core/window.c b/src/core/window.c index 38aaf11fd..480aa3deb 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -4970,9 +4970,10 @@ meta_window_move_resize_internal (MetaWindow *window, newx, newy, window->rect.width, window->rect.height, window->user_rect.x, window->user_rect.y, window->user_rect.width, window->user_rect.height); - meta_compositor_sync_window_geometry (window->display->compositor, - window, - did_placement); + if (window->visible_to_compositor) + meta_compositor_sync_window_geometry (window->display->compositor, + window, + did_placement); } else { From ff635bad3b72c70120a9bf4f78e8bdfb71fe6f0b Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 20:28:18 -0400 Subject: [PATCH 695/889] Clean up the source tree Remove a lot of old, unmaintained files --- AUTHORS | 1 - COMPLIANCE | 159 - ChangeLog | 15414 ------------------------- Doxyfile | 1297 --- HACKING | 298 - MAINTAINERS | 8 - METACITY_MAINTAINERS | 43 - README | 416 - rationales.txt => doc/rationales.txt | 0 src/run-mutter.sh | 109 - stamp.h.in | 0 test/tokentest/Makefile | 7 - test/tokentest/README | 19 - test/tokentest/get-tokens.py | 89 - test/tokentest/tokentest.c | 304 - test/tokentest/tokentest.ini | 1873 --- tools/xlib.py | 43 - 17 files changed, 20080 deletions(-) delete mode 100644 AUTHORS delete mode 100644 COMPLIANCE delete mode 100644 ChangeLog delete mode 100644 Doxyfile delete mode 100644 HACKING delete mode 100644 MAINTAINERS delete mode 100644 METACITY_MAINTAINERS delete mode 100644 README rename rationales.txt => doc/rationales.txt (100%) delete mode 100755 src/run-mutter.sh delete mode 100644 stamp.h.in delete mode 100644 test/tokentest/Makefile delete mode 100644 test/tokentest/README delete mode 100644 test/tokentest/get-tokens.py delete mode 100644 test/tokentest/tokentest.c delete mode 100644 test/tokentest/tokentest.ini delete mode 100644 tools/xlib.py diff --git a/AUTHORS b/AUTHORS deleted file mode 100644 index 9971ab08a..000000000 --- a/AUTHORS +++ /dev/null @@ -1 +0,0 @@ -Havoc Pennington diff --git a/COMPLIANCE b/COMPLIANCE deleted file mode 100644 index b45a6724f..000000000 --- a/COMPLIANCE +++ /dev/null @@ -1,159 +0,0 @@ -Metacity Standards Compliance -============================= -$Id$ - -1) Introduction -2) EWMH Compliance - a. Root Window Properties - b. Root Window Messages - c. Application Window Properties - d. Window Manager Protocols -3) ICCCM Compliance - -1) Introduction ---------------- - -This document details metacity compliance with the relevent standards. -The format of this document is as follows: - -[-/+?] Hint Name/Feature Name (Version number) - Errata/Comments - -The first character indicates the level of compliance as follows: - - none - / partial - + complete - ? unknown - -The title indicates a feature or a hint in the specification, and the -version number indicates the minimum version of the specification -supported by metacity. Later versions may be supported if no -incompatible changes have been made in the specification. - -2) EWMH Compliance ------------------- - -The EWMH, or Extended Window Manager Hints is a freedesktop.org- -developed standard to support a number of conventions for -communication between the window manager and clients. It builds on -and extends the ICCCM (See Section 3). A copy of the current EWMH -standard is available at http://freedesktop.org/Standards/wm-spec/ - - a. Root Window Properties - ------------------------- - -+ _NET_SUPPORTED (1.3) - -+ _NET_CLIENT_LIST (1.3) - -+ _NET_NUMBER_OF_DESKTOPS (1.3) - -+ _NET_DESKTOP_GEOMETRY (1.3) - Metacity does not implement large desktops, so this is kept set to - the screen size. - -+ _NET_DESKTOP_VIEWPORT (1.3) - Metacity does not implement viewports, so this is a constant (0,0). - -+ _NET_CURRENT_DESKTOP (1.3) - -+ _NET_DESKTOP_NAMES (1.3) - -+ _NET_ACTIVE_WINDOW (1.3) - -+ _NET_WORKAREA (1.3) - -+ _NET_SUPPORTING_WM_CHECK (1.3) - -+ _NET_VIRTUAL_ROOTS (1.3) - Metacity does not read or set this property, but it does not use - virtual roots to implement virtual desktops, so it complies with the - specification. - -+ _NET_DESKTOP_LAYOUT (1.3) - -+ _NET_SHOWING_DESKTOP (1.3) - - b. Root Window Messages - ----------------------- - -+ _NET_CLOSE_WINDOW (1.3) - -- _NET_MOVERESIZE_WINDOW (1.3) - Metacity supports this message, but the specification is unclear on - the layout of the detail value, and as such it is #if 0'd in the code - -+ _NET_WM_MOVERESIZE (1.3) - -- _NET_RESTACK_WINDOW (1.3) - Metacity will raise or lower windows in response to this message, - but the sibling restack modes are not supported, and it is currently - #if 0'd in the code. - -+ _NET_REQUEST_FRAME_EXTENTS (1.3) - - c. Application Window Properties - -------------------------------- - -+ _NET_WM_NAME (1.3) - -+ _NET_WM_VISIBLE_NAME (1.3) - Metacity does not set this property, but metacity will never display - a name different from _NET_WM_NAME - -+ _NET_WM_ICON_NAME (1.3) - -+ _NET_WM_VISIBLE_ICON_NAME (1.3) - Metacity does not set this property, but metacity will never display - a name different from _NET_WM_NAME - -+ _NET_WM_DESKTOP (1.3) - -+ _NET_WM_WINDOW_TYPE (1.3) - -/ _NET_WM_STATE (1.3) - This property is read and updated according to the specification, - but see caveat below. - Metacity does not recognize separate vertical and horizontal - maximization states. Currently metacity will do a two-dimensional - maximization if either property is set. - See: http://bugzilla.gnome.org/show_bug.cgi?id=113601 - Metacity doesn't implement viewports so _NET_WM_STATE_STICKY is - unimplemented. - -+ _NET_WM_ALLOWED_ACTIONS (1.3) - Metacity keeps this hint up to date. The code is somewhat crufty - and should be rewritten, though it is functional. - See: http://bugzilla.gnome.org/show_bug.cgi?id=90420 - -+ _NET_WM_STRUT (1.3) - -+ _NET_WM_STRUT_PARTIAL (1.3) - -+ _NET_WM_ICON_GEOMETRY (1.3) - Metacity uses this property to draw minimize/restore animations - -+ _NET_WM_ICON (1.3) - -+ _NET_WM_PID (1.3) - -+ _NET_WM_HANDLED_ICONS (1.3) - Metacity does not read or set this property. However, metacity - never manages iconified windows, and so has no need to do so. - -+ _NET_WM_USER_TIME (1.3) - Metacity uses this property to prevent applications from stealing - focus if supported by the toolkit. - -+ _NET_FRAME_EXTENTS (1.3) - If set in response to a _NET_REQUEST_FRAME_EXTENTS message received - prior to the window being mapped, this may be an estimate. This is, - however, expressly allowed by the specification. - - d. Window Manager Protocols - --------------------------- -+ _NET_WM_PING (1.3) - -3) ICCCM Compliance -------------------- -TODO \ No newline at end of file diff --git a/ChangeLog b/ChangeLog deleted file mode 100644 index e68822de0..000000000 --- a/ChangeLog +++ /dev/null @@ -1,15414 +0,0 @@ -2009-03-16 Thomas Thurman - - * NEWS: 2.26.0 release. - -2009-02-04 Neil Jagdish Patel - - * src/core/frame.c: queue resize on window undecorate - -2009-02-03 Luca Ferretti - - * src/include/all-keybindings.h: Fix description, focus the - desktop, not desktop backgroung (Closes bug #569649) - -2009-02-02 Matt Kraai - - * src/core/schema-bindings.c: Wrap g_error calls in braces. - -2009-02-01 Thomas Thurman - - * configure.in: Post-release bump to 2.25.233. - -2009-02-01 Thomas Thurman - - * NEWS: 2.25.144 release. - -2009-02-01 Matt Kraai - - Set prop_hooks_table to NULL after freeing it. - - * src/core/window-props.c: - -2009-01-29 Thomas Thurman - - Window properties are looked up in a hash table rather than - by iteration over an array. Saves ~44us per window, but - also makes the code cleaner. - - * src/core/display-private.h: - * src/core/window-props.c: - -2009-01-27 Matthias Claesen - - * src/core/edge-resistance.c: some lists failed to keep track - of their contents and therefore didn't free correctly. - Closes #552303. - -2009-01-27 Matthias Claesen - - * src/core/prefs.c: Free name of old theme when new theme - is loaded. Closes #552973. - -2009-01-27 Matthias Claesen - - * src/ui/ui.c: free the result of gdk_text_property_to_utf8_list() - even when it returns no data. - -2009-01-27 Owen Taylor - - GtkStyle is specific to a particular colormap. Metacity - uses different colormaps for windows with different - visuals, so it must specialize the GtkStyle. - - Closes #568365 and #513944. - - * src/ui/frames.[ch]: Keep a GtkStyle for each MetaUIFrame, which is - obtained by calling gtk_style_attach() on the style for the - MetaFrames. When the style of the MetaFrames changes, reattach - everything. When we call gtk_style_set_background() pass in the - right style. - - * src/ui/themes.[ch]: Create a _with_style() variant of functions that - previously took the style from widget->style passed in, so we - can draw with the right style for the colormap. - -2009-01-27 Thomas Thurman - - Added a gconf key to swap the meanings of the right and - middle buttons when the modifier key is held down. - Closes #437910. Thanks to Matt Kraai for looking over - the patch. - - * src/core/display.c: - * src/core/prefs.c: - * src/include/prefs.h: - * src/metacity.schemas.in.in: - -2009-01-27 Thomas Thurman - - All the window properties are now handled using simple - window property handlers. Closes #549886. - - * src/core/window-private.h: - * src/core/window-props.c: - * src/core/window.c: - -2009-01-26 Thomas Thurman - - More of the window properties are checked using simple - window property handlers. The ones which remain don't - actually look up the new value in the ordinary way, and - so are a little trickier to merge. Added an "initial" - flag to be on the safe side that the behaviour is the - same as before (so we don't do things when a window's - first mapped that we only used to do when a property - changed). Partial fix for bug #549886. - - * src/core/window-props.c: - * src/core/window-props.h: - * src/core/window.c: - -2009-01-25 Elijah Newren - - * src/core/window.c: add support for _NET_WM_MOVERESIZE_CANCEL. - -2009-01-10 Thomas Thurman - - * src/ui/theme.[ch]: add meta_theme_draw_frame_by_name, which - is needed for the theme editor. - -2008-12-26 Thomas Thurman - - * configure.in: Post-release bump to 2.25.144. - -2008-12-26 Thomas Thurman - - * NEWS: 2.25.89 release. - -2008-12-25 Thomas Thurman - - * src/include/all-keybindings.h: alt-F10 toggles maximisation, - alt-F5 only restores. Also rename "unmaximize" to "restore". - * src/ui/frames.c: Rename "unmaximize" to "restore". - Closes #343824. - -2008-12-25 Frederic Peters - - * src/core/main.c: (main): added call to g_thread_init(), as ORBit2 - stopped doing it and Metacity is using gconf; closes #565517. - -2008-12-24 Yanko Kaneti - - * src/metacity.schemas.in.in: add screenshot commands which had - mistakenly been removed; closes #564343, Launchpad bug 298463, - Red Hat bug 474635, and probably others. - -2008-12-24 Thomas Thurman - - * src/include/all-keybindings.h: fix move_to_corner_se - -2008-12-21 Colin Walters - - * src/core/window.c: windows which attempt to present themselves - but are offscreen end up demanding attention, unless they - are transient, when they move to the current workspace - as before. Closes #482354. - -2008-12-19 Thomas Thurman - - * src/ui/frames.c: when the user double-clicks the title bar, - end the grab op. Closes #401028. - -2008-12-16 Thomas Thurman - - * configure.in: Post-release bump to 2.25.89. - -2008-12-16 Thomas Thurman - - * NEWS: 2.25.55 release. - -2008-12-15 Erwann Chenede - - * configure.in: fix build on Solaris. Closes #564123. - -2008-12-02 Thomas Thurman - - * configure.in: Post-release bump to 2.25.55. - -2008-12-02 Thomas Thurman - - * NEWS: 2.25.34 release. - -2008-12-02 Matt Kraai - - * src/core/iconcache.c: patches to fixes for -Wall. Closes #562939. - -2008-12-01 Thomas Thurman - - * configure.in: Post-release bump to 2.25.34. - -2008-12-01 Thomas Thurman - - * NEWS: 2.25.21 release. - -2008-12-01 Thomas Thurman - - * configure.in: gnome-doc-tools version doesn't need to be so high. - * src/compositor/compositor-xrender.c: disable the entire file if the - compositor is disabled. - * src/core/async-getprop.[ch]: fixes for -Wall - * src/core/iconcache.c: fixes for -Wall - * src/core/testasyncgetprop.c: fixes for -Wall - * src/core/xprops.c: fixes for -Wall - -2008-11-26 Thomas Thurman - - * tools/announce-wrangler.py: linked language codes to po files - * tools/commit-wrangler.py: print revision url - -2008-11-26 Thomas Thurman - - * tools/announce-wrangler.py: renamed ini file - * tools/commit-wrangler.py: rewriting in terms of moap - -2008-11-25 Thomas Thurman - - * configure.in: Post-release bump to 2.25.21. - -2008-11-25 Thomas Thurman - - * NEWS: 2.25.13 release. - -2008-11-26 Thomas Thurman - - * tools/announce-wrangler.py (added): script to produce announcements - -2008-11-26 Thomas Thurman - - * src/core/xprops.c: add casts (#562106) - -2008-11-25 Thomas Thurman - - * metacity.doap: change to standard description. - -2008-11-23 Thomas Thurman - - * configure.in: Post-release bump to 2.25.13. - -2008-11-23 Thomas Thurman - - * NEWS: 2.25.8 release. - -2008-11-23 Thomas Thurman - - * po/POTFILES.in: add new bindings file - -2008-11-23 Daniel Macks - - reviewed by: Thomas Thurman - - * src/Makefile.am: reorder compiler flags so local includes come last. - Closes #562033. - -2008-11-23 Daniel Macks - - reviewed by: Thomas Thurman - - * configure.in: only accept --enable-compositor if we find we can - actually composite. Closes #560990. - -2008-11-23 Thomas Thurman - - * src/core/display.c: remove apparently spurious warnings about - operations on window "none" - -2008-11-23 Thomas Thurman - - * src/core/util.c: Set _POSIX_C_SOURCE to 200112L as it should always - have been, in an attempt to close #561962. - -2008-11-22 Thomas Thurman - - * configure.in: Set -ansi so people stop complaining about C99. - -2008-11-22 Thomas Thurman - - * src/core/prefs.c: fix stupid infinite loop when GConf is turned off. - -2008-11-22 Thomas Thurman - - * src/core/prefs.c: fix two places where there was a warning - if GConf was turned off. - -2008-11-22 Thomas Thurman - - * src/core/all-keybindings.h: "backward", not "backwards" throughout. - -2008-11-20 Thomas Thurman - - * configure.in: turned on -Wall and -Werror in order to - trap as many problems as possible. - * src/ui/resizepopup.c: added correct #include. - * src/ui/theme-viewer.c: initialised variable. - * src/core/xprops.c: corrected cast. - * src/core/main.c: added warning if chdir() fails. - * src/core/schema-bindings.c: checking the return - result of fgets(). - -2008-11-20 Thomas Thurman - - Merged screen and window keybinding tables so that - we can use just one file for the both. Also incidentally - closes #528337. Further efficiencies of scale to come. - - * src/include/prefs.h: replace META_PREF_*_KEYBINDINGS - with META_PREF_KEYBINDINGS - * src/core/keybindings.c: replace *_bindings with key_bindings - and similar throughout; all window-based functions are now - guaranteed to receive a window so don't need to check for - themselves - (find_handler): moved so it can also be called from - rebuild_binding_table - * src/core/display-private.h: replace *_bindings with key_bindings - * src/core/prefs.c: update_*_binding becomes update_key_binding; - (change_notify): tidy up references to "enormous if statement" - since it's almost entirely gone now - * src/core/all-keybindings.h: new merged version of - screen-bindings.h and window-bindings.h. - -2008-11-16 David Trowbridge - - This change adds support for the new _NET_WM_FULLSCREEN_MONITORS - property and client message. This allows client applications to request - that a fullscreen window cover more than one monitor. - - * src/include/boxes.h: - * src/core/boxes.c: Add meta_rectangle_union - - * src/core/window-private.h: - * src/core/window.c: - (meta_window_new_with_attrs, meta_window_free, set_net_wm_state, - meta_window_update_fullscreen_monitors, meta_window_client_message): Add - MetaWindow property to store fullscreen monitors field, update - _NET_WM_FULLSCREEN_MONITORS property on windows, and handle client - message. - - * src/core/atomnames.h: Add _NET_WM_FULLSCREEN_MONITORS atom. - - * src/core/constraints.c (setup_constraint_info): If - _NET_WM_FULLSCREEN_MONITORS is interesting, use the data stored in - MetaWindow::fullscreen_monitors to determine the fullscreen area instead - of the basic xinerama_info area. - -2008-11-11 Thomas Thurman - - Removed deprecated calls. Closes #560445. - - * src/core/delete.c: remove deprecated g_strcasecmp. - * src/include/main.h: no actual deprecated call, but - a mention of one which was out of date. - -2008-11-11 Maxim Ermilov - - Clean up #includes according to the GNOME Goal. - Closes #560449. Patch is 122467. - - * src/core/place.c: - * src/ui/draw-workspace.h: - * src/ui/gradient.h: - * src/ui/metaaccellabel.c: - * src/ui/metaaccellabel.h: - * src/ui/preview-widget.c: - * src/ui/preview-widget.h: - * src/ui/resizepopup.c: - * src/ui/theme.c: - * src/ui/theme.h: - * src/ui/themewidget.h: - -2008-11-10 Elijah Newren - - * src/metacity.schemas.in.in: updated description of - raise_on_click: - http://bugzilla.gnome.org/show_bug.cgi?id=445447#c6 - -2008-11-08 Thomas Thurman - - * configure.in: added dependency on Zenity - * src/core/keybindings.c: remove error_on_generic_command() and - error_on_terminal_command(); rewrite error_on_command - in terms of meta_show_dialog() - * src/core/util.c: add meta_show_dialog() to call Zenity - * src/include/util.h: ditto - -2008-11-03 Olav Vitters - - * src/ui/theme-parser.c: Fix build by readding accidentally removed - '}'. - -2008-10-29 Thomas Thurman - - * src/ui/theme-parser.c: variable names in messages should be - double-quoted. Closes #558309. - -2008-10-28 Thomas Thurman - - * src/include/screen-bindings.h: fix accidental name change of - run_command_terminal. Closes #557943. - -2008-10-27 Thomas Thurman - - * src/core/prefs.c (titlebar_handler, handle_preference_update_enum): - Add initialisation which I missed on the previous checkin. Also - an extra comment. - -2008-10-27 Brian Cameron - - Fix some crashes with the new GDM 2.24. Closes #558058. - - * src/ui/ui.c (meta_ui_parse_modifier): another null check - * src/core/prefs.c (titlebar_handler, button_layout_handler): - more null checks. - -2008-10-26 Thomas Thurman - - * src/core/prefs.c (mouse_button_mods_handler): Ignore values - of .../mouse_button_modifier key if the key's missing. - Closes Launchpad bug #258054, Launchpad bug #266929. - -2008-10-23 Frederic Peters - - * doc/creating_themes/C/creating-metacity-themes.xml: added missing @id - on top element. - -2008-10-23 Frederic Peters - - * doc/creating_themes/Makefile.am: - * doc/creating_themes/C/creating_metacity_themes.xml: renamed document - to creating-metacity-themes to match other manuals usage of dashes. - -2008-10-23 Thomas Thurman - - * configure.in: Post-release bump to 2.25.8. - -2008-10-23 Thomas Thurman - - * NEWS: 2.25.5 release. - -2008-10-23 Thomas Thurman - - * src/core/schema-bindings.c: fix stupid thinko which - caused defaults to be incorrect - * src/include/window-bindings.h: "space" needs to be - lowercase - -2008-10-23 Thomas Thurman - - Support _NET_WM_STATE_STICKY (i.e. allow third-party apps to decide - whether a window is on all workspaces). Bug found by Ka-Hing - Cheung. Closes #557536. - - * src/core/window.c (set_net_wm_state): report it - * src/core/window.c (meta_window_client_message): set sticky - if we receive it - * src/core/window-props.c: set sticky if we find it - * src/core/atomnames.h: add _NET_WM_STATE_STICKY - -2008-10-22 Thomas Thurman - - * src/core/schema-bindings.c: support builds outside tree properly. - * src/Makefile.am: ditto. - * po/POTFILES.skip: ditto. - -2008-10-22 Thomas Thurman - - * configure.in: Post-release bump to 2.25.5. - -2008-10-22 Thomas Thurman - - * NEWS: 2.25.3 release. - -2008-10-22 Thomas Thurman - - * configure.in: bump to 2.25.3 (thought the release script - had already done this) - -2008-10-22 Thomas Thurman - - Fixes to make distcheck work again. - - * src/Makefile.am: include *-binding.h, and make the schema - building work when builddir != srcdir - * po/POTFILES.in (src/core/keybindings.): include *-binding.h - -2008-10-22 Götz Waschk - - * configure.in: add libm reference. Closes #557357. - -2008-10-22 Murray Cumming - - * doc/creating_themes/C/creating_metacity_themes.xml: - Fixed various tags to make this validate. - Bug #557337 - -2008-10-22 Thomas Thurman - - * NEWS: 2.25.2 release. - -2008-10-22 Thomas Thurman - - * NEWS: 2.25.2 release. - -2008-10-22 Thomas Thurman - - * NEWS: 2.25.2 release. - -2008-10-22 Joe Marcus Clarke - - * src/core/main.c (meta_finalize, sigterm_handler): new functions - * src/core/main.c (main): add sigterm_handler in case we receive - a SIGTERM. Closes #553980. - -2008-10-22 Matthew Martin - - * src/core/window.c (meta_window_set_demands_attention): minimised - windows are necessarily obscured. Closes #528927. - -2008-10-22 Thomas Thurman - - Slight transformation of the x-macros used in keybindings - to make them clearer: write handler names out in full - because the old suffix system was confusing to people - skim-reading, and switched the order of the last two - parameters so more would generally fit on a screen. - - * src/core/keybindings.c, src/core/schema-bindings.c - src/core/prefs.c: sympathy changes - * src/core/window-bindings.h, src/core/screen-bindings.h: - transformation as above - -2008-10-21 Christian Persch - - * src/Makefile.am: fix build when schemas are not installed. - Closes #557335. - -2008-10-21 Tomas Frydrych - - * src/core/screen-bindings.h: Fix off-by-one error. - * src/core/window-bindings.h: Fix off-by-one error. - Closes #557201. - -2008-10-18 Thomas Thurman - - During a discussion with Rodney Dawes about making life easier - for the translators, he pointed out that the short and long - forms of almost all the keybindings say much the same thing - in different words. I believe this is an unconscionable burden - to place on translators, and have therefore merged the short - and long descriptions into the short description. The long - is now a general explanation of the format, plus possibly a - notice about reversibility. Closes #469361, and should solve - the l10n issue previously mentioned. - - * src/core/keybindings.c: reflect changes in *-bindings.h - * src/core/schema-bindings.c: reflect changes in *-bindings.h - * src/core/prefs.c: reflect changes in *-bindings.h - * src/core/window-bindings.h: Add flags field, always the same - currently, so that it's the same as screen-bindings.h. - Also, lose ONLY_BOUND_BY_DEFAULT, since we already had a - rather more elegant way to perform the same effect. - And merge the long and short descriptions. - * src/core/screen-bindings.h (, item): Merge the long and - short descriptions. - -2008-10-17 Murray Cumming - - * configure.in: Call GNOME_DOC_INIT() so we can use the gnome-doc-utils - variables in our Makefile.am: - * doc/Makefile.am: - * doc/creating_themes/Makefile.am - * doc/creating_themes/C/creating_metacity_themes.xml: - Added this new DocBook document, converted from the HTML here - http://blogs.gnome.org/metacity/2008/05/30/themes/ - This will be installed for yelp and can be translated and hosted on - library.gnome.org. - -2008-10-15 Thomas Thurman - - Since Patrick Niklaus's checkin of 2008-08-14 dealt with windows with - no icons not using fallback icons, we don't need fallback icons. - - * src/ui/theme.h: remove fallback icons from struct. - * src/core/iconcache.c (meta_read_icons): don't look for fallbacks. - * src/*/ui.[ch] (meta_ui_get_fallback_icons): removed - * src/ui/theme-parser.c (typedef, parse_toplevel_element): don't - parse fallback specifications. - -2008-10-13 Thomas Thurman - - * po/POTFILES.in: add screen-bindings.h - -2008-10-13 Thomas Thurman - - * po/POTFILES.in: raw schemas is now .in.in - * po/LINGUAS: add Latin - -2008-10-12 Thomas Thurman - - Make the bindings in src/core/*-bindings.h generate - GConf schemas too. Note that there's an i18n issue - (documented in schema-bindings.c) which will be fixed - next checkin. - - * src/core/schema-bindings.c: major fixup to make it - ready for use as part of the actual build process. - * src/Makefile.am: added magic to make it call schema-bindings - after it builds it. - * src/core/window-bindings.h: added comments; - also, window menu was listed variously as alt-Space - and alt-Print; it should have been alt-Space. - * src/metacity.schemas.in.in: renamed from s/\.in$//, - sentinel added for the generated bindings, - warning at the top now untrue, and removed. - -2008-10-12 Thomas Thurman - - Fix annoying bug where alt-tab and friends would jump - backwards a space on initial movement. - - * src/core/screen-bindings.h: although reversed bindings - are necessarily reversible, don't set both bits in the - constant, or when we test for them we'll get confused. - -2008-10-12 Thomas Thurman - - An attempt to make life a little easier for our beloved translators; - this has the same behaviour as before, but removes over thirty - translation strings. - - * src/core/session.c (start_element_handler): all "attribute not found - on element" strings are identical - * src/ui/theme-parser.c (locate_attributes): allow attribute names to - be preceded with "!" (in the code) to show they're required. - (parse_aspect_ratio, parse_distance, parse_toplevel_element, - parse_style_element, parse_gradient_element, static, parse_border, - parse_style_set_element, parse_draw_op_element): use the new "!" - prefix for locate_attributes(), or in some cases just the identical - constant, for generating this error. - * src/ui/theme.c (check_state, meta_theme_validate): add - translator comments - * src/ui/resizepopup.c (update_size_window): add - translator comments - -2008-10-06 William Lachance - - Pass modified mouse button events down to panel windows - instead of dealing with them ourselves. Closes #554428. - - * src/core/display.c (prefs_changed_callback): don't grab mouse - buttons on panels - * src/core/window.c (meta_window_new_with_attrs): ditto - -2008-10-05 Thomas Thurman - - Second half of the switch to using x-macros for keybindings so that - we don't have lots of places with the same information which must - stay in the same order. This time it's screen bindings. - - * src/core/screen-bindings.h: New file, containing screen bindings. - * src/core/schema-bindings.c: added ability to output screen bindings. - * src/core/window-bindings.h: tiny tweak to comment - * src/core/keybindings.c: generate function prototypes using s-b.h; - several handlers modified to use ints rather than ints cast into - pointers, or renamed. - * src/include/prefs.h: generate names of bindings using s-b.h; - generate screen_handlers using s-b.h; - arguments to bindings are ints and not ints cast to pointers; - several handler functions renamed to consistent names. - * src/core/prefs.c (meta_prefs_set_num_workspaces, init_bindings): - generate screen_handlers using s-b.h; - generate screen_string_bindings using s-b.h (and add check for - null bindings in init_bindings to enable this simply). - -2008-10-05 Thomas Thurman - - * tools/ppa-magic.py: experimental tool for Launchpad upload - -2008-10-05 Thomas Thurman - - * metacity.doap: Havoc is an author; Thomas has an email address; - add a ton of release information going back to the early days, - although not right to the beginning. - -2008-09-26 Thomas Thurman - - * autogen.sh: not all versions of /bin/sh can handle this script, - so specify one. Also update the error message because we don't - use CVS these days. - -2008-09-20 Thomas Thurman - - * po/POTFILES.in: fix name of window-bindings.h - -2008-09-20 Thomas Thurman - - * po/POTFILES.in: added new files and re-sorted - -2008-09-12 Vincent Untz - - Install desktop files in both - .../share/applications and .../share/gnome/wm-properties. - Copied in from the 2.23.x branch. Closes #549479. - - * src/metacity-wm.desktop.in: new file - * src/.cvsignore: include the above - * src/Makefile.am: install the above - -2008-09-06 Thomas Thurman - - An attempt to keep all information about window bindings - in the same place. Screen bindings to come. - - * src/core/window-bindings.h: new file, list of all window bindings - * src/include/prefs.h: drop all the existing window-binding macros - - * src/core/schema-bindings.c (): output all the schema blocks that - would appear in metacity.schema for these window bindings. This - ought to become part of the build process, and hopefully will soon. - When this works it will also close #469361. - - * src/core/keybindings.c: generate handle_* prototypes using - x-macros; populate window_handlers using x-macros; rename several - functions to have consistent names; do_handle_move_to_workspace(), - handle_move_to_workspace_flip(), and handle_move_to_workspace() all - merged into handle_move_to_workspace. - - * src/core/prefs.c: generate window_bindings and window_string_bindings - using x-macros; (meta_prefs_set_compositing_manager) fix unrelated - problem with use of GConf functions when GConf was disabled. - - * src/core/core.c (meta_core_get_menu_accelerator): binding names - given as literals since this is the only place in the code they - now appear - - -2008-09-03 Thomas Thurman - - * src/metacity.desktop.in: removed invalid "Window Manager" group - at request of Matthias Clasen. - -2008-09-02 Thomas Thurman - - Desktop file moved, according to policy change. Closes #549479. - - * src/metacity.desktop.in: Don't display the desktop file - * src/Makefile.am: Desktop file goes in apps directory - -2008-09-01 Thomas Thurman - - * configure.in: Post-release bump to 2.25.2. - -2008-09-01 Thomas Thurman - - * NEWS: 2.25.1 release. - -2008-09-01 Thomas Thurman - - * src/core/workspace.c: When a workspace's list of struts - is freed, free the struts too. Closes #549952, and #468075. - -2008-09-01 Thomas Thurman - - Add new move_to_center keybinding, requested by Khanh-Dang Nguyen - Thu Lam; closes #549979. - - * src/include/prefs.h (void): add name of new binding - * src/core/prefs.c: added pref for it - * src/core/keybindings.c (handle_move_to_center): new function - * src/metacity.schemas.in: included new binding - -2008-08-31 Thomas Thurman - - * src/core/prefs.[ch] (meta_prefs_set_compositing_manager): new - function. - * src/core/main.c (meta_parse_options): turn the compositing - manager on or off as necessary. - -2008-08-30 Thomas Thurman - - * src/core/window.c (process_property_notify): moving all - messages about properties to the top, as a start at #549886 - -2008-08-18 Thomas Thurman - - * NEWS: fix version number which broke - -2008-08-18 Thomas Thurman - - * configure.in: Post-release version bump to 2.25.1. - -2008-08-18 Thomas Thurman - - * configure.in: correct incorrect version number - -2008-08-18 Thomas Thurman - - * NEWS: 2.25.1 release. - -2008-08-18 Thomas Thurman - - Adding doxygen headers to some files. - - * src/core/metacity-Xatomtype.h - * src/core/main.c - * src/core/screen-private.h - * src/core/window-private.h - * src/core/keybindings.h - * src/core/session.h - * src/core/workspace.h - * src/core/window-props.h () - -2008-08-18 Eric Piel - - * src/core/workspace.c (ensure_work_areas_validated): add a copy of - each strut in a window to the workspace's strut list, instead of - using the copy in the list (which would mean it was double-freed). - Believed to fix #468075. - -2008-08-16 Ted Percival - - Ensure the user_rect is set sanely for windows that start maximized. - Prevents maximized windows from warping across the screen. - Fixes bug #504692. - - * src/core/window.c (save_user_placement): renamed version of - meta_window_save_user_rect(). - * src/core/window.c (force_save_user_placement): similar, but will - always save user_rect even if the window is maximised or fullscreen. - * src/core/window.c (meta_window_move_resize_internal): unplaced - windows have force_save_user_placement() called instead of - save_user_placement(). - -2008-08-14 Patrick Niklaus - - Icons for windows are taken from the desktop theme, not from - the Metacity theme or from the fallback icon that Metacity - provided. Closes #524343. - - * src/ui/ui.c: Use GtkIconTheme to load the default window icon. - Assumes the existence of an icon called "window", otherwise - falls back to "gtk-missing-image". Fixes #524343. - * src/ui/preview-widget: See above. - * src/include/common.h: Add META_DEFAULT_ICON_NAME. - * src/Makefile.am: Remove default_icon.png from inlinepixbufs.h. - * src/default_icon.png: Removed. - -2008-08-14 Akira TAGOH - - * doc/man/metacity-message.1: new manual page. - * doc/man/Makefile.am: added new reference. - -2008-08-13 Thomas Thurman - - * configure.in: Post-branch bump to 2.25.0. - -2008-08-04 Thomas Thurman - - * configure.in: Post-release bump to 2.23.144. - -2008-08-04 Thomas Thurman - - * NEWS: 2.23.89 release. - -2008-07-26 Thomas Thurman - - * metacity.doap (added): DOAP file (first pass, anyway). - -2008-07-14 Thomas Thurman - - * configure.in: Post-release bump to 2.23.89. - -2008-07-14 Thomas Thurman - - * NEWS: 2.23.55 release. - -2008-07-13 Thomas Thurman - - * src/core/display.c (event_callback): meta_display_screen_for_root() - can return NULL, so check for that. Fixes #422242. Also tidying. - -2008-07-13 Elijah Newren - - * src/core/workspace.c (meta_workspace_free): Don't attempt to - double-free struts, edges and regions if work areas have already - been invalidated at the time of freeing a workspace. - Possible fix to #361804. - -2008-07-12 Thomas Thurman - - * src/core/constraints.c (do_screen_and_xinerama_relative_constraints): - Don't allocate memory for log messages unless we're logging. - -2008-07-12 Thomas Thurman - - * src/core/group.c (meta_window_get_group): This function can now - officially return NULL. - * src/core/window.c (meta_window_same_application): Two windows can't - belong to the same application unless they both belong to some - application. (Both belonging to no application is not the same.) - -2008-06-30 Thomas Thurman - - * src/core/bell.c (meta_bell_set_audible): Fix typo that - slipped through. - -2008-06-30 Thomas Thurman - - * src/core/bell.[ch]: Move comments for non-statics from the .c to .h. - * Doxyfile: adapt better for C, and make quiet. - -2008-06-29 Thomas Thurman - - * src/ui/theme-viewer.c (main): display the theme name - in the title bar. Closes #430198. - -2008-06-29 Thomas Thurman - - Allow toggling of non-compositor effects (since there's a - non-Metacity key to do so: /desktop/gnome/interface/enable_animations). - Closes #92867. - - * src/include/prefs.h: add META_PREFS_GNOME_ANIMATIONS key and - meta_prefs_get_gnome_animations() function - * src/include/prefs.c: added meta_prefs_get_gnome_animations() - function, and made supporting changes to structs. - * src/core/effects.c (run_handler): checked whether enable_animations - is set before running an effect. - * src/core/effects.c (meta_effect_run_minimize): remove debug message. - -2008-06-29 Thomas Thurman - - * src/core/bell.c: remove meta_ prefix on all static functions. - -2008-06-29 Thomas Thurman - - * src/core/stack.c (stack_sync_to_server): lose meta prefix - since it's static. - * src/core/stack.c (meta_stack_remove, stack_do_window_deletions): - replace our own cast with glib macro designed to do the same thing - -2008-06-28 Thomas Thurman - - * src/core/display.c, src/compositor/compositor-xrender.c: add checks - for HAVE_SHAPE where appropriate. - * src/core/xprops.c: fix type error which was causing warnings. - -2008-06-28 Thomas Thurman - - Some refactoring, simplifying, and commenting of the non-composited - effects code. effects.c could still do with some polish, which will - come along later. - - * src/core/effects.h (meta_push_effect_handler): removed since it's - never used and does nothing very useful. - * src/core/effects.h (meta_pop_effect_handler): removed since its - only effect is to crash the program. - * src/core/effects.h (META_MINIMIZE_ANIMATION_LENGTH, - META_SHADE_ANIMATION_LENGTH): move to effects.c because they're used - nowhere else. - * src/core/effects.c: there were three versions of the box-zoom effect. - Remove the one which was never used, and make only the ones which - are used with certain configure settings be compiled. - * src/core/effects.h (meta_effect_end): move to effects.c, make static, - and rename to effect_free. - * src/core/effects.h (meta_effects_draw_box_animation): move to - effects.c, make static, and rename to draw_box_animation. - * src/core/effects.h (MetaEffectType): remove the values which weren't - used. - * src/core/window.c (meta_window_shade): remove commented-out code to - call effect for shading. - * src/core/effects.h (MetaEffectFinish): remove useless MetaEffect - parameter. - * src/core/window.c (finish_minimize): remove MetaEffect parameter. - -2008-06-27 Thomas Thurman - - * src/core/stack.h: Commented everything. - -2008-06-26 Thomas Thurman - - Keep the compiler from giving some warnings. - - * src/compositor/compositor-xrender.c (xrender_begin_move, - xrender_update_move, xrender_end_move, xrender_free_window): four - functions which were never called and contain no code #iffed out. - * src/tools/metacity-mag.c (grab_area_at_mouse): fixed typecast error. - -2008-06-26 Thomas Thurman - - Refactor so the long scary stack functions are less long and scary: - - * stack.c (stack_ensure_sorted): the five parts of this long function - broken out into the new functions stack_do_window_deletions, - stack_do_window_additions, stack_do_relayer, stack_do_constrain - (which was already separate: see next) and stack_do_resort. - * stack.c (constrain_stacking): renamed to stack_do_constrain. - * stack.c (stack_ignore_sorted): lose meta prefix since it's static. - -2008-06-16 Thomas Thurman - - * configure.in: Post-release bump to 2.23.55. - -2008-06-16 Thomas Thurman - - * NEWS: 2.23.34 release. - -2008-06-16 Thomas Thurman - - * NEWS: 2.23.34 release. - -2008-06-13 Thomas Thurman - - * src/core/window-props.c: Some commenting. - - * src/core/prefs.c: Added unified handling of integer preferences. - Re-ordered fields in existing preferences so that changing to - a union-based system will be easier in the future. - -2008-06-10 Thomas Thurman - - * test/tokentest/tokentest.c (draw_string_to_spec): doubles are - %f or %g, not %d - * test/tokentest/tokentest.ini: re-created fair copy accordingly - -2008-06-10 Thomas Thurman - - * test/tokentest: A preliminary attempt at a test for the - theme expression tokeniser. - -2008-06-05 Thomas Thurman - - * src/compositor/compositor-xrender.c (paint_root, destroy_win, - create_root_buffer, paint_windows, repair_screen, window_has_shadow, - xrender_set_active_window, paint_dock_shadows, unmap_win, restack_win, - make_shadow, resize_win, process_property_notify, free_win, - process_configure_notify, process_circulate_notify, add_damage): - defensive programming; check meta_screen_get_compositor_data() - throughout in case it returns NULL. In particular, when this - happened in a certain situation in xrender_set_active_window - this caused a segfault; refs #530702 (and LP#178953 has more data) - but this doesn't close them. - -2008-06-02 Thomas Thurman - - * NEWS: 2.23.34 release. - -2008-06-02 Thomas Thurman - - * src/core/display.c: make sure compositor things don't get - compiled when we're not using the compositor. - -2008-06-02 Thomas Thurman - - * test/metacity-test: new test script, imported from - branch. - -2008-05-30 Thomas Thurman - - * src/core/window-props.h: fix comments (number) - -2008-05-30 Thomas Thurman - - * src/core/window-props.h: commenting - -2008-05-28 Thomas Thurman - - * src/core/prefs.c (handle_preference_update_string, - meta_prefs_remove_listener, queue_changed): Make disabling - gconf work again. Closes #530870. - -2008-05-26 Thomas Thurman - - * configure.in: Post-release bump to 2.23.34. - -2008-05-26 Thomas Thurman - - * NEWS: 2.23.21 release. - -2008-05-26 Thomas Thurman - - * src/Makefile.am: added in two files needed for Iain's - changes earlier to work in a release tarball - -2008-05-24 Iain Holmes - - * src/compositor/compositor-xrender.c: Add Dropdown menu atoms so we - can add shadows to them. Fixes #517442 - Handle tooltips as well. Fixes #517524 - -2008-05-24 Iain Holmes - - * src/compositor/compositor.c: Check the compositor isn't NULL before - dereferencing it. Fixes #534569 - (meta_compositor_get_window_pixmap): Actually return a value - -2008-05-19 Iain Holmes - - * src/core/window.c: Applied patch from Ed Catmur to fix #528787 - -2008-05-19 Iain Holmes - - * src/include/frame.h - * src/include/display.h - * src/include/xprops.h - * src/include/compositor.h - * src/include/types.h - * src/include/window.h - * src/include/errors.h - * src/include/screen.h: New basic public API for compositor. - - * src/compositor/*: Separate the compositor out into its own separate - directory and set it up for backends. Initial XRender backend. - - * src/core/compositor.[ch]: Remove - - * src/core/frame.h - * src/core/screen.h - * src/core/display.h - * src/core/window.h: Rename to -private.h so as not to clash with the - new files in include - - * src/core/delete.c - * src/core/workspace.h - * src/core/stack.[ch] - * src/core/keybindings.[ch] - * src/core/errors.c - * src/core/effects.[ch] - * src/core/core.c - * src/core/group.h - * src/core/edge-resistance.[ch] - * src/core/window-props.[ch] - * src/core/constraints.h - * src/core/bell.[ch] - * src/core/iconcache.h - * src/core/session.[ch] - * src/core/main.c - * src/core/place.h - * src/core/xprops.c - * src/ui/tabpopup.c: Use the new -private headers - - * src/core/display.c - * src/core/frame.c - * src/core/window.c - * src/core/screen.c: Add the API functions required by the compositor - - * src/Makefile.am: Relocate the new files - -2008-05-13 Robert Escriva - - * src/ui/theme.h (struct): remove color_set flag - * src/ui/theme.c (meta_color_spec_render, - meta_color_spec_new_from_string): remove check of color_set flag - before rendering (we always do it now). Closes #511826. - -2008-05-12 Thomas Thurman - - * tools/xlib.py: Basic Python-based Xlib client for testing - and building upon. - -2008-05-09 Elijah Newren - - * src/ui/color.[ch]: - Remove these two unused files - -2008-05-04 Thomas Thurman - - Added curly brackets in two places to keep -pedantic happy. - - * src/core/window-props.c (meta_display_init_window_prop_hooks) - * src/core/group-props.c (meta_display_init_group_prop_hooks) - -2008-05-03 Matt Krai - - * src/core/delete.c (io_from_ping_dialog): fix type of "len" variable - (refs #526049) -2008-05-02 Thomas Thurman - - All information should live in exactly one place. This means - that the list of atoms should not be replicated anywhere. - Therefore, we include it via x-macros. Closes #530843. - - * src/core/atomnames.h: added list of atom names - * src/Makefile.am: added reference to new file - * src/core/display.h - * src/core/display.c (twice) - * src/core/screen.c: #included atomnames.h instead of having - an enormous list of atoms - * src/core/group-props.c - * src/core/window.c - * src/core/compositor.c - * src/core/window-props.c - * src/core/delete.c - * src/core/workspace.c - * src/core/stack.c - * src/core/keybindings.c - * src/core/iconcache.c - * src/core/group.c - * src/core/xprops.c: changed to new, simpler identifiers - for atoms - -2008-04-29 Chris Wang - - * src/core/window.c (meta_window_new): XGetWindowAttributes - can return an error value, and if it does its other results - are invalid! (#530485) - -2008-04-29 Thomas Thurman - - * src/ui/fixedtip.[ch]: documentation - -2008-04-27 Thomas Thurman - - * configure.in: Post-release bump to 2.23.21. - -2008-04-27 Thomas Thurman - - * NEWS: 2.23.13 release. - -2008-04-27 Erwann Chenede - - * src/core/place.c (meta_window_place): re-enable cascade - code which was wrongly removed a year ago. Closes #529925. - -2008-04-22 Carlos Garnacho - - * src/core/compositor.c (process_property_notify, - find_window_in_display): Propagate opacity to frame window. - -2008-04-22 Thomas Thurman - - * configure.in: Post-release bump to 2.23.13. - -2008-04-22 Thomas Thurman - - * NEWS: 2.23.8 release. - -2008-04-22 Thomas Thurman - - * configure.in: Post-release bump to 2.21.8. - (Which was seriously belated. Sorry, folks.) - -2008-04-22 Thomas Thurman - - * src/core/effects.c: a few comments - -2008-04-10 Lucas Rocha - - * src/Makefile.am: no need to create a symlink to .desktop file in - default-session directory anymore as gnome-session will find - metacity's .desktop in its original place. - -2008-04-07 iain - - * src/core/compositor.c (hide_overlay_window): Hide the overlay window - (meta_compositor_unmanage_screen): Release the compositor overlay. - (#526770) - -2008-04-07 Jens Granseuer - - * src/core/session.c: (save_state), - (warn_about_lame_clients_and_finish_interact): - reorder declarations so we don't break C89 compilers. - -2008-04-06 Thomas Thurman - - * NEWS: 2.23.5 release. - -2008-04-03 Thomas Thurman - - * src/core/prefs.c (handle_preference_update_bool): preferences - which have a null target don't get updated! (#526016) - -2008-03-29 Lucas Rocha - - * src/metacity.desktop.in, src/Makefile.am: make Metacity - install its desktop files in the default session directory - as required by the new gnome-session. (Closes #525051.) - -2008-03-29 Thomas Thurman - - * src/ui/preview-widget.c (meta_preview_get_clip_region): - prevent null dereference if the theme was invalid, which - caused crashes in gnome-appearance-properties. No GNOME - bug number, but I believe this is a fix for Launchpad bug - #199402 and its many duplicates. - -2008-03-28 Owen Taylor - - * src/core/window.c (meta_window_new_with_attrs): Don't - immediately unminimize an initially iconic window (#491090) - -2008-03-27 Thomas Thurman - - * src/core/session.c (regenerate_save_file, save_state, load_state): - files are saved in ~/.config/metacity/sessions and checked for there - and in ~/.metacity/sessions. Fixes #518596. - -2008-03-27 Thomas Thurman - - * src/core/display.c (meta_display_close): fix regression - where Metacity sometimes wouldn't quit when replaced - -2008-03-26 Thomas Thurman - - * src/core/display.c (event_callback): meta_display_screen_for_root - is quite capable of returning NULL. - -2008-03-25 Thomas Thurman - - * src/core/display.c (meta_display_queue_retheme_all_windows, - meta_set_syncing, meta_display_set_cursor_theme, disable_compositor, - meta_display_for_x_display, meta_display_open, meta_display_close, - meta_display_ungrab): MetaDisplay becomes a singleton. The static - variable which holds this singleton is renamed "the_display" so as - not to mask the this parameter in the methods. - - * src/core/main.c (main): - * src/core/session.c (warn_about_lame_clients_and_finish_inte, - save_state, io_from_warning_dialog): - * src/core/core.c (meta_core_increment_event_serial): - * src/core/delete.c (release_window_with_fd, search_and_destroy_window): - sympathy changes for this, and consequent simplification. - Closes #499301. - -2008-03-21 Thomas Thurman - - * configure.in: Post-release bump to 2.23.5. - -2008-03-21 Thomas Thurman - - * NEWS: 2.23.3 release. - -2008-03-21 Thomas Thurman - - * src/ui/menu.c (activate_cb, get_workspace_name_with_accel): Workspaces - whose name is the standard name plus a non-empty string are handled - correctly in menus. Closes #453678. - -2008-03-19 Iain Holmes - - * src/core/compositor.c (meta_compositor_set_active_window): Handle - compositor being disabled and don't crash. - -2008-03-19 Iain Holmes - - * src/core/compositor.c (meta_compositor_set_active_window): Add a - screen argument. - (process_property_notify): Damage the whole screen when the background - changes. Fixes 522599 - (add_repair): Use the idle instead of the timeout. Fixes 522166 - (unmap_win): If the window is also focus window NULLify it. - - * src/core/window.c (meta_window_notify_focus): Notify when a window - has lost focus, pass in screen as well. - -2008-03-18 Iain Holmes - - * src/core/compositor.c (window_has_shadow): Allow shaped windows - _with frames_ to have shadows. - (meta_compositor_set_active_window): Watch for the focus of windows - and change the size of the drop shadows. - (generate_shadows): Create differently sized shadows. - (meta_compositor_get_window_pixmap): Get the xwindow correctly. - - * src/core/window.c (meta_window_notify_focus): Set the active window - in the compositor. - -2008-03-18 Marco Pesenti Gritti - - * src/core/window.c (window_would_be_covered): newly created windows - can't be considered to be above themselves; fixes bug #519188. - -2008-03-11 Matthew Wilson - - * src/core/keybindings.c (meta_display_process_key_event, process_event, - find_handler, process_mouse_move_resize_grab): allow moving workspace - while moving window with modifier - * src/core/workspace.c (meta_workspace_activate_with_focus): remove the - correct window on jumping workspace while moving - -2008-03-10 Josh Lee - - * src/core/compositor.c (window_has_shadow): Don't shadow - shaped windows. - -2008-03-07 Thomas Thurman - - * configure.in: Post-release bump to 2.23.3. - -2008-03-07 Thomas Thurman - - * NEWS: 2.23.2 release. - -2008-03-07 Thomas Thurman - - * src/core/prefs.c (mouse_button_mods_handler): remove - debug statements (*blush*) - -2008-03-06 Thomas Thurman - - * configure.in: Post-release bump to 2.23.2. - -2008-03-06 Thomas Thurman - - * NEWS: 2.23.1 release. - -2008-03-06 Thomas Thurman - - * tools/release-wrangler.py: basic md5 printing (not used yet); - also print release announcements to stdout (eventually will - need to be emailed to release list and blogged) - -2008-03-06 Thomas Thurman - - Part three of the great prefs refactor, this time - dealing with string preferences. (This was the most - complicated part, and has been especially tested and - valground before committing. As ever, though, let us - know if you find a problem.) - - * src/core/prefs.c (MetaStringPreference): new struct. - * src/core/prefs.c (update_*): replaced with *_handler - * src/core/prefs.c (meta_prefs_init): uses new string prefs - init; uses array of gconf dirs to monitor rather than - repeating code. - * src/core/prefs.c (handle_preference_init_enum): tidying - * src/core/prefs.c (change_notify): uses new string prefs - -2008-03-04 Thomas Thurman - - * MAINTAINERS: added some spacing to see whether it - helps Pulse - -2008-03-03 Cosimo Cecchi - - Add ability to vertically and horizontally maximise - using the mouse, by clicking the titlebar in various - ways. A very similar patch was received from Jason Ribero. - Thanks also go to Tony Houghton and Carlo Wood, who - both submitted patches which solved this differently. - Closes #358674. - - * src/include/common.h (MetaActionTitlebar): new values - for the new actions - * src/core/core.c (meta_core_maximize_{vertic|horizont}ally): - new functions. - * src/ui/frames.c (meta_frame_titlebar_event): handle the - new action values - * src/core/window.h: new macros (for regularity, not really - necessary) - * src/core/prefs.c (symtab_titlebar_action): new string - representations of the action values - * src/metacity.schemas.in: documentation - -2008-02-29 Andrea Del Signore - - Add support for "spacer" as a button type which adds some - empty space. Closes #509165. - - * src/ui/theme.c (meta_frame_layout_calc_geometry), - src/include/common.h (MetaButtonLayout), - src/core/prefs.c (update_button_layout, button_layout_equal), - src/metacity.schemas.in: add spacer support - -2008-02-28 Thomas Thurman - - * src/core/compositor.h: removed unnecessary #include which - should have been in Jim's patch (not sure how it slipped - through the tests!) - -2008-02-27 Jim Huang - - * src/core/spring-model.[ch]: deleted as no longer used - * src/Makefile.am: modified accordingly - -2008-02-27 Thomas Thurman - - Lots of tiny fixes to make sure we compile with - "gcc -ansi -Werror". - -2008-02-26 Jens Granseuer - - * src/core/constraints.c (constrain_aspect_ratio, - constrain_size_limits, constrain_size_increments): - reorder declarations so we don't break C89 compilers. - Closes #518917. - -2008-02-26 Thomas Thurman - - * configure.in: Post-release bump to 2.23.1. - -2008-02-26 Thomas Thurman - - * NEWS: 2.23.0 release. - -2008-02-26 Thomas Thurman - - * tools/release-wrangler.py: ANY post-release bump is now the - most recent, not just the one that matches the current version. - Otherwise, you can't use these tools straight after a branch. - The changeset before this one was mislabelled because of this. - It has now been excised from the changelog. - -2008-02-25 Thomas Wood - - * src/ui/preview-widget.[ch] (meta_preview_get_clip_region): - allow users of the preview widget to get a mask for windows - in the correct shape for the current theme. - -2008-02-23 Thomas Thurman - - Refactor handling of boolean preferences. - - * src/core/prefs.c (handle_preference_init_bool, - handle_preference_update_bool): new functions. - * src/core/prefs.c (meta_prefs_init, change_notify): - use the new functions. - * src/core/prefs.c (update_*): several of these removed whose - only purpose was to receive boolean preferences. - * src/core/prefs.c (cleanup_error, get_bool): moved down to make - the flow of ideas more obvious. - * src/core/prefs.c (maybe_give_disable_workarounds_warning): new - function containing duplicated code from elsewhere. - * src/core/prefs.c (init_button_layout): only compiled when - HAVE_GCONF is not defined. Removed a compiler warning. - -2008-02-23 Thomas Thurman - - * tools/commit-wrangler.py: Print URL of changeset on success. - -2008-02-23 Thomas Thurman - - Refactored handling of enumerated preferences. - - * src/core/prefs.c (handle_preference_init_enum, - handle_preference_update_enum): new functions. - (meta_prefs_init, change_notify): use regularised - forms and remove old copy-and-pasted code. - Also many small similar functions removed which - only existed to deal with each kind of enum. - Also some amount of correction of which parts were - and weren't inside "#ifdef HAVE_GCONF" blocks. - - -2008-02-21 Mikkel Kamstrup Erlandsen - - * src/core/constraints.c: Respect requested position on - _NET_MOVERESIZE_WINDOW. Closes #448183. - -2008-02-18 Matthias Clasen - - * src/core/window.h: Make skip-taskbar windows appear in the - Ctrl-Alt-Tab list. Closes #106249. - -2008-02-18 Thomas Thurman - - * configure.in: if we have libSM and its headers, - that means we did find it, not that we didn't. - Closes #328210. - -2008-02-18 Thomas Thurman - - * src/core/window.c (warp_grab_pointer): When - resizing a window with the keyboard, stay one - pixels from the edges so that the cursor remains - resting on a window edge even if we escape, - whatever side it was on. Closes #436257. - -2008-02-17 Thomas Thurman - - * tools/commit-wrangler.py: added new script to manage commits - -2008-02-17 Jim Huang - - * src/core/prefs.c (update_binding): Allow compilation - when gconf mode is disabled. Closes #515019. - -2008-02-14 Jim Huang - - * src/core/display.c, src/core/util.c: fixups to allow - compilation in non-verbose mode. Closes #515152. - -2008-02-12 Thomas Thurman - - * configure.in: Correct help for verbose option name. - -2008-02-12 Thomas Thurman - - * configure.in: Post-branch bump to 2.23.0. - -2008-02-12 Thomas Thurman - - * configure.in: Post-release bump to 2.21.21. - -2008-02-11 Thomas Thurman - - * NEWS: 2.21.13 release. - -2008-02-04 Thomas Thurman - - * src/core/compositor.c: only use compositor version if - we have a compositor. Closes #514453. - -2008-02-04 Thomas Thurman - - * configure.in, src/ui/ui.c: remove workaround for a problem - in GTK 1.3.9(!) which was causing problems. Closes #513737. - -2008-01-28 Michael Meeks - - * src/core/display.c (meta_display_open), - * src/core/compositor.c: fetch & use composite - version, for remote screens that don't match the - compile system's version. - (meta_compositor_manage_screen): bin erroneous FIXME. - (add_win): remove common warning churn for (very) - transient windows - -2008-02-03 Thomas Thurman - - * tools/patch-wrangler.py: another program I use for maintenance - which other people might find useful and which should probably - be in svn. Also not very polished. - -2008-02-03 Thomas Thurman - - * test/tokentest/tokentest.c, test/tokentest/tokentest.ini: added - new files for a regression test on the tokeniser. (They aren't very - polished at the moment and aren't included in the autotools build.) - -2008-02-03 Thomas Thurman - - * configure.in: Post-release bump to 2.21.13. - -2008-02-03 Thomas Thurman - - * NEWS: 2.21.8 release. - -2008-02-03 Thomas Thurman - - * tools/release-wrangler.py: Fix quoting error and added some - more error checking. - -2008-02-03 Thomas Thurman - - * tools/release-wrangler.py: basic release script; needs work, - but probably good enough for the current unstable release - -2008-02-02 Thomas Thurman - - * src/Makefile.am: core.h is in include, not core. (Last one, I - promise.) - -2008-02-02 Thomas Thurman - - * src/Makefile.am: main.h is in include, not core. - -2008-02-02 Thomas Thurman - - * src/Makefile.am: draw-workspace.h is in ui, not core. - -2008-02-01 Alex R.M. Turner - - * src/core/display.c (meta_get_tab_entry_list): Have the list also pull - windows that are in other workspaces that have the - wm_state_needs_attention flag set - * src/core/window.c (meta_window_set_demands_attention): Make windows that - are on other workspaces that demand attention that aren't obscured - count as being obscured - Bug #333548. - -2008-01-28 Christian Persch - - * src/core/display.c (convert_property): - * src/core/screen.c (meta_screen_calc_workspace_layout): - * src/core/xprops.c (meta_prop_get_values): - Use G_STRFUNC instead of the deprecated G_GNUC_FUNCTION. - Bug #512561. - -2008-01-21 Thomas Thurman - - * src/ui/theme.[ch]: more commenting. - -2008-01-18 Thomas Thurman - - * src/ui/theme.[ch]: some more commenting. - -2008-01-16 Thomas Thurman - - * src/core/bell.c: Correct comment. - * src/core/main.c: Correct comment. - * src/ui/theme.c: Much commenting; #ifdeffed-out - debug code removed. - * src/ui/theme.h: Much commenting. - -2008-01-13 Thomas Thurman - - * src/core/bell.c: Commenting. - * src/core/main.c: Commenting, and fixing existing comments. - -2008-01-12 Thomas Thurman - - * src/core/main.c: Refactor repeated lines in main() to - iterate instead. - -2008-01-12 Thomas Thurman - - * src/core/main.[ch] (meta_get_main_loop): removed as it - was never used. - * src/core/main.c: lots of comments. - * src/core/main.c (version): copyright year is 2008. - * src/core/c-screen.[ch], src/core/c-window.[ch]: removed - files from Søren's compositor which were removed by the - merge with Iain's compositor but reintroduced by the split - to separate subdirectories. - * src/core/display.c: fix comments. - -2008-01-12 Thomas Thurman - - * src/core/display.c: reinstated missing first character! - * Doxyfile: correct reordering of blank fields. - -2008-01-12 Thomas Thurman - - * src/core/display.c: change comments from /*! to /** because the - other way makes doxygen think they are Qt comments, which messes - up brief descriptions. - * Doxyfile: check in so other people can generate documentation - too. - -2008-01-07 Thomas Thurman - - * src/core/display.c: further commenting (trying to keep comment - addings down to once a day at most so you don't all get spammed - too much). - -2008-01-07 Thomas Thurman - - * src/core/main.c (main): g_free is a no-op on nulls; there is no - need to test. - -2008-01-06 Thomas Thurman - - * src/core/display.c: Function commenting marathon; more to come. - -2008-01-02 Thomas Thurman - - * src/core/xprops.c (meta_prop_get_cardinal), src/core/compositor.c - (timeout_debug): Two really minor coding standards layout tweaks. - -2007-12-27 Iain Holmes - - * src/core/compositor.c: Don't do anything in - meta_compositor_free_window, it doesn't seem to be needed and breaks - things very badly. http://bugzilla.gnome.org/show_bug.cgi?id=504876 - -2007-12-27 Iain Holmes - - * src/core/compositor.c: When a window is mapped, don't set damaged to - TRUE. Fixes a bug when redrawing shadows. - -2007-12-25 Iain Holmes - - * src/core/compositor.c: USe the compositor overlay window instead of - the root window. - -2007-12-21 Paolo Borelli - - * src/core/core.c (meta_invalidate_default_icons): do not leak list. - - * src/core/edge-resistance.c - (meta_display_compute_resistance_and_snapping_edges): ditto. - - * src/core/workspace.c (meta_workspace_index): small cleanup in list - handling. - -2007-12-19 Havoc Pennington - - * src/core/display.c (meta_display_open): fix a third warning - about %d and long int - - * src/core/delete.c (io_from_ping_dialog): fix another warning - about long int to %d - - * src/core/compositor.c (meta_compositor_new): fix a warning about - long int to %d - - * src/core/iconcache.c (meta_read_icons): use - meta_ui_get_fallback_icons() instead of incorrectly including theme.h - - * src/ui/ui.c (meta_ui_get_fallback_icons): new function - -2007-12-19 Havoc Pennington - - * src/ui, src/core, src/include: sort source files into these - directories according to which part of the WM they are supposed to - be in. In an eventual plan, we should also create - src/compositor/render, src/compositor/fallback and move some of - the compositor stuff into that. - - * autogen.sh: require a newer automake, so we don't have to use - a recursive build - - * src/ui/tabpopup.c: put in a hack to make the build temporarily - work, want to commit the large rearrangement before fixing this - not to include workspace.h or frame.h - - * src/core/iconcache.c (meta_read_icons): temporarily break this - to get the build to work, want to commit the large rearrangement - before fixing this file not to include theme.h - -2007-12-19 Thomas Thurman - - * configure.in: Post-release bump to 2.21.8. - -2007-12-19 Thomas Thurman - - * NEWS: 2.21.5 release. - -2007-12-19 Thomas Thurman - - * configure.in: print "Subversion" and not "CVS". - -2007-12-18 Thomas Thurman - - * configure.in: compositor enabled by default. - -2007-12-18 Iain Holmes - - * configure.in, src/theme.c, src/display.c, - src/theme.h, src/display.h, src/theme-parser.c, - src/compositor.c, src/c-screen.c, src/compositor.h, - src/c-screen.h, src/ui.c, src/screen.c, src/ui.h, - src/screen.h, src/c-window.c, src/c-window.h, - src/theme-viewer.c, src/Makefile.am: Merge compositor branch. - -2007-12-14 Thomas Thurman - - * configure.in: Post-release bump to 2.21.5. - -2007-12-14 Thomas Thurman - - * NEWS: 2.21.3 release. - -2007-12-11 Thomas Thurman - - * src/theme-parser.c: remove dead code; closes #501365. - -2007-12-08 Thomas Thurman - - * src/metacity.schemas.in: rewrite long description of - /schemas/apps/metacity/general/focus_new_windows because we - love the translators really. Closes #474889. - -2007-12-08 Matthias Clasen - - * src/menu.c (meta_window_menu_new): check for null before adding - menu; closes #496054. - -2007-12-08 Thomas Thurman - - * src/keybindings.c (meta_display_process_key_event): Recur if the - keypress ended a grab, so it can be processed in its own right. - Closes #112560. - -2007-12-08 Martin Meyer - - * src/theme-parser.c (parse_draw_op_element): Fix - typo where wrong variable was checked (reported by - Kjartan Maraas). Closes #501362. - -2007-11-19 Lucas Rocha - - * src/main.c (main): try to get the session client ID from - DESKTOP_AUTOSTART_ID environment variable in case the --sm-client-id - is not used. Closes #498033. - -2007-11-17 Thomas Thurman - - * configure.in: Post-release bump to 2.21.3. - -2007-11-17 Thomas Thurman - - * NEWS: 2.21.2 release. - -2007-11-17 Benjamin Gramlich - - * src/theme-parser.c (meta_theme_load): make our theme - search compliant to the XDG Base Directory Specification. - Closes #480026. - -2007-11-15 Thomas Thurman - - * src/api.[ch]: remove almost-unused files. - * src/colors.[ch]: move the used parts of api.[ch] in here. - Closes #496947. - -2007-11-13 Peter Bloomfield - - * src/window.c: (meta_window_save_user_rect): new helper, saves - only unmaximized dimensions, and not when fullscreen. - (meta_window_move_resize_internal, - meta_window_move_resize_request): use it. (#461927) - -2007-11-11 Thomas Thurman - - * configure.in: Post-release bump to 2.21.2. - -2007-11-11 Thomas Thurman - - * NEWS: 2.21.1 release. - -2007-11-11 Thomas Thurman - - * src/window.c (meta_window_show): adjust expression which decides - whether new windows should not go on top, so that restacking happens - only the first time a window is mapped. Thanks to Olav Vitters for - pointing out the problem. Re-fixes #486445. - -2007-11-11 Alex R.M. Turner - - * src/tabpopup.c (tab_entry_new, meta_ui_tab_popup_new): Instruct the - GtkLabel in the tabpopup to ellipsize text that is too big. Set the - maximum window width of the tabpopup to screen_width/4, which seems a - sensible size for the popup. - -2007-11-09 Elijah Newren - - * src/window.c (meta_window_new_with_attrs): If a window is - launched without any kind of launch timestamp, grab the current - time and stash it away. When transients of that window are also - launched without a timestamp, we can use the stashed timestamp - from the parent. Fixes #488468. - -2007-11-07 Federico Mena Quintero - - * src/window-props.c (reload_net_wm_user_time_window): Fix typo; - the arguments to meta_window_reload_property_from_xwindow() were - reversed. This is why the wm_user_time wasn't getting initialized - properly from the _NET_WM_USER_TIME_WINDOW. Fixes part of - http://bugzilla.gnome.org/show_bug.cgi?id=488468 - -2007-11-06 Peter Bloomfield - - * src/window.c (meta_window_move_resize_internal): save - unmaximized part of client root coords. (#461927) - -2007-11-06 Peter Bloomfield - - * src/window.c (meta_window_move_resize_internal): do not save - client root coords while window is maximized. (#461927) - -2007-10-30 iain Holmes - - * src/main.c (meta_parse_options): Add --sync option - (main): Check if the --sync option was passed on command line. - -2007-10-28 Jans Granseuer - - * src/preview-widget.c (meta_preview_finalize): Free title of - preview when the preview is destroyed. Closes #469682. - -2007-10-27 Alex R.M. Turner - - * src/tabpopup.c (tab_entry_new): Truncate the string to - max_char_per_title before adding bold tags and fix general flow of - function. - -2007-10-16 Thomas Thurman - - * src/window.c (window_would_be_covered): new function. - * src/window.c (meta_window_show): rewrite assertion not - to put window on top in terms of window_would_be_covered(); - remove assertion because it's no longer valid; explicitly - don't focus windows that shouldn't be focussed; closes #486445. - -2007-10-14 Thomas Thurman - - * configure.in: Post-branch bump to 2.21.1. - -2007-10-03 Kjartan Maraas - - * configure.in: Remove circular dep metacity<->gnomecc. - -2007-09-15 Elijah Newren - - * configure.in: post-release version bump to 2.20.1 - -2007-09-15 Elijah Newren - - * configure.in: - * NEWS: - 2.20.0 release - -2007-09-15 Elijah Newren - - * src/session.c (warn_about_lame_clients_and_finish_interact): - Patch from Alexey Rusakov to prevent a crash on logout with - metacity subsequently not being restored in future sessions. - Fixes #433253. - -2007-09-01 Elijah Newren - - * HACKING: update; cvs->svn & mention GConf needed - * MAINTAINERS: Make it match idiotic format requirements (I love - you Olav!) - -2007-08-07 Thomas Thurman - - * configure.in: post-release bump to 2.19.89. - -2007-08-07 Thomas Thurman - - * NEWS: 2.19.55 release. - -2007-08-06 Thomas Thurman - - If KEY_AUTO_RAISE_DELAY is undefined or non-integer, it is not treated - as zero. - - * src/prefs.c (meta_prefs_init): check type of key, and behave sensibly - if it's unexpected. - * src/prefs.c (find_and_update_list_binding): remove old comment. - -2007-08-03 Frederic Crozat - - * src/delete.c: Fix mangled window title in "Force Quit" - dialog when using non-UTF8 locale. Close #462734. - -2007-08-02 Thomas Thurman - - Move "close" to bottom of window menu; allow workspace list to appear - at any position in the menu. Closes #104026. - - * src/menu.c (MetaMenuItemType): added new MENU_ITEM_WORKSPACE_LIST - item. - * src/menu.c (menuitems): reordered "close", added a workspace list. - * src/menu.c (menu_item_new): return null for workspace lists. - * src/menu.c (meta_window_menu_new): handle workspace lists. - -2007-07-31 Thomas Thurman - - * src/window.c (meta_window_show_menu): windows which are - always on top have the "stick" menu option insensitive. (#460997). - -2007-07-23 Thomas Thurman - - * src/window.h (MetaWindow): Put all bitfields together to - help with optimisation. Closes #450271 (for real this time). - -2007-07-23 Matthias Clasen - - * configure.in: - * src/Makefile.am: Use the correct directory when - installing keybindings. (#454055) - -2007-07-22 Thomas Thurman - - * configure.in: post-release bump to 2.19.55. - -2007-07-22 Thomas Thurman - - * NEWS: 2.19.34 release. - -2007-07-22 Rob Bradford - - Fix a bug where the window can be focused without being raised - if the maximize is aborted. Fixes #459027. - - * src/frames.c (meta_frames_button_press_event, - meta_frames_button_release_event): When maximising only focus - the window once the button press is released. - -2007-07-22 Cosimo Cecchi - - Unset fullscreen is an allowed action where relevant. Fixes #449427. - - * src/window.c (set_allowed_actions_hint): Separate FULLSCREEN action - from RESIZE action. - -2007-07-22 Yair Hershkovitz - - Reverse window buttons and align them to the left for RTL locales. - Fixed #92212. - - * src/prefs.c (button_layout, init_button_layout, update_button_layout): - Support reversing and left-aligning of buttons for both Gconf and - NO-Gconf modes. - * src/main.c (main): Call meta_ui_init() before meta_prefs_init(). - meta_prefs_init() check for RTL locales which is initialized in - meta_ui_init(). - * src/theme.c (meta_frame_layout_calc_geometry): Fixed access to - button_layout to stop iterating when getting to a - META_BUTTON_FUNCTION_LAST value. - -2007-06-23 Thomas Thurman - - * src/window.c (MetaWindow): Put all bitfields together to - help with optimisation. Closes #450271. - -2007-06-18 Thomas Thurman - - * src/main.c (version): Update copyright year because it was - five years out of date. - -2007-06-18 Thomas Thurman - - * configure.in: post-release bump to 2.19.34. - -2007-06-18 Thomas Thurman - - * NEWS: 2.19.21 release. - -2007-06-18 Thomas Thurman - - * src/place.c (find_first_fit, meta_window_place): Only open new - windows on the current xinerama. Closes #145503, for now. - -2007-06-17 Thomas Thurman - - * src/screen.[ch] (meta_screen_apply_startup_properties): return a - boolean instead a void, to show whether startup properties were - applied. Also some commenting. - * src/window-props.c: (reload_net_startup_id): Only activate the - window if the startup_id was actually changed. Closes #400167. - -2007-06-16 Damien Carbery - - * effects.h: MetaCloseEffect and MetaFocusEffect, which were empty - structs, #ifdeffed out because they broke the build on Solaris. - Closes #397296. - -2007-06-16 Damien Carbery - - * window.h: make prototype of meta_window_unqueue match - implementation. Closes #446535. - -2007-06-10 Thomas Thurman - - * configure.in: post-release bump to 2.19.21. - -2007-06-10 Thomas Thurman - - * NEWS: 2.19.13 release. - -2007-06-10 Thomas Thurman - - Refactor thrice-duplicated queue code in window.c. Closes #376760. - - * src/window.c (meta_window_queue, meta_window_unqueue): - New functiortl.patchns. - * src/window.[ch] (meta_window_unqueue_*, meta_window_queue_*): - Removed functions. - * src/window.c (meta_window_new_with_attrs, meta_window_free, - meta_window_flush_calc_showing, queue_calc_showing_func, - meta_window_minimize, meta_window_unminimize, meta_window_maximize, - meta_window_make_fullscreen, meta_window_shade, - meta_window_unshade, meta_window_move_resize_internal, - window_stick_impl, window_unstick_impl, - meta_window_client_message, process_property_notify): Modified to - use new queueing functions. - * src/window.c (idle_move_resize, idle_update_icon, - idle_calc_showing): update to receive queue number from pointer. - * src/window.h (MetaQueueType): new enum. - * src/window.h (MetaWindow): *_queued replaced with is_in_queue - bitfield. - * src/core.c (meta_core_queue_frame_resize): - * src/display.c (event_callback, - meta_display_queue_retheme_all_windows): Using new queueing functions. - * src/frame.c (meta_window_destroy_frame): Using new queueing functions. - * src/screen.c (queue_resize, meta_screen_resize_func, - queue_windows_showing): Using new queueing functions. - * src/window-props.c (reload_mwm_hints, reload_wm_hints, - reload_transient_for): Using new queueing functions. - * src/workspace.c (meta_workspace_add_window, - meta_workspace_remove_window, meta_workspace_queue_calc_showing, - meta_workspace_invalidate_work_area): Using new queueing functions. - -2007-06-09 Thomas Thurman - - * src/50-metacity-key.xml.in: added switch_group; closes #444879. - -2007-06-08 Elijah Newren - - * src/metacity.schemas.in: - Update the raise_on_click description to try to prevent misuses, - to appropriately warn users, and to stop wasting the time of - application developers. #445447, #389923 - -2007-06-06 Thomas Thurman - - * frames.c, core.[ch]: changed all tabs to spaces. - * core.[ch] (meta_core_get_client_size, meta_core_window_has_frame, - meta_core_titlebar_is_onscreen, meta_core_get_client_xwindow, - meta_core_get_frame_flags, meta_core_get_frame_type, - meta_core_get_mini_icon, meta_core_get_icon, meta_core_get_position, - meta_core_get_size, meta_core_get_frame_workspace, - meta_core_get_frame_extents, meta_core_get_screen_size): Removed - and replaced with meta_core_get(). - * core.[ch] (meta_core_get): New function. - * core.h (MetaCoreGetType): New enum. - * frames.c (meta_frames_ensure_layout, meta_frames_calc_geometry, - meta_frames_get_geometry, meta_frames_apply_shapes, - meta_frame_titlebar_event, meta_frames_button_press_event, - populate_cache, clip_to_screen, meta_frames_paint_to_drawable, - meta_frames_set_window_background, get_control): Replace use of - removed functions in ui.c with meta_core_get(). - - All this should make things a little faster. Closes #377495. - -2007-06-04 Thomas Thurman - - * NEWS: Added translators' names from 2.19.8 (sorry, folks: - I forgot to save NEWS with their names in it before shipping.) - -2007-06-04 Thomas Thurman - - * configure.in: post-release bump to 2.19.13. - -2007-06-04 Thomas Thurman - - * NEWS: 2.19.8 release. - -2007-06-04 Thomas Thurman - - * src/metaaccellabel.c (meta_accel_label_expose_event): fix - label layout for RTL languages. Closes #433400. - -2007-06-03 Thomas Thurman - - * src/frames.c (meta_frames_ensure_layout): Pango layout for - titlebars should take LTR/RTL-ness from the underlying widget - and not from sniffing the content. Closes #438944. - -2007-05-25 Yair Hershkovitz - - * src/workspace.c (meta_workspace_get_neighbor): Add support - for RTL languages so that alt-tab, etc., go the other way. - * src/keybindings.c (handle_activate_menu): In RTL locales, - pop up the menu on the right-hand side when the menu keystroke - is pressed. - * src/fixedtip.c (meta_fixed_tip_show): right-justify tooltips - in RTL locales. - * src/menu.c (popup_position_func): popup menus in RTL locales - are flush with the right-hand side of the window where possible. - * src/frames.c (show_tip_now, meta_frames_button_press_event): - tooltips are aligned with the right-hand side of buttons in - RTL locales. - * src/ui.[ch] (meta_ui_get_direction, enum MetaUIDirection): - New content. - * src/window.c (meta_window_show_menu): "move left" appears above - "move right" in the window menu for LTR locales, and vice versa - for RTL locales. - - This is all to close bug #387893. - -2007-04-24 Linus Torvalds - - * src/prefs.[ch] (init_action_meta_prefs, meta_prefs_init, - action_change_titlebar, change_notify, update_action_titlebar, - meta_preference_to_string): Add code to configure what happens - when the titlebar is right or middle clicked as well as - double clicked. - -2007-04-23 Elijah Newren - - * configure.in: post-release bump to 2.19.8. - -2007-04-23 Elijah Newren - - * NEWS: 2.19.5 release. - -2007-04-23 Elijah Newren - - Fix some uninitialized memory usage errors. #427385 - - * src/frame.c (meta_window_ensure_frame): - * src/frames.c (meta_frames_manage_window): - Do not try to set the window background in - meta_frames_manage_window() since the frame window is not yet - created and not yet registered with the corresponding MetaWindow. - Do it inside meta_window_ensure_frame() instead. - -2007-04-17 Elijah Newren - - Fix some fallout from #426519; update user_rect for all position - changes prior to the window being marked as placed. Prevents - emacs in particular from flickering on start and always being - shoved to the upper-left corner. - - * src/window.c (meta_window_move_resize_internal): - Record position in user_rect if the window is not yet marked as - placed too - - * src/window.c (struct MetaWindow, meta_window_new_with_attrs, - meta_window_move_resize_internal): - Remove window->user_has_move_resized; it's not needed or used - anymore. - - * src/window.[ch] (meta_window_get_user_position): - Remove this function as it is no longer needed or used. - -2007-04-16 Elijah Newren - - Prevent metacity from "forgetting" which machine a window is on. - #418552 - - * src/window.c (meta_window_new_with_attrs): reorder the property - loading so that we know the wm_client_machine when we load the - name of the window and can modify the window name accordingly. - -2007-04-16 Elijah Newren - - * configure.in: post-release bump to 2.19.5. - -2007-04-16 Elijah Newren - - * NEWS: 2.19.3 release. - -2007-04-15 Elijah Newren - - Preserve stacking order across restarts. - - * src/display.c (meta_display_unmanage_windows_for_screen): - unmap windows in stacking order so that stacking is preserved upon - shutdown - - * src/display.[ch] (meta_display_stack_cmp): - * src/session.c (stack_cmp, save_state): - rename stack_cmp() -> meta_display_stack_cmp() and move it to a - different function so that it can be used in both - session.c:save_state() and - meta_display_unmanage_windows_for_screen() - -2007-04-15 Elijah Newren - - Remove incorrect usage of window.h from menu.c. See #426791 & - #382962. - - * src/menu.c (enum MetaMenuItemType, variable menuitems, - meta_menu_item_new): - cleanup: add a MENU_ITEM_RADIOBUTTON for the sticky stuff - - * src/menu.c (variable menuitems): - * src/core.c (meta_core_get_menu_accelerator): - * src/window.c (menu_callback, meta_window_show_menu): - * src/common.h (enum MetaMenuOp): - reinstate META_MENU_OP_UNABOVE - - * src/menu.c (meta_window_menu_new): - remove hacks (using inappropriate data) for STICK/UNSTICK/ABOVE - and clean it up while just setting STICK/UNSTICK activeness as - necessary - - * src/menu.[ch] (meta_window_menu_new): - * src/ui.[ch] (meta_ui_window_menu_new): - make the active_workspace parameter an unsigned long - -2007-04-15 Bruno Boaventura - - * src/menu.c (meta_window_menu_new): don't show the current - workspace as a possible workspace to switch to. Fixes #426791. - -2007-04-12 Elijah Newren - - * src/place.c (meta_window_place): do not auto-maximize windows - larger than the workarea in only a single direction. Fixes - #419810. - -2007-04-11 Elijah Newren - - Make sure apps have correct info about their coordinates, even on - unmap. Fixes temporary hang with libXt (XtVaSetValues setting x & - y coordinates). #399552. - - * src/frame.c (meta_window_destroy_frame): Add a comment noting - that the current choice causes the need for a ConfigureNotify - event - - * src/window.c (meta_window_free): Send a configure notify event - due to our XReparentWindow coordinate choices on withdrawal, - (unmaximize_window_before_freeing): no need to send a configure - notify from here since it is always done in meta_window_free new, - (send_configure_notify): have to special case the coordinates used - when withdrawing the window - -2007-04-11 Thomas Thurman - - Workaround for a gdk bug which dies with BadAlloc if you try - to allocate an insanely huge rectangle for an insanely huge - window. Fixes #399529. - -2007-04-11 Elijah Newren - - Advertise support of Above and Below operations (assuming the - proposed EWMH additions of _NET_WM_ACTION_(ABOVE|BELOW) will be - accepted, otherwise these changes will have to be modified). Part - of #115247. - - * src/display.[ch] (meta_display_open, struct MetaDisplay): - * src/screen.c (set_wm_check_hint): - Add support for _NET_WM_ACTION_ABOVE and _NET_WM_ACTION_BELOW - - * src/window.c (set_allowed_actions_hints): - add active_above and action_below - -2007-04-10 Elijah Newren - - * src/window.c (recalc_window_features): make sure to set - _NET_WM_ALLOWED_ACTIONS so that libwnck menus don't have sensitive - but ineffective menu items. The "On Top" item is now buggy, but - due to the fact that _NET_WM_ACTION_ABOVE is not yet defined in - the EWMH. Fixes #115247. - -2007-04-09 Elijah Newren - - Add support for _NET_MOVERESIZE_WINDOW. Based on patch from - Magnus Therning. #344521. - - * src/display.c (handle_net_moveresize_window, event_callback): - Remove handle_net_moveresize_window() and the call to it; this - code was highly buggy, though to be fair it was never tested and - had simply been put into the code in commented out form. - - * src/screen.c (set_supported_hint): - add atom_net_moveresize_window - - * src/window.[ch]: - (meta_window_configure_request, meta_window_move_resize_request): - Split out the moving/resize part of the configure request and put - it into meta_window_move_resize_request - - (meta_window_client_message): - check for NET_MOVERESIZE_WINDOW messages and call - meta_window_move_resize_request() with the appropriate parameters - to handle them - - (meta_window_move_resize_internal): - fix some of the big comment at this function -- it wasn't quite - right, use the passed in gravity instead of - window->size_hints.win_gravity when calling adjust_for_gravity() - to make sure the correct adjustments are used. - - (meta_window_get_gravity_position, - meta_window_get_geometry, meta_window_move_resize_request): - add a gravity parameter to meta_window_get_gravity_position and - have it use that gravity instead of window->size_hints.win_gravity - -2007-04-09 Elijah Newren - - * configure.in: post-release bump to 2.19.3. - -2007-04-09 Elijah Newren - - * NEWS: 2.19.2 release. - -2007-04-08 Elijah Newren - - Remove grab_start_serial, which we expect to be an ancient attempt - to workaround sloppy/mouse focus bugs that have since been - correctly fixed. May fix some race conditions. May cause nasty - bugs in sloppy/mouse focus modes. We'll find out soon enough... - See #304430. - - * src/display.c (event_callback): - remove event->xany.serial >= display->grab_start_serial in several - event callback handlers - - * src/display.[ch] (struct _MetaDisplay, meta_display_begin_grab_op): - * src/keybindings.c (do_choose_window, handle_workspace_switch): - * src/frames.c (meta_frames_button_press_event): - * src/core.[ch] (meta_core_begin_grab_op): - * src/window.c (meta_window_client_message, meta_window_begin_grab_op): - don't require an event_serial to be passed to - meta_display_begin_grab_op () and don't record it anymore. - - * src/ui.c (struct _EventFunc, filter_func, - meta_ui_get_last_event_serial) - * src/core.h (meta_ui_get_last_event_serial): - remove meta_ui_get_last_event_serial() function (don't ask me why - it was declared in core.h) and the last_even_serial field of - _EventFunc - -2007-04-08 Elijah Newren - - Fix move/resize events in relation to combinations of - ConfigureRequest and WM_NORMAL_HINTS change notifications (plus a - few code cleanups). Fixes #426519. - - * src/window.c (meta_window_move_resize_now): - move to the user_rect position, not some weird combination of rect - and user_rect - - * src/window.c (meta_window_configure_request): - set user_rect in response to ConfigureRequest events (after the - ConfigureRequest values have been constrained) and add a big - comment explaining this change, remove unused only_resize variable - and irrelevant huge FIXME comment about it - - * src/window.[ch] (meta_window_get_client_root_coords): - new function - - * src/display.c (meta_display_begin_grab_op): - * src/keybindings.c (process_keyboard_move_grab): - * src/window.c (meta_window_unmaximize, - meta_window_move_resize_internal, meta_window_begin_wireframe, - update_move, meta_window_refresh_resize_popup, - warp_grab_pointer) - combine multi-step client rect root coord setting into a single - function call to meta_window_get_client_root_coords() - -2007-04-08 Thomas Thurman - - * ChangeLog: removed conflict line. - -2007-04-07 Elijah Newren - - * src/prefs.[ch] (screen_bindings array, - META_KEYBINDING_SET_SPEW_MARK definition): - * src/keybindings.c (handle_spew_mark, screen_handlers array): - Add an (unbound by default) keybinding for setting spew marks in - verbose debugging logs. I'm not sure why this was ever removed; - I've wanted it so many times. - - * HACKING: - valgrind wants --log-file not --logfile. - -2007-04-07 Elijah Newren - - * src/window.c (meta_window_free): Fix memory bug (invalid free) - introduced in 2007-04-02 strut cleanup commit. Part of #427385. - -2007-04-05 Thomas Thurman - - * src/theme_parser.c: if theme is invalid and therefore got - freed, don't attempt to read from it. Closes #423855. - -2007-04-05 Bastien Nocera - - * src/50-metacity-desktop-key.xml.in: - * src/50-metacity-key.xml.in: - * src/Makefile.am: - Add new control-center key bindings definitions (Closes: #420145) - -2007-04-04 Elijah Newren - - * configure.in: post-release bump to 2.19.2. - -2007-04-04 Elijah Newren - - * NEWS: 2.19.1 release. - -2007-04-04 Elijah Newren - - * src/window.c (meta_window_move_resize_internal): send synthetic - configurenotify events also in response to MapRequest events when - the window has a frame and the application specifies PPosition or - UPosition hints. I believe they are already sent for all other - cases. Should fix #322840. Fixes the testcase at least. :) - -2007-04-04 Elijah Newren - - Fix lots of little issues with min/max constraints and size - increment constraints. Fixes #329152, #418395, and possibly - others. - - * src/window-props.c (meta_set_normal_hints): - Do more checking to make sure application specified constraints - are self-consistent, modifying the size_hints as necessary to - achieve self-consistency. - - * src/constraints.c (setup_constraint_info): remove ugly - copy-pasto, (constrain_size_increments): be careful that fixing - violation of the constraints doesn't cause a violation of the - minimum size constraints. - - * src/window.c (ensure_size_hints_satisfied): new function, - (meta_window_unmaximize, meta_window_unmake_fullscreen): the - saved_rect may no longer be valid (as in the case of #329152) so - call ensure_size_hints_satisfied to fix it up. - - * doc/how-to-get-focus-right.txt: Some minor spacing and wording - fixes completely unrelated to the rest of this commit - -2007-04-03 Elijah Newren - - * src/window.c (meta_window_unmaximize): - Only use saved_rect for determining the position to unmaximize to - for the previously-maximized direction(s). Fixes #355497. - -2007-04-03 Elijah Newren - - * MAINTAINERS: Update. #412319. - -2007-04-03 Elijah Newren - - * src/display.c (meta_display_update_active_window_hint): - _NET_ACTIVE_WINDOW is a single xwindow id, not two. - -2007-04-03 Elijah Newren - - * src/keybindings.c (handle_panel_keybinding): turn mouse_mode off - to prevent focus issues with the run application dialog. Fixes - #374752. - -2007-04-03 Elijah Newren - - Avoid some crashes when dragging windows partially offscreen. - Possible (or at least partial) fix for #353513. - - * src/edge-resistance.c (apply_edge_resistance): be more careful - about calls to find_index_of_edge_near_position() returning - possibly invalid indices. Also, add a warning comment to - find_index_of_edge_near_position(). - -2007-04-03 Elijah Newren - - Patch from Carlo Wood to do some miscellaneous code cleanups found - while working on #358311. - - * src/constraints.c (do_screen_and_xinerama_relative_constraints): - nicer way of avoiding compilation warning - - * src/boxes.c (meta_rectangle_clamp_to_fit_into_region, - meta_rectangle_clip_to_region, meta_rectangle_shove_into_region): - Much cleaner way of ignoring invalid boxes in comparisons - -2007-04-02 Elijah Newren - - Patch from Carlo Wood to fix handling of unidirectional - maximization and partial struts. #358311. - - * src/constraints.c (constrain_maximization): - determine target size for unidirectionally maximized windows by - determining how far they can be maximized without hitting - orthogonal struts. Avoids weird "empty spaces". - - * src/boxes.[ch] (meta_rectangle_expand_to_avoiding_struts): - new function - -2007-04-02 Elijah Newren - - Make the strut lists (stored in workspaces) record both the - rectangle and the side that the strut is on. Lots of code - cleanups relating to struts. - - * src/boxes.h (struct MetaStrut): - new struct for struts - - * src/window.[ch] (struct MetaStruts, struct MetaWindow, - meta_window_update_struts): - overhaul to make window's struts remember their side as well as - their rectangular location, and just use a list instead of several - copies of near-identical code for left/right/top/bottom (allowing - us to nuke MetaStruts struct as well) - - * src/testboxes.c (new_meta_strut, get_strut_list): - * src/workspace.c (ensure_work_areas_validated): - * src/boxes.c (meta_rectangle_get_minimal_spanning_set_for_region, - meta_rectangle_expand_to_avoiding_struts, - get_disjoint_strut_rect_list_in_region, fix_up_edges, - meta_rectangle_find_onscreen_edges, - meta_rectangle_find_nonintersected_xinerama_edges): - modify to handle struts being rectangle + side instead of just rectangle - - * src/workspace.c (ensure_work_areas_validated): - simplify strut list creation considerably given MetaWindow change, - modify work_area computations to take advantage of region - computations being done (makes the code shorter as well as more - robust against pathological cases). - - * src/util.[ch] (meta_free_gslist_and_elements): - new convenience function - - * src/common.h (enum MetaDirection): - * src/edge-resistance.c (movement_towards_edge): - * src/boxes.c (meta_rectangle_edge_aligns, - rectangle_and_edge_intersection, split_edge): - Add more MetaDirection fields for convenience - - * src/boxes.h (enum FixedDirections): - * src/constraints.c (setup_constraint_info, place_window_if_needed): - add a FIXED_DIRECTION_NONE to the FixedDirections enum to make - code more clear - -2007-04-01 Bruno Boaventura - - * src/theme.c (kill_window_question): Fallback to NORMAL state after - checking for the middle button. Fixes bug #419043. - Patch from Benjamin Berg . - -2007-03-31 Elijah Newren - - Clean up event mask handling and meta_create_offscreen_window, to - prevent nasty metacity/gdk interactions causing hangs. See #354213. - - * src/screen.[ch] (meta_create_offscreen_window): - * src/display.c (meta_display_open): - * src/screen.c (meta_screen_new): - Add a valuemask parameter to meta_create_offscreen_window - - * src/display.c (meta_display_open): - make it explicit that we can't rely on PropertyNotify events for - the leader_window due to nasty metacity/gdk interaction - - * src/session.c (warn_about_lame_clients_and_finish_interact): - remove cut-and-paste code for timestamp pinging and just call - meta_display_get_current_time_roundtrip - -2007-03-30 Elijah Newren - - Add support for _NET_WM_USER_TIME_WINDOW in order to cut down on - context switches. Fixes #354213. - - * src/display.c (meta_display_open): - * src/display.h (struct _MetaDisplay): - * src/screen.c (set_supported_hint): - new atom - - * src/display.c (meta_display_open, - meta_display_get_current_time_roundtrip): - * src/display.h (struct _MetaDisplay): - create a dedicated timestamp pinging window instead of reusing - display->leader_window - - * src/display.c (event_callback): - * src/window-props.c (reload_net_wm_user_time_window): - * src/window.c (meta_window_new_with_attrs, meta_window_free, - process_property_notify): - * src/window.h (struct _MetaWindow): - monitor property notify events on _NET_WM_USER_TIME_WINDOW windows too - - * src/window-props.[ch]: - new meta_window_reload_propert(y|ies)_from_xwindow() functions - - * src/window-props.[ch] - (init_net_wm_user_time_window, reload_net_wm_user_time_window, - meta_display_init_window_prop_hooks): - * src/window.c (meta_window_new_with_attrs): - new hooks to handle new atom - -2007-03-26 Josselin Mouette - - * src/session.c (meta_session_init): if previous client ID - was supplied, use it in filename. - * src/session.c (set_clone_restart_commands): use --sm-client-id - in command line to restore session, not original file name. - * src/session.c (regenerate_save_file): generate filename using - client ID and not original file name. - * src/session.c (base_save_file): removed function. - Closes GNOME 407981, Debian 391287, Debian 315169. - -2007-03-25 Elijah Newren - - * configure.in: bump version to 2.19.1; doesn't make sense to have - the development version have a version number less than the stable - version. ;-) - -2007-03-20 Arthur Taylor - - * src/frames.c (meta_frames_apply_shapes): adjusted the rounded - corners so that they fit nicely with the arcs around them. - Fixes #399373. - -2007-03-17 Kjartan Maraas - - * src/ui.c: Remove #include since it's - apparently not installed anymore. Builds just fine without it too. - -2007-03-10 Charlie Brej - - * src/metacity.schemas.in: add action_{middle|right}_click_titlebar. - Closes #408903. - -2007-03-09 Linus Torvalds - - * src/frames.c (meta_frame_middle_click_event, - meta_frame_right_click_event): honour preferences. - * src/prefs.[ch] (meta_prefs_get_action_middle_click_titlebar, - meta_prefs_get_action_right_click_titlebar): new functions. - -2007-02-20 Kjartan Maraas - - * Makefile.am: Add MAINTAINERS to EXTRA_DIST so others - can find out where to send patches. Hi Linus :-) - -2007-02-17 Linus Torvalds - - * src/common.h (MetaActionTitleBar): renamed from - MetaActionDoubleClickTitleBar; added _LOWER and _MENU. - * src/frames.c (meta_frame_titlebar_event): renamed - enums as above; added code to handle _LOWER and _MENU, - which is moved in from meta_frame_{middle|right}_click_event. - * src/frames.c (meta_frame_middle_click_event, - meta_frame_right_click_event): rewrote in terms of - meta_frame_titlebar_event. - * src/prefs.c: removed "DoubleClick" from names as above. - * src/prefs.c (action_titlebar_from_string): added cases - for "lower" and "menu". - Fixes #408902. - -2007-02-17 Linus Torvalds - - * src/frames.c (meta_frames_button_press_event): Split out - code for different kinds of click into separate functions. - Fixes #408899. - * src/frames.c (meta_frame_titlebar_event, - meta_frame_double_click_event, meta_frame_middle_click_event, - meta_frame_right_click_event): new functions. - -2007-01-27 Bruno Boaventura - - * src/metacity-dialog.c (kill_window_question): Change dialog - icon because gnome-icon-theme have no more "panel-force-quit". - Patch from Jaap A. Haitsma . - -2007-01-16 Thomas Thurman - - * doc/compositor-control.txt: fix silly thinko. - -2007-01-16 Thomas Thurman - - * configure.in: post-release bump to 2.17.8. - -2007-01-16 Thomas Thurman - - * doc/compositor-control.txt: New file. - -2007-01-16 Thomas Thurman - - * src/compositor.c (meta_compositor_new): Removed - #ifdef SPIFFY_COMPOSITOR throughout the file. Replaced with check - for environment variable METACITY_BLING, which may be temporary. - -2007-01-13 Bruno Boaventura - - * src/frames.c (meta_frames_motion_notify_event): Unmaximize - button must keep preesed appearence when clicked (hold down), - move off, and back over the button. Fixes #395560. Patch from - Mad Alex . - -2007-01-02 Thomas Thurman - - * src/c-screen.c (meta_comp_screen_redirect): Remove double unref - of stacker object. Fixes #387761. - -2006-12-27 Bruno Boaventura - - Move "On Top" option in menu. Fix #382962. - - * src/common.h, src/core.c: Remove META_MENU_OP_UNABOVE. - * src/menu.c: remove unabove menu item and put above item - next "Always on Visible Viewport". - * src/window.c: remove handles of META_MENU_OP_UNABOVE. - -2006-12-21 Thomas Thurman - - * src/compositor.c: Disabled bling for now; added function for - handling CirculateNotify XEvent; some commenting. - * src/compositor.h, src/c-window.c: fix function prototype visibility. - -2006-12-12 Thomas Thurman - - * src/compositor.c (do_effect): Sanity check to avoid dereferencing - a null pointer. - -2006-12-10 Thomas Thurman - - * configure.in: post-release bump to 2.17.5. - -2006-12-10 Thomas Thurman - - * NEWS: 2.17.3 release. - -2006-12-05 Christof Krüger - - * src/window.c (update_move): Fix flickering about when dragging - maximised windows between xineramas. Closes #358715. - -2006-12-03 Federico Mena Quintero - - Fix http://bugzilla.gnome.org/show_bug.cgi?id=381127: - - * src/window.c (idle_calc_showing): Grab the server while the - windows are being shuffled. First show the windows to be shown, - and then hide the windows to be hidden, in order to minimize - the number of expose events. - -2006-11-15 Bruno Boaventura -2006-11-15 Björn Lindqvist - - * src/menu.c: added MetaMenuItemType enum; added it - to MenuItem; added values of this type to menuitems - array. - * src/menu.c (menu_item_new): rewrite to take a MenuItem - instead of a set of parameters describing the menu item. - * src/menu.c (meta_window_menu_new): use proper checkboxes - or radio buttons on the window menu. (#343108) - * src/window.c (meta_window_show_menu): unstick and stick - are always shown. - -2006-11-06 Thomas Thurman - - * configure.in: post-release bump to 2.17.3. - -2006-11-06 Thomas Thurman - - * configure.in: pre-release bump to 2.17.2. - * NEWS: 2.17.2 release. - -2006-11-05 Priit Laes - - * src/main.c, src/ui.c: remove deprecated gtk stuff. - -2006-11-05 Bruno Boaventura - - * src/theme.c, src/testgradient.c: remove deprecated gtk stuff. - -2006-11-05 Kjartan Maraas - - * src/ui.c: use g_strdup to allocate a string, not strdup. Fixes - #363354. - * src/metacity-dialog.c: add missing spaces to string. Fixes - #363355. - -2006-11-05 Justin Mason - - * src/keybindings.c: implement handle_move_to_{side|corner}_* to - allow the user to flip a window to the side or corner of the - screen. Fixes #317884. - * src/prefs.h: keybindings for the above. - * src/metacity.schemas.in: keybindings for the above. - -2006-11-05 Elijah Newren - - * src/frames.c: improved rounding of rounded corners. Fixes #360542, - mostly. - -2006-10-30 Dan Mick - - * src/window.c: (__window_is_terminal): Fix strict focus - mode by picking up on res_class. Fixes #361054, strict focus - mode still not working; should look for res_class, not res_name - -2006-10-16 Elijah Newren - - * NEWS: 2.17.1 release. - -2006-10-13 Carlo Wood - - Fix cases when titlebar is allowed offscreen and shouldn't be (and - vice-versa). #333995. - - * src/display.[ch] (struct _MetaDisplay): add grab_frame_action - member - - * src/display.[ch] (meta_display_begin_grab_op): - * src/window.[ch] (meta_window_begin_grab_op): - * src/core.[ch] (meta_core_begin_grab_op): - Add frame_action parameter (core & window versions pass it on to - display) - - * src/display.c (event_callback): - * src/window.c (meta_window_begin_grab_op, - meta_window_client_message, menu_callback): - * frames.c (meta_frames_button_press_event): - * keybindings.c (do_choose_window, handle_begin_move, - handle_begin_resize, handle_workspace_switch): - Pass whether the action should be considered a 'frame_action', - which will be used to determine whether to force the titlebar to - remain onscreen, to meta_*_begin_grab_op - - * constraints.c (constrain_titlebar_visible): - Replace previous ugly hack by using grab_frame_action (and whether - the action is a user action) to determine whether to enforce the - titlebar_visible constraint. - -2006-10-10 Elijah Newren - - * src/draw-workspace.c (draw_window, wnck_draw_workspace): Patch - from Bruno Boaventura to sync metacity workspace previews with - libwnck. #341893 - -2006-10-07 Thomas Thurman - - * configure.in: post-release bump to 2.17.1. - -2006-10-07 Thomas Thurman - - * NEWS: 2.17.0 release. - -2006-10-07 Thomas Thurman - - * src/themes/Crux/metacity-theme-2.xml: removed hide_buttons. - Closes #360498. - -2006-10-07 Thomas Thurman - - * MAINTAINERS: added myself. - -2006-10-07 Thomas Thurman - - * doc/theme-format.txt: described new theme format. - - * src/themes/Bright, src/themes/Crux: added version 2 themes. - -2006-10-07 Thomas Thurman - - * common.h: Added "above" to the list of flags a frame can have, so - that we know when to mark it as always on top. Added six grab ops, - one to do and one to undo each of the three new titlebar buttons - (shade, above, stick). Added six new button functions, similarly. - (#96229) - - * frame.c (meta_frame_get_flags): If a frame has the WM_STATE_ABOVE X - attribute, set META_FRAME_ABOVE in its flags. - - * frames.c (meta_frames_apply_shapes): Allow variable amounts of - rounding. (#113162) - - * frames.c (show_tip_now, meta_frames_paint_to_drawable, control_rect, - get_control): extend handling of existing buttons to the - 3*2 new kinds of button. (#96229) - - * frames.c (meta_frames_button_press_event): translate clicks on the 3*2 - new kinds of button to the new grab ops. (#96229) - - * frames.c (meta_frames_button_release_event): implement the various - actions for the 3*2 new kinds of button. (#96229) - - * frames.c (meta_frames_update_prelit_control, - meta_frames_motion_notify_event): extend existing motion - notifications for buttons to the 3*2 new kinds of button. (#96229) - - * frames.c (meta_frames_set_window_background): handle specified - background colours and alpha transparency. (#151261) - - * frames.h (MetaFrameControl): New control types for the 3*2 new kinds - of button. (#96229) - - * iconcache.[ch] (meta_read_icons): use theme's fallback icons if a - window has no icon; use metacity's fallback icons only if the theme - does not provide any. (#11363) - - * iconcache.[ch] (meta_invalidate_default_icons (new function)): clear - icon cache on windows using default icons, and update them. (#11363) - - * main.c (main): added \n to error message. - - * prefs.c (button_function_from_string): extend for 3 new button - types. (#96229) - - * prefs.c (button_opposite_function (new function)): return a button - function's inverse (shade -> unshade, etc) (#96229) - - * prefs.c (update_button_layout): allocate space for a button's - inverse, if it has one. (#96229) - - * theme-parser.c (ParseState): add state for fallback icons (#11363) - - * theme-parser.c (ParseInfo): add format_version; remove - menu_icon_* (#114305) - - * theme-parser.c (parse_positive_integer): add lookup for integer - constants (#331356) - - * theme-parser.c (parse_rounding (new function)): parse window - rounding amount (#113162) - - * theme-parser.c (parse_alpha): don't set error if the number can't - be parsed since it'll already be set; change tolerance in comparison - from 1e6 to 1e-6 - - * theme-parser.c (parse_color (new function)): parse colour, including - possible constant lookup. - - * theme-parser.c (parse_toplevel_element): allow defining of various - new kinds of constant; allow - hide_buttons (#121639) and more detailed rounding attributes on - (#113162); allow background and alpha attributes on - ; (#151261) remove support for except as - stub; (#114305) add support for loading stock images (#113465); add - support for . (#11363)) - - * theme-parser.c (parse_draw_op_element): add from and to attribute - for arcs. (#121603) - - * theme-parser.c (parse_style_element): add check for theme version - supporting a button function. (#96229) - - * theme-parser.c (parse_style_set_element): add ability for shaded - windows to be resizable (#114304) - - * theme-parser.c (meta_theme_load): add theme versioning routine. - - * theme.c ( meta_frame_layout_get_borders): return rectangles for - the new 3*2 kinds of button, except where they're - inapplicable. (#96229) - - * theme.c (meta_frame_layout_calc_geometry): don't format buttons on - windows with no buttons (#121639); strip the 3*2 new kinds of button - correctly (#96229); allow variable amounts of rounding (#113162). - - * theme.c (meta_frame_style_new): set alpha to 255 by - default. (#151261) - - * theme.c (meta_frame_style_unref): free colour spec if - allocated. (#151261) - - * theme.c (meta_frame_style_validate): it's only an error not to - include a button if that button is valid in the current - theme. (#96229) - - * theme.c (button_rect): return rectangles for the new 3*2 kinds - of button. (#96229) - - * theme.c (meta_frame_style_set_unref): free differently resizable - shaded styles. (#114304) - - * theme.c (get_style): look up differently resizable styles - for shaded windows. (#114304) - - * theme.c (free_menu_ops (removed function), get_menu_icon - (removed function), meta_theme_draw_menu_icon (removed function), - meta_menu_icon_type_from_string (removed function), - meta_menu_icon_type_to_string (removed function), - meta_theme_free, meta_theme_validate): removed menu icon code. (#114305) - - * theme.c (meta_theme_load_image): add size_of_theme_icons - parameter. (#113465) - - * theme.c (meta_theme_define_color_constant (new function), - meta_theme_lookup_color_constant (new function)): allow - definition of colour constants. (#129747) - - * theme.c (meta_button_type_from_string, meta_button_type_to_string): - add the 3*2 new kinds of button. (#96229) - - * theme.c (meta_theme_earliest_version_with_button (new function)): - return the theme version each button was introduced in. (#96229) - - * theme.h ( MetaFrameLayout): add "hide_buttons" flag (#121639) and - corner radiuses. (#113162) - - * theme.h (MetaFrameGeometry): add rectangles for the 3*2 new - buttons. (#96229) - - * theme.h (MetaButtonType): the 3*2 new buttons. (#96229) - - * theme.h (MetaFrameStyle): add window_background_color and - window_background_alpha so that we can specify background on a - . (#151261) - - * theme.h (MetaFrameStyleSet): shaded_styles gets resize - dimension. (#114304) - - * theme.h (MetaTheme): added format_version, color_constants - hash, (#129747) fallback_icon and fallback_mini_icon, (#11363) - and removed menu_icons. (#114305) - - * theme.h (META_THEME_ALLOWS (new macro)): return whether a theme - supports a given feature. Also, several macros representing - new features in v2. - - * ui.c (meta_ui_set_current_theme)): also invalidate default - icons. (#11363) - - * window.[ch] (meta_window_update_icon_now)): became - non-static. (#11363) - -2006-10-06 Elijah Newren - - * src/metacity-dialog.c (kill_window_question): Be nice to - translators; remove unnecessary markup from strings marked for - translation (oops, I missed this in my review before previous - commit) - -2006-10-06 Elijah Newren - - * src/metacity-dialog.c (kill_window_question): Patch from Bruno - Boaventura to improve the "Force Quit" dialog. #121936 - -2006-10-02 Elijah Newren - - Ignore edge resistance for size-increment windows when resizing - with the keyboard. #346782. - - * src/edge-resistance.c (apply_edge_resistance_to_each_side): - ignore edge resistance for size-increment windows when resizing - with the keyboard, (apply_edge_resistance_to_each_side, - meta_window_edge_resistance_for_move, - meta_window_edge_resistance_for_resize): pass a is_resize - parameter as well - -2006-10-01 Elijah Newren - - * src/display.c (meta_display_set_input_focus_window): - * src/window.c (meta_window_focus): - Don't require a push/pop trap around - meta_display_set_input_focus_window(), but rather move the - push/pop into that function surrounding the XSetInputFocus() call - directly. Follow up to #358514. - -2006-10-01 Elijah Newren - - * src/*.[ch]: Stick an emacs comment directive at the beginning of - all the code files so that people using emacs will be more likely - to get coding style correct in their patches. We still need a - similar vi directive. #358866 - -2006-10-01 Elijah Newren - - Patch from Carlo Wood to ensure that maximized and minimized - properties are maintained across restarts. #358042. - - * src/constraints.c (place_window_if_needed): fix up partial - maximization handling and add minimize_after_placement handling. - - * src/display.[ch] (struct MetaDisplay, meta_display_open): add a - new display->display_opening flag to allow handling startup - differently where needed. - - * src/window-props.c (reload_net_wm_state): handle - _net_wm_state_hidden as well, setting - window->minimize_after_placement appropriately - - * src/window.[ch] (struct MetaWindow, meta_window_new_with_attrs): - add a window->minimize_after_placement field - - * src/window.c (meta_window_new_with_attrs): only unminimize the - window and its transients if the display isn't being opened, - (unmaximize_window_before_freeing): don't reset the state unless - the window is becoming withdrawn, if the screen is being closed be - sure to save the unmaximized state of the window so the next - window manager can restore it - -2006-10-01 Elijah Newren - - * src/window-props.c (set_title_text): surround the - XDeleteProperty() call with a - meta_error_trap_push/meta_error_trap_pop pair to prevent a crash - when closing a remote instance of gedit (and perhaps other apps). - #358514. - -2006-10-01 Elijah Newren - - Fix longstanding focus bug with mouse (not sloppy) focus mode with - popup override-redirect windows, particularly mozilla and - firefox's location bar autocompletion. #357695. - - * src/display.c (event_callback -- EnterNotify & LeaveNotify events): - for mouse focus, defocus the focused window when the mouse enters - the desktop window rather than when the mouse leaves the focused - window. - - * doc/how-to-get-focus-right.txt: - update for the slightly nuanced definition of mouse focus (people - without a DESKTOP window like nautilus get sloppy focus behavior - now) - -2006-09-27 Elijah Newren - - * src/menu.c (var menuitems): Patch from Bruno Boaventura to add - notes to remind translators to keep translations in sync with - libwnck. #355620. - -2006-09-18 Elijah Newren - - * src/window.c (meta_window_show): Patch from Jens Granseuer to - fix c89 cleanness, again. #356631. - -2006-09-18 Elijah Newren - - * src/constraints.c (constrain_maximization): Ignore maximum size - hints when maximizing. Should fix #327543 (see comment 4 and comment - 5). - -2006-09-18 Elijah Newren - - * src/ui.c (filter_func): avoid a compilation warning by making - sure to return something. #348067 - -2006-09-18 Thomas Thurman - - Branched for Gnome 2.17. - - * configure.in: bump version to 2.17.0. - -2006-09-18 Thomas Thurman - - * configure.in: post-release bump to 2.16.3 - -2006-09-18 Thomas Thurman - - * NEWS: 2.16.2 release - -2006-09-18 Elijah Newren - - Partial audit to fix timestamp usage. One step towards fixing - #355180; see important comments in that bug. - - * src/core.[ch] (meta_core_unshade, meta_core_shade): - * src/delete.c (meta_window_present_delete_dialog, - delete_ping_timeout_func): - * src/display.[ch] (meta_display_open, meta_display_close, - event_callback, meta_display_begin_grab_op, - process_selection_clear, meta_display_unmanage_screen, - meta_display_unmanage_windows_for_screen): - * src/frames.c (meta_frames_button_press_event): - * src/keybindings.c (handle_toggle_shade): - * src/main.c (main): - * src/screen.[ch] (update_num_workspaces, meta_screen_new, - meta_screen_free, prefs_changed_callback): - * src/window.[ch] (meta_window_free, finish_minimize, - implement_showing, meta_window_show, meta_window_maximize, - meta_window_make_fullscreen_internal, - meta_window_unmake_fullscreen, meta_window_shade, - meta_window_unshade, window_activate, send_sync_request, - meta_window_client_message, menu_callback, - meta_window_update_keyboard_resize): - Remove usage of CurrentTime, meta_display_get_current_time() and - meta_display_get_current_time_roundtrip() where possible, or - document why it isn't possible, or at very least add a FIXME with - some explanation of my laziness and what needs to be done. - -2006-09-18 Elijah Newren - - * src/spring-model.c (on_end_move, model_is_calm): Patch from Maik - Beckmann to remove compilation warnings. Fixes #355876. - -2006-09-18 Elijah Newren - - * configure.in: Make detection of stable vs. unstable automatic - and based upon the version number. Partially based on patch from - Christian Hamar in #356122. Fixes #356122. - -2006-09-13 Elijah Newren - - * HACKING: update -- we depend on gtk+ >= 2.10 since Vincent's - July patches for #348633. - -2006-09-13 Elijah Newren - - * src/window.c (meta_window_show): Patch from Thomas Andersen to - make windows be stacked correctly before showing them, to prevent - flicker with focus stealing prevention. #332385. - -2006-09-13 Elijah Newren - - * src/common.h (MetaWindowMenuFunc): - * src/core.[ch] (meta_core_user_lower_and_unfocus, - meta_core_user_focus, meta_core_show_window_menu, - meta_core_begin_grab_op, meta_core_end_grab_op): - * src/delete.c (delete_ping_reply_func, delete_ping_timeout_func, - meta_window_delete): - * src/display.[ch] (struct MetaDisplay, struct MetaPingData, - sanity_check_timestamps, meta_display_open, event_callback, - meta_spew_event, meta_display_set_grab_op_cursor, - meta_display_begin_grab_op, meta_display_end_grab_op, - meta_display_ping_timeout, meta_display_ping_window, - process_pong_message, timestamp_too_old, - meta_display_set_input_focus_window): - * src/keybindings.[ch] (grab_keyboard, ungrab_keyboard, - meta_screen_grab_all_keys, meta_window_grab_all_keys, - meta_window_ungrab_all_keys, error_on_generic_command, - error_on_command, error_on_terminal_command): - * src/metacity-dialog.c (on_realize, warn_about_no_sm_support, - error_about_command, main): - * src/screen.[ch] (struct _MetaScreen, meta_screen_new, - meta_screen_show_desktop, meta_screen_apply_startup_properties): - * src/session.c (warn_about_lame_clients_and_finish_interact): - * src/window.[ch] (struct _MetaWindow, - intervening_user_event_occurred, window_activate, - meta_window_delete, meta_window_focus, - meta_window_send_icccm_message, meta_window_client_message, - menu_callback, meta_window_show_menu, struct EventScannerData, - check_use_this_motion_notify, meta_window_begin_grab_op, - meta_window_set_user_time): - * src/workspace.[ch] (focus_ancestor_or_mru_window, - meta_workspace_activate_with_focus, meta_workspace_activate, - meta_workspace_focus_default_window, - focus_ancestor_or_mru_window): - Fix issues on 64-bit machines with timestamps by using guint32 - (like gtk+ does) instead of Time. #348305 - -2006-09-12 Elijah Newren - - * src/theme.c (meta_gtk_arrow_from_string, - meta_gtk_arrow_to_string): patch from Bruno Boaventura de Oliveira - to fix a compiler warning about not handling GTK_ARRROW_NONE. - #355490. - -2006-09-12 Elijah Newren - - * src/compositor.c: Patch from Bruno Boaventura de Oliveira - Lacerda to fix warnings about unused function and global var. - #355489. - -2006-09-11 Thomas Thurman - - * configure.in: post-release bump to 2.16.2 - -2006-09-11 Thomas Thurman - - * NEWS: 2.16.1 release - -22006-09-09 Elijah Newren - - * src/display.c (meta_display_open): Fix build when XKB not found. - #354211 - -2006-09-09 Elijah Newren - - Avoid a stuck grab, preventing focus from being transferred - between windows. Thanks to Fryderyk Dziarmagowski for steps to - reproduce. Fixes at least part of #354422. - - * src/display.c (meta_display_begin_grab_op, - meta_display_end_grab_op): pass timestamp to - meta_screen_ungrab_all_keys, meta_screen_ungrab_all_keys, and - meta_window_ungrab_all_keys - - * src/keybindings.[ch] (grab_keyboard, ungrab_keyboard): add a - timestamp parameter and remove call to - meta_display_get_current_time(), (meta_screen_grab_all_keys, - meta_screen_ungrab_all_keys, meta_window_ungrab_all_keys): add a - timestamp parameter and pass it on to grab_keyboard and - ungrab_keyboard - -2006-09-07 Elijah Newren - - * src/constraints.c (update_onscreen_requirements): make sure - windows returning from fullscreen mode are constrained to be - "onscreen"; fixes #353699. - -2006-08-30 Colin Watson - - * src/window-props.c (reload_transient_for): Clear - window->xtransient_for after emitting the invalid window warning. - #353540 - -2006-09-07 Elijah Newren - - * src/metacity-dialog.c: Patch from Bruno Boaventura de Oliveira - Lacerda to replace copy_of_gdk_x11_window_set_user_time() with - gdk_x11_window_set_user_time(). We've long since adopted gtk+ >= - 2.6 as a dependency. #352293 - -2006-09-04 Thomas Thurman - - * configure.in: post-release version bump to 2.16.1 - -2006-09-04 Thomas Thurman - - * NEWS: 2.16.0 release - -2006-08-22 Elijah Newren - - * src/metacity-dialog.c (main): Patch from Jens Granseuer to fix - the build with c89/gcc 2.95. - -2006-08-21 Elijah Newren - - * NEWS: Oops, forgot to mention the translators in the 2.15.34 - release; add them retroactively - -2006-08-21 Elijah Newren - - * configure.in: post-release version bump to 2.15.55 - -2006-08-21 Elijah Newren - - * NEWS: 2.15.34 release - -2006-08-21 Elijah Newren - - Patch from Thomas Andersen to fix metacity-dialog handling of - arguments. #340690 - - * src/metacity-dialog.c (main): replace hackish argument parsing - with GOption parsing. Much nicer. :) - -2006-08-21 Elijah Newren - - Patch from Ed Catmur to fix keybindings with hex-values (coming - from special extended keyboard keys). #140448. - - * src/keybindings.c (struct _MetaKeyBinding): change keycode from - KeyCode to unsigned int (comment from Elijah: why???), - (reload_keycodes): only grab keysyms for keybindings that have - them, (count_bindings, rebuild_binding_table): bindings can be - valid either due to a valid keysym or a valid keycode, - (display_get_keybinding_action, meta_change_keygrab, - process_tab_grab, process_workspace_switch_grab): handle keycode - as well as keysym - - * src/prefs.[ch] (struct MetaKeyCombo, update_binding, - update_list_binding): handle keycode as well as keysym - - * src/ui.[ch] (meta_ui_accelerator_parse): new function special - cases strings of the form "0x[0-9a-fA-F]+" and otherwise calling - gtk_accelerator_parse(), (meta_ui_parse_accelerator, - meta_ui_parse_modifier): call meta_ui_accelerator_parse instead of - gtk_accelerator_parse. - -2006-08-21 Elijah Newren - - Allow drags & resizes to be reverted by hitting escape. Based on - patch from Thomas Andersen. #126497. - - * src/display.c (grab_op_is_mouse_only): new function, - (meta_display_begin_grab_op): grab the keyboard when moving or - resizing too so that we can get escape keypresses - - * src/display.h (struct _MetaDisplay): add a comment to remind - that grab_was_cancelled is only used in wireframe mode - - * src/keybindings.[ch] (process_mouse_move_resize_grab): add new - function for handling keypresses during mouse-only moving and - resizing, (meta_window_grab_all_keys): add a timestamp parameter - and pass it to meta_window_focus(), - (meta_display_process_key_event): make sure - process_mouse_move_resize_grab() gets called when needed, - (process_keyboard_move_grab, process_keyboard_resize_grab): - rearrange some code slightly and improve the comments to make it - more readable - -2006-08-21 Elijah Newren - - Fix several bugs with handling of fullscreen windows, causing them - to not actually be fullscreen. #343115 (and also #346927, - #350547, #351643, the recent additional WINE-related issue - mentioned on the mailing list, and probably others...) - - * src/constraints.c (setup_constraint_info): if a window tries to - resize to fullscreen-size and it has a fullscreen function but - isn't actually marked as fullscreen then assist it by marking it - as such, (constrain_fully_onscreen, constrain_titlebar_visible): - ignore this constraint for fullscreen windows since such windows - have a separate specialized constraint - - * src/stack.c (window_is_fullscreen_size, get_standalone_layer): - remove the old window_is_fullscreen_size() hack for detecting - windows to treat as fullscreen since it doesn't work well with the - new constraints framework (i.e. we needed a slightly different - hack) - - * src/window.[ch] (meta_window_new_with_addrs): shuffle the order - of adding the window to the stack and moveresizing the window - since moveresizing can cause stack changes if the window's initial - size is fullscreen size, (meta_window_make_fullscreen, - meta_window_make_fullscreen_internal): split - meta_window_make_fullscreen() similar to meta_window_maximize() so - that constraints can make use of it - -2006-08-19 Baptiste Mille-Mathias - - * src/stock_delete.png: Update the pixmap to a new one which - fit better with the other pixmaps of the menu. First patch in - metacity, woot! #345498 - -2006-08-18 Elijah Newren - - * src/tabpopup.c (meta_ui_tab_popup_new): Patch from Willie Walker - to restore the part of the patch that I should not have reverted - in #123372, in order to fix accessibility. #350624 - -2006-08-09 Elijah Newren - - * src/window.c (intervening_user_event_occurred): Vytautus Liuolia - totally rocks; he tested and debugged and tracked down where we - were using the focus window's net_wm_user_time even when it was - uninitialized. This may fix bug 311868 and others I've heard - about (with Valknut, IIRC). It definitely fixes the issues Vytas - was seeing with his single instance library. :-) - -2006-08-07 Elijah Newren - - * src/constraints.c (setup_constraint_info): patch from Stéphane - Rosi to allow moving maximized windows between xineramas again. - #323820 - -2006-08-07 Elijah Newren - - * configure.in: post-release version bump to 2.15.34 - -2006-08-07 Elijah Newren - - * NEWS: 2.15.21 release - -2006-08-07 Elijah Newren - - Add a constrain_titlebar_visible constraint; should fix both bug - 333328 and bug 345522. Not perfect (minor annoying snap pulling - windows back onscreen, plus an ugly hack almost as bad as the old - one), but tarballs are due in less than half an hour. ;-) - - * src/boxes.[ch] (meta_rectangle_overlaps_with_region): - new function - - * src/constraints.c (constrain_titlebar_visible): new function, - (enum ConstraintPriority, array all_constraints, - update_onscreen_requirements): various small changes to - accomodate the new function - - * src/edge-resistance.c: remove the infinite edge resistance, - which was a big hack of a way to workaround the lack of a - titlebar_visible constraint - - * src/window.[ch] (MetaWindow): new require_titlebar_visible - bitfield, (meta_window_new_with_attrs): initialized here - -2006-08-07 Elijah Newren - - * src/frames.c (meta_frames_button_press_event): Patch from Chris - Ball to not minimize in response to double clicks on the titlebar - when minimiziation should not be allowed. #347377 - -2006-08-07 Elijah Newren - - Patch from Björn Lindqvist to fix button lighting with dragged - clicks. #321474. - - * src/frames.c (meta_frames_button_press_event): update the - prelit_control, (meta_frames_button_release_event): some code - refactoring to simplify things a bit, and make sure to update the - prelit_control - -2006-08-07 Elijah Newren - - * src/keybindings.c (process_keyboard_move_grab): Patch from - Thomas Andersen to return the window to maximized state if the - window was "shaken loose" from maximized state during a resize but - the resize is later aborted. #346719. - -2006-08-07 Elijah Newren - - Patch from Vytautas Liuolia to react to _NET_STARTUP_ID changes, - as proposed for the new startup-notification/EWMH spec. #347515 - - * src/window-props.c (reload_net_startup_id): be sure to act on - the new id instead of just recording it - - * src/window.[ch] (window_activate, meta_window_activate, - meta_window_activate_with_workspace, meta_window_client_message): - change window_activate() to take a workspace parameter instead of - hardcoding to the current workspace, add - meta_window_activate_with_workspace() function needed by - reload_net_startup_id(). - -2006-08-07 Thomas Thurman - - * src/frames.h: add new MetaButtonSpace struct; use it for - close_rect, max_rect, min_rect and menu_rect. (#97703) - - * src/frames.c (control_rect, get_control): modify to support - the new fields in MetaButtonSpace. - - * src/theme.c (meta_frame_layout_get_borders, rect_for_function, - meta_frame_layout_calc_geometry, button_rect): add support for - the new fields in MetaButtonSpace. - -2006-08-07 Elijah Newren - - * src/screen.c (meta_screen_resize_func): patch from Dmitry - Timoshkov to make sure window features get recalculated when the - screen is resized via XRandR. Part of #346927. - -2006-08-04 Elijah Newren - - Patch from Dmitry Timoshkov to fix the heuristic for determining - if windows can be made fullscreen (needed for WINE and possible - also some legacy applications). Part of #346927. - - * src/window.c (recalc_window_features): ignore window decoration - when checking size for determing whether an unresizable window - should be allowed ot be considered for fullscreening - -2006-07-31 Björn Lindqvist - - * src/window.c: Make it so maximized windows do not have rounded - corners. #336850. - -2006-07-30 Jens Granseuer - - * src/tabpopup.c: Fix another C89 vs. C99 issue. #347621. - -2006-07-26 Vincent Untz - - * src/update-from-egg.sh: also kill this - -2006-07-25 Vincent Untz - - * src/Makefile.am, ui.c: Kill usage of libegg. #348633. - -2006-07-24 Thomas Thurman - - * configure.in: post-release version bump to 2.15.21 - -2006-07-24 Thomas Thurman - - * NEWS: 2.15.13 release - -2006-07-24 Björn Lindqvist - - * src/display.c (meta_display_grab_window_buttons): Grab - Alt+Shift+Button1 as well to partially fix operation ordering - issues when trying to snap-move windows. Part of #112478. - -2006-07-21 Thomas Thurman - - * ui.[ch] (filter_func): Avoid a case where a struct's - fields might be updated after it was freed. #348067. - -2006-07-10 Elijah Newren - - * configure.in: post-release version bump to 2.15.13 - -2006-07-10 Elijah Newren - - * NEWS: 2.15.8 release - -2006-06-12 Elijah Newren - - * configure.in: post-release version bump to 2.15.8 - -2006-06-12 Elijah Newren - - * NEWS: 2.15.5 release - -2006-06-10 Elijah Newren - - Patch from Aidan Delaney to tidy tabpopup.c by factoring out - tab_entry_new(). #166890. - - * src/tabpopup.c (tab_entry_new): new function, - (meta_ui_tab_popup_new): use tab_entry_new() to remove a big chunk - of code, plus a few other small cleanups. - -Tue Jun 6 12:46:42 2006 Søren Sandmann - - * configure.in (GETTEXT_PACKAGE): Bunp intltool requirement to - 0.35.0. - -2006-05-29 Elijah Newren - - * HACKING: Slightly more detailed instructions on setting up a - build environment to mention relevant development tools in - addition to the needed development libraries. - -Fri May 26 16:48:29 2006 Søren Sandmann - - * src/effects.c (meta_effect_run_unminimize): Run an unminimize effect - - * src/window.c (meta_window_unminimize): Store a "was_minimized" - boolean in the window. - - * src/window.c (meta_window_show): If the window was minimized, - run an unminimize animation. - - * src/c-window.c (meta_comp_window_run_unminimize): Add an - unminimize animation, running the minimize one in reverse. - -Fri May 26 14:55:07 2006 Søren Sandmann - - * src/c-window.c (meta_comp_window_run_focus): Rename from - _bounce() to _focus(). - -2006-05-26 Elijah Newren - - * src/display.c (meta_display_close): Fix a crash on exit/logout - from assuming a compositor would always exist - -2006-05-25 Elijah Newren - - * src/place.h: - * src/common.h: - Remove MetaWindowEdgePosition enum that isn't used anymore - -Thu May 25 15:56:43 2006 Søren Sandmann - - * src/effects.h (struct MetaEffect): Move duplicated window field - outside the union - - * src/compositor.c: delete duplicated code to get at the window. - -Thu May 25 15:17:29 2006 Søren Sandmann - - * src/c-window.c: Fix compilation in non-compositor case, by - moving the stack functions into the HAVE_COMPOSITOR defines. - -Thu May 25 15:11:58 2006 Søren Sandmann - - * src/c-window.h: Add a destroy notifier to the window. - - * src/c-screen.c (on_window_destroy): New function. - - * src/c-screen.c (meta_comp_screen_add_window): Use the destroy - notifier here. - - * src/c-window.c (generate_phases): New function. Simplify the - minimize animation a lot by generating all the rectangle - information into an array, then processing that. - -2006-05-25 Adam Jackson - - * src/c-window.c: - * src/c-window.h: - * src/compositor.c: - * src/compositor.h: - * src/effects.c: - * src/effects.h: - * src/spring-model.c: - * src/window.c: - Bounce on window focus. - -Wed May 24 22:15:01 2006 Søren Sandmann - - * src/compositor.c (do_effect): Make sure windows are kept on top - of the panel during minimize. - -Wed May 24 21:17:59 2006 Søren Sandmann - - * src/compositor.c (do_effect): Shrink the window instead of - explode it. - - * src/compositor.c (do_effect): don't read the frame if it is - NULL. - - * src/c-window.c (meta_comp_window_run_minimize): Resurrect the - shrinking minimize animation. - - * src/c-window.c (meta_comp_window_fade_in): Make dialogs 90% - translucent. - - * src/c-window.c (update_fade): End at end_fade, not 1.0. - -Wed May 24 19:15:45 2006 Søren Sandmann - - * src/c-window.c (cancel_fade): Add a fade-in animation when - windows are mapped. - -Wed May 24 16:37:11 2006 Søren Sandmann - - * src/c-window.c (private_metacity_window): New function - - * src/c-window.c (meta_comp_window_refresh_attrs): Map metacity's - own windows directly. - -Wed May 24 16:35:54 2006 Søren Sandmann - - * src/c-window.c (private_metacity_window): - -Wed May 24 14:36:42 2006 Søren Sandmann - - * src/c-window.c (meta_comp_window_{freeze,thaw}_stack: Add a - stack-freeze feature to CWindow. - - * src/c-screen.c (meta_comp_screen_restack): Don't restack if the - window is frozen. - -Wed May 24 13:09:49 2006 Søren Sandmann - - * src/c-window.c: Fix compilation in the non-composited case. - -Wed May 24 12:57:32 2006 Søren Sandmann - - * src/c-window.c (meta_comp_window_free): return TRUE when the - window is actually freed. - - * src/compositor.c (do_effect): Disable updating before exploding - the window. - - * src/c-window.c: Make MetaCompWindow refcounted. - - * src/c-window.[ch]: New functions meta_comp_window_{show,hide} - - * src/c-screen.c (meta_comp_screen_unmap): Call - meta_comp_window_hide() instead of directly setting the viewable - status of the node. - - * src/c-screen.c (meta_comp_screen_remove_window): Only remove the - window when it is actually freed. - -Wed May 24 12:45:21 2006 Søren Sandmann - - * src/c-screen.c: Delete unused meta_comp_screen_hide_window(). - -2006-05-23 Adam Jackson - - * src/c-window.c: - * src/c-window.h: - * src/compositor.c: - * src/effects.c: - * src/effects.h: - * src/window.c: - Move shrink effect code from compositor.c to c-window.c. Stubs for - restore effect. Notes in various places for where to hook in - other effects. - -Tue May 23 16:36:04 2006 Søren Sandmann - - * src/compositor.c (do_effect): Also use explode when windows close. - - * src/c-window.c (meta_comp_window_explode): Add refcounting to - comp window, and use it in the explosion effect - - * src/effects.h (struct MetaEffect): Add new MetaCloseEffect. - - * src/display.c (event_callback): Run it from the UnmapNotify - event handler. - -Tue May 23 15:23:58 2006 Søren Sandmann - - * src/c-window.c (send_sync_request): New function to send a sync - request to newly mapped windows. - (on_request_alarm): Show the window here. - -2006-05-23 Adam Jackson - - * src/effects.h: - Add more effect tokens. - -Mon May 22 17:35:52 2006 Søren Sandmann - - * src/effects.[ch]: Beginning of new layer that abstracts - transition effects. - - New functions: - (meta_push_effect_handler): Install an effect handler - (meta_pop_effect_handler): Remove last effect handler - (meta_effect_run_minimize): Create a minimize effect and pass it - to the handler. - (meta_effect_end): Called by handler when the effect is finished. - - * src/compositor.c: Move explosion code form there to src/c-window.c. - - * src/c-screen.c: Delete explosion related code. - -2006-05-22 Björn Lindqvist - - * common.h (enum MetaCursor): - * display.c (meta_display_create_x_cursor): Make mouse cursor when - moving windows become a hand. Fixes #337376. - -2006-05-19 Björn Lindqvist - - * frames.c: Fix a logic bug so that the whole titlebar becomes - sensitive to mouse clicks. Fixes #336320. - -2006-05-18 Björn Lindqvist - - * resizepopup.c: Remove the unused attributes resize_gravity, - width_inc, height_inc, min_width, min_height, frame_left, - frame_right, frame_top, frame_bottom, tick_origin_x, tick_origin_y - from the MetaResizePopup struct. Delete all code that references - those attributes. - -2006-05-15 Elijah Newren - - * configure.in: post-release version bump to 2.15.5 - -2006-05-15 Elijah Newren - - * NEWS: 2.15.3 release - -2006-05-15 Elijah Newren - - Revert the accessibility module loading workaround from Gnome - 2.6, since gtk+ has long since fixed this for us. #123372. - - * src/Makefile.am: remove METACITY_LIBDIR define - - * src/main.c (find_accessibility_module, - accessibility_invoke_module, accessibility_invoke, main): remove - the first three of these functions and all calls to them - - * src/tabpopup.c (meta_ui_tab_popup_new): not sure if this part of - 120025 needed to be reverted but doing the reversion, if wrong, is - the best way to get someone from the accessibility team to scream, - er, I mean comment. ;-) - -2006-05-15 Elijah Newren - - * src/screen.c (reload_xinerama_infos): Patch from - jylefort@FreeBSD.org to prevent a crash when changing resolution. - Fixes #340847. - -2006-05-15 Björn Lindqvist - - * places.[ch] (intcmp, window_get_edges, - get_windows_showing_on_same_screen, get_vertical_edges, - get_horizontal_edges, meta_window_find_next_vertical_edge, - meta_window_find_next_horizontal_edge, - meta_window_find_nearest_vertical_edge, - meta_window_find_nearest_horizontal_edge): Remove the preceeding - functions as they are all obsoleted by the new edge-resistance - stuff. Fixes #341561. - -2006-05-15 Paolo Borelli - - * src/prefs.c (update_binding): plug a small leak. - -2006-05-12 Elijah Newren - - * configure.in: I don't think we want a config file for the - no-gconf case; embedded people would prefer hard-coding things - into the binary - (http://mail.gnome.org/archives/metacity-devel-list/2006-May/msg00010.html) - -2006-04-25 Elijah Newren - - * HACKING: Clarify that gnome-common is needed now that autogen.sh - has been rewritten to use gnome-autogen.sh - -Fri May 5 12:50:58 2006 Søren Sandmann - - * src/c-window.c (has_counter): Some experimental code to handle - sync counter notifications on a window. - - * src/c-screen.c (meta_comp_screen_add_window): Pass a MetaDisplay - -2006-04-25 Elijah Newren - - Clear _NET_WM_VISIBLE_NAME (and the ICON_ equivalent) when no - longer being used. Fixes #330671. - - * src/window.[ch] (struct MetaWindow): new - using_net_wm_visible_name and using_net_wm_visible_icon_name bits, - (meta_window_new_with_attrs): initialize these new bits to false - - * src/window-props.c (set_title_text, set_window_title, set_icon_title): - if the _NET_WM_VISIBLE_(ICON_)NAME property was previously set but - doesn't need to be this time, make sure to clear it - -2006-04-25 Elijah Newren - - * rationales.txt: add three new tracker bugs - -Thu May 4 13:30:04 2006 Søren Sandmann - - * src/ui.h: Delete unused META_PRIORITY_COMPOSITE - - * src/ui.c: Delete argument from meta_ui_get_display(). - - * src/c-window.c: Remove the xid->window hashtable and associated - code. - - * src/c-screen.[ch]: Rename MetaScreenInfo to MetaCompScreen. Put the - xid->windows table here instaed of as a static variable. Also make - sure that CompWindows are freed when the screen is unredirected. - - * src/display.c: Delete non USE_GDK_DISPLAY case, as it didn't - work and hasn't been compiled for a long time. - - * src/display.[ch] (meta_display_open): Remove argument as it was - always NULL (and couldn't possibly be anything else in the - USE_GDK_DISPLAY case). - -Tue May 2 17:12:54 2006 Søren Sandmann - - * src/c-window.[ch]: New files - - * src/c-screen.c: Move WindowInfo struct to new c-window.[ch] - files. Delete various bits of obsolete, commented-out code. - -Fri Apr 28 12:53:23 2006 Søren Sandmann - - * src/core.c (get_window): New function. - * src/core.c: Use get_window() instead of cutted-and-pasted code - all over the place. - -2006-04-25 Elijah Newren - - * configure.in: post-release version bump to 2.15.3 - -2006-04-25 Elijah Newren - - * NEWS: 2.15.2 release - -2006-04-25 Elijah Newren - - * autogen.sh: Nuke the old version, copy one from gcalctool that - uses gnome-autogen.sh. Seems to fix the - translations-aren't-included-in-the-tarball problem. Fix from - Rodney in IRC. - -2006-04-25 Elijah Newren - - * configure.in: post-release version bump to 2.15.2 - -2006-04-25 Elijah Newren - - * NEWS: 2.15.1 release - * configure.in: belated post-release version bump to 2.15.1 - * src/Makefile.am: Include boxes.h so that control-center won't - fail to build #339708. - -2006-04-24 Elijah Newren - - * NEWS: 2.15.0 release - -2006-04-20 Brian Pepple - - #337951. - - * po/LINGUAS: New file listing all supported languages. - - * configure.in: Use po/LINGUAS instead of including all languages - directly in this file. See the wiki for more information: - http://live.gnome.org/GnomeGoals/PoLinguas. - -2006-04-19 Thomas Andersen - - * src/window-props.c (reload_transient_for): warn and ignore if - transient_for is set to a non-top-level window. Fixes #335524. - -2006-04-19 Björn Lindqvist - - * src/frames.c (struct CachedPixels, meta_frames_destroy, - invalidate_cache, generate_pixmap, populate_cache, - cached_pixels_draw, meta_frames_expose_event, - meta_frames_paint_to_drawable): - - Replace while loops iterating over sequences with for loops. Also, - replace the attributes in the CachedPixels struct with a list of - four CachedFramePiece:s, this allows iteration over the four - pixmaps instead of treating each one separately. Fixes #338359. - -2006-04-18 Björn Lindqvist - - * makefile.am: Add boxes.{c,h} to libmetacity_private - * src/theme-parser.c (check_expression): - * src/theme-viewer.c (run_position_expression_tests): - Use meta_rect (). - - * src/theme.c: Replace while loops iterating over sequences with - for loops. - - * src/theme.c, src/theme.h (struct _MetaPositionExprEnv, - meta_draw_op_draw, meta_draw_op_list_draw, - meta_theme_draw_menu_icon): Use MetaRectangles in function - prototypes instead of x, y, with, height ints where applicable. - -2006-04-18 Kjartan Maraas - - * configure.in: Remove obsolete entry for no_NO - * po/no.po: And the translation. - -2004-04-17 Thomas Thurman - - * keybindings.c (count_bindings, rebuild_binding_table): - * prefs.c (change_notify, screen_bindings, - window_bindings, init_bindings, update_binding, - find_and_update_list_binding, update_list_binding, - meta_prefs_get_window_binding): Allow any keybinding pref - to be specified either with , a string, or _list, - a list of strings, or both. Fixes #164831. - -2006-04-16 Elijah Newren - - Patch from Dan Sanders to fix #334899. - - * window.c (meta_window_new_with_attrs): Unminimize ancestors of - new windows when mapped; this prevents e.g. confirmation windows - from causing applications to appear locked when closing via the - window list. - -2006-04-15 Elijah Newren - - Patch from Dan Sanders to fix #335076. - - * src/core.c (meta_core_maximize, meta_core_toggle_maximize, - meta_core_unmaximize): - * src/window.c (meta_window_client_message): - Raise windows on maximize/unmaximize. - -2006-04-15 Elijah Newren - - * src/display.h: Patch from Andy Morum to fix the build with - --disable-xsync. #336605 - -2006-04-14 Elijah Newren - - * HACKING: Include instructions on setting up a minimal - building/testing environment - -2006-04-14 Thomas Thurman - - Add a tabbing function, bound to alt-f6 by default, to cycle - through the windows of the current application. Fixes #94682. - - * src/common.h: two new MetaGrabOpts values for group switching - * src/display.c (ping_data_free, meta_display_in_grab_op, - IN_TAB_CHAIN): adapt to new MetaGrabOpts - * src/display.h: new enum value for MetaTabList for group switching - * src/keybindings.c (meta_display_process_key_event): - adapt to new MetaGrabOpts - (process_tab_grab): adapt to new MetaGrabOpts, and use switch - statement for cancelling instead of if statement - * src/metacity.schemas.in: new keybindings - * src/prefs.c, src/prefs.h: handle new keybindings - * src/window.h: define META_WINDOW_IN_GROUP_TAB_CHAIN macro - -2006-04-14 Elijah Newren - - * HACKING: Include reasons why gdk/gtk.h and core includes like - display.h/window.h must be kept separate. Taken from a private - email from Havoc. - -2006-04-13 Alejandro Andres - - * README: Fixed broken links. #333303 - -Thu Apr 13 12:23:28 2006 Søren Sandmann - - * src/c-screen.c (meta_screen_info_add_window): Check for both - POPUP and DROPDOWN. - -2006-04-13 Björn Lindqvist - - * src/async-getprop.c, src/async-getprop.h - (async_get_property_handler, ag_task_get_reply_and_free): - * src/testasyncgetprop.c (try_get_reply, run_speed_comparison): - Change unsigned chars to chars. - - * src/display.h (struct MetaDisplay): - * src/keybindings.c (reload_modmap): - Change unsigned ints to ints. - - * src/screen.c (set_workspace_names) - * src/stack.c (meta_stack_sync_to_server): - * src/xprops.c (utf8_string_from_results, utf8_list_from_results, - class_hint_from_results, meta_prop_get_values): - Introduce casts. - - Add a number of casts and change signedness on a number of - variables so that Metacity compiles with many fewer - warnings. Fixes #336032. - -2006-04-12 Elijah Newren - - Patch from Ron Yorston to add a focus_new_windows option. Default - is 'smart' (focus by default but normal focus-stealing-prevention - can kick in); 'strict' is current other choice (like 'smart' - except that programs launched by the terminal will not be - focused). Fixes remainder of #326159. Should also close #152004 - and a bunch of others. - - * src/common.h: - Add a MetaFocusNewWindows enum giving the current types allowed - - * src/display.h: - Update docs on allow_terminal_deactivation to note that it is only - relevant when focus_new_windows is 'strict' - - * src/metacity.schemas.in: add the new gconf key and explanation - - * src/prefs.[ch] (#define KEY_FOCUS_NEW_WINDOWS, static gboolean - focus_new_windows, update_focus_new_windows, meta_prefs_init, - change_notify, meta_prefs_get_focus_new_windows, - meta_preference_to_string): - Add all the normal preference handling stuff for this new - focus-new-windows option. - - * src/window.c (window_state_on_map, meta_window_set_user_time): - Don't focus windows launched from a terminal - -Mon Apr 10 16:44:51 2006 Søren Sandmann - - * src/c-screen.c (is_menu): Check if the window is a menu and make - it 90% opaque in that case. - - * src/c-screen.c (claim_selection): Handle CM_Sn selection - properly. - - * src/c-screen.c: Remove debug spew - - * src/screen.c (meta_screen_composite_all_windows): Remove debug spew - -2006-04-10 Björn Lindqvist - - * display.c (meta_display_open, event_callback): - * ui.c (meta_ui_get_double_click_timeout): - - Delete dead code that used to handle double click on the - titlebar. Remove the attributes last_button_time, - last_button_xwindow, last_button_num and is_double_click from - MetaDisplay and the functions meta_ui_get_double_click_timeout() - and meta_display_is_double_click() from their respective - files. Fixes #337507. - -2006-03-27 Gora Mohanty - - * src/metacity.schemas.in: - * src/theme.c: - Changes strings to make them more readable, and more translatable. - Fixes #335720. - -2006-04-02 Elijah Newren - - Fix constraints bug causing negative width windows and crashes. - #336651 - - * src/constraints.c (constrain_partially_onscreen): Don't - accidentally shove & resize the window by requiring more pixels to - be onscreen than the size of the window. - -Fri Mar 31 16:44:56 2006 Søren Sandmann - - * src/c-screen.c (meta_screen_info_unredirect): Release the GL - window here. Disconect from the magnifier, not the stacker. - -Fri Mar 31 12:24:26 2006 Søren Sandmann - - * src/c-screen.c (meta_screen_info_redirect): Only use magnifier - when USE_MAGNIFIER is set. - - * src/compositor.c (meta_compositor_free_window): Only wobble when - USE_WOBBLE is set. - -Fri Mar 31 12:13:21 2006 Søren Sandmann - - * src/c-screen.c (meta_screen_info_redirect): Don't hardcode - screen size. - -Thu Mar 30 17:01:12 2006 Søren Sandmann - - * src/compositor.c (struct MetaCompositor): Fix the memory - corruption in a better way. - -Thu Mar 30 16:38:35 2006 Søren Sandmann - - * src/compositor.c (meta_compositor_begin_move): Fix an illegal write. - -Thu Mar 30 16:13:52 2006 Søren Sandmann - - * composite.c: Turn wobbling back on Add new explosion effect. - -2006-03-29 Elijah Newren - - Fix grouping in the presence of ancestors; caught by Björn. - #336184 - - * src/group.c (meta_window_compute_group): Use new - meta_window_find_root_ancestor() function to get ancestor; for the - computed group, use the ancestor's group instead of the ancestor - itself - - * src/window.[ch] (meta_window_find_root_ancestor, - meta_window_raise): split meta_window_find_root_ancestor() - functionality of meta_window_raise() and make it available - elsewhere - -2006-03-29 Elijah Newren - - * rationales.txt: Add bugs about pointer warping; update - raise-on-click ones. - -2006-03-29 Thomas Thurman - - Abstract out the functions for setting/unsetting demands attention - hint and avoid doing it when the window isn't obscured. Fixes the - remainder of #305882. - - * src/window.c, src/window.h (meta_window_set_demands_attention, - meta_window_unset_demands_attention): new functions to mark a - window as needing or not needing the user's attention - * src/window.c (meta_window_show, window_activate, - meta_window_focus, meta_window_configure_request, - meta_window_client_message): use the new set/unset - demands attention functions. - -2006-03-29 Björn Lindqvist - - * src/resizepopup.c: - * src/resizepopup.h: - * src/window.c (meta_window_refresh_resize_popup): - Aggregate the x, y, width and height attributes of MetaResizePopup - to one MetaRectangle rect attribute and update code using the - MetaResizePopup struct. Fixes #335177. - -2006-03-28 Elijah Newren - - * MAINTAINERS: New file. #335026. ;-) - -Tue Mar 28 09:57:26 2006 Søren Sandmann - - * src/c-screen.c (meta_screen_info_add_window): Also check for overlay_window. - - * src/c-screen.c (meta_screen_info_redirect): Trap errors out of - unredirect(). - -2006-03-25 Thomas Thurman - - * src/window.c, src/window.h (update_net_wm_state, - update_mwm_hints, update_wm_class, update_transient_for): - deleted and moved into window-props.c - (meta_window_new_with_attrs): added constructing field - and four new initial properties (as above) - (meta_window_recalc_features, - meta_window_recalc_window_type): new functions - - * src/window-props.c (init_net_wm_state, reload_net_wm_state - init_mwm_hints, reload_mwm_hints, init_wm_class, - reload_mwm_class, init_transient_for, reload_transient_for): - new functions, moved in from window.c - - (meta_display_init_window_prop_hooks): initialise new properties - - Closes #309567. - -2006-03-25 Paolo Borelli - - * src/prefs.c: use g_str_has_prefix instead of a local copy - of the function. - -2006-03-16 Ray Strode - - Add patch from Elijah Newren to fix type - for compositing_manager schema entry (bug 335901) - - * src/metacity.schemas.in: Change type from "boolean" to "bool" - and default value from "FALSE" to "false" - -Wed Mar 22 13:16:48 2006 Søren Sandmann - - * src/compositor.c (meta_compositor_remove_window): Actually - remove the window. - - * src/c-screen.c (meta_screen_info_remove_window): Only remove - node if non-NULL - -Wed Mar 22 10:33:21 2006 Søren Sandmann - - * src/c-screen.c (meta_screen_info_redirect): Put a square below - the desktop stack. - -Mon Mar 20 11:50:44 2006 Søren Sandmann - - * src/c-screen.c (meta_screen_info_redirect): Put the desktop into - a magnifier. - - * src/c-screen.c (struct MetaScreenInfo): Add a CmMagnifier - - * src/c-screen.c (meta_screen_info_redirect): Move some of the gl - window related stuff here. - -2006-03-16 Soren Sandmann (sandmann@daimi.au.dk) - - * src/c-screen.c (meta_screen_info_set_target_rect): Put inside - COMPOSIT_EXTENSIONS - -2006-03-03 Thomas Thurman - - Always set _NET_WM_STATE when a window is shown or - hidden, even if it wasn't mapped. Fixes #315142. - - * src/window.c (meta_window_hide, meta_window_show): - call set_net_wm_state unconditionally - -2006-03-16 Elijah Newren - - Add debugging information for edge resistance - - * src/edge-resistance.c (cache_edges): print out the edges that - are being cached if in verbose mode, - (meta_window_edge_resistance_for_move, - meta_window_edge_resistance_for_resize): if edge resistance kicked - in then print out a message about it - - * src/util.c: - * src/util.h: - Add META_DEBUG_EDGE_RESISTANCE to MetaDebugTopic enum list - -Thu Mar 16 14:55:18 2006 Søren Sandmann - - * src/c-screen.c (struct WindowInfo): Maintain the size of the - window. - -Wed Mar 15 16:30:09 2006 Søren Sandmann - - * src/compositor.c (set_geometry): Use set_target_rect() instead - of set_size(). - - * src/c-screen.c: Add set_target_rect() as a way of scaling windows. - - * src/window.c (meta_window_handle_mouse_grab_op_event): Turn - updates on after a button release. - - * src/window.c (meta_window_move_resize_internal): Fix - indentation. - -Wed Mar 15 11:34:54 2006 Søren Sandmann - - * src/c-screen.c (meta_screen_info_add_window): Use unset_patch() - instead of unset_geometry(). - -Tue Mar 14 11:57:46 2006 Søren Sandmann - - * src/compositor.c: Comment out wobbling - - * src/compositor.c (blow_up): remove this function - - * src/compositor.c (process_configure_notify): Uncomment - set_size(). - - * src/c-screen.c (meta_screen_info_set_updates): When updates are - true, set all the properties such as size and shape. - - * src/c-screen.c (meta_screen_info_add_window): Create a special - WindowInfo structure for each window. - - * src/c-screen.c (meta_screen_info_set_size): Set size and output - shape of the drawable node. - -2006-03-13 Elijah Newren - - * README: - * configure.in: - Update to reflect that we're now targetting 2.15 development. - -2006-03-12 Thomas Thurman - - * src/window-props.c (set_title_text): Mark a particular - string for translation. #334332. - -2006-03-06 Ryan Lortie - - * src/window.c (meta_window_free): Only unmaximise window before - freeing if the window is actually maximised. #333563. - -Fri Mar 3 15:31:04 2006 Søren Sandmann - - * src/c-screen.c (meta_screen_info_new): Update for libcm API - change. - -Wed Mar 3 13:25:03 2006 Søren Sandmann - - * src/compositor.c, src/c-screen.[ch]: Split the ScreenInfo data - structure into separate, new files c-screen.[ch]. - - * src/errors.c (x_error_handler): Forward foreign errors to - foreign displays. - - * src/errors.c (meta_errors_register_foreign_display): Implement - this function - - * src/errors.h: Add new meta_errors_register_foreign_display() - -Tue Feb 28 14:49:23 2006 Søren Sandmann - - * src/compositor.c: Put the windows in a stacker rather than - do the traversing outselves. - -2006-02-27 Elijah Newren - - Patch from Thomas Thurman to prevent setting cycle_windows to - keybindings that won't work. #329676 - - * src/prefs.c (update_binding): - Make sure that bindings which require a modifier key are set to a - keybinding with one or else that the binding is reverted. - - * src/ui.[ch] (meta_ui_accelerator_name): - New function - -2006-02-27 Elijah Newren - - Patch from Thomas Thurman to work around buggy application - grouping with transient windows. #328211 - - * src/group.c (meta_window_compute_group): - Put transients in the same group with their parent, always. - - * src/window.c (update_transient_for): - Update group too - -2006-02-27 Elijah Newren - - * configure.in: - Patch from Sylvain Bertrand to fix build issues with library - search order. #330695. - -Sat Feb 25 14:50:17 2006 Søren Sandmann - - * src/window.c: Remove include of flash.h - -Sat Feb 25 11:46:14 2006 Søren Sandmann - - * src/display.c (meta_display_begin_grab_op): Call - meta_compositor_begin_move if there is a compositor - - * src/compositor.c (meta_compositor_begin/update/end_move): - Implement those functions. - - * src/spring-model.[ch]: New files - -Thu Feb 23 15:40:52 2006 Søren Sandmann - - * src/compositor.c (meta_compositor_manage_screen): Don't attempt - to manage the screen if it already is managed. - - * src/compositor.c (meta_compositor_unmanage_screen): Synchronize - the display. - -2006-02-19 Thomas Thurman - - Removed "move to another workspace" menu when there are - exactly two workspaces. Fixes #151183. - - * src/menu.c (meta_window_menu_new): clear - META_MENU_OP_WORKSPACES bit when n_workspaces==2 - -Fri Feb 17 11:56:35 2006 Søren Sandmann - - * src/screen.c (meta_screen_free): Only uncomposite the screen if - there is a compositor. - - * src/compositor.c (meta_compositor_new): Warn and fail if the - server doesn't have composite - -Thu Feb 16 18:57:48 2006 Søren Sandmann - - * src/compositor.c: Fix the build when --enable-compositor is - there. - -Thu Feb 16 15:54:48 2006 Søren Sandmann - - * src/compositor.c: Insert #ifdef's to make it build again - -Thu Feb 16 15:24:42 2006 Søren Sandmann - - * src/screen.c (meta_screen_composite_all_windows): New function. - - * src/prefs.[ch], src/metacity.schemas.in: Add new - compositing_manager key. - - * src/display.c (prefs_changed_callback): Handle - META_PREF_COMPOSITOR_MANAGER - - * src/display.c (event_callback): Only call - meta_compositor_process_event() if there is in fact a compositor. - - * src/display.c (enable/disable_compositor): Add code to - enable/disable compositor at runtime - -Wed Feb 15 18:42:03 2006 Søren Sandmann - - * src/compositor.[ch]: Add code to destroy compositor. Implement - unmanage_screen() functionality. - -Wed Feb 15 14:47:50 2006 Søren Sandmann - - * src/compositor.c (meta_compositor_unminimize): Add unused wobbly - unminimize animation by Kristian - - * src/compositor.c (meta_compositor_minimize): Add wobbly minimize - animation by Kristian. - - * src/compositor.c: Add support for turning updates on and off. - - * src/window.c (meta_window_move_resize_internal): Use - sync counter to make composited resizing tear free - -2006-02-14 Elijah Newren - - Patch from Jens Granseuer to fix more build issues with gcc 2.95. - #331166. - - * src/prefs.c (meta_prefs_init): - Remove C99 style variable initiailization - -2006-02-13 Elijah Newren - - * configure.in: post-release version bump to 2.13.144 - -2006-02-13 Elijah Newren - - * NEWS: 2.13.89 release - -2006-02-13 Elijah Newren - - * src/keybindings.c (process_tab_grab): - We had that prev_window code in multiple places and it was all - identical. Let's just stick it in one place to make the function - easier to read. - -2006-02-13 Thomas Thurman - - * src/keybindings.c (process_tab_grab): - Allow alt-escape to cancel alt-tabbing, and vice versa. Fixes - #141425. - -2006-02-11 Thomas Thurman - - Disable alt-f7 if a window can't be moved, and alt-f8 if it - can't be resized. Fixes #328920. - - * src/keybindings.c (handle_begin_move, handle_begin_resize): - check window->has_*_func before beginning operation - -2006-02-11 Elijah Newren - - Add a man page for metacity. Original version taken from Debian - (written by Thom May and Akira Tagoh) and updated by Luke Morton - and Philip O'Brien. Necessary auto-fu supplied by Philip O'Brien. - Fixes #321279. - -2006-02-11 Elijah Newren - - * src/stack.h (enum MetaStackLayer): - * src/stack.c (get_standalone_layer): - actually use META_LAYER_TOP but just manually make it equal to - META_LAYER_DOCK. Add a note point to the EWMH for why we do this. - #330717 - -2006-02-11 Elijah Newren - - * src/window.c (enum GnomeWinLayer): remove this legacy cruft that - we stopped using years ago - -2006-02-10 Thomas Thurman - - Avoid a memory leak when checking which workspace(s) a window is - on. Fixes #322059. - - * src/workspace.h (struct MetaWorkspace): - * src/workspace.c (meta_workspace_new, meta_workspace_free): - added list_containing_self member to MetaWorkspace - - * src/window.c (meta_window_get_workspaces): use - window->workspace->list_containing_self instead of allocating (and - leaking) such a list on the fly. - -2006-02-09 Thomas Thurman - - * src/testboxes.c (test_regions_okay, test_clamping_to_region): - add messages to explain that warnings are harmless - -Tue Feb 7 00:58:05 2006 Soeren Sandmann - - * src/compositor.c: Wrap fade code in #ifdef HAVE_COMPOSITE_EXTENSIONS - -Mon Feb 6 17:45:39 2006 Søren Sandmann - - * src/compositor.c: New fancy minimize animation. Fade windows in - and out. - -2006-02-03 Thomas Thurman - - * src/display.c (event_callback): produce warning when invalid - events with no timestamp are received, rather than failing an - assertion - -Thu Feb 2 17:58:22 2006 Søren Sandmann - - * compositor.c (process_map): update the pixmap. - (update) print out framerate. - (dump_stacking_order) new debug - function. - (meta_compositor_add_window) error trap fixes - (MiniInfo): Make the minimize animation fade out. - -2006-01-30 Elijah Newren - - * configure.in: post-release version bump to 2.13.89 - -2006-01-30 Elijah Newren - - * NEWS: 2.13.55 release - -2006-01-30 Elijah Newren - - * src/display.[ch] (struct MetaDisplay), meta_display_open, - meta_display_set_input_focus_window, - meta_display_focus_the_no_focus_window): Track the active_screen, - (event_callback): If the mouse enters a window on a different - screen, activate the default window on the new screen. May need - to be modified for click-to-focus; we'll wait for feedback. Fixes - #319348. - -2006-01-23 Elijah Newren - - * src/display.c (meta_display_check_threshold_reached): change the - order of the ||'ed items in the if to avoid using an uninitialized - value - - * src/prefs.c (meta_prefs_init): fix a couple uninitialized value - problems - -2006-01-21 Elijah Newren - - Patch from Christian Kirbach to prevent a critical warning crasher - when switching themes. #327847. - - * src/theme.c (meta_theme_free): since themes are only constructed - as needed and may be NULL, check for that before freeing theme - hash tables - -2006-01-21 Elijah Newren - - * src/common.h (enum MetaActionDoubleClickTitlebar): - * src/frames.c (meta_frames_button_press_event): - * src/prefs.c (action_double_click_titlebar_from_string): - * src/metacity.schemas.in: - Patch from Dick Marinus to add a minimize - double-click-titlebar-action; slightly modified to also include a - none action. #300210. - -2006-01-20 Elijah Newren - - * configure.in: post-release version bump to 2.13.55 - -2006-01-20 Elijah Newren - - * NEWS: 2.13.34 release - -2006-01-20 Elijah Newren - - * src/constraints.c (setup_constraint_info): fixed_directions is - only meant for explicit user interactions; disable it for - everything else. There are other bugs and improvements that could - be made with fixed_directions that I should be filing too, but at - least put a FIXME there for now--I'm so lame. Fixes #327822. - -2006-01-20 Elijah Newren - - Avoid flashing when closing a maximized window. Fixes #317254. - - * src/window.c (unmaximize_window_before_freeing): new function - that just fixes the net_wm_state and sends a configure_notify, - (meta_window_free): use unmaximize_window_before_freeing() instead - of meta_window_unmaximize() to avoid flicker - -2006-01-20 Elijah Newren - - Fix unitialized value problem when in raise-on-click mode. Søren, - #327572. - - * src/display.c (meta_display_check_threshold_reached): make - function be a no op if raise_on_click!=FALSE - - * src/display.h (struct MetaDisplay): point out that - grab_initial_[xy] and grab_threshold_movement_reached are only for - raise_on_click==FALSE mode. - -2006-01-20 Elijah Newren - - Patch from Søren to fix some reading-from-free'd-data errors. - #327575 - - * src/edge-resistance.c (meta_display_cleanup_edges): store the - edges in a hash table so that we can still read their values - within the loop from the other array they are stored in, then free - them all at the end. - -2006-01-20 Elijah Newren - - Fix various initialization and default issues, especially for - --disable-gconf. Make --disable-gconf actually work. #326661. - - * configure.in: Fix compilation with --disable-gconf - * src/metacity.schemas.in: Add a note that if any defaults are - changed in this file, src/prefs.c may need to be updated to - reflect the change - * src/prefs.c: set various static global vars to the right default - value, (meta_prefs_init): get the titlebar_font and current_theme - handled better when not using gconf, (struct MetaSimpleKeyMapping, - screen_string_bindings, window_string_bindings): helper vars to - allow some keybindings to work even without gconf, - (init_bindings): initialize bindings for the without-gconf case - too, (init_commands): make sure these are all NULL for the - non-gconf case so that we don't access random memory, - (init_workspace_names): just give these all a default name for the - non-gconf case, - (meta_prefs_change_workspace_name): actually change the name for - the non-gconf case too - -2006-01-20 Elijah Newren - - More careful error handling of values returned by GConf. Fixes - #326615. - - * src/prefs.c (get_bool): new helper function, (meta_prefs_init): - use get_bool to handle the case of a gconf key not existing, - (update_cursor_size): sanity check for sane values - -2006-01-20 Elijah Newren - - Prevent rapidly repeated visual bells from hanging metacity. - Fixes #322032. - - * src/display.h (struct MetaDisplay): add a last_bell_time field, - (XSERVER_TIME_IS_BEFORE_ASSUMING_REAL_TIMESTAMPS macro, - XERVER_TIME_IS_BEFORE macro): add parentheses around usage of - macro parameter - - * src/display.c (meta_display_open): initialize last_bell_time, - (event_callback): don't allow more than one bell per second - -2006-01-20 Elijah Newren - - * src/async-getprop.c: - * src/common.h: - * src/display.c: - * src/eggaccelerators.c: - * src/frames.c: - * src/gradient.c: - * src/iconcache.c: - * src/keybindings.c: - * src/metaaccellabel.c: - * src/place.c: - * src/prefs.c: - * src/preview-widget.c: - * src/screen.c: - * src/session.c: - * src/stack.c: - * src/tabpopup.c: - * src/theme-viewer.c: - * src/theme.c: - * src/window-props.c: - * src/window.c: - * src/workspace.c: - * src/tools/metacity-window-demo.c: - * src/wm-tester/test-gravity.c: - * src/wm-tester/test-resizing.c: - * src/wm-tester/test-size-hints.c: - Patch from Kjartan Maraas to fix a lot of tiny issues (unused - variable removal, making unused variables used again, correction - of types passed/declared for printf arguments, removal of unneeded - breaks and returns, dead code removal, dead code revival, renaming - to prevent shadowed variables, declaring unexported functions as - static) spotted by the intel compiler. #321439 - -2006-01-20 Elijah Newren - - Patch from Björn Lindqvist to fix #98340. - - * src/screen.c (meta_screen_ensure_tab_popup): Make sure an - outline border is shown even if a window frame's width is 0. - Also, correctly handle window outlines in showing desktop mode. - -Fri Jan 20 16:42:25 2006 Søren Sandmann - - * src/compositor.c: Make minimize animation update again. - -Thu Jan 19 18:05:47 2006 Søren Sandmann - - * src/compositor.c (meta_compositor_manage_screen): - g_object_unref() rather than ws_region_unref(). - -Thu Jan 19 16:50:50 2006 Søren Sandmann - - * src/compositor.c: Port to changes in libcm - -Tue Jan 17 17:25:29 2006 Søren Sandmann - - * src/compositor.c: Port to changes in libcm. - -2006-01-16 Elijah Newren - - * src/window-props.c: manually define HOST_NAME_MAX if not already - defined to fix Solaris compilation issue. Caught by Damien - Carbery, patch from Havoc. #326745 - -2006-01-16 Elijah Newren - - * configure.in: post-release version bump to 2.13.34 - -2006-01-16 Elijah Newren - - * NEWS: 2.13.21 release - -Mon Jan 16 11:55:20 2006 Søren Sandmann - - * src/compositor.c (meta_compositor_manage_screen): Really turn - off draw-in-a-loop. - -2006-01-15 Kyle Ambroff - - * src/workspace.c (focus_ancestor_or_mru_window): - If no valid window is found in the MRU list, then set focus to the - desktop window. (#317405) - -2006-01-15 Elijah Newren - - Fix accidental overzealous focus holding by the terminal - introduced by the original patch in bug 326159. Windows launched - from panel icons, the panel menu, or global keybindings should get - focus now. #326159. - - * src/display.c (meta_display_open, event_callback): - * src/display.h (struct MetaDisplay): - * src/keybindings.c (process_event): - * src/window.c (meta_window_set_user_time): - Add a new allow_terminal_deactivation field to MetaDisplay and use - it to track whether the user's last action was interaction with - the terminal or some outside action (global keybinding, clicking - on a dock, etc.) likely to launch a new window. - - * src/window.c (window_state_on_map): - Allow the focus switch from a terminal to something else if - allow_terminal_deactiviation is true. - - * src/keybindings.c (handle_panel_keybinding): - Remove some unneeded code. - -2006-01-15 Elijah Newren - - Patch from Jens Granseuer to fix more build issues with gcc 2.95. - #327050. - - * src/boxes.c (meta_rectangle_edge_cmp_ignore_type): - * src/window.c (meta_window_show): - Remove C99 style variable initiailization - -2006-01-14 Elijah Newren - - * src/window.c (__window_is_terminal): Don't dereference a NULL - string. Fixes #327013. - -2006-01-14 Elijah Newren - - * src/compositor.[ch]: fix compilation when - HAVE_COMPOSITE_EXTENSIONS is undefined. #326912 - -Fri Jan 13 16:37:26 2006 Søren Sandmann - - * src/compositor.c (update): Only update on damage events. - -2006-01-13 Elijah Newren - - Patch from Damien Carbery. Fixes #326746. - - * src/util.c: explicitly #include Xlib.h to fix a compilation - issue on Solaris. - -Fri Jan 13 14:40:19 2006 Søren Sandmann - - * configure.in: Add a dependency on libcm when building with - compositor. - - * src/window.c (meta_window_hide): Make this function static. - - * src/window.c (implement_showing): Use meta_compositor_minimize() - to do a weird minimize effect. - - * src/compositor.[ch]: Beginning of new GL based compositor. - - * src/screen.h (struct _MetaScreen): Add void pointer to - compositor data. - - * src/screen.c (meta_screen_new): Remove obsolete compositor - stuff; initialize compositor_data. Don't composite manage screen - out of this function. - - * src/errors.c (x_error_handler): Check that display is non-NULL - before using it. Add comment about how that can happen. - - * src/display.c (meta_display_{begin,end}_grab_op): Remove - explicity damage of windows. - - * src/display.c (meta_display_open): Composite manage all the - screens. - -2006-01-11 Elijah Newren - - * src/textboxes.c (test_area, test_intersect, test_equal, - test_overlap_funcs, test_basic_fitting, test_merge_regions, - test_regions_okay, test_region_fitting, test_clamping_to_region, - test_clipping_to_region, test_shoving_into_region, - test_find_onscreen_edges, - test_find_nonintersected_xinerama_edges, test_gravity_resize, - test_find_closest_point_to_line): - Replace __PRETTY_FUNCTION__ with G_STRFUNC, because lesser - compilers don't support the former. Caught by Damien Carbery, fix - suggested by Ray Strode. #326281. - -2006-01-10 Elijah Newren - - * configure.in: post-release version bump to 2.13.21 - -2006-01-10 Elijah Newren - - * NEWS: 2.13.13 release - -2006-01-10 Elijah Newren - - * src/bell.c: - * src/boxes.c: - * src/boxes.h: - * src/constraints.c: - * src/core.c: - * src/display.c: - * src/display.h: - * src/edge-resistance.c: - * src/frames.c: - * src/keybindings.c: - * src/main.c: - * src/prefs.c: - * src/prefs.h: - * src/screen.c: - * src/screen.h: - * src/window.c: - * src/window.h: - Whoops, I forgot to keep my copyright info updated with my previous - commits as Havoc had asked me to do. Doing that now... - -2006-01-10 Elijah Newren - - Add a raise on click option, basically only because all the major - distros are patching it in anyway. See #326156. - - * src/metacity.schemas.in: add the new gconf key and explanation - - * src/prefs.[ch] (#define KEY_RAISE_ON_CLICK, static gboolean - raise_on_click, update_raise_on_click, meta_prefs_init, - change_notify, meta_prefs_get_raise_on_click, - meta_preference_to_string): - Add all the normal preference handling stuff for this new - raise-on-click option. - - * src/core.c (meta_core_show_window_menu): - * src/display.c (event_callback, meta_display_begin_grab_op): - * src/window.c (window_activate, meta_window_configure_request, ): - Only raise the window if in raise_on_click mode. - - * src/display.c (meta_display_begin_grab_op, - meta_display_end_grab_op, meta_display_check_threshold_reached): - * src/display.h (struct MetaDisplay): - * src/window.c (meta_window_handle_mouse_grab_op_event): - if not in raise-on-click mode only raise on button release if the - click didn't start a move or resize operation; needs a few extra - MetaDisplay fields to handle this - - * src/core.c (meta_core_user_lower_and_unfocus): - no need to do the MRU shuffling if not maintaining the stacking - order == MRU order invariant - - * src/frames.c (meta_frames_button_press_event): - * src/window.c (meta_window_begin_grab_op): - remove an unneeded window raising that is already handled elsewhere - -2006-01-10 Elijah Newren - - Don't "steal" focus from terminal windows for new window mappings - as the difference in usage between terminals and other apps seems - to suggest this difference in treatment. See #326159 for details, - feedback welcome. - - * src/window.[ch] (__window_is_terminal): New function, currently - an ugly hack and should be replaced by a new property set by - applications if the behavior works to our liking, - (window_state_on_map): don't transfer focus to new windows from - terminals unless the new window is a transient of the focused - terminal - - * src/keybindigns.c (handle_panel_keybinding): panel run dialog - keybinding should be counted as an explicit transfer of focus to - the new window, so override the - don't-transfer-focus-from-terminals in this case - -2006-01-09 Elijah Newren - - More thorough handling of source indication. Part of #326041. - - * src/window.c (window_activate): new function based off the old - meta_window_activate but which also takes source indication into - account, (meta_window_active): just call window_activate() with - the necessary source indication to get the behavior wanted, - (meta_window_client_message): check source indication too for - _net_active_window messages - - * src/window.h (enum MetaClientType): convenience enum for source - indication handling - -2006-01-09 Elijah Newren - - Make the taskbar less flash happy and fix up some related stacking - issues. #326035. - - * src/window.c (windows_overlap): new function, - (meta_window_show): if a window is denied focus but doesn't - overlap with the focus window there is no need to set the demands - attention hint nor stack that window below the focus window, - (meta_window_get_outer_rect): we're not modifying the window so - declare it to be const - -2006-01-09 Elijah Newren - - Fix window outline for minimized windows when using alt-esc. - #325092. - - * src/display.c (meta_display_begin_grab_op): Specify the showing - type of tabbing operation (Alt tab vs. alt-esc) in addition to the - listing type of tabbing operation (docks vs normal windows) to - meta_screen_ensure_tab_popup(). - - * src/display.h (enum MetaTabShowType): new convenience enum - - * src/screen.[ch] (meta_screen_ensure_tab_popup): require the - showing type be specified in addition to the tabbing type; put the - outline around the window instead of the icon when in alt-esc - mode. - -2006-01-09 Elijah Newren - - Fix reduced resources resize handling for windows with sizing or - resizing constraints. #325774. - - * src/display.c (meta_display_end_grab_op): Provide constraints.c - with the correct gravity information. - -2006-01-09 Elijah Newren - - Be more strict about what is considered a valid region with - partial struts. Fixes #322070. - - * src/boxes.[ch]: - (meta_rectangle_expand_region_conditionally): - new function behaving like meta_rectangle_expand_region() but - which only does so when the width and height of the rectangles - meet a certain threshold - - (replace_rect_with_list): - Remove a compiling warning - - * src/constraints.c: - (constrain_partially_onscreen): - provide minimum thresholds in each direction for the size of the - rectangles to avoid cases where only a single pixel thick layer of - a window might be showing - -2006-01-09 Elijah Newren - - * src/bell.c (meta_bell_notify_frame_destroy): Use the right - function to remove the timeout so that we don't crash if removed - at an inopportune time. Fixes #322031. - -2006-01-09 Elijah Newren - - * src/edge-resistance.c (apply_edge_resistance): Remove the - "pull-away" edge resistance. Fixes another of the zillions of - issues covered in #321905. - -2006-01-09 Elijah Newren - - * src/edge-resistance.c (apply_edge_resistance): Revert to the old - edge resistance behavior for keyboard movement/resizing based - resistance. Not only makes the code much simpler and shorter, but - also fixes another of the zillions of issues covered in #321905. - -2006-01-09 Elijah Newren - - * src/edge-resistance.c (apply_edge_resistance): Remove the - timeout resistance at screen/xinerama edges for the whiners. - Okay, it made sense. Fixes another of the zillions of issues - covered in #321905. - -2006-01-09 Elijah Newren - - * src/edge-resistance.c (apply_edge_resistance): Make extra - timeout edge resistance apply even if one edge already offscreen. - Fixes another of the zillions of issues covered in #321905. - -2006-01-09 Elijah Newren - - Allow edge resistance at both sides of a window and also when - edges don't overlap but are a single pixel away from doing so. - Fixes one of the zillions of issues covered in #321905. - - * src/boxes.[ch]: - (meta_rectangle_edges_align): - new function to handle the overlap or off by one determining - whether edge resistance should kick in for an edge. - - (meta_rectangle_edge_cmp_ignore_type): - new function to sort edges but ignore the type so that e.g. left & - right edges of windows can be used interchangeably. - - (meta_rectangle_edge_cmp): - now uses meta_rectangle_edge_cmp_ignore_type() to do most the work - and just adds an extra condition - - * src/edge-resistance.c: - (find_nearest_position): - use meta_rectangle_edges_align() now to determine whether the - edges align, - - (apply_edge_resistance, apply_edge_resistance_to_each_side): - have the edge resistance kick in if either the beginning or ending - positions would cause overlap in the given direction -- fixes an - uncommon but annoying corner case, - - (apply_edge_snapping, apply_edge_resistance_to_each_side, - meta_display_cleanup_edges, - stupid_sort_requiring_extra_pointer_dereference, cache_edges): - mix edges from both sides now - -2006-01-09 Elijah Newren - - Plug a few leaks. Fixes #309178. - - * src/main.c (main): remove an unneeded g_set_prgname() call, free - some strings allocated by the GOptions parsing - -2006-01-02 Elijah Newren - - Patch from Björn Lindqvist to fix a logic error. #322149. - - * src/window.c (update_resize): && should have been ||. - -2006-01-02 Elijah Newren - - Patch from Jens Granseuer to fix build with gcc 2.95. #322622. - - * src/boxes.c (meta_rectangle_region_to_string, - meta_rectangle_edge_list_to_string, fix_up_edges): - * src/constraints.c (meta_window_constrain, setup_constraint_info, - place_window_if_needed, constrain_maximization, - constrain_fullscreen, constrain_size_increments, - constrain_size_limits, constrain_aspect_ratio, - do_screen_and_xinerama_relative_constrai, - constrain_to_single_xinerama, constrain_fully_onscreen, - constrain_partially_onscreen): - * src/edge-resistance.c (find_nearest_position, - apply_edge_resistance, apply_edge_resistance_to_each_side): - * src/testboxes.c (test_clamping_to_region, - test_clipping_to_region, test_shoving_into_region): - * src/window.c (meta_window_new_with_attrs, - meta_window_apply_session_info, meta_window_resize, - meta_window_resize_with_gravity, meta_window_configure_request): - Remove C99 style variable initiailization - -2006-01-02 Elijah Newren - - * configure.in: post-release version bump to 2.13.13 - -2006-01-02 Elijah Newren - - * NEWS: 2.13.8 release - -2005-12-27 Elijah Newren - - Make the workspace switcher work with dual-head (non-xinerama) - setups. Fixes #319423. - - * src/display.c (meta_display_open, event_callback, - meta_display_focus_the_no_focus_window): - * src/display.h (struct MetaDisplay, - meta_display_focus_the_no_focus_window): - * src/keybindings.c (primary_modifier_still_pressed): - * src/screen.c (meta_screen_new): - * src/screen.h (struct MetaScreen): - * src/window.c (meta_window_new_with_attrs, meta_window_show): - * src/workspace.c (meta_workspace_focus_default_window): - Replace display->no_focus_window with a no_focus_window for each - screen. - - * src/display.[ch] (meta_display_xwindow_is_a_no_focus_window, - event_callback): - * src/window.c (meta_window_new_with_attrs): - New utility function, meta_display_xwindow_is_a_no_focus_window(), - for checking if the given xwindow is a no_focus_window for one of - the screens. - -2005-12-27 Elijah Newren - - * src/tabpopup.c (meta_ui_tab_popup_new): since the title is going - to be treated as markup, escape it. Fixes #324846. - -2005-12-13 Kang Jeong-Hee - - * src/compositor.c: replace old call to width and height - of MetaScreen struct with rect.width and rect.height. - Now compile ok. - * src/delete.c: make an int variable into unsigned int. - Now compile warning has gone. - -2005-12-12 Elijah Newren - - * configure.in: post-release version bump to 2.13.8 - -2005-12-12 Elijah Newren - - * NEWS: 2.13.5 release - -2005-12-12 Elijah Newren - - * src/window.c (update_net_frame_extents): make the debugging - message actually correspond to the code. Patch from Björn - Lindqvist. Fixes #322051. - -2005-11-29 Kjartan Maraas - - * src/screen.h: Make the wireframe a bit slimmer. - Closes bug #320051. - -2005-11-24 Davyd Madeley - - * src/window-props.c: display hostname in titlebar for remote X - clients. Closes bug #322202. - -2005-11-22 Elijah Newren - - * configure.in: post-release version bump to 2.13.5 - -2005-11-22 Elijah Newren - - * NEWS: 2.13.3 release - -2005-11-22 Elijah Newren - - Don't allow removing a window from maximized or fullscreened state - to place the titlebar under the top panel. Fixes #322075. - - * src/display.c (handle_net_moveresize_window): fix up previous - comments now that I know a little more, modify the code just - slightly to clarify that this is NOT a manual user move/resize - operation - - * src/window.c (meta_window_unmaximize, - meta_window_unmake_fullscreen, - meta_window_shove_titlebar_onscreen): - don't claim that these are manual user move/resize operations - -2005-11-21 Elijah Newren - - * src/constraints.c (constrain_partially_onscreen): Relax the - partially onscreen constraint to allow the titlebar to touch the - bottom panel in order to make the new constraints code function - the same as the old version. Fixes #322071. - -2005-11-21 Elijah Newren - - * src/constraints.c (place_window_if_needed): When updating the - xinerama due to placement, update which maximal/spanning rect set - to use as well. Fixes #322068. - -2005-11-21 Elijah Newren - - * doc/strut-and-related-updating.txt: It took me a little while to - figure out how struts & workareas are updated and to learn what - all the related functions were used for so I thought I'd clean up - my notes and make them available. This will probably be more - useful now since regions and edges are also computed and stored at - the same time as the workareas. - -2005-11-20 Elijah Newren - - * src/constraints.c (place_window_if_needed): compute the frame - geometry due to maximization only after actually maximizing. - Fixes #321902. - -2005-11-21 Davyd Madeley - - * src/edge-resistance.c (meta_display_compute_resistance_and_snap): - Use GPOINTER_TO_INT() macro instead of cast to allow compilation on - 64-bit architectures without warning. - -2005-11-19 Elijah Newren - - * src/edge-resistance.c (apply_edge_resistance): differentiate - between movement towards an edge and movement away from one. Pick - smaller constants for movement away from an edge. - -2005-11-19 Elijah Newren - - * configure.in: post-release version bump to 2.13.3 - -2005-11-19 Elijah Newren - - * NEWS: 2.13.2 release - -2005-11-18 Elijah Newren - - Merge of all the changes on the constraints_experiments branch. - This is just a summary, to get the full ChangeLog of those - changes (approx. 2000 lines): - cvs -q -z3 update -Pd -r constraints_experiments - cvs -q -z3 diff -pu -r CONSTRAINTS_EXPERIMENTS_BRANCHPOINT ChangeLog - - Bugs fixed: - unfiled - constraints.c is overly complicated[1] - unfiled - constraints.c is not robust when all constraints - cannot simultaneously be met (constraints need to be - prioritized) - unfiled - keep-titlebar-onscreen constraint is decoration - unaware (since get_outermost_onscreen_positions() - forgets to include decorations) - unfiled - keyboard snap-moving and snap-resizing snap to hidden - edges - 86644 - resize should have a shift option like move does - 109553 - gravity w/ simultaneous move & resize doesn't work - 113601 - maximize vertical and horizontal should toggle and be - constrained - 122196 - windows show up under vertical panels - 122670 - jerky/random resizing of window via keyboard[2] - 124582 - keyboard and mouse snap-resizing and snap-moving - erroneously moves the window multidimensionally - 136307 - don't allow apps to resize themselves off the screen - (*cough* filechooser *cough*) - 142016, 143784 - windows should not span multiple xineramas - unless placed there by the user - 143145 - clamp new windows to screensize and force them - onscreen, if they'll fit - 144126 - Handle pathological strut lists sanely[3] - 149867 - fixed aspect ratio windows are difficult to resize[4] - 152898 - make screen edges consistent; allow easy slamming of - windows into the left, right, and bottom edges of the - screen too. - 154706 - bouncing weirdness at screen edge with keyboard moving - or resizing - 156699 - avoid struts when placing windows, if possible (nasty - a11y blocker) - 302456 - dragging offscreen too restrictive - 304857 - wireframe moving off the top of the screen is misleading - 308521 - make uni-directional resizing easier with - alt-middle-drag and prevent the occasional super - annoying resize-the-wrong-side(s) behavior - 312007 - snap-resize moves windows with a minimum size - constraint - 312104 - resizing the top of a window can cause the bottom to - grow - 319351 - don't instantly snap on mouse-move-snapping, remove - braindeadedness of having order of releasing shift and - releasing button press matter so much - - [1] fixed in my opinion, anyway. - [2] Actually, it's not totally fixed--it's just annoying - instead of almost completely unusable. Matthias had a - suggestion that may fix the remainder of the problems (see - http://tinyurl.com/bwzuu). - [3] This bug was originally about not-quite-so-pathological - cases but was left open for the worse cases. The code from - the branch handles the remainder of the cases mentioned in - this bug. - [4] Actually, although it's far better there's still some minor - issues left: a slight drift that's only noticeable after - lots of resizing, and potential problems with partially - onscreen constraints due to not clearing any - fixed_directions flags (aspect ratio windows get resized in - both directions and thus aren't fixed in one of them) - - New feature: - 81704 - edge resistance for user move and resize operations; - in particular 3 different kinds of resistance are - implemented: - Pixel-Distance: window movement is resisted when it - aligns with an edge unless the movement is greater than - a threshold number of pixels - Timeout: window movement past an edge is prevented until - a certain amount of time has elapsed during the - operation since the first request to move it past that - edge - Keyboard-Buildup: when moving or resizing with the - keyboard, once a window is aligned with a certain edge - it cannot move past until the correct direction has - been pressed enough times (e.g. 2 or 3 times) - - Major changes: - - constraints.c has been rewritten; very few lines of code from - the old version remain. There is a comment near the top of - the function explaining the basics of how the new framework - works. A more detailed explanation can be found in - doc/how-constraints-works.txt - - edge-resistance.[ch] are new files implementing edge-resistance. - - boxes.[ch] are new files containing low-level error-prone - functions used heavily in constraints.c and edge-resistance.c, - among various places throughout the code. testboxes.c - contains a thorough testsuite for the boxes.[ch] functions - compiled into a program, testboxes. - - meta_window_move_resize_internal() *must* be told the gravity - of the associated operation (if it's just a move operation, - the gravity will be ignored, but for resize and move+resize - the correct value is needed) - - the craziness of different values that - meta_window_move_resize_internal() accepts has been documented - in a large comment at the beginning of the function. It may - be possible to clean this up some, but until then things will - remain as they were before--caller beware. - - screen and xinerama usable areas (i.e. places not covered by - e.g. panels) are cached in the workspace now, as are the - screen and xinerama edges. These get updated with the - workarea in src/workspace.c:ensure_work_areas_validated() - -2005-11-14 Elijah Newren - - * configure.in: post-release version bump to 2.13.2 - -2005-11-14 Elijah Newren - - * NEWS: 2.13.1 release - -2005-11-11 Aidan Delaney - - * src/tabpopup.h: (struct _MetaTabEntry): - * src/tabpopup.c: (meta_ui_tab_popup_new): - * src/screen.c: (meta_screen_ensure_tab_popup): - Changed the 'minimized' field of the MetaTabEntry struct to - 'hidden'. Fixes reopened bug #168455. - -2005-10-29 Kjartan Maraas - - * src/eventqueue.c: (meta_event_queue_new): Merge fix - for bug #320050 from stable. - -2005-10-27 Erdal Ronahi - - * configure.in: Added ku (Kurdish) to ALL_LINGUAS - -2005-10-25 Philip O'Brien - - * src/prefs.c (meta_preference_to_string): add handling for - META_PREF_CURSOR_THEME and META_PREF_CURSOR_SIZE for more complete - debug info - -2005-10-24 Elijah Newren - - * configure.in: post-release version bump to 2.13.1 - -2005-10-24 Elijah Newren - - * NEWS: 2.13.0 release - -2005-10-23 Elijah Newren - - Fix edge snapping for multi-screen (non-xinerama) setups. #319425 - - * src/place.c (get_windows_showing_on_same_screen, - get_vertical_edges, get_horizontal_edges): rename - get_windows_on_same_workspace() to - get_windows_showing_on_same_screen() - - * src/place.c (get_windows_showing_on_same_screen): exclude windows - in the list that are on a different screen - -2005-10-20 Elijah Newren - - * HACKING: Clarify why METACITY_VERBOSE=1 is bad without - META_USE_LOGFILE=1; point to bug 305091 for details. - -2005-10-13 Muktha - - * src/themes/Simple/metacity-theme-1.xml: Make the unfocussed - Simple window border visible with high contrast inverse theme. - Fixes #121361. - -2005-10-08 Elijah Newren - - Fix a crash that occurs when removing some virtual desktops and - windows happen to be on those desktops. #318306. - - * src/workspace.c (meta_workspace_relocate_windows): Since windows - cannot be on more than one workspace at a time, remove the window - from the old workspace before adding it to the new one. - -2005-10-08 Elijah Newren - - Add my copyright notice to a number of files on which it should - already exist. - -2005-10-03 Elijah Newren - - * src/metacity.schemas.in: clarify the meaning of the auto_raise - preference. Fixes one of the issues in #312421. - -2005-10-03 Elijah Newren - - Patch from Ross Cohen to make alt-esc consistent with alt-tab by - leaving stacking of unselected windows unchanged. Fixes #314285. - - * src/keybindings.c (process_tab_grab): before raising and showing - the next candidate, reset the stack positions to what they were - at the beginning of the grab - -2005-10-03 Elijah Newren - - Patch from Ross Cohen to make alt-esc (show windows instantly) - actually show minimized windows too. Fixes #107072. - - * src/keybindings.c (process_tab_grab): initialize tab_unminimized - to FALSE for the target window when starting the grab, when - advancing through the list check to find the previous window and - re-minimize it if it was tab-unminimized, unminimize the new - window we're alt-esc'ing to if it's minimized, (do_choose_window): - raise and unminimize the initial window as well in alt-esc'ing - - * src/window.h (struct _MetaWindow): add a tab_unminimized field - - * src/window.c (meta_window_new_with_attrs): initialize - tab_unminimized to false - -2005-10-03 Elijah Newren - - Branched for Gnome 2.13. :-) - - * configure.in: bump version to 2.13.0. Add UNSTABLE warning. - * README: add 2.13.x to the list of unstable branches - -2005-10-03 Elijah Newren - - A combination of a couple memory leaks fixes, from Kjartan, - Soeren, and I. Fixes #313030. - - * src/bell.c (meta_bell_flash_screen): call XFreeGC() - - * src/frames.c (invalidate_cache): free pixels - - * src/window.c (meta_window_show_menu): call - meta_screen_free_workspace_layout() - -2005-10-03 Elijah Newren - - Patch from Björn Lindqvist fix the workspace switcher tabpopup to - display the right windows and to fix the - pick-a-new-window-to-focus algorithm in order to not select - windows that aren't showing. Fixes #170475. - - * src/tabpopup.c (meta_convert_meta_to_wnck, - meta_select_workspace_expose_event): factor out conversion code - from meta_select_workspace_expose_event() into the new - meta_convert_meta_to_wnck() function - - * src/tabpopup.c (meta_select_workspace_expose_event): - * src/workspace.c (focus_ancestor_or_mru_window): - replace the buggy window->minimized logic with - !meta_window_showing_on_its_workspace (window) - -2005-10-03 Elijah Newren - - Patch from Björn Lindqvist to have ancestors come along with the - transient when moving the window from one workspace to another. - Fixes #314977. - - * src/window.c (meta_window_change_workspace): have all ancestors - change workspaces too - -2005-10-03 Elijah Newren - - * configure.in: post-release version bump to 2.12.2 - -2005-10-03 Elijah Newren - - * NEWS: 2.12.1 release - -2005-10-03 Elijah Newren - - Truncate ridiculously long titles to avoid crashing or letting the - pager crash. Based on patch from Ray, incorporating suggestions - from Havoc and some extensions of my own. Fixes #315070. - - * src/display.c (set_utf8_string_hint, meta_display_open): - * src/xprops.[ch] (meta_prop_set_utf8_string_hint): - Move set_utf8_string_hint() to props.[ch], namespace it - ("meta_prop_"), and make it public - - * src/tabpopup.c (utf8_strndup, meta_ui_tab_popup_new): - * src/util.[ch] (meta_g_utf8_strndup): - Move utf8_strndup() to util.[ch], namespace it ("meta_g_"), and - make it public - - * src/display.c (meta_display_open): - * src/display.h (struct _MetaDisplay): - add net_wm_visible_name and net_wm_visible_icon_name atoms to the - list of atoms we work with - - * src/window-props.c (set_window_title, set_icon_title): If title - length is greater than 512, truncate it and set - _NET_WM_VISIBLE_NAME or _NET_WM_VISIBLE_ICON_NAME accordingly - -2005-10-03 Elijah Newren - - Get the tabbing window outline to work with gtk+ 2.8.4 again. - Fixes #317528. - - * src/tabpopup.c (display_entry): gtk+ 2.8.4 needs to know the - mapped state of its windows (see bug 316180), and since we - manually map with gdk_window_show_unraised() we need to manually - set the mapped state too - -2005-09-05 Elijah Newren - - * configure.in: post-release version bump to 2.12.1 - -2005-09-05 Elijah Newren - - * configure.in: - * README: - * NEWS: - 2.12.0 release - -2005-09-04 Danilo Šegan - - * configure.in: Added Armenian (hy) to ALL_LINGUAS. - -2005-09-03 Elijah Newren - - * HACKING: Add tips on how to more easily get the ids of windows, - and how to shorten xprop output. - -2005-09-02 Brent Smith - - * src/place.c: (meta_window_place): Moved the call to - meta_screen_get_natural_xinerama_list to earlier in - function so that xineramas_list is allocated before - find_first_fit is called. Fixes #315000 - -2005-08-22 Elijah Newren - - * configure.in: post-release version bump to 2.11.5 - -2005-08-22 Elijah Newren - - * NEWS: 2.11.3 release - -2005-08-22 Elijah Newren - - * configure.in: Patch from Björn Lindqvist to check for the - appropriate versions of glib and gtk. Fixes #314116. - -2005-08-12 Elijah Newren - - * src/place.c (meta_window_place): Avoid obscuring - centered-on-desktop windows which are denied focus. Fixes - #313234. - -2005-08-08 Elijah Newren - - * configure.in: post-release version bump to 2.11.3 - -2005-08-08 Elijah Newren - - * NEWS: 2.11.2 release - -2005-08-08 Elijah Newren - - Patch from Brent Smith to fix a duplicate string. Fixes #309774. - - * src/theme-parser.c (parse_toplevel_element, parse_draw_op_element): - Change "No \"%s\" attribute on element <%s>" string to "No \"%s\" - attribute on <%s> element" - -2005-08-03 Ray Strode - - Improve the behavior of keyboard move/resize and edge - snapping. Still not perfect, bug 310888. - - * src/effects.c (draw_xor_rect): Make the outside of a - wireframe rectangle line up with the outside edge of its - window, instead of centering the wireframe edges on the - window edges. - - * src/keybindings.c (process_keyboard_move_grab): allow - edge snapping in wireframe mode. Adjust code to take - into account changed semantics of find_next_*_edge - functions. - (process_keyboard_resize_grab_op_change): new function - to take some orthogonal logic out of - process_keyboard_resize_grab_op. Only allow keyboard - resize cursor to go to flat edges, not corners. - (process_keyboard_resize_grab): allow edge snapping in - wireframe mode. Fix up snapping logic. - - * src/place.c (get_{vertical,horizontal}_edges): use - GArray instead of int *, since the number of output - edges isn't known until the middle of the function now. - Use xor rect extents instead of window extends if in - wireframe mode. - (meta_window_find_next_{vertical,horizontal}_edge: add - new source_edge_position parameter to specify which edge - on the active window to start from when looking for next - edge on the screen. Return the coordinate of the edge - found and not the coordinate of where the window should be - moved to snap to where the edge was found. - - * src/window.c (update_move): all the user to specify - an edge to resize with mouse in keyboard resize mode. - window - -2005-08-01 Elijah Newren - - * src/metacity.schemas.in: Change default theme from "Simple" to - "Clearlooks". - -2005-07-31 Elijah Newren - - * src/stack.c (is_focused_foreach, get_standalone_layer): use only - the expected_focus_window instead of both the focused_window and - the expected_focus_window. Removes an infinite flicker loop in - sloppy and mouse focus, and an ugly one time flicker in click to - focus. Fixes #311400. - -2005-07-30 Elijah Newren - - Patch from Jaap Haitsma to make sure that Metacity dialogs have - icons. Fixes #309876. - - * src/metacity-dialog.c (kill_window_question, - warn_about_no_sm_support, error_about_command): call - gtk_window_set_icon_name() to set the dialog icon - -2005-07-28 Elijah Newren - - * src/place.c (avoid_being_obscured_as_second_modal_dialog): - remove some unneeded debug spew that was causing crashes. Fixes - #311819. - -2005-07-24 Elijah Newren - - * configure.in: post-release version bump to 2.11.2 - -2005-07-24 Elijah Newren - - * NEWS: 2.11.1 release - -2005-07-24 Elijah Newren - - * src/place.c (find_most_freespace): try to place windows denied - focus near the focus window and fix a xinerama bug with the - placement, (avoid_being_obscured_as_a_second_modal_dialog): avoid - modal dialogs being obscured in somewhat pathologically strange - circumstances that Eclipse seems to be good at triggering, - (meta_window_place): have dialog windows make use of - avoid_being_obscured_as_a_second_modal_dialog(). Fixes one of the - issues found in #307875. - -2005-07-24 Elijah Newren - - * src/window.c (meta_window_raise): raise the window as well as - its ancestor; fixes a stacking bug with an ancestor that has more - than one child window. Fixes one of the issues in #307875. - -2005-07-24 Elijah Newren - - * src/window.c (meta_window_free): restore original window size if - the window was maximized, as the FIXME says. ;-) Fixes #137185. - Thanks to Christian Persch for the testcase that made this easier - to track down. - -2005-07-23 Elijah Newren - - * src/window.c (meta_window_activate): revert the patch from - #128380--change _NET_ACTIVE_WINDOW behavior to what it originally - was. - -2005-07-18 Matthias Clasen - - * configure.in: Add checks for Xcursor, to make the changes - done on 2005-07-11 effective. - -2005-07-14 Elijah Newren - - Patch from Ken Harris to provide a more lenient threshold for - drawing rounded corners. Fixes #122065. - - * src/theme.c (meta_frame_layout_calc_geometry): use height + - width > 5 instead of height > 3 && width > 3 as criterion - -2005-07-13 Elijah Newren - - Fix a slight bug (causing possible miscoloring of parts of the - titlebar) introduced by the patch from #169982. - - * src/gradient.c: - (meta_gradient_create_interwoven): - (meta_gradient_create_multi_vertical): - - bitshifting operators do not take precedence over typecasting, so - make sure to use parentheses to get the right operation order. - -2005-07-12 Elijah Newren - - * configure.in: post-release version bump to 2.11.1 - -2005-07-12 Elijah Newren - - * NEWS: 2.11.0 release - -2005-07-12 Elijah Newren - - Patch from Andrew Johnson to speed up vertical gradients. Fixes - #169982. - - * src/gradient.c: - (meta_gradient_create_interwoven): - (meta_gradient_create_vertical): - (meta_gradient_create_multi_vertical): - - use memcpy instead of really long loops to set values in memory to - a given pattern. - -2005-07-12 Elijah Newren - - Patch from Björn Lindqvist to split up main() into more manageable - chunks and make use of GOpt. Closes #305331. - - * src/main.c (usage): remove this function, - (meta_print_compilation_info): new function taken from main(), - (meta_print_self_identity): new function taken from main(), - (struct MetaArguments) new struct to replace some free variables, - (meta_parse_options): new funcion taken from main() but now using - GOpt, (meta_select_display): new function taken from main() - -2005-07-12 Aivars Kalvans - - * src/screen.c (meta_screen_free): free ->xinerama_infos - Closes #307884 - -2005-07-11 Elijah Newren - - Stuff I forgot to do when I branched an hour or so ago before - Matthias' commit... - - * configure.in: bump version to 2.11.0. Add UNSTABLE warning. - * README: add 2.11.x to the list of unstable branches - -2005-07-11 Matthias Clasen - - React to cursor theme changes: (#308106) - - * src/prefs.h: - * src/prefs.c: Expose the GConf keys for cursor theme - and size as preferences META_PREF_CURSOR_THEME and - META_PREF_CURSOR_SIZE with getters meta_prefs_get_cursor_theme() - and meta_prefs_get_cursor_size(). - - * src/display.c (meta_display_open): Initialize the cursor - theme and size. - - * src/display.h: - * src/display.c (meta_display_set_cursor_theme): New function - to change the cursor theme and update all cursors. - - * src/screen.h - * src/screen.c (meta_screen_update_cursor): New function to - refesh the root cursor of a screen. - - * src/main.c (prefs_changed_callback): Update the cursor - theme when the cursor preferences change. - -2005-06-27 Elijah Newren - - * configure.in: post-release version bump to 2.10.3 - -2005-06-27 Elijah Newren - - * NEWS: 2.10.2 release - -Sun Jun 26 11:19:18 2005 Soeren Sandmann - - * src/frames.c: Add a cache of pixmaps for recently exposed frame - areas. Makes metacity a bit faster when dragging windows around. - See bug 141813. - -2005-06-10 Ryan Lortie - - * src/frames.c: Prevent using the address of a local variable - as a hash key. (Bug #307209) - - * src/xprops.c (meta_prop_get_values): Fix a small leak in the - case of a SYNC_COUNTER property value and HAVE_XSYNC not - defined. (Bug #307214) - -2005-06-07 Ray Strode - - Cleanup font data when done with it (bug 306720). - - * src/effects.c (draw_xor_rect): free font info structure. - * src/screen.c (meta_screen_new): pass a 1 not a 0 to - XFreeFontInfo to free font info structure. - (meta_screen_free): call XUnloadFont on GC font before freeing - the GC. - -2005-06-02 Elijah Newren - - * src/window.c (meta_window_focus): if the window has a modal - transient which is being unmanaged, don't focus it. Fixes the - Metacity issue reported in #305362. - -2005-05-30 Ray Strode - - Bug 305564 again. - - When drawing XOR resize popup use "fixed" font instead of - -misc-fixed-*-16-* xlfd. Should work on more xservers. - - Also take steps to fail better if the xserver isn't - cooperating. - - * src/effects.c (draw_xor_rect): if we can't draw font box - for whatever reason, at least draw grid frames. - - * src/screen.c (meta_screen_new): use fixed alias instead - of a xfld. Don't pass GCFont to XCreateGC if font couldn't - be loaded. Print a warning if font couldn't be loaded. - -2005-05-26 Elijah Newren - - * HACKING: Add a clarification that METACITY_VERBOSE needs to be - accompanied by METACITY_USE_LOGFILE - -2005-05-26 Elijah Newren - - * src/window.c (meta_window_configure_request): Patch from Greg - Hudson to make sure window position is calculated correctly for - reconfigure requests when part of the XWindowChanges structure is - uninitialized. Fixes #305257. - -2005-05-26 Ray Strode - - Actually commit the stuff mentioned in the last - ChangeLog entry. - -2005-05-26 Ray Strode - - Add a resize popup when resizing constrained - windows, (bug 305564). - - * src/display.c: - (meta_display_begin_grab_op), - (meta_display_end_grab_op): - * src/keybindings.c (process_keyboard_move_grab), - (process_keyboard_resize_grab): Call - meta_window_{begin,update,end}_wireframe convenience - functions instead of the meta_effects counterparts. - - * src/display.h: keep track of old wireframe geometry to - clean up xor popup on resize - - * src/effects.[ch] (meta_effects_begin_wireframe), - (meta_effects_update_wireframe), - (meta_effects_end_wireframe), - (draw_xor_rect): take optional width and height arguments - to show to user in resize popup. Draw resize popup if - width and height >= 0 and wireframe isn't smaller than - the popup would be. - - * src/screen.c (meta_screen_new): load a largish font for - the resize popup - - * src/window.[ch] - (meta_window_move_resize_internal): update - wireframe resize popup when the window is resized. - (meta_window_get_wireframe_geometry): new function to - calculate the numbers to display in resize popup - (meta_window_begin_wireframe), - (meta_window_update_wireframe), - (meta_window_end_wireframe): new functions to reduce - repetitive wireframe code. Functions handle updating - wireframe and resize popup geometry. - (update_move), (update_resize), - (meta_window_refresh_resize_popup): remove fixme and - add debug message. - -2005-05-26 Elijah Newren - - * src/window.c (check_maximize_to_work_area): don't accidentally - treat maximize vertically as maximize in both directions. Fixes - #302204. - -2005-05-26 Elijah Newren - - * src/window.c (meta_window_new_with_attrs): put all transients - of the new window, if any exist, in the calc_showing queue. Fixes - #303284. Thanks to Billy Biggs for the testcase that made this - easy to track down. - -2005-04-11 Elijah Newren - - * configure.in: post-release version bump to 2.10.2 - -2005-04-11 Elijah Newren - - * NEWS: 2.10.1 release - -2005-04-05 Dan Winship - - * src/metacity-dialog.c (warn_about_no_sm_support): Make sure the - "Close" button has the focus, not the table. (#172703) - -2005-04-05 Pawan Chitrakar - - * configure.in: Added ne in ALL_LINGUAS - -2005-03-31 Steve Murphy - - * configure.in: Added "rw" to ALL_LINGUAS. - -2005-03-17 Lex Hider - - * doc/Makefile.am (EXTRA_DIST): add doc/code-overview.txt and - doc/how-to-get-focus-right.txt - -2005-03-10 Adi Attar - - * configure.in: Added "xh" to ALL_LINGUAS. - -2005-03-07 Elijah Newren - - * configure.in: post-release version bump to 2.10.1 - -2005-03-07 Elijah Newren - - * configure.in: - * README: - * NEWS: - 2.10.0 release - -2005-02-28 Elijah Newren - - * configure.in: post-release version bump to 2.9.55 - -2005-02-28 Elijah Newren - - * NEWS: Metacity 2.9.34 unstable release - -2005-02-28 Elijah Newren - - Patch from Aidan Delaney to make sure that icons in the alt-tab - popup are dimmed for all hidden windows, not just minimized ones. - Fixes #168455. - - * src/screen.c: (meta_screen_ensure_tab_popup): make use - meta_window_showing_on_its_workspace() instead of just checking if - the window is minimized. - -2005-02-25 Elijah Newren - - Prevent the visual bell from changing the focus window. Fixes - #123366. - - * src/bell.c: (meta_bell_flash_screen): if not in click-to-focus - mode and mouse_mode is also false, increment the focus sentinel so - that we can ignore spurious EnterNotify and LeaveNotify events. - - * src.display.c: (event_callback): make sure to also ignore - LeaveNotify events when the focus sentinel isn't clear - -2005-02-23 Elijah Newren - - * src/window.c: (meta_window_new_with_attrs): Fix crash that - occurs when stupid apps claim that a window is its own parent. - #168207 - -2005-02-21 Elijah Newren - - * configure.in: post-release version bump to 2.9.34 - -2005-02-21 Elijah Newren - - * NEWS: Metacity 2.9.21 unstable release - -2005-02-21 Elijah Newren - - Handle keynav vs. mousenav in mouse and sloppy focus modes. Fixes - #167545. - - * doc/how-to-get-focus-right.txt: Update due to this new method - for handling keynav vs. mousenav, plus various other updates that - I previously forgot. - - * src/display.h: (struct _MetaDisplay): add a mouse_mode boolean - - * src/display.c: (meta_display_open): initialize mouse_mode to - true, (event_callback): have EnterNotify and LeaveNotify events - set mouse_mode to true when focusing a window - - * src/keybindings.c: (process_tab_grab): set mouse_mode to false - when using alt-tab/alt-esc, (do_choose_window): likewise, - (do_handle_move_to_workspace): set mouse_mode to false on - move-window-to-workspace- keybindings - - * src/window.c (idle_calc_showing): if we're in keynav mode while - using sloppy or mouse focus, use metacity_sentinel to avoid - EnterNotify events being generated from events other than mouse - movement. - - * src/workspace.c (meta_workspace_activate_with_focus): add a - FIXME in a potentially duplicate section of code, - (meta_workspace_focus_default_window): use the same focus choice - as click-to-focus if in keynav mode. - -2005-02-20 Elijah Newren - - * src/display.c: (event_callback): Handle _NET_CURRENT_DESKTOP - messages that come with timestamps. Fixes the metacity portion of - #161361 other than the portion handled by #128380. - -2005-02-20 Elijah Newren - - * src/window.c: (meta_window_activate): when receiving a - _NET_ACTIVE_WINDOW message, switch to the desktop where the window - is located before activating instead of moving the window to the - current desktop. Thanks to Lubos Lunak for catching this issue. - Fixes #128380. - -2005-02-20 Elijah Newren - - * src/window.c (meta_window_show): Ignore all focus and - focus-stealing-prevention code in meta_window_show when not - showing the window for the first time. Fixes #167199. - -2005-02-20 Elijah Newren - - Fix an obscure xinerama placement bug with windows that are too - large to fit in the workarea in both dimensions. #166757 - - * src/place.c: (meta_window_place): use the current xinerama - instead of arbitrarily resetting to 0 - -2005-02-20 Elijah Newren - - Patch from Joe Marcus Clarke to fix a possible crash on logout. - #167935. Thanks for fixing my mistakes, Joe! - - * src/display.c: (meta_display_open): initialize - display->grab_old_window_stacking to NULL. - -2005-02-20 Elijah Newren - - Big patch to cover about 6 different issues in order to correct - rare problems with timestamps (make sure window selected in - tasklist actually gets focus, sanity check timestamps to avoid - rogue apps hosing the system, correct the updating of - net_wm_user_time, correctly handle timestamps of 0 when comparing - xserver timestamps for those who have had their systems up for - over 25 days or so, add some debugging information to verbose - logs, some code cleanups). Fixes all issues listed in #167358. - - * src/display.h: (struct _MetaDisplay): clarify comment on - last_focus_time, introduce a new variable--last_user_time, - (XSERVER_TIME_IS_BEFORE macro): put this functionality into a - separate macro and then introduce a new macro with this name that - uses the old one but adds additional special-case checks for - timestamps that are 0, (comment to - meta_display_set_input_focus_window): add information about how - last_user_time should be used in this function - - * src/display.c (santiy_check_timestamps): new function, - (meta_display_open): intialize display->last_user_time, - (meta_display_get_current_time_roundtrip): use the timestamp, - which is known to be good, in order to sanity_check_timestamps, - (event_callback): use the new meta_window_ste_user_time() function - in order to correct problems, use the timestamp of KeyPress and - ButtonPress events, which are known to be good, in order to - sanity_check_timestamps, (timestamp_too_old): new function for - common behavior of meta_display_focus_the_no_focus_window and - meta_display_set_input_focus_window, with added checking for - display->last_user_time in addition to display->last_focus_time, - (meta_display_set_input_focus_window): replace some of the code - with a call to timestamp_too_old(), - (meta_display_focus_the_no_focus_window): replace some of th ecode - with a call to timestamp_too_old() - - * src/window.h: (meta_window_set_user_time): new function to - abstract the many things that need to be done when updating the - net_wm_user_time of any window - - * src/window.c: (meta_window_activate): add debugging spew, make - sure the comparison is made with last_user_time NOT - last_focus_time, use meta_window_set_user_time() function in order - to correct problems, (meta_window_client_message): add a newline - to a debugging message to make them easier to read, - (meta_window_set_user_time): new function - - * src/window-props.c (reload_net_wm_user_time): use the new - meta_window_ste_user_time() function in order to correct problems - -2005-02-16 Elijah Newren - - * src/display.c: (event_callback): trivial fix to a log message: - change %d to %lu (see debugging log from bug 167358). - -2005-02-12 Elijah Newren - - Raise the ancestor of a window instead of the window itself. - Fixes #166894. - - * src/window.c: (find_root_ancestor): new function, - (meta_window_raise): get the ancestor of the given window and - raise it if possible instead of the window - -2005-02-12 Elijah Newren - - Don't unconditionally place splashscreens (and other - not-to-be-focused windows) below the focus window. Fixes #167042. - - * src/window.c: (intervening_user_event_occurred): new function - taken from the timestamp comparison portion of the old - window_takes_focus_on_map function, (window_state_on_map): new - function with remainder of old window_takes_focus_on_map function - that determines both whether the window will take focus and - whether it should be placed on top, (meta_window_show): use - place_on_top_on_map to determine window stacking instead of trying - to infer it from takes_focus_on_map - -2005-02-11 Elijah Newren - - Avoid new windows being obscured by the focus window (and thus - possibly lost). Fixes #166524. - - * src/place.c: new MetaWindowDirection enum, - (find_most_freespace): new function to find where there is the - most space available around the focused window, - (meta_window_place): if a window is denied focus and the window - overlaps the focused window, retry the first-fit algorithm only - paying attention to the focus window position and if that fails - just find the location on the screen with the most space - available. - - * src/window.h: (struct MetaWindow): new - denied_focus_and_not_transient bitfield - - * src/window.c: (meta_window_new_with_attrs): initialize - denied_focus_and_not_transient, (meta_window_show): set and unset - the denied_focus_and_not_transient field appropriately - -2005-02-08 Aidan Delaney - - Removed useless function call. #166730 - - * src/tabpopup.c: (outline_window_expose): Removed unused - references to variables and an unnecessary function call to - gdk_window_get_size(). - -2005-02-08 Elijah Newren - - Avoid using CurrentTime when focusing, handle it better in case we - miss any cases. Fixes #166732. - - * src/window.c: (meta_window_shade): use - meta_display_get_current_time_roundtrip() to ensure we have a - valid timestamp, (meta_window_unshade): same - - * src/display.c: (meta_display_set_input_focus_window): If - CurrentTime was passed, get one from the XServer in addition to - throwing a warning, (meta_display_focus_the_no_focus_window): same - -2005-02-08 Elijah Newren - - * src/window.c: (meta_window_activate): If we're not passed a - timestamp, make sure to manually get one. Fixes #166728. - -2005-02-07 Elijah Newren - - * configure.in: post-release version bump to 2.9.21 - -2005-02-07 Elijah Newren - - * NEWS: Metacity 2.9.13 unstable release - -2005-02-06 Elijah Newren - - Set a _METACITY_VERSION property (a utf8 string) on the WM check - window. #165350. - - * src/display.h: (struct MetaDisplay): add a atom_metacity_version - field - - * src/display.c: (meta_display_open): initialize the - _METACITY_VERSION property on the WM check window to the current - version of Metacity. - -2005-02-06 Elijah Newren - - Ignore xconfigurerequest events for stacking when it should be - safe to do so. Again, thanks to Crispin Flowerday for the test - case. Thanks to KWin for the inspiration (and to Google for - indexing their source code). Fixes the other half of #166395. - - * src/window.c: (meta_window_configure_request): if the - active_window is from a separate application than the one getting - the configure request and the net_wm_user_time of the active - window is later than that of the window getting the configure - request, then ignore the request. - -2005-02-06 Elijah Newren - - If activation requests are too old, set the demands_attention hint - instead of actually activating. Thanks to Crispin Flowerday for - the test case and for testing the patch. Fixes half of #166395. - - * src/window.c: (meta_window_activate): if the request came before - the last focus time, set the demands attention hint instead - -2005-02-04 Dave Ahlswede - - * src/metacity.schemas.in: Add period to the end of - reduced_resources' description. Fixes #165780. - -2005-02-04 Elijah Newren - - Make sure window->border_only is initialized so we don't get - random windows without decorations. Thanks to Sinisa Segvic and - Owen Taylor for providing test cases. Fixes #145131. - - * src/window.c: (update_mwm_hints): Be sure to call - recalc_window_features even if no MWM hints are set - -2005-02-02 Elijah Newren - - Focus parents of dismissed transient windows in preference to the - window that most recently had keyboard focus. Fixes #157360. - - * doc/how-to-get-focus-right.txt: Note the distinction between - "most recently used window" and "most recent to have keyboard - focus" that we are now making. - - * src/workspace.c: (focus_ancestor_or_mru_window): rename from - meta_workspace_focus_mru_window, and first check whether we need - to focus an ancestor window before looking for the mru window, - (record_ancestor): helper function for - focus_ancestor_or_mru_window, - (meta_workspace_focus_default_window): update due to the function - rename from meta_workspace_focus_mru_window to - focus_ancestor_or_mru_window - -2005-01-31 Elijah Newren - - Try 2 to correct misleading and inaccurate wording. Hopefully, - really fixes #165380. - - * src/menu.c: Change wording of menu from "Always on Current - Workspace" to "Always on Visible Workspace". "Always on Current - Workspace" could sound like a synonym of "Only on This Workspace" - when it was supposed to be the opposite. - -2005-01-31 Elijah Newren - - Correct the stacking when return from fullscreen mode. Fixes - #165718. - - * src/window.c: (meta_window_unmake_fullscreen): Update the layer - after resizing the window - -2005-01-31 Muktha - - src/themes/Atlanta/metacity-theme-1.xml: - src/themes/Simple/metacity-theme-1.xml: - src/themes/Bright/metacity-theme-1.xml: - Make the unfocussed title bar distinguishable. Fixes #125291. - -2005-01-28 Elijah Newren - - Patch from RHEL-3 (Havoc doesn't remember how it got there) that - Havoc posted in bug 156511 to fix the problem with fullscreen - windows on a different xinerama monitor not staying on top. I - updated to HEAD. Should fix #156511. - - * src/stack.c: (windows_on_different_xinerama): new function, - (get_standalone_layer): let windows on a different screen than the - one with the focus window stay in the fullscreen layer - -2005-01-28 Elijah Newren - - * src/metacity-dialog.c: (warn_about_no_sm_support): make this - dialog be sticky. Fixes #164745. - -2005-01-28 Elijah Newren - - Patch from Tim Herold to handle xcomposite pkgconfig version - regression. Fixes #149368. - - * configure.in: Change XCOMPOSITE_VERSION from 1.0 to 0.2 - -2005-01-28 Elijah Newren - - Correct misleading and inaccurate wording. Fixes #165380. - - * src/menu.c: Change wording of menu to "Always on Current - Workspace" from "Put on All Workspaces", remove a quick-key - conflict between "On _Top" and "Only on _This Workspace" by - switching the latter to "_Only on This Workspace" - - * src/window.c: Remove a comment that is no longer necessary - (since bug 87531 has been fixed) - -2005-01-28 Elijah Newren - - Take into account the appropriate list of windows when placing a - new one. Fixes #165381. - - * src/place.c: (meta_window_place): use - meta_window_showing_on_its_workspace(w) instead of !w->minimzed, - also take into account sticky windows - - * src/window.[ch]: rename window_showing_on_its_workspace to - meta_window_showing_on_its_workspace and export it - -2005-01-27 Elijah Newren - - Plug a pair of leaks. Fixes #165378 - - * src/place.c: (meta_window_place, get_windows_on_same_workspace): - free list returned by meta_display_list_windows. - -2005-01-27 Elijah Newren - - Treat splashscreens same as other windows for stacking. Fixes - #165243. - - * src/stack.h: (MetaStackLayer enum): remove META_LAYER_SPLASH - from the list - - * src/stack.c: (get_standalone_layer): remove the special casing - of META_WINDOW_SPLASHSCREEN - -2005-01-27 Elijah Newren - - * src/window.c: (set_net_wm_state): shaded windows should not show - up in pagers. Fixes #165377. - -2005-01-26 Elijah Newren - - Stick and unstick transients with their parent automatically. - Fixes #152283. - - * src/window.c: (window_stick_impl, window_unstick_impl): rename - from meta_window_stick and meta_window_unstick respectively, - (stick_foreach_func): a function to assist calling - window_(un)stick_impl on each transient, (meta_window_stick, - meta_window_unstick): new functions that call window_stick_impl or - window_unstick_impl for the window and each of its transients. - -2005-01-26 Elijah Newren - - Patch from John Paul Wallington to keep tooltip on screen - horizontally for xinerama. Fixes #165261. - - * src/fixedtip.c: (meta_fixed_tip_show): rename screen_width and - screen_height to screen_right_edge and screen_bottom_edge, set - them using xinerama info instead of just screen geometry, and use - them to determine where to place the tooltip window. - -2005-01-26 Arvind Samptur - - Don't wireframe when accessibility is on, it apparently - causes a desktop wide freeze. - - * src/prefs.[ch] (meta_prefs_init) (change_notify) - (update_gnome_accessibility) (meta_preference_to_string) - (meta_prefs_get_gnome_accessibility) : Add code to monitor - accessibility status. - - * src/display.c (meta_display_begin_grab_op): Check - accessibility status before going ahead with wireframe. - Fixes #159538 - -2005-01-25 Elijah Newren - - * src/tabpopup.c: (meta_select_workspace_expose_event): ignore - sticky windows for non-active workspaces. Fixes #165259. - -2005-01-25 Elijah Newren - - * src/window.c: (meta_window_new_with_attrs): set the window state - hints _after_ applying session information. Fixes #164677. - -2005-01-25 Elijah Newren - - Add man pages for metacity-window-demo and metacity-theme-viewer. - Man pages from Jose Moya, auto-fu from Dave Ahlswede. (#143513) - - * doc/man/metacity-theme-viewer.1: - * doc/man/metacity-window-demo.1: - - New man pages - - * doc/man/Makefile.am: - * doc/Makefile.am: - * configure.in: - - Make sure to install the man pages - - * doc/man/.cvsignore: - - Silence cvs - -2005-01-25 Benjamin Kahn - - New 48x48 default icon as specified in bug #160660 - -2005-01-25 Elijah Newren - - Patch from Stephane LOEUILLET in bug #151850. - - * src/metacity.desktop.in: specify encoding - -2005-01-25 Balamurali Viswanathan - - * src/prefs.c (meta_prefs_init): Get gconf to load the - terminal dir so that we get the notifications when - the command is changed. Fixes bug #160934 - -2005-01-25 Elijah Newren - - Refuse to focus a window with a modal transient, and focus the - transient instead. Fixes #164716. - - * src/window.c: (get_modal_transient): new function, - (meta_window_focus): if the window has a modal transient, make - sure it is on the current workspace and then focus it instead. - -2005-01-24 Elijah Newren - - * configure.in: post-release version bump to 2.9.13 - -2005-01-24 Elijah Newren - - * NEWS: Metacity 2.9.8 unstable release - -2005-01-24 Elijah Newren - - * src/display.c: (meta_display_begin_grab_op): don't forget to - initialize display->grab_old_window_stacking. Thanks to Sebastien - Bacher and the bleeding edge Ubuntu users for catching the - occasional crash this could cause so quickly, and for verifying - that the patch worked (I couldn't duplicate). Fixes #165093. - -2005-01-23 Elijah Newren - - * configure.in: post-release version bump to 2.9.8 - -2005-01-23 Elijah Newren - - * NEWS: Metacity 2.9.5 unstable release - * README: there are more stable releases beyond 2.8.6... - -2005-01-23 Elijah Newren - - Restore original stacking when aborting an alt-esc window switch - operation. Fixes #123576. - - * src/display.c: (GRAB_OP_IS_WINDOW_SWITCH): new macro, - (meta_display_close): clear grab_old_window_stacking if non-NULL, - (event_callback): restore stack positions if alt-esc op cancelled - with button press, (meta_display_begin_grab_op): store the old - stacking positions, (meta_display_end_grab_op): free the old stack - positions - - * src/display.h: (struct _MetaDisplay): add a - grab_old_window_stacking list - - * src/keybindings.c: (process_tab_grab): restore stack positions - if alt-esc op cancelled with an errant key press - - * src/stack.c: (compare_just_window_stack_position): new - GCompareFunc function, (meta_stack_get_positions): get current - stack positions, (compare_pointers): new GCompareFunc function, - (lists_contain_same_windows): simple utility func to see if two - lists contains the same windows, (meta_stack_set_positions): new - function to set the positions of all the windows in the stack - - * src/stack.h: (meta_stack_get_postions, - meta_stack_set_positions): new functions - -2005-01-23 Elijah Newren - - Patch from John Paul Wallington to fix #163420. - - * src/window.c: (check_maximize_to_work_area): fix vertical - maximization for second screen - -2005-01-21 Elijah Newren - - * rationales.txt: Add a tracker bug for modal dialog issues - -2005-01-20 Elijah Newren - - * src/tabpopup.c (dimm_icon): use pixbuf, not dimmed_pixbuf (which - isn't defined yet). Fixes crash from #136666. - -2005-01-20 Vincent Noel - - * src/screen.c: (meta_screen_ensure_tab_popup), - (meta_screen_ensure_workspace_popup): - * src/tabpopup.c: (meta_ui_tab_popup_new), (display_entry): - * src/tabpopup.h: Show labels in bold for windows that demand - attention. Fixes #164590. - -2005-01-18 Vincent Noel - - * src/screen.c: (meta_screen_ensure_tab_popup), - (meta_screen_ensure_workspace_popup): - * src/tabpopup.c: (dimm_icon), (meta_ui_tab_popup_new), - (free_entry): - * src/tabpopup.h: In the tab task switcher popup, dim the window - icon and put its name between brackets when the window is - minimized. Fixes #136666. - -2005-01-11 Elijah Newren - - Correct highlighting of windows in workspace switcher popup. - Fixes #163450. - - * src/tabpopup.c (meta_select_workspace_expose_event): Remove race - between FocusIn/FocusOut events and the expose event by replacing - window->has_focus with - window==window->display->expected_focus_window. - -2005-01-09 Elijah Newren - - * configure.in: post-release version bump to 2.9.5 - -2005-01-09 Elijah Newren - - * NEWS: Metacity 2.9.3 unstable release - -2005-01-09 Elijah Newren - - * src/display.c (meta_display_open): - * src/display.h (struct _MetaDisplay): - * src/window.c (meta_window_free, meta_window_client_message, - meta_window_notify_focus): - - Remove the hack from bug 128200; it isn't needed anymore with the - fix from bug #160470. - -2005-01-09 Elijah Newren - - Don't focus the panel on click. Fixes #160470 (and 100470 and - removes the need for the hack from 128200) - - * doc/how-to-get-focus-right.txt: Update section on focusing - non-decorated windows (specifically, DOCKS and DESKTOPS) - - * src/display.c (event_callback): don't focus dock windows on - click - -2005-01-06 Elijah Newren - - Make sure the save session dialog appears focused. Fixes #162983. - - * src/session.c (warn_about_lame_clients_and_finish_inter): Get a - timestamp by explicit request from Xserver, since none is - available otherwise. - -2005-01-06 Leena Gunda - - * src/window.c (meta_window_unmaximize): Restore the wireframe - rectangle co-ordinates to saved window co-ordinates. Fixes - bug #161236. - -2005-01-03 Thomas Fitzsimmons - - * src/Makefile.am (install-data-local): Install schema data from - builddir not srcdir. - -2005-01-02 Elijah Newren - - Provide more documentation to make it easier for people to - contribute to Metacity. (#162646) - - * HACKING: Add lots of information to extend this document: more - on relevant standards and X properties, lots of information on - debugging and testing, and add a list of some other important - things to read; also move some information to - src/code-overview.txt and organize this file into sections. - - * doc/code-overview.txt: New file including some small parts from - the old HACKING file and lots of new stuff. This file gives a - brief overview of some of the bigger structures and files, with - guides for a variety of task categories providing places to start - looking in the code and things to look for. - -2004-12-28 Elijah Newren - - Allow users to move the window around immediately after - double-clicking to shade (#90290) - - * src/display.c (event_callback): only end the grab op if either - there is no frame or else the frame is not mapped - -2004-12-27 Elijah Newren - - Focus windows that manually position themselves too (fixes - #107347). - - * src/window.h (struct _MetaWindow): add a new - showing_for_first_time flag - - * src/window.c (meta_window_new_with_attrs): initialize - showing_for_first_time flag to !mapped, (meta_window_show): - replace did_placement with showing_for_first_time in the section - to decided whether to focus since did_placement isn't quite what - we want - -2004-12-27 Elijah Newren - - * src/display.c (meta_display_set_input_focus_window, - meta_display_focus_the_no_focus_window): Spew warning if - CurrentTime is passed to the function, but don't exit prematurely. - (fixes #162353) - -2004-12-24 Elijah Newren - - * src/window.c (meta_window_show_menu): Don't show menu if all - options are invalid (fixes #148915) - -2004-12-24 Elijah Newren - - * src/window.c (window_takes_focus_on_map): Fix error in - distinguishing < vs. <= introduced by the patch in #154598, - restructure code so that verbose log matches code better in order - ensure such mistakes are harder to make in the future (fixes - #162172) - -2004-12-24 Elijah Newren - - Thanks to mild7@users.sourceforge.net for this fix. - - * src/window.h: (META_WINDOW_IN_NORMAL_TAB_CHAIN): Excludes - windows with skip_taskbar hint set from the alt-tab list; they'll - appear in the ctrl-alt-tab list instead. (fixes #106249) - -2004-12-22 Elijah Newren - - Wrap XSetInputFocus, making display->expected_focus_window a - little more reliable (see #154598) - - * src/display.h: (struct _MetaDisplay): add a large comment about - the expected_focus_window, add a last_focus_time field, - (XSERVER_TIME_IS_BEFORE): new macro moved from window.c but fixed - for 64-bit systems, (meta_display_set_input_focus_window): new - function - - * src/display.c (meta_display_open): initialize last_focus_time, - add a comment about brokenness of trying to set intial focus - window, (meta_display_set_input_focus_window): new function that - wraps XSetInputFocus, - (meta_display_focus_the_no_focus_window): make this function - closer to a wrapping of XSetInputFocus for the no_focus_window. - - * src/window.c (XSERVER_TIME_IS_LATER): remove this macro in favor - of the improved one added to display.h - - * src/display.c (meta_display_open): - * src/window.c (meta_window_focus): - use meta_display_focus_the_no_focus_window and - meta_display_set_input_focus instead of XSetInputFocus - -2004-12-22 Elijah Newren - - * src/core.c (meta_core_user_lower_and_unfocus): - * src/display.c (meta_display_get_current_tab): - * src/stack.c (get_default_focus_window, meta_stack_list_windows): - * src/window.c (set_net_wm_state, meta_window_should_be_showing, - implement_showing, meta_window_activate, - meta_window_notify_focus): - * src/window.h: - * src/workspace.c (meta_workspace_list_windows): - - Rename meta_window_visible_on_workspace to - meta_window_located_on_workspace (whether or not the window was - showing wasn't taken into account, which made "visible" - confusing). Fixes #136314. - -2004-12-22 Elijah Newren - - Partially resolve the conflicting requirements of windows on - multiple workspaces and hidden being a global quantity for windows - (fixes bug 156182; the remainder of the work is bug 87531 and is a - libwnck issue) - - * src/display.c (event_callback): - * src/window.c (meta_window_visible_on_workspace, meta_window_unstick): - * src/workspace.c (meta_workspace_add_window, - meta_workspace_contains_window, - meta_workspace_queue_calc_showing): - * src/workspace.h: - - Remove meta_workspace_contains_window, replace with simple - comparison utilizing window->workspace - - * src/place.c (meta_window_place): - * src/window.c (meta_window_shares_some_workspace): - * src/window.h: - - Remove meta_window_shares_some_workspace, replace with a simple - comparison utilizing window->workspace - - * src/session.c (save_state), - * src/window.c (meta_window_new_with_attrs, - meta_window_apply_session_info, meta_window_free, - window_showing_on_its_workspace, - meta_window_change_workspace_without_transients, - meta_window_unstick, meta_window_set_current_workspace_hint, - meta_window_get_workspaces): - * src/window.h: - * src/workspace.c (meta_workspace_free, meta_workspace_add_window, - meta_workspace_remove_window): - - Only one workspace now - -2004-12-20 Elijah Newren - - * configure.in: post-release version bump to 2.9.3 - -2004-12-20 Elijah Newren - - * NEWS: Metacity 2.9.2 unstable release - -2004-12-20 Elijah Newren - - * configure.in: re-add the note about Fibonacci sequence micro - version numbers that was lost with 2.8.5 - -2004-12-19 Elijah Newren - - Thanks to Baptiste Mille-Mathias for this fix. - - * src/metacity.schemas.in: Add a missing period at the end of a - sentence. - -2004-12-19 Elijah Newren - - When snap-moving, don't snap to transients of minimized windows - since they are hidden. Fixes #157180 - - * src/place.c (get_windows_on_same_workspace): make the logic to - determine hidden windows more thorough by calling - meta_window_should_be_showing() - - * src/window.c (meta_window_should_be_showing): rename this - function from window_should_be_showing and also export it, - (implement_showing): - s/window_should_be_showing/meta_window_should_be_showing/, - (idle_calc_showing): - s/window_should_be_showing/meta_window_should_be_showing/ - - * src/window.h (meta_window_should_be_showing): Add this function - to the list so that it can be used in src/place.c - -2004-12-19 Elijah Newren - - Focus the desktop when showing it. Fixes #159257. - - * src/display.c (event_callback): obtain a timestamp to pass to - meta_screen_show_desktop - - * src/keybindings.c (handle_toggle_desktop): obtain a timestamp to - pass to meta_screen_show_desktop - - * src/screen.c (meta_screen_show_desktop): add a timestamp - parameter, get the most recently used window of type DESKTOP (if - there is one) and focus it - - * src/screen.h (meta_screen_show_desktop): add a timestamp - parameter - -2004-12-19 Elijah Newren - - Thanks to ash@contact.bg for this fix. - - * po/POTFILES.in: Remove reference to metacity-properties.* files - since Alex removed them in his 2004-12-07 commit. - -2004-12-13 Elijah Newren - - * configure.in: post-release version bump to 2.9.2 that I forgot - to do last week (oops) - -2004-12-07 Alex Duggan - - * configure.in: - * src/tools/Makefile.am: - - Remove deprecated capplet from GNOME 2.0 - - * src/tools/metacity-properties.c: - * src/tools/metacity-properties.desktop.in: - * src/tools/metacity-properties.glade: - * src/tools/metacity-properties.png: - - Removed from cvs - -2004-12-06 Elijah Newren - - * NEWS: Metacity 2.9.1 unstable release - -2004-12-06 Benjamin Kahn - - * src/default_icon.png: Use a better default application - icon. Fixes bug #160373 - -2004-11-16 Marco Pesenti Gritti - - * src/Makefile.am: - - Fix build out of src directory. Bug #158325 - -2004-11-10 James Henstridge - - * Makefile.am (DISTCLEANFILES): remove intltool stuff on distclean. - - * src/themes/Makefile.am (uninstall-local): add uninstall rule. - - * src/Makefile.am (libmetacity_private_la_CFLAGS): set this - variable so that the files shared with metacity get compiled with - different names. - - * configure.in: use more modern macros in some places, and make - sure that $ACLOCAL_AMFLAGS is set so that rebuilds work better. - - * autogen.sh (conf_flags): use newer automake. - -2004-11-06 Vincent Untz - - * src/metacity.schemas.in: gnome-panel-screenshot was renamed to - gnome-screenshot - -2004-11-01 Elijah Newren - - * configure.in: bump version to 2.9.1 - -2004-11-01 Elijah Newren - - * NEWS, README: Metacity 2.9.0 (unstable release) - -2004-10-25 Elijah Newren - - Don't lower newly mapped windows when they're denied focus, if - they are transients of the focused window. Instead, defocus the - currently focused window. (fixes #151996). - - (Also, reenable focus stealing prevention and do a small spacing - cleanup) - - * src/window-props.c (init_net_startup_id): fix spacing - - * src/window.c (window_takes_focus_on_map): re-enable focus - stealing prevention, (meta_window_show): if the new window is - denied focus and is a transient of the currently focused window, - defocus the currently focused window but keep the transient on - top; remove some old code about transients and focus; make sure - that EnterNotify events won't accidentally focus the new window. - -2004-10-25 Elijah Newren - - Fix the alt-tab order--if the most recently used window is not - focused, start alt tabbing with that window instead of the one - after it (fixes #156251) - - * src/display.c (find_tab_forward): add a skip_first parameter, - (find_tab_backward): add a skip_last parameter, - (meta_display_get_tab_next): if a beginning window wasn't given - and the focused window isn't the tab chain, don't skip the MRU - window - -2004-10-22 Elijah Newren - - Update _NET_WM_STATE_HIDDEN so the pager on the panel will know - whether to display windows as visible or hidden (#105665) - - * src/screen.c (queue_windows_showing): Revert the - queue_windows_showing portion of the patch committed on 2004-10-16 - for #142198--it was an ill-advised optimization. - - * src/window.c (window_showing_on_its_workspace, - window_should_be_showing): split the old window_should_be_showing - into these two functions, (set_net_wm_state): hidden state is more - complex; use window_showing_on_its_workspace to determine the - correct value - -2004-10-20 Elijah Newren - - Patch from Soeren to fix the modifier key breakage introduced by - an Xorg change. (fixes #151554) - - * src/keybindings.c: include X11/XKBlib.h if available, - (handle_spew_mark): remove this unused function declaration, - (end_keyboard_grab): new function, uses XKB if available, - (process_tab_grab): use end_keyboard_grab to determine whether to - end the grab, (error_on_command): make key a const char *, - (process_workspace_switch_grab): use end_keyboard_grab to - determine whether to end the grab - -2004-10-19 Anders Carlsson - - * src/frame.c: (meta_window_ensure_frame): - Don't try to use an ARGB visual at all if the depth isn't - 32-bit. This caused major slowdowns with Composite enabled. - -2004-10-16 Elijah Newren - - Make the "showing desktop" mode be per-workspace instead of - per-screen. (fixes #142198) - - * src/keybindings.c (handle_toggle_desktop): access - showing_desktop through the active workspace - - * src/screen.c (meta_screen_new): remove initialization of - screen->showing_desktop, - (meta_screen_update_showing_desktop_hint): rename and make not - static and access showing_desktop through the active workspace, - (queue_windows_showing): replace meta_display_list_windows() with - screen->active_workspace->windows, - (meta_screen_minimize_all_on_active_workspace_except): renamed - from meta_screen_minimize_all_except since it now only works on - the active workspace, (meta_screen_show_desktop, - meta_screen_unshow_desktop): access showing_desktop through the - active workspace - - * src/screen.h (struct _MetaScreen): remove showing_desktop field, - (meta_screen_minimize_all_on_active_workspace_except): rename from - meta_screen_minimize_all_except, - (meta_screen_update)_showing_desktop_hint): export this function too - - * src/window.c (maybe_leave_show_desktop_mode): access - showing_desktop through the active workspace and use new name for - meta_screen_minimize_all_on_active_workspace_except, - (window_should_be_showing): access showing_desktop through the - active workspace - - * src/workspace.c (meta_workspace_new): initialize - workspace->showing_desktop, (meta_workspace_activate_with_focus): - add note that old can be NULL, update showing_desktop_hint if - different on this workspace than the previous one - - * src/workspace.h (struct _MetaWorkspace): add showing_desktop - field - -2004-10-16 Elijah Newren - - * rationales.txt: Add new tracker bugs - -2004-10-15 Elijah Newren - - * src/keybindings.c (reload_keymap): Fix from Rob to correct - requested number of keycodes (#155247) - -2004-10-13 Elijah Newren - - Code cleanup - - * src/window.c (is_in_dock_group, docks_at_end_cmp, - shuffle_docks_to_end): removed functions, - (meta_window_notify_focus): no need to call is_in_dock_group or - shuffle_docks_to_end because of the patch from #120100 that was - committed. - -2004-10-13 Vincent Untz - - Add a keybinding to launch a terminal - - * src/keybindings.c: (handle_run_terminal): new function, - (error_on_generic_command): new function, (error_on_command): wrapper - around error_on_generic_command(), (error_on_terminal_command): new - function - - * src/metacity.schemas.in: add run_command_terminal key - - * src/prefs.[ch]: (meta_prefs_init): cache the terminal command and - register a gconf callback to update it, (change_notify): handle the - notification of terminal command changes, (meta_preference_to_string): - add the terminal command case, (update_terminal_command): new function, - (meta_prefs_get_terminal_command): new function, - (meta_prefs_get_gconf_key_for_terminal_command): new function - -2004-10-11 Rob Adams - - * configure.in: bump version to 2.9.0. Add UNSTABLE warning. - -2004-10-11 Rob Adams - - * NEWS, README: Metacity 2.8.6 (stable release) - -2004-10-08 Elijah Newren - - Fix middle-frame-click-to-lower focus inconsistency (#154601) - - * src/core.c (meta_core_user_lower_and_unfocus): focus the default - window in all focus modes, not just click-to-focus (EnterNotify - events will not handle this case for sloppy and mouse focus) - - * src/display.c (event_callback): replace window->has_focus with - window == display->expected_focus_window to avoid a race issue - -2004-10-08 Elijah Newren - - Alter the meaning of expected_focus_window; doesn't affect - current operation but assists in fixing some other bugs - (#154598) - - * src/display.c (meta_display_focus_the_no_focus_window): set the - expected_focus_window to NULL. - - * src/window.c (meta_window_notify_focus): don't NULL the - expected_focus_window when that window receives a FocusIn event - -2004-10-04 Elijah Newren - - * src/display.c (event_callback): if the root window gets focused, - set the focus to the default window; this fixes the - "focus-follows-mouse" behavior seen for click-to-focus mode after - cancelling log out (fixes #153220) - -2004-10-04 Elijah Newren - - Fix a variety of issues with autoraise (#134206) - - * src/display.h: (struct _MetaDisplay): add an autoraise_window - parameter - - * src/display.[hc] (meta_display_focus_the_no_focus_window): new - function, (meta_display_queue_autoraise_callback): new function, - (meta_display_remove_autoraise_callback): new function - - * src/display.c (meta_display_open): intialize - display->autoraise_window too, (meta_display_close): remove any - pending autoraise callback, (window_raise_with_delay_callback): - clear out auto_raise->display->autoraise_window too, - (event_callback): call meta_display_queue_autoraise_callback - instead of having the code inline, call - meta_display_focus_the_no_focus_window to handle focusing that - window - - * src/window.c (meta_window_focus): If there's a window with an - autoraise timeout that isn't the window being focused, remove the - autoraise timeout - - * src/workspace.c (meta_workspace_focus_default_window): If no - autoraise timeout is queued for the given window then queue one - now, call meta_display_focus_the_no_focus_window to handle - focusing that window, (meta_workspace_focus_mru_window): call - meta_display_focus_the_no_focus_window to handle focusing that - window - -2004-10-04 Elijah Newren - - * src/display.c (event_callback): When no window becomes focused, - focus the default window instead of punting to the - no_focus_window. Also, change the warning to a verbose - message--this will happen frequently due to brain-damage in the X - protocol. (see #125492) - -2004-10-04 Elijah Newren - - Fix a variety of focus race conditions in all focus modes, or at - least make them harder to trigger (fixes #152000) - - * src/core.[ch] (meta_core_user_lower_and_unfocus): add a - timestamp parameter; pass it along to - meta_workspace_focus_default_window - - * src/display.[ch] (meta_display_get_current_time_roundtrip): new - function - - * src/display.c (event_callback): pass a timestamp to the - meta_workspace_activate and meta_workspace_focus_default_window - function calls - - * src/frames.c (meta_frames_button_press_event): pass a timestamp - to meta_core_user_lower_and_unfocus - - * src/keybindings.c (handle_activate_workspace): pass a timestamp - to meta_workspace_activate, (process_workspace_switch_grab): pass - a timestamp to meta_workspace_focus_default_window and - meta_workspace_activate, (handle_toggle_desktop): pass a timestamp - to meta_workspace_focus_default_window, - (do_handle_move_to_workspace): pass a timestamp to - meta_workspace_activate_with_focus, (handle_workspace_switch): - meta_workspace_activate - - * src/screen.c (meta_screen_new): pass a timestamp to - meta_workspace_activate - - * src/window.c (meta_window_free): pass a timestamp to - meta_workspace_focus_default_window, (idle_calc_showing): don't - increment the focus sentinel here, (meta_window_minimize): pass a - timestamp to meta_workspace_focus_default_window, - (meta_window_client_message), pass a timestamp to - meta_workspace_focus_default_window - - * src/workspace.h (meta_workspace_activate): add timestamp - parameter, (meta_workspace_activate_with_focus): add timestamp - parameter, (meta_workspace_focus_default_window): add timestamp - parameter - - * src/workspace.c (meta_workspace_focus_mru_window): make this - function take a timestamp and use it for meta_window_focus or - XSetInputFocus, (meta_workspace_activate_with_focus): make this - function take a timestamp and pass it along to meta_window_focus - and meta_workspace_focus_default_window, - (meta_workspace_activate): make this function take a timestamp and - pass it to meta_workspace_activate_with_focus), - (meta_workspace_focus_default_window): make this function take a - timestamp, warn if its 0 but try to handle that case sanely, and - pass the timestamp on to meta_window_focus or - meta_workspace_focus_mru_window or XSetInputFocus - -2004-09-22 Elijah Newren - - * src/keybindings.c (process_workspace_switch_grab): Focus the - default window after the user dismisses the workspace switcher - popup (fixes #123803; note that an alternate fix was made - independently by David Baron for sloppy and mouse focus users) - -2004-09-22 Elijah Newren - - Fix some uninitialized variable errors reported by valgrind (see - #153338) - - * src/display.c (meta_display_open): initialize - display->grab_resize_timeout_id, and display->grab_have_keyboard - - * src/ui.c (meta_ui_create_frame_window): initialize attrs.width - and attrs.height - -2004-09-17 Elijah Newren - - * src/workspace.c (meta_workspace_focus_mru_window): Don't focus a - window that is minimized (fixes #147947) - -2004-09-17 Kjartan Maraas - - * src/bell.c: (meta_bell_flash_screen): - * src/compositor.c: - * src/effects.c: (meta_effects_draw_box_animation): - * src/fixedtip.c: (meta_fixed_tip_show): - * src/frame.c: (find_argb_visual): - * src/frames.c: (unsigned_long_hash), (meta_frames_manage_window), - (meta_frames_apply_shapes): - * src/iconcache.c: (find_largest_sizes), (find_best_size): - * src/keybindings.c: (meta_spawn_command_line_async_on_screen): - * src/main.c: (main): - * src/menu.c: (meta_window_menu_new): - * src/prefs.c: (meta_prefs_get_visual_bell), - (meta_prefs_bell_is_audible), (meta_prefs_get_visual_bell_type), - (meta_prefs_get_action_double_click_titlebar), - (meta_prefs_get_auto_raise), (meta_prefs_get_auto_raise_delay), - (meta_prefs_get_reduced_resources): - * src/screen.c: (meta_create_offscreen_window): - * src/tabpopup.c: (meta_ui_tab_popup_get_selected): - * src/theme-parser.c: (meta_theme_load): - * src/theme.c: (meta_gtk_widget_get_font_desc): - * src/tools/metacity-mag.c: (mouse_press), (begin_area_grab): - * src/util.c: (meta_unsigned_long_hash): A load of fixes of issues - reported by sparse. Closes bug #152849 - -2004-09-15 Elijah Newren - - * src/display.c (event_callback): Remove some redundant code - regarding focusing the default window (#152117) - -2004-09-15 Elijah Newren - - Patch from Ken Harris in #135786 to focus a new default window - when lowering via middle-click on the frame. - - * src/core.[hc], src/frames.c: rename meta_core_user_lower to - meta_core_user_lower_and_unfocus - - * src/core.c (meta_core_user_lower_and_unfocus): if in - click-to-focus mode then also move the window to the back of the - mru list and focus the new default window for the active workspace - -2004-09-15 Elijah Newren - - Focus the no_focus_window if no suitable window is in the mru list - (should fix the almost contrived extra issue found in #147475) - - * doc/how-to-get-focus-right.txt: We no longer need to lie about - only focusing panels upon explicit request. - - * src/workspace.c: (meta_workspace_focus_top_window): removed this - function--it was more code than needed and was unreliable anyway, - (meta_workspace_focus_mru_window): if a suitable window isn't in - the mru list, focus the no_focus_window instead of calling - focus_top_window. - -2004-09-15 Elijah Newren - - Prevent focus inconsistencies by only providing one focus method - (fixes #151990) - - * src/screen.c (meta_screen_show_desktop): remove call to - meta_workspace_focus_top_window (it was merely focusing a window - that was going to be hidden anyway, and likely the one that - already had focus) - - * src/workspace.[hc]: remove meta_workspace_focus_mru_window and - meta_workspace_focus_top_window from workspace.h, make them static - functions in workspace.c - -2004-09-15 Elijah Newren - - Remove race condition for focus window choice on window close - followed by rapid mouse movement in sloppy and mouse focus modes - (partially fixes #152000) - - * src/window.c (meta_window_free): Don't increment the focus - sentinel for windows being freed, (idle_calc_showing): don't - increment the focus sentinel for windows being minimized - -2004-09-15 Elijah Newren - - Fix unwanted loss of focus to the mouse window when using keynav - (fixes #101190) - - * src/display.c (event_callback): Ignore EnterNotify events with - xcrossing.mode of either NotifyGrab or NotifyUngrab - -2004-09-15 Elijah Newren - - Focus correct window after minimizing via the tasklist (fixes - #128200; see also #107681) - - * src/display.h (struct _MetaDisplay): track the - previously_focused_window - - * src/display.c (meta_display_open): initialize - previously_focused_window - - * src/window.c (meta_window_free): clear the - previously_focused_window if it's being freed, - (meta_window_client_message): if we get a request to minimize the - previously_focused_window and the focus_window is a dock or the - desktop, focus the default window, (meta_window_notify_focus): - update the previously_focused_window - -2004-09-13 Rob Adams - - * configure.in: post-release increment - -2004-09-13 Rob Adams - - * configure.in: bump version number - - * NEWS: 2.8.5 release - - * README: 2.8.5 release - -2004-09-14 Gora Mohanty - - * configure.in: Added 'or' to ALL_LINGUAS. - -2004-09-07 Elijah Newren - - Add a new write-up on making window focus consistent (see #152004) - - * doc/how-to-get-focus-right.txt: New document - - * rationales.txt: Remove references to focus bugs, instead point - to doc/how-to-get-focus-right.txt - -2004-09-06 Elijah Newren - - * rationales.txt: Add bugs regarding window focus - -2004-08-29 Elijah Newren - - * NEWS: 2.8.4 release - -2004-08-29 Elijah Newren - - * src/window.c (window_takes_focus_on_map): Disable - focus-stealing-prevention for now; there are still some issues and - hard code freeze is tomorrow...so this will have to wait until - Gnome 2.10. - -2004-08-27 Havoc Pennington - - * src/compositor.c (meta_compositor_new): disable NameWindowPixmap - stuff always for now, it seemed kind of busted - (paint_screen): don't grab the server during repaint, adds to the - speed, though only slightly. - - * src/frames.c (meta_frames_set_window_background): factor out all - the set_background stuff to one function; disable setting - background to transparent, because it breaks existing themes. We - need to add a flag in the theme XML file to say "start me with a - transparent background" - -2004-08-27 Elijah Newren - - Prevent an assertion failure that can occur after increasing the - number of workspaces; also fix a warning and stacking order when a - window is denied focus (fixes #150615) - - * src/window.c (meta_window_stack_just_below): the position of the - window should be set equal to that of the one we want to be below, - not 1 lower than that number - - * src/workspace.c (maybe_add_to_list): new function to add - on_all_workspace windows to an mru_list, (meta_workspace_new): - call maybe_add_to_list for all windows on the screen in order to - initialize the mru_list - -2004-08-26 Havoc Pennington - - * src/frame.c: delete extra copy of find_argb_visual so things - compile - - * src/compositor.c (HAS_NAME_WINDOW_PIXMAP): copy the - XCompositeNameWindowPixmap() stuff from xcompmgr, though I can't - say I really know what it's supposed to help with (painting the - window border?) - -2004-08-26 Havoc Pennington - - * src/frame.c, src/theme.c: couple of cosmetic tweaks from - resolving my local patch with the bugzilla patch from the 8-19 - entry below - -2004-08-26 Havoc Pennington - - * configure.in: move the have_xrender variable initialization up - in the file since it can be set as part of composite check - -2004-08-19 Havoc Pennington - - Fixes from Rich Wareham - - * src/display.h (struct _MetaDisplay): add render extension check - to the display - - * src/display.c: check for render - - * configure.in: don't build compositing manager by default, don't - want any nasty surprises; check for render separately from - compositing manager - - * src/frame.c: use an ARGB visual when available for the window - frame, so we can be all cool-ass - -2004-08-25 Elijah Newren - - Make dialogs that Metacity shows follow focus-stealing-prevention - conventions. (fixes one issue in #149028; see comments 47-54) - - * src/delete.c (delete_ping_reply_func, - delete_ping_timeout_func): Make callback functions take a - timestamp arg, (delete_ping_timeout_func): pass the timestamp to - metacity-dialog - - * src/display.c (meta_display_ping_timeout): add a timestamp to - the call to the ping_timeout_func, (meta_display_ping_window, - process_pong_message): add a timestamp to the call to the - ping_reply_func - - * src/display.h (MetaWindowPingFunc typedef): add a timestamp to - this function typedef - - * src/keybindings.c (error_on_command): require a timestamp and - pass the timestamp on to metacity-dialog, (handle_run_command): - pass a timestamp to error_on_command - - * src/metacity-dialog.c (copy_of_gdk_x11_window_set_user_time): - new function (temporary; only for use while using gtk+-2.4), - (kill_window_question, warn_about_no_sm_support, - error_about_command): make these functions take a timestamp and - call copy_of_gdk_x11_window_set_user_time, (main): require the - first two args to the program to be "--timestamp " - - * src/session.c (warn_about_lame_clients_and_finish_inter): pass a - timestamp of 0 to metacity-dialog to prevent focus (it's a popup - not generated by and kind of user request). - -Fri Aug 20 12:54:12 2004 Soeren Sandmann - - * src/display.c (meta_display_end_grab_op): Move wireframe code - before grab is released to prevent endless loops with fullscreen - windows. - -2004-08-18 Havoc Pennington - - * src/display.h (struct _MetaDisplay): track the last_xor_rect - separately from the current window size, and then use that to - paint the wireframe including the frame, and taking into - account shaded windows. - - * src/window.c (meta_window_get_xor_rect): new function to compute - the xor rect; it is not really 100% right, because it uses the - frame dimensions from the window at the start of the move/resize. - But probably won't break in practice. - -2004-08-17 Christian Rose - - * configure.in: Added "bs" to ALL_LINGUAS. - -2004-08-16 Kjartan Maraas - - * configure.in: Added nb to ALL_LINGUAS. - -2004-08-15 Rob Adams - - * configure.in: Bump version to 2.8.4 - -2004-08-15 Rob Adams - - * NEWS: 2.8.3 release - -2004-08-15 Rob Adams - - * src/windows.c (meta_window_update_struts): use height and - top/bottom struts to compute gap (copy/paste bug). - -2004-08-15 Rob Adams - - * src/window.c (meta_window_update_struts): Allow struts larger - than 1/2 the screen width/height, as long as there's a minimum - sized gap between them. Patch from Bill Haneman - for bug #144126. - -2004-08-13 Gurban M. Tewekgeli - * po/tk.po: Added Turkmen translation. - * configure.in: Added "tk" to ALL_LINGUAS. - -Mon Aug 9 05:38:33 2004 Soeren Sandmann - - * src/effects.c (graphics_sync): New function. - * src/effects.c (effects_draw_box_animation_timeout): Use it here - to synchronize with the hardware between each frame. - -2004-08-08 Rob Adams - - * src/window.c (meta_window_move_resize_internal): Add #ifdef - around XSYNC code; fixes compile problem if XSYNC is disabled. - Path for #149314 from Peter O'Shea and independently Mike Castle. - -Sun Aug 8 14:20:00 2004 Soeren Sandmann - - * src/frame.c (meta_frame_set_screen_cursor): Flush after setting - cursor. (Rest of #149413). - -2004-08-07 Elijah Newren - - * src/display.c (event_callback): activating the current workspace - should be a no-op. This prevents a race condition in focus window - choice when activating a window via the taskbar. Fix for #149589. - -2004-08-07 Elijah Newren - - * src/window.c, src/window.h: Revert Rob's 2004-07-31 patch that - ignored net_wm_user_time when unminimizing a window - - * src/window.c (meta_window_activate): If a nonzero timestamp is - passed, update the window's net_wm_user_time accordingly. (see - comments 102-108 of bug 118372) - -2004-08-07 Rob Adams - - Remove some extraneous items that could sometimes appear in the - window menu. Fix for #144493. - - * src/menu.c (menuitems): Change the second separator to key on - whether there are any workspaces. - (meta_window_menu_new): use NULL label instead of 0 op to identify - separator - - * src/window.c (meta_window_show_menu): Change the conditions on - the directions to take into account "holes" in the workspace - layout and also only set META_MENU_OP_WORKSPACES when there's more - than one workspace. - -2004-08-07 Havoc Pennington - - * src/screen.c (meta_screen_set_cursor): add XFlush() after - setting cursor, #149413 - -2004-08-06 Elijah Newren - - * src/display.c (event_callback): Focusing a window upon unshowing - the desktop in various ways (panel applet or keybinding) was - inconsistent for sloppy and click focus modes. Fix this by - calling meta_workspace_focus_default_window after unshowing the - desktop via a _NET_SHOWING_DESKTOP message. (resolves #149543) - -2004-08-06 Elijah Newren - - * src/workspace.c (meta_workspace_focus_default_window): prevent - keyboard from "getting locked" upon workspace switch, by making - sure that the no_focus_window has focus if no other window does. - (fixes #147475) - -2004-08-05 Elijah Newren - - Have newly mapped windows that are denied focus appear after the - focused window in the alt-tab list. This allows one to switch to - such a window with a single alt-tab press. (fixes #149366) - - * src/window.c (ensure_mru_position_after): new function, - (meta_window_show): If newly mapped window is denied focus, call - ensure_mru_position_after to make the window appear after the - focus window in the mru list. - -2004-08-05 Elijah Newren - - * src/window.c (meta_window_stick): prepend window to mru list - instead of appending, since making the window sticky should imply - that it is the most recently used, not the least recently. (fixes - #149369) - -2004-08-04 Elijah Newren - - * configure.in: post-release version bump (2.8.3) that I forgot to - do yesterday. - -2004-08-03 Elijah Newren - - Released 2.8.2 - - * NEWS, README: update - -2004-08-02 Elijah Newren - - Fix some bugs (reported in #120100) regarding the focus window - when using the workspace switcher. - - * src/display.c (event_callback): When switching workspaces due to - a _NET_CURRENT_DESKTOP message, make sure to focus the default - window as well. - - * src/workspace.c (meta_workspace_focus_default_window, - meta_workspace_focus_mru_window): Make DOCK or DESKTOP windows - have lower priority than others when choosing a window to focus. - (For the former function, this means don't focus them at all; for - the latter, this means only focus them (via the - meta_workspace_focus_top_window call) if no other mru window can - be found.) - -2004-07-31 Rob Adams - - Fix bug that caused windows to not be focused on unminimizing - because of user time support. - - * src/window.c (meta_window_new_with_attrs): initialize - focus_despite_user_time bit - (window_takes_focus_on_map): focus if focus_despite_user_time - despite user time, interestingly enough - (meta_window_show): reset focus_despite_user_time after showing - - * src/window.h (_MetaWindow): add focus_despite_user_time bit - -2004-07-31 Rob Adams - - Fix some support for EWMH hints, and fix USER_TIME support to - include the DEMANDS_ATTENTION hint. Also includes some code for - implementing _NET_RESTACK_WINDOW and _NET_MOVERESIZE_WINDOW, but - this is disabled pending feature thaw. - - * COMPLIANCE: update with new information - - * src/display.c (meta_display_open): add new hints to list - - * src/display.h (_MetaDisplay): Add new atoms to struct - - * src/screen.c (set_supported_hint): update the list of support - hints. - (set_desktop_viewport_hint): new function sets the viewport hint - to (0,0) as required by the spec for WMs with no viewport support. - (set_desktop_geometry_hint): new function to set the desktop size - hint to the size of the display, since we don't implement large - desktop support, as required by the spec. - (meta_screen_resize): update the geometry hint on screen resize - - * src/window.c (meta_window_new_with_attrs): Initialize - demands_attention state - (set_net_wm_state): Set demands_attention hint in the window state - (meta_window_show): If we don't pop up a window because of - USER_TIME, set DEMANDS_ATTENTION on the window. - (meta_window_focus): When a window receives focus, remove - DEMANDS_ATTENTION hint - (meta_window_client_message): Allow other apps to set - DEMANDS_ATTENTION on a window. Also, if the _NET_ACTIVE_WINDOW - hint includes a timestamp, use it. - (update_net_wm_state): Read DEMANDS_ATTENTION state also - - * src/window.h (_MetaWindow): add wm_state_demands_attention bit. - -2004-07-22 Rob Adams - - * src/metacity.schemas.in: Add trailing quotes to keybinding - explanation text. Patch from Emil Soleyman-Zomalan. - -Fri Jun 25 17:41:53 2004 Soeren Sandmann - - * configure.in: Require startup-notification 0.7 - -2004-06-25 Rob Adams - - * COMPLIANCE: indicate that _NET_WM_USER_TIME is now supported - -2004-06-24 Elijah Newren - - * src/keybindings.c: (handle_toggle_desktop): Choose correct - window to focus when "un-showing" the desktop. Fixes #144900. - -2004-06-24 Elijah Newren - - Make choice of focus window be consistent for each focus mode. - Fixes #135810. - - * src/delete.c: (meta_window_delete): In some #if 0'ed code, - replace meta_workspace_focus_mru_window with - meta_workspace_focus_default_window (just in case the code becomes - un-#if 0'ed out). - - * src/screen.c, src/screen.h: Change - meta_screen_focus_mouse_window to meta_screen_get_mouse_window, - and don't focus the window when found but rather return it. - - * src/window.c: (meta_window_free, meta_window_minimize): replace - meta_workspace_focus_mru_window with - meta_workspace_focus_default_window. - - * src/workspace.c: (meta_workspace_focus_default_window): Focus - appropriately for the given focus method: - click-to-focus: focus MRU window (== toplevel window) - sloppy focus: focus the window under the pointer if there is - such a window, otherwise focus the mru window - mouse focus: focus the window under the pointer if there is - such a window, otherwise don't focus anything - -2004-06-24 Elijah Newren - - * src/window.c: Avoid a race condition on the choice of window to - focus after the previously focused window gets closed or - minimized. Fixes #131582. - -2004-06-24 Elijah Newren - - * src/metacity.schemas.in: make naming for "move a window"/"move - the window"/"move window" more consistent. Patch from Michael - Terry for #142235. - -2004-06-24 Elijah Newren - - * src/session.c: Change meta_warning to meta_topic on failure to - connect to a session manager. Fixes #136218. - -2004-06-17 Elijah Newren - - Add support for _NET_WM_USER_TIME - - * src/display.c: - (meta_display_open): Add _NET_WM_USER_TIME to atom_names[], - (event_callback): Manually set _NET_WM_USER_TIME upon KeyPress - (doesn't work since keyboard isn't grabbed) and ButtonPress (does - work), this is just a fallback for applications that don't update - this themselves. - - * src/display.h: (struct _MetaDisplay): Add atom_net_wm_user_time field - - * src/screen.c: (meta_screen_apply_startup_properties): Check for - TIMESTAMP provided from startup sequence as well. - - * src/stack.c: - s/meta_window_set_stack_position/meta_window_set_stack_position_no_sync/, - (meta_window_set_stack_position): New function which calls the - meta_window_set_stack_position_no_sync function followed immediately - by calling meta_stack_sync_to_server. - - * src/window-props.c: - (init_net_wm_user_time), (reload_net_wm_user_time): new functions, - (reload_wm_hints): also load atom_net_wm_user_time - - * src/window.c: - new XSERVER_TIME_IS_LATER macro (accounts for timestamp wraparound), - (meta_window_new_with_attrs): add timestamp attributes, - (window_takes_focus_on_map): use TIMESTAMP from startup - notification and _NET_WM_USER_TIME to decide whether to focus new - windows, - (meta_window_show): if app doesn't take focus on map, place it - just below the focused window in the stack - (process_property_notify): check for changes to _NET_WM_USRE_TIME, - (meta_window_stack_just_below): new function - - * src/window.h: - (_MetaWindow struct): new fields for initial_timestamp, - initial_timestamp_set, net_wm_user_time_set, and net_wm_user_time, - (meta_window_stack_just_below): new function - -2004-06-21 Anders Carlsson - - * src/common.h: - * src/menu.c: (menu_closed), (activate_cb): - * src/window.c: (menu_callback): - Add a timestamp argument to menu functions and - use it in meta_window_delete. - -2004-06-21 Anders Carlsson - - * src/window.c: (meta_window_client_message): - Get the timestamp from the client message. - -Sat Jun 19 02:21:08 2004 Soeren Sandmann - - Fix bug 143333, support for update counter spec, and 109362, - schedule compensation events when events are ignored. - - * src/display.c (meta_display_open): Add _NET_WM_SYNC_REQUEST and - _NET_WM_SYNC_REQUEST_COUNTER atoms. Remove the old - METACITY_SYNC_COUNTER stuff. - (meta_display_begin_op): Setup the sync counter - - * src/xprops.c, src/xprops.h, src/window-props.c, src/display.h: - Add new atoms. - - * src/window.c (send_sync_request): new function. - (meta_window_move_resize_internal): send a sync request before - resizing. - (check_move_resize_frequence): Rework logic to also check the SYNC - case. If an event is ignored return the remaining time. - (update_resize_timeout): Timeout that gets called when a - compensation event is scheduled. - (uddate_resize): schedule compensation events when an event is - ignored. - (meta_window_handle_mouse_grap_op_event): When an alarm is - received and sync was turned off, turn it back on. - - * src/window.h (struct MetaWindow) Add some variables - -2004-06-16 Havoc Pennington - - * configure.in: bump version, add the UNSTABLE note - - * Branch off GNOME 2.6, we are now officially unstable - -2004-06-04 Jeff Waugh - - * src/metacity.schemas.in: Set titlebar_uses_system_font = false. The - previous default was almost violent in its lack of appreciation for - human beings. In fact, this entire setting should probably be removed, but - for now, let's just fix the default. Permission granted by Havoc. - -2004-05-04 Elijah Newren - - * configure.in: 2.8.1 - - * NEWS: update - -2004-05-02 Rob Adams - - * src/metacity-dialog.c (warn_about_no_sm_support): make the no sm - support warning dialog resizable, since the default GTK warning - dialog not has default not resizable. Fix for #141672 from - Olivier Crete. - -2004-04-29 Rob Adams - - * src/prefs.c (change_notify): Add a value type check for the - visual bell/audible bell gconf settings. Patch from Jarrod - Johnson for #141409. - -2004-04-19 Mark McLoughlin - - Syncing across this change from libwnck. - Patch from Neil Muller in bug #133979. - - * src/iconcache.c: (find_largest_sizes), (find_best_size): - Don't down-size nitems from a gulong to an int. Fixes a - crash with enlightenment, apparently. - -2004-04-16 Iñaki Larrañaga - - * configure.in: Added "eu" (Basque) to ALL_LINGUAS. - -2004-04-15 Elijah Newren - - * src/display.c: Prevent unwanted grab op from occurring. - Previously, for some people under certain conditions, clicking and - releasing the mouse button rapidly enough would result in Metacity - starting a move operation due to ignoring the button release. - This should fix that problem (it does for me). See bug 136587. - -2004-04-11 Rob Adams - - * configure.in: Make the --enable-xinerama switch work properly. - Fix for #138562 from foser@gentoo.org. - -2004-04-09 Guntupalli Karunakar - - * configure.in: Added "gu" (Gujarati) to ALL_LINGUAS. - -2004-03-27 Tõivo Leedjärv - - * configure.in: Added et to ALL_LINGUAS. - -2004-03-24 Guntupalli Karunakar - - * configure.in: Added "pa" (Punjabi) to ALL_LINGUAS. - -2004-03-21 Havoc Pennington - - * configure.in: 2.8.0 - - * NEWS: update - -2004-03-07 Elijah Newren - - * rationales.txt: Bring up to date (see bug 136252). - -2004-03-07 Havoc Pennington - - * configure.in: 2.7.1 - -2004-03-04 Paisa Seeluangsawat - - * configure.in: Added "th" (Thai) to ALL_LINGUAS. - -2004-03-01 Rob Adams - - * src/stack.c (compute_layer): don't promote due to transiency; we - handle that elsewhere now. - (ensure_above): perform layer promotion here as well as stack - position promotion. Note that this means that we need to do stack - constraints now on layer change now. - (get_maximum_layer_of_ancestor): remove function - (max_layer_func): remove function - (MaxLayerData): remove struct - -2004-02-28 Rob Adams - - Revert 2/27 patch for layer promotion. - -2004-02-27 Rob Adams - - * src/window.c (meta_window_notify_focus): only move on MRU list - if the window belongs on the workspace, since the FocusIn event - could be for a window whose workspace we've since switched away - from. Possible fix for #122016. - - * src/workspace.c (meta_workspace_contains_window): search for the - workspace in window->workspaces rather than the window in - workspace->windows. Since the number of workspaces is at most 36, - this is a O(1) lookup rather than a O(n) lookup. Sorry; couldn't - resist. - -2004-02-27 Rob Adams - - * src/metacity.schemas.in: Change - move_to_workspace_left/right/up/down keybindings to - arrow to avoid conflicting with new - keybindings in spacial nautilus. - -2004-02-27 Rob Adams - - Handle layer promotion of transient descendants of layer-promoted - windows to also be layer promoted, using a simple iterative - algorithm. - - * src/stack.c (compute_layer): change name to promote_layer, and - convert to simply perform any necessary layer promotion without - computing the standalone layer. - (max_layer_func): use window->layer instead of - get_standalone_layer - (get_maximum_layer_of_ancestor): use window->layer instead of - get_standalone_layer - (meta_stack_ensure_sorted): implement iterative algorithm, - explained in a long comment. - - * src/window.h: add a tmp_layer field used by stack.c for - determining if the stack is dirty or not, since maintaining this - information in meta_stack_ensure_sorted is no longer practical. - -2004-02-23 Rob Adams - - Add my copyright notice to a number of files on which it should - already exist. - - * src/window.c (meta_window_notify_focus): modify code to move to - front of MRU list so that we can have an assert that it was there - in the first place. This code may be causing some crashes. See - #131196. - -2004-02-22 Christian Rose - - * configure.in: Added "en_CA" to ALL_LINGUAS. - -2004-02-19 Rob Adams - - * src/prefs.h: remove trailing comma in MetaKeyBindingAction enum. - Fix for #134868 thanks to bugzilla-gnome@thewrittenword.com. - -2004-02-16 Rob Adams - - * src/window.c (update_move): reset drag state after shaking loose - or reattaching. Fix for #132625. - -2004-02-15 Anders Carlsson - - * src/menu.c (meta_window_menu_new): Actually translate a message, - don't just mark it for translation. - -2004-02-14 Elijah Newren - - * src/workspace.c: When moving a window to a different workspace, - prepend it to the mru list insted of appending it. Fixes #134368. - -2004-02-14 Rob Adams - - If we're moving a window and receive a _NET_CURRENT_DESKTOP - message indicating a workspace switch, bring along the drag window - to the new workspace, solving a potentially weird bug where the - window would be lost on the old workspace. This also makes it - possible to implement edge flipping in an external program with - just a few lines of code. Patch for #131630 from ed@catmur.co.uk. - - * src/keybindings.c (switch_to_workspace): remove function -- no - longer needed. - (handle_activate_workspace): call meta_workspace_activate instead - of switch_to_workspace - - * src/workspace.c (meta_workspace_activate_with_focus): if we're - in a move grab op, bring along the drag window. - -2004-02-14 Rob Adams - - * configure.in: Add configure option to not even try using - xinerama, to make metacity buildable on systems with no shared - library version of the xinerama libraries. Patch for #134203 from - Julio M. Merino Vidal. - -2004-02-01 Rob Adams - - * COMPLIANCE: Bring up to date with current draft EWHM. - -2004-01-27 James M. Cape - - * src/themes/Esco/metacity-theme-1.xml: Use the 'utility' frame - for dialogs too. - -2004-01-24 James M. Cape - - * src/themes/Esco/metacity-theme-1.xml: Updated this theme. - -2004-01-21 Elijah Newren - - * src/screen.c (set_supported_hint): Removed some duplicate - entries. - -2004-01-17 Rob Adams - - * src/metacity.schemas.in: Default binding removed for - toggle_shaded, since we don't have anything in the graphical UI - for it any more. - -2004-01-17 Rob Adams - - * src/window.c (meta_window_show_menu): Don't show - left/right/up/down if a window is sticky. Make "On Top" - insensitive for docks, splash screens, and desktops since it has - no effect anyway. - -2004-01-10 Rob Adams - - * src/metacity.schemas.in: update default - action_double_click_titlebar to be toggle_maximize instead of - toggle_shade. See #131126. - -2004-01-10 Rob Adams - - * src/constraints.c (meta_window_constrain): if we maximize after - placement, and the window is too big to fix in the work area, - define a sane saved_rect approximately with dimensions - three-quarters approximately three quarters the size of the work - area. This avoids the problem where large windows would - unmaximize and actually get bigger. See #93590. - -2004-01-09 Thomas Fitzsimmons - - Add _NET_FRAME_EXTENTS and _NET_REQUEST_FRAME_EXTENTS. - - * src/display.c: include xprops.h - (process_request_frame_extents): new function - (meta_display_open): add _NET_FRAME_EXTENTS and - _NET_REQUEST_FRAME_EXTENTS atoms - (event_callback): handle frame extents message - - * src/display.h (struct _MetaDisplay): add atom_net_frame_extents - and atom_net_request_frame_extents - - * src/theme.c (meta_pango_font_desc_get_text_height): make font_desc - parameter const - - * src/ui.c: include prefs.h - (meta_ui_theme_get_frame_borders): new function - - * src/window.c (update_net_frame_extents): new function - (meta_window_move_resize_internal): update frame extents - property when frame geometry changes - - * src/screen.c (set_supported_hint): add atom_net_frame_extents - and atom_net_request_frame_extents - -2004-01-09 Calum Benson - - * src/themes/Atlanta/metacity-theme-1.xml: - - Ensure Atlanta window buttons get larger when using large - print themes. Fixes #123469. - -2003-01-04 Rob Adams - - Maintain the button grab for sloppy and mouse focus all the time. - This fixes a number of problem introduced by trying to drop the - grab; we now do this only for click to focus mode. This has the - unfortunate effect that #102209 reappears for sloppy and mouse - focus, but this seems unavoidable, because of limitations in the X - protocol. See #115072. - - * src/display.c (meta_display_grab_focus_window_button): #if 0 the - section on not grabbing unless in click-to-focus mode. - - * src/window.c (meta_window_notify_focus): drop focus button grab - on FocusIn and acquire it on FocusOut only when in click-to-focus - mode. - -2004-01-03 Robert Sedak - - * configure.in: Added "hr" in ALL_LINGUAS. - -2003-01-02 Rob Adams - - * README: Update reference to EWMH. - - * HACKING: Add a reference to COMPLIANCE and to the ICCCM and - EWHM. - -2003-12-25 Havoc Pennington - - * src/compositor.c (process_reparent): handle ReparentNotify, and - add a lot of debug output. - -2003-12-25 Havoc Pennington - - * src/compositor.c (meta_compositor_process_event): change to - track all children of the root window, not only mapped children; - this keeps us from losing track of the stacking order - - * src/display.c (event_callback): don't do any of the compositor - event handling inline, do it all in compositor.c - -2003-12-21 Rob Adams - - Reorganize the window menu according to discussion on #110904. - The workspace name mnemonic chunk of the patch is thanks to - Jonathan Blandford. - - * src/common.h: add MENU_OP_ABOVE, MENU_OP_UNABOVE, MENU_UP_MOVE_TO_* - menu ops. - - * src/core.c (meta_core_get_menu_accelerator): add accelerator for - the new menu ops. - - * src/menu.c: add checked attribute in _MenuItem struct to display - a checkmark next to a menu item. Add the new menu items to - menuitems. - (get_workspace_name_with_accel): Add mnemonics even to renamed - workspaces. - (menu_item_new): provide support for the checked attribute - (meta_window_menu_new): construct new submenu for workspace - switching. - - * src/window.c (menu_callback): implement support for the new menu - ops. - (meta_window_show_menu): don't use the OP_*SHAPE operations, and - compute which of the OP_MOVE_TO_* ops should be used for the - current workspace and workspace layout. Add the OP_*ABOVE - operations. - -2003-12-20 Arafat Medini - - * configure.in: Added Arabic locale "ar" to ALL_LINGUAS - -2003-12-17 Rob Adams - - * src/display.c (meta_display_open): initialize - grab_wireframe_active to FALSE. Fix for #128090. - -2003-12-17 Rob Adams - - * src/tabpopup.c (meta_ui_tab_popup_new): Don't try to call - utf8_strndup on a null title for an entry. Fix for #128566. - - * src/workspace.c (meta_workspace_free): Call g_list_free on the - mru_list, since with sticky windows that MRU list could well not - be emtpy. See #122016. - -2003-12-13 Rob Adams - - * src/window.c (meta_window_new_with_attrs): set on_all_workspaces - in all cases _before_ adding to the workspaces, so that windows - initially on all workspaces are added correctly to the MRU lists. - Fix for #120907. - - * src/workspace.c (meta_workspace_add_window): handle sticky - windows so that we add to add mru lists if needed - (meta_workspace_remove_window): handle sticky windows so that they - are removed from all mru lists if needed. - -2003-12-12 Havoc Pennington - - * src/window.c (meta_window_free): unstick window to get it out of - mru_list it should not be in; assert that window has been removed - from all mru_list. Perhaps fixes #122016 crash. - -2003-11-29 Havoc Pennington - - * fix up compositing manager to somewhat work - -2003-11-26 Rob Adams - - * COMPLIANCE: fix a couple of minor typos. - -2003-11-24 Havoc Pennington - - * src/compositor.c (meta_compositor_new): fix the extension checks - -2003-11-24 Havoc Pennington - - * src/iconcache.c (meta_icon_cache_init): init prev_mask field - - * src/window.c (meta_window_new_with_attrs): init xgroup_leader - prior to use - -2003-11-24 Havoc Pennington - - * src/display.c (meta_display_begin_grab_op): add an event_serial - argument and use it when the pointer is already grabbed - automatically on the button press. May fix bug #126871 - -2003-11-24 Havoc Pennington - - * Apply patch from Gregory Merchan to avoid using CurrentTime when - setting input focus. Bug #108881 - -2003-11-23 Havoc Pennington - - * src/compositor.c: move xcompmgr code in here (minus drop - shadows), untested since Keith's server just crashes at the - moment. "It compiles" - -2003-11-20 Havoc Pennington - - * src/window.c (meta_window_new_with_attrs): new function - - * src/display.c, src/screen.c: create the compositor and feed - windows and events to it - -2003-11-20 Havoc Pennington - - * src/window.c (meta_window_notify_focus): revert the change here - -2003-11-17 Rob Adams - - Create COMPLIANCE document describing metacity specification - compliance. Right now gives detailed EWMH compliance; still need - to add ICCCM compliance information. Also some minor fixes to - bring metacity into compliance on some points. - - * COMPLIANCE: new file - - * src/display.h, src/display.c (meta_display_open), - src/screen.c (set_supported_hint): add - atom_net_wm_action_fullscreen and atom_net_wm_action_minimize - - * src/window.c (set_allowed_actions_hint): some fixes to which - hints to set and add fullscreen and minimize. - -2003-11-16 Rob Adams - - * src/window.c (meta_window_notify_focus): add paranoia check to - make sure a window is really on a workspace before inserting it at - the beginning of the MRU list. Maybe there's a race condition - with focusing and workspace switching. Hopefully a fix for - #122016. - -2003-11-15 Havoc Pennington - - * src/main.c (main): fix warning - - * src/compositor.c: add a new file to contain compositing manager - functionality; not yet implemented at all. - -2003-11-15 Rob Adams - - Inherit visual from frame window so that metacity will work with - the new compositing manager extension work by Keith on - freedesktop.org, so that ARGB windows can be full - alpha-transparent without a metacity frame getting drawn in the - background. In the long term, we need to actually set alpha - values when drawing the frame so that it will really work; this is - a stopgap solution. Patch from Keith Packard; see Bug 126875. - - * src/frame.c (meta_window_ensure_frame): pass client visual to - frame. - - * src/ui.[ch] (meta_ui_create_frame_window): add new xvisual - parameter and use it to create new window. - -2003-11-15 Rob Adams - - * src/window.c (update_net_wm_type): don't set window->type_atom - here so that the type-inference code will actually be called. Fix - for #126873 from Keith Packard. - -2003-11-08 Rob Adams - - * src/window.c (meta_window_move_resize_internal): configure frame - first if we grow more than we shrink combined in both dimensions. - Patch from Soren Sandmann for #108925. - -2003-11-07 Rob Adams - - * src/place.c (meta_window_place): use maximize_after_placement to - automaximize in meta_window_place; avoids a problem with not - recalculating the frame geometry after auto-maximizing. - -2003-11-07 Rob Adams - - * src/window.c (window_should_be_showing): show the window if it's - a transient of a dock or desktop, since otherwise such windows are - invisible in show desktop mode. Fix for #124648. - -2003-11-07 Rob Adams - - * src/main.c (main): Try harder to find a theme in the event that - the theme in the preference cannot be found. Patch from Marcin - Krzyzanowski. See #125815. - - * src/place.c (meta_window_place): use "visual" centering for - dialog placement and clip new dialogs to an xinerama workspace. - Fix for #118336. - -2003-10-30 Havoc Pennington - - * src/menu.c (meta_window_menu_new): patch to avoid creating - stick/unstick menu items when only one workspace, bug #116563 - from Michael Terry - -2003-10-25 Havoc Pennington - - * src/window.c (meta_window_notify_focus): if a window is focused - which is not either a dock or a transient in the same group as a - dock, shuffle all dock/desktop windows to the end of the MRU list - so they won't annoyingly get focus all the time. #123816 - -2003-10-15 Yukihiro Nakai - - Gettextize metacity-theme-viewer. #121747 - - * src/theme-viewer.c: gettextize. - * po/POTFILES.in: Add src/theme-viewer.c - -2003-10-13 Havoc Pennington - - In the "prefs cause code complexity" department, here's a "sloppy - focus die die die" kind of moment. - - * src/display.c (meta_display_grab_focus_window_button): don't - grab in sloppy focus mode, since we were dropping the grab on - window enter anyway this just removes races from the current - behavior. - - * src/display.c (prefs_changed_callback): ungrab/grab on focus - mode changes, since we treat sloppy and click differently. - -2003-10-12 Havoc Pennington - - Merge reduced_resources mode patch from the branch. Offers - wireframe and no-animations. - - * src/window.c (implement_showing): no animation if we are - in reduced resources mode - - * src/prefs.c: add REDUCED_RESOURCES pref - - * src/window.c (meta_window_update_keyboard_resize): fix to - modify grab_anchor_window_pos to grab_wireframe_rect if - appropriate instead of window->rect - - * src/display.h (struct _MetaDisplay): add grab_start_serial used - to avoid responding to events that occurred prior to the grab - initialization. - - Still broken in various ways, specifically EnterNotify that - occurred prior to XGrabPointer is processed as if it occurred - after. - - * src/window.c (meta_window_update_keyboard_move): add this - instead of meta_window_warp_pointer() crack - - * src/effects.c (meta_effects_update_wireframe): draw a kind of - grid for the wireframe, instead of just a rectangle, like twm - - * src/screen.c (meta_screen_new): line width of 3 for the XOR gc - - "Reduced resources" mode based on wireframe patch from - Erwann Chenede. Still pretty buggy. - - * src/keybindings.c (process_keyboard_move_grab) - (process_keyboard_resize_grab): add gruesome wireframe hacks - - * src/display.c (meta_display_end_grab_op): end wireframe - (meta_display_begin_grab_op): begin wireframe - - * src/effects.c (meta_effects_end_wireframe) - (meta_effects_update_wireframe, meta_effects_begin_wireframe): - routines to draw the wireframe stuff - - * src/window.c (window_should_be_showing): hide window when - doing wireframe, commented out as it breaks grab - * src/window.c (meta_window_refresh_resize_popup): handle wireframe - - * src/screen.c (meta_screen_new): create a screen->root_xor_gc - for use in drawing wireframes - - * src/frames.c (meta_frames_push_delay_exposes): repaint - everything before we delay - -2003-10-11 Havoc Pennington - - * src/display.c (meta_display_begin_grab_op): initialize - display->grab_have_pointer to FALSE, previously I think you could - get a case where we didn't have the grab and thought we did. - Bugs were reported with this happening. Of course we still have - the "why did the grab fail" problem, but it should be less - noticeable with this fixed. - -2003-10-06 Rob Adams - - * src/constraints.c (constraint_onscreen_*_func): disable onscreen - resize constraints for right, left, and bottom, since there is no - way to violate onscreen constraints by resizing in these - directions and the code to implement the constraints made some - incorrect assumptions. Fix for #120701, #120756, #123165, - #123631, #123838. - -2003-10-06 Žygimantas Beručka - - * configure.in: Added "lt" to ALL_LINGUAS - -2003-10-01 Havoc Pennington - - * NEWS: update - - * configure.in: 2.6.2 - -2003-09-30 Havoc Pennington - - * src/window.c (meta_window_queue_move_resize): add the moveresize - idle at META_PRIORITY_RESIZE so it runs before GTK does any - drawing, may fix bug #109211 (seems to for me) - - * src/ui.h (META_PRIORITY_RESIZE): add this between GTK - resize/redraw priorities - - * src/display.c (meta_display_queue_retheme_all_windows): remove - some debug spew from meta_warning - -2003-09-30 Havoc Pennington - - * src/testasyncgetprop.c: remove nonstandard header include, - #121870 - -2003-09-30 Havoc Pennington - - * src/tools/metacity-message.c (main): call - bind_textdomain_codeset(), fix from Yukihiro Nakai bug #121743 - -2003-07-28 Rached Ben Mustapha - - Fix bug #118428 - - * src/window.c (redraw_icon): Also redraw window icon if the window - is not mapped but its frame is. - (idle_update_icon): Unset the window->update_icon_queued flag. - -2003-09-29 Havoc Pennington - - * src/tabpopup.c (meta_ui_tab_popup_new): put a random cap on - number of characters in the title of each window, bug #109301 - -2003-09-29 Havoc Pennington - - * configure.in: put -lXext in Xrandr check, bug #115996 - -2003-09-29 Havoc Pennington - - * src/wm-tester/test-size-hints.c: a little program to test size - hints, for now just a 0x0 min size to verify bug #113320 - -2003-09-29 Havoc Pennington - - * src/async-getprop.c (async_get_property_handler): attempt to fix - this to return the data as an array of long even on 64-bit as with - XGetWindowProperty() breakage, bug #114035, credit to Gwenole - Beauchesne for tracking down. - -2003-09-29 Havoc Pennington - - * src/xprops.c (cvtINT16toInt): fix the 64-bit check not to use - macros from the X tree that don't get set - - * configure.in: check for sizes of various types - -2003-09-29 Havoc Pennington - - * src/delete.c (meta_window_delete): don't move the focus after - you click the close button on a window. bug #108706 - -2003-09-29 Havoc Pennington - - * src/main.c (find_accessibility_module): fix warnings (one was a - real bug) - - * src/ui.c (meta_gdk_pixbuf_get_from_pixmap): fix warning that - probably explains remaining crash on bug #116923. Jeez, need to - use -Werror here or something. - - Fix #103575, spawn child processes on proper screen. - - * src/keybindings.c (error_on_command): pass --screen to - metacity-dialog - (handle_run_command): launch user command with DISPLAY reflecting - the screen you launch it from - - * src/delete.c (delete_ping_timeout_func): pass --screen to - metacity-dialog - -2003-09-26 Havoc Pennington - - * src/display.c (event_callback): when focus on root window - becomes None, set it to something other than None so keybindings - keep working and print a warning about how some application sucks. - #84564 - (event_callback): Fix debug spew to print focus event details - properly - (meta_display_open): when setting initial focus, always use - RevertToPointerRoot and fix the focus if it's None or PointerRoot - -2003-09-26 Padraig O'Briain - - * src/Makefile.am: Add -DMETACITY_LIBDIR to support loading of modules - * src/main.c: Add functions find_accessibility_module, - accessibility_invoke_module and accessibility_invoke - (main); Check whether GConf accessibility key is true and if so - load accessibility modules. This code is based on the libgnome code. - - src/tabpopup.c (meta_ui_tab_popup_new): Set accessible role of - accessible for label containing window name to STATUSBAR so - AT can be aware of window name. - - This fixes bug #120025 - -2003-09-24 Havoc Pennington - - * src/session.c (io_from_warning_dialog): fix hang when we get - EOF, #121376 from Laurent Vivier - -2003-09-22 Taneem Ahmed - - * configure.in: Added "bn" to ALL_LINGUAS. - -2003-09-20 Åsmund Skjæveland - - * configure.in: Added Norwegian (nynorsk) translation code to - ALL_LINGUAS - -2003-09-20 Rob Adams - - Fix bug where multiple entries could appear in MRU lists, or no - entry when sticking/unsticking windows. Fix for #122016 - - * src/window.c (meta_window_stick): use window->screen->workspaces - instead of window->workspaces. - (meta_window_unstick): use window->screen->workspaces instead of - window->workspaces. - -2003-09-19 Rob Adams - - Fix a bug with partial-width panel struts caused by incorrect - computation of rectangle widths, and another when using different - screen resolutions on xineramas. See #122404. Also fix a crash - bug with the MRU list when sticking and unsticking windows. See - #120809. - - * src/constraints.c (get_outermost_onscreen_positions): Fix - off-by-one error with partial-width struts. - - * src/window.c (meta_window_update_struts): Fix off-by-one error - with partial-width struts. - (meta_window_stick): assign back to GList after g_list_append - (meta_window_unstick): assign back to GList after g_list_append - - * src/workspace.c (ensure_work_areas_validated): For right and - bottom struts, compute strut relative to root window and not to - xinerama edge in compliance with EWMH recommendations. - - -2003-09-17 Fatih Demir - - * configure.in: Added "ta" (Tamil) to the languages' list. - -Wed Sep 10 15:38:09 2003 Jonathan Blandford - - * configure.in: Rerelease 2.4.0.1 to fix glib-gettext problem. - -2003-09-08 Havoc Pennington - - * configure.in: remove "this is the unstable branch" warning - -2003-09-08 Havoc Pennington - - * configure.in: 2.6.0 - -2003-09-04 Havoc Pennington - - * configure.in: 2.5.5 - - * HACKING: add instructions on how to make a release - -2003-08-29 Rob Adams - - * src/ui.c (meta_gdk_pixbuf_get_from_pixmap): harden against null - return from gdk_pixmap_foreign_new. Fix for #116923. - -2003-08-26 Guntupalli Karunakar - - * configure.in: Added "hi" (Hindi) to ALL_LINGUAS. - -2003-08-20 Rob Adams - - Complete the transition to using the MRU window as the default - focus window instead of the topmost window; fixes a number of - problems with sloppy focus and utility windows. See #112031. - - * src/window.c (meta_window_free): call - meta_workspace_focus_mru_window - (meta_window_minimize): call meta_workspace_focus_mru_window - -2003-08-20 Rob Adams - - * src/constraints.c (meta_window_constrain): do northwest resize - when maximizing and fullscreening to avoid potential "off-by-one" - problems. - -2003-08-19 Rob Adams - - * src/stack.c (get_standalone_layer): put windows with - wm_state_below at the bottom. Make this higher priority than full - screen layer; see #120238. - -2003-08-18 Rob Adams - - * src/constraints.c (meta_window_constrain): recalculate frame - geometry if the window gets maximized after placement, since it's - likely to change. Fix for #120117. - -2003-08-17 Ray Strode - - * src/delete.c (meta_window_delete): Use MRU list to find focusing - window after a window is deleted instead of using top window. Fix - for #108643. - -2003-08-16 Havoc Pennington - - Patch from Soeren Sandmann #108926 to improve opaque resize - - * src/frame.c (meta_window_ensure_frame): new function - - * src/ui.c (meta_ui_create_frame_window): new function to create - a frame with GDK, so that GDK's invalidation etc. work properly - -2003-08-16 Havoc Pennington - - * src/display.c (xcursor_for_op): fix cursor for - META_GRAB_OP_MOVING, #111943 from John Paul Wallington - -2003-08-15 Rob Adams - - * src/constraints.c (meta_window_constrain): move to upper left - corner since we're resizing/moving instead of moving/resizing. - Fix for #119988. - -2003-08-15 Ray Strode - - Changed MRU list to be per workspace instead of per display, so - sticky windows don't hijack the window focus after workspace - switching (Bug #97635). - - * src/delete.c (meta_window_delete): Use - meta_workspace_focus_top_window instead of - meta_screen_focus_top_window. - - * src/display.c (meta_display_open): Stop using display->mru_list. - (find_tab_forward): - (find_tab_backward): - (meta_display_get_tab_list): Use workspace->mru_list instead of - display->mru_list and remove unneeded calls to - meta_window_visible_on_workspace - - * src/display.h: Remove mru_list from MetaDisplay - - * src/keybindings.c (handle_toggle_desktop): Use - meta_workspace_focus_top_window instead of - meta_screen_focus_top_window. - - * src/screen.c (meta_screen_focus_top_window): - (meta_screen_focus_default_window): Remove functions. - (meta_screen_show_desktop): Use meta_workspace_focus_top_window - instead of meta_screen_focus_top_window. - - * src/screen.h: Remove meta_screen_focus_top_window and - meta_screen_focus_default_window declarations. - - * src/window.c (meta_window_new): Stop using display->mru_list. - (meta_window_free): Use meta_workspace_focus_top_window - instead of meta_screen_focus_top_window and stop using - display->mru_list. - (meta_window_stick): Add sticky window to all workspace MRU lists. - (meta_window_unstick): Remove non-sticky window from the workspace - MRU lists it doesn't belong in. - (meta_window_notify_focus): Move newly focused window to the front - of active workspace's MRU list. - - * src/workspace.c (meta_workspace_new): Initialize - workspace->mru_list to NULL. - (meta_workspace_add_window): Add window to workspace's MRU list. - (meta_workspace_remove_window): Remove window from workspace's MRU - list. - (meta_workspace_activate_with_focus): Use - meta_workspace_focus_default_window instead of - meta_screen_focus_default_window. - (meta_workspace_focus_default_window): - (meta_workspace_focus_mru_window): - (meta_workspace_focus_top_window): Add functions. - - * src/workspace.h: Add mru_list to MetaWorkspace and add function - declarations for meta_workspace_focus_default_window, - meta_workspace_focus_mru_window, meta_workspace_focus_top_window. - -2003-08-14 Rob Adams - - Allow windows that are too tall for the workarea to break the - onscreen constraints just enough so that their bottom edges can be - made visible. Fix for #106740. Also, changes constraints to - constrain the resize and then the move to avoid complexities in - the code for the above fix. - - * src/constraints.c (get_outermost_onscreen_positions) - Compute the "effective" height of the work area and the minimum - size for the window to compute a value by which a window is - allowed to violate the top constraint. - (meta_window_constrain): convert to a resize then a move instead - of a move then resize. - -2003-08-13 Rob Adams - - * configure.in: remove metacity.spec from AC_OUTPUT - -2003-08-13 Havoc Pennington - - * metacity.spec.in: remove, nobody is maintaining it. - -2003-08-13 Laurent Dhima - - * configure.in: Added "sq" to ALL_LINGUAS. - -2003-08-10 Havoc Pennington - - * src/screen.c (meta_screen_new): don't select for button - press/release events, as that keeps other clients from doing so, - and it doesn't seem that metacity has any reason to do it. - Patch from Andreas Volz. - -2003-08-08 Bastien Nocera - - * src/metacity-dialog.c: (kill_window_question), - (warn_about_no_sm_support): fix markup being ignored when a window - title has a forbidden character in it (eg. "Send & Receive") - * src/tools/metacity-window-demo.c: fix warning - -2003-07-29 Arvind Samptur - - * src/xprops.c (utf8_list_from_results): Number of - strings we are processing is one more than required. - - Also get the string count right even without a null byte at the end. - Pointed out by Havoc. - -2003-07-27 Rob Adams - - * src/window.c (update_move): Update window shaking loose so that - the window is moved to the pointer and certain drag state is - properly restored once windows "reattach". Fix for #115000 based - on the patch by Jurg Billeter. - - * src/screen.c (meta_screen_resize): Invalidate work areas after - an xrandr screen size update. Fix for #117230. - - * src/stack.c (window_is_fullscreen_size): Check the bottom corner - of the window in addition to the top corner. Fix for #118194. - - * src/constraints.c (meta_window_constrain): Support aspect ratio - hints in the new constraints code. Fix for #113798. - - * src/tools/metacity-window-demo.c (toggle_aspect_ratio): toggle - the aspect ratio hints to force a 16:9 aspect ratio. - (do_appwindow): add a button to toggle aspect ratio. - -2003-07-27 Havoc Pennington - - * src/theme-viewer.c (run_theme_benchmark): also measure wall - clock time, and run over a number of window sizes. - -2003-07-15 Havoc Pennington - - * NEWS: update - - * configure.in: 2.5.3 - -2003-07-12 Pablo Saratxaga - - * configure.in: Added Walloon (wa) to ALL_LINGUAS - -2003-07-04 Havoc Pennington - - * Makefile.am (EXTRA_DIST): add rationales.txt - -2003-07-02 Jordi Mallach - - * src/metacity.desktop.in: Add X-GNOME-Bugzilla entries. - -2003-07-01 Padraig O'Briain - - * src/keybindings.c (process_tab_grab): Activate window before ending - grab. This fixes bug #114037. - -2003-06-20 Rob Adams - - * src/window.c (meta_window_unmaximize): Update grab state when we - unmaximize so double-clicking doesn't cause weird window-jumping - problems. See #116292. - -2003-06-29 Rob Adams - - * src/constraints.c (meta_window_constrain): Actually maximize - after placement. See #116285. - -2003-06-26 Havoc Pennington - - * src/workspace.c (meta_workspace_invalidate_work_area): nuke the - lists of struts here, to improve confidence that we never try to - use them after a window with rects in the list gets freed. - (it wasn't broken before I don't think, just making the - code more robust against future mods) - - * src/window.c (meta_window_update_struts): replace magic "75" - with a macro - - * src/constraints.c (constraint_hints_applies_func): don't apply - hints to maximized or fullscreen, rather than only fullscreen - (constrain_move): add paranoia max number of iterations to the - heuristic loop - -2003-06-26 Rob Adams - - Add keybinding to allow the user to toggle _NET_WM_STATE_ABOVE on - windows. Disabled by default. See #98387. - - * src/keybindings.c (handle_toggle_above): new function implements - the keybinding - - * src/metacity.schemas.in: add toggle_above keybinding - - * src/prefs.[ch]: add toggle_above keybinding - - * src/window.[ch] (meta_window_make_above): new function to put a - window into the above state - (meta_window_unmake_above): new function takes a window out of the - above state - -2003-06-26 Mohammad DAMT - - * po/id.po: Added Indonesian translation - * configure.in: Added "id" to ALL_LINGUAS - -2003-06-25 Rob Adams - - Update constraints code to support the new _NET_WM_STRUT_PARTIAL - EWMH draft specification. See #86682. Also, fix a bug involving - work area invalidation on metacity startup. Fix for #108497. - Finally, some minor fixes for full screen windows. - - * src/window.h: Add new MetaStruts structure to store strut rects - for a window. Remove has_struts and do_not_cover flag, and - support new MetaStruts instead of the four ints. - - * src/window.c (meta_window_new): change initialization to work - with new struts. Also, move meta_window_update_struts call to - after the workspaces are initialized to fix #108497. Remove - do_not_cover and related code. - (process_property_notify): add strut_partial - (update_struts): change function name to meta_window_update_struts - and expose in external MetaWindow API. Support partial width - struts and the new strut rects. - - * src/workspace.h: add new GSLists containing pointers to all - relevant struts for this workspace. - - * src/workspace.c (meta_workspace_new): initialize the list of - strut rects for this workspace. - (meta_workspace_free): free the strut rect lists - (ensure_work_areas_validated): support new struts and new strut - rect lists. Unleash the per-xinerama work areas. - - * src/constraints.c (get_outermost_onscreen_positions): Use the - current window position along with the new per-workspace strut - rects to compute the constraints that apply to a particular - window. - (constraint_hint_applies_func): don't do hints constraints on - fullscreen windows - (update_position_limits): for maximized windows use the work areas - to set the position limits; for other windows rely on the struts - constraints to be computed later in - get_outermost_onscreen_positions - (meta_window_constrain): don't apply aspect ratio hints to full - screen windows - - * src/display.c (meta_display_open): add _NET_WM_STRUT_PARTIAL atom - (meta_rectangle_equal): new helper function for MetaRectangles - (event_queue_callback): #ifndef out if USE_GDK_DISPLAY not set to - avoid compiler warning - - * src/display.h: add atom_net_wm_strut_partial, and add - meta_rectangle_equal. - - * src/screen.c (meta_screen_rect_intersects_xinerama): change - _window_intersects_ to _rect_intersects_ which is more useful now. - (meta_screen_resize_func): update struts on windows with struts - since struts are relative to the screen size, and this function is - called when the screen size updates. - - * src/screen.h (meta_screen_rect_intersects_xinerama): change - _window_intersects_ to _rect_intersects_ which is more useful now. - - * src/window-props.c (meta_display_init_window_prop_hooks): add - hook for strut_partial - - * src/tools/metacity-window-demo.c: Support partial-width struts - on the dock window tests for metacity testing purposes. - -2003-06-22 Samúel Jón Gunnarsson - - * configure.in: Added "is" to ALL_LINGUAS - -2003-06-12 Rob Adams - - * src/display.c (event_callback): Focus on mouse click in - sloppy/mouse to fix keynav. Fix for #115072. - -2003-06-12 Rob Adams - - * src/Makefile.am: honor --disable-schemas-install. Fix for - #106123 from Julio Merino - -2003-06-12 Rob Adams - - Remove legacy support for Gnome 1 hints, since we deem it unlikely - that anyone is running a current metacity with Gnome 1. The - removed hints are _WIN_WORKSPACE, _WIN_LAYER, _WIN_PROTOCOLS, - _WIN_SUPPORTING_WM_CHECK, and _WIN_HINTS. Thanks to Ben Jansens - for much of this patch. - - * display.c (meta_display_open): remove hints - - * display.h: remove atoms for hints - - * screen.c (set_wm_check_hint): don't set legacy hint - (set_supported_hint): don't set legacy hint - - * window-props.c (init_win_workspace): removed - (reload_win_workspace): removed - (meta_display_init_window_prop_hooks): remove hints - - * window.h: remove do_not_cover flag - - * window.c: remove GnomeWinHints enum - (recalc_do_not_cover_struts): removed - (meta_window_new): don't initialize removed flags or compute - legacy struts - (move_resize_cmp): removed - (idle_move_resize): Don't bother sorting the idle queue - (meta_window_client_message): don't set legacy hint - (process_property_notify): remove hints - (update_net_wm_type): don't fall back to WIN_LAYER hint - (update_struts): remove legacy struts - -2003-06-12 Havoc Pennington - - * src/display.c (event_callback): make raise-on-click explicitly - only happen in click to focus mode. - - * src/window.c (update_move): apply patch from Jurg Billeter to - allow you to "shake loose" maximized windows and move them between - Xinerama heads. #93586 - - * src/display.c: delete event_queue_callback - - * src/display.h (struct _MetaDisplay): get rid of - grab_current_window_pos and grab_current_root_[xy] as I could find - absolutely no code using them for anything. They were just sort of - randomly assigned to for no apparent reason. - - * src/display.c (event_callback): double-click timeout is per - screen, so get the screen and pass screen->ui to - meta_ui_get_double_click_timeout() - - * src/ui.c (meta_ui_get_double_click_timeout): take a MetaUI - argument so we get the right settings for each screen - (meta_ui_get_drag_threshold): new function - -2003-06-09 Rob Adams - - Revamp placement policy for windows that are maximized when they - are mapped, including windows that set a hint to be maximized or - windows that are auto-maximized using our heuristic. See #111902. - - * src/window.h: add new flag maximize_after_placement and new - function meta_window_maximize_internal. - - * src/window.c (meta_window_new): initialize - maximize_after_placement to FALSE and remove the automaximize - heuristic. - (meta_window_maximize_internal): new function accepts a saved_rect - argument to be used as the new saved_rect for the window, and does - not queue a move_resize. - (meta_window_maximize): re-implement using - meta_window_maximize_internal. - (update_net_wm_state): If a window has a maximize hint set on - startup set maximize_after_placement to TRUE - - * src/constraints.c (meta_window_constrain): Update the xinerama - information in the ConstraintInfo after placing the window, and - maximize the window after placement if - window->maximize_after_placement - - * src/place.c (find_first_fit): take a natural xinerama list as an - argument instead of generating it here - (constrain_placement): remove function, since it is no longer - needed - (meta_window_place): generate the natural xinerama list here and - pass it into find_first_fit. If find_first_fit fails, use the - list to find empty xineramas where we can place windows that may - be maximized later. This makes maximized windows follow the - correct placement policy. Move the automaximize heuristic here. - -2003-06-09 Rob Adams - - * src/metacity-dialog.c (warn_about_no_sm_support): install an - alarm to timeout the no-sm-dialog after 4 minutes of inactivity. - Patch from Ximian. See #114789. - -2003-06-07 Rob Adams - - * src/window.c (meta_window_new): call meta_group_compute_group - after setting window->desc to avoid SIGSEGV when verbose mode is - enabled. - -2003-06-07 Havoc Pennington - - * src/window.c (meta_window_notify_focus): drop the mouse button - grabs for the focused window; we'll see if this breaks anything. - It should fix #102209 - -Fri Jun 6 19:27:53 2003 Jonathan Blandford - - * src/metacity.schemas.in: fix the location of the schemas file. - -2003-06-04 Rob Adams - - * src/window.c (meta_window_new): don't be stupid and set - window->group = NULL after calling meta_window_compute_group. - - * src/group.c (meta_window_get_group): assert that window->group - != NULL in here instead of computing the group to ensure - robustness. - -2003-06-04 Rob Adams - - Precompute groups to guarantee that meta_group_list_windows always - returns the correct list of windows. See Bug #96973 - - * src/window.h: change cached_group variable to group - - * src/window.c (meta_window_new): change cached_group to group and - call meta_window_compute_group - - * src/groups.c (meta_window_get_group): simply return - window->group rather than computing it and returning - window->cached_group - (meta_window_compute_group): new function computes window->group. - Designed to be called once from meta_window_new - (remove_window_from_group): change cached_group to group - (meta_window_group_leader_changed): call meta_window_compute_group - instead of meta_window_get_group - -2003-05-29 Rob Adams - - Use a new property _METACITY_SENTINEL to eliminate a race - condition that causes focus to behave badly with sloppy/mouse - focus when lots of windows are mapped/unmapped, such as with a - workspace switch. The EnterNotify events on a display are ignored - until the PropertyNotify sent after all the window maps is - received. This is a fix for #110970. - - * src/display.[ch]: New _METACITY_SENTINEL atom. - (event_callback): ignore EnterNotify if the sentinel isn't clear, - and decrement the sentinel counter when the PropertyNotify is - received. - (meta_display_increment_focus_sentinel): new function. Increments - the sentinel counter and updates the property on a root window on - this display. - (meta_display_decrement_focus_sentinel): Decrement the sentinel - counter. - (meta_display_focus_sentinel_clear): returns whether the sentinel - counter is zero. - - * src/window.c (idle_calc_showing): after showing windows, call - meta_display_increment_focus_sentinel on each display for windows - to be shown. - - * src/workspace.[ch] (meta_workspace_activate_with_focus): new - function activates a workspace and focuses a particular window - after the workspace is activated. - (meta_workspace_activate): now just a wrapper for - meta_workspace_activate_with_focus - - * src/keybindings.c: use new meta_workspace_activate_with_focus - function to ensure that focus will follow the focused window - through the workspace switch. - -2003-05-29 Havoc Pennington - - * src/theme-parser.c (meta_theme_load): s/int/gsize/ for - g_file_get_contents() (found independently by - marcus@freebsd.org on SPARC and James Laska on s390x; - #113661 - - * src/main.c (main): fix theme location mentioned in error message - -2003-05-29 Ray Strode - - Get and use double-click speed from GtkSettings (Bug #103218). - - * src/ui.c, src/ui.h: - add function meta_ui_get_double_click_timeout for looking up - the global double-click speed. - - * src/display.c, src/display.h: remove double_click_time - field from MetaDisplay and use meta_ui_get_double_click_timeout - instead. - -2003-05-29 Rob Adams - - * src/main.c (main): chdir to the user's home directory on - startup. See #113755. - - * src/stack.c (get_standalone_layer): a window should be in the - fullscreen layer if it or any of its transient descendants are - focused or expecting the focus and it is either fullscreen or - fullscreen sized. Fix for #104369. - - * src/stack.c (is_focused_foreach): foreach used by - get_standalone_layer to find focused transient descendants. - -2003-05-20 Havoc Pennington - - * src/keybindings.c (meta_change_keygrab): the mask - display->ignored_modifier_mask wasn't being bound, - due to "<" instead of "<=" (most people didn't notice - as display->ignored_modifier_mask included Scroll_Lock). - Red Hat bugzilla #91301 reported by Youssef Makki - - * src/display.c (meta_change_button_grab): make corresponding - change for button grabs. - -2003-05-20 Havoc Pennington - - * NEWS: update - - * configure.in: 2.5.2 - -2003-05-20 Anders Carlsson - - * src/metacity-dialog.c: (kill_window_question): - Split up the strings to make life easier for translators. - -2003-05-20 Anders Carlsson - - * src/metacity-dialog.c: (kill_window_question): - Fix the wording and HIGify the dialog. - -2003-05-18 Havoc Pennington - - * src/window.c (unminimize_window_and_all_transient_parents): - revert broken change that assumed foreach_ancestor iterated - over the window itself. Andrew Sobala, Rob Adams, - #113232 - -2003-05-16 Rob Adams - - Flip the workspace when using up/down/left/right for move window - to, but not when specifying a workspace explicitly as in move to - workspace 4. Possible fix for #105492. - - * src/keybindings.c (do_handle_move_to_workspace): new function - moves a window to a workspace with the option to flip to that - workspace. - (handle_move_to_workspace): Use new do_handle_move_to_workspace - function without flipping (a keybinding) - (handle_move_to_workspace_flip): Use new - do_handle_move_to_workspace function with flipping (a keybinding) - -2003-05-16 Havoc Pennington - - * src/frames.c (meta_frames_paint_to_drawable): fix for - bug #104018 from David Santiago, change button state to - normal while it's being pressed if you move the mouse - outside it. Do this by tracking prelit_control for whether - to draw a button as active, not just for whether to draw - it as prelit. - (meta_frames_motion_notify_event): also update prelit_control - while clicking a button - -2003-05-16 Havoc Pennington - - * src/window.c (meta_window_new): fill in window->desc sooner - since we use it sooner now. - - * src/display.c (meta_display_open): init - display->grab_update_alarm - - * src/window.c (meta_window_new): initialize the always_sticky - field - (meta_window_new): initialize the update_icon_queued field - - Patch from Julien Olivier bug #92335 for converting "show desktop - mode" to "all windows are minimized" when you open a new window, - instead of just mapping all the windows again. - - * src/window.c (meta_window_activate): minimize all windows before - coming out of show desktop mode. - (meta_window_unminimize): don't toggle show desktop mode here - - * src/screen.c (meta_screen_minimize_all_except): new function - -2003-05-01 Havoc Pennington - - * src/theme-parser.c (meta_theme_load): fix memleak on error - -2003-05-16 Telsa Gwynne - - * configure.in: Added "cy" (Welsh) to ALL_LINGUAS. - -2003-05-06 Danilo Å egan - - * configure.in: Added "sr" and "sr@Latn" to ALL_LINGUAS. - -2003-05-03 Havoc Pennington - - * src/keybindings.c (handle_move_to_workspace): when moving - window to another workspace, don't switch to that workspace. - - * src/window.c (menu_callback): when moving window to another - workspace, don't switch to that workspace. - -2003-05-03 Havoc Pennington - - * configure.in: 2.5.1 - - * NEWS: update - -2003-05-01 Rob Adams - - * src/constraints.c (constraint_onscreen_applies_func): Don't - apply onscreen constraints to full screen windows. Fix for - #110048 - -2003-04-29 Havoc Pennington - - * src/bell.h: include Xlib.h before XKBlib.h which is required on - Solaris. #111877 from Peter O'Shea - -2003-04-23 Havoc Pennington - - * src/keybindings.c (process_keyboard_move_grab): support - diagonal keypad keybindings, from Dafydd Harries - -2003-04-21 Havoc Pennington - - * purge HAVE_GTK_MULTIHEAD from the source code, not just from - configure.in. Yes I am a loser. - -2003-04-19 Masahiro Sakai - - * configure.in: call AC_LIBTOOL_WIN32_DLL. - - * src/Makefile.am: add -no-undefined to libmetacity_private_la_LDFLAGS - and write dependency libraries in libmetacity_private_la_LIBADD. - -2003-04-06 Rob Adams - - * src/place.c (find_next_cascade): cascade on xinerama with - pointer instead of on first xinerama. - -2003-04-05 Rob Adams - - Update placement policy for screen with multiple xineramas. - Windows will be placed preferentially on the xinerama with the - pointer, and progressively further away as needed to find a place - where the window does not overlap other windows. - - * src/place.c (rect_fits_in_work_area): function - fit_rect_in_xinerama greatly simplified to work with new placement - policy. - (find_first_fit): implement new first fit placement scheme - - * src/screen.c (meta_screen_get_xinerama_neighbor): look for an - xinerama in the xinerama list that is adjacent to the specified - xinerama. - (meta_screen_get_natural_xinerama_list): return a list of - xineramas in the order to be preferred by the placement algorithm - as determined by the current location of the pointer. - - * src/screen.h: add function prototypes and an enum used by - meta_screen_get_xinerama_neighbor. - -2003-04-05 Rob Adams - - * src/place.c (center_tile_rect_in_area): Fix a minor off-by-one - error. See #110079. - -2003-03-30 Rob Adams - - * src/window.c (meta_window_move_resize_internal): When passing - frame geometry to meta_window_constrain, send null if no frame. - Possible fix for #109039. - -2003-03-29 Havoc Pennington - - * src/wm-tester/test-gravity.c (main): add --noframes option for - testing, showing how broken we currently are. - -Fri Mar 28 14:13:37 2003 Soeren Sandmann - - * src/window.c (update_resize): Only cap refresh rate when not - using SYNC. Remove bogus update-if-we-moved-more-than-a-delta. - - * src/window.c (update_move): Don't cap refresh rate during - moves. Remove bogus update-if-we-moved-more-than-a-delta. - -2003-03-26 Havoc Pennington - - * NEWS: update - - * configure.in: release 2.5.0 - -Sun Mar 23 23:04:06 2003 Soeren Sandmann - - * src/display.c (meta_spew_event): just return if we are not - verbose. - -2003-03-11 Havoc Pennington - - Should fix #108108, #106217, tracked down by Owen Taylor and - Frederic Crozat - - * src/window.c (meta_window_foreach_transient): change - MetaWindowForeachFunc to return a boolean for whether to continue - (meta_window_foreach_ancestor): new function - (window_should_be_showing): use meta_window_foreach_ancestor - (unminimize_window_and_all_transient_parents): ditto - (update_sm_hints): ditto - (meta_window_is_ancestor_of_transient): ditto - - * src/stack.c (get_maximum_layer_of_ancestor): use - meta_window_foreach_ancestor - -2003-03-16 Rob Adams - - * window.c (meta_window_show_menu): Free old window menu if it - already exists so we don't end up with more than one. Fix for - #108392. - -2003-03-14 Rob Adams - - * contraints.c (get_outermost_screen_positions): Don't try to - force a window onscreen by more than its width. Fix for #94815. - -2003-03-13 Rob Adams - - Make it so that the alt-tabbing won't try to go to a minimized - window by default. Fix for #107071. - - * display.c (meta_display_get_tab_list): use a GList instead of a - GSList - (meta_display_get_tab_next): use meta_display_get_tab_list to - decide what the next/previous tab window should be. - - * display.h (meta_display_get_tab_list): update function prototype - to return GList instead of GSList. - - * screen.c (meta_screen_ensure_tab_popup): update function to deal - with GList returned by meta_display_get_tab_list instead of GSList. - -2003-03-13 Christian Rose - - * configure.in: Added "ml" to ALL_LINGUAS. - -2003-03-11 Paul Duffy - - * configure.in: Added "ga" to ALL_LINGUAS - -2003-03-11 Rob Adams - - * src/constraints.c (meta_window_constrain): include left frame - geometry when maximizing or fullscreening windows. Fix for - #108127. - -2003-03-10 Roozbeh Pournader - - * configure.in: Added "fa" to ALL_LINGUAS. - -2003-02-27 Havoc Pennington - - Switch over to new constraints code, unquestionably introduces - some bugs, but should get us on the right path. - - * src/window.c (meta_window_get_work_area_all_xineramas): create - this function again as it turned out to be legitimate for window - position constraint - (adjust_for_gravity): use the width/height from the configure - request to compute the requested move - (meta_window_move_resize_internal): use meta_window_constrain - (update_size_hints): clamp max size to MAXSHORT to avoid worrying - about overflow stuff - - * src/constraints.c (meta_window_constrain): don't base placement - on uninitialized variables, general hacking - - * src/Makefile.am (metacity_SOURCES): add constraints.c, - constraints.h - - * src/constraints.c (meta_window_constrain): update the - cut-and-paste aspect ratio code to have latest bugfixes - -2003-03-08 Rob Adams - - * src/window-props.c (reload_normal_hints): Check that window min - and max size hints are at least 1. Fix for #107110. - -2003-02-27 Havoc Pennington - - Changes made on plane from FOSDEM, syncing from laptop. - - * src/main.c (main): add more debug spew about conditional - build stuff - (main): panic to "Simple" theme - - * src/window.c, src/window-props.c: move WM_NORMAL_HINTS and - WM_PROTOCOLS to new property system; don't queue move resize on - updating WM_PROTOCOLS; move WM_HINTS to new property system; - reload icon in an idle handler. - -2003-02-28 Mark McLoughlin - - Give me back my keys. - - * src/keybindings.c: (meta_window_grab_keys): don't - grab keys on DOCK windows. - - * src/window.c: (recalc_window_type): re-grab the - keys. - -2003-02-26 Dmitry G. Mastrukov - - * configure.in: Added Belarusian to ALL_LINGUAS. - -2003-02-26 Mark McLoughlin - - * src/keybindings.c: (handle_panel_keybinding): release - the keyboard grab before sending the action message to - the panel. - -2003-02-24 Mark McLoughlin - - Take control of the panel's global keybindings. The - screenshot utility is hooked up using a special case - run_command and the menu and run dialog bindings are - done using the _GNOME_PANEL_ACTION ClientMessage - protocol. - - * src/display.[ch]: (meta_display_open): add some atoms. - - * src/keybindings.c: - (handle_panel_keybinding): impl to handle a keybinding - by sending an action message to the panel. - - * src/metacity.schemas.in: add schemas for the panel and - screenshot keybindings and the screenshot commands. - - * src/prefs.[ch]: (update_command), - (meta_prefs_get_gconf_key_for_command): impl special case - handling for the screenshot commands. They are stored at - the the end of the commands array but have named keys. - -2003-02-23 Havoc Pennington - - Patch from Rob Adams addresses #95014 (placement issues), - makes first fit algorithm "center tile", adds most code - for per-xinerama workspaces (#86682) but disables it for now. - - * src/workspace.c (meta_workspace_get_work_area_for_xinerama) - (meta_workspace_get_work_area_all_xineramas): new xinerama - functions, maintain workspace->work_areas with a different - work area for each xinerama. However for now all the work - areas are the same, because haven't quite figured out how - _NET_WM_STRUT is supposed to work - - * src/window.c: adapt to new meta_window_* xinerama APIs - (meta_window_get_work_area_current_xinerama): new xinerama - API - (meta_window_get_work_area_for_xinerama): new xinerama API - (constrain_position): be a bit more clever about which xinerama's - work area we choose to use. - - * src/stack.c: adapt to new Xinerama API - - * src/screen.c (reload_xinerama_infos): invalidate all work areas - (meta_screen_get_xinerama_for_rect): new function - (meta_screen_window_intersects_xinerama): new function - - * src/place.c (find_first_fit): change to use - "center tiling" (center a screen full of tiled windows, - rather than aligning them top left). Adapt to new - xinerama functions. - -2003-02-22 Rob Adams - - * src/metacity.schemas.in: change toggle_maximized to - toggle_maximize and toggle_shaded to toggle_shade in - action_double_click_titlebar long description to match the values - used by metacity - - * po/*.po: change toggle_maximized to toggle_maximize and - toggle_shaded to toggle_shade in action_double_click_titlebar long - description to match the values used by metacity - -2003-02-22 Rob Adams - - * window.c (set_wm_state): modify comment to explain why the icon - window element is set to None. Fix for #97357 thanks to Gregory - Merchan. - -2003-02-22 Havoc Pennington - - * README: fix a typo, pointed out by Steve Kemp - -2003-02-22 Havoc Pennington - - * src/prefs.c (MAX_REASONABLE_WORKSPACES): change max workspaces - to 36 #81855 - -2003-02-22 Havoc Pennington - - * src/display.c (event_callback): fix to unfocus window only when - you leave the window frame, not when you leave the window itself, - unless window has no frame. #100248 fix from Orien Vandenbergh - -2003-02-22 Havoc Pennington - - * src/display.c (meta_display_get_tab_next): when tabbing - backward, we are still tabbing *from* the most recently used - window, not from the least recently used window. - - * src/keybindings.c (struct _MetaKeyBinding): make keycode - unsigned to match XEvent - - Patch for #84999 based on patch from Mark McLoughlin - - * src/prefs.c: add an add_shift field to MetaKeyPref to - add shift when grabbing the given keybinding. - - * src/keybindings.c (rebuild_screen_binding_table) - (rebuild_window_binding_table): refactor to share code, - and honor add_shift field in MetaKeyPref - -2003-02-20 Havoc Pennington - - * src/stack.c (create_constraints): don't create constraints - between windows on different screens, #106086 tracked down - by Arvind - -2003-02-14 Arvind Samptur - - * src/screen.c: (meta_screen_new) : Update the workspace - names from gconf and set the NET_DESKTOP_NAMES atom. - Renamed update_workspace_names() to set_workspace_names(). - Fixes #105498 - -2003-02-13 Havoc Pennington - - * configure.in: require GTK+ 2.2.0 - - * src/ui.c (meta_ui_init): remove hackaround for Pango X core - fonts backend - -2003-02-05 Abel Cheung - - * configure.in: Added "en_GB" and "nl" to ALL_LINGUAS. - -2003-02-05 Akira TAGOH - - * src/main.c (usage): fix a typo and missing option. (#105186) - -2003-02-04 Havoc Pennington - - * src/themes/Simple/ChangeLog: nuke subdir ChangeLog, - there can be only one true ChangeLog. - -2003-01-30 Havoc Pennington - - * src/keybindings.c (process_event): match handlers to key events - using key codes, not key syms - -Thu Jan 30 22:55:16 2003 Jonathan Blandford - - * src/themes/Makefile.am (THEMES): add Simple to the list of - themes. - - * src/metacity.schemas.in: change default theme to Simple. - -2003-01-29 Havoc Pennington - - * src/menu.c (meta_window_menu_new): don't create workspaces - menu items if only 1 workspace. Fix for #101952 from - Orien Vandenbergh - -2003-01-28 Bill Haneman - - * Re-instated visual-bell patch - (please see ChangeLog entry for 2002-12-16 for details). - - * src/prefs.c: - (visual_bell_type_from_string): - Accept a NULL string for 'visual-bell-type'. - -2003-01-25 Havoc Pennington - - * src/stack.c (window_is_fullscreen_size): When checking if a - window is fullscreen size, only require it to be at the origin - of the work area, not at the origin of the screen/xinerama. - Still require it to be full screen in width x height. - May fix xine in the case where the user has a top panel. - - * src/window.c (constrain_position): restore the ability for - undecorated windows to position themselves overlapping the top - panel, but don't let decorated windows do so. Oh the hacks... - -2003-01-08 Havoc Pennington - - * src/screen.c (meta_screen_apply_startup_properties): small code - snippet to fix startup sequences that set legacy class/name - -2003-01-22 Havoc Pennington - - * src/async-getprop.c (async_get_property_handler): do not read - sizeof(long) off the X connection. The X protocol does not vary - by architecture. Fixes longstanding hang on all 64-bit platforms. - -2003-01-22 Havoc Pennington - - * src/tools/Makefile.am: fix conditional so we get - metacity-properties.c in the distribution #103071 - -2003-01-22 Havoc Pennington - - * src/window.c (update_struts): be robust against the panel's - lame "set a negative number for struts" thing, even though - we'll also fix the panel. - -2003-01-21 Havoc Pennington - - Fix for the "mangles focus window when switching workspaces - and using mouse focus" bug - - * src/stack.c (meta_stack_get_default_focus_window_at_point): new - function - - * src/screen.c (meta_screen_focus_mouse_window): new function - (meta_screen_focus_default_window): new function - - * src/workspace.c (meta_workspace_activate): use the - new meta_screen_focus_default_window() - -2003-01-17 Havoc Pennington - - * src/window.c (meta_window_handle_mouse_grab_op_event): fix event - compression code to use GDK algorithm suggested by Owen, should be - more efficient. - -2003-01-22 Christian Rose - - * configure.in: Added "mn" to ALL_LINGUAS. - -2003-01-21 Havoc Pennington - - * src/display.c (event_callback): only hop window to the current - workspace if the window was previously minimized. Should keep - mozilla from popping windows over to your current workspace. - -2003-01-20 Havoc Pennington - - Attempt to fix #85916 - - * src/keybindings.c (primary_modifier_still_pressed): new function - (handle_workspace_switch): handle modifier release prior to - getting the grab - (do_choose_window): handle modifier release prior to getting the - grab - - * src/keybindings.c (grab_keyboard): properly return failure - if the GrabKeyboard doesn't work - -2003-01-19 Havoc Pennington - - * configure.in: add note about how this is the unstable branch, - set version to 2.5.0 - -2003-01-14 Havoc Pennington - - * src/window.c (meta_window_maximize, meta_window_unmaximize) - (meta_window_make_fullscreen, meta_window_unmake_fullscreen): - recalc_window_features() after making these changes, should fix - #103317 - -2003-01-14 Rob Adams - - * src/prefs.c: Increase the number of run_command bindings in - screen_bindings from 12 to 32. - - * src/prefs.h: Increase the number of META_KEYBINDING_COMMAND_N - macros from 12 to 32. - - * src/keybindings.c: Increase the number of run_command handlers - from 12 to 32. - -2003-01-11 Havoc Pennington - - * src/window.c (meta_window_handle_mouse_grab_op_event): implement - compression of motion events (drop all but the most recently - received), guessing at fixes for #103009 - -2003-01-11 Havoc Pennington - - * configure.in: add ability to --disable-shape - -2003-01-11 Akira TAGOH - - * configure.in: fix the behavior of --enable-*. - -2003-01-10 Havoc Pennington - - * src/Makefile.am (desktopfiles_in_files): revert that change, I - got the wrong .desktop file. doh. - -2003-01-10 Havoc Pennington - - * src/Makefile.am (desktopfiles_DATA): don't install .desktop file - for properties dialog if we aren't building/installing the - properties dialog. - -2003-01-10 Havoc Pennington - - * NEWS: update - - * configure.in: bump to 2.4.13, require 2.2.0 for multihead - -2003-01-09 James M. Cape - - * src/themes/Esco/metacity-theme-1.xml: Use a line for the titlebar - text bg. - -2003-01-09 Havoc Pennington - - * src/window.c (recalc_window_features): argh, we were making all - dialogs skip taskbar; when did that get added. Fix to match - libwnck, only skip taskbar when the dialog is transient for some - other app window. - -2003-01-09 Havoc Pennington - - * src/metacity.schemas.in: change Windows+click back to Alt+click, - Windows+click just surprised everybody and didn't work half the - time. Maya users can configure it, and GTK DND can change its - default. - -2003-01-08 Havoc Pennington - - * src/metacity.schemas.in: assign Alt+F12 to shade window, - per #102658 - -2003-01-07 Havoc Pennington - - * src/screen.c (update_num_workspaces): fix off-by-one, patch from - readams@hmc.edu, #102806 - -2003-01-06 Arvind Samptur - - * src/window.c: (constrain_position) don't apply - offscreen height difference. This would get the - window under the panel on a resize or a move. - Fixes #102418 - -2003-01-05 Havoc Pennington - - * src/screen.c (meta_screen_calc_workspace_layout): invert - vertical_workspaces cases (we want to go down each column if - it's vertical, and across each row if horizontal). Patch - from readams@hmc.edu - -2003-01-05 Pablo Saratxaga - - * configure.in: Added Macedonian (mk) to ALL_LINGUAS - -2003-01-05 Havoc Pennington - - * src/frames.c (meta_frames_apply_shapes): put in the - HAVE_GTK_MULTIHEAD conditionals so we build with GTK 2.0 - -2003-01-05 Havoc Pennington - - * src/window.c (meta_window_show): focus new windows even in - mouse focus mode, #89981, patch from readams@hmc.edu - -2003-01-05 Havoc Pennington - - * src/workspace.c (meta_workspace_get_neighbor): redo using new - calc_workspace_layout to fix #98302 - - * src/util.c (topic_name): shorten default prefix - - * src/screen.c (meta_screen_calc_workspace_layout): enhance this - to handle all the funky layouts and calculate more information - than before - -2003-01-05 Pauli Virtanen - - * configure.in (ALL_LINGUAS): Added "fi" (Finnish). - -2003-01-05 Havoc Pennington - - * src/frames.c (meta_frames_apply_shapes): handle - the client having a shape mask, fixes #101806 - - * src/core.c (meta_core_get_client_xwindow): new function - - * src/frame.c, src/frame.h: keep a flag for whether we need to - update the frame shape - - * src/window.c (meta_window_new): select for ShapeNotify - - * src/display.h, src/display.c: actually query the shape - extension, instead of just using it all over the place. - - * src/prefs.c (update_application_based): don't let people turn on - application_based, as it just causes funky bugs. We can reenable - the pref when/if it ever does something useful. - -2003-01-03 Havoc Pennington - - * src/display.c: include the Xrandr header file - - * src/window.c (meta_window_fill_horizontal) - (meta_window_fill_vertical): maximize to work area, not entire - screen. doh. - -2002-12-19 Ross Burton - - * doc/metacity-theme.dtd: Fix a typo and loosen the requirements - for the resize element. - -2002-12-19 Havoc Pennington - - * Reverted visual bell patch, #99886 - -2002-12-19 Yanko Kaneti - - * configure.in: (ALL_LINGUAS) Added Bulgarian (bg). - -2002-12-18 Havoc Pennington - - * src/window.c (meta_window_new): select ColormapChangeMask - on toplevel windows, maybe a partial fix for #101478 - -Tue Dec 17 17:50:19 2002 HideToshi Tajima - - * src/themes/AgingGorilla/metacity-theme-1.xml: added support for - border only windows. #100984. - -2002-12-17 Havoc Pennington - - * src/display.c (meta_display_begin_grab_op): don't use "(null)" - for null pointers, use "none", so I can distinguish - glibc-generated (null) which is a bug. - (key_event_description): ditto - (meta_display_begin_grab_op): ditto - - * src/window.c (update_sm_hints): ditto - - * src/keybindings.c (reload_modmap): ditto - (meta_display_process_key_event): ditto - -2002-12-17 Havoc Pennington - - * src/metacity.schemas.in: s/focussed/focused/ - -2002-12-17 Havoc Pennington - - * src/xprops.c (validate_or_free_results): add a comma to message #101401 - -2002-12-16 Bill Haneman - - * configure.in: - Check for XKB extension. - - * src/Makefile.am: - Added bell.c and bell.h to metacity sources. - - * src/common.h: - (MetaFrameFlags): - Added META_FRAME_IS_FLASHING flag. - - * src/frame.h: - (MetaFrame): Added is_flashing field. - - * src/frame.c: - (meta_window_ensure_frame): - Initialize the is_flashing flag to FALSE. - (meta_frame_get_flags): - Handle the FRAME_IS_FLASHING flag. - (meta_window_destroy_frame): - Call meta_bell_notify_frame_destroy. - - * src/prefs.h: - (MetaPreference): - Added META_PREF_VISUAL_BELL, META_PREF_AUDIBLE_BELL, - META_PREF_VISUAL_BELL_TYPE. - (MetaVisualBellType): New enum. - (meta_prefs_get_visual_bell, meta_prefs_bell_is_audible): - (meta_prefs_get_visual_bell_type): - New accessor declarations. - - * src/prefs.c: - (#includes): Include "display.h", since we now call - meta_displays_list() in our update func. - (#defines): - Define KEY_VISUAL_BELL, KEY_AUDIBLE_BELL, - and KEY_VISUAL_BELL_TYPE. - (provide_visual_bell, bell_is_audible, visual_bell_type): - New static state variables. - (update_visual_bell): New method to update visual-bell - boolean settings from keys "visual_bell" and "audible_bell". - (update_visual_bell_type): - New method to update visual-bell type setting. - (visual_bell_type_from_string) : - New method to convert from gconf string to visual-bell - type enum. Only currently recognized values are "fullscreen" - and "frame_flash". - (change_notify): - Handle changes to visual and audible bell properties. - (meta_prefs_get_visual_bell, meta_prefs_bell_is_audible): - (meta_prefs_get_visual_bell_type): - New accessor definitions. - (meta_prefs_init): Added a second call to notify_add, - listens to "/desktop/gnome/interface" as well as "apps/metacity". - Also call the update funcs for the new visual-bell gconf keys. - (meta_preference_to_string): - Handle the visual/audible bell cases. - - * src/bell.h: - (meta_bell_notify); - New method, calls a visual notifucation - method based on the visual-bell-type, or none if the type - is unrecognized or invalid. - (meta_bell_set_audible): - New public method for setting the audible bell setting, - used in updater for new gconf key "audible_bell". - (meta_bell_init): - Initialize the bell notification for a display. - (meta_bell_shutdown): - Shutdown the bell notification for a display. - (meta_bell_notify_frame_destroy): - Remove pending idle handlers on notification. - - * src/bell.c: - Include "bell.h", and conditionally include . - (meta_bell_set_audible): - If XKB is present, enable/disable the audible system - bell based on the gconf key /desktop/gnome/interface/audible_bell. - (meta_bell_init): - Query and initialize XKB if present, register for notification - on the bell, and set audible bell according to gconf settings. - (meta_bell_flash_screen): - Maps and unmaps a fullscreen X window (painted white, then - black), which causes a fullscreen 'flash' transient. - (meta_bell_flash_window_frame): - Flashes the titlebar of a specified window. - (meta_bell_flash_frame): - Calls meta_bell_flash_window_frame on the window which - was the source of the current bell event, or the currently - focussed window if the event source cannot be determined. - (meta_bell_unflash_frame): - Restore the frame's appearance to normal. - (meta_bell_flash_fullscreen): - Call meta_bell_flash_fullscreen for all screens. - (meta_bell_shutdown): - New method. - (meta_bell_notify_frame_destroy): - Remove pending idle handlers on notification, - testing for frame->is_flashing first. - - * src/display.h: - (MetaDisplay): Added xkb_base_event_type field. - - * src/display.c: - Check for XKB and include "X11/XKBlib.h" if present. - (meta_display_open): Call meta_bell_init. - (event_callback): Call meta_bell_notify - when event comes from XKB and is XkbBellNotify - (prefs_changed_callback): - Handle META_PREF_AUDIBLE_BELL notification. - - * src/screen.h: - (MetaScreen): Add flash_window field. - - * src/screen.c: - (meta_screen_new): - Initialize flash_window field. - - * src/theme.c: - (theme_get_style): - New heuristic for focus-style, to invert sense of focus - flag when META_FRAME_IS_FLASHING flag is set. - - * src/metacity.schemas.in: - Added scheme information for - /apps/metacity/general/visual_bell, - /apps/metacity/general/audible_bell, and - /apps/metacity/general/visual_bell_type. - -2002-12-16 Havoc Pennington - - * src/window-props.c (init_wm_name): argh, screwed that up. get - WM_NAME as VALUE_TEXT_PROPERTY #101383 - -2002-12-16 Bill Haneman - - * configure.in: - Check for XKB extension. - - * src/Makefile.am: - Added bell.c and bell.h to metacity sources. - - * src/common.h: - (MetaFrameFlags): - Added META_FRAME_IS_FLASHING flag. - - * src/frame.h: - (MetaFrame): Added is_flashing field. - - * src/frame.c: - (meta_window_ensure_frame): - Initialize the is_flashing flag to FALSE. - (meta_frame_get_flags): - Handle the FRAME_IS_FLASHING flag. - (meta_window_destroy_frame): - Call meta_bell_notify_frame_destroy. - - * src/prefs.h: - (MetaPreference): - Added META_PREF_VISUAL_BELL, META_PREF_AUDIBLE_BELL, - META_PREF_VISUAL_BELL_TYPE. - (MetaVisualBellType): New enum. - (meta_prefs_get_visual_bell, meta_prefs_bell_is_audible): - (meta_prefs_get_visual_bell_type): - New accessor declarations. - - * src/prefs.c: - (#includes): Include "display.h", since we now call - meta_displays_list() in our update func. - (#defines): - Define KEY_VISUAL_BELL, KEY_AUDIBLE_BELL, - and KEY_VISUAL_BELL_TYPE. - (provide_visual_bell, bell_is_audible, visual_bell_type): - New static state variables. - (update_visual_bell): New method to update visual-bell - boolean settings from keys "visual_bell" and "audible_bell". - (update_visual_bell_type): - New method to update visual-bell type setting. - (visual_bell_type_from_string) : - New method to convert from gconf string to visual-bell - type enum. Only currently recognized values are "fullscreen" - and "frame_flash". - (change_notify): - Handle changes to visual and audible bell properties. - (meta_prefs_get_visual_bell, meta_prefs_bell_is_audible): - (meta_prefs_get_visual_bell_type): - New accessor definitions. - (meta_prefs_init): Added a second call to notify_add, - listens to "/desktop/gnome/interface" as well as "apps/metacity". - Also call the update funcs for the new visual-bell gconf keys. - (meta_preference_to_string): - Handle the visual/audible bell cases. - - * src/bell.h: - (meta_bell_notify); - New method, calls a visual notifucation - method based on the visual-bell-type, or none if the type - is unrecognized or invalid. - (meta_bell_set_audible): - New public method for setting the audible bell setting, - used in updater for new gconf key "audible_bell". - (meta_bell_init): - Initialize the bell notification for a display. - (meta_bell_shutdown): - Shutdown the bell notification for a display. - (meta_bell_notify_frame_destroy): - Remove pending idle handlers on notification. - - * src/bell.c: - Include "bell.h", and conditionally include . - (meta_bell_set_audible): - If XKB is present, enable/disable the audible system - bell based on the gconf key /desktop/gnome/interface/audible_bell. - (meta_bell_init): - Query and initialize XKB if present, register for notification - on the bell, and set audible bell according to gconf settings. - (meta_bell_flash_screen): - Maps and unmaps a fullscreen X window (painted white, then - black), which causes a fullscreen 'flash' transient. - (meta_bell_flash_window_frame): - Flashes the titlebar of a specified window. - (meta_bell_flash_frame): - Calls meta_bell_flash_window_frame on the window which - was the source of the current bell event, or the currently - focussed window if the event source cannot be determined. - (meta_bell_unflash_frame): - Restore the frame's appearance to normal. - (meta_bell_flash_fullscreen): - Call meta_bell_flash_fullscreen for all screens. - (meta_bell_shutdown): - New method. - (meta_bell_notify_frame_destroy): - Remove pending idle handlers on notification, - testing for frame->is_flashing first. - - * src/display.h: - (MetaDisplay): Added xkb_base_event_type field. - - * src/display.c: - Check for XKB and include "X11/XKBlib.h" if present. - (meta_display_open): Call meta_bell_init. - (event_callback): Call meta_bell_notify - when event comes from XKB and is XkbBellNotify - (prefs_changed_callback): - Handle META_PREF_AUDIBLE_BELL notification. - - * src/screen.h: - (MetaScreen): Add flash_window field. - - * src/screen.c: - (meta_screen_new): - Initialize flash_window field. - - * src/theme.c: - (theme_get_style): - New heuristic for focus-style, to invert sense of focus - flag when META_FRAME_IS_FLASHING flag is set. - - * src/metacity.schemas.in: - Added scheme information for - /apps/metacity/general/visual_bell, - /apps/metacity/general/audible_bell, and - /apps/metacity/general/visual_bell_type. - -2002-12-16 Havoc Pennington - - * src/window-props.c: use META_PROP_VALUE_STRING_AS_UTF8 so - we convert old Latin-1 WM_NAME to UTF-8 - - * src/xprops.h (enum): add META_PROP_VALUE_STRING_AS_UTF8 to get a - latin1 string then convert. - -2002-12-15 Havoc Pennington - - * src/window.c (meta_window_new): get window name before anything - else. - - * src/xprops.c (validate_or_free_results): instead of suggesting - how to get window title etc. with xprop, just print out the - window title. much better. - -2002-12-15 Havoc Pennington - - * src/xprops.c (validate_or_free_results): make the warning about - strange property contents blame the application and explain how to - use xprop to diagnose which app is causing the problem. - -2002-12-15 Havoc Pennington - - * src/prefs.c (meta_prefs_change_workspace_name): don't pass NULL - string to gconf_client_set_string #101237 - -2002-12-13 Havoc Pennington - - * src/tools/Makefile.am (Desktop_in_files): only install .desktop - file for metacity-properties if we actually install - metacity-properties - - * src/display.c (event_callback): not focusing on button 2 click - was crack, revert that change. - -2002-12-09 Havoc Pennington - - * AUTHORS: add myself here, bug #100789 - - * src/display.c (meta_display_set_grab_op_cursor): drop - PointerMotionHintMask - - * src/window.c (meta_window_handle_mouse_grab_op_event): don't use - XQueryPointer, as we aren't using PointerMotionHint now - - * src/display.c (event_callback): rearrange a bit of code - for slight speedup and clarity - - * src/window.c (update_resize) - (meta_window_handle_mouse_grab_op_event): implement - usage of the _METACITY_UPDATE_COUNTER - (meta_window_handle_mouse_grab_op_event): fix code that - used event->xbutton with a motion event - - * src/display.c (meta_display_open): add new atoms, and - initialize Xsync if we have it - (grab_op_is_resizing): new function - (meta_display_begin_grab_op): create an alarm monitoring - window's _METACITY_UPDATE_COUNTER - (meta_spew_event): conditionalize this on WITH_VERBOSE_MODE - and print alarm events. - - * src/window.c (meta_window_new): fetch _METACITY_UPDATE_COUNTER - - * configure.in (HAVE_XSYNC): check for Xsync extension - -Mon Dec 9 22:09:56 2002 Soeren Sandmann - - * src/display.c, src/window.c: Handle crossing events during - resizing. (#93384). - -2002-12-09 Havoc Pennington - - * configure.in: 2.4.8 - -2002-12-08 Havoc Pennington - - * README: updates - - * src/window.c (MAX_RESIZES_PER_SECOND): change to 20 instead of - 30, just as an experiment. - (MOVE_THRESHOLD): change 15 to 20 - (RESIZE_THRESHOLD): change 15 to 20 - - * src/util.c (ensure_logfile): kill this function when verbose - mode is disabled. - -2002-12-08 Havoc Pennington - - * src/window.c (meta_window_fill_vertical) - (meta_window_fill_horizontal): new functions to resize to - fill screen - - * src/keybindings.c: add vert, horiz maximize - - * src/prefs.c: had vert, horiz maximize - - * src/metacity.schemas.in: shorten some overlong short - descriptions that make the keybindings capplet look ugly. - Add maximize_vertically, maximize_horizontally keys. - -2002-12-08 Havoc Pennington - - * src/prefs.c (meta_prefs_get_application_based): make this always - return FALSE for now, to avoid bug reports. - - * src/util.c (ensure_logfile): put "opened log file" message on - stderr so it will normally land in ~/.xsession-errors - - * configure.in: remove extra AC_ARG_PROGRAM - - * src/display.c (event_callback): handle the toggle-verbose message - - * src/tools/metacity-message.c: add a toggle-verbose message, been - meaning to do this for a while. - - * src/util.c (meta_set_verbose): if verbose mode is enabled and we - don't support it, then exit. - - * src/prefs.c: allow building without gconf (currently means some - prefs are no-ops) - - * src/util.c, src/util.h: support defining macros to - kill all verbose output entirely. (Removes the code and strings - associated with it) - - * configure.in: don't get METACITY_PROPS_LIBS if not building the - config dialog. - (HAVE_GCONF): allow building sans gconf, if you are size-sensitive - and not using gnome. - (WITH_VERBOSE_MODE): add ability to disable all the verbose debug - spew strings, to shrink the binary. - (--disable-sm): allow SM support to be forced on or off - (--disable-startup-notification): allow forcing this on or off - -2002-12-08 Havoc Pennington - - * src/prefs.c (update_workspace_name): also treat empty string as - "unset" in this function. - -Thu Dec 5 18:41:02 2002 HideToshi Tajima - - * src/window.h (META_WINDOW_IN_NORMAL_TAB_CHAIN, - META_WINDOW_IN_DOCK_TAB_CHAIN) : never use a window with input = - FALSE take_focus = FALSE in the normal and dock tab chains. #90409 - -Thu Dec 5 13:56:52 2002 HideToshi Tajima - - * src/display.c (event_callback): move a window to the current - space on the MapRequest when it's not on the space yet. #100390 - -2002-12-01 Havoc Pennington - - * src/frames.c (get_control): rearrange this function a bit, so - that we return CONTROL_TITLE for anything above the bottom of the - titlebar, in the fallback case where no other control was found. - Also, don't return RESIZE_N for title rect above the top resize - size, unless the window is resizable. - (meta_frames_button_press_event): only start a move when clicking - control TITLE, not control NONE. This way you don't start moving - a nonresizable window if you click its edges. - -2002-12-01 Havoc Pennington - - * src/tools/Makefile.am: conditionalize building the config dialog - - * configure.in (BUILD_CONFIG_DIALOG): add --enable-config-dialog - option to turn on the "window focus" dialog. This is part of - deprecating this dialog. - -2002-11-30 Havoc Pennington - - * src/screen.c (STARTUP_TIMEOUT): lengthen to 15 seconds - - * src/util.c (utf8_fputs): hmm, return a value - - * src/screen.c (meta_screen_apply_startup_properties): new - function to apply initial workspace based on startup sequence. - - * src/window.c (meta_window_new): load _NET_STARTUP_ID - (meta_window_get_startup_id): new function - - * src/window-props.c (meta_display_init_window_prop_hooks): add - hooks for _NET_STARTUP_ID - - * src/display.c (event_callback): send property events to - groups. - - * src/xprops.c (meta_prop_get_values): make a type of INVALID - mean to ignore that property (don't fetch its value). - - * src/group.c (meta_group_property_notify): new function - - * src/screen.c (set_supported_hint): support _NET_STARTUP_ID - - * src/display.c (meta_display_open): add _NET_STARTUP_ID to atoms - we initialize - - * src/group-private.h: private header shared between - group-props.c, group.c - - * src/group-props.h, src/group-props.c: new files to contain - functions for retrieving group properties - - * src/window.c (meta_window_same_application): change this a bit - to work with new definition of group - - * src/group.c (meta_window_get_group): always create a group for - every window, using the window's own ID as group leader if - required. - - * src/window.c (update_wm_hints): handle changes to group leader - - * src/group.c (meta_window_group_leader_changed): new function - - * src/display.h (struct _MetaDisplay): _NET_WM_WINDOW_TYPE_SPLASH, - not SPLASHSCREEN. Reported by Gregory Merchan and Matthias Clasen. - - * src/screen.c (startup_sequence_timeout): when timing out a - startup sequence, send a remove message, don't just time it out - locally. - -2002-11-26 Calum Benson - - * src/themes/Crux : - - Removed alpha layers from the pixmaps that don't need them. - Fixes #98389, results in 10-15% speedup on most machines. - -2002-11-26 Glynn Foster - - * configure.in: 2.4.5 - -2002-11-23 Dan Mills - - * Makefile.am: remove theme-format.txt, it's now in doc/. - -2002-11-22 Havoc Pennington - - * src/window.c (meta_window_change_workspace): patch from - Hidetoshi Tajima to move a window's transients when moving - the window between workspaces. #98900 - -2002-11-21 Havoc Pennington - - * src/display.c (meta_display_open): init ret_to to - RevertToPointerRoot out of sheer paranoia; don't want no - RevertToNone in my code! - -2002-11-21 Havoc Pennington - - * src/window.c (update_initial_workspace): delete - (meta_window_new): add getting initial workspace to the batch - property get call - - * src/window-props.c (meta_display_init_window_prop_hooks): add - net_wm_desktop and win_workspace support - -2002-11-20 Havoc Pennington - - * src/window-props.c (set_icon_title): remove unused variable - - * src/screen.c (meta_screen_new): read an existing - _NET_CURRENT_DESKTOP and restore it if set. Makes a restart even - less visible. - - * src/workspace.c (set_active_space_hint): don't set the hint - during the process of unmanaging a screen - -2002-11-20 Havoc Pennington - - * configure.in: add doc/Makefile - - * doc/metacity-theme.dtd: add DTD for themes from Ross Burton - - * doc/Makefile.am: doc subdir - - * doc/theme-format.txt: move to doc subdir - -2002-11-19 Havoc Pennington - - Should really fix #98303 - - * src/prefs.c (meta_prefs_change_workspace_name): add - bad hack to treat empty string the same as null - - * src/menu.c (get_workspace_name_with_accel): allocate one more - than the length of "name" so we have room for a nul byte (and - don't malloc(0) on empty strings). Also some formatting cleanups. - -2002-11-19 Havoc Pennington - - * src/window.c (meta_window_client_message): do a - recalc_window_features after setting new wm_state in order - to update skip_pager in addition to wm_state_skip_pager - (set_net_wm_state): base _NET_WM_STATE on skip_pager not - wm_state_skip_pager, ditto for skip_taskbar - -2002-11-19 Havoc Pennington - - Fix #98303 and assorted cleanup - - * src/prefs.c (meta_preference_to_string): handle - META_PREF_WORKSPACE_NAMES - - * src/menu.c (get_workspace_name_with_accel): assert that the - workspace has a name - - * src/screen.c (meta_screen_ensure_workspace_popup): assert that - we got a workspace name - (meta_screen_ensure_workspace_popup): assert that we got a - workspace name - - * src/prefs.c (update_workspace_name): fix screwiness (strcmp with - a freed string, assorted bad logic) - (init_workspace_names): assert that we filled in a default - workspace name - (meta_prefs_get_workspace_name): assert non-NULL workspace name - -2002-11-16 Bill Haneman - - * src/themes/Atlanta/metacity-theme-1.xml: - Changed outer bevel and focus line color to - work better with inverse themes (no effect on - Default or other existing gtk+ themes). - -2002-11-13 Havoc Pennington - - * src/ui.c (get_cmap): fix a multihead safety thing (use proper - system colormap for the drawable's screen) - -Thu Nov 14 17:30:10 2002 Jonathan Blandford - - * src/Makefile.am (libmetacityinclude_HEADERS): include common.h. - -2002-11-12 Havoc Pennington - - * src/theme.c (draw_op_as_pixbuf): don't read from op->data.image - when the op is an icon - -2002-11-12 Havoc Pennington - - * src/stack.c (meta_stack_get_default_focus_window): never use a - window with input = FALSE take_focus = FALSE as the default focus - window #95454 fix from Hidetoshi Tajima - -2002-11-10 James M. Cape - - * src/themes/Esco/metacity-theme-1.xml: Major changes - to look of theme. I'd also recommend "minimize,maximize:close" - for the button_layout, it looks really slick :-). - -2002-11-08 Mark McLoughlin - - * src/workspace.c: - (meta_motion_direction_to_string), - (meta_screen_corner_to_string): impl for nice debugging. - (meta_workspace_get_neighbor): fix broken logic and - cleanup debugging. - -Thu Nov 7 17:07:21 2002 Jonathan Blandford - - * src/libmetacity-private.pc.in: add a pc file for - libmetacity-private - - * src/Makefile.am: Install a few files as a shared library so that - others can draw metacity themes. - -2002-11-06 Havoc Pennington - - * src/keybindings.c (grab_keys): push an error trap around the - whole window-key-grab loop - (ungrab_all_keys): avoid requiring return value from the error - trap, unless in debugging mode - (regrab_window_bindings, regrab_screen_bindings): push traps - around the loops, for efficiency - - * src/display.c (event_callback): fix from Padraig O'Briain to - compress extra MappingNotify events to avoid extra work. - -2002-11-05 Calum Benson - - * src/themes/Crux/active-restore-button.png: - * src/themes/Crux/inactive-restore-button.png: - * src/themes/Crux/metacity-theme-1.xml: add a restore button - for maximized windows, and un-hard-code titlebar text colors. - Fixes #97759. - -2002-11-05 Havoc Pennington - - * src/workspace.c (meta_workspace_get_neighbor): apply patch from - Nikos Mouat to fix this function - -2002-11-04 Havoc Pennington - - * src/theme.c (scale_and_alpha_pixbuf): fix bug I introduced in - case where scaling was done in both directions. - -2002-11-04 Havoc Pennington - - Patch from Brian Cameron to implement the vertical/horizontal - striped image accelerated scaling from the gtk pixbuf engine. - - * src/theme.c (scale_and_alpha_pixbuf): if an image is - vertical/horizontal stripes, use special extra-fast scaling - routines. - - * src/theme-parser.c (parse_draw_op_element): when loading an - image, mark it as vertically/horizontally striped when appropriate - -2002-11-04 Erwann Chenede - - - * src/xprops.c (meta_prop_get_values): changed __FUNCTION__ - to G_GNUC_FUNCTION as __FUNCTION__ is not portable. - -2002-11-03 Havoc Pennington - - * src/display.c (meta_display_grab): remove XSync calls from here - (meta_display_ungrab): remove XSync from here, but put in - an XFlush to be sure we get the ungrab sent. - - * src/util.c (meta_topic): track sync count here - - * src/errors.c: move sync count out of here - - Throughout: error spew on all XSync() calls - - * src/run-metacity.sh: don't set METACITY_DEBUG - -2002-11-03 Havoc Pennington - - * src/window-props.c (meta_display_init_window_prop_hooks): add - _NET_WM_NAME, WM_NAME, _NET_WM_ICON_NAME, WM_ICON_NAME support - - * src/window.c (meta_window_new): use window-props.h for - _NET_WM_NAME, WM_NAME, _NET_WM_ICON_NAME, WM_ICON_NAME - -2002-11-03 Havoc Pennington - - * src/window.c (meta_window_new): use window-props.h stuff for a - couple of properties - (implement_showing): fix printf string - - * src/xprops.c (meta_prop_free_values): new function - - * src/window-props.h, src/window-props.c: start moving code that - handles loading window properties into this file. - -2002-11-03 Havoc Pennington - - * src/stack.c (create_constraints): filter out windows that aren't - in the stack for whatever reason, avoids a crash - -2002-11-03 Havoc Pennington - - * src/window.c (meta_window_calc_showing): split into "see if we - should be showing" and "actually show/hide" functions - (idle_calc_showing): rework to first unmap all newly-hidden - windows from bottom to top then map all newly-showing windows from - top to bottom resulting in fewer exposes, #95220 - -2002-11-03 Havoc Pennington - - * src/theme.c (meta_frame_layout_calc_geometry): fix from Garrett - LeSage for which button backgrounds we draw when - -2002-11-03 Havoc Pennington - - * src/workspace.c (meta_workspace_get_name): new function, - and remove workspace->name field, instead just get the - name from prefs each time - - * src/screen.c (meta_screen_update_workspace_names): update the - gconf key to persist workspace names here, instead of changing - the names we use - - * src/util.c (topic_name): add META_DEBUG_PREFS - - * src/prefs.c: change NUM_COMMANDS to 32 to allow more custom - commands, implement workspace names - - * src/metacity.schemas.in: add workspace_names/name_NN gconf keys. - -2002-11-01 Christian Neumair - - * configure.in: We want at least autoconf 2.5. - -2002-10-29 Havoc Pennington - - * configure.in: 2.4.3, why not - -2002-10-28 Havoc Pennington - - * src/window.c (update_size_hints): use meta_prop_get_size_hints - - * src/xprops.c: add support for getting XSizeHints - -2002-10-28 Havoc Pennington - - * src/window.c, src/display.c: store the window menu on the - display and blow it away when a window closes, so we don't - get funny stuck menus. Patch from Martin Garton #87514 - -2002-10-27 Anders Carlsson - - * configure.in: Make XRandr detection work better. - -2002-10-27 Havoc Pennington - - * src/window.c (meta_window_free): move - meta_window_shutdown_group() much earlier in the destroy process. - May fix #96928 tracked down by Kjartan Maraas and Martin Garton. - - * src/group.c (meta_window_get_group): never add window to a group - after we've started unmanaging the window - -2002-10-26 Havoc Pennington - - * src/iconcache.c: include config.h - - * src/group.c: include config.h - - * src/frame.c: include config.h - - * src/core.c: include config.h so it doesn't crash all over the - place due to #ifdef HAVE_STARTUP_NOTIFICATION - - * src/util.c (meta_print_backtrace): export from this file - - * src/main.c (log_handler): print backtrace here - -2002-10-26 Havoc Pennington - - * src/wm-tester/main.c (evil_timeout): make windows randomly - transient for each other http://bugzilla.gnome.org/show_bug.cgi?id=96928 - -2002-10-26 Havoc Pennington - - * src/xprops.c (meta_prop_get_text_property): new function - (meta_prop_get_wm_hints): new function - (meta_prop_get_class_hint): new function - -2002-10-26 Havoc Pennington - - * src/window.c (meta_window_new): use multi-value-get on a couple - of properties for testing - - * src/xprops.c (meta_prop_get_values): implement multi-value-get - - * src/window.c (update_mwm_hints): XFree motif hints as we changed - it to use Xmalloc - - * src/xprops.c: massively rework this to set up a - get-multiple-properties-at-once API. - - * src/async-getprop.c (ag_Xmalloc): new function - -2002-10-25 Havoc Pennington - - Add "busy cursor on app startup" support, conditionally - works - only if libstartup-notification is found, and in practice requires - a GTK patch that's not in yet. - - * src/screen.c: monitor startup events and set busy cursor if - appropriate - - * src/display.c (meta_display_open): create SnDisplay - - * configure.in: check for startup notification, - and add the cute "configure summary" at the end - -2002-10-24 Havoc Pennington - - * src/theme.c (meta_frame_layout_calc_geometry): if only one - right-corner button, use right_right_background not - right_left_background - -2002-10-24 Havoc Pennington - - * src/window.c (meta_window_get_icon_geometry): make public - - * src/screen.c (meta_screen_ensure_tab_popup): put the alt+tab - highlight-window indicator on the icon, not the window itself, - if the window is minimized. - -2002-10-24 Havoc Pennington - - * src/display.c (meta_display_get_tab_list): put minimized windows - at the end of Alt+Tab, #89416 - -2002-10-23 Havoc Pennington - - * src/theme.c (meta_frame_layout_calc_geometry): initialize the - left button background rectangles. - -2002-10-21 Havoc Pennington - - Optimizations for managing new windows (do not all take effect if - METACITY_DEBUG=1). Bug #96404 - - * src/keybindings.c (meta_change_keygrab): use error trap nesting - and conditionalize on meta_is_verbose() to avoid a ton of XSync - - * src/display.c (meta_change_button_grab): ditto - - Throughout: move to new error trap setup to save on XSync calls, - new setup is: - - * src/errors.c (meta_error_trap_push_with_return): new function, - an error trap that needs to care about return value and thus - sync even if an outer trap still exists - (meta_error_trap_pop_with_return): new function - (meta_error_trap_pop): add "last_request_was_roundtrip" - argument allowing us to avoid XSync() if we just did - a GetProperty or whatever. - - * src/util.c (meta_warning): flush the warning file descriptor - - * src/Makefile.am (INCLUDES): define G_LOG_DOMAIN - -2002-10-20 Havoc Pennington - - * src/ui.c (meta_image_window_new): put multihead stuff in - HAVE_GTK_MULTIHEAD, reported by John Palmieri - -2002-10-20 Havoc Pennington - - * src/keybindings.c (handle_raise_or_lower): check above->mapped - before deciding if it overlaps the window being raiselowered, - fix from Stephane Chauveau - -2002-10-19 Jeremy Katz - - * configure.in: make Xrandr check less noisy - -2002-10-18 Havoc Pennington - - * src/effects.c (meta_effects_draw_box_animation): call - meta_image_window_new in multihead-safe way - - * src/ui.c (meta_image_window_new): multihead safety - -2002-10-18 Havoc Pennington - - * src/window.c (meta_window_refresh_resize_popup): only create the - resize popup if width_inc or height_inc are > 1 - - * src/resizepopup.c: Clear out all the weird tickmark cruft, - saves us about 2.5K of binary size, whee - (meta_ui_resize_popup_new): take display/screen arguments and make - multihead-safe #94349 - -2002-10-18 Havoc Pennington - - * src/keybindings.c (do_choose_window): don't start the cycle - process if the binding for switching windows has no modifier bits, - just focus the window immediately. - - * src/prefs.c, src/keybindings.c: add a keybinding to move between - windows that goes in the opposite direction. This is mostly - useful if you want to bind unmodified keys to the switch windows - functions, e.g. if you have "Forward" and "Back" keys on your - keyboard. Patch from Shilad Sen - -2002-10-18 Havoc Pennington - - * src/prefs.c, src/frames.c: add "what happens when you double - click the titlebar" setting, patch from Sean Middleditch bug - #95625. This is basically an "add Windows emulation mode" patch. - -2002-10-18 Havoc Pennington - - * src/metacity.schemas.in: move window-click to Super+click not - Alt+click by default. Super should be the Windows key on keyboards - that have one and are so configured. Prepare for the FAQ on this. - -2002-10-18 Havoc Pennington - - * src/window.c (constrain_size): fix min aspect handling, - patch from Martin Garton #94943 - -2002-10-18 Andras Timar - - * configure.in: Added hu to ALL_LINGUAS. - -2002-10-18 Havoc Pennington - - * src/stack.c (constrain_stacking): replace the old - apply_constraints with wacky new approach involving graphing all - the constraints then walking the graph. Fixes #94876 and probably - other stacking bugs as well, thanks to Arvind for tracking down - the issue. - - (compute_layer): add FIXME and reference to bug #96140 - -2002-10-17 Havoc Pennington - - * src/stack.c (apply_constraints): don't place - transient-for-whole-group windows above _each other_, only - above other windows in the group that aren't themselves - transient-for-whole-group. Should help with part of #94876 - -2002-10-17 Havoc Pennington - - * src/stack.c (apply_constraints): fix memory leak of - group_windows, and don't use the variable name "tmp" twice. Shadow - variables bad. - -2002-10-17 Havoc Pennington - - * src/tools/metacity-window-demo.c (dialog_cb): add code to create - big stacks of dialogs transient for each other, for testing. - -2002-10-16 Havoc Pennington - - * src/workspace.c: workspaces are all per-screen now, fix - accordingly - - * src/core.c: fix multihead workspace stuff - - * src/keybindings.c: multihead-rama - - * src/screen.c (meta_screen_show_desktop): new functions to - replace display equivalents - - * src/display.c (meta_display_get_workspace_by_screen_index): get - rid of this - (meta_display_get_workspace_by_index): get rid of this - (event_callback): handle _NET_SHOWING_DESKTOP message per-screen - - * src/screen.c (meta_screen_get_workspace_by_index): new function - - * src/screen.h (struct _MetaScreen): move workspace list, and - showing_desktop flag, to be per-screen - - * src/window.c (window_query_root_pointer): return whether pointer - is on window's screen - (meta_window_handle_mouse_grab_op_event): don't use coordinates - from other screens when updating a window operation on the current - screen. I can't believe no one has reported this... - -2002-10-16 Havoc Pennington - - * src/window.c (meta_window_client_message): update window layer - when above/below state is changed. Fixed by Ross Burton. - -2002-10-14 Federico Mena Quintero - - * src/display.c (event_callback): Ignore EnterNotify events when - the detail field is set to NotifyInferior. Fixes #95747. - -2002-10-12 Havoc Pennington - - * src/metacity.schemas.in: button layout key - - * src/prefs.c: Add button layout gconf key - (change_notify): use some "else if" instead of "if" where we - should have been - -2002-10-11 Havoc Pennington - - * src/display.c (event_callback): don't raise window on button 2 - click, only on button 1 and button 3. - - * src/frames.c (meta_frames_button_press_event): lower on button 2 - press on frame - - * src/core.c (meta_core_user_lower): new function - -2002-10-11 Havoc Pennington - - * src/stack.c (window_is_fullscreen_size): make the checks here - allow windows larger than the screen in addition to - exactly-screen-size - - * src/window.c (meta_window_configure_request): delete the "try to - auto-enter-fullscreen-state" hack here, because it was broken, and - the changes to the stacking code to move screen-size focused - windows to the fullscreen layer should work better. - (meta_window_new): remove auto-fullscreen hack from here too - -2002-10-09 Havoc Pennington - - * src/stack.c (apply_constraints): also keep utility/menu/toolbar - windows above their whole group. - - (get_standalone_layer): don't use META_LAYER_FOCUSED_WINDOW, but - only use META_LAYER_FULLSCREEN while the fullscreen window has - focus. Also, put screen-sized windows in the fullscreen layer, - even if we didn't dare to actually put them in the fullscreen - state. - -2002-10-07 Havoc Pennington - - Add a modifier key preference for the Alt+click stuff. - Can be set to "disabled" as well. - - * src/run-metacity.sh: load .Xmodmap in the Xnest if it exists - - * src/display.c (meta_display_ungrab_window_buttons): ungrab - AnyModifier in case the modifier changed since we grabbed - (meta_display_open): rearrange code to use meta_display_close() to - mop up when we can't find any screens, avoiding the need to - keep the bail-out code in sync with meta_display_close. - - * src/keybindings.c (devirtualize_modifiers): move this function - to a public place in display.c - - * src/metacity.schemas.in: add setting for the modifier key - to use for Alt+left/middle/right click. - - * src/prefs.c (update_binding): add a missing newline to a warning - (meta_prefs_get_mouse_button_mods): new function - - * src/ui.c (meta_ui_parse_modifier): new function - -2002-10-07 Havoc Pennington - - * src/async-getprop.c: don't include unportable Xproto.h, fix from - Glynn Foster. - -2002-10-06 Havoc Pennington - - * src/async-getprop.c: change to add only one _XAsyncHandler per - display, speeding things up a bit. - -2002-10-06 Havoc Pennington - - * src/async-getprop.c: Add wacky hack suggested by Keith Packard - to get X properties asynchronously. Not actually used by metacity - yet, but thinking about it. - -2002-10-04 Havoc Pennington - - * configure.in: actually link to RANDR_LIBS - -2002-10-04 Havoc Pennington - - * src/display.c (event_callback): do XRRUpdateConfiguration() - if we have RandR extension, else poke in Xlib's screen struct to - update the screen size. - - * configure.in: fix a bogus overwrite of cppflags, - add a check for RandR extension - -2002-10-04 Arvind Samptur - - * src/window.c (meta_window_change_workspace): call - meta_window_unstick before adding window to workspace. - (menu_callback): call meta_workspace_activate before - meta_window_change_workspace. This would avoid us running an - extra loop for determining the window workspace list. - - Patches from Jeyasudha and Arvind. Fixes #92575 - -2002-10-03 Havoc Pennington - - * src/themes/Esco/metacity-theme-1.xml: only specify the - middle backgrounds, let left/right fall back to middle - - * src/theme.c (get_button): fall back to middle_background draw - routines when missing the left/right button backgrounds. - (button_rect): fix to handle drawing middle button backgrounds - (meta_frame_style_draw): draw middle background once per middle - button - -2002-10-03 Havoc Pennington - - Button-reordering patch. Has all the code except actually - installing a gconf schema and reading the gconf key in prefs.c. - metacity-theme-viewer displays the button layouts for testing - themes. - - * src/preview-widget.c (meta_preview_size_request): make up a - width/height if no child widget - - * src/prefs.c (meta_prefs_get_button_layout): new function - - * src/frames.c: get the button layout from prefs and - use it when drawing - - * src/theme.c (meta_frame_layout_calc_geometry): enhance to be - able to lay out buttons in different arrangements - (button_rect): draw the new button background rectangles - (meta_theme_draw_frame): require a button layout argument - (meta_theme_calc_geometry): pass in the button layout - - * src/preview-widget.h: mod to handle button layouts - - * src/theme-viewer.c: mod to handle button layouts - -2002-10-03 Havoc Pennington - - * configure.in: 2.4.2 - -2002-10-03 Havoc Pennington - - * src/window.c (check_moveresize_frequency): handle the case where - the clock is set backward - -2002-10-01 Havoc Pennington - - * src/place.c (find_next_cascade): try extra cascades alongside - the first, if the first fails; patch from readams@hmc.edu - -2002-10-01 Havoc Pennington - - * src/stack.c (get_standalone_layer): put ABOVE windows in same - layer as docks. - -2002-10-01 Havoc Pennington - - * src/screen.c (meta_screen_resize_func): make it static - - * src/stack.c (get_standalone_layer): put above/below windows - in an appropriate layer. - - * src/screen.c (set_supported_hint): say we support above/below - - * src/display.h (struct _MetaDisplay): add _NET_WM_STATE_ABOVE, - _NET_WM_STATE_BELOW atoms - - * src/window.c (meta_window_client_message): handle above/below - state messages - (set_net_wm_state): handler above/below state - (update_net_wm_state): handle above/below states - -2002-10-01 Mark McLoughlin - - * src/screen.c: (meta_screen_new): default to - topleft starting corner. - (meta_screen_update_workspace_layout): handle - new property format : orient,x,y,starting corner. - Fixes #89373. - - * src/screen.h: add MetaScreenCorner enum. - -2002-10-01 Havoc Pennington - - * src/window.c (constrain_position): always align fullscreen - windows to top, as we do with maximized windows. - -2002-10-01 Stanislav Brabec - - * configure.in: Added cs to ALL_LINGUAS. - -2002-09-30 Havoc Pennington - - * src/screen.c (reload_xinerama_infos): fix compilation on - Solaris, patch from Satyajit Kanungo - -2002-09-29 Havoc Pennington - - * src/eggaccelerators.c: update from libegg to get fix from Ralph - Loader for parsing, #93005 - -2002-09-29 Havoc Pennington - - * src/effects.h (META_MINIMIZE_ANIMATION_LENGTH): shorten minimize - animation a bit - -2002-09-28 Havoc Pennington - - Patch from Keith Packard to handle root window resizes. - - * src/screen.c (reload_xinerama_infos): factor out Xinerama code - (meta_screen_resize): implement this, to be called from display.c - on screen resize - - * src/display.c (event_callback): handle ConfigureNotify on root - windows - -2002-09-28 Havoc Pennington - - * src/stack.c (get_standalone_layer): re-enable the FOCUSED_WINDOW - layer, should now work correctly. - -2002-09-28 Havoc Pennington - - * src/window.c, src/stack.c: Rewrite stack code to work a lot - differently. Should be better now, and not lose relative positions - of windows when moving among layers. Also should now be possible - to get session management to restore the stacking order. Probably - breaks some stuff, and makes all the stack.c changes I made - yesterday sort of irrelevant. - -2002-09-27 Havoc Pennington - - * src/stack.c (get_standalone_layer): Temporarily disable use of - the FOCUSED_WINDOW layer, because given the fact that moving - multiple windows into the same layer changes the Z-order of those - windows, it was breaking click-to-focus. - -2002-09-27 Havoc Pennington - - * src/screen.c (meta_screen_focus_top_window): raise the focused - window, since it may not be the window on top, given the below - change. - - * src/stack.c (meta_stack_get_default_focus_window): make this - more complex to prefer to focus the transient parent, followed by - other windows in group, followed by topmost non-dock, followed by - dock. Previously was just topmost non-dock followed by dock - ignoring groups and transiency. - -2002-09-27 Havoc Pennington - - * src/place.c (constrain_placement): constrain placement to try to - keep windows from going offscreen to the right/bottom - - * src/stack.c (compute_layer): rearrange the logic here to say - that a window must always be in at least as high a layer as any of - its transient parents or group members, rather than special-casing - fullscreen. Also, group_member_is_fullscreen was leaking the list - of group members every time, a fairly major memory leak. - -2002-09-27 Havoc Pennington - - * src/themes/Makefile.am (THEMES): use AgingGorilla not Gorilla - (renamed on the CVS server) - -2002-09-27 Havoc Pennington - - Try to handle Solaris Xinerama, all coded blind, someone - on Solaris will need to debug the typos. - - * src/display.c: updates for Solaris Xinerama - - * src/screen.c: updates for Solaris Xinerama - - * configure.in: make Xinerama check more complicated to catch - Solaris Xinerama - -2002-09-27 Havoc Pennington - - * src/window.c (update_transient_for): keep a flag - transient_parent_is_root_window for whether the - root-window-as-parent convention was used. - -2002-09-25 Arvind Samptur - - * src/stack.c (sort_window_list): Keep dialogs without - transient parent above entire app. Fixes #88926 - -2002-09-26 Havoc Pennington - - * src/menu.c (meta_window_menu_new): use MetaAccelLabel to display - accelerators for the menu items - - * src/metaaccellabel.c: cut-and-paste GtkAccelLabel and port to - use virtual modifiers - - * src/Makefile.am (metacity_SOURCES): add metaaccellabel.[hc] - - * src/prefs.c (meta_prefs_get_window_binding): new function - - * src/core.c (meta_core_get_menu_accelerator): new function - -2002-09-25 Havoc Pennington - - * src/metacity.schemas.in: Change short desc of switch_windows and - cycle_windows to be different - -2002-09-24 Havoc Pennington - - * src/place.c (fit_rect_in_xinerama): update best_overlap as we go - through the loop - doh. Fix from readams@hmc.edu for #90799. - (find_first_fit): try the origin of each xinerama screen - after the first. Also from readams@hmc.edu - -2002-09-24 Havoc Pennington - - * src/window.c (meta_window_save_rect): new function, - only saves rect after checking current state, #93795 - (meta_window_make_fullscreen): use new function - (meta_window_maximize): use new function - -2002-09-24 Havoc Pennington - - * src/window.c (meta_window_update_layer): new function - - * src/stack.c (compute_layer): put focused window in a layer above - all other windows, in click-to-focus mode. #93022 - - * src/window.c (meta_window_notify_focus): update window layer on - focus change. - -2002-09-24 Havoc Pennington - - * src/main.c (main): support --version, #92796 patch from - Christian Neumair - - * autogen.sh: change gettext test to be happy with - glib-gettextize, #81425 - - * src/menu.c: change mnemonics to match bug #78999 - - * src/theme.c (meta_theme_validate): consolidate some - nearly-identical themes for ease of translation, #70962 - -2002-09-24 Arvind Samptur - - * src/menu.c: Replace strings Shade with Roll Up and - Unshade with Unroll. - -2002-09-23 Havoc Pennington - - * src/main.c (main): re-enable the log handler, maybe it will - break something, I don't remember why I turned it off. - - * src/display.c: s/_NET_SHOW_DESKTOP/_NET_SHOWING_DESKTOP/ which - is what's in the spec - -2002-09-22 Havoc Pennington - - * src/window.c (recalc_window_features): small reordering of - code - - * src/display.c (meta_spew_event): more spew for MapNotify, - UnmapNotify - - * src/window.c (recalc_window_features): spew more stuff - - * src/display.c (meta_spew_event): spew override_redirect field of - ConfigureNotify - -2002-09-20 Arvind Samptur - * src/metacity.schemas.in: added keybindings for - moving windows between workspaces. - - Patch from Jeyasudha. Fixes #91944. - -2002-09-19 Arvind Samptur - * src/tools/metacity-properties.desktop.in : - change in the tooltip suggested in ui-review. - -2002-09-18 Havoc Pennington - - * src/window.c (update_net_wm_state): handle fullscreen state - here. - -2002-09-15 Havoc Pennington - - * src/session.c (save_state): escape the window title before - saving in the session file, reported by Jos Vos - -2002-09-12 Havoc Pennington - - * src/workspace.c (meta_workspace_screen_index) - (meta_workspace_index): fix compiler warnings - - * src/tools/metacity-window-demo.c (menu_items): add a test for - dialogs with no transient parent - - * src/place.c (find_first_fit): Try placing window at origin of - first Xinerama, even if there are no windows to place next to; - makes placement work when no other windows are open on the screen. - -2002-09-09 Havoc Pennington - - * configure.in: 2.4.1 - -2002-09-09 Christian Neumair - - * src/keybindings.c: Make virtual desktops apply - instantly and still show the pager popup by - Benjamin Kahn , fixes #86590. - -2002-09-06 Frederic Crozat - - * src/themes/Crux/metacity-theme-1.xml: Fix titlebar - glitch on small dialogs. - -2002-09-06 Arvind Samptur - * theme-format.txt : corrected some of the attributes - which were not in sync with theme-parser.c - Patch from Jim Bowen. #92057. - -2002-09-05 Havoc Pennington - - * configure.in: put ro back in ALL_LINGUAS - -2002-09-05 Havoc Pennington - - * configure.in (ALL_LINGUAS): remove 'ro' from ALL_LINGUAS, it - contained invalid XML and broke the build. No <> in the - translations of gconf keys! - -2002-09-04 Marius Andreiana - - * configure.in: added 'ro' to ALL_LINGUAS - -2002-09-03 Havoc Pennington - - * src/display.c (meta_display_get_tab_current): new function - - * src/keybindings.c (do_choose_window): apply modified patch from - JeyaSudha to still display tab popup if only one window is on the - desktop. - -2002-06-25 JeyaSudha - - * src/session.c, src/window.c: Session saves the unmaximized - postion, size of a maximized window. #86059 - -2002-09-03 Havoc Pennington - - * src/frames.c (meta_frames_update_prelit_control): don't filter - out prelight for unmaximize button. #83860 - (meta_frames_paint_to_drawable): handle unmaximize here as well - -2002-08-27 Havoc Pennington - - * src/theme.c (meta_frame_layout_calc_geometry): always apply - rounding for shaded windows, fixes Bluecurve theme when shaded - -2002-08-25 Havoc Pennington - - * src/window.c (meta_window_free): when freeing a fullscreen - window, update layers of the window's group. - -2002-08-25 Havoc Pennington - - * src/display.c (meta_display_open): _NET_SUPPORTING_WM_CHECK is - supposed to have type WINDOW not CARDINAL. reported by - Ben Jansens - -2002-08-24 Havoc Pennington - - * src/window.c (process_property_notify): recalculate mapped-ness - of frame after toggling decorations on/off, so that windows don't - disappear when decorations are toggled on. - - * src/tools/metacity-window-demo.c (toggle_decorated_cb): add a - test for toggling decoration state on the fly - -2002-08-24 Havoc Pennington - - * src/window.c (update_sm_hints): hack around bug in kmail etc. - where SM_CLIENT_ID was set on the window, not the client leader. - - * src/theme.c (meta_frame_layout_calc_geometry): don't round - corners unless we have enough frame to chop off. - -2002-08-24 Havoc Pennington - - * src/util.c: translate some strings that should have been, and - convert to locale encoding before printing stuff. - - * src/stack.c (group_member_is_fullscreen): if window itself is - fullscreen, return TRUE immediately. - - * src/window.c (meta_window_configure_request): add hack to - fullscreenize large undecorated windows. - -2002-08-21 Deepa Natarajan - - * src/keybindings.c, src/metacity.schemas.in, src/prefs.[ch]: - add maximize and unmaximize keybinding setting. Partly fixes - bug# 78999. - -2002-08-20 Steve Fox - - * metacity.spec.in: Add so that the spec file gets auto-updated - whenever configure.in gets bumped. Include some missing - directories. - - * Makefile.am - * configure.in: Necessary changes for spec file magic - -2002-08-20 Havoc Pennington - - * src/frames.c (get_control): if in the title rect check for y - <= TOP_RESIZE_HEIGHT - - * src/display.c (meta_spew_event): put x/y coordinates in spew for - enter/leave notify - - * src/frames.c (meta_frames_motion_notify_event): move cursor - changing from here to update_prelit_control so it happens on enter - notify as well - (get_control): change test "y < TOP_RESIZE_HEIGHT" to - "y <= TOP_RESIZE_HEIGHT" - - * src/Makefile.am (EXTRA_DIST): include .in files in EXTRA_DIST - -2002-08-17 Simos Xenitellis - - * configure.in (ALL_LINGUAS): Added Greek (el). - -2002-08-17 Evandro Fernandes Giovanini - - * configure.in (ALL_LINGUAS): Added Brazilian Portuguese (pt_BR). - -2002-08-15 Havoc Pennington - - * src/metacity.schemas.in: default to "Sans Bold 10" for the - titlebar font. - -2002-08-15 Havoc Pennington - - * src/window.c (recalc_window_features): leave has_fullscreen_func - set to TRUE if the window is screen sized and undecorated, even if - the window isn't resizable. idea from Christian - Manny Calavera - - Neumair - - * src/keybindings.c (handle_toggle_fullscreen) - (handle_toggle_maximize): these disabled fullscreen/maximize if - the window wasn't resizable, should have used has_fullscreen_func - has_maximize_func instead. - -2002-08-15 Havoc Pennington - - * src/keybindings.c: implement raise/lower - - * src/metacity.schemas.in: add raise/lower - - * src/prefs.c: add "raise" and "lower" prefs to keybindings - - * src/display.c (meta_display_set_grab_op_cursor): assert that - the screen arg is non-NULL in appropriate cases - -2002-08-14 Jayaraj Rajappan - - * src/display.c (meta_display_set_grab_op_cursor): - In XGrabPointer, set the confine_to argument to the root window - of the screen the window is on. - - * src/display.h: add screen argument. - - * src/window.c (meta_window_update_resize_grab_op): - pass screen argument as NULL. - -2002-08-14 James M. Cape - - * src/themes/Esco/metacity-theme-1.xml: use button positioning - theme stuff. - -2002-08-14 Mark McLoughlin - - * src/screen.c: (set_number_of_spaces_hint), move from - workspace.c. - (update_num_workspaces): set the hint here. Fixes #90123. - - * src/workspace.c: - (meta_workspace_new), (meta_workspace_free): don't set - the hint here. - (update_num_workspaces): move to screen.c - -2002-08-12 Havoc Pennington - - * src/stack.c (compute_layer): window is in fullscreen layer if - any member of its group is fullscreen - - * src/window.c (meta_window_unmake_fullscreen): update layer for - whole window group - (meta_window_make_fullscreen): ditto - - * src/util.c (meta_unsigned_long_hash): move hash/equal funcs for - Window in here. - - * src/group.c: track window groups so we can do stuff with them. - -2002-08-11 Havoc Pennington - - * src/menu.c: don't include nonexistent stock-icons.h file - -2002-08-10 Havoc Pennington - - * src/metacity.schemas.in: default keybindings for move, resize, - maximize, etc. from Deepa #78999 - -2002-08-10 Havoc Pennington - - * src/window.c (meta_window_maximize): unshade window if shaded, - from JeyaSudha - (meta_window_make_fullscreen): ditto - -2002-08-10 Havoc Pennington - - * src/menu.c: reorder the menu items so that Close is at the - bottom - - * src/theme-viewer.c (main): set debugging mode if METACITY_DEBUG - enabled - -2002-08-10 Havoc Pennington - - * src/xprops.c (meta_prop_get_motif_hints): allow Motif hints to - be smaller than expected; GLUT for example seems to set a smaller - struct. #89841 - - * src/window.c (update_mwm_hints): use g_free on motif hints as we - don't use the XGetWindowProperty return directly anymore - -2002-08-10 Havoc Pennington - - * src/window.c (meta_window_free): be sure window is - mapped if we unmanage it and it's not withdrawn; - bug #90369 - - * src/screen.c (meta_screen_new): change string - s/override/replace/ bug #89077 - - * src/theme.c (scale_and_alpha_pixbuf): dump the - sometimes-use-NEAREST-instead-of-BILINEAR optimization, - bug #87489 - -2002-08-10 Havoc Pennington - - * src/window.c (menu_callback): raise window when moving to - another workspace bug #88896 - - * src/keybindings.c (switch_to_workspace): raise window when - moving between spaces - -2002-08-10 Jorn Baayen - - Register window menu icons with the Gtk stock system, instead - of using the ones from the Metacity theme (which looked very bad with - some themes). - - * src/Makefile.am: - * src/main.c: - * src/menu.c: - * src/stock_delete.png: added these files - * src/stock_minimize.png: - * src/stock_maximize.png: - * src/ui.c - -2002-08-10 Havoc Pennington - - * src/keybindings.c (meta_display_process_key_event): filter out - key events that happen on popup menus etc. - - * src/ui.c (meta_ui_window_is_widget): new function to check - whether a window belongs to a GtkWidget such as the popup menu - - * src/prefs.c (change_notify): put in a no-op line for AIX - compiler, #84252 - -2002-08-10 Havoc Pennington - - * src/window.c (update_resize): track time to avoid sending a - deluge of move/resize requests, suggestion from - xavier.bestel@free.fr bug #86830. Not really sure if this will - make a difference or not. We'll see I guess. - (update_move): do same on move though it seems less important - here. - - * src/display.h (struct _MetaDisplay): store the - last time we sent a move/resize event. - -2002-08-10 Havoc Pennington - - * src/window.c (meta_window_notify_focus): add a FIXME comment - with a link to bug #90382 - -2002-08-09 Havoc Pennington - - * src/keybindings.c (handle_toggle_maximize): disable maximize, - fullscreen, shade via keybindings on windows that don't support - it. - -2002-08-08 Craig Black - - Patch to provide extra cues when using the window menu - move and resize items, #85724. - - * src/common.h: add new cursors - - * src/display.c: (grab_op_is_mouse) - (meta_display_create_x_cursor), (xcursor_for_op), - (meta_display_set_grab_op_cursor), - (meta_display_begin_grab_op): - The keyboard move and resize grab ops now also use the mouse. - Allow the grab cursor to be changed during the grab op. - Hold onto the initial grab position in case of reset. - - * src/display.h: save the initial grab position - - * src/keybindings.c: (process_keyboard_move_grab), - (process_keyboard_resize_grab), (handle_begin_move), - (handle_begin_resize): - The keyboard move and resize grab ops now also use the mouse. - - * src/window.c: (meta_window_client_message), (menu_callback), - (update_move), (update_resize), - (meta_window_handle_mouse_grab_op_event), (warp_pointer), - (meta_window_warp_pointer), (meta_window_begin_grab_op), - (meta_window_update_resize_grab_op): - When moving or resizing a window use the last grab position - in computing change increment. - Provide support for warping the mouse pointer. - - * src/window.h: new warp pointer and grab op helper functions - -2002-08-08 Craig Black - - * src/display.h: update comment - * src/window.c: (meta_window_focus): also set expected - focus window when setting input focus. - -2002-08-07 Craig Black - - * src/display.c: (meta_display_unshow_desktop): focus - top window after showing desktop, fixes #88080. - -2002-08-07 Craig Black - - * src/core.c: (meta_core_show_window_menu): focus window - on right click for menu, #87299. - -2002-08-07 Craig Black - - * src/display.c: (meta_display_open): clear expected focus window - on open - - * src/display.h: add expected_focus_window field - - * src/window.c: (meta_window_make_fullscreen), - (meta_window_unmake_fullscreen): change meta_window_update_layer() - to meta_stack_update_layer() so build works again. - (meta_window_free), (meta_window_make_fullscreen), - (meta_window_focus), (meta_window_notify_focus): keep track of - expected focus window after sending WM_TAKE_FOCUS event, - previously if a UnmapNotify event arrived before the FocusIn event - we would lose focus, fixes #84564. - -2002-08-07 Havoc Pennington - - * src/window.c (meta_window_unmake_fullscreen): update layer - (meta_window_make_fullscreen): update layer - - * src/stack.c (compute_layer): put window on fullscreen layer if - fullscreen - -2002-08-06 Craig Black - - * src/window.c: (meta_window_client_message): implement - _NET_WM_MOVERESIZE enhancements, see #90077. - -2002-08-06 Havoc Pennington - - * configure.in: 2.4.0 (this version number has no special - significance, just didn't want to go to 4-digit micro version ;-) - -2002-07-28 Havoc Pennington - - * src/window.c (meta_window_shade): disable animation when shading - windows, just doesn't really convey the idea anyway. - - * src/effects.c: Move to using a shaped window instead of - IncludeInferiors to do the animations, looks a lot better - because we don't have to grab the server. - - * src/window.c (meta_window_change_workspace): remove bogus - assertion that was causing a crash - (meta_window_new): auto-fullscreen huge undecorated windows. - - * src/keybindings.c (switch_to_workspace): use - meta_window_change_workspace() to avoid same bug in cut-and-paste - code from there - -2002-08-06 He Qiangqiang - - * configure.in: Added "zh_CN" to ALL_LINGUAS. - -2002-08-05 Ross Burton - - * src/window.c: (meta_window_client_message): Set - ->wm_state_skip_pager (ditto for _taskbar) instead of ->skip_pager - so that these hints actually work. Fixes #89850. - -2002-08-04 Havoc Pennington - - * src/frames.c (meta_frames_paint_to_drawable): init button - states for the button backgrounds - - * src/themes/Atlanta/metacity-theme-1.xml: adapt to work correctly - with button repositioning - -2002-08-04 Havoc Pennington - - * src/frames.c (meta_frames_button_press_event): raise/focus - on click, even if the click was on the client area - (this makes Alt+button1 raise windows again, yay) - - * src/stack.c (compute_layer): put panels in the DOCK layer always - (keep them on top of other windows). Still sloppy-focus raised - with respect to other docks. - - * configure.in: remove -Wshadow for now as GTK headers make all - kinds of noise with it. - -2002-08-02 Mark McLoughlin - - * src/screen.c: (meta_screen_new): set active_workspace - to NULL. Also actually activate the first workspace instead - of just setting active_workspace. Fixes #87367. - (meta_screen_ensure_workspace_popup): don't re-use our - iterator for setting the entries list, stop iterating - when we've gone beyond the last workspace (there may - be empty spaces in the last row). - - * src/workspace.c: (meta_workspace_activate): if no workspace - was previously activated, return. - -2002-08-04 Havoc Pennington - - * src/theme.c (free_menu_ops): use MetaMenuIconType not button - type for the size of the menu ops array - (meta_theme_define_int_constant): return TRUE on success (how the - heck did this ever work?) - (meta_theme_define_float_constant): return TRUE on success - (meta_frame_style_validate): allow the "positional" buttons to - be omitted for now. - - * src/testgradient.c (render_multi): don't define N_COLORS twice - - * src/theme-viewer.c (run_theme_benchmark): don't define - ITERATIONS twice - - * src/theme.c (button_rect): handle new button types - (meta_button_type_to_string): update - (meta_button_type_from_string): update - - * src/theme.h (enum): add button types for the 6 possible button - positions. No way to reposition buttons still but this will allow - themes to go ahead and support doing so. - -2002-08-03 Craig Black - - * src/keybindings.c: (meta_display_process_key_event), - (process_tab_grab), (do_choose_window): change alt+tab to a - windowless grab, fixes #83499 - -2002-08-03 Craig Black - - * src/display.c: (event_callback): Have ButtonPress and - UnmapNotify events account for a null grab window, fixes #87896 - -2002-08-03 Gaute Lindkvist - - Corrected some issues with the Bright theme. Mainly - making sure the text does not clip, as well as increasing - the size of the menu icon. - -2002-08-01 Mark McLoughlin - - Implements support for _NET_WM_ALLOWED_ACTIONS. - Fixes #84282. - - * src/display.[ch]: (meta_display_open): add - _NET_WM_ALLOWED_ACTIONS atoms. - - * src/screen.c: (set_supported_hint): set them - as being supported. - - * src/window.c: - (set_allowed_actions_hint): impl setting - _NET_WM_ALLOWED_ACTIONS. - (recalc_window_features): use it here, but only - if things have changed. - -2002-08-01 Christophe Fergeau - - * src/metacity-dialog.c: focus the "Close" button by default on - the dialog which appears at exit when some apps can't be session - managed - -2002-08-01 Mark McLoughlin - - * src/session.c: - (save_yourself_possibly_done): send a SaveYourselfDone - if we're skipping this global save. - (save_yourself_callback): don't not save session state - if the save style is Global. Fixes #89390. - - * theme-format.txt: update. - -2002-07-30 Pablo Saratxaga - - * configure.in: Added Vietnamese (vi) to ALL_LINGUAS - -2002-07-24 Havoc Pennington - - * src/themes/Makefile.am (THEMES): add Metabox theme from Garrett - - * README: updates - -2002-07-21 Havoc Pennington - - * src/window.c (meta_window_new): don't automaximize fullscreen - windows. - -2002-07-14 Havoc Pennington - - * src/window.c (recalc_window_features): don't allow shading of - border-only windows. - -2002-07-24 Havoc Pennington - - * src/theme-parser.c (meta_theme_load): look for themes in - ~/.themes/NAME/metacity-1/ and datadir/themes/NAME/metacity-1 - instead of the old locations. - - * src/themes/Makefile.am: install themes to - datadir/themes/NAME/metacity-1/ to match how GTK works, breaking - third-party themes yet again! woot! - -2002-07-20 Havoc Pennington - - * src/display.c (meta_display_open): grab display across managing - each screen; XGetInputFocus() on startup. - -2002-07-19 Havoc Pennington - - * src/window.c (meta_window_configure_request): disable configure - requests during a user move/resize operation, mostly a workaround - for stoopid apps. - -2002-07-24 jacob berkman - - * configure.in: fix x11 header checks when x11 is not in the - default include path - -2002-07-23 Ross Burton - - * src/menu.c (meta_window_menu_new): Use the real workspace names - instead of making up numbers. - -2002-07-23 Havoc Pennington - - * src/themes/Makefile.am (THEMES): put Gorilla back in the build - - * src/themes/Gorilla/metacity-theme-1.xml, - src/themes/Crux/metacity-theme-1.xml: fixes from - Sebastien Delestaing so that these themes work properly with - different font sizes. - - * src/frames.c (get_control): patch from Balamurali Viswanathan - for #81984 (resize titlebar from the top not the bottom) - -2002-07-23 Havoc Pennington - - * src/keybindings.c (meta_display_process_key_event): handle - NULL screen from screen_for_xwindow - - * src/display.c (meta_display_screen_for_xwindow): put an error - trap around the XGetWindowAttributes(), should fix the popular - "closing a window results in a crash" bug. - - * src/util.c (print_backtrace): support optional backtrace - feature using gnu libc backtrace() call - -2002-07-15 jacob berkman - - * src/update-from-egg.sh: steal from profterm to fix build - -2002-07-13 Havoc Pennington - - * src/workspace.c (meta_workspace_new): don't put a newline after - the default workspace name - -2002-07-13 Havoc Pennington - - * src/keybindings.c: adapt to virtual modifiers - (meta_display_process_mapping_event): we need to reload the - binding tables now when the modmap changes. - - * src/prefs.c (update_binding): parse virtual modifiers, not - plain modmask - - * src/common.h (MetaVirtualModifer): new enum - - * src/ui.c (meta_ui_parse_accelerator): use - egg_accelerator_parse_virtual() - - * src/Makefile.am: add eggaccelerators.[hc] for the virtual - accelerator parsing function - -2002-07-13 Christophe Fergeau - - * configure.in: added fr to ALL_LINGUAS - -2002-07-12 Havoc Pennington - - * src/session.c (warn_about_lame_clients_and_finish_interact): - don't display the dialog if all the apps were session managed. - -2002-07-12 Havoc Pennington - - * src/session.c: don't send SmInteractDone until the warning - dialog about crappy clients has been closed. - -2002-07-12 Havoc Pennington - - * src/window.c (meta_window_new): try to maximize windows that - are too big for the work area - - * src/place.c (find_next_cascade): don't let the cascade algorithm - place windows off the screen, and fix it to always exhaustively - search the window list for cascade parents. - -2002-07-11 Havoc Pennington - - * src/metacity-dialog.c (main): option to display error when a - command fails to run. - - * src/keybindings.c (handle_run_command): run commands - in response to keybindings. - - * src/prefs.c: add command keybinding stuff - - * src/metacity.schemas.in: add keybindings for running commands, - and keys to store the commands themselves. - -2002-07-10 Havoc Pennington - - * src/display.c: properly attribute selection code to Matthias - Clasen - -2002-07-10 Havoc Pennington - - * README: couple of updates - - * src/main.c (usage): add --replace to usage, reported by Matthias - Clasen - -2002-07-09 Havoc Pennington - - * src/metacity.schemas.in: fix short description for - begin_resize, patch from Jayaraj, #87654 - - * src/keybindings.c (handle_begin_resize): apply patch from - Jayaraj to actually handle the begin resize keybinding. - -2002-07-09 Havoc Pennington - - * src/window.c (constrain_position): don't center vertically for - maximized windows that don't fill the screen, just leave them at - the top. - -2002-07-06 Havoc Pennington - - * src/tabpopup.c (selectable_workspace_new): increase the size of - the mini workspaces - -2002-07-06 Havoc Pennington - - Apply blackc@speakeasy.net patch, bug #83940, to do - mini-workspaces similar to the pager, when switching - spaces. - - * src/window.c (update_net_wm_state): actually fill in - wm_state_skip_taskbar, wm_state_skip_pager flags - - * src/tabpopup.c: support drawing a mini-workspace similar to the - one the pager draws. - - * src/stack.c (meta_stack_list_windows): new function to list - the windows in stacking order - - * src/screen.c (meta_screen_ensure_workspace_popup): don't pass in - the ugly default app icon for workspaces - - * src/display.c (event_callback): fix from blackc@speakeasy.net - to avoid dereferencing a NULL grab window. - -2002-07-06 Havoc Pennington - - * src/display.c (meta_display_open): put _NET_DESKTOP_NAMES in the - array of atom names, so desktop names might work and we don't read - uninitialized memory. - - * src/main.c (main): add VERSION/timestamp verbose message. - - * src/keybindings.c: implement cycle_windows cycle_panels - - * src/metacity.schemas.in: add the cycle_windows cycle_panels - keybindings - - * src/prefs.h (META_KEYBINDING_FOCUS_PREVIOUS): replace - FOCUS_PREVIOUS key binding with CYCLE_WINDOWS and CYCLE_PANELS - (not good names really, but I don't have ideas). - - * src/common.h: add a grab op for alt+esc window cycling - -2002-07-05 Havoc Pennington - - * src/themes/Makefile.am (THEMES): Take Gorilla out until it gets - repaired. - -2002-07-05 Havoc Pennington - - * src/window.c (update_wm_hints): Change default value of input - hint (if not specified) to true instead of false. This is what - some clients assume, such as Visual SlickEdit. - -2002-07-02 Havoc Pennington - - * src/window.c (meta_window_show_menu): use new macros to get - whether we allow move/resize correct - - * src/frame.c (meta_frame_get_flags): use new macros to get - whether we can move/resize correct, considering - maximized/fullscreen for the move case. - - * src/window.h (META_WINDOW_ALLOWS_RESIZE, - META_WINDOW_ALLOWS_MOVE): new macros - - * src/keybindings.c (process_keyboard_resize_grab): finish the - right/left resize, patch from Jayaraj #78179. - - Has the same old move/resize bug, if it hits a constraint it - starts to break because we move without resizing. - -2002-07-02 Mark McLoughlin - - * src/keybindings.c: - (grab_keyboard), (ungrab_keyboard): rename from - {un}grab_all_keys_and_keyboard and only do an XKeyboardGrab, - the XKeyGrab isn't neccessary. - (meta_screen_grab_all_keys), (meta_screen_ungrab_all_keys), - (meta_window_grab_all_keys), (meta_window_ungrab_all_keys): - update for above change. - (handle_workspace_switch): don't use a MetaWindow when - workspace switching, use the root window instead. - -2002-07-01 Mark McLoughlin - - Fix broken workspace switching from my previous commit. - - * src/display.c: (meta_display_begin_grab_op): don't - leak a pointer grab if we fail to grab the keyboard. - - * src/keybindings.c: (meta_screen_grab_keys): check - screen->all_keys_grabbed. - (meta_screen_grab_all_keys): regrab our standard - bindings if we fail. - (handle_workspace_switch): revert to our previous - behaviour of using the last focused window to do - the grab upon. Only use the RootWindow if there - isn't anything else to use. - - * src/screen.c: (meta_screen_new): initialise - all_keys_grabbed. - -2002-06-26 Mark McLoughlin - - Fixes not being able to tab out of a - workspace which contains no windows. - - * src/core.c: (meta_core_begin_grab_op): upd - for meta_display_begin_grab_op change. - (meta_core_get_grab_frame): allow for - grab_window == NULL. - - * src/display.[ch]: - (meta_display_screen_for_xwindow): implement. - (meta_display_begin_grab_op): grab on the root window - if window == NULL. - (meta_display_end_grab_op): use grab_screen instead of - grab_window. - - * src/keybindings.c: - (grab_all_keys_and_keyboard): split out from - meta_window_grab_all_keys. - (ungrab_all_keys_and_keyboard): split out from - meta_window_ungrab_all_keys. - (meta_screen_grab_all_keys), (meta_screen_ungrab_all_keys): - implement grabbing and ungrabbing on the root window. - (meta_display_process_key_event): if window == NULL, - check the event is from the same screen and process. Only - happens with workspace switching. - (process_workspace_switch_grab): kill window param and - don't use grab_window. - (handle_tab_forward), (handle_begin_move): upd for - meta_display_begin_grab_op change. - (handle_workspace_switch): remove brokeness. Always do - the grab op on the root window. - - * src/keybindings.h: add meta_screen_{un}grab_all_keys. - - * src/window.c: (meta_window_client_message), (menu_callback): - update for meta_display_begin_grab_op change. - -2002-06-25 Mark McLoughlin - - * src/fixedtip.c: (meta_fixed_tip_show): - * src/frames.c: (meta_frames_new): - * src/tabpopup.c: (meta_ui_tab_popup_new): - s/gdk_get_default_display/gdk_display_get_default/ - s/gdk_get_default_screen/gdk_screen_get_default/ - -2002-06-25 Mark McLoughlin - - * src/themes/Crux/active-border-top-left-border.png: - * src/themes/Crux/active-border-top-right-border.png: - * src/themes/Crux/active-top-left-corner.png: - * src/themes/Crux/active-top-mid-left-border.png: - * src/themes/Crux/active-top-mid-right-border.png: - * src/themes/Crux/active-top-right-corner.png: - * src/themes/Crux/inactive-border-top-left-border.png: - * src/themes/Crux/inactive-border-top-right-border.png: - * src/themes/Crux/inactive-top-left-corner.png: - * src/themes/Crux/inactive-top-mid-border.png: - * src/themes/Crux/inactive-top-right-corner.png: - * src/themes/Crux/metacity-theme-1.xml: added support - for border only windows. - -2002-06-24 James M. Cape - - * src/themes/Esco/metacity-theme-1.xml: Added some stuff to - the window buttons, so they use the ACTIVE bg/fg. - -2002-06-25 Mark McLoughlin - - * src/display.[ch]: (meta_display_open): - src/screen.c: (set_supported_hint), (set_work_area_hint): - Its _NET_WORKAREA, not _NET_WM_WORKAREA silly :-) - -2002-06-25 Mark McLoughlin - - * src/screen.[ch]: - (update_num_workspaces), recalc workarea hint when - new workspaces created. Fixes bug that workarea - not calculated until first non-dock window is - mapped. - (set_work_area_hint), (set_work_area_idle_func), - (meta_screen_queue_workarea_recalc): move all this - stuff from workspace.c. - - * src/workspace.c: (meta_workspace_invalidate_work_area): - use meta_screen_queue_workarea_recalc. - -2002-06-23 Gediminas Paulauskas - - * src/themes/Bright/metacity-theme-1.xml: Update with border-only - window stuff from Atlanta. - -2002-06-22 James M. Cape - - * src/themes/Esco/metacity-theme-1.xml: Update for "border" - frame stuff, minor button/spacing improvements. - -2002-06-22 Havoc Pennington - - Partially fix Jacob's SM bugs. - - * src/window.c (meta_window_apply_session_info): restore the extra - stuff we're saving, except stack position I didn't figure out yet. - - * src/session.c: save stack position, minimized, maximized, - in the session file. - -2002-06-22 Havoc Pennington - - * src/workspace.c (set_number_of_spaces_hint): do nothing if - screen is being unmanaged, we don't want to blow away state, - we want to remember it for the next window manager. - -2002-06-22 Havoc Pennington - - * src/workspace.c (meta_screen_ensure_workspace_popup): rename - from meta_workspace_ensure_tab_popup, and use workspace->name - instead of a hardcoded name - -2002-06-22 Havoc Pennington - - * src/xprops.c (meta_prop_get_utf8_list): new utility function - - * src/display.c (meta_display_open): _NET_DESKTOP_NAMES atom - (event_callback): update workspace names when the property changes - - * src/screen.c (set_supported_hint): "support" _NET_DESKTOP_NAMES - (nothing to do really) - -2002-06-21 Havoc Pennington - - Theme breakage! Themes have to implement "border" frames - now, see Atlanta for an example. Fixes #84285 - - * src/tools/metacity-window-demo.c (do_appwindow): add a - border-only window - - * src/window.c (update_mwm_hints): read border only from the MWM - hints - - * src/window.h (struct _MetaWindow): add border_only flag - - * src/core.c (meta_core_get_frame_type): report border type if - required - - * src/common.h (enum): add META_FRAME_TYPE_BORDER - -2002-06-20 Mark McLoughlin - - * src/window.c: (meta_window_visible_on_workspace): sticky - windows aren't visibile on all screens. Check the workspace - is on the same screen as the window. - - * src/workspace.c: (meta_workspace_list_windows): use - meta_window_visible_on_workspace here. - -2002-06-19 Havoc Pennington - - * src/display.c (meta_resize_gravity_from_grab_op): handle UNKNOWN - keyboard resizing state - - * src/keybindings.c (process_keyboard_resize_grab): implement - keyboard resize key handling somewhat (only vertical resize works, - left/right arrow not implemented, and visual feedback of the - edge we're resizing isn't implemented) - - * src/window.c (menu_callback): start keyboard resize grab when - it's chosen from the menu - -2002-06-17 Havoc Pennington - - * src/stack.c (meta_stack_get_default_focus_window): don't use a - minimized window as the next focus window, patch from - blackc@speakeasy.net - -2002-06-17 Havoc Pennington - - * src/place.c (find_next_cascade): increase the cascade threshold - a bit. - (find_first_fit): implement a somewhat lame first fit algorithm - -2002-06-17 Havoc Pennington - - * src/window.c (meta_window_change_workspace): fix from Gaute - Lindkvist #82977 for unsticking windows - -2002-06-17 Frederic Crozat - - * src/metacity.schemas.in: associate close_window keybinding to - Alt-F4 - -2002-06-16 Havoc Pennington - - * src/main.c (main): fix spelling error, #85452 - -2002-06-15 Havoc Pennington - - * src/keybindings.c (meta_display_process_key_event): don't pass a - null string to printf - - * src/display.c (key_event_description): don't pass a null string - to printf - - * src/keybindings.c (meta_set_keybindings_disabled): allow - enable/disable keybindings regardless of debug mode. - -2002-06-15 Havoc Pennington - - * src/draw-workspace.h, src/draw-workspace.c: workspace-drawing - code factored out of libwnck, needs wiring up to tabpopup.c - (which is kind of annoying since you have to get the list of - workspaces and MetaWindow across the barrier between the GDK-aware - and non-GDK-aware sides of metacity) - -2002-06-14 Havoc Pennington - - * src/window.c (meta_window_show): always focus new windows, - trying to be smart about it was a flop. - -2002-06-14 Jayaraj Rajappan - - * src/delete.c (io_from_ping_dialog): Check for NULL string - before calling strlen(). Fixes the core dump issue reported in #84873. - -2002-06-13 Anders Carlsson - - * src/theme.c (meta_frame_layout_calc_geometry): Set client height - as 0 when the window actually is shaded, not the other way around. - -2002-06-12 Havoc Pennington - - * src/theme.c (meta_frame_layout_calc_geometry): when a window is - shaded, don't include client height in the height calculation. - - * src/workspace.c (meta_workspace_get_neighbor): apply fix from - Mads Villadsen for the Up arrow key, #84582 - -2002-06-12 Havoc Pennington - - * src/theme.c (meta_frame_style_draw): Draw the buttons right - before the "overlay" piece. - -2002-06-12 Jayaraj Rajappan - - * src/tools/metacity-properties.glade: accessibility work for - metacity-properties capplet. Set appropriate atk relations. - Fixes bug #84749 - -2002-06-11 Havoc Pennington - - * src/window.c (meta_window_show): allow dialogs to steal focus - from panels/desktop - -2002-06-10 Jayaraj Rajappan - - * src/fixedtip.c: include - fix for #83960 - -2002-06-10 Erwann Chenede - - - * src/keybindings.c : (handle_close_window, handle_minimize_window) - verify the active window has the appropriate close/minimize function - before closing or minimizing the window. - -2002-06-09 Havoc Pennington - - * configure.in: 2.3.987 - -2002-06-09 Havoc Pennington - - * src/delete.c (delete_ping_timeout_func): add G_IO_NVAL to watch - condition, patch from Gustavo Giraldez, avoids another 100% CPU - thingy - -2002-06-09 Havoc Pennington - - * src/place.c (meta_window_place): don't run constrain_placement - on windows we allow to go anywhere (docks, etc.). Fixes - positioning of panel windows in certain cases. - -2002-06-09 Havoc Pennington - - * src/frames.c (meta_frames_button_press_event): don't raise/focus - the window if minimize/close are clicked, patch from Gaute - Lindkvist #75460 - -2002-06-08 Havoc Pennington - - Cleanups to workspace popup patch. Space before all parens - in a couple places. - - * src/prefs.c (meta_prefs_get_keybinding_action): fix brace - indentation, and use while instead of for loop. Take a "mask" - argument to avoid ambiguity issues. - - * src/keybindings.c (handle_workspace_switch): rename from - handle_workspace_forward since there's no directionality here - (handle_workspace_switch): add a FIXME about how screwed it is - that we need a window in order to do our grab. Should be able to - grab on a dummy window like no_focus_window or the root window. - (process_workspace_switch_grab): rename from tab_grab for clarity, - no tab involved here. - - * src/common.h (enum): have only one grab op for all workspace - switching directions, instead of one for each. - -2002-06-08 Havoc Pennington - - Apply big patch from blackc@speakeasy.net adding a popup window - to the Ctrl+Alt+arrows shortcuts. #83940 - -2002-06-08 Havoc Pennington - - * src/screen.c (meta_screen_new): select key press/release on the - display->no_focus_window, another attempted fix for not getting - keybindings when no window is focused. Still doesn't seem to work - though. I don't get what's going wrong. - (meta_create_offscreen_window): new function, used instead of - XCreateSimpleWindow so we get override redirect offscreen windows. - -2002-06-08 Havoc Pennington - - * src/display.c (meta_display_open): set net_supporting_wm_check - in addition to win_supporting_wm_check, patch from - JeyaSudha for #83365 - - * src/screen.c (set_wm_check_hint): remove setting - win_supporting_wm_check on leader window here, done already in - display.c - -2002-06-08 Havoc Pennington - - * src/keybindings.c (meta_window_ungrab_keys): set keys_grabbed to - FALSE, patch from Jayaraj for #81857 - -2002-06-08 Havoc Pennington - - * src/xprops.c (meta_prop_get_utf8_string): don't die on bad atom - name - - * src/display.c (meta_display_close): don't unmanage windows here, - do it in screen_free and then closing the display unmanages - windows as a side effect of unmanaging the screen - (meta_display_unmanage_screen): new function - (process_selection_clear, process_selection_request): handle - selection stuff - (meta_spew_event): don't crash on client message containing - invalid atom - (meta_spew_event): don't crash on property notify with invalid - atom - - * src/main.c (main): add --replace option to replace existing - window manager. - - * src/screen.c: implement holding manager selection. - - * src/display.c (meta_display_open): add new selection-related - atoms. - -2002-06-08 Havoc Pennington - - * src/screen.c (meta_screen_new): select keypress/keyrelease - events on root window, this may fix the bug where keybindings - didn't work if you didn't have a focused window. - -2002-06-08 Havoc Pennington - - * src/main.c (main): call meta_session_shutdown when exiting - cleanly - - * src/session.c (meta_session_shutdown): function to change use to - RestartIfRunning - (meta_session_init): change normal restart hint to - RestartImmediately - -2002-06-08 Havoc Pennington - - Yeah I know maximization is broken, I'm too tired to fix it. - Probably because of the change to update_struts() that was - supposed to fix the 100% CPU bug. - - * src/place.c (meta_window_place): don't run docks and things - through the placement algorithm. Thought it might fix - metacity-window-demo but it didn't. - - * src/window.c (constrain_size): only get work area when needed - (meta_window_new): init the do_not_cover field - -2002-06-08 Havoc Pennington - - * src/screen.c (meta_screen_get_xinerama_for_window): - short-circuit the "only one xinerama" case, and use outer rect of - window instead of window->rect, so we get root window coords. - - * src/theme.c (meta_frame_layout_get_borders): if fullscreen all - frame edges are zero-width. - - * src/frame.c (meta_frame_get_flags): init fullscreen flag. - - * src/common.h (enum): add META_FRAME_FULLSCREEN frame flag - - * src/place.c: fix up calls to meta_window_get_work_area - - * src/window.c (meta_window_get_work_area): add an arg for whether - the work area is for the screen or the xinerama subscreen. - (constrain_position): fix up calls to meta_window_get_work_area - (constrain_size): ditto - - * src/screen.c (meta_screen_new): add METACITY_DEBUG_XINERAMA - environment variable which simulates xinerama on a single head. - -2002-06-08 Havoc Pennington - - * src/window.c (update_struts): only invalidate things if the - struts actually change, since the panel likes to set them over and - over. May fix the infinite loop that caused 100% CPU usage. - -2002-06-07 Havoc Pennington - - * src/screen.c (meta_screen_new): use XineramaIsActive() not - XineramaQueryExtension() - -2002-06-07 Havoc Pennington - - * src/screen.c (meta_screen_get_current_xinerama): don't return - null on non-multihead - -2002-06-06 Havoc Pennington - - * src/screen.c (meta_screen_get_current_xinerama): implement - - * src/place.c (meta_window_place): cascade windows on the active - Xinerama screen - - * src/window.c (meta_window_move_resize_internal): strip out the - #if 0 cruft about guessing fullscreen mode - (constrain_position, constrain_size): fullscreen/maximize to the - Xinerama head, not the whole screen - (meta_window_get_work_area): autocreate struts at the Xinerama - physical screen edges for the screen the window is on. - - * src/screen.c (meta_screen_get_xinerama_for_window): someone - snuck in a for loop, fix it. ;-) - -2002-06-06 James M. Cape - - * src/themes/Esco/metacity-theme-1.xml: Increase the border size - of the buttons so they aren't quite so huge on my box. Also get - a *little* closer to finally fixing the horizontal line behind - the icon. It now works decently with common font sizes (in pixels). - -2002-06-05 Havoc Pennington - - * src/theme.c (meta_color_spec_new_from_string): parse - "shade/foo/factor" as a color - (colorize_pixbuf): remove the unused hsv_to_rgb and vice-versa - stuff, add the gtk_style_shade stuff. - (meta_color_spec_render): render the shaded color spec - - * src/theme.h (struct _MetaColorSpec): add "shade" mode to - MetaColorSpec. - -2002-06-04 Seth Nickell - - * src/metacity.desktop.in: - - Add X-GnomeWMSettingsLibrary to desktop file to support new - Window capplet. - -2002-06-04 Havoc Pennington - - * src/window.c (update_wm_hints): fix for how we read the input - hint, from Hidetoshi Tajima - - (meta_window_show): from Hidetoshi, don't autofocus windows with - input = FALSE wm_take_focus = FALSE when they first appear. We do - allow these windows to be focused (so keynav works), but they - don't get focused automatically. Now how do we keep them out of - the task list? - -2002-06-04 Gustavo GirÃ�¡ldez - - * src/theme.c (draw_op_as_pixbuf): Use icon's instead of image's - fill_type when type is META_DRAW_ICON. - -2002-06-03 Havoc Pennington - - * src/window.c (meta_window_new): don't automatically fullscreen - things opened fullscreen, because there's no GUI to un-fullscreen - them. - -2002-06-03 Havoc Pennington - - * src/theme-parser.c (parse_aspect_ratio): fix error message about - bad aspect ratio name. - -2002-06-03 Havoc Pennington - - * src/themes/Esco/metacity-theme-1.xml: test button aspect ratio - instead of hardcoded button size, James feel free to revert if you - don't like it this way. - - * src/theme-parser.c: parse the aspect_ratio element for button - aspect ratios. - - * src/theme.h (struct _MetaFrameLayout): allow button sizes to be - given as an aspect ratio derived from the titlebar height, - instead of as a fixed size. - - * src/theme.c (meta_frame_layout_validate): validate new button - sizing parameters - - * src/theme.c (meta_frame_layout_calc_geometry): use new button - layout params - -Mon Jun 3 15:12:11 2002 HideToshi Tajima - - * configure.in (METACITY_LIBS): put -lXext into SHAPE_LIBS - -2002-06-03 Kjartan Maraas - - * src/tools/metacity-properties.desktop.in: Someone forgot to mark - the two strings in here for translation :) - -2002-06-02 Havoc Pennington - - * configure.in: 2.3.610 - -2002-06-01 Havoc Pennington - - * src/frames.c (meta_frames_finalize): move the remove_listener - to finalize instead of destroy, thanks to Jayaraj for tracking - down the bug. - -2002-06-01 Havoc Pennington - - * src/session.c: add some missing \n - (meta_session_init): remove the #if 0 interact callback from our - initial SmcOpenConnection call, this arg to SmcOpenConnection - doesn't exist. - -2002-06-01 Havoc Pennington - - * src/session.c: put in more debug spew about the session - -2002-05-30 Havoc Pennington - - * src/Makefile.am (INCLUDES): use $(prefix)/@DATADIRNAME@/locale - for localedir to work with Solaris native gettext, patch from - Hidetoshi Tajima - - * src/tools/Makefile.am: ditto - -2002-05-31 Havoc Pennington - - * src/theme.c: add MetaImageFillType and implement TILE in - addition to the existing SCALE - - * src/theme.h (struct _MetaDrawOp): remove no-longer-used "alpha" - field - -2002-05-31 Havoc Pennington - - * src/theme.c (multiply_alpha): now just uses - meta_gradient_add_alpha - (draw_op_as_pixbuf): implement alpha gradients for tint, gradient, - and image draw ops, so I can implement garrett's stuff. - - * src/gradient.c (meta_gradient_add_alpha): new function to - multiply the alpha channel of a pixbuf by an alpha gradient - -2002-05-30 Havoc Pennington - - * src/main.c (main): verbose-log on startup whether we were - compiled with various extensions - - * src/display.c (meta_display_queue_retheme_all_windows): reapply - shape mask when changing themes, sucks to do it here though, makes - theme changing slower. Needs fixing. - - * src/theme-parser.c (parse_toplevel_element): parse rounded - corner options to frame_geometry - - * src/frames.c (meta_frames_apply_shapes): apply rounded corners - if requested by the theme - - * configure.in (HAVE_SHAPE): check for shape extension - -2002-05-30 Stephen Browne - - * src/tools/metacity-properties.c: - Some day I'll make all my changes in one commit :) - Needed to rip out code for adding icon to the dialog since it was - removed from teh galde file in my previous change. - -2002-05-30 Stephen Browne - - * src/tools/metacity-properties.glade: - Some UI changes demanded by Pat and Calum. - Make Close default response - Change mnemonic for Click so as not to clash with Close - -2002-05-30 Stephen Browne - - * src/tools/metacity-properties.glade: changed window title - to match other control center dialogs - -2002-05-29 Havoc Pennington - - * src/session.c (meta_session_init): improve error about failing - to open session manager. - (shutdown_cancelled_callback): send SmcSaveYourselfDone when we - get cancelled - (interact_callback): implement an interact callback that complains - about lame clients that can't be saved. Still somewhat buggy - in that it sends InteractDone before the user has closed the - dialog. - -2002-05-29 Havoc Pennington - - * src/tools/metacity-mag.c: add a magnifier I'm using when making - themes. Not installed. - - * src/tools/metacity-properties.c: reindentation, show window, add - copyright info. - - * src/tools/metacity-properties.glade: make main window !visible - on startup, to avoid funkiness. - -2002-05-29 Jacob Berkman - - * src/tools/Makefile.am (EXTRA_DIST): dist .desktop.in files - -2002-05-29 Stephen Browne - - New simple metacity-properties dialog to configure focus mode - and auto raise. - - * configure.in: added build support for metacity-properties - * src/tools/Makefile: more build stuff - * src/tools/metacity-properties.c: added these files - * src/tools/metacity-properties.glade: - * src/tools/metacity-properties.desktop.in: - * src/tools/metacity-properties.png: - -2002-05-29 Havoc Pennington - - * src/window.c (meta_window_move_resize_internal): add code to - also guess that client wants to come out of fullscreen, then - #if 0 the whole deal, I'm not sure it's such a good idea. - -2002-05-29 Havoc Pennington - - * src/window.c (meta_window_move_resize_internal): guess if a - window meant to be fullscreen, and if so put it in that state. - -2002-05-28 Havoc Pennington - - * src/window.c (redraw_icon): handle missing frame, prevents segv - with undecorated windows. #83298 - -2002-05-28 Havoc Pennington - - Patch from Erwann Chenede for raise_or_lower keybinding - - * src/display.c, src/common.h: POINT_IN_RECT moved to a common - location, removed from here - (meta_rectangle_intersect): move here and make it public - - * src/prefs.c: add raise_or_lower keybinding - - * src/stack.c (meta_stack_get_below, meta_stack_get_above): add an - arg to only get windows within the same layer - - * src/keybindings.c (handle_raise_or_lower): add handling for a - "raise window if obscured, else lower" keybinding - -2002-05-28 Havoc Pennington - - * src/window.c (meta_window_configure_request): handle CWStackMode - in configure requests - (meta_window_new): if a window is opened at 0,0 and screen size, - put it in the fullscreen state. - (meta_window_new): remove old code that set the window position to - 0,0 if PPosition/USPosition unset, that will be handled by whether - we place the window or not. - -2002-05-28 Abel Cheung - - * configure.in: Added "zh_TW" to ALL_LINGUAS. - -2002-05-27 Havoc Pennington - - * src/window.c (meta_window_new): search for the window's screen - by root window instead of Screen*, maybe it will help with - bug #82664 - -2002-05-27 Kjartan Maraas - - * autogen.sh: Hook up intltoolize here. - * configure.in: Initialize intltool. - * src/metacity.schemas.in: Add this. - * src/metacity.desktop.in: Add this too - * src/Makefile.am: Hook up intltool support for .schemas and .desktop. - * Makefile.am: Dist the intltool files. - -2002-05-27 Anders Carlsson - - * src/themes/Gorilla/metacity-theme-1.xml: Apparently someone - thinks my name is Anders Carlsom. Well, it's not. - (Thanks to Carl-Johan Kjellander for noticing.) - -2002-05-26 James M. Cape - - * src/themes/Esco/metacity-theme-1.xml: Remove borders from - Esco theme as well (didn't know you could), apparently fixed - the problem where the spacing between the icon & the title - got larger as the fontsize went up. - -2002-05-26 Havoc Pennington - - * src/themes/Atlanta/metacity-theme-1.xml: totally drop the - borders off of maximized windows. - -2002-05-26 Havoc Pennington - - Patch from Gaute Lindkvist so you can't move the panel or desktop - to only one workspace. - - * src/keybindings.c (handle_move_to_workspace): don't allow moving - window to another space if the window is always_sticky - - * src/window.c (recalc_window_features): set the always_sticky - field for desktop/dock windows. - (meta_window_show_menu): disable unsticking always sticky windows - via the menus - - * src/menu.c (meta_window_menu_new): disable workspace items - if requested - -2002-05-26 Matthias Warkus - - * po/de.po: Added. - * configure.in: de added to ALL_LINGUAS - -2002-05-25 Erwann Chenede - - - * src/keybindings.c (rebuild_screen_binding_table, - rebuild_window_binding_table, - meta_change_keygrab): allow key grabbing for - unmodified keys (e.g F1, etc) fix #82630 - -2002-05-25 Anders Carlsson - - * src/place.c: (get_vertical_edges), (get_horizontal_edges): - Take Xinerama screen edges into consideration. - - * src/screen.c: (meta_rectangle_intersect), - (meta_screen_get_xinerama_for_window): - * src/screen.h: - Add a new function that returns the xinerama monitor that - a window is on. - -2002-05-24 Havoc Pennington - - * src/window.c (menu_callback): follow windows to their new - workspace - - * src/keybindings.c (handle_move_to_workspace): follow windows to - their new workspace - -2002-05-24 Havoc Pennington - - * src/metacity.schemas: add minimize window binding - - * src/keybindings.c (handle_minimize_window): add minimize keybinding - -2002-05-24 Havoc Pennington - - * src/window.c (meta_window_show): change how focusing windows - on initial map works, so that we only steal focus from our - transient parent or from a panel/desktop, never from other - normal windows. - -2002-05-24 Havoc Pennington - - * src/window.c (meta_window_configure_request): modify to ignore - PPosition and USPosition once the window has been placed - -2002-05-24 Anders Carlsson - - * src/window.c: Redraw the window frame when the icon changes. - Fixes #78543, reported by Kang Jeong-Hee. - -2002-05-23 Havoc Pennington - - * src/display.c (event_callback): also filter out LeaveNotify - with NotifyInferior - -2002-05-23 Jayaraj Rajappan - - * src/display.c (event_callback): fix for bugzilla bug #72314, - filter out LeaveNotify caused by grabs when in mouse focus mode. - -2002-05-23 Havoc Pennington - - * src/metacity.schemas: clean up the font preference - - * src/prefs.c: font pref - - * src/frames.c: pay attention to the font pref - -2002-05-23 Havoc Pennington - - Crack from Erwann - - * src/metacity.schemas: add autoraise crackrock - - * src/display.c (event_callback): autoraise window if autoraise is - enabled - - * src/prefs.c: autoraise crack - -2002-05-21 Havoc Pennington - - * src/window.c (constrain_position): fix positioning in fullscreen - mode, patch from Gustavo GirÃ�¡ldez - -2002-05-20 Alessio Frusciante - - * configure.in: Added Italian to ALL_LINGUAS. - -2002-05-20 Pablo Saratxaga - - * configure.in: Added Catalan (ca) and Azeri (az) to ALL_LINGUAS - -2002-05-17 Havoc Pennington - - * configure.in: 2.3.377 - -2002-05-16 Havoc Pennington - - * src/workspace.c (meta_workspace_get_neighbor): fix it, maybe - -2002-05-16 Havoc Pennington - - * src/window.c (constrain_position): lock desktop to position 0,0 - -2002-05-16 Havoc Pennington - - * src/window.c (meta_window_show): don't focus dock, desktop, - etc. windows on initial map, only windows that should have focus. - -2002-05-15 Havoc Pennington - - * src/workspace.c (meta_workspace_get_neighbor): use the layout - information to figure out up/down neighbors - - * src/display.c (event_callback): catch propertynotify on - _NET_DESKTOP_LAYOUT - - * src/screen.c (meta_screen_update_workspace_layout): keep track - of the layout of workspaces as set by the pager - -2002-05-15 James M. Cape - - * src/themes/Esco/metacity-theme-1.xml: Minor tweak to minimize - button. - -2002-05-14 Havoc Pennington - - * src/themes/Makefile.am (THEMES): add Esco theme from James Cape - -2002-05-12 Havoc Pennington - - * src/place.c (meta_window_place): move pposition/usposition - honoring code into here, instead of putting it in window.c. - Makes focusing new windows work, and cleans things up a bit. - #81585 - -2002-05-12 Havoc Pennington - - * src/main.c (main): turn on --g-fatal-warnings if - METACITY_G_FATAL_WARNINGS env variable is set. - -2002-05-11 Anders Carlsson - - * src/display.c: (find_tab_forward), (find_tab_backward), - (meta_display_get_tab_next): - * src/display.h: - * src/keybindings.c: (handle_tab_forward), (handle_focus_previous): - Add screen argument to meta_display_get_tab_next, since we only - want windows on the same screen to appear in the tab chain. - - * src/screen.c: (meta_screen_new): - Or the event mask with existing events since gtk+ may listen to - certain events and we don't want to disable those events. - - (meta_screen_ensure_tab_popup): - * src/tabpopup.c: (meta_ui_tab_popup_new): - * src/tabpopup.h: - Add a screen number argument to meta_ui_tab_popup_new so we - can position the popup on the correct screen. - -2002-05-11 Havoc Pennington - - * src/main.c: include locale.h, fix from Hidetoshi Tajima - - * src/window.c (meta_window_new): disable show desktop mode when a - new window is managed. - -2002-05-11 Havoc Pennington - - * src/fixedtip.c (meta_fixed_tip_show): keep the tooltip - on the screen horizontally, #76825 - - * src/window.c (meta_window_handle_mouse_grab_op_event): end grab - op _after_ doing the final update of the move or resize. - Hopefully I didn't have a reason for the order I was using before. - -2002-05-10 Havoc Pennington - - * src/tools/metacity-window-demo.c: add override redirect test - window - - * src/stack.c (raise_window_relative_to_managed_windows): new - function, used to avoid moving windows above override redirect - popup windows. - - * src/display.c (event_callback): don't lower panels on - LeaveNotify if they have focus, #70895 - -2002-05-10 Havoc Pennington - - * src/window.c (constrain_position): when maximizing/fullscreening - something with a grid, like a terminal, center it in the - maximization area in case it can't fill the whole area. - #70554 - - * src/main.c (main): use g_strerror() to get proper UTF-8. - -2002-05-10 Havoc Pennington - - * src/keybindings.c (reload_modmap): put LockMask into the - ignored_modifier_mask so that caps lock doesn't mess up - keybindings. - -2002-05-10 Havoc Pennington - - * src/window.c (meta_window_focus): if window is not mapped after - the calc_showing, don't focus it, it's probably on another - workspace or something. - -2002-05-09 Havoc Pennington - - * src/frames.c (show_tip_now): DefaultScreen() returns the screen - number not Screen* - - * src/frame.c (meta_frame_sync_to_window): immediately repaint - frame whenever we resize it, if we're inside a grab operation. - - * src/frames.c (meta_frames_repaint_frame): new function - - * src/window.c (meta_window_new): initialize window's colormap - (meta_window_notify_focus): install the colormap for a window when - it gets focus, uninstall on unfocus. - - * src/window.h (struct _MetaWindow): store window's colormap - - * src/display.c (event_callback): note changes to window colormap - - * src/frame.c (EVENT_MASK): add ColormapChangeMask - -2002-05-09 Havoc Pennington - - * src/display.c (event_callback): make Alt+button2 do a resize - -2002-05-08 Anders Carlsson - - * src/fixedtip.c (meta_fixed_tip_show): - #ifdef out call to gtk_window_set_screen, reported by - Erwann Chenede. - -2002-05-08 Anders Carlsson - - * configure.in: - * src/display.c: (meta_display_open): - * src/fixedtip.c: (meta_fixed_tip_show): - * src/fixedtip.h: - * src/frames.c: (meta_frames_new), (show_tip_now): - * src/frames.h: - * src/menu.c: (meta_window_menu_new): - * src/ui.c: (meta_ui_new): - Add multi-screen support. Also add patch by Erwann Chenede - to make tooltips appear on the correct screen. - -2002-05-07 Anders Carlsson - - * src/workspace.c (set_work_area_hint): Doh, only update - the tmp pointer when the screen matches. Fixes a segfault - when running with multiple screens. - - * src/display.c: (meta_display_open), (event_callback), - (meta_display_update_show_desktop_hint): - * src/display.h: - * src/screen.c: (set_supported_hint): - Fix atom name; it's _NET_SHOW_DESKTOP, not - _NET_WM_SHOW_DESKTOP. - - * src/frames.c: (meta_frames_unmanage_window): - Restore the mouse cursor to default when unmanaging a window. - -2002-05-06 Anders Carlsson - - * src/display.c: (set_utf8_string_hint): - Fix an off-by-one error. - - (meta_display_open), - (event_callback), (meta_display_update_show_desktop_hint), - (meta_display_show_desktop), (meta_display_unshow_desktop): - * src/display.h: - * src/screen.c: (set_supported_hint): - Add support for _NET_WM_SHOW_DESKTOP, both as a message and - as a root window property. - -2002-05-05 Havoc Pennington - - * src/window.c (meta_window_unminimize): on unminimize, queue - calc_showing on all transients - (meta_window_activate): on activate, unminimize all a window's - ancestors, not just the window itself. - - * src/workspace.c (set_work_area_hint): don't increment "tmp" by - 16 unsigned long, increment by 4 - - * src/window.c (meta_window_free): if a window isn't minimized, - restore its WM_STATE to NormalState instead of IconicState, - since IconicState on initial window map means that the window - should be minimized. - - * src/workspace.c (meta_workspace_invalidate_work_area): queue an - idle to recompute the work area hint. - (set_work_area_hint): we need 4*num_workspaces ints, not just - num_workspaces. - - * src/screen.c (meta_screen_new): add work_area_idle field, - handle it on screen shutdown - - * src/common.h (META_PRIORITY_PREFS_NOTIFY, - META_PRIORITY_WORK_AREA_HINT): define some idle priorities - - * src/window.c (meta_window_calc_showing): hide windows if - their parent window is minimized - (meta_window_minimize): also queue_calc_showing on all - transients of the window being minimized - - * src/place.c (constrain_placement): function to apply - placement-time-only constraints, such as "not off the left of the - screen" - (meta_window_place): put dialogs down a bit over their parent, - not right at the top. - (meta_window_place): when centering a dialog, center it - on the current xinerama screen, rather than the entire - screen. - - * src/screen.c (meta_screen_get_current_xinerama): new function, - but not implemented - -2002-05-04 Havoc Pennington - - * src/frames.c (meta_frames_paint_to_drawable): chop out the - portion of the region that's outside the screen. - - * src/core.c (meta_core_get_screen_size): new function - (meta_core_get_frame_extents): new function - -2002-05-04 Havoc Pennington - - * src/frames.c (meta_frames_init): disable automatic GTK double - buffering, since it resulted in gigantic backing pixmaps the size - of the whole screen. - (meta_frames_paint_to_drawable): change to take a region argument; - punch the client area out of the expose region, then iterate over - rectangles in the region and draw each, manually doing - begin_paint_rect. Results in 4 long thin backing pixmaps - per frame repaint, instead of one large backing pixmap. - Suggested by Owen. - -2002-05-05 Bastien Nocera - - * src/workspace.c: (meta_workspace_get_neighbor): - Wrap-around workspaces (ie. when on the last workspace, - "switch_to_workspace_right" goes back to the - first one) - -2002-05-05 Anders Carlsson - - * src/metacity.schemas: Fix a spelling error and change - switch_to_workspace_up and switch_to_workspace_down to use - Ctrl+Alt since Nautilus uses Alt now. - -2002-05-04 Havoc Pennington - - * src/window.c (update_net_wm_type): correctly print things if the - type_atom is unset - (meta_window_new): with workarounds disabled, always allow - self-placement for windows with PPosition or USPosition set. - -2002-05-03 Havoc Pennington - - * src/Makefile.am: fix for automake 1.5, patch from Tomasz Kloczko - -2002-05-03 Laszlo Peter - - * configure.in: add the X libs to METACITY_MESSAGE_LIBS and - METACITY_WINDOW_DEMO_LIBS - -2002-05-02 Havoc Pennington - - * README: updates - - * configure.in: 2.3.233 - -2002-05-02 Bastien Nocera - - * src/metacity.schemas: change the default for switch_to_workspace_* - to be arrow as just arrow collides with some apps - (especially web browsers) - -2002-05-01 Havoc Pennington - - * src/screen.c (meta_screen_new): Xlib doesn't like NULL for out - arguments; fix for #80472 from lbedford - -2002-04-30 Havoc Pennington - - * src/keybindings.c: finish mopping up mode_switch_mask field - - * src/display.h (struct _MetaDisplay): remove mode_switch_mask - field - -2002-04-30 Havoc Pennington - - * src/window.c (recalc_window_features): don't try to decorate - toolbars. - - * src/tools/metacity-window-demo.c: add menu and toolbar tests - - * src/place.c (meta_window_place): only dialogs should be centered - over parent, not anything with transient for set. - - * src/window.c (meta_window_configure_request): become more - fascist about window positioning if workarounds are disabled, and - less fascist if they are enabled. - - * src/metacity.schemas: add a "disable_workarounds" option. Kind - of crack-smoking. But we just can't get all applications - fixed. And I need no-workarounds mode to monitor which apps are - broken and what needs fixing in specs. - - * src/window.c (meta_window_configure_request): always allow - windows to resize themselves - - * src/keybindings.c (reload_modmap): don't filter out Mode_switch, - apparently some people bind window manager shortcuts to that. - -2002-04-30 Havoc Pennington - - * src/window.c (constrain_position): oops, fix - maximization. Pointed out by Gustavo GirÃ�¡ldez - -Tue Apr 30 06:24:09 2002 Jonathan Blandford - - * src/menu.c: give Maximize/Unmaximize and Shade/Unshade the same - mnemonic for consistency's sake. - -2002-04-29 Havoc Pennington - - * src/window.c (TITLEBAR_LENGTH_ONSCREEN): require 36 pixels - onscreen so you typically get a sliver of titlebar, suggested by - tigert. Should still fix this to consider actual theme geometry. - (constrain_position): change to allow movement off the left - -2002-04-29 Havoc Pennington - - * src/display.c (event_callback): always raise windows on focus - click, regardless of focus mode. - -2002-04-29 Havoc Pennington - - * configure.in: 2.3.144 - -2002-04-29 Havoc Pennington - - * src/ui.c (meta_ui_init): don't leak the PangoContext - -2002-04-28 Anders Carlsson - - * src/display.c: (meta_display_open): - * src/display.h: - * src/screen.c: (set_supported_hint): - * src/workspace.c: (set_number_of_spaces_hint), - (set_workarea_hint): - Add support for setting the _NET_WM_WORKAREA hint. No code - does it yet though. - -2002-04-28 Havoc Pennington - - * README: remove caveats about keybindings - - * src/metacity.schemas: add schemas for all the keybindings. - - * src/window.c (meta_window_activate): if in "show desktop" mode - when a window is activated, leave show desktop mode. So e.g. - when you click on a task in the task list, show desktop mode - will be turned off. - - * src/workspace.c (meta_workspace_get_neighbor): new function - that doesn't quite work yet (needs support for getting - workspace layout from the pager) - - * src/prefs.c: keybindings stuff - - * src/keybindings.c: make keybindings configurable - - * src/ui.c (meta_ui_parse_accelerator): new function - -2002-04-25 Havoc Pennington - - * metacity.spec: fix to install gconf schemas - -2002-04-25 jacob berkman - - * src/session.c (load_state): g_file_get_contents() takes a gsize - not int (fixes bus error on 64-bit platforms) - -2002-04-22 Havoc Pennington - - * src/main.c (main): call setlocale ourselves because due to a - GLib bug that sticks us in ASCII if you call g_print or anything - prior to setlocale, and print a warning if we don't set the locale - successfully. #79280 - - * src/workspace.c (meta_workspace_get_work_area): be more verbose - about how the work area was computed, to help find bugs here. - - * src/main.c (main): put locale and codeset in the log file - -2002-04-21 Havoc Pennington - - * src/window.c (meta_window_send_icccm_message): add error trap, - fixes a possible BadWindow if a window closed itself in response - to the delete window message prior to us sending the ping message. - -2002-04-21 Havoc Pennington - - * src/window.c (meta_window_move_resize_now): never revert to - user_rect.width, user_rect.height. Maybe fixes assorted resize - screwups e.g. with gnome-terminal. - -2002-04-21 Anders Carlsson - - * src/iconcache.c (scaled_from_pixdata): Add padding if - icon width and height differ. - -2002-04-17 Havoc Pennington - - * src/screen.c (meta_screen_new): query Xinerama screen - information if HAVE_XINERAMA - - * configure.in (found_xinerama): check for Xinerama - -2002-04-17 Changwoo Ryu - - * configure.in (ALL_LINGUAS): Added ko (Korean). - -2002-04-16 Akira TAGOH - - * configure.in (ALL_LINGUAS): add ja.po entry. - -2002-04-15 Havoc Pennington - - * src/window.c (update_title): fix issue with GNU libc - mangling %.10s format - - * metacity.spec: Fix up spec file - - * README: update README - - * configure.in (ALL_LINGUAS): require GTK 2.0.0 - -2002-04-15 Havoc Pennington - - * src/display.c (meta_display_ping_window): reply immediately for - windows that don't support _NET_WM_PING - - * src/window.c (update_protocols): check whether windows - support _NET_WM_PING - -2002-04-13 Havoc Pennington - - * src/ui.c (get_cmap): same fix as libwnck, avoid using cmap - with the wrong depth - -2002-04-13 Havoc Pennington - - * src/delete.c: new file containing all the - wacky mess I just added to a simple "click the close button", - contains all the dealing-with-dead-application cruft. - Use metacity-window-demo to test by clicking the - toolbar button that locks it up. - -2002-04-12 Havoc Pennington - - * src/tools/metacity-window-demo.c (do_appwindow): make one of the - toolbar buttons lock up the demo - - * src/window.c (meta_window_delete): move error trap to be around - a narrower part of the function, and add part of the ping stuff, - nothing user-visible yet - - * src/metacity-dialog.c (main): metacity-dialog executable to - live in libexecdir and pop up dialogs for us. - -2002-04-09 Havoc Pennington - - * src/theme.c (multiply_alpha): fix alpha multiplication routine - to perhaps work correctly, reported by tigert. Also, be sure - we always copy the image if necessary before modifying the - alpha channel. - -2002-04-05 Havoc Pennington - - * src/stack.c: remove the unused tab stuff - - * src/display.c: implement tab list among panels - - * src/keybindings.c: fill in move-between-panels keybindings - -2002-03-31 Johan Dahlin - - * src/menu.c (meta_window_menu_new): Make sure all menu items are - translated. - -2002-03-27 Havoc Pennington - - * src/window.c (meta_window_free): remove - unmanaged windows from save set, and unselect - input so we don't get events from them. Fixes annoying - bug where withdrawn windows would decide to map themselves - due to save set stuff. - -2002-03-22 Zbigniew Chyla - - * configure.in (ALL_LINGUAS): Added pl (Polish). - -2002-03-21 Havoc Pennington - - * src/themes/Bright/metacity-theme-1.xml: Added "Bright" theme - from Gaute Lindkvist, with some small clipping tweaks to keep - text/icons from overlapping their frames. - -2002-03-19 Havoc Pennington - - * src/resizepopup.c (place_vertical_size_window) - (place_horizontal_size_window): disable the little shaped windows - with the window size, they caused a crash anytime you tried to - resize with Xft. And they were kind of on crack anyway. - -2002-03-17 Havoc Pennington - - * src/resizepopup.c (ensure_tick_windows): turn off the tick - marks, that got annoying after about 5 minutes. One big shape - window instead of lots of little windows might fix it. - -2002-03-17 Havoc Pennington - - * src/resizepopup.c: Add some total crackrock resize-grid - indication for windows that have width_inc/height_inc - so I can debug gnome-terminal sizing. - -2002-03-17 Havoc Pennington - - * src/session.c (set_clone_restart_commands): use proper property - name for SmDiscardCommand (instead of setting the clone command to - "rm"). Also fix typo that iterated over clonev not discardv to - fill in prop list, and NULL-terminate discardv. #74584 from Kang - Jeong-Hee. - -2002-03-13 Havoc Pennington - - * src/main.c (main): put back --sm-client-id argument, needed - for including us in a default session - -2002-03-13 Havoc Pennington - - * src/session.c (meta_session_init): don't save a file here, only - in response to SaveYourself. Change the code to properly use a - unique state file for each SaveYourself. Totally, totally - untested. - -2002-03-12 Havoc Pennington - - * src/theme-viewer.c: improve the theme viewer so people - can see the broken aspects of their themes. - -2002-03-11 Havoc Pennington - - * src/keybindings.c: use new functions - - * src/display.c (meta_display_get_tab_next): - (meta_display_get_tab_list): new tab order functions using - MRU list instead of map order - - * src/window.c (meta_window_notify_focus): maintain focus MRU list - - * src/display.h (struct _MetaDisplay): Keep an MRU list of - windows. - -2002-03-10 Havoc Pennington - - * src/display.c (event_callback): support _NET_NUMBER_OF_DESKTOPS - message so you can change number of desktops with the pager - - * src/prefs.c (meta_prefs_set_num_workspaces): new function - - * src/display.c (meta_spew_event): print stacking aspects of - configure requests - -2002-03-10 Havoc Pennington - - * src/screen.c (set_supported_hint): we didn't claim to support - _NET_ACTIVE_WINDOW so gtk_window_present() didn't work. Mumble. - Only worked with tasklist because libwnck didn't check for - WM support. - - * src/window.c (meta_window_free): clean off window state - when windows are withdrawn, to avoid sticking dialogs - to their initial desktop. - (meta_window_queue_calc_showing): return if window is withdrawn - -2002-03-08 Laszlo Peter - - * configure.in: fix the X linker flags - -2002-03-06 Havoc Pennington - - * src/core.c (meta_core_get_grab_frame): add some assertions - - * src/menu.c (meta_window_menu_new): make another warning - into a verbose - - * src/display.c (meta_change_button_grab): use verbose rather than - warning to log failures to grab button, since these are typically - BadWindow from a destroyed window. - -2002-03-06 Havoc Pennington - - * src/frames.c (meta_frames_manage_window): use hash_table_replace - instead of g_hash_table_insert - - * src/main.c (main): only enable verbose/debug if you set - METACITY_VERBOSE/METACITY_DEBUG - - * src/util.c (ensure_logfile): only use a log file if - METACITY_USE_LOGFILE is set - - * src/display.c (meta_display_for_x_display): add warning if - MetaDisplay isn't found - - * src/window.c (meta_window_free): add an assertion that we - successfully cleared the grab window - -2002-03-05 Havoc Pennington - - Work on opaque animations more, still suck too much - to turn on. Not sure how to make them good. - - * src/effects.c (meta_effects_draw_box_animation): - add a slide-up mode for shading - - * src/ui.c (meta_image_window_set): change image window to work by - setting back pixmap on the GtkWindow, instead of using GtkImage. - -2002-03-04 Havoc Pennington - - * src/main.c (main): try ignoring SIGXFSZ, though I'm not - sure what that does exactly. I'm hoping it gives me EFBIG. - - * src/util.c (ensure_logfile): log to a file in /tmp instead - of to ~/metacity.log. - -2002-03-04 Havoc Pennington - - * configure.in: fix configure.in since GTK no longer gives us - -L/usr/X11R6/lib - -2002-03-03 Havoc Pennington - - * src/window.c: improve debug spew about initial workspace - -2002-03-02 Havoc Pennington - - * src/window.c (recalc_window_features): disable resize etc. if - we're fullscreen - (constrain_size): fix size constraints when fullscreen - - * src/display.c (meta_display_open): fix missing comma that - ended up concatenating two of the properties breaking - FULLSCREEN state and PING protocol - -2002-03-02 Havoc Pennington - - * src/display.c: Add hacking to fix the problem that we made our - XGrabPointer() during Alt+Tab actually succeed, so on popping down - Alt+Tab we got an EnterNotify from the ungrab, which resulted in - focusing the window under the mouse. i.e. Alt+Tab didn't work with - sloppy focus. - -2002-02-26 Havoc Pennington - - Screw around with Anders's ping patch so he'll get plenty of CVS - conflicts. ;-) - - * src/display.c (meta_display_ping_window): spew warnings - if we try to call this with CurrentTime - (meta_display_ping_timeout): remove ping from the pending pings - after it times out. - - * src/util.h: added PING debug category - - * src/display.c (remove_pending_pings_for_window): don't remove - "tmp" just before "tmp->next", don't break out of loop after - finding the first match - (meta_display_open): no trailing comma in array init - (event_callback): move the processing of ping replies into a - separate function - - * src/screen.c (set_supported_hint): add _NET_WM_PING to supported - list - - * src/display.h: change gpointer to void* - -2002-02-26 Anders Carlsson - - * src/display.c: (ping_data_free), - (remove_pending_pings_for_window), (meta_display_open), - (event_callback), (meta_display_unregister_x_window), - (meta_display_ping_timeout), (meta_display_ping_window), - (meta_display_window_has_pending_pings): - Implement meta_display_ping_window, and filter out scroll wheel - events. - - * src/display.h: - Add MetaWindowPingFunc, meta_display_ping_window and - meta_display_window_has_pending_pings. - -2002-02-24 Havoc Pennington - - * src/display.c (xcursor_for_op): switch on the op passed in, not - the active op. Gives us the right cursor during resizing, etc. - - * src/errors.c: rearrange all the error stuff to adapt to the GDK - change a while back, so now we print our X errors again - - * src/display.c (meta_display_begin_grab_op): remove KeyPressMask - and KeyReleaseMask from the XGrabPointer(), this caused BadValue - and kept the grab from ever succeeding. Fixes the problem with the - GTK resize grip - this is why you shouldn't break your X error - spew. ;-) - - * src/display.c: debug spew tweaks - - * src/window.c (meta_window_client_message): do some - s/verbose/topic/ stuff - -2002-02-23 Havoc Pennington - - * src/ui.c (meta_ui_init): fix the - be-sure-we-create-coverage-cache hack - -2002-02-19 Havoc Pennington - - * src/ui.c (meta_ui_init): put in hack to keep Pango from mangling - our server grab and locking up on startup. (hack doesn't work - but I want to fix it on my real computer not this laptop) - - * src/window.c: Implement _NET_WM_STATE_FULLSCREEN - - * src/display.c (meta_display_open): add atoms for - _NET_WM_STATE_FULLSCREEN - -2002-02-16 Kjartan Maraas - - * src/main.c: Use bind_textdomain_codeset etc. - -2002-02-14 Havoc Pennington - - * src/theme-viewer.c: use the preview widget here - - * src/preview-widget.h, src/preview-widget.c: make the theme - preview into a nice widget - - * src/frames.c (meta_frames_ensure_layout): replace frame layout - if the frame style changes, this only ends up mattering if you - e.g. changed the font size for windows in a different state such - as maximized, which is crack, but the code may as well be correct - - * src/theme.c (meta_theme_get_frame_style): new function so we can - detect an invalid cache of the PangoLayout in a frame - -2002-02-14 Anders Carlsson - - * src/themes/Crux/metacity-theme-1.xml: Fix some bugs with - prelighting. - -2002-02-13 Anders Carlsson - - * src/theme.c (meta_pango_font_desc_get_text_height): Use - pango_context_get_metrics instead of loading the font. - -2002-02-12 Anders Carlsson - - * src/frames.c (meta_frames_manage_window): Set prelit_control - to META_FRAME_CONTROL_NONE. - (meta_frames_update_prelit_control): New function for setting - the prelit control. - (meta_frames_paint_to_drawable): Set prelight state. - (meta_frames_enter_notify_event): Update prelit control. - (meta_frames_leave_notify_event): Likewise. - (meta_frames_motion_notify_event): Likewise. - - * src/frames.h (struct _MetaUIFrame): add prelit_control. - - * src/window.c (update_mwm_hints): and MWM_FUNC_ALL - with hints->functions instead of hints->flags. - -2002-02-11 Anders Carlsson - - * src/theme.c (meta_frame_layout_new): Set title_scale to 1.0 - -2002-02-11 Bastien Nocera - - * src/theme-viewer.c: (main): change default theme to be Atlanta - like in the .schema file - -2002-02-10 Havoc Pennington - - * src/tools/Makefile.am (EXTRA_DIST): add $(icon_DATA) - - * configure.in: 2.3.55 - - * HACKING: update - - * README: update - -2002-02-09 Havoc Pennington - - * src/theme.c (meta_theme_set_current): add a newline to an error - message - - * src/themes/Gorilla: add Gorilla theme by Jakub Steiner ported to - metacity by Kenneth Christiansen - -2002-02-09 Havoc Pennington - - * src/theme.c (meta_draw_op_draw_with_env): implement wacky "tile" - draw op to lose some of the PNG files in Gorilla theme - - * src/theme-parser.c: parse the tile primitive - -2002-02-09 Havoc Pennington - - * src/window.c (update_icon): port to icon cache - - * src/iconcache.c, src/iconcache.c: begin process of cleaning up - window.c by moving the icon-reading code in here, based on the - code in libwnck, which was in turn based on the earlier metacity - code - -2002-02-09 Havoc Pennington - - * src/stack.c (meta_stack_sync_to_server): hmm, and don't set - last_window at all if we don't ++newp. Fixes even more obscure - stacking bug. - -2002-02-09 Havoc Pennington - - * src/stack.c (meta_stack_sync_to_server): assign last_window - prior to ++newp, so we don't try to stack windows with respect to - themselves. Fixes some obscure stacking bugs. - -2002-02-09 Havoc Pennington - - * src/theme-parser.c: try to make more error message strings the - same, easier for translators - - * src/theme.c (meta_draw_op_free): free color spec for line op - (meta_theme_free): free the integer_constants hash - - * src/theme-parser.c (parse_boolean): move above first use - - * src/theme-viewer.c: fixes for theme.h changes - - * src/frames.c (queue_recalc_func): don't recreate layout - immediately, just save title text. should speed things up. - (meta_frames_set_title): just remove the layout here also, - and save title text. - - * src/theme-parser.c (parse_toplevel_element): parse title_scale - attribute on frame_geometry - - * src/theme.c: support setting the text size - - * src/frames.c: support setting the text size - - * theme-format.txt: updates - -2002-02-09 Havoc Pennington - - * src/themes/Atlanta/metacity-theme-1.xml: put in some kind of - distinctive frame for UTILITY, though it's ugly. Also put in the - borderless look for maximized windows. - - * src/stack.c (compute_layer): put splash screen in the splash - layer - - * src/stack.h (enum): create a splash screen layer - - * src/place.c (meta_window_place): center splashscreen, and fix a - typo in the centering code - - * src/window.c (recalc_window_features): disable most features on - splash screens - - * src/screen.c (set_supported_hint): add UTILITY and SPLASHSCREEN - hints - - * src/window.c: add UTILITY, SPLASHSCREEN implementation - - * src/window.h (enum): add UTILITY, SPLASHSCREEN types - - * src/theme-parser.c (parse_toplevel_element): parser support - for has_title attribute - - * src/theme.c (meta_frame_layout_get_borders): handle a has_title - field in the layout, for utility windows that don't display a - title (would be better to be able to shrink the title text, - but that's kind of tricky to implement :-/) - -2002-02-08 Havoc Pennington - - * src/screen.c (set_supported_hint): add _NET_WM_STATE_HIDDEN - to _NET_SUPPORTED - - * src/keybindings.c (meta_set_keybindings_disabled): put in header - file, to fix warning. - - * src/display.c (meta_display_open): add _NET_WM_STATE_HIDDEN atom - - * src/window.c (set_net_wm_state): set _NET_WM_STATE_HIDDEN for - shaded and minimized windows - (meta_window_show): call set_net_wm_state() if we map the window - or frame - (meta_window_hide): call set_net_wm_state() if we unmap the window - or frame - -2002-02-08 Havoc Pennington - - * src/window.c (set_net_wm_state): only set skip pager/tasklist if - the app set it, don't set it again based on semantic type. - -2002-02-08 Anders Carlsson - - * src/theme.c (scale_and_alpha_pixbuf): If we're only - scaling horizontally or vertically, use GDK_INTERP_NEAREST. - -2002-02-08 Havoc Pennington - - * autogen.sh: unbreak - -2002-02-08 Havoc Pennington - - * src/display.c (meta_display_grab_focus_window_button): grab - buttons 2 and 3 also, so you can focus a window with those, - #70840 - (event_callback): fix this to let you focus a window with any - unmodified click, and also with Alt+button1 - - * configure.in (AC_OUTPUT): add po/Makefile.in - - * autogen.sh: port to glib-gettextize, remove stupid - auto-find-subdirs crap - - * Makefile.am (SUBDIRS): add po to subdirs, #70615 - - * src/window.c (meta_window_activate): unshaded window if shaded, - I thought this was in bugzilla but I don't see it. anyway thanks - whoever mentioned it to me. - -2002-02-08 Havoc Pennington - - * src/tools/metacity-window-demo.c (menu_items): add modal dialog test - -2002-02-08 Havoc Pennington - - * src/window.c (meta_window_show): when mapping a window with - struts, invalidate the work areas it's on. Should fix at least - part of the problem with windows maximizing over panels. - - * src/workspace.c (meta_workspace_invalidate_work_area): also - queue move/resize on sticky windows - - * src/tools/Makefile.am: consolidate reload-theme, restart into a - "metacity-message" app and add enable/disable keybindings to the - messages it knows about. - - * src/keybindings.c: - (meta_change_keygrab): grab keyboard synchronously - (meta_display_process_key_event): if all keybindings are toggled - off, ReplayKeyboard, else AsyncKeyboard, except that the debug - binding for toggling back on is always processed - (meta_set_keybindings_disabled): function to disable/enable - all keybindings - -2002-02-07 Havoc Pennington - - * src/run-metacity.sh: if DEMO_TEST is set then run the window - demo - - * src/tools/metacity-window-demo.c: Create an app with all the - semantic window types, for testing and for designing themes. - -2002-02-07 Havoc Pennington - - Throughout: move to meta_topic rather than meta_verbose so - metacity.log can start being more useful - - * src/util.h (enum): add more debug topics - - * src/frames.c: clean up some cruft that caused warnings - -2002-02-07 Havoc Pennington - - * src/theme.c (colorize_pixbuf): do random voodoo on the algorithm - -2002-02-07 Havoc Pennington - - * src/theme.c (colorize_pixbuf): use the intensity of the gray - pixel for both saturation and value, not just value. - -2002-02-07 Havoc Pennington - - * src/theme.c (INTENSITY): don't define the macro twice - -2002-02-07 Havoc Pennington - - * src/theme.c (colorize_pixbuf): get algorithm right (use HSV/RGB - conversion) at cost of making it a lot slower. It doesn't matter - anyhow with the cache, though. - -2002-02-06 Havoc Pennington - - * src/theme.c (colorize_pixbuf): handle out-of-memory creating - target pixbuf - - * src/themes/Crux/*.png: convert the green-channel images to grayscale - -2002-02-06 Havoc Pennington - - * src/prefs.c (change_notify): s/update_focus_mode/update_theme/ - in case of theme key changing - -2002-02-06 Havoc Pennington - - * src/theme-viewer.c: benchmark theme on startup - - * src/theme-parser.c (parse_draw_op_element): fix "colorize != - NULL" to "colorize_spec != NULL" and free pixbuf on color spec - failure - - * src/theme.c (colorize_pixbuf): minor reformatting, raise - function calls out of inner loop, clamp r/g/b values to uchar - range before assigning to uchar - (draw_op_as_pixbuf): cache the colorized pixbuf - (meta_draw_op_free): free the cache pixbuf - -2002-02-07 Anders Carlsson - - * src/theme-parser.c: (parse_draw_op_element): - Add support for "colorize" image attribute. - - * src/theme.c: (colorize_pixbuf): - New function that colorizes a pixbuf. - - (pos_tokenize): Allow "\n" as a whitespace character. - - (meta_draw_op_free): Free colorize_spec; - - (draw_op_as_pixbuf): Colorize image if needed. - - * src/theme.h: Add colorize_spec to struct. - -2002-02-07 Anders Carlsson - - * src/themes/Crux/metacity-theme-1.xml: Add maximized and - shaded_and_maximized frame styles. - -2002-02-06 Havoc Pennington - - * src/main.c (prefs_changed_callback): redo window - sizes/appearance when the theme changes - - * src/display.c (meta_display_retheme_all): new function - - * src/theme-parser.c (locate_attributes): remove error handling - for MAX_ATTRS reached, add an assert instead, the way this code - ended up the attrs in the array depend on the code not the theme - file. - -2002-02-06 Havoc Pennington - - * src/main.c (main): disable custom log handler and fatal mask for - now - - * src/theme.c (meta_draw_op_list_draw): - Add META_DRAW_CLIP - - * src/main.c: load theme, monitor current theme setting - - * src/prefs.c: add "current theme" setting - - * src/stack.c (meta_stack_free): don't try to free - last_root_children_stacked if it doesn't exist - - * src/themewidget.c: pluggable GtkMisc subclass to use - for menu icons - - * src/screen.c (meta_screen_manage_all_windows): fix - signed/unsigned warning - - * src/frames.c: port to theme system - (meta_frames_style_set): chain up - - * theme-format.txt: new file - - * configure.in: add more compiler warnings - - * src/theme.c: add various stuff needed to get theme parser - working. Remove the "spacer" concept from FrameLayout object. - Add draw op that references a draw op list. - - * configure.in: require GTK 1.3.13 - - * src/Makefile.am: add theme-parser.[hc], implement loading a - theme - - * src/theme.c: add "draw title" and "draw window icon" operations - (meta_draw_op_draw): put object_width/object_height in expression - environment before computing x/y. Handle out-of-memory when - creating pixbufs. Assorted other cleanups. - -2002-02-07 Anders Carlsson - - * src/themes/Crux/metacity-theme-1.xml: - Simplify things so we can remove some - now unnecessary .png files. - * src/themes/Crux/*.png: Remove some files. - -2002-02-07 Anders Carlsson - - * src/themes/Crux/metacity-theme-1.xml - * src/themes/Crux/*.png: - Add Crux theme - -2002-02-07 Kenneth Rohde Christiansen - - * configure.in: add da to ALL_LINGUAS - * po/da.po: add Danish translation - -2002-02-02 Havoc Pennington - - * src/theme-viewer.c: test % operator - - * src/theme.c (pos_tokenize): add % to switch for operators - - * src/theme.c: rework theme stuff so we have - MetaDrawOp/MetaDrawOpList instead of MetaTextureSpec/MetaShapeSpec - -2002-01-28 Havoc Pennington - - * src/theme.c (meta_texture_spec_render): fix shadowed variable - (stupid -Wall should have that) - - * src/theme-viewer.c (main): implement a simple - viewer for frame styles - - * src/theme.c (meta_frame_style_get_test): create partial - frame style to test drawing - -2002-01-27 Havoc Pennington - - * src/theme.c (meta_shape_spec_draw): implement - (meta_texture_spec_draw): implement shape spec and blank - texture support - (meta_frame_style_draw): implement - -2002-01-27 Havoc Pennington - - * src/display.c (meta_set_syncing): move in here so util.c doesn't - require display.[hc] - - * src/theme.h, src/theme.c: implement coordinate expression - parser, write MetaShapeSpec declaration - - * src/util.c (meta_exit): move in here so we can link - to util.c with a different main() - - * src/theme.h: rename the MetaWindow* enums to MetaFrame* - -2002-01-27 Peteris Krisjanis - - * configure.in - Added lv to ALL_LINGUAS - -2002-01-27 Havoc Pennington - - * src/frames.c (get_control): Only consider the bottom of the - titlebar a resize control; I keep accidentally resizing windows - instead of activating them. Also, give south resizing priority - over north, if the window is so small the active regions overlap - - * src/theme.c: add MetaTheme, get MetaFrameStyleSet into - a usable state - - * src/common.h: move window type back to window.h, decided - not to use it on frame side - (MetaFrameType): add this instead - -2002-01-27 Havoc Pennington - - * src/theme.h, src/theme.c: implement all kinds of crazy - compositing-one-texture-onto-another BS. - -2002-01-27 Havoc Pennington - - * src/display.c (event_callback): make the check for whether to - eat focus click a lot more complicated - - * src/window.c (meta_window_same_application): new function - - * src/prefs.h, src/prefs.c: add application based pref - - * src/metacity.schemas: add "application_based" setting to - give me a mode to fool with being application based, - without being unusable in the meantime. Yeah the crack flows - freely these days. Everyone knew it would happen. - -2002-01-27 Havoc Pennington - - * src/frames.c: separate code to draw frame from the - expose_event handler, so in principle we can draw the - frame to a pixmap, but this isn't used yet. - -2002-01-22 Hasbullah Bin Pit - - * configure.in: Added Malay (ms)to ALL_LINGUAS. - * po/ms.po: Added Malay Translation. - -2002-01-19 Havoc Pennington - - * src/wm-tester/test-resizing.c: cheesy client with static - bit gravity, used to test the below change. - - * src/window.c (meta_window_move_resize_internal): implement - Owen's proposal for window resizing. - http://mail.gnome.org/archives/wm-spec-list/1999-November/msg00088.html - - Currently you have to do METACITY_USE_STATIC_GRAVITY=1 in order to - use it, because some GDK bug is screwing up exposes on my frames - when it's enabled. - - * src/display.c (meta_display_create_x_cursor): fix glyph for - NE/NW cursors - - * src/frames.c (get_control): add ability to resize from top - - * src/frame.c (meta_frame_get_flags): can't resize shaded windows - (meta_frame_sync_to_window): add gravity arg - - * src/common.h (MetaWindowType): move here from window.h so - it can be used in themes stuff. - (MetaFrameFlags): remove META_FRAME_TRANSIENT since it - overlaps with window type and was unused. - -2002-01-18 Havoc Pennington - - * src/window.c (constrain_position): give priority to keeping NW - corner onscreen rather than SE, if we need to shift the window - to fit inside constraints - - * src/frames.c (meta_frames_get_geometry): don't depend on the - current window size - - * src/theme.c: move geometry stuff in here, to be calculated as - part of the theme - - * src/core.c (meta_core_get_client_size): new function to replace - meta_core_get_frame_size() so we don't have weird cycles - in the geometry calculation - -2002-01-12 Havoc Pennington - - * src/window.c (meta_window_queue_move_resize): make this actually - queue, rather than being synchronous as it was before. We'll see - what breaks. Should be more efficient and reduce flickery stuff a - bit in some cases. - -2002-01-15 Havoc Pennington - - * src/keybindings.c (handle_tab_backward): fix crash - when grab failed due to another operation in progress - (handle_tab_forward): fix crash when grab failed - -2002-01-10 Havoc Pennington - - * src/frame.c (meta_window_destroy_frame): only bump - unmaps_pending if the window was mapped - (meta_window_ensure_frame): ditto - - * src/keybindings.c: change arrow key bindings to use Ctrl+Alt not - just Alt, and add debug mode key bindings - - * src/stack.c (meta_stack_get_default_focus_window): don't choose - a default focus window with unmaps pending, since we probably just - unmapped it. - - * src/display.c (event_callback): move notify_focus on UnmapNotify - after the window_free check, so we can move focus to another - window when we unmanage - - * src/window.c (meta_window_hide): invalidate work areas when - hiding a window with struts - (meta_window_free): invalidate work areas when unmanaging a window - with struts - -2002-01-09 Havoc Pennington - - * src/window.c, src/window.h: store strut information, - update it on property changes, etc. etc. so we avoid panel - on maximize. - - * src/workspace.c (meta_workspace_get_work_area): add accessor for - work area so we can compute it lazily - - * src/display.h, src/display.c: add _NET_WM_STRUT atom - and _WIN_HINTS atom - -2002-01-08 Havoc Pennington - - * configure.in (ACLOCAL): add code to save ACLOCAL_FLAGS - - * src/frames.c (meta_frames_expose_event): max dither - - * src/testgradient.c (render_simple): change dither mode to MAX - to avoid banding - - * src/theme.c: lose the gradient cache, and put in some initial - data types for the theme format - -2002-01-07 Havoc Pennington - - * src/frames.c (meta_frames_expose_event): make gradient a bit - more subtle (don't go to the full background, but to a blend of - selection and background; put lighter color on top) - -2002-01-06 Havoc Pennington - - * src/window.c (meta_window_notify_focus): rearrange code a bit to - make it clear that has_focus flag always follows - display->focus_window - -2002-01-06 Havoc Pennington - - * src/window.c (meta_window_notify_focus): put in attempted fix - for the GTK 1.2 plug/socket screwup, now that my fixed debug spew - reveals what's actually happening. ;-) - - * src/gradient.c (meta_gradient_description_new): object - to store gradient descriptions - - * src/window.c (meta_window_notify_focus): fix the debug spew - that was confusing me - - * src/wm-tester/focus-window.c: add little program to focus - a window ID - -2002-01-06 Havoc Pennington - - * src/theme.c (meta_theme_get_gradient): change to use spiffy - gradient code. - - * src/gradient.c: copy lovely gradient code from WindowMaker, - as usual Dan and Alfredo have very nice code - -2002-01-06 Fatih Demir - - * configure.in: Added "tr" to the languages list. - -2002-01-05 Havoc Pennington - - * src/frames.c (meta_frames_expose_event): draw titlebar highlight - with snazzy gradient that needs some tweaking to be less - dumb-looking - - * src/theme.c: replace old theme.[hc] contents with newer stuff - that doesn't do anything - -2002-01-05 Havoc Pennington - - GTK 1.2 plug/socket clients still broken, don't know why. - - * src/screen.c (meta_screen_new): select focus change on root - window, for debugging - - * src/display.c (event_callback): when unfocusing, use - no_focus_window to hold the focus - - * src/display.h (struct _MetaDisplay): have a no_focus_window to - hold the focus when we don't want to have anything focused. - Then we can avoid confusing focusing-the-frame stuff. - - * src/window.c (meta_window_notify_focus): improve some debug spew - (meta_window_notify_focus): add hack from WindowMaker to ignore - focus in events with detail > NotifyNonlinearVirtual - -2002-01-04 Havoc Pennington - - * src/display.c (event_callback): don't lower docks when a grab - causes them to get LeaveNotify - -2002-01-04 Havoc Pennington - - * src/screen.c (meta_screen_free): set event mask on root window - to 0 so other window managers (such as ourselves restarting) can - start up; addresses race condition on restart where the old WM - still had RedirectMask when the new WM was trying to start up. - - * src/display.c (meta_display_close): free each screen - - * src/window.c (meta_window_show): always focus new windows in - click-to-focus mode - -2002-01-03 Havoc Pennington - - * src/window.c: use meta_XFree not XFree - - * src/display.h (meta_XFree): add null-safe XFree - - * src/util.c (meta_warning): have message prefix indicate that - it's a warning - (meta_fatal): indicate it's an error - - * src/window.c (update_sm_hints): clean up using - meta_prop_get_latin1_string - (update_role): ditto - (read_client_leader): clean up using meta_prop_get_window - (update_net_wm_type): clean up using meta_prop_get_cardinal - (update_initial_workspace): ditto - (update_net_wm_type): clean up using meta_prop_get_atom_list - (read_rgb_icon): get result from XGetWindowProperty return value - not from error trap - (update_kwm_icon): ditto - (meta_window_new): fix to read WM_STATE correctly - -2002-01-03 Havoc Pennington - - * src/window.c (update_net_wm_state): clean up using - meta_prop_get_atom_list - (update_mwm_hints): clean up using meta_prop_get_motif_hints - - * src/Makefile.am (metacity_SOURCES): add xprops.[hc] - - * src/xprops.c: new file with convenience functions for X - properties - -2002-01-03 Havoc Pennington - - * src/workspace.c (meta_workspace_activate): focus top window when - switching to a new workspace - - * src/util.c (meta_topic): start putting verbose output in - categories - - * src/window.c (meta_window_shade): focus frame after we queue - the calc_showing so the maps/unmaps have already happened. - - * src/display.c (meta_display_get_current_time): add the "get time - of current event" function and call it occasionally. - - * src/window.c (meta_window_free): if we have focus, call - meta_screen_focus_top_window(). - (meta_window_minimize): ditto - (meta_window_delete): ditto - - * src/screen.c (meta_screen_ensure_tab_popup): fix memory leak - - didn't free tab list - (meta_screen_focus_top_window): new function to use when we unmap - or unmanage a focused window - - * src/stack.c (meta_stack_get_default_focus_window): function used - in meta_screen_focus_top_window - -2001-12-21 Havoc Pennington - - * src/frame.c (meta_window_ensure_frame): add a server grab - here since we were failing to have one when calling the function - -2001-12-27 Duarte Loreto - - * configure.in: Added portuguese to ALL_LINGUAS - -2001-12-16 Kjartan Maraas - - * configure.in: Added "no" to ALL_LINGUAS. - -2001-12-11 Stanislav Visnovsky - - * configure.in: Added "sk" to ALL_LINGUAS. - -2001-12-10 Havoc Pennington - - Rework the click-client-area-to-focus support to use synchronous - grabs, avoids a big mess, lets us pass through click when - required (for dock/desktop). Disadvantage is all left-button - clicks now require window manager approval. ;-) - - * src/display.c (event_callback): don't focus dock/desktop when - the mouse enters them; require a click. - (meta_change_button_grab): allow sync grabs - (meta_display_grab_unfocused_window_buttons): establish a - synchronous grab and maintain it all the time, rename to - meta_display_grab_focus_window_button - - * src/window.c: change to reflect display.c - -2001-12-10 Havoc Pennington - - * src/window.c (meta_window_update_unfocused_button_grabs): oops, - unbreak this _again_ - reported by Josh Barrow - -2001-12-10 Havoc Pennington - - * src/window.c (meta_window_update_unfocused_button_grabs): don't - allow grab on docks/desktop for now; needs fixing later to - do the grab, but pass thru click, so we can focus those windows. - And in fact we need to do that even in sloppy mode. - -2001-12-10 Havoc Pennington - - * src/screen.c (meta_screen_foreach_window): fix broken - "tmp = tmp->data" - - Implement do-not-pass-thru-click for click-to-focus mode. - - * src/screen.c (update_focus_mode): when focus mode changes, - update all the window grabs - - * src/display.c (meta_display_grab_unfocused_window_buttons): - implement grabbing button 1 on client area of unfocused - click-to-focus windows - - * src/window.c (meta_window_update_unfocused_button_grabs): update - whether we're grabbing unmodified button 1 on client area - according to focus state and focus mode - (meta_window_new): start out with proper grab state - -2001-12-10 Havoc Pennington - - * src/menu.c (meta_window_menu_new): don't do mnemonics for - workspaces above 9 - -2001-12-10 Havoc Pennington - - * src/screen.c (meta_screen_new): oops, remove extra workspace - creation, and update to current pref. - -2001-12-09 Havoc Pennington - - * src/workspace.c (meta_workspace_free): update number of - workspaces hint - - * src/screen.c (update_num_workspaces): implement number of - workspaces setting - - * src/window.c (meta_window_configure_request): honor configure - requests on windows of type NORMAL, but still be mean to those of - type DIALOG - - * src/main.c (main): add more log domains to those we set a log - handler for, and only set warnings fatal in debug mode - - * src/metacity.schemas: add number of workspaces setting - -2001-12-09 Havoc Pennington - - * src/display.c (event_callback): in click-to-focus mode don't - focus on enter notify. Implement unfocusing on LeaveNotify in - mouse focus mode. Click to focus just ends up working if we - do nothing on enter/leave, because of the way things already - worked. Except I need to add some relatively complex hack to - allow clicking on client area, right now you have to click - on the frame. - -2001-12-09 Havoc Pennington - - * src/main.c (main): move SM init a bit later in the process, and - init prefs - - * src/session.c: fix no SM case (though I hardly know why I'm - bothering) - - * src/main.c (main): call bindtextdomain - - * src/util.h (_): actually call gettext - - * configure.in: put in AM_GLIB_GNU_GETTEXT and gconf stuff - - * src/prefs.c: Preferences - this marks the beginning of our doom. - None of them are actually implemented yet, but we monitor - some stuff from gconf. - -2001-12-07 Havoc Pennington - - * src/window.c (meta_window_unminimize): when unminimizing an app, - if we're in "show desktop" (all windows minimized) mode, leave - show desktop mode. Will occasionally be a bit weird, but allows - people to recover via task list if they accidentally do the show - desktop thing, and don't know what's going on. - -2001-12-06 Havoc Pennington - - * src/ui.c (meta_text_property_to_utf8): fix gdkatom/xatom screwup - - gee, I should read my warnings - -2001-12-03 Laszlo Peter - - * src/frames.c: add a dummy element to the enum so - the signals array is not empty. (breaks the build with Forte C) - - * src/window.c: s/__FUNCTION__/G_GNUC_FUNCTION/ - -2001-11-27 Havoc Pennington - - * src/window.c (constrain_position): change so that window can be - offscreen to the bottom or the right, as long as a small top-left - corner of the window remains onscreen. However, windows still - can't go off the left or top. - -2001-11-26 Havoc Pennington - - * src/window.c (window_query_root_pointer): add error trap - -2001-11-27 Jesus Bravo Alvarez - - * configure.in: Added gl (Galician) to ALL_LINGUAS. - -Tue Nov 20 18:49:16 2001 Owen Taylor - - * configure.in (found_sm): Add some additional quoting to - make it work with autoconf-2.5x. - -2001-11-02 Laszlo Peter - - * src/window.c (update_sm_hints): protect meta_verbose from - a NULL pointer. - -2001-10-29 Havoc Pennington - - * configure.in: bump version - -2001-10-29 Havoc Pennington - - * src/window.c (idle_calc_showing): handle queue/unqueue of - calc showings as we are iterating over the pending list - (meta_window_show): focus placed transients in here instead - of in meta_window_place - now it should actually work, yay - - * src/place.c (meta_window_place): remove focusing of transient - child from here; this was really broken - -2001-10-29 Yuriy Syrota - - * configure.in: Added "uk" to ALL_LINGUAS. - -2001-10-29 Havoc Pennington - - * README: note exciting new unminimize feature for the tab popup - - * src/keybindings.c (process_tab_grab): use meta_window_activate() - when choosing a window with tab popup, this should deiconify it - - * src/window.c (meta_window_client_message): use - meta_window_activate for _NET_ACTIVE_WINDOW message - (meta_window_activate): new function to raise/focus/unminimize - (meta_window_flush_calc_showing): new function - (meta_window_focus): force a calc showing on focus, so that we can - focus the window if appropriate (it must be mapped) - -2001-10-26 Havoc Pennington - - * src/display.c (meta_display_grab_window_buttons): fix for - ignoring NumLock on Alt-windowclick (previous NumLock fix - was only for key grabs not button grabs) - -2001-10-25 Havoc Pennington - - * src/window.c (meta_window_new): set the current workspace hint - -2001-10-25 Havoc Pennington - - * src/window.c (meta_window_visible_on_workspace): - I was using meta_workspace_contains_window() in a number of - places where on_all_workspaces should also have been considered, - thus this new function. Fixes bugs such as pinned windows - not appearing in the tab order. - (meta_window_client_message): use meta_window_visible_on_workspace - - * src/stack.c (find_tab_forward): ditto - (find_tab_backward): ditto - (meta_stack_get_tab_next): ditto - (meta_stack_get_tab_list): ditto - - * src/place.c (get_windows_on_same_workspace): ditto - - * src/keybindings.c (handle_focus_previous): ditto - (handle_focus_previous): ditto - -2001-10-24 Havoc Pennington - - * src/frames.c (meta_frames_expose_event): use bg/fg not base/text - for the window title area. - -2001-10-24 Havoc Pennington - - * src/window.c (meta_window_new): support initial - on-all-workspaces setting - -2001-10-22 Havoc Pennington - - * src/stack.c (meta_stack_sync_to_server): fix to keep desktop - window from appearing on top of everything else, among other stack - bugs. Untested. - -2001-10-15 Havoc Pennington - - * src/window.c (meta_window_new): use queried attributes to check - whether window should be initially maximized, rather than window - rect - -2001-10-15 Havoc Pennington - - * src/main.c (meta_restart): add a restart feature, for debugging - - * src/tools/metacity-restart.c: little utility program to trigger - the restart - -2001-10-14 Havoc Pennington - - * src/frames.c (meta_frames_button_press_event): raise/focus - windows on left-click, seem to have broken that yesterday - - * src/keybindings.c, src/display.c, src/window.c: add keybinding - to show/hide all normal windows (so you can see the desktop). - Currently Ctrl+Alt+D, which I don't like, but yay. - -2001-10-14 Havoc Pennington - - * src/window.c (meta_window_new): take a window mapped at - fullscreen size/pos to desire maximization; once I add a - fullscreen state, will change to copy kwin and take this mapping - as a desire for fullscreen, but for now testing with maximization. - - * src/window.h: remove fullscreen window type, now proposing it - as a window state instead. - -2001-10-14 Havoc Pennington - - * src/window.c (meta_window_maximize): always raise windows on - maximize - (meta_window_client_message): when activating a window, move - it to current workspace, instead of moving user to the - window's workspace. - -2001-10-14 HÃ�©ctor GarcÃ�­a Ã�lvarez - - * configure.in: Added "es" to ALL_LINGUAS for Spanish translation. - -2001-10-14 Havoc Pennington - - * src/display.c (event_callback): only handle events here if - the modmask from our button grab is active. i.e. only the - Alt-click is handled here. - - * src/frames.c: add check for whether button presses are in the - frame client area before handling them, so we don't weirdly let - you move a frame by clicking in its client area if the client - hasn't selected button press events. - -2001-10-13 Havoc Pennington - - * src/stack.c (meta_stack_sync_to_server): set last window before - setting newp, so we don't get the current window as the last - window and screw everything up - (IN_TAB_CHAIN): use type not layer to decide if a window is - in the tab chain, keeps panel out of alt-tab choices - -2001-10-13 Havoc Pennington - - * configure.in: add bad hack to work with GTK 1.3.9.90 RPMs from - gnomehide for now - - * src/ui.c: another piece of bad hack in here - -2001-10-13 Havoc Pennington - - * configure.in: bump version - -2001-10-13 Havoc Pennington - - * src/session.c (meta_session_init): hmm, fix build - -2001-10-12 Havoc Pennington - - * src/session.c (meta_session_init): set the session manager - priority so we start up before other apps. - -2001-10-12 Mikael Hallendal - - * src/ui.c (meta_ui_get_default_window_icon): use - gdk_pixbuf_new_from_inline - (meta_ui_get_default_mini_icon): use - gdk_pixbuf_new_from_inline - -2001-10-11 Christian Rose - - * configure.in: Added "sv" to ALL_LINGUAS. - -2001-10-10 Havoc Pennington - - * src/stack.c (meta_stack_free): fix mem leak of the MetaStack - object - (meta_stack_sync_to_server): try to avoid the restack-flicker - thing - -2001-10-07 Havoc Pennington - - * src/display.c (meta_display_update_active_window_hint): - set _NET_ACTIVE_WINDOW hint - - * src/window.c (meta_window_client_message): support - _NET_ACTIVE_WINDOW client message - -2001-10-07 Havoc Pennington - - * src/window.c (meta_window_client_message): don't allow - shade/maximize/minimize for windows that don't support those - operations. (minimizing the panel = bad) - -2001-10-04 Havoc Pennington - - * src/keybindings.c (meta_change_keygrab): add code to grab all - modifier combinations, so keybindings work with NumLock etc. - - * src/menu.c (meta_window_menu_new): remove newlines from menu - items - -2001-09-27 Havoc Pennington - - * src/session.c (save_state): when encoding text for session file, - escape XML entities - -2001-09-21 Alex Graveley - - * src/Makefile.am (metacity_SOURCES): Add inlinepixbufs.h so - that it gets generated. - - * src/frames.c (meta_frames_style_set): Update for new opaque - PangoFontMetrics. - -2001-09-17 Havoc Pennington - - * src/ui.c (meta_ui_init): add hackaround for the warning about - gtk-menu-bar-accel - -2001-09-17 Havoc Pennington - - * src/ui.c (meta_ui_get_default_mini_icon): - (meta_ui_get_default_window_icon): ref the returned icon, oops. - - * src/main.c (main): get the GLib warning/error output into - the metacity logfile, set warnings to be always fatal - - * configure.in: bump version to 2.3.13 - - * src/window.c (get_text_property): hrm, fix bug where we didn't - check errors on XGetTextProperty - -2001-09-17 Havoc Pennington - - * src/Makefile.am (VARIABLES): fix srcdir != builddir glitch - -2001-09-17 Havoc Pennington - - * src/ui.c: use the inline image data for default icon - - * src/common.h (META_MINI_ICON_HEIGHT): move icon size defines - here - - * src/Makefile.am: Create an inlinepixbufs.h header with inline - images - -2001-09-16 Havoc Pennington - - * src/session.c (process_ice_messages): disconnect this callback - on error - -2001-09-16 Havoc Pennington - - * src/window.c (meta_window_lower): new function - - * configure.in: bump version to 2.3.8 - - * src/display.c (event_callback): raise dock on enter notify, - lower it on leave notify (need to refine this behavior) - - * src/stack.c (compute_layer): experiment with putting the panel - in the normal layer, and raising it on mouseover - -2001-09-15 Havoc Pennington - - * src/window.c: add support for a mini icon in the titlebar - (update_icon): re-enable support for _NET_WM_ICON - - * src/session.c (save_state): add an ferror check when writing - session file - -2001-09-11 Havoc Pennington - - * src/main.c (usage): exit with error code on usage() (kind of - wrong for --help, but oh well). - -2001-09-11 Havoc Pennington - - * src/window.c: fix up handling of text properties, so we - get UTF8_STRING as that type and not as text list, and so - we properly convert from text list to UTF-8 - -2001-09-10 Havoc Pennington - - * src/menu.c (meta_window_menu_new): icon for unmaximize - - * src/ui.c (meta_ui_init): fix call to XDisplayName - - * src/util.c: add missing header - - * src/frames.c: draw an unmaximize control if already maximized - -2001-09-10 Havoc Pennington - - * src/window.c: Don't separate user_has_moved/user_has_resized, - fixes bug in east-resizing Emacs, among other things - - * src/frame.c (meta_frame_sync_to_window): return immediately if - nothing to do - - * src/util.c (ensure_logfile): replace rather than truncate old - logfiles - -2001-09-08 Havoc Pennington - - * src/ui.c (meta_ui_init): don't use gdk_display_name - - * src/frame.c (meta_window_ensure_frame): create frame - with screen default visual, rather than client window visual; - for DRI games, the client window visual was not allowed to be - a child of another window with the same visual, apparently. - Anyhow now we copy twm, etc. so it must be correct. - - * src/place.c (meta_window_place): if a transient is placed and - its parent has focus, focus the transient. - -2001-09-06 Havoc Pennington - - * configure.in: bump version 2.3.5, require newer GTK release - -2001-09-04 Havoc Pennington - - * src/wm-tester/Makefile.am (noinst_PROGRAMS): make test apps - noinst - - * src/metacity.desktop: for the capplet - - * src/Makefile.am: add .desktop file - -2001-09-01 Havoc Pennington - - * src/errors.c: clean up the code, and replace GDK X error handler - with one that chains up to GDK but first logs the error to logfile. - -2001-08-31 Havoc Pennington - - * src/tabpopup.c (meta_ui_tab_popup_new): fix args to - gtk_alignment_new() - -2001-08-29 Havoc Pennington - - * src/display.c (event_callback): avoid focusing a window on tab - popup popdown - - * src/screen.c (meta_screen_ensure_tab_popup): compute frame - outline size here - -2001-08-29 Havoc Pennington - - * src/tabpopup.c: Switch back to outline. - -2001-08-29 Havoc Pennington - - * src/tabpopup.c: experiment with window-cover-with-icon - instead of just the outline; can't decide. - -2001-08-29 Havoc Pennington - - * src/tabpopup.c: add crackrock window-outlining feature - - * src/session.c (window_type_to_string): handle fullscreen - -2001-08-29 Havoc Pennington - - * src/display.c (meta_display_open): wrong atom name - - _NET_SUPPORTED not _NET_WM_SUPPORTED - - * src/window.c (meta_window_configure_request): geez, why were we - honoring configure requests for width/height for normal windows. - Denied! - (meta_window_client_message): _NET_WM_MOVERESIZE support, sort of - (doesn't quite work, acts like owner_events = true?) - - * src/display.c: add _NET_WM_MOVERESIZE atom - -2001-08-28 Havoc Pennington - - Unbreak tab popup a bit. - - * src/stack.c (meta_stack_get_tab_list): add workspace argument - (meta_stack_get_tab_next): add workspace argument - - * src/window.c: implement recording of the last user-initiated - window position, so we can magically handle moving panels around - really nicely. - - * src/wm-tester/main.c (set_up_icon_windows): fix to use new GTK - API - -2001-08-24 Havoc Pennington - - * src/window.c (constrain_position): force fullscreen windows to - be at 0,0 - - * src/ui.c: use NULL colormap to get bitmaps, requires - very latest GTK from CVS or it will spew warnings - and not work. - - * src/window.c (constrain_size): disallow larger than screen in - all cases, even if user has performed a resize operation. - (constrain_position): keep window boxed onscreen. - - * src/keybindings.c (meta_display_process_key_event): revert an - earlier change that disabled global keybindings when a grab is in - effect; instead, only disable global keybindings if a _keyboard_ - grab is in effect. The earlier change was just a broken - workaround, the problems it fixed should have been solved by the - addition of XGrabKeyboard() on the metacity keyboard grabs. - - This should fix the problem with - pick-up-window-and-move-to-another-desktop. - -2001-08-23 Havoc Pennington - - * src/window.c (update_icon): attempt to use the mask as well as - the pixmap. Probably doesn't work so well. - - * src/tabpopup.c: make this look a little nicer - -2001-08-22 Havoc Pennington - - * src/window.c (update_mwm_hints): all the MWM flag tests were - backward - -2001-08-22 Havoc Pennington - - * src/window.c (update_icon): half-ass implementation of - getting pixmap icons (WM_NORMAL_HINTS and KWM_WIN_ICON). - Ignores mask for now, with possibly ugly results for - some apps. - (read_rgb_icon): fixage - -2001-08-19 Havoc Pennington - - * src/window.c: add a "fullscreen" semantic type; if a window - requests the screen size exactly, and is undecorated, and is not a - desktop window, we consider it a fullscreen window and keep it on - top. - - Totally untested. - -2001-08-19 Havoc Pennington - - * src/screen.c (set_supported_hint): we support _NET_WM_ICON - - * src/wm-tester/main.c: add stuff to test _NET_WM_ICON - (but it doesn't work, so it isn't tested yet) - - * src/window.c (update_icon): read _NET_WM_ICON - - * src/screen.c (meta_screen_new): set the WM_ICON_SIZE hint - - * src/tabpopup.c (meta_ui_tab_popup_select): remove assertion - - * src/window.c (meta_window_get_icon_geometry): fix obscure - memleak - -2001-08-19 Havoc Pennington - - * src/display.c (meta_display_grab_window_buttons): remove XSync, - error traps already do that - (meta_display_grab_window_buttons): implement - - * src/keybindings.c: - src/display.c: wire up the tab window, it rulez! - -2001-08-19 Havoc Pennington - - * src/tabpopup.c: add prototype thingy to display windows we're - cycling through with tab. Not wired up to keybindings yet. - -2001-08-18 Havoc Pennington - - * src/effects.c (meta_effects_draw_box_animation): put an XFlush() - right after starting things moving - -2001-08-18 Havoc Pennington - - * src/window.c (meta_window_configure_request): - (meta_window_move_resize_internal): Make a half-hearted - not-very-tested attempt to handle window resizes correctly with - respect to window gravity. - -2001-08-18 Havoc Pennington - - * src/window.c (meta_window_get_gravity_position): hrm, I fixed - this wrong the other day. Fixes static gravity when moving - windows. - -2001-08-18 Havoc Pennington - - * src/ui.c (meta_image_window_set_position): also set the current - size. Lame hack of the day. - - * src/effects.c (effects_draw_box_animation_timeout): use the - delay exposes feature to avoid the screen dirt - - * src/ui.c - (meta_ui_push_delay_exposes): - (meta_ui_pop_delay_exposes): feature to let us delay redraws until - after we do server-grabbed draw-on-inferiors effects - -2001-08-17 Havoc Pennington - - * src/window.c (meta_window_get_gravity_position): fix for - StaticGravity - -2001-08-09 Havoc Pennington - - * src/window.c (meta_window_configure_request): Honor USPosition - even post-map. I know I'll regret this. - -2001-08-07 Havoc Pennington - - * src/display.c (meta_display_open): set _NET_WM_NAME - hint as a UTF8_STRING not STRING. Patch from Anders. - -2001-08-06 Havoc Pennington - - * src/effects.c: disable opaque animations by default, current - implementation suXors. - -2001-08-06 Havoc Pennington - - * src/effects.c (meta_effects_draw_box_animation): Get start - time after we do the pixbuf from drawable, so we don't count - time spent getting pixbuf from drawable in the animation time. - -2001-08-06 Havoc Pennington - - * src/effects.c: add opaque minimize/shade feature. The wireframe - seemed kind of confusing and unclear from a UI standpoint. - I know, I know. The bloat begins here. - - Also, we don't need to grab the server during opaque min/shade, - which has some nice implications. - - * src/ui.c: Add features to render a window with an image in it, - and also wrap pixbuf_from_drawable - - * src/effects.c (meta_effects_draw_box_animation): - modify to be smoother (at least theoretically) by - syncing to current time and "dropping frames" - as appropriate. - - * src/window.c (meta_window_shade): draw animation - for shading too - -2001-08-05 Anders Carlsson - - * src/display.h, src/display.c: Add _NET_WM_ICON_GEOMETRY atom. - - * src/window.c (meta_window_calc_showing): See if the window has - an icon geometry and show a morphing animation from the window's - coordinates to the icon's coordinates. - (meta_window_get_icon_geometry): New function that fetches a - window's icon geometry. - - * src/Makefile.am: Add effects.[ch]. - - * src/effects.c: New file with cool effects. - -2001-08-03 Havoc Pennington - - * src/keybindings.c: Add Alt + left/right arrow to - move between workspaces. - - * src/screen.c (set_wm_check_hint): put property pointing back to - itself on the _WIN_SUPPORTING_WM_CHECK window. - -2001-08-03 Havoc Pennington - - * src/display.c (event_callback): push error trap around configure - of withdrawn window, fixes a crash caused by rapidly - creating/destroying a window. - - * src/window.c (recalc_window_features): don't allow shading - undecorated windows. - - * src/wm-tester/main.c: add a program to torture window managers. - -2001-08-01 Havoc Pennington - - * src/window.c (recalc_window_features): if a window isn't - resizeable, turn off maximize function. If min size is equal to - max size, turn off resize function. - diff --git a/Doxyfile b/Doxyfile deleted file mode 100644 index a8a75411a..000000000 --- a/Doxyfile +++ /dev/null @@ -1,1297 +0,0 @@ -# Doxyfile 1.5.3 - -# This is the doxyfile for Metacity. - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project -# -# All text after a hash (#) is considered a comment and will be ignored -# The format is: -# TAG = value [value, ...] -# For lists items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" ") - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# This tag specifies the encoding used for all characters in the config file that -# follow. The default is UTF-8 which is also the encoding used for all text before -# the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into -# libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of -# possible encodings. - -DOXYFILE_ENCODING = UTF-8 - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded -# by quotes) that should identify the project. - -PROJECT_NAME = metacity - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. - -# Do not enter a setting here; it will only get out of date. -PROJECT_NUMBER = - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. - -OUTPUT_DIRECTORY = doc - -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of -# source files, where putting all generated files in the same directory would -# otherwise cause performance problems for the file system. - -CREATE_SUBDIRS = NO - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, -# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, -# Italian, Japanese, Japanese-en (Japanese with English messages), Korean, -# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, -# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian. - -OUTPUT_LANGUAGE = English - -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. - -REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is -# used as the annotated text. Otherwise, the brief description is used as-is. -# If left blank, the following values are used ("$name" is automatically -# replaced with the name of the entity): "The $name class" "The $name widget" -# "The $name file" "is" "provides" "specifies" "contains" -# "represents" "a" "an" "the" - -ABBREVIATE_BRIEF = - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief -# description. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. - -INLINE_INHERITED_MEMB = NO - -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. - -FULL_PATH_NAMES = YES - -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the -# path to strip. - -STRIP_FROM_PATH = - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that -# are normally passed to the compiler using the -I flag. - -STRIP_FROM_INC_PATH = - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful is your file systems -# doesn't support long names like on DOS, Mac, or CD-ROM. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like regular Qt-style comments -# (thus requiring an explicit @brief command for a brief description.) - -JAVADOC_AUTOBRIEF = YES - -# If the QT_AUTOBRIEF tag is set to YES then Doxygen will -# interpret the first line (until the first dot) of a Qt-style -# comment as the brief description. If set to NO, the comments -# will behave just like regular Qt-style comments (thus requiring -# an explicit \brief command for a brief description.) - -QT_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed -# description. Set this tag to YES if you prefer the old behaviour instead. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the DETAILS_AT_TOP tag is set to YES then Doxygen -# will output the detailed description near the top, like JavaDoc. -# If set to NO, the detailed description appears after the member -# documentation. - -DETAILS_AT_TOP = NO - -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# re-implements. - -INHERIT_DOCS = YES - -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will -# be part of the file/class/namespace that contains it. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. - -TAB_SIZE = 8 - -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. - -ALIASES = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list -# of all members will be omitted, etc. - -OPTIMIZE_OUTPUT_FOR_C = YES - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java -# sources only. Doxygen will then generate output that is more tailored for Java. -# For instance, namespaces will be presented as packages, qualified scopes -# will look different, etc. - -OPTIMIZE_OUTPUT_JAVA = NO - -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to -# include (a tag file for) the STL sources as input, then you should -# set this tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. -# func(std::string) {}). This also make the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. - -BUILTIN_STL_SUPPORT = NO - -# If you use Microsoft's C++/CLI language, you should set this option to YES to -# enable parsing support. - -CPP_CLI_SUPPORT = NO - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. - -DISTRIBUTE_GROUP_DOC = NO - -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using -# the \nosubgrouping command. - -SUBGROUPING = YES - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES - -EXTRACT_ALL = YES - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - -EXTRACT_PRIVATE = YES - -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. - -EXTRACT_STATIC = YES - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. - -EXTRACT_LOCAL_CLASSES = YES - -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. -# If set to NO (the default) only methods in the interface are included. - -EXTRACT_LOCAL_METHODS = NO - -# If this flag is set to YES, the members of anonymous namespaces will be extracted -# and appear in the documentation as a namespace called 'anonymous_namespace{file}', -# where file will be replaced with the base name of the file that contains the anonymous -# namespace. By default anonymous namespace are hidden. - -EXTRACT_ANON_NSPACES = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_CLASSES = NO - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the -# documentation. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the -# function's detailed documentation block. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. - -INTERNAL_DOCS = NO - -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. - -CASE_SENSE_NAMES = YES - -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. - -HIDE_SCOPE_NAMES = NO - -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation -# of that file. - -SHOW_INCLUDE_FILES = NO - -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] -# is inserted in the documentation for inline members. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in -# declaration order. - -SORT_MEMBER_DOCS = YES - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in -# declaration order. - -SORT_BRIEF_DOCS = NO - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the -# alphabetical list. - -SORT_BY_SCOPE_NAME = NO - -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo -# commands in the documentation. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test -# commands in the documentation. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug -# commands in the documentation. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting -# \deprecated commands in the documentation. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or define consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and defines in the -# documentation can be controlled using \showinitializer or \hideinitializer -# command in the documentation regardless of this setting. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the -# list will mention the files that were used to generate the documentation. - -SHOW_USED_FILES = YES - -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy -# in the documentation. The default is NO. - -SHOW_DIRECTORIES = YES - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from the -# version control system). Doxygen will invoke the program by executing (via -# popen()) the command , where is the value of -# the FILE_VERSION_FILTER tag, and is the name of an input file -# provided by doxygen. Whatever the program writes to standard output -# is used as the file version. See the manual for examples. - -FILE_VERSION_FILTER = - -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. - -QUIET = YES - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. - -WARNINGS = YES - -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will -# automatically be disabled. - -WARN_IF_UNDOCUMENTED = YES - -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that -# don't exist or using markup commands wrongly. - -WARN_IF_DOC_ERROR = YES - -# This WARN_NO_PARAMDOC option can be abled to get warnings for -# functions that are documented, but have no documentation for their parameters -# or return value. If set to NO (the default) doxygen will only warn about -# wrong or incomplete parameter documentation, but not about the absence of -# documentation. - -WARN_NO_PARAMDOC = NO - -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. Optionally the format may contain -# $version, which will be replaced by the version of the file (if it could -# be obtained via FILE_VERSION_FILTER) - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written -# to stderr. - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. - -INPUT = src - -# This tag can be used to specify the character encoding of the source files that -# doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default -# input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding. -# See http://www.gnu.org/software/libiconv for the list of possible encodings. - -INPUT_ENCODING = UTF-8 - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx -# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py - -FILE_PATTERNS = *.c *.h - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. - -RECURSIVE = YES - -# The EXCLUDE tag can be used to specify files and/or directories that should -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. - -EXCLUDE = - -# The EXCLUDE_SYMLINKS tag can be used select whether or not files or -# directories that are symbolic links (a Unix filesystem feature) are excluded -# from the input. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. Note that the wildcards are matched -# against the file with absolute path, so to exclude all test directories -# for example use the pattern */test/* - -EXCLUDE_PATTERNS = - -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the output. -# The symbol name can be a fully qualified name, a word, or if the wildcard * is used, -# a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test - -EXCLUDE_SYMBOLS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). - -EXAMPLE_PATH = - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. - -EXAMPLE_PATTERNS = - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. -# Possible values are YES and NO. If left blank NO is used. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see -# the \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command , where -# is the value of the INPUT_FILTER tag, and is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. If FILTER_PATTERNS is specified, this tag will be -# ignored. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER -# is applied to all files. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse (i.e. when SOURCE_BROWSER is set to YES). - -FILTER_SOURCE_FILES = NO - -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also -# VERBATIM_HEADERS is set to NO. If you have enabled CALL_GRAPH or CALLER_GRAPH -# then you must also enable this option. If you don't then doxygen will produce -# a warning and turn it on anyway - -SOURCE_BROWSER = YES - -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. - -STRIP_CODE_COMMENTS = YES - -# If the REFERENCED_BY_RELATION tag is set to YES (the default) -# then for each documented function all documented -# functions referencing it will be listed. - -REFERENCED_BY_RELATION = YES - -# If the REFERENCES_RELATION tag is set to YES (the default) -# then for each documented function all documented entities -# called/used by that function will be listed. - -REFERENCES_RELATION = YES - -# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) -# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from -# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will -# link to the source code. Otherwise they will link to the documentstion. - -REFERENCES_LINK_SOURCE = YES - -# If the USE_HTAGS tag is set to YES then the references to source code -# will point to the HTML generated by the htags(1) tool instead of doxygen -# built-in source browser. The htags tool is part of GNU's global source -# tagging system (see http://www.gnu.org/software/global/global.html). You -# will need version 4.8.6 or higher. - -USE_HTAGS = NO - -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. - -VERBATIM_HEADERS = YES - -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. - -ALPHABETICAL_INDEX = NO - -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns -# in which this list will be split (can be a number in the range [1..20]) - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. - -HTML_OUTPUT = html - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own -# stylesheet in the HTML output directory as well, or it will be erased! - -HTML_STYLESHEET = - -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) -# of the generated HTML documentation. - -GENERATE_HTMLHELP = NO - -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. For this to work a browser that supports -# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox -# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). - -HTML_DYNAMIC_SECTIONS = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be -# written to the html output directory. - -CHM_FILE = - -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run -# the HTML help compiler on the generated index.hhp. - -HHC_LOCATION = - -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that -# it should be included in the master .chm file (NO). - -GENERATE_CHI = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a -# normal table of contents (NO) in the .chm file. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the HTML help documentation and to the tree view. - -TOC_EXPAND = NO - -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. - -DISABLE_INDEX = NO - -# This tag can be used to set the number of enum values (range [1..20]) -# that doxygen will group on one line in the generated HTML documentation. - -ENUM_VALUES_PER_LINE = 4 - -# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be -# generated containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, -# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are -# probably better off using the HTML help feature. - -GENERATE_TREEVIEW = NO - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. - -TREEVIEW_WIDTH = 250 - -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will -# generate Latex output. - -GENERATE_LATEX = YES - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `latex' will be used as the default path. - -LATEX_OUTPUT = latex - -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be -# invoked. If left blank `latex' will be used as the default command name. - -LATEX_CMD_NAME = latex - -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the -# default command name. - -MAKEINDEX_CMD_NAME = makeindex - -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_LATEX = NO - -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, a4wide, letter, legal and -# executive. If left blank a4wide will be used. - -PAPER_TYPE = a4wide - -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX -# packages that should be included in the LaTeX output. - -EXTRA_PACKAGES = - -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a -# standard header. Notice: only use this tag if you know what you are doing! - -LATEX_HEADER = - -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references -# This makes the output suitable for online browsing using a pdf viewer. - -PDF_HYPERLINKS = NO - -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a -# higher quality PDF documentation. - -USE_PDFLATEX = NO - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. -# This option is also used when generating formulas in HTML. - -LATEX_BATCHMODE = NO - -# If LATEX_HIDE_INDICES is set to YES then doxygen will not -# include the index chapters (such as File Index, Compound Index, etc.) -# in the output. - -LATEX_HIDE_INDICES = NO - -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- - -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimized for Word 97 and may not look very pretty with -# other RTF readers or editors. - -GENERATE_RTF = NO - -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `rtf' will be used as the default path. - -RTF_OUTPUT = rtf - -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_RTF = NO - -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. -# Note: wordpad (write) and others do not support links. - -RTF_HYPERLINKS = NO - -# Load stylesheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assignments. You only have to provide -# replacements, missing definitions are set to their default value. - -RTF_STYLESHEET_FILE = - -# Set optional variables used in the generation of an rtf document. -# Syntax is similar to doxygen's config file. - -RTF_EXTENSIONS_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will -# generate man pages - -GENERATE_MAN = NO - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `man' will be used as the default path. - -MAN_OUTPUT = man - -# The MAN_EXTENSION tag determines the extension that is added to -# the generated man pages (default is the subroutine's section .3) - -MAN_EXTENSION = .3 - -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command -# would be unable to find the correct page. The default is NO. - -MAN_LINKS = NO - -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of -# the code including all documentation. - -GENERATE_XML = NO - -# The XML_OUTPUT tag is used to specify where the XML pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `xml' will be used as the default path. - -XML_OUTPUT = xml - -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_DTD = - -# If the XML_PROGRAMLISTING tag is set to YES Doxygen will -# dump the program listings (including syntax highlighting -# and cross-referencing information) to the XML output. Note that -# enabling this will significantly increase the size of the XML output. - -XML_PROGRAMLISTING = YES - -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- - -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental -# and incomplete at the moment. - -GENERATE_AUTOGEN_DEF = NO - -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- - -# If the GENERATE_PERLMOD tag is set to YES Doxygen will -# generate a Perl module file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the -# moment. - -GENERATE_PERLMOD = NO - -# If the PERLMOD_LATEX tag is set to YES Doxygen will generate -# the necessary Makefile rules, Perl scripts and LaTeX code to be able -# to generate PDF and DVI output from the Perl module output. - -PERLMOD_LATEX = NO - -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. This is useful -# if you want to understand what is going on. On the other hand, if this -# tag is set to NO the size of the Perl module output will be much smaller -# and Perl will parse it just the same. - -PERLMOD_PRETTY = YES - -# The names of the make variables in the generated doxyrules.make file -# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. -# This is useful so different doxyrules.make files included by the same -# Makefile don't overwrite each other's variables. - -PERLMOD_MAKEVAR_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include -# files. - -ENABLE_PREPROCESSING = YES - -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled -# way by setting EXPAND_ONLY_PREDEF to YES. - -MACRO_EXPANSION = NO - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the -# PREDEFINED and EXPAND_AS_DEFINED tags. - -EXPAND_ONLY_PREDEF = NO - -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# in the INCLUDE_PATH (see below) will be search if a #include is found. - -SEARCH_INCLUDES = YES - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by -# the preprocessor. - -INCLUDE_PATH = - -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will -# be used. - -INCLUDE_FILE_PATTERNS = - -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. To prevent a macro definition from being -# undefined via #undef or recursively expanded use the := operator -# instead of the = operator. - -PREDEFINED = - -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition. - -EXPAND_AS_DEFINED = - -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all function-like macros that are alone -# on a line, have an all uppercase name, and do not end with a semicolon. Such -# function macros are typically used for boiler-plate code, and will confuse -# the parser if not removed. - -SKIP_FUNCTION_MACROS = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES option can be used to specify one or more tagfiles. -# Optionally an initial location of the external documentation -# can be added for each tagfile. The format of a tag file without -# this location is as follows: -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths or -# URLs. If a location is present for each tag, the installdox tool -# does not have to be run to correct the links. -# Note that each tag file must have a unique name -# (where the name does NOT include the path) -# If a tag file is not located in the directory in which doxygen -# is run, you must also specify the path to the tagfile here. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create -# a tag file that is based on the input files it reads. - -GENERATE_TAGFILE = - -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes -# will be listed. - -ALLEXTERNALS = NO - -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will -# be listed. - -EXTERNAL_GROUPS = YES - -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of `which perl'). - -PERL_PATH = /usr/bin/perl - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- - -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base -# or super classes. Setting the tag to NO turns the diagrams off. Note that -# this option is superseded by the HAVE_DOT option below. This is only a -# fallback. It is recommended to install and use dot, since it yields more -# powerful graphs. - -CLASS_DIAGRAMS = YES - -# You can define message sequence charts within doxygen comments using the \msc -# command. Doxygen will then run the mscgen tool (see http://www.mcternan.me.uk/mscgen/) to -# produce the chart and insert it in the documentation. The MSCGEN_PATH tag allows you to -# specify the directory where the mscgen tool resides. If left empty the tool is assumed to -# be found in the default search path. - -MSCGEN_PATH = - -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented -# or is not a class. - -HIDE_UNDOC_RELATIONS = YES - -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section -# have no effect if this option is set to NO (the default) - -HAVE_DOT = NO - -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the -# the CLASS_DIAGRAMS tag to NO. - -CLASS_GRAPH = YES - -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and -# class references variables) of the class with other documented classes. - -COLLABORATION_GRAPH = YES - -# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for groups, showing the direct groups dependencies - -GROUP_GRAPHS = YES - -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling -# Language. - -UML_LOOK = NO - -# If set to YES, the inheritance and collaboration graphs will show the -# relations between templates and their instances. - -TEMPLATE_RELATIONS = NO - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with -# other documented files. - -INCLUDE_GRAPH = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or -# indirectly include this file. - -INCLUDED_BY_GRAPH = YES - -# If the CALL_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will -# generate a call dependency graph for every global function or class method. -# Note that enabling this option will significantly increase the time of a run. -# So in most cases it will be better to enable call graphs for selected -# functions only using the \callgraph command. - -CALL_GRAPH = NO - -# If the CALLER_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will -# generate a caller dependency graph for every global function or class method. -# Note that enabling this option will significantly increase the time of a run. -# So in most cases it will be better to enable caller graphs for selected -# functions only using the \callergraph command. - -CALLER_GRAPH = NO - -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will graphical hierarchy of all classes instead of a textual one. - -GRAPHICAL_HIERARCHY = YES - -# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES -# then doxygen will show the dependencies a directory has on other directories -# in a graphical way. The dependency relations are determined by the #include -# relations between the files in the directories. - -DIRECTORY_GRAPH = YES - -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are png, jpg, or gif -# If left blank png will be used. - -DOT_IMAGE_FORMAT = png - -# The tag DOT_PATH can be used to specify the path where the dot tool can be -# found. If left blank, it is assumed the dot tool can be found in the path. - -DOT_PATH = - -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the -# \dotfile command). - -DOTFILE_DIRS = - -# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of -# nodes that will be shown in the graph. If the number of nodes in a graph -# becomes larger than this value, doxygen will truncate the graph, which is -# visualized by representing a node as a red box. Note that doxygen if the number -# of direct children of the root node in a graph is already larger than -# MAX_DOT_GRAPH_NOTES then the graph will not be shown at all. Also note -# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. - -DOT_GRAPH_MAX_NODES = 50 - -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the -# graphs generated by dot. A depth value of 3 means that only nodes reachable -# from the root by following a path via at most 3 edges will be shown. Nodes -# that lay further from the root node will be omitted. Note that setting this -# option to 1 or 2 may greatly reduce the computation time needed for large -# code bases. Also note that the size of a graph can be further restricted by -# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. - -MAX_DOT_GRAPH_DEPTH = 0 - -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, which results in a white background. -# Warning: Depending on the platform used, enabling this option may lead to -# badly anti-aliased labels on the edges of a graph (i.e. they become hard to -# read). - -DOT_TRANSPARENT = NO - -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) -# support this, this feature is disabled by default. - -DOT_MULTI_TARGETS = NO - -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and -# arrows in the dot generated graphs. - -GENERATE_LEGEND = YES - -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermediate dot files that are used to generate -# the various graphs. - -DOT_CLEANUP = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to the search engine -#--------------------------------------------------------------------------- - -# The SEARCHENGINE tag specifies whether or not a search engine should be -# used. If set to NO the values of all tags below this one will be ignored. - -SEARCHENGINE = NO diff --git a/HACKING b/HACKING deleted file mode 100644 index 763bc8830..000000000 --- a/HACKING +++ /dev/null @@ -1,298 +0,0 @@ -Intro... - -Window managers have a few ways in which they are significantly different -from other applications. This file, combined with the code overview in -doc/code-overview.txt, should hopefully provide a series of relatively -quick pointers (hopefully only a few minutes each) to some of the places -one can look to orient themselves and get started. Some of this will be -general to window managers on X, much will be specific to Metacity, and -there's probably some information that's common to programs in general but -is nonetheless useful. - -Overview - Administrative issues - Minimal Building/Testing Environment - Relevant standards and X properties - Debugging and testing - Debugging logs - Adding information to the log - Valgrind - Testing Utilities - Technical gotchas to keep in mind - Other important reading - Extra reading - Ideas for tasks to work on - - -Administrative issues - Don't commit substantive code in here without asking hp@redhat.com. - Adding translations, no-brainer typo fixes, etc. is fine. - - The code could use cleanup in a lot of places, feel free to do so. - - See http://developer.gnome.org/dotplan/for_maintainers.html for - information on how to make a release. The only difference from those - instructions is that the minor version number of a Metacity release - should always be a number from the Fibonacci sequence. - -Minimal Building/Testing Environment - You do not need to _install_ a development version of Metacity to - build, run and test it; you can run it from some temporary - directory. Also, you do not need to build all of Gnome in order to - build a development version of Metacity -- odds are, you may be able - to build metacity from CVS without building any other modules. - - As long as you have gtk+ >= 3.0 and GIO >= 2.25.10 with your distro - (gtk+ >= 2.6 if you manually revert the change from bug 348633), you - should be able to install your distro's development packages - (e.g. gtk2-devel, glib-devel, startup-notification-devel on - Fedora; also, remember to install the gnome-common package which is - needed for building cvs versions of Gnome modules like Metacity) as - well as the standard development tools (gcc, autoconf, automake, - pkg-config, intltool, and libtool) and be ready to build and test - Metacity. Steps to do so: - - $ svn checkout http://svn.gnome.org/svn/metacity/trunk metacity - $ cd metacity - $ ./autogen.sh --prefix /usr - $ make - $ ./src/metacity --replace - - Again, note that you do not need to run 'make install'. - -Relevant standards and X properties - There are two documents that describe some basics about how window - managers should behave: the ICCCM (Inter-Client Communication Conventions - Manual) and EWMH (Extended Window Manager Hints). You can find these at - the following locations: - ICCCM - http://tronche.com/gui/x/icccm/ - EWMH - :pserver:anoncvs@pdx.freedesktop.org:/cvs - The ICCCM is usually available in RPM or DEB format as well. There is - actually an online version of the EWMH, but it is almost always woefully - out of date. Just get it from cvs with these commands (the backslash - means include the stuff from the next line): - cvs -d :pserver:anoncvs@cvs.freedesktop.org:/cvs/icccm-extensions login - cvs -d :pserver:anoncvs@cvs.freedesktop.org:/cvs/icccm-extensions \ - checkout wm-spec - - DO NOT GO AND READ THOSE THINGS. THEY ARE REALLY, REALLY BORING. - - If you do, you'll probably end up catching up on your sleep instead of - hacking on Metacity. ;-) Instead, just look at the table of contents and - glance at a page or two to get an idea of what's in there. Then only - refer to it if you see something weird in the code and you don't know - what it is but has some funny looking name like you see in one of those - two documents. - - You can refer to the COMPLIANCE file for additional information on these - specifications and Metacity's compliance therewith. - - One of the major things those documents cover that are useful to learn - about immediately are X properties. The right way to learn about those, - though, is through hand on experimentation with the xprop command (and - then look up things you find from xprop in those two manuals if you're - curious enough). First, try running - xprop - in a terminal and click on one of the windows on your screen. That gives - you the x properties for that window. Look through them and get a basic - idea of what's there for kicks. Note that you can get rid of some of the - verboseness by grepping out the _NET_WM_ICON stuff, i.e. - xprop | grep -v _NET_WM_ICON - Next, try running - xprop -root - in a terminal. There's all the properties of the root window (which you - can think of as the "main" Xserver window). You can also manually - specify individual windows that you want the properties of with - xprop -id - if you know the id of the window in question. You can get the id of a - given window by either running xwininfo, e.g. - xwininfo | grep "Window id" | cut -f 4 -d ' ' - or by looking at the _NET_CLIENT_STACKING property of the root - window. Finally, it can also be useful to add "-spy" (without the - quotes) to the xprop command to get it to continually monitor that - window and report any changes to you. - -Debugging information - Trying to run a window manager under a typical debugger, such as gdb, - unfortunately just doesn't work very well. So, we have to resort to - other methods. - - Debugging logs - - First, note that you can start a new version of metacity to replace the - existing one by running - metacity --replace - (which also comes in handy in the form "./src/metacity --replace" when - trying to quickly test a small change while hacking on metacity without - doing a full "make install", though I'm going off topic...) This will - allow you to see any warnings printed at the terminal. Sometimes it's - useful to have these directed to a logfile instead, which you can do by - running - METACITY_USE_LOGFILE=1 metacity --replace - The logfile it uses will be printed in the terminal. Sometimes, it's - useful to get more information than just warnings. You can set - METACITY_VERBOSE to do that, like so: - METACITY_VERBOSE=1 METACITY_USE_LOGFILE=1 metacity --replace - (note that METACITY_VERBOSE=1 can be problematic without - METACITY_USE_LOGFILE=1; avoid it unless running in from something that - won't be managed by the new Metacity--see bug 305091 for more details). - There are also other flags, such as METACITY_DEBUG, most of which I - haven't tried and don't know what they do. Go to the source code - directory and run - grep "METACITY_" * | grep getenv - to find out what the other ones are. - - Adding information to the log - - Since we can't single step with a debugger, we often have to fall back to - the primitive method of getting information we want to know: adding - "print" statements. Metacity has a fairly structured way to do this, - using the functions meta_warning, meta_topic, and meta_verbose. All - three have the same basic format as printf, except that meta_topic also - takes a leading enumeration parameter to specify the type of message - being shown (makes it easier for grepping in a verbose log). You'll find - tons of examples in the source code if you need them; just do a quick - grep or look in most any file. Note that meta_topic and meta_verbose - messages only appear if verbosity is turned on. I tend to frequently add - temporary meta_warning statements (or switch meta_topic or meta_verbose - ones to meta_warning ones) and then undo the changes once I've learned - the info that I needed. - - There is also a meta_print_backtrace (which again is only active if - verbosity is turned on) that can also be useful if you want to learn how - a particular line of code gets called. And, of course, there's always - g_assert if you want to make sure some section isn't executed (or isn't - executed under certain conditions). - - Valgrind - - Valgrind is awesome for finding memory leaks or corruption and - uninitialized variables. But I also tend to use it in a non-traditional - way as a partial substitute for a normal debugger: it can provide me with - a stack trace of where metacity is crashing if I made a change that - caused it to do so, which is one of the major uses of debuggers. (And, - what makes it cooler than a debugger is that there will also often be - warnings pinpointing the cause of the crash from either some kind of - simple memory corruption or an uninitialized variable). Sometimes, when - I merely want to know what is calling a particular function I'll just - throw in an "int i; printf("%d\n", i);" just because valgrind will give - me a full stacktrace whenever it sees that uninitialized variable being - used (yes, I could use meta_print_backtrace, but that means I have to - turn verbosity on). - - To run metacity under valgrind, use options typical for any Gnome - program, such as - valgrind --log-file=metacity.log --tool=memcheck --num-callers=48 \ - --leak-check=yes --leak-resolution=high --show-reachable=yes \ - ./src/metacity --replace - where, again, the backslashes mean to join all the stuff on the following - line with the previous one. - - However, there is a downside. Things run a little bit slowly, and it - appears that you'll need about 1.5GB of ram, which unfortunately prevents - most people from trying this. - - Testing Utilities - - src/run-metacity.sh - The script src/run-metacity.sh is useful to hack on the window manager. - It runs metacity in an Xnest. e.g.: - CLIENTS=3 ./run-metacity.sh - or - DEBUG=memprof ./run-metacity.sh - or - DEBUG_TEST=1 ./run-metacity-sh - or whatever. - - metacity-message - The tool metacity-message can be used as follows: - metacity-message reload-theme - metacity-message restart - metacity-message enable-keybindings - metacity-message disable-keybindings - The first of these is useful for testing themes, the second is just - another way (besides the --restart flag to metacity itself) of - restarting metacity, and the third is useful for testing Metacity when - running it under an Xnest (typically, the Metacity under the Xnest - wouldn't get keybinding notifications--making keyboard navigation not - work--but if you disable the keybindings for the global Metacity then - the Metacity under the Xnest can then get those keybinding notifications). - - metacity-window-demo - metacity-window-demo is good for trying behavior of various kinds - of window without launching a full desktop. - -Technical gotchas to keep in mind - Files that include gdk.h or gtk.h are not supposed to include - display.h or window.h or other core files. Files in the core - (display.[hc], window.[hc]) are not supposed to include gdk.h or - gtk.h. Reasons: - - "Basically you don't want GDK most of the time. It adds - abstractions that cause problems, because they aren't designed to - be used in a WM where we do weird stuff (display grabs, and just - being the WM). At best GDK adds inefficiency, at worst it breaks - things in weird ways where you have to be a GDK guru to figure - them out. Owen also told me that they didn't want to start adding - a lot of hacks to GDK to let a WM use it; we both agreed back in - the mists of time that metacity would only use it for the "UI" - bits as it does. - - Having the split in the source code contains and makes very clear - the interface between the WM and GDK/GTK. This keeps people from - introducing extra GDK/GTK usage when it isn't needed or - appropriate. Also, it speeds up the compilation a bit, though this - was perhaps more relevant 5 years ago than it is now. - - There was also a very old worry that the GDK stuff might have to - be in a separate process to work right; that turned out to be - untrue. Though who knows what issues the CM will introduce." - - Remember that strings stored in X properties are not in UTF-8, and they - have to end up in UTF-8 before we try putting them through Pango. - - If you make any X request involving a client window, you have to - meta_error_trap_push() around the call; this is not necessary for X - requests on the frame windows. - - Remember that not all windows have frames, and window->frame can be NULL. - -Other important reading & where to get started - Extra reading - - There are some other important things to read to get oriented as well. - These are: - http://pobox.com/~hp/features.html - rationales.txt - doc/code-overview.txt - - It pays to read http://pobox.com/~hp/features.html in order - to understand the philosophy of Metacity. - - The rationales.txt file has two things: (1) a list of design choices with - links in the form of bugzilla bugs that discuss the issue, and (2) a list - outstanding bug categories, each of which is tracked by a particular - tracker bug in bugzilla from which you can find several closely related - bug reports. - - doc/code-overview.txt provides a fairly good overview of the code, - including coverage of the function of the various files, the main - structures and their relationships, and places to start looking in the - code tailored to general categories of tasks. - - Ideas for tasks to work on - - There are a variety of things you could work on in the code. You may - have ideas of your own, but in case you don't, let me provide a list of - ideas you could choose from: - - If you're ambitious, there's a list of things Havoc made that he'd really - like to see tackled, which you can find at - http://log.ometer.com/2004-05.html. Be sure to double check with someone - to make sure the item is still relevant if you're interested in one of - these. Another place to look for ideas, of course, is bugzilla. One can - just do queries and look for things that look fixable. - - However, perhaps the best way of getting ideas of related tasks to work - on, is to look at the second half of the rationales.txt file, which tries - to group bugs by type. diff --git a/MAINTAINERS b/MAINTAINERS deleted file mode 100644 index 0031c7f9c..000000000 --- a/MAINTAINERS +++ /dev/null @@ -1,8 +0,0 @@ -Tomas Frydrych -Email: tf linux intel com -Userid: tomasf - -Owen Taylor -Email: otaylor redhat com -Userid: otaylor - diff --git a/METACITY_MAINTAINERS b/METACITY_MAINTAINERS deleted file mode 100644 index 205dbf224..000000000 --- a/METACITY_MAINTAINERS +++ /dev/null @@ -1,43 +0,0 @@ -Currently active maintainers --------------------------------- - -Elijah Newren -Email: newren gmail com -Userid: newren - - - Usually won't touch the theme bugs (isn't interested) or the - compositor (until open source nvidia drivers are up to snuff). - Tends to be most interested in libwnck/gtk interactions, focus - issues, constraints problems, and raising/stacking, but works on - just about anything other than themes and the compositor. - -Thomas Thurman -Email: thomas thurman org uk -Userid: tthurman - - - Responsible for all theme bugs and the compositor (thank goodness - Thomas got involved, eh?). I'm sure he'll replace this sentence - with his interests when he reads it. ;-) - - -Semi-active maintainers --------------------------------- - -Havoc Pennington -Email: hp redhat com -Userid: hp - - Original author. Doesn't patch metacity anymore, but is active in - answering questions, responding to bugs, providing very helpful - suggestions and insight, and even assisting with debugging. - - -Important historical figureheads --------------------------------- - -Rob Adams (readams readams net) - - Was the main maintainer of metacity for a while; particular areas - of focus included xinerama, placement, and an older version of the - constraints code. Still responds to bugs every once in a while. - -Søren Sandmann (sandmann redhat com) - - Wrote most of the current compositing manager code + libcm diff --git a/README b/README deleted file mode 100644 index aa45a7616..000000000 --- a/README +++ /dev/null @@ -1,416 +0,0 @@ -The original codebase named "Metacity" is not a meta-City as in an -urban center, but rather Meta-ness as in the state of being -meta. i.e. metacity : meta as opacity : opaque. Also it may have -something to do with the Meta key on UNIX keyboards. - -Since then, it has been renamed mutter after a rebase on top of -clutter as a compositing manager. - -COMPILING MUTTER -=== - -You need GTK+ 2.2. For startup notification to work you need -libstartup-notification at -http://www.freedesktop.org/software/startup-notification/ or on the -GNOME ftp site. -You need Clutter 1.0. You need gobject-introspection 0.6.3. - -REPORTING BUGS AND SUBMITTING PATCHES -=== - -Report new bugs on http://bugzilla.gnome.org. Please check for -duplicates, *especially* if you are reporting a feature request. - -Please do *not* add "me too!" or "yes I really want this!" comments to -feature requests in bugzilla. Please read -http://pobox.com/~hp/features.html prior to adding any kind of flame -about missing features or misfeatures. - -Feel free to send patches too; Metacity is relatively small and -simple, so if you find a bug or want to add a feature it should be -pretty easy. Send me mail, or put the patch in bugzilla. - -See the HACKING file for some notes on hacking Mutter. - -MUTTER FEATURES -=== - - - Uses GTK+ 2.0 for drawing window frames. This means colors, fonts, - etc. come from GTK+ theme. - - - Does not expose the concept of "window manager" to the user. Some - of the features in the GNOME control panel and other parts of the - desktop happen to be implemented in metacity, such as changing your - window border theme, or changing your window navigation shortcuts, - but the user doesn't need to know this. - - - Includes only the window manager; does not try to be a desktop - environment. The pager, configuration, etc. are all separate and - modular. The "libwnck" library (which I also wrote) is available - for writing metacity extensions, pagers, and so on. (But libwnck - isn't metacity specific, or GNOME-dependent; it requires only GTK, - and should work with KWin, fvwm2, and other EWMH-compliant WMs.) - - - Has a simple theme system and a couple of extra themes come with it. - Change themes via gsettings: - gsettings set org.gnome.desktop.wm.preferences theme Crux - gsettings set org.gnome.desktop.wm.preferences theme Gorilla - gsettings set org.gnome.desktop.wm.preferences theme Atlanta - gsettings set org.gnome.desktop.wm.preferences theme Bright - - See theme-format.txt for docs on the theme format. Use - metacity-theme-viewer to preview themes. - - - Change number of workspaces via gsettings: - gsettings set org.gnome.desktop.wm.preferences num-workspaces 5 - - Can also change workspaces from GNOME 2 pager. - - - Change focus mode: - gsettings set org.gnome.desktop.wm.preferences focus-mode mouse - gsettings set org.gnome.desktop.wm.preferences focus-mode sloppy - gsettings set org.gnome.desktop.wm.preferences focus-mode click - - - Global keybinding defaults include: - - Alt-Tab forward cycle window focus - Alt-Shift-Tab backward cycle focus - Alt-Ctrl-Tab forward cycle focus among panels - Alt-Ctrl-Shift-Tab backward cycle focus among panels - Alt-Escape cycle window focus without a popup thingy - Ctrl-Alt-Left Arrow previous workspace - Ctrl-Alt-Right Arrow next workspace - Ctrl-Alt-D minimize/unminimize all, to show desktop - - Change keybindings for example: - - gsettings set org.gnome.desktop.wm.keybindings switch-to-workspace-1 '[F1]' - - Also try the GNOME keyboard shortcuts control panel. - - - Window keybindings: - - Alt-space window menu - - Mnemonics work in the menu. That is, Alt-space then underlined - letter in the menu item works. - - Choose Move from menu, and arrow keys to move the window. - - While moving, hold down Control to move slower, and - Shift to snap to edges. - - Choose Resize from menu, and nothing happens yet, but - eventually I might implement something. - - Keybindings for things like maximize window, vertical maximize, - etc. can be bound, but may not all exist by default. See - metacity.schemas. - - - Window mouse bindings: - - Clicking anywhere on frame with button 1 will raise/focus window - - If you click a window control, such as the close button, then the - control will activate on button release if you are still over it - on release (as with most GUI toolkits) - - If you click and drag borders with button 1 it resizes the window - - If you click and drag the titlebar with button 1 it moves the - window. - - If you click anywhere on the frame with button 2 it lowers the - window. - - If you click anywhere on the frame with button 3 it shows the - window menu. - - If you hold down Super (windows key) and click inside a window, it - will move the window (buttons 1 and 2) or show menu (button 3). - Or you can configure a different modifier for this. - - If you pick up a window with button 1 and then switch workspaces - the window will come with you to the new workspace, this is - a feature copied from Enlightenment. - - If you hold down Shift while moving a window, the window snaps - to edges of other windows and the screen. - - - Session management: - - Mutter connects to the session manager and will set itself up to - be respawned. It theoretically restores sizes/positions/workspace - for session-aware applications. - - - Mutter implements much of the EWMH window manager specification - from freedesktop.org, as well as the older ICCCM. Please refer to - the COMPLIANCE file for information on mutter compliance with - these standards. - - - Uses Pango to render text, so has cool i18n capabilities. - Supports UTF-8 window titles and such. - - - There are simple animations for actions such as minimization, - to help users see what is happening. Should probably - have a few more of these and make them nicer. - - - if you have the proper X setup, set the GDK_USE_XFT=1 - environment variable to get antialiased window titles. - - - considers the panel when placing windows and maximizing - them. - - - handles the window manager selection from the ICCCM. Will exit if - another WM claims it, and can claim it from another WM if you pass - the --replace argument. So if you're running another - ICCCM-compliant WM, you can run "mutter --replace" to replace it - with Metacity. - - - does basic colormap handling - - - and much more! well, maybe not a lot more. - -HOW TO ADD EXTERNAL FEATURES -=== - -You can write a mutter "plugin" such as a pager, window list, icon -box, task menu, or even things like "window matching" using the -Extended Window Manager Hints. See http://www.freedesktop.org for the -EWMH specification. An easy-to-use library called "libwnck" is -available that uses the EWMH and is specifically designed for writing -WM accessories. - -You might be interested in existing accessories such as "Devil's Pie" -by Ross Burton, which add features to Mutter (or other -EWMH-compliant WMs). - -MUTTER BUGS, NON-FEATURES, AND CAVEATS -=== - -See bugzilla: http://bugzilla.gnome.org/query.cgi - -FAQ -=== - -Q: Will you add my feature? - -A: If it makes sense to turn on unconditionally, or is genuinely a - harmless preference that I would not be embarrassed to put in a - simple, uncluttered, user-friendly configuration dialog. - - If the only rationale for your feature is that other window - managers have it, or that you are personally used to it, or - something like that, then I will not be impressed. Metacity is - firmly in the "choose good defaults" camp rather than the "offer 6 - equally broken ways to do it, and let the user pick one" camp. - - This is part of a "no crackrock" policy, despite some exceptions - I'm mildly embarrassed about. For example, multiple workspaces - probably constitute crackrock, they confuse most users and really - are not that useful if you have a decent tasklist and so on. But I - am too used to them to turn them off. Or alternatively - iconification/tasklist is crack, and workspaces/pager are good. But - having both is certainly a bit wrong. Sloppy focus is probably - crackrock too. - - But don't think unlimited crack is OK just because I slipped up a - little. No slippery slope here. - - Don't let this discourage patches and fixes - I love those. ;-) - Just be prepared to hear the above objections if your patch adds - some crack-ridden configuration option. - - http://pobox.com/~hp/free-software-ui.html - http://pobox.com/~hp/features.html - -Q: Will Mutter be part of GNOME? - -A: It is not officially part of GNOME as of GNOME 2.27. We are - hoping to have mutter officially included as of GNOME 2.28. - -Q: Why does Mutter remember the workspace/position of some apps - but not others across logout/login? - -A: Mutter only stores sizes/positions for apps that are session - managed. As far as I can determine, there is no way to attempt to - remember workspace/position for non-session-aware apps without - causing a lot of weird effects. - - The reason is that you don't know which non-SM-aware apps were - launched by the session. When you initially log in, Metacity sees a - bunch of new windows appear. But it can't distinguish between - windows that were stored in your session, or windows you just - launched after logging in. If Metacity tried to guess that a window - was from the session, it could e.g. end up maximizing a dialog, or - put a window you just launched on another desktop or in a weird - place. And in fact I see a lot of bugs like this in window managers - that try to handle non-session-aware apps. - - However, for session-aware apps, Mutter can tell that the - application instance is from the session and thus restore it - reliably, assuming the app properly restores the windows it had - open on session save. - - So the correct way to fix the situation is to make apps - session-aware. libSM has come with X for years, it's very - standardized, it's shared by GNOME and KDE - even twm is - session-aware. So anyone who won't take a patch to add SM is more - archaic than twm - and you should flame them. ;-) - - Docs on session management: - http://www.fifi.org/doc/xspecs/xsmp.txt.gz - http://www.fifi.org/doc/xspecs/SMlib.txt.gz - - See also the ICCCM section on SM. For GNOME apps, use the - GnomeClient object. For a simple example of using libSM directly, - twm/session.c in the twm source code is pretty easy to understand. - -Q: How about adding viewports in addition to workspaces? - -A: I could conceivably be convinced to use viewports _instead_ of - workspaces, though currently I'm not thinking that. But I don't - think it makes any sense to have both; it's just confusing. They - are functionally equivalent. - - You may think this means that you won't have certain keybindings, - or something like that. This is a misconception. The only - _fundamental_ difference between viewports and workspaces is that - with viewports, windows can "overlap" and appear partially on - one and partially on another. All other differences that - traditionally exist in other window managers are accidental - - the features commonly associated with viewports can be implemented - for workspaces, and vice versa. - - So I don't want to have two kinds of - workspace/desktop/viewport/whatever, but I'm willing to add - features traditionally associated with either kind if those - features make sense. - -Q: Why is the panel always on top? - -A: Because it's a better user interface, and until we made this not - configurable a bunch of apps were not getting fixed (the app - authors were just saying "put your panel on the bottom" instead of - properly supporting fullscreen mode, and such). - - rationales.txt has the bugzilla URL for some flamefesting on this, - if you want to go back and relive the glory. - Read these and the bugzilla stuff before asking/commenting: - http://pobox.com/~hp/free-software-ui.html - http://pobox.com/~hp/features.html - -Q: Why is there no edge flipping? - -A: This one is also in rationales.txt. Because "ouija board" UI, where - you just move the mouse around and the computer guesses what you - mean, has a lot of issues. This includes mouse focus, shade-hover - mode, edge flipping, autoraise, etc. Metacity has mouse focus and - autoraise as a compromise, but these features are all confusing for - many users, and cause problems with accessibility, fitt's law, and - so on. - - Read these and the bugzilla stuff before asking/commenting: - http://pobox.com/~hp/free-software-ui.html - http://pobox.com/~hp/features.html - -Q: Why does wireframe move/resize suck? - -A: You can turn it on with the reduced_resources setting. - - But: it has low usability, and is a pain - to implement, and there's no reason opaque move/resize should be a - problem on any setup that can run a modern desktop worth a darn to - begin with. - - Read these and the bugzilla stuff before asking/commenting: - http://pobox.com/~hp/free-software-ui.html - http://pobox.com/~hp/features.html - - The reason we had to add wireframe anyway was broken - proprietary apps that can't handle lots of resize events. - -Q: Why no XYZ? - -A: You are probably getting the idea by now - check rationales.txt, - query/search bugzilla, and read http://pobox.com/~hp/features.html - and http://pobox.com/~hp/free-software-ui.html - - Then sit down and answer the question for yourself. Is the feature - good? What's the rationale for it? Answer "why" not just "why not." - Justify in terms of users as a whole, not just users like - yourself. How else can you solve the same problem? etc. If that - leads you to a strong opinion, then please, post the rationale for - discussion to an appropriate bugzilla bug, or to - usability@gnome.org. - - Please don't just "me too!" on bugzilla bugs, please don't think - flames will get you anywhere, and please don't repeat rationale - that's already been offered. - -Q: Your dumb web pages you made me read talk about solving problems in - fundamental ways instead of adding preferences or workarounds. - What are some examples where metacity has done this? - -A: There are quite a few, though many opportunities remain. Sometimes - the real fix involves application changes. The metacity approach is - that it's OK to require apps to change, though there are also - plenty of workarounds in metacity for battles considered too hard - to fight. - - Here are some examples: - - - fullscreen mode was introduced to allow position constraints, - panel-on-top, and other such things to apply to normal windows - while still allowing video players etc. to "just work" - - - "whether to include minimized windows in Alt+Tab" was solved - by putting minimized windows at the *end* of the tab order. - - - Whether to pop up a feedback display during Alt+Tab was solved by - having both Alt+Tab and Alt+Esc - - - Whether to have a "kill" feature was solved by automatically - detecting and offering to kill stuck apps. Better, metacity - actually does "kill -9" on the process, it doesn't just - disconnect the process from the X server. You'll appreciate this - if you ever did a "kill" on Netscape 4, and watched it keep - eating 100% CPU even though the X server had booted it. - - - The workspaces vs. viewports mess was avoided by adding - directional navigation and such to workspaces, see discussion - earlier in this file. - - - Instead of configurable placement algorithms, there's just one - that works fairly well most of the time. - - - To avoid excess CPU use during opaque move/resize, we rate limit - the updates to the application window's size. - - - Instead of configurable "show size of window while resizing," - it's only shown for windows where it matters, such as terminals. - (Only use-case given for all windows is for web designers - choosing their web browser size, but there are web sites and - desktop backgrounds that do this for you.) - - - Using startup notification, applications open on the workspace - where you launched them, not the active workspace when their - window is opened. - - - and much more. - -Q: I think mutter sucks. - -A: Feel free to use any WM you like. The reason metacity follows the - ICCCM and EWMH specifications is that it makes metacity a modular, - interchangeable part in the desktop. libwnck-based apps such as the - GNOME window list will work just fine with any EWMH-compliant WM. - -Q: Did you spend a lot of time on this? - -A: Originally the answer was no. Sadly the answer is now yes. - -Q: How can you claim that you are anti-crack, while still - writing a window manager? - -A: I have no comment on that. diff --git a/rationales.txt b/doc/rationales.txt similarity index 100% rename from rationales.txt rename to doc/rationales.txt diff --git a/src/run-mutter.sh b/src/run-mutter.sh deleted file mode 100755 index b64834f7a..000000000 --- a/src/run-mutter.sh +++ /dev/null @@ -1,109 +0,0 @@ -#! /bin/bash - -if test -z "$XNEST_DISPLAY"; then - XNEST_DISPLAY=:8 -fi - -if test -z "$CLIENT_DISPLAY"; then - CLIENT_DISPLAY=:8 -fi - -if test -z "$MUTTER_DISPLAY"; then - export MUTTER_DISPLAY=$CLIENT_DISPLAY -fi - -if test -z "$SCREENS"; then - SCREENS=1 -fi - -MAX_SCREEN=`echo $SCREENS-1 | bc` - -if test "$DEBUG" = none; then - DEBUG= -elif test -z "$DEBUG"; then - DEBUG= -fi - -if test -z "$CLIENTS"; then - CLIENTS=0 -fi - -if test -z "$SM_CLIENTS"; then - SM_CLIENTS=0 -fi - -if test -n "$EVIL_TEST"; then - TEST_CLIENT='./wm-tester/wm-tester --evil' -fi - -if test -n "$ICON_TEST"; then - TEST_CLIENT='./wm-tester/wm-tester --icon-windows' -fi - -if test -n "$DEMO_TEST"; then - TEST_CLIENT='./tools/mutter-window-demo' -fi - -if test -n "$XINERAMA"; then - XINERAMA_FLAGS='+xinerama' -fi - -export EF_ALLOW_MALLOC_0=1 - -if test -z "$ONLY_WM"; then - echo "Launching Xnest" - Xnest -ac $XNEST_DISPLAY -scrns $SCREENS -geometry 640x480 -bw 15 $XINERAMA_FLAGS & - ## usleep 800000 - sleep 1 - - if test -n "$XMON_DIR"; then - echo "Launching xmond" - $XMON_DIR/xmonui | $XMON_DIR/xmond -server localhost:$XNEST_DISPLAY & - sleep 1 - fi - - if test -n "$XSCOPE_DIR"; then - ## xscope doesn't like to die when it should, it backgrounds itself - killall -9 xscope - killall -9 xscope - echo "Launching xscope" - DISPLAY= $XSCOPE_DIR/xscope -o1 -i28 > xscoped-replies.txt & - export MUTTER_DISPLAY=localhost:28 - sleep 1 - fi - - echo "Launching clients" - if test -n "$TEST_CLIENT"; then - for I in `seq 0 $MAX_SCREEN`; do - DISPLAY=$CLIENT_DISPLAY.$I $TEST_CLIENT & - done - fi - - if test $CLIENTS != 0; then - for I in `seq 1 $CLIENTS`; do - echo "Launching xterm $I" - DISPLAY=$CLIENT_DISPLAY xterm -geometry 25x15 & - done - fi - - if test $SM_CLIENTS != 0; then - for I in `seq 1 $SM_CLIENTS`; do - echo "Launching gnome-terminal $I" - DISPLAY=$CLIENT_DISPLAY gnome-terminal --geometry 25x15 & - done - fi - - if test -e ~/.Xmodmap; then - DISPLAY=$CLIENT_DISPLAY xmodmap ~/.Xmodmap - fi - - usleep 50000 - - for I in `seq 0 $MAX_SCREEN`; do - DISPLAY=$CLIENT_DISPLAY.$I xsetroot -solid royalblue3 - done -fi - -if test -z "$ONLY_SETUP"; then - MUTTER_VERBOSE=1 MUTTER_USE_LOGFILE=1 MUTTER_DEBUG_BUTTON_GRABS=1 exec $DEBUG ./mutter $OPTIONS -fi diff --git a/stamp.h.in b/stamp.h.in deleted file mode 100644 index e69de29bb..000000000 diff --git a/test/tokentest/Makefile b/test/tokentest/Makefile deleted file mode 100644 index 010fd604d..000000000 --- a/test/tokentest/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# completely hacked-up makefile, proceed at your own risk, etc - -default: - @echo "Try 'make tp' or 'make glib'" - -tp: tokentest.c - gcc `pkg-config --cflags --libs glib-2.0 gdk-2.0 atk` -DMUTTER_DATADIR=\"/usr/share/mutter\" -I../.. -I../../src -I../../src/include tokentest.c ../../src/ui/theme.c ../../src/ui/gradient.c -o tp diff --git a/test/tokentest/README b/test/tokentest/README deleted file mode 100644 index c98dbe4ad..000000000 --- a/test/tokentest/README +++ /dev/null @@ -1,19 +0,0 @@ -Tokeniser test -============== -This directory contains a set of tools for checking the behaviour -of the tokeniser for Metacity theme files. - -tokentest.ini contains a list of all expressions retrieved from -all theme files on art.gnome.org, and mappings to what the tokenising -should be, in a separate representation. get-tokens.py produces the -template version of this; it will produce a file with no expected -values. - -tokentest.c will either check that a tokeniser behaves according to -tokentest.ini, or, if it finds a file, is empty it will print the -values that the tokeniser it's using is producing. - -The makefile is a hacky attempt at letting you compile either against -Metacity's existing tokeniser or one which uses GLib's "scanner". - -This code may or may not eventually end up in the automated test suite. \ No newline at end of file diff --git a/test/tokentest/get-tokens.py b/test/tokentest/get-tokens.py deleted file mode 100644 index 42a8844e6..000000000 --- a/test/tokentest/get-tokens.py +++ /dev/null @@ -1,89 +0,0 @@ -#!/usr/bin/python -# Copyright (C) 2008 Thomas Thurman -# -# 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 . - - -import os -import xml.sax - -standard = ['x', 'y', 'width', 'height'] - -expressions = { - 'line': ['x1', 'x2', 'y1', 'y2'], - 'rectangle': standard, - 'arc': standard, - 'clip': standard, - 'gradient': standard, - 'image': standard, - 'gtk_arrow': standard, - 'gtk_box': standard, - 'gtk_vline': standard, - 'icon': standard, - 'title': standard, - 'include': standard, - 'tile': ['x', 'y', 'width', 'height', - 'tile_xoffset', 'tile_yoffset', - 'tile_width', 'tile_height'], -} - -all_themes = '../../../all-themes/' - -result = {} - -class themeparser: - def __init__(self, name): - self.filename = name - - def processingInstruction(self): - pass - - def characters(self, what): - pass - - def setDocumentLocator(self, where): - pass - - def startDocument(self): - pass - - def startElement(self, name, attrs): - if expressions.has_key(name): - for attr in expressions[name]: - if attrs.has_key(attr): - expression = attrs[attr] - if not result.has_key(expression): result[expression] = {} - result[expression][self.filename] = 1 - - def endElement(self, name): - pass # print "end element" - - def endDocument(self): - pass - -def maybe_parse(themename, filename): - if os.access(all_themes+filename, os.F_OK): - parser = themeparser(themename) - xml.sax.parse(all_themes+filename, parser) - -for theme in os.listdir(all_themes): - maybe_parse(theme, theme+'/metacity-1/metacity-theme-1.xml') - maybe_parse(theme, theme+'/metacity-theme-1.xml') - -print '[tokentest0]' - -for expr in sorted(result.keys()): - print "# %s" % (', '.join(sorted(result[expr]))) - print "%s=REQ" % (expr) - print diff --git a/test/tokentest/tokentest.c b/test/tokentest/tokentest.c deleted file mode 100644 index 107d9ee4a..000000000 --- a/test/tokentest/tokentest.c +++ /dev/null @@ -1,304 +0,0 @@ -/* - * tokentest.c - test for Metacity's tokeniser - * - * Copyright (C) 2008 Thomas Thurman - * - * 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 . - */ - -/* Still under heavy development. */ -/* Especially: FIXME: GErrors need checking! */ - -#include -#include -#include -#include -#include -#include - -#define TOKENTEST_GROUP "tokentest0" - -/************************/ -/* Dummy functions which are just here to keep the linker happy */ - -MetaTheme* meta_theme_load (const char *theme_name, - GError **err) { - /* dummy */ - return NULL; -} - -void -meta_bug(const char *format, ...) -{ - /* dummy */ -} - -void -meta_warning(const char *format, ...) -{ - /* dummy */ -} - -GType -gtk_widget_get_type (void) -{ - /* dummy */ -} - -GType -gtk_object_get_type (void) -{ - /* dummy */ -} - -void gtk_paint_arrow (GtkStyle *style, - GdkWindow *window, - GtkStateType state_type, - GtkShadowType shadow_type, - GdkRectangle *area, - GtkWidget *widget, - const gchar *detail, - GtkArrowType arrow_type, - gboolean fill, - gint x, - gint y, - gint width, - gint height) -{ - /* dummy */ -} - -void gtk_paint_vline (GtkStyle *style, - GdkWindow *window, - GtkStateType state_type, - GdkRectangle *area, - GtkWidget *widget, - const gchar *detail, - gint y1_, - gint y2_, - gint x) -{ - /* dummy */ -} -void gtk_paint_box (GtkStyle *style, - GdkWindow *window, - GtkStateType state_type, - GtkShadowType shadow_type, - GdkRectangle *area, - GtkWidget *widget, - const gchar *detail, - gint x, - gint y, - gint width, - gint height) -{ - /* dummy */ -} - -GtkIconTheme *gtk_icon_theme_get_default (void) -{ - /* dummy */ -} - -GdkPixbuf * gtk_icon_theme_load_icon (GtkIconTheme *icon_theme, - const gchar *icon_name, - gint size, - GtkIconLookupFlags flags, - GError **error) -{ - /* dummy */ -} - -MetaRectangle meta_rect (int x, int y, int width, int height) -{ - /* dummy */ -} - -void -meta_topic_real (MetaDebugTopic topic, - const char *format, - ...) -{ - /* dummy */ -} - - -/*********************************/ - -GString *draw_spec_to_string(MetaDrawSpec *spec) -{ - GString *result; - int i; - - if (spec == NULL) - return g_string_new ("NONE"); - - result = g_string_new (""); - - if (spec->constant) - { - g_string_append_printf (result, "{%d==}", spec->value); - } - - for (i=0; in_tokens; i++) - { - PosToken t = spec->tokens[i]; - - switch (t.type) - { - case POS_TOKEN_INT: - g_string_append_printf (result, "(int %d)", t.d.i.val); - break; - - case POS_TOKEN_DOUBLE: - g_string_append_printf (result, "(double %g)", t.d.d.val); - break; - - case POS_TOKEN_OPERATOR: - - switch (t.d.o.op) { - case POS_OP_NONE: - g_string_append (result, "(no-op)"); - break; - - case POS_OP_ADD: - g_string_append (result, "(add)"); - break; - - case POS_OP_SUBTRACT: - g_string_append (result, "(subtract)"); - break; - - case POS_OP_MULTIPLY: - g_string_append (result, "(multiply)"); - break; - - case POS_OP_DIVIDE: - g_string_append (result, "(divide)"); - break; - - case POS_OP_MOD: - g_string_append (result, "(mod)"); - break; - - case POS_OP_MAX: - g_string_append (result, "(max)"); - break; - - case POS_OP_MIN: - g_string_append (result, "(min)"); - break; - - default: - g_string_append_printf (result, "(op %d)", t.d.o.op); - } - - break; - - case POS_TOKEN_VARIABLE: - g_string_append_printf (result, "(str %s)", t.d.v.name); - break; - - case POS_TOKEN_OPEN_PAREN: - g_string_append (result, "( "); - break; - - case POS_TOKEN_CLOSE_PAREN: - g_string_append (result, " )"); - break; - - default: - g_string_append_printf (result, "(strange %d)", t.type); - } - - } - - return result; -} - -GKeyFile *keys; - -void -load_keys () -{ - GError* err = NULL; - gchar** keys_of_file; - gchar** cursor; - gboolean ever_printed_header = FALSE; - gint passes = 0, fails = 0; - - keys = g_key_file_new (); - - g_key_file_load_from_file (keys, - "tokentest.ini", - G_KEY_FILE_KEEP_COMMENTS, - &err); - - keys_of_file = g_key_file_get_keys (keys, - TOKENTEST_GROUP, - NULL, - &err); - - cursor = keys_of_file; - - while (*cursor) - { - gchar *desideratum = g_key_file_get_value (keys, - TOKENTEST_GROUP, - *cursor, - &err); - MetaTheme *dummy = meta_theme_new (); - MetaDrawSpec *spec; - GString *str; - - spec = meta_draw_spec_new (dummy, *cursor, &err); - - str = draw_spec_to_string (spec); - - if (strcmp ("REQ", desideratum)==0) { - gchar *comment = g_key_file_get_comment (keys, TOKENTEST_GROUP, *cursor, &err); - - if (!ever_printed_header) { - g_print ("[%s]\n", TOKENTEST_GROUP); - ever_printed_header = TRUE; - } - - g_print ("\n#%s%s=%s\n", comment? comment: "", *cursor, str->str); - g_free (comment); - } else if (strcmp (str->str, desideratum)==0) { - g_print("PASS: %s\n", *cursor); - passes++; - } else { - g_warning ("FAIL: %s, wanted %s, got %s\n", - *cursor, desideratum, str->str); - fails++; - } - - meta_theme_free (dummy); - g_string_free (str, TRUE); - g_free (desideratum); - - cursor++; - } - - g_strfreev (keys_of_file); - - g_print("\n# Passes: %d. Fails: %d.\n", passes, fails); -} - -int -main () -{ - load_keys (); -} diff --git a/test/tokentest/tokentest.ini b/test/tokentest/tokentest.ini deleted file mode 100644 index edfc58764..000000000 --- a/test/tokentest/tokentest.ini +++ /dev/null @@ -1,1873 +0,0 @@ -# Copyright (C) 2008 Thomas Thurman and others -# Generated using the "get-tokens.py" script from all themes on -# art.gnome.org, which are all released under DFSG-compatible -# licences. -# -# 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 . - -########################### - -[tokentest0] - -########################### - -# Some very simple examples -width+height=(str width)(add)(str height) -width*height=(str width)(multiply)(str height) -width `min` height=(str width)(min)(str height) - -########################### - -# Strings which can't possibly be well-formed -~~~=NONE - -########################### - -# Strings auto-generated by the original tokeniser -# from art.gnome.org themes (the theme name is given -# in a comment) - -# Amiga, AmigaRelief, pOS -(((height - title_height) / 2) `max` 0)=( ( ( (str height)(subtract)(str title_height) )(divide)(int 2) )(max)(int 0) ) - -# Amiga, AmigaRelief, pOS -(((height - title_height) / 2) `max` 0)=( ( ( (str height)(subtract)(str title_height) )(divide)(int 2) )(max)(int 0) ) - -# Aquarius, Chiro, Clearlooks, Clearlooks-2.0-blend, Clearlooks-Pinstripe, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop, Gilouche, GiloucheIM, River, SmoothGNOME, TangoDance, c2 -(((height - title_height) / 2) `max` 0) + 1=( ( ( (str height)(subtract)(str title_height) )(divide)(int 2) )(max)(int 0) )(add)(int 1) - -# Chiro, Clearlooks, Clearlooks-2.0-blend, Clearlooks-Pinstripe, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop, River, SmoothGNOME, TangoDance, c2 -(((height - title_height) / 2) `max` 0) + 2=( ( ( (str height)(subtract)(str title_height) )(divide)(int 2) )(max)(int 0) )(add)(int 2) - -# Clearlooks-RedExit -(((height - title_height) / 2) `max` 0) - 1=( ( ( (str height)(subtract)(str title_height) )(divide)(int 2) )(max)(int 0) )(subtract)(int 1) - -# Gilouche, GiloucheIM -(((height - title_height) / 2) `max` 0)-1=( ( ( (str height)(subtract)(str title_height) )(divide)(int 2) )(max)(int 0) )(subtract)(int 1) - -# Gilouche, GiloucheIM -((3 `max` (width-title_width)) / 2)=( ( (int 3)(max)( (str width)(subtract)(str title_width) ) )(divide)(int 2) ) - -# Gilouche, GiloucheIM -((3 `max` (width-title_width)) / 2)+1=( ( (int 3)(max)( (str width)(subtract)(str title_width) ) )(divide)(int 2) )(add)(int 1) - -# Gilouche, GiloucheIM -((3 `max` (width-title_width)) / 2)-1=( ( (int 3)(max)( (str width)(subtract)(str title_width) ) )(divide)(int 2) )(subtract)(int 1) - -# Esco -((height - (ButtonIPad + 1) * 2) * 0.4) * 0.67=( ( (str height)(subtract)( (str ButtonIPad)(add)(int 1) )(multiply)(int 2) )(multiply)(double 0.4) )(multiply)(double 0.67) - -# Atlanta, Bright, Carved2, Chiro, Clearlooks, Clearlooks-2.0-blend, Clearlooks-Pinstripe, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop, Crux, Gilouche, GiloucheIM, Metabox, Mista, Outcrop, Quiet-Environment, Quiet-Environment-v2, Quiet-Graphite, Quiet-Graphite-v2, Quiet-Human, Quiet-Purple-2K6, Quiet-Purple-2K6-v2, River, Sandwish, Simple, SmoothGNOME, TangoDance, Tetelestai-Modern -((height - title_height) / 2) `max` 0=( ( (str height)(subtract)(str title_height) )(divide)(int 2) )(max)(int 0) - -# Simple, Tetelestai-Modern -((height - title_height) / 2) `max` 0 + 1=( ( (str height)(subtract)(str title_height) )(divide)(int 2) )(max)(int 0)(add)(int 1) - -# Outcrop -((height - title_height) / 2) `max` 0 +2=( ( (str height)(subtract)(str title_height) )(divide)(int 2) )(max)(int 0)(add)(int 2) - -# Clearlooks, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop -((height-(Bmin`max`height-Bpad*2))/2)=( ( (str height)(subtract)( (str Bmin)(max)(str height)(subtract)(str Bpad)(multiply)(int 2) ) )(divide)(int 2) ) - -# Clearlooks, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop -((height-(Bmin`max`height-Bpad*2))/2) + 1=( ( (str height)(subtract)( (str Bmin)(max)(str height)(subtract)(str Bpad)(multiply)(int 2) ) )(divide)(int 2) )(add)(int 1) - -# Clearlooks, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop -((height-(Bmin`max`height-Bpad*2))/2) + 2=( ( (str height)(subtract)( (str Bmin)(max)(str height)(subtract)(str Bpad)(multiply)(int 2) ) )(divide)(int 2) )(add)(int 2) - -# Clearlooks, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop -((height-(Bmin`max`height-Bpad*2))/2) - 1=( ( (str height)(subtract)( (str Bmin)(max)(str height)(subtract)(str Bpad)(multiply)(int 2) ) )(divide)(int 2) )(subtract)(int 1) - -# Clearbox-in, Clearbox-out, Simplebox -((height-title_height)/2) `max` 0=( ( (str height)(subtract)(str title_height) )(divide)(int 2) )(max)(int 0) - -# Crux -((left_width + ButtonWidth + IconTitleSpacing + title_width + CenterTitlePieceWidth * height / 22) `min` (width - 3 * ButtonWidth - right_width)) + 1=( ( (str left_width)(add)(str ButtonWidth)(add)(str IconTitleSpacing)(add)(str title_width)(add)(str CenterTitlePieceWidth)(multiply)(str height)(divide)(int 22) )(min)( (str width)(subtract)(int 3)(multiply)(str ButtonWidth)(subtract)(str right_width) ) )(add)(int 1) - -# Crux -((left_width + ButtonWidth + IconTitleSpacing + title_width) `min` (width - object_width * height / 22 - right_width - 3 * ButtonWidth)) + 1=( ( (str left_width)(add)(str ButtonWidth)(add)(str IconTitleSpacing)(add)(str title_width) )(min)( (str width)(subtract)(str object_width)(multiply)(str height)(divide)(int 22)(subtract)(str right_width)(subtract)(int 3)(multiply)(str ButtonWidth) ) )(add)(int 1) - -# Crux, Sandwish -((title_width + height / 2 + 32)) + 1=( ( (str title_width)(add)(str height)(divide)(int 2)(add)(int 32) ) )(add)(int 1) - -# Crux, Sandwish -((title_width + height / 2 - 4) `min` (width - object_width - 26))=( ( (str title_width)(add)(str height)(divide)(int 2)(subtract)(int 4) )(min)( (str width)(subtract)(str object_width)(subtract)(int 26) ) ) - -# Crux, Sandwish -((title_width + height / 2) `min` (width - object_width - 6)) + 1=( ( (str title_width)(add)(str height)(divide)(int 2) )(min)( (str width)(subtract)(str object_width)(subtract)(int 6) ) )(add)(int 1) - -# Sandwish -((title_width - 4) `min` (title_width/2-10))=( ( (str title_width)(subtract)(int 4) )(min)( (str title_width)(divide)(int 2)(subtract)(int 10) ) ) - -# Sandwish -((title_width) `min` (title_width/2-10))=( ( (str title_width) )(min)( (str title_width)(divide)(int 2)(subtract)(int 10) ) ) - -# Sandwish -((title_width) `min` (width)) + 1=( ( (str title_width) )(min)( (str width) ) )(add)(int 1) - -# Sandwish -((title_width)) + 1=( ( (str title_width) ) )(add)(int 1) - -# Quiet-Environment-v2, Quiet-Graphite-v2, Quiet-Purple-2K6-v2 -((width - title_width) / 2)=( ( (str width)(subtract)(str title_width) )(divide)(int 2) ) - -# Clearlooks, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop -((width-(Bmin`max`height-Bpad*2))/2)=( ( (str width)(subtract)( (str Bmin)(max)(str height)(subtract)(str Bpad)(multiply)(int 2) ) )(divide)(int 2) ) - -# Clearlooks, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop -((width-(Bmin`max`height-Bpad*2))/2) + 1=( ( (str width)(subtract)( (str Bmin)(max)(str height)(subtract)(str Bpad)(multiply)(int 2) ) )(divide)(int 2) )(add)(int 1) - -# Clearlooks, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop -((width-(Bmin`max`height-Bpad*2))/2) + 2=( ( (str width)(subtract)( (str Bmin)(max)(str height)(subtract)(str Bpad)(multiply)(int 2) ) )(divide)(int 2) )(add)(int 2) - -# Sloth -((width-title_width)/2) `max` 40=( ( (str width)(subtract)(str title_width) )(divide)(int 2) )(max)(int 40) - -# Atlanta, EasyListening, Metabox, Outcrop -(0 `max` (width-title_width)) / 2=( (int 0)(max)( (str width)(subtract)(str title_width) ) )(divide)(int 2) - -# Outcrop -(0 `max` (width-title_width)) / 2 +1=( (int 0)(max)( (str width)(subtract)(str title_width) ) )(divide)(int 2)(add)(int 1) - -# EasyListening -(0 `max` (width-title_width)) / 2 - 1=( (int 0)(max)( (str width)(subtract)(str title_width) ) )(divide)(int 2)(subtract)(int 1) - -# Atlanta, Bright, Metabox, Outcrop -(0 `max` (width-title_width-mini_icon_width-IconTitleSpacing)) / 2=( (int 0)(max)( (str width)(subtract)(str title_width)(subtract)(str mini_icon_width)(subtract)(str IconTitleSpacing) ) )(divide)(int 2) - -# Atlanta, Metabox, Outcrop, Simple -(0 `max` (width-title_width-mini_icon_width-IconTitleSpacing)) / 2 + mini_icon_width + IconTitleSpacing=( (int 0)(max)( (str width)(subtract)(str title_width)(subtract)(str mini_icon_width)(subtract)(str IconTitleSpacing) ) )(divide)(int 2)(add)(str mini_icon_width)(add)(str IconTitleSpacing) - -# Simple -(0 `max` (width-title_width-mini_icon_width-IconTitleSpacing)) / 2 + mini_icon_width + IconTitleSpacing + 1=( (int 0)(max)( (str width)(subtract)(str title_width)(subtract)(str mini_icon_width)(subtract)(str IconTitleSpacing) ) )(divide)(int 2)(add)(str mini_icon_width)(add)(str IconTitleSpacing)(add)(int 1) - -# Outcrop -(0 `max` (width-title_width-mini_icon_width-IconTitleSpacing)) / 2 + mini_icon_width + IconTitleSpacing +1=( (int 0)(max)( (str width)(subtract)(str title_width)(subtract)(str mini_icon_width)(subtract)(str IconTitleSpacing) ) )(divide)(int 2)(add)(str mini_icon_width)(add)(str IconTitleSpacing)(add)(int 1) - -# Aquarius, Carved2, Chiro, Clearlooks, Clearlooks-2.0-blend, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, Gilouche, GiloucheIM, River, SmoothGNOME, TangoDance, c2 -(3 `max` (width-title_width)) / 2=( (int 3)(max)( (str width)(subtract)(str title_width) ) )(divide)(int 2) - -# Aquarius, Carved2, Chiro, Clearlooks, Clearlooks-2.0-blend, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, River, SmoothGNOME, TangoDance, c2 -(3 `max` (width-title_width)) / 2 + 1=( (int 3)(max)( (str width)(subtract)(str title_width) ) )(divide)(int 2)(add)(int 1) - -# Chiro, Clearlooks, Clearlooks-2.0-blend, Clearlooks-Pinstripe, Clearlooks2-Squared, Clearlooks2-Squared-Berries, River, SmoothGNOME, TangoDance, c2 -(3 `max` (width-title_width)) / 2 + 2=( (int 3)(max)( (str width)(subtract)(str title_width) ) )(divide)(int 2)(add)(int 2) - -# Bright -(3 `max` (width-title_width)) / 2+2=( (int 3)(max)( (str width)(subtract)(str title_width) ) )(divide)(int 2)(add)(int 2) - -# Sandwish -(4+title_width+20) `min` (title_width-30)=( (int 4)(add)(str title_width)(add)(int 20) )(min)( (str title_width)(subtract)(int 30) ) - -# Sandwish -(4+title_width+291-34) `min` (width-4)=( (int 4)(add)(str title_width)(add)(int 291)(subtract)(int 34) )(min)( (str width)(subtract)(int 4) ) - -# Chiro, c2 -(ButtonIPad+1) + 1=( (str ButtonIPad)(add)(int 1) )(add)(int 1) - -# Esco -(height - (ButtonIPad + 1) * 2) * 0.4=( (str height)(subtract)( (str ButtonIPad)(add)(int 1) )(multiply)(int 2) )(multiply)(double 0.4) - -# Esco -(height - (ButtonIPad + 1) * 2) * 0.4 + 1=( (str height)(subtract)( (str ButtonIPad)(add)(int 1) )(multiply)(int 2) )(multiply)(double 0.4)(add)(int 1) - -# Esco -(height - (ButtonIPad + 1) * 2) * 0.67=( (str height)(subtract)( (str ButtonIPad)(add)(int 1) )(multiply)(int 2) )(multiply)(double 0.67) - -# AgingGorilla, Crux, Gorilla, Sandwish, Soft Squares, Tactile, ThinMC -(height - object_height) / 2=( (str height)(subtract)(str object_height) )(divide)(int 2) - -# Graphite -(height - title_height + 2) / 2=( (str height)(subtract)(str title_height)(add)(int 2) )(divide)(int 2) - -# Agata, Alphacube 0.9b Metacity Color, Alphacube 0.9b Metacity Light, Alphacube 0.9b Metacity Simple, Black, Correcamins, Firey 1.0, Firey Dark, Graphite, Maemo, Redmond, Silverado, Soft Squares, Tactile, ThinMC -(height - title_height) / 2=( (str height)(subtract)(str title_height) )(divide)(int 2) - -# Agata, Black, Firey 1.0, Firey Dark -(height - title_height) / 2 + 1=( (str height)(subtract)(str title_height) )(divide)(int 2)(add)(int 1) - -# Agata -(height - title_height) / 2 - 1=( (str height)(subtract)(str title_height) )(divide)(int 2)(subtract)(int 1) - -# Maemo -(height - title_height) / 2+1=( (str height)(subtract)(str title_height) )(divide)(int 2)(add)(int 1) - -# sky, sky-blue -(height - title_height) / 5=( (str height)(subtract)(str title_height) )(divide)(int 5) - -# Esco -(height / 2) - (mini_icon_height / 2)=( (str height)(divide)(int 2) )(subtract)( (str mini_icon_height)(divide)(int 2) ) - -# Esco -(height / 2) - (mini_icon_height / 2) - 2=( (str height)(divide)(int 2) )(subtract)( (str mini_icon_height)(divide)(int 2) )(subtract)(int 2) - -# Esco -(height / 2) - (title_height / 2)=( (str height)(divide)(int 2) )(subtract)( (str title_height)(divide)(int 2) ) - -# Esco -(height / 2) - (title_height / 2) - 1=( (str height)(divide)(int 2) )(subtract)( (str title_height)(divide)(int 2) )(subtract)(int 1) - -# Esco -(height / 2) - (title_height / 2) - 2=( (str height)(divide)(int 2) )(subtract)( (str title_height)(divide)(int 2) )(subtract)(int 2) - -# Atlanta -(height-(ArrowSpacer*2)) `max` MinArrowSize=( (str height)(subtract)( (str ArrowSpacer)(multiply)(int 2) ) )(max)(str MinArrowSize) - -# Outcrop -(height-1)-(title_height /1.5)=( (str height)(subtract)(int 1) )(subtract)( (str title_height)(divide)(double 1.5) ) - -# Clearlooks-2.0-blend, Gilouche, GiloucheIM, TangoDance -(height-10)/2=( (str height)(subtract)(int 10) )(divide)(int 2) - -# Atlanta, Bright, Metabox, Outcrop -(height-mini_icon_height) / 2=( (str height)(subtract)(str mini_icon_height) )(divide)(int 2) - -# Aquarius, Clearlooks-RedExit, Firey 1.0, Firey Dark, Gilouche, GiloucheIM -(height-mini_icon_height)/2=( (str height)(subtract)(str mini_icon_height) )(divide)(int 2) - -# Clearlooks-2.0-blend, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop, TangoDance -(height-mini_icon_height)/2+1=( (str height)(subtract)(str mini_icon_height) )(divide)(int 2)(add)(int 1) - -# Vista Basic -(height-mini_icon_height)/2-1=( (str height)(subtract)(str mini_icon_height) )(divide)(int 2)(subtract)(int 1) - -# boxx -(height-object_height)/2=( (str height)(subtract)(str object_height) )(divide)(int 2) - -# boxx -(height-object_height)/2+1=( (str height)(subtract)(str object_height) )(divide)(int 2)(add)(int 1) - -# 4DWM, MWM -(height-title_height)/2=( (str height)(subtract)(str title_height) )(divide)(int 2) - -# Tetelestai-Modern -(height/2)-3=( (str height)(divide)(int 2) )(subtract)(int 3) - -# Tetelestai-Modern -(height/2)-4=( (str height)(divide)(int 2) )(subtract)(int 4) - -# Sloth -(height/2)-5=( (str height)(divide)(int 2) )(subtract)(int 5) - -# Crux -(left_width + ButtonWidth + IconTitleSpacing + title_width) `min` (width - right_width - 3 * ButtonWidth - CenterTitlePieceWidth * height / 22 - 3)=( (str left_width)(add)(str ButtonWidth)(add)(str IconTitleSpacing)(add)(str title_width) )(min)( (str width)(subtract)(str right_width)(subtract)(int 3)(multiply)(str ButtonWidth)(subtract)(str CenterTitlePieceWidth)(multiply)(str height)(divide)(int 22)(subtract)(int 3) ) - -# Chiro, c2 -(title_height + 6)/2=( (str title_height)(add)(int 6) )(divide)(int 2) - -# Chiro, c2 -(title_height + 6)/2+1=( (str title_height)(add)(int 6) )(divide)(int 2)(add)(int 1) - -# Esco -(width - (ButtonIPad + 1) * 2) * 0.67=( (str width)(subtract)( (str ButtonIPad)(add)(int 1) )(multiply)(int 2) )(multiply)(double 0.67) - -# AgingGorilla, Crux, Gorilla, Quiet-Environment, Quiet-Environment-v2, Quiet-Graphite, Quiet-Graphite-v2, Quiet-Human, Quiet-Purple-2K6, Quiet-Purple-2K6-v2, Sandwish, Soft Squares, Tactile, ThinMC -(width - object_width) / 2=( (str width)(subtract)(str object_width) )(divide)(int 2) - -# Crux, Sandwish -(width - title_width - height / 2 - 32 - 7) `max` 0=( (str width)(subtract)(str title_width)(subtract)(str height)(divide)(int 2)(subtract)(int 32)(subtract)(int 7) )(max)(int 0) - -# Crux -(width - title_width - left_width - ButtonWidth - IconTitleSpacing - CenterTitlePieceWidth * height / 22 - right_width) `max` (3 * ButtonWidth)=( (str width)(subtract)(str title_width)(subtract)(str left_width)(subtract)(str ButtonWidth)(subtract)(str IconTitleSpacing)(subtract)(str CenterTitlePieceWidth)(multiply)(str height)(divide)(int 22)(subtract)(str right_width) )(max)( (int 3)(multiply)(str ButtonWidth) ) - -# Sandwish -(width - title_width - left_width - ButtonWidth - IconTitleSpacing - right_width) `max` (3 * ButtonWidth)=( (str width)(subtract)(str title_width)(subtract)(str left_width)(subtract)(str ButtonWidth)(subtract)(str IconTitleSpacing)(subtract)(str right_width) )(max)( (int 3)(multiply)(str ButtonWidth) ) - -# Agata, Alphacube 0.9b Metacity Color, Alphacube 0.9b Metacity Light, Alphacube 0.9b Metacity Simple, Black, Firey 1.0, Firey Dark, Soft Squares, Tactile -(width - title_width) / 2=( (str width)(subtract)(str title_width) )(divide)(int 2) - -# Agata, Black -(width - title_width) / 2 +1=( (str width)(subtract)(str title_width) )(divide)(int 2)(add)(int 1) - -# Agata -(width - title_width) / 2 -1=( (str width)(subtract)(str title_width) )(divide)(int 2)(subtract)(int 1) - -# Sandwish -(width -183) `max` 0=( (str width)(subtract)(int 183) )(max)(int 0) - -# Graphite -(width -title_width + 2) / 2=( (str width)(subtract)(str title_width)(add)(int 2) )(divide)(int 2) - -# Graphite -(width -title_width) / 2=( (str width)(subtract)(str title_width) )(divide)(int 2) - -# Carved2 -(width / 2) + 3=( (str width)(divide)(int 2) )(add)(int 3) - -# Carved2 -(width / 2) - 3=( (str width)(divide)(int 2) )(subtract)(int 3) - -# Atlanta -(width-(ArrowSpacer*2)) `max` MinArrowSize=( (str width)(subtract)( (str ArrowSpacer)(multiply)(int 2) ) )(max)(str MinArrowSize) - -# Clearlooks-2.0-blend, Gilouche, GiloucheIM, TangoDance -(width-10)/2=( (str width)(subtract)(int 10) )(divide)(int 2) - -# boxx -(width-18-title_width-18)/18*18+9=( (str width)(subtract)(int 18)(subtract)(str title_width)(subtract)(int 18) )(divide)(int 18)(multiply)(int 18)(add)(int 9) - -# Metabox -(width-ButtonIPad)/2+1=( (str width)(subtract)(str ButtonIPad) )(divide)(int 2)(add)(int 1) - -# Clearlooks-RedExit, Firey 1.0, Firey Dark, Gilouche, GiloucheIM, Mista -(width-mini_icon_width)/2=( (str width)(subtract)(str mini_icon_width) )(divide)(int 2) - -# Aquarius, Clearlooks-2.0-blend, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop, TangoDance, Vista Basic -(width-mini_icon_width)/2-2=( (str width)(subtract)(str mini_icon_width) )(divide)(int 2)(subtract)(int 2) - -# MWM -(width-title_width)/2 `max` 10=( (str width)(subtract)(str title_width) )(divide)(int 2)(max)(int 10) - -# 4DWM, Agata, AgingGorilla, Almond, Alphacube 0.9b Metacity Color, Alphacube 0.9b Metacity Light, Alphacube 0.9b Metacity Simple, Amiga, AmigaRelief, Aquarius, Atlanta, Bentham, Black, Bright, Carved2, Chiro, Clearbox-in, Clearbox-look-2, Clearbox-out, Clearlooks, Clearlooks-2.0-blend, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop, Correcamins, Crux, EasyListening, Esco, Firey 1.0, Firey Dark, Gilouche, GiloucheIM, Gorilla, Graphite, MWM, Maemo, MetaGrip, Metabox, Mista, Outcrop, Quiet-Environment, Quiet-Environment-v2, Quiet-Graphite, Quiet-Graphite-v2, Quiet-Human, Quiet-Purple-2K6, Quiet-Purple-2K6-v2, Redmond, River, Sandwish, Shiny, Shiny-Tango, Silverado, Simple, Simplebox, Sloth , SmoothGNOME, Soft Squares, Tactile, TangoDance, Tetelestai-Modern, ThinMC, Vista Basic, W2k, boxx, c2, pOS, sky, sky-blue -0={0==}(int 0) - -# Esco -0 - 25={-25==}(int 0)(subtract)(int 25) - -# Clearbox-look-2 -0 `max` ((height-title_height)/2)=(int 0)(max)( ( (str height)(subtract)(str title_height) )(divide)(int 2) ) - -# Bentham -0 `max` ((width-title_width)) / 2 - height=(int 0)(max)( ( (str width)(subtract)(str title_width) ) )(divide)(int 2)(subtract)(str height) - -# Vista Basic -0+1={1==}(int 0)(add)(int 1) - -# Vista Basic -0+2={2==}(int 0)(add)(int 2) - -# Amiga -0.125 * height=(double 0.125)(multiply)(str height) - -# Amiga -0.125 * width=(double 0.125)(multiply)(str width) - -# Amiga, AmigaRelief -0.25 * height=(double 0.25)(multiply)(str height) - -# Amiga, AmigaRelief -0.25 * width=(double 0.25)(multiply)(str width) - -# AmigaRelief -0.3 * height=(double 0.3)(multiply)(str height) - -# AmigaRelief -0.3 * width=(double 0.3)(multiply)(str width) - -# Amiga, AmigaRelief -0.35 * height=(double 0.35)(multiply)(str height) - -# Amiga, AmigaRelief -0.35 * width=(double 0.35)(multiply)(str width) - -# Amiga, AmigaRelief -0.375 * height=(double 0.375)(multiply)(str height) - -# Amiga, AmigaRelief -0.375 * width=(double 0.375)(multiply)(str width) - -# Amiga, AmigaRelief -0.4 * height=(double 0.4)(multiply)(str height) - -# Amiga, AmigaRelief -0.4 * width=(double 0.4)(multiply)(str width) - -# Amiga, AmigaRelief -0.5 * height=(double 0.5)(multiply)(str height) - -# Amiga, AmigaRelief -0.5 * width=(double 0.5)(multiply)(str width) - -# Amiga, AmigaRelief -0.525 * height=(double 0.525)(multiply)(str height) - -# AmigaRelief -0.525 * width=(double 0.525)(multiply)(str width) - -# AmigaRelief -0.6 * height=(double 0.6)(multiply)(str height) - -# AmigaRelief -0.6 * width=(double 0.6)(multiply)(str width) - -# AmigaRelief -0.625 * height=(double 0.625)(multiply)(str height) - -# AmigaRelief -0.625 * width=(double 0.625)(multiply)(str width) - -# AmigaRelief -0.65 * height=(double 0.65)(multiply)(str height) - -# AmigaRelief -0.7 * height=(double 0.7)(multiply)(str height) - -# AmigaRelief -0.7 * width=(double 0.7)(multiply)(str width) - -# AmigaRelief -0.75 * height=(double 0.75)(multiply)(str height) - -# AmigaRelief -0.75 * width=(double 0.75)(multiply)(str width) - -# 4DWM, AgingGorilla, Almond, Amiga, AmigaRelief, Aquarius, Atlanta, Bentham, Bright, Carved2, Chiro, Clearbox-in, Clearbox-look-2, Clearbox-out, Clearlooks, Clearlooks-2.0-blend, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop, EasyListening, Esco, Firey 1.0, Firey Dark, Gilouche, GiloucheIM, Gorilla, MWM, Maemo, MetaGrip, Metabox, Outcrop, Quiet-Environment, Quiet-Environment-v2, Quiet-Graphite, Quiet-Graphite-v2, Quiet-Human, Quiet-Purple-2K6, Quiet-Purple-2K6-v2, Redmond, River, Shiny, Shiny-Tango, Silverado, Simple, Simplebox, SmoothGNOME, Soft Squares, Tactile, TangoDance, Tetelestai-Modern, Vista Basic, W2k, boxx, c2, pOS -1={1==}(int 1) - -# Clearbox-look-2 -1 `max` ((height-title_height)/2)+1=(int 1)(max)( ( (str height)(subtract)(str title_height) )(divide)(int 2) )(add)(int 1) - -# Almond, MetaGrip, Shiny, Shiny-Tango -1 `max` ((height-title_height)/2)-1=(int 1)(max)( ( (str height)(subtract)(str title_height) )(divide)(int 2) )(subtract)(int 1) - -# Agata, Alphacube 0.9b Metacity Color, Alphacube 0.9b Metacity Light, Alphacube 0.9b Metacity Simple, Amiga, AmigaRelief, Black, Clearlooks-2.0-blend, Gilouche, GiloucheIM, Maemo, Outcrop, Shiny, Shiny-Tango, Sloth , TangoDance, pOS, sky, sky-blue -10={10==}(int 10) - -# MetaGrip -1024={1024==}(int 1024) - -# MetaGrip, Shiny, Shiny-Tango -11={11==}(int 11) - -# Almond, Shiny, Shiny-Tango -12={12==}(int 12) - -# Shiny -13={13==}(int 13) - -# Almond, Sloth -14={14==}(int 14) - -# sky, sky-blue -15={15==}(int 15) - -# Almond, Graphite, Maemo, MetaGrip, Shiny, Shiny-Tango, sky, sky-blue -16={16==}(int 16) - -# boxx -1600={1600==}(int 1600) - -# Agata, Maemo, boxx -17={17==}(int 17) - -# EasyListening, MetaGrip, Shiny, Shiny-Tango, boxx -19={19==}(int 19) - -# 4DWM, AgingGorilla, Almond, Amiga, AmigaRelief, Aquarius, Bright, Carved2, Chiro, Clearbox-in, Clearbox-look-2, Clearbox-out, Clearlooks, Clearlooks-2.0-blend, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop, Crux, EasyListening, Esco, Gilouche, GiloucheIM, Gorilla, MWM, Maemo, Mista, Outcrop, Quiet-Environment, Quiet-Environment-v2, Quiet-Graphite, Quiet-Graphite-v2, Quiet-Human, Quiet-Purple-2K6, Quiet-Purple-2K6-v2, River, Sandwish, Shiny, Shiny-Tango, Silverado, Simple, Simplebox, Sloth , SmoothGNOME, Tactile, TangoDance, Tetelestai-Modern, ThinMC, Vista Basic, boxx, c2, pOS -2={2==}(int 2) - -# Redmond -2 + ButtonIPad=(int 2)(add)(str ButtonIPad) - -# Shiny, Shiny-Tango -2 `max` ((height-title_height)/2)=(int 2)(max)( ( (str height)(subtract)(str title_height) )(divide)(int 2) ) - -# Firey 1.0, Firey Dark, Maemo, MetaGrip, Shiny, Shiny-Tango -20={20==}(int 20) - -# Shiny, Shiny-Tango -21={21==}(int 21) - -# Soft Squares -22={22==}(int 22) - -# Graphite, MetaGrip, Shiny, Shiny-Tango, sky, sky-blue -23={23==}(int 23) - -# Almond, Maemo, Shiny, Shiny-Tango -24={24==}(int 24) - -# Agata -25={25==}(int 25) - -# 4DWM, AgingGorilla, Amiga, AmigaRelief, Aquarius, Bright, Chiro, Clearbox-look-2, Clearlooks, Clearlooks-2.0-blend, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop, Crux, EasyListening, Esco, Gilouche, GiloucheIM, Gorilla, Maemo, MetaGrip, Mista, Outcrop, Quiet-Environment, Quiet-Environment-v2, Quiet-Graphite, Quiet-Graphite-v2, Quiet-Human, Quiet-Purple-2K6, Quiet-Purple-2K6-v2, Redmond, River, Sandwish, Shiny, Shiny-Tango, Sloth , SmoothGNOME, Tetelestai-Modern, Vista Basic, W2k, boxx, c2, pOS -3={3==}(int 3) - -# Atlanta, Bright, Metabox, Redmond, Simple, SmoothGNOME, Tetelestai-Modern -3 + ButtonIPad=(int 3)(add)(str ButtonIPad) - -# SmoothGNOME -3 + ButtonIPad+1=(int 3)(add)(str ButtonIPad)(add)(int 1) - -# Chiro, Maemo, SmoothGNOME -32={32==}(int 32) - -# Outcrop -36={36==}(int 36) - -# Graphite -39={39==}(int 39) - -# 4DWM, Agata, AgingGorilla, Almond, Amiga, AmigaRelief, Aquarius, Chiro, Clearbox-in, Clearbox-look-2, Clearbox-out, Clearlooks, Clearlooks-2.0-blend, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop, Crux, EasyListening, Firey 1.0, Firey Dark, Gilouche, GiloucheIM, Gorilla, MWM, Maemo, MetaGrip, Redmond, River, Sandwish, Silverado, Simplebox, Sloth , SmoothGNOME, W2k, boxx, c2, pOS -4={4==}(int 4) - -# Clearbox-look-2 -4 `max` (width-title_width)/2=(int 4)(max)( (str width)(subtract)(str title_width) )(divide)(int 2) - -# sky, sky-blue -40={40==}(int 40) - -# TangoDance -48={48==}(int 48) - -# 4DWM, AgingGorilla, Almond, AmigaRelief, Aquarius, Black, Clearbox-in, Clearbox-look-2, Clearbox-out, Clearlooks, Clearlooks-2.0-blend, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop, Correcamins, Crux, Gorilla, MWM, MetaGrip, Outcrop, Redmond, Sandwish, Shiny, Shiny-Tango, Simplebox, Sloth , Tactile, ThinMC, Vista Basic, pOS -5={5==}(int 5) - -# Almond, Clearbox-look-2, MetaGrip, Shiny, Shiny-Tango -5 `max` (width-title_width)/2+1=(int 5)(max)( (str width)(subtract)(str title_width) )(divide)(int 2)(add)(int 1) - -# 4DWM, AgingGorilla, Clearbox-in, Clearbox-out, Clearlooks-RedExit, Firey 1.0, Firey Dark, Gorilla, Graphite, MWM, Maemo, Outcrop, Simplebox, Soft Squares, Vista Basic, pOS -6={6==}(int 6) - -# Shiny, Shiny-Tango -6 `max` (width-title_width)/2+2=(int 6)(max)( (str width)(subtract)(str title_width) )(divide)(int 2)(add)(int 2) - -# 4DWM, Almond, Alphacube 0.9b Metacity Color, Alphacube 0.9b Metacity Light, Alphacube 0.9b Metacity Simple, Clearbox-in, Clearbox-out, MWM, MetaGrip, Outcrop, Shiny, Shiny-Tango, Simplebox, pOS -7={7==}(int 7) - -# 4DWM, AgingGorilla, Almond, Clearlooks-RedExit, Gorilla, Maemo, Outcrop, Shiny, Sloth , Tactile, pOS -8={8==}(int 8) - -# Clearlooks-RedExit -8 + top_height - 16=(int 8)(add)(str top_height)(subtract)(int 16) - -# Vista Basic -87={87==}(int 87) - -# Clearbox-in, Clearbox-out, Outcrop, Shiny, Shiny-Tango, Simplebox, Vista Basic, pOS, sky, sky-blue -9={9==}(int 9) - -# Atlanta -ArrowSpacer `min` (height-MinArrowSize)/2=(str ArrowSpacer)(min)( (str height)(subtract)(str MinArrowSize) )(divide)(int 2) - -# Atlanta -ArrowSpacer `min` (width-MinArrowSize)/2=(str ArrowSpacer)(min)( (str width)(subtract)(str MinArrowSize) )(divide)(int 2) - -# Atlanta, Bright, Carved2, Chiro, Esco, Metabox, Redmond, River, Simple, SmoothGNOME, Tetelestai-Modern, c2 -ButtonIPad=(str ButtonIPad) - -# Esco -ButtonIPad + (height - (ButtonIPad + 1) * 2) * 0.33=(str ButtonIPad)(add)( (str height)(subtract)( (str ButtonIPad)(add)(int 1) )(multiply)(int 2) )(multiply)(double 0.33) - -# Esco -ButtonIPad + (height - (ButtonIPad + 1) * 2) * 0.33 + 1=(str ButtonIPad)(add)( (str height)(subtract)( (str ButtonIPad)(add)(int 1) )(multiply)(int 2) )(multiply)(double 0.33)(add)(int 1) - -# Esco -ButtonIPad + (width - (ButtonIPad + 1) * 2) * 0.33=(str ButtonIPad)(add)( (str width)(subtract)( (str ButtonIPad)(add)(int 1) )(multiply)(int 2) )(multiply)(double 0.33) - -# Esco -ButtonIPad + (width - (ButtonIPad + 1) * 2) * 0.33 + 1=(str ButtonIPad)(add)( (str width)(subtract)( (str ButtonIPad)(add)(int 1) )(multiply)(int 2) )(multiply)(double 0.33)(add)(int 1) - -# Carved2, Chiro, Esco, River, c2 -ButtonIPad + 1=(str ButtonIPad)(add)(int 1) - -# Esco -ButtonIPad + 1 + 1=(str ButtonIPad)(add)(int 1)(add)(int 1) - -# Chiro, River, c2 -ButtonIPad + 2=(str ButtonIPad)(add)(int 2) - -# Chiro, River, c2 -ButtonIPad + 3=(str ButtonIPad)(add)(int 3) - -# Carved2, Chiro, Esco, Metabox, Redmond, River, Simple, Tetelestai-Modern, c2 -ButtonIPad - 1=(str ButtonIPad)(subtract)(int 1) - -# Esco -ButtonIPad - 1 + 1=(str ButtonIPad)(subtract)(int 1)(add)(int 1) - -# Atlanta, Bright, Chiro, Metabox, Redmond, Simple, SmoothGNOME, Tetelestai-Modern, c2 -ButtonIPad+1=(str ButtonIPad)(add)(int 1) - -# Simple -ButtonIPad+2=(str ButtonIPad)(add)(int 2) - -# Redmond, SmoothGNOME -ButtonIPad-1=(str ButtonIPad)(subtract)(int 1) - -# Clearbox-look-2 -ButtonPad=(str ButtonPad) - -# Clearbox-look-2 -ButtonPad+(height-ButtonPad)/6=(str ButtonPad)(add)( (str height)(subtract)(str ButtonPad) )(divide)(int 6) - -# Clearbox-look-2 -ButtonPad+(height-ButtonPad)/6-1=(str ButtonPad)(add)( (str height)(subtract)(str ButtonPad) )(divide)(int 6)(subtract)(int 1) - -# Clearbox-look-2 -ButtonPad+1=(str ButtonPad)(add)(int 1) - -# Clearbox-look-2 -ButtonPad+2=(str ButtonPad)(add)(int 2) - -# Clearbox-look-2 -ButtonPad+3=(str ButtonPad)(add)(int 3) - -# Clearbox-look-2 -ButtonPad-1=(str ButtonPad)(subtract)(int 1) - -# Clearbox-look-2 -ButtonPad-2=(str ButtonPad)(subtract)(int 2) - -# Mista -CaptionStart=(str CaptionStart) - -# AgingGorilla, Crux, Gorilla, Sandwish -IconTitleSpacing=(str IconTitleSpacing) - -# Clearbox-look-2 -PrelightPad=(str PrelightPad) - -# Clearbox-look-2 -PrelightPad+(height-PrelightPad)/6=(str PrelightPad)(add)( (str height)(subtract)(str PrelightPad) )(divide)(int 6) - -# Clearbox-look-2 -PrelightPad+(height-PrelightPad)/6-1=(str PrelightPad)(add)( (str height)(subtract)(str PrelightPad) )(divide)(int 6)(subtract)(int 1) - -# Clearbox-look-2 -PrelightPad+1=(str PrelightPad)(add)(int 1) - -# Clearbox-look-2 -PrelightPad+2=(str PrelightPad)(add)(int 2) - -# Clearbox-look-2 -PrelightPad+3=(str PrelightPad)(add)(int 3) - -# Clearbox-look-2 -PrelightPad-1=(str PrelightPad)(subtract)(int 1) - -# Clearbox-look-2 -PrelightPad-2=(str PrelightPad)(subtract)(int 2) - -# Carved2 -ResizerWidth=(str ResizerWidth) - -# Carved2 -ResizerWidth + 1=(str ResizerWidth)(add)(int 1) - -# Mista -TitlebarPad=(str TitlebarPad) - -# Silverado -bottom_height=(str bottom_height) - -# Carved2 -bottom_height - 3=(str bottom_height)(subtract)(int 3) - -# Carved2 -bottom_height - 4=(str bottom_height)(subtract)(int 4) - -# MWM, Tetelestai-Modern -bottom_height-1=(str bottom_height)(subtract)(int 1) - -# 4DWM -bottom_height-2=(str bottom_height)(subtract)(int 2) - -# 4DWM -bottom_height-4=(str bottom_height)(subtract)(int 4) - -# 4DWM, Agata, AgingGorilla, Almond, Alphacube 0.9b Metacity Color, Alphacube 0.9b Metacity Light, Alphacube 0.9b Metacity Simple, Amiga, Atlanta, Black, Bright, Carved2, Chiro, Clearbox-in, Clearbox-out, Clearlooks, Clearlooks-Pinstripe, Clearlooks-RedExit, Correcamins, Crux, EasyListening, Esco, Firey 1.0, Firey Dark, Gorilla, Graphite, MWM, Maemo, MetaGrip, Metabox, Mista, Outcrop, Redmond, River, Sandwish, Shiny, Shiny-Tango, Silverado, Simple, Simplebox, SmoothGNOME, Soft Squares, Tactile, TangoDance, Tetelestai-Modern, ThinMC, Vista Basic, W2k, boxx, c2, sky, sky-blue -height=(str height) - -# Esco -height + 25=(str height)(add)(int 25) - -# Clearlooks, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop -height - ((height-(Bmin`max`height-Bpad*2))/2)=(str height)(subtract)( ( (str height)(subtract)( (str Bmin)(max)(str height)(subtract)(str Bpad)(multiply)(int 2) ) )(divide)(int 2) ) - -# Clearlooks, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop -height - ((height-(Bmin`max`height-Bpad*2))/2) - 1=(str height)(subtract)( ( (str height)(subtract)( (str Bmin)(max)(str height)(subtract)(str Bpad)(multiply)(int 2) ) )(divide)(int 2) )(subtract)(int 1) - -# Clearlooks, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop -height - ((height-(Bmin`max`height-Bpad*2))/2) - 2=(str height)(subtract)( ( (str height)(subtract)( (str Bmin)(max)(str height)(subtract)(str Bpad)(multiply)(int 2) ) )(divide)(int 2) )(subtract)(int 2) - -# Clearlooks, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop -height - ((height-(Bmin`max`height-Bpad*2))/2)-1=(str height)(subtract)( ( (str height)(subtract)( (str Bmin)(max)(str height)(subtract)(str Bpad)(multiply)(int 2) ) )(divide)(int 2) )(subtract)(int 1) - -# Esco -height - (ButtonIPad + 1) * 2=(str height)(subtract)( (str ButtonIPad)(add)(int 1) )(multiply)(int 2) - -# AgingGorilla, Aquarius, Carved2, Clearlooks, Clearlooks-2.0-blend, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop, Esco, Gilouche, GiloucheIM, Gorilla, Quiet-Environment, Quiet-Environment-v2, Quiet-Graphite, Quiet-Graphite-v2, Quiet-Human, Quiet-Purple-2K6, Quiet-Purple-2K6-v2, Redmond, River, Simple, SmoothGNOME, TangoDance -height - 1=(str height)(subtract)(int 1) - -# Esco -height - 1 - ButtonIPad - 1=(str height)(subtract)(int 1)(subtract)(str ButtonIPad)(subtract)(int 1) - -# Esco -height - 1 - ButtonIPad - 1 + 1=(str height)(subtract)(int 1)(subtract)(str ButtonIPad)(subtract)(int 1)(add)(int 1) - -# Esco -height - 1 - ButtonIPad - 1 - 1=(str height)(subtract)(int 1)(subtract)(str ButtonIPad)(subtract)(int 1)(subtract)(int 1) - -# Esco -height - 1 - ButtonIPad - 1 - 1 + 1=(str height)(subtract)(int 1)(subtract)(str ButtonIPad)(subtract)(int 1)(subtract)(int 1)(add)(int 1) - -# AgingGorilla, Gorilla -height - 10=(str height)(subtract)(int 10) - -# AgingGorilla, Gorilla -height - 12=(str height)(subtract)(int 12) - -# AgingGorilla, Gorilla -height - 14=(str height)(subtract)(int 14) - -# AgingGorilla, Aquarius, Carved2, Clearlooks, Clearlooks-2.0-blend, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop, Esco, Gorilla, Quiet-Environment-v2, Quiet-Graphite-v2, Quiet-Purple-2K6-v2, Redmond, River, Simple, SmoothGNOME -height - 2=(str height)(subtract)(int 2) - -# Esco, Gilouche, GiloucheIM, SmoothGNOME, TangoDance -height - 3=(str height)(subtract)(int 3) - -# Crux, Sandwish, SmoothGNOME -height - 4=(str height)(subtract)(int 4) - -# Atlanta, Bright, Simple -height - 5 - ButtonIPad=(str height)(subtract)(int 5)(subtract)(str ButtonIPad) - -# AgingGorilla, Esco, Gorilla -height - 7=(str height)(subtract)(int 7) - -# Metabox, Redmond, SmoothGNOME, Tetelestai-Modern -height - 7 - ButtonIPad=(str height)(subtract)(int 7)(subtract)(str ButtonIPad) - -# AgingGorilla, Gorilla -height - 8=(str height)(subtract)(int 8) - -# Carved2, Chiro, Metabox, Redmond, River, Simple, SmoothGNOME, Tetelestai-Modern, c2 -height - ButtonIPad=(str height)(subtract)(str ButtonIPad) - -# Carved2, Simple -height - ButtonIPad + 1=(str height)(subtract)(str ButtonIPad)(add)(int 1) - -# Esco -height - ButtonIPad - ((height - (ButtonIPad + 1) * 2) * 0.4)=(str height)(subtract)(str ButtonIPad)(subtract)( ( (str height)(subtract)( (str ButtonIPad)(add)(int 1) )(multiply)(int 2) )(multiply)(double 0.4) ) - -# Esco -height - ButtonIPad - ((height - (ButtonIPad + 1) * 2) * 0.4) - 1=(str height)(subtract)(str ButtonIPad)(subtract)( ( (str height)(subtract)( (str ButtonIPad)(add)(int 1) )(multiply)(int 2) )(multiply)(double 0.4) )(subtract)(int 1) - -# Atlanta, Carved2, Esco, Metabox, Redmond, SmoothGNOME, Tetelestai-Modern -height - ButtonIPad - 1=(str height)(subtract)(str ButtonIPad)(subtract)(int 1) - -# Esco -height - ButtonIPad - 1 + 1=(str height)(subtract)(str ButtonIPad)(subtract)(int 1)(add)(int 1) - -# Esco -height - ButtonIPad - 1 - 1=(str height)(subtract)(str ButtonIPad)(subtract)(int 1)(subtract)(int 1) - -# Esco -height - ButtonIPad - 1 - 1 + 1=(str height)(subtract)(str ButtonIPad)(subtract)(int 1)(subtract)(int 1)(add)(int 1) - -# Bright, Chiro, Esco, Redmond, River, SmoothGNOME, c2 -height - ButtonIPad - 2=(str height)(subtract)(str ButtonIPad)(subtract)(int 2) - -# Esco -height - ButtonIPad - 2 + 1=(str height)(subtract)(str ButtonIPad)(subtract)(int 2)(add)(int 1) - -# Esco -height - ButtonIPad - 3=(str height)(subtract)(str ButtonIPad)(subtract)(int 3) - -# Esco -height - ButtonIPad - 3 + 1=(str height)(subtract)(str ButtonIPad)(subtract)(int 3)(add)(int 1) - -# Esco -height - ButtonIPad - 3 - 4=(str height)(subtract)(str ButtonIPad)(subtract)(int 3)(subtract)(int 4) - -# Esco -height - ButtonIPad - 3 - 4 + 1=(str height)(subtract)(str ButtonIPad)(subtract)(int 3)(subtract)(int 4)(add)(int 1) - -# Esco -height - ButtonIPad - 3 - 5=(str height)(subtract)(str ButtonIPad)(subtract)(int 3)(subtract)(int 5) - -# Esco -height - ButtonIPad - 3 - 5 + 1=(str height)(subtract)(str ButtonIPad)(subtract)(int 3)(subtract)(int 5)(add)(int 1) - -# Metabox, Tetelestai-Modern -height - ButtonIPad - 4=(str height)(subtract)(str ButtonIPad)(subtract)(int 4) - -# Esco -height - ButtonIPad - 5=(str height)(subtract)(str ButtonIPad)(subtract)(int 5) - -# Esco -height - ButtonIPad - 5 + 1=(str height)(subtract)(str ButtonIPad)(subtract)(int 5)(add)(int 1) - -# Atlanta, Bright, Metabox, Redmond, SmoothGNOME, Tetelestai-Modern -height - ButtonIPad - ThickLineWidth + 1=(str height)(subtract)(str ButtonIPad)(subtract)(str ThickLineWidth)(add)(int 1) - -# Simple -height - ButtonIPad - ThickLineWidth + 3=(str height)(subtract)(str ButtonIPad)(subtract)(str ThickLineWidth)(add)(int 3) - -# Chiro, River, c2 -height - ButtonIPad-1=(str height)(subtract)(str ButtonIPad)(subtract)(int 1) - -# Quiet-Environment, Quiet-Graphite, Quiet-Human, Quiet-Purple-2K6 -height - height / 4=(str height)(subtract)(str height)(divide)(int 4) - -# Quiet-Environment-v2, Quiet-Graphite-v2, Quiet-Purple-2K6-v2 -height - height / 4 + 2=(str height)(subtract)(str height)(divide)(int 4)(add)(int 2) - -# Crux, Maemo, Sandwish -height - object_height=(str height)(subtract)(str object_height) - -# Esco -height - top_height - bottom_height + 1=(str height)(subtract)(str top_height)(subtract)(str bottom_height)(add)(int 1) - -# Esco -height - top_height - bottom_height - 1=(str height)(subtract)(str top_height)(subtract)(str bottom_height)(subtract)(int 1) - -# Aquarius, Clearlooks-2.0-blend, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop, TangoDance -height / 2=(str height)(divide)(int 2) - -# TangoDance -height / 2 - 1=(str height)(divide)(int 2)(subtract)(int 1) - -# TangoDance -height / 2 - 2=(str height)(divide)(int 2)(subtract)(int 2) - -# Aquarius, Clearlooks-2.0-blend, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop, TangoDance -height / 2 - 3=(str height)(divide)(int 2)(subtract)(int 3) - -# Aquarius, Clearlooks-2.0-blend, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop -height / 2 - 4=(str height)(divide)(int 2)(subtract)(int 4) - -# Quiet-Environment-v2, Quiet-Graphite-v2, Quiet-Purple-2K6-v2 -height / 3=(str height)(divide)(int 3) - -# Quiet-Environment, Quiet-Graphite, Quiet-Human, Quiet-Purple-2K6 -height / 4=(str height)(divide)(int 4) - -# Quiet-Environment-v2, Quiet-Graphite-v2, Quiet-Purple-2K6-v2 -height / 4 + 2=(str height)(divide)(int 4)(add)(int 2) - -# Outcrop -height /2=(str height)(divide)(int 2) - -# Outcrop -height /2 +1=(str height)(divide)(int 2)(add)(int 1) - -# Outcrop -height /2 +2=(str height)(divide)(int 2)(add)(int 2) - -# Outcrop -height /2 -1=(str height)(divide)(int 2)(subtract)(int 1) - -# Bentham -height `max` ((width-title_width)) / 2=(str height)(max)( ( (str width)(subtract)(str title_width) ) )(divide)(int 2) - -# Mista -height `min` object_height=(str height)(min)(str object_height) - -# Sloth -height+1=(str height)(add)(int 1) - -# Clearlooks, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop -height-((height-(Bmin`max`height-Bpad*2))/2)*2-1=(str height)(subtract)( ( (str height)(subtract)( (str Bmin)(max)(str height)(subtract)(str Bpad)(multiply)(int 2) ) )(divide)(int 2) )(multiply)(int 2)(subtract)(int 1) - -# Clearlooks, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop -height-((height-(Bmin`max`height-Bpad*2))/2)*2-3=(str height)(subtract)( ( (str height)(subtract)( (str Bmin)(max)(str height)(subtract)(str Bpad)(multiply)(int 2) ) )(divide)(int 2) )(multiply)(int 2)(subtract)(int 3) - -# 4DWM -height-(2 * right_width - 1)=(str height)(subtract)( (int 2)(multiply)(str right_width)(subtract)(int 1) ) - -# Chiro, c2 -height-(ButtonIPad+1)*2-1=(str height)(subtract)( (str ButtonIPad)(add)(int 1) )(multiply)(int 2)(subtract)(int 1) - -# 4DWM -height-(right_width-1)=(str height)(subtract)( (str right_width)(subtract)(int 1) ) - -# 4DWM -height-(right_width-2)=(str height)(subtract)( (str right_width)(subtract)(int 2) ) - -# 4DWM, Almond, Amiga, AmigaRelief, Aquarius, Atlanta, Bentham, Bright, Chiro, Clearbox-in, Clearbox-look-2, Clearbox-out, Clearlooks, Clearlooks-2.0-blend, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop, EasyListening, MWM, MetaGrip, Metabox, Outcrop, Quiet-Environment, Quiet-Environment-v2, Quiet-Graphite, Quiet-Graphite-v2, Quiet-Human, Quiet-Purple-2K6, Quiet-Purple-2K6-v2, Redmond, River, Simple, Simplebox, Sloth , SmoothGNOME, Tactile, Tetelestai-Modern, Vista Basic, W2k, boxx, c2, pOS -height-1=(str height)(subtract)(int 1) - -# pOS -height-11=(str height)(subtract)(int 11) - -# 4DWM, AmigaRelief, Aquarius, Atlanta, Bentham, Bright, Chiro, Clearbox-look-2, Clearlooks, Clearlooks-2.0-blend, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop, EasyListening, Gilouche, GiloucheIM, MWM, Metabox, Outcrop, River, Shiny, Shiny-Tango, Silverado, Simple, SmoothGNOME, Tactile, Tetelestai-Modern, Vista Basic, W2k, boxx, c2, pOS -height-2=(str height)(subtract)(int 2) - -# Shiny, Shiny-Tango -height-21=(str height)(subtract)(int 21) - -# Soft Squares, Tactile -height-23=(str height)(subtract)(int 23) - -# Maemo -height-25=(str height)(subtract)(int 25) - -# Maemo -height-26=(str height)(subtract)(int 26) - -# Maemo, Shiny, Shiny-Tango -height-29=(str height)(subtract)(int 29) - -# 4DWM, Aquarius, Bright, Carved2, Chiro, Clearbox-in, Clearbox-look-2, Clearbox-out, Clearlooks, Clearlooks-2.0-blend, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop, Gilouche, GiloucheIM, MWM, Outcrop, River, Simple, Simplebox, SmoothGNOME, Tactile, Tetelestai-Modern, W2k, c2 -height-3=(str height)(subtract)(int 3) - -# 4DWM, Amiga, AmigaRelief, Aquarius, Bright, Carved2, Chiro, Clearbox-look-2, Clearlooks, Clearlooks-2.0-blend, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop, Crux, Maemo, Outcrop, Quiet-Environment, Quiet-Environment-v2, Quiet-Graphite, Quiet-Graphite-v2, Quiet-Human, Quiet-Purple-2K6, Quiet-Purple-2K6-v2, River, Sandwish, SmoothGNOME, Tetelestai-Modern, W2k, c2, pOS -height-4=(str height)(subtract)(int 4) - -# 4DWM, Almond, Amiga, AmigaRelief, Aquarius, Carved2, Chiro, Clearbox-look-2, Clearlooks, Clearlooks-2.0-blend, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop, MWM, River, SmoothGNOME, Tetelestai-Modern, W2k, c2, pOS -height-5=(str height)(subtract)(int 5) - -# 4DWM, AmigaRelief, Clearlooks, Clearlooks-Pinstripe, Clearlooks-RedExit, EasyListening, MWM, pOS -height-6=(str height)(subtract)(int 6) - -# 4DWM, MWM, Shiny, Shiny-Tango, pOS -height-7=(str height)(subtract)(int 7) - -# 4DWM, pOS -height-8=(str height)(subtract)(int 8) - -# Almond, Outcrop, pOS -height-9=(str height)(subtract)(int 9) - -# Carved2 -height-ButtonIPad*2=(str height)(subtract)(str ButtonIPad)(multiply)(int 2) - -# Simple -height-ButtonIPad*2 + 1=(str height)(subtract)(str ButtonIPad)(multiply)(int 2)(add)(int 1) - -# Atlanta, Chiro, Metabox, Redmond, River, SmoothGNOME, Tetelestai-Modern, c2 -height-ButtonIPad*2-1=(str height)(subtract)(str ButtonIPad)(multiply)(int 2)(subtract)(int 1) - -# Bright -height-ButtonIPad*2-2=(str height)(subtract)(str ButtonIPad)(multiply)(int 2)(subtract)(int 2) - -# Chiro, River, c2 -height-ButtonIPad*2-5=(str height)(subtract)(str ButtonIPad)(multiply)(int 2)(subtract)(int 5) - -# Clearbox-look-2 -height-ButtonPad=(str height)(subtract)(str ButtonPad) - -# Clearbox-look-2 -height-ButtonPad*2+1=(str height)(subtract)(str ButtonPad)(multiply)(int 2)(add)(int 1) - -# Clearbox-look-2 -height-ButtonPad*2-2=(str height)(subtract)(str ButtonPad)(multiply)(int 2)(subtract)(int 2) - -# Clearbox-look-2 -height-ButtonPad+1=(str height)(subtract)(str ButtonPad)(add)(int 1) - -# Clearbox-look-2 -height-ButtonPad-1=(str height)(subtract)(str ButtonPad)(subtract)(int 1) - -# Clearbox-look-2 -height-ButtonPad-2=(str height)(subtract)(str ButtonPad)(subtract)(int 2) - -# Clearbox-look-2 -height-PrelightPad=(str height)(subtract)(str PrelightPad) - -# Clearbox-look-2 -height-PrelightPad*2+1=(str height)(subtract)(str PrelightPad)(multiply)(int 2)(add)(int 1) - -# Clearbox-look-2 -height-PrelightPad*2-2=(str height)(subtract)(str PrelightPad)(multiply)(int 2)(subtract)(int 2) - -# Clearbox-look-2 -height-PrelightPad+1=(str height)(subtract)(str PrelightPad)(add)(int 1) - -# Clearbox-look-2 -height-PrelightPad-1=(str height)(subtract)(str PrelightPad)(subtract)(int 1) - -# Clearbox-look-2 -height-PrelightPad-2=(str height)(subtract)(str PrelightPad)(subtract)(int 2) - -# Chiro, Gilouche, GiloucheIM, SmoothGNOME, Tetelestai-Modern -height-bottom_height=(str height)(subtract)(str bottom_height) - -# Carved2 -height-bottom_height + 1=(str height)(subtract)(str bottom_height)(add)(int 1) - -# Carved2 -height-bottom_height + 2=(str height)(subtract)(str bottom_height)(add)(int 2) - -# 4DWM, MWM -height-bottom_height+1=(str height)(subtract)(str bottom_height)(add)(int 1) - -# Gilouche, GiloucheIM -height-bottom_height-top_height=(str height)(subtract)(str bottom_height)(subtract)(str top_height) - -# 4DWM -height-bottom_height/2=(str height)(subtract)(str bottom_height)(divide)(int 2) - -# Mista -height-object_height=(str height)(subtract)(str object_height) - -# 4DWM, MWM -height-right_width=(str height)(subtract)(str right_width) - -# MWM -height-right_width-1=(str height)(subtract)(str right_width)(subtract)(int 1) - -# c2 -height-title_height=(str height)(subtract)(str title_height) - -# Chiro, SmoothGNOME -height-title_height-38=(str height)(subtract)(str title_height)(subtract)(int 38) - -# Amiga, AmigaRelief, c2, pOS -height-title_height-6=(str height)(subtract)(str title_height)(subtract)(int 6) - -# 4DWM, MWM -height-top_height=(str height)(subtract)(str top_height) - -# 4DWM -height-top_height+1=(str height)(subtract)(str top_height)(add)(int 1) - -# 4DWM, MWM, Tactile -height-top_height-1=(str height)(subtract)(str top_height)(subtract)(int 1) - -# 4DWM -height-top_height-2=(str height)(subtract)(str top_height)(subtract)(int 2) - -# Atlanta, Bright, Metabox, Simple, SmoothGNOME, TangoDance, Tetelestai-Modern -height-top_height-bottom_height+1=(str height)(subtract)(str top_height)(subtract)(str bottom_height)(add)(int 1) - -# Sloth -height/1.5=(str height)(divide)(double 1.5) - -# 4DWM, Aquarius, Bentham, Clearbox-in, Clearbox-out, MWM, Simplebox, Sloth , Tetelestai-Modern -height/2=(str height)(divide)(int 2) - -# Bentham -height/2 + height/4 - 1=(str height)(divide)(int 2)(add)(str height)(divide)(int 4)(subtract)(int 1) - -# Bentham -height/2 + height/4 - 2=(str height)(divide)(int 2)(add)(str height)(divide)(int 4)(subtract)(int 2) - -# Bentham -height/2 - height/4=(str height)(divide)(int 2)(subtract)(str height)(divide)(int 4) - -# Bentham -height/2 - height/4 + 1=(str height)(divide)(int 2)(subtract)(str height)(divide)(int 4)(add)(int 1) - -# Quiet-Environment, Quiet-Environment-v2, Quiet-Graphite, Quiet-Graphite-v2, Quiet-Human, Quiet-Purple-2K6, Quiet-Purple-2K6-v2 -height/2 - width/2=(str height)(divide)(int 2)(subtract)(str width)(divide)(int 2) - -# Amiga, AmigaRelief -height/2 - width/2 + 2=(str height)(divide)(int 2)(subtract)(str width)(divide)(int 2)(add)(int 2) - -# Clearbox-look-2 -height/2+(height-ButtonPad)/6+1=(str height)(divide)(int 2)(add)( (str height)(subtract)(str ButtonPad) )(divide)(int 6)(add)(int 1) - -# Clearbox-look-2 -height/2+(height-PrelightPad)/6+1=(str height)(divide)(int 2)(add)( (str height)(subtract)(str PrelightPad) )(divide)(int 6)(add)(int 1) - -# 4DWM, Aquarius, Clearbox-in, Clearbox-out, Simplebox -height/2+1=(str height)(divide)(int 2)(add)(int 1) - -# 4DWM, Clearbox-in, Clearbox-out, MWM, Simplebox -height/2+2=(str height)(divide)(int 2)(add)(int 2) - -# 4DWM, Clearbox-in, Clearbox-out, Simplebox -height/2+3=(str height)(divide)(int 2)(add)(int 3) - -# Clearbox-in, Clearbox-out, Simplebox -height/2+4=(str height)(divide)(int 2)(add)(int 4) - -# Clearbox-in, Clearbox-out, Simplebox -height/2+5=(str height)(divide)(int 2)(add)(int 5) - -# Clearbox-in, Clearbox-out, Simplebox -height/2+6=(str height)(divide)(int 2)(add)(int 6) - -# Aquarius -height/2+height/4=(str height)(divide)(int 2)(add)(str height)(divide)(int 4) - -# Aquarius -height/2+height/4-1=(str height)(divide)(int 2)(add)(str height)(divide)(int 4)(subtract)(int 1) - -# Clearbox-in, Clearbox-out, MWM, Simplebox -height/2-1=(str height)(divide)(int 2)(subtract)(int 1) - -# 4DWM, Aquarius, Clearbox-in, Clearbox-out, Simplebox -height/2-2=(str height)(divide)(int 2)(subtract)(int 2) - -# Clearbox-in, Clearbox-out, Outcrop, Simplebox -height/2-3=(str height)(divide)(int 2)(subtract)(int 3) - -# Clearbox-in, Clearbox-out, Outcrop, Simplebox -height/2-4=(str height)(divide)(int 2)(subtract)(int 4) - -# Clearbox-in, Clearbox-out, Simplebox -height/2-5=(str height)(divide)(int 2)(subtract)(int 5) - -# Aquarius -height/2-5+(2`max`height/8)=(str height)(divide)(int 2)(subtract)(int 5)(add)( (int 2)(max)(str height)(divide)(int 8) ) - -# Aquarius -height/2-height/4=(str height)(divide)(int 2)(subtract)(str height)(divide)(int 4) - -# Aquarius -height/2-height/4+1=(str height)(divide)(int 2)(subtract)(str height)(divide)(int 4)(add)(int 1) - -# Aquarius -height/2-height/4+2=(str height)(divide)(int 2)(subtract)(str height)(divide)(int 4)(add)(int 2) - -# Aquarius -height/2-height/6+1=(str height)(divide)(int 2)(subtract)(str height)(divide)(int 6)(add)(int 1) - -# Aquarius -height/2-height/6+2=(str height)(divide)(int 2)(subtract)(str height)(divide)(int 6)(add)(int 2) - -# Bentham -height/2-height/8-1=(str height)(divide)(int 2)(subtract)(str height)(divide)(int 8)(subtract)(int 1) - -# Bentham -height/2-height/8-2=(str height)(divide)(int 2)(subtract)(str height)(divide)(int 8)(subtract)(int 2) - -# Aquarius -height/3+1=(str height)(divide)(int 3)(add)(int 1) - -# Aquarius -height/3-1=(str height)(divide)(int 3)(subtract)(int 1) - -# Aquarius -height/3-3=(str height)(divide)(int 3)(subtract)(int 3) - -# Bentham -height/4=(str height)(divide)(int 4) - -# Bentham -height/4+2=(str height)(divide)(int 4)(add)(int 2) - -# 4DWM, Esco, Gilouche, GiloucheIM, MWM, Silverado -left_width=(str left_width) - -# Esco -left_width - 1=(str left_width)(subtract)(int 1) - -# 4DWM, Atlanta, Bright, Chiro, Gilouche, GiloucheIM, MWM, Metabox, Simple, SmoothGNOME, TangoDance, Tetelestai-Modern -left_width-1=(str left_width)(subtract)(int 1) - -# 4DWM, Tetelestai-Modern -left_width-2=(str left_width)(subtract)(int 2) - -# 4DWM -left_width-3=(str left_width)(subtract)(int 3) - -# Aquarius, Atlanta, Clearlooks-2.0-blend, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop, Esco, Firey 1.0, Firey Dark, Gilouche, GiloucheIM, Metabox, Mista, Outcrop, Silverado, TangoDance, Vista Basic, W2k -mini_icon_height=(str mini_icon_height) - -# Bright -mini_icon_height-1=(str mini_icon_height)(subtract)(int 1) - -# Aquarius, Atlanta, Clearlooks-2.0-blend, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop, Esco, Firey 1.0, Firey Dark, Gilouche, GiloucheIM, Metabox, Mista, Outcrop, Silverado, Sloth , TangoDance, Vista Basic, W2k -mini_icon_width=(str mini_icon_width) - -# Esco -mini_icon_width + IconTitleSpacing=(str mini_icon_width)(add)(str IconTitleSpacing) - -# Bright -mini_icon_width-1=(str mini_icon_width)(subtract)(int 1) - -# Agata, AgingGorilla, Alphacube 0.9b Metacity Color, Alphacube 0.9b Metacity Light, Alphacube 0.9b Metacity Simple, Black, Correcamins, Crux, Firey 1.0, Firey Dark, Gorilla, Graphite, Maemo, Mista, Quiet-Environment, Quiet-Environment-v2, Quiet-Graphite, Quiet-Graphite-v2, Quiet-Human, Quiet-Purple-2K6, Quiet-Purple-2K6-v2, Sandwish, Soft Squares, Tactile, ThinMC, Vista Basic, boxx, sky, sky-blue -object_height=(str object_height) - -# Maemo -object_height+2=(str object_height)(add)(int 2) - -# Agata, AgingGorilla, Alphacube 0.9b Metacity Color, Alphacube 0.9b Metacity Light, Alphacube 0.9b Metacity Simple, Black, Correcamins, Crux, Firey 1.0, Firey Dark, Gorilla, Graphite, Maemo, Mista, Quiet-Environment, Quiet-Environment-v2, Quiet-Graphite, Quiet-Graphite-v2, Quiet-Human, Quiet-Purple-2K6, Quiet-Purple-2K6-v2, Sandwish, Silverado, Soft Squares, Tactile, ThinMC, Vista Basic, W2k, sky, sky-blue -object_width=(str object_width) - -# Crux -object_width * height / 22=(str object_width)(multiply)(str height)(divide)(int 22) - -# Maemo -object_width+2=(str object_width)(add)(int 2) - -# 4DWM, MWM, Silverado -right_width=(str right_width) - -# 4DWM, MWM -right_width-1=(str right_width)(subtract)(int 1) - -# 4DWM, Tetelestai-Modern -right_width-2=(str right_width)(subtract)(int 2) - -# 4DWM -right_width-3=(str right_width)(subtract)(int 3) - -# 4DWM -right_width-4=(str right_width)(subtract)(int 4) - -# Gilouche, GiloucheIM -title_height + 10=(str title_height)(add)(int 10) - -# TangoDance -title_height + 12=(str title_height)(add)(int 12) - -# Clearlooks, Clearlooks-Pinstripe, River -title_height + 3=(str title_height)(add)(int 3) - -# Chiro, SmoothGNOME -title_height + 38=(str title_height)(add)(int 38) - -# Chiro, Gilouche, GiloucheIM, River, SmoothGNOME, TangoDance, c2 -title_height + 4=(str title_height)(add)(int 4) - -# Chiro, Clearlooks, Clearlooks-Pinstripe, Gilouche, GiloucheIM, River, SmoothGNOME, TangoDance, c2 -title_height + 5=(str title_height)(add)(int 5) - -# Clearlooks, Clearlooks-Pinstripe, SmoothGNOME, c2 -title_height + 6=(str title_height)(add)(int 6) - -# TangoDance -title_height + 9=(str title_height)(add)(int 9) - -# Outcrop -title_height +8=(str title_height)(add)(int 8) - -# Outcrop -title_height -7=(str title_height)(subtract)(int 7) - -# TangoDance -title_height / 2 - 5=(str title_height)(divide)(int 2)(subtract)(int 5) - -# Outcrop -title_height /1.5=(str title_height)(divide)(double 1.5) - -# Outcrop -title_height /2=(str title_height)(divide)(int 2) - -# Outcrop -title_height /4=(str title_height)(divide)(int 4) - -# 4DWM -title_height*2/3=(str title_height)(multiply)(int 2)(divide)(int 3) - -# AmigaRelief, pOS -title_height+3=(str title_height)(add)(int 3) - -# Amiga, AmigaRelief, Clearbox-look-2, pOS -title_height+4=(str title_height)(add)(int 4) - -# Amiga, AmigaRelief, pOS -title_height+5=(str title_height)(add)(int 5) - -# Chiro, Outcrop, SmoothGNOME, c2 -title_height+6=(str title_height)(add)(int 6) - -# Outcrop -title_height+7=(str title_height)(add)(int 7) - -# Outcrop -title_height+8=(str title_height)(add)(int 8) - -# sky, sky-blue -title_width + 16 `min` width - 14=(str title_width)(add)(int 16)(min)(str width)(subtract)(int 14) - -# sky, sky-blue -title_width + 21 `min` width - object_width=(str title_width)(add)(int 21)(min)(str width)(subtract)(str object_width) - -# sky, sky-blue -title_width + 6=(str title_width)(add)(int 6) - -# Esco -title_width + mini_icon_width + IconTitleSpacing * 3 - 1=(str title_width)(add)(str mini_icon_width)(add)(str IconTitleSpacing)(multiply)(int 3)(subtract)(int 1) - -# boxx -title_width+15=(str title_width)(add)(int 15) - -# Maemo -title_width+181=(str title_width)(add)(int 181) - -# Sandwish -title_width+20=(str title_width)(add)(int 20) - -# Maemo -title_width+32=(str title_width)(add)(int 32) - -# Maemo -title_width+32+149=(str title_width)(add)(int 32)(add)(int 149) - -# boxx -title_width-2=(str title_width)(subtract)(int 2) - -# Sandwish -title_width/2+150=(str title_width)(divide)(int 2)(add)(int 150) - -# 4DWM, Chiro, Clearbox-in, Clearbox-out, Esco, MWM, Simplebox -top_height=(str top_height) - -# Clearlooks-RedExit, Esco -top_height - 1=(str top_height)(subtract)(int 1) - -# Clearlooks-RedExit -top_height - 16=(str top_height)(subtract)(int 16) - -# Clearlooks-RedExit -top_height - 2=(str top_height)(subtract)(int 2) - -# Clearlooks-2.0-blend, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop -top_height / 2=(str top_height)(divide)(int 2) - -# Aquarius -top_height*2/5=(str top_height)(multiply)(int 2)(divide)(int 5) - -# Aquarius -top_height*3/10=(str top_height)(multiply)(int 3)(divide)(int 10) - -# Aquarius -top_height*3/5=(str top_height)(multiply)(int 3)(divide)(int 5) - -# Aquarius -top_height*4/5=(str top_height)(multiply)(int 4)(divide)(int 5) - -# Aquarius -top_height*7/10=(str top_height)(multiply)(int 7)(divide)(int 10) - -# Aquarius -top_height*9/10=(str top_height)(multiply)(int 9)(divide)(int 10) - -# 4DWM -top_height+1=(str top_height)(add)(int 1) - -# 4DWM, Aquarius, Atlanta, Bright, Clearlooks-2.0-blend, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop, Gilouche, GiloucheIM, MWM, Metabox, Simple, SmoothGNOME, Tactile, TangoDance, Tetelestai-Modern -top_height-1=(str top_height)(subtract)(int 1) - -# 4DWM, Aquarius, Clearlooks-2.0-blend, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop -top_height-2=(str top_height)(subtract)(int 2) - -# 4DWM -top_height-3=(str top_height)(subtract)(int 3) - -# Aquarius -top_height/10=(str top_height)(divide)(int 10) - -# Aquarius -top_height/10+1=(str top_height)(divide)(int 10)(add)(int 1) - -# Aquarius -top_height/2=(str top_height)(divide)(int 2) - -# Aquarius -top_height/5=(str top_height)(divide)(int 5) - -# 4DWM, Agata, AgingGorilla, Almond, Alphacube 0.9b Metacity Color, Alphacube 0.9b Metacity Light, Alphacube 0.9b Metacity Simple, Amiga, AmigaRelief, Aquarius, Atlanta, Bentham, Black, Bright, Carved2, Chiro, Clearbox-in, Clearbox-look-2, Clearbox-out, Clearlooks, Clearlooks-2.0-blend, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop, Correcamins, Crux, EasyListening, Esco, Firey 1.0, Firey Dark, Gilouche, GiloucheIM, Gorilla, Graphite, MWM, MetaGrip, Metabox, Mista, Outcrop, Quiet-Environment, Quiet-Environment-v2, Quiet-Graphite, Quiet-Graphite-v2, Quiet-Human, Quiet-Purple-2K6, Quiet-Purple-2K6-v2, Redmond, River, Sandwish, Shiny, Shiny-Tango, Silverado, Simple, Simplebox, SmoothGNOME, TangoDance, Tetelestai-Modern, ThinMC, Vista Basic, W2k, boxx, c2, pOS, sky, sky-blue -width=(str width) - -# Clearlooks, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop -width - ((width-(Bmin`max`height-Bpad*2))/2)=(str width)(subtract)( ( (str width)(subtract)( (str Bmin)(max)(str height)(subtract)(str Bpad)(multiply)(int 2) ) )(divide)(int 2) ) - -# Clearlooks, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop -width - ((width-(Bmin`max`height-Bpad*2))/2) - 1=(str width)(subtract)( ( (str width)(subtract)( (str Bmin)(max)(str height)(subtract)(str Bpad)(multiply)(int 2) ) )(divide)(int 2) )(subtract)(int 1) - -# Esco -width - (ButtonIPad + 1) * 2=(str width)(subtract)( (str ButtonIPad)(add)(int 1) )(multiply)(int 2) - -# sky, sky-blue -width - 0=(str width)(subtract)(int 0) - -# AgingGorilla, Aquarius, Carved2, Clearlooks, Clearlooks-2.0-blend, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop, Esco, Gilouche, GiloucheIM, Gorilla, Quiet-Environment, Quiet-Environment-v2, Quiet-Graphite, Quiet-Graphite-v2, Quiet-Human, Quiet-Purple-2K6, Quiet-Purple-2K6-v2, Redmond, River, Simple, SmoothGNOME, Soft Squares, TangoDance -width - 1=(str width)(subtract)(int 1) - -# Esco -width - 1 - ButtonIPad=(str width)(subtract)(int 1)(subtract)(str ButtonIPad) - -# Esco -width - 1 - ButtonIPad + 1=(str width)(subtract)(int 1)(subtract)(str ButtonIPad)(add)(int 1) - -# Esco -width - 1 - ButtonIPad - 1=(str width)(subtract)(int 1)(subtract)(str ButtonIPad)(subtract)(int 1) - -# Esco -width - 1 - ButtonIPad - 1 + 1=(str width)(subtract)(int 1)(subtract)(str ButtonIPad)(subtract)(int 1)(add)(int 1) - -# Agata, Black, Correcamins -width - 10=(str width)(subtract)(int 10) - -# AgingGorilla, Gorilla -width - 11=(str width)(subtract)(int 11) - -# AgingGorilla, Almond, Gorilla, Graphite, sky, sky-blue -width - 12=(str width)(subtract)(int 12) - -# AgingGorilla, Gorilla -width - 13=(str width)(subtract)(int 13) - -# AgingGorilla, Gorilla -width - 16=(str width)(subtract)(int 16) - -# AgingGorilla, Aquarius, Clearlooks, Clearlooks-2.0-blend, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop, Esco, Gilouche, GiloucheIM, Gorilla, Quiet-Environment-v2, Quiet-Graphite-v2, Quiet-Purple-2K6-v2, Redmond, River, Simple, SmoothGNOME, Soft Squares, TangoDance, ThinMC -width - 2=(str width)(subtract)(int 2) - -# Alphacube 0.9b Metacity Color, Alphacube 0.9b Metacity Light, Alphacube 0.9b Metacity Simple -width - 20=(str width)(subtract)(int 20) - -# Almond -width - 24=(str width)(subtract)(int 24) - -# Graphite, sky, sky-blue -width - 27=(str width)(subtract)(int 27) - -# Carved2, Clearlooks, Clearlooks-Pinstripe, Clearlooks-RedExit, Gilouche, GiloucheIM, SmoothGNOME, TangoDance -width - 3=(str width)(subtract)(int 3) - -# Aquarius, Carved2, Clearlooks, Clearlooks-2.0-blend, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop, Crux, Firey 1.0, Firey Dark, Gilouche, GiloucheIM, Quiet-Environment-v2, Quiet-Graphite-v2, Quiet-Purple-2K6-v2, River, Sandwish, SmoothGNOME, Tactile, TangoDance -width - 4=(str width)(subtract)(int 4) - -# Gilouche, GiloucheIM -width - 5=(str width)(subtract)(int 5) - -# Atlanta, Bright, Simple -width - 5 - ButtonIPad=(str width)(subtract)(int 5)(subtract)(str ButtonIPad) - -# Firey 1.0, Firey Dark, Tactile -width - 6=(str width)(subtract)(int 6) - -# Agata, Alphacube 0.9b Metacity Color, Alphacube 0.9b Metacity Light, Alphacube 0.9b Metacity Simple, Esco -width - 7=(str width)(subtract)(int 7) - -# Metabox, Redmond, SmoothGNOME, Tetelestai-Modern -width - 7 - ButtonIPad=(str width)(subtract)(int 7)(subtract)(str ButtonIPad) - -# AgingGorilla, Gorilla -width - 8=(str width)(subtract)(int 8) - -# AgingGorilla, Gorilla -width - 9=(str width)(subtract)(int 9) - -# Atlanta, Metabox, Redmond, SmoothGNOME, Tetelestai-Modern -width - ButtonIPad=(str width)(subtract)(str ButtonIPad) - -# Simple -width - ButtonIPad + 1=(str width)(subtract)(str ButtonIPad)(add)(int 1) - -# Atlanta, Esco, Redmond, SmoothGNOME, Tetelestai-Modern -width - ButtonIPad - 1=(str width)(subtract)(str ButtonIPad)(subtract)(int 1) - -# Esco -width - ButtonIPad - 1 + 1=(str width)(subtract)(str ButtonIPad)(subtract)(int 1)(add)(int 1) - -# Esco -width - ButtonIPad - 1 - 1=(str width)(subtract)(str ButtonIPad)(subtract)(int 1)(subtract)(int 1) - -# Esco -width - ButtonIPad - 1 - 1 + 1=(str width)(subtract)(str ButtonIPad)(subtract)(int 1)(subtract)(int 1)(add)(int 1) - -# Bright, Esco -width - ButtonIPad - 2=(str width)(subtract)(str ButtonIPad)(subtract)(int 2) - -# Esco -width - ButtonIPad - 2 + 1=(str width)(subtract)(str ButtonIPad)(subtract)(int 2)(add)(int 1) - -# Esco, Metabox, Tetelestai-Modern -width - ButtonIPad - 4=(str width)(subtract)(str ButtonIPad)(subtract)(int 4) - -# Esco -width - ButtonIPad - 4 + 1=(str width)(subtract)(str ButtonIPad)(subtract)(int 4)(add)(int 1) - -# Esco -width - ButtonIPad - 5=(str width)(subtract)(str ButtonIPad)(subtract)(int 5) - -# Esco -width - ButtonIPad - 5 + 1=(str width)(subtract)(str ButtonIPad)(subtract)(int 5)(add)(int 1) - -# Tetelestai-Modern -width - ButtonIPad -2=(str width)(subtract)(str ButtonIPad)(subtract)(int 2) - -# Bright -width - ButtonIPad-1=(str width)(subtract)(str ButtonIPad)(subtract)(int 1) - -# Carved2 -width - ResizerWidth - 1=(str width)(subtract)(str ResizerWidth)(subtract)(int 1) - -# Carved2 -width - ResizerWidth - 2=(str width)(subtract)(str ResizerWidth)(subtract)(int 2) - -# Esco -width - left_width - right_width + 1=(str width)(subtract)(str left_width)(subtract)(str right_width)(add)(int 1) - -# Esco -width - left_width - right_width - 1=(str width)(subtract)(str left_width)(subtract)(str right_width)(subtract)(int 1) - -# Esco -width - mini_icon_width - IconTitleSpacing=(str width)(subtract)(str mini_icon_width)(subtract)(str IconTitleSpacing) - -# Agata, Alphacube 0.9b Metacity Color, Alphacube 0.9b Metacity Light, Alphacube 0.9b Metacity Simple, Black, Correcamins, Crux, Firey 1.0, Firey Dark, Graphite, Maemo, Sandwish, Silverado, Tactile, sky, sky-blue -width - object_width=(str width)(subtract)(str object_width) - -# Esco -width - title_width - IconTitleSpacing=(str width)(subtract)(str title_width)(subtract)(str IconTitleSpacing) - -# Esco -width - title_width - IconTitleSpacing + 25 + 3=(str width)(subtract)(str title_width)(subtract)(str IconTitleSpacing)(add)(int 25)(add)(int 3) - -# Esco -width - title_width - IconTitleSpacing + 25 - 1 + 3=(str width)(subtract)(str title_width)(subtract)(str IconTitleSpacing)(add)(int 25)(subtract)(int 1)(add)(int 3) - -# Esco -width - title_width - IconTitleSpacing - height - 25 + 3=(str width)(subtract)(str title_width)(subtract)(str IconTitleSpacing)(subtract)(str height)(subtract)(int 25)(add)(int 3) - -# Esco -width - title_width - IconTitleSpacing - height - 25 - 1 + 3=(str width)(subtract)(str title_width)(subtract)(str IconTitleSpacing)(subtract)(str height)(subtract)(int 25)(subtract)(int 1)(add)(int 3) - -# Esco -width - title_width - height - (IconTitleSpacing * 2)=(str width)(subtract)(str title_width)(subtract)(str height)(subtract)( (str IconTitleSpacing)(multiply)(int 2) ) - -# Esco -width - title_width - mini_icon_width - (IconTitleSpacing * 2)=(str width)(subtract)(str title_width)(subtract)(str mini_icon_width)(subtract)( (str IconTitleSpacing)(multiply)(int 2) ) - -# Esco -width - title_width - mini_icon_width - IconTitleSpacing * 3=(str width)(subtract)(str title_width)(subtract)(str mini_icon_width)(subtract)(str IconTitleSpacing)(multiply)(int 3) - -# Esco -width - title_width - mini_icon_width - IconTitleSpacing * 3 - 18=(str width)(subtract)(str title_width)(subtract)(str mini_icon_width)(subtract)(str IconTitleSpacing)(multiply)(int 3)(subtract)(int 18) - -# Outcrop -width -(width /3.6)=(str width)(subtract)( (str width)(divide)(double 3.6) ) - -# Outcrop -width -(width /3.6) +1=(str width)(subtract)( (str width)(divide)(double 3.6) )(add)(int 1) - -# Outcrop -width -(width /3.6) +2=(str width)(subtract)( (str width)(divide)(double 3.6) )(add)(int 2) - -# Outcrop -width -(width /3.6) -1=(str width)(subtract)( (str width)(divide)(double 3.6) )(subtract)(int 1) - -# Alphacube 0.9b Metacity Color, Alphacube 0.9b Metacity Light, Alphacube 0.9b Metacity Simple -width -7=(str width)(subtract)(int 7) - -# Carved2 -width / 2=(str width)(divide)(int 2) - -# Outcrop -width / 3.4=(str width)(divide)(double 3.4) - -# Outcrop -width / 3.4 -1=(str width)(divide)(double 3.4)(subtract)(int 1) - -# Outcrop -width /2=(str width)(divide)(int 2) - -# Outcrop -width /2+1=(str width)(divide)(int 2)(add)(int 1) - -# Outcrop -width /2-1=(str width)(divide)(int 2)(subtract)(int 1) - -# Outcrop -width /2-2=(str width)(divide)(int 2)(subtract)(int 2) - -# Outcrop -width /3.4 +1=(str width)(divide)(double 3.4)(add)(int 1) - -# Outcrop -width /3.4 +2=(str width)(divide)(double 3.4)(add)(int 2) - -# Mista -width `min` object_width=(str width)(min)(str object_width) - -# Atlanta, Bright -width+1-SpacerWidth/2=(str width)(add)(int 1)(subtract)(str SpacerWidth)(divide)(int 2) - -# Vista Basic -width+2=(str width)(add)(int 2) - -# Clearlooks, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop -width- ((width-(Bmin`max`height-Bpad*2))/2)=(str width)(subtract)( ( (str width)(subtract)( (str Bmin)(max)(str height)(subtract)(str Bpad)(multiply)(int 2) ) )(divide)(int 2) ) - -# Clearlooks, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop -width-((width-(Bmin`max`height-Bpad*2))/2)=(str width)(subtract)( ( (str width)(subtract)( (str Bmin)(max)(str height)(subtract)(str Bpad)(multiply)(int 2) ) )(divide)(int 2) ) - -# Clearlooks, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop -width-((width-(Bmin`max`height-Bpad*2))/2) - 2=(str width)(subtract)( ( (str width)(subtract)( (str Bmin)(max)(str height)(subtract)(str Bpad)(multiply)(int 2) ) )(divide)(int 2) )(subtract)(int 2) - -# Clearlooks, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop -width-((width-(Bmin`max`height-Bpad*2))/2)*2=(str width)(subtract)( ( (str width)(subtract)( (str Bmin)(max)(str height)(subtract)(str Bpad)(multiply)(int 2) ) )(divide)(int 2) )(multiply)(int 2) - -# Clearlooks, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop -width-((width-(Bmin`max`height-Bpad*2))/2)*2-1=(str width)(subtract)( ( (str width)(subtract)( (str Bmin)(max)(str height)(subtract)(str Bpad)(multiply)(int 2) ) )(divide)(int 2) )(multiply)(int 2)(subtract)(int 1) - -# Clearlooks, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop -width-((width-(Bmin`max`height-Bpad*2))/2)*2-3=(str width)(subtract)( ( (str width)(subtract)( (str Bmin)(max)(str height)(subtract)(str Bpad)(multiply)(int 2) ) )(divide)(int 2) )(multiply)(int 2)(subtract)(int 3) - -# Clearlooks, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop -width-((width-(Bmin`max`height-Bpad*2))/2)-1=(str width)(subtract)( ( (str width)(subtract)( (str Bmin)(max)(str height)(subtract)(str Bpad)(multiply)(int 2) ) )(divide)(int 2) )(subtract)(int 1) - -# Chiro, c2 -width-(ButtonIPad+1)=(str width)(subtract)( (str ButtonIPad)(add)(int 1) ) - -# Chiro, c2 -width-(ButtonIPad+1)*2-1=(str width)(subtract)( (str ButtonIPad)(add)(int 1) )(multiply)(int 2)(subtract)(int 1) - -# Mista -width-(TitlebarPad*2)=(str width)(subtract)( (str TitlebarPad)(multiply)(int 2) ) - -# 4DWM -width-(left_width+right_width - 1)=(str width)(subtract)( (str left_width)(add)(str right_width)(subtract)(int 1) ) - -# 4DWM -width-(right_width-1)=(str width)(subtract)( (str right_width)(subtract)(int 1) ) - -# 4DWM -width-(right_width-2)=(str width)(subtract)( (str right_width)(subtract)(int 2) ) - -# Maemo -width-(title_width+80)=(str width)(subtract)( (str title_width)(add)(int 80) ) - -# Maemo -width-(title_width+88+8)=(str width)(subtract)( (str title_width)(add)(int 88)(add)(int 8) ) - -# Metabox -width-(width-ButtonIPad)/2-1=(str width)(subtract)( (str width)(subtract)(str ButtonIPad) )(divide)(int 2)(subtract)(int 1) - -# sky, sky-blue -width-0=(str width)(subtract)(int 0) - -# 4DWM, Almond, Amiga, AmigaRelief, Aquarius, Atlanta, Bentham, Bright, Carved2, Chiro, Clearbox-in, Clearbox-look-2, Clearbox-out, Clearlooks, Clearlooks-2.0-blend, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop, EasyListening, MWM, Maemo, MetaGrip, Metabox, Outcrop, Quiet-Environment, Quiet-Environment-v2, Quiet-Graphite, Quiet-Graphite-v2, Quiet-Human, Quiet-Purple-2K6, Quiet-Purple-2K6-v2, Redmond, River, Shiny, Shiny-Tango, Simple, Simplebox, Sloth , SmoothGNOME, Soft Squares, Tactile, Tetelestai-Modern, Vista Basic, W2k, boxx, c2, pOS -width-1=(str width)(subtract)(int 1) - -# 4DWM, Almond, Outcrop, Shiny, Shiny-Tango -width-10=(str width)(subtract)(int 10) - -# Graphite -width-12=(str width)(subtract)(int 12) - -# Almond, Outcrop, pOS -width-15=(str width)(subtract)(int 15) - -# 4DWM, Almond, Amiga, AmigaRelief, Aquarius, Atlanta, Bentham, Bright, Carved2, Chiro, Clearbox-look-2, Clearlooks, Clearlooks-2.0-blend, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop, EasyListening, Gilouche, GiloucheIM, MWM, MetaGrip, Metabox, Outcrop, Quiet-Environment, Quiet-Environment-v2, Quiet-Graphite, Quiet-Graphite-v2, Quiet-Human, Quiet-Purple-2K6, Quiet-Purple-2K6-v2, River, Shiny, Shiny-Tango, Silverado, Simple, SmoothGNOME, Tactile, Tetelestai-Modern, Vista Basic, W2k, boxx, c2, pOS -width-2=(str width)(subtract)(int 2) - -# 4DWM, Aquarius, Bright, Carved2, Chiro, Clearbox-in, Clearbox-look-2, Clearbox-out, Clearlooks, Clearlooks-2.0-blend, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop, Gilouche, GiloucheIM, Maemo, Outcrop, River, Simple, Simplebox, SmoothGNOME, Tetelestai-Modern, Vista Basic, W2k, c2 -width-3=(str width)(subtract)(int 3) - -# 4DWM, Almond, Amiga, AmigaRelief, Aquarius, Carved2, Chiro, Clearlooks, Clearlooks-2.0-blend, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop, Crux, Maemo, MetaGrip, Outcrop, River, Sandwish, Shiny, Shiny-Tango, SmoothGNOME, Tactile, Tetelestai-Modern, Vista Basic, boxx, c2, pOS -width-4=(str width)(subtract)(int 4) - -# 4DWM, Amiga, AmigaRelief, Aquarius, Bright, Chiro, Clearbox-look-2, Clearlooks, Clearlooks-2.0-blend, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop, EasyListening, MWM, River, Shiny-Tango, Sloth , SmoothGNOME, boxx, c2, pOS -width-5=(str width)(subtract)(int 5) - -# 4DWM, Aquarius, Clearlooks, Clearlooks-2.0-blend, Clearlooks-Pinstripe, Clearlooks-RedExit, Clearlooks2-Squared, Clearlooks2-Squared-Berries, ClearlooksWithACherryOnTop, EasyListening, MWM, MetaGrip, Shiny, Shiny-Tango, Vista Basic, W2k -width-6=(str width)(subtract)(int 6) - -# 4DWM, MWM, MetaGrip, Outcrop, Shiny, Shiny-Tango, pOS -width-7=(str width)(subtract)(int 7) - -# Maemo -width-70=(str width)(subtract)(int 70) - -# Maemo -width-72=(str width)(subtract)(int 72) - -# Almond, Outcrop, W2k, pOS -width-8=(str width)(subtract)(int 8) - -# 4DWM, Almond, Maemo, Outcrop, pOS -width-9=(str width)(subtract)(int 9) - -# Atlanta, Carved2, Chiro, Metabox, Redmond, River, SmoothGNOME, Tetelestai-Modern, c2 -width-ButtonIPad=(str width)(subtract)(str ButtonIPad) - -# Carved2 -width-ButtonIPad + 1=(str width)(subtract)(str ButtonIPad)(add)(int 1) - -# Simple -width-ButtonIPad + 2=(str width)(subtract)(str ButtonIPad)(add)(int 2) - -# Chiro, River, c2 -width-ButtonIPad - 3=(str width)(subtract)(str ButtonIPad)(subtract)(int 3) - -# Carved2, Chiro, River, c2 -width-ButtonIPad*2=(str width)(subtract)(str ButtonIPad)(multiply)(int 2) - -# Simple -width-ButtonIPad*2 + 2=(str width)(subtract)(str ButtonIPad)(multiply)(int 2)(add)(int 2) - -# Carved2 -width-ButtonIPad*2+1=(str width)(subtract)(str ButtonIPad)(multiply)(int 2)(add)(int 1) - -# Atlanta, Chiro, Metabox, Redmond, River, SmoothGNOME, Tetelestai-Modern, c2 -width-ButtonIPad*2-1=(str width)(subtract)(str ButtonIPad)(multiply)(int 2)(subtract)(int 1) - -# Bright -width-ButtonIPad*2-2=(str width)(subtract)(str ButtonIPad)(multiply)(int 2)(subtract)(int 2) - -# Chiro, River, c2 -width-ButtonIPad*2-5=(str width)(subtract)(str ButtonIPad)(multiply)(int 2)(subtract)(int 5) - -# Bright, Chiro, Metabox, River, c2 -width-ButtonIPad-1=(str width)(subtract)(str ButtonIPad)(subtract)(int 1) - -# Clearbox-look-2 -width-ButtonPad=(str width)(subtract)(str ButtonPad) - -# Clearbox-look-2 -width-ButtonPad*2+1=(str width)(subtract)(str ButtonPad)(multiply)(int 2)(add)(int 1) - -# Clearbox-look-2 -width-ButtonPad*2-1=(str width)(subtract)(str ButtonPad)(multiply)(int 2)(subtract)(int 1) - -# Clearbox-look-2 -width-ButtonPad+1=(str width)(subtract)(str ButtonPad)(add)(int 1) - -# Clearbox-look-2 -width-ButtonPad-1=(str width)(subtract)(str ButtonPad)(subtract)(int 1) - -# Clearbox-look-2 -width-ButtonPad-2=(str width)(subtract)(str ButtonPad)(subtract)(int 2) - -# Clearbox-look-2 -width-PrelightPad=(str width)(subtract)(str PrelightPad) - -# Clearbox-look-2 -width-PrelightPad*2+1=(str width)(subtract)(str PrelightPad)(multiply)(int 2)(add)(int 1) - -# Clearbox-look-2 -width-PrelightPad*2-1=(str width)(subtract)(str PrelightPad)(multiply)(int 2)(subtract)(int 1) - -# Clearbox-look-2 -width-PrelightPad+1=(str width)(subtract)(str PrelightPad)(add)(int 1) - -# Clearbox-look-2 -width-PrelightPad-1=(str width)(subtract)(str PrelightPad)(subtract)(int 1) - -# Clearbox-look-2 -width-PrelightPad-2=(str width)(subtract)(str PrelightPad)(subtract)(int 2) - -# Atlanta, Outcrop, Simple -width-SpacerWidth=(str width)(subtract)(str SpacerWidth) - -# Bright -width-SpacerWidth+2=(str width)(subtract)(str SpacerWidth)(add)(int 2) - -# Bright -width-SpacerWidth+3=(str width)(subtract)(str SpacerWidth)(add)(int 3) - -# Bright -width-SpacerWidth-2=(str width)(subtract)(str SpacerWidth)(subtract)(int 2) - -# Chiro -width-left_width=(str width)(subtract)(str left_width) - -# Atlanta, Bright, Metabox, Simple, SmoothGNOME, TangoDance, Tetelestai-Modern -width-left_width-right_width+1=(str width)(subtract)(str left_width)(subtract)(str right_width)(add)(int 1) - -# Maemo, Mista -width-object_width=(str width)(subtract)(str object_width) - -# 4DWM, Gilouche, GiloucheIM, MWM, SmoothGNOME, Tetelestai-Modern -width-right_width=(str width)(subtract)(str right_width) - -# 4DWM, MWM, Tetelestai-Modern -width-right_width+1=(str width)(subtract)(str right_width)(add)(int 1) - -# 4DWM -width-right_width/2=(str width)(subtract)(str right_width)(divide)(int 2) - -# 4DWM, MWM -width-top_height=(str width)(subtract)(str top_height) - -# 4DWM -width-top_height+1=(str width)(subtract)(str top_height)(add)(int 1) - -# 4DWM -width-top_height+2=(str width)(subtract)(str top_height)(add)(int 2) - -# 4DWM, MWM -width-top_height-1=(str width)(subtract)(str top_height)(subtract)(int 1) - -# Bentham, Clearbox-in, Clearbox-look-2, Clearbox-out, Simplebox, Sloth -width/2=(str width)(divide)(int 2) - -# Bentham -width/2 + width/4 - 1=(str width)(divide)(int 2)(add)(str width)(divide)(int 4)(subtract)(int 1) - -# Bentham -width/2 + width/4 - 2=(str width)(divide)(int 2)(add)(str width)(divide)(int 4)(subtract)(int 2) - -# Bentham -width/2 - width/4 + 1=(str width)(divide)(int 2)(subtract)(str width)(divide)(int 4)(add)(int 1) - -# Clearbox-in, Clearbox-out, MWM, Simplebox -width/2+1=(str width)(divide)(int 2)(add)(int 1) - -# Clearbox-in, Clearbox-out, Metabox, Simplebox -width/2+2=(str width)(divide)(int 2)(add)(int 2) - -# 4DWM, Clearbox-in, Clearbox-out, Simplebox -width/2+3=(str width)(divide)(int 2)(add)(int 3) - -# Clearbox-in, Clearbox-out, Simplebox -width/2+4=(str width)(divide)(int 2)(add)(int 4) - -# Clearbox-in, Clearbox-out, Simplebox -width/2+5=(str width)(divide)(int 2)(add)(int 5) - -# Aquarius -width/2+height/4=(str width)(divide)(int 2)(add)(str height)(divide)(int 4) - -# Aquarius -width/2+height/4+1=(str width)(divide)(int 2)(add)(str height)(divide)(int 4)(add)(int 1) - -# Aquarius -width/2+height/4+2=(str width)(divide)(int 2)(add)(str height)(divide)(int 4)(add)(int 2) - -# Clearbox-look-2 -width/2+width/2-ButtonPad+1=(str width)(divide)(int 2)(add)(str width)(divide)(int 2)(subtract)(str ButtonPad)(add)(int 1) - -# Clearbox-look-2 -width/2+width/2-PrelightPad+1=(str width)(divide)(int 2)(add)(str width)(divide)(int 2)(subtract)(str PrelightPad)(add)(int 1) - -# 4DWM, Clearbox-in, Clearbox-look-2, Clearbox-out, MWM, Simplebox -width/2-1=(str width)(divide)(int 2)(subtract)(int 1) - -# 4DWM, Clearbox-in, Clearbox-out, MWM, Metabox, Simplebox -width/2-2=(str width)(divide)(int 2)(subtract)(int 2) - -# Clearbox-in, Clearbox-out, Simplebox -width/2-3=(str width)(divide)(int 2)(subtract)(int 3) - -# Clearbox-in, Clearbox-out, Simplebox -width/2-4=(str width)(divide)(int 2)(subtract)(int 4) - -# Clearbox-in, Clearbox-out, Simplebox -width/2-5=(str width)(divide)(int 2)(subtract)(int 5) - -# Clearbox-in, Clearbox-out, Simplebox -width/2-6=(str width)(divide)(int 2)(subtract)(int 6) - -# Aquarius -width/2-height/4=(str width)(divide)(int 2)(subtract)(str height)(divide)(int 4) - -# Aquarius -width/2-height/4+1=(str width)(divide)(int 2)(subtract)(str height)(divide)(int 4)(add)(int 1) - -# Aquarius -width/2-height/4+2=(str width)(divide)(int 2)(subtract)(str height)(divide)(int 4)(add)(int 2) - -# Aquarius -width/2-height/6=(str width)(divide)(int 2)(subtract)(str height)(divide)(int 6) - -# Aquarius -width/2-height/6+1=(str width)(divide)(int 2)(subtract)(str height)(divide)(int 6)(add)(int 1) - -# Bentham -width/2-width/8-1=(str width)(divide)(int 2)(subtract)(str width)(divide)(int 8)(subtract)(int 1) - -# Bentham -width/2-width/8-2=(str width)(divide)(int 2)(subtract)(str width)(divide)(int 8)(subtract)(int 2) - -# Bentham -width/4=(str width)(divide)(int 4) - -# Bentham -width/4+2=(str width)(divide)(int 4)(add)(int 2) - -########################### - -# EOF tokentest.ini diff --git a/tools/xlib.py b/tools/xlib.py deleted file mode 100644 index 4a244c4f6..000000000 --- a/tools/xlib.py +++ /dev/null @@ -1,43 +0,0 @@ -# Very simple Xlib-based client in Python. -# Copyright (c) 2008 Thomas Thurman ; GPL 2.0 or later. -# Originally based around example code in python-xlib -# by Peter Liljenberg . - -import sys - -from Xlib import X -from Xlib.protocol import display -from Xlib.protocol.request import * - -display = display.Display() -screen = display.info.roots[display.default_screen] -window = display.allocate_resource_id() -gc = display.allocate_resource_id() - -CreateWindow(display, None, - depth = screen.root_depth, - wid = window, - parent = screen.root, - x = 100, y = 100, width = 250, height = 250, border_width = 2, - window_class = X.InputOutput, visual = X.CopyFromParent, - background_pixel = screen.white_pixel, - event_mask = (X.ExposureMask | - X.StructureNotifyMask | - X.ButtonPressMask | - X.ButtonReleaseMask | - X.Button1MotionMask), - colormap = X.CopyFromParent) - -CreateGC(display, None, gc, window) - -MapWindow(display, None, window) - -while 1: - event = display.next_event() - - if event.type == X.DestroyNotify: - sys.exit(0) - - print event - - From 0eb86de8077f566a79e19af9e59631c75f8ab2fb Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 20:32:02 -0400 Subject: [PATCH 696/889] Move Wayland protocols into src/wayland --- Makefile.am | 2 +- configure.ac | 1 - protocol/Makefile.am | 7 ------- src/Makefile.am | 12 ++++++++---- {protocol => src/wayland/protocol}/gtk-shell.xml | 0 {protocol => src/wayland/protocol}/xdg-shell.xml | 0 {protocol => src/wayland/protocol}/xserver.xml | 0 7 files changed, 9 insertions(+), 13 deletions(-) delete mode 100644 protocol/Makefile.am rename {protocol => src/wayland/protocol}/gtk-shell.xml (100%) rename {protocol => src/wayland/protocol}/xdg-shell.xml (100%) rename {protocol => src/wayland/protocol}/xserver.xml (100%) diff --git a/Makefile.am b/Makefile.am index 19dbe9cf1..d08cc6391 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,5 +1,5 @@ -SUBDIRS=src protocol po doc +SUBDIRS=src po doc EXTRA_DIST = HACKING MAINTAINERS rationales.txt diff --git a/configure.ac b/configure.ac index 6bc1ab4c2..6cc69fc0c 100644 --- a/configure.ac +++ b/configure.ac @@ -453,7 +453,6 @@ doc/reference/meta-docs.sgml src/Makefile src/libmutter-wayland.pc src/compositor/plugins/Makefile -protocol/Makefile po/Makefile.in ]) diff --git a/protocol/Makefile.am b/protocol/Makefile.am deleted file mode 100644 index 8ce700537..000000000 --- a/protocol/Makefile.am +++ /dev/null @@ -1,7 +0,0 @@ -NULL = - -EXTRA_DIST = \ - gtk-shell.xml \ - xdg-shell.xml \ - xserver.xml \ - $(NULL) diff --git a/src/Makefile.am b/src/Makefile.am index a94f49e61..fff1f22dd 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -49,6 +49,11 @@ mutter_built_sources = \ wayland/xserver-protocol.c \ wayland/xserver-server-protocol.h +wayland_protocols = \ + wayland/protocol/gtk-shell.xml \ + wayland/protocol/xdg-shell.xml \ + wayland/protocol/xserver.xml + libmutter_wayland_la_SOURCES = \ core/above-tab-keycode.c \ core/barrier.c \ @@ -362,6 +367,7 @@ EXTRA_DIST=$(desktopfiles_files) \ $(desktopfiles_in_files) \ $(wmproperties_in_files) \ $(xml_in_files) \ + $(wayland_protocols) \ org.gnome.mutter.gschema.xml.in \ org.gnome.mutter.wayland.gschema.xml.in \ mutter-schemas.convert \ @@ -411,9 +417,7 @@ $(dbus_idle_built_sources) : Makefile.am idle-monitor.xml --c-generate-object-manager \ $(srcdir)/idle-monitor.xml -wayland/%-protocol.c : $(top_builddir)/protocol/%.xml - mkdir -p wayland +wayland/%-protocol.c : $(srcdir)/wayland/protocol/%.xml $(AM_V_GEN)$(WAYLAND_SCANNER) code < $< > $@ -wayland/%-server-protocol.h : $(top_builddir)/protocol/%.xml - mkdir -p wayland +wayland/%-server-protocol.h : $(srcdir)/wayland/protocol/%.xml $(AM_V_GEN)$(WAYLAND_SCANNER) server-header < $< > $@ diff --git a/protocol/gtk-shell.xml b/src/wayland/protocol/gtk-shell.xml similarity index 100% rename from protocol/gtk-shell.xml rename to src/wayland/protocol/gtk-shell.xml diff --git a/protocol/xdg-shell.xml b/src/wayland/protocol/xdg-shell.xml similarity index 100% rename from protocol/xdg-shell.xml rename to src/wayland/protocol/xdg-shell.xml diff --git a/protocol/xserver.xml b/src/wayland/protocol/xserver.xml similarity index 100% rename from protocol/xserver.xml rename to src/wayland/protocol/xserver.xml From 3fe755e6849af28ebf27bdf9ae1e6ff2efbf427d Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 20:57:32 -0400 Subject: [PATCH 697/889] display: Fix a typo --- src/core/display.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/core/display.c b/src/core/display.c index f4c5946aa..3a068b8c7 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -175,8 +175,6 @@ static void prefs_changed_callback (MetaPreference pref, static void sanity_check_timestamps (MetaDisplay *display, guint32 known_good_timestamp); - -MetaGroup* get_focussed_group (MetaDisplay *display); static void meta_display_get_property(GObject *object, @@ -4776,8 +4774,8 @@ meta_display_pong_for_serial (MetaDisplay *display, } } -MetaGroup* -get_focussed_group (MetaDisplay *display) +static MetaGroup * +get_focused_group (MetaDisplay *display) { if (display->focus_window) return display->focus_window->group; @@ -4787,7 +4785,7 @@ get_focussed_group (MetaDisplay *display) #define IN_TAB_CHAIN(w,t) (((t) == META_TAB_LIST_NORMAL && META_WINDOW_IN_NORMAL_TAB_CHAIN (w)) \ || ((t) == META_TAB_LIST_DOCKS && META_WINDOW_IN_DOCK_TAB_CHAIN (w)) \ - || ((t) == META_TAB_LIST_GROUP && META_WINDOW_IN_GROUP_TAB_CHAIN (w, get_focussed_group(w->display))) \ + || ((t) == META_TAB_LIST_GROUP && META_WINDOW_IN_GROUP_TAB_CHAIN (w, get_focused_group (w->display))) \ || ((t) == META_TAB_LIST_NORMAL_ALL && META_WINDOW_IN_NORMAL_TAB_CHAIN_TYPE (w))) static MetaWindow* From dfcefd3315b662f3b1349f519de095a093ab438e Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 21:11:36 -0400 Subject: [PATCH 698/889] Remove meta_core_increment_event_serial It's unused. --- src/core/core.c | 10 ---------- src/core/core.h | 6 ------ 2 files changed, 16 deletions(-) diff --git a/src/core/core.c b/src/core/core.c index 9f41a3577..0c46a2f22 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -718,16 +718,6 @@ meta_core_set_screen_cursor (Display *xdisplay, meta_frame_set_screen_cursor (window->frame, cursor); } -void -meta_core_increment_event_serial (Display *xdisplay) -{ - MetaDisplay *display; - - display = meta_display_for_x_display (xdisplay); - - meta_display_increment_event_serial (display); -} - void meta_invalidate_default_icons (void) { diff --git a/src/core/core.h b/src/core/core.h index a3321531b..4c9e58754 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -193,12 +193,6 @@ void meta_core_set_screen_cursor (Display *xdisplay, Window frame_on_screen, MetaCursor cursor); -/* Used because we ignore EnterNotify when a window is unmapped that - * really shouldn't cause focus changes, by comparing the event serial - * of the EnterNotify and the UnmapNotify. - */ -void meta_core_increment_event_serial (Display *display); - void meta_invalidate_default_icons (void); void meta_core_add_old_event_mask (Display *xdisplay, From f05983be42a72c6524c0574e1044a4cc44dc095b Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 21:15:49 -0400 Subject: [PATCH 699/889] window: Move type_atom to window-x11 --- src/core/window-private.h | 3 +-- src/core/window.c | 18 ---------------- src/meta/window.h | 1 - src/x11/window-x11-private.h | 2 ++ src/x11/window-x11.c | 42 +++++++++++++++++++----------------- 5 files changed, 25 insertions(+), 41 deletions(-) diff --git a/src/core/window-private.h b/src/core/window-private.h index e2751e5ba..8a90de67e 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -95,9 +95,8 @@ struct _MetaWindow MetaIconCache icon_cache; Pixmap wm_hints_pixmap; Pixmap wm_hints_mask; - + MetaWindowType type; - Atom type_atom; /* NOTE these five are not in UTF-8, we just treat them as random * binary data diff --git a/src/core/window.c b/src/core/window.c index 480aa3deb..68d9c5140 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -940,7 +940,6 @@ _meta_window_shared_new (MetaDisplay *display, window->transient_parent_is_root_window = FALSE; window->type = META_WINDOW_NORMAL; - window->type_atom = None; window->struts = NULL; @@ -9417,23 +9416,6 @@ meta_window_get_window_type (MetaWindow *window) return window->type; } -/** - * meta_window_get_window_type_atom: (skip) - * @window: a #MetaWindow - * - * Gets the X atom from the _NET_WM_WINDOW_TYPE property used by the - * application to set the window type. (Note that this is constrained - * to be some value that Mutter recognizes - a completely unrecognized - * type atom will be returned as None.) - * - * Return value: the raw X atom for the window type, or None - */ -Atom -meta_window_get_window_type_atom (MetaWindow *window) -{ - return window->type_atom; -} - /** * meta_window_get_workspace: * @window: a #MetaWindow diff --git a/src/meta/window.h b/src/meta/window.h index f79088ba1..3677790b5 100644 --- a/src/meta/window.h +++ b/src/meta/window.h @@ -125,7 +125,6 @@ MetaScreen *meta_window_get_screen (MetaWindow *window); MetaDisplay *meta_window_get_display (MetaWindow *window); Window meta_window_get_xwindow (MetaWindow *window); MetaWindowType meta_window_get_window_type (MetaWindow *window); -Atom meta_window_get_window_type_atom (MetaWindow *window); MetaWorkspace *meta_window_get_workspace (MetaWindow *window); int meta_window_get_monitor (MetaWindow *window); gboolean meta_window_is_on_all_workspaces (MetaWindow *window); diff --git a/src/x11/window-x11-private.h b/src/x11/window-x11-private.h index d3ceb3ba7..54404d6cc 100644 --- a/src/x11/window-x11-private.h +++ b/src/x11/window-x11-private.h @@ -50,6 +50,8 @@ struct _MetaWindowX11Private guint using_net_wm_visible_name : 1; /* tracked so we can clear it */ guint using_net_wm_icon_name : 1; /* vs. plain wm_icon_name */ guint using_net_wm_visible_icon_name : 1; /* tracked so we can clear it */ + + Atom type_atom; }; G_END_DECLS diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c index 5abc848a6..ec8749453 100644 --- a/src/x11/window-x11.c +++ b/src/x11/window-x11.c @@ -199,11 +199,13 @@ meta_window_x11_set_net_wm_state (MetaWindow *window) void meta_window_x11_update_net_wm_type (MetaWindow *window) { + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11); int n_atoms; Atom *atoms; int i; - window->type_atom = None; + priv->type_atom = None; n_atoms = 0; atoms = NULL; @@ -234,7 +236,7 @@ meta_window_x11_update_net_wm_type (MetaWindow *window) atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_DND || atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_NORMAL) { - window->type_atom = atoms[i]; + priv->type_atom = atoms[i]; break; } @@ -248,10 +250,10 @@ meta_window_x11_update_net_wm_type (MetaWindow *window) char *str; str = NULL; - if (window->type_atom != None) + if (priv->type_atom != None) { meta_error_trap_push (window->display); - str = XGetAtomName (window->display->xdisplay, window->type_atom); + str = XGetAtomName (window->display->xdisplay, priv->type_atom); meta_error_trap_pop (window->display); } @@ -1549,38 +1551,38 @@ meta_window_x11_recalc_window_type (MetaWindow *window) MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11); MetaWindowType type; - if (window->type_atom != None) + if (priv->type_atom != None) { - if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DESKTOP) + if (priv->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DESKTOP) type = META_WINDOW_DESKTOP; - else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DOCK) + else if (priv->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DOCK) type = META_WINDOW_DOCK; - else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_TOOLBAR) + else if (priv->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_TOOLBAR) type = META_WINDOW_TOOLBAR; - else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_MENU) + else if (priv->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_MENU) type = META_WINDOW_MENU; - else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_UTILITY) + else if (priv->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_UTILITY) type = META_WINDOW_UTILITY; - else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_SPLASH) + else if (priv->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_SPLASH) type = META_WINDOW_SPLASHSCREEN; - else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DIALOG) + else if (priv->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DIALOG) type = META_WINDOW_DIALOG; - else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_NORMAL) + else if (priv->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_NORMAL) type = META_WINDOW_NORMAL; /* The below are *typically* override-redirect windows, but the spec does * not disallow using them for managed windows. */ - else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DROPDOWN_MENU) + else if (priv->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DROPDOWN_MENU) type = META_WINDOW_DROPDOWN_MENU; - else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_POPUP_MENU) + else if (priv->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_POPUP_MENU) type = META_WINDOW_POPUP_MENU; - else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_TOOLTIP) + else if (priv->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_TOOLTIP) type = META_WINDOW_TOOLTIP; - else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_NOTIFICATION) + else if (priv->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_NOTIFICATION) type = META_WINDOW_NOTIFICATION; - else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_COMBO) + else if (priv->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_COMBO) type = META_WINDOW_COMBO; - else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DND) + else if (priv->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DND) type = META_WINDOW_DND; else { @@ -1593,7 +1595,7 @@ meta_window_x11_recalc_window_type (MetaWindow *window) meta_error_trap_push (window->display); atom_name = XGetAtomName (window->display->xdisplay, - window->type_atom); + priv->type_atom); meta_error_trap_pop (window->display); meta_warning ("Unrecognized type atom [%s] set for %s \n", From 48a36356ddd0892202b4cf6ed8100827647681cf Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 21:19:51 -0400 Subject: [PATCH 700/889] window: Make window->desc a bit clearer And remove the hack for the "broken GNU libc". It works fine on my system here. --- src/core/window.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/core/window.c b/src/core/window.c index 68d9c5140..6bc821acc 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -742,6 +742,17 @@ sync_client_window_mapped (MetaWindow *window) meta_error_trap_pop (window->display); } +static void +meta_window_update_desc (MetaWindow *window) +{ + g_clear_pointer (&window->desc, g_free); + + if (window->title) + window->desc = g_strdup_printf ("0x%lx (%.10s)", window->xwindow, window->title); + else + window->desc = g_strdup_printf ("0x%lx", window->xwindow); +} + MetaWindow * _meta_window_shared_new (MetaDisplay *display, MetaScreen *screen, @@ -797,7 +808,7 @@ _meta_window_shared_new (MetaDisplay *display, window->screen = screen; - window->desc = g_strdup_printf ("0x%lx", window->xwindow); + meta_window_update_desc (window); window->override_redirect = attrs->override_redirect; @@ -9925,22 +9936,16 @@ void meta_window_set_title (MetaWindow *window, const char *title) { - char *str; - g_free (window->title); window->title = g_strdup (title); - /* strndup is a hack since GNU libc has broken %.10s */ - str = g_strndup (window->title, 10); - g_free (window->desc); - window->desc = g_strdup_printf ("0x%lx (%s)", window->xwindow, str); - g_free (str); - if (window->frame) meta_ui_set_frame_title (window->screen->ui, window->frame->xwindow, window->title); + meta_window_update_desc (window); + g_object_notify (G_OBJECT (window), "title"); } From f940292cfe5a80290a5dae8a62e05fbcbab32a7f Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 21:22:58 -0400 Subject: [PATCH 701/889] Move MetaGroup to be X11-specific --- src/Makefile.am | 4 +--- src/core/stack.c | 2 +- src/core/window-private.h | 2 ++ src/core/window.c | 2 +- src/meta/types.h | 5 ----- src/x11/group-private.h | 41 --------------------------------------- src/x11/group-props.c | 1 - src/x11/group-props.h | 2 +- src/x11/group.c | 2 +- src/{meta => x11}/group.h | 26 ++++++++++++++++--------- src/x11/window-props.c | 2 +- 11 files changed, 25 insertions(+), 64 deletions(-) delete mode 100644 src/x11/group-private.h rename src/{meta => x11}/group.h (84%) diff --git a/src/Makefile.am b/src/Makefile.am index fff1f22dd..7bb7b586b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -183,11 +183,10 @@ libmutter_wayland_la_SOURCES = \ x11/iconcache.h \ x11/async-getprop.c \ x11/async-getprop.h \ - x11/group-private.h \ x11/group-props.c \ x11/group-props.h \ x11/group.c \ - meta/group.h \ + x11/group.h \ x11/window-props.c \ x11/window-props.h \ x11/window-x11.c \ @@ -234,7 +233,6 @@ libmutterinclude_base_headers = \ meta/display.h \ meta/errors.h \ meta/gradient.h \ - meta/group.h \ meta/keybindings.h \ meta/main.h \ meta/meta-background-actor.h \ diff --git a/src/core/stack.c b/src/core/stack.c index c9223ccd4..c088bea62 100644 --- a/src/core/stack.c +++ b/src/core/stack.c @@ -30,7 +30,7 @@ #include "window-private.h" #include #include "frame.h" -#include +#include "group.h" #include #include diff --git a/src/core/window-private.h b/src/core/window-private.h index 8a90de67e..b52d88b2c 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -45,6 +45,8 @@ #include #include "meta-wayland-types.h" +#include "group.h" + typedef struct _MetaWindowQueue MetaWindowQueue; typedef enum { diff --git a/src/core/window.c b/src/core/window.c index 6bc821acc..2a4503d1c 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -43,7 +43,7 @@ #include #include "resizepopup.h" #include "xprops.h" -#include +#include "group.h" #include "window-props.h" #include "constraints.h" #include "mutter-enum-types.h" diff --git a/src/meta/types.h b/src/meta/types.h index cd6af2b63..13446ef31 100644 --- a/src/meta/types.h +++ b/src/meta/types.h @@ -30,11 +30,6 @@ typedef struct _MetaFrame MetaFrame; typedef struct _MetaScreen MetaScreen; typedef struct _MetaWindow MetaWindow; typedef struct _MetaWorkspace MetaWorkspace; -/** - * MetaGroup: (skip) - * - */ -typedef struct _MetaGroup MetaGroup; typedef struct _MetaKeyBinding MetaKeyBinding; typedef struct _MetaCursorTracker MetaCursorTracker; diff --git a/src/x11/group-private.h b/src/x11/group-private.h deleted file mode 100644 index 72e6cd275..000000000 --- a/src/x11/group-private.h +++ /dev/null @@ -1,41 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* Mutter window group private header */ - -/* - * Copyright (C) 2002 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_GROUP_PRIVATE_H -#define META_GROUP_PRIVATE_H - -#include - -struct _MetaGroup -{ - int refcount; - MetaDisplay *display; - GSList *windows; - Window group_leader; - char *startup_id; - char *wm_client_machine; -}; - -#endif - - - - diff --git a/src/x11/group-props.c b/src/x11/group-props.c index 521ffbd60..f079d2c72 100644 --- a/src/x11/group-props.c +++ b/src/x11/group-props.c @@ -21,7 +21,6 @@ #include #include "group-props.h" -#include "group-private.h" #include "xprops.h" #include diff --git a/src/x11/group-props.h b/src/x11/group-props.h index 1fb49ea1a..492b87241 100644 --- a/src/x11/group-props.h +++ b/src/x11/group-props.h @@ -22,7 +22,7 @@ #ifndef META_GROUP_PROPS_H #define META_GROUP_PROPS_H -#include +#include "group.h" #include "window-private.h" void meta_group_reload_property (MetaGroup *group, diff --git a/src/x11/group.c b/src/x11/group.c index 8965735c2..71b2280b7 100644 --- a/src/x11/group.c +++ b/src/x11/group.c @@ -27,7 +27,7 @@ #include #include -#include "group-private.h" +#include "group.h" #include "group-props.h" #include "window-private.h" #include diff --git a/src/meta/group.h b/src/x11/group.h similarity index 84% rename from src/meta/group.h rename to src/x11/group.h index 2ec647806..7d97e44a5 100644 --- a/src/meta/group.h +++ b/src/x11/group.h @@ -1,10 +1,10 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* Mutter window groups */ +/* Mutter window group private header */ -/* +/* * Copyright (C) 2002 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 @@ -14,7 +14,7 @@ * 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 . */ @@ -26,9 +26,21 @@ #include #include +typedef struct _MetaGroup MetaGroup; + +struct _MetaGroup +{ + int refcount; + MetaDisplay *display; + GSList *windows; + Window group_leader; + char *startup_id; + char *wm_client_machine; +}; + /* note, can return NULL */ MetaGroup* meta_window_get_group (MetaWindow *window); -void meta_window_compute_group (MetaWindow* window); +void meta_window_compute_group (MetaWindow *window); void meta_window_shutdown_group (MetaWindow *window); void meta_window_group_leader_changed (MetaWindow *window); @@ -49,7 +61,3 @@ gboolean meta_group_property_notify (MetaGroup *group, XEvent *event); #endif - - - - diff --git a/src/x11/window-props.c b/src/x11/window-props.c index b1bd6e1e4..5b4707b14 100644 --- a/src/x11/window-props.c +++ b/src/x11/window-props.c @@ -44,7 +44,7 @@ #include #include "xprops.h" #include "frame.h" -#include +#include "group.h" #include #include #include From 9c94f8ae471ad3cfb899c830cb57cbc50bf1da57 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 22:04:27 -0400 Subject: [PATCH 702/889] Move testasyncgetprop.c to x11/ --- src/Makefile.am | 2 +- src/{core => x11}/testasyncgetprop.c | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename src/{core => x11}/testasyncgetprop.c (100%) diff --git a/src/Makefile.am b/src/Makefile.am index 7bb7b586b..ebcf263a5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -314,7 +314,7 @@ endif testboxes_SOURCES = core/testboxes.c testgradient_SOURCES = ui/testgradient.c -testasyncgetprop_SOURCES = core/testasyncgetprop.c +testasyncgetprop_SOURCES = x11/testasyncgetprop.c noinst_PROGRAMS=testboxes testgradient testasyncgetprop diff --git a/src/core/testasyncgetprop.c b/src/x11/testasyncgetprop.c similarity index 100% rename from src/core/testasyncgetprop.c rename to src/x11/testasyncgetprop.c From 0a20f7458cbc688c06fd1f7e4df16d50bb9f9b42 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 21:48:52 -0400 Subject: [PATCH 703/889] window: Remove support for _NET_WM_ICON_NAME We don't seem to use it anywhere. --- src/core/window-private.h | 1 - src/core/window.c | 2 - src/meta/atomnames.h | 2 - src/x11/window-props.c | 76 +----------------------------------- src/x11/window-x11-private.h | 2 - 5 files changed, 2 insertions(+), 81 deletions(-) diff --git a/src/core/window-private.h b/src/core/window-private.h index b52d88b2c..d5e771423 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -91,7 +91,6 @@ struct _MetaWindow char *desc; /* used in debug spew */ char *title; - char *icon_name; GdkPixbuf *icon; GdkPixbuf *mini_icon; MetaIconCache icon_cache; diff --git a/src/core/window.c b/src/core/window.c index 2a4503d1c..93a5c0601 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -249,7 +249,6 @@ meta_window_finalize (GObject *object) g_free (window->res_class); g_free (window->res_name); g_free (window->title); - g_free (window->icon_name); g_free (window->desc); g_free (window->gtk_theme_variant); g_free (window->gtk_application_id); @@ -838,7 +837,6 @@ _meta_window_shared_new (MetaDisplay *display, window->colormap = attrs->colormap; window->title = NULL; - window->icon_name = NULL; window->icon = NULL; window->mini_icon = NULL; meta_icon_cache_init (&window->icon_cache); diff --git a/src/meta/atomnames.h b/src/meta/atomnames.h index d5e8a47ff..f93876cce 100644 --- a/src/meta/atomnames.h +++ b/src/meta/atomnames.h @@ -91,7 +91,6 @@ item(hotplug_mode_update) item(_NET_WM_SYNC_REQUEST) item(_NET_WM_SYNC_REQUEST_COUNTER) item(_NET_WM_VISIBLE_NAME) -item(_NET_WM_VISIBLE_ICON_NAME) item(_NET_SUPPORTING_WM_CHECK) /* But I suppose it's quite reasonable not to advertise using @@ -132,7 +131,6 @@ item(_NET_CLIENT_LIST) item(_NET_CLIENT_LIST_STACKING) item(_NET_WM_STATE_SKIP_TASKBAR) item(_NET_WM_STATE_SKIP_PAGER) -item(_NET_WM_ICON_NAME) item(_NET_WM_ICON) item(_NET_WM_ICON_GEOMETRY) item(_NET_WM_MOVERESIZE) diff --git a/src/x11/window-props.c b/src/x11/window-props.c index 5b4707b14..d9aacc661 100644 --- a/src/x11/window-props.c +++ b/src/x11/window-props.c @@ -429,9 +429,8 @@ reload_net_wm_user_time_window (MetaWindow *window, /** * set_title_text: * - * Called by set_window_title() and set_icon_title() to set the value of - * @target to @title. It required and @atom is set, it will update the - * appropriate property. + * Called by set_window_title() to set the value of @target to @title. + * If required and @atom is set, it will update the appropriate property. * * Returns: %TRUE if a new title was set. */ @@ -611,75 +610,6 @@ reload_mutter_hints (MetaWindow *window, } } -static void -set_icon_title (MetaWindow *window, - const char *title) -{ - MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); - MetaWindowX11Private *priv = window_x11->priv; - - gboolean modified = - set_title_text (window, - priv->using_net_wm_visible_icon_name, - title, - window->display->atom__NET_WM_VISIBLE_ICON_NAME, - &window->icon_name); - priv->using_net_wm_visible_icon_name = modified; -} - -static void -reload_net_wm_icon_name (MetaWindow *window, - MetaPropValue *value, - gboolean initial) -{ - MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); - MetaWindowX11Private *priv = window_x11->priv; - - if (value->type != META_PROP_VALUE_INVALID) - { - set_icon_title (window, value->v.str); - priv->using_net_wm_icon_name = TRUE; - - meta_verbose ("Using _NET_WM_ICON_NAME for new title of %s: \"%s\"\n", - window->desc, window->title); - } - else - { - set_icon_title (window, NULL); - priv->using_net_wm_icon_name = FALSE; - if (!initial) - meta_window_reload_property (window, XA_WM_ICON_NAME, FALSE); - } -} - -static void -reload_wm_icon_name (MetaWindow *window, - MetaPropValue *value, - gboolean initial) -{ - MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); - MetaWindowX11Private *priv = window_x11->priv; - - if (priv->using_net_wm_icon_name) - { - meta_verbose ("Ignoring WM_ICON_NAME \"%s\" as _NET_WM_ICON_NAME is set\n", - value->v.str); - return; - } - - if (value->type != META_PROP_VALUE_INVALID) - { - set_icon_title (window, value->v.str); - - meta_verbose ("Using WM_ICON_NAME for new title of %s: \"%s\"\n", - window->desc, window->title); - } - else - { - set_icon_title (window, NULL); - } -} - static void reload_net_wm_state (MetaWindow *window, MetaPropValue *value, @@ -1741,8 +1671,6 @@ meta_display_init_window_prop_hooks (MetaDisplay *display) { XA_WM_NAME, META_PROP_VALUE_TEXT_PROPERTY, reload_wm_name, TRUE, TRUE }, { display->atom__MUTTER_HINTS, META_PROP_VALUE_TEXT_PROPERTY, reload_mutter_hints, TRUE, TRUE }, { display->atom__NET_WM_OPAQUE_REGION, META_PROP_VALUE_CARDINAL_LIST, reload_opaque_region, TRUE, TRUE }, - { display->atom__NET_WM_ICON_NAME, META_PROP_VALUE_UTF8, reload_net_wm_icon_name, TRUE, FALSE }, - { XA_WM_ICON_NAME, META_PROP_VALUE_TEXT_PROPERTY, reload_wm_icon_name, TRUE, FALSE }, { display->atom__NET_WM_DESKTOP, META_PROP_VALUE_CARDINAL, reload_net_wm_desktop, TRUE, FALSE }, { display->atom__NET_STARTUP_ID, META_PROP_VALUE_UTF8, reload_net_startup_id, TRUE, FALSE }, { display->atom__NET_WM_SYNC_REQUEST_COUNTER, META_PROP_VALUE_SYNC_COUNTER_LIST, reload_update_counter, TRUE, TRUE }, diff --git a/src/x11/window-x11-private.h b/src/x11/window-x11-private.h index 54404d6cc..e288439bb 100644 --- a/src/x11/window-x11-private.h +++ b/src/x11/window-x11-private.h @@ -48,8 +48,6 @@ struct _MetaWindowX11Private /* Info on which props we got our attributes from */ guint using_net_wm_name : 1; /* vs. plain wm_name */ guint using_net_wm_visible_name : 1; /* tracked so we can clear it */ - guint using_net_wm_icon_name : 1; /* vs. plain wm_icon_name */ - guint using_net_wm_visible_icon_name : 1; /* tracked so we can clear it */ Atom type_atom; }; From a3ccc4fd1c7986c4f2250011a6d5bfba0afc9506 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 21:56:45 -0400 Subject: [PATCH 704/889] Remove x11/ directory from default include path --- src/Makefile.am | 1 - src/compositor/compositor.c | 1 - src/compositor/meta-window-actor.c | 1 - src/core/display.c | 9 +++++---- src/core/screen.c | 3 ++- src/core/stack.c | 3 ++- src/core/window-private.h | 4 ++-- src/core/window.c | 9 +++++---- 8 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index ebcf263a5..0bc63b718 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -16,7 +16,6 @@ INCLUDES= \ -I$(srcdir)/core \ -I$(srcdir)/ui \ -I$(srcdir)/compositor \ - -I$(srcdir)/x11 \ -DMUTTER_LIBEXECDIR=\"$(libexecdir)\" \ -DHOST_ALIAS=\"@HOST_ALIAS@\" \ -DMUTTER_LOCALEDIR=\"$(prefix)/@DATADIRNAME@/locale\" \ diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index e98c0c5c6..fa723fa46 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -65,7 +65,6 @@ #include #include "compositor-private.h" #include -#include "xprops.h" #include #include #include diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index a4368356d..a626328e0 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -20,7 +20,6 @@ #include "frame.h" #include #include -#include "xprops.h" #include "compositor-private.h" #include "meta-shaped-texture-private.h" diff --git a/src/core/display.c b/src/core/display.c index 3a068b8c7..1bd451a89 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -36,15 +36,11 @@ #include #include "screen-private.h" #include "window-private.h" -#include "window-x11.h" -#include "window-props.h" -#include "group-props.h" #include "frame.h" #include #include "keybindings-private.h" #include #include "resizepopup.h" -#include "xprops.h" #include "workspace-private.h" #include "bell.h" #include @@ -72,6 +68,11 @@ #include #include +#include "x11/window-x11.h" +#include "x11/window-props.h" +#include "x11/group-props.h" +#include "x11/xprops.h" + #include "meta-xwayland-private.h" #include "meta-surface-actor-wayland.h" diff --git a/src/core/screen.c b/src/core/screen.c index 512a722a6..8e0398917 100644 --- a/src/core/screen.c +++ b/src/core/screen.c @@ -39,7 +39,6 @@ #include "workspace-private.h" #include "keybindings-private.h" #include "stack.h" -#include "xprops.h" #include #include "mutter-enum-types.h" #include "core.h" @@ -54,6 +53,8 @@ #include #include +#include "x11/xprops.h" + static char* get_screen_name (MetaDisplay *display, int number); diff --git a/src/core/stack.c b/src/core/stack.c index c088bea62..ce31944d9 100644 --- a/src/core/stack.c +++ b/src/core/stack.c @@ -30,12 +30,13 @@ #include "window-private.h" #include #include "frame.h" -#include "group.h" #include #include #include +#include "x11/group.h" + #define WINDOW_HAS_TRANSIENT_TYPE(w) \ (w->type == META_WINDOW_DIALOG || \ w->type == META_WINDOW_MODAL_DIALOG || \ diff --git a/src/core/window-private.h b/src/core/window-private.h index d5e771423..6b774cb85 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -38,14 +38,14 @@ #include "screen-private.h" #include #include "stack.h" -#include "iconcache.h" #include #include #include #include #include "meta-wayland-types.h" -#include "group.h" +#include "x11/iconcache.h" +#include "x11/group.h" typedef struct _MetaWindowQueue MetaWindowQueue; diff --git a/src/core/window.c b/src/core/window.c index 93a5c0601..d21c704f8 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -28,7 +28,6 @@ #include #include "window-private.h" -#include "window-x11.h" #include "boxes-private.h" #include "edge-resistance.h" #include "util-private.h" @@ -42,9 +41,6 @@ #include "session.h" #include #include "resizepopup.h" -#include "xprops.h" -#include "group.h" -#include "window-props.h" #include "constraints.h" #include "mutter-enum-types.h" #include "core.h" @@ -61,6 +57,11 @@ #include "meta-wayland-private.h" #include "meta/compositor-mutter.h" +#include "x11/window-x11.h" +#include "x11/window-props.h" +#include "x11/xprops.h" +#include "x11/group.h" + /* Windows that unmaximize to a size bigger than that fraction of the workarea * will be scaled down to that size (while maintaining aspect ratio). * Windows that cover an area greater then this size are automaximized on map. From 044c06bff384387b1daf3d278d1fb903b30611a9 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 22:01:31 -0400 Subject: [PATCH 705/889] Don't include wayland/ by default either --- src/Makefile.am | 6 +----- src/compositor/compositor.c | 5 ++--- src/compositor/meta-surface-actor-wayland.c | 3 ++- src/compositor/meta-surface-actor-wayland.h | 2 +- src/compositor/meta-window-actor.c | 3 ++- src/core/delete.c | 2 +- src/core/display.c | 2 +- src/core/keybindings.c | 3 ++- src/core/main.c | 3 ++- src/core/meta-cursor-tracker.c | 3 ++- src/core/screen.c | 1 - src/core/window-private.h | 3 ++- src/core/window.c | 3 ++- 13 files changed, 20 insertions(+), 19 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 0bc63b718..972fb27ca 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -29,11 +29,7 @@ INCLUDES= \ -DMUTTER_PLUGIN_API_VERSION=$(MUTTER_PLUGIN_API_VERSION) \ -DMUTTER_PKGLIBDIR=\"$(pkglibdir)\" \ -DMUTTER_PLUGIN_DIR=\"@MUTTER_PLUGIN_DIR@\" \ - -DGETTEXT_PACKAGE=\"$(GETTEXT_PACKAGE)\" - -INCLUDES += \ - -I$(srcdir)/wayland \ - -I$(builddir)/wayland \ + -DGETTEXT_PACKAGE=\"$(GETTEXT_PACKAGE)\" \ -DXWAYLAND_PATH='"@XWAYLAND_PATH@"' mutter_built_sources = \ diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index fa723fa46..6a4904323 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -76,12 +76,11 @@ #include "display-private.h" /* for meta_display_lookup_x_window() */ #include "util-private.h" #include "frame.h" -#include "meta-wayland-private.h" -#include "meta-wayland-pointer.h" -#include "meta-wayland-keyboard.h" #include #include +#include "wayland/meta-wayland-private.h" + static gboolean is_modal (MetaDisplay *display) { diff --git a/src/compositor/meta-surface-actor-wayland.c b/src/compositor/meta-surface-actor-wayland.c index 56dd8bd13..bdd8df05c 100644 --- a/src/compositor/meta-surface-actor-wayland.c +++ b/src/compositor/meta-surface-actor-wayland.c @@ -28,7 +28,8 @@ #include #include "meta-shaped-texture-private.h" -#include "meta-wayland-private.h" + +#include "wayland/meta-wayland-private.h" struct _MetaSurfaceActorWaylandPrivate { diff --git a/src/compositor/meta-surface-actor-wayland.h b/src/compositor/meta-surface-actor-wayland.h index fbca3ff4d..35058ccf2 100644 --- a/src/compositor/meta-surface-actor-wayland.h +++ b/src/compositor/meta-surface-actor-wayland.h @@ -29,7 +29,7 @@ #include "meta-surface-actor.h" -#include "meta-wayland.h" +#include "wayland/meta-wayland.h" G_BEGIN_DECLS diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index a626328e0..7356d7da8 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -29,11 +29,12 @@ #include "region-utils.h" #include "monitor-private.h" #include "meta-cullable.h" -#include "meta-wayland-private.h" #include "meta-surface-actor.h" #include "meta-surface-actor-x11.h" +#include "wayland/meta-wayland-surface.h" + struct _MetaWindowActorPrivate { MetaWindow *window; diff --git a/src/core/delete.c b/src/core/delete.c index b86dcf304..136e564ea 100644 --- a/src/core/delete.c +++ b/src/core/delete.c @@ -37,7 +37,7 @@ #include #include -#include "meta-wayland-surface.h" +#include "wayland/meta-wayland-surface.h" static void meta_window_present_delete_dialog (MetaWindow *window, guint32 timestamp); diff --git a/src/core/display.c b/src/core/display.c index 1bd451a89..e43cd2772 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -73,7 +73,7 @@ #include "x11/group-props.h" #include "x11/xprops.h" -#include "meta-xwayland-private.h" +#include "wayland/meta-xwayland-private.h" #include "meta-surface-actor-wayland.h" /* diff --git a/src/core/keybindings.c b/src/core/keybindings.c index 415ccf851..c47178773 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -41,7 +41,6 @@ #include "screen-private.h" #include #include "util-private.h" -#include "meta-wayland.h" #include #include @@ -52,6 +51,8 @@ #include #endif +#include "wayland/meta-wayland.h" + #define SCHEMA_COMMON_KEYBINDINGS "org.gnome.desktop.wm.keybindings" #define SCHEMA_MUTTER_KEYBINDINGS "org.gnome.mutter.keybindings" #define SCHEMA_MUTTER_WAYLAND_KEYBINDINGS "org.gnome.mutter.wayland.keybindings" diff --git a/src/core/main.c b/src/core/main.c index 84d808751..df87ea213 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -53,7 +53,6 @@ #include "session.h" #include #include -#include "meta-wayland.h" #include #include @@ -79,6 +78,8 @@ #include #endif +#include "wayland/meta-wayland.h" + /* * The exit code we'll return to our parent process when we eventually die. */ diff --git a/src/core/meta-cursor-tracker.c b/src/core/meta-cursor-tracker.c index e98f2e72a..37dd9faac 100644 --- a/src/core/meta-cursor-tracker.c +++ b/src/core/meta-cursor-tracker.c @@ -47,9 +47,10 @@ #include "meta-cursor-tracker-private.h" #include "screen-private.h" -#include "meta-wayland-private.h" #include "monitor-private.h" +#include "wayland/meta-wayland-private.h" + #define META_WAYLAND_DEFAULT_CURSOR_HOTSPOT_X 7 #define META_WAYLAND_DEFAULT_CURSOR_HOTSPOT_Y 4 diff --git a/src/core/screen.c b/src/core/screen.c index 8e0398917..bac8dcaf0 100644 --- a/src/core/screen.c +++ b/src/core/screen.c @@ -42,7 +42,6 @@ #include #include "mutter-enum-types.h" #include "core.h" -#include "meta-wayland.h" #include "meta-cursor-tracker-private.h" #include diff --git a/src/core/window-private.h b/src/core/window-private.h index 6b774cb85..2470b8127 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -42,11 +42,12 @@ #include #include #include -#include "meta-wayland-types.h" #include "x11/iconcache.h" #include "x11/group.h" +#include "wayland/meta-wayland-types.h" + typedef struct _MetaWindowQueue MetaWindowQueue; typedef enum { diff --git a/src/core/window.c b/src/core/window.c index d21c704f8..36a585738 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -54,7 +54,6 @@ #include #endif -#include "meta-wayland-private.h" #include "meta/compositor-mutter.h" #include "x11/window-x11.h" @@ -62,6 +61,8 @@ #include "x11/xprops.h" #include "x11/group.h" +#include "wayland/meta-wayland-private.h" + /* Windows that unmaximize to a size bigger than that fraction of the workarea * will be scaled down to that size (while maintaining aspect ratio). * Windows that cover an area greater then this size are automaximized on map. From 5fa5ace5e6023932399de1c7ec471f09c870cf7b Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 22:02:47 -0400 Subject: [PATCH 706/889] Move session to x11/ XSMP code is X11-specific, of course. --- src/Makefile.am | 4 ++-- src/core/main.c | 3 ++- src/core/window.c | 2 +- src/{core => x11}/session.c | 0 src/{core => x11}/session.h | 0 5 files changed, 5 insertions(+), 4 deletions(-) rename src/{core => x11}/session.c (100%) rename src/{core => x11}/session.h (100%) diff --git a/src/Makefile.am b/src/Makefile.am index 972fb27ca..9130aec92 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -144,8 +144,6 @@ libmutter_wayland_la_SOURCES = \ core/screen-private.h \ meta/screen.h \ meta/types.h \ - core/session.c \ - core/session.h \ core/stack.c \ core/stack.h \ core/stack-tracker.c \ @@ -182,6 +180,8 @@ libmutter_wayland_la_SOURCES = \ x11/group-props.h \ x11/group.c \ x11/group.h \ + x11/session.c \ + x11/session.h \ x11/window-props.c \ x11/window-props.h \ x11/window-x11.c \ diff --git a/src/core/main.c b/src/core/main.c index df87ea213..d4a8ac3f8 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -50,7 +50,6 @@ #include "display-private.h" #include #include "ui.h" -#include "session.h" #include #include @@ -78,6 +77,8 @@ #include #endif +#include "x11/session.h" + #include "wayland/meta-wayland.h" /* diff --git a/src/core/window.c b/src/core/window.c index 36a585738..caef90706 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -38,7 +38,6 @@ #include "keybindings-private.h" #include "ui.h" #include "place.h" -#include "session.h" #include #include "resizepopup.h" #include "constraints.h" @@ -60,6 +59,7 @@ #include "x11/window-props.h" #include "x11/xprops.h" #include "x11/group.h" +#include "x11/session.h" #include "wayland/meta-wayland-private.h" diff --git a/src/core/session.c b/src/x11/session.c similarity index 100% rename from src/core/session.c rename to src/x11/session.c diff --git a/src/core/session.h b/src/x11/session.h similarity index 100% rename from src/core/session.h rename to src/x11/session.h From f0c7b518e610969b93adbf766239e2f01db23bbb Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 22:06:20 -0400 Subject: [PATCH 707/889] Don't generate sources in a subdirectory This fixes srcdir != builddir issues. --- src/Makefile.am | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 9130aec92..a64c9a19f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -37,12 +37,12 @@ mutter_built_sources = \ $(dbus_xrandr_built_sources) \ mutter-enum-types.h \ mutter-enum-types.c \ - wayland/gtk-shell-protocol.c \ - wayland/gtk-shell-server-protocol.h \ - wayland/xdg-shell-protocol.c \ - wayland/xdg-shell-server-protocol.h \ - wayland/xserver-protocol.c \ - wayland/xserver-server-protocol.h + gtk-shell-protocol.c \ + gtk-shell-server-protocol.h \ + xdg-shell-protocol.c \ + xdg-shell-server-protocol.h \ + xserver-protocol.c \ + xserver-server-protocol.h wayland_protocols = \ wayland/protocol/gtk-shell.xml \ @@ -410,7 +410,7 @@ $(dbus_idle_built_sources) : Makefile.am idle-monitor.xml --c-generate-object-manager \ $(srcdir)/idle-monitor.xml -wayland/%-protocol.c : $(srcdir)/wayland/protocol/%.xml +%-protocol.c : $(srcdir)/wayland/protocol/%.xml $(AM_V_GEN)$(WAYLAND_SCANNER) code < $< > $@ -wayland/%-server-protocol.h : $(srcdir)/wayland/protocol/%.xml +%-server-protocol.h : $(srcdir)/wayland/protocol/%.xml $(AM_V_GEN)$(WAYLAND_SCANNER) server-header < $< > $@ From 91ad92c96815df53b97de470d76481e040eacb4d Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 22:08:04 -0400 Subject: [PATCH 708/889] Update .gitignore --- .gitignore | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index eafa0d7ec..7a08ed3ca 100644 --- a/.gitignore +++ b/.gitignore @@ -78,12 +78,12 @@ src/stamp-mutter-marshal.h src/meta-dbus-xrandr.[ch] src/meta-dbus-idle-monitor.[ch] src/mutter-plugins.pc -src/wayland/gtk-shell-protocol.c -src/wayland/gtk-shell-server-protocol.h -src/wayland/xdg-shell-protocol.c -src/wayland/xdg-shell-server-protocol.h -src/wayland/xserver-protocol.c -src/wayland/xserver-server-protocol.h +src/gtk-shell-protocol.c +src/gtk-shell-server-protocol.h +src/xdg-shell-protocol.c +src/xdg-shell-server-protocol.h +src/xserver-protocol.c +src/xserver-server-protocol.h doc/reference/*.args doc/reference/*.bak doc/reference/*.hierarchy From a1427c7130ef6884bc503e2686bd7b49893a5071 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 19 Mar 2014 09:11:23 -0400 Subject: [PATCH 709/889] Revert "Move MetaGroup to be X11-specific" This reverts commit f940292cfe5a80290a5dae8a62e05fbcbab32a7f. Turns out MetaGroup was public API and was used by gnome-shell. Ugh. --- src/Makefile.am | 4 +++- src/core/stack.c | 3 ++- src/core/window-private.h | 2 +- src/core/window.c | 2 +- src/{x11 => meta}/group.h | 26 +++++++++---------------- src/meta/types.h | 5 +++++ src/x11/group-private.h | 41 +++++++++++++++++++++++++++++++++++++++ src/x11/group-props.c | 1 + src/x11/group-props.h | 2 +- src/x11/group.c | 2 +- src/x11/window-props.c | 2 +- 11 files changed, 66 insertions(+), 24 deletions(-) rename src/{x11 => meta}/group.h (84%) create mode 100644 src/x11/group-private.h diff --git a/src/Makefile.am b/src/Makefile.am index a64c9a19f..d67362b15 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -176,10 +176,11 @@ libmutter_wayland_la_SOURCES = \ x11/iconcache.h \ x11/async-getprop.c \ x11/async-getprop.h \ + x11/group-private.h \ x11/group-props.c \ x11/group-props.h \ x11/group.c \ - x11/group.h \ + meta/group.h \ x11/session.c \ x11/session.h \ x11/window-props.c \ @@ -228,6 +229,7 @@ libmutterinclude_base_headers = \ meta/display.h \ meta/errors.h \ meta/gradient.h \ + meta/group.h \ meta/keybindings.h \ meta/main.h \ meta/meta-background-actor.h \ diff --git a/src/core/stack.c b/src/core/stack.c index ce31944d9..68400e2ba 100644 --- a/src/core/stack.c +++ b/src/core/stack.c @@ -30,12 +30,13 @@ #include "window-private.h" #include #include "frame.h" +#include #include #include #include -#include "x11/group.h" +#include "x11/group-private.h" #define WINDOW_HAS_TRANSIENT_TYPE(w) \ (w->type == META_WINDOW_DIALOG || \ diff --git a/src/core/window-private.h b/src/core/window-private.h index 2470b8127..b70e04fb9 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -44,7 +44,7 @@ #include #include "x11/iconcache.h" -#include "x11/group.h" +#include "x11/group-private.h" #include "wayland/meta-wayland-types.h" diff --git a/src/core/window.c b/src/core/window.c index caef90706..e906f69c7 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -39,6 +39,7 @@ #include "ui.h" #include "place.h" #include +#include #include "resizepopup.h" #include "constraints.h" #include "mutter-enum-types.h" @@ -58,7 +59,6 @@ #include "x11/window-x11.h" #include "x11/window-props.h" #include "x11/xprops.h" -#include "x11/group.h" #include "x11/session.h" #include "wayland/meta-wayland-private.h" diff --git a/src/x11/group.h b/src/meta/group.h similarity index 84% rename from src/x11/group.h rename to src/meta/group.h index 7d97e44a5..2ec647806 100644 --- a/src/x11/group.h +++ b/src/meta/group.h @@ -1,10 +1,10 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* Mutter window group private header */ +/* Mutter window groups */ -/* +/* * Copyright (C) 2002 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 @@ -14,7 +14,7 @@ * 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 . */ @@ -26,21 +26,9 @@ #include #include -typedef struct _MetaGroup MetaGroup; - -struct _MetaGroup -{ - int refcount; - MetaDisplay *display; - GSList *windows; - Window group_leader; - char *startup_id; - char *wm_client_machine; -}; - /* note, can return NULL */ MetaGroup* meta_window_get_group (MetaWindow *window); -void meta_window_compute_group (MetaWindow *window); +void meta_window_compute_group (MetaWindow* window); void meta_window_shutdown_group (MetaWindow *window); void meta_window_group_leader_changed (MetaWindow *window); @@ -61,3 +49,7 @@ gboolean meta_group_property_notify (MetaGroup *group, XEvent *event); #endif + + + + diff --git a/src/meta/types.h b/src/meta/types.h index 13446ef31..cd6af2b63 100644 --- a/src/meta/types.h +++ b/src/meta/types.h @@ -30,6 +30,11 @@ typedef struct _MetaFrame MetaFrame; typedef struct _MetaScreen MetaScreen; typedef struct _MetaWindow MetaWindow; typedef struct _MetaWorkspace MetaWorkspace; +/** + * MetaGroup: (skip) + * + */ +typedef struct _MetaGroup MetaGroup; typedef struct _MetaKeyBinding MetaKeyBinding; typedef struct _MetaCursorTracker MetaCursorTracker; diff --git a/src/x11/group-private.h b/src/x11/group-private.h new file mode 100644 index 000000000..72e6cd275 --- /dev/null +++ b/src/x11/group-private.h @@ -0,0 +1,41 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* Mutter window group private header */ + +/* + * Copyright (C) 2002 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_GROUP_PRIVATE_H +#define META_GROUP_PRIVATE_H + +#include + +struct _MetaGroup +{ + int refcount; + MetaDisplay *display; + GSList *windows; + Window group_leader; + char *startup_id; + char *wm_client_machine; +}; + +#endif + + + + diff --git a/src/x11/group-props.c b/src/x11/group-props.c index f079d2c72..521ffbd60 100644 --- a/src/x11/group-props.c +++ b/src/x11/group-props.c @@ -21,6 +21,7 @@ #include #include "group-props.h" +#include "group-private.h" #include "xprops.h" #include diff --git a/src/x11/group-props.h b/src/x11/group-props.h index 492b87241..1fb49ea1a 100644 --- a/src/x11/group-props.h +++ b/src/x11/group-props.h @@ -22,7 +22,7 @@ #ifndef META_GROUP_PROPS_H #define META_GROUP_PROPS_H -#include "group.h" +#include #include "window-private.h" void meta_group_reload_property (MetaGroup *group, diff --git a/src/x11/group.c b/src/x11/group.c index 71b2280b7..8965735c2 100644 --- a/src/x11/group.c +++ b/src/x11/group.c @@ -27,7 +27,7 @@ #include #include -#include "group.h" +#include "group-private.h" #include "group-props.h" #include "window-private.h" #include diff --git a/src/x11/window-props.c b/src/x11/window-props.c index d9aacc661..128dfdeb7 100644 --- a/src/x11/window-props.c +++ b/src/x11/window-props.c @@ -44,7 +44,7 @@ #include #include "xprops.h" #include "frame.h" -#include "group.h" +#include #include #include #include From 27c018ab981fd968aa09b12957fbf9da3fee63e5 Mon Sep 17 00:00:00 2001 From: Marek Chalupa Date: Wed, 19 Mar 2014 09:27:38 +0100 Subject: [PATCH 710/889] update POTFILES.in some files were moved from src/core to src/x11 https://bugzilla.gnome.org/show_bug.cgi?id=726683 --- po/POTFILES.in | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/po/POTFILES.in b/po/POTFILES.in index 57351193c..f6696d90f 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -16,11 +16,11 @@ src/core/monitor.c src/core/mutter.c src/core/prefs.c src/core/screen.c -src/core/session.c +src/x11/session.c src/core/util.c src/core/window.c -src/core/window-props.c -src/core/xprops.c +src/x11/window-props.c +src/x11/xprops.c src/mutter-wayland.desktop.in src/org.gnome.mutter.gschema.xml.in src/org.gnome.mutter.wayland.gschema.xml.in From ce3d9fb89f798c6b964ec55eb41001478cfaecf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 19 Mar 2014 20:59:16 +0100 Subject: [PATCH 711/889] build: Don't try to distribute removed files Fixes some left-overs from commit ff635bad3b72c701. --- Makefile.am | 2 -- doc/Makefile.am | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/Makefile.am b/Makefile.am index d08cc6391..0529c4009 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,8 +1,6 @@ SUBDIRS=src po doc -EXTRA_DIST = HACKING MAINTAINERS rationales.txt - DISTCLEANFILES = intltool-extract intltool-merge intltool-update po/stamp-it po/.intltool-merge-cache DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc diff --git a/doc/Makefile.am b/doc/Makefile.am index d16ae33fe..12dc522dd 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -1,4 +1,4 @@ SUBDIRS = man reference EXTRA_DIST=theme-format.txt dialogs.txt code-overview.txt \ - how-to-get-focus-right.txt + how-to-get-focus-right.txt rationales.txt From 56e8c3b625bc5c66f235a4048929dbfc9743f0ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 19 Mar 2014 21:22:46 +0100 Subject: [PATCH 712/889] Bump version to 3.11.92 Update NEWS. --- NEWS | 11 +++++++++++ configure.ac | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 045021e56..cec317764 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,14 @@ +3.11.92 +======= +* Fix identification of CSD windows [Owen; #723029] +* Update keyboard state unconditionally [Rui; #722847] +* Misc bug fixes and cleanups [Owen, Rui, Giovanni, Matthias, Adel, Ryan, + Jasper, Marek, Florian; #723580, #726123, #726683] + +Contributors: + Giovanni Campagna, Marek Chalupa, Matthias Clasen, Adel Gadllah, Ryan Lortie, + Rui Matos, Florian Müllner, Jasper St. Pierre, Owen W. Taylor + 3.11.91 ======= * Don't use keysym to match keybindings [Rui; #678001] diff --git a/configure.ac b/configure.ac index 6cc69fc0c..250ed6753 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ AC_CONFIG_MACRO_DIR([m4]) m4_define([mutter_major_version], [3]) m4_define([mutter_minor_version], [11]) -m4_define([mutter_micro_version], [91]) +m4_define([mutter_micro_version], [92]) m4_define([mutter_version], [mutter_major_version.mutter_minor_version.mutter_micro_version]) From 63350c52ccaddf08659fe6f8ea580ea3eba4b623 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 19 Mar 2014 09:21:14 -0400 Subject: [PATCH 713/889] window: Remove code for static gravity resizes It was never turned on for all the years it's been there. --- src/core/display-private.h | 2 - src/core/display.c | 3 -- src/core/window.c | 84 +++----------------------------------- 3 files changed, 5 insertions(+), 84 deletions(-) diff --git a/src/core/display-private.h b/src/core/display-private.h index 281cc92b2..096304f3f 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -145,8 +145,6 @@ struct _MetaDisplay * multiple events with the same serial. */ guint focused_by_us : 1; - - guint static_gravity_works : 1; /*< private-ish >*/ guint error_trap_synced_at_last_pop : 1; diff --git a/src/core/display.c b/src/core/display.c index e43cd2772..489ca9ff7 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -527,9 +527,6 @@ meta_display_open (void) the_display->mouse_mode = TRUE; /* Only relevant for mouse or sloppy focus */ the_display->allow_terminal_deactivation = TRUE; /* Only relevant for when a terminal has the focus */ - - /* FIXME copy the checks from GDK probably */ - the_display->static_gravity_works = g_getenv ("MUTTER_USE_STATIC_GRAVITY") != NULL; meta_bell_init (the_display); diff --git a/src/core/window.c b/src/core/window.c index e906f69c7..0941dcad8 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -4078,12 +4078,6 @@ adjust_for_gravity (MetaWindow *window, } } -static gboolean -static_gravity_works (MetaDisplay *display) -{ - return display->static_gravity_works; -} - void meta_window_create_sync_request_alarm (MetaWindow *window) { @@ -4397,26 +4391,6 @@ meta_window_update_monitor (MetaWindow *window) } } -static void -meta_window_set_gravity (MetaWindow *window, - int gravity) -{ - XSetWindowAttributes attrs; - - meta_verbose ("Setting gravity of %s to %d\n", window->desc, gravity); - - attrs.win_gravity = gravity; - - meta_error_trap_push (window->display); - - XChangeWindowAttributes (window->display->xdisplay, - window->xwindow, - CWWinGravity, - &attrs); - - meta_error_trap_pop (window->display); -} - static void meta_window_move_resize_internal (MetaWindow *window, MetaMoveResizeFlags flags, @@ -4481,7 +4455,6 @@ meta_window_move_resize_internal (MetaWindow *window, gboolean is_wayland_resize; gboolean did_placement; gboolean configure_frame_first; - gboolean use_static_gravity; /* used for the configure request, but may not be final * destination due to StaticGravity etc. */ @@ -4745,50 +4718,12 @@ meta_window_move_resize_internal (MetaWindow *window, new_x = borders.total.left; new_y = borders.total.top; + client_move_x = new_x; + client_move_y = new_y; - if (need_resize_frame && need_move_frame && - static_gravity_works (window->display)) - { - /* static gravity kicks in because frame - * is both moved and resized - */ - /* when we move the frame by frame_pos_dx, frame_pos_dy the - * client will implicitly move relative to frame by the - * inverse delta. - * - * When moving client then frame, we move the client by the - * frame delta, to be canceled out by the implicit move by - * the inverse frame delta, resulting in a client at new_x, - * new_y. - * - * When moving frame then client, we move the client - * by the same delta as the frame, because the client - * was "left behind" by the frame - resulting in a client - * at new_x, new_y. - * - * In both cases we need to move the client window - * in all cases where we had to move the frame window. - */ - - client_move_x = new_x + frame_pos_dx; - client_move_y = new_y + frame_pos_dy; - - if (need_move_frame) - need_move_client = TRUE; - - use_static_gravity = TRUE; - } - else - { - client_move_x = new_x; - client_move_y = new_y; - - if (client_move_x != window->rect.x || - client_move_y != window->rect.y) - need_move_client = TRUE; - - use_static_gravity = FALSE; - } + if (client_move_x != window->rect.x || + client_move_y != window->rect.y) + need_move_client = TRUE; /* This is the final target position, but not necessarily what * we pass to XConfigureWindow, due to StaticGravity implicit @@ -4808,8 +4743,6 @@ meta_window_move_resize_internal (MetaWindow *window, client_move_x = window->rect.x; client_move_y = window->rect.y; - - use_static_gravity = FALSE; } /* If frame extents have changed, fill in other frame fields and @@ -4887,9 +4820,6 @@ meta_window_move_resize_internal (MetaWindow *window, configure_frame_first = size_dx + size_dy >= 0; } - if (use_static_gravity) - meta_window_set_gravity (window, StaticGravity); - if (configure_frame_first && window->frame) frame_shape_changed = meta_frame_sync_to_window (window->frame, gravity, @@ -4950,10 +4880,6 @@ meta_window_move_resize_internal (MetaWindow *window, gravity, need_move_frame, need_resize_frame); - /* Put gravity back to be nice to lesser window managers */ - if (use_static_gravity) - meta_window_set_gravity (window, NorthWestGravity); - if (need_configure_notify) send_configure_notify (window); } From 1c41f71eef1d12862131c47d1461235dbe7a1e8e Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 19 Mar 2014 09:26:17 -0400 Subject: [PATCH 714/889] window: Add a type for Wayland windows --- src/Makefile.am | 4 ++- src/core/window.c | 3 ++- src/wayland/window-wayland.c | 51 ++++++++++++++++++++++++++++++++++++ src/wayland/window-wayland.h | 44 +++++++++++++++++++++++++++++++ 4 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 src/wayland/window-wayland.c create mode 100644 src/wayland/window-wayland.h diff --git a/src/Makefile.am b/src/Makefile.am index d67362b15..1d0c53c64 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -210,7 +210,9 @@ libmutter_wayland_la_SOURCES = \ wayland/meta-wayland-types.h \ wayland/meta-wayland-versions.h \ wayland/meta-weston-launch.c \ - wayland/meta-weston-launch.h + wayland/meta-weston-launch.h \ + wayland/window-wayland.c \ + wayland/window-wayland.h nodist_libmutter_wayland_la_SOURCES = \ $(mutter_built_sources) diff --git a/src/core/window.c b/src/core/window.c index 0941dcad8..78adb985d 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -61,6 +61,7 @@ #include "x11/xprops.h" #include "x11/session.h" +#include "wayland/window-wayland.h" #include "wayland/meta-wayland-private.h" /* Windows that unmaximize to a size bigger than that fraction of the workarea @@ -783,7 +784,7 @@ _meta_window_shared_new (MetaDisplay *display, if (client_type == META_WINDOW_CLIENT_TYPE_X11) window = g_object_new (META_TYPE_WINDOW_X11, NULL); else - window = g_object_new (META_TYPE_WINDOW, NULL); + window = g_object_new (META_TYPE_WINDOW_WAYLAND, NULL); window->constructing = TRUE; diff --git a/src/wayland/window-wayland.c b/src/wayland/window-wayland.c new file mode 100644 index 000000000..627755ddf --- /dev/null +++ b/src/wayland/window-wayland.c @@ -0,0 +1,51 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2014 Red Hat + * + * 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. + * + * Written by: + * Jasper St. Pierre + */ + +#include "config.h" + +#include "window-wayland.h" + +#include "window-private.h" + +struct _MetaWindowWayland +{ + MetaWindow parent; +}; + +struct _MetaWindowWaylandClass +{ + MetaWindowClass parent_class; +}; + +G_DEFINE_TYPE (MetaWindowWayland, meta_window_wayland, META_TYPE_WINDOW) + +static void +meta_window_wayland_init (MetaWindowWayland *window_wayland) +{ +} + +static void +meta_window_wayland_class_init (MetaWindowWaylandClass *klass) +{ +} diff --git a/src/wayland/window-wayland.h b/src/wayland/window-wayland.h new file mode 100644 index 000000000..c1c667468 --- /dev/null +++ b/src/wayland/window-wayland.h @@ -0,0 +1,44 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2014 Red Hat + * + * 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. + * + * Written by: + * Jasper St. Pierre + */ + +#ifndef META_WINDOW_WAYLAND_H +#define META_WINDOW_WAYLAND_H + +#include + +G_BEGIN_DECLS + +#define META_TYPE_WINDOW_WAYLAND (meta_window_wayland_get_type()) +#define META_WINDOW_WAYLAND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_WINDOW_WAYLAND, MetaWindowWayland)) +#define META_WINDOW_WAYLAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_WINDOW_WAYLAND, MetaWindowWaylandClass)) +#define META_IS_WINDOW_WAYLAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_WINDOW_WAYLAND)) +#define META_IS_WINDOW_WAYLAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_WINDOW_WAYLAND)) +#define META_WINDOW_WAYLAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_WINDOW_WAYLAND, MetaWindowWaylandClass)) + +GType meta_window_wayland_get_type (void); + +typedef struct _MetaWindowWayland MetaWindowWayland; +typedef struct _MetaWindowWaylandClass MetaWindowWaylandClass; + +#endif From 74a1e00e302d0844bd14518583f92387073ca361 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 19 Mar 2014 09:36:36 -0400 Subject: [PATCH 715/889] window: MetaWindow is now abstract --- src/core/window.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/window.c b/src/core/window.c index 78adb985d..852321a7e 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -146,7 +146,7 @@ static gboolean idle_calc_showing (gpointer data); static gboolean idle_move_resize (gpointer data); static gboolean idle_update_icon (gpointer data); -G_DEFINE_TYPE (MetaWindow, meta_window, G_TYPE_OBJECT); +G_DEFINE_ABSTRACT_TYPE (MetaWindow, meta_window, G_TYPE_OBJECT); enum { PROP_0, From a377a1a11082ed138a519707a41aa47982428ea5 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 19 Mar 2014 09:36:15 -0400 Subject: [PATCH 716/889] window: Move client-type-specific managing / unmanaging to a vfunc --- src/core/window-private.h | 2 + src/core/window.c | 240 +---------------------------------- src/wayland/window-wayland.c | 38 ++++++ src/x11/window-x11.c | 206 ++++++++++++++++++++++++++++++ 4 files changed, 250 insertions(+), 236 deletions(-) diff --git a/src/core/window-private.h b/src/core/window-private.h index b70e04fb9..d706ff9c9 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -454,6 +454,8 @@ struct _MetaWindowClass { GObjectClass parent_class; + void (*manage) (MetaWindow *window); + void (*unmanage) (MetaWindow *window); void (*get_default_skip_hints) (MetaWindow *window, gboolean *skip_taskbar_out, gboolean *skip_pager_out); diff --git a/src/core/window.c b/src/core/window.c index 852321a7e..4e930dc53 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -73,7 +73,6 @@ static int destroying_windows_disallowed = 0; -static void update_sm_hints (MetaWindow *window); static void update_net_frame_extents (MetaWindow *window); static void invalidate_work_areas (MetaWindow *window); static void set_wm_state (MetaWindow *window); @@ -971,25 +970,9 @@ _meta_window_shared_new (MetaDisplay *display, */ window->stable_sequence = ++display->window_sequence_counter; - if (client_type == META_WINDOW_CLIENT_TYPE_X11) - { - meta_display_register_x_window (display, &window->xwindow, window); - meta_window_x11_update_shape_region (window); - meta_window_x11_update_input_region (window); - } - else - meta_display_register_wayland_window (display, window); - window->opacity = 0xFF; - /* assign the window to its group, or create a new group if needed - */ - window->group = NULL; - window->xgroup_leader = None; - meta_window_compute_group (window); - - if (client_type == META_WINDOW_CLIENT_TYPE_X11) - meta_window_load_initial_properties (window); + META_WINDOW_GET_CLASS (window)->manage (window); if (window->override_redirect) { @@ -1001,13 +984,6 @@ _meta_window_shared_new (MetaDisplay *display, window->has_resize_func = FALSE; } - if (!window->override_redirect && - client_type == META_WINDOW_CLIENT_TYPE_X11) - update_sm_hints (window); /* must come after transient_for */ - - if (client_type == META_WINDOW_CLIENT_TYPE_X11) - meta_window_x11_update_net_wm_type (window); - if (!window->override_redirect) meta_window_update_icon_now (window); @@ -1068,16 +1044,6 @@ _meta_window_shared_new (MetaDisplay *display, if (window->decorated) meta_window_ensure_frame (window); - if (window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND) - { - MetaStackWindow stack_window; - stack_window.any.type = META_WINDOW_CLIENT_TYPE_WAYLAND; - stack_window.wayland.meta_window = window; - meta_stack_tracker_record_add (window->screen->stack_tracker, - &stack_window, - 0); - } - meta_window_grab_keys (window); if (window->type != META_WINDOW_DOCK && !window->override_redirect) { @@ -1502,19 +1468,11 @@ meta_window_unmanage (MetaWindow *window, meta_verbose ("Unmanaging 0x%lx\n", window->xwindow); + /* This needs to happen for both Wayland and XWayland clients, + * so it can't be in MetaWindowWayland. */ if (window->surface) meta_wayland_surface_window_unmanaged (window->surface); - if (window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND) - { - MetaStackWindow stack_window; - stack_window.any.type = META_WINDOW_CLIENT_TYPE_WAYLAND; - stack_window.wayland.meta_window = window; - meta_stack_tracker_record_remove (window->screen->stack_tracker, - &stack_window, - 0); - } - if (window->visible_to_compositor) meta_compositor_hide_window (window->display->compositor, window, META_COMP_EFFECT_DESTROY); @@ -1670,105 +1628,15 @@ meta_window_unmanage (MetaWindow *window, */ meta_stack_tracker_queue_sync_stack (window->screen->stack_tracker); - if (window->withdrawn) - { - /* We need to clean off the window's state so it - * won't be restored if the app maps it again. - */ - meta_error_trap_push (window->display); - meta_verbose ("Cleaning state from window %s\n", window->desc); - XDeleteProperty (window->display->xdisplay, - window->xwindow, - window->display->atom__NET_WM_DESKTOP); - XDeleteProperty (window->display->xdisplay, - window->xwindow, - window->display->atom__NET_WM_STATE); - XDeleteProperty (window->display->xdisplay, - window->xwindow, - window->display->atom__NET_WM_FULLSCREEN_MONITORS); - set_wm_state (window); - meta_error_trap_pop (window->display); - } - else - { - /* We need to put WM_STATE so that others will understand it on - * restart. - */ - if (!window->minimized) - { - meta_error_trap_push (window->display); - set_wm_state (window); - meta_error_trap_pop (window->display); - } - - /* If we're unmanaging a window that is not withdrawn, then - * either (a) mutter is exiting, in which case we need to map - * the window so the next WM will know that it's not Withdrawn, - * or (b) we want to create a new MetaWindow to replace the - * current one, which will happen automatically if we re-map - * the X Window. - */ - meta_error_trap_push (window->display); - XMapWindow (window->display->xdisplay, - window->xwindow); - meta_error_trap_pop (window->display); - } - meta_window_ungrab_keys (window); meta_display_ungrab_window_buttons (window->display, window->xwindow); meta_display_ungrab_focus_window_button (window->display, window); if (window->display->autoraise_window == window) meta_display_remove_autoraise_callback (window->display); - if (window->client_type == META_WINDOW_CLIENT_TYPE_X11) - { - meta_display_unregister_x_window (window->display, window->xwindow); - - meta_error_trap_push (window->display); - - /* Put back anything we messed up */ - if (window->border_width != 0) - XSetWindowBorderWidth (window->display->xdisplay, - window->xwindow, - window->border_width); - - /* No save set */ - XRemoveFromSaveSet (window->display->xdisplay, - window->xwindow); - - /* Even though the window is now unmanaged, we can't unselect events. This - * window might be a window from this process, like a GdkMenu, in - * which case it will have pointer events and so forth selected - * for it by GDK. There's no way to disentangle those events from the events - * we've selected. Even for a window from a different X client, - * GDK could also have selected events for it for IPC purposes, so we - * can't unselect in that case either. - * - * Similarly, we can't unselected for events on window->user_time_window. - * It might be our own GDK focus window, or it might be a window that a - * different client is using for multiple different things: - * _NET_WM_USER_TIME_WINDOW and IPC, perhaps. - */ - - if (window->user_time_window != None) - { - meta_display_unregister_x_window (window->display, - window->user_time_window); - window->user_time_window = None; - } - -#ifdef HAVE_SHAPE - if (META_DISPLAY_HAS_SHAPE (window->display)) - XShapeSelectInput (window->display->xdisplay, window->xwindow, NoEventMask); -#endif - - meta_error_trap_pop (window->display); - } - else - meta_display_unregister_wayland_window (window->display, window); + META_WINDOW_GET_CLASS (window)->unmanage (window); meta_prefs_remove_listener (prefs_changed_callback, window); - meta_screen_queue_check_fullscreen (window->screen); g_signal_emit (window, window_signals[UNMANAGED], 0); @@ -6541,106 +6409,6 @@ meta_window_set_icon_geometry (MetaWindow *window, } } -static Window -read_client_leader (MetaDisplay *display, - Window xwindow) -{ - Window retval = None; - - meta_prop_get_window (display, xwindow, - display->atom_WM_CLIENT_LEADER, - &retval); - - return retval; -} - -typedef struct -{ - Window leader; -} ClientLeaderData; - -static gboolean -find_client_leader_func (MetaWindow *ancestor, - void *data) -{ - ClientLeaderData *d; - - d = data; - - d->leader = read_client_leader (ancestor->display, - ancestor->xwindow); - - /* keep going if no client leader found */ - return d->leader == None; -} - -static void -update_sm_hints (MetaWindow *window) -{ - Window leader; - - window->xclient_leader = None; - window->sm_client_id = NULL; - - /* If not on the current window, we can get the client - * leader from transient parents. If we find a client - * leader, we read the SM_CLIENT_ID from it. - */ - leader = read_client_leader (window->display, window->xwindow); - if (leader == None) - { - ClientLeaderData d; - d.leader = None; - meta_window_foreach_ancestor (window, find_client_leader_func, - &d); - leader = d.leader; - } - - if (leader != None) - { - char *str; - - window->xclient_leader = leader; - - if (meta_prop_get_latin1_string (window->display, leader, - window->display->atom_SM_CLIENT_ID, - &str)) - { - window->sm_client_id = g_strdup (str); - meta_XFree (str); - } - } - else - { - meta_verbose ("Didn't find a client leader for %s\n", window->desc); - - if (!meta_prefs_get_disable_workarounds ()) - { - /* Some broken apps (kdelibs fault?) set SM_CLIENT_ID on the app - * instead of the client leader - */ - char *str; - - str = NULL; - if (meta_prop_get_latin1_string (window->display, window->xwindow, - window->display->atom_SM_CLIENT_ID, - &str)) - { - if (window->sm_client_id == NULL) /* first time through */ - meta_warning ("Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER window as specified in the ICCCM.\n", - window->desc); - - window->sm_client_id = g_strdup (str); - meta_XFree (str); - } - } - } - - meta_verbose ("Window %s client leader: 0x%lx SM_CLIENT_ID: '%s'\n", - window->desc, window->xclient_leader, - window->sm_client_id ? window->sm_client_id : "none"); -} - static void redraw_icon (MetaWindow *window) { diff --git a/src/wayland/window-wayland.c b/src/wayland/window-wayland.c index 627755ddf..9a0a15c7d 100644 --- a/src/wayland/window-wayland.c +++ b/src/wayland/window-wayland.c @@ -27,6 +27,8 @@ #include "window-wayland.h" #include "window-private.h" +#include "stack-tracker.h" +#include "meta-wayland-surface.h" struct _MetaWindowWayland { @@ -40,6 +42,38 @@ struct _MetaWindowWaylandClass G_DEFINE_TYPE (MetaWindowWayland, meta_window_wayland, META_TYPE_WINDOW) +static void +meta_window_wayland_manage (MetaWindow *window) +{ + MetaDisplay *display = window->display; + + meta_display_register_wayland_window (display, window); + + { + MetaStackWindow stack_window; + stack_window.any.type = META_WINDOW_CLIENT_TYPE_WAYLAND; + stack_window.wayland.meta_window = window; + meta_stack_tracker_record_add (window->screen->stack_tracker, + &stack_window, + 0); + } +} + +static void +meta_window_wayland_unmanage (MetaWindow *window) +{ + { + MetaStackWindow stack_window; + stack_window.any.type = META_WINDOW_CLIENT_TYPE_WAYLAND; + stack_window.wayland.meta_window = window; + meta_stack_tracker_record_remove (window->screen->stack_tracker, + &stack_window, + 0); + } + + meta_display_unregister_wayland_window (window->display, window); +} + static void meta_window_wayland_init (MetaWindowWayland *window_wayland) { @@ -48,4 +82,8 @@ meta_window_wayland_init (MetaWindowWayland *window_wayland) static void meta_window_wayland_class_init (MetaWindowWaylandClass *klass) { + MetaWindowClass *window_class = META_WINDOW_CLASS (klass); + + window_class->manage = meta_window_wayland_manage; + window_class->unmanage = meta_window_wayland_unmanage; } diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c index ec8749453..f1f98b240 100644 --- a/src/x11/window-x11.c +++ b/src/x11/window-x11.c @@ -58,6 +58,210 @@ meta_window_x11_init (MetaWindowX11 *window_x11) window_x11->priv = meta_window_x11_get_instance_private (window_x11); } +static Window +read_client_leader (MetaDisplay *display, + Window xwindow) +{ + Window retval = None; + + meta_prop_get_window (display, xwindow, + display->atom_WM_CLIENT_LEADER, + &retval); + + return retval; +} + +typedef struct +{ + Window leader; +} ClientLeaderData; + +static gboolean +find_client_leader_func (MetaWindow *ancestor, + void *data) +{ + ClientLeaderData *d; + + d = data; + + d->leader = read_client_leader (ancestor->display, + ancestor->xwindow); + + /* keep going if no client leader found */ + return d->leader == None; +} + +static void +update_sm_hints (MetaWindow *window) +{ + Window leader; + + window->xclient_leader = None; + window->sm_client_id = NULL; + + /* If not on the current window, we can get the client + * leader from transient parents. If we find a client + * leader, we read the SM_CLIENT_ID from it. + */ + leader = read_client_leader (window->display, window->xwindow); + if (leader == None) + { + ClientLeaderData d; + d.leader = None; + meta_window_foreach_ancestor (window, find_client_leader_func, + &d); + leader = d.leader; + } + + if (leader != None) + { + char *str; + + window->xclient_leader = leader; + + if (meta_prop_get_latin1_string (window->display, leader, + window->display->atom_SM_CLIENT_ID, + &str)) + { + window->sm_client_id = g_strdup (str); + meta_XFree (str); + } + } + else + { + meta_verbose ("Didn't find a client leader for %s\n", window->desc); + + if (!meta_prefs_get_disable_workarounds ()) + { + /* Some broken apps (kdelibs fault?) set SM_CLIENT_ID on the app + * instead of the client leader + */ + char *str; + + str = NULL; + if (meta_prop_get_latin1_string (window->display, window->xwindow, + window->display->atom_SM_CLIENT_ID, + &str)) + { + if (window->sm_client_id == NULL) /* first time through */ + meta_warning ("Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER window as specified in the ICCCM.\n", + window->desc); + + window->sm_client_id = g_strdup (str); + meta_XFree (str); + } + } + } + + meta_verbose ("Window %s client leader: 0x%lx SM_CLIENT_ID: '%s'\n", + window->desc, window->xclient_leader, + window->sm_client_id ? window->sm_client_id : "none"); +} + +static void +meta_window_x11_manage (MetaWindow *window) +{ + MetaDisplay *display = window->display; + + meta_display_register_x_window (display, &window->xwindow, window); + meta_window_x11_update_shape_region (window); + meta_window_x11_update_input_region (window); + + /* assign the window to its group, or create a new group if needed */ + window->group = NULL; + window->xgroup_leader = None; + meta_window_compute_group (window); + + meta_window_load_initial_properties (window); + + if (!window->override_redirect) + update_sm_hints (window); /* must come after transient_for */ + + meta_window_x11_update_net_wm_type (window); +} + +static void +meta_window_x11_unmanage (MetaWindow *window) +{ + meta_error_trap_push (window->display); + + if (window->withdrawn) + { + /* We need to clean off the window's state so it + * won't be restored if the app maps it again. + */ + meta_verbose ("Cleaning state from window %s\n", window->desc); + XDeleteProperty (window->display->xdisplay, + window->xwindow, + window->display->atom__NET_WM_DESKTOP); + XDeleteProperty (window->display->xdisplay, + window->xwindow, + window->display->atom__NET_WM_STATE); + XDeleteProperty (window->display->xdisplay, + window->xwindow, + window->display->atom__NET_WM_FULLSCREEN_MONITORS); + meta_window_x11_set_wm_state (window); + } + else + { + /* We need to put WM_STATE so that others will understand it on + * restart. + */ + if (!window->minimized) + meta_window_x11_set_wm_state (window); + + /* If we're unmanaging a window that is not withdrawn, then + * either (a) mutter is exiting, in which case we need to map + * the window so the next WM will know that it's not Withdrawn, + * or (b) we want to create a new MetaWindow to replace the + * current one, which will happen automatically if we re-map + * the X Window. + */ + XMapWindow (window->display->xdisplay, + window->xwindow); + } + + meta_display_unregister_x_window (window->display, window->xwindow); + + /* Put back anything we messed up */ + if (window->border_width != 0) + XSetWindowBorderWidth (window->display->xdisplay, + window->xwindow, + window->border_width); + + /* No save set */ + XRemoveFromSaveSet (window->display->xdisplay, + window->xwindow); + + /* Even though the window is now unmanaged, we can't unselect events. This + * window might be a window from this process, like a GdkMenu, in + * which case it will have pointer events and so forth selected + * for it by GDK. There's no way to disentangle those events from the events + * we've selected. Even for a window from a different X client, + * GDK could also have selected events for it for IPC purposes, so we + * can't unselect in that case either. + * + * Similarly, we can't unselected for events on window->user_time_window. + * It might be our own GDK focus window, or it might be a window that a + * different client is using for multiple different things: + * _NET_WM_USER_TIME_WINDOW and IPC, perhaps. + */ + + if (window->user_time_window != None) + { + meta_display_unregister_x_window (window->display, + window->user_time_window); + window->user_time_window = None; + } + +#ifdef HAVE_SHAPE + if (META_DISPLAY_HAS_SHAPE (window->display)) + XShapeSelectInput (window->display->xdisplay, window->xwindow, NoEventMask); +#endif + + meta_error_trap_pop (window->display); +} + static void meta_window_x11_get_default_skip_hints (MetaWindow *window, gboolean *skip_taskbar_out, @@ -75,6 +279,8 @@ meta_window_x11_class_init (MetaWindowX11Class *klass) { MetaWindowClass *window_class = META_WINDOW_CLASS (klass); + window_class->manage = meta_window_x11_manage; + window_class->unmanage = meta_window_x11_unmanage; window_class->get_default_skip_hints = meta_window_x11_get_default_skip_hints; } From a53e094fcd4bec77873d201c582b9a5a74e733ac Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 19 Mar 2014 10:30:12 -0400 Subject: [PATCH 717/889] window: Move move_resize_internal logic to protocol-specific directories --- src/core/constraints.h | 10 - src/core/window-private.h | 28 +- src/core/window.c | 572 ++--------------------------------- src/wayland/window-wayland.c | 91 ++++++ src/x11/window-x11.c | 464 ++++++++++++++++++++++++++++ 5 files changed, 610 insertions(+), 555 deletions(-) diff --git a/src/core/constraints.h b/src/core/constraints.h index 52a6f209f..9c3c41e0e 100644 --- a/src/core/constraints.h +++ b/src/core/constraints.h @@ -27,16 +27,6 @@ #include "window-private.h" #include "frame.h" -typedef enum -{ - META_IS_CONFIGURE_REQUEST = 1 << 0, - 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_WAYLAND_RESIZE = 1 << 5 -} MetaMoveResizeFlags; - void meta_window_constrain (MetaWindow *window, MetaMoveResizeFlags flags, int resize_gravity, diff --git a/src/core/window-private.h b/src/core/window-private.h index d706ff9c9..aa57332eb 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -65,13 +65,28 @@ typedef enum { #define NUMBER_OF_QUEUES 3 - typedef enum { _NET_WM_BYPASS_COMPOSITOR_HINT_AUTO = 0, _NET_WM_BYPASS_COMPOSITOR_HINT_ON = 1, _NET_WM_BYPASS_COMPOSITOR_HINT_OFF = 2, } MetaBypassCompositorHintValue; +typedef enum +{ + META_IS_CONFIGURE_REQUEST = 1 << 0, + 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_WAYLAND_RESIZE = 1 << 5 +} MetaMoveResizeFlags; + +typedef enum +{ + META_MOVE_RESIZE_RESULT_MOVED = 1 << 0, + META_MOVE_RESIZE_RESULT_RESIZED = 1 << 1, + META_MOVE_RESIZE_RESULT_FRAME_SHAPE_CHANGED = 1 << 2, +} MetaMoveResizeResultFlags; struct _MetaWindow { @@ -456,6 +471,12 @@ struct _MetaWindowClass void (*manage) (MetaWindow *window); void (*unmanage) (MetaWindow *window); + void (*move_resize_internal) (MetaWindow *window, + int gravity, + MetaRectangle requested_rect, + MetaRectangle constrained_rect, + MetaMoveResizeFlags flags, + MetaMoveResizeResultFlags *result); void (*get_default_skip_hints) (MetaWindow *window, gboolean *skip_taskbar_out, gboolean *skip_pager_out); @@ -732,4 +753,9 @@ void meta_window_update_monitor (MetaWindow *window); void meta_window_set_urgent (MetaWindow *window, gboolean urgent); +void meta_window_update_resize (MetaWindow *window, + gboolean snap, + int x, int y, + gboolean force); + #endif diff --git a/src/core/window.c b/src/core/window.c index 4e930dc53..3c4c53966 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -73,15 +73,12 @@ static int destroying_windows_disallowed = 0; -static void update_net_frame_extents (MetaWindow *window); static void invalidate_work_areas (MetaWindow *window); static void set_wm_state (MetaWindow *window); static void set_net_wm_state (MetaWindow *window); static void meta_window_set_above (MetaWindow *window, gboolean new_value); -static void send_configure_notify (MetaWindow *window); - static void meta_window_force_placement (MetaWindow *window); static void meta_window_show (MetaWindow *window); @@ -1578,12 +1575,6 @@ meta_window_unmanage (MetaWindow *window, if (window->maximized_horizontally || window->maximized_vertically) unmaximize_window_before_freeing (window); - /* The XReparentWindow call in meta_window_destroy_frame() moves the - * window so we need to send a configure notify; see bug 399552. (We - * also do this just in case a window got unmaximized.) - */ - send_configure_notify (window); - meta_window_unqueue (window, META_QUEUE_CALC_SHOWING | META_QUEUE_MOVE_RESIZE | META_QUEUE_UPDATE_ICON); @@ -1619,9 +1610,6 @@ meta_window_unmanage (MetaWindow *window, meta_window_destroy_sync_request_alarm (window); - if (window->frame) - meta_window_destroy_frame (window); - /* If an undecorated window is being withdrawn, that will change the * stack as presented to the compositing manager, without actually * changing the stacking order of X windows. @@ -1636,6 +1624,9 @@ meta_window_unmanage (MetaWindow *window, META_WINDOW_GET_CLASS (window)->unmanage (window); + if (window->frame) + meta_window_destroy_frame (window); + meta_prefs_remove_listener (prefs_changed_callback, window); meta_screen_queue_check_fullscreen (window->screen); @@ -4034,90 +4025,6 @@ meta_window_destroy_sync_request_alarm (MetaWindow *window) #endif /* HAVE_XSYNC */ } -#ifdef HAVE_XSYNC -static gboolean -sync_request_timeout (gpointer data) -{ - MetaWindow *window = data; - - window->sync_request_timeout_id = 0; - - /* We have now waited for more than a second for the - * application to respond to the sync request - */ - window->disable_sync = TRUE; - - /* Reset the wait serial, so we don't continue freezing - * window updates - */ - window->sync_request_wait_serial = 0; - meta_compositor_set_updates_frozen (window->display->compositor, window, - meta_window_updates_are_frozen (window)); - - if (window == window->display->grab_window && - meta_grab_op_is_resizing (window->display->grab_op)) - { - update_resize (window, - window->display->grab_last_user_action_was_snap, - window->display->grab_latest_motion_x, - window->display->grab_latest_motion_y, - TRUE); - } - - return FALSE; -} - -static void -send_sync_request (MetaWindow *window) -{ - XClientMessageEvent ev; - gint64 wait_serial; - - /* For the old style of _NET_WM_SYNC_REQUEST_COUNTER, we just have to - * increase the value, but for the new "extended" style we need to - * pick an even (unfrozen) value sufficiently ahead of the last serial - * that we received from the client; the same code still works - * for the old style. The increment of 240 is specified by the EWMH - * and is (1 second) * (60fps) * (an increment of 4 per frame). - */ - wait_serial = window->sync_request_serial + 240; - - window->sync_request_wait_serial = wait_serial; - - ev.type = ClientMessage; - ev.window = window->xwindow; - ev.message_type = window->display->atom_WM_PROTOCOLS; - ev.format = 32; - ev.data.l[0] = window->display->atom__NET_WM_SYNC_REQUEST; - /* FIXME: meta_display_get_current_time() is bad, but since calls - * come from meta_window_move_resize_internal (which in turn come - * from all over), I'm not sure what we can do to fix it. Do we - * want to use _roundtrip, though? - */ - ev.data.l[1] = meta_display_get_current_time (window->display); - ev.data.l[2] = wait_serial & G_GUINT64_CONSTANT(0xffffffff); - ev.data.l[3] = wait_serial >> 32; - ev.data.l[4] = window->extended_sync_request_counter ? 1 : 0; - - /* We don't need to trap errors here as we are already - * inside an error_trap_push()/pop() pair. - */ - XSendEvent (window->display->xdisplay, - window->xwindow, False, 0, (XEvent*) &ev); - - /* We give the window 1 sec to respond to _NET_WM_SYNC_REQUEST; - * if this time expires, we consider the window unresponsive - * and resize it unsynchonized. - */ - window->sync_request_timeout_id = g_timeout_add (1000, - sync_request_timeout, - window); - - meta_compositor_set_updates_frozen (window->display->compositor, window, - meta_window_updates_are_frozen (window)); -} -#endif - /** * meta_window_updates_are_frozen: * @window: a #MetaWindow @@ -4307,30 +4214,21 @@ meta_window_move_resize_internal (MetaWindow *window, * we don't decorate wayland clients), and the client has acknowledged * the window size change. */ - XWindowChanges values; - unsigned int mask; - gboolean need_configure_notify; - MetaFrameBorders borders; - gboolean need_move_client = FALSE; - gboolean need_move_frame = FALSE; - gboolean need_resize_client = FALSE; - gboolean need_resize_frame = FALSE; - int size_dx; - int size_dy; gboolean frame_shape_changed = FALSE; + gboolean is_configure_request; gboolean do_gravity_adjust; gboolean is_user_action; gboolean is_wayland_resize; gboolean did_placement; - gboolean configure_frame_first; /* used for the configure request, but may not be final * destination due to StaticGravity etc. */ - int client_move_x; - int client_move_y; MetaRectangle new_rect; MetaRectangle old_rect; + MetaRectangle requested_rect; + MetaMoveResizeResultFlags result; + MetaFrameBorders borders; g_return_if_fail (!window->override_redirect); @@ -4356,13 +4254,14 @@ meta_window_move_resize_internal (MetaWindow *window, is_user_action ? " (user move/resize)" : "", old_rect.x, old_rect.y, old_rect.width, old_rect.height); - meta_frame_calc_borders (window->frame, - &borders); + meta_frame_calc_borders (window->frame, &borders); - new_rect.x = root_x_nw; - new_rect.y = root_y_nw; - new_rect.width = w; - new_rect.height = h; + requested_rect.x = root_x_nw; + requested_rect.y = root_y_nw; + requested_rect.width = w; + requested_rect.height = h; + + new_rect = requested_rect; /* If this is a resize only, the position should be ignored and * instead obtained by resizing the old rectangle according to the @@ -4409,363 +4308,21 @@ meta_window_move_resize_internal (MetaWindow *window, &new_rect); } - if (window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND) - { - g_assert (window->frame == NULL); - - /* For wayland clients, the size is completely determined by the client, - * and while this allows to avoid some trickery with frames and the resulting - * lagging, we also need to insist a bit when the constraints would apply - * a different size than the client decides. - * - * Note that this is not generally a problem for normal toplevel windows (the - * constraints don't see the size hints, or just change the position), but - * it can be for maximized or fullscreen. - * - */ - root_x_nw = new_rect.x; - root_y_nw = new_rect.y; - - /* First, save where we would like the client to be. This is used by the next - * attach to determine if the client is really moving/resizing or not. - */ - window->expected_rect = new_rect; - - if (is_wayland_resize) - { - /* This is a call to wl_surface_commit(), ignore the new_rect and - * update the real client size to match the buffer size. - */ - - window->rect.width = w; - window->rect.height = h; - } - - if (new_rect.width != window->rect.width || - new_rect.height != window->rect.height) - { - /* We need to resize the client. Resizing is in two parts: - * some of the movement happens immediately, and some happens as part - * of the resizing (through dx/dy in wl_surface_attach). - * - * To do so, we need to compute the resize from the point of the view - * of the client, and then adjust the immediate resize to match. - * - * dx/dy are the values we expect from the new attach(), while deltax/ - * deltay reflect the overall movement. - */ - MetaRectangle client_rect; - int dx, dy; - int deltax, deltay; - - meta_rectangle_resize_with_gravity (&old_rect, - &client_rect, - gravity, - new_rect.width, - new_rect.height); - - deltax = new_rect.x - old_rect.x; - deltay = new_rect.y - old_rect.y; - dx = client_rect.x - old_rect.x; - dy = client_rect.y - old_rect.y; - - if (deltax != dx || deltay != dy) - need_move_client = TRUE; - - window->rect.x += (deltax - dx); - window->rect.y += (deltay - dy); - - need_resize_client = TRUE; - meta_wayland_surface_configure_notify (window->surface, - new_rect.width, - new_rect.height); - } - else - { - /* No resize happening, we can just move the window and live with it. */ - if (window->rect.x != new_rect.x || - window->rect.y != new_rect.y) - need_move_client = TRUE; - - window->rect.x = new_rect.x; - window->rect.y = new_rect.y; - } - } - else - { - /* Everything else is the old X11 code, including weird gravities, - * the interaction with frames and the synthetic configure notifies. - */ - - /* meta_window_constrain() might have maximized the window after placement, - * changing the borders. - */ - meta_frame_calc_borders (window->frame, &borders); - - root_x_nw = new_rect.x; - root_y_nw = new_rect.y; - w = new_rect.width; - h = new_rect.height; - - if (w != window->rect.width || - h != window->rect.height) - need_resize_client = TRUE; - - window->rect.width = w; - window->rect.height = h; - - if (window->frame) - { - int frame_size_dx, frame_size_dy; - int new_w, new_h; - - new_w = window->rect.width + borders.total.left + borders.total.right; - - if (window->shaded) - new_h = borders.total.top; - else - new_h = window->rect.height + borders.total.top + borders.total.bottom; - - frame_size_dx = new_w - window->frame->rect.width; - frame_size_dy = new_h - window->frame->rect.height; - - need_resize_frame = (frame_size_dx != 0 || frame_size_dy != 0); - - window->frame->rect.width = new_w; - window->frame->rect.height = new_h; - - meta_topic (META_DEBUG_GEOMETRY, - "Calculated frame size %dx%d\n", - window->frame->rect.width, - window->frame->rect.height); - } - - /* For nice effect, when growing the window we want to move/resize - * the frame first, when shrinking the window we want to move/resize - * the client first. If we grow one way and shrink the other, - * see which way we're moving "more" - * - * Mail from Owen subject "Suggestion: Gravity and resizing from the left" - * http://mail.gnome.org/archives/wm-spec-list/1999-November/msg00088.html - * - * An annoying fact you need to know in this code is that StaticGravity - * does nothing if you _only_ resize or _only_ move the frame; - * it must move _and_ resize, otherwise you get NorthWestGravity - * behavior. The move and resize must actually occur, it is not - * enough to set CWX | CWWidth but pass in the current size/pos. - */ - - if (window->frame) - { - int new_x, new_y; - int frame_pos_dx, frame_pos_dy; - - /* Compute new frame coords */ - new_x = root_x_nw - borders.total.left; - new_y = root_y_nw - borders.total.top; - - frame_pos_dx = new_x - window->frame->rect.x; - frame_pos_dy = new_y - window->frame->rect.y; - - need_move_frame = (frame_pos_dx != 0 || frame_pos_dy != 0); - - window->frame->rect.x = new_x; - window->frame->rect.y = new_y; - - /* If frame will both move and resize, then StaticGravity - * on the child window will kick in and implicitly move - * the child with respect to the frame. The implicit - * move will keep the child in the same place with - * respect to the root window. If frame only moves - * or only resizes, then the child will just move along - * with the frame. - */ - - /* window->rect.x, window->rect.y are relative to frame, - * remember they are the server coords - */ - - new_x = borders.total.left; - new_y = borders.total.top; - client_move_x = new_x; - client_move_y = new_y; - - if (client_move_x != window->rect.x || - client_move_y != window->rect.y) - need_move_client = TRUE; - - /* This is the final target position, but not necessarily what - * we pass to XConfigureWindow, due to StaticGravity implicit - * movement. - */ - window->rect.x = new_x; - window->rect.y = new_y; - } - else - { - if (root_x_nw != window->rect.x || - root_y_nw != window->rect.y) - need_move_client = TRUE; - - window->rect.x = root_x_nw; - window->rect.y = root_y_nw; - - client_move_x = window->rect.x; - client_move_y = window->rect.y; - } - - /* If frame extents have changed, fill in other frame fields and - change frame's extents property. */ - if (window->frame && - (window->frame->child_x != borders.total.left || - window->frame->child_y != borders.total.top || - window->frame->right_width != borders.total.right || - window->frame->bottom_height != borders.total.bottom)) - { - window->frame->child_x = borders.total.left; - window->frame->child_y = borders.total.top; - window->frame->right_width = borders.total.right; - window->frame->bottom_height = borders.total.bottom; - - update_net_frame_extents (window); - } - - /* See ICCCM 4.1.5 for when to send ConfigureNotify */ - - need_configure_notify = FALSE; - - /* If this is a configure request and we change nothing, then we - * must send configure notify. - */ - if (is_configure_request && - !(need_move_client || need_move_frame || - need_resize_client || need_resize_frame || - window->border_width != 0)) - need_configure_notify = TRUE; - - /* We must send configure notify if we move but don't resize, since - * the client window may not get a real event - */ - if ((need_move_client || need_move_frame) && - !(need_resize_client || need_resize_frame)) - need_configure_notify = TRUE; - - /* MapRequest events with a PPosition or UPosition hint with a frame - * are moved by mutter without resizing; send a configure notify - * in such cases. See #322840. (Note that window->constructing is - * only true iff this call is due to a MapRequest, and when - * PPosition/UPosition hints aren't set, mutter seems to send a - * ConfigureNotify anyway due to the above code.) - */ - if (window->constructing && window->frame && - ((window->size_hints.flags & PPosition) || - (window->size_hints.flags & USPosition))) - need_configure_notify = TRUE; - - /* The rest of this function syncs our new size/pos with X as - * efficiently as possible - */ - - /* Normally, we configure the frame first depending on whether - * we grow the frame more than we shrink. The idea is to avoid - * messing up the window contents by having a temporary situation - * where the frame is smaller than the window. However, if we're - * cooperating with the client to create an atomic frame upate, - * and the window is redirected, then we should always update - * the frame first, since updating the frame will force a new - * backing pixmap to be allocated, and the old backing pixmap - * will be left undisturbed for us to paint to the screen until - * the client finishes redrawing. - */ - if (window->extended_sync_request_counter) - { - configure_frame_first = TRUE; - } - else - { - size_dx = w - window->rect.width; - size_dy = h - window->rect.height; - - configure_frame_first = size_dx + size_dy >= 0; - } - - if (configure_frame_first && window->frame) - frame_shape_changed = meta_frame_sync_to_window (window->frame, - gravity, - need_move_frame, need_resize_frame); - - values.border_width = 0; - values.x = client_move_x; - values.y = client_move_y; - values.width = window->rect.width; - values.height = window->rect.height; - - mask = 0; - if (is_configure_request && window->border_width != 0) - mask |= CWBorderWidth; /* must force to 0 */ - if (need_move_client) - mask |= (CWX | CWY); - if (need_resize_client) - mask |= (CWWidth | CWHeight); - - if (mask != 0) - { - { - int newx, newy; - meta_window_get_position (window, &newx, &newy); - meta_topic (META_DEBUG_GEOMETRY, - "Syncing new client geometry %d,%d %dx%d, border: %s pos: %s size: %s\n", - newx, newy, - window->rect.width, window->rect.height, - mask & CWBorderWidth ? "true" : "false", - need_move_client ? "true" : "false", - need_resize_client ? "true" : "false"); - } - - meta_error_trap_push (window->display); - -#ifdef HAVE_XSYNC - if (window == window->display->grab_window && - meta_grab_op_is_resizing (window->display->grab_op) && - !window->disable_sync && - window->sync_request_counter != None && - window->sync_request_alarm != None && - window->sync_request_timeout_id == 0) - { - send_sync_request (window); - } -#endif - - XConfigureWindow (window->display->xdisplay, - window->xwindow, - mask, - &values); - - meta_error_trap_pop (window->display); - } - - if (!configure_frame_first && window->frame) - frame_shape_changed = meta_frame_sync_to_window (window->frame, - gravity, - need_move_frame, need_resize_frame); - - if (need_configure_notify) - send_configure_notify (window); - } + /* Do the protocol-specific move/resize logic */ + META_WINDOW_GET_CLASS (window)->move_resize_internal (window, gravity, requested_rect, new_rect, flags, &result); if (!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); - if (need_move_client || need_move_frame) + if (result & META_MOVE_RESIZE_RESULT_MOVED) g_signal_emit (window, window_signals[POSITION_CHANGED], 0); - if (need_resize_client || need_resize_frame) + if (result & META_MOVE_RESIZE_RESULT_RESIZED) g_signal_emit (window, window_signals[SIZE_CHANGED], 0); - if (need_move_frame || need_resize_frame || - need_move_client || need_resize_client || + if ((result & (META_MOVE_RESIZE_RESULT_MOVED | META_MOVE_RESIZE_RESULT_RESIZED)) != 0 || did_placement || is_wayland_resize) { int newx, newy; @@ -5751,35 +5308,6 @@ meta_window_get_net_wm_desktop (MetaWindow *window) return meta_workspace_index (window->workspace); } -static void -update_net_frame_extents (MetaWindow *window) -{ - unsigned long data[4]; - MetaFrameBorders borders; - - meta_frame_calc_borders (window->frame, &borders); - /* Left */ - data[0] = borders.visible.left; - /* Right */ - data[1] = borders.visible.right; - /* Top */ - data[2] = borders.visible.top; - /* Bottom */ - data[3] = borders.visible.bottom; - - meta_topic (META_DEBUG_GEOMETRY, - "Setting _NET_FRAME_EXTENTS on managed window 0x%lx " - "to left = %lu, right = %lu, top = %lu, bottom = %lu\n", - window->xwindow, data[0], data[1], data[2], data[3]); - - meta_error_trap_push (window->display); - XChangeProperty (window->display->xdisplay, window->xwindow, - window->display->atom__NET_FRAME_EXTENTS, - XA_CARDINAL, - 32, PropModeReplace, (guchar*) data, 4); - meta_error_trap_pop (window->display); -} - void meta_window_set_current_workspace_hint (MetaWindow *window) { @@ -6304,59 +5832,6 @@ meta_window_set_focused_internal (MetaWindow *window, } } -static void -send_configure_notify (MetaWindow *window) -{ - XEvent event; - - /* from twm */ - - event.type = ConfigureNotify; - event.xconfigure.display = window->display->xdisplay; - event.xconfigure.event = window->xwindow; - event.xconfigure.window = window->xwindow; - event.xconfigure.x = window->rect.x - window->border_width; - event.xconfigure.y = window->rect.y - window->border_width; - if (window->frame) - { - if (window->withdrawn) - { - MetaFrameBorders borders; - /* We reparent the client window and put it to the position - * where the visible top-left of the frame window currently is. - */ - - meta_frame_calc_borders (window->frame, &borders); - - event.xconfigure.x = window->frame->rect.x + borders.invisible.left; - event.xconfigure.y = window->frame->rect.y + borders.invisible.top; - } - else - { - /* Need to be in root window coordinates */ - event.xconfigure.x += window->frame->rect.x; - event.xconfigure.y += window->frame->rect.y; - } - } - event.xconfigure.width = window->rect.width; - event.xconfigure.height = window->rect.height; - event.xconfigure.border_width = window->border_width; /* requested not actual */ - event.xconfigure.above = None; /* FIXME */ - event.xconfigure.override_redirect = False; - - meta_topic (META_DEBUG_GEOMETRY, - "Sending synthetic configure notify to %s with x: %d y: %d w: %d h: %d\n", - window->desc, - event.xconfigure.x, event.xconfigure.y, - event.xconfigure.width, event.xconfigure.height); - - meta_error_trap_push (window->display); - XSendEvent (window->display->xdisplay, - window->xwindow, - False, StructureNotifyMask, &event); - meta_error_trap_pop (window->display); -} - /** * meta_window_get_icon_geometry: * @window: a #MetaWindow @@ -8083,6 +7558,15 @@ update_tile_mode (MetaWindow *window) } } +void +meta_window_update_resize (MetaWindow *window, + gboolean snap, + int x, int y, + gboolean force) +{ + update_resize (window, snap, x, y, force); +} + #ifdef HAVE_XSYNC void meta_window_update_sync_request_counter (MetaWindow *window, diff --git a/src/wayland/window-wayland.c b/src/wayland/window-wayland.c index 9a0a15c7d..8b75da743 100644 --- a/src/wayland/window-wayland.c +++ b/src/wayland/window-wayland.c @@ -27,6 +27,7 @@ #include "window-wayland.h" #include "window-private.h" +#include "boxes-private.h" #include "stack-tracker.h" #include "meta-wayland-surface.h" @@ -74,6 +75,95 @@ meta_window_wayland_unmanage (MetaWindow *window) meta_display_unregister_wayland_window (window->display, window); } +static void +meta_window_wayland_move_resize_internal (MetaWindow *window, + int gravity, + MetaRectangle requested_rect, + MetaRectangle constrained_rect, + MetaMoveResizeFlags flags, + MetaMoveResizeResultFlags *result) +{ + g_assert (window->frame == NULL); + + /* For wayland clients, the size is completely determined by the client, + * and while this allows to avoid some trickery with frames and the resulting + * lagging, we also need to insist a bit when the constraints would apply + * a different size than the client decides. + * + * Note that this is not generally a problem for normal toplevel windows (the + * constraints don't see the size hints, or just change the position), but + * it can be for maximized or fullscreen. + */ + + /* First, save where we would like the client to be. This is used by the next + * attach to determine if the client is really moving/resizing or not. + */ + window->expected_rect = constrained_rect; + + if (flags & META_IS_WAYLAND_RESIZE) + { + /* This is a call to wl_surface_commit(), ignore the constrained_rect and + * update the real client size to match the buffer size. + */ + + window->rect.width = requested_rect.width; + window->rect.height = requested_rect.height; + } + + if (constrained_rect.width != window->rect.width || + constrained_rect.height != window->rect.height) + { + /* We need to resize the client. Resizing is in two parts: + * some of the movement happens immediately, and some happens as part + * of the resizing (through dx/dy in wl_surface_attach). + * + * To do so, we need to compute the resize from the point of the view + * of the client, and then adjust the immediate resize to match. + * + * dx/dy are the values we expect from the new attach(), while deltax/ + * deltay reflect the overall movement. + */ + MetaRectangle old_rect; + MetaRectangle client_rect; + int dx, dy; + int deltax, deltay; + + meta_window_get_client_root_coords (window, &old_rect); + + meta_rectangle_resize_with_gravity (&old_rect, + &client_rect, + gravity, + constrained_rect.width, + constrained_rect.height); + + deltax = constrained_rect.x - old_rect.x; + deltay = constrained_rect.y - old_rect.y; + dx = client_rect.x - constrained_rect.x; + dy = client_rect.y - constrained_rect.y; + + if (deltax != dx || deltay != dy) + *result |= META_MOVE_RESIZE_RESULT_MOVED; + + window->rect.x += (deltax - dx); + window->rect.y += (deltay - dy); + + *result |= META_MOVE_RESIZE_RESULT_RESIZED; + meta_wayland_surface_configure_notify (window->surface, + constrained_rect.width, + constrained_rect.height); + } + else + { + /* No resize happening, we can just move the window and live with it. */ + if (window->rect.x != constrained_rect.x || + window->rect.y != constrained_rect.y) + *result |= META_MOVE_RESIZE_RESULT_MOVED; + + window->rect.x = constrained_rect.x; + window->rect.y = constrained_rect.y; + } +} + static void meta_window_wayland_init (MetaWindowWayland *window_wayland) { @@ -86,4 +176,5 @@ meta_window_wayland_class_init (MetaWindowWaylandClass *klass) window_class->manage = meta_window_wayland_manage; window_class->unmanage = meta_window_wayland_unmanage; + window_class->move_resize_internal = meta_window_wayland_move_resize_internal; } diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c index f1f98b240..86491a665 100644 --- a/src/x11/window-x11.c +++ b/src/x11/window-x11.c @@ -41,6 +41,7 @@ #include #include +#include "frame.h" #include "window-private.h" #include "window-props.h" #include "xprops.h" @@ -158,6 +159,59 @@ update_sm_hints (MetaWindow *window) window->sm_client_id ? window->sm_client_id : "none"); } +static void +send_configure_notify (MetaWindow *window) +{ + XEvent event; + + /* from twm */ + + event.type = ConfigureNotify; + event.xconfigure.display = window->display->xdisplay; + event.xconfigure.event = window->xwindow; + event.xconfigure.window = window->xwindow; + event.xconfigure.x = window->rect.x - window->border_width; + event.xconfigure.y = window->rect.y - window->border_width; + if (window->frame) + { + if (window->withdrawn) + { + MetaFrameBorders borders; + /* We reparent the client window and put it to the position + * where the visible top-left of the frame window currently is. + */ + + meta_frame_calc_borders (window->frame, &borders); + + event.xconfigure.x = window->frame->rect.x + borders.invisible.left; + event.xconfigure.y = window->frame->rect.y + borders.invisible.top; + } + else + { + /* Need to be in root window coordinates */ + event.xconfigure.x += window->frame->rect.x; + event.xconfigure.y += window->frame->rect.y; + } + } + event.xconfigure.width = window->rect.width; + event.xconfigure.height = window->rect.height; + event.xconfigure.border_width = window->border_width; /* requested not actual */ + event.xconfigure.above = None; /* FIXME */ + event.xconfigure.override_redirect = False; + + meta_topic (META_DEBUG_GEOMETRY, + "Sending synthetic configure notify to %s with x: %d y: %d w: %d h: %d\n", + window->desc, + event.xconfigure.x, event.xconfigure.y, + event.xconfigure.width, event.xconfigure.height); + + meta_error_trap_push (window->display); + XSendEvent (window->display->xdisplay, + window->xwindow, + False, StructureNotifyMask, &event); + meta_error_trap_pop (window->display); +} + static void meta_window_x11_manage (MetaWindow *window) { @@ -259,9 +313,418 @@ meta_window_x11_unmanage (MetaWindow *window) XShapeSelectInput (window->display->xdisplay, window->xwindow, NoEventMask); #endif + /* The XReparentWindow call in meta_window_destroy_frame() moves the + * window so we need to send a configure notify; see bug 399552. (We + * also do this just in case a window got unmaximized.) + */ + send_configure_notify (window); + meta_error_trap_pop (window->display); } +static void +update_net_frame_extents (MetaWindow *window) +{ + unsigned long data[4]; + MetaFrameBorders borders; + + meta_frame_calc_borders (window->frame, &borders); + /* Left */ + data[0] = borders.visible.left; + /* Right */ + data[1] = borders.visible.right; + /* Top */ + data[2] = borders.visible.top; + /* Bottom */ + data[3] = borders.visible.bottom; + + meta_topic (META_DEBUG_GEOMETRY, + "Setting _NET_FRAME_EXTENTS on managed window 0x%lx " + "to left = %lu, right = %lu, top = %lu, bottom = %lu\n", + window->xwindow, data[0], data[1], data[2], data[3]); + + meta_error_trap_push (window->display); + XChangeProperty (window->display->xdisplay, window->xwindow, + window->display->atom__NET_FRAME_EXTENTS, + XA_CARDINAL, + 32, PropModeReplace, (guchar*) data, 4); + meta_error_trap_pop (window->display); +} + +#ifdef HAVE_XSYNC +static gboolean +sync_request_timeout (gpointer data) +{ + MetaWindow *window = data; + + window->sync_request_timeout_id = 0; + + /* We have now waited for more than a second for the + * application to respond to the sync request + */ + window->disable_sync = TRUE; + + /* Reset the wait serial, so we don't continue freezing + * window updates + */ + window->sync_request_wait_serial = 0; + meta_compositor_set_updates_frozen (window->display->compositor, window, + meta_window_updates_are_frozen (window)); + + if (window == window->display->grab_window && + meta_grab_op_is_resizing (window->display->grab_op)) + { + meta_window_update_resize (window, + window->display->grab_last_user_action_was_snap, + window->display->grab_latest_motion_x, + window->display->grab_latest_motion_y, + TRUE); + } + + return FALSE; +} + +static void +send_sync_request (MetaWindow *window) +{ + XClientMessageEvent ev; + gint64 wait_serial; + + /* For the old style of _NET_WM_SYNC_REQUEST_COUNTER, we just have to + * increase the value, but for the new "extended" style we need to + * pick an even (unfrozen) value sufficiently ahead of the last serial + * that we received from the client; the same code still works + * for the old style. The increment of 240 is specified by the EWMH + * and is (1 second) * (60fps) * (an increment of 4 per frame). + */ + wait_serial = window->sync_request_serial + 240; + + window->sync_request_wait_serial = wait_serial; + + ev.type = ClientMessage; + ev.window = window->xwindow; + ev.message_type = window->display->atom_WM_PROTOCOLS; + ev.format = 32; + ev.data.l[0] = window->display->atom__NET_WM_SYNC_REQUEST; + /* FIXME: meta_display_get_current_time() is bad, but since calls + * come from meta_window_move_resize_internal (which in turn come + * from all over), I'm not sure what we can do to fix it. Do we + * want to use _roundtrip, though? + */ + ev.data.l[1] = meta_display_get_current_time (window->display); + ev.data.l[2] = wait_serial & G_GUINT64_CONSTANT(0xffffffff); + ev.data.l[3] = wait_serial >> 32; + ev.data.l[4] = window->extended_sync_request_counter ? 1 : 0; + + /* We don't need to trap errors here as we are already + * inside an error_trap_push()/pop() pair. + */ + XSendEvent (window->display->xdisplay, + window->xwindow, False, 0, (XEvent*) &ev); + + /* We give the window 1 sec to respond to _NET_WM_SYNC_REQUEST; + * if this time expires, we consider the window unresponsive + * and resize it unsynchonized. + */ + window->sync_request_timeout_id = g_timeout_add (1000, + sync_request_timeout, + window); + + meta_compositor_set_updates_frozen (window->display->compositor, window, + meta_window_updates_are_frozen (window)); +} +#endif + +static void +meta_window_x11_move_resize_internal (MetaWindow *window, + int gravity, + MetaRectangle requested_rect, + MetaRectangle constrained_rect, + MetaMoveResizeFlags flags, + MetaMoveResizeResultFlags *result) +{ + int root_x_nw, root_y_nw; + int w, h; + int client_move_x, client_move_y; + int size_dx, size_dy; + XWindowChanges values; + unsigned int mask; + gboolean need_configure_notify; + MetaFrameBorders borders; + gboolean need_move_client = FALSE; + gboolean need_move_frame = FALSE; + gboolean need_resize_client = FALSE; + gboolean need_resize_frame = FALSE; + gboolean frame_shape_changed = FALSE; + gboolean configure_frame_first; + + gboolean is_configure_request; + + is_configure_request = (flags & META_IS_CONFIGURE_REQUEST) != 0; + + /* meta_window_constrain() might have maximized the window after placement, + * changing the borders. + */ + meta_frame_calc_borders (window->frame, &borders); + + root_x_nw = constrained_rect.x; + root_y_nw = constrained_rect.y; + w = constrained_rect.width; + h = constrained_rect.height; + + if (w != window->rect.width || + h != window->rect.height) + need_resize_client = TRUE; + + window->rect.width = w; + window->rect.height = h; + + if (window->frame) + { + int frame_size_dx, frame_size_dy; + int new_w, new_h; + + new_w = window->rect.width + borders.total.left + borders.total.right; + + if (window->shaded) + new_h = borders.total.top; + else + new_h = window->rect.height + borders.total.top + borders.total.bottom; + + frame_size_dx = new_w - window->frame->rect.width; + frame_size_dy = new_h - window->frame->rect.height; + + need_resize_frame = (frame_size_dx != 0 || frame_size_dy != 0); + + window->frame->rect.width = new_w; + window->frame->rect.height = new_h; + + meta_topic (META_DEBUG_GEOMETRY, + "Calculated frame size %dx%d\n", + window->frame->rect.width, + window->frame->rect.height); + } + + /* For nice effect, when growing the window we want to move/resize + * the frame first, when shrinking the window we want to move/resize + * the client first. If we grow one way and shrink the other, + * see which way we're moving "more" + * + * Mail from Owen subject "Suggestion: Gravity and resizing from the left" + * http://mail.gnome.org/archives/wm-spec-list/1999-November/msg00088.html + * + * An annoying fact you need to know in this code is that StaticGravity + * does nothing if you _only_ resize or _only_ move the frame; + * it must move _and_ resize, otherwise you get NorthWestGravity + * behavior. The move and resize must actually occur, it is not + * enough to set CWX | CWWidth but pass in the current size/pos. + */ + + if (window->frame) + { + int new_x, new_y; + int frame_pos_dx, frame_pos_dy; + + /* Compute new frame coords */ + new_x = root_x_nw - borders.total.left; + new_y = root_y_nw - borders.total.top; + + frame_pos_dx = new_x - window->frame->rect.x; + frame_pos_dy = new_y - window->frame->rect.y; + + need_move_frame = (frame_pos_dx != 0 || frame_pos_dy != 0); + + window->frame->rect.x = new_x; + window->frame->rect.y = new_y; + + /* If frame will both move and resize, then StaticGravity + * on the child window will kick in and implicitly move + * the child with respect to the frame. The implicit + * move will keep the child in the same place with + * respect to the root window. If frame only moves + * or only resizes, then the child will just move along + * with the frame. + */ + + /* window->rect.x, window->rect.y are relative to frame, + * remember they are the server coords + */ + + new_x = borders.total.left; + new_y = borders.total.top; + client_move_x = new_x; + client_move_y = new_y; + + if (client_move_x != window->rect.x || + client_move_y != window->rect.y) + need_move_client = TRUE; + + /* This is the final target position, but not necessarily what + * we pass to XConfigureWindow, due to StaticGravity implicit + * movement. + */ + window->rect.x = new_x; + window->rect.y = new_y; + } + else + { + if (root_x_nw != window->rect.x || + root_y_nw != window->rect.y) + need_move_client = TRUE; + + window->rect.x = root_x_nw; + window->rect.y = root_y_nw; + + client_move_x = window->rect.x; + client_move_y = window->rect.y; + } + + /* If frame extents have changed, fill in other frame fields and + change frame's extents property. */ + if (window->frame && + (window->frame->child_x != borders.total.left || + window->frame->child_y != borders.total.top || + window->frame->right_width != borders.total.right || + window->frame->bottom_height != borders.total.bottom)) + { + window->frame->child_x = borders.total.left; + window->frame->child_y = borders.total.top; + window->frame->right_width = borders.total.right; + window->frame->bottom_height = borders.total.bottom; + + update_net_frame_extents (window); + } + + /* See ICCCM 4.1.5 for when to send ConfigureNotify */ + + need_configure_notify = FALSE; + + /* If this is a configure request and we change nothing, then we + * must send configure notify. + */ + if (is_configure_request && + !(need_move_client || need_move_frame || + need_resize_client || need_resize_frame || + window->border_width != 0)) + need_configure_notify = TRUE; + + /* We must send configure notify if we move but don't resize, since + * the client window may not get a real event + */ + if ((need_move_client || need_move_frame) && + !(need_resize_client || need_resize_frame)) + need_configure_notify = TRUE; + + /* MapRequest events with a PPosition or UPosition hint with a frame + * are moved by mutter without resizing; send a configure notify + * in such cases. See #322840. (Note that window->constructing is + * only true iff this call is due to a MapRequest, and when + * PPosition/UPosition hints aren't set, mutter seems to send a + * ConfigureNotify anyway due to the above code.) + */ + if (window->constructing && window->frame && + ((window->size_hints.flags & PPosition) || + (window->size_hints.flags & USPosition))) + need_configure_notify = TRUE; + + /* The rest of this function syncs our new size/pos with X as + * efficiently as possible + */ + + /* Normally, we configure the frame first depending on whether + * we grow the frame more than we shrink. The idea is to avoid + * messing up the window contents by having a temporary situation + * where the frame is smaller than the window. However, if we're + * cooperating with the client to create an atomic frame upate, + * and the window is redirected, then we should always update + * the frame first, since updating the frame will force a new + * backing pixmap to be allocated, and the old backing pixmap + * will be left undisturbed for us to paint to the screen until + * the client finishes redrawing. + */ + if (window->extended_sync_request_counter) + { + configure_frame_first = TRUE; + } + else + { + size_dx = w - window->rect.width; + size_dy = h - window->rect.height; + + configure_frame_first = size_dx + size_dy >= 0; + } + + if (configure_frame_first && window->frame) + frame_shape_changed = meta_frame_sync_to_window (window->frame, + gravity, + need_move_frame, need_resize_frame); + + values.border_width = 0; + values.x = client_move_x; + values.y = client_move_y; + values.width = window->rect.width; + values.height = window->rect.height; + + mask = 0; + if (is_configure_request && window->border_width != 0) + mask |= CWBorderWidth; /* must force to 0 */ + if (need_move_client) + mask |= (CWX | CWY); + if (need_resize_client) + mask |= (CWWidth | CWHeight); + + if (mask != 0) + { + { + int newx, newy; + meta_window_get_position (window, &newx, &newy); + meta_topic (META_DEBUG_GEOMETRY, + "Syncing new client geometry %d,%d %dx%d, border: %s pos: %s size: %s\n", + newx, newy, + window->rect.width, window->rect.height, + mask & CWBorderWidth ? "true" : "false", + need_move_client ? "true" : "false", + need_resize_client ? "true" : "false"); + } + + meta_error_trap_push (window->display); + +#ifdef HAVE_XSYNC + if (window == window->display->grab_window && + meta_grab_op_is_resizing (window->display->grab_op) && + !window->disable_sync && + window->sync_request_counter != None && + window->sync_request_alarm != None && + window->sync_request_timeout_id == 0) + { + send_sync_request (window); + } +#endif + + XConfigureWindow (window->display->xdisplay, + window->xwindow, + mask, + &values); + + meta_error_trap_pop (window->display); + } + + if (!configure_frame_first && window->frame) + frame_shape_changed = meta_frame_sync_to_window (window->frame, + gravity, + need_move_frame, need_resize_frame); + + if (need_configure_notify) + send_configure_notify (window); + + if (frame_shape_changed) + *result |= META_MOVE_RESIZE_RESULT_FRAME_SHAPE_CHANGED; + if (need_move_client || need_move_frame) + *result |= META_MOVE_RESIZE_RESULT_MOVED; + if (need_resize_client || need_resize_frame) + *result |= META_MOVE_RESIZE_RESULT_RESIZED; +} + static void meta_window_x11_get_default_skip_hints (MetaWindow *window, gboolean *skip_taskbar_out, @@ -281,6 +744,7 @@ meta_window_x11_class_init (MetaWindowX11Class *klass) window_class->manage = meta_window_x11_manage; window_class->unmanage = meta_window_x11_unmanage; + window_class->move_resize_internal = meta_window_x11_move_resize_internal; window_class->get_default_skip_hints = meta_window_x11_get_default_skip_hints; } From 15c59f991943cfe2cf0bed62de7a3ae62e9a8e0b Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 20 Mar 2014 10:24:43 -0400 Subject: [PATCH 718/889] keybindings: Split out check for filter_keybinding This is a small code cleanup for clarity. --- src/core/keybindings.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/core/keybindings.c b/src/core/keybindings.c index c47178773..a574f6c5a 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -1680,8 +1680,13 @@ process_event (MetaDisplay *display, event->hardware_keycode, event->modifier_state); if (!binding || - (!window && binding->flags & META_KEY_BINDING_PER_WINDOW) || - meta_compositor_filter_keybinding (display->compositor, screen, binding)) + (!window && binding->flags & META_KEY_BINDING_PER_WINDOW)) + goto not_found; + + /* If the compositor filtered out the keybindings, that + * means they don't want the binding to trigger, so we do + * the same thing as if the binding didn't exist. */ + if (meta_compositor_filter_keybinding (display->compositor, screen, binding)) goto not_found; if (binding->handler == NULL) From 1b29113150a91b1b889047988f860ee58fe6c61d Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Tue, 11 Mar 2014 18:45:39 +0100 Subject: [PATCH 719/889] wayland: Set/unset wayland focus on mutter grab/ungrab operations This ensures that we send the proper leave and enter events to wayland clients. Particularly, this solves a bug in SSD xwayland windows where clicking and dragging on the title bar to move the window only works on the odd turn (unless the pointer moves away from the title bar between tries). This happens because xwayland gets a button press but doesn't see the release so when it gets the next button press it discards it because its pointer button tracking logic says that the button is already pressed. Sending the proper wayland pointer leave event fixes it since wayland clients must forget about button state at that point. https://bugzilla.gnome.org/show_bug.cgi?id=726123 --- src/compositor/compositor.c | 26 +++++++++++++---------- src/core/display-private.h | 2 ++ src/core/display.c | 42 ++++++++++++++++++++++++++----------- 3 files changed, 47 insertions(+), 23 deletions(-) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 6a4904323..6a5fb46ee 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -426,11 +426,8 @@ meta_begin_modal_for_plugin (MetaScreen *screen, if (is_modal (display) || display->grab_op != META_GRAB_OP_NONE) return FALSE; - if (meta_is_wayland_compositor ()) - ok = TRUE; - else - ok = begin_modal_x11 (screen, plugin, options, timestamp); - if (!ok) + if (!meta_is_wayland_compositor () && + !begin_modal_x11 (screen, plugin, options, timestamp)) return FALSE; display->grab_op = META_GRAB_OP_COMPOSITOR; @@ -439,6 +436,9 @@ meta_begin_modal_for_plugin (MetaScreen *screen, display->grab_have_pointer = TRUE; display->grab_have_keyboard = TRUE; + if (meta_is_wayland_compositor ()) + meta_display_sync_wayland_input_focus (display); + return TRUE; } @@ -452,17 +452,21 @@ meta_end_modal_for_plugin (MetaScreen *screen, g_return_if_fail (is_modal (display)); - if (!meta_is_wayland_compositor ()) - { - XIUngrabDevice (xdpy, META_VIRTUAL_CORE_POINTER_ID, timestamp); - XIUngrabDevice (xdpy, META_VIRTUAL_CORE_KEYBOARD_ID, timestamp); - } - display->grab_op = META_GRAB_OP_NONE; display->grab_window = NULL; display->grab_screen = NULL; display->grab_have_pointer = FALSE; display->grab_have_keyboard = FALSE; + + if (meta_is_wayland_compositor ()) + { + meta_display_sync_wayland_input_focus (display); + } + else + { + XIUngrabDevice (xdpy, META_VIRTUAL_CORE_POINTER_ID, timestamp); + XIUngrabDevice (xdpy, META_VIRTUAL_CORE_KEYBOARD_ID, timestamp); + } } static void diff --git a/src/core/display-private.h b/src/core/display-private.h index 096304f3f..14725c1e8 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -486,4 +486,6 @@ void meta_display_set_input_focus_xwindow (MetaDisplay *display, Window window, guint32 timestamp); +void meta_display_sync_wayland_input_focus (MetaDisplay *display); + #endif diff --git a/src/core/display.c b/src/core/display.c index 489ca9ff7..58dede3d1 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -1742,6 +1742,29 @@ get_input_event (MetaDisplay *display, return NULL; } +void +meta_display_sync_wayland_input_focus (MetaDisplay *display) +{ + MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); + MetaWindow *focus_window; + + if (display->grab_op != META_GRAB_OP_NONE) + focus_window = NULL; + else if (meta_display_xwindow_is_a_no_focus_window (display, display->focus_xwindow)) + focus_window = NULL; + else if (display->focus_window && display->focus_window->surface) + focus_window = display->focus_window; + else + meta_topic (META_DEBUG_FOCUS, "Focus change has no effect, because there is no matching wayland surface"); + + meta_wayland_compositor_set_input_focus (compositor, focus_window); + + if (display->grab_op != META_GRAB_OP_NONE) + meta_wayland_pointer_set_focus (&compositor->seat->pointer, NULL); + else + meta_wayland_seat_repick (compositor->seat, NULL); +} + static void update_focus_window (MetaDisplay *display, MetaWindow *window, @@ -1749,8 +1772,6 @@ update_focus_window (MetaDisplay *display, gulong serial, gboolean focused_by_us) { - MetaWaylandCompositor *compositor; - display->focus_serial = serial; display->focused_by_us = focused_by_us; @@ -1790,16 +1811,7 @@ update_focus_window (MetaDisplay *display, meta_topic (META_DEBUG_FOCUS, "* Focus --> NULL with serial %lu\n", serial); if (meta_is_wayland_compositor ()) - { - compositor = meta_wayland_compositor_get_default (); - - if (meta_display_xwindow_is_a_no_focus_window (display, xwindow)) - meta_wayland_compositor_set_input_focus (compositor, NULL); - else if (window && window->surface) - meta_wayland_compositor_set_input_focus (compositor, window); - else - meta_topic (META_DEBUG_FOCUS, "Focus change has no effect, because there is no matching wayland surface"); - } + meta_display_sync_wayland_input_focus (display); g_object_notify (G_OBJECT (display), "focus-window"); meta_display_update_active_window_hint (display); @@ -4070,6 +4082,9 @@ meta_display_begin_grab_op (MetaDisplay *display, meta_window_refresh_resize_popup (display->grab_window); } + if (meta_is_wayland_compositor ()) + meta_display_sync_wayland_input_focus (display); + g_signal_emit (display, display_signals[GRAB_OP_BEGIN], 0, screen, display->grab_window, display->grab_op); @@ -4163,6 +4178,9 @@ meta_display_end_grab_op (MetaDisplay *display, g_source_remove (display->grab_resize_timeout_id); display->grab_resize_timeout_id = 0; } + + if (meta_is_wayland_compositor ()) + meta_display_sync_wayland_input_focus (display); } /** From 89685010313c2c902d4a0f2856138507112c1559 Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Sun, 16 Mar 2014 20:32:52 +0100 Subject: [PATCH 720/889] wayland-seat: Don't send pointer enter/leave events during a GRAB_OP meta_wayland_seat_repick() can be called in various cases while mutter has a GRAB_OP ongoing which means we could be sending wrong pointer enter/leave events. https://bugzilla.gnome.org/show_bug.cgi?id=726123 --- src/wayland/meta-wayland-pointer.c | 13 +++++++++++++ src/wayland/meta-wayland-pointer.h | 4 ++++ src/wayland/meta-wayland-seat.c | 15 ++++++++------- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index 336cea023..9e423a4e6 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -583,3 +583,16 @@ meta_wayland_pointer_get_relative_coordinates (MetaWaylandPointer *pointer, *sx = wl_fixed_from_double (xf); *sy = wl_fixed_from_double (yf); } + +void +meta_wayland_pointer_update_current_focus (MetaWaylandPointer *pointer, + MetaWaylandSurface *surface) +{ + pointer->current = surface; + if (surface != pointer->focus_surface) + { + const MetaWaylandPointerGrabInterface *interface = + pointer->grab->interface; + interface->focus (pointer->grab, surface); + } +} diff --git a/src/wayland/meta-wayland-pointer.h b/src/wayland/meta-wayland-pointer.h index 5eb6756e9..d5e303838 100644 --- a/src/wayland/meta-wayland-pointer.h +++ b/src/wayland/meta-wayland-pointer.h @@ -94,4 +94,8 @@ meta_wayland_pointer_get_relative_coordinates (MetaWaylandPointer *pointer, wl_fixed_t *x, wl_fixed_t *y); +void +meta_wayland_pointer_update_current_focus (MetaWaylandPointer *pointer, + MetaWaylandSurface *surface); + #endif /* __META_WAYLAND_POINTER_H__ */ diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c index 85c244b30..4b08e4ac3 100644 --- a/src/wayland/meta-wayland-seat.c +++ b/src/wayland/meta-wayland-seat.c @@ -434,6 +434,13 @@ meta_wayland_seat_repick (MetaWaylandSeat *seat, ClutterActor *actor = NULL; MetaWaylandPointer *pointer = &seat->pointer; MetaWaylandSurface *surface = NULL; + MetaDisplay *display = meta_get_display (); + + if (display->grab_op != META_GRAB_OP_NONE) + { + meta_wayland_pointer_update_current_focus (pointer, NULL); + return; + } if (for_event) { @@ -456,13 +463,7 @@ meta_wayland_seat_repick (MetaWaylandSeat *seat, if (META_IS_SURFACE_ACTOR_WAYLAND (actor)) surface = meta_surface_actor_wayland_get_surface (META_SURFACE_ACTOR_WAYLAND (actor)); - pointer->current = surface; - if (surface != pointer->focus_surface) - { - const MetaWaylandPointerGrabInterface *interface = - pointer->grab->interface; - interface->focus (pointer->grab, surface); - } + meta_wayland_pointer_update_current_focus (pointer, surface); } void From 76dc0ca681819e2cbb7f422c6a7f4fef6aeea0e1 Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Mon, 17 Mar 2014 20:53:19 +0100 Subject: [PATCH 721/889] wayland: Exempt CLICKING grab ops when syncing wayland input focus If we have a CLICKING grab op we still need to send events to xwayland so that we get them back for gtk+ to process thus we can't steer wayland input focus away from it. https://bugzilla.gnome.org/show_bug.cgi?id=726123 --- src/compositor/compositor.c | 25 +------------------------ src/core/display-private.h | 2 ++ src/core/display.c | 33 +++++++++++++++++++++++++++++++-- src/wayland/meta-wayland-seat.c | 2 +- 4 files changed, 35 insertions(+), 27 deletions(-) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 6a5fb46ee..2d798755f 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -847,29 +847,6 @@ meta_compositor_window_surface_changed (MetaCompositor *compositor, meta_window_actor_update_surface (window_actor); } -static gboolean -grab_op_is_clicking (MetaGrabOp grab_op) -{ - switch (grab_op) - { - case META_GRAB_OP_CLICKING_MINIMIZE: - case META_GRAB_OP_CLICKING_MAXIMIZE: - case META_GRAB_OP_CLICKING_UNMAXIMIZE: - case META_GRAB_OP_CLICKING_DELETE: - case META_GRAB_OP_CLICKING_MENU: - case META_GRAB_OP_CLICKING_SHADE: - case META_GRAB_OP_CLICKING_UNSHADE: - case META_GRAB_OP_CLICKING_ABOVE: - case META_GRAB_OP_CLICKING_UNABOVE: - case META_GRAB_OP_CLICKING_STICK: - case META_GRAB_OP_CLICKING_UNSTICK: - return TRUE; - - default: - return FALSE; - } -} - static gboolean event_is_passive_button_grab (MetaDisplay *display, XIDeviceEvent *device_event) @@ -925,7 +902,7 @@ maybe_spoof_event_as_stage_event (MetaCompScreen *info, /* If this is a window frame, and we think GTK+ needs to handle the event, let GTK+ handle it without mangling */ if (window && window->frame && device_event->event == window->frame->xwindow && - (grab_op_is_clicking (display->grab_op) || + (meta_grab_op_is_clicking (display->grab_op) || (display->grab_op == META_GRAB_OP_NONE && !event_is_passive_button_grab (display, device_event)))) break; diff --git a/src/core/display-private.h b/src/core/display-private.h index 14725c1e8..c4548fcd0 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -454,6 +454,8 @@ int meta_resize_gravity_from_grab_op (MetaGrabOp op); gboolean meta_grab_op_is_moving (MetaGrabOp op); gboolean meta_grab_op_is_resizing (MetaGrabOp op); gboolean meta_grab_op_is_mouse (MetaGrabOp op); +gboolean meta_grab_op_is_clicking (MetaGrabOp op); +gboolean meta_grab_op_is_wayland (MetaGrabOp op); void meta_display_devirtualize_modifiers (MetaDisplay *display, MetaVirtualModifier modifiers, diff --git a/src/core/display.c b/src/core/display.c index 58dede3d1..67efd2c9c 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -1424,6 +1424,35 @@ grab_op_should_block_mouse_events (MetaGrabOp op) } } +gboolean +meta_grab_op_is_clicking (MetaGrabOp grab_op) +{ + switch (grab_op) + { + case META_GRAB_OP_CLICKING_MINIMIZE: + case META_GRAB_OP_CLICKING_MAXIMIZE: + case META_GRAB_OP_CLICKING_UNMAXIMIZE: + case META_GRAB_OP_CLICKING_DELETE: + case META_GRAB_OP_CLICKING_MENU: + case META_GRAB_OP_CLICKING_SHADE: + case META_GRAB_OP_CLICKING_UNSHADE: + case META_GRAB_OP_CLICKING_ABOVE: + case META_GRAB_OP_CLICKING_UNABOVE: + case META_GRAB_OP_CLICKING_STICK: + case META_GRAB_OP_CLICKING_UNSTICK: + return TRUE; + + default: + return FALSE; + } +} + +gboolean +meta_grab_op_is_wayland (MetaGrabOp op) +{ + return (op != META_GRAB_OP_NONE && !meta_grab_op_is_clicking (op)); +} + /** * meta_display_xserver_time_is_before: * @display: a #MetaDisplay @@ -1748,7 +1777,7 @@ meta_display_sync_wayland_input_focus (MetaDisplay *display) MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); MetaWindow *focus_window; - if (display->grab_op != META_GRAB_OP_NONE) + if (meta_grab_op_is_wayland (display->grab_op)) focus_window = NULL; else if (meta_display_xwindow_is_a_no_focus_window (display, display->focus_xwindow)) focus_window = NULL; @@ -1759,7 +1788,7 @@ meta_display_sync_wayland_input_focus (MetaDisplay *display) meta_wayland_compositor_set_input_focus (compositor, focus_window); - if (display->grab_op != META_GRAB_OP_NONE) + if (meta_grab_op_is_wayland (display->grab_op)) meta_wayland_pointer_set_focus (&compositor->seat->pointer, NULL); else meta_wayland_seat_repick (compositor->seat, NULL); diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c index 4b08e4ac3..8ec7b2b75 100644 --- a/src/wayland/meta-wayland-seat.c +++ b/src/wayland/meta-wayland-seat.c @@ -436,7 +436,7 @@ meta_wayland_seat_repick (MetaWaylandSeat *seat, MetaWaylandSurface *surface = NULL; MetaDisplay *display = meta_get_display (); - if (display->grab_op != META_GRAB_OP_NONE) + if (meta_grab_op_is_wayland (display->grab_op)) { meta_wayland_pointer_update_current_focus (pointer, NULL); return; From ca4777f77860155bbc114bee6faa12edc0ce7e1d Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 20 Mar 2014 13:18:47 -0400 Subject: [PATCH 722/889] compositor: Make code a bit more understandable --- src/compositor/compositor.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 2d798755f..0a20a0637 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -426,9 +426,9 @@ meta_begin_modal_for_plugin (MetaScreen *screen, if (is_modal (display) || display->grab_op != META_GRAB_OP_NONE) return FALSE; - if (!meta_is_wayland_compositor () && - !begin_modal_x11 (screen, plugin, options, timestamp)) - return FALSE; + if (!meta_is_wayland_compositor ()) + if (!begin_modal_x11 (screen, plugin, options, timestamp)) + return FALSE; display->grab_op = META_GRAB_OP_COMPOSITOR; display->grab_window = NULL; From e67abdd3ff140c91a3f54b8b1b016f559437e247 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 20 Mar 2014 13:18:55 -0400 Subject: [PATCH 723/889] compositor: Kill unused variable --- src/compositor/compositor.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 0a20a0637..3881ff941 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -421,7 +421,6 @@ meta_begin_modal_for_plugin (MetaScreen *screen, * merge the two. */ MetaDisplay *display = meta_screen_get_display (screen); - gboolean ok; if (is_modal (display) || display->grab_op != META_GRAB_OP_NONE) return FALSE; From 57359da9b43d543cee05688a6b2d3ae4d3980fdb Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 20 Mar 2014 13:20:47 -0400 Subject: [PATCH 724/889] wayland: Kill the buffer destroy error Previously, a sequence like this would crash a client: => surface.attach(buffer) => buffer.destroy() The correct behavior is to wait until we release the buffer before destroying it. => surface.attach(buffer) => surface.attach(buffer2) <= buffer.release() => buffer.destroy() The protocol upstream says that "the surface contents are undefined" in a case like this. Personally, I think that this is broken behavior and no client should ever do it, so I explicitly killed any client that tried to do this. But unfortunately, as we're all well aware, XWayland does this. Rather than wait for XWayland to be fixed, let's just allow this. Technically, since we always copy SHM buffers into GL textures, we could release the buffer as soon as the Cogl texture is made. Since we do this copy, the semantics we apply are that the texture is "frozen" in time until another newer buffer is attached. For simple clients that simply abort on exit and don't wait for the buffer event anyhow, this has the added bonus that we'll get nice destroy animations. --- src/compositor/meta-surface-actor-wayland.c | 45 ++++++++++++++++----- src/wayland/meta-wayland-surface.c | 18 ++++----- src/wayland/meta-wayland.c | 1 - 3 files changed, 43 insertions(+), 21 deletions(-) diff --git a/src/compositor/meta-surface-actor-wayland.c b/src/compositor/meta-surface-actor-wayland.c index bdd8df05c..875dd1c6b 100644 --- a/src/compositor/meta-surface-actor-wayland.c +++ b/src/compositor/meta-surface-actor-wayland.c @@ -35,11 +35,24 @@ struct _MetaSurfaceActorWaylandPrivate { MetaWaylandSurface *surface; MetaWaylandBuffer *buffer; + struct wl_listener buffer_destroy_listener; }; typedef struct _MetaSurfaceActorWaylandPrivate MetaSurfaceActorWaylandPrivate; G_DEFINE_TYPE_WITH_PRIVATE (MetaSurfaceActorWayland, meta_surface_actor_wayland, META_TYPE_SURFACE_ACTOR) +static void +meta_surface_actor_handle_buffer_destroy (struct wl_listener *listener, void *data) +{ + MetaSurfaceActorWaylandPrivate *priv = wl_container_of (listener, priv, buffer_destroy_listener); + + /* If the buffer is destroyed while we're attached to it, + * we want to unset priv->buffer so we don't access freed + * memory. Keep the texture set however so the user doesn't + * see the window disappear. */ + priv->buffer = NULL; +} + static void meta_surface_actor_wayland_process_damage (MetaSurfaceActor *actor, int x, int y, int width, int height) @@ -47,16 +60,19 @@ meta_surface_actor_wayland_process_damage (MetaSurfaceActor *actor, MetaSurfaceActorWayland *self = META_SURFACE_ACTOR_WAYLAND (actor); MetaSurfaceActorWaylandPrivate *priv = meta_surface_actor_wayland_get_instance_private (self); - struct wl_resource *resource = priv->buffer->resource; - struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get (resource); - - if (shm_buffer) + if (priv->buffer) { - CoglTexture2D *texture = COGL_TEXTURE_2D (priv->buffer->texture); - cogl_wayland_texture_set_region_from_shm_buffer (texture, x, y, width, height, shm_buffer, x, y, 0, NULL); - } + struct wl_resource *resource = priv->buffer->resource; + struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get (resource); - meta_surface_actor_update_area (META_SURFACE_ACTOR (self), x, y, width, height); + if (shm_buffer) + { + CoglTexture2D *texture = COGL_TEXTURE_2D (priv->buffer->texture); + cogl_wayland_texture_set_region_from_shm_buffer (texture, x, y, width, height, shm_buffer, x, y, 0, NULL); + } + + meta_surface_actor_update_area (META_SURFACE_ACTOR (self), x, y, width, height); + } } static void @@ -127,6 +143,9 @@ meta_surface_actor_wayland_class_init (MetaSurfaceActorWaylandClass *klass) static void meta_surface_actor_wayland_init (MetaSurfaceActorWayland *self) { + MetaSurfaceActorWaylandPrivate *priv = meta_surface_actor_wayland_get_instance_private (self); + + priv->buffer_destroy_listener.notify = meta_surface_actor_handle_buffer_destroy; } MetaSurfaceActor * @@ -149,10 +168,16 @@ meta_surface_actor_wayland_set_buffer (MetaSurfaceActorWayland *self, MetaSurfaceActorWaylandPrivate *priv = meta_surface_actor_wayland_get_instance_private (self); MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self)); + if (priv->buffer) + wl_list_remove (&priv->buffer_destroy_listener.link); + priv->buffer = buffer; - if (buffer) - meta_shaped_texture_set_texture (stex, buffer->texture); + if (priv->buffer) + { + wl_signal_add (&priv->buffer->destroy_signal, &priv->buffer_destroy_listener); + meta_shaped_texture_set_texture (stex, priv->buffer->texture); + } else meta_shaped_texture_set_texture (stex, NULL); } diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 940c32f0f..739c17133 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -74,16 +74,6 @@ typedef struct struct wl_listener sibling_destroy_listener; } MetaWaylandSubsurfacePlacementOp; -static void -surface_handle_buffer_destroy (struct wl_listener *listener, void *data) -{ - MetaWaylandSurface *surface = wl_container_of (listener, surface, buffer_destroy_listener); - - wl_resource_post_error (surface->resource, WL_DISPLAY_ERROR_INVALID_OBJECT, - "Destroyed buffer while it was attached to the surface"); - surface->buffer = NULL; -} - static void surface_set_buffer (MetaWaylandSurface *surface, MetaWaylandBuffer *buffer) @@ -106,6 +96,14 @@ surface_set_buffer (MetaWaylandSurface *surface, } } +static void +surface_handle_buffer_destroy (struct wl_listener *listener, void *data) +{ + MetaWaylandSurface *surface = wl_container_of (listener, surface, buffer_destroy_listener); + + surface_set_buffer (surface, NULL); +} + static void surface_process_damage (MetaWaylandSurface *surface, cairo_region_t *region) diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index a01d6f971..79ebd302d 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -151,7 +151,6 @@ meta_wayland_buffer_unref (MetaWaylandBuffer *buffer) if (buffer->ref_count == 0) { g_clear_pointer (&buffer->texture, cogl_object_unref); - g_assert (wl_resource_get_client (buffer->resource)); wl_resource_queue_event (buffer->resource, WL_BUFFER_RELEASE); } } From 9debd2fb0d2618774a1a9b721df67a5dbdfe092c Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 20 Mar 2014 15:07:44 -0400 Subject: [PATCH 725/889] Move delete / kill to be a vfunc --- src/core/delete.c | 51 ++------------------------------- src/core/window-private.h | 3 ++ src/wayland/window-wayland.c | 15 ++++++++++ src/x11/window-x11.c | 55 ++++++++++++++++++++++++++++++++++++ 4 files changed, 75 insertions(+), 49 deletions(-) diff --git a/src/core/delete.c b/src/core/delete.c index 136e564ea..8b5070796 100644 --- a/src/core/delete.c +++ b/src/core/delete.c @@ -143,31 +143,7 @@ void meta_window_delete (MetaWindow *window, guint32 timestamp) { - if (window->client_type == META_WINDOW_CLIENT_TYPE_X11) - { - meta_error_trap_push (window->display); - if (window->delete_window) - { - meta_topic (META_DEBUG_WINDOW_OPS, - "Deleting %s with delete_window request\n", - window->desc); - meta_window_send_icccm_message (window, - window->display->atom_WM_DELETE_WINDOW, - timestamp); - } - else - { - meta_topic (META_DEBUG_WINDOW_OPS, - "Deleting %s with explicit kill\n", - window->desc); - XKillClient (window->display->xdisplay, window->xwindow); - } - meta_error_trap_pop (window->display); - } - else - { - meta_wayland_surface_delete (window->surface); - } + META_WINDOW_GET_CLASS (window)->delete (window, timestamp); meta_window_check_alive (window, timestamp); @@ -200,33 +176,10 @@ meta_window_delete (MetaWindow *window, } } - void meta_window_kill (MetaWindow *window) { - meta_topic (META_DEBUG_WINDOW_OPS, - "Killing %s brutally\n", - window->desc); - - if (!meta_window_is_remote (window) && - window->net_wm_pid > 0) - { - meta_topic (META_DEBUG_WINDOW_OPS, - "Killing %s with kill()\n", - window->desc); - - if (kill (window->net_wm_pid, 9) < 0) - meta_topic (META_DEBUG_WINDOW_OPS, - "Failed to signal %s: %s\n", - window->desc, strerror (errno)); - } - - meta_topic (META_DEBUG_WINDOW_OPS, - "Disconnecting %s with XKillClient()\n", - window->desc); - meta_error_trap_push (window->display); - XKillClient (window->display->xdisplay, window->xwindow); - meta_error_trap_pop (window->display); + META_WINDOW_GET_CLASS (window)->kill (window); } void diff --git a/src/core/window-private.h b/src/core/window-private.h index aa57332eb..82bfbdebf 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -471,6 +471,9 @@ struct _MetaWindowClass void (*manage) (MetaWindow *window); void (*unmanage) (MetaWindow *window); + void (*delete) (MetaWindow *window, + guint32 timestamp); + void (*kill) (MetaWindow *window); void (*move_resize_internal) (MetaWindow *window, int gravity, MetaRectangle requested_rect, diff --git a/src/wayland/window-wayland.c b/src/wayland/window-wayland.c index 8b75da743..eea45f31e 100644 --- a/src/wayland/window-wayland.c +++ b/src/wayland/window-wayland.c @@ -75,6 +75,19 @@ meta_window_wayland_unmanage (MetaWindow *window) meta_display_unregister_wayland_window (window->display, window); } +static void +meta_window_wayland_delete (MetaWindow *window, + guint32 timestamp) +{ + meta_wayland_surface_delete (window->surface); +} + +static void +meta_window_wayland_kill (MetaWindow *window) +{ + /* TODO */ +} + static void meta_window_wayland_move_resize_internal (MetaWindow *window, int gravity, @@ -176,5 +189,7 @@ meta_window_wayland_class_init (MetaWindowWaylandClass *klass) window_class->manage = meta_window_wayland_manage; window_class->unmanage = meta_window_wayland_unmanage; + window_class->delete = meta_window_wayland_delete; + window_class->kill = meta_window_wayland_kill; window_class->move_resize_internal = meta_window_wayland_move_resize_internal; } diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c index 86491a665..e95fdec3a 100644 --- a/src/x11/window-x11.c +++ b/src/x11/window-x11.c @@ -322,6 +322,59 @@ meta_window_x11_unmanage (MetaWindow *window) meta_error_trap_pop (window->display); } +static void +meta_window_x11_delete (MetaWindow *window, + guint32 timestamp) +{ + meta_error_trap_push (window->display); + if (window->delete_window) + { + meta_topic (META_DEBUG_WINDOW_OPS, + "Deleting %s with delete_window request\n", + window->desc); + meta_window_send_icccm_message (window, + window->display->atom_WM_DELETE_WINDOW, + timestamp); + } + else + { + meta_topic (META_DEBUG_WINDOW_OPS, + "Deleting %s with explicit kill\n", + window->desc); + XKillClient (window->display->xdisplay, window->xwindow); + } + meta_error_trap_pop (window->display); +} + +static void +meta_window_x11_kill (MetaWindow *window) +{ + meta_topic (META_DEBUG_WINDOW_OPS, + "Killing %s brutally\n", + window->desc); + + if (!meta_window_is_remote (window) && + window->net_wm_pid > 0) + { + meta_topic (META_DEBUG_WINDOW_OPS, + "Killing %s with kill()\n", + window->desc); + + if (kill (window->net_wm_pid, 9) < 0) + meta_topic (META_DEBUG_WINDOW_OPS, + "Failed to signal %s: %s\n", + window->desc, strerror (errno)); + } + + meta_topic (META_DEBUG_WINDOW_OPS, + "Disconnecting %s with XKillClient()\n", + window->desc); + + meta_error_trap_push (window->display); + XKillClient (window->display->xdisplay, window->xwindow); + meta_error_trap_pop (window->display); +} + static void update_net_frame_extents (MetaWindow *window) { @@ -744,6 +797,8 @@ meta_window_x11_class_init (MetaWindowX11Class *klass) window_class->manage = meta_window_x11_manage; window_class->unmanage = meta_window_x11_unmanage; + window_class->delete = meta_window_x11_delete; + window_class->kill = meta_window_x11_kill; window_class->move_resize_internal = meta_window_x11_move_resize_internal; window_class->get_default_skip_hints = meta_window_x11_get_default_skip_hints; } From 14f424cd02fa174c5654cee33c29f738b55fc319 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 20 Mar 2014 15:12:44 -0400 Subject: [PATCH 726/889] Move ping to be a vfunc --- src/core/display.c | 7 +------ src/core/window-private.h | 2 ++ src/wayland/window-wayland.c | 8 ++++++++ src/x11/window-x11.c | 12 ++++++++++++ 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/core/display.c b/src/core/display.c index 67efd2c9c..287f1f565 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -4701,12 +4701,7 @@ meta_display_ping_window (MetaWindow *window, "Sending ping with timestamp %u to window %s\n", timestamp, window->desc); - if (window->client_type == META_WINDOW_CLIENT_TYPE_X11) - meta_window_send_icccm_message (window, - display->atom__NET_WM_PING, - timestamp); - else - meta_wayland_surface_ping (window->surface, timestamp); + META_WINDOW_GET_CLASS (window)->ping (window, timestamp); } static void diff --git a/src/core/window-private.h b/src/core/window-private.h index 82bfbdebf..c6e4adc8c 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -471,6 +471,8 @@ struct _MetaWindowClass void (*manage) (MetaWindow *window); void (*unmanage) (MetaWindow *window); + void (*ping) (MetaWindow *window, + guint32 serial); void (*delete) (MetaWindow *window, guint32 timestamp); void (*kill) (MetaWindow *window); diff --git a/src/wayland/window-wayland.c b/src/wayland/window-wayland.c index eea45f31e..32c511e40 100644 --- a/src/wayland/window-wayland.c +++ b/src/wayland/window-wayland.c @@ -75,6 +75,13 @@ meta_window_wayland_unmanage (MetaWindow *window) meta_display_unregister_wayland_window (window->display, window); } +static void +meta_window_wayland_ping (MetaWindow *window, + guint32 serial) +{ + meta_wayland_surface_ping (window->surface, serial); +} + static void meta_window_wayland_delete (MetaWindow *window, guint32 timestamp) @@ -189,6 +196,7 @@ meta_window_wayland_class_init (MetaWindowWaylandClass *klass) window_class->manage = meta_window_wayland_manage; window_class->unmanage = meta_window_wayland_unmanage; + window_class->ping = meta_window_wayland_ping; window_class->delete = meta_window_wayland_delete; window_class->kill = meta_window_wayland_kill; window_class->move_resize_internal = meta_window_wayland_move_resize_internal; diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c index e95fdec3a..a7e438145 100644 --- a/src/x11/window-x11.c +++ b/src/x11/window-x11.c @@ -322,6 +322,17 @@ meta_window_x11_unmanage (MetaWindow *window) meta_error_trap_pop (window->display); } +static void +meta_window_x11_ping (MetaWindow *window, + guint32 serial) +{ + MetaDisplay *display = window->display; + + meta_window_send_icccm_message (window, + display->atom__NET_WM_PING, + serial); +} + static void meta_window_x11_delete (MetaWindow *window, guint32 timestamp) @@ -797,6 +808,7 @@ meta_window_x11_class_init (MetaWindowX11Class *klass) window_class->manage = meta_window_x11_manage; window_class->unmanage = meta_window_x11_unmanage; + window_class->ping = meta_window_x11_ping; window_class->delete = meta_window_x11_delete; window_class->kill = meta_window_x11_kill; window_class->move_resize_internal = meta_window_x11_move_resize_internal; From 0808adefafde263dcf6d8414b8b91d44b1bf950d Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 20 Mar 2014 15:16:57 -0400 Subject: [PATCH 727/889] Move focus to be a vfunc --- src/core/window-private.h | 2 ++ src/core/window.c | 64 +-------------------------------- src/wayland/window-wayland.c | 11 ++++++ src/x11/window-x11.c | 70 ++++++++++++++++++++++++++++++++++++ 4 files changed, 84 insertions(+), 63 deletions(-) diff --git a/src/core/window-private.h b/src/core/window-private.h index c6e4adc8c..56d902d6a 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -476,6 +476,8 @@ struct _MetaWindowClass void (*delete) (MetaWindow *window, guint32 timestamp); void (*kill) (MetaWindow *window); + void (*focus) (MetaWindow *window, + guint32 timestamp); void (*move_resize_internal) (MetaWindow *window, int gravity, MetaRectangle requested_rect, diff --git a/src/core/window.c b/src/core/window.c index 3c4c53966..12a3f2aec 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -5090,69 +5090,7 @@ meta_window_focus (MetaWindow *window, return; } - /* For output-only or shaded windows, focus the frame. - * This seems to result in the client window getting key events - * though, so I don't know if it's icccm-compliant. - * - * Still, we have to do this or keynav breaks for these windows. - */ - if (window->frame && - (window->shaded || - !(window->input || window->take_focus))) - { - if (window->frame) - { - meta_topic (META_DEBUG_FOCUS, - "Focusing frame of %s\n", window->desc); - meta_display_set_input_focus_window (window->display, - window, - TRUE, - timestamp); - } - } - else - { - if (window->input) - { - meta_topic (META_DEBUG_FOCUS, - "Setting input focus on %s since input = true\n", - window->desc); - meta_display_set_input_focus_window (window->display, - window, - FALSE, - timestamp); - } - - if (window->take_focus) - { - meta_topic (META_DEBUG_FOCUS, - "Sending WM_TAKE_FOCUS to %s since take_focus = true\n", - window->desc); - - if (!window->input) - { - /* The "Globally Active Input" window case, where the window - * doesn't want us to call XSetInputFocus on it, but does - * want us to send a WM_TAKE_FOCUS. - * - * Normally, we want to just leave the focus undisturbed until - * the window respnds to WM_TAKE_FOCUS, but if we're unmanaging - * the current focus window we *need* to move the focus away, so - * we focus the no_focus_window now (and set - * display->focus_window to that) before sending WM_TAKE_FOCUS. - */ - if (window->display->focus_window != NULL && - window->display->focus_window->unmanaging) - meta_display_focus_the_no_focus_window (window->display, - window->screen, - timestamp); - } - - meta_display_request_take_focus (window->display, - window, - timestamp); - } - } + META_WINDOW_GET_CLASS (window)->focus (window, timestamp); if (window->wm_state_demands_attention) meta_window_unset_demands_attention(window); diff --git a/src/wayland/window-wayland.c b/src/wayland/window-wayland.c index 32c511e40..2eaaf017f 100644 --- a/src/wayland/window-wayland.c +++ b/src/wayland/window-wayland.c @@ -95,6 +95,16 @@ meta_window_wayland_kill (MetaWindow *window) /* TODO */ } +static void +meta_window_wayland_focus (MetaWindow *window, + guint32 timestamp) +{ + meta_display_set_input_focus_window (window->display, + window, + FALSE, + timestamp); +} + static void meta_window_wayland_move_resize_internal (MetaWindow *window, int gravity, @@ -199,5 +209,6 @@ meta_window_wayland_class_init (MetaWindowWaylandClass *klass) window_class->ping = meta_window_wayland_ping; window_class->delete = meta_window_wayland_delete; window_class->kill = meta_window_wayland_kill; + window_class->focus = meta_window_wayland_focus; window_class->move_resize_internal = meta_window_wayland_move_resize_internal; } diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c index a7e438145..aae590609 100644 --- a/src/x11/window-x11.c +++ b/src/x11/window-x11.c @@ -386,6 +386,75 @@ meta_window_x11_kill (MetaWindow *window) meta_error_trap_pop (window->display); } +static void +meta_window_x11_focus (MetaWindow *window, + guint32 timestamp) +{ + /* For output-only or shaded windows, focus the frame. + * This seems to result in the client window getting key events + * though, so I don't know if it's icccm-compliant. + * + * Still, we have to do this or keynav breaks for these windows. + */ + if (window->frame && + (window->shaded || + !(window->input || window->take_focus))) + { + if (window->frame) + { + meta_topic (META_DEBUG_FOCUS, + "Focusing frame of %s\n", window->desc); + meta_display_set_input_focus_window (window->display, + window, + TRUE, + timestamp); + } + } + else + { + if (window->input) + { + meta_topic (META_DEBUG_FOCUS, + "Setting input focus on %s since input = true\n", + window->desc); + meta_display_set_input_focus_window (window->display, + window, + FALSE, + timestamp); + } + + if (window->take_focus) + { + meta_topic (META_DEBUG_FOCUS, + "Sending WM_TAKE_FOCUS to %s since take_focus = true\n", + window->desc); + + if (!window->input) + { + /* The "Globally Active Input" window case, where the window + * doesn't want us to call XSetInputFocus on it, but does + * want us to send a WM_TAKE_FOCUS. + * + * Normally, we want to just leave the focus undisturbed until + * the window respnds to WM_TAKE_FOCUS, but if we're unmanaging + * the current focus window we *need* to move the focus away, so + * we focus the no_focus_window now (and set + * display->focus_window to that) before sending WM_TAKE_FOCUS. + */ + if (window->display->focus_window != NULL && + window->display->focus_window->unmanaging) + meta_display_focus_the_no_focus_window (window->display, + window->screen, + timestamp); + } + + meta_display_request_take_focus (window->display, + window, + timestamp); + } + } +} + static void update_net_frame_extents (MetaWindow *window) { @@ -811,6 +880,7 @@ meta_window_x11_class_init (MetaWindowX11Class *klass) window_class->ping = meta_window_x11_ping; window_class->delete = meta_window_x11_delete; window_class->kill = meta_window_x11_kill; + window_class->focus = meta_window_x11_focus; window_class->move_resize_internal = meta_window_x11_move_resize_internal; window_class->get_default_skip_hints = meta_window_x11_get_default_skip_hints; } From 24b08d1a3608c09aed271798d91de208132c3c6e Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 20 Mar 2014 15:29:30 -0400 Subject: [PATCH 728/889] Move event handling to a new file display.c is getting a bit crowded. Move most of the handling out to another file, events.c. The long-term goal is to have generic event handling here, with backend-specific handling for the types of windows and such. --- src/Makefile.am | 2 + src/core/display-private.h | 9 + src/core/display.c | 2285 +----------------------------------- src/core/events.c | 2265 +++++++++++++++++++++++++++++++++++ src/core/events.h | 32 + 5 files changed, 2331 insertions(+), 2262 deletions(-) create mode 100644 src/core/events.c create mode 100644 src/core/events.h diff --git a/src/Makefile.am b/src/Makefile.am index 1d0c53c64..3763746af 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -116,6 +116,8 @@ libmutter_wayland_la_SOURCES = \ core/edge-resistance.h \ core/edid-parse.c \ core/edid.h \ + core/events.c \ + core/events.h \ core/errors.c \ meta/errors.h \ core/frame.c \ diff --git a/src/core/display-private.h b/src/core/display-private.h index c4548fcd0..3194afce3 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -456,6 +456,7 @@ gboolean meta_grab_op_is_resizing (MetaGrabOp op); gboolean meta_grab_op_is_mouse (MetaGrabOp op); gboolean meta_grab_op_is_clicking (MetaGrabOp op); gboolean meta_grab_op_is_wayland (MetaGrabOp op); +gboolean meta_grab_op_is_keyboard (MetaGrabOp op); void meta_display_devirtualize_modifiers (MetaDisplay *display, MetaVirtualModifier modifiers, @@ -489,5 +490,13 @@ void meta_display_set_input_focus_xwindow (MetaDisplay *display, guint32 timestamp); void meta_display_sync_wayland_input_focus (MetaDisplay *display); +void meta_display_update_focus_window (MetaDisplay *display, + MetaWindow *window, + Window xwindow, + gulong serial, + gboolean focused_by_us); + +void meta_display_sanity_check_timestamps (MetaDisplay *display, + guint32 timestamp); #endif diff --git a/src/core/display.c b/src/core/display.c index 287f1f565..2910c69a1 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -32,6 +32,7 @@ #include #include "display-private.h" +#include "events.h" #include "util-private.h" #include #include "screen-private.h" @@ -56,9 +57,6 @@ #ifdef HAVE_SHAPE #include #endif -#ifdef HAVE_XKB -#include -#endif #include #include #include @@ -147,36 +145,10 @@ static MetaDisplay *the_display = NULL; static const char *gnome_wm_keybindings = "Mutter"; static const char *net_wm_name = "Mutter"; -#ifdef WITH_VERBOSE_MODE -static void meta_spew_event (MetaDisplay *display, - XEvent *event); -#endif - -static gboolean xevent_callback (XEvent *event, - gpointer data); -static gboolean event_callback (const ClutterEvent *event, - gpointer data); -static Window event_get_modified_window (MetaDisplay *display, - XEvent *event); -static Window xievent_get_modified_window (MetaDisplay *display, - XIEvent *input_event); -static guint32 event_get_time (MetaDisplay *display, - XEvent *event); -static void process_request_frame_extents (MetaDisplay *display, - XEvent *event); -static void process_selection_request (MetaDisplay *display, - XEvent *event); -static void process_selection_clear (MetaDisplay *display, - XEvent *event); - static void update_window_grab_modifiers (MetaDisplay *display); static void prefs_changed_callback (MetaPreference pref, void *data); - -static void sanity_check_timestamps (MetaDisplay *display, - guint32 known_good_timestamp); - static void meta_display_get_property(GObject *object, guint prop_id, @@ -574,13 +546,7 @@ meta_display_open (void) #endif /* Get events */ - meta_ui_add_event_func (the_display->xdisplay, - xevent_callback, - the_display); - the_display->clutter_event_filter = clutter_event_add_filter (NULL, - event_callback, - NULL, - the_display); + meta_display_init_events (the_display); the_display->xids = g_hash_table_new (meta_unsigned_long_hash, meta_unsigned_long_equal); @@ -1083,13 +1049,9 @@ meta_display_close (MetaDisplay *display, if (display->grab_old_window_stacking) g_list_free (display->grab_old_window_stacking); - + /* Stop caring about events */ - meta_ui_remove_event_func (display->xdisplay, - xevent_callback, - display); - clutter_event_remove_filter (display->clutter_event_filter); - display->clutter_event_filter = 0; + meta_display_free_events (display); /* Free all screens */ tmp = display->screens; @@ -1344,8 +1306,8 @@ meta_grab_op_is_mouse (MetaGrabOp op) } } -static gboolean -grab_op_is_keyboard (MetaGrabOp op) +gboolean +meta_grab_op_is_keyboard (MetaGrabOp op) { switch (op) { @@ -1410,20 +1372,6 @@ meta_grab_op_is_moving (MetaGrabOp op) } } -static gboolean -grab_op_should_block_mouse_events (MetaGrabOp op) -{ - switch (op) - { - case META_GRAB_OP_WAYLAND_CLIENT: - case META_GRAB_OP_COMPOSITOR: - return TRUE; - - default: - return FALSE; - } -} - gboolean meta_grab_op_is_clicking (MetaGrabOp grab_op) { @@ -1529,7 +1477,7 @@ meta_display_get_current_time_roundtrip (MetaDisplay *display) timestamp = property_event.xproperty.time; } - sanity_check_timestamps (display, timestamp); + meta_display_sanity_check_timestamps (display, timestamp); return timestamp; } @@ -1579,22 +1527,6 @@ meta_display_add_ignored_crossing_serial (MetaDisplay *display, display->ignored_crossing_serials[i] = serial; } -static gboolean -crossing_serial_is_ignored (MetaDisplay *display, - unsigned long serial) -{ - int i; - - i = 0; - while (i < N_IGNORED_CROSSING_SERIALS) - { - if (display->ignored_crossing_serials[i] == serial) - return TRUE; - ++i; - } - return FALSE; -} - static gboolean window_raise_with_delay_callback (void *data) { @@ -1693,84 +1625,6 @@ handle_net_restack_window (MetaDisplay* display, } #endif -static MetaWindow * -get_window_for_event (MetaDisplay *display, - const ClutterEvent *event) -{ - ClutterActor *source; - - if (display->grab_op != META_GRAB_OP_NONE) - return display->grab_window; - - /* Always use the key focused window for key events. */ - switch (event->type) - { - case CLUTTER_KEY_PRESS: - case CLUTTER_KEY_RELEASE: - return display->focus_window; - default: - break; - } - - source = clutter_event_get_source (event); - if (META_IS_SURFACE_ACTOR (source)) - return meta_surface_actor_get_window (META_SURFACE_ACTOR (source)); - - return NULL; -} - -static XIEvent * -get_input_event (MetaDisplay *display, - XEvent *event) -{ - if (event->type == GenericEvent && - event->xcookie.extension == display->xinput_opcode) - { - XIEvent *input_event; - - /* NB: GDK event filters already have generic events - * allocated, so no need to do XGetEventData() on our own - */ - input_event = (XIEvent *) event->xcookie.data; - - switch (input_event->evtype) - { - case XI_Motion: - case XI_ButtonPress: - case XI_ButtonRelease: - if (((XIDeviceEvent *) input_event)->deviceid == META_VIRTUAL_CORE_POINTER_ID) - return input_event; - break; - case XI_KeyPress: - case XI_KeyRelease: - if (((XIDeviceEvent *) input_event)->deviceid == META_VIRTUAL_CORE_KEYBOARD_ID) - return input_event; - break; - case XI_FocusIn: - case XI_FocusOut: - if (((XIEnterEvent *) input_event)->deviceid == META_VIRTUAL_CORE_KEYBOARD_ID) - return input_event; - break; - case XI_Enter: - case XI_Leave: - if (((XIEnterEvent *) input_event)->deviceid == META_VIRTUAL_CORE_POINTER_ID) - return input_event; - break; -#ifdef HAVE_XI23 - case XI_BarrierHit: - case XI_BarrierLeave: - if (((XIBarrierEvent *) input_event)->deviceid == META_VIRTUAL_CORE_POINTER_ID) - return input_event; - break; -#endif /* HAVE_XI23 */ - default: - break; - } - } - - return NULL; -} - void meta_display_sync_wayland_input_focus (MetaDisplay *display) { @@ -1794,12 +1648,12 @@ meta_display_sync_wayland_input_focus (MetaDisplay *display) meta_wayland_seat_repick (compositor->seat, NULL); } -static void -update_focus_window (MetaDisplay *display, - MetaWindow *window, - Window xwindow, - gulong serial, - gboolean focused_by_us) +void +meta_display_update_focus_window (MetaDisplay *display, + MetaWindow *window, + Window xwindow, + gulong serial, + gboolean focused_by_us) { display->focus_serial = serial; display->focused_by_us = focused_by_us; @@ -1912,11 +1766,11 @@ request_xserver_input_focus_change (MetaDisplay *display, meta_display_ungrab (display); - update_focus_window (display, - meta_window, - xwindow, - serial, - TRUE); + meta_display_update_focus_window (display, + meta_window, + xwindow, + serial, + TRUE); meta_error_trap_pop (display); @@ -1927,1823 +1781,6 @@ request_xserver_input_focus_change (MetaDisplay *display, meta_display_remove_autoraise_callback (display); } -static void -handle_window_focus_event (MetaDisplay *display, - MetaWindow *window, - XIEnterEvent *event, - unsigned long serial) -{ - MetaWindow *focus_window; -#ifdef WITH_VERBOSE_MODE - const char *window_type; - - /* Note the event can be on either the window or the frame, - * we focus the frame for shaded windows - */ - if (window) - { - if (event->event == window->xwindow) - window_type = "client window"; - else if (window->frame && event->event == window->frame->xwindow) - window_type = "frame window"; - else - window_type = "unknown client window"; - } - else if (meta_display_xwindow_is_a_no_focus_window (display, event->event)) - window_type = "no_focus_window"; - else if (meta_display_screen_for_root (display, event->event)) - window_type = "root window"; - else - window_type = "unknown window"; - - meta_topic (META_DEBUG_FOCUS, - "Focus %s event received on %s 0x%lx (%s) " - "mode %s detail %s serial %lu\n", - event->evtype == XI_FocusIn ? "in" : - event->evtype == XI_FocusOut ? "out" : - "???", - window ? window->desc : "", - event->event, window_type, - meta_event_mode_to_string (event->mode), - meta_event_detail_to_string (event->mode), - event->serial); -#endif - - /* FIXME our pointer tracking is broken; see how - * gtk+/gdk/x11/gdkevents-x11.c or XFree86/xc/programs/xterm/misc.c - * for how to handle it the correct way. In brief you need to track - * pointer focus and regular focus, and handle EnterNotify in - * PointerRoot mode with no window manager. However as noted above, - * accurate focus tracking will break things because we want to keep - * windows "focused" when using keybindings on them, and also we - * sometimes "focus" a window by focusing its frame or - * no_focus_window; so this all needs rethinking massively. - * - * My suggestion is to change it so that we clearly separate - * actual keyboard focus tracking using the xterm algorithm, - * and mutter's "pretend" focus window, and go through all - * the code and decide which one should be used in each place; - * a hard bit is deciding on a policy for that. - * - * http://bugzilla.gnome.org/show_bug.cgi?id=90382 - */ - - /* We ignore grabs, though this is questionable. It may be better to - * increase the intelligence of the focus window tracking. - * - * The problem is that keybindings for windows are done with - * XGrabKey, which means focus_window disappears and the front of - * the MRU list gets confused from what the user expects once a - * keybinding is used. - */ - - if (event->mode == XINotifyGrab || - event->mode == XINotifyUngrab || - /* From WindowMaker, ignore all funky pointer root events */ - event->detail > XINotifyNonlinearVirtual) - { - meta_topic (META_DEBUG_FOCUS, - "Ignoring focus event generated by a grab or other weirdness\n"); - return; - } - - if (event->evtype == XI_FocusIn) - { - display->server_focus_window = event->event; - display->server_focus_serial = serial; - focus_window = window; - } - else if (event->evtype == XI_FocusOut) - { - if (event->detail == XINotifyInferior) - { - /* This event means the client moved focus to a subwindow */ - meta_topic (META_DEBUG_FOCUS, - "Ignoring focus out with NotifyInferior\n"); - return; - } - - display->server_focus_window = None; - display->server_focus_serial = serial; - focus_window = NULL; - } - else - g_return_if_reached (); - - /* If display->focused_by_us, then the focus_serial will be used only - * for a focus change we made and have already accounted for. - * (See request_xserver_input_focus_change().) Otherwise, we can get - * multiple focus events with the same serial. - */ - if (display->server_focus_serial > display->focus_serial || - (!display->focused_by_us && - display->server_focus_serial == display->focus_serial)) - { - update_focus_window (display, - focus_window, - focus_window ? focus_window->xwindow : None, - display->server_focus_serial, - FALSE); - } -} - -static gboolean -window_has_xwindow (MetaWindow *window, - Window xwindow) -{ - if (window->xwindow == xwindow) - return TRUE; - - if (window->frame && window->frame->xwindow == xwindow) - return TRUE; - - return FALSE; -} - -static gboolean -meta_display_handle_event (MetaDisplay *display, - const ClutterEvent *event) -{ - MetaWindow *window; - gboolean bypass_clutter = FALSE, bypass_wayland = FALSE; - MetaWaylandCompositor *compositor = NULL; - - if (meta_is_wayland_compositor ()) - { - compositor = meta_wayland_compositor_get_default (); - meta_wayland_compositor_update (compositor, event); - } - - window = get_window_for_event (display, event); - - display->current_time = event->any.time; - - if (window && !window->override_redirect && - (event->type == CLUTTER_KEY_PRESS || event->type == CLUTTER_BUTTON_PRESS)) - { - if (CurrentTime == display->current_time) - { - /* We can't use missing (i.e. invalid) timestamps to set user time, - * nor do we want to use them to sanity check other timestamps. - * See bug 313490 for more details. - */ - meta_warning ("Event has no timestamp! You may be using a broken " - "program such as xse. Please ask the authors of that " - "program to fix it.\n"); - } - else - { - meta_window_set_user_time (window, display->current_time); - sanity_check_timestamps (display, display->current_time); - } - } - - switch (event->type) - { - case CLUTTER_BUTTON_PRESS: - if (grab_op_should_block_mouse_events (display->grab_op)) - break; - - display->overlay_key_only_pressed = FALSE; - - if ((window && - meta_grab_op_is_mouse (display->grab_op) && - (event->button.modifier_state & display->window_grab_modifiers) && - display->grab_button != (int) event->button.button && - display->grab_window == window) || - grab_op_is_keyboard (display->grab_op)) - { - meta_topic (META_DEBUG_WINDOW_OPS, - "Ending grab op %u on window %s due to button press\n", - display->grab_op, - (display->grab_window ? - display->grab_window->desc : - "none")); - meta_display_end_grab_op (display, event->any.time); - bypass_clutter = TRUE; - bypass_wayland = TRUE; - } - else if (window && display->grab_op == META_GRAB_OP_NONE) - { - ClutterModifierType grab_mask; - gboolean unmodified; - gboolean fully_modified; - - grab_mask = display->window_grab_modifiers; - if (g_getenv ("MUTTER_DEBUG_BUTTON_GRABS")) - grab_mask |= CLUTTER_CONTROL_MASK; - - /* We have three passive button grabs: - * - on any button, without modifiers => focuses and maybe raises the window - * - on resize button, with modifiers => start an interactive resizing - * (normally middle) - * - on move button, with modifiers => start an interactive move - * (normally left) - * - on menu button, with modifiers => show the window menu - * (normally right) - * - * We may get here because we actually have a button - * grab on the window, or because we're a wayland - * compositor and thus we see all the events, so we - * need to check if the event is interesting. - * We want an event that is not modified, for a window - * that has (or would have, the wayland case) the - * button grab active. - * - * We may have other events on the window, for example - * a click on a frame button, but that's not for us to - * care about. Just let the event through. - */ - unmodified = (event->button.modifier_state & grab_mask) == 0; - fully_modified = grab_mask && (event->button.modifier_state & grab_mask) == grab_mask; - - if (unmodified && window && window->have_focus_click_grab) - { - if (meta_prefs_get_raise_on_click ()) - meta_window_raise (window); - else - meta_topic (META_DEBUG_FOCUS, - "Not raising window on click due to don't-raise-on-click option\n"); - - /* Don't focus panels--they must explicitly request focus. - * See bug 160470 - */ - if (window->type != META_WINDOW_DOCK) - { - meta_topic (META_DEBUG_FOCUS, - "Focusing %s due to unmodified button %u press (display.c)\n", - window->desc, event->button.button); - meta_window_focus (window, event->any.time); - } - else - /* However, do allow terminals to lose focus due to new - * window mappings after the user clicks on a panel. - */ - display->allow_terminal_deactivation = TRUE; - - meta_verbose ("Allowing events time %u\n", - (unsigned int)event->button.time); - - XIAllowEvents (display->xdisplay, clutter_input_device_get_device_id (event->button.device), - XIReplayDevice, event->button.time); - bypass_clutter = TRUE; - } - else if (fully_modified && (int) event->button.button == meta_prefs_get_mouse_button_resize ()) - { - if (window->has_resize_func) - { - gboolean north, south; - gboolean west, east; - MetaRectangle frame_rect; - MetaGrabOp op; - - meta_window_get_frame_rect (window, &frame_rect); - - west = event->button.x < (frame_rect.x + 1 * frame_rect.width / 3); - east = event->button.x > (frame_rect.x + 2 * frame_rect.width / 3); - north = event->button.y < (frame_rect.y + 1 * frame_rect.height / 3); - south = event->button.y > (frame_rect.y + 2 * frame_rect.height / 3); - - if (north && west) - op = META_GRAB_OP_RESIZING_NW; - else if (north && east) - op = META_GRAB_OP_RESIZING_NE; - else if (south && west) - op = META_GRAB_OP_RESIZING_SW; - else if (south && east) - op = META_GRAB_OP_RESIZING_SE; - else if (north) - op = META_GRAB_OP_RESIZING_N; - else if (west) - op = META_GRAB_OP_RESIZING_W; - else if (east) - op = META_GRAB_OP_RESIZING_E; - else if (south) - op = META_GRAB_OP_RESIZING_S; - else /* Middle region is no-op to avoid user triggering wrong action */ - op = META_GRAB_OP_NONE; - - if (op != META_GRAB_OP_NONE) - meta_display_begin_grab_op (display, - window->screen, - window, - op, - TRUE, - FALSE, - event->button.button, - 0, - event->any.time, - event->button.x, - event->button.y); - } - bypass_clutter = TRUE; - bypass_wayland = TRUE; - } - else if (fully_modified && (int) event->button.button == meta_prefs_get_mouse_button_menu ()) - { - if (meta_prefs_get_raise_on_click ()) - meta_window_raise (window); - meta_window_show_menu (window, - event->button.x, - event->button.y, - event->button.button, - event->any.time); - bypass_clutter = TRUE; - bypass_wayland = TRUE; - } - else if (fully_modified && (int) event->button.button == 1) - { - if (window->has_move_func) - { - meta_display_begin_grab_op (display, - window->screen, - window, - META_GRAB_OP_MOVING, - TRUE, - FALSE, - event->button.button, - 0, - event->any.time, - event->button.x, - event->button.y); - } - bypass_clutter = TRUE; - bypass_wayland = TRUE; - } - } - break; - case CLUTTER_BUTTON_RELEASE: - if (grab_op_should_block_mouse_events (display->grab_op)) - break; - - display->overlay_key_only_pressed = FALSE; - - if (display->grab_window == window && - meta_grab_op_is_mouse (display->grab_op)) - { - meta_window_handle_mouse_grab_op_event (window, event); - bypass_clutter = TRUE; - bypass_wayland = TRUE; - } - break; - case CLUTTER_MOTION: - if (grab_op_should_block_mouse_events (display->grab_op)) - break; - - if (display->grab_window == window && - meta_grab_op_is_mouse (display->grab_op)) - { - meta_window_handle_mouse_grab_op_event (window, event); - bypass_clutter = TRUE; - bypass_wayland = TRUE; - } - break; - - case CLUTTER_KEY_PRESS: - case CLUTTER_KEY_RELEASE: - /* For key events, it's important to enforce single-handling, or - * we can get into a confused state. So if a keybinding is - * handled (because it's one of our hot-keys, or because we are - * in a keyboard-grabbed mode like moving a window, we don't - * want to pass the key event to the compositor or Wayland at all. - */ - if (meta_display_process_key_event (display, window, (ClutterKeyEvent *) event)) - { - bypass_clutter = TRUE; - bypass_wayland = TRUE; - } - - default: - break; - } - - /* If the compositor has a grab, don't pass that through to Wayland */ - if (display->grab_op == META_GRAB_OP_COMPOSITOR) - bypass_wayland = TRUE; - - /* If a Wayland client has a grab, don't pass that through to Clutter */ - if (display->grab_op == META_GRAB_OP_WAYLAND_CLIENT) - bypass_clutter = TRUE; - - if (compositor && !bypass_wayland) - { - if (meta_wayland_compositor_handle_event (compositor, event)) - bypass_clutter = TRUE; - } - - return bypass_clutter; -} - -static gboolean -handle_input_xevent (MetaDisplay *display, - XIEvent *input_event, - gulong serial) -{ - XIEnterEvent *enter_event = (XIEnterEvent *) input_event; - Window modified; - MetaWindow *window; - MetaScreen *screen; - - if (input_event == NULL) - return FALSE; - - modified = xievent_get_modified_window (display, input_event); - window = modified != None ? meta_display_lookup_x_window (display, modified) : NULL; - - switch (input_event->evtype) - { - case XI_Enter: - if (display->grab_op == META_GRAB_OP_COMPOSITOR) - break; - - /* If the mouse switches screens, active the default window on the new - * screen; this will make keybindings and workspace-launched items - * actually appear on the right screen. - */ - { - MetaScreen *new_screen = - meta_display_screen_for_root (display, enter_event->root); - - if (new_screen != NULL && display->active_screen != new_screen) - meta_workspace_focus_default_window (new_screen->active_workspace, - NULL, - enter_event->time); - } - - /* Check if we've entered a window; do this even if window->has_focus to - * avoid races. - */ - if (window && !crossing_serial_is_ignored (display, serial) && - enter_event->mode != XINotifyGrab && - enter_event->mode != XINotifyUngrab && - enter_event->detail != XINotifyInferior && - meta_display_focus_sentinel_clear (display)) - { - meta_window_handle_enter (window, - enter_event->time, - enter_event->root_x, - enter_event->root_y); - - if (window->type == META_WINDOW_DOCK) - meta_window_raise (window); - } - break; - case XI_Leave: - if (display->grab_op == META_GRAB_OP_COMPOSITOR) - break; - - if (window != NULL) - { - if (window->type == META_WINDOW_DOCK && - enter_event->mode != XINotifyGrab && - enter_event->mode != XINotifyUngrab && - !window->has_focus) - meta_window_lower (window); - } - break; - case XI_FocusIn: - case XI_FocusOut: - handle_window_focus_event (display, window, enter_event, serial); - if (!window) - { - /* Check if the window is a root window. */ - if (enter_event->root != enter_event->event) - break; - - screen = meta_display_screen_for_root (display, enter_event->root); - - if (enter_event->evtype == XI_FocusIn && - enter_event->mode == XINotifyDetailNone) - { - meta_topic (META_DEBUG_FOCUS, - "Focus got set to None, probably due to " - "brain-damage in the X protocol (see bug " - "125492). Setting the default focus window.\n"); - meta_workspace_focus_default_window (screen->active_workspace, - NULL, - meta_display_get_current_time_roundtrip (display)); - } - else if (enter_event->evtype == XI_FocusIn && - enter_event->mode == XINotifyNormal && - enter_event->detail == XINotifyInferior) - { - meta_topic (META_DEBUG_FOCUS, - "Focus got set to root window, probably due to " - "gnome-session logout dialog usage (see bug " - "153220). Setting the default focus window.\n"); - meta_workspace_focus_default_window (screen->active_workspace, - NULL, - meta_display_get_current_time_roundtrip (display)); - } - - } - - /* Don't send FocusIn / FocusOut to Clutter */ - return TRUE; - } - - return FALSE; -} - -static void -reload_xkb_rules (MetaScreen *screen) -{ - MetaWaylandCompositor *compositor; - char **names; - int n_names; - gboolean ok; - const char *rules, *model, *layout, *variant, *options; - - compositor = meta_wayland_compositor_get_default (); - - ok = meta_prop_get_latin1_list (screen->display, screen->xroot, - screen->display->atom__XKB_RULES_NAMES, - &names, &n_names); - if (!ok) - return; - - if (n_names != 5) - goto out; - - rules = names[0]; - model = names[1]; - layout = names[2]; - variant = names[3]; - options = names[4]; - - meta_wayland_keyboard_set_keymap_names (&compositor->seat->keyboard, - rules, model, layout, variant, options, - META_WAYLAND_KEYBOARD_SKIP_XCLIENTS); - - out: - g_strfreev (names); -} - -static gboolean -handle_other_xevent (MetaDisplay *display, - XEvent *event) -{ - Window modified; - MetaWindow *window; - MetaWindow *property_for_window; - gboolean frame_was_receiver; - gboolean bypass_gtk = FALSE; - - modified = event_get_modified_window (display, event); - window = modified != None ? meta_display_lookup_x_window (display, modified) : NULL; - frame_was_receiver = (window && window->frame && modified == window->frame->xwindow); - - /* We only want to respond to _NET_WM_USER_TIME property notify - * events on _NET_WM_USER_TIME_WINDOW windows; in particular, - * responding to UnmapNotify events is kind of bad. - */ - property_for_window = NULL; - if (window && modified == window->user_time_window) - { - property_for_window = window; - window = NULL; - } - -#ifdef HAVE_XSYNC - if (META_DISPLAY_HAS_XSYNC (display) && - event->type == (display->xsync_event_base + XSyncAlarmNotify)) - { - MetaWindow *alarm_window = meta_display_lookup_sync_alarm (display, - ((XSyncAlarmNotifyEvent*)event)->alarm); - - if (alarm_window != NULL) - { - XSyncValue value = ((XSyncAlarmNotifyEvent*)event)->counter_value; - gint64 new_counter_value; - new_counter_value = XSyncValueLow32 (value) + ((gint64)XSyncValueHigh32 (value) << 32); - meta_window_update_sync_request_counter (alarm_window, new_counter_value); - bypass_gtk = TRUE; /* GTK doesn't want to see this really */ - } - else - meta_idle_monitor_handle_xevent_all (event); - - goto out; - } -#endif /* HAVE_XSYNC */ - -#ifdef HAVE_SHAPE - if (META_DISPLAY_HAS_SHAPE (display) && - event->type == (display->shape_event_base + ShapeNotify)) - { - bypass_gtk = TRUE; /* GTK doesn't want to see this really */ - - if (window && !frame_was_receiver) - { - XShapeEvent *sev = (XShapeEvent*) event; - - if (sev->kind == ShapeBounding) - meta_window_x11_update_shape_region (window); - else if (sev->kind == ShapeInput) - meta_window_x11_update_input_region (window); - } - else - { - meta_topic (META_DEBUG_SHAPES, - "ShapeNotify not on a client window (window %s frame_was_receiver = %d)\n", - window ? window->desc : "(none)", - frame_was_receiver); - } - - goto out; - } -#endif /* HAVE_SHAPE */ - - switch (event->type) - { - case KeymapNotify: - break; - case Expose: - break; - case GraphicsExpose: - break; - case NoExpose: - break; - case VisibilityNotify: - break; - case CreateNotify: - { - MetaScreen *screen; - - screen = meta_display_screen_for_root (display, - event->xcreatewindow.parent); - if (screen) - meta_stack_tracker_create_event (screen->stack_tracker, - &event->xcreatewindow); - } - break; - - case DestroyNotify: - { - MetaScreen *screen; - - screen = meta_display_screen_for_root (display, - event->xdestroywindow.event); - if (screen) - meta_stack_tracker_destroy_event (screen->stack_tracker, - &event->xdestroywindow); - } - if (window) - { - /* FIXME: It sucks that DestroyNotify events don't come with - * a timestamp; could we do something better here? Maybe X - * will change one day? - */ - guint32 timestamp; - timestamp = meta_display_get_current_time_roundtrip (display); - - if (display->grab_op != META_GRAB_OP_NONE && - display->grab_window == window) - meta_display_end_grab_op (display, timestamp); - - if (frame_was_receiver) - { - meta_warning ("Unexpected destruction of frame 0x%lx, not sure if this should silently fail or be considered a bug\n", - window->frame->xwindow); - meta_error_trap_push (display); - meta_window_destroy_frame (window->frame->window); - meta_error_trap_pop (display); - } - else - { - /* Unmanage destroyed window */ - meta_window_unmanage (window, timestamp); - window = NULL; - } - } - break; - case UnmapNotify: - if (window) - { - /* FIXME: It sucks that UnmapNotify events don't come with - * a timestamp; could we do something better here? Maybe X - * will change one day? - */ - guint32 timestamp; - timestamp = meta_display_get_current_time_roundtrip (display); - - if (display->grab_op != META_GRAB_OP_NONE && - display->grab_window == window && - window->frame == NULL) - meta_display_end_grab_op (display, timestamp); - - if (!frame_was_receiver) - { - if (window->unmaps_pending == 0) - { - meta_topic (META_DEBUG_WINDOW_STATE, - "Window %s withdrawn\n", - window->desc); - - /* Unmanage withdrawn window */ - window->withdrawn = TRUE; - meta_window_unmanage (window, timestamp); - window = NULL; - } - else - { - window->unmaps_pending -= 1; - meta_topic (META_DEBUG_WINDOW_STATE, - "Received pending unmap, %d now pending\n", - window->unmaps_pending); - } - } - } - break; - case MapNotify: - /* NB: override redirect windows wont cause a map request so we - * watch out for map notifies against any root windows too if a - * compositor is enabled: */ - if (window == NULL - && meta_display_screen_for_root (display, event->xmap.event)) - { - window = meta_window_x11_new (display, event->xmap.window, - FALSE, META_COMP_EFFECT_CREATE); - } - break; - case MapRequest: - if (window == NULL) - { - window = meta_window_x11_new (display, event->xmaprequest.window, - FALSE, META_COMP_EFFECT_CREATE); - } - /* if frame was receiver it's some malicious send event or something */ - else if (!frame_was_receiver && window) - { - meta_verbose ("MapRequest on %s mapped = %d minimized = %d\n", - window->desc, window->mapped, window->minimized); - if (window->minimized) - { - meta_window_unminimize (window); - if (window->workspace != window->screen->active_workspace) - { - meta_verbose ("Changing workspace due to MapRequest mapped = %d minimized = %d\n", - window->mapped, window->minimized); - meta_window_change_workspace (window, - window->screen->active_workspace); - } - } - } - break; - case ReparentNotify: - { - MetaScreen *screen; - - screen = meta_display_screen_for_root (display, - event->xconfigure.event); - if (screen) - meta_stack_tracker_reparent_event (screen->stack_tracker, - &event->xreparent); - } - break; - case ConfigureNotify: - if (event->xconfigure.event != event->xconfigure.window) - { - MetaScreen *screen; - - screen = meta_display_screen_for_root (display, - event->xconfigure.event); - if (screen) - meta_stack_tracker_configure_event (screen->stack_tracker, - &event->xconfigure); - } - - if (window && window->override_redirect) - meta_window_x11_configure_notify (window, &event->xconfigure); - - break; - case ConfigureRequest: - /* This comment and code is found in both twm and fvwm */ - /* - * According to the July 27, 1988 ICCCM draft, we should ignore size and - * position fields in the WM_NORMAL_HINTS property when we map a window. - * Instead, we'll read the current geometry. Therefore, we should respond - * to configuration requests for windows which have never been mapped. - */ - if (window == NULL) - { - unsigned int xwcm; - XWindowChanges xwc; - - xwcm = event->xconfigurerequest.value_mask & - (CWX | CWY | CWWidth | CWHeight | CWBorderWidth); - - xwc.x = event->xconfigurerequest.x; - xwc.y = event->xconfigurerequest.y; - xwc.width = event->xconfigurerequest.width; - xwc.height = event->xconfigurerequest.height; - xwc.border_width = event->xconfigurerequest.border_width; - - meta_verbose ("Configuring withdrawn window to %d,%d %dx%d border %d (some values may not be in mask)\n", - xwc.x, xwc.y, xwc.width, xwc.height, xwc.border_width); - meta_error_trap_push (display); - XConfigureWindow (display->xdisplay, event->xconfigurerequest.window, - xwcm, &xwc); - meta_error_trap_pop (display); - } - else - { - if (!frame_was_receiver) - meta_window_x11_configure_request (window, event); - } - break; - case GravityNotify: - break; - case ResizeRequest: - break; - case CirculateNotify: - break; - case CirculateRequest: - break; - case PropertyNotify: - { - MetaGroup *group; - MetaScreen *screen; - - if (window && !frame_was_receiver) - meta_window_x11_property_notify (window, event); - else if (property_for_window && !frame_was_receiver) - meta_window_x11_property_notify (property_for_window, event); - - group = meta_display_lookup_group (display, - event->xproperty.window); - if (group != NULL) - meta_group_property_notify (group, event); - - screen = NULL; - if (window == NULL && - group == NULL) /* window/group != NULL means it wasn't a root window */ - screen = meta_display_screen_for_root (display, - event->xproperty.window); - - if (screen != NULL) - { - if (event->xproperty.atom == - display->atom__NET_DESKTOP_LAYOUT) - meta_screen_update_workspace_layout (screen); - else if (event->xproperty.atom == - display->atom__NET_DESKTOP_NAMES) - meta_screen_update_workspace_names (screen); - else if (meta_is_wayland_compositor () && - event->xproperty.atom == - display->atom__XKB_RULES_NAMES) - reload_xkb_rules (screen); -#if 0 - else if (event->xproperty.atom == - display->atom__NET_RESTACK_WINDOW) - handle_net_restack_window (display, event); -#endif - - /* we just use this property as a sentinel to avoid - * certain race conditions. See the comment for the - * sentinel_counter variable declaration in display.h - */ - if (event->xproperty.atom == - display->atom__MUTTER_SENTINEL) - { - meta_display_decrement_focus_sentinel (display); - } - } - } - break; - case SelectionClear: - /* do this here instead of at end of function - * so we can return - */ - - /* FIXME: Clearing display->current_time here makes no sense to - * me; who put this here and why? - */ - display->current_time = CurrentTime; - - process_selection_clear (display, event); - /* Note that processing that may have resulted in - * closing the display... so return right away. - */ - return FALSE; - case SelectionRequest: - process_selection_request (display, event); - break; - case SelectionNotify: - break; - case ColormapNotify: - if (window && !frame_was_receiver) - window->colormap = event->xcolormap.colormap; - break; - case ClientMessage: - if (window) - { - if (!frame_was_receiver) - meta_window_x11_client_message (window, event); - } - else - { - MetaScreen *screen; - - screen = meta_display_screen_for_root (display, - event->xclient.window); - - if (screen) - { - if (event->xclient.message_type == - display->atom__NET_CURRENT_DESKTOP) - { - int space; - MetaWorkspace *workspace; - guint32 time; - - space = event->xclient.data.l[0]; - time = event->xclient.data.l[1]; - - meta_verbose ("Request to change current workspace to %d with " - "specified timestamp of %u\n", - space, time); - - workspace = - meta_screen_get_workspace_by_index (screen, - space); - - /* Handle clients using the older version of the spec... */ - if (time == 0 && workspace) - { - meta_warning ("Received a NET_CURRENT_DESKTOP message " - "from a broken (outdated) client who sent " - "a 0 timestamp\n"); - time = meta_display_get_current_time_roundtrip (display); - } - - if (workspace) - meta_workspace_activate (workspace, time); - else - meta_verbose ("Don't know about workspace %d\n", space); - } - else if (event->xclient.message_type == - display->atom__NET_NUMBER_OF_DESKTOPS) - { - int num_spaces; - - num_spaces = event->xclient.data.l[0]; - - meta_verbose ("Request to set number of workspaces to %d\n", - num_spaces); - - meta_prefs_set_num_workspaces (num_spaces); - } - else if (event->xclient.message_type == - display->atom__NET_SHOWING_DESKTOP) - { - gboolean showing_desktop; - guint32 timestamp; - - showing_desktop = event->xclient.data.l[0] != 0; - /* FIXME: Braindead protocol doesn't have a timestamp */ - timestamp = meta_display_get_current_time_roundtrip (display); - meta_verbose ("Request to %s desktop\n", - showing_desktop ? "show" : "hide"); - - if (showing_desktop) - meta_screen_show_desktop (screen, timestamp); - else - { - meta_screen_unshow_desktop (screen); - meta_workspace_focus_default_window (screen->active_workspace, NULL, timestamp); - } - } - else if (event->xclient.message_type == - display->atom_WM_PROTOCOLS) - { - meta_verbose ("Received WM_PROTOCOLS message\n"); - - if ((Atom)event->xclient.data.l[0] == display->atom__NET_WM_PING) - { - guint32 timestamp = event->xclient.data.l[1]; - - meta_display_pong_for_serial (display, timestamp); - - /* We don't want ping reply events going into - * the GTK+ event loop because gtk+ will treat - * them as ping requests and send more replies. - */ - bypass_gtk = TRUE; - } - } - } - - if (event->xclient.message_type == - display->atom__NET_REQUEST_FRAME_EXTENTS) - { - meta_verbose ("Received _NET_REQUEST_FRAME_EXTENTS message\n"); - process_request_frame_extents (display, event); - } - } - break; - case MappingNotify: - { - gboolean ignore_current; - - ignore_current = FALSE; - - /* Check whether the next event is an identical MappingNotify - * event. If it is, ignore the current event, we'll update - * when we get the next one. - */ - if (XPending (display->xdisplay)) - { - XEvent next_event; - - XPeekEvent (display->xdisplay, &next_event); - - if (next_event.type == MappingNotify && - next_event.xmapping.request == event->xmapping.request) - ignore_current = TRUE; - } - - if (!ignore_current) - { - /* Let XLib know that there is a new keyboard mapping. - */ - XRefreshKeyboardMapping (&event->xmapping); - meta_display_process_mapping_event (display, event); - } - } - break; - default: -#ifdef HAVE_XKB - if (event->type == display->xkb_base_event_type) - { - XkbAnyEvent *xkb_ev = (XkbAnyEvent *) event; - - switch (xkb_ev->xkb_type) - { - case XkbBellNotify: - if (XSERVER_TIME_IS_BEFORE(display->last_bell_time, - xkb_ev->time - 100)) - { - display->last_bell_time = xkb_ev->time; - meta_bell_notify (display, xkb_ev); - } - break; - case XkbNewKeyboardNotify: - case XkbMapNotify: - if (xkb_ev->device == META_VIRTUAL_CORE_KEYBOARD_ID) - meta_display_process_mapping_event (display, event); - break; - } - } -#endif - break; - } - - out: - return bypass_gtk; -} - -/** - * meta_display_handle_xevent: - * @display: The MetaDisplay that events are coming from - * @event: The event that just happened - * - * This is the most important function in the whole program. It is the heart, - * it is the nexus, it is the Grand Central Station of Mutter's world. - * When we create a #MetaDisplay, we ask GDK to pass *all* events for *all* - * windows to this function. So every time anything happens that we might - * want to know about, this function gets called. You see why it gets a bit - * busy around here. Most of this function is a ginormous switch statement - * dealing with all the kinds of events that might turn up. - */ -static gboolean -meta_display_handle_xevent (MetaDisplay *display, - XEvent *event) -{ - Window modified; - gboolean bypass_compositor = FALSE, bypass_gtk = FALSE; - XIEvent *input_event; - MetaMonitorManager *monitor; - MetaScreen *screen; - -#if 0 - meta_spew_event (display, event); -#endif - -#ifdef HAVE_STARTUP_NOTIFICATION - sn_display_process_event (display->sn_display, event); -#endif - - /* Intercept XRandR events early and don't attempt any - processing for them. We still let them through to Gdk though, - so it can update its own internal state. - */ - monitor = meta_monitor_manager_get (); - if (meta_monitor_manager_handle_xevent (monitor, event)) - { - bypass_compositor = TRUE; - goto out; - } - - display->current_time = event_get_time (display, event); - display->monitor_cache_invalidated = TRUE; - - if (display->focused_by_us && - event->xany.serial > display->focus_serial && - display->focus_window && - !window_has_xwindow (display->focus_window, display->server_focus_window)) - { - meta_topic (META_DEBUG_FOCUS, "Earlier attempt to focus %s failed\n", - display->focus_window->desc); - update_focus_window (display, - meta_display_lookup_x_window (display, display->server_focus_window), - display->server_focus_window, - display->server_focus_serial, - FALSE); - } - - screen = meta_display_screen_for_root (display, event->xany.window); - if (screen) - { - if (meta_screen_handle_xevent (screen, event)) - { - bypass_gtk = bypass_compositor = TRUE; - goto out; - } - } - - modified = event_get_modified_window (display, event); - - input_event = get_input_event (display, event); - - if (event->type == UnmapNotify) - { - if (meta_ui_window_should_not_cause_focus (display->xdisplay, - modified)) - { - meta_display_add_ignored_crossing_serial (display, event->xany.serial); - meta_topic (META_DEBUG_FOCUS, - "Adding EnterNotify serial %lu to ignored focus serials\n", - event->xany.serial); - } - } - else if (input_event && - input_event->evtype == XI_Leave && - ((XILeaveEvent *)input_event)->mode == XINotifyUngrab && - modified == display->ungrab_should_not_cause_focus_window) - { - meta_display_add_ignored_crossing_serial (display, event->xany.serial); - meta_topic (META_DEBUG_FOCUS, - "Adding LeaveNotify serial %lu to ignored focus serials\n", - event->xany.serial); - } - -#ifdef HAVE_XI23 - if (meta_display_process_barrier_event (display, input_event)) - { - bypass_gtk = bypass_compositor = TRUE; - goto out; - } -#endif /* HAVE_XI23 */ - - /* libXi does not properly copy the serial to XI2 events, so pull it - * from the parent XAnyEvent and pass it to handle_input_xevent. - * See: https://bugs.freedesktop.org/show_bug.cgi?id=64687 - */ - if (handle_input_xevent (display, input_event, event->xany.serial)) - { - bypass_gtk = bypass_compositor = TRUE; - goto out; - } - - if (handle_other_xevent (display, event)) - { - bypass_gtk = TRUE; - goto out; - } - - out: - if (!bypass_compositor) - { - MetaWindow *window = modified != None ? meta_display_lookup_x_window (display, modified) : NULL; - - if (meta_compositor_process_event (display->compositor, event, window)) - bypass_gtk = TRUE; - } - - display->current_time = CurrentTime; - return bypass_gtk; -} - -static gboolean -xevent_callback (XEvent *event, - gpointer data) -{ - MetaDisplay *display = data; - - return meta_display_handle_xevent (display, event); -} - -static gboolean -event_callback (const ClutterEvent *event, - gpointer data) -{ - MetaDisplay *display = data; - - return meta_display_handle_event (display, event); -} - -static Window -xievent_get_modified_window (MetaDisplay *display, - XIEvent *input_event) -{ - switch (input_event->evtype) - { - case XI_Motion: - case XI_ButtonPress: - case XI_ButtonRelease: - case XI_KeyPress: - case XI_KeyRelease: - return ((XIDeviceEvent *) input_event)->event; - case XI_FocusIn: - case XI_FocusOut: - case XI_Enter: - case XI_Leave: - return ((XIEnterEvent *) input_event)->event; -#ifdef HAVE_XI23 - case XI_BarrierHit: - case XI_BarrierLeave: - return ((XIBarrierEvent *) input_event)->event; -#endif /* HAVE_XI23 */ - } - - return None; -} - -/* Return the window this has to do with, if any, rather - * than the frame or root window that was selecting - * for substructure - */ -static Window -event_get_modified_window (MetaDisplay *display, - XEvent *event) -{ - XIEvent *input_event = get_input_event (display, event); - - if (input_event) - return xievent_get_modified_window (display, input_event); - - switch (event->type) - { - case KeymapNotify: - case Expose: - case GraphicsExpose: - case NoExpose: - case VisibilityNotify: - case ResizeRequest: - case PropertyNotify: - case SelectionClear: - case SelectionRequest: - case SelectionNotify: - case ColormapNotify: - case ClientMessage: - return event->xany.window; - - case CreateNotify: - return event->xcreatewindow.window; - - case DestroyNotify: - return event->xdestroywindow.window; - - case UnmapNotify: - return event->xunmap.window; - - case MapNotify: - return event->xmap.window; - - case MapRequest: - return event->xmaprequest.window; - - case ReparentNotify: - return event->xreparent.window; - - case ConfigureNotify: - return event->xconfigure.window; - - case ConfigureRequest: - return event->xconfigurerequest.window; - - case GravityNotify: - return event->xgravity.window; - - case CirculateNotify: - return event->xcirculate.window; - - case CirculateRequest: - return event->xcirculaterequest.window; - - case MappingNotify: - return None; - - default: -#ifdef HAVE_SHAPE - if (META_DISPLAY_HAS_SHAPE (display) && - event->type == (display->shape_event_base + ShapeNotify)) - { - XShapeEvent *sev = (XShapeEvent*) event; - return sev->window; - } -#endif - - return None; - } -} - -static guint32 -event_get_time (MetaDisplay *display, - XEvent *event) -{ - XIEvent *input_event = get_input_event (display, event); - - if (input_event) - return input_event->time; - - switch (event->type) - { - case PropertyNotify: - return event->xproperty.time; - - case SelectionClear: - case SelectionRequest: - case SelectionNotify: - return event->xselection.time; - - case KeymapNotify: - case Expose: - case GraphicsExpose: - case NoExpose: - case MapNotify: - case UnmapNotify: - case VisibilityNotify: - case ResizeRequest: - case ColormapNotify: - case ClientMessage: - case CreateNotify: - case DestroyNotify: - case MapRequest: - case ReparentNotify: - case ConfigureNotify: - case ConfigureRequest: - case GravityNotify: - case CirculateNotify: - case CirculateRequest: - case MappingNotify: - default: - return CurrentTime; - } -} - -G_GNUC_UNUSED const char* -meta_event_detail_to_string (int d) -{ - const char *detail = "???"; - switch (d) - { - /* We are an ancestor in the A<->B focus change relationship */ - case XINotifyAncestor: - detail = "NotifyAncestor"; - break; - case XINotifyDetailNone: - detail = "NotifyDetailNone"; - break; - /* We are a descendant in the A<->B focus change relationship */ - case XINotifyInferior: - detail = "NotifyInferior"; - break; - case XINotifyNonlinear: - detail = "NotifyNonlinear"; - break; - case XINotifyNonlinearVirtual: - detail = "NotifyNonlinearVirtual"; - break; - case XINotifyPointer: - detail = "NotifyPointer"; - break; - case XINotifyPointerRoot: - detail = "NotifyPointerRoot"; - break; - case XINotifyVirtual: - detail = "NotifyVirtual"; - break; - } - - return detail; -} - -G_GNUC_UNUSED const char* -meta_event_mode_to_string (int m) -{ - const char *mode = "???"; - switch (m) - { - case XINotifyNormal: - mode = "NotifyNormal"; - break; - case XINotifyGrab: - mode = "NotifyGrab"; - break; - case XINotifyUngrab: - mode = "NotifyUngrab"; - break; - case XINotifyWhileGrabbed: - mode = "NotifyWhileGrabbed"; - break; - } - - return mode; -} - -G_GNUC_UNUSED static const char* -stack_mode_to_string (int mode) -{ - switch (mode) - { - case Above: - return "Above"; - case Below: - return "Below"; - case TopIf: - return "TopIf"; - case BottomIf: - return "BottomIf"; - case Opposite: - return "Opposite"; - } - - return "Unknown"; -} - -#ifdef HAVE_XSYNC -G_GNUC_UNUSED static gint64 -sync_value_to_64 (const XSyncValue *value) -{ - gint64 v; - - v = XSyncValueLow32 (*value); - v |= (((gint64)XSyncValueHigh32 (*value)) << 32); - - return v; -} - -G_GNUC_UNUSED static const char* -alarm_state_to_string (XSyncAlarmState state) -{ - switch (state) - { - case XSyncAlarmActive: - return "Active"; - case XSyncAlarmInactive: - return "Inactive"; - case XSyncAlarmDestroyed: - return "Destroyed"; - default: - return "(unknown)"; - } -} -#endif /* HAVE_XSYNC */ - -G_GNUC_UNUSED static void -meta_spew_xi2_event (MetaDisplay *display, - XIEvent *input_event, - const char **name_p, - char **extra_p) -{ - const char *name = NULL; - char *extra = NULL; - - XIEnterEvent *enter_event = (XIEnterEvent *) input_event; - - switch (input_event->evtype) - { - case XI_FocusIn: - name = "XI_FocusIn"; - break; - case XI_FocusOut: - name = "XI_FocusOut"; - break; - case XI_Enter: - name = "XI_Enter"; - break; - case XI_Leave: - name = "XI_Leave"; - break; -#ifdef HAVE_XI23 - case XI_BarrierHit: - name = "XI_BarrierHit"; - break; - case XI_BarrierLeave: - name = "XI_BarrierLeave"; - break; -#endif /* HAVE_XI23 */ - } - - switch (input_event->evtype) - { - case XI_FocusIn: - case XI_FocusOut: - extra = g_strdup_printf ("detail: %s mode: %s\n", - meta_event_detail_to_string (enter_event->detail), - meta_event_mode_to_string (enter_event->mode)); - break; - case XI_Enter: - case XI_Leave: - extra = g_strdup_printf ("win: 0x%lx root: 0x%lx mode: %s detail: %s focus: %d x: %g y: %g", - enter_event->event, - enter_event->root, - meta_event_mode_to_string (enter_event->mode), - meta_event_detail_to_string (enter_event->detail), - enter_event->focus, - enter_event->root_x, - enter_event->root_y); - break; - } - - *name_p = name; - *extra_p = extra; -} - -G_GNUC_UNUSED static void -meta_spew_core_event (MetaDisplay *display, - XEvent *event, - const char **name_p, - char **extra_p) -{ - const char *name = NULL; - char *extra = NULL; - - switch (event->type) - { - case KeymapNotify: - name = "KeymapNotify"; - break; - case Expose: - name = "Expose"; - break; - case GraphicsExpose: - name = "GraphicsExpose"; - break; - case NoExpose: - name = "NoExpose"; - break; - case VisibilityNotify: - name = "VisibilityNotify"; - break; - case CreateNotify: - name = "CreateNotify"; - extra = g_strdup_printf ("parent: 0x%lx window: 0x%lx", - event->xcreatewindow.parent, - event->xcreatewindow.window); - break; - case DestroyNotify: - name = "DestroyNotify"; - extra = g_strdup_printf ("event: 0x%lx window: 0x%lx", - event->xdestroywindow.event, - event->xdestroywindow.window); - break; - case UnmapNotify: - name = "UnmapNotify"; - extra = g_strdup_printf ("event: 0x%lx window: 0x%lx from_configure: %d", - event->xunmap.event, - event->xunmap.window, - event->xunmap.from_configure); - break; - case MapNotify: - name = "MapNotify"; - extra = g_strdup_printf ("event: 0x%lx window: 0x%lx override_redirect: %d", - event->xmap.event, - event->xmap.window, - event->xmap.override_redirect); - break; - case MapRequest: - name = "MapRequest"; - extra = g_strdup_printf ("window: 0x%lx parent: 0x%lx\n", - event->xmaprequest.window, - event->xmaprequest.parent); - break; - case ReparentNotify: - name = "ReparentNotify"; - extra = g_strdup_printf ("window: 0x%lx parent: 0x%lx event: 0x%lx\n", - event->xreparent.window, - event->xreparent.parent, - event->xreparent.event); - break; - case ConfigureNotify: - name = "ConfigureNotify"; - extra = g_strdup_printf ("x: %d y: %d w: %d h: %d above: 0x%lx override_redirect: %d", - event->xconfigure.x, - event->xconfigure.y, - event->xconfigure.width, - event->xconfigure.height, - event->xconfigure.above, - event->xconfigure.override_redirect); - break; - case ConfigureRequest: - name = "ConfigureRequest"; - extra = g_strdup_printf ("parent: 0x%lx window: 0x%lx x: %d %sy: %d %sw: %d %sh: %d %sborder: %d %sabove: %lx %sstackmode: %s %s", - event->xconfigurerequest.parent, - event->xconfigurerequest.window, - event->xconfigurerequest.x, - event->xconfigurerequest.value_mask & - CWX ? "" : "(unset) ", - event->xconfigurerequest.y, - event->xconfigurerequest.value_mask & - CWY ? "" : "(unset) ", - event->xconfigurerequest.width, - event->xconfigurerequest.value_mask & - CWWidth ? "" : "(unset) ", - event->xconfigurerequest.height, - event->xconfigurerequest.value_mask & - CWHeight ? "" : "(unset) ", - event->xconfigurerequest.border_width, - event->xconfigurerequest.value_mask & - CWBorderWidth ? "" : "(unset)", - event->xconfigurerequest.above, - event->xconfigurerequest.value_mask & - CWSibling ? "" : "(unset)", - stack_mode_to_string (event->xconfigurerequest.detail), - event->xconfigurerequest.value_mask & - CWStackMode ? "" : "(unset)"); - break; - case GravityNotify: - name = "GravityNotify"; - break; - case ResizeRequest: - name = "ResizeRequest"; - extra = g_strdup_printf ("width = %d height = %d", - event->xresizerequest.width, - event->xresizerequest.height); - break; - case CirculateNotify: - name = "CirculateNotify"; - break; - case CirculateRequest: - name = "CirculateRequest"; - break; - case PropertyNotify: - { - char *str; - const char *state; - - name = "PropertyNotify"; - - meta_error_trap_push (display); - str = XGetAtomName (display->xdisplay, - event->xproperty.atom); - meta_error_trap_pop (display); - - if (event->xproperty.state == PropertyNewValue) - state = "PropertyNewValue"; - else if (event->xproperty.state == PropertyDelete) - state = "PropertyDelete"; - else - state = "???"; - - extra = g_strdup_printf ("atom: %s state: %s", - str ? str : "(unknown atom)", - state); - meta_XFree (str); - } - break; - case SelectionClear: - name = "SelectionClear"; - break; - case SelectionRequest: - name = "SelectionRequest"; - break; - case SelectionNotify: - name = "SelectionNotify"; - break; - case ColormapNotify: - name = "ColormapNotify"; - break; - case ClientMessage: - { - char *str; - name = "ClientMessage"; - meta_error_trap_push (display); - str = XGetAtomName (display->xdisplay, - event->xclient.message_type); - meta_error_trap_pop (display); - extra = g_strdup_printf ("type: %s format: %d\n", - str ? str : "(unknown atom)", - event->xclient.format); - meta_XFree (str); - } - break; - case MappingNotify: - name = "MappingNotify"; - break; - default: -#ifdef HAVE_XSYNC - if (META_DISPLAY_HAS_XSYNC (display) && - event->type == (display->xsync_event_base + XSyncAlarmNotify)) - { - XSyncAlarmNotifyEvent *aevent = (XSyncAlarmNotifyEvent*) event; - - name = "XSyncAlarmNotify"; - extra = - g_strdup_printf ("alarm: 0x%lx" - " counter_value: %" G_GINT64_FORMAT - " alarm_value: %" G_GINT64_FORMAT - " time: %u alarm state: %s", - aevent->alarm, - (gint64) sync_value_to_64 (&aevent->counter_value), - (gint64) sync_value_to_64 (&aevent->alarm_value), - (unsigned int)aevent->time, - alarm_state_to_string (aevent->state)); - } - else -#endif /* HAVE_XSYNC */ -#ifdef HAVE_SHAPE - if (META_DISPLAY_HAS_SHAPE (display) && - event->type == (display->shape_event_base + ShapeNotify)) - { - XShapeEvent *sev = (XShapeEvent*) event; - - name = "ShapeNotify"; - - extra = - g_strdup_printf ("kind: %s " - "x: %d y: %d w: %u h: %u " - "shaped: %d", - sev->kind == ShapeBounding ? - "ShapeBounding" : - (sev->kind == ShapeClip ? - "ShapeClip" : "(unknown)"), - sev->x, sev->y, sev->width, sev->height, - sev->shaped); - } - else -#endif /* HAVE_SHAPE */ - { - name = "(Unknown event)"; - extra = g_strdup_printf ("type: %d", event->xany.type); - } - break; - } - - *name_p = name; - *extra_p = extra; -} - -G_GNUC_UNUSED static void -meta_spew_event (MetaDisplay *display, - XEvent *event) -{ - const char *name = NULL; - char *extra = NULL; - char *winname; - MetaScreen *screen; - XIEvent *input_event; - - /* filter overnumerous events */ - if (event->type == Expose || event->type == MotionNotify || - event->type == NoExpose) - return; - - if (event->type == (display->damage_event_base + XDamageNotify)) - return; - - if (event->type == (display->xsync_event_base + XSyncAlarmNotify)) - return; - - if (event->type == PropertyNotify && event->xproperty.atom == display->atom__NET_WM_USER_TIME) - return; - - input_event = get_input_event (display, event); - - if (input_event) - meta_spew_xi2_event (display, input_event, &name, &extra); - else - meta_spew_core_event (display, event, &name, &extra); - - screen = meta_display_screen_for_root (display, event->xany.window); - - if (screen) - winname = g_strdup_printf ("root %d", screen->number); - else - winname = g_strdup_printf ("0x%lx", event->xany.window); - - g_print ("%s on %s%s %s %sserial %lu\n", name, winname, - extra ? ":" : "", extra ? extra : "", - event->xany.send_event ? "SEND " : "", - event->xany.serial); - - g_free (winname); - - if (extra) - g_free (extra); -} - MetaWindow* meta_display_lookup_x_window (MetaDisplay *display, Window xwindow) @@ -4020,7 +2057,7 @@ meta_display_begin_grab_op (MetaDisplay *display, meta_display_set_grab_op_cursor (display, screen, op, grab_xwindow, timestamp); - if (!display->grab_have_pointer && !grab_op_is_keyboard (op)) + if (!display->grab_have_pointer && !meta_grab_op_is_keyboard (op)) { meta_topic (META_DEBUG_WINDOW_OPS, "XIGrabDevice() failed\n"); @@ -4028,7 +2065,7 @@ meta_display_begin_grab_op (MetaDisplay *display, } /* Grab keys for keyboard ops and mouse move/resizes; see #126497 */ - if (grab_op_is_keyboard (op) || grab_op_is_mouse_only (op)) + if (meta_grab_op_is_keyboard (op) || grab_op_is_mouse_only (op)) { if (grab_window) display->grab_have_keyboard = @@ -4704,66 +2741,6 @@ meta_display_ping_window (MetaWindow *window, META_WINDOW_GET_CLASS (window)->ping (window, timestamp); } -static void -process_request_frame_extents (MetaDisplay *display, - XEvent *event) -{ - /* The X window whose frame extents will be set. */ - Window xwindow = event->xclient.window; - unsigned long data[4] = { 0, 0, 0, 0 }; - - MotifWmHints *hints = NULL; - gboolean hints_set = FALSE; - - meta_verbose ("Setting frame extents for 0x%lx\n", xwindow); - - /* See if the window is decorated. */ - hints_set = meta_prop_get_motif_hints (display, - xwindow, - display->atom__MOTIF_WM_HINTS, - &hints); - if ((hints_set && hints->decorations) || !hints_set) - { - MetaFrameBorders borders; - MetaScreen *screen; - - screen = meta_display_screen_for_xwindow (display, - event->xclient.window); - if (screen == NULL) - { - meta_warning ("Received request to set _NET_FRAME_EXTENTS " - "on 0x%lx which is on a screen we are not managing\n", - event->xclient.window); - meta_XFree (hints); - return; - } - - /* Return estimated frame extents for a normal window. */ - meta_ui_theme_get_frame_borders (screen->ui, - META_FRAME_TYPE_NORMAL, - 0, - &borders); - data[0] = borders.visible.left; - data[1] = borders.visible.right; - data[2] = borders.visible.top; - data[3] = borders.visible.bottom; - } - - meta_topic (META_DEBUG_GEOMETRY, - "Setting _NET_FRAME_EXTENTS on unmanaged window 0x%lx " - "to top = %lu, left = %lu, bottom = %lu, right = %lu\n", - xwindow, data[0], data[1], data[2], data[3]); - - meta_error_trap_push (display); - XChangeProperty (display->xdisplay, xwindow, - display->atom__NET_FRAME_EXTENTS, - XA_CARDINAL, - 32, PropModeReplace, (guchar*) data, 4); - meta_error_trap_pop (display); - - meta_XFree (hints); -} - /** * meta_display_pong_for_serial: * @display: the display we got the pong from @@ -5145,222 +3122,6 @@ meta_resize_gravity_from_grab_op (MetaGrabOp op) return gravity; } -static MetaScreen* -find_screen_for_selection (MetaDisplay *display, - Window owner, - Atom selection) -{ - GSList *tmp; - - tmp = display->screens; - while (tmp != NULL) - { - MetaScreen *screen = tmp->data; - - if (screen->wm_sn_selection_window == owner && - screen->wm_sn_atom == selection) - return screen; - - tmp = tmp->next; - } - - return NULL; -} - -/* from fvwm2, Copyright Matthias Clasen, Dominik Vogt */ -static gboolean -convert_property (MetaDisplay *display, - MetaScreen *screen, - Window w, - Atom target, - Atom property) -{ -#define N_TARGETS 4 - Atom conversion_targets[N_TARGETS]; - long icccm_version[] = { 2, 0 }; - - conversion_targets[0] = display->atom_TARGETS; - conversion_targets[1] = display->atom_MULTIPLE; - conversion_targets[2] = display->atom_TIMESTAMP; - conversion_targets[3] = display->atom_VERSION; - - meta_error_trap_push_with_return (display); - if (target == display->atom_TARGETS) - XChangeProperty (display->xdisplay, w, property, - XA_ATOM, 32, PropModeReplace, - (unsigned char *)conversion_targets, N_TARGETS); - else if (target == display->atom_TIMESTAMP) - XChangeProperty (display->xdisplay, w, property, - XA_INTEGER, 32, PropModeReplace, - (unsigned char *)&screen->wm_sn_timestamp, 1); - else if (target == display->atom_VERSION) - XChangeProperty (display->xdisplay, w, property, - XA_INTEGER, 32, PropModeReplace, - (unsigned char *)icccm_version, 2); - else - { - meta_error_trap_pop_with_return (display); - return FALSE; - } - - if (meta_error_trap_pop_with_return (display) != Success) - return FALSE; - - /* Be sure the PropertyNotify has arrived so we - * can send SelectionNotify - */ - /* FIXME the error trap pop synced anyway, right? */ - meta_topic (META_DEBUG_SYNC, "Syncing on %s\n", G_STRFUNC); - XSync (display->xdisplay, False); - - return TRUE; -} - -/* from fvwm2, Copyright Matthias Clasen, Dominik Vogt */ -static void -process_selection_request (MetaDisplay *display, - XEvent *event) -{ - XSelectionEvent reply; - MetaScreen *screen; - - screen = find_screen_for_selection (display, - event->xselectionrequest.owner, - event->xselectionrequest.selection); - - if (screen == NULL) - { - char *str; - - meta_error_trap_push (display); - str = XGetAtomName (display->xdisplay, - event->xselectionrequest.selection); - meta_error_trap_pop (display); - - meta_verbose ("Selection request with selection %s window 0x%lx not a WM_Sn selection we recognize\n", - str ? str : "(bad atom)", event->xselectionrequest.owner); - - meta_XFree (str); - - return; - } - - reply.type = SelectionNotify; - reply.display = display->xdisplay; - reply.requestor = event->xselectionrequest.requestor; - reply.selection = event->xselectionrequest.selection; - reply.target = event->xselectionrequest.target; - reply.property = None; - reply.time = event->xselectionrequest.time; - - if (event->xselectionrequest.target == display->atom_MULTIPLE) - { - if (event->xselectionrequest.property != None) - { - Atom type, *adata; - int i, format; - unsigned long num, rest; - unsigned char *data; - - meta_error_trap_push_with_return (display); - if (XGetWindowProperty (display->xdisplay, - event->xselectionrequest.requestor, - event->xselectionrequest.property, 0, 256, False, - display->atom_ATOM_PAIR, - &type, &format, &num, &rest, &data) != Success) - { - meta_error_trap_pop_with_return (display); - return; - } - - if (meta_error_trap_pop_with_return (display) == Success) - { - /* FIXME: to be 100% correct, should deal with rest > 0, - * but since we have 4 possible targets, we will hardly ever - * meet multiple requests with a length > 8 - */ - adata = (Atom*)data; - i = 0; - while (i < (int) num) - { - if (!convert_property (display, screen, - event->xselectionrequest.requestor, - adata[i], adata[i+1])) - adata[i+1] = None; - i += 2; - } - - meta_error_trap_push (display); - XChangeProperty (display->xdisplay, - event->xselectionrequest.requestor, - event->xselectionrequest.property, - display->atom_ATOM_PAIR, - 32, PropModeReplace, data, num); - meta_error_trap_pop (display); - meta_XFree (data); - } - } - } - else - { - if (event->xselectionrequest.property == None) - event->xselectionrequest.property = event->xselectionrequest.target; - - if (convert_property (display, screen, - event->xselectionrequest.requestor, - event->xselectionrequest.target, - event->xselectionrequest.property)) - reply.property = event->xselectionrequest.property; - } - - XSendEvent (display->xdisplay, - event->xselectionrequest.requestor, - False, 0L, (XEvent*)&reply); - - meta_verbose ("Handled selection request\n"); -} - -static void -process_selection_clear (MetaDisplay *display, - XEvent *event) -{ - /* We need to unmanage the screen on which we lost the selection */ - MetaScreen *screen; - - screen = find_screen_for_selection (display, - event->xselectionclear.window, - event->xselectionclear.selection); - - - if (screen != NULL) - { - meta_verbose ("Got selection clear for screen %d on display %s\n", - screen->number, display->name); - - meta_display_unmanage_screen (display, - screen, - event->xselectionclear.time); - - /* display and screen may both be invalid memory... */ - - return; - } - - { - char *str; - - meta_error_trap_push (display); - str = XGetAtomName (display->xdisplay, - event->xselectionclear.selection); - meta_error_trap_pop (display); - - meta_verbose ("Selection clear with selection %s window 0x%lx not a WM_Sn selection we recognize\n", - str ? str : "(bad atom)", event->xselectionclear.window); - - meta_XFree (str); - } -} - void meta_display_unmanage_screen (MetaDisplay *display, MetaScreen *screen, @@ -5584,9 +3345,9 @@ meta_display_focus_sentinel_clear (MetaDisplay *display) return (display->sentinel_counter == 0); } -static void -sanity_check_timestamps (MetaDisplay *display, - guint32 timestamp) +void +meta_display_sanity_check_timestamps (MetaDisplay *display, + guint32 timestamp) { if (XSERVER_TIME_IS_BEFORE (timestamp, display->last_focus_time)) { diff --git a/src/core/events.c b/src/core/events.c new file mode 100644 index 000000000..b37c77a99 --- /dev/null +++ b/src/core/events.c @@ -0,0 +1,2265 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2001 Havoc Pennington + * Copyright (C) 2002, 2003, 2004 Red Hat, Inc. + * Copyright (C) 2003, 2004 Rob Adams + * Copyright (C) 2004-2006 Elijah Newren + * + * 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 "config.h" +#include "events.h" + +#include +#include +#ifdef HAVE_SHAPE +#include +#endif + +#include +#include "display-private.h" +#include "window-private.h" +#include "bell.h" +#include "workspace-private.h" +#include "meta-idle-monitor-private.h" + +#include "x11/window-x11.h" +#include "x11/xprops.h" +#include "wayland/meta-wayland-private.h" +#include "meta-surface-actor-wayland.h" + +static MetaWindow * +get_window_for_event (MetaDisplay *display, + const ClutterEvent *event) +{ + ClutterActor *source; + + if (display->grab_op != META_GRAB_OP_NONE) + return display->grab_window; + + /* Always use the key focused window for key events. */ + switch (event->type) + { + case CLUTTER_KEY_PRESS: + case CLUTTER_KEY_RELEASE: + return display->focus_window; + default: + break; + } + + source = clutter_event_get_source (event); + if (META_IS_SURFACE_ACTOR (source)) + return meta_surface_actor_get_window (META_SURFACE_ACTOR (source)); + + return NULL; +} + +static XIEvent * +get_input_event (MetaDisplay *display, + XEvent *event) +{ + if (event->type == GenericEvent && + event->xcookie.extension == display->xinput_opcode) + { + XIEvent *input_event; + + /* NB: GDK event filters already have generic events + * allocated, so no need to do XGetEventData() on our own + */ + input_event = (XIEvent *) event->xcookie.data; + + switch (input_event->evtype) + { + case XI_Motion: + case XI_ButtonPress: + case XI_ButtonRelease: + if (((XIDeviceEvent *) input_event)->deviceid == META_VIRTUAL_CORE_POINTER_ID) + return input_event; + break; + case XI_KeyPress: + case XI_KeyRelease: + if (((XIDeviceEvent *) input_event)->deviceid == META_VIRTUAL_CORE_KEYBOARD_ID) + return input_event; + break; + case XI_FocusIn: + case XI_FocusOut: + if (((XIEnterEvent *) input_event)->deviceid == META_VIRTUAL_CORE_KEYBOARD_ID) + return input_event; + break; + case XI_Enter: + case XI_Leave: + if (((XIEnterEvent *) input_event)->deviceid == META_VIRTUAL_CORE_POINTER_ID) + return input_event; + break; +#ifdef HAVE_XI23 + case XI_BarrierHit: + case XI_BarrierLeave: + if (((XIBarrierEvent *) input_event)->deviceid == META_VIRTUAL_CORE_POINTER_ID) + return input_event; + break; +#endif /* HAVE_XI23 */ + default: + break; + } + } + + return NULL; +} + +static Window +xievent_get_modified_window (MetaDisplay *display, + XIEvent *input_event) +{ + switch (input_event->evtype) + { + case XI_Motion: + case XI_ButtonPress: + case XI_ButtonRelease: + case XI_KeyPress: + case XI_KeyRelease: + return ((XIDeviceEvent *) input_event)->event; + case XI_FocusIn: + case XI_FocusOut: + case XI_Enter: + case XI_Leave: + return ((XIEnterEvent *) input_event)->event; +#ifdef HAVE_XI23 + case XI_BarrierHit: + case XI_BarrierLeave: + return ((XIBarrierEvent *) input_event)->event; +#endif /* HAVE_XI23 */ + } + + return None; +} + +/* Return the window this has to do with, if any, rather + * than the frame or root window that was selecting + * for substructure + */ +static Window +event_get_modified_window (MetaDisplay *display, + XEvent *event) +{ + XIEvent *input_event = get_input_event (display, event); + + if (input_event) + return xievent_get_modified_window (display, input_event); + + switch (event->type) + { + case KeymapNotify: + case Expose: + case GraphicsExpose: + case NoExpose: + case VisibilityNotify: + case ResizeRequest: + case PropertyNotify: + case SelectionClear: + case SelectionRequest: + case SelectionNotify: + case ColormapNotify: + case ClientMessage: + return event->xany.window; + + case CreateNotify: + return event->xcreatewindow.window; + + case DestroyNotify: + return event->xdestroywindow.window; + + case UnmapNotify: + return event->xunmap.window; + + case MapNotify: + return event->xmap.window; + + case MapRequest: + return event->xmaprequest.window; + + case ReparentNotify: + return event->xreparent.window; + + case ConfigureNotify: + return event->xconfigure.window; + + case ConfigureRequest: + return event->xconfigurerequest.window; + + case GravityNotify: + return event->xgravity.window; + + case CirculateNotify: + return event->xcirculate.window; + + case CirculateRequest: + return event->xcirculaterequest.window; + + case MappingNotify: + return None; + + default: +#ifdef HAVE_SHAPE + if (META_DISPLAY_HAS_SHAPE (display) && + event->type == (display->shape_event_base + ShapeNotify)) + { + XShapeEvent *sev = (XShapeEvent*) event; + return sev->window; + } +#endif + + return None; + } +} + +static guint32 +event_get_time (MetaDisplay *display, + XEvent *event) +{ + XIEvent *input_event = get_input_event (display, event); + + if (input_event) + return input_event->time; + + switch (event->type) + { + case PropertyNotify: + return event->xproperty.time; + + case SelectionClear: + case SelectionRequest: + case SelectionNotify: + return event->xselection.time; + + case KeymapNotify: + case Expose: + case GraphicsExpose: + case NoExpose: + case MapNotify: + case UnmapNotify: + case VisibilityNotify: + case ResizeRequest: + case ColormapNotify: + case ClientMessage: + case CreateNotify: + case DestroyNotify: + case MapRequest: + case ReparentNotify: + case ConfigureNotify: + case ConfigureRequest: + case GravityNotify: + case CirculateNotify: + case CirculateRequest: + case MappingNotify: + default: + return CurrentTime; + } +} + +G_GNUC_UNUSED const char* +meta_event_detail_to_string (int d) +{ + const char *detail = "???"; + switch (d) + { + /* We are an ancestor in the A<->B focus change relationship */ + case XINotifyAncestor: + detail = "NotifyAncestor"; + break; + case XINotifyDetailNone: + detail = "NotifyDetailNone"; + break; + /* We are a descendant in the A<->B focus change relationship */ + case XINotifyInferior: + detail = "NotifyInferior"; + break; + case XINotifyNonlinear: + detail = "NotifyNonlinear"; + break; + case XINotifyNonlinearVirtual: + detail = "NotifyNonlinearVirtual"; + break; + case XINotifyPointer: + detail = "NotifyPointer"; + break; + case XINotifyPointerRoot: + detail = "NotifyPointerRoot"; + break; + case XINotifyVirtual: + detail = "NotifyVirtual"; + break; + } + + return detail; +} + +G_GNUC_UNUSED const char* +meta_event_mode_to_string (int m) +{ + const char *mode = "???"; + switch (m) + { + case XINotifyNormal: + mode = "NotifyNormal"; + break; + case XINotifyGrab: + mode = "NotifyGrab"; + break; + case XINotifyUngrab: + mode = "NotifyUngrab"; + break; + case XINotifyWhileGrabbed: + mode = "NotifyWhileGrabbed"; + break; + } + + return mode; +} + +G_GNUC_UNUSED static const char* +stack_mode_to_string (int mode) +{ + switch (mode) + { + case Above: + return "Above"; + case Below: + return "Below"; + case TopIf: + return "TopIf"; + case BottomIf: + return "BottomIf"; + case Opposite: + return "Opposite"; + } + + return "Unknown"; +} + +#ifdef HAVE_XSYNC +G_GNUC_UNUSED static gint64 +sync_value_to_64 (const XSyncValue *value) +{ + gint64 v; + + v = XSyncValueLow32 (*value); + v |= (((gint64)XSyncValueHigh32 (*value)) << 32); + + return v; +} + +G_GNUC_UNUSED static const char* +alarm_state_to_string (XSyncAlarmState state) +{ + switch (state) + { + case XSyncAlarmActive: + return "Active"; + case XSyncAlarmInactive: + return "Inactive"; + case XSyncAlarmDestroyed: + return "Destroyed"; + default: + return "(unknown)"; + } +} +#endif /* HAVE_XSYNC */ + +G_GNUC_UNUSED static void +meta_spew_xi2_event (MetaDisplay *display, + XIEvent *input_event, + const char **name_p, + char **extra_p) +{ + const char *name = NULL; + char *extra = NULL; + + XIEnterEvent *enter_event = (XIEnterEvent *) input_event; + + switch (input_event->evtype) + { + case XI_FocusIn: + name = "XI_FocusIn"; + break; + case XI_FocusOut: + name = "XI_FocusOut"; + break; + case XI_Enter: + name = "XI_Enter"; + break; + case XI_Leave: + name = "XI_Leave"; + break; +#ifdef HAVE_XI23 + case XI_BarrierHit: + name = "XI_BarrierHit"; + break; + case XI_BarrierLeave: + name = "XI_BarrierLeave"; + break; +#endif /* HAVE_XI23 */ + } + + switch (input_event->evtype) + { + case XI_FocusIn: + case XI_FocusOut: + extra = g_strdup_printf ("detail: %s mode: %s\n", + meta_event_detail_to_string (enter_event->detail), + meta_event_mode_to_string (enter_event->mode)); + break; + case XI_Enter: + case XI_Leave: + extra = g_strdup_printf ("win: 0x%lx root: 0x%lx mode: %s detail: %s focus: %d x: %g y: %g", + enter_event->event, + enter_event->root, + meta_event_mode_to_string (enter_event->mode), + meta_event_detail_to_string (enter_event->detail), + enter_event->focus, + enter_event->root_x, + enter_event->root_y); + break; + } + + *name_p = name; + *extra_p = extra; +} + +G_GNUC_UNUSED static void +meta_spew_core_event (MetaDisplay *display, + XEvent *event, + const char **name_p, + char **extra_p) +{ + const char *name = NULL; + char *extra = NULL; + + switch (event->type) + { + case KeymapNotify: + name = "KeymapNotify"; + break; + case Expose: + name = "Expose"; + break; + case GraphicsExpose: + name = "GraphicsExpose"; + break; + case NoExpose: + name = "NoExpose"; + break; + case VisibilityNotify: + name = "VisibilityNotify"; + break; + case CreateNotify: + name = "CreateNotify"; + extra = g_strdup_printf ("parent: 0x%lx window: 0x%lx", + event->xcreatewindow.parent, + event->xcreatewindow.window); + break; + case DestroyNotify: + name = "DestroyNotify"; + extra = g_strdup_printf ("event: 0x%lx window: 0x%lx", + event->xdestroywindow.event, + event->xdestroywindow.window); + break; + case UnmapNotify: + name = "UnmapNotify"; + extra = g_strdup_printf ("event: 0x%lx window: 0x%lx from_configure: %d", + event->xunmap.event, + event->xunmap.window, + event->xunmap.from_configure); + break; + case MapNotify: + name = "MapNotify"; + extra = g_strdup_printf ("event: 0x%lx window: 0x%lx override_redirect: %d", + event->xmap.event, + event->xmap.window, + event->xmap.override_redirect); + break; + case MapRequest: + name = "MapRequest"; + extra = g_strdup_printf ("window: 0x%lx parent: 0x%lx\n", + event->xmaprequest.window, + event->xmaprequest.parent); + break; + case ReparentNotify: + name = "ReparentNotify"; + extra = g_strdup_printf ("window: 0x%lx parent: 0x%lx event: 0x%lx\n", + event->xreparent.window, + event->xreparent.parent, + event->xreparent.event); + break; + case ConfigureNotify: + name = "ConfigureNotify"; + extra = g_strdup_printf ("x: %d y: %d w: %d h: %d above: 0x%lx override_redirect: %d", + event->xconfigure.x, + event->xconfigure.y, + event->xconfigure.width, + event->xconfigure.height, + event->xconfigure.above, + event->xconfigure.override_redirect); + break; + case ConfigureRequest: + name = "ConfigureRequest"; + extra = g_strdup_printf ("parent: 0x%lx window: 0x%lx x: %d %sy: %d %sw: %d %sh: %d %sborder: %d %sabove: %lx %sstackmode: %s %s", + event->xconfigurerequest.parent, + event->xconfigurerequest.window, + event->xconfigurerequest.x, + event->xconfigurerequest.value_mask & + CWX ? "" : "(unset) ", + event->xconfigurerequest.y, + event->xconfigurerequest.value_mask & + CWY ? "" : "(unset) ", + event->xconfigurerequest.width, + event->xconfigurerequest.value_mask & + CWWidth ? "" : "(unset) ", + event->xconfigurerequest.height, + event->xconfigurerequest.value_mask & + CWHeight ? "" : "(unset) ", + event->xconfigurerequest.border_width, + event->xconfigurerequest.value_mask & + CWBorderWidth ? "" : "(unset)", + event->xconfigurerequest.above, + event->xconfigurerequest.value_mask & + CWSibling ? "" : "(unset)", + stack_mode_to_string (event->xconfigurerequest.detail), + event->xconfigurerequest.value_mask & + CWStackMode ? "" : "(unset)"); + break; + case GravityNotify: + name = "GravityNotify"; + break; + case ResizeRequest: + name = "ResizeRequest"; + extra = g_strdup_printf ("width = %d height = %d", + event->xresizerequest.width, + event->xresizerequest.height); + break; + case CirculateNotify: + name = "CirculateNotify"; + break; + case CirculateRequest: + name = "CirculateRequest"; + break; + case PropertyNotify: + { + char *str; + const char *state; + + name = "PropertyNotify"; + + meta_error_trap_push (display); + str = XGetAtomName (display->xdisplay, + event->xproperty.atom); + meta_error_trap_pop (display); + + if (event->xproperty.state == PropertyNewValue) + state = "PropertyNewValue"; + else if (event->xproperty.state == PropertyDelete) + state = "PropertyDelete"; + else + state = "???"; + + extra = g_strdup_printf ("atom: %s state: %s", + str ? str : "(unknown atom)", + state); + meta_XFree (str); + } + break; + case SelectionClear: + name = "SelectionClear"; + break; + case SelectionRequest: + name = "SelectionRequest"; + break; + case SelectionNotify: + name = "SelectionNotify"; + break; + case ColormapNotify: + name = "ColormapNotify"; + break; + case ClientMessage: + { + char *str; + name = "ClientMessage"; + meta_error_trap_push (display); + str = XGetAtomName (display->xdisplay, + event->xclient.message_type); + meta_error_trap_pop (display); + extra = g_strdup_printf ("type: %s format: %d\n", + str ? str : "(unknown atom)", + event->xclient.format); + meta_XFree (str); + } + break; + case MappingNotify: + name = "MappingNotify"; + break; + default: +#ifdef HAVE_XSYNC + if (META_DISPLAY_HAS_XSYNC (display) && + event->type == (display->xsync_event_base + XSyncAlarmNotify)) + { + XSyncAlarmNotifyEvent *aevent = (XSyncAlarmNotifyEvent*) event; + + name = "XSyncAlarmNotify"; + extra = + g_strdup_printf ("alarm: 0x%lx" + " counter_value: %" G_GINT64_FORMAT + " alarm_value: %" G_GINT64_FORMAT + " time: %u alarm state: %s", + aevent->alarm, + (gint64) sync_value_to_64 (&aevent->counter_value), + (gint64) sync_value_to_64 (&aevent->alarm_value), + (unsigned int)aevent->time, + alarm_state_to_string (aevent->state)); + } + else +#endif /* HAVE_XSYNC */ +#ifdef HAVE_SHAPE + if (META_DISPLAY_HAS_SHAPE (display) && + event->type == (display->shape_event_base + ShapeNotify)) + { + XShapeEvent *sev = (XShapeEvent*) event; + + name = "ShapeNotify"; + + extra = + g_strdup_printf ("kind: %s " + "x: %d y: %d w: %u h: %u " + "shaped: %d", + sev->kind == ShapeBounding ? + "ShapeBounding" : + (sev->kind == ShapeClip ? + "ShapeClip" : "(unknown)"), + sev->x, sev->y, sev->width, sev->height, + sev->shaped); + } + else +#endif /* HAVE_SHAPE */ + { + name = "(Unknown event)"; + extra = g_strdup_printf ("type: %d", event->xany.type); + } + break; + } + + *name_p = name; + *extra_p = extra; +} + +G_GNUC_UNUSED static void +meta_spew_event (MetaDisplay *display, + XEvent *event) +{ + const char *name = NULL; + char *extra = NULL; + char *winname; + MetaScreen *screen; + XIEvent *input_event; + + /* filter overnumerous events */ + if (event->type == Expose || event->type == MotionNotify || + event->type == NoExpose) + return; + + if (event->type == (display->damage_event_base + XDamageNotify)) + return; + + if (event->type == (display->xsync_event_base + XSyncAlarmNotify)) + return; + + if (event->type == PropertyNotify && event->xproperty.atom == display->atom__NET_WM_USER_TIME) + return; + + input_event = get_input_event (display, event); + + if (input_event) + meta_spew_xi2_event (display, input_event, &name, &extra); + else + meta_spew_core_event (display, event, &name, &extra); + + screen = meta_display_screen_for_root (display, event->xany.window); + + if (screen) + winname = g_strdup_printf ("root %d", screen->number); + else + winname = g_strdup_printf ("0x%lx", event->xany.window); + + g_print ("%s on %s%s %s %sserial %lu\n", name, winname, + extra ? ":" : "", extra ? extra : "", + event->xany.send_event ? "SEND " : "", + event->xany.serial); + + g_free (winname); + + if (extra) + g_free (extra); +} + +static void +handle_window_focus_event (MetaDisplay *display, + MetaWindow *window, + XIEnterEvent *event, + unsigned long serial) +{ + MetaWindow *focus_window; +#ifdef WITH_VERBOSE_MODE + const char *window_type; + + /* Note the event can be on either the window or the frame, + * we focus the frame for shaded windows + */ + if (window) + { + if (event->event == window->xwindow) + window_type = "client window"; + else if (window->frame && event->event == window->frame->xwindow) + window_type = "frame window"; + else + window_type = "unknown client window"; + } + else if (meta_display_xwindow_is_a_no_focus_window (display, event->event)) + window_type = "no_focus_window"; + else if (meta_display_screen_for_root (display, event->event)) + window_type = "root window"; + else + window_type = "unknown window"; + + meta_topic (META_DEBUG_FOCUS, + "Focus %s event received on %s 0x%lx (%s) " + "mode %s detail %s serial %lu\n", + event->evtype == XI_FocusIn ? "in" : + event->evtype == XI_FocusOut ? "out" : + "???", + window ? window->desc : "", + event->event, window_type, + meta_event_mode_to_string (event->mode), + meta_event_detail_to_string (event->mode), + event->serial); +#endif + + /* FIXME our pointer tracking is broken; see how + * gtk+/gdk/x11/gdkevents-x11.c or XFree86/xc/programs/xterm/misc.c + * for how to handle it the correct way. In brief you need to track + * pointer focus and regular focus, and handle EnterNotify in + * PointerRoot mode with no window manager. However as noted above, + * accurate focus tracking will break things because we want to keep + * windows "focused" when using keybindings on them, and also we + * sometimes "focus" a window by focusing its frame or + * no_focus_window; so this all needs rethinking massively. + * + * My suggestion is to change it so that we clearly separate + * actual keyboard focus tracking using the xterm algorithm, + * and mutter's "pretend" focus window, and go through all + * the code and decide which one should be used in each place; + * a hard bit is deciding on a policy for that. + * + * http://bugzilla.gnome.org/show_bug.cgi?id=90382 + */ + + /* We ignore grabs, though this is questionable. It may be better to + * increase the intelligence of the focus window tracking. + * + * The problem is that keybindings for windows are done with + * XGrabKey, which means focus_window disappears and the front of + * the MRU list gets confused from what the user expects once a + * keybinding is used. + */ + + if (event->mode == XINotifyGrab || + event->mode == XINotifyUngrab || + /* From WindowMaker, ignore all funky pointer root events */ + event->detail > XINotifyNonlinearVirtual) + { + meta_topic (META_DEBUG_FOCUS, + "Ignoring focus event generated by a grab or other weirdness\n"); + return; + } + + if (event->evtype == XI_FocusIn) + { + display->server_focus_window = event->event; + display->server_focus_serial = serial; + focus_window = window; + } + else if (event->evtype == XI_FocusOut) + { + if (event->detail == XINotifyInferior) + { + /* This event means the client moved focus to a subwindow */ + meta_topic (META_DEBUG_FOCUS, + "Ignoring focus out with NotifyInferior\n"); + return; + } + + display->server_focus_window = None; + display->server_focus_serial = serial; + focus_window = NULL; + } + else + g_return_if_reached (); + + /* If display->focused_by_us, then the focus_serial will be used only + * for a focus change we made and have already accounted for. + * (See request_xserver_input_focus_change().) Otherwise, we can get + * multiple focus events with the same serial. + */ + if (display->server_focus_serial > display->focus_serial || + (!display->focused_by_us && + display->server_focus_serial == display->focus_serial)) + { + meta_display_update_focus_window (display, + focus_window, + focus_window ? focus_window->xwindow : None, + display->server_focus_serial, + FALSE); + } +} + +static gboolean +crossing_serial_is_ignored (MetaDisplay *display, + unsigned long serial) +{ + int i; + + i = 0; + while (i < N_IGNORED_CROSSING_SERIALS) + { + if (display->ignored_crossing_serials[i] == serial) + return TRUE; + ++i; + } + return FALSE; +} + +static gboolean +handle_input_xevent (MetaDisplay *display, + XIEvent *input_event, + gulong serial) +{ + XIEnterEvent *enter_event = (XIEnterEvent *) input_event; + Window modified; + MetaWindow *window; + MetaScreen *screen; + + if (input_event == NULL) + return FALSE; + + modified = xievent_get_modified_window (display, input_event); + window = modified != None ? meta_display_lookup_x_window (display, modified) : NULL; + + switch (input_event->evtype) + { + case XI_Enter: + if (display->grab_op == META_GRAB_OP_COMPOSITOR) + break; + + /* If the mouse switches screens, active the default window on the new + * screen; this will make keybindings and workspace-launched items + * actually appear on the right screen. + */ + { + MetaScreen *new_screen = + meta_display_screen_for_root (display, enter_event->root); + + if (new_screen != NULL && display->active_screen != new_screen) + meta_workspace_focus_default_window (new_screen->active_workspace, + NULL, + enter_event->time); + } + + /* Check if we've entered a window; do this even if window->has_focus to + * avoid races. + */ + if (window && !crossing_serial_is_ignored (display, serial) && + enter_event->mode != XINotifyGrab && + enter_event->mode != XINotifyUngrab && + enter_event->detail != XINotifyInferior && + meta_display_focus_sentinel_clear (display)) + { + meta_window_handle_enter (window, + enter_event->time, + enter_event->root_x, + enter_event->root_y); + + if (window->type == META_WINDOW_DOCK) + meta_window_raise (window); + } + break; + case XI_Leave: + if (display->grab_op == META_GRAB_OP_COMPOSITOR) + break; + + if (window != NULL) + { + if (window->type == META_WINDOW_DOCK && + enter_event->mode != XINotifyGrab && + enter_event->mode != XINotifyUngrab && + !window->has_focus) + meta_window_lower (window); + } + break; + case XI_FocusIn: + case XI_FocusOut: + handle_window_focus_event (display, window, enter_event, serial); + if (!window) + { + /* Check if the window is a root window. */ + if (enter_event->root != enter_event->event) + break; + + screen = meta_display_screen_for_root (display, enter_event->root); + + if (enter_event->evtype == XI_FocusIn && + enter_event->mode == XINotifyDetailNone) + { + meta_topic (META_DEBUG_FOCUS, + "Focus got set to None, probably due to " + "brain-damage in the X protocol (see bug " + "125492). Setting the default focus window.\n"); + meta_workspace_focus_default_window (screen->active_workspace, + NULL, + meta_display_get_current_time_roundtrip (display)); + } + else if (enter_event->evtype == XI_FocusIn && + enter_event->mode == XINotifyNormal && + enter_event->detail == XINotifyInferior) + { + meta_topic (META_DEBUG_FOCUS, + "Focus got set to root window, probably due to " + "gnome-session logout dialog usage (see bug " + "153220). Setting the default focus window.\n"); + meta_workspace_focus_default_window (screen->active_workspace, + NULL, + meta_display_get_current_time_roundtrip (display)); + } + + } + + /* Don't send FocusIn / FocusOut to Clutter */ + return TRUE; + } + + return FALSE; +} + +static void +reload_xkb_rules (MetaScreen *screen) +{ + MetaWaylandCompositor *compositor; + char **names; + int n_names; + gboolean ok; + const char *rules, *model, *layout, *variant, *options; + + compositor = meta_wayland_compositor_get_default (); + + ok = meta_prop_get_latin1_list (screen->display, screen->xroot, + screen->display->atom__XKB_RULES_NAMES, + &names, &n_names); + if (!ok) + return; + + if (n_names != 5) + goto out; + + rules = names[0]; + model = names[1]; + layout = names[2]; + variant = names[3]; + options = names[4]; + + meta_wayland_keyboard_set_keymap_names (&compositor->seat->keyboard, + rules, model, layout, variant, options, + META_WAYLAND_KEYBOARD_SKIP_XCLIENTS); + + out: + g_strfreev (names); +} + +static void +process_request_frame_extents (MetaDisplay *display, + XEvent *event) +{ + /* The X window whose frame extents will be set. */ + Window xwindow = event->xclient.window; + unsigned long data[4] = { 0, 0, 0, 0 }; + + MotifWmHints *hints = NULL; + gboolean hints_set = FALSE; + + meta_verbose ("Setting frame extents for 0x%lx\n", xwindow); + + /* See if the window is decorated. */ + hints_set = meta_prop_get_motif_hints (display, + xwindow, + display->atom__MOTIF_WM_HINTS, + &hints); + if ((hints_set && hints->decorations) || !hints_set) + { + MetaFrameBorders borders; + MetaScreen *screen; + + screen = meta_display_screen_for_xwindow (display, + event->xclient.window); + if (screen == NULL) + { + meta_warning ("Received request to set _NET_FRAME_EXTENTS " + "on 0x%lx which is on a screen we are not managing\n", + event->xclient.window); + meta_XFree (hints); + return; + } + + /* Return estimated frame extents for a normal window. */ + meta_ui_theme_get_frame_borders (screen->ui, + META_FRAME_TYPE_NORMAL, + 0, + &borders); + data[0] = borders.visible.left; + data[1] = borders.visible.right; + data[2] = borders.visible.top; + data[3] = borders.visible.bottom; + } + + meta_topic (META_DEBUG_GEOMETRY, + "Setting _NET_FRAME_EXTENTS on unmanaged window 0x%lx " + "to top = %lu, left = %lu, bottom = %lu, right = %lu\n", + xwindow, data[0], data[1], data[2], data[3]); + + meta_error_trap_push (display); + XChangeProperty (display->xdisplay, xwindow, + display->atom__NET_FRAME_EXTENTS, + XA_CARDINAL, + 32, PropModeReplace, (guchar*) data, 4); + meta_error_trap_pop (display); + + meta_XFree (hints); +} + +static MetaScreen* +find_screen_for_selection (MetaDisplay *display, + Window owner, + Atom selection) +{ + GSList *tmp; + + tmp = display->screens; + while (tmp != NULL) + { + MetaScreen *screen = tmp->data; + + if (screen->wm_sn_selection_window == owner && + screen->wm_sn_atom == selection) + return screen; + + tmp = tmp->next; + } + + return NULL; +} + +/* from fvwm2, Copyright Matthias Clasen, Dominik Vogt */ +static gboolean +convert_property (MetaDisplay *display, + MetaScreen *screen, + Window w, + Atom target, + Atom property) +{ +#define N_TARGETS 4 + Atom conversion_targets[N_TARGETS]; + long icccm_version[] = { 2, 0 }; + + conversion_targets[0] = display->atom_TARGETS; + conversion_targets[1] = display->atom_MULTIPLE; + conversion_targets[2] = display->atom_TIMESTAMP; + conversion_targets[3] = display->atom_VERSION; + + meta_error_trap_push_with_return (display); + if (target == display->atom_TARGETS) + XChangeProperty (display->xdisplay, w, property, + XA_ATOM, 32, PropModeReplace, + (unsigned char *)conversion_targets, N_TARGETS); + else if (target == display->atom_TIMESTAMP) + XChangeProperty (display->xdisplay, w, property, + XA_INTEGER, 32, PropModeReplace, + (unsigned char *)&screen->wm_sn_timestamp, 1); + else if (target == display->atom_VERSION) + XChangeProperty (display->xdisplay, w, property, + XA_INTEGER, 32, PropModeReplace, + (unsigned char *)icccm_version, 2); + else + { + meta_error_trap_pop_with_return (display); + return FALSE; + } + + if (meta_error_trap_pop_with_return (display) != Success) + return FALSE; + + /* Be sure the PropertyNotify has arrived so we + * can send SelectionNotify + */ + /* FIXME the error trap pop synced anyway, right? */ + meta_topic (META_DEBUG_SYNC, "Syncing on %s\n", G_STRFUNC); + XSync (display->xdisplay, False); + + return TRUE; +} + +/* from fvwm2, Copyright Matthias Clasen, Dominik Vogt */ +static void +process_selection_request (MetaDisplay *display, + XEvent *event) +{ + XSelectionEvent reply; + MetaScreen *screen; + + screen = find_screen_for_selection (display, + event->xselectionrequest.owner, + event->xselectionrequest.selection); + + if (screen == NULL) + { + char *str; + + meta_error_trap_push (display); + str = XGetAtomName (display->xdisplay, + event->xselectionrequest.selection); + meta_error_trap_pop (display); + + meta_verbose ("Selection request with selection %s window 0x%lx not a WM_Sn selection we recognize\n", + str ? str : "(bad atom)", event->xselectionrequest.owner); + + meta_XFree (str); + + return; + } + + reply.type = SelectionNotify; + reply.display = display->xdisplay; + reply.requestor = event->xselectionrequest.requestor; + reply.selection = event->xselectionrequest.selection; + reply.target = event->xselectionrequest.target; + reply.property = None; + reply.time = event->xselectionrequest.time; + + if (event->xselectionrequest.target == display->atom_MULTIPLE) + { + if (event->xselectionrequest.property != None) + { + Atom type, *adata; + int i, format; + unsigned long num, rest; + unsigned char *data; + + meta_error_trap_push_with_return (display); + if (XGetWindowProperty (display->xdisplay, + event->xselectionrequest.requestor, + event->xselectionrequest.property, 0, 256, False, + display->atom_ATOM_PAIR, + &type, &format, &num, &rest, &data) != Success) + { + meta_error_trap_pop_with_return (display); + return; + } + + if (meta_error_trap_pop_with_return (display) == Success) + { + /* FIXME: to be 100% correct, should deal with rest > 0, + * but since we have 4 possible targets, we will hardly ever + * meet multiple requests with a length > 8 + */ + adata = (Atom*)data; + i = 0; + while (i < (int) num) + { + if (!convert_property (display, screen, + event->xselectionrequest.requestor, + adata[i], adata[i+1])) + adata[i+1] = None; + i += 2; + } + + meta_error_trap_push (display); + XChangeProperty (display->xdisplay, + event->xselectionrequest.requestor, + event->xselectionrequest.property, + display->atom_ATOM_PAIR, + 32, PropModeReplace, data, num); + meta_error_trap_pop (display); + meta_XFree (data); + } + } + } + else + { + if (event->xselectionrequest.property == None) + event->xselectionrequest.property = event->xselectionrequest.target; + + if (convert_property (display, screen, + event->xselectionrequest.requestor, + event->xselectionrequest.target, + event->xselectionrequest.property)) + reply.property = event->xselectionrequest.property; + } + + XSendEvent (display->xdisplay, + event->xselectionrequest.requestor, + False, 0L, (XEvent*)&reply); + + meta_verbose ("Handled selection request\n"); +} + +static void +process_selection_clear (MetaDisplay *display, + XEvent *event) +{ + /* We need to unmanage the screen on which we lost the selection */ + MetaScreen *screen; + + screen = find_screen_for_selection (display, + event->xselectionclear.window, + event->xselectionclear.selection); + + + if (screen != NULL) + { + meta_verbose ("Got selection clear for screen %d on display %s\n", + screen->number, display->name); + + meta_display_unmanage_screen (display, + screen, + event->xselectionclear.time); + + /* display and screen may both be invalid memory... */ + + return; + } + + { + char *str; + + meta_error_trap_push (display); + str = XGetAtomName (display->xdisplay, + event->xselectionclear.selection); + meta_error_trap_pop (display); + + meta_verbose ("Selection clear with selection %s window 0x%lx not a WM_Sn selection we recognize\n", + str ? str : "(bad atom)", event->xselectionclear.window); + + meta_XFree (str); + } +} + +static gboolean +handle_other_xevent (MetaDisplay *display, + XEvent *event) +{ + Window modified; + MetaWindow *window; + MetaWindow *property_for_window; + gboolean frame_was_receiver; + gboolean bypass_gtk = FALSE; + + modified = event_get_modified_window (display, event); + window = modified != None ? meta_display_lookup_x_window (display, modified) : NULL; + frame_was_receiver = (window && window->frame && modified == window->frame->xwindow); + + /* We only want to respond to _NET_WM_USER_TIME property notify + * events on _NET_WM_USER_TIME_WINDOW windows; in particular, + * responding to UnmapNotify events is kind of bad. + */ + property_for_window = NULL; + if (window && modified == window->user_time_window) + { + property_for_window = window; + window = NULL; + } + +#ifdef HAVE_XSYNC + if (META_DISPLAY_HAS_XSYNC (display) && + event->type == (display->xsync_event_base + XSyncAlarmNotify)) + { + MetaWindow *alarm_window = meta_display_lookup_sync_alarm (display, + ((XSyncAlarmNotifyEvent*)event)->alarm); + + if (alarm_window != NULL) + { + XSyncValue value = ((XSyncAlarmNotifyEvent*)event)->counter_value; + gint64 new_counter_value; + new_counter_value = XSyncValueLow32 (value) + ((gint64)XSyncValueHigh32 (value) << 32); + meta_window_update_sync_request_counter (alarm_window, new_counter_value); + bypass_gtk = TRUE; /* GTK doesn't want to see this really */ + } + else + meta_idle_monitor_handle_xevent_all (event); + + goto out; + } +#endif /* HAVE_XSYNC */ + +#ifdef HAVE_SHAPE + if (META_DISPLAY_HAS_SHAPE (display) && + event->type == (display->shape_event_base + ShapeNotify)) + { + bypass_gtk = TRUE; /* GTK doesn't want to see this really */ + + if (window && !frame_was_receiver) + { + XShapeEvent *sev = (XShapeEvent*) event; + + if (sev->kind == ShapeBounding) + meta_window_x11_update_shape_region (window); + else if (sev->kind == ShapeInput) + meta_window_x11_update_input_region (window); + } + else + { + meta_topic (META_DEBUG_SHAPES, + "ShapeNotify not on a client window (window %s frame_was_receiver = %d)\n", + window ? window->desc : "(none)", + frame_was_receiver); + } + + goto out; + } +#endif /* HAVE_SHAPE */ + + switch (event->type) + { + case KeymapNotify: + break; + case Expose: + break; + case GraphicsExpose: + break; + case NoExpose: + break; + case VisibilityNotify: + break; + case CreateNotify: + { + MetaScreen *screen; + + screen = meta_display_screen_for_root (display, + event->xcreatewindow.parent); + if (screen) + meta_stack_tracker_create_event (screen->stack_tracker, + &event->xcreatewindow); + } + break; + + case DestroyNotify: + { + MetaScreen *screen; + + screen = meta_display_screen_for_root (display, + event->xdestroywindow.event); + if (screen) + meta_stack_tracker_destroy_event (screen->stack_tracker, + &event->xdestroywindow); + } + if (window) + { + /* FIXME: It sucks that DestroyNotify events don't come with + * a timestamp; could we do something better here? Maybe X + * will change one day? + */ + guint32 timestamp; + timestamp = meta_display_get_current_time_roundtrip (display); + + if (display->grab_op != META_GRAB_OP_NONE && + display->grab_window == window) + meta_display_end_grab_op (display, timestamp); + + if (frame_was_receiver) + { + meta_warning ("Unexpected destruction of frame 0x%lx, not sure if this should silently fail or be considered a bug\n", + window->frame->xwindow); + meta_error_trap_push (display); + meta_window_destroy_frame (window->frame->window); + meta_error_trap_pop (display); + } + else + { + /* Unmanage destroyed window */ + meta_window_unmanage (window, timestamp); + window = NULL; + } + } + break; + case UnmapNotify: + if (window) + { + /* FIXME: It sucks that UnmapNotify events don't come with + * a timestamp; could we do something better here? Maybe X + * will change one day? + */ + guint32 timestamp; + timestamp = meta_display_get_current_time_roundtrip (display); + + if (display->grab_op != META_GRAB_OP_NONE && + display->grab_window == window && + window->frame == NULL) + meta_display_end_grab_op (display, timestamp); + + if (!frame_was_receiver) + { + if (window->unmaps_pending == 0) + { + meta_topic (META_DEBUG_WINDOW_STATE, + "Window %s withdrawn\n", + window->desc); + + /* Unmanage withdrawn window */ + window->withdrawn = TRUE; + meta_window_unmanage (window, timestamp); + window = NULL; + } + else + { + window->unmaps_pending -= 1; + meta_topic (META_DEBUG_WINDOW_STATE, + "Received pending unmap, %d now pending\n", + window->unmaps_pending); + } + } + } + break; + case MapNotify: + /* NB: override redirect windows wont cause a map request so we + * watch out for map notifies against any root windows too if a + * compositor is enabled: */ + if (window == NULL + && meta_display_screen_for_root (display, event->xmap.event)) + { + window = meta_window_x11_new (display, event->xmap.window, + FALSE, META_COMP_EFFECT_CREATE); + } + break; + case MapRequest: + if (window == NULL) + { + window = meta_window_x11_new (display, event->xmaprequest.window, + FALSE, META_COMP_EFFECT_CREATE); + } + /* if frame was receiver it's some malicious send event or something */ + else if (!frame_was_receiver && window) + { + meta_verbose ("MapRequest on %s mapped = %d minimized = %d\n", + window->desc, window->mapped, window->minimized); + if (window->minimized) + { + meta_window_unminimize (window); + if (window->workspace != window->screen->active_workspace) + { + meta_verbose ("Changing workspace due to MapRequest mapped = %d minimized = %d\n", + window->mapped, window->minimized); + meta_window_change_workspace (window, + window->screen->active_workspace); + } + } + } + break; + case ReparentNotify: + { + MetaScreen *screen; + + screen = meta_display_screen_for_root (display, + event->xconfigure.event); + if (screen) + meta_stack_tracker_reparent_event (screen->stack_tracker, + &event->xreparent); + } + break; + case ConfigureNotify: + if (event->xconfigure.event != event->xconfigure.window) + { + MetaScreen *screen; + + screen = meta_display_screen_for_root (display, + event->xconfigure.event); + if (screen) + meta_stack_tracker_configure_event (screen->stack_tracker, + &event->xconfigure); + } + + if (window && window->override_redirect) + meta_window_x11_configure_notify (window, &event->xconfigure); + + break; + case ConfigureRequest: + /* This comment and code is found in both twm and fvwm */ + /* + * According to the July 27, 1988 ICCCM draft, we should ignore size and + * position fields in the WM_NORMAL_HINTS property when we map a window. + * Instead, we'll read the current geometry. Therefore, we should respond + * to configuration requests for windows which have never been mapped. + */ + if (window == NULL) + { + unsigned int xwcm; + XWindowChanges xwc; + + xwcm = event->xconfigurerequest.value_mask & + (CWX | CWY | CWWidth | CWHeight | CWBorderWidth); + + xwc.x = event->xconfigurerequest.x; + xwc.y = event->xconfigurerequest.y; + xwc.width = event->xconfigurerequest.width; + xwc.height = event->xconfigurerequest.height; + xwc.border_width = event->xconfigurerequest.border_width; + + meta_verbose ("Configuring withdrawn window to %d,%d %dx%d border %d (some values may not be in mask)\n", + xwc.x, xwc.y, xwc.width, xwc.height, xwc.border_width); + meta_error_trap_push (display); + XConfigureWindow (display->xdisplay, event->xconfigurerequest.window, + xwcm, &xwc); + meta_error_trap_pop (display); + } + else + { + if (!frame_was_receiver) + meta_window_x11_configure_request (window, event); + } + break; + case GravityNotify: + break; + case ResizeRequest: + break; + case CirculateNotify: + break; + case CirculateRequest: + break; + case PropertyNotify: + { + MetaGroup *group; + MetaScreen *screen; + + if (window && !frame_was_receiver) + meta_window_x11_property_notify (window, event); + else if (property_for_window && !frame_was_receiver) + meta_window_x11_property_notify (property_for_window, event); + + group = meta_display_lookup_group (display, + event->xproperty.window); + if (group != NULL) + meta_group_property_notify (group, event); + + screen = NULL; + if (window == NULL && + group == NULL) /* window/group != NULL means it wasn't a root window */ + screen = meta_display_screen_for_root (display, + event->xproperty.window); + + if (screen != NULL) + { + if (event->xproperty.atom == + display->atom__NET_DESKTOP_LAYOUT) + meta_screen_update_workspace_layout (screen); + else if (event->xproperty.atom == + display->atom__NET_DESKTOP_NAMES) + meta_screen_update_workspace_names (screen); + else if (meta_is_wayland_compositor () && + event->xproperty.atom == + display->atom__XKB_RULES_NAMES) + reload_xkb_rules (screen); +#if 0 + else if (event->xproperty.atom == + display->atom__NET_RESTACK_WINDOW) + handle_net_restack_window (display, event); +#endif + + /* we just use this property as a sentinel to avoid + * certain race conditions. See the comment for the + * sentinel_counter variable declaration in display.h + */ + if (event->xproperty.atom == + display->atom__MUTTER_SENTINEL) + { + meta_display_decrement_focus_sentinel (display); + } + } + } + break; + case SelectionClear: + /* do this here instead of at end of function + * so we can return + */ + + /* FIXME: Clearing display->current_time here makes no sense to + * me; who put this here and why? + */ + display->current_time = CurrentTime; + + process_selection_clear (display, event); + /* Note that processing that may have resulted in + * closing the display... so return right away. + */ + return FALSE; + case SelectionRequest: + process_selection_request (display, event); + break; + case SelectionNotify: + break; + case ColormapNotify: + if (window && !frame_was_receiver) + window->colormap = event->xcolormap.colormap; + break; + case ClientMessage: + if (window) + { + if (!frame_was_receiver) + meta_window_x11_client_message (window, event); + } + else + { + MetaScreen *screen; + + screen = meta_display_screen_for_root (display, + event->xclient.window); + + if (screen) + { + if (event->xclient.message_type == + display->atom__NET_CURRENT_DESKTOP) + { + int space; + MetaWorkspace *workspace; + guint32 time; + + space = event->xclient.data.l[0]; + time = event->xclient.data.l[1]; + + meta_verbose ("Request to change current workspace to %d with " + "specified timestamp of %u\n", + space, time); + + workspace = + meta_screen_get_workspace_by_index (screen, + space); + + /* Handle clients using the older version of the spec... */ + if (time == 0 && workspace) + { + meta_warning ("Received a NET_CURRENT_DESKTOP message " + "from a broken (outdated) client who sent " + "a 0 timestamp\n"); + time = meta_display_get_current_time_roundtrip (display); + } + + if (workspace) + meta_workspace_activate (workspace, time); + else + meta_verbose ("Don't know about workspace %d\n", space); + } + else if (event->xclient.message_type == + display->atom__NET_NUMBER_OF_DESKTOPS) + { + int num_spaces; + + num_spaces = event->xclient.data.l[0]; + + meta_verbose ("Request to set number of workspaces to %d\n", + num_spaces); + + meta_prefs_set_num_workspaces (num_spaces); + } + else if (event->xclient.message_type == + display->atom__NET_SHOWING_DESKTOP) + { + gboolean showing_desktop; + guint32 timestamp; + + showing_desktop = event->xclient.data.l[0] != 0; + /* FIXME: Braindead protocol doesn't have a timestamp */ + timestamp = meta_display_get_current_time_roundtrip (display); + meta_verbose ("Request to %s desktop\n", + showing_desktop ? "show" : "hide"); + + if (showing_desktop) + meta_screen_show_desktop (screen, timestamp); + else + { + meta_screen_unshow_desktop (screen); + meta_workspace_focus_default_window (screen->active_workspace, NULL, timestamp); + } + } + else if (event->xclient.message_type == + display->atom_WM_PROTOCOLS) + { + meta_verbose ("Received WM_PROTOCOLS message\n"); + + if ((Atom)event->xclient.data.l[0] == display->atom__NET_WM_PING) + { + guint32 timestamp = event->xclient.data.l[1]; + + meta_display_pong_for_serial (display, timestamp); + + /* We don't want ping reply events going into + * the GTK+ event loop because gtk+ will treat + * them as ping requests and send more replies. + */ + bypass_gtk = TRUE; + } + } + } + + if (event->xclient.message_type == + display->atom__NET_REQUEST_FRAME_EXTENTS) + { + meta_verbose ("Received _NET_REQUEST_FRAME_EXTENTS message\n"); + process_request_frame_extents (display, event); + } + } + break; + case MappingNotify: + { + gboolean ignore_current; + + ignore_current = FALSE; + + /* Check whether the next event is an identical MappingNotify + * event. If it is, ignore the current event, we'll update + * when we get the next one. + */ + if (XPending (display->xdisplay)) + { + XEvent next_event; + + XPeekEvent (display->xdisplay, &next_event); + + if (next_event.type == MappingNotify && + next_event.xmapping.request == event->xmapping.request) + ignore_current = TRUE; + } + + if (!ignore_current) + { + /* Let XLib know that there is a new keyboard mapping. + */ + XRefreshKeyboardMapping (&event->xmapping); + meta_display_process_mapping_event (display, event); + } + } + break; + default: +#ifdef HAVE_XKB + if (event->type == display->xkb_base_event_type) + { + XkbAnyEvent *xkb_ev = (XkbAnyEvent *) event; + + switch (xkb_ev->xkb_type) + { + case XkbBellNotify: + if (XSERVER_TIME_IS_BEFORE(display->last_bell_time, + xkb_ev->time - 100)) + { + display->last_bell_time = xkb_ev->time; + meta_bell_notify (display, xkb_ev); + } + break; + case XkbNewKeyboardNotify: + case XkbMapNotify: + if (xkb_ev->device == META_VIRTUAL_CORE_KEYBOARD_ID) + meta_display_process_mapping_event (display, event); + break; + } + } +#endif + break; + } + + out: + return bypass_gtk; +} + +static gboolean +grab_op_should_block_mouse_events (MetaGrabOp op) +{ + switch (op) + { + case META_GRAB_OP_WAYLAND_CLIENT: + case META_GRAB_OP_COMPOSITOR: + return TRUE; + + default: + return FALSE; + } +} + +static gboolean +window_has_xwindow (MetaWindow *window, + Window xwindow) +{ + if (window->xwindow == xwindow) + return TRUE; + + if (window->frame && window->frame->xwindow == xwindow) + return TRUE; + + return FALSE; +} + +/** + * meta_display_handle_xevent: + * @display: The MetaDisplay that events are coming from + * @event: The event that just happened + * + * This is the most important function in the whole program. It is the heart, + * it is the nexus, it is the Grand Central Station of Mutter's world. + * When we create a #MetaDisplay, we ask GDK to pass *all* events for *all* + * windows to this function. So every time anything happens that we might + * want to know about, this function gets called. You see why it gets a bit + * busy around here. Most of this function is a ginormous switch statement + * dealing with all the kinds of events that might turn up. + */ +static gboolean +meta_display_handle_xevent (MetaDisplay *display, + XEvent *event) +{ + Window modified; + gboolean bypass_compositor = FALSE, bypass_gtk = FALSE; + XIEvent *input_event; + MetaMonitorManager *monitor; + MetaScreen *screen; + +#if 0 + meta_spew_event (display, event); +#endif + +#ifdef HAVE_STARTUP_NOTIFICATION + sn_display_process_event (display->sn_display, event); +#endif + + /* Intercept XRandR events early and don't attempt any + processing for them. We still let them through to Gdk though, + so it can update its own internal state. + */ + monitor = meta_monitor_manager_get (); + if (meta_monitor_manager_handle_xevent (monitor, event)) + { + bypass_compositor = TRUE; + goto out; + } + + display->current_time = event_get_time (display, event); + display->monitor_cache_invalidated = TRUE; + + if (display->focused_by_us && + event->xany.serial > display->focus_serial && + display->focus_window && + !window_has_xwindow (display->focus_window, display->server_focus_window)) + { + meta_topic (META_DEBUG_FOCUS, "Earlier attempt to focus %s failed\n", + display->focus_window->desc); + meta_display_update_focus_window (display, + meta_display_lookup_x_window (display, display->server_focus_window), + display->server_focus_window, + display->server_focus_serial, + FALSE); + } + + screen = meta_display_screen_for_root (display, event->xany.window); + if (screen) + { + if (meta_screen_handle_xevent (screen, event)) + { + bypass_gtk = bypass_compositor = TRUE; + goto out; + } + } + + modified = event_get_modified_window (display, event); + + input_event = get_input_event (display, event); + + if (event->type == UnmapNotify) + { + if (meta_ui_window_should_not_cause_focus (display->xdisplay, + modified)) + { + meta_display_add_ignored_crossing_serial (display, event->xany.serial); + meta_topic (META_DEBUG_FOCUS, + "Adding EnterNotify serial %lu to ignored focus serials\n", + event->xany.serial); + } + } + else if (input_event && + input_event->evtype == XI_Leave && + ((XILeaveEvent *)input_event)->mode == XINotifyUngrab && + modified == display->ungrab_should_not_cause_focus_window) + { + meta_display_add_ignored_crossing_serial (display, event->xany.serial); + meta_topic (META_DEBUG_FOCUS, + "Adding LeaveNotify serial %lu to ignored focus serials\n", + event->xany.serial); + } + +#ifdef HAVE_XI23 + if (meta_display_process_barrier_event (display, input_event)) + { + bypass_gtk = bypass_compositor = TRUE; + goto out; + } +#endif /* HAVE_XI23 */ + + /* libXi does not properly copy the serial to XI2 events, so pull it + * from the parent XAnyEvent and pass it to handle_input_xevent. + * See: https://bugs.freedesktop.org/show_bug.cgi?id=64687 + */ + if (handle_input_xevent (display, input_event, event->xany.serial)) + { + bypass_gtk = bypass_compositor = TRUE; + goto out; + } + + if (handle_other_xevent (display, event)) + { + bypass_gtk = TRUE; + goto out; + } + + out: + if (!bypass_compositor) + { + MetaWindow *window = modified != None ? meta_display_lookup_x_window (display, modified) : NULL; + + if (meta_compositor_process_event (display->compositor, event, window)) + bypass_gtk = TRUE; + } + + display->current_time = CurrentTime; + return bypass_gtk; +} + +static gboolean +meta_display_handle_event (MetaDisplay *display, + const ClutterEvent *event) +{ + MetaWindow *window; + gboolean bypass_clutter = FALSE, bypass_wayland = FALSE; + MetaWaylandCompositor *compositor = NULL; + + if (meta_is_wayland_compositor ()) + { + compositor = meta_wayland_compositor_get_default (); + meta_wayland_compositor_update (compositor, event); + } + + window = get_window_for_event (display, event); + + display->current_time = event->any.time; + + if (window && !window->override_redirect && + (event->type == CLUTTER_KEY_PRESS || event->type == CLUTTER_BUTTON_PRESS)) + { + if (CurrentTime == display->current_time) + { + /* We can't use missing (i.e. invalid) timestamps to set user time, + * nor do we want to use them to sanity check other timestamps. + * See bug 313490 for more details. + */ + meta_warning ("Event has no timestamp! You may be using a broken " + "program such as xse. Please ask the authors of that " + "program to fix it.\n"); + } + else + { + meta_window_set_user_time (window, display->current_time); + meta_display_sanity_check_timestamps (display, display->current_time); + } + } + + switch (event->type) + { + case CLUTTER_BUTTON_PRESS: + if (grab_op_should_block_mouse_events (display->grab_op)) + break; + + display->overlay_key_only_pressed = FALSE; + + if ((window && + meta_grab_op_is_mouse (display->grab_op) && + (event->button.modifier_state & display->window_grab_modifiers) && + display->grab_button != (int) event->button.button && + display->grab_window == window) || + meta_grab_op_is_keyboard (display->grab_op)) + { + meta_topic (META_DEBUG_WINDOW_OPS, + "Ending grab op %u on window %s due to button press\n", + display->grab_op, + (display->grab_window ? + display->grab_window->desc : + "none")); + meta_display_end_grab_op (display, event->any.time); + bypass_clutter = TRUE; + bypass_wayland = TRUE; + } + else if (window && display->grab_op == META_GRAB_OP_NONE) + { + ClutterModifierType grab_mask; + gboolean unmodified; + gboolean fully_modified; + + grab_mask = display->window_grab_modifiers; + if (g_getenv ("MUTTER_DEBUG_BUTTON_GRABS")) + grab_mask |= CLUTTER_CONTROL_MASK; + + /* We have three passive button grabs: + * - on any button, without modifiers => focuses and maybe raises the window + * - on resize button, with modifiers => start an interactive resizing + * (normally middle) + * - on move button, with modifiers => start an interactive move + * (normally left) + * - on menu button, with modifiers => show the window menu + * (normally right) + * + * We may get here because we actually have a button + * grab on the window, or because we're a wayland + * compositor and thus we see all the events, so we + * need to check if the event is interesting. + * We want an event that is not modified, for a window + * that has (or would have, the wayland case) the + * button grab active. + * + * We may have other events on the window, for example + * a click on a frame button, but that's not for us to + * care about. Just let the event through. + */ + unmodified = (event->button.modifier_state & grab_mask) == 0; + fully_modified = grab_mask && (event->button.modifier_state & grab_mask) == grab_mask; + + if (unmodified && window && window->have_focus_click_grab) + { + if (meta_prefs_get_raise_on_click ()) + meta_window_raise (window); + else + meta_topic (META_DEBUG_FOCUS, + "Not raising window on click due to don't-raise-on-click option\n"); + + /* Don't focus panels--they must explicitly request focus. + * See bug 160470 + */ + if (window->type != META_WINDOW_DOCK) + { + meta_topic (META_DEBUG_FOCUS, + "Focusing %s due to unmodified button %u press (display.c)\n", + window->desc, event->button.button); + meta_window_focus (window, event->any.time); + } + else + /* However, do allow terminals to lose focus due to new + * window mappings after the user clicks on a panel. + */ + display->allow_terminal_deactivation = TRUE; + + meta_verbose ("Allowing events time %u\n", + (unsigned int)event->button.time); + + XIAllowEvents (display->xdisplay, clutter_input_device_get_device_id (event->button.device), + XIReplayDevice, event->button.time); + bypass_clutter = TRUE; + } + else if (fully_modified && (int) event->button.button == meta_prefs_get_mouse_button_resize ()) + { + if (window->has_resize_func) + { + gboolean north, south; + gboolean west, east; + MetaRectangle frame_rect; + MetaGrabOp op; + + meta_window_get_frame_rect (window, &frame_rect); + + west = event->button.x < (frame_rect.x + 1 * frame_rect.width / 3); + east = event->button.x > (frame_rect.x + 2 * frame_rect.width / 3); + north = event->button.y < (frame_rect.y + 1 * frame_rect.height / 3); + south = event->button.y > (frame_rect.y + 2 * frame_rect.height / 3); + + if (north && west) + op = META_GRAB_OP_RESIZING_NW; + else if (north && east) + op = META_GRAB_OP_RESIZING_NE; + else if (south && west) + op = META_GRAB_OP_RESIZING_SW; + else if (south && east) + op = META_GRAB_OP_RESIZING_SE; + else if (north) + op = META_GRAB_OP_RESIZING_N; + else if (west) + op = META_GRAB_OP_RESIZING_W; + else if (east) + op = META_GRAB_OP_RESIZING_E; + else if (south) + op = META_GRAB_OP_RESIZING_S; + else /* Middle region is no-op to avoid user triggering wrong action */ + op = META_GRAB_OP_NONE; + + if (op != META_GRAB_OP_NONE) + meta_display_begin_grab_op (display, + window->screen, + window, + op, + TRUE, + FALSE, + event->button.button, + 0, + event->any.time, + event->button.x, + event->button.y); + } + bypass_clutter = TRUE; + bypass_wayland = TRUE; + } + else if (fully_modified && (int) event->button.button == meta_prefs_get_mouse_button_menu ()) + { + if (meta_prefs_get_raise_on_click ()) + meta_window_raise (window); + meta_window_show_menu (window, + event->button.x, + event->button.y, + event->button.button, + event->any.time); + bypass_clutter = TRUE; + bypass_wayland = TRUE; + } + else if (fully_modified && (int) event->button.button == 1) + { + if (window->has_move_func) + { + meta_display_begin_grab_op (display, + window->screen, + window, + META_GRAB_OP_MOVING, + TRUE, + FALSE, + event->button.button, + 0, + event->any.time, + event->button.x, + event->button.y); + } + bypass_clutter = TRUE; + bypass_wayland = TRUE; + } + } + break; + case CLUTTER_BUTTON_RELEASE: + if (grab_op_should_block_mouse_events (display->grab_op)) + break; + + display->overlay_key_only_pressed = FALSE; + + if (display->grab_window == window && + meta_grab_op_is_mouse (display->grab_op)) + { + meta_window_handle_mouse_grab_op_event (window, event); + bypass_clutter = TRUE; + bypass_wayland = TRUE; + } + break; + case CLUTTER_MOTION: + if (grab_op_should_block_mouse_events (display->grab_op)) + break; + + if (display->grab_window == window && + meta_grab_op_is_mouse (display->grab_op)) + { + meta_window_handle_mouse_grab_op_event (window, event); + bypass_clutter = TRUE; + bypass_wayland = TRUE; + } + break; + + case CLUTTER_KEY_PRESS: + case CLUTTER_KEY_RELEASE: + /* For key events, it's important to enforce single-handling, or + * we can get into a confused state. So if a keybinding is + * handled (because it's one of our hot-keys, or because we are + * in a keyboard-grabbed mode like moving a window, we don't + * want to pass the key event to the compositor or Wayland at all. + */ + if (meta_display_process_key_event (display, window, (ClutterKeyEvent *) event)) + { + bypass_clutter = TRUE; + bypass_wayland = TRUE; + } + + default: + break; + } + + /* If the compositor has a grab, don't pass that through to Wayland */ + if (display->grab_op == META_GRAB_OP_COMPOSITOR) + bypass_wayland = TRUE; + + /* If a Wayland client has a grab, don't pass that through to Clutter */ + if (display->grab_op == META_GRAB_OP_WAYLAND_CLIENT) + bypass_clutter = TRUE; + + if (compositor && !bypass_wayland) + { + if (meta_wayland_compositor_handle_event (compositor, event)) + bypass_clutter = TRUE; + } + + return bypass_clutter; +} + +static gboolean +xevent_callback (XEvent *event, + gpointer data) +{ + MetaDisplay *display = data; + + return meta_display_handle_xevent (display, event); +} + +static gboolean +event_callback (const ClutterEvent *event, + gpointer data) +{ + MetaDisplay *display = data; + + return meta_display_handle_event (display, event); +} + +void +meta_display_init_events (MetaDisplay *display) +{ + meta_ui_add_event_func (display->xdisplay, + xevent_callback, + display); + display->clutter_event_filter = clutter_event_add_filter (NULL, + event_callback, + NULL, + display); +} + +void +meta_display_free_events (MetaDisplay *display) +{ + meta_ui_remove_event_func (display->xdisplay, + xevent_callback, + display); + clutter_event_remove_filter (display->clutter_event_filter); + display->clutter_event_filter = 0; +} diff --git a/src/core/events.h b/src/core/events.h new file mode 100644 index 000000000..66a34caa2 --- /dev/null +++ b/src/core/events.h @@ -0,0 +1,32 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2001 Havoc Pennington + * Copyright (C) 2002, 2003, 2004 Red Hat, Inc. + * Copyright (C) 2003, 2004 Rob Adams + * Copyright (C) 2004-2006 Elijah Newren + * + * 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 + +#ifndef META_EVENTS_H +#define META_EVENTS_H + +void meta_display_init_events (MetaDisplay *display); +void meta_display_free_events (MetaDisplay *display); + +#endif + From ab2224686aafa1717862ed19ab114c8dd0c9c349 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 20 Mar 2014 15:54:16 -0400 Subject: [PATCH 729/889] events: Clean up trailing whitespace --- src/core/events.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/core/events.c b/src/core/events.c index b37c77a99..43015ad2d 100644 --- a/src/core/events.c +++ b/src/core/events.c @@ -1056,18 +1056,18 @@ static MetaScreen* find_screen_for_selection (MetaDisplay *display, Window owner, Atom selection) -{ - GSList *tmp; - +{ + GSList *tmp; + tmp = display->screens; while (tmp != NULL) { MetaScreen *screen = tmp->data; - + if (screen->wm_sn_selection_window == owner && screen->wm_sn_atom == selection) return screen; - + tmp = tmp->next; } @@ -1109,7 +1109,7 @@ convert_property (MetaDisplay *display, meta_error_trap_pop_with_return (display); return FALSE; } - + if (meta_error_trap_pop_with_return (display) != Success) return FALSE; @@ -1138,20 +1138,20 @@ process_selection_request (MetaDisplay *display, if (screen == NULL) { char *str; - + meta_error_trap_push (display); str = XGetAtomName (display->xdisplay, event->xselectionrequest.selection); meta_error_trap_pop (display); - + meta_verbose ("Selection request with selection %s window 0x%lx not a WM_Sn selection we recognize\n", str ? str : "(bad atom)", event->xselectionrequest.owner); - + meta_XFree (str); return; } - + reply.type = SelectionNotify; reply.display = display->xdisplay; reply.requestor = event->xselectionrequest.requestor; @@ -1179,9 +1179,9 @@ process_selection_request (MetaDisplay *display, meta_error_trap_pop_with_return (display); return; } - + if (meta_error_trap_pop_with_return (display) == Success) - { + { /* FIXME: to be 100% correct, should deal with rest > 0, * but since we have 4 possible targets, we will hardly ever * meet multiple requests with a length > 8 @@ -1212,7 +1212,7 @@ process_selection_request (MetaDisplay *display, { if (event->xselectionrequest.property == None) event->xselectionrequest.property = event->xselectionrequest.target; - + if (convert_property (display, screen, event->xselectionrequest.requestor, event->xselectionrequest.target, @@ -1237,25 +1237,25 @@ process_selection_clear (MetaDisplay *display, screen = find_screen_for_selection (display, event->xselectionclear.window, event->xselectionclear.selection); - + if (screen != NULL) { meta_verbose ("Got selection clear for screen %d on display %s\n", screen->number, display->name); - - meta_display_unmanage_screen (display, + + meta_display_unmanage_screen (display, screen, event->xselectionclear.time); /* display and screen may both be invalid memory... */ - + return; } { char *str; - + meta_error_trap_push (display); str = XGetAtomName (display->xdisplay, event->xselectionclear.selection); @@ -1316,11 +1316,11 @@ handle_other_xevent (MetaDisplay *display, #endif /* HAVE_XSYNC */ #ifdef HAVE_SHAPE - if (META_DISPLAY_HAS_SHAPE (display) && + if (META_DISPLAY_HAS_SHAPE (display) && event->type == (display->shape_event_base + ShapeNotify)) { bypass_gtk = TRUE; /* GTK doesn't want to see this really */ - + if (window && !frame_was_receiver) { XShapeEvent *sev = (XShapeEvent*) event; From 46b4d6c0f0982498270f36ff6a0b75112671286b Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 20 Mar 2014 16:06:24 -0400 Subject: [PATCH 730/889] Move request_take_focus to window-x11 This will let us kill off send_icccm_message --- src/core/display-private.h | 2 ++ src/core/display.c | 24 ++++-------------------- src/meta/display.h | 4 ---- src/x11/window-x11.c | 16 +++++++++++++--- 4 files changed, 19 insertions(+), 27 deletions(-) diff --git a/src/core/display-private.h b/src/core/display-private.h index 3194afce3..885940120 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -498,5 +498,7 @@ void meta_display_update_focus_window (MetaDisplay *display, void meta_display_sanity_check_timestamps (MetaDisplay *display, guint32 timestamp); +gboolean meta_display_timestamp_too_old (MetaDisplay *display, + guint32 *timestamp); #endif diff --git a/src/core/display.c b/src/core/display.c index 2910c69a1..1eb39ecc8 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -1700,9 +1700,9 @@ meta_display_update_focus_window (MetaDisplay *display, meta_display_update_active_window_hint (display); } -static gboolean -timestamp_too_old (MetaDisplay *display, - guint32 *timestamp) +gboolean +meta_display_timestamp_too_old (MetaDisplay *display, + guint32 *timestamp) { /* FIXME: If Soeren's suggestion in bug 151984 is implemented, it will allow * us to sanity check the timestamp here and ensure it doesn't correspond to @@ -1738,7 +1738,7 @@ request_xserver_input_focus_change (MetaDisplay *display, { gulong serial; - if (timestamp_too_old (display, ×tamp)) + if (meta_display_timestamp_too_old (display, ×tamp)) return; meta_error_trap_push (display); @@ -3404,22 +3404,6 @@ meta_display_set_input_focus_window (MetaDisplay *display, timestamp); } -void -meta_display_request_take_focus (MetaDisplay *display, - MetaWindow *window, - guint32 timestamp) -{ - if (timestamp_too_old (display, ×tamp)) - return; - - meta_topic (META_DEBUG_FOCUS, "WM_TAKE_FOCUS(%s, %u)\n", - window->desc, timestamp); - - meta_window_send_icccm_message (window, - display->atom_WM_TAKE_FOCUS, - timestamp); -} - void meta_display_set_input_focus_xwindow (MetaDisplay *display, MetaScreen *screen, diff --git a/src/meta/display.h b/src/meta/display.h index 60e9ab14d..c882ac4aa 100644 --- a/src/meta/display.h +++ b/src/meta/display.h @@ -163,10 +163,6 @@ void meta_display_set_input_focus_window (MetaDisplay *display, gboolean focus_frame, guint32 timestamp); -void meta_display_request_take_focus (MetaDisplay *display, - MetaWindow *window, - guint32 timestamp); - /* meta_display_focus_the_no_focus_window is called when the * designated no_focus_window should be focused, but is otherwise the * same as meta_display_set_input_focus_window diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c index aae590609..58c3d1979 100644 --- a/src/x11/window-x11.c +++ b/src/x11/window-x11.c @@ -386,6 +386,18 @@ meta_window_x11_kill (MetaWindow *window) meta_error_trap_pop (window->display); } +static void +request_take_focus (MetaWindow *window, + guint32 timestamp) +{ + MetaDisplay *display = window->display; + + meta_topic (META_DEBUG_FOCUS, "WM_TAKE_FOCUS(%s, %u)\n", + window->desc, timestamp); + + meta_window_send_icccm_message (window, display->atom_WM_TAKE_FOCUS, timestamp); +} + static void meta_window_x11_focus (MetaWindow *window, guint32 timestamp) @@ -448,9 +460,7 @@ meta_window_x11_focus (MetaWindow *window, timestamp); } - meta_display_request_take_focus (window->display, - window, - timestamp); + request_take_focus (window, timestamp); } } } From 852589897e45c2b42f1e12438bd750b414567e30 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 20 Mar 2014 16:07:23 -0400 Subject: [PATCH 731/889] Move send_icccm_message to window-x11 --- src/core/window-private.h | 6 ----- src/core/window.c | 36 ------------------------------ src/x11/window-x11.c | 46 +++++++++++++++++++++++++++++++++------ 3 files changed, 39 insertions(+), 49 deletions(-) diff --git a/src/core/window-private.h b/src/core/window-private.h index 56d902d6a..97b052cbb 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -612,12 +612,6 @@ void meta_window_get_geometry (MetaWindow *window, void meta_window_update_unfocused_button_grabs (MetaWindow *window); -/* Sends a client message */ -void meta_window_send_icccm_message (MetaWindow *window, - Atom atom, - guint32 timestamp); - - void meta_window_move_resize_request(MetaWindow *window, guint value_mask, int gravity, diff --git a/src/core/window.c b/src/core/window.c index 12a3f2aec..5d831ca2a 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -5362,42 +5362,6 @@ meta_window_lower (MetaWindow *window) meta_stack_lower (window->screen->stack, window); } -void -meta_window_send_icccm_message (MetaWindow *window, - Atom atom, - guint32 timestamp) -{ - /* This comment and code are from twm, copyright - * Open Group, Evans & Sutherland, etc. - */ - - /* - * ICCCM Client Messages - Section 4.2.8 of the ICCCM dictates that all - * client messages will have the following form: - * - * event type ClientMessage - * message type _XA_WM_PROTOCOLS - * window tmp->w - * format 32 - * data[0] message atom - * data[1] time stamp - */ - - XClientMessageEvent ev; - - ev.type = ClientMessage; - ev.window = window->xwindow; - ev.message_type = window->display->atom_WM_PROTOCOLS; - ev.format = 32; - ev.data.l[0] = atom; - ev.data.l[1] = timestamp; - - meta_error_trap_push (window->display); - XSendEvent (window->display->xdisplay, - window->xwindow, False, 0, (XEvent*) &ev); - meta_error_trap_pop (window->display); -} - void meta_window_move_resize_request (MetaWindow *window, guint value_mask, diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c index 58c3d1979..54b25fc00 100644 --- a/src/x11/window-x11.c +++ b/src/x11/window-x11.c @@ -59,6 +59,42 @@ meta_window_x11_init (MetaWindowX11 *window_x11) window_x11->priv = meta_window_x11_get_instance_private (window_x11); } +static void +send_icccm_message (MetaWindow *window, + Atom atom, + guint32 timestamp) +{ + /* This comment and code are from twm, copyright + * Open Group, Evans & Sutherland, etc. + */ + + /* + * ICCCM Client Messages - Section 4.2.8 of the ICCCM dictates that all + * client messages will have the following form: + * + * event type ClientMessage + * message type _XA_WM_PROTOCOLS + * window tmp->w + * format 32 + * data[0] message atom + * data[1] time stamp + */ + + XClientMessageEvent ev; + + ev.type = ClientMessage; + ev.window = window->xwindow; + ev.message_type = window->display->atom_WM_PROTOCOLS; + ev.format = 32; + ev.data.l[0] = atom; + ev.data.l[1] = timestamp; + + meta_error_trap_push (window->display); + XSendEvent (window->display->xdisplay, + window->xwindow, False, 0, (XEvent*) &ev); + meta_error_trap_pop (window->display); +} + static Window read_client_leader (MetaDisplay *display, Window xwindow) @@ -328,9 +364,7 @@ meta_window_x11_ping (MetaWindow *window, { MetaDisplay *display = window->display; - meta_window_send_icccm_message (window, - display->atom__NET_WM_PING, - serial); + send_icccm_message (window, display->atom__NET_WM_PING, serial); } static void @@ -343,9 +377,7 @@ meta_window_x11_delete (MetaWindow *window, meta_topic (META_DEBUG_WINDOW_OPS, "Deleting %s with delete_window request\n", window->desc); - meta_window_send_icccm_message (window, - window->display->atom_WM_DELETE_WINDOW, - timestamp); + send_icccm_message (window, window->display->atom_WM_DELETE_WINDOW, timestamp); } else { @@ -395,7 +427,7 @@ request_take_focus (MetaWindow *window, meta_topic (META_DEBUG_FOCUS, "WM_TAKE_FOCUS(%s, %u)\n", window->desc, timestamp); - meta_window_send_icccm_message (window, display->atom_WM_TAKE_FOCUS, timestamp); + send_icccm_message (window, display->atom_WM_TAKE_FOCUS, timestamp); } static void From 054c307353de48af204cfbf6a8a1c4a98924a45a Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 20 Mar 2014 16:22:56 -0400 Subject: [PATCH 732/889] window: Remove support for colormaps While the ICCCM mandates the use of this, it's not necessary under a composited environment from my understanding, and it's a flat out no-op under XWayland. Looking at the other rootless servers like Xwin/Xquartz, it seems that they contain code for colormap emulation, but they're actually never used -- a bug prevents the code from ever being called. Given that it's been this way since 2003, I'm going to hazard a guess that not many apps using colormaps. Kill them off. --- src/core/window.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/core/window.c b/src/core/window.c index 5d831ca2a..9c30162ce 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -5676,11 +5676,6 @@ meta_window_set_focused_internal (MetaWindow *window, if (window->frame) meta_frame_queue_draw (window->frame); - meta_error_trap_push (window->display); - XInstallColormap (window->display->xdisplay, - window->colormap); - meta_error_trap_pop (window->display); - /* move into FOCUSED_WINDOW layer */ meta_window_update_layer (window); @@ -5719,11 +5714,6 @@ meta_window_set_focused_internal (MetaWindow *window, if (!window->attached_focus_window) meta_window_appears_focused_changed (window); - meta_error_trap_push (window->display); - XUninstallColormap (window->display->xdisplay, - window->colormap); - meta_error_trap_pop (window->display); - /* move out of FOCUSED_WINDOW layer */ meta_window_update_layer (window); From 337db2a660b4cf8f2d7325f95a8ff2e6ee7dc7b5 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 20 Mar 2014 16:26:14 -0400 Subject: [PATCH 733/889] window: Kill off the rest of colormaps I removed the XInstallColormap / XUninstallColormap but forgot to remove the fields in MetaWindow and the code to set them. --- src/core/events.c | 2 -- src/core/frame.c | 3 +-- src/core/window-private.h | 1 - src/core/window.c | 1 - src/x11/window-x11.c | 2 +- 5 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/core/events.c b/src/core/events.c index 43015ad2d..342503664 100644 --- a/src/core/events.c +++ b/src/core/events.c @@ -1620,8 +1620,6 @@ handle_other_xevent (MetaDisplay *display, case SelectionNotify: break; case ColormapNotify: - if (window && !frame_was_receiver) - window->colormap = event->xcolormap.colormap; break; case ClientMessage: if (window) diff --git a/src/core/frame.c b/src/core/frame.c index e54e86210..350493c59 100644 --- a/src/core/frame.c +++ b/src/core/frame.c @@ -35,8 +35,7 @@ ButtonPressMask | ButtonReleaseMask | \ PointerMotionMask | PointerMotionHintMask | \ EnterWindowMask | LeaveWindowMask | \ - FocusChangeMask | \ - ColormapChangeMask) + FocusChangeMask) void meta_window_ensure_frame (MetaWindow *window) diff --git a/src/core/window-private.h b/src/core/window-private.h index 97b052cbb..ebda724b9 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -103,7 +103,6 @@ struct _MetaWindow MetaFrame *frame; int depth; Visual *xvisual; - Colormap colormap; char *desc; /* used in debug spew */ char *title; diff --git a/src/core/window.c b/src/core/window.c index 9c30162ce..1f9796443 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -833,7 +833,6 @@ _meta_window_shared_new (MetaDisplay *display, window->depth = attrs->depth; window->xvisual = attrs->visual; - window->colormap = attrs->colormap; window->title = NULL; window->icon = NULL; diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c index 54b25fc00..339f4ac18 100644 --- a/src/x11/window-x11.c +++ b/src/x11/window-x11.c @@ -2322,7 +2322,7 @@ meta_window_x11_new (MetaDisplay *display, meta_error_trap_push_with_return (display); - event_mask = PropertyChangeMask | ColormapChangeMask; + event_mask = PropertyChangeMask; if (attrs.override_redirect) event_mask |= StructureNotifyMask; From 0de83ebfb590d62515d118af1ab4be0f9443d4d5 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 20 Mar 2014 16:46:21 -0400 Subject: [PATCH 734/889] display: Remove get_leader_window It's unused. --- src/core/display.c | 16 ---------------- src/meta/display.h | 2 -- 2 files changed, 18 deletions(-) diff --git a/src/core/display.c b/src/core/display.c index 1eb39ecc8..4f6de93d1 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -3574,22 +3574,6 @@ meta_display_get_shape_event_base (MetaDisplay *display) } #endif -/** - * meta_display_get_leader_window: - * @display: a #MetaDisplay - * - * Returns the window manager's leader window (as defined by the - * _NET_SUPPORTING_WM_CHECK mechanism of EWMH). For use by plugins that wish - * to attach additional custom properties to this window. - * - * Return value: (transfer none): xid of the leader window. - **/ -Window -meta_display_get_leader_window (MetaDisplay *display) -{ - return display->leader_window; -} - /** * meta_display_clear_mouse_mode: * @display: a #MetaDisplay diff --git a/src/meta/display.h b/src/meta/display.h index c882ac4aa..c13f151fd 100644 --- a/src/meta/display.h +++ b/src/meta/display.h @@ -174,8 +174,6 @@ void meta_display_focus_the_no_focus_window (MetaDisplay *display, GSList *meta_display_sort_windows_by_stacking (MetaDisplay *display, GSList *windows); -Window meta_display_get_leader_window (MetaDisplay *display); - void meta_display_add_ignored_crossing_serial (MetaDisplay *display, unsigned long serial); From 9696e785daeb4511a70a225fc87a7dd416e7078f Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 20 Mar 2014 16:48:15 -0400 Subject: [PATCH 735/889] screen: Remove flash_window It's unused as well --- src/core/screen-private.h | 2 -- src/core/screen.c | 1 - src/x11/window-x11.c | 3 --- 3 files changed, 6 deletions(-) diff --git a/src/core/screen-private.h b/src/core/screen-private.h index 427bda28f..22b62cf6e 100644 --- a/src/core/screen-private.h +++ b/src/core/screen-private.h @@ -82,8 +82,6 @@ struct _MetaScreen MetaCursorTracker *cursor_tracker; MetaCursor current_cursor; - Window flash_window; - Window wm_sn_selection_window; Atom wm_sn_atom; guint32 wm_sn_timestamp; diff --git a/src/core/screen.c b/src/core/screen.c index bac8dcaf0..5538aee05 100644 --- a/src/core/screen.c +++ b/src/core/screen.c @@ -690,7 +690,6 @@ meta_screen_new (MetaDisplay *display, screen->current_cursor = -1; /* invalid/unset */ screen->default_xvisual = DefaultVisualOfScreen (screen->xscreen); screen->default_depth = DefaultDepthOfScreen (screen->xscreen); - screen->flash_window = None; screen->wm_sn_selection_window = new_wm_sn_owner; screen->wm_sn_atom = wm_sn_atom; diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c index 339f4ac18..b5e7d6ebb 100644 --- a/src/x11/window-x11.c +++ b/src/x11/window-x11.c @@ -2184,9 +2184,6 @@ is_our_xwindow (MetaDisplay *display, if (xwindow == screen->no_focus_window) return TRUE; - if (xwindow == screen->flash_window) - return TRUE; - if (xwindow == screen->wm_sn_selection_window) return TRUE; From 42491f7724b9acee737ffa840fc7aad31170ff5a Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 20 Mar 2014 18:00:55 -0400 Subject: [PATCH 736/889] window: Actually interpret the FRAME_SHAPE_CHANGED result When I refactored this out into a vfunc, I forgot to change the code that interprets the result flags to actually respect the new FRAME_SHAPE_CHANGED result flag. Since we weren't ever clearing the frame bounds, this meant that the "shadow clip" wasn't ever updated as a result. Since right now all Wayland surfaces are considered ARGB32, we always clip shadows under frames, and thus shadows had this weird "punch-out" from the first frame shape. --- src/core/window.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/core/window.c b/src/core/window.c index 1f9796443..eb2ed9dce 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -4213,8 +4213,6 @@ meta_window_move_resize_internal (MetaWindow *window, * we don't decorate wayland clients), and the client has acknowledged * the window size change. */ - gboolean frame_shape_changed = FALSE; - gboolean is_configure_request; gboolean do_gravity_adjust; gboolean is_user_action; @@ -4351,7 +4349,7 @@ meta_window_move_resize_internal (MetaWindow *window, * b) all constraints are obeyed by window->rect and frame->rect */ - if (frame_shape_changed && window->frame_bounds) + if ((result & META_MOVE_RESIZE_RESULT_FRAME_SHAPE_CHANGED) && window->frame_bounds) { cairo_region_destroy (window->frame_bounds); window->frame_bounds = NULL; From 1cfaf45389e200334f91f5dbcca39400392386c8 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 20 Mar 2014 17:59:22 -0400 Subject: [PATCH 737/889] surface-actor-wayland: Fix meta_surface_actor_wayland_is_argb32 This prevents us from clipping shadows under windows for all apps, and loads of other fun optimizations. --- src/compositor/meta-surface-actor-wayland.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/compositor/meta-surface-actor-wayland.c b/src/compositor/meta-surface-actor-wayland.c index 875dd1c6b..00b766626 100644 --- a/src/compositor/meta-surface-actor-wayland.c +++ b/src/compositor/meta-surface-actor-wayland.c @@ -83,8 +83,21 @@ meta_surface_actor_wayland_pre_paint (MetaSurfaceActor *actor) static gboolean meta_surface_actor_wayland_is_argb32 (MetaSurfaceActor *actor) { - /* XXX -- look at the SHM buffer format. */ - return TRUE; + MetaShapedTexture *stex = meta_surface_actor_get_texture (actor); + CoglTexture *texture = meta_shaped_texture_get_texture (stex); + + switch (cogl_texture_get_components (texture)) + { + case COGL_TEXTURE_COMPONENTS_A: + case COGL_TEXTURE_COMPONENTS_RGBA: + return TRUE; + case COGL_TEXTURE_COMPONENTS_RG: + case COGL_TEXTURE_COMPONENTS_RGB: + case COGL_TEXTURE_COMPONENTS_DEPTH: + return FALSE; + default: + g_assert_not_reached (); + } } static gboolean From a55622d924739937bcedf79212fe49b0fa09efa0 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Mon, 24 Mar 2014 14:17:56 -0400 Subject: [PATCH 738/889] wayland: drop -logfile argument It breaks testing wayland with setuid X server. --- src/wayland/meta-xwayland.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index ae8509e19..65288ff41 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -303,7 +303,6 @@ meta_xwayland_start (MetaXWaylandManager *manager, pid_t pid; char **env; char *fd_string; - char *log_path; char *args[10]; GError *error; @@ -364,15 +363,12 @@ meta_xwayland_start (MetaXWaylandManager *manager, g_free (fd_string); manager->display_name = g_strdup_printf (":%d", manager->display_index); - log_path = g_build_filename (g_get_user_cache_dir (), "xwayland.log", NULL); args[0] = XWAYLAND_PATH; args[1] = manager->display_name; args[2] = "-wayland"; args[3] = "-rootless"; args[4] = "-noreset"; - args[5] = "-logfile"; - args[6] = log_path; args[7] = "-nolisten"; args[8] = "all"; args[9] = NULL; @@ -382,9 +378,7 @@ meta_xwayland_start (MetaXWaylandManager *manager, args, env, G_SPAWN_LEAVE_DESCRIPTORS_OPEN | - G_SPAWN_DO_NOT_REAP_CHILD | - G_SPAWN_STDOUT_TO_DEV_NULL | - G_SPAWN_STDERR_TO_DEV_NULL, + G_SPAWN_DO_NOT_REAP_CHILD, uncloexec, GINT_TO_POINTER (sp[1]), &pid, @@ -404,7 +398,6 @@ meta_xwayland_start (MetaXWaylandManager *manager, } g_strfreev (env); - g_free (log_path); /* We need to run a mainloop until we know xwayland has a binding * for our xserver interface at which point we can assume it's From 7484d540cdef81d704b260e96e2d6b403b22cfd9 Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Tue, 25 Mar 2014 11:59:04 +0100 Subject: [PATCH 739/889] wayland: Use an array initializer for the X server arguments This fixes the unitialized array members introduced previously and should avoid such mistakes again going forward. https://bugzilla.gnome.org/show_bug.cgi?id=727011 --- src/wayland/meta-xwayland.c | 62 ++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index 65288ff41..20bf59684 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -303,8 +303,6 @@ meta_xwayland_start (MetaXWaylandManager *manager, pid_t pid; char **env; char *fd_string; - char *args[10]; - GError *error; wl_global_create (wl_display, &xserver_interface, META_XSERVER_VERSION, @@ -364,38 +362,40 @@ meta_xwayland_start (MetaXWaylandManager *manager, manager->display_name = g_strdup_printf (":%d", manager->display_index); - args[0] = XWAYLAND_PATH; - args[1] = manager->display_name; - args[2] = "-wayland"; - args[3] = "-rootless"; - args[4] = "-noreset"; - args[7] = "-nolisten"; - args[8] = "all"; - args[9] = NULL; + { + GError *error = NULL; + gchar *args[] = { XWAYLAND_PATH, + manager->display_name, + "-wayland", + "-rootless", + "-noreset", + "-nolisten", + "all", + NULL }; - error = NULL; - if (g_spawn_async (NULL, /* cwd */ - args, - env, - G_SPAWN_LEAVE_DESCRIPTORS_OPEN | - G_SPAWN_DO_NOT_REAP_CHILD, - uncloexec, - GINT_TO_POINTER (sp[1]), - &pid, - &error)) - { - g_message ("forked X server, pid %d\n", pid); + if (g_spawn_async (NULL, /* cwd */ + args, + env, + G_SPAWN_LEAVE_DESCRIPTORS_OPEN | + G_SPAWN_DO_NOT_REAP_CHILD, + uncloexec, + GINT_TO_POINTER (sp[1]), + &pid, + &error)) + { + g_message ("forked X server, pid %d\n", pid); - close (sp[1]); - manager->client = wl_client_create (wl_display, sp[0]); + close (sp[1]); + manager->client = wl_client_create (wl_display, sp[0]); - manager->pid = pid; - g_child_watch_add (pid, xserver_died, NULL); - } - else - { - g_error ("Failed to fork for xwayland server: %s", error->message); - } + manager->pid = pid; + g_child_watch_add (pid, xserver_died, NULL); + } + else + { + g_error ("Failed to fork for xwayland server: %s", error->message); + } + } g_strfreev (env); From 71be7e8493759cd75f556d83d866f9188d3c3bfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Tue, 25 Mar 2014 16:27:09 +0100 Subject: [PATCH 740/889] display: Fix compiler warning Don't leave a variable uninitialized in case we don't find a matching surface. --- src/core/display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/display.c b/src/core/display.c index 4f6de93d1..c63f2cee7 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -1629,7 +1629,7 @@ void meta_display_sync_wayland_input_focus (MetaDisplay *display) { MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); - MetaWindow *focus_window; + MetaWindow *focus_window = NULL; if (meta_grab_op_is_wayland (display->grab_op)) focus_window = NULL; From eba848e8aaf002e5e87c3924b51f205ad6cc809f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Tue, 25 Mar 2014 16:19:39 +0100 Subject: [PATCH 741/889] Bump version to 3.12.0 Update NEWS. --- NEWS | 8 ++++++++ configure.ac | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index cec317764..d7dee7268 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,11 @@ +3.12.0 +====== +* Fix grab issue with SSD xwayland windows [Rui; #726123] +* Misc. bug fixes [Jasper, Ray, Rui, Florian; #727011] + +Contributors: + Rui Matos, Florian Müllner, Jasper St. Pierre, Ray Strode + 3.11.92 ======= * Fix identification of CSD windows [Owen; #723029] diff --git a/configure.ac b/configure.ac index 250ed6753..6ca7add31 100644 --- a/configure.ac +++ b/configure.ac @@ -2,8 +2,8 @@ AC_PREREQ(2.50) AC_CONFIG_MACRO_DIR([m4]) m4_define([mutter_major_version], [3]) -m4_define([mutter_minor_version], [11]) -m4_define([mutter_micro_version], [92]) +m4_define([mutter_minor_version], [12]) +m4_define([mutter_micro_version], [0]) m4_define([mutter_version], [mutter_major_version.mutter_minor_version.mutter_micro_version]) From 456e3e24294f77822d34e981b556880cefc3ae8e Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 25 Mar 2014 11:35:53 -0400 Subject: [PATCH 742/889] xwayland: Punt stdout / stderr to /dev/null This should really go to the journal, but I'm tired of seeing Xorg log a bunch of garbage that I don't care about when debugging mutter. --- src/wayland/meta-xwayland.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index 20bf59684..20b86b443 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -377,7 +377,9 @@ meta_xwayland_start (MetaXWaylandManager *manager, args, env, G_SPAWN_LEAVE_DESCRIPTORS_OPEN | - G_SPAWN_DO_NOT_REAP_CHILD, + G_SPAWN_DO_NOT_REAP_CHILD | + G_SPAWN_STDOUT_TO_DEV_NULL | + G_SPAWN_STDERR_TO_DEV_NULL, uncloexec, GINT_TO_POINTER (sp[1]), &pid, From 44580ddb80e292d61f856ace0326ff6e3f99e3f3 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 25 Mar 2014 11:59:16 -0400 Subject: [PATCH 743/889] wayland-surface: Unref the buffer after removing the destroy listener --- src/wayland/meta-wayland-surface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 739c17133..39239ef71 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -83,8 +83,8 @@ surface_set_buffer (MetaWaylandSurface *surface, if (surface->buffer) { - meta_wayland_buffer_unref (surface->buffer); wl_list_remove (&surface->buffer_destroy_listener.link); + meta_wayland_buffer_unref (surface->buffer); } surface->buffer = buffer; From 272676b8967780c8ef922a6c74058e3907e808ca Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 25 Mar 2014 11:59:52 -0400 Subject: [PATCH 744/889] surface-actor-wayland: Make sure to clean up on dispose We need to remove our destroy handler if the surface is destroyed before the buffer is, which is the case when we have no destroy effect. --- src/compositor/meta-surface-actor-wayland.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/compositor/meta-surface-actor-wayland.c b/src/compositor/meta-surface-actor-wayland.c index 00b766626..bf9441bae 100644 --- a/src/compositor/meta-surface-actor-wayland.c +++ b/src/compositor/meta-surface-actor-wayland.c @@ -136,10 +136,21 @@ meta_surface_actor_wayland_get_window (MetaSurfaceActor *actor) return priv->surface->window; } +static void +meta_surface_actor_wayland_dispose (GObject *object) +{ + MetaSurfaceActorWayland *self = META_SURFACE_ACTOR_WAYLAND (object); + + meta_surface_actor_wayland_set_buffer (self, NULL); + + G_OBJECT_CLASS (meta_surface_actor_wayland_parent_class)->dispose (object); +} + static void meta_surface_actor_wayland_class_init (MetaSurfaceActorWaylandClass *klass) { MetaSurfaceActorClass *surface_actor_class = META_SURFACE_ACTOR_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); surface_actor_class->process_damage = meta_surface_actor_wayland_process_damage; surface_actor_class->pre_paint = meta_surface_actor_wayland_pre_paint; @@ -151,6 +162,8 @@ meta_surface_actor_wayland_class_init (MetaSurfaceActorWaylandClass *klass) surface_actor_class->is_unredirected = meta_surface_actor_wayland_is_unredirected; surface_actor_class->get_window = meta_surface_actor_wayland_get_window; + + object_class->dispose = meta_surface_actor_wayland_dispose; } static void From ef65848d1149866cf160452f7ae84719694dfb91 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 25 Mar 2014 12:05:21 -0400 Subject: [PATCH 745/889] window-wayland: Implement kill --- src/wayland/window-wayland.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/wayland/window-wayland.c b/src/wayland/window-wayland.c index 2eaaf017f..e52c1435e 100644 --- a/src/wayland/window-wayland.c +++ b/src/wayland/window-wayland.c @@ -92,7 +92,13 @@ meta_window_wayland_delete (MetaWindow *window, static void meta_window_wayland_kill (MetaWindow *window) { - /* TODO */ + MetaWaylandSurface *surface = window->surface; + struct wl_resource *resource = surface->resource; + + /* Send the client an unrecoverable error to kill the client. */ + wl_resource_post_error (resource, + WL_DISPLAY_ERROR_NO_MEMORY, + "User requested that we kill you. Sorry. Don't take it too personally."); } static void From d699b2409ae0c5fadd3ef3124aaea8ebe1480e78 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 25 Mar 2014 12:41:52 -0400 Subject: [PATCH 746/889] xwayland: Shut up conditionally --- src/wayland/meta-xwayland.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index 20b86b443..8c0fe3595 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -372,14 +372,22 @@ meta_xwayland_start (MetaXWaylandManager *manager, "-nolisten", "all", NULL }; + int flags = 0; + + flags |= G_SPAWN_LEAVE_DESCRIPTORS_OPEN; + flags |= G_SPAWN_DO_NOT_REAP_CHILD; + + /* xwayland, please. */ + if (getenv ("XWAYLAND_STFU")) + { + flags |= G_SPAWN_STDOUT_TO_DEV_NULL; + flags |= G_SPAWN_STDERR_TO_DEV_NULL; + } if (g_spawn_async (NULL, /* cwd */ args, env, - G_SPAWN_LEAVE_DESCRIPTORS_OPEN | - G_SPAWN_DO_NOT_REAP_CHILD | - G_SPAWN_STDOUT_TO_DEV_NULL | - G_SPAWN_STDERR_TO_DEV_NULL, + flags, uncloexec, GINT_TO_POINTER (sp[1]), &pid, From e30ed6892cc845aa9ba741680e2b274337a242ca Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 25 Mar 2014 17:00:43 -0400 Subject: [PATCH 747/889] surface-actor: Prevent a dumb crash is_argb32 can be called at any time, including times when we don't have a texture. In that case, just assume we're ARGB32. The value really shouldn't be important though. --- src/compositor/meta-surface-actor-wayland.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/compositor/meta-surface-actor-wayland.c b/src/compositor/meta-surface-actor-wayland.c index bf9441bae..3389b614f 100644 --- a/src/compositor/meta-surface-actor-wayland.c +++ b/src/compositor/meta-surface-actor-wayland.c @@ -86,6 +86,11 @@ meta_surface_actor_wayland_is_argb32 (MetaSurfaceActor *actor) MetaShapedTexture *stex = meta_surface_actor_get_texture (actor); CoglTexture *texture = meta_shaped_texture_get_texture (stex); + /* If we don't have a texture, like during initialization, assume + * that we're ARGB32. */ + if (!texture) + return TRUE; + switch (cogl_texture_get_components (texture)) { case COGL_TEXTURE_COMPONENTS_A: From cc0488f1e29da928e1c66e363b59582752d1ea32 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 25 Mar 2014 17:02:50 -0400 Subject: [PATCH 748/889] surface-actor: Implement is_argb32 generically for both X11 and Wayland cogl_texture_get_components can be used on both X11 and Wayland backends. Technically, the detection is different: we actually check the actual RENDER format in the old code, while Cogl simply assumes that any pixmap with a depth >= 32 is ARGB32. Since Cogl already seems to be working with its internal checks, it makes more sense to use Cogl's check rather than keeping our own. --- src/compositor/meta-surface-actor-wayland.c | 26 ------------------ src/compositor/meta-surface-actor-x11.c | 29 +-------------------- src/compositor/meta-surface-actor.c | 21 ++++++++++++++- src/compositor/meta-surface-actor.h | 1 - 4 files changed, 21 insertions(+), 56 deletions(-) diff --git a/src/compositor/meta-surface-actor-wayland.c b/src/compositor/meta-surface-actor-wayland.c index 3389b614f..e0c6ff7b7 100644 --- a/src/compositor/meta-surface-actor-wayland.c +++ b/src/compositor/meta-surface-actor-wayland.c @@ -80,31 +80,6 @@ meta_surface_actor_wayland_pre_paint (MetaSurfaceActor *actor) { } -static gboolean -meta_surface_actor_wayland_is_argb32 (MetaSurfaceActor *actor) -{ - MetaShapedTexture *stex = meta_surface_actor_get_texture (actor); - CoglTexture *texture = meta_shaped_texture_get_texture (stex); - - /* If we don't have a texture, like during initialization, assume - * that we're ARGB32. */ - if (!texture) - return TRUE; - - switch (cogl_texture_get_components (texture)) - { - case COGL_TEXTURE_COMPONENTS_A: - case COGL_TEXTURE_COMPONENTS_RGBA: - return TRUE; - case COGL_TEXTURE_COMPONENTS_RG: - case COGL_TEXTURE_COMPONENTS_RGB: - case COGL_TEXTURE_COMPONENTS_DEPTH: - return FALSE; - default: - g_assert_not_reached (); - } -} - static gboolean meta_surface_actor_wayland_is_visible (MetaSurfaceActor *actor) { @@ -159,7 +134,6 @@ meta_surface_actor_wayland_class_init (MetaSurfaceActorWaylandClass *klass) surface_actor_class->process_damage = meta_surface_actor_wayland_process_damage; surface_actor_class->pre_paint = meta_surface_actor_wayland_pre_paint; - surface_actor_class->is_argb32 = meta_surface_actor_wayland_is_argb32; surface_actor_class->is_visible = meta_surface_actor_wayland_is_visible; surface_actor_class->should_unredirect = meta_surface_actor_wayland_should_unredirect; diff --git a/src/compositor/meta-surface-actor-x11.c b/src/compositor/meta-surface-actor-x11.c index 5cab15fd7..f6c9fb185 100644 --- a/src/compositor/meta-surface-actor-x11.c +++ b/src/compositor/meta-surface-actor-x11.c @@ -28,7 +28,6 @@ #include "meta-surface-actor-x11.h" #include -#include #include #include @@ -54,7 +53,6 @@ struct _MetaSurfaceActorX11Private guint does_full_damage : 1; /* Other state... */ - guint argb32 : 1; guint received_damage : 1; guint size_changed : 1; @@ -266,28 +264,6 @@ meta_surface_actor_x11_pre_paint (MetaSurfaceActor *actor) update_pixmap (self); } -static void -update_is_argb32 (MetaSurfaceActorX11 *self) -{ - MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); - MetaDisplay *display = priv->display; - Display *xdisplay = meta_display_get_xdisplay (display); - - XRenderPictFormat *format; - format = XRenderFindVisualFormat (xdisplay, priv->window->xvisual); - - priv->argb32 = (format && format->type == PictTypeDirect && format->direct.alphaMask); -} - -static gboolean -meta_surface_actor_x11_is_argb32 (MetaSurfaceActor *actor) -{ - MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor); - MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); - - return priv->argb32; -} - static gboolean meta_surface_actor_x11_is_visible (MetaSurfaceActor *actor) { @@ -312,7 +288,7 @@ meta_surface_actor_x11_should_unredirect (MetaSurfaceActor *actor) if (window->shape_region != NULL) return FALSE; - if (priv->argb32 && !meta_window_requested_bypass_compositor (window)) + if (meta_surface_actor_is_argb32 (actor) && !meta_window_requested_bypass_compositor (window)) return FALSE; if (!meta_window_is_monitor_sized (window)) @@ -405,7 +381,6 @@ meta_surface_actor_x11_class_init (MetaSurfaceActorX11Class *klass) surface_actor_class->process_damage = meta_surface_actor_x11_process_damage; surface_actor_class->pre_paint = meta_surface_actor_x11_pre_paint; - surface_actor_class->is_argb32 = meta_surface_actor_x11_is_argb32; surface_actor_class->is_visible = meta_surface_actor_x11_is_visible; surface_actor_class->should_unredirect = meta_surface_actor_x11_should_unredirect; @@ -461,8 +436,6 @@ meta_surface_actor_x11_new (MetaWindow *window) g_signal_connect_object (priv->window, "notify::decorated", G_CALLBACK (window_decorated_notify), self, 0); - update_is_argb32 (self); - priv->unredirected = FALSE; sync_unredirected (self); diff --git a/src/compositor/meta-surface-actor.c b/src/compositor/meta-surface-actor.c index 7b4fc298d..3e7db6b20 100644 --- a/src/compositor/meta-surface-actor.c +++ b/src/compositor/meta-surface-actor.c @@ -263,7 +263,26 @@ meta_surface_actor_pre_paint (MetaSurfaceActor *self) gboolean meta_surface_actor_is_argb32 (MetaSurfaceActor *self) { - return META_SURFACE_ACTOR_GET_CLASS (self)->is_argb32 (self); + MetaShapedTexture *stex = meta_surface_actor_get_texture (self); + CoglTexture *texture = meta_shaped_texture_get_texture (stex); + + /* If we don't have a texture, like during initialization, assume + * that we're ARGB32. */ + if (!texture) + return TRUE; + + switch (cogl_texture_get_components (texture)) + { + case COGL_TEXTURE_COMPONENTS_A: + case COGL_TEXTURE_COMPONENTS_RGBA: + return TRUE; + case COGL_TEXTURE_COMPONENTS_RG: + case COGL_TEXTURE_COMPONENTS_RGB: + case COGL_TEXTURE_COMPONENTS_DEPTH: + return FALSE; + default: + g_assert_not_reached (); + } } gboolean diff --git a/src/compositor/meta-surface-actor.h b/src/compositor/meta-surface-actor.h index c06e1836b..3991d5297 100644 --- a/src/compositor/meta-surface-actor.h +++ b/src/compositor/meta-surface-actor.h @@ -29,7 +29,6 @@ struct _MetaSurfaceActorClass void (* process_damage) (MetaSurfaceActor *actor, int x, int y, int width, int height); void (* pre_paint) (MetaSurfaceActor *actor); - gboolean (* is_argb32) (MetaSurfaceActor *actor); gboolean (* is_visible) (MetaSurfaceActor *actor); gboolean (* should_unredirect) (MetaSurfaceActor *actor); From 208296a619c13950877aaea4da4e236bb140a0e2 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 26 Mar 2014 12:02:08 -0400 Subject: [PATCH 749/889] wayland: Shut up about Setenv if we're past initialization I'm a bit tired of hearing about this when I launch mutter-wayland nested. Ideally, this would be part of display server integration, not GNOME integration, so we could simply not make the call when nested, but oh well. --- src/wayland/meta-wayland.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index 79ebd302d..12c1935c4 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -575,14 +575,13 @@ set_gnome_env (const char *name, const char *value) { GDBusConnection *session_bus; - GError *error; + GError *error = NULL; setenv (name, value, TRUE); session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); g_assert (session_bus); - error = NULL; g_dbus_connection_call_sync (session_bus, "org.gnome.SessionManager", "/org/gnome/SessionManager", @@ -594,8 +593,10 @@ set_gnome_env (const char *name, -1, NULL, &error); if (error) { - meta_warning ("Failed to set environment variable %s for gnome-session: %s\n", name, error->message); - g_clear_error (&error); + if (g_strcmp0 (g_dbus_error_get_remote_error (error), "org.gnome.SessionManager.NotInInitialization") != 0) + meta_warning ("Failed to set environment variable %s for gnome-session: %s\n", name, error->message); + + g_error_free (error); } } From 97ea4e87172259b0a0eb6bd000760c438d27beb1 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 26 Mar 2014 12:03:46 -0400 Subject: [PATCH 750/889] xwayland: Remove some stray logs These really aren't too helpful. --- src/wayland/meta-xwayland.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index 8c0fe3595..7748b123c 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -145,7 +145,6 @@ create_lockfile (int display, int *display_out) if (kill (other, 0) < 0 && errno == ESRCH) { - g_warning ("unlinking stale lock file %s", filename); if (unlink (filename) < 0) { const char *msg = strerror (errno); @@ -393,8 +392,6 @@ meta_xwayland_start (MetaXWaylandManager *manager, &pid, &error)) { - g_message ("forked X server, pid %d\n", pid); - close (sp[1]); manager->client = wl_client_create (wl_display, sp[0]); From d7519f4ebc3202998e3fd0662735b05b32974577 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 3 Oct 2013 18:31:09 -0400 Subject: [PATCH 751/889] Remove any possibility for zaphod mode We previously separated out MetaDisplay and MetaScreen. mutter would only manage one screen, but we still kept a list of screens for simplicity. With Wayland support, we no longer care about the ability to manage more than one screen at a time. Remove this by killing the list of screens, in favor of having just one MetaScreen in MetaDisplay. We also kill off active_screen at the same time, since it's not necessary anymore. A future cleanup should merge MetaDisplay and MetaScreen. To avoid breaking API, we should probably keep MetaScreen around as a dummy type. --- src/compositor/compositor.c | 34 +---- src/core/bell.c | 20 +-- src/core/core.c | 9 +- src/core/display-private.h | 7 +- src/core/display.c | 241 +++++------------------------------- src/core/events.c | 186 +++++++--------------------- src/core/keybindings.c | 44 ++----- src/core/screen.c | 22 ---- src/core/window.c | 3 +- src/meta/display.h | 6 - src/meta/screen.h | 2 - src/x11/session.c | 2 +- src/x11/window-x11.c | 16 +-- 13 files changed, 100 insertions(+), 492 deletions(-) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 3881ff941..9f30b7ee3 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -935,10 +935,7 @@ meta_compositor_process_event (MetaCompositor *compositor, MetaWindow *window) { MetaDisplay *display = compositor->display; - MetaScreen *screen = display->screens->data; - MetaCompScreen *info; - - info = meta_screen_get_compositor_data (screen); + MetaCompScreen *info = meta_screen_get_compositor_data (display->screen); if (is_modal (display) && is_grabbed_event (compositor->display, event)) { @@ -1367,18 +1364,8 @@ static gboolean meta_repaint_func (gpointer data) { MetaCompositor *compositor = data; - GSList *screens = meta_display_get_screens (compositor->display); - GSList *l; - - for (l = screens; l; l = l->next) - { - MetaScreen *screen = l->data; - MetaCompScreen *info = meta_screen_get_compositor_data (screen); - if (!info) - continue; - - pre_paint_windows (info); - } + MetaCompScreen *info = meta_screen_get_compositor_data (compositor->display->screen); + pre_paint_windows (info); return TRUE; } @@ -1387,20 +1374,11 @@ static void on_shadow_factory_changed (MetaShadowFactory *factory, MetaCompositor *compositor) { - GSList *screens = meta_display_get_screens (compositor->display); + MetaCompScreen *info = meta_screen_get_compositor_data (compositor->display->screen); GList *l; - GSList *sl; - for (sl = screens; sl; sl = sl->next) - { - MetaScreen *screen = sl->data; - MetaCompScreen *info = meta_screen_get_compositor_data (screen); - if (!info) - continue; - - for (l = info->windows; l; l = l->next) - meta_window_actor_invalidate_shadow (l->data); - } + for (l = info->windows; l; l = l->next) + meta_window_actor_invalidate_shadow (l->data); } /** diff --git a/src/core/bell.c b/src/core/bell.c index 5479142f4..0b1457b40 100644 --- a/src/core/bell.c +++ b/src/core/bell.c @@ -74,26 +74,8 @@ static void bell_flash_fullscreen (MetaDisplay *display, XkbAnyEvent *xkb_ev) { - XkbBellNotifyEvent *xkb_bell_ev = (XkbBellNotifyEvent *) xkb_ev; - MetaScreen *screen; - g_assert (xkb_ev->xkb_type == XkbBellNotify); - if (xkb_bell_ev->window != None) - { - screen = meta_display_screen_for_xwindow (display, xkb_bell_ev->window); - if (screen) - meta_compositor_flash_screen (display->compositor, screen); - } - else - { - GSList *screen_list = display->screens; - while (screen_list) - { - screen = (MetaScreen *) screen_list->data; - meta_compositor_flash_screen (display->compositor, screen); - screen_list = screen_list->next; - } - } + meta_compositor_flash_screen (display->compositor, display->screen); } /** diff --git a/src/core/core.c b/src/core/core.c index 0c46a2f22..c18975674 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -274,7 +274,7 @@ meta_core_lower_beneath_grab_window (Display *xdisplay, MetaStackWindow stack_sibling; display = meta_display_for_x_display (xdisplay); - screen = meta_display_screen_for_xwindow (display, xwindow); + screen = display->screen; grab_window = display->grab_window; if (grab_window == NULL) @@ -603,13 +603,10 @@ meta_core_get_workspace_name_with_index (Display *xdisplay, int index) { MetaDisplay *display; - MetaScreen *screen; MetaWorkspace *workspace; display = meta_display_for_x_display (xdisplay); - screen = meta_display_screen_for_root (display, xroot); - g_assert (screen != NULL); - workspace = meta_screen_get_workspace_by_index (screen, index); + workspace = meta_screen_get_workspace_by_index (display->screen, index); return workspace ? meta_workspace_get_name (workspace) : NULL; } @@ -630,7 +627,7 @@ meta_core_begin_grab_op (Display *xdisplay, MetaScreen *screen; display = meta_display_for_x_display (xdisplay); - screen = meta_display_screen_for_xwindow (display, frame_xwindow); + screen = display->screen; g_assert (screen != NULL); diff --git a/src/core/display-private.h b/src/core/display-private.h index 885940120..1a78402e2 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -148,8 +148,7 @@ struct _MetaDisplay /*< private-ish >*/ guint error_trap_synced_at_last_pop : 1; - GSList *screens; - MetaScreen *active_screen; + MetaScreen *screen; GHashTable *xids; GHashTable *wayland_windows; int error_traps; @@ -351,10 +350,6 @@ struct _MetaDisplayClass gboolean meta_display_open (void); void meta_display_close (MetaDisplay *display, guint32 timestamp); -MetaScreen* meta_display_screen_for_x_screen (MetaDisplay *display, - Screen *screen); -MetaScreen* meta_display_screen_for_xwindow (MetaDisplay *display, - Window xindow); void meta_display_grab (MetaDisplay *display); void meta_display_ungrab (MetaDisplay *display); diff --git a/src/core/display.c b/src/core/display.c index c63f2cee7..372bb1e06 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -362,8 +362,6 @@ sn_error_trap_pop (SnDisplay *sn_display, static void enable_compositor (MetaDisplay *display) { - GSList *list; - if (!META_DISPLAY_HAS_COMPOSITE (display) || !META_DISPLAY_HAS_DAMAGE (display) || !META_DISPLAY_HAS_RENDER (display)) @@ -379,14 +377,8 @@ enable_compositor (MetaDisplay *display) if (!display->compositor) return; - - for (list = display->screens; list != NULL; list = list->next) - { - MetaScreen *screen = list->data; - - meta_compositor_manage_screen (screen->display->compositor, - screen); - } + + meta_compositor_manage_screen (display->compositor, display->screen); } static void @@ -440,7 +432,6 @@ gboolean meta_display_open (void) { Display *xdisplay; - GSList *screens; MetaScreen *screen; int i; guint32 timestamp; @@ -536,8 +527,7 @@ meta_display_open (void) the_display->window_with_menu = NULL; the_display->window_menu = NULL; - the_display->screens = NULL; - the_display->active_screen = NULL; + the_display->screen = NULL; #ifdef HAVE_STARTUP_NOTIFICATION the_display->sn_display = sn_display_new (the_display->xdisplay, @@ -841,15 +831,12 @@ meta_display_open (void) the_display->last_focus_time = timestamp; the_display->last_user_time = timestamp; the_display->compositor = NULL; - + /* Mutter used to manage all X screens of the display in a single process, but * now it always manages exactly one screen as specified by the DISPLAY - * environment variable. The screens GSList is left for simplicity. + * environment variable. */ - screens = NULL; - i = meta_ui_get_screen_number (); - screen = meta_screen_new (the_display, i, timestamp); if (!screen) @@ -861,9 +848,7 @@ meta_display_open (void) return FALSE; } - screens = g_slist_prepend (screens, screen); - - the_display->screens = screens; + the_display->screen = screen; enable_compositor (the_display); @@ -895,7 +880,7 @@ meta_display_open (void) if (focus == None || focus == PointerRoot) /* Just focus the no_focus_window on the first screen */ meta_display_focus_the_no_focus_window (the_display, - the_display->screens->data, + the_display->screen, timestamp); else { @@ -906,7 +891,7 @@ meta_display_open (void) else /* Just focus the no_focus_window on the first screen */ meta_display_focus_the_no_focus_window (the_display, - the_display->screens->data, + the_display->screen, timestamp); } @@ -948,8 +933,8 @@ meta_display_list_windows (MetaDisplay *display, MetaListWindowsFlags flags) { GSList *winlist; - GSList *tmp; GSList *prev; + GSList *tmp; GHashTableIter iter; gpointer key, value; @@ -1024,8 +1009,6 @@ void meta_display_close (MetaDisplay *display, guint32 timestamp) { - GSList *tmp; - g_assert (display != NULL); if (display->closing != 0) @@ -1053,17 +1036,7 @@ meta_display_close (MetaDisplay *display, /* Stop caring about events */ meta_display_free_events (display); - /* Free all screens */ - tmp = display->screens; - while (tmp != NULL) - { - MetaScreen *screen = tmp->data; - meta_screen_free (screen, timestamp); - tmp = tmp->next; - } - - g_slist_free (display->screens); - display->screens = NULL; + meta_screen_free (display->screen, timestamp); #ifdef HAVE_STARTUP_NOTIFICATION if (display->sn_display) @@ -1099,77 +1072,6 @@ meta_display_close (MetaDisplay *display, meta_quit (META_EXIT_SUCCESS); } -/** - * meta_display_screen_for_root: - * @display: a #MetaDisplay - * @xroot: a X window - * - * Return the #MetaScreen corresponding to a specified X root window ID. - * - * Return Value: (transfer none): the screen for the specified root window ID, or %NULL - */ -MetaScreen* -meta_display_screen_for_root (MetaDisplay *display, - Window xroot) -{ - GSList *tmp; - - tmp = display->screens; - while (tmp != NULL) - { - MetaScreen *screen = tmp->data; - - if (xroot == screen->xroot) - return screen; - - tmp = tmp->next; - } - - return NULL; -} - -MetaScreen* -meta_display_screen_for_xwindow (MetaDisplay *display, - Window xwindow) -{ - XWindowAttributes attr; - int result; - - meta_error_trap_push (display); - attr.screen = NULL; - result = XGetWindowAttributes (display->xdisplay, xwindow, &attr); - meta_error_trap_pop (display); - - /* Note, XGetWindowAttributes is on all kinds of crack - * and returns 1 on success 0 on failure, rather than Success - * on success. - */ - if (result == 0 || attr.screen == NULL) - return NULL; - - return meta_display_screen_for_x_screen (display, attr.screen); -} - -MetaScreen* -meta_display_screen_for_x_screen (MetaDisplay *display, - Screen *xscreen) -{ - GSList *tmp; - - tmp = display->screens; - while (tmp != NULL) - { - MetaScreen *screen = tmp->data; - - if (xscreen == screen->xscreen) - return screen; - - tmp = tmp->next; - } - - return NULL; -} - /* Grab/ungrab routines taken from fvwm. * Calling this function will cause X to ignore all other clients until * you ungrab. This may not be quite as bad as it sounds, yet there is @@ -1775,7 +1677,6 @@ request_xserver_input_focus_change (MetaDisplay *display, meta_error_trap_pop (display); display->last_focus_time = timestamp; - display->active_screen = screen; if (meta_window == NULL || meta_window != display->autoraise_window) meta_display_remove_autoraise_callback (display); @@ -1877,18 +1778,7 @@ gboolean meta_display_xwindow_is_a_no_focus_window (MetaDisplay *display, Window xwindow) { - gboolean is_a_no_focus_window = FALSE; - GSList *temp = display->screens; - while (temp != NULL) { - MetaScreen *screen = temp->data; - if (screen->no_focus_window == xwindow) { - is_a_no_focus_window = TRUE; - break; - } - temp = temp->next; - } - - return is_a_no_focus_window; + return xwindow == display->screen->no_focus_window; } static MetaCursor @@ -2517,30 +2407,19 @@ meta_display_increment_event_serial (MetaDisplay *display) void meta_display_update_active_window_hint (MetaDisplay *display) { - GSList *tmp; - gulong data[1]; if (display->focus_window) data[0] = display->focus_window->xwindow; else data[0] = None; - - tmp = display->screens; - while (tmp != NULL) - { - MetaScreen *screen = tmp->data; - - meta_error_trap_push (display); - XChangeProperty (display->xdisplay, screen->xroot, - display->atom__NET_ACTIVE_WINDOW, - XA_WINDOW, - 32, PropModeReplace, (guchar*) data, 1); - meta_error_trap_pop (display); - - tmp = tmp->next; - } + meta_error_trap_push (display); + XChangeProperty (display->xdisplay, display->screen->xroot, + display->atom__NET_ACTIVE_WINDOW, + XA_WINDOW, + 32, PropModeReplace, (guchar*) data, 1); + meta_error_trap_pop (display); } void @@ -2578,22 +2457,12 @@ void meta_display_set_cursor_theme (const char *theme, int size) { - GSList *tmp; - MetaDisplay *display = meta_get_display (); XcursorSetTheme (display->xdisplay, theme); XcursorSetDefaultSize (display->xdisplay, size); - tmp = display->screens; - while (tmp != NULL) - { - MetaScreen *screen = tmp->data; - - meta_screen_update_cursor (screen); - - tmp = tmp->next; - } + meta_screen_update_cursor (display->screen); } /* @@ -2808,7 +2677,6 @@ get_focused_group (MetaDisplay *display) static MetaWindow* find_tab_forward (MetaDisplay *display, MetaTabList type, - MetaScreen *screen, MetaWorkspace *workspace, GList *start, gboolean skip_first) @@ -2826,8 +2694,7 @@ find_tab_forward (MetaDisplay *display, { MetaWindow *window = tmp->data; - if (window->screen == screen && - IN_TAB_CHAIN (window, type)) + if (IN_TAB_CHAIN (window, type)) return window; tmp = tmp->next; @@ -2850,7 +2717,6 @@ find_tab_forward (MetaDisplay *display, static MetaWindow* find_tab_backward (MetaDisplay *display, MetaTabList type, - MetaScreen *screen, MetaWorkspace *workspace, GList *start, gboolean skip_last) @@ -2867,8 +2733,7 @@ find_tab_backward (MetaDisplay *display, { MetaWindow *window = tmp->data; - if (window->screen == screen && - IN_TAB_CHAIN (window, type)) + if (IN_TAB_CHAIN (window, type)) return window; tmp = tmp->prev; @@ -2909,21 +2774,19 @@ mru_cmp (gconstpointer a, * meta_display_get_tab_list: * @display: a #MetaDisplay * @type: type of tab list - * @screen: a #MetaScreen * @workspace: (allow-none): origin workspace * * Determine the list of windows that should be displayed for Alt-TAB * functionality. The windows are returned in most recently used order. * If @workspace is not %NULL, the list only conains windows that are on * @workspace or have the demands-attention hint set; otherwise it contains - * all windows on @screen. + * all windows. * * Returns: (transfer container) (element-type Meta.Window): List of windows */ GList* meta_display_get_tab_list (MetaDisplay *display, MetaTabList type, - MetaScreen *screen, MetaWorkspace *workspace) { GList *tab_list = NULL; @@ -2948,8 +2811,7 @@ meta_display_get_tab_list (MetaDisplay *display, { MetaWindow *window = tmp->data; - if (window->screen == screen && - IN_TAB_CHAIN (window, type)) + if (IN_TAB_CHAIN (window, type)) tab_list = g_list_prepend (tab_list, window); } @@ -2979,7 +2841,6 @@ meta_display_get_tab_list (MetaDisplay *display, * meta_display_get_tab_next: * @display: a #MetaDisplay * @type: type of tab list - * @screen: a #MetaScreen * @workspace: origin workspace * @window: (allow-none): starting window * @backward: If %TRUE, look for the previous window. @@ -2993,7 +2854,6 @@ meta_display_get_tab_list (MetaDisplay *display, MetaWindow* meta_display_get_tab_next (MetaDisplay *display, MetaTabList type, - MetaScreen *screen, MetaWorkspace *workspace, MetaWindow *window, gboolean backward) @@ -3001,10 +2861,7 @@ meta_display_get_tab_next (MetaDisplay *display, gboolean skip; GList *tab_list; MetaWindow *ret; - tab_list = meta_display_get_tab_list(display, - type, - screen, - workspace); + tab_list = meta_display_get_tab_list (display, type, workspace); if (tab_list == NULL) return NULL; @@ -3014,26 +2871,18 @@ meta_display_get_tab_next (MetaDisplay *display, g_assert (window->display == display); if (backward) - ret = find_tab_backward (display, type, screen, workspace, - g_list_find (tab_list, - window), - TRUE); + ret = find_tab_backward (display, type, workspace, g_list_find (tab_list, window), TRUE); else - ret = find_tab_forward (display, type, screen, workspace, - g_list_find (tab_list, - window), - TRUE); + ret = find_tab_forward (display, type, workspace, g_list_find (tab_list, window), TRUE); } else { skip = display->focus_window != NULL && tab_list->data == display->focus_window; if (backward) - ret = find_tab_backward (display, type, screen, workspace, - tab_list, skip); + ret = find_tab_backward (display, type, workspace, tab_list, skip); else - ret = find_tab_forward (display, type, screen, workspace, - tab_list, skip); + ret = find_tab_forward (display, type, workspace, tab_list, skip); } g_list_free (tab_list); @@ -3044,7 +2893,6 @@ meta_display_get_tab_next (MetaDisplay *display, * meta_display_get_tab_current: * @display: a #MetaDisplay * @type: type of tab list - * @screen: a #MetaScreen * @workspace: origin workspace * * Determine the active window that should be displayed for Alt-TAB. @@ -3055,7 +2903,6 @@ meta_display_get_tab_next (MetaDisplay *display, MetaWindow* meta_display_get_tab_current (MetaDisplay *display, MetaTabList type, - MetaScreen *screen, MetaWorkspace *workspace) { MetaWindow *window; @@ -3063,7 +2910,6 @@ meta_display_get_tab_current (MetaDisplay *display, window = display->focus_window; if (window != NULL && - window->screen == screen && IN_TAB_CHAIN (window, type) && (workspace == NULL || meta_window_located_on_workspace (window, workspace))) @@ -3129,14 +2975,9 @@ meta_display_unmanage_screen (MetaDisplay *display, { meta_verbose ("Unmanaging screen %d on display %s\n", screen->number, display->name); - - g_return_if_fail (g_slist_find (display->screens, screen) != NULL); - - meta_screen_free (screen, timestamp); - display->screens = g_slist_remove (display->screens, screen); - if (display->screens == NULL) - meta_display_close (display, timestamp); + meta_screen_free (screen, timestamp); + meta_display_close (display, timestamp); } void @@ -3178,15 +3019,7 @@ meta_display_stack_cmp (const void *a, MetaWindow *aw = (void*) a; MetaWindow *bw = (void*) b; - if (aw->screen == bw->screen) - return meta_stack_windows_cmp (aw->screen->stack, aw, bw); - /* Then assume screens are stacked by number */ - else if (aw->screen->number < bw->screen->number) - return -1; - else if (aw->screen->number > bw->screen->number) - return 1; - else - return 0; /* not reached in theory, if windows on same display */ + return meta_stack_windows_cmp (aw->screen->stack, aw, bw); } /** @@ -3322,7 +3155,7 @@ meta_display_increment_focus_sentinel (MetaDisplay *display) data[0] = meta_display_get_current_time (display); XChangeProperty (display->xdisplay, - ((MetaScreen*) display->screens->data)->xroot, + display->screen->xroot, display->atom__MUTTER_SENTINEL, XA_CARDINAL, 32, PropModeReplace, (guchar*) data, 1); @@ -3526,18 +3359,6 @@ meta_display_get_compositor (MetaDisplay *display) return display->compositor; } -/** - * meta_display_get_screens: - * @display: a #MetaDisplay - * - * Returns: (transfer none) (element-type Meta.Screen): Screens for this display - */ -GSList * -meta_display_get_screens (MetaDisplay *display) -{ - return display->screens; -} - gboolean meta_display_has_shape (MetaDisplay *display) { diff --git a/src/core/events.c b/src/core/events.c index 342503664..137c60539 100644 --- a/src/core/events.c +++ b/src/core/events.c @@ -666,10 +666,10 @@ G_GNUC_UNUSED static void meta_spew_event (MetaDisplay *display, XEvent *event) { + MetaScreen *screen = display->screen; const char *name = NULL; char *extra = NULL; char *winname; - MetaScreen *screen; XIEvent *input_event; /* filter overnumerous events */ @@ -693,9 +693,7 @@ meta_spew_event (MetaDisplay *display, else meta_spew_core_event (display, event, &name, &extra); - screen = meta_display_screen_for_root (display, event->xany.window); - - if (screen) + if (event->xany.window == screen->xroot) winname = g_strdup_printf ("root %d", screen->number); else winname = g_strdup_printf ("0x%lx", event->xany.window); @@ -735,7 +733,7 @@ handle_window_focus_event (MetaDisplay *display, } else if (meta_display_xwindow_is_a_no_focus_window (display, event->event)) window_type = "no_focus_window"; - else if (meta_display_screen_for_root (display, event->event)) + else if (event->event == display->screen->xroot) window_type = "root window"; else window_type = "unknown window"; @@ -855,7 +853,7 @@ handle_input_xevent (MetaDisplay *display, XIEnterEvent *enter_event = (XIEnterEvent *) input_event; Window modified; MetaWindow *window; - MetaScreen *screen; + MetaScreen *screen = display->screen; if (input_event == NULL) return FALSE; @@ -869,20 +867,6 @@ handle_input_xevent (MetaDisplay *display, if (display->grab_op == META_GRAB_OP_COMPOSITOR) break; - /* If the mouse switches screens, active the default window on the new - * screen; this will make keybindings and workspace-launched items - * actually appear on the right screen. - */ - { - MetaScreen *new_screen = - meta_display_screen_for_root (display, enter_event->root); - - if (new_screen != NULL && display->active_screen != new_screen) - meta_workspace_focus_default_window (new_screen->active_workspace, - NULL, - enter_event->time); - } - /* Check if we've entered a window; do this even if window->has_focus to * avoid races. */ @@ -923,8 +907,6 @@ handle_input_xevent (MetaDisplay *display, if (enter_event->root != enter_event->event) break; - screen = meta_display_screen_for_root (display, enter_event->root); - if (enter_event->evtype == XI_FocusIn && enter_event->mode == XINotifyDetailNone) { @@ -1013,21 +995,9 @@ process_request_frame_extents (MetaDisplay *display, if ((hints_set && hints->decorations) || !hints_set) { MetaFrameBorders borders; - MetaScreen *screen; - - screen = meta_display_screen_for_xwindow (display, - event->xclient.window); - if (screen == NULL) - { - meta_warning ("Received request to set _NET_FRAME_EXTENTS " - "on 0x%lx which is on a screen we are not managing\n", - event->xclient.window); - meta_XFree (hints); - return; - } /* Return estimated frame extents for a normal window. */ - meta_ui_theme_get_frame_borders (screen->ui, + meta_ui_theme_get_frame_borders (display->screen->ui, META_FRAME_TYPE_NORMAL, 0, &borders); @@ -1052,28 +1022,6 @@ process_request_frame_extents (MetaDisplay *display, meta_XFree (hints); } -static MetaScreen* -find_screen_for_selection (MetaDisplay *display, - Window owner, - Atom selection) -{ - GSList *tmp; - - tmp = display->screens; - while (tmp != NULL) - { - MetaScreen *screen = tmp->data; - - if (screen->wm_sn_selection_window == owner && - screen->wm_sn_atom == selection) - return screen; - - tmp = tmp->next; - } - - return NULL; -} - /* from fvwm2, Copyright Matthias Clasen, Dominik Vogt */ static gboolean convert_property (MetaDisplay *display, @@ -1128,14 +1076,11 @@ static void process_selection_request (MetaDisplay *display, XEvent *event) { + MetaScreen *screen = display->screen; XSelectionEvent reply; - MetaScreen *screen; - screen = find_screen_for_selection (display, - event->xselectionrequest.owner, - event->xselectionrequest.selection); - - if (screen == NULL) + if (screen->wm_sn_selection_window != event->xselectionrequest.owner || + screen->wm_sn_atom != event->xselectionrequest.selection) { char *str; @@ -1231,41 +1176,31 @@ static void process_selection_clear (MetaDisplay *display, XEvent *event) { - /* We need to unmanage the screen on which we lost the selection */ - MetaScreen *screen; + MetaScreen *screen = display->screen; - screen = find_screen_for_selection (display, - event->xselectionclear.window, - event->xselectionclear.selection); - - - if (screen != NULL) + if (screen->wm_sn_selection_window != event->xselectionclear.window || + screen->wm_sn_atom != event->xselectionclear.selection) { - meta_verbose ("Got selection clear for screen %d on display %s\n", - screen->number, display->name); + char *str; - meta_display_unmanage_screen (display, - screen, - event->xselectionclear.time); + meta_error_trap_push (display); + str = XGetAtomName (display->xdisplay, + event->xselectionclear.selection); + meta_error_trap_pop (display); - /* display and screen may both be invalid memory... */ + meta_verbose ("Selection clear with selection %s window 0x%lx not a WM_Sn selection we recognize\n", + str ? str : "(bad atom)", event->xselectionclear.window); + + meta_XFree (str); return; } - { - char *str; + meta_verbose ("Got selection clear for screen %d on display %s\n", + screen->number, display->name); - meta_error_trap_push (display); - str = XGetAtomName (display->xdisplay, - event->xselectionclear.selection); - meta_error_trap_pop (display); - - meta_verbose ("Selection clear with selection %s window 0x%lx not a WM_Sn selection we recognize\n", - str ? str : "(bad atom)", event->xselectionclear.window); - - meta_XFree (str); - } + meta_display_unmanage_screen (display, display->screen, + event->xselectionclear.time); } static gboolean @@ -1356,24 +1291,16 @@ handle_other_xevent (MetaDisplay *display, break; case CreateNotify: { - MetaScreen *screen; - - screen = meta_display_screen_for_root (display, - event->xcreatewindow.parent); - if (screen) - meta_stack_tracker_create_event (screen->stack_tracker, + if (event->xcreatewindow.parent == display->screen->xroot) + meta_stack_tracker_create_event (display->screen->stack_tracker, &event->xcreatewindow); } break; case DestroyNotify: { - MetaScreen *screen; - - screen = meta_display_screen_for_root (display, - event->xdestroywindow.event); - if (screen) - meta_stack_tracker_destroy_event (screen->stack_tracker, + if (event->xdestroywindow.event == display->screen->xroot) + meta_stack_tracker_destroy_event (display->screen->stack_tracker, &event->xdestroywindow); } if (window) @@ -1447,8 +1374,7 @@ handle_other_xevent (MetaDisplay *display, /* NB: override redirect windows wont cause a map request so we * watch out for map notifies against any root windows too if a * compositor is enabled: */ - if (window == NULL - && meta_display_screen_for_root (display, event->xmap.event)) + if (window == NULL) { window = meta_window_x11_new (display, event->xmap.window, FALSE, META_COMP_EFFECT_CREATE); @@ -1480,24 +1406,16 @@ handle_other_xevent (MetaDisplay *display, break; case ReparentNotify: { - MetaScreen *screen; - - screen = meta_display_screen_for_root (display, - event->xconfigure.event); - if (screen) - meta_stack_tracker_reparent_event (screen->stack_tracker, + if (event->xreparent.event == display->screen->xroot) + meta_stack_tracker_reparent_event (display->screen->stack_tracker, &event->xreparent); } break; case ConfigureNotify: if (event->xconfigure.event != event->xconfigure.window) { - MetaScreen *screen; - - screen = meta_display_screen_for_root (display, - event->xconfigure.event); - if (screen) - meta_stack_tracker_configure_event (screen->stack_tracker, + if (event->xconfigure.event == display->screen->xroot) + meta_stack_tracker_configure_event (display->screen->stack_tracker, &event->xconfigure); } @@ -1551,7 +1469,6 @@ handle_other_xevent (MetaDisplay *display, case PropertyNotify: { MetaGroup *group; - MetaScreen *screen; if (window && !frame_was_receiver) meta_window_x11_property_notify (window, event); @@ -1563,24 +1480,18 @@ handle_other_xevent (MetaDisplay *display, if (group != NULL) meta_group_property_notify (group, event); - screen = NULL; - if (window == NULL && - group == NULL) /* window/group != NULL means it wasn't a root window */ - screen = meta_display_screen_for_root (display, - event->xproperty.window); - - if (screen != NULL) + if (event->xproperty.window == display->screen->xroot) { if (event->xproperty.atom == display->atom__NET_DESKTOP_LAYOUT) - meta_screen_update_workspace_layout (screen); + meta_screen_update_workspace_layout (display->screen); else if (event->xproperty.atom == display->atom__NET_DESKTOP_NAMES) - meta_screen_update_workspace_names (screen); + meta_screen_update_workspace_names (display->screen); else if (meta_is_wayland_compositor () && event->xproperty.atom == display->atom__XKB_RULES_NAMES) - reload_xkb_rules (screen); + reload_xkb_rules (display->screen); #if 0 else if (event->xproperty.atom == display->atom__NET_RESTACK_WINDOW) @@ -1629,12 +1540,7 @@ handle_other_xevent (MetaDisplay *display, } else { - MetaScreen *screen; - - screen = meta_display_screen_for_root (display, - event->xclient.window); - - if (screen) + if (event->xclient.window == display->screen->xroot) { if (event->xclient.message_type == display->atom__NET_CURRENT_DESKTOP) @@ -1650,9 +1556,7 @@ handle_other_xevent (MetaDisplay *display, "specified timestamp of %u\n", space, time); - workspace = - meta_screen_get_workspace_by_index (screen, - space); + workspace = meta_screen_get_workspace_by_index (display->screen, space); /* Handle clients using the older version of the spec... */ if (time == 0 && workspace) @@ -1693,11 +1597,11 @@ handle_other_xevent (MetaDisplay *display, showing_desktop ? "show" : "hide"); if (showing_desktop) - meta_screen_show_desktop (screen, timestamp); + meta_screen_show_desktop (display->screen, timestamp); else { - meta_screen_unshow_desktop (screen); - meta_workspace_focus_default_window (screen->active_workspace, NULL, timestamp); + meta_screen_unshow_desktop (display->screen); + meta_workspace_focus_default_window (display->screen->active_workspace, NULL, timestamp); } } else if (event->xclient.message_type == @@ -1837,7 +1741,6 @@ meta_display_handle_xevent (MetaDisplay *display, gboolean bypass_compositor = FALSE, bypass_gtk = FALSE; XIEvent *input_event; MetaMonitorManager *monitor; - MetaScreen *screen; #if 0 meta_spew_event (display, event); @@ -1875,10 +1778,9 @@ meta_display_handle_xevent (MetaDisplay *display, FALSE); } - screen = meta_display_screen_for_root (display, event->xany.window); - if (screen) + if (event->xany.window == display->screen->xroot) { - if (meta_screen_handle_xevent (screen, event)) + if (meta_screen_handle_xevent (display->screen, event)) { bypass_gtk = bypass_compositor = TRUE; goto out; diff --git a/src/core/keybindings.c b/src/core/keybindings.c index a574f6c5a..32c1ecaaa 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -685,15 +685,7 @@ ungrab_key_bindings (MetaDisplay *display) meta_error_trap_push (display); /* for efficiency push outer trap */ - tmp = display->screens; - while (tmp != NULL) - { - MetaScreen *screen = tmp->data; - - meta_screen_ungrab_keys (screen); - - tmp = tmp->next; - } + meta_screen_ungrab_keys (display->screen); windows = meta_display_list_windows (display, META_LIST_DEFAULT); tmp = windows; @@ -718,15 +710,7 @@ grab_key_bindings (MetaDisplay *display) meta_error_trap_push (display); /* for efficiency push outer trap */ - tmp = display->screens; - while (tmp != NULL) - { - MetaScreen *screen = tmp->data; - - meta_screen_grab_keys (screen); - - tmp = tmp->next; - } + meta_screen_grab_keys (display->screen); windows = meta_display_list_windows (display, META_LIST_DEFAULT); tmp = windows; @@ -1298,7 +1282,6 @@ meta_display_grab_accelerator (MetaDisplay *display, guint keycode = 0; guint mask = 0; MetaVirtualModifier modifiers = 0; - GSList *l; if (!meta_ui_parse_accelerator (accelerator, &keysym, &keycode, &modifiers)) { @@ -1318,11 +1301,7 @@ meta_display_grab_accelerator (MetaDisplay *display, if (display_get_keybinding (display, keycode, mask)) return META_KEYBINDING_ACTION_NONE; - for (l = display->screens; l; l = l->next) - { - MetaScreen *screen = l->data; - meta_change_keygrab (display, screen->xroot, TRUE, keysym, keycode, mask); - } + meta_change_keygrab (display, display->screen->xroot, TRUE, keysym, keycode, mask); grab = g_new0 (MetaKeyGrab, 1); grab->action = next_dynamic_keybinding_action (); @@ -1372,16 +1351,11 @@ meta_display_ungrab_accelerator (MetaDisplay *display, if (binding) { guint32 index_key; - GSList *l; - for (l = display->screens; l; l = l->next) - { - MetaScreen *screen = l->data; - meta_change_keygrab (display, screen->xroot, FALSE, - binding->keysym, - binding->keycode, - binding->mask); - } + meta_change_keygrab (display, display->screen->xroot, FALSE, + binding->keysym, + binding->keycode, + binding->mask); index_key = key_binding_key (binding->keycode, binding->mask); g_hash_table_remove (display->key_bindings_index, GINT_TO_POINTER (index_key)); @@ -1871,8 +1845,7 @@ meta_display_process_key_event (MetaDisplay *display, /* window may be NULL */ - /* XXX */ - screen = display->active_screen; + screen = display->screen; all_keys_grabbed = window ? window->all_keys_grabbed : screen->all_keys_grabbed; if (!all_keys_grabbed) @@ -2824,7 +2797,6 @@ do_choose_window (MetaDisplay *display, initial_selection = meta_display_get_tab_next (display, type, - screen, screen->active_workspace, NULL, backward); diff --git a/src/core/screen.c b/src/core/screen.c index 5538aee05..36290dc5e 100644 --- a/src/core/screen.c +++ b/src/core/screen.c @@ -900,28 +900,6 @@ meta_screen_manage_all_windows (MetaScreen *screen) meta_stack_thaw (screen->stack); } -/** - * meta_screen_for_x_screen: - * @xscreen: an X screen structure. - * - * Gets the #MetaScreen corresponding to an X screen structure. - * - * Return value: (transfer none): the #MetaScreen for the X screen - * %NULL if Metacity is not managing the screen. - */ -MetaScreen* -meta_screen_for_x_screen (Screen *xscreen) -{ - MetaDisplay *display; - - display = meta_display_for_x_display (DisplayOfScreen (xscreen)); - - if (display == NULL) - return NULL; - - return meta_display_screen_for_x_screen (display, xscreen); -} - static void prefs_changed_callback (MetaPreference pref, gpointer data) diff --git a/src/core/window.c b/src/core/window.c index eb2ed9dce..c70993c25 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -1248,7 +1248,7 @@ meta_window_wayland_new (MetaDisplay *display, MetaWaylandSurface *surface) { XWindowAttributes attrs; - MetaScreen *scr = display->screens->data; + MetaScreen *scr = display->screen; MetaWindow *window; attrs.x = 0; @@ -1280,7 +1280,6 @@ meta_window_wayland_new (MetaDisplay *display, * X requests (passing a window xid of None) until we thoroughly audit all * the code to make sure it knows about non X based clients... */ - meta_error_trap_push (display); /* Push a trap over all of window * creation, to reduce XSync() calls */ diff --git a/src/meta/display.h b/src/meta/display.h index c13f151fd..8d1e669f7 100644 --- a/src/meta/display.h +++ b/src/meta/display.h @@ -73,12 +73,9 @@ int meta_display_get_xinput_opcode (MetaDisplay *display); gboolean meta_display_supports_extended_barriers (MetaDisplay *display); Display *meta_display_get_xdisplay (MetaDisplay *display); MetaCompositor *meta_display_get_compositor (MetaDisplay *display); -GSList *meta_display_get_screens (MetaDisplay *display); gboolean meta_display_has_shape (MetaDisplay *display); -MetaScreen *meta_display_screen_for_root (MetaDisplay *display, - Window xroot); MetaWindow *meta_display_get_focus_window (MetaDisplay *display); gboolean meta_display_xwindow_is_a_no_focus_window (MetaDisplay *display, @@ -99,19 +96,16 @@ unsigned int meta_display_get_ignored_modifier_mask (MetaDisplay *display); GList* meta_display_get_tab_list (MetaDisplay *display, MetaTabList type, - MetaScreen *screen, MetaWorkspace *workspace); MetaWindow* meta_display_get_tab_next (MetaDisplay *display, MetaTabList type, - MetaScreen *screen, MetaWorkspace *workspace, MetaWindow *window, gboolean backward); MetaWindow* meta_display_get_tab_current (MetaDisplay *display, MetaTabList type, - MetaScreen *screen, MetaWorkspace *workspace); gboolean meta_display_begin_grab_op (MetaDisplay *display, diff --git a/src/meta/screen.h b/src/meta/screen.h index 6e0cde7ee..8c65246ca 100644 --- a/src/meta/screen.h +++ b/src/meta/screen.h @@ -48,8 +48,6 @@ gpointer meta_screen_get_compositor_data (MetaScreen *screen); void meta_screen_set_compositor_data (MetaScreen *screen, gpointer info); -MetaScreen *meta_screen_for_x_screen (Screen *xscreen); - void meta_screen_set_cm_selection (MetaScreen *screen); void meta_screen_unset_cm_selection (MetaScreen *screen); diff --git a/src/x11/session.c b/src/x11/session.c index 269d4d0c3..48678ab61 100644 --- a/src/x11/session.c +++ b/src/x11/session.c @@ -1816,7 +1816,7 @@ warn_about_lame_clients_and_finish_interact (gboolean shutdown) "and will have to be restarted manually next time " "you log in."), "240", - meta_get_display()->active_screen->screen_name, + meta_get_display()->screen->screen_name, NULL, NULL, NULL, None, columns, diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c index b5e7d6ebb..896003200 100644 --- a/src/x11/window-x11.c +++ b/src/x11/window-x11.c @@ -2227,9 +2227,8 @@ meta_window_x11_new (MetaDisplay *display, gboolean must_be_viewable, MetaCompEffect effect) { + MetaScreen *screen = display->screen; XWindowAttributes attrs; - MetaScreen *screen = NULL; - GSList *tmp; gulong existing_wm_state; MetaWindow *window = NULL; gulong event_mask; @@ -2259,19 +2258,12 @@ meta_window_x11_new (MetaDisplay *display, goto error; } - for (tmp = display->screens; tmp != NULL; tmp = tmp->next) + if (attrs.root != screen->xroot) { - MetaScreen *scr = tmp->data; - - if (scr->xroot == attrs.root) - { - screen = tmp->data; - break; - } + meta_verbose ("Not on our screen\n"); + goto error; } - g_assert (screen); - if (is_our_xwindow (display, screen, xwindow, &attrs)) { meta_verbose ("Not managing our own windows\n"); From 47aa583625d66460f61aeba8fa7732011e39742e Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 17:57:53 -0400 Subject: [PATCH 752/889] display: Kill off grab_screen Just like active_screen, the screen can always be inferred from the MetaDisplay, so there's no point in keeping it around. --- src/compositor/compositor.c | 2 -- src/core/core.c | 4 ---- src/core/display-private.h | 1 - src/core/display.c | 11 ++++------- src/core/edge-resistance.c | 13 ++++++------- src/core/keybindings.c | 3 +-- 6 files changed, 11 insertions(+), 23 deletions(-) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 9f30b7ee3..897940dd6 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -431,7 +431,6 @@ meta_begin_modal_for_plugin (MetaScreen *screen, display->grab_op = META_GRAB_OP_COMPOSITOR; display->grab_window = NULL; - display->grab_screen = screen; display->grab_have_pointer = TRUE; display->grab_have_keyboard = TRUE; @@ -453,7 +452,6 @@ meta_end_modal_for_plugin (MetaScreen *screen, display->grab_op = META_GRAB_OP_NONE; display->grab_window = NULL; - display->grab_screen = NULL; display->grab_have_pointer = FALSE; display->grab_have_keyboard = FALSE; diff --git a/src/core/core.c b/src/core/core.c index c18975674..a091bb8ca 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -667,10 +667,6 @@ meta_core_get_grab_frame (Display *xdisplay) display = meta_display_for_x_display (xdisplay); g_assert (display != NULL); - g_assert (display->grab_op == META_GRAB_OP_NONE || - display->grab_screen != NULL); - g_assert (display->grab_op == META_GRAB_OP_NONE || - display->grab_screen->display->xdisplay == xdisplay); if (display->grab_op != META_GRAB_OP_NONE && display->grab_window && diff --git a/src/core/display-private.h b/src/core/display-private.h index 1a78402e2..1b8355c72 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -189,7 +189,6 @@ struct _MetaDisplay /* current window operation */ MetaGrabOp grab_op; - MetaScreen *grab_screen; MetaWindow *grab_window; Window grab_xwindow; int grab_button; diff --git a/src/core/display.c b/src/core/display.c index 372bb1e06..b40b76acf 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -562,7 +562,6 @@ meta_display_open (void) the_display->grab_op = META_GRAB_OP_NONE; the_display->grab_window = NULL; - the_display->grab_screen = NULL; the_display->grab_resize_popup = NULL; the_display->grab_tile_mode = META_TILE_NONE; the_display->grab_tile_monitor_number = -1; @@ -1977,7 +1976,6 @@ meta_display_begin_grab_op (MetaDisplay *display, display->grab_op = op; display->grab_window = grab_window; - display->grab_screen = screen; display->grab_xwindow = grab_xwindow; display->grab_button = button; display->grab_mask = modmask; @@ -2030,7 +2028,7 @@ meta_display_begin_grab_op (MetaDisplay *display, "Grab op %u on window %s successful\n", display->grab_op, window ? window->desc : "(null)"); - g_assert (display->grab_window != NULL || display->grab_screen != NULL); + g_assert (display->grab_window != NULL); g_assert (display->grab_op != META_GRAB_OP_NONE); if (display->grab_window) @@ -2058,7 +2056,7 @@ meta_display_end_grab_op (MetaDisplay *display, return; g_signal_emit (display, display_signals[GRAB_OP_END], 0, - display->grab_screen, display->grab_window, display->grab_op); + display->screen, display->grab_window, display->grab_op); if (display->grab_window != NULL) display->grab_window->shaken_loose = FALSE; @@ -2110,14 +2108,13 @@ meta_display_end_grab_op (MetaDisplay *display, if (display->grab_window) meta_window_ungrab_all_keys (display->grab_window, timestamp); else - meta_screen_ungrab_all_keys (display->grab_screen, timestamp); + meta_screen_ungrab_all_keys (display->screen, timestamp); } - meta_cursor_tracker_set_grab_cursor (display->grab_screen->cursor_tracker, META_CURSOR_DEFAULT); + meta_cursor_tracker_set_grab_cursor (display->screen->cursor_tracker, META_CURSOR_DEFAULT); display->grab_timestamp = 0; display->grab_window = NULL; - display->grab_screen = NULL; display->grab_xwindow = None; display->grab_tile_mode = META_TILE_NONE; display->grab_tile_monitor_number = -1; diff --git a/src/core/edge-resistance.c b/src/core/edge-resistance.c index 6a2648a0a..8eb48a729 100644 --- a/src/core/edge-resistance.c +++ b/src/core/edge-resistance.c @@ -30,7 +30,6 @@ */ #define WINDOW_EDGES_RELEVANT(window, display) \ meta_window_should_be_showing (window) && \ - window->screen == display->grab_screen && \ window != display->grab_window && \ window->type != META_WINDOW_DESKTOP && \ window->type != META_WINDOW_MENU && \ @@ -963,9 +962,9 @@ compute_resistance_and_snapping_edges (MetaDisplay *display) /* * 1st: Get the list of relevant windows, from bottom to top */ - stacked_windows = - meta_stack_list_windows (display->grab_screen->stack, - display->grab_screen->active_workspace); + stacked_windows = + meta_stack_list_windows (display->screen->stack, + display->screen->active_workspace); /* * 2nd: we need to separate that stacked list into a list of windows that @@ -1026,7 +1025,7 @@ compute_resistance_and_snapping_edges (MetaDisplay *display) * by other windows or DOCKS, but that's handled below). */ meta_rectangle_intersect (&cur_rect, - &display->grab_screen->rect, + &display->screen->rect, &reduced); new_edges = NULL; @@ -1123,8 +1122,8 @@ compute_resistance_and_snapping_edges (MetaDisplay *display) */ cache_edges (display, edges, - display->grab_screen->active_workspace->monitor_edges, - display->grab_screen->active_workspace->screen_edges); + display->screen->active_workspace->monitor_edges, + display->screen->active_workspace->screen_edges); g_list_free (edges); /* diff --git a/src/core/keybindings.c b/src/core/keybindings.c index 32c1ecaaa..2d82b1651 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -1872,8 +1872,7 @@ meta_display_process_key_event (MetaDisplay *display, * we're in some special keyboard mode such as window move * mode. */ - if (window ? (window == display->grab_window) : - (screen == display->grab_screen)) + if ((window && window == display->grab_window) || !window) { switch (display->grab_op) { From cd905a34fb18666376b44bbd670c8b8e855df149 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 18 Mar 2014 17:31:22 -0400 Subject: [PATCH 753/889] compositor: Kill off MetaCompScreen Compositors haven't been able to manage more than one screen for quite a while. Merge MetaCompScreen into MetaCompositor, and update the API to match. We still keep MetaScreen in the public compositor API for compatibility purposes. --- src/compositor/compositor-private.h | 13 +- src/compositor/compositor.c | 358 ++++++++++++--------------- src/compositor/meta-plugin-manager.c | 18 +- src/compositor/meta-plugin-manager.h | 2 +- src/compositor/meta-plugin.c | 16 +- src/compositor/meta-window-actor.c | 95 +++---- src/core/display.c | 2 +- src/core/keybindings.c | 4 +- src/core/screen-private.h | 3 - src/core/screen.c | 31 +-- src/core/stack-tracker.c | 1 - src/core/workspace.c | 2 +- src/meta/compositor.h | 14 +- src/meta/meta-plugin.h | 2 +- src/meta/screen.h | 4 - 15 files changed, 222 insertions(+), 343 deletions(-) diff --git a/src/compositor/compositor-private.h b/src/compositor/compositor-private.h index bae233baf..ef0a53457 100644 --- a/src/compositor/compositor-private.h +++ b/src/compositor/compositor-private.h @@ -11,8 +11,6 @@ #include "meta-window-actor-private.h" #include -typedef struct _MetaCompScreen MetaCompScreen; - struct _MetaCompositor { MetaDisplay *display; @@ -24,11 +22,6 @@ struct _MetaCompositor guint server_time_is_monotonic_time : 1; guint no_mipmaps : 1; -}; - -struct _MetaCompScreen -{ - MetaScreen *screen; ClutterActor *stage, *window_group, *top_window_group; ClutterActor *background_actor; @@ -50,13 +43,13 @@ struct _MetaCompScreen /* Wait 2ms after vblank before starting to draw next frame */ #define META_SYNC_DELAY 2 -void meta_switch_workspace_completed (MetaScreen *screen); +void meta_switch_workspace_completed (MetaCompositor *compositor); -gboolean meta_begin_modal_for_plugin (MetaScreen *screen, +gboolean meta_begin_modal_for_plugin (MetaCompositor *compositor, MetaPlugin *plugin, MetaModalOptions options, guint32 timestamp); -void meta_end_modal_for_plugin (MetaScreen *screen, +void meta_end_modal_for_plugin (MetaCompositor *compositor, MetaPlugin *plugin, guint32 timestamp); diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 897940dd6..22eec9e65 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -99,36 +99,34 @@ composite_at_least_version (MetaDisplay *display, int maj, int min) return (major > maj || (major == maj && minor >= min)); } -static void sync_actor_stacking (MetaCompScreen *info); +static void sync_actor_stacking (MetaCompositor *compositor); static void -meta_finish_workspace_switch (MetaCompScreen *info) +meta_finish_workspace_switch (MetaCompositor *compositor) { GList *l; /* Finish hiding and showing actors for the new workspace */ - for (l = info->windows; l; l = l->next) + for (l = compositor->windows; l; l = l->next) meta_window_actor_sync_visibility (l->data); /* Fix up stacking order. */ - sync_actor_stacking (info); + sync_actor_stacking (compositor); } void -meta_switch_workspace_completed (MetaScreen *screen) +meta_switch_workspace_completed (MetaCompositor *compositor) { - MetaCompScreen *info = meta_screen_get_compositor_data (screen); - /* FIXME -- must redo stacking order */ - info->switch_workspace_in_progress--; - if (info->switch_workspace_in_progress < 0) + compositor->switch_workspace_in_progress--; + if (compositor->switch_workspace_in_progress < 0) { g_warning ("Error in workspace_switch accounting!"); - info->switch_workspace_in_progress = 0; + compositor->switch_workspace_in_progress = 0; } - if (!info->switch_workspace_in_progress) - meta_finish_workspace_switch (info); + if (!compositor->switch_workspace_in_progress) + meta_finish_workspace_switch (compositor); } void @@ -147,17 +145,17 @@ process_damage (MetaCompositor *compositor, } static Window -get_output_window (MetaScreen *screen) +get_output_window (MetaCompositor *compositor) { - MetaDisplay *display = meta_screen_get_display (screen); - Display *xdisplay = meta_display_get_xdisplay (display); - Window output, xroot; + MetaDisplay *display = compositor->display; + Display *xdisplay = display->xdisplay; + Window output, xroot; XWindowAttributes attr; - long event_mask; + long event_mask; unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits }; - xroot = meta_screen_get_xroot (screen); + xroot = display->screen->xroot; output = XCompositeGetOverlayWindow (xdisplay, xroot); meta_core_add_old_event_mask (xdisplay, output, &mask); @@ -182,6 +180,13 @@ get_output_window (MetaScreen *screen) return output; } +/* compat helper */ +static MetaCompositor * +get_compositor_for_screen (MetaScreen *screen) +{ + return screen->display->compositor; +} + /** * meta_get_stage_for_screen: * @screen: a #MetaScreen @@ -191,12 +196,8 @@ get_output_window (MetaScreen *screen) ClutterActor * meta_get_stage_for_screen (MetaScreen *screen) { - MetaCompScreen *info = meta_screen_get_compositor_data (screen); - - if (!info) - return NULL; - - return info->stage; + MetaCompositor *compositor = get_compositor_for_screen (screen); + return compositor->stage; } /** @@ -208,12 +209,8 @@ meta_get_stage_for_screen (MetaScreen *screen) ClutterActor * meta_get_window_group_for_screen (MetaScreen *screen) { - MetaCompScreen *info = meta_screen_get_compositor_data (screen); - - if (!info) - return NULL; - - return info->window_group; + MetaCompositor *compositor = get_compositor_for_screen (screen); + return compositor->window_group; } /** @@ -225,12 +222,8 @@ meta_get_window_group_for_screen (MetaScreen *screen) ClutterActor * meta_get_top_window_group_for_screen (MetaScreen *screen) { - MetaCompScreen *info = meta_screen_get_compositor_data (screen); - - if (!info) - return NULL; - - return info->top_window_group; + MetaCompositor *compositor = get_compositor_for_screen (screen); + return compositor->top_window_group; } /** @@ -242,12 +235,8 @@ meta_get_top_window_group_for_screen (MetaScreen *screen) GList * meta_get_window_actors (MetaScreen *screen) { - MetaCompScreen *info = meta_screen_get_compositor_data (screen); - - if (!info) - return NULL; - - return info->windows; + MetaCompositor *compositor = get_compositor_for_screen (screen); + return compositor->windows; } void @@ -261,10 +250,10 @@ meta_set_stage_input_region (MetaScreen *screen, */ if (!meta_is_wayland_compositor ()) { - MetaCompScreen *info = meta_screen_get_compositor_data (screen); - MetaDisplay *display = meta_screen_get_display (screen); - Display *xdpy = meta_display_get_xdisplay (display); - Window xstage = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage)); + MetaDisplay *display = screen->display; + MetaCompositor *compositor = display->compositor; + Display *xdpy = meta_display_get_xdisplay (display); + Window xstage = clutter_x11_get_stage_window (CLUTTER_STAGE (compositor->stage)); XFixesSetWindowShapeRegion (xdpy, xstage, ShapeInput, 0, 0, region); @@ -273,7 +262,7 @@ meta_set_stage_input_region (MetaScreen *screen, * it's not the user doing something, it's the environment changing under the user. */ meta_display_add_ignored_crossing_serial (display, XNextRequest (xdpy)); - XFixesSetWindowShapeRegion (xdpy, info->output, ShapeInput, 0, 0, region); + XFixesSetWindowShapeRegion (xdpy, compositor->output, ShapeInput, 0, 0, region); } } @@ -338,15 +327,14 @@ meta_stage_is_focused (MetaScreen *screen) } static gboolean -begin_modal_x11 (MetaScreen *screen, +begin_modal_x11 (MetaCompositor *compositor, MetaPlugin *plugin, MetaModalOptions options, guint32 timestamp) { - MetaDisplay *display = meta_screen_get_display (screen); + MetaDisplay *display = compositor->display; Display *xdpy = meta_display_get_xdisplay (display); - MetaCompScreen *info = meta_screen_get_compositor_data (screen); - Window grab_window = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage)); + Window grab_window = clutter_x11_get_stage_window (CLUTTER_STAGE (compositor->stage)); int result; gboolean pointer_grabbed = FALSE; gboolean keyboard_grabbed = FALSE; @@ -411,7 +399,7 @@ begin_modal_x11 (MetaScreen *screen, } gboolean -meta_begin_modal_for_plugin (MetaScreen *screen, +meta_begin_modal_for_plugin (MetaCompositor *compositor, MetaPlugin *plugin, MetaModalOptions options, guint32 timestamp) @@ -420,13 +408,13 @@ meta_begin_modal_for_plugin (MetaScreen *screen, * are significant differences in how we handle grabs that make it difficult to * merge the two. */ - MetaDisplay *display = meta_screen_get_display (screen); + MetaDisplay *display = compositor->display; if (is_modal (display) || display->grab_op != META_GRAB_OP_NONE) return FALSE; if (!meta_is_wayland_compositor ()) - if (!begin_modal_x11 (screen, plugin, options, timestamp)) + if (!begin_modal_x11 (compositor, plugin, options, timestamp)) return FALSE; display->grab_op = META_GRAB_OP_COMPOSITOR; @@ -441,11 +429,11 @@ meta_begin_modal_for_plugin (MetaScreen *screen, } void -meta_end_modal_for_plugin (MetaScreen *screen, +meta_end_modal_for_plugin (MetaCompositor *compositor, MetaPlugin *plugin, guint32 timestamp) { - MetaDisplay *display = meta_screen_get_display (screen); + MetaDisplay *display = compositor->display; Display *xdpy = meta_display_get_xdisplay (display); g_return_if_fail (is_modal (display)); @@ -470,10 +458,10 @@ static void after_stage_paint (ClutterStage *stage, gpointer data) { - MetaCompScreen *info = (MetaCompScreen*) data; + MetaCompositor *compositor = data; GList *l; - for (l = info->windows; l; l = l->next) + for (l = compositor->windows; l; l = l->next) meta_window_actor_post_paint (l->data); if (meta_is_wayland_compositor ()) @@ -481,8 +469,7 @@ after_stage_paint (ClutterStage *stage, } static void -redirect_windows (MetaCompositor *compositor, - MetaScreen *screen) +redirect_windows (MetaScreen *screen) { MetaDisplay *display = meta_screen_get_display (screen); Display *xdisplay = meta_display_get_xdisplay (display); @@ -525,48 +512,35 @@ redirect_windows (MetaCompositor *compositor, } void -meta_compositor_manage_screen (MetaCompositor *compositor, - MetaScreen *screen) +meta_compositor_manage (MetaCompositor *compositor) { - MetaCompScreen *info; - MetaDisplay *display = meta_screen_get_display (screen); - Display *xdisplay = meta_display_get_xdisplay (display); - Window xwin = None; - gint width, height; + MetaDisplay *display = compositor->display; + Display *xdisplay = display->xdisplay; + MetaScreen *screen = display->screen; + Window xwin; + gint width, height; MetaWaylandCompositor *wayland_compositor; - /* Check if the screen is already managed */ - if (meta_screen_get_compositor_data (screen)) - return; - - info = g_new0 (MetaCompScreen, 1); - info->screen = screen; - - meta_screen_set_compositor_data (screen, info); - - info->output = None; - info->windows = NULL; - - meta_screen_set_cm_selection (screen); + meta_screen_set_cm_selection (display->screen); /* We will have already created a stage if running as a wayland * compositor... */ if (meta_is_wayland_compositor ()) { wayland_compositor = meta_wayland_compositor_get_default (); - info->stage = wayland_compositor->stage; + compositor->stage = wayland_compositor->stage; meta_screen_get_size (screen, &width, &height); - clutter_actor_set_size (info->stage, width, height); + clutter_actor_set_size (compositor->stage, width, height); } else { - info->stage = clutter_stage_new (); + compositor->stage = clutter_stage_new (); meta_screen_get_size (screen, &width, &height); - clutter_actor_realize (info->stage); + clutter_actor_realize (compositor->stage); - xwin = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage)); + xwin = clutter_x11_get_stage_window (CLUTTER_STAGE (compositor->stage)); XResizeWindow (xdisplay, xwin, width, height); @@ -600,30 +574,30 @@ meta_compositor_manage_screen (MetaCompositor *compositor, } } - clutter_stage_set_paint_callback (CLUTTER_STAGE (info->stage), + clutter_stage_set_paint_callback (CLUTTER_STAGE (compositor->stage), after_stage_paint, - info, + compositor, NULL); - clutter_stage_set_sync_delay (CLUTTER_STAGE (info->stage), META_SYNC_DELAY); + clutter_stage_set_sync_delay (CLUTTER_STAGE (compositor->stage), META_SYNC_DELAY); - info->window_group = meta_window_group_new (screen); - info->top_window_group = meta_window_group_new (screen); + compositor->window_group = meta_window_group_new (screen); + compositor->top_window_group = meta_window_group_new (screen); - clutter_actor_add_child (info->stage, info->window_group); - clutter_actor_add_child (info->stage, info->top_window_group); + clutter_actor_add_child (compositor->stage, compositor->window_group); + clutter_actor_add_child (compositor->stage, compositor->top_window_group); if (meta_is_wayland_compositor ()) { /* NB: When running as a wayland compositor we don't need an X * composite overlay window, and we don't need to play any input * region tricks to redirect events into clutter. */ - info->output = None; + compositor->output = None; } else { - info->output = get_output_window (screen); - XReparentWindow (xdisplay, xwin, info->output, 0, 0); + compositor->output = get_output_window (compositor); + XReparentWindow (xdisplay, xwin, compositor->output, 0, 0); meta_empty_stage_input_region (screen); @@ -635,28 +609,27 @@ meta_compositor_manage_screen (MetaCompositor *compositor, * because the X server will destroy the overlay window * when the last client using it exits. */ - XFixesSetWindowShapeRegion (xdisplay, info->output, ShapeBounding, 0, 0, None); + XFixesSetWindowShapeRegion (xdisplay, compositor->output, ShapeBounding, 0, 0, None); /* Map overlay window before redirecting windows offscreen so we catch their * contents until we show the stage. */ - XMapWindow (xdisplay, info->output); + XMapWindow (xdisplay, compositor->output); } - redirect_windows (compositor, screen); + redirect_windows (display->screen); - info->plugin_mgr = meta_plugin_manager_new (screen); + compositor->plugin_mgr = meta_plugin_manager_new (compositor); } void -meta_compositor_unmanage_screen (MetaCompositor *compositor, - MetaScreen *screen) +meta_compositor_unmanage (MetaCompositor *compositor) { if (!meta_is_wayland_compositor ()) { - MetaDisplay *display = meta_screen_get_display (screen); - Display *xdisplay = meta_display_get_xdisplay (display); - Window xroot = meta_screen_get_xroot (screen); + MetaDisplay *display = compositor->display; + Display *xdisplay = meta_display_get_xdisplay (display); + Window xroot = display->screen->xroot; /* This is the most important part of cleanup - we have to do this * before giving up the window manager selection or the next @@ -667,7 +640,7 @@ meta_compositor_unmanage_screen (MetaCompositor *compositor, /** * meta_shape_cow_for_window: - * @screen: A #MetaScreen + * @compositor: A #MetaCompositor * @window: (allow-none): A #MetaWindow to shape the COW for * * Sets an bounding shape on the COW so that the given window @@ -677,14 +650,14 @@ meta_compositor_unmanage_screen (MetaCompositor *compositor, * of the COW, letting the raw window be seen through below. */ static void -meta_shape_cow_for_window (MetaScreen *screen, +meta_shape_cow_for_window (MetaCompositor *compositor, MetaWindow *window) { - MetaCompScreen *info = meta_screen_get_compositor_data (screen); - Display *xdisplay = meta_display_get_xdisplay (meta_screen_get_display (screen)); + MetaDisplay *display = compositor->display; + Display *xdisplay = meta_display_get_xdisplay (display); if (window == NULL) - XFixesSetWindowShapeRegion (xdisplay, info->output, ShapeBounding, 0, 0, None); + XFixesSetWindowShapeRegion (xdisplay, compositor->output, ShapeBounding, 0, 0, None); else { XserverRegion output_region; @@ -699,7 +672,7 @@ meta_shape_cow_for_window (MetaScreen *screen, window_bounds.width = rect.width; window_bounds.height = rect.height; - meta_screen_get_size (screen, &width, &height); + meta_screen_get_size (display->screen, &width, &height); screen_rect.x = 0; screen_rect.y = 0; screen_rect.width = width; @@ -708,47 +681,45 @@ meta_shape_cow_for_window (MetaScreen *screen, output_region = XFixesCreateRegion (xdisplay, &window_bounds, 1); XFixesInvertRegion (xdisplay, output_region, &screen_rect, output_region); - XFixesSetWindowShapeRegion (xdisplay, info->output, ShapeBounding, 0, 0, output_region); + XFixesSetWindowShapeRegion (xdisplay, compositor->output, ShapeBounding, 0, 0, output_region); XFixesDestroyRegion (xdisplay, output_region); } } static void -set_unredirected_window (MetaCompScreen *info, +set_unredirected_window (MetaCompositor *compositor, MetaWindow *window) { - if (info->unredirected_window == window) + if (compositor->unredirected_window == window) return; - if (info->unredirected_window != NULL) + if (compositor->unredirected_window != NULL) { - MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (info->unredirected_window)); + MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (compositor->unredirected_window)); meta_window_actor_set_unredirected (window_actor, FALSE); } - info->unredirected_window = window; + compositor->unredirected_window = window; - if (info->unredirected_window != NULL) + if (compositor->unredirected_window != NULL) { - MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (info->unredirected_window)); + MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (compositor->unredirected_window)); meta_window_actor_set_unredirected (window_actor, TRUE); } - meta_shape_cow_for_window (info->screen, info->unredirected_window); + meta_shape_cow_for_window (compositor, compositor->unredirected_window); } void meta_compositor_add_window (MetaCompositor *compositor, MetaWindow *window) { - MetaScreen *screen = meta_window_get_screen (window); - MetaDisplay *display = meta_screen_get_display (screen); - MetaCompScreen *info = meta_screen_get_compositor_data (screen); + MetaDisplay *display = compositor->display; meta_error_trap_push (display); meta_window_actor_new (window); - sync_actor_stacking (info); + sync_actor_stacking (compositor); meta_error_trap_pop (display); } @@ -758,11 +729,9 @@ meta_compositor_remove_window (MetaCompositor *compositor, MetaWindow *window) { MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - MetaScreen *screen = meta_window_get_screen (window); - MetaCompScreen *info = meta_screen_get_compositor_data (screen); - if (info->unredirected_window == window) - set_unredirected_window (info, NULL); + if (compositor->unredirected_window == window) + set_unredirected_window (compositor, NULL); meta_window_actor_destroy (window_actor); } @@ -879,11 +848,11 @@ event_is_passive_button_grab (MetaDisplay *display, * these events by pretending we got an event on the stage window. */ static void -maybe_spoof_event_as_stage_event (MetaCompScreen *info, +maybe_spoof_event_as_stage_event (MetaCompositor *compositor, MetaWindow *window, XEvent *event) { - MetaDisplay *display = meta_screen_get_display (info->screen); + MetaDisplay *display = compositor->display; if (event->type == GenericEvent && event->xcookie.extension == display->xinput_opcode) @@ -907,10 +876,10 @@ maybe_spoof_event_as_stage_event (MetaCompScreen *info, case XI_KeyRelease: /* If this is a GTK+ widget, like a window menu, let GTK+ handle * it as-is without mangling. */ - if (meta_ui_window_is_widget (info->screen->ui, device_event->event)) + if (meta_ui_window_is_widget (display->screen->ui, device_event->event)) break; - device_event->event = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage)); + device_event->event = clutter_x11_get_stage_window (CLUTTER_STAGE (compositor->stage)); device_event->event_x = device_event->root_x; device_event->event_y = device_event->root_y; break; @@ -933,11 +902,10 @@ meta_compositor_process_event (MetaCompositor *compositor, MetaWindow *window) { MetaDisplay *display = compositor->display; - MetaCompScreen *info = meta_screen_get_compositor_data (display->screen); - if (is_modal (display) && is_grabbed_event (compositor->display, event)) + if (is_modal (display) && is_grabbed_event (display, event)) { - meta_plugin_manager_xevent_filter (info->plugin_mgr, event); + meta_plugin_manager_xevent_filter (compositor->plugin_mgr, event); /* We always consume events even if the plugin says it didn't handle them; * exclusive is exclusive */ @@ -945,9 +913,9 @@ meta_compositor_process_event (MetaCompositor *compositor, } if (!meta_is_wayland_compositor ()) - maybe_spoof_event_as_stage_event (info, window, event); + maybe_spoof_event_as_stage_event (compositor, window, event); - if (meta_plugin_manager_xevent_filter (info->plugin_mgr, event)) + if (meta_plugin_manager_xevent_filter (compositor->plugin_mgr, event)) return TRUE; if (!meta_is_wayland_compositor () && @@ -979,11 +947,9 @@ meta_compositor_process_event (MetaCompositor *compositor, gboolean meta_compositor_filter_keybinding (MetaCompositor *compositor, - MetaScreen *screen, MetaKeyBinding *binding) { - MetaCompScreen *info = meta_screen_get_compositor_data (screen); - return meta_plugin_manager_filter_keybinding (info->plugin_mgr, binding); + return meta_plugin_manager_filter_keybinding (compositor->plugin_mgr, binding); } void @@ -1026,40 +992,35 @@ meta_compositor_unmaximize_window (MetaCompositor *compositor, void meta_compositor_switch_workspace (MetaCompositor *compositor, - MetaScreen *screen, MetaWorkspace *from, MetaWorkspace *to, MetaMotionDirection direction) { - MetaCompScreen *info; - gint to_indx, from_indx; + gint to_indx, from_indx; - info = meta_screen_get_compositor_data (screen); to_indx = meta_workspace_index (to); from_indx = meta_workspace_index (from); - if (!info) /* During startup before manage_screen() */ - return; + compositor->switch_workspace_in_progress++; - info->switch_workspace_in_progress++; - - if (!meta_plugin_manager_switch_workspace (info->plugin_mgr, - from_indx, to_indx, + if (!meta_plugin_manager_switch_workspace (compositor->plugin_mgr, + from_indx, + to_indx, direction)) { - info->switch_workspace_in_progress--; + compositor->switch_workspace_in_progress--; /* We have to explicitely call this to fix up stacking order of the * actors; this is because the abs stacking position of actors does not * necessarily change during the window hiding/unhiding, only their * relative position toward the destkop window. */ - meta_finish_workspace_switch (info); + meta_finish_workspace_switch (compositor); } } static void -sync_actor_stacking (MetaCompScreen *info) +sync_actor_stacking (MetaCompositor *compositor) { GList *children; GList *expected_window_node; @@ -1075,7 +1036,7 @@ sync_actor_stacking (MetaCompScreen *info) * little effort to make sure we actually need to restack before * we go ahead and do it */ - children = clutter_actor_get_children (info->window_group); + children = clutter_actor_get_children (compositor->window_group); has_windows = FALSE; reordered = FALSE; @@ -1087,7 +1048,7 @@ sync_actor_stacking (MetaCompScreen *info) /* First we collect a list of all backgrounds, and check if they're at the * bottom. Then we check if the window actors are in the correct sequence */ backgrounds = NULL; - expected_window_node = info->windows; + expected_window_node = compositor->windows; for (old = children; old != NULL; old = old->next) { ClutterActor *actor = old->data; @@ -1125,7 +1086,7 @@ sync_actor_stacking (MetaCompScreen *info) * We reorder the actors even if they're not parented to the window group, * to allow stacking to work with intermediate actors (eg during effects) */ - for (tmp = g_list_last (info->windows); tmp != NULL; tmp = tmp->prev) + for (tmp = g_list_last (compositor->windows); tmp != NULL; tmp = tmp->prev) { ClutterActor *actor = tmp->data, *parent; @@ -1148,11 +1109,9 @@ sync_actor_stacking (MetaCompScreen *info) void meta_compositor_sync_stack (MetaCompositor *compositor, - MetaScreen *screen, GList *stack) { GList *old_stack; - MetaCompScreen *info = meta_screen_get_compositor_data (screen); /* This is painful because hidden windows that we are in the process * of animating out of existence. They'll be at the bottom of the @@ -1162,8 +1121,8 @@ meta_compositor_sync_stack (MetaCompositor *compositor, /* Sources: first window is the highest */ stack = g_list_copy (stack); /* The new stack of MetaWindow */ - old_stack = g_list_reverse (info->windows); /* The old stack of MetaWindowActor */ - info->windows = NULL; + old_stack = g_list_reverse (compositor->windows); /* The old stack of MetaWindowActor */ + compositor->windows = NULL; while (TRUE) { @@ -1227,13 +1186,13 @@ meta_compositor_sync_stack (MetaCompositor *compositor, * be at the front of at least one, hopefully it will be * near the front of the other.) */ - info->windows = g_list_prepend (info->windows, actor); + compositor->windows = g_list_prepend (compositor->windows, actor); stack = g_list_remove (stack, window); old_stack = g_list_remove (old_stack, actor); } - sync_actor_stacking (info); + sync_actor_stacking (compositor); } void @@ -1247,12 +1206,10 @@ meta_compositor_sync_window_geometry (MetaCompositor *compositor, void meta_compositor_sync_screen_size (MetaCompositor *compositor, - MetaScreen *screen, guint width, guint height) { - MetaDisplay *display = meta_screen_get_display (screen); - MetaCompScreen *info = meta_screen_get_compositor_data (screen); + MetaDisplay *display = compositor->display; if (meta_is_wayland_compositor ()) { @@ -1266,23 +1223,21 @@ meta_compositor_sync_screen_size (MetaCompositor *compositor, show the right portions on the right screens. */ - clutter_actor_set_size (info->stage, width, height); + clutter_actor_set_size (compositor->stage, width, height); } else { Display *xdisplay; Window xwin; - g_return_if_fail (info); - xdisplay = meta_display_get_xdisplay (display); - xwin = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage)); + xwin = clutter_x11_get_stage_window (CLUTTER_STAGE (compositor->stage)); XResizeWindow (xdisplay, xwin, width, height); } meta_verbose ("Changed size for stage on screen %d to %dx%d\n", - meta_screen_get_screen_number (screen), + meta_screen_get_screen_number (display->screen), width, height); } @@ -1292,7 +1247,7 @@ frame_callback (CoglOnscreen *onscreen, CoglFrameInfo *frame_info, void *user_data) { - MetaCompScreen *info = user_data; + MetaCompositor *compositor = user_data; GList *l; if (event == COGL_FRAME_EVENT_COMPLETE) @@ -1323,38 +1278,38 @@ frame_callback (CoglOnscreen *onscreen, presentation_time = 0; } - for (l = info->windows; l; l = l->next) + for (l = compositor->windows; l; l = l->next) meta_window_actor_frame_complete (l->data, frame_info, presentation_time); } } static void -pre_paint_windows (MetaCompScreen *info) +pre_paint_windows (MetaCompositor *compositor) { GList *l; MetaWindowActor *top_window; - if (info->onscreen == NULL) + if (compositor->onscreen == NULL) { - info->onscreen = COGL_ONSCREEN (cogl_get_draw_framebuffer ()); - info->frame_closure = cogl_onscreen_add_frame_callback (info->onscreen, - frame_callback, - info, - NULL); + compositor->onscreen = COGL_ONSCREEN (cogl_get_draw_framebuffer ()); + compositor->frame_closure = cogl_onscreen_add_frame_callback (compositor->onscreen, + frame_callback, + compositor, + NULL); } - if (info->windows == NULL) + if (compositor->windows == NULL) return; - top_window = g_list_last (info->windows)->data; + top_window = g_list_last (compositor->windows)->data; if (meta_window_actor_should_unredirect (top_window) && - info->disable_unredirect_count == 0) - set_unredirected_window (info, meta_window_actor_get_meta_window (top_window)); + compositor->disable_unredirect_count == 0) + set_unredirected_window (compositor, meta_window_actor_get_meta_window (top_window)); else - set_unredirected_window (info, NULL); + set_unredirected_window (compositor, NULL); - for (l = info->windows; l; l = l->next) + for (l = compositor->windows; l; l = l->next) meta_window_actor_pre_paint (l->data); } @@ -1362,9 +1317,7 @@ static gboolean meta_repaint_func (gpointer data) { MetaCompositor *compositor = data; - MetaCompScreen *info = meta_screen_get_compositor_data (compositor->display->screen); - pre_paint_windows (info); - + pre_paint_windows (compositor); return TRUE; } @@ -1372,10 +1325,9 @@ static void on_shadow_factory_changed (MetaShadowFactory *factory, MetaCompositor *compositor) { - MetaCompScreen *info = meta_screen_get_compositor_data (compositor->display->screen); GList *l; - for (l = info->windows; l; l = l->next) + for (l = compositor->windows; l; l = l->next) meta_window_actor_invalidate_shadow (l->data); } @@ -1419,9 +1371,8 @@ meta_compositor_new (MetaDisplay *display) Window meta_get_overlay_window (MetaScreen *screen) { - MetaCompScreen *info = meta_screen_get_compositor_data (screen); - - return info->output; + MetaCompositor *compositor = get_compositor_for_screen (screen); + return compositor->output; } /** @@ -1435,9 +1386,8 @@ meta_get_overlay_window (MetaScreen *screen) void meta_disable_unredirect_for_screen (MetaScreen *screen) { - MetaCompScreen *info = meta_screen_get_compositor_data (screen); - if (info != NULL) - info->disable_unredirect_count = info->disable_unredirect_count + 1; + MetaCompositor *compositor = get_compositor_for_screen (screen); + compositor->disable_unredirect_count++; } /** @@ -1450,11 +1400,11 @@ meta_disable_unredirect_for_screen (MetaScreen *screen) void meta_enable_unredirect_for_screen (MetaScreen *screen) { - MetaCompScreen *info = meta_screen_get_compositor_data (screen); - if (info != NULL && info->disable_unredirect_count == 0) + MetaCompositor *compositor = get_compositor_for_screen (screen); + if (compositor->disable_unredirect_count == 0) g_warning ("Called enable_unredirect_for_screen while unredirection is enabled."); - if (info != NULL && info->disable_unredirect_count > 0) - info->disable_unredirect_count = info->disable_unredirect_count - 1; + if (compositor->disable_unredirect_count > 0) + compositor->disable_unredirect_count--; } #define FLASH_TIME_MS 50 @@ -1551,20 +1501,16 @@ meta_compositor_monotonic_time_to_server_time (MetaDisplay *display, void meta_compositor_show_tile_preview (MetaCompositor *compositor, - MetaScreen *screen, MetaWindow *window, MetaRectangle *tile_rect, int tile_monitor_number) { - MetaCompScreen *info = meta_screen_get_compositor_data (screen); - meta_plugin_manager_show_tile_preview (info->plugin_mgr, + meta_plugin_manager_show_tile_preview (compositor->plugin_mgr, window, tile_rect, tile_monitor_number); } void -meta_compositor_hide_tile_preview (MetaCompositor *compositor, - MetaScreen *screen) +meta_compositor_hide_tile_preview (MetaCompositor *compositor) { - MetaCompScreen *info = meta_screen_get_compositor_data (screen); - meta_plugin_manager_hide_tile_preview (info->plugin_mgr); + meta_plugin_manager_hide_tile_preview (compositor->plugin_mgr); } diff --git a/src/compositor/meta-plugin-manager.c b/src/compositor/meta-plugin-manager.c index 29bac00e5..8987e219d 100644 --- a/src/compositor/meta-plugin-manager.c +++ b/src/compositor/meta-plugin-manager.c @@ -37,7 +37,7 @@ static GType plugin_type = G_TYPE_NONE; struct MetaPluginManager { - MetaScreen *screen; + MetaCompositor *compositor; MetaPlugin *plugin; }; @@ -91,7 +91,7 @@ on_confirm_display_change (MetaMonitorManager *monitors, } MetaPluginManager * -meta_plugin_manager_new (MetaScreen *screen) +meta_plugin_manager_new (MetaCompositor *compositor) { MetaPluginManager *plugin_mgr; MetaPluginClass *klass; @@ -99,10 +99,10 @@ meta_plugin_manager_new (MetaScreen *screen) MetaMonitorManager *monitors; plugin_mgr = g_new0 (MetaPluginManager, 1); - plugin_mgr->screen = screen; + plugin_mgr->compositor = compositor; plugin_mgr->plugin = plugin = g_object_new (plugin_type, NULL); - _meta_plugin_set_screen (plugin, screen); + _meta_plugin_set_compositor (plugin, compositor); klass = META_PLUGIN_GET_CLASS (plugin); @@ -153,7 +153,7 @@ meta_plugin_manager_event_simple (MetaPluginManager *plugin_mgr, { MetaPlugin *plugin = plugin_mgr->plugin; MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin); - MetaDisplay *display = meta_screen_get_display (plugin_mgr->screen); + MetaDisplay *display = plugin_mgr->compositor->display; gboolean retval = FALSE; if (display->display_opening) @@ -213,7 +213,7 @@ meta_plugin_manager_event_maximize (MetaPluginManager *plugin_mgr, { MetaPlugin *plugin = plugin_mgr->plugin; MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin); - MetaDisplay *display = meta_screen_get_display (plugin_mgr->screen); + MetaDisplay *display = plugin_mgr->compositor->display; gboolean retval = FALSE; if (display->display_opening) @@ -266,7 +266,7 @@ meta_plugin_manager_switch_workspace (MetaPluginManager *plugin_mgr, { MetaPlugin *plugin = plugin_mgr->plugin; MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin); - MetaDisplay *display = meta_screen_get_display (plugin_mgr->screen); + MetaDisplay *display = plugin_mgr->compositor->display; gboolean retval = FALSE; if (display->display_opening) @@ -324,7 +324,7 @@ meta_plugin_manager_show_tile_preview (MetaPluginManager *plugin_mgr, { MetaPlugin *plugin = plugin_mgr->plugin; MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin); - MetaDisplay *display = meta_screen_get_display (plugin_mgr->screen); + MetaDisplay *display = plugin_mgr->compositor->display; if (display->display_opening) return FALSE; @@ -343,7 +343,7 @@ meta_plugin_manager_hide_tile_preview (MetaPluginManager *plugin_mgr) { MetaPlugin *plugin = plugin_mgr->plugin; MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin); - MetaDisplay *display = meta_screen_get_display (plugin_mgr->screen); + MetaDisplay *display = plugin_mgr->compositor->display; if (display->display_opening) return FALSE; diff --git a/src/compositor/meta-plugin-manager.h b/src/compositor/meta-plugin-manager.h index efc4deb52..d814ee677 100644 --- a/src/compositor/meta-plugin-manager.h +++ b/src/compositor/meta-plugin-manager.h @@ -44,7 +44,7 @@ */ typedef struct MetaPluginManager MetaPluginManager; -MetaPluginManager * meta_plugin_manager_new (MetaScreen *screen); +MetaPluginManager * meta_plugin_manager_new (MetaCompositor *compositor); void meta_plugin_manager_load (const gchar *plugin_name); diff --git a/src/compositor/meta-plugin.c b/src/compositor/meta-plugin.c index 61d99d0f8..f9f6b3df0 100644 --- a/src/compositor/meta-plugin.c +++ b/src/compositor/meta-plugin.c @@ -49,7 +49,7 @@ G_DEFINE_ABSTRACT_TYPE (MetaPlugin, meta_plugin, G_TYPE_OBJECT); struct _MetaPluginPrivate { - MetaScreen *screen; + MetaCompositor *compositor; }; static void @@ -101,9 +101,8 @@ void meta_plugin_switch_workspace_completed (MetaPlugin *plugin) { MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv; - MetaScreen *screen = priv->screen; - meta_switch_workspace_completed (screen); + meta_switch_workspace_completed (priv->compositor); } static void @@ -177,7 +176,7 @@ meta_plugin_begin_modal (MetaPlugin *plugin, { MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv; - return meta_begin_modal_for_plugin (priv->screen, plugin, + return meta_begin_modal_for_plugin (priv->compositor, plugin, options, timestamp); } @@ -198,7 +197,7 @@ meta_plugin_end_modal (MetaPlugin *plugin, { MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv; - meta_end_modal_for_plugin (priv->screen, plugin, timestamp); + meta_end_modal_for_plugin (priv->compositor, plugin, timestamp); } /** @@ -214,16 +213,15 @@ meta_plugin_get_screen (MetaPlugin *plugin) { MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv; - return priv->screen; + return priv->compositor->display->screen; } void -_meta_plugin_set_screen (MetaPlugin *plugin, - MetaScreen *screen) +_meta_plugin_set_compositor (MetaPlugin *plugin, MetaCompositor *compositor) { MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv; - priv->screen = screen; + priv->compositor = compositor; } void diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 7356d7da8..2054771eb 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -37,8 +37,8 @@ struct _MetaWindowActorPrivate { - MetaWindow *window; - MetaScreen *screen; + MetaWindow *window; + MetaCompositor *compositor; MetaSurfaceActor *surface; @@ -371,11 +371,11 @@ meta_window_actor_update_surface (MetaWindowActor *self) static void meta_window_actor_constructed (GObject *object) { - MetaWindowActor *self = META_WINDOW_ACTOR (object); - MetaWindowActorPrivate *priv = self->priv; - MetaWindow *window = priv->window; + MetaWindowActor *self = META_WINDOW_ACTOR (object); + MetaWindowActorPrivate *priv = self->priv; + MetaWindow *window = priv->window; - priv->screen = window->screen; + priv->compositor = window->display->compositor; meta_window_actor_update_surface (self); @@ -389,19 +389,15 @@ meta_window_actor_constructed (GObject *object) static void meta_window_actor_dispose (GObject *object) { - MetaWindowActor *self = META_WINDOW_ACTOR (object); + MetaWindowActor *self = META_WINDOW_ACTOR (object); MetaWindowActorPrivate *priv = self->priv; - MetaScreen *screen; - MetaCompScreen *info; + MetaCompositor *compositor = priv->compositor; if (priv->disposed) return; priv->disposed = TRUE; - screen = priv->screen; - info = meta_screen_get_compositor_data (screen); - if (priv->send_frame_messages_timer != 0) { g_source_remove (priv->send_frame_messages_timer); @@ -416,7 +412,7 @@ meta_window_actor_dispose (GObject *object) g_clear_pointer (&priv->unfocused_shadow, meta_shadow_unref); g_clear_pointer (&priv->shadow_shape, meta_window_shape_unref); - info->windows = g_list_remove (info->windows, (gconstpointer) self); + compositor->windows = g_list_remove (compositor->windows, (gconstpointer) self); g_clear_object (&priv->window); @@ -851,8 +847,7 @@ static void queue_send_frame_messages_timeout (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; - MetaScreen *screen = priv->screen; - MetaDisplay *display = meta_screen_get_display (screen); + MetaDisplay *display = meta_window_get_display (priv->window); gint64 current_time = meta_compositor_monotonic_time_to_server_time (display, g_get_monotonic_time ()); MetaMonitorManager *monitor_manager = meta_monitor_manager_get (); MetaWindow *window = priv->window; @@ -964,7 +959,7 @@ start_simple_effect (MetaWindowActor *self, gulong event) { MetaWindowActorPrivate *priv = self->priv; - MetaCompScreen *info = meta_screen_get_compositor_data (priv->screen); + MetaCompositor *compositor = priv->compositor; gint *counter = NULL; gboolean use_freeze_thaw = FALSE; @@ -995,9 +990,7 @@ start_simple_effect (MetaWindowActor *self, (*counter)++; - if (!meta_plugin_manager_event_simple (info->plugin_mgr, - self, - event)) + if (!meta_plugin_manager_event_simple (compositor->plugin_mgr, self, event)) { (*counter)--; if (use_freeze_thaw) @@ -1118,15 +1111,11 @@ meta_window_actor_set_unredirected (MetaWindowActor *self, void meta_window_actor_destroy (MetaWindowActor *self) { - MetaWindow *window; - MetaCompScreen *info; - MetaWindowActorPrivate *priv; - MetaWindowType window_type; + MetaWindowActorPrivate *priv = self->priv; + MetaWindow *window = priv->window; + MetaCompositor *compositor = priv->compositor; + MetaWindowType window_type = meta_window_get_window_type (window); - priv = self->priv; - - window = priv->window; - window_type = meta_window_get_window_type (window); meta_window_set_compositor_private (window, NULL); if (priv->send_frame_messages_timer != 0) @@ -1139,8 +1128,7 @@ meta_window_actor_destroy (MetaWindowActor *self) * We remove the window from internal lookup hashes and thus any other * unmap events etc fail */ - info = meta_screen_get_compositor_data (priv->screen); - info->windows = g_list_remove (info->windows, (gconstpointer) self); + compositor->windows = g_list_remove (compositor->windows, (gconstpointer) self); if (window_type == META_WINDOW_DROPDOWN_MENU || window_type == META_WINDOW_POPUP_MENU || @@ -1201,18 +1189,14 @@ void meta_window_actor_show (MetaWindowActor *self, MetaCompEffect effect) { - MetaWindowActorPrivate *priv; - MetaCompScreen *info; - gulong event; - - priv = self->priv; - info = meta_screen_get_compositor_data (priv->screen); + MetaWindowActorPrivate *priv = self->priv; + MetaCompositor *compositor = priv->compositor; + gulong event = 0; g_return_if_fail (!priv->visible); self->priv->visible = TRUE; - event = 0; switch (effect) { case META_COMP_EFFECT_CREATE: @@ -1229,7 +1213,7 @@ meta_window_actor_show (MetaWindowActor *self, g_assert_not_reached(); } - if (info->switch_workspace_in_progress || + if (compositor->switch_workspace_in_progress || event == 0 || !start_simple_effect (self, event)) { @@ -1241,12 +1225,9 @@ void meta_window_actor_hide (MetaWindowActor *self, MetaCompEffect effect) { - MetaWindowActorPrivate *priv; - MetaCompScreen *info; - gulong event; - - priv = self->priv; - info = meta_screen_get_compositor_data (priv->screen); + MetaWindowActorPrivate *priv = self->priv; + MetaCompositor *compositor = priv->compositor; + gulong event = 0; g_return_if_fail (priv->visible); @@ -1256,10 +1237,9 @@ meta_window_actor_hide (MetaWindowActor *self, * hold off on hiding the window, and do it after the workspace * switch completes */ - if (info->switch_workspace_in_progress) + if (compositor->switch_workspace_in_progress) return; - event = 0; switch (effect) { case META_COMP_EFFECT_DESTROY: @@ -1285,7 +1265,8 @@ meta_window_actor_maximize (MetaWindowActor *self, MetaRectangle *old_rect, MetaRectangle *new_rect) { - MetaCompScreen *info = meta_screen_get_compositor_data (self->priv->screen); + MetaWindowActorPrivate *priv = self->priv; + MetaCompositor *compositor = priv->compositor; /* The window has already been resized (in order to compute new_rect), * which by side effect caused the actor to be resized. Restore it to the @@ -1296,7 +1277,7 @@ meta_window_actor_maximize (MetaWindowActor *self, self->priv->maximize_in_progress++; meta_window_actor_freeze (self); - if (!meta_plugin_manager_event_maximize (info->plugin_mgr, + if (!meta_plugin_manager_event_maximize (compositor->plugin_mgr, self, META_PLUGIN_MAXIMIZE, new_rect->x, new_rect->y, @@ -1313,7 +1294,8 @@ meta_window_actor_unmaximize (MetaWindowActor *self, MetaRectangle *old_rect, MetaRectangle *new_rect) { - MetaCompScreen *info = meta_screen_get_compositor_data (self->priv->screen); + MetaWindowActorPrivate *priv = self->priv; + MetaCompositor *compositor = priv->compositor; /* The window has already been resized (in order to compute new_rect), * which by side effect caused the actor to be resized. Restore it to the @@ -1324,7 +1306,7 @@ meta_window_actor_unmaximize (MetaWindowActor *self, self->priv->unmaximize_in_progress++; meta_window_actor_freeze (self); - if (!meta_plugin_manager_event_maximize (info->plugin_mgr, + if (!meta_plugin_manager_event_maximize (compositor->plugin_mgr, self, META_PLUGIN_UNMAXIMIZE, new_rect->x, new_rect->y, @@ -1338,8 +1320,8 @@ meta_window_actor_unmaximize (MetaWindowActor *self, MetaWindowActor * meta_window_actor_new (MetaWindow *window) { - MetaScreen *screen = meta_window_get_screen (window); - MetaCompScreen *info = meta_screen_get_compositor_data (screen); + MetaDisplay *display = meta_window_get_display (window); + MetaCompositor *compositor = display->compositor; MetaWindowActor *self; MetaWindowActorPrivate *priv; ClutterActor *window_group; @@ -1364,9 +1346,9 @@ meta_window_actor_new (MetaWindow *window) meta_window_set_compositor_private (window, G_OBJECT (self)); if (window->layer == META_LAYER_OVERRIDE_REDIRECT) - window_group = info->top_window_group; + window_group = compositor->top_window_group; else - window_group = info->window_group; + window_group = compositor->window_group; clutter_actor_add_child (window_group, CLUTTER_ACTOR (self)); @@ -1375,7 +1357,7 @@ meta_window_actor_new (MetaWindow *window) /* Initial position in the stack is arbitrary; stacking will be synced * before we first paint. */ - info->windows = g_list_append (info->windows, self); + compositor->windows = g_list_append (compositor->windows, self); return self; } @@ -1912,8 +1894,7 @@ static void do_send_frame_drawn (MetaWindowActor *self, FrameData *frame) { MetaWindowActorPrivate *priv = self->priv; - MetaScreen *screen = priv->screen; - MetaDisplay *display = meta_screen_get_display (screen); + MetaDisplay *display = meta_window_get_display (priv->window); Display *xdisplay = meta_display_get_xdisplay (display); XClientMessageEvent ev = { 0, }; @@ -1965,7 +1946,7 @@ do_send_frame_timings (MetaWindowActor *self, gint64 presentation_time) { MetaWindowActorPrivate *priv = self->priv; - MetaDisplay *display = meta_screen_get_display (priv->screen); + MetaDisplay *display = meta_window_get_display (priv->window); Display *xdisplay = meta_display_get_xdisplay (display); XClientMessageEvent ev = { 0, }; diff --git a/src/core/display.c b/src/core/display.c index b40b76acf..2f5c6cd07 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -378,7 +378,7 @@ enable_compositor (MetaDisplay *display) if (!display->compositor) return; - meta_compositor_manage_screen (display->compositor, display->screen); + meta_compositor_manage (display->compositor); } static void diff --git a/src/core/keybindings.c b/src/core/keybindings.c index 2d82b1651..8f787b78d 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -1660,7 +1660,7 @@ process_event (MetaDisplay *display, /* If the compositor filtered out the keybindings, that * means they don't want the binding to trigger, so we do * the same thing as if the binding didn't exist. */ - if (meta_compositor_filter_keybinding (display->compositor, screen, binding)) + if (meta_compositor_filter_keybinding (display->compositor, binding)) goto not_found; if (binding->handler == NULL) @@ -1745,7 +1745,7 @@ process_overlay_key (MetaDisplay *display, display->overlay_key_combo.keycode, display->grab_mask); if (binding && - meta_compositor_filter_keybinding (display->compositor, screen, binding)) + meta_compositor_filter_keybinding (display->compositor, binding)) return TRUE; meta_display_overlay_key_activate (display); } diff --git a/src/core/screen-private.h b/src/core/screen-private.h index 22b62cf6e..78a1f9a5b 100644 --- a/src/core/screen-private.h +++ b/src/core/screen-private.h @@ -116,9 +116,6 @@ struct _MetaScreen guint all_keys_grabbed : 1; int closing; - - /* Managed by compositor.c */ - gpointer compositor_data; /* Instead of unmapping withdrawn windows we can leave them mapped * and restack them below a guard window. When using a compositor diff --git a/src/core/screen.c b/src/core/screen.c index 36290dc5e..26354a60c 100644 --- a/src/core/screen.c +++ b/src/core/screen.c @@ -707,7 +707,6 @@ meta_screen_new (MetaDisplay *display, screen->columns_of_workspaces = -1; screen->vertical_workspaces = FALSE; screen->starting_corner = META_SCREEN_TOPLEFT; - screen->compositor_data = NULL; screen->guard_window = None; reload_monitor_infos (screen); @@ -808,8 +807,7 @@ meta_screen_free (MetaScreen *screen, meta_display_grab (display); - meta_compositor_unmanage_screen (screen->display->compositor, - screen); + meta_compositor_unmanage (screen->display->compositor); meta_display_unmanage_windows_for_screen (display, screen, timestamp); @@ -1439,11 +1437,10 @@ meta_screen_update_tile_preview_timeout (gpointer data) monitor = meta_window_get_current_tile_monitor_number (window); meta_window_get_current_tile_area (window, &tile_rect); meta_compositor_show_tile_preview (screen->display->compositor, - screen, window, &tile_rect, monitor); + window, &tile_rect, monitor); } else - meta_compositor_hide_tile_preview (screen->display->compositor, - screen); + meta_compositor_hide_tile_preview (screen->display->compositor); return FALSE; } @@ -1479,8 +1476,7 @@ meta_screen_hide_tile_preview (MetaScreen *screen) if (screen->tile_preview_timeout_id > 0) g_source_remove (screen->tile_preview_timeout_id); - meta_compositor_hide_tile_preview (screen->display->compositor, - screen); + meta_compositor_hide_tile_preview (screen->display->compositor); } MetaWindow* @@ -2498,7 +2494,6 @@ on_monitors_changed (MetaMonitorManager *manager, } meta_compositor_sync_screen_size (screen->display->compositor, - screen, screen->rect.width, screen->rect.height); /* Queue a resize on all the windows */ @@ -3039,24 +3034,6 @@ meta_screen_get_size (MetaScreen *screen, *height = screen->rect.height; } -/** - * meta_screen_get_compositor_data: (skip) - * @screen: A #MetaScreen - * - */ -gpointer -meta_screen_get_compositor_data (MetaScreen *screen) -{ - return screen->compositor_data; -} - -void -meta_screen_set_compositor_data (MetaScreen *screen, - gpointer compositor) -{ - screen->compositor_data = compositor; -} - void meta_screen_set_cm_selection (MetaScreen *screen) { diff --git a/src/core/stack-tracker.c b/src/core/stack-tracker.c index e87c13f1c..77266a088 100644 --- a/src/core/stack-tracker.c +++ b/src/core/stack-tracker.c @@ -1246,7 +1246,6 @@ meta_stack_tracker_sync_stack (MetaStackTracker *tracker) } meta_compositor_sync_stack (tracker->screen->display->compositor, - tracker->screen, meta_windows); g_list_free (meta_windows); diff --git a/src/core/workspace.c b/src/core/workspace.c index f1e2527a1..ca87c0bf7 100644 --- a/src/core/workspace.c +++ b/src/core/workspace.c @@ -665,7 +665,7 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace, meta_screen_free_workspace_layout (&layout1); meta_screen_free_workspace_layout (&layout2); - meta_compositor_switch_workspace (comp, screen, old, workspace, direction); + meta_compositor_switch_workspace (comp, old, workspace, direction); /* This needs to be done after telling the compositor we are switching * workspaces since focusing a window will cause it to be immediately diff --git a/src/meta/compositor.h b/src/meta/compositor.h index 76ad10ba8..57be80afd 100644 --- a/src/meta/compositor.h +++ b/src/meta/compositor.h @@ -57,10 +57,8 @@ typedef enum MetaCompositor *meta_compositor_new (MetaDisplay *display); void meta_compositor_destroy (MetaCompositor *compositor); -void meta_compositor_manage_screen (MetaCompositor *compositor, - MetaScreen *screen); -void meta_compositor_unmanage_screen (MetaCompositor *compositor, - MetaScreen *screen); +void meta_compositor_manage (MetaCompositor *compositor); +void meta_compositor_unmanage (MetaCompositor *compositor); void meta_compositor_window_shape_changed (MetaCompositor *compositor, MetaWindow *window); @@ -74,7 +72,6 @@ gboolean meta_compositor_process_event (MetaCompositor *compositor, MetaWindow *window); gboolean meta_compositor_filter_keybinding (MetaCompositor *compositor, - MetaScreen *screen, MetaKeyBinding *binding); void meta_compositor_add_window (MetaCompositor *compositor, @@ -88,7 +85,6 @@ void meta_compositor_hide_window (MetaCompositor *compositor, MetaWindow *window, MetaCompEffect effect); void meta_compositor_switch_workspace (MetaCompositor *compositor, - MetaScreen *screen, MetaWorkspace *from, MetaWorkspace *to, MetaMotionDirection direction); @@ -113,10 +109,8 @@ void meta_compositor_queue_frame_drawn (MetaCompositor *compositor, gboolean no_delay_frame); void meta_compositor_sync_stack (MetaCompositor *compositor, - MetaScreen *screen, GList *stack); void meta_compositor_sync_screen_size (MetaCompositor *compositor, - MetaScreen *screen, guint width, guint height); @@ -124,11 +118,9 @@ void meta_compositor_flash_screen (MetaCompositor *compositor, MetaScreen *screen); void meta_compositor_show_tile_preview (MetaCompositor *compositor, - MetaScreen *screen, MetaWindow *window, MetaRectangle *tile_rect, int tile_monitor_number); -void meta_compositor_hide_tile_preview (MetaCompositor *compositor, - MetaScreen *screen); +void meta_compositor_hide_tile_preview (MetaCompositor *compositor); #endif /* META_COMPOSITOR_H */ diff --git a/src/meta/meta-plugin.h b/src/meta/meta-plugin.h index df42f3e34..983db7a47 100644 --- a/src/meta/meta-plugin.h +++ b/src/meta/meta-plugin.h @@ -405,7 +405,7 @@ meta_plugin_end_modal (MetaPlugin *plugin, MetaScreen *meta_plugin_get_screen (MetaPlugin *plugin); -void _meta_plugin_set_screen (MetaPlugin *plugin, MetaScreen *screen); +void _meta_plugin_set_compositor (MetaPlugin *plugin, MetaCompositor *compositor); /* XXX: Putting this in here so it's in the public header. */ void meta_plugin_manager_set_plugin_type (GType gtype); diff --git a/src/meta/screen.h b/src/meta/screen.h index 8c65246ca..4c3c52e3f 100644 --- a/src/meta/screen.h +++ b/src/meta/screen.h @@ -44,10 +44,6 @@ void meta_screen_get_size (MetaScreen *screen, int *width, int *height); -gpointer meta_screen_get_compositor_data (MetaScreen *screen); -void meta_screen_set_compositor_data (MetaScreen *screen, - gpointer info); - void meta_screen_set_cm_selection (MetaScreen *screen); void meta_screen_unset_cm_selection (MetaScreen *screen); From 6eeaf09ab70a001d30d3f72599963d7448ca5f40 Mon Sep 17 00:00:00 2001 From: Adel Gadllah Date: Thu, 27 Mar 2014 13:57:53 +0100 Subject: [PATCH 754/889] compositor: Don't call process_damage if the window is gone We might get a damage event for an already unmanaged window calling process_damage is pointless and causes a crash so simply skip that case. https://bugzilla.gnome.org/show_bug.cgi?id=727115 --- src/compositor/compositor.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 22eec9e65..54fcd4482 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -930,7 +930,8 @@ meta_compositor_process_event (MetaCompositor *compositor, window = meta_display_lookup_x_window (compositor->display, xwin); } - process_damage (compositor, (XDamageNotifyEvent *) event, window); + if (window) + process_damage (compositor, (XDamageNotifyEvent *) event, window); } /* Clutter needs to know about MapNotify events otherwise it will From 3f70bdd3314df5f5d409a371540c8a2a4821d702 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 27 Mar 2014 12:41:36 -0400 Subject: [PATCH 755/889] display: Revert API break for get_tab_list gnome-shell apparently uses this, and we shouldn't break it. --- src/core/display.c | 6 ++++-- src/meta/display.h | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/core/display.c b/src/core/display.c index 2f5c6cd07..70e8aa58d 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -2771,19 +2771,21 @@ mru_cmp (gconstpointer a, * meta_display_get_tab_list: * @display: a #MetaDisplay * @type: type of tab list + * @screen: a #MetaScreen * @workspace: (allow-none): origin workspace * * Determine the list of windows that should be displayed for Alt-TAB * functionality. The windows are returned in most recently used order. * If @workspace is not %NULL, the list only conains windows that are on * @workspace or have the demands-attention hint set; otherwise it contains - * all windows. + * all windows on @screen. * * Returns: (transfer container) (element-type Meta.Window): List of windows */ GList* meta_display_get_tab_list (MetaDisplay *display, MetaTabList type, + MetaScreen *screen, MetaWorkspace *workspace) { GList *tab_list = NULL; @@ -2858,7 +2860,7 @@ meta_display_get_tab_next (MetaDisplay *display, gboolean skip; GList *tab_list; MetaWindow *ret; - tab_list = meta_display_get_tab_list (display, type, workspace); + tab_list = meta_display_get_tab_list (display, type, NULL, workspace); if (tab_list == NULL) return NULL; diff --git a/src/meta/display.h b/src/meta/display.h index 8d1e669f7..d6cfacf89 100644 --- a/src/meta/display.h +++ b/src/meta/display.h @@ -96,6 +96,7 @@ unsigned int meta_display_get_ignored_modifier_mask (MetaDisplay *display); GList* meta_display_get_tab_list (MetaDisplay *display, MetaTabList type, + MetaScreen *screen, MetaWorkspace *workspace); MetaWindow* meta_display_get_tab_next (MetaDisplay *display, From f4f529385ab0c397caa7816435c3e203acb3686e Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Thu, 27 Mar 2014 14:58:20 -0400 Subject: [PATCH 756/889] Fix the build with -Werror=maybe-uninitialized gcc can't really know that the condition won't change between the first if and the second, so help it out by initializing the variable up top. --- src/compositor/compositor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 54fcd4482..075d4ac65 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -517,7 +517,7 @@ meta_compositor_manage (MetaCompositor *compositor) MetaDisplay *display = compositor->display; Display *xdisplay = display->xdisplay; MetaScreen *screen = display->screen; - Window xwin; + Window xwin = 0; gint width, height; MetaWaylandCompositor *wayland_compositor; From e10fd19d240dbc59eaef0a5fe9e88c45f22fbdfe Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 28 Mar 2014 13:46:00 -0400 Subject: [PATCH 757/889] events: Make sure to check the event window of the MapNotify This was lost in a rebase when killing off zaphod mode. --- src/core/events.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/events.c b/src/core/events.c index 137c60539..1cbd6ba8f 100644 --- a/src/core/events.c +++ b/src/core/events.c @@ -1374,7 +1374,7 @@ handle_other_xevent (MetaDisplay *display, /* NB: override redirect windows wont cause a map request so we * watch out for map notifies against any root windows too if a * compositor is enabled: */ - if (window == NULL) + if (window == NULL && event->xmap.event == display->screen->xroot) { window = meta_window_x11_new (display, event->xmap.window, FALSE, META_COMP_EFFECT_CREATE); From ed9dbf6aa241e9283d4009cfd384cbf51bb596aa Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 28 Mar 2014 13:51:34 -0400 Subject: [PATCH 758/889] window: Ensure that visible_to_compositor is set when unmanaging visible_to_compositor should always be in sync with show_window / hide_window calls, even when unmananging. This fixes a crash where we call sync_window_state when the window is unmanaging, since we use visible_to_compositor to determine whether the compositor will crash. This is actually wrong; we should be using the knowledge about whether we have called add_window / remove_window. We'll introduce this with a new boolean next time. --- src/core/window.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/core/window.c b/src/core/window.c index c70993c25..29050234e 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -1469,8 +1469,11 @@ meta_window_unmanage (MetaWindow *window, meta_wayland_surface_window_unmanaged (window->surface); if (window->visible_to_compositor) - meta_compositor_hide_window (window->display->compositor, window, - META_COMP_EFFECT_DESTROY); + { + window->visible_to_compositor = FALSE; + meta_compositor_hide_window (window->display->compositor, window, + META_COMP_EFFECT_DESTROY); + } meta_compositor_remove_window (window->display->compositor, window); From b367965f6c66bcbbd8b1c8daddc550d3d0fed231 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 28 Mar 2014 13:50:45 -0400 Subject: [PATCH 759/889] window: Track known_to_compositor and visible_to_compositor separately Really, visible_to_compositor means that the window is shown, e.g. not minimized. We need to be using a boolean tracking whether we've called meta_compositor_add_window / meta_compositor_remove_window. This fixes a jump during window placement when a window appears. --- src/core/window-private.h | 10 +++++++++- src/core/window.c | 5 ++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/core/window-private.h b/src/core/window-private.h index ebda724b9..374bca7d7 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -220,10 +220,18 @@ struct _MetaWindow */ guint hidden : 1; - /* Whether the compositor thinks the window is visible + /* Whether the compositor thinks the window is visible. + * This should match up with calls to meta_compositor_show_window / + * meta_compositor_hide_window. */ guint visible_to_compositor : 1; + /* Whether the compositor knows about the window. + * This should match up with calls to meta_compositor_add_window / + * meta_compositor_remove_window. + */ + guint known_to_compositor : 1; + /* When we next show or hide the window, what effect we should * tell the compositor to perform. */ diff --git a/src/core/window.c b/src/core/window.c index 29050234e..1deece0db 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -867,6 +867,7 @@ _meta_window_shared_new (MetaDisplay *display, window->iconic = FALSE; window->mapped = attrs->map_state != IsUnmapped; window->hidden = FALSE; + window->known_to_compositor = FALSE; window->visible_to_compositor = FALSE; window->pending_compositor_effect = effect; /* if already mapped, no need to worry about focus-on-first-time-showing */ @@ -1195,6 +1196,7 @@ _meta_window_shared_new (MetaDisplay *display, } meta_compositor_add_window (screen->display->compositor, window); + window->known_to_compositor = TRUE; /* Sync stack changes */ meta_stack_thaw (window->screen->stack); @@ -1476,6 +1478,7 @@ meta_window_unmanage (MetaWindow *window, } meta_compositor_remove_window (window->display->compositor, window); + window->known_to_compositor = FALSE; if (window->display->window_with_menu == window) { @@ -4331,7 +4334,7 @@ meta_window_move_resize_internal (MetaWindow *window, newx, newy, window->rect.width, window->rect.height, window->user_rect.x, window->user_rect.y, window->user_rect.width, window->user_rect.height); - if (window->visible_to_compositor) + if (window->known_to_compositor) meta_compositor_sync_window_geometry (window->display->compositor, window, did_placement); From 0f9b29b14049009d38d45fc0f5063507c001144b Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 28 Mar 2014 13:58:21 -0400 Subject: [PATCH 760/889] display: Don't double-free the screen We already free the screen once in meta_display_close. This fixes a crash when trying to restart mutter. --- src/core/display.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/core/display.c b/src/core/display.c index 70e8aa58d..2b1a574be 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -2974,8 +2974,6 @@ meta_display_unmanage_screen (MetaDisplay *display, { meta_verbose ("Unmanaging screen %d on display %s\n", screen->number, display->name); - - meta_screen_free (screen, timestamp); meta_display_close (display, timestamp); } From 82e02e39d322b8c0c8a79944b6918e62ea901e4d Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sun, 30 Mar 2014 20:11:47 -0400 Subject: [PATCH 761/889] window-actor: Fix the input shape region for decorated X11 windows The code here before was completely wrong. Not only did it mix up coordinate spaces of "client rect" vs. "frame rect", but it used meta_frame_get_frame_bounds, which is specifically for the *visible* bounds of a window! In the case that we don't have a bounding or input shape region at all on the client window, the input shape that we should apply is the surface's natural shape. So, set the region to NULL to get the natural rect picking semantics. --- src/compositor/meta-window-actor.c | 41 ++++++++---------------------- 1 file changed, 10 insertions(+), 31 deletions(-) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 2054771eb..39fa7db8b 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -1738,41 +1738,20 @@ static void meta_window_actor_update_input_region (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; - cairo_region_t *region = NULL; - cairo_rectangle_int_t client_area; + MetaWindow *window = priv->window; + cairo_region_t *region; - meta_window_get_client_area_rect (priv->window, &client_area); - - if (priv->window->frame != NULL) + if (window->shape_region && window->input_region) { - region = meta_frame_get_frame_bounds (priv->window->frame); - - /* input_region is in client window coordinates, so translate the - * input region into that coordinate system and back */ - cairo_region_translate (region, -client_area.x, -client_area.y); - cairo_region_union_rectangle (region, &client_area); - cairo_region_translate (region, client_area.x, client_area.y); - } - else if (priv->window->shape_region != NULL || - priv->window->input_region != NULL) - { - if (priv->window->shape_region != NULL) - { - region = cairo_region_copy (priv->window->shape_region); - - if (priv->window->input_region != NULL) - cairo_region_intersect (region, priv->window->input_region); - } - else - region = cairo_region_reference (priv->window->input_region); + region = cairo_region_copy (window->shape_region); + cairo_region_intersect (region, window->input_region); } + else if (window->shape_region) + region = cairo_region_reference (window->shape_region); + else if (window->input_region) + region = cairo_region_reference (window->input_region); else - { - /* If we don't have a shape on the server, that means that - * we have an implicit shape of one rectangle covering the - * entire window. */ - region = cairo_region_create_rectangle (&client_area); - } + region = NULL; meta_surface_actor_set_input_region (priv->surface, region); cairo_region_destroy (region); From 390c028da7b454a0cd30b8eaf569a53d9c1d55b5 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sun, 30 Mar 2014 20:21:39 -0400 Subject: [PATCH 762/889] Rename the monitor backend filenames To match the "meta-*" new-style naming. --- src/Makefile.am | 4 ++-- src/core/{monitor-kms.c => meta-monitor-manager-kms.c} | 0 src/core/{monitor-xrandr.c => meta-monitor-manager-xrandr.c} | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename src/core/{monitor-kms.c => meta-monitor-manager-kms.c} (100%) rename src/core/{monitor-xrandr.c => meta-monitor-manager-xrandr.c} (100%) diff --git a/src/Makefile.am b/src/Makefile.am index 3763746af..4b5cf7498 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -134,9 +134,9 @@ libmutter_wayland_la_SOURCES = \ core/meta-xrandr-shared.h \ core/monitor.c \ core/monitor-config.c \ - core/monitor-kms.c \ core/monitor-private.h \ - core/monitor-xrandr.c \ + core/meta-monitor-manager-kms.c \ + core/meta-monitor-manager-xrandr.c \ core/mutter-Xatomtype.h \ core/place.c \ core/place.h \ diff --git a/src/core/monitor-kms.c b/src/core/meta-monitor-manager-kms.c similarity index 100% rename from src/core/monitor-kms.c rename to src/core/meta-monitor-manager-kms.c diff --git a/src/core/monitor-xrandr.c b/src/core/meta-monitor-manager-xrandr.c similarity index 100% rename from src/core/monitor-xrandr.c rename to src/core/meta-monitor-manager-xrandr.c From b2405b701a82d5a4306ea75a6c3f63efa4a29949 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sun, 30 Mar 2014 20:25:31 -0400 Subject: [PATCH 763/889] Move monitor manager headers to their own files Instead of having them in monitor-private.h. This way, it's easier to move our own backend when the chance arises. --- src/Makefile.am | 2 ++ src/core/meta-monitor-manager-kms.c | 3 +- src/core/meta-monitor-manager-kms.h | 40 ++++++++++++++++++++++++++ src/core/meta-monitor-manager-xrandr.c | 4 +-- src/core/meta-monitor-manager-xrandr.h | 40 ++++++++++++++++++++++++++ src/core/monitor-private.h | 24 ---------------- src/core/monitor.c | 2 ++ 7 files changed, 88 insertions(+), 27 deletions(-) create mode 100644 src/core/meta-monitor-manager-kms.h create mode 100644 src/core/meta-monitor-manager-xrandr.h diff --git a/src/Makefile.am b/src/Makefile.am index 4b5cf7498..df5e040bd 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -136,7 +136,9 @@ libmutter_wayland_la_SOURCES = \ core/monitor-config.c \ core/monitor-private.h \ core/meta-monitor-manager-kms.c \ + core/meta-monitor-manager-kms.h \ core/meta-monitor-manager-xrandr.c \ + core/meta-monitor-manager-xrandr.h \ core/mutter-Xatomtype.h \ core/place.c \ core/place.h \ diff --git a/src/core/meta-monitor-manager-kms.c b/src/core/meta-monitor-manager-kms.c index a44df83c2..698c60608 100644 --- a/src/core/meta-monitor-manager-kms.c +++ b/src/core/meta-monitor-manager-kms.c @@ -23,6 +23,8 @@ #include "config.h" +#include "meta-monitor-manager-kms.h" + #include #include #include @@ -36,7 +38,6 @@ #include #include -#include "monitor-private.h" #include "edid.h" #define ALL_WL_TRANSFORMS ((1 << (WL_OUTPUT_TRANSFORM_FLIPPED_270 + 1)) - 1) diff --git a/src/core/meta-monitor-manager-kms.h b/src/core/meta-monitor-manager-kms.h new file mode 100644 index 000000000..ef75dd60c --- /dev/null +++ b/src/core/meta-monitor-manager-kms.h @@ -0,0 +1,40 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2001 Havoc Pennington + * Copyright (C) 2003 Rob Adams + * Copyright (C) 2004-2006 Elijah Newren + * Copyright (C) 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, see . + */ + +#ifndef META_MONITOR_MANAGER_KMS_H +#define META_MONITOR_MANAGER_KMS_H + +#include "monitor-private.h" + +#define META_TYPE_MONITOR_MANAGER_KMS (meta_monitor_manager_kms_get_type ()) +#define META_MONITOR_MANAGER_KMS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_MONITOR_MANAGER_KMS, MetaMonitorManagerKms)) +#define META_MONITOR_MANAGER_KMS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_MONITOR_MANAGER_KMS, MetaMonitorManagerKmsClass)) +#define META_IS_MONITOR_MANAGER_KMS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_MONITOR_MANAGER_KMS)) +#define META_IS_MONITOR_MANAGER_KMS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_MONITOR_MANAGER_KMS)) +#define META_MONITOR_MANAGER_KMS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_MONITOR_MANAGER_KMS, MetaMonitorManagerKmsClass)) + +typedef struct _MetaMonitorManagerKmsClass MetaMonitorManagerKmsClass; +typedef struct _MetaMonitorManagerKms MetaMonitorManagerKms; + +GType meta_monitor_manager_kms_get_type (void); + +#endif /* META_MONITOR_MANAGER_KMS_H */ diff --git a/src/core/meta-monitor-manager-xrandr.c b/src/core/meta-monitor-manager-xrandr.c index 66d89539d..59b5fbac7 100644 --- a/src/core/meta-monitor-manager-xrandr.c +++ b/src/core/meta-monitor-manager-xrandr.c @@ -25,6 +25,8 @@ #include "config.h" +#include "meta-monitor-manager-xrandr.h" + #include #include #include @@ -36,8 +38,6 @@ #include #include -#include "monitor-private.h" - #include "edid.h" #define ALL_WL_TRANSFORMS ((1 << (WL_OUTPUT_TRANSFORM_FLIPPED_270 + 1)) - 1) diff --git a/src/core/meta-monitor-manager-xrandr.h b/src/core/meta-monitor-manager-xrandr.h new file mode 100644 index 000000000..15268e1c1 --- /dev/null +++ b/src/core/meta-monitor-manager-xrandr.h @@ -0,0 +1,40 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2001 Havoc Pennington + * Copyright (C) 2003 Rob Adams + * Copyright (C) 2004-2006 Elijah Newren + * Copyright (C) 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, see . + */ + +#ifndef META_MONITOR_MANAGER_XRANDR_H +#define META_MONITOR_MANAGER_XRANDR_H + +#include "monitor-private.h" + +#define META_TYPE_MONITOR_MANAGER_XRANDR (meta_monitor_manager_xrandr_get_type ()) +#define META_MONITOR_MANAGER_XRANDR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_MONITOR_MANAGER_XRANDR, MetaMonitorManagerXrandr)) +#define META_MONITOR_MANAGER_XRANDR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_MONITOR_MANAGER_XRANDR, MetaMonitorManagerXrandrClass)) +#define META_IS_MONITOR_MANAGER_XRANDR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_MONITOR_MANAGER_XRANDR)) +#define META_IS_MONITOR_MANAGER_XRANDR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_MONITOR_MANAGER_XRANDR)) +#define META_MONITOR_MANAGER_XRANDR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_MONITOR_MANAGER_XRANDR, MetaMonitorManagerXrandrClass)) + +typedef struct _MetaMonitorManagerXrandrClass MetaMonitorManagerXrandrClass; +typedef struct _MetaMonitorManagerXrandr MetaMonitorManagerXrandr; + +GType meta_monitor_manager_xrandr_get_type (void); + +#endif /* META_MONITOR_MANAGER_XRANDR_H */ diff --git a/src/core/monitor-private.h b/src/core/monitor-private.h index 842ab97af..7f215b57e 100644 --- a/src/core/monitor-private.h +++ b/src/core/monitor-private.h @@ -335,30 +335,6 @@ void meta_monitor_manager_apply_configuration (MetaMonitorManager void meta_monitor_manager_confirm_configuration (MetaMonitorManager *manager, gboolean ok); -#define META_TYPE_MONITOR_MANAGER_XRANDR (meta_monitor_manager_xrandr_get_type ()) -#define META_MONITOR_MANAGER_XRANDR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_MONITOR_MANAGER_XRANDR, MetaMonitorManagerXrandr)) -#define META_MONITOR_MANAGER_XRANDR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_MONITOR_MANAGER_XRANDR, MetaMonitorManagerXrandrClass)) -#define META_IS_MONITOR_MANAGER_XRANDR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_MONITOR_MANAGER_XRANDR)) -#define META_IS_MONITOR_MANAGER_XRANDR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_MONITOR_MANAGER_XRANDR)) -#define META_MONITOR_MANAGER_XRANDR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_MONITOR_MANAGER_XRANDR, MetaMonitorManagerXrandrClass)) - -typedef struct _MetaMonitorManagerXrandrClass MetaMonitorManagerXrandrClass; -typedef struct _MetaMonitorManagerXrandr MetaMonitorManagerXrandr; - -GType meta_monitor_manager_xrandr_get_type (void); - -#define META_TYPE_MONITOR_MANAGER_KMS (meta_monitor_manager_kms_get_type ()) -#define META_MONITOR_MANAGER_KMS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_MONITOR_MANAGER_KMS, MetaMonitorManagerKms)) -#define META_MONITOR_MANAGER_KMS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_MONITOR_MANAGER_KMS, MetaMonitorManagerKmsClass)) -#define META_IS_MONITOR_MANAGER_KMS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_MONITOR_MANAGER_KMS)) -#define META_IS_MONITOR_MANAGER_KMS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_MONITOR_MANAGER_KMS)) -#define META_MONITOR_MANAGER_KMS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_MONITOR_MANAGER_KMS, MetaMonitorManagerKmsClass)) - -typedef struct _MetaMonitorManagerKmsClass MetaMonitorManagerKmsClass; -typedef struct _MetaMonitorManagerKms MetaMonitorManagerKms; - -GType meta_monitor_manager_kms_get_type (void); - #define META_TYPE_MONITOR_CONFIG (meta_monitor_config_get_type ()) #define META_MONITOR_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_MONITOR_CONFIG, MetaMonitorConfig)) #define META_MONITOR_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_MONITOR_CONFIG, MetaMonitorConfigClass)) diff --git a/src/core/monitor.c b/src/core/monitor.c index 2b2c1f781..51fb28004 100644 --- a/src/core/monitor.c +++ b/src/core/monitor.c @@ -34,6 +34,8 @@ #include "util-private.h" #include #include "monitor-private.h" +#include "meta-monitor-manager-kms.h" +#include "meta-monitor-manager-xrandr.h" #include "meta-dbus-xrandr.h" From afce4482819642645c6f74938f844b1400824c21 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sun, 30 Mar 2014 20:58:11 -0400 Subject: [PATCH 764/889] Kill meta_ui_add_event_func / remove_event_func The reason we don't simply use gdk_window_add_filter directly is because of some twisted idea that any GDK symbol being used from core/ is a layer violation. While we certainly want to keep any serious GDK code out of ui/, event handling is quite important to have in core/, so simply use a GDK event filter directly. --- src/core/events.c | 20 ++++++++--------- src/ui/ui.c | 55 +++++++++-------------------------------------- src/ui/ui.h | 7 ------ 3 files changed, 20 insertions(+), 62 deletions(-) diff --git a/src/core/events.c b/src/core/events.c index 1cbd6ba8f..aaf97f9f7 100644 --- a/src/core/events.c +++ b/src/core/events.c @@ -2124,13 +2124,17 @@ meta_display_handle_event (MetaDisplay *display, return bypass_clutter; } -static gboolean -xevent_callback (XEvent *event, - gpointer data) +static GdkFilterReturn +xevent_filter (GdkXEvent *xevent, + GdkEvent *event, + gpointer data) { MetaDisplay *display = data; - return meta_display_handle_xevent (display, event); + if (meta_display_handle_xevent (display, xevent)) + return GDK_FILTER_REMOVE; + else + return GDK_FILTER_CONTINUE; } static gboolean @@ -2145,9 +2149,7 @@ event_callback (const ClutterEvent *event, void meta_display_init_events (MetaDisplay *display) { - meta_ui_add_event_func (display->xdisplay, - xevent_callback, - display); + gdk_window_add_filter (NULL, xevent_filter, display); display->clutter_event_filter = clutter_event_add_filter (NULL, event_callback, NULL, @@ -2157,9 +2159,7 @@ meta_display_init_events (MetaDisplay *display) void meta_display_free_events (MetaDisplay *display) { - meta_ui_remove_event_func (display->xdisplay, - xevent_callback, - display); + gdk_window_remove_filter (NULL, xevent_filter, display); clutter_event_remove_filter (display->clutter_event_filter); display->clutter_event_filter = 0; } diff --git a/src/ui/ui.c b/src/ui/ui.c index 1a19838f4..822eff5cf 100644 --- a/src/ui/ui.c +++ b/src/ui/ui.c @@ -228,58 +228,17 @@ maybe_redirect_mouse_event (XEvent *xevent) return TRUE; } -typedef struct _EventFunc EventFunc; - -struct _EventFunc -{ - MetaEventFunc func; - gpointer data; -}; - -static EventFunc *ef = NULL; - static GdkFilterReturn -filter_func (GdkXEvent *xevent, - GdkEvent *event, - gpointer data) +ui_filter_func (GdkXEvent *xevent, + GdkEvent *event, + gpointer data) { - g_return_val_if_fail (ef != NULL, GDK_FILTER_CONTINUE); - - if ((* ef->func) (xevent, ef->data) || - maybe_redirect_mouse_event (xevent)) + if (maybe_redirect_mouse_event (xevent)) return GDK_FILTER_REMOVE; else return GDK_FILTER_CONTINUE; } -void -meta_ui_add_event_func (Display *xdisplay, - MetaEventFunc func, - gpointer data) -{ - g_return_if_fail (ef == NULL); - - ef = g_new (EventFunc, 1); - ef->func = func; - ef->data = data; - - gdk_window_add_filter (NULL, filter_func, ef); -} - -/* removal is by data due to proxy function */ -void -meta_ui_remove_event_func (Display *xdisplay, - MetaEventFunc func, - gpointer data) -{ - g_return_if_fail (ef != NULL); - - gdk_window_remove_filter (NULL, filter_func, ef); - - g_free (ef); - ef = NULL; -} - MetaUI* meta_ui_new (Display *xdisplay, Screen *screen) @@ -294,6 +253,8 @@ meta_ui_new (Display *xdisplay, gdisplay = gdk_x11_lookup_xdisplay (xdisplay); g_assert (gdisplay == gdk_display_get_default ()); + gdk_window_add_filter (NULL, ui_filter_func, NULL); + ui->frames = meta_frames_new (XScreenNumberOfScreen (screen)); /* GTK+ needs the frame-sync protocol to work in order to properly * handle style changes. This means that the dummy widget we create @@ -303,6 +264,8 @@ meta_ui_new (Display *xdisplay, */ gtk_widget_show (GTK_WIDGET (ui->frames)); + gdk_window_add_filter (NULL, ui_filter_func, NULL); + g_object_set_data (G_OBJECT (gdisplay), "meta-ui", ui); return ui; @@ -318,6 +281,8 @@ meta_ui_free (MetaUI *ui) gdisplay = gdk_x11_lookup_xdisplay (ui->xdisplay); g_object_set_data (G_OBJECT (gdisplay), "meta-ui", NULL); + gdk_window_remove_filter (NULL, ui_filter_func, NULL); + g_free (ui); } diff --git a/src/ui/ui.h b/src/ui/ui.h index ca52f4c45..42b2b0975 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -46,13 +46,6 @@ Display* meta_ui_get_display (void); gint meta_ui_get_screen_number (void); -void meta_ui_add_event_func (Display *xdisplay, - MetaEventFunc func, - gpointer data); -void meta_ui_remove_event_func (Display *xdisplay, - MetaEventFunc func, - gpointer data); - MetaUI* meta_ui_new (Display *xdisplay, Screen *screen); void meta_ui_free (MetaUI *ui); From 9a751a95e3f1f038c8a40c0e6fd4038d395ce18a Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sun, 30 Mar 2014 20:36:47 -0400 Subject: [PATCH 765/889] idle-monitor: Rearrange code to make it a cleaner split We're going to push this to be subclasses soon. --- src/core/meta-idle-monitor.c | 48 +++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/src/core/meta-idle-monitor.c b/src/core/meta-idle-monitor.c index 4f853ea1b..baadaf068 100644 --- a/src/core/meta-idle-monitor.c +++ b/src/core/meta-idle-monitor.c @@ -96,15 +96,6 @@ G_DEFINE_TYPE (MetaIdleMonitor, meta_idle_monitor, G_TYPE_OBJECT) static MetaIdleMonitor *device_monitors[256]; static int device_id_max; -static gint64 -_xsyncvalue_to_int64 (XSyncValue value) -{ - return ((guint64) XSyncValueHigh32 (value)) << 32 - | (guint64) XSyncValueLow32 (value); -} - -#define GUINT64_TO_XSYNCVALUE(value, ret) XSyncIntsToValue (ret, (value) & 0xFFFFFFFF, ((guint64)(value)) >> 32) - static void fire_watch (MetaIdleMonitorWatch *watch) { @@ -133,6 +124,15 @@ fire_watch (MetaIdleMonitorWatch *watch) g_object_unref (monitor); } +static gint64 +_xsyncvalue_to_int64 (XSyncValue value) +{ + return ((guint64) XSyncValueHigh32 (value)) << 32 + | (guint64) XSyncValueLow32 (value); +} + +#define GUINT64_TO_XSYNCVALUE(value, ret) XSyncIntsToValue (ret, (value) & 0xFFFFFFFF, ((guint64)(value)) >> 32) + static XSyncAlarm _xsync_alarm_set (MetaIdleMonitor *monitor, XSyncTestType test_type, @@ -659,6 +659,23 @@ meta_idle_monitor_remove_watch (MetaIdleMonitor *monitor, g_object_unref (monitor); } +static gint64 +meta_idle_monitor_get_idletime_wayland (MetaIdleMonitor *monitor) +{ + return (g_get_monotonic_time () - monitor->last_event_time) / 1000; +} + +static gint64 +meta_idle_monitor_get_idletime_x11 (MetaIdleMonitor *monitor) +{ + XSyncValue value; + + if (!XSyncQueryCounter (monitor->display, monitor->counter, &value)) + return -1; + + return _xsyncvalue_to_int64 (value); +} + /** * meta_idle_monitor_get_idletime: * @monitor: A #MetaIdleMonitor @@ -668,19 +685,10 @@ meta_idle_monitor_remove_watch (MetaIdleMonitor *monitor, gint64 meta_idle_monitor_get_idletime (MetaIdleMonitor *monitor) { - XSyncValue value; - if (meta_is_wayland_compositor ()) - { - return (g_get_monotonic_time () - monitor->last_event_time) / 1000; - } + return meta_idle_monitor_get_idletime_wayland (monitor); else - { - if (!XSyncQueryCounter (monitor->display, monitor->counter, &value)) - return -1; - - return _xsyncvalue_to_int64 (value); - } + return meta_idle_monitor_get_idletime_x11 (monitor); } typedef struct { From 490e1c8c3bb9cf1e3a856d0707521ead83f02793 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sun, 30 Mar 2014 20:38:56 -0400 Subject: [PATCH 766/889] idle-monitor: Split the DBus implementation to a separate file --- src/Makefile.am | 2 + src/core/display.c | 2 +- src/core/meta-idle-monitor-dbus.c | 286 +++++++++++++++++++++++++++ src/core/meta-idle-monitor-dbus.h | 28 +++ src/core/meta-idle-monitor-private.h | 2 - src/core/meta-idle-monitor.c | 272 ++----------------------- 6 files changed, 328 insertions(+), 264 deletions(-) create mode 100644 src/core/meta-idle-monitor-dbus.c create mode 100644 src/core/meta-idle-monitor-dbus.h diff --git a/src/Makefile.am b/src/Makefile.am index df5e040bd..9a0cbe809 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -131,6 +131,8 @@ libmutter_wayland_la_SOURCES = \ core/meta-cursor-tracker-private.h \ core/meta-idle-monitor.c \ core/meta-idle-monitor-private.h \ + core/meta-idle-monitor-dbus.c \ + core/meta-idle-monitor-dbus.h \ core/meta-xrandr-shared.h \ core/monitor.c \ core/monitor-config.c \ diff --git a/src/core/display.c b/src/core/display.c index 2b1a574be..b4c5b2bce 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -48,7 +48,7 @@ #include #include #include "mutter-enum-types.h" -#include "meta-idle-monitor-private.h" +#include "meta-idle-monitor-dbus.h" #include "meta-cursor-tracker-private.h" #ifdef HAVE_RANDR diff --git a/src/core/meta-idle-monitor-dbus.c b/src/core/meta-idle-monitor-dbus.c new file mode 100644 index 000000000..811b46ada --- /dev/null +++ b/src/core/meta-idle-monitor-dbus.c @@ -0,0 +1,286 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright 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, see . + * + * Adapted from gnome-session/gnome-session/gs-idle-monitor.c and + * from gnome-desktop/libgnome-desktop/gnome-idle-monitor.c + */ + +#include "config.h" + +#include "meta-idle-monitor-dbus.h" +#include +#include "meta-dbus-idle-monitor.h" + +#include +#include +#include /* for meta_get_replace_current_wm () */ + +static gboolean +handle_get_idletime (MetaDBusIdleMonitor *skeleton, + GDBusMethodInvocation *invocation, + MetaIdleMonitor *monitor) +{ + guint64 idletime; + + idletime = meta_idle_monitor_get_idletime (monitor); + meta_dbus_idle_monitor_complete_get_idletime (skeleton, invocation, idletime); + + return TRUE; +} + +typedef struct { + MetaDBusIdleMonitor *dbus_monitor; + MetaIdleMonitor *monitor; + char *dbus_name; + guint watch_id; + guint name_watcher_id; +} DBusWatch; + +static void +destroy_dbus_watch (gpointer data) +{ + DBusWatch *watch = data; + + g_object_unref (watch->dbus_monitor); + g_object_unref (watch->monitor); + g_free (watch->dbus_name); + g_bus_unwatch_name (watch->name_watcher_id); + + g_slice_free (DBusWatch, watch); +} + +static void +dbus_idle_callback (MetaIdleMonitor *monitor, + guint watch_id, + gpointer user_data) +{ + DBusWatch *watch = user_data; + GDBusInterfaceSkeleton *skeleton = G_DBUS_INTERFACE_SKELETON (watch->dbus_monitor); + + g_dbus_connection_emit_signal (g_dbus_interface_skeleton_get_connection (skeleton), + watch->dbus_name, + g_dbus_interface_skeleton_get_object_path (skeleton), + "org.gnome.Mutter.IdleMonitor", + "WatchFired", + g_variant_new ("(u)", watch_id), + NULL); +} + +static void +name_vanished_callback (GDBusConnection *connection, + const char *name, + gpointer user_data) +{ + DBusWatch *watch = user_data; + + meta_idle_monitor_remove_watch (watch->monitor, watch->watch_id); +} + +static DBusWatch * +make_dbus_watch (MetaDBusIdleMonitor *skeleton, + GDBusMethodInvocation *invocation, + MetaIdleMonitor *monitor) +{ + DBusWatch *watch; + + watch = g_slice_new (DBusWatch); + watch->dbus_monitor = g_object_ref (skeleton); + watch->monitor = g_object_ref (monitor); + watch->dbus_name = g_strdup (g_dbus_method_invocation_get_sender (invocation)); + watch->name_watcher_id = g_bus_watch_name_on_connection (g_dbus_method_invocation_get_connection (invocation), + watch->dbus_name, + G_BUS_NAME_WATCHER_FLAGS_NONE, + NULL, /* appeared */ + name_vanished_callback, + watch, NULL); + + return watch; +} + +static gboolean +handle_add_idle_watch (MetaDBusIdleMonitor *skeleton, + GDBusMethodInvocation *invocation, + guint64 interval, + MetaIdleMonitor *monitor) +{ + DBusWatch *watch; + + watch = make_dbus_watch (skeleton, invocation, monitor); + watch->watch_id = meta_idle_monitor_add_idle_watch (monitor, interval, + dbus_idle_callback, watch, destroy_dbus_watch); + + meta_dbus_idle_monitor_complete_add_idle_watch (skeleton, invocation, watch->watch_id); + + return TRUE; +} + +static gboolean +handle_add_user_active_watch (MetaDBusIdleMonitor *skeleton, + GDBusMethodInvocation *invocation, + MetaIdleMonitor *monitor) +{ + DBusWatch *watch; + + watch = make_dbus_watch (skeleton, invocation, monitor); + watch->watch_id = meta_idle_monitor_add_user_active_watch (monitor, + dbus_idle_callback, watch, + destroy_dbus_watch); + + meta_dbus_idle_monitor_complete_add_user_active_watch (skeleton, invocation, watch->watch_id); + + return TRUE; +} + +static gboolean +handle_remove_watch (MetaDBusIdleMonitor *skeleton, + GDBusMethodInvocation *invocation, + guint id, + MetaIdleMonitor *monitor) +{ + meta_idle_monitor_remove_watch (monitor, id); + meta_dbus_idle_monitor_complete_remove_watch (skeleton, invocation); + + return TRUE; +} + +static void +create_monitor_skeleton (GDBusObjectManagerServer *manager, + MetaIdleMonitor *monitor, + const char *path) +{ + MetaDBusIdleMonitor *skeleton; + MetaDBusObjectSkeleton *object; + + skeleton = meta_dbus_idle_monitor_skeleton_new (); + g_signal_connect_object (skeleton, "handle-add-idle-watch", + G_CALLBACK (handle_add_idle_watch), monitor, 0); + g_signal_connect_object (skeleton, "handle-add-user-active-watch", + G_CALLBACK (handle_add_user_active_watch), monitor, 0); + g_signal_connect_object (skeleton, "handle-remove-watch", + G_CALLBACK (handle_remove_watch), monitor, 0); + g_signal_connect_object (skeleton, "handle-get-idletime", + G_CALLBACK (handle_get_idletime), monitor, 0); + + object = meta_dbus_object_skeleton_new (path); + meta_dbus_object_skeleton_set_idle_monitor (object, skeleton); + + g_dbus_object_manager_server_export (manager, G_DBUS_OBJECT_SKELETON (object)); +} + +static void +on_device_added (ClutterDeviceManager *device_manager, + ClutterInputDevice *device, + GDBusObjectManagerServer *manager) +{ + + MetaIdleMonitor *monitor; + int device_id; + char *path; + + device_id = clutter_input_device_get_device_id (device); + monitor = meta_idle_monitor_get_for_device (device_id); + path = g_strdup_printf ("/org/gnome/Mutter/IdleMonitor/Device%d", device_id); + + create_monitor_skeleton (manager, monitor, path); + g_free (path); +} + +static void +on_device_removed (ClutterDeviceManager *device_manager, + ClutterInputDevice *device, + GDBusObjectManagerServer *manager) +{ + int device_id; + char *path; + + device_id = clutter_input_device_get_device_id (device); + path = g_strdup_printf ("/org/gnome/Mutter/IdleMonitor/Device%d", device_id); + g_dbus_object_manager_server_unexport (manager, path); + g_free (path); +} + +static void +on_bus_acquired (GDBusConnection *connection, + const char *name, + gpointer user_data) +{ + GDBusObjectManagerServer *manager; + ClutterDeviceManager *device_manager; + MetaIdleMonitor *monitor; + GSList *devices, *iter; + char *path; + + manager = g_dbus_object_manager_server_new ("/org/gnome/Mutter/IdleMonitor"); + + /* We never clear the core monitor, as that's supposed to cumulate idle times from + all devices */ + monitor = meta_idle_monitor_get_core (); + path = g_strdup ("/org/gnome/Mutter/IdleMonitor/Core"); + create_monitor_skeleton (manager, monitor, path); + g_free (path); + + device_manager = clutter_device_manager_get_default (); + devices = clutter_device_manager_list_devices (device_manager); + + for (iter = devices; iter; iter = iter->next) + on_device_added (device_manager, iter->data, manager); + + g_slist_free (devices); + + g_signal_connect_object (device_manager, "device-added", + G_CALLBACK (on_device_added), manager, 0); + g_signal_connect_object (device_manager, "device-removed", + G_CALLBACK (on_device_removed), manager, 0); + + g_dbus_object_manager_server_set_connection (manager, connection); +} + +static void +on_name_acquired (GDBusConnection *connection, + const char *name, + gpointer user_data) +{ + meta_verbose ("Acquired name %s\n", name); +} + +static void +on_name_lost (GDBusConnection *connection, + const char *name, + gpointer user_data) +{ + meta_verbose ("Lost or failed to acquire name %s\n", name); +} + +void +meta_idle_monitor_init_dbus (void) +{ + static int dbus_name_id; + + if (dbus_name_id > 0) + return; + + dbus_name_id = g_bus_own_name (G_BUS_TYPE_SESSION, + "org.gnome.Mutter.IdleMonitor", + G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT | + (meta_get_replace_current_wm () ? + G_BUS_NAME_OWNER_FLAGS_REPLACE : 0), + on_bus_acquired, + on_name_acquired, + on_name_lost, + NULL, NULL); +} diff --git a/src/core/meta-idle-monitor-dbus.h b/src/core/meta-idle-monitor-dbus.h new file mode 100644 index 000000000..a0d703f0e --- /dev/null +++ b/src/core/meta-idle-monitor-dbus.h @@ -0,0 +1,28 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright 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, see . + * + * Adapted from gnome-session/gnome-session/gs-idle-monitor.c and + * from gnome-desktop/libgnome-desktop/gnome-idle-monitor.c + */ + +#ifndef META_IDLE_MONITOR_DBUS_H +#define META_IDLE_MONITOR_DBUS_H + +void meta_idle_monitor_init_dbus (void); + +#endif diff --git a/src/core/meta-idle-monitor-private.h b/src/core/meta-idle-monitor-private.h index 05289782f..aabd1cc3b 100644 --- a/src/core/meta-idle-monitor-private.h +++ b/src/core/meta-idle-monitor-private.h @@ -25,5 +25,3 @@ void meta_idle_monitor_handle_xevent_all (XEvent *xevent); void meta_idle_monitor_reset_idletime (MetaIdleMonitor *monitor); - -void meta_idle_monitor_init_dbus (void); diff --git a/src/core/meta-idle-monitor.c b/src/core/meta-idle-monitor.c index baadaf068..7af248584 100644 --- a/src/core/meta-idle-monitor.c +++ b/src/core/meta-idle-monitor.c @@ -36,9 +36,9 @@ #include #include #include -#include "display-private.h" #include "meta-idle-monitor-private.h" -#include "meta-dbus-idle-monitor.h" +#include "meta-idle-monitor-dbus.h" +#include "display-private.h" G_STATIC_ASSERT(sizeof(unsigned long) == sizeof(gpointer)); @@ -443,6 +443,15 @@ ensure_device_monitor (int device_id) device_id_max = MAX (device_id_max, device_id); } +/* FIXME -- destroy device monitors at some point */ +G_GNUC_UNUSED static void +destroy_device_monitor (int device_id) +{ + g_clear_object (&device_monitors[device_id]); + if (device_id == device_id_max) + device_id_max--; +} + /** * meta_idle_monitor_get_core: * @@ -743,262 +752,3 @@ meta_idle_monitor_reset_idletime (MetaIdleMonitor *monitor) g_list_free (closure.fired_watches); } -static gboolean -handle_get_idletime (MetaDBusIdleMonitor *skeleton, - GDBusMethodInvocation *invocation, - MetaIdleMonitor *monitor) -{ - guint64 idletime; - - idletime = meta_idle_monitor_get_idletime (monitor); - meta_dbus_idle_monitor_complete_get_idletime (skeleton, invocation, idletime); - - return TRUE; -} - -typedef struct { - MetaDBusIdleMonitor *dbus_monitor; - MetaIdleMonitor *monitor; - char *dbus_name; - guint watch_id; - guint name_watcher_id; -} DBusWatch; - -static void -destroy_dbus_watch (gpointer data) -{ - DBusWatch *watch = data; - - g_object_unref (watch->dbus_monitor); - g_object_unref (watch->monitor); - g_free (watch->dbus_name); - g_bus_unwatch_name (watch->name_watcher_id); - - g_slice_free (DBusWatch, watch); -} - -static void -dbus_idle_callback (MetaIdleMonitor *monitor, - guint watch_id, - gpointer user_data) -{ - DBusWatch *watch = user_data; - GDBusInterfaceSkeleton *skeleton = G_DBUS_INTERFACE_SKELETON (watch->dbus_monitor); - - g_dbus_connection_emit_signal (g_dbus_interface_skeleton_get_connection (skeleton), - watch->dbus_name, - g_dbus_interface_skeleton_get_object_path (skeleton), - "org.gnome.Mutter.IdleMonitor", - "WatchFired", - g_variant_new ("(u)", watch_id), - NULL); -} - -static void -name_vanished_callback (GDBusConnection *connection, - const char *name, - gpointer user_data) -{ - DBusWatch *watch = user_data; - - meta_idle_monitor_remove_watch (watch->monitor, watch->watch_id); -} - -static DBusWatch * -make_dbus_watch (MetaDBusIdleMonitor *skeleton, - GDBusMethodInvocation *invocation, - MetaIdleMonitor *monitor) -{ - DBusWatch *watch; - - watch = g_slice_new (DBusWatch); - watch->dbus_monitor = g_object_ref (skeleton); - watch->monitor = g_object_ref (monitor); - watch->dbus_name = g_strdup (g_dbus_method_invocation_get_sender (invocation)); - watch->name_watcher_id = g_bus_watch_name_on_connection (g_dbus_method_invocation_get_connection (invocation), - watch->dbus_name, - G_BUS_NAME_WATCHER_FLAGS_NONE, - NULL, /* appeared */ - name_vanished_callback, - watch, NULL); - - return watch; -} - -static gboolean -handle_add_idle_watch (MetaDBusIdleMonitor *skeleton, - GDBusMethodInvocation *invocation, - guint64 interval, - MetaIdleMonitor *monitor) -{ - DBusWatch *watch; - - watch = make_dbus_watch (skeleton, invocation, monitor); - watch->watch_id = meta_idle_monitor_add_idle_watch (monitor, interval, - dbus_idle_callback, watch, destroy_dbus_watch); - - meta_dbus_idle_monitor_complete_add_idle_watch (skeleton, invocation, watch->watch_id); - - return TRUE; -} - -static gboolean -handle_add_user_active_watch (MetaDBusIdleMonitor *skeleton, - GDBusMethodInvocation *invocation, - MetaIdleMonitor *monitor) -{ - DBusWatch *watch; - - watch = make_dbus_watch (skeleton, invocation, monitor); - watch->watch_id = meta_idle_monitor_add_user_active_watch (monitor, - dbus_idle_callback, watch, - destroy_dbus_watch); - - meta_dbus_idle_monitor_complete_add_user_active_watch (skeleton, invocation, watch->watch_id); - - return TRUE; -} - -static gboolean -handle_remove_watch (MetaDBusIdleMonitor *skeleton, - GDBusMethodInvocation *invocation, - guint id, - MetaIdleMonitor *monitor) -{ - meta_idle_monitor_remove_watch (monitor, id); - meta_dbus_idle_monitor_complete_remove_watch (skeleton, invocation); - - return TRUE; -} - -static void -create_monitor_skeleton (GDBusObjectManagerServer *manager, - MetaIdleMonitor *monitor, - const char *path) -{ - MetaDBusIdleMonitor *skeleton; - MetaDBusObjectSkeleton *object; - - skeleton = meta_dbus_idle_monitor_skeleton_new (); - g_signal_connect_object (skeleton, "handle-add-idle-watch", - G_CALLBACK (handle_add_idle_watch), monitor, 0); - g_signal_connect_object (skeleton, "handle-add-user-active-watch", - G_CALLBACK (handle_add_user_active_watch), monitor, 0); - g_signal_connect_object (skeleton, "handle-remove-watch", - G_CALLBACK (handle_remove_watch), monitor, 0); - g_signal_connect_object (skeleton, "handle-get-idletime", - G_CALLBACK (handle_get_idletime), monitor, 0); - - object = meta_dbus_object_skeleton_new (path); - meta_dbus_object_skeleton_set_idle_monitor (object, skeleton); - - g_dbus_object_manager_server_export (manager, G_DBUS_OBJECT_SKELETON (object)); -} - -static void -on_device_added (ClutterDeviceManager *device_manager, - ClutterInputDevice *device, - GDBusObjectManagerServer *manager) -{ - - MetaIdleMonitor *monitor; - int device_id; - char *path; - - device_id = clutter_input_device_get_device_id (device); - monitor = meta_idle_monitor_get_for_device (device_id); - path = g_strdup_printf ("/org/gnome/Mutter/IdleMonitor/Device%d", device_id); - - create_monitor_skeleton (manager, monitor, path); - g_free (path); -} - -static void -on_device_removed (ClutterDeviceManager *device_manager, - ClutterInputDevice *device, - GDBusObjectManagerServer *manager) -{ - int device_id; - char *path; - - device_id = clutter_input_device_get_device_id (device); - path = g_strdup_printf ("/org/gnome/Mutter/IdleMonitor/Device%d", device_id); - g_dbus_object_manager_server_unexport (manager, path); - g_free (path); - - g_clear_object (&device_monitors[device_id]); - if (device_id == device_id_max) - device_id_max--; -} - -static void -on_bus_acquired (GDBusConnection *connection, - const char *name, - gpointer user_data) -{ - GDBusObjectManagerServer *manager; - ClutterDeviceManager *device_manager; - MetaIdleMonitor *monitor; - GSList *devices, *iter; - char *path; - - manager = g_dbus_object_manager_server_new ("/org/gnome/Mutter/IdleMonitor"); - - /* We never clear the core monitor, as that's supposed to cumulate idle times from - all devices */ - monitor = meta_idle_monitor_get_core (); - path = g_strdup ("/org/gnome/Mutter/IdleMonitor/Core"); - create_monitor_skeleton (manager, monitor, path); - g_free (path); - - device_manager = clutter_device_manager_get_default (); - devices = clutter_device_manager_list_devices (device_manager); - - for (iter = devices; iter; iter = iter->next) - on_device_added (device_manager, iter->data, manager); - - g_slist_free (devices); - - g_signal_connect_object (device_manager, "device-added", - G_CALLBACK (on_device_added), manager, 0); - g_signal_connect_object (device_manager, "device-removed", - G_CALLBACK (on_device_removed), manager, 0); - - g_dbus_object_manager_server_set_connection (manager, connection); -} - -static void -on_name_acquired (GDBusConnection *connection, - const char *name, - gpointer user_data) -{ - meta_verbose ("Acquired name %s\n", name); -} - -static void -on_name_lost (GDBusConnection *connection, - const char *name, - gpointer user_data) -{ - meta_verbose ("Lost or failed to acquire name %s\n", name); -} - -void -meta_idle_monitor_init_dbus (void) -{ - static int dbus_name_id; - - if (dbus_name_id > 0) - return; - - dbus_name_id = g_bus_own_name (G_BUS_TYPE_SESSION, - "org.gnome.Mutter.IdleMonitor", - G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT | - (meta_get_replace_current_wm () ? - G_BUS_NAME_OWNER_FLAGS_REPLACE : 0), - on_bus_acquired, - on_name_acquired, - on_name_lost, - NULL, NULL); -} - From 1e2bdcc3c5cbf8df59e0fb3ddfb2f4cfe6d909ce Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sun, 30 Mar 2014 20:50:03 -0400 Subject: [PATCH 767/889] idle-monitor: Move reset_idletime handling to events.c It's not specific to the Wayland protocol at all, and it's not really a Wayland compositor thing. This should eventually be in the native backend. --- src/core/events.c | 34 ++++++++++++++++++++++++++++++ src/wayland/meta-wayland-surface.c | 1 - src/wayland/meta-wayland.c | 25 ---------------------- 3 files changed, 34 insertions(+), 26 deletions(-) diff --git a/src/core/events.c b/src/core/events.c index aaf97f9f7..3d113bdf4 100644 --- a/src/core/events.c +++ b/src/core/events.c @@ -1850,6 +1850,38 @@ meta_display_handle_xevent (MetaDisplay *display, return bypass_gtk; } +static void +handle_idletime_for_event (const ClutterEvent *event) +{ + ClutterInputDevice *device, *source_device; + MetaIdleMonitor *core_monitor, *device_monitor; + int device_id; + + /* This is handled by XSync under X11. */ + if (!meta_is_wayland_compositor ()) + return; + + device = clutter_event_get_device (event); + if (device == NULL) + return; + + device_id = clutter_input_device_get_device_id (device); + + core_monitor = meta_idle_monitor_get_core (); + device_monitor = meta_idle_monitor_get_for_device (device_id); + + meta_idle_monitor_reset_idletime (core_monitor); + meta_idle_monitor_reset_idletime (device_monitor); + + source_device = clutter_event_get_source_device (event); + if (source_device != device) + { + device_id = clutter_input_device_get_device_id (device); + device_monitor = meta_idle_monitor_get_for_device (device_id); + meta_idle_monitor_reset_idletime (device_monitor); + } +} + static gboolean meta_display_handle_event (MetaDisplay *display, const ClutterEvent *event) @@ -1864,6 +1896,8 @@ meta_display_handle_event (MetaDisplay *display, meta_wayland_compositor_update (compositor, event); } + handle_idletime_for_event (event); + window = get_window_for_event (display, event); display->current_time = event->any.time; diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 39239ef71..77ea2e563 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -55,7 +55,6 @@ #include #include #include "frame.h" -#include "meta-idle-monitor-private.h" #include "monitor-private.h" #include "meta-surface-actor.h" diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index 12c1935c4..6a4a0ce4c 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -51,7 +51,6 @@ #include #include #include "frame.h" -#include "meta-idle-monitor-private.h" #include "meta-weston-launch.h" #include "monitor-private.h" @@ -520,30 +519,6 @@ void meta_wayland_compositor_update (MetaWaylandCompositor *compositor, const ClutterEvent *event) { - ClutterInputDevice *device, *source_device; - MetaIdleMonitor *core_monitor, *device_monitor; - int device_id; - - device = clutter_event_get_device (event); - if (device == NULL) - return; - - device_id = clutter_input_device_get_device_id (device); - - core_monitor = meta_idle_monitor_get_core (); - device_monitor = meta_idle_monitor_get_for_device (device_id); - - meta_idle_monitor_reset_idletime (core_monitor); - meta_idle_monitor_reset_idletime (device_monitor); - - source_device = clutter_event_get_source_device (event); - if (source_device != device) - { - device_id = clutter_input_device_get_device_id (device); - device_monitor = meta_idle_monitor_get_for_device (device_id); - meta_idle_monitor_reset_idletime (device_monitor); - } - meta_wayland_seat_update (compositor->seat, event); } From 78457cf7b4a3148fc6410d15b3cf5c04256cded4 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sun, 30 Mar 2014 20:52:25 -0400 Subject: [PATCH 768/889] idle-monitor: Create separate subtypes for backend-specific idle monitors The separation here isn't 100% clean yet, as there's common parts that are still protocol specific. We'll clean that up in the next commit. --- src/Makefile.am | 4 + src/core/events.c | 11 +- src/core/meta-idle-monitor-native.c | 174 ++++++++++++ src/core/meta-idle-monitor-native.h | 43 +++ src/core/meta-idle-monitor-private.h | 58 +++- src/core/meta-idle-monitor-xsync.c | 311 ++++++++++++++++++++ src/core/meta-idle-monitor-xsync.h | 49 ++++ src/core/meta-idle-monitor.c | 411 +++------------------------ 8 files changed, 675 insertions(+), 386 deletions(-) create mode 100644 src/core/meta-idle-monitor-native.c create mode 100644 src/core/meta-idle-monitor-native.h create mode 100644 src/core/meta-idle-monitor-xsync.c create mode 100644 src/core/meta-idle-monitor-xsync.h diff --git a/src/Makefile.am b/src/Makefile.am index 9a0cbe809..c81d0963d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -133,6 +133,10 @@ libmutter_wayland_la_SOURCES = \ core/meta-idle-monitor-private.h \ core/meta-idle-monitor-dbus.c \ core/meta-idle-monitor-dbus.h \ + core/meta-idle-monitor-xsync.c \ + core/meta-idle-monitor-xsync.h \ + core/meta-idle-monitor-native.c \ + core/meta-idle-monitor-native.h \ core/meta-xrandr-shared.h \ core/monitor.c \ core/monitor-config.c \ diff --git a/src/core/events.c b/src/core/events.c index 3d113bdf4..49a37d320 100644 --- a/src/core/events.c +++ b/src/core/events.c @@ -34,7 +34,8 @@ #include "window-private.h" #include "bell.h" #include "workspace-private.h" -#include "meta-idle-monitor-private.h" +#include "meta-idle-monitor-xsync.h" +#include "meta-idle-monitor-native.h" #include "x11/window-x11.h" #include "x11/xprops.h" @@ -1244,7 +1245,7 @@ handle_other_xevent (MetaDisplay *display, bypass_gtk = TRUE; /* GTK doesn't want to see this really */ } else - meta_idle_monitor_handle_xevent_all (event); + meta_idle_monitor_xsync_handle_xevent_all (event); goto out; } @@ -1870,15 +1871,15 @@ handle_idletime_for_event (const ClutterEvent *event) core_monitor = meta_idle_monitor_get_core (); device_monitor = meta_idle_monitor_get_for_device (device_id); - meta_idle_monitor_reset_idletime (core_monitor); - meta_idle_monitor_reset_idletime (device_monitor); + meta_idle_monitor_native_reset_idletime (core_monitor); + meta_idle_monitor_native_reset_idletime (device_monitor); source_device = clutter_event_get_source_device (event); if (source_device != device) { device_id = clutter_input_device_get_device_id (device); device_monitor = meta_idle_monitor_get_for_device (device_id); - meta_idle_monitor_reset_idletime (device_monitor); + meta_idle_monitor_native_reset_idletime (device_monitor); } } diff --git a/src/core/meta-idle-monitor-native.c b/src/core/meta-idle-monitor-native.c new file mode 100644 index 000000000..eb3ab6a26 --- /dev/null +++ b/src/core/meta-idle-monitor-native.c @@ -0,0 +1,174 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright 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, see . + * + * Adapted from gnome-session/gnome-session/gs-idle-monitor.c and + * from gnome-desktop/libgnome-desktop/gnome-idle-monitor.c + */ + +#include "config.h" + +#include "meta-idle-monitor-native.h" +#include "meta-idle-monitor-private.h" + +#include +#include "display-private.h" + +#include + +struct _MetaIdleMonitorNative +{ + MetaIdleMonitor parent; +}; + +struct _MetaIdleMonitorNativeClass +{ + MetaIdleMonitorClass parent_class; +}; + +G_DEFINE_TYPE (MetaIdleMonitorNative, meta_idle_monitor_native, META_TYPE_IDLE_MONITOR) + +static gint64 +meta_idle_monitor_native_get_idletime (MetaIdleMonitor *monitor) +{ + return (g_get_monotonic_time () - monitor->last_event_time) / 1000; +} + +static guint32 +get_next_watch_serial (void) +{ + static guint32 serial = 0; + g_atomic_int_inc (&serial); + return serial; +} + +static gboolean +native_dispatch_timeout (GSource *source, + GSourceFunc callback, + gpointer user_data) +{ + MetaIdleMonitorWatch *watch = user_data; + + _meta_idle_monitor_watch_fire (watch); + g_source_set_ready_time (watch->timeout_source, -1); + return TRUE; +} + +static GSourceFuncs native_source_funcs = { + NULL, /* prepare */ + NULL, /* check */ + native_dispatch_timeout, + NULL, /* finalize */ +}; + +static MetaIdleMonitorWatch * +meta_idle_monitor_native_make_watch (MetaIdleMonitor *monitor, + guint64 timeout_msec, + MetaIdleMonitorWatchFunc callback, + gpointer user_data, + GDestroyNotify notify) +{ + MetaIdleMonitorWatch *watch; + + watch = g_slice_new0 (MetaIdleMonitorWatch); + watch->monitor = monitor; + watch->id = get_next_watch_serial (); + watch->callback = callback; + watch->user_data = user_data; + watch->notify = notify; + watch->timeout_msec = timeout_msec; + + if (timeout_msec != 0) + { + GSource *source = g_source_new (&native_source_funcs, sizeof (GSource)); + + g_source_set_callback (source, NULL, watch, NULL); + g_source_set_ready_time (source, monitor->last_event_time + timeout_msec * 1000); + g_source_attach (source, NULL); + g_source_unref (source); + + watch->timeout_source = source; + } + + return watch; +} + +static void +meta_idle_monitor_native_class_init (MetaIdleMonitorNativeClass *klass) +{ + MetaIdleMonitorClass *idle_monitor_class = META_IDLE_MONITOR_CLASS (klass); + + idle_monitor_class->get_idletime = meta_idle_monitor_native_get_idletime; + idle_monitor_class->make_watch = meta_idle_monitor_native_make_watch; +} + +static void +meta_idle_monitor_native_init (MetaIdleMonitorNative *monitor) +{ +} + +typedef struct { + MetaIdleMonitor *monitor; + GList *fired_watches; +} CheckNativeClosure; + +static gboolean +check_native_watch (gpointer key, + gpointer value, + gpointer user_data) +{ + MetaIdleMonitorWatch *watch = value; + CheckNativeClosure *closure = user_data; + gboolean steal; + + if (watch->timeout_msec == 0) + { + closure->fired_watches = g_list_prepend (closure->fired_watches, watch); + steal = TRUE; + } + else + { + g_source_set_ready_time (watch->timeout_source, + closure->monitor->last_event_time + + watch->timeout_msec * 1000); + steal = FALSE; + } + + return steal; +} + +static void +fire_native_watch (gpointer watch, + gpointer data) +{ + _meta_idle_monitor_watch_fire (watch); +} + +void +meta_idle_monitor_native_reset_idletime (MetaIdleMonitor *monitor) +{ + CheckNativeClosure closure; + + monitor->last_event_time = g_get_monotonic_time (); + + closure.monitor = monitor; + closure.fired_watches = NULL; + g_hash_table_foreach_steal (monitor->watches, check_native_watch, &closure); + + g_list_foreach (closure.fired_watches, fire_native_watch, NULL); + g_list_free (closure.fired_watches); +} diff --git a/src/core/meta-idle-monitor-native.h b/src/core/meta-idle-monitor-native.h new file mode 100644 index 000000000..37745c489 --- /dev/null +++ b/src/core/meta-idle-monitor-native.h @@ -0,0 +1,43 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright 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, see . + * + * Adapted from gnome-session/gnome-session/gs-idle-monitor.c and + * from gnome-desktop/libgnome-desktop/gnome-idle-monitor.c + */ + +#ifndef META_IDLE_MONITOR_NATIVE_H +#define META_IDLE_MONITOR_NATIVE_H + +#include +#include + +#define META_TYPE_IDLE_MONITOR_NATIVE (meta_idle_monitor_native_get_type ()) +#define META_IDLE_MONITOR_NATIVE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_IDLE_MONITOR_NATIVE, MetaIdleMonitorNative)) +#define META_IDLE_MONITOR_NATIVE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_IDLE_MONITOR_NATIVE, MetaIdleMonitorNativeClass)) +#define META_IS_IDLE_MONITOR_NATIVE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_IDLE_MONITOR_NATIVE)) +#define META_IS_IDLE_MONITOR_NATIVE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_IDLE_MONITOR_NATIVE)) +#define META_IDLE_MONITOR_NATIVE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_IDLE_MONITOR_NATIVE, MetaIdleMonitorNativeClass)) + +typedef struct _MetaIdleMonitorNative MetaIdleMonitorNative; +typedef struct _MetaIdleMonitorNativeClass MetaIdleMonitorNativeClass; + +GType meta_idle_monitor_native_get_type (void); + +void meta_idle_monitor_native_reset_idletime (MetaIdleMonitor *monitor); + +#endif /* META_IDLE_MONITOR_NATIVE_H */ diff --git a/src/core/meta-idle-monitor-private.h b/src/core/meta-idle-monitor-private.h index aabd1cc3b..b34ca83d1 100644 --- a/src/core/meta-idle-monitor-private.h +++ b/src/core/meta-idle-monitor-private.h @@ -20,8 +20,62 @@ * from gnome-desktop/libgnome-desktop/gnome-idle-monitor.c */ +#ifndef META_IDLE_MONITOR_PRIVATE_H +#define META_IDLE_MONITOR_PRIVATE_H + #include +#include "display-private.h" -void meta_idle_monitor_handle_xevent_all (XEvent *xevent); +#include +#include -void meta_idle_monitor_reset_idletime (MetaIdleMonitor *monitor); +typedef struct +{ + MetaIdleMonitor *monitor; + guint id; + MetaIdleMonitorWatchFunc callback; + gpointer user_data; + GDestroyNotify notify; + guint64 timeout_msec; + + /* x11 */ + XSyncAlarm xalarm; + int idle_source_id; + + /* wayland */ + GSource *timeout_source; +} MetaIdleMonitorWatch; + +struct _MetaIdleMonitor +{ + GObject parent_instance; + + GHashTable *watches; + GHashTable *alarms; + int device_id; + + /* X11 implementation */ + Display *display; + int sync_event_base; + XSyncCounter counter; + XSyncAlarm user_active_alarm; + + /* Wayland implementation */ + guint64 last_event_time; +}; + +struct _MetaIdleMonitorClass +{ + GObjectClass parent_class; + + gint64 (*get_idletime) (MetaIdleMonitor *monitor); + MetaIdleMonitorWatch * (*make_watch) (MetaIdleMonitor *monitor, + guint64 timeout_msec, + MetaIdleMonitorWatchFunc callback, + gpointer user_data, + GDestroyNotify notify); +}; + +void _meta_idle_monitor_watch_fire (MetaIdleMonitorWatch *watch); + +#endif /* META_IDLE_MONITOR_PRIVATE_H */ diff --git a/src/core/meta-idle-monitor-xsync.c b/src/core/meta-idle-monitor-xsync.c new file mode 100644 index 000000000..b1f47ba18 --- /dev/null +++ b/src/core/meta-idle-monitor-xsync.c @@ -0,0 +1,311 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright 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, see . + * + * Adapted from gnome-session/gnome-session/gs-idle-monitor.c and + * from gnome-desktop/libgnome-desktop/gnome-idle-monitor.c + */ + +#include "config.h" + +#include "meta-idle-monitor-xsync.h" +#include "meta-idle-monitor-private.h" + +#include +#include "display-private.h" + +#include + +struct _MetaIdleMonitorXSync +{ + MetaIdleMonitor parent; +}; + +struct _MetaIdleMonitorXSyncClass +{ + MetaIdleMonitorClass parent_class; +}; + +G_DEFINE_TYPE (MetaIdleMonitorXSync, meta_idle_monitor_xsync, META_TYPE_IDLE_MONITOR) + +static gint64 +_xsyncvalue_to_int64 (XSyncValue value) +{ + return ((guint64) XSyncValueHigh32 (value)) << 32 + | (guint64) XSyncValueLow32 (value); +} + +#define GUINT64_TO_XSYNCVALUE(value, ret) XSyncIntsToValue (ret, (value) & 0xFFFFFFFF, ((guint64)(value)) >> 32) + +static XSyncAlarm +_xsync_alarm_set (MetaIdleMonitor *monitor, + XSyncTestType test_type, + guint64 interval, + gboolean want_events) +{ + XSyncAlarmAttributes attr; + XSyncValue delta; + guint flags; + + flags = XSyncCACounter | XSyncCAValueType | XSyncCATestType | + XSyncCAValue | XSyncCADelta | XSyncCAEvents; + + XSyncIntToValue (&delta, 0); + attr.trigger.counter = monitor->counter; + attr.trigger.value_type = XSyncAbsolute; + attr.delta = delta; + attr.events = want_events; + + GUINT64_TO_XSYNCVALUE (interval, &attr.trigger.wait_value); + attr.trigger.test_type = test_type; + return XSyncCreateAlarm (monitor->display, flags, &attr); +} + +static void +ensure_alarm_rescheduled (Display *dpy, + XSyncAlarm alarm) +{ + XSyncAlarmAttributes attr; + + /* Some versions of Xorg have an issue where alarms aren't + * always rescheduled. Calling XSyncChangeAlarm, even + * without any attributes, will reschedule the alarm. */ + XSyncChangeAlarm (dpy, alarm, 0, &attr); +} + +static void +set_alarm_enabled (Display *dpy, + XSyncAlarm alarm, + gboolean enabled) +{ + XSyncAlarmAttributes attr; + attr.events = enabled; + XSyncChangeAlarm (dpy, alarm, XSyncCAEvents, &attr); +} + +static void +check_x11_watch (gpointer data, + gpointer user_data) +{ + MetaIdleMonitorWatch *watch = data; + XSyncAlarm alarm = (XSyncAlarm) user_data; + + if (watch->xalarm != alarm) + return; + + _meta_idle_monitor_watch_fire (watch); +} + +static char * +counter_name_for_device (int device_id) +{ + if (device_id > 0) + return g_strdup_printf ("DEVICEIDLETIME %d", device_id); + + return g_strdup ("IDLETIME"); +} + +static XSyncCounter +find_idletime_counter (MetaIdleMonitor *monitor) +{ + int i; + int ncounters; + XSyncSystemCounter *counters; + XSyncCounter counter = None; + char *counter_name; + + counter_name = counter_name_for_device (monitor->device_id); + counters = XSyncListSystemCounters (monitor->display, &ncounters); + for (i = 0; i < ncounters; i++) + { + if (counters[i].name != NULL && strcmp (counters[i].name, counter_name) == 0) + { + counter = counters[i].counter; + break; + } + } + XSyncFreeSystemCounterList (counters); + g_free (counter_name); + + return counter; +} + +static void +init_xsync (MetaIdleMonitor *monitor) +{ + monitor->counter = find_idletime_counter (monitor); + /* IDLETIME counter not found? */ + if (monitor->counter == None) + { + g_warning ("IDLETIME counter not found\n"); + return; + } + + monitor->user_active_alarm = _xsync_alarm_set (monitor, XSyncNegativeTransition, 1, FALSE); +} + +static void +meta_idle_monitor_xsync_dispose (GObject *object) +{ + MetaIdleMonitor *monitor = META_IDLE_MONITOR (object); + + if (monitor->user_active_alarm != None) + { + XSyncDestroyAlarm (monitor->display, monitor->user_active_alarm); + monitor->user_active_alarm = None; + } + + G_OBJECT_CLASS (meta_idle_monitor_xsync_parent_class)->dispose (object); +} + +static void +meta_idle_monitor_xsync_constructed (GObject *object) +{ + MetaIdleMonitor *monitor = META_IDLE_MONITOR (object); + + g_assert (!meta_is_wayland_compositor ()); + + monitor->display = meta_get_display ()->xdisplay; + init_xsync (monitor); + + G_OBJECT_CLASS (meta_idle_monitor_xsync_parent_class)->constructed (object); +} + +static gint64 +meta_idle_monitor_xsync_get_idletime (MetaIdleMonitor *monitor) +{ + XSyncValue value; + + if (!XSyncQueryCounter (monitor->display, monitor->counter, &value)) + return -1; + + return _xsyncvalue_to_int64 (value); +} + +static gboolean +fire_watch_idle (gpointer data) +{ + MetaIdleMonitorWatch *watch = data; + + watch->idle_source_id = 0; + _meta_idle_monitor_watch_fire (watch); + + return FALSE; +} + +static guint32 +get_next_watch_serial (void) +{ + static guint32 serial = 0; + g_atomic_int_inc (&serial); + return serial; +} + +static MetaIdleMonitorWatch * +meta_idle_monitor_xsync_make_watch (MetaIdleMonitor *monitor, + guint64 timeout_msec, + MetaIdleMonitorWatchFunc callback, + gpointer user_data, + GDestroyNotify notify) +{ + MetaIdleMonitorWatch *watch; + + watch = g_slice_new0 (MetaIdleMonitorWatch); + watch->monitor = monitor; + watch->id = get_next_watch_serial (); + watch->callback = callback; + watch->user_data = user_data; + watch->notify = notify; + watch->timeout_msec = timeout_msec; + + if (monitor->user_active_alarm != None) + { + if (timeout_msec != 0) + { + watch->xalarm = _xsync_alarm_set (monitor, XSyncPositiveTransition, timeout_msec, TRUE); + + g_hash_table_add (monitor->alarms, (gpointer) watch->xalarm); + + if (meta_idle_monitor_get_idletime (monitor) > (gint64)timeout_msec) + watch->idle_source_id = g_idle_add (fire_watch_idle, watch); + } + else + { + watch->xalarm = monitor->user_active_alarm; + + set_alarm_enabled (monitor->display, monitor->user_active_alarm, TRUE); + } + } + + return watch; +} + +static void +meta_idle_monitor_xsync_class_init (MetaIdleMonitorXSyncClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + MetaIdleMonitorClass *idle_monitor_class = META_IDLE_MONITOR_CLASS (klass); + + object_class->dispose = meta_idle_monitor_xsync_dispose; + object_class->constructed = meta_idle_monitor_xsync_constructed; + + idle_monitor_class->get_idletime = meta_idle_monitor_xsync_get_idletime; + idle_monitor_class->make_watch = meta_idle_monitor_xsync_make_watch; +} + +static void +meta_idle_monitor_xsync_init (MetaIdleMonitorXSync *monitor) +{ +} + +void +meta_idle_monitor_xsync_handle_xevent (MetaIdleMonitor *monitor, + XSyncAlarmNotifyEvent *alarm_event) +{ + XSyncAlarm alarm; + GList *watches; + gboolean has_alarm; + + if (alarm_event->state != XSyncAlarmActive) + return; + + alarm = alarm_event->alarm; + + has_alarm = FALSE; + + if (alarm == monitor->user_active_alarm) + { + set_alarm_enabled (monitor->display, + alarm, + FALSE); + has_alarm = TRUE; + } + else if (g_hash_table_contains (monitor->alarms, (gpointer) alarm)) + { + ensure_alarm_rescheduled (monitor->display, + alarm); + has_alarm = TRUE; + } + + if (has_alarm) + { + watches = g_hash_table_get_values (monitor->watches); + + g_list_foreach (watches, check_x11_watch, (gpointer) alarm); + g_list_free (watches); + } +} diff --git a/src/core/meta-idle-monitor-xsync.h b/src/core/meta-idle-monitor-xsync.h new file mode 100644 index 000000000..f8e88f09e --- /dev/null +++ b/src/core/meta-idle-monitor-xsync.h @@ -0,0 +1,49 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright 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, see . + * + * Adapted from gnome-session/gnome-session/gs-idle-monitor.c and + * from gnome-desktop/libgnome-desktop/gnome-idle-monitor.c + */ + +#ifndef META_IDLE_MONITOR_XSYNC_H +#define META_IDLE_MONITOR_XSYNC_H + +#include +#include + +#include +#include + +#define META_TYPE_IDLE_MONITOR_XSYNC (meta_idle_monitor_xsync_get_type ()) +#define META_IDLE_MONITOR_XSYNC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_IDLE_MONITOR_XSYNC, MetaIdleMonitorXSync)) +#define META_IDLE_MONITOR_XSYNC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_IDLE_MONITOR_XSYNC, MetaIdleMonitorXSyncClass)) +#define META_IS_IDLE_MONITOR_XSYNC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_IDLE_MONITOR_XSYNC)) +#define META_IS_IDLE_MONITOR_XSYNC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_IDLE_MONITOR_XSYNC)) +#define META_IDLE_MONITOR_XSYNC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_IDLE_MONITOR_XSYNC, MetaIdleMonitorXSyncClass)) + +typedef struct _MetaIdleMonitorXSync MetaIdleMonitorXSync; +typedef struct _MetaIdleMonitorXSyncClass MetaIdleMonitorXSyncClass; + +GType meta_idle_monitor_xsync_get_type (void); + +void meta_idle_monitor_xsync_handle_xevent (MetaIdleMonitor *monitor, + XSyncAlarmNotifyEvent *xevent); + +void meta_idle_monitor_xsync_handle_xevent_all (XEvent *xevent); + +#endif /* META_IDLE_MONITOR_XSYNC_H */ diff --git a/src/core/meta-idle-monitor.c b/src/core/meta-idle-monitor.c index 7af248584..522727004 100644 --- a/src/core/meta-idle-monitor.c +++ b/src/core/meta-idle-monitor.c @@ -38,50 +38,11 @@ #include #include "meta-idle-monitor-private.h" #include "meta-idle-monitor-dbus.h" -#include "display-private.h" +#include "meta-idle-monitor-xsync.h" +#include "meta-idle-monitor-native.h" G_STATIC_ASSERT(sizeof(unsigned long) == sizeof(gpointer)); -struct _MetaIdleMonitor -{ - GObject parent_instance; - - GHashTable *watches; - GHashTable *alarms; - int device_id; - - /* X11 implementation */ - Display *display; - int sync_event_base; - XSyncCounter counter; - XSyncAlarm user_active_alarm; - - /* Wayland implementation */ - guint64 last_event_time; -}; - -struct _MetaIdleMonitorClass -{ - GObjectClass parent_class; -}; - -typedef struct -{ - MetaIdleMonitor *monitor; - guint id; - MetaIdleMonitorWatchFunc callback; - gpointer user_data; - GDestroyNotify notify; - guint64 timeout_msec; - - /* x11 */ - XSyncAlarm xalarm; - int idle_source_id; - - /* wayland */ - GSource *timeout_source; -} MetaIdleMonitorWatch; - enum { PROP_0, @@ -96,8 +57,8 @@ G_DEFINE_TYPE (MetaIdleMonitor, meta_idle_monitor, G_TYPE_OBJECT) static MetaIdleMonitor *device_monitors[256]; static int device_id_max; -static void -fire_watch (MetaIdleMonitorWatch *watch) +void +_meta_idle_monitor_watch_fire (MetaIdleMonitorWatch *watch) { MetaIdleMonitor *monitor; guint id; @@ -124,164 +85,6 @@ fire_watch (MetaIdleMonitorWatch *watch) g_object_unref (monitor); } -static gint64 -_xsyncvalue_to_int64 (XSyncValue value) -{ - return ((guint64) XSyncValueHigh32 (value)) << 32 - | (guint64) XSyncValueLow32 (value); -} - -#define GUINT64_TO_XSYNCVALUE(value, ret) XSyncIntsToValue (ret, (value) & 0xFFFFFFFF, ((guint64)(value)) >> 32) - -static XSyncAlarm -_xsync_alarm_set (MetaIdleMonitor *monitor, - XSyncTestType test_type, - guint64 interval, - gboolean want_events) -{ - XSyncAlarmAttributes attr; - XSyncValue delta; - guint flags; - - flags = XSyncCACounter | XSyncCAValueType | XSyncCATestType | - XSyncCAValue | XSyncCADelta | XSyncCAEvents; - - XSyncIntToValue (&delta, 0); - attr.trigger.counter = monitor->counter; - attr.trigger.value_type = XSyncAbsolute; - attr.delta = delta; - attr.events = want_events; - - GUINT64_TO_XSYNCVALUE (interval, &attr.trigger.wait_value); - attr.trigger.test_type = test_type; - return XSyncCreateAlarm (monitor->display, flags, &attr); -} - -static void -ensure_alarm_rescheduled (Display *dpy, - XSyncAlarm alarm) -{ - XSyncAlarmAttributes attr; - - /* Some versions of Xorg have an issue where alarms aren't - * always rescheduled. Calling XSyncChangeAlarm, even - * without any attributes, will reschedule the alarm. */ - XSyncChangeAlarm (dpy, alarm, 0, &attr); -} - -static void -set_alarm_enabled (Display *dpy, - XSyncAlarm alarm, - gboolean enabled) -{ - XSyncAlarmAttributes attr; - attr.events = enabled; - XSyncChangeAlarm (dpy, alarm, XSyncCAEvents, &attr); -} - -static void -check_x11_watch (gpointer data, - gpointer user_data) -{ - MetaIdleMonitorWatch *watch = data; - XSyncAlarm alarm = (XSyncAlarm) user_data; - - if (watch->xalarm != alarm) - return; - - fire_watch (watch); -} - -static void -meta_idle_monitor_handle_xevent (MetaIdleMonitor *monitor, - XSyncAlarmNotifyEvent *alarm_event) -{ - XSyncAlarm alarm; - GList *watches; - gboolean has_alarm; - - if (alarm_event->state != XSyncAlarmActive) - return; - - alarm = alarm_event->alarm; - - has_alarm = FALSE; - - if (alarm == monitor->user_active_alarm) - { - set_alarm_enabled (monitor->display, - alarm, - FALSE); - has_alarm = TRUE; - } - else if (g_hash_table_contains (monitor->alarms, (gpointer) alarm)) - { - ensure_alarm_rescheduled (monitor->display, - alarm); - has_alarm = TRUE; - } - - if (has_alarm) - { - watches = g_hash_table_get_values (monitor->watches); - - g_list_foreach (watches, check_x11_watch, (gpointer) alarm); - g_list_free (watches); - } -} - -void -meta_idle_monitor_handle_xevent_all (XEvent *xevent) -{ - int i; - - for (i = 0; i <= device_id_max; i++) - if (device_monitors[i]) - meta_idle_monitor_handle_xevent (device_monitors[i], (XSyncAlarmNotifyEvent*)xevent); -} - -static char * -counter_name_for_device (int device_id) -{ - if (device_id > 0) - return g_strdup_printf ("DEVICEIDLETIME %d", device_id); - - return g_strdup ("IDLETIME"); -} - -static XSyncCounter -find_idletime_counter (MetaIdleMonitor *monitor) -{ - int i; - int ncounters; - XSyncSystemCounter *counters; - XSyncCounter counter = None; - char *counter_name; - - counter_name = counter_name_for_device (monitor->device_id); - counters = XSyncListSystemCounters (monitor->display, &ncounters); - for (i = 0; i < ncounters; i++) - { - if (counters[i].name != NULL && strcmp (counters[i].name, counter_name) == 0) - { - counter = counters[i].counter; - break; - } - } - XSyncFreeSystemCounterList (counters); - g_free (counter_name); - - return counter; -} - -static guint32 -get_next_watch_serial (void) -{ - static guint32 serial = 0; - g_atomic_int_inc (&serial); - return serial; -} - static void idle_monitor_watch_free (MetaIdleMonitorWatch *watch) { @@ -316,36 +119,14 @@ idle_monitor_watch_free (MetaIdleMonitorWatch *watch) g_slice_free (MetaIdleMonitorWatch, watch); } -static void -init_xsync (MetaIdleMonitor *monitor) -{ - monitor->counter = find_idletime_counter (monitor); - /* IDLETIME counter not found? */ - if (monitor->counter == None) - { - meta_warning ("IDLETIME counter not found\n"); - return; - } - - monitor->user_active_alarm = _xsync_alarm_set (monitor, XSyncNegativeTransition, 1, FALSE); -} - static void meta_idle_monitor_dispose (GObject *object) { - MetaIdleMonitor *monitor; - - monitor = META_IDLE_MONITOR (object); + MetaIdleMonitor *monitor = META_IDLE_MONITOR (object); g_clear_pointer (&monitor->watches, g_hash_table_destroy); g_clear_pointer (&monitor->alarms, g_hash_table_destroy); - if (monitor->user_active_alarm != None) - { - XSyncDestroyAlarm (monitor->display, monitor->user_active_alarm); - monitor->user_active_alarm = None; - } - G_OBJECT_CLASS (meta_idle_monitor_parent_class)->dispose (object); } @@ -386,25 +167,12 @@ meta_idle_monitor_set_property (GObject *object, } } -static void -meta_idle_monitor_constructed (GObject *object) -{ - MetaIdleMonitor *monitor = META_IDLE_MONITOR (object); - - if (!meta_is_wayland_compositor ()) - { - monitor->display = meta_get_display ()->xdisplay; - init_xsync (monitor); - } -} - static void meta_idle_monitor_class_init (MetaIdleMonitorClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->dispose = meta_idle_monitor_dispose; - object_class->constructed = meta_idle_monitor_constructed; object_class->get_property = meta_idle_monitor_get_property; object_class->set_property = meta_idle_monitor_set_property; @@ -433,13 +201,24 @@ meta_idle_monitor_init (MetaIdleMonitor *monitor) monitor->alarms = g_hash_table_new (NULL, NULL); } +static GType +get_idle_monitor_type (void) +{ + if (meta_is_wayland_compositor ()) + return META_TYPE_IDLE_MONITOR_NATIVE; + else + return META_TYPE_IDLE_MONITOR_XSYNC; +} + static void ensure_device_monitor (int device_id) { if (device_monitors[device_id]) return; - device_monitors[device_id] = g_object_new (META_TYPE_IDLE_MONITOR, "device-id", device_id, NULL); + device_monitors[device_id] = g_object_new (get_idle_monitor_type (), + "device-id", device_id, + NULL); device_id_max = MAX (device_id_max, device_id); } @@ -483,85 +262,20 @@ meta_idle_monitor_get_for_device (int device_id) return device_monitors[device_id]; } -static gboolean -wayland_dispatch_timeout (GSource *source, - GSourceFunc callback, - gpointer user_data) -{ - MetaIdleMonitorWatch *watch = user_data; - - fire_watch (watch); - g_source_set_ready_time (watch->timeout_source, -1); - return TRUE; -} - -static GSourceFuncs wayland_source_funcs = { - NULL, /* prepare */ - NULL, /* check */ - wayland_dispatch_timeout, - NULL, /* finalize */ -}; - -static gboolean -fire_watch_idle (gpointer data) -{ - MetaIdleMonitorWatch *watch = data; - - watch->idle_source_id = 0; - fire_watch (watch); - - return FALSE; -} - static MetaIdleMonitorWatch * make_watch (MetaIdleMonitor *monitor, guint64 timeout_msec, - MetaIdleMonitorWatchFunc callback, - gpointer user_data, - GDestroyNotify notify) + MetaIdleMonitorWatchFunc callback, + gpointer user_data, + GDestroyNotify notify) { MetaIdleMonitorWatch *watch; - watch = g_slice_new0 (MetaIdleMonitorWatch); - watch->monitor = monitor; - watch->id = get_next_watch_serial (); - watch->callback = callback; - watch->user_data = user_data; - watch->notify = notify; - watch->timeout_msec = timeout_msec; - - if (meta_is_wayland_compositor ()) - { - if (timeout_msec != 0) - { - GSource *source = g_source_new (&wayland_source_funcs, sizeof (GSource)); - - g_source_set_callback (source, NULL, watch, NULL); - g_source_set_ready_time (source, monitor->last_event_time + timeout_msec * 1000); - g_source_attach (source, NULL); - g_source_unref (source); - - watch->timeout_source = source; - } - } - else if (monitor->user_active_alarm != None) - { - if (timeout_msec != 0) - { - watch->xalarm = _xsync_alarm_set (monitor, XSyncPositiveTransition, timeout_msec, TRUE); - - g_hash_table_add (monitor->alarms, (gpointer) watch->xalarm); - - if (meta_idle_monitor_get_idletime (monitor) > (gint64)timeout_msec) - watch->idle_source_id = g_idle_add (fire_watch_idle, watch); - } - else - { - watch->xalarm = monitor->user_active_alarm; - - set_alarm_enabled (monitor->display, monitor->user_active_alarm, TRUE); - } - } + watch = META_IDLE_MONITOR_GET_CLASS (monitor)->make_watch (monitor, + timeout_msec, + callback, + user_data, + notify); g_hash_table_insert (monitor->watches, GUINT_TO_POINTER (watch->id), @@ -668,23 +382,6 @@ meta_idle_monitor_remove_watch (MetaIdleMonitor *monitor, g_object_unref (monitor); } -static gint64 -meta_idle_monitor_get_idletime_wayland (MetaIdleMonitor *monitor) -{ - return (g_get_monotonic_time () - monitor->last_event_time) / 1000; -} - -static gint64 -meta_idle_monitor_get_idletime_x11 (MetaIdleMonitor *monitor) -{ - XSyncValue value; - - if (!XSyncQueryCounter (monitor->display, monitor->counter, &value)) - return -1; - - return _xsyncvalue_to_int64 (value); -} - /** * meta_idle_monitor_get_idletime: * @monitor: A #MetaIdleMonitor @@ -694,61 +391,17 @@ meta_idle_monitor_get_idletime_x11 (MetaIdleMonitor *monitor) gint64 meta_idle_monitor_get_idletime (MetaIdleMonitor *monitor) { - if (meta_is_wayland_compositor ()) - return meta_idle_monitor_get_idletime_wayland (monitor); - else - return meta_idle_monitor_get_idletime_x11 (monitor); -} - -typedef struct { - MetaIdleMonitor *monitor; - GList *fired_watches; -} CheckWaylandClosure; - -static gboolean -check_wayland_watch (gpointer key, - gpointer value, - gpointer user_data) -{ - MetaIdleMonitorWatch *watch = value; - CheckWaylandClosure *closure = user_data; - gboolean steal; - - if (watch->timeout_msec == 0) - { - closure->fired_watches = g_list_prepend (closure->fired_watches, watch); - steal = TRUE; - } - else - { - g_source_set_ready_time (watch->timeout_source, - closure->monitor->last_event_time + - watch->timeout_msec * 1000); - steal = FALSE; - } - - return steal; -} - -static void -fire_wayland_watch (gpointer watch, - gpointer data) -{ - fire_watch (watch); + return META_IDLE_MONITOR_GET_CLASS (monitor)->get_idletime (monitor); } void -meta_idle_monitor_reset_idletime (MetaIdleMonitor *monitor) +meta_idle_monitor_xsync_handle_xevent_all (XEvent *xevent) { - CheckWaylandClosure closure; + int i; - monitor->last_event_time = g_get_monotonic_time (); + g_assert (!meta_is_wayland_compositor ()); - closure.monitor = monitor; - closure.fired_watches = NULL; - g_hash_table_foreach_steal (monitor->watches, check_wayland_watch, &closure); - - g_list_foreach (closure.fired_watches, fire_wayland_watch, NULL); - g_list_free (closure.fired_watches); + for (i = 0; i <= device_id_max; i++) + if (device_monitors[i]) + meta_idle_monitor_xsync_handle_xevent (device_monitors[i], (XSyncAlarmNotifyEvent*)xevent); } - From 61d8b35254ee4b1683d09b6ee32dd2ce71e2ef79 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sun, 30 Mar 2014 22:30:54 -0400 Subject: [PATCH 769/889] idle-monitor: Move watch implementations to be private to the subclass --- src/core/meta-idle-monitor-native.c | 52 +++++++++++++++++++++++--- src/core/meta-idle-monitor-private.h | 6 --- src/core/meta-idle-monitor-xsync.c | 56 ++++++++++++++++++++++++---- src/core/meta-idle-monitor.c | 39 ------------------- 4 files changed, 95 insertions(+), 58 deletions(-) diff --git a/src/core/meta-idle-monitor-native.c b/src/core/meta-idle-monitor-native.c index eb3ab6a26..a2c5c3a61 100644 --- a/src/core/meta-idle-monitor-native.c +++ b/src/core/meta-idle-monitor-native.c @@ -40,6 +40,12 @@ struct _MetaIdleMonitorNativeClass MetaIdleMonitorClass parent_class; }; +typedef struct { + MetaIdleMonitorWatch base; + + GSource *timeout_source; +} MetaIdleMonitorWatchNative; + G_DEFINE_TYPE (MetaIdleMonitorNative, meta_idle_monitor_native, META_TYPE_IDLE_MONITOR) static gint64 @@ -61,10 +67,11 @@ native_dispatch_timeout (GSource *source, GSourceFunc callback, gpointer user_data) { - MetaIdleMonitorWatch *watch = user_data; + MetaIdleMonitorWatchNative *watch_native = user_data; + MetaIdleMonitorWatch *watch = (MetaIdleMonitorWatch *) watch; _meta_idle_monitor_watch_fire (watch); - g_source_set_ready_time (watch->timeout_source, -1); + g_source_set_ready_time (watch_native->timeout_source, -1); return TRUE; } @@ -75,6 +82,31 @@ static GSourceFuncs native_source_funcs = { NULL, /* finalize */ }; +static void +free_watch (gpointer data) +{ + MetaIdleMonitorWatchNative *watch_native = data; + MetaIdleMonitorWatch *watch = (MetaIdleMonitorWatch *) watch_native; + MetaIdleMonitor *monitor = watch->monitor; + + g_object_ref (monitor); + + if (watch->idle_source_id) + { + g_source_remove (watch->idle_source_id); + watch->idle_source_id = 0; + } + + if (watch->notify != NULL) + watch->notify (watch->user_data); + + if (watch_native->timeout_source != NULL) + g_source_destroy (watch_native->timeout_source); + + g_object_unref (monitor); + g_slice_free (MetaIdleMonitorWatchNative, watch_native); +} + static MetaIdleMonitorWatch * meta_idle_monitor_native_make_watch (MetaIdleMonitor *monitor, guint64 timeout_msec, @@ -82,8 +114,12 @@ meta_idle_monitor_native_make_watch (MetaIdleMonitor *monitor, gpointer user_data, GDestroyNotify notify) { + MetaIdleMonitorWatchNative *watch_native; MetaIdleMonitorWatch *watch; + watch_native = g_slice_new0 (MetaIdleMonitorWatchNative); + watch = (MetaIdleMonitorWatch *) watch_native; + watch = g_slice_new0 (MetaIdleMonitorWatch); watch->monitor = monitor; watch->id = get_next_watch_serial (); @@ -101,7 +137,7 @@ meta_idle_monitor_native_make_watch (MetaIdleMonitor *monitor, g_source_attach (source, NULL); g_source_unref (source); - watch->timeout_source = source; + watch_native->timeout_source = source; } return watch; @@ -117,8 +153,11 @@ meta_idle_monitor_native_class_init (MetaIdleMonitorNativeClass *klass) } static void -meta_idle_monitor_native_init (MetaIdleMonitorNative *monitor) +meta_idle_monitor_native_init (MetaIdleMonitorNative *monitor_native) { + MetaIdleMonitor *monitor = META_IDLE_MONITOR (monitor_native); + + monitor->watches = g_hash_table_new_full (NULL, NULL, NULL, free_watch); } typedef struct { @@ -131,7 +170,8 @@ check_native_watch (gpointer key, gpointer value, gpointer user_data) { - MetaIdleMonitorWatch *watch = value; + MetaIdleMonitorWatchNative *watch_native = value; + MetaIdleMonitorWatch *watch = (MetaIdleMonitorWatch *) watch_native; CheckNativeClosure *closure = user_data; gboolean steal; @@ -142,7 +182,7 @@ check_native_watch (gpointer key, } else { - g_source_set_ready_time (watch->timeout_source, + g_source_set_ready_time (watch_native->timeout_source, closure->monitor->last_event_time + watch->timeout_msec * 1000); steal = FALSE; diff --git a/src/core/meta-idle-monitor-private.h b/src/core/meta-idle-monitor-private.h index b34ca83d1..f3fc4c732 100644 --- a/src/core/meta-idle-monitor-private.h +++ b/src/core/meta-idle-monitor-private.h @@ -37,13 +37,7 @@ typedef struct gpointer user_data; GDestroyNotify notify; guint64 timeout_msec; - - /* x11 */ - XSyncAlarm xalarm; int idle_source_id; - - /* wayland */ - GSource *timeout_source; } MetaIdleMonitorWatch; struct _MetaIdleMonitor diff --git a/src/core/meta-idle-monitor-xsync.c b/src/core/meta-idle-monitor-xsync.c index b1f47ba18..8d3fcc73c 100644 --- a/src/core/meta-idle-monitor-xsync.c +++ b/src/core/meta-idle-monitor-xsync.c @@ -40,6 +40,12 @@ struct _MetaIdleMonitorXSyncClass MetaIdleMonitorClass parent_class; }; +typedef struct { + MetaIdleMonitorWatch base; + + XSyncAlarm xalarm; +} MetaIdleMonitorWatchXSync; + G_DEFINE_TYPE (MetaIdleMonitorXSync, meta_idle_monitor_xsync, META_TYPE_IDLE_MONITOR) static gint64 @@ -101,10 +107,11 @@ static void check_x11_watch (gpointer data, gpointer user_data) { - MetaIdleMonitorWatch *watch = data; + MetaIdleMonitorWatchXSync *watch_xsync = data; + MetaIdleMonitorWatch *watch = (MetaIdleMonitorWatch *) watch_xsync; XSyncAlarm alarm = (XSyncAlarm) user_data; - if (watch->xalarm != alarm) + if (watch_xsync->xalarm != alarm) return; _meta_idle_monitor_watch_fire (watch); @@ -215,6 +222,35 @@ get_next_watch_serial (void) return serial; } +static void +free_watch (gpointer data) +{ + MetaIdleMonitorWatchXSync *watch_xsync = data; + MetaIdleMonitorWatch *watch = (MetaIdleMonitorWatch *) watch_xsync; + MetaIdleMonitor *monitor = watch->monitor; + + g_object_ref (monitor); + + if (watch->idle_source_id) + { + g_source_remove (watch->idle_source_id); + watch->idle_source_id = 0; + } + + if (watch->notify != NULL) + watch->notify (watch->user_data); + + if (watch_xsync->xalarm != monitor->user_active_alarm && + watch_xsync->xalarm != None) + { + XSyncDestroyAlarm (monitor->display, watch_xsync->xalarm); + g_hash_table_remove (monitor->alarms, (gpointer) watch_xsync->xalarm); + } + + g_object_unref (monitor); + g_slice_free (MetaIdleMonitorWatchXSync, watch_xsync); +} + static MetaIdleMonitorWatch * meta_idle_monitor_xsync_make_watch (MetaIdleMonitor *monitor, guint64 timeout_msec, @@ -222,9 +258,12 @@ meta_idle_monitor_xsync_make_watch (MetaIdleMonitor *monitor, gpointer user_data, GDestroyNotify notify) { + MetaIdleMonitorWatchXSync *watch_xsync; MetaIdleMonitorWatch *watch; - watch = g_slice_new0 (MetaIdleMonitorWatch); + watch_xsync = g_slice_new0 (MetaIdleMonitorWatchXSync); + watch = (MetaIdleMonitorWatch *) watch_xsync; + watch->monitor = monitor; watch->id = get_next_watch_serial (); watch->callback = callback; @@ -236,16 +275,16 @@ meta_idle_monitor_xsync_make_watch (MetaIdleMonitor *monitor, { if (timeout_msec != 0) { - watch->xalarm = _xsync_alarm_set (monitor, XSyncPositiveTransition, timeout_msec, TRUE); + watch_xsync->xalarm = _xsync_alarm_set (monitor, XSyncPositiveTransition, timeout_msec, TRUE); - g_hash_table_add (monitor->alarms, (gpointer) watch->xalarm); + g_hash_table_add (monitor->alarms, (gpointer) watch_xsync->xalarm); if (meta_idle_monitor_get_idletime (monitor) > (gint64)timeout_msec) watch->idle_source_id = g_idle_add (fire_watch_idle, watch); } else { - watch->xalarm = monitor->user_active_alarm; + watch_xsync->xalarm = monitor->user_active_alarm; set_alarm_enabled (monitor->display, monitor->user_active_alarm, TRUE); } @@ -268,8 +307,11 @@ meta_idle_monitor_xsync_class_init (MetaIdleMonitorXSyncClass *klass) } static void -meta_idle_monitor_xsync_init (MetaIdleMonitorXSync *monitor) +meta_idle_monitor_xsync_init (MetaIdleMonitorXSync *monitor_xsync) { + MetaIdleMonitor *monitor = META_IDLE_MONITOR (monitor_xsync); + + monitor->watches = g_hash_table_new_full (NULL, NULL, NULL, free_watch); } void diff --git a/src/core/meta-idle-monitor.c b/src/core/meta-idle-monitor.c index 522727004..4230679cc 100644 --- a/src/core/meta-idle-monitor.c +++ b/src/core/meta-idle-monitor.c @@ -85,40 +85,6 @@ _meta_idle_monitor_watch_fire (MetaIdleMonitorWatch *watch) g_object_unref (monitor); } -static void -idle_monitor_watch_free (MetaIdleMonitorWatch *watch) -{ - MetaIdleMonitor *monitor; - - if (watch == NULL) - return; - - monitor = watch->monitor; - g_object_ref (monitor); - - if (watch->idle_source_id) - { - g_source_remove (watch->idle_source_id); - watch->idle_source_id = 0; - } - - if (watch->notify != NULL) - watch->notify (watch->user_data); - - if (watch->xalarm != monitor->user_active_alarm && - watch->xalarm != None) - { - XSyncDestroyAlarm (monitor->display, watch->xalarm); - g_hash_table_remove (monitor->alarms, (gpointer) watch->xalarm); - } - - if (watch->timeout_source != NULL) - g_source_destroy (watch->timeout_source); - - g_object_unref (monitor); - g_slice_free (MetaIdleMonitorWatch, watch); -} - static void meta_idle_monitor_dispose (GObject *object) { @@ -193,11 +159,6 @@ meta_idle_monitor_class_init (MetaIdleMonitorClass *klass) static void meta_idle_monitor_init (MetaIdleMonitor *monitor) { - monitor->watches = g_hash_table_new_full (NULL, - NULL, - NULL, - (GDestroyNotify)idle_monitor_watch_free); - monitor->alarms = g_hash_table_new (NULL, NULL); } From 3961f291e44026fc75abfdd6cc01e0e9d0f8c571 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sun, 30 Mar 2014 22:33:49 -0400 Subject: [PATCH 770/889] idle-monitor: Move the alarms field to the XSync backend For whatever reason, this hash table was in the generic implementation section instead of the XSync implementation, even though it's only used by the XSync implementation. Use it as a first pass of things to move over. --- src/core/meta-idle-monitor-private.h | 1 - src/core/meta-idle-monitor-xsync.c | 17 +++++++++++++---- src/core/meta-idle-monitor.c | 2 -- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/core/meta-idle-monitor-private.h b/src/core/meta-idle-monitor-private.h index f3fc4c732..f2cc71641 100644 --- a/src/core/meta-idle-monitor-private.h +++ b/src/core/meta-idle-monitor-private.h @@ -45,7 +45,6 @@ struct _MetaIdleMonitor GObject parent_instance; GHashTable *watches; - GHashTable *alarms; int device_id; /* X11 implementation */ diff --git a/src/core/meta-idle-monitor-xsync.c b/src/core/meta-idle-monitor-xsync.c index 8d3fcc73c..df04a12d2 100644 --- a/src/core/meta-idle-monitor-xsync.c +++ b/src/core/meta-idle-monitor-xsync.c @@ -33,6 +33,8 @@ struct _MetaIdleMonitorXSync { MetaIdleMonitor parent; + + GHashTable *alarms; }; struct _MetaIdleMonitorXSyncClass @@ -168,7 +170,8 @@ init_xsync (MetaIdleMonitor *monitor) static void meta_idle_monitor_xsync_dispose (GObject *object) { - MetaIdleMonitor *monitor = META_IDLE_MONITOR (object); + MetaIdleMonitorXSync *monitor_xsync = META_IDLE_MONITOR_XSYNC (object); + MetaIdleMonitor *monitor = META_IDLE_MONITOR (monitor_xsync); if (monitor->user_active_alarm != None) { @@ -176,6 +179,8 @@ meta_idle_monitor_xsync_dispose (GObject *object) monitor->user_active_alarm = None; } + g_clear_pointer (&monitor_xsync->alarms, g_hash_table_destroy); + G_OBJECT_CLASS (meta_idle_monitor_xsync_parent_class)->dispose (object); } @@ -228,6 +233,7 @@ free_watch (gpointer data) MetaIdleMonitorWatchXSync *watch_xsync = data; MetaIdleMonitorWatch *watch = (MetaIdleMonitorWatch *) watch_xsync; MetaIdleMonitor *monitor = watch->monitor; + MetaIdleMonitorXSync *monitor_xsync = META_IDLE_MONITOR_XSYNC (monitor); g_object_ref (monitor); @@ -244,7 +250,7 @@ free_watch (gpointer data) watch_xsync->xalarm != None) { XSyncDestroyAlarm (monitor->display, watch_xsync->xalarm); - g_hash_table_remove (monitor->alarms, (gpointer) watch_xsync->xalarm); + g_hash_table_remove (monitor_xsync->alarms, (gpointer) watch_xsync->xalarm); } g_object_unref (monitor); @@ -258,6 +264,7 @@ meta_idle_monitor_xsync_make_watch (MetaIdleMonitor *monitor, gpointer user_data, GDestroyNotify notify) { + MetaIdleMonitorXSync *monitor_xsync = META_IDLE_MONITOR_XSYNC (monitor); MetaIdleMonitorWatchXSync *watch_xsync; MetaIdleMonitorWatch *watch; @@ -277,7 +284,7 @@ meta_idle_monitor_xsync_make_watch (MetaIdleMonitor *monitor, { watch_xsync->xalarm = _xsync_alarm_set (monitor, XSyncPositiveTransition, timeout_msec, TRUE); - g_hash_table_add (monitor->alarms, (gpointer) watch_xsync->xalarm); + g_hash_table_add (monitor_xsync->alarms, (gpointer) watch_xsync->xalarm); if (meta_idle_monitor_get_idletime (monitor) > (gint64)timeout_msec) watch->idle_source_id = g_idle_add (fire_watch_idle, watch); @@ -312,12 +319,14 @@ meta_idle_monitor_xsync_init (MetaIdleMonitorXSync *monitor_xsync) MetaIdleMonitor *monitor = META_IDLE_MONITOR (monitor_xsync); monitor->watches = g_hash_table_new_full (NULL, NULL, NULL, free_watch); + monitor_xsync->alarms = g_hash_table_new (NULL, NULL); } void meta_idle_monitor_xsync_handle_xevent (MetaIdleMonitor *monitor, XSyncAlarmNotifyEvent *alarm_event) { + MetaIdleMonitorXSync *monitor_xsync = META_IDLE_MONITOR_XSYNC (monitor); XSyncAlarm alarm; GList *watches; gboolean has_alarm; @@ -336,7 +345,7 @@ meta_idle_monitor_xsync_handle_xevent (MetaIdleMonitor *monitor, FALSE); has_alarm = TRUE; } - else if (g_hash_table_contains (monitor->alarms, (gpointer) alarm)) + else if (g_hash_table_contains (monitor_xsync->alarms, (gpointer) alarm)) { ensure_alarm_rescheduled (monitor->display, alarm); diff --git a/src/core/meta-idle-monitor.c b/src/core/meta-idle-monitor.c index 4230679cc..faa89b3a4 100644 --- a/src/core/meta-idle-monitor.c +++ b/src/core/meta-idle-monitor.c @@ -91,7 +91,6 @@ meta_idle_monitor_dispose (GObject *object) MetaIdleMonitor *monitor = META_IDLE_MONITOR (object); g_clear_pointer (&monitor->watches, g_hash_table_destroy); - g_clear_pointer (&monitor->alarms, g_hash_table_destroy); G_OBJECT_CLASS (meta_idle_monitor_parent_class)->dispose (object); } @@ -159,7 +158,6 @@ meta_idle_monitor_class_init (MetaIdleMonitorClass *klass) static void meta_idle_monitor_init (MetaIdleMonitor *monitor) { - monitor->alarms = g_hash_table_new (NULL, NULL); } static GType From 422f2e5fe6643874ed93045fe1b5ff4eafc396e5 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sun, 30 Mar 2014 23:00:10 -0400 Subject: [PATCH 771/889] idle-monitor: Kill off an unused field --- src/core/meta-idle-monitor-private.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/meta-idle-monitor-private.h b/src/core/meta-idle-monitor-private.h index f2cc71641..85084629d 100644 --- a/src/core/meta-idle-monitor-private.h +++ b/src/core/meta-idle-monitor-private.h @@ -49,7 +49,6 @@ struct _MetaIdleMonitor /* X11 implementation */ Display *display; - int sync_event_base; XSyncCounter counter; XSyncAlarm user_active_alarm; From f842ea6d15d9036cc4f482aa7c00530d0fdc1827 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sun, 30 Mar 2014 22:59:46 -0400 Subject: [PATCH 772/889] idle-monitor: Make the rest of the implementation-specific fields private --- src/core/meta-idle-monitor-native.c | 18 ++++++--- src/core/meta-idle-monitor-private.h | 12 +----- src/core/meta-idle-monitor-xsync.c | 58 +++++++++++++++------------- 3 files changed, 45 insertions(+), 43 deletions(-) diff --git a/src/core/meta-idle-monitor-native.c b/src/core/meta-idle-monitor-native.c index a2c5c3a61..75b4e5a28 100644 --- a/src/core/meta-idle-monitor-native.c +++ b/src/core/meta-idle-monitor-native.c @@ -33,6 +33,8 @@ struct _MetaIdleMonitorNative { MetaIdleMonitor parent; + + guint64 last_event_time; }; struct _MetaIdleMonitorNativeClass @@ -51,7 +53,9 @@ G_DEFINE_TYPE (MetaIdleMonitorNative, meta_idle_monitor_native, META_TYPE_IDLE_M static gint64 meta_idle_monitor_native_get_idletime (MetaIdleMonitor *monitor) { - return (g_get_monotonic_time () - monitor->last_event_time) / 1000; + MetaIdleMonitorNative *monitor_native = META_IDLE_MONITOR_NATIVE (monitor); + + return (g_get_monotonic_time () - monitor_native->last_event_time) / 1000; } static guint32 @@ -116,6 +120,7 @@ meta_idle_monitor_native_make_watch (MetaIdleMonitor *monitor, { MetaIdleMonitorWatchNative *watch_native; MetaIdleMonitorWatch *watch; + MetaIdleMonitorNative *monitor_native = META_IDLE_MONITOR_NATIVE (monitor); watch_native = g_slice_new0 (MetaIdleMonitorWatchNative); watch = (MetaIdleMonitorWatch *) watch_native; @@ -133,7 +138,7 @@ meta_idle_monitor_native_make_watch (MetaIdleMonitor *monitor, GSource *source = g_source_new (&native_source_funcs, sizeof (GSource)); g_source_set_callback (source, NULL, watch, NULL); - g_source_set_ready_time (source, monitor->last_event_time + timeout_msec * 1000); + g_source_set_ready_time (source, monitor_native->last_event_time + timeout_msec * 1000); g_source_attach (source, NULL); g_source_unref (source); @@ -161,7 +166,7 @@ meta_idle_monitor_native_init (MetaIdleMonitorNative *monitor_native) } typedef struct { - MetaIdleMonitor *monitor; + MetaIdleMonitorNative *monitor_native; GList *fired_watches; } CheckNativeClosure; @@ -183,7 +188,7 @@ check_native_watch (gpointer key, else { g_source_set_ready_time (watch_native->timeout_source, - closure->monitor->last_event_time + + closure->monitor_native->last_event_time + watch->timeout_msec * 1000); steal = FALSE; } @@ -201,11 +206,12 @@ fire_native_watch (gpointer watch, void meta_idle_monitor_native_reset_idletime (MetaIdleMonitor *monitor) { + MetaIdleMonitorNative *monitor_native = META_IDLE_MONITOR_NATIVE (monitor); CheckNativeClosure closure; - monitor->last_event_time = g_get_monotonic_time (); + monitor_native->last_event_time = g_get_monotonic_time (); - closure.monitor = monitor; + closure.monitor_native = monitor_native; closure.fired_watches = NULL; g_hash_table_foreach_steal (monitor->watches, check_native_watch, &closure); diff --git a/src/core/meta-idle-monitor-private.h b/src/core/meta-idle-monitor-private.h index 85084629d..ea414e162 100644 --- a/src/core/meta-idle-monitor-private.h +++ b/src/core/meta-idle-monitor-private.h @@ -44,16 +44,8 @@ struct _MetaIdleMonitor { GObject parent_instance; - GHashTable *watches; - int device_id; - - /* X11 implementation */ - Display *display; - XSyncCounter counter; - XSyncAlarm user_active_alarm; - - /* Wayland implementation */ - guint64 last_event_time; + GHashTable *watches; + int device_id; }; struct _MetaIdleMonitorClass diff --git a/src/core/meta-idle-monitor-xsync.c b/src/core/meta-idle-monitor-xsync.c index df04a12d2..25338a775 100644 --- a/src/core/meta-idle-monitor-xsync.c +++ b/src/core/meta-idle-monitor-xsync.c @@ -34,7 +34,10 @@ struct _MetaIdleMonitorXSync { MetaIdleMonitor parent; - GHashTable *alarms; + GHashTable *alarms; + Display *display; + XSyncCounter counter; + XSyncAlarm user_active_alarm; }; struct _MetaIdleMonitorXSyncClass @@ -60,7 +63,7 @@ _xsyncvalue_to_int64 (XSyncValue value) #define GUINT64_TO_XSYNCVALUE(value, ret) XSyncIntsToValue (ret, (value) & 0xFFFFFFFF, ((guint64)(value)) >> 32) static XSyncAlarm -_xsync_alarm_set (MetaIdleMonitor *monitor, +_xsync_alarm_set (MetaIdleMonitorXSync *monitor_xsync, XSyncTestType test_type, guint64 interval, gboolean want_events) @@ -73,14 +76,14 @@ _xsync_alarm_set (MetaIdleMonitor *monitor, XSyncCAValue | XSyncCADelta | XSyncCAEvents; XSyncIntToValue (&delta, 0); - attr.trigger.counter = monitor->counter; + attr.trigger.counter = monitor_xsync->counter; attr.trigger.value_type = XSyncAbsolute; attr.delta = delta; attr.events = want_events; GUINT64_TO_XSYNCVALUE (interval, &attr.trigger.wait_value); attr.trigger.test_type = test_type; - return XSyncCreateAlarm (monitor->display, flags, &attr); + return XSyncCreateAlarm (monitor_xsync->display, flags, &attr); } static void @@ -129,8 +132,9 @@ counter_name_for_device (int device_id) } static XSyncCounter -find_idletime_counter (MetaIdleMonitor *monitor) +find_idletime_counter (MetaIdleMonitorXSync *monitor_xsync) { + MetaIdleMonitor *monitor = META_IDLE_MONITOR (monitor_xsync); int i; int ncounters; XSyncSystemCounter *counters; @@ -138,7 +142,7 @@ find_idletime_counter (MetaIdleMonitor *monitor) char *counter_name; counter_name = counter_name_for_device (monitor->device_id); - counters = XSyncListSystemCounters (monitor->display, &ncounters); + counters = XSyncListSystemCounters (monitor_xsync->display, &ncounters); for (i = 0; i < ncounters; i++) { if (counters[i].name != NULL && strcmp (counters[i].name, counter_name) == 0) @@ -154,29 +158,28 @@ find_idletime_counter (MetaIdleMonitor *monitor) } static void -init_xsync (MetaIdleMonitor *monitor) +init_xsync (MetaIdleMonitorXSync *monitor_xsync) { - monitor->counter = find_idletime_counter (monitor); + monitor_xsync->counter = find_idletime_counter (monitor_xsync); /* IDLETIME counter not found? */ - if (monitor->counter == None) + if (monitor_xsync->counter == None) { g_warning ("IDLETIME counter not found\n"); return; } - monitor->user_active_alarm = _xsync_alarm_set (monitor, XSyncNegativeTransition, 1, FALSE); + monitor_xsync->user_active_alarm = _xsync_alarm_set (monitor_xsync, XSyncNegativeTransition, 1, FALSE); } static void meta_idle_monitor_xsync_dispose (GObject *object) { MetaIdleMonitorXSync *monitor_xsync = META_IDLE_MONITOR_XSYNC (object); - MetaIdleMonitor *monitor = META_IDLE_MONITOR (monitor_xsync); - if (monitor->user_active_alarm != None) + if (monitor_xsync->user_active_alarm != None) { - XSyncDestroyAlarm (monitor->display, monitor->user_active_alarm); - monitor->user_active_alarm = None; + XSyncDestroyAlarm (monitor_xsync->display, monitor_xsync->user_active_alarm); + monitor_xsync->user_active_alarm = None; } g_clear_pointer (&monitor_xsync->alarms, g_hash_table_destroy); @@ -187,12 +190,12 @@ meta_idle_monitor_xsync_dispose (GObject *object) static void meta_idle_monitor_xsync_constructed (GObject *object) { - MetaIdleMonitor *monitor = META_IDLE_MONITOR (object); + MetaIdleMonitorXSync *monitor_xsync = META_IDLE_MONITOR_XSYNC (object); g_assert (!meta_is_wayland_compositor ()); - monitor->display = meta_get_display ()->xdisplay; - init_xsync (monitor); + monitor_xsync->display = meta_get_display ()->xdisplay; + init_xsync (monitor_xsync); G_OBJECT_CLASS (meta_idle_monitor_xsync_parent_class)->constructed (object); } @@ -200,9 +203,10 @@ meta_idle_monitor_xsync_constructed (GObject *object) static gint64 meta_idle_monitor_xsync_get_idletime (MetaIdleMonitor *monitor) { + MetaIdleMonitorXSync *monitor_xsync = META_IDLE_MONITOR_XSYNC (monitor); XSyncValue value; - if (!XSyncQueryCounter (monitor->display, monitor->counter, &value)) + if (!XSyncQueryCounter (monitor_xsync->display, monitor_xsync->counter, &value)) return -1; return _xsyncvalue_to_int64 (value); @@ -246,10 +250,10 @@ free_watch (gpointer data) if (watch->notify != NULL) watch->notify (watch->user_data); - if (watch_xsync->xalarm != monitor->user_active_alarm && + if (watch_xsync->xalarm != monitor_xsync->user_active_alarm && watch_xsync->xalarm != None) { - XSyncDestroyAlarm (monitor->display, watch_xsync->xalarm); + XSyncDestroyAlarm (monitor_xsync->display, watch_xsync->xalarm); g_hash_table_remove (monitor_xsync->alarms, (gpointer) watch_xsync->xalarm); } @@ -278,11 +282,11 @@ meta_idle_monitor_xsync_make_watch (MetaIdleMonitor *monitor, watch->notify = notify; watch->timeout_msec = timeout_msec; - if (monitor->user_active_alarm != None) + if (monitor_xsync->user_active_alarm != None) { if (timeout_msec != 0) { - watch_xsync->xalarm = _xsync_alarm_set (monitor, XSyncPositiveTransition, timeout_msec, TRUE); + watch_xsync->xalarm = _xsync_alarm_set (monitor_xsync, XSyncPositiveTransition, timeout_msec, TRUE); g_hash_table_add (monitor_xsync->alarms, (gpointer) watch_xsync->xalarm); @@ -291,9 +295,9 @@ meta_idle_monitor_xsync_make_watch (MetaIdleMonitor *monitor, } else { - watch_xsync->xalarm = monitor->user_active_alarm; + watch_xsync->xalarm = monitor_xsync->user_active_alarm; - set_alarm_enabled (monitor->display, monitor->user_active_alarm, TRUE); + set_alarm_enabled (monitor_xsync->display, monitor_xsync->user_active_alarm, TRUE); } } @@ -338,16 +342,16 @@ meta_idle_monitor_xsync_handle_xevent (MetaIdleMonitor *monitor, has_alarm = FALSE; - if (alarm == monitor->user_active_alarm) + if (alarm == monitor_xsync->user_active_alarm) { - set_alarm_enabled (monitor->display, + set_alarm_enabled (monitor_xsync->display, alarm, FALSE); has_alarm = TRUE; } else if (g_hash_table_contains (monitor_xsync->alarms, (gpointer) alarm)) { - ensure_alarm_rescheduled (monitor->display, + ensure_alarm_rescheduled (monitor_xsync->display, alarm); has_alarm = TRUE; } From b93176d89aa7c802cb628f35a42b230aa07678ec Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sun, 30 Mar 2014 23:06:01 -0400 Subject: [PATCH 773/889] cursor-tracker: Kill off an unused include --- src/core/meta-cursor-tracker-private.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/meta-cursor-tracker-private.h b/src/core/meta-cursor-tracker-private.h index deaa5acd1..835036acb 100644 --- a/src/core/meta-cursor-tracker-private.h +++ b/src/core/meta-cursor-tracker-private.h @@ -24,7 +24,6 @@ #include #include -#include gboolean meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker, XEvent *xevent); From a15a4faff062d103d740a35df74ce0f3f2a731ba Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 31 Mar 2014 15:08:43 -0400 Subject: [PATCH 774/889] cursor-tracker: Remove unused constants --- src/core/meta-cursor-tracker.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/core/meta-cursor-tracker.c b/src/core/meta-cursor-tracker.c index 37dd9faac..1faaf1bc8 100644 --- a/src/core/meta-cursor-tracker.c +++ b/src/core/meta-cursor-tracker.c @@ -51,9 +51,6 @@ #include "wayland/meta-wayland-private.h" -#define META_WAYLAND_DEFAULT_CURSOR_HOTSPOT_X 7 -#define META_WAYLAND_DEFAULT_CURSOR_HOTSPOT_Y 4 - typedef struct { CoglTexture2D *texture; struct gbm_bo *bo; From a7ea2cd36576a6bb157fced75c69922760d5fd12 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 31 Mar 2014 14:16:20 -0400 Subject: [PATCH 775/889] cursor-tracker: Shadowing is bad, don't do it --- src/core/meta-cursor-tracker.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/core/meta-cursor-tracker.c b/src/core/meta-cursor-tracker.c index 1faaf1bc8..cdf389f82 100644 --- a/src/core/meta-cursor-tracker.c +++ b/src/core/meta-cursor-tracker.c @@ -951,12 +951,10 @@ meta_cursor_tracker_queue_redraw (MetaCursorTracker *tracker) if (tracker->previous_is_valid) { - cairo_rectangle_int_t clip = { - .x = tracker->previous_rect.x, - .y = tracker->previous_rect.y, - .width = tracker->previous_rect.width, - .height = tracker->previous_rect.height - }; + clip.x = tracker->previous_rect.x; + clip.y = tracker->previous_rect.y; + clip.width = tracker->previous_rect.width; + clip.height = tracker->previous_rect.height; clutter_actor_queue_redraw_with_clip (stage, &clip); tracker->previous_is_valid = FALSE; } From 11de01741cee8fec904ccfff44ab1bdd8a8938f5 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 31 Mar 2014 14:16:54 -0400 Subject: [PATCH 776/889] cursor-tracker: Add a comment about what previous is It confused me a bit. --- src/core/meta-cursor-tracker.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/meta-cursor-tracker.c b/src/core/meta-cursor-tracker.c index cdf389f82..7480ed698 100644 --- a/src/core/meta-cursor-tracker.c +++ b/src/core/meta-cursor-tracker.c @@ -949,6 +949,7 @@ meta_cursor_tracker_queue_redraw (MetaCursorTracker *tracker) g_assert (meta_is_wayland_compositor ()); + /* Clear the location the cursor was at before, if we need to. */ if (tracker->previous_is_valid) { clip.x = tracker->previous_rect.x; From 08a8254debfa097d6574e1c3784d7b71597b4fb1 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 31 Mar 2014 14:18:48 -0400 Subject: [PATCH 777/889] cursor-tracker: Move ref_count to the top --- src/core/meta-cursor-tracker.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/meta-cursor-tracker.c b/src/core/meta-cursor-tracker.c index 7480ed698..84ccbf998 100644 --- a/src/core/meta-cursor-tracker.c +++ b/src/core/meta-cursor-tracker.c @@ -52,11 +52,11 @@ #include "wayland/meta-wayland-private.h" typedef struct { + int ref_count; + CoglTexture2D *texture; struct gbm_bo *bo; int hot_x, hot_y; - - int ref_count; } MetaCursorReference; struct _MetaCursorTracker { From b64d14ff4ac1a125a56a8df77cd41f1504f1d3bf Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 31 Mar 2014 14:26:28 -0400 Subject: [PATCH 778/889] cursor-tracker: Rearrange code Move take_texture closer to where it's used, and add hot_x / hot_y args. --- src/core/meta-cursor-tracker.c | 36 ++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/src/core/meta-cursor-tracker.c b/src/core/meta-cursor-tracker.c index 84ccbf998..b2a619f3b 100644 --- a/src/core/meta-cursor-tracker.c +++ b/src/core/meta-cursor-tracker.c @@ -341,19 +341,6 @@ meta_cursor_reference_from_theme (MetaCursorTracker *tracker, return self; } -static MetaCursorReference * -meta_cursor_reference_take_texture (CoglTexture2D *texture) -{ - MetaCursorReference *self; - - self = g_slice_new0 (MetaCursorReference); - self->ref_count = 1; - - self->texture = texture; - - return self; -} - static MetaCursorReference * meta_cursor_reference_from_buffer (MetaCursorTracker *tracker, struct wl_resource *buffer, @@ -659,6 +646,22 @@ meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker, return TRUE; } +static MetaCursorReference * +meta_cursor_reference_take_texture (CoglTexture2D *texture, + int hot_x, + int hot_y) +{ + MetaCursorReference *self; + + self = g_slice_new0 (MetaCursorReference); + self->ref_count = 1; + self->texture = texture; + self->hot_x = hot_x; + self->hot_y = hot_y; + + return self; +} + static void ensure_xfixes_cursor (MetaCursorTracker *tracker) { @@ -715,10 +718,9 @@ ensure_xfixes_cursor (MetaCursorTracker *tracker) if (sprite != NULL) { - MetaCursorReference *cursor = meta_cursor_reference_take_texture (sprite); - cursor->hot_x = cursor_image->xhot; - cursor->hot_y = cursor_image->yhot; - + MetaCursorReference *cursor = meta_cursor_reference_take_texture (sprite, + cursor_image->xhot, + cursor_image->yhot); set_window_cursor (tracker, TRUE, cursor); } XFree (cursor_image); From 0aec98cf0245f5a0383ce2555933ec331ff3a671 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 31 Mar 2014 18:26:18 -0400 Subject: [PATCH 779/889] idle-monitor: Hack out assert fail It seems that we're getting XSyncAlarmNotify events here as a Wayland compositor for some reason. Just hack this one out for now. --- src/core/meta-idle-monitor.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/meta-idle-monitor.c b/src/core/meta-idle-monitor.c index faa89b3a4..85affc580 100644 --- a/src/core/meta-idle-monitor.c +++ b/src/core/meta-idle-monitor.c @@ -358,7 +358,8 @@ meta_idle_monitor_xsync_handle_xevent_all (XEvent *xevent) { int i; - g_assert (!meta_is_wayland_compositor ()); + if (!meta_is_wayland_compositor ()) + return; for (i = 0; i <= device_id_max; i++) if (device_monitors[i]) From 5f52f55916b29e87f321137f7ef04936482a8f68 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 31 Mar 2014 14:08:14 -0400 Subject: [PATCH 780/889] cursor-tracker: Start moving some code to a new file I want the MetaCursorTracker to mostly be about retrieving cursor information. Start moving the code that loads cursor images to a new file, MetaCursor. Eventually, MetaCursorTracker's APIs will all take MetaCursorReferences, and we can have a clean backend split here. --- src/Makefile.am | 3 +++ src/core/meta-cursor-private.h | 38 +++++++++++++++++++++++++++ src/core/meta-cursor-tracker.c | 33 +---------------------- src/core/meta-cursor.c | 48 ++++++++++++++++++++++++++++++++++ src/core/meta-cursor.h | 30 +++++++++++++++++++++ 5 files changed, 120 insertions(+), 32 deletions(-) create mode 100644 src/core/meta-cursor-private.h create mode 100644 src/core/meta-cursor.c create mode 100644 src/core/meta-cursor.h diff --git a/src/Makefile.am b/src/Makefile.am index c81d0963d..5f432724f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -127,6 +127,9 @@ libmutter_wayland_la_SOURCES = \ core/keybindings.c \ core/keybindings-private.h \ core/main.c \ + core/meta-cursor.c \ + core/meta-cursor.h \ + core/meta-cursor-private.h \ core/meta-cursor-tracker.c \ core/meta-cursor-tracker-private.h \ core/meta-idle-monitor.c \ diff --git a/src/core/meta-cursor-private.h b/src/core/meta-cursor-private.h new file mode 100644 index 000000000..14d3ec64e --- /dev/null +++ b/src/core/meta-cursor-private.h @@ -0,0 +1,38 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright 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, see . + * + * Author: Giovanni Campagna + */ + +#ifndef META_CURSOR_PRIVATE_H +#define META_CURSOR_PRIVATE_H + +#include "meta-cursor.h" + +#include +#include + +struct _MetaCursorReference { + int ref_count; + + CoglTexture2D *texture; + struct gbm_bo *bo; + int hot_x, hot_y; +}; + +#endif /* META_CURSOR_PRIVATE_H */ diff --git a/src/core/meta-cursor-tracker.c b/src/core/meta-cursor-tracker.c index b2a619f3b..5c315fca6 100644 --- a/src/core/meta-cursor-tracker.c +++ b/src/core/meta-cursor-tracker.c @@ -45,20 +45,13 @@ #include #include +#include "meta-cursor-private.h" #include "meta-cursor-tracker-private.h" #include "screen-private.h" #include "monitor-private.h" #include "wayland/meta-wayland-private.h" -typedef struct { - int ref_count; - - CoglTexture2D *texture; - struct gbm_bo *bo; - int hot_x, hot_y; -} MetaCursorReference; - struct _MetaCursorTracker { GObject parent_instance; @@ -123,30 +116,6 @@ static void meta_cursor_tracker_set_crtc_has_hw_cursor (MetaCursorTracker *track gboolean has_hw_cursor); static void sync_cursor (MetaCursorTracker *tracker); -static MetaCursorReference * -meta_cursor_reference_ref (MetaCursorReference *self) -{ - g_assert (self->ref_count > 0); - self->ref_count++; - - return self; -} - -static void -meta_cursor_reference_unref (MetaCursorReference *self) -{ - self->ref_count--; - - if (self->ref_count == 0) - { - cogl_object_unref (self->texture); - if (self->bo) - gbm_bo_destroy (self->bo); - - g_slice_free (MetaCursorReference, self); - } -} - static void translate_meta_cursor (MetaCursor cursor, guint *glyph_out, diff --git a/src/core/meta-cursor.c b/src/core/meta-cursor.c new file mode 100644 index 000000000..822fd11d9 --- /dev/null +++ b/src/core/meta-cursor.c @@ -0,0 +1,48 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright 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, see . + * + * Author: Giovanni Campagna + */ + +#include "config.h" + +#include "meta-cursor-private.h" + +MetaCursorReference * +meta_cursor_reference_ref (MetaCursorReference *self) +{ + g_assert (self->ref_count > 0); + self->ref_count++; + + return self; +} + +void +meta_cursor_reference_unref (MetaCursorReference *self) +{ + self->ref_count--; + + if (self->ref_count == 0) + { + cogl_object_unref (self->texture); + if (self->bo) + gbm_bo_destroy (self->bo); + + g_slice_free (MetaCursorReference, self); + } +} diff --git a/src/core/meta-cursor.h b/src/core/meta-cursor.h new file mode 100644 index 000000000..6d5bc3ec3 --- /dev/null +++ b/src/core/meta-cursor.h @@ -0,0 +1,30 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright 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, see . + * + * Author: Giovanni Campagna + */ + +#ifndef META_CURSOR_H +#define META_CURSOR_H + +typedef struct _MetaCursorReference MetaCursorReference; + +MetaCursorReference * meta_cursor_reference_ref (MetaCursorReference *cursor); +void meta_cursor_reference_unref (MetaCursorReference *cursor); + +#endif /* META_CURSOR_H */ From 863569b70248470f82893020853b5ef379378c76 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 31 Mar 2014 15:04:49 -0400 Subject: [PATCH 781/889] cursor-tracker: Split out the code that updates the new cursor --- src/core/meta-cursor-tracker.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/core/meta-cursor-tracker.c b/src/core/meta-cursor-tracker.c index 5c315fca6..cc698fbd0 100644 --- a/src/core/meta-cursor-tracker.c +++ b/src/core/meta-cursor-tracker.c @@ -886,6 +886,20 @@ get_displayed_cursor (MetaCursorTracker *tracker) return tracker->root_cursor; } +static void +update_displayed_cursor (MetaCursorTracker *tracker) +{ + if (meta_is_wayland_compositor ()) + { + if (tracker->displayed_cursor) + cogl_pipeline_set_layer_texture (tracker->pipeline, 0, COGL_TEXTURE (displayed_cursor->texture)); + else + cogl_pipeline_set_layer_texture (tracker->pipeline, 0, NULL); + + update_hw_cursor (tracker); + } +} + static void sync_displayed_cursor (MetaCursorTracker *tracker) { @@ -898,16 +912,7 @@ sync_displayed_cursor (MetaCursorTracker *tracker) if (displayed_cursor) tracker->displayed_cursor = meta_cursor_reference_ref (displayed_cursor); - if (meta_is_wayland_compositor ()) - { - if (displayed_cursor) - cogl_pipeline_set_layer_texture (tracker->pipeline, 0, COGL_TEXTURE (displayed_cursor->texture)); - else - cogl_pipeline_set_layer_texture (tracker->pipeline, 0, NULL); - - update_hw_cursor (tracker); - } - + update_displayed_cursor (tracker); g_signal_emit (tracker, signals[CURSOR_CHANGED], 0); } From 21425b583371774a2a6a636c8448fd5fbeac2b86 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 31 Mar 2014 15:21:19 -0400 Subject: [PATCH 782/889] cursor-tracker: Split the code that loads MetaCursorReferences out The plan here is to move the usage of these interfaces to the consumer, and then slam the code into backends. --- src/core/meta-cursor-tracker-private.h | 52 ++++ src/core/meta-cursor-tracker.c | 371 ------------------------- src/core/meta-cursor.c | 331 ++++++++++++++++++++++ src/core/meta-cursor.h | 12 + 4 files changed, 395 insertions(+), 371 deletions(-) diff --git a/src/core/meta-cursor-tracker-private.h b/src/core/meta-cursor-tracker-private.h index 835036acb..62b32d39f 100644 --- a/src/core/meta-cursor-tracker-private.h +++ b/src/core/meta-cursor-tracker-private.h @@ -25,6 +25,58 @@ #include #include +#include "meta-cursor.h" + +struct _MetaCursorTracker { + GObject parent_instance; + + MetaScreen *screen; + + gboolean is_showing; + gboolean has_hw_cursor; + + /* The cursor tracker stores the cursor for the current grab + * operation, the cursor for the window with pointer focus, and + * the cursor for the root window, which contains either the + * default arrow cursor or the 'busy' hourglass if we're launching + * an app. + * + * We choose the first one available -- if there's a grab cursor, + * we choose that cursor, if there's window cursor, we choose that, + * otherwise we choose the root cursor. + * + * The displayed_cursor contains the chosen cursor. + */ + MetaCursorReference *displayed_cursor; + + MetaCursorReference *grab_cursor; + + /* Wayland clients can set a NULL buffer as their cursor + * explicitly, which means that we shouldn't display anything. + * So, we can't simply store a NULL in window_cursor to + * determine an unset window cursor; we need an extra boolean. + */ + gboolean has_window_cursor; + MetaCursorReference *window_cursor; + + MetaCursorReference *root_cursor; + + MetaCursorReference *default_cursors[META_CURSOR_LAST]; + + int current_x, current_y; + MetaRectangle current_rect; + MetaRectangle previous_rect; + gboolean previous_is_valid; + + CoglPipeline *pipeline; + int drm_fd; + struct gbm_device *gbm; +}; + +struct _MetaCursorTrackerClass { + GObjectClass parent_class; +}; + gboolean meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker, XEvent *xevent); diff --git a/src/core/meta-cursor-tracker.c b/src/core/meta-cursor-tracker.c index cc698fbd0..d038109d1 100644 --- a/src/core/meta-cursor-tracker.c +++ b/src/core/meta-cursor-tracker.c @@ -41,10 +41,6 @@ #include #include -#include -#include -#include - #include "meta-cursor-private.h" #include "meta-cursor-tracker-private.h" #include "screen-private.h" @@ -52,56 +48,6 @@ #include "wayland/meta-wayland-private.h" -struct _MetaCursorTracker { - GObject parent_instance; - - MetaScreen *screen; - - gboolean is_showing; - gboolean has_hw_cursor; - - /* The cursor tracker stores the cursor for the current grab - * operation, the cursor for the window with pointer focus, and - * the cursor for the root window, which contains either the - * default arrow cursor or the 'busy' hourglass if we're launching - * an app. - * - * We choose the first one available -- if there's a grab cursor, - * we choose that cursor, if there's window cursor, we choose that, - * otherwise we choose the root cursor. - * - * The displayed_cursor contains the chosen cursor. - */ - MetaCursorReference *displayed_cursor; - - MetaCursorReference *grab_cursor; - - /* Wayland clients can set a NULL buffer as their cursor - * explicitly, which means that we shouldn't display anything. - * So, we can't simply store a NULL in window_cursor to - * determine an unset window cursor; we need an extra boolean. - */ - gboolean has_window_cursor; - MetaCursorReference *window_cursor; - - MetaCursorReference *root_cursor; - - MetaCursorReference *default_cursors[META_CURSOR_LAST]; - - int current_x, current_y; - MetaRectangle current_rect; - MetaRectangle previous_rect; - gboolean previous_is_valid; - - CoglPipeline *pipeline; - int drm_fd; - struct gbm_device *gbm; -}; - -struct _MetaCursorTrackerClass { - GObjectClass parent_class; -}; - G_DEFINE_TYPE (MetaCursorTracker, meta_cursor_tracker, G_TYPE_OBJECT); enum { @@ -116,323 +62,6 @@ static void meta_cursor_tracker_set_crtc_has_hw_cursor (MetaCursorTracker *track gboolean has_hw_cursor); static void sync_cursor (MetaCursorTracker *tracker); -static void -translate_meta_cursor (MetaCursor cursor, - guint *glyph_out, - const char **name_out) -{ - guint glyph = XC_num_glyphs; - const char *name = NULL; - - switch (cursor) - { - case META_CURSOR_DEFAULT: - glyph = XC_left_ptr; - break; - case META_CURSOR_NORTH_RESIZE: - glyph = XC_top_side; - break; - case META_CURSOR_SOUTH_RESIZE: - glyph = XC_bottom_side; - break; - case META_CURSOR_WEST_RESIZE: - glyph = XC_left_side; - break; - case META_CURSOR_EAST_RESIZE: - glyph = XC_right_side; - break; - case META_CURSOR_SE_RESIZE: - glyph = XC_bottom_right_corner; - break; - case META_CURSOR_SW_RESIZE: - glyph = XC_bottom_left_corner; - break; - case META_CURSOR_NE_RESIZE: - glyph = XC_top_right_corner; - break; - case META_CURSOR_NW_RESIZE: - glyph = XC_top_left_corner; - break; - case META_CURSOR_MOVE_OR_RESIZE_WINDOW: - glyph = XC_fleur; - break; - case META_CURSOR_BUSY: - glyph = XC_watch; - break; - case META_CURSOR_DND_IN_DRAG: - name = "dnd-none"; - break; - case META_CURSOR_DND_MOVE: - name = "dnd-move"; - break; - case META_CURSOR_DND_COPY: - name = "dnd-copy"; - break; - case META_CURSOR_DND_UNSUPPORTED_TARGET: - name = "dnd-none"; - break; - case META_CURSOR_POINTING_HAND: - glyph = XC_hand2; - break; - case META_CURSOR_CROSSHAIR: - glyph = XC_crosshair; - break; - case META_CURSOR_IBEAM: - glyph = XC_xterm; - break; - - default: - g_assert_not_reached (); - glyph = 0; /* silence compiler */ - break; - } - - *glyph_out = glyph; - *name_out = name; -} - -static Cursor -load_cursor_on_server (MetaDisplay *display, - MetaCursor cursor) -{ - Cursor xcursor; - guint glyph; - const char *name; - - translate_meta_cursor (cursor, &glyph, &name); - - if (name != NULL) - xcursor = XcursorLibraryLoadCursor (display->xdisplay, name); - else - xcursor = XCreateFontCursor (display->xdisplay, glyph); - - return xcursor; -} - -Cursor -meta_display_create_x_cursor (MetaDisplay *display, - MetaCursor cursor) -{ - return load_cursor_on_server (display, cursor); -} - -static XcursorImage * -load_cursor_on_client (MetaDisplay *display, - MetaCursor cursor) -{ - XcursorImage *image; - guint glyph; - const char *name; - const char *theme = XcursorGetTheme (display->xdisplay); - int size = XcursorGetDefaultSize (display->xdisplay); - - translate_meta_cursor (cursor, &glyph, &name); - - if (name != NULL) - image = XcursorLibraryLoadImage (name, theme, size); - else - image = XcursorShapeLoadImage (glyph, theme, size); - - return image; -} - -static MetaCursorReference * -meta_cursor_reference_from_theme (MetaCursorTracker *tracker, - MetaCursor cursor) -{ - XcursorImage *image; - int width, height, rowstride; - CoglPixelFormat cogl_format; - uint32_t gbm_format; - ClutterBackend *clutter_backend; - CoglContext *cogl_context; - MetaCursorReference *self; - - image = load_cursor_on_client (tracker->screen->display, cursor); - if (!image) - return NULL; - - width = image->width; - height = image->height; - rowstride = width * 4; - - gbm_format = GBM_FORMAT_ARGB8888; -#if G_BYTE_ORDER == G_LITTLE_ENDIAN - cogl_format = COGL_PIXEL_FORMAT_BGRA_8888; -#else - cogl_format = COGL_PIXEL_FORMAT_ARGB_8888; -#endif - - self = g_slice_new0 (MetaCursorReference); - self->ref_count = 1; - self->hot_x = image->xhot; - self->hot_y = image->yhot; - - clutter_backend = clutter_get_default_backend (); - cogl_context = clutter_backend_get_cogl_context (clutter_backend); - self->texture = cogl_texture_2d_new_from_data (cogl_context, - width, height, - cogl_format, - rowstride, - (uint8_t*)image->pixels, - NULL); - - if (tracker->gbm) - { - if (width > 64 || height > 64) - { - meta_warning ("Invalid theme cursor size (must be at most 64x64)\n"); - goto out; - } - - if (gbm_device_is_format_supported (tracker->gbm, gbm_format, - GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE)) - { - uint32_t buf[64 * 64]; - int i; - - self->bo = gbm_bo_create (tracker->gbm, 64, 64, - gbm_format, GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE); - - memset (buf, 0, sizeof(buf)); - for (i = 0; i < height; i++) - memcpy (buf + i * 64, image->pixels + i * width, width * 4); - - gbm_bo_write (self->bo, buf, 64 * 64 * 4); - } - else - meta_warning ("HW cursor for format %d not supported\n", gbm_format); - } - - out: - XcursorImageDestroy (image); - - return self; -} - -static MetaCursorReference * -meta_cursor_reference_from_buffer (MetaCursorTracker *tracker, - struct wl_resource *buffer, - int hot_x, - int hot_y) -{ - ClutterBackend *backend; - CoglContext *cogl_context; - MetaCursorReference *self; - CoglPixelFormat cogl_format; - struct wl_shm_buffer *shm_buffer; - uint32_t gbm_format; - - self = g_slice_new0 (MetaCursorReference); - self->ref_count = 1; - self->hot_x = hot_x; - self->hot_y = hot_y; - - backend = clutter_get_default_backend (); - cogl_context = clutter_backend_get_cogl_context (backend); - - shm_buffer = wl_shm_buffer_get (buffer); - if (shm_buffer) - { - int rowstride = wl_shm_buffer_get_stride (shm_buffer); - int width = wl_shm_buffer_get_width (shm_buffer); - int height = wl_shm_buffer_get_height (shm_buffer); - - switch (wl_shm_buffer_get_format (shm_buffer)) - { -#if G_BYTE_ORDER == G_BIG_ENDIAN - case WL_SHM_FORMAT_ARGB8888: - cogl_format = COGL_PIXEL_FORMAT_ARGB_8888_PRE; - gbm_format = GBM_FORMAT_ARGB8888; - break; - case WL_SHM_FORMAT_XRGB8888: - cogl_format = COGL_PIXEL_FORMAT_ARGB_8888; - gbm_format = GBM_FORMAT_XRGB8888; - break; -#else - case WL_SHM_FORMAT_ARGB8888: - cogl_format = COGL_PIXEL_FORMAT_BGRA_8888_PRE; - gbm_format = GBM_FORMAT_ARGB8888; - break; - case WL_SHM_FORMAT_XRGB8888: - cogl_format = COGL_PIXEL_FORMAT_BGRA_8888; - gbm_format = GBM_FORMAT_XRGB8888; - break; -#endif - default: - g_warn_if_reached (); - cogl_format = COGL_PIXEL_FORMAT_ARGB_8888; - gbm_format = GBM_FORMAT_ARGB8888; - } - - self->texture = cogl_texture_2d_new_from_data (cogl_context, - width, height, - cogl_format, - rowstride, - wl_shm_buffer_get_data (shm_buffer), - NULL); - - if (width > 64 || height > 64) - { - meta_warning ("Invalid cursor size (must be at most 64x64), falling back to software (GL) cursors\n"); - return self; - } - - if (tracker->gbm) - { - if (gbm_device_is_format_supported (tracker->gbm, gbm_format, - GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE)) - { - uint8_t *data; - uint8_t buf[4 * 64 * 64]; - int i; - - self->bo = gbm_bo_create (tracker->gbm, 64, 64, - gbm_format, GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE); - - data = wl_shm_buffer_get_data (shm_buffer); - memset (buf, 0, sizeof(buf)); - for (i = 0; i < height; i++) - memcpy (buf + i * 4 * 64, data + i * rowstride, 4 * width); - - gbm_bo_write (self->bo, buf, 64 * 64 * 4); - } - else - meta_warning ("HW cursor for format %d not supported\n", gbm_format); - } - } - else - { - int width, height; - - self->texture = cogl_wayland_texture_2d_new_from_buffer (cogl_context, buffer, NULL); - width = cogl_texture_get_width (COGL_TEXTURE (self->texture)); - height = cogl_texture_get_height (COGL_TEXTURE (self->texture)); - - /* HW cursors must be 64x64, but 64x64 is huge, and no cursor theme actually uses - that, so themed cursors must be padded with transparent pixels to fill the - overlay. This is trivial if we have CPU access to the data, but it's not - possible if the buffer is in GPU memory (and possibly tiled too), so if we - don't get the right size, we fallback to GL. - */ - if (width != 64 || height != 64) - { - meta_warning ("Invalid cursor size (must be 64x64), falling back to software (GL) cursors\n"); - return self; - } - - if (tracker->gbm) - { - self->bo = gbm_bo_import (tracker->gbm, GBM_BO_IMPORT_WL_BUFFER, - buffer, GBM_BO_USE_CURSOR_64X64); - if (!self->bo) - meta_warning ("Importing HW cursor from wl_buffer failed\n"); - } - } - - return self; -} - static void meta_cursor_tracker_init (MetaCursorTracker *self) { diff --git a/src/core/meta-cursor.c b/src/core/meta-cursor.c index 822fd11d9..5749054eb 100644 --- a/src/core/meta-cursor.c +++ b/src/core/meta-cursor.c @@ -23,6 +23,20 @@ #include "meta-cursor-private.h" +#include + +#include "display-private.h" +#include "screen-private.h" +#include "meta-cursor-tracker-private.h" /* for tracker->gbm */ + +#include + +#include +#include +#include + +#include + MetaCursorReference * meta_cursor_reference_ref (MetaCursorReference *self) { @@ -46,3 +60,320 @@ meta_cursor_reference_unref (MetaCursorReference *self) g_slice_free (MetaCursorReference, self); } } + +static void +translate_meta_cursor (MetaCursor cursor, + guint *glyph_out, + const char **name_out) +{ + guint glyph = XC_num_glyphs; + const char *name = NULL; + + switch (cursor) + { + case META_CURSOR_DEFAULT: + glyph = XC_left_ptr; + break; + case META_CURSOR_NORTH_RESIZE: + glyph = XC_top_side; + break; + case META_CURSOR_SOUTH_RESIZE: + glyph = XC_bottom_side; + break; + case META_CURSOR_WEST_RESIZE: + glyph = XC_left_side; + break; + case META_CURSOR_EAST_RESIZE: + glyph = XC_right_side; + break; + case META_CURSOR_SE_RESIZE: + glyph = XC_bottom_right_corner; + break; + case META_CURSOR_SW_RESIZE: + glyph = XC_bottom_left_corner; + break; + case META_CURSOR_NE_RESIZE: + glyph = XC_top_right_corner; + break; + case META_CURSOR_NW_RESIZE: + glyph = XC_top_left_corner; + break; + case META_CURSOR_MOVE_OR_RESIZE_WINDOW: + glyph = XC_fleur; + break; + case META_CURSOR_BUSY: + glyph = XC_watch; + break; + case META_CURSOR_DND_IN_DRAG: + name = "dnd-none"; + break; + case META_CURSOR_DND_MOVE: + name = "dnd-move"; + break; + case META_CURSOR_DND_COPY: + name = "dnd-copy"; + break; + case META_CURSOR_DND_UNSUPPORTED_TARGET: + name = "dnd-none"; + break; + case META_CURSOR_POINTING_HAND: + glyph = XC_hand2; + break; + case META_CURSOR_CROSSHAIR: + glyph = XC_crosshair; + break; + case META_CURSOR_IBEAM: + glyph = XC_xterm; + break; + + default: + g_assert_not_reached (); + glyph = 0; /* silence compiler */ + break; + } + + *glyph_out = glyph; + *name_out = name; +} + +static Cursor +load_cursor_on_server (MetaDisplay *display, + MetaCursor cursor) +{ + Cursor xcursor; + guint glyph; + const char *name; + + translate_meta_cursor (cursor, &glyph, &name); + + if (name != NULL) + xcursor = XcursorLibraryLoadCursor (display->xdisplay, name); + else + xcursor = XCreateFontCursor (display->xdisplay, glyph); + + return xcursor; +} + +Cursor +meta_display_create_x_cursor (MetaDisplay *display, + MetaCursor cursor) +{ + return load_cursor_on_server (display, cursor); +} + +static XcursorImage * +load_cursor_on_client (MetaDisplay *display, + MetaCursor cursor) +{ + XcursorImage *image; + guint glyph; + const char *name; + const char *theme = XcursorGetTheme (display->xdisplay); + int size = XcursorGetDefaultSize (display->xdisplay); + + translate_meta_cursor (cursor, &glyph, &name); + + if (name != NULL) + image = XcursorLibraryLoadImage (name, theme, size); + else + image = XcursorShapeLoadImage (glyph, theme, size); + + return image; +} + +MetaCursorReference * +meta_cursor_reference_from_theme (MetaCursorTracker *tracker, + MetaCursor cursor) +{ + XcursorImage *image; + int width, height, rowstride; + CoglPixelFormat cogl_format; + uint32_t gbm_format; + ClutterBackend *clutter_backend; + CoglContext *cogl_context; + MetaCursorReference *self; + + image = load_cursor_on_client (tracker->screen->display, cursor); + if (!image) + return NULL; + + width = image->width; + height = image->height; + rowstride = width * 4; + + gbm_format = GBM_FORMAT_ARGB8888; +#if G_BYTE_ORDER == G_LITTLE_ENDIAN + cogl_format = COGL_PIXEL_FORMAT_BGRA_8888; +#else + cogl_format = COGL_PIXEL_FORMAT_ARGB_8888; +#endif + + self = g_slice_new0 (MetaCursorReference); + self->ref_count = 1; + self->hot_x = image->xhot; + self->hot_y = image->yhot; + + clutter_backend = clutter_get_default_backend (); + cogl_context = clutter_backend_get_cogl_context (clutter_backend); + self->texture = cogl_texture_2d_new_from_data (cogl_context, + width, height, + cogl_format, + rowstride, + (uint8_t*)image->pixels, + NULL); + + if (tracker->gbm) + { + if (width > 64 || height > 64) + { + meta_warning ("Invalid theme cursor size (must be at most 64x64)\n"); + goto out; + } + + if (gbm_device_is_format_supported (tracker->gbm, gbm_format, + GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE)) + { + uint32_t buf[64 * 64]; + int i; + + self->bo = gbm_bo_create (tracker->gbm, 64, 64, + gbm_format, GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE); + + memset (buf, 0, sizeof(buf)); + for (i = 0; i < height; i++) + memcpy (buf + i * 64, image->pixels + i * width, width * 4); + + gbm_bo_write (self->bo, buf, 64 * 64 * 4); + } + else + meta_warning ("HW cursor for format %d not supported\n", gbm_format); + } + + out: + XcursorImageDestroy (image); + + return self; +} + +MetaCursorReference * +meta_cursor_reference_from_buffer (MetaCursorTracker *tracker, + struct wl_resource *buffer, + int hot_x, + int hot_y) +{ + ClutterBackend *backend; + CoglContext *cogl_context; + MetaCursorReference *self; + CoglPixelFormat cogl_format; + struct wl_shm_buffer *shm_buffer; + uint32_t gbm_format; + + self = g_slice_new0 (MetaCursorReference); + self->ref_count = 1; + self->hot_x = hot_x; + self->hot_y = hot_y; + + backend = clutter_get_default_backend (); + cogl_context = clutter_backend_get_cogl_context (backend); + + shm_buffer = wl_shm_buffer_get (buffer); + if (shm_buffer) + { + int rowstride = wl_shm_buffer_get_stride (shm_buffer); + int width = wl_shm_buffer_get_width (shm_buffer); + int height = wl_shm_buffer_get_height (shm_buffer); + + switch (wl_shm_buffer_get_format (shm_buffer)) + { +#if G_BYTE_ORDER == G_BIG_ENDIAN + case WL_SHM_FORMAT_ARGB8888: + cogl_format = COGL_PIXEL_FORMAT_ARGB_8888_PRE; + gbm_format = GBM_FORMAT_ARGB8888; + break; + case WL_SHM_FORMAT_XRGB8888: + cogl_format = COGL_PIXEL_FORMAT_ARGB_8888; + gbm_format = GBM_FORMAT_XRGB8888; + break; +#else + case WL_SHM_FORMAT_ARGB8888: + cogl_format = COGL_PIXEL_FORMAT_BGRA_8888_PRE; + gbm_format = GBM_FORMAT_ARGB8888; + break; + case WL_SHM_FORMAT_XRGB8888: + cogl_format = COGL_PIXEL_FORMAT_BGRA_8888; + gbm_format = GBM_FORMAT_XRGB8888; + break; +#endif + default: + g_warn_if_reached (); + cogl_format = COGL_PIXEL_FORMAT_ARGB_8888; + gbm_format = GBM_FORMAT_ARGB8888; + } + + self->texture = cogl_texture_2d_new_from_data (cogl_context, + width, height, + cogl_format, + rowstride, + wl_shm_buffer_get_data (shm_buffer), + NULL); + + if (width > 64 || height > 64) + { + meta_warning ("Invalid cursor size (must be at most 64x64), falling back to software (GL) cursors\n"); + return self; + } + + if (tracker->gbm) + { + if (gbm_device_is_format_supported (tracker->gbm, gbm_format, + GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE)) + { + uint8_t *data; + uint8_t buf[4 * 64 * 64]; + int i; + + self->bo = gbm_bo_create (tracker->gbm, 64, 64, + gbm_format, GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE); + + data = wl_shm_buffer_get_data (shm_buffer); + memset (buf, 0, sizeof(buf)); + for (i = 0; i < height; i++) + memcpy (buf + i * 4 * 64, data + i * rowstride, 4 * width); + + gbm_bo_write (self->bo, buf, 64 * 64 * 4); + } + else + meta_warning ("HW cursor for format %d not supported\n", gbm_format); + } + } + else + { + int width, height; + + self->texture = cogl_wayland_texture_2d_new_from_buffer (cogl_context, buffer, NULL); + width = cogl_texture_get_width (COGL_TEXTURE (self->texture)); + height = cogl_texture_get_height (COGL_TEXTURE (self->texture)); + + /* HW cursors must be 64x64, but 64x64 is huge, and no cursor theme actually uses + that, so themed cursors must be padded with transparent pixels to fill the + overlay. This is trivial if we have CPU access to the data, but it's not + possible if the buffer is in GPU memory (and possibly tiled too), so if we + don't get the right size, we fallback to GL. + */ + if (width != 64 || height != 64) + { + meta_warning ("Invalid cursor size (must be 64x64), falling back to software (GL) cursors\n"); + return self; + } + + if (tracker->gbm) + { + self->bo = gbm_bo_import (tracker->gbm, GBM_BO_IMPORT_WL_BUFFER, + buffer, GBM_BO_USE_CURSOR_64X64); + if (!self->bo) + meta_warning ("Importing HW cursor from wl_buffer failed\n"); + } + } + + return self; +} diff --git a/src/core/meta-cursor.h b/src/core/meta-cursor.h index 6d5bc3ec3..50ad086e7 100644 --- a/src/core/meta-cursor.h +++ b/src/core/meta-cursor.h @@ -27,4 +27,16 @@ typedef struct _MetaCursorReference MetaCursorReference; MetaCursorReference * meta_cursor_reference_ref (MetaCursorReference *cursor); void meta_cursor_reference_unref (MetaCursorReference *cursor); +#include +#include +#include + +MetaCursorReference * meta_cursor_reference_from_theme (MetaCursorTracker *tracker, + MetaCursor cursor); + +MetaCursorReference * meta_cursor_reference_from_buffer (MetaCursorTracker *tracker, + struct wl_resource *buffer, + int hot_x, + int hot_y); + #endif /* META_CURSOR_H */ From 383d4c7e4e47891a4c7544c1b27a6529e1b4fed5 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 31 Mar 2014 15:31:15 -0400 Subject: [PATCH 783/889] cursor: Introduce accessors for the texture / GBM bo We want to make this private, and have MetaCursorReference be backend-defined, with the texture possibly loaded on demand. We can't make the definition of MetaCursorReference truly private yet because of the XFixes cursor. A victim of MetaCursorTracker trying to do too many things at once... --- src/core/meta-cursor-private.h | 8 ++++++ src/core/meta-cursor-tracker.c | 50 +++++++++++++++++++++------------- src/core/meta-cursor.c | 24 ++++++++++++++++ 3 files changed, 63 insertions(+), 19 deletions(-) diff --git a/src/core/meta-cursor-private.h b/src/core/meta-cursor-private.h index 14d3ec64e..a5f04a730 100644 --- a/src/core/meta-cursor-private.h +++ b/src/core/meta-cursor-private.h @@ -35,4 +35,12 @@ struct _MetaCursorReference { int hot_x, hot_y; }; +CoglTexture *meta_cursor_reference_get_cogl_texture (MetaCursorReference *cursor, + int *hot_x, + int *hot_y); + +struct gbm_bo *meta_cursor_reference_get_gbm_bo (MetaCursorReference *cursor, + int *hot_x, + int *hot_y); + #endif /* META_CURSOR_PRIVATE_H */ diff --git a/src/core/meta-cursor-tracker.c b/src/core/meta-cursor-tracker.c index d038109d1..7338e2ad5 100644 --- a/src/core/meta-cursor-tracker.c +++ b/src/core/meta-cursor-tracker.c @@ -338,7 +338,7 @@ meta_cursor_tracker_get_sprite (MetaCursorTracker *tracker) ensure_xfixes_cursor (tracker); if (tracker->displayed_cursor) - return COGL_TEXTURE (tracker->displayed_cursor->texture); + return meta_cursor_reference_get_cogl_texture (tracker->displayed_cursor, NULL, NULL); else return NULL; } @@ -361,13 +361,7 @@ meta_cursor_tracker_get_hot (MetaCursorTracker *tracker, ensure_xfixes_cursor (tracker); if (tracker->displayed_cursor) - { - MetaCursorReference *displayed_cursor = tracker->displayed_cursor; - if (x) - *x = displayed_cursor->hot_x; - if (y) - *y = displayed_cursor->hot_y; - } + meta_cursor_reference_get_cogl_texture (tracker->displayed_cursor, x, y); else { if (x) @@ -446,6 +440,15 @@ meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker, } } +static gboolean +should_have_hw_cursor (MetaCursorTracker *tracker) +{ + if (tracker->displayed_cursor) + return (meta_cursor_reference_get_gbm_bo (tracker->displayed_cursor, NULL, NULL) != NULL); + else + return FALSE; +} + static void update_hw_cursor (MetaCursorTracker *tracker) { @@ -454,7 +457,7 @@ update_hw_cursor (MetaCursorTracker *tracker) unsigned int i, n_crtcs; gboolean enabled; - enabled = tracker->displayed_cursor && tracker->displayed_cursor->bo != NULL; + enabled = should_have_hw_cursor (tracker); tracker->has_hw_cursor = enabled; monitors = meta_monitor_manager_get (); @@ -521,7 +524,10 @@ update_displayed_cursor (MetaCursorTracker *tracker) if (meta_is_wayland_compositor ()) { if (tracker->displayed_cursor) - cogl_pipeline_set_layer_texture (tracker->pipeline, 0, COGL_TEXTURE (displayed_cursor->texture)); + { + CoglTexture *texture = meta_cursor_reference_get_cogl_texture (tracker->displayed_cursor, NULL, NULL); + cogl_pipeline_set_layer_texture (tracker->pipeline, 0, texture); + } else cogl_pipeline_set_layer_texture (tracker->pipeline, 0, NULL); @@ -585,10 +591,15 @@ sync_cursor (MetaCursorTracker *tracker) if (displayed_cursor) { - tracker->current_rect.x = tracker->current_x - displayed_cursor->hot_x; - tracker->current_rect.y = tracker->current_y - displayed_cursor->hot_y; - tracker->current_rect.width = cogl_texture_get_width (COGL_TEXTURE (displayed_cursor->texture)); - tracker->current_rect.height = cogl_texture_get_height (COGL_TEXTURE (displayed_cursor->texture)); + CoglTexture *texture; + int hot_x, hot_y; + + texture = meta_cursor_reference_get_cogl_texture (displayed_cursor, &hot_x, &hot_y); + + tracker->current_rect.x = tracker->current_x - hot_x; + tracker->current_rect.y = tracker->current_y - hot_y; + tracker->current_rect.width = cogl_texture_get_width (COGL_TEXTURE (texture)); + tracker->current_rect.height = cogl_texture_get_height (COGL_TEXTURE (texture)); } else { @@ -649,15 +660,16 @@ meta_cursor_tracker_set_crtc_has_hw_cursor (MetaCursorTracker *tracker, if (has) { MetaCursorReference *displayed_cursor = tracker->displayed_cursor; + struct gbm_bo *bo; union gbm_bo_handle handle; int width, height; int hot_x, hot_y; - handle = gbm_bo_get_handle (displayed_cursor->bo); - width = gbm_bo_get_width (displayed_cursor->bo); - height = gbm_bo_get_height (displayed_cursor->bo); - hot_x = displayed_cursor->hot_x; - hot_y = displayed_cursor->hot_y; + bo = meta_cursor_reference_get_gbm_bo (displayed_cursor, &hot_x, &hot_y); + + handle = gbm_bo_get_handle (bo); + width = gbm_bo_get_width (bo); + height = gbm_bo_get_height (bo); drmModeSetCursor2 (tracker->drm_fd, crtc->crtc_id, handle.u32, width, height, hot_x, hot_y); diff --git a/src/core/meta-cursor.c b/src/core/meta-cursor.c index 5749054eb..bc1d140c3 100644 --- a/src/core/meta-cursor.c +++ b/src/core/meta-cursor.c @@ -377,3 +377,27 @@ meta_cursor_reference_from_buffer (MetaCursorTracker *tracker, return self; } + +CoglTexture * +meta_cursor_reference_get_cogl_texture (MetaCursorReference *cursor, + int *hot_x, + int *hot_y) +{ + if (hot_x) + *hot_x = cursor->hot_x; + if (hot_y) + *hot_y = cursor->hot_y; + return COGL_TEXTURE (cursor->texture); +} + +struct gbm_bo * +meta_cursor_reference_get_gbm_bo (MetaCursorReference *cursor, + int *hot_x, + int *hot_y) +{ + if (hot_x) + *hot_x = cursor->hot_x; + if (hot_y) + *hot_y = cursor->hot_y; + return cursor->bo; +} From 0f810a4e21e099927e47a9ac4260c95b11e435a7 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 31 Mar 2014 16:09:32 -0400 Subject: [PATCH 784/889] cursor: Refactor out code that loads from XcursorImage --- src/core/meta-cursor.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src/core/meta-cursor.c b/src/core/meta-cursor.c index bc1d140c3..94cf34155 100644 --- a/src/core/meta-cursor.c +++ b/src/core/meta-cursor.c @@ -181,11 +181,10 @@ load_cursor_on_client (MetaDisplay *display, return image; } -MetaCursorReference * -meta_cursor_reference_from_theme (MetaCursorTracker *tracker, - MetaCursor cursor) +static MetaCursorReference * +meta_cursor_reference_from_xcursor_image (MetaCursorTracker *tracker, + XcursorImage *image) { - XcursorImage *image; int width, height, rowstride; CoglPixelFormat cogl_format; uint32_t gbm_format; @@ -193,10 +192,6 @@ meta_cursor_reference_from_theme (MetaCursorTracker *tracker, CoglContext *cogl_context; MetaCursorReference *self; - image = load_cursor_on_client (tracker->screen->display, cursor); - if (!image) - return NULL; - width = image->width; height = image->height; rowstride = width * 4; @@ -250,8 +245,23 @@ meta_cursor_reference_from_theme (MetaCursorTracker *tracker, } out: - XcursorImageDestroy (image); + return self; +} +MetaCursorReference * +meta_cursor_reference_from_theme (MetaCursorTracker *tracker, + MetaCursor cursor) +{ + MetaCursorReference *self; + XcursorImage *image; + + image = load_cursor_on_client (tracker->screen->display, cursor); + if (!image) + return NULL; + + self = meta_cursor_reference_from_xcursor_image (tracker, image); + + XcursorImageDestroy (image); return self; } From 0efb0b47ebb2712cbd021d26027d8244414dd5c8 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 31 Mar 2014 16:10:58 -0400 Subject: [PATCH 785/889] cursor: Move cursor caching layer to meta_cursor_reference_from_theme --- src/core/meta-cursor-tracker-private.h | 2 +- src/core/meta-cursor-tracker.c | 22 ++++------------------ src/core/meta-cursor.c | 3 +++ 3 files changed, 8 insertions(+), 19 deletions(-) diff --git a/src/core/meta-cursor-tracker-private.h b/src/core/meta-cursor-tracker-private.h index 62b32d39f..9da347a3c 100644 --- a/src/core/meta-cursor-tracker-private.h +++ b/src/core/meta-cursor-tracker-private.h @@ -61,7 +61,7 @@ struct _MetaCursorTracker { MetaCursorReference *root_cursor; - MetaCursorReference *default_cursors[META_CURSOR_LAST]; + MetaCursorReference *theme_cursors[META_CURSOR_LAST]; int current_x, current_y; MetaRectangle current_rect; diff --git a/src/core/meta-cursor-tracker.c b/src/core/meta-cursor-tracker.c index 7338e2ad5..ebc661b8a 100644 --- a/src/core/meta-cursor-tracker.c +++ b/src/core/meta-cursor-tracker.c @@ -85,8 +85,8 @@ meta_cursor_tracker_finalize (GObject *object) meta_cursor_reference_unref (self->root_cursor); for (i = 0; i < META_CURSOR_LAST; i++) - if (self->default_cursors[i]) - meta_cursor_reference_unref (self->default_cursors[i]); + if (self->theme_cursors[i]) + meta_cursor_reference_unref (self->theme_cursors[i]); if (self->pipeline) cogl_object_unref (self->pipeline); @@ -371,27 +371,13 @@ meta_cursor_tracker_get_hot (MetaCursorTracker *tracker, } } -static MetaCursorReference * -ensure_wayland_cursor (MetaCursorTracker *tracker, - MetaCursor cursor) -{ - if (!tracker->default_cursors[cursor]) - { - tracker->default_cursors[cursor] = meta_cursor_reference_from_theme (tracker, cursor); - if (!tracker->default_cursors[cursor]) - meta_warning ("Failed to load cursor from theme\n"); - } - - return meta_cursor_reference_ref (tracker->default_cursors[cursor]); -} - void meta_cursor_tracker_set_grab_cursor (MetaCursorTracker *tracker, MetaCursor cursor) { g_clear_pointer (&tracker->grab_cursor, meta_cursor_reference_unref); if (cursor != META_CURSOR_DEFAULT) - tracker->grab_cursor = ensure_wayland_cursor (tracker, cursor); + tracker->grab_cursor = meta_cursor_reference_from_theme (tracker, cursor); sync_cursor (tracker); } @@ -435,7 +421,7 @@ meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker, if (meta_is_wayland_compositor ()) { g_clear_pointer (&tracker->root_cursor, meta_cursor_reference_unref); - tracker->root_cursor = ensure_wayland_cursor (tracker, cursor); + tracker->root_cursor = meta_cursor_reference_from_theme (tracker, cursor); sync_cursor (tracker); } } diff --git a/src/core/meta-cursor.c b/src/core/meta-cursor.c index 94cf34155..021a20619 100644 --- a/src/core/meta-cursor.c +++ b/src/core/meta-cursor.c @@ -255,6 +255,9 @@ meta_cursor_reference_from_theme (MetaCursorTracker *tracker, MetaCursorReference *self; XcursorImage *image; + if (tracker->theme_cursors[cursor]) + return meta_cursor_reference_ref (tracker->theme_cursors[cursor]); + image = load_cursor_on_client (tracker->screen->display, cursor); if (!image) return NULL; From fa6082409699f986f43740ca161151efdc760e0d Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 31 Mar 2014 16:17:49 -0400 Subject: [PATCH 786/889] cursor-tracker: Make set_grab_cursor take a MetaCursorReference --- src/core/display.c | 7 +++++-- src/core/meta-cursor-tracker-private.h | 4 ++-- src/core/meta-cursor-tracker.c | 9 +++++---- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/core/display.c b/src/core/display.c index b4c5b2bce..716f864f9 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -1839,6 +1839,7 @@ meta_display_set_grab_op_cursor (MetaDisplay *display, unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits }; MetaCursor cursor = meta_cursor_for_grab_op (op); + MetaCursorReference *cursor_ref; XISetMask (mask.mask, XI_ButtonPress); XISetMask (mask.mask, XI_ButtonRelease); @@ -1872,7 +1873,9 @@ meta_display_set_grab_op_cursor (MetaDisplay *display, meta_error_trap_pop (display); - meta_cursor_tracker_set_grab_cursor (screen->cursor_tracker, cursor); + cursor_ref = meta_cursor_reference_from_theme (screen->cursor_tracker, cursor); + meta_cursor_tracker_set_grab_cursor (screen->cursor_tracker, cursor_ref); + meta_cursor_reference_unref (cursor_ref); } gboolean @@ -2111,7 +2114,7 @@ meta_display_end_grab_op (MetaDisplay *display, meta_screen_ungrab_all_keys (display->screen, timestamp); } - meta_cursor_tracker_set_grab_cursor (display->screen->cursor_tracker, META_CURSOR_DEFAULT); + meta_cursor_tracker_set_grab_cursor (display->screen->cursor_tracker, NULL); display->grab_timestamp = 0; display->grab_window = NULL; diff --git a/src/core/meta-cursor-tracker-private.h b/src/core/meta-cursor-tracker-private.h index 9da347a3c..ced31b3c1 100644 --- a/src/core/meta-cursor-tracker-private.h +++ b/src/core/meta-cursor-tracker-private.h @@ -80,8 +80,8 @@ struct _MetaCursorTrackerClass { gboolean meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker, XEvent *xevent); -void meta_cursor_tracker_set_grab_cursor (MetaCursorTracker *tracker, - MetaCursor cursor); +void meta_cursor_tracker_set_grab_cursor (MetaCursorTracker *tracker, + MetaCursorReference *cursor); void meta_cursor_tracker_set_window_cursor (MetaCursorTracker *tracker, struct wl_resource *buffer, int hot_x, diff --git a/src/core/meta-cursor-tracker.c b/src/core/meta-cursor-tracker.c index ebc661b8a..beaf25594 100644 --- a/src/core/meta-cursor-tracker.c +++ b/src/core/meta-cursor-tracker.c @@ -372,12 +372,13 @@ meta_cursor_tracker_get_hot (MetaCursorTracker *tracker, } void -meta_cursor_tracker_set_grab_cursor (MetaCursorTracker *tracker, - MetaCursor cursor) +meta_cursor_tracker_set_grab_cursor (MetaCursorTracker *tracker, + MetaCursorReference *cursor) { g_clear_pointer (&tracker->grab_cursor, meta_cursor_reference_unref); - if (cursor != META_CURSOR_DEFAULT) - tracker->grab_cursor = meta_cursor_reference_from_theme (tracker, cursor); + if (cursor) + tracker->grab_cursor = meta_cursor_reference_ref (cursor); + sync_cursor (tracker); } From be60e4f6e76574fe1023b3d18b0b0fd2c62586ac Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 31 Mar 2014 16:50:15 -0400 Subject: [PATCH 787/889] cursor-tracker: Make set_window_cursor take a MetaCursorReference as well --- src/core/meta-cursor-tracker-private.h | 12 +++++------- src/core/meta-cursor-tracker.c | 13 ++----------- src/wayland/meta-wayland-seat.c | 20 +++++++++++++------- 3 files changed, 20 insertions(+), 25 deletions(-) diff --git a/src/core/meta-cursor-tracker-private.h b/src/core/meta-cursor-tracker-private.h index ced31b3c1..f236b3494 100644 --- a/src/core/meta-cursor-tracker-private.h +++ b/src/core/meta-cursor-tracker-private.h @@ -82,13 +82,11 @@ gboolean meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker, void meta_cursor_tracker_set_grab_cursor (MetaCursorTracker *tracker, MetaCursorReference *cursor); -void meta_cursor_tracker_set_window_cursor (MetaCursorTracker *tracker, - struct wl_resource *buffer, - int hot_x, - int hot_y); -void meta_cursor_tracker_unset_window_cursor (MetaCursorTracker *tracker); -void meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker, - MetaCursor cursor); +void meta_cursor_tracker_set_window_cursor (MetaCursorTracker *tracker, + MetaCursorReference *cursor); +void meta_cursor_tracker_unset_window_cursor (MetaCursorTracker *tracker); +void meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker, + MetaCursor cursor); void meta_cursor_tracker_update_position (MetaCursorTracker *tracker, int new_x, diff --git a/src/core/meta-cursor-tracker.c b/src/core/meta-cursor-tracker.c index beaf25594..8b6561eae 100644 --- a/src/core/meta-cursor-tracker.c +++ b/src/core/meta-cursor-tracker.c @@ -383,18 +383,9 @@ meta_cursor_tracker_set_grab_cursor (MetaCursorTracker *tracker, } void -meta_cursor_tracker_set_window_cursor (MetaCursorTracker *tracker, - struct wl_resource *buffer, - int hot_x, - int hot_y) +meta_cursor_tracker_set_window_cursor (MetaCursorTracker *tracker, + MetaCursorReference *cursor) { - MetaCursorReference *cursor; - - if (buffer) - cursor = meta_cursor_reference_from_buffer (tracker, buffer, hot_x, hot_y); - else - cursor = NULL; - set_window_cursor (tracker, TRUE, cursor); } diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c index 8ec7b2b75..2d5f0fbb9 100644 --- a/src/wayland/meta-wayland-seat.c +++ b/src/wayland/meta-wayland-seat.c @@ -68,20 +68,26 @@ set_cursor_surface (MetaWaylandSeat *seat, void meta_wayland_seat_update_cursor_surface (MetaWaylandSeat *seat) { - struct wl_resource *buffer; + MetaCursorReference *cursor; if (seat->cursor_tracker == NULL) return; if (seat->cursor_surface && seat->cursor_surface->buffer) - buffer = seat->cursor_surface->buffer->resource; + { + struct wl_resource *buffer = seat->cursor_surface->buffer->resource; + cursor = meta_cursor_reference_from_buffer (seat->cursor_tracker, + buffer, + seat->hotspot_x, + seat->hotspot_y); + } else - buffer = NULL; + cursor = NULL; - meta_cursor_tracker_set_window_cursor (seat->cursor_tracker, - buffer, - seat->hotspot_x, - seat->hotspot_y); + meta_cursor_tracker_set_window_cursor (seat->cursor_tracker, cursor); + + if (cursor) + meta_cursor_reference_unref (cursor); } static void From 565883dadb66b3fabc470dc8771f604e77ad07ba Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 31 Mar 2014 17:21:04 -0400 Subject: [PATCH 788/889] screen: Refactor update_cursor a bit --- src/core/screen.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/core/screen.c b/src/core/screen.c index 26354a60c..283544549 100644 --- a/src/core/screen.c +++ b/src/core/screen.c @@ -1381,6 +1381,12 @@ update_focus_mode (MetaScreen *screen) /* nothing to do anymore */ ; } +void +meta_screen_update_cursor (MetaScreen *screen) +{ + meta_cursor_tracker_set_root_cursor (screen->cursor_tracker, screen->current_cursor); +} + void meta_screen_set_cursor (MetaScreen *screen, MetaCursor cursor) @@ -1389,14 +1395,7 @@ meta_screen_set_cursor (MetaScreen *screen, return; screen->current_cursor = cursor; - meta_cursor_tracker_set_root_cursor (screen->cursor_tracker, cursor); -} - -void -meta_screen_update_cursor (MetaScreen *screen) -{ - meta_cursor_tracker_set_root_cursor (screen->cursor_tracker, - screen->current_cursor); + meta_screen_update_cursor (screen); } static gboolean From fe42a4eb4ec466bce3f686b38a0221a198c0afb5 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 31 Mar 2014 17:22:23 -0400 Subject: [PATCH 789/889] screen: Move XDefineCursor on the root window here This is really an X11 front-end thing, so it doesn't belong in the cursor tracker, which is a back-end thing. --- src/core/meta-cursor-tracker.c | 19 +++---------------- src/core/screen.c | 13 ++++++++++++- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/core/meta-cursor-tracker.c b/src/core/meta-cursor-tracker.c index 8b6561eae..a5ceb2e72 100644 --- a/src/core/meta-cursor-tracker.c +++ b/src/core/meta-cursor-tracker.c @@ -399,23 +399,10 @@ void meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker, MetaCursor cursor) { - Cursor xcursor; - MetaDisplay *display = tracker->screen->display; + g_clear_pointer (&tracker->root_cursor, meta_cursor_reference_unref); + tracker->root_cursor = meta_cursor_reference_from_theme (tracker, cursor); - /* First create a cursor for X11 applications that don't specify their own */ - xcursor = meta_display_create_x_cursor (display, cursor); - - XDefineCursor (display->xdisplay, tracker->screen->xroot, xcursor); - XFlush (display->xdisplay); - XFreeCursor (display->xdisplay, xcursor); - - /* Now update the real root cursor */ - if (meta_is_wayland_compositor ()) - { - g_clear_pointer (&tracker->root_cursor, meta_cursor_reference_unref); - tracker->root_cursor = meta_cursor_reference_from_theme (tracker, cursor); - sync_cursor (tracker); - } + sync_cursor (tracker); } static gboolean diff --git a/src/core/screen.c b/src/core/screen.c index 283544549..38f8da8c7 100644 --- a/src/core/screen.c +++ b/src/core/screen.c @@ -1384,7 +1384,18 @@ update_focus_mode (MetaScreen *screen) void meta_screen_update_cursor (MetaScreen *screen) { - meta_cursor_tracker_set_root_cursor (screen->cursor_tracker, screen->current_cursor); + MetaDisplay *display = screen->display; + MetaCursor cursor = screen->current_cursor; + Cursor xcursor; + + meta_cursor_tracker_set_root_cursor (screen->cursor_tracker, cursor); + + /* Set a cursor for X11 applications that don't specify their own */ + xcursor = meta_display_create_x_cursor (display, cursor); + + XDefineCursor (display->xdisplay, screen->xroot, xcursor); + XFlush (display->xdisplay); + XFreeCursor (display->xdisplay, xcursor); } void From f95f2b0c6d297d6c7eaad8fe0341188a2f917b50 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 31 Mar 2014 17:28:19 -0400 Subject: [PATCH 790/889] cursor-tracker: Make set_root_cursor take a MetaCursorReference --- src/core/meta-cursor-tracker-private.h | 2 +- src/core/meta-cursor-tracker.c | 7 ++++--- src/core/screen.c | 5 ++++- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/core/meta-cursor-tracker-private.h b/src/core/meta-cursor-tracker-private.h index f236b3494..ef8de4b98 100644 --- a/src/core/meta-cursor-tracker-private.h +++ b/src/core/meta-cursor-tracker-private.h @@ -86,7 +86,7 @@ void meta_cursor_tracker_set_window_cursor (MetaCursorTracker *tracker, MetaCursorReference *cursor); void meta_cursor_tracker_unset_window_cursor (MetaCursorTracker *tracker); void meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker, - MetaCursor cursor); + MetaCursorReference *cursor); void meta_cursor_tracker_update_position (MetaCursorTracker *tracker, int new_x, diff --git a/src/core/meta-cursor-tracker.c b/src/core/meta-cursor-tracker.c index a5ceb2e72..9e05edbb0 100644 --- a/src/core/meta-cursor-tracker.c +++ b/src/core/meta-cursor-tracker.c @@ -396,11 +396,12 @@ meta_cursor_tracker_unset_window_cursor (MetaCursorTracker *tracker) } void -meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker, - MetaCursor cursor) +meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker, + MetaCursorReference *cursor) { g_clear_pointer (&tracker->root_cursor, meta_cursor_reference_unref); - tracker->root_cursor = meta_cursor_reference_from_theme (tracker, cursor); + if (cursor) + tracker->root_cursor = meta_cursor_reference_ref (cursor); sync_cursor (tracker); } diff --git a/src/core/screen.c b/src/core/screen.c index 38f8da8c7..030bab78c 100644 --- a/src/core/screen.c +++ b/src/core/screen.c @@ -1387,8 +1387,11 @@ meta_screen_update_cursor (MetaScreen *screen) MetaDisplay *display = screen->display; MetaCursor cursor = screen->current_cursor; Cursor xcursor; + MetaCursorReference *cursor_ref; - meta_cursor_tracker_set_root_cursor (screen->cursor_tracker, cursor); + cursor_ref = meta_cursor_reference_from_theme (screen->cursor_tracker, cursor); + meta_cursor_tracker_set_root_cursor (screen->cursor_tracker, cursor_ref); + meta_cursor_reference_unref (cursor_ref); /* Set a cursor for X11 applications that don't specify their own */ xcursor = meta_display_create_x_cursor (display, cursor); From f4e299ca4685c2421e20ee856c794545961f7a89 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 31 Mar 2014 16:56:03 -0400 Subject: [PATCH 791/889] cursor: Split out code that frees the MetaCursorReference --- src/core/meta-cursor.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/core/meta-cursor.c b/src/core/meta-cursor.c index 021a20619..d10d3072a 100644 --- a/src/core/meta-cursor.c +++ b/src/core/meta-cursor.c @@ -46,19 +46,23 @@ meta_cursor_reference_ref (MetaCursorReference *self) return self; } +static void +meta_cursor_reference_free (MetaCursorReference *self) +{ + cogl_object_unref (self->texture); + if (self->bo) + gbm_bo_destroy (self->bo); + + g_slice_free (MetaCursorReference, self); +} + void meta_cursor_reference_unref (MetaCursorReference *self) { self->ref_count--; if (self->ref_count == 0) - { - cogl_object_unref (self->texture); - if (self->bo) - gbm_bo_destroy (self->bo); - - g_slice_free (MetaCursorReference, self); - } + meta_cursor_reference_free (self); } static void From 78dbf8cb56d9652a5b98516da136196e7fee03d5 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 31 Mar 2014 17:01:14 -0400 Subject: [PATCH 792/889] cursor: Split out the structure for the actual textures / buffers out This will allow us to have a MetaCursorReference 'subclass' that's lazily loaded. We currently always load all the images. The long-term plan is to have a subclass for each "backend" and only have CoglTexture as a common denominator. For the nested X11 backend, we use XDefineCursor on our stage window. For the Wayland backend, we would use set_cursor on our stage surface. For the native backend, we would use the GBM code that's there right now. The CoglTexture is there to be a "shared fallback" between all devices, and also for the get_sprite API. The odd man out is the X11 compositor case. For that, we need to move the responsibility of setting the final cursor image out of MetaCursorTracker, and simply have it be about tracking the used sprite image and pointer position. --- src/core/meta-cursor-private.h | 10 +++-- src/core/meta-cursor-tracker.c | 6 +-- src/core/meta-cursor.c | 81 ++++++++++++++++++---------------- 3 files changed, 53 insertions(+), 44 deletions(-) diff --git a/src/core/meta-cursor-private.h b/src/core/meta-cursor-private.h index a5f04a730..b1490212a 100644 --- a/src/core/meta-cursor-private.h +++ b/src/core/meta-cursor-private.h @@ -27,12 +27,16 @@ #include #include -struct _MetaCursorReference { - int ref_count; - +typedef struct { CoglTexture2D *texture; struct gbm_bo *bo; int hot_x, hot_y; +} MetaCursorImage; + +struct _MetaCursorReference { + int ref_count; + + MetaCursorImage image; }; CoglTexture *meta_cursor_reference_get_cogl_texture (MetaCursorReference *cursor, diff --git a/src/core/meta-cursor-tracker.c b/src/core/meta-cursor-tracker.c index 9e05edbb0..098b2511c 100644 --- a/src/core/meta-cursor-tracker.c +++ b/src/core/meta-cursor-tracker.c @@ -253,9 +253,9 @@ meta_cursor_reference_take_texture (CoglTexture2D *texture, self = g_slice_new0 (MetaCursorReference); self->ref_count = 1; - self->texture = texture; - self->hot_x = hot_x; - self->hot_y = hot_y; + self->image.texture = texture; + self->image.hot_x = hot_x; + self->image.hot_y = hot_y; return self; } diff --git a/src/core/meta-cursor.c b/src/core/meta-cursor.c index d10d3072a..92a33b535 100644 --- a/src/core/meta-cursor.c +++ b/src/core/meta-cursor.c @@ -46,13 +46,18 @@ meta_cursor_reference_ref (MetaCursorReference *self) return self; } +static void +meta_cursor_image_free (MetaCursorImage *image) +{ + cogl_object_unref (image->texture); + if (image->bo) + gbm_bo_destroy (image->bo); +} + static void meta_cursor_reference_free (MetaCursorReference *self) { - cogl_object_unref (self->texture); - if (self->bo) - gbm_bo_destroy (self->bo); - + meta_cursor_image_free (&self->image); g_slice_free (MetaCursorReference, self); } @@ -209,17 +214,17 @@ meta_cursor_reference_from_xcursor_image (MetaCursorTracker *tracker, self = g_slice_new0 (MetaCursorReference); self->ref_count = 1; - self->hot_x = image->xhot; - self->hot_y = image->yhot; + self->image.hot_x = image->xhot; + self->image.hot_y = image->yhot; clutter_backend = clutter_get_default_backend (); cogl_context = clutter_backend_get_cogl_context (clutter_backend); - self->texture = cogl_texture_2d_new_from_data (cogl_context, - width, height, - cogl_format, - rowstride, - (uint8_t*)image->pixels, - NULL); + self->image.texture = cogl_texture_2d_new_from_data (cogl_context, + width, height, + cogl_format, + rowstride, + (uint8_t*)image->pixels, + NULL); if (tracker->gbm) { @@ -235,14 +240,14 @@ meta_cursor_reference_from_xcursor_image (MetaCursorTracker *tracker, uint32_t buf[64 * 64]; int i; - self->bo = gbm_bo_create (tracker->gbm, 64, 64, - gbm_format, GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE); + self->image.bo = gbm_bo_create (tracker->gbm, 64, 64, + gbm_format, GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE); memset (buf, 0, sizeof(buf)); for (i = 0; i < height; i++) memcpy (buf + i * 64, image->pixels + i * width, width * 4); - gbm_bo_write (self->bo, buf, 64 * 64 * 4); + gbm_bo_write (self->image.bo, buf, 64 * 64 * 4); } else meta_warning ("HW cursor for format %d not supported\n", gbm_format); @@ -287,8 +292,8 @@ meta_cursor_reference_from_buffer (MetaCursorTracker *tracker, self = g_slice_new0 (MetaCursorReference); self->ref_count = 1; - self->hot_x = hot_x; - self->hot_y = hot_y; + self->image.hot_x = hot_x; + self->image.hot_y = hot_y; backend = clutter_get_default_backend (); cogl_context = clutter_backend_get_cogl_context (backend); @@ -327,12 +332,12 @@ meta_cursor_reference_from_buffer (MetaCursorTracker *tracker, gbm_format = GBM_FORMAT_ARGB8888; } - self->texture = cogl_texture_2d_new_from_data (cogl_context, - width, height, - cogl_format, - rowstride, - wl_shm_buffer_get_data (shm_buffer), - NULL); + self->image.texture = cogl_texture_2d_new_from_data (cogl_context, + width, height, + cogl_format, + rowstride, + wl_shm_buffer_get_data (shm_buffer), + NULL); if (width > 64 || height > 64) { @@ -349,15 +354,15 @@ meta_cursor_reference_from_buffer (MetaCursorTracker *tracker, uint8_t buf[4 * 64 * 64]; int i; - self->bo = gbm_bo_create (tracker->gbm, 64, 64, - gbm_format, GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE); + self->image.bo = gbm_bo_create (tracker->gbm, 64, 64, + gbm_format, GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE); data = wl_shm_buffer_get_data (shm_buffer); memset (buf, 0, sizeof(buf)); for (i = 0; i < height; i++) memcpy (buf + i * 4 * 64, data + i * rowstride, 4 * width); - gbm_bo_write (self->bo, buf, 64 * 64 * 4); + gbm_bo_write (self->image.bo, buf, 64 * 64 * 4); } else meta_warning ("HW cursor for format %d not supported\n", gbm_format); @@ -367,9 +372,9 @@ meta_cursor_reference_from_buffer (MetaCursorTracker *tracker, { int width, height; - self->texture = cogl_wayland_texture_2d_new_from_buffer (cogl_context, buffer, NULL); - width = cogl_texture_get_width (COGL_TEXTURE (self->texture)); - height = cogl_texture_get_height (COGL_TEXTURE (self->texture)); + self->image.texture = cogl_wayland_texture_2d_new_from_buffer (cogl_context, buffer, NULL); + width = cogl_texture_get_width (COGL_TEXTURE (self->image.texture)); + height = cogl_texture_get_height (COGL_TEXTURE (self->image.texture)); /* HW cursors must be 64x64, but 64x64 is huge, and no cursor theme actually uses that, so themed cursors must be padded with transparent pixels to fill the @@ -385,9 +390,9 @@ meta_cursor_reference_from_buffer (MetaCursorTracker *tracker, if (tracker->gbm) { - self->bo = gbm_bo_import (tracker->gbm, GBM_BO_IMPORT_WL_BUFFER, - buffer, GBM_BO_USE_CURSOR_64X64); - if (!self->bo) + self->image.bo = gbm_bo_import (tracker->gbm, GBM_BO_IMPORT_WL_BUFFER, + buffer, GBM_BO_USE_CURSOR_64X64); + if (!self->image.bo) meta_warning ("Importing HW cursor from wl_buffer failed\n"); } } @@ -401,10 +406,10 @@ meta_cursor_reference_get_cogl_texture (MetaCursorReference *cursor, int *hot_y) { if (hot_x) - *hot_x = cursor->hot_x; + *hot_x = cursor->image.hot_x; if (hot_y) - *hot_y = cursor->hot_y; - return COGL_TEXTURE (cursor->texture); + *hot_y = cursor->image.hot_y; + return COGL_TEXTURE (cursor->image.texture); } struct gbm_bo * @@ -413,8 +418,8 @@ meta_cursor_reference_get_gbm_bo (MetaCursorReference *cursor, int *hot_y) { if (hot_x) - *hot_x = cursor->hot_x; + *hot_x = cursor->image.hot_x; if (hot_y) - *hot_y = cursor->hot_y; - return cursor->bo; + *hot_y = cursor->image.hot_y; + return cursor->image.bo; } From da27735265f6d52939f7a766bdd1700d6df6ba3f Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 31 Mar 2014 17:13:03 -0400 Subject: [PATCH 793/889] cursor: Refactor code to load cursor images out We're going to make MetaCursorReference specialized and per-backend soon. --- src/core/meta-cursor.c | 112 ++++++++++++++++++++++------------------- 1 file changed, 60 insertions(+), 52 deletions(-) diff --git a/src/core/meta-cursor.c b/src/core/meta-cursor.c index 92a33b535..b5ed94f85 100644 --- a/src/core/meta-cursor.c +++ b/src/core/meta-cursor.c @@ -190,19 +190,19 @@ load_cursor_on_client (MetaDisplay *display, return image; } -static MetaCursorReference * -meta_cursor_reference_from_xcursor_image (MetaCursorTracker *tracker, - XcursorImage *image) +static void +meta_cursor_image_load_from_xcursor_image (MetaCursorTracker *tracker, + MetaCursorImage *image, + XcursorImage *xc_image) { int width, height, rowstride; CoglPixelFormat cogl_format; uint32_t gbm_format; ClutterBackend *clutter_backend; CoglContext *cogl_context; - MetaCursorReference *self; - width = image->width; - height = image->height; + width = xc_image->width; + height = xc_image->height; rowstride = width * 4; gbm_format = GBM_FORMAT_ARGB8888; @@ -212,26 +212,24 @@ meta_cursor_reference_from_xcursor_image (MetaCursorTracker *tracker, cogl_format = COGL_PIXEL_FORMAT_ARGB_8888; #endif - self = g_slice_new0 (MetaCursorReference); - self->ref_count = 1; - self->image.hot_x = image->xhot; - self->image.hot_y = image->yhot; + image->hot_x = xc_image->xhot; + image->hot_y = xc_image->yhot; clutter_backend = clutter_get_default_backend (); cogl_context = clutter_backend_get_cogl_context (clutter_backend); - self->image.texture = cogl_texture_2d_new_from_data (cogl_context, - width, height, - cogl_format, - rowstride, - (uint8_t*)image->pixels, - NULL); + image->texture = cogl_texture_2d_new_from_data (cogl_context, + width, height, + cogl_format, + rowstride, + (uint8_t*)xc_image->pixels, + NULL); if (tracker->gbm) { if (width > 64 || height > 64) { meta_warning ("Invalid theme cursor size (must be at most 64x64)\n"); - goto out; + return; } if (gbm_device_is_format_supported (tracker->gbm, gbm_format, @@ -240,21 +238,18 @@ meta_cursor_reference_from_xcursor_image (MetaCursorTracker *tracker, uint32_t buf[64 * 64]; int i; - self->image.bo = gbm_bo_create (tracker->gbm, 64, 64, - gbm_format, GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE); + image->bo = gbm_bo_create (tracker->gbm, 64, 64, + gbm_format, GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE); memset (buf, 0, sizeof(buf)); for (i = 0; i < height; i++) - memcpy (buf + i * 64, image->pixels + i * width, width * 4); + memcpy (buf + i * 64, xc_image->pixels + i * width, width * 4); - gbm_bo_write (self->image.bo, buf, 64 * 64 * 4); + gbm_bo_write (image->bo, buf, 64 * 64 * 4); } else meta_warning ("HW cursor for format %d not supported\n", gbm_format); } - - out: - return self; } MetaCursorReference * @@ -271,29 +266,29 @@ meta_cursor_reference_from_theme (MetaCursorTracker *tracker, if (!image) return NULL; - self = meta_cursor_reference_from_xcursor_image (tracker, image); + self = g_slice_new0 (MetaCursorReference); + self->ref_count = 1; + meta_cursor_image_load_from_xcursor_image (tracker, &self->image, image); XcursorImageDestroy (image); return self; } -MetaCursorReference * -meta_cursor_reference_from_buffer (MetaCursorTracker *tracker, - struct wl_resource *buffer, - int hot_x, - int hot_y) +static void +meta_cursor_image_load_from_buffer (MetaCursorTracker *tracker, + MetaCursorImage *image, + struct wl_resource *buffer, + int hot_x, + int hot_y) { ClutterBackend *backend; CoglContext *cogl_context; - MetaCursorReference *self; CoglPixelFormat cogl_format; struct wl_shm_buffer *shm_buffer; uint32_t gbm_format; - self = g_slice_new0 (MetaCursorReference); - self->ref_count = 1; - self->image.hot_x = hot_x; - self->image.hot_y = hot_y; + image->hot_x = hot_x; + image->hot_y = hot_y; backend = clutter_get_default_backend (); cogl_context = clutter_backend_get_cogl_context (backend); @@ -332,17 +327,17 @@ meta_cursor_reference_from_buffer (MetaCursorTracker *tracker, gbm_format = GBM_FORMAT_ARGB8888; } - self->image.texture = cogl_texture_2d_new_from_data (cogl_context, - width, height, - cogl_format, - rowstride, - wl_shm_buffer_get_data (shm_buffer), - NULL); + image->texture = cogl_texture_2d_new_from_data (cogl_context, + width, height, + cogl_format, + rowstride, + wl_shm_buffer_get_data (shm_buffer), + NULL); if (width > 64 || height > 64) { meta_warning ("Invalid cursor size (must be at most 64x64), falling back to software (GL) cursors\n"); - return self; + return; } if (tracker->gbm) @@ -354,15 +349,15 @@ meta_cursor_reference_from_buffer (MetaCursorTracker *tracker, uint8_t buf[4 * 64 * 64]; int i; - self->image.bo = gbm_bo_create (tracker->gbm, 64, 64, - gbm_format, GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE); + image->bo = gbm_bo_create (tracker->gbm, 64, 64, + gbm_format, GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE); data = wl_shm_buffer_get_data (shm_buffer); memset (buf, 0, sizeof(buf)); for (i = 0; i < height; i++) memcpy (buf + i * 4 * 64, data + i * rowstride, 4 * width); - gbm_bo_write (self->image.bo, buf, 64 * 64 * 4); + gbm_bo_write (image->bo, buf, 64 * 64 * 4); } else meta_warning ("HW cursor for format %d not supported\n", gbm_format); @@ -372,9 +367,9 @@ meta_cursor_reference_from_buffer (MetaCursorTracker *tracker, { int width, height; - self->image.texture = cogl_wayland_texture_2d_new_from_buffer (cogl_context, buffer, NULL); - width = cogl_texture_get_width (COGL_TEXTURE (self->image.texture)); - height = cogl_texture_get_height (COGL_TEXTURE (self->image.texture)); + image->texture = cogl_wayland_texture_2d_new_from_buffer (cogl_context, buffer, NULL); + width = cogl_texture_get_width (COGL_TEXTURE (image->texture)); + height = cogl_texture_get_height (COGL_TEXTURE (image->texture)); /* HW cursors must be 64x64, but 64x64 is huge, and no cursor theme actually uses that, so themed cursors must be padded with transparent pixels to fill the @@ -385,17 +380,30 @@ meta_cursor_reference_from_buffer (MetaCursorTracker *tracker, if (width != 64 || height != 64) { meta_warning ("Invalid cursor size (must be 64x64), falling back to software (GL) cursors\n"); - return self; + return; } if (tracker->gbm) { - self->image.bo = gbm_bo_import (tracker->gbm, GBM_BO_IMPORT_WL_BUFFER, - buffer, GBM_BO_USE_CURSOR_64X64); - if (!self->image.bo) + image->bo = gbm_bo_import (tracker->gbm, GBM_BO_IMPORT_WL_BUFFER, + buffer, GBM_BO_USE_CURSOR_64X64); + if (!image->bo) meta_warning ("Importing HW cursor from wl_buffer failed\n"); } } +} + +MetaCursorReference * +meta_cursor_reference_from_buffer (MetaCursorTracker *tracker, + struct wl_resource *buffer, + int hot_x, + int hot_y) +{ + MetaCursorReference *self; + + self = g_slice_new0 (MetaCursorReference); + self->ref_count = 1; + meta_cursor_image_load_from_buffer (tracker, &self->image, buffer, hot_x, hot_y); return self; } From 30ebf46aa4747d79c9bbfaa40de5c01dce42696c Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 31 Mar 2014 17:13:38 -0400 Subject: [PATCH 794/889] cursor: Reindent --- src/core/meta-cursor.c | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/core/meta-cursor.c b/src/core/meta-cursor.c index b5ed94f85..f08af08c7 100644 --- a/src/core/meta-cursor.c +++ b/src/core/meta-cursor.c @@ -303,28 +303,28 @@ meta_cursor_image_load_from_buffer (MetaCursorTracker *tracker, switch (wl_shm_buffer_get_format (shm_buffer)) { #if G_BYTE_ORDER == G_BIG_ENDIAN - case WL_SHM_FORMAT_ARGB8888: - cogl_format = COGL_PIXEL_FORMAT_ARGB_8888_PRE; - gbm_format = GBM_FORMAT_ARGB8888; - break; - case WL_SHM_FORMAT_XRGB8888: - cogl_format = COGL_PIXEL_FORMAT_ARGB_8888; - gbm_format = GBM_FORMAT_XRGB8888; - break; + case WL_SHM_FORMAT_ARGB8888: + cogl_format = COGL_PIXEL_FORMAT_ARGB_8888_PRE; + gbm_format = GBM_FORMAT_ARGB8888; + break; + case WL_SHM_FORMAT_XRGB8888: + cogl_format = COGL_PIXEL_FORMAT_ARGB_8888; + gbm_format = GBM_FORMAT_XRGB8888; + break; #else - case WL_SHM_FORMAT_ARGB8888: - cogl_format = COGL_PIXEL_FORMAT_BGRA_8888_PRE; - gbm_format = GBM_FORMAT_ARGB8888; - break; - case WL_SHM_FORMAT_XRGB8888: - cogl_format = COGL_PIXEL_FORMAT_BGRA_8888; - gbm_format = GBM_FORMAT_XRGB8888; - break; + case WL_SHM_FORMAT_ARGB8888: + cogl_format = COGL_PIXEL_FORMAT_BGRA_8888_PRE; + gbm_format = GBM_FORMAT_ARGB8888; + break; + case WL_SHM_FORMAT_XRGB8888: + cogl_format = COGL_PIXEL_FORMAT_BGRA_8888; + gbm_format = GBM_FORMAT_XRGB8888; + break; #endif - default: - g_warn_if_reached (); - cogl_format = COGL_PIXEL_FORMAT_ARGB_8888; - gbm_format = GBM_FORMAT_ARGB8888; + default: + g_warn_if_reached (); + cogl_format = COGL_PIXEL_FORMAT_ARGB_8888; + gbm_format = GBM_FORMAT_ARGB8888; } image->texture = cogl_texture_2d_new_from_data (cogl_context, @@ -390,7 +390,7 @@ meta_cursor_image_load_from_buffer (MetaCursorTracker *tracker, if (!image->bo) meta_warning ("Importing HW cursor from wl_buffer failed\n"); } - } + } } MetaCursorReference * From ba131626c28a22cda3f3b547f465ba25a039413e Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 31 Mar 2014 17:48:51 -0400 Subject: [PATCH 795/889] cursor: Always use cogl_wayland_texture_2d_new_from_buffer It makes our life so much easier. --- src/core/meta-cursor.c | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/src/core/meta-cursor.c b/src/core/meta-cursor.c index f08af08c7..2163ccb3c 100644 --- a/src/core/meta-cursor.c +++ b/src/core/meta-cursor.c @@ -283,9 +283,9 @@ meta_cursor_image_load_from_buffer (MetaCursorTracker *tracker, { ClutterBackend *backend; CoglContext *cogl_context; - CoglPixelFormat cogl_format; struct wl_shm_buffer *shm_buffer; uint32_t gbm_format; + int width, height; image->hot_x = hot_x; image->hot_y = hot_y; @@ -293,47 +293,38 @@ meta_cursor_image_load_from_buffer (MetaCursorTracker *tracker, backend = clutter_get_default_backend (); cogl_context = clutter_backend_get_cogl_context (backend); + image->texture = cogl_wayland_texture_2d_new_from_buffer (cogl_context, buffer, NULL); + + width = cogl_texture_get_width (COGL_TEXTURE (image->texture)); + height = cogl_texture_get_height (COGL_TEXTURE (image->texture)); + shm_buffer = wl_shm_buffer_get (buffer); if (shm_buffer) { int rowstride = wl_shm_buffer_get_stride (shm_buffer); - int width = wl_shm_buffer_get_width (shm_buffer); - int height = wl_shm_buffer_get_height (shm_buffer); switch (wl_shm_buffer_get_format (shm_buffer)) { #if G_BYTE_ORDER == G_BIG_ENDIAN case WL_SHM_FORMAT_ARGB8888: - cogl_format = COGL_PIXEL_FORMAT_ARGB_8888_PRE; gbm_format = GBM_FORMAT_ARGB8888; break; case WL_SHM_FORMAT_XRGB8888: - cogl_format = COGL_PIXEL_FORMAT_ARGB_8888; gbm_format = GBM_FORMAT_XRGB8888; break; #else case WL_SHM_FORMAT_ARGB8888: - cogl_format = COGL_PIXEL_FORMAT_BGRA_8888_PRE; gbm_format = GBM_FORMAT_ARGB8888; break; case WL_SHM_FORMAT_XRGB8888: - cogl_format = COGL_PIXEL_FORMAT_BGRA_8888; gbm_format = GBM_FORMAT_XRGB8888; break; #endif default: g_warn_if_reached (); - cogl_format = COGL_PIXEL_FORMAT_ARGB_8888; gbm_format = GBM_FORMAT_ARGB8888; } - image->texture = cogl_texture_2d_new_from_data (cogl_context, - width, height, - cogl_format, - rowstride, - wl_shm_buffer_get_data (shm_buffer), - NULL); - if (width > 64 || height > 64) { meta_warning ("Invalid cursor size (must be at most 64x64), falling back to software (GL) cursors\n"); @@ -365,12 +356,6 @@ meta_cursor_image_load_from_buffer (MetaCursorTracker *tracker, } else { - int width, height; - - image->texture = cogl_wayland_texture_2d_new_from_buffer (cogl_context, buffer, NULL); - width = cogl_texture_get_width (COGL_TEXTURE (image->texture)); - height = cogl_texture_get_height (COGL_TEXTURE (image->texture)); - /* HW cursors must be 64x64, but 64x64 is huge, and no cursor theme actually uses that, so themed cursors must be padded with transparent pixels to fill the overlay. This is trivial if we have CPU access to the data, but it's not From 59e064f61023bd1d7d8df108f94958ef58b5ecea Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 31 Mar 2014 17:50:15 -0400 Subject: [PATCH 796/889] cursor: Split out code that loads an image into a GBM buffer --- src/core/meta-cursor.c | 98 +++++++++++++++++++----------------------- 1 file changed, 45 insertions(+), 53 deletions(-) diff --git a/src/core/meta-cursor.c b/src/core/meta-cursor.c index 2163ccb3c..a9bce1999 100644 --- a/src/core/meta-cursor.c +++ b/src/core/meta-cursor.c @@ -190,6 +190,40 @@ load_cursor_on_client (MetaDisplay *display, return image; } +static void +meta_cursor_image_load_gbm_buffer (struct gbm_device *gbm, + MetaCursorImage *image, + uint8_t *pixels, + int width, + int height, + int rowstride, + uint32_t gbm_format) +{ + if (width > 64 || height > 64) + { + meta_warning ("Invalid theme cursor size (must be at most 64x64)\n"); + return; + } + + if (gbm_device_is_format_supported (gbm, gbm_format, + GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE)) + { + uint8_t buf[4 * 64 * 64]; + int i; + + image->bo = gbm_bo_create (gbm, 64, 64, + gbm_format, GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE); + + memset (buf, 0, sizeof(buf)); + for (i = 0; i < height; i++) + memcpy (buf + i * 4 * 64, pixels + i * rowstride, width * 4); + + gbm_bo_write (image->bo, buf, 64 * 64 * 4); + } + else + meta_warning ("HW cursor for format %d not supported\n", gbm_format); +} + static void meta_cursor_image_load_from_xcursor_image (MetaCursorTracker *tracker, MetaCursorImage *image, @@ -221,35 +255,15 @@ meta_cursor_image_load_from_xcursor_image (MetaCursorTracker *tracker, width, height, cogl_format, rowstride, - (uint8_t*)xc_image->pixels, + (uint8_t *) xc_image->pixels, NULL); if (tracker->gbm) - { - if (width > 64 || height > 64) - { - meta_warning ("Invalid theme cursor size (must be at most 64x64)\n"); - return; - } - - if (gbm_device_is_format_supported (tracker->gbm, gbm_format, - GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE)) - { - uint32_t buf[64 * 64]; - int i; - - image->bo = gbm_bo_create (tracker->gbm, 64, 64, - gbm_format, GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE); - - memset (buf, 0, sizeof(buf)); - for (i = 0; i < height; i++) - memcpy (buf + i * 64, xc_image->pixels + i * width, width * 4); - - gbm_bo_write (image->bo, buf, 64 * 64 * 4); - } - else - meta_warning ("HW cursor for format %d not supported\n", gbm_format); - } + meta_cursor_image_load_gbm_buffer (tracker->gbm, + image, + (uint8_t *) xc_image->pixels, + width, height, rowstride, + gbm_format); } MetaCursorReference * @@ -325,34 +339,12 @@ meta_cursor_image_load_from_buffer (MetaCursorTracker *tracker, gbm_format = GBM_FORMAT_ARGB8888; } - if (width > 64 || height > 64) - { - meta_warning ("Invalid cursor size (must be at most 64x64), falling back to software (GL) cursors\n"); - return; - } - if (tracker->gbm) - { - if (gbm_device_is_format_supported (tracker->gbm, gbm_format, - GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE)) - { - uint8_t *data; - uint8_t buf[4 * 64 * 64]; - int i; - - image->bo = gbm_bo_create (tracker->gbm, 64, 64, - gbm_format, GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE); - - data = wl_shm_buffer_get_data (shm_buffer); - memset (buf, 0, sizeof(buf)); - for (i = 0; i < height; i++) - memcpy (buf + i * 4 * 64, data + i * rowstride, 4 * width); - - gbm_bo_write (image->bo, buf, 64 * 64 * 4); - } - else - meta_warning ("HW cursor for format %d not supported\n", gbm_format); - } + meta_cursor_image_load_gbm_buffer (tracker->gbm, + image, + (uint8_t *) wl_shm_buffer_get_data (shm_buffer), + width, height, rowstride, + gbm_format); } else { From f6a73bcf22b4132d107cf52393820d3ee48935d3 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 31 Mar 2014 17:59:14 -0400 Subject: [PATCH 797/889] cursor: Do less work if we don't have a connection to GBM at all --- src/core/meta-cursor.c | 60 ++++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/src/core/meta-cursor.c b/src/core/meta-cursor.c index a9bce1999..2a78328ef 100644 --- a/src/core/meta-cursor.c +++ b/src/core/meta-cursor.c @@ -315,36 +315,38 @@ meta_cursor_image_load_from_buffer (MetaCursorTracker *tracker, shm_buffer = wl_shm_buffer_get (buffer); if (shm_buffer) { - int rowstride = wl_shm_buffer_get_stride (shm_buffer); - - switch (wl_shm_buffer_get_format (shm_buffer)) - { -#if G_BYTE_ORDER == G_BIG_ENDIAN - case WL_SHM_FORMAT_ARGB8888: - gbm_format = GBM_FORMAT_ARGB8888; - break; - case WL_SHM_FORMAT_XRGB8888: - gbm_format = GBM_FORMAT_XRGB8888; - break; -#else - case WL_SHM_FORMAT_ARGB8888: - gbm_format = GBM_FORMAT_ARGB8888; - break; - case WL_SHM_FORMAT_XRGB8888: - gbm_format = GBM_FORMAT_XRGB8888; - break; -#endif - default: - g_warn_if_reached (); - gbm_format = GBM_FORMAT_ARGB8888; - } - if (tracker->gbm) - meta_cursor_image_load_gbm_buffer (tracker->gbm, - image, - (uint8_t *) wl_shm_buffer_get_data (shm_buffer), - width, height, rowstride, - gbm_format); + { + int rowstride = wl_shm_buffer_get_stride (shm_buffer); + + switch (wl_shm_buffer_get_format (shm_buffer)) + { +#if G_BYTE_ORDER == G_BIG_ENDIAN + case WL_SHM_FORMAT_ARGB8888: + gbm_format = GBM_FORMAT_ARGB8888; + break; + case WL_SHM_FORMAT_XRGB8888: + gbm_format = GBM_FORMAT_XRGB8888; + break; +#else + case WL_SHM_FORMAT_ARGB8888: + gbm_format = GBM_FORMAT_ARGB8888; + break; + case WL_SHM_FORMAT_XRGB8888: + gbm_format = GBM_FORMAT_XRGB8888; + break; +#endif + default: + g_warn_if_reached (); + gbm_format = GBM_FORMAT_ARGB8888; + } + + meta_cursor_image_load_gbm_buffer (tracker->gbm, + image, + (uint8_t *) wl_shm_buffer_get_data (shm_buffer), + width, height, rowstride, + gbm_format); + } } else { From 2a0289a21696b9bfe2a85a0d35c7ecb24fe98b0c Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 31 Mar 2014 21:50:09 -0400 Subject: [PATCH 798/889] Move the dummy monitor manager to his own subclass / file --- src/Makefile.am | 2 + src/core/meta-monitor-manager-dummy.c | 243 ++++++++++++++++++++++++++ src/core/meta-monitor-manager-dummy.h | 40 +++++ src/core/monitor.c | 201 +-------------------- 4 files changed, 290 insertions(+), 196 deletions(-) create mode 100644 src/core/meta-monitor-manager-dummy.c create mode 100644 src/core/meta-monitor-manager-dummy.h diff --git a/src/Makefile.am b/src/Makefile.am index 5f432724f..c53a6c998 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -144,6 +144,8 @@ libmutter_wayland_la_SOURCES = \ core/monitor.c \ core/monitor-config.c \ core/monitor-private.h \ + core/meta-monitor-manager-dummy.c \ + core/meta-monitor-manager-dummy.h \ core/meta-monitor-manager-kms.c \ core/meta-monitor-manager-kms.h \ core/meta-monitor-manager-xrandr.c \ diff --git a/src/core/meta-monitor-manager-dummy.c b/src/core/meta-monitor-manager-dummy.c new file mode 100644 index 000000000..cf74d9d7b --- /dev/null +++ b/src/core/meta-monitor-manager-dummy.c @@ -0,0 +1,243 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2001, 2002 Havoc Pennington + * Copyright (C) 2002, 2003 Red Hat Inc. + * Some ICCCM manager selection code derived from fvwm2, + * Copyright (C) 2001 Dominik Vogt, Matthias Clasen, and fvwm2 team + * Copyright (C) 2003 Rob Adams + * Copyright (C) 2004-2006 Elijah Newren + * Copyright (C) 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, see . + */ + +#include "config.h" + +#include "meta-monitor-manager-dummy.h" + +#define ALL_WL_TRANSFORMS ((1 << (WL_OUTPUT_TRANSFORM_FLIPPED_270 + 1)) - 1) + +struct _MetaMonitorManagerDummy +{ + MetaMonitorManager parent_instance; +}; + +struct _MetaMonitorManagerDummyClass +{ + MetaMonitorManagerClass parent_class; +}; + +G_DEFINE_TYPE (MetaMonitorManagerDummy, meta_monitor_manager_dummy, META_TYPE_MONITOR_MANAGER); + +static void +meta_monitor_manager_dummy_read_current (MetaMonitorManager *manager) +{ + manager->max_screen_width = 65535; + manager->max_screen_height = 65535; + manager->screen_width = 1024; + manager->screen_height = 768; + + manager->modes = g_new0 (MetaMonitorMode, 1); + manager->n_modes = 1; + + manager->modes[0].mode_id = 0; + manager->modes[0].width = 1024; + manager->modes[0].height = 768; + manager->modes[0].refresh_rate = 60.0; + + manager->crtcs = g_new0 (MetaCRTC, 1); + manager->n_crtcs = 1; + + manager->crtcs[0].crtc_id = 1; + manager->crtcs[0].rect.x = 0; + manager->crtcs[0].rect.y = 0; + manager->crtcs[0].rect.width = manager->modes[0].width; + manager->crtcs[0].rect.height = manager->modes[0].height; + manager->crtcs[0].current_mode = &manager->modes[0]; + manager->crtcs[0].transform = WL_OUTPUT_TRANSFORM_NORMAL; + manager->crtcs[0].all_transforms = ALL_WL_TRANSFORMS; + manager->crtcs[0].is_dirty = FALSE; + manager->crtcs[0].logical_monitor = NULL; + + manager->outputs = g_new0 (MetaOutput, 1); + manager->n_outputs = 1; + + manager->outputs[0].crtc = &manager->crtcs[0]; + manager->outputs[0].output_id = 1; + manager->outputs[0].name = g_strdup ("LVDS"); + manager->outputs[0].vendor = g_strdup ("MetaProducts Inc."); + manager->outputs[0].product = g_strdup ("unknown"); + manager->outputs[0].serial = g_strdup ("0xC0FFEE"); + manager->outputs[0].width_mm = 222; + manager->outputs[0].height_mm = 125; + manager->outputs[0].subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN; + manager->outputs[0].preferred_mode = &manager->modes[0]; + manager->outputs[0].n_modes = 1; + manager->outputs[0].modes = g_new0 (MetaMonitorMode *, 1); + manager->outputs[0].modes[0] = &manager->modes[0]; + manager->outputs[0].n_possible_crtcs = 1; + manager->outputs[0].possible_crtcs = g_new0 (MetaCRTC *, 1); + manager->outputs[0].possible_crtcs[0] = &manager->crtcs[0]; + manager->outputs[0].n_possible_clones = 0; + manager->outputs[0].possible_clones = g_new0 (MetaOutput *, 0); + manager->outputs[0].backlight = -1; + manager->outputs[0].backlight_min = 0; + manager->outputs[0].backlight_max = 0; +} + +static void +meta_monitor_manager_dummy_apply_config (MetaMonitorManager *manager, + MetaCRTCInfo **crtcs, + unsigned int n_crtcs, + MetaOutputInfo **outputs, + unsigned int n_outputs) +{ + unsigned i; + int screen_width = 0, screen_height = 0; + + for (i = 0; i < n_crtcs; i++) + { + MetaCRTCInfo *crtc_info = crtcs[i]; + MetaCRTC *crtc = crtc_info->crtc; + crtc->is_dirty = TRUE; + + if (crtc_info->mode == NULL) + { + crtc->rect.x = 0; + crtc->rect.y = 0; + crtc->rect.width = 0; + crtc->rect.height = 0; + crtc->current_mode = NULL; + } + else + { + MetaMonitorMode *mode; + MetaOutput *output; + int i, n_outputs; + int width, height; + + mode = crtc_info->mode; + + if (meta_monitor_transform_is_rotated (crtc_info->transform)) + { + width = mode->height; + height = mode->width; + } + else + { + width = mode->width; + height = mode->height; + } + + crtc->rect.x = crtc_info->x; + crtc->rect.y = crtc_info->y; + crtc->rect.width = width; + crtc->rect.height = height; + crtc->current_mode = mode; + crtc->transform = crtc_info->transform; + + screen_width = MAX (screen_width, crtc_info->x + width); + screen_height = MAX (screen_height, crtc_info->y + height); + + n_outputs = crtc_info->outputs->len; + for (i = 0; i < n_outputs; i++) + { + output = ((MetaOutput**)crtc_info->outputs->pdata)[i]; + + output->is_dirty = TRUE; + output->crtc = crtc; + } + } + } + + for (i = 0; i < n_outputs; i++) + { + MetaOutputInfo *output_info = outputs[i]; + MetaOutput *output = output_info->output; + + output->is_primary = output_info->is_primary; + output->is_presentation = output_info->is_presentation; + } + + /* Disable CRTCs not mentioned in the list */ + for (i = 0; i < manager->n_crtcs; i++) + { + MetaCRTC *crtc = &manager->crtcs[i]; + + crtc->logical_monitor = NULL; + + if (crtc->is_dirty) + { + crtc->is_dirty = FALSE; + continue; + } + + crtc->rect.x = 0; + crtc->rect.y = 0; + crtc->rect.width = 0; + crtc->rect.height = 0; + crtc->current_mode = NULL; + } + + /* Disable outputs not mentioned in the list */ + for (i = 0; i < manager->n_outputs; i++) + { + MetaOutput *output = &manager->outputs[i]; + + if (output->is_dirty) + { + output->is_dirty = FALSE; + continue; + } + + output->crtc = NULL; + output->is_primary = FALSE; + } + + manager->screen_width = screen_width; + manager->screen_height = screen_height; + + meta_monitor_manager_rebuild_derived (manager); +} + +static GBytes * +meta_monitor_manager_dummy_read_edid (MetaMonitorManager *manager, + MetaOutput *output) +{ + return NULL; +} + +static char * +meta_monitor_manager_dummy_get_edid_file (MetaMonitorManager *manager, + MetaOutput *output) +{ + return NULL; +} + +static void +meta_monitor_manager_dummy_class_init (MetaMonitorManagerDummyClass *klass) +{ + MetaMonitorManagerClass *manager_class = META_MONITOR_MANAGER_CLASS (klass); + + manager_class->read_current = meta_monitor_manager_dummy_read_current; + manager_class->apply_configuration = meta_monitor_manager_dummy_apply_config; + manager_class->get_edid_file = meta_monitor_manager_dummy_get_edid_file; + manager_class->read_edid = meta_monitor_manager_dummy_read_edid; +} + +static void +meta_monitor_manager_dummy_init (MetaMonitorManagerDummy *manager) +{ +} diff --git a/src/core/meta-monitor-manager-dummy.h b/src/core/meta-monitor-manager-dummy.h new file mode 100644 index 000000000..896838cbb --- /dev/null +++ b/src/core/meta-monitor-manager-dummy.h @@ -0,0 +1,40 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2001 Havoc Pennington + * Copyright (C) 2003 Rob Adams + * Copyright (C) 2004-2006 Elijah Newren + * Copyright (C) 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, see . + */ + +#ifndef META_MONITOR_MANAGER_DUMMY_H +#define META_MONITOR_MANAGER_DUMMY_H + +#include "monitor-private.h" + +#define META_TYPE_MONITOR_MANAGER_DUMMY (meta_monitor_manager_dummy_get_type ()) +#define META_MONITOR_MANAGER_DUMMY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_MONITOR_MANAGER_DUMMY, MetaMonitorManagerDummy)) +#define META_MONITOR_MANAGER_DUMMY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_MONITOR_MANAGER_DUMMY, MetaMonitorManagerDummyClass)) +#define META_IS_MONITOR_MANAGER_DUMMY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_MONITOR_MANAGER_DUMMY)) +#define META_IS_MONITOR_MANAGER_DUMMY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_MONITOR_MANAGER_DUMMY)) +#define META_MONITOR_MANAGER_DUMMY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_MONITOR_MANAGER_DUMMY, MetaMonitorManagerDummyClass)) + +typedef struct _MetaMonitorManagerDummyClass MetaMonitorManagerDummyClass; +typedef struct _MetaMonitorManagerDummy MetaMonitorManagerDummy; + +GType meta_monitor_manager_dummy_get_type (void); + +#endif /* META_MONITOR_MANAGER_DUMMY_H */ diff --git a/src/core/monitor.c b/src/core/monitor.c index 51fb28004..d2d9f20d5 100644 --- a/src/core/monitor.c +++ b/src/core/monitor.c @@ -36,11 +36,10 @@ #include "monitor-private.h" #include "meta-monitor-manager-kms.h" #include "meta-monitor-manager-xrandr.h" +#include "meta-monitor-manager-dummy.h" #include "meta-dbus-xrandr.h" -#define ALL_WL_TRANSFORMS ((1 << (WL_OUTPUT_TRANSFORM_FLIPPED_270 + 1)) - 1) - enum { CONFIRM_DISPLAY_CHANGE, SIGNALS_LAST @@ -56,196 +55,11 @@ static int signals[SIGNALS_LAST]; static void meta_monitor_manager_display_config_init (MetaDBusDisplayConfigIface *iface); -G_DEFINE_TYPE_WITH_CODE (MetaMonitorManager, meta_monitor_manager, META_DBUS_TYPE_DISPLAY_CONFIG_SKELETON, - G_IMPLEMENT_INTERFACE (META_DBUS_TYPE_DISPLAY_CONFIG, meta_monitor_manager_display_config_init)); +G_DEFINE_ABSTRACT_TYPE_WITH_CODE (MetaMonitorManager, meta_monitor_manager, META_DBUS_TYPE_DISPLAY_CONFIG_SKELETON, + G_IMPLEMENT_INTERFACE (META_DBUS_TYPE_DISPLAY_CONFIG, meta_monitor_manager_display_config_init)); static void initialize_dbus_interface (MetaMonitorManager *manager); -static void -read_current_dummy (MetaMonitorManager *manager) -{ - manager->max_screen_width = 65535; - manager->max_screen_height = 65535; - manager->screen_width = 1024; - manager->screen_height = 768; - - manager->modes = g_new0 (MetaMonitorMode, 1); - manager->n_modes = 1; - - manager->modes[0].mode_id = 0; - manager->modes[0].width = 1024; - manager->modes[0].height = 768; - manager->modes[0].refresh_rate = 60.0; - - manager->crtcs = g_new0 (MetaCRTC, 1); - manager->n_crtcs = 1; - - manager->crtcs[0].crtc_id = 1; - manager->crtcs[0].rect.x = 0; - manager->crtcs[0].rect.y = 0; - manager->crtcs[0].rect.width = manager->modes[0].width; - manager->crtcs[0].rect.height = manager->modes[0].height; - manager->crtcs[0].current_mode = &manager->modes[0]; - manager->crtcs[0].transform = WL_OUTPUT_TRANSFORM_NORMAL; - manager->crtcs[0].all_transforms = ALL_WL_TRANSFORMS; - manager->crtcs[0].is_dirty = FALSE; - manager->crtcs[0].logical_monitor = NULL; - - manager->outputs = g_new0 (MetaOutput, 1); - manager->n_outputs = 1; - - manager->outputs[0].crtc = &manager->crtcs[0]; - manager->outputs[0].output_id = 1; - manager->outputs[0].name = g_strdup ("LVDS"); - manager->outputs[0].vendor = g_strdup ("MetaProducts Inc."); - manager->outputs[0].product = g_strdup ("unknown"); - manager->outputs[0].serial = g_strdup ("0xC0FFEE"); - manager->outputs[0].width_mm = 222; - manager->outputs[0].height_mm = 125; - manager->outputs[0].subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN; - manager->outputs[0].preferred_mode = &manager->modes[0]; - manager->outputs[0].n_modes = 1; - manager->outputs[0].modes = g_new0 (MetaMonitorMode *, 1); - manager->outputs[0].modes[0] = &manager->modes[0]; - manager->outputs[0].n_possible_crtcs = 1; - manager->outputs[0].possible_crtcs = g_new0 (MetaCRTC *, 1); - manager->outputs[0].possible_crtcs[0] = &manager->crtcs[0]; - manager->outputs[0].n_possible_clones = 0; - manager->outputs[0].possible_clones = g_new0 (MetaOutput *, 0); - manager->outputs[0].backlight = -1; - manager->outputs[0].backlight_min = 0; - manager->outputs[0].backlight_max = 0; -} - -static void -apply_config_dummy (MetaMonitorManager *manager, - MetaCRTCInfo **crtcs, - unsigned int n_crtcs, - MetaOutputInfo **outputs, - unsigned int n_outputs) -{ - unsigned i; - int screen_width = 0, screen_height = 0; - - for (i = 0; i < n_crtcs; i++) - { - MetaCRTCInfo *crtc_info = crtcs[i]; - MetaCRTC *crtc = crtc_info->crtc; - crtc->is_dirty = TRUE; - - if (crtc_info->mode == NULL) - { - crtc->rect.x = 0; - crtc->rect.y = 0; - crtc->rect.width = 0; - crtc->rect.height = 0; - crtc->current_mode = NULL; - } - else - { - MetaMonitorMode *mode; - MetaOutput *output; - int i, n_outputs; - int width, height; - - mode = crtc_info->mode; - - if (meta_monitor_transform_is_rotated (crtc_info->transform)) - { - width = mode->height; - height = mode->width; - } - else - { - width = mode->width; - height = mode->height; - } - - crtc->rect.x = crtc_info->x; - crtc->rect.y = crtc_info->y; - crtc->rect.width = width; - crtc->rect.height = height; - crtc->current_mode = mode; - crtc->transform = crtc_info->transform; - - screen_width = MAX (screen_width, crtc_info->x + width); - screen_height = MAX (screen_height, crtc_info->y + height); - - n_outputs = crtc_info->outputs->len; - for (i = 0; i < n_outputs; i++) - { - output = ((MetaOutput**)crtc_info->outputs->pdata)[i]; - - output->is_dirty = TRUE; - output->crtc = crtc; - } - } - } - - for (i = 0; i < n_outputs; i++) - { - MetaOutputInfo *output_info = outputs[i]; - MetaOutput *output = output_info->output; - - output->is_primary = output_info->is_primary; - output->is_presentation = output_info->is_presentation; - } - - /* Disable CRTCs not mentioned in the list */ - for (i = 0; i < manager->n_crtcs; i++) - { - MetaCRTC *crtc = &manager->crtcs[i]; - - crtc->logical_monitor = NULL; - - if (crtc->is_dirty) - { - crtc->is_dirty = FALSE; - continue; - } - - crtc->rect.x = 0; - crtc->rect.y = 0; - crtc->rect.width = 0; - crtc->rect.height = 0; - crtc->current_mode = NULL; - } - - /* Disable outputs not mentioned in the list */ - for (i = 0; i < manager->n_outputs; i++) - { - MetaOutput *output = &manager->outputs[i]; - - if (output->is_dirty) - { - output->is_dirty = FALSE; - continue; - } - - output->crtc = NULL; - output->is_primary = FALSE; - } - - manager->screen_width = screen_width; - manager->screen_height = screen_height; - - meta_monitor_manager_rebuild_derived (manager); -} - -static GBytes * -read_edid_dummy (MetaMonitorManager *manager, - MetaOutput *output) -{ - return NULL; -} - -static char * -get_edid_file_dummy (MetaMonitorManager *manager, - MetaOutput *output) -{ - return NULL; -} - static void meta_monitor_manager_init (MetaMonitorManager *manager) { @@ -369,7 +183,7 @@ get_default_backend (void) * we're a nested configuration, so return the dummy * monitor setup. */ if (meta_is_wayland_compositor ()) - return META_TYPE_MONITOR_MANAGER; + return META_TYPE_MONITOR_MANAGER_DUMMY; else return META_TYPE_MONITOR_MANAGER_XRANDR; } @@ -381,7 +195,7 @@ get_default_backend (void) /* Use the dummy implementation on Wayland for now. * In the future, we should support wl_fullscreen_output * which will have CRTC management in the protocol. */ - return META_TYPE_MONITOR_MANAGER; + return META_TYPE_MONITOR_MANAGER_DUMMY; } #endif @@ -586,11 +400,6 @@ meta_monitor_manager_class_init (MetaMonitorManagerClass *klass) object_class->dispose = meta_monitor_manager_dispose; object_class->finalize = meta_monitor_manager_finalize; - klass->read_current = read_current_dummy; - klass->apply_configuration = apply_config_dummy; - klass->get_edid_file = get_edid_file_dummy; - klass->read_edid = read_edid_dummy; - signals[CONFIRM_DISPLAY_CHANGE] = g_signal_new ("confirm-display-change", G_TYPE_FROM_CLASS (object_class), From ba6584a0d7dbf0fd75865632e69111f31f666887 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 31 Mar 2014 21:57:58 -0400 Subject: [PATCH 799/889] Move monitor-config to its own header file --- src/Makefile.am | 3 +- src/core/meta-monitor-manager-xrandr.c | 1 + src/core/monitor-config.c | 2 + src/core/monitor-config.h | 55 ++++++++++++++++++++++++++ src/core/monitor-private.h | 27 ------------- src/core/monitor.c | 1 + 6 files changed, 61 insertions(+), 28 deletions(-) create mode 100644 src/core/monitor-config.h diff --git a/src/Makefile.am b/src/Makefile.am index c53a6c998..ca8fac057 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -142,8 +142,9 @@ libmutter_wayland_la_SOURCES = \ core/meta-idle-monitor-native.h \ core/meta-xrandr-shared.h \ core/monitor.c \ - core/monitor-config.c \ core/monitor-private.h \ + core/monitor-config.c \ + core/monitor-config.h \ core/meta-monitor-manager-dummy.c \ core/meta-monitor-manager-dummy.h \ core/meta-monitor-manager-kms.c \ diff --git a/src/core/meta-monitor-manager-xrandr.c b/src/core/meta-monitor-manager-xrandr.c index 59b5fbac7..5aba4877d 100644 --- a/src/core/meta-monitor-manager-xrandr.c +++ b/src/core/meta-monitor-manager-xrandr.c @@ -39,6 +39,7 @@ #include #include #include "edid.h" +#include "monitor-config.h" #define ALL_WL_TRANSFORMS ((1 << (WL_OUTPUT_TRANSFORM_FLIPPED_270 + 1)) - 1) diff --git a/src/core/monitor-config.c b/src/core/monitor-config.c index 5d69a5d52..91f3a82f2 100644 --- a/src/core/monitor-config.c +++ b/src/core/monitor-config.c @@ -34,6 +34,8 @@ #include "config.h" +#include "monitor-config.h" + #include #include #include diff --git a/src/core/monitor-config.h b/src/core/monitor-config.h new file mode 100644 index 000000000..caf4abf52 --- /dev/null +++ b/src/core/monitor-config.h @@ -0,0 +1,55 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2001 Havoc Pennington + * Copyright (C) 2003 Rob Adams + * Copyright (C) 2004-2006 Elijah Newren + * Copyright (C) 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, see . + */ + +#ifndef META_MONITOR_CONFIG_H +#define META_MONITOR_CONFIG_H + +#include "monitor-private.h" + +#define META_TYPE_MONITOR_CONFIG (meta_monitor_config_get_type ()) +#define META_MONITOR_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_MONITOR_CONFIG, MetaMonitorConfig)) +#define META_MONITOR_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_MONITOR_CONFIG, MetaMonitorConfigClass)) +#define META_IS_MONITOR_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_MONITOR_CONFIG)) +#define META_IS_MONITOR_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_MONITOR_CONFIG)) +#define META_MONITOR_CONFIG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_MONITOR_CONFIG, MetaMonitorConfigClass)) + +GType meta_monitor_config_get_type (void) G_GNUC_CONST; + +MetaMonitorConfig *meta_monitor_config_new (void); + +gboolean meta_monitor_config_match_current (MetaMonitorConfig *config, + MetaMonitorManager *manager); + +gboolean meta_monitor_config_apply_stored (MetaMonitorConfig *config, + MetaMonitorManager *manager); + +void meta_monitor_config_make_default (MetaMonitorConfig *config, + MetaMonitorManager *manager); + +void meta_monitor_config_update_current (MetaMonitorConfig *config, + MetaMonitorManager *manager); +void meta_monitor_config_make_persistent (MetaMonitorConfig *config); + +void meta_monitor_config_restore_previous (MetaMonitorConfig *config, + MetaMonitorManager *manager); + +#endif /* META_MONITOR_CONFIG_H */ diff --git a/src/core/monitor-private.h b/src/core/monitor-private.h index 7f215b57e..8fc0c57f7 100644 --- a/src/core/monitor-private.h +++ b/src/core/monitor-private.h @@ -335,33 +335,6 @@ void meta_monitor_manager_apply_configuration (MetaMonitorManager void meta_monitor_manager_confirm_configuration (MetaMonitorManager *manager, gboolean ok); -#define META_TYPE_MONITOR_CONFIG (meta_monitor_config_get_type ()) -#define META_MONITOR_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_MONITOR_CONFIG, MetaMonitorConfig)) -#define META_MONITOR_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_MONITOR_CONFIG, MetaMonitorConfigClass)) -#define META_IS_MONITOR_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_MONITOR_CONFIG)) -#define META_IS_MONITOR_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_MONITOR_CONFIG)) -#define META_MONITOR_CONFIG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_MONITOR_CONFIG, MetaMonitorConfigClass)) - -GType meta_monitor_config_get_type (void) G_GNUC_CONST; - -MetaMonitorConfig *meta_monitor_config_new (void); - -gboolean meta_monitor_config_match_current (MetaMonitorConfig *config, - MetaMonitorManager *manager); - -gboolean meta_monitor_config_apply_stored (MetaMonitorConfig *config, - MetaMonitorManager *manager); - -void meta_monitor_config_make_default (MetaMonitorConfig *config, - MetaMonitorManager *manager); - -void meta_monitor_config_update_current (MetaMonitorConfig *config, - MetaMonitorManager *manager); -void meta_monitor_config_make_persistent (MetaMonitorConfig *config); - -void meta_monitor_config_restore_previous (MetaMonitorConfig *config, - MetaMonitorManager *manager); - void meta_crtc_info_free (MetaCRTCInfo *info); void meta_output_info_free (MetaOutputInfo *info); diff --git a/src/core/monitor.c b/src/core/monitor.c index d2d9f20d5..c7e88a163 100644 --- a/src/core/monitor.c +++ b/src/core/monitor.c @@ -34,6 +34,7 @@ #include "util-private.h" #include #include "monitor-private.h" +#include "monitor-config.h" #include "meta-monitor-manager-kms.h" #include "meta-monitor-manager-xrandr.h" #include "meta-monitor-manager-dummy.h" From 28b9160c016b0cb4b8cfcfe7cbc3e6956fabcd93 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 31 Mar 2014 21:59:16 -0400 Subject: [PATCH 800/889] Rename monitor-config => meta-monitor-config --- src/Makefile.am | 4 ++-- src/core/{monitor-config.c => meta-monitor-config.c} | 2 +- src/core/{monitor-config.h => meta-monitor-config.h} | 0 src/core/meta-monitor-manager-xrandr.c | 2 +- src/core/monitor.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) rename src/core/{monitor-config.c => meta-monitor-config.c} (99%) rename src/core/{monitor-config.h => meta-monitor-config.h} (100%) diff --git a/src/Makefile.am b/src/Makefile.am index ca8fac057..d9d824229 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -143,8 +143,8 @@ libmutter_wayland_la_SOURCES = \ core/meta-xrandr-shared.h \ core/monitor.c \ core/monitor-private.h \ - core/monitor-config.c \ - core/monitor-config.h \ + core/meta-monitor-config.c \ + core/meta-monitor-config.h \ core/meta-monitor-manager-dummy.c \ core/meta-monitor-manager-dummy.h \ core/meta-monitor-manager-kms.c \ diff --git a/src/core/monitor-config.c b/src/core/meta-monitor-config.c similarity index 99% rename from src/core/monitor-config.c rename to src/core/meta-monitor-config.c index 91f3a82f2..bf57796a1 100644 --- a/src/core/monitor-config.c +++ b/src/core/meta-monitor-config.c @@ -34,7 +34,7 @@ #include "config.h" -#include "monitor-config.h" +#include "meta-monitor-config.h" #include #include diff --git a/src/core/monitor-config.h b/src/core/meta-monitor-config.h similarity index 100% rename from src/core/monitor-config.h rename to src/core/meta-monitor-config.h diff --git a/src/core/meta-monitor-manager-xrandr.c b/src/core/meta-monitor-manager-xrandr.c index 5aba4877d..86ce344ee 100644 --- a/src/core/meta-monitor-manager-xrandr.c +++ b/src/core/meta-monitor-manager-xrandr.c @@ -39,7 +39,7 @@ #include #include #include "edid.h" -#include "monitor-config.h" +#include "meta-monitor-config.h" #define ALL_WL_TRANSFORMS ((1 << (WL_OUTPUT_TRANSFORM_FLIPPED_270 + 1)) - 1) diff --git a/src/core/monitor.c b/src/core/monitor.c index c7e88a163..95f83c81d 100644 --- a/src/core/monitor.c +++ b/src/core/monitor.c @@ -34,7 +34,7 @@ #include "util-private.h" #include #include "monitor-private.h" -#include "monitor-config.h" +#include "meta-monitor-config.h" #include "meta-monitor-manager-kms.h" #include "meta-monitor-manager-xrandr.h" #include "meta-monitor-manager-dummy.h" From ccced506ed0c5776f2e458b39d8dab8f9c8d71a2 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 31 Mar 2014 22:04:10 -0400 Subject: [PATCH 801/889] Rename monitor => meta-monitor-manager --- src/Makefile.am | 4 ++-- src/compositor/meta-plugin.c | 2 +- src/compositor/meta-window-actor.c | 2 +- src/core/meta-cursor-tracker.c | 2 +- src/core/meta-monitor-config.c | 1 - src/core/meta-monitor-config.h | 2 +- src/core/meta-monitor-manager-dummy.h | 2 +- src/core/meta-monitor-manager-kms.h | 2 +- src/core/meta-monitor-manager-xrandr.h | 2 +- src/core/{monitor.c => meta-monitor-manager.c} | 3 ++- src/core/{monitor-private.h => meta-monitor-manager.h} | 2 -- src/core/screen-private.h | 2 +- src/wayland/meta-wayland-surface.c | 1 - src/wayland/meta-wayland.c | 2 +- 14 files changed, 13 insertions(+), 16 deletions(-) rename src/core/{monitor.c => meta-monitor-manager.c} (99%) rename src/core/{monitor-private.h => meta-monitor-manager.h} (99%) diff --git a/src/Makefile.am b/src/Makefile.am index d9d824229..0af758288 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -141,10 +141,10 @@ libmutter_wayland_la_SOURCES = \ core/meta-idle-monitor-native.c \ core/meta-idle-monitor-native.h \ core/meta-xrandr-shared.h \ - core/monitor.c \ - core/monitor-private.h \ core/meta-monitor-config.c \ core/meta-monitor-config.h \ + core/meta-monitor-manager.c \ + core/meta-monitor-manager.h \ core/meta-monitor-manager-dummy.c \ core/meta-monitor-manager-dummy.h \ core/meta-monitor-manager-kms.c \ diff --git a/src/compositor/meta-plugin.c b/src/compositor/meta-plugin.c index f9f6b3df0..d7c4f11d4 100644 --- a/src/compositor/meta-plugin.c +++ b/src/compositor/meta-plugin.c @@ -40,7 +40,7 @@ #include "compositor-private.h" #include "meta-window-actor-private.h" -#include "monitor-private.h" +#include "meta-monitor-manager.h" G_DEFINE_ABSTRACT_TYPE (MetaPlugin, meta_plugin, G_TYPE_OBJECT); diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 39fa7db8b..f7f32a0e5 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -27,7 +27,7 @@ #include "meta-window-actor-private.h" #include "meta-texture-rectangle.h" #include "region-utils.h" -#include "monitor-private.h" +#include "meta-monitor-manager.h" #include "meta-cullable.h" #include "meta-surface-actor.h" diff --git a/src/core/meta-cursor-tracker.c b/src/core/meta-cursor-tracker.c index 098b2511c..28a6af2fc 100644 --- a/src/core/meta-cursor-tracker.c +++ b/src/core/meta-cursor-tracker.c @@ -44,7 +44,7 @@ #include "meta-cursor-private.h" #include "meta-cursor-tracker-private.h" #include "screen-private.h" -#include "monitor-private.h" +#include "meta-monitor-manager.h" #include "wayland/meta-wayland-private.h" diff --git a/src/core/meta-monitor-config.c b/src/core/meta-monitor-config.c index bf57796a1..8150c091f 100644 --- a/src/core/meta-monitor-config.c +++ b/src/core/meta-monitor-config.c @@ -42,7 +42,6 @@ #include #include -#include "monitor-private.h" /* These structures represent the intended/persistent configuration, as stored in the monitors.xml file. diff --git a/src/core/meta-monitor-config.h b/src/core/meta-monitor-config.h index caf4abf52..840156925 100644 --- a/src/core/meta-monitor-config.h +++ b/src/core/meta-monitor-config.h @@ -23,7 +23,7 @@ #ifndef META_MONITOR_CONFIG_H #define META_MONITOR_CONFIG_H -#include "monitor-private.h" +#include "meta-monitor-manager.h" #define META_TYPE_MONITOR_CONFIG (meta_monitor_config_get_type ()) #define META_MONITOR_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_MONITOR_CONFIG, MetaMonitorConfig)) diff --git a/src/core/meta-monitor-manager-dummy.h b/src/core/meta-monitor-manager-dummy.h index 896838cbb..4f1fb349c 100644 --- a/src/core/meta-monitor-manager-dummy.h +++ b/src/core/meta-monitor-manager-dummy.h @@ -23,7 +23,7 @@ #ifndef META_MONITOR_MANAGER_DUMMY_H #define META_MONITOR_MANAGER_DUMMY_H -#include "monitor-private.h" +#include "meta-monitor-manager.h" #define META_TYPE_MONITOR_MANAGER_DUMMY (meta_monitor_manager_dummy_get_type ()) #define META_MONITOR_MANAGER_DUMMY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_MONITOR_MANAGER_DUMMY, MetaMonitorManagerDummy)) diff --git a/src/core/meta-monitor-manager-kms.h b/src/core/meta-monitor-manager-kms.h index ef75dd60c..4794e313d 100644 --- a/src/core/meta-monitor-manager-kms.h +++ b/src/core/meta-monitor-manager-kms.h @@ -23,7 +23,7 @@ #ifndef META_MONITOR_MANAGER_KMS_H #define META_MONITOR_MANAGER_KMS_H -#include "monitor-private.h" +#include "meta-monitor-manager.h" #define META_TYPE_MONITOR_MANAGER_KMS (meta_monitor_manager_kms_get_type ()) #define META_MONITOR_MANAGER_KMS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_MONITOR_MANAGER_KMS, MetaMonitorManagerKms)) diff --git a/src/core/meta-monitor-manager-xrandr.h b/src/core/meta-monitor-manager-xrandr.h index 15268e1c1..245a42e43 100644 --- a/src/core/meta-monitor-manager-xrandr.h +++ b/src/core/meta-monitor-manager-xrandr.h @@ -23,7 +23,7 @@ #ifndef META_MONITOR_MANAGER_XRANDR_H #define META_MONITOR_MANAGER_XRANDR_H -#include "monitor-private.h" +#include "meta-monitor-manager.h" #define META_TYPE_MONITOR_MANAGER_XRANDR (meta_monitor_manager_xrandr_get_type ()) #define META_MONITOR_MANAGER_XRANDR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_MONITOR_MANAGER_XRANDR, MetaMonitorManagerXrandr)) diff --git a/src/core/monitor.c b/src/core/meta-monitor-manager.c similarity index 99% rename from src/core/monitor.c rename to src/core/meta-monitor-manager.c index 95f83c81d..aaf318eb0 100644 --- a/src/core/monitor.c +++ b/src/core/meta-monitor-manager.c @@ -25,6 +25,8 @@ #include "config.h" +#include "meta-monitor-manager.h" + #include #include #include @@ -33,7 +35,6 @@ #include #include "util-private.h" #include -#include "monitor-private.h" #include "meta-monitor-config.h" #include "meta-monitor-manager-kms.h" #include "meta-monitor-manager-xrandr.h" diff --git a/src/core/monitor-private.h b/src/core/meta-monitor-manager.h similarity index 99% rename from src/core/monitor-private.h rename to src/core/meta-monitor-manager.h index 8fc0c57f7..2a553c9de 100644 --- a/src/core/monitor-private.h +++ b/src/core/meta-monitor-manager.h @@ -227,8 +227,6 @@ struct _MetaMonitorManager CRTCs refer to stuff that can drive outputs (like encoders, but less tied to the HW), while monitor_infos refer to logical ones. - - See also the comment in monitor-private.h */ MetaOutput *outputs; unsigned int n_outputs; diff --git a/src/core/screen-private.h b/src/core/screen-private.h index 78a1f9a5b..ef279e580 100644 --- a/src/core/screen-private.h +++ b/src/core/screen-private.h @@ -36,7 +36,7 @@ #include #include "stack-tracker.h" #include "ui.h" -#include "monitor-private.h" +#include "meta-monitor-manager.h" typedef void (* MetaScreenWindowFunc) (MetaScreen *screen, MetaWindow *window, gpointer user_data); diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 77ea2e563..2eb32ecb5 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -55,7 +55,6 @@ #include #include #include "frame.h" -#include "monitor-private.h" #include "meta-surface-actor.h" #include "meta-surface-actor-wayland.h" diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index 6a4a0ce4c..d27ea8d1e 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -52,7 +52,7 @@ #include #include "frame.h" #include "meta-weston-launch.h" -#include "monitor-private.h" +#include "meta-monitor-manager.h" static MetaWaylandCompositor _meta_wayland_compositor; From 229360b248a7275f690d14eae26e8e0f36d71d0b Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 31 Mar 2014 22:07:49 -0400 Subject: [PATCH 802/889] Start molding out a new src/backends/ dir Right now this just has all of the files in one directory. We'll be introducing more structure to this in the future, and build a proper backend system. --- src/Makefile.am | 49 ++++++++++--------- src/{core => backends}/meta-cursor-private.h | 0 .../meta-cursor-tracker-private.h | 0 src/{core => backends}/meta-cursor-tracker.c | 0 src/{core => backends}/meta-cursor.c | 0 src/{core => backends}/meta-cursor.h | 0 .../meta-idle-monitor-dbus.c | 0 .../meta-idle-monitor-dbus.h | 0 .../meta-idle-monitor-native.c | 0 .../meta-idle-monitor-native.h | 0 .../meta-idle-monitor-private.h | 0 .../meta-idle-monitor-xsync.c | 0 .../meta-idle-monitor-xsync.h | 0 src/{core => backends}/meta-idle-monitor.c | 0 src/{core => backends}/meta-monitor-config.c | 0 src/{core => backends}/meta-monitor-config.h | 0 .../meta-monitor-manager-dummy.c | 0 .../meta-monitor-manager-dummy.h | 0 .../meta-monitor-manager-kms.c | 0 .../meta-monitor-manager-kms.h | 0 .../meta-monitor-manager-xrandr.c | 0 .../meta-monitor-manager-xrandr.h | 0 src/{core => backends}/meta-monitor-manager.c | 0 src/{core => backends}/meta-monitor-manager.h | 0 src/{core => backends}/meta-xrandr-shared.h | 0 25 files changed, 25 insertions(+), 24 deletions(-) rename src/{core => backends}/meta-cursor-private.h (100%) rename src/{core => backends}/meta-cursor-tracker-private.h (100%) rename src/{core => backends}/meta-cursor-tracker.c (100%) rename src/{core => backends}/meta-cursor.c (100%) rename src/{core => backends}/meta-cursor.h (100%) rename src/{core => backends}/meta-idle-monitor-dbus.c (100%) rename src/{core => backends}/meta-idle-monitor-dbus.h (100%) rename src/{core => backends}/meta-idle-monitor-native.c (100%) rename src/{core => backends}/meta-idle-monitor-native.h (100%) rename src/{core => backends}/meta-idle-monitor-private.h (100%) rename src/{core => backends}/meta-idle-monitor-xsync.c (100%) rename src/{core => backends}/meta-idle-monitor-xsync.h (100%) rename src/{core => backends}/meta-idle-monitor.c (100%) rename src/{core => backends}/meta-monitor-config.c (100%) rename src/{core => backends}/meta-monitor-config.h (100%) rename src/{core => backends}/meta-monitor-manager-dummy.c (100%) rename src/{core => backends}/meta-monitor-manager-dummy.h (100%) rename src/{core => backends}/meta-monitor-manager-kms.c (100%) rename src/{core => backends}/meta-monitor-manager-kms.h (100%) rename src/{core => backends}/meta-monitor-manager-xrandr.c (100%) rename src/{core => backends}/meta-monitor-manager-xrandr.h (100%) rename src/{core => backends}/meta-monitor-manager.c (100%) rename src/{core => backends}/meta-monitor-manager.h (100%) rename src/{core => backends}/meta-xrandr-shared.h (100%) diff --git a/src/Makefile.am b/src/Makefile.am index 0af758288..4912f354e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -13,6 +13,7 @@ INCLUDES= \ $(MUTTER_CFLAGS) \ -I$(top_builddir) \ -I$(srcdir) \ + -I$(srcdir)/backends \ -I$(srcdir)/core \ -I$(srcdir)/ui \ -I$(srcdir)/compositor \ @@ -50,6 +51,30 @@ wayland_protocols = \ wayland/protocol/xserver.xml libmutter_wayland_la_SOURCES = \ + backends/meta-cursor.c \ + backends/meta-cursor.h \ + backends/meta-cursor-private.h \ + backends/meta-cursor-tracker.c \ + backends/meta-cursor-tracker-private.h \ + backends/meta-idle-monitor.c \ + backends/meta-idle-monitor-private.h \ + backends/meta-idle-monitor-dbus.c \ + backends/meta-idle-monitor-dbus.h \ + backends/meta-idle-monitor-xsync.c \ + backends/meta-idle-monitor-xsync.h \ + backends/meta-idle-monitor-native.c \ + backends/meta-idle-monitor-native.h \ + backends/meta-xrandr-shared.h \ + backends/meta-monitor-config.c \ + backends/meta-monitor-config.h \ + backends/meta-monitor-manager.c \ + backends/meta-monitor-manager.h \ + backends/meta-monitor-manager-dummy.c \ + backends/meta-monitor-manager-dummy.h \ + backends/meta-monitor-manager-kms.c \ + backends/meta-monitor-manager-kms.h \ + backends/meta-monitor-manager-xrandr.c \ + backends/meta-monitor-manager-xrandr.h \ core/above-tab-keycode.c \ core/barrier.c \ meta/barrier.h \ @@ -127,30 +152,6 @@ libmutter_wayland_la_SOURCES = \ core/keybindings.c \ core/keybindings-private.h \ core/main.c \ - core/meta-cursor.c \ - core/meta-cursor.h \ - core/meta-cursor-private.h \ - core/meta-cursor-tracker.c \ - core/meta-cursor-tracker-private.h \ - core/meta-idle-monitor.c \ - core/meta-idle-monitor-private.h \ - core/meta-idle-monitor-dbus.c \ - core/meta-idle-monitor-dbus.h \ - core/meta-idle-monitor-xsync.c \ - core/meta-idle-monitor-xsync.h \ - core/meta-idle-monitor-native.c \ - core/meta-idle-monitor-native.h \ - core/meta-xrandr-shared.h \ - core/meta-monitor-config.c \ - core/meta-monitor-config.h \ - core/meta-monitor-manager.c \ - core/meta-monitor-manager.h \ - core/meta-monitor-manager-dummy.c \ - core/meta-monitor-manager-dummy.h \ - core/meta-monitor-manager-kms.c \ - core/meta-monitor-manager-kms.h \ - core/meta-monitor-manager-xrandr.c \ - core/meta-monitor-manager-xrandr.h \ core/mutter-Xatomtype.h \ core/place.c \ core/place.h \ diff --git a/src/core/meta-cursor-private.h b/src/backends/meta-cursor-private.h similarity index 100% rename from src/core/meta-cursor-private.h rename to src/backends/meta-cursor-private.h diff --git a/src/core/meta-cursor-tracker-private.h b/src/backends/meta-cursor-tracker-private.h similarity index 100% rename from src/core/meta-cursor-tracker-private.h rename to src/backends/meta-cursor-tracker-private.h diff --git a/src/core/meta-cursor-tracker.c b/src/backends/meta-cursor-tracker.c similarity index 100% rename from src/core/meta-cursor-tracker.c rename to src/backends/meta-cursor-tracker.c diff --git a/src/core/meta-cursor.c b/src/backends/meta-cursor.c similarity index 100% rename from src/core/meta-cursor.c rename to src/backends/meta-cursor.c diff --git a/src/core/meta-cursor.h b/src/backends/meta-cursor.h similarity index 100% rename from src/core/meta-cursor.h rename to src/backends/meta-cursor.h diff --git a/src/core/meta-idle-monitor-dbus.c b/src/backends/meta-idle-monitor-dbus.c similarity index 100% rename from src/core/meta-idle-monitor-dbus.c rename to src/backends/meta-idle-monitor-dbus.c diff --git a/src/core/meta-idle-monitor-dbus.h b/src/backends/meta-idle-monitor-dbus.h similarity index 100% rename from src/core/meta-idle-monitor-dbus.h rename to src/backends/meta-idle-monitor-dbus.h diff --git a/src/core/meta-idle-monitor-native.c b/src/backends/meta-idle-monitor-native.c similarity index 100% rename from src/core/meta-idle-monitor-native.c rename to src/backends/meta-idle-monitor-native.c diff --git a/src/core/meta-idle-monitor-native.h b/src/backends/meta-idle-monitor-native.h similarity index 100% rename from src/core/meta-idle-monitor-native.h rename to src/backends/meta-idle-monitor-native.h diff --git a/src/core/meta-idle-monitor-private.h b/src/backends/meta-idle-monitor-private.h similarity index 100% rename from src/core/meta-idle-monitor-private.h rename to src/backends/meta-idle-monitor-private.h diff --git a/src/core/meta-idle-monitor-xsync.c b/src/backends/meta-idle-monitor-xsync.c similarity index 100% rename from src/core/meta-idle-monitor-xsync.c rename to src/backends/meta-idle-monitor-xsync.c diff --git a/src/core/meta-idle-monitor-xsync.h b/src/backends/meta-idle-monitor-xsync.h similarity index 100% rename from src/core/meta-idle-monitor-xsync.h rename to src/backends/meta-idle-monitor-xsync.h diff --git a/src/core/meta-idle-monitor.c b/src/backends/meta-idle-monitor.c similarity index 100% rename from src/core/meta-idle-monitor.c rename to src/backends/meta-idle-monitor.c diff --git a/src/core/meta-monitor-config.c b/src/backends/meta-monitor-config.c similarity index 100% rename from src/core/meta-monitor-config.c rename to src/backends/meta-monitor-config.c diff --git a/src/core/meta-monitor-config.h b/src/backends/meta-monitor-config.h similarity index 100% rename from src/core/meta-monitor-config.h rename to src/backends/meta-monitor-config.h diff --git a/src/core/meta-monitor-manager-dummy.c b/src/backends/meta-monitor-manager-dummy.c similarity index 100% rename from src/core/meta-monitor-manager-dummy.c rename to src/backends/meta-monitor-manager-dummy.c diff --git a/src/core/meta-monitor-manager-dummy.h b/src/backends/meta-monitor-manager-dummy.h similarity index 100% rename from src/core/meta-monitor-manager-dummy.h rename to src/backends/meta-monitor-manager-dummy.h diff --git a/src/core/meta-monitor-manager-kms.c b/src/backends/meta-monitor-manager-kms.c similarity index 100% rename from src/core/meta-monitor-manager-kms.c rename to src/backends/meta-monitor-manager-kms.c diff --git a/src/core/meta-monitor-manager-kms.h b/src/backends/meta-monitor-manager-kms.h similarity index 100% rename from src/core/meta-monitor-manager-kms.h rename to src/backends/meta-monitor-manager-kms.h diff --git a/src/core/meta-monitor-manager-xrandr.c b/src/backends/meta-monitor-manager-xrandr.c similarity index 100% rename from src/core/meta-monitor-manager-xrandr.c rename to src/backends/meta-monitor-manager-xrandr.c diff --git a/src/core/meta-monitor-manager-xrandr.h b/src/backends/meta-monitor-manager-xrandr.h similarity index 100% rename from src/core/meta-monitor-manager-xrandr.h rename to src/backends/meta-monitor-manager-xrandr.h diff --git a/src/core/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c similarity index 100% rename from src/core/meta-monitor-manager.c rename to src/backends/meta-monitor-manager.c diff --git a/src/core/meta-monitor-manager.h b/src/backends/meta-monitor-manager.h similarity index 100% rename from src/core/meta-monitor-manager.h rename to src/backends/meta-monitor-manager.h diff --git a/src/core/meta-xrandr-shared.h b/src/backends/meta-xrandr-shared.h similarity index 100% rename from src/core/meta-xrandr-shared.h rename to src/backends/meta-xrandr-shared.h From 2cf185b4e45f5c3a3e233ef3d7f95f681071d794 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 31 Mar 2014 22:11:44 -0400 Subject: [PATCH 803/889] Move mutter-Xatomtype to x11/ --- src/Makefile.am | 2 +- src/{core => x11}/mutter-Xatomtype.h | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename src/{core => x11}/mutter-Xatomtype.h (100%) diff --git a/src/Makefile.am b/src/Makefile.am index 4912f354e..e7fad42de 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -152,7 +152,6 @@ libmutter_wayland_la_SOURCES = \ core/keybindings.c \ core/keybindings-private.h \ core/main.c \ - core/mutter-Xatomtype.h \ core/place.c \ core/place.h \ core/prefs.c \ @@ -207,6 +206,7 @@ libmutter_wayland_la_SOURCES = \ x11/window-x11-private.h \ x11/xprops.c \ x11/xprops.h \ + x11/mutter-Xatomtype.h \ wayland/meta-wayland.c \ wayland/meta-wayland.h \ wayland/meta-wayland-private.h \ diff --git a/src/core/mutter-Xatomtype.h b/src/x11/mutter-Xatomtype.h similarity index 100% rename from src/core/mutter-Xatomtype.h rename to src/x11/mutter-Xatomtype.h From 20547e3b63c623e0de25755de49be491b6b3322b Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 31 Mar 2014 22:47:45 -0400 Subject: [PATCH 804/889] Move weston-launch to backends/ It's about display servers, not Wayland integration. --- src/Makefile.am | 6 +++--- src/{wayland => backends}/meta-weston-launch.c | 2 +- src/{wayland => backends}/meta-weston-launch.h | 0 src/{wayland => backends}/weston-launch.c | 0 src/{wayland => backends}/weston-launch.h | 0 5 files changed, 4 insertions(+), 4 deletions(-) rename src/{wayland => backends}/meta-weston-launch.c (99%) rename src/{wayland => backends}/meta-weston-launch.h (100%) rename src/{wayland => backends}/weston-launch.c (100%) rename src/{wayland => backends}/weston-launch.h (100%) diff --git a/src/Makefile.am b/src/Makefile.am index e7fad42de..6eb4dc518 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -75,6 +75,8 @@ libmutter_wayland_la_SOURCES = \ backends/meta-monitor-manager-kms.h \ backends/meta-monitor-manager-xrandr.c \ backends/meta-monitor-manager-xrandr.h \ + backends/meta-weston-launch.c \ + backends/meta-weston-launch.h \ core/above-tab-keycode.c \ core/barrier.c \ meta/barrier.h \ @@ -226,8 +228,6 @@ libmutter_wayland_la_SOURCES = \ wayland/meta-wayland-surface.h \ wayland/meta-wayland-types.h \ wayland/meta-wayland-versions.h \ - wayland/meta-weston-launch.c \ - wayland/meta-weston-launch.h \ wayland/window-wayland.c \ wayland/window-wayland.h @@ -286,7 +286,7 @@ mutter_wayland_LDADD = $(MUTTER_LIBS) libmutter-wayland.la bin_PROGRAMS+=mutter-launch -mutter_launch_SOURCES = wayland/weston-launch.c wayland/weston-launch.h +mutter_launch_SOURCES = backends/weston-launch.c backends/weston-launch.h mutter_launch_CFLAGS = $(MUTTER_LAUNCH_CFLAGS) -DLIBDIR=\"$(libdir)\" mutter_launch_LDFLAGS = $(MUTTER_LAUNCH_LIBS) -lpam diff --git a/src/wayland/meta-weston-launch.c b/src/backends/meta-weston-launch.c similarity index 99% rename from src/wayland/meta-weston-launch.c rename to src/backends/meta-weston-launch.c index 6ef5c6908..a77b2eaf7 100644 --- a/src/wayland/meta-weston-launch.c +++ b/src/backends/meta-weston-launch.c @@ -42,7 +42,7 @@ #include #include -#include "meta-wayland-private.h" +#include "wayland/meta-wayland-private.h" #include "meta-cursor-tracker-private.h" #include "meta-weston-launch.h" diff --git a/src/wayland/meta-weston-launch.h b/src/backends/meta-weston-launch.h similarity index 100% rename from src/wayland/meta-weston-launch.h rename to src/backends/meta-weston-launch.h diff --git a/src/wayland/weston-launch.c b/src/backends/weston-launch.c similarity index 100% rename from src/wayland/weston-launch.c rename to src/backends/weston-launch.c diff --git a/src/wayland/weston-launch.h b/src/backends/weston-launch.h similarity index 100% rename from src/wayland/weston-launch.h rename to src/backends/weston-launch.h From e22e9f5df562bf9986afd960a86453e82869394a Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 31 Mar 2014 22:55:13 -0400 Subject: [PATCH 805/889] main: Refactor some code slightly --- src/core/main.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/core/main.c b/src/core/main.c index d4a8ac3f8..4ccf75a07 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -318,19 +318,17 @@ static GSourceFuncs event_funcs = { static void meta_clutter_init (void) { + GSource *source; + clutter_x11_set_display (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ())); clutter_x11_disable_event_retrieval (); - if (CLUTTER_INIT_SUCCESS == clutter_init (NULL, NULL)) - { - GSource *source = g_source_new (&event_funcs, sizeof (GSource)); - g_source_attach (source, NULL); - g_source_unref (source); - } - else - { - meta_fatal ("Unable to initialize Clutter.\n"); - } + if (clutter_init (NULL, NULL) != CLUTTER_INIT_SUCCESS) + meta_fatal ("Unable to initialize Clutter.\n"); + + source = g_source_new (&event_funcs, sizeof (GSource)); + g_source_attach (source, NULL); + g_source_unref (source); } /** From 89b931435d386c647ac17b2a60355ff7d10447a8 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 31 Mar 2014 23:00:07 -0400 Subject: [PATCH 806/889] Move meta_clutter_init into a new file We'll use this to get the initialization between the Wayland and X11 compositor codepaths back in sync. --- src/Makefile.am | 2 + src/backends/meta-backend.c | 95 +++++++++++++++++++++++++++++++++++++ src/backends/meta-backend.h | 30 ++++++++++++ src/core/main.c | 67 +------------------------- 4 files changed, 128 insertions(+), 66 deletions(-) create mode 100644 src/backends/meta-backend.c create mode 100644 src/backends/meta-backend.h diff --git a/src/Makefile.am b/src/Makefile.am index 6eb4dc518..a1983bd99 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -51,6 +51,8 @@ wayland_protocols = \ wayland/protocol/xserver.xml libmutter_wayland_la_SOURCES = \ + backends/meta-backend.c \ + backends/meta-backend.h \ backends/meta-cursor.c \ backends/meta-cursor.h \ backends/meta-cursor-private.h \ diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c new file mode 100644 index 000000000..b4de3f674 --- /dev/null +++ b/src/backends/meta-backend.c @@ -0,0 +1,95 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2014 Red Hat + * + * 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. + * + * Written by: + * Jasper St. Pierre + */ + +#include "config.h" + +#include "meta-backend.h" + +#include +#include +#include + +/* Mutter is responsible for pulling events off the X queue, so Clutter + * doesn't need (and shouldn't) run its normal event source which polls + * the X fd, but we do have to deal with dispatching events that accumulate + * in the clutter queue. This happens, for example, when clutter generate + * enter/leave events on mouse motion - several events are queued in the + * clutter queue but only one dispatched. It could also happen because of + * explicit calls to clutter_event_put(). We add a very simple custom + * event loop source which is simply responsible for pulling events off + * of the queue and dispatching them before we block for new events. + */ + +static gboolean +event_prepare (GSource *source, + gint *timeout_) +{ + *timeout_ = -1; + + return clutter_events_pending (); +} + +static gboolean +event_check (GSource *source) +{ + return clutter_events_pending (); +} + +static gboolean +event_dispatch (GSource *source, + GSourceFunc callback, + gpointer user_data) +{ + ClutterEvent *event = clutter_event_get (); + + if (event) + { + clutter_do_event (event); + clutter_event_free (event); + } + + return TRUE; +} + +static GSourceFuncs event_funcs = { + event_prepare, + event_check, + event_dispatch +}; + +void +meta_clutter_init (void) +{ + GSource *source; + + clutter_x11_set_display (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ())); + clutter_x11_disable_event_retrieval (); + + if (clutter_init (NULL, NULL) != CLUTTER_INIT_SUCCESS) + g_error ("Unable to initialize Clutter.\n"); + + source = g_source_new (&event_funcs, sizeof (GSource)); + g_source_attach (source, NULL); + g_source_unref (source); +} diff --git a/src/backends/meta-backend.h b/src/backends/meta-backend.h new file mode 100644 index 000000000..4c4ee1fc3 --- /dev/null +++ b/src/backends/meta-backend.h @@ -0,0 +1,30 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2014 Red Hat + * + * 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. + * + * Written by: + * Jasper St. Pierre + */ + +#ifndef META_BACKEND_H +#define META_BACKEND_H + +void meta_clutter_init (void); + +#endif /* META_BACKEND_H */ diff --git a/src/core/main.c b/src/core/main.c index 4ccf75a07..c0aeeb651 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -55,7 +55,6 @@ #include #include -#include #include #include @@ -71,7 +70,6 @@ #include #include -#include #ifdef HAVE_INTROSPECTION #include @@ -80,6 +78,7 @@ #include "x11/session.h" #include "wayland/meta-wayland.h" +#include "backends/meta-backend.h" /* * The exit code we'll return to our parent process when we eventually die. @@ -267,70 +266,6 @@ meta_get_option_context (void) return ctx; } -/* Mutter is responsible for pulling events off the X queue, so Clutter - * doesn't need (and shouldn't) run its normal event source which polls - * the X fd, but we do have to deal with dispatching events that accumulate - * in the clutter queue. This happens, for example, when clutter generate - * enter/leave events on mouse motion - several events are queued in the - * clutter queue but only one dispatched. It could also happen because of - * explicit calls to clutter_event_put(). We add a very simple custom - * event loop source which is simply responsible for pulling events off - * of the queue and dispatching them before we block for new events. - */ - -static gboolean -event_prepare (GSource *source, - gint *timeout_) -{ - *timeout_ = -1; - - return clutter_events_pending (); -} - -static gboolean -event_check (GSource *source) -{ - return clutter_events_pending (); -} - -static gboolean -event_dispatch (GSource *source, - GSourceFunc callback, - gpointer user_data) -{ - ClutterEvent *event = clutter_event_get (); - - if (event) - { - clutter_do_event (event); - clutter_event_free (event); - } - - return TRUE; -} - -static GSourceFuncs event_funcs = { - event_prepare, - event_check, - event_dispatch -}; - -static void -meta_clutter_init (void) -{ - GSource *source; - - clutter_x11_set_display (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ())); - clutter_x11_disable_event_retrieval (); - - if (clutter_init (NULL, NULL) != CLUTTER_INIT_SUCCESS) - meta_fatal ("Unable to initialize Clutter.\n"); - - source = g_source_new (&event_funcs, sizeof (GSource)); - g_source_attach (source, NULL); - g_source_unref (source); -} - /** * meta_select_display: * From 521125b672fbde33090f1c67b5051db2fd8404a3 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 31 Mar 2014 23:04:44 -0400 Subject: [PATCH 807/889] meta-wayland: Use meta_clutter_init --- src/wayland/meta-wayland.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index d27ea8d1e..2e5635321 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -37,6 +37,8 @@ #include +#include "backends/meta-backend.h" + #include "meta-wayland-private.h" #include "meta-xwayland-private.h" #include "meta-wayland-stage.h" @@ -634,8 +636,7 @@ meta_wayland_init (void) compositor->launcher = meta_launcher_new (); #endif - if (clutter_init (NULL, NULL) != CLUTTER_INIT_SUCCESS) - g_error ("Failed to initialize Clutter"); + meta_clutter_init (); meta_monitor_manager_initialize (); monitors = meta_monitor_manager_get (); From 5bcc78498f4a31076672c1770c579bdd8effc37b Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 31 Mar 2014 23:19:13 -0400 Subject: [PATCH 808/889] Move MetaLauncher to meta-backend --- src/backends/meta-backend.c | 46 ++++++++++++++++++++++++++++++ src/backends/meta-backend.h | 4 +++ src/core/keybindings.c | 4 +-- src/core/main.c | 26 ----------------- src/meta/main.h | 2 +- src/wayland/meta-wayland-private.h | 3 -- src/wayland/meta-wayland.c | 42 --------------------------- src/wayland/meta-wayland.h | 6 ---- 8 files changed, 53 insertions(+), 80 deletions(-) diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c index b4de3f674..f464425b3 100644 --- a/src/backends/meta-backend.c +++ b/src/backends/meta-backend.c @@ -25,11 +25,14 @@ #include "config.h" #include "meta-backend.h" +#include #include #include #include +#include "meta-weston-launch.h" + /* Mutter is responsible for pulling events off the X queue, so Clutter * doesn't need (and shouldn't) run its normal event source which polls * the X fd, but we do have to deal with dispatching events that accumulate @@ -78,6 +81,8 @@ static GSourceFuncs event_funcs = { event_dispatch }; +static MetaLauncher *launcher; + void meta_clutter_init (void) { @@ -86,6 +91,13 @@ meta_clutter_init (void) clutter_x11_set_display (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ())); clutter_x11_disable_event_retrieval (); + /* If we're running on bare metal, we're a display server, + * so start talking to weston-launch. */ +#if defined(CLUTTER_WINDOWING_EGL) + if (clutter_check_windowing_backend (CLUTTER_WINDOWING_EGL)) + launcher = meta_launcher_new (); +#endif + if (clutter_init (NULL, NULL) != CLUTTER_INIT_SUCCESS) g_error ("Unable to initialize Clutter.\n"); @@ -93,3 +105,37 @@ meta_clutter_init (void) g_source_attach (source, NULL); g_source_unref (source); } + +gboolean +meta_activate_vt (int vt, GError **error) +{ + if (launcher) + return meta_launcher_activate_vt (launcher, vt, error); + else + { + g_debug ("Ignoring VT switch keybinding, not running as display server"); + return TRUE; + } +} + +/** + * meta_activate_session: + * + * Tells mutter to activate the session. When mutter is a + * Wayland compositor, this tells logind to switch over to + * the new session. + */ +gboolean +meta_activate_session (void) +{ + GError *error = NULL; + + if (!meta_launcher_activate_vt (launcher, -1, &error)) + { + g_warning ("Could not activate session: %s\n", error->message); + g_error_free (error); + return FALSE; + } + + return TRUE; +} diff --git a/src/backends/meta-backend.h b/src/backends/meta-backend.h index 4c4ee1fc3..03d8a5633 100644 --- a/src/backends/meta-backend.h +++ b/src/backends/meta-backend.h @@ -25,6 +25,10 @@ #ifndef META_BACKEND_H #define META_BACKEND_H +#include + void meta_clutter_init (void); +gboolean meta_activate_vt (int vt, GError **error); + #endif /* META_BACKEND_H */ diff --git a/src/core/keybindings.c b/src/core/keybindings.c index 8f787b78d..e663311fb 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -52,6 +52,7 @@ #endif #include "wayland/meta-wayland.h" +#include "meta-backend.h" #define SCHEMA_COMMON_KEYBINDINGS "org.gnome.desktop.wm.keybindings" #define SCHEMA_MUTTER_KEYBINDINGS "org.gnome.mutter.keybindings" @@ -3181,10 +3182,9 @@ handle_switch_vt (MetaDisplay *display, gpointer dummy) { gint vt = binding->handler->data; - MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); GError *error = NULL; - if (!meta_wayland_compositor_activate_vt (compositor, vt, &error)) + if (!meta_activate_vt (vt, &error)) { g_warning ("Failed to switch VT: %s", error->message); g_error_free (error); diff --git a/src/core/main.c b/src/core/main.c index c0aeeb651..a3d000e0a 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -437,32 +437,6 @@ meta_register_with_session (void) g_free (opt_client_id); } -/** - * meta_activate_session: - * - * Tells mutter to activate the session. When mutter is a - * Wayland compositor, this tells logind to switch over to - * the new session. - */ -gboolean -meta_activate_session (void) -{ - if (meta_is_wayland_compositor ()) - { - MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); - GError *error = NULL; - - if (!meta_wayland_compositor_activate_session (compositor, &error)) - { - g_warning ("Could not activate session: %s\n", error->message); - g_error_free (error); - return FALSE; - } - } - - return TRUE; -} - /** * meta_run: (skip) * diff --git a/src/meta/main.h b/src/meta/main.h index 9a748099e..82f05a018 100644 --- a/src/meta/main.h +++ b/src/meta/main.h @@ -28,7 +28,7 @@ GOptionContext *meta_get_option_context (void); void meta_init (void); int meta_run (void); void meta_register_with_session (void); -gboolean meta_activate_session (void); +gboolean meta_activate_session (void); /* Actually defined in meta-backend.c */ gboolean meta_get_replace_current_wm (void); /* Actually defined in util.c */ void meta_set_wm_name (const char *wm_name); diff --git a/src/wayland/meta-wayland-private.h b/src/wayland/meta-wayland-private.h index a2a2b90a5..d575e2f0c 100644 --- a/src/wayland/meta-wayland-private.h +++ b/src/wayland/meta-wayland-private.h @@ -27,7 +27,6 @@ #include #include "window-private.h" -#include "meta-weston-launch.h" #include #include "meta-wayland.h" @@ -85,8 +84,6 @@ struct _MetaWaylandCompositor MetaXWaylandManager xwayland_manager; - MetaLauncher *launcher; - MetaWaylandSeat *seat; }; diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index 2e5635321..1d9be56ad 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -53,7 +53,6 @@ #include #include #include "frame.h" -#include "meta-weston-launch.h" #include "meta-monitor-manager.h" static MetaWaylandCompositor _meta_wayland_compositor; @@ -629,13 +628,6 @@ meta_wayland_init (void) clutter_wayland_set_compositor_display (compositor->wayland_display); - /* If we're running on bare metal, we're a display server, - * so start talking to weston-launch. */ -#if defined(CLUTTER_WINDOWING_EGL) - if (clutter_check_windowing_backend (CLUTTER_WINDOWING_EGL)) - compositor->launcher = meta_launcher_new (); -#endif - meta_clutter_init (); meta_monitor_manager_initialize (); @@ -688,38 +680,4 @@ meta_wayland_finalize (void) compositor = meta_wayland_compositor_get_default (); meta_xwayland_stop (&compositor->xwayland_manager); - - if (compositor->launcher) - meta_launcher_free (compositor->launcher); -} - -gboolean -meta_wayland_compositor_activate_vt (MetaWaylandCompositor *compositor, - int vt, - GError **error) -{ - if (compositor->launcher) - { - return meta_launcher_activate_vt (compositor->launcher, vt, error); - } - else - { - g_debug ("Ignoring VT switch keybinding, not running as display server"); - return TRUE; - } -} - -gboolean -meta_wayland_compositor_activate_session (MetaWaylandCompositor *compositor, - GError **error) -{ - if (compositor->launcher) - { - return meta_launcher_activate_vt (compositor->launcher, -1, error); - } - else - { - g_debug ("Ignoring activate_session, not running as display server"); - return TRUE; - } } diff --git a/src/wayland/meta-wayland.h b/src/wayland/meta-wayland.h index 81bb2e535..4f12660d9 100644 --- a/src/wayland/meta-wayland.h +++ b/src/wayland/meta-wayland.h @@ -43,11 +43,5 @@ void meta_wayland_compositor_update (MetaWaylandComp const ClutterEvent *event); void meta_wayland_compositor_paint_finished (MetaWaylandCompositor *compositor); -gboolean meta_wayland_compositor_activate_vt (MetaWaylandCompositor *compositor, - int vt, - GError **error); -gboolean meta_wayland_compositor_activate_session (MetaWaylandCompositor *compositor, - GError **error); - #endif From b641d9d5a8abb35443afe9140a60ca40ecd49bd1 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 31 Mar 2014 23:31:42 -0400 Subject: [PATCH 809/889] Rename the DBus interface files --- src/Makefile.am | 12 ++++++------ ...xrandr.xml => org.gnome.Mutter.DisplayConfig.xml} | 0 ...-monitor.xml => org.gnome.Mutter.IdleMonitor.xml} | 0 3 files changed, 6 insertions(+), 6 deletions(-) rename src/{xrandr.xml => org.gnome.Mutter.DisplayConfig.xml} (100%) rename src/{idle-monitor.xml => org.gnome.Mutter.IdleMonitor.xml} (100%) diff --git a/src/Makefile.am b/src/Makefile.am index a1983bd99..b8f055728 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -390,7 +390,8 @@ EXTRA_DIST=$(desktopfiles_files) \ libmutter-wayland.pc.in \ mutter-enum-types.h.in \ mutter-enum-types.c.in \ - xrandr.xml idle-monitor.xml + org.gnome.Mutter.DisplayConfig.xml \ + org.gnome.Mutter.IdleMonitor.xml BUILT_SOURCES = $(mutter_built_sources) MUTTER_STAMP_FILES = stamp-mutter-enum-types.h @@ -417,21 +418,20 @@ mutter-enum-types.c: stamp-mutter-enum-types.h mutter-enum-types.c.in dbus_xrandr_built_sources = meta-dbus-xrandr.c meta-dbus-xrandr.h -$(dbus_xrandr_built_sources) : Makefile.am xrandr.xml +$(dbus_xrandr_built_sources) : Makefile.am org.gnome.Mutter.DisplayConfig.xml $(AM_V_GEN)gdbus-codegen \ --interface-prefix org.gnome.Mutter \ --c-namespace MetaDBus \ --generate-c-code meta-dbus-xrandr \ - $(srcdir)/xrandr.xml + $(srcdir)/org.gnome.Mutter.DisplayConfig.xml - -$(dbus_idle_built_sources) : Makefile.am idle-monitor.xml +$(dbus_idle_built_sources) : Makefile.am org.gnome.Mutter.IdleMonitor.xml $(AM_V_GEN)gdbus-codegen \ --interface-prefix org.gnome.Mutter \ --c-namespace MetaDBus \ --generate-c-code meta-dbus-idle-monitor \ --c-generate-object-manager \ - $(srcdir)/idle-monitor.xml + $(srcdir)/org.gnome.Mutter.IdleMonitor.xml %-protocol.c : $(srcdir)/wayland/protocol/%.xml $(AM_V_GEN)$(WAYLAND_SCANNER) code < $< > $@ diff --git a/src/xrandr.xml b/src/org.gnome.Mutter.DisplayConfig.xml similarity index 100% rename from src/xrandr.xml rename to src/org.gnome.Mutter.DisplayConfig.xml diff --git a/src/idle-monitor.xml b/src/org.gnome.Mutter.IdleMonitor.xml similarity index 100% rename from src/idle-monitor.xml rename to src/org.gnome.Mutter.IdleMonitor.xml From fd392cc1e736e7c69263e34e5f65f9a8647b04e5 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 31 Mar 2014 23:33:01 -0400 Subject: [PATCH 810/889] Remove "xrandr" from the name of the generated DBus files It's about generic display config, not XRandR specifically. --- .gitignore | 2 +- src/Makefile.am | 8 ++++---- src/backends/meta-monitor-manager.c | 2 -- src/backends/meta-monitor-manager.h | 2 +- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 7a08ed3ca..efe17465b 100644 --- a/.gitignore +++ b/.gitignore @@ -75,7 +75,7 @@ src/mutter-enum-types.[ch] src/stamp-mutter-enum-types.h src/mutter-marshal.[ch] src/stamp-mutter-marshal.h -src/meta-dbus-xrandr.[ch] +src/meta-dbus-display-config.[ch] src/meta-dbus-idle-monitor.[ch] src/mutter-plugins.pc src/gtk-shell-protocol.c diff --git a/src/Makefile.am b/src/Makefile.am index b8f055728..78c0230e8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -35,7 +35,7 @@ INCLUDES= \ mutter_built_sources = \ $(dbus_idle_built_sources) \ - $(dbus_xrandr_built_sources) \ + $(dbus_display_config_built_sources) \ mutter-enum-types.h \ mutter-enum-types.c \ gtk-shell-protocol.c \ @@ -416,13 +416,13 @@ mutter-enum-types.c: stamp-mutter-enum-types.h mutter-enum-types.c.in cp xgen-tetc mutter-enum-types.c && \ rm -f xgen-tetc -dbus_xrandr_built_sources = meta-dbus-xrandr.c meta-dbus-xrandr.h +dbus_display_config_built_sources = meta-dbus-display-config.c meta-dbus-display-config.h -$(dbus_xrandr_built_sources) : Makefile.am org.gnome.Mutter.DisplayConfig.xml +$(dbus_display_config_built_sources) : Makefile.am org.gnome.Mutter.DisplayConfig.xml $(AM_V_GEN)gdbus-codegen \ --interface-prefix org.gnome.Mutter \ --c-namespace MetaDBus \ - --generate-c-code meta-dbus-xrandr \ + --generate-c-code meta-dbus-display-config \ $(srcdir)/org.gnome.Mutter.DisplayConfig.xml $(dbus_idle_built_sources) : Makefile.am org.gnome.Mutter.IdleMonitor.xml diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c index aaf318eb0..74b68acf6 100644 --- a/src/backends/meta-monitor-manager.c +++ b/src/backends/meta-monitor-manager.c @@ -40,8 +40,6 @@ #include "meta-monitor-manager-xrandr.h" #include "meta-monitor-manager-dummy.h" -#include "meta-dbus-xrandr.h" - enum { CONFIRM_DISPLAY_CHANGE, SIGNALS_LAST diff --git a/src/backends/meta-monitor-manager.h b/src/backends/meta-monitor-manager.h index 2a553c9de..a1a33b5c5 100644 --- a/src/backends/meta-monitor-manager.h +++ b/src/backends/meta-monitor-manager.h @@ -45,7 +45,7 @@ #include #include "meta-xrandr-shared.h" -#include "meta-dbus-xrandr.h" +#include "meta-dbus-display-config.h" typedef struct _MetaMonitorManagerClass MetaMonitorManagerClass; typedef struct _MetaMonitorManager MetaMonitorManager; From d5552cc372405d0eb4b8e06e3382d2d23cdaf9ff Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 31 Mar 2014 23:34:23 -0400 Subject: [PATCH 811/889] Rename meta-xrandr-shared to meta-display-config-shared --- ...{meta-xrandr-shared.h => meta-display-config-shared.h} | 8 ++++---- src/backends/meta-monitor-manager.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) rename src/backends/{meta-xrandr-shared.h => meta-display-config-shared.h} (84%) diff --git a/src/backends/meta-xrandr-shared.h b/src/backends/meta-display-config-shared.h similarity index 84% rename from src/backends/meta-xrandr-shared.h rename to src/backends/meta-display-config-shared.h index 99e3d9825..92665cc00 100644 --- a/src/backends/meta-xrandr-shared.h +++ b/src/backends/meta-display-config-shared.h @@ -16,7 +16,7 @@ * along with this program; if not, see . */ -/* This file is shared between mutter (src/core/meta-xrandr-shared.h) +/* This file is shared between mutter (src/core/meta-display-config-shared.h) and gnome-desktop (libgnome-desktop/meta-xrandr-shared.h). The canonical place for all changes is mutter. @@ -24,8 +24,8 @@ There should be no includes in this file. */ -#ifndef META_XRANDR_SHARED_H -#define META_XRANDR_SHARED_H +#ifndef META_DISPLAY_CONFIG_SHARED_H +#define META_DISPLAY_CONFIG_SHARED_H typedef enum { META_POWER_SAVE_UNSUPPORTED = -1, @@ -35,4 +35,4 @@ typedef enum { META_POWER_SAVE_OFF, } MetaPowerSave; -#endif +#endif /* META_DISPLAY_CONFIG_SHARED_H */ diff --git a/src/backends/meta-monitor-manager.h b/src/backends/meta-monitor-manager.h index a1a33b5c5..0feb73d25 100644 --- a/src/backends/meta-monitor-manager.h +++ b/src/backends/meta-monitor-manager.h @@ -43,8 +43,8 @@ #include "stack-tracker.h" #include "ui.h" #include -#include "meta-xrandr-shared.h" +#include "meta-display-config-shared.h" #include "meta-dbus-display-config.h" typedef struct _MetaMonitorManagerClass MetaMonitorManagerClass; From bce1d5117b9ec20143c991959c140f11ca6a25bf Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 31 Mar 2014 23:25:37 -0400 Subject: [PATCH 812/889] Start creating different subdirectories for each backend --- src/Makefile.am | 26 ++++++++++--------- src/backends/meta-backend.c | 2 +- src/backends/meta-idle-monitor.c | 4 +-- src/backends/meta-monitor-manager.c | 4 +-- .../{ => native}/meta-idle-monitor-native.c | 0 .../{ => native}/meta-idle-monitor-native.h | 0 .../{ => native}/meta-monitor-manager-kms.c | 0 .../{ => native}/meta-monitor-manager-kms.h | 0 .../{ => native}/meta-weston-launch.c | 0 .../{ => native}/meta-weston-launch.h | 0 src/backends/{ => native}/weston-launch.c | 0 src/backends/{ => native}/weston-launch.h | 0 .../{ => x11}/meta-idle-monitor-xsync.c | 0 .../{ => x11}/meta-idle-monitor-xsync.h | 0 .../{ => x11}/meta-monitor-manager-xrandr.c | 0 .../{ => x11}/meta-monitor-manager-xrandr.h | 0 src/core/events.c | 4 +-- 17 files changed, 21 insertions(+), 19 deletions(-) rename src/backends/{ => native}/meta-idle-monitor-native.c (100%) rename src/backends/{ => native}/meta-idle-monitor-native.h (100%) rename src/backends/{ => native}/meta-monitor-manager-kms.c (100%) rename src/backends/{ => native}/meta-monitor-manager-kms.h (100%) rename src/backends/{ => native}/meta-weston-launch.c (100%) rename src/backends/{ => native}/meta-weston-launch.h (100%) rename src/backends/{ => native}/weston-launch.c (100%) rename src/backends/{ => native}/weston-launch.h (100%) rename src/backends/{ => x11}/meta-idle-monitor-xsync.c (100%) rename src/backends/{ => x11}/meta-idle-monitor-xsync.h (100%) rename src/backends/{ => x11}/meta-monitor-manager-xrandr.c (100%) rename src/backends/{ => x11}/meta-monitor-manager-xrandr.h (100%) diff --git a/src/Makefile.am b/src/Makefile.am index 78c0230e8..2dff8b2fa 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -62,23 +62,23 @@ libmutter_wayland_la_SOURCES = \ backends/meta-idle-monitor-private.h \ backends/meta-idle-monitor-dbus.c \ backends/meta-idle-monitor-dbus.h \ - backends/meta-idle-monitor-xsync.c \ - backends/meta-idle-monitor-xsync.h \ - backends/meta-idle-monitor-native.c \ - backends/meta-idle-monitor-native.h \ - backends/meta-xrandr-shared.h \ backends/meta-monitor-config.c \ backends/meta-monitor-config.h \ backends/meta-monitor-manager.c \ backends/meta-monitor-manager.h \ backends/meta-monitor-manager-dummy.c \ backends/meta-monitor-manager-dummy.h \ - backends/meta-monitor-manager-kms.c \ - backends/meta-monitor-manager-kms.h \ - backends/meta-monitor-manager-xrandr.c \ - backends/meta-monitor-manager-xrandr.h \ - backends/meta-weston-launch.c \ - backends/meta-weston-launch.h \ + backends/native/meta-idle-monitor-native.c \ + backends/native/meta-idle-monitor-native.h \ + backends/native/meta-monitor-manager-kms.c \ + backends/native/meta-monitor-manager-kms.h \ + backends/native/meta-weston-launch.c \ + backends/native/meta-weston-launch.h \ + backends/x11/meta-idle-monitor-xsync.c \ + backends/x11/meta-idle-monitor-xsync.h \ + backends/x11/meta-monitor-manager-xrandr.c \ + backends/x11/meta-monitor-manager-xrandr.h \ + backends/x11/meta-xrandr-shared.h \ core/above-tab-keycode.c \ core/barrier.c \ meta/barrier.h \ @@ -288,7 +288,9 @@ mutter_wayland_LDADD = $(MUTTER_LIBS) libmutter-wayland.la bin_PROGRAMS+=mutter-launch -mutter_launch_SOURCES = backends/weston-launch.c backends/weston-launch.h +mutter_launch_SOURCES = \ + backends/native/weston-launch.c \ + backends/native/weston-launch.h mutter_launch_CFLAGS = $(MUTTER_LAUNCH_CFLAGS) -DLIBDIR=\"$(libdir)\" mutter_launch_LDFLAGS = $(MUTTER_LAUNCH_LIBS) -lpam diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c index f464425b3..464b44218 100644 --- a/src/backends/meta-backend.c +++ b/src/backends/meta-backend.c @@ -31,7 +31,7 @@ #include #include -#include "meta-weston-launch.h" +#include "backends/native/meta-weston-launch.h" /* Mutter is responsible for pulling events off the X queue, so Clutter * doesn't need (and shouldn't) run its normal event source which polls diff --git a/src/backends/meta-idle-monitor.c b/src/backends/meta-idle-monitor.c index 85affc580..7d9d29355 100644 --- a/src/backends/meta-idle-monitor.c +++ b/src/backends/meta-idle-monitor.c @@ -38,8 +38,8 @@ #include #include "meta-idle-monitor-private.h" #include "meta-idle-monitor-dbus.h" -#include "meta-idle-monitor-xsync.h" -#include "meta-idle-monitor-native.h" +#include "backends/x11/meta-idle-monitor-xsync.h" +#include "backends/native/meta-idle-monitor-native.h" G_STATIC_ASSERT(sizeof(unsigned long) == sizeof(gpointer)); diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c index 74b68acf6..c8a640ee3 100644 --- a/src/backends/meta-monitor-manager.c +++ b/src/backends/meta-monitor-manager.c @@ -36,8 +36,8 @@ #include "util-private.h" #include #include "meta-monitor-config.h" -#include "meta-monitor-manager-kms.h" -#include "meta-monitor-manager-xrandr.h" +#include "backends/native/meta-monitor-manager-kms.h" +#include "backends/x11/meta-monitor-manager-xrandr.h" #include "meta-monitor-manager-dummy.h" enum { diff --git a/src/backends/meta-idle-monitor-native.c b/src/backends/native/meta-idle-monitor-native.c similarity index 100% rename from src/backends/meta-idle-monitor-native.c rename to src/backends/native/meta-idle-monitor-native.c diff --git a/src/backends/meta-idle-monitor-native.h b/src/backends/native/meta-idle-monitor-native.h similarity index 100% rename from src/backends/meta-idle-monitor-native.h rename to src/backends/native/meta-idle-monitor-native.h diff --git a/src/backends/meta-monitor-manager-kms.c b/src/backends/native/meta-monitor-manager-kms.c similarity index 100% rename from src/backends/meta-monitor-manager-kms.c rename to src/backends/native/meta-monitor-manager-kms.c diff --git a/src/backends/meta-monitor-manager-kms.h b/src/backends/native/meta-monitor-manager-kms.h similarity index 100% rename from src/backends/meta-monitor-manager-kms.h rename to src/backends/native/meta-monitor-manager-kms.h diff --git a/src/backends/meta-weston-launch.c b/src/backends/native/meta-weston-launch.c similarity index 100% rename from src/backends/meta-weston-launch.c rename to src/backends/native/meta-weston-launch.c diff --git a/src/backends/meta-weston-launch.h b/src/backends/native/meta-weston-launch.h similarity index 100% rename from src/backends/meta-weston-launch.h rename to src/backends/native/meta-weston-launch.h diff --git a/src/backends/weston-launch.c b/src/backends/native/weston-launch.c similarity index 100% rename from src/backends/weston-launch.c rename to src/backends/native/weston-launch.c diff --git a/src/backends/weston-launch.h b/src/backends/native/weston-launch.h similarity index 100% rename from src/backends/weston-launch.h rename to src/backends/native/weston-launch.h diff --git a/src/backends/meta-idle-monitor-xsync.c b/src/backends/x11/meta-idle-monitor-xsync.c similarity index 100% rename from src/backends/meta-idle-monitor-xsync.c rename to src/backends/x11/meta-idle-monitor-xsync.c diff --git a/src/backends/meta-idle-monitor-xsync.h b/src/backends/x11/meta-idle-monitor-xsync.h similarity index 100% rename from src/backends/meta-idle-monitor-xsync.h rename to src/backends/x11/meta-idle-monitor-xsync.h diff --git a/src/backends/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c similarity index 100% rename from src/backends/meta-monitor-manager-xrandr.c rename to src/backends/x11/meta-monitor-manager-xrandr.c diff --git a/src/backends/meta-monitor-manager-xrandr.h b/src/backends/x11/meta-monitor-manager-xrandr.h similarity index 100% rename from src/backends/meta-monitor-manager-xrandr.h rename to src/backends/x11/meta-monitor-manager-xrandr.h diff --git a/src/core/events.c b/src/core/events.c index 49a37d320..afc499997 100644 --- a/src/core/events.c +++ b/src/core/events.c @@ -34,8 +34,8 @@ #include "window-private.h" #include "bell.h" #include "workspace-private.h" -#include "meta-idle-monitor-xsync.h" -#include "meta-idle-monitor-native.h" +#include "backends/x11/meta-idle-monitor-xsync.h" +#include "backends/native/meta-idle-monitor-native.h" #include "x11/window-x11.h" #include "x11/xprops.h" From 34cc5efb90d56d28937b887573bc74d9de35f07a Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 31 Mar 2014 23:47:11 -0400 Subject: [PATCH 813/889] configure: Add on subdir-objects To stop automake from complaining --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 6ca7add31..97d91cba6 100644 --- a/configure.ac +++ b/configure.ac @@ -16,7 +16,7 @@ AC_INIT([mutter], [mutter_version], AC_CONFIG_SRCDIR(src/core/display.c) AC_CONFIG_HEADERS(config.h) -AM_INIT_AUTOMAKE([1.11 foreign no-dist-gzip dist-xz tar-ustar]) +AM_INIT_AUTOMAKE([1.11 foreign no-dist-gzip dist-xz tar-ustar subdir-objects]) m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])],) AM_MAINTAINER_MODE([enable]) From 216ff7ebe5577a0b27cb209099218149df489d4a Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 31 Mar 2014 23:47:40 -0400 Subject: [PATCH 814/889] Update .gitignore It seems the new automake likes to litter these files all around. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index efe17465b..29da1c7d9 100644 --- a/.gitignore +++ b/.gitignore @@ -108,3 +108,4 @@ ltoptions.m4 ltsugar.m4 ltversion.m4 lt~obsolete.m4 +.dirstamp From f1c7063ee77b3a8b508c34d8a079e68456fb544c Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 31 Mar 2014 23:48:26 -0400 Subject: [PATCH 815/889] configure: Clean up old status line While I'm here, I might as well. We rely on Xcursor now. --- configure.ac | 1 - 1 file changed, 1 deletion(-) diff --git a/configure.ac b/configure.ac index 97d91cba6..b5905a74a 100644 --- a/configure.ac +++ b/configure.ac @@ -480,7 +480,6 @@ mutter-wayland-$VERSION Session management: ${found_sm} Shape extension: ${found_shape} Xsync: ${found_xsync} - Xcursor: ${have_xcursor} " From 899d4d84772c3cf5e4458923ce03d4d95837f2ac Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 1 Apr 2014 10:24:10 -0400 Subject: [PATCH 816/889] monitor-manager: Move default get_edid_file / read_edid to base class These are also used by the native manager. --- src/backends/meta-monitor-manager-dummy.c | 16 ---------------- src/backends/meta-monitor-manager.c | 17 +++++++++++++++++ 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/backends/meta-monitor-manager-dummy.c b/src/backends/meta-monitor-manager-dummy.c index cf74d9d7b..46cea9396 100644 --- a/src/backends/meta-monitor-manager-dummy.c +++ b/src/backends/meta-monitor-manager-dummy.c @@ -212,20 +212,6 @@ meta_monitor_manager_dummy_apply_config (MetaMonitorManager *manager, meta_monitor_manager_rebuild_derived (manager); } -static GBytes * -meta_monitor_manager_dummy_read_edid (MetaMonitorManager *manager, - MetaOutput *output) -{ - return NULL; -} - -static char * -meta_monitor_manager_dummy_get_edid_file (MetaMonitorManager *manager, - MetaOutput *output) -{ - return NULL; -} - static void meta_monitor_manager_dummy_class_init (MetaMonitorManagerDummyClass *klass) { @@ -233,8 +219,6 @@ meta_monitor_manager_dummy_class_init (MetaMonitorManagerDummyClass *klass) manager_class->read_current = meta_monitor_manager_dummy_read_current; manager_class->apply_configuration = meta_monitor_manager_dummy_apply_config; - manager_class->get_edid_file = meta_monitor_manager_dummy_get_edid_file; - manager_class->read_edid = meta_monitor_manager_dummy_read_edid; } static void diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c index c8a640ee3..3e0a238d3 100644 --- a/src/backends/meta-monitor-manager.c +++ b/src/backends/meta-monitor-manager.c @@ -389,6 +389,20 @@ meta_monitor_manager_get_property (GObject *object, } } +static GBytes * +meta_monitor_manager_real_read_edid (MetaMonitorManager *manager, + MetaOutput *output) +{ + return NULL; +} + +static char * +meta_monitor_manager_real_get_edid_file (MetaMonitorManager *manager, + MetaOutput *output) +{ + return NULL; +} + static void meta_monitor_manager_class_init (MetaMonitorManagerClass *klass) { @@ -400,6 +414,9 @@ meta_monitor_manager_class_init (MetaMonitorManagerClass *klass) object_class->dispose = meta_monitor_manager_dispose; object_class->finalize = meta_monitor_manager_finalize; + klass->get_edid_file = meta_monitor_manager_real_get_edid_file; + klass->read_edid = meta_monitor_manager_real_read_edid; + signals[CONFIRM_DISPLAY_CHANGE] = g_signal_new ("confirm-display-change", G_TYPE_FROM_CLASS (object_class), From 29396014fd7965d757c7989194e3e4b0f6569fae Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 1 Apr 2014 13:56:40 -0400 Subject: [PATCH 817/889] backend: Fix the nested mode --- src/backends/meta-backend.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c index 464b44218..b5ea43d5e 100644 --- a/src/backends/meta-backend.c +++ b/src/backends/meta-backend.c @@ -88,8 +88,23 @@ meta_clutter_init (void) { GSource *source; - clutter_x11_set_display (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ())); - clutter_x11_disable_event_retrieval (); + /* When running as an X11 compositor, we install our own event filter and + * pass events to Clutter explicitly, so we need to prevent Clutter from + * handling our events. + * + * However, when running as a Wayland compostior under X11 nested, Clutter + * Clutter needs to see events related to its own window. We need to + * eventually replace this with a proper frontend / backend split: Clutter + * under nested is connecting to the "host X server" to get its events it + * needs to put up a window, and GTK+ is connecting to the "inner X server". + * The two would the same in the X11 compositor case, but not when running + * XWayland as a Wayland compositor. + */ + if (!meta_is_wayland_compositor ()) + { + clutter_x11_set_display (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ())); + clutter_x11_disable_event_retrieval (); + } /* If we're running on bare metal, we're a display server, * so start talking to weston-launch. */ From 67b6737b271fa777342fcff52deadd08479eec40 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 1 Apr 2014 14:04:53 -0400 Subject: [PATCH 818/889] backend: Fix warning --- src/backends/meta-backend.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c index b5ea43d5e..b8a6dc1cf 100644 --- a/src/backends/meta-backend.c +++ b/src/backends/meta-backend.c @@ -32,6 +32,7 @@ #include #include "backends/native/meta-weston-launch.h" +#include /* Mutter is responsible for pulling events off the X queue, so Clutter * doesn't need (and shouldn't) run its normal event source which polls From 57803f1d59b51512ac6a3541e4f92a1f9e99f81a Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 31 Mar 2014 23:54:25 -0400 Subject: [PATCH 819/889] wayland-stage: Clean up and rename It should be META_TYPE_WAYLAND_STAGE, not META_WAYLAND_TYPE_STAGE. Well, actually, it *should* be META_TYPE_NATIVE_STAGE, because it's not related to Wayland at all. But that comes later :) --- src/wayland/meta-wayland-stage.c | 2 +- src/wayland/meta-wayland-stage.h | 26 ++++++-------------------- 2 files changed, 7 insertions(+), 21 deletions(-) diff --git a/src/wayland/meta-wayland-stage.c b/src/wayland/meta-wayland-stage.c index 16cb753a6..b795dd570 100644 --- a/src/wayland/meta-wayland-stage.c +++ b/src/wayland/meta-wayland-stage.c @@ -62,7 +62,7 @@ meta_wayland_stage_init (MetaWaylandStage *self) ClutterActor * meta_wayland_stage_new (void) { - return g_object_new (META_WAYLAND_TYPE_STAGE, + return g_object_new (META_TYPE_WAYLAND_STAGE, "cursor-visible", FALSE, NULL); } diff --git a/src/wayland/meta-wayland-stage.h b/src/wayland/meta-wayland-stage.h index c242fbd60..4dcfb6418 100644 --- a/src/wayland/meta-wayland-stage.h +++ b/src/wayland/meta-wayland-stage.h @@ -27,26 +27,12 @@ G_BEGIN_DECLS -#define META_WAYLAND_TYPE_STAGE \ - (meta_wayland_stage_get_type()) -#define META_WAYLAND_STAGE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ - META_WAYLAND_TYPE_STAGE, \ - MetaWaylandStage)) -#define META_WAYLAND_STAGE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), \ - META_WAYLAND_TYPE_STAGE, \ - MetaWaylandStageClass)) -#define META_WAYLAND_IS_STAGE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ - META_WAYLAND_TYPE_STAGE)) -#define META_WAYLAND_IS_STAGE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), \ - META_WAYLAND_TYPE_STAGE)) -#define META_WAYLAND_STAGE_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), \ - META_WAYLAND_STAGE, \ - MetaWaylandStageClass)) +#define META_TYPE_WAYLAND_STAGE (meta_wayland_stage_get_type ()) +#define META_WAYLAND_STAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_WAYLAND_STAGE, MetaWaylandStage)) +#define META_WAYLAND_STAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_WAYLAND_STAGE, MetaWaylandStageClass)) +#define META_IS_WAYLAND_STAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_WAYLAND_STAGE)) +#define META_IS_WAYLAND_STAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_WAYLAND_STAGE)) +#define META_WAYLAND_STAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_WAYLAND_STAGE, MetaWaylandStageClass)) typedef struct _MetaWaylandStage MetaWaylandStage; typedef struct _MetaWaylandStageClass MetaWaylandStageClass; From ab6bc76bfd9a47ba6772e36abcfc36ce6d81d070 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 1 Apr 2014 14:34:52 -0400 Subject: [PATCH 820/889] Move edid-parse to backends/ --- src/Makefile.am | 4 ++-- src/{core => backends}/edid-parse.c | 0 src/{core => backends}/edid.h | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename src/{core => backends}/edid-parse.c (100%) rename src/{core => backends}/edid.h (100%) diff --git a/src/Makefile.am b/src/Makefile.am index 2dff8b2fa..aacec1829 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -68,6 +68,8 @@ libmutter_wayland_la_SOURCES = \ backends/meta-monitor-manager.h \ backends/meta-monitor-manager-dummy.c \ backends/meta-monitor-manager-dummy.h \ + backends/edid-parse.c \ + backends/edid.h \ backends/native/meta-idle-monitor-native.c \ backends/native/meta-idle-monitor-native.h \ backends/native/meta-monitor-manager-kms.c \ @@ -143,8 +145,6 @@ libmutter_wayland_la_SOURCES = \ meta/display.h \ core/edge-resistance.c \ core/edge-resistance.h \ - core/edid-parse.c \ - core/edid.h \ core/events.c \ core/events.h \ core/errors.c \ diff --git a/src/core/edid-parse.c b/src/backends/edid-parse.c similarity index 100% rename from src/core/edid-parse.c rename to src/backends/edid-parse.c diff --git a/src/core/edid.h b/src/backends/edid.h similarity index 100% rename from src/core/edid.h rename to src/backends/edid.h From 94692414cb28317e1a69538050d98617e80ad673 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 1 Apr 2014 15:46:31 -0400 Subject: [PATCH 821/889] idle-monitor-native: Fix copy/paste bug --- src/backends/native/meta-idle-monitor-native.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backends/native/meta-idle-monitor-native.c b/src/backends/native/meta-idle-monitor-native.c index 75b4e5a28..9f4f7341b 100644 --- a/src/backends/native/meta-idle-monitor-native.c +++ b/src/backends/native/meta-idle-monitor-native.c @@ -72,7 +72,7 @@ native_dispatch_timeout (GSource *source, gpointer user_data) { MetaIdleMonitorWatchNative *watch_native = user_data; - MetaIdleMonitorWatch *watch = (MetaIdleMonitorWatch *) watch; + MetaIdleMonitorWatch *watch = (MetaIdleMonitorWatch *) watch_native; _meta_idle_monitor_watch_fire (watch); g_source_set_ready_time (watch_native->timeout_source, -1); From 617b00dfbd2422d779ea3ce1bf53c9664fa3182c Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 1 Apr 2014 15:46:50 -0400 Subject: [PATCH 822/889] idle-monitor-native: Reindent --- src/backends/native/meta-idle-monitor-native.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/backends/native/meta-idle-monitor-native.c b/src/backends/native/meta-idle-monitor-native.c index 9f4f7341b..8eb357615 100644 --- a/src/backends/native/meta-idle-monitor-native.c +++ b/src/backends/native/meta-idle-monitor-native.c @@ -113,10 +113,10 @@ free_watch (gpointer data) static MetaIdleMonitorWatch * meta_idle_monitor_native_make_watch (MetaIdleMonitor *monitor, - guint64 timeout_msec, - MetaIdleMonitorWatchFunc callback, - gpointer user_data, - GDestroyNotify notify) + guint64 timeout_msec, + MetaIdleMonitorWatchFunc callback, + gpointer user_data, + GDestroyNotify notify) { MetaIdleMonitorWatchNative *watch_native; MetaIdleMonitorWatch *watch; From dcd83b736556bac2531b627a4337c186f03d3219 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 1 Apr 2014 16:00:49 -0400 Subject: [PATCH 823/889] idle-monitor-native: Remove another copy/paste error Don't overwrite the watch with a new malloc'd variable. --- src/backends/native/meta-idle-monitor-native.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/backends/native/meta-idle-monitor-native.c b/src/backends/native/meta-idle-monitor-native.c index 8eb357615..13d8d516f 100644 --- a/src/backends/native/meta-idle-monitor-native.c +++ b/src/backends/native/meta-idle-monitor-native.c @@ -125,7 +125,6 @@ meta_idle_monitor_native_make_watch (MetaIdleMonitor *monitor, watch_native = g_slice_new0 (MetaIdleMonitorWatchNative); watch = (MetaIdleMonitorWatch *) watch_native; - watch = g_slice_new0 (MetaIdleMonitorWatch); watch->monitor = monitor; watch->id = get_next_watch_serial (); watch->callback = callback; From c1e3a6b742e5e947aa973e0d6e5c83124d3e9b07 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 1 Apr 2014 16:05:20 -0400 Subject: [PATCH 824/889] idle-monitor: Actually get the check for is_wayland_compositor correctly If we're a Wayland compositor we shouldn't be taking this path, ever. --- src/backends/meta-idle-monitor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backends/meta-idle-monitor.c b/src/backends/meta-idle-monitor.c index 7d9d29355..4c4357af6 100644 --- a/src/backends/meta-idle-monitor.c +++ b/src/backends/meta-idle-monitor.c @@ -358,7 +358,7 @@ meta_idle_monitor_xsync_handle_xevent_all (XEvent *xevent) { int i; - if (!meta_is_wayland_compositor ()) + if (meta_is_wayland_compositor ()) return; for (i = 0; i <= device_id_max; i++) From 6296fefea615eb46f1096948b6d16ff26403aeba Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 2 Apr 2014 10:31:14 -0400 Subject: [PATCH 825/889] window-actor: Clean up has_shadow This has some particularly picky #if 0'd code. Since the history for it isn't illuminating in the slightest, I'm just going to kill it. --- src/compositor/meta-window-actor.c | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index f7f32a0e5..ae5a276ed 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -702,7 +702,6 @@ static gboolean meta_window_actor_has_shadow (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; - MetaWindowType window_type = meta_window_get_window_type (priv->window); if (priv->no_shadow) return FALSE; @@ -741,25 +740,6 @@ meta_window_actor_has_shadow (MetaWindowActor *self) if (priv->window->override_redirect) return TRUE; - /* - * Don't put shadow around DND icon windows - */ - if (window_type == META_WINDOW_DND || - window_type == META_WINDOW_DESKTOP) - return FALSE; - - if (window_type == META_WINDOW_MENU -#if 0 - || window_type == META_WINDOW_DROPDOWN_MENU -#endif - ) - return TRUE; - -#if 0 - if (window_type == META_WINDOW_TOOLTIP) - return TRUE; -#endif - return FALSE; } From e4cd000cef3c1dde52da48ce1afde3f6ee918077 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 2 Apr 2014 11:38:21 -0400 Subject: [PATCH 826/889] wayland: Implement wl_seat v3 The new XWayland DDX flat out requires seat v3. --- src/wayland/meta-wayland-seat.c | 21 ++++++++++++++++++++- src/wayland/meta-wayland-versions.h | 6 +++--- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c index 2d5f0fbb9..f5e3867a4 100644 --- a/src/wayland/meta-wayland-seat.c +++ b/src/wayland/meta-wayland-seat.c @@ -115,8 +115,16 @@ pointer_set_cursor (struct wl_client *client, meta_wayland_seat_update_cursor_surface (seat); } +static void +pointer_release (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + static const struct wl_pointer_interface pointer_interface = { - pointer_set_cursor + pointer_set_cursor, + pointer_release, }; static void @@ -137,6 +145,17 @@ seat_get_pointer (struct wl_client *client, meta_wayland_pointer_set_focus (&seat->pointer, seat->pointer.focus_surface); } +static void +keyboard_release (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static const struct wl_keyboard_interface keyboard_interface = { + keyboard_release, +}; + static void seat_get_keyboard (struct wl_client *client, struct wl_resource *resource, diff --git a/src/wayland/meta-wayland-versions.h b/src/wayland/meta-wayland-versions.h index 17d8895eb..d599908fa 100644 --- a/src/wayland/meta-wayland-versions.h +++ b/src/wayland/meta-wayland-versions.h @@ -38,7 +38,7 @@ #define META_WL_COMPOSITOR_VERSION 3 #define META_WL_DATA_DEVICE_MANAGER_VERSION 1 #define META_WL_SHELL_VERSION 1 -#define META_WL_SEAT_VERSION 2 /* 3 not implemented yet */ +#define META_WL_SEAT_VERSION 3 #define META_WL_OUTPUT_VERSION 2 #define META_XSERVER_VERSION 1 #define META_GTK_SHELL_VERSION 1 @@ -49,8 +49,8 @@ #define META_WL_DATA_SOURCE_VERSION 1 /* from wl_data_device */ #define META_WL_DATA_DEVICE_VERSION 1 /* from wl_data_device_manager */ #define META_WL_SURFACE_VERSION 3 /* from wl_compositor */ -#define META_WL_POINTER_VERSION 2 /* from wl_seat; 3 not implemented yet */ -#define META_WL_KEYBOARD_VERSION 2 /* from wl_seat; 3 not implemented yet */ +#define META_WL_POINTER_VERSION 3 /* from wl_seat */ +#define META_WL_KEYBOARD_VERSION 3 /* from wl_seat */ #define META_WL_TOUCH_VERSION 0 /* from wl_seat; wl_touch not supported */ #define META_WL_REGION_VERSION 1 /* from wl_compositor */ #define META_XDG_SURFACE_VERSION 1 /* from xdg_shell */ From 3c404c5db3b08219154e832c05ce4cfcfb5d6277 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 2 Apr 2014 10:37:08 -0400 Subject: [PATCH 827/889] wayland: Replace make_toplevel / window_unmanaging with set_window The make_toplevel / window_unmanaging interface has never made a lot of sense to me. Replace it with set_window, which does effectively the same thing. It's still not perfect in the case of XWayland, but I don't think XWayland will ever make me happy. --- src/core/window.c | 2 +- src/wayland/meta-wayland-surface.c | 40 +++++++++++++++--------------- src/wayland/meta-wayland-surface.h | 4 +-- src/wayland/meta-xwayland.c | 4 +-- 4 files changed, 24 insertions(+), 26 deletions(-) diff --git a/src/core/window.c b/src/core/window.c index 1deece0db..0ba7980ab 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -1468,7 +1468,7 @@ meta_window_unmanage (MetaWindow *window, /* This needs to happen for both Wayland and XWayland clients, * so it can't be in MetaWindowWayland. */ if (window->surface) - meta_wayland_surface_window_unmanaged (window->surface); + meta_wayland_surface_set_window (window->surface, NULL); if (window->visible_to_compositor) { diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 2eb32ecb5..2c49c4721 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -549,16 +549,13 @@ const struct wl_surface_interface meta_wayland_surface_interface = { }; void -meta_wayland_surface_make_toplevel (MetaWaylandSurface *surface) +meta_wayland_surface_set_window (MetaWaylandSurface *surface, + MetaWindow *window) { - clutter_actor_set_reactive (CLUTTER_ACTOR (surface->surface_actor), TRUE); -} + gboolean has_window = (window != NULL); -void -meta_wayland_surface_window_unmanaged (MetaWaylandSurface *surface) -{ - clutter_actor_set_reactive (CLUTTER_ACTOR (surface->surface_actor), FALSE); - surface->window = NULL; + clutter_actor_set_reactive (CLUTTER_ACTOR (surface->surface_actor), has_window); + surface->window = window; } static void @@ -909,6 +906,7 @@ xdg_shell_get_xdg_surface (struct wl_client *client, struct wl_resource *surface_resource) { MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); + MetaWindow *window; if (!create_surface_extension (&surface->xdg_surface, META_XDG_SURFACE_VERSION, @@ -923,8 +921,8 @@ xdg_shell_get_xdg_surface (struct wl_client *client, return; } - meta_wayland_surface_make_toplevel (surface); - surface->window = meta_window_wayland_new (meta_get_display (), surface); + window = meta_window_wayland_new (meta_get_display (), surface); + meta_wayland_surface_set_window (surface, window); } static void @@ -962,6 +960,7 @@ xdg_shell_get_xdg_popup (struct wl_client *client, MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); MetaWaylandSurface *parent_surf = wl_resource_get_user_data (parent_resource); MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); + MetaWindow *window; if (parent_surf == NULL || parent_surf->window == NULL) return; @@ -979,15 +978,15 @@ xdg_shell_get_xdg_popup (struct wl_client *client, return; } - meta_wayland_surface_make_toplevel (surface); - surface->window = meta_window_wayland_new (meta_get_display (), surface); - surface->window->rect.x = parent_surf->window->rect.x + x; - surface->window->rect.y = parent_surf->window->rect.y + y; - surface->window->showing_for_first_time = FALSE; - surface->window->placed = TRUE; - meta_window_set_transient_for (surface->window, parent_surf->window); + window = meta_window_wayland_new (meta_get_display (), surface); + window->rect.x = parent_surf->window->rect.x + x; + window->rect.y = parent_surf->window->rect.y + y; + window->showing_for_first_time = FALSE; + window->placed = TRUE; + meta_window_set_transient_for (window, parent_surf->window); + meta_window_set_type (window, META_WINDOW_DROPDOWN_MENU); - meta_window_set_type (surface->window, META_WINDOW_DROPDOWN_MENU); + meta_wayland_surface_set_window (surface, window); meta_wayland_pointer_start_popup_grab (&seat->pointer, surface); } @@ -1270,6 +1269,7 @@ wl_shell_get_shell_surface (struct wl_client *client, struct wl_resource *surface_resource) { MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); + MetaWindow *window; if (!create_surface_extension (&surface->wl_shell_surface, META_WL_SHELL_SURFACE_VERSION, @@ -1284,8 +1284,8 @@ wl_shell_get_shell_surface (struct wl_client *client, return; } - meta_wayland_surface_make_toplevel (surface); - surface->window = meta_window_wayland_new (meta_get_display (), surface); + window = meta_window_wayland_new (meta_get_display (), surface); + meta_wayland_surface_set_window (surface, window); } static const struct wl_shell_interface meta_wayland_wl_shell_interface = { diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h index e0886536e..25fe83c11 100644 --- a/src/wayland/meta-wayland-surface.h +++ b/src/wayland/meta-wayland-surface.h @@ -111,8 +111,8 @@ MetaWaylandSurface *meta_wayland_surface_create (MetaWaylandCompositor *composit guint32 id, guint32 version); -void meta_wayland_surface_make_toplevel (MetaWaylandSurface *surface); -void meta_wayland_surface_window_unmanaged (MetaWaylandSurface *surface); +void meta_wayland_surface_set_window (MetaWaylandSurface *surface, + MetaWindow *window); void meta_wayland_surface_configure_notify (MetaWaylandSurface *surface, int width, diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index 7748b123c..d261ca712 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -54,9 +54,7 @@ xserver_set_window_id (struct wl_client *client, if (window->surface) window->surface->window = NULL; - meta_wayland_surface_make_toplevel (surface); - - surface->window = window; + meta_wayland_surface_set_window (surface, window); window->surface = surface; meta_compositor_window_surface_changed (display->compositor, window); From e9ee984921e9c3482296f3c4ae5359f4c0d294d8 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 2 Apr 2014 11:10:20 -0400 Subject: [PATCH 828/889] wayland: Rename the wl_surface interface handlers We usually name the method handlers after the direct name of the interface methods. Do that for wl_surface as well. --- src/wayland/meta-wayland-surface.c | 80 +++++++++++++++--------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 2c49c4721..d654ae23a 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -118,17 +118,17 @@ surface_process_damage (MetaWaylandSurface *surface, } static void -meta_wayland_surface_destroy (struct wl_client *client, - struct wl_resource *resource) +wl_surface_destroy (struct wl_client *client, + struct wl_resource *resource) { wl_resource_destroy (resource); } static void -meta_wayland_surface_attach (struct wl_client *client, - struct wl_resource *surface_resource, - struct wl_resource *buffer_resource, - gint32 dx, gint32 dy) +wl_surface_attach (struct wl_client *client, + struct wl_resource *surface_resource, + struct wl_resource *buffer_resource, + gint32 dx, gint32 dy) { MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); @@ -158,12 +158,12 @@ meta_wayland_surface_attach (struct wl_client *client, } static void -meta_wayland_surface_damage (struct wl_client *client, - struct wl_resource *surface_resource, - gint32 x, - gint32 y, - gint32 width, - gint32 height) +wl_surface_damage (struct wl_client *client, + struct wl_resource *surface_resource, + gint32 x, + gint32 y, + gint32 width, + gint32 height) { MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); cairo_rectangle_int_t rectangle = { x, y, width, height }; @@ -186,9 +186,9 @@ destroy_frame_callback (struct wl_resource *callback_resource) } static void -meta_wayland_surface_frame (struct wl_client *client, - struct wl_resource *surface_resource, - guint32 callback_id) +wl_surface_frame (struct wl_client *client, + struct wl_resource *surface_resource, + guint32 callback_id) { MetaWaylandFrameCallback *callback; MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); @@ -206,9 +206,9 @@ meta_wayland_surface_frame (struct wl_client *client, } static void -meta_wayland_surface_set_opaque_region (struct wl_client *client, - struct wl_resource *surface_resource, - struct wl_resource *region_resource) +wl_surface_set_opaque_region (struct wl_client *client, + struct wl_resource *surface_resource, + struct wl_resource *region_resource) { MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); @@ -225,9 +225,9 @@ meta_wayland_surface_set_opaque_region (struct wl_client *client, } static void -meta_wayland_surface_set_input_region (struct wl_client *client, - struct wl_resource *surface_resource, - struct wl_resource *region_resource) +wl_surface_set_input_region (struct wl_client *client, + struct wl_resource *surface_resource, + struct wl_resource *region_resource) { MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); @@ -507,8 +507,8 @@ commit_double_buffered_state (MetaWaylandSurface *surface, } static void -meta_wayland_surface_commit (struct wl_client *client, - struct wl_resource *resource) +wl_surface_commit (struct wl_client *client, + struct wl_resource *resource) { MetaWaylandSurface *surface = wl_resource_get_user_data (resource); @@ -520,32 +520,32 @@ meta_wayland_surface_commit (struct wl_client *client, } static void -meta_wayland_surface_set_buffer_transform (struct wl_client *client, - struct wl_resource *resource, - int32_t transform) +wl_surface_set_buffer_transform (struct wl_client *client, + struct wl_resource *resource, + int32_t transform) { g_warning ("TODO: support set_buffer_transform request"); } static void -meta_wayland_surface_set_buffer_scale (struct wl_client *client, - struct wl_resource *resource, - int scale) +wl_surface_set_buffer_scale (struct wl_client *client, + struct wl_resource *resource, + int scale) { if (scale != 1) g_warning ("TODO: support set_buffer_scale request"); } -const struct wl_surface_interface meta_wayland_surface_interface = { - meta_wayland_surface_destroy, - meta_wayland_surface_attach, - meta_wayland_surface_damage, - meta_wayland_surface_frame, - meta_wayland_surface_set_opaque_region, - meta_wayland_surface_set_input_region, - meta_wayland_surface_commit, - meta_wayland_surface_set_buffer_transform, - meta_wayland_surface_set_buffer_scale +const struct wl_surface_interface meta_wayland_wl_surface_interface = { + wl_surface_destroy, + wl_surface_attach, + wl_surface_damage, + wl_surface_frame, + wl_surface_set_opaque_region, + wl_surface_set_input_region, + wl_surface_commit, + wl_surface_set_buffer_transform, + wl_surface_set_buffer_scale }; void @@ -609,7 +609,7 @@ meta_wayland_surface_create (MetaWaylandCompositor *compositor, surface->compositor = compositor; surface->resource = wl_resource_create (client, &wl_surface_interface, version, id); - wl_resource_set_implementation (surface->resource, &meta_wayland_surface_interface, surface, wl_surface_destructor); + wl_resource_set_implementation (surface->resource, &meta_wayland_wl_surface_interface, surface, wl_surface_destructor); surface->buffer_destroy_listener.notify = surface_handle_buffer_destroy; surface->surface_actor = g_object_ref_sink (meta_surface_actor_wayland_new (surface)); From 81d033ec738c3e8b9c1153b533bd2f8a896158d7 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 1 Apr 2014 19:57:55 -0400 Subject: [PATCH 829/889] xwayland: Use %m instead of manual strerror(errno) --- src/wayland/meta-xwayland.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index d261ca712..aa4b24df5 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -204,8 +204,7 @@ bind_to_abstract_socket (int display) size = offsetof (struct sockaddr_un, sun_path) + name_size; if (bind (fd, (struct sockaddr *) &addr, size) < 0) { - g_warning ("failed to bind to @%s: %s\n", - addr.sun_path + 1, strerror (errno)); + g_warning ("failed to bind to @%s: %m", addr.sun_path + 1); close (fd); return -1; } @@ -237,8 +236,7 @@ bind_to_unix_socket (int display) unlink (addr.sun_path); if (bind (fd, (struct sockaddr *) &addr, size) < 0) { - char *msg = strerror (errno); - g_warning ("failed to bind to %s (%s)\n", addr.sun_path, msg); + g_warning ("failed to bind to %s: %m\n", addr.sun_path); close (fd); return -1; } From af272f2685e2ef92248155d3ad3db200d956b001 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 1 Apr 2014 20:00:20 -0400 Subject: [PATCH 830/889] xwayland: Move global initialization down --- src/wayland/meta-xwayland.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index aa4b24df5..543e8ffbc 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -299,10 +299,6 @@ meta_xwayland_start (MetaXWaylandManager *manager, char **env; char *fd_string; - wl_global_create (wl_display, &xserver_interface, - META_XSERVER_VERSION, - manager, bind_xserver); - do { lockfile = create_lockfile (display, &display); @@ -341,6 +337,10 @@ meta_xwayland_start (MetaXWaylandManager *manager, manager->display_index = display; manager->lockfile = lockfile; + wl_global_create (wl_display, &xserver_interface, + META_XSERVER_VERSION, + manager, bind_xserver); + /* We want xwayland to be a wayland client so we make a socketpair to setup a * wayland protocol connection. */ if (socketpair (AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sp) < 0) From a44295599c6b2d18674a581130894a109ea205a5 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 1 Apr 2014 20:00:59 -0400 Subject: [PATCH 831/889] xwayland: Split out the code that creates the XWayland sockets --- src/wayland/meta-xwayland.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index 543e8ffbc..1c3f12df6 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -288,16 +288,11 @@ x_io_error (Display *display) return 0; } -gboolean -meta_xwayland_start (MetaXWaylandManager *manager, - struct wl_display *wl_display) +static gboolean +choose_xdisplay (MetaXWaylandManager *manager) { int display = 0; char *lockfile = NULL; - int sp[2]; - pid_t pid; - char **env; - char *fd_string; do { @@ -337,6 +332,21 @@ meta_xwayland_start (MetaXWaylandManager *manager, manager->display_index = display; manager->lockfile = lockfile; + return TRUE; +} + +gboolean +meta_xwayland_start (MetaXWaylandManager *manager, + struct wl_display *wl_display) +{ + int sp[2]; + pid_t pid; + char **env; + char *fd_string; + + if (!choose_xdisplay (manager)) + return FALSE; + wl_global_create (wl_display, &xserver_interface, META_XSERVER_VERSION, manager, bind_xserver); @@ -346,7 +356,7 @@ meta_xwayland_start (MetaXWaylandManager *manager, if (socketpair (AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sp) < 0) { g_warning ("socketpair failed\n"); - unlink (lockfile); + unlink (manager->lockfile); return 1; } From c540ddf59bbcfa91916698ae7b349a21eb359c3c Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 1 Apr 2014 19:38:05 -0400 Subject: [PATCH 832/889] xwayland: Move display_name into choose_xdisplay --- src/wayland/meta-xwayland.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index 1c3f12df6..5321aefcc 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -330,6 +330,7 @@ choose_xdisplay (MetaXWaylandManager *manager) while (1); manager->display_index = display; + manager->display_name = g_strdup_printf (":%d", manager->display_index); manager->lockfile = lockfile; return TRUE; @@ -365,8 +366,6 @@ meta_xwayland_start (MetaXWaylandManager *manager, env = g_environ_setenv (env, "WAYLAND_SOCKET", fd_string, TRUE); g_free (fd_string); - manager->display_name = g_strdup_printf (":%d", manager->display_index); - { GError *error = NULL; gchar *args[] = { XWAYLAND_PATH, From 5cf0740b4e13cc577935247146628be8f30cb71c Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 1 Apr 2014 19:51:43 -0400 Subject: [PATCH 833/889] xwayland: Fork the X server ourselves gspawn just isn't us the fine-grained control we need for starting processes and leaking file descriptors in. --- src/wayland/meta-xwayland.c | 93 +++++++++++++------------------------ 1 file changed, 33 insertions(+), 60 deletions(-) diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index 5321aefcc..9ef639867 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -251,18 +251,6 @@ bind_to_unix_socket (int display) return fd; } -static void -uncloexec (gpointer user_data) -{ - int fd = GPOINTER_TO_INT (user_data); - - /* Make sure the client end of the socket pair doesn't get closed - * when we exec xwayland. */ - int flags = fcntl (fd, F_GETFD); - if (flags != -1) - fcntl (fd, F_SETFD, flags & ~FD_CLOEXEC); -} - static void xserver_died (GPid pid, gint status, @@ -341,9 +329,8 @@ meta_xwayland_start (MetaXWaylandManager *manager, struct wl_display *wl_display) { int sp[2]; - pid_t pid; - char **env; - char *fd_string; + int fd; + char *socket_fd; if (!choose_xdisplay (manager)) return FALSE; @@ -361,55 +348,41 @@ meta_xwayland_start (MetaXWaylandManager *manager, return 1; } - env = g_get_environ (); - fd_string = g_strdup_printf ("%d", sp[1]); - env = g_environ_setenv (env, "WAYLAND_SOCKET", fd_string, TRUE); - g_free (fd_string); + manager->pid = fork (); + if (manager->pid == 0) + { + /* We passed SOCK_CLOEXEC, so dup the FD so it isn't + * closed on exec.. */ + fd = dup (sp[1]); + socket_fd = g_strdup_printf ("%d", fd); + setenv ("WAYLAND_SOCKET", socket_fd, TRUE); + g_free (socket_fd); - { - GError *error = NULL; - gchar *args[] = { XWAYLAND_PATH, - manager->display_name, - "-wayland", - "-rootless", - "-noreset", - "-nolisten", - "all", - NULL }; - int flags = 0; + /* xwayland, please. */ + if (g_getenv ("XWAYLAND_STFU")) + { + int dev_null; + dev_null = open ("/dev/null", O_WRONLY); - flags |= G_SPAWN_LEAVE_DESCRIPTORS_OPEN; - flags |= G_SPAWN_DO_NOT_REAP_CHILD; + dup2 (dev_null, STDOUT_FILENO); + dup2 (dev_null, STDERR_FILENO); + } - /* xwayland, please. */ - if (getenv ("XWAYLAND_STFU")) - { - flags |= G_SPAWN_STDOUT_TO_DEV_NULL; - flags |= G_SPAWN_STDERR_TO_DEV_NULL; - } + if (execl (XWAYLAND_PATH, XWAYLAND_PATH, + manager->display_name, + "-wayland", + "-rootless", + "-noreset", + "-nolisten", "all", + NULL) < 0) + { + g_warning ("Failed to spawn XWayland: %m"); + exit (EXIT_FAILURE); + } + } - if (g_spawn_async (NULL, /* cwd */ - args, - env, - flags, - uncloexec, - GINT_TO_POINTER (sp[1]), - &pid, - &error)) - { - close (sp[1]); - manager->client = wl_client_create (wl_display, sp[0]); - - manager->pid = pid; - g_child_watch_add (pid, xserver_died, NULL); - } - else - { - g_error ("Failed to fork for xwayland server: %s", error->message); - } - } - - g_strfreev (env); + g_child_watch_add (manager->pid, xserver_died, NULL); + manager->client = wl_client_create (wl_display, sp[0]); /* We need to run a mainloop until we know xwayland has a binding * for our xserver interface at which point we can assume it's From e07bd15fc2bd6a3e6817e70f3525c10dead9c6bc Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 1 Apr 2014 20:35:26 -0400 Subject: [PATCH 834/889] xwayland: Make file cosmetically modern Put a modeline, include "config.h", and shift around the include ordering --- src/wayland/meta-xwayland.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index 9ef639867..4fcadcf00 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -1,3 +1,5 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + /* * X Wayland Support * @@ -19,8 +21,11 @@ * 02111-1307, USA. */ -#include +#include "config.h" +#include "meta-xwayland-private.h" + +#include #include #include #include @@ -29,7 +34,6 @@ #include #include -#include "meta-xwayland-private.h" #include "meta-window-actor-private.h" #include "xserver-server-protocol.h" From 9653b79a358230d1c7b1e2d5ca38d93c12f64ca4 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 2 Apr 2014 10:19:39 -0400 Subject: [PATCH 835/889] xwayland: Split a helper out This will make the next commit, which ports to the new ClientMessage API, more understandable. --- src/wayland/meta-xwayland.c | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index 4fcadcf00..ada9c26aa 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -37,6 +37,25 @@ #include "meta-window-actor-private.h" #include "xserver-server-protocol.h" +static void +associate_window_with_surface (MetaWindow *window, + MetaWaylandSurface *surface) +{ + MetaDisplay *display = window->display; + + /* If the window has an existing surface, like if we're + * undecorating or decorating the window, then we need + * to detach the window from its old surface. + */ + if (window->surface) + window->surface->window = NULL; + + meta_wayland_surface_set_window (surface, window); + window->surface = surface; + + meta_compositor_window_surface_changed (display->compositor, window); +} + static void xserver_set_window_id (struct wl_client *client, struct wl_resource *compositor_resource, @@ -51,17 +70,7 @@ xserver_set_window_id (struct wl_client *client, if (!window) return; - /* If the window has an existing surface, like if we're - * undecorating or decorating the window, then we need - * to detach the window from its old surface. - */ - if (window->surface) - window->surface->window = NULL; - - meta_wayland_surface_set_window (surface, window); - window->surface = surface; - - meta_compositor_window_surface_changed (display->compositor, window); + associate_window_with_surface (window, surface); } static const struct xserver_interface xserver_implementation = { From eb5b54dd8b173f904f29c98deadd3c79e297712f Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 2 Apr 2014 10:22:01 -0400 Subject: [PATCH 836/889] xwayland: Split another part of the initialization sequence out This will be used from a SIGUSR1 handler. --- src/wayland/meta-xwayland.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index ada9c26aa..72be3525e 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -37,6 +37,9 @@ #include "meta-window-actor-private.h" #include "xserver-server-protocol.h" +static void +xserver_finished_init (MetaXWaylandManager *manager); + static void associate_window_with_surface (MetaWindow *window, MetaWaylandSurface *surface) @@ -104,12 +107,7 @@ bind_xserver (struct wl_client *client, * manager. */ wl_client_flush (client); - /* At this point xwayland is all setup to start accepting - * connections so we can quit the transient initialization mainloop - * and unblock meta_wayland_init() to continue initializing mutter. - * */ - g_main_loop_quit (manager->init_loop); - g_clear_pointer (&manager->init_loop, g_main_loop_unref); + xserver_finished_init (manager); } static char * @@ -337,6 +335,17 @@ choose_xdisplay (MetaXWaylandManager *manager) return TRUE; } +static void +xserver_finished_init (MetaXWaylandManager *manager) +{ + /* At this point xwayland is all setup to start accepting + * connections so we can quit the transient initialization mainloop + * and unblock meta_wayland_init() to continue initializing mutter. + * */ + g_main_loop_quit (manager->init_loop); + g_clear_pointer (&manager->init_loop, g_main_loop_unref); +} + gboolean meta_xwayland_start (MetaXWaylandManager *manager, struct wl_display *wl_display) From 8373c90cd8c8e3edec5b21a41426d4cb073e8b9e Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 2 Apr 2014 12:35:24 -0400 Subject: [PATCH 837/889] background: Remove load_still_frame Nothing uses it, and it's incompatible with XWayland anyway. --- src/compositor/meta-background.c | 84 -------------------------------- src/meta/meta-background.h | 1 - 2 files changed, 85 deletions(-) diff --git a/src/compositor/meta-background.c b/src/compositor/meta-background.c index 4337f7053..825ee90d1 100644 --- a/src/compositor/meta-background.c +++ b/src/compositor/meta-background.c @@ -26,8 +26,6 @@ #include -#include - #include #include "cogl-utils.h" @@ -755,88 +753,6 @@ set_filename (MetaBackground *self, priv->filename = g_strdup (filename); } -static Pixmap -get_still_frame_for_monitor (MetaScreen *screen, - int monitor) -{ - MetaDisplay *display = meta_screen_get_display (screen); - Display *xdisplay = meta_display_get_xdisplay (display); - Window xroot = meta_screen_get_xroot (screen); - Pixmap pixmap; - GC gc; - XGCValues values; - MetaRectangle geometry; - int depth; - - meta_screen_get_monitor_geometry (screen, monitor, &geometry); - - depth = DefaultDepth (xdisplay, meta_screen_get_screen_number (screen)); - - pixmap = XCreatePixmap (xdisplay, - xroot, - geometry.width, geometry.height, depth); - - values.function = GXcopy; - values.plane_mask = AllPlanes; - values.fill_style = FillSolid; - values.subwindow_mode = IncludeInferiors; - - gc = XCreateGC (xdisplay, - xroot, - GCFunction | GCPlaneMask | GCFillStyle | GCSubwindowMode, - &values); - - XCopyArea (xdisplay, - xroot, pixmap, gc, - geometry.x, geometry.y, - geometry.width, geometry.height, - 0, 0); - - XFreeGC (xdisplay, gc); - - return pixmap; -} - -/** - * meta_background_load_still_frame: - * @self: the #MetaBackground - * - * Takes a screenshot of the desktop and uses it as the background - * source. - */ -void -meta_background_load_still_frame (MetaBackground *self) -{ - MetaBackgroundPrivate *priv = self->priv; - MetaDisplay *display = meta_screen_get_display (priv->screen); - Pixmap still_frame; - CoglTexture *texture; - CoglContext *context = clutter_backend_get_cogl_context (clutter_get_default_backend ()); - GError *error = NULL; - - ensure_pipeline (self); - - unset_texture (self); - set_style (self, G_DESKTOP_BACKGROUND_STYLE_STRETCHED); - - still_frame = get_still_frame_for_monitor (priv->screen, priv->monitor); - XSync (meta_display_get_xdisplay (display), False); - - meta_error_trap_push (display); - texture = COGL_TEXTURE (cogl_texture_pixmap_x11_new (context, still_frame, FALSE, &error)); - meta_error_trap_pop (display); - - if (error != NULL) - { - g_warning ("Failed to create background texture from pixmap: %s", - error->message); - g_error_free (error); - return; - } - - set_texture (self, texture); -} - /** * meta_background_load_gradient: * @self: the #MetaBackground diff --git a/src/meta/meta-background.h b/src/meta/meta-background.h index c171df326..a861600f8 100644 --- a/src/meta/meta-background.h +++ b/src/meta/meta-background.h @@ -91,7 +91,6 @@ void meta_background_load_gradient (MetaBackground *self, ClutterColor *second_color); void meta_background_load_color (MetaBackground *self, ClutterColor *color); -void meta_background_load_still_frame (MetaBackground *self); void meta_background_load_file_async (MetaBackground *self, const char *filename, GDesktopBackgroundStyle style, From c4c0b5f0ab461a6346ad0820b41cf9eea25f9e33 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 2 Apr 2014 13:03:17 -0400 Subject: [PATCH 838/889] xwayland: Detect a fail to fork --- src/wayland/meta-xwayland.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index 72be3525e..2904965af 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -402,6 +402,10 @@ meta_xwayland_start (MetaXWaylandManager *manager, exit (EXIT_FAILURE); } } + else if (manager->pid == -1) + { + g_error ("Failed to fork: %m"); + } g_child_watch_add (manager->pid, xserver_died, NULL); manager->client = wl_client_create (wl_display, sp[0]); From 2a7d12ba142fcc7876245785c1d4c75776e9b8a4 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 2 Apr 2014 13:03:29 -0400 Subject: [PATCH 839/889] xwayland: Make failing to exec a fatal error --- src/wayland/meta-xwayland.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index 2904965af..cfef99e76 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -398,8 +398,7 @@ meta_xwayland_start (MetaXWaylandManager *manager, "-nolisten", "all", NULL) < 0) { - g_warning ("Failed to spawn XWayland: %m"); - exit (EXIT_FAILURE); + g_error ("Failed to spawn XWayland: %m"); } } else if (manager->pid == -1) From 4f609dbf5e18a6c8af24753372ac3aa3dc23a3ec Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 2 Apr 2014 13:04:18 -0400 Subject: [PATCH 840/889] xwayland: Don't use glib after forking glib doesn't have any guarantee about working after forking. We can get away with it, but we're better off just not using it. --- src/wayland/meta-xwayland.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index cfef99e76..8527519e0 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -352,7 +352,6 @@ meta_xwayland_start (MetaXWaylandManager *manager, { int sp[2]; int fd; - char *socket_fd; if (!choose_xdisplay (manager)) return FALSE; @@ -373,15 +372,16 @@ meta_xwayland_start (MetaXWaylandManager *manager, manager->pid = fork (); if (manager->pid == 0) { + char socket_fd[8]; + /* We passed SOCK_CLOEXEC, so dup the FD so it isn't * closed on exec.. */ fd = dup (sp[1]); - socket_fd = g_strdup_printf ("%d", fd); + snprintf (socket_fd, sizeof (socket_fd), "%d", fd); setenv ("WAYLAND_SOCKET", socket_fd, TRUE); - g_free (socket_fd); /* xwayland, please. */ - if (g_getenv ("XWAYLAND_STFU")) + if (getenv ("XWAYLAND_STFU")) { int dev_null; dev_null = open ("/dev/null", O_WRONLY); From 43730f166066f23cad315c0357dabf8100dc3d36 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 2 Apr 2014 10:25:56 -0400 Subject: [PATCH 841/889] xwayland: Switch to SIGUSR1 to know when the X server has finished init This is effectively the same, but since we lose the xserver.xml protocol in the new XWayland DDX, we have to use SIGUSR1 anyway, so might as well switch over now. --- src/wayland/meta-xwayland.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index 8527519e0..ec9f342c1 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -26,9 +26,11 @@ #include "meta-xwayland-private.h" #include +#include #include #include #include +#include #include #include #include @@ -37,9 +39,6 @@ #include "meta-window-actor-private.h" #include "xserver-server-protocol.h" -static void -xserver_finished_init (MetaXWaylandManager *manager); - static void associate_window_with_surface (MetaWindow *window, MetaWaylandSurface *surface) @@ -106,8 +105,6 @@ bind_xserver (struct wl_client *client, * then going to immediately try and connect to those as the window * manager. */ wl_client_flush (client); - - xserver_finished_init (manager); } static char * @@ -346,6 +343,16 @@ xserver_finished_init (MetaXWaylandManager *manager) g_clear_pointer (&manager->init_loop, g_main_loop_unref); } +static gboolean +got_sigusr1 (gpointer user_data) +{ + MetaXWaylandManager *manager = user_data; + + xserver_finished_init (manager); + + return G_SOURCE_REMOVE; +} + gboolean meta_xwayland_start (MetaXWaylandManager *manager, struct wl_display *wl_display) @@ -390,6 +397,10 @@ meta_xwayland_start (MetaXWaylandManager *manager, dup2 (dev_null, STDERR_FILENO); } + /* We have to ignore SIGUSR1 in the child to make sure + * that the server will send it to mutter-wayland. */ + signal(SIGUSR1, SIG_IGN); + if (execl (XWAYLAND_PATH, XWAYLAND_PATH, manager->display_name, "-wayland", @@ -407,6 +418,7 @@ meta_xwayland_start (MetaXWaylandManager *manager, } g_child_watch_add (manager->pid, xserver_died, NULL); + g_unix_signal_add (SIGUSR1, got_sigusr1, manager); manager->client = wl_client_create (wl_display, sp[0]); /* We need to run a mainloop until we know xwayland has a binding From be02fa1120d9ad2be3c093b14b8760b6b22ca912 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 20 Mar 2014 13:12:43 -0400 Subject: [PATCH 842/889] xwayland: Switch to the new Xwayland DDX --- configure.ac | 2 +- src/Makefile.am | 10 ++- src/core/events.c | 8 ++- src/meta/atomnames.h | 1 + src/wayland/meta-xwayland.c | 106 +++++++++++++++++-------------- src/wayland/meta-xwayland.h | 35 ++++++++++ src/wayland/protocol/xserver.xml | 18 ------ 7 files changed, 106 insertions(+), 74 deletions(-) create mode 100644 src/wayland/meta-xwayland.h delete mode 100644 src/wayland/protocol/xserver.xml diff --git a/configure.ac b/configure.ac index b5905a74a..180af409e 100644 --- a/configure.ac +++ b/configure.ac @@ -133,7 +133,7 @@ AC_ARG_WITH([wayland-protocols], AC_ARG_WITH([xwayland-path], [AS_HELP_STRING([--with-xwayland-path], [Absolute path for an X Wayland server])], [XWAYLAND_PATH="$withval"], - [XWAYLAND_PATH="$bindir/Xorg"]) + [XWAYLAND_PATH="$bindir/Xwayland"]) AM_GLIB_GNU_GETTEXT diff --git a/src/Makefile.am b/src/Makefile.am index aacec1829..61a14fe74 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -41,14 +41,11 @@ mutter_built_sources = \ gtk-shell-protocol.c \ gtk-shell-server-protocol.h \ xdg-shell-protocol.c \ - xdg-shell-server-protocol.h \ - xserver-protocol.c \ - xserver-server-protocol.h + xdg-shell-server-protocol.h wayland_protocols = \ wayland/protocol/gtk-shell.xml \ - wayland/protocol/xdg-shell.xml \ - wayland/protocol/xserver.xml + wayland/protocol/xdg-shell.xml libmutter_wayland_la_SOURCES = \ backends/meta-backend.c \ @@ -214,8 +211,9 @@ libmutter_wayland_la_SOURCES = \ wayland/meta-wayland.c \ wayland/meta-wayland.h \ wayland/meta-wayland-private.h \ - wayland/meta-xwayland-private.h \ wayland/meta-xwayland.c \ + wayland/meta-xwayland.h \ + wayland/meta-xwayland-private.h \ wayland/meta-wayland-data-device.c \ wayland/meta-wayland-data-device.h \ wayland/meta-wayland-keyboard.c \ diff --git a/src/core/events.c b/src/core/events.c index afc499997..35e397f29 100644 --- a/src/core/events.c +++ b/src/core/events.c @@ -39,6 +39,7 @@ #include "x11/window-x11.h" #include "x11/xprops.h" +#include "wayland/meta-xwayland.h" #include "wayland/meta-wayland-private.h" #include "meta-surface-actor-wayland.h" @@ -1536,7 +1537,12 @@ handle_other_xevent (MetaDisplay *display, case ClientMessage: if (window) { - if (!frame_was_receiver) + if (event->xclient.message_type == display->atom_WL_SURFACE_ID) + { + guint32 surface_id = event->xclient.data.l[0]; + meta_xwayland_handle_wl_surface_id (window, surface_id); + } + else if (!frame_was_receiver) meta_window_x11_client_message (window, event); } else diff --git a/src/meta/atomnames.h b/src/meta/atomnames.h index f93876cce..38227deaa 100644 --- a/src/meta/atomnames.h +++ b/src/meta/atomnames.h @@ -81,6 +81,7 @@ item(ATOM_PAIR) item(BACKLIGHT) item(_XKB_RULES_NAMES) item(hotplug_mode_update) +item(WL_SURFACE_ID) /* Oddities: These are used, and we need atoms for them, * but when we need all _NET_WM hints (i.e. when we're making diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index ec9f342c1..cb1f54ad1 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -23,6 +23,7 @@ #include "config.h" +#include "meta-xwayland.h" #include "meta-xwayland-private.h" #include @@ -36,9 +37,6 @@ #include #include -#include "meta-window-actor-private.h" -#include "xserver-server-protocol.h" - static void associate_window_with_surface (MetaWindow *window, MetaWaylandSurface *surface) @@ -58,53 +56,63 @@ associate_window_with_surface (MetaWindow *window, meta_compositor_window_surface_changed (display->compositor, window); } -static void -xserver_set_window_id (struct wl_client *client, - struct wl_resource *compositor_resource, - struct wl_resource *surface_resource, - guint32 xid) +static gboolean +associate_window_with_surface_id (MetaXWaylandManager *manager, + MetaWindow *window, + guint32 surface_id) { - MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); - MetaDisplay *display = meta_get_display (); - MetaWindow *window; + struct wl_resource *resource; - window = meta_display_lookup_x_window (display, xid); - if (!window) - return; - - associate_window_with_surface (window, surface); + resource = wl_client_get_object (manager->client, surface_id); + if (resource) + { + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); + associate_window_with_surface (window, surface); + return TRUE; + } + else + return FALSE; } -static const struct xserver_interface xserver_implementation = { - xserver_set_window_id -}; +typedef struct { + MetaXWaylandManager *manager; + MetaWindow *window; + guint32 surface_id; +} AssociateWindowWithSurfaceOp; -static void -bind_xserver (struct wl_client *client, - void *data, - guint32 version, - guint32 id) +static gboolean +associate_window_with_surface_idle (gpointer user_data) { - MetaXWaylandManager *manager = data; + AssociateWindowWithSurfaceOp *op = user_data; + if (!associate_window_with_surface_id (op->manager, op->window, op->surface_id)) + { + /* Not here? Oh well... nothing we can do */ + g_warning ("Unknown surface ID %d (from window %s)", op->surface_id, op->window->desc); + } + g_free (op); - /* If it's a different client than the xserver we launched, - * just freeze up... */ - if (client != manager->client) - return; + return G_SOURCE_REMOVE; +} - manager->xserver_resource = wl_resource_create (client, &xserver_interface, - MIN (META_XSERVER_VERSION, version), id); - wl_resource_set_implementation (manager->xserver_resource, - &xserver_implementation, manager, NULL); +void +meta_xwayland_handle_wl_surface_id (MetaWindow *window, + guint32 surface_id) +{ + MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); + MetaXWaylandManager *manager = &compositor->xwayland_manager; - xserver_send_listen_socket (manager->xserver_resource, manager->abstract_fd); - xserver_send_listen_socket (manager->xserver_resource, manager->unix_fd); - - /* Make sure xwayland will recieve the above sockets in a finite - * time before unblocking the initialization mainloop since we are - * then going to immediately try and connect to those as the window - * manager. */ - wl_client_flush (client); + if (!associate_window_with_surface_id (manager, window, surface_id)) + { + /* No surface ID yet... it should arrive after the next + * iteration through the loop, so queue an idle and see + * what happens. + */ + AssociateWindowWithSurfaceOp *op = g_new0 (AssociateWindowWithSurfaceOp, 1); + op->manager = manager; + op->window = window; + op->surface_id = surface_id; + g_idle_add (associate_window_with_surface_idle, op); + } } static char * @@ -363,10 +371,6 @@ meta_xwayland_start (MetaXWaylandManager *manager, if (!choose_xdisplay (manager)) return FALSE; - wl_global_create (wl_display, &xserver_interface, - META_XSERVER_VERSION, - manager, bind_xserver); - /* We want xwayland to be a wayland client so we make a socketpair to setup a * wayland protocol connection. */ if (socketpair (AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sp) < 0) @@ -379,7 +383,7 @@ meta_xwayland_start (MetaXWaylandManager *manager, manager->pid = fork (); if (manager->pid == 0) { - char socket_fd[8]; + char socket_fd[8], unix_fd[8], abstract_fd[8]; /* We passed SOCK_CLOEXEC, so dup the FD so it isn't * closed on exec.. */ @@ -387,6 +391,12 @@ meta_xwayland_start (MetaXWaylandManager *manager, snprintf (socket_fd, sizeof (socket_fd), "%d", fd); setenv ("WAYLAND_SOCKET", socket_fd, TRUE); + fd = dup (manager->abstract_fd); + snprintf (abstract_fd, sizeof (abstract_fd), "%d", fd); + + fd = dup (manager->unix_fd); + snprintf (unix_fd, sizeof (unix_fd), "%d", fd); + /* xwayland, please. */ if (getenv ("XWAYLAND_STFU")) { @@ -403,10 +413,10 @@ meta_xwayland_start (MetaXWaylandManager *manager, if (execl (XWAYLAND_PATH, XWAYLAND_PATH, manager->display_name, - "-wayland", "-rootless", "-noreset", - "-nolisten", "all", + "-listen", abstract_fd, + "-listen", unix_fd, NULL) < 0) { g_error ("Failed to spawn XWayland: %m"); diff --git a/src/wayland/meta-xwayland.h b/src/wayland/meta-xwayland.h new file mode 100644 index 000000000..5308f2957 --- /dev/null +++ b/src/wayland/meta-xwayland.h @@ -0,0 +1,35 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2014 Red Hat + * + * 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. + * + * Written by: + * Jasper St. Pierre + */ + +#ifndef META_XWAYLAND_H +#define META_XWAYLAND_H + +#include +#include + +void +meta_xwayland_handle_wl_surface_id (MetaWindow *window, + guint32 surface_id); + +#endif /* META_XWAYLAND_H */ diff --git a/src/wayland/protocol/xserver.xml b/src/wayland/protocol/xserver.xml deleted file mode 100644 index 9e25f5c0d..000000000 --- a/src/wayland/protocol/xserver.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - From 371fba68437c7559819552709e479485fba3e696 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 2 Apr 2014 11:12:58 -0400 Subject: [PATCH 843/889] wayland: Move the commit implementation to the top We're going to need to expose commit as a public method for XWayland support, so decouple it from the handler implementation. --- src/wayland/meta-wayland-surface.c | 260 +++++++++++++++-------------- 1 file changed, 133 insertions(+), 127 deletions(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index d654ae23a..544687786 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -117,132 +117,6 @@ surface_process_damage (MetaWaylandSurface *surface, } } -static void -wl_surface_destroy (struct wl_client *client, - struct wl_resource *resource) -{ - wl_resource_destroy (resource); -} - -static void -wl_surface_attach (struct wl_client *client, - struct wl_resource *surface_resource, - struct wl_resource *buffer_resource, - gint32 dx, gint32 dy) -{ - MetaWaylandSurface *surface = - wl_resource_get_user_data (surface_resource); - MetaWaylandBuffer *buffer; - - /* X11 unmanaged window */ - if (!surface) - return; - - if (buffer_resource) - buffer = meta_wayland_buffer_from_resource (buffer_resource); - else - buffer = NULL; - - /* Attach without commit in between does not send wl_buffer.release */ - if (surface->pending.buffer) - wl_list_remove (&surface->pending.buffer_destroy_listener.link); - - surface->pending.dx = dx; - surface->pending.dy = dy; - surface->pending.buffer = buffer; - surface->pending.newly_attached = TRUE; - - if (buffer) - wl_signal_add (&buffer->destroy_signal, - &surface->pending.buffer_destroy_listener); -} - -static void -wl_surface_damage (struct wl_client *client, - struct wl_resource *surface_resource, - gint32 x, - gint32 y, - gint32 width, - gint32 height) -{ - MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); - cairo_rectangle_int_t rectangle = { x, y, width, height }; - - /* X11 unmanaged window */ - if (!surface) - return; - - cairo_region_union_rectangle (surface->pending.damage, &rectangle); -} - -static void -destroy_frame_callback (struct wl_resource *callback_resource) -{ - MetaWaylandFrameCallback *callback = - wl_resource_get_user_data (callback_resource); - - wl_list_remove (&callback->link); - g_slice_free (MetaWaylandFrameCallback, callback); -} - -static void -wl_surface_frame (struct wl_client *client, - struct wl_resource *surface_resource, - guint32 callback_id) -{ - MetaWaylandFrameCallback *callback; - MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); - - /* X11 unmanaged window */ - if (!surface) - return; - - callback = g_slice_new0 (MetaWaylandFrameCallback); - callback->compositor = surface->compositor; - callback->resource = wl_resource_create (client, &wl_callback_interface, META_WL_CALLBACK_VERSION, callback_id); - wl_resource_set_implementation (callback->resource, NULL, callback, destroy_frame_callback); - - wl_list_insert (surface->pending.frame_callback_list.prev, &callback->link); -} - -static void -wl_surface_set_opaque_region (struct wl_client *client, - struct wl_resource *surface_resource, - struct wl_resource *region_resource) -{ - MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); - - /* X11 unmanaged window */ - if (!surface) - return; - - g_clear_pointer (&surface->pending.opaque_region, cairo_region_destroy); - if (region_resource) - { - MetaWaylandRegion *region = wl_resource_get_user_data (region_resource); - surface->pending.opaque_region = cairo_region_copy (region->region); - } -} - -static void -wl_surface_set_input_region (struct wl_client *client, - struct wl_resource *surface_resource, - struct wl_resource *region_resource) -{ - MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); - - /* X11 unmanaged window */ - if (!surface) - return; - - g_clear_pointer (&surface->pending.input_region, cairo_region_destroy); - if (region_resource) - { - MetaWaylandRegion *region = wl_resource_get_user_data (region_resource); - surface->pending.input_region = cairo_region_copy (region->region); - } -} - static void empty_region (cairo_region_t *region) { @@ -506,6 +380,138 @@ commit_double_buffered_state (MetaWaylandSurface *surface, double_buffered_state_reset (pending); } +static void +meta_wayland_surface_commit (MetaWaylandSurface *surface) +{ + commit_double_buffered_state (surface, &surface->pending); +} + +static void +wl_surface_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static void +wl_surface_attach (struct wl_client *client, + struct wl_resource *surface_resource, + struct wl_resource *buffer_resource, + gint32 dx, gint32 dy) +{ + MetaWaylandSurface *surface = + wl_resource_get_user_data (surface_resource); + MetaWaylandBuffer *buffer; + + /* X11 unmanaged window */ + if (!surface) + return; + + if (buffer_resource) + buffer = meta_wayland_buffer_from_resource (buffer_resource); + else + buffer = NULL; + + /* Attach without commit in between does not send wl_buffer.release */ + if (surface->pending.buffer) + wl_list_remove (&surface->pending.buffer_destroy_listener.link); + + surface->pending.dx = dx; + surface->pending.dy = dy; + surface->pending.buffer = buffer; + surface->pending.newly_attached = TRUE; + + if (buffer) + wl_signal_add (&buffer->destroy_signal, + &surface->pending.buffer_destroy_listener); +} + +static void +wl_surface_damage (struct wl_client *client, + struct wl_resource *surface_resource, + gint32 x, + gint32 y, + gint32 width, + gint32 height) +{ + MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); + cairo_rectangle_int_t rectangle = { x, y, width, height }; + + /* X11 unmanaged window */ + if (!surface) + return; + + cairo_region_union_rectangle (surface->pending.damage, &rectangle); +} + +static void +destroy_frame_callback (struct wl_resource *callback_resource) +{ + MetaWaylandFrameCallback *callback = + wl_resource_get_user_data (callback_resource); + + wl_list_remove (&callback->link); + g_slice_free (MetaWaylandFrameCallback, callback); +} + +static void +wl_surface_frame (struct wl_client *client, + struct wl_resource *surface_resource, + guint32 callback_id) +{ + MetaWaylandFrameCallback *callback; + MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); + + /* X11 unmanaged window */ + if (!surface) + return; + + callback = g_slice_new0 (MetaWaylandFrameCallback); + callback->compositor = surface->compositor; + callback->resource = wl_resource_create (client, &wl_callback_interface, META_WL_CALLBACK_VERSION, callback_id); + wl_resource_set_implementation (callback->resource, NULL, callback, destroy_frame_callback); + + wl_list_insert (surface->pending.frame_callback_list.prev, &callback->link); +} + +static void +wl_surface_set_opaque_region (struct wl_client *client, + struct wl_resource *surface_resource, + struct wl_resource *region_resource) +{ + MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); + + /* X11 unmanaged window */ + if (!surface) + return; + + g_clear_pointer (&surface->pending.opaque_region, cairo_region_destroy); + if (region_resource) + { + MetaWaylandRegion *region = wl_resource_get_user_data (region_resource); + surface->pending.opaque_region = cairo_region_copy (region->region); + } +} + +static void +wl_surface_set_input_region (struct wl_client *client, + struct wl_resource *surface_resource, + struct wl_resource *region_resource) +{ + MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); + + /* X11 unmanaged window */ + if (!surface) + return; + + g_clear_pointer (&surface->pending.input_region, cairo_region_destroy); + if (region_resource) + { + MetaWaylandRegion *region = wl_resource_get_user_data (region_resource); + surface->pending.input_region = cairo_region_copy (region->region); + } +} + static void wl_surface_commit (struct wl_client *client, struct wl_resource *resource) @@ -516,7 +522,7 @@ wl_surface_commit (struct wl_client *client, if (!surface) return; - commit_double_buffered_state (surface, &surface->pending); + meta_wayland_surface_commit (surface); } static void From a21e7a21886cf8b4cbf3b2262e5259ed19471e1c Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 2 Apr 2014 11:24:19 -0400 Subject: [PATCH 844/889] wayland: Move surface_set_buffer back into the commits For XWayland support, we need to delay the buffer set until after we do the typechecking, as we need to bail out early in that case. --- src/wayland/meta-wayland-surface.c | 61 ++++++++++++++++-------------- 1 file changed, 32 insertions(+), 29 deletions(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 544687786..c3987f7fa 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -144,22 +144,37 @@ ensure_buffer_texture (MetaWaylandBuffer *buffer) buffer->texture = texture; } -static void -cursor_surface_commit (MetaWaylandSurface *surface, - MetaWaylandDoubleBufferedState *pending, - gboolean buffer_changed) +static gboolean +commit_attached_surface (MetaWaylandSurface *surface, + MetaWaylandDoubleBufferedState *pending) { - if (buffer_changed) - meta_wayland_seat_update_cursor_surface (surface->compositor->seat); + /* wl_surface.attach */ + if (pending->newly_attached && surface->buffer != pending->buffer) + { + surface_set_buffer (surface, pending->buffer); + return TRUE; + } + else + return FALSE; } static void +cursor_surface_commit (MetaWaylandSurface *surface, + MetaWaylandDoubleBufferedState *pending) +{ + if (commit_attached_surface (surface, pending)) + meta_wayland_seat_update_cursor_surface (surface->compositor->seat); +} + +static gboolean actor_surface_commit (MetaWaylandSurface *surface, - MetaWaylandDoubleBufferedState *pending, - gboolean buffer_changed) + MetaWaylandDoubleBufferedState *pending) { MetaSurfaceActor *surface_actor = surface->surface_actor; MetaWaylandBuffer *buffer = pending->buffer; + gboolean buffer_changed; + + buffer_changed = commit_attached_surface (surface, pending); if (buffer_changed && buffer) { @@ -173,16 +188,15 @@ actor_surface_commit (MetaWaylandSurface *surface, meta_surface_actor_set_opaque_region (surface_actor, pending->opaque_region); if (pending->input_region) meta_surface_actor_set_input_region (surface_actor, pending->input_region); + + return buffer_changed; } static void toplevel_surface_commit (MetaWaylandSurface *surface, - MetaWaylandDoubleBufferedState *pending, - gboolean buffer_changed) + MetaWaylandDoubleBufferedState *pending) { - actor_surface_commit (surface, pending, buffer_changed); - - if (buffer_changed) + if (actor_surface_commit (surface, pending)) { MetaWindow *window = surface->window; MetaWaylandBuffer *buffer = pending->buffer; @@ -291,8 +305,7 @@ move_double_buffered_state (MetaWaylandDoubleBufferedState *from, static void subsurface_surface_commit (MetaWaylandSurface *surface, - MetaWaylandDoubleBufferedState *pending, - gboolean buffer_changed) + MetaWaylandDoubleBufferedState *pending) { /* * If the sub-surface is in synchronous mode, post-pone the commit of its @@ -312,9 +325,7 @@ subsurface_surface_commit (MetaWaylandSurface *surface, } else { - actor_surface_commit (surface, pending, buffer_changed); - - if (buffer_changed) + if (actor_surface_commit (surface, pending)) { MetaSurfaceActor *surface_actor = surface->surface_actor; MetaWaylandBuffer *buffer = pending->buffer; @@ -347,21 +358,13 @@ commit_double_buffered_state (MetaWaylandSurface *surface, MetaWaylandDoubleBufferedState *pending) { MetaWaylandCompositor *compositor = surface->compositor; - gboolean buffer_changed = FALSE; - - /* wl_surface.attach */ - if (pending->newly_attached && surface->buffer != pending->buffer) - { - surface_set_buffer (surface, pending->buffer); - buffer_changed = TRUE; - } if (surface == compositor->seat->cursor_surface) - cursor_surface_commit (surface, pending, buffer_changed); + cursor_surface_commit (surface, pending); else if (surface->window) - toplevel_surface_commit (surface, pending, buffer_changed); + toplevel_surface_commit (surface, pending); else if (surface->subsurface.resource) - subsurface_surface_commit (surface, pending, buffer_changed); + subsurface_surface_commit (surface, pending); g_list_foreach (surface->subsurfaces, parent_surface_committed, From c40868b239239a8f91ab9b62ccf2a75413246543 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 2 Apr 2014 11:20:30 -0400 Subject: [PATCH 845/889] xwayland: Fix rendering Since we get the ClientMessage after the surface is created, there's no good way to synchronize the two streams. In this case, what we need to do is delay the surface commit until after we get the ClientMessage. Ideally, we'd be using a better surface system overall where committing the surface didn't depend on what type it is, but oh well, this is a good short-term hack for now. --- src/wayland/meta-wayland-surface-private.h | 32 ++++++++++++++++++++++ src/wayland/meta-wayland-surface.c | 11 +++++++- src/wayland/meta-xwayland.c | 8 ++++++ 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 src/wayland/meta-wayland-surface-private.h diff --git a/src/wayland/meta-wayland-surface-private.h b/src/wayland/meta-wayland-surface-private.h new file mode 100644 index 000000000..9b882dfb1 --- /dev/null +++ b/src/wayland/meta-wayland-surface-private.h @@ -0,0 +1,32 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2014 Red Hat + * + * 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. + * + * Written by: + * Jasper St. Pierre + */ + +#ifndef META_WAYLAND_SURFACE_PRIVATE_H +#define META_WAYLAND_SURFACE_PRIVATE_H + +#include "meta-wayland-types.h" + +void meta_wayland_surface_commit (MetaWaylandSurface *surface); + +#endif /* META_WAYLAND_SURFACE_PRIVATE_H */ diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index c3987f7fa..a9aae3540 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -48,6 +48,7 @@ #include "meta-wayland-keyboard.h" #include "meta-wayland-pointer.h" #include "meta-wayland-data-device.h" +#include "meta-wayland-surface-private.h" #include "meta-cursor-tracker-private.h" #include "display-private.h" @@ -365,6 +366,14 @@ commit_double_buffered_state (MetaWaylandSurface *surface, toplevel_surface_commit (surface, pending); else if (surface->subsurface.resource) subsurface_surface_commit (surface, pending); + else + { + /* Unknown surface type. In this case, it's most likely a XWayland + * surface that we haven't gotten the ClientMessage for yet. Make + * sure *not* to reset the double-buffered state or do anything too + * fancy. */ + return; + } g_list_foreach (surface->subsurfaces, parent_surface_committed, @@ -383,7 +392,7 @@ commit_double_buffered_state (MetaWaylandSurface *surface, double_buffered_state_reset (pending); } -static void +void meta_wayland_surface_commit (MetaWaylandSurface *surface) { commit_double_buffered_state (surface, &surface->pending); diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index cb1f54ad1..b913f4927 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -26,6 +26,8 @@ #include "meta-xwayland.h" #include "meta-xwayland-private.h" +#include "meta-wayland-surface-private.h" + #include #include #include @@ -54,6 +56,12 @@ associate_window_with_surface (MetaWindow *window, window->surface = surface; meta_compositor_window_surface_changed (display->compositor, window); + + /* Since the association comes in the form of a ClientMessage, + * we have no way to know when the surface was set up. Since + * commit just breaks if we don't have a window associated with + * it, we need to do a commit *again* here. */ + meta_wayland_surface_commit (surface); } static gboolean From 4752776ebf643619850bb6b1cb44ba734f5ebbcd Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sun, 6 Apr 2014 15:19:04 -0400 Subject: [PATCH 846/889] ui: Don't add our filter function twice --- src/ui/ui.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/ui/ui.c b/src/ui/ui.c index 822eff5cf..0c8149bcb 100644 --- a/src/ui/ui.c +++ b/src/ui/ui.c @@ -253,8 +253,6 @@ meta_ui_new (Display *xdisplay, gdisplay = gdk_x11_lookup_xdisplay (xdisplay); g_assert (gdisplay == gdk_display_get_default ()); - gdk_window_add_filter (NULL, ui_filter_func, NULL); - ui->frames = meta_frames_new (XScreenNumberOfScreen (screen)); /* GTK+ needs the frame-sync protocol to work in order to properly * handle style changes. This means that the dummy widget we create From 840378ae682b20b3c955f77d8c36ade1e7725b7b Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sun, 6 Apr 2014 17:03:53 -0400 Subject: [PATCH 847/889] xprop: Don't use GDK for reading text properties --- src/ui/ui.c | 32 -------------------------------- src/ui/ui.h | 3 --- src/x11/xprops.c | 28 +++++++++++++++++++++++++--- 3 files changed, 25 insertions(+), 38 deletions(-) diff --git a/src/ui/ui.c b/src/ui/ui.c index 0c8149bcb..c5d184285 100644 --- a/src/ui/ui.c +++ b/src/ui/ui.c @@ -650,38 +650,6 @@ meta_ui_window_should_not_cause_focus (Display *xdisplay, return FALSE; } -char* -meta_text_property_to_utf8 (Display *xdisplay, - const XTextProperty *prop) -{ - GdkDisplay *display; - char **list; - int count; - char *retval; - - list = NULL; - - display = gdk_x11_lookup_xdisplay (xdisplay); - count = gdk_text_property_to_utf8_list_for_display (display, - gdk_x11_xatom_to_atom_for_display (display, prop->encoding), - prop->format, - prop->value, - prop->nitems, - &list); - - if (count == 0) - retval = NULL; - else - { - retval = list[0]; - list[0] = g_strdup (""); /* something to free */ - } - - g_strfreev (list); - - return retval; -} - void meta_ui_theme_get_frame_borders (MetaUI *ui, MetaFrameType type, diff --git a/src/ui/ui.h b/src/ui/ui.h index 42b2b0975..165129fa8 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -142,9 +142,6 @@ GdkPixbuf* meta_ui_get_default_mini_icon (MetaUI *ui); gboolean meta_ui_window_should_not_cause_focus (Display *xdisplay, Window xwindow); -char* meta_text_property_to_utf8 (Display *xdisplay, - const XTextProperty *prop); - void meta_ui_set_current_theme (const char *name); gboolean meta_ui_have_a_theme (void); diff --git a/src/x11/xprops.c b/src/x11/xprops.c index 33278ab07..e38006ae1 100644 --- a/src/x11/xprops.c +++ b/src/x11/xprops.c @@ -736,6 +736,29 @@ meta_prop_get_cardinal_with_atom_type (MetaDisplay *display, return cardinal_with_atom_type_from_results (&results, prop_type, cardinal_p); } +static char * +text_property_to_utf8 (Display *xdisplay, + const XTextProperty *prop) +{ + char *ret = NULL; + char **local_list = NULL; + int count = 0; + int res; + + res = XmbTextPropertyToTextList (xdisplay, prop, &local_list, &count); + if (res == XNoMemory || res == XLocaleNotSupported || res == XConverterNotFound) + goto out; + + if (count == 0) + goto out; + + ret = g_strdup (local_list[0]); + + out: + meta_XFree (local_list); + return ret; +} + static gboolean text_property_from_results (GetPropertyResults *results, char **utf8_str_p) @@ -743,15 +766,14 @@ text_property_from_results (GetPropertyResults *results, XTextProperty tp; *utf8_str_p = NULL; - + tp.value = results->prop; results->prop = NULL; tp.encoding = results->type; tp.format = results->format; tp.nitems = results->n_items; - *utf8_str_p = meta_text_property_to_utf8 (results->display->xdisplay, - &tp); + *utf8_str_p = text_property_to_utf8 (results->display->xdisplay, &tp); if (tp.value != NULL) XFree (tp.value); From 0e6570b09b4b2336cbe2acc6dd18587ca95e31ef Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sun, 6 Apr 2014 15:23:10 -0400 Subject: [PATCH 848/889] events: Early exit when we get a SN notification event Nothing else needs to see this. --- src/core/events.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/core/events.c b/src/core/events.c index 35e397f29..086268fab 100644 --- a/src/core/events.c +++ b/src/core/events.c @@ -1754,7 +1754,11 @@ meta_display_handle_xevent (MetaDisplay *display, #endif #ifdef HAVE_STARTUP_NOTIFICATION - sn_display_process_event (display->sn_display, event); + if (sn_display_process_event (display->sn_display, event)) + { + bypass_gtk = bypass_compositor = TRUE; + goto out; + } #endif /* Intercept XRandR events early and don't attempt any From e2b24092d6e7e2313d862e590bfaa4fb8f937c24 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sun, 6 Apr 2014 15:32:30 -0400 Subject: [PATCH 849/889] events: Don't pass any X input events on to Clutter / GTK+ --- src/core/events.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/core/events.c b/src/core/events.c index 086268fab..8546ce672 100644 --- a/src/core/events.c +++ b/src/core/events.c @@ -860,6 +860,17 @@ handle_input_xevent (MetaDisplay *display, if (input_event == NULL) return FALSE; + switch (input_event->evtype) + { + case XI_Enter: + case XI_Leave: + case XI_FocusIn: + case XI_FocusOut: + break; + default: + return FALSE; + } + modified = xievent_get_modified_window (display, input_event); window = modified != None ? meta_display_lookup_x_window (display, modified) : NULL; @@ -934,12 +945,11 @@ handle_input_xevent (MetaDisplay *display, } } - - /* Don't send FocusIn / FocusOut to Clutter */ - return TRUE; + break; } - return FALSE; + /* Don't pass these events through to Clutter / GTK+ */ + return TRUE; } static void From 75de29f5f7768b50f191724626e2878312936230 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sun, 6 Apr 2014 15:54:47 -0400 Subject: [PATCH 850/889] errors: Remove vestigals of old error trap implementation --- src/core/display-private.h | 5 +---- src/core/display.c | 6 ------ 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/src/core/display-private.h b/src/core/display-private.h index 1b8355c72..84ee5a809 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -147,13 +147,10 @@ struct _MetaDisplay guint focused_by_us : 1; /*< private-ish >*/ - guint error_trap_synced_at_last_pop : 1; MetaScreen *screen; GHashTable *xids; GHashTable *wayland_windows; - int error_traps; - int (* error_trap_handler) (Display *display, - XErrorEvent *error); + int server_grab_count; /* serials of leave/unmap events that may diff --git a/src/core/display.c b/src/core/display.c index 716f864f9..231249625 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -472,9 +472,6 @@ meta_display_open (void) */ the_display->name = g_strdup (XDisplayName (NULL)); the_display->xdisplay = xdisplay; - the_display->error_trap_synced_at_last_pop = TRUE; - the_display->error_traps = 0; - the_display->error_trap_handler = NULL; the_display->server_grab_count = 0; the_display->display_opening = TRUE; @@ -1016,9 +1013,6 @@ meta_display_close (MetaDisplay *display, return; } - if (display->error_traps > 0) - meta_bug ("Display closed with error traps pending\n"); - display->closing += 1; meta_prefs_remove_listener (prefs_changed_callback, display); From b9e9595e8b63d8fcc7a3c94c248010a09dd316e4 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sun, 6 Apr 2014 15:52:44 -0400 Subject: [PATCH 851/889] errors: Kill off meta_error_trap_push_with_return It isn't special; it's just an alias for meta_error_trap_push. --- src/compositor/compositor.c | 2 +- src/core/display.c | 2 +- src/core/errors.c | 6 ------ src/core/events.c | 4 ++-- src/core/keybindings.c | 4 ++-- src/core/screen.c | 6 +++--- src/core/window.c | 4 ++-- src/meta/errors.h | 1 - src/x11/iconcache.c | 4 ++-- src/x11/window-x11.c | 8 ++++---- src/x11/xprops.c | 2 +- 11 files changed, 18 insertions(+), 25 deletions(-) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 075d4ac65..acb0599df 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -491,7 +491,7 @@ redirect_windows (MetaScreen *screen) */ while (TRUE) { - meta_error_trap_push_with_return (display); + meta_error_trap_push (display); XCompositeRedirectSubwindows (xdisplay, xroot, CompositeRedirectManual); XSync (xdisplay, FALSE); diff --git a/src/core/display.c b/src/core/display.c index 231249625..c234ad8e8 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -2206,7 +2206,7 @@ meta_change_button_grab (MetaDisplay *display, mods = (XIGrabModifiers) { modmask | ignored_mask, 0 }; if (meta_is_debugging ()) - meta_error_trap_push_with_return (display); + meta_error_trap_push (display); /* GrabModeSync means freeze until XAllowEvents */ diff --git a/src/core/errors.c b/src/core/errors.c index 56a7bd423..f199c69b2 100644 --- a/src/core/errors.c +++ b/src/core/errors.c @@ -55,12 +55,6 @@ meta_error_trap_pop (MetaDisplay *display) gdk_error_trap_pop_ignored (); } -void -meta_error_trap_push_with_return (MetaDisplay *display) -{ - gdk_error_trap_push (); -} - int meta_error_trap_pop_with_return (MetaDisplay *display) { diff --git a/src/core/events.c b/src/core/events.c index 8546ce672..97adfc4f4 100644 --- a/src/core/events.c +++ b/src/core/events.c @@ -1051,7 +1051,7 @@ convert_property (MetaDisplay *display, conversion_targets[2] = display->atom_TIMESTAMP; conversion_targets[3] = display->atom_VERSION; - meta_error_trap_push_with_return (display); + meta_error_trap_push (display); if (target == display->atom_TARGETS) XChangeProperty (display->xdisplay, w, property, XA_ATOM, 32, PropModeReplace, @@ -1126,7 +1126,7 @@ process_selection_request (MetaDisplay *display, unsigned long num, rest; unsigned char *data; - meta_error_trap_push_with_return (display); + meta_error_trap_push (display); if (XGetWindowProperty (display->xdisplay, event->xselectionrequest.requestor, event->xselectionrequest.property, 0, 256, False, diff --git a/src/core/keybindings.c b/src/core/keybindings.c index e663311fb..88ff425fc 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -1065,7 +1065,7 @@ meta_change_keygrab (MetaDisplay *display, mods = (XIGrabModifiers) { modmask | ignored_mask, 0 }; if (meta_is_debugging ()) - meta_error_trap_push_with_return (display); + meta_error_trap_push (display); if (grab) XIGrabKeycode (display->xdisplay, META_VIRTUAL_CORE_KEYBOARD_ID, @@ -1410,7 +1410,7 @@ grab_keyboard (MetaDisplay *display, /* Grab the keyboard, so we get key releases and all key * presses */ - meta_error_trap_push_with_return (display); + meta_error_trap_push (display); /* Strictly, we only need to set grab_mode on the keyboard device * while the pointer should always be XIGrabModeAsync. Unfortunately diff --git a/src/core/screen.c b/src/core/screen.c index 030bab78c..d2c05b07a 100644 --- a/src/core/screen.c +++ b/src/core/screen.c @@ -560,7 +560,7 @@ meta_screen_new (MetaDisplay *display, } /* We want to find out when the current selection owner dies */ - meta_error_trap_push_with_return (display); + meta_error_trap_push (display); attrs.event_mask = StructureNotifyMask; XChangeWindowAttributes (xdisplay, current_wm_sn_owner, CWEventMask, &attrs); @@ -619,7 +619,7 @@ meta_screen_new (MetaDisplay *display, } /* select our root window events */ - meta_error_trap_push_with_return (display); + meta_error_trap_push (display); /* We need to or with the existing event mask since * gtk+ may be interested in other events. @@ -838,7 +838,7 @@ meta_screen_free (MetaScreen *screen, meta_stack_free (screen->stack); meta_stack_tracker_free (screen->stack_tracker); - meta_error_trap_push_with_return (screen->display); + meta_error_trap_push (screen->display); XSelectInput (screen->display->xdisplay, screen->xroot, 0); if (meta_error_trap_pop_with_return (screen->display) != Success) meta_warning ("Could not release screen %d on display \"%s\"\n", diff --git a/src/core/window.c b/src/core/window.c index 0ba7980ab..60a69f304 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -3953,7 +3953,7 @@ meta_window_create_sync_request_alarm (MetaWindow *window) window->sync_request_alarm != None) return; - meta_error_trap_push_with_return (window->display); + meta_error_trap_push (window->display); /* In the new (extended style), the counter value is initialized by * the client before mapping the window. In the old style, we're @@ -8038,7 +8038,7 @@ warp_grab_pointer (MetaWindow *window, *x = CLAMP (*x, 0, window->screen->rect.width-1); *y = CLAMP (*y, 0, window->screen->rect.height-1); - meta_error_trap_push_with_return (display); + meta_error_trap_push (display); meta_topic (META_DEBUG_WINDOW_OPS, "Warping pointer to %d,%d with window at %d,%d\n", diff --git a/src/meta/errors.h b/src/meta/errors.h index d2aa27b6b..36bd9b703 100644 --- a/src/meta/errors.h +++ b/src/meta/errors.h @@ -30,7 +30,6 @@ void meta_error_trap_push (MetaDisplay *display); void meta_error_trap_pop (MetaDisplay *display); -void meta_error_trap_push_with_return (MetaDisplay *display); /* returns X error code, or 0 for no error */ int meta_error_trap_pop_with_return (MetaDisplay *display); diff --git a/src/x11/iconcache.c b/src/x11/iconcache.c index 30018d22e..ac09190f3 100644 --- a/src/x11/iconcache.c +++ b/src/x11/iconcache.c @@ -230,7 +230,7 @@ read_rgb_icon (MetaDisplay *display, int mini_w, mini_h; gulong *data_as_long; - meta_error_trap_push_with_return (display); + meta_error_trap_push (display); type = None; data = NULL; result = XGetWindowProperty (display->xdisplay, @@ -504,7 +504,7 @@ get_kwm_win_icon (MetaDisplay *display, *pixmap = None; *mask = None; - meta_error_trap_push_with_return (display); + meta_error_trap_push (display); icons = NULL; result = XGetWindowProperty (display->xdisplay, xwindow, display->atom__KWM_WIN_ICON, diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c index 896003200..099a55dbd 100644 --- a/src/x11/window-x11.c +++ b/src/x11/window-x11.c @@ -1665,12 +1665,12 @@ meta_window_x11_client_message (MetaWindow *window, char *str1; char *str2; - meta_error_trap_push_with_return (display); + meta_error_trap_push (display); str1 = XGetAtomName (display->xdisplay, first); if (meta_error_trap_pop_with_return (display) != Success) str1 = NULL; - meta_error_trap_push_with_return (display); + meta_error_trap_push (display); str2 = XGetAtomName (display->xdisplay, second); if (meta_error_trap_pop_with_return (display) != Success) str2 = NULL; @@ -2298,7 +2298,7 @@ meta_window_x11_new (MetaDisplay *display, wm_state_to_string (existing_wm_state)); } - meta_error_trap_push_with_return (display); + meta_error_trap_push (display); /* * XAddToSaveSet can only be called on windows created by a different @@ -2309,7 +2309,7 @@ meta_window_x11_new (MetaDisplay *display, */ XAddToSaveSet (display->xdisplay, xwindow); - meta_error_trap_push_with_return (display); + meta_error_trap_push (display); event_mask = PropertyChangeMask; if (attrs.override_redirect) diff --git a/src/x11/xprops.c b/src/x11/xprops.c index e38006ae1..44c1113ca 100644 --- a/src/x11/xprops.c +++ b/src/x11/xprops.c @@ -191,7 +191,7 @@ get_property (MetaDisplay *display, results->bytes_after = 0; results->format = 0; - meta_error_trap_push_with_return (display); + meta_error_trap_push (display); if (XGetWindowProperty (display->xdisplay, xwindow, xatom, 0, G_MAXLONG, False, req_type, &results->type, &results->format, From dbf5d8f9bc6f0f1a6dc9dcdd42f933f5c697434e Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 7 Apr 2014 10:46:50 -0400 Subject: [PATCH 852/889] ui: Kill off meta_ui_accelerator_name It's unused. --- src/ui/ui.c | 37 ------------------------------------- src/ui/ui.h | 4 ---- 2 files changed, 41 deletions(-) diff --git a/src/ui/ui.c b/src/ui/ui.c index c5d184285..6fe435e86 100644 --- a/src/ui/ui.c +++ b/src/ui/ui.c @@ -821,43 +821,6 @@ meta_ui_parse_accelerator (const char *accel, return TRUE; } -/* Caller responsible for freeing return string of meta_ui_accelerator_name! */ -gchar* -meta_ui_accelerator_name (unsigned int keysym, - MetaVirtualModifier mask) -{ - GdkModifierType mods = 0; - - if (keysym == 0 && mask == 0) - { - return g_strdup ("disabled"); - } - - if (mask & META_VIRTUAL_SHIFT_MASK) - mods |= GDK_SHIFT_MASK; - if (mask & META_VIRTUAL_CONTROL_MASK) - mods |= GDK_CONTROL_MASK; - if (mask & META_VIRTUAL_ALT_MASK) - mods |= GDK_MOD1_MASK; - if (mask & META_VIRTUAL_MOD2_MASK) - mods |= GDK_MOD2_MASK; - if (mask & META_VIRTUAL_MOD3_MASK) - mods |= GDK_MOD3_MASK; - if (mask & META_VIRTUAL_MOD4_MASK) - mods |= GDK_MOD4_MASK; - if (mask & META_VIRTUAL_MOD5_MASK) - mods |= GDK_MOD5_MASK; - if (mask & META_VIRTUAL_SUPER_MASK) - mods |= GDK_SUPER_MASK; - if (mask & META_VIRTUAL_HYPER_MASK) - mods |= GDK_HYPER_MASK; - if (mask & META_VIRTUAL_META_MASK) - mods |= GDK_META_MASK; - - return gtk_accelerator_name (keysym, mods); - -} - gboolean meta_ui_parse_modifier (const char *accel, MetaVirtualModifier *mask) diff --git a/src/ui/ui.h b/src/ui/ui.h index 165129fa8..9633b2c20 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -157,10 +157,6 @@ gboolean meta_ui_parse_accelerator (const char *accel, MetaVirtualModifier *mask); gboolean meta_ui_parse_modifier (const char *accel, MetaVirtualModifier *mask); - -/* Caller responsible for freeing return string of meta_ui_accelerator_name! */ -gchar* meta_ui_accelerator_name (unsigned int keysym, - MetaVirtualModifier mask); gboolean meta_ui_window_is_widget (MetaUI *ui, Window xwindow); From 0466fe9301c8d33564809a547de91977904edef7 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 7 Apr 2014 10:48:16 -0400 Subject: [PATCH 853/889] Move meta_ui_parse_accelerator into core/ We're currently using GTK+ for this, but we'll stop doing that fairly quickly and instead just copy the GTK+ code in-tree. --- src/Makefile.am | 2 + src/core/keybindings.c | 3 +- src/core/meta-accel-parse.c | 184 ++++++++++++++++++++++++++++++++++++ src/core/meta-accel-parse.h | 43 +++++++++ src/core/prefs.c | 11 ++- src/ui/ui.c | 158 ------------------------------- src/ui/ui.h | 12 --- 7 files changed, 237 insertions(+), 176 deletions(-) create mode 100644 src/core/meta-accel-parse.c create mode 100644 src/core/meta-accel-parse.h diff --git a/src/Makefile.am b/src/Makefile.am index 61a14fe74..2d6a7df07 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -78,6 +78,8 @@ libmutter_wayland_la_SOURCES = \ backends/x11/meta-monitor-manager-xrandr.c \ backends/x11/meta-monitor-manager-xrandr.h \ backends/x11/meta-xrandr-shared.h \ + core/meta-accel-parse.c \ + core/meta-accel-parse.h \ core/above-tab-keycode.c \ core/barrier.c \ meta/barrier.h \ diff --git a/src/core/keybindings.c b/src/core/keybindings.c index 88ff425fc..cefcf23a0 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -41,6 +41,7 @@ #include "screen-private.h" #include #include "util-private.h" +#include "meta-accel-parse.h" #include #include @@ -1284,7 +1285,7 @@ meta_display_grab_accelerator (MetaDisplay *display, guint mask = 0; MetaVirtualModifier modifiers = 0; - if (!meta_ui_parse_accelerator (accelerator, &keysym, &keycode, &modifiers)) + if (!meta_parse_accelerator (accelerator, &keysym, &keycode, &modifiers)) { meta_topic (META_DEBUG_KEYBINDINGS, "Failed to parse accelerator\n"); diff --git a/src/core/meta-accel-parse.c b/src/core/meta-accel-parse.c new file mode 100644 index 000000000..2a165ef1a --- /dev/null +++ b/src/core/meta-accel-parse.c @@ -0,0 +1,184 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2014 Red Hat + * + * 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. + * + * Written by: + * Jasper St. Pierre + */ + +#include "config.h" + +#include "meta-accel-parse.h" + +#include +#include +#include + +static void +accelerator_parse (const char *accel, + guint *keysym, + guint *keycode, + GdkModifierType *keymask) +{ + const char *above_tab; + + if (accel[0] == '0' && accel[1] == 'x') + { + *keysym = 0; + *keycode = (guint) strtoul (accel, NULL, 16); + *keymask = 0; + + return; + } + + /* The key name 'Above_Tab' is special - it's not an actual keysym name, + * but rather refers to the key above the tab key. In order to use + * the GDK parsing for modifiers in combination with it, we substitute + * it with 'Tab' temporarily before calling gtk_accelerator_parse(). + */ +#define is_word_character(c) (g_ascii_isalnum(c) || ((c) == '_')) +#define ABOVE_TAB "Above_Tab" +#define ABOVE_TAB_LEN 9 + + above_tab = strstr (accel, ABOVE_TAB); + if (above_tab && + (above_tab == accel || !is_word_character (above_tab[-1])) && + !is_word_character (above_tab[ABOVE_TAB_LEN])) + { + char *before = g_strndup (accel, above_tab - accel); + char *after = g_strdup (above_tab + ABOVE_TAB_LEN); + char *replaced = g_strconcat (before, "Tab", after, NULL); + + gtk_accelerator_parse (replaced, NULL, keymask); + + g_free (before); + g_free (after); + g_free (replaced); + + *keysym = META_KEY_ABOVE_TAB; + return; + } + +#undef is_word_character +#undef ABOVE_TAB +#undef ABOVE_TAB_LEN + + gtk_accelerator_parse (accel, keysym, keymask); +} + +gboolean +meta_parse_accelerator (const char *accel, + unsigned int *keysym, + unsigned int *keycode, + MetaVirtualModifier *mask) +{ + GdkModifierType gdk_mask = 0; + guint gdk_sym = 0; + guint gdk_code = 0; + + *keysym = 0; + *keycode = 0; + *mask = 0; + + if (!accel[0] || strcmp (accel, "disabled") == 0) + return TRUE; + + accelerator_parse (accel, &gdk_sym, &gdk_code, &gdk_mask); + if (gdk_mask == 0 && gdk_sym == 0 && gdk_code == 0) + return FALSE; + + if (gdk_sym == None && gdk_code == 0) + return FALSE; + + if (gdk_mask & GDK_RELEASE_MASK) /* we don't allow this */ + return FALSE; + + *keysym = gdk_sym; + *keycode = gdk_code; + + if (gdk_mask & GDK_SHIFT_MASK) + *mask |= META_VIRTUAL_SHIFT_MASK; + if (gdk_mask & GDK_CONTROL_MASK) + *mask |= META_VIRTUAL_CONTROL_MASK; + if (gdk_mask & GDK_MOD1_MASK) + *mask |= META_VIRTUAL_ALT_MASK; + if (gdk_mask & GDK_MOD2_MASK) + *mask |= META_VIRTUAL_MOD2_MASK; + if (gdk_mask & GDK_MOD3_MASK) + *mask |= META_VIRTUAL_MOD3_MASK; + if (gdk_mask & GDK_MOD4_MASK) + *mask |= META_VIRTUAL_MOD4_MASK; + if (gdk_mask & GDK_MOD5_MASK) + *mask |= META_VIRTUAL_MOD5_MASK; + if (gdk_mask & GDK_SUPER_MASK) + *mask |= META_VIRTUAL_SUPER_MASK; + if (gdk_mask & GDK_HYPER_MASK) + *mask |= META_VIRTUAL_HYPER_MASK; + if (gdk_mask & GDK_META_MASK) + *mask |= META_VIRTUAL_META_MASK; + + return TRUE; +} + +gboolean +meta_parse_modifier (const char *accel, + MetaVirtualModifier *mask) +{ + GdkModifierType gdk_mask = 0; + guint gdk_sym = 0; + guint gdk_code = 0; + + *mask = 0; + + if (accel == NULL || !accel[0] || strcmp (accel, "disabled") == 0) + return TRUE; + + accelerator_parse (accel, &gdk_sym, &gdk_code, &gdk_mask); + if (gdk_mask == 0 && gdk_sym == 0 && gdk_code == 0) + return FALSE; + + if (gdk_sym != None || gdk_code != 0) + return FALSE; + + if (gdk_mask & GDK_RELEASE_MASK) /* we don't allow this */ + return FALSE; + + if (gdk_mask & GDK_SHIFT_MASK) + *mask |= META_VIRTUAL_SHIFT_MASK; + if (gdk_mask & GDK_CONTROL_MASK) + *mask |= META_VIRTUAL_CONTROL_MASK; + if (gdk_mask & GDK_MOD1_MASK) + *mask |= META_VIRTUAL_ALT_MASK; + if (gdk_mask & GDK_MOD2_MASK) + *mask |= META_VIRTUAL_MOD2_MASK; + if (gdk_mask & GDK_MOD3_MASK) + *mask |= META_VIRTUAL_MOD3_MASK; + if (gdk_mask & GDK_MOD4_MASK) + *mask |= META_VIRTUAL_MOD4_MASK; + if (gdk_mask & GDK_MOD5_MASK) + *mask |= META_VIRTUAL_MOD5_MASK; + if (gdk_mask & GDK_SUPER_MASK) + *mask |= META_VIRTUAL_SUPER_MASK; + if (gdk_mask & GDK_HYPER_MASK) + *mask |= META_VIRTUAL_HYPER_MASK; + if (gdk_mask & GDK_META_MASK) + *mask |= META_VIRTUAL_META_MASK; + + return TRUE; +} diff --git a/src/core/meta-accel-parse.h b/src/core/meta-accel-parse.h new file mode 100644 index 000000000..1d58375e6 --- /dev/null +++ b/src/core/meta-accel-parse.h @@ -0,0 +1,43 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* + * Copyright (C) 2014 Red Hat + * + * 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. + * + * Written by: + * Jasper St. Pierre + */ + +#ifndef META_ACCEL_PARSE_H +#define META_ACCEL_PARSE_H + +#include +#include + +/* Not a real key symbol but means "key above the tab key"; this is + * used as the default keybinding for cycle_group. + * 0x2xxxxxxx is a range not used by GDK or X. the remaining digits are + * randomly chosen */ +#define META_KEY_ABOVE_TAB 0x2f7259c9 + +gboolean meta_parse_accelerator (const char *accel, + unsigned int *keysym, + unsigned int *keycode, + MetaVirtualModifier *mask); +gboolean meta_parse_modifier (const char *accel, + MetaVirtualModifier *mask); + +#endif /* META_ACCEL_PARSE_H */ diff --git a/src/core/prefs.c b/src/core/prefs.c index a2d01deaf..98d62eed7 100644 --- a/src/core/prefs.c +++ b/src/core/prefs.c @@ -36,6 +36,7 @@ #include #include #include "keybindings-private.h" +#include "meta-accel-parse.h" /* If you add a key, it needs updating in init() and in the gsettings * notify listener and of course in the .schemas file. @@ -1323,7 +1324,7 @@ mouse_button_mods_handler (GVariant *value, *result = NULL; /* ignored */ string_value = g_variant_get_string (value, NULL); - if (!string_value || !meta_ui_parse_modifier (string_value, &mods)) + if (!string_value || !meta_parse_modifier (string_value, &mods)) { meta_topic (META_DEBUG_KEYBINDINGS, "Failed to parse new GSettings value\n"); @@ -1627,9 +1628,9 @@ overlay_key_handler (GVariant *value, *result = NULL; /* ignored */ string_value = g_variant_get_string (value, NULL); - if (string_value && meta_ui_parse_accelerator (string_value, &combo.keysym, - &combo.keycode, - &combo.modifiers)) + if (string_value && meta_parse_accelerator (string_value, &combo.keysym, + &combo.keycode, + &combo.modifiers)) ; else { @@ -1887,7 +1888,7 @@ update_binding (MetaKeyPref *binding, keycode = 0; mods = 0; - if (!meta_ui_parse_accelerator (strokes[i], &keysym, &keycode, &mods)) + if (!meta_parse_accelerator (strokes[i], &keysym, &keycode, &mods)) { meta_topic (META_DEBUG_KEYBINDINGS, "Failed to parse new GSettings value\n"); diff --git a/src/ui/ui.c b/src/ui/ui.c index 6fe435e86..9dbb6a6fd 100644 --- a/src/ui/ui.c +++ b/src/ui/ui.c @@ -32,11 +32,6 @@ #include #include -static void meta_ui_accelerator_parse (const char *accel, - guint *keysym, - guint *keycode, - GdkModifierType *keymask); - struct _MetaUI { Display *xdisplay; @@ -715,159 +710,6 @@ meta_ui_have_a_theme (void) return meta_theme_get_current () != NULL; } -static void -meta_ui_accelerator_parse (const char *accel, - guint *keysym, - guint *keycode, - GdkModifierType *keymask) -{ - const char *above_tab; - - if (accel[0] == '0' && accel[1] == 'x') - { - *keysym = 0; - *keycode = (guint) strtoul (accel, NULL, 16); - *keymask = 0; - - return; - } - - /* The key name 'Above_Tab' is special - it's not an actual keysym name, - * but rather refers to the key above the tab key. In order to use - * the GDK parsing for modifiers in combination with it, we substitute - * it with 'Tab' temporarily before calling gtk_accelerator_parse(). - */ -#define is_word_character(c) (g_ascii_isalnum(c) || ((c) == '_')) -#define ABOVE_TAB "Above_Tab" -#define ABOVE_TAB_LEN 9 - - above_tab = strstr (accel, ABOVE_TAB); - if (above_tab && - (above_tab == accel || !is_word_character (above_tab[-1])) && - !is_word_character (above_tab[ABOVE_TAB_LEN])) - { - char *before = g_strndup (accel, above_tab - accel); - char *after = g_strdup (above_tab + ABOVE_TAB_LEN); - char *replaced = g_strconcat (before, "Tab", after, NULL); - - gtk_accelerator_parse (replaced, NULL, keymask); - - g_free (before); - g_free (after); - g_free (replaced); - - *keysym = META_KEY_ABOVE_TAB; - return; - } - -#undef is_word_character -#undef ABOVE_TAB -#undef ABOVE_TAB_LEN - - gtk_accelerator_parse (accel, keysym, keymask); -} - -gboolean -meta_ui_parse_accelerator (const char *accel, - unsigned int *keysym, - unsigned int *keycode, - MetaVirtualModifier *mask) -{ - GdkModifierType gdk_mask = 0; - guint gdk_sym = 0; - guint gdk_code = 0; - - *keysym = 0; - *keycode = 0; - *mask = 0; - - if (!accel[0] || strcmp (accel, "disabled") == 0) - return TRUE; - - meta_ui_accelerator_parse (accel, &gdk_sym, &gdk_code, &gdk_mask); - if (gdk_mask == 0 && gdk_sym == 0 && gdk_code == 0) - return FALSE; - - if (gdk_sym == None && gdk_code == 0) - return FALSE; - - if (gdk_mask & GDK_RELEASE_MASK) /* we don't allow this */ - return FALSE; - - *keysym = gdk_sym; - *keycode = gdk_code; - - if (gdk_mask & GDK_SHIFT_MASK) - *mask |= META_VIRTUAL_SHIFT_MASK; - if (gdk_mask & GDK_CONTROL_MASK) - *mask |= META_VIRTUAL_CONTROL_MASK; - if (gdk_mask & GDK_MOD1_MASK) - *mask |= META_VIRTUAL_ALT_MASK; - if (gdk_mask & GDK_MOD2_MASK) - *mask |= META_VIRTUAL_MOD2_MASK; - if (gdk_mask & GDK_MOD3_MASK) - *mask |= META_VIRTUAL_MOD3_MASK; - if (gdk_mask & GDK_MOD4_MASK) - *mask |= META_VIRTUAL_MOD4_MASK; - if (gdk_mask & GDK_MOD5_MASK) - *mask |= META_VIRTUAL_MOD5_MASK; - if (gdk_mask & GDK_SUPER_MASK) - *mask |= META_VIRTUAL_SUPER_MASK; - if (gdk_mask & GDK_HYPER_MASK) - *mask |= META_VIRTUAL_HYPER_MASK; - if (gdk_mask & GDK_META_MASK) - *mask |= META_VIRTUAL_META_MASK; - - return TRUE; -} - -gboolean -meta_ui_parse_modifier (const char *accel, - MetaVirtualModifier *mask) -{ - GdkModifierType gdk_mask = 0; - guint gdk_sym = 0; - guint gdk_code = 0; - - *mask = 0; - - if (accel == NULL || !accel[0] || strcmp (accel, "disabled") == 0) - return TRUE; - - meta_ui_accelerator_parse (accel, &gdk_sym, &gdk_code, &gdk_mask); - if (gdk_mask == 0 && gdk_sym == 0 && gdk_code == 0) - return FALSE; - - if (gdk_sym != None || gdk_code != 0) - return FALSE; - - if (gdk_mask & GDK_RELEASE_MASK) /* we don't allow this */ - return FALSE; - - if (gdk_mask & GDK_SHIFT_MASK) - *mask |= META_VIRTUAL_SHIFT_MASK; - if (gdk_mask & GDK_CONTROL_MASK) - *mask |= META_VIRTUAL_CONTROL_MASK; - if (gdk_mask & GDK_MOD1_MASK) - *mask |= META_VIRTUAL_ALT_MASK; - if (gdk_mask & GDK_MOD2_MASK) - *mask |= META_VIRTUAL_MOD2_MASK; - if (gdk_mask & GDK_MOD3_MASK) - *mask |= META_VIRTUAL_MOD3_MASK; - if (gdk_mask & GDK_MOD4_MASK) - *mask |= META_VIRTUAL_MOD4_MASK; - if (gdk_mask & GDK_MOD5_MASK) - *mask |= META_VIRTUAL_MOD5_MASK; - if (gdk_mask & GDK_SUPER_MASK) - *mask |= META_VIRTUAL_SUPER_MASK; - if (gdk_mask & GDK_HYPER_MASK) - *mask |= META_VIRTUAL_HYPER_MASK; - if (gdk_mask & GDK_META_MASK) - *mask |= META_VIRTUAL_META_MASK; - - return TRUE; -} - gboolean meta_ui_window_is_widget (MetaUI *ui, Window xwindow) diff --git a/src/ui/ui.h b/src/ui/ui.h index 9633b2c20..56e19fce8 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -145,18 +145,6 @@ gboolean meta_ui_window_should_not_cause_focus (Display *xdisplay, void meta_ui_set_current_theme (const char *name); gboolean meta_ui_have_a_theme (void); -/* Not a real key symbol but means "key above the tab key"; this is - * used as the default keybinding for cycle_group. - * 0x2xxxxxxx is a range not used by GDK or X. the remaining digits are - * randomly chosen */ -#define META_KEY_ABOVE_TAB 0x2f7259c9 - -gboolean meta_ui_parse_accelerator (const char *accel, - unsigned int *keysym, - unsigned int *keycode, - MetaVirtualModifier *mask); -gboolean meta_ui_parse_modifier (const char *accel, - MetaVirtualModifier *mask); gboolean meta_ui_window_is_widget (MetaUI *ui, Window xwindow); From 242784d3e440cb1b90a50c4fbed04a0bd1c51d16 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 7 Apr 2014 10:54:21 -0400 Subject: [PATCH 854/889] accel-parse: Copy the code from GTK+ in-tree We can't use GTK+ for accelerator parsing under Wayland, since we don't want to go through Xwayland to make that happen. --- src/core/meta-accel-parse.c | 305 +++++++++++++++++++++++++++++++++++- 1 file changed, 303 insertions(+), 2 deletions(-) diff --git a/src/core/meta-accel-parse.c b/src/core/meta-accel-parse.c index 2a165ef1a..8eddd5348 100644 --- a/src/core/meta-accel-parse.c +++ b/src/core/meta-accel-parse.c @@ -30,6 +30,307 @@ #include #include +static inline gboolean +is_alt (const gchar *string) +{ + return ((string[0] == '<') && + (string[1] == 'a' || string[1] == 'A') && + (string[2] == 'l' || string[2] == 'L') && + (string[3] == 't' || string[3] == 'T') && + (string[4] == '>')); +} + +static inline gboolean +is_ctl (const gchar *string) +{ + return ((string[0] == '<') && + (string[1] == 'c' || string[1] == 'C') && + (string[2] == 't' || string[2] == 'T') && + (string[3] == 'l' || string[3] == 'L') && + (string[4] == '>')); +} + +static inline gboolean +is_modx (const gchar *string) +{ + return ((string[0] == '<') && + (string[1] == 'm' || string[1] == 'M') && + (string[2] == 'o' || string[2] == 'O') && + (string[3] == 'd' || string[3] == 'D') && + (string[4] >= '1' && string[4] <= '5') && + (string[5] == '>')); +} + +static inline gboolean +is_ctrl (const gchar *string) +{ + return ((string[0] == '<') && + (string[1] == 'c' || string[1] == 'C') && + (string[2] == 't' || string[2] == 'T') && + (string[3] == 'r' || string[3] == 'R') && + (string[4] == 'l' || string[4] == 'L') && + (string[5] == '>')); +} + +static inline gboolean +is_shft (const gchar *string) +{ + return ((string[0] == '<') && + (string[1] == 's' || string[1] == 'S') && + (string[2] == 'h' || string[2] == 'H') && + (string[3] == 'f' || string[3] == 'F') && + (string[4] == 't' || string[4] == 'T') && + (string[5] == '>')); +} + +static inline gboolean +is_shift (const gchar *string) +{ + return ((string[0] == '<') && + (string[1] == 's' || string[1] == 'S') && + (string[2] == 'h' || string[2] == 'H') && + (string[3] == 'i' || string[3] == 'I') && + (string[4] == 'f' || string[4] == 'F') && + (string[5] == 't' || string[5] == 'T') && + (string[6] == '>')); +} + +static inline gboolean +is_control (const gchar *string) +{ + return ((string[0] == '<') && + (string[1] == 'c' || string[1] == 'C') && + (string[2] == 'o' || string[2] == 'O') && + (string[3] == 'n' || string[3] == 'N') && + (string[4] == 't' || string[4] == 'T') && + (string[5] == 'r' || string[5] == 'R') && + (string[6] == 'o' || string[6] == 'O') && + (string[7] == 'l' || string[7] == 'L') && + (string[8] == '>')); +} + +static inline gboolean +is_release (const gchar *string) +{ + return ((string[0] == '<') && + (string[1] == 'r' || string[1] == 'R') && + (string[2] == 'e' || string[2] == 'E') && + (string[3] == 'l' || string[3] == 'L') && + (string[4] == 'e' || string[4] == 'E') && + (string[5] == 'a' || string[5] == 'A') && + (string[6] == 's' || string[6] == 'S') && + (string[7] == 'e' || string[7] == 'E') && + (string[8] == '>')); +} + +static inline gboolean +is_meta (const gchar *string) +{ + return ((string[0] == '<') && + (string[1] == 'm' || string[1] == 'M') && + (string[2] == 'e' || string[2] == 'E') && + (string[3] == 't' || string[3] == 'T') && + (string[4] == 'a' || string[4] == 'A') && + (string[5] == '>')); +} + +static inline gboolean +is_super (const gchar *string) +{ + return ((string[0] == '<') && + (string[1] == 's' || string[1] == 'S') && + (string[2] == 'u' || string[2] == 'U') && + (string[3] == 'p' || string[3] == 'P') && + (string[4] == 'e' || string[4] == 'E') && + (string[5] == 'r' || string[5] == 'R') && + (string[6] == '>')); +} + +static inline gboolean +is_hyper (const gchar *string) +{ + return ((string[0] == '<') && + (string[1] == 'h' || string[1] == 'H') && + (string[2] == 'y' || string[2] == 'Y') && + (string[3] == 'p' || string[3] == 'P') && + (string[4] == 'e' || string[4] == 'E') && + (string[5] == 'r' || string[5] == 'R') && + (string[6] == '>')); +} + +static inline gboolean +is_primary (const gchar *string) +{ + return ((string[0] == '<') && + (string[1] == 'p' || string[1] == 'P') && + (string[2] == 'r' || string[2] == 'R') && + (string[3] == 'i' || string[3] == 'I') && + (string[4] == 'm' || string[4] == 'M') && + (string[5] == 'a' || string[5] == 'A') && + (string[6] == 'r' || string[6] == 'R') && + (string[7] == 'y' || string[7] == 'Y') && + (string[8] == '>')); +} + +static inline gboolean +is_keycode (const gchar *string) +{ + return (string[0] == '0' && + string[1] == 'x' && + g_ascii_isxdigit (string[2]) && + g_ascii_isxdigit (string[3])); +} + +static void +do_accelerator_parse (const gchar *accelerator, + guint *accelerator_key, + GdkModifierType *accelerator_mods) +{ + guint keyval; + GdkModifierType mods; + gint len; + gboolean error; + + if (accelerator_key) + *accelerator_key = 0; + if (accelerator_mods) + *accelerator_mods = 0; + g_return_if_fail (accelerator != NULL); + + error = FALSE; + keyval = 0; + mods = 0; + len = strlen (accelerator); + while (len) + { + if (*accelerator == '<') + { + if (len >= 9 && is_release (accelerator)) + { + accelerator += 9; + len -= 9; + mods |= GDK_RELEASE_MASK; + } + else if (len >= 9 && is_primary (accelerator)) + { + /* Primary is treated the same as Control */ + accelerator += 9; + len -= 9; + mods |= GDK_CONTROL_MASK; + } + else if (len >= 9 && is_control (accelerator)) + { + accelerator += 9; + len -= 9; + mods |= GDK_CONTROL_MASK; + } + else if (len >= 7 && is_shift (accelerator)) + { + accelerator += 7; + len -= 7; + mods |= GDK_SHIFT_MASK; + } + else if (len >= 6 && is_shft (accelerator)) + { + accelerator += 6; + len -= 6; + mods |= GDK_SHIFT_MASK; + } + else if (len >= 6 && is_ctrl (accelerator)) + { + accelerator += 6; + len -= 6; + mods |= GDK_CONTROL_MASK; + } + else if (len >= 6 && is_modx (accelerator)) + { + static const guint mod_vals[] = { + GDK_MOD1_MASK, GDK_MOD2_MASK, GDK_MOD3_MASK, + GDK_MOD4_MASK, GDK_MOD5_MASK + }; + + len -= 6; + accelerator += 4; + mods |= mod_vals[*accelerator - '1']; + accelerator += 2; + } + else if (len >= 5 && is_ctl (accelerator)) + { + accelerator += 5; + len -= 5; + mods |= GDK_CONTROL_MASK; + } + else if (len >= 5 && is_alt (accelerator)) + { + accelerator += 5; + len -= 5; + mods |= GDK_MOD1_MASK; + } + else if (len >= 6 && is_meta (accelerator)) + { + accelerator += 6; + len -= 6; + mods |= GDK_META_MASK; + } + else if (len >= 7 && is_hyper (accelerator)) + { + accelerator += 7; + len -= 7; + mods |= GDK_HYPER_MASK; + } + else if (len >= 7 && is_super (accelerator)) + { + accelerator += 7; + len -= 7; + mods |= GDK_SUPER_MASK; + } + else + { + gchar last_ch; + + last_ch = *accelerator; + while (last_ch && last_ch != '>') + { + last_ch = *accelerator; + accelerator += 1; + len -= 1; + } + } + } + else + { + if (len >= 4 && is_keycode (accelerator)) + { + /* There was a keycode in the string, but + * we cannot store it, so we have an error */ + error = TRUE; + goto out; + } + else + { + keyval = gdk_keyval_from_name (accelerator); + if (keyval == GDK_KEY_VoidSymbol) + { + error = TRUE; + goto out; + } + } + + accelerator += len; + len -= len; + } + } + +out: + if (error) + keyval = mods = 0; + + if (accelerator_key) + *accelerator_key = gdk_keyval_to_lower (keyval); + if (accelerator_mods) + *accelerator_mods = mods; +} + static void accelerator_parse (const char *accel, guint *keysym, @@ -65,7 +366,7 @@ accelerator_parse (const char *accel, char *after = g_strdup (above_tab + ABOVE_TAB_LEN); char *replaced = g_strconcat (before, "Tab", after, NULL); - gtk_accelerator_parse (replaced, NULL, keymask); + do_accelerator_parse (replaced, NULL, keymask); g_free (before); g_free (after); @@ -79,7 +380,7 @@ accelerator_parse (const char *accel, #undef ABOVE_TAB #undef ABOVE_TAB_LEN - gtk_accelerator_parse (accel, keysym, keymask); + do_accelerator_parse (accel, keysym, keymask); } gboolean From 50e69109b6509a25456c0ecbfbd71f92e6eaa3ee Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 7 Apr 2014 11:03:10 -0400 Subject: [PATCH 855/889] accel-parse: Integrate Above_Tab parsing code directly into our copy --- src/core/meta-accel-parse.c | 41 ++++++------------------------------- 1 file changed, 6 insertions(+), 35 deletions(-) diff --git a/src/core/meta-accel-parse.c b/src/core/meta-accel-parse.c index 8eddd5348..0fc0d2c28 100644 --- a/src/core/meta-accel-parse.c +++ b/src/core/meta-accel-parse.c @@ -306,7 +306,12 @@ do_accelerator_parse (const gchar *accelerator, error = TRUE; goto out; } - else + else if (strcmp (accelerator, "Above_Tab") == 0) + { + keyval = META_KEY_ABOVE_TAB; + goto out; + } + else { keyval = gdk_keyval_from_name (accelerator); if (keyval == GDK_KEY_VoidSymbol) @@ -337,8 +342,6 @@ accelerator_parse (const char *accel, guint *keycode, GdkModifierType *keymask) { - const char *above_tab; - if (accel[0] == '0' && accel[1] == 'x') { *keysym = 0; @@ -348,38 +351,6 @@ accelerator_parse (const char *accel, return; } - /* The key name 'Above_Tab' is special - it's not an actual keysym name, - * but rather refers to the key above the tab key. In order to use - * the GDK parsing for modifiers in combination with it, we substitute - * it with 'Tab' temporarily before calling gtk_accelerator_parse(). - */ -#define is_word_character(c) (g_ascii_isalnum(c) || ((c) == '_')) -#define ABOVE_TAB "Above_Tab" -#define ABOVE_TAB_LEN 9 - - above_tab = strstr (accel, ABOVE_TAB); - if (above_tab && - (above_tab == accel || !is_word_character (above_tab[-1])) && - !is_word_character (above_tab[ABOVE_TAB_LEN])) - { - char *before = g_strndup (accel, above_tab - accel); - char *after = g_strdup (above_tab + ABOVE_TAB_LEN); - char *replaced = g_strconcat (before, "Tab", after, NULL); - - do_accelerator_parse (replaced, NULL, keymask); - - g_free (before); - g_free (after); - g_free (replaced); - - *keysym = META_KEY_ABOVE_TAB; - return; - } - -#undef is_word_character -#undef ABOVE_TAB -#undef ABOVE_TAB_LEN - do_accelerator_parse (accel, keysym, keymask); } From 616f1a09b1ef0de84c44cabf2b7cada057847e5a Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 7 Apr 2014 11:05:46 -0400 Subject: [PATCH 856/889] accel-parse: Add keycode parsing as well --- src/core/meta-accel-parse.c | 37 +++++++++++-------------------------- 1 file changed, 11 insertions(+), 26 deletions(-) diff --git a/src/core/meta-accel-parse.c b/src/core/meta-accel-parse.c index 0fc0d2c28..be86af12d 100644 --- a/src/core/meta-accel-parse.c +++ b/src/core/meta-accel-parse.c @@ -182,17 +182,20 @@ is_keycode (const gchar *string) } static void -do_accelerator_parse (const gchar *accelerator, - guint *accelerator_key, - GdkModifierType *accelerator_mods) +accelerator_parse (const gchar *accelerator, + guint *accelerator_key, + guint *accelerator_keycode, + GdkModifierType *accelerator_mods) { - guint keyval; + guint keyval, keycode; GdkModifierType mods; gint len; gboolean error; if (accelerator_key) *accelerator_key = 0; + if (accelerator_keycode) + *accelerator_keycode = 0; if (accelerator_mods) *accelerator_mods = 0; g_return_if_fail (accelerator != NULL); @@ -301,9 +304,7 @@ do_accelerator_parse (const gchar *accelerator, { if (len >= 4 && is_keycode (accelerator)) { - /* There was a keycode in the string, but - * we cannot store it, so we have an error */ - error = TRUE; + keycode = strtoul (accelerator, NULL, 16); goto out; } else if (strcmp (accelerator, "Above_Tab") == 0) @@ -328,32 +329,16 @@ do_accelerator_parse (const gchar *accelerator, out: if (error) - keyval = mods = 0; + keyval = keycode = mods = 0; if (accelerator_key) *accelerator_key = gdk_keyval_to_lower (keyval); + if (accelerator_keycode) + *accelerator_keycode = keycode; if (accelerator_mods) *accelerator_mods = mods; } -static void -accelerator_parse (const char *accel, - guint *keysym, - guint *keycode, - GdkModifierType *keymask) -{ - if (accel[0] == '0' && accel[1] == 'x') - { - *keysym = 0; - *keycode = (guint) strtoul (accel, NULL, 16); - *keymask = 0; - - return; - } - - do_accelerator_parse (accel, keysym, keymask); -} - gboolean meta_parse_accelerator (const char *accel, unsigned int *keysym, From 0dc63f395dbb1c224b028622d715d84ee55e4457 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 7 Apr 2014 11:06:55 -0400 Subject: [PATCH 857/889] accel-parse: Remove support for --- src/core/meta-accel-parse.c | 28 +--------------------------- 1 file changed, 1 insertion(+), 27 deletions(-) diff --git a/src/core/meta-accel-parse.c b/src/core/meta-accel-parse.c index be86af12d..ceba9bc39 100644 --- a/src/core/meta-accel-parse.c +++ b/src/core/meta-accel-parse.c @@ -109,20 +109,6 @@ is_control (const gchar *string) (string[8] == '>')); } -static inline gboolean -is_release (const gchar *string) -{ - return ((string[0] == '<') && - (string[1] == 'r' || string[1] == 'R') && - (string[2] == 'e' || string[2] == 'E') && - (string[3] == 'l' || string[3] == 'L') && - (string[4] == 'e' || string[4] == 'E') && - (string[5] == 'a' || string[5] == 'A') && - (string[6] == 's' || string[6] == 'S') && - (string[7] == 'e' || string[7] == 'E') && - (string[8] == '>')); -} - static inline gboolean is_meta (const gchar *string) { @@ -208,13 +194,7 @@ accelerator_parse (const gchar *accelerator, { if (*accelerator == '<') { - if (len >= 9 && is_release (accelerator)) - { - accelerator += 9; - len -= 9; - mods |= GDK_RELEASE_MASK; - } - else if (len >= 9 && is_primary (accelerator)) + if (len >= 9 && is_primary (accelerator)) { /* Primary is treated the same as Control */ accelerator += 9; @@ -363,9 +343,6 @@ meta_parse_accelerator (const char *accel, if (gdk_sym == None && gdk_code == 0) return FALSE; - if (gdk_mask & GDK_RELEASE_MASK) /* we don't allow this */ - return FALSE; - *keysym = gdk_sym; *keycode = gdk_code; @@ -412,9 +389,6 @@ meta_parse_modifier (const char *accel, if (gdk_sym != None || gdk_code != 0) return FALSE; - - if (gdk_mask & GDK_RELEASE_MASK) /* we don't allow this */ - return FALSE; if (gdk_mask & GDK_SHIFT_MASK) *mask |= META_VIRTUAL_SHIFT_MASK; From 806f1742accd112360778cfa10b4d2ca1b71d68e Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 7 Apr 2014 11:09:27 -0400 Subject: [PATCH 858/889] accel-parse: Switch code to output MetaVirtualModifier directly --- src/core/meta-accel-parse.c | 92 +++++++++++-------------------------- 1 file changed, 28 insertions(+), 64 deletions(-) diff --git a/src/core/meta-accel-parse.c b/src/core/meta-accel-parse.c index ceba9bc39..da007a095 100644 --- a/src/core/meta-accel-parse.c +++ b/src/core/meta-accel-parse.c @@ -168,13 +168,13 @@ is_keycode (const gchar *string) } static void -accelerator_parse (const gchar *accelerator, - guint *accelerator_key, - guint *accelerator_keycode, - GdkModifierType *accelerator_mods) +accelerator_parse (const gchar *accelerator, + guint *accelerator_key, + guint *accelerator_keycode, + MetaVirtualModifier *accelerator_mods) { guint keyval, keycode; - GdkModifierType mods; + MetaVirtualModifier mods; gint len; gboolean error; @@ -199,37 +199,40 @@ accelerator_parse (const gchar *accelerator, /* Primary is treated the same as Control */ accelerator += 9; len -= 9; - mods |= GDK_CONTROL_MASK; + mods |= META_VIRTUAL_CONTROL_MASK; } else if (len >= 9 && is_control (accelerator)) { accelerator += 9; len -= 9; - mods |= GDK_CONTROL_MASK; + mods |= META_VIRTUAL_CONTROL_MASK; } else if (len >= 7 && is_shift (accelerator)) { accelerator += 7; len -= 7; - mods |= GDK_SHIFT_MASK; + mods |= META_VIRTUAL_SHIFT_MASK; } else if (len >= 6 && is_shft (accelerator)) { accelerator += 6; len -= 6; - mods |= GDK_SHIFT_MASK; + mods |= META_VIRTUAL_SHIFT_MASK; } else if (len >= 6 && is_ctrl (accelerator)) { accelerator += 6; len -= 6; - mods |= GDK_CONTROL_MASK; + mods |= META_VIRTUAL_CONTROL_MASK; } else if (len >= 6 && is_modx (accelerator)) { static const guint mod_vals[] = { - GDK_MOD1_MASK, GDK_MOD2_MASK, GDK_MOD3_MASK, - GDK_MOD4_MASK, GDK_MOD5_MASK + META_VIRTUAL_ALT_MASK, + META_VIRTUAL_MOD2_MASK, + META_VIRTUAL_MOD3_MASK, + META_VIRTUAL_MOD4_MASK, + META_VIRTUAL_MOD5_MASK, }; len -= 6; @@ -241,31 +244,31 @@ accelerator_parse (const gchar *accelerator, { accelerator += 5; len -= 5; - mods |= GDK_CONTROL_MASK; + mods |= META_VIRTUAL_CONTROL_MASK; } else if (len >= 5 && is_alt (accelerator)) { accelerator += 5; len -= 5; - mods |= GDK_MOD1_MASK; + mods |= META_VIRTUAL_ALT_MASK; } else if (len >= 6 && is_meta (accelerator)) { accelerator += 6; len -= 6; - mods |= GDK_META_MASK; + mods |= META_VIRTUAL_META_MASK; } else if (len >= 7 && is_hyper (accelerator)) { accelerator += 7; len -= 7; - mods |= GDK_HYPER_MASK; + mods |= META_VIRTUAL_HYPER_MASK; } else if (len >= 7 && is_super (accelerator)) { accelerator += 7; len -= 7; - mods |= GDK_SUPER_MASK; + mods |= META_VIRTUAL_SUPER_MASK; } else { @@ -325,10 +328,10 @@ meta_parse_accelerator (const char *accel, unsigned int *keycode, MetaVirtualModifier *mask) { - GdkModifierType gdk_mask = 0; + MetaVirtualModifier gdk_mask = 0; guint gdk_sym = 0; guint gdk_code = 0; - + *keysym = 0; *keycode = 0; *mask = 0; @@ -342,30 +345,10 @@ meta_parse_accelerator (const char *accel, if (gdk_sym == None && gdk_code == 0) return FALSE; - + *keysym = gdk_sym; *keycode = gdk_code; - - if (gdk_mask & GDK_SHIFT_MASK) - *mask |= META_VIRTUAL_SHIFT_MASK; - if (gdk_mask & GDK_CONTROL_MASK) - *mask |= META_VIRTUAL_CONTROL_MASK; - if (gdk_mask & GDK_MOD1_MASK) - *mask |= META_VIRTUAL_ALT_MASK; - if (gdk_mask & GDK_MOD2_MASK) - *mask |= META_VIRTUAL_MOD2_MASK; - if (gdk_mask & GDK_MOD3_MASK) - *mask |= META_VIRTUAL_MOD3_MASK; - if (gdk_mask & GDK_MOD4_MASK) - *mask |= META_VIRTUAL_MOD4_MASK; - if (gdk_mask & GDK_MOD5_MASK) - *mask |= META_VIRTUAL_MOD5_MASK; - if (gdk_mask & GDK_SUPER_MASK) - *mask |= META_VIRTUAL_SUPER_MASK; - if (gdk_mask & GDK_HYPER_MASK) - *mask |= META_VIRTUAL_HYPER_MASK; - if (gdk_mask & GDK_META_MASK) - *mask |= META_VIRTUAL_META_MASK; + *mask = gdk_mask; return TRUE; } @@ -374,7 +357,7 @@ gboolean meta_parse_modifier (const char *accel, MetaVirtualModifier *mask) { - GdkModifierType gdk_mask = 0; + MetaVirtualModifier gdk_mask = 0; guint gdk_sym = 0; guint gdk_code = 0; @@ -382,7 +365,7 @@ meta_parse_modifier (const char *accel, if (accel == NULL || !accel[0] || strcmp (accel, "disabled") == 0) return TRUE; - + accelerator_parse (accel, &gdk_sym, &gdk_code, &gdk_mask); if (gdk_mask == 0 && gdk_sym == 0 && gdk_code == 0) return FALSE; @@ -390,26 +373,7 @@ meta_parse_modifier (const char *accel, if (gdk_sym != None || gdk_code != 0) return FALSE; - if (gdk_mask & GDK_SHIFT_MASK) - *mask |= META_VIRTUAL_SHIFT_MASK; - if (gdk_mask & GDK_CONTROL_MASK) - *mask |= META_VIRTUAL_CONTROL_MASK; - if (gdk_mask & GDK_MOD1_MASK) - *mask |= META_VIRTUAL_ALT_MASK; - if (gdk_mask & GDK_MOD2_MASK) - *mask |= META_VIRTUAL_MOD2_MASK; - if (gdk_mask & GDK_MOD3_MASK) - *mask |= META_VIRTUAL_MOD3_MASK; - if (gdk_mask & GDK_MOD4_MASK) - *mask |= META_VIRTUAL_MOD4_MASK; - if (gdk_mask & GDK_MOD5_MASK) - *mask |= META_VIRTUAL_MOD5_MASK; - if (gdk_mask & GDK_SUPER_MASK) - *mask |= META_VIRTUAL_SUPER_MASK; - if (gdk_mask & GDK_HYPER_MASK) - *mask |= META_VIRTUAL_HYPER_MASK; - if (gdk_mask & GDK_META_MASK) - *mask |= META_VIRTUAL_META_MASK; - + *mask = gdk_mask; + return TRUE; } From e70f336a0970ca9e971218746560af0a2a7fee97 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 7 Apr 2014 11:12:14 -0400 Subject: [PATCH 859/889] accel-parse: Use libxkbcommon for keysym parsing This kills our dependency on GTK+ / GDK entirely. --- src/core/meta-accel-parse.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/meta-accel-parse.c b/src/core/meta-accel-parse.c index da007a095..aec068c59 100644 --- a/src/core/meta-accel-parse.c +++ b/src/core/meta-accel-parse.c @@ -26,7 +26,7 @@ #include "meta-accel-parse.h" -#include +#include #include #include @@ -297,8 +297,8 @@ accelerator_parse (const gchar *accelerator, } else { - keyval = gdk_keyval_from_name (accelerator); - if (keyval == GDK_KEY_VoidSymbol) + keyval = xkb_keysym_from_name (accelerator, XKB_KEYSYM_CASE_INSENSITIVE); + if (keyval == XKB_KEY_NoSymbol) { error = TRUE; goto out; @@ -315,7 +315,7 @@ out: keyval = keycode = mods = 0; if (accelerator_key) - *accelerator_key = gdk_keyval_to_lower (keyval); + *accelerator_key = keyval; if (accelerator_keycode) *accelerator_keycode = keycode; if (accelerator_mods) From 545c3b667840e1b0afb517e82fb0a67c25c9bf7b Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 7 Apr 2014 11:20:27 -0400 Subject: [PATCH 860/889] accel-parse: Clean up error handling Now that we have the code in-tree, we can change the API to actually report an error rather than checking afterwards. --- src/core/meta-accel-parse.c | 54 +++++++++---------------------------- 1 file changed, 13 insertions(+), 41 deletions(-) diff --git a/src/core/meta-accel-parse.c b/src/core/meta-accel-parse.c index aec068c59..0ba7d3df8 100644 --- a/src/core/meta-accel-parse.c +++ b/src/core/meta-accel-parse.c @@ -167,16 +167,16 @@ is_keycode (const gchar *string) g_ascii_isxdigit (string[3])); } -static void +static gboolean accelerator_parse (const gchar *accelerator, guint *accelerator_key, guint *accelerator_keycode, MetaVirtualModifier *accelerator_mods) { + gboolean error = FALSE; guint keyval, keycode; MetaVirtualModifier mods; gint len; - gboolean error; if (accelerator_key) *accelerator_key = 0; @@ -184,9 +184,13 @@ accelerator_parse (const gchar *accelerator, *accelerator_keycode = 0; if (accelerator_mods) *accelerator_mods = 0; - g_return_if_fail (accelerator != NULL); - error = FALSE; + if (accelerator == NULL) + { + error = TRUE; + goto out; + } + keyval = 0; mods = 0; len = strlen (accelerator); @@ -312,7 +316,7 @@ accelerator_parse (const gchar *accelerator, out: if (error) - keyval = keycode = mods = 0; + return FALSE; if (accelerator_key) *accelerator_key = keyval; @@ -320,6 +324,8 @@ out: *accelerator_keycode = keycode; if (accelerator_mods) *accelerator_mods = mods; + + return TRUE; } gboolean @@ -328,52 +334,18 @@ meta_parse_accelerator (const char *accel, unsigned int *keycode, MetaVirtualModifier *mask) { - MetaVirtualModifier gdk_mask = 0; - guint gdk_sym = 0; - guint gdk_code = 0; - - *keysym = 0; - *keycode = 0; - *mask = 0; - if (!accel[0] || strcmp (accel, "disabled") == 0) return TRUE; - accelerator_parse (accel, &gdk_sym, &gdk_code, &gdk_mask); - if (gdk_mask == 0 && gdk_sym == 0 && gdk_code == 0) - return FALSE; - - if (gdk_sym == None && gdk_code == 0) - return FALSE; - - *keysym = gdk_sym; - *keycode = gdk_code; - *mask = gdk_mask; - - return TRUE; + return accelerator_parse (accel, keysym, keycode, mask); } gboolean meta_parse_modifier (const char *accel, MetaVirtualModifier *mask) { - MetaVirtualModifier gdk_mask = 0; - guint gdk_sym = 0; - guint gdk_code = 0; - - *mask = 0; - if (accel == NULL || !accel[0] || strcmp (accel, "disabled") == 0) return TRUE; - accelerator_parse (accel, &gdk_sym, &gdk_code, &gdk_mask); - if (gdk_mask == 0 && gdk_sym == 0 && gdk_code == 0) - return FALSE; - - if (gdk_sym != None || gdk_code != 0) - return FALSE; - - *mask = gdk_mask; - - return TRUE; + return accelerator_parse (accel, NULL, NULL, mask); } From 4d4ecae2a1ce928b3ddc92442d5f394a5fc230b6 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 7 Apr 2014 11:24:23 -0400 Subject: [PATCH 861/889] accel-parse: Clean up trailing whitespace --- src/core/meta-accel-parse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/meta-accel-parse.c b/src/core/meta-accel-parse.c index 0ba7d3df8..47fc22a36 100644 --- a/src/core/meta-accel-parse.c +++ b/src/core/meta-accel-parse.c @@ -336,7 +336,7 @@ meta_parse_accelerator (const char *accel, { if (!accel[0] || strcmp (accel, "disabled") == 0) return TRUE; - + return accelerator_parse (accel, keysym, keycode, mask); } From a7d4713393e2969cd8ea82645f67ff1aa6fec47e Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 7 Apr 2014 11:25:16 -0400 Subject: [PATCH 862/889] accel-parse: Add a notice about where the code came from --- src/core/meta-accel-parse.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/core/meta-accel-parse.c b/src/core/meta-accel-parse.c index 47fc22a36..e9d30540b 100644 --- a/src/core/meta-accel-parse.c +++ b/src/core/meta-accel-parse.c @@ -30,6 +30,10 @@ #include #include +/* This is copied from GTK+ and modified to work with mutter's + * internal structures. Originating code comes from gtk/gtkaccelgroup.c + */ + static inline gboolean is_alt (const gchar *string) { From 9fe5a3b407171fc6bc2aef3fb3b18922e1bdd459 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 7 Apr 2014 15:59:38 -0400 Subject: [PATCH 863/889] keybindings: Fix style --- src/core/keybindings.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/keybindings.c b/src/core/keybindings.c index cefcf23a0..f886ed56a 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -743,7 +743,8 @@ display_get_keybinding (MetaDisplay *display, } static guint -next_dynamic_keybinding_action () { +next_dynamic_keybinding_action (void) +{ static guint num_dynamic_bindings = 0; return META_KEYBINDING_ACTION_LAST + (++num_dynamic_bindings); } From 96b6dcec018a29d3fec9c530bf6feb42d9b2d454 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 7 Apr 2014 15:56:21 -0400 Subject: [PATCH 864/889] display: Kill some bad whitespace --- src/core/display.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/display.c b/src/core/display.c index c234ad8e8..8f9e40c40 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -3075,7 +3075,6 @@ meta_display_devirtualize_modifiers (MetaDisplay *display, static void update_window_grab_modifiers (MetaDisplay *display) - { MetaVirtualModifier virtual_mods; unsigned int mods; From 4daf20483da087057a5bb5f6acc129f43a822c56 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 7 Apr 2014 14:49:46 -0400 Subject: [PATCH 865/889] keybindings: Handle META_KEY_ABOVE_TAB in get_keycodes_for_keysym We're going to switch to get_keycodes_for_keysym for the other bindings, so add that special case here. --- src/core/keybindings.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/core/keybindings.c b/src/core/keybindings.c index f886ed56a..a487a45f4 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -311,6 +311,14 @@ get_keycodes_for_keysym (MetaDisplay *display, retval = g_array_new (FALSE, FALSE, sizeof (int)); + /* Special-case: Fake mutter keysym */ + if (keysym == META_KEY_ABOVE_TAB) + { + keycode = meta_display_get_above_tab_keycode (display); + g_array_append_val (retval, keycode); + goto out; + } + keycode = display->min_keycode; while (keycode <= display->max_keycode) { @@ -328,9 +336,9 @@ get_keycodes_for_keysym (MetaDisplay *display, ++keycode; } + out: n_keycodes = retval->len; *keycodes = (int*) g_array_free (retval, n_keycodes == 0 ? TRUE : FALSE); - return n_keycodes; } From 1d08d751086c4b0a112f79c7543425809a9a736a Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 7 Apr 2014 14:51:13 -0400 Subject: [PATCH 866/889] keybindings: Rename and move keysym_to_keycode This makes it more what it's actually doing. --- src/core/keybindings.c | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/src/core/keybindings.c b/src/core/keybindings.c index a487a45f4..1dd04d589 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -342,6 +342,25 @@ get_keycodes_for_keysym (MetaDisplay *display, return n_keycodes; } +static guint +get_first_keycode_for_keysym (MetaDisplay *display, + guint keysym) +{ + int *keycodes; + int n_keycodes; + int keycode; + + n_keycodes = get_keycodes_for_keysym (display, keysym, &keycodes); + + if (n_keycodes > 0) + keycode = keycodes[0]; + else + keycode = 0; + + g_free (keycodes); + return keycode; +} + static void reload_iso_next_group_combos (MetaDisplay *display) { @@ -472,16 +491,6 @@ reload_iso_next_group_combos (MetaDisplay *display) display->iso_next_group_combos = combos; } -static guint -keysym_to_keycode (MetaDisplay *display, - guint keysym) -{ - if (keysym == META_KEY_ABOVE_TAB) - return meta_display_get_above_tab_keycode (display); - else - return XKeysymToKeycode (display->xdisplay, keysym); -} - static void binding_reload_keycode_foreach (gpointer key, gpointer value, @@ -491,7 +500,7 @@ binding_reload_keycode_foreach (gpointer key, MetaKeyBinding *binding = value; if (binding->keysym) - binding->keycode = keysym_to_keycode (display, binding->keysym); + binding->keycode = get_first_keycode_for_keysym (display, binding->keysym); } static void @@ -503,7 +512,7 @@ reload_keycodes (MetaDisplay *display) if (display->overlay_key_combo.keysym != 0) { display->overlay_key_combo.keycode = - keysym_to_keycode (display, display->overlay_key_combo.keysym); + get_first_keycode_for_keysym (display, display->overlay_key_combo.keysym); } else { @@ -1304,7 +1313,7 @@ meta_display_grab_accelerator (MetaDisplay *display, } meta_display_devirtualize_modifiers (display, modifiers, &mask); - keycode = keysym_to_keycode (display, keysym); + keycode = get_first_keycode_for_keysym (display, keysym); if (keycode == 0) return META_KEYBINDING_ACTION_NONE; @@ -1356,7 +1365,7 @@ meta_display_ungrab_accelerator (MetaDisplay *display, return FALSE; meta_display_devirtualize_modifiers (display, grab->combo->modifiers, &mask); - keycode = keysym_to_keycode (display, grab->combo->keysym); + keycode = get_first_keycode_for_keysym (display, grab->combo->keysym); binding = display_get_keybinding (display, keycode, mask); if (binding) From b0ea0afd2f8ef78323b5cb19a804d4d6c4fc3b06 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 7 Apr 2014 17:16:29 -0400 Subject: [PATCH 867/889] display: Remove meta_display_get_ignored_modifier_mask It's unused, in both here and in gnome-shell. --- src/core/display.c | 13 ------------- src/meta/display.h | 2 -- 2 files changed, 15 deletions(-) diff --git a/src/core/display.c b/src/core/display.c index 8f9e40c40..cdcfdd25f 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -1377,19 +1377,6 @@ meta_display_get_current_time_roundtrip (MetaDisplay *display) return timestamp; } -/** - * meta_display_get_ignored_modifier_mask: - * @display: a #MetaDisplay - * - * Returns: a mask of modifiers that should be ignored - * when matching keybindings to events - */ -unsigned int -meta_display_get_ignored_modifier_mask (MetaDisplay *display) -{ - return display->ignored_modifier_mask; -} - /** * meta_display_add_ignored_crossing_serial: * @display: a #MetaDisplay diff --git a/src/meta/display.h b/src/meta/display.h index d6cfacf89..694d7e95a 100644 --- a/src/meta/display.h +++ b/src/meta/display.h @@ -92,8 +92,6 @@ guint32 meta_display_get_last_user_time (MetaDisplay *display); guint32 meta_display_get_current_time (MetaDisplay *display); guint32 meta_display_get_current_time_roundtrip (MetaDisplay *display); -unsigned int meta_display_get_ignored_modifier_mask (MetaDisplay *display); - GList* meta_display_get_tab_list (MetaDisplay *display, MetaTabList type, MetaScreen *screen, From 42bcad6549c44e093b83b5fbd00abc43f987ff8f Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 7 Apr 2014 17:22:55 -0400 Subject: [PATCH 868/889] display: Ignore the modmask passed into meta_display_begin_grab_op A careful analysis of mutter's codebase shows that nothing actually passes anything but 0 to this. gnome-shell has one instance, but it's most likely a mistake. Remove the grab_mask field and the one place in keybindings.c that uses it. The parameter to begin_grab_op is left in for API compatibility reasons. --- src/core/display-private.h | 1 - src/core/display.c | 3 +-- src/core/keybindings.c | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/core/display-private.h b/src/core/display-private.h index 84ee5a809..2bbf184a2 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -196,7 +196,6 @@ struct _MetaDisplay int grab_tile_monitor_number; int grab_latest_motion_x; int grab_latest_motion_y; - gulong grab_mask; guint grab_have_pointer : 1; guint grab_have_keyboard : 1; guint grab_frame_action : 1; diff --git a/src/core/display.c b/src/core/display.c index cdcfdd25f..4556389ee 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -1867,7 +1867,7 @@ meta_display_begin_grab_op (MetaDisplay *display, gboolean pointer_already_grabbed, gboolean frame_action, int button, - gulong modmask, + gulong modmask, /* XXX - ignored */ guint32 timestamp, int root_x, int root_y) @@ -1962,7 +1962,6 @@ meta_display_begin_grab_op (MetaDisplay *display, display->grab_window = grab_window; display->grab_xwindow = grab_xwindow; display->grab_button = button; - display->grab_mask = modmask; if (window) { display->grab_tile_mode = window->tile_mode; diff --git a/src/core/keybindings.c b/src/core/keybindings.c index 1dd04d589..5344aa1ec 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -1763,7 +1763,7 @@ process_overlay_key (MetaDisplay *display, binding = display_get_keybinding (display, display->overlay_key_combo.keycode, - display->grab_mask); + 0); if (binding && meta_compositor_filter_keybinding (display->compositor, binding)) return TRUE; From b38b0370926ed7cfd44e757dd7a201387db1e2d5 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 7 Apr 2014 17:19:39 -0400 Subject: [PATCH 869/889] keybindings: Don't bother saving num_lock / caps_lock in MetaDisplay It's unused outside of this one function. --- src/core/display-private.h | 2 -- src/core/keybindings.c | 18 ++++++++---------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/core/display-private.h b/src/core/display-private.h index 2bbf184a2..0d9524b90 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -233,8 +233,6 @@ struct _MetaDisplay XModifierKeymap *modmap; unsigned int above_tab_keycode; unsigned int ignored_modifier_mask; - unsigned int num_lock_mask; - unsigned int scroll_lock_mask; unsigned int hyper_mask; unsigned int super_mask; unsigned int meta_mask; diff --git a/src/core/keybindings.c b/src/core/keybindings.c index 5344aa1ec..a59f9962b 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -200,6 +200,8 @@ reload_modmap (MetaDisplay *display) XModifierKeymap *modmap; int map_size; int i; + int num_lock_mask = 0; + int scroll_lock_mask = 0; if (display->modmap) XFreeModifiermap (display->modmap); @@ -210,8 +212,6 @@ reload_modmap (MetaDisplay *display) display->ignored_modifier_mask = 0; /* Multiple bits may get set in each of these */ - display->num_lock_mask = 0; - display->scroll_lock_mask = 0; display->meta_mask = 0; display->hyper_mask = 0; display->super_mask = 0; @@ -255,11 +255,11 @@ reload_modmap (MetaDisplay *display) * index */ - display->num_lock_mask |= (1 << ( i / modmap->max_keypermod)); + num_lock_mask |= (1 << ( i / modmap->max_keypermod)); } else if (syms[j] == XK_Scroll_Lock) { - display->scroll_lock_mask |= (1 << ( i / modmap->max_keypermod)); + scroll_lock_mask |= (1 << ( i / modmap->max_keypermod)); } else if (syms[j] == XK_Super_L || syms[j] == XK_Super_R) @@ -284,15 +284,15 @@ reload_modmap (MetaDisplay *display) ++i; } - display->ignored_modifier_mask = (display->num_lock_mask | - display->scroll_lock_mask | + display->ignored_modifier_mask = (num_lock_mask | + scroll_lock_mask | LockMask); meta_topic (META_DEBUG_KEYBINDINGS, "Ignoring modmask 0x%x num lock 0x%x scroll lock 0x%x hyper 0x%x super 0x%x meta 0x%x\n", display->ignored_modifier_mask, - display->num_lock_mask, - display->scroll_lock_mask, + num_lock_mask, + scroll_lock_mask, display->hyper_mask, display->super_mask, display->meta_mask); @@ -3913,8 +3913,6 @@ meta_display_init_keys (MetaDisplay *display) display->min_keycode = 0; display->max_keycode = 0; display->ignored_modifier_mask = 0; - display->num_lock_mask = 0; - display->scroll_lock_mask = 0; display->hyper_mask = 0; display->super_mask = 0; display->meta_mask = 0; From 15cf804dbcb9978d76c548c91d70dda871dad0df Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 7 Apr 2014 15:41:37 -0400 Subject: [PATCH 870/889] keybindings: Eliminate the use of the stored modmap We can simply check the XKB keysym here to see if it's a modifier. --- src/core/display-private.h | 1 - src/core/keybindings.c | 55 +++++++++++++++++--------------------- 2 files changed, 25 insertions(+), 31 deletions(-) diff --git a/src/core/display-private.h b/src/core/display-private.h index 0d9524b90..c46bafe85 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -230,7 +230,6 @@ struct _MetaDisplay int max_keycode; KeySym *keymap; int keysyms_per_keycode; - XModifierKeymap *modmap; unsigned int above_tab_keycode; unsigned int ignored_modifier_mask; unsigned int hyper_mask; diff --git a/src/core/keybindings.c b/src/core/keybindings.c index a59f9962b..cbe893dd1 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -48,6 +48,8 @@ #include #include +#include + #ifdef HAVE_XKB #include #endif @@ -203,12 +205,7 @@ reload_modmap (MetaDisplay *display) int num_lock_mask = 0; int scroll_lock_mask = 0; - if (display->modmap) - XFreeModifiermap (display->modmap); - modmap = XGetModifierMapping (display->xdisplay); - display->modmap = modmap; - display->ignored_modifier_mask = 0; /* Multiple bits may get set in each of these */ @@ -296,6 +293,8 @@ reload_modmap (MetaDisplay *display) display->hyper_mask, display->super_mask, display->meta_mask); + + XFreeModifiermap (modmap); } /* Original code from gdk_x11_keymap_get_entries_for_keyval() in @@ -1017,9 +1016,6 @@ meta_display_shutdown_keys (MetaDisplay *display) if (display->keymap) meta_XFree (display->keymap); - if (display->modmap) - XFreeModifiermap (display->modmap); - g_hash_table_destroy (display->key_bindings_index); g_hash_table_destroy (display->key_bindings); } @@ -1610,28 +1606,28 @@ meta_display_unfreeze_keyboard (MetaDisplay *display, guint32 timestamp) } static gboolean -is_modifier (MetaDisplay *display, - unsigned int keycode) +is_modifier (xkb_keysym_t keysym) { - int i; - int map_size; - gboolean retval = FALSE; - - g_assert (display->modmap); - - map_size = 8 * display->modmap->max_keypermod; - i = 0; - while (i < map_size) + switch (keysym) { - if (keycode == display->modmap->modifiermap[i]) - { - retval = TRUE; - break; - } - ++i; + case XKB_KEY_Shift_L: + case XKB_KEY_Shift_R: + case XKB_KEY_Control_L: + case XKB_KEY_Control_R: + case XKB_KEY_Caps_Lock: + case XKB_KEY_Shift_Lock: + case XKB_KEY_Meta_L: + case XKB_KEY_Meta_R: + case XKB_KEY_Alt_L: + case XKB_KEY_Alt_R: + case XKB_KEY_Super_L: + case XKB_KEY_Super_R: + case XKB_KEY_Hyper_L: + case XKB_KEY_Hyper_R: + return TRUE; + default: + return FALSE; } - - return retval; } static void @@ -2009,7 +2005,7 @@ process_keyboard_move_grab (MetaDisplay *display, return TRUE; /* don't end grab on modifier key presses */ - if (is_modifier (display, event->hardware_keycode)) + if (is_modifier (event->keyval)) return TRUE; meta_window_get_position (window, &x, &y); @@ -2251,7 +2247,7 @@ process_keyboard_resize_grab (MetaDisplay *display, return TRUE; /* don't end grab on modifier key presses */ - if (is_modifier (display, event->hardware_keycode)) + if (is_modifier (event->keyval)) return TRUE; if (event->keyval == CLUTTER_KEY_Escape) @@ -3909,7 +3905,6 @@ meta_display_init_keys (MetaDisplay *display) /* Keybindings */ display->keymap = NULL; display->keysyms_per_keycode = 0; - display->modmap = NULL; display->min_keycode = 0; display->max_keycode = 0; display->ignored_modifier_mask = 0; From db058d4a81af745dee3865965edf9171cd716ad8 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 7 Apr 2014 17:49:06 -0400 Subject: [PATCH 871/889] keybindings: Use xkb_keysym_get_name --- src/core/keybindings.c | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/src/core/keybindings.c b/src/core/keybindings.c index cbe893dd1..17370572f 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -196,6 +196,14 @@ reload_keymap (MetaDisplay *display) &display->keysyms_per_keycode); } +static const char * +keysym_name (xkb_keysym_t keysym) +{ + static char name[32] = ""; + xkb_keysym_get_name (keysym, name, sizeof (name)); + return name; +} + static void reload_modmap (MetaDisplay *display) { @@ -236,12 +244,9 @@ reload_modmap (MetaDisplay *display) { if (syms[j] != 0) { - const char *str; - - str = XKeysymToString (syms[j]); meta_topic (META_DEBUG_KEYBINDINGS, "Keysym %s bound to modifier 0x%x\n", - str ? str : "none", + keysym_name (syms[j]), (1 << ( i / modmap->max_keypermod))); } @@ -1020,18 +1025,6 @@ meta_display_shutdown_keys (MetaDisplay *display) g_hash_table_destroy (display->key_bindings); } -static const char* -keysym_name (int keysym) -{ - const char *name; - - name = XKeysymToString (keysym); - if (name == NULL) - name = "(unknown)"; - - return name; -} - /* Grab/ungrab, ignoring all annoying modifiers like NumLock etc. */ static void meta_change_keygrab (MetaDisplay *display, From a730361d6c96a58c73cd3c782a7741c0737ba52d Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 7 Apr 2014 17:45:38 -0400 Subject: [PATCH 872/889] Use libxkbcommon keysym names everywhere --- src/core/keybindings.c | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/src/core/keybindings.c b/src/core/keybindings.c index 17370572f..f90127a2a 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -43,7 +43,6 @@ #include "util-private.h" #include "meta-accel-parse.h" -#include #include #include #include @@ -250,7 +249,7 @@ reload_modmap (MetaDisplay *display) (1 << ( i / modmap->max_keypermod))); } - if (syms[j] == XK_Num_Lock) + if (syms[j] == XKB_KEY_Num_Lock) { /* Mod1Mask is 1 << 3 for example, i.e. the * fourth modifier, i / keyspermod is the modifier @@ -259,22 +258,22 @@ reload_modmap (MetaDisplay *display) num_lock_mask |= (1 << ( i / modmap->max_keypermod)); } - else if (syms[j] == XK_Scroll_Lock) + else if (syms[j] == XKB_KEY_Scroll_Lock) { scroll_lock_mask |= (1 << ( i / modmap->max_keypermod)); } - else if (syms[j] == XK_Super_L || - syms[j] == XK_Super_R) + else if (syms[j] == XKB_KEY_Super_L || + syms[j] == XKB_KEY_Super_R) { display->super_mask |= (1 << ( i / modmap->max_keypermod)); } - else if (syms[j] == XK_Hyper_L || - syms[j] == XK_Hyper_R) + else if (syms[j] == XKB_KEY_Hyper_L || + syms[j] == XKB_KEY_Hyper_R) { display->hyper_mask |= (1 << ( i / modmap->max_keypermod)); } - else if (syms[j] == XK_Meta_L || - syms[j] == XK_Meta_R) + else if (syms[j] == XKB_KEY_Meta_L || + syms[j] == XKB_KEY_Meta_R) { display->meta_mask |= (1 << ( i / modmap->max_keypermod)); } @@ -382,7 +381,7 @@ reload_iso_next_group_combos (MetaDisplay *display) if (iso_next_group_option == NULL) return; - n_keycodes = get_keycodes_for_keysym (display, XK_ISO_Next_Group, &keycodes); + n_keycodes = get_keycodes_for_keysym (display, XKB_KEY_ISO_Next_Group, &keycodes); if (g_str_equal (iso_next_group_option, "toggle") || g_str_equal (iso_next_group_option, "lalt_toggle") || @@ -401,7 +400,7 @@ reload_iso_next_group_combos (MetaDisplay *display) for (i = 0; i < n_keycodes; ++i) { - combos[i].keysym = XK_ISO_Next_Group; + combos[i].keysym = XKB_KEY_ISO_Next_Group; combos[i].keycode = keycodes[i]; combos[i].modifiers = 0; } @@ -414,7 +413,7 @@ reload_iso_next_group_combos (MetaDisplay *display) for (i = 0; i < n_keycodes; ++i) { - combos[i].keysym = XK_ISO_Next_Group; + combos[i].keysym = XKB_KEY_ISO_Next_Group; combos[i].keycode = keycodes[i]; combos[i].modifiers = ShiftMask; } @@ -427,7 +426,7 @@ reload_iso_next_group_combos (MetaDisplay *display) for (i = 0; i < n_keycodes; ++i) { - combos[i].keysym = XK_ISO_Next_Group; + combos[i].keysym = XKB_KEY_ISO_Next_Group; combos[i].keycode = keycodes[i]; combos[i].modifiers = Mod1Mask; } @@ -441,11 +440,11 @@ reload_iso_next_group_combos (MetaDisplay *display) for (i = 0; i < n_keycodes; ++i) { - combos[i].keysym = XK_ISO_Next_Group; + combos[i].keysym = XKB_KEY_ISO_Next_Group; combos[i].keycode = keycodes[i]; combos[i].modifiers = ShiftMask; - combos[i + n_keycodes].keysym = XK_ISO_Next_Group; + combos[i + n_keycodes].keysym = XKB_KEY_ISO_Next_Group; combos[i + n_keycodes].keycode = keycodes[i]; combos[i + n_keycodes].modifiers = ControlMask; } @@ -457,11 +456,11 @@ reload_iso_next_group_combos (MetaDisplay *display) for (i = 0; i < n_keycodes; ++i) { - combos[i].keysym = XK_ISO_Next_Group; + combos[i].keysym = XKB_KEY_ISO_Next_Group; combos[i].keycode = keycodes[i]; combos[i].modifiers = Mod1Mask; - combos[i + n_keycodes].keysym = XK_ISO_Next_Group; + combos[i + n_keycodes].keysym = XKB_KEY_ISO_Next_Group; combos[i + n_keycodes].keycode = keycodes[i]; combos[i + n_keycodes].modifiers = ControlMask; } @@ -474,11 +473,11 @@ reload_iso_next_group_combos (MetaDisplay *display) for (i = 0; i < n_keycodes; ++i) { - combos[i].keysym = XK_ISO_Next_Group; + combos[i].keysym = XKB_KEY_ISO_Next_Group; combos[i].keycode = keycodes[i]; combos[i].modifiers = Mod1Mask; - combos[i + n_keycodes].keysym = XK_ISO_Next_Group; + combos[i + n_keycodes].keysym = XKB_KEY_ISO_Next_Group; combos[i + n_keycodes].keycode = keycodes[i]; combos[i + n_keycodes].modifiers = ShiftMask; } From 2f229c3928be3af57cf17dd3d983571505adbc3c Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 7 Apr 2014 14:24:53 -0400 Subject: [PATCH 873/889] display: Remove code to calculate the above-tab keycode We always know it will be KEY_GRAVE + 8. --- src/Makefile.am | 1 - src/core/above-tab-keycode.c | 241 ----------------------------------- src/core/display-private.h | 4 - src/core/keybindings.c | 8 +- 4 files changed, 3 insertions(+), 251 deletions(-) delete mode 100644 src/core/above-tab-keycode.c diff --git a/src/Makefile.am b/src/Makefile.am index 2d6a7df07..61cbb7ab0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -80,7 +80,6 @@ libmutter_wayland_la_SOURCES = \ backends/x11/meta-xrandr-shared.h \ core/meta-accel-parse.c \ core/meta-accel-parse.h \ - core/above-tab-keycode.c \ core/barrier.c \ meta/barrier.h \ core/bell.c \ diff --git a/src/core/above-tab-keycode.c b/src/core/above-tab-keycode.c deleted file mode 100644 index e980f5228..000000000 --- a/src/core/above-tab-keycode.c +++ /dev/null @@ -1,241 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* Find the keycode for the key above the tab key */ -/* - * Copyright 2010 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 . - */ - -/* The standard cycle-windows keybinding should be the key above the - * tab key. This will have a different keysym on different keyboards - - * it's the ` (grave) key on US keyboards but something else on many - * other national layouts. So we need to figure out the keycode for - * this key without reference to key symbol. - * - * The "correct" way to do this is to get the XKB geometry from the - * X server, find the Tab key, find the key above the Tab key in the - * same section and use the keycode for that key. This is what I - * implemented here, but unfortunately, fetching the geometry is rather - * slow (It could take 20ms or more.) - * - * If you looking for a way to optimize Mutter startup performance: - * On all Linux systems using evdev the key above TAB will have - * keycode 49. (KEY_GRAVE=41 + the 8 code point offset between - * evdev keysyms and X keysyms.) So a configure option - * --with-above-tab-keycode=49 could be added that bypassed this - * code. It wouldn't work right for displaying Mutter remotely - * to a non-Linux X server, but that is pretty rare. - */ - -#include - -#include - -#include "display-private.h" - -#include - -#ifdef HAVE_XKB -#include -#include - -static guint -compute_above_tab_keycode (Display *xdisplay) -{ - XkbDescPtr keyboard; - XkbGeometryPtr geometry; - int i, j, k; - int tab_keycode; - char *tab_name; - XkbSectionPtr tab_section; - XkbBoundsRec tab_bounds; - XkbKeyPtr best_key = NULL; - guint best_keycode = (guint)-1; - int best_x_dist = G_MAXINT; - int best_y_dist = G_MAXINT; - - /* We need only the Names and the Geometry, but asking for these results - * in the Keyboard information retrieval failing for unknown reasons. - * (Testing with xorg-1.9.1.) So we ask for a part that we don't need - * as well. - */ - keyboard = XkbGetKeyboard (xdisplay, - XkbGBN_ClientSymbolsMask | XkbGBN_KeyNamesMask | XkbGBN_GeometryMask, - XkbUseCoreKbd); - if (!keyboard) - return best_keycode; - - geometry = keyboard->geom; - - /* There could potentially be multiple keys with the Tab keysym on the keyboard; - * but XKeysymToKeycode() returns us the one that the alt-Tab binding will - * use which is good enough - */ - tab_keycode = XKeysymToKeycode (xdisplay, XK_Tab); - if (tab_keycode == 0 || tab_keycode < keyboard->min_key_code || tab_keycode > keyboard->max_key_code) - goto out; - - /* The keyboard geometry is stored by key "name" rather than keycode. - * (Key names are 4-character strings like like TAB or AE01.) We use the - * 'names' part of the keyboard description to map keycode to key name. - * - * XKB has a "key aliases" feature where a single keyboard key can have - * multiple names (with separate sets of aliases in the 'names' part and - * in the 'geometry' part), but I don't really understand it or how it is used, - * so I'm ignoring it here. - */ - - tab_name = keyboard->names->keys[tab_keycode].name; /* Not NULL terminated! */ - - /* First, iterate through the keyboard geometry to find the tab key; the keyboard - * geometry has a three-level heirarchy of section > row > key - */ - for (i = 0; i < geometry->num_sections; i++) - { - XkbSectionPtr section = &geometry->sections[i]; - for (j = 0; j < section->num_rows; j++) - { - int x = 0; - int y = 0; - - XkbRowPtr row = §ion->rows[j]; - for (k = 0; k < row->num_keys; k++) - { - XkbKeyPtr key = &row->keys[k]; - XkbShapePtr shape = XkbKeyShape (geometry, key); - - if (row->vertical) - y += key->gap; - else - x += key->gap; - - if (strncmp (key->name.name, tab_name, XkbKeyNameLength) == 0) - { - tab_section = section; - tab_bounds = shape->bounds; - tab_bounds.x1 += row->left + x; - tab_bounds.x2 += row->left + x; - tab_bounds.y1 += row->top + y; - tab_bounds.y2 += row->top + y; - - goto found_tab; - } - - if (row->vertical) - y += (shape->bounds.y2 - shape->bounds.y1); - else - x += (shape->bounds.x2 - shape->bounds.x1); - } - } - } - - /* No tab key found */ - goto out; - - found_tab: - - /* Now find the key that: - * - Is in the same section as the Tab key - * - Has a horizontal center in the Tab key's horizonal bounds - * - Is above the Tab key at a distance closer than any other key - * - In case of ties, has its horizontal center as close as possible - * to the Tab key's horizontal center - */ - for (j = 0; j < tab_section->num_rows; j++) - { - int x = 0; - int y = 0; - - XkbRowPtr row = &tab_section->rows[j]; - for (k = 0; k < row->num_keys; k++) - { - XkbKeyPtr key = &row->keys[k]; - XkbShapePtr shape = XkbKeyShape(geometry, key); - XkbBoundsRec bounds = shape->bounds; - int x_center; - int x_dist, y_dist; - - if (row->vertical) - y += key->gap; - else - x += key->gap; - - bounds.x1 += row->left + x; - bounds.x2 += row->left + x; - bounds.y1 += row->top + y; - bounds.y2 += row->top + y; - - y_dist = tab_bounds.y1 - bounds.y2; - if (y_dist < 0) - continue; - - x_center = (bounds.x1 + bounds.x2) / 2; - if (x_center < tab_bounds.x1 || x_center > tab_bounds.x2) - continue; - - x_dist = ABS (x_center - (tab_bounds.x1 + tab_bounds.x2) / 2); - - if (y_dist < best_y_dist || - (y_dist == best_y_dist && x_dist < best_x_dist)) - { - best_key = key; - best_x_dist = x_dist; - best_y_dist = y_dist; - } - - if (row->vertical) - y += (shape->bounds.y2 - shape->bounds.y1); - else - x += (shape->bounds.x2 - shape->bounds.x1); - } - } - - if (best_key == NULL) - goto out; - - /* Now we need to resolve the name of the best key back to a keycode */ - for (i = keyboard->min_key_code; i < keyboard->max_key_code; i++) - { - if (strncmp (best_key->name.name, keyboard->names->keys[i].name, XkbKeyNameLength) == 0) - { - best_keycode = i; - break; - } - } - - out: - XkbFreeKeyboard (keyboard, 0, True); - - return best_keycode; -} -#else /* !HAVE_XKB */ -static guint -compute_above_tab_keycode (Display *xdisplay) -{ - return XKeysymToKeycode (xdisplay, XK_grave); -} -#endif /* HAVE_XKB */ - -guint -meta_display_get_above_tab_keycode (MetaDisplay *display) -{ - if (display->above_tab_keycode == 0) /* not yet computed */ - display->above_tab_keycode = compute_above_tab_keycode (display->xdisplay); - - if (display->above_tab_keycode == (guint)-1) /* failed to compute */ - return 0; - else - return display->above_tab_keycode; -} diff --git a/src/core/display-private.h b/src/core/display-private.h index c46bafe85..8209c8f19 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -230,7 +230,6 @@ struct _MetaDisplay int max_keycode; KeySym *keymap; int keysyms_per_keycode; - unsigned int above_tab_keycode; unsigned int ignored_modifier_mask; unsigned int hyper_mask; unsigned int super_mask; @@ -463,9 +462,6 @@ void meta_display_accelerator_activate (MetaDisplay *display, ClutterKeyEvent *event); gboolean meta_display_modifiers_accelerator_activate (MetaDisplay *display); -/* In above-tab-keycode.c */ -guint meta_display_get_above_tab_keycode (MetaDisplay *display); - #ifdef HAVE_XI23 gboolean meta_display_process_barrier_event (MetaDisplay *display, XIEvent *event); diff --git a/src/core/keybindings.c b/src/core/keybindings.c index f90127a2a..8aa247af0 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -47,6 +47,8 @@ #include #include +#include + #include #ifdef HAVE_XKB @@ -184,10 +186,6 @@ reload_keymap (MetaDisplay *display) if (display->keymap) meta_XFree (display->keymap); - /* This is expensive to compute, so we'll lazily load if and when we first - * need it */ - display->above_tab_keycode = 0; - display->keymap = XGetKeyboardMapping (display->xdisplay, display->min_keycode, display->max_keycode - @@ -317,7 +315,7 @@ get_keycodes_for_keysym (MetaDisplay *display, /* Special-case: Fake mutter keysym */ if (keysym == META_KEY_ABOVE_TAB) { - keycode = meta_display_get_above_tab_keycode (display); + keycode = KEY_GRAVE + 8; g_array_append_val (retval, keycode); goto out; } From feca0fb5126c8575db088883030fdd8561efb874 Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Tue, 8 Apr 2014 18:39:15 +0200 Subject: [PATCH 874/889] xwayland: Re-sync input focus when associating a surface to a window When the MetaWindow is created we don't have the surface yet and thus we can't set input focus to it so we need to try again when we get the surface. --- src/wayland/meta-xwayland.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index b913f4927..a4ec03f6e 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -62,6 +62,9 @@ associate_window_with_surface (MetaWindow *window, * commit just breaks if we don't have a window associated with * it, we need to do a commit *again* here. */ meta_wayland_surface_commit (surface); + + /* Now that we have a surface check if it should have focus. */ + meta_display_sync_wayland_input_focus (display); } static gboolean From ab0bd59f5e1d7462a6efacf1a8ca71425a9d1715 Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Wed, 9 Apr 2014 11:27:52 +0530 Subject: [PATCH 875/889] window-props: _NET_WM_WINDOW_OPACITY range is 0xffffffff to 0 After reading the atom, scale the value from 0xffffffff to 0xff. Not doing so causes Clutter to truncate the opacity value, and only read the last two digits. Hence, 0x7fffffff (50%) becomes 0xff (100%). https://bugzilla.gnome.org/show_bug.cgi?id=727874 --- src/x11/window-props.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/x11/window-props.c b/src/x11/window-props.c index 128dfdeb7..404e61b24 100644 --- a/src/x11/window-props.c +++ b/src/x11/window-props.c @@ -1594,12 +1594,12 @@ reload_window_opacity (MetaWindow *window, gboolean initial) { - int requested_value = 0xFF; + guint8 opacity = 0xFF; if (value->type != META_PROP_VALUE_INVALID) - requested_value = (int) value->v.cardinal; + opacity = (guint8)((gfloat)value->v.cardinal * 255.0 / ((gfloat)0xffffffff)); - meta_window_set_opacity (window, requested_value); + meta_window_set_opacity (window, opacity); } #define RELOAD_STRING(var_name, propname) \ From 797c46ba7d7ef65414ab1cec9d716aafe35a9a95 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 9 Apr 2014 11:38:39 -0700 Subject: [PATCH 876/889] events: Fix event handling for window menus under X11 We need to pass XI_Enter / XI_Leave events for GTK+ windows to GTK+, rather than eating them. --- src/core/events.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/core/events.c b/src/core/events.c index 97adfc4f4..3cc548835 100644 --- a/src/core/events.c +++ b/src/core/events.c @@ -874,6 +874,10 @@ handle_input_xevent (MetaDisplay *display, modified = xievent_get_modified_window (display, input_event); window = modified != None ? meta_display_lookup_x_window (display, modified) : NULL; + /* If this is an event for a GTK+ widget, let GTK+ handle it. */ + if (meta_ui_window_is_widget (display->screen->ui, modified)) + return FALSE; + switch (input_event->evtype) { case XI_Enter: From 99ad5c00a77b3dbbe4f7687ceced907ed2f0d336 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 20 Aug 2013 16:32:02 -0400 Subject: [PATCH 877/889] texture-tower: Remove CPU codepath for mipmap generation The CPU codepath for mipmapping is unusably slow, and we expect modern graphics cards with modern TFP/FBO support. --- src/compositor/meta-texture-tower.c | 141 +--------------------------- 1 file changed, 2 insertions(+), 139 deletions(-) diff --git a/src/compositor/meta-texture-tower.c b/src/compositor/meta-texture-tower.c index 0fd5f5f70..bafd508b8 100644 --- a/src/compositor/meta-texture-tower.c +++ b/src/compositor/meta-texture-tower.c @@ -373,7 +373,7 @@ texture_tower_create_texture (MetaTextureTower *tower, tower->invalid[level].y2 = height; } -static gboolean +static void texture_tower_revalidate_fbo (MetaTextureTower *tower, int level) { @@ -408,150 +408,13 @@ texture_tower_revalidate_fbo (MetaTextureTower *tower, (2. * invalid->y2) / source_texture_height); cogl_pop_framebuffer (); - - return TRUE; -} - -static void -fill_copy (guchar *buf, - const guchar *source, - int width) -{ - memcpy (buf, source, width * 4); -} - -static void -fill_scale_down (guchar *buf, - const guchar *source, - int width) -{ - while (width > 1) - { - buf[0] = (source[0] + source[4]) / 2; - buf[1] = (source[1] + source[5]) / 2; - buf[2] = (source[2] + source[6]) / 2; - buf[3] = (source[3] + source[7]) / 2; - - buf += 4; - source += 8; - width -= 2; - } - - if (width > 0) - { - buf[0] = source[0] / 2; - buf[1] = source[1] / 2; - buf[2] = source[2] / 2; - buf[3] = source[3] / 2; - } -} - -static void -texture_tower_revalidate_client (MetaTextureTower *tower, - int level) -{ - CoglTexture *source_texture = tower->textures[level - 1]; - int source_texture_width = cogl_texture_get_width (source_texture); - int source_texture_height = cogl_texture_get_height (source_texture); - guint source_rowstride; - guchar *source_data; - CoglTexture *dest_texture = tower->textures[level]; - int dest_texture_width = cogl_texture_get_width (dest_texture); - int dest_texture_height = cogl_texture_get_height (dest_texture); - int dest_x = tower->invalid[level].x1; - int dest_y = tower->invalid[level].y1; - int dest_width = tower->invalid[level].x2 - tower->invalid[level].x1; - int dest_height = tower->invalid[level].y2 - tower->invalid[level].y1; - guchar *dest_data; - guchar *source_tmp1 = NULL, *source_tmp2 = NULL; - int i, j; - - source_rowstride = source_texture_width * 4; - - source_data = g_malloc (source_texture_height * source_rowstride); - cogl_texture_get_data (source_texture, TEXTURE_FORMAT, source_rowstride, - source_data); - - dest_data = g_malloc (dest_height * dest_width * 4); - - if (dest_texture_height < source_texture_height) - { - source_tmp1 = g_malloc (dest_width * 4); - source_tmp2 = g_malloc (dest_width * 4); - } - - for (i = 0; i < dest_height; i++) - { - guchar *dest_row = dest_data + i * dest_width * 4; - if (dest_texture_height < source_texture_height) - { - guchar *source1, *source2; - guchar *dest; - - if (dest_texture_width < source_texture_width) - { - fill_scale_down (source_tmp1, - source_data + ((i + dest_y) * 2) * source_rowstride + dest_x * 2 * 4, - dest_width * 2); - fill_scale_down (source_tmp2, - source_data + ((i + dest_y) * 2 + 1) * source_rowstride + dest_x * 2 * 4, - dest_width * 2); - } - else - { - fill_copy (source_tmp1, - source_data + ((i + dest_y) * 2) * source_rowstride + dest_x * 4, - dest_width); - fill_copy (source_tmp2, - source_data + ((i + dest_y) * 2 + 1) * source_rowstride + dest_x * 4, - dest_width); - } - - source1 = source_tmp1; - source2 = source_tmp2; - - dest = dest_row; - for (j = 0; j < dest_width * 4; j++) - *(dest++) = (*(source1++) + *(source2++)) / 2; - } - else - { - if (dest_texture_width < source_texture_width) - fill_scale_down (dest_row, - source_data + (i + dest_y) * source_rowstride + dest_x * 2 * 4, - dest_width * 2); - else - fill_copy (dest_row, - source_data + (i + dest_y) * source_rowstride, - dest_width); - } - } - - cogl_texture_set_region (dest_texture, - 0, 0, - dest_x, dest_y, - dest_width, dest_height, - dest_width, dest_height, - TEXTURE_FORMAT, - 4 * dest_width, - dest_data); - - if (dest_texture_height < source_texture_height) - { - g_free (source_tmp1); - g_free (source_tmp2); - } - - g_free (source_data); - g_free (dest_data); } static void texture_tower_revalidate (MetaTextureTower *tower, int level) { - if (!texture_tower_revalidate_fbo (tower, level)) - texture_tower_revalidate_client (tower, level); + texture_tower_revalidate_fbo (tower, level); } /** From d0b870d3a9f4e5e90c42bfa2663b205a14c4b180 Mon Sep 17 00:00:00 2001 From: Robert Bragg Date: Wed, 21 Aug 2013 01:52:16 +0100 Subject: [PATCH 878/889] tower: make sure not to blend when updating tower Each level in the tower is initialized by binding the texture for that level to an offscreen framebuffer and rendering the previous level as a textured rectangle. The problem was that we were blending the previous level with undefined data so argb32 windows with transparencies would result in artefacts. This makes sure to disable blending when drawing the textured rectangle. --- src/compositor/meta-texture-tower.c | 49 +++++++++++++++++++---------- 1 file changed, 33 insertions(+), 16 deletions(-) diff --git a/src/compositor/meta-texture-tower.c b/src/compositor/meta-texture-tower.c index bafd508b8..ced55510f 100644 --- a/src/compositor/meta-texture-tower.c +++ b/src/compositor/meta-texture-tower.c @@ -60,6 +60,7 @@ struct _MetaTextureTower CoglTexture *textures[MAX_TEXTURE_LEVELS]; CoglOffscreen *fbos[MAX_TEXTURE_LEVELS]; Box invalid[MAX_TEXTURE_LEVELS]; + CoglPipeline *pipeline_template; }; /** @@ -91,6 +92,9 @@ meta_texture_tower_free (MetaTextureTower *tower) { g_return_if_fail (tower != NULL); + if (tower->pipeline_template != NULL) + cogl_object_unref (tower->pipeline_template); + meta_texture_tower_set_base_texture (tower, NULL); g_slice_free (MetaTextureTower, tower); @@ -384,30 +388,43 @@ texture_tower_revalidate_fbo (MetaTextureTower *tower, int dest_texture_width = cogl_texture_get_width (dest_texture); int dest_texture_height = cogl_texture_get_height (dest_texture); Box *invalid = &tower->invalid[level]; - CoglMatrix modelview; + CoglFramebuffer *fb; + CoglError *catch_error = NULL; + CoglPipeline *pipeline; if (tower->fbos[level] == NULL) - tower->fbos[level] = cogl_offscreen_new_to_texture (dest_texture); + tower->fbos[level] = cogl_offscreen_new_with_texture (dest_texture); - if (tower->fbos[level] == NULL) - return FALSE; + fb = COGL_FRAMEBUFFER (tower->fbos[level]); - cogl_push_framebuffer (COGL_FRAMEBUFFER (tower->fbos[level])); + if (!cogl_framebuffer_allocate (fb, &catch_error)) + { + cogl_error_free (catch_error); + return FALSE; + } - cogl_ortho (0, dest_texture_width, dest_texture_height, 0, -1., 1.); + cogl_framebuffer_orthographic (fb, 0, 0, dest_texture_width, dest_texture_height, -1., 1.); - cogl_matrix_init_identity (&modelview); - cogl_set_modelview_matrix (&modelview); + if (!tower->pipeline_template) + { + CoglContext *ctx = + clutter_backend_get_cogl_context (clutter_get_default_backend ()); + tower->pipeline_template = cogl_pipeline_new (ctx); + cogl_pipeline_set_blend (tower->pipeline_template, "RGBA = ADD (SRC_COLOR, 0)", NULL); + } - cogl_set_source_texture (tower->textures[level - 1]); - cogl_rectangle_with_texture_coords (invalid->x1, invalid->y1, - invalid->x2, invalid->y2, - (2. * invalid->x1) / source_texture_width, - (2. * invalid->y1) / source_texture_height, - (2. * invalid->x2) / source_texture_width, - (2. * invalid->y2) / source_texture_height); + pipeline = cogl_pipeline_copy (tower->pipeline_template); + cogl_pipeline_set_layer_texture (pipeline, 0, tower->textures[level - 1]); - cogl_pop_framebuffer (); + cogl_framebuffer_draw_textured_rectangle (fb, pipeline, + invalid->x1, invalid->y1, + invalid->x2, invalid->y2, + (2. * invalid->x1) / source_texture_width, + (2. * invalid->y1) / source_texture_height, + (2. * invalid->x2) / source_texture_width, + (2. * invalid->y2) / source_texture_height); + + cogl_object_unref (pipeline); } static void From 7ac66faa721cedf0d3c7626cab2960c3de09604a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 21 Aug 2013 22:05:49 +0200 Subject: [PATCH 879/889] tower: Fix erroneous return value The function's return value is void, not gboolean. --- src/compositor/meta-texture-tower.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compositor/meta-texture-tower.c b/src/compositor/meta-texture-tower.c index ced55510f..5d82addb4 100644 --- a/src/compositor/meta-texture-tower.c +++ b/src/compositor/meta-texture-tower.c @@ -400,7 +400,7 @@ texture_tower_revalidate_fbo (MetaTextureTower *tower, if (!cogl_framebuffer_allocate (fb, &catch_error)) { cogl_error_free (catch_error); - return FALSE; + return; } cogl_framebuffer_orthographic (fb, 0, 0, dest_texture_width, dest_texture_height, -1., 1.); From e215f3f5eb379ec95b3bae06c32043d94292a4aa Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Tue, 15 Oct 2013 20:12:05 +0200 Subject: [PATCH 880/889] monitor-config: prevent assert that at least one output is connected Apparently some connector technologies don't distinguish between on and off, and there might be valid use cases for running without any connected monitor. In that case, just avoid any configuration at all. https://bugzilla.gnome.org/show_bug.cgi?id=709009 --- src/backends/meta-monitor-config.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/backends/meta-monitor-config.c b/src/backends/meta-monitor-config.c index 8150c091f..f7ddce527 100644 --- a/src/backends/meta-monitor-config.c +++ b/src/backends/meta-monitor-config.c @@ -840,6 +840,9 @@ meta_monitor_config_get_stored (MetaMonitorConfig *self, MetaConfiguration key; MetaConfiguration *stored; + if (n_outputs == 0) + return NULL; + make_config_key (&key, outputs, n_outputs, -1); stored = g_hash_table_lookup (self->configs, &key); @@ -1247,6 +1250,12 @@ meta_monitor_config_make_default (MetaMonitorConfig *self, outputs = meta_monitor_manager_get_outputs (manager, &n_outputs); meta_monitor_manager_get_screen_limits (manager, &max_width, &max_height); + if (n_outputs == 0) + { + meta_verbose ("No output connected, not applying configuration\n"); + return; + } + default_config = make_default_config (self, outputs, n_outputs, max_width, max_height); if (default_config != NULL) From 42f267bb5097ba6b35f610c3dae9284966d9a181 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Mon, 2 Sep 2013 09:29:26 +0200 Subject: [PATCH 881/889] MonitorManager: make sure to pass the right sizes to vararg functions A gulong is not enough to get 64 bits in all arches, so we must cast it, or we can corrupt the stack. This was downstream bug bugzilla.redhat.com/show_bug.cgi?id=1002055 https://bugzilla.gnome.org/show_bug.cgi?id=707267 --- src/backends/meta-monitor-manager.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c index 3e0a238d3..a437c5fa6 100644 --- a/src/backends/meta-monitor-manager.c +++ b/src/backends/meta-monitor-manager.c @@ -536,13 +536,13 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton, g_variant_builder_add (&crtc_builder, "(uxiiiiiuaua{sv})", i, /* ID */ - crtc->crtc_id, + (gint64)crtc->crtc_id, (int)crtc->rect.x, (int)crtc->rect.y, (int)crtc->rect.width, (int)crtc->rect.height, (int)(crtc->current_mode ? crtc->current_mode - manager->modes : -1), - crtc->transform, + (guint32)crtc->transform, &transforms, NULL /* properties */); } @@ -613,7 +613,7 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton, g_variant_builder_add (&output_builder, "(uxiausauaua{sv})", i, /* ID */ - output->output_id, + (gint64)output->output_id, (int)(output->crtc ? output->crtc - manager->crtcs : -1), &crtcs, output->name, @@ -628,9 +628,9 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton, g_variant_builder_add (&mode_builder, "(uxuud)", i, /* ID */ - mode->mode_id, - mode->width, - mode->height, + (gint64)mode->mode_id, + (guint32)mode->width, + (guint32)mode->height, (double)mode->refresh_rate); } From f68d65a5aed13193b4f232f5d257f3367752a29e Mon Sep 17 00:00:00 2001 From: Robert Ancell Date: Tue, 4 Feb 2014 12:36:11 +0000 Subject: [PATCH 882/889] xrandr: Use specified output property name for backlight control Backlight controls are set using the "BACKLIGHT" XRANDR output property. This should be "Backlight" according to the XRANDR spec [1]. Some drivers (Intel) export both properties and some only the specified property (nvidia). Users of drivers that only export the specified property cannot change their backlight using XRANDR. [1] http://cgit.freedesktop.org/xorg/proto/randrproto/tree/randrproto.txt section 9.1 https://bugzilla.gnome.org/show_bug.cgi?id=723606 --- src/backends/x11/meta-monitor-manager-xrandr.c | 6 +++--- src/meta/atomnames.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c index 86ce344ee..f8284a066 100644 --- a/src/backends/x11/meta-monitor-manager-xrandr.c +++ b/src/backends/x11/meta-monitor-manager-xrandr.c @@ -186,7 +186,7 @@ output_get_backlight_xrandr (MetaMonitorManagerXrandr *manager_xrandr, XRRGetOutputProperty (manager_xrandr->xdisplay, (XID)output->output_id, - display->atom_BACKLIGHT, + display->atom_Backlight, 0, G_MAXLONG, False, False, XA_INTEGER, &actual_type, &actual_format, &nitems, &bytes_after, &buffer); @@ -211,7 +211,7 @@ output_get_backlight_limits_xrandr (MetaMonitorManagerXrandr *manager_xrandr, meta_error_trap_push (display); info = XRRQueryOutputProperty (manager_xrandr->xdisplay, (XID)output->output_id, - display->atom_BACKLIGHT); + display->atom_Backlight); meta_error_trap_pop (display); if (info == NULL) @@ -947,7 +947,7 @@ meta_monitor_manager_xrandr_change_backlight (MetaMonitorManager *manager, meta_error_trap_push (display); XRRChangeOutputProperty (manager_xrandr->xdisplay, (XID)output->output_id, - display->atom_BACKLIGHT, + display->atom_Backlight, XA_INTEGER, 32, PropModeReplace, (unsigned char *) &hw_value, 1); meta_error_trap_pop (display); diff --git a/src/meta/atomnames.h b/src/meta/atomnames.h index 38227deaa..46e1a664e 100644 --- a/src/meta/atomnames.h +++ b/src/meta/atomnames.h @@ -78,7 +78,7 @@ item(MULTIPLE) item(TIMESTAMP) item(VERSION) item(ATOM_PAIR) -item(BACKLIGHT) +item(Backlight) item(_XKB_RULES_NAMES) item(hotplug_mode_update) item(WL_SURFACE_ID) From c2b91559798b5ea8c7f9af11569803839c7df475 Mon Sep 17 00:00:00 2001 From: Colin Guthrie Date: Mon, 2 Sep 2013 16:09:22 +0100 Subject: [PATCH 883/889] MonitorXrandr: Mask a BadValue error on VirtualBox. https://bugzilla.gnome.org/show_bug.cgi?id=707563 --- src/backends/x11/meta-monitor-manager-xrandr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c index f8284a066..5fbddd48d 100644 --- a/src/backends/x11/meta-monitor-manager-xrandr.c +++ b/src/backends/x11/meta-monitor-manager-xrandr.c @@ -677,11 +677,13 @@ output_set_presentation_xrandr (MetaMonitorManagerXrandr *manager_xrandr, MetaDisplay *display = meta_get_display (); int value = presentation; + meta_error_trap_push (display); XRRChangeOutputProperty (manager_xrandr->xdisplay, (XID)output->output_id, display->atom__MUTTER_PRESENTATION_OUTPUT, XA_CARDINAL, 32, PropModeReplace, (unsigned char*) &value, 1); + meta_error_trap_pop (display); } static void From 4396ac809bdd3aa49d946086aecdac4a815b17f5 Mon Sep 17 00:00:00 2001 From: "A. Walton" Date: Wed, 16 Oct 2013 22:39:21 -0400 Subject: [PATCH 884/889] screen: Name the guard window So that extensons can recognize it, for the case where they want to watch the window list. https://bugzilla.gnome.org/show_bug.cgi?id=710346 --- src/core/screen.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/core/screen.c b/src/core/screen.c index d2c05b07a..2250dee40 100644 --- a/src/core/screen.c +++ b/src/core/screen.c @@ -477,6 +477,9 @@ create_guard_window (Display *xdisplay, MetaScreen *screen) CWEventMask|CWOverrideRedirect, &attributes); + /* https://bugzilla.gnome.org/show_bug.cgi?id=710346 */ + XStoreName (xdisplay, guard_window, "mutter guard window"); + { unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits }; From ebbdfabed6922b650796a882324560441574d0c7 Mon Sep 17 00:00:00 2001 From: "Owen W. Taylor" Date: Fri, 22 Nov 2013 08:57:44 -0500 Subject: [PATCH 885/889] window-props.c: React to changes to _GTK_FRAME_EXTENTS When _GTK_FRAME_EXTENTS changes, we need to redo constraints on the window - this matters in particular if the toolkit removes invisible borders when a window is maximized, since otherwise the maximized window will be positioned as if it still has invisible borders. https://bugzilla.gnome.org/show_bug.cgi?id=714707 --- src/x11/window-props.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/x11/window-props.c b/src/x11/window-props.c index 404e61b24..755225122 100644 --- a/src/x11/window-props.c +++ b/src/x11/window-props.c @@ -316,6 +316,9 @@ reload_gtk_frame_extents (MetaWindow *window, { meta_window_set_custom_frame_extents (window, NULL); } + + if (!initial) + meta_window_queue(window, META_QUEUE_MOVE_RESIZE); } static void From 814b2dbda91ecf33315bacf3e8f0f1e4f679a947 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Se=C3=A1n=20de=20B=C3=BArca?= Date: Mon, 26 Aug 2013 06:47:13 -0400 Subject: [PATCH 886/889] build: Create m4 directory Due to changes in gnome-common git, an implicit m4 directory is no longer created during autogen. The attached patch explicitly and correctly specifies a macro directory. https://bugzilla.gnome.org/show_bug.cgi?id=706787 --- Makefile.am | 2 ++ configure.ac | 1 + 2 files changed, 3 insertions(+) diff --git a/Makefile.am b/Makefile.am index 0529c4009..b55c1d144 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,8 @@ SUBDIRS=src po doc +ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS} + DISTCLEANFILES = intltool-extract intltool-merge intltool-update po/stamp-it po/.intltool-merge-cache DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc diff --git a/configure.ac b/configure.ac index 180af409e..3f91c7e52 100644 --- a/configure.ac +++ b/configure.ac @@ -13,6 +13,7 @@ m4_define([mutter_plugin_api_version], [3]) AC_INIT([mutter], [mutter_version], [http://bugzilla.gnome.org/enter_bug.cgi?product=mutter]) +AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_SRCDIR(src/core/display.c) AC_CONFIG_HEADERS(config.h) From 333d78f33820ea431d1e66cee74209426a54ee0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Mon, 16 Sep 2013 22:55:31 +0200 Subject: [PATCH 887/889] Update .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 29da1c7d9..0bf82c3c9 100644 --- a/.gitignore +++ b/.gitignore @@ -56,6 +56,7 @@ org.gnome.mutter.wayland.gschema.xml testasyncgetprop testboxes testgradient +m4/* mutter-grayscale mutter-mag mutter-message From d7c4f57aaebcd1e6da7a7b343765c0c4b6b81b25 Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Tue, 20 Aug 2013 14:03:42 +0200 Subject: [PATCH 888/889] ui: Disable scaling support in Gtk+ We can't really support the Gtk+ automatic scaling, as to much code relies on the GdkWindow and XWindow sizes, etc to match. In order to keep working we just disable the scaling, meaning we will pick up the larger fonts, but nothing else. Its not ideal but it works for now. https://bugzilla.gnome.org/show_bug.cgi?id=706388 --- src/ui/ui.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/ui/ui.c b/src/ui/ui.c index 9dbb6a6fd..31225bfe3 100644 --- a/src/ui/ui.c +++ b/src/ui/ui.c @@ -53,6 +53,11 @@ meta_ui_init (void) if (!gtk_init_check (NULL, NULL)) meta_fatal ("Unable to open X display %s\n", XDisplayName (NULL)); + + /* We need to be able to fully trust that the window and monitor sizes + that Gdk reports corresponds to the X ones, so we disable the automatic + scale handling */ + gdk_x11_display_set_window_scale (gdk_display_get_default (), 1); } Display* From 954677dcbd6ef07e7d26db2f409ec3da5c4fe2c3 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 9 Apr 2014 12:40:13 -0700 Subject: [PATCH 889/889] window: Make sure to end the grab even if the last action was a snap This seems to be a cherry-pick failure while we were switching event handling around. This matches what the master branch does. --- src/core/window.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/window.c b/src/core/window.c index 60a69f304..5729d5778 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -7569,8 +7569,8 @@ meta_window_handle_mouse_grab_op_event (MetaWindow *window, */ update_tile_mode (window); } - meta_display_end_grab_op (window->display, event->any.time); } + meta_display_end_grab_op (window->display, event->any.time); } break;