Compare commits

...

38 Commits

Author SHA1 Message Date
Giovanni Campagna
a3a2109c0c Fix input and bounding shapes
1) We need to select for shape events
2) For decorated windows, we don't want to apply any input
   shape, because the frame is always rectangular and eats
   all the input
3) For undecorated windows, the "has input shape" check is
   wrong if the window has a bounding shape but not an input
   shape
2014-02-25 01:16:13 +01:00
Giovanni Campagna
bdbeafc222 MetaWindowActor: replace MetaSurfaceActorEmpty with no MSA at all
Have MetaWindowActor cope with having a NULL surface actor, and
drop the Empty class.
2014-02-24 22:40:43 +01:00
Giovanni Campagna
89ca36818a 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.
2014-02-24 22:00:12 +01:00
Jasper St. Pierre
fe1a58b459 compositor: Add a new MetaSurfaceActorEmpty
This will be used in the interim before MetaSurfaceActorWayland
we set_window_id is called. This is somewhat expensive and hacky,
but all other attempts to prevent either MetaWindowActor or
MetaWindow from created prematurely, e.g. before we have a
set_window_id have failed.
2014-02-24 14:46:19 -05:00
Jasper St. Pierre
f0cd9b0687 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.
2014-02-24 14:46:19 -05:00
Jasper St. Pierre
1783bf20ec Revert "window: Delay the showing of XWayland clients until set_window_id"
This reverts commit 59c8b949ad.
2014-02-24 14:46:19 -05:00
Jasper St. Pierre
9b24ae2033 Revert "compositor: Delay meta_compositor_add_window until the first show"
This reverts commit 4efe4483fb.
2014-02-24 14:46:18 -05:00
Jasper St. Pierre
0be4622e14 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.
2014-02-24 09:46:22 -05:00
Carlos Garnacho
bcd5446cdc 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
2014-02-24 11:50:08 +01:00
Jasper St. Pierre
04b5232960 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.
2014-02-23 12:34:53 -05:00
Jasper St. Pierre
f860df4b2d Revert "compositor: fix focusing the stage window"
This reverts commit 876f81db12.

This doesn't quite work properly, and is overcomplicated.
2014-02-23 12:34:52 -05:00
Jasper St. Pierre
ff8c4b1bcf 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...
2014-02-23 10:00:31 -05:00
Jasper St. Pierre
337c69e223 pointer/keyboard: Unset focus_resource when the surface is destroyed
focus_resource is supposed to be set only if focus_surface is
as well.
2014-02-22 18:15:53 -05:00
Adel Gadllah
14841475b5 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."
2014-02-21 20:39:25 +01:00
Jasper St. Pierre
7283fb320f 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 <Primary><Alt>F1 path. This is
ridiculous, but key, so is the entirety of XKB.

This took an embarassingly long time to figure out and debug.
2014-02-21 13:50:40 -05:00
Jasper St. Pierre
020cfa7283 surface-actor-x11: Recreate damage when the toplevel X window changes 2014-02-20 14:50:48 -05:00
Jasper St. Pierre
83aca0b53d 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
2014-02-20 14:44:31 -05:00
Jasper St. Pierre
0b055fae2e 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
2014-02-20 11:51:52 -05:00
Jasper St. Pierre
bc79259398 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
2014-02-20 11:35:01 -05:00
Jasper St. Pierre
7ebf5aa69a 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.
2014-02-20 11:35:01 -05:00
Florian Müllner
7499621ecb Bump version to 3.11.90
Update NEWS.
2014-02-19 21:58:42 +01:00
Stefano Facchini
4de3f7ca29 Make tile preview a compositor plugin effect
https://bugzilla.gnome.org/show_bug.cgi?id=665758
2014-02-19 21:55:35 +01:00
Marek Chalupa
17462c21e8 pointer/keyboard: fix setting focus
Set focus to NULL after using the variable
2014-02-19 10:24:36 -05:00
Jasper St. Pierre
c964ef4e01 window-actor: Fix build
I'm bad.
2014-02-19 01:11:42 -05:00
Jasper St. Pierre
0dccc440b6 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.
2014-02-18 23:36:46 -05:00
Jasper St. Pierre
48f7232492 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.
2014-02-18 23:21:06 -05:00
Jasper St. Pierre
ff5867e4d3 pointer: Make the code here a bit clearer 2014-02-18 23:21:06 -05:00
Jasper St. Pierre
a5d950f453 pointer/keyboard: Fix focus setting once again
Yet another large-scale restructuring... this is some messy code.
2014-02-18 23:21:06 -05:00
Jasper St. Pierre
7615d17293 wayland: Tie activate / deactivate to appears-focused
... rather than actual focus. This makes things behave better.
2014-02-18 23:21:06 -05:00
Jasper St. Pierre
374e30043b wayland: Remove width / height from MetaWaylandBuffer
They're in the texture.
2014-02-18 22:43:24 -05:00
Jasper St. Pierre
f771bb88d6 Revert "wayland: Explicitly destroy the surface actor"
This reverts commit 283a81eac0.

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.
2014-02-18 22:23:08 -05:00
Jasper St. Pierre
7ef8d21e48 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.
2014-02-18 22:21:33 -05:00
Jasper St. Pierre
c251eb8ec0 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.
2014-02-18 21:29:50 -05:00
Jasper St. Pierre
1e6b3faa83 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.
2014-02-18 21:29:23 -05:00
Jasper St. Pierre
e62fe956fd 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.
2014-02-18 20:30:52 -05:00
Jasper St. Pierre
24c5290d7f main: Kill a runtime warning
g_setenv doesn't take NULL for a value.
2014-02-18 20:30:36 -05:00
Jasper St. Pierre
00c8d3c897 xdg-shell: Update to latest renames for focused_set / focused_unset 2014-02-18 19:02:17 -05:00
Jasper St. Pierre
cc13f8f65e 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.
2014-02-18 19:01:50 -05:00
43 changed files with 1764 additions and 1400 deletions

11
NEWS
View File

@@ -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]

View File

@@ -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])

View File

@@ -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 @@
</description>
</request>
<event name="focused_set">
<description summary="surface was focused">
The focused_set event is sent when this surface has been
activated. Window decorations should be updated accordingly.
<event name="activated">
<description summary="surface was activated">
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.
</description>
</event>
<event name="focused_unset">
<description summary="surface was unfocused">
The focused_unset event is sent when this surface has been
deactivated, because another surface has been activated. Window
decorations should be updated accordingly.
<event name="deactivated">
<description summary="surface was deactivated">
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.
</description>
</event>

View File

@@ -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 \
@@ -182,8 +186,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 \

View File

@@ -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,
@@ -316,39 +329,36 @@ 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;
if (meta_is_wayland_compositor ())
return TRUE;
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
@@ -822,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
@@ -937,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
@@ -1695,3 +1710,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);
}

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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

View File

@@ -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 <jstpierre@mecheye.net>
*/
#include "config.h"
#include "meta-surface-actor-wayland.h"
#include <cogl/cogl-wayland-server.h>
#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;
}

View File

@@ -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 <jstpierre@mecheye.net>
*/
#ifndef __META_SURFACE_ACTOR_WAYLAND_H__
#define __META_SURFACE_ACTOR_WAYLAND_H__
#include <glib-object.h>
#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__ */

View File

@@ -0,0 +1,475 @@
/* -*- 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 <otaylor@redhat.com>
* Jasper St. Pierre <jstpierre@mecheye.net>
*/
#include "config.h"
#include "meta-surface-actor-x11.h"
#include <X11/extensions/Xcomposite.h>
#include <X11/extensions/Xrender.h>
#include <cogl/cogl-texture-pixmap-x11.h>
#include <meta/errors.h>
#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;
}
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);
g_assert (!meta_is_wayland_compositor ());
priv->window = window;
priv->display = display;
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;
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;
}

View File

@@ -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 <otaylor@redhat.com>
* Jasper St. Pierre <jstpierre@mecheye.net>
*/
#ifndef __META_SURFACE_ACTOR_X11_H__
#define __META_SURFACE_ACTOR_X11_H__
#include <glib-object.h>
#include "meta-surface-actor.h"
#include <X11/extensions/Xdamage.h>
#include <meta/display.h>
#include <meta/window.h>
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__ */

View File

@@ -10,26 +10,38 @@
*/
#include <config.h>
#include <clutter/clutter.h>
#include <cogl/cogl-wayland-server.h>
#include <cogl/cogl-texture-pixmap-x11.h>
#include <meta/meta-shaped-texture.h>
#include "meta-surface-actor.h"
#include <clutter/clutter.h>
#include <meta/meta-shaped-texture.h>
#include "meta-wayland-private.h"
#include "meta-cullable.h"
#include "meta-shaped-texture-private.h"
struct _MetaSurfaceActorPrivate
{
MetaShapedTexture *texture;
MetaWaylandBuffer *buffer;
cairo_region_t *input_region;
/* Freeze/thaw accounting */
guint needs_damage_all : 1;
guint frozen : 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,
@@ -39,9 +51,84 @@ 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;
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));
}
@@ -92,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
@@ -146,33 +196,19 @@ 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)
{
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 +219,96 @@ meta_surface_actor_set_opaque_region (MetaSurfaceActor *self,
meta_shaped_texture_set_opaque_region (priv->texture, region);
}
MetaSurfaceActor *
meta_surface_actor_new (void)
static gboolean
is_frozen (MetaSurfaceActor *self)
{
return g_object_new (META_TYPE_SURFACE_ACTOR, NULL);
MetaSurfaceActorPrivate *priv = self->priv;
return priv->frozen;
}
void
meta_surface_actor_process_damage (MetaSurfaceActor *self,
int x, int y, int width, int height)
{
MetaSurfaceActorPrivate *priv = self->priv;
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;
}
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_set_frozen (MetaSurfaceActor *self,
gboolean frozen)
{
MetaSurfaceActorPrivate *priv = self->priv;
priv->frozen = frozen;
if (!frozen && priv->needs_damage_all)
{
/* 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. */
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_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);
}

View File

@@ -6,7 +6,6 @@
#include <config.h>
#include <meta/meta-shaped-texture.h>
#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,33 +46,37 @@ 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);
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);
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_set_frozen (MetaSurfaceActor *actor,
gboolean frozen);
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
#endif /* META_SURFACE_ACTOR_PRIVATE_H */

View File

@@ -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 */

File diff suppressed because it is too large Load Diff

View File

@@ -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);

View File

@@ -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)
{

View File

@@ -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

View File

@@ -73,6 +73,7 @@
#include <unistd.h>
#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,8 +1683,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_WAYLAND (source))
{
MetaWaylandSurface *surface = meta_surface_actor_wayland_get_surface (META_SURFACE_ACTOR_WAYLAND (source));
g_assert (surface != NULL);
return surface->window;
}
return NULL;
}
@@ -1741,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;
@@ -1754,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;
@@ -1777,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;
@@ -1804,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);
@@ -1847,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;
@@ -1885,7 +1885,6 @@ request_xserver_input_focus_change (MetaDisplay *display,
meta_display_ungrab (display);
update_focus_window (display,
type,
meta_window,
xwindow,
serial,
@@ -1907,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
*/
@@ -1924,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",
@@ -2028,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,
@@ -3277,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,
@@ -4980,7 +4962,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);
@@ -5946,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);
@@ -5970,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);
@@ -5991,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);

View File

@@ -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;

View File

@@ -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

View File

@@ -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);
}
/**

View File

@@ -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);

View File

@@ -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*

View File

@@ -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;

View File

@@ -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;
@@ -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);

View File

@@ -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;
}

View File

@@ -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);
@@ -1453,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);
@@ -1485,14 +1511,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;

View File

@@ -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;
@@ -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 */
@@ -1220,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);
@@ -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 */
@@ -2771,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);
}
}
@@ -3368,7 +3369,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)
{
@@ -6359,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);
}
}
/**
@@ -8099,7 +8108,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);
@@ -8947,6 +8956,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)
@@ -8955,12 +8978,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);

View File

@@ -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,
@@ -121,4 +123,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 */

View File

@@ -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:

View File

@@ -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);

View File

@@ -2,31 +2,31 @@
<schema id="org.gnome.mutter.wayland.keybindings" path="/org/gnome/mutter/wayland/keybindings/"
gettext-domain="@GETTEXT_DOMAIN@">
<key name="switch-to-session-1" type="as">
<default><![CDATA[['<Primary><Alt>F1']]]></default>
<default><![CDATA[['<Primary><Alt>F1', 'XF86Switch_VT_1']]]></default>
<_summary>Switch to VT 1</_summary>
</key>
<key name="switch-to-session-2" type="as">
<default><![CDATA[['<Primary><Alt>F2']]]></default>
<default><![CDATA[['<Primary><Alt>F2', 'XF86Switch_VT_2']]]></default>
<_summary>Switch to VT 2</_summary>
</key>
<key name="switch-to-session-3" type="as">
<default><![CDATA[['<Primary><Alt>F3']]]></default>
<default><![CDATA[['<Primary><Alt>F3', 'XF86Switch_VT_3']]]></default>
<_summary>Switch to VT 3</_summary>
</key>
<key name="switch-to-session-4" type="as">
<default><![CDATA[['<Primary><Alt>F4']]]></default>
<default><![CDATA[['<Primary><Alt>F4', 'XF86Switch_VT_4']]]></default>
<_summary>Switch to VT 4</_summary>
</key>
<key name="switch-to-session-5" type="as">
<default><![CDATA[['<Primary><Alt>F5']]]></default>
<default><![CDATA[['<Primary><Alt>F5', 'XF86Switch_VT_5']]]></default>
<_summary>Switch to VT 5</_summary>
</key>
<key name="switch-to-session-6" type="as">
<default><![CDATA[['<Primary><Alt>F6']]]></default>
<default><![CDATA[['<Primary><Alt>F6', 'XF86Switch_VT_6']]]></default>
<_summary>Switch to VT 6</_summary>
</key>
<key name="switch-to-session-7" type="as">
<default><![CDATA[['<Primary><Alt>F7']]]></default>
<default><![CDATA[['<Primary><Alt>F7', 'XF86Switch_VT_7']]]></default>
<_summary>Switch to VT 7</_summary>
</key>
</schema>

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include <gtk/gtk.h>
#include <cairo.h>
#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);
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#ifndef META_TILE_PREVIEW_H
#define META_TILE_PREVIEW_H
#include <meta/boxes.h>
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 */

View File

@@ -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

View File

@@ -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)
@@ -225,28 +217,28 @@ 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;
if (keyboard->focus_resource)
{
wl_list_remove (&keyboard->focus_resource_listener.link);
keyboard->focus_resource = 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
@@ -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);
}
}
@@ -527,72 +502,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)
if (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_surface->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);
}
meta_wayland_surface_focused_unset (keyboard->focus_surface);
wl_list_remove (&keyboard->focus_resource_listener.link);
keyboard->focus_resource = NULL;
}
wl_list_remove (&keyboard->focus_resource_listener.link);
wl_list_remove (&keyboard->focus_surface_listener.link);
keyboard->focus_resource = NULL;
keyboard->focus_surface = 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);
}
meta_wayland_surface_focused_set (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;
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;
}
}
}

View File

@@ -55,36 +55,28 @@
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)
{
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;
if (pointer->focus_resource)
{
wl_list_remove (&pointer->focus_resource_listener.link);
pointer->focus_resource = 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
@@ -310,7 +302,7 @@ meta_wayland_pointer_init (MetaWaylandPointer *pointer)
void
meta_wayland_pointer_release (MetaWaylandPointer *pointer)
{
release_focus (pointer);
/* Do nothing. */
}
static struct wl_resource *
@@ -331,70 +323,57 @@ void
meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
MetaWaylandSurface *surface)
{
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)
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_surface->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_resource = NULL;
}
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);
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);
uint32_t serial = wl_display_next_serial (display);
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_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;
}
}
}

View File

@@ -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,13 +421,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_WAYLAND (actor))
surface = meta_surface_actor_wayland_get_surface (META_SURFACE_ACTOR_WAYLAND (actor));
pointer->current = surface;
if (surface != pointer->focus_surface)

View File

@@ -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);
}
}
@@ -273,8 +276,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
@@ -297,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);
@@ -324,11 +325,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 ||
@@ -573,34 +574,30 @@ 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;
}
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,18 +607,17 @@ 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);
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)
@@ -645,10 +641,9 @@ 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_wayland_new (surface));
double_buffered_state_init (&surface->pending);
return surface;
}
@@ -976,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);
}
@@ -1015,13 +1011,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,
@@ -1034,9 +1027,10 @@ 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_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);
@@ -1248,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)
{
@@ -1511,17 +1513,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

View File

@@ -38,7 +38,6 @@ struct _MetaWaylandBuffer
struct wl_listener destroy_listener;
CoglTexture *texture;
int32_t width, height;
uint32_t ref_count;
};
@@ -119,14 +118,15 @@ 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,
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);

View File

@@ -47,10 +47,12 @@ xserver_set_window_id (struct wl_client *client,
if (!window)
return;
meta_wayland_surface_make_toplevel (surface);
surface->window = window;
window->surface = surface;
meta_window_set_surface_mapped (window, TRUE);
meta_compositor_window_surface_changed (display->compositor, window);
}
static const struct xserver_interface xserver_implementation = {