2009-06-26 19:33:20 +00:00
|
|
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
|
|
|
|
2013-03-11 15:52:36 +00:00
|
|
|
/**
|
|
|
|
* SECTION:meta-window-actor
|
|
|
|
* @title: MetaWindowActor
|
2018-10-19 07:15:54 +00:00
|
|
|
* @short_description: An actor representing a top-level window in the scene
|
|
|
|
* graph
|
|
|
|
*
|
|
|
|
* #MetaWindowActor is a #ClutterActor that adds a notion of a window to the
|
|
|
|
* Clutter scene graph. It contains a #MetaWindow which provides the windowing
|
|
|
|
* API, and the #MetaCompositor that handles it. For the actual content of the
|
|
|
|
* window, it contains a #MetaSurfaceActor.
|
|
|
|
*
|
|
|
|
* #MetaWindowActor takes care of the rendering features you need for your
|
|
|
|
* window. For example, it will take the windows' requested opacity and use
|
|
|
|
* that for clutter_actor_set_opacity(). Furthermore, it will also draw a
|
|
|
|
* shadow around the window (using #MetaShadow) and deal with synchronization
|
|
|
|
* between events of the window and the actual render loop. See
|
|
|
|
* MetaWindowActor::first-frame for an example of the latter.
|
2013-03-11 15:52:36 +00:00
|
|
|
*/
|
|
|
|
|
2018-07-10 08:36:24 +00:00
|
|
|
#include "config.h"
|
2010-09-10 14:06:37 +00:00
|
|
|
|
2009-06-29 18:30:26 +00:00
|
|
|
#include <math.h>
|
2012-04-27 04:14:42 +00:00
|
|
|
#include <string.h>
|
2009-06-26 19:33:20 +00:00
|
|
|
|
2018-12-04 15:29:47 +00:00
|
|
|
#include "backends/meta-screen-cast-window.h"
|
2018-07-10 08:36:24 +00:00
|
|
|
#include "compositor/compositor-private.h"
|
2019-09-28 08:26:21 +00:00
|
|
|
#include "compositor/meta-shaped-texture-private.h"
|
2018-07-10 08:36:24 +00:00
|
|
|
#include "compositor/meta-surface-actor-x11.h"
|
|
|
|
#include "compositor/meta-surface-actor.h"
|
|
|
|
#include "compositor/meta-window-actor-private.h"
|
2019-08-17 08:00:46 +00:00
|
|
|
#include "core/boxes-private.h"
|
|
|
|
#include "core/window-private.h"
|
2018-07-10 08:36:24 +00:00
|
|
|
#include "meta/window.h"
|
2017-08-26 16:26:30 +00:00
|
|
|
|
2014-08-14 00:19:35 +00:00
|
|
|
#ifdef HAVE_WAYLAND
|
2018-07-10 08:36:24 +00:00
|
|
|
#include "compositor/meta-surface-actor-wayland.h"
|
2014-03-19 02:01:31 +00:00
|
|
|
#include "wayland/meta-wayland-surface.h"
|
2014-08-27 16:41:26 +00:00
|
|
|
#endif
|
2014-03-19 02:01:31 +00:00
|
|
|
|
2018-12-19 08:04:25 +00:00
|
|
|
typedef enum
|
|
|
|
{
|
2014-05-21 13:57:15 +00:00
|
|
|
INITIALLY_FROZEN,
|
|
|
|
DRAWING_FIRST_FRAME,
|
|
|
|
EMITTED_FIRST_FRAME
|
|
|
|
} FirstFrameState;
|
|
|
|
|
2018-12-21 20:12:49 +00:00
|
|
|
typedef struct _MetaWindowActorPrivate
|
2009-06-26 19:33:20 +00:00
|
|
|
{
|
2014-03-18 21:31:22 +00:00
|
|
|
MetaWindow *window;
|
|
|
|
MetaCompositor *compositor;
|
2009-06-26 19:33:20 +00:00
|
|
|
|
2022-07-02 19:51:13 +00:00
|
|
|
gulong stage_views_changed_id;
|
|
|
|
|
2013-10-13 11:47:53 +00:00
|
|
|
MetaSurfaceActor *surface;
|
2013-11-05 03:13:33 +00:00
|
|
|
|
2019-07-12 17:33:17 +00:00
|
|
|
int geometry_scale;
|
|
|
|
|
2009-06-26 19:33:20 +00:00
|
|
|
/*
|
|
|
|
* These need to be counters rather than flags, since more plugins
|
|
|
|
* can implement same effect; the practicality of stacking effects
|
|
|
|
* might be dubious, but we have to at least handle it correctly.
|
|
|
|
*/
|
|
|
|
gint minimize_in_progress;
|
2013-06-14 01:01:17 +00:00
|
|
|
gint unminimize_in_progress;
|
2015-07-06 04:08:08 +00:00
|
|
|
gint size_change_in_progress;
|
2009-06-26 19:33:20 +00:00
|
|
|
gint map_in_progress;
|
|
|
|
gint destroy_in_progress;
|
|
|
|
|
2014-02-24 21:00:12 +00:00
|
|
|
guint freeze_count;
|
2023-02-11 06:03:27 +00:00
|
|
|
guint screen_cast_usage_count;
|
2011-06-13 22:09:59 +00:00
|
|
|
|
Simplify relationship between mapping and visibility
Previously, changes to the visibility of a window could be indicated
by meta_compositor_map_window(), meta_compositor_unminimize_window(),
meta_compositor_set_window_hidden(), etc, with the exact behavior
depending on the 'live_hidden_windows' preference.
Simplify this so that visibility is controlled by:
meta_compositor_show_window()
meta_compositor_hide_window()
With an 'effect' parameter provided to indicate the appropriate
effect (CREATE/UNMINIMIZE/MINIMIZE/DESTROY/NONE.)
The map state of the window is signalled separately by:
meta_compositor_map_window()
meta_compositor_unmap_window()
And is used only to control resource handling.
Other changes:
* The desired effect on show/hide is explicitly stored in
MetaWindow, avoiding the need for the was_minimized flag.
At idle, once we calculate the window state, we pass the
effect to the compositor if it matches the new window
state, and then clear the effect to start over for future
map state changes.
* meta_compositor_switch_workspace() is called before any windows
are hidden or shown, allowing the compositor to avoid hiding
or showing an effect for windows involved in the switch.
http://bugzilla.gnome.org/show_bug.cgi?id=582341
* Handling of post-effect cleanups for MutterWindow are
simplified - instead of trying to do different things based
on the individual needs of different effects, we just wait until
all effects complete and sync the window state to what it
should be.
* On unmap, once we destroy the pixmap, we tell ClutterX11Pixmap
that we've done so, so it can clean up and unbind. (The
unbinding doesn't seem to be working properly because of
ClutterGLXPixmap or video driver issues.)
http://bugzilla.gnome.org/show_bug.cgi?id=587251
2009-06-28 21:10:40 +00:00
|
|
|
guint visible : 1;
|
2009-06-26 19:33:20 +00:00
|
|
|
guint disposed : 1;
|
|
|
|
|
|
|
|
guint needs_destroy : 1;
|
|
|
|
|
2012-01-07 22:21:32 +00:00
|
|
|
guint updates_frozen : 1;
|
2014-05-21 13:57:15 +00:00
|
|
|
guint first_frame_state : 2; /* FirstFrameState */
|
2018-12-21 20:12:49 +00:00
|
|
|
} MetaWindowActorPrivate;
|
2009-06-26 19:33:20 +00:00
|
|
|
|
2014-05-21 13:57:15 +00:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
FIRST_FRAME,
|
2018-04-04 08:10:32 +00:00
|
|
|
EFFECTS_COMPLETED,
|
2019-08-26 13:09:53 +00:00
|
|
|
DAMAGED,
|
2019-08-17 08:00:46 +00:00
|
|
|
THAWED,
|
2018-04-04 08:10:32 +00:00
|
|
|
|
2014-05-21 13:57:15 +00:00
|
|
|
LAST_SIGNAL
|
|
|
|
};
|
|
|
|
|
|
|
|
static guint signals[LAST_SIGNAL] = { 0 };
|
|
|
|
|
2009-06-26 19:33:20 +00:00
|
|
|
enum
|
|
|
|
{
|
2010-10-18 17:27:14 +00:00
|
|
|
PROP_META_WINDOW = 1,
|
2009-06-26 19:33:20 +00:00
|
|
|
};
|
|
|
|
|
2010-10-18 17:27:14 +00:00
|
|
|
static void meta_window_actor_dispose (GObject *object);
|
|
|
|
static void meta_window_actor_constructed (GObject *object);
|
|
|
|
static void meta_window_actor_set_property (GObject *object,
|
|
|
|
guint prop_id,
|
|
|
|
const GValue *value,
|
|
|
|
GParamSpec *pspec);
|
|
|
|
static void meta_window_actor_get_property (GObject *object,
|
|
|
|
guint prop_id,
|
|
|
|
GValue *value,
|
|
|
|
GParamSpec *pspec);
|
2009-06-26 19:33:20 +00:00
|
|
|
|
2022-05-11 20:32:33 +00:00
|
|
|
static MetaSurfaceActor * meta_window_actor_real_get_scanout_candidate (MetaWindowActor *self);
|
2022-01-05 21:05:50 +00:00
|
|
|
|
2019-06-27 17:33:24 +00:00
|
|
|
static void meta_window_actor_real_assign_surface_actor (MetaWindowActor *self,
|
|
|
|
MetaSurfaceActor *surface_actor);
|
|
|
|
|
2018-12-04 15:29:47 +00:00
|
|
|
static void screen_cast_window_iface_init (MetaScreenCastWindowInterface *iface);
|
|
|
|
|
2019-01-03 18:17:08 +00:00
|
|
|
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (MetaWindowActor, meta_window_actor, CLUTTER_TYPE_ACTOR,
|
|
|
|
G_ADD_PRIVATE (MetaWindowActor)
|
|
|
|
G_IMPLEMENT_INTERFACE (META_TYPE_SCREEN_CAST_WINDOW, screen_cast_window_iface_init));
|
2009-06-26 19:33:20 +00:00
|
|
|
|
|
|
|
static void
|
2010-10-18 17:27:14 +00:00
|
|
|
meta_window_actor_class_init (MetaWindowActorClass *klass)
|
2009-06-26 19:33:20 +00:00
|
|
|
{
|
|
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
|
|
GParamSpec *pspec;
|
|
|
|
|
2010-10-18 17:27:14 +00:00
|
|
|
object_class->dispose = meta_window_actor_dispose;
|
|
|
|
object_class->set_property = meta_window_actor_set_property;
|
|
|
|
object_class->get_property = meta_window_actor_get_property;
|
|
|
|
object_class->constructed = meta_window_actor_constructed;
|
2009-06-26 19:33:20 +00:00
|
|
|
|
2022-05-11 20:32:33 +00:00
|
|
|
klass->get_scanout_candidate = meta_window_actor_real_get_scanout_candidate;
|
2019-06-27 17:33:24 +00:00
|
|
|
klass->assign_surface_actor = meta_window_actor_real_assign_surface_actor;
|
2018-12-21 20:51:02 +00:00
|
|
|
|
2014-05-21 13:57:15 +00:00
|
|
|
/**
|
|
|
|
* MetaWindowActor::first-frame:
|
|
|
|
* @actor: the #MetaWindowActor instance
|
|
|
|
*
|
|
|
|
* The ::first-frame signal will be emitted the first time a frame
|
|
|
|
* of window contents has been drawn by the application and Mutter
|
|
|
|
* has had the chance to drawn that frame to the screen. If the
|
|
|
|
* window starts off initially hidden, obscured, or on on a
|
|
|
|
* different workspace, the ::first-frame signal will be emitted
|
|
|
|
* even though the user doesn't see the contents.
|
|
|
|
*
|
|
|
|
* MetaDisplay::window-created is a good place to connect to this
|
|
|
|
* signal - at that point, the MetaWindowActor for the window
|
|
|
|
* exists, but the window has reliably not yet been drawn.
|
|
|
|
* Connecting to an existing window that has already been drawn to
|
|
|
|
* the screen is not useful.
|
|
|
|
*/
|
|
|
|
signals[FIRST_FRAME] =
|
|
|
|
g_signal_new ("first-frame",
|
|
|
|
G_TYPE_FROM_CLASS (object_class),
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
0,
|
|
|
|
NULL, NULL, NULL,
|
|
|
|
G_TYPE_NONE, 0);
|
|
|
|
|
2018-04-04 08:10:32 +00:00
|
|
|
/**
|
|
|
|
* MetaWindowActor::effects-completed:
|
|
|
|
* @actor: the #MetaWindowActor instance
|
|
|
|
*
|
|
|
|
* The ::effects-completed signal will be emitted once all pending compositor
|
|
|
|
* effects are completed.
|
|
|
|
*/
|
|
|
|
signals[EFFECTS_COMPLETED] =
|
|
|
|
g_signal_new ("effects-completed",
|
|
|
|
G_TYPE_FROM_CLASS (object_class),
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
0,
|
|
|
|
NULL, NULL, NULL,
|
|
|
|
G_TYPE_NONE, 0);
|
|
|
|
|
2019-08-26 13:09:53 +00:00
|
|
|
/**
|
|
|
|
* MetaWindowActor::damaged:
|
|
|
|
* @actor: the #MetaWindowActor instance
|
|
|
|
*
|
|
|
|
* Notify that one or more of the surfaces of the window have been damaged.
|
|
|
|
*/
|
|
|
|
signals[DAMAGED] =
|
|
|
|
g_signal_new ("damaged",
|
|
|
|
G_TYPE_FROM_CLASS (object_class),
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
0,
|
|
|
|
NULL, NULL, NULL,
|
|
|
|
G_TYPE_NONE, 0);
|
|
|
|
|
2019-08-17 08:00:46 +00:00
|
|
|
/**
|
|
|
|
* MetaWindowActor::thawed:
|
|
|
|
* @actor: the #MetaWindowActor instance
|
|
|
|
*/
|
|
|
|
signals[THAWED] =
|
|
|
|
g_signal_new ("thawed",
|
|
|
|
G_TYPE_FROM_CLASS (object_class),
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
0,
|
|
|
|
NULL, NULL, NULL,
|
|
|
|
G_TYPE_NONE, 0);
|
|
|
|
|
2009-06-26 19:33:20 +00:00
|
|
|
pspec = g_param_spec_object ("meta-window",
|
|
|
|
"MetaWindow",
|
|
|
|
"The displayed MetaWindow",
|
|
|
|
META_TYPE_WINDOW,
|
2012-04-23 22:54:46 +00:00
|
|
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
2009-06-26 19:33:20 +00:00
|
|
|
|
|
|
|
g_object_class_install_property (object_class,
|
2010-10-18 17:27:14 +00:00
|
|
|
PROP_META_WINDOW,
|
2009-06-26 19:33:20 +00:00
|
|
|
pspec);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2010-10-18 17:27:14 +00:00
|
|
|
meta_window_actor_init (MetaWindowActor *self)
|
2009-06-26 19:33:20 +00:00
|
|
|
{
|
2019-07-12 17:33:17 +00:00
|
|
|
MetaWindowActorPrivate *priv =
|
|
|
|
meta_window_actor_get_instance_private (self);
|
|
|
|
|
|
|
|
priv->geometry_scale = 1;
|
2009-06-26 19:33:20 +00:00
|
|
|
}
|
|
|
|
|
2011-03-25 01:36:47 +00:00
|
|
|
static void
|
|
|
|
window_appears_focused_notify (MetaWindow *mw,
|
|
|
|
GParamSpec *arg1,
|
|
|
|
gpointer data)
|
|
|
|
{
|
|
|
|
clutter_actor_queue_redraw (CLUTTER_ACTOR (data));
|
|
|
|
}
|
|
|
|
|
2019-08-17 08:00:46 +00:00
|
|
|
gboolean
|
|
|
|
meta_window_actor_is_opaque (MetaWindowActor *self)
|
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-01 22:21:11 +00:00
|
|
|
{
|
2018-12-21 20:12:49 +00:00
|
|
|
MetaWindowActorPrivate *priv =
|
|
|
|
meta_window_actor_get_instance_private (self);
|
2019-08-17 08:00:46 +00:00
|
|
|
MetaWindow *window = priv->window;
|
2018-12-21 20:12:49 +00:00
|
|
|
|
2019-08-17 08:00:46 +00:00
|
|
|
if (window->opacity != 0xff)
|
|
|
|
return FALSE;
|
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-01 22:21:11 +00:00
|
|
|
|
2019-08-17 08:00:46 +00:00
|
|
|
if (!priv->surface)
|
|
|
|
return FALSE;
|
2013-12-06 18:44:31 +00:00
|
|
|
|
2019-08-17 08:00:46 +00:00
|
|
|
return meta_surface_actor_is_opaque (priv->surface);
|
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-01 22:21:11 +00:00
|
|
|
}
|
|
|
|
|
2019-08-17 08:00:46 +00:00
|
|
|
gboolean
|
|
|
|
meta_window_actor_is_frozen (MetaWindowActor *self)
|
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-01 22:21:11 +00:00
|
|
|
{
|
2018-12-21 20:12:49 +00:00
|
|
|
MetaWindowActorPrivate *priv =
|
|
|
|
meta_window_actor_get_instance_private (self);
|
|
|
|
|
|
|
|
return priv->surface == NULL || priv->freeze_count > 0;
|
2013-12-06 18:44:31 +00:00
|
|
|
}
|
|
|
|
|
2020-03-03 09:26:54 +00:00
|
|
|
void
|
|
|
|
meta_window_actor_update_regions (MetaWindowActor *self)
|
|
|
|
{
|
|
|
|
META_WINDOW_ACTOR_GET_CLASS (self)->update_regions (self);
|
|
|
|
}
|
|
|
|
|
2021-01-22 15:26:17 +00:00
|
|
|
gboolean
|
|
|
|
meta_window_actor_can_freeze_commits (MetaWindowActor *self)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (META_IS_WINDOW_ACTOR (self), FALSE);
|
|
|
|
|
|
|
|
return META_WINDOW_ACTOR_GET_CLASS (self)->can_freeze_commits (self);
|
|
|
|
}
|
|
|
|
|
2019-12-09 14:06:58 +00:00
|
|
|
static void
|
|
|
|
meta_window_actor_set_frozen (MetaWindowActor *self,
|
|
|
|
gboolean frozen)
|
|
|
|
{
|
|
|
|
META_WINDOW_ACTOR_GET_CLASS (self)->set_frozen (self, frozen);
|
|
|
|
}
|
|
|
|
|
2020-05-12 10:04:28 +00:00
|
|
|
/**
|
|
|
|
* meta_window_actor_freeze:
|
|
|
|
* @self: The #MetaWindowActor
|
|
|
|
*
|
|
|
|
* Freezes the #MetaWindowActor, which inhibits updates and geometry
|
|
|
|
* changes of the window. This property is refcounted, so make sure
|
|
|
|
* to call meta_window_actor_thaw() the exact same amount of times
|
|
|
|
* as this function to allow updates again.
|
|
|
|
*/
|
|
|
|
void
|
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-01 22:21:11 +00:00
|
|
|
meta_window_actor_freeze (MetaWindowActor *self)
|
2013-12-09 21:01:07 +00:00
|
|
|
{
|
2020-05-12 10:04:28 +00:00
|
|
|
MetaWindowActorPrivate *priv;
|
|
|
|
|
|
|
|
g_return_if_fail (META_IS_WINDOW_ACTOR (self));
|
|
|
|
|
|
|
|
priv = meta_window_actor_get_instance_private (self);
|
2018-12-21 20:12:49 +00:00
|
|
|
|
|
|
|
if (priv->freeze_count == 0 && priv->surface)
|
2019-12-09 14:06:58 +00:00
|
|
|
meta_window_actor_set_frozen (self, TRUE);
|
2014-02-24 21:00:12 +00:00
|
|
|
|
2018-12-21 20:12:49 +00:00
|
|
|
priv->freeze_count ++;
|
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-01 22:21:11 +00:00
|
|
|
}
|
2009-06-26 19:33:20 +00:00
|
|
|
|
2016-09-07 08:20:15 +00:00
|
|
|
static void
|
|
|
|
meta_window_actor_sync_thawed_state (MetaWindowActor *self)
|
|
|
|
{
|
2018-12-21 20:12:49 +00:00
|
|
|
MetaWindowActorPrivate *priv =
|
|
|
|
meta_window_actor_get_instance_private (self);
|
2016-09-07 08:20:15 +00:00
|
|
|
|
2018-12-21 20:12:49 +00:00
|
|
|
if (priv->first_frame_state == INITIALLY_FROZEN)
|
|
|
|
priv->first_frame_state = DRAWING_FIRST_FRAME;
|
|
|
|
|
|
|
|
if (priv->surface)
|
2019-12-09 14:06:58 +00:00
|
|
|
meta_window_actor_set_frozen (self, FALSE);
|
2016-09-07 08:20:15 +00:00
|
|
|
|
|
|
|
/* We sometimes ignore moves and resizes on frozen windows */
|
|
|
|
meta_window_actor_sync_actor_geometry (self, FALSE);
|
|
|
|
}
|
|
|
|
|
2020-05-12 10:04:28 +00:00
|
|
|
/**
|
|
|
|
* meta_window_actor_thaw:
|
|
|
|
* @self: The #MetaWindowActor
|
|
|
|
*
|
|
|
|
* Thaws/unfreezes the #MetaWindowActor to allow updates and geometry
|
|
|
|
* changes after a window was frozen using meta_window_actor_freeze().
|
|
|
|
*/
|
|
|
|
void
|
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-01 22:21:11 +00:00
|
|
|
meta_window_actor_thaw (MetaWindowActor *self)
|
|
|
|
{
|
2020-05-12 10:04:28 +00:00
|
|
|
MetaWindowActorPrivate *priv;
|
|
|
|
|
|
|
|
g_return_if_fail (META_IS_WINDOW_ACTOR (self));
|
|
|
|
|
|
|
|
priv = meta_window_actor_get_instance_private (self);
|
2018-12-21 20:12:49 +00:00
|
|
|
|
|
|
|
if (priv->freeze_count <= 0)
|
2014-02-24 21:00:12 +00:00
|
|
|
g_error ("Error in freeze/thaw accounting");
|
2009-06-26 19:33:20 +00:00
|
|
|
|
2018-12-21 20:12:49 +00:00
|
|
|
priv->freeze_count--;
|
|
|
|
if (priv->freeze_count > 0)
|
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-01 22:21:11 +00:00
|
|
|
return;
|
2013-12-09 21:01:07 +00:00
|
|
|
|
2016-09-07 08:20:15 +00:00
|
|
|
/* We still might be frozen due to lack of a MetaSurfaceActor */
|
2019-08-17 08:00:46 +00:00
|
|
|
if (meta_window_actor_is_frozen (self))
|
2016-09-07 08:20:15 +00:00
|
|
|
return;
|
2014-02-24 21:00:12 +00:00
|
|
|
|
2016-09-07 08:20:15 +00:00
|
|
|
meta_window_actor_sync_thawed_state (self);
|
2013-12-09 21:01:07 +00:00
|
|
|
|
2019-08-17 08:00:46 +00:00
|
|
|
g_signal_emit (self, signals[THAWED], 0);
|
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-01 22:21:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2019-06-27 17:33:24 +00:00
|
|
|
meta_window_actor_real_assign_surface_actor (MetaWindowActor *self,
|
|
|
|
MetaSurfaceActor *surface_actor)
|
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-01 22:21:11 +00:00
|
|
|
{
|
2018-12-21 20:12:49 +00:00
|
|
|
MetaWindowActorPrivate *priv =
|
|
|
|
meta_window_actor_get_instance_private (self);
|
|
|
|
|
2019-08-17 08:00:46 +00:00
|
|
|
g_clear_object (&priv->surface);
|
2019-06-27 17:33:24 +00:00
|
|
|
priv->surface = g_object_ref_sink (surface_actor);
|
2016-09-07 08:20:15 +00:00
|
|
|
|
2019-08-17 08:00:46 +00:00
|
|
|
if (meta_window_actor_is_frozen (self))
|
2019-12-09 14:06:58 +00:00
|
|
|
meta_window_actor_set_frozen (self, TRUE);
|
2019-06-27 17:33:24 +00:00
|
|
|
else
|
|
|
|
meta_window_actor_sync_thawed_state (self);
|
2014-02-24 18:32:17 +00:00
|
|
|
}
|
|
|
|
|
2014-02-25 00:22:56 +00:00
|
|
|
void
|
2019-06-27 17:33:24 +00:00
|
|
|
meta_window_actor_assign_surface_actor (MetaWindowActor *self,
|
|
|
|
MetaSurfaceActor *surface_actor)
|
|
|
|
{
|
|
|
|
META_WINDOW_ACTOR_GET_CLASS (self)->assign_surface_actor (self,
|
|
|
|
surface_actor);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
init_surface_actor (MetaWindowActor *self)
|
2014-02-24 18:32:17 +00:00
|
|
|
{
|
2018-12-21 20:12:49 +00:00
|
|
|
MetaWindowActorPrivate *priv =
|
|
|
|
meta_window_actor_get_instance_private (self);
|
|
|
|
MetaWindow *window = priv->window;
|
2022-05-18 11:51:44 +00:00
|
|
|
MetaSurfaceActor *surface_actor = NULL;
|
2014-02-24 18:32:17 +00:00
|
|
|
|
2019-06-27 17:33:24 +00:00
|
|
|
if (!meta_is_wayland_compositor ())
|
2022-05-18 11:51:44 +00:00
|
|
|
{
|
|
|
|
surface_actor = meta_surface_actor_x11_new (window);
|
|
|
|
}
|
2014-08-27 16:56:05 +00:00
|
|
|
#ifdef HAVE_WAYLAND
|
2014-02-25 00:22:56 +00:00
|
|
|
else
|
2022-05-18 11:51:44 +00:00
|
|
|
{
|
|
|
|
MetaWaylandSurface *surface = meta_window_get_wayland_surface (window);
|
|
|
|
surface_actor = surface ? meta_wayland_surface_get_actor (surface) : NULL;
|
|
|
|
}
|
|
|
|
#endif
|
2014-02-24 18:32:17 +00:00
|
|
|
|
2019-06-27 17:33:24 +00:00
|
|
|
if (surface_actor)
|
|
|
|
meta_window_actor_assign_surface_actor (self, surface_actor);
|
2014-02-24 18:32:17 +00:00
|
|
|
}
|
|
|
|
|
2022-07-02 19:51:13 +00:00
|
|
|
static void
|
|
|
|
on_stage_views_changed (MetaWindowActor *self)
|
|
|
|
{
|
|
|
|
MetaWindowActorPrivate *priv =
|
|
|
|
meta_window_actor_get_instance_private (self);
|
|
|
|
|
|
|
|
meta_compositor_window_actor_stage_views_changed (priv->compositor);
|
|
|
|
}
|
|
|
|
|
2014-02-24 18:32:17 +00:00
|
|
|
static void
|
|
|
|
meta_window_actor_constructed (GObject *object)
|
|
|
|
{
|
2014-03-18 21:31:22 +00:00
|
|
|
MetaWindowActor *self = META_WINDOW_ACTOR (object);
|
2018-12-21 20:12:49 +00:00
|
|
|
MetaWindowActorPrivate *priv =
|
|
|
|
meta_window_actor_get_instance_private (self);
|
|
|
|
MetaWindow *window = priv->window;
|
2014-02-24 18:32:17 +00:00
|
|
|
|
2018-12-21 20:12:49 +00:00
|
|
|
priv->compositor = window->display->compositor;
|
2014-02-24 18:32:17 +00:00
|
|
|
|
2022-07-02 19:51:13 +00:00
|
|
|
priv->stage_views_changed_id =
|
|
|
|
g_signal_connect (self,
|
|
|
|
"stage-views-changed",
|
|
|
|
G_CALLBACK (on_stage_views_changed),
|
|
|
|
NULL);
|
|
|
|
|
2019-06-28 09:18:22 +00:00
|
|
|
/* Hang our compositor window state off the MetaWindow for fast retrieval */
|
|
|
|
meta_window_set_compositor_private (window, object);
|
|
|
|
|
2019-06-27 17:33:24 +00:00
|
|
|
init_surface_actor (self);
|
2009-06-26 19:33:20 +00:00
|
|
|
|
2011-04-26 16:08:15 +00:00
|
|
|
meta_window_actor_update_opacity (self);
|
2013-01-15 02:47:46 +00:00
|
|
|
|
2018-12-22 14:21:34 +00:00
|
|
|
meta_window_actor_sync_updates_frozen (self);
|
|
|
|
|
2019-08-17 08:00:46 +00:00
|
|
|
if (meta_window_actor_is_frozen (self))
|
2018-12-22 14:21:34 +00:00
|
|
|
priv->first_frame_state = INITIALLY_FROZEN;
|
|
|
|
else
|
|
|
|
priv->first_frame_state = DRAWING_FIRST_FRAME;
|
|
|
|
|
|
|
|
meta_window_actor_sync_actor_geometry (self, priv->window->placed);
|
2009-06-26 19:33:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2010-10-18 17:27:14 +00:00
|
|
|
meta_window_actor_dispose (GObject *object)
|
2009-06-26 19:33:20 +00:00
|
|
|
{
|
2014-03-18 21:31:22 +00:00
|
|
|
MetaWindowActor *self = META_WINDOW_ACTOR (object);
|
2018-12-21 20:12:49 +00:00
|
|
|
MetaWindowActorPrivate *priv =
|
|
|
|
meta_window_actor_get_instance_private (self);
|
|
|
|
MetaCompositor *compositor = priv->compositor;
|
2009-06-26 19:33:20 +00:00
|
|
|
|
2018-12-21 20:12:49 +00:00
|
|
|
if (priv->disposed)
|
2019-06-27 17:31:19 +00:00
|
|
|
{
|
|
|
|
G_OBJECT_CLASS (meta_window_actor_parent_class)->dispose (object);
|
|
|
|
return;
|
|
|
|
}
|
2009-06-26 19:33:20 +00:00
|
|
|
|
2018-12-21 20:12:49 +00:00
|
|
|
priv->disposed = TRUE;
|
2009-06-26 19:33:20 +00:00
|
|
|
|
2022-07-02 19:51:13 +00:00
|
|
|
g_clear_signal_handler (&priv->stage_views_changed_id, self);
|
|
|
|
|
2019-08-14 17:04:41 +00:00
|
|
|
meta_compositor_remove_window_actor (compositor, self);
|
2009-06-26 19:33:20 +00:00
|
|
|
|
2018-12-21 20:12:49 +00:00
|
|
|
g_clear_object (&priv->window);
|
2011-03-08 03:22:19 +00:00
|
|
|
|
2022-05-03 16:47:57 +00:00
|
|
|
g_clear_object (&priv->surface);
|
2009-08-07 16:14:48 +00:00
|
|
|
|
2010-10-18 17:27:14 +00:00
|
|
|
G_OBJECT_CLASS (meta_window_actor_parent_class)->dispose (object);
|
2009-06-26 19:33:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2010-10-18 17:27:14 +00:00
|
|
|
meta_window_actor_set_property (GObject *object,
|
|
|
|
guint prop_id,
|
|
|
|
const GValue *value,
|
|
|
|
GParamSpec *pspec)
|
2009-06-26 19:33:20 +00:00
|
|
|
{
|
2018-10-31 10:47:17 +00:00
|
|
|
MetaWindowActor *self = META_WINDOW_ACTOR (object);
|
2018-12-21 20:12:49 +00:00
|
|
|
MetaWindowActorPrivate *priv =
|
|
|
|
meta_window_actor_get_instance_private (self);
|
2009-06-26 19:33:20 +00:00
|
|
|
|
|
|
|
switch (prop_id)
|
|
|
|
{
|
2010-10-18 17:27:14 +00:00
|
|
|
case PROP_META_WINDOW:
|
2018-12-21 20:12:49 +00:00
|
|
|
priv->window = g_value_dup_object (value);
|
|
|
|
g_signal_connect_object (priv->window, "notify::appears-focused",
|
2013-12-09 18:45:12 +00:00
|
|
|
G_CALLBACK (window_appears_focused_notify), self, 0);
|
2009-06-26 19:33:20 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2010-10-18 17:27:14 +00:00
|
|
|
meta_window_actor_get_property (GObject *object,
|
|
|
|
guint prop_id,
|
|
|
|
GValue *value,
|
|
|
|
GParamSpec *pspec)
|
2009-06-26 19:33:20 +00:00
|
|
|
{
|
2018-10-31 10:47:17 +00:00
|
|
|
MetaWindowActor *self = META_WINDOW_ACTOR (object);
|
2018-12-21 20:12:49 +00:00
|
|
|
MetaWindowActorPrivate *priv =
|
|
|
|
meta_window_actor_get_instance_private (self);
|
2009-06-26 19:33:20 +00:00
|
|
|
|
|
|
|
switch (prop_id)
|
|
|
|
{
|
2010-10-18 17:27:14 +00:00
|
|
|
case PROP_META_WINDOW:
|
2018-12-21 20:12:49 +00:00
|
|
|
g_value_set_object (value, priv->window);
|
2009-06-26 19:33:20 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2010-10-18 17:27:14 +00:00
|
|
|
* meta_window_actor_get_meta_window:
|
2013-02-15 18:42:08 +00:00
|
|
|
* @self: a #MetaWindowActor
|
2009-06-26 19:33:20 +00:00
|
|
|
*
|
2011-10-18 02:10:00 +00:00
|
|
|
* Gets the #MetaWindow object that the the #MetaWindowActor is displaying
|
2009-06-26 19:33:20 +00:00
|
|
|
*
|
2022-11-24 14:16:13 +00:00
|
|
|
* Return value: (transfer none) (nullable): the displayed #MetaWindow
|
2009-06-26 19:33:20 +00:00
|
|
|
*/
|
|
|
|
MetaWindow *
|
2010-10-18 17:27:14 +00:00
|
|
|
meta_window_actor_get_meta_window (MetaWindowActor *self)
|
2009-06-26 19:33:20 +00:00
|
|
|
{
|
2018-12-21 20:12:49 +00:00
|
|
|
MetaWindowActorPrivate *priv =
|
|
|
|
meta_window_actor_get_instance_private (self);
|
|
|
|
|
|
|
|
return priv->window;
|
2009-06-26 19:33:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2010-10-18 17:27:14 +00:00
|
|
|
* meta_window_actor_get_texture:
|
2013-02-15 18:42:08 +00:00
|
|
|
* @self: a #MetaWindowActor
|
2009-06-26 19:33:20 +00:00
|
|
|
*
|
2014-02-25 00:22:56 +00:00
|
|
|
* 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.
|
2009-06-26 19:33:20 +00:00
|
|
|
*
|
2022-11-24 14:16:13 +00:00
|
|
|
* Return value: (transfer none) (nullable): the #ClutterActor for the contents
|
2009-06-26 19:33:20 +00:00
|
|
|
*/
|
2018-12-26 15:41:26 +00:00
|
|
|
MetaShapedTexture *
|
2010-10-18 17:27:14 +00:00
|
|
|
meta_window_actor_get_texture (MetaWindowActor *self)
|
2009-06-26 19:33:20 +00:00
|
|
|
{
|
2018-12-21 20:12:49 +00:00
|
|
|
MetaWindowActorPrivate *priv =
|
|
|
|
meta_window_actor_get_instance_private (self);
|
|
|
|
|
|
|
|
if (priv->surface)
|
2018-12-26 15:41:26 +00:00
|
|
|
return meta_surface_actor_get_texture (priv->surface);
|
2014-02-25 00:22:56 +00:00
|
|
|
else
|
|
|
|
return NULL;
|
2013-10-13 11:47:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* meta_window_actor_get_surface:
|
|
|
|
* @self: a #MetaWindowActor
|
|
|
|
*
|
2014-02-25 00:22:56 +00:00
|
|
|
* Gets the MetaSurfaceActor that draws the content of this window,
|
|
|
|
* or NULL if there is no surface yet associated with this window.
|
2013-10-13 11:47:53 +00:00
|
|
|
*
|
2022-11-24 14:16:13 +00:00
|
|
|
* Return value: (transfer none) (nullable): the #MetaSurfaceActor for the
|
|
|
|
* contents
|
2013-10-13 11:47:53 +00:00
|
|
|
*/
|
|
|
|
MetaSurfaceActor *
|
|
|
|
meta_window_actor_get_surface (MetaWindowActor *self)
|
|
|
|
{
|
2018-12-21 20:12:49 +00:00
|
|
|
MetaWindowActorPrivate *priv =
|
|
|
|
meta_window_actor_get_instance_private (self);
|
|
|
|
|
|
|
|
return priv->surface;
|
2009-06-26 19:33:20 +00:00
|
|
|
}
|
|
|
|
|
2022-01-05 21:05:50 +00:00
|
|
|
static MetaSurfaceActor *
|
2022-05-11 20:32:33 +00:00
|
|
|
meta_window_actor_real_get_scanout_candidate (MetaWindowActor *self)
|
2022-01-05 21:05:50 +00:00
|
|
|
{
|
2022-05-11 20:32:33 +00:00
|
|
|
return NULL;
|
2022-01-05 21:05:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
MetaSurfaceActor *
|
2022-05-11 20:32:33 +00:00
|
|
|
meta_window_actor_get_scanout_candidate (MetaWindowActor *self)
|
2022-01-05 21:05:50 +00:00
|
|
|
{
|
2022-05-11 20:32:33 +00:00
|
|
|
return META_WINDOW_ACTOR_GET_CLASS (self)->get_scanout_candidate (self);
|
2022-01-05 21:05:50 +00:00
|
|
|
}
|
|
|
|
|
2011-01-18 18:34:15 +00:00
|
|
|
/**
|
|
|
|
* meta_window_actor_is_destroyed:
|
2013-02-15 18:42:08 +00:00
|
|
|
* @self: a #MetaWindowActor
|
2011-01-18 18:34:15 +00:00
|
|
|
*
|
|
|
|
* Gets whether the X window that the actor was displaying has been destroyed
|
|
|
|
*
|
|
|
|
* Return value: %TRUE when the window is destroyed, otherwise %FALSE
|
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
meta_window_actor_is_destroyed (MetaWindowActor *self)
|
|
|
|
{
|
2018-12-21 20:12:49 +00:00
|
|
|
MetaWindowActorPrivate *priv =
|
|
|
|
meta_window_actor_get_instance_private (self);
|
|
|
|
|
|
|
|
return priv->disposed || priv->needs_destroy;
|
2011-01-18 18:34:15 +00:00
|
|
|
}
|
|
|
|
|
2013-02-14 18:40:55 +00:00
|
|
|
void
|
|
|
|
meta_window_actor_queue_frame_drawn (MetaWindowActor *self,
|
|
|
|
gboolean no_delay_frame)
|
|
|
|
{
|
2018-12-21 20:51:02 +00:00
|
|
|
META_WINDOW_ACTOR_GET_CLASS (self)->queue_frame_drawn (self,
|
|
|
|
no_delay_frame);
|
2010-03-02 18:02:28 +00:00
|
|
|
}
|
|
|
|
|
2009-06-26 19:33:20 +00:00
|
|
|
gboolean
|
2010-10-18 17:27:14 +00:00
|
|
|
meta_window_actor_effect_in_progress (MetaWindowActor *self)
|
2009-06-26 19:33:20 +00:00
|
|
|
{
|
2018-12-21 20:12:49 +00:00
|
|
|
MetaWindowActorPrivate *priv =
|
|
|
|
meta_window_actor_get_instance_private (self);
|
|
|
|
|
|
|
|
return (priv->minimize_in_progress ||
|
|
|
|
priv->size_change_in_progress ||
|
|
|
|
priv->map_in_progress ||
|
|
|
|
priv->destroy_in_progress);
|
2009-06-26 19:33:20 +00:00
|
|
|
}
|
|
|
|
|
2010-03-02 18:02:28 +00:00
|
|
|
static gboolean
|
2015-07-06 03:58:40 +00:00
|
|
|
is_freeze_thaw_effect (MetaPluginEffect event)
|
2010-03-02 18:02:28 +00:00
|
|
|
{
|
|
|
|
switch (event)
|
|
|
|
{
|
2010-10-18 17:27:14 +00:00
|
|
|
case META_PLUGIN_DESTROY:
|
2010-03-02 18:02:28 +00:00
|
|
|
return TRUE;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Simplify relationship between mapping and visibility
Previously, changes to the visibility of a window could be indicated
by meta_compositor_map_window(), meta_compositor_unminimize_window(),
meta_compositor_set_window_hidden(), etc, with the exact behavior
depending on the 'live_hidden_windows' preference.
Simplify this so that visibility is controlled by:
meta_compositor_show_window()
meta_compositor_hide_window()
With an 'effect' parameter provided to indicate the appropriate
effect (CREATE/UNMINIMIZE/MINIMIZE/DESTROY/NONE.)
The map state of the window is signalled separately by:
meta_compositor_map_window()
meta_compositor_unmap_window()
And is used only to control resource handling.
Other changes:
* The desired effect on show/hide is explicitly stored in
MetaWindow, avoiding the need for the was_minimized flag.
At idle, once we calculate the window state, we pass the
effect to the compositor if it matches the new window
state, and then clear the effect to start over for future
map state changes.
* meta_compositor_switch_workspace() is called before any windows
are hidden or shown, allowing the compositor to avoid hiding
or showing an effect for windows involved in the switch.
http://bugzilla.gnome.org/show_bug.cgi?id=582341
* Handling of post-effect cleanups for MutterWindow are
simplified - instead of trying to do different things based
on the individual needs of different effects, we just wait until
all effects complete and sync the window state to what it
should be.
* On unmap, once we destroy the pixmap, we tell ClutterX11Pixmap
that we've done so, so it can clean up and unbind. (The
unbinding doesn't seem to be working properly because of
ClutterGLXPixmap or video driver issues.)
http://bugzilla.gnome.org/show_bug.cgi?id=587251
2009-06-28 21:10:40 +00:00
|
|
|
static gboolean
|
2015-07-06 03:58:40 +00:00
|
|
|
start_simple_effect (MetaWindowActor *self,
|
|
|
|
MetaPluginEffect event)
|
Simplify relationship between mapping and visibility
Previously, changes to the visibility of a window could be indicated
by meta_compositor_map_window(), meta_compositor_unminimize_window(),
meta_compositor_set_window_hidden(), etc, with the exact behavior
depending on the 'live_hidden_windows' preference.
Simplify this so that visibility is controlled by:
meta_compositor_show_window()
meta_compositor_hide_window()
With an 'effect' parameter provided to indicate the appropriate
effect (CREATE/UNMINIMIZE/MINIMIZE/DESTROY/NONE.)
The map state of the window is signalled separately by:
meta_compositor_map_window()
meta_compositor_unmap_window()
And is used only to control resource handling.
Other changes:
* The desired effect on show/hide is explicitly stored in
MetaWindow, avoiding the need for the was_minimized flag.
At idle, once we calculate the window state, we pass the
effect to the compositor if it matches the new window
state, and then clear the effect to start over for future
map state changes.
* meta_compositor_switch_workspace() is called before any windows
are hidden or shown, allowing the compositor to avoid hiding
or showing an effect for windows involved in the switch.
http://bugzilla.gnome.org/show_bug.cgi?id=582341
* Handling of post-effect cleanups for MutterWindow are
simplified - instead of trying to do different things based
on the individual needs of different effects, we just wait until
all effects complete and sync the window state to what it
should be.
* On unmap, once we destroy the pixmap, we tell ClutterX11Pixmap
that we've done so, so it can clean up and unbind. (The
unbinding doesn't seem to be working properly because of
ClutterGLXPixmap or video driver issues.)
http://bugzilla.gnome.org/show_bug.cgi?id=587251
2009-06-28 21:10:40 +00:00
|
|
|
{
|
2018-12-21 20:12:49 +00:00
|
|
|
MetaWindowActorPrivate *priv =
|
|
|
|
meta_window_actor_get_instance_private (self);
|
|
|
|
MetaCompositor *compositor = priv->compositor;
|
2019-08-14 17:04:41 +00:00
|
|
|
MetaPluginManager *plugin_mgr =
|
|
|
|
meta_compositor_get_plugin_manager (compositor);
|
Simplify relationship between mapping and visibility
Previously, changes to the visibility of a window could be indicated
by meta_compositor_map_window(), meta_compositor_unminimize_window(),
meta_compositor_set_window_hidden(), etc, with the exact behavior
depending on the 'live_hidden_windows' preference.
Simplify this so that visibility is controlled by:
meta_compositor_show_window()
meta_compositor_hide_window()
With an 'effect' parameter provided to indicate the appropriate
effect (CREATE/UNMINIMIZE/MINIMIZE/DESTROY/NONE.)
The map state of the window is signalled separately by:
meta_compositor_map_window()
meta_compositor_unmap_window()
And is used only to control resource handling.
Other changes:
* The desired effect on show/hide is explicitly stored in
MetaWindow, avoiding the need for the was_minimized flag.
At idle, once we calculate the window state, we pass the
effect to the compositor if it matches the new window
state, and then clear the effect to start over for future
map state changes.
* meta_compositor_switch_workspace() is called before any windows
are hidden or shown, allowing the compositor to avoid hiding
or showing an effect for windows involved in the switch.
http://bugzilla.gnome.org/show_bug.cgi?id=582341
* Handling of post-effect cleanups for MutterWindow are
simplified - instead of trying to do different things based
on the individual needs of different effects, we just wait until
all effects complete and sync the window state to what it
should be.
* On unmap, once we destroy the pixmap, we tell ClutterX11Pixmap
that we've done so, so it can clean up and unbind. (The
unbinding doesn't seem to be working properly because of
ClutterGLXPixmap or video driver issues.)
http://bugzilla.gnome.org/show_bug.cgi?id=587251
2009-06-28 21:10:40 +00:00
|
|
|
gint *counter = NULL;
|
2010-03-02 18:02:28 +00:00
|
|
|
gboolean use_freeze_thaw = FALSE;
|
Simplify relationship between mapping and visibility
Previously, changes to the visibility of a window could be indicated
by meta_compositor_map_window(), meta_compositor_unminimize_window(),
meta_compositor_set_window_hidden(), etc, with the exact behavior
depending on the 'live_hidden_windows' preference.
Simplify this so that visibility is controlled by:
meta_compositor_show_window()
meta_compositor_hide_window()
With an 'effect' parameter provided to indicate the appropriate
effect (CREATE/UNMINIMIZE/MINIMIZE/DESTROY/NONE.)
The map state of the window is signalled separately by:
meta_compositor_map_window()
meta_compositor_unmap_window()
And is used only to control resource handling.
Other changes:
* The desired effect on show/hide is explicitly stored in
MetaWindow, avoiding the need for the was_minimized flag.
At idle, once we calculate the window state, we pass the
effect to the compositor if it matches the new window
state, and then clear the effect to start over for future
map state changes.
* meta_compositor_switch_workspace() is called before any windows
are hidden or shown, allowing the compositor to avoid hiding
or showing an effect for windows involved in the switch.
http://bugzilla.gnome.org/show_bug.cgi?id=582341
* Handling of post-effect cleanups for MutterWindow are
simplified - instead of trying to do different things based
on the individual needs of different effects, we just wait until
all effects complete and sync the window state to what it
should be.
* On unmap, once we destroy the pixmap, we tell ClutterX11Pixmap
that we've done so, so it can clean up and unbind. (The
unbinding doesn't seem to be working properly because of
ClutterGLXPixmap or video driver issues.)
http://bugzilla.gnome.org/show_bug.cgi?id=587251
2009-06-28 21:10:40 +00:00
|
|
|
|
2019-08-14 17:04:41 +00:00
|
|
|
g_assert (plugin_mgr != NULL);
|
2017-10-20 07:52:04 +00:00
|
|
|
|
Simplify relationship between mapping and visibility
Previously, changes to the visibility of a window could be indicated
by meta_compositor_map_window(), meta_compositor_unminimize_window(),
meta_compositor_set_window_hidden(), etc, with the exact behavior
depending on the 'live_hidden_windows' preference.
Simplify this so that visibility is controlled by:
meta_compositor_show_window()
meta_compositor_hide_window()
With an 'effect' parameter provided to indicate the appropriate
effect (CREATE/UNMINIMIZE/MINIMIZE/DESTROY/NONE.)
The map state of the window is signalled separately by:
meta_compositor_map_window()
meta_compositor_unmap_window()
And is used only to control resource handling.
Other changes:
* The desired effect on show/hide is explicitly stored in
MetaWindow, avoiding the need for the was_minimized flag.
At idle, once we calculate the window state, we pass the
effect to the compositor if it matches the new window
state, and then clear the effect to start over for future
map state changes.
* meta_compositor_switch_workspace() is called before any windows
are hidden or shown, allowing the compositor to avoid hiding
or showing an effect for windows involved in the switch.
http://bugzilla.gnome.org/show_bug.cgi?id=582341
* Handling of post-effect cleanups for MutterWindow are
simplified - instead of trying to do different things based
on the individual needs of different effects, we just wait until
all effects complete and sync the window state to what it
should be.
* On unmap, once we destroy the pixmap, we tell ClutterX11Pixmap
that we've done so, so it can clean up and unbind. (The
unbinding doesn't seem to be working properly because of
ClutterGLXPixmap or video driver issues.)
http://bugzilla.gnome.org/show_bug.cgi?id=587251
2009-06-28 21:10:40 +00:00
|
|
|
switch (event)
|
|
|
|
{
|
2015-07-06 04:08:08 +00:00
|
|
|
case META_PLUGIN_NONE:
|
|
|
|
return FALSE;
|
2010-10-18 17:27:14 +00:00
|
|
|
case META_PLUGIN_MINIMIZE:
|
2018-12-21 20:12:49 +00:00
|
|
|
counter = &priv->minimize_in_progress;
|
Simplify relationship between mapping and visibility
Previously, changes to the visibility of a window could be indicated
by meta_compositor_map_window(), meta_compositor_unminimize_window(),
meta_compositor_set_window_hidden(), etc, with the exact behavior
depending on the 'live_hidden_windows' preference.
Simplify this so that visibility is controlled by:
meta_compositor_show_window()
meta_compositor_hide_window()
With an 'effect' parameter provided to indicate the appropriate
effect (CREATE/UNMINIMIZE/MINIMIZE/DESTROY/NONE.)
The map state of the window is signalled separately by:
meta_compositor_map_window()
meta_compositor_unmap_window()
And is used only to control resource handling.
Other changes:
* The desired effect on show/hide is explicitly stored in
MetaWindow, avoiding the need for the was_minimized flag.
At idle, once we calculate the window state, we pass the
effect to the compositor if it matches the new window
state, and then clear the effect to start over for future
map state changes.
* meta_compositor_switch_workspace() is called before any windows
are hidden or shown, allowing the compositor to avoid hiding
or showing an effect for windows involved in the switch.
http://bugzilla.gnome.org/show_bug.cgi?id=582341
* Handling of post-effect cleanups for MutterWindow are
simplified - instead of trying to do different things based
on the individual needs of different effects, we just wait until
all effects complete and sync the window state to what it
should be.
* On unmap, once we destroy the pixmap, we tell ClutterX11Pixmap
that we've done so, so it can clean up and unbind. (The
unbinding doesn't seem to be working properly because of
ClutterGLXPixmap or video driver issues.)
http://bugzilla.gnome.org/show_bug.cgi?id=587251
2009-06-28 21:10:40 +00:00
|
|
|
break;
|
2013-06-14 01:01:17 +00:00
|
|
|
case META_PLUGIN_UNMINIMIZE:
|
2018-12-21 20:12:49 +00:00
|
|
|
counter = &priv->unminimize_in_progress;
|
2013-06-14 01:01:17 +00:00
|
|
|
break;
|
2010-10-18 17:27:14 +00:00
|
|
|
case META_PLUGIN_MAP:
|
2018-12-21 20:12:49 +00:00
|
|
|
counter = &priv->map_in_progress;
|
Simplify relationship between mapping and visibility
Previously, changes to the visibility of a window could be indicated
by meta_compositor_map_window(), meta_compositor_unminimize_window(),
meta_compositor_set_window_hidden(), etc, with the exact behavior
depending on the 'live_hidden_windows' preference.
Simplify this so that visibility is controlled by:
meta_compositor_show_window()
meta_compositor_hide_window()
With an 'effect' parameter provided to indicate the appropriate
effect (CREATE/UNMINIMIZE/MINIMIZE/DESTROY/NONE.)
The map state of the window is signalled separately by:
meta_compositor_map_window()
meta_compositor_unmap_window()
And is used only to control resource handling.
Other changes:
* The desired effect on show/hide is explicitly stored in
MetaWindow, avoiding the need for the was_minimized flag.
At idle, once we calculate the window state, we pass the
effect to the compositor if it matches the new window
state, and then clear the effect to start over for future
map state changes.
* meta_compositor_switch_workspace() is called before any windows
are hidden or shown, allowing the compositor to avoid hiding
or showing an effect for windows involved in the switch.
http://bugzilla.gnome.org/show_bug.cgi?id=582341
* Handling of post-effect cleanups for MutterWindow are
simplified - instead of trying to do different things based
on the individual needs of different effects, we just wait until
all effects complete and sync the window state to what it
should be.
* On unmap, once we destroy the pixmap, we tell ClutterX11Pixmap
that we've done so, so it can clean up and unbind. (The
unbinding doesn't seem to be working properly because of
ClutterGLXPixmap or video driver issues.)
http://bugzilla.gnome.org/show_bug.cgi?id=587251
2009-06-28 21:10:40 +00:00
|
|
|
break;
|
2010-10-18 17:27:14 +00:00
|
|
|
case META_PLUGIN_DESTROY:
|
2018-12-21 20:12:49 +00:00
|
|
|
counter = &priv->destroy_in_progress;
|
Simplify relationship between mapping and visibility
Previously, changes to the visibility of a window could be indicated
by meta_compositor_map_window(), meta_compositor_unminimize_window(),
meta_compositor_set_window_hidden(), etc, with the exact behavior
depending on the 'live_hidden_windows' preference.
Simplify this so that visibility is controlled by:
meta_compositor_show_window()
meta_compositor_hide_window()
With an 'effect' parameter provided to indicate the appropriate
effect (CREATE/UNMINIMIZE/MINIMIZE/DESTROY/NONE.)
The map state of the window is signalled separately by:
meta_compositor_map_window()
meta_compositor_unmap_window()
And is used only to control resource handling.
Other changes:
* The desired effect on show/hide is explicitly stored in
MetaWindow, avoiding the need for the was_minimized flag.
At idle, once we calculate the window state, we pass the
effect to the compositor if it matches the new window
state, and then clear the effect to start over for future
map state changes.
* meta_compositor_switch_workspace() is called before any windows
are hidden or shown, allowing the compositor to avoid hiding
or showing an effect for windows involved in the switch.
http://bugzilla.gnome.org/show_bug.cgi?id=582341
* Handling of post-effect cleanups for MutterWindow are
simplified - instead of trying to do different things based
on the individual needs of different effects, we just wait until
all effects complete and sync the window state to what it
should be.
* On unmap, once we destroy the pixmap, we tell ClutterX11Pixmap
that we've done so, so it can clean up and unbind. (The
unbinding doesn't seem to be working properly because of
ClutterGLXPixmap or video driver issues.)
http://bugzilla.gnome.org/show_bug.cgi?id=587251
2009-06-28 21:10:40 +00:00
|
|
|
break;
|
2015-07-06 04:08:08 +00:00
|
|
|
case META_PLUGIN_SIZE_CHANGE:
|
2010-10-18 17:27:14 +00:00
|
|
|
case META_PLUGIN_SWITCH_WORKSPACE:
|
Simplify relationship between mapping and visibility
Previously, changes to the visibility of a window could be indicated
by meta_compositor_map_window(), meta_compositor_unminimize_window(),
meta_compositor_set_window_hidden(), etc, with the exact behavior
depending on the 'live_hidden_windows' preference.
Simplify this so that visibility is controlled by:
meta_compositor_show_window()
meta_compositor_hide_window()
With an 'effect' parameter provided to indicate the appropriate
effect (CREATE/UNMINIMIZE/MINIMIZE/DESTROY/NONE.)
The map state of the window is signalled separately by:
meta_compositor_map_window()
meta_compositor_unmap_window()
And is used only to control resource handling.
Other changes:
* The desired effect on show/hide is explicitly stored in
MetaWindow, avoiding the need for the was_minimized flag.
At idle, once we calculate the window state, we pass the
effect to the compositor if it matches the new window
state, and then clear the effect to start over for future
map state changes.
* meta_compositor_switch_workspace() is called before any windows
are hidden or shown, allowing the compositor to avoid hiding
or showing an effect for windows involved in the switch.
http://bugzilla.gnome.org/show_bug.cgi?id=582341
* Handling of post-effect cleanups for MutterWindow are
simplified - instead of trying to do different things based
on the individual needs of different effects, we just wait until
all effects complete and sync the window state to what it
should be.
* On unmap, once we destroy the pixmap, we tell ClutterX11Pixmap
that we've done so, so it can clean up and unbind. (The
unbinding doesn't seem to be working properly because of
ClutterGLXPixmap or video driver issues.)
http://bugzilla.gnome.org/show_bug.cgi?id=587251
2009-06-28 21:10:40 +00:00
|
|
|
g_assert_not_reached ();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_assert (counter);
|
|
|
|
|
2010-03-02 18:02:28 +00:00
|
|
|
use_freeze_thaw = is_freeze_thaw_effect (event);
|
|
|
|
|
|
|
|
if (use_freeze_thaw)
|
2010-10-18 17:27:14 +00:00
|
|
|
meta_window_actor_freeze (self);
|
2010-03-02 18:02:28 +00:00
|
|
|
|
Simplify relationship between mapping and visibility
Previously, changes to the visibility of a window could be indicated
by meta_compositor_map_window(), meta_compositor_unminimize_window(),
meta_compositor_set_window_hidden(), etc, with the exact behavior
depending on the 'live_hidden_windows' preference.
Simplify this so that visibility is controlled by:
meta_compositor_show_window()
meta_compositor_hide_window()
With an 'effect' parameter provided to indicate the appropriate
effect (CREATE/UNMINIMIZE/MINIMIZE/DESTROY/NONE.)
The map state of the window is signalled separately by:
meta_compositor_map_window()
meta_compositor_unmap_window()
And is used only to control resource handling.
Other changes:
* The desired effect on show/hide is explicitly stored in
MetaWindow, avoiding the need for the was_minimized flag.
At idle, once we calculate the window state, we pass the
effect to the compositor if it matches the new window
state, and then clear the effect to start over for future
map state changes.
* meta_compositor_switch_workspace() is called before any windows
are hidden or shown, allowing the compositor to avoid hiding
or showing an effect for windows involved in the switch.
http://bugzilla.gnome.org/show_bug.cgi?id=582341
* Handling of post-effect cleanups for MutterWindow are
simplified - instead of trying to do different things based
on the individual needs of different effects, we just wait until
all effects complete and sync the window state to what it
should be.
* On unmap, once we destroy the pixmap, we tell ClutterX11Pixmap
that we've done so, so it can clean up and unbind. (The
unbinding doesn't seem to be working properly because of
ClutterGLXPixmap or video driver issues.)
http://bugzilla.gnome.org/show_bug.cgi?id=587251
2009-06-28 21:10:40 +00:00
|
|
|
(*counter)++;
|
|
|
|
|
2019-08-14 17:04:41 +00:00
|
|
|
if (!meta_plugin_manager_event_simple (plugin_mgr, self, event))
|
Simplify relationship between mapping and visibility
Previously, changes to the visibility of a window could be indicated
by meta_compositor_map_window(), meta_compositor_unminimize_window(),
meta_compositor_set_window_hidden(), etc, with the exact behavior
depending on the 'live_hidden_windows' preference.
Simplify this so that visibility is controlled by:
meta_compositor_show_window()
meta_compositor_hide_window()
With an 'effect' parameter provided to indicate the appropriate
effect (CREATE/UNMINIMIZE/MINIMIZE/DESTROY/NONE.)
The map state of the window is signalled separately by:
meta_compositor_map_window()
meta_compositor_unmap_window()
And is used only to control resource handling.
Other changes:
* The desired effect on show/hide is explicitly stored in
MetaWindow, avoiding the need for the was_minimized flag.
At idle, once we calculate the window state, we pass the
effect to the compositor if it matches the new window
state, and then clear the effect to start over for future
map state changes.
* meta_compositor_switch_workspace() is called before any windows
are hidden or shown, allowing the compositor to avoid hiding
or showing an effect for windows involved in the switch.
http://bugzilla.gnome.org/show_bug.cgi?id=582341
* Handling of post-effect cleanups for MutterWindow are
simplified - instead of trying to do different things based
on the individual needs of different effects, we just wait until
all effects complete and sync the window state to what it
should be.
* On unmap, once we destroy the pixmap, we tell ClutterX11Pixmap
that we've done so, so it can clean up and unbind. (The
unbinding doesn't seem to be working properly because of
ClutterGLXPixmap or video driver issues.)
http://bugzilla.gnome.org/show_bug.cgi?id=587251
2009-06-28 21:10:40 +00:00
|
|
|
{
|
|
|
|
(*counter)--;
|
2010-03-02 18:02:28 +00:00
|
|
|
if (use_freeze_thaw)
|
2010-10-18 17:27:14 +00:00
|
|
|
meta_window_actor_thaw (self);
|
Simplify relationship between mapping and visibility
Previously, changes to the visibility of a window could be indicated
by meta_compositor_map_window(), meta_compositor_unminimize_window(),
meta_compositor_set_window_hidden(), etc, with the exact behavior
depending on the 'live_hidden_windows' preference.
Simplify this so that visibility is controlled by:
meta_compositor_show_window()
meta_compositor_hide_window()
With an 'effect' parameter provided to indicate the appropriate
effect (CREATE/UNMINIMIZE/MINIMIZE/DESTROY/NONE.)
The map state of the window is signalled separately by:
meta_compositor_map_window()
meta_compositor_unmap_window()
And is used only to control resource handling.
Other changes:
* The desired effect on show/hide is explicitly stored in
MetaWindow, avoiding the need for the was_minimized flag.
At idle, once we calculate the window state, we pass the
effect to the compositor if it matches the new window
state, and then clear the effect to start over for future
map state changes.
* meta_compositor_switch_workspace() is called before any windows
are hidden or shown, allowing the compositor to avoid hiding
or showing an effect for windows involved in the switch.
http://bugzilla.gnome.org/show_bug.cgi?id=582341
* Handling of post-effect cleanups for MutterWindow are
simplified - instead of trying to do different things based
on the individual needs of different effects, we just wait until
all effects complete and sync the window state to what it
should be.
* On unmap, once we destroy the pixmap, we tell ClutterX11Pixmap
that we've done so, so it can clean up and unbind. (The
unbinding doesn't seem to be working properly because of
ClutterGLXPixmap or video driver issues.)
http://bugzilla.gnome.org/show_bug.cgi?id=587251
2009-06-28 21:10:40 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2010-10-18 17:27:14 +00:00
|
|
|
meta_window_actor_after_effects (MetaWindowActor *self)
|
Simplify relationship between mapping and visibility
Previously, changes to the visibility of a window could be indicated
by meta_compositor_map_window(), meta_compositor_unminimize_window(),
meta_compositor_set_window_hidden(), etc, with the exact behavior
depending on the 'live_hidden_windows' preference.
Simplify this so that visibility is controlled by:
meta_compositor_show_window()
meta_compositor_hide_window()
With an 'effect' parameter provided to indicate the appropriate
effect (CREATE/UNMINIMIZE/MINIMIZE/DESTROY/NONE.)
The map state of the window is signalled separately by:
meta_compositor_map_window()
meta_compositor_unmap_window()
And is used only to control resource handling.
Other changes:
* The desired effect on show/hide is explicitly stored in
MetaWindow, avoiding the need for the was_minimized flag.
At idle, once we calculate the window state, we pass the
effect to the compositor if it matches the new window
state, and then clear the effect to start over for future
map state changes.
* meta_compositor_switch_workspace() is called before any windows
are hidden or shown, allowing the compositor to avoid hiding
or showing an effect for windows involved in the switch.
http://bugzilla.gnome.org/show_bug.cgi?id=582341
* Handling of post-effect cleanups for MutterWindow are
simplified - instead of trying to do different things based
on the individual needs of different effects, we just wait until
all effects complete and sync the window state to what it
should be.
* On unmap, once we destroy the pixmap, we tell ClutterX11Pixmap
that we've done so, so it can clean up and unbind. (The
unbinding doesn't seem to be working properly because of
ClutterGLXPixmap or video driver issues.)
http://bugzilla.gnome.org/show_bug.cgi?id=587251
2009-06-28 21:10:40 +00:00
|
|
|
{
|
2018-12-21 20:12:49 +00:00
|
|
|
MetaWindowActorPrivate *priv =
|
|
|
|
meta_window_actor_get_instance_private (self);
|
2020-12-22 17:22:43 +00:00
|
|
|
ClutterStage *stage;
|
|
|
|
ClutterSeat *seat;
|
|
|
|
|
|
|
|
stage = CLUTTER_STAGE (clutter_actor_get_stage (CLUTTER_ACTOR (self)));
|
|
|
|
seat = clutter_backend_get_default_seat (clutter_get_default_backend ());
|
2018-12-21 20:12:49 +00:00
|
|
|
|
|
|
|
if (priv->needs_destroy)
|
Simplify relationship between mapping and visibility
Previously, changes to the visibility of a window could be indicated
by meta_compositor_map_window(), meta_compositor_unminimize_window(),
meta_compositor_set_window_hidden(), etc, with the exact behavior
depending on the 'live_hidden_windows' preference.
Simplify this so that visibility is controlled by:
meta_compositor_show_window()
meta_compositor_hide_window()
With an 'effect' parameter provided to indicate the appropriate
effect (CREATE/UNMINIMIZE/MINIMIZE/DESTROY/NONE.)
The map state of the window is signalled separately by:
meta_compositor_map_window()
meta_compositor_unmap_window()
And is used only to control resource handling.
Other changes:
* The desired effect on show/hide is explicitly stored in
MetaWindow, avoiding the need for the was_minimized flag.
At idle, once we calculate the window state, we pass the
effect to the compositor if it matches the new window
state, and then clear the effect to start over for future
map state changes.
* meta_compositor_switch_workspace() is called before any windows
are hidden or shown, allowing the compositor to avoid hiding
or showing an effect for windows involved in the switch.
http://bugzilla.gnome.org/show_bug.cgi?id=582341
* Handling of post-effect cleanups for MutterWindow are
simplified - instead of trying to do different things based
on the individual needs of different effects, we just wait until
all effects complete and sync the window state to what it
should be.
* On unmap, once we destroy the pixmap, we tell ClutterX11Pixmap
that we've done so, so it can clean up and unbind. (The
unbinding doesn't seem to be working properly because of
ClutterGLXPixmap or video driver issues.)
http://bugzilla.gnome.org/show_bug.cgi?id=587251
2009-06-28 21:10:40 +00:00
|
|
|
{
|
|
|
|
clutter_actor_destroy (CLUTTER_ACTOR (self));
|
2020-12-22 17:22:43 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
g_signal_emit (self, signals[EFFECTS_COMPLETED], 0);
|
|
|
|
meta_window_actor_sync_visibility (self);
|
|
|
|
meta_window_actor_sync_actor_geometry (self, FALSE);
|
Simplify relationship between mapping and visibility
Previously, changes to the visibility of a window could be indicated
by meta_compositor_map_window(), meta_compositor_unminimize_window(),
meta_compositor_set_window_hidden(), etc, with the exact behavior
depending on the 'live_hidden_windows' preference.
Simplify this so that visibility is controlled by:
meta_compositor_show_window()
meta_compositor_hide_window()
With an 'effect' parameter provided to indicate the appropriate
effect (CREATE/UNMINIMIZE/MINIMIZE/DESTROY/NONE.)
The map state of the window is signalled separately by:
meta_compositor_map_window()
meta_compositor_unmap_window()
And is used only to control resource handling.
Other changes:
* The desired effect on show/hide is explicitly stored in
MetaWindow, avoiding the need for the was_minimized flag.
At idle, once we calculate the window state, we pass the
effect to the compositor if it matches the new window
state, and then clear the effect to start over for future
map state changes.
* meta_compositor_switch_workspace() is called before any windows
are hidden or shown, allowing the compositor to avoid hiding
or showing an effect for windows involved in the switch.
http://bugzilla.gnome.org/show_bug.cgi?id=582341
* Handling of post-effect cleanups for MutterWindow are
simplified - instead of trying to do different things based
on the individual needs of different effects, we just wait until
all effects complete and sync the window state to what it
should be.
* On unmap, once we destroy the pixmap, we tell ClutterX11Pixmap
that we've done so, so it can clean up and unbind. (The
unbinding doesn't seem to be working properly because of
ClutterGLXPixmap or video driver issues.)
http://bugzilla.gnome.org/show_bug.cgi?id=587251
2009-06-28 21:10:40 +00:00
|
|
|
}
|
|
|
|
|
2020-12-22 17:22:43 +00:00
|
|
|
clutter_stage_repick_device (stage, clutter_seat_get_pointer (seat));
|
Simplify relationship between mapping and visibility
Previously, changes to the visibility of a window could be indicated
by meta_compositor_map_window(), meta_compositor_unminimize_window(),
meta_compositor_set_window_hidden(), etc, with the exact behavior
depending on the 'live_hidden_windows' preference.
Simplify this so that visibility is controlled by:
meta_compositor_show_window()
meta_compositor_hide_window()
With an 'effect' parameter provided to indicate the appropriate
effect (CREATE/UNMINIMIZE/MINIMIZE/DESTROY/NONE.)
The map state of the window is signalled separately by:
meta_compositor_map_window()
meta_compositor_unmap_window()
And is used only to control resource handling.
Other changes:
* The desired effect on show/hide is explicitly stored in
MetaWindow, avoiding the need for the was_minimized flag.
At idle, once we calculate the window state, we pass the
effect to the compositor if it matches the new window
state, and then clear the effect to start over for future
map state changes.
* meta_compositor_switch_workspace() is called before any windows
are hidden or shown, allowing the compositor to avoid hiding
or showing an effect for windows involved in the switch.
http://bugzilla.gnome.org/show_bug.cgi?id=582341
* Handling of post-effect cleanups for MutterWindow are
simplified - instead of trying to do different things based
on the individual needs of different effects, we just wait until
all effects complete and sync the window state to what it
should be.
* On unmap, once we destroy the pixmap, we tell ClutterX11Pixmap
that we've done so, so it can clean up and unbind. (The
unbinding doesn't seem to be working properly because of
ClutterGLXPixmap or video driver issues.)
http://bugzilla.gnome.org/show_bug.cgi?id=587251
2009-06-28 21:10:40 +00:00
|
|
|
}
|
|
|
|
|
2009-06-26 19:33:20 +00:00
|
|
|
void
|
2015-07-06 03:58:40 +00:00
|
|
|
meta_window_actor_effect_completed (MetaWindowActor *self,
|
|
|
|
MetaPluginEffect event)
|
2009-06-26 19:33:20 +00:00
|
|
|
{
|
2018-12-21 20:12:49 +00:00
|
|
|
MetaWindowActorPrivate *priv =
|
|
|
|
meta_window_actor_get_instance_private (self);
|
2017-01-24 10:03:41 +00:00
|
|
|
gboolean inconsistent = FALSE;
|
2009-06-26 19:33:20 +00:00
|
|
|
|
|
|
|
/* NB: Keep in mind that when effects get completed it possible
|
|
|
|
* that the corresponding MetaWindow may have be been destroyed.
|
2018-12-21 20:12:49 +00:00
|
|
|
* In this case priv->window will == NULL */
|
2009-06-26 19:33:20 +00:00
|
|
|
|
|
|
|
switch (event)
|
|
|
|
{
|
2015-07-06 04:08:08 +00:00
|
|
|
case META_PLUGIN_NONE:
|
|
|
|
break;
|
2010-10-18 17:27:14 +00:00
|
|
|
case META_PLUGIN_MINIMIZE:
|
2009-06-26 19:33:20 +00:00
|
|
|
{
|
2018-12-21 20:12:49 +00:00
|
|
|
priv->minimize_in_progress--;
|
|
|
|
if (priv->minimize_in_progress < 0)
|
2018-10-31 10:47:17 +00:00
|
|
|
{
|
|
|
|
g_warning ("Error in minimize accounting.");
|
2018-12-21 20:12:49 +00:00
|
|
|
priv->minimize_in_progress = 0;
|
2017-01-24 10:03:41 +00:00
|
|
|
inconsistent = TRUE;
|
2018-10-31 10:47:17 +00:00
|
|
|
}
|
2009-06-26 19:33:20 +00:00
|
|
|
}
|
|
|
|
break;
|
2013-06-14 01:01:17 +00:00
|
|
|
case META_PLUGIN_UNMINIMIZE:
|
|
|
|
{
|
2018-12-21 20:12:49 +00:00
|
|
|
priv->unminimize_in_progress--;
|
|
|
|
if (priv->unminimize_in_progress < 0)
|
2013-06-14 01:01:17 +00:00
|
|
|
{
|
|
|
|
g_warning ("Error in unminimize accounting.");
|
2018-12-21 20:12:49 +00:00
|
|
|
priv->unminimize_in_progress = 0;
|
2017-01-24 10:03:41 +00:00
|
|
|
inconsistent = TRUE;
|
2013-06-14 01:01:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2010-10-18 17:27:14 +00:00
|
|
|
case META_PLUGIN_MAP:
|
2009-06-26 19:33:20 +00:00
|
|
|
/*
|
|
|
|
* Make sure that the actor is at the correct place in case
|
|
|
|
* the plugin fscked.
|
|
|
|
*/
|
2018-12-21 20:12:49 +00:00
|
|
|
priv->map_in_progress--;
|
2009-06-26 19:33:20 +00:00
|
|
|
|
2018-12-21 20:12:49 +00:00
|
|
|
if (priv->map_in_progress < 0)
|
2009-06-26 19:33:20 +00:00
|
|
|
{
|
2018-10-31 10:47:17 +00:00
|
|
|
g_warning ("Error in map accounting.");
|
2018-12-21 20:12:49 +00:00
|
|
|
priv->map_in_progress = 0;
|
2017-01-24 10:03:41 +00:00
|
|
|
inconsistent = TRUE;
|
2009-06-26 19:33:20 +00:00
|
|
|
}
|
|
|
|
break;
|
2010-10-18 17:27:14 +00:00
|
|
|
case META_PLUGIN_DESTROY:
|
2018-12-21 20:12:49 +00:00
|
|
|
priv->destroy_in_progress--;
|
2009-06-26 19:33:20 +00:00
|
|
|
|
2018-12-21 20:12:49 +00:00
|
|
|
if (priv->destroy_in_progress < 0)
|
2009-06-26 19:33:20 +00:00
|
|
|
{
|
2018-10-31 10:47:17 +00:00
|
|
|
g_warning ("Error in destroy accounting.");
|
2018-12-21 20:12:49 +00:00
|
|
|
priv->destroy_in_progress = 0;
|
2017-01-24 10:03:41 +00:00
|
|
|
inconsistent = TRUE;
|
2009-06-26 19:33:20 +00:00
|
|
|
}
|
|
|
|
break;
|
2015-07-06 04:08:08 +00:00
|
|
|
case META_PLUGIN_SIZE_CHANGE:
|
2018-12-21 20:12:49 +00:00
|
|
|
priv->size_change_in_progress--;
|
|
|
|
if (priv->size_change_in_progress < 0)
|
2009-06-26 19:33:20 +00:00
|
|
|
{
|
2018-10-31 10:47:17 +00:00
|
|
|
g_warning ("Error in size change accounting.");
|
2018-12-21 20:12:49 +00:00
|
|
|
priv->size_change_in_progress = 0;
|
2017-01-24 10:03:41 +00:00
|
|
|
inconsistent = TRUE;
|
2009-06-26 19:33:20 +00:00
|
|
|
}
|
|
|
|
break;
|
2010-10-18 17:27:14 +00:00
|
|
|
case META_PLUGIN_SWITCH_WORKSPACE:
|
2009-06-26 19:33:20 +00:00
|
|
|
g_assert_not_reached ();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2017-01-24 10:03:41 +00:00
|
|
|
if (is_freeze_thaw_effect (event) && !inconsistent)
|
2010-10-18 17:27:14 +00:00
|
|
|
meta_window_actor_thaw (self);
|
2010-03-02 18:02:28 +00:00
|
|
|
|
2010-10-18 17:27:14 +00:00
|
|
|
if (!meta_window_actor_effect_in_progress (self))
|
|
|
|
meta_window_actor_after_effects (self);
|
2009-06-26 19:33:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2017-12-01 03:17:02 +00:00
|
|
|
meta_window_actor_queue_destroy (MetaWindowActor *self)
|
2009-06-26 19:33:20 +00:00
|
|
|
{
|
2018-12-21 20:12:49 +00:00
|
|
|
MetaWindowActorPrivate *priv =
|
|
|
|
meta_window_actor_get_instance_private (self);
|
|
|
|
MetaWindow *window = priv->window;
|
2014-03-18 21:31:22 +00:00
|
|
|
MetaWindowType window_type = meta_window_get_window_type (window);
|
2009-06-26 19:33:20 +00:00
|
|
|
|
|
|
|
meta_window_set_compositor_private (window, NULL);
|
|
|
|
|
2018-12-21 20:51:02 +00:00
|
|
|
META_WINDOW_ACTOR_GET_CLASS (self)->queue_destroy (self);
|
2014-02-02 10:37:25 +00:00
|
|
|
|
2010-09-30 16:35:12 +00:00
|
|
|
if (window_type == META_WINDOW_DROPDOWN_MENU ||
|
|
|
|
window_type == META_WINDOW_POPUP_MENU ||
|
|
|
|
window_type == META_WINDOW_TOOLTIP ||
|
|
|
|
window_type == META_WINDOW_NOTIFICATION ||
|
|
|
|
window_type == META_WINDOW_COMBO ||
|
|
|
|
window_type == META_WINDOW_DND ||
|
|
|
|
window_type == META_WINDOW_OVERRIDE_OTHER)
|
2009-06-26 19:33:20 +00:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
* No effects, just kill it.
|
|
|
|
*/
|
|
|
|
clutter_actor_destroy (CLUTTER_ACTOR (self));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-12-21 20:12:49 +00:00
|
|
|
priv->needs_destroy = TRUE;
|
2009-06-26 19:33:20 +00:00
|
|
|
|
2010-10-18 17:27:14 +00:00
|
|
|
if (!meta_window_actor_effect_in_progress (self))
|
Simplify relationship between mapping and visibility
Previously, changes to the visibility of a window could be indicated
by meta_compositor_map_window(), meta_compositor_unminimize_window(),
meta_compositor_set_window_hidden(), etc, with the exact behavior
depending on the 'live_hidden_windows' preference.
Simplify this so that visibility is controlled by:
meta_compositor_show_window()
meta_compositor_hide_window()
With an 'effect' parameter provided to indicate the appropriate
effect (CREATE/UNMINIMIZE/MINIMIZE/DESTROY/NONE.)
The map state of the window is signalled separately by:
meta_compositor_map_window()
meta_compositor_unmap_window()
And is used only to control resource handling.
Other changes:
* The desired effect on show/hide is explicitly stored in
MetaWindow, avoiding the need for the was_minimized flag.
At idle, once we calculate the window state, we pass the
effect to the compositor if it matches the new window
state, and then clear the effect to start over for future
map state changes.
* meta_compositor_switch_workspace() is called before any windows
are hidden or shown, allowing the compositor to avoid hiding
or showing an effect for windows involved in the switch.
http://bugzilla.gnome.org/show_bug.cgi?id=582341
* Handling of post-effect cleanups for MutterWindow are
simplified - instead of trying to do different things based
on the individual needs of different effects, we just wait until
all effects complete and sync the window state to what it
should be.
* On unmap, once we destroy the pixmap, we tell ClutterX11Pixmap
that we've done so, so it can clean up and unbind. (The
unbinding doesn't seem to be working properly because of
ClutterGLXPixmap or video driver issues.)
http://bugzilla.gnome.org/show_bug.cgi?id=587251
2009-06-28 21:10:40 +00:00
|
|
|
clutter_actor_destroy (CLUTTER_ACTOR (self));
|
2009-06-26 19:33:20 +00:00
|
|
|
}
|
|
|
|
|
2019-05-07 10:08:13 +00:00
|
|
|
MetaWindowActorChanges
|
2013-02-16 02:27:00 +00:00
|
|
|
meta_window_actor_sync_actor_geometry (MetaWindowActor *self,
|
|
|
|
gboolean did_placement)
|
2009-06-26 19:33:20 +00:00
|
|
|
{
|
2018-12-21 20:12:49 +00:00
|
|
|
MetaWindowActorPrivate *priv =
|
|
|
|
meta_window_actor_get_instance_private (self);
|
2022-09-27 14:54:29 +00:00
|
|
|
MetaRectangle actor_rect;
|
2019-05-07 10:08:13 +00:00
|
|
|
ClutterActor *actor = CLUTTER_ACTOR (self);
|
|
|
|
MetaWindowActorChanges changes = 0;
|
2009-06-26 19:33:20 +00:00
|
|
|
|
2022-09-27 14:54:29 +00:00
|
|
|
meta_window_get_buffer_rect (priv->window, &actor_rect);
|
2013-09-25 17:16:08 +00:00
|
|
|
|
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-01 22:21:11 +00:00
|
|
|
/* When running as a Wayland compositor we catch size changes when new
|
|
|
|
* buffers are attached */
|
2018-12-21 20:12:49 +00:00
|
|
|
if (META_IS_SURFACE_ACTOR_X11 (priv->surface))
|
|
|
|
meta_surface_actor_x11_set_size (META_SURFACE_ACTOR_X11 (priv->surface),
|
2022-09-27 14:54:29 +00:00
|
|
|
actor_rect.width, actor_rect.height);
|
2013-09-25 17:16:08 +00:00
|
|
|
|
2013-02-16 02:27:00 +00:00
|
|
|
/* Normally we want freezing a window to also freeze its position; this allows
|
|
|
|
* windows to atomically move and resize together, either under app control,
|
|
|
|
* or because the user is resizing from the left/top. But on initial placement
|
|
|
|
* we need to assign a position, since immediately after the window
|
|
|
|
* is shown, the map effect will go into effect and prevent further geometry
|
|
|
|
* updates.
|
|
|
|
*/
|
2019-08-17 08:00:46 +00:00
|
|
|
if (meta_window_actor_is_frozen (self) && !did_placement)
|
2019-05-07 10:08:13 +00:00
|
|
|
return META_WINDOW_ACTOR_CHANGE_POSITION | META_WINDOW_ACTOR_CHANGE_SIZE;
|
2013-02-16 02:27:00 +00:00
|
|
|
|
2022-05-03 16:47:57 +00:00
|
|
|
META_WINDOW_ACTOR_GET_CLASS (self)->sync_geometry (self, &actor_rect);
|
|
|
|
|
2019-05-07 10:08:13 +00:00
|
|
|
if (clutter_actor_has_allocation (actor))
|
|
|
|
{
|
|
|
|
ClutterActorBox box;
|
|
|
|
float old_x, old_y;
|
|
|
|
float old_width, old_height;
|
|
|
|
|
|
|
|
clutter_actor_get_allocation_box (actor, &box);
|
|
|
|
|
|
|
|
old_x = box.x1;
|
|
|
|
old_y = box.y1;
|
|
|
|
old_width = box.x2 - box.x1;
|
|
|
|
old_height = box.y2 - box.y1;
|
|
|
|
|
2022-09-27 14:54:29 +00:00
|
|
|
if (old_x != actor_rect.x || old_y != actor_rect.y)
|
2019-05-07 10:08:13 +00:00
|
|
|
changes |= META_WINDOW_ACTOR_CHANGE_POSITION;
|
|
|
|
|
2022-09-27 14:54:29 +00:00
|
|
|
if (old_width != actor_rect.width || old_height != actor_rect.height)
|
2019-05-07 10:08:13 +00:00
|
|
|
changes |= META_WINDOW_ACTOR_CHANGE_SIZE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
changes = META_WINDOW_ACTOR_CHANGE_POSITION | META_WINDOW_ACTOR_CHANGE_SIZE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (changes & META_WINDOW_ACTOR_CHANGE_POSITION)
|
2022-09-27 14:54:29 +00:00
|
|
|
clutter_actor_set_position (actor, actor_rect.x, actor_rect.y);
|
2019-05-07 10:08:13 +00:00
|
|
|
|
|
|
|
if (changes & META_WINDOW_ACTOR_CHANGE_SIZE)
|
2022-09-27 14:54:29 +00:00
|
|
|
clutter_actor_set_size (actor, actor_rect.width, actor_rect.height);
|
2009-06-26 19:33:20 +00:00
|
|
|
|
2019-05-07 10:08:13 +00:00
|
|
|
return changes;
|
2009-06-26 19:33:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2010-10-18 17:27:14 +00:00
|
|
|
meta_window_actor_show (MetaWindowActor *self,
|
|
|
|
MetaCompEffect effect)
|
2009-06-26 19:33:20 +00:00
|
|
|
{
|
2018-12-21 20:12:49 +00:00
|
|
|
MetaWindowActorPrivate *priv =
|
|
|
|
meta_window_actor_get_instance_private (self);
|
|
|
|
MetaCompositor *compositor = priv->compositor;
|
2015-07-06 03:58:40 +00:00
|
|
|
MetaPluginEffect event;
|
2009-06-26 19:33:20 +00:00
|
|
|
|
2018-12-21 20:12:49 +00:00
|
|
|
g_return_if_fail (!priv->visible);
|
2009-06-26 19:33:20 +00:00
|
|
|
|
2018-12-21 20:12:49 +00:00
|
|
|
priv->visible = TRUE;
|
2009-06-26 19:33:20 +00:00
|
|
|
|
Simplify relationship between mapping and visibility
Previously, changes to the visibility of a window could be indicated
by meta_compositor_map_window(), meta_compositor_unminimize_window(),
meta_compositor_set_window_hidden(), etc, with the exact behavior
depending on the 'live_hidden_windows' preference.
Simplify this so that visibility is controlled by:
meta_compositor_show_window()
meta_compositor_hide_window()
With an 'effect' parameter provided to indicate the appropriate
effect (CREATE/UNMINIMIZE/MINIMIZE/DESTROY/NONE.)
The map state of the window is signalled separately by:
meta_compositor_map_window()
meta_compositor_unmap_window()
And is used only to control resource handling.
Other changes:
* The desired effect on show/hide is explicitly stored in
MetaWindow, avoiding the need for the was_minimized flag.
At idle, once we calculate the window state, we pass the
effect to the compositor if it matches the new window
state, and then clear the effect to start over for future
map state changes.
* meta_compositor_switch_workspace() is called before any windows
are hidden or shown, allowing the compositor to avoid hiding
or showing an effect for windows involved in the switch.
http://bugzilla.gnome.org/show_bug.cgi?id=582341
* Handling of post-effect cleanups for MutterWindow are
simplified - instead of trying to do different things based
on the individual needs of different effects, we just wait until
all effects complete and sync the window state to what it
should be.
* On unmap, once we destroy the pixmap, we tell ClutterX11Pixmap
that we've done so, so it can clean up and unbind. (The
unbinding doesn't seem to be working properly because of
ClutterGLXPixmap or video driver issues.)
http://bugzilla.gnome.org/show_bug.cgi?id=587251
2009-06-28 21:10:40 +00:00
|
|
|
switch (effect)
|
2009-06-26 19:33:20 +00:00
|
|
|
{
|
Simplify relationship between mapping and visibility
Previously, changes to the visibility of a window could be indicated
by meta_compositor_map_window(), meta_compositor_unminimize_window(),
meta_compositor_set_window_hidden(), etc, with the exact behavior
depending on the 'live_hidden_windows' preference.
Simplify this so that visibility is controlled by:
meta_compositor_show_window()
meta_compositor_hide_window()
With an 'effect' parameter provided to indicate the appropriate
effect (CREATE/UNMINIMIZE/MINIMIZE/DESTROY/NONE.)
The map state of the window is signalled separately by:
meta_compositor_map_window()
meta_compositor_unmap_window()
And is used only to control resource handling.
Other changes:
* The desired effect on show/hide is explicitly stored in
MetaWindow, avoiding the need for the was_minimized flag.
At idle, once we calculate the window state, we pass the
effect to the compositor if it matches the new window
state, and then clear the effect to start over for future
map state changes.
* meta_compositor_switch_workspace() is called before any windows
are hidden or shown, allowing the compositor to avoid hiding
or showing an effect for windows involved in the switch.
http://bugzilla.gnome.org/show_bug.cgi?id=582341
* Handling of post-effect cleanups for MutterWindow are
simplified - instead of trying to do different things based
on the individual needs of different effects, we just wait until
all effects complete and sync the window state to what it
should be.
* On unmap, once we destroy the pixmap, we tell ClutterX11Pixmap
that we've done so, so it can clean up and unbind. (The
unbinding doesn't seem to be working properly because of
ClutterGLXPixmap or video driver issues.)
http://bugzilla.gnome.org/show_bug.cgi?id=587251
2009-06-28 21:10:40 +00:00
|
|
|
case META_COMP_EFFECT_CREATE:
|
2010-10-18 17:27:14 +00:00
|
|
|
event = META_PLUGIN_MAP;
|
Simplify relationship between mapping and visibility
Previously, changes to the visibility of a window could be indicated
by meta_compositor_map_window(), meta_compositor_unminimize_window(),
meta_compositor_set_window_hidden(), etc, with the exact behavior
depending on the 'live_hidden_windows' preference.
Simplify this so that visibility is controlled by:
meta_compositor_show_window()
meta_compositor_hide_window()
With an 'effect' parameter provided to indicate the appropriate
effect (CREATE/UNMINIMIZE/MINIMIZE/DESTROY/NONE.)
The map state of the window is signalled separately by:
meta_compositor_map_window()
meta_compositor_unmap_window()
And is used only to control resource handling.
Other changes:
* The desired effect on show/hide is explicitly stored in
MetaWindow, avoiding the need for the was_minimized flag.
At idle, once we calculate the window state, we pass the
effect to the compositor if it matches the new window
state, and then clear the effect to start over for future
map state changes.
* meta_compositor_switch_workspace() is called before any windows
are hidden or shown, allowing the compositor to avoid hiding
or showing an effect for windows involved in the switch.
http://bugzilla.gnome.org/show_bug.cgi?id=582341
* Handling of post-effect cleanups for MutterWindow are
simplified - instead of trying to do different things based
on the individual needs of different effects, we just wait until
all effects complete and sync the window state to what it
should be.
* On unmap, once we destroy the pixmap, we tell ClutterX11Pixmap
that we've done so, so it can clean up and unbind. (The
unbinding doesn't seem to be working properly because of
ClutterGLXPixmap or video driver issues.)
http://bugzilla.gnome.org/show_bug.cgi?id=587251
2009-06-28 21:10:40 +00:00
|
|
|
break;
|
|
|
|
case META_COMP_EFFECT_UNMINIMIZE:
|
2013-06-14 01:01:17 +00:00
|
|
|
event = META_PLUGIN_UNMINIMIZE;
|
Simplify relationship between mapping and visibility
Previously, changes to the visibility of a window could be indicated
by meta_compositor_map_window(), meta_compositor_unminimize_window(),
meta_compositor_set_window_hidden(), etc, with the exact behavior
depending on the 'live_hidden_windows' preference.
Simplify this so that visibility is controlled by:
meta_compositor_show_window()
meta_compositor_hide_window()
With an 'effect' parameter provided to indicate the appropriate
effect (CREATE/UNMINIMIZE/MINIMIZE/DESTROY/NONE.)
The map state of the window is signalled separately by:
meta_compositor_map_window()
meta_compositor_unmap_window()
And is used only to control resource handling.
Other changes:
* The desired effect on show/hide is explicitly stored in
MetaWindow, avoiding the need for the was_minimized flag.
At idle, once we calculate the window state, we pass the
effect to the compositor if it matches the new window
state, and then clear the effect to start over for future
map state changes.
* meta_compositor_switch_workspace() is called before any windows
are hidden or shown, allowing the compositor to avoid hiding
or showing an effect for windows involved in the switch.
http://bugzilla.gnome.org/show_bug.cgi?id=582341
* Handling of post-effect cleanups for MutterWindow are
simplified - instead of trying to do different things based
on the individual needs of different effects, we just wait until
all effects complete and sync the window state to what it
should be.
* On unmap, once we destroy the pixmap, we tell ClutterX11Pixmap
that we've done so, so it can clean up and unbind. (The
unbinding doesn't seem to be working properly because of
ClutterGLXPixmap or video driver issues.)
http://bugzilla.gnome.org/show_bug.cgi?id=587251
2009-06-28 21:10:40 +00:00
|
|
|
break;
|
|
|
|
case META_COMP_EFFECT_NONE:
|
2015-07-06 04:08:08 +00:00
|
|
|
event = META_PLUGIN_NONE;
|
Simplify relationship between mapping and visibility
Previously, changes to the visibility of a window could be indicated
by meta_compositor_map_window(), meta_compositor_unminimize_window(),
meta_compositor_set_window_hidden(), etc, with the exact behavior
depending on the 'live_hidden_windows' preference.
Simplify this so that visibility is controlled by:
meta_compositor_show_window()
meta_compositor_hide_window()
With an 'effect' parameter provided to indicate the appropriate
effect (CREATE/UNMINIMIZE/MINIMIZE/DESTROY/NONE.)
The map state of the window is signalled separately by:
meta_compositor_map_window()
meta_compositor_unmap_window()
And is used only to control resource handling.
Other changes:
* The desired effect on show/hide is explicitly stored in
MetaWindow, avoiding the need for the was_minimized flag.
At idle, once we calculate the window state, we pass the
effect to the compositor if it matches the new window
state, and then clear the effect to start over for future
map state changes.
* meta_compositor_switch_workspace() is called before any windows
are hidden or shown, allowing the compositor to avoid hiding
or showing an effect for windows involved in the switch.
http://bugzilla.gnome.org/show_bug.cgi?id=582341
* Handling of post-effect cleanups for MutterWindow are
simplified - instead of trying to do different things based
on the individual needs of different effects, we just wait until
all effects complete and sync the window state to what it
should be.
* On unmap, once we destroy the pixmap, we tell ClutterX11Pixmap
that we've done so, so it can clean up and unbind. (The
unbinding doesn't seem to be working properly because of
ClutterGLXPixmap or video driver issues.)
http://bugzilla.gnome.org/show_bug.cgi?id=587251
2009-06-28 21:10:40 +00:00
|
|
|
break;
|
2015-07-06 04:08:08 +00:00
|
|
|
default:
|
Simplify relationship between mapping and visibility
Previously, changes to the visibility of a window could be indicated
by meta_compositor_map_window(), meta_compositor_unminimize_window(),
meta_compositor_set_window_hidden(), etc, with the exact behavior
depending on the 'live_hidden_windows' preference.
Simplify this so that visibility is controlled by:
meta_compositor_show_window()
meta_compositor_hide_window()
With an 'effect' parameter provided to indicate the appropriate
effect (CREATE/UNMINIMIZE/MINIMIZE/DESTROY/NONE.)
The map state of the window is signalled separately by:
meta_compositor_map_window()
meta_compositor_unmap_window()
And is used only to control resource handling.
Other changes:
* The desired effect on show/hide is explicitly stored in
MetaWindow, avoiding the need for the was_minimized flag.
At idle, once we calculate the window state, we pass the
effect to the compositor if it matches the new window
state, and then clear the effect to start over for future
map state changes.
* meta_compositor_switch_workspace() is called before any windows
are hidden or shown, allowing the compositor to avoid hiding
or showing an effect for windows involved in the switch.
http://bugzilla.gnome.org/show_bug.cgi?id=582341
* Handling of post-effect cleanups for MutterWindow are
simplified - instead of trying to do different things based
on the individual needs of different effects, we just wait until
all effects complete and sync the window state to what it
should be.
* On unmap, once we destroy the pixmap, we tell ClutterX11Pixmap
that we've done so, so it can clean up and unbind. (The
unbinding doesn't seem to be working properly because of
ClutterGLXPixmap or video driver issues.)
http://bugzilla.gnome.org/show_bug.cgi?id=587251
2009-06-28 21:10:40 +00:00
|
|
|
g_assert_not_reached();
|
2009-06-26 19:33:20 +00:00
|
|
|
}
|
|
|
|
|
2020-03-30 10:23:42 +00:00
|
|
|
if (event == META_PLUGIN_MAP)
|
|
|
|
meta_window_actor_sync_actor_geometry (self, TRUE);
|
|
|
|
|
2019-08-14 17:04:41 +00:00
|
|
|
if (meta_compositor_is_switching_workspace (compositor) ||
|
Simplify relationship between mapping and visibility
Previously, changes to the visibility of a window could be indicated
by meta_compositor_map_window(), meta_compositor_unminimize_window(),
meta_compositor_set_window_hidden(), etc, with the exact behavior
depending on the 'live_hidden_windows' preference.
Simplify this so that visibility is controlled by:
meta_compositor_show_window()
meta_compositor_hide_window()
With an 'effect' parameter provided to indicate the appropriate
effect (CREATE/UNMINIMIZE/MINIMIZE/DESTROY/NONE.)
The map state of the window is signalled separately by:
meta_compositor_map_window()
meta_compositor_unmap_window()
And is used only to control resource handling.
Other changes:
* The desired effect on show/hide is explicitly stored in
MetaWindow, avoiding the need for the was_minimized flag.
At idle, once we calculate the window state, we pass the
effect to the compositor if it matches the new window
state, and then clear the effect to start over for future
map state changes.
* meta_compositor_switch_workspace() is called before any windows
are hidden or shown, allowing the compositor to avoid hiding
or showing an effect for windows involved in the switch.
http://bugzilla.gnome.org/show_bug.cgi?id=582341
* Handling of post-effect cleanups for MutterWindow are
simplified - instead of trying to do different things based
on the individual needs of different effects, we just wait until
all effects complete and sync the window state to what it
should be.
* On unmap, once we destroy the pixmap, we tell ClutterX11Pixmap
that we've done so, so it can clean up and unbind. (The
unbinding doesn't seem to be working properly because of
ClutterGLXPixmap or video driver issues.)
http://bugzilla.gnome.org/show_bug.cgi?id=587251
2009-06-28 21:10:40 +00:00
|
|
|
!start_simple_effect (self, event))
|
2009-06-26 19:33:20 +00:00
|
|
|
{
|
2012-01-17 14:16:46 +00:00
|
|
|
clutter_actor_show (CLUTTER_ACTOR (self));
|
2009-06-26 19:33:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2010-10-18 17:27:14 +00:00
|
|
|
meta_window_actor_hide (MetaWindowActor *self,
|
|
|
|
MetaCompEffect effect)
|
2009-06-26 19:33:20 +00:00
|
|
|
{
|
2018-12-21 20:12:49 +00:00
|
|
|
MetaWindowActorPrivate *priv =
|
|
|
|
meta_window_actor_get_instance_private (self);
|
|
|
|
MetaCompositor *compositor = priv->compositor;
|
2015-07-06 04:08:08 +00:00
|
|
|
MetaPluginEffect event;
|
2009-06-26 19:33:20 +00:00
|
|
|
|
2018-12-21 20:12:49 +00:00
|
|
|
g_return_if_fail (priv->visible);
|
2009-06-26 19:33:20 +00:00
|
|
|
|
2018-12-21 20:12:49 +00:00
|
|
|
priv->visible = FALSE;
|
2009-06-26 19:33:20 +00:00
|
|
|
|
Simplify relationship between mapping and visibility
Previously, changes to the visibility of a window could be indicated
by meta_compositor_map_window(), meta_compositor_unminimize_window(),
meta_compositor_set_window_hidden(), etc, with the exact behavior
depending on the 'live_hidden_windows' preference.
Simplify this so that visibility is controlled by:
meta_compositor_show_window()
meta_compositor_hide_window()
With an 'effect' parameter provided to indicate the appropriate
effect (CREATE/UNMINIMIZE/MINIMIZE/DESTROY/NONE.)
The map state of the window is signalled separately by:
meta_compositor_map_window()
meta_compositor_unmap_window()
And is used only to control resource handling.
Other changes:
* The desired effect on show/hide is explicitly stored in
MetaWindow, avoiding the need for the was_minimized flag.
At idle, once we calculate the window state, we pass the
effect to the compositor if it matches the new window
state, and then clear the effect to start over for future
map state changes.
* meta_compositor_switch_workspace() is called before any windows
are hidden or shown, allowing the compositor to avoid hiding
or showing an effect for windows involved in the switch.
http://bugzilla.gnome.org/show_bug.cgi?id=582341
* Handling of post-effect cleanups for MutterWindow are
simplified - instead of trying to do different things based
on the individual needs of different effects, we just wait until
all effects complete and sync the window state to what it
should be.
* On unmap, once we destroy the pixmap, we tell ClutterX11Pixmap
that we've done so, so it can clean up and unbind. (The
unbinding doesn't seem to be working properly because of
ClutterGLXPixmap or video driver issues.)
http://bugzilla.gnome.org/show_bug.cgi?id=587251
2009-06-28 21:10:40 +00:00
|
|
|
/* If a plugin is animating a workspace transition, we have to
|
|
|
|
* hold off on hiding the window, and do it after the workspace
|
|
|
|
* switch completes
|
2009-06-26 19:33:20 +00:00
|
|
|
*/
|
2019-08-14 17:04:41 +00:00
|
|
|
if (meta_compositor_is_switching_workspace (compositor))
|
Simplify relationship between mapping and visibility
Previously, changes to the visibility of a window could be indicated
by meta_compositor_map_window(), meta_compositor_unminimize_window(),
meta_compositor_set_window_hidden(), etc, with the exact behavior
depending on the 'live_hidden_windows' preference.
Simplify this so that visibility is controlled by:
meta_compositor_show_window()
meta_compositor_hide_window()
With an 'effect' parameter provided to indicate the appropriate
effect (CREATE/UNMINIMIZE/MINIMIZE/DESTROY/NONE.)
The map state of the window is signalled separately by:
meta_compositor_map_window()
meta_compositor_unmap_window()
And is used only to control resource handling.
Other changes:
* The desired effect on show/hide is explicitly stored in
MetaWindow, avoiding the need for the was_minimized flag.
At idle, once we calculate the window state, we pass the
effect to the compositor if it matches the new window
state, and then clear the effect to start over for future
map state changes.
* meta_compositor_switch_workspace() is called before any windows
are hidden or shown, allowing the compositor to avoid hiding
or showing an effect for windows involved in the switch.
http://bugzilla.gnome.org/show_bug.cgi?id=582341
* Handling of post-effect cleanups for MutterWindow are
simplified - instead of trying to do different things based
on the individual needs of different effects, we just wait until
all effects complete and sync the window state to what it
should be.
* On unmap, once we destroy the pixmap, we tell ClutterX11Pixmap
that we've done so, so it can clean up and unbind. (The
unbinding doesn't seem to be working properly because of
ClutterGLXPixmap or video driver issues.)
http://bugzilla.gnome.org/show_bug.cgi?id=587251
2009-06-28 21:10:40 +00:00
|
|
|
return;
|
2009-06-26 19:33:20 +00:00
|
|
|
|
Simplify relationship between mapping and visibility
Previously, changes to the visibility of a window could be indicated
by meta_compositor_map_window(), meta_compositor_unminimize_window(),
meta_compositor_set_window_hidden(), etc, with the exact behavior
depending on the 'live_hidden_windows' preference.
Simplify this so that visibility is controlled by:
meta_compositor_show_window()
meta_compositor_hide_window()
With an 'effect' parameter provided to indicate the appropriate
effect (CREATE/UNMINIMIZE/MINIMIZE/DESTROY/NONE.)
The map state of the window is signalled separately by:
meta_compositor_map_window()
meta_compositor_unmap_window()
And is used only to control resource handling.
Other changes:
* The desired effect on show/hide is explicitly stored in
MetaWindow, avoiding the need for the was_minimized flag.
At idle, once we calculate the window state, we pass the
effect to the compositor if it matches the new window
state, and then clear the effect to start over for future
map state changes.
* meta_compositor_switch_workspace() is called before any windows
are hidden or shown, allowing the compositor to avoid hiding
or showing an effect for windows involved in the switch.
http://bugzilla.gnome.org/show_bug.cgi?id=582341
* Handling of post-effect cleanups for MutterWindow are
simplified - instead of trying to do different things based
on the individual needs of different effects, we just wait until
all effects complete and sync the window state to what it
should be.
* On unmap, once we destroy the pixmap, we tell ClutterX11Pixmap
that we've done so, so it can clean up and unbind. (The
unbinding doesn't seem to be working properly because of
ClutterGLXPixmap or video driver issues.)
http://bugzilla.gnome.org/show_bug.cgi?id=587251
2009-06-28 21:10:40 +00:00
|
|
|
switch (effect)
|
2009-06-26 19:33:20 +00:00
|
|
|
{
|
Simplify relationship between mapping and visibility
Previously, changes to the visibility of a window could be indicated
by meta_compositor_map_window(), meta_compositor_unminimize_window(),
meta_compositor_set_window_hidden(), etc, with the exact behavior
depending on the 'live_hidden_windows' preference.
Simplify this so that visibility is controlled by:
meta_compositor_show_window()
meta_compositor_hide_window()
With an 'effect' parameter provided to indicate the appropriate
effect (CREATE/UNMINIMIZE/MINIMIZE/DESTROY/NONE.)
The map state of the window is signalled separately by:
meta_compositor_map_window()
meta_compositor_unmap_window()
And is used only to control resource handling.
Other changes:
* The desired effect on show/hide is explicitly stored in
MetaWindow, avoiding the need for the was_minimized flag.
At idle, once we calculate the window state, we pass the
effect to the compositor if it matches the new window
state, and then clear the effect to start over for future
map state changes.
* meta_compositor_switch_workspace() is called before any windows
are hidden or shown, allowing the compositor to avoid hiding
or showing an effect for windows involved in the switch.
http://bugzilla.gnome.org/show_bug.cgi?id=582341
* Handling of post-effect cleanups for MutterWindow are
simplified - instead of trying to do different things based
on the individual needs of different effects, we just wait until
all effects complete and sync the window state to what it
should be.
* On unmap, once we destroy the pixmap, we tell ClutterX11Pixmap
that we've done so, so it can clean up and unbind. (The
unbinding doesn't seem to be working properly because of
ClutterGLXPixmap or video driver issues.)
http://bugzilla.gnome.org/show_bug.cgi?id=587251
2009-06-28 21:10:40 +00:00
|
|
|
case META_COMP_EFFECT_DESTROY:
|
2010-10-18 17:27:14 +00:00
|
|
|
event = META_PLUGIN_DESTROY;
|
Simplify relationship between mapping and visibility
Previously, changes to the visibility of a window could be indicated
by meta_compositor_map_window(), meta_compositor_unminimize_window(),
meta_compositor_set_window_hidden(), etc, with the exact behavior
depending on the 'live_hidden_windows' preference.
Simplify this so that visibility is controlled by:
meta_compositor_show_window()
meta_compositor_hide_window()
With an 'effect' parameter provided to indicate the appropriate
effect (CREATE/UNMINIMIZE/MINIMIZE/DESTROY/NONE.)
The map state of the window is signalled separately by:
meta_compositor_map_window()
meta_compositor_unmap_window()
And is used only to control resource handling.
Other changes:
* The desired effect on show/hide is explicitly stored in
MetaWindow, avoiding the need for the was_minimized flag.
At idle, once we calculate the window state, we pass the
effect to the compositor if it matches the new window
state, and then clear the effect to start over for future
map state changes.
* meta_compositor_switch_workspace() is called before any windows
are hidden or shown, allowing the compositor to avoid hiding
or showing an effect for windows involved in the switch.
http://bugzilla.gnome.org/show_bug.cgi?id=582341
* Handling of post-effect cleanups for MutterWindow are
simplified - instead of trying to do different things based
on the individual needs of different effects, we just wait until
all effects complete and sync the window state to what it
should be.
* On unmap, once we destroy the pixmap, we tell ClutterX11Pixmap
that we've done so, so it can clean up and unbind. (The
unbinding doesn't seem to be working properly because of
ClutterGLXPixmap or video driver issues.)
http://bugzilla.gnome.org/show_bug.cgi?id=587251
2009-06-28 21:10:40 +00:00
|
|
|
break;
|
|
|
|
case META_COMP_EFFECT_MINIMIZE:
|
2010-10-18 17:27:14 +00:00
|
|
|
event = META_PLUGIN_MINIMIZE;
|
Simplify relationship between mapping and visibility
Previously, changes to the visibility of a window could be indicated
by meta_compositor_map_window(), meta_compositor_unminimize_window(),
meta_compositor_set_window_hidden(), etc, with the exact behavior
depending on the 'live_hidden_windows' preference.
Simplify this so that visibility is controlled by:
meta_compositor_show_window()
meta_compositor_hide_window()
With an 'effect' parameter provided to indicate the appropriate
effect (CREATE/UNMINIMIZE/MINIMIZE/DESTROY/NONE.)
The map state of the window is signalled separately by:
meta_compositor_map_window()
meta_compositor_unmap_window()
And is used only to control resource handling.
Other changes:
* The desired effect on show/hide is explicitly stored in
MetaWindow, avoiding the need for the was_minimized flag.
At idle, once we calculate the window state, we pass the
effect to the compositor if it matches the new window
state, and then clear the effect to start over for future
map state changes.
* meta_compositor_switch_workspace() is called before any windows
are hidden or shown, allowing the compositor to avoid hiding
or showing an effect for windows involved in the switch.
http://bugzilla.gnome.org/show_bug.cgi?id=582341
* Handling of post-effect cleanups for MutterWindow are
simplified - instead of trying to do different things based
on the individual needs of different effects, we just wait until
all effects complete and sync the window state to what it
should be.
* On unmap, once we destroy the pixmap, we tell ClutterX11Pixmap
that we've done so, so it can clean up and unbind. (The
unbinding doesn't seem to be working properly because of
ClutterGLXPixmap or video driver issues.)
http://bugzilla.gnome.org/show_bug.cgi?id=587251
2009-06-28 21:10:40 +00:00
|
|
|
break;
|
|
|
|
case META_COMP_EFFECT_NONE:
|
2015-07-06 04:08:08 +00:00
|
|
|
event = META_PLUGIN_NONE;
|
Simplify relationship between mapping and visibility
Previously, changes to the visibility of a window could be indicated
by meta_compositor_map_window(), meta_compositor_unminimize_window(),
meta_compositor_set_window_hidden(), etc, with the exact behavior
depending on the 'live_hidden_windows' preference.
Simplify this so that visibility is controlled by:
meta_compositor_show_window()
meta_compositor_hide_window()
With an 'effect' parameter provided to indicate the appropriate
effect (CREATE/UNMINIMIZE/MINIMIZE/DESTROY/NONE.)
The map state of the window is signalled separately by:
meta_compositor_map_window()
meta_compositor_unmap_window()
And is used only to control resource handling.
Other changes:
* The desired effect on show/hide is explicitly stored in
MetaWindow, avoiding the need for the was_minimized flag.
At idle, once we calculate the window state, we pass the
effect to the compositor if it matches the new window
state, and then clear the effect to start over for future
map state changes.
* meta_compositor_switch_workspace() is called before any windows
are hidden or shown, allowing the compositor to avoid hiding
or showing an effect for windows involved in the switch.
http://bugzilla.gnome.org/show_bug.cgi?id=582341
* Handling of post-effect cleanups for MutterWindow are
simplified - instead of trying to do different things based
on the individual needs of different effects, we just wait until
all effects complete and sync the window state to what it
should be.
* On unmap, once we destroy the pixmap, we tell ClutterX11Pixmap
that we've done so, so it can clean up and unbind. (The
unbinding doesn't seem to be working properly because of
ClutterGLXPixmap or video driver issues.)
http://bugzilla.gnome.org/show_bug.cgi?id=587251
2009-06-28 21:10:40 +00:00
|
|
|
break;
|
2015-07-06 04:08:08 +00:00
|
|
|
default:
|
Simplify relationship between mapping and visibility
Previously, changes to the visibility of a window could be indicated
by meta_compositor_map_window(), meta_compositor_unminimize_window(),
meta_compositor_set_window_hidden(), etc, with the exact behavior
depending on the 'live_hidden_windows' preference.
Simplify this so that visibility is controlled by:
meta_compositor_show_window()
meta_compositor_hide_window()
With an 'effect' parameter provided to indicate the appropriate
effect (CREATE/UNMINIMIZE/MINIMIZE/DESTROY/NONE.)
The map state of the window is signalled separately by:
meta_compositor_map_window()
meta_compositor_unmap_window()
And is used only to control resource handling.
Other changes:
* The desired effect on show/hide is explicitly stored in
MetaWindow, avoiding the need for the was_minimized flag.
At idle, once we calculate the window state, we pass the
effect to the compositor if it matches the new window
state, and then clear the effect to start over for future
map state changes.
* meta_compositor_switch_workspace() is called before any windows
are hidden or shown, allowing the compositor to avoid hiding
or showing an effect for windows involved in the switch.
http://bugzilla.gnome.org/show_bug.cgi?id=582341
* Handling of post-effect cleanups for MutterWindow are
simplified - instead of trying to do different things based
on the individual needs of different effects, we just wait until
all effects complete and sync the window state to what it
should be.
* On unmap, once we destroy the pixmap, we tell ClutterX11Pixmap
that we've done so, so it can clean up and unbind. (The
unbinding doesn't seem to be working properly because of
ClutterGLXPixmap or video driver issues.)
http://bugzilla.gnome.org/show_bug.cgi?id=587251
2009-06-28 21:10:40 +00:00
|
|
|
g_assert_not_reached();
|
2009-06-26 19:33:20 +00:00
|
|
|
}
|
Simplify relationship between mapping and visibility
Previously, changes to the visibility of a window could be indicated
by meta_compositor_map_window(), meta_compositor_unminimize_window(),
meta_compositor_set_window_hidden(), etc, with the exact behavior
depending on the 'live_hidden_windows' preference.
Simplify this so that visibility is controlled by:
meta_compositor_show_window()
meta_compositor_hide_window()
With an 'effect' parameter provided to indicate the appropriate
effect (CREATE/UNMINIMIZE/MINIMIZE/DESTROY/NONE.)
The map state of the window is signalled separately by:
meta_compositor_map_window()
meta_compositor_unmap_window()
And is used only to control resource handling.
Other changes:
* The desired effect on show/hide is explicitly stored in
MetaWindow, avoiding the need for the was_minimized flag.
At idle, once we calculate the window state, we pass the
effect to the compositor if it matches the new window
state, and then clear the effect to start over for future
map state changes.
* meta_compositor_switch_workspace() is called before any windows
are hidden or shown, allowing the compositor to avoid hiding
or showing an effect for windows involved in the switch.
http://bugzilla.gnome.org/show_bug.cgi?id=582341
* Handling of post-effect cleanups for MutterWindow are
simplified - instead of trying to do different things based
on the individual needs of different effects, we just wait until
all effects complete and sync the window state to what it
should be.
* On unmap, once we destroy the pixmap, we tell ClutterX11Pixmap
that we've done so, so it can clean up and unbind. (The
unbinding doesn't seem to be working properly because of
ClutterGLXPixmap or video driver issues.)
http://bugzilla.gnome.org/show_bug.cgi?id=587251
2009-06-28 21:10:40 +00:00
|
|
|
|
2015-07-06 04:08:08 +00:00
|
|
|
if (!start_simple_effect (self, event))
|
Simplify relationship between mapping and visibility
Previously, changes to the visibility of a window could be indicated
by meta_compositor_map_window(), meta_compositor_unminimize_window(),
meta_compositor_set_window_hidden(), etc, with the exact behavior
depending on the 'live_hidden_windows' preference.
Simplify this so that visibility is controlled by:
meta_compositor_show_window()
meta_compositor_hide_window()
With an 'effect' parameter provided to indicate the appropriate
effect (CREATE/UNMINIMIZE/MINIMIZE/DESTROY/NONE.)
The map state of the window is signalled separately by:
meta_compositor_map_window()
meta_compositor_unmap_window()
And is used only to control resource handling.
Other changes:
* The desired effect on show/hide is explicitly stored in
MetaWindow, avoiding the need for the was_minimized flag.
At idle, once we calculate the window state, we pass the
effect to the compositor if it matches the new window
state, and then clear the effect to start over for future
map state changes.
* meta_compositor_switch_workspace() is called before any windows
are hidden or shown, allowing the compositor to avoid hiding
or showing an effect for windows involved in the switch.
http://bugzilla.gnome.org/show_bug.cgi?id=582341
* Handling of post-effect cleanups for MutterWindow are
simplified - instead of trying to do different things based
on the individual needs of different effects, we just wait until
all effects complete and sync the window state to what it
should be.
* On unmap, once we destroy the pixmap, we tell ClutterX11Pixmap
that we've done so, so it can clean up and unbind. (The
unbinding doesn't seem to be working properly because of
ClutterGLXPixmap or video driver issues.)
http://bugzilla.gnome.org/show_bug.cgi?id=587251
2009-06-28 21:10:40 +00:00
|
|
|
clutter_actor_hide (CLUTTER_ACTOR (self));
|
2009-06-26 19:33:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2015-07-06 04:08:08 +00:00
|
|
|
meta_window_actor_size_change (MetaWindowActor *self,
|
|
|
|
MetaSizeChange which_change,
|
|
|
|
MetaRectangle *old_frame_rect,
|
|
|
|
MetaRectangle *old_buffer_rect)
|
2009-06-26 19:33:20 +00:00
|
|
|
{
|
2018-12-21 20:12:49 +00:00
|
|
|
MetaWindowActorPrivate *priv =
|
|
|
|
meta_window_actor_get_instance_private (self);
|
|
|
|
MetaCompositor *compositor = priv->compositor;
|
2019-08-14 17:04:41 +00:00
|
|
|
MetaPluginManager *plugin_mgr =
|
|
|
|
meta_compositor_get_plugin_manager (compositor);
|
2009-06-26 19:33:20 +00:00
|
|
|
|
2018-12-21 20:12:49 +00:00
|
|
|
priv->size_change_in_progress++;
|
2009-06-26 19:33:20 +00:00
|
|
|
|
2019-08-14 17:04:41 +00:00
|
|
|
if (!meta_plugin_manager_event_size_change (plugin_mgr, self,
|
2015-07-06 04:08:08 +00:00
|
|
|
which_change, old_frame_rect, old_buffer_rect))
|
2020-05-12 10:08:41 +00:00
|
|
|
priv->size_change_in_progress--;
|
2009-06-26 19:33:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2010-10-18 17:27:14 +00:00
|
|
|
meta_window_actor_sync_visibility (MetaWindowActor *self)
|
2009-06-26 19:33:20 +00:00
|
|
|
{
|
2018-12-21 20:12:49 +00:00
|
|
|
MetaWindowActorPrivate *priv =
|
|
|
|
meta_window_actor_get_instance_private (self);
|
|
|
|
|
|
|
|
if (CLUTTER_ACTOR_IS_VISIBLE (self) != priv->visible)
|
2009-06-26 19:33:20 +00:00
|
|
|
{
|
2018-12-21 20:12:49 +00:00
|
|
|
if (priv->visible)
|
Simplify relationship between mapping and visibility
Previously, changes to the visibility of a window could be indicated
by meta_compositor_map_window(), meta_compositor_unminimize_window(),
meta_compositor_set_window_hidden(), etc, with the exact behavior
depending on the 'live_hidden_windows' preference.
Simplify this so that visibility is controlled by:
meta_compositor_show_window()
meta_compositor_hide_window()
With an 'effect' parameter provided to indicate the appropriate
effect (CREATE/UNMINIMIZE/MINIMIZE/DESTROY/NONE.)
The map state of the window is signalled separately by:
meta_compositor_map_window()
meta_compositor_unmap_window()
And is used only to control resource handling.
Other changes:
* The desired effect on show/hide is explicitly stored in
MetaWindow, avoiding the need for the was_minimized flag.
At idle, once we calculate the window state, we pass the
effect to the compositor if it matches the new window
state, and then clear the effect to start over for future
map state changes.
* meta_compositor_switch_workspace() is called before any windows
are hidden or shown, allowing the compositor to avoid hiding
or showing an effect for windows involved in the switch.
http://bugzilla.gnome.org/show_bug.cgi?id=582341
* Handling of post-effect cleanups for MutterWindow are
simplified - instead of trying to do different things based
on the individual needs of different effects, we just wait until
all effects complete and sync the window state to what it
should be.
* On unmap, once we destroy the pixmap, we tell ClutterX11Pixmap
that we've done so, so it can clean up and unbind. (The
unbinding doesn't seem to be working properly because of
ClutterGLXPixmap or video driver issues.)
http://bugzilla.gnome.org/show_bug.cgi?id=587251
2009-06-28 21:10:40 +00:00
|
|
|
clutter_actor_show (CLUTTER_ACTOR (self));
|
|
|
|
else
|
|
|
|
clutter_actor_hide (CLUTTER_ACTOR (self));
|
2009-06-26 19:33:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-11-12 19:11:08 +00:00
|
|
|
void
|
clutter: Paint views with individual frame clocks
Replace the default master clock with multiple frame clocks, each
driving its own stage view. As each stage view represents one CRTC, this
means we draw each CRTC with its own designated frame clock,
disconnected from all the others.
For example this means we when using the native backend will never need
to wait for one monitor to vsync before painting another, so e.g. having
a 144 Hz monitor next to a 60 Hz monitor, things including both Wayland
and X11 applications and shell UI will be able to render at the
corresponding monitor refresh rate.
This also changes a warning about missed frames when sending
_NETWM_FRAME_TIMINGS messages to a debug log entry, as it's expected
that we'll start missing frames e.g. when a X11 window (via Xwayland) is
exclusively within a stage view that was not painted, while another one
was, still increasing the global frame clock.
Addititonally, this also requires the X11 window actor to schedule
timeouts for _NET_WM_FRAME_DRAWN/_NET_WM_FRAME_TIMINGS event emitting,
if the actor wasn't on any stage views, as now we'll only get the frame
callbacks on actors when they actually were painted, while in the past,
we'd invoke that vfunc when anything was painted.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/903
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/3
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1285
2020-05-29 22:27:56 +00:00
|
|
|
meta_window_actor_before_paint (MetaWindowActor *self,
|
|
|
|
ClutterStageView *stage_view)
|
2012-11-12 19:11:08 +00:00
|
|
|
{
|
2014-09-10 21:55:22 +00:00
|
|
|
if (meta_window_actor_is_destroyed (self))
|
|
|
|
return;
|
|
|
|
|
clutter: Paint views with individual frame clocks
Replace the default master clock with multiple frame clocks, each
driving its own stage view. As each stage view represents one CRTC, this
means we draw each CRTC with its own designated frame clock,
disconnected from all the others.
For example this means we when using the native backend will never need
to wait for one monitor to vsync before painting another, so e.g. having
a 144 Hz monitor next to a 60 Hz monitor, things including both Wayland
and X11 applications and shell UI will be able to render at the
corresponding monitor refresh rate.
This also changes a warning about missed frames when sending
_NETWM_FRAME_TIMINGS messages to a debug log entry, as it's expected
that we'll start missing frames e.g. when a X11 window (via Xwayland) is
exclusively within a stage view that was not painted, while another one
was, still increasing the global frame clock.
Addititonally, this also requires the X11 window actor to schedule
timeouts for _NET_WM_FRAME_DRAWN/_NET_WM_FRAME_TIMINGS event emitting,
if the actor wasn't on any stage views, as now we'll only get the frame
callbacks on actors when they actually were painted, while in the past,
we'd invoke that vfunc when anything was painted.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/903
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/3
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1285
2020-05-29 22:27:56 +00:00
|
|
|
META_WINDOW_ACTOR_GET_CLASS (self)->before_paint (self, stage_view);
|
2013-08-17 17:11:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
clutter: Paint views with individual frame clocks
Replace the default master clock with multiple frame clocks, each
driving its own stage view. As each stage view represents one CRTC, this
means we draw each CRTC with its own designated frame clock,
disconnected from all the others.
For example this means we when using the native backend will never need
to wait for one monitor to vsync before painting another, so e.g. having
a 144 Hz monitor next to a 60 Hz monitor, things including both Wayland
and X11 applications and shell UI will be able to render at the
corresponding monitor refresh rate.
This also changes a warning about missed frames when sending
_NETWM_FRAME_TIMINGS messages to a debug log entry, as it's expected
that we'll start missing frames e.g. when a X11 window (via Xwayland) is
exclusively within a stage view that was not painted, while another one
was, still increasing the global frame clock.
Addititonally, this also requires the X11 window actor to schedule
timeouts for _NET_WM_FRAME_DRAWN/_NET_WM_FRAME_TIMINGS event emitting,
if the actor wasn't on any stage views, as now we'll only get the frame
callbacks on actors when they actually were painted, while in the past,
we'd invoke that vfunc when anything was painted.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/903
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/3
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1285
2020-05-29 22:27:56 +00:00
|
|
|
meta_window_actor_after_paint (MetaWindowActor *self,
|
|
|
|
ClutterStageView *stage_view)
|
2013-08-17 17:11:12 +00:00
|
|
|
{
|
2018-12-21 20:12:49 +00:00
|
|
|
MetaWindowActorPrivate *priv =
|
|
|
|
meta_window_actor_get_instance_private (self);
|
|
|
|
|
clutter: Paint views with individual frame clocks
Replace the default master clock with multiple frame clocks, each
driving its own stage view. As each stage view represents one CRTC, this
means we draw each CRTC with its own designated frame clock,
disconnected from all the others.
For example this means we when using the native backend will never need
to wait for one monitor to vsync before painting another, so e.g. having
a 144 Hz monitor next to a 60 Hz monitor, things including both Wayland
and X11 applications and shell UI will be able to render at the
corresponding monitor refresh rate.
This also changes a warning about missed frames when sending
_NETWM_FRAME_TIMINGS messages to a debug log entry, as it's expected
that we'll start missing frames e.g. when a X11 window (via Xwayland) is
exclusively within a stage view that was not painted, while another one
was, still increasing the global frame clock.
Addititonally, this also requires the X11 window actor to schedule
timeouts for _NET_WM_FRAME_DRAWN/_NET_WM_FRAME_TIMINGS event emitting,
if the actor wasn't on any stage views, as now we'll only get the frame
callbacks on actors when they actually were painted, while in the past,
we'd invoke that vfunc when anything was painted.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/903
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/3
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1285
2020-05-29 22:27:56 +00:00
|
|
|
META_WINDOW_ACTOR_GET_CLASS (self)->after_paint (self, stage_view);
|
2011-06-13 22:09:59 +00:00
|
|
|
|
2014-09-10 21:55:22 +00:00
|
|
|
if (meta_window_actor_is_destroyed (self))
|
|
|
|
return;
|
|
|
|
|
2018-12-21 20:12:49 +00:00
|
|
|
if (priv->first_frame_state == DRAWING_FIRST_FRAME)
|
2014-05-21 13:57:15 +00:00
|
|
|
{
|
2018-12-21 20:12:49 +00:00
|
|
|
priv->first_frame_state = EMITTED_FIRST_FRAME;
|
2014-05-21 13:57:15 +00:00
|
|
|
g_signal_emit (self, signals[FIRST_FRAME], 0);
|
|
|
|
}
|
2012-11-12 19:11:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2016-06-08 05:07:09 +00:00
|
|
|
meta_window_actor_frame_complete (MetaWindowActor *self,
|
|
|
|
ClutterFrameInfo *frame_info,
|
|
|
|
gint64 presentation_time)
|
2012-11-12 19:11:08 +00:00
|
|
|
{
|
2018-12-21 20:51:02 +00:00
|
|
|
META_WINDOW_ACTOR_GET_CLASS (self)->frame_complete (self,
|
|
|
|
frame_info,
|
|
|
|
presentation_time);
|
2009-06-26 19:33:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2010-10-18 17:27:14 +00:00
|
|
|
meta_window_actor_update_opacity (MetaWindowActor *self)
|
2009-06-26 19:33:20 +00:00
|
|
|
{
|
2018-12-21 20:12:49 +00:00
|
|
|
MetaWindowActorPrivate *priv =
|
|
|
|
meta_window_actor_get_instance_private (self);
|
|
|
|
MetaWindow *window = priv->window;
|
2009-06-26 19:33:20 +00:00
|
|
|
|
2018-12-21 20:12:49 +00:00
|
|
|
if (priv->surface)
|
|
|
|
clutter_actor_set_opacity (CLUTTER_ACTOR (priv->surface), window->opacity);
|
2009-06-26 19:33:20 +00:00
|
|
|
}
|
2011-06-13 21:53:23 +00:00
|
|
|
|
2014-06-17 17:06:10 +00:00
|
|
|
static void
|
2011-06-13 21:53:23 +00:00
|
|
|
meta_window_actor_set_updates_frozen (MetaWindowActor *self,
|
|
|
|
gboolean updates_frozen)
|
|
|
|
{
|
2018-12-21 20:12:49 +00:00
|
|
|
MetaWindowActorPrivate *priv =
|
|
|
|
meta_window_actor_get_instance_private (self);
|
|
|
|
|
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-01 22:21:11 +00:00
|
|
|
updates_frozen = updates_frozen != FALSE;
|
2011-06-13 21:53:23 +00:00
|
|
|
|
2018-12-21 20:12:49 +00:00
|
|
|
if (priv->updates_frozen != updates_frozen)
|
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-01 22:21:11 +00:00
|
|
|
{
|
2018-12-21 20:12:49 +00:00
|
|
|
priv->updates_frozen = updates_frozen;
|
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-01 22:21:11 +00:00
|
|
|
if (updates_frozen)
|
|
|
|
meta_window_actor_freeze (self);
|
|
|
|
else
|
|
|
|
meta_window_actor_thaw (self);
|
2011-06-13 21:53:23 +00:00
|
|
|
}
|
|
|
|
}
|
2014-06-17 17:06:10 +00:00
|
|
|
|
|
|
|
void
|
|
|
|
meta_window_actor_sync_updates_frozen (MetaWindowActor *self)
|
|
|
|
{
|
2018-12-21 20:12:49 +00:00
|
|
|
MetaWindowActorPrivate *priv =
|
|
|
|
meta_window_actor_get_instance_private (self);
|
|
|
|
MetaWindow *window = priv->window;
|
2014-06-17 17:06:10 +00:00
|
|
|
|
|
|
|
meta_window_actor_set_updates_frozen (self, meta_window_updates_are_frozen (window));
|
|
|
|
}
|
2018-04-04 08:10:32 +00:00
|
|
|
|
|
|
|
MetaWindowActor *
|
|
|
|
meta_window_actor_from_window (MetaWindow *window)
|
|
|
|
{
|
|
|
|
return META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
|
|
|
|
}
|
2018-12-04 15:29:47 +00:00
|
|
|
|
2019-07-12 17:33:17 +00:00
|
|
|
void
|
|
|
|
meta_window_actor_set_geometry_scale (MetaWindowActor *window_actor,
|
|
|
|
int geometry_scale)
|
|
|
|
{
|
|
|
|
MetaWindowActorPrivate *priv =
|
|
|
|
meta_window_actor_get_instance_private (window_actor);
|
2020-09-11 18:57:28 +00:00
|
|
|
graphene_matrix_t child_transform;
|
2019-07-12 17:33:17 +00:00
|
|
|
|
|
|
|
if (priv->geometry_scale == geometry_scale)
|
|
|
|
return;
|
|
|
|
|
|
|
|
priv->geometry_scale = geometry_scale;
|
|
|
|
|
2020-09-11 22:12:54 +00:00
|
|
|
graphene_matrix_init_scale (&child_transform,
|
|
|
|
geometry_scale,
|
|
|
|
geometry_scale,
|
|
|
|
1);
|
2019-07-12 17:33:17 +00:00
|
|
|
clutter_actor_set_child_transform (CLUTTER_ACTOR (window_actor),
|
|
|
|
&child_transform);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
meta_window_actor_get_geometry_scale (MetaWindowActor *window_actor)
|
|
|
|
{
|
|
|
|
MetaWindowActorPrivate *priv =
|
|
|
|
meta_window_actor_get_instance_private (window_actor);
|
|
|
|
|
|
|
|
return priv->geometry_scale;
|
|
|
|
}
|
|
|
|
|
2018-12-04 15:29:47 +00:00
|
|
|
static void
|
2020-01-28 10:13:41 +00:00
|
|
|
meta_window_actor_get_buffer_bounds (MetaScreenCastWindow *screen_cast_window,
|
|
|
|
MetaRectangle *bounds)
|
2018-12-04 15:29:47 +00:00
|
|
|
{
|
|
|
|
MetaWindowActor *window_actor = META_WINDOW_ACTOR (screen_cast_window);
|
2018-12-21 20:12:49 +00:00
|
|
|
MetaWindowActorPrivate *priv =
|
|
|
|
meta_window_actor_get_instance_private (window_actor);
|
2018-12-04 15:29:47 +00:00
|
|
|
MetaShapedTexture *stex;
|
2018-12-26 15:41:26 +00:00
|
|
|
int buffer_scale;
|
2018-12-04 15:29:47 +00:00
|
|
|
|
2018-12-21 20:12:49 +00:00
|
|
|
stex = meta_surface_actor_get_texture (priv->surface);
|
2018-12-26 15:41:26 +00:00
|
|
|
buffer_scale = meta_shaped_texture_get_buffer_scale (stex);
|
2020-01-28 10:13:41 +00:00
|
|
|
*bounds = (MetaRectangle) {
|
|
|
|
.width = meta_shaped_texture_get_width (stex) * buffer_scale,
|
|
|
|
.height = meta_shaped_texture_get_height (stex) * buffer_scale,
|
|
|
|
};
|
2018-12-04 15:29:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
meta_window_actor_transform_relative_position (MetaScreenCastWindow *screen_cast_window,
|
|
|
|
double x,
|
|
|
|
double y,
|
|
|
|
double *x_out,
|
|
|
|
double *y_out)
|
|
|
|
|
|
|
|
{
|
|
|
|
MetaWindowActor *window_actor = META_WINDOW_ACTOR (screen_cast_window);
|
2018-12-21 20:12:49 +00:00
|
|
|
MetaWindowActorPrivate *priv =
|
|
|
|
meta_window_actor_get_instance_private (window_actor);
|
2018-12-04 15:29:47 +00:00
|
|
|
MetaRectangle bounds;
|
2019-02-20 13:18:48 +00:00
|
|
|
graphene_point3d_t v1 = { 0.f, }, v2 = { 0.f, };
|
2018-12-04 15:29:47 +00:00
|
|
|
|
2020-01-28 10:13:41 +00:00
|
|
|
meta_window_actor_get_buffer_bounds (screen_cast_window, &bounds);
|
2018-12-04 15:29:47 +00:00
|
|
|
|
|
|
|
v1.x = CLAMP ((float) x,
|
|
|
|
bounds.x,
|
|
|
|
bounds.x + bounds.width);
|
|
|
|
v1.y = CLAMP ((float) y,
|
|
|
|
bounds.y,
|
|
|
|
bounds.y + bounds.height);
|
|
|
|
|
2018-12-26 15:41:26 +00:00
|
|
|
clutter_actor_apply_transform_to_point (CLUTTER_ACTOR (priv->surface),
|
|
|
|
&v1,
|
|
|
|
&v2);
|
2018-12-04 15:29:47 +00:00
|
|
|
|
|
|
|
*x_out = (double) v2.x;
|
|
|
|
*y_out = (double) v2.y;
|
|
|
|
}
|
|
|
|
|
2019-01-23 18:09:17 +00:00
|
|
|
static gboolean
|
|
|
|
meta_window_actor_transform_cursor_position (MetaScreenCastWindow *screen_cast_window,
|
|
|
|
MetaCursorSprite *cursor_sprite,
|
2019-02-20 14:53:44 +00:00
|
|
|
graphene_point_t *cursor_position,
|
2019-01-23 18:09:17 +00:00
|
|
|
float *out_cursor_scale,
|
2022-07-02 16:50:45 +00:00
|
|
|
MetaMonitorTransform *out_cursor_transform,
|
2019-02-20 14:53:44 +00:00
|
|
|
graphene_point_t *out_relative_cursor_position)
|
2019-01-23 18:09:17 +00:00
|
|
|
{
|
|
|
|
MetaWindowActor *window_actor = META_WINDOW_ACTOR (screen_cast_window);
|
|
|
|
MetaWindowActorPrivate *priv =
|
|
|
|
meta_window_actor_get_instance_private (window_actor);
|
|
|
|
MetaWindow *window;
|
|
|
|
|
|
|
|
window = priv->window;
|
|
|
|
if (!meta_window_has_pointer (window))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if (cursor_sprite &&
|
|
|
|
meta_cursor_sprite_get_cogl_texture (cursor_sprite) &&
|
|
|
|
out_cursor_scale)
|
|
|
|
{
|
2022-05-27 20:17:13 +00:00
|
|
|
MetaDisplay *display = meta_compositor_get_display (priv->compositor);
|
|
|
|
MetaContext *context = meta_display_get_context (display);
|
|
|
|
MetaBackend *backend = meta_context_get_backend (context);
|
2022-12-03 13:36:26 +00:00
|
|
|
MetaLogicalMonitor *logical_monitor;
|
|
|
|
float view_scale;
|
2019-01-23 18:09:17 +00:00
|
|
|
float cursor_texture_scale;
|
|
|
|
|
2022-12-03 13:36:26 +00:00
|
|
|
logical_monitor = meta_window_get_main_logical_monitor (window);
|
|
|
|
|
2022-05-27 20:17:13 +00:00
|
|
|
if (meta_backend_is_stage_views_scaled (backend))
|
2022-12-03 13:36:26 +00:00
|
|
|
view_scale = meta_logical_monitor_get_scale (logical_monitor);
|
|
|
|
else
|
|
|
|
view_scale = 1.0;
|
|
|
|
|
2019-01-23 18:09:17 +00:00
|
|
|
cursor_texture_scale = meta_cursor_sprite_get_texture_scale (cursor_sprite);
|
|
|
|
|
2022-12-03 13:36:26 +00:00
|
|
|
*out_cursor_scale = view_scale * cursor_texture_scale;
|
2019-01-23 18:09:17 +00:00
|
|
|
}
|
|
|
|
|
2022-07-02 16:50:45 +00:00
|
|
|
if (cursor_sprite &&
|
|
|
|
meta_cursor_sprite_get_cogl_texture (cursor_sprite) &&
|
|
|
|
out_cursor_transform)
|
|
|
|
{
|
|
|
|
*out_cursor_transform =
|
|
|
|
meta_cursor_sprite_get_texture_transform (cursor_sprite);
|
|
|
|
}
|
|
|
|
|
2019-01-23 18:09:17 +00:00
|
|
|
if (out_relative_cursor_position)
|
|
|
|
{
|
2022-12-03 13:24:25 +00:00
|
|
|
float resource_scale;
|
|
|
|
|
2018-12-26 15:41:26 +00:00
|
|
|
clutter_actor_transform_stage_point (CLUTTER_ACTOR (priv->surface),
|
2019-01-23 18:09:17 +00:00
|
|
|
cursor_position->x,
|
|
|
|
cursor_position->y,
|
|
|
|
&out_relative_cursor_position->x,
|
|
|
|
&out_relative_cursor_position->y);
|
2022-12-03 13:24:25 +00:00
|
|
|
|
|
|
|
resource_scale =
|
|
|
|
clutter_actor_get_resource_scale (CLUTTER_ACTOR (window_actor));
|
|
|
|
out_relative_cursor_position->x *= resource_scale;
|
|
|
|
out_relative_cursor_position->y *= resource_scale;
|
2019-01-23 18:09:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2018-12-04 15:29:47 +00:00
|
|
|
static void
|
|
|
|
meta_window_actor_capture_into (MetaScreenCastWindow *screen_cast_window,
|
|
|
|
MetaRectangle *bounds,
|
|
|
|
uint8_t *data)
|
|
|
|
{
|
|
|
|
MetaWindowActor *window_actor = META_WINDOW_ACTOR (screen_cast_window);
|
|
|
|
cairo_surface_t *image;
|
|
|
|
uint8_t *cr_data;
|
|
|
|
int cr_stride;
|
2019-01-22 09:22:27 +00:00
|
|
|
int cr_width;
|
|
|
|
int cr_height;
|
2018-12-04 15:29:47 +00:00
|
|
|
int bpp = 4;
|
|
|
|
|
|
|
|
if (meta_window_actor_is_destroyed (window_actor))
|
|
|
|
return;
|
|
|
|
|
2019-08-26 13:31:06 +00:00
|
|
|
image = meta_window_actor_get_image (window_actor, bounds);
|
2018-12-04 15:29:47 +00:00
|
|
|
cr_data = cairo_image_surface_get_data (image);
|
2019-01-22 09:22:27 +00:00
|
|
|
cr_width = cairo_image_surface_get_width (image);
|
|
|
|
cr_height = cairo_image_surface_get_height (image);
|
2018-12-04 15:29:47 +00:00
|
|
|
cr_stride = cairo_image_surface_get_stride (image);
|
|
|
|
|
2020-02-04 13:58:30 +00:00
|
|
|
if (cr_width == bounds->width && cr_height == bounds->height)
|
2018-12-04 15:29:47 +00:00
|
|
|
{
|
2020-02-04 13:58:30 +00:00
|
|
|
memcpy (data, cr_data, cr_height * cr_stride);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int width = MIN (bounds->width, cr_width);
|
|
|
|
int height = MIN (bounds->height, cr_height);
|
|
|
|
int stride = width * bpp;
|
2018-12-04 15:29:47 +00:00
|
|
|
uint8_t *src, *dst;
|
2020-02-04 13:58:30 +00:00
|
|
|
|
2018-12-04 15:29:47 +00:00
|
|
|
src = cr_data;
|
|
|
|
dst = data;
|
|
|
|
|
2020-02-04 13:58:30 +00:00
|
|
|
for (int i = 0; i < height; i++)
|
2018-12-04 15:29:47 +00:00
|
|
|
{
|
2020-02-04 13:58:30 +00:00
|
|
|
memcpy (dst, src, stride);
|
|
|
|
if (width < bounds->width)
|
|
|
|
memset (dst + stride, 0, (bounds->width * bpp) - stride);
|
2018-12-04 15:29:47 +00:00
|
|
|
|
|
|
|
src += cr_stride;
|
|
|
|
dst += bounds->width * bpp;
|
|
|
|
}
|
|
|
|
|
2020-02-04 13:58:30 +00:00
|
|
|
for (int i = height; i < bounds->height; i++)
|
2018-12-04 15:29:47 +00:00
|
|
|
{
|
|
|
|
memset (dst, 0, bounds->width * bpp);
|
|
|
|
dst += bounds->width * bpp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
cairo_surface_destroy (image);
|
|
|
|
}
|
|
|
|
|
2020-02-28 15:23:15 +00:00
|
|
|
static gboolean
|
|
|
|
meta_window_actor_blit_to_framebuffer (MetaScreenCastWindow *screen_cast_window,
|
|
|
|
MetaRectangle *bounds,
|
|
|
|
CoglFramebuffer *framebuffer)
|
|
|
|
{
|
|
|
|
MetaWindowActor *window_actor = META_WINDOW_ACTOR (screen_cast_window);
|
|
|
|
ClutterActor *actor = CLUTTER_ACTOR (window_actor);
|
|
|
|
ClutterPaintContext *paint_context;
|
|
|
|
MetaRectangle scaled_clip;
|
|
|
|
CoglColor clear_color;
|
|
|
|
float resource_scale;
|
|
|
|
float width, height;
|
|
|
|
float x, y;
|
|
|
|
|
|
|
|
if (meta_window_actor_is_destroyed (window_actor))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
clutter_actor_get_size (actor, &width, &height);
|
|
|
|
|
|
|
|
if (width == 0 || height == 0)
|
|
|
|
return FALSE;
|
|
|
|
|
2020-04-10 09:41:58 +00:00
|
|
|
resource_scale = clutter_actor_get_resource_scale (actor);
|
2020-02-28 15:23:15 +00:00
|
|
|
|
2020-03-19 00:14:58 +00:00
|
|
|
clutter_actor_inhibit_culling (actor);
|
|
|
|
|
2020-02-28 15:23:15 +00:00
|
|
|
width = ceilf (width * resource_scale);
|
|
|
|
height = ceilf (height * resource_scale);
|
|
|
|
|
|
|
|
clutter_actor_get_position (actor, &x, &y);
|
|
|
|
|
2020-03-16 22:47:30 +00:00
|
|
|
cogl_color_init_from_4ub (&clear_color, 0, 0, 0, 0);
|
2020-02-28 15:23:15 +00:00
|
|
|
cogl_framebuffer_clear (framebuffer, COGL_BUFFER_BIT_COLOR, &clear_color);
|
|
|
|
cogl_framebuffer_orthographic (framebuffer, 0, 0, width, height, 0, 1.0);
|
2020-04-03 15:12:58 +00:00
|
|
|
cogl_framebuffer_set_viewport (framebuffer, 0, 0, width, height);
|
2020-02-28 15:23:15 +00:00
|
|
|
|
|
|
|
meta_rectangle_scale_double (bounds, resource_scale,
|
|
|
|
META_ROUNDING_STRATEGY_GROW,
|
|
|
|
&scaled_clip);
|
|
|
|
meta_rectangle_intersect (&scaled_clip,
|
|
|
|
&(MetaRectangle) {
|
|
|
|
.width = width,
|
|
|
|
.height = height,
|
|
|
|
},
|
|
|
|
&scaled_clip);
|
|
|
|
|
|
|
|
cogl_framebuffer_push_rectangle_clip (framebuffer,
|
|
|
|
scaled_clip.x, scaled_clip.y,
|
|
|
|
scaled_clip.x + scaled_clip.width,
|
|
|
|
scaled_clip.y + scaled_clip.height);
|
|
|
|
|
2020-03-16 22:55:16 +00:00
|
|
|
cogl_framebuffer_push_matrix (framebuffer);
|
|
|
|
cogl_framebuffer_scale (framebuffer, resource_scale, resource_scale, 1);
|
|
|
|
cogl_framebuffer_translate (framebuffer, -x, -y, 0);
|
|
|
|
|
2020-04-20 19:10:23 +00:00
|
|
|
paint_context =
|
2020-04-20 19:13:38 +00:00
|
|
|
clutter_paint_context_new_for_framebuffer (framebuffer, NULL,
|
2020-04-20 19:10:23 +00:00
|
|
|
CLUTTER_PAINT_FLAG_NONE);
|
2020-02-28 15:23:15 +00:00
|
|
|
clutter_actor_paint (actor, paint_context);
|
|
|
|
clutter_paint_context_destroy (paint_context);
|
|
|
|
|
|
|
|
cogl_framebuffer_pop_matrix (framebuffer);
|
2020-03-16 22:55:16 +00:00
|
|
|
cogl_framebuffer_pop_clip (framebuffer);
|
2020-02-28 15:23:15 +00:00
|
|
|
|
2020-03-19 00:14:58 +00:00
|
|
|
clutter_actor_uninhibit_culling (actor);
|
|
|
|
|
2020-02-28 15:23:15 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2019-01-23 18:10:58 +00:00
|
|
|
static gboolean
|
|
|
|
meta_window_actor_has_damage (MetaScreenCastWindow *screen_cast_window)
|
|
|
|
{
|
|
|
|
return clutter_actor_has_damage (CLUTTER_ACTOR (screen_cast_window));
|
|
|
|
}
|
|
|
|
|
2023-02-11 06:03:27 +00:00
|
|
|
static void
|
|
|
|
meta_window_actor_inc_screen_cast_usage (MetaScreenCastWindow *screen_cast_window)
|
|
|
|
{
|
|
|
|
MetaWindowActor *window_actor = META_WINDOW_ACTOR (screen_cast_window);
|
|
|
|
MetaWindowActorPrivate *priv =
|
|
|
|
meta_window_actor_get_instance_private (window_actor);
|
|
|
|
|
|
|
|
priv->screen_cast_usage_count++;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
meta_window_actor_dec_screen_cast_usage (MetaScreenCastWindow *screen_cast_window)
|
|
|
|
{
|
|
|
|
MetaWindowActor *window_actor = META_WINDOW_ACTOR (screen_cast_window);
|
|
|
|
MetaWindowActorPrivate *priv =
|
|
|
|
meta_window_actor_get_instance_private (window_actor);
|
|
|
|
|
|
|
|
priv->screen_cast_usage_count--;
|
|
|
|
}
|
|
|
|
|
2018-12-04 15:29:47 +00:00
|
|
|
static void
|
|
|
|
screen_cast_window_iface_init (MetaScreenCastWindowInterface *iface)
|
|
|
|
{
|
2020-01-28 10:13:41 +00:00
|
|
|
iface->get_buffer_bounds = meta_window_actor_get_buffer_bounds;
|
2018-12-04 15:29:47 +00:00
|
|
|
iface->transform_relative_position = meta_window_actor_transform_relative_position;
|
2019-01-23 18:09:17 +00:00
|
|
|
iface->transform_cursor_position = meta_window_actor_transform_cursor_position;
|
2018-12-04 15:29:47 +00:00
|
|
|
iface->capture_into = meta_window_actor_capture_into;
|
2020-02-28 15:23:15 +00:00
|
|
|
iface->blit_to_framebuffer = meta_window_actor_blit_to_framebuffer;
|
2019-01-23 18:10:58 +00:00
|
|
|
iface->has_damage = meta_window_actor_has_damage;
|
2023-02-11 06:03:27 +00:00
|
|
|
iface->inc_usage = meta_window_actor_inc_screen_cast_usage;
|
|
|
|
iface->dec_usage = meta_window_actor_dec_screen_cast_usage;
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
meta_window_actor_is_streaming (MetaWindowActor *window_actor)
|
|
|
|
{
|
|
|
|
MetaWindowActorPrivate *priv =
|
|
|
|
meta_window_actor_get_instance_private (window_actor);
|
|
|
|
|
|
|
|
return priv->screen_cast_usage_count > 0;
|
2018-12-04 15:29:47 +00:00
|
|
|
}
|
2019-06-13 18:16:37 +00:00
|
|
|
|
|
|
|
MetaWindowActor *
|
|
|
|
meta_window_actor_from_actor (ClutterActor *actor)
|
|
|
|
{
|
|
|
|
if (!META_IS_SURFACE_ACTOR (actor))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
actor = clutter_actor_get_parent (actor);
|
|
|
|
|
|
|
|
if (META_IS_WINDOW_ACTOR (actor))
|
|
|
|
return META_WINDOW_ACTOR (actor);
|
|
|
|
}
|
|
|
|
while (actor != NULL);
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
2019-08-26 13:09:53 +00:00
|
|
|
|
|
|
|
void
|
|
|
|
meta_window_actor_notify_damaged (MetaWindowActor *window_actor)
|
|
|
|
{
|
|
|
|
g_signal_emit (window_actor, signals[DAMAGED], 0);
|
|
|
|
}
|
2019-08-26 13:29:33 +00:00
|
|
|
|
2021-06-06 12:28:48 +00:00
|
|
|
static CoglFramebuffer *
|
|
|
|
create_framebuffer_from_window_actor (MetaWindowActor *self,
|
|
|
|
MetaRectangle *clip,
|
|
|
|
GError **error)
|
|
|
|
{
|
2022-05-27 20:17:13 +00:00
|
|
|
MetaWindowActorPrivate *priv = meta_window_actor_get_instance_private (self);
|
2021-06-06 12:28:48 +00:00
|
|
|
ClutterActor *actor = CLUTTER_ACTOR (self);
|
2022-05-27 20:17:13 +00:00
|
|
|
MetaDisplay *display = meta_compositor_get_display (priv->compositor);
|
|
|
|
MetaContext *context = meta_display_get_context (display);
|
|
|
|
MetaBackend *backend = meta_context_get_backend (context);
|
2021-06-06 12:28:48 +00:00
|
|
|
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
|
|
|
CoglContext *cogl_context =
|
|
|
|
clutter_backend_get_cogl_context (clutter_backend);
|
|
|
|
CoglTexture2D *texture;
|
|
|
|
CoglOffscreen *offscreen;
|
|
|
|
CoglFramebuffer *framebuffer;
|
|
|
|
CoglColor clear_color;
|
|
|
|
ClutterPaintContext *paint_context;
|
|
|
|
float resource_scale;
|
|
|
|
|
|
|
|
resource_scale = clutter_actor_get_resource_scale (actor);
|
|
|
|
|
|
|
|
texture = cogl_texture_2d_new_with_size (cogl_context,
|
|
|
|
clip->width * resource_scale,
|
|
|
|
clip->height * resource_scale);
|
|
|
|
if (!texture)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
cogl_primitive_texture_set_auto_mipmap (COGL_PRIMITIVE_TEXTURE (texture),
|
|
|
|
FALSE);
|
|
|
|
|
|
|
|
offscreen = cogl_offscreen_new_with_texture (COGL_TEXTURE (texture));
|
|
|
|
framebuffer = COGL_FRAMEBUFFER (offscreen);
|
|
|
|
|
|
|
|
cogl_object_unref (texture);
|
|
|
|
|
|
|
|
if (!cogl_framebuffer_allocate (framebuffer, error))
|
|
|
|
{
|
|
|
|
g_object_unref (framebuffer);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
cogl_color_init_from_4ub (&clear_color, 0, 0, 0, 0);
|
|
|
|
cogl_framebuffer_clear (framebuffer, COGL_BUFFER_BIT_COLOR, &clear_color);
|
|
|
|
cogl_framebuffer_orthographic (framebuffer, 0, 0, clip->width, clip->height,
|
|
|
|
0, 1.0);
|
|
|
|
cogl_framebuffer_translate (framebuffer, -clip->x, -clip->y, 0);
|
|
|
|
|
|
|
|
paint_context =
|
|
|
|
clutter_paint_context_new_for_framebuffer (framebuffer, NULL,
|
|
|
|
CLUTTER_PAINT_FLAG_NONE);
|
|
|
|
clutter_actor_paint (actor, paint_context);
|
|
|
|
clutter_paint_context_destroy (paint_context);
|
|
|
|
|
|
|
|
return framebuffer;
|
|
|
|
}
|
|
|
|
|
2022-03-15 11:21:17 +00:00
|
|
|
static gboolean
|
|
|
|
meta_window_actor_is_single_surface_actor (MetaWindowActor *self)
|
|
|
|
{
|
|
|
|
return META_WINDOW_ACTOR_GET_CLASS (self)->is_single_surface_actor (self);
|
|
|
|
}
|
|
|
|
|
2019-09-13 04:01:54 +00:00
|
|
|
/**
|
|
|
|
* meta_window_actor_get_image:
|
|
|
|
* @self: A #MetaWindowActor
|
|
|
|
* @clip: (nullable): A clipping rectangle, to help prevent extra processing.
|
|
|
|
* In the case that the clipping rectangle is partially or fully
|
|
|
|
* outside the bounds of the actor, the rectangle will be clipped.
|
|
|
|
*
|
|
|
|
* Flattens the layers of @self into one ARGB32 image by alpha blending
|
|
|
|
* the images, and returns the flattened image.
|
|
|
|
*
|
|
|
|
* Returns: (nullable) (transfer full): a new cairo surface to be freed with
|
|
|
|
* cairo_surface_destroy().
|
|
|
|
*/
|
2019-08-26 13:29:33 +00:00
|
|
|
cairo_surface_t *
|
|
|
|
meta_window_actor_get_image (MetaWindowActor *self,
|
|
|
|
MetaRectangle *clip)
|
|
|
|
{
|
|
|
|
MetaWindowActorPrivate *priv = meta_window_actor_get_instance_private (self);
|
|
|
|
ClutterActor *actor = CLUTTER_ACTOR (self);
|
2021-08-22 11:46:52 +00:00
|
|
|
MetaShapedTexture *stex;
|
2020-03-19 00:14:58 +00:00
|
|
|
cairo_surface_t *surface = NULL;
|
2021-06-06 12:28:48 +00:00
|
|
|
CoglFramebuffer *framebuffer;
|
|
|
|
MetaRectangle framebuffer_clip;
|
|
|
|
float resource_scale;
|
|
|
|
float x, y, width, height;
|
2019-08-26 13:29:33 +00:00
|
|
|
|
|
|
|
if (!priv->surface)
|
|
|
|
return NULL;
|
|
|
|
|
2020-03-19 00:14:58 +00:00
|
|
|
clutter_actor_inhibit_culling (actor);
|
|
|
|
|
2021-08-22 11:46:52 +00:00
|
|
|
stex = meta_surface_actor_get_texture (priv->surface);
|
|
|
|
if (!meta_shaped_texture_should_get_via_offscreen (stex) &&
|
2022-03-15 11:21:17 +00:00
|
|
|
meta_window_actor_is_single_surface_actor (self))
|
2019-08-26 13:29:33 +00:00
|
|
|
{
|
2019-10-14 15:45:14 +00:00
|
|
|
MetaRectangle *surface_clip = NULL;
|
2019-09-14 17:21:41 +00:00
|
|
|
|
2019-10-14 15:45:14 +00:00
|
|
|
if (clip)
|
|
|
|
{
|
|
|
|
int geometry_scale;
|
2019-09-14 17:21:41 +00:00
|
|
|
|
2019-10-14 15:45:14 +00:00
|
|
|
geometry_scale =
|
|
|
|
meta_window_actor_get_geometry_scale (self);
|
|
|
|
|
|
|
|
surface_clip = g_alloca (sizeof (MetaRectangle));
|
|
|
|
surface_clip->x = clip->x / geometry_scale,
|
|
|
|
surface_clip->y = clip->y / geometry_scale;
|
|
|
|
surface_clip->width = clip->width / geometry_scale;
|
|
|
|
surface_clip->height = clip->height / geometry_scale;
|
|
|
|
}
|
2019-08-26 13:29:33 +00:00
|
|
|
|
2020-03-19 00:14:58 +00:00
|
|
|
surface = meta_shaped_texture_get_image (stex, surface_clip);
|
|
|
|
goto out;
|
2019-08-26 13:29:33 +00:00
|
|
|
}
|
|
|
|
|
2021-06-06 12:28:48 +00:00
|
|
|
clutter_actor_get_position (actor, &x, &y);
|
2019-08-26 13:29:33 +00:00
|
|
|
clutter_actor_get_size (actor, &width, &height);
|
|
|
|
|
|
|
|
if (width == 0 || height == 0)
|
2020-03-19 00:14:58 +00:00
|
|
|
goto out;
|
2019-08-26 13:29:33 +00:00
|
|
|
|
2021-06-06 12:28:48 +00:00
|
|
|
framebuffer_clip = (MetaRectangle) {
|
|
|
|
.x = floorf (x),
|
|
|
|
.y = floorf (y),
|
|
|
|
.width = ceilf (width),
|
|
|
|
.height = ceilf (height),
|
|
|
|
};
|
2019-08-26 13:29:33 +00:00
|
|
|
|
|
|
|
if (clip)
|
|
|
|
{
|
2021-06-06 12:28:48 +00:00
|
|
|
MetaRectangle tmp_clip;
|
|
|
|
MetaRectangle intersected_clip;
|
|
|
|
|
|
|
|
tmp_clip = *clip;
|
|
|
|
tmp_clip.x += floorf (x);
|
|
|
|
tmp_clip.y += floorf (y);
|
|
|
|
if (!meta_rectangle_intersect (&framebuffer_clip,
|
|
|
|
&tmp_clip,
|
|
|
|
&intersected_clip))
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
framebuffer_clip = intersected_clip;
|
2019-08-26 13:29:33 +00:00
|
|
|
}
|
|
|
|
|
2021-06-06 12:28:48 +00:00
|
|
|
framebuffer = create_framebuffer_from_window_actor (self,
|
|
|
|
&framebuffer_clip,
|
|
|
|
NULL);
|
|
|
|
if (!framebuffer)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
resource_scale = clutter_actor_get_resource_scale (actor);
|
2019-08-26 13:29:33 +00:00
|
|
|
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
2021-06-06 12:28:48 +00:00
|
|
|
framebuffer_clip.width *
|
|
|
|
resource_scale,
|
|
|
|
framebuffer_clip.height *
|
|
|
|
resource_scale);
|
2019-08-26 13:29:33 +00:00
|
|
|
cogl_framebuffer_read_pixels (framebuffer,
|
2021-06-06 12:28:48 +00:00
|
|
|
0, 0,
|
|
|
|
framebuffer_clip.width * resource_scale,
|
|
|
|
framebuffer_clip.height * resource_scale,
|
2019-08-26 13:29:33 +00:00
|
|
|
CLUTTER_CAIRO_FORMAT_ARGB32,
|
|
|
|
cairo_image_surface_get_data (surface));
|
|
|
|
|
2020-10-13 09:35:47 +00:00
|
|
|
g_object_unref (framebuffer);
|
2019-08-26 13:29:33 +00:00
|
|
|
|
|
|
|
cairo_surface_mark_dirty (surface);
|
|
|
|
|
2020-03-19 00:14:58 +00:00
|
|
|
out:
|
|
|
|
clutter_actor_uninhibit_culling (actor);
|
2019-08-26 13:29:33 +00:00
|
|
|
return surface;
|
|
|
|
}
|
2021-08-22 11:21:56 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* meta_window_actor_paint_to_content:
|
|
|
|
* @self: A #MetaWindowActor
|
|
|
|
* @clip: (nullable): A clipping rectangle, in actor coordinates, to help
|
|
|
|
* prevent extra processing.
|
|
|
|
* In the case that the clipping rectangle is partially or fully
|
|
|
|
* outside the bounds of the actor, the rectangle will be clipped.
|
|
|
|
* @error: A #GError to catch exceptional errors or %NULL.
|
|
|
|
*
|
|
|
|
* Returns: (nullable) (transfer full): a new #ClutterContent
|
|
|
|
*/
|
|
|
|
ClutterContent *
|
|
|
|
meta_window_actor_paint_to_content (MetaWindowActor *self,
|
|
|
|
MetaRectangle *clip,
|
|
|
|
GError **error)
|
|
|
|
{
|
|
|
|
MetaWindowActorPrivate *priv = meta_window_actor_get_instance_private (self);
|
|
|
|
ClutterActor *actor = CLUTTER_ACTOR (self);
|
|
|
|
ClutterContent *content = NULL;
|
|
|
|
CoglFramebuffer *framebuffer;
|
|
|
|
CoglTexture *texture;
|
|
|
|
MetaRectangle framebuffer_clip;
|
|
|
|
float x, y, width, height;
|
|
|
|
|
|
|
|
if (!priv->surface)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
clutter_actor_inhibit_culling (actor);
|
|
|
|
|
|
|
|
clutter_actor_get_position (actor, &x, &y);
|
|
|
|
clutter_actor_get_size (actor, &width, &height);
|
|
|
|
|
|
|
|
if (width == 0 || height == 0)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
framebuffer_clip = (MetaRectangle) {
|
|
|
|
.x = floorf (x),
|
|
|
|
.y = floorf (y),
|
|
|
|
.width = ceilf (width),
|
|
|
|
.height = ceilf (height),
|
|
|
|
};
|
|
|
|
|
|
|
|
if (clip)
|
|
|
|
{
|
|
|
|
MetaRectangle tmp_clip;
|
|
|
|
|
|
|
|
if (!meta_rectangle_intersect (&framebuffer_clip, clip, &tmp_clip))
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
framebuffer_clip = tmp_clip;
|
|
|
|
}
|
|
|
|
|
|
|
|
framebuffer = create_framebuffer_from_window_actor (self,
|
|
|
|
&framebuffer_clip,
|
|
|
|
error);
|
|
|
|
if (!framebuffer)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
texture = cogl_offscreen_get_texture (COGL_OFFSCREEN (framebuffer));
|
|
|
|
content = clutter_texture_content_new_from_texture (texture, NULL);
|
|
|
|
|
|
|
|
g_object_unref (framebuffer);
|
|
|
|
|
|
|
|
out:
|
|
|
|
clutter_actor_uninhibit_culling (actor);
|
|
|
|
return content;
|
|
|
|
}
|