Compare commits

...

18 Commits

Author SHA1 Message Date
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
32 changed files with 481 additions and 615 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

@@ -182,8 +182,6 @@ libmutter_wayland_la_SOURCES = \
ui/resizepopup.h \
ui/tabpopup.c \
ui/tabpopup.h \
ui/tile-preview.c \
ui/tile-preview.h \
ui/theme-parser.c \
ui/theme.c \
meta/theme.h \

View File

@@ -1695,3 +1695,31 @@ meta_compositor_monotonic_time_to_server_time (MetaDisplay *display,
else
return monotonic_time + compositor->server_time_offset;
}
void
meta_compositor_show_tile_preview (MetaCompositor *compositor,
MetaScreen *screen,
MetaWindow *window,
MetaRectangle *tile_rect,
int tile_monitor_number)
{
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
if (!info->plugin_mgr)
return;
meta_plugin_manager_show_tile_preview (info->plugin_mgr,
window, tile_rect, tile_monitor_number);
}
void
meta_compositor_hide_tile_preview (MetaCompositor *compositor,
MetaScreen *screen)
{
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
if (!info->plugin_mgr)
return;
meta_plugin_manager_hide_tile_preview (info->plugin_mgr);
}

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

@@ -22,8 +22,12 @@
struct _MetaSurfaceActorPrivate
{
MetaWaylandSurface *surface;
MetaShapedTexture *texture;
MetaWaylandBuffer *buffer;
cairo_region_t *input_region;
};
static void cullable_iface_init (MetaCullableInterface *iface);
@@ -39,9 +43,77 @@ meta_surface_actor_get_unobscured_bounds (MetaSurfaceActor *self,
return meta_shaped_texture_get_unobscured_bounds (priv->texture, unobscured_bounds);
}
static void
meta_surface_actor_pick (ClutterActor *actor,
const ClutterColor *color)
{
MetaSurfaceActor *self = META_SURFACE_ACTOR (actor);
MetaSurfaceActorPrivate *priv = self->priv;
if (!clutter_actor_should_pick_paint (actor))
return;
/* If there is no region then use the regular pick */
if (priv->input_region == NULL)
CLUTTER_ACTOR_CLASS (meta_surface_actor_parent_class)->pick (actor, color);
else
{
int n_rects;
float *rectangles;
int i;
CoglPipeline *pipeline;
CoglContext *ctx;
CoglFramebuffer *fb;
CoglColor cogl_color;
n_rects = cairo_region_num_rectangles (priv->input_region);
rectangles = g_alloca (sizeof (float) * 4 * n_rects);
for (i = 0; i < n_rects; i++)
{
cairo_rectangle_int_t rect;
int pos = i * 4;
cairo_region_get_rectangle (priv->input_region, i, &rect);
rectangles[pos + 0] = rect.x;
rectangles[pos + 1] = rect.y;
rectangles[pos + 2] = rect.x + rect.width;
rectangles[pos + 3] = rect.y + rect.height;
}
ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
fb = cogl_get_draw_framebuffer ();
cogl_color_init_from_4ub (&cogl_color, color->red, color->green, color->blue, color->alpha);
pipeline = cogl_pipeline_new (ctx);
cogl_pipeline_set_color (pipeline, &cogl_color);
cogl_framebuffer_draw_rectangles (fb, pipeline, rectangles, n_rects);
cogl_object_unref (pipeline);
}
}
static void
meta_surface_actor_dispose (GObject *object)
{
MetaSurfaceActor *self = META_SURFACE_ACTOR (object);
MetaSurfaceActorPrivate *priv = self->priv;
g_clear_pointer (&priv->input_region, cairo_region_destroy);
G_OBJECT_CLASS (meta_surface_actor_parent_class)->dispose (object);
}
static void
meta_surface_actor_class_init (MetaSurfaceActorClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
object_class->dispose = meta_surface_actor_dispose;
actor_class->pick = meta_surface_actor_pick;
g_type_class_add_private (klass, sizeof (MetaSurfaceActorPrivate));
}
@@ -172,7 +244,14 @@ meta_surface_actor_set_input_region (MetaSurfaceActor *self,
cairo_region_t *region)
{
MetaSurfaceActorPrivate *priv = self->priv;
meta_shaped_texture_set_input_shape_region (priv->texture, region);
if (priv->input_region)
cairo_region_destroy (priv->input_region);
if (region)
priv->input_region = cairo_region_reference (region);
else
priv->input_region = NULL;
}
void
@@ -183,8 +262,20 @@ meta_surface_actor_set_opaque_region (MetaSurfaceActor *self,
meta_shaped_texture_set_opaque_region (priv->texture, region);
}
MetaSurfaceActor *
meta_surface_actor_new (void)
MetaWaylandSurface *
meta_surface_actor_get_surface (MetaSurfaceActor *self)
{
return g_object_new (META_TYPE_SURFACE_ACTOR, NULL);
MetaSurfaceActorPrivate *priv = self->priv;
return priv->surface;
}
MetaSurfaceActor *
meta_surface_actor_new (MetaWaylandSurface *surface)
{
MetaSurfaceActor *self = g_object_new (META_TYPE_SURFACE_ACTOR, NULL);
MetaSurfaceActorPrivate *priv = self->priv;
priv->surface = surface;
return self;
}

View File

@@ -36,7 +36,7 @@ struct _MetaSurfaceActor
GType meta_surface_actor_get_type (void);
MetaSurfaceActor *meta_surface_actor_new (void);
MetaSurfaceActor *meta_surface_actor_new (MetaWaylandSurface *surface);
cairo_surface_t *meta_surface_actor_get_image (MetaSurfaceActor *self,
cairo_rectangle_int_t *clip);
@@ -63,6 +63,8 @@ void meta_surface_actor_set_input_region (MetaSurfaceActor *self,
void meta_surface_actor_set_opaque_region (MetaSurfaceActor *self,
cairo_region_t *region);
MetaWaylandSurface *meta_surface_actor_get_surface (MetaSurfaceActor *surface);
G_END_DECLS
#endif /* META_SURFACE_ACTOR_PRIVATE_H */

View File

@@ -353,7 +353,7 @@ meta_window_actor_constructed (GObject *object)
if (window->surface)
priv->surface = window->surface->surface_actor;
else
priv->surface = meta_surface_actor_new ();
priv->surface = meta_surface_actor_new (NULL);
g_object_ref_sink (priv->surface);
clutter_actor_add_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface));
@@ -1424,7 +1424,6 @@ meta_window_actor_hide (MetaWindowActor *self,
g_return_if_fail (priv->visible);
priv->visible = FALSE;
clutter_actor_set_reactive (CLUTTER_ACTOR (self), FALSE);
/* If a plugin is animating a workspace transition, we have to
* hold off on hiding the window, and do it after the workspace
@@ -1557,8 +1556,6 @@ meta_window_actor_new (MetaWindow *window)
clutter_actor_hide (CLUTTER_ACTOR (self));
clutter_actor_set_reactive (CLUTTER_ACTOR (self), TRUE);
/* Initial position in the stack is arbitrary; stacking will be synced
* before we first paint.
*/
@@ -1654,11 +1651,12 @@ meta_window_actor_cull_out (MetaCullable *cullable,
MetaWindowActor *self = META_WINDOW_ACTOR (cullable);
MetaWindowActorPrivate *priv = self->priv;
meta_cullable_cull_out_children (cullable, unobscured_region, clip_region);
/* Don't do any culling for the unredirected window */
if (priv->unredirected)
return;
meta_cullable_cull_out_children (cullable, unobscured_region, clip_region);
meta_window_actor_set_clip_region_beneath (self, clip_region);
}
@@ -1686,20 +1684,14 @@ cullable_iface_init (MetaCullableInterface *iface)
static void
check_needs_x11_pixmap (MetaWindowActor *self)
{
MetaWindowActorPrivate *priv = self->priv;
MetaScreen *screen = priv->screen;
MetaDisplay *display = meta_screen_get_display (screen);
Display *xdisplay = meta_display_get_xdisplay (display);
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
Window xwindow = meta_window_get_toplevel_xwindow (priv->window);
MetaWindowActorPrivate *priv = self->priv;
MetaDisplay *display = meta_screen_get_display (priv->screen);
Display *xdisplay = meta_display_get_xdisplay (display);
Window xwindow = meta_window_get_toplevel_xwindow (priv->window);
if (!priv->needs_pixmap)
return;
if (xwindow == meta_screen_get_xroot (screen) ||
xwindow == clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage)))
return;
if (priv->x11_size_changed)
{
meta_window_actor_detach_x11_pixmap (self);

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

@@ -1682,8 +1682,12 @@ get_window_for_event (MetaDisplay *display,
return display->grab_window;
source = clutter_event_get_source (event);
if (META_IS_WINDOW_ACTOR (source))
return meta_window_actor_get_meta_window (META_WINDOW_ACTOR (source));
if (META_IS_SURFACE_ACTOR (source))
{
MetaWaylandSurface *surface = meta_surface_actor_get_surface (META_SURFACE_ACTOR (source));
g_assert (surface != NULL);
return surface->window;
}
return NULL;
}
@@ -4980,7 +4984,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);

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

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

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

@@ -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 */
@@ -1320,6 +1317,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 */
@@ -3368,7 +3366,7 @@ meta_window_tile (MetaWindow *window)
directions = META_MAXIMIZE_VERTICAL;
meta_window_maximize_internal (window, directions, NULL);
meta_screen_tile_preview_update (window->screen, FALSE);
meta_screen_update_tile_preview (window->screen, FALSE);
if (window->display->compositor)
{
@@ -6359,6 +6357,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 +8105,7 @@ update_move (MetaWindow *window,
* trigger it unwittingly, e.g. when shaking loose the window or moving
* it to another monitor.
*/
meta_screen_tile_preview_update (window->screen,
meta_screen_update_tile_preview (window->screen,
window->tile_mode != META_TILE_NONE);
meta_window_get_client_root_coords (window, &old);
@@ -8947,6 +8953,20 @@ meta_window_get_work_area_all_monitors (MetaWindow *window,
window->desc, area->x, area->y, area->width, area->height);
}
int
meta_window_get_current_tile_monitor_number (MetaWindow *window)
{
int tile_monitor_number = window->tile_monitor_number;
if (tile_monitor_number < 0)
{
meta_warning ("%s called with an invalid monitor number; using 0 instead\n", G_STRFUNC);
tile_monitor_number = 0;
}
return tile_monitor_number;
}
void
meta_window_get_current_tile_area (MetaWindow *window,
MetaRectangle *tile_area)
@@ -8955,12 +8975,7 @@ meta_window_get_current_tile_area (MetaWindow *window,
g_return_if_fail (window->tile_mode != META_TILE_NONE);
tile_monitor_number = window->tile_monitor_number;
if (tile_monitor_number < 0)
{
meta_warning ("%s called with an invalid monitor number; using 0 instead\n", G_STRFUNC);
tile_monitor_number = 0;
}
tile_monitor_number = meta_window_get_current_tile_monitor_number (window);
meta_window_get_work_area_for_monitor (window, tile_monitor_number, tile_area);

View File

@@ -121,4 +121,12 @@ void meta_compositor_sync_screen_size (MetaCompositor *compositor,
void meta_compositor_flash_screen (MetaCompositor *compositor,
MetaScreen *screen);
void meta_compositor_show_tile_preview (MetaCompositor *compositor,
MetaScreen *screen,
MetaWindow *window,
MetaRectangle *tile_rect,
int tile_monitor_number);
void meta_compositor_hide_tile_preview (MetaCompositor *compositor,
MetaScreen *screen);
#endif /* META_COMPOSITOR_H */

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

@@ -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)
@@ -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,14 +55,6 @@
static void meta_wayland_pointer_end_popup_grab (MetaWaylandPointer *pointer);
static MetaWaylandSeat *
meta_wayland_pointer_get_seat (MetaWaylandPointer *pointer)
{
MetaWaylandSeat *seat = wl_container_of (pointer, seat, pointer);
return seat;
}
static void
release_focus (MetaWaylandPointer *pointer)
{
@@ -331,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

@@ -420,13 +420,8 @@ meta_wayland_seat_repick (MetaWaylandSeat *seat,
else
seat->current_stage = NULL;
if (META_IS_WINDOW_ACTOR (actor))
{
MetaWindow *window =
meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor));
surface = window->surface;
}
if (META_IS_SURFACE_ACTOR (actor))
surface = meta_surface_actor_get_surface (META_SURFACE_ACTOR (actor));
pointer->current = surface;
if (surface != pointer->focus_surface)

View File

@@ -273,8 +273,6 @@ ensure_buffer_texture (MetaWaylandBuffer *buffer)
}
buffer->texture = texture;
buffer->width = cogl_texture_get_width (texture);
buffer->height = cogl_texture_get_height (texture);
}
static void
@@ -324,11 +322,11 @@ toplevel_surface_commit (MetaWaylandSurface *surface,
/* We resize X based surfaces according to X events */
if (buffer != NULL && window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND)
{
int new_width;
int new_height;
int new_width, new_height;
new_width = cogl_texture_get_width (buffer->texture);
new_height = cogl_texture_get_height (buffer->texture);
new_width = surface->buffer->width;
new_height = surface->buffer->height;
if (new_width != window->rect.width ||
new_height != window->rect.height ||
pending->dx != 0 ||
@@ -596,11 +594,14 @@ meta_wayland_surface_window_unmanaged (MetaWaylandSurface *surface)
static void
destroy_window (MetaWaylandSurface *surface)
{
MetaDisplay *display = meta_get_display ();
guint32 timestamp = meta_display_get_current_time_roundtrip (display);
if (surface->window)
{
MetaDisplay *display = meta_get_display ();
guint32 timestamp = meta_display_get_current_time_roundtrip (display);
meta_window_unmanage (surface->window, timestamp);
}
g_assert (surface->window != NULL);
meta_window_unmanage (surface->window, timestamp);
g_assert (surface->window == NULL);
}
@@ -610,18 +611,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,7 +645,8 @@ meta_wayland_surface_create (MetaWaylandCompositor *compositor,
wl_resource_set_implementation (surface->resource, &meta_wayland_surface_interface, surface, wl_surface_destructor);
surface->buffer_destroy_listener.notify = surface_handle_buffer_destroy;
surface->surface_actor = g_object_ref_sink (meta_surface_actor_new ());
surface->surface_actor = g_object_ref_sink (meta_surface_actor_new (surface));
clutter_actor_set_reactive (CLUTTER_ACTOR (surface->surface_actor), TRUE);
double_buffered_state_init (&surface->pending);
@@ -1015,13 +1016,10 @@ xdg_shell_get_xdg_popup (struct wl_client *client,
MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource);
MetaWaylandSurface *parent_surf = wl_resource_get_user_data (parent_resource);
MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource);
MetaRectangle parent_rect;
if (parent_surf == NULL || parent_surf->window == NULL)
return;
meta_window_get_rect (parent_surf->window, &parent_rect);
if (!create_surface_extension (&surface->xdg_popup, client, surface_resource, resource, id,
META_XDG_POPUP_VERSION,
&xdg_popup_interface,
@@ -1035,8 +1033,8 @@ xdg_shell_get_xdg_popup (struct wl_client *client,
}
surface->window = meta_window_wayland_new (meta_get_display (), surface);
surface->window->rect.x = parent_rect.x + x;
surface->window->rect.y = parent_rect.y + y;
surface->window->rect.x = parent_surf->window->rect.x + x;
surface->window->rect.y = parent_surf->window->rect.y + y;
surface->window->showing_for_first_time = FALSE;
surface->window->placed = TRUE;
meta_window_set_transient_for (surface->window, parent_surf->window);
@@ -1511,17 +1509,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;
};
@@ -125,8 +124,8 @@ void meta_wayland_surface_configure_notify (MetaWaylandSurface *s
int width,
int height);
void meta_wayland_surface_focused_set (MetaWaylandSurface *surface);
void meta_wayland_surface_focused_unset (MetaWaylandSurface *surface);
void meta_wayland_surface_activated (MetaWaylandSurface *surface);
void meta_wayland_surface_deactivated (MetaWaylandSurface *surface);
void meta_wayland_surface_ping (MetaWaylandSurface *surface,
guint32 serial);