1
From 52b9d12764e90efe21806a54c4191ae999ed7751 Mon Sep 17 00:00:00 2001
2
From: Andreas Pokorny <andreas.pokorny@canonical.com>
3
Date: Tue, 19 Jul 2016 14:56:34 +0200
4
Subject: [PATCH] Update the GDK-Mir backend to fix a few problems
6
See https://bugzilla.gnome.org/show_bug.cgi?id=768138
9
gdk/mir/gdkmir-private.h | 4 +-
10
gdk/mir/gdkmirdisplay.c | 2 +-
11
gdk/mir/gdkmireventsource.c | 62 +++----
12
gdk/mir/gdkmirscreen.c | 4 +-
13
gdk/mir/gdkmirwindowimpl.c | 425 ++++++++++++++++++++++++++++++++++++--------
14
6 files changed, 382 insertions(+), 117 deletions(-)
16
diff --git a/configure.ac b/configure.ac
17
index 89722cd..66a5fc6 100644
20
@@ -61,7 +61,7 @@ m4_define([gdk_pixbuf_required_version], [2.30.0])
21
m4_define([introspection_required_version], [1.39.0])
22
m4_define([wayland_required_version], [1.9.91])
23
m4_define([wayland_protocols_required_version], [1.0])
24
-m4_define([mirclient_required_version], [0.11.0])
25
+m4_define([mirclient_required_version], [0.22.0])
26
m4_define([mircookie_required_version], [0.17.0])
27
m4_define([epoxy_required_version], [1.0])
28
GLIB_REQUIRED_VERSION=glib_required_version
29
diff --git a/gdk/mir/gdkmir-private.h b/gdk/mir/gdkmir-private.h
30
index 84051a7..38f1d7a 100644
31
--- a/gdk/mir/gdkmir-private.h
32
+++ b/gdk/mir/gdkmir-private.h
33
@@ -83,12 +83,14 @@ GdkCursor *_gdk_mir_cursor_new_for_name (GdkDisplay *display, const gchar *name)
35
const gchar *_gdk_mir_cursor_get_name (GdkCursor *cursor);
37
-GdkWindowImpl *_gdk_mir_window_impl_new (void);
38
+GdkWindowImpl *_gdk_mir_window_impl_new (GdkDisplay *display, GdkWindow *window, GdkWindowAttr *attributes, gint attributes_mask);
40
void _gdk_mir_window_impl_set_surface_state (GdkMirWindowImpl *impl, MirSurfaceState state);
42
void _gdk_mir_window_impl_set_surface_type (GdkMirWindowImpl *impl, MirSurfaceType type);
44
+void _gdk_mir_window_set_surface_output (GdkWindow *window, gdouble scale);
46
void _gdk_mir_window_impl_set_cursor_state (GdkMirWindowImpl *impl, gdouble x, gdouble y, gboolean cursor_inside, guint button_state);
48
void _gdk_mir_window_impl_get_cursor_state (GdkMirWindowImpl *impl, gdouble *x, gdouble *y, gboolean *cursor_inside, guint *button_state);
49
diff --git a/gdk/mir/gdkmirdisplay.c b/gdk/mir/gdkmirdisplay.c
50
index ffcee8a..eea892c 100644
51
--- a/gdk/mir/gdkmirdisplay.c
52
+++ b/gdk/mir/gdkmirdisplay.c
53
@@ -411,7 +411,7 @@ gdk_mir_display_create_window_impl (GdkDisplay *display,
55
if (attributes->wclass == GDK_INPUT_OUTPUT)
57
- window->impl = _gdk_mir_window_impl_new ();
58
+ window->impl = _gdk_mir_window_impl_new (display, window, attributes, attributes_mask);
59
window->impl_window = window;
61
else /* attributes->wclass == GDK_INPUT_ONLY */
62
diff --git a/gdk/mir/gdkmireventsource.c b/gdk/mir/gdkmireventsource.c
63
index a288cb7..865b6f6 100644
64
--- a/gdk/mir/gdkmireventsource.c
65
+++ b/gdk/mir/gdkmireventsource.c
66
@@ -289,28 +289,17 @@ handle_key_event (GdkWindow *window, const MirInputEvent *event)
70
- switch (mir_keyboard_event_action (keyboard_event))
72
- case mir_keyboard_action_up:
73
- case mir_keyboard_action_down:
74
- // FIXME: Convert keycode
75
- _gdk_mir_window_impl_get_cursor_state (impl, NULL, NULL, NULL, &button_state);
76
- modifier_state = get_modifier_state (mir_keyboard_event_modifiers (keyboard_event), button_state);
77
- keymap = gdk_keymap_get_for_display (gdk_window_get_display (window));
79
- generate_key_event (window,
80
- mir_keyboard_event_action (keyboard_event) == mir_keyboard_action_down ? GDK_KEY_PRESS : GDK_KEY_RELEASE,
82
- mir_keyboard_event_key_code (keyboard_event),
83
- mir_keyboard_event_scan_code (keyboard_event),
84
- _gdk_mir_keymap_key_is_modifier (keymap, mir_keyboard_event_key_code (keyboard_event)),
85
- NANO_TO_MILLI (mir_input_event_get_event_time (event)));
88
- //case mir_key_action_multiple:
92
+ _gdk_mir_window_impl_get_cursor_state (impl, NULL, NULL, NULL, &button_state);
93
+ modifier_state = get_modifier_state (mir_keyboard_event_modifiers (keyboard_event), button_state);
94
+ keymap = gdk_keymap_get_for_display (gdk_window_get_display (window));
96
+ generate_key_event (window,
97
+ mir_keyboard_event_action (keyboard_event) == mir_keyboard_action_up ? GDK_KEY_RELEASE : GDK_KEY_PRESS,
99
+ mir_keyboard_event_key_code (keyboard_event),
100
+ mir_keyboard_event_scan_code (keyboard_event),
101
+ _gdk_mir_keymap_key_is_modifier (keymap, mir_keyboard_event_key_code (keyboard_event)),
102
+ NANO_TO_MILLI (mir_input_event_get_event_time (event)));
106
@@ -324,18 +313,13 @@ handle_touch_event (GdkWindow *window,
108
for (i = 0; i < n; i++)
110
- switch (mir_touch_event_action (mir_touch_event, i))
112
- case mir_touch_action_up:
113
- gdk_event = gdk_event_new (GDK_TOUCH_END);
115
- case mir_touch_action_down:
116
- gdk_event = gdk_event_new (GDK_TOUCH_BEGIN);
118
- case mir_touch_action_change:
119
- gdk_event = gdk_event_new (GDK_TOUCH_UPDATE);
122
+ MirTouchAction action = mir_touch_event_action (mir_touch_event, i);
123
+ if (action == mir_touch_action_up)
124
+ gdk_event = gdk_event_new (GDK_TOUCH_END);
125
+ else if (action == mir_touch_action_down)
126
+ gdk_event = gdk_event_new (GDK_TOUCH_BEGIN);
128
+ gdk_event = gdk_event_new (GDK_TOUCH_UPDATE);
130
gdk_event->touch.window = window;
131
gdk_event->touch.sequence = GINT_TO_POINTER (mir_touch_event_id (mir_touch_event, i));
132
@@ -543,6 +527,13 @@ handle_close_event (GdkWindow *window)
133
gdk_window_destroy_notify (window);
137
+handle_surface_output_event (GdkWindow *window,
138
+ const MirSurfaceOutputEvent *event)
140
+ _gdk_mir_window_set_surface_output (window, mir_surface_output_event_get_scale (event));
146
@@ -597,6 +588,9 @@ gdk_mir_event_source_queue_event (GdkDisplay *display,
147
case mir_event_type_close_surface:
148
handle_close_event (window);
150
+ case mir_event_type_surface_output:
151
+ handle_surface_output_event (window, mir_event_get_surface_output_event (event));
154
g_warning ("Ignoring unknown Mir event %d", mir_event_get_type (event));
156
diff --git a/gdk/mir/gdkmirscreen.c b/gdk/mir/gdkmirscreen.c
157
index 7aa0aa6..b369b03 100644
158
--- a/gdk/mir/gdkmirscreen.c
159
+++ b/gdk/mir/gdkmirscreen.c
160
@@ -257,7 +257,6 @@ gdk_mir_screen_get_root_window (GdkScreen *screen)
161
get_screen_size (GDK_MIR_SCREEN (screen)->display_config, &width, &height);
163
s->root_window = _gdk_display_create_window (s->display);
164
- s->root_window->impl = _gdk_mir_window_impl_new ();
165
s->root_window->impl_window = s->root_window;
166
s->root_window->visual = s->visual;
167
s->root_window->window_type = GDK_WINDOW_ROOT;
168
@@ -269,6 +268,7 @@ gdk_mir_screen_get_root_window (GdkScreen *screen)
169
s->root_window->width = width;
170
s->root_window->height = height;
171
s->root_window->viewable = TRUE;
172
+ s->root_window->impl = _gdk_mir_window_impl_new (s->display, s->root_window, NULL, 0);
174
return s->root_window;
176
@@ -352,6 +352,8 @@ gdk_mir_screen_get_monitor_plug_name (GdkScreen *screen,
177
return g_strdup_printf ("TV-%u", output->output_id);
178
case mir_display_output_type_edp:
179
return g_strdup_printf ("eDP-%u", output->output_id);
180
+ case mir_display_output_type_virtual:
181
+ return g_strdup_printf ("Virtual-%u", output->output_id);
185
diff --git a/gdk/mir/gdkmirwindowimpl.c b/gdk/mir/gdkmirwindowimpl.c
186
index 5ca9d89..fc37c7e 100644
187
--- a/gdk/mir/gdkmirwindowimpl.c
188
+++ b/gdk/mir/gdkmirwindowimpl.c
192
#include <inttypes.h>
199
#include "gdkdisplayprivate.h"
200
#include "gdkdeviceprivate.h"
201
+#include "gdkframeclockprivate.h"
203
#define GDK_MIR_WINDOW_IMPL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_WINDOW_IMPL_MIR, GdkMirWindowImplClass))
204
#define GDK_IS_WINDOW_IMPL_MIR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_WINDOW_IMPL_MIR))
205
@@ -58,12 +60,21 @@ struct _GdkMirWindowImpl
209
+ GdkDisplay *display;
211
/* Surface being rendered to (only exists when window visible) */
213
+ MirBufferStream *buffer_stream;
214
+ MirBufferUsage buffer_usage;
216
/* Cairo context for current frame */
217
cairo_surface_t *cairo_surface;
221
+ GdkGeometry geometry_hints;
222
+ GdkWindowHints geometry_mask;
224
/* Egl surface for the current mir surface */
225
EGLSurface egl_surface;
227
@@ -75,6 +86,12 @@ struct _GdkMirWindowImpl
229
/* TRUE if cursor is inside this window */
230
gboolean cursor_inside;
232
+ gboolean pending_redraw;
233
+ gboolean pending_commit;
234
+ gboolean pending_swap;
235
+ gboolean pending_spec_update;
239
struct _GdkMirWindowImplClass
240
@@ -85,11 +102,97 @@ struct _GdkMirWindowImplClass
241
G_DEFINE_TYPE (GdkMirWindowImpl, gdk_mir_window_impl, GDK_TYPE_WINDOW_IMPL)
243
static cairo_surface_t *gdk_mir_window_impl_ref_cairo_surface (GdkWindow *window);
244
+static void on_frame_clock_after_paint (GdkFrameClock *clock, GdkWindow *window);
245
+static void ensure_surface (GdkWindow *window);
246
+static void apply_geometry_hints (MirSurfaceSpec *spec, GdkMirWindowImpl *impl);
249
+type_hint_differs (GdkWindowTypeHint lhs, GdkWindowTypeHint rhs)
256
+ case GDK_WINDOW_TYPE_HINT_DIALOG:
257
+ case GDK_WINDOW_TYPE_HINT_DOCK:
258
+ return rhs != GDK_WINDOW_TYPE_HINT_DIALOG &&
259
+ rhs != GDK_WINDOW_TYPE_HINT_DOCK;
260
+ case GDK_WINDOW_TYPE_HINT_MENU:
261
+ case GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU:
262
+ case GDK_WINDOW_TYPE_HINT_POPUP_MENU:
263
+ case GDK_WINDOW_TYPE_HINT_TOOLBAR:
264
+ case GDK_WINDOW_TYPE_HINT_COMBO:
265
+ return rhs != GDK_WINDOW_TYPE_HINT_MENU &&
266
+ rhs != GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU &&
267
+ rhs != GDK_WINDOW_TYPE_HINT_POPUP_MENU &&
268
+ rhs != GDK_WINDOW_TYPE_HINT_TOOLBAR &&
269
+ rhs != GDK_WINDOW_TYPE_HINT_COMBO;
270
+ case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
271
+ case GDK_WINDOW_TYPE_HINT_UTILITY:
272
+ return rhs != GDK_WINDOW_TYPE_HINT_SPLASHSCREEN &&
273
+ rhs != GDK_WINDOW_TYPE_HINT_UTILITY;
274
+ case GDK_WINDOW_TYPE_HINT_DND:
275
+ case GDK_WINDOW_TYPE_HINT_TOOLTIP:
276
+ case GDK_WINDOW_TYPE_HINT_NOTIFICATION:
277
+ return rhs != GDK_WINDOW_TYPE_HINT_DND &&
278
+ rhs != GDK_WINDOW_TYPE_HINT_TOOLTIP &&
279
+ rhs != GDK_WINDOW_TYPE_HINT_NOTIFICATION;
280
+ case GDK_WINDOW_TYPE_HINT_NORMAL:
281
+ case GDK_WINDOW_TYPE_HINT_DESKTOP:
283
+ return rhs != GDK_WINDOW_TYPE_HINT_NORMAL &&
284
+ rhs != GDK_WINDOW_TYPE_HINT_DESKTOP;
289
+drop_cairo_surface (GdkWindow *window)
291
+ GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
293
+ g_clear_pointer (&impl->cairo_surface, cairo_surface_destroy);
296
+static const gchar *
297
+get_default_title (void)
301
+ title = g_get_application_name ();
303
+ title = g_get_prgname ();
311
-_gdk_mir_window_impl_new (void)
312
+_gdk_mir_window_impl_new (GdkDisplay *display, GdkWindow *window, GdkWindowAttr *attributes, gint attributes_mask)
314
- return g_object_new (GDK_TYPE_MIR_WINDOW_IMPL, NULL);
315
+ GdkFrameClock *frame_clock = gdk_window_get_frame_clock (window);
316
+ GdkMirWindowImpl *impl = g_object_new (GDK_TYPE_MIR_WINDOW_IMPL, NULL);
318
+ impl->display = display;
320
+ if (attributes && attributes_mask & GDK_WA_TITLE)
321
+ impl->title = g_strdup (attributes->title);
323
+ impl->title = g_strdup (get_default_title ());
325
+ if (attributes && attributes_mask & GDK_WA_TYPE_HINT)
326
+ impl->type_hint = attributes->type_hint;
328
+ impl->pending_spec_update = TRUE;
330
+ if (window->window_type != GDK_WINDOW_ROOT)
332
+ g_signal_connect (frame_clock, "after-paint",
333
+ G_CALLBACK (on_frame_clock_after_paint), window);
336
+ return (GdkWindowImpl *) impl;
340
@@ -139,18 +242,25 @@ gdk_mir_window_impl_init (GdkMirWindowImpl *impl)
342
impl->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
343
impl->surface_state = mir_surface_state_unknown;
344
+ impl->output_scale = 1;
348
set_surface_state (GdkMirWindowImpl *impl,
349
MirSurfaceState state)
351
+ MirConnection *connection = gdk_mir_display_get_mir_connection (impl->display);
352
if (impl->surface_state == state)
355
impl->surface_state = state;
357
- mir_surface_set_state (impl->surface, state);
358
+ if (impl->surface && !impl->pending_spec_update)
360
+ MirSurfaceSpec *spec = mir_connection_create_spec_for_changes (connection);
361
+ mir_surface_spec_set_state (spec, state);
362
+ mir_surface_apply_spec (impl->surface, spec);
363
+ mir_surface_spec_release (spec);
368
@@ -161,26 +271,21 @@ event_cb (MirSurface *surface,
369
_gdk_mir_event_source_queue (context, event);
372
-static void ensure_surface (GdkWindow *window);
375
-create_mir_surface (GdkDisplay *display,
381
- GdkWindowTypeHint type,
382
- MirBufferUsage buffer_usage)
383
+static MirSurfaceSpec *
384
+create_window_type_spec (GdkDisplay *display,
390
+ GdkWindowTypeHint type,
391
+ MirBufferUsage buffer_usage)
393
- MirSurface *parent_surface = NULL;
394
- MirSurfaceSpec *spec;
395
- MirConnection *connection;
396
- MirPixelFormat format;
397
- MirSurface *surface;
399
+ MirPixelFormat format;
400
+ MirSurface *parent_surface = NULL;
401
+ MirConnection *connection = gdk_mir_display_get_mir_connection (display);
403
- connection = gdk_mir_display_get_mir_connection (display);
404
format = _gdk_mir_display_get_pixel_format (display, buffer_usage);
406
if (parent && parent->impl)
407
@@ -206,11 +311,10 @@ create_mir_surface (GdkDisplay *display,
409
case GDK_WINDOW_TYPE_HINT_DIALOG:
410
case GDK_WINDOW_TYPE_HINT_DOCK:
411
- spec = mir_connection_create_spec_for_dialog (connection,
412
+ return mir_connection_create_spec_for_dialog (connection,
417
case GDK_WINDOW_TYPE_HINT_MENU:
418
case GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU:
419
case GDK_WINDOW_TYPE_HINT_POPUP_MENU:
420
@@ -220,22 +324,20 @@ create_mir_surface (GdkDisplay *display,
424
- spec = mir_connection_create_spec_for_menu (connection,
425
+ return mir_connection_create_spec_for_menu (connection,
431
mir_edge_attachment_any);
433
case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
434
case GDK_WINDOW_TYPE_HINT_UTILITY:
435
- spec = mir_connection_create_spec_for_modal_dialog (connection,
436
+ return mir_connection_create_spec_for_modal_dialog (connection,
442
case GDK_WINDOW_TYPE_HINT_DND:
443
case GDK_WINDOW_TYPE_HINT_TOOLTIP:
444
case GDK_WINDOW_TYPE_HINT_NOTIFICATION:
445
@@ -243,7 +345,7 @@ create_mir_surface (GdkDisplay *display,
449
- spec = mir_connection_create_spec_for_tooltip (connection,
450
+ return mir_connection_create_spec_for_tooltip (connection,
454
@@ -253,19 +355,73 @@ create_mir_surface (GdkDisplay *display,
455
case GDK_WINDOW_TYPE_HINT_NORMAL:
456
case GDK_WINDOW_TYPE_HINT_DESKTOP:
458
- spec = mir_connection_create_spec_for_normal_surface (connection,
459
+ return mir_connection_create_spec_for_normal_surface (connection,
467
- mir_surface_spec_set_name (spec, g_get_prgname ());
468
- mir_surface_spec_set_buffer_usage (spec, buffer_usage);
469
- surface = mir_surface_create_sync (spec);
470
- mir_surface_spec_release (spec);
472
+apply_geometry_hints (MirSurfaceSpec *spec, GdkMirWindowImpl *impl)
474
+ if (impl->geometry_mask & GDK_HINT_RESIZE_INC)
476
+ mir_surface_spec_set_width_increment (spec, impl->geometry_hints.width_inc);
477
+ mir_surface_spec_set_height_increment (spec, impl->geometry_hints.height_inc);
479
+ if (impl->geometry_mask & GDK_HINT_MIN_SIZE)
481
+ mir_surface_spec_set_min_width (spec, impl->geometry_hints.min_width);
482
+ mir_surface_spec_set_min_height (spec, impl->geometry_hints.min_height);
484
+ if (impl->geometry_mask & GDK_HINT_MAX_SIZE)
486
+ mir_surface_spec_set_max_width (spec, impl->geometry_hints.max_width);
487
+ mir_surface_spec_set_max_height (spec, impl->geometry_hints.max_height);
489
+ if (impl->geometry_mask & GDK_HINT_ASPECT)
491
+ mir_surface_spec_set_min_aspect_ratio (spec, 1000, (unsigned)(1000.0/impl->geometry_hints.min_aspect));
492
+ mir_surface_spec_set_max_aspect_ratio (spec, 1000, (unsigned)(1000.0/impl->geometry_hints.max_aspect));
496
+static MirSurfaceSpec*
497
+create_spec (GdkWindow *window, GdkMirWindowImpl *impl)
499
+ MirSurfaceSpec *spec = NULL;
501
+ spec = create_window_type_spec (impl->display,
502
+ impl->transient_for,
503
+ impl->transient_x, impl->transient_y,
504
+ window->width, window->height,
506
+ impl->buffer_usage);
508
+ mir_surface_spec_set_name (spec, impl->title);
509
+ mir_surface_spec_set_buffer_usage (spec, impl->buffer_usage);
511
+ apply_geometry_hints (spec, impl);
517
+update_surface_spec (GdkWindow *window)
519
+ GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
520
+ MirSurfaceSpec *spec;
522
+ if (!impl->surface)
525
+ spec = create_spec (window, impl);
528
+ mir_surface_apply_spec (impl->surface, spec);
529
+ mir_surface_spec_release (spec);
530
+ impl->pending_spec_update = FALSE;
531
+ impl->buffer_stream = mir_surface_get_buffer_stream (impl->surface);
535
@@ -319,20 +475,29 @@ ensure_surface_full (GdkWindow *window,
537
GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
538
GdkMirWindowReference *window_ref;
539
+ MirSurfaceSpec *spec;
544
+ if (impl->pending_spec_update)
545
+ update_surface_spec(window);
549
/* no destroy notify -- we must leak for now
550
* https://bugs.launchpad.net/mir/+bug/1324100
552
window_ref = _gdk_mir_event_source_get_window_reference (window);
553
+ impl->buffer_usage = buffer_usage;
555
+ spec = create_spec (window, impl);
557
+ impl->surface = mir_surface_create_sync (spec);
559
- impl->surface = create_mir_surface (gdk_window_get_display (window), impl->transient_for,
560
- impl->transient_x, impl->transient_y,
561
- window->width, window->height,
564
+ mir_surface_spec_release(spec);
566
+ impl->pending_spec_update = FALSE;
567
+ impl->buffer_stream = mir_surface_get_buffer_stream (impl->surface);
569
/* FIXME: can't make an initial resize event */
570
// MirEvent *resize_event;
571
@@ -356,9 +521,10 @@ ensure_surface_full (GdkWindow *window,
573
ensure_surface (GdkWindow *window)
575
- ensure_surface_full (window, window->gl_paint_context ?
576
- mir_buffer_usage_hardware :
577
- mir_buffer_usage_software);
578
+ ensure_surface_full (window,
579
+ window->gl_paint_context ?
580
+ mir_buffer_usage_hardware :
581
+ mir_buffer_usage_software);
585
@@ -390,19 +556,63 @@ ensure_no_surface (GdkWindow *window)
589
+ impl->pending_commit = FALSE;
590
+ impl->pending_swap = FALSE;
591
g_clear_pointer(&impl->surface, mir_surface_release_sync);
595
-send_buffer (GdkWindow *window)
596
+on_swap_buffer_completed (MirBufferStream *stream, void *data)
598
+ GdkWindow *window = data;
599
GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
601
- /* Send the completed buffer to Mir */
602
- mir_buffer_stream_swap_buffers_sync (mir_surface_get_buffer_stream (impl->surface));
604
/* The Cairo context is no longer valid */
605
g_clear_pointer (&impl->cairo_surface, cairo_surface_destroy);
606
+ impl->pending_swap = FALSE;
608
+ _gdk_frame_clock_thaw (gdk_window_get_frame_clock (window));
612
+on_frame_clock_after_paint (GdkFrameClock *clock,
615
+ GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
617
+ if (!impl->pending_commit)
620
+ impl->pending_commit = FALSE;
621
+ _gdk_frame_clock_freeze (clock);
623
+ if (impl->pending_spec_update)
624
+ update_surface_spec (window);
626
+ impl->pending_spec_update = FALSE;
628
+ /* Send the completed buffer to Mir */
629
+ impl->pending_swap = TRUE;
630
+ mir_buffer_stream_swap_buffers (impl->buffer_stream, on_swap_buffer_completed, window);
634
+send_buffer_delayed (GdkWindow *window)
636
+ GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
638
+ if (impl->pending_swap || impl->pending_commit)
641
+ impl->pending_commit = TRUE;
645
+send_buffer (GdkWindow *window)
647
+ send_buffer_delayed (window);
648
+ gdk_frame_clock_request_phase (gdk_window_get_frame_clock (window),
649
+ GDK_FRAME_CLOCK_PHASE_AFTER_PAINT);
652
static cairo_surface_t *
653
@@ -421,15 +631,16 @@ gdk_mir_window_impl_ref_cairo_surface (GdkWindow *window)
654
return impl->cairo_surface;
657
+ ensure_surface (window);
659
/* Transient windows get rendered into a buffer and copied onto their parent */
660
if (window->gl_paint_context)
662
cairo_surface = cairo_image_surface_create (pixel_format, window->width, window->height);
663
+ cairo_surface_set_device_scale (cairo_surface, (double) impl->output_scale, (double) impl->output_scale);
665
else if (impl->visible)
667
- ensure_surface (window);
669
mir_buffer_stream_get_graphics_region (mir_surface_get_buffer_stream (impl->surface), ®ion);
671
switch (region.pixel_format)
672
@@ -473,6 +684,7 @@ gdk_mir_window_impl_ref_cairo_surface (GdkWindow *window)
676
+ cairo_surface_set_device_scale (cairo_surface, (double) impl->output_scale, (double) impl->output_scale);
679
cairo_surface = cairo_image_surface_create (pixel_format, 0, 0);
680
@@ -506,6 +718,7 @@ gdk_mir_window_impl_finalize (GObject *object)
682
GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (object);
684
+ g_free (impl->title);
685
if (impl->background)
686
cairo_pattern_destroy (impl->background);
688
@@ -526,6 +739,7 @@ gdk_mir_window_impl_show (GdkWindow *window,
689
//g_printerr ("gdk_mir_window_impl_show window=%p\n", window);
691
impl->visible = TRUE;
692
+ set_surface_state (impl, mir_surface_state_restored);
694
/* Make sure there's a surface to see */
695
ensure_surface (window);
696
@@ -547,7 +761,8 @@ gdk_mir_window_impl_hide (GdkWindow *window)
698
impl->cursor_inside = FALSE;
699
impl->visible = FALSE;
700
- ensure_no_surface (window);
702
+ set_surface_state (impl, mir_surface_state_hidden);
706
@@ -558,7 +773,8 @@ gdk_mir_window_impl_withdraw (GdkWindow *window)
708
impl->cursor_inside = FALSE;
709
impl->visible = FALSE;
710
- ensure_no_surface (window);
712
+ set_surface_state (impl, mir_surface_state_hidden);
716
@@ -610,32 +826,28 @@ gdk_mir_window_impl_move_resize (GdkWindow *window,
719
GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
720
- gboolean recreate_surface = FALSE;
722
- /* Transient windows can move wherever they want */
725
- if (x != impl->transient_x || y != impl->transient_y)
727
- impl->transient_x = x;
728
- impl->transient_y = y;
729
- recreate_surface = TRUE;
732
+ //g_printerr ("gdk_mir_window_impl_move_resize window=%p, impl=%p\n", window, impl);
734
/* If resize requested then rebuild surface */
736
+ if (width >= 0 && (window->width != width || window->height != height))
738
/* We accept any resize */
739
window->width = width;
740
window->height = height;
741
- recreate_surface = TRUE;
742
+ impl->pending_redraw = TRUE;
743
+ impl->pending_spec_update = TRUE;
746
- if (recreate_surface && impl->surface)
747
+ /* Transient windows can move wherever they want */
750
- ensure_no_surface (window);
751
- ensure_surface (window);
752
+ if (x != impl->transient_x || y != impl->transient_y)
754
+ impl->transient_x = x;
755
+ impl->transient_y = y;
756
+ if (!impl->pending_spec_update && impl->surface)
757
+ update_surface_spec (window);
762
@@ -754,9 +966,12 @@ gdk_mir_window_impl_get_device_state (GdkWindow *window,
764
gdk_mir_window_impl_begin_paint (GdkWindow *window)
766
+ GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
768
+ ensure_surface (window);
769
//g_printerr ("gdk_mir_window_impl_begin_paint window=%p\n", window);
770
/* Indicate we are ready to be drawn onto directly? */
772
+ return impl->pending_swap;
776
@@ -832,10 +1047,11 @@ gdk_mir_window_impl_set_type_hint (GdkWindow *window,
778
GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
780
- if (hint != impl->type_hint)
781
+ if (type_hint_differs (hint, impl->type_hint))
783
impl->type_hint = hint;
784
- ensure_no_surface (window);
785
+ if (impl->surface && !impl->pending_spec_update)
786
+ update_surface_spec (window);
790
@@ -881,15 +1097,39 @@ gdk_mir_window_impl_set_geometry_hints (GdkWindow *window,
791
const GdkGeometry *geometry,
792
GdkWindowHints geom_mask)
794
- //g_printerr ("gdk_mir_window_impl_set_geometry_hints window=%p\n", window);
796
+ GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
797
+ MirConnection *connection = gdk_mir_display_get_mir_connection (impl->display);
798
+ //g_printerr ("gdk_mir_window_impl_set_geometry_hints window=%p impl=%p\n", window, impl);
800
+ impl->geometry_hints = *geometry;
801
+ impl->geometry_mask = geom_mask;
803
+ if (impl->surface && !impl->pending_spec_update)
805
+ MirSurfaceSpec* spec = mir_connection_create_spec_for_changes (connection);
806
+ apply_geometry_hints (spec, impl);
807
+ mir_surface_apply_spec (impl->surface, spec);
808
+ mir_surface_spec_release (spec);
813
gdk_mir_window_impl_set_title (GdkWindow *window,
816
- // g_printerr ("gdk_mir_window_impl_set_title window=%p\n", window);
817
+ GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
818
+ MirConnection *connection = gdk_mir_display_get_mir_connection (impl->display);
819
+ //g_printerr ("gdk_mir_window_impl_set_title window=%p\n", window);
821
+ g_free (impl->title);
822
+ impl->title = g_strdup (title);
823
+ if (impl->surface && !impl->pending_spec_update)
825
+ MirSurfaceSpec* spec = mir_connection_create_spec_for_changes (connection);
826
+ mir_surface_spec_set_name (spec, impl->title);
827
+ mir_surface_apply_spec (impl->surface, spec);
828
+ mir_surface_spec_release (spec);
833
@@ -918,6 +1158,9 @@ gdk_mir_window_impl_set_transient_for (GdkWindow *window,
835
/* Link this window to the parent */
836
impl->transient_for = parent;
838
+ if (impl->surface && !impl->pending_spec_update)
839
+ update_surface_spec (window);
843
@@ -1247,8 +1490,8 @@ static gint
844
gdk_mir_window_impl_get_scale_factor (GdkWindow *window)
846
//g_printerr ("gdk_mir_window_impl_get_scale_factor window=%p\n", window);
847
- /* Don't support monitor scaling */
849
+ GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
850
+ return impl->output_scale;
854
@@ -1460,7 +1703,7 @@ _gdk_mir_window_get_egl_surface (GdkWindow *window,
855
ensure_surface_full (window, mir_buffer_usage_hardware);
857
egl_display = _gdk_mir_display_get_egl_display (gdk_window_get_display (window));
858
- egl_window = (EGLNativeWindowType) mir_buffer_stream_get_egl_native_window (mir_surface_get_buffer_stream (impl->surface));
859
+ egl_window = (EGLNativeWindowType) mir_buffer_stream_get_egl_native_window (impl->buffer_stream);
862
eglCreateWindowSurface (egl_display, config, egl_window, NULL);
863
@@ -1485,7 +1728,7 @@ _gdk_mir_window_get_dummy_egl_surface (GdkWindow *window,
865
display = gdk_window_get_display (window);
866
egl_display = _gdk_mir_display_get_egl_display (display);
867
- egl_window = (EGLNativeWindowType) mir_buffer_stream_get_egl_native_window (mir_surface_get_buffer_stream (impl->surface));
868
+ egl_window = (EGLNativeWindowType) mir_buffer_stream_get_egl_native_window (impl->buffer_stream);
870
impl->dummy_egl_surface =
871
eglCreateWindowSurface (egl_display, config, egl_window, NULL);
872
@@ -1506,6 +1749,30 @@ gdk_mir_window_get_mir_surface (GdkWindow *window)
873
return impl->surface;
877
+_gdk_mir_window_set_surface_output (GdkWindow *window, gdouble scale)
879
+ // g_printerr ("_gdk_mir_window_impl_set_surface_output impl=%p\n", impl);
880
+ GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
881
+ GdkRectangle area = {0, 0, window->width, window->height};
882
+ cairo_region_t *region;
883
+ gint new_scale = (gint) round (scale);
885
+ if (impl->output_scale != new_scale)
887
+ impl->output_scale = new_scale;
889
+ drop_cairo_surface (window);
891
+ if (impl->buffer_stream)
892
+ mir_buffer_stream_set_scale (impl->buffer_stream, (float) new_scale);
894
+ region = cairo_region_create_rectangle (&area);
895
+ _gdk_window_invalidate_for_expose (window, region);
896
+ cairo_region_destroy (region);
901
gdk_mir_window_impl_class_init (GdkMirWindowImplClass *klass)