wayland: GObject:ify surface roles
Make a surface roles into objects with vfuncs for things where there before was a big switch statement. The declaration and definition boilerplate is hidden behind C macros. https://bugzilla.gnome.org/show_bug.cgi?id=744932
This commit is contained in:
parent
8e5fb03611
commit
83c17134f1
6 changed files with 474 additions and 125 deletions
|
@ -538,7 +538,7 @@ data_device_start_drag (struct wl_client *client,
|
|||
|
||||
if (icon_resource &&
|
||||
!meta_wayland_surface_assign_role (icon_surface,
|
||||
META_WAYLAND_SURFACE_ROLE_DND))
|
||||
META_TYPE_WAYLAND_SURFACE_ROLE_DND))
|
||||
{
|
||||
wl_resource_post_error (resource, WL_DATA_DEVICE_ERROR_ROLE,
|
||||
"wl_surface@%d already has a different role",
|
||||
|
|
|
@ -774,16 +774,14 @@ pointer_set_cursor (struct wl_client *client,
|
|||
if (pointer->focus_serial - serial > G_MAXUINT32 / 2)
|
||||
return;
|
||||
|
||||
if (surface)
|
||||
if (surface &&
|
||||
!meta_wayland_surface_assign_role (surface,
|
||||
META_TYPE_WAYLAND_SURFACE_ROLE_CURSOR))
|
||||
{
|
||||
if (!meta_wayland_surface_assign_role (surface,
|
||||
META_WAYLAND_SURFACE_ROLE_CURSOR))
|
||||
{
|
||||
wl_resource_post_error (resource, WL_POINTER_ERROR_ROLE,
|
||||
"wl_surface@%d already has a different role",
|
||||
wl_resource_get_id (surface_resource));
|
||||
return;
|
||||
}
|
||||
wl_resource_post_error (resource, WL_POINTER_ERROR_ROLE,
|
||||
"wl_surface@%d already has a different role",
|
||||
wl_resource_get_id (surface_resource));
|
||||
return;
|
||||
}
|
||||
|
||||
pointer->hotspot_x = x;
|
||||
|
|
|
@ -55,6 +55,11 @@
|
|||
#include "meta-surface-actor-wayland.h"
|
||||
#include "meta-xwayland-private.h"
|
||||
|
||||
typedef struct _MetaWaylandSurfaceRolePrivate
|
||||
{
|
||||
MetaWaylandSurface *surface;
|
||||
} MetaWaylandSurfaceRolePrivate;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
META_WAYLAND_SUBSURFACE_PLACEMENT_ABOVE,
|
||||
|
@ -72,47 +77,107 @@ GType meta_wayland_surface_get_type (void) G_GNUC_CONST;
|
|||
|
||||
G_DEFINE_TYPE (MetaWaylandSurface, meta_wayland_surface, G_TYPE_OBJECT);
|
||||
|
||||
gboolean
|
||||
meta_wayland_surface_assign_role (MetaWaylandSurface *surface,
|
||||
MetaWaylandSurfaceRole role)
|
||||
GType meta_wayland_surface_role_get_type (void) G_GNUC_CONST;
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaWaylandSurfaceRole,
|
||||
meta_wayland_surface_role,
|
||||
G_TYPE_OBJECT);
|
||||
|
||||
struct _MetaWaylandSurfaceRoleSubsurface
|
||||
{
|
||||
MetaSurfaceActorWayland *surface_actor;
|
||||
MetaWaylandSurfaceRole parent;
|
||||
};
|
||||
|
||||
if (surface->role == META_WAYLAND_SURFACE_ROLE_NONE ||
|
||||
surface->role == role)
|
||||
GType meta_wayland_surface_role_subsurface_get_type (void) G_GNUC_CONST;
|
||||
G_DEFINE_TYPE (MetaWaylandSurfaceRoleSubsurface,
|
||||
meta_wayland_surface_role_subsurface,
|
||||
META_TYPE_WAYLAND_SURFACE_ROLE);
|
||||
|
||||
struct _MetaWaylandSurfaceRoleXdgSurface
|
||||
{
|
||||
MetaWaylandSurfaceRole parent;
|
||||
};
|
||||
|
||||
GType meta_wayland_surface_role_xdg_surface_get_type (void) G_GNUC_CONST;
|
||||
G_DEFINE_TYPE (MetaWaylandSurfaceRoleXdgSurface,
|
||||
meta_wayland_surface_role_xdg_surface,
|
||||
META_TYPE_WAYLAND_SURFACE_ROLE);
|
||||
|
||||
struct _MetaWaylandSurfaceRoleXdgPopup
|
||||
{
|
||||
MetaWaylandSurfaceRole parent;
|
||||
};
|
||||
|
||||
GType meta_wayland_surface_role_xdg_popup_get_type (void) G_GNUC_CONST;
|
||||
G_DEFINE_TYPE (MetaWaylandSurfaceRoleXdgPopup,
|
||||
meta_wayland_surface_role_xdg_popup,
|
||||
META_TYPE_WAYLAND_SURFACE_ROLE);
|
||||
|
||||
struct _MetaWaylandSurfaceRoleWlShellSurface
|
||||
{
|
||||
MetaWaylandSurfaceRole parent;
|
||||
};
|
||||
|
||||
GType meta_wayland_surface_role_wl_shell_surface_get_type (void) G_GNUC_CONST;
|
||||
G_DEFINE_TYPE (MetaWaylandSurfaceRoleWlShellSurface,
|
||||
meta_wayland_surface_role_wl_shell_surface,
|
||||
META_TYPE_WAYLAND_SURFACE_ROLE);
|
||||
|
||||
struct _MetaWaylandSurfaceRoleCursor
|
||||
{
|
||||
MetaWaylandSurfaceRole parent;
|
||||
};
|
||||
|
||||
GType meta_wayland_surface_role_cursor_get_type (void) G_GNUC_CONST;
|
||||
G_DEFINE_TYPE (MetaWaylandSurfaceRoleCursor,
|
||||
meta_wayland_surface_role_cursor,
|
||||
META_TYPE_WAYLAND_SURFACE_ROLE);
|
||||
|
||||
struct _MetaWaylandSurfaceRoleDND
|
||||
{
|
||||
MetaWaylandSurfaceRole parent;
|
||||
};
|
||||
|
||||
GType meta_wayland_surface_role_dnd_get_type (void) G_GNUC_CONST;
|
||||
G_DEFINE_TYPE (MetaWaylandSurfaceRoleDND,
|
||||
meta_wayland_surface_role_dnd,
|
||||
META_TYPE_WAYLAND_SURFACE_ROLE);
|
||||
|
||||
static void
|
||||
meta_wayland_surface_role_assigned (MetaWaylandSurfaceRole *surface_role);
|
||||
|
||||
static void
|
||||
meta_wayland_surface_role_commit (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaWaylandPendingState *pending);
|
||||
|
||||
static gboolean
|
||||
meta_wayland_surface_role_is_on_output (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaMonitorInfo *info);
|
||||
|
||||
gboolean
|
||||
meta_wayland_surface_assign_role (MetaWaylandSurface *surface,
|
||||
GType role_type)
|
||||
{
|
||||
if (!surface->role)
|
||||
{
|
||||
surface->role = role;
|
||||
MetaWaylandSurfaceRolePrivate *role_priv;
|
||||
|
||||
switch (surface->role)
|
||||
{
|
||||
case META_WAYLAND_SURFACE_ROLE_NONE:
|
||||
g_assert_not_reached();
|
||||
break;
|
||||
case META_WAYLAND_SURFACE_ROLE_XWAYLAND:
|
||||
/* See apply_pending_state for explanation why Xwayland is special here. */
|
||||
case META_WAYLAND_SURFACE_ROLE_CURSOR:
|
||||
case META_WAYLAND_SURFACE_ROLE_DND:
|
||||
wl_list_insert_list (&surface->compositor->frame_callbacks,
|
||||
&surface->pending_frame_callback_list);
|
||||
wl_list_init (&surface->pending_frame_callback_list);
|
||||
break;
|
||||
case META_WAYLAND_SURFACE_ROLE_WL_SHELL_SURFACE:
|
||||
case META_WAYLAND_SURFACE_ROLE_SUBSURFACE:
|
||||
case META_WAYLAND_SURFACE_ROLE_XDG_SURFACE:
|
||||
case META_WAYLAND_SURFACE_ROLE_XDG_POPUP:
|
||||
surface_actor = META_SURFACE_ACTOR_WAYLAND (surface->surface_actor);
|
||||
meta_surface_actor_wayland_add_frame_callbacks (surface_actor,
|
||||
&surface->pending_frame_callback_list);
|
||||
wl_list_init (&surface->pending_frame_callback_list);
|
||||
break;
|
||||
}
|
||||
surface->role = g_object_new (role_type, NULL);
|
||||
role_priv =
|
||||
meta_wayland_surface_role_get_instance_private (surface->role);
|
||||
role_priv->surface = surface;
|
||||
|
||||
meta_wayland_surface_role_assigned (surface->role);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
else if (G_OBJECT_TYPE (surface->role) != role_type)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -193,18 +258,37 @@ surface_process_damage (MetaWaylandSurface *surface,
|
|||
cairo_region_destroy (scaled_region);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_surface_queue_pending_state_frame_callbacks (MetaWaylandSurface *surface,
|
||||
MetaWaylandPendingState *pending)
|
||||
{
|
||||
wl_list_insert_list (&surface->compositor->frame_callbacks,
|
||||
&pending->frame_callback_list);
|
||||
wl_list_init (&pending->frame_callback_list);
|
||||
}
|
||||
|
||||
static void
|
||||
cursor_surface_commit (MetaWaylandSurface *surface,
|
||||
cursor_surface_commit (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaWaylandPendingState *pending)
|
||||
{
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
|
||||
meta_wayland_surface_queue_pending_state_frame_callbacks (surface, pending);
|
||||
|
||||
if (pending->newly_attached)
|
||||
meta_wayland_seat_update_cursor_surface (surface->compositor->seat);
|
||||
}
|
||||
|
||||
static void
|
||||
dnd_surface_commit (MetaWaylandSurface *surface,
|
||||
dnd_surface_commit (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaWaylandPendingState *pending)
|
||||
{
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
|
||||
meta_wayland_surface_queue_pending_state_frame_callbacks (surface, pending);
|
||||
|
||||
meta_wayland_data_device_update_dnd_surface (&surface->compositor->seat->data_device);
|
||||
}
|
||||
|
||||
|
@ -261,12 +345,28 @@ destroy_window (MetaWaylandSurface *surface)
|
|||
}
|
||||
|
||||
static void
|
||||
toplevel_surface_commit (MetaWaylandSurface *surface,
|
||||
queue_surface_actor_frame_callbacks (MetaWaylandSurface *surface,
|
||||
MetaWaylandPendingState *pending)
|
||||
{
|
||||
MetaSurfaceActorWayland *surface_actor =
|
||||
META_SURFACE_ACTOR_WAYLAND (surface->surface_actor);
|
||||
|
||||
meta_surface_actor_wayland_add_frame_callbacks (surface_actor,
|
||||
&pending->frame_callback_list);
|
||||
wl_list_init (&pending->frame_callback_list);
|
||||
}
|
||||
|
||||
static void
|
||||
toplevel_surface_commit (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaWaylandPendingState *pending)
|
||||
{
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
MetaWindow *window = surface->window;
|
||||
|
||||
if (surface->role == META_WAYLAND_SURFACE_ROLE_WL_SHELL_SURFACE)
|
||||
queue_surface_actor_frame_callbacks (surface, pending);
|
||||
|
||||
if (META_IS_WAYLAND_SURFACE_ROLE_WL_SHELL_SURFACE (surface->role))
|
||||
{
|
||||
/* For wl_shell, it's equivalent to an unmap. Semantics
|
||||
* are poorly defined, so we can choose some that are
|
||||
|
@ -282,7 +382,7 @@ toplevel_surface_commit (MetaWaylandSurface *surface,
|
|||
return;
|
||||
}
|
||||
}
|
||||
else if (surface->role == META_WAYLAND_SURFACE_ROLE_XDG_POPUP)
|
||||
else if (META_IS_WAYLAND_SURFACE_ROLE_XDG_POPUP (surface->role))
|
||||
{
|
||||
/* Ignore commits if we couldn't grab the pointer */
|
||||
if (!window)
|
||||
|
@ -418,12 +518,16 @@ move_pending_state (MetaWaylandPendingState *from,
|
|||
}
|
||||
|
||||
static void
|
||||
subsurface_surface_commit (MetaWaylandSurface *surface,
|
||||
subsurface_surface_commit (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaWaylandPendingState *pending)
|
||||
{
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
MetaSurfaceActorWayland *surface_actor =
|
||||
META_SURFACE_ACTOR_WAYLAND (surface->surface_actor);
|
||||
|
||||
queue_surface_actor_frame_callbacks (surface, pending);
|
||||
|
||||
if (surface->buffer != NULL)
|
||||
clutter_actor_show (CLUTTER_ACTOR (surface_actor));
|
||||
else
|
||||
|
@ -521,9 +625,6 @@ static void
|
|||
apply_pending_state (MetaWaylandSurface *surface,
|
||||
MetaWaylandPendingState *pending)
|
||||
{
|
||||
MetaWaylandCompositor *compositor = surface->compositor;
|
||||
MetaSurfaceActorWayland *surface_actor;
|
||||
|
||||
if (pending->newly_attached)
|
||||
{
|
||||
if (!surface->buffer && surface->window)
|
||||
|
@ -567,63 +668,20 @@ apply_pending_state (MetaWaylandSurface *surface,
|
|||
surface->input_region = NULL;
|
||||
}
|
||||
|
||||
/* wl_surface.frame */
|
||||
switch (surface->role)
|
||||
if (surface->role)
|
||||
{
|
||||
meta_wayland_surface_role_commit (surface->role, pending);
|
||||
g_assert (wl_list_empty (&pending->frame_callback_list));
|
||||
}
|
||||
else
|
||||
{
|
||||
case META_WAYLAND_SURFACE_ROLE_NONE:
|
||||
/* Since there is no role assigned to the surface yet, keep frame
|
||||
* callbacks queued until a role is assigned and we know how
|
||||
* the surface will be drawn.
|
||||
*/
|
||||
wl_list_insert_list (&surface->pending_frame_callback_list,
|
||||
&pending->frame_callback_list);
|
||||
break;
|
||||
case META_WAYLAND_SURFACE_ROLE_XWAYLAND:
|
||||
/* For Xwayland windows, throttling frames when the window isn't actually
|
||||
* drawn is less useful, because Xwayland still has to do the drawing
|
||||
* sent from the application - the throttling would only be of sending us
|
||||
* damage messages, so we simplify and send frame callbacks after the
|
||||
* next paint of the screen, whether the window was drawn or not.
|
||||
*
|
||||
* Currently it may take a few frames before we draw the window, for not
|
||||
* completely understood reasons, and in that case, not thottling frame
|
||||
* callbacks to drawing has the happy side effect that we avoid showing
|
||||
* the user the initial black frame from when the window is mapped empty.
|
||||
*/
|
||||
case META_WAYLAND_SURFACE_ROLE_CURSOR:
|
||||
case META_WAYLAND_SURFACE_ROLE_DND:
|
||||
wl_list_insert_list (&compositor->frame_callbacks, &pending->frame_callback_list);
|
||||
break;
|
||||
case META_WAYLAND_SURFACE_ROLE_XDG_SURFACE:
|
||||
case META_WAYLAND_SURFACE_ROLE_XDG_POPUP:
|
||||
case META_WAYLAND_SURFACE_ROLE_WL_SHELL_SURFACE:
|
||||
case META_WAYLAND_SURFACE_ROLE_SUBSURFACE:
|
||||
surface_actor = META_SURFACE_ACTOR_WAYLAND (surface->surface_actor);
|
||||
meta_surface_actor_wayland_add_frame_callbacks (surface_actor,
|
||||
&pending->frame_callback_list);
|
||||
break;
|
||||
}
|
||||
wl_list_init (&pending->frame_callback_list);
|
||||
|
||||
switch (surface->role)
|
||||
{
|
||||
case META_WAYLAND_SURFACE_ROLE_NONE:
|
||||
case META_WAYLAND_SURFACE_ROLE_XWAYLAND:
|
||||
break;
|
||||
case META_WAYLAND_SURFACE_ROLE_CURSOR:
|
||||
cursor_surface_commit (surface, pending);
|
||||
break;
|
||||
case META_WAYLAND_SURFACE_ROLE_DND:
|
||||
dnd_surface_commit (surface, pending);
|
||||
break;
|
||||
case META_WAYLAND_SURFACE_ROLE_XDG_SURFACE:
|
||||
case META_WAYLAND_SURFACE_ROLE_XDG_POPUP:
|
||||
case META_WAYLAND_SURFACE_ROLE_WL_SHELL_SURFACE:
|
||||
toplevel_surface_commit (surface, pending);
|
||||
break;
|
||||
case META_WAYLAND_SURFACE_ROLE_SUBSURFACE:
|
||||
subsurface_surface_commit (surface, pending);
|
||||
break;
|
||||
wl_list_init (&pending->frame_callback_list);
|
||||
}
|
||||
|
||||
meta_surface_actor_wayland_sync_state (
|
||||
|
@ -932,16 +990,28 @@ set_surface_is_on_output (MetaWaylandSurface *surface,
|
|||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
actor_surface_is_on_output (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaMonitorInfo *monitor)
|
||||
{
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
MetaSurfaceActorWayland *actor =
|
||||
META_SURFACE_ACTOR_WAYLAND (surface->surface_actor);
|
||||
|
||||
return meta_surface_actor_wayland_is_on_monitor (actor, monitor);
|
||||
}
|
||||
|
||||
static void
|
||||
update_surface_output_state (gpointer key, gpointer value, gpointer user_data)
|
||||
{
|
||||
MetaWaylandOutput *wayland_output = value;
|
||||
MetaWaylandSurface *surface = user_data;
|
||||
MetaSurfaceActorWayland *actor =
|
||||
META_SURFACE_ACTOR_WAYLAND (surface->surface_actor);
|
||||
MetaMonitorInfo *monitor;
|
||||
gboolean is_on_output;
|
||||
|
||||
g_assert (surface->role);
|
||||
|
||||
monitor = wayland_output->monitor_info;
|
||||
if (!monitor)
|
||||
{
|
||||
|
@ -949,7 +1019,7 @@ update_surface_output_state (gpointer key, gpointer value, gpointer user_data)
|
|||
return;
|
||||
}
|
||||
|
||||
is_on_output = meta_surface_actor_wayland_is_on_monitor (actor, monitor);
|
||||
is_on_output = meta_wayland_surface_role_is_on_output (surface->role, monitor);
|
||||
set_surface_is_on_output (surface, wayland_output, is_on_output);
|
||||
}
|
||||
|
||||
|
@ -980,6 +1050,8 @@ wl_surface_destructor (struct wl_resource *resource)
|
|||
MetaWaylandCompositor *compositor = surface->compositor;
|
||||
MetaWaylandFrameCallback *cb, *next;
|
||||
|
||||
g_clear_object (&surface->role);
|
||||
|
||||
/* If we still have a window at the time of destruction, that means that
|
||||
* the client is disconnecting, as the resources are destroyed in a random
|
||||
* order. Simply destroy the window in this case. */
|
||||
|
@ -1334,7 +1406,7 @@ xdg_shell_get_xdg_surface (struct wl_client *client,
|
|||
}
|
||||
|
||||
if (!meta_wayland_surface_assign_role (surface,
|
||||
META_WAYLAND_SURFACE_ROLE_XDG_SURFACE))
|
||||
META_TYPE_WAYLAND_SURFACE_ROLE_XDG_SURFACE))
|
||||
{
|
||||
wl_resource_post_error (resource, XDG_SHELL_ERROR_ROLE,
|
||||
"wl_surface@%d already has a different role",
|
||||
|
@ -1445,7 +1517,7 @@ xdg_shell_get_xdg_popup (struct wl_client *client,
|
|||
}
|
||||
|
||||
if (!meta_wayland_surface_assign_role (surface,
|
||||
META_WAYLAND_SURFACE_ROLE_XDG_POPUP))
|
||||
META_TYPE_WAYLAND_SURFACE_ROLE_XDG_POPUP))
|
||||
{
|
||||
wl_resource_post_error (resource, XDG_SHELL_ERROR_ROLE,
|
||||
"wl_surface@%d already has a different role",
|
||||
|
@ -1788,7 +1860,7 @@ wl_shell_get_shell_surface (struct wl_client *client,
|
|||
}
|
||||
|
||||
if (!meta_wayland_surface_assign_role (surface,
|
||||
META_WAYLAND_SURFACE_ROLE_WL_SHELL_SURFACE))
|
||||
META_TYPE_WAYLAND_SURFACE_ROLE_WL_SHELL_SURFACE))
|
||||
{
|
||||
wl_resource_post_error (resource, WL_SHELL_ERROR_ROLE,
|
||||
"wl_surface@%d already has a different role",
|
||||
|
@ -2140,7 +2212,7 @@ wl_subcompositor_get_subsurface (struct wl_client *client,
|
|||
}
|
||||
|
||||
if (!meta_wayland_surface_assign_role (surface,
|
||||
META_WAYLAND_SURFACE_ROLE_SUBSURFACE))
|
||||
META_TYPE_WAYLAND_SURFACE_ROLE_SUBSURFACE))
|
||||
{
|
||||
/* FIXME: There is no subcompositor "role" error yet, so lets just use something
|
||||
* similar until there is.
|
||||
|
@ -2369,3 +2441,167 @@ static void
|
|||
meta_wayland_surface_class_init (MetaWaylandSurfaceClass *klass)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_surface_role_init (MetaWaylandSurfaceRole *role)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_surface_role_class_init (MetaWaylandSurfaceRoleClass *klass)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_surface_role_assigned (MetaWaylandSurfaceRole *surface_role)
|
||||
{
|
||||
META_WAYLAND_SURFACE_ROLE_GET_CLASS (surface_role)->assigned (surface_role);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_surface_role_commit (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaWaylandPendingState *pending)
|
||||
{
|
||||
META_WAYLAND_SURFACE_ROLE_GET_CLASS (surface_role)->commit (surface_role,
|
||||
pending);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_wayland_surface_role_is_on_output (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaMonitorInfo *monitor)
|
||||
{
|
||||
MetaWaylandSurfaceRoleClass *klass;
|
||||
|
||||
klass = META_WAYLAND_SURFACE_ROLE_GET_CLASS (surface_role);
|
||||
if (klass->is_on_output)
|
||||
return klass->is_on_output (surface_role, monitor);
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
MetaWaylandSurface *
|
||||
meta_wayland_surface_role_get_surface (MetaWaylandSurfaceRole *role)
|
||||
{
|
||||
MetaWaylandSurfaceRolePrivate *priv =
|
||||
meta_wayland_surface_role_get_instance_private (role);
|
||||
|
||||
return priv->surface;
|
||||
}
|
||||
|
||||
static void
|
||||
default_role_assigned (MetaWaylandSurfaceRole *surface_role)
|
||||
{
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
|
||||
wl_list_insert_list (&surface->compositor->frame_callbacks,
|
||||
&surface->pending_frame_callback_list);
|
||||
wl_list_init (&surface->pending_frame_callback_list);
|
||||
}
|
||||
|
||||
static void
|
||||
actor_surface_assigned (MetaWaylandSurfaceRole *surface_role)
|
||||
{
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
MetaSurfaceActorWayland *surface_actor =
|
||||
META_SURFACE_ACTOR_WAYLAND (surface->surface_actor);
|
||||
|
||||
meta_surface_actor_wayland_add_frame_callbacks (surface_actor,
|
||||
&surface->pending_frame_callback_list);
|
||||
wl_list_init (&surface->pending_frame_callback_list);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_surface_role_cursor_init (MetaWaylandSurfaceRoleCursor *role)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_surface_role_cursor_class_init (MetaWaylandSurfaceRoleCursorClass *klass)
|
||||
{
|
||||
MetaWaylandSurfaceRoleClass *surface_role_class =
|
||||
META_WAYLAND_SURFACE_ROLE_CLASS (klass);
|
||||
|
||||
surface_role_class->assigned = default_role_assigned;
|
||||
surface_role_class->commit = cursor_surface_commit;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_surface_role_dnd_init (MetaWaylandSurfaceRoleDND *role)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_surface_role_dnd_class_init (MetaWaylandSurfaceRoleDNDClass *klass)
|
||||
{
|
||||
MetaWaylandSurfaceRoleClass *surface_role_class =
|
||||
META_WAYLAND_SURFACE_ROLE_CLASS (klass);
|
||||
|
||||
surface_role_class->assigned = default_role_assigned;
|
||||
surface_role_class->commit = dnd_surface_commit;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_surface_role_xdg_surface_init (MetaWaylandSurfaceRoleXdgSurface *role)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_surface_role_xdg_surface_class_init (MetaWaylandSurfaceRoleXdgSurfaceClass *klass)
|
||||
{
|
||||
MetaWaylandSurfaceRoleClass *surface_role_class =
|
||||
META_WAYLAND_SURFACE_ROLE_CLASS (klass);
|
||||
|
||||
surface_role_class->assigned = actor_surface_assigned;
|
||||
surface_role_class->commit = toplevel_surface_commit;
|
||||
surface_role_class->is_on_output = actor_surface_is_on_output;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_surface_role_xdg_popup_init (MetaWaylandSurfaceRoleXdgPopup *role)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_surface_role_xdg_popup_class_init (MetaWaylandSurfaceRoleXdgPopupClass *klass)
|
||||
{
|
||||
MetaWaylandSurfaceRoleClass *surface_role_class =
|
||||
META_WAYLAND_SURFACE_ROLE_CLASS (klass);
|
||||
|
||||
surface_role_class->assigned = actor_surface_assigned;
|
||||
surface_role_class->commit = toplevel_surface_commit;
|
||||
surface_role_class->is_on_output = actor_surface_is_on_output;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_surface_role_wl_shell_surface_init (MetaWaylandSurfaceRoleWlShellSurface *role)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_surface_role_wl_shell_surface_class_init (MetaWaylandSurfaceRoleWlShellSurfaceClass *klass)
|
||||
{
|
||||
MetaWaylandSurfaceRoleClass *surface_role_class =
|
||||
META_WAYLAND_SURFACE_ROLE_CLASS (klass);
|
||||
|
||||
surface_role_class->assigned = actor_surface_assigned;
|
||||
surface_role_class->commit = toplevel_surface_commit;
|
||||
surface_role_class->is_on_output = actor_surface_is_on_output;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_surface_role_subsurface_init (MetaWaylandSurfaceRoleSubsurface *role)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_surface_role_subsurface_class_init (MetaWaylandSurfaceRoleSubsurfaceClass *klass)
|
||||
{
|
||||
MetaWaylandSurfaceRoleClass *surface_role_class =
|
||||
META_WAYLAND_SURFACE_ROLE_CLASS (klass);
|
||||
|
||||
surface_role_class->assigned = actor_surface_assigned;
|
||||
surface_role_class->commit = subsurface_surface_commit;
|
||||
surface_role_class->is_on_output = actor_surface_is_on_output;
|
||||
}
|
||||
|
|
|
@ -30,6 +30,9 @@
|
|||
#include <meta/meta-cursor-tracker.h>
|
||||
#include "meta-wayland-types.h"
|
||||
#include "meta-surface-actor.h"
|
||||
#include "backends/meta-monitor-manager-private.h"
|
||||
|
||||
typedef struct _MetaWaylandPendingState MetaWaylandPendingState;
|
||||
|
||||
#define META_TYPE_WAYLAND_SURFACE (meta_wayland_surface_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaWaylandSurface,
|
||||
|
@ -37,24 +40,63 @@ G_DECLARE_FINAL_TYPE (MetaWaylandSurface,
|
|||
META, WAYLAND_SURFACE,
|
||||
GObject);
|
||||
|
||||
#define META_TYPE_WAYLAND_SURFACE_ROLE (meta_wayland_surface_role_get_type ())
|
||||
G_DECLARE_DERIVABLE_TYPE (MetaWaylandSurfaceRole, meta_wayland_surface_role,
|
||||
META, WAYLAND_SURFACE_ROLE, GObject);
|
||||
|
||||
struct _MetaWaylandSurfaceRoleClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
void (*assigned) (MetaWaylandSurfaceRole *surface_role);
|
||||
void (*commit) (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaWaylandPendingState *pending);
|
||||
gboolean (*is_on_output) (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaMonitorInfo *monitor);
|
||||
};
|
||||
|
||||
struct _MetaWaylandSerial {
|
||||
gboolean set;
|
||||
uint32_t value;
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
META_WAYLAND_SURFACE_ROLE_NONE,
|
||||
META_WAYLAND_SURFACE_ROLE_SUBSURFACE,
|
||||
META_WAYLAND_SURFACE_ROLE_XDG_SURFACE,
|
||||
META_WAYLAND_SURFACE_ROLE_XDG_POPUP,
|
||||
META_WAYLAND_SURFACE_ROLE_WL_SHELL_SURFACE,
|
||||
META_WAYLAND_SURFACE_ROLE_CURSOR,
|
||||
META_WAYLAND_SURFACE_ROLE_DND,
|
||||
META_WAYLAND_SURFACE_ROLE_XWAYLAND,
|
||||
} MetaWaylandSurfaceRole;
|
||||
#define META_TYPE_WAYLAND_SURFACE_ROLE_SUBSURFACE (meta_wayland_surface_role_subsurface_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaWaylandSurfaceRoleSubsurface,
|
||||
meta_wayland_surface_role_subsurface,
|
||||
META, WAYLAND_SURFACE_ROLE_SUBSURFACE,
|
||||
MetaWaylandSurfaceRole);
|
||||
|
||||
typedef struct
|
||||
#define META_TYPE_WAYLAND_SURFACE_ROLE_XDG_SURFACE (meta_wayland_surface_role_xdg_surface_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaWaylandSurfaceRoleXdgSurface,
|
||||
meta_wayland_surface_role_xdg_surface,
|
||||
META, WAYLAND_SURFACE_ROLE_XDG_SURFACE,
|
||||
MetaWaylandSurfaceRole);
|
||||
|
||||
#define META_TYPE_WAYLAND_SURFACE_ROLE_XDG_POPUP (meta_wayland_surface_role_xdg_popup_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaWaylandSurfaceRoleXdgPopup,
|
||||
meta_wayland_surface_role_xdg_popup,
|
||||
META, WAYLAND_SURFACE_ROLE_XDG_POPUP,
|
||||
MetaWaylandSurfaceRole);
|
||||
|
||||
#define META_TYPE_WAYLAND_SURFACE_ROLE_WL_SHELL_SURFACE (meta_wayland_surface_role_wl_shell_surface_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaWaylandSurfaceRoleWlShellSurface,
|
||||
meta_wayland_surface_role_wl_shell_surface,
|
||||
META, WAYLAND_SURFACE_ROLE_WL_SHELL_SURFACE,
|
||||
MetaWaylandSurfaceRole);
|
||||
|
||||
#define META_TYPE_WAYLAND_SURFACE_ROLE_CURSOR (meta_wayland_surface_role_cursor_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaWaylandSurfaceRoleCursor,
|
||||
meta_wayland_surface_role_cursor,
|
||||
META, WAYLAND_SURFACE_ROLE_CURSOR,
|
||||
MetaWaylandSurfaceRole);
|
||||
|
||||
#define META_TYPE_WAYLAND_SURFACE_ROLE_DND (meta_wayland_surface_role_dnd_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaWaylandSurfaceRoleDND,
|
||||
meta_wayland_surface_role_dnd,
|
||||
META, WAYLAND_SURFACE_ROLE_DND,
|
||||
MetaWaylandSurfaceRole);
|
||||
|
||||
struct _MetaWaylandPendingState
|
||||
{
|
||||
/* wl_surface.attach */
|
||||
gboolean newly_attached;
|
||||
|
@ -78,7 +120,7 @@ typedef struct
|
|||
|
||||
MetaRectangle new_geometry;
|
||||
gboolean has_new_geometry;
|
||||
} MetaWaylandPendingState;
|
||||
};
|
||||
|
||||
struct _MetaWaylandDragDestFuncs
|
||||
{
|
||||
|
@ -102,7 +144,7 @@ struct _MetaWaylandSurface
|
|||
struct wl_resource *resource;
|
||||
MetaWaylandCompositor *compositor;
|
||||
MetaSurfaceActor *surface_actor;
|
||||
MetaWaylandSurfaceRole role;
|
||||
MetaWaylandSurfaceRole *role;
|
||||
MetaWindow *window;
|
||||
MetaWaylandBuffer *buffer;
|
||||
struct wl_listener buffer_destroy_listener;
|
||||
|
@ -180,8 +222,8 @@ MetaWaylandSurface *meta_wayland_surface_create (MetaWaylandCompositor *composit
|
|||
struct wl_resource *compositor_resource,
|
||||
guint32 id);
|
||||
|
||||
gboolean meta_wayland_surface_assign_role (MetaWaylandSurface *surface,
|
||||
MetaWaylandSurfaceRole role);
|
||||
gboolean meta_wayland_surface_assign_role (MetaWaylandSurface *surface,
|
||||
GType role_type);
|
||||
|
||||
void meta_wayland_surface_set_window (MetaWaylandSurface *surface,
|
||||
MetaWindow *window);
|
||||
|
@ -209,4 +251,9 @@ void meta_wayland_surface_update_outputs (MetaWaylandSurface *sur
|
|||
|
||||
MetaWindow * meta_wayland_surface_get_toplevel_window (MetaWaylandSurface *surface);
|
||||
|
||||
void meta_wayland_surface_queue_pending_state_frame_callbacks (MetaWaylandSurface *surface,
|
||||
MetaWaylandPendingState *pending);
|
||||
|
||||
MetaWaylandSurface * meta_wayland_surface_role_get_surface (MetaWaylandSurfaceRole *role);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -66,7 +66,7 @@ meta_window_wayland_manage (MetaWindow *window)
|
|||
0);
|
||||
}
|
||||
|
||||
if (window->surface->role == META_WAYLAND_SURFACE_ROLE_XDG_POPUP)
|
||||
if (META_IS_WAYLAND_SURFACE_ROLE_XDG_POPUP (window->surface->role))
|
||||
{
|
||||
MetaWaylandSurface *parent = window->surface->popup.parent;
|
||||
|
||||
|
|
|
@ -32,6 +32,24 @@
|
|||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include "compositor/meta-surface-actor-wayland.h"
|
||||
|
||||
#define META_TYPE_WAYLAND_SURFACE_ROLE_XWAYLAND (meta_wayland_surface_role_xwayland_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaWaylandSurfaceRoleXWayland,
|
||||
meta_wayland_surface_role_xwayland,
|
||||
META, WAYLAND_SURFACE_ROLE_XWAYLAND,
|
||||
MetaWaylandSurfaceRole);
|
||||
|
||||
struct _MetaWaylandSurfaceRoleXWayland
|
||||
{
|
||||
MetaWaylandSurfaceRole parent;
|
||||
};
|
||||
|
||||
GType meta_wayland_surface_role_xwayland_get_type (void) G_GNUC_CONST;
|
||||
G_DEFINE_TYPE (MetaWaylandSurfaceRoleXWayland,
|
||||
meta_wayland_surface_role_xwayland,
|
||||
META_TYPE_WAYLAND_SURFACE_ROLE);
|
||||
|
||||
static void
|
||||
associate_window_with_surface (MetaWindow *window,
|
||||
MetaWaylandSurface *surface)
|
||||
|
@ -46,7 +64,7 @@ associate_window_with_surface (MetaWindow *window,
|
|||
window->surface->window = NULL;
|
||||
|
||||
if (!meta_wayland_surface_assign_role (surface,
|
||||
META_WAYLAND_SURFACE_ROLE_XWAYLAND))
|
||||
META_TYPE_WAYLAND_SURFACE_ROLE_XWAYLAND))
|
||||
{
|
||||
wl_resource_post_error (surface->resource,
|
||||
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||
|
@ -553,3 +571,53 @@ meta_xwayland_stop (MetaXWaylandManager *manager)
|
|||
g_clear_pointer (&manager->lock_file, g_free);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
xwayland_surface_assigned (MetaWaylandSurfaceRole *surface_role)
|
||||
{
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
|
||||
/* See comment in xwayland_surface_commit for why we reply even though the
|
||||
* surface may not be drawn the next frame.
|
||||
*/
|
||||
wl_list_insert_list (&surface->compositor->frame_callbacks,
|
||||
&surface->pending_frame_callback_list);
|
||||
wl_list_init (&surface->pending_frame_callback_list);
|
||||
}
|
||||
|
||||
static void
|
||||
xwayland_surface_commit (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaWaylandPendingState *pending)
|
||||
{
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
|
||||
/* For Xwayland windows, throttling frames when the window isn't actually
|
||||
* drawn is less useful, because Xwayland still has to do the drawing sent
|
||||
* from the application - the throttling would only be of sending us damage
|
||||
* messages, so we simplify and send frame callbacks after the next paint of
|
||||
* the screen, whether the window was drawn or not.
|
||||
*
|
||||
* Currently it may take a few frames before we draw the window, for not
|
||||
* completely understood reasons, and in that case, not thottling frame
|
||||
* callbacks to drawing has the happy side effect that we avoid showing the
|
||||
* user the initial black frame from when the window is mapped empty.
|
||||
*/
|
||||
meta_wayland_surface_queue_pending_state_frame_callbacks (surface, pending);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_surface_role_xwayland_init (MetaWaylandSurfaceRoleXWayland *role)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_surface_role_xwayland_class_init (MetaWaylandSurfaceRoleXWaylandClass *klass)
|
||||
{
|
||||
MetaWaylandSurfaceRoleClass *surface_role_class =
|
||||
META_WAYLAND_SURFACE_ROLE_CLASS (klass);
|
||||
|
||||
surface_role_class->assigned = xwayland_surface_assigned;
|
||||
surface_role_class->commit = xwayland_surface_commit;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue