mirror of
https://github.com/brl/mutter.git
synced 2024-11-27 02:20:43 -05:00
7e2a0ede16
All child classes of `MetaWaylandShellSurface` as well as `MetaWaylandSurfaceRoleXWayland` should only sync their actor if their toplevel surface has a window. Currently this check is done in the actor-surface class, but not all surface classes have a toplevel window, e.g. dnd-surfaces. Move the check to the right places. For subsurfaces this assumes that the subsurface is not the child of a window-less surface (like, as stated above, e.g. a dnd-surface). If we want to support subsurfaces of window-less surfaces in the future we have to extend the check here. But as this is not a regression, ignore this case for now. https://gitlab.gnome.org/GNOME/mutter/merge_requests/537
211 lines
7.2 KiB
C
211 lines
7.2 KiB
C
/*
|
|
* 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"
|
|
#include "wayland/meta-wayland-subsurface.h"
|
|
#include "wayland/meta-wayland-surface.h"
|
|
#include "wayland/meta-window-wayland.h"
|
|
|
|
G_DEFINE_ABSTRACT_TYPE (MetaWaylandShellSurface,
|
|
meta_wayland_shell_surface,
|
|
META_TYPE_WAYLAND_ACTOR_SURFACE)
|
|
|
|
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;
|
|
GList *l;
|
|
|
|
geometry = (MetaRectangle) {
|
|
.width = meta_wayland_surface_get_width (surface),
|
|
.height = meta_wayland_surface_get_height (surface),
|
|
};
|
|
|
|
for (l = surface->subsurfaces; l; l = l->next)
|
|
{
|
|
MetaWaylandSurface *subsurface_surface = l->data;
|
|
MetaWaylandSubsurface *subsurface =
|
|
META_WAYLAND_SUBSURFACE (subsurface_surface->role);
|
|
|
|
meta_wayland_subsurface_union_geometry (subsurface,
|
|
0, 0,
|
|
&geometry);
|
|
}
|
|
|
|
*out_geometry = geometry;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
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);
|
|
meta_window_update_monitor (window, META_WINDOW_UPDATE_MONITOR_FLAGS_NONE);
|
|
}
|
|
|
|
void
|
|
meta_wayland_shell_surface_configure (MetaWaylandShellSurface *shell_surface,
|
|
int new_x,
|
|
int new_y,
|
|
int new_width,
|
|
int new_height,
|
|
MetaWaylandSerial *sent_serial)
|
|
{
|
|
MetaWaylandShellSurfaceClass *shell_surface_class =
|
|
META_WAYLAND_SHELL_SURFACE_GET_CLASS (shell_surface);
|
|
|
|
shell_surface_class->configure (shell_surface,
|
|
new_x,
|
|
new_y,
|
|
new_width,
|
|
new_height,
|
|
sent_serial);
|
|
}
|
|
|
|
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,
|
|
MetaWaylandPendingState *pending)
|
|
{
|
|
MetaWaylandActorSurface *actor_surface =
|
|
META_WAYLAND_ACTOR_SURFACE (surface_role);
|
|
MetaWaylandSurface *surface =
|
|
meta_wayland_surface_role_get_surface (surface_role);
|
|
MetaWaylandSurfaceRoleClass *surface_role_class;
|
|
MetaWindow *window;
|
|
MetaWaylandBuffer *buffer;
|
|
CoglTexture *texture;
|
|
double scale;
|
|
|
|
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;
|
|
|
|
scale = meta_wayland_actor_surface_calculate_scale (actor_surface);
|
|
texture = meta_wayland_surface_get_texture (surface);
|
|
|
|
window->buffer_rect.width = cogl_texture_get_width (texture) * scale;
|
|
window->buffer_rect.height = cogl_texture_get_height (texture) * scale;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
static void
|
|
meta_wayland_shell_surface_init (MetaWaylandShellSurface *role)
|
|
{
|
|
}
|
|
|
|
static void
|
|
meta_wayland_shell_surface_class_init (MetaWaylandShellSurfaceClass *klass)
|
|
{
|
|
MetaWaylandSurfaceRoleClass *surface_role_class =
|
|
META_WAYLAND_SURFACE_ROLE_CLASS (klass);
|
|
MetaWaylandActorSurfaceClass *actor_surface_class =
|
|
META_WAYLAND_ACTOR_SURFACE_CLASS (klass);
|
|
|
|
surface_role_class->commit = meta_wayland_shell_surface_surface_commit;
|
|
actor_surface_class->sync_actor_state =
|
|
meta_wayland_shell_surface_sync_actor_state;
|
|
}
|