2010-12-18 20:38:49 +00:00
|
|
|
|
/*
|
|
|
|
|
* Copyright © 2010 Intel Corporation
|
|
|
|
|
*
|
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
|
* modify it under the terms of the GNU Lesser General Public License
|
|
|
|
|
* as published by the Free Software Foundation; either version 2 of
|
|
|
|
|
* the License, or (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* This library 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
|
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
2012-02-27 13:01:10 +00:00
|
|
|
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
2010-12-18 20:38:49 +00:00
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
|
|
|
|
|
#include <netinet/in.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
|
|
#include "gdk.h"
|
|
|
|
|
#include "gdkwayland.h"
|
|
|
|
|
|
|
|
|
|
#include "gdkwindow.h"
|
|
|
|
|
#include "gdkwindowimpl.h"
|
|
|
|
|
#include "gdkdisplay-wayland.h"
|
2013-04-24 22:14:22 +00:00
|
|
|
|
#include "gdkframeclockprivate.h"
|
2010-12-18 20:38:49 +00:00
|
|
|
|
#include "gdkprivate-wayland.h"
|
|
|
|
|
#include "gdkinternals.h"
|
|
|
|
|
#include "gdkdeviceprivate.h"
|
|
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <string.h>
|
2012-04-19 16:18:46 +00:00
|
|
|
|
#include <errno.h>
|
2010-12-18 20:38:49 +00:00
|
|
|
|
|
2013-07-12 14:49:52 +00:00
|
|
|
|
#define WL_SURFACE_HAS_BUFFER_SCALE 3
|
2011-02-08 21:02:22 +00:00
|
|
|
|
|
2010-12-18 20:38:49 +00:00
|
|
|
|
#define WINDOW_IS_TOPLEVEL_OR_FOREIGN(window) \
|
|
|
|
|
(GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \
|
|
|
|
|
GDK_WINDOW_TYPE (window) != GDK_WINDOW_OFFSCREEN)
|
|
|
|
|
|
2013-09-16 21:23:29 +00:00
|
|
|
|
#define WINDOW_IS_TOPLEVEL(window) \
|
2010-12-18 20:38:49 +00:00
|
|
|
|
(GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \
|
|
|
|
|
GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN && \
|
|
|
|
|
GDK_WINDOW_TYPE (window) != GDK_WINDOW_OFFSCREEN)
|
|
|
|
|
|
|
|
|
|
/* Return whether time1 is considered later than time2 as far as xserver
|
|
|
|
|
* time is concerned. Accounts for wraparound.
|
|
|
|
|
*/
|
|
|
|
|
#define XSERVER_TIME_IS_LATER(time1, time2) \
|
|
|
|
|
( (( time1 > time2 ) && ( time1 - time2 < ((guint32)-1)/2 )) || \
|
|
|
|
|
(( time1 < time2 ) && ( time2 - time1 > ((guint32)-1)/2 )) \
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
typedef struct _GdkWaylandWindow GdkWaylandWindow;
|
|
|
|
|
typedef struct _GdkWaylandWindowClass GdkWaylandWindowClass;
|
|
|
|
|
|
|
|
|
|
struct _GdkWaylandWindow {
|
|
|
|
|
GdkWindow parent;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct _GdkWaylandWindowClass {
|
|
|
|
|
GdkWindowClass parent_class;
|
|
|
|
|
};
|
|
|
|
|
|
2013-01-23 21:20:05 +00:00
|
|
|
|
G_DEFINE_TYPE (GdkWaylandWindow, gdk_wayland_window, GDK_TYPE_WINDOW)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
|
|
|
|
|
static void
|
2013-01-23 21:20:05 +00:00
|
|
|
|
gdk_wayland_window_class_init (GdkWaylandWindowClass *wayland_window_class)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2013-01-23 21:20:05 +00:00
|
|
|
|
gdk_wayland_window_init (GdkWaylandWindow *wayland_window)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2011-01-06 21:51:12 +00:00
|
|
|
|
#define GDK_TYPE_WINDOW_IMPL_WAYLAND (_gdk_window_impl_wayland_get_type ())
|
|
|
|
|
#define GDK_WINDOW_IMPL_WAYLAND(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WINDOW_IMPL_WAYLAND, GdkWindowImplWayland))
|
|
|
|
|
#define GDK_WINDOW_IMPL_WAYLAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_WINDOW_IMPL_WAYLAND, GdkWindowImplWaylandClass))
|
|
|
|
|
#define GDK_IS_WINDOW_IMPL_WAYLAND(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_WINDOW_IMPL_WAYLAND))
|
|
|
|
|
#define GDK_IS_WINDOW_IMPL_WAYLAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_WINDOW_IMPL_WAYLAND))
|
|
|
|
|
#define GDK_WINDOW_IMPL_WAYLAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_WINDOW_IMPL_WAYLAND, GdkWindowImplWaylandClass))
|
|
|
|
|
|
|
|
|
|
typedef struct _GdkWindowImplWayland GdkWindowImplWayland;
|
|
|
|
|
typedef struct _GdkWindowImplWaylandClass GdkWindowImplWaylandClass;
|
|
|
|
|
|
|
|
|
|
struct _GdkWindowImplWayland
|
|
|
|
|
{
|
|
|
|
|
GdkWindowImpl parent_instance;
|
|
|
|
|
|
|
|
|
|
GdkWindow *wrapper;
|
|
|
|
|
|
2013-04-25 15:19:31 +00:00
|
|
|
|
/* The wl_outputs that this window currently touches */
|
|
|
|
|
GSList *outputs;
|
|
|
|
|
|
2011-01-06 21:51:12 +00:00
|
|
|
|
struct wl_surface *surface;
|
2013-11-11 23:02:19 +00:00
|
|
|
|
|
|
|
|
|
struct xdg_surface *xdg_surface;
|
|
|
|
|
struct xdg_popup *xdg_popup;
|
2013-08-30 11:55:37 +00:00
|
|
|
|
struct gtk_surface *gtk_surface;
|
2013-11-19 23:27:54 +00:00
|
|
|
|
|
2011-01-07 15:16:17 +00:00
|
|
|
|
unsigned int mapped : 1;
|
2013-09-22 03:35:02 +00:00
|
|
|
|
unsigned int use_custom_surface : 1;
|
|
|
|
|
unsigned int pending_commit : 1;
|
2012-01-13 14:48:46 +00:00
|
|
|
|
GdkWindowTypeHint hint;
|
2013-09-22 03:35:02 +00:00
|
|
|
|
GdkWindow *transient_for;
|
2011-01-06 21:51:12 +00:00
|
|
|
|
|
|
|
|
|
cairo_surface_t *cairo_surface;
|
2012-03-06 21:24:20 +00:00
|
|
|
|
|
2013-03-16 23:57:17 +00:00
|
|
|
|
gchar *title;
|
|
|
|
|
|
2012-01-09 17:11:22 +00:00
|
|
|
|
GdkGeometry geometry_hints;
|
|
|
|
|
GdkWindowHints geometry_mask;
|
2012-02-27 14:06:22 +00:00
|
|
|
|
|
2013-09-22 03:35:02 +00:00
|
|
|
|
guint32 grab_time;
|
2013-02-15 11:16:51 +00:00
|
|
|
|
GdkDevice *grab_device;
|
2012-07-11 13:29:43 +00:00
|
|
|
|
struct wl_seat *grab_input_seat;
|
2013-01-29 18:40:02 +00:00
|
|
|
|
|
2013-04-24 22:14:22 +00:00
|
|
|
|
gint64 pending_frame_counter;
|
2013-09-22 03:35:02 +00:00
|
|
|
|
guint32 scale;
|
2014-02-27 21:54:20 +00:00
|
|
|
|
|
|
|
|
|
int margin_left;
|
|
|
|
|
int margin_right;
|
|
|
|
|
int margin_top;
|
|
|
|
|
int margin_bottom;
|
2014-03-17 20:08:35 +00:00
|
|
|
|
|
|
|
|
|
cairo_region_t *opaque_region;
|
2014-03-17 20:02:47 +00:00
|
|
|
|
cairo_region_t *input_region;
|
2011-01-06 21:51:12 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct _GdkWindowImplWaylandClass
|
|
|
|
|
{
|
|
|
|
|
GdkWindowImplClass parent_class;
|
|
|
|
|
};
|
|
|
|
|
|
2013-06-04 09:39:36 +00:00
|
|
|
|
static void gdk_wayland_window_configure (GdkWindow *window,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
int width,
|
2014-02-07 22:16:28 +00:00
|
|
|
|
int height);
|
2013-06-04 09:39:36 +00:00
|
|
|
|
|
2010-12-18 20:38:49 +00:00
|
|
|
|
G_DEFINE_TYPE (GdkWindowImplWayland, _gdk_window_impl_wayland, GDK_TYPE_WINDOW_IMPL)
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
_gdk_window_impl_wayland_init (GdkWindowImplWayland *impl)
|
2011-01-06 21:51:12 +00:00
|
|
|
|
{
|
2013-06-04 09:39:36 +00:00
|
|
|
|
impl->scale = 1;
|
2010-12-18 20:38:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-09-16 21:23:29 +00:00
|
|
|
|
/*
|
2012-01-29 12:15:12 +00:00
|
|
|
|
* gdk_wayland_window_update_size:
|
2010-12-18 20:38:49 +00:00
|
|
|
|
* @drawable: a #GdkDrawableImplWayland.
|
2013-09-16 21:23:29 +00:00
|
|
|
|
*
|
2010-12-18 20:38:49 +00:00
|
|
|
|
* Updates the state of the drawable (in particular the drawable's
|
|
|
|
|
* cairo surface) when its size has changed.
|
2013-09-16 21:23:29 +00:00
|
|
|
|
*/
|
2012-01-29 12:15:12 +00:00
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_window_update_size (GdkWindow *window,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
int32_t width,
|
2014-02-07 22:16:28 +00:00
|
|
|
|
int32_t height)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
2011-01-06 21:51:12 +00:00
|
|
|
|
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
2011-01-07 15:16:17 +00:00
|
|
|
|
GdkRectangle area;
|
|
|
|
|
cairo_region_t *region;
|
2010-12-18 20:38:49 +00:00
|
|
|
|
|
|
|
|
|
if (impl->cairo_surface)
|
|
|
|
|
{
|
|
|
|
|
cairo_surface_destroy (impl->cairo_surface);
|
|
|
|
|
impl->cairo_surface = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2011-02-11 03:37:51 +00:00
|
|
|
|
window->width = width;
|
|
|
|
|
window->height = height;
|
|
|
|
|
|
2011-01-07 15:16:17 +00:00
|
|
|
|
area.x = 0;
|
|
|
|
|
area.y = 0;
|
|
|
|
|
area.width = window->width;
|
|
|
|
|
area.height = window->height;
|
|
|
|
|
|
|
|
|
|
region = cairo_region_create_rectangle (&area);
|
|
|
|
|
_gdk_window_invalidate_for_expose (window, region);
|
|
|
|
|
cairo_region_destroy (region);
|
2010-12-18 20:38:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GdkWindow *
|
|
|
|
|
_gdk_wayland_screen_create_root_window (GdkScreen *screen,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
int width,
|
|
|
|
|
int height)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
|
|
|
|
GdkWindow *window;
|
|
|
|
|
GdkWindowImplWayland *impl;
|
|
|
|
|
|
|
|
|
|
window = _gdk_display_create_window (gdk_screen_get_display (screen));
|
|
|
|
|
window->impl = g_object_new (GDK_TYPE_WINDOW_IMPL_WAYLAND, NULL);
|
|
|
|
|
window->impl_window = window;
|
|
|
|
|
window->visual = gdk_screen_get_system_visual (screen);
|
|
|
|
|
|
|
|
|
|
impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
|
|
|
|
|
|
|
|
|
impl->wrapper = GDK_WINDOW (window);
|
2013-07-24 17:30:19 +00:00
|
|
|
|
if (gdk_screen_get_n_monitors(screen) > 0)
|
|
|
|
|
impl->scale = gdk_screen_get_monitor_scale_factor (screen, 0);
|
|
|
|
|
else
|
|
|
|
|
impl->scale = 1;
|
|
|
|
|
|
|
|
|
|
/* logical 1x1 fake buffer */
|
|
|
|
|
impl->cairo_surface =
|
|
|
|
|
cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
|
|
|
|
impl->scale,
|
|
|
|
|
impl->scale);
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_CAIRO_SURFACE_SET_DEVICE_SCALE
|
|
|
|
|
cairo_surface_set_device_scale (impl->cairo_surface, impl->scale, impl->scale);
|
|
|
|
|
#endif
|
2010-12-18 20:38:49 +00:00
|
|
|
|
|
|
|
|
|
window->window_type = GDK_WINDOW_ROOT;
|
|
|
|
|
window->depth = 32;
|
|
|
|
|
|
|
|
|
|
window->x = 0;
|
|
|
|
|
window->y = 0;
|
|
|
|
|
window->abs_x = 0;
|
|
|
|
|
window->abs_y = 0;
|
|
|
|
|
window->width = width;
|
|
|
|
|
window->height = height;
|
|
|
|
|
window->viewable = TRUE;
|
|
|
|
|
|
|
|
|
|
/* see init_randr_support() in gdkscreen-wayland.c */
|
|
|
|
|
window->event_mask = GDK_STRUCTURE_MASK;
|
|
|
|
|
|
|
|
|
|
return window;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const gchar *
|
|
|
|
|
get_default_title (void)
|
|
|
|
|
{
|
|
|
|
|
const char *title;
|
|
|
|
|
|
|
|
|
|
title = g_get_application_name ();
|
|
|
|
|
if (!title)
|
|
|
|
|
title = g_get_prgname ();
|
|
|
|
|
if (!title)
|
|
|
|
|
title = "";
|
|
|
|
|
|
|
|
|
|
return title;
|
|
|
|
|
}
|
|
|
|
|
|
2013-04-25 15:46:31 +00:00
|
|
|
|
static void
|
|
|
|
|
fill_presentation_time_from_frame_time (GdkFrameTimings *timings,
|
|
|
|
|
guint32 frame_time)
|
|
|
|
|
{
|
|
|
|
|
/* The timestamp in a wayland frame is a msec time value that in some
|
|
|
|
|
* way reflects the time at which the server started drawing the frame.
|
|
|
|
|
* This is not useful from our perspective.
|
|
|
|
|
*
|
|
|
|
|
* However, for the DRM backend of Weston, on reasonably recent
|
|
|
|
|
* Linux, we know that the time is the
|
2013-09-16 21:23:29 +00:00
|
|
|
|
* clock_gettime (CLOCK_MONOTONIC) value at the vblank, and that
|
2013-04-25 15:46:31 +00:00
|
|
|
|
* backend starts drawing immediately after receiving the vblank
|
|
|
|
|
* notification. If we detect this, and make the assumption that the
|
|
|
|
|
* compositor will finish drawing before the next vblank, we can
|
|
|
|
|
* then determine the presentation time as the frame time we
|
2013-09-16 21:23:29 +00:00
|
|
|
|
* received plus one refresh interval.
|
2013-04-25 15:46:31 +00:00
|
|
|
|
*
|
|
|
|
|
* If a backend is using clock_gettime(CLOCK_MONOTONIC), but not
|
|
|
|
|
* picking values right at the vblank, then the presentation times
|
|
|
|
|
* we compute won't be accurate, but not really worse than then
|
|
|
|
|
* the alternative of not providing presentation times at all.
|
|
|
|
|
*
|
|
|
|
|
* The complexity here is dealing with the fact that we receive
|
|
|
|
|
* only the low 32 bits of the CLOCK_MONOTONIC value in milliseconds.
|
|
|
|
|
*/
|
|
|
|
|
gint64 now_monotonic = g_get_monotonic_time ();
|
|
|
|
|
gint64 now_monotonic_msec = now_monotonic / 1000;
|
|
|
|
|
uint32_t now_monotonic_low = (uint32_t)now_monotonic_msec;
|
|
|
|
|
|
|
|
|
|
if (frame_time - now_monotonic_low < 1000 ||
|
|
|
|
|
frame_time - now_monotonic_low > (uint32_t)-1000)
|
|
|
|
|
{
|
|
|
|
|
/* Timestamp we received is within one second of the current time.
|
|
|
|
|
*/
|
|
|
|
|
gint64 last_frame_time = now_monotonic + (gint64)1000 * (gint32)(frame_time - now_monotonic_low);
|
|
|
|
|
if ((gint32)now_monotonic_low < 0 && (gint32)frame_time > 0)
|
|
|
|
|
last_frame_time += (gint64)1000 * G_GINT64_CONSTANT(0x100000000);
|
|
|
|
|
else if ((gint32)now_monotonic_low > 0 && (gint32)frame_time < 0)
|
|
|
|
|
last_frame_time -= (gint64)1000 * G_GINT64_CONSTANT(0x100000000);
|
|
|
|
|
|
|
|
|
|
timings->presentation_time = last_frame_time + timings->refresh_interval;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-04-24 22:14:22 +00:00
|
|
|
|
static void
|
|
|
|
|
frame_callback (void *data,
|
|
|
|
|
struct wl_callback *callback,
|
|
|
|
|
uint32_t time)
|
|
|
|
|
{
|
|
|
|
|
GdkWindow *window = data;
|
|
|
|
|
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
2013-04-25 15:19:31 +00:00
|
|
|
|
GdkWaylandDisplay *wayland_display = GDK_WAYLAND_DISPLAY (gdk_window_get_display (window));
|
2013-04-24 22:14:22 +00:00
|
|
|
|
GdkFrameClock *clock = gdk_window_get_frame_clock (window);
|
|
|
|
|
GdkFrameTimings *timings;
|
|
|
|
|
|
|
|
|
|
wl_callback_destroy (callback);
|
2014-01-31 21:39:33 +00:00
|
|
|
|
|
|
|
|
|
if (GDK_WINDOW_DESTROYED (window))
|
|
|
|
|
return;
|
|
|
|
|
|
2013-04-24 22:14:22 +00:00
|
|
|
|
_gdk_frame_clock_thaw (clock);
|
|
|
|
|
|
|
|
|
|
timings = gdk_frame_clock_get_timings (clock, impl->pending_frame_counter);
|
|
|
|
|
impl->pending_frame_counter = 0;
|
|
|
|
|
|
|
|
|
|
if (timings == NULL)
|
|
|
|
|
return;
|
|
|
|
|
|
2013-04-25 15:19:31 +00:00
|
|
|
|
timings->refresh_interval = 16667; /* default to 1/60th of a second */
|
|
|
|
|
if (impl->outputs)
|
|
|
|
|
{
|
|
|
|
|
/* We pick a random output out of the outputs that the window touches
|
|
|
|
|
* The rate here is in milli-hertz */
|
|
|
|
|
int refresh_rate = _gdk_wayland_screen_get_output_refresh_rate (wayland_display->screen,
|
|
|
|
|
impl->outputs->data);
|
|
|
|
|
if (refresh_rate != 0)
|
|
|
|
|
timings->refresh_interval = G_GINT64_CONSTANT(1000000000) / refresh_rate;
|
|
|
|
|
}
|
|
|
|
|
|
2013-04-25 15:46:31 +00:00
|
|
|
|
fill_presentation_time_from_frame_time (timings, time);
|
|
|
|
|
|
2013-04-24 22:14:22 +00:00
|
|
|
|
timings->complete = TRUE;
|
|
|
|
|
|
|
|
|
|
#ifdef G_ENABLE_DEBUG
|
|
|
|
|
if ((_gdk_debug_flags & GDK_DEBUG_FRAMES) != 0)
|
|
|
|
|
_gdk_frame_clock_debug_print_timings (clock, timings);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const struct wl_callback_listener listener = {
|
|
|
|
|
frame_callback
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
on_frame_clock_before_paint (GdkFrameClock *clock,
|
|
|
|
|
GdkWindow *window)
|
|
|
|
|
{
|
2013-04-25 15:46:31 +00:00
|
|
|
|
GdkFrameTimings *timings = gdk_frame_clock_get_current_timings (clock);
|
|
|
|
|
gint64 presentation_time;
|
|
|
|
|
gint64 refresh_interval;
|
|
|
|
|
|
|
|
|
|
gdk_frame_clock_get_refresh_info (clock,
|
|
|
|
|
timings->frame_time,
|
|
|
|
|
&refresh_interval, &presentation_time);
|
|
|
|
|
|
|
|
|
|
if (presentation_time != 0)
|
|
|
|
|
{
|
|
|
|
|
/* Assume the algorithm used by the DRM backend of Weston - it
|
|
|
|
|
* starts drawing at the next vblank after receiving the commit
|
|
|
|
|
* for this frame, and presentation occurs at the vblank
|
|
|
|
|
* after that.
|
|
|
|
|
*/
|
|
|
|
|
timings->predicted_presentation_time = presentation_time + refresh_interval;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* As above, but we don't actually know the phase of the vblank,
|
|
|
|
|
* so just assume that we're half way through a refresh cycle.
|
|
|
|
|
*/
|
|
|
|
|
timings->predicted_presentation_time = timings->frame_time + refresh_interval / 2 + refresh_interval;
|
|
|
|
|
}
|
2013-04-24 22:14:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
on_frame_clock_after_paint (GdkFrameClock *clock,
|
|
|
|
|
GdkWindow *window)
|
|
|
|
|
{
|
|
|
|
|
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
|
|
|
|
struct wl_callback *callback;
|
|
|
|
|
|
|
|
|
|
if (!impl->pending_commit)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
impl->pending_commit = FALSE;
|
|
|
|
|
impl->pending_frame_counter = gdk_frame_clock_get_frame_counter (clock);
|
|
|
|
|
|
|
|
|
|
callback = wl_surface_frame (impl->surface);
|
|
|
|
|
wl_callback_add_listener (callback, &listener, window);
|
|
|
|
|
_gdk_frame_clock_freeze (clock);
|
|
|
|
|
|
|
|
|
|
wl_surface_commit (impl->surface);
|
2014-02-23 18:57:24 +00:00
|
|
|
|
_gdk_wayland_shm_surface_set_busy (impl->cairo_surface);
|
2013-04-24 22:14:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-06-04 09:39:36 +00:00
|
|
|
|
static void
|
|
|
|
|
window_update_scale (GdkWindow *window)
|
|
|
|
|
{
|
|
|
|
|
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
|
|
|
|
GdkWaylandDisplay *wayland_display = GDK_WAYLAND_DISPLAY (gdk_window_get_display (window));
|
|
|
|
|
guint32 scale;
|
|
|
|
|
GSList *l;
|
|
|
|
|
|
2013-07-12 14:49:52 +00:00
|
|
|
|
if (wayland_display->compositor_version < WL_SURFACE_HAS_BUFFER_SCALE)
|
|
|
|
|
{
|
|
|
|
|
/* We can't set the scale on this surface */
|
|
|
|
|
impl->scale = 1;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2013-06-04 09:39:36 +00:00
|
|
|
|
scale = 1;
|
|
|
|
|
for (l = impl->outputs; l != NULL; l = l->next)
|
|
|
|
|
{
|
|
|
|
|
guint32 output_scale =
|
2013-09-16 21:23:29 +00:00
|
|
|
|
_gdk_wayland_screen_get_output_scale (wayland_display->screen,
|
|
|
|
|
l->data);
|
2013-06-04 09:39:36 +00:00
|
|
|
|
scale = MAX (scale, output_scale);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifndef HAVE_CAIRO_SURFACE_SET_DEVICE_SCALE
|
|
|
|
|
/* Don't announce a scale if we can't support it */
|
|
|
|
|
scale = 1;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if (scale != impl->scale)
|
|
|
|
|
{
|
|
|
|
|
impl->scale = scale;
|
|
|
|
|
|
|
|
|
|
/* Notify app that scale changed */
|
2014-02-07 22:16:28 +00:00
|
|
|
|
gdk_wayland_window_configure (window, window->width, window->height);
|
2013-06-04 09:39:36 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
on_monitors_changed (GdkScreen *screen,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
GdkWindow *window)
|
2013-06-04 09:39:36 +00:00
|
|
|
|
{
|
|
|
|
|
window_update_scale (window);
|
|
|
|
|
}
|
|
|
|
|
|
2013-07-03 15:19:39 +00:00
|
|
|
|
|
2013-09-16 21:23:29 +00:00
|
|
|
|
static void gdk_wayland_window_create_surface (GdkWindow *window);
|
2013-07-03 15:19:39 +00:00
|
|
|
|
|
2010-12-18 20:38:49 +00:00
|
|
|
|
void
|
|
|
|
|
_gdk_wayland_display_create_window_impl (GdkDisplay *display,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
GdkWindow *window,
|
|
|
|
|
GdkWindow *real_parent,
|
|
|
|
|
GdkScreen *screen,
|
|
|
|
|
GdkEventMask event_mask,
|
|
|
|
|
GdkWindowAttr *attributes,
|
|
|
|
|
gint attributes_mask)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
|
|
|
|
GdkWindowImplWayland *impl;
|
2013-04-24 22:14:22 +00:00
|
|
|
|
GdkFrameClock *frame_clock;
|
2010-12-18 20:38:49 +00:00
|
|
|
|
const char *title;
|
|
|
|
|
|
|
|
|
|
impl = g_object_new (GDK_TYPE_WINDOW_IMPL_WAYLAND, NULL);
|
|
|
|
|
window->impl = GDK_WINDOW_IMPL (impl);
|
|
|
|
|
impl->wrapper = GDK_WINDOW (window);
|
|
|
|
|
|
|
|
|
|
if (window->width > 65535 ||
|
|
|
|
|
window->height > 65535)
|
|
|
|
|
{
|
|
|
|
|
g_warning ("Native Windows wider or taller than 65535 pixels are not supported");
|
2011-01-06 20:23:52 +00:00
|
|
|
|
|
2010-12-18 20:38:49 +00:00
|
|
|
|
if (window->width > 65535)
|
2013-09-16 21:23:29 +00:00
|
|
|
|
window->width = 65535;
|
2010-12-18 20:38:49 +00:00
|
|
|
|
if (window->height > 65535)
|
2013-09-16 21:23:29 +00:00
|
|
|
|
window->height = 65535;
|
2010-12-18 20:38:49 +00:00
|
|
|
|
}
|
2011-01-06 20:23:52 +00:00
|
|
|
|
|
2010-12-18 20:38:49 +00:00
|
|
|
|
g_object_ref (window);
|
|
|
|
|
|
2013-06-04 09:39:36 +00:00
|
|
|
|
/* More likely to be right than just assuming 1 */
|
|
|
|
|
impl->scale = gdk_screen_get_monitor_scale_factor (screen, 0);
|
|
|
|
|
|
2013-03-16 23:57:17 +00:00
|
|
|
|
impl->title = NULL;
|
|
|
|
|
|
2010-12-18 20:38:49 +00:00
|
|
|
|
switch (GDK_WINDOW_TYPE (window))
|
|
|
|
|
{
|
|
|
|
|
case GDK_WINDOW_TOPLEVEL:
|
|
|
|
|
case GDK_WINDOW_TEMP:
|
|
|
|
|
if (attributes_mask & GDK_WA_TITLE)
|
2013-09-16 21:23:29 +00:00
|
|
|
|
title = attributes->title;
|
2010-12-18 20:38:49 +00:00
|
|
|
|
else
|
2013-09-16 21:23:29 +00:00
|
|
|
|
title = get_default_title ();
|
2010-12-18 20:38:49 +00:00
|
|
|
|
|
|
|
|
|
gdk_window_set_title (window, title);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GDK_WINDOW_CHILD:
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2013-07-03 15:19:39 +00:00
|
|
|
|
gdk_wayland_window_create_surface (window);
|
|
|
|
|
|
2010-12-18 20:38:49 +00:00
|
|
|
|
if (attributes_mask & GDK_WA_TYPE_HINT)
|
|
|
|
|
gdk_window_set_type_hint (window, attributes->type_hint);
|
2013-04-24 22:14:22 +00:00
|
|
|
|
|
|
|
|
|
frame_clock = gdk_window_get_frame_clock (window);
|
|
|
|
|
|
|
|
|
|
g_signal_connect (frame_clock, "before-paint",
|
|
|
|
|
G_CALLBACK (on_frame_clock_before_paint), window);
|
|
|
|
|
g_signal_connect (frame_clock, "after-paint",
|
|
|
|
|
G_CALLBACK (on_frame_clock_after_paint), window);
|
2013-06-04 09:39:36 +00:00
|
|
|
|
|
|
|
|
|
g_signal_connect (screen, "monitors-changed",
|
|
|
|
|
G_CALLBACK (on_monitors_changed), window);
|
2010-12-18 20:38:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
2011-01-08 01:49:40 +00:00
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_window_attach_image (GdkWindow *window)
|
|
|
|
|
{
|
2013-07-12 14:49:52 +00:00
|
|
|
|
GdkWaylandDisplay *display;
|
2011-01-08 01:49:40 +00:00
|
|
|
|
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
2010-12-18 20:38:49 +00:00
|
|
|
|
|
2011-01-08 01:49:40 +00:00
|
|
|
|
if (GDK_WINDOW_DESTROYED (window))
|
|
|
|
|
return;
|
|
|
|
|
|
2012-03-06 21:24:20 +00:00
|
|
|
|
/* Attach this new buffer to the surface */
|
2014-02-23 18:57:24 +00:00
|
|
|
|
wl_surface_attach (impl->surface,
|
|
|
|
|
_gdk_wayland_shm_surface_get_wl_buffer (impl->cairo_surface),
|
2014-04-11 23:53:05 +00:00
|
|
|
|
0, 0);
|
2013-07-12 14:49:52 +00:00
|
|
|
|
|
|
|
|
|
/* Only set the buffer scale if supported by the compositor */
|
|
|
|
|
display = GDK_WAYLAND_DISPLAY (gdk_window_get_display (window));
|
|
|
|
|
if (display->compositor_version >= WL_SURFACE_HAS_BUFFER_SCALE)
|
2014-02-23 18:57:24 +00:00
|
|
|
|
wl_surface_set_buffer_scale (impl->surface, impl->scale);
|
2013-06-04 09:39:36 +00:00
|
|
|
|
|
2013-04-24 22:14:22 +00:00
|
|
|
|
impl->pending_commit = TRUE;
|
2010-12-18 20:38:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-04-24 22:00:41 +00:00
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_window_ensure_cairo_surface (GdkWindow *window)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
|
|
|
|
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
|
|
|
|
if (!impl->cairo_surface)
|
|
|
|
|
{
|
2014-02-23 18:57:24 +00:00
|
|
|
|
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_window_get_display (impl->wrapper));
|
|
|
|
|
|
|
|
|
|
impl->cairo_surface = _gdk_wayland_display_create_shm_surface (display_wayland,
|
|
|
|
|
impl->wrapper->width,
|
|
|
|
|
impl->wrapper->height,
|
|
|
|
|
impl->scale);
|
2010-12-18 20:38:49 +00:00
|
|
|
|
}
|
2013-04-24 22:00:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Unlike other backends the Cairo surface is not just a cheap wrapper
|
|
|
|
|
* around some other backing. It is the buffer itself.
|
|
|
|
|
*/
|
|
|
|
|
static cairo_surface_t *
|
|
|
|
|
gdk_wayland_window_ref_cairo_surface (GdkWindow *window)
|
|
|
|
|
{
|
|
|
|
|
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
|
|
|
|
|
|
|
|
|
if (GDK_WINDOW_DESTROYED (impl->wrapper))
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
gdk_wayland_window_ensure_cairo_surface (window);
|
2011-01-08 01:49:40 +00:00
|
|
|
|
|
|
|
|
|
cairo_surface_reference (impl->cairo_surface);
|
2010-12-18 20:38:49 +00:00
|
|
|
|
|
|
|
|
|
return impl->cairo_surface;
|
|
|
|
|
}
|
|
|
|
|
|
2013-07-03 14:03:25 +00:00
|
|
|
|
static cairo_surface_t *
|
|
|
|
|
gdk_wayland_window_create_similar_image_surface (GdkWindow * window,
|
|
|
|
|
cairo_format_t format,
|
|
|
|
|
int width,
|
|
|
|
|
int height)
|
|
|
|
|
{
|
|
|
|
|
return cairo_image_surface_create (format, width, height);
|
|
|
|
|
}
|
2012-04-04 13:05:27 +00:00
|
|
|
|
|
2013-04-29 19:49:12 +00:00
|
|
|
|
static gboolean
|
2013-09-16 21:23:29 +00:00
|
|
|
|
gdk_window_impl_wayland_begin_paint_region (GdkWindow *window,
|
|
|
|
|
const cairo_region_t *region)
|
2013-04-29 19:49:12 +00:00
|
|
|
|
{
|
|
|
|
|
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
|
|
|
|
gdk_wayland_window_ensure_cairo_surface (window);
|
2014-02-23 18:57:24 +00:00
|
|
|
|
return _gdk_wayland_shm_surface_get_busy (impl->cairo_surface);
|
2013-04-29 19:49:12 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-04-04 13:05:27 +00:00
|
|
|
|
static void
|
|
|
|
|
gdk_window_impl_wayland_finalize (GObject *object)
|
|
|
|
|
{
|
|
|
|
|
GdkWindowImplWayland *impl;
|
|
|
|
|
|
|
|
|
|
g_return_if_fail (GDK_IS_WINDOW_IMPL_WAYLAND (object));
|
|
|
|
|
|
|
|
|
|
impl = GDK_WINDOW_IMPL_WAYLAND (object);
|
|
|
|
|
|
2013-08-21 11:09:29 +00:00
|
|
|
|
g_free (impl->title);
|
|
|
|
|
|
2014-03-17 20:08:35 +00:00
|
|
|
|
g_clear_pointer (&impl->opaque_region, cairo_region_destroy);
|
2014-03-17 20:02:47 +00:00
|
|
|
|
g_clear_pointer (&impl->input_region, cairo_region_destroy);
|
2014-03-17 20:08:35 +00:00
|
|
|
|
|
2012-04-04 13:05:27 +00:00
|
|
|
|
G_OBJECT_CLASS (_gdk_window_impl_wayland_parent_class)->finalize (object);
|
|
|
|
|
}
|
|
|
|
|
|
2012-01-30 14:04:45 +00:00
|
|
|
|
static void
|
2012-01-29 12:15:12 +00:00
|
|
|
|
gdk_wayland_window_configure (GdkWindow *window,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
int width,
|
2014-02-07 22:16:28 +00:00
|
|
|
|
int height)
|
2012-01-29 12:15:12 +00:00
|
|
|
|
{
|
|
|
|
|
GdkDisplay *display;
|
|
|
|
|
GdkEvent *event;
|
|
|
|
|
|
|
|
|
|
display = gdk_window_get_display (window);
|
|
|
|
|
|
2013-06-04 09:39:36 +00:00
|
|
|
|
/* TODO: Only generate a configure event if width/height/scale have actually
|
2012-01-29 12:15:12 +00:00
|
|
|
|
* changed?
|
|
|
|
|
*/
|
|
|
|
|
event = gdk_event_new (GDK_CONFIGURE);
|
|
|
|
|
event->configure.window = window;
|
|
|
|
|
event->configure.send_event = FALSE;
|
|
|
|
|
event->configure.width = width;
|
|
|
|
|
event->configure.height = height;
|
|
|
|
|
|
2014-02-07 22:16:28 +00:00
|
|
|
|
gdk_wayland_window_update_size (window, width, height);
|
2013-05-14 14:25:30 +00:00
|
|
|
|
_gdk_window_update_size (window);
|
2012-01-29 12:15:12 +00:00
|
|
|
|
|
|
|
|
|
g_object_ref(window);
|
|
|
|
|
|
|
|
|
|
_gdk_wayland_display_deliver_event (display, event);
|
|
|
|
|
}
|
|
|
|
|
|
2011-02-11 22:20:14 +00:00
|
|
|
|
static void
|
2014-04-11 23:55:37 +00:00
|
|
|
|
gdk_wayland_window_sync_parent (GdkWindow *window)
|
2011-02-11 22:20:14 +00:00
|
|
|
|
{
|
|
|
|
|
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
2014-04-11 23:55:37 +00:00
|
|
|
|
struct wl_surface *parent_surface;
|
2012-07-11 18:18:37 +00:00
|
|
|
|
|
2013-11-11 23:02:19 +00:00
|
|
|
|
if (!impl->xdg_surface)
|
|
|
|
|
return;
|
2013-02-07 11:27:25 +00:00
|
|
|
|
|
2013-11-19 17:36:12 +00:00
|
|
|
|
if (impl->transient_for)
|
|
|
|
|
{
|
|
|
|
|
GdkWindowImplWayland *impl_parent = GDK_WINDOW_IMPL_WAYLAND (impl->transient_for->impl);
|
|
|
|
|
|
|
|
|
|
/* XXX: Is this correct? */
|
|
|
|
|
if (!impl_parent->surface)
|
|
|
|
|
return;
|
|
|
|
|
|
2014-04-11 23:55:37 +00:00
|
|
|
|
parent_surface = impl_parent->surface;
|
2013-11-19 17:36:12 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
2014-04-11 23:55:37 +00:00
|
|
|
|
parent_surface = NULL;
|
2013-02-07 11:27:25 +00:00
|
|
|
|
|
2014-04-11 23:55:37 +00:00
|
|
|
|
xdg_surface_set_parent (impl->xdg_surface, parent_surface);
|
2011-02-11 22:20:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-11-21 17:03:18 +00:00
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_window_sync_title (GdkWindow *window)
|
|
|
|
|
{
|
|
|
|
|
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
|
|
|
|
|
|
|
|
|
if (!impl->xdg_surface)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (!impl->title)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
xdg_surface_set_title (impl->xdg_surface, impl->title);
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-27 21:54:20 +00:00
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_window_sync_margin (GdkWindow *window)
|
|
|
|
|
{
|
|
|
|
|
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
|
|
|
|
|
|
|
|
|
if (!impl->xdg_surface)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
xdg_surface_set_margin (impl->xdg_surface,
|
|
|
|
|
impl->margin_left,
|
|
|
|
|
impl->margin_right,
|
|
|
|
|
impl->margin_top,
|
|
|
|
|
impl->margin_bottom);
|
|
|
|
|
}
|
|
|
|
|
|
2014-03-17 20:08:35 +00:00
|
|
|
|
static struct wl_region *
|
|
|
|
|
wl_region_from_cairo_region (GdkWaylandDisplay *display,
|
|
|
|
|
cairo_region_t *region)
|
|
|
|
|
{
|
|
|
|
|
struct wl_region *wl_region;
|
|
|
|
|
int i, n_rects;
|
|
|
|
|
|
|
|
|
|
wl_region = wl_compositor_create_region (display->compositor);
|
|
|
|
|
if (wl_region == NULL)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
n_rects = cairo_region_num_rectangles (region);
|
|
|
|
|
for (i = 0; i < n_rects; i++)
|
|
|
|
|
{
|
|
|
|
|
cairo_rectangle_int_t rect;
|
|
|
|
|
cairo_region_get_rectangle (region, i, &rect);
|
|
|
|
|
wl_region_add (wl_region, rect.x, rect.y, rect.width, rect.height);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return wl_region;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_window_sync_opaque_region (GdkWindow *window)
|
|
|
|
|
{
|
|
|
|
|
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
|
|
|
|
struct wl_region *wl_region = NULL;
|
|
|
|
|
|
|
|
|
|
if (!impl->surface)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (impl->opaque_region != NULL)
|
|
|
|
|
wl_region = wl_region_from_cairo_region (GDK_WAYLAND_DISPLAY (gdk_window_get_display (window)),
|
|
|
|
|
impl->opaque_region);
|
|
|
|
|
|
|
|
|
|
wl_surface_set_opaque_region (impl->surface, wl_region);
|
|
|
|
|
|
|
|
|
|
if (wl_region != NULL)
|
|
|
|
|
wl_region_destroy (wl_region);
|
|
|
|
|
}
|
|
|
|
|
|
2014-03-17 20:02:47 +00:00
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_window_sync_input_region (GdkWindow *window)
|
|
|
|
|
{
|
|
|
|
|
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
|
|
|
|
struct wl_region *wl_region = NULL;
|
|
|
|
|
|
|
|
|
|
if (!impl->surface)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (impl->input_region != NULL)
|
|
|
|
|
wl_region = wl_region_from_cairo_region (GDK_WAYLAND_DISPLAY (gdk_window_get_display (window)),
|
|
|
|
|
impl->input_region);
|
|
|
|
|
|
|
|
|
|
wl_surface_set_input_region (impl->surface, wl_region);
|
|
|
|
|
|
|
|
|
|
if (wl_region != NULL)
|
|
|
|
|
wl_region_destroy (wl_region);
|
|
|
|
|
}
|
|
|
|
|
|
2013-04-25 15:19:31 +00:00
|
|
|
|
static void
|
2013-09-16 21:23:29 +00:00
|
|
|
|
surface_enter (void *data,
|
2013-04-25 15:19:31 +00:00
|
|
|
|
struct wl_surface *wl_surface,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
struct wl_output *output)
|
2013-04-25 15:19:31 +00:00
|
|
|
|
{
|
|
|
|
|
GdkWindow *window = GDK_WINDOW (data);
|
|
|
|
|
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
|
|
|
|
|
|
|
|
|
impl->outputs = g_slist_prepend (impl->outputs, output);
|
2013-06-04 09:39:36 +00:00
|
|
|
|
|
|
|
|
|
window_update_scale (window);
|
2013-04-25 15:19:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2013-09-16 21:23:29 +00:00
|
|
|
|
surface_leave (void *data,
|
2013-04-25 15:19:31 +00:00
|
|
|
|
struct wl_surface *wl_surface,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
struct wl_output *output)
|
2013-04-25 15:19:31 +00:00
|
|
|
|
{
|
|
|
|
|
GdkWindow *window = GDK_WINDOW (data);
|
|
|
|
|
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
|
|
|
|
|
|
|
|
|
impl->outputs = g_slist_remove (impl->outputs, output);
|
2013-06-04 09:39:36 +00:00
|
|
|
|
|
|
|
|
|
window_update_scale (window);
|
2013-04-25 15:19:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-11-11 23:02:19 +00:00
|
|
|
|
static const struct wl_surface_listener surface_listener = {
|
|
|
|
|
surface_enter,
|
|
|
|
|
surface_leave
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_window_create_surface (GdkWindow *window)
|
|
|
|
|
{
|
|
|
|
|
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
|
|
|
|
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_window_get_display (window));
|
|
|
|
|
|
|
|
|
|
impl->surface = wl_compositor_create_surface (display_wayland->compositor);
|
|
|
|
|
wl_surface_set_user_data (impl->surface, window);
|
2014-03-17 20:08:35 +00:00
|
|
|
|
wl_surface_add_listener (impl->surface, &surface_listener, window);
|
|
|
|
|
|
|
|
|
|
gdk_wayland_window_sync_opaque_region (window);
|
2014-03-17 20:02:47 +00:00
|
|
|
|
gdk_wayland_window_sync_input_region (window);
|
2013-11-11 23:02:19 +00:00
|
|
|
|
}
|
2013-06-04 09:39:36 +00:00
|
|
|
|
|
2013-11-11 23:02:19 +00:00
|
|
|
|
static void
|
|
|
|
|
xdg_surface_configure (void *data,
|
|
|
|
|
struct xdg_surface *xdg_surface,
|
|
|
|
|
int32_t width,
|
2014-04-12 00:31:27 +00:00
|
|
|
|
int32_t height,
|
|
|
|
|
struct wl_array *states,
|
|
|
|
|
uint32_t serial)
|
2011-12-05 15:55:37 +00:00
|
|
|
|
{
|
|
|
|
|
GdkWindow *window = GDK_WINDOW (data);
|
2012-01-09 17:15:00 +00:00
|
|
|
|
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
2014-04-12 00:31:27 +00:00
|
|
|
|
GdkWindowState new_state = 0;
|
|
|
|
|
uint32_t *p;
|
2011-12-05 15:55:37 +00:00
|
|
|
|
|
2014-04-12 00:31:27 +00:00
|
|
|
|
if (width > 0 && height > 0)
|
2014-02-09 16:39:01 +00:00
|
|
|
|
{
|
2014-04-12 00:31:27 +00:00
|
|
|
|
gdk_window_constrain_size (&impl->geometry_hints,
|
|
|
|
|
impl->geometry_mask,
|
|
|
|
|
width,
|
|
|
|
|
height,
|
|
|
|
|
&width,
|
|
|
|
|
&height);
|
|
|
|
|
|
|
|
|
|
gdk_wayland_window_configure (window, width, height);
|
2014-02-09 16:39:01 +00:00
|
|
|
|
}
|
2013-12-07 18:19:59 +00:00
|
|
|
|
|
2014-04-12 00:31:27 +00:00
|
|
|
|
wl_array_for_each(p, states)
|
|
|
|
|
{
|
|
|
|
|
uint32_t state = *p;
|
|
|
|
|
switch (state)
|
|
|
|
|
{
|
|
|
|
|
case XDG_SURFACE_STATE_FULLSCREEN:
|
|
|
|
|
new_state |= GDK_WINDOW_STATE_FULLSCREEN;
|
|
|
|
|
break;
|
|
|
|
|
case XDG_SURFACE_STATE_MAXIMIZED:
|
|
|
|
|
new_state |= GDK_WINDOW_STATE_MAXIMIZED;
|
|
|
|
|
break;
|
|
|
|
|
case XDG_SURFACE_STATE_ACTIVATED:
|
|
|
|
|
new_state |= GDK_WINDOW_STATE_FOCUSED;
|
|
|
|
|
break;
|
|
|
|
|
case XDG_SURFACE_STATE_RESIZING:
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
/* Unknown state */
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-02-06 19:28:51 +00:00
|
|
|
|
|
2014-04-12 00:31:27 +00:00
|
|
|
|
_gdk_set_window_state (window, new_state);
|
2014-05-13 20:21:11 +00:00
|
|
|
|
xdg_surface_ack_configure (xdg_surface, serial);
|
2014-02-06 19:28:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-02-07 22:16:40 +00:00
|
|
|
|
static void
|
2014-04-17 17:14:44 +00:00
|
|
|
|
xdg_surface_close (void *data,
|
|
|
|
|
struct xdg_surface *xdg_surface)
|
2014-02-07 22:16:40 +00:00
|
|
|
|
{
|
|
|
|
|
GdkWindow *window = GDK_WINDOW (data);
|
|
|
|
|
GdkDisplay *display;
|
|
|
|
|
GdkEvent *event;
|
|
|
|
|
|
|
|
|
|
display = gdk_window_get_display (window);
|
|
|
|
|
|
|
|
|
|
event = gdk_event_new (GDK_DELETE);
|
|
|
|
|
|
|
|
|
|
event->any.window = window;
|
|
|
|
|
event->any.send_event = TRUE;
|
|
|
|
|
|
|
|
|
|
_gdk_wayland_display_deliver_event (display, event);
|
|
|
|
|
}
|
|
|
|
|
|
2013-11-11 23:02:19 +00:00
|
|
|
|
static const struct xdg_surface_listener xdg_surface_listener = {
|
|
|
|
|
xdg_surface_configure,
|
2014-04-17 17:14:44 +00:00
|
|
|
|
xdg_surface_close,
|
2013-11-11 23:02:19 +00:00
|
|
|
|
};
|
|
|
|
|
|
2012-07-11 13:15:04 +00:00
|
|
|
|
static void
|
2013-11-11 23:02:19 +00:00
|
|
|
|
gdk_wayland_window_create_xdg_surface (GdkWindow *window)
|
2012-07-11 13:15:04 +00:00
|
|
|
|
{
|
2013-11-11 23:02:19 +00:00
|
|
|
|
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_window_get_display (window));
|
|
|
|
|
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
|
|
|
|
|
|
|
|
|
impl->xdg_surface = xdg_shell_get_xdg_surface (display_wayland->xdg_shell, impl->surface);
|
|
|
|
|
xdg_surface_add_listener (impl->xdg_surface, &xdg_surface_listener, window);
|
2013-11-21 17:03:18 +00:00
|
|
|
|
|
2014-04-11 23:55:37 +00:00
|
|
|
|
gdk_wayland_window_sync_parent (window);
|
2013-11-21 17:03:18 +00:00
|
|
|
|
gdk_wayland_window_sync_title (window);
|
2014-02-27 21:54:20 +00:00
|
|
|
|
gdk_wayland_window_sync_margin (window);
|
2013-11-21 17:03:18 +00:00
|
|
|
|
xdg_surface_set_app_id (impl->xdg_surface, gdk_get_program_class ());
|
2013-11-11 23:02:19 +00:00
|
|
|
|
}
|
2012-07-11 16:09:23 +00:00
|
|
|
|
|
2013-11-11 23:02:19 +00:00
|
|
|
|
static void
|
|
|
|
|
xdg_popup_done (void *data,
|
|
|
|
|
struct xdg_popup *xdg_popup,
|
|
|
|
|
uint32_t serial)
|
|
|
|
|
{
|
|
|
|
|
GdkWindow *window = GDK_WINDOW (data);
|
|
|
|
|
|
|
|
|
|
gdk_window_hide (window);
|
|
|
|
|
}
|
2013-04-25 15:19:31 +00:00
|
|
|
|
|
2013-11-11 23:02:19 +00:00
|
|
|
|
static const struct xdg_popup_listener xdg_popup_listener = {
|
|
|
|
|
xdg_popup_done,
|
2011-12-05 15:55:37 +00:00
|
|
|
|
};
|
|
|
|
|
|
2014-03-17 19:25:23 +00:00
|
|
|
|
/**
|
|
|
|
|
* gdk_wayland_window_get_fake_root_coords:
|
|
|
|
|
* @window: A #GdkWindow
|
|
|
|
|
* @x_out: (out): The X offset of this window
|
|
|
|
|
* @y_out: (out): The Y offset of this window
|
|
|
|
|
*
|
|
|
|
|
* Wayland does not have a global coordinate space shared between
|
|
|
|
|
* surfaces. In fact, for regular toplevels, we have no idea where
|
|
|
|
|
* our surfaces are positioned, relatively.
|
|
|
|
|
*
|
|
|
|
|
* However, there are some cases like popups and subsurfaces where
|
|
|
|
|
* we do have some amount of control over the placement of our
|
|
|
|
|
* window, and we can semi-accurately control the x/y position of
|
|
|
|
|
* these windows, if they are relative to another surface.
|
|
|
|
|
*
|
|
|
|
|
* GTK+ loves to position "relative" popups like menus in root
|
|
|
|
|
* window coordinates, since it was built for display servers that
|
|
|
|
|
* have queryable absolute coordinate spaces. In these cases, GTK+
|
|
|
|
|
* might ask for the root coordinates of a widget window, add a
|
|
|
|
|
* few values, and then call gdk_window_move() with that absolute
|
|
|
|
|
* value.
|
|
|
|
|
*
|
|
|
|
|
* In Wayland, we have to "reverse-engineer" this use, and figure
|
|
|
|
|
* out the root coordinates from the relative position, and the
|
|
|
|
|
* relative position from the root coordinates.
|
|
|
|
|
*
|
|
|
|
|
* We invent a coordinate space called the "fake root coordinate"
|
|
|
|
|
* space in which a toplevel is always at 0,0, and all popups are
|
|
|
|
|
* relative to that space.
|
|
|
|
|
*
|
|
|
|
|
* gdk_wayland_window_get_fake_root_coords() gives you the
|
|
|
|
|
* position of a #GdkWindow in "fake root" coordinates.
|
|
|
|
|
*/
|
2014-03-10 17:30:21 +00:00
|
|
|
|
static void
|
2014-03-17 19:25:23 +00:00
|
|
|
|
gdk_wayland_window_get_fake_root_coords (GdkWindow *window,
|
|
|
|
|
gint *x_out,
|
|
|
|
|
gint *y_out)
|
2014-03-10 17:31:53 +00:00
|
|
|
|
{
|
|
|
|
|
gint x_offset = 0, y_offset = 0;
|
|
|
|
|
|
2014-03-17 19:27:13 +00:00
|
|
|
|
while (window)
|
2014-03-10 17:31:53 +00:00
|
|
|
|
{
|
2014-03-17 19:27:13 +00:00
|
|
|
|
GdkWindowImplWayland *impl;
|
2014-03-10 17:31:53 +00:00
|
|
|
|
|
|
|
|
|
x_offset += window->x;
|
|
|
|
|
y_offset += window->y;
|
|
|
|
|
|
2014-03-17 19:27:13 +00:00
|
|
|
|
impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
|
|
|
|
window = impl->transient_for;
|
2014-03-10 17:31:53 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*x_out = x_offset;
|
|
|
|
|
*y_out = y_offset;
|
|
|
|
|
}
|
2014-03-10 17:30:21 +00:00
|
|
|
|
|
2013-04-25 15:11:02 +00:00
|
|
|
|
static void
|
2013-11-11 23:02:19 +00:00
|
|
|
|
gdk_wayland_window_create_xdg_popup (GdkWindow *window,
|
2014-03-10 17:30:21 +00:00
|
|
|
|
GdkWindow *parent,
|
2013-11-11 23:02:19 +00:00
|
|
|
|
struct wl_seat *seat,
|
|
|
|
|
uint32_t flags)
|
2013-04-25 15:11:02 +00:00
|
|
|
|
{
|
|
|
|
|
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_window_get_display (window));
|
2013-11-11 23:02:19 +00:00
|
|
|
|
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
2014-03-10 17:30:21 +00:00
|
|
|
|
GdkWindowImplWayland *parent_impl = GDK_WINDOW_IMPL_WAYLAND (parent->impl);
|
2013-11-11 23:02:19 +00:00
|
|
|
|
GdkWaylandDeviceData *device;
|
2014-03-10 17:30:21 +00:00
|
|
|
|
int x, y;
|
|
|
|
|
int parent_x, parent_y;
|
2013-04-25 15:11:02 +00:00
|
|
|
|
|
2013-11-11 23:02:19 +00:00
|
|
|
|
if (!impl->surface)
|
|
|
|
|
return;
|
2013-04-25 15:11:02 +00:00
|
|
|
|
|
2014-03-10 17:30:21 +00:00
|
|
|
|
if (!parent_impl->surface)
|
2013-11-11 23:02:19 +00:00
|
|
|
|
return;
|
2013-08-30 11:55:37 +00:00
|
|
|
|
|
2013-11-11 23:02:19 +00:00
|
|
|
|
device = wl_seat_get_user_data (seat);
|
|
|
|
|
|
2014-03-17 19:25:23 +00:00
|
|
|
|
gdk_wayland_window_get_fake_root_coords (parent, &parent_x, &parent_y);
|
2014-03-10 17:30:21 +00:00
|
|
|
|
|
|
|
|
|
x = window->x - parent_x;
|
|
|
|
|
y = window->y - parent_y;
|
|
|
|
|
|
2013-11-11 23:02:19 +00:00
|
|
|
|
impl->xdg_popup = xdg_shell_get_xdg_popup (display_wayland->xdg_shell,
|
|
|
|
|
impl->surface,
|
2014-03-10 17:30:21 +00:00
|
|
|
|
parent_impl->surface,
|
2013-11-11 23:02:19 +00:00
|
|
|
|
seat,
|
|
|
|
|
_gdk_wayland_device_get_button_press_serial (device),
|
2014-03-10 17:30:21 +00:00
|
|
|
|
x, y, flags);
|
2013-11-11 23:02:19 +00:00
|
|
|
|
|
|
|
|
|
xdg_popup_add_listener (impl->xdg_popup, &xdg_popup_listener, window);
|
|
|
|
|
}
|
|
|
|
|
|
2014-05-15 21:12:09 +00:00
|
|
|
|
static struct wl_seat *
|
|
|
|
|
find_grab_input_seat (GdkWindow *window, GdkWindow *transient_for)
|
|
|
|
|
{
|
wayland: Fix GtkMenuButton popups in a terrible, hacky way
Since you can't take grabs on unmapped windows, GtkMenu takes a grab on
the menu in a convoluted way: it first grabs another window, shows the
menu window, and then transfers the grab over to the GtkMenu widget.
For normal menubars, this is perfectly fine, as the first window it grabs
is our toplevel, and that gets picked up in our transient path. For
GtkMenuButton or other spurious uses of gtk_menu_popup, it creates a new
temporary input-only window which it takes the grab on, known as the "grab
transfer window". Since this window isn't a transient-for of our new menu
widget window, the grab isn't noticed when we go to show it, and thus the
menu ends up as a new toplevel.
Add a special hack to GtkMenu and the Wayland backend which lets us notice
this "grab transfer window", and include it in our grab finding path.
It's sort of terrible to have to hack up the widgets instead of just the
backend, but the alternative would be an entirely new window type which is
managed correctly by GDK. I don't want to write that.
2014-05-15 21:20:00 +00:00
|
|
|
|
GdkWindow *attached_grab_window;
|
2014-05-15 21:12:09 +00:00
|
|
|
|
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
|
|
|
|
GdkWindowImplWayland *tmp_impl;
|
|
|
|
|
|
|
|
|
|
/* Use the device that was used for the grab as the device for
|
|
|
|
|
* the popup window setup - so this relies on GTK+ taking the
|
|
|
|
|
* grab before showing the popup window.
|
|
|
|
|
*/
|
2014-05-15 21:14:26 +00:00
|
|
|
|
if (impl->grab_input_seat)
|
|
|
|
|
return impl->grab_input_seat;
|
2014-05-15 21:12:09 +00:00
|
|
|
|
|
wayland: Fix GtkMenuButton popups in a terrible, hacky way
Since you can't take grabs on unmapped windows, GtkMenu takes a grab on
the menu in a convoluted way: it first grabs another window, shows the
menu window, and then transfers the grab over to the GtkMenu widget.
For normal menubars, this is perfectly fine, as the first window it grabs
is our toplevel, and that gets picked up in our transient path. For
GtkMenuButton or other spurious uses of gtk_menu_popup, it creates a new
temporary input-only window which it takes the grab on, known as the "grab
transfer window". Since this window isn't a transient-for of our new menu
widget window, the grab isn't noticed when we go to show it, and thus the
menu ends up as a new toplevel.
Add a special hack to GtkMenu and the Wayland backend which lets us notice
this "grab transfer window", and include it in our grab finding path.
It's sort of terrible to have to hack up the widgets instead of just the
backend, but the alternative would be an entirely new window type which is
managed correctly by GDK. I don't want to write that.
2014-05-15 21:20:00 +00:00
|
|
|
|
/* HACK: GtkMenu grabs a special window known as the "grab transfer window"
|
|
|
|
|
* and then transfers the grab over to the correct window later. Look for
|
|
|
|
|
* this window when taking the grab to know it's correct.
|
|
|
|
|
*
|
|
|
|
|
* See: associate_menu_grab_transfer_window in gtkmenu.c
|
|
|
|
|
*/
|
|
|
|
|
attached_grab_window = g_object_get_data (G_OBJECT (window), "gdk-attached-grab-window");
|
|
|
|
|
if (attached_grab_window)
|
|
|
|
|
{
|
|
|
|
|
tmp_impl = GDK_WINDOW_IMPL_WAYLAND (attached_grab_window->impl);
|
|
|
|
|
if (tmp_impl->grab_input_seat)
|
|
|
|
|
return tmp_impl->grab_input_seat;
|
|
|
|
|
}
|
|
|
|
|
|
2014-05-15 21:14:26 +00:00
|
|
|
|
while (transient_for)
|
2014-05-15 21:12:09 +00:00
|
|
|
|
{
|
2014-05-15 21:14:26 +00:00
|
|
|
|
tmp_impl = GDK_WINDOW_IMPL_WAYLAND (transient_for->impl);
|
2014-05-15 21:12:09 +00:00
|
|
|
|
|
2014-05-15 21:14:26 +00:00
|
|
|
|
if (tmp_impl->grab_input_seat)
|
|
|
|
|
return tmp_impl->grab_input_seat;
|
|
|
|
|
|
|
|
|
|
transient_for = tmp_impl->transient_for;
|
2014-05-15 21:12:09 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-05-15 21:14:26 +00:00
|
|
|
|
return NULL;
|
2014-05-15 21:12:09 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-11-11 23:02:19 +00:00
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_window_map (GdkWindow *window)
|
|
|
|
|
{
|
|
|
|
|
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
|
|
|
|
GdkWindow *transient_for;
|
|
|
|
|
|
|
|
|
|
if (!impl->mapped && !impl->use_custom_surface)
|
|
|
|
|
{
|
|
|
|
|
/* Popup menus can appear without a transient parent, which means they
|
|
|
|
|
* cannot be positioned properly on Wayland. This attempts to guess the
|
|
|
|
|
* surface they should be positioned with by finding the surface beneath
|
|
|
|
|
* the device that created the grab for the popup window
|
|
|
|
|
*/
|
|
|
|
|
if (!impl->transient_for && impl->hint == GDK_WINDOW_TYPE_HINT_POPUP_MENU)
|
|
|
|
|
{
|
|
|
|
|
transient_for = gdk_device_get_window_at_position (impl->grab_device, NULL, NULL);
|
|
|
|
|
transient_for = gdk_window_get_toplevel (transient_for);
|
|
|
|
|
|
|
|
|
|
/* start the popup at the position of the device that holds the grab */
|
|
|
|
|
gdk_window_get_device_position (transient_for,
|
|
|
|
|
impl->grab_device,
|
|
|
|
|
&window->x, &window->y, NULL);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
transient_for = impl->transient_for;
|
|
|
|
|
|
|
|
|
|
if (transient_for)
|
|
|
|
|
{
|
2014-05-15 21:12:09 +00:00
|
|
|
|
struct wl_seat *grab_input_seat = find_grab_input_seat (window, transient_for);
|
2013-11-11 23:02:19 +00:00
|
|
|
|
if (grab_input_seat &&
|
|
|
|
|
(impl->hint == GDK_WINDOW_TYPE_HINT_POPUP_MENU ||
|
|
|
|
|
impl->hint == GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU ||
|
|
|
|
|
impl->hint == GDK_WINDOW_TYPE_HINT_COMBO))
|
|
|
|
|
{
|
2014-03-10 17:30:21 +00:00
|
|
|
|
gdk_wayland_window_create_xdg_popup (window, transient_for, grab_input_seat, 0);
|
2013-11-11 23:02:19 +00:00
|
|
|
|
goto mapped;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gdk_wayland_window_create_xdg_surface (window);
|
|
|
|
|
|
|
|
|
|
mapped:
|
|
|
|
|
impl->mapped = TRUE;
|
|
|
|
|
}
|
2013-04-25 15:11:02 +00:00
|
|
|
|
}
|
|
|
|
|
|
2010-12-18 20:38:49 +00:00
|
|
|
|
static void
|
2013-09-16 21:23:29 +00:00
|
|
|
|
gdk_wayland_window_show (GdkWindow *window,
|
|
|
|
|
gboolean already_mapped)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
|
|
|
|
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
|
|
|
|
|
2013-03-20 15:38:36 +00:00
|
|
|
|
if (!impl->surface)
|
2013-04-25 15:11:02 +00:00
|
|
|
|
gdk_wayland_window_create_surface (window);
|
2010-12-18 20:38:49 +00:00
|
|
|
|
|
2014-04-22 23:16:48 +00:00
|
|
|
|
gdk_wayland_window_map (window);
|
|
|
|
|
|
2010-12-18 20:38:49 +00:00
|
|
|
|
_gdk_make_event (window, GDK_MAP, NULL, FALSE);
|
2011-02-11 03:21:08 +00:00
|
|
|
|
|
|
|
|
|
if (impl->cairo_surface)
|
|
|
|
|
gdk_wayland_window_attach_image (window);
|
2010-12-18 20:38:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2013-04-25 15:11:02 +00:00
|
|
|
|
gdk_wayland_window_hide_surface (GdkWindow *window,
|
|
|
|
|
gboolean is_destroy)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
|
|
|
|
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
|
|
|
|
|
|
|
|
|
if (impl->surface)
|
|
|
|
|
{
|
2013-09-16 22:39:55 +00:00
|
|
|
|
if (!is_destroy)
|
2013-03-20 15:38:36 +00:00
|
|
|
|
{
|
|
|
|
|
wl_surface_attach (impl->surface, NULL, 0, 0);
|
|
|
|
|
wl_surface_commit (impl->surface);
|
|
|
|
|
}
|
2013-09-16 22:38:48 +00:00
|
|
|
|
else
|
2013-03-20 15:38:36 +00:00
|
|
|
|
{
|
2013-09-16 21:23:29 +00:00
|
|
|
|
wl_surface_destroy (impl->surface);
|
2013-03-20 15:38:36 +00:00
|
|
|
|
impl->surface = NULL;
|
2013-04-25 15:19:31 +00:00
|
|
|
|
|
|
|
|
|
g_slist_free (impl->outputs);
|
|
|
|
|
impl->outputs = NULL;
|
2013-03-20 15:38:36 +00:00
|
|
|
|
}
|
2013-09-16 22:38:15 +00:00
|
|
|
|
|
2013-11-11 23:02:19 +00:00
|
|
|
|
if (impl->xdg_surface)
|
2013-09-16 22:38:15 +00:00
|
|
|
|
{
|
2013-11-11 23:02:19 +00:00
|
|
|
|
xdg_surface_destroy (impl->xdg_surface);
|
|
|
|
|
impl->xdg_surface = NULL;
|
|
|
|
|
}
|
|
|
|
|
else if (impl->xdg_popup)
|
|
|
|
|
{
|
|
|
|
|
xdg_popup_destroy (impl->xdg_popup);
|
|
|
|
|
impl->xdg_popup = NULL;
|
2013-09-16 22:38:15 +00:00
|
|
|
|
}
|
2010-12-18 20:38:49 +00:00
|
|
|
|
}
|
2013-09-16 22:36:18 +00:00
|
|
|
|
|
|
|
|
|
impl->mapped = FALSE;
|
2013-04-25 15:11:02 +00:00
|
|
|
|
}
|
2010-12-18 20:38:49 +00:00
|
|
|
|
|
2013-04-25 15:11:02 +00:00
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_window_hide (GdkWindow *window)
|
|
|
|
|
{
|
|
|
|
|
gdk_wayland_window_hide_surface (window, FALSE);
|
2010-12-18 20:38:49 +00:00
|
|
|
|
_gdk_window_clear_update_area (window);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_window_wayland_withdraw (GdkWindow *window)
|
|
|
|
|
{
|
|
|
|
|
if (!window->destroyed)
|
|
|
|
|
{
|
|
|
|
|
if (GDK_WINDOW_IS_MAPPED (window))
|
2013-09-16 21:23:29 +00:00
|
|
|
|
gdk_synthesize_window_state (window, 0, GDK_WINDOW_STATE_WITHDRAWN);
|
2010-12-18 20:38:49 +00:00
|
|
|
|
|
|
|
|
|
g_assert (!GDK_WINDOW_IS_MAPPED (window));
|
|
|
|
|
|
2013-04-25 15:11:02 +00:00
|
|
|
|
gdk_wayland_window_hide_surface (window, FALSE);
|
2010-12-18 20:38:49 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_window_wayland_set_events (GdkWindow *window,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
GdkEventMask event_mask)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
|
|
|
|
GDK_WINDOW (window)->event_mask = event_mask;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static GdkEventMask
|
|
|
|
|
gdk_window_wayland_get_events (GdkWindow *window)
|
|
|
|
|
{
|
|
|
|
|
if (GDK_WINDOW_DESTROYED (window))
|
|
|
|
|
return 0;
|
|
|
|
|
else
|
|
|
|
|
return GDK_WINDOW (window)->event_mask;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_window_wayland_raise (GdkWindow *window)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_window_wayland_lower (GdkWindow *window)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_window_wayland_restack_under (GdkWindow *window,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
GList *native_siblings)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_window_wayland_restack_toplevel (GdkWindow *window,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
GdkWindow *sibling,
|
|
|
|
|
gboolean above)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_window_wayland_move_resize (GdkWindow *window,
|
2012-04-20 16:57:33 +00:00
|
|
|
|
gboolean with_move,
|
|
|
|
|
gint x,
|
|
|
|
|
gint y,
|
|
|
|
|
gint width,
|
|
|
|
|
gint height)
|
|
|
|
|
{
|
|
|
|
|
if (with_move)
|
|
|
|
|
{
|
|
|
|
|
window->x = x;
|
|
|
|
|
window->y = y;
|
|
|
|
|
}
|
2010-12-18 20:38:49 +00:00
|
|
|
|
|
2012-01-17 14:59:03 +00:00
|
|
|
|
/* If this function is called with width and height = -1 then that means
|
|
|
|
|
* just move the window - don't update its size
|
|
|
|
|
*/
|
|
|
|
|
if (width > 0 && height > 0)
|
2014-02-07 22:16:28 +00:00
|
|
|
|
gdk_wayland_window_configure (window, width, height);
|
2010-12-18 20:38:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2013-09-16 21:23:29 +00:00
|
|
|
|
gdk_window_wayland_set_background (GdkWindow *window,
|
|
|
|
|
cairo_pattern_t *pattern)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
gdk_window_wayland_reparent (GdkWindow *window,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
GdkWindow *new_parent,
|
|
|
|
|
gint x,
|
|
|
|
|
gint y)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_window_wayland_set_device_cursor (GdkWindow *window,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
GdkDevice *device,
|
|
|
|
|
GdkCursor *cursor)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
|
|
|
|
g_return_if_fail (GDK_IS_WINDOW (window));
|
|
|
|
|
g_return_if_fail (GDK_IS_DEVICE (device));
|
|
|
|
|
|
|
|
|
|
if (!GDK_WINDOW_DESTROYED (window))
|
|
|
|
|
GDK_DEVICE_GET_CLASS (device)->set_window_cursor (device, window, cursor);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_window_wayland_get_geometry (GdkWindow *window,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
gint *x,
|
|
|
|
|
gint *y,
|
|
|
|
|
gint *width,
|
|
|
|
|
gint *height)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
|
|
|
|
if (!GDK_WINDOW_DESTROYED (window))
|
|
|
|
|
{
|
|
|
|
|
if (x)
|
2013-09-16 21:23:29 +00:00
|
|
|
|
*x = window->x;
|
2010-12-18 20:38:49 +00:00
|
|
|
|
if (y)
|
2013-09-16 21:23:29 +00:00
|
|
|
|
*y = window->y;
|
2010-12-18 20:38:49 +00:00
|
|
|
|
if (width)
|
2013-09-16 21:23:29 +00:00
|
|
|
|
*width = window->width;
|
2010-12-18 20:38:49 +00:00
|
|
|
|
if (height)
|
2013-09-16 21:23:29 +00:00
|
|
|
|
*height = window->height;
|
2010-12-18 20:38:49 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-28 01:58:13 +00:00
|
|
|
|
static void
|
2010-12-18 20:38:49 +00:00
|
|
|
|
gdk_window_wayland_get_root_coords (GdkWindow *window,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
gint x,
|
|
|
|
|
gint y,
|
|
|
|
|
gint *root_x,
|
|
|
|
|
gint *root_y)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
2012-04-23 16:26:49 +00:00
|
|
|
|
gint x_offset, y_offset;
|
|
|
|
|
|
2014-03-17 19:25:23 +00:00
|
|
|
|
gdk_wayland_window_get_fake_root_coords (window, &x_offset, &y_offset);
|
2012-04-23 16:26:49 +00:00
|
|
|
|
|
2013-08-30 07:23:56 +00:00
|
|
|
|
if (root_x)
|
|
|
|
|
*root_x = x_offset + x;
|
|
|
|
|
|
|
|
|
|
if (root_y)
|
|
|
|
|
*root_y = y_offset + y;
|
2010-12-18 20:38:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
gdk_window_wayland_get_device_state (GdkWindow *window,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
GdkDevice *device,
|
|
|
|
|
gdouble *x,
|
|
|
|
|
gdouble *y,
|
|
|
|
|
GdkModifierType *mask)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
|
|
|
|
gboolean return_val;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), FALSE);
|
|
|
|
|
|
|
|
|
|
return_val = TRUE;
|
|
|
|
|
|
|
|
|
|
if (!GDK_WINDOW_DESTROYED (window))
|
|
|
|
|
{
|
|
|
|
|
GdkWindow *child;
|
|
|
|
|
|
|
|
|
|
GDK_DEVICE_GET_CLASS (device)->query_state (device, window,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
NULL, &child,
|
|
|
|
|
NULL, NULL,
|
|
|
|
|
x, y, mask);
|
2010-12-18 20:38:49 +00:00
|
|
|
|
return_val = (child != NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return return_val;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2013-09-16 21:23:29 +00:00
|
|
|
|
gdk_window_wayland_shape_combine_region (GdkWindow *window,
|
|
|
|
|
const cairo_region_t *shape_region,
|
|
|
|
|
gint offset_x,
|
|
|
|
|
gint offset_y)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-16 21:23:29 +00:00
|
|
|
|
static void
|
|
|
|
|
gdk_window_wayland_input_shape_combine_region (GdkWindow *window,
|
|
|
|
|
const cairo_region_t *shape_region,
|
|
|
|
|
gint offset_x,
|
|
|
|
|
gint offset_y)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
2014-03-17 20:02:47 +00:00
|
|
|
|
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
|
|
|
|
|
|
|
|
|
if (GDK_WINDOW_DESTROYED (window))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
g_clear_pointer (&impl->input_region, cairo_region_destroy);
|
|
|
|
|
impl->input_region = cairo_region_copy (shape_region);
|
|
|
|
|
cairo_region_translate (impl->input_region, offset_x, offset_y);
|
|
|
|
|
gdk_wayland_window_sync_input_region (window);
|
2010-12-18 20:38:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
gdk_window_wayland_set_static_gravities (GdkWindow *window,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
gboolean use_static)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
2013-09-16 21:23:29 +00:00
|
|
|
|
gdk_wayland_window_queue_antiexpose (GdkWindow *window,
|
|
|
|
|
cairo_region_t *area)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_window_destroy (GdkWindow *window,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
gboolean recursing,
|
|
|
|
|
gboolean foreign_destroy)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
|
|
|
|
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
|
|
|
|
|
|
|
|
|
g_return_if_fail (GDK_IS_WINDOW (window));
|
|
|
|
|
|
2013-04-25 15:11:02 +00:00
|
|
|
|
/* We don't have nested windows */
|
|
|
|
|
g_return_if_fail (!recursing);
|
|
|
|
|
/* Wayland windows can't be externally destroyed; we may possibly
|
2013-09-16 21:23:29 +00:00
|
|
|
|
* eventually want to use this path at display close-down
|
|
|
|
|
*/
|
2013-04-25 15:11:02 +00:00
|
|
|
|
g_return_if_fail (!foreign_destroy);
|
|
|
|
|
|
|
|
|
|
gdk_wayland_window_hide_surface (window, TRUE);
|
|
|
|
|
|
2010-12-18 20:38:49 +00:00
|
|
|
|
if (impl->cairo_surface)
|
2014-02-23 18:57:24 +00:00
|
|
|
|
cairo_surface_finish (impl->cairo_surface);
|
2010-12-18 20:38:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_window_wayland_destroy_foreign (GdkWindow *window)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-25 23:02:04 +00:00
|
|
|
|
static gboolean
|
2010-12-18 20:38:49 +00:00
|
|
|
|
gdk_window_wayland_resize_cairo_surface (GdkWindow *window,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
cairo_surface_t *surface,
|
|
|
|
|
gint width,
|
|
|
|
|
gint height)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
2014-02-22 18:10:59 +00:00
|
|
|
|
/* cairo image surfaces cannot be resized */
|
2014-02-25 23:02:04 +00:00
|
|
|
|
return FALSE;
|
2010-12-18 20:38:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static cairo_region_t *
|
|
|
|
|
gdk_wayland_window_get_shape (GdkWindow *window)
|
|
|
|
|
{
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static cairo_region_t *
|
|
|
|
|
gdk_wayland_window_get_input_shape (GdkWindow *window)
|
|
|
|
|
{
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_window_focus (GdkWindow *window,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
guint32 timestamp)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2013-09-16 21:23:29 +00:00
|
|
|
|
gdk_wayland_window_set_type_hint (GdkWindow *window,
|
|
|
|
|
GdkWindowTypeHint hint)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
2012-01-13 14:48:46 +00:00
|
|
|
|
GdkWindowImplWayland *impl;
|
|
|
|
|
|
|
|
|
|
impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
|
|
|
|
|
2010-12-18 20:38:49 +00:00
|
|
|
|
if (GDK_WINDOW_DESTROYED (window))
|
|
|
|
|
return;
|
|
|
|
|
|
2012-01-13 14:48:46 +00:00
|
|
|
|
impl->hint = hint;
|
2010-12-18 20:38:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static GdkWindowTypeHint
|
|
|
|
|
gdk_wayland_window_get_type_hint (GdkWindow *window)
|
|
|
|
|
{
|
|
|
|
|
return GDK_WINDOW_TYPE_HINT_NORMAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
gdk_wayland_window_set_modal_hint (GdkWindow *window,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
gboolean modal)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_window_set_skip_taskbar_hint (GdkWindow *window,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
gboolean skips_taskbar)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_window_set_skip_pager_hint (GdkWindow *window,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
gboolean skips_pager)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_window_set_urgency_hint (GdkWindow *window,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
gboolean urgent)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_window_set_geometry_hints (GdkWindow *window,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
const GdkGeometry *geometry,
|
|
|
|
|
GdkWindowHints geom_mask)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
2012-01-09 17:11:22 +00:00
|
|
|
|
GdkWindowImplWayland *impl;
|
|
|
|
|
|
2010-12-18 20:38:49 +00:00
|
|
|
|
if (GDK_WINDOW_DESTROYED (window) ||
|
|
|
|
|
!WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
|
|
|
|
|
return;
|
|
|
|
|
|
2012-01-09 17:11:22 +00:00
|
|
|
|
impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
|
|
|
|
|
|
|
|
|
impl->geometry_hints = *geometry;
|
|
|
|
|
impl->geometry_mask = geom_mask;
|
|
|
|
|
|
2010-12-18 20:38:49 +00:00
|
|
|
|
/*
|
|
|
|
|
* GDK_HINT_POS
|
|
|
|
|
* GDK_HINT_USER_POS
|
|
|
|
|
* GDK_HINT_USER_SIZE
|
|
|
|
|
* GDK_HINT_MIN_SIZE
|
|
|
|
|
* GDK_HINT_MAX_SIZE
|
|
|
|
|
* GDK_HINT_BASE_SIZE
|
|
|
|
|
* GDK_HINT_RESIZE_INC
|
|
|
|
|
* GDK_HINT_ASPECT
|
|
|
|
|
* GDK_HINT_WIN_GRAVITY
|
|
|
|
|
*/
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_window_set_title (GdkWindow *window,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
const gchar *title)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
2013-03-16 23:57:17 +00:00
|
|
|
|
GdkWindowImplWayland *impl;
|
2010-12-18 20:38:49 +00:00
|
|
|
|
g_return_if_fail (title != NULL);
|
|
|
|
|
|
|
|
|
|
if (GDK_WINDOW_DESTROYED (window))
|
|
|
|
|
return;
|
2013-03-16 23:57:17 +00:00
|
|
|
|
|
|
|
|
|
impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
|
|
|
|
|
2013-08-21 11:09:29 +00:00
|
|
|
|
g_free (impl->title);
|
|
|
|
|
impl->title = g_strdup (title);
|
2013-11-21 17:03:18 +00:00
|
|
|
|
|
|
|
|
|
gdk_wayland_window_sync_title (window);
|
2010-12-18 20:38:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_window_set_role (GdkWindow *window,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
const gchar *role)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_window_set_startup_id (GdkWindow *window,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
const gchar *startup_id)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_window_set_transient_for (GdkWindow *window,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
GdkWindow *parent)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
2011-02-11 22:20:14 +00:00
|
|
|
|
GdkWindowImplWayland *impl;
|
|
|
|
|
|
|
|
|
|
impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
|
|
|
|
impl->transient_for = parent;
|
2013-11-11 23:02:19 +00:00
|
|
|
|
|
2014-04-11 23:55:37 +00:00
|
|
|
|
gdk_wayland_window_sync_parent (window);
|
2010-12-18 20:38:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_window_get_frame_extents (GdkWindow *window,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
GdkRectangle *rect)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
2014-03-17 19:41:08 +00:00
|
|
|
|
gdk_wayland_window_get_fake_root_coords (window, &rect->x, &rect->y);
|
2010-12-18 20:38:49 +00:00
|
|
|
|
rect->width = window->width;
|
|
|
|
|
rect->height = window->height;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_window_set_override_redirect (GdkWindow *window,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
gboolean override_redirect)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_window_set_accept_focus (GdkWindow *window,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
gboolean accept_focus)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_window_set_focus_on_map (GdkWindow *window,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
gboolean focus_on_map)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_window_set_icon_list (GdkWindow *window,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
GList *pixbufs)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_window_set_icon_name (GdkWindow *window,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
const gchar *name)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
|
|
|
|
if (GDK_WINDOW_DESTROYED (window))
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_window_iconify (GdkWindow *window)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_window_deiconify (GdkWindow *window)
|
|
|
|
|
{
|
|
|
|
|
if (GDK_WINDOW_DESTROYED (window) ||
|
|
|
|
|
!WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (GDK_WINDOW_IS_MAPPED (window))
|
2013-09-16 21:23:29 +00:00
|
|
|
|
gdk_window_show (window);
|
2010-12-18 20:38:49 +00:00
|
|
|
|
else
|
2013-09-16 21:23:29 +00:00
|
|
|
|
/* Flip our client side flag, the real work happens on map. */
|
|
|
|
|
gdk_synthesize_window_state (window, GDK_WINDOW_STATE_ICONIFIED, 0);
|
2010-12-18 20:38:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_window_stick (GdkWindow *window)
|
|
|
|
|
{
|
|
|
|
|
if (GDK_WINDOW_DESTROYED (window))
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_window_unstick (GdkWindow *window)
|
|
|
|
|
{
|
|
|
|
|
if (GDK_WINDOW_DESTROYED (window))
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_window_maximize (GdkWindow *window)
|
|
|
|
|
{
|
2013-11-11 23:02:19 +00:00
|
|
|
|
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
2013-03-16 23:34:57 +00:00
|
|
|
|
|
2013-11-11 23:02:19 +00:00
|
|
|
|
if (GDK_WINDOW_DESTROYED (window))
|
2010-12-18 20:38:49 +00:00
|
|
|
|
return;
|
2013-03-16 23:34:57 +00:00
|
|
|
|
|
2013-11-11 23:02:19 +00:00
|
|
|
|
if (!impl->xdg_surface)
|
|
|
|
|
return;
|
2013-03-16 23:34:57 +00:00
|
|
|
|
|
2014-04-12 00:31:27 +00:00
|
|
|
|
xdg_surface_set_maximized (impl->xdg_surface);
|
2010-12-18 20:38:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_window_unmaximize (GdkWindow *window)
|
|
|
|
|
{
|
2013-11-11 23:02:19 +00:00
|
|
|
|
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
2013-03-16 23:34:57 +00:00
|
|
|
|
|
2013-11-11 23:02:19 +00:00
|
|
|
|
if (GDK_WINDOW_DESTROYED (window))
|
2010-12-18 20:38:49 +00:00
|
|
|
|
return;
|
2013-03-16 23:34:57 +00:00
|
|
|
|
|
2013-11-11 23:02:19 +00:00
|
|
|
|
if (!impl->xdg_surface)
|
|
|
|
|
return;
|
2013-03-19 19:52:49 +00:00
|
|
|
|
|
2014-04-12 00:31:27 +00:00
|
|
|
|
xdg_surface_unset_maximized (impl->xdg_surface);
|
2010-12-18 20:38:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_window_fullscreen (GdkWindow *window)
|
|
|
|
|
{
|
2013-01-29 18:40:02 +00:00
|
|
|
|
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
|
|
|
|
|
2010-12-18 20:38:49 +00:00
|
|
|
|
if (GDK_WINDOW_DESTROYED (window))
|
|
|
|
|
return;
|
2013-01-29 18:40:02 +00:00
|
|
|
|
|
2013-11-11 23:02:19 +00:00
|
|
|
|
if (!impl->xdg_surface)
|
2013-03-20 15:38:36 +00:00
|
|
|
|
return;
|
|
|
|
|
|
2014-04-12 00:31:27 +00:00
|
|
|
|
xdg_surface_set_fullscreen (impl->xdg_surface, NULL);
|
2010-12-18 20:38:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_window_unfullscreen (GdkWindow *window)
|
|
|
|
|
{
|
2013-01-29 18:40:02 +00:00
|
|
|
|
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
|
|
|
|
|
2010-12-18 20:38:49 +00:00
|
|
|
|
if (GDK_WINDOW_DESTROYED (window))
|
|
|
|
|
return;
|
2013-01-29 18:40:02 +00:00
|
|
|
|
|
2013-11-11 23:02:19 +00:00
|
|
|
|
if (!impl->xdg_surface)
|
2013-03-20 15:38:36 +00:00
|
|
|
|
return;
|
|
|
|
|
|
2014-04-12 00:31:27 +00:00
|
|
|
|
xdg_surface_unset_fullscreen (impl->xdg_surface);
|
2010-12-18 20:38:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2014-03-17 19:42:43 +00:00
|
|
|
|
gdk_wayland_window_set_keep_above (GdkWindow *window, gboolean setting)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_window_set_keep_below (GdkWindow *window, gboolean setting)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static GdkWindow *
|
|
|
|
|
gdk_wayland_window_get_group (GdkWindow *window)
|
|
|
|
|
{
|
|
|
|
|
if (GDK_WINDOW_DESTROYED (window) ||
|
|
|
|
|
!WINDOW_IS_TOPLEVEL (window))
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_window_set_group (GdkWindow *window,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
GdkWindow *leader)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
|
|
|
|
g_return_if_fail (GDK_IS_WINDOW (window));
|
|
|
|
|
g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
|
|
|
|
|
g_return_if_fail (leader == NULL || GDK_IS_WINDOW (leader));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2013-09-16 21:23:29 +00:00
|
|
|
|
gdk_wayland_window_set_decorations (GdkWindow *window,
|
|
|
|
|
GdkWMDecoration decorations)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
gdk_wayland_window_get_decorations (GdkWindow *window,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
GdkWMDecoration *decorations)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2013-09-16 21:23:29 +00:00
|
|
|
|
gdk_wayland_window_set_functions (GdkWindow *window,
|
|
|
|
|
GdkWMFunction functions)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_window_begin_resize_drag (GdkWindow *window,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
GdkWindowEdge edge,
|
2011-11-05 05:12:26 +00:00
|
|
|
|
GdkDevice *device,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
gint button,
|
|
|
|
|
gint root_x,
|
|
|
|
|
gint root_y,
|
|
|
|
|
guint32 timestamp)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
|
|
|
|
GdkWindowImplWayland *impl;
|
2012-07-11 16:10:40 +00:00
|
|
|
|
GdkWaylandDisplay *wayland_display =
|
|
|
|
|
GDK_WAYLAND_DISPLAY (gdk_window_get_display (window));
|
|
|
|
|
|
2014-02-07 22:16:28 +00:00
|
|
|
|
uint32_t resize_edges;
|
2010-12-18 20:38:49 +00:00
|
|
|
|
|
|
|
|
|
if (GDK_WINDOW_DESTROYED (window) ||
|
|
|
|
|
!WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
switch (edge)
|
|
|
|
|
{
|
|
|
|
|
case GDK_WINDOW_EDGE_NORTH_WEST:
|
2014-02-07 22:16:28 +00:00
|
|
|
|
resize_edges = XDG_SURFACE_RESIZE_EDGE_TOP_LEFT;
|
2010-12-18 20:38:49 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GDK_WINDOW_EDGE_NORTH:
|
2014-02-07 22:16:28 +00:00
|
|
|
|
resize_edges = XDG_SURFACE_RESIZE_EDGE_TOP;
|
2010-12-18 20:38:49 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GDK_WINDOW_EDGE_NORTH_EAST:
|
2014-03-21 22:22:46 +00:00
|
|
|
|
resize_edges = XDG_SURFACE_RESIZE_EDGE_TOP_RIGHT;
|
2010-12-18 20:38:49 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GDK_WINDOW_EDGE_WEST:
|
2014-02-07 22:16:28 +00:00
|
|
|
|
resize_edges = XDG_SURFACE_RESIZE_EDGE_LEFT;
|
2010-12-18 20:38:49 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GDK_WINDOW_EDGE_EAST:
|
2014-02-07 22:16:28 +00:00
|
|
|
|
resize_edges = XDG_SURFACE_RESIZE_EDGE_RIGHT;
|
2010-12-18 20:38:49 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GDK_WINDOW_EDGE_SOUTH_WEST:
|
2014-02-07 22:16:28 +00:00
|
|
|
|
resize_edges = XDG_SURFACE_RESIZE_EDGE_BOTTOM_LEFT;
|
2010-12-18 20:38:49 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GDK_WINDOW_EDGE_SOUTH:
|
2014-02-07 22:16:28 +00:00
|
|
|
|
resize_edges = XDG_SURFACE_RESIZE_EDGE_BOTTOM;
|
2010-12-18 20:38:49 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GDK_WINDOW_EDGE_SOUTH_EAST:
|
2014-02-07 22:16:28 +00:00
|
|
|
|
resize_edges = XDG_SURFACE_RESIZE_EDGE_BOTTOM_RIGHT;
|
2010-12-18 20:38:49 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
2013-09-16 21:23:29 +00:00
|
|
|
|
g_warning ("gdk_window_begin_resize_drag: bad resize edge %d!", edge);
|
2010-12-18 20:38:49 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
|
|
|
|
|
2013-11-11 23:02:19 +00:00
|
|
|
|
if (!impl->xdg_surface)
|
2013-03-20 15:38:36 +00:00
|
|
|
|
return;
|
2013-09-16 21:23:29 +00:00
|
|
|
|
|
2013-11-11 23:02:19 +00:00
|
|
|
|
xdg_surface_resize (impl->xdg_surface,
|
|
|
|
|
gdk_wayland_device_get_wl_seat (device),
|
|
|
|
|
_gdk_wayland_display_get_serial (wayland_display),
|
2014-02-07 22:16:28 +00:00
|
|
|
|
resize_edges);
|
2012-01-06 16:49:22 +00:00
|
|
|
|
|
2012-01-09 16:00:14 +00:00
|
|
|
|
/* This is needed since Wayland will absorb all the pointer events after the
|
|
|
|
|
* above function - FIXME: Is this always safe..?
|
2012-01-06 16:49:22 +00:00
|
|
|
|
*/
|
2012-01-09 16:00:14 +00:00
|
|
|
|
gdk_device_ungrab (device, timestamp);
|
2010-12-18 20:38:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_window_begin_move_drag (GdkWindow *window,
|
2011-11-05 05:12:26 +00:00
|
|
|
|
GdkDevice *device,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
gint button,
|
|
|
|
|
gint root_x,
|
|
|
|
|
gint root_y,
|
|
|
|
|
guint32 timestamp)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
|
|
|
|
GdkWindowImplWayland *impl;
|
2012-07-11 16:10:40 +00:00
|
|
|
|
GdkWaylandDisplay *wayland_display =
|
|
|
|
|
GDK_WAYLAND_DISPLAY (gdk_window_get_display (window));
|
2010-12-18 20:38:49 +00:00
|
|
|
|
|
|
|
|
|
if (GDK_WINDOW_DESTROYED (window) ||
|
|
|
|
|
!WINDOW_IS_TOPLEVEL (window))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
|
|
|
|
|
2013-11-11 23:02:19 +00:00
|
|
|
|
if (!impl->xdg_surface)
|
2013-03-20 15:38:36 +00:00
|
|
|
|
return;
|
|
|
|
|
|
2013-11-11 23:02:19 +00:00
|
|
|
|
xdg_surface_move (impl->xdg_surface,
|
|
|
|
|
gdk_wayland_device_get_wl_seat (device),
|
|
|
|
|
_gdk_wayland_display_get_serial (wayland_display));
|
2012-01-09 16:00:14 +00:00
|
|
|
|
|
|
|
|
|
/* This is needed since Wayland will absorb all the pointer events after the
|
|
|
|
|
* above function - FIXME: Is this always safe..?
|
|
|
|
|
*/
|
|
|
|
|
gdk_device_ungrab (device, timestamp);
|
2010-12-18 20:38:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_window_set_opacity (GdkWindow *window,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
gdouble opacity)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_window_set_composited (GdkWindow *window,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
gboolean composited)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_window_destroy_notify (GdkWindow *window)
|
|
|
|
|
{
|
|
|
|
|
if (!GDK_WINDOW_DESTROYED (window))
|
|
|
|
|
{
|
2013-09-16 21:23:29 +00:00
|
|
|
|
if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
|
|
|
|
|
g_warning ("GdkWindow %p unexpectedly destroyed", window);
|
2010-12-18 20:38:49 +00:00
|
|
|
|
|
|
|
|
|
_gdk_window_destroy (window, TRUE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_object_unref (window);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2012-04-04 16:20:13 +00:00
|
|
|
|
gdk_wayland_window_process_updates_recurse (GdkWindow *window,
|
|
|
|
|
cairo_region_t *region)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
|
|
|
|
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
|
|
|
|
cairo_rectangle_int_t rect;
|
|
|
|
|
int i, n;
|
|
|
|
|
|
2013-04-24 22:00:41 +00:00
|
|
|
|
gdk_wayland_window_ensure_cairo_surface (window);
|
|
|
|
|
gdk_wayland_window_attach_image (window);
|
2011-02-11 03:04:26 +00:00
|
|
|
|
|
2013-04-23 18:39:48 +00:00
|
|
|
|
_gdk_window_process_updates_recurse (window, region);
|
|
|
|
|
|
2013-09-16 21:23:29 +00:00
|
|
|
|
n = cairo_region_num_rectangles (region);
|
2010-12-18 20:38:49 +00:00
|
|
|
|
for (i = 0; i < n; i++)
|
|
|
|
|
{
|
|
|
|
|
cairo_region_get_rectangle (region, i, &rect);
|
|
|
|
|
wl_surface_damage (impl->surface,
|
2012-04-04 16:20:13 +00:00
|
|
|
|
rect.x, rect.y, rect.width, rect.height);
|
2013-04-24 22:14:22 +00:00
|
|
|
|
impl->pending_commit = TRUE;
|
2010-12-18 20:38:49 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_window_sync_rendering (GdkWindow *window)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
2013-09-16 21:23:29 +00:00
|
|
|
|
gdk_wayland_window_simulate_key (GdkWindow *window,
|
|
|
|
|
gint x,
|
|
|
|
|
gint y,
|
|
|
|
|
guint keyval,
|
|
|
|
|
GdkModifierType modifiers,
|
|
|
|
|
GdkEventType key_pressrelease)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
2013-09-16 21:23:29 +00:00
|
|
|
|
gdk_wayland_window_simulate_button (GdkWindow *window,
|
|
|
|
|
gint x,
|
|
|
|
|
gint y,
|
|
|
|
|
guint button,
|
|
|
|
|
GdkModifierType modifiers,
|
|
|
|
|
GdkEventType button_pressrelease)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
gdk_wayland_window_get_property (GdkWindow *window,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
GdkAtom property,
|
|
|
|
|
GdkAtom type,
|
|
|
|
|
gulong offset,
|
|
|
|
|
gulong length,
|
|
|
|
|
gint pdelete,
|
|
|
|
|
GdkAtom *actual_property_type,
|
|
|
|
|
gint *actual_format_type,
|
|
|
|
|
gint *actual_length,
|
|
|
|
|
guchar **data)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_window_change_property (GdkWindow *window,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
GdkAtom property,
|
|
|
|
|
GdkAtom type,
|
|
|
|
|
gint format,
|
|
|
|
|
GdkPropMode mode,
|
|
|
|
|
const guchar *data,
|
|
|
|
|
gint nelements)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_window_delete_property (GdkWindow *window,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
GdkAtom property)
|
2010-12-18 20:38:49 +00:00
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2013-06-04 09:39:36 +00:00
|
|
|
|
static gint
|
|
|
|
|
gdk_wayland_window_get_scale_factor (GdkWindow *window)
|
|
|
|
|
{
|
|
|
|
|
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
|
|
|
|
|
|
|
|
|
if (GDK_WINDOW_DESTROYED (window))
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
return impl->scale;
|
|
|
|
|
}
|
|
|
|
|
|
2013-05-14 20:23:33 +00:00
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_window_set_opaque_region (GdkWindow *window,
|
|
|
|
|
cairo_region_t *region)
|
|
|
|
|
{
|
|
|
|
|
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
|
|
|
|
|
|
|
|
|
if (GDK_WINDOW_DESTROYED (window))
|
|
|
|
|
return;
|
|
|
|
|
|
2014-03-17 20:08:35 +00:00
|
|
|
|
g_clear_pointer (&impl->opaque_region, cairo_region_destroy);
|
|
|
|
|
impl->opaque_region = cairo_region_reference (region);
|
|
|
|
|
gdk_wayland_window_sync_opaque_region (window);
|
2013-05-14 20:23:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-02-07 22:20:14 +00:00
|
|
|
|
static void
|
|
|
|
|
gdk_wayland_window_set_shadow_width (GdkWindow *window,
|
|
|
|
|
int left,
|
|
|
|
|
int right,
|
|
|
|
|
int top,
|
|
|
|
|
int bottom)
|
|
|
|
|
{
|
|
|
|
|
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
|
|
|
|
|
|
|
|
|
if (GDK_WINDOW_DESTROYED (window))
|
|
|
|
|
return;
|
|
|
|
|
|
2014-02-27 21:54:20 +00:00
|
|
|
|
impl->margin_left = left;
|
|
|
|
|
impl->margin_right = right;
|
|
|
|
|
impl->margin_top = top;
|
|
|
|
|
impl->margin_bottom = bottom;
|
|
|
|
|
gdk_wayland_window_sync_margin (window);
|
2014-02-07 22:20:14 +00:00
|
|
|
|
}
|
2013-06-04 09:39:36 +00:00
|
|
|
|
|
2010-12-18 20:38:49 +00:00
|
|
|
|
static void
|
|
|
|
|
_gdk_window_impl_wayland_class_init (GdkWindowImplWaylandClass *klass)
|
|
|
|
|
{
|
|
|
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
|
|
|
GdkWindowImplClass *impl_class = GDK_WINDOW_IMPL_CLASS (klass);
|
|
|
|
|
|
|
|
|
|
object_class->finalize = gdk_window_impl_wayland_finalize;
|
|
|
|
|
|
|
|
|
|
impl_class->ref_cairo_surface = gdk_wayland_window_ref_cairo_surface;
|
2013-07-03 14:03:25 +00:00
|
|
|
|
impl_class->create_similar_image_surface = gdk_wayland_window_create_similar_image_surface;
|
2010-12-18 20:38:49 +00:00
|
|
|
|
impl_class->show = gdk_wayland_window_show;
|
|
|
|
|
impl_class->hide = gdk_wayland_window_hide;
|
|
|
|
|
impl_class->withdraw = gdk_window_wayland_withdraw;
|
|
|
|
|
impl_class->set_events = gdk_window_wayland_set_events;
|
|
|
|
|
impl_class->get_events = gdk_window_wayland_get_events;
|
|
|
|
|
impl_class->raise = gdk_window_wayland_raise;
|
|
|
|
|
impl_class->lower = gdk_window_wayland_lower;
|
|
|
|
|
impl_class->restack_under = gdk_window_wayland_restack_under;
|
|
|
|
|
impl_class->restack_toplevel = gdk_window_wayland_restack_toplevel;
|
|
|
|
|
impl_class->move_resize = gdk_window_wayland_move_resize;
|
|
|
|
|
impl_class->set_background = gdk_window_wayland_set_background;
|
|
|
|
|
impl_class->reparent = gdk_window_wayland_reparent;
|
|
|
|
|
impl_class->set_device_cursor = gdk_window_wayland_set_device_cursor;
|
|
|
|
|
impl_class->get_geometry = gdk_window_wayland_get_geometry;
|
|
|
|
|
impl_class->get_root_coords = gdk_window_wayland_get_root_coords;
|
|
|
|
|
impl_class->get_device_state = gdk_window_wayland_get_device_state;
|
|
|
|
|
impl_class->shape_combine_region = gdk_window_wayland_shape_combine_region;
|
|
|
|
|
impl_class->input_shape_combine_region = gdk_window_wayland_input_shape_combine_region;
|
|
|
|
|
impl_class->set_static_gravities = gdk_window_wayland_set_static_gravities;
|
|
|
|
|
impl_class->queue_antiexpose = gdk_wayland_window_queue_antiexpose;
|
|
|
|
|
impl_class->destroy = gdk_wayland_window_destroy;
|
|
|
|
|
impl_class->destroy_foreign = gdk_window_wayland_destroy_foreign;
|
|
|
|
|
impl_class->resize_cairo_surface = gdk_window_wayland_resize_cairo_surface;
|
|
|
|
|
impl_class->get_shape = gdk_wayland_window_get_shape;
|
|
|
|
|
impl_class->get_input_shape = gdk_wayland_window_get_input_shape;
|
2013-04-29 19:49:12 +00:00
|
|
|
|
impl_class->begin_paint_region = gdk_window_impl_wayland_begin_paint_region;
|
2010-12-18 20:38:49 +00:00
|
|
|
|
/* impl_class->beep */
|
|
|
|
|
|
|
|
|
|
impl_class->focus = gdk_wayland_window_focus;
|
|
|
|
|
impl_class->set_type_hint = gdk_wayland_window_set_type_hint;
|
|
|
|
|
impl_class->get_type_hint = gdk_wayland_window_get_type_hint;
|
|
|
|
|
impl_class->set_modal_hint = gdk_wayland_window_set_modal_hint;
|
|
|
|
|
impl_class->set_skip_taskbar_hint = gdk_wayland_window_set_skip_taskbar_hint;
|
|
|
|
|
impl_class->set_skip_pager_hint = gdk_wayland_window_set_skip_pager_hint;
|
|
|
|
|
impl_class->set_urgency_hint = gdk_wayland_window_set_urgency_hint;
|
|
|
|
|
impl_class->set_geometry_hints = gdk_wayland_window_set_geometry_hints;
|
|
|
|
|
impl_class->set_title = gdk_wayland_window_set_title;
|
|
|
|
|
impl_class->set_role = gdk_wayland_window_set_role;
|
|
|
|
|
impl_class->set_startup_id = gdk_wayland_window_set_startup_id;
|
|
|
|
|
impl_class->set_transient_for = gdk_wayland_window_set_transient_for;
|
|
|
|
|
impl_class->get_frame_extents = gdk_wayland_window_get_frame_extents;
|
|
|
|
|
impl_class->set_override_redirect = gdk_wayland_window_set_override_redirect;
|
|
|
|
|
impl_class->set_accept_focus = gdk_wayland_window_set_accept_focus;
|
|
|
|
|
impl_class->set_focus_on_map = gdk_wayland_window_set_focus_on_map;
|
|
|
|
|
impl_class->set_icon_list = gdk_wayland_window_set_icon_list;
|
|
|
|
|
impl_class->set_icon_name = gdk_wayland_window_set_icon_name;
|
|
|
|
|
impl_class->iconify = gdk_wayland_window_iconify;
|
|
|
|
|
impl_class->deiconify = gdk_wayland_window_deiconify;
|
|
|
|
|
impl_class->stick = gdk_wayland_window_stick;
|
|
|
|
|
impl_class->unstick = gdk_wayland_window_unstick;
|
|
|
|
|
impl_class->maximize = gdk_wayland_window_maximize;
|
|
|
|
|
impl_class->unmaximize = gdk_wayland_window_unmaximize;
|
|
|
|
|
impl_class->fullscreen = gdk_wayland_window_fullscreen;
|
|
|
|
|
impl_class->unfullscreen = gdk_wayland_window_unfullscreen;
|
|
|
|
|
impl_class->set_keep_above = gdk_wayland_window_set_keep_above;
|
|
|
|
|
impl_class->set_keep_below = gdk_wayland_window_set_keep_below;
|
|
|
|
|
impl_class->get_group = gdk_wayland_window_get_group;
|
|
|
|
|
impl_class->set_group = gdk_wayland_window_set_group;
|
|
|
|
|
impl_class->set_decorations = gdk_wayland_window_set_decorations;
|
|
|
|
|
impl_class->get_decorations = gdk_wayland_window_get_decorations;
|
|
|
|
|
impl_class->set_functions = gdk_wayland_window_set_functions;
|
|
|
|
|
impl_class->begin_resize_drag = gdk_wayland_window_begin_resize_drag;
|
|
|
|
|
impl_class->begin_move_drag = gdk_wayland_window_begin_move_drag;
|
|
|
|
|
impl_class->set_opacity = gdk_wayland_window_set_opacity;
|
|
|
|
|
impl_class->set_composited = gdk_wayland_window_set_composited;
|
|
|
|
|
impl_class->destroy_notify = gdk_wayland_window_destroy_notify;
|
2011-02-08 13:12:59 +00:00
|
|
|
|
impl_class->get_drag_protocol = _gdk_wayland_window_get_drag_protocol;
|
2010-12-18 20:38:49 +00:00
|
|
|
|
impl_class->register_dnd = _gdk_wayland_window_register_dnd;
|
|
|
|
|
impl_class->drag_begin = _gdk_wayland_window_drag_begin;
|
|
|
|
|
impl_class->process_updates_recurse = gdk_wayland_window_process_updates_recurse;
|
|
|
|
|
impl_class->sync_rendering = gdk_wayland_window_sync_rendering;
|
|
|
|
|
impl_class->simulate_key = gdk_wayland_window_simulate_key;
|
|
|
|
|
impl_class->simulate_button = gdk_wayland_window_simulate_button;
|
|
|
|
|
impl_class->get_property = gdk_wayland_window_get_property;
|
|
|
|
|
impl_class->change_property = gdk_wayland_window_change_property;
|
|
|
|
|
impl_class->delete_property = gdk_wayland_window_delete_property;
|
2013-06-04 09:39:36 +00:00
|
|
|
|
impl_class->get_scale_factor = gdk_wayland_window_get_scale_factor;
|
2013-05-14 20:23:33 +00:00
|
|
|
|
impl_class->set_opaque_region = gdk_wayland_window_set_opaque_region;
|
2014-02-07 22:20:14 +00:00
|
|
|
|
impl_class->set_shadow_width = gdk_wayland_window_set_shadow_width;
|
2010-12-18 20:38:49 +00:00
|
|
|
|
}
|
2012-02-27 14:06:22 +00:00
|
|
|
|
|
|
|
|
|
void
|
2012-07-11 13:29:43 +00:00
|
|
|
|
_gdk_wayland_window_set_device_grabbed (GdkWindow *window,
|
2013-02-15 11:16:51 +00:00
|
|
|
|
GdkDevice *device,
|
2012-07-11 13:29:43 +00:00
|
|
|
|
struct wl_seat *seat,
|
|
|
|
|
guint32 time_)
|
2012-02-27 14:06:22 +00:00
|
|
|
|
{
|
2012-03-05 19:41:11 +00:00
|
|
|
|
GdkWindowImplWayland *impl;
|
|
|
|
|
|
|
|
|
|
g_return_if_fail (window != NULL);
|
|
|
|
|
|
|
|
|
|
impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
2012-02-27 14:06:22 +00:00
|
|
|
|
|
2013-02-15 11:16:51 +00:00
|
|
|
|
impl->grab_device = device;
|
2012-07-11 13:29:43 +00:00
|
|
|
|
impl->grab_input_seat = seat;
|
2012-02-27 14:06:22 +00:00
|
|
|
|
impl->grab_time = time_;
|
|
|
|
|
}
|
2013-01-23 21:20:05 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* gdk_wayland_window_get_wl_surface
|
|
|
|
|
* @window: (type GdkWaylandWindow): a #GdkWindow
|
|
|
|
|
*
|
|
|
|
|
* Returns the Wayland surface of a #GdkWindow
|
|
|
|
|
*
|
|
|
|
|
* Returns: (transfer none): a Wayland wl_surface
|
|
|
|
|
*
|
|
|
|
|
* Since: 3.8
|
|
|
|
|
*/
|
|
|
|
|
struct wl_surface *
|
|
|
|
|
gdk_wayland_window_get_wl_surface (GdkWindow *window)
|
|
|
|
|
{
|
|
|
|
|
GdkWindowImplWayland *impl;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (GDK_IS_WAYLAND_WINDOW (window), NULL);
|
|
|
|
|
|
|
|
|
|
impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
|
|
|
|
|
|
|
|
|
return impl->surface;
|
|
|
|
|
}
|
|
|
|
|
|
2013-03-20 15:38:36 +00:00
|
|
|
|
/**
|
|
|
|
|
* gdk_wayland_window_set_use_custom_surface:
|
|
|
|
|
* @window: (type GdkWaylandWindow): a #GdkWindow
|
|
|
|
|
*
|
|
|
|
|
* Marks a #GdkWindow as a custom Wayland surface. The application is
|
|
|
|
|
* expected to register the surface as some type of surface using
|
|
|
|
|
* some Wayland interface.
|
|
|
|
|
*
|
2013-09-16 21:23:29 +00:00
|
|
|
|
* A good example would be writing a panel or on-screen-keyboard as an
|
2013-03-20 15:38:36 +00:00
|
|
|
|
* out-of-process helper - as opposed to having those in the compositor
|
2014-02-07 18:32:47 +00:00
|
|
|
|
* process. In this case the underlying surface isn’t an xdg_shell
|
2013-03-20 15:38:36 +00:00
|
|
|
|
* surface and the panel or OSK client need to identify the wl_surface
|
|
|
|
|
* as a panel or OSK to the compositor. The assumption is that the
|
|
|
|
|
* compositor will expose a private interface to the special client
|
|
|
|
|
* that lets the client identify the wl_surface as a panel or such.
|
|
|
|
|
*
|
|
|
|
|
* This function should be called before a #GdkWindow is shown. This is
|
2014-01-21 23:46:05 +00:00
|
|
|
|
* best done by connecting to the #GtkWidget::realize signal:
|
2013-03-20 15:38:36 +00:00
|
|
|
|
*
|
2014-01-27 19:55:18 +00:00
|
|
|
|
* |[<!-- language="C" -->
|
2013-03-20 15:38:36 +00:00
|
|
|
|
* static void
|
|
|
|
|
* widget_realize_cb (GtkWidget *widget)
|
|
|
|
|
* {
|
|
|
|
|
* GdkWindow *window;
|
|
|
|
|
* struct wl_surface *surface;
|
|
|
|
|
* struct input_panel_surface *ip_surface;
|
|
|
|
|
*
|
|
|
|
|
* window = gtk_widget_get_window (widget);
|
|
|
|
|
* gdk_wayland_window_set_custom_surface (window);
|
|
|
|
|
*
|
|
|
|
|
* surface = gdk_wayland_window_get_wl_surface (window);
|
|
|
|
|
* ip_surface = input_panel_get_input_panel_surface (input_panel, surface);
|
|
|
|
|
* input_panel_surface_set_panel (ip_surface);
|
|
|
|
|
* }
|
|
|
|
|
*
|
|
|
|
|
* static void
|
|
|
|
|
* setup_window (GtkWindow *window)
|
|
|
|
|
* {
|
|
|
|
|
* g_signal_connect (window, "realize", G_CALLBACK (widget_realize_cb), NULL);
|
|
|
|
|
* }
|
2014-01-27 17:12:55 +00:00
|
|
|
|
* ]|
|
2013-03-20 15:38:36 +00:00
|
|
|
|
*
|
|
|
|
|
* Since: 3.10
|
|
|
|
|
*/
|
|
|
|
|
void
|
|
|
|
|
gdk_wayland_window_set_use_custom_surface (GdkWindow *window)
|
|
|
|
|
{
|
|
|
|
|
GdkWindowImplWayland *impl;
|
|
|
|
|
|
|
|
|
|
g_return_if_fail (GDK_IS_WAYLAND_WINDOW (window));
|
|
|
|
|
|
|
|
|
|
impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
|
|
|
|
|
|
|
|
|
if (!impl->surface)
|
2013-04-25 15:11:02 +00:00
|
|
|
|
gdk_wayland_window_create_surface (window);
|
2013-03-20 15:38:36 +00:00
|
|
|
|
|
|
|
|
|
impl->use_custom_surface = TRUE;
|
|
|
|
|
}
|
2013-08-30 11:56:45 +00:00
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
gdk_wayland_window_set_dbus_properties_libgtk_only (GdkWindow *window,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
const char *application_id,
|
|
|
|
|
const char *app_menu_path,
|
|
|
|
|
const char *menubar_path,
|
|
|
|
|
const char *window_object_path,
|
|
|
|
|
const char *application_object_path,
|
|
|
|
|
const char *unique_bus_name)
|
2013-08-30 11:56:45 +00:00
|
|
|
|
{
|
2013-11-19 23:27:54 +00:00
|
|
|
|
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_window_get_display (window));
|
2013-08-30 11:56:45 +00:00
|
|
|
|
GdkWindowImplWayland *impl;
|
|
|
|
|
|
|
|
|
|
g_return_if_fail (GDK_IS_WAYLAND_WINDOW (window));
|
|
|
|
|
|
|
|
|
|
impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
|
|
|
|
|
|
|
|
|
if (impl->gtk_surface == NULL)
|
2013-11-19 23:27:54 +00:00
|
|
|
|
{
|
|
|
|
|
if (impl->xdg_surface == NULL)
|
|
|
|
|
return;
|
|
|
|
|
if (display_wayland->gtk_shell == NULL)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
impl->gtk_surface = gtk_shell_get_gtk_surface (display_wayland->gtk_shell, impl->surface);
|
|
|
|
|
}
|
2013-08-30 11:56:45 +00:00
|
|
|
|
|
|
|
|
|
gtk_surface_set_dbus_properties (impl->gtk_surface,
|
2013-09-16 21:23:29 +00:00
|
|
|
|
application_id,
|
|
|
|
|
app_menu_path,
|
|
|
|
|
menubar_path,
|
|
|
|
|
window_object_path,
|
|
|
|
|
application_object_path,
|
|
|
|
|
unique_bus_name);
|
2013-08-30 11:56:45 +00:00
|
|
|
|
}
|