Compare commits
76 Commits
wip/subsur
...
3.11.5-way
Author | SHA1 | Date | |
---|---|---|---|
![]() |
b8e096db82 | ||
![]() |
3e98ffaf99 | ||
![]() |
0a9754f305 | ||
![]() |
965a784c8a | ||
![]() |
2db9f55669 | ||
![]() |
3e73babaf7 | ||
![]() |
66c4555dc7 | ||
![]() |
183ad75603 | ||
![]() |
66fc32ee14 | ||
![]() |
d6396cf2c4 | ||
![]() |
c9b7104117 | ||
![]() |
6bf1a66b7c | ||
![]() |
7e7b671b8e | ||
![]() |
e04a55d1a2 | ||
![]() |
8905bd2280 | ||
![]() |
b09e1399c0 | ||
![]() |
59c8b949ad | ||
![]() |
6dbb3fddce | ||
![]() |
f166240225 | ||
![]() |
91b789c707 | ||
![]() |
14db280fab | ||
![]() |
f7097e6f66 | ||
![]() |
ff89f1e271 | ||
![]() |
6a8a4bfdcd | ||
![]() |
cd35982d4e | ||
![]() |
2f6f0f252c | ||
![]() |
13651949ed | ||
![]() |
fdeb72224c | ||
![]() |
92e36e7076 | ||
![]() |
d74796ee80 | ||
![]() |
3e35cac67a | ||
![]() |
1f7a6bf845 | ||
![]() |
365442c1ff | ||
![]() |
c8d185fc74 | ||
![]() |
9567fa9c6a | ||
![]() |
7a8de0c0af | ||
![]() |
10fead9ba1 | ||
![]() |
d5d5c2167a | ||
![]() |
b9755ea725 | ||
![]() |
39fee9f5a2 | ||
![]() |
d6282716b2 | ||
![]() |
60d9bee3bf | ||
![]() |
a09fa3b0e4 | ||
![]() |
9edff6f250 | ||
![]() |
7d3012fd67 | ||
![]() |
225e20a898 | ||
![]() |
1a62ac9276 | ||
![]() |
45cb151443 | ||
![]() |
55b18f9671 | ||
![]() |
4f4b1bfc37 | ||
![]() |
9348c9bd4b | ||
![]() |
16de7f66fb | ||
![]() |
799c27484d | ||
![]() |
c3b0faec82 | ||
![]() |
9c876722a0 | ||
![]() |
96fc93d744 | ||
![]() |
20545941fa | ||
![]() |
59f79e8294 | ||
![]() |
ac32b9ef95 | ||
![]() |
ba484be754 | ||
![]() |
a318198ab4 | ||
![]() |
e6391c2896 | ||
![]() |
7ea537fad7 | ||
![]() |
03146c2967 | ||
![]() |
0a81314337 | ||
![]() |
fa7a5782c6 | ||
![]() |
e3b64912b6 | ||
![]() |
a0fe392665 | ||
![]() |
0e5f365d55 | ||
![]() |
bfc906cbc4 | ||
![]() |
8e6f8087e8 | ||
![]() |
56207ddb6a | ||
![]() |
8cb9cfb7b8 | ||
![]() |
be698b597b | ||
![]() |
1d61a0f9b5 | ||
![]() |
788bd59857 |
25
NEWS
25
NEWS
@@ -1,3 +1,28 @@
|
||||
3.11.5
|
||||
======
|
||||
* Fix CSD titlebars being placed off-screen [Jasper; #719772]
|
||||
* Add support for subsurfaces [Jonas; #705502]
|
||||
* Expose MetaWindow:skip-taskbar property [Florian; #723307]
|
||||
* Fix legacy tray icons showing up blank [Adel; #721596]
|
||||
* Fix configuration of cloned monitors [Adel; #710610]
|
||||
* Misc bug fixes and cleanups [Jasper, Adel, Marek, Jonas; #720631, #723468,
|
||||
#720818, #723563, #723564]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Marek Ch, Adel Gadllah, Florian Müllner, Jasper St. Pierre
|
||||
|
||||
3.11.4
|
||||
======
|
||||
* Don't leave focus on windows that are being unmanaged [Owen; #711618]
|
||||
* Reduce server grabs [Daniel Drake; #721345, #721709]
|
||||
* Improve heuristic to determine display output name [Cosimo Cecchi; #721674]
|
||||
* Atomically unmaximize both directions [Jasper; #722108]
|
||||
* Misc bug fixes [Debarshi, Andika, Florian; #721517, #721674, #722347]
|
||||
|
||||
Contributors:
|
||||
Cosimo Cecchi, Daniel Drake, Florian Müllner, Debarshi Ray, Jasper St. Pierre,
|
||||
Andika Triwidada, Owen W. Taylor
|
||||
|
||||
3.11.3
|
||||
======
|
||||
* Fix focus issues with external OSKs[Jasper; #715030]
|
||||
|
@@ -3,7 +3,7 @@ AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
m4_define([mutter_major_version], [3])
|
||||
m4_define([mutter_minor_version], [11])
|
||||
m4_define([mutter_micro_version], [3])
|
||||
m4_define([mutter_micro_version], [5])
|
||||
|
||||
m4_define([mutter_version],
|
||||
[mutter_major_version.mutter_minor_version.mutter_micro_version])
|
||||
|
@@ -163,6 +163,8 @@ libmutter_wayland_la_SOURCES = \
|
||||
core/util-private.h \
|
||||
core/window-props.c \
|
||||
core/window-props.h \
|
||||
core/window-x11.c \
|
||||
core/window-x11.h \
|
||||
core/window.c \
|
||||
core/window-private.h \
|
||||
meta/window.h \
|
||||
|
@@ -46,11 +46,8 @@ struct _MetaCompScreen
|
||||
CoglFrameClosure *frame_closure;
|
||||
|
||||
/* Used for unredirecting fullscreen windows */
|
||||
guint disable_unredirect_count;
|
||||
MetaWindowActor *unredirected_window;
|
||||
|
||||
/* Before we create the output window */
|
||||
XserverRegion pending_input_region;
|
||||
guint disable_unredirect_count;
|
||||
MetaWindow *unredirected_window;
|
||||
|
||||
gint switch_workspace_in_progress;
|
||||
|
||||
|
@@ -283,25 +283,6 @@ meta_get_window_actors (MetaScreen *screen)
|
||||
return info->windows;
|
||||
}
|
||||
|
||||
static void
|
||||
do_set_stage_input_region (MetaScreen *screen,
|
||||
XserverRegion region)
|
||||
{
|
||||
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
|
||||
MetaDisplay *display = meta_screen_get_display (screen);
|
||||
Display *xdpy = meta_display_get_xdisplay (display);
|
||||
Window xstage = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage));
|
||||
|
||||
XFixesSetWindowShapeRegion (xdpy, xstage, ShapeInput, 0, 0, region);
|
||||
|
||||
/* It's generally a good heuristic that when a crossing event is generated because
|
||||
* we reshape the overlay, we don't want it to affect focus-follows-mouse focus -
|
||||
* it's not the user doing something, it's the environment changing under the user.
|
||||
*/
|
||||
meta_display_add_ignored_crossing_serial (display, XNextRequest (xdpy));
|
||||
XFixesSetWindowShapeRegion (xdpy, info->output, ShapeInput, 0, 0, region);
|
||||
}
|
||||
|
||||
void
|
||||
meta_set_stage_input_region (MetaScreen *screen,
|
||||
XserverRegion region)
|
||||
@@ -313,29 +294,19 @@ meta_set_stage_input_region (MetaScreen *screen,
|
||||
*/
|
||||
if (!meta_is_wayland_compositor ())
|
||||
{
|
||||
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
|
||||
MetaDisplay *display = meta_screen_get_display (screen);
|
||||
Display *xdpy = meta_display_get_xdisplay (display);
|
||||
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
|
||||
MetaDisplay *display = meta_screen_get_display (screen);
|
||||
Display *xdpy = meta_display_get_xdisplay (display);
|
||||
Window xstage = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage));
|
||||
|
||||
if (info->stage && info->output)
|
||||
{
|
||||
do_set_stage_input_region (screen, region);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Reset info->pending_input_region if one existed before and set the new
|
||||
* one to use it later. */
|
||||
if (info->pending_input_region)
|
||||
{
|
||||
XFixesDestroyRegion (xdpy, info->pending_input_region);
|
||||
info->pending_input_region = None;
|
||||
}
|
||||
if (region != None)
|
||||
{
|
||||
info->pending_input_region = XFixesCreateRegion (xdpy, NULL, 0);
|
||||
XFixesCopyRegion (xdpy, info->pending_input_region, region);
|
||||
}
|
||||
}
|
||||
XFixesSetWindowShapeRegion (xdpy, xstage, ShapeInput, 0, 0, region);
|
||||
|
||||
/* It's generally a good heuristic that when a crossing event is generated because
|
||||
* we reshape the overlay, we don't want it to affect focus-follows-mouse focus -
|
||||
* it's not the user doing something, it's the environment changing under the user.
|
||||
*/
|
||||
meta_display_add_ignored_crossing_serial (display, XNextRequest (xdpy));
|
||||
XFixesSetWindowShapeRegion (xdpy, info->output, ShapeInput, 0, 0, region);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -677,21 +648,6 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
|
||||
return;
|
||||
|
||||
info = g_new0 (MetaCompScreen, 1);
|
||||
/*
|
||||
* We use an empty input region for Clutter as a default because that allows
|
||||
* the user to interact with all the windows displayed on the screen.
|
||||
* We have to initialize info->pending_input_region to an empty region explicitly,
|
||||
* because None value is used to mean that the whole screen is an input region.
|
||||
*/
|
||||
if (!meta_is_wayland_compositor ())
|
||||
info->pending_input_region = XFixesCreateRegion (xdisplay, NULL, 0);
|
||||
else
|
||||
{
|
||||
/* Stage input region trickery isn't needed when we're running as a
|
||||
* wayland compositor. */
|
||||
info->pending_input_region = None;
|
||||
}
|
||||
|
||||
info->screen = screen;
|
||||
|
||||
meta_screen_set_compositor_data (screen, info);
|
||||
@@ -777,6 +733,8 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
|
||||
info->output = get_output_window (screen);
|
||||
XReparentWindow (xdisplay, xwin, info->output, 0, 0);
|
||||
|
||||
meta_empty_stage_input_region (screen);
|
||||
|
||||
/* Make sure there isn't any left-over output shape on the
|
||||
* overlay window by setting the whole screen to be an
|
||||
* output region.
|
||||
@@ -787,13 +745,6 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
|
||||
*/
|
||||
XFixesSetWindowShapeRegion (xdisplay, info->output, ShapeBounding, 0, 0, None);
|
||||
|
||||
do_set_stage_input_region (screen, info->pending_input_region);
|
||||
if (info->pending_input_region != None)
|
||||
{
|
||||
XFixesDestroyRegion (xdisplay, info->pending_input_region);
|
||||
info->pending_input_region = None;
|
||||
}
|
||||
|
||||
/* Map overlay window before redirecting windows offscreen so we catch their
|
||||
* contents until we show the stage.
|
||||
*/
|
||||
@@ -863,6 +814,30 @@ meta_shape_cow_for_window (MetaScreen *screen,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_unredirected_window (MetaCompScreen *info,
|
||||
MetaWindow *window)
|
||||
{
|
||||
if (info->unredirected_window == window)
|
||||
return;
|
||||
|
||||
if (info->unredirected_window != NULL)
|
||||
{
|
||||
MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (info->unredirected_window));
|
||||
meta_window_actor_set_unredirected (window_actor, FALSE);
|
||||
}
|
||||
|
||||
info->unredirected_window = window;
|
||||
|
||||
if (info->unredirected_window != NULL)
|
||||
{
|
||||
MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (info->unredirected_window));
|
||||
meta_window_actor_set_unredirected (window_actor, TRUE);
|
||||
}
|
||||
|
||||
meta_shape_cow_for_window (info->screen, info->unredirected_window);
|
||||
}
|
||||
|
||||
void
|
||||
meta_compositor_add_window (MetaCompositor *compositor,
|
||||
MetaWindow *window)
|
||||
@@ -891,19 +866,11 @@ meta_compositor_remove_window (MetaCompositor *compositor,
|
||||
if (!window_actor)
|
||||
return;
|
||||
|
||||
if (!meta_is_wayland_compositor ())
|
||||
{
|
||||
screen = meta_window_get_screen (window);
|
||||
info = meta_screen_get_compositor_data (screen);
|
||||
screen = meta_window_get_screen (window);
|
||||
info = meta_screen_get_compositor_data (screen);
|
||||
|
||||
if (window_actor == info->unredirected_window)
|
||||
{
|
||||
meta_window_actor_set_redirected (window_actor, TRUE);
|
||||
meta_shape_cow_for_window (meta_window_get_screen (meta_window_actor_get_meta_window (info->unredirected_window)),
|
||||
NULL);
|
||||
info->unredirected_window = NULL;
|
||||
}
|
||||
}
|
||||
if (info->unredirected_window == window)
|
||||
set_unredirected_window (info, NULL);
|
||||
|
||||
meta_window_actor_destroy (window_actor);
|
||||
}
|
||||
@@ -1533,7 +1500,6 @@ pre_paint_windows (MetaCompScreen *info)
|
||||
{
|
||||
GList *l;
|
||||
MetaWindowActor *top_window;
|
||||
MetaWindowActor *expected_unredirected_window = NULL;
|
||||
|
||||
if (info->onscreen == NULL)
|
||||
{
|
||||
@@ -1547,33 +1513,13 @@ pre_paint_windows (MetaCompScreen *info)
|
||||
if (info->windows == NULL)
|
||||
return;
|
||||
|
||||
if (!meta_is_wayland_compositor ())
|
||||
{
|
||||
top_window = g_list_last (info->windows)->data;
|
||||
top_window = g_list_last (info->windows)->data;
|
||||
|
||||
if (meta_window_actor_should_unredirect (top_window) &&
|
||||
info->disable_unredirect_count == 0)
|
||||
expected_unredirected_window = top_window;
|
||||
|
||||
if (info->unredirected_window != expected_unredirected_window)
|
||||
{
|
||||
if (info->unredirected_window != NULL)
|
||||
{
|
||||
meta_window_actor_set_redirected (info->unredirected_window, TRUE);
|
||||
meta_shape_cow_for_window (meta_window_get_screen (meta_window_actor_get_meta_window (info->unredirected_window)),
|
||||
NULL);
|
||||
}
|
||||
|
||||
if (expected_unredirected_window != NULL)
|
||||
{
|
||||
meta_shape_cow_for_window (meta_window_get_screen (meta_window_actor_get_meta_window (top_window)),
|
||||
meta_window_actor_get_meta_window (top_window));
|
||||
meta_window_actor_set_redirected (top_window, FALSE);
|
||||
}
|
||||
|
||||
info->unredirected_window = expected_unredirected_window;
|
||||
}
|
||||
}
|
||||
if (meta_window_actor_should_unredirect (top_window) &&
|
||||
info->disable_unredirect_count == 0)
|
||||
set_unredirected_window (info, meta_window_actor_get_meta_window (top_window));
|
||||
else
|
||||
set_unredirected_window (info, NULL);
|
||||
|
||||
for (l = info->windows; l; l = l->next)
|
||||
meta_window_actor_pre_paint (l->data);
|
||||
|
@@ -605,8 +605,8 @@ get_clip (MetaShapedTexture *stex,
|
||||
ClutterActor *self = CLUTTER_ACTOR (stex);
|
||||
MetaShapedTexturePrivate *priv;
|
||||
ClutterActorBox allocation;
|
||||
float scale_x;
|
||||
float scale_y;
|
||||
double scale_x;
|
||||
double scale_y;
|
||||
|
||||
/* NB: clutter_actor_queue_redraw_with_clip expects a box in the actor's
|
||||
* coordinate space so we need to convert from surface coordinates to
|
||||
|
@@ -39,13 +39,13 @@ void meta_window_actor_frame_complete (MetaWindowActor *self,
|
||||
|
||||
void meta_window_actor_invalidate_shadow (MetaWindowActor *self);
|
||||
|
||||
void meta_window_actor_set_redirected (MetaWindowActor *self, gboolean state);
|
||||
|
||||
gboolean meta_window_actor_should_unredirect (MetaWindowActor *self);
|
||||
|
||||
void meta_window_actor_get_shape_bounds (MetaWindowActor *self,
|
||||
cairo_rectangle_int_t *bounds);
|
||||
|
||||
gboolean meta_window_actor_should_unredirect (MetaWindowActor *self);
|
||||
void meta_window_actor_set_unredirected (MetaWindowActor *self,
|
||||
gboolean unredirected);
|
||||
|
||||
gboolean meta_window_actor_effect_in_progress (MetaWindowActor *self);
|
||||
void meta_window_actor_sync_actor_geometry (MetaWindowActor *self,
|
||||
gboolean did_placement);
|
||||
|
@@ -721,7 +721,7 @@ meta_window_actor_get_paint_volume (ClutterActor *actor,
|
||||
gdk_rectangle_union (&bounds, &shadow_bounds, &bounds);
|
||||
}
|
||||
|
||||
if (priv->unobscured_region)
|
||||
if (priv->unobscured_region && !clutter_actor_has_mapped_clones (actor))
|
||||
{
|
||||
cairo_rectangle_int_t unobscured_bounds;
|
||||
cairo_region_get_extents (priv->unobscured_region, &unobscured_bounds);
|
||||
@@ -860,59 +860,6 @@ meta_window_actor_is_destroyed (MetaWindowActor *self)
|
||||
return self->priv->disposed;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_window_actor_is_override_redirect (MetaWindowActor *self)
|
||||
{
|
||||
return meta_window_is_override_redirect (self->priv->window);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_window_actor_get_workspace:
|
||||
* @self: #MetaWindowActor
|
||||
*
|
||||
* Returns the index of workspace on which this window is located; if the
|
||||
* window is sticky, or is not currently located on any workspace, returns -1.
|
||||
* This function is deprecated and should not be used in newly written code;
|
||||
* meta_window_get_workspace() instead.
|
||||
*
|
||||
* Return value: (transfer none): index of workspace on which this window is
|
||||
* located.
|
||||
*/
|
||||
gint
|
||||
meta_window_actor_get_workspace (MetaWindowActor *self)
|
||||
{
|
||||
MetaWindowActorPrivate *priv;
|
||||
MetaWorkspace *workspace;
|
||||
|
||||
if (!self)
|
||||
return -1;
|
||||
|
||||
priv = self->priv;
|
||||
|
||||
if (!priv->window || meta_window_is_on_all_workspaces (priv->window))
|
||||
return -1;
|
||||
|
||||
workspace = meta_window_get_workspace (priv->window);
|
||||
|
||||
if (!workspace)
|
||||
return -1;
|
||||
|
||||
return meta_workspace_index (workspace);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_window_actor_showing_on_its_workspace (MetaWindowActor *self)
|
||||
{
|
||||
if (!self)
|
||||
return FALSE;
|
||||
|
||||
/* If override redirect: */
|
||||
if (!self->priv->window)
|
||||
return TRUE;
|
||||
|
||||
return meta_window_showing_on_its_workspace (self->priv->window);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_actor_freeze (MetaWindowActor *self)
|
||||
{
|
||||
@@ -1321,6 +1268,9 @@ meta_window_actor_should_unredirect (MetaWindowActor *self)
|
||||
MetaWindow *metaWindow = meta_window_actor_get_meta_window (self);
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
|
||||
if (meta_is_wayland_compositor ())
|
||||
return FALSE;
|
||||
|
||||
if (meta_window_requested_dont_bypass_compositor (metaWindow))
|
||||
return FALSE;
|
||||
|
||||
@@ -1342,14 +1292,15 @@ meta_window_actor_should_unredirect (MetaWindowActor *self)
|
||||
if (meta_window_is_override_redirect (metaWindow))
|
||||
return TRUE;
|
||||
|
||||
if (!meta_is_wayland_compositor () && priv->does_full_damage)
|
||||
if (priv->does_full_damage)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_actor_set_redirected (MetaWindowActor *self, gboolean state)
|
||||
meta_window_actor_set_unredirected (MetaWindowActor *self,
|
||||
gboolean unredirected)
|
||||
{
|
||||
MetaWindow *metaWindow = meta_window_actor_get_meta_window (self);
|
||||
MetaDisplay *display = meta_window_get_display (metaWindow);
|
||||
@@ -1357,21 +1308,20 @@ meta_window_actor_set_redirected (MetaWindowActor *self, gboolean state)
|
||||
Display *xdisplay = meta_display_get_xdisplay (display);
|
||||
Window xwin = meta_window_get_toplevel_xwindow (metaWindow);
|
||||
|
||||
if (state)
|
||||
meta_error_trap_push (display);
|
||||
|
||||
if (unredirected)
|
||||
{
|
||||
meta_error_trap_push (display);
|
||||
XCompositeRedirectWindow (xdisplay, xwin, CompositeRedirectManual);
|
||||
meta_error_trap_pop (display);
|
||||
meta_window_actor_detach_x11_pixmap (self);
|
||||
self->priv->unredirected = FALSE;
|
||||
XCompositeUnredirectWindow (xdisplay, xwin, CompositeRedirectManual);
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_error_trap_push (display);
|
||||
XCompositeUnredirectWindow (xdisplay, xwin, CompositeRedirectManual);
|
||||
meta_error_trap_pop (display);
|
||||
self->priv->unredirected = TRUE;
|
||||
XCompositeRedirectWindow (xdisplay, xwin, CompositeRedirectManual);
|
||||
meta_window_actor_detach_x11_pixmap (self);
|
||||
}
|
||||
|
||||
self->priv->unredirected = unredirected;
|
||||
meta_error_trap_pop (display);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1388,6 +1338,12 @@ meta_window_actor_destroy (MetaWindowActor *self)
|
||||
window_type = meta_window_get_window_type (window);
|
||||
meta_window_set_compositor_private (window, NULL);
|
||||
|
||||
if (priv->send_frame_messages_timer != 0)
|
||||
{
|
||||
g_source_remove (priv->send_frame_messages_timer);
|
||||
priv->send_frame_messages_timer = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* We remove the window from internal lookup hashes and thus any other
|
||||
* unmap events etc fail
|
||||
@@ -1805,15 +1761,11 @@ meta_window_actor_cull_out (MetaCullable *cullable,
|
||||
cairo_region_t *clip_region)
|
||||
{
|
||||
MetaWindowActor *self = META_WINDOW_ACTOR (cullable);
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
|
||||
if (!meta_is_wayland_compositor ())
|
||||
{
|
||||
MetaCompScreen *info = meta_screen_get_compositor_data (self->priv->screen);
|
||||
|
||||
/* Don't do any culling for the unredirected window */
|
||||
if (self == info->unredirected_window)
|
||||
return;
|
||||
}
|
||||
/* Don't do any culling for the unredirected window */
|
||||
if (priv->unredirected)
|
||||
return;
|
||||
|
||||
meta_window_actor_set_unobscured_region (self, unobscured_region);
|
||||
meta_cullable_cull_out_children (cullable, unobscured_region, clip_region);
|
||||
|
@@ -184,9 +184,8 @@ meta_window_group_paint (ClutterActor *actor)
|
||||
if (info->unredirected_window != NULL)
|
||||
{
|
||||
cairo_rectangle_int_t unredirected_rect;
|
||||
MetaWindow *window = meta_window_actor_get_meta_window (info->unredirected_window);
|
||||
|
||||
meta_window_get_frame_rect (window, (MetaRectangle *)&unredirected_rect);
|
||||
meta_window_get_frame_rect (info->unredirected_window, (MetaRectangle *)&unredirected_rect);
|
||||
cairo_region_subtract_rectangle (unobscured_region, &unredirected_rect);
|
||||
cairo_region_subtract_rectangle (clip_region, &unredirected_rect);
|
||||
}
|
||||
|
@@ -407,9 +407,11 @@ switch_workspace (MetaPlugin *plugin,
|
||||
MetaWindowActor *window_actor = l->data;
|
||||
ActorPrivate *apriv = get_actor_private (window_actor);
|
||||
ClutterActor *actor = CLUTTER_ACTOR (window_actor);
|
||||
MetaWorkspace *workspace;
|
||||
gint win_workspace;
|
||||
|
||||
win_workspace = meta_window_actor_get_workspace (window_actor);
|
||||
workspace = meta_window_get_workspace (meta_window_actor_get_meta_window (window_actor));
|
||||
win_workspace = meta_workspace_index (workspace);
|
||||
|
||||
if (win_workspace == to || win_workspace == from)
|
||||
{
|
||||
|
@@ -1353,7 +1353,6 @@ constrain_titlebar_visible (MetaWindow *window,
|
||||
window->type == META_WINDOW_DOCK ||
|
||||
window->fullscreen ||
|
||||
!window->require_titlebar_visible ||
|
||||
!window->decorated ||
|
||||
unconstrained_user_action)
|
||||
return TRUE;
|
||||
|
||||
|
@@ -36,6 +36,7 @@
|
||||
#include <meta/main.h>
|
||||
#include "screen-private.h"
|
||||
#include "window-private.h"
|
||||
#include "window-x11.h"
|
||||
#include "window-props.h"
|
||||
#include "group-props.h"
|
||||
#include "frame.h"
|
||||
@@ -829,22 +830,12 @@ meta_display_open (void)
|
||||
{
|
||||
MetaScreen *screen = tmp->data;
|
||||
|
||||
if (meta_is_wayland_compositor ())
|
||||
{
|
||||
/* Instead of explicitly enumerating all windows during
|
||||
* initialization, when we run as a wayland compositor we can rely on
|
||||
* xwayland notifying us of all top level windows so we create
|
||||
* MetaWindows when we get those notifications.
|
||||
*
|
||||
* We still want a guard window so we can avoid
|
||||
* unmapping/withdrawing minimized windows for live
|
||||
* thumbnails...
|
||||
*/
|
||||
if (screen->guard_window == None)
|
||||
screen->guard_window =
|
||||
meta_screen_create_guard_window (screen->display->xdisplay, screen);
|
||||
}
|
||||
else
|
||||
meta_screen_create_guard_window (screen);
|
||||
|
||||
/* We know that if mutter is running as a Wayland compositor,
|
||||
* we start out with no windows.
|
||||
*/
|
||||
if (!meta_is_wayland_compositor ())
|
||||
meta_screen_manage_all_windows (screen);
|
||||
|
||||
tmp = tmp->next;
|
||||
@@ -1581,7 +1572,7 @@ handle_net_restack_window (MetaDisplay* display,
|
||||
*
|
||||
* Also, unconditionally following these is REALLY stupid--we should
|
||||
* combine this code with the stuff in
|
||||
* meta_window_configure_request() which is smart about whether to
|
||||
* meta_window_x11_configure_request() which is smart about whether to
|
||||
* follow the request or do something else (though not smart enough
|
||||
* and is also too stupid to handle the sibling stuff).
|
||||
*/
|
||||
@@ -1984,6 +1975,7 @@ meta_display_handle_event (MetaDisplay *display,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
MetaWindow *window;
|
||||
gboolean bypass_clutter = FALSE, bypass_wayland = FALSE;
|
||||
|
||||
/* XXX -- we need to fill this in properly at some point... */
|
||||
gboolean frame_was_receiver = FALSE;
|
||||
@@ -2055,8 +2047,9 @@ meta_display_handle_event (MetaDisplay *display,
|
||||
meta_stack_set_positions (window->screen->stack,
|
||||
display->grab_old_window_stacking);
|
||||
}
|
||||
meta_display_end_grab_op (display,
|
||||
event->any.time);
|
||||
meta_display_end_grab_op (display, event->any.time);
|
||||
bypass_clutter = TRUE;
|
||||
bypass_wayland = TRUE;
|
||||
}
|
||||
else if (window && display->grab_op == META_GRAB_OP_NONE)
|
||||
{
|
||||
@@ -2171,20 +2164,8 @@ meta_display_handle_event (MetaDisplay *display,
|
||||
event->button.y,
|
||||
event->button.button,
|
||||
event->any.time);
|
||||
}
|
||||
|
||||
if (!frame_was_receiver && unmodified)
|
||||
{
|
||||
/* This is from our synchronous grab since
|
||||
* it has no modifiers and was on the client window
|
||||
*/
|
||||
|
||||
meta_verbose ("Allowing events time %u\n",
|
||||
(unsigned int) event->any.time);
|
||||
|
||||
/* XXX -- implement this in Wayland */
|
||||
XIAllowEvents (display->xdisplay, META_VIRTUAL_CORE_POINTER_ID,
|
||||
XIReplayDevice, event->any.time);
|
||||
bypass_clutter = TRUE;
|
||||
bypass_wayland = TRUE;
|
||||
}
|
||||
|
||||
if (begin_move && window->has_move_func)
|
||||
@@ -2200,6 +2181,8 @@ meta_display_handle_event (MetaDisplay *display,
|
||||
event->any.time,
|
||||
event->button.x,
|
||||
event->button.y);
|
||||
bypass_clutter = TRUE;
|
||||
bypass_wayland = TRUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -2211,7 +2194,11 @@ meta_display_handle_event (MetaDisplay *display,
|
||||
|
||||
if (display->grab_window == window &&
|
||||
meta_grab_op_is_mouse (display->grab_op))
|
||||
meta_window_handle_mouse_grab_op_event (window, event);
|
||||
{
|
||||
meta_window_handle_mouse_grab_op_event (window, event);
|
||||
bypass_clutter = TRUE;
|
||||
bypass_wayland = TRUE;
|
||||
}
|
||||
break;
|
||||
case CLUTTER_MOTION:
|
||||
if (display->grab_op == META_GRAB_OP_COMPOSITOR)
|
||||
@@ -2219,7 +2206,11 @@ meta_display_handle_event (MetaDisplay *display,
|
||||
|
||||
if (display->grab_window == window &&
|
||||
meta_grab_op_is_mouse (display->grab_op))
|
||||
meta_window_handle_mouse_grab_op_event (window, event);
|
||||
{
|
||||
meta_window_handle_mouse_grab_op_event (window, event);
|
||||
bypass_clutter = TRUE;
|
||||
bypass_wayland = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case CLUTTER_KEY_PRESS:
|
||||
@@ -2231,22 +2222,28 @@ meta_display_handle_event (MetaDisplay *display,
|
||||
* want to pass the key event to the compositor or Wayland at all.
|
||||
*/
|
||||
if (meta_display_process_key_event (display, window, (ClutterKeyEvent *) event))
|
||||
return TRUE;
|
||||
{
|
||||
bypass_clutter = TRUE;
|
||||
bypass_wayland = TRUE;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* If the compositor has a grab, don't pass that through to Wayland */
|
||||
if (display->grab_op == META_GRAB_OP_COMPOSITOR)
|
||||
bypass_wayland = TRUE;
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
if (compositor && (display->grab_op == META_GRAB_OP_NONE))
|
||||
if (compositor && !bypass_wayland)
|
||||
{
|
||||
if (meta_wayland_compositor_handle_event (compositor, event))
|
||||
return TRUE;
|
||||
bypass_clutter = TRUE;
|
||||
}
|
||||
#endif /* HAVE_WAYLAND */
|
||||
|
||||
return (display->grab_op != META_GRAB_OP_NONE &&
|
||||
display->grab_op != META_GRAB_OP_COMPOSITOR);
|
||||
return bypass_clutter;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -2686,9 +2683,9 @@ handle_other_xevent (MetaDisplay *display,
|
||||
XShapeEvent *sev = (XShapeEvent*) event;
|
||||
|
||||
if (sev->kind == ShapeBounding)
|
||||
meta_window_update_shape_region_x11 (window);
|
||||
meta_window_x11_update_shape_region (window);
|
||||
else if (sev->kind == ShapeInput)
|
||||
meta_window_update_input_region_x11 (window);
|
||||
meta_window_x11_update_input_region (window);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2810,15 +2807,15 @@ handle_other_xevent (MetaDisplay *display,
|
||||
if (display->compositor && window == NULL
|
||||
&& meta_display_screen_for_root (display, event->xmap.event))
|
||||
{
|
||||
window = meta_window_new (display, event->xmap.window,
|
||||
FALSE, META_COMP_EFFECT_CREATE);
|
||||
window = meta_window_x11_new (display, event->xmap.window,
|
||||
FALSE, META_COMP_EFFECT_CREATE);
|
||||
}
|
||||
break;
|
||||
case MapRequest:
|
||||
if (window == NULL)
|
||||
{
|
||||
window = meta_window_new (display, event->xmaprequest.window,
|
||||
FALSE, META_COMP_EFFECT_CREATE);
|
||||
window = meta_window_x11_new (display, event->xmaprequest.window,
|
||||
FALSE, META_COMP_EFFECT_CREATE);
|
||||
}
|
||||
/* if frame was receiver it's some malicious send event or something */
|
||||
else if (!frame_was_receiver && window)
|
||||
@@ -2897,7 +2894,7 @@ handle_other_xevent (MetaDisplay *display,
|
||||
else
|
||||
{
|
||||
if (!frame_was_receiver)
|
||||
meta_window_configure_request (window, event);
|
||||
meta_window_x11_configure_request (window, event);
|
||||
}
|
||||
break;
|
||||
case GravityNotify:
|
||||
@@ -2914,9 +2911,9 @@ handle_other_xevent (MetaDisplay *display,
|
||||
MetaScreen *screen;
|
||||
|
||||
if (window && !frame_was_receiver)
|
||||
meta_window_property_notify (window, event);
|
||||
meta_window_x11_property_notify (window, event);
|
||||
else if (property_for_window && !frame_was_receiver)
|
||||
meta_window_property_notify (property_for_window, event);
|
||||
meta_window_x11_property_notify (property_for_window, event);
|
||||
|
||||
group = meta_display_lookup_group (display,
|
||||
event->xproperty.window);
|
||||
@@ -2987,7 +2984,7 @@ handle_other_xevent (MetaDisplay *display,
|
||||
if (window)
|
||||
{
|
||||
if (!frame_was_receiver)
|
||||
meta_window_client_message (window, event);
|
||||
meta_window_x11_client_message (window, event);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@@ -28,7 +28,6 @@
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#define _SVID_SOURCE /* for putenv() */
|
||||
|
||||
#include <config.h>
|
||||
#include "keybindings-private.h"
|
||||
@@ -54,9 +53,6 @@
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
#include "meta-wayland-private.h"
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/vt.h>
|
||||
#endif
|
||||
|
||||
#define SCHEMA_COMMON_KEYBINDINGS "org.gnome.desktop.wm.keybindings"
|
||||
@@ -4084,18 +4080,6 @@ handle_set_spew_mark (MetaDisplay *display,
|
||||
}
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
static gboolean
|
||||
activate_vt (int vt)
|
||||
{
|
||||
int tty, reply;
|
||||
|
||||
tty = open ("/dev/tty", O_RDWR | O_NOCTTY | O_CLOEXEC);
|
||||
reply = ioctl (tty, VT_ACTIVATE, vt);
|
||||
close (tty);
|
||||
|
||||
return (reply == 0);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_switch_vt (MetaDisplay *display,
|
||||
MetaScreen *screen,
|
||||
@@ -4105,9 +4089,14 @@ handle_switch_vt (MetaDisplay *display,
|
||||
gpointer dummy)
|
||||
{
|
||||
gint vt = binding->handler->data;
|
||||
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
|
||||
GError *error = NULL;
|
||||
|
||||
if (!activate_vt (vt))
|
||||
g_warning ("Failed to switch VT");
|
||||
if (!meta_wayland_compositor_activate_vt (compositor, vt, &error))
|
||||
{
|
||||
g_warning ("Failed to switch VT: %s", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@@ -302,8 +302,12 @@ event_dispatch (GSource *source,
|
||||
gpointer user_data)
|
||||
{
|
||||
ClutterEvent *event = clutter_event_get ();
|
||||
|
||||
if (event)
|
||||
clutter_do_event (event);
|
||||
{
|
||||
clutter_do_event (event);
|
||||
clutter_event_free (event);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -341,16 +345,16 @@ meta_clutter_init (void)
|
||||
* also is %NULL, use the default - :0.0
|
||||
*/
|
||||
static void
|
||||
meta_select_display (gchar *display_name)
|
||||
meta_select_display (char *display_arg)
|
||||
{
|
||||
gchar *envVar = "";
|
||||
if (display_name)
|
||||
envVar = g_strconcat ("DISPLAY=", display_name, NULL);
|
||||
else if (g_getenv ("MUTTER_DISPLAY"))
|
||||
envVar = g_strconcat ("DISPLAY=",
|
||||
g_getenv ("MUTTER_DISPLAY"), NULL);
|
||||
/* DO NOT FREE envVar, putenv() sucks */
|
||||
putenv (envVar);
|
||||
const char *display_name;
|
||||
|
||||
if (display_arg)
|
||||
display_name = (const char *) display_arg;
|
||||
else
|
||||
display_name = g_getenv ("MUTTER_DISPLAY");
|
||||
|
||||
g_setenv ("DISPLAY", display_name, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -468,47 +468,10 @@ meta_cursor_reference_from_buffer (MetaCursorTracker *tracker,
|
||||
|
||||
if (tracker->gbm)
|
||||
{
|
||||
cogl_format = cogl_texture_get_format (COGL_TEXTURE (self->texture));
|
||||
switch (cogl_format)
|
||||
{
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
case COGL_PIXEL_FORMAT_ARGB_8888_PRE:
|
||||
case COGL_PIXEL_FORMAT_ARGB_8888:
|
||||
gbm_format = GBM_FORMAT_BGRA8888;
|
||||
break;
|
||||
case COGL_PIXEL_FORMAT_BGRA_8888_PRE:
|
||||
case COGL_PIXEL_FORMAT_BGRA_8888:
|
||||
break;
|
||||
case COGL_PIXEL_FORMAT_RGB_888:
|
||||
break;
|
||||
#else
|
||||
case COGL_PIXEL_FORMAT_ARGB_8888_PRE:
|
||||
case COGL_PIXEL_FORMAT_ARGB_8888:
|
||||
gbm_format = GBM_FORMAT_ARGB8888;
|
||||
break;
|
||||
case COGL_PIXEL_FORMAT_BGRA_8888_PRE:
|
||||
case COGL_PIXEL_FORMAT_BGRA_8888:
|
||||
gbm_format = GBM_FORMAT_BGRA8888;
|
||||
break;
|
||||
case COGL_PIXEL_FORMAT_RGB_888:
|
||||
gbm_format = GBM_FORMAT_RGB888;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
meta_warning ("Unknown cogl format %d\n", cogl_format);
|
||||
return self;
|
||||
}
|
||||
|
||||
if (gbm_device_is_format_supported (tracker->gbm, gbm_format,
|
||||
GBM_BO_USE_CURSOR_64X64))
|
||||
{
|
||||
self->bo = gbm_bo_import (tracker->gbm, GBM_BO_IMPORT_WL_BUFFER,
|
||||
buffer, GBM_BO_USE_CURSOR_64X64);
|
||||
if (!self->bo)
|
||||
meta_warning ("Importing HW cursor from wl_buffer failed\n");
|
||||
}
|
||||
else
|
||||
meta_warning ("HW cursor for format %d not supported\n", gbm_format);
|
||||
self->bo = gbm_bo_import (tracker->gbm, GBM_BO_IMPORT_WL_BUFFER,
|
||||
buffer, GBM_BO_USE_CURSOR_64X64);
|
||||
if (!self->bo)
|
||||
meta_warning ("Importing HW cursor from wl_buffer failed\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -111,8 +111,7 @@ make_output_name (drmModeConnector *connector)
|
||||
};
|
||||
const char *connector_type_name;
|
||||
|
||||
if (connector->connector_type >= 0 &&
|
||||
connector->connector_type < G_N_ELEMENTS (connector_type_names))
|
||||
if (connector->connector_type < G_N_ELEMENTS (connector_type_names))
|
||||
connector_type_name = connector_type_names[connector->connector_type];
|
||||
else
|
||||
connector_type_name = "unknown";
|
||||
|
@@ -288,7 +288,7 @@ make_logical_config (MetaMonitorManager *manager)
|
||||
|
||||
for (j = 0; j < monitor_infos->len; j++)
|
||||
{
|
||||
MetaMonitorInfo *info = &g_array_index (monitor_infos, MetaMonitorInfo, i);
|
||||
MetaMonitorInfo *info = &g_array_index (monitor_infos, MetaMonitorInfo, j);
|
||||
if (meta_rectangle_equal (&crtc->rect,
|
||||
&info->rect))
|
||||
{
|
||||
|
@@ -241,7 +241,7 @@ void meta_screen_workspace_switched (MetaScreen *screen,
|
||||
|
||||
void meta_screen_set_active_workspace_hint (MetaScreen *screen);
|
||||
|
||||
Window meta_screen_create_guard_window (Display *xdisplay, MetaScreen *screen);
|
||||
void meta_screen_create_guard_window (MetaScreen *screen);
|
||||
|
||||
gboolean meta_screen_handle_xevent (MetaScreen *screen,
|
||||
XEvent *xevent);
|
||||
|
@@ -445,17 +445,16 @@ reload_monitor_infos (MetaScreen *screen)
|
||||
* should effectively be forwarded to events on the background actor,
|
||||
* providing that the scene graph is set up correctly.
|
||||
*/
|
||||
Window
|
||||
meta_screen_create_guard_window (Display *xdisplay, MetaScreen *screen)
|
||||
static Window
|
||||
create_guard_window (Display *xdisplay, MetaScreen *screen)
|
||||
{
|
||||
XSetWindowAttributes attributes;
|
||||
Window guard_window;
|
||||
gulong create_serial;
|
||||
MetaStackWindow stack_window;
|
||||
|
||||
|
||||
attributes.event_mask = NoEventMask;
|
||||
attributes.override_redirect = True;
|
||||
attributes.background_pixel = BlackPixel (xdisplay, screen->number);
|
||||
|
||||
/* We have to call record_add() after we have the new window ID,
|
||||
* so save the serial for the CreateWindow request until then */
|
||||
@@ -468,10 +467,10 @@ meta_screen_create_guard_window (Display *xdisplay, MetaScreen *screen)
|
||||
screen->rect.width,
|
||||
screen->rect.height,
|
||||
0, /* border width */
|
||||
CopyFromParent, /* depth */
|
||||
CopyFromParent, /* class */
|
||||
0, /* depth */
|
||||
InputOnly, /* class */
|
||||
CopyFromParent, /* visual */
|
||||
CWEventMask|CWOverrideRedirect|CWBackPixel,
|
||||
CWEventMask|CWOverrideRedirect,
|
||||
&attributes);
|
||||
|
||||
{
|
||||
@@ -878,6 +877,13 @@ meta_screen_free (MetaScreen *screen,
|
||||
meta_display_ungrab (display);
|
||||
}
|
||||
|
||||
void
|
||||
meta_screen_create_guard_window (MetaScreen *screen)
|
||||
{
|
||||
if (screen->guard_window == None)
|
||||
screen->guard_window = create_guard_window (screen->display->xdisplay, screen);
|
||||
}
|
||||
|
||||
void
|
||||
meta_screen_manage_all_windows (MetaScreen *screen)
|
||||
{
|
||||
@@ -885,10 +891,6 @@ meta_screen_manage_all_windows (MetaScreen *screen)
|
||||
MetaStackWindow *children;
|
||||
int n_children, i;
|
||||
|
||||
if (screen->guard_window == None)
|
||||
screen->guard_window =
|
||||
meta_screen_create_guard_window (screen->display->xdisplay, screen);
|
||||
|
||||
meta_stack_freeze (screen->stack);
|
||||
meta_stack_tracker_get_stack (screen->stack_tracker, &_children, &n_children);
|
||||
|
||||
@@ -897,8 +899,8 @@ meta_screen_manage_all_windows (MetaScreen *screen)
|
||||
|
||||
for (i = 0; i < n_children; ++i)
|
||||
{
|
||||
meta_window_new (screen->display, children[i].x11.xwindow, TRUE,
|
||||
META_COMP_EFFECT_NONE);
|
||||
meta_window_x11_new (screen->display, children[i].x11.xwindow, TRUE,
|
||||
META_COMP_EFFECT_NONE);
|
||||
}
|
||||
|
||||
g_free (children);
|
||||
|
@@ -506,12 +506,22 @@ struct _MetaWindowClass
|
||||
#define META_WINDOW_ALLOWS_HORIZONTAL_RESIZE(w) (META_WINDOW_ALLOWS_RESIZE_EXCEPT_HINTS (w) && (w)->size_hints.min_width < (w)->size_hints.max_width)
|
||||
#define META_WINDOW_ALLOWS_VERTICAL_RESIZE(w) (META_WINDOW_ALLOWS_RESIZE_EXCEPT_HINTS (w) && (w)->size_hints.min_height < (w)->size_hints.max_height)
|
||||
|
||||
MetaWindow* meta_window_new (MetaDisplay *display,
|
||||
Window xwindow,
|
||||
gboolean must_be_viewable,
|
||||
MetaCompEffect effect);
|
||||
MetaWindow *meta_window_new_for_wayland (MetaDisplay *display,
|
||||
MetaWindow * _meta_window_shared_new (MetaDisplay *display,
|
||||
MetaScreen *screen,
|
||||
MetaWindowClientType client_type,
|
||||
MetaWaylandSurface *surface,
|
||||
Window xwindow,
|
||||
gulong existing_wm_state,
|
||||
MetaCompEffect effect,
|
||||
XWindowAttributes *attrs);
|
||||
|
||||
MetaWindow * meta_window_x11_new (MetaDisplay *display,
|
||||
Window xwindow,
|
||||
gboolean must_be_viewable,
|
||||
MetaCompEffect effect);
|
||||
MetaWindow * meta_window_wayland_new (MetaDisplay *display,
|
||||
MetaWaylandSurface *surface);
|
||||
|
||||
void meta_window_unmanage (MetaWindow *window,
|
||||
guint32 timestamp);
|
||||
void meta_window_calc_showing (MetaWindow *window);
|
||||
@@ -615,12 +625,6 @@ void meta_window_move_resize_wayland (MetaWindow *window,
|
||||
int height,
|
||||
int dx,
|
||||
int dy);
|
||||
gboolean meta_window_configure_request (MetaWindow *window,
|
||||
XEvent *event);
|
||||
gboolean meta_window_property_notify (MetaWindow *window,
|
||||
XEvent *event);
|
||||
gboolean meta_window_client_message (MetaWindow *window,
|
||||
XEvent *event);
|
||||
void meta_window_set_focused_internal (MetaWindow *window,
|
||||
gboolean focused);
|
||||
|
||||
@@ -697,8 +701,6 @@ void meta_window_set_user_time (MetaWindow *window,
|
||||
|
||||
void meta_window_update_icon_now (MetaWindow *window);
|
||||
|
||||
void meta_window_update_role (MetaWindow *window);
|
||||
void meta_window_update_net_wm_type (MetaWindow *window);
|
||||
void meta_window_update_for_monitors_changed (MetaWindow *window);
|
||||
void meta_window_update_on_all_workspaces (MetaWindow *window);
|
||||
|
||||
@@ -712,10 +714,6 @@ void meta_window_compute_tile_match (MetaWindow *window);
|
||||
|
||||
gboolean meta_window_updates_are_frozen (MetaWindow *window);
|
||||
|
||||
void meta_window_update_opaque_region_x11 (MetaWindow *window);
|
||||
void meta_window_update_input_region_x11 (MetaWindow *window);
|
||||
void meta_window_update_shape_region_x11 (MetaWindow *window);
|
||||
|
||||
void meta_window_set_title (MetaWindow *window,
|
||||
const char *title);
|
||||
void meta_window_set_wm_class (MetaWindow *window,
|
||||
@@ -756,4 +754,9 @@ void meta_window_pong (MetaWindow *window,
|
||||
guint32 timestamp);
|
||||
Window meta_window_get_toplevel_xwindow (MetaWindow *window);
|
||||
|
||||
void meta_window_activate_full (MetaWindow *window,
|
||||
guint32 timestamp,
|
||||
MetaClientType source_indication,
|
||||
MetaWorkspace *workspace);
|
||||
|
||||
#endif
|
||||
|
@@ -39,6 +39,7 @@
|
||||
|
||||
#include <config.h>
|
||||
#include "window-props.h"
|
||||
#include "window-x11.h"
|
||||
#include <meta/errors.h>
|
||||
#include "xprops.h"
|
||||
#include "frame.h"
|
||||
@@ -229,7 +230,7 @@ reload_net_wm_window_type (MetaWindow *window,
|
||||
MetaPropValue *value,
|
||||
gboolean initial)
|
||||
{
|
||||
meta_window_update_net_wm_type (window);
|
||||
meta_window_x11_update_net_wm_type (window);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -333,7 +334,7 @@ reload_wm_window_role (MetaWindow *window,
|
||||
MetaPropValue *value,
|
||||
gboolean initial)
|
||||
{
|
||||
meta_window_update_role (window);
|
||||
meta_window_x11_update_role (window);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -558,7 +559,7 @@ reload_opaque_region (MetaWindow *window,
|
||||
MetaPropValue *value,
|
||||
gboolean initial)
|
||||
{
|
||||
meta_window_update_opaque_region_x11 (window);
|
||||
meta_window_x11_update_opaque_region (window);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -845,7 +846,7 @@ reload_mwm_hints (MetaWindow *window,
|
||||
|
||||
meta_window_recalc_features (window);
|
||||
|
||||
/* We do all this anyhow at the end of meta_window_new() */
|
||||
/* We do all this anyhow at the end of meta_window_x11_new() */
|
||||
if (!window->constructing)
|
||||
{
|
||||
if (window->decorated)
|
||||
@@ -1764,8 +1765,8 @@ meta_display_init_window_prop_hooks (MetaDisplay *display)
|
||||
{ display->atom__NET_WM_ICON_GEOMETRY, META_PROP_VALUE_CARDINAL_LIST, reload_icon_geometry, FALSE, FALSE },
|
||||
{ display->atom_WM_CLIENT_LEADER, META_PROP_VALUE_INVALID, complain_about_broken_client, FALSE, FALSE },
|
||||
{ display->atom_SM_CLIENT_ID, META_PROP_VALUE_INVALID, complain_about_broken_client, FALSE, FALSE },
|
||||
{ display->atom_WM_WINDOW_ROLE, META_PROP_VALUE_INVALID, reload_wm_window_role, FALSE, FALSE },
|
||||
{ display->atom__NET_WM_WINDOW_TYPE, META_PROP_VALUE_INVALID, reload_net_wm_window_type, FALSE, TRUE },
|
||||
{ display->atom_WM_WINDOW_ROLE, META_PROP_VALUE_INVALID, reload_wm_window_role, TRUE, FALSE },
|
||||
{ display->atom__NET_WM_WINDOW_TYPE, META_PROP_VALUE_INVALID, reload_net_wm_window_type, TRUE, TRUE },
|
||||
{ display->atom__NET_WM_STRUT, META_PROP_VALUE_INVALID, reload_struts, FALSE, FALSE },
|
||||
{ display->atom__NET_WM_STRUT_PARTIAL, META_PROP_VALUE_INVALID, reload_struts, FALSE, FALSE },
|
||||
{ display->atom__NET_WM_BYPASS_COMPOSITOR, META_PROP_VALUE_CARDINAL, reload_bypass_compositor, FALSE, FALSE },
|
||||
|
1491
src/core/window-x11.c
Normal file
1491
src/core/window-x11.c
Normal file
File diff suppressed because it is too large
Load Diff
45
src/core/window-x11.h
Normal file
45
src/core/window-x11.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington
|
||||
* Copyright (C) 2002 Red Hat, Inc.
|
||||
* Copyright (C) 2003, 2004 Rob Adams
|
||||
* Copyright (C) 2004-2006 Elijah Newren
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef META_WINDOW_X11_H
|
||||
#define META_WINDOW_X11_H
|
||||
|
||||
#include <meta/window.h>
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
void meta_window_x11_set_net_wm_state (MetaWindow *window);
|
||||
void meta_window_x11_set_wm_state (MetaWindow *window);
|
||||
|
||||
void meta_window_x11_update_role (MetaWindow *window);
|
||||
void meta_window_x11_update_net_wm_type (MetaWindow *window);
|
||||
void meta_window_x11_update_opaque_region (MetaWindow *window);
|
||||
void meta_window_x11_update_input_region (MetaWindow *window);
|
||||
void meta_window_x11_update_shape_region (MetaWindow *window);
|
||||
|
||||
gboolean meta_window_x11_configure_request (MetaWindow *window,
|
||||
XEvent *event);
|
||||
gboolean meta_window_x11_property_notify (MetaWindow *window,
|
||||
XEvent *event);
|
||||
gboolean meta_window_x11_client_message (MetaWindow *window,
|
||||
XEvent *event);
|
||||
|
||||
#endif
|
1573
src/core/window.c
1573
src/core/window.c
File diff suppressed because it is too large
Load Diff
@@ -58,11 +58,8 @@ struct _MetaWindowActor
|
||||
GType meta_window_actor_get_type (void);
|
||||
|
||||
Window meta_window_actor_get_x_window (MetaWindowActor *self);
|
||||
gint meta_window_actor_get_workspace (MetaWindowActor *self);
|
||||
MetaWindow * meta_window_actor_get_meta_window (MetaWindowActor *self);
|
||||
ClutterActor * meta_window_actor_get_texture (MetaWindowActor *self);
|
||||
gboolean meta_window_actor_is_override_redirect (MetaWindowActor *self);
|
||||
gboolean meta_window_actor_showing_on_its_workspace (MetaWindowActor *self);
|
||||
gboolean meta_window_actor_is_destroyed (MetaWindowActor *self);
|
||||
|
||||
#endif /* META_WINDOW_ACTOR_H */
|
||||
|
@@ -322,12 +322,16 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
|
||||
return;
|
||||
|
||||
resource = pointer->focus_resource;
|
||||
if (resource && pointer->focus->resource)
|
||||
if (resource)
|
||||
{
|
||||
struct wl_client *client = wl_resource_get_client (resource);
|
||||
struct wl_display *display = wl_client_get_display (client);
|
||||
serial = wl_display_next_serial (display);
|
||||
wl_pointer_send_leave (resource, serial, pointer->focus->resource);
|
||||
if (pointer->focus->resource)
|
||||
{
|
||||
struct wl_client *client = wl_resource_get_client (resource);
|
||||
struct wl_display *display = wl_client_get_display (client);
|
||||
serial = wl_display_next_serial (display);
|
||||
wl_pointer_send_leave (resource, serial, pointer->focus->resource);
|
||||
}
|
||||
|
||||
wl_list_remove (&pointer->focus_listener.link);
|
||||
}
|
||||
|
||||
|
@@ -101,13 +101,16 @@ gboolean meta_wayland_compositor_handle_event (MetaWaylandComp
|
||||
|
||||
gboolean meta_wayland_compositor_is_native (MetaWaylandCompositor *compositor);
|
||||
|
||||
MetaWaylandBuffer * meta_wayland_buffer_from_resource (struct wl_resource *resource);
|
||||
|
||||
void meta_wayland_buffer_reference (MetaWaylandBufferReference *ref,
|
||||
MetaWaylandBuffer *buffer);
|
||||
MetaWaylandBuffer * meta_wayland_buffer_from_resource (struct wl_resource *resource);
|
||||
void meta_wayland_buffer_ref (MetaWaylandBuffer *buffer);
|
||||
void meta_wayland_buffer_unref (MetaWaylandBuffer *buffer);
|
||||
|
||||
void meta_wayland_compositor_update (MetaWaylandCompositor *compositor,
|
||||
const ClutterEvent *event);
|
||||
void meta_wayland_compositor_paint_finished (MetaWaylandCompositor *compositor);
|
||||
|
||||
gboolean meta_wayland_compositor_activate_vt (MetaWaylandCompositor *compositor,
|
||||
int vt,
|
||||
GError **error);
|
||||
|
||||
#endif /* META_WAYLAND_PRIVATE_H */
|
||||
|
@@ -48,28 +48,32 @@ unbind_resource (struct wl_resource *resource)
|
||||
}
|
||||
|
||||
static void
|
||||
pointer_unmap_sprite (MetaWaylandSeat *seat)
|
||||
set_cursor_surface (MetaWaylandSeat *seat,
|
||||
MetaWaylandSurface *surface)
|
||||
{
|
||||
if (seat->cursor_tracker)
|
||||
meta_cursor_tracker_set_window_cursor (seat->cursor_tracker, NULL, 0, 0);
|
||||
if (seat->cursor_surface == surface)
|
||||
return;
|
||||
|
||||
if (seat->sprite)
|
||||
{
|
||||
wl_list_remove (&seat->sprite_destroy_listener.link);
|
||||
seat->sprite = NULL;
|
||||
}
|
||||
if (seat->cursor_surface)
|
||||
wl_list_remove (&seat->cursor_surface_destroy_listener.link);
|
||||
|
||||
seat->cursor_surface = surface;
|
||||
|
||||
if (seat->cursor_surface)
|
||||
wl_resource_add_destroy_listener (seat->cursor_surface->resource,
|
||||
&seat->cursor_surface_destroy_listener);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_seat_update_sprite (MetaWaylandSeat *seat)
|
||||
meta_wayland_seat_update_cursor_surface (MetaWaylandSeat *seat)
|
||||
{
|
||||
struct wl_resource *buffer;
|
||||
|
||||
if (seat->cursor_tracker == NULL)
|
||||
return;
|
||||
|
||||
if (seat->sprite->buffer_ref.buffer)
|
||||
buffer = seat->sprite->buffer_ref.buffer->resource;
|
||||
if (seat->cursor_surface && seat->cursor_surface->buffer)
|
||||
buffer = seat->cursor_surface->buffer->resource;
|
||||
else
|
||||
buffer = NULL;
|
||||
|
||||
@@ -89,9 +93,7 @@ pointer_set_cursor (struct wl_client *client,
|
||||
MetaWaylandSeat *seat = wl_resource_get_user_data (resource);
|
||||
MetaWaylandSurface *surface;
|
||||
|
||||
surface = (surface_resource ?
|
||||
wl_resource_get_user_data (surface_resource) :
|
||||
NULL);
|
||||
surface = (surface_resource ? wl_resource_get_user_data (surface_resource) : NULL);
|
||||
|
||||
if (seat->pointer.focus == NULL)
|
||||
return;
|
||||
@@ -102,29 +104,13 @@ pointer_set_cursor (struct wl_client *client,
|
||||
|
||||
seat->hotspot_x = x;
|
||||
seat->hotspot_y = y;
|
||||
|
||||
if (seat->sprite != surface)
|
||||
{
|
||||
pointer_unmap_sprite (seat);
|
||||
|
||||
if (!surface)
|
||||
return;
|
||||
|
||||
wl_resource_add_destroy_listener (surface->resource,
|
||||
&seat->sprite_destroy_listener);
|
||||
|
||||
seat->sprite = surface;
|
||||
|
||||
if (seat->sprite->buffer_ref.buffer)
|
||||
meta_wayland_seat_update_sprite (seat);
|
||||
}
|
||||
set_cursor_surface (seat, surface);
|
||||
meta_wayland_seat_update_cursor_surface (seat);
|
||||
}
|
||||
|
||||
static const struct wl_pointer_interface
|
||||
pointer_interface =
|
||||
{
|
||||
pointer_set_cursor
|
||||
};
|
||||
static const struct wl_pointer_interface pointer_interface = {
|
||||
pointer_set_cursor
|
||||
};
|
||||
|
||||
static void
|
||||
seat_get_pointer (struct wl_client *client,
|
||||
@@ -209,12 +195,12 @@ bind_seat (struct wl_client *client,
|
||||
}
|
||||
|
||||
static void
|
||||
pointer_handle_sprite_destroy (struct wl_listener *listener, void *data)
|
||||
pointer_handle_cursor_surface_destroy (struct wl_listener *listener, void *data)
|
||||
{
|
||||
MetaWaylandSeat *seat =
|
||||
wl_container_of (listener, seat, sprite_destroy_listener);
|
||||
MetaWaylandSeat *seat = wl_container_of (listener, seat, cursor_surface_destroy_listener);
|
||||
|
||||
pointer_unmap_sprite (seat);
|
||||
set_cursor_surface (seat, NULL);
|
||||
meta_wayland_seat_update_cursor_surface (seat);
|
||||
}
|
||||
|
||||
MetaWaylandSeat *
|
||||
@@ -235,8 +221,8 @@ meta_wayland_seat_new (struct wl_display *display,
|
||||
|
||||
seat->current_stage = 0;
|
||||
|
||||
seat->sprite = NULL;
|
||||
seat->sprite_destroy_listener.notify = pointer_handle_sprite_destroy;
|
||||
seat->cursor_surface = NULL;
|
||||
seat->cursor_surface_destroy_listener.notify = pointer_handle_cursor_surface_destroy;
|
||||
seat->hotspot_x = 16;
|
||||
seat->hotspot_y = 16;
|
||||
|
||||
@@ -457,7 +443,7 @@ meta_wayland_seat_repick (MetaWaylandSeat *seat,
|
||||
void
|
||||
meta_wayland_seat_free (MetaWaylandSeat *seat)
|
||||
{
|
||||
pointer_unmap_sprite (seat);
|
||||
set_cursor_surface (seat, NULL);
|
||||
|
||||
meta_wayland_pointer_release (&seat->pointer);
|
||||
meta_wayland_keyboard_release (&seat->keyboard);
|
||||
|
@@ -66,9 +66,9 @@ struct _MetaWaylandSeat
|
||||
struct wl_display *display;
|
||||
|
||||
MetaCursorTracker *cursor_tracker;
|
||||
MetaWaylandSurface *sprite;
|
||||
MetaWaylandSurface *cursor_surface;
|
||||
int hotspot_x, hotspot_y;
|
||||
struct wl_listener sprite_destroy_listener;
|
||||
struct wl_listener cursor_surface_destroy_listener;
|
||||
|
||||
ClutterActor *current_stage;
|
||||
};
|
||||
@@ -90,7 +90,7 @@ meta_wayland_seat_repick (MetaWaylandSeat *seat,
|
||||
const ClutterEvent *for_event);
|
||||
|
||||
void
|
||||
meta_wayland_seat_update_sprite (MetaWaylandSeat *seat);
|
||||
meta_wayland_seat_update_cursor_surface (MetaWaylandSeat *seat);
|
||||
|
||||
void
|
||||
meta_wayland_seat_free (MetaWaylandSeat *seat);
|
||||
|
@@ -58,6 +58,52 @@
|
||||
#include "meta-idle-monitor-private.h"
|
||||
#include "monitor-private.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
META_WAYLAND_SUBSURFACE_PLACEMENT_ABOVE,
|
||||
META_WAYLAND_SUBSURFACE_PLACEMENT_BELOW
|
||||
} MetaWaylandSubsurfacePlacement;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
MetaWaylandSubsurfacePlacement placement;
|
||||
MetaWaylandSurface *sibling;
|
||||
struct wl_listener sibling_destroy_listener;
|
||||
} MetaWaylandSubsurfacePlacementOp;
|
||||
|
||||
static void
|
||||
surface_handle_buffer_destroy (struct wl_listener *listener, void *data)
|
||||
{
|
||||
MetaWaylandSurface *surface = wl_container_of (listener, surface, buffer_destroy_listener);
|
||||
|
||||
wl_resource_post_error (surface->resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||
"Destroyed buffer while it was attached to the surface");
|
||||
surface->buffer = NULL;
|
||||
wl_list_remove (&surface->buffer_destroy_listener.link);
|
||||
}
|
||||
|
||||
static void
|
||||
surface_set_buffer (MetaWaylandSurface *surface,
|
||||
MetaWaylandBuffer *buffer)
|
||||
{
|
||||
if (surface->buffer == buffer)
|
||||
return;
|
||||
|
||||
if (surface->buffer)
|
||||
{
|
||||
meta_wayland_buffer_unref (surface->buffer);
|
||||
wl_list_remove (&surface->buffer_destroy_listener.link);
|
||||
}
|
||||
|
||||
surface->buffer = buffer;
|
||||
|
||||
if (surface->buffer)
|
||||
{
|
||||
meta_wayland_buffer_ref (surface->buffer);
|
||||
wl_signal_add (&surface->buffer->destroy_signal, &surface->buffer_destroy_listener);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
surface_process_damage (MetaWaylandSurface *surface,
|
||||
cairo_region_t *region)
|
||||
@@ -78,28 +124,28 @@ surface_process_damage (MetaWaylandSurface *surface,
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_surface_destroy (struct wl_client *wayland_client,
|
||||
struct wl_resource *wayland_resource)
|
||||
meta_wayland_surface_destroy (struct wl_client *client,
|
||||
struct wl_resource *resource)
|
||||
{
|
||||
wl_resource_destroy (wayland_resource);
|
||||
wl_resource_destroy (resource);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_surface_attach (struct wl_client *wayland_client,
|
||||
struct wl_resource *wayland_surface_resource,
|
||||
struct wl_resource *wayland_buffer_resource,
|
||||
meta_wayland_surface_attach (struct wl_client *client,
|
||||
struct wl_resource *surface_resource,
|
||||
struct wl_resource *buffer_resource,
|
||||
gint32 dx, gint32 dy)
|
||||
{
|
||||
MetaWaylandSurface *surface =
|
||||
wl_resource_get_user_data (wayland_surface_resource);
|
||||
wl_resource_get_user_data (surface_resource);
|
||||
MetaWaylandBuffer *buffer;
|
||||
|
||||
/* X11 unmanaged window */
|
||||
if (!surface)
|
||||
return;
|
||||
|
||||
if (wayland_buffer_resource)
|
||||
buffer = meta_wayland_buffer_from_resource (wayland_buffer_resource);
|
||||
if (buffer_resource)
|
||||
buffer = meta_wayland_buffer_from_resource (buffer_resource);
|
||||
else
|
||||
buffer = NULL;
|
||||
|
||||
@@ -159,11 +205,8 @@ meta_wayland_surface_frame (struct wl_client *client,
|
||||
|
||||
callback = g_slice_new0 (MetaWaylandFrameCallback);
|
||||
callback->compositor = surface->compositor;
|
||||
callback->resource = wl_resource_create (client,
|
||||
&wl_callback_interface, 1,
|
||||
callback_id);
|
||||
wl_resource_set_user_data (callback->resource, callback);
|
||||
wl_resource_set_destructor (callback->resource, destroy_frame_callback);
|
||||
callback->resource = wl_resource_create (client, &wl_callback_interface, META_WL_CALLBACK_VERSION, callback_id);
|
||||
wl_resource_set_implementation (callback->resource, NULL, callback, destroy_frame_callback);
|
||||
|
||||
wl_list_insert (surface->pending.frame_callback_list.prev, &callback->link);
|
||||
}
|
||||
@@ -239,52 +282,47 @@ ensure_buffer_texture (MetaWaylandBuffer *buffer)
|
||||
}
|
||||
|
||||
static void
|
||||
cursor_surface_commit (MetaWaylandSurface *surface)
|
||||
cursor_surface_commit (MetaWaylandSurface *surface,
|
||||
MetaWaylandDoubleBufferedState *pending,
|
||||
gboolean buffer_changed)
|
||||
{
|
||||
MetaWaylandBuffer *buffer = surface->pending.buffer;
|
||||
|
||||
if (surface->pending.newly_attached && buffer != surface->buffer_ref.buffer)
|
||||
{
|
||||
ensure_buffer_texture (buffer);
|
||||
meta_wayland_buffer_reference (&surface->buffer_ref, buffer);
|
||||
}
|
||||
|
||||
meta_wayland_seat_update_sprite (surface->compositor->seat);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
actor_surface_commit (MetaWaylandSurface *surface)
|
||||
{
|
||||
MetaSurfaceActor *surface_actor = surface->surface_actor;
|
||||
MetaWaylandBuffer *buffer = surface->pending.buffer;
|
||||
gboolean changed = FALSE;
|
||||
|
||||
/* wl_surface.attach */
|
||||
if (surface->pending.newly_attached && buffer != surface->buffer_ref.buffer)
|
||||
{
|
||||
ensure_buffer_texture (buffer);
|
||||
meta_wayland_buffer_reference (&surface->buffer_ref, buffer);
|
||||
meta_surface_actor_attach_wayland_buffer (surface_actor, buffer);
|
||||
changed = TRUE;
|
||||
}
|
||||
|
||||
surface_process_damage (surface, surface->pending.damage);
|
||||
|
||||
if (surface->pending.opaque_region)
|
||||
meta_surface_actor_set_opaque_region (surface_actor, surface->pending.opaque_region);
|
||||
if (surface->pending.input_region)
|
||||
meta_surface_actor_set_input_region (surface_actor, surface->pending.input_region);
|
||||
|
||||
return changed;
|
||||
if (buffer_changed)
|
||||
meta_wayland_seat_update_cursor_surface (surface->compositor->seat);
|
||||
}
|
||||
|
||||
static void
|
||||
toplevel_surface_commit (MetaWaylandSurface *surface)
|
||||
actor_surface_commit (MetaWaylandSurface *surface,
|
||||
MetaWaylandDoubleBufferedState *pending,
|
||||
gboolean buffer_changed)
|
||||
{
|
||||
if (actor_surface_commit (surface))
|
||||
MetaSurfaceActor *surface_actor = surface->surface_actor;
|
||||
MetaWaylandBuffer *buffer = pending->buffer;
|
||||
|
||||
if (buffer_changed)
|
||||
{
|
||||
ensure_buffer_texture (buffer);
|
||||
meta_surface_actor_attach_wayland_buffer (surface_actor, buffer);
|
||||
}
|
||||
|
||||
surface_process_damage (surface, pending->damage);
|
||||
|
||||
if (pending->opaque_region)
|
||||
meta_surface_actor_set_opaque_region (surface_actor, pending->opaque_region);
|
||||
if (pending->input_region)
|
||||
meta_surface_actor_set_input_region (surface_actor, pending->input_region);
|
||||
}
|
||||
|
||||
static void
|
||||
toplevel_surface_commit (MetaWaylandSurface *surface,
|
||||
MetaWaylandDoubleBufferedState *pending,
|
||||
gboolean buffer_changed)
|
||||
{
|
||||
actor_surface_commit (surface, pending, buffer_changed);
|
||||
|
||||
if (buffer_changed)
|
||||
{
|
||||
MetaWindow *window = surface->window;
|
||||
MetaWaylandBuffer *buffer = surface->pending.buffer;
|
||||
MetaWaylandBuffer *buffer = pending->buffer;
|
||||
|
||||
meta_window_set_surface_mapped (window, buffer != NULL);
|
||||
/* We resize X based surfaces according to X events */
|
||||
@@ -293,37 +331,185 @@ toplevel_surface_commit (MetaWaylandSurface *surface)
|
||||
int new_width;
|
||||
int new_height;
|
||||
|
||||
new_width = surface->buffer_ref.buffer->width;
|
||||
new_height = surface->buffer_ref.buffer->height;
|
||||
new_width = surface->buffer->width;
|
||||
new_height = surface->buffer->height;
|
||||
if (new_width != window->rect.width ||
|
||||
new_height != window->rect.height ||
|
||||
surface->pending.dx != 0 ||
|
||||
surface->pending.dy != 0)
|
||||
meta_window_move_resize_wayland (window, new_width, new_height,
|
||||
surface->pending.dx, surface->pending.dy);
|
||||
pending->dx != 0 ||
|
||||
pending->dy != 0)
|
||||
meta_window_move_resize_wayland (window, new_width, new_height, pending->dx, pending->dy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
subsurface_surface_commit (MetaWaylandSurface *surface)
|
||||
surface_handle_pending_buffer_destroy (struct wl_listener *listener, void *data)
|
||||
{
|
||||
if (actor_surface_commit (surface))
|
||||
MetaWaylandDoubleBufferedState *state =
|
||||
wl_container_of (listener, state, buffer_destroy_listener);
|
||||
|
||||
state->buffer = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
double_buffered_state_init (MetaWaylandDoubleBufferedState *state)
|
||||
{
|
||||
state->newly_attached = FALSE;
|
||||
state->buffer = NULL;
|
||||
state->dx = 0;
|
||||
state->dy = 0;
|
||||
|
||||
state->damage = cairo_region_create ();
|
||||
state->buffer_destroy_listener.notify =
|
||||
surface_handle_pending_buffer_destroy;
|
||||
wl_list_init (&state->frame_callback_list);
|
||||
}
|
||||
|
||||
static void
|
||||
double_buffered_state_destroy (MetaWaylandDoubleBufferedState *state)
|
||||
{
|
||||
MetaWaylandFrameCallback *cb, *next;
|
||||
|
||||
g_clear_pointer (&state->damage, cairo_region_destroy);
|
||||
g_clear_pointer (&state->input_region, cairo_region_destroy);
|
||||
g_clear_pointer (&state->opaque_region, cairo_region_destroy);
|
||||
|
||||
if (state->buffer)
|
||||
wl_list_remove (&state->buffer_destroy_listener.link);
|
||||
wl_list_for_each_safe (cb, next, &state->frame_callback_list, link)
|
||||
wl_resource_destroy (cb->resource);
|
||||
}
|
||||
|
||||
static void
|
||||
double_buffered_state_reset (MetaWaylandDoubleBufferedState *state)
|
||||
{
|
||||
double_buffered_state_destroy (state);
|
||||
double_buffered_state_init (state);
|
||||
}
|
||||
|
||||
static void
|
||||
move_double_buffered_state (MetaWaylandDoubleBufferedState *from,
|
||||
MetaWaylandDoubleBufferedState *to)
|
||||
{
|
||||
if (from->buffer)
|
||||
wl_list_remove (&from->buffer_destroy_listener.link);
|
||||
|
||||
to->newly_attached = from->newly_attached;
|
||||
from->newly_attached = FALSE;
|
||||
|
||||
to->buffer = from->buffer;
|
||||
from->buffer = NULL;
|
||||
if (to->buffer)
|
||||
wl_signal_add (&to->buffer->destroy_signal, &to->buffer_destroy_listener);
|
||||
|
||||
to->dx = from->dx;
|
||||
to->dy = from->dy;
|
||||
from->dx = from->dy = 0;
|
||||
|
||||
empty_region (to->damage);
|
||||
cairo_region_union (to->damage, from->damage);
|
||||
empty_region (from->damage);
|
||||
|
||||
g_clear_pointer (&to->input_region, cairo_region_destroy);
|
||||
g_clear_pointer (&to->opaque_region, cairo_region_destroy);
|
||||
to->input_region = from->input_region;
|
||||
to->opaque_region = from->opaque_region;
|
||||
from->input_region = from->opaque_region = NULL;
|
||||
|
||||
wl_list_init (&to->frame_callback_list);
|
||||
wl_list_insert_list (&to->frame_callback_list, &from->frame_callback_list);
|
||||
wl_list_init (&from->frame_callback_list);
|
||||
}
|
||||
|
||||
static void
|
||||
subsurface_surface_commit (MetaWaylandSurface *surface,
|
||||
MetaWaylandDoubleBufferedState *pending,
|
||||
gboolean buffer_changed)
|
||||
{
|
||||
/*
|
||||
* If the sub-surface is in synchronous mode, post-pone the commit of its
|
||||
* state until the sub-surface parent commits.
|
||||
*
|
||||
* This is done by moving the various states (damage, input region, buffer
|
||||
* etc.) from the buffered state pending commit to the sub-surface's pending
|
||||
* buffered state.
|
||||
*
|
||||
* The sub-surface's pending buffered state will be committed to the
|
||||
* associated surface when its parent surface is committed, or if the user
|
||||
* issues a wl_subsurface.set_desync request.
|
||||
*/
|
||||
if (surface->sub.synchronous)
|
||||
{
|
||||
MetaSurfaceActor *surface_actor = surface->surface_actor;
|
||||
MetaWaylandBuffer *buffer = surface->pending.buffer;
|
||||
float x, y;
|
||||
|
||||
if (buffer != NULL)
|
||||
clutter_actor_show (CLUTTER_ACTOR (surface_actor));
|
||||
else
|
||||
clutter_actor_hide (CLUTTER_ACTOR (surface_actor));
|
||||
|
||||
clutter_actor_get_position (CLUTTER_ACTOR (surface_actor), &x, &y);
|
||||
x += surface->pending.dx;
|
||||
y += surface->pending.dy;
|
||||
clutter_actor_set_position (CLUTTER_ACTOR (surface_actor), x, y);
|
||||
move_double_buffered_state (pending, &surface->sub.pending_surface_state);
|
||||
}
|
||||
else
|
||||
{
|
||||
actor_surface_commit (surface, pending, buffer_changed);
|
||||
|
||||
if (buffer_changed)
|
||||
{
|
||||
MetaSurfaceActor *surface_actor = surface->surface_actor;
|
||||
MetaWaylandBuffer *buffer = pending->buffer;
|
||||
float x, y;
|
||||
|
||||
if (buffer != NULL)
|
||||
clutter_actor_show (CLUTTER_ACTOR (surface_actor));
|
||||
else
|
||||
clutter_actor_hide (CLUTTER_ACTOR (surface_actor));
|
||||
|
||||
clutter_actor_get_position (CLUTTER_ACTOR (surface_actor), &x, &y);
|
||||
x += pending->dx;
|
||||
y += pending->dy;
|
||||
clutter_actor_set_position (CLUTTER_ACTOR (surface_actor), x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
subsurface_parent_surface_committed (MetaWaylandSurface *surface);
|
||||
|
||||
static void
|
||||
parent_surface_committed (gpointer data, gpointer user_data)
|
||||
{
|
||||
subsurface_parent_surface_committed (data);
|
||||
}
|
||||
|
||||
static void
|
||||
commit_double_buffered_state (MetaWaylandSurface *surface,
|
||||
MetaWaylandDoubleBufferedState *pending)
|
||||
{
|
||||
MetaWaylandCompositor *compositor = surface->compositor;
|
||||
gboolean buffer_changed = FALSE;
|
||||
|
||||
/* wl_surface.attach */
|
||||
if (pending->newly_attached && surface->buffer != pending->buffer)
|
||||
{
|
||||
surface_set_buffer (surface, pending->buffer);
|
||||
buffer_changed = TRUE;
|
||||
}
|
||||
|
||||
if (surface == compositor->seat->cursor_surface)
|
||||
cursor_surface_commit (surface, pending, buffer_changed);
|
||||
else if (surface->window)
|
||||
toplevel_surface_commit (surface, pending, buffer_changed);
|
||||
else if (surface->subsurface.resource)
|
||||
subsurface_surface_commit (surface, pending, buffer_changed);
|
||||
|
||||
g_list_foreach (surface->subsurfaces,
|
||||
parent_surface_committed,
|
||||
NULL);
|
||||
|
||||
if (pending->buffer)
|
||||
{
|
||||
wl_list_remove (&pending->buffer_destroy_listener.link);
|
||||
pending->buffer = NULL;
|
||||
}
|
||||
|
||||
/* wl_surface.frame */
|
||||
wl_list_insert_list (&compositor->frame_callbacks, &pending->frame_callback_list);
|
||||
wl_list_init (&pending->frame_callback_list);
|
||||
|
||||
double_buffered_state_reset (pending);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -331,38 +517,12 @@ meta_wayland_surface_commit (struct wl_client *client,
|
||||
struct wl_resource *resource)
|
||||
{
|
||||
MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
|
||||
MetaWaylandCompositor *compositor;
|
||||
|
||||
/* X11 unmanaged window */
|
||||
if (!surface)
|
||||
return;
|
||||
|
||||
compositor = surface->compositor;
|
||||
|
||||
if (surface == compositor->seat->sprite)
|
||||
cursor_surface_commit (surface);
|
||||
else if (surface->window)
|
||||
toplevel_surface_commit (surface);
|
||||
else if (surface->subsurface.resource)
|
||||
subsurface_surface_commit (surface);
|
||||
|
||||
if (surface->pending.buffer)
|
||||
{
|
||||
wl_list_remove (&surface->pending.buffer_destroy_listener.link);
|
||||
surface->pending.buffer = NULL;
|
||||
}
|
||||
|
||||
surface->pending.dx = 0;
|
||||
surface->pending.dy = 0;
|
||||
surface->pending.newly_attached = FALSE;
|
||||
g_clear_pointer (&surface->pending.opaque_region, cairo_region_destroy);
|
||||
g_clear_pointer (&surface->pending.input_region, cairo_region_destroy);
|
||||
empty_region (surface->pending.damage);
|
||||
|
||||
/* wl_surface.frame */
|
||||
wl_list_insert_list (&compositor->frame_callbacks,
|
||||
&surface->pending.frame_callback_list);
|
||||
wl_list_init (&surface->pending.frame_callback_list);
|
||||
commit_double_buffered_state (surface, &surface->pending);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -398,28 +558,17 @@ static void
|
||||
meta_wayland_surface_free (MetaWaylandSurface *surface)
|
||||
{
|
||||
MetaWaylandCompositor *compositor = surface->compositor;
|
||||
MetaWaylandFrameCallback *cb, *next;
|
||||
|
||||
compositor->surfaces = g_list_remove (compositor->surfaces, surface);
|
||||
|
||||
meta_wayland_buffer_reference (&surface->buffer_ref, NULL);
|
||||
|
||||
if (surface->pending.buffer)
|
||||
wl_list_remove (&surface->pending.buffer_destroy_listener.link);
|
||||
|
||||
cairo_region_destroy (surface->pending.damage);
|
||||
|
||||
wl_list_for_each_safe (cb, next,
|
||||
&surface->pending.frame_callback_list, link)
|
||||
wl_resource_destroy (cb->resource);
|
||||
|
||||
meta_wayland_compositor_repick (compositor);
|
||||
|
||||
surface_set_buffer (surface, NULL);
|
||||
double_buffered_state_destroy (&surface->pending);
|
||||
g_object_unref (surface->surface_actor);
|
||||
|
||||
if (surface->resource)
|
||||
wl_resource_set_user_data (surface->resource, NULL);
|
||||
g_slice_free (MetaWaylandSurface, surface);
|
||||
|
||||
meta_wayland_compositor_repick (compositor);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -473,19 +622,9 @@ meta_wayland_surface_resource_destroy_cb (struct wl_resource *resource)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
surface_handle_pending_buffer_destroy (struct wl_listener *listener,
|
||||
void *data)
|
||||
{
|
||||
MetaWaylandSurface *surface =
|
||||
wl_container_of (listener, surface, pending.buffer_destroy_listener);
|
||||
|
||||
surface->pending.buffer = NULL;
|
||||
}
|
||||
|
||||
MetaWaylandSurface *
|
||||
meta_wayland_surface_create (MetaWaylandCompositor *compositor,
|
||||
struct wl_client *wayland_client,
|
||||
struct wl_client *client,
|
||||
guint32 id,
|
||||
guint32 version)
|
||||
{
|
||||
@@ -493,17 +632,13 @@ meta_wayland_surface_create (MetaWaylandCompositor *compositor,
|
||||
|
||||
surface->compositor = compositor;
|
||||
|
||||
surface->resource = wl_resource_create (wayland_client,
|
||||
&wl_surface_interface,
|
||||
version, id);
|
||||
surface->resource = wl_resource_create (client, &wl_surface_interface, version, id);
|
||||
wl_resource_set_implementation (surface->resource, &meta_wayland_surface_interface, surface,
|
||||
meta_wayland_surface_resource_destroy_cb);
|
||||
|
||||
surface->pending.damage = cairo_region_create ();
|
||||
double_buffered_state_init (&surface->pending);
|
||||
|
||||
surface->pending.buffer_destroy_listener.notify =
|
||||
surface_handle_pending_buffer_destroy;
|
||||
wl_list_init (&surface->pending.frame_callback_list);
|
||||
surface->buffer_destroy_listener.notify = surface_handle_buffer_destroy;
|
||||
|
||||
surface->surface_actor = g_object_ref_sink (meta_surface_actor_new ());
|
||||
return surface;
|
||||
@@ -513,7 +648,6 @@ static void
|
||||
destroy_surface_extension (MetaWaylandSurfaceExtension *extension)
|
||||
{
|
||||
wl_list_remove (&extension->surface_destroy_listener.link);
|
||||
extension->surface_destroy_listener.notify = NULL;
|
||||
extension->resource = NULL;
|
||||
}
|
||||
|
||||
@@ -543,17 +677,15 @@ create_surface_extension (MetaWaylandSurfaceExtension *extension,
|
||||
const void *implementation,
|
||||
wl_resource_destroy_func_t destructor)
|
||||
{
|
||||
struct wl_resource *resource;
|
||||
|
||||
if (extension->resource != NULL)
|
||||
return FALSE;
|
||||
|
||||
resource = wl_resource_create (client, interface, get_resource_version (master_resource, max_version), id);
|
||||
wl_resource_set_implementation (resource, implementation, extension, destructor);
|
||||
extension->resource = wl_resource_create (client, interface, get_resource_version (master_resource, max_version), id);
|
||||
wl_resource_set_implementation (extension->resource, implementation, extension, destructor);
|
||||
|
||||
extension->resource = resource;
|
||||
extension->surface_destroy_listener.notify = extension_handle_surface_destroy;
|
||||
wl_resource_add_destroy_listener (surface_resource, &extension->surface_destroy_listener);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -815,7 +947,7 @@ get_xdg_surface (struct wl_client *client,
|
||||
return;
|
||||
}
|
||||
|
||||
surface->window = meta_window_new_for_wayland (meta_get_display (), surface);
|
||||
surface->window = meta_window_wayland_new (meta_get_display (), surface);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -885,7 +1017,7 @@ get_xdg_popup (struct wl_client *client,
|
||||
return;
|
||||
}
|
||||
|
||||
surface->window = meta_window_new_for_wayland (meta_get_display (), surface);
|
||||
surface->window = meta_window_wayland_new (meta_get_display (), surface);
|
||||
surface->window->rect.x = parent_rect.x + x;
|
||||
surface->window->rect.y = parent_rect.y + y;
|
||||
surface->window->showing_for_first_time = FALSE;
|
||||
@@ -993,13 +1125,79 @@ bind_gtk_shell (struct wl_client *client,
|
||||
gtk_shell_send_capabilities (resource, GTK_SHELL_CAPABILITY_GLOBAL_APP_MENU);
|
||||
}
|
||||
|
||||
static void
|
||||
subsurface_parent_surface_committed (MetaWaylandSurface *surface)
|
||||
{
|
||||
MetaWaylandDoubleBufferedState *pending_surface_state = &surface->sub.pending_surface_state;
|
||||
|
||||
if (surface->sub.pending_pos)
|
||||
{
|
||||
clutter_actor_set_position (CLUTTER_ACTOR (surface->surface_actor),
|
||||
surface->sub.pending_x,
|
||||
surface->sub.pending_y);
|
||||
surface->sub.pending_pos = FALSE;
|
||||
}
|
||||
|
||||
if (surface->sub.pending_placement_ops)
|
||||
{
|
||||
GSList *it;
|
||||
for (it = surface->sub.pending_placement_ops; it; it = it->next)
|
||||
{
|
||||
MetaWaylandSubsurfacePlacementOp *op = it->data;
|
||||
ClutterActor *surface_actor;
|
||||
ClutterActor *parent_actor;
|
||||
ClutterActor *sibling_actor;
|
||||
|
||||
if (!op->sibling)
|
||||
{
|
||||
g_slice_free (MetaWaylandSubsurfacePlacementOp, op);
|
||||
continue;
|
||||
}
|
||||
|
||||
surface_actor = CLUTTER_ACTOR (surface->surface_actor);
|
||||
parent_actor = clutter_actor_get_parent (CLUTTER_ACTOR (surface->sub.parent));
|
||||
sibling_actor = CLUTTER_ACTOR (op->sibling->surface_actor);
|
||||
|
||||
switch (op->placement)
|
||||
{
|
||||
case META_WAYLAND_SUBSURFACE_PLACEMENT_ABOVE:
|
||||
clutter_actor_set_child_above_sibling (parent_actor, surface_actor, sibling_actor);
|
||||
break;
|
||||
case META_WAYLAND_SUBSURFACE_PLACEMENT_BELOW:
|
||||
clutter_actor_set_child_below_sibling (parent_actor, surface_actor, sibling_actor);
|
||||
break;
|
||||
}
|
||||
|
||||
wl_list_remove (&op->sibling_destroy_listener.link);
|
||||
g_slice_free (MetaWaylandSubsurfacePlacementOp, op);
|
||||
}
|
||||
|
||||
g_slist_free (surface->sub.pending_placement_ops);
|
||||
surface->sub.pending_placement_ops = NULL;
|
||||
}
|
||||
|
||||
if (surface->sub.synchronous)
|
||||
commit_double_buffered_state (surface, pending_surface_state);
|
||||
|
||||
double_buffered_state_reset (pending_surface_state);
|
||||
}
|
||||
|
||||
static void
|
||||
wl_subsurface_destructor (struct wl_resource *resource)
|
||||
{
|
||||
MetaWaylandSurfaceExtension *subsurface = wl_resource_get_user_data (resource);
|
||||
MetaWaylandSurface *surface = wl_container_of (subsurface, surface, subsurface);
|
||||
|
||||
unparent_actor (surface);
|
||||
if (surface->sub.parent)
|
||||
{
|
||||
wl_list_remove (&surface->sub.parent_destroy_listener.link);
|
||||
surface->sub.parent->subsurfaces =
|
||||
g_list_remove (surface->sub.parent->subsurfaces, surface);
|
||||
unparent_actor (surface);
|
||||
surface->sub.parent = NULL;
|
||||
}
|
||||
|
||||
double_buffered_state_destroy (&surface->sub.pending_surface_state);
|
||||
destroy_surface_extension (subsurface);
|
||||
}
|
||||
|
||||
@@ -1019,7 +1217,47 @@ wl_subsurface_set_position (struct wl_client *client,
|
||||
MetaWaylandSurfaceExtension *subsurface = wl_resource_get_user_data (resource);
|
||||
MetaWaylandSurface *surface = wl_container_of (subsurface, surface, subsurface);
|
||||
|
||||
clutter_actor_set_position (CLUTTER_ACTOR (surface->surface_actor), x, y);
|
||||
surface->sub.pending_x = x;
|
||||
surface->sub.pending_y = y;
|
||||
surface->sub.pending_pos = TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_valid_sibling (MetaWaylandSurface *surface, MetaWaylandSurface *sibling)
|
||||
{
|
||||
if (surface->sub.parent == sibling)
|
||||
return TRUE;
|
||||
if (surface->sub.parent == sibling->sub.parent)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
subsurface_handle_pending_sibling_destroyed (struct wl_listener *listener, void *data)
|
||||
{
|
||||
MetaWaylandSubsurfacePlacementOp *op =
|
||||
wl_container_of (listener, op, sibling_destroy_listener);
|
||||
|
||||
op->sibling = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
queue_subsurface_placement (MetaWaylandSurface *surface,
|
||||
MetaWaylandSurface *sibling,
|
||||
MetaWaylandSubsurfacePlacement placement)
|
||||
{
|
||||
MetaWaylandSubsurfacePlacementOp *op =
|
||||
g_slice_new (MetaWaylandSubsurfacePlacementOp);
|
||||
|
||||
op->placement = placement;
|
||||
op->sibling = sibling;
|
||||
op->sibling_destroy_listener.notify =
|
||||
subsurface_handle_pending_sibling_destroyed;
|
||||
wl_resource_add_destroy_listener (sibling->resource,
|
||||
&op->sibling_destroy_listener);
|
||||
|
||||
surface->sub.pending_placement_ops =
|
||||
g_slist_append (surface->sub.pending_placement_ops, op);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1027,16 +1265,22 @@ wl_subsurface_place_above (struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
struct wl_resource *sibling_resource)
|
||||
{
|
||||
ClutterActor *parent_actor;
|
||||
MetaWaylandSurfaceExtension *subsurface = wl_resource_get_user_data (resource);
|
||||
MetaWaylandSurface *surface = wl_container_of (subsurface, surface, subsurface);
|
||||
MetaWaylandSurface *sibling = wl_resource_get_user_data (sibling_resource);
|
||||
|
||||
parent_actor = clutter_actor_get_parent (CLUTTER_ACTOR (surface->surface_actor));
|
||||
if (!is_valid_sibling (surface, sibling))
|
||||
{
|
||||
wl_resource_post_error (resource, WL_SUBSURFACE_ERROR_BAD_SURFACE,
|
||||
"wl_subsurface::place_above: wl_surface@%d is "
|
||||
"not a valid parent or sibling",
|
||||
wl_resource_get_id (sibling->resource));
|
||||
return;
|
||||
}
|
||||
|
||||
clutter_actor_set_child_above_sibling (parent_actor,
|
||||
CLUTTER_ACTOR (surface->surface_actor),
|
||||
CLUTTER_ACTOR (sibling->surface_actor));
|
||||
queue_subsurface_placement (surface,
|
||||
sibling,
|
||||
META_WAYLAND_SUBSURFACE_PLACEMENT_ABOVE);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1044,30 +1288,49 @@ wl_subsurface_place_below (struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
struct wl_resource *sibling_resource)
|
||||
{
|
||||
ClutterActor *parent_actor;
|
||||
MetaWaylandSurfaceExtension *subsurface = wl_resource_get_user_data (resource);
|
||||
MetaWaylandSurface *surface = wl_container_of (subsurface, surface, subsurface);
|
||||
MetaWaylandSurface *sibling = wl_resource_get_user_data (sibling_resource);
|
||||
|
||||
parent_actor = clutter_actor_get_parent (CLUTTER_ACTOR (surface->surface_actor));
|
||||
if (!is_valid_sibling (surface, sibling))
|
||||
{
|
||||
wl_resource_post_error (resource, WL_SUBSURFACE_ERROR_BAD_SURFACE,
|
||||
"wl_subsurface::place_below: wl_surface@%d is "
|
||||
"not a valid parent or sibling",
|
||||
wl_resource_get_id (sibling->resource));
|
||||
return;
|
||||
}
|
||||
|
||||
clutter_actor_set_child_below_sibling (parent_actor,
|
||||
CLUTTER_ACTOR (surface->surface_actor),
|
||||
CLUTTER_ACTOR (sibling->surface_actor));
|
||||
queue_subsurface_placement (surface,
|
||||
sibling,
|
||||
META_WAYLAND_SUBSURFACE_PLACEMENT_BELOW);
|
||||
}
|
||||
|
||||
static void
|
||||
wl_subsurface_set_sync (struct wl_client *client,
|
||||
struct wl_resource *resource)
|
||||
{
|
||||
g_warning ("TODO: support wl_subsurface.set_sync");
|
||||
MetaWaylandSurfaceExtension *subsurface =
|
||||
wl_resource_get_user_data (resource);
|
||||
MetaWaylandSurface *surface =
|
||||
wl_container_of (subsurface, surface, subsurface);
|
||||
|
||||
surface->sub.synchronous = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
wl_subsurface_set_desync (struct wl_client *client,
|
||||
struct wl_resource *resource)
|
||||
{
|
||||
g_warning ("TODO: support wl_subsurface.set_desync");
|
||||
MetaWaylandSurfaceExtension *subsurface =
|
||||
wl_resource_get_user_data (resource);
|
||||
MetaWaylandSurface *surface =
|
||||
wl_container_of (subsurface, surface, subsurface);
|
||||
|
||||
if (surface->sub.synchronous)
|
||||
subsurface_parent_surface_committed (surface);
|
||||
|
||||
surface->sub.synchronous = FALSE;
|
||||
}
|
||||
|
||||
static const struct wl_subsurface_interface meta_wayland_subsurface_interface = {
|
||||
@@ -1086,6 +1349,18 @@ wl_subcompositor_destroy (struct wl_client *client,
|
||||
wl_resource_destroy (resource);
|
||||
}
|
||||
|
||||
static void
|
||||
surface_handle_parent_surface_destroyed (struct wl_listener *listener,
|
||||
void *data)
|
||||
{
|
||||
MetaWaylandSurface *surface = wl_container_of (listener,
|
||||
surface,
|
||||
sub.parent_destroy_listener);
|
||||
|
||||
surface->sub.parent = NULL;
|
||||
unparent_actor (surface);
|
||||
}
|
||||
|
||||
static void
|
||||
wl_subcompositor_get_subsurface (struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
@@ -1108,6 +1383,14 @@ wl_subcompositor_get_subsurface (struct wl_client *client,
|
||||
return;
|
||||
}
|
||||
|
||||
double_buffered_state_init (&surface->sub.pending_surface_state);
|
||||
surface->sub.parent = parent;
|
||||
surface->sub.parent_destroy_listener.notify =
|
||||
surface_handle_parent_surface_destroyed;
|
||||
wl_resource_add_destroy_listener (parent->resource,
|
||||
&surface->sub.parent_destroy_listener);
|
||||
parent->subsurfaces = g_list_append (parent->subsurfaces, surface);
|
||||
|
||||
clutter_actor_add_child (CLUTTER_ACTOR (parent->surface_actor),
|
||||
CLUTTER_ACTOR (surface->surface_actor));
|
||||
}
|
||||
|
@@ -39,13 +39,7 @@ struct _MetaWaylandBuffer
|
||||
|
||||
CoglTexture *texture;
|
||||
int32_t width, height;
|
||||
uint32_t busy_count;
|
||||
};
|
||||
|
||||
struct _MetaWaylandBufferReference
|
||||
{
|
||||
MetaWaylandBuffer *buffer;
|
||||
struct wl_listener destroy_listener;
|
||||
uint32_t ref_count;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
@@ -77,7 +71,6 @@ struct _MetaWaylandSurface
|
||||
{
|
||||
struct wl_resource *resource;
|
||||
MetaWaylandCompositor *compositor;
|
||||
MetaWaylandBufferReference buffer_ref;
|
||||
MetaSurfaceActor *surface_actor;
|
||||
MetaWindow *window;
|
||||
MetaWaylandSurfaceExtension xdg_surface;
|
||||
@@ -85,6 +78,24 @@ struct _MetaWaylandSurface
|
||||
MetaWaylandSurfaceExtension gtk_surface;
|
||||
MetaWaylandSurfaceExtension subsurface;
|
||||
|
||||
MetaWaylandBuffer *buffer;
|
||||
struct wl_listener buffer_destroy_listener;
|
||||
|
||||
GList *subsurfaces;
|
||||
|
||||
struct {
|
||||
MetaWaylandSurface *parent;
|
||||
struct wl_listener parent_destroy_listener;
|
||||
|
||||
gboolean synchronous;
|
||||
MetaWaylandDoubleBufferedState pending_surface_state;
|
||||
|
||||
int32_t pending_x;
|
||||
int32_t pending_y;
|
||||
gboolean pending_pos;
|
||||
GSList *pending_placement_ops;
|
||||
} sub;
|
||||
|
||||
/* All the pending state, that wl_surface.commit will apply. */
|
||||
MetaWaylandDoubleBufferedState pending;
|
||||
};
|
||||
|
@@ -138,6 +138,24 @@ meta_wayland_buffer_destroy_handler (struct wl_listener *listener,
|
||||
g_slice_free (MetaWaylandBuffer, buffer);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_buffer_ref (MetaWaylandBuffer *buffer)
|
||||
{
|
||||
buffer->ref_count++;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_buffer_unref (MetaWaylandBuffer *buffer)
|
||||
{
|
||||
buffer->ref_count--;
|
||||
if (buffer->ref_count == 0)
|
||||
{
|
||||
g_clear_pointer (&buffer->texture, cogl_object_unref);
|
||||
g_assert (wl_resource_get_client (buffer->resource));
|
||||
wl_resource_queue_event (buffer->resource, WL_BUFFER_RELEASE);
|
||||
}
|
||||
}
|
||||
|
||||
MetaWaylandBuffer *
|
||||
meta_wayland_buffer_from_resource (struct wl_resource *resource)
|
||||
{
|
||||
@@ -165,46 +183,6 @@ meta_wayland_buffer_from_resource (struct wl_resource *resource)
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_buffer_reference_handle_destroy (struct wl_listener *listener,
|
||||
void *data)
|
||||
{
|
||||
MetaWaylandBufferReference *ref =
|
||||
wl_container_of (listener, ref, destroy_listener);
|
||||
|
||||
g_assert (data == ref->buffer);
|
||||
|
||||
ref->buffer = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_buffer_reference (MetaWaylandBufferReference *ref,
|
||||
MetaWaylandBuffer *buffer)
|
||||
{
|
||||
if (ref->buffer && buffer != ref->buffer)
|
||||
{
|
||||
ref->buffer->busy_count--;
|
||||
|
||||
if (ref->buffer->busy_count == 0)
|
||||
{
|
||||
g_clear_pointer (&ref->buffer->texture, cogl_object_unref);
|
||||
g_assert (wl_resource_get_client (ref->buffer->resource));
|
||||
wl_resource_queue_event (ref->buffer->resource, WL_BUFFER_RELEASE);
|
||||
}
|
||||
|
||||
wl_list_remove (&ref->destroy_listener.link);
|
||||
}
|
||||
|
||||
if (buffer && buffer != ref->buffer)
|
||||
{
|
||||
buffer->busy_count++;
|
||||
wl_signal_add (&buffer->destroy_signal, &ref->destroy_listener);
|
||||
}
|
||||
|
||||
ref->buffer = buffer;
|
||||
ref->destroy_listener.notify = meta_wayland_buffer_reference_handle_destroy;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_compositor_set_input_focus (MetaWaylandCompositor *compositor,
|
||||
MetaWindow *window)
|
||||
@@ -505,8 +483,7 @@ meta_wayland_compositor_paint_finished (MetaWaylandCompositor *compositor)
|
||||
MetaWaylandFrameCallback *callback =
|
||||
wl_container_of (compositor->frame_callbacks.next, callback, link);
|
||||
|
||||
wl_resource_post_event (callback->resource,
|
||||
WL_CALLBACK_DONE, get_time ());
|
||||
wl_callback_send_done (callback->resource, get_time ());
|
||||
wl_resource_destroy (callback->resource);
|
||||
}
|
||||
}
|
||||
@@ -687,7 +664,7 @@ meta_wayland_init (void)
|
||||
clutter_wayland_set_compositor_display (compositor->wayland_display);
|
||||
|
||||
if (getenv ("WESTON_LAUNCHER_SOCK"))
|
||||
compositor->launcher = meta_launcher_new ();
|
||||
compositor->launcher = meta_launcher_new ();
|
||||
|
||||
if (clutter_init (NULL, NULL) != CLUTTER_INIT_SUCCESS)
|
||||
g_error ("Failed to initialize Clutter");
|
||||
@@ -761,7 +738,9 @@ meta_wayland_finalize (void)
|
||||
compositor = meta_wayland_compositor_get_default ();
|
||||
|
||||
meta_xwayland_stop (compositor);
|
||||
meta_launcher_free (compositor->launcher);
|
||||
|
||||
if (compositor->launcher)
|
||||
meta_launcher_free (compositor->launcher);
|
||||
}
|
||||
|
||||
gboolean
|
||||
@@ -769,3 +748,19 @@ meta_wayland_compositor_is_native (MetaWaylandCompositor *compositor)
|
||||
{
|
||||
return compositor->native;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_wayland_compositor_activate_vt (MetaWaylandCompositor *compositor,
|
||||
int vt,
|
||||
GError **error)
|
||||
{
|
||||
if (compositor->launcher)
|
||||
{
|
||||
return meta_launcher_activate_vt (compositor->launcher, vt, error);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_debug ("Ignoring VT switch keybinding, not running as VT manager");
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
@@ -385,3 +385,17 @@ meta_launcher_free (MetaLauncher *launcher)
|
||||
|
||||
g_slice_free (MetaLauncher, launcher);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_launcher_activate_vt (MetaLauncher *launcher,
|
||||
int vt,
|
||||
GError **error)
|
||||
{
|
||||
struct weston_launcher_activate_vt message;
|
||||
|
||||
message.header.opcode = WESTON_LAUNCHER_ACTIVATE_VT;
|
||||
message.vt = vt;
|
||||
|
||||
return send_message_to_wl (launcher, &message, sizeof (message), NULL, NULL, error);
|
||||
}
|
||||
|
||||
|
@@ -28,6 +28,10 @@ typedef struct _MetaLauncher MetaLauncher;
|
||||
MetaLauncher *meta_launcher_new (void);
|
||||
void meta_launcher_free (MetaLauncher *self);
|
||||
|
||||
gboolean meta_launcher_activate_vt (MetaLauncher *self,
|
||||
int number,
|
||||
GError **error);
|
||||
|
||||
gboolean meta_launcher_set_drm_fd (MetaLauncher *self,
|
||||
int drm_fd,
|
||||
GError **error);
|
||||
|
@@ -44,15 +44,17 @@ xserver_set_window_id (struct wl_client *client,
|
||||
MetaWindow *window;
|
||||
|
||||
window = meta_display_lookup_x_window (display, xid);
|
||||
if (window)
|
||||
{
|
||||
surface->window = window;
|
||||
window->surface = surface;
|
||||
}
|
||||
if (!window)
|
||||
return;
|
||||
|
||||
surface->window = window;
|
||||
window->surface = surface;
|
||||
|
||||
meta_window_set_surface_mapped (window, TRUE);
|
||||
}
|
||||
|
||||
static const struct xserver_interface xserver_implementation = {
|
||||
xserver_set_window_id
|
||||
xserver_set_window_id
|
||||
};
|
||||
|
||||
static void
|
||||
@@ -73,13 +75,8 @@ bind_xserver (struct wl_client *client,
|
||||
wl_resource_set_implementation (compositor->xserver_resource,
|
||||
&xserver_implementation, compositor, NULL);
|
||||
|
||||
wl_resource_post_event (compositor->xserver_resource,
|
||||
XSERVER_LISTEN_SOCKET,
|
||||
compositor->xwayland_abstract_fd);
|
||||
|
||||
wl_resource_post_event (compositor->xserver_resource,
|
||||
XSERVER_LISTEN_SOCKET,
|
||||
compositor->xwayland_unix_fd);
|
||||
xserver_send_listen_socket (compositor->xserver_resource, compositor->xwayland_abstract_fd);
|
||||
xserver_send_listen_socket (compositor->xserver_resource, compositor->xwayland_unix_fd);
|
||||
|
||||
/* Make sure xwayland will recieve the above sockets in a finite
|
||||
* time before unblocking the initialization mainloop since we are
|
||||
@@ -123,7 +120,7 @@ create_lockfile (int display, int *display_out)
|
||||
/* ignore error and try the next display number */
|
||||
display++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
close (fd);
|
||||
|
||||
other = strtol (pid, &end, 0);
|
||||
@@ -135,7 +132,7 @@ create_lockfile (int display, int *display_out)
|
||||
/* ignore error and try the next display number */
|
||||
display++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (kill (other, 0) < 0 && errno == ESRCH)
|
||||
{
|
||||
@@ -148,7 +145,7 @@ create_lockfile (int display, int *display_out)
|
||||
}
|
||||
g_free (filename);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
g_free (filename);
|
||||
display++;
|
||||
@@ -240,11 +237,12 @@ bind_to_unix_socket (int display)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (listen (fd, 1) < 0) {
|
||||
if (listen (fd, 1) < 0)
|
||||
{
|
||||
unlink (addr.sun_path);
|
||||
close (fd);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
@@ -310,8 +308,8 @@ meta_xwayland_start (MetaWaylandCompositor *compositor)
|
||||
lockfile = create_lockfile (display, &display);
|
||||
if (!lockfile)
|
||||
{
|
||||
g_warning ("Failed to create an X lock file");
|
||||
return FALSE;
|
||||
g_warning ("Failed to create an X lock file");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
compositor->xwayland_abstract_fd = bind_to_abstract_socket (display);
|
||||
|
@@ -269,6 +269,40 @@ out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
handle_activate_vt(struct weston_launch *wl, struct msghdr *msg, ssize_t len)
|
||||
{
|
||||
struct weston_launcher_reply reply;
|
||||
struct weston_launcher_activate_vt *message;
|
||||
|
||||
reply.header.opcode = WESTON_LAUNCHER_ACTIVATE_VT;
|
||||
reply.ret = -1;
|
||||
|
||||
if (len != sizeof(*message)) {
|
||||
error(0, 0, "missing value in activate_vt request");
|
||||
goto out;
|
||||
}
|
||||
|
||||
message = msg->msg_iov->iov_base;
|
||||
|
||||
reply.ret = ioctl(wl->tty, VT_ACTIVATE, message->vt);
|
||||
if (reply.ret < 0)
|
||||
reply.ret = -errno;
|
||||
|
||||
if (wl->verbose)
|
||||
fprintf(stderr, "mutter-launch: activate VT, ret: %d\n", reply.ret);
|
||||
|
||||
out:
|
||||
do {
|
||||
len = send(wl->sock[0], &reply, sizeof reply, 0);
|
||||
} while (len < 0 && errno == EINTR);
|
||||
if (len < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
handle_open(struct weston_launch *wl, struct msghdr *msg, ssize_t len)
|
||||
{
|
||||
@@ -385,6 +419,9 @@ handle_socket_msg(struct weston_launch *wl)
|
||||
case WESTON_LAUNCHER_CONFIRM_VT_SWITCH:
|
||||
ret = handle_confirm_vt_switch(wl, &msg, len);
|
||||
break;
|
||||
case WESTON_LAUNCHER_ACTIVATE_VT:
|
||||
ret = handle_activate_vt(wl, &msg, len);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@@ -32,7 +32,8 @@ enum weston_launcher_message_type {
|
||||
enum weston_launcher_opcode {
|
||||
WESTON_LAUNCHER_OPEN = (1 << 1 | WESTON_LAUNCHER_REQUEST),
|
||||
WESTON_LAUNCHER_DRM_SET_FD = (2 << 1 | WESTON_LAUNCHER_REQUEST),
|
||||
WESTON_LAUNCHER_CONFIRM_VT_SWITCH = (3 << 1 | WESTON_LAUNCHER_REQUEST),
|
||||
WESTON_LAUNCHER_ACTIVATE_VT = (3 << 1 | WESTON_LAUNCHER_REQUEST),
|
||||
WESTON_LAUNCHER_CONFIRM_VT_SWITCH = (4 << 1 | WESTON_LAUNCHER_REQUEST),
|
||||
};
|
||||
|
||||
enum weston_launcher_server_opcode {
|
||||
|
Reference in New Issue
Block a user