Merge lp:~unity-team/compiz/x-sru6 into lp:compiz/0.9.13

Proposed by Marco Trevisan (Treviño)
Status: Superseded
Proposed branch: lp:~unity-team/compiz/x-sru6
Merge into: lp:compiz/0.9.13
Diff against target: 1727 lines (+1673/-1) (has conflicts)
5 files modified
VERSION (+4/-0)
debian/changelog (+108/-0)
gtk/window-decorator/decorator.c (+2/-0)
gtk/window-decorator/metacity.c.OTHER (+1555/-0)
src/region/src/region.cpp (+4/-1)
Text conflict in VERSION
Text conflict in debian/changelog
Contents conflict in gtk/window-decorator/metacity.c
To merge this branch: bzr merge lp:~unity-team/compiz/x-sru6
Reviewer Review Type Date Requested Status
Compiz Maintainers Pending
Review via email: mp+338344@code.launchpad.net

This proposal has been superseded by a proposal from 2018-02-20.

Commit message

Releasing Xenial Compiz SRU6

To post a comment you must log in.
lp:~unity-team/compiz/x-sru6 updated
4021. By Marco Trevisan (Treviño)

Region: define static const functions returning infinite and empty regions

See https://gcc.gnu.org/ml/gcc-help/2010-10/msg00255.html

Unmerged revisions

4021. By Marco Trevisan (Treviño)

Region: define static const functions returning infinite and empty regions

See https://gcc.gnu.org/ml/gcc-help/2010-10/msg00255.html

4020. By CI Train Bot Account

Releasing 1:0.9.12.3+16.04.20171116-0ubuntu1

4019. By CI Train Bot Account

* Added option to disable blend in grid plugin (LP: #1700859)
* Move: add options for showing only the window shape (filled or not)
  (LP: #1700859)
* Ensure that surfaces used by metacity theme have device scale set to
  1 . (LP: #1530277) (LP: #1530277)
* Use AnyPropertyType when getting _MOTIF_WM_HINTS property. (LP:
  #1702297)
* mate: Avoid artefacts of Windows Thumbnail Previews (LP: #1606369)
* move: damage all the border area in outline mode and ignore
  transparent colors (LP: #1700859)
* grid: ignore alpha in colors when not blending, and fix animations
  (LP: #1700859)
* resize: add support for disabling transparency and avoid over-
  damaging in outline mode (LP: #1700859)
* Screen: add averageColor to get the current desktop average color
* unity-lowgfx.ini: remove unsupported unity option

4018. By CI Train Bot Account

Releasing 1:0.9.12.2+16.04.20160823-0ubuntu1

4017. By CI Train Bot Account

[expo] limit scroll to workarea. (LP: #913880)

4016. By CI Train Bot Account

Releasing 1:0.9.12.2+16.04.20160801.3-0ubuntu1

4015. By CI Train Bot Account

* Don't activate expo if not needed (1x1 setup) (LP: #1606254)
* Don't crash if gsettings key is not found. Default value will be
  used. (LP: #1044662)
* focusDefaultWindow: focus Most Recently Used (MRU) window and
  fallback to the top window in case MRU list is not available. (LP:
  #1073488, LP: #1459671)
* Unity MigrationScript: sync gsettings on exit, and only use dconf on
  failure (LP: #1605011)

4014. By CI Train Bot Account

Releasing 1:0.9.12.2+16.04.20160714-0ubuntu1

4013. By CI Train Bot Account

* Added options for no animation in expo and scale plugins. They skip
  the intermediate fading steps that force several redraws.
* Added a new option in show desktop plugin that skips the fade
  animation: useful when performance is more important than eyecandy.
* debian: add unity-lowgfx profile to compizconfig (LP: #1598770)
* Composite: use C++ goodness for managing damaging rectangles
* ccsGSettingsBackend: don't try to update setting if wrapper is not
  found
* migration scripts: remove unsupported plugins for all the unity
  profiles

4012. By CI Train Bot Account

Releasing 1:0.9.12.2+16.04.20160526-0ubuntu1

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'VERSION'
2--- VERSION 2016-11-11 16:21:01 +0000
3+++ VERSION 2018-02-20 17:39:33 +0000
4@@ -1,1 +1,5 @@
5+<<<<<<< TREE
6 0.9.13.1
7+=======
8+0.9.12.3
9+>>>>>>> MERGE-SOURCE
10
11=== modified file 'debian/changelog'
12--- debian/changelog 2017-11-16 03:25:55 +0000
13+++ debian/changelog 2018-02-20 17:39:33 +0000
14@@ -1,3 +1,4 @@
15+<<<<<<< TREE
16 compiz (1:0.9.13.1+18.04.20171116-0ubuntu1) bionic; urgency=medium
17
18 [ Marco Trevisan (Treviño) ]
19@@ -379,6 +380,113 @@
20
21 -- Matthias Klose <doko@ubuntu.com> Sat, 23 Apr 2016 00:01:37 +0000
22
23+=======
24+compiz (1:0.9.12.3+16.04.20171116-0ubuntu2) UNRELEASED; urgency=medium
25+
26+ * Region: nullify the priv XRegion after destroying it (LP: #1750619)
27+
28+ -- Marco Trevisan (Treviño) <mail@3v1n0.net> Tue, 20 Feb 2018 18:38:26 +0100
29+
30+compiz (1:0.9.12.3+16.04.20171116-0ubuntu1) xenial; urgency=medium
31+
32+ [ Eleni Maria Stea ]
33+ * Added option to disable blend in grid plugin (LP: #1700859)
34+ * Move: add options for showing only the window shape (filled or not)
35+ (LP: #1700859)
36+
37+ [ Alberts Muktupāvels ]
38+ * Ensure that surfaces used by metacity theme have device scale set to
39+ 1 . (LP: #1530277) (LP: #1530277)
40+ * Use AnyPropertyType when getting _MOTIF_WM_HINTS property. (LP:
41+ #1702297)
42+
43+ [ Martin Wimpress ]
44+ * mate: Avoid artefacts of Windows Thumbnail Previews (LP: #1606369)
45+
46+ [ Marco Trevisan (Treviño) ]
47+ * move: damage all the border area in outline mode and ignore
48+ transparent colors (LP: #1700859)
49+ * grid: ignore alpha in colors when not blending, and fix animations
50+ (LP: #1700859)
51+ * resize: add support for disabling transparency and avoid over-
52+ damaging in outline mode (LP: #1700859)
53+ * Screen: add averageColor to get the current desktop average color
54+ * unity-lowgfx.ini: remove unsupported unity option
55+
56+ -- Marco Trevisan (Treviño) <mail@3v1n0.net> Thu, 16 Nov 2017 23:00:54 +0000
57+
58+compiz (1:0.9.12.2+16.04.20160823-0ubuntu1) xenial; urgency=medium
59+
60+ [ Andrea Azzarone ]
61+ * [expo] limit scroll to workarea. (LP: #913880)
62+
63+ -- Marco Trevisan (Treviño) <mail@3v1n0.net> Tue, 23 Aug 2016 16:06:02 +0000
64+
65+compiz (1:0.9.12.2+16.04.20160801.3-0ubuntu1) xenial; urgency=medium
66+
67+ [ Andrea Azzarone ]
68+ * Don't activate expo if not needed (1x1 setup) (LP: #1606254)
69+ * Don't crash if gsettings key is not found. Default value will be
70+ used. (LP: #1044662)
71+ * focusDefaultWindow: focus Most Recently Used (MRU) window and
72+ fallback to the top window in case MRU list is not available. (LP:
73+ #1073488, LP: #1459671)
74+
75+ [ Marco Trevisan (Treviño) ]
76+ * Unity MigrationScript: sync gsettings on exit, and only use dconf on
77+ failure (LP: #1605011)
78+
79+ -- Marco Trevisan (Treviño) <mail@3v1n0.net> Mon, 01 Aug 2016 13:41:42 +0000
80+
81+compiz (1:0.9.12.2+16.04.20160714-0ubuntu1) xenial; urgency=medium
82+
83+ [ Eleni Maria Stea ]
84+ * Added options for no animation in expo and scale plugins. They skip
85+ the intermediate fading steps that force several redraws.
86+ * Added a new option in show desktop plugin that skips the fade
87+ animation: useful when performance is more important than eyecandy.
88+
89+ [ Marco Trevisan (Treviño) ]
90+ * debian: add unity-lowgfx profile to compizconfig (LP: #1598770)
91+ * Composite: use C++ goodness for managing damaging rectangles
92+ * ccsGSettingsBackend: don't try to update setting if wrapper is not
93+ found
94+ * migration scripts: remove unsupported plugins for all the unity
95+ profiles
96+
97+ -- Marco Trevisan (Treviño) <mail@3v1n0.net> Thu, 14 Jul 2016 16:00:57 +0000
98+
99+compiz (1:0.9.12.2+16.04.20160526-0ubuntu1) xenial; urgency=medium
100+
101+ [ Andrea Azzarone ]
102+ * Add an option to notify that a key press is actually an "auto
103+ repeat" one. (LP: #1572241)
104+
105+ [ Alberts Muktupāvels ]
106+ * OpenGL: use the number of Opaque windows around to decide whether
107+ paint the bg or not (LP: #1574866)
108+
109+ [ Marco Trevisan (Treviño) ]
110+ * Scale: use the selectedWindow as starting point when focusing a
111+ window (LP: #1575168)
112+ * Scale: allow to iterate through windows using Tab key
113+ * Window: call stateChangeNotify when compiz state changed but before
114+ changing the WM state (LP: #1521302)
115+
116+ [ Eleni Maria Stea ]
117+ * Expo, Scale: add support for bottom offsets (LP: #1562346, LP:
118+ #1573897)
119+
120+ [ handsome_feng ]
121+ * Add a YBottomOffset value when stretch maximized windows。 (LP:
122+ #1562348)
123+
124+ [ CI Train Bot ]
125+ * No-change rebuild.
126+
127+ -- Marco Trevisan (Treviño) <mail@3v1n0.net> Thu, 26 May 2016 00:12:16 +0000
128+
129+>>>>>>> MERGE-SOURCE
130 compiz (1:0.9.12.2+16.04.20160415-0ubuntu1) xenial; urgency=medium
131
132 [ Martin Wimpress ]
133
134=== modified file 'debian/mate.ini'
135=== modified file 'gtk/window-decorator/decorator.c'
136--- gtk/window-decorator/decorator.c 2017-04-02 17:32:10 +0000
137+++ gtk/window-decorator/decorator.c 2018-02-20 17:39:33 +0000
138@@ -553,6 +553,8 @@
139 }
140 #endif
141
142+ // FIXME: this should match the current monitor scaling!
143+ cairo_surface_set_device_scale (buffer_surface, 1, 1);
144 gdk_flush ();
145
146 /* Handle failure */
147
148=== added file 'gtk/window-decorator/metacity.c.OTHER'
149--- gtk/window-decorator/metacity.c.OTHER 1970-01-01 00:00:00 +0000
150+++ gtk/window-decorator/metacity.c.OTHER 2018-02-20 17:39:33 +0000
151@@ -0,0 +1,1555 @@
152+/*
153+ * Copyright © 2006 Novell, Inc.
154+ *
155+ * This library is free software; you can redistribute it and/or
156+ * modify it under the terms of the GNU Lesser General Public
157+ * License as published by the Free Software Foundation; either
158+ * version 2 of the License, or (at your option) any later version.
159+ *
160+ * This library is distributed in the hope that it will be useful,
161+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
162+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
163+ * Lesser General Public License for more details.
164+ *
165+ * You should have received a copy of the GNU Lesser General Public
166+ * License along with this library; if not, write to the
167+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
168+ * Boston, MA 02111-1307, USA.
169+ *
170+ * Author: David Reveman <davidr@novell.com>
171+ *
172+ * 2D Mode: Copyright © 2010 Sam Spilsbury <smspillaz@gmail.com>
173+ * Frames Management: Copright © 2011 Canonical Ltd.
174+ * Authored By: Sam Spilsbury <sam.spilsbury@canonical.com>
175+ */
176+
177+#include "gtk-window-decorator.h"
178+
179+#ifdef USE_METACITY
180+
181+MetaButtonLayout meta_button_layout;
182+
183+static gboolean
184+meta_button_present (MetaButtonLayout *button_layout,
185+ MetaButtonFunction function)
186+{
187+ int i;
188+
189+ for (i = 0; i < MAX_BUTTONS_PER_CORNER; ++i)
190+ if (button_layout->left_buttons[i] == function)
191+ return TRUE;
192+
193+ for (i = 0; i < MAX_BUTTONS_PER_CORNER; ++i)
194+ if (button_layout->right_buttons[i] == function)
195+ return TRUE;
196+
197+ return FALSE;
198+}
199+
200+static void
201+decor_update_meta_window_property (decor_t *d,
202+ MetaTheme *theme,
203+ MetaFrameFlags flags,
204+ MetaFrameType type,
205+ Region top,
206+ Region bottom,
207+ Region left,
208+ Region right)
209+{
210+ long *data;
211+ GdkDisplay *display;
212+ Display *xdisplay;
213+ gint nQuad;
214+ decor_extents_t win_extents;
215+ decor_extents_t frame_win_extents;
216+ decor_extents_t max_win_extents;
217+ decor_extents_t frame_max_win_extents;
218+ decor_quad_t quads[N_QUADS_MAX];
219+ unsigned int nOffset;
220+ unsigned int frame_type;
221+ unsigned int frame_state;
222+ unsigned int frame_actions;
223+ gint w;
224+ gint lh;
225+ gint rh;
226+ gint top_stretch_offset;
227+ gint bottom_stretch_offset;
228+ gint left_stretch_offset;
229+ gint right_stretch_offset;
230+
231+ display = gdk_display_get_default ();
232+ xdisplay = gdk_x11_display_get_xdisplay (display);
233+
234+ nOffset = 1;
235+
236+ frame_type = populate_frame_type (d);
237+ frame_state = populate_frame_state (d);
238+ frame_actions = populate_frame_actions (d);
239+
240+ win_extents = frame_win_extents = d->frame->win_extents;
241+ max_win_extents = frame_max_win_extents = d->frame->max_win_extents;
242+
243+ /* Add the invisible grab area padding, but only for
244+ * pixmap type decorations */
245+ if (!d->frame_window)
246+ {
247+ GdkScreen *screen;
248+ MetaStyleInfo *style_info;
249+ MetaFrameBorders borders;
250+
251+ screen = gtk_widget_get_screen (d->frame->style_window_rgba);
252+ style_info = meta_theme_create_style_info (screen, d->gtk_theme_variant);
253+
254+ meta_theme_get_frame_borders (theme, style_info, type,
255+ d->frame->text_height,
256+ flags, &borders);
257+
258+ if (flags & META_FRAME_ALLOWS_HORIZONTAL_RESIZE)
259+ {
260+ frame_win_extents.left += borders.invisible.left;
261+ frame_win_extents.right += borders.invisible.right;
262+ frame_max_win_extents.left += borders.invisible.left;
263+ frame_max_win_extents.right += borders.invisible.right;
264+ }
265+
266+ if (flags & META_FRAME_ALLOWS_VERTICAL_RESIZE)
267+ {
268+ frame_win_extents.bottom += borders.invisible.bottom;
269+ frame_win_extents.top += borders.invisible.top;
270+ frame_max_win_extents.bottom += borders.invisible.bottom;
271+ frame_max_win_extents.top += borders.invisible.top;
272+ }
273+
274+ meta_style_info_unref (style_info);
275+ }
276+
277+ w = d->border_layout.top.x2 - d->border_layout.top.x1 -
278+ d->context->left_space - d->context->right_space;
279+
280+ if (d->border_layout.rotation)
281+ lh = d->border_layout.left.x2 - d->border_layout.left.x1;
282+ else
283+ lh = d->border_layout.left.y2 - d->border_layout.left.y1;
284+
285+ if (d->border_layout.rotation)
286+ rh = d->border_layout.right.x2 - d->border_layout.right.x1;
287+ else
288+ rh = d->border_layout.right.y2 - d->border_layout.right.y1;
289+
290+ left_stretch_offset = lh / 2;
291+ right_stretch_offset = rh / 2;
292+ top_stretch_offset = w - d->button_width - 1;
293+ bottom_stretch_offset = (d->border_layout.bottom.x2 - d->border_layout.bottom.x1 -
294+ d->context->left_space - d->context->right_space) / 2;
295+
296+ nQuad = decor_set_lXrXtXbX_window_quads (quads, d->context, &d->border_layout,
297+ left_stretch_offset, right_stretch_offset,
298+ top_stretch_offset, bottom_stretch_offset);
299+
300+ win_extents.top += d->frame->titlebar_height;
301+ frame_win_extents.top += d->frame->titlebar_height;
302+ max_win_extents.top += d->frame->max_titlebar_height;
303+ frame_max_win_extents.top += d->frame->max_titlebar_height;
304+
305+ if (d->frame_window)
306+ {
307+ data = decor_alloc_property (nOffset, WINDOW_DECORATION_TYPE_WINDOW);
308+ decor_gen_window_property (data, nOffset - 1, &win_extents, &max_win_extents,
309+ 20, 20, frame_type, frame_state, frame_actions);
310+ }
311+ else
312+ {
313+ data = decor_alloc_property (nOffset, WINDOW_DECORATION_TYPE_PIXMAP);
314+ decor_quads_to_property (data, nOffset - 1, cairo_xlib_surface_get_drawable (d->surface),
315+ &frame_win_extents, &win_extents,
316+ &frame_max_win_extents, &max_win_extents,
317+ ICON_SPACE + d->button_width,
318+ 0, quads, nQuad, frame_type, frame_state, frame_actions);
319+ }
320+
321+ gdk_error_trap_push ();
322+
323+ XChangeProperty (xdisplay, d->prop_xid, win_decor_atom, XA_INTEGER,
324+ 32, PropModeReplace, (guchar *) data,
325+ PROP_HEADER_SIZE + BASE_PROP_SIZE + QUAD_PROP_SIZE * N_QUADS_MAX);
326+ gdk_display_sync (display);
327+
328+ gdk_error_trap_pop_ignored ();
329+
330+ free (data);
331+
332+ decor_update_blur_property (d, w, lh,
333+ top, top_stretch_offset,
334+ bottom, bottom_stretch_offset,
335+ left, left_stretch_offset,
336+ right, right_stretch_offset);
337+}
338+
339+static void
340+meta_get_corner_radius (const MetaFrameGeometry *fgeom,
341+ int *top_left_radius,
342+ int *top_right_radius,
343+ int *bottom_left_radius,
344+ int *bottom_right_radius)
345+{
346+ *top_left_radius = fgeom->top_left_corner_rounded_radius;
347+ *top_right_radius = fgeom->top_right_corner_rounded_radius;
348+ *bottom_left_radius = fgeom->bottom_left_corner_rounded_radius;
349+ *bottom_right_radius = fgeom->bottom_right_corner_rounded_radius;
350+}
351+
352+static int
353+radius_to_width (int radius,
354+ int i)
355+{
356+ float r1 = sqrt (radius) + radius;
357+ float r2 = r1 * r1 - (r1 - (i + 0.5)) * (r1 - (i + 0.5));
358+
359+ return floor (0.5f + r1 - sqrt (r2));
360+}
361+
362+static Region
363+meta_get_top_border_region (const MetaFrameGeometry *fgeom,
364+ int width)
365+{
366+ Region corners_xregion;
367+ Region border_xregion;
368+ XRectangle xrect;
369+ int top_left_radius;
370+ int top_right_radius;
371+ int bottom_left_radius;
372+ int bottom_right_radius;
373+ int w;
374+ int i;
375+ int height;
376+
377+ corners_xregion = XCreateRegion ();
378+
379+ meta_get_corner_radius (fgeom, &top_left_radius, &top_right_radius,
380+ &bottom_left_radius, &bottom_right_radius);
381+
382+ width = width - fgeom->borders.invisible.left - fgeom->borders.invisible.right;
383+ height = fgeom->borders.visible.top;
384+
385+ if (top_left_radius)
386+ {
387+ for (i = 0; i < top_left_radius; ++i)
388+ {
389+ w = radius_to_width (top_left_radius, i);
390+
391+ xrect.x = 0;
392+ xrect.y = i;
393+ xrect.width = w;
394+ xrect.height = 1;
395+
396+ XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
397+ }
398+ }
399+
400+ if (top_right_radius)
401+ {
402+ for (i = 0; i < top_right_radius; ++i)
403+ {
404+ w = radius_to_width (top_right_radius, i);
405+
406+ xrect.x = width - w;
407+ xrect.y = i;
408+ xrect.width = w;
409+ xrect.height = 1;
410+
411+ XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
412+ }
413+ }
414+
415+ border_xregion = XCreateRegion ();
416+
417+ xrect.x = 0;
418+ xrect.y = 0;
419+ xrect.width = width;
420+ xrect.height = height;
421+
422+ XUnionRectWithRegion (&xrect, border_xregion, border_xregion);
423+
424+ XSubtractRegion (border_xregion, corners_xregion, border_xregion);
425+
426+ XDestroyRegion (corners_xregion);
427+
428+ return border_xregion;
429+}
430+
431+static Region
432+meta_get_bottom_border_region (const MetaFrameGeometry *fgeom,
433+ int width)
434+{
435+ Region corners_xregion;
436+ Region border_xregion;
437+ XRectangle xrect;
438+ int top_left_radius;
439+ int top_right_radius;
440+ int bottom_left_radius;
441+ int bottom_right_radius;
442+ int w;
443+ int i;
444+ int height;
445+
446+ corners_xregion = XCreateRegion ();
447+
448+ meta_get_corner_radius (fgeom, &top_left_radius, &top_right_radius,
449+ &bottom_left_radius, &bottom_right_radius);
450+
451+ width = width - fgeom->borders.invisible.left - fgeom->borders.invisible.right;
452+ height = fgeom->borders.visible.bottom;
453+
454+ if (bottom_left_radius)
455+ {
456+ for (i = 0; i < bottom_left_radius; ++i)
457+ {
458+ w = radius_to_width (bottom_left_radius, i);
459+
460+ xrect.x = 0;
461+ xrect.y = height - i - 1;
462+ xrect.width = w;
463+ xrect.height = 1;
464+
465+ XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
466+ }
467+ }
468+
469+ if (bottom_right_radius)
470+ {
471+ for (i = 0; i < bottom_right_radius; ++i)
472+ {
473+ w = radius_to_width (bottom_right_radius, i);
474+
475+ xrect.x = width - w;
476+ xrect.y = height - i - 1;
477+ xrect.width = w;
478+ xrect.height = 1;
479+
480+ XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
481+ }
482+ }
483+
484+ border_xregion = XCreateRegion ();
485+
486+ xrect.x = 0;
487+ xrect.y = 0;
488+ xrect.width = width;
489+ xrect.height = height;
490+
491+ XUnionRectWithRegion (&xrect, border_xregion, border_xregion);
492+
493+ XSubtractRegion (border_xregion, corners_xregion, border_xregion);
494+
495+ XDestroyRegion (corners_xregion);
496+
497+ return border_xregion;
498+}
499+
500+static Region
501+meta_get_left_border_region (const MetaFrameGeometry *fgeom,
502+ int height)
503+{
504+ Region border_xregion;
505+ XRectangle xrect;
506+
507+ border_xregion = XCreateRegion ();
508+
509+ xrect.x = 0;
510+ xrect.y = 0;
511+ xrect.width = fgeom->borders.visible.left;
512+ xrect.height = height - fgeom->borders.total.top - fgeom->borders.total.bottom;
513+
514+ XUnionRectWithRegion (&xrect, border_xregion, border_xregion);
515+
516+ return border_xregion;
517+}
518+
519+static Region
520+meta_get_right_border_region (const MetaFrameGeometry *fgeom,
521+ int height)
522+{
523+ Region border_xregion;
524+ XRectangle xrect;
525+
526+ border_xregion = XCreateRegion ();
527+
528+ xrect.x = 0;
529+ xrect.y = 0;
530+ xrect.width = fgeom->borders.visible.right;
531+ xrect.height = height - fgeom->borders.total.top - fgeom->borders.total.bottom;
532+
533+ XUnionRectWithRegion (&xrect, border_xregion, border_xregion);
534+
535+ return border_xregion;
536+}
537+
538+static MetaButtonState
539+meta_button_state (int state)
540+{
541+ if (state & IN_EVENT_WINDOW)
542+ {
543+ if (state & PRESSED_EVENT_WINDOW)
544+ return META_BUTTON_STATE_PRESSED;
545+
546+ return META_BUTTON_STATE_PRELIGHT;
547+ }
548+
549+ return META_BUTTON_STATE_NORMAL;
550+}
551+
552+static MetaButtonType
553+meta_function_to_type (MetaButtonFunction function)
554+{
555+ switch (function)
556+ {
557+ case META_BUTTON_FUNCTION_MENU:
558+ return META_BUTTON_TYPE_MENU;
559+ case META_BUTTON_FUNCTION_MINIMIZE:
560+ return META_BUTTON_TYPE_MINIMIZE;
561+ case META_BUTTON_FUNCTION_MAXIMIZE:
562+ return META_BUTTON_TYPE_MAXIMIZE;
563+ case META_BUTTON_FUNCTION_CLOSE:
564+ return META_BUTTON_TYPE_CLOSE;
565+ case META_BUTTON_FUNCTION_SHADE:
566+ return META_BUTTON_TYPE_SHADE;
567+ case META_BUTTON_FUNCTION_ABOVE:
568+ return META_BUTTON_TYPE_ABOVE;
569+ case META_BUTTON_FUNCTION_STICK:
570+ return META_BUTTON_TYPE_STICK;
571+ case META_BUTTON_FUNCTION_UNSHADE:
572+ return META_BUTTON_TYPE_UNSHADE;
573+ case META_BUTTON_FUNCTION_UNABOVE:
574+ return META_BUTTON_TYPE_UNABOVE;
575+ case META_BUTTON_FUNCTION_UNSTICK:
576+ return META_BUTTON_TYPE_UNSTICK;
577+ default:
578+ break;
579+ }
580+
581+ return META_BUTTON_TYPE_LAST;
582+}
583+
584+static MetaButtonState
585+meta_button_state_for_button_type (decor_t *d,
586+ MetaButtonType type)
587+{
588+ switch (type)
589+ {
590+ case META_BUTTON_TYPE_LEFT_LEFT_BACKGROUND:
591+ type = meta_function_to_type (meta_button_layout.left_buttons[0]);
592+ break;
593+ case META_BUTTON_TYPE_LEFT_MIDDLE_BACKGROUND:
594+ type = meta_function_to_type (meta_button_layout.left_buttons[1]);
595+ break;
596+ case META_BUTTON_TYPE_LEFT_RIGHT_BACKGROUND:
597+ type = meta_function_to_type (meta_button_layout.left_buttons[2]);
598+ break;
599+ case META_BUTTON_TYPE_RIGHT_LEFT_BACKGROUND:
600+ type = meta_function_to_type (meta_button_layout.right_buttons[0]);
601+ break;
602+ case META_BUTTON_TYPE_RIGHT_MIDDLE_BACKGROUND:
603+ type = meta_function_to_type (meta_button_layout.right_buttons[1]);
604+ break;
605+ case META_BUTTON_TYPE_RIGHT_RIGHT_BACKGROUND:
606+ type = meta_function_to_type (meta_button_layout.right_buttons[2]);
607+ default:
608+ break;
609+ }
610+
611+ switch (type)
612+ {
613+ case META_BUTTON_TYPE_CLOSE:
614+ return meta_button_state (d->button_states[BUTTON_CLOSE]);
615+ case META_BUTTON_TYPE_MAXIMIZE:
616+ return meta_button_state (d->button_states[BUTTON_MAX]);
617+ case META_BUTTON_TYPE_MINIMIZE:
618+ return meta_button_state (d->button_states[BUTTON_MIN]);
619+ case META_BUTTON_TYPE_MENU:
620+ return meta_button_state (d->button_states[BUTTON_MENU]);
621+ case META_BUTTON_TYPE_SHADE:
622+ return meta_button_state (d->button_states[BUTTON_SHADE]);
623+ case META_BUTTON_TYPE_ABOVE:
624+ return meta_button_state (d->button_states[BUTTON_ABOVE]);
625+ case META_BUTTON_TYPE_STICK:
626+ return meta_button_state (d->button_states[BUTTON_STICK]);
627+ case META_BUTTON_TYPE_UNSHADE:
628+ return meta_button_state (d->button_states[BUTTON_UNSHADE]);
629+ case META_BUTTON_TYPE_UNABOVE:
630+ return meta_button_state (d->button_states[BUTTON_UNABOVE]);
631+ case META_BUTTON_TYPE_UNSTICK:
632+ return meta_button_state (d->button_states[BUTTON_UNSTICK]);
633+ default:
634+ break;
635+ }
636+
637+ return META_BUTTON_STATE_NORMAL;
638+}
639+
640+static void
641+meta_get_decoration_geometry (decor_t *d,
642+ MetaTheme *theme,
643+ MetaFrameFlags *flags,
644+ MetaFrameGeometry *fgeom,
645+ MetaButtonLayout *button_layout,
646+ MetaFrameType frame_type)
647+{
648+ GdkScreen *screen;
649+ MetaStyleInfo *style_info;
650+ gint client_width;
651+ gint client_height;
652+
653+ if (!(frame_type < META_FRAME_TYPE_LAST))
654+ frame_type = META_FRAME_TYPE_NORMAL;
655+
656+ if (meta_button_layout_set)
657+ {
658+ *button_layout = meta_button_layout;
659+ }
660+ else
661+ {
662+ gint i;
663+
664+ button_layout->left_buttons[0] = META_BUTTON_FUNCTION_MENU;
665+
666+ for (i = 1; i < MAX_BUTTONS_PER_CORNER; ++i)
667+ button_layout->left_buttons[i] = META_BUTTON_FUNCTION_LAST;
668+
669+ button_layout->right_buttons[0] = META_BUTTON_FUNCTION_MINIMIZE;
670+ button_layout->right_buttons[1] = META_BUTTON_FUNCTION_MAXIMIZE;
671+ button_layout->right_buttons[2] = META_BUTTON_FUNCTION_CLOSE;
672+
673+ for (i = 3; i < MAX_BUTTONS_PER_CORNER; ++i)
674+ button_layout->right_buttons[i] = META_BUTTON_FUNCTION_LAST;
675+ }
676+
677+ *flags = 0;
678+
679+ if (d->actions & WNCK_WINDOW_ACTION_CLOSE)
680+ *flags |= (MetaFrameFlags ) META_FRAME_ALLOWS_DELETE;
681+
682+ if (d->actions & WNCK_WINDOW_ACTION_MINIMIZE)
683+ *flags |= (MetaFrameFlags ) META_FRAME_ALLOWS_MINIMIZE;
684+
685+ if (d->actions & WNCK_WINDOW_ACTION_MAXIMIZE)
686+ *flags |= (MetaFrameFlags ) META_FRAME_ALLOWS_MAXIMIZE;
687+
688+ *flags |= (MetaFrameFlags ) META_FRAME_ALLOWS_MENU;
689+
690+ if (d->actions & WNCK_WINDOW_ACTION_RESIZE)
691+ {
692+ if (!(d->state & WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY))
693+ *flags |= (MetaFrameFlags ) META_FRAME_ALLOWS_VERTICAL_RESIZE;
694+ if (!(d->state & WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY))
695+ *flags |= (MetaFrameFlags ) META_FRAME_ALLOWS_HORIZONTAL_RESIZE;
696+ }
697+
698+ if (d->actions & WNCK_WINDOW_ACTION_MOVE)
699+ *flags |= (MetaFrameFlags ) META_FRAME_ALLOWS_MOVE;
700+
701+ if (d->actions & WNCK_WINDOW_ACTION_MAXIMIZE)
702+ *flags |= (MetaFrameFlags ) META_FRAME_ALLOWS_MAXIMIZE;
703+
704+ if (d->actions & WNCK_WINDOW_ACTION_SHADE)
705+ *flags |= (MetaFrameFlags ) META_FRAME_ALLOWS_SHADE;
706+
707+ if (d->active)
708+ *flags |= (MetaFrameFlags ) META_FRAME_HAS_FOCUS;
709+
710+ if ((d->state & META_MAXIMIZED) == META_MAXIMIZED)
711+ *flags |= (MetaFrameFlags ) META_FRAME_MAXIMIZED;
712+
713+ if (d->state & WNCK_WINDOW_STATE_STICKY)
714+ *flags |= (MetaFrameFlags ) META_FRAME_STUCK;
715+
716+ if (d->state & WNCK_WINDOW_STATE_FULLSCREEN)
717+ *flags |= (MetaFrameFlags ) META_FRAME_FULLSCREEN;
718+
719+ if (d->state & WNCK_WINDOW_STATE_SHADED)
720+ *flags |= (MetaFrameFlags ) META_FRAME_SHADED;
721+
722+ if (d->state & WNCK_WINDOW_STATE_ABOVE)
723+ *flags |= (MetaFrameFlags ) META_FRAME_ABOVE;
724+
725+ client_width = d->border_layout.top.x2 - d->border_layout.top.x1;
726+ client_width -= d->context->right_space + d->context->left_space;
727+
728+ if (d->border_layout.rotation)
729+ client_height = d->border_layout.left.x2 - d->border_layout.left.x1;
730+ else
731+ client_height = d->border_layout.left.y2 - d->border_layout.left.y1;
732+
733+ screen = gtk_widget_get_screen (d->frame->style_window_rgba);
734+ style_info = meta_theme_create_style_info (screen, d->gtk_theme_variant);
735+
736+ meta_theme_calc_geometry (theme, style_info, frame_type, d->frame->text_height,
737+ *flags, client_width, client_height,
738+ button_layout, fgeom);
739+
740+ meta_style_info_unref (style_info);
741+}
742+
743+void
744+meta_draw_window_decoration (decor_t *d)
745+{
746+ GdkDisplay *display;
747+ GdkScreen *screen;
748+ Display *xdisplay;
749+ cairo_surface_t *surface;
750+ Picture src;
751+ MetaButtonState button_states [META_BUTTON_TYPE_LAST];
752+ MetaButtonLayout button_layout;
753+ MetaFrameGeometry fgeom;
754+ MetaFrameFlags flags;
755+ MetaFrameType frame_type;
756+ MetaTheme *theme;
757+ MetaStyleInfo *style_info;
758+ GtkStyleContext *context;
759+ cairo_t *cr;
760+ gint i;
761+ Region top_region;
762+ Region bottom_region;
763+ Region left_region;
764+ Region right_region;
765+ gdouble meta_active_opacity;
766+ gdouble meta_inactive_opacity;
767+ gboolean meta_active_shade_opacity;
768+ gboolean meta_inactive_shade_opacity;
769+ double alpha;
770+ gboolean shade_alpha;
771+ MetaFrameStyle *frame_style;
772+ GtkWidget *style_window;
773+ GdkRGBA bg_rgba;
774+
775+ if (!d->surface || !d->picture)
776+ return;
777+
778+ display = gdk_display_get_default ();
779+ xdisplay = gdk_x11_display_get_xdisplay (display);
780+
781+ top_region = NULL;
782+ bottom_region = NULL;
783+ left_region = NULL;
784+ right_region = NULL;
785+
786+ g_object_get (settings, "metacity-active-opacity", &meta_active_opacity, NULL);
787+ g_object_get (settings, "metacity-inactive-opacity", &meta_inactive_opacity, NULL);
788+ g_object_get (settings, "metacity-active-shade-opacity", &meta_active_shade_opacity, NULL);
789+ g_object_get (settings, "metacity-inactive-shade-opacity", &meta_inactive_shade_opacity, NULL);
790+
791+ alpha = (d->active) ? meta_active_opacity : meta_inactive_opacity;
792+ shade_alpha = (d->active) ? meta_active_shade_opacity : meta_inactive_shade_opacity;
793+
794+ if (decoration_alpha == 1.0)
795+ alpha = 1.0;
796+
797+ if (cairo_xlib_surface_get_depth (d->surface) == 32)
798+ style_window = d->frame->style_window_rgba;
799+ else
800+ style_window = d->frame->style_window_rgb;
801+
802+ context = gtk_widget_get_style_context (style_window);
803+
804+ cr = cairo_create (d->buffer_surface ? d->buffer_surface : d->surface);
805+
806+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
807+
808+ theme = meta_theme_get_current ();
809+
810+ frame_type = meta_frame_type_from_string (d->frame->type);
811+
812+ if (frame_type == META_FRAME_TYPE_LAST)
813+ frame_type = META_FRAME_TYPE_NORMAL;
814+
815+ meta_get_decoration_geometry (d, theme, &flags, &fgeom, &button_layout,
816+ frame_type);
817+
818+ if ((d->prop_xid || !d->buffer_surface) && !d->frame_window)
819+ draw_shadow_background (d, cr, d->shadow, d->context);
820+
821+ for (i = 0; i < META_BUTTON_TYPE_LAST; ++i)
822+ button_states[i] = meta_button_state_for_button_type (d, i);
823+
824+ frame_style = meta_theme_get_frame_style (theme, frame_type, flags);
825+
826+ gtk_style_context_get_background_color (context, GTK_STATE_FLAG_NORMAL, &bg_rgba);
827+ bg_rgba.alpha = 1.0;
828+
829+ if (frame_style->window_background_color)
830+ {
831+ meta_color_spec_render (frame_style->window_background_color,
832+ context, &bg_rgba);
833+
834+ bg_rgba.alpha = frame_style->window_background_alpha / 255.0;
835+ }
836+
837+ /* Draw something that will be almost invisible to user. This is hacky way
838+ * to fix invisible decorations. */
839+ cairo_set_source_rgba (cr, 0, 0, 0, 0.01);
840+ cairo_rectangle (cr, 0, 0, 1, 1);
841+ cairo_fill (cr);
842+ /* ------------ */
843+
844+ cairo_destroy (cr);
845+
846+ if (d->frame_window)
847+ surface = create_surface (fgeom.width, fgeom.height, d->frame->style_window_rgb);
848+ else
849+ surface = create_surface (fgeom.width, fgeom.height, d->frame->style_window_rgba);
850+
851+ // FIXME: this should match the current monitor scaling!
852+ cairo_surface_set_device_scale (surface, 1, 1);
853+ cr = cairo_create (surface);
854+ gdk_cairo_set_source_rgba (cr, &bg_rgba);
855+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
856+
857+ src = XRenderCreatePicture (xdisplay, cairo_xlib_surface_get_drawable (surface),
858+ get_format_for_surface (d, surface), 0, NULL);
859+
860+ screen = gtk_widget_get_screen (d->frame->style_window_rgba);
861+ style_info = meta_theme_create_style_info (screen, d->gtk_theme_variant);
862+
863+ cairo_paint (cr);
864+ meta_theme_draw_frame (theme, style_info, cr, frame_type, flags,
865+ fgeom.width - fgeom.borders.total.left - fgeom.borders.total.right,
866+ fgeom.height - fgeom.borders.total.top - fgeom.borders.total.bottom,
867+ d->layout, d->frame->text_height, &button_layout,
868+ button_states, d->icon_pixbuf, NULL);
869+
870+ meta_style_info_unref (style_info);
871+
872+ if (fgeom.borders.visible.top)
873+ {
874+ top_region = meta_get_top_border_region (&fgeom, fgeom.width);
875+
876+ decor_blend_border_picture (xdisplay, d->context, src,
877+ fgeom.borders.invisible.left,
878+ fgeom.borders.invisible.top,
879+ d->picture, &d->border_layout,
880+ BORDER_TOP, top_region,
881+ alpha * 0xffff, shade_alpha, 0);
882+ }
883+
884+ if (fgeom.borders.visible.bottom)
885+ {
886+ bottom_region = meta_get_bottom_border_region (&fgeom, fgeom.width);
887+
888+ decor_blend_border_picture (xdisplay, d->context, src,
889+ fgeom.borders.invisible.left,
890+ fgeom.height - fgeom.borders.total.bottom,
891+ d->picture, &d->border_layout,
892+ BORDER_BOTTOM, bottom_region,
893+ alpha * 0xffff, shade_alpha, 0);
894+ }
895+
896+ if (fgeom.borders.visible.left)
897+ {
898+ left_region = meta_get_left_border_region (&fgeom, fgeom.height);
899+
900+ decor_blend_border_picture (xdisplay, d->context, src,
901+ fgeom.borders.invisible.left,
902+ fgeom.borders.total.top,
903+ d->picture, &d->border_layout,
904+ BORDER_LEFT, left_region,
905+ alpha * 0xffff, shade_alpha, 0);
906+ }
907+
908+ if (fgeom.borders.visible.right)
909+ {
910+ right_region = meta_get_right_border_region (&fgeom, fgeom.height);
911+
912+ decor_blend_border_picture (xdisplay, d->context, src,
913+ fgeom.width - fgeom.borders.total.right,
914+ fgeom.borders.total.top,
915+ d->picture, &d->border_layout,
916+ BORDER_RIGHT, right_region,
917+ alpha * 0xffff, shade_alpha, 0);
918+ }
919+
920+ cairo_destroy (cr);
921+ cairo_surface_destroy (surface);
922+ XRenderFreePicture (xdisplay, src);
923+
924+ copy_to_front_buffer (d);
925+
926+ if (d->frame_window)
927+ {
928+ GdkWindow *gdk_frame_window;
929+ GdkPixbuf *pixbuf;
930+
931+ gdk_frame_window = gtk_widget_get_window (d->decor_window);
932+
933+ pixbuf = gdk_pixbuf_get_from_surface (d->surface, 0, 0, d->width, d->height);
934+ gtk_image_set_from_pixbuf (GTK_IMAGE (d->decor_image), pixbuf);
935+ g_object_unref (pixbuf);
936+
937+ gdk_window_move_resize (gdk_frame_window,
938+ d->context->left_corner_space - 1,
939+ d->context->top_corner_space - 1,
940+ d->width,
941+ d->height);
942+
943+ gdk_window_lower (gdk_frame_window);
944+ }
945+
946+ if (d->prop_xid)
947+ {
948+ /* translate from frame to client window space */
949+ if (top_region)
950+ XOffsetRegion (top_region, -fgeom.borders.total.left, -fgeom.borders.total.top);
951+ if (bottom_region)
952+ XOffsetRegion (bottom_region, -fgeom.borders.total.left, 0);
953+ if (left_region)
954+ XOffsetRegion (left_region, -fgeom.borders.total.left, 0);
955+
956+ decor_update_meta_window_property (d, theme, flags, frame_type,
957+ top_region, bottom_region,
958+ left_region, right_region);
959+
960+ d->prop_xid = 0;
961+ }
962+
963+ if (top_region)
964+ XDestroyRegion (top_region);
965+ if (bottom_region)
966+ XDestroyRegion (bottom_region);
967+ if (left_region)
968+ XDestroyRegion (left_region);
969+ if (right_region)
970+ XDestroyRegion (right_region);
971+}
972+
973+static void
974+meta_calc_button_size (decor_t *d)
975+{
976+ MetaTheme *theme;
977+ MetaFrameType frame_type;
978+ MetaFrameFlags flags;
979+ MetaFrameGeometry fgeom;
980+ MetaButtonLayout button_layout;
981+ gint i, min_x, x, y, w, h, width;
982+
983+ if (!d->context)
984+ {
985+ d->button_width = 0;
986+ return;
987+ }
988+
989+ theme = meta_theme_get_current ();
990+
991+ frame_type = meta_frame_type_from_string (d->frame->type);
992+ if (!(frame_type < META_FRAME_TYPE_LAST))
993+ frame_type = META_FRAME_TYPE_NORMAL;
994+
995+ meta_get_decoration_geometry (d, theme, &flags, &fgeom, &button_layout,
996+ frame_type);
997+
998+ width = d->border_layout.top.x2 - d->border_layout.top.x1 -
999+ d->context->left_space - d->context->right_space +
1000+ fgeom.borders.total.left + fgeom.borders.total.right;
1001+
1002+ min_x = width;
1003+
1004+ for (i = 0; i < 3; ++i)
1005+ {
1006+ static guint button_actions[3] = {
1007+ WNCK_WINDOW_ACTION_CLOSE,
1008+ WNCK_WINDOW_ACTION_MAXIMIZE,
1009+ WNCK_WINDOW_ACTION_MINIMIZE
1010+ };
1011+
1012+ if (d->actions & button_actions[i])
1013+ {
1014+ if (meta_get_button_position (d, i, width, 256, &x, &y, &w, &h))
1015+ {
1016+ if (x > width / 2 && x < min_x)
1017+ min_x = x;
1018+ }
1019+ }
1020+ }
1021+
1022+ d->button_width = width - min_x;
1023+}
1024+
1025+static MetaButtonFunction
1026+button_to_meta_button_function (gint i)
1027+{
1028+ switch (i)
1029+ {
1030+ case BUTTON_MENU:
1031+ return META_BUTTON_FUNCTION_MENU;
1032+ case BUTTON_MIN:
1033+ return META_BUTTON_FUNCTION_MINIMIZE;
1034+ case BUTTON_MAX:
1035+ return META_BUTTON_FUNCTION_MAXIMIZE;
1036+ case BUTTON_CLOSE:
1037+ return META_BUTTON_FUNCTION_CLOSE;
1038+ case BUTTON_SHADE:
1039+ return META_BUTTON_FUNCTION_SHADE;
1040+ case BUTTON_ABOVE:
1041+ return META_BUTTON_FUNCTION_ABOVE;
1042+ case BUTTON_STICK:
1043+ return META_BUTTON_FUNCTION_STICK;
1044+ case BUTTON_UNSHADE:
1045+ return META_BUTTON_FUNCTION_UNSHADE;
1046+ case BUTTON_UNABOVE:
1047+ return META_BUTTON_FUNCTION_UNABOVE;
1048+ case BUTTON_UNSTICK:
1049+ return META_BUTTON_FUNCTION_UNSTICK;
1050+ default:
1051+ break;
1052+ }
1053+
1054+ return META_BUTTON_FUNCTION_LAST;
1055+}
1056+
1057+gboolean
1058+meta_get_button_position (decor_t *d,
1059+ gint i,
1060+ gint width,
1061+ gint height,
1062+ gint *x,
1063+ gint *y,
1064+ gint *w,
1065+ gint *h)
1066+{
1067+ MetaButtonLayout button_layout;
1068+ MetaFrameGeometry fgeom;
1069+ MetaFrameType frame_type;
1070+ MetaFrameFlags flags;
1071+ MetaTheme *theme;
1072+ MetaButtonFunction button_function;
1073+ MetaButtonSpace *space;
1074+
1075+ if (!d->context)
1076+ {
1077+ /* undecorated windows implicitly have no buttons */
1078+ return FALSE;
1079+ }
1080+
1081+ theme = meta_theme_get_current ();
1082+
1083+ frame_type = meta_frame_type_from_string (d->frame->type);
1084+ if (!(frame_type < META_FRAME_TYPE_LAST))
1085+ frame_type = META_FRAME_TYPE_NORMAL;
1086+
1087+ meta_get_decoration_geometry (d, theme, &flags, &fgeom, &button_layout,
1088+ frame_type);
1089+
1090+ button_function = button_to_meta_button_function (i);
1091+ if (!meta_button_present (&button_layout, button_function))
1092+ return FALSE;
1093+
1094+ switch (i)
1095+ {
1096+ case BUTTON_MENU:
1097+ space = &fgeom.menu_rect;
1098+ break;
1099+ case BUTTON_MIN:
1100+ space = &fgeom.min_rect;
1101+ break;
1102+ case BUTTON_MAX:
1103+ space = &fgeom.max_rect;
1104+ break;
1105+ case BUTTON_CLOSE:
1106+ space = &fgeom.close_rect;
1107+ break;
1108+ case BUTTON_SHADE:
1109+ space = &fgeom.shade_rect;
1110+ break;
1111+ case BUTTON_ABOVE:
1112+ space = &fgeom.above_rect;
1113+ break;
1114+ case BUTTON_STICK:
1115+ space = &fgeom.stick_rect;
1116+ break;
1117+ case BUTTON_UNSHADE:
1118+ space = &fgeom.unshade_rect;
1119+ break;
1120+ case BUTTON_UNABOVE:
1121+ space = &fgeom.unabove_rect;
1122+ break;
1123+ case BUTTON_UNSTICK:
1124+ space = &fgeom.unstick_rect;
1125+ break;
1126+ default:
1127+ return FALSE;
1128+ }
1129+
1130+ if (!space->clickable.width && !space->clickable.height)
1131+ return FALSE;
1132+
1133+ *x = space->clickable.x;
1134+ *y = space->clickable.y;
1135+ *w = space->clickable.width;
1136+ *h = space->clickable.height;
1137+
1138+ if (d->frame_window)
1139+ {
1140+ *x += d->frame->win_extents.left + 4;
1141+ *y += d->frame->win_extents.top + 2;
1142+ }
1143+
1144+ return TRUE;
1145+}
1146+
1147+gfloat
1148+meta_get_title_scale (decor_frame_t *frame)
1149+{
1150+ MetaTheme *theme;
1151+ MetaFrameType type;
1152+ MetaFrameFlags flags;
1153+
1154+ theme = meta_theme_get_current ();
1155+ type = meta_frame_type_from_string (frame->type);
1156+ flags = 0xc33; /* fixme */
1157+
1158+ if (type == META_FRAME_TYPE_LAST)
1159+ return 1.0f;
1160+
1161+ gfloat scale = meta_theme_get_title_scale (theme, type, flags);
1162+
1163+ return scale;
1164+}
1165+
1166+gboolean
1167+meta_calc_decoration_size (decor_t *d,
1168+ gint w,
1169+ gint h,
1170+ gint name_width,
1171+ gint *width,
1172+ gint *height)
1173+{
1174+ decor_layout_t layout;
1175+ decor_context_t *context;
1176+ decor_shadow_t *shadow;
1177+
1178+ if (!d->decorated)
1179+ return FALSE;
1180+
1181+ if ((d->state & META_MAXIMIZED) == META_MAXIMIZED)
1182+ {
1183+ if (!d->frame_window)
1184+ {
1185+ if (d->active)
1186+ {
1187+ context = &d->frame->max_window_context_active;
1188+ shadow = d->frame->max_border_shadow_active;
1189+ }
1190+ else
1191+ {
1192+ context = &d->frame->max_window_context_inactive;
1193+ shadow = d->frame->max_border_shadow_inactive;
1194+ }
1195+ }
1196+ else
1197+ {
1198+ context = &d->frame->max_window_context_no_shadow;
1199+ shadow = d->frame->max_border_no_shadow;
1200+ }
1201+ }
1202+ else
1203+ {
1204+ if (!d->frame_window)
1205+ {
1206+ if (d->active)
1207+ {
1208+ context = &d->frame->window_context_active;
1209+ shadow = d->frame->border_shadow_active;
1210+ }
1211+ else
1212+ {
1213+ context = &d->frame->window_context_inactive;
1214+ shadow = d->frame->border_shadow_inactive;
1215+ }
1216+ }
1217+ else
1218+ {
1219+ context = &d->frame->window_context_no_shadow;
1220+ shadow = d->frame->border_no_shadow;
1221+ }
1222+ }
1223+
1224+ if (!d->frame_window)
1225+ {
1226+ decor_get_best_layout (context, w, h, &layout);
1227+
1228+ if (context != d->context || memcmp (&layout, &d->border_layout, sizeof (layout)))
1229+ {
1230+ *width = layout.width;
1231+ *height = layout.height;
1232+
1233+ d->border_layout = layout;
1234+ d->context = context;
1235+ d->shadow = shadow;
1236+
1237+ meta_calc_button_size (d);
1238+
1239+ return TRUE;
1240+ }
1241+ }
1242+ else
1243+ {
1244+ if ((d->state & META_MAXIMIZED) == META_MAXIMIZED)
1245+ decor_get_default_layout (context, d->client_width,
1246+ d->client_height - d->frame->titlebar_height,
1247+ &layout);
1248+ else
1249+ decor_get_default_layout (context, d->client_width,
1250+ d->client_height, &layout);
1251+
1252+ *width = layout.width;
1253+ *height = layout.height;
1254+
1255+ d->border_layout = layout;
1256+ d->shadow = shadow;
1257+ d->context = context;
1258+
1259+ meta_calc_button_size (d);
1260+
1261+ return TRUE;
1262+ }
1263+
1264+ return FALSE;
1265+}
1266+
1267+#define TOP_RESIZE_HEIGHT 2
1268+#define RESIZE_EXTENDS 15
1269+
1270+void
1271+meta_get_event_window_position (decor_t *d,
1272+ gint i,
1273+ gint j,
1274+ gint width,
1275+ gint height,
1276+ gint *x,
1277+ gint *y,
1278+ gint *w,
1279+ gint *h)
1280+{
1281+ MetaButtonLayout button_layout;
1282+ MetaFrameGeometry fgeom;
1283+ MetaFrameFlags flags;
1284+ MetaTheme *theme;
1285+
1286+ theme = meta_theme_get_current ();
1287+
1288+ meta_get_decoration_geometry (d, theme, &flags, &fgeom, &button_layout,
1289+ meta_frame_type_from_string (d->frame->type));
1290+
1291+ width += fgeom.borders.total.right + fgeom.borders.total.left;
1292+ height += fgeom.borders.total.top + fgeom.borders.total.bottom;
1293+
1294+ switch (i)
1295+ {
1296+ case 2: /* bottom */
1297+ switch (j)
1298+ {
1299+ case 2: /* bottom right */
1300+ *x = width - fgeom.borders.total.right - RESIZE_EXTENDS;
1301+ *y = height - fgeom.borders.total.bottom - RESIZE_EXTENDS;
1302+
1303+ if (d->frame_window)
1304+ {
1305+ *x += d->frame->win_extents.left + 2;
1306+ *y += d->frame->win_extents.top + 2;
1307+ }
1308+
1309+ *w = fgeom.borders.total.right + RESIZE_EXTENDS;
1310+ *h = fgeom.borders.total.bottom + RESIZE_EXTENDS;
1311+ break;
1312+ case 1: /* bottom */
1313+ *x = fgeom.borders.total.left + RESIZE_EXTENDS;
1314+ *y = height - fgeom.borders.total.bottom;
1315+
1316+ if (d->frame_window)
1317+ *y += d->frame->win_extents.top + 2;
1318+
1319+ *w = width - fgeom.borders.total.left - fgeom.borders.total.right - (2 * RESIZE_EXTENDS);
1320+ *h = fgeom.borders.total.bottom;
1321+ break;
1322+ case 0: /* bottom left */
1323+ default:
1324+ *x = 0;
1325+ *y = height - fgeom.borders.total.bottom - RESIZE_EXTENDS;
1326+
1327+ if (d->frame_window)
1328+ {
1329+ *x += d->frame->win_extents.left + 4;
1330+ *y += d->frame->win_extents.bottom + 2;
1331+ }
1332+
1333+ *w = fgeom.borders.total.left + RESIZE_EXTENDS;
1334+ *h = fgeom.borders.total.bottom + RESIZE_EXTENDS;
1335+ break;
1336+ }
1337+ break;
1338+ case 1: /* middle */
1339+ switch (j)
1340+ {
1341+ case 2: /* right */
1342+ *x = width - fgeom.borders.total.right;
1343+ *y = fgeom.borders.total.top + RESIZE_EXTENDS;
1344+
1345+ if (d->frame_window)
1346+ *x += d->frame->win_extents.left + 2;
1347+
1348+ *w = fgeom.borders.total.right;
1349+ *h = height - fgeom.borders.total.top - fgeom.borders.total.bottom - (2 * RESIZE_EXTENDS);
1350+ break;
1351+ case 1: /* middle */
1352+ *x = fgeom.borders.total.left;
1353+ *y = fgeom.title_rect.y + TOP_RESIZE_HEIGHT;
1354+ *w = width - fgeom.borders.total.left - fgeom.borders.total.right;
1355+ *h = height - fgeom.top_titlebar_edge - fgeom.borders.total.bottom;
1356+ break;
1357+ case 0: /* left */
1358+ default:
1359+ *x = 0;
1360+ *y = fgeom.borders.total.top + RESIZE_EXTENDS;
1361+
1362+ if (d->frame_window)
1363+ *x += d->frame->win_extents.left + 4;
1364+
1365+ *w = fgeom.borders.total.left;
1366+ *h = height - fgeom.borders.total.top - fgeom.borders.total.bottom - (2 * RESIZE_EXTENDS);
1367+ break;
1368+ }
1369+ break;
1370+ case 0: /* top */
1371+ default:
1372+ switch (j)
1373+ {
1374+ case 2: /* top right */
1375+ *x = width - fgeom.borders.total.right - RESIZE_EXTENDS;
1376+ *y = 0;
1377+
1378+ if (d->frame_window)
1379+ {
1380+ *x += d->frame->win_extents.left + 2;
1381+ *y += d->frame->win_extents.top + 2 - fgeom.title_rect.height;
1382+ }
1383+
1384+ *w = fgeom.borders.total.right + RESIZE_EXTENDS;
1385+ *h = fgeom.borders.total.top + RESIZE_EXTENDS;
1386+ break;
1387+ case 1: /* top */
1388+ *x = fgeom.borders.total.left + RESIZE_EXTENDS;
1389+ *y = 0;
1390+
1391+ if (d->frame_window)
1392+ *y += d->frame->win_extents.top + 2;
1393+
1394+ *w = width - fgeom.borders.total.left - fgeom.borders.total.right - (2 * RESIZE_EXTENDS);
1395+ *h = fgeom.borders.total.top - fgeom.title_rect.height;
1396+ break;
1397+ case 0: /* top left */
1398+ default:
1399+ *x = 0;
1400+ *y = 0;
1401+
1402+ if (d->frame_window)
1403+ {
1404+ *x += d->frame->win_extents.left + 4;
1405+ *y += d->frame->win_extents.top + 2 - fgeom.title_rect.height;
1406+ }
1407+
1408+ *w = fgeom.borders.total.left + RESIZE_EXTENDS;
1409+ *h = fgeom.borders.total.top + RESIZE_EXTENDS;
1410+ break;
1411+ }
1412+ break;
1413+ }
1414+
1415+ if (!(flags & META_FRAME_ALLOWS_VERTICAL_RESIZE))
1416+ {
1417+ /* turn off top and bottom event windows */
1418+ if (i == 0 || i == 2)
1419+ *w = *h = 0;
1420+ }
1421+
1422+ if (!(flags & META_FRAME_ALLOWS_HORIZONTAL_RESIZE))
1423+ {
1424+ /* turn off left and right event windows */
1425+ if (j == 0 || j == 2)
1426+ *w = *h = 0;
1427+ }
1428+}
1429+
1430+static MetaButtonFunction
1431+meta_button_function_from_string (const char *str)
1432+{
1433+ if (strcmp (str, "menu") == 0)
1434+ return META_BUTTON_FUNCTION_MENU;
1435+ else if (strcmp (str, "appmenu") == 0)
1436+ return META_BUTTON_FUNCTION_APPMENU;
1437+ else if (strcmp (str, "minimize") == 0)
1438+ return META_BUTTON_FUNCTION_MINIMIZE;
1439+ else if (strcmp (str, "maximize") == 0)
1440+ return META_BUTTON_FUNCTION_MAXIMIZE;
1441+ else if (strcmp (str, "close") == 0)
1442+ return META_BUTTON_FUNCTION_CLOSE;
1443+ else if (strcmp (str, "shade") == 0)
1444+ return META_BUTTON_FUNCTION_SHADE;
1445+ else if (strcmp (str, "above") == 0)
1446+ return META_BUTTON_FUNCTION_ABOVE;
1447+ else if (strcmp (str, "stick") == 0)
1448+ return META_BUTTON_FUNCTION_STICK;
1449+ else if (strcmp (str, "unshade") == 0)
1450+ return META_BUTTON_FUNCTION_UNSHADE;
1451+ else if (strcmp (str, "unabove") == 0)
1452+ return META_BUTTON_FUNCTION_UNABOVE;
1453+ else if (strcmp (str, "unstick") == 0)
1454+ return META_BUTTON_FUNCTION_UNSTICK;
1455+ else
1456+ return META_BUTTON_FUNCTION_LAST;
1457+}
1458+
1459+static MetaButtonFunction
1460+meta_button_opposite_function (MetaButtonFunction ofwhat)
1461+{
1462+ switch (ofwhat)
1463+ {
1464+ case META_BUTTON_FUNCTION_SHADE:
1465+ return META_BUTTON_FUNCTION_UNSHADE;
1466+ case META_BUTTON_FUNCTION_UNSHADE:
1467+ return META_BUTTON_FUNCTION_SHADE;
1468+
1469+ case META_BUTTON_FUNCTION_ABOVE:
1470+ return META_BUTTON_FUNCTION_UNABOVE;
1471+ case META_BUTTON_FUNCTION_UNABOVE:
1472+ return META_BUTTON_FUNCTION_ABOVE;
1473+
1474+ case META_BUTTON_FUNCTION_STICK:
1475+ return META_BUTTON_FUNCTION_UNSTICK;
1476+ case META_BUTTON_FUNCTION_UNSTICK:
1477+ return META_BUTTON_FUNCTION_STICK;
1478+
1479+ default:
1480+ return META_BUTTON_FUNCTION_LAST;
1481+ }
1482+}
1483+
1484+static void
1485+meta_initialize_button_layout (MetaButtonLayout *layout)
1486+{
1487+ int i;
1488+
1489+ for (i = 0; i < MAX_BUTTONS_PER_CORNER; ++i)
1490+ {
1491+ layout->left_buttons[i] = META_BUTTON_FUNCTION_LAST;
1492+ layout->right_buttons[i] = META_BUTTON_FUNCTION_LAST;
1493+ layout->left_buttons_has_spacer[i] = FALSE;
1494+ layout->right_buttons_has_spacer[i] = FALSE;
1495+ }
1496+}
1497+
1498+void
1499+meta_update_button_layout (const char *value)
1500+{
1501+ MetaButtonLayout new_layout;
1502+ MetaButtonFunction f;
1503+ char **sides;
1504+ int i;
1505+
1506+ meta_initialize_button_layout (&new_layout);
1507+
1508+ sides = g_strsplit (value, ":", 2);
1509+
1510+ if (sides[0] != NULL)
1511+ {
1512+ char **buttons;
1513+ int b;
1514+ gboolean used[META_BUTTON_FUNCTION_LAST];
1515+
1516+ for (i = 0; i < META_BUTTON_FUNCTION_LAST; ++i)
1517+ used[i] = FALSE;
1518+
1519+ buttons = g_strsplit (sides[0], ",", -1);
1520+
1521+ i = b = 0;
1522+ while (buttons[b] != NULL)
1523+ {
1524+ f = meta_button_function_from_string (buttons[b]);
1525+ if (i > 0 && strcmp ("spacer", buttons[b]) == 0)
1526+ {
1527+ new_layout.left_buttons_has_spacer[i - 1] = TRUE;
1528+ f = meta_button_opposite_function (f);
1529+
1530+ if (f != META_BUTTON_FUNCTION_LAST)
1531+ new_layout.left_buttons_has_spacer[i - 2] = TRUE;
1532+ }
1533+ else
1534+ {
1535+ if (f != META_BUTTON_FUNCTION_LAST && !used[f])
1536+ {
1537+ used[f] = TRUE;
1538+ new_layout.left_buttons[i++] = f;
1539+
1540+ f = meta_button_opposite_function (f);
1541+
1542+ if (f != META_BUTTON_FUNCTION_LAST)
1543+ new_layout.left_buttons[i++] = f;
1544+
1545+ }
1546+ else
1547+ {
1548+ fprintf (stderr, "%s: Ignoring unknown or already-used "
1549+ "button name \"%s\"\n", program_name, buttons[b]);
1550+ }
1551+ }
1552+ ++b;
1553+ }
1554+
1555+ new_layout.left_buttons[i] = META_BUTTON_FUNCTION_LAST;
1556+
1557+ g_strfreev (buttons);
1558+
1559+ if (sides[1] != NULL)
1560+ {
1561+ for (i = 0; i < META_BUTTON_FUNCTION_LAST; ++i)
1562+ used[i] = FALSE;
1563+
1564+ buttons = g_strsplit (sides[1], ",", -1);
1565+
1566+ i = b = 0;
1567+ while (buttons[b] != NULL)
1568+ {
1569+ f = meta_button_function_from_string (buttons[b]);
1570+ if (i > 0 && strcmp ("spacer", buttons[b]) == 0)
1571+ {
1572+ new_layout.right_buttons_has_spacer[i - 1] = TRUE;
1573+ f = meta_button_opposite_function (f);
1574+ if (f != META_BUTTON_FUNCTION_LAST)
1575+ new_layout.right_buttons_has_spacer[i - 2] = TRUE;
1576+ }
1577+ else
1578+ {
1579+ if (f != META_BUTTON_FUNCTION_LAST && !used[f])
1580+ {
1581+ used[f] = TRUE;
1582+ new_layout.right_buttons[i++] = f;
1583+
1584+ f = meta_button_opposite_function (f);
1585+
1586+ if (f != META_BUTTON_FUNCTION_LAST)
1587+ new_layout.right_buttons[i++] = f;
1588+ }
1589+ else
1590+ {
1591+ fprintf (stderr, "%s: Ignoring unknown or "
1592+ "already-used button name \"%s\"\n",
1593+ program_name, buttons[b]);
1594+ }
1595+ }
1596+ ++b;
1597+ }
1598+
1599+ new_layout.right_buttons[i] = META_BUTTON_FUNCTION_LAST;
1600+
1601+ g_strfreev (buttons);
1602+ }
1603+ }
1604+
1605+ g_strfreev (sides);
1606+
1607+ /* Invert the button layout for RTL languages */
1608+ if (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL)
1609+ {
1610+ MetaButtonLayout rtl_layout;
1611+ int j;
1612+
1613+ meta_initialize_button_layout (&rtl_layout);
1614+
1615+ i = 0;
1616+ while (new_layout.left_buttons[i] != META_BUTTON_FUNCTION_LAST)
1617+ ++i;
1618+
1619+ for (j = 0; j < i; ++j)
1620+ {
1621+ rtl_layout.right_buttons[j] = new_layout.left_buttons[i - j - 1];
1622+ if (j == 0)
1623+ rtl_layout.right_buttons_has_spacer[i - 1] = new_layout.left_buttons_has_spacer[i - j - 1];
1624+ else
1625+ rtl_layout.right_buttons_has_spacer[j - 1] = new_layout.left_buttons_has_spacer[i - j - 1];
1626+ }
1627+
1628+ i = 0;
1629+ while (new_layout.right_buttons[i] != META_BUTTON_FUNCTION_LAST)
1630+ ++i;
1631+
1632+ for (j = 0; j < i; ++j)
1633+ {
1634+ rtl_layout.left_buttons[j] = new_layout.right_buttons[i - j - 1];
1635+ if (j == 0)
1636+ rtl_layout.left_buttons_has_spacer[i - 1] = new_layout.right_buttons_has_spacer[i - j - 1];
1637+ else
1638+ rtl_layout.left_buttons_has_spacer[j - 1] = new_layout.right_buttons_has_spacer[i - j - 1];
1639+ }
1640+
1641+ new_layout = rtl_layout;
1642+ }
1643+
1644+ meta_button_layout = new_layout;
1645+}
1646+
1647+void
1648+meta_update_border_extents (decor_frame_t *frame)
1649+{
1650+ MetaTheme *theme;
1651+ GdkScreen *screen;
1652+ MetaStyleInfo *style_info;
1653+ MetaFrameBorders borders;
1654+ MetaFrameType frame_type;
1655+ gint top_height;
1656+ gint bottom_height;
1657+ gint left_width;
1658+ gint right_width;
1659+
1660+ gwd_decor_frame_ref (frame);
1661+
1662+ frame_type = meta_frame_type_from_string (frame->type);
1663+ if (!(frame_type < META_FRAME_TYPE_LAST))
1664+ frame_type = META_FRAME_TYPE_NORMAL;
1665+
1666+ theme = meta_theme_get_current ();
1667+
1668+ screen = gtk_widget_get_screen (frame->style_window_rgba);
1669+ style_info = meta_theme_create_style_info (screen, NULL);
1670+
1671+ meta_theme_get_frame_borders (theme, style_info, frame_type, frame->text_height,
1672+ 0, &borders);
1673+
1674+ top_height = borders.visible.top;
1675+ bottom_height = borders.visible.bottom;
1676+ left_width = borders.visible.left;
1677+ right_width = borders.visible.right;
1678+
1679+ frame->win_extents.top = frame->win_extents.top;
1680+ frame->win_extents.bottom = bottom_height;
1681+ frame->win_extents.left = left_width;
1682+ frame->win_extents.right = right_width;
1683+
1684+ frame->titlebar_height = top_height - frame->win_extents.top;
1685+
1686+ meta_theme_get_frame_borders (theme, style_info, frame_type, frame->text_height,
1687+ META_FRAME_MAXIMIZED, &borders);
1688+
1689+ top_height = borders.visible.top;
1690+ bottom_height = borders.visible.bottom;
1691+ left_width = borders.visible.left;
1692+ right_width = borders.visible.right;
1693+
1694+ frame->max_win_extents.top = frame->win_extents.top;
1695+ frame->max_win_extents.bottom = bottom_height;
1696+ frame->max_win_extents.left = left_width;
1697+ frame->max_win_extents.right = right_width;
1698+
1699+ frame->max_titlebar_height = top_height - frame->max_win_extents.top;
1700+
1701+ meta_style_info_unref (style_info);
1702+
1703+ gwd_decor_frame_unref (frame);
1704+}
1705+
1706+#endif
1707
1708=== modified file 'plugins/grid/src/grid.cpp'
1709=== modified file 'plugins/neg/src/neg.cpp'
1710=== modified file 'plugins/opengl/src/paint.cpp'
1711=== modified file 'src/region/src/region.cpp'
1712--- src/region/src/region.cpp 2012-10-16 07:00:03 +0000
1713+++ src/region/src/region.cpp 2018-02-20 17:39:33 +0000
1714@@ -110,7 +110,10 @@
1715 CompRegion::~CompRegion ()
1716 {
1717 if (priv)
1718- XDestroyRegion (static_cast<Region> (priv));
1719+ {
1720+ XDestroyRegion (static_cast<Region> (priv));
1721+ priv = NULL;
1722+ }
1723 }
1724
1725 void
1726
1727=== modified file 'src/screen.cpp'

Subscribers

People subscribed via source and target branches

to all changes: