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