Compare commits

..

1 Commits

Author SHA1 Message Date
Jasper St. Pierre
2afbf369af double-buffer place_above/place_below 2014-01-15 20:05:31 -05:00
39 changed files with 2283 additions and 2455 deletions

25
NEWS
View File

@@ -1,28 +1,3 @@
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]

View File

@@ -3,7 +3,7 @@ AC_CONFIG_MACRO_DIR([m4])
m4_define([mutter_major_version], [3])
m4_define([mutter_minor_version], [11])
m4_define([mutter_micro_version], [5])
m4_define([mutter_micro_version], [3])
m4_define([mutter_version],
[mutter_major_version.mutter_minor_version.mutter_micro_version])

View File

@@ -163,8 +163,6 @@ 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 \

View File

@@ -46,8 +46,11 @@ struct _MetaCompScreen
CoglFrameClosure *frame_closure;
/* Used for unredirecting fullscreen windows */
guint disable_unredirect_count;
MetaWindow *unredirected_window;
guint disable_unredirect_count;
MetaWindowActor *unredirected_window;
/* Before we create the output window */
XserverRegion pending_input_region;
gint switch_workspace_in_progress;

View File

@@ -283,6 +283,25 @@ meta_get_window_actors (MetaScreen *screen)
return info->windows;
}
static void
do_set_stage_input_region (MetaScreen *screen,
XserverRegion region)
{
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
MetaDisplay *display = meta_screen_get_display (screen);
Display *xdpy = meta_display_get_xdisplay (display);
Window xstage = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage));
XFixesSetWindowShapeRegion (xdpy, xstage, ShapeInput, 0, 0, region);
/* It's generally a good heuristic that when a crossing event is generated because
* we reshape the overlay, we don't want it to affect focus-follows-mouse focus -
* it's not the user doing something, it's the environment changing under the user.
*/
meta_display_add_ignored_crossing_serial (display, XNextRequest (xdpy));
XFixesSetWindowShapeRegion (xdpy, info->output, ShapeInput, 0, 0, region);
}
void
meta_set_stage_input_region (MetaScreen *screen,
XserverRegion region)
@@ -294,19 +313,29 @@ meta_set_stage_input_region (MetaScreen *screen,
*/
if (!meta_is_wayland_compositor ())
{
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
MetaDisplay *display = meta_screen_get_display (screen);
Display *xdpy = meta_display_get_xdisplay (display);
Window xstage = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage));
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
MetaDisplay *display = meta_screen_get_display (screen);
Display *xdpy = meta_display_get_xdisplay (display);
XFixesSetWindowShapeRegion (xdpy, xstage, ShapeInput, 0, 0, region);
/* It's generally a good heuristic that when a crossing event is generated because
* we reshape the overlay, we don't want it to affect focus-follows-mouse focus -
* it's not the user doing something, it's the environment changing under the user.
*/
meta_display_add_ignored_crossing_serial (display, XNextRequest (xdpy));
XFixesSetWindowShapeRegion (xdpy, info->output, ShapeInput, 0, 0, region);
if (info->stage && info->output)
{
do_set_stage_input_region (screen, region);
}
else
{
/* Reset info->pending_input_region if one existed before and set the new
* one to use it later. */
if (info->pending_input_region)
{
XFixesDestroyRegion (xdpy, info->pending_input_region);
info->pending_input_region = None;
}
if (region != None)
{
info->pending_input_region = XFixesCreateRegion (xdpy, NULL, 0);
XFixesCopyRegion (xdpy, info->pending_input_region, region);
}
}
}
}
@@ -648,6 +677,21 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
return;
info = g_new0 (MetaCompScreen, 1);
/*
* We use an empty input region for Clutter as a default because that allows
* the user to interact with all the windows displayed on the screen.
* We have to initialize info->pending_input_region to an empty region explicitly,
* because None value is used to mean that the whole screen is an input region.
*/
if (!meta_is_wayland_compositor ())
info->pending_input_region = XFixesCreateRegion (xdisplay, NULL, 0);
else
{
/* Stage input region trickery isn't needed when we're running as a
* wayland compositor. */
info->pending_input_region = None;
}
info->screen = screen;
meta_screen_set_compositor_data (screen, info);
@@ -733,8 +777,6 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
info->output = get_output_window (screen);
XReparentWindow (xdisplay, xwin, info->output, 0, 0);
meta_empty_stage_input_region (screen);
/* Make sure there isn't any left-over output shape on the
* overlay window by setting the whole screen to be an
* output region.
@@ -745,6 +787,13 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
*/
XFixesSetWindowShapeRegion (xdisplay, info->output, ShapeBounding, 0, 0, None);
do_set_stage_input_region (screen, info->pending_input_region);
if (info->pending_input_region != None)
{
XFixesDestroyRegion (xdisplay, info->pending_input_region);
info->pending_input_region = None;
}
/* Map overlay window before redirecting windows offscreen so we catch their
* contents until we show the stage.
*/
@@ -814,30 +863,6 @@ meta_shape_cow_for_window (MetaScreen *screen,
}
}
static void
set_unredirected_window (MetaCompScreen *info,
MetaWindow *window)
{
if (info->unredirected_window == window)
return;
if (info->unredirected_window != NULL)
{
MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (info->unredirected_window));
meta_window_actor_set_unredirected (window_actor, FALSE);
}
info->unredirected_window = window;
if (info->unredirected_window != NULL)
{
MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (info->unredirected_window));
meta_window_actor_set_unredirected (window_actor, TRUE);
}
meta_shape_cow_for_window (info->screen, info->unredirected_window);
}
void
meta_compositor_add_window (MetaCompositor *compositor,
MetaWindow *window)
@@ -866,11 +891,19 @@ meta_compositor_remove_window (MetaCompositor *compositor,
if (!window_actor)
return;
screen = meta_window_get_screen (window);
info = meta_screen_get_compositor_data (screen);
if (!meta_is_wayland_compositor ())
{
screen = meta_window_get_screen (window);
info = meta_screen_get_compositor_data (screen);
if (info->unredirected_window == window)
set_unredirected_window (info, NULL);
if (window_actor == info->unredirected_window)
{
meta_window_actor_set_redirected (window_actor, TRUE);
meta_shape_cow_for_window (meta_window_get_screen (meta_window_actor_get_meta_window (info->unredirected_window)),
NULL);
info->unredirected_window = NULL;
}
}
meta_window_actor_destroy (window_actor);
}
@@ -1500,6 +1533,7 @@ pre_paint_windows (MetaCompScreen *info)
{
GList *l;
MetaWindowActor *top_window;
MetaWindowActor *expected_unredirected_window = NULL;
if (info->onscreen == NULL)
{
@@ -1513,13 +1547,33 @@ pre_paint_windows (MetaCompScreen *info)
if (info->windows == NULL)
return;
top_window = g_list_last (info->windows)->data;
if (!meta_is_wayland_compositor ())
{
top_window = g_list_last (info->windows)->data;
if (meta_window_actor_should_unredirect (top_window) &&
info->disable_unredirect_count == 0)
set_unredirected_window (info, meta_window_actor_get_meta_window (top_window));
else
set_unredirected_window (info, NULL);
if (meta_window_actor_should_unredirect (top_window) &&
info->disable_unredirect_count == 0)
expected_unredirected_window = top_window;
if (info->unredirected_window != expected_unredirected_window)
{
if (info->unredirected_window != NULL)
{
meta_window_actor_set_redirected (info->unredirected_window, TRUE);
meta_shape_cow_for_window (meta_window_get_screen (meta_window_actor_get_meta_window (info->unredirected_window)),
NULL);
}
if (expected_unredirected_window != NULL)
{
meta_shape_cow_for_window (meta_window_get_screen (meta_window_actor_get_meta_window (top_window)),
meta_window_actor_get_meta_window (top_window));
meta_window_actor_set_redirected (top_window, FALSE);
}
info->unredirected_window = expected_unredirected_window;
}
}
for (l = info->windows; l; l = l->next)
meta_window_actor_pre_paint (l->data);

View File

@@ -605,8 +605,8 @@ get_clip (MetaShapedTexture *stex,
ClutterActor *self = CLUTTER_ACTOR (stex);
MetaShapedTexturePrivate *priv;
ClutterActorBox allocation;
double scale_x;
double scale_y;
float scale_x;
float 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

View File

@@ -24,6 +24,8 @@ struct _MetaSurfaceActorPrivate
{
MetaShapedTexture *texture;
MetaWaylandBuffer *buffer;
GSList *ops;
};
static void cullable_iface_init (MetaCullableInterface *iface);
@@ -31,9 +33,23 @@ static void cullable_iface_init (MetaCullableInterface *iface);
G_DEFINE_TYPE_WITH_CODE (MetaSurfaceActor, meta_surface_actor, CLUTTER_TYPE_ACTOR,
G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init));
static void meta_surface_actor_free_ops (MetaSurfaceActor *self);
static void
meta_surface_actor_dispose (GObject *object)
{
MetaSurfaceActor *self = META_SURFACE_ACTOR (object);
meta_surface_actor_free_ops (self);
}
static void
meta_surface_actor_class_init (MetaSurfaceActorClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = meta_surface_actor_dispose;
g_type_class_add_private (klass, sizeof (MetaSurfaceActorPrivate));
}
@@ -181,3 +197,127 @@ meta_surface_actor_new (void)
{
return g_object_new (META_TYPE_SURFACE_ACTOR, NULL);
}
typedef enum {
OP_SET_POSITION,
OP_PLACE_ABOVE,
OP_PLACE_BELOW,
} MetaSurfaceActorOpType;
typedef struct {
MetaSurfaceActorOpType type;
} MetaSurfaceActorOp;
typedef struct {
MetaSurfaceActorOpType type;
ClutterActor *subsurface;
int32_t x;
int32_t y;
} MetaSurfaceActorOp_SetPosition;
typedef struct {
MetaSurfaceActorOpType type;
ClutterActor *subsurface;
ClutterActor *sibling;
} MetaSurfaceActorOp_Stack;
void
meta_surface_actor_subsurface_set_position (MetaSurfaceActor *self,
MetaSurfaceActor *subsurface,
int32_t x,
int32_t y)
{
MetaSurfaceActorPrivate *priv = self->priv;
MetaSurfaceActorOp_SetPosition *op = g_slice_new0 (MetaSurfaceActorOp_SetPosition);
op->type = OP_SET_POSITION;
op->subsurface = CLUTTER_ACTOR (subsurface);
op->x = x;
op->y = y;
priv->ops = g_slist_append (priv->ops, op);
}
static void
meta_surface_actor_stack_op (MetaSurfaceActor *self,
MetaSurfaceActorOpType type,
MetaSurfaceActor *subsurface,
MetaSurfaceActor *sibling)
{
MetaSurfaceActorPrivate *priv = self->priv;
MetaSurfaceActorOp_Stack *op = g_slice_new0 (MetaSurfaceActorOp_Stack);
op->type = type;
op->subsurface = CLUTTER_ACTOR (subsurface);
op->sibling = CLUTTER_ACTOR (sibling);
priv->ops = g_slist_append (priv->ops, op);
}
void
meta_surface_actor_subsurface_place_above (MetaSurfaceActor *self,
MetaSurfaceActor *subsurface,
MetaSurfaceActor *sibling)
{
meta_surface_actor_stack_op (self, OP_PLACE_ABOVE, subsurface, sibling);
}
void
meta_surface_actor_subsurface_place_below (MetaSurfaceActor *self,
MetaSurfaceActor *subsurface,
MetaSurfaceActor *sibling)
{
meta_surface_actor_stack_op (self, OP_PLACE_BELOW, subsurface, sibling);
}
static void
meta_surface_actor_do_op (MetaSurfaceActor *self,
MetaSurfaceActorOp *op)
{
MetaSurfaceActorOp_SetPosition *op_pos = (MetaSurfaceActorOp_SetPosition *) op;
MetaSurfaceActorOp_Stack *op_stack = (MetaSurfaceActorOp_Stack *) op;
switch (op->type)
{
case OP_SET_POSITION:
clutter_actor_set_position (op_pos->subsurface, op_pos->x, op_pos->y);
break;
case OP_PLACE_ABOVE:
clutter_actor_set_child_above_sibling (CLUTTER_ACTOR (self), op_stack->subsurface, op_stack->sibling);
break;
case OP_PLACE_BELOW:
clutter_actor_set_child_below_sibling (CLUTTER_ACTOR (self), op_stack->subsurface, op_stack->sibling);
break;
}
}
static void
meta_surface_actor_op_free (MetaSurfaceActorOp *op)
{
g_slice_free (MetaSurfaceActorOp, op);
}
static void
meta_surface_actor_free_ops (MetaSurfaceActor *self)
{
MetaSurfaceActorPrivate *priv = self->priv;
g_slist_free_full (priv->ops, (GDestroyNotify) meta_surface_actor_op_free);
priv->ops = NULL;
}
static void
meta_surface_actor_do_ops (MetaSurfaceActor *self)
{
MetaSurfaceActorPrivate *priv = self->priv;
GSList *l;
for (l = priv->ops; l; l = l->next)
meta_surface_actor_do_op (self, ((MetaSurfaceActorOp *) l->data));
}
void
meta_surface_actor_commit (MetaSurfaceActor *self)
{
meta_surface_actor_do_ops (self);
}

View File

@@ -62,6 +62,18 @@ void meta_surface_actor_set_input_region (MetaSurfaceActor *self,
void meta_surface_actor_set_opaque_region (MetaSurfaceActor *self,
cairo_region_t *region);
void meta_surface_actor_subsurface_set_position (MetaSurfaceActor *self,
MetaSurfaceActor *subsurface,
int32_t x,
int32_t y);
void meta_surface_actor_subsurface_place_above (MetaSurfaceActor *self,
MetaSurfaceActor *subsurface,
MetaSurfaceActor *sibling);
void meta_surface_actor_subsurface_place_below (MetaSurfaceActor *self,
MetaSurfaceActor *subsurface,
MetaSurfaceActor *sibling);
void meta_surface_actor_commit (MetaSurfaceActor *self);
G_END_DECLS
#endif /* META_SURFACE_ACTOR_PRIVATE_H */

View File

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

View File

@@ -721,7 +721,7 @@ meta_window_actor_get_paint_volume (ClutterActor *actor,
gdk_rectangle_union (&bounds, &shadow_bounds, &bounds);
}
if (priv->unobscured_region && !clutter_actor_has_mapped_clones (actor))
if (priv->unobscured_region)
{
cairo_rectangle_int_t unobscured_bounds;
cairo_region_get_extents (priv->unobscured_region, &unobscured_bounds);
@@ -860,6 +860,59 @@ 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)
{
@@ -1268,9 +1321,6 @@ 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;
@@ -1292,15 +1342,14 @@ meta_window_actor_should_unredirect (MetaWindowActor *self)
if (meta_window_is_override_redirect (metaWindow))
return TRUE;
if (priv->does_full_damage)
if (!meta_is_wayland_compositor () && priv->does_full_damage)
return TRUE;
return FALSE;
}
void
meta_window_actor_set_unredirected (MetaWindowActor *self,
gboolean unredirected)
meta_window_actor_set_redirected (MetaWindowActor *self, gboolean state)
{
MetaWindow *metaWindow = meta_window_actor_get_meta_window (self);
MetaDisplay *display = meta_window_get_display (metaWindow);
@@ -1308,20 +1357,21 @@ meta_window_actor_set_unredirected (MetaWindowActor *self,
Display *xdisplay = meta_display_get_xdisplay (display);
Window xwin = meta_window_get_toplevel_xwindow (metaWindow);
meta_error_trap_push (display);
if (unredirected)
if (state)
{
XCompositeUnredirectWindow (xdisplay, xwin, CompositeRedirectManual);
meta_error_trap_push (display);
XCompositeRedirectWindow (xdisplay, xwin, CompositeRedirectManual);
meta_error_trap_pop (display);
meta_window_actor_detach_x11_pixmap (self);
self->priv->unredirected = FALSE;
}
else
{
XCompositeRedirectWindow (xdisplay, xwin, CompositeRedirectManual);
meta_window_actor_detach_x11_pixmap (self);
meta_error_trap_push (display);
XCompositeUnredirectWindow (xdisplay, xwin, CompositeRedirectManual);
meta_error_trap_pop (display);
self->priv->unredirected = TRUE;
}
self->priv->unredirected = unredirected;
meta_error_trap_pop (display);
}
void
@@ -1338,12 +1388,6 @@ 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
@@ -1761,11 +1805,15 @@ meta_window_actor_cull_out (MetaCullable *cullable,
cairo_region_t *clip_region)
{
MetaWindowActor *self = META_WINDOW_ACTOR (cullable);
MetaWindowActorPrivate *priv = self->priv;
/* Don't do any culling for the unredirected window */
if (priv->unredirected)
return;
if (!meta_is_wayland_compositor ())
{
MetaCompScreen *info = meta_screen_get_compositor_data (self->priv->screen);
/* Don't do any culling for the unredirected window */
if (self == info->unredirected_window)
return;
}
meta_window_actor_set_unobscured_region (self, unobscured_region);
meta_cullable_cull_out_children (cullable, unobscured_region, clip_region);

View File

@@ -184,8 +184,9 @@ meta_window_group_paint (ClutterActor *actor)
if (info->unredirected_window != NULL)
{
cairo_rectangle_int_t unredirected_rect;
MetaWindow *window = meta_window_actor_get_meta_window (info->unredirected_window);
meta_window_get_frame_rect (info->unredirected_window, (MetaRectangle *)&unredirected_rect);
meta_window_get_frame_rect (window, (MetaRectangle *)&unredirected_rect);
cairo_region_subtract_rectangle (unobscured_region, &unredirected_rect);
cairo_region_subtract_rectangle (clip_region, &unredirected_rect);
}

View File

@@ -407,11 +407,9 @@ 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;
workspace = meta_window_get_workspace (meta_window_actor_get_meta_window (window_actor));
win_workspace = meta_workspace_index (workspace);
win_workspace = meta_window_actor_get_workspace (window_actor);
if (win_workspace == to || win_workspace == from)
{

View File

@@ -1353,6 +1353,7 @@ constrain_titlebar_visible (MetaWindow *window,
window->type == META_WINDOW_DOCK ||
window->fullscreen ||
!window->require_titlebar_visible ||
!window->decorated ||
unconstrained_user_action)
return TRUE;

View File

@@ -36,7 +36,6 @@
#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"
@@ -830,12 +829,22 @@ meta_display_open (void)
{
MetaScreen *screen = tmp->data;
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 ())
if (meta_is_wayland_compositor ())
{
/* Instead of explicitly enumerating all windows during
* initialization, when we run as a wayland compositor we can rely on
* xwayland notifying us of all top level windows so we create
* MetaWindows when we get those notifications.
*
* We still want a guard window so we can avoid
* unmapping/withdrawing minimized windows for live
* thumbnails...
*/
if (screen->guard_window == None)
screen->guard_window =
meta_screen_create_guard_window (screen->display->xdisplay, screen);
}
else
meta_screen_manage_all_windows (screen);
tmp = tmp->next;
@@ -1572,7 +1581,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_x11_configure_request() which is smart about whether to
* meta_window_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).
*/
@@ -1975,7 +1984,6 @@ 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;
@@ -2047,9 +2055,8 @@ 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);
bypass_clutter = TRUE;
bypass_wayland = TRUE;
meta_display_end_grab_op (display,
event->any.time);
}
else if (window && display->grab_op == META_GRAB_OP_NONE)
{
@@ -2164,8 +2171,20 @@ meta_display_handle_event (MetaDisplay *display,
event->button.y,
event->button.button,
event->any.time);
bypass_clutter = TRUE;
bypass_wayland = TRUE;
}
if (!frame_was_receiver && unmodified)
{
/* This is from our synchronous grab since
* it has no modifiers and was on the client window
*/
meta_verbose ("Allowing events time %u\n",
(unsigned int) event->any.time);
/* XXX -- implement this in Wayland */
XIAllowEvents (display->xdisplay, META_VIRTUAL_CORE_POINTER_ID,
XIReplayDevice, event->any.time);
}
if (begin_move && window->has_move_func)
@@ -2181,8 +2200,6 @@ meta_display_handle_event (MetaDisplay *display,
event->any.time,
event->button.x,
event->button.y);
bypass_clutter = TRUE;
bypass_wayland = TRUE;
}
}
break;
@@ -2194,11 +2211,7 @@ 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);
bypass_clutter = TRUE;
bypass_wayland = TRUE;
}
meta_window_handle_mouse_grab_op_event (window, event);
break;
case CLUTTER_MOTION:
if (display->grab_op == META_GRAB_OP_COMPOSITOR)
@@ -2206,11 +2219,7 @@ 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);
bypass_clutter = TRUE;
bypass_wayland = TRUE;
}
meta_window_handle_mouse_grab_op_event (window, event);
break;
case CLUTTER_KEY_PRESS:
@@ -2222,28 +2231,22 @@ 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))
{
bypass_clutter = TRUE;
bypass_wayland = TRUE;
}
return 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 && !bypass_wayland)
if (compositor && (display->grab_op == META_GRAB_OP_NONE))
{
if (meta_wayland_compositor_handle_event (compositor, event))
bypass_clutter = TRUE;
return TRUE;
}
#endif /* HAVE_WAYLAND */
return bypass_clutter;
return (display->grab_op != META_GRAB_OP_NONE &&
display->grab_op != META_GRAB_OP_COMPOSITOR);
}
static gboolean
@@ -2683,9 +2686,9 @@ handle_other_xevent (MetaDisplay *display,
XShapeEvent *sev = (XShapeEvent*) event;
if (sev->kind == ShapeBounding)
meta_window_x11_update_shape_region (window);
meta_window_update_shape_region_x11 (window);
else if (sev->kind == ShapeInput)
meta_window_x11_update_input_region (window);
meta_window_update_input_region_x11 (window);
}
else
{
@@ -2807,15 +2810,15 @@ handle_other_xevent (MetaDisplay *display,
if (display->compositor && window == NULL
&& meta_display_screen_for_root (display, event->xmap.event))
{
window = meta_window_x11_new (display, event->xmap.window,
FALSE, META_COMP_EFFECT_CREATE);
window = meta_window_new (display, event->xmap.window,
FALSE, META_COMP_EFFECT_CREATE);
}
break;
case MapRequest:
if (window == NULL)
{
window = meta_window_x11_new (display, event->xmaprequest.window,
FALSE, META_COMP_EFFECT_CREATE);
window = meta_window_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)
@@ -2894,7 +2897,7 @@ handle_other_xevent (MetaDisplay *display,
else
{
if (!frame_was_receiver)
meta_window_x11_configure_request (window, event);
meta_window_configure_request (window, event);
}
break;
case GravityNotify:
@@ -2911,9 +2914,9 @@ handle_other_xevent (MetaDisplay *display,
MetaScreen *screen;
if (window && !frame_was_receiver)
meta_window_x11_property_notify (window, event);
meta_window_property_notify (window, event);
else if (property_for_window && !frame_was_receiver)
meta_window_x11_property_notify (property_for_window, event);
meta_window_property_notify (property_for_window, event);
group = meta_display_lookup_group (display,
event->xproperty.window);
@@ -2984,7 +2987,7 @@ handle_other_xevent (MetaDisplay *display,
if (window)
{
if (!frame_was_receiver)
meta_window_x11_client_message (window, event);
meta_window_client_message (window, event);
}
else
{

View File

@@ -28,6 +28,7 @@
*/
#define _GNU_SOURCE
#define _SVID_SOURCE /* for putenv() */
#include <config.h>
#include "keybindings-private.h"
@@ -53,6 +54,9 @@
#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"
@@ -4080,6 +4084,18 @@ handle_set_spew_mark (MetaDisplay *display,
}
#ifdef HAVE_WAYLAND
static gboolean
activate_vt (int vt)
{
int tty, reply;
tty = open ("/dev/tty", O_RDWR | O_NOCTTY | O_CLOEXEC);
reply = ioctl (tty, VT_ACTIVATE, vt);
close (tty);
return (reply == 0);
}
static void
handle_switch_vt (MetaDisplay *display,
MetaScreen *screen,
@@ -4089,14 +4105,9 @@ handle_switch_vt (MetaDisplay *display,
gpointer dummy)
{
gint vt = binding->handler->data;
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
GError *error = NULL;
if (!meta_wayland_compositor_activate_vt (compositor, vt, &error))
{
g_warning ("Failed to switch VT: %s", error->message);
g_error_free (error);
}
if (!activate_vt (vt))
g_warning ("Failed to switch VT");
}
#endif

View File

@@ -302,12 +302,8 @@ event_dispatch (GSource *source,
gpointer user_data)
{
ClutterEvent *event = clutter_event_get ();
if (event)
{
clutter_do_event (event);
clutter_event_free (event);
}
clutter_do_event (event);
return TRUE;
}
@@ -345,16 +341,16 @@ meta_clutter_init (void)
* also is %NULL, use the default - :0.0
*/
static void
meta_select_display (char *display_arg)
meta_select_display (gchar *display_name)
{
const char *display_name;
if (display_arg)
display_name = (const char *) display_arg;
else
display_name = g_getenv ("MUTTER_DISPLAY");
g_setenv ("DISPLAY", display_name, TRUE);
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);
}
static void

View File

@@ -468,10 +468,47 @@ meta_cursor_reference_from_buffer (MetaCursorTracker *tracker,
if (tracker->gbm)
{
self->bo = gbm_bo_import (tracker->gbm, GBM_BO_IMPORT_WL_BUFFER,
buffer, GBM_BO_USE_CURSOR_64X64);
if (!self->bo)
meta_warning ("Importing HW cursor from wl_buffer failed\n");
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);
}
}

View File

@@ -111,7 +111,8 @@ make_output_name (drmModeConnector *connector)
};
const char *connector_type_name;
if (connector->connector_type < G_N_ELEMENTS (connector_type_names))
if (connector->connector_type >= 0 &&
connector->connector_type < G_N_ELEMENTS (connector_type_names))
connector_type_name = connector_type_names[connector->connector_type];
else
connector_type_name = "unknown";

View File

@@ -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, j);
MetaMonitorInfo *info = &g_array_index (monitor_infos, MetaMonitorInfo, i);
if (meta_rectangle_equal (&crtc->rect,
&info->rect))
{

View File

@@ -241,7 +241,7 @@ void meta_screen_workspace_switched (MetaScreen *screen,
void meta_screen_set_active_workspace_hint (MetaScreen *screen);
void meta_screen_create_guard_window (MetaScreen *screen);
Window meta_screen_create_guard_window (Display *xdisplay, MetaScreen *screen);
gboolean meta_screen_handle_xevent (MetaScreen *screen,
XEvent *xevent);

View File

@@ -445,16 +445,17 @@ reload_monitor_infos (MetaScreen *screen)
* should effectively be forwarded to events on the background actor,
* providing that the scene graph is set up correctly.
*/
static Window
create_guard_window (Display *xdisplay, MetaScreen *screen)
Window
meta_screen_create_guard_window (Display *xdisplay, MetaScreen *screen)
{
XSetWindowAttributes attributes;
Window guard_window;
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 */
@@ -467,10 +468,10 @@ create_guard_window (Display *xdisplay, MetaScreen *screen)
screen->rect.width,
screen->rect.height,
0, /* border width */
0, /* depth */
InputOnly, /* class */
CopyFromParent, /* depth */
CopyFromParent, /* class */
CopyFromParent, /* visual */
CWEventMask|CWOverrideRedirect,
CWEventMask|CWOverrideRedirect|CWBackPixel,
&attributes);
{
@@ -877,13 +878,6 @@ 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)
{
@@ -891,6 +885,10 @@ 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);
@@ -899,8 +897,8 @@ meta_screen_manage_all_windows (MetaScreen *screen)
for (i = 0; i < n_children; ++i)
{
meta_window_x11_new (screen->display, children[i].x11.xwindow, TRUE,
META_COMP_EFFECT_NONE);
meta_window_new (screen->display, children[i].x11.xwindow, TRUE,
META_COMP_EFFECT_NONE);
}
g_free (children);

View File

@@ -506,22 +506,12 @@ 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_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,
MetaWindow* meta_window_new (MetaDisplay *display,
Window xwindow,
gboolean must_be_viewable,
MetaCompEffect effect);
MetaWindow *meta_window_new_for_wayland (MetaDisplay *display,
MetaWaylandSurface *surface);
void meta_window_unmanage (MetaWindow *window,
guint32 timestamp);
void meta_window_calc_showing (MetaWindow *window);
@@ -625,6 +615,12 @@ 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);
@@ -701,6 +697,8 @@ 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);
@@ -714,6 +712,10 @@ 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,
@@ -754,9 +756,4 @@ 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

View File

@@ -39,7 +39,6 @@
#include <config.h>
#include "window-props.h"
#include "window-x11.h"
#include <meta/errors.h>
#include "xprops.h"
#include "frame.h"
@@ -230,7 +229,7 @@ reload_net_wm_window_type (MetaWindow *window,
MetaPropValue *value,
gboolean initial)
{
meta_window_x11_update_net_wm_type (window);
meta_window_update_net_wm_type (window);
}
static void
@@ -334,7 +333,7 @@ reload_wm_window_role (MetaWindow *window,
MetaPropValue *value,
gboolean initial)
{
meta_window_x11_update_role (window);
meta_window_update_role (window);
}
static void
@@ -559,7 +558,7 @@ reload_opaque_region (MetaWindow *window,
MetaPropValue *value,
gboolean initial)
{
meta_window_x11_update_opaque_region (window);
meta_window_update_opaque_region_x11 (window);
}
static void
@@ -846,7 +845,7 @@ reload_mwm_hints (MetaWindow *window,
meta_window_recalc_features (window);
/* We do all this anyhow at the end of meta_window_x11_new() */
/* We do all this anyhow at the end of meta_window_new() */
if (!window->constructing)
{
if (window->decorated)
@@ -1765,8 +1764,8 @@ meta_display_init_window_prop_hooks (MetaDisplay *display)
{ display->atom__NET_WM_ICON_GEOMETRY, META_PROP_VALUE_CARDINAL_LIST, reload_icon_geometry, FALSE, FALSE },
{ display->atom_WM_CLIENT_LEADER, META_PROP_VALUE_INVALID, complain_about_broken_client, FALSE, FALSE },
{ display->atom_SM_CLIENT_ID, META_PROP_VALUE_INVALID, complain_about_broken_client, FALSE, FALSE },
{ display->atom_WM_WINDOW_ROLE, META_PROP_VALUE_INVALID, reload_wm_window_role, TRUE, FALSE },
{ display->atom__NET_WM_WINDOW_TYPE, META_PROP_VALUE_INVALID, reload_net_wm_window_type, TRUE, TRUE },
{ 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__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 },

File diff suppressed because it is too large Load Diff

View File

@@ -1,45 +0,0 @@
/* -*- 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

File diff suppressed because it is too large Load Diff

View File

@@ -58,8 +58,11 @@ struct _MetaWindowActor
GType meta_window_actor_get_type (void);
Window meta_window_actor_get_x_window (MetaWindowActor *self);
gint meta_window_actor_get_workspace (MetaWindowActor *self);
MetaWindow * meta_window_actor_get_meta_window (MetaWindowActor *self);
ClutterActor * meta_window_actor_get_texture (MetaWindowActor *self);
gboolean meta_window_actor_is_override_redirect (MetaWindowActor *self);
gboolean meta_window_actor_showing_on_its_workspace (MetaWindowActor *self);
gboolean meta_window_actor_is_destroyed (MetaWindowActor *self);
#endif /* META_WINDOW_ACTOR_H */

View File

@@ -322,16 +322,12 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
return;
resource = pointer->focus_resource;
if (resource)
if (resource && 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);
}
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);
}

View File

@@ -101,16 +101,13 @@ 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_ref (MetaWaylandBuffer *buffer);
void meta_wayland_buffer_unref (MetaWaylandBuffer *buffer);
MetaWaylandBuffer * meta_wayland_buffer_from_resource (struct wl_resource *resource);
void meta_wayland_buffer_reference (MetaWaylandBufferReference *ref,
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 */

View File

@@ -48,32 +48,28 @@ unbind_resource (struct wl_resource *resource)
}
static void
set_cursor_surface (MetaWaylandSeat *seat,
MetaWaylandSurface *surface)
pointer_unmap_sprite (MetaWaylandSeat *seat)
{
if (seat->cursor_surface == surface)
return;
if (seat->cursor_tracker)
meta_cursor_tracker_set_window_cursor (seat->cursor_tracker, NULL, 0, 0);
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);
if (seat->sprite)
{
wl_list_remove (&seat->sprite_destroy_listener.link);
seat->sprite = NULL;
}
}
void
meta_wayland_seat_update_cursor_surface (MetaWaylandSeat *seat)
meta_wayland_seat_update_sprite (MetaWaylandSeat *seat)
{
struct wl_resource *buffer;
if (seat->cursor_tracker == NULL)
return;
if (seat->cursor_surface && seat->cursor_surface->buffer)
buffer = seat->cursor_surface->buffer->resource;
if (seat->sprite->buffer_ref.buffer)
buffer = seat->sprite->buffer_ref.buffer->resource;
else
buffer = NULL;
@@ -93,7 +89,9 @@ 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;
@@ -104,13 +102,29 @@ pointer_set_cursor (struct wl_client *client,
seat->hotspot_x = x;
seat->hotspot_y = y;
set_cursor_surface (seat, surface);
meta_wayland_seat_update_cursor_surface (seat);
if (seat->sprite != surface)
{
pointer_unmap_sprite (seat);
if (!surface)
return;
wl_resource_add_destroy_listener (surface->resource,
&seat->sprite_destroy_listener);
seat->sprite = surface;
if (seat->sprite->buffer_ref.buffer)
meta_wayland_seat_update_sprite (seat);
}
}
static const struct wl_pointer_interface 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,
@@ -195,12 +209,12 @@ bind_seat (struct wl_client *client,
}
static void
pointer_handle_cursor_surface_destroy (struct wl_listener *listener, void *data)
pointer_handle_sprite_destroy (struct wl_listener *listener, void *data)
{
MetaWaylandSeat *seat = wl_container_of (listener, seat, cursor_surface_destroy_listener);
MetaWaylandSeat *seat =
wl_container_of (listener, seat, sprite_destroy_listener);
set_cursor_surface (seat, NULL);
meta_wayland_seat_update_cursor_surface (seat);
pointer_unmap_sprite (seat);
}
MetaWaylandSeat *
@@ -221,8 +235,8 @@ meta_wayland_seat_new (struct wl_display *display,
seat->current_stage = 0;
seat->cursor_surface = NULL;
seat->cursor_surface_destroy_listener.notify = pointer_handle_cursor_surface_destroy;
seat->sprite = NULL;
seat->sprite_destroy_listener.notify = pointer_handle_sprite_destroy;
seat->hotspot_x = 16;
seat->hotspot_y = 16;
@@ -443,7 +457,7 @@ meta_wayland_seat_repick (MetaWaylandSeat *seat,
void
meta_wayland_seat_free (MetaWaylandSeat *seat)
{
set_cursor_surface (seat, NULL);
pointer_unmap_sprite (seat);
meta_wayland_pointer_release (&seat->pointer);
meta_wayland_keyboard_release (&seat->keyboard);

View File

@@ -66,9 +66,9 @@ struct _MetaWaylandSeat
struct wl_display *display;
MetaCursorTracker *cursor_tracker;
MetaWaylandSurface *cursor_surface;
MetaWaylandSurface *sprite;
int hotspot_x, hotspot_y;
struct wl_listener cursor_surface_destroy_listener;
struct wl_listener sprite_destroy_listener;
ClutterActor *current_stage;
};
@@ -90,7 +90,7 @@ meta_wayland_seat_repick (MetaWaylandSeat *seat,
const ClutterEvent *for_event);
void
meta_wayland_seat_update_cursor_surface (MetaWaylandSeat *seat);
meta_wayland_seat_update_sprite (MetaWaylandSeat *seat);
void
meta_wayland_seat_free (MetaWaylandSeat *seat);

View File

@@ -58,52 +58,6 @@
#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)
@@ -124,28 +78,28 @@ surface_process_damage (MetaWaylandSurface *surface,
}
static void
meta_wayland_surface_destroy (struct wl_client *client,
struct wl_resource *resource)
meta_wayland_surface_destroy (struct wl_client *wayland_client,
struct wl_resource *wayland_resource)
{
wl_resource_destroy (resource);
wl_resource_destroy (wayland_resource);
}
static void
meta_wayland_surface_attach (struct wl_client *client,
struct wl_resource *surface_resource,
struct wl_resource *buffer_resource,
meta_wayland_surface_attach (struct wl_client *wayland_client,
struct wl_resource *wayland_surface_resource,
struct wl_resource *wayland_buffer_resource,
gint32 dx, gint32 dy)
{
MetaWaylandSurface *surface =
wl_resource_get_user_data (surface_resource);
wl_resource_get_user_data (wayland_surface_resource);
MetaWaylandBuffer *buffer;
/* X11 unmanaged window */
if (!surface)
return;
if (buffer_resource)
buffer = meta_wayland_buffer_from_resource (buffer_resource);
if (wayland_buffer_resource)
buffer = meta_wayland_buffer_from_resource (wayland_buffer_resource);
else
buffer = NULL;
@@ -205,8 +159,11 @@ 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, META_WL_CALLBACK_VERSION, callback_id);
wl_resource_set_implementation (callback->resource, NULL, callback, destroy_frame_callback);
callback->resource = wl_resource_create (client,
&wl_callback_interface, 1,
callback_id);
wl_resource_set_user_data (callback->resource, callback);
wl_resource_set_destructor (callback->resource, destroy_frame_callback);
wl_list_insert (surface->pending.frame_callback_list.prev, &callback->link);
}
@@ -282,47 +239,52 @@ ensure_buffer_texture (MetaWaylandBuffer *buffer)
}
static void
cursor_surface_commit (MetaWaylandSurface *surface,
MetaWaylandDoubleBufferedState *pending,
gboolean buffer_changed)
cursor_surface_commit (MetaWaylandSurface *surface)
{
if (buffer_changed)
meta_wayland_seat_update_cursor_surface (surface->compositor->seat);
}
MetaWaylandBuffer *buffer = surface->pending.buffer;
static void
actor_surface_commit (MetaWaylandSurface *surface,
MetaWaylandDoubleBufferedState *pending,
gboolean buffer_changed)
{
MetaSurfaceActor *surface_actor = surface->surface_actor;
MetaWaylandBuffer *buffer = pending->buffer;
if (buffer_changed)
if (surface->pending.newly_attached && buffer != surface->buffer_ref.buffer)
{
ensure_buffer_texture (buffer);
meta_surface_actor_attach_wayland_buffer (surface_actor, buffer);
meta_wayland_buffer_reference (&surface->buffer_ref, buffer);
}
surface_process_damage (surface, pending->damage);
meta_wayland_seat_update_sprite (surface->compositor->seat);
}
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 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;
}
static void
toplevel_surface_commit (MetaWaylandSurface *surface,
MetaWaylandDoubleBufferedState *pending,
gboolean buffer_changed)
toplevel_surface_commit (MetaWaylandSurface *surface)
{
actor_surface_commit (surface, pending, buffer_changed);
if (buffer_changed)
if (actor_surface_commit (surface))
{
MetaWindow *window = surface->window;
MetaWaylandBuffer *buffer = pending->buffer;
MetaWaylandBuffer *buffer = surface->pending.buffer;
meta_window_set_surface_mapped (window, buffer != NULL);
/* We resize X based surfaces according to X events */
@@ -331,185 +293,37 @@ toplevel_surface_commit (MetaWaylandSurface *surface,
int new_width;
int new_height;
new_width = surface->buffer->width;
new_height = surface->buffer->height;
new_width = surface->buffer_ref.buffer->width;
new_height = surface->buffer_ref.buffer->height;
if (new_width != window->rect.width ||
new_height != window->rect.height ||
pending->dx != 0 ||
pending->dy != 0)
meta_window_move_resize_wayland (window, new_width, new_height, pending->dx, pending->dy);
surface->pending.dx != 0 ||
surface->pending.dy != 0)
meta_window_move_resize_wayland (window, new_width, new_height,
surface->pending.dx, surface->pending.dy);
}
}
}
static void
surface_handle_pending_buffer_destroy (struct wl_listener *listener, void *data)
subsurface_surface_commit (MetaWaylandSurface *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)
if (actor_surface_commit (surface))
{
move_double_buffered_state (pending, &surface->sub.pending_surface_state);
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);
}
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
@@ -517,12 +331,40 @@ 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;
commit_double_buffered_state (surface, &surface->pending);
compositor = surface->compositor;
meta_surface_actor_commit (surface->surface_actor);
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);
}
static void
@@ -558,17 +400,28 @@ static void
meta_wayland_surface_free (MetaWaylandSurface *surface)
{
MetaWaylandCompositor *compositor = surface->compositor;
MetaWaylandFrameCallback *cb, *next;
compositor->surfaces = g_list_remove (compositor->surfaces, surface);
surface_set_buffer (surface, NULL);
double_buffered_state_destroy (&surface->pending);
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);
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
@@ -622,9 +475,19 @@ 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 *client,
struct wl_client *wayland_client,
guint32 id,
guint32 version)
{
@@ -632,13 +495,17 @@ meta_wayland_surface_create (MetaWaylandCompositor *compositor,
surface->compositor = compositor;
surface->resource = wl_resource_create (client, &wl_surface_interface, version, id);
surface->resource = wl_resource_create (wayland_client,
&wl_surface_interface,
version, id);
wl_resource_set_implementation (surface->resource, &meta_wayland_surface_interface, surface,
meta_wayland_surface_resource_destroy_cb);
double_buffered_state_init (&surface->pending);
surface->pending.damage = cairo_region_create ();
surface->buffer_destroy_listener.notify = surface_handle_buffer_destroy;
surface->pending.buffer_destroy_listener.notify =
surface_handle_pending_buffer_destroy;
wl_list_init (&surface->pending.frame_callback_list);
surface->surface_actor = g_object_ref_sink (meta_surface_actor_new ());
return surface;
@@ -648,6 +515,7 @@ static void
destroy_surface_extension (MetaWaylandSurfaceExtension *extension)
{
wl_list_remove (&extension->surface_destroy_listener.link);
extension->surface_destroy_listener.notify = NULL;
extension->resource = NULL;
}
@@ -677,15 +545,17 @@ create_surface_extension (MetaWaylandSurfaceExtension *extension,
const void *implementation,
wl_resource_destroy_func_t destructor)
{
struct wl_resource *resource;
if (extension->resource != NULL)
return FALSE;
extension->resource = wl_resource_create (client, interface, get_resource_version (master_resource, max_version), id);
wl_resource_set_implementation (extension->resource, implementation, extension, destructor);
resource = wl_resource_create (client, interface, get_resource_version (master_resource, max_version), id);
wl_resource_set_implementation (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;
}
@@ -947,7 +817,7 @@ get_xdg_surface (struct wl_client *client,
return;
}
surface->window = meta_window_wayland_new (meta_get_display (), surface);
surface->window = meta_window_new_for_wayland (meta_get_display (), surface);
}
static void
@@ -1017,7 +887,7 @@ get_xdg_popup (struct wl_client *client,
return;
}
surface->window = meta_window_wayland_new (meta_get_display (), surface);
surface->window = meta_window_new_for_wayland (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;
@@ -1125,79 +995,13 @@ 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);
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);
unparent_actor (surface);
destroy_surface_extension (subsurface);
}
@@ -1208,6 +1012,12 @@ wl_subsurface_destroy (struct wl_client *client,
wl_resource_destroy (resource);
}
static MetaSurfaceActor *
get_parent (MetaWaylandSurface *surface)
{
return META_SURFACE_ACTOR (clutter_actor_get_parent (CLUTTER_ACTOR (surface->surface_actor)));
}
static void
wl_subsurface_set_position (struct wl_client *client,
struct wl_resource *resource,
@@ -1217,47 +1027,7 @@ wl_subsurface_set_position (struct wl_client *client,
MetaWaylandSurfaceExtension *subsurface = wl_resource_get_user_data (resource);
MetaWaylandSurface *surface = wl_container_of (subsurface, surface, subsurface);
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);
meta_surface_actor_subsurface_set_position (get_parent (surface), surface->surface_actor, x, y);
}
static void
@@ -1269,18 +1039,7 @@ wl_subsurface_place_above (struct wl_client *client,
MetaWaylandSurface *surface = wl_container_of (subsurface, surface, subsurface);
MetaWaylandSurface *sibling = wl_resource_get_user_data (sibling_resource);
if (!is_valid_sibling (surface, sibling))
{
wl_resource_post_error (resource, WL_SUBSURFACE_ERROR_BAD_SURFACE,
"wl_subsurface::place_above: wl_surface@%d is "
"not a valid parent or sibling",
wl_resource_get_id (sibling->resource));
return;
}
queue_subsurface_placement (surface,
sibling,
META_WAYLAND_SUBSURFACE_PLACEMENT_ABOVE);
meta_surface_actor_subsurface_place_above (get_parent (surface), surface->surface_actor, sibling->surface_actor);
}
static void
@@ -1292,45 +1051,21 @@ wl_subsurface_place_below (struct wl_client *client,
MetaWaylandSurface *surface = wl_container_of (subsurface, surface, subsurface);
MetaWaylandSurface *sibling = wl_resource_get_user_data (sibling_resource);
if (!is_valid_sibling (surface, sibling))
{
wl_resource_post_error (resource, WL_SUBSURFACE_ERROR_BAD_SURFACE,
"wl_subsurface::place_below: wl_surface@%d is "
"not a valid parent or sibling",
wl_resource_get_id (sibling->resource));
return;
}
queue_subsurface_placement (surface,
sibling,
META_WAYLAND_SUBSURFACE_PLACEMENT_BELOW);
meta_surface_actor_subsurface_place_below (get_parent (surface), surface->surface_actor, sibling->surface_actor);
}
static void
wl_subsurface_set_sync (struct wl_client *client,
struct wl_resource *resource)
{
MetaWaylandSurfaceExtension *subsurface =
wl_resource_get_user_data (resource);
MetaWaylandSurface *surface =
wl_container_of (subsurface, surface, subsurface);
surface->sub.synchronous = TRUE;
g_warning ("TODO: support wl_subsurface.set_sync");
}
static void
wl_subsurface_set_desync (struct wl_client *client,
struct wl_resource *resource)
{
MetaWaylandSurfaceExtension *subsurface =
wl_resource_get_user_data (resource);
MetaWaylandSurface *surface =
wl_container_of (subsurface, surface, subsurface);
if (surface->sub.synchronous)
subsurface_parent_surface_committed (surface);
surface->sub.synchronous = FALSE;
g_warning ("TODO: support wl_subsurface.set_desync");
}
static const struct wl_subsurface_interface meta_wayland_subsurface_interface = {
@@ -1349,18 +1084,6 @@ 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,
@@ -1383,14 +1106,6 @@ 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));
}

View File

@@ -39,7 +39,13 @@ struct _MetaWaylandBuffer
CoglTexture *texture;
int32_t width, height;
uint32_t ref_count;
uint32_t busy_count;
};
struct _MetaWaylandBufferReference
{
MetaWaylandBuffer *buffer;
struct wl_listener destroy_listener;
};
typedef struct
@@ -71,6 +77,7 @@ struct _MetaWaylandSurface
{
struct wl_resource *resource;
MetaWaylandCompositor *compositor;
MetaWaylandBufferReference buffer_ref;
MetaSurfaceActor *surface_actor;
MetaWindow *window;
MetaWaylandSurfaceExtension xdg_surface;
@@ -78,24 +85,6 @@ 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;
};

View File

@@ -138,24 +138,6 @@ 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)
{
@@ -183,6 +165,46 @@ 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)
@@ -483,7 +505,8 @@ meta_wayland_compositor_paint_finished (MetaWaylandCompositor *compositor)
MetaWaylandFrameCallback *callback =
wl_container_of (compositor->frame_callbacks.next, callback, link);
wl_callback_send_done (callback->resource, get_time ());
wl_resource_post_event (callback->resource,
WL_CALLBACK_DONE, get_time ());
wl_resource_destroy (callback->resource);
}
}
@@ -664,7 +687,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");
@@ -738,9 +761,7 @@ meta_wayland_finalize (void)
compositor = meta_wayland_compositor_get_default ();
meta_xwayland_stop (compositor);
if (compositor->launcher)
meta_launcher_free (compositor->launcher);
meta_launcher_free (compositor->launcher);
}
gboolean
@@ -748,19 +769,3 @@ 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;
}
}

View File

@@ -385,17 +385,3 @@ 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);
}

View File

@@ -28,10 +28,6 @@ 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);

View File

@@ -44,17 +44,15 @@ xserver_set_window_id (struct wl_client *client,
MetaWindow *window;
window = meta_display_lookup_x_window (display, xid);
if (!window)
return;
surface->window = window;
window->surface = surface;
meta_window_set_surface_mapped (window, TRUE);
if (window)
{
surface->window = window;
window->surface = surface;
}
}
static const struct xserver_interface xserver_implementation = {
xserver_set_window_id
xserver_set_window_id
};
static void
@@ -75,8 +73,13 @@ bind_xserver (struct wl_client *client,
wl_resource_set_implementation (compositor->xserver_resource,
&xserver_implementation, compositor, NULL);
xserver_send_listen_socket (compositor->xserver_resource, compositor->xwayland_abstract_fd);
xserver_send_listen_socket (compositor->xserver_resource, compositor->xwayland_unix_fd);
wl_resource_post_event (compositor->xserver_resource,
XSERVER_LISTEN_SOCKET,
compositor->xwayland_abstract_fd);
wl_resource_post_event (compositor->xserver_resource,
XSERVER_LISTEN_SOCKET,
compositor->xwayland_unix_fd);
/* Make sure xwayland will recieve the above sockets in a finite
* time before unblocking the initialization mainloop since we are
@@ -120,7 +123,7 @@ create_lockfile (int display, int *display_out)
/* ignore error and try the next display number */
display++;
continue;
}
}
close (fd);
other = strtol (pid, &end, 0);
@@ -132,7 +135,7 @@ create_lockfile (int display, int *display_out)
/* ignore error and try the next display number */
display++;
continue;
}
}
if (kill (other, 0) < 0 && errno == ESRCH)
{
@@ -145,7 +148,7 @@ create_lockfile (int display, int *display_out)
}
g_free (filename);
continue;
}
}
g_free (filename);
display++;
@@ -237,12 +240,11 @@ 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;
}
@@ -308,8 +310,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);

View File

@@ -269,40 +269,6 @@ out:
return 0;
}
static int
handle_activate_vt(struct weston_launch *wl, struct msghdr *msg, ssize_t len)
{
struct weston_launcher_reply reply;
struct weston_launcher_activate_vt *message;
reply.header.opcode = WESTON_LAUNCHER_ACTIVATE_VT;
reply.ret = -1;
if (len != sizeof(*message)) {
error(0, 0, "missing value in activate_vt request");
goto out;
}
message = msg->msg_iov->iov_base;
reply.ret = ioctl(wl->tty, VT_ACTIVATE, message->vt);
if (reply.ret < 0)
reply.ret = -errno;
if (wl->verbose)
fprintf(stderr, "mutter-launch: activate VT, ret: %d\n", reply.ret);
out:
do {
len = send(wl->sock[0], &reply, sizeof reply, 0);
} while (len < 0 && errno == EINTR);
if (len < 0)
return -1;
return 0;
}
static int
handle_open(struct weston_launch *wl, struct msghdr *msg, ssize_t len)
{
@@ -419,9 +385,6 @@ handle_socket_msg(struct weston_launch *wl)
case WESTON_LAUNCHER_CONFIRM_VT_SWITCH:
ret = handle_confirm_vt_switch(wl, &msg, len);
break;
case WESTON_LAUNCHER_ACTIVATE_VT:
ret = handle_activate_vt(wl, &msg, len);
break;
}
return ret;

View File

@@ -32,8 +32,7 @@ enum weston_launcher_message_type {
enum weston_launcher_opcode {
WESTON_LAUNCHER_OPEN = (1 << 1 | WESTON_LAUNCHER_REQUEST),
WESTON_LAUNCHER_DRM_SET_FD = (2 << 1 | WESTON_LAUNCHER_REQUEST),
WESTON_LAUNCHER_ACTIVATE_VT = (3 << 1 | WESTON_LAUNCHER_REQUEST),
WESTON_LAUNCHER_CONFIRM_VT_SWITCH = (4 << 1 | WESTON_LAUNCHER_REQUEST),
WESTON_LAUNCHER_CONFIRM_VT_SWITCH = (3 << 1 | WESTON_LAUNCHER_REQUEST),
};
enum weston_launcher_server_opcode {