Compare commits

..

3 Commits

Author SHA1 Message Date
2210c30cba window-actor: Split into two subclasses of MetaSurfaceActor
The rendering logic before was somewhat complex. We had three independent
cases to take into account when doing rendering:

  * X11 compositor. In this case, we're a traditional X11 compositor,
    not a Wayland compositor. We use XCompositeNameWindowPixmap to get
    the backing pixmap for the window, and deal with the COMPOSITE
    extension messiness.

    In this case, meta_is_wayland_compositor() is FALSE.

  * Wayland clients. In this case, we're a Wayland compositor managing
    Wayland surfaces. The rendering for this is fairly straightforward,
    as Cogl handles most of the complexity with EGL and SHM buffers...
    Wayland clients give us the input and opaque regions through
    wl_surface.

    In this case, meta_is_wayland_compositor() is TRUE and
    priv->window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND.

  * XWayland clients. In this case, we're a Wayland compositor, like
    above, and XWayland hands us Wayland surfaces. XWayland handles
    the COMPOSITE extension messiness for us, and hands us a buffer
    like any other Wayland client. We have to fetch the input and
    opaque regions from the X11 window ourselves.

    In this case, meta_is_wayland_compositor() is TRUE and
    priv->window->client_type == META_WINDOW_CLIENT_TYPE_X11.

We now split the rendering logic into two subclasses, which are:

  * MetaSurfaceActorX11, which handles the X11 compositor case, in that
    it uses XCompositeNameWindowPixmap to get the backing pixmap, and
    deal with all the COMPOSITE extension messiness.

  * MetaSurfaceActorWayland, which handles the Wayland compositor case
    for both native Wayland clients and XWayland clients. XWayland handles
    COMPOSITE for us, and handles pushing a surface over through the
    xf86-video-wayland DDX.

Frame sync is still in MetaWindowActor, as it needs to work for both the
X11 compositor and XWayland client cases. When Wayland's video display
protocol lands, this will need to be significantly overhauled, as it would
have to work for any wl_surface, including subsurfaces, so we would need
surface-level discretion.

https://bugzilla.gnome.org/show_bug.cgi?id=720631
2014-02-19 10:24:38 -05:00
6b98ac3d1f window-actor: Kill off needs_pixmap
It's mostly equivalent to the case where we've already detached
the pixmap, *except* for the x11_size_changed case. We can simply
detach the pixmap at the time the window changes size, though.
2014-02-19 10:24:38 -05:00
13ddd366a9 window-actor: Don't queue a redraw when queueing a new pixmap
We guarantee ourselves that a valid pixmap will appear any time
that the window is painted. The window actor will be scheduled
for a repaint if it's added / removed from the scene graph, like
during construction, if the size changes, or if we receive damage,
which are the existing use cases where this function is called.

So, I can't see any reason that we queue a redraw in here.
2014-02-19 10:24:38 -05:00
33 changed files with 553 additions and 600 deletions

11
NEWS
View File

@ -1,14 +1,3 @@
3.11.90
=======
* Fix double-scaling on high DPI resolutions [Adel; #723931]
* Make tile previews a compositor effect [Stefano, Florian; #665758]
* Misc. bug fixes and cleanups [Ryan, Giovanni, Jasper, Adel; #722530, #724257,
#724258, #720631, #724364, #724472]
Contributors:
Giovanni Campagna, Marek Chalupa, Stefano Facchini, Adel Gadllah,
Ryan Lortie, Florian Müllner, Jasper St. Pierre, Rico Tzschichholz
3.11.5
======
* Fix CSD titlebars being placed off-screen [Jasper; #719772]

View File

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

View File

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

View File

@ -140,19 +140,6 @@ meta_compositor_destroy (MetaCompositor *compositor)
clutter_threads_remove_repaint_func (compositor->repaint_func_id);
}
static void
add_win (MetaWindow *window)
{
MetaScreen *screen = meta_window_get_screen (window);
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
g_return_if_fail (info != NULL);
meta_window_actor_new (window);
sync_actor_stacking (info);
}
static void
process_damage (MetaCompositor *compositor,
XDamageNotifyEvent *event,
@ -329,36 +316,39 @@ meta_focus_stage_window (MetaScreen *screen,
if (!stage)
return;
window = clutter_x11_get_stage_window (stage);
if (!meta_is_wayland_compositor ())
{
window = clutter_x11_get_stage_window (stage);
if (window == None)
return;
if (window == None)
return;
meta_display_set_input_focus_xwindow (screen->display,
screen,
window,
timestamp);
meta_display_set_input_focus_xwindow (screen->display,
screen,
META_FOCUS_STAGE,
window,
timestamp);
}
else
{
meta_display_set_input_focus_xwindow (screen->display,
screen,
META_FOCUS_STAGE,
None,
timestamp);
}
}
gboolean
meta_stage_is_focused (MetaScreen *screen)
{
ClutterStage *stage;
Window window;
if (meta_is_wayland_compositor ())
return TRUE;
stage = CLUTTER_STAGE (meta_get_stage_for_screen (screen));
if (!stage)
return FALSE;
window = clutter_x11_get_stage_window (stage);
if (window == None)
return FALSE;
return (screen->display->focus_xwindow == window);
return (screen->display->focus_type == META_FOCUS_STAGE);
}
static gboolean
@ -832,13 +822,20 @@ meta_compositor_add_window (MetaCompositor *compositor,
{
MetaScreen *screen = meta_window_get_screen (window);
MetaDisplay *display = meta_screen_get_display (screen);
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
g_return_if_fail (info != NULL);
/* Window was already added previously, probably coming
* back from hiding */
if (window->compositor_private != NULL)
return;
DEBUG_TRACE ("meta_compositor_add_window\n");
meta_error_trap_push (display);
add_win (window);
meta_window_actor_new (window);
meta_error_trap_pop (display);
sync_actor_stacking (info);
}
void
@ -940,18 +937,6 @@ meta_compositor_window_opacity_changed (MetaCompositor *compositor,
meta_window_actor_update_opacity (window_actor);
}
void
meta_compositor_window_surface_changed (MetaCompositor *compositor,
MetaWindow *window)
{
MetaWindowActor *window_actor;
window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
if (!window_actor)
return;
meta_window_actor_update_surface (window_actor);
}
/* Clutter makes the assumption that there is only one X window
* per stage, which is a valid assumption to make for a generic
* application toolkit. As such, it will ignore any events sent
@ -1710,31 +1695,3 @@ meta_compositor_monotonic_time_to_server_time (MetaDisplay *display,
else
return monotonic_time + compositor->server_time_offset;
}
void
meta_compositor_show_tile_preview (MetaCompositor *compositor,
MetaScreen *screen,
MetaWindow *window,
MetaRectangle *tile_rect,
int tile_monitor_number)
{
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
if (!info->plugin_mgr)
return;
meta_plugin_manager_show_tile_preview (info->plugin_mgr,
window, tile_rect, tile_monitor_number);
}
void
meta_compositor_hide_tile_preview (MetaCompositor *compositor,
MetaScreen *screen)
{
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
if (!info->plugin_mgr)
return;
meta_plugin_manager_hide_tile_preview (info->plugin_mgr);
}

View File

@ -324,44 +324,3 @@ meta_plugin_manager_confirm_display_change (MetaPluginManager *plugin_mgr)
else
return meta_plugin_complete_display_change (plugin, TRUE);
}
gboolean
meta_plugin_manager_show_tile_preview (MetaPluginManager *plugin_mgr,
MetaWindow *window,
MetaRectangle *tile_rect,
int tile_monitor_number)
{
MetaPlugin *plugin = plugin_mgr->plugin;
MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
MetaDisplay *display = meta_screen_get_display (plugin_mgr->screen);
if (display->display_opening)
return FALSE;
if (klass->show_tile_preview)
{
klass->show_tile_preview (plugin, window, tile_rect, tile_monitor_number);
return TRUE;
}
return FALSE;
}
gboolean
meta_plugin_manager_hide_tile_preview (MetaPluginManager *plugin_mgr)
{
MetaPlugin *plugin = plugin_mgr->plugin;
MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
MetaDisplay *display = meta_screen_get_display (plugin_mgr->screen);
if (display->display_opening)
return FALSE;
if (klass->hide_tile_preview)
{
klass->hide_tile_preview (plugin);
return TRUE;
}
return FALSE;
}

View File

@ -75,9 +75,4 @@ gboolean _meta_plugin_xevent_filter (MetaPlugin *plugin,
void meta_plugin_manager_confirm_display_change (MetaPluginManager *mgr);
gboolean meta_plugin_manager_show_tile_preview (MetaPluginManager *mgr,
MetaWindow *window,
MetaRectangle *tile_rect,
int tile_monitor_number);
gboolean meta_plugin_manager_hide_tile_preview (MetaPluginManager *mgr);
#endif

View File

@ -414,43 +414,21 @@ meta_surface_actor_x11_init (MetaSurfaceActorX11 *self)
priv->last_height = -1;
}
static void
create_damage (MetaSurfaceActorX11 *self)
{
MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self);
Display *xdisplay = meta_display_get_xdisplay (priv->display);
Window xwindow = meta_window_get_toplevel_xwindow (priv->window);
priv->damage = XDamageCreate (xdisplay, xwindow, XDamageReportBoundingBox);
}
static void
window_decorated_notify (MetaWindow *window,
GParamSpec *pspec,
gpointer user_data)
{
MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (user_data);
free_damage (self);
create_damage (self);
}
MetaSurfaceActor *
meta_surface_actor_x11_new (MetaWindow *window)
{
MetaSurfaceActorX11 *self = g_object_new (META_TYPE_SURFACE_ACTOR_X11, NULL);
MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self);
MetaDisplay *display = meta_window_get_display (window);
Display *xdisplay = meta_display_get_xdisplay (display);
Window xwindow = meta_window_get_toplevel_xwindow (window);
g_assert (!meta_is_wayland_compositor ());
priv->window = window;
priv->display = display;
create_damage (self);
g_signal_connect_object (priv->window, "notify::decorated",
G_CALLBACK (window_decorated_notify), self, 0);
priv->damage = XDamageCreate (xdisplay, xwindow, XDamageReportBoundingBox);
update_is_argb32 (self);
priv->unredirected = FALSE;

View File

@ -26,8 +26,8 @@ struct _MetaSurfaceActorPrivate
cairo_region_t *input_region;
/* Freeze/thaw accounting */
guint freeze_count;
guint needs_damage_all : 1;
guint frozen : 1;
};
static void cullable_iface_init (MetaCullableInterface *iface);
@ -35,14 +35,6 @@ static void cullable_iface_init (MetaCullableInterface *iface);
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (MetaSurfaceActor, meta_surface_actor, CLUTTER_TYPE_ACTOR,
G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init));
enum {
REPAINT_SCHEDULED,
LAST_SIGNAL,
};
static guint signals[LAST_SIGNAL];
gboolean
meta_surface_actor_get_unobscured_bounds (MetaSurfaceActor *self,
cairo_rectangle_int_t *unobscured_bounds)
@ -122,13 +114,6 @@ meta_surface_actor_class_init (MetaSurfaceActorClass *klass)
object_class->dispose = meta_surface_actor_dispose;
actor_class->pick = meta_surface_actor_pick;
signals[REPAINT_SCHEDULED] = g_signal_new ("repaint-scheduled",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 0);
g_type_class_add_private (klass, sizeof (MetaSurfaceActorPrivate));
}
@ -179,14 +164,12 @@ meta_surface_actor_get_texture (MetaSurfaceActor *self)
return self->priv->texture;
}
void
gboolean
meta_surface_actor_update_area (MetaSurfaceActor *self,
int x, int y, int width, int height)
{
MetaSurfaceActorPrivate *priv = self->priv;
if (meta_shaped_texture_update_area (priv->texture, x, y, width, height))
g_signal_emit (self, signals[REPAINT_SCHEDULED], 0);
return meta_shaped_texture_update_area (priv->texture, x, y, width, height);
}
gboolean
@ -223,7 +206,7 @@ static gboolean
is_frozen (MetaSurfaceActor *self)
{
MetaSurfaceActorPrivate *priv = self->priv;
return priv->frozen;
return (priv->freeze_count > 0);
}
void
@ -274,19 +257,31 @@ meta_surface_actor_is_visible (MetaSurfaceActor *self)
}
void
meta_surface_actor_set_frozen (MetaSurfaceActor *self,
gboolean frozen)
meta_surface_actor_freeze (MetaSurfaceActor *self)
{
MetaSurfaceActorPrivate *priv = self->priv;
priv->frozen = frozen;
priv->freeze_count ++;
}
if (!frozen && priv->needs_damage_all)
void
meta_surface_actor_thaw (MetaSurfaceActor *self)
{
MetaSurfaceActorPrivate *priv = self->priv;
if (priv->freeze_count == 0)
{
/* Since we ignore damage events while a window is frozen for certain effects
* we may need to issue an update_area() covering the whole pixmap if we
* don't know what real damage has happened. */
g_critical ("Error in freeze/thaw accounting.");
return;
}
priv->freeze_count --;
/* Since we ignore damage events while a window is frozen for certain effects
* we may need to issue an update_area() covering the whole pixmap if we
* don't know what real damage has happened. */
if (priv->needs_damage_all)
{
meta_surface_actor_process_damage (self, 0, 0,
clutter_actor_get_width (CLUTTER_ACTOR (priv->texture)),
clutter_actor_get_height (CLUTTER_ACTOR (priv->texture)));
@ -294,6 +289,12 @@ meta_surface_actor_set_frozen (MetaSurfaceActor *self,
}
}
gboolean
meta_surface_actor_is_frozen (MetaSurfaceActor *self)
{
return is_frozen (self);
}
gboolean
meta_surface_actor_should_unredirect (MetaSurfaceActor *self)
{

View File

@ -60,8 +60,8 @@ 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_update_area (MetaSurfaceActor *actor,
int x, int y, int width, int height);
gboolean meta_surface_actor_update_area (MetaSurfaceActor *actor,
int x, int y, int width, int height);
void meta_surface_actor_process_damage (MetaSurfaceActor *actor,
int x, int y, int width, int height);
@ -69,8 +69,9 @@ void meta_surface_actor_pre_paint (MetaSurfaceActor *actor);
gboolean meta_surface_actor_is_argb32 (MetaSurfaceActor *actor);
gboolean meta_surface_actor_is_visible (MetaSurfaceActor *actor);
void meta_surface_actor_set_frozen (MetaSurfaceActor *actor,
gboolean frozen);
void meta_surface_actor_freeze (MetaSurfaceActor *actor);
void meta_surface_actor_thaw (MetaSurfaceActor *actor);
gboolean meta_surface_actor_is_frozen (MetaSurfaceActor *actor);
gboolean meta_surface_actor_should_unredirect (MetaSurfaceActor *actor);
void meta_surface_actor_set_unredirected (MetaSurfaceActor *actor,

View File

@ -63,6 +63,5 @@ void meta_window_actor_effect_completed (MetaWindowActor *actor,
gulong event);
MetaSurfaceActor *meta_window_actor_get_surface (MetaWindowActor *self);
void meta_window_actor_update_surface (MetaWindowActor *self);
#endif /* META_WINDOW_ACTOR_PRIVATE_H */

View File

@ -68,9 +68,6 @@ struct _MetaWindowActorPrivate
guint send_frame_messages_timer;
gint64 frame_drawn_time;
guint repaint_scheduled_id;
guint allocation_changed_id;
/*
* These need to be counters rather than flags, since more plugins
* can implement same effect; the practicality of stacking effects
@ -84,10 +81,10 @@ struct _MetaWindowActorPrivate
/* List of FrameData for recent frames */
GList *frames;
guint freeze_count;
guint visible : 1;
guint disposed : 1;
guint redecorating : 1;
/* If set, the client needs to be sent a _NET_WM_FRAME_DRAWN
* client message using the most recent frame in ->frames */
@ -222,6 +219,26 @@ meta_window_actor_init (MetaWindowActor *self)
priv->shadow_class = NULL;
}
static void
window_decorated_notify (MetaWindow *mw,
GParamSpec *arg1,
gpointer data)
{
MetaWindowActor *self = META_WINDOW_ACTOR (data);
MetaWindowActorPrivate *priv = self->priv;
/*
* Basically, we have to reconstruct the the internals of this object
* from scratch, as everything has changed.
*/
priv->redecorating = TRUE;
/*
* Recreate the contents.
*/
meta_window_actor_constructed (G_OBJECT (self));
}
static void
window_appears_focused_notify (MetaWindow *mw,
GParamSpec *arg1,
@ -240,29 +257,11 @@ surface_allocation_changed_notify (ClutterActor *actor,
meta_window_actor_update_shape (self);
}
static void
surface_repaint_scheduled (MetaSurfaceActor *actor,
gpointer user_data)
{
MetaWindowActor *self = META_WINDOW_ACTOR (user_data);
MetaWindowActorPrivate *priv = self->priv;
priv->repaint_scheduled = TRUE;
}
static gboolean
is_argb32 (MetaWindowActor *self)
{
MetaWindowActorPrivate *priv = self->priv;
/* assume we're argb until we get the window (because
in practice we're drawing nothing, so we're fully
transparent)
*/
if (priv->surface)
return meta_surface_actor_is_argb32 (priv->surface);
else
return TRUE;
return meta_surface_actor_is_argb32 (priv->surface);
}
static gboolean
@ -278,19 +277,14 @@ static gboolean
is_frozen (MetaWindowActor *self)
{
MetaWindowActorPrivate *priv = self->priv;
return priv->surface == NULL || priv->freeze_count > 0;
return meta_surface_actor_is_frozen (priv->surface);
}
static void
meta_window_actor_freeze (MetaWindowActor *self)
{
MetaWindowActorPrivate *priv = self->priv;
if (priv->freeze_count == 0 && priv->surface)
meta_surface_actor_set_frozen (priv->surface, TRUE);
priv->freeze_count ++;
meta_surface_actor_freeze (priv->surface);
}
static void
@ -298,16 +292,11 @@ meta_window_actor_thaw (MetaWindowActor *self)
{
MetaWindowActorPrivate *priv = self->priv;
if (priv->freeze_count <= 0)
g_error ("Error in freeze/thaw accounting");
meta_surface_actor_thaw (priv->surface);
priv->freeze_count--;
if (priv->freeze_count > 0)
if (is_frozen (self))
return;
if (priv->surface)
meta_surface_actor_set_frozen (priv->surface, FALSE);
/* We sometimes ignore moves and resizes on frozen windows */
meta_window_actor_sync_actor_geometry (self, FALSE);
@ -316,58 +305,6 @@ meta_window_actor_thaw (MetaWindowActor *self)
meta_window_actor_handle_updates (self);
}
static void
set_surface (MetaWindowActor *self,
MetaSurfaceActor *surface)
{
MetaWindowActorPrivate *priv = self->priv;
if (priv->surface)
{
g_signal_handler_disconnect (priv->surface, priv->repaint_scheduled_id);
priv->repaint_scheduled_id = 0;
g_signal_handler_disconnect (priv->surface, priv->allocation_changed_id);
priv->allocation_changed_id = 0;
clutter_actor_remove_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface));
g_object_unref (priv->surface);
}
priv->surface = surface;
if (priv->surface)
{
g_object_ref_sink (priv->surface);
priv->repaint_scheduled_id = g_signal_connect (priv->surface, "repaint-scheduled",
G_CALLBACK (surface_repaint_scheduled), self);
priv->allocation_changed_id = g_signal_connect (priv->surface, "allocation-changed",
G_CALLBACK (surface_allocation_changed_notify), self);
clutter_actor_add_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface));
/* If the previous surface actor was frozen, start out
* frozen as well... */
meta_surface_actor_set_frozen (priv->surface, priv->freeze_count > 0);
meta_window_actor_update_shape (self);
}
}
void
meta_window_actor_update_surface (MetaWindowActor *self)
{
MetaWindowActorPrivate *priv = self->priv;
MetaWindow *window = priv->window;
MetaSurfaceActor *surface_actor;
if (window->surface)
surface_actor = window->surface->surface_actor;
else if (!meta_is_wayland_compositor ())
surface_actor = meta_surface_actor_x11_new (window);
else
surface_actor = NULL;
set_surface (self, surface_actor);
}
static void
meta_window_actor_constructed (GObject *object)
{
@ -377,7 +314,20 @@ meta_window_actor_constructed (GObject *object)
priv->screen = window->screen;
meta_window_actor_update_surface (self);
if (!priv->surface)
{
if (window->surface)
priv->surface = window->surface->surface_actor;
else
priv->surface = meta_surface_actor_x11_new (window);
g_object_ref_sink (priv->surface);
clutter_actor_add_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface));
g_signal_connect_object (priv->surface, "allocation-changed",
G_CALLBACK (surface_allocation_changed_notify), self, 0);
meta_window_actor_update_shape (self);
}
meta_window_actor_update_opacity (self);
@ -420,7 +370,10 @@ meta_window_actor_dispose (GObject *object)
g_clear_object (&priv->window);
set_surface (self, NULL);
/*
* Release the extra reference we took on the actor.
*/
g_clear_object (&priv->surface);
G_OBJECT_CLASS (meta_window_actor_parent_class)->dispose (object);
}
@ -449,6 +402,9 @@ meta_window_actor_set_property (GObject *object,
{
case PROP_META_WINDOW:
priv->window = g_value_dup_object (value);
g_signal_connect_object (priv->window, "notify::decorated",
G_CALLBACK (window_decorated_notify), self, 0);
g_signal_connect_object (priv->window, "notify::appears-focused",
G_CALLBACK (window_appears_focused_notify), self, 0);
break;
@ -670,12 +626,6 @@ meta_window_actor_get_paint_volume (ClutterActor *actor,
meta_window_actor_get_shape_bounds (self, &bounds);
if (priv->surface)
{
if (meta_surface_actor_get_unobscured_bounds (priv->surface, &unobscured_bounds))
gdk_rectangle_intersect (&bounds, &unobscured_bounds, &bounds);
}
if (appears_focused ? priv->focused_shadow : priv->unfocused_shadow)
{
cairo_rectangle_int_t shadow_bounds;
@ -691,6 +641,9 @@ meta_window_actor_get_paint_volume (ClutterActor *actor,
gdk_rectangle_union (&bounds, &shadow_bounds, &bounds);
}
if (meta_surface_actor_get_unobscured_bounds (priv->surface, &unobscured_bounds))
gdk_rectangle_intersect (&bounds, &unobscured_bounds, &bounds);
origin.x = bounds.x;
origin.y = bounds.y;
origin.z = 0.0f;
@ -785,26 +738,21 @@ meta_window_actor_get_meta_window (MetaWindowActor *self)
* meta_window_actor_get_texture:
* @self: a #MetaWindowActor
*
* Gets the ClutterActor that is used to display the contents of the window,
* or NULL if no texture is shown yet, because the window is not mapped.
* Gets the ClutterActor that is used to display the contents of the window
*
* Return value: (transfer none): the #ClutterActor for the contents
*/
ClutterActor *
meta_window_actor_get_texture (MetaWindowActor *self)
{
if (self->priv->surface)
return CLUTTER_ACTOR (meta_surface_actor_get_texture (self->priv->surface));
else
return NULL;
return CLUTTER_ACTOR (meta_surface_actor_get_texture (self->priv->surface));
}
/**
* meta_window_actor_get_surface:
* @self: a #MetaWindowActor
*
* Gets the MetaSurfaceActor that draws the content of this window,
* or NULL if there is no surface yet associated with this window.
* Gets the MetaSurfaceActor that draws the content of this window
*
* Return value: (transfer none): the #MetaSurfaceActor for the contents
*/
@ -903,12 +851,7 @@ meta_window_actor_queue_frame_drawn (MetaWindowActor *self,
if (!priv->repaint_scheduled)
{
gboolean is_obscured;
if (priv->surface)
is_obscured = meta_surface_actor_is_obscured (priv->surface);
else
is_obscured = FALSE;
gboolean is_obscured = meta_surface_actor_is_obscured (priv->surface);
/* A frame was marked by the client without actually doing any
* damage or any unobscured, or while we had the window frozen
@ -924,12 +867,9 @@ meta_window_actor_queue_frame_drawn (MetaWindowActor *self,
}
else
{
if (priv->surface)
{
const cairo_rectangle_int_t clip = { 0, 0, 1, 1 };
clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (priv->surface), &clip);
priv->repaint_scheduled = TRUE;
}
const cairo_rectangle_int_t clip = { 0, 0, 1, 1 };
clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (priv->surface), &clip);
priv->repaint_scheduled = TRUE;
}
}
}
@ -1102,10 +1042,7 @@ gboolean
meta_window_actor_should_unredirect (MetaWindowActor *self)
{
MetaWindowActorPrivate *priv = self->priv;
if (priv->surface)
return meta_surface_actor_should_unredirect (priv->surface);
else
return FALSE;
return meta_surface_actor_should_unredirect (priv->surface);
}
void
@ -1113,8 +1050,6 @@ meta_window_actor_set_unredirected (MetaWindowActor *self,
gboolean unredirected)
{
MetaWindowActorPrivate *priv = self->priv;
g_assert(priv->surface); /* because otherwise should_unredirect() is FALSE */
meta_surface_actor_set_unredirected (priv->surface, unredirected);
}
@ -1232,11 +1167,13 @@ meta_window_actor_show (MetaWindowActor *self,
g_assert_not_reached();
}
if (info->switch_workspace_in_progress ||
if (priv->redecorating ||
info->switch_workspace_in_progress ||
event == 0 ||
!start_simple_effect (self, event))
{
clutter_actor_show (CLUTTER_ACTOR (self));
priv->redecorating = FALSE;
}
}
@ -1560,12 +1497,11 @@ meta_window_actor_process_x11_damage (MetaWindowActor *self,
{
MetaWindowActorPrivate *priv = self->priv;
if (priv->surface)
meta_surface_actor_process_damage (priv->surface,
event->area.x,
event->area.y,
event->area.width,
event->area.height);
meta_surface_actor_process_damage (priv->surface,
event->area.x,
event->area.y,
event->area.width,
event->area.height);
}
void
@ -1760,27 +1696,21 @@ meta_window_actor_update_input_region (MetaWindowActor *self,
MetaWindowActorPrivate *priv = self->priv;
cairo_region_t *region = NULL;
if (priv->window->frame != NULL)
if (priv->window->frame != NULL && priv->window->input_region != NULL)
{
region = meta_frame_get_frame_bounds (priv->window->frame);
/* client area is in client window coordinates, so translate the
cairo_region_subtract_rectangle (region, client_area);
/* input_region is in client window coordinates, so translate the
* input region into that coordinate system and back */
cairo_region_translate (region, -client_area->x, -client_area->y);
cairo_region_union_rectangle (region, client_area);
cairo_region_union (region, priv->window->input_region);
cairo_region_translate (region, client_area->x, client_area->y);
}
else if (priv->window->shape_region != NULL ||
priv->window->input_region != NULL)
else if (priv->window->input_region != NULL)
{
if (priv->window->shape_region != NULL)
{
region = cairo_region_copy (priv->window->shape_region);
if (priv->window->input_region != NULL)
cairo_region_intersect (region, priv->window->input_region);
}
else
region = cairo_region_reference (priv->window->input_region);
region = cairo_region_reference (priv->window->input_region);
}
else
{
@ -2074,8 +2004,7 @@ meta_window_actor_update_opacity (MetaWindowActor *self)
MetaWindowActorPrivate *priv = self->priv;
MetaWindow *window = priv->window;
if (priv->surface)
clutter_actor_set_opacity (CLUTTER_ACTOR (priv->surface), window->opacity);
clutter_actor_set_opacity (CLUTTER_ACTOR (self->priv->surface), window->opacity);
}
void

View File

@ -39,7 +39,6 @@
#define SWITCH_TIMEOUT 500
#define ACTOR_DATA_KEY "MCCP-Default-actor-data"
#define SCREEN_TILE_PREVIEW_DATA_KEY "MCCP-Default-screen-tile-preview-data"
#define META_TYPE_DEFAULT_PLUGIN (meta_default_plugin_get_type ())
#define META_DEFAULT_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_DEFAULT_PLUGIN, MetaDefaultPlugin))
@ -68,7 +67,6 @@ struct _MetaDefaultPluginClass
};
static GQuark actor_data_quark = 0;
static GQuark screen_tile_preview_data_quark = 0;
static void start (MetaPlugin *plugin);
static void minimize (MetaPlugin *plugin,
@ -99,12 +97,6 @@ static void kill_window_effects (MetaPlugin *plugin,
MetaWindowActor *actor);
static void kill_switch_workspace (MetaPlugin *plugin);
static void show_tile_preview (MetaPlugin *plugin,
MetaWindow *window,
MetaRectangle *tile_rect,
int tile_monitor_number);
static void hide_tile_preview (MetaPlugin *plugin);
static void confirm_display_change (MetaPlugin *plugin);
static const MetaPluginInfo * plugin_info (MetaPlugin *plugin);
@ -151,15 +143,6 @@ typedef struct
} EffectCompleteData;
typedef struct _ScreenTilePreview
{
ClutterActor *actor;
GdkRGBA *preview_color;
MetaRectangle tile_rect;
} ScreenTilePreview;
static void
meta_default_plugin_dispose (GObject *object)
{
@ -220,8 +203,6 @@ meta_default_plugin_class_init (MetaDefaultPluginClass *klass)
plugin_class->unmaximize = unmaximize;
plugin_class->destroy = destroy;
plugin_class->switch_workspace = switch_workspace;
plugin_class->show_tile_preview = show_tile_preview;
plugin_class->hide_tile_preview = hide_tile_preview;
plugin_class->plugin_info = plugin_info;
plugin_class->kill_window_effects = kill_window_effects;
plugin_class->kill_switch_workspace = kill_switch_workspace;
@ -768,82 +749,6 @@ destroy (MetaPlugin *plugin, MetaWindowActor *window_actor)
meta_plugin_destroy_completed (plugin, window_actor);
}
/*
* Tile preview private data accessor
*/
static void
free_screen_tile_preview (gpointer data)
{
ScreenTilePreview *preview = data;
if (G_LIKELY (preview != NULL)) {
clutter_actor_destroy (preview->actor);
g_slice_free (ScreenTilePreview, preview);
}
}
static ScreenTilePreview *
get_screen_tile_preview (MetaScreen *screen)
{
ScreenTilePreview *preview = g_object_get_qdata (G_OBJECT (screen), screen_tile_preview_data_quark);
if (G_UNLIKELY (screen_tile_preview_data_quark == 0))
screen_tile_preview_data_quark = g_quark_from_static_string (SCREEN_TILE_PREVIEW_DATA_KEY);
if (G_UNLIKELY (!preview))
{
preview = g_slice_new0 (ScreenTilePreview);
preview->actor = clutter_actor_new ();
clutter_actor_set_background_color (preview->actor, CLUTTER_COLOR_Blue);
clutter_actor_set_opacity (preview->actor, 100);
clutter_actor_add_child (meta_get_window_group_for_screen (screen), preview->actor);
g_object_set_qdata_full (G_OBJECT (screen),
screen_tile_preview_data_quark, preview,
free_screen_tile_preview);
}
return preview;
}
static void
show_tile_preview (MetaPlugin *plugin,
MetaWindow *window,
MetaRectangle *tile_rect,
int tile_monitor_number)
{
MetaScreen *screen = meta_plugin_get_screen (plugin);
ScreenTilePreview *preview = get_screen_tile_preview (screen);
ClutterActor *window_actor;
if (CLUTTER_ACTOR_IS_VISIBLE (preview->actor)
&& preview->tile_rect.x == tile_rect->x
&& preview->tile_rect.y == tile_rect->y
&& preview->tile_rect.width == tile_rect->width
&& preview->tile_rect.height == tile_rect->height)
return; /* nothing to do */
clutter_actor_set_position (preview->actor, tile_rect->x, tile_rect->y);
clutter_actor_set_size (preview->actor, tile_rect->width, tile_rect->height);
clutter_actor_show (preview->actor);
window_actor = CLUTTER_ACTOR (meta_window_get_compositor_private (window));
clutter_actor_lower (preview->actor, window_actor);
preview->tile_rect = *tile_rect;
}
static void
hide_tile_preview (MetaPlugin *plugin)
{
MetaScreen *screen = meta_plugin_get_screen (plugin);
ScreenTilePreview *preview = get_screen_tile_preview (screen);
clutter_actor_hide (preview->actor);
}
static void
kill_switch_workspace (MetaPlugin *plugin)
{

View File

@ -84,6 +84,14 @@ typedef enum {
META_TILE_MAXIMIZED
} MetaTileMode;
typedef enum {
META_FOCUS_NONE = 0,
META_FOCUS_X_CLIENT = 1,
META_FOCUS_WAYLAND_CLIENT = 2,
META_FOCUS_NO_FOCUS_WINDOW = 3,
META_FOCUS_STAGE = 4
} MetaFocusType;
struct _MetaDisplay
{
GObject parent_instance;
@ -117,6 +125,7 @@ struct _MetaDisplay
* like the no_focus_window or the stage X window. */
Window focus_xwindow;
gulong focus_serial;
MetaFocusType focus_type;
/* last timestamp passed to XSetInputFocus */
guint32 last_focus_time;
@ -484,9 +493,10 @@ gboolean meta_display_process_barrier_event (MetaDisplay *display,
XIEvent *event);
#endif /* HAVE_XI23 */
void meta_display_set_input_focus_xwindow (MetaDisplay *display,
MetaScreen *screen,
Window window,
guint32 timestamp);
void meta_display_set_input_focus_xwindow (MetaDisplay *display,
MetaScreen *screen,
MetaFocusType type,
Window window,
guint32 timestamp);
#endif

View File

@ -1746,11 +1746,12 @@ get_input_event (MetaDisplay *display,
}
static void
update_focus_window (MetaDisplay *display,
MetaWindow *window,
Window xwindow,
gulong serial,
gboolean focused_by_us)
update_focus_window (MetaDisplay *display,
MetaFocusType type,
MetaWindow *window,
Window xwindow,
gulong serial,
gboolean focused_by_us)
{
MetaWaylandCompositor *compositor;
@ -1758,6 +1759,7 @@ update_focus_window (MetaDisplay *display,
display->focused_by_us = focused_by_us;
if (display->focus_xwindow == xwindow &&
display->focus_type == type &&
display->focus_window == window)
return;
@ -1780,6 +1782,7 @@ update_focus_window (MetaDisplay *display,
meta_window_set_focused_internal (previous, FALSE);
}
display->focus_type = type;
display->focus_window = window;
display->focus_xwindow = xwindow;
@ -1806,7 +1809,8 @@ update_focus_window (MetaDisplay *display,
{
compositor = meta_wayland_compositor_get_default ();
if (meta_display_xwindow_is_a_no_focus_window (display, xwindow))
if (display->focus_type == META_FOCUS_NO_FOCUS_WINDOW ||
display->focus_type == META_FOCUS_STAGE)
meta_wayland_compositor_set_input_focus (compositor, NULL);
else if (window && window->surface)
meta_wayland_compositor_set_input_focus (compositor, window);
@ -1848,11 +1852,12 @@ timestamp_too_old (MetaDisplay *display,
}
static void
request_xserver_input_focus_change (MetaDisplay *display,
MetaScreen *screen,
MetaWindow *meta_window,
Window xwindow,
guint32 timestamp)
request_xserver_input_focus_change (MetaDisplay *display,
MetaScreen *screen,
MetaFocusType type,
MetaWindow *meta_window,
Window xwindow,
guint32 timestamp)
{
gulong serial;
@ -1885,6 +1890,7 @@ request_xserver_input_focus_change (MetaDisplay *display,
meta_display_ungrab (display);
update_focus_window (display,
type,
meta_window,
xwindow,
serial,
@ -1906,9 +1912,12 @@ handle_window_focus_event (MetaDisplay *display,
unsigned long serial)
{
MetaWindow *focus_window;
MetaFocusType type;
#ifdef WITH_VERBOSE_MODE
const char *window_type;
type = META_FOCUS_NONE;
/* Note the event can be on either the window or the frame,
* we focus the frame for shaded windows
*/
@ -1920,14 +1929,26 @@ handle_window_focus_event (MetaDisplay *display,
window_type = "frame window";
else
window_type = "unknown client window";
if (window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND)
type = META_FOCUS_WAYLAND_CLIENT;
else
type = META_FOCUS_X_CLIENT;
}
else if (meta_display_xwindow_is_a_no_focus_window (display, event->event))
window_type = "no_focus_window";
{
window_type = "no_focus_window";
type = META_FOCUS_NO_FOCUS_WINDOW;
}
else if (meta_display_screen_for_root (display, event->event))
window_type = "root window";
else
window_type = "unknown window";
/* Don't change type if we don't know the new window */
if (type == META_FOCUS_NONE)
type = display->focus_type;
meta_topic (META_DEBUG_FOCUS,
"Focus %s event received on %s 0x%lx (%s) "
"mode %s detail %s serial %lu\n",
@ -2012,6 +2033,7 @@ handle_window_focus_event (MetaDisplay *display,
display->server_focus_serial == display->focus_serial))
{
update_focus_window (display,
type,
focus_window,
focus_window ? focus_window->xwindow : None,
display->server_focus_serial,
@ -3260,6 +3282,7 @@ meta_display_handle_xevent (MetaDisplay *display,
meta_topic (META_DEBUG_FOCUS, "Earlier attempt to focus %s failed\n",
display->focus_window->desc);
update_focus_window (display,
META_FOCUS_NONE,
meta_display_lookup_x_window (display, display->server_focus_window),
display->server_focus_window,
display->server_focus_serial,
@ -5928,6 +5951,8 @@ meta_display_set_input_focus_window (MetaDisplay *display,
{
request_xserver_input_focus_change (display,
window->screen,
window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND ?
META_FOCUS_WAYLAND_CLIENT : META_FOCUS_X_CLIENT,
window,
focus_frame ? window->frame->xwindow : window->xwindow,
timestamp);
@ -5950,13 +5975,15 @@ meta_display_request_take_focus (MetaDisplay *display,
}
void
meta_display_set_input_focus_xwindow (MetaDisplay *display,
MetaScreen *screen,
Window window,
guint32 timestamp)
meta_display_set_input_focus_xwindow (MetaDisplay *display,
MetaScreen *screen,
MetaFocusType type,
Window window,
guint32 timestamp)
{
request_xserver_input_focus_change (display,
screen,
type,
NULL,
window,
timestamp);
@ -5969,6 +5996,7 @@ meta_display_focus_the_no_focus_window (MetaDisplay *display,
{
request_xserver_input_focus_change (display,
screen,
META_FOCUS_NO_FOCUS_WINDOW,
NULL,
screen->no_focus_window,
timestamp);

View File

@ -2165,7 +2165,7 @@ process_mouse_move_resize_grab (MetaDisplay *display,
{
/* Hide the tiling preview if necessary */
if (window->tile_mode != META_TILE_NONE)
meta_screen_hide_tile_preview (screen);
meta_screen_tile_preview_hide (screen);
/* Restore the original tile mode */
window->tile_mode = display->grab_tile_mode;

View File

@ -653,10 +653,8 @@ meta_idle_monitor_remove_watch (MetaIdleMonitor *monitor,
{
g_return_if_fail (META_IS_IDLE_MONITOR (monitor));
g_object_ref (monitor);
g_hash_table_remove (monitor->watches,
GUINT_TO_POINTER (id));
g_object_unref (monitor);
}
/**

View File

@ -65,6 +65,7 @@ struct _MetaScreen
MetaRectangle rect; /* Size of screen; rect.x & rect.y are always 0 */
MetaUI *ui;
MetaTabPopup *tab_popup, *ws_popup;
MetaTilePreview *tile_preview;
guint tile_preview_timeout_id;
@ -166,9 +167,9 @@ void meta_screen_workspace_popup_select (MetaScreen *screen,
MetaWorkspace*meta_screen_workspace_popup_get_selected (MetaScreen *screen);
void meta_screen_workspace_popup_destroy (MetaScreen *screen);
void meta_screen_update_tile_preview (MetaScreen *screen,
void meta_screen_tile_preview_update (MetaScreen *screen,
gboolean delay);
void meta_screen_hide_tile_preview (MetaScreen *screen);
void meta_screen_tile_preview_hide (MetaScreen *screen);
MetaWindow* meta_screen_get_mouse_window (MetaScreen *screen,
MetaWindow *not_this_one);

View File

@ -762,6 +762,7 @@ meta_screen_new (MetaDisplay *display,
screen->tab_popup = NULL;
screen->ws_popup = NULL;
screen->tile_preview = NULL;
screen->tile_preview_timeout_id = 0;
@ -867,6 +868,9 @@ meta_screen_free (MetaScreen *screen,
if (screen->tile_preview_timeout_id)
g_source_remove (screen->tile_preview_timeout_id);
if (screen->tile_preview)
meta_tile_preview_free (screen->tile_preview);
g_free (screen->screen_name);
g_object_unref (screen);
@ -1676,7 +1680,7 @@ meta_screen_workspace_popup_destroy (MetaScreen *screen)
}
static gboolean
meta_screen_update_tile_preview_timeout (gpointer data)
meta_screen_tile_preview_update_timeout (gpointer data)
{
MetaScreen *screen = data;
MetaWindow *window = screen->display->grab_window;
@ -1684,6 +1688,22 @@ meta_screen_update_tile_preview_timeout (gpointer data)
screen->tile_preview_timeout_id = 0;
if (!screen->tile_preview)
{
Window xwindow;
gulong create_serial;
MetaStackWindow stack_window;
screen->tile_preview = meta_tile_preview_new (screen->number);
xwindow = meta_tile_preview_get_xwindow (screen->tile_preview,
&create_serial);
stack_window.any.type = META_WINDOW_CLIENT_TYPE_X11;
stack_window.x11.xwindow = xwindow;
meta_stack_tracker_record_add (screen->stack_tracker,
&stack_window,
create_serial);
}
if (window)
{
switch (window->tile_mode)
@ -1708,16 +1728,12 @@ meta_screen_update_tile_preview_timeout (gpointer data)
if (needs_preview)
{
MetaRectangle tile_rect;
int monitor;
monitor = meta_window_get_current_tile_monitor_number (window);
meta_window_get_current_tile_area (window, &tile_rect);
meta_compositor_show_tile_preview (screen->display->compositor,
screen, window, &tile_rect, monitor);
meta_tile_preview_show (screen->tile_preview, &tile_rect);
}
else
meta_compositor_hide_tile_preview (screen->display->compositor,
screen);
meta_tile_preview_hide (screen->tile_preview);
return FALSE;
}
@ -1725,7 +1741,7 @@ meta_screen_update_tile_preview_timeout (gpointer data)
#define TILE_PREVIEW_TIMEOUT_MS 200
void
meta_screen_update_tile_preview (MetaScreen *screen,
meta_screen_tile_preview_update (MetaScreen *screen,
gboolean delay)
{
if (delay)
@ -1735,7 +1751,7 @@ meta_screen_update_tile_preview (MetaScreen *screen,
screen->tile_preview_timeout_id =
g_timeout_add (TILE_PREVIEW_TIMEOUT_MS,
meta_screen_update_tile_preview_timeout,
meta_screen_tile_preview_update_timeout,
screen);
}
else
@ -1743,18 +1759,18 @@ meta_screen_update_tile_preview (MetaScreen *screen,
if (screen->tile_preview_timeout_id > 0)
g_source_remove (screen->tile_preview_timeout_id);
meta_screen_update_tile_preview_timeout ((gpointer)screen);
meta_screen_tile_preview_update_timeout ((gpointer)screen);
}
}
void
meta_screen_hide_tile_preview (MetaScreen *screen)
meta_screen_tile_preview_hide (MetaScreen *screen)
{
if (screen->tile_preview_timeout_id > 0)
g_source_remove (screen->tile_preview_timeout_id);
meta_compositor_hide_tile_preview (screen->display->compositor,
screen);
if (screen->tile_preview)
meta_tile_preview_hide (screen->tile_preview);
}
MetaWindow*

View File

@ -1041,7 +1041,7 @@ stack_tracker_event_received (MetaStackTracker *tracker,
if (op->any.serial < tracker->xserver_serial)
{
/* g_warning ("Spurious X event received affecting stack; doing full re-query"); */
g_warning ("Spurious X event received affecting stack; doing full re-query");
resync_verified_stack_with_xserver_stack (tracker);
meta_stack_tracker_dump (tracker);
return;

View File

@ -652,7 +652,6 @@ void meta_window_handle_mouse_grab_op_xevent (MetaWindow *window,
GList* meta_window_get_workspaces (MetaWindow *window);
int meta_window_get_current_tile_monitor_number (MetaWindow *window);
void meta_window_get_current_tile_area (MetaWindow *window,
MetaRectangle *tile_area);

View File

@ -350,43 +350,11 @@ meta_window_set_input_region (MetaWindow *window,
meta_compositor_window_shape_changed (window->display->compositor, window);
}
#if 0
/* Print out a region; useful for debugging */
static void
print_region (cairo_region_t *region)
{
int n_rects;
int i;
n_rects = cairo_region_num_rectangles (region);
g_print ("[");
for (i = 0; i < n_rects; i++)
{
cairo_rectangle_int_t rect;
cairo_region_get_rectangle (region, i, &rect);
g_print ("+%d+%dx%dx%d ",
rect.x, rect.y, rect.width, rect.height);
}
g_print ("]\n");
}
#endif
void
meta_window_x11_update_input_region (MetaWindow *window)
{
cairo_region_t *region = NULL;
/* Decorated windows don't have an input region, because
we don't shape the frame to match the client windows
(so the events are blocked by the frame anyway)
*/
if (window->decorated)
{
if (window->input_region)
meta_window_set_input_region (window, NULL);
return;
}
#ifdef HAVE_SHAPE
if (META_DISPLAY_HAS_SHAPE (window->display))
{
@ -395,6 +363,17 @@ meta_window_x11_update_input_region (MetaWindow *window)
XRectangle *rects = NULL;
int n_rects, ordering;
int x_bounding, y_bounding, x_clip, y_clip;
unsigned w_bounding, h_bounding, w_clip, h_clip;
int bounding_shaped, clip_shaped;
meta_error_trap_push (window->display);
XShapeQueryExtents (window->display->xdisplay, window->xwindow,
&bounding_shaped, &x_bounding, &y_bounding,
&w_bounding, &h_bounding,
&clip_shaped, &x_clip, &y_clip,
&w_clip, &h_clip);
rects = XShapeGetRectangles (window->display->xdisplay,
window->xwindow,
ShapeInput,
@ -409,10 +388,10 @@ meta_window_x11_update_input_region (MetaWindow *window)
{
if (n_rects > 1 ||
(n_rects == 1 &&
(rects[0].x != 0 ||
rects[0].y != 0 ||
rects[0].width != window->rect.width ||
rects[0].height != window->rect.height)))
(rects[0].x != x_bounding ||
rects[0].y != y_bounding ||
rects[0].width != w_bounding ||
rects[0].height != h_bounding)))
region = region_create_from_x_rectangles (rects, n_rects);
XFree (rects);
@ -1474,11 +1453,6 @@ meta_window_x11_new (MetaDisplay *display,
XISelectEvents (display->xdisplay, xwindow, &mask, 1);
}
#ifdef HAVE_SHAPE
if (META_DISPLAY_HAS_SHAPE (display))
XShapeSelectInput (display->xdisplay, xwindow, ShapeNotifyMask);
#endif
/* Get rid of any borders */
if (attrs.border_width != 0)
XSetWindowBorderWidth (display->xdisplay, xwindow, 0);
@ -1511,7 +1485,14 @@ meta_window_x11_new (MetaDisplay *display,
existing_wm_state,
effect,
&attrs);
meta_window_set_surface_mapped (window, TRUE);
/* When running as an X compositor, we can simply show the window now.
*
* When running as a Wayland compositor, we need to wait until we see
* the Wayland surface appear. We will later call meta_window_set_surface_mapped()
* to show the window in our in our set_surface_id implementation */
if (!meta_is_wayland_compositor ())
meta_window_set_surface_mapped (window, TRUE);
meta_error_trap_pop (display); /* pop the XSync()-reducing trap */
return window;

View File

@ -1177,6 +1177,9 @@ _meta_window_shared_new (MetaDisplay *display,
if (!window->override_redirect)
meta_stack_add (window->screen->stack,
window);
else if (window->screen->tile_preview != NULL &&
meta_tile_preview_get_xwindow (window->screen->tile_preview, NULL) == xwindow)
window->layer = META_LAYER_NORMAL;
else
window->layer = META_LAYER_OVERRIDE_REDIRECT; /* otherwise set by MetaStack */
@ -1217,9 +1220,6 @@ _meta_window_shared_new (MetaDisplay *display,
set_net_wm_state (window);
}
if (screen->display->compositor)
meta_compositor_add_window (screen->display->compositor, window);
/* Sync stack changes */
meta_stack_thaw (window->screen->stack);
@ -2772,8 +2772,8 @@ meta_window_show (MetaWindow *window)
break;
}
meta_compositor_show_window (window->display->compositor,
window, effect);
meta_compositor_add_window (window->display->compositor, window);
meta_compositor_show_window (window->display->compositor, window, effect);
}
}
@ -3369,7 +3369,7 @@ meta_window_tile (MetaWindow *window)
directions = META_MAXIMIZE_VERTICAL;
meta_window_maximize_internal (window, directions, NULL);
meta_screen_update_tile_preview (window->screen, FALSE);
meta_screen_tile_preview_update (window->screen, FALSE);
if (window->display->compositor)
{
@ -8108,7 +8108,7 @@ update_move (MetaWindow *window,
* trigger it unwittingly, e.g. when shaking loose the window or moving
* it to another monitor.
*/
meta_screen_update_tile_preview (window->screen,
meta_screen_tile_preview_update (window->screen,
window->tile_mode != META_TILE_NONE);
meta_window_get_client_root_coords (window, &old);
@ -8956,20 +8956,6 @@ meta_window_get_work_area_all_monitors (MetaWindow *window,
window->desc, area->x, area->y, area->width, area->height);
}
int
meta_window_get_current_tile_monitor_number (MetaWindow *window)
{
int tile_monitor_number = window->tile_monitor_number;
if (tile_monitor_number < 0)
{
meta_warning ("%s called with an invalid monitor number; using 0 instead\n", G_STRFUNC);
tile_monitor_number = 0;
}
return tile_monitor_number;
}
void
meta_window_get_current_tile_area (MetaWindow *window,
MetaRectangle *tile_area)
@ -8978,7 +8964,12 @@ meta_window_get_current_tile_area (MetaWindow *window,
g_return_if_fail (window->tile_mode != META_TILE_NONE);
tile_monitor_number = meta_window_get_current_tile_monitor_number (window);
tile_monitor_number = window->tile_monitor_number;
if (tile_monitor_number < 0)
{
meta_warning ("%s called with an invalid monitor number; using 0 instead\n", G_STRFUNC);
tile_monitor_number = 0;
}
meta_window_get_work_area_for_monitor (window, tile_monitor_number, tile_area);

View File

@ -66,8 +66,6 @@ void meta_compositor_window_shape_changed (MetaCompositor *compositor,
MetaWindow *window);
void meta_compositor_window_opacity_changed (MetaCompositor *compositor,
MetaWindow *window);
void meta_compositor_window_surface_changed (MetaCompositor *compositor,
MetaWindow *window);
gboolean meta_compositor_process_event (MetaCompositor *compositor,
XEvent *event,
@ -123,12 +121,4 @@ void meta_compositor_sync_screen_size (MetaCompositor *compositor,
void meta_compositor_flash_screen (MetaCompositor *compositor,
MetaScreen *screen);
void meta_compositor_show_tile_preview (MetaCompositor *compositor,
MetaScreen *screen,
MetaWindow *window,
MetaRectangle *tile_rect,
int tile_monitor_number);
void meta_compositor_hide_tile_preview (MetaCompositor *compositor,
MetaScreen *screen);
#endif /* META_COMPOSITOR_H */

View File

@ -158,11 +158,6 @@ struct _MetaPluginClass
gint to,
MetaMotionDirection direction);
void (*show_tile_preview) (MetaPlugin *plugin,
MetaWindow *window,
MetaRectangle *tile_rect,
int tile_monitor_number);
void (*hide_tile_preview) (MetaPlugin *plugin);
/**
* MetaPluginClass::kill_window_effects:

View File

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

196
src/ui/tile-preview.c Normal file
View File

@ -0,0 +1,196 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* Mutter tile-preview marks the area a window will *ehm* snap to */
/*
* Copyright (C) 2010 Florian Müllner
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include <gtk/gtk.h>
#include <cairo.h>
#include "tile-preview.h"
#include "core.h"
#define OUTLINE_WIDTH 5 /* frame width in non-composite case */
struct _MetaTilePreview {
GtkWidget *preview_window;
gulong create_serial;
GdkRGBA *preview_color;
MetaRectangle tile_rect;
};
static gboolean
meta_tile_preview_draw (GtkWidget *widget,
cairo_t *cr,
gpointer user_data)
{
MetaTilePreview *preview = user_data;
cairo_set_line_width (cr, 1.0);
/* Fill the preview area with a transparent color */
gdk_cairo_set_source_rgba (cr, preview->preview_color);
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
cairo_paint (cr);
/* Use the opaque color for the border */
cairo_set_source_rgb (cr,
preview->preview_color->red,
preview->preview_color->green,
preview->preview_color->blue);
cairo_rectangle (cr,
0.5, 0.5,
preview->tile_rect.width - 1,
preview->tile_rect.height - 1);
cairo_stroke (cr);
return FALSE;
}
MetaTilePreview *
meta_tile_preview_new (int screen_number)
{
MetaTilePreview *preview;
GdkScreen *screen;
GtkStyleContext *context;
GtkWidgetPath *path;
guchar selection_alpha = 0xFF;
screen = gdk_display_get_screen (gdk_display_get_default (), screen_number);
preview = g_new (MetaTilePreview, 1);
preview->preview_window = gtk_window_new (GTK_WINDOW_POPUP);
gtk_window_set_screen (GTK_WINDOW (preview->preview_window), screen);
gtk_widget_set_app_paintable (preview->preview_window, TRUE);
preview->preview_color = NULL;
preview->tile_rect.x = preview->tile_rect.y = 0;
preview->tile_rect.width = preview->tile_rect.height = 0;
gtk_widget_set_visual (preview->preview_window,
gdk_screen_get_rgba_visual (screen));
path = gtk_widget_path_new ();
gtk_widget_path_append_type (path, GTK_TYPE_ICON_VIEW);
context = gtk_style_context_new ();
gtk_style_context_set_path (context, path);
gtk_style_context_add_class (context,
GTK_STYLE_CLASS_RUBBERBAND);
gtk_widget_path_free (path);
gtk_style_context_get (context, GTK_STATE_FLAG_SELECTED,
"background-color", &preview->preview_color,
NULL);
/* The background-color for the .rubberband class should probably
* contain the correct alpha value - unfortunately, at least for now
* it doesn't. Hopefully the following workaround can be removed
* when GtkIconView gets ported to GtkStyleContext.
*/
gtk_style_context_get_style (context,
"selection-box-alpha", &selection_alpha,
NULL);
preview->preview_color->alpha = (double)selection_alpha / 0xFF;
g_object_unref (context);
/* We make an assumption that XCreateWindow will be the first operation
* when calling gtk_widget_realize() (via gdk_window_new()), or that it
* is at least "close enough".
*/
preview->create_serial = XNextRequest (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
gtk_widget_realize (preview->preview_window);
g_signal_connect (preview->preview_window, "draw",
G_CALLBACK (meta_tile_preview_draw), preview);
return preview;
}
void
meta_tile_preview_free (MetaTilePreview *preview)
{
gtk_widget_destroy (preview->preview_window);
if (preview->preview_color)
gdk_rgba_free (preview->preview_color);
g_free (preview);
}
void
meta_tile_preview_show (MetaTilePreview *preview,
MetaRectangle *tile_rect)
{
GdkWindow *window;
GdkRectangle old_rect;
if (gtk_widget_get_visible (preview->preview_window)
&& preview->tile_rect.x == tile_rect->x
&& preview->tile_rect.y == tile_rect->y
&& preview->tile_rect.width == tile_rect->width
&& preview->tile_rect.height == tile_rect->height)
return; /* nothing to do */
gtk_widget_show (preview->preview_window);
window = gtk_widget_get_window (preview->preview_window);
meta_core_lower_beneath_grab_window (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
GDK_WINDOW_XID (window),
gtk_get_current_event_time ());
old_rect.x = old_rect.y = 0;
old_rect.width = preview->tile_rect.width;
old_rect.height = preview->tile_rect.height;
gdk_window_invalidate_rect (window, &old_rect, FALSE);
preview->tile_rect = *tile_rect;
gdk_window_move_resize (window,
preview->tile_rect.x, preview->tile_rect.y,
preview->tile_rect.width, preview->tile_rect.height);
}
void
meta_tile_preview_hide (MetaTilePreview *preview)
{
gtk_widget_hide (preview->preview_window);
}
Window
meta_tile_preview_get_xwindow (MetaTilePreview *preview,
gulong *create_serial)
{
GdkWindow *window = gtk_widget_get_window (preview->preview_window);
if (create_serial)
*create_serial = preview->create_serial;
return GDK_WINDOW_XID (window);
}

36
src/ui/tile-preview.h Normal file
View File

@ -0,0 +1,36 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* Meta tile preview */
/*
* Copyright (C) 2010 Florian Müllner
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef META_TILE_PREVIEW_H
#define META_TILE_PREVIEW_H
#include <meta/boxes.h>
typedef struct _MetaTilePreview MetaTilePreview;
MetaTilePreview *meta_tile_preview_new (int screen_number);
void meta_tile_preview_free (MetaTilePreview *preview);
void meta_tile_preview_show (MetaTilePreview *preview,
MetaRectangle *rect);
void meta_tile_preview_hide (MetaTilePreview *preview);
Window meta_tile_preview_get_xwindow (MetaTilePreview *preview,
gulong *create_serial);
#endif /* META_TILE_PREVIEW_H */

View File

@ -179,5 +179,6 @@ int meta_ui_get_drag_threshold (MetaUI *ui);
MetaUIDirection meta_ui_get_direction (void);
#include "tabpopup.h"
#include "tile-preview.h"
#endif

View File

@ -217,28 +217,28 @@ err_keymap_str:
return;
}
static void
release_focus (MetaWaylandKeyboard *keyboard)
{
wl_list_remove (&keyboard->focus_surface_listener.link);
wl_list_remove (&keyboard->focus_resource_listener.link);
keyboard->focus_resource = NULL;
keyboard->focus_surface = NULL;
}
static void
keyboard_handle_focus_surface_destroy (struct wl_listener *listener, void *data)
{
MetaWaylandKeyboard *keyboard = wl_container_of (listener, keyboard, focus_surface_listener);
wl_list_remove (&keyboard->focus_surface_listener.link);
keyboard->focus_surface = NULL;
if (keyboard->focus_resource)
{
wl_list_remove (&keyboard->focus_resource_listener.link);
keyboard->focus_resource = NULL;
}
release_focus (keyboard);
}
static void
keyboard_handle_focus_resource_destroy (struct wl_listener *listener, void *data)
{
MetaWaylandKeyboard *keyboard = wl_container_of (listener, keyboard, focus_resource_listener);
wl_list_remove (&keyboard->focus_resource_listener.link);
keyboard->focus_resource = NULL;
release_focus (keyboard);
}
static gboolean

View File

@ -55,28 +55,28 @@
static void meta_wayland_pointer_end_popup_grab (MetaWaylandPointer *pointer);
static void
release_focus (MetaWaylandPointer *pointer)
{
wl_list_remove (&pointer->focus_surface_listener.link);
wl_list_remove (&pointer->focus_resource_listener.link);
pointer->focus_resource = NULL;
pointer->focus_surface = NULL;
}
static void
pointer_handle_focus_surface_destroy (struct wl_listener *listener, void *data)
{
MetaWaylandPointer *pointer = wl_container_of (listener, pointer, focus_surface_listener);
wl_list_remove (&pointer->focus_surface_listener.link);
pointer->focus_surface = NULL;
if (pointer->focus_resource)
{
wl_list_remove (&pointer->focus_resource_listener.link);
pointer->focus_resource = NULL;
}
release_focus (pointer);
}
static void
pointer_handle_focus_resource_destroy (struct wl_listener *listener, void *data)
{
MetaWaylandPointer *pointer = wl_container_of (listener, pointer, focus_resource_listener);
wl_list_remove (&pointer->focus_resource_listener.link);
pointer->focus_resource = NULL;
release_focus (pointer);
}
static void
@ -302,7 +302,7 @@ meta_wayland_pointer_init (MetaWaylandPointer *pointer)
void
meta_wayland_pointer_release (MetaWaylandPointer *pointer)
{
/* Do nothing. */
release_focus (pointer);
}
static struct wl_resource *

View File

@ -574,16 +574,23 @@ const struct wl_surface_interface meta_wayland_surface_interface = {
meta_wayland_surface_set_buffer_scale
};
void
meta_wayland_surface_make_toplevel (MetaWaylandSurface *surface)
static void
unparent_actor (MetaWaylandSurface *surface)
{
clutter_actor_set_reactive (CLUTTER_ACTOR (surface->surface_actor), TRUE);
ClutterActor *parent_actor;
parent_actor = clutter_actor_get_parent (CLUTTER_ACTOR (surface->surface_actor));
clutter_actor_remove_child (parent_actor, CLUTTER_ACTOR (surface->surface_actor));
}
void
meta_wayland_surface_window_unmanaged (MetaWaylandSurface *surface)
{
clutter_actor_set_reactive (CLUTTER_ACTOR (surface->surface_actor), FALSE);
/* The window is being unmanaged. Unparent our surface actor
* before the window actor is destroyed, as we need to hold
* onto it... */
unparent_actor (surface);
surface->window = NULL;
}
@ -642,8 +649,10 @@ meta_wayland_surface_create (MetaWaylandCompositor *compositor,
surface->buffer_destroy_listener.notify = surface_handle_buffer_destroy;
surface->surface_actor = g_object_ref_sink (meta_surface_actor_wayland_new (surface));
clutter_actor_set_reactive (CLUTTER_ACTOR (surface->surface_actor), TRUE);
double_buffered_state_init (&surface->pending);
return surface;
}
@ -971,7 +980,6 @@ xdg_shell_get_xdg_surface (struct wl_client *client,
return;
}
meta_wayland_surface_make_toplevel (surface);
surface->window = meta_window_wayland_new (meta_get_display (), surface);
}
@ -1027,7 +1035,6 @@ xdg_shell_get_xdg_popup (struct wl_client *client,
return;
}
meta_wayland_surface_make_toplevel (surface);
surface->window = meta_window_wayland_new (meta_get_display (), surface);
surface->window->rect.x = parent_surf->window->rect.x + x;
surface->window->rect.y = parent_surf->window->rect.y + y;
@ -1242,14 +1249,6 @@ subsurface_parent_surface_committed (MetaWaylandSurface *surface)
double_buffered_state_reset (pending_surface_state);
}
static void
unparent_actor (MetaWaylandSurface *surface)
{
ClutterActor *parent_actor;
parent_actor = clutter_actor_get_parent (CLUTTER_ACTOR (surface->surface_actor));
clutter_actor_remove_child (parent_actor, CLUTTER_ACTOR (surface->surface_actor));
}
static void
wl_subsurface_destructor (struct wl_resource *resource)
{

View File

@ -118,7 +118,6 @@ MetaWaylandSurface *meta_wayland_surface_create (MetaWaylandCompositor *composit
guint32 id,
guint32 version);
void meta_wayland_surface_make_toplevel (MetaWaylandSurface *surface);
void meta_wayland_surface_window_unmanaged (MetaWaylandSurface *surface);
void meta_wayland_surface_configure_notify (MetaWaylandSurface *surface,

View File

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