2017-12-20 04:40:22 -05:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2012,2013 Intel Corporation
|
|
|
|
* Copyright (C) 2013-2017 Red Hat, Inc.
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License as
|
|
|
|
* published by the Free Software Foundation; either version 2 of the
|
|
|
|
* License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful, but
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
|
|
* 02111-1307, USA.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
|
|
|
#include "wayland/meta-wayland-shell-surface.h"
|
|
|
|
|
|
|
|
#include "compositor/meta-surface-actor-wayland.h"
|
|
|
|
#include "wayland/meta-wayland-actor-surface.h"
|
|
|
|
#include "wayland/meta-wayland-buffer.h"
|
2017-12-22 01:28:28 -05:00
|
|
|
#include "wayland/meta-wayland-subsurface.h"
|
|
|
|
#include "wayland/meta-wayland-surface.h"
|
|
|
|
#include "wayland/meta-window-wayland.h"
|
2017-12-20 04:40:22 -05:00
|
|
|
|
2018-02-23 06:05:05 -05:00
|
|
|
G_DEFINE_ABSTRACT_TYPE (MetaWaylandShellSurface,
|
|
|
|
meta_wayland_shell_surface,
|
|
|
|
META_TYPE_WAYLAND_ACTOR_SURFACE)
|
2017-12-20 04:40:22 -05:00
|
|
|
|
2017-12-22 01:28:28 -05:00
|
|
|
void
|
|
|
|
meta_wayland_shell_surface_calculate_geometry (MetaWaylandShellSurface *shell_surface,
|
|
|
|
MetaRectangle *out_geometry)
|
|
|
|
{
|
|
|
|
MetaWaylandSurfaceRole *surface_role =
|
|
|
|
META_WAYLAND_SURFACE_ROLE (shell_surface);
|
|
|
|
MetaWaylandSurface *surface =
|
|
|
|
meta_wayland_surface_role_get_surface (surface_role);
|
|
|
|
MetaRectangle geometry;
|
2019-06-30 09:18:46 -04:00
|
|
|
GNode *n;
|
2017-12-22 01:28:28 -05:00
|
|
|
|
|
|
|
geometry = (MetaRectangle) {
|
2018-06-29 11:53:21 -04:00
|
|
|
.width = meta_wayland_surface_get_width (surface),
|
|
|
|
.height = meta_wayland_surface_get_height (surface),
|
2017-12-22 01:28:28 -05:00
|
|
|
};
|
|
|
|
|
2019-06-30 09:18:46 -04:00
|
|
|
for (n = g_node_first_child (surface->subsurface_branch_node);
|
|
|
|
n;
|
|
|
|
n = g_node_next_sibling (n))
|
2017-12-22 01:28:28 -05:00
|
|
|
{
|
2019-06-30 09:18:46 -04:00
|
|
|
MetaWaylandSurface *subsurface_surface = n->data;
|
|
|
|
MetaWaylandSubsurface *subsurface;
|
2017-12-22 01:28:28 -05:00
|
|
|
|
2019-06-30 09:18:46 -04:00
|
|
|
if (G_NODE_IS_LEAF (n))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
subsurface = META_WAYLAND_SUBSURFACE (subsurface_surface->role);
|
2017-12-22 01:28:28 -05:00
|
|
|
meta_wayland_subsurface_union_geometry (subsurface,
|
|
|
|
0, 0,
|
|
|
|
&geometry);
|
|
|
|
}
|
|
|
|
|
|
|
|
*out_geometry = geometry;
|
|
|
|
}
|
|
|
|
|
2018-08-18 13:41:15 -04:00
|
|
|
void
|
|
|
|
meta_wayland_shell_surface_determine_geometry (MetaWaylandShellSurface *shell_surface,
|
|
|
|
MetaRectangle *set_geometry,
|
|
|
|
MetaRectangle *out_geometry)
|
|
|
|
{
|
|
|
|
MetaRectangle bounding_geometry = { 0 };
|
|
|
|
MetaRectangle intersected_geometry = { 0 };
|
|
|
|
|
|
|
|
meta_wayland_shell_surface_calculate_geometry (shell_surface,
|
|
|
|
&bounding_geometry);
|
|
|
|
|
|
|
|
meta_rectangle_intersect (set_geometry, &bounding_geometry,
|
|
|
|
&intersected_geometry);
|
|
|
|
|
|
|
|
*out_geometry = intersected_geometry;
|
|
|
|
}
|
|
|
|
|
2017-12-22 03:26:24 -05:00
|
|
|
void
|
|
|
|
meta_wayland_shell_surface_set_window (MetaWaylandShellSurface *shell_surface,
|
|
|
|
MetaWindow *window)
|
|
|
|
{
|
|
|
|
MetaWaylandSurfaceRole *surface_role =
|
|
|
|
META_WAYLAND_SURFACE_ROLE (shell_surface);
|
|
|
|
MetaWaylandSurface *surface =
|
|
|
|
meta_wayland_surface_role_get_surface (surface_role);
|
|
|
|
|
|
|
|
meta_wayland_surface_set_window (surface, window);
|
2018-08-24 06:54:50 -04:00
|
|
|
meta_window_update_monitor (window, META_WINDOW_UPDATE_MONITOR_FLAGS_NONE);
|
2017-12-22 03:26:24 -05:00
|
|
|
}
|
|
|
|
|
2017-12-20 04:40:22 -05:00
|
|
|
void
|
2019-07-05 12:10:14 -04:00
|
|
|
meta_wayland_shell_surface_configure (MetaWaylandShellSurface *shell_surface,
|
|
|
|
MetaWaylandWindowConfiguration *configuration)
|
2017-12-20 04:40:22 -05:00
|
|
|
{
|
|
|
|
MetaWaylandShellSurfaceClass *shell_surface_class =
|
|
|
|
META_WAYLAND_SHELL_SURFACE_GET_CLASS (shell_surface);
|
|
|
|
|
2019-07-05 12:10:14 -04:00
|
|
|
shell_surface_class->configure (shell_surface, configuration);
|
2017-12-20 04:40:22 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
meta_wayland_shell_surface_ping (MetaWaylandShellSurface *shell_surface,
|
|
|
|
uint32_t serial)
|
|
|
|
{
|
|
|
|
MetaWaylandShellSurfaceClass *shell_surface_class =
|
|
|
|
META_WAYLAND_SHELL_SURFACE_GET_CLASS (shell_surface);
|
|
|
|
|
|
|
|
shell_surface_class->ping (shell_surface, serial);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
meta_wayland_shell_surface_close (MetaWaylandShellSurface *shell_surface)
|
|
|
|
{
|
|
|
|
MetaWaylandShellSurfaceClass *shell_surface_class =
|
|
|
|
META_WAYLAND_SHELL_SURFACE_GET_CLASS (shell_surface);
|
|
|
|
|
|
|
|
shell_surface_class->close (shell_surface);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
meta_wayland_shell_surface_managed (MetaWaylandShellSurface *shell_surface,
|
|
|
|
MetaWindow *window)
|
|
|
|
{
|
|
|
|
MetaWaylandShellSurfaceClass *shell_surface_class =
|
|
|
|
META_WAYLAND_SHELL_SURFACE_GET_CLASS (shell_surface);
|
|
|
|
|
|
|
|
shell_surface_class->managed (shell_surface, window);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
meta_wayland_shell_surface_surface_commit (MetaWaylandSurfaceRole *surface_role,
|
2019-03-13 08:27:25 -04:00
|
|
|
MetaWaylandSurfaceState *pending)
|
2017-12-20 04:40:22 -05:00
|
|
|
{
|
2017-12-22 01:28:28 -05:00
|
|
|
MetaWaylandActorSurface *actor_surface =
|
|
|
|
META_WAYLAND_ACTOR_SURFACE (surface_role);
|
2017-12-20 04:40:22 -05:00
|
|
|
MetaWaylandSurface *surface =
|
|
|
|
meta_wayland_surface_role_get_surface (surface_role);
|
|
|
|
MetaWaylandSurfaceRoleClass *surface_role_class;
|
|
|
|
MetaWindow *window;
|
|
|
|
MetaWaylandBuffer *buffer;
|
2019-07-09 11:29:37 -04:00
|
|
|
double geometry_scale;
|
2017-12-20 04:40:22 -05:00
|
|
|
|
|
|
|
surface_role_class =
|
|
|
|
META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_shell_surface_parent_class);
|
|
|
|
surface_role_class->commit (surface_role, pending);
|
|
|
|
|
|
|
|
buffer = surface->buffer_ref.buffer;
|
|
|
|
if (!buffer)
|
|
|
|
return;
|
|
|
|
|
|
|
|
window = surface->window;
|
|
|
|
if (!window)
|
|
|
|
return;
|
|
|
|
|
2019-07-09 11:29:37 -04:00
|
|
|
geometry_scale = meta_wayland_actor_surface_get_geometry_scale (actor_surface);
|
2017-12-20 04:40:22 -05:00
|
|
|
|
2019-07-09 11:29:37 -04:00
|
|
|
window->buffer_rect.width =
|
|
|
|
meta_wayland_surface_get_width (surface) * geometry_scale;
|
|
|
|
window->buffer_rect.height =
|
|
|
|
meta_wayland_surface_get_height (surface) * geometry_scale;
|
2017-12-20 04:40:22 -05:00
|
|
|
}
|
|
|
|
|
2019-09-06 09:13:24 -04:00
|
|
|
static double
|
|
|
|
meta_wayland_shell_surface_get_geometry_scale (MetaWaylandActorSurface *actor_surface)
|
|
|
|
{
|
|
|
|
MetaWaylandSurfaceRole *surface_role =
|
|
|
|
META_WAYLAND_SURFACE_ROLE (actor_surface);
|
|
|
|
MetaWaylandSurface *surface =
|
|
|
|
meta_wayland_surface_role_get_surface (surface_role);
|
|
|
|
MetaWindow *toplevel_window;
|
|
|
|
|
|
|
|
toplevel_window = meta_wayland_surface_get_toplevel_window (surface);
|
|
|
|
if (meta_is_stage_views_scaled () || !toplevel_window)
|
|
|
|
return 1;
|
|
|
|
else
|
|
|
|
return meta_window_wayland_get_geometry_scale (toplevel_window);
|
|
|
|
}
|
|
|
|
|
2019-04-16 17:35:28 -04:00
|
|
|
static void
|
|
|
|
meta_wayland_shell_surface_sync_actor_state (MetaWaylandActorSurface *actor_surface)
|
|
|
|
{
|
|
|
|
MetaWaylandSurfaceRole *surface_role =
|
|
|
|
META_WAYLAND_SURFACE_ROLE (actor_surface);
|
|
|
|
MetaWaylandSurface *surface =
|
|
|
|
meta_wayland_surface_role_get_surface (surface_role);
|
|
|
|
MetaWaylandActorSurfaceClass *actor_surface_class =
|
|
|
|
META_WAYLAND_ACTOR_SURFACE_CLASS (meta_wayland_shell_surface_parent_class);
|
|
|
|
MetaWaylandSurface *toplevel_surface;
|
|
|
|
|
|
|
|
toplevel_surface = meta_wayland_surface_get_toplevel (surface);
|
|
|
|
if (toplevel_surface && toplevel_surface->window)
|
|
|
|
actor_surface_class->sync_actor_state (actor_surface);
|
|
|
|
}
|
|
|
|
|
2019-09-04 12:35:08 -04:00
|
|
|
void
|
|
|
|
meta_wayland_shell_surface_destroy_window (MetaWaylandShellSurface *shell_surface)
|
|
|
|
{
|
|
|
|
MetaWaylandSurfaceRole *surface_role =
|
|
|
|
META_WAYLAND_SURFACE_ROLE (shell_surface);
|
|
|
|
MetaWaylandSurface *surface =
|
|
|
|
meta_wayland_surface_role_get_surface (surface_role);
|
|
|
|
MetaWindow *window;
|
|
|
|
MetaDisplay *display;
|
|
|
|
uint32_t timestamp;
|
|
|
|
|
|
|
|
window = surface->window;
|
|
|
|
if (!window)
|
|
|
|
return;
|
|
|
|
|
|
|
|
display = meta_window_get_display (window);
|
|
|
|
timestamp = meta_display_get_current_time_roundtrip (display);
|
|
|
|
meta_window_unmanage (surface->window, timestamp);
|
|
|
|
g_assert (!surface->window);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
meta_wayland_shell_surface_finalize (GObject *object)
|
|
|
|
{
|
|
|
|
MetaWaylandShellSurface *shell_surface = META_WAYLAND_SHELL_SURFACE (object);
|
|
|
|
|
|
|
|
meta_wayland_shell_surface_destroy_window (shell_surface);
|
|
|
|
|
|
|
|
G_OBJECT_CLASS (meta_wayland_shell_surface_parent_class)->finalize (object);
|
|
|
|
}
|
|
|
|
|
2017-12-20 04:40:22 -05:00
|
|
|
static void
|
|
|
|
meta_wayland_shell_surface_init (MetaWaylandShellSurface *role)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
meta_wayland_shell_surface_class_init (MetaWaylandShellSurfaceClass *klass)
|
|
|
|
{
|
2019-09-04 12:35:08 -04:00
|
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
2017-12-20 04:40:22 -05:00
|
|
|
MetaWaylandSurfaceRoleClass *surface_role_class =
|
|
|
|
META_WAYLAND_SURFACE_ROLE_CLASS (klass);
|
2019-04-16 17:35:28 -04:00
|
|
|
MetaWaylandActorSurfaceClass *actor_surface_class =
|
|
|
|
META_WAYLAND_ACTOR_SURFACE_CLASS (klass);
|
2017-12-20 04:40:22 -05:00
|
|
|
|
2019-09-04 12:35:08 -04:00
|
|
|
object_class->finalize = meta_wayland_shell_surface_finalize;
|
|
|
|
|
2017-12-20 04:40:22 -05:00
|
|
|
surface_role_class->commit = meta_wayland_shell_surface_surface_commit;
|
2019-09-06 09:13:24 -04:00
|
|
|
|
|
|
|
actor_surface_class->get_geometry_scale =
|
|
|
|
meta_wayland_shell_surface_get_geometry_scale;
|
2019-04-16 17:35:28 -04:00
|
|
|
actor_surface_class->sync_actor_state =
|
|
|
|
meta_wayland_shell_surface_sync_actor_state;
|
2017-12-20 04:40:22 -05:00
|
|
|
}
|