Merge lp:~attente/gtk/refresh-mir-4 into lp:~ubuntu-desktop/gtk/ubuntugtk3

Proposed by William Hua
Status: Merged
Merged at revision: 522
Proposed branch: lp:~attente/gtk/refresh-mir-4
Merge into: lp:~ubuntu-desktop/gtk/ubuntugtk3
Diff against target: 934 lines (+914/-0)
3 files modified
debian/changelog (+8/-0)
debian/patches/0001-Update-the-GDK-Mir-backend-to-fix-a-few-problems.patch (+905/-0)
debian/patches/series (+1/-0)
To merge this branch: bzr merge lp:~attente/gtk/refresh-mir-4
Reviewer Review Type Date Requested Status
Iain Lane Approve
Review via email: mp+301660@code.launchpad.net

Commit message

* Add 0001-Update-the-GDK-Mir-backend-to-fix-a-few-problems.patch
  - See https://bugzilla.gnome.org/show_bug.cgi?id=768138, thanks to Andreas Pokorny

Description of the change

* Add 0001-Update-the-GDK-Mir-backend-to-fix-a-few-problems.patch
  - See https://bugzilla.gnome.org/show_bug.cgi?id=768138, thanks to Andreas Pokorny

To post a comment you must log in.
Revision history for this message
Iain Lane (laney) wrote :

merci

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/changelog'
2--- debian/changelog 2016-07-29 12:48:49 +0000
3+++ debian/changelog 2016-08-01 15:06:42 +0000
4@@ -1,3 +1,11 @@
5+gtk+3.0 (3.20.6-1ubuntu2) UNRELEASED; urgency=medium
6+
7+ * Add 0001-Update-the-GDK-Mir-backend-to-fix-a-few-problems.patch
8+ - See https://bugzilla.gnome.org/show_bug.cgi?id=768138, thanks to
9+ Andreas Pokorny
10+
11+ -- William Hua <william.hua@canonical.com> Fri, 29 Jul 2016 10:53:20 -0400
12+
13 gtk+3.0 (3.20.6-1ubuntu1) yakkety; urgency=medium
14
15 * Merge with Debian (LP: #1576576). Remaining changes:
16
17=== added file 'debian/patches/0001-Update-the-GDK-Mir-backend-to-fix-a-few-problems.patch'
18--- debian/patches/0001-Update-the-GDK-Mir-backend-to-fix-a-few-problems.patch 1970-01-01 00:00:00 +0000
19+++ debian/patches/0001-Update-the-GDK-Mir-backend-to-fix-a-few-problems.patch 2016-08-01 15:06:42 +0000
20@@ -0,0 +1,905 @@
21+From 52b9d12764e90efe21806a54c4191ae999ed7751 Mon Sep 17 00:00:00 2001
22+From: Andreas Pokorny <andreas.pokorny@canonical.com>
23+Date: Tue, 19 Jul 2016 14:56:34 +0200
24+Subject: [PATCH] Update the GDK-Mir backend to fix a few problems
25+
26+See https://bugzilla.gnome.org/show_bug.cgi?id=768138
27+---
28+ configure.ac | 2 +-
29+ gdk/mir/gdkmir-private.h | 4 +-
30+ gdk/mir/gdkmirdisplay.c | 2 +-
31+ gdk/mir/gdkmireventsource.c | 62 +++----
32+ gdk/mir/gdkmirscreen.c | 4 +-
33+ gdk/mir/gdkmirwindowimpl.c | 425 ++++++++++++++++++++++++++++++++++++--------
34+ 6 files changed, 382 insertions(+), 117 deletions(-)
35+
36+diff --git a/configure.ac b/configure.ac
37+index 89722cd..66a5fc6 100644
38+--- a/configure.ac
39++++ b/configure.ac
40+@@ -61,7 +61,7 @@ m4_define([gdk_pixbuf_required_version], [2.30.0])
41+ m4_define([introspection_required_version], [1.39.0])
42+ m4_define([wayland_required_version], [1.9.91])
43+ m4_define([wayland_protocols_required_version], [1.0])
44+-m4_define([mirclient_required_version], [0.11.0])
45++m4_define([mirclient_required_version], [0.22.0])
46+ m4_define([mircookie_required_version], [0.17.0])
47+ m4_define([epoxy_required_version], [1.0])
48+ GLIB_REQUIRED_VERSION=glib_required_version
49+diff --git a/gdk/mir/gdkmir-private.h b/gdk/mir/gdkmir-private.h
50+index 84051a7..38f1d7a 100644
51+--- a/gdk/mir/gdkmir-private.h
52++++ b/gdk/mir/gdkmir-private.h
53+@@ -83,12 +83,14 @@ GdkCursor *_gdk_mir_cursor_new_for_name (GdkDisplay *display, const gchar *name)
54+
55+ const gchar *_gdk_mir_cursor_get_name (GdkCursor *cursor);
56+
57+-GdkWindowImpl *_gdk_mir_window_impl_new (void);
58++GdkWindowImpl *_gdk_mir_window_impl_new (GdkDisplay *display, GdkWindow *window, GdkWindowAttr *attributes, gint attributes_mask);
59+
60+ void _gdk_mir_window_impl_set_surface_state (GdkMirWindowImpl *impl, MirSurfaceState state);
61+
62+ void _gdk_mir_window_impl_set_surface_type (GdkMirWindowImpl *impl, MirSurfaceType type);
63+
64++void _gdk_mir_window_set_surface_output (GdkWindow *window, gdouble scale);
65++
66+ void _gdk_mir_window_impl_set_cursor_state (GdkMirWindowImpl *impl, gdouble x, gdouble y, gboolean cursor_inside, guint button_state);
67+
68+ void _gdk_mir_window_impl_get_cursor_state (GdkMirWindowImpl *impl, gdouble *x, gdouble *y, gboolean *cursor_inside, guint *button_state);
69+diff --git a/gdk/mir/gdkmirdisplay.c b/gdk/mir/gdkmirdisplay.c
70+index ffcee8a..eea892c 100644
71+--- a/gdk/mir/gdkmirdisplay.c
72++++ b/gdk/mir/gdkmirdisplay.c
73+@@ -411,7 +411,7 @@ gdk_mir_display_create_window_impl (GdkDisplay *display,
74+
75+ if (attributes->wclass == GDK_INPUT_OUTPUT)
76+ {
77+- window->impl = _gdk_mir_window_impl_new ();
78++ window->impl = _gdk_mir_window_impl_new (display, window, attributes, attributes_mask);
79+ window->impl_window = window;
80+ }
81+ else /* attributes->wclass == GDK_INPUT_ONLY */
82+diff --git a/gdk/mir/gdkmireventsource.c b/gdk/mir/gdkmireventsource.c
83+index a288cb7..865b6f6 100644
84+--- a/gdk/mir/gdkmireventsource.c
85++++ b/gdk/mir/gdkmireventsource.c
86+@@ -289,28 +289,17 @@ handle_key_event (GdkWindow *window, const MirInputEvent *event)
87+ if (!keyboard_event)
88+ return;
89+
90+- switch (mir_keyboard_event_action (keyboard_event))
91+- {
92+- case mir_keyboard_action_up:
93+- case mir_keyboard_action_down:
94+- // FIXME: Convert keycode
95+- _gdk_mir_window_impl_get_cursor_state (impl, NULL, NULL, NULL, &button_state);
96+- modifier_state = get_modifier_state (mir_keyboard_event_modifiers (keyboard_event), button_state);
97+- keymap = gdk_keymap_get_for_display (gdk_window_get_display (window));
98+-
99+- generate_key_event (window,
100+- mir_keyboard_event_action (keyboard_event) == mir_keyboard_action_down ? GDK_KEY_PRESS : GDK_KEY_RELEASE,
101+- modifier_state,
102+- mir_keyboard_event_key_code (keyboard_event),
103+- mir_keyboard_event_scan_code (keyboard_event),
104+- _gdk_mir_keymap_key_is_modifier (keymap, mir_keyboard_event_key_code (keyboard_event)),
105+- NANO_TO_MILLI (mir_input_event_get_event_time (event)));
106+- break;
107+- default:
108+- //case mir_key_action_multiple:
109+- // FIXME
110+- break;
111+- }
112++ _gdk_mir_window_impl_get_cursor_state (impl, NULL, NULL, NULL, &button_state);
113++ modifier_state = get_modifier_state (mir_keyboard_event_modifiers (keyboard_event), button_state);
114++ keymap = gdk_keymap_get_for_display (gdk_window_get_display (window));
115++
116++ generate_key_event (window,
117++ mir_keyboard_event_action (keyboard_event) == mir_keyboard_action_up ? GDK_KEY_RELEASE : GDK_KEY_PRESS,
118++ modifier_state,
119++ mir_keyboard_event_key_code (keyboard_event),
120++ mir_keyboard_event_scan_code (keyboard_event),
121++ _gdk_mir_keymap_key_is_modifier (keymap, mir_keyboard_event_key_code (keyboard_event)),
122++ NANO_TO_MILLI (mir_input_event_get_event_time (event)));
123+ }
124+
125+ static void
126+@@ -324,18 +313,13 @@ handle_touch_event (GdkWindow *window,
127+
128+ for (i = 0; i < n; i++)
129+ {
130+- switch (mir_touch_event_action (mir_touch_event, i))
131+- {
132+- case mir_touch_action_up:
133+- gdk_event = gdk_event_new (GDK_TOUCH_END);
134+- break;
135+- case mir_touch_action_down:
136+- gdk_event = gdk_event_new (GDK_TOUCH_BEGIN);
137+- break;
138+- case mir_touch_action_change:
139+- gdk_event = gdk_event_new (GDK_TOUCH_UPDATE);
140+- break;
141+- }
142++ MirTouchAction action = mir_touch_event_action (mir_touch_event, i);
143++ if (action == mir_touch_action_up)
144++ gdk_event = gdk_event_new (GDK_TOUCH_END);
145++ else if (action == mir_touch_action_down)
146++ gdk_event = gdk_event_new (GDK_TOUCH_BEGIN);
147++ else
148++ gdk_event = gdk_event_new (GDK_TOUCH_UPDATE);
149+
150+ gdk_event->touch.window = window;
151+ gdk_event->touch.sequence = GINT_TO_POINTER (mir_touch_event_id (mir_touch_event, i));
152+@@ -543,6 +527,13 @@ handle_close_event (GdkWindow *window)
153+ gdk_window_destroy_notify (window);
154+ }
155+
156++static void
157++handle_surface_output_event (GdkWindow *window,
158++ const MirSurfaceOutputEvent *event)
159++{
160++ _gdk_mir_window_set_surface_output (window, mir_surface_output_event_get_scale (event));
161++}
162++
163+ typedef struct
164+ {
165+ GdkWindow *window;
166+@@ -597,6 +588,9 @@ gdk_mir_event_source_queue_event (GdkDisplay *display,
167+ case mir_event_type_close_surface:
168+ handle_close_event (window);
169+ break;
170++ case mir_event_type_surface_output:
171++ handle_surface_output_event (window, mir_event_get_surface_output_event (event));
172++ break;
173+ default:
174+ g_warning ("Ignoring unknown Mir event %d", mir_event_get_type (event));
175+ // FIXME?
176+diff --git a/gdk/mir/gdkmirscreen.c b/gdk/mir/gdkmirscreen.c
177+index 7aa0aa6..b369b03 100644
178+--- a/gdk/mir/gdkmirscreen.c
179++++ b/gdk/mir/gdkmirscreen.c
180+@@ -257,7 +257,6 @@ gdk_mir_screen_get_root_window (GdkScreen *screen)
181+ get_screen_size (GDK_MIR_SCREEN (screen)->display_config, &width, &height);
182+
183+ s->root_window = _gdk_display_create_window (s->display);
184+- s->root_window->impl = _gdk_mir_window_impl_new ();
185+ s->root_window->impl_window = s->root_window;
186+ s->root_window->visual = s->visual;
187+ s->root_window->window_type = GDK_WINDOW_ROOT;
188+@@ -269,6 +268,7 @@ gdk_mir_screen_get_root_window (GdkScreen *screen)
189+ s->root_window->width = width;
190+ s->root_window->height = height;
191+ s->root_window->viewable = TRUE;
192++ s->root_window->impl = _gdk_mir_window_impl_new (s->display, s->root_window, NULL, 0);
193+
194+ return s->root_window;
195+ }
196+@@ -352,6 +352,8 @@ gdk_mir_screen_get_monitor_plug_name (GdkScreen *screen,
197+ return g_strdup_printf ("TV-%u", output->output_id);
198+ case mir_display_output_type_edp:
199+ return g_strdup_printf ("eDP-%u", output->output_id);
200++ case mir_display_output_type_virtual:
201++ return g_strdup_printf ("Virtual-%u", output->output_id);
202+ }
203+ }
204+
205+diff --git a/gdk/mir/gdkmirwindowimpl.c b/gdk/mir/gdkmirwindowimpl.c
206+index 5ca9d89..fc37c7e 100644
207+--- a/gdk/mir/gdkmirwindowimpl.c
208++++ b/gdk/mir/gdkmirwindowimpl.c
209+@@ -16,6 +16,7 @@
210+ */
211+
212+ #include <inttypes.h>
213++#include <math.h>
214+
215+ #include "config.h"
216+
217+@@ -28,6 +29,7 @@
218+ #include "gdkintl.h"
219+ #include "gdkdisplayprivate.h"
220+ #include "gdkdeviceprivate.h"
221++#include "gdkframeclockprivate.h"
222+
223+ #define GDK_MIR_WINDOW_IMPL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_WINDOW_IMPL_MIR, GdkMirWindowImplClass))
224+ #define GDK_IS_WINDOW_IMPL_MIR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_WINDOW_IMPL_MIR))
225+@@ -58,12 +60,21 @@ struct _GdkMirWindowImpl
226+ gdouble y;
227+ guint button_state;
228+
229++ GdkDisplay *display;
230++
231+ /* Surface being rendered to (only exists when window visible) */
232+ MirSurface *surface;
233++ MirBufferStream *buffer_stream;
234++ MirBufferUsage buffer_usage;
235+
236+ /* Cairo context for current frame */
237+ cairo_surface_t *cairo_surface;
238+
239++ gchar *title;
240++
241++ GdkGeometry geometry_hints;
242++ GdkWindowHints geometry_mask;
243++
244+ /* Egl surface for the current mir surface */
245+ EGLSurface egl_surface;
246+
247+@@ -75,6 +86,12 @@ struct _GdkMirWindowImpl
248+
249+ /* TRUE if cursor is inside this window */
250+ gboolean cursor_inside;
251++
252++ gboolean pending_redraw;
253++ gboolean pending_commit;
254++ gboolean pending_swap;
255++ gboolean pending_spec_update;
256++ gint output_scale;
257+ };
258+
259+ struct _GdkMirWindowImplClass
260+@@ -85,11 +102,97 @@ struct _GdkMirWindowImplClass
261+ G_DEFINE_TYPE (GdkMirWindowImpl, gdk_mir_window_impl, GDK_TYPE_WINDOW_IMPL)
262+
263+ static cairo_surface_t *gdk_mir_window_impl_ref_cairo_surface (GdkWindow *window);
264++static void on_frame_clock_after_paint (GdkFrameClock *clock, GdkWindow *window);
265++static void ensure_surface (GdkWindow *window);
266++static void apply_geometry_hints (MirSurfaceSpec *spec, GdkMirWindowImpl *impl);
267++
268++static gboolean
269++type_hint_differs (GdkWindowTypeHint lhs, GdkWindowTypeHint rhs)
270++{
271++ if (lhs == rhs)
272++ return FALSE;
273++
274++ switch (lhs)
275++ {
276++ case GDK_WINDOW_TYPE_HINT_DIALOG:
277++ case GDK_WINDOW_TYPE_HINT_DOCK:
278++ return rhs != GDK_WINDOW_TYPE_HINT_DIALOG &&
279++ rhs != GDK_WINDOW_TYPE_HINT_DOCK;
280++ case GDK_WINDOW_TYPE_HINT_MENU:
281++ case GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU:
282++ case GDK_WINDOW_TYPE_HINT_POPUP_MENU:
283++ case GDK_WINDOW_TYPE_HINT_TOOLBAR:
284++ case GDK_WINDOW_TYPE_HINT_COMBO:
285++ return rhs != GDK_WINDOW_TYPE_HINT_MENU &&
286++ rhs != GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU &&
287++ rhs != GDK_WINDOW_TYPE_HINT_POPUP_MENU &&
288++ rhs != GDK_WINDOW_TYPE_HINT_TOOLBAR &&
289++ rhs != GDK_WINDOW_TYPE_HINT_COMBO;
290++ case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
291++ case GDK_WINDOW_TYPE_HINT_UTILITY:
292++ return rhs != GDK_WINDOW_TYPE_HINT_SPLASHSCREEN &&
293++ rhs != GDK_WINDOW_TYPE_HINT_UTILITY;
294++ case GDK_WINDOW_TYPE_HINT_DND:
295++ case GDK_WINDOW_TYPE_HINT_TOOLTIP:
296++ case GDK_WINDOW_TYPE_HINT_NOTIFICATION:
297++ return rhs != GDK_WINDOW_TYPE_HINT_DND &&
298++ rhs != GDK_WINDOW_TYPE_HINT_TOOLTIP &&
299++ rhs != GDK_WINDOW_TYPE_HINT_NOTIFICATION;
300++ case GDK_WINDOW_TYPE_HINT_NORMAL:
301++ case GDK_WINDOW_TYPE_HINT_DESKTOP:
302++ default:
303++ return rhs != GDK_WINDOW_TYPE_HINT_NORMAL &&
304++ rhs != GDK_WINDOW_TYPE_HINT_DESKTOP;
305++ }
306++}
307++
308++static void
309++drop_cairo_surface (GdkWindow *window)
310++{
311++ GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
312++
313++ g_clear_pointer (&impl->cairo_surface, cairo_surface_destroy);
314++}
315++
316++static const gchar *
317++get_default_title (void)
318++{
319++ const char *title;
320++
321++ title = g_get_application_name ();
322++ if (!title)
323++ title = g_get_prgname ();
324++ if (!title)
325++ title = "";
326++
327++ return title;
328++}
329+
330+ GdkWindowImpl *
331+-_gdk_mir_window_impl_new (void)
332++_gdk_mir_window_impl_new (GdkDisplay *display, GdkWindow *window, GdkWindowAttr *attributes, gint attributes_mask)
333+ {
334+- return g_object_new (GDK_TYPE_MIR_WINDOW_IMPL, NULL);
335++ GdkFrameClock *frame_clock = gdk_window_get_frame_clock (window);
336++ GdkMirWindowImpl *impl = g_object_new (GDK_TYPE_MIR_WINDOW_IMPL, NULL);
337++
338++ impl->display = display;
339++
340++ if (attributes && attributes_mask & GDK_WA_TITLE)
341++ impl->title = g_strdup (attributes->title);
342++ else
343++ impl->title = g_strdup (get_default_title ());
344++
345++ if (attributes && attributes_mask & GDK_WA_TYPE_HINT)
346++ impl->type_hint = attributes->type_hint;
347++
348++ impl->pending_spec_update = TRUE;
349++
350++ if (window->window_type != GDK_WINDOW_ROOT)
351++ {
352++ g_signal_connect (frame_clock, "after-paint",
353++ G_CALLBACK (on_frame_clock_after_paint), window);
354++ }
355++
356++ return (GdkWindowImpl *) impl;
357+ }
358+
359+ void
360+@@ -139,18 +242,25 @@ gdk_mir_window_impl_init (GdkMirWindowImpl *impl)
361+ {
362+ impl->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
363+ impl->surface_state = mir_surface_state_unknown;
364++ impl->output_scale = 1;
365+ }
366+
367+ static void
368+ set_surface_state (GdkMirWindowImpl *impl,
369+ MirSurfaceState state)
370+ {
371++ MirConnection *connection = gdk_mir_display_get_mir_connection (impl->display);
372+ if (impl->surface_state == state)
373+ return;
374+
375+ impl->surface_state = state;
376+- if (impl->surface)
377+- mir_surface_set_state (impl->surface, state);
378++ if (impl->surface && !impl->pending_spec_update)
379++ {
380++ MirSurfaceSpec *spec = mir_connection_create_spec_for_changes (connection);
381++ mir_surface_spec_set_state (spec, state);
382++ mir_surface_apply_spec (impl->surface, spec);
383++ mir_surface_spec_release (spec);
384++ }
385+ }
386+
387+ static void
388+@@ -161,26 +271,21 @@ event_cb (MirSurface *surface,
389+ _gdk_mir_event_source_queue (context, event);
390+ }
391+
392+-static void ensure_surface (GdkWindow *window);
393+-
394+-static MirSurface *
395+-create_mir_surface (GdkDisplay *display,
396+- GdkWindow *parent,
397+- gint x,
398+- gint y,
399+- gint width,
400+- gint height,
401+- GdkWindowTypeHint type,
402+- MirBufferUsage buffer_usage)
403++static MirSurfaceSpec *
404++create_window_type_spec (GdkDisplay *display,
405++ GdkWindow *parent,
406++ gint x,
407++ gint y,
408++ gint width,
409++ gint height,
410++ GdkWindowTypeHint type,
411++ MirBufferUsage buffer_usage)
412+ {
413+- MirSurface *parent_surface = NULL;
414+- MirSurfaceSpec *spec;
415+- MirConnection *connection;
416+- MirPixelFormat format;
417+- MirSurface *surface;
418+ MirRectangle rect;
419++ MirPixelFormat format;
420++ MirSurface *parent_surface = NULL;
421++ MirConnection *connection = gdk_mir_display_get_mir_connection (display);
422+
423+- connection = gdk_mir_display_get_mir_connection (display);
424+ format = _gdk_mir_display_get_pixel_format (display, buffer_usage);
425+
426+ if (parent && parent->impl)
427+@@ -206,11 +311,10 @@ create_mir_surface (GdkDisplay *display,
428+ {
429+ case GDK_WINDOW_TYPE_HINT_DIALOG:
430+ case GDK_WINDOW_TYPE_HINT_DOCK:
431+- spec = mir_connection_create_spec_for_dialog (connection,
432++ return mir_connection_create_spec_for_dialog (connection,
433+ width,
434+ height,
435+ format);
436+- break;
437+ case GDK_WINDOW_TYPE_HINT_MENU:
438+ case GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU:
439+ case GDK_WINDOW_TYPE_HINT_POPUP_MENU:
440+@@ -220,22 +324,20 @@ create_mir_surface (GdkDisplay *display,
441+ rect.top = y;
442+ rect.width = 1;
443+ rect.height = 1;
444+- spec = mir_connection_create_spec_for_menu (connection,
445++ return mir_connection_create_spec_for_menu (connection,
446+ width,
447+ height,
448+ format,
449+ parent_surface,
450+ &rect,
451+ mir_edge_attachment_any);
452+- break;
453+ case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
454+ case GDK_WINDOW_TYPE_HINT_UTILITY:
455+- spec = mir_connection_create_spec_for_modal_dialog (connection,
456++ return mir_connection_create_spec_for_modal_dialog (connection,
457+ width,
458+ height,
459+ format,
460+ parent_surface);
461+- break;
462+ case GDK_WINDOW_TYPE_HINT_DND:
463+ case GDK_WINDOW_TYPE_HINT_TOOLTIP:
464+ case GDK_WINDOW_TYPE_HINT_NOTIFICATION:
465+@@ -243,7 +345,7 @@ create_mir_surface (GdkDisplay *display,
466+ rect.top = y;
467+ rect.width = 1;
468+ rect.height = 1;
469+- spec = mir_connection_create_spec_for_tooltip (connection,
470++ return mir_connection_create_spec_for_tooltip (connection,
471+ width,
472+ height,
473+ format,
474+@@ -253,19 +355,73 @@ create_mir_surface (GdkDisplay *display,
475+ case GDK_WINDOW_TYPE_HINT_NORMAL:
476+ case GDK_WINDOW_TYPE_HINT_DESKTOP:
477+ default:
478+- spec = mir_connection_create_spec_for_normal_surface (connection,
479++ return mir_connection_create_spec_for_normal_surface (connection,
480+ width,
481+ height,
482+ format);
483+- break;
484+ }
485++}
486+
487+- mir_surface_spec_set_name (spec, g_get_prgname ());
488+- mir_surface_spec_set_buffer_usage (spec, buffer_usage);
489+- surface = mir_surface_create_sync (spec);
490+- mir_surface_spec_release (spec);
491++static void
492++apply_geometry_hints (MirSurfaceSpec *spec, GdkMirWindowImpl *impl)
493++{
494++ if (impl->geometry_mask & GDK_HINT_RESIZE_INC)
495++ {
496++ mir_surface_spec_set_width_increment (spec, impl->geometry_hints.width_inc);
497++ mir_surface_spec_set_height_increment (spec, impl->geometry_hints.height_inc);
498++ }
499++ if (impl->geometry_mask & GDK_HINT_MIN_SIZE)
500++ {
501++ mir_surface_spec_set_min_width (spec, impl->geometry_hints.min_width);
502++ mir_surface_spec_set_min_height (spec, impl->geometry_hints.min_height);
503++ }
504++ if (impl->geometry_mask & GDK_HINT_MAX_SIZE)
505++ {
506++ mir_surface_spec_set_max_width (spec, impl->geometry_hints.max_width);
507++ mir_surface_spec_set_max_height (spec, impl->geometry_hints.max_height);
508++ }
509++ if (impl->geometry_mask & GDK_HINT_ASPECT)
510++ {
511++ mir_surface_spec_set_min_aspect_ratio (spec, 1000, (unsigned)(1000.0/impl->geometry_hints.min_aspect));
512++ mir_surface_spec_set_max_aspect_ratio (spec, 1000, (unsigned)(1000.0/impl->geometry_hints.max_aspect));
513++ }
514++}
515++
516++static MirSurfaceSpec*
517++create_spec (GdkWindow *window, GdkMirWindowImpl *impl)
518++{
519++ MirSurfaceSpec *spec = NULL;
520++
521++ spec = create_window_type_spec (impl->display,
522++ impl->transient_for,
523++ impl->transient_x, impl->transient_y,
524++ window->width, window->height,
525++ impl->type_hint,
526++ impl->buffer_usage);
527++
528++ mir_surface_spec_set_name (spec, impl->title);
529++ mir_surface_spec_set_buffer_usage (spec, impl->buffer_usage);
530++
531++ apply_geometry_hints (spec, impl);
532++
533++ return spec;
534++}
535++
536++static void
537++update_surface_spec (GdkWindow *window)
538++{
539++ GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
540++ MirSurfaceSpec *spec;
541++
542++ if (!impl->surface)
543++ return;
544++
545++ spec = create_spec (window, impl);
546+
547+- return surface;
548++ mir_surface_apply_spec (impl->surface, spec);
549++ mir_surface_spec_release (spec);
550++ impl->pending_spec_update = FALSE;
551++ impl->buffer_stream = mir_surface_get_buffer_stream (impl->surface);
552+ }
553+
554+ static GdkDevice *
555+@@ -319,20 +475,29 @@ ensure_surface_full (GdkWindow *window,
556+ {
557+ GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
558+ GdkMirWindowReference *window_ref;
559++ MirSurfaceSpec *spec;
560+
561+ if (impl->surface)
562+- return;
563++ {
564++ if (impl->pending_spec_update)
565++ update_surface_spec(window);
566++ return;
567++ }
568+
569+ /* no destroy notify -- we must leak for now
570+ * https://bugs.launchpad.net/mir/+bug/1324100
571+ */
572+ window_ref = _gdk_mir_event_source_get_window_reference (window);
573++ impl->buffer_usage = buffer_usage;
574++
575++ spec = create_spec (window, impl);
576++
577++ impl->surface = mir_surface_create_sync (spec);
578+
579+- impl->surface = create_mir_surface (gdk_window_get_display (window), impl->transient_for,
580+- impl->transient_x, impl->transient_y,
581+- window->width, window->height,
582+- impl->type_hint,
583+- buffer_usage);
584++ mir_surface_spec_release(spec);
585++
586++ impl->pending_spec_update = FALSE;
587++ impl->buffer_stream = mir_surface_get_buffer_stream (impl->surface);
588+
589+ /* FIXME: can't make an initial resize event */
590+ // MirEvent *resize_event;
591+@@ -356,9 +521,10 @@ ensure_surface_full (GdkWindow *window,
592+ static void
593+ ensure_surface (GdkWindow *window)
594+ {
595+- ensure_surface_full (window, window->gl_paint_context ?
596+- mir_buffer_usage_hardware :
597+- mir_buffer_usage_software);
598++ ensure_surface_full (window,
599++ window->gl_paint_context ?
600++ mir_buffer_usage_hardware :
601++ mir_buffer_usage_software);
602+ }
603+
604+ static void
605+@@ -390,19 +556,63 @@ ensure_no_surface (GdkWindow *window)
606+ }
607+ }
608+
609++ impl->pending_commit = FALSE;
610++ impl->pending_swap = FALSE;
611+ g_clear_pointer(&impl->surface, mir_surface_release_sync);
612+ }
613+
614+ static void
615+-send_buffer (GdkWindow *window)
616++on_swap_buffer_completed (MirBufferStream *stream, void *data)
617+ {
618++ GdkWindow *window = data;
619+ GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
620+
621+- /* Send the completed buffer to Mir */
622+- mir_buffer_stream_swap_buffers_sync (mir_surface_get_buffer_stream (impl->surface));
623+-
624+ /* The Cairo context is no longer valid */
625+ g_clear_pointer (&impl->cairo_surface, cairo_surface_destroy);
626++ impl->pending_swap = FALSE;
627++
628++ _gdk_frame_clock_thaw (gdk_window_get_frame_clock (window));
629++}
630++
631++static void
632++on_frame_clock_after_paint (GdkFrameClock *clock,
633++ GdkWindow *window)
634++{
635++ GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
636++
637++ if (!impl->pending_commit)
638++ return;
639++
640++ impl->pending_commit = FALSE;
641++ _gdk_frame_clock_freeze (clock);
642++
643++ if (impl->pending_spec_update)
644++ update_surface_spec (window);
645++
646++ impl->pending_spec_update = FALSE;
647++
648++ /* Send the completed buffer to Mir */
649++ impl->pending_swap = TRUE;
650++ mir_buffer_stream_swap_buffers (impl->buffer_stream, on_swap_buffer_completed, window);
651++}
652++
653++static void
654++send_buffer_delayed (GdkWindow *window)
655++{
656++ GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
657++
658++ if (impl->pending_swap || impl->pending_commit)
659++ return;
660++
661++ impl->pending_commit = TRUE;
662++}
663++
664++static void
665++send_buffer (GdkWindow *window)
666++{
667++ send_buffer_delayed (window);
668++ gdk_frame_clock_request_phase (gdk_window_get_frame_clock (window),
669++ GDK_FRAME_CLOCK_PHASE_AFTER_PAINT);
670+ }
671+
672+ static cairo_surface_t *
673+@@ -421,15 +631,16 @@ gdk_mir_window_impl_ref_cairo_surface (GdkWindow *window)
674+ return impl->cairo_surface;
675+ }
676+
677++ ensure_surface (window);
678++
679+ /* Transient windows get rendered into a buffer and copied onto their parent */
680+ if (window->gl_paint_context)
681+ {
682+ cairo_surface = cairo_image_surface_create (pixel_format, window->width, window->height);
683++ cairo_surface_set_device_scale (cairo_surface, (double) impl->output_scale, (double) impl->output_scale);
684+ }
685+ else if (impl->visible)
686+ {
687+- ensure_surface (window);
688+-
689+ mir_buffer_stream_get_graphics_region (mir_surface_get_buffer_stream (impl->surface), &region);
690+
691+ switch (region.pixel_format)
692+@@ -473,6 +684,7 @@ gdk_mir_window_impl_ref_cairo_surface (GdkWindow *window)
693+ region.width,
694+ region.height,
695+ region.stride);
696++ cairo_surface_set_device_scale (cairo_surface, (double) impl->output_scale, (double) impl->output_scale);
697+ }
698+ else
699+ cairo_surface = cairo_image_surface_create (pixel_format, 0, 0);
700+@@ -506,6 +718,7 @@ gdk_mir_window_impl_finalize (GObject *object)
701+ {
702+ GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (object);
703+
704++ g_free (impl->title);
705+ if (impl->background)
706+ cairo_pattern_destroy (impl->background);
707+ if (impl->surface)
708+@@ -526,6 +739,7 @@ gdk_mir_window_impl_show (GdkWindow *window,
709+ //g_printerr ("gdk_mir_window_impl_show window=%p\n", window);
710+
711+ impl->visible = TRUE;
712++ set_surface_state (impl, mir_surface_state_restored);
713+
714+ /* Make sure there's a surface to see */
715+ ensure_surface (window);
716+@@ -547,7 +761,8 @@ gdk_mir_window_impl_hide (GdkWindow *window)
717+
718+ impl->cursor_inside = FALSE;
719+ impl->visible = FALSE;
720+- ensure_no_surface (window);
721++
722++ set_surface_state (impl, mir_surface_state_hidden);
723+ }
724+
725+ static void
726+@@ -558,7 +773,8 @@ gdk_mir_window_impl_withdraw (GdkWindow *window)
727+
728+ impl->cursor_inside = FALSE;
729+ impl->visible = FALSE;
730+- ensure_no_surface (window);
731++
732++ set_surface_state (impl, mir_surface_state_hidden);
733+ }
734+
735+ static void
736+@@ -610,32 +826,28 @@ gdk_mir_window_impl_move_resize (GdkWindow *window,
737+ g_printerr ("\n");
738+ */
739+ GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
740+- gboolean recreate_surface = FALSE;
741+-
742+- /* Transient windows can move wherever they want */
743+- if (with_move)
744+- {
745+- if (x != impl->transient_x || y != impl->transient_y)
746+- {
747+- impl->transient_x = x;
748+- impl->transient_y = y;
749+- recreate_surface = TRUE;
750+- }
751+- }
752++ //g_printerr ("gdk_mir_window_impl_move_resize window=%p, impl=%p\n", window, impl);
753+
754+ /* If resize requested then rebuild surface */
755+- if (width >= 0)
756++ if (width >= 0 && (window->width != width || window->height != height))
757+ {
758+ /* We accept any resize */
759+ window->width = width;
760+ window->height = height;
761+- recreate_surface = TRUE;
762++ impl->pending_redraw = TRUE;
763++ impl->pending_spec_update = TRUE;
764+ }
765+
766+- if (recreate_surface && impl->surface)
767++ /* Transient windows can move wherever they want */
768++ if (with_move)
769+ {
770+- ensure_no_surface (window);
771+- ensure_surface (window);
772++ if (x != impl->transient_x || y != impl->transient_y)
773++ {
774++ impl->transient_x = x;
775++ impl->transient_y = y;
776++ if (!impl->pending_spec_update && impl->surface)
777++ update_surface_spec (window);
778++ }
779+ }
780+ }
781+
782+@@ -754,9 +966,12 @@ gdk_mir_window_impl_get_device_state (GdkWindow *window,
783+ static gboolean
784+ gdk_mir_window_impl_begin_paint (GdkWindow *window)
785+ {
786++ GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
787++
788++ ensure_surface (window);
789+ //g_printerr ("gdk_mir_window_impl_begin_paint window=%p\n", window);
790+ /* Indicate we are ready to be drawn onto directly? */
791+- return FALSE;
792++ return impl->pending_swap;
793+ }
794+
795+ static void
796+@@ -832,10 +1047,11 @@ gdk_mir_window_impl_set_type_hint (GdkWindow *window,
797+ {
798+ GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
799+
800+- if (hint != impl->type_hint)
801++ if (type_hint_differs (hint, impl->type_hint))
802+ {
803+ impl->type_hint = hint;
804+- ensure_no_surface (window);
805++ if (impl->surface && !impl->pending_spec_update)
806++ update_surface_spec (window);
807+ }
808+ }
809+
810+@@ -881,15 +1097,39 @@ gdk_mir_window_impl_set_geometry_hints (GdkWindow *window,
811+ const GdkGeometry *geometry,
812+ GdkWindowHints geom_mask)
813+ {
814+- //g_printerr ("gdk_mir_window_impl_set_geometry_hints window=%p\n", window);
815+- //FIXME: ?
816++ GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
817++ MirConnection *connection = gdk_mir_display_get_mir_connection (impl->display);
818++ //g_printerr ("gdk_mir_window_impl_set_geometry_hints window=%p impl=%p\n", window, impl);
819++
820++ impl->geometry_hints = *geometry;
821++ impl->geometry_mask = geom_mask;
822++
823++ if (impl->surface && !impl->pending_spec_update)
824++ {
825++ MirSurfaceSpec* spec = mir_connection_create_spec_for_changes (connection);
826++ apply_geometry_hints (spec, impl);
827++ mir_surface_apply_spec (impl->surface, spec);
828++ mir_surface_spec_release (spec);
829++ }
830+ }
831+
832+ static void
833+ gdk_mir_window_impl_set_title (GdkWindow *window,
834+ const gchar *title)
835+ {
836+- // g_printerr ("gdk_mir_window_impl_set_title window=%p\n", window);
837++ GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
838++ MirConnection *connection = gdk_mir_display_get_mir_connection (impl->display);
839++ //g_printerr ("gdk_mir_window_impl_set_title window=%p\n", window);
840++
841++ g_free (impl->title);
842++ impl->title = g_strdup (title);
843++ if (impl->surface && !impl->pending_spec_update)
844++ {
845++ MirSurfaceSpec* spec = mir_connection_create_spec_for_changes (connection);
846++ mir_surface_spec_set_name (spec, impl->title);
847++ mir_surface_apply_spec (impl->surface, spec);
848++ mir_surface_spec_release (spec);
849++ }
850+ }
851+
852+ static void
853+@@ -918,6 +1158,9 @@ gdk_mir_window_impl_set_transient_for (GdkWindow *window,
854+
855+ /* Link this window to the parent */
856+ impl->transient_for = parent;
857++
858++ if (impl->surface && !impl->pending_spec_update)
859++ update_surface_spec (window);
860+ }
861+
862+ static void
863+@@ -1247,8 +1490,8 @@ static gint
864+ gdk_mir_window_impl_get_scale_factor (GdkWindow *window)
865+ {
866+ //g_printerr ("gdk_mir_window_impl_get_scale_factor window=%p\n", window);
867+- /* Don't support monitor scaling */
868+- return 1;
869++ GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
870++ return impl->output_scale;
871+ }
872+
873+ static void
874+@@ -1460,7 +1703,7 @@ _gdk_mir_window_get_egl_surface (GdkWindow *window,
875+ ensure_surface_full (window, mir_buffer_usage_hardware);
876+
877+ egl_display = _gdk_mir_display_get_egl_display (gdk_window_get_display (window));
878+- egl_window = (EGLNativeWindowType) mir_buffer_stream_get_egl_native_window (mir_surface_get_buffer_stream (impl->surface));
879++ egl_window = (EGLNativeWindowType) mir_buffer_stream_get_egl_native_window (impl->buffer_stream);
880+
881+ impl->egl_surface =
882+ eglCreateWindowSurface (egl_display, config, egl_window, NULL);
883+@@ -1485,7 +1728,7 @@ _gdk_mir_window_get_dummy_egl_surface (GdkWindow *window,
884+
885+ display = gdk_window_get_display (window);
886+ egl_display = _gdk_mir_display_get_egl_display (display);
887+- egl_window = (EGLNativeWindowType) mir_buffer_stream_get_egl_native_window (mir_surface_get_buffer_stream (impl->surface));
888++ egl_window = (EGLNativeWindowType) mir_buffer_stream_get_egl_native_window (impl->buffer_stream);
889+
890+ impl->dummy_egl_surface =
891+ eglCreateWindowSurface (egl_display, config, egl_window, NULL);
892+@@ -1506,6 +1749,30 @@ gdk_mir_window_get_mir_surface (GdkWindow *window)
893+ return impl->surface;
894+ }
895+
896++void
897++_gdk_mir_window_set_surface_output (GdkWindow *window, gdouble scale)
898++{
899++ // g_printerr ("_gdk_mir_window_impl_set_surface_output impl=%p\n", impl);
900++ GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
901++ GdkRectangle area = {0, 0, window->width, window->height};
902++ cairo_region_t *region;
903++ gint new_scale = (gint) round (scale);
904++
905++ if (impl->output_scale != new_scale)
906++ {
907++ impl->output_scale = new_scale;
908++
909++ drop_cairo_surface (window);
910++
911++ if (impl->buffer_stream)
912++ mir_buffer_stream_set_scale (impl->buffer_stream, (float) new_scale);
913++
914++ region = cairo_region_create_rectangle (&area);
915++ _gdk_window_invalidate_for_expose (window, region);
916++ cairo_region_destroy (region);
917++ }
918++}
919++
920+ static void
921+ gdk_mir_window_impl_class_init (GdkMirWindowImplClass *klass)
922+ {
923+--
924+2.8.1
925+
926
927=== modified file 'debian/patches/series'
928--- debian/patches/series 2016-07-29 12:47:27 +0000
929+++ debian/patches/series 2016-08-01 15:06:42 +0000
930@@ -23,3 +23,4 @@
931 ubuntu_fileselector_behaviour.patch
932 unity-border-radius.patch
933 unity-headerbar-maximized-mode.patch
934+0001-Update-the-GDK-Mir-backend-to-fix-a-few-problems.patch

Subscribers

People subscribed via source and target branches

to all changes: