Compare commits

...

66 Commits

Author SHA1 Message Date
Jasper St. Pierre
bb9501dbdf compositor: Remove meta_compositor_window_[un]mapped
We no longer unmap the toplevel windows during normal operation. The
toplevel state is tied to the window's lifetime.

Call meta_compositor_add_window / meta_compositor_remove_window instead...
2013-12-09 15:49:50 -05:00
Jasper St. Pierre
1db95bc32b Move _NET_WM_WINDOW_OPACITY handling to the standard window-props interface
This removes one X11 dependency that the MetaWindowActor interface has,
making it easier for us to use Wayland on this one...

https://bugzilla.gnome.org/show_bug.cgi?id=720106
2013-12-09 15:43:52 -05:00
Jasper St. Pierre
93a8933282 compositor: Remove atom_x_root_pixmap
It's unused

https://bugzilla.gnome.org/show_bug.cgi?id=720106
2013-12-09 15:43:16 -05:00
Jasper St. Pierre
5a63aaa5ac window-actor: Fix build
This was a bad rebase...
2013-12-09 14:17:06 -05:00
Jasper St. Pierre
a3eb5e562a window-actor: Move signal handler connections to the meta-window setter 2013-12-09 14:07:25 -05:00
Jasper St. Pierre
8a76383eca window-actor: Make the meta-window property construct-only
We don't deal with setting this property at all, and it's unlikely
to come up in future settings, so just don't allow setting it at all.

https://bugzilla.gnome.org/show_bug.cgi?id=678989
2013-12-09 14:06:13 -05:00
Jasper St. Pierre
734deeb17c window-actor: Remove meta-screen property
This can be inferred from the window. Don't allow anybody to set it.

https://bugzilla.gnome.org/show_bug.cgi?id=678989
2013-12-09 14:06:13 -05:00
Jasper St. Pierre
f8b4c28278 window-actor: Remove (private) xwindow property
This should make it easier to construct a MetaWindowActor from bindings.

https://bugzilla.gnome.org/show_bug.cgi?id=678989
2013-12-09 14:06:13 -05:00
Jasper St. Pierre
3e179c07bc window: Add a simple meta_window_get_toplevel_xwindow utility
To replace all the places where we do:

  window->frame ? window->frame->xwindow : window->xwindow

or similar...
2013-12-09 14:06:13 -05:00
Jasper St. Pierre
56aae17b46 window-actor: Remove outdated code path
The shadow is added in the paint step, not as a separate actor,
so the raise is a no-op. It also gets rid of an annoying misspelling
that's driving me crazy.
2013-12-09 14:06:12 -05:00
甘露(Gan Lu)
78741846a4 Update Chinese simplified translation 2013-12-07 15:02:43 +08:00
Alberto Milone
55180f5bb3 xrandr: ignore the error if setting the primary output fails
Some drivers which support RandR 1.4 may not support setting
or getting the primary output, therefore mutter should trap
and ignore any relevant errors.

The modesetting driver exposes this problem when used in
combination with the nvidia binary driver using RandR 1.4
offloading.

Also use a local display variable instead of calling
meta_get_display () every time.
2013-12-06 16:39:40 +01:00
Jasper St. Pierre
62b884dd42 display: Fix checks for KeyPress/ButtonPress 2013-12-06 00:51:41 -05:00
Owen W. Taylor
3283018bfb Use the correct frame size during unmaximize
When unmaximizing, we changed bits of window state, then called out
to code that used the frame extents *before* we cleared old cached
extents. Clear the cache up-front as soon as we change the window
state.

https://bugzilla.gnome.org/show_bug.cgi?id=714707
2013-12-05 11:15:23 -05:00
Owen W. Taylor
55226ada8a MetaWindowGroup: fix paint volume
In the past, MetaWindowGroup was allocated the size of the screen and
painted the size of the screen because it contained the screen background,
but now we also have the "top window group" which contains only popup
windows, so the allocation doesn't properly reflect the paint bounds
of the window group. Compute the paint bounds accurately from the
children.

https://bugzilla.gnome.org/show_bug.cgi?id=719669
2013-12-05 09:02:44 -05:00
Owen W. Taylor
ff790f7b39 window-props.c: React to changes to _GTK_FRAME_EXTENTS
When _GTK_FRAME_EXTENTS changes, we need to redo constraints on
the window - this matters in particular if the toolkit removes
invisible borders when a window is maximized, since otherwise
the maximized window will be positioned as if it still has
invisible borders.

https://bugzilla.gnome.org/show_bug.cgi?id=714707
2013-12-05 07:47:57 -05:00
Jasper St. Pierre
899570d213 background-actor: Remove custom get_paint_volume
The paint volume should be based on what we paint, not what the content
wants to be painted as. Thus, it should be the allocation.
2013-12-03 14:32:28 -05:00
Rico Tzschichholz
3b2506851c prefs: Properly add new META_KEYBINDING_ACTION_* value
In addition to 4373916d9d
2013-11-29 13:53:15 +01:00
Rico Tzschichholz
9b88059e55 window: Proper argument naming for meta_window_client_rect_to_frame_rect 2013-11-29 13:52:18 +01:00
Rico Tzschichholz
59168b2c64 window: Fix deprecated version of get_outer_rect 2013-11-29 09:12:16 +01:00
Jasper St. Pierre
47144253e4 cullable: Turn cull_out / reset_culling into a separate interface
Instead of hardcoded knowledge of certain classes in MetaWindowGroup,
create a generic interface that all actors can implement to get parts of
their regions culled out during redraw, without needing any special
knowledge of how to handle a specific actor.

The names now are a bit suspect. MetaBackgroundGroup is a simple
MetaCullable that knows how to cull children, and MetaWindowGroup is the
"toplevel" cullable that computes the initial two regions. A future
cleanup here could be to merge MetaWindowGroup / MetaBackgroundGroup so
that we only have a generic MetaSimpleCullable, and move the "toplevel"
cullability to be a MetaCullableToplevel.

https://bugzilla.gnome.org/show_bug.cgi?id=714706
2013-11-25 15:08:22 -05:00
Jasper St. Pierre
d8c66077f0 window-actor: Move the operations we need to do when we cull out here
Soon, we'll move this into a generic MetaCullable interface, but for
now, just put hardcoded knowledge in MetaWindowGroup.

https://bugzilla.gnome.org/show_bug.cgi?id=714706
2013-11-25 15:08:22 -05:00
Jasper St. Pierre
59a01137e1 window-group: Decompose culling operations into two methods
This also fixes a bug in the translation of clip_region.

We will add an interface for this soon, so we can recursively cull like this...

https://bugzilla.gnome.org/show_bug.cgi?id=714706
2013-11-25 15:08:22 -05:00
Jasper St. Pierre
ce3804ee04 display: Use MetaWindow for auto-raise callbacks
This allows us to autoraise Wayland windows... well, except for the
XQueryPointer, but we'll replace that soon.

https://bugzilla.gnome.org/show_bug.cgi?id=715030
2013-11-25 15:08:21 -05:00
Jasper St. Pierre
f0bc53ce5a display: Fix logic for determining whether our focus was successful
In some cases, we can focus the frame window instead of the client
window, so make sure that our checks include that as well.

https://bugzilla.gnome.org/show_bug.cgi?id=715030
2013-11-25 15:08:21 -05:00
Jasper St. Pierre
b8938e9d4d window-actor: Fix a copy/paste typo 2013-11-21 17:36:20 -05:00
Jasper St. Pierre
7116d9cedb background-group: Fix cast warning 2013-11-21 16:07:51 -05:00
Jasper St. Pierre
66fb86fd0c background-group: Use the Clutter iteration APIs 2013-11-21 16:07:51 -05:00
Jasper St. Pierre
59cfbb07c8 background-group: Remove some unnecessary cruft 2013-11-21 16:07:51 -05:00
Rui Matos
dc5bc3fea8 idle-monitor: Fix a GSList leak
https://bugzilla.gnome.org/show_bug.cgi?id=712833
2013-11-21 19:24:07 +01:00
Owen W. Taylor
fbbc32422e Rename meta_window_get_outer_rect() to meta_window_get_frame_rect()
For clarity, rename meta_window_get_outer_rect() to match terminology
we use elsewhere. The old function is left as a deprecated
compatibility wrapper.
2013-11-19 13:28:23 -05:00
Owen W. Taylor
fe8829f324 Stop passing around MetaFrameBorders
Instead of passing around MetaFrameBorders, compute it when we need it.
This also allows us to know that we are using MetaFrameBorders only for windows
with frames (where it is meaningful) and not for frameless windows, which
can have custom borders which we need to interpret differently.

https://bugzilla.gnome.org/show_bug.cgi?id=707194
2013-11-19 13:28:23 -05:00
Owen W. Taylor
b4036e061a MetaFrame: Cache borders
Cache the computed border size so we can fetch the border size at
any time without worrying that we'll be spending too much time in
the theme code (in some cases we might allocate a PangoFontDescription
or do other significant work.)

The main effort here is clearing the cache when various bits of window
state change that could potentially affect the computed borders.

https://bugzilla.gnome.org/show_bug.cgi?id=707194
2013-11-19 13:28:23 -05:00
Owen W. Taylor
4ee9f3563b Use utility functions to convert between frame and client rectangles
There are extensive places in the code where we convert between the client
rectangle and the frame rectangle. Instead of manually doing it use
new helper functions on MetaWindow and the existing meta_window_get_outer_rect().

This fixes a number of bugs where the computation was being done incorrectly,
most of these bugs are with the recently added custom frame extents, but
some relate to invisible borders or even simply to confusion between the
window and frame rectangle.

Switch the placement code to place the frame rectangle rather
than the client window - this simplifies things considerably.

https://bugzilla.gnome.org/show_bug.cgi?id=707194
2013-11-19 13:28:23 -05:00
Giovanni Campagna
c652a54f59 constraints: account for decorations when positioning modal dialogs
What we want to achieve is that the dialog is visually centered
on the parent, including the decorations for both, and making sure
that CSD/frame_extents are respected.

https://bugzilla.gnome.org/show_bug.cgi?id=707194
2013-11-19 13:28:23 -05:00
Robert Bragg
61881477ac Track the X Shape input region and use it for picking
We now track whether a window has an input shape specified via the X
Shape extension. Intersecting that with the bounding shape (as required
by the X Shape extension) we use the resulting rectangles to paint
window silhouettes when picking. As well as improving the correctness of
picking this should also be much more efficient because typically when
only picking solid rectangles then the need to actually render and issue
a read_pixels request can be optimized away and instead the picking is
done on the cpu.
2013-11-18 13:06:54 -05:00
Sindhu S
4373916d9d Add keyboard shortcut for Always on Top, bug 704831 2013-11-16 22:48:28 +05:30
Sindhu S
660d7df5ab Revert "Add keyboard shortcut for Always on Top"
This reverts commit b7e3f627f1.
2013-11-16 21:34:48 +05:30
Sindhu S
b7e3f627f1 Add keyboard shortcut for Always on Top 2013-11-16 21:14:30 +05:30
Marc-André Lureau
ca5d115715 xrandr: use "hotplug_mode_update" property
Use the "hotplug_mode_update" connector property indicating that the
screen settings should be updated: get a new preferred mode on hotplug
events to handle dynamic guest resizing (where you resize the host
window and the guest resizes with it).

https://bugzilla.gnome.org/show_bug.cgi?id=711216
2013-11-14 14:55:42 +01:00
Florian Müllner
21c46852cd Bump version to 3.11.2
Update NEWS.
2013-11-13 20:50:11 +01:00
Florian Müllner
10036832dd doc: Fix file globs
Any files matching the previously used globs are no longer distributed,
breaking distcheck. Match the actual sources in compositor/, core/, meta/
and ui/ instead.
2013-11-13 20:49:52 +01:00
Jasper St. Pierre
25b5ea8b4f screen: Laters are not GSources
This warns with the new GLib when we destroy the screen.

https://bugzilla.gnome.org/show_bug.cgi?id=711731
2013-11-09 11:46:01 -05:00
Jasper St. Pierre
20beaf7fe1 compositor: Clean up comment
So it seems that we were intentionally delaying the output window,
although I wonder why...
2013-11-05 09:15:23 -05:00
Jasper St. Pierre
e72af50420 compositor: Initialize the plugin manager after initializing the output window
Plugins like gnome-shell may want to grab the output window immediately
before bouncing back to the mainloop.
2013-11-04 10:39:49 -05:00
Lionel Landwerlin
ef4417b717 window: don't ignore resize button release event for move/resize actions
https://bugzilla.gnome.org/show_bug.cgi?id=710251
2013-11-04 13:52:06 +00:00
Rico Tzschichholz
cf943627e2 build: Make sure built-sources are introspected as needed 2013-10-31 00:09:15 +01:00
Rico Tzschichholz
96543cb009 build: Do not ship generated source-files in tarball 2013-10-30 23:42:12 +01:00
Florian Müllner
fbb2207f8c Fix typo 2013-10-30 17:14:16 +01:00
Florian Müllner
cce8a4341b Bump version to 3.11.1
Update NEWS.
2013-10-30 16:34:59 +01:00
Jasper St. Pierre
b82784ee46 display: Don't focus the no-focus-window when sending WM_TAKE_FOCUS to a globally active window
Clients like on-screen keyboards try not to take focus when the user clicks
on their window by setting the Input hint to false. However, due to GTK+ and
GDK bugs, the public API for setting the Input hint to false don't remove
WM_TAKE_FOCUS from WM_PROTOCOLS, unintentionally putting them into Globally
Active mode.

These clients also expect that since they don't want to take focus, they want
the focus to remain on the existing window. In this case, for clients like
on-screen keyboards, it's so they can send synthesized keyboard events to the
focused window.

https://bugzilla.gnome.org/show_bug.cgi?id=710296
2013-10-29 16:26:00 -04:00
Magdalen Berns
6b8959916c Mutter-Wayland: fix build failure
Bug https://bugzilla.gnome.org/show_bug.cgi?id=710565
2013-10-29 13:04:48 +00:00
Rico Tzschichholz
ecc1830296 meta-cursor-tracker: Add missing include of Xcursor.h 2013-10-29 11:39:02 +01:00
Reinout van Schouwen
497916aad7 Updated Dutch translation 2013-10-25 00:25:49 +02:00
Asad Mehmood
e171a31ac5 monitor: expose min-backlight-step
Expose min-backlight-step so that gnome-settings-daemon can
support backlights with less than 10 steps without mutter
normalizing the brightness back to its original value

https://bugzilla.gnome.org/show_bug.cgi?id=710380
2013-10-21 23:22:41 +02:00
Bastien Nocera
a9a10aaa20 MonitorConfig: Use new UPower API
The "changed" signal was removed. Use "notify" instead
to track just the lid-is-closed state.
2013-10-21 14:00:48 +02:00
A. Walton
656d079ffc screen: Name the guard window
So that extensons can recognize it, for the case where they
want to watch the window list.

https://bugzilla.gnome.org/show_bug.cgi?id=710346
2013-10-16 22:39:21 -04:00
Olav Vitters
d801f699af link mutter-wayland to mutter git repos 2013-10-16 15:37:48 +02:00
Jasper St. Pierre
89d01d2c17 core: Remove old unused methods 2013-10-16 01:29:56 -04:00
Jasper St. Pierre
ec284bc56a display: Fix whitespace / code style with autoraise stuff 2013-10-16 00:34:22 -04:00
Jasper St. Pierre
db2e00d41c keybindings: Remove unused function 2013-10-15 23:38:48 -04:00
Jasper St. Pierre
0a616c9fcb keybindings: Remove unused parameter from process_event 2013-10-15 23:38:47 -04:00
Jasper St. Pierre
fed3cd9e82 keybindings: Drop an unnecessary check 2013-10-15 23:38:47 -04:00
Jasper St. Pierre
d0d8a3d4ea window: Remove timestamp argument from change_workspace_by_index
It's unused, since we aren't activating the workspace.

https://bugzilla.gnome.org/show_bug.cgi?id=709776
2013-10-15 15:45:21 -04:00
Jasper St. Pierre
bdf5f88349 display: Deduplicate cursor loading code
Rather than do the cursor -> name translation ourselves in two different
places, use the facilities in libXcursor to do it for us. Put the shared
piece of code in meta-cursor-tracker, and use it for both server-side and
client-side cursor loading.
2013-10-15 15:39:58 -04:00
Giovanni Campagna
809dbe16d6 monitor-config: prevent assert that at least one output is connected
Apparently some connector technologies don't distinguish between
on and off, and there might be valid use cases for running without
any connected monitor.
In that case, just avoid any configuration at all.

https://bugzilla.gnome.org/show_bug.cgi?id=709009
2013-10-15 21:26:36 +02:00
50 changed files with 2227 additions and 1959 deletions

View File

@@ -8,3 +8,5 @@ EXTRA_DIST = HACKING MAINTAINERS rationales.txt
DISTCLEANFILES = intltool-extract intltool-merge intltool-update po/stamp-it po/.intltool-merge-cache DISTCLEANFILES = intltool-extract intltool-merge intltool-update po/stamp-it po/.intltool-merge-cache
DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}

24
NEWS
View File

@@ -1,3 +1,27 @@
3.11.2
======
* Fix resize operations using mouse-button-modifier [Lionel; #710251]
* Misc. fixes and cleanups [Jasper, Rico, Florian; #711731]
Contributors:
Lionel Landwerlin, Florian Müllner, Jasper St. Pierre, Rico Tzschichholz
3.11.1
======
* Don't require at least one output device to be connected [Giovanni; #709009]
* Name the guard window [Andrew; #710346]
* Use new UPower API [Bastien]
* Expose min-backlight-step [Asad; #710380]
* Don't focus the no-focus-window for globally active windows [Jasper; #710296]
* Misc. fixes and cleanups [Jasper, Rico, Olav, Magdalen; #709776]
Contributors:
Magdalen Berns, Giovanni Campagna, Asad Mehmood, Bastien Nocera,
Jasper St. Pierre, Rico Tzschichholz, Olav Vitters, Andrew Walton
Translations:
Reinout van Schouwen [nl]
3.10.1 3.10.1
====== ======
* Don't apply fullscreen workarounds to CSD windows [Giovanni; #708718] * Don't apply fullscreen workarounds to CSD windows [Giovanni; #708718]

View File

@@ -1,8 +1,9 @@
AC_PREREQ(2.50) AC_PREREQ(2.50)
AC_CONFIG_MACRO_DIR([m4])
m4_define([mutter_major_version], [3]) m4_define([mutter_major_version], [3])
m4_define([mutter_minor_version], [10]) m4_define([mutter_minor_version], [11])
m4_define([mutter_micro_version], [1]) m4_define([mutter_micro_version], [2])
m4_define([mutter_version], m4_define([mutter_version],
[mutter_major_version.mutter_minor_version.mutter_micro_version]) [mutter_major_version.mutter_minor_version.mutter_micro_version])
@@ -76,7 +77,7 @@ MUTTER_PC_MODULES="
xcomposite >= 0.2 xfixes xrender xdamage xi >= 1.6.0 xcomposite >= 0.2 xfixes xrender xdamage xi >= 1.6.0
$CLUTTER_PACKAGE >= 1.15.90 $CLUTTER_PACKAGE >= 1.15.90
cogl-1.0 >= 1.15.6 cogl-1.0 >= 1.15.6
upower-glib > 0.9.11 upower-glib >= 0.99.0
gnome-desktop-3.0 gnome-desktop-3.0
" "

View File

@@ -49,8 +49,8 @@ FIXXREF_OPTIONS=
# Used for dependencies. The docs will be rebuilt if any of these change. # Used for dependencies. The docs will be rebuilt if any of these change.
# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h # e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h
# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c # e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c
HFILE_GLOB=$(top_srcdir)/src/*.h HFILE_GLOB=$(top_srcdir)/src/*/*.h
CFILE_GLOB=$(top_srcdir)/src/*.c CFILE_GLOB=$(top_srcdir)/src/*/*.c
# Extra header to include when scanning, which are not under DOC_SOURCE_DIR # Extra header to include when scanning, which are not under DOC_SOURCE_DIR
# e.g. EXTRA_HFILES=$(top_srcdir}/contrib/extra.h # e.g. EXTRA_HFILES=$(top_srcdir}/contrib/extra.h

View File

@@ -96,8 +96,6 @@ meta_compositor_hide_window
meta_compositor_switch_workspace meta_compositor_switch_workspace
meta_compositor_maximize_window meta_compositor_maximize_window
meta_compositor_unmaximize_window meta_compositor_unmaximize_window
meta_compositor_window_mapped
meta_compositor_window_unmapped
meta_compositor_sync_window_geometry meta_compositor_sync_window_geometry
meta_compositor_set_updates_frozen meta_compositor_set_updates_frozen
meta_compositor_queue_frame_drawn meta_compositor_queue_frame_drawn
@@ -207,7 +205,6 @@ meta_key_binding_get_modifiers
meta_key_binding_get_mask meta_key_binding_get_mask
meta_key_binding_is_builtin meta_key_binding_is_builtin
meta_keybindings_set_custom_handler meta_keybindings_set_custom_handler
meta_keybindings_switch_window
meta_screen_ungrab_all_keys meta_screen_ungrab_all_keys
meta_screen_grab_all_keys meta_screen_grab_all_keys
</SECTION> </SECTION>
@@ -389,6 +386,23 @@ MetaWindowActorPrivate
meta_window_actor_get_type meta_window_actor_get_type
</SECTION> </SECTION>
<SECTION>
<FILE>meta-cullable</FILE>
<TITLE>MetaCullable</TITLE>
MetaCullable
MetaCullableInterface
meta_cullable_cull_out
meta_cullable_reset_culling
meta_cullable_cull_out_children
meta_cullable_reset_culling_children
<SUBSECTION Standard>
META_TYPE_CULLABLE
META_CULLABLE
META_IS_CULLABLE
META_CULLABLE_GET_IFACE
meta_cullable_get_type
</SECTION>
<SECTION> <SECTION>
<FILE>prefs</FILE> <FILE>prefs</FILE>
MetaPreference MetaPreference
@@ -542,7 +556,10 @@ meta_window_is_override_redirect
meta_window_is_skip_taskbar meta_window_is_skip_taskbar
meta_window_get_rect meta_window_get_rect
meta_window_get_input_rect meta_window_get_input_rect
meta_window_get_frame_rect
meta_window_get_outer_rect meta_window_get_outer_rect
meta_window_client_rect_to_frame_rect
meta_window_frame_rect_to_client_rect
meta_window_get_screen meta_window_get_screen
meta_window_get_display meta_window_get_display
meta_window_get_xwindow meta_window_get_xwindow

View File

@@ -21,6 +21,7 @@ environment.</description>
--> -->
<mailing-list rdf:resource="http://mail.gnome.org/mailman/listinfo/gnome-shell-list" /> <mailing-list rdf:resource="http://mail.gnome.org/mailman/listinfo/gnome-shell-list" />
<download-page rdf:resource="http://download.gnome.org/sources/mutter/" /> <download-page rdf:resource="http://download.gnome.org/sources/mutter/" />
<download-page rdf:resource="http://download.gnome.org/sources/mutter-wayland/" />
<bug-database rdf:resource="http://bugzilla.gnome.org/browse.cgi?product=mutter" /> <bug-database rdf:resource="http://bugzilla.gnome.org/browse.cgi?product=mutter" />
<category rdf:resource="http://api.gnome.org/doap-extensions#desktop" /> <category rdf:resource="http://api.gnome.org/doap-extensions#desktop" />

230
po/nl.po
View File

@@ -7,10 +7,9 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: mutter\n" "Project-Id-Version: mutter\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=mutter" "Report-Msgid-Bugs-To: \n"
"&keywords=I18N+L10N&component=general\n" "POT-Creation-Date: 2013-10-25 00:25+0200\n"
"POT-Creation-Date: 2013-08-18 20:03+0000\n" "PO-Revision-Date: 2013-10-25 00:23+0200\n"
"PO-Revision-Date: 2013-10-12 00:32+0200\n"
"Last-Translator: Reinout van Schouwen <reinouts@gnome.org>\n" "Last-Translator: Reinout van Schouwen <reinouts@gnome.org>\n"
"Language-Team: Dutch <vertaling@vrijschrift.org>\n" "Language-Team: Dutch <vertaling@vrijschrift.org>\n"
"Language: nl\n" "Language: nl\n"
@@ -18,7 +17,6 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Virtaal 0.7.1\n"
"X-Project-Style: gnome\n" "X-Project-Style: gnome\n"
#: ../src/50-mutter-navigation.xml.in.h:1 #: ../src/50-mutter-navigation.xml.in.h:1
@@ -211,16 +209,16 @@ msgstr "Weergave gesplitst op rechts"
#. This probably means that a non-WM compositor like xcompmgr is running; #. This probably means that a non-WM compositor like xcompmgr is running;
#. * we have no way to get it to exit #. * we have no way to get it to exit
#: ../src/compositor/compositor.c:589 #: ../src/compositor/compositor.c:596
#, c-format #, c-format
msgid "" msgid ""
"Another compositing manager is already running on screen %i on display \"%s" "Another compositing manager is already running on screen %i on display \"%s"
"\"." "\"."
msgstr "" msgstr ""
"Er is al een andere compositing manager actief op scherm %i van display %" "Er is al een andere compositing manager actief op scherm %i van display "
"s." "%s."
#: ../src/compositor/meta-background.c:1076 #: ../src/compositor/meta-background.c:1075
msgid "background texture could not be created from file" msgid "background texture could not be created from file"
msgstr "aanmaken achtergrondstructuur uit bestand mislukt" msgstr "aanmaken achtergrondstructuur uit bestand mislukt"
@@ -235,7 +233,6 @@ msgstr "Onbekende aanvraag voor vensterinformatie: %d"
#: ../src/core/delete.c:111 #: ../src/core/delete.c:111
#, c-format #, c-format
#| msgid "<tt>%s</tt> is not responding."
msgid "“%s” is not responding." msgid "“%s” is not responding."
msgstr "%s reageert niet." msgstr "%s reageert niet."
@@ -281,7 +278,6 @@ msgstr ""
#: ../src/core/keybindings.c:1333 #: ../src/core/keybindings.c:1333
#, c-format #, c-format
#| msgid "\"%s\" is not a valid value for focus attribute"
msgid "\"%s\" is not a valid accelerator\n" msgid "\"%s\" is not a valid accelerator\n"
msgstr "%s is geen geldige sneltoets\n" msgstr "%s is geen geldige sneltoets\n"
@@ -322,7 +318,7 @@ msgstr ""
"Kon geen thema vinden! Zorg ervoor dat %s bestaat en de gebruikelijke " "Kon geen thema vinden! Zorg ervoor dat %s bestaat en de gebruikelijke "
"thema's bevat.\n" "thema's bevat.\n"
#: ../src/core/monitor.c:711 #: ../src/core/monitor.c:696
msgid "Built-in display" msgid "Built-in display"
msgstr "Ingebouwd beeldscherm" msgstr "Ingebouwd beeldscherm"
@@ -330,9 +326,8 @@ msgstr "Ingebouwd beeldscherm"
#. the vendor), it's Unknown followed by a size in inches, #. the vendor), it's Unknown followed by a size in inches,
#. like 'Unknown 15"' #. like 'Unknown 15"'
#. #.
#: ../src/core/monitor.c:739 #: ../src/core/monitor.c:724
#, c-format #, c-format
#| msgid "Unknown element %s"
msgid "Unknown %s" msgid "Unknown %s"
msgstr "Onbekend %s" msgstr "Onbekend %s"
@@ -394,12 +389,12 @@ msgstr ""
msgid "Workspace %d" msgid "Workspace %d"
msgstr "Werkblad %d" msgstr "Werkblad %d"
#: ../src/core/screen.c:534 #: ../src/core/screen.c:540
#, c-format #, c-format
msgid "Screen %d on display '%s' is invalid\n" msgid "Screen %d on display '%s' is invalid\n"
msgstr "Scherm %d op display '%s' is ongeldig\n" msgstr "Scherm %d op display '%s' is ongeldig\n"
#: ../src/core/screen.c:550 #: ../src/core/screen.c:556
#, c-format #, c-format
msgid "" msgid ""
"Screen %d on display \"%s\" already has a window manager; try using the --" "Screen %d on display \"%s\" already has a window manager; try using the --"
@@ -408,19 +403,19 @@ msgstr ""
"Scherm %d op display %s heeft al een window manager; probeer de optie: --" "Scherm %d op display %s heeft al een window manager; probeer de optie: --"
"replace te gebruiken om de huidige window manager te vervangen.\n" "replace te gebruiken om de huidige window manager te vervangen.\n"
#: ../src/core/screen.c:577 #: ../src/core/screen.c:583
#, c-format #, c-format
msgid "" msgid ""
"Could not acquire window manager selection on screen %d display \"%s\"\n" "Could not acquire window manager selection on screen %d display \"%s\"\n"
msgstr "" msgstr ""
"Kon window manager-selectie niet verkrijgen op scherm %d display %s\n" "Kon window manager-selectie niet verkrijgen op scherm %d display %s\n"
#: ../src/core/screen.c:655 #: ../src/core/screen.c:661
#, c-format #, c-format
msgid "Screen %d on display \"%s\" already has a window manager\n" msgid "Screen %d on display \"%s\" already has a window manager\n"
msgstr "Scherm %d op display %s heeft al een window manager\n" msgstr "Scherm %d op display %s heeft al een window manager\n"
#: ../src/core/screen.c:846 #: ../src/core/screen.c:853
#, c-format #, c-format
msgid "Could not release screen %d on display \"%s\"\n" msgid "Could not release screen %d on display \"%s\"\n"
msgstr "Kon scherm %d op display %s niet vrijmaken\n" msgstr "Kon scherm %d op display %s niet vrijmaken\n"
@@ -516,7 +511,7 @@ msgid "Window manager error: "
msgstr "Fout van vensterbeheer:" msgstr "Fout van vensterbeheer:"
#. first time through #. first time through
#: ../src/core/window.c:7533 #: ../src/core/window.c:7510
#, c-format #, c-format
msgid "" msgid ""
"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER "
@@ -532,7 +527,7 @@ msgstr ""
#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain #. * MWM but not WM_NORMAL_HINTS are basically broken. We complain
#. * about these apps but make them work. #. * about these apps but make them work.
#. #.
#: ../src/core/window.c:8257 #: ../src/core/window.c:8340
#, c-format #, c-format
msgid "" msgid ""
"Window %s sets an MWM hint indicating it isn't resizable, but sets min size " "Window %s sets an MWM hint indicating it isn't resizable, but sets min size "
@@ -650,6 +645,9 @@ msgid ""
"static number of workspaces (determined by the num-workspaces key in org." "static number of workspaces (determined by the num-workspaces key in org."
"gnome.desktop.wm.preferences)." "gnome.desktop.wm.preferences)."
msgstr "" msgstr ""
"Bepaalt of werkbladen dynamisch worden beheerd of dat er een statisch aantal "
"werkbladen is (gegeven door de sleutel num-workspaces in org.gnome.desktop."
"wm.preferences)."
#: ../src/org.gnome.mutter.gschema.xml.in.h:9 #: ../src/org.gnome.mutter.gschema.xml.in.h:9
msgid "Workspaces only on primary" msgid "Workspaces only on primary"
@@ -672,10 +670,12 @@ msgid ""
"Determines whether the use of popup and highlight frame should be disabled " "Determines whether the use of popup and highlight frame should be disabled "
"for window cycling." "for window cycling."
msgstr "" msgstr ""
"Bepaalt of het gebruik van pop-up en markering van het kader uitgeschakeld "
"wordt voor het vensterbladeren."
#: ../src/org.gnome.mutter.gschema.xml.in.h:13 #: ../src/org.gnome.mutter.gschema.xml.in.h:13
msgid "Delay focus changes until the pointer stops moving" msgid "Delay focus changes until the pointer stops moving"
msgstr "" msgstr "Aandacht vertragen totdat de muispijl stopt met bewegen"
#: ../src/org.gnome.mutter.gschema.xml.in.h:14 #: ../src/org.gnome.mutter.gschema.xml.in.h:14
msgid "" msgid ""
@@ -683,16 +683,22 @@ msgid ""
"the focus will not be changed immediately when entering a window, but only " "the focus will not be changed immediately when entering a window, but only "
"after the pointer stops moving." "after the pointer stops moving."
msgstr "" msgstr ""
"Indien op true ingesteld en de aandachtsmodus is ofwel sloppy of "
"mouse, dan zal de aandacht niet direct veranderd worden bij het binnengaan "
"van een venster, maar slechts wanneer de muispijl stopt met bewegen."
#: ../src/org.gnome.mutter.gschema.xml.in.h:15 #: ../src/org.gnome.mutter.gschema.xml.in.h:15
msgid "Draggable border width" msgid "Draggable border width"
msgstr "" msgstr "Sleepbare randbreedte"
#: ../src/org.gnome.mutter.gschema.xml.in.h:16 #: ../src/org.gnome.mutter.gschema.xml.in.h:16
msgid "" msgid ""
"The amount of total draggable borders. If the theme's visible borders are " "The amount of total draggable borders. If the theme's visible borders are "
"not enough, invisible borders will be added to meet this value." "not enough, invisible borders will be added to meet this value."
msgstr "" msgstr ""
"Het totaal aantal sleepbare randen. Als de zichtbare randen in het thema "
"onvoldoende zijn, worden onzichtbare randen toegevoegd om deze waarde te "
"bereiken."
#: ../src/org.gnome.mutter.gschema.xml.in.h:17 #: ../src/org.gnome.mutter.gschema.xml.in.h:17
msgid "Auto maximize nearly monitor sized windows" msgid "Auto maximize nearly monitor sized windows"
@@ -957,13 +963,13 @@ msgid "Gradients should have at least two colors"
msgstr "Kleurverloop moet tenminste twee kleuren hebben" msgstr "Kleurverloop moet tenminste twee kleuren hebben"
#: ../src/ui/theme.c:1203 #: ../src/ui/theme.c:1203
#, fuzzy, c-format #, c-format
msgid "" msgid ""
"GTK custom color specification must have color name and fallback in " "GTK custom color specification must have color name and fallback in "
"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" "parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\""
msgstr "" msgstr ""
"GTK-kleurspecificatie moet een sluithaakje hebben na de status, dus: gtk: " "Aangepaste GTK-kleurspecificatie moet een kleurnaam en terugvaloptie hebben "
"fg[NORMAL] waarbij NORMAL de stutus is; kon %s niet verwerken" "tussen haakjes, dus: gtk:custom(foo,bar); kon %s niet verwerken"
#: ../src/ui/theme.c:1219 #: ../src/ui/theme.c:1219
#, c-format #, c-format
@@ -971,15 +977,17 @@ msgid ""
"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" "Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-"
"_ are valid" "_ are valid"
msgstr "" msgstr ""
"Ongeldig teken %c in color_name-parameter van gtk:custom, alleen A-Za-z0-9-"
"_ zijn geldig"
#: ../src/ui/theme.c:1233 #: ../src/ui/theme.c:1233
#, fuzzy, c-format #, c-format
msgid "" msgid ""
"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " "Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not "
"fit the format" "fit the format"
msgstr "" msgstr ""
"Schaduwformaat is schaduw/basiskleur/factor, %s voldoet niet aan dit " "Gtk:custom-formaat is gtk:custom(color_name,fallback), %s voldoet niet "
"formaat" "aan dit formaat"
#: ../src/ui/theme.c:1278 #: ../src/ui/theme.c:1278
#, c-format #, c-format
@@ -987,8 +995,8 @@ msgid ""
"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " "GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] "
"where NORMAL is the state; could not parse \"%s\"" "where NORMAL is the state; could not parse \"%s\""
msgstr "" msgstr ""
"GTK-kleurspecificatie moet de toestand in rechte haken hebben, bijv. gtk:fg" "GTK-kleurspecificatie moet de toestand in rechte haken hebben, bijv. gtk:"
"[NORMAL] waarbij NORMAL de toestand is; kon %s niet verwerken" "fg[NORMAL] waarbij NORMAL de toestand is; kon %s niet verwerken"
#: ../src/ui/theme.c:1292 #: ../src/ui/theme.c:1292
#, c-format #, c-format
@@ -996,8 +1004,8 @@ msgid ""
"GTK color specification must have a close bracket after the state, e.g. gtk:" "GTK color specification must have a close bracket after the state, e.g. gtk:"
"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" "fg[NORMAL] where NORMAL is the state; could not parse \"%s\""
msgstr "" msgstr ""
"GTK-kleurspecificatie moet een sluithaakje hebben na de status, dus: gtk: fg" "GTK-kleurspecificatie moet een sluithaakje hebben na de status, dus: gtk: "
"[NORMAL] waarbij NORMAL de stutus is; kon %s niet verwerken" "fg[NORMAL] waarbij NORMAL de stutus is; kon %s niet verwerken"
#: ../src/ui/theme.c:1303 #: ../src/ui/theme.c:1303
#, c-format #, c-format
@@ -1222,59 +1230,59 @@ msgstr "Geen %s-attribuut op element <%s>"
msgid "Line %d character %d: %s" msgid "Line %d character %d: %s"
msgstr "Regel %d teken %d: %s" msgstr "Regel %d teken %d: %s"
#: ../src/ui/theme-parser.c:479 #: ../src/ui/theme-parser.c:483
#, c-format #, c-format
msgid "Attribute \"%s\" repeated twice on the same <%s> element" msgid "Attribute \"%s\" repeated twice on the same <%s> element"
msgstr "Attribuut %s twee keer herhaald op hetzelfde <%s>-element" msgstr "Attribuut %s twee keer herhaald op hetzelfde <%s>-element"
#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 #: ../src/ui/theme-parser.c:507 ../src/ui/theme-parser.c:556
#, c-format #, c-format
msgid "Attribute \"%s\" is invalid on <%s> element in this context" msgid "Attribute \"%s\" is invalid on <%s> element in this context"
msgstr "Attribuut %s is ongeldig op een <%s>-element in deze context" msgstr "Attribuut %s is ongeldig op een <%s>-element in deze context"
#: ../src/ui/theme-parser.c:594 #: ../src/ui/theme-parser.c:598
#, c-format #, c-format
msgid "Could not parse \"%s\" as an integer" msgid "Could not parse \"%s\" as an integer"
msgstr "Kon %s niet verwerken als geheel getal" msgstr "Kon %s niet verwerken als geheel getal"
#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 #: ../src/ui/theme-parser.c:607 ../src/ui/theme-parser.c:662
#, c-format #, c-format
msgid "Did not understand trailing characters \"%s\" in string \"%s\"" msgid "Did not understand trailing characters \"%s\" in string \"%s\""
msgstr "Niet begrepen: de laatste tekens %s in %s" msgstr "Niet begrepen: de laatste tekens %s in %s"
#: ../src/ui/theme-parser.c:613 #: ../src/ui/theme-parser.c:617
#, c-format #, c-format
msgid "Integer %ld must be positive" msgid "Integer %ld must be positive"
msgstr "Geheel getal %ld moet positief zijn" msgstr "Geheel getal %ld moet positief zijn"
#: ../src/ui/theme-parser.c:621 #: ../src/ui/theme-parser.c:625
#, c-format #, c-format
msgid "Integer %ld is too large, current max is %d" msgid "Integer %ld is too large, current max is %d"
msgstr "Geheel getal %ld is te groot, huidige maximum is %d" msgstr "Geheel getal %ld is te groot, huidige maximum is %d"
#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 #: ../src/ui/theme-parser.c:653 ../src/ui/theme-parser.c:769
#, c-format #, c-format
msgid "Could not parse \"%s\" as a floating point number" msgid "Could not parse \"%s\" as a floating point number"
msgstr "Kon %s niet als 'floating-point'-getal verwerken" msgstr "Kon %s niet als 'floating-point'-getal verwerken"
#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 #: ../src/ui/theme-parser.c:684 ../src/ui/theme-parser.c:712
#, c-format #, c-format
msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" msgid "Boolean values must be \"true\" or \"false\" not \"%s\""
msgstr "Boolese waarde moet true of false zijn, niet %s" msgstr "Boolese waarde moet true of false zijn, niet %s"
#: ../src/ui/theme-parser.c:735 #: ../src/ui/theme-parser.c:739
#, c-format #, c-format
msgid "Angle must be between 0.0 and 360.0, was %g\n" msgid "Angle must be between 0.0 and 360.0, was %g\n"
msgstr "Hoek moet liggen tussen 0.0 en 360.0, maar was %g\n" msgstr "Hoek moet liggen tussen 0.0 en 360.0, maar was %g\n"
#: ../src/ui/theme-parser.c:798 #: ../src/ui/theme-parser.c:802
#, c-format #, c-format
msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n"
msgstr "" msgstr ""
"Alpha moet liggen tussen 0.0 (onzichtbaar) en 1.0 (volledig ondoorzichtig), " "Alpha moet liggen tussen 0.0 (onzichtbaar) en 1.0 (volledig ondoorzichtig), "
"maar was %g\n" "maar was %g\n"
#: ../src/ui/theme-parser.c:863 #: ../src/ui/theme-parser.c:867
#, c-format #, c-format
msgid "" msgid ""
"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium,"
@@ -1283,60 +1291,60 @@ msgstr ""
"Ongeldige titel-schaal %s (u kunt kiezen uit: xx-small, x-small, small, " "Ongeldige titel-schaal %s (u kunt kiezen uit: xx-small, x-small, small, "
"medium, large, x-large, xx-large)\n" "medium, large, x-large, xx-large)\n"
#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 #: ../src/ui/theme-parser.c:1023 ../src/ui/theme-parser.c:1086
#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 #: ../src/ui/theme-parser.c:1120 ../src/ui/theme-parser.c:1223
#, c-format #, c-format
msgid "<%s> name \"%s\" used a second time" msgid "<%s> name \"%s\" used a second time"
msgstr "<%s>-naam %s een tweede keer gebruikt" msgstr "<%s>-naam %s een tweede keer gebruikt"
#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 #: ../src/ui/theme-parser.c:1035 ../src/ui/theme-parser.c:1132
#: ../src/ui/theme-parser.c:1231 #: ../src/ui/theme-parser.c:1235
#, c-format #, c-format
msgid "<%s> parent \"%s\" has not been defined" msgid "<%s> parent \"%s\" has not been defined"
msgstr "<%s>-ouder %s is niet gedefinieerd" msgstr "<%s>-ouder %s is niet gedefinieerd"
#: ../src/ui/theme-parser.c:1141 #: ../src/ui/theme-parser.c:1145
#, c-format #, c-format
msgid "<%s> geometry \"%s\" has not been defined" msgid "<%s> geometry \"%s\" has not been defined"
msgstr "<%s>-afmetingen %s is niet gedefinieerd" msgstr "<%s>-afmetingen %s is niet gedefinieerd"
#: ../src/ui/theme-parser.c:1154 #: ../src/ui/theme-parser.c:1158
#, c-format #, c-format
msgid "<%s> must specify either a geometry or a parent that has a geometry" msgid "<%s> must specify either a geometry or a parent that has a geometry"
msgstr "<%s> moet ofwel afmetingen specificeren, of een ouder met afmetingen" msgstr "<%s> moet ofwel afmetingen specificeren, of een ouder met afmetingen"
#: ../src/ui/theme-parser.c:1196 #: ../src/ui/theme-parser.c:1200
msgid "You must specify a background for an alpha value to be meaningful" msgid "You must specify a background for an alpha value to be meaningful"
msgstr "" msgstr ""
"U dient een achtergrond te specificeren voordat een alpha-waarde betekenis " "U dient een achtergrond te specificeren voordat een alpha-waarde betekenis "
"heeft" "heeft"
#: ../src/ui/theme-parser.c:1264 #: ../src/ui/theme-parser.c:1268
#, c-format #, c-format
msgid "Unknown type \"%s\" on <%s> element" msgid "Unknown type \"%s\" on <%s> element"
msgstr "Onbekend type %s op <%s>-element" msgstr "Onbekend type %s op <%s>-element"
#: ../src/ui/theme-parser.c:1275 #: ../src/ui/theme-parser.c:1279
#, c-format #, c-format
msgid "Unknown style_set \"%s\" on <%s> element" msgid "Unknown style_set \"%s\" on <%s> element"
msgstr "Onbekende style_set %s op <%s>-element" msgstr "Onbekende style_set %s op <%s>-element"
#: ../src/ui/theme-parser.c:1283 #: ../src/ui/theme-parser.c:1287
#, c-format #, c-format
msgid "Window type \"%s\" has already been assigned a style set" msgid "Window type \"%s\" has already been assigned a style set"
msgstr "Venstertype %s heeft reeds een stijlset toegewezen gekregen" msgstr "Venstertype %s heeft reeds een stijlset toegewezen gekregen"
#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 #: ../src/ui/theme-parser.c:1317 ../src/ui/theme-parser.c:1381
#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 #: ../src/ui/theme-parser.c:1607 ../src/ui/theme-parser.c:2842
#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 #: ../src/ui/theme-parser.c:2888 ../src/ui/theme-parser.c:3038
#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 #: ../src/ui/theme-parser.c:3274 ../src/ui/theme-parser.c:3312
#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 #: ../src/ui/theme-parser.c:3350 ../src/ui/theme-parser.c:3388
#, c-format #, c-format
msgid "Element <%s> is not allowed below <%s>" msgid "Element <%s> is not allowed below <%s>"
msgstr "Element <%s> is niet toegestaan onder <%s>" msgstr "Element <%s> is niet toegestaan onder <%s>"
#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 #: ../src/ui/theme-parser.c:1431 ../src/ui/theme-parser.c:1445
#: ../src/ui/theme-parser.c:1486 #: ../src/ui/theme-parser.c:1490
msgid "" msgid ""
"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" "
"for buttons" "for buttons"
@@ -1344,123 +1352,123 @@ msgstr ""
"Kan niet tegelijk button_width/button_height en aspect_ratio voor " "Kan niet tegelijk button_width/button_height en aspect_ratio voor "
"knoppen opgeven." "knoppen opgeven."
#: ../src/ui/theme-parser.c:1450 #: ../src/ui/theme-parser.c:1454
#, c-format #, c-format
msgid "Distance \"%s\" is unknown" msgid "Distance \"%s\" is unknown"
msgstr "Afstand %s is onbekend" msgstr "Afstand %s is onbekend"
#: ../src/ui/theme-parser.c:1495 #: ../src/ui/theme-parser.c:1499
#, c-format #, c-format
msgid "Aspect ratio \"%s\" is unknown" msgid "Aspect ratio \"%s\" is unknown"
msgstr "Verhouding %s is onbekend" msgstr "Verhouding %s is onbekend"
#: ../src/ui/theme-parser.c:1557 #: ../src/ui/theme-parser.c:1561
#, c-format #, c-format
msgid "Border \"%s\" is unknown" msgid "Border \"%s\" is unknown"
msgstr "Rand %s is onbekend" msgstr "Rand %s is onbekend"
#: ../src/ui/theme-parser.c:1868 #: ../src/ui/theme-parser.c:1872
#, c-format #, c-format
msgid "No \"start_angle\" or \"from\" attribute on element <%s>" msgid "No \"start_angle\" or \"from\" attribute on element <%s>"
msgstr "Geen start_angle- of from-attribuut op element <%s>" msgstr "Geen start_angle- of from-attribuut op element <%s>"
#: ../src/ui/theme-parser.c:1875 #: ../src/ui/theme-parser.c:1879
#, c-format #, c-format
msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" msgid "No \"extent_angle\" or \"to\" attribute on element <%s>"
msgstr "Geen extent_angle- of to-attribuut op element <%s>" msgstr "Geen extent_angle- of to-attribuut op element <%s>"
#: ../src/ui/theme-parser.c:2115 #: ../src/ui/theme-parser.c:2119
#, c-format #, c-format
msgid "Did not understand value \"%s\" for type of gradient" msgid "Did not understand value \"%s\" for type of gradient"
msgstr "Niet begrepen: de waarde %s voor type kleurverloop" msgstr "Niet begrepen: de waarde %s voor type kleurverloop"
#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 #: ../src/ui/theme-parser.c:2197 ../src/ui/theme-parser.c:2572
#, c-format #, c-format
msgid "Did not understand fill type \"%s\" for <%s> element" msgid "Did not understand fill type \"%s\" for <%s> element"
msgstr "Niet begrepen: vul-type %s voor <%s>-element" msgstr "Niet begrepen: vul-type %s voor <%s>-element"
#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 #: ../src/ui/theme-parser.c:2364 ../src/ui/theme-parser.c:2447
#: ../src/ui/theme-parser.c:2506 #: ../src/ui/theme-parser.c:2510
#, c-format #, c-format
msgid "Did not understand state \"%s\" for <%s> element" msgid "Did not understand state \"%s\" for <%s> element"
msgstr "Niet begrepen: status %s voor <%s>-element" msgstr "Niet begrepen: status %s voor <%s>-element"
#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 #: ../src/ui/theme-parser.c:2374 ../src/ui/theme-parser.c:2457
#, c-format #, c-format
msgid "Did not understand shadow \"%s\" for <%s> element" msgid "Did not understand shadow \"%s\" for <%s> element"
msgstr "Niet begrepen: schaduw %s voor <%s>-element" msgstr "Niet begrepen: schaduw %s voor <%s>-element"
#: ../src/ui/theme-parser.c:2380 #: ../src/ui/theme-parser.c:2384
#, c-format #, c-format
msgid "Did not understand arrow \"%s\" for <%s> element" msgid "Did not understand arrow \"%s\" for <%s> element"
msgstr "Niet begrepen: pijl %s voor <%s>-element" msgstr "Niet begrepen: pijl %s voor <%s>-element"
#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 #: ../src/ui/theme-parser.c:2698 ../src/ui/theme-parser.c:2794
#, c-format #, c-format
msgid "No <draw_ops> called \"%s\" has been defined" msgid "No <draw_ops> called \"%s\" has been defined"
msgstr "Er zijn geen <draw_ops> genaamd %s gedefinieerd" msgstr "Er zijn geen <draw_ops> genaamd %s gedefinieerd"
#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 #: ../src/ui/theme-parser.c:2710 ../src/ui/theme-parser.c:2806
#, c-format #, c-format
msgid "Including draw_ops \"%s\" here would create a circular reference" msgid "Including draw_ops \"%s\" here would create a circular reference"
msgstr "Hier draw_ops %s meenemen zou een circulaire verwijzing creëren" msgstr "Hier draw_ops %s meenemen zou een circulaire verwijzing creëren"
#: ../src/ui/theme-parser.c:2917 #: ../src/ui/theme-parser.c:2921
#, c-format #, c-format
msgid "Unknown position \"%s\" for frame piece" msgid "Unknown position \"%s\" for frame piece"
msgstr "Onbekende positie %s voor kader-onderdeel" msgstr "Onbekende positie %s voor kader-onderdeel"
#: ../src/ui/theme-parser.c:2925 #: ../src/ui/theme-parser.c:2929
#, c-format #, c-format
msgid "Frame style already has a piece at position %s" msgid "Frame style already has a piece at position %s"
msgstr "Kader-stijl heeft al een onderdeel op positie %s" msgstr "Kader-stijl heeft al een onderdeel op positie %s"
#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 #: ../src/ui/theme-parser.c:2946 ../src/ui/theme-parser.c:3023
#, c-format #, c-format
msgid "No <draw_ops> with the name \"%s\" has been defined" msgid "No <draw_ops> with the name \"%s\" has been defined"
msgstr "Er zijn geen <draw_ops> met naam %s gedefinieerd" msgstr "Er zijn geen <draw_ops> met naam %s gedefinieerd"
#: ../src/ui/theme-parser.c:2972 #: ../src/ui/theme-parser.c:2976
#, c-format #, c-format
msgid "Unknown function \"%s\" for button" msgid "Unknown function \"%s\" for button"
msgstr "Onbekende functie %s voor knop" msgstr "Onbekende functie %s voor knop"
#: ../src/ui/theme-parser.c:2982 #: ../src/ui/theme-parser.c:2986
#, c-format #, c-format
msgid "Button function \"%s\" does not exist in this version (%d, need %d)" msgid "Button function \"%s\" does not exist in this version (%d, need %d)"
msgstr "Knopfunctie %s bestaat niet in deze versie (%d, %d benodigd)" msgstr "Knopfunctie %s bestaat niet in deze versie (%d, %d benodigd)"
#: ../src/ui/theme-parser.c:2994 #: ../src/ui/theme-parser.c:2998
#, c-format #, c-format
msgid "Unknown state \"%s\" for button" msgid "Unknown state \"%s\" for button"
msgstr "Onbekende status %s voor knop" msgstr "Onbekende status %s voor knop"
#: ../src/ui/theme-parser.c:3002 #: ../src/ui/theme-parser.c:3006
#, c-format #, c-format
msgid "Frame style already has a button for function %s state %s" msgid "Frame style already has a button for function %s state %s"
msgstr "Kader-stijl heeft reeds een knop voor functie %s status %s" msgstr "Kader-stijl heeft reeds een knop voor functie %s status %s"
#: ../src/ui/theme-parser.c:3073 #: ../src/ui/theme-parser.c:3077
#, c-format #, c-format
msgid "\"%s\" is not a valid value for focus attribute" msgid "\"%s\" is not a valid value for focus attribute"
msgstr "%s is geen geldige waarde voor focus-attribuut" msgstr "%s is geen geldige waarde voor focus-attribuut"
#: ../src/ui/theme-parser.c:3082 #: ../src/ui/theme-parser.c:3086
#, c-format #, c-format
msgid "\"%s\" is not a valid value for state attribute" msgid "\"%s\" is not a valid value for state attribute"
msgstr "%s is geen geldige waarde voor state-attribuut" msgstr "%s is geen geldige waarde voor state-attribuut"
#: ../src/ui/theme-parser.c:3092 #: ../src/ui/theme-parser.c:3096
#, c-format #, c-format
msgid "A style called \"%s\" has not been defined" msgid "A style called \"%s\" has not been defined"
msgstr "Een stijl genaamd %s is niet gedefinieerd" msgstr "Een stijl genaamd %s is niet gedefinieerd"
#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 #: ../src/ui/theme-parser.c:3117 ../src/ui/theme-parser.c:3140
#, c-format #, c-format
msgid "\"%s\" is not a valid value for resize attribute" msgid "\"%s\" is not a valid value for resize attribute"
msgstr "%s is geen geldige waarde voor resize-attribuut" msgstr "%s is geen geldige waarde voor resize-attribuut"
#: ../src/ui/theme-parser.c:3147 #: ../src/ui/theme-parser.c:3151
#, c-format #, c-format
msgid "" msgid ""
"Should not have \"resize\" attribute on <%s> element for maximized/shaded " "Should not have \"resize\" attribute on <%s> element for maximized/shaded "
@@ -1469,7 +1477,7 @@ msgstr ""
"Behoort geen resize-attribuut te hebben op <%s>-element voor " "Behoort geen resize-attribuut te hebben op <%s>-element voor "
"gemaximaliseerde/opgerolde toestanden" "gemaximaliseerde/opgerolde toestanden"
#: ../src/ui/theme-parser.c:3161 #: ../src/ui/theme-parser.c:3165
#, c-format #, c-format
msgid "" msgid ""
"Should not have \"resize\" attribute on <%s> element for maximized states" "Should not have \"resize\" attribute on <%s> element for maximized states"
@@ -1477,20 +1485,20 @@ msgstr ""
"Behoort geen resize-attribuut te hebben op <%s>-element voor " "Behoort geen resize-attribuut te hebben op <%s>-element voor "
"gemaximaliseerde toestand" "gemaximaliseerde toestand"
#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 #: ../src/ui/theme-parser.c:3179 ../src/ui/theme-parser.c:3223
#, c-format #, c-format
msgid "Style has already been specified for state %s resize %s focus %s" msgid "Style has already been specified for state %s resize %s focus %s"
msgstr "" msgstr ""
"Stijl is reeds gespecificeerd voor status %s grootte aanpassen %s aandacht %s" "Stijl is reeds gespecificeerd voor status %s grootte aanpassen %s aandacht %s"
#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 #: ../src/ui/theme-parser.c:3190 ../src/ui/theme-parser.c:3201
#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 #: ../src/ui/theme-parser.c:3212 ../src/ui/theme-parser.c:3234
#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 #: ../src/ui/theme-parser.c:3245 ../src/ui/theme-parser.c:3256
#, c-format #, c-format
msgid "Style has already been specified for state %s focus %s" msgid "Style has already been specified for state %s focus %s"
msgstr "Stijl is reeds gespecificeerd voor status %s aandacht %s" msgstr "Stijl is reeds gespecificeerd voor status %s aandacht %s"
#: ../src/ui/theme-parser.c:3294 #: ../src/ui/theme-parser.c:3295
msgid "" msgid ""
"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " "Can't have a two draw_ops for a <piece> element (theme specified a draw_ops "
"attribute and also a <draw_ops> element, or specified two elements)" "attribute and also a <draw_ops> element, or specified two elements)"
@@ -1499,7 +1507,7 @@ msgstr ""
"specificeerde een draw_ops-attribuut en tevens een <draw_ops>-element, of " "specificeerde een draw_ops-attribuut en tevens een <draw_ops>-element, of "
"specificeerde twee elementen)" "specificeerde twee elementen)"
#: ../src/ui/theme-parser.c:3332 #: ../src/ui/theme-parser.c:3333
msgid "" msgid ""
"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " "Can't have a two draw_ops for a <button> element (theme specified a draw_ops "
"attribute and also a <draw_ops> element, or specified two elements)" "attribute and also a <draw_ops> element, or specified two elements)"
@@ -1508,7 +1516,7 @@ msgstr ""
"specificeerde een draw_ops-attribuut en tevens een <draw_ops>-element, of " "specificeerde een draw_ops-attribuut en tevens een <draw_ops>-element, of "
"specificeerde twee elementen)" "specificeerde twee elementen)"
#: ../src/ui/theme-parser.c:3370 #: ../src/ui/theme-parser.c:3371
msgid "" msgid ""
"Can't have a two draw_ops for a <menu_icon> element (theme specified a " "Can't have a two draw_ops for a <menu_icon> element (theme specified a "
"draw_ops attribute and also a <draw_ops> element, or specified two elements)" "draw_ops attribute and also a <draw_ops> element, or specified two elements)"
@@ -1517,12 +1525,12 @@ msgstr ""
"specificeerde een draw_ops-attribuut en tevens een <draw_ops>-element, of " "specificeerde een draw_ops-attribuut en tevens een <draw_ops>-element, of "
"specificeerde twee elementen)" "specificeerde twee elementen)"
#: ../src/ui/theme-parser.c:3434 #: ../src/ui/theme-parser.c:3435
#, c-format #, c-format
msgid "Bad version specification '%s'" msgid "Bad version specification '%s'"
msgstr "Foutieve opgave van versie: %s" msgstr "Foutieve opgave van versie: %s"
#: ../src/ui/theme-parser.c:3507 #: ../src/ui/theme-parser.c:3508
msgid "" msgid ""
"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" "\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-"
"theme-2.xml" "theme-2.xml"
@@ -1530,18 +1538,18 @@ msgstr ""
"Het version-attribuut kan niet gebruikt worden in metacity-theme-1.xml of " "Het version-attribuut kan niet gebruikt worden in metacity-theme-1.xml of "
"metacity-theme-2.xml." "metacity-theme-2.xml."
#: ../src/ui/theme-parser.c:3530 #: ../src/ui/theme-parser.c:3531
#, c-format #, c-format
msgid "Theme requires version %s but latest supported theme version is %d.%d" msgid "Theme requires version %s but latest supported theme version is %d.%d"
msgstr "" msgstr ""
"Het thema vereist versie %s, maar de recentste ondersteunde versie is %d.%d" "Het thema vereist versie %s, maar de recentste ondersteunde versie is %d.%d"
#: ../src/ui/theme-parser.c:3562 #: ../src/ui/theme-parser.c:3563
#, c-format #, c-format
msgid "Outermost element in theme must be <metacity_theme> not <%s>" msgid "Outermost element in theme must be <metacity_theme> not <%s>"
msgstr "Buitenste element in thema moet zijn: <metacity_theme>, niet <%s>" msgstr "Buitenste element in thema moet zijn: <metacity_theme>, niet <%s>"
#: ../src/ui/theme-parser.c:3582 #: ../src/ui/theme-parser.c:3583
#, c-format #, c-format
msgid "" msgid ""
"Element <%s> is not allowed inside a name/author/date/description element" "Element <%s> is not allowed inside a name/author/date/description element"
@@ -1549,12 +1557,12 @@ msgstr ""
"Element <%s> is niet toegestaan binnen een naam/auteur/datum/beschrijving " "Element <%s> is niet toegestaan binnen een naam/auteur/datum/beschrijving "
"element" "element"
#: ../src/ui/theme-parser.c:3587 #: ../src/ui/theme-parser.c:3588
#, c-format #, c-format
msgid "Element <%s> is not allowed inside a <constant> element" msgid "Element <%s> is not allowed inside a <constant> element"
msgstr "Element <%s> is niet toegestaan binnen een <constant>-element" msgstr "Element <%s> is niet toegestaan binnen een <constant>-element"
#: ../src/ui/theme-parser.c:3599 #: ../src/ui/theme-parser.c:3600
#, c-format #, c-format
msgid "" msgid ""
"Element <%s> is not allowed inside a distance/border/aspect_ratio element" "Element <%s> is not allowed inside a distance/border/aspect_ratio element"
@@ -1562,38 +1570,38 @@ msgstr ""
"Element <%s> is niet toegestaan binnen de elementen distance/border/" "Element <%s> is niet toegestaan binnen de elementen distance/border/"
"aspect_ratio" "aspect_ratio"
#: ../src/ui/theme-parser.c:3621 #: ../src/ui/theme-parser.c:3622
#, c-format #, c-format
msgid "Element <%s> is not allowed inside a draw operation element" msgid "Element <%s> is not allowed inside a draw operation element"
msgstr "Element <%s> is niet toegestaan binnen een draw operation-element" msgstr "Element <%s> is niet toegestaan binnen een draw operation-element"
#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 #: ../src/ui/theme-parser.c:3632 ../src/ui/theme-parser.c:3662
#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 #: ../src/ui/theme-parser.c:3667 ../src/ui/theme-parser.c:3672
#, c-format #, c-format
msgid "Element <%s> is not allowed inside a <%s> element" msgid "Element <%s> is not allowed inside a <%s> element"
msgstr "Element <%s> is niet toegestaan binnen een <%s>-element" msgstr "Element <%s> is niet toegestaan binnen een <%s>-element"
#: ../src/ui/theme-parser.c:3899 #: ../src/ui/theme-parser.c:3900
msgid "No draw_ops provided for frame piece" msgid "No draw_ops provided for frame piece"
msgstr "Geen draw_ops gegeven voor kader-onderdeel" msgstr "Geen draw_ops gegeven voor kader-onderdeel"
#: ../src/ui/theme-parser.c:3914 #: ../src/ui/theme-parser.c:3915
msgid "No draw_ops provided for button" msgid "No draw_ops provided for button"
msgstr "Geen draw_ops gegeven voor knop" msgstr "Geen draw_ops gegeven voor knop"
#: ../src/ui/theme-parser.c:3968 #: ../src/ui/theme-parser.c:3969
#, c-format #, c-format
msgid "No text is allowed inside element <%s>" msgid "No text is allowed inside element <%s>"
msgstr "Geen tekst toegestaan binnen element <%s>" msgstr "Geen tekst toegestaan binnen element <%s>"
#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 #: ../src/ui/theme-parser.c:4027 ../src/ui/theme-parser.c:4039
#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 #: ../src/ui/theme-parser.c:4051 ../src/ui/theme-parser.c:4063
#: ../src/ui/theme-parser.c:4074 #: ../src/ui/theme-parser.c:4075
#, c-format #, c-format
msgid "<%s> specified twice for this theme" msgid "<%s> specified twice for this theme"
msgstr "<%s> twee keer gegeven voor dit thema" msgstr "<%s> twee keer gegeven voor dit thema"
#: ../src/ui/theme-parser.c:4336 #: ../src/ui/theme-parser.c:4337
#, c-format #, c-format
msgid "Failed to find a valid file for theme %s\n" msgid "Failed to find a valid file for theme %s\n"
msgstr "Geen geldig bestand gevonden voor thema %s\n" msgstr "Geen geldig bestand gevonden voor thema %s\n"

File diff suppressed because it is too large Load Diff

View File

@@ -55,7 +55,8 @@ libmutter_la_SOURCES = \
compositor/meta-background-actor.c \ compositor/meta-background-actor.c \
compositor/meta-background-actor-private.h \ compositor/meta-background-actor-private.h \
compositor/meta-background-group.c \ compositor/meta-background-group.c \
compositor/meta-background-group-private.h \ compositor/meta-cullable.c \
compositor/meta-cullable.h \
compositor/meta-module.c \ compositor/meta-module.c \
compositor/meta-module.h \ compositor/meta-module.h \
compositor/meta-plugin.c \ compositor/meta-plugin.c \
@@ -168,7 +169,9 @@ libmutter_la_SOURCES = \
ui/theme.c \ ui/theme.c \
meta/theme.h \ meta/theme.h \
ui/theme-private.h \ ui/theme-private.h \
ui/ui.c \ ui/ui.c
nodist_libmutter_la_SOURCES = \
$(mutter_built_sources) $(mutter_built_sources)
libmutter_la_LDFLAGS = -no-undefined libmutter_la_LDFLAGS = -no-undefined
@@ -249,7 +252,7 @@ Meta-$(api_version).gir: libmutter.la
@META_GIR@_FILES = \ @META_GIR@_FILES = \
mutter-enum-types.h \ mutter-enum-types.h \
$(libmutterinclude_base_headers) \ $(libmutterinclude_base_headers) \
$(filter %.c,$(libmutter_la_SOURCES)) $(filter %.c,$(libmutter_la_SOURCES) $(nodist_libmutter_la_SOURCES))
@META_GIR@_SCANNERFLAGS = --warn-all --warn-error @META_GIR@_SCANNERFLAGS = --warn-all --warn-error
endif endif

View File

@@ -17,8 +17,6 @@ struct _MetaCompositor
{ {
MetaDisplay *display; MetaDisplay *display;
Atom atom_x_root_pixmap;
Atom atom_net_wm_window_opacity;
guint repaint_func_id; guint repaint_func_id;
ClutterActor *shadow_src; ClutterActor *shadow_src;

View File

@@ -42,15 +42,6 @@
* the call, so it may be necessary to readjust the display based on the * the call, so it may be necessary to readjust the display based on the
* old_rect to start the animation. * old_rect to start the animation.
* *
* meta_compositor_window_mapped() and meta_compositor_window_unmapped() are
* notifications when the toplevel window (frame or client window) is mapped or
* unmapped. That is, when the result of meta_window_toplevel_is_mapped()
* changes. The main use of this is to drop resources when a window is unmapped.
* A window will always be mapped before meta_compositor_show_window()
* is called and will not be unmapped until after meta_compositor_hide_window()
* is called. If the live_hidden_windows preference is set, windows will never
* be unmapped.
*
* # Containers # * # Containers #
* *
* There's two containers in the stage that are used to place window actors, here * There's two containers in the stage that are used to place window actors, here
@@ -175,31 +166,6 @@ process_damage (MetaCompositor *compositor,
meta_window_actor_process_damage (window_actor, event); meta_window_actor_process_damage (window_actor, event);
} }
static void
process_property_notify (MetaCompositor *compositor,
XPropertyEvent *event,
MetaWindow *window)
{
MetaWindowActor *window_actor;
if (window == NULL)
return;
window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
if (window_actor == NULL)
return;
/* Check for the opacity changing */
if (event->atom == compositor->atom_net_wm_window_opacity)
{
meta_window_actor_update_opacity (window_actor);
DEBUG_TRACE ("process_property_notify: net_wm_window_opacity\n");
return;
}
DEBUG_TRACE ("process_property_notify: unknown\n");
}
static Window static Window
get_output_window (MetaScreen *screen) get_output_window (MetaScreen *screen)
{ {
@@ -685,15 +651,6 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
clutter_actor_add_child (info->stage, info->window_group); clutter_actor_add_child (info->stage, info->window_group);
clutter_actor_add_child (info->stage, info->top_window_group); clutter_actor_add_child (info->stage, info->top_window_group);
info->plugin_mgr = meta_plugin_manager_new (screen);
/*
* Delay the creation of the overlay window as long as we can, to avoid
* blanking out the screen. This means that during the plugin loading, the
* overlay window is not accessible; if the plugin needs to access it
* directly, it should hook into the "show" signal on stage, and do
* its stuff there.
*/
info->output = get_output_window (screen); info->output = get_output_window (screen);
XReparentWindow (xdisplay, xwin, info->output, 0, 0); XReparentWindow (xdisplay, xwin, info->output, 0, 0);
@@ -714,6 +671,8 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
info->pending_input_region = None; info->pending_input_region = None;
} }
info->plugin_mgr = meta_plugin_manager_new (screen);
/* Map overlay window before redirecting windows offscreen so we catch their /* Map overlay window before redirecting windows offscreen so we catch their
* contents until we show the stage. * contents until we show the stage.
*/ */
@@ -756,7 +715,7 @@ meta_shape_cow_for_window (MetaScreen *screen,
int width, height; int width, height;
MetaRectangle rect; MetaRectangle rect;
meta_window_get_outer_rect (metaWindow, &rect); meta_window_get_frame_rect (metaWindow, &rect);
window_bounds.x = rect.x; window_bounds.x = rect.x;
window_bounds.y = rect.y; window_bounds.y = rect.y;
@@ -884,6 +843,18 @@ meta_compositor_window_shape_changed (MetaCompositor *compositor,
meta_window_actor_update_shape (window_actor); meta_window_actor_update_shape (window_actor);
} }
void
meta_compositor_window_opacity_changed (MetaCompositor *compositor,
MetaWindow *window)
{
MetaWindowActor *window_actor;
window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
if (!window_actor)
return;
meta_window_actor_update_opacity (window_actor);
}
/* Clutter makes the assumption that there is only one X window /* Clutter makes the assumption that there is only one X window
* per stage, which is a valid assumption to make for a generic * per stage, which is a valid assumption to make for a generic
* application toolkit. As such, it will ignore any events sent * application toolkit. As such, it will ignore any events sent
@@ -990,28 +961,19 @@ meta_compositor_process_event (MetaCompositor *compositor,
} }
} }
switch (event->type) if (event->type == meta_display_get_damage_event_base (compositor->display) + XDamageNotify)
{ {
case PropertyNotify: /* Core code doesn't handle damage events, so we need to extract the MetaWindow
process_property_notify (compositor, (XPropertyEvent *) event, window); * ourselves
break; */
if (window == NULL)
default:
if (event->type == meta_display_get_damage_event_base (compositor->display) + XDamageNotify)
{ {
/* Core code doesn't handle damage events, so we need to extract the MetaWindow Window xwin = ((XDamageNotifyEvent *) event)->drawable;
* ourselves window = meta_display_lookup_x_window (compositor->display, xwin);
*/
if (window == NULL)
{
Window xwin = ((XDamageNotifyEvent *) event)->drawable;
window = meta_display_lookup_x_window (compositor->display, xwin);
}
DEBUG_TRACE ("meta_compositor_process_event (process_damage)\n");
process_damage (compositor, (XDamageNotifyEvent *) event, window);
} }
break;
DEBUG_TRACE ("meta_compositor_process_event (process_damage)\n");
process_damage (compositor, (XDamageNotifyEvent *) event, window);
} }
/* Clutter needs to know about MapNotify events otherwise it will /* Clutter needs to know about MapNotify events otherwise it will
@@ -1311,30 +1273,6 @@ meta_compositor_sync_stack (MetaCompositor *compositor,
sync_actor_stacking (info); sync_actor_stacking (info);
} }
void
meta_compositor_window_mapped (MetaCompositor *compositor,
MetaWindow *window)
{
MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
DEBUG_TRACE ("meta_compositor_window_mapped\n");
if (!window_actor)
return;
meta_window_actor_mapped (window_actor);
}
void
meta_compositor_window_unmapped (MetaCompositor *compositor,
MetaWindow *window)
{
MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
DEBUG_TRACE ("meta_compositor_window_unmapped\n");
if (!window_actor)
return;
meta_window_actor_unmapped (window_actor);
}
void void
meta_compositor_sync_window_geometry (MetaCompositor *compositor, meta_compositor_sync_window_geometry (MetaCompositor *compositor,
MetaWindow *window, MetaWindow *window,
@@ -1515,13 +1453,7 @@ on_shadow_factory_changed (MetaShadowFactory *factory,
MetaCompositor * MetaCompositor *
meta_compositor_new (MetaDisplay *display) meta_compositor_new (MetaDisplay *display)
{ {
char *atom_names[] = {
"_XROOTPMAP_ID",
"_NET_WM_WINDOW_OPACITY",
};
Atom atoms[G_N_ELEMENTS(atom_names)];
MetaCompositor *compositor; MetaCompositor *compositor;
Display *xdisplay = meta_display_get_xdisplay (display);
if (!composite_at_least_version (display, 0, 3)) if (!composite_at_least_version (display, 0, 3))
return NULL; return NULL;
@@ -1533,18 +1465,11 @@ meta_compositor_new (MetaDisplay *display)
if (g_getenv("META_DISABLE_MIPMAPS")) if (g_getenv("META_DISABLE_MIPMAPS"))
compositor->no_mipmaps = TRUE; compositor->no_mipmaps = TRUE;
meta_verbose ("Creating %d atoms\n", (int) G_N_ELEMENTS (atom_names));
XInternAtoms (xdisplay, atom_names, G_N_ELEMENTS (atom_names),
False, atoms);
g_signal_connect (meta_shadow_factory_get_default (), g_signal_connect (meta_shadow_factory_get_default (),
"changed", "changed",
G_CALLBACK (on_shadow_factory_changed), G_CALLBACK (on_shadow_factory_changed),
compositor); compositor);
compositor->atom_x_root_pixmap = atoms[0];
compositor->atom_net_wm_window_opacity = atoms[1];
compositor->repaint_func_id = clutter_threads_add_repaint_func (meta_repaint_func, compositor->repaint_func_id = clutter_threads_add_repaint_func (meta_repaint_func,
compositor, compositor,
NULL); NULL);

View File

@@ -6,9 +6,6 @@
#include <meta/screen.h> #include <meta/screen.h>
#include <meta/meta-background-actor.h> #include <meta/meta-background-actor.h>
void meta_background_actor_set_clip_region (MetaBackgroundActor *self,
cairo_region_t *clip_region);
cairo_region_t *meta_background_actor_get_clip_region (MetaBackgroundActor *self); cairo_region_t *meta_background_actor_get_clip_region (MetaBackgroundActor *self);
#endif /* META_BACKGROUND_ACTOR_PRIVATE_H */ #endif /* META_BACKGROUND_ACTOR_PRIVATE_H */

View File

@@ -41,20 +41,35 @@
#include <meta/errors.h> #include <meta/errors.h>
#include <meta/meta-background.h> #include <meta/meta-background.h>
#include "meta-background-actor-private.h" #include "meta-background-actor-private.h"
#include "meta-cullable.h"
struct _MetaBackgroundActorPrivate struct _MetaBackgroundActorPrivate
{ {
cairo_region_t *clip_region; cairo_region_t *clip_region;
}; };
G_DEFINE_TYPE (MetaBackgroundActor, meta_background_actor, CLUTTER_TYPE_ACTOR); static void cullable_iface_init (MetaCullableInterface *iface);
G_DEFINE_TYPE_WITH_CODE (MetaBackgroundActor, meta_background_actor, CLUTTER_TYPE_ACTOR,
G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init));
static void
set_clip_region (MetaBackgroundActor *self,
cairo_region_t *clip_region)
{
MetaBackgroundActorPrivate *priv = self->priv;
g_clear_pointer (&priv->clip_region, (GDestroyNotify) cairo_region_destroy);
if (clip_region)
priv->clip_region = cairo_region_copy (clip_region);
}
static void static void
meta_background_actor_dispose (GObject *object) meta_background_actor_dispose (GObject *object)
{ {
MetaBackgroundActor *self = META_BACKGROUND_ACTOR (object); MetaBackgroundActor *self = META_BACKGROUND_ACTOR (object);
meta_background_actor_set_clip_region (self, NULL); set_clip_region (self, NULL);
G_OBJECT_CLASS (meta_background_actor_parent_class)->dispose (object); G_OBJECT_CLASS (meta_background_actor_parent_class)->dispose (object);
} }
@@ -104,26 +119,6 @@ meta_background_actor_get_preferred_height (ClutterActor *actor,
*natural_height_p = height; *natural_height_p = height;
} }
static gboolean
meta_background_actor_get_paint_volume (ClutterActor *actor,
ClutterPaintVolume *volume)
{
ClutterContent *content;
gfloat width, height;
content = clutter_actor_get_content (actor);
if (!content)
return FALSE;
clutter_content_get_preferred_size (content, &width, &height);
clutter_paint_volume_set_width (volume, width);
clutter_paint_volume_set_height (volume, height);
return TRUE;
}
static void static void
meta_background_actor_class_init (MetaBackgroundActorClass *klass) meta_background_actor_class_init (MetaBackgroundActorClass *klass)
{ {
@@ -136,7 +131,6 @@ meta_background_actor_class_init (MetaBackgroundActorClass *klass)
actor_class->get_preferred_width = meta_background_actor_get_preferred_width; actor_class->get_preferred_width = meta_background_actor_get_preferred_width;
actor_class->get_preferred_height = meta_background_actor_get_preferred_height; actor_class->get_preferred_height = meta_background_actor_get_preferred_height;
actor_class->get_paint_volume = meta_background_actor_get_paint_volume;
} }
static void static void
@@ -166,31 +160,27 @@ meta_background_actor_new (void)
return CLUTTER_ACTOR (self); return CLUTTER_ACTOR (self);
} }
/** static void
* meta_background_actor_set_clip_region: meta_background_actor_cull_out (MetaCullable *cullable,
* @self: a #MetaBackgroundActor cairo_region_t *unobscured_region,
* @clip_region: (allow-none): the area of the actor (in allocate-relative cairo_region_t *clip_region)
* coordinates) that is visible.
*
* Sets the area of the background that is unobscured by overlapping windows.
* This is used to optimize and only paint the visible portions.
*/
void
meta_background_actor_set_clip_region (MetaBackgroundActor *self,
cairo_region_t *clip_region)
{ {
MetaBackgroundActorPrivate *priv; MetaBackgroundActor *self = META_BACKGROUND_ACTOR (cullable);
set_clip_region (self, clip_region);
}
g_return_if_fail (META_IS_BACKGROUND_ACTOR (self)); static void
meta_background_actor_reset_culling (MetaCullable *cullable)
{
MetaBackgroundActor *self = META_BACKGROUND_ACTOR (cullable);
set_clip_region (self, NULL);
}
priv = self->priv; static void
cullable_iface_init (MetaCullableInterface *iface)
g_clear_pointer (&priv->clip_region, {
(GDestroyNotify) iface->cull_out = meta_background_actor_cull_out;
cairo_region_destroy); iface->reset_culling = meta_background_actor_reset_culling;
if (clip_region)
priv->clip_region = cairo_region_copy (clip_region);
} }
/** /**

View File

@@ -1,11 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
#ifndef META_BACKGROUND_GROUP_PRIVATE_H
#define META_BACKGROUND_GROUP_PRIVATE_H
#include <meta/screen.h>
#include <meta/meta-background-group.h>
void meta_background_group_set_clip_region (MetaBackgroundGroup *self,
cairo_region_t *visible_region);
#endif /* META_BACKGROUND_GROUP_PRIVATE_H */

View File

@@ -16,87 +16,43 @@
#include <config.h> #include <config.h>
#include "compositor-private.h" #include <meta/meta-background-group.h>
#include "clutter-utils.h" #include "meta-cullable.h"
#include "meta-background-actor-private.h"
#include "meta-background-group-private.h"
G_DEFINE_TYPE (MetaBackgroundGroup, meta_background_group, CLUTTER_TYPE_ACTOR); static void cullable_iface_init (MetaCullableInterface *iface);
struct _MetaBackgroundGroupPrivate G_DEFINE_TYPE_WITH_CODE (MetaBackgroundGroup, meta_background_group, CLUTTER_TYPE_ACTOR,
{ G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init));
gpointer dummy;
};
static void
meta_background_group_dispose (GObject *object)
{
G_OBJECT_CLASS (meta_background_group_parent_class)->dispose (object);
}
static gboolean
meta_background_group_get_paint_volume (ClutterActor *actor,
ClutterPaintVolume *volume)
{
return clutter_paint_volume_set_from_allocation (volume, actor);
}
static void static void
meta_background_group_class_init (MetaBackgroundGroupClass *klass) meta_background_group_class_init (MetaBackgroundGroupClass *klass)
{ {
GObjectClass *object_class = G_OBJECT_CLASS (klass); }
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
actor_class->get_paint_volume = meta_background_group_get_paint_volume; static void
object_class->dispose = meta_background_group_dispose; meta_background_group_cull_out (MetaCullable *cullable,
cairo_region_t *unobscured_region,
cairo_region_t *clip_region)
{
meta_cullable_cull_out_children (cullable, unobscured_region, clip_region);
}
g_type_class_add_private (klass, sizeof (MetaBackgroundGroupPrivate)); static void
meta_background_group_reset_culling (MetaCullable *cullable)
{
meta_cullable_reset_culling_children (cullable);
}
static void
cullable_iface_init (MetaCullableInterface *iface)
{
iface->cull_out = meta_background_group_cull_out;
iface->reset_culling = meta_background_group_reset_culling;
} }
static void static void
meta_background_group_init (MetaBackgroundGroup *self) meta_background_group_init (MetaBackgroundGroup *self)
{ {
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
META_TYPE_BACKGROUND_GROUP,
MetaBackgroundGroupPrivate);
}
/**
* meta_background_group_set_clip_region:
* @self: a #MetaBackgroundGroup
* @region: (allow-none): the parts of the background to paint
*
* Sets the area of the backgrounds that is unobscured by overlapping windows.
* This is used to optimize and only paint the visible portions.
*/
void
meta_background_group_set_clip_region (MetaBackgroundGroup *self,
cairo_region_t *region)
{
GList *children, *l;
children = clutter_actor_get_children (CLUTTER_ACTOR (self));
for (l = children; l; l = l->next)
{
ClutterActor *actor = l->data;
if (META_IS_BACKGROUND_ACTOR (actor))
{
meta_background_actor_set_clip_region (META_BACKGROUND_ACTOR (actor), region);
}
else if (META_IS_BACKGROUND_GROUP (actor))
{
int x, y;
if (!meta_actor_is_untransformed (actor, &x, &y))
continue;
cairo_region_translate (region, -x, -y);
meta_background_group_set_clip_region (META_BACKGROUND_GROUP (actor), region);
cairo_region_translate (region, x, y);
}
}
g_list_free (children);
} }
ClutterActor * ClutterActor *

View File

@@ -0,0 +1,191 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (C) 2013 Red Hat
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Written by:
* Owen Taylor <otaylor@redhat.com>
* Ray Strode <rstrode@redhat.com>
* Jasper St. Pierre <jstpierre@mecheye.net>
*/
#include "config.h"
#include "meta-cullable.h"
#include "clutter-utils.h"
G_DEFINE_INTERFACE (MetaCullable, meta_cullable, CLUTTER_TYPE_ACTOR);
/**
* SECTION:meta-cullable
* @title: MetaCullable
* @short_description: CPU culling operations for efficient drawing
*
* When we are painting a stack of 5-10 large actors, the standard
* bottom-to-top method of drawing every actor results in a tremendous
* amount of overdraw. If these actors are painting textures like
* windows, it can easily max out the available memory bandwidth on a
* low-end graphics chipset. It's even worse if window textures are
* being accessed over the AGP bus.
*
* #MetaCullable is our solution. The basic technique applied here is to
* do a pre-pass before painting where we walk each actor from top to bottom
* and ask each actor to "cull itself out". We pass in a region it can copy
* to clip its drawing to, and the actor can subtract its fully opaque pixels
* so that actors underneath know not to draw there as well.
*/
/**
* meta_cullable_cull_out_children:
* @cullable: The #MetaCullable
* @unobscured_region: The unobscured region, as passed into cull_out()
* @clip_region: The clip region, as passed into cull_out()
*
* This is a helper method for actors that want to recurse over their
* child actors, and cull them out.
*
* See #MetaCullable and meta_cullable_cull_out() for more details.
*/
void
meta_cullable_cull_out_children (MetaCullable *cullable,
cairo_region_t *unobscured_region,
cairo_region_t *clip_region)
{
ClutterActor *actor = CLUTTER_ACTOR (cullable);
ClutterActor *child;
ClutterActorIter iter;
clutter_actor_iter_init (&iter, actor);
while (clutter_actor_iter_prev (&iter, &child))
{
int x, y;
if (!CLUTTER_ACTOR_IS_VISIBLE (child))
continue;
/* If an actor has effects applied, then that can change the area
* it paints and the opacity, so we no longer can figure out what
* portion of the actor is obscured and what portion of the screen
* it obscures, so we skip the actor.
*
* This has a secondary beneficial effect: if a ClutterOffscreenEffect
* is applied to an actor, then our clipped redraws interfere with the
* caching of the FBO - even if we only need to draw a small portion
* of the window right now, ClutterOffscreenEffect may use other portions
* of the FBO later. So, skipping actors with effects applied also
* prevents these bugs.
*
* Theoretically, we should check clutter_actor_get_offscreen_redirect()
* as well for the same reason, but omitted for simplicity in the
* hopes that no-one will do that.
*/
if (clutter_actor_has_effects (child))
continue;
if (!META_IS_CULLABLE (child))
continue;
if (!meta_actor_is_untransformed (child, &x, &y))
continue;
/* Temporarily move to the coordinate system of the actor */
cairo_region_translate (unobscured_region, - x, - y);
cairo_region_translate (clip_region, - x, - y);
meta_cullable_cull_out (META_CULLABLE (child), unobscured_region, clip_region);
cairo_region_translate (unobscured_region, x, y);
cairo_region_translate (clip_region, x, y);
}
}
/**
* meta_cullable_reset_culling_children:
* @cullable: The #MetaCullable
*
* This is a helper method for actors that want to recurse over their
* child actors, and cull them out.
*
* See #MetaCullable and meta_cullable_reset_culling() for more details.
*/
void
meta_cullable_reset_culling_children (MetaCullable *cullable)
{
ClutterActor *actor = CLUTTER_ACTOR (cullable);
ClutterActor *child;
ClutterActorIter iter;
clutter_actor_iter_init (&iter, actor);
while (clutter_actor_iter_next (&iter, &child))
{
if (!META_IS_CULLABLE (child))
continue;
meta_cullable_reset_culling (META_CULLABLE (child));
}
}
static void
meta_cullable_default_init (MetaCullableInterface *iface)
{
}
/**
* meta_cullable_cull_out:
* @cullable: The #MetaCullable
* @unobscured_region: The unobscured region, in @cullable's space.
* @clip_region: The clip region, in @cullable's space.
*
* When #MetaWindowGroup is painted, we walk over its direct cullable
* children from top to bottom and ask themselves to "cull out". Cullables
* can use @unobscured_region and @clip_region to clip their drawing. Actors
* interested in eliminating overdraw should copy the @clip_region and only
* paint those parts, as everything else has been obscured by actors above it.
*
* Actors that may have fully opaque parts should also subtract out a region
* that is fully opaque from @unobscured_region and @clip_region.
*
* @unobscured_region and @clip_region are extremely similar. The difference
* is that @clip_region starts off with the stage's clip, if Clutter detects
* that we're doing a clipped redraw. @unobscured_region, however, starts off
* with the full stage size, so actors that may want to record what parts of
* their window are unobscured for e.g. scheduling repaints can do so.
*
* Actors that have children can also use the meta_cullable_cull_out_children()
* helper method to do a simple cull across all their children.
*/
void
meta_cullable_cull_out (MetaCullable *cullable,
cairo_region_t *unobscured_region,
cairo_region_t *clip_region)
{
META_CULLABLE_GET_IFACE (cullable)->cull_out (cullable, unobscured_region, clip_region);
}
/**
* meta_cullable_reset_culling:
* @cullable: The #MetaCullable
*
* Actors that copied data in their cull_out() implementation can now
* reset their data, as the paint is now over. Additional paints may be
* done by #ClutterClone or similar, and they should not be affected by
* the culling operation.
*/
void
meta_cullable_reset_culling (MetaCullable *cullable)
{
META_CULLABLE_GET_IFACE (cullable)->reset_culling (cullable);
}

View File

@@ -0,0 +1,68 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (C) 2013 Red Hat
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Written by:
* Owen Taylor <otaylor@redhat.com>
* Ray Strode <rstrode@redhat.com>
* Jasper St. Pierre <jstpierre@mecheye.net>
*/
#ifndef __META_CULLABLE_H__
#define __META_CULLABLE_H__
#include <clutter/clutter.h>
G_BEGIN_DECLS
#define META_TYPE_CULLABLE (meta_cullable_get_type ())
#define META_CULLABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_CULLABLE, MetaCullable))
#define META_IS_CULLABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_CULLABLE))
#define META_CULLABLE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), META_TYPE_CULLABLE, MetaCullableInterface))
typedef struct _MetaCullable MetaCullable;
typedef struct _MetaCullableInterface MetaCullableInterface;
struct _MetaCullableInterface
{
GTypeInterface g_iface;
void (* cull_out) (MetaCullable *cullable,
cairo_region_t *unobscured_region,
cairo_region_t *clip_region);
void (* reset_culling) (MetaCullable *cullable);
};
GType meta_cullable_get_type (void);
void meta_cullable_cull_out (MetaCullable *cullable,
cairo_region_t *unobscured_region,
cairo_region_t *clip_region);
void meta_cullable_reset_culling (MetaCullable *cullable);
/* Utility methods for implementations */
void meta_cullable_cull_out_children (MetaCullable *cullable,
cairo_region_t *unobscured_region,
cairo_region_t *clip_region);
void meta_cullable_reset_culling_children (MetaCullable *cullable);
G_END_DECLS
#endif /* __META_CULLABLE_H__ */

View File

@@ -72,6 +72,7 @@ struct _MetaShapedTexturePrivate
cairo_region_t *clip_region; cairo_region_t *clip_region;
cairo_region_t *opaque_region; cairo_region_t *opaque_region;
cairo_region_t *input_shape_region;
guint tex_width, tex_height; guint tex_width, tex_height;
@@ -394,45 +395,60 @@ meta_shaped_texture_pick (ClutterActor *actor,
MetaShapedTexture *stex = (MetaShapedTexture *) actor; MetaShapedTexture *stex = (MetaShapedTexture *) actor;
MetaShapedTexturePrivate *priv = stex->priv; MetaShapedTexturePrivate *priv = stex->priv;
if (!clutter_actor_should_pick_paint (actor) ||
(priv->clip_region && cairo_region_is_empty (priv->clip_region)))
return;
/* If there is no region then use the regular pick */ /* If there is no region then use the regular pick */
if (priv->mask_texture == NULL) if (priv->input_shape_region == NULL)
CLUTTER_ACTOR_CLASS (meta_shaped_texture_parent_class)->pick (actor, color); CLUTTER_ACTOR_CLASS (meta_shaped_texture_parent_class)->pick (actor, color);
else if (clutter_actor_should_pick_paint (actor)) else
{ {
CoglTexture *paint_tex; int n_rects;
ClutterActorBox alloc; float *rectangles;
guint tex_width, tex_height; int i;
CoglPipeline *pipeline; CoglPipeline *pipeline;
CoglContext *ctx; CoglContext *ctx;
CoglFramebuffer *fb; CoglFramebuffer *fb;
CoglColor cogl_color; CoglColor cogl_color;
paint_tex = COGL_TEXTURE (priv->texture); /* Note: We don't bother trying to intersect the pick and clip regions
* since needing to copy the region, do the intersection, and probably
* increase the number of rectangles seems more likely to have a negative
* effect.
*
* NB: Most of the time when just using rectangles for picking then
* picking shouldn't involve any rendering, and minimizing the number of
* rectangles has more benefit than reducing the area of the pick
* region.
*/
if (paint_tex == NULL) n_rects = cairo_region_num_rectangles (priv->input_shape_region);
return; rectangles = g_alloca (sizeof (float) * 4 * n_rects);
tex_width = cogl_texture_get_width (paint_tex); for (i = 0; i < n_rects; i++)
tex_height = cogl_texture_get_height (paint_tex); {
cairo_rectangle_int_t rect;
int pos = i * 4;
if (tex_width == 0 || tex_height == 0) /* no contents yet */ cairo_region_get_rectangle (priv->input_shape_region, i, &rect);
return;
rectangles[pos] = rect.x;
rectangles[pos + 1] = rect.y;
rectangles[pos + 2] = rect.x + rect.width;
rectangles[pos + 3] = rect.y + rect.height;
}
ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ()); ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
fb = cogl_get_draw_framebuffer (); fb = cogl_get_draw_framebuffer ();
cogl_color_init_from_4ub (&cogl_color, color->red, color->green, color->blue, color->alpha); cogl_color_init_from_4ub (&cogl_color, color->red, color->green, color->blue, color->alpha);
pipeline = get_masked_pipeline (ctx); pipeline = cogl_pipeline_new (ctx);
cogl_pipeline_set_layer_texture (pipeline, 1, priv->mask_texture);
cogl_pipeline_set_color (pipeline, &cogl_color); cogl_pipeline_set_color (pipeline, &cogl_color);
clutter_actor_get_allocation_box (actor, &alloc); cogl_framebuffer_draw_rectangles (fb, pipeline,
rectangles, n_rects);
cogl_framebuffer_draw_rectangle (fb, pipeline,
0, 0,
alloc.x2 - alloc.x1,
alloc.y2 - alloc.y1);
cogl_object_unref (pipeline); cogl_object_unref (pipeline);
} }
} }
@@ -691,6 +707,41 @@ meta_shaped_texture_get_texture (MetaShapedTexture *stex)
return COGL_TEXTURE (stex->priv->texture); return COGL_TEXTURE (stex->priv->texture);
} }
/**
* meta_shaped_texture_set_input_shape_region:
* @stex: a #MetaShapedTexture
* @shape_region: the region of the texture that should respond to
* input.
*
* Determines what region of the texture should accept input. For
* X based windows this is defined by the ShapeInput region of the
* window.
*/
void
meta_shaped_texture_set_input_shape_region (MetaShapedTexture *stex,
cairo_region_t *shape_region)
{
MetaShapedTexturePrivate *priv;
g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
priv = stex->priv;
if (priv->input_shape_region != NULL)
{
cairo_region_destroy (priv->input_shape_region);
priv->input_shape_region = NULL;
}
if (shape_region != NULL)
{
cairo_region_reference (shape_region);
priv->input_shape_region = shape_region;
}
clutter_actor_queue_redraw (CLUTTER_ACTOR (stex));
}
/** /**
* meta_shaped_texture_set_clip_region: * meta_shaped_texture_set_clip_region:
* @stex: a #MetaShapedTexture * @stex: a #MetaShapedTexture

View File

@@ -55,14 +55,6 @@ void meta_window_actor_set_updates_frozen (MetaWindowActor *self,
void meta_window_actor_queue_frame_drawn (MetaWindowActor *self, void meta_window_actor_queue_frame_drawn (MetaWindowActor *self,
gboolean no_delay_frame); gboolean no_delay_frame);
cairo_region_t *meta_window_actor_get_obscured_region (MetaWindowActor *self);
void meta_window_actor_set_clip_region (MetaWindowActor *self,
cairo_region_t *clip_region);
void meta_window_actor_set_clip_region_beneath (MetaWindowActor *self,
cairo_region_t *beneath_region);
void meta_window_actor_reset_clip_regions (MetaWindowActor *self);
void meta_window_actor_set_unobscured_region (MetaWindowActor *self, void meta_window_actor_set_unobscured_region (MetaWindowActor *self,
cairo_region_t *unobscured_region); cairo_region_t *unobscured_region);

View File

@@ -32,6 +32,7 @@
#include "meta-texture-rectangle.h" #include "meta-texture-rectangle.h"
#include "region-utils.h" #include "region-utils.h"
#include "monitor-private.h" #include "monitor-private.h"
#include "meta-cullable.h"
enum { enum {
POSITION_CHANGED, POSITION_CHANGED,
@@ -45,7 +46,6 @@ static guint signals[LAST_SIGNAL] = {0};
struct _MetaWindowActorPrivate struct _MetaWindowActorPrivate
{ {
MetaWindow *window; MetaWindow *window;
Window xwindow;
MetaScreen *screen; MetaScreen *screen;
ClutterActor *actor; ClutterActor *actor;
@@ -68,10 +68,10 @@ struct _MetaWindowActorPrivate
Damage damage; Damage damage;
guint8 opacity;
/* A region that matches the shape of the window, including frame bounds */ /* A region that matches the shape of the window, including frame bounds */
cairo_region_t *shape_region; cairo_region_t *shape_region;
/* If the window has an input shape, a region that matches the shape */
cairo_region_t *input_region;
/* The opaque region, from _NET_WM_OPAQUE_REGION, intersected with /* The opaque region, from _NET_WM_OPAQUE_REGION, intersected with
* the shape region. */ * the shape region. */
cairo_region_t *opaque_region; cairo_region_t *opaque_region;
@@ -109,7 +109,6 @@ struct _MetaWindowActorPrivate
GList *frames; GList *frames;
guint visible : 1; guint visible : 1;
guint mapped : 1;
guint argb32 : 1; guint argb32 : 1;
guint disposed : 1; guint disposed : 1;
guint redecorating : 1; guint redecorating : 1;
@@ -152,8 +151,6 @@ struct _FrameData
enum enum
{ {
PROP_META_WINDOW = 1, PROP_META_WINDOW = 1,
PROP_META_SCREEN,
PROP_X_WINDOW,
PROP_NO_SHADOW, PROP_NO_SHADOW,
PROP_SHADOW_CLASS PROP_SHADOW_CLASS
}; };
@@ -189,7 +186,10 @@ static void do_send_frame_timings (MetaWindowActor *self,
gint refresh_interval, gint refresh_interval,
gint64 presentation_time); gint64 presentation_time);
G_DEFINE_TYPE (MetaWindowActor, meta_window_actor, CLUTTER_TYPE_ACTOR); static void cullable_iface_init (MetaCullableInterface *iface);
G_DEFINE_TYPE_WITH_CODE (MetaWindowActor, meta_window_actor, CLUTTER_TYPE_ACTOR,
G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init));
static void static void
frame_data_free (FrameData *frame) frame_data_free (FrameData *frame)
@@ -219,33 +219,12 @@ meta_window_actor_class_init (MetaWindowActorClass *klass)
"MetaWindow", "MetaWindow",
"The displayed MetaWindow", "The displayed MetaWindow",
META_TYPE_WINDOW, META_TYPE_WINDOW,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT); G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
g_object_class_install_property (object_class, g_object_class_install_property (object_class,
PROP_META_WINDOW, PROP_META_WINDOW,
pspec); pspec);
pspec = g_param_spec_pointer ("meta-screen",
"MetaScreen",
"MetaScreen",
G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
g_object_class_install_property (object_class,
PROP_META_SCREEN,
pspec);
pspec = g_param_spec_ulong ("x-window",
"Window",
"Window",
0,
G_MAXULONG,
0,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
g_object_class_install_property (object_class,
PROP_X_WINDOW,
pspec);
pspec = g_param_spec_boolean ("no-shadow", pspec = g_param_spec_boolean ("no-shadow",
"No shadow", "No shadow",
"Do not add shaddow to this window", "Do not add shaddow to this window",
@@ -288,7 +267,6 @@ meta_window_actor_init (MetaWindowActor *self)
priv = self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, priv = self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
META_TYPE_WINDOW_ACTOR, META_TYPE_WINDOW_ACTOR,
MetaWindowActorPrivate); MetaWindowActorPrivate);
priv->opacity = 0xff;
priv->shadow_class = NULL; priv->shadow_class = NULL;
} }
@@ -299,11 +277,9 @@ window_decorated_notify (MetaWindow *mw,
{ {
MetaWindowActor *self = META_WINDOW_ACTOR (data); MetaWindowActor *self = META_WINDOW_ACTOR (data);
MetaWindowActorPrivate *priv = self->priv; MetaWindowActorPrivate *priv = self->priv;
MetaFrame *frame = meta_window_get_frame (mw);
MetaScreen *screen = priv->screen; MetaScreen *screen = priv->screen;
MetaDisplay *display = meta_screen_get_display (screen); MetaDisplay *display = meta_screen_get_display (screen);
Display *xdisplay = meta_display_get_xdisplay (display); Display *xdisplay = meta_display_get_xdisplay (display);
Window new_xwindow;
/* /*
* Basically, we have to reconstruct the the internals of this object * Basically, we have to reconstruct the the internals of this object
@@ -311,11 +287,6 @@ window_decorated_notify (MetaWindow *mw,
*/ */
priv->redecorating = TRUE; priv->redecorating = TRUE;
if (frame)
new_xwindow = meta_frame_get_xwindow (frame);
else
new_xwindow = meta_window_get_xwindow (mw);
meta_window_actor_detach (self); meta_window_actor_detach (self);
/* /*
@@ -330,8 +301,6 @@ window_decorated_notify (MetaWindow *mw,
priv->damage = None; priv->damage = None;
} }
priv->xwindow = new_xwindow;
/* /*
* Recreate the contents. * Recreate the contents.
*/ */
@@ -346,18 +315,30 @@ window_appears_focused_notify (MetaWindow *mw,
clutter_actor_queue_redraw (CLUTTER_ACTOR (data)); clutter_actor_queue_redraw (CLUTTER_ACTOR (data));
} }
static gboolean
is_non_opaque (MetaWindowActor *self)
{
MetaWindowActorPrivate *priv = self->priv;
MetaWindow *window = priv->window;
return priv->argb32 || (window->opacity != 0xFF);
}
static void static void
meta_window_actor_constructed (GObject *object) meta_window_actor_constructed (GObject *object)
{ {
MetaWindowActor *self = META_WINDOW_ACTOR (object); MetaWindowActor *self = META_WINDOW_ACTOR (object);
MetaWindowActorPrivate *priv = self->priv; MetaWindowActorPrivate *priv = self->priv;
MetaScreen *screen = priv->screen;
MetaDisplay *display = meta_screen_get_display (screen);
Window xwindow = priv->xwindow;
MetaWindow *window = priv->window; MetaWindow *window = priv->window;
MetaScreen *screen = meta_window_get_screen (window);
MetaDisplay *display = meta_screen_get_display (screen);
Display *xdisplay = meta_display_get_xdisplay (display); Display *xdisplay = meta_display_get_xdisplay (display);
XRenderPictFormat *format; XRenderPictFormat *format;
Window xwindow;
xwindow = meta_window_get_toplevel_xwindow (window);
priv->screen = screen;
priv->damage = XDamageCreate (xdisplay, xwindow, priv->damage = XDamageCreate (xdisplay, xwindow,
XDamageReportBoundingBox); XDamageReportBoundingBox);
@@ -380,19 +361,6 @@ meta_window_actor_constructed (GObject *object)
* We will release it in dispose(). * We will release it in dispose().
*/ */
g_object_ref (priv->actor); g_object_ref (priv->actor);
g_signal_connect_object (window, "notify::decorated",
G_CALLBACK (window_decorated_notify), self, 0);
g_signal_connect_object (window, "notify::appears-focused",
G_CALLBACK (window_appears_focused_notify), self, 0);
}
else
{
/*
* This is the case where existing window is gaining/loosing frame.
* Just ensure the actor is top most (i.e., above shadow).
*/
clutter_actor_set_child_above_sibling (CLUTTER_ACTOR (self), priv->actor, NULL);
} }
meta_window_actor_update_opacity (self); meta_window_actor_update_opacity (self);
@@ -432,6 +400,7 @@ meta_window_actor_dispose (GObject *object)
g_clear_pointer (&priv->unobscured_region, cairo_region_destroy); g_clear_pointer (&priv->unobscured_region, cairo_region_destroy);
g_clear_pointer (&priv->shape_region, cairo_region_destroy); g_clear_pointer (&priv->shape_region, cairo_region_destroy);
g_clear_pointer (&priv->input_region, cairo_region_destroy);
g_clear_pointer (&priv->opaque_region, cairo_region_destroy); g_clear_pointer (&priv->opaque_region, cairo_region_destroy);
g_clear_pointer (&priv->shadow_clip, cairo_region_destroy); g_clear_pointer (&priv->shadow_clip, cairo_region_destroy);
@@ -484,17 +453,12 @@ meta_window_actor_set_property (GObject *object,
switch (prop_id) switch (prop_id)
{ {
case PROP_META_WINDOW: case PROP_META_WINDOW:
{ priv->window = g_value_dup_object (value);
if (priv->window)
g_object_unref (priv->window); g_signal_connect_object (priv->window, "notify::decorated",
priv->window = g_value_dup_object (value); G_CALLBACK (window_decorated_notify), self, 0);
} g_signal_connect_object (priv->window, "notify::appears-focused",
break; G_CALLBACK (window_appears_focused_notify), self, 0);
case PROP_META_SCREEN:
priv->screen = g_value_get_pointer (value);
break;
case PROP_X_WINDOW:
priv->xwindow = g_value_get_ulong (value);
break; break;
case PROP_NO_SHADOW: case PROP_NO_SHADOW:
{ {
@@ -540,12 +504,6 @@ meta_window_actor_get_property (GObject *object,
case PROP_META_WINDOW: case PROP_META_WINDOW:
g_value_set_object (value, priv->window); g_value_set_object (value, priv->window);
break; break;
case PROP_META_SCREEN:
g_value_set_pointer (value, priv->screen);
break;
case PROP_X_WINDOW:
g_value_set_ulong (value, priv->xwindow);
break;
case PROP_NO_SHADOW: case PROP_NO_SHADOW:
g_value_set_boolean (value, priv->no_shadow); g_value_set_boolean (value, priv->no_shadow);
break; break;
@@ -643,7 +601,7 @@ clip_shadow_under_window (MetaWindowActor *self)
{ {
MetaWindowActorPrivate *priv = self->priv; MetaWindowActorPrivate *priv = self->priv;
return (priv->argb32 || priv->opacity != 0xff) && priv->window->frame; return is_non_opaque (self) && priv->window->frame;
} }
static void static void
@@ -669,6 +627,7 @@ meta_window_actor_paint (ClutterActor *actor)
MetaShadowParams params; MetaShadowParams params;
cairo_rectangle_int_t shape_bounds; cairo_rectangle_int_t shape_bounds;
cairo_region_t *clip = priv->shadow_clip; cairo_region_t *clip = priv->shadow_clip;
MetaWindow *window = priv->window;
meta_window_actor_get_shape_bounds (self, &shape_bounds); meta_window_actor_get_shape_bounds (self, &shape_bounds);
meta_window_actor_get_shadow_params (self, appears_focused, &params); meta_window_actor_get_shadow_params (self, appears_focused, &params);
@@ -692,7 +651,7 @@ meta_window_actor_paint (ClutterActor *actor)
params.y_offset + shape_bounds.y, params.y_offset + shape_bounds.y,
shape_bounds.width, shape_bounds.width,
shape_bounds.height, shape_bounds.height,
(clutter_actor_get_paint_opacity (actor) * params.opacity * priv->opacity) / (255 * 255), (clutter_actor_get_paint_opacity (actor) * params.opacity * window->opacity) / (255 * 255),
clip, clip,
clip_shadow_under_window (self)); /* clip_strictly - not just as an optimization */ clip_shadow_under_window (self)); /* clip_strictly - not just as an optimization */
@@ -779,10 +738,10 @@ meta_window_actor_has_shadow (MetaWindowActor *self)
return TRUE; return TRUE;
/* /*
* Do not add shadows to ARGB windows; eventually we should generate a * Do not add shadows to non-opaque windows; eventually we should generate
* shadow from the input shape for such windows. * a shadow from the input shape for such windows.
*/ */
if (priv->argb32 || priv->opacity != 0xff) if (is_non_opaque (self))
return FALSE; return FALSE;
/* /*
@@ -813,20 +772,6 @@ meta_window_actor_has_shadow (MetaWindowActor *self)
return FALSE; return FALSE;
} }
/**
* meta_window_actor_get_x_window: (skip)
* @self: a #MetaWindowActor
*
*/
Window
meta_window_actor_get_x_window (MetaWindowActor *self)
{
if (!self)
return None;
return self->priv->xwindow;
}
/** /**
* meta_window_actor_get_meta_window: * meta_window_actor_get_meta_window:
* @self: a #MetaWindowActor * @self: a #MetaWindowActor
@@ -994,7 +939,7 @@ meta_window_actor_damage_all (MetaWindowActor *self)
texture = meta_shaped_texture_get_texture (META_SHAPED_TEXTURE (priv->actor)); texture = meta_shaped_texture_get_texture (META_SHAPED_TEXTURE (priv->actor));
if (!priv->mapped || priv->needs_pixmap) if (priv->needs_pixmap)
return; return;
redraw_queued = meta_shaped_texture_update_area (META_SHAPED_TEXTURE (priv->actor), redraw_queued = meta_shaped_texture_update_area (META_SHAPED_TEXTURE (priv->actor),
@@ -1083,7 +1028,7 @@ meta_window_actor_queue_frame_drawn (MetaWindowActor *self,
{ {
queue_send_frame_messages_timeout (self); queue_send_frame_messages_timeout (self);
} }
else if (priv->mapped && !priv->needs_pixmap) else
{ {
const cairo_rectangle_int_t clip = { 0, 0, 1, 1 }; const cairo_rectangle_int_t clip = { 0, 0, 1, 1 };
clutter_actor_queue_redraw_with_clip (priv->actor, &clip); clutter_actor_queue_redraw_with_clip (priv->actor, &clip);
@@ -1115,9 +1060,6 @@ meta_window_actor_queue_create_pixmap (MetaWindowActor *self)
priv->needs_pixmap = TRUE; priv->needs_pixmap = TRUE;
if (!priv->mapped)
return;
if (is_frozen (self)) if (is_frozen (self))
return; return;
@@ -1331,7 +1273,7 @@ meta_window_actor_should_unredirect (MetaWindowActor *self)
if (meta_window_requested_dont_bypass_compositor (metaWindow)) if (meta_window_requested_dont_bypass_compositor (metaWindow))
return FALSE; return FALSE;
if (priv->opacity != 0xff) if (metaWindow->opacity != 0xFF)
return FALSE; return FALSE;
if (metaWindow->shape_region != NULL) if (metaWindow->shape_region != NULL)
@@ -1362,7 +1304,7 @@ meta_window_actor_set_redirected (MetaWindowActor *self, gboolean state)
MetaDisplay *display = meta_window_get_display (metaWindow); MetaDisplay *display = meta_window_get_display (metaWindow);
Display *xdisplay = meta_display_get_xdisplay (display); Display *xdisplay = meta_display_get_xdisplay (display);
Window xwin = meta_window_actor_get_x_window (self); Window xwin = meta_window_get_toplevel_xwindow (metaWindow);
if (state) if (state)
{ {
@@ -1616,22 +1558,10 @@ meta_window_actor_new (MetaWindow *window)
MetaCompScreen *info = meta_screen_get_compositor_data (screen); MetaCompScreen *info = meta_screen_get_compositor_data (screen);
MetaWindowActor *self; MetaWindowActor *self;
MetaWindowActorPrivate *priv; MetaWindowActorPrivate *priv;
MetaFrame *frame;
Window top_window;
ClutterActor *window_group; ClutterActor *window_group;
frame = meta_window_get_frame (window);
if (frame)
top_window = meta_frame_get_xwindow (frame);
else
top_window = meta_window_get_xwindow (window);
meta_verbose ("add window: Meta %p, xwin 0x%x\n", window, (guint)top_window);
self = g_object_new (META_TYPE_WINDOW_ACTOR, self = g_object_new (META_TYPE_WINDOW_ACTOR,
"meta-window", window, "meta-window", window,
"x-window", top_window,
"meta-screen", screen,
NULL); NULL);
priv = self->priv; priv = self->priv;
@@ -1639,10 +1569,6 @@ meta_window_actor_new (MetaWindow *window)
priv->last_width = -1; priv->last_width = -1;
priv->last_height = -1; priv->last_height = -1;
priv->mapped = meta_window_toplevel_is_mapped (priv->window);
if (priv->mapped)
meta_window_actor_queue_create_pixmap (self);
meta_window_actor_set_updates_frozen (self, meta_window_actor_set_updates_frozen (self,
meta_window_updates_are_frozen (priv->window)); meta_window_updates_are_frozen (priv->window));
@@ -1676,34 +1602,6 @@ meta_window_actor_new (MetaWindow *window)
return self; return self;
} }
void
meta_window_actor_mapped (MetaWindowActor *self)
{
MetaWindowActorPrivate *priv = self->priv;
g_return_if_fail (!priv->mapped);
priv->mapped = TRUE;
meta_window_actor_queue_create_pixmap (self);
}
void
meta_window_actor_unmapped (MetaWindowActor *self)
{
MetaWindowActorPrivate *priv = self->priv;
g_return_if_fail (priv->mapped);
priv->mapped = FALSE;
if (meta_window_actor_effect_in_progress (self))
return;
meta_window_actor_detach (self);
priv->needs_pixmap = FALSE;
}
/** /**
* meta_window_actor_get_obscured_region: * meta_window_actor_get_obscured_region:
* @self: a #MetaWindowActor * @self: a #MetaWindowActor
@@ -1714,12 +1612,13 @@ meta_window_actor_unmapped (MetaWindowActor *self)
* Return value: (transfer none): the area obscured by the window, * Return value: (transfer none): the area obscured by the window,
* %NULL is the same as an empty region. * %NULL is the same as an empty region.
*/ */
cairo_region_t * static cairo_region_t *
meta_window_actor_get_obscured_region (MetaWindowActor *self) meta_window_actor_get_obscured_region (MetaWindowActor *self)
{ {
MetaWindowActorPrivate *priv = self->priv; MetaWindowActorPrivate *priv = self->priv;
MetaWindow *window = priv->window;
if (priv->back_pixmap && priv->opacity == 0xff && !priv->window->shaded) if (priv->back_pixmap && window->opacity != 0xFF && !priv->window->shaded)
return priv->opaque_region; return priv->opaque_region;
else else
return NULL; return NULL;
@@ -1803,7 +1702,7 @@ meta_window_actor_set_unobscured_region (MetaWindowActor *self,
* not drawn in this frame. * not drawn in this frame.
* This will be set before painting then unset afterwards. * This will be set before painting then unset afterwards.
*/ */
void static void
meta_window_actor_set_clip_region (MetaWindowActor *self, meta_window_actor_set_clip_region (MetaWindowActor *self,
cairo_region_t *clip_region) cairo_region_t *clip_region)
{ {
@@ -1825,7 +1724,7 @@ meta_window_actor_set_clip_region (MetaWindowActor *self,
* shadow hid by the window itself. This will be set before painting * shadow hid by the window itself. This will be set before painting
* then unset afterwards. * then unset afterwards.
*/ */
void static void
meta_window_actor_set_clip_region_beneath (MetaWindowActor *self, meta_window_actor_set_clip_region_beneath (MetaWindowActor *self,
cairo_region_t *beneath_region) cairo_region_t *beneath_region)
{ {
@@ -1845,16 +1744,38 @@ meta_window_actor_set_clip_region_beneath (MetaWindowActor *self,
} }
} }
/** static void
* meta_window_actor_reset_clip_regions: meta_window_actor_cull_out (MetaCullable *cullable,
* @self: a #MetaWindowActor cairo_region_t *unobscured_region,
* cairo_region_t *clip_region)
* Unsets the regions set by meta_window_actor_set_clip_region() and
* meta_window_actor_set_clip_region_beneath()
*/
void
meta_window_actor_reset_clip_regions (MetaWindowActor *self)
{ {
MetaWindowActor *self = META_WINDOW_ACTOR (cullable);
MetaCompScreen *info = meta_screen_get_compositor_data (self->priv->screen);
/* Don't do any culling for the unredirected window */
if (self == info->unredirected_window)
return;
meta_window_actor_set_unobscured_region (self, unobscured_region);
meta_window_actor_set_clip_region (self, clip_region);
if (clutter_actor_get_paint_opacity (CLUTTER_ACTOR (self)) == 0xff)
{
cairo_region_t *obscured_region = meta_window_actor_get_obscured_region (self);
if (obscured_region)
{
cairo_region_subtract (unobscured_region, obscured_region);
cairo_region_subtract (clip_region, obscured_region);
}
}
meta_window_actor_set_clip_region_beneath (self, clip_region);
}
static void
meta_window_actor_reset_culling (MetaCullable *cullable)
{
MetaWindowActor *self = META_WINDOW_ACTOR (cullable);
MetaWindowActorPrivate *priv = self->priv; MetaWindowActorPrivate *priv = self->priv;
meta_shaped_texture_set_clip_region (META_SHAPED_TEXTURE (priv->actor), meta_shaped_texture_set_clip_region (META_SHAPED_TEXTURE (priv->actor),
@@ -1862,6 +1783,13 @@ meta_window_actor_reset_clip_regions (MetaWindowActor *self)
g_clear_pointer (&priv->shadow_clip, cairo_region_destroy); g_clear_pointer (&priv->shadow_clip, cairo_region_destroy);
} }
static void
cullable_iface_init (MetaCullableInterface *iface)
{
iface->cull_out = meta_window_actor_cull_out;
iface->reset_culling = meta_window_actor_reset_culling;
}
static void static void
check_needs_pixmap (MetaWindowActor *self) check_needs_pixmap (MetaWindowActor *self)
{ {
@@ -1870,15 +1798,12 @@ check_needs_pixmap (MetaWindowActor *self)
MetaDisplay *display = meta_screen_get_display (screen); MetaDisplay *display = meta_screen_get_display (screen);
Display *xdisplay = meta_display_get_xdisplay (display); Display *xdisplay = meta_display_get_xdisplay (display);
MetaCompScreen *info = meta_screen_get_compositor_data (screen); MetaCompScreen *info = meta_screen_get_compositor_data (screen);
Window xwindow = meta_window_get_toplevel_xwindow (priv->window);
MetaCompositor *compositor; MetaCompositor *compositor;
Window xwindow = priv->xwindow;
if (!priv->needs_pixmap) if (!priv->needs_pixmap)
return; return;
if (!priv->mapped)
return;
if (xwindow == meta_screen_get_xroot (screen) || if (xwindow == meta_screen_get_xroot (screen) ||
xwindow == clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage))) xwindow == clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage)))
return; return;
@@ -1936,7 +1861,7 @@ check_needs_pixmap (MetaWindowActor *self)
if (G_UNLIKELY (!cogl_texture_pixmap_x11_is_using_tfp_extension (COGL_TEXTURE_PIXMAP_X11 (texture)))) if (G_UNLIKELY (!cogl_texture_pixmap_x11_is_using_tfp_extension (COGL_TEXTURE_PIXMAP_X11 (texture))))
g_warning ("NOTE: Not using GLX TFP!\n"); g_warning ("NOTE: Not using GLX TFP!\n");
/* ::size-changed is supposed to refer to meta_window_get_outer_rect(). /* ::size-changed is supposed to refer to meta_window_get_frame_rect().
* Emitting it here works pretty much OK because a new value of the * Emitting it here works pretty much OK because a new value of the
* *input* rect (which is the outer rect with the addition of invisible * *input* rect (which is the outer rect with the addition of invisible
* borders) forces a new pixmap and we get here. In the rare case where * borders) forces a new pixmap and we get here. In the rare case where
@@ -1964,9 +1889,6 @@ check_needs_shadow (MetaWindowActor *self)
gboolean should_have_shadow; gboolean should_have_shadow;
gboolean appears_focused; gboolean appears_focused;
if (!priv->mapped)
return;
/* Calling meta_window_actor_has_shadow() here at every pre-paint is cheap /* Calling meta_window_actor_has_shadow() here at every pre-paint is cheap
* and avoids the need to explicitly handle window type changes, which * and avoids the need to explicitly handle window type changes, which
* we would do if tried to keep track of when we might be adding or removing * we would do if tried to keep track of when we might be adding or removing
@@ -2032,7 +1954,7 @@ meta_window_actor_process_damage (MetaWindowActor *self,
if (meta_window_is_fullscreen (priv->window) && g_list_last (info->windows)->data == self && !priv->unredirected) if (meta_window_is_fullscreen (priv->window) && g_list_last (info->windows)->data == self && !priv->unredirected)
{ {
MetaRectangle window_rect; MetaRectangle window_rect;
meta_window_get_outer_rect (priv->window, &window_rect); meta_window_get_frame_rect (priv->window, &window_rect);
if (window_rect.x == event->area.x && if (window_rect.x == event->area.x &&
window_rect.y == event->area.y && window_rect.y == event->area.y &&
@@ -2070,7 +1992,7 @@ meta_window_actor_process_damage (MetaWindowActor *self,
return; return;
} }
if (!priv->mapped || priv->needs_pixmap) if (priv->needs_pixmap)
return; return;
redraw_queued = meta_shaped_texture_update_area (META_SHAPED_TEXTURE (priv->actor), redraw_queued = meta_shaped_texture_update_area (META_SHAPED_TEXTURE (priv->actor),
@@ -2256,9 +2178,46 @@ meta_window_actor_update_shape_region (MetaWindowActor *self,
priv->shape_region = region; priv->shape_region = region;
g_clear_pointer (&priv->shadow_shape, meta_window_shape_unref); g_clear_pointer (&priv->shadow_shape, meta_window_shape_unref);
meta_window_actor_invalidate_shadow (self); meta_window_actor_invalidate_shadow (self);
} }
static void
meta_window_actor_update_input_region (MetaWindowActor *self,
cairo_rectangle_int_t *client_area)
{
MetaWindowActorPrivate *priv = self->priv;
MetaShapedTexture *stex = META_SHAPED_TEXTURE (priv->actor);
cairo_region_t *region = NULL;
if (priv->window->frame != NULL && priv->window->input_region != NULL)
{
region = meta_frame_get_frame_bounds (priv->window->frame);
cairo_region_subtract_rectangle (region, client_area);
/* input_region is in client window coordinates, so translate the
* input region into that coordinate system and back */
cairo_region_translate (region, -client_area->x, -client_area->y);
cairo_region_union (region, priv->window->input_region);
cairo_region_translate (region, client_area->x, client_area->y);
}
else if (priv->window->input_region != NULL)
{
region = cairo_region_reference (priv->window->input_region);
}
else
{
/* If we don't have a shape on the server, that means that
* we have an implicit shape of one rectangle covering the
* entire window. */
region = cairo_region_create_rectangle (client_area);
}
meta_shaped_texture_set_input_shape_region (stex, region);
cairo_region_destroy (region);
}
static void static void
meta_window_actor_update_opaque_region (MetaWindowActor *self) meta_window_actor_update_opaque_region (MetaWindowActor *self)
{ {
@@ -2302,9 +2261,6 @@ check_needs_reshape (MetaWindowActor *self)
MetaFrameBorders borders; MetaFrameBorders borders;
cairo_rectangle_int_t client_area; cairo_rectangle_int_t client_area;
if (!priv->mapped)
return;
if (!priv->needs_reshape) if (!priv->needs_reshape)
return; return;
@@ -2319,10 +2275,10 @@ check_needs_reshape (MetaWindowActor *self)
client_area.height = priv->window->rect.height; client_area.height = priv->window->rect.height;
meta_window_actor_update_shape_region (self, &client_area); meta_window_actor_update_shape_region (self, &client_area);
meta_window_actor_update_input_region (self, &client_area);
meta_window_actor_update_opaque_region (self); meta_window_actor_update_opaque_region (self);
priv->needs_reshape = FALSE; priv->needs_reshape = FALSE;
meta_window_actor_invalidate_shadow (self);
} }
void void
@@ -2567,23 +2523,9 @@ void
meta_window_actor_update_opacity (MetaWindowActor *self) meta_window_actor_update_opacity (MetaWindowActor *self)
{ {
MetaWindowActorPrivate *priv = self->priv; MetaWindowActorPrivate *priv = self->priv;
MetaDisplay *display = meta_screen_get_display (priv->screen); MetaWindow *window = priv->window;
MetaCompositor *compositor = meta_display_get_compositor (display);
Window xwin = meta_window_get_xwindow (priv->window);
gulong value;
guint8 opacity;
if (meta_prop_get_cardinal (display, xwin, clutter_actor_set_opacity (self->priv->actor, window->opacity);
compositor->atom_net_wm_window_opacity,
&value))
{
opacity = (guint8)((gfloat)value * 255.0 / ((gfloat)0xffffffff));
}
else
opacity = 255;
self->priv->opacity = opacity;
clutter_actor_set_opacity (self->priv->actor, opacity);
} }
void void

View File

@@ -11,8 +11,8 @@
#include "compositor-private.h" #include "compositor-private.h"
#include "meta-window-actor-private.h" #include "meta-window-actor-private.h"
#include "meta-window-group.h" #include "meta-window-group.h"
#include "meta-background-actor-private.h" #include "window-private.h"
#include "meta-background-group-private.h" #include "meta-cullable.h"
struct _MetaWindowGroupClass struct _MetaWindowGroupClass
{ {
@@ -26,7 +26,10 @@ struct _MetaWindowGroup
MetaScreen *screen; MetaScreen *screen;
}; };
G_DEFINE_TYPE (MetaWindowGroup, meta_window_group, CLUTTER_TYPE_ACTOR); static void cullable_iface_init (MetaCullableInterface *iface);
G_DEFINE_TYPE_WITH_CODE (MetaWindowGroup, meta_window_group, CLUTTER_TYPE_ACTOR,
G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init));
/* Help macros to scale from OpenGL <-1,1> coordinates system to /* Help macros to scale from OpenGL <-1,1> coordinates system to
* window coordinates ranging [0,window-size]. Borrowed from clutter-utils.c * window coordinates ranging [0,window-size]. Borrowed from clutter-utils.c
@@ -86,6 +89,27 @@ painting_untransformed (MetaWindowGroup *window_group,
return meta_actor_vertices_are_untransformed (vertices, width, height, x_origin, y_origin); return meta_actor_vertices_are_untransformed (vertices, width, height, x_origin, y_origin);
} }
static void
meta_window_group_cull_out (MetaCullable *cullable,
cairo_region_t *unobscured_region,
cairo_region_t *clip_region)
{
meta_cullable_cull_out_children (cullable, unobscured_region, clip_region);
}
static void
meta_window_group_reset_culling (MetaCullable *cullable)
{
meta_cullable_reset_culling_children (cullable);
}
static void
cullable_iface_init (MetaCullableInterface *iface)
{
iface->cull_out = meta_window_group_cull_out;
iface->reset_culling = meta_window_group_reset_culling;
}
static void static void
meta_window_group_paint (ClutterActor *actor) meta_window_group_paint (ClutterActor *actor)
{ {
@@ -94,13 +118,13 @@ meta_window_group_paint (ClutterActor *actor)
ClutterActorIter iter; ClutterActorIter iter;
ClutterActor *child; ClutterActor *child;
cairo_rectangle_int_t visible_rect, clip_rect; cairo_rectangle_int_t visible_rect, clip_rect;
int paint_x_offset, paint_y_offset;
int paint_x_origin, paint_y_origin; int paint_x_origin, paint_y_origin;
int actor_x_origin, actor_y_origin; int actor_x_origin, actor_y_origin;
int paint_x_offset, paint_y_offset;
MetaWindowGroup *window_group = META_WINDOW_GROUP (actor); MetaWindowGroup *window_group = META_WINDOW_GROUP (actor);
MetaCompScreen *info = meta_screen_get_compositor_data (window_group->screen);
ClutterActor *stage = clutter_actor_get_stage (actor); ClutterActor *stage = clutter_actor_get_stage (actor);
MetaCompScreen *info = meta_screen_get_compositor_data (window_group->screen);
/* Start off by treating all windows as completely unobscured, so damage anywhere /* Start off by treating all windows as completely unobscured, so damage anywhere
* in a window queues redraws, but confine it more below. */ * in a window queues redraws, but confine it more below. */
@@ -134,9 +158,6 @@ meta_window_group_paint (ClutterActor *actor)
return; return;
} }
paint_x_offset = paint_x_origin - actor_x_origin;
paint_y_offset = paint_y_origin - actor_y_origin;
visible_rect.x = visible_rect.y = 0; visible_rect.x = visible_rect.y = 0;
visible_rect.width = clutter_actor_get_width (CLUTTER_ACTOR (stage)); visible_rect.width = clutter_actor_get_width (CLUTTER_ACTOR (stage));
visible_rect.height = clutter_actor_get_height (CLUTTER_ACTOR (stage)); visible_rect.height = clutter_actor_get_height (CLUTTER_ACTOR (stage));
@@ -154,134 +175,54 @@ meta_window_group_paint (ClutterActor *actor)
clip_region = cairo_region_create_rectangle (&clip_rect); clip_region = cairo_region_create_rectangle (&clip_rect);
paint_x_offset = paint_x_origin - actor_x_origin;
paint_y_offset = paint_y_origin - actor_y_origin;
cairo_region_translate (clip_region, -paint_x_offset, -paint_y_offset);
if (info->unredirected_window != NULL) if (info->unredirected_window != NULL)
{ {
cairo_rectangle_int_t unredirected_rect; cairo_rectangle_int_t unredirected_rect;
MetaWindow *window = meta_window_actor_get_meta_window (info->unredirected_window); MetaWindow *window = meta_window_actor_get_meta_window (info->unredirected_window);
meta_window_get_outer_rect (window, (MetaRectangle *)&unredirected_rect); meta_window_get_frame_rect (window, (MetaRectangle *)&unredirected_rect);
cairo_region_subtract_rectangle (unobscured_region, &unredirected_rect); cairo_region_subtract_rectangle (unobscured_region, &unredirected_rect);
cairo_region_subtract_rectangle (clip_region, &unredirected_rect); cairo_region_subtract_rectangle (clip_region, &unredirected_rect);
} }
/* We walk the list from top to bottom (opposite of painting order), meta_cullable_cull_out (META_CULLABLE (window_group), unobscured_region, clip_region);
* and subtract the opaque area of each window out of the visible
* region that we pass to the windows below.
*/
clutter_actor_iter_init (&iter, actor);
while (clutter_actor_iter_prev (&iter, &child))
{
if (!CLUTTER_ACTOR_IS_VISIBLE (child))
continue;
if (info->unredirected_window != NULL &&
child == CLUTTER_ACTOR (info->unredirected_window))
continue;
/* If an actor has effects applied, then that can change the area
* it paints and the opacity, so we no longer can figure out what
* portion of the actor is obscured and what portion of the screen
* it obscures, so we skip the actor.
*
* This has a secondary beneficial effect: if a ClutterOffscreenEffect
* is applied to an actor, then our clipped redraws interfere with the
* caching of the FBO - even if we only need to draw a small portion
* of the window right now, ClutterOffscreenEffect may use other portions
* of the FBO later. So, skipping actors with effects applied also
* prevents these bugs.
*
* Theoretically, we should check clutter_actor_get_offscreen_redirect()
* as well for the same reason, but omitted for simplicity in the
* hopes that no-one will do that.
*/
if (clutter_actor_has_effects (child))
continue;
if (META_IS_WINDOW_ACTOR (child))
{
MetaWindowActor *window_actor = META_WINDOW_ACTOR (child);
int x, y;
if (!meta_actor_is_untransformed (CLUTTER_ACTOR (window_actor), &x, &y))
continue;
x += paint_x_offset;
y += paint_y_offset;
/* Temporarily move to the coordinate system of the actor */
cairo_region_translate (unobscured_region, - x, - y);
cairo_region_translate (clip_region, - x, - y);
meta_window_actor_set_unobscured_region (window_actor, unobscured_region);
meta_window_actor_set_clip_region (window_actor, clip_region);
if (clutter_actor_get_paint_opacity (CLUTTER_ACTOR (window_actor)) == 0xff)
{
cairo_region_t *obscured_region = meta_window_actor_get_obscured_region (window_actor);
if (obscured_region)
{
cairo_region_subtract (unobscured_region, obscured_region);
cairo_region_subtract (clip_region, obscured_region);
}
}
meta_window_actor_set_clip_region_beneath (window_actor, clip_region);
cairo_region_translate (unobscured_region, x, y);
cairo_region_translate (clip_region, x, y);
}
else if (META_IS_BACKGROUND_ACTOR (child) ||
META_IS_BACKGROUND_GROUP (child))
{
int x, y;
if (!meta_actor_is_untransformed (child, &x, &y))
continue;
x += paint_x_offset;
y += paint_y_offset;
cairo_region_translate (clip_region, - x, - y);
if (META_IS_BACKGROUND_GROUP (child))
meta_background_group_set_clip_region (META_BACKGROUND_GROUP (child), clip_region);
else
meta_background_actor_set_clip_region (META_BACKGROUND_ACTOR (child), clip_region);
cairo_region_translate (clip_region, x, y);
}
}
cairo_region_destroy (unobscured_region); cairo_region_destroy (unobscured_region);
cairo_region_destroy (clip_region); cairo_region_destroy (clip_region);
CLUTTER_ACTOR_CLASS (meta_window_group_parent_class)->paint (actor); CLUTTER_ACTOR_CLASS (meta_window_group_parent_class)->paint (actor);
/* Now that we are done painting, unset the visible regions (they will meta_cullable_reset_culling (META_CULLABLE (window_group));
* mess up painting clones of our actors)
*/
clutter_actor_iter_init (&iter, actor);
while (clutter_actor_iter_next (&iter, &child))
{
if (META_IS_WINDOW_ACTOR (child))
{
MetaWindowActor *window_actor = META_WINDOW_ACTOR (child);
meta_window_actor_reset_clip_regions (window_actor);
}
else if (META_IS_BACKGROUND_ACTOR (child))
{
MetaBackgroundActor *background_actor = META_BACKGROUND_ACTOR (child);
meta_background_actor_set_clip_region (background_actor, NULL);
}
}
} }
/* Adapted from clutter_actor_update_default_paint_volume() */
static gboolean static gboolean
meta_window_group_get_paint_volume (ClutterActor *actor, meta_window_group_get_paint_volume (ClutterActor *self,
ClutterPaintVolume *volume) ClutterPaintVolume *volume)
{ {
return clutter_paint_volume_set_from_allocation (volume, actor); ClutterActorIter iter;
ClutterActor *child;
clutter_actor_iter_init (&iter, self);
while (clutter_actor_iter_next (&iter, &child))
{
const ClutterPaintVolume *child_volume;
if (!CLUTTER_ACTOR_IS_MAPPED (child))
continue;
child_volume = clutter_actor_get_transformed_paint_volume (child, self);
if (child_volume == NULL)
return FALSE;
clutter_paint_volume_union (volume, child_volume);
}
return TRUE;
} }
static void static void

View File

@@ -11,29 +11,9 @@
* MetaWindowGroup: * MetaWindowGroup:
* *
* This class is a subclass of ClutterActor with special handling for * This class is a subclass of ClutterActor with special handling for
* MetaWindowActor/MetaBackgroundActor/MetaBackgroundGroup when painting * #MetaCullable when painting children. It uses code similar to
* children. * meta_cullable_cull_out_children(), but also has additional special
* * cases for the undirected window, and similar.
* When we are painting a stack of 5-10 maximized windows, the
* standard bottom-to-top method of drawing every actor results in a
* tremendous amount of overdraw and can easily max out the available
* memory bandwidth on a low-end graphics chipset. It's even worse if
* window textures are being accessed over the AGP bus.
*
* The basic technique applied here is to do a pre-pass before painting
* where we walk window from top to bottom and compute the visible area
* at each step by subtracting out the windows above it. The visible
* area is passed to MetaWindowActor which uses it to clip the portion of
* the window which drawn and avoid redrawing the shadow if it is completely
* obscured.
*
* A caveat is that this is ineffective if applications are using ARGB
* visuals, since we have no way of knowing whether a window obscures
* the windows behind it or not. Alternate approaches using the depth
* or stencil buffer rather than client side regions might be able to
* handle alpha windows, but the combination of glAlphaFunc and stenciling
* tends not to be efficient except on newer cards. (And on newer cards
* we have lots of memory and bandwidth.)
*/ */
#define META_TYPE_WINDOW_GROUP (meta_window_group_get_type ()) #define META_TYPE_WINDOW_GROUP (meta_window_group_get_type ())

View File

@@ -118,8 +118,6 @@ typedef struct
{ {
MetaRectangle orig; MetaRectangle orig;
MetaRectangle current; MetaRectangle current;
MetaFrameBorders *borders;
gboolean must_free_borders;
ActionType action_type; ActionType action_type;
gboolean is_user_action; gboolean is_user_action;
@@ -195,7 +193,6 @@ static gboolean constrain_partially_onscreen (MetaWindow *window,
static void setup_constraint_info (ConstraintInfo *info, static void setup_constraint_info (ConstraintInfo *info,
MetaWindow *window, MetaWindow *window,
MetaFrameBorders *orig_borders,
MetaMoveResizeFlags flags, MetaMoveResizeFlags flags,
int resize_gravity, int resize_gravity,
const MetaRectangle *orig, const MetaRectangle *orig,
@@ -204,13 +201,12 @@ static void place_window_if_needed (MetaWindow *window,
ConstraintInfo *info); ConstraintInfo *info);
static void update_onscreen_requirements (MetaWindow *window, static void update_onscreen_requirements (MetaWindow *window,
ConstraintInfo *info); ConstraintInfo *info);
static void extend_by_frame (MetaRectangle *rect, static void extend_by_frame (MetaWindow *window,
const MetaFrameBorders *borders); MetaRectangle *rect);
static void unextend_by_frame (MetaRectangle *rect, static void unextend_by_frame (MetaWindow *window,
const MetaFrameBorders *borders); MetaRectangle *rect);
static inline void get_size_limits (const MetaWindow *window, static inline void get_size_limits (MetaWindow *window,
const MetaFrameBorders *borders, gboolean include_frame,
gboolean include_frame,
MetaRectangle *min_size, MetaRectangle *min_size,
MetaRectangle *max_size); MetaRectangle *max_size);
@@ -280,7 +276,6 @@ do_all_constraints (MetaWindow *window,
void void
meta_window_constrain (MetaWindow *window, meta_window_constrain (MetaWindow *window,
MetaFrameBorders *orig_borders,
MetaMoveResizeFlags flags, MetaMoveResizeFlags flags,
int resize_gravity, int resize_gravity,
const MetaRectangle *orig, const MetaRectangle *orig,
@@ -303,7 +298,6 @@ meta_window_constrain (MetaWindow *window,
setup_constraint_info (&info, setup_constraint_info (&info,
window, window,
orig_borders,
flags, flags,
resize_gravity, resize_gravity,
orig, orig,
@@ -333,19 +327,11 @@ meta_window_constrain (MetaWindow *window,
* if this was a user move or user move-and-resize operation. * if this was a user move or user move-and-resize operation.
*/ */
update_onscreen_requirements (window, &info); update_onscreen_requirements (window, &info);
/* Ew, what an ugly way to do things. Destructors (in a real OOP language,
* not gobject-style--gobject would be more pain than it's worth) or
* smart pointers would be so much nicer here. *shrug*
*/
if (info.must_free_borders)
g_free (info.borders);
} }
static void static void
setup_constraint_info (ConstraintInfo *info, setup_constraint_info (ConstraintInfo *info,
MetaWindow *window, MetaWindow *window,
MetaFrameBorders *orig_borders,
MetaMoveResizeFlags flags, MetaMoveResizeFlags flags,
int resize_gravity, int resize_gravity,
const MetaRectangle *orig, const MetaRectangle *orig,
@@ -357,18 +343,6 @@ setup_constraint_info (ConstraintInfo *info,
info->orig = *orig; info->orig = *orig;
info->current = *new; info->current = *new;
/* Create a fake frame geometry if none really exists */
if (orig_borders && !window->fullscreen)
{
info->borders = orig_borders;
info->must_free_borders = FALSE;
}
else
{
info->borders = g_new0 (MetaFrameBorders, 1);
info->must_free_borders = TRUE;
}
if (flags & META_IS_MOVE_ACTION && flags & META_IS_RESIZE_ACTION) if (flags & META_IS_MOVE_ACTION && flags & META_IS_RESIZE_ACTION)
info->action_type = ACTION_MOVE_AND_RESIZE; info->action_type = ACTION_MOVE_AND_RESIZE;
else if (flags & META_IS_RESIZE_ACTION) else if (flags & META_IS_RESIZE_ACTION)
@@ -519,11 +493,12 @@ place_window_if_needed(MetaWindow *window,
!window->minimized && !window->minimized &&
!window->fullscreen) !window->fullscreen)
{ {
MetaRectangle placed_rect = info->orig; MetaRectangle placed_rect;
MetaWorkspace *cur_workspace; MetaWorkspace *cur_workspace;
const MetaMonitorInfo *monitor_info; const MetaMonitorInfo *monitor_info;
meta_window_place (window, info->borders, info->orig.x, info->orig.y, meta_window_get_frame_rect (window, &placed_rect);
meta_window_place (window, info->orig.x, info->orig.y,
&placed_rect.x, &placed_rect.y); &placed_rect.x, &placed_rect.y);
did_placement = TRUE; did_placement = TRUE;
@@ -541,6 +516,7 @@ place_window_if_needed(MetaWindow *window,
meta_workspace_get_onmonitor_region (cur_workspace, meta_workspace_get_onmonitor_region (cur_workspace,
monitor_info->number); monitor_info->number);
meta_window_frame_rect_to_client_rect (window, &placed_rect, &placed_rect);
info->current.x = placed_rect.x; info->current.x = placed_rect.x;
info->current.y = placed_rect.y; info->current.y = placed_rect.y;
@@ -586,10 +562,6 @@ place_window_if_needed(MetaWindow *window,
(window->maximize_vertically_after_placement ? (window->maximize_vertically_after_placement ?
META_MAXIMIZE_VERTICAL : 0), &info->current); META_MAXIMIZE_VERTICAL : 0), &info->current);
/* maximization may have changed frame geometry */
if (!window->fullscreen)
meta_frame_calc_borders (window->frame, info->borders);
if (window->fullscreen_after_placement) if (window->fullscreen_after_placement)
{ {
window->saved_rect = info->current; window->saved_rect = info->current;
@@ -649,7 +621,7 @@ update_onscreen_requirements (MetaWindow *window,
/* The require onscreen/on-single-monitor and titlebar_visible /* The require onscreen/on-single-monitor and titlebar_visible
* stuff is relative to the outer window, not the inner * stuff is relative to the outer window, not the inner
*/ */
extend_by_frame (&info->current, info->borders); extend_by_frame (window, &info->current);
/* Update whether we want future constraint runs to require the /* Update whether we want future constraint runs to require the
* window to be on fully onscreen. * window to be on fully onscreen.
@@ -682,10 +654,13 @@ update_onscreen_requirements (MetaWindow *window,
*/ */
if (window->frame && window->decorated) if (window->frame && window->decorated)
{ {
MetaFrameBorders borders;
MetaRectangle titlebar_rect; MetaRectangle titlebar_rect;
meta_frame_calc_borders (window->frame, &borders);
titlebar_rect = info->current; titlebar_rect = info->current;
titlebar_rect.height = info->borders->visible.top; titlebar_rect.height = borders.visible.top;
old = window->require_titlebar_visible; old = window->require_titlebar_visible;
window->require_titlebar_visible = window->require_titlebar_visible =
meta_rectangle_overlaps_with_region (info->usable_screen_region, meta_rectangle_overlaps_with_region (info->usable_screen_region,
@@ -698,39 +673,33 @@ update_onscreen_requirements (MetaWindow *window,
} }
/* Don't forget to restore the position of the window */ /* Don't forget to restore the position of the window */
unextend_by_frame (&info->current, info->borders); unextend_by_frame (window, &info->current);
} }
static void static void
extend_by_frame (MetaRectangle *rect, extend_by_frame (MetaWindow *window,
const MetaFrameBorders *borders) MetaRectangle *rect)
{ {
rect->x -= borders->visible.left; meta_window_client_rect_to_frame_rect (window, rect, rect);
rect->y -= borders->visible.top;
rect->width += borders->visible.left + borders->visible.right;
rect->height += borders->visible.top + borders->visible.bottom;
} }
static void static void
unextend_by_frame (MetaRectangle *rect, unextend_by_frame (MetaWindow *window,
const MetaFrameBorders *borders) MetaRectangle *rect)
{ {
rect->x += borders->visible.left; meta_window_frame_rect_to_client_rect (window, rect, rect);
rect->y += borders->visible.top;
rect->width -= borders->visible.left + borders->visible.right;
rect->height -= borders->visible.top + borders->visible.bottom;
} }
static inline void static inline void
get_size_limits (const MetaWindow *window, get_size_limits (MetaWindow *window,
const MetaFrameBorders *borders, gboolean include_frame,
gboolean include_frame,
MetaRectangle *min_size, MetaRectangle *min_size,
MetaRectangle *max_size) MetaRectangle *max_size)
{ {
/* We pack the results into MetaRectangle structs just for convienience; we /* We pack the results into MetaRectangle structs just for convienience; we
* don't actually use the position of those rects. * don't actually use the position of those rects.
*/ */
min_size->x = min_size->y = max_size->x = max_size->y = 0;
min_size->width = window->size_hints.min_width; min_size->width = window->size_hints.min_width;
min_size->height = window->size_hints.min_height; min_size->height = window->size_hints.min_height;
max_size->width = window->size_hints.max_width; max_size->width = window->size_hints.max_width;
@@ -738,22 +707,8 @@ get_size_limits (const MetaWindow *window,
if (include_frame) if (include_frame)
{ {
int fw = borders->visible.left + borders->visible.right; meta_window_client_rect_to_frame_rect (window, min_size, min_size);
int fh = borders->visible.top + borders->visible.bottom; meta_window_client_rect_to_frame_rect (window, max_size, max_size);
min_size->width += fw;
min_size->height += fh;
/* Do check to avoid overflow (e.g. max_size->width & max_size->height
* may be set to G_MAXINT by meta_set_normal_hints()).
*/
if (max_size->width < (G_MAXINT - fw))
max_size->width += fw;
else
max_size->width = G_MAXINT;
if (max_size->height < (G_MAXINT - fh))
max_size->height += fh;
else
max_size->height = G_MAXINT;
} }
} }
@@ -765,18 +720,28 @@ constrain_modal_dialog (MetaWindow *window,
{ {
int x, y; int x, y;
MetaWindow *parent = meta_window_get_transient_for (window); MetaWindow *parent = meta_window_get_transient_for (window);
MetaRectangle child_rect, parent_rect;
gboolean constraint_already_satisfied; gboolean constraint_already_satisfied;
if (!meta_window_is_attached_dialog (window)) if (!meta_window_is_attached_dialog (window))
return TRUE; return TRUE;
x = parent->rect.x + (parent->rect.width / 2 - info->current.width / 2); /* We want to center the dialog on the parent, including the decorations
y = parent->rect.y + (parent->rect.height / 2 - info->current.height / 2); for both of them. info->current is in client X window coordinates, so we need
if (parent->frame) to convert them to frame coordinates, apply the centering and then
{ convert back to client.
x += parent->frame->rect.x; */
y += parent->frame->rect.y;
} child_rect = info->current;
extend_by_frame (window, &child_rect);
meta_window_get_frame_rect (parent, &parent_rect);
child_rect.x = parent_rect.x + (parent_rect.width / 2 - child_rect.width / 2);
child_rect.y = parent_rect.y + (parent_rect.height / 2 - child_rect.height / 2);
unextend_by_frame (window, &child_rect);
x = child_rect.x;
y = child_rect.y;
constraint_already_satisfied = (x == info->current.x) && (y == info->current.y); constraint_already_satisfied = (x == info->current.x) && (y == info->current.y);
@@ -841,19 +806,19 @@ constrain_maximization (MetaWindow *window,
active_workspace_struts = window->screen->active_workspace->all_struts; active_workspace_struts = window->screen->active_workspace->all_struts;
target_size = info->current; target_size = info->current;
extend_by_frame (&target_size, info->borders); extend_by_frame (window, &target_size);
meta_rectangle_expand_to_avoiding_struts (&target_size, meta_rectangle_expand_to_avoiding_struts (&target_size,
&info->entire_monitor, &info->entire_monitor,
direction, direction,
active_workspace_struts); active_workspace_struts);
} }
/* Now make target_size = maximized size of client window */ /* Now make target_size = maximized size of client window */
unextend_by_frame (&target_size, info->borders); unextend_by_frame (window, &target_size);
/* Check min size constraints; max size constraints are ignored for maximized /* Check min size constraints; max size constraints are ignored for maximized
* windows, as per bug 327543. * windows, as per bug 327543.
*/ */
get_size_limits (window, info->borders, FALSE, &min_size, &max_size); get_size_limits (window, FALSE, &min_size, &max_size);
hminbad = target_size.width < min_size.width && window->maximized_horizontally; hminbad = target_size.width < min_size.width && window->maximized_horizontally;
vminbad = target_size.height < min_size.height && window->maximized_vertically; vminbad = target_size.height < min_size.height && window->maximized_vertically;
if (hminbad || vminbad) if (hminbad || vminbad)
@@ -907,12 +872,12 @@ constrain_tiling (MetaWindow *window,
* use an external function for the actual calculation * use an external function for the actual calculation
*/ */
meta_window_get_current_tile_area (window, &target_size); meta_window_get_current_tile_area (window, &target_size);
unextend_by_frame (&target_size, info->borders); unextend_by_frame (window, &target_size);
/* Check min size constraints; max size constraints are ignored as for /* Check min size constraints; max size constraints are ignored as for
* maximized windows. * maximized windows.
*/ */
get_size_limits (window, info->borders, FALSE, &min_size, &max_size); get_size_limits (window, FALSE, &min_size, &max_size);
hminbad = target_size.width < min_size.width; hminbad = target_size.width < min_size.width;
vminbad = target_size.height < min_size.height; vminbad = target_size.height < min_size.height;
if (hminbad || vminbad) if (hminbad || vminbad)
@@ -955,7 +920,7 @@ constrain_fullscreen (MetaWindow *window,
monitor = info->entire_monitor; monitor = info->entire_monitor;
get_size_limits (window, info->borders, FALSE, &min_size, &max_size); get_size_limits (window, FALSE, &min_size, &max_size);
too_big = !meta_rectangle_could_fit_rect (&monitor, &min_size); too_big = !meta_rectangle_could_fit_rect (&monitor, &min_size);
too_small = !meta_rectangle_could_fit_rect (&max_size, &monitor); too_small = !meta_rectangle_could_fit_rect (&max_size, &monitor);
if (too_big || too_small) if (too_big || too_small)
@@ -1064,7 +1029,7 @@ constrain_size_limits (MetaWindow *window,
return TRUE; return TRUE;
/* Determine whether constraint is already satisfied; exit if it is */ /* Determine whether constraint is already satisfied; exit if it is */
get_size_limits (window, info->borders, FALSE, &min_size, &max_size); get_size_limits (window, FALSE, &min_size, &max_size);
/* We ignore max-size limits for maximized windows; see #327543 */ /* We ignore max-size limits for maximized windows; see #327543 */
if (window->maximized_horizontally) if (window->maximized_horizontally)
max_size.width = MAX (max_size.width, info->current.width); max_size.width = MAX (max_size.width, info->current.width);
@@ -1256,8 +1221,8 @@ do_screen_and_monitor_relative_constraints (
/* Determine whether constraint applies; exit if it doesn't */ /* Determine whether constraint applies; exit if it doesn't */
how_far_it_can_be_smushed = info->current; how_far_it_can_be_smushed = info->current;
get_size_limits (window, info->borders, TRUE, &min_size, &max_size); get_size_limits (window, TRUE, &min_size, &max_size);
extend_by_frame (&info->current, info->borders); extend_by_frame (window, &info->current);
if (info->action_type != ACTION_MOVE) if (info->action_type != ACTION_MOVE)
{ {
@@ -1277,7 +1242,7 @@ do_screen_and_monitor_relative_constraints (
&info->current); &info->current);
if (exit_early || constraint_satisfied || check_only) if (exit_early || constraint_satisfied || check_only)
{ {
unextend_by_frame (&info->current, info->borders); unextend_by_frame (window, &info->current);
return constraint_satisfied; return constraint_satisfied;
} }
@@ -1301,7 +1266,7 @@ do_screen_and_monitor_relative_constraints (
info->fixed_directions, info->fixed_directions,
&info->current); &info->current);
unextend_by_frame (&info->current, info->borders); unextend_by_frame (window, &info->current);
return TRUE; return TRUE;
} }
@@ -1414,8 +1379,11 @@ constrain_titlebar_visible (MetaWindow *window,
*/ */
if (window->frame) if (window->frame)
{ {
bottom_amount = info->current.height + info->borders->visible.bottom; MetaFrameBorders borders;
vert_amount_onscreen = info->borders->visible.top; meta_frame_calc_borders (window->frame, &borders);
bottom_amount = info->current.height + borders.visible.bottom;
vert_amount_onscreen = borders.visible.top;
} }
else else
bottom_amount = vert_amount_offscreen; bottom_amount = vert_amount_offscreen;
@@ -1489,8 +1457,11 @@ constrain_partially_onscreen (MetaWindow *window,
*/ */
if (window->frame) if (window->frame)
{ {
bottom_amount = info->current.height + info->borders->visible.bottom; MetaFrameBorders borders;
vert_amount_onscreen = info->borders->visible.top; meta_frame_calc_borders (window->frame, &borders);
bottom_amount = info->current.height + borders.visible.bottom;
vert_amount_onscreen = borders.visible.top;
} }
else else
bottom_amount = vert_amount_offscreen; bottom_amount = vert_amount_offscreen;

View File

@@ -39,7 +39,6 @@ typedef enum
} MetaMoveResizeFlags; } MetaMoveResizeFlags;
void meta_window_constrain (MetaWindow *window, void meta_window_constrain (MetaWindow *window,
MetaFrameBorders *orig_borders,
MetaMoveResizeFlags flags, MetaMoveResizeFlags flags,
int resize_gravity, int resize_gravity,
const MetaRectangle *orig, const MetaRectangle *orig,

View File

@@ -171,6 +171,7 @@ meta_core_queue_frame_resize (Display *xdisplay,
MetaWindow *window = get_window (xdisplay, frame_xwindow); MetaWindow *window = get_window (xdisplay, frame_xwindow);
meta_window_queue (window, META_QUEUE_MOVE_RESIZE); meta_window_queue (window, META_QUEUE_MOVE_RESIZE);
meta_window_frame_size_changed (window);
} }
void void
@@ -279,8 +280,7 @@ meta_core_lower_beneath_grab_window (Display *xdisplay,
return; return;
changes.stack_mode = Below; changes.stack_mode = Below;
changes.sibling = grab_window->frame ? grab_window->frame->xwindow changes.sibling = meta_window_get_toplevel_xwindow (grab_window);
: grab_window->xwindow;
meta_stack_tracker_record_lower_below (screen->stack_tracker, meta_stack_tracker_record_lower_below (screen->stack_tracker,
xwindow, xwindow,
@@ -469,26 +469,6 @@ meta_core_change_workspace (Display *xdisplay,
new_workspace)); new_workspace));
} }
int
meta_core_get_num_workspaces (Screen *xscreen)
{
MetaScreen *screen;
screen = meta_screen_for_x_screen (xscreen);
return meta_screen_get_n_workspaces (screen);
}
int
meta_core_get_active_workspace (Screen *xscreen)
{
MetaScreen *screen;
screen = meta_screen_for_x_screen (xscreen);
return meta_workspace_index (screen->active_workspace);
}
void void
meta_core_show_window_menu (Display *xdisplay, meta_core_show_window_menu (Display *xdisplay,
Window frame_xwindow, Window frame_xwindow,

View File

@@ -153,8 +153,6 @@ void meta_core_change_workspace (Display *xdisplay,
Window frame_xwindow, Window frame_xwindow,
int new_workspace); int new_workspace);
int meta_core_get_num_workspaces (Screen *xscreen);
int meta_core_get_active_workspace (Screen *xscreen);
int meta_core_get_frame_workspace (Display *xdisplay, int meta_core_get_frame_workspace (Display *xdisplay,
Window frame_xwindow); Window frame_xwindow);
const char* meta_core_get_workspace_name_with_index (Display *xdisplay, const char* meta_core_get_workspace_name_with_index (Display *xdisplay,

View File

@@ -51,7 +51,6 @@
#include <meta/compositor.h> #include <meta/compositor.h>
#include <meta/compositor-mutter.h> #include <meta/compositor-mutter.h>
#include <X11/Xatom.h> #include <X11/Xatom.h>
#include <X11/cursorfont.h>
#include "mutter-enum-types.h" #include "mutter-enum-types.h"
#include "meta-idle-monitor-private.h" #include "meta-idle-monitor-private.h"
@@ -118,12 +117,6 @@ typedef struct
guint ping_timeout_id; guint ping_timeout_id;
} MetaPingData; } MetaPingData;
typedef struct
{
MetaDisplay *display;
Window xwindow;
} MetaAutoRaiseData;
typedef struct typedef struct
{ {
MetaDisplay *display; MetaDisplay *display;
@@ -1586,23 +1579,10 @@ reset_ignored_crossing_serials (MetaDisplay *display)
static gboolean static gboolean
window_raise_with_delay_callback (void *data) window_raise_with_delay_callback (void *data)
{ {
MetaWindow *window; MetaWindow *window = data;
MetaAutoRaiseData *auto_raise;
auto_raise = data; window->display->autoraise_timeout_id = 0;
window->display->autoraise_window = NULL;
meta_topic (META_DEBUG_FOCUS,
"In autoraise callback for window 0x%lx\n",
auto_raise->xwindow);
auto_raise->display->autoraise_timeout_id = 0;
auto_raise->display->autoraise_window = NULL;
window = meta_display_lookup_x_window (auto_raise->display,
auto_raise->xwindow);
if (window == NULL)
return FALSE;
/* If we aren't already on top, check whether the pointer is inside /* If we aren't already on top, check whether the pointer is inside
* the window and raise the window if so. * the window and raise the window if so.
@@ -1611,6 +1591,7 @@ window_raise_with_delay_callback (void *data)
{ {
int x, y, root_x, root_y; int x, y, root_x, root_y;
Window root, child; Window root, child;
MetaRectangle frame_rect;
unsigned int mask; unsigned int mask;
gboolean same_screen; gboolean same_screen;
gboolean point_in_window; gboolean point_in_window;
@@ -1622,9 +1603,8 @@ window_raise_with_delay_callback (void *data)
&root_x, &root_y, &x, &y, &mask); &root_x, &root_y, &x, &y, &mask);
meta_error_trap_pop (window->display); meta_error_trap_pop (window->display);
point_in_window = meta_window_get_frame_rect (window, &frame_rect);
(window->frame && POINT_IN_RECT (root_x, root_y, window->frame->rect)) || point_in_window = POINT_IN_RECT (root_x, root_y, frame_rect);
(window->frame == NULL && POINT_IN_RECT (root_x, root_y, window->rect));
if (same_screen && point_in_window) if (same_screen && point_in_window)
meta_window_raise (window); meta_window_raise (window);
else else
@@ -1639,7 +1619,8 @@ window_raise_with_delay_callback (void *data)
static void static void
meta_display_mouse_mode_focus (MetaDisplay *display, meta_display_mouse_mode_focus (MetaDisplay *display,
MetaWindow *window, MetaWindow *window,
guint32 timestamp) { guint32 timestamp)
{
if (window->type != META_WINDOW_DESKTOP) if (window->type != META_WINDOW_DESKTOP)
{ {
meta_topic (META_DEBUG_FOCUS, meta_topic (META_DEBUG_FOCUS,
@@ -1678,7 +1659,8 @@ meta_display_mouse_mode_focus (MetaDisplay *display,
} }
static gboolean static gboolean
window_focus_on_pointer_rest_callback (gpointer data) { window_focus_on_pointer_rest_callback (gpointer data)
{
MetaFocusData *focus_data; MetaFocusData *focus_data;
MetaDisplay *display; MetaDisplay *display;
MetaScreen *screen; MetaScreen *screen;
@@ -1723,9 +1705,9 @@ window_focus_on_pointer_rest_callback (gpointer data) {
goto out; goto out;
window = window =
meta_stack_get_default_focus_window_at_point (screen->stack, meta_stack_get_default_focus_window_at_point (screen->stack,
screen->active_workspace, screen->active_workspace,
None, root_x, root_y); None, root_x, root_y);
if (window == NULL) if (window == NULL)
goto out; goto out;
@@ -1733,7 +1715,7 @@ window_focus_on_pointer_rest_callback (gpointer data) {
timestamp = meta_display_get_current_time_roundtrip (display); timestamp = meta_display_get_current_time_roundtrip (display);
meta_display_mouse_mode_focus (display, window, timestamp); meta_display_mouse_mode_focus (display, window, timestamp);
out: out:
display->focus_timeout_id = 0; display->focus_timeout_id = 0;
return FALSE; return FALSE;
} }
@@ -1742,17 +1724,11 @@ void
meta_display_queue_autoraise_callback (MetaDisplay *display, meta_display_queue_autoraise_callback (MetaDisplay *display,
MetaWindow *window) MetaWindow *window)
{ {
MetaAutoRaiseData *auto_raise_data;
meta_topic (META_DEBUG_FOCUS, meta_topic (META_DEBUG_FOCUS,
"Queuing an autoraise timeout for %s with delay %d\n", "Queuing an autoraise timeout for %s with delay %d\n",
window->desc, window->desc,
meta_prefs_get_auto_raise_delay ()); meta_prefs_get_auto_raise_delay ());
auto_raise_data = g_new (MetaAutoRaiseData, 1);
auto_raise_data->display = window->display;
auto_raise_data->xwindow = window->xwindow;
if (display->autoraise_timeout_id != 0) if (display->autoraise_timeout_id != 0)
g_source_remove (display->autoraise_timeout_id); g_source_remove (display->autoraise_timeout_id);
@@ -1760,8 +1736,7 @@ meta_display_queue_autoraise_callback (MetaDisplay *display,
g_timeout_add_full (G_PRIORITY_DEFAULT, g_timeout_add_full (G_PRIORITY_DEFAULT,
meta_prefs_get_auto_raise_delay (), meta_prefs_get_auto_raise_delay (),
window_raise_with_delay_callback, window_raise_with_delay_callback,
auto_raise_data, window, NULL);
g_free);
display->autoraise_window = window; display->autoraise_window = window;
} }
@@ -2126,6 +2101,19 @@ handle_window_focus_event (MetaDisplay *display,
} }
} }
static gboolean
window_has_xwindow (MetaWindow *window,
Window xwindow)
{
if (window->xwindow == xwindow)
return TRUE;
if (window->frame && window->frame->xwindow == xwindow)
return TRUE;
return FALSE;
}
/** /**
* event_callback: * event_callback:
* @event: The event that just happened * @event: The event that just happened
@@ -2181,7 +2169,7 @@ event_callback (XEvent *event,
if (event->xany.serial > display->focus_serial && if (event->xany.serial > display->focus_serial &&
display->focus_window && display->focus_window &&
display->focus_window->xwindow != display->server_focus_window) !window_has_xwindow (display->focus_window, display->server_focus_window))
{ {
meta_topic (META_DEBUG_FOCUS, "Earlier attempt to focus %s failed\n", meta_topic (META_DEBUG_FOCUS, "Earlier attempt to focus %s failed\n",
display->focus_window->desc); display->focus_window->desc);
@@ -2304,7 +2292,7 @@ event_callback (XEvent *event,
XIEnterEvent *enter_event = (XIEnterEvent *) input_event; XIEnterEvent *enter_event = (XIEnterEvent *) input_event;
if (window && !window->override_redirect && if (window && !window->override_redirect &&
((input_event->type == XI_KeyPress) || (input_event->type == XI_ButtonPress))) ((input_event->evtype == XI_KeyPress) || (input_event->evtype == XI_ButtonPress)))
{ {
if (CurrentTime == display->current_time) if (CurrentTime == display->current_time)
{ {
@@ -2436,15 +2424,15 @@ event_callback (XEvent *event,
{ {
gboolean north, south; gboolean north, south;
gboolean west, east; gboolean west, east;
int root_x, root_y; MetaRectangle frame_rect;
MetaGrabOp op; MetaGrabOp op;
meta_window_get_position (window, &root_x, &root_y); meta_window_get_frame_rect (window, &frame_rect);
west = device_event->root_x < (root_x + 1 * window->rect.width / 3); west = device_event->root_x < (frame_rect.x + 1 * frame_rect.width / 3);
east = device_event->root_x > (root_x + 2 * window->rect.width / 3); east = device_event->root_x > (frame_rect.x + 2 * frame_rect.width / 3);
north = device_event->root_y < (root_y + 1 * window->rect.height / 3); north = device_event->root_y < (frame_rect.y + 1 * frame_rect.height / 3);
south = device_event->root_y > (root_y + 2 * window->rect.height / 3); south = device_event->root_y > (frame_rect.y + 2 * frame_rect.height / 3);
if (north && west) if (north && west)
op = META_GRAB_OP_RESIZING_NW; op = META_GRAB_OP_RESIZING_NW;
@@ -3859,85 +3847,6 @@ meta_display_xwindow_is_a_no_focus_window (MetaDisplay *display,
return is_a_no_focus_window; return is_a_no_focus_window;
} }
Cursor
meta_display_create_x_cursor (MetaDisplay *display,
MetaCursor cursor)
{
Cursor xcursor;
guint glyph = XC_num_glyphs;
const char *name = NULL;
switch (cursor)
{
case META_CURSOR_DEFAULT:
glyph = XC_left_ptr;
break;
case META_CURSOR_NORTH_RESIZE:
glyph = XC_top_side;
break;
case META_CURSOR_SOUTH_RESIZE:
glyph = XC_bottom_side;
break;
case META_CURSOR_WEST_RESIZE:
glyph = XC_left_side;
break;
case META_CURSOR_EAST_RESIZE:
glyph = XC_right_side;
break;
case META_CURSOR_SE_RESIZE:
glyph = XC_bottom_right_corner;
break;
case META_CURSOR_SW_RESIZE:
glyph = XC_bottom_left_corner;
break;
case META_CURSOR_NE_RESIZE:
glyph = XC_top_right_corner;
break;
case META_CURSOR_NW_RESIZE:
glyph = XC_top_left_corner;
break;
case META_CURSOR_MOVE_OR_RESIZE_WINDOW:
glyph = XC_fleur;
break;
case META_CURSOR_BUSY:
glyph = XC_watch;
break;
case META_CURSOR_DND_IN_DRAG:
name = "dnd-none";
break;
case META_CURSOR_DND_MOVE:
name = "dnd-move";
break;
case META_CURSOR_DND_COPY:
name = "dnd-copy";
break;
case META_CURSOR_DND_UNSUPPORTED_TARGET:
name = "dnd-none";
break;
case META_CURSOR_POINTING_HAND:
glyph = XC_hand2;
break;
case META_CURSOR_CROSSHAIR:
glyph = XC_crosshair;
break;
case META_CURSOR_IBEAM:
glyph = XC_xterm;
break;
default:
g_assert_not_reached ();
glyph = 0; /* silence compiler */
break;
}
if (name != NULL)
xcursor = XcursorLibraryLoadCursor (display->xdisplay, name);
else
xcursor = XCreateFontCursor (display->xdisplay, glyph);
return xcursor;
}
static Cursor static Cursor
xcursor_for_op (MetaDisplay *display, xcursor_for_op (MetaDisplay *display,
MetaGrabOp op) MetaGrabOp op)
@@ -4099,7 +4008,7 @@ meta_display_begin_grab_op (MetaDisplay *display,
* key grab on the RootWindow. * key grab on the RootWindow.
*/ */
if (grab_window) if (grab_window)
grab_xwindow = grab_window->frame ? grab_window->frame->xwindow : grab_window->xwindow; grab_xwindow = meta_window_get_toplevel_xwindow (grab_window);
else else
grab_xwindow = screen->xroot; grab_xwindow = screen->xroot;
@@ -4627,6 +4536,7 @@ meta_display_queue_retheme_all_windows (MetaDisplay *display)
MetaWindow *window = tmp->data; MetaWindow *window = tmp->data;
meta_window_queue (window, META_QUEUE_MOVE_RESIZE); meta_window_queue (window, META_QUEUE_MOVE_RESIZE);
meta_window_frame_size_changed (window);
if (window->frame) if (window->frame)
{ {
meta_frame_queue_draw (window->frame); meta_frame_queue_draw (window->frame);
@@ -5808,25 +5718,6 @@ meta_display_request_take_focus (MetaDisplay *display,
meta_topic (META_DEBUG_FOCUS, "WM_TAKE_FOCUS(%s, %u)\n", meta_topic (META_DEBUG_FOCUS, "WM_TAKE_FOCUS(%s, %u)\n",
window->desc, timestamp); window->desc, timestamp);
if (window != display->focus_window)
{
/* The "Globally Active Input" window case, where the window
* doesn't want us to call XSetInputFocus on it, but does
* want us to send a WM_TAKE_FOCUS.
*
* We can't just set display->focus_window to @window, since we
* we don't know when (or even if) the window will actually take
* focus, so we could end up being wrong for arbitrarily long.
* But we also can't leave it set to the current window, or else
* bug #597352 would come back. So we focus the no_focus_window
* now (and set display->focus_window to that), send the
* WM_TAKE_FOCUS, and then just forget about @window
* until/unless we get a FocusIn.
*/
meta_display_focus_the_no_focus_window (display,
window->screen,
timestamp);
}
meta_window_send_icccm_message (window, meta_window_send_icccm_message (window,
display->atom_WM_TAKE_FOCUS, display->atom_WM_TAKE_FOCUS,
timestamp); timestamp);

View File

@@ -985,7 +985,7 @@ compute_resistance_and_snapping_edges (MetaDisplay *display)
{ {
MetaRectangle *new_rect; MetaRectangle *new_rect;
new_rect = g_new (MetaRectangle, 1); new_rect = g_new (MetaRectangle, 1);
meta_window_get_outer_rect (cur_window, new_rect); meta_window_get_frame_rect (cur_window, new_rect);
obscuring_windows = g_slist_prepend (obscuring_windows, new_rect); obscuring_windows = g_slist_prepend (obscuring_windows, new_rect);
window_stacking = window_stacking =
g_slist_prepend (window_stacking, GINT_TO_POINTER (stack_position)); g_slist_prepend (window_stacking, GINT_TO_POINTER (stack_position));
@@ -1010,7 +1010,7 @@ compute_resistance_and_snapping_edges (MetaDisplay *display)
{ {
MetaRectangle cur_rect; MetaRectangle cur_rect;
MetaWindow *cur_window = cur_window_iter->data; MetaWindow *cur_window = cur_window_iter->data;
meta_window_get_outer_rect (cur_window, &cur_rect); meta_window_get_frame_rect (cur_window, &cur_rect);
/* Check if we want to use this window's edges for edge /* Check if we want to use this window's edges for edge
* resistance (note that dock edges are considered screen edges * resistance (note that dock edges are considered screen edges
@@ -1151,7 +1151,7 @@ meta_window_edge_resistance_for_move (MetaWindow *window,
MetaRectangle old_outer, proposed_outer, new_outer; MetaRectangle old_outer, proposed_outer, new_outer;
gboolean is_resize; gboolean is_resize;
meta_window_get_outer_rect (window, &old_outer); meta_window_get_frame_rect (window, &old_outer);
proposed_outer = old_outer; proposed_outer = old_outer;
proposed_outer.x += (*new_x - old_x); proposed_outer.x += (*new_x - old_x);
@@ -1237,7 +1237,7 @@ meta_window_edge_resistance_for_resize (MetaWindow *window,
int proposed_outer_width, proposed_outer_height; int proposed_outer_width, proposed_outer_height;
gboolean is_resize; gboolean is_resize;
meta_window_get_outer_rect (window, &old_outer); meta_window_get_frame_rect (window, &old_outer);
proposed_outer_width = old_outer.width + (*new_width - old_width); proposed_outer_width = old_outer.width + (*new_width - old_width);
proposed_outer_height = old_outer.height + (*new_height - old_height); proposed_outer_height = old_outer.height + (*new_height - old_height);
meta_rectangle_resize_with_gravity (&old_outer, meta_rectangle_resize_with_gravity (&old_outer,

View File

@@ -68,6 +68,7 @@ meta_window_ensure_frame (MetaWindow *window)
frame->mapped = FALSE; frame->mapped = FALSE;
frame->is_flashing = FALSE; frame->is_flashing = FALSE;
frame->borders_cached = FALSE;
meta_verbose ("Framing window %s: visual %s default, depth %d default depth %d\n", meta_verbose ("Framing window %s: visual %s default, depth %d default depth %d\n",
window->desc, window->desc,
@@ -327,9 +328,23 @@ meta_frame_calc_borders (MetaFrame *frame,
if (frame == NULL) if (frame == NULL)
meta_frame_borders_clear (borders); meta_frame_borders_clear (borders);
else else
meta_ui_get_frame_borders (frame->window->screen->ui, {
frame->xwindow, if (!frame->borders_cached)
borders); {
meta_ui_get_frame_borders (frame->window->screen->ui,
frame->xwindow,
&frame->cached_borders);
frame->borders_cached = TRUE;
}
*borders = frame->cached_borders;
}
}
void
meta_frame_clear_cached_borders (MetaFrame *frame)
{
frame->borders_cached = FALSE;
} }
gboolean gboolean

View File

@@ -41,6 +41,8 @@ struct _MetaFrame
*/ */
MetaRectangle rect; MetaRectangle rect;
MetaFrameBorders cached_borders; /* valid if borders_cached is set */
/* position of client, size of frame */ /* position of client, size of frame */
int child_x; int child_x;
int child_y; int child_y;
@@ -50,6 +52,7 @@ struct _MetaFrame
guint mapped : 1; guint mapped : 1;
guint need_reapply_frame_shape : 1; guint need_reapply_frame_shape : 1;
guint is_flashing : 1; /* used by the visual bell flash */ guint is_flashing : 1; /* used by the visual bell flash */
guint borders_cached : 1;
}; };
void meta_window_ensure_frame (MetaWindow *window); void meta_window_ensure_frame (MetaWindow *window);
@@ -68,6 +71,8 @@ gboolean meta_frame_sync_to_window (MetaFrame *frame,
gboolean need_move, gboolean need_move,
gboolean need_resize); gboolean need_resize);
void meta_frame_clear_cached_borders (MetaFrame *frame);
cairo_region_t *meta_frame_get_frame_bounds (MetaFrame *frame); cairo_region_t *meta_frame_get_frame_bounds (MetaFrame *frame);
void meta_frame_get_mask (MetaFrame *frame, void meta_frame_get_mask (MetaFrame *frame,

View File

@@ -1277,7 +1277,7 @@ meta_window_grab_keys (MetaWindow *window)
} }
meta_window_change_keygrabs (window, meta_window_change_keygrabs (window,
window->frame ? window->frame->xwindow : window->xwindow, meta_window_get_toplevel_xwindow (window),
TRUE); TRUE);
window->keys_grabbed = TRUE; window->keys_grabbed = TRUE;
@@ -1580,7 +1580,7 @@ meta_window_grab_all_keys (MetaWindow *window,
window->desc); window->desc);
meta_window_focus (window, timestamp); meta_window_focus (window, timestamp);
grabwindow = window->frame ? window->frame->xwindow : window->xwindow; grabwindow = meta_window_get_toplevel_xwindow (window);
meta_topic (META_DEBUG_KEYBINDINGS, meta_topic (META_DEBUG_KEYBINDINGS,
"Grabbing all keys on window %s\n", window->desc); "Grabbing all keys on window %s\n", window->desc);
@@ -1835,7 +1835,6 @@ invoke_handler_by_name (MetaDisplay *display,
invoke_handler (display, screen, handler, window, event, NULL); invoke_handler (display, screen, handler, window, event, NULL);
} }
/* now called from only one place, may be worth merging */
static gboolean static gboolean
process_event (MetaKeyBinding *bindings, process_event (MetaKeyBinding *bindings,
int n_bindings, int n_bindings,
@@ -1843,7 +1842,6 @@ process_event (MetaKeyBinding *bindings,
MetaScreen *screen, MetaScreen *screen,
MetaWindow *window, MetaWindow *window,
XIDeviceEvent *event, XIDeviceEvent *event,
KeySym keysym,
gboolean on_window) gboolean on_window)
{ {
int i; int i;
@@ -1861,7 +1859,6 @@ process_event (MetaKeyBinding *bindings,
MetaKeyHandler *handler = bindings[i].handler; MetaKeyHandler *handler = bindings[i].handler;
if ((!on_window && handler->flags & META_KEY_BINDING_PER_WINDOW) || if ((!on_window && handler->flags & META_KEY_BINDING_PER_WINDOW) ||
event->evtype != XI_KeyPress ||
bindings[i].keycode != event->detail || bindings[i].keycode != event->detail ||
((event->mods.effective & 0xff & ~(display->ignored_modifier_mask)) != ((event->mods.effective & 0xff & ~(display->ignored_modifier_mask)) !=
bindings[i].mask) || bindings[i].mask) ||
@@ -1928,7 +1925,7 @@ process_overlay_key (MetaDisplay *display,
*/ */
if (process_event (display->key_bindings, if (process_event (display->key_bindings,
display->n_key_bindings, display->n_key_bindings,
display, screen, NULL, event, keysym, display, screen, NULL, event,
FALSE)) FALSE))
{ {
/* As normally, after we've handled a global key /* As normally, after we've handled a global key
@@ -2192,7 +2189,7 @@ meta_display_process_key_event (MetaDisplay *display,
/* Do the normal keybindings */ /* Do the normal keybindings */
return process_event (display->key_bindings, return process_event (display->key_bindings,
display->n_key_bindings, display->n_key_bindings,
display, screen, window, event, keysym, display, screen, window, event,
!all_keys_grabbed && window); !all_keys_grabbed && window);
} }
@@ -3140,6 +3137,20 @@ handle_maximize_horizontally (MetaDisplay *display,
} }
} }
static void
handle_always_on_top (MetaDisplay *display,
MetaScreen *screen,
MetaWindow *window,
XIDeviceEvent *event,
MetaKeyBinding *binding,
gpointer dummy)
{
if (window->wm_state_above == FALSE)
meta_window_make_above (window);
else
meta_window_unmake_above (window);
}
/* Move a window to a corner; to_bottom/to_right are FALSE for the /* Move a window to a corner; to_bottom/to_right are FALSE for the
* top or left edge, or TRUE for the bottom/right edge. xchange/ychange * top or left edge, or TRUE for the bottom/right edge. xchange/ychange
* are FALSE if that dimension is not to be changed, TRUE otherwise. * are FALSE if that dimension is not to be changed, TRUE otherwise.
@@ -3157,17 +3168,17 @@ handle_move_to_corner_backend (MetaDisplay *display,
gpointer dummy) gpointer dummy)
{ {
MetaRectangle work_area; MetaRectangle work_area;
MetaRectangle outer; MetaRectangle frame_rect;
int orig_x, orig_y; int orig_x, orig_y;
int new_x, new_y; int new_x, new_y;
meta_window_get_work_area_all_monitors (window, &work_area); meta_window_get_work_area_all_monitors (window, &work_area);
meta_window_get_outer_rect (window, &outer); meta_window_get_frame_rect (window, &frame_rect);
meta_window_get_position (window, &orig_x, &orig_y); meta_window_get_position (window, &orig_x, &orig_y);
if (xchange) { if (xchange) {
new_x = work_area.x + (to_right ? new_x = work_area.x + (to_right ?
work_area.width - outer.width : work_area.width - frame_rect.width :
0); 0);
} else { } else {
new_x = orig_x; new_x = orig_x;
@@ -3175,7 +3186,7 @@ handle_move_to_corner_backend (MetaDisplay *display,
if (ychange) { if (ychange) {
new_y = work_area.y + (to_bottom ? new_y = work_area.y + (to_bottom ?
work_area.height - outer.height : work_area.height - frame_rect.height :
0); 0);
} else { } else {
new_y = orig_y; new_y = orig_y;
@@ -3284,12 +3295,12 @@ handle_move_to_center (MetaDisplay *display,
gpointer dummy) gpointer dummy)
{ {
MetaRectangle work_area; MetaRectangle work_area;
MetaRectangle outer; MetaRectangle frame_rect;
int orig_x, orig_y; int orig_x, orig_y;
int frame_width, frame_height; int frame_width, frame_height;
meta_window_get_work_area_all_monitors (window, &work_area); meta_window_get_work_area_all_monitors (window, &work_area);
meta_window_get_outer_rect (window, &outer); meta_window_get_frame_rect (window, &frame_rect);
meta_window_get_position (window, &orig_x, &orig_y); meta_window_get_position (window, &orig_x, &orig_y);
frame_width = (window->frame ? window->frame->child_x : 0); frame_width = (window->frame ? window->frame->child_x : 0);
@@ -3297,8 +3308,8 @@ handle_move_to_center (MetaDisplay *display,
meta_window_move_resize (window, meta_window_move_resize (window,
TRUE, TRUE,
work_area.x + (work_area.width +frame_width -outer.width )/2, work_area.x + (work_area.width +frame_width -frame_rect.width )/2,
work_area.y + (work_area.height+frame_height-outer.height)/2, work_area.y + (work_area.height+frame_height-frame_rect.height)/2,
window->rect.width, window->rect.width,
window->rect.height); window->rect.height);
} }
@@ -3991,8 +4002,8 @@ handle_raise_or_lower (MetaDisplay *display,
if (above->mapped) if (above->mapped)
{ {
meta_window_get_outer_rect (window, &win_rect); meta_window_get_frame_rect (window, &win_rect);
meta_window_get_outer_rect (above, &above_rect); meta_window_get_frame_rect (above, &above_rect);
/* Check if obscured */ /* Check if obscured */
if (meta_rectangle_intersect (&win_rect, &above_rect, &tmp)) if (meta_rectangle_intersect (&win_rect, &above_rect, &tmp))
@@ -4132,28 +4143,6 @@ meta_keybindings_set_custom_handler (const gchar *name,
return TRUE; return TRUE;
} }
/**
* meta_keybindings_switch_window: (skip)
* @display: a #MetaDisplay
* @screen: a #MetaScreen
* @event_window: a #MetaWindow
* @event: a #XIDeviceEvent
* @binding: a #MetaKeyBinding
*
*/
void
meta_keybindings_switch_window (MetaDisplay *display,
MetaScreen *screen,
MetaWindow *event_window,
XIDeviceEvent *event,
MetaKeyBinding *binding)
{
gint backwards = (binding->handler->flags & META_KEY_BINDING_IS_REVERSED) != 0;
do_choose_window (display, screen, event_window, event, binding,
backwards, FALSE);
}
static void static void
init_builtin_key_bindings (MetaDisplay *display) init_builtin_key_bindings (MetaDisplay *display)
{ {
@@ -4675,6 +4664,13 @@ init_builtin_key_bindings (MetaDisplay *display)
META_KEYBINDING_ACTION_MAXIMIZE_HORIZONTALLY, META_KEYBINDING_ACTION_MAXIMIZE_HORIZONTALLY,
handle_maximize_horizontally, 0); handle_maximize_horizontally, 0);
add_builtin_keybinding (display,
"always-on-top",
common_keybindings,
META_KEY_BINDING_PER_WINDOW,
META_KEYBINDING_ACTION_ALWAYS_ON_TOP,
handle_always_on_top, 0);
add_builtin_keybinding (display, add_builtin_keybinding (display,
"move-to-corner-nw", "move-to-corner-nw",
common_keybindings, common_keybindings,

View File

@@ -37,7 +37,9 @@
#include <gdk/gdk.h> #include <gdk/gdk.h>
#include <X11/cursorfont.h>
#include <X11/extensions/Xfixes.h> #include <X11/extensions/Xfixes.h>
#include <X11/Xcursor/Xcursor.h>
#include "meta-cursor-tracker-private.h" #include "meta-cursor-tracker-private.h"
#include "screen-private.h" #include "screen-private.h"
@@ -69,6 +71,106 @@ enum {
static guint signals[LAST_SIGNAL]; static guint signals[LAST_SIGNAL];
static void
translate_meta_cursor (MetaCursor cursor,
guint *glyph_out,
const char **name_out)
{
guint glyph = XC_num_glyphs;
const char *name = NULL;
switch (cursor)
{
case META_CURSOR_DEFAULT:
glyph = XC_left_ptr;
break;
case META_CURSOR_NORTH_RESIZE:
glyph = XC_top_side;
break;
case META_CURSOR_SOUTH_RESIZE:
glyph = XC_bottom_side;
break;
case META_CURSOR_WEST_RESIZE:
glyph = XC_left_side;
break;
case META_CURSOR_EAST_RESIZE:
glyph = XC_right_side;
break;
case META_CURSOR_SE_RESIZE:
glyph = XC_bottom_right_corner;
break;
case META_CURSOR_SW_RESIZE:
glyph = XC_bottom_left_corner;
break;
case META_CURSOR_NE_RESIZE:
glyph = XC_top_right_corner;
break;
case META_CURSOR_NW_RESIZE:
glyph = XC_top_left_corner;
break;
case META_CURSOR_MOVE_OR_RESIZE_WINDOW:
glyph = XC_fleur;
break;
case META_CURSOR_BUSY:
glyph = XC_watch;
break;
case META_CURSOR_DND_IN_DRAG:
name = "dnd-none";
break;
case META_CURSOR_DND_MOVE:
name = "dnd-move";
break;
case META_CURSOR_DND_COPY:
name = "dnd-copy";
break;
case META_CURSOR_DND_UNSUPPORTED_TARGET:
name = "dnd-none";
break;
case META_CURSOR_POINTING_HAND:
glyph = XC_hand2;
break;
case META_CURSOR_CROSSHAIR:
glyph = XC_crosshair;
break;
case META_CURSOR_IBEAM:
glyph = XC_xterm;
break;
default:
g_assert_not_reached ();
glyph = 0; /* silence compiler */
break;
}
*glyph_out = glyph;
*name_out = name;
}
static Cursor
load_cursor_on_server (MetaDisplay *display,
MetaCursor cursor)
{
Cursor xcursor;
guint glyph;
const char *name;
translate_meta_cursor (cursor, &glyph, &name);
if (name != NULL)
xcursor = XcursorLibraryLoadCursor (display->xdisplay, name);
else
xcursor = XCreateFontCursor (display->xdisplay, glyph);
return xcursor;
}
Cursor
meta_display_create_x_cursor (MetaDisplay *display,
MetaCursor cursor)
{
return load_cursor_on_server (display, cursor);
}
static void static void
meta_cursor_tracker_init (MetaCursorTracker *self) meta_cursor_tracker_init (MetaCursorTracker *self)
{ {

View File

@@ -842,6 +842,8 @@ on_bus_acquired (GDBusConnection *connection,
for (iter = devices; iter; iter = iter->next) for (iter = devices; iter; iter = iter->next)
on_device_added (device_manager, iter->data, manager); on_device_added (device_manager, iter->data, manager);
g_slist_free (devices);
g_signal_connect_object (device_manager, "device-added", g_signal_connect_object (device_manager, "device-added",
G_CALLBACK (on_device_added), manager, 0); G_CALLBACK (on_device_added), manager, 0);
g_signal_connect_object (device_manager, "device-removed", g_signal_connect_object (device_manager, "device-removed",

View File

@@ -99,8 +99,9 @@ static gboolean meta_monitor_config_assign_crtcs (MetaConfiguration *config,
GPtrArray *crtcs, GPtrArray *crtcs,
GPtrArray *outputs); GPtrArray *outputs);
static void power_client_changed_cb (UpClient *client, static void power_client_changed_cb (UpClient *client,
gpointer user_data); GParamSpec *pspec,
gpointer user_data);
static void static void
free_output_key (MetaOutputKey *key) free_output_key (MetaOutputKey *key)
@@ -232,7 +233,7 @@ meta_monitor_config_init (MetaMonitorConfig *self)
self->up_client = up_client_new (); self->up_client = up_client_new ();
self->lid_is_closed = up_client_get_lid_is_closed (self->up_client); self->lid_is_closed = up_client_get_lid_is_closed (self->up_client);
g_signal_connect_object (self->up_client, "changed", g_signal_connect_object (self->up_client, "notify::lid-is-closed",
G_CALLBACK (power_client_changed_cb), self, 0); G_CALLBACK (power_client_changed_cb), self, 0);
} }
@@ -816,6 +817,22 @@ meta_monitor_config_match_current (MetaMonitorConfig *self,
return ok; return ok;
} }
gboolean
meta_monitor_manager_has_hotplug_mode_update (MetaMonitorManager *manager)
{
MetaOutput *outputs;
unsigned n_outputs;
unsigned int i;
outputs = meta_monitor_manager_get_outputs (manager, &n_outputs);
for (i = 0; i < n_outputs; i++)
if (outputs[i].hotplug_mode_update)
return TRUE;
return FALSE;
}
static MetaConfiguration * static MetaConfiguration *
meta_monitor_config_get_stored (MetaMonitorConfig *self, meta_monitor_config_get_stored (MetaMonitorConfig *self,
MetaOutput *outputs, MetaOutput *outputs,
@@ -824,6 +841,9 @@ meta_monitor_config_get_stored (MetaMonitorConfig *self,
MetaConfiguration key; MetaConfiguration key;
MetaConfiguration *stored; MetaConfiguration *stored;
if (n_outputs == 0)
return NULL;
make_config_key (&key, outputs, n_outputs, -1); make_config_key (&key, outputs, n_outputs, -1);
stored = g_hash_table_lookup (self->configs, &key); stored = g_hash_table_lookup (self->configs, &key);
@@ -1231,6 +1251,12 @@ meta_monitor_config_make_default (MetaMonitorConfig *self,
outputs = meta_monitor_manager_get_outputs (manager, &n_outputs); outputs = meta_monitor_manager_get_outputs (manager, &n_outputs);
meta_monitor_manager_get_screen_limits (manager, &max_width, &max_height); meta_monitor_manager_get_screen_limits (manager, &max_width, &max_height);
if (n_outputs == 0)
{
meta_verbose ("No output connected, not applying configuration\n");
return;
}
default_config = make_default_config (self, outputs, n_outputs, max_width, max_height); default_config = make_default_config (self, outputs, n_outputs, max_width, max_height);
if (default_config != NULL) if (default_config != NULL)
@@ -1335,8 +1361,9 @@ turn_off_laptop_display (MetaMonitorConfig *self,
} }
static void static void
power_client_changed_cb (UpClient *client, power_client_changed_cb (UpClient *client,
gpointer user_data) GParamSpec *pspec,
gpointer user_data)
{ {
MetaMonitorManager *manager = meta_monitor_manager_get (); MetaMonitorManager *manager = meta_monitor_manager_get ();
MetaMonitorConfig *self = user_data; MetaMonitorConfig *self = user_data;

View File

@@ -116,6 +116,9 @@ struct _MetaOutput
*/ */
gboolean is_primary; gboolean is_primary;
gboolean is_presentation; gboolean is_presentation;
/* get a new preferred mode on hotplug events, to handle dynamic guest resizing */
gboolean hotplug_mode_update;
}; };
struct _MetaCRTC struct _MetaCRTC
@@ -383,6 +386,7 @@ void meta_output_info_free (MetaOutputInfo *info);
void meta_monitor_manager_free_output_array (MetaOutput *old_outputs, void meta_monitor_manager_free_output_array (MetaOutput *old_outputs,
int n_old_outputs); int n_old_outputs);
gboolean meta_monitor_manager_has_hotplug_mode_update (MetaMonitorManager *manager);
/* Returns true if transform causes width and height to be inverted /* Returns true if transform causes width and height to be inverted
This is true for the odd transforms in the enum */ This is true for the odd transforms in the enum */

View File

@@ -311,6 +311,29 @@ read_output_edid (MetaMonitorManagerXrandr *manager_xrandr,
return NULL; return NULL;
} }
static gboolean
output_get_hotplug_mode_update (MetaMonitorManagerXrandr *manager_xrandr,
XID output_id)
{
MetaDisplay *display = meta_get_display ();
XRRPropertyInfo *info;
gboolean result = FALSE;
meta_error_trap_push (display);
info = XRRQueryOutputProperty (manager_xrandr->xdisplay, output_id,
display->atom_hotplug_mode_update);
meta_error_trap_pop (display);
if (info)
{
result = TRUE;
XFree (info);
}
return result;
}
static void static void
meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager) meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
{ {
@@ -430,8 +453,10 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
XRRFreeCrtcInfo (crtc); XRRFreeCrtcInfo (crtc);
} }
meta_error_trap_push (meta_get_display ());
primary_output = XRRGetOutputPrimary (manager_xrandr->xdisplay, primary_output = XRRGetOutputPrimary (manager_xrandr->xdisplay,
DefaultRootWindow (manager_xrandr->xdisplay)); DefaultRootWindow (manager_xrandr->xdisplay));
meta_error_trap_pop (meta_get_display ());
n_actual_outputs = 0; n_actual_outputs = 0;
for (i = 0; i < (unsigned)resources->noutput; i++) for (i = 0; i < (unsigned)resources->noutput; i++)
@@ -484,6 +509,8 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
meta_output->width_mm = output->mm_width; meta_output->width_mm = output->mm_width;
meta_output->height_mm = output->mm_height; meta_output->height_mm = output->mm_height;
meta_output->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN; meta_output->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN;
meta_output->hotplug_mode_update =
output_get_hotplug_mode_update (manager_xrandr, meta_output->output_id);
meta_output->n_modes = output->nmode; meta_output->n_modes = output->nmode;
meta_output->modes = g_new0 (MetaMonitorMode *, meta_output->n_modes); meta_output->modes = g_new0 (MetaMonitorMode *, meta_output->n_modes);
@@ -668,10 +695,11 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
unsigned int n_outputs) unsigned int n_outputs)
{ {
MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (manager); MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (manager);
MetaDisplay *display = meta_get_display ();
unsigned i; unsigned i;
int width, height, width_mm, height_mm; int width, height, width_mm, height_mm;
meta_display_grab (meta_get_display ()); meta_display_grab (display);
/* First compute the new size of the screen (framebuffer) */ /* First compute the new size of the screen (framebuffer) */
width = 0; height = 0; width = 0; height = 0;
@@ -765,10 +793,10 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
*/ */
width_mm = (width / DPI_FALLBACK) * 25.4 + 0.5; width_mm = (width / DPI_FALLBACK) * 25.4 + 0.5;
height_mm = (height / DPI_FALLBACK) * 25.4 + 0.5; height_mm = (height / DPI_FALLBACK) * 25.4 + 0.5;
meta_error_trap_push (meta_get_display ()); meta_error_trap_push (display);
XRRSetScreenSize (manager_xrandr->xdisplay, DefaultRootWindow (manager_xrandr->xdisplay), XRRSetScreenSize (manager_xrandr->xdisplay, DefaultRootWindow (manager_xrandr->xdisplay),
width, height, width_mm, height_mm); width, height, width_mm, height_mm);
meta_error_trap_pop (meta_get_display ()); meta_error_trap_pop (display);
for (i = 0; i < n_crtcs; i++) for (i = 0; i < n_crtcs; i++)
{ {
@@ -825,7 +853,7 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
goto next; goto next;
} }
meta_error_trap_push (meta_get_display ()); meta_error_trap_push (display);
ok = XRRSetCrtcConfig (manager_xrandr->xdisplay, ok = XRRSetCrtcConfig (manager_xrandr->xdisplay,
manager_xrandr->resources, manager_xrandr->resources,
(XID)crtc->crtc_id, (XID)crtc->crtc_id,
@@ -834,7 +862,7 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
(XID)mode->mode_id, (XID)mode->mode_id,
wl_transform_to_xrandr (crtc_info->transform), wl_transform_to_xrandr (crtc_info->transform),
outputs, n_outputs); outputs, n_outputs);
meta_error_trap_pop (meta_get_display ()); meta_error_trap_pop (display);
if (ok != Success) if (ok != Success)
{ {
@@ -875,9 +903,11 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
if (output_info->is_primary) if (output_info->is_primary)
{ {
meta_error_trap_push (display);
XRRSetOutputPrimary (manager_xrandr->xdisplay, XRRSetOutputPrimary (manager_xrandr->xdisplay,
DefaultRootWindow (manager_xrandr->xdisplay), DefaultRootWindow (manager_xrandr->xdisplay),
(XID)output_info->output->output_id); (XID)output_info->output->output_id);
meta_error_trap_pop (display);
} }
output_set_presentation_xrandr (manager_xrandr, output_set_presentation_xrandr (manager_xrandr,
@@ -903,7 +933,7 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
output->is_primary = FALSE; output->is_primary = FALSE;
} }
meta_display_ungrab (meta_get_display ()); meta_display_ungrab (display);
} }
static void static void
@@ -971,6 +1001,16 @@ meta_monitor_manager_xrandr_set_crtc_gamma (MetaMonitorManager *manager,
XRRFreeGamma (gamma); XRRFreeGamma (gamma);
} }
static void
meta_monitor_manager_xrandr_rebuild_derived (MetaMonitorManager *manager)
{
/* This will be a no-op if the change was from our side, as
we already called it in the DBus method handler */
meta_monitor_config_update_current (manager->config, manager);
meta_monitor_manager_rebuild_derived (manager);
}
static gboolean static gboolean
meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManager *manager, meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManager *manager,
XEvent *event) XEvent *event)
@@ -980,6 +1020,7 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManager *manager,
MetaCRTC *old_crtcs; MetaCRTC *old_crtcs;
MetaMonitorMode *old_modes; MetaMonitorMode *old_modes;
int n_old_outputs; int n_old_outputs;
gboolean new_config;
if ((event->type - manager_xrandr->rr_event_base) != RRScreenChangeNotify) if ((event->type - manager_xrandr->rr_event_base) != RRScreenChangeNotify)
return FALSE; return FALSE;
@@ -995,31 +1036,36 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManager *manager,
manager->serial++; manager->serial++;
meta_monitor_manager_xrandr_read_current (manager); meta_monitor_manager_xrandr_read_current (manager);
/* Check if the current intended configuration has the same outputs new_config = manager_xrandr->resources->timestamp >=
as the new real one, or if the event is a result of an XRandR call. manager_xrandr->resources->configTimestamp;
If so, we can go straight to rebuild the logical config and tell if (meta_monitor_manager_has_hotplug_mode_update (manager))
the outside world.
Otherwise, this event was caused by hotplug, so give a chance to
MetaMonitorConfig.
Note that we need to check both the timestamps and the list of
outputs, because the X server might emit spurious events with
new configTimestamps (bug 702804), and the driver may have
changed the EDID for some other reason (old broken qxl and vbox
drivers...).
*/
if (manager_xrandr->resources->timestamp >= manager_xrandr->resources->configTimestamp ||
meta_monitor_config_match_current (manager->config, manager))
{ {
/* This will be a no-op if the change was from our side, as /* Check if the current intended configuration is a result of an
we already called it in the DBus method handler */ XRandR call. Otherwise, hotplug_mode_update tells us to get
meta_monitor_config_update_current (manager->config, manager); a new preferred mode on hotplug events to handle dynamic
guest resizing. */
meta_monitor_manager_rebuild_derived (manager); if (new_config)
meta_monitor_manager_xrandr_rebuild_derived (manager);
else
meta_monitor_config_make_default (manager->config, manager);
} }
else else
{ {
if (!meta_monitor_config_apply_stored (manager->config, manager)) /* Check if the current intended configuration has the same outputs
as the new real one, or if the event is a result of an XRandR call.
If so, we can go straight to rebuild the logical config and tell
the outside world.
Otherwise, this event was caused by hotplug, so give a chance to
MetaMonitorConfig.
Note that we need to check both the timestamps and the list of
outputs, because the X server might emit spurious events with new
configTimestamps (bug 702804), and the driver may have changed
the EDID for some other reason (old qxl and vbox drivers). */
if (new_config || meta_monitor_config_match_current (manager->config, manager))
meta_monitor_manager_xrandr_rebuild_derived (manager);
else if (!meta_monitor_config_apply_stored (manager->config, manager))
meta_monitor_config_make_default (manager->config, manager); meta_monitor_config_make_default (manager->config, manager);
} }

View File

@@ -806,6 +806,9 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
g_variant_new_take_string (make_display_name (manager, output))); g_variant_new_take_string (make_display_name (manager, output)));
g_variant_builder_add (&properties, "{sv}", "backlight", g_variant_builder_add (&properties, "{sv}", "backlight",
g_variant_new_int32 (output->backlight)); g_variant_new_int32 (output->backlight));
g_variant_builder_add (&properties, "{sv}", "min-backlight-step",
g_variant_new_int32 ((output->backlight_max - output->backlight_min) ?
100 / (output->backlight_max - output->backlight_min) : -1));
g_variant_builder_add (&properties, "{sv}", "primary", g_variant_builder_add (&properties, "{sv}", "primary",
g_variant_new_boolean (output->is_primary)); g_variant_new_boolean (output->is_primary));
g_variant_builder_add (&properties, "{sv}", "presentation", g_variant_builder_add (&properties, "{sv}", "presentation",

View File

@@ -47,34 +47,18 @@ northwestcmp (gconstpointer a, gconstpointer b)
{ {
MetaWindow *aw = (gpointer) a; MetaWindow *aw = (gpointer) a;
MetaWindow *bw = (gpointer) b; MetaWindow *bw = (gpointer) b;
MetaRectangle a_frame;
MetaRectangle b_frame;
int from_origin_a; int from_origin_a;
int from_origin_b; int from_origin_b;
int ax, ay, bx, by; int ax, ay, bx, by;
/* we're interested in the frame position for cascading, meta_window_get_frame_rect (aw, &a_frame);
* not meta_window_get_position() meta_window_get_frame_rect (bw, &b_frame);
*/ ax = a_frame.x;
if (aw->frame) ay = a_frame.y;
{ bx = b_frame.x;
ax = aw->frame->rect.x; by = b_frame.y;
ay = aw->frame->rect.y;
}
else
{
ax = aw->rect.x;
ay = aw->rect.y;
}
if (bw->frame)
{
bx = bw->frame->rect.x;
by = bw->frame->rect.y;
}
else
{
bx = bw->rect.x;
by = bw->rect.y;
}
/* probably there's a fast good-enough-guess we could use here. */ /* probably there's a fast good-enough-guess we could use here. */
from_origin_a = sqrt (ax * ax + ay * ay); from_origin_a = sqrt (ax * ax + ay * ay);
@@ -90,7 +74,6 @@ northwestcmp (gconstpointer a, gconstpointer b)
static void static void
find_next_cascade (MetaWindow *window, find_next_cascade (MetaWindow *window,
MetaFrameBorders *borders,
/* visible windows on relevant workspaces */ /* visible windows on relevant workspaces */
GList *windows, GList *windows,
int x, int x,
@@ -102,6 +85,7 @@ find_next_cascade (MetaWindow *window,
GList *sorted; GList *sorted;
int cascade_x, cascade_y; int cascade_x, cascade_y;
int x_threshold, y_threshold; int x_threshold, y_threshold;
MetaRectangle frame_rect;
int window_width, window_height; int window_width, window_height;
int cascade_stage; int cascade_stage;
MetaRectangle work_area; MetaRectangle work_area;
@@ -120,10 +104,13 @@ find_next_cascade (MetaWindow *window,
* manually cascade. * manually cascade.
*/ */
#define CASCADE_FUZZ 15 #define CASCADE_FUZZ 15
if (borders) if (window->frame)
{ {
x_threshold = MAX (borders->visible.left, CASCADE_FUZZ); MetaFrameBorders borders;
y_threshold = MAX (borders->visible.top, CASCADE_FUZZ);
meta_frame_calc_borders (window->frame, &borders);
x_threshold = MAX (borders.visible.left, CASCADE_FUZZ);
y_threshold = MAX (borders.visible.top, CASCADE_FUZZ);
} }
else else
{ {
@@ -143,30 +130,25 @@ find_next_cascade (MetaWindow *window,
cascade_y = MAX (0, work_area.y); cascade_y = MAX (0, work_area.y);
/* Find first cascade position that's not used. */ /* Find first cascade position that's not used. */
window_width = window->frame ? window->frame->rect.width : window->rect.width; meta_window_get_frame_rect (window, &frame_rect);
window_height = window->frame ? window->frame->rect.height : window->rect.height; window_width = frame_rect.width;
window_height = frame_rect.height;
cascade_stage = 0; cascade_stage = 0;
tmp = sorted; tmp = sorted;
while (tmp != NULL) while (tmp != NULL)
{ {
MetaWindow *w; MetaWindow *w;
MetaRectangle w_frame_rect;
int wx, wy; int wx, wy;
w = tmp->data; w = tmp->data;
/* we want frame position, not window position */ /* we want frame position, not window position */
if (w->frame) meta_window_get_frame_rect (w, &w_frame_rect);
{ wx = w_frame_rect.x;
wx = w->frame->rect.x; wy = w_frame_rect.y;
wy = w->frame->rect.y;
}
else
{
wx = w->rect.x;
wy = w->rect.y;
}
if (ABS (wx - cascade_x) < x_threshold && if (ABS (wx - cascade_x) < x_threshold &&
ABS (wy - cascade_y) < y_threshold) ABS (wy - cascade_y) < y_threshold)
@@ -223,22 +205,12 @@ find_next_cascade (MetaWindow *window,
g_list_free (sorted); g_list_free (sorted);
/* Convert coords to position of window, not position of frame. */ *new_x = cascade_x;
if (borders == NULL) *new_y = cascade_y;
{
*new_x = cascade_x;
*new_y = cascade_y;
}
else
{
*new_x = cascade_x + borders->visible.left;
*new_y = cascade_y + borders->visible.top;
}
} }
static void static void
find_most_freespace (MetaWindow *window, find_most_freespace (MetaWindow *window,
MetaFrameBorders *borders,
/* visible windows on relevant workspaces */ /* visible windows on relevant workspaces */
MetaWindow *focus_window, MetaWindow *focus_window,
int x, int x,
@@ -250,29 +222,25 @@ find_most_freespace (MetaWindow *window,
int max_area; int max_area;
int max_width, max_height, left, right, top, bottom; int max_width, max_height, left, right, top, bottom;
int left_space, right_space, top_space, bottom_space; int left_space, right_space, top_space, bottom_space;
int frame_size_left, frame_size_top;
MetaRectangle work_area; MetaRectangle work_area;
MetaRectangle avoid; MetaRectangle avoid;
MetaRectangle outer; MetaRectangle frame_rect;
frame_size_left = borders ? borders->visible.left : 0;
frame_size_top = borders ? borders->visible.top : 0;
meta_window_get_work_area_current_monitor (focus_window, &work_area); meta_window_get_work_area_current_monitor (focus_window, &work_area);
meta_window_get_outer_rect (focus_window, &avoid); meta_window_get_frame_rect (focus_window, &avoid);
meta_window_get_outer_rect (window, &outer); meta_window_get_frame_rect (window, &frame_rect);
/* Find the areas of choosing the various sides of the focus window */ /* Find the areas of choosing the various sides of the focus window */
max_width = MIN (avoid.width, outer.width); max_width = MIN (avoid.width, frame_rect.width);
max_height = MIN (avoid.height, outer.height); max_height = MIN (avoid.height, frame_rect.height);
left_space = avoid.x - work_area.x; left_space = avoid.x - work_area.x;
right_space = work_area.width - (avoid.x + avoid.width - work_area.x); right_space = work_area.width - (avoid.x + avoid.width - work_area.x);
top_space = avoid.y - work_area.y; top_space = avoid.y - work_area.y;
bottom_space = work_area.height - (avoid.y + avoid.height - work_area.y); bottom_space = work_area.height - (avoid.y + avoid.height - work_area.y);
left = MIN (left_space, outer.width); left = MIN (left_space, frame_rect.width);
right = MIN (right_space, outer.width); right = MIN (right_space, frame_rect.width);
top = MIN (top_space, outer.height); top = MIN (top_space, frame_rect.height);
bottom = MIN (bottom_space, outer.height); bottom = MIN (bottom_space, frame_rect.height);
/* Find out which side of the focus_window can show the most of the window */ /* Find out which side of the focus_window can show the most of the window */
side = META_LEFT; side = META_LEFT;
@@ -304,39 +272,56 @@ find_most_freespace (MetaWindow *window,
switch (side) switch (side)
{ {
case META_LEFT: case META_LEFT:
*new_y = avoid.y + frame_size_top; *new_y = avoid.y;
if (left_space > outer.width) if (left_space > frame_rect.width)
*new_x = avoid.x - outer.width + frame_size_left; *new_x = avoid.x - frame_rect.width;
else else
*new_x = work_area.x + frame_size_left; *new_x = work_area.x;
break; break;
case META_RIGHT: case META_RIGHT:
*new_y = avoid.y + frame_size_top; *new_y = avoid.y;
if (right_space > outer.width) if (right_space > frame_rect.width)
*new_x = avoid.x + avoid.width + frame_size_left; *new_x = avoid.x + avoid.width;
else else
*new_x = work_area.x + work_area.width - outer.width + frame_size_left; *new_x = work_area.x + work_area.width - frame_rect.width;
break; break;
case META_TOP: case META_TOP:
*new_x = avoid.x + frame_size_left; *new_x = avoid.x;
if (top_space > outer.height) if (top_space > frame_rect.height)
*new_y = avoid.y - outer.height + frame_size_top; *new_y = avoid.y - frame_rect.height;
else else
*new_y = work_area.y + frame_size_top; *new_y = work_area.y;
break; break;
case META_BOTTOM: case META_BOTTOM:
*new_x = avoid.x + frame_size_left; *new_x = avoid.x;
if (bottom_space > outer.height) if (bottom_space > frame_rect.height)
*new_y = avoid.y + avoid.height + frame_size_top; *new_y = avoid.y + avoid.height;
else else
*new_y = work_area.y + work_area.height - outer.height + frame_size_top; *new_y = work_area.y + work_area.height - frame_rect.height;
break; break;
} }
} }
static gboolean
window_overlaps_focus_window (MetaWindow *window)
{
MetaWindow *focus_window;
MetaRectangle window_frame, focus_frame, overlap;
focus_window = window->display->focus_window;
if (focus_window == NULL)
return FALSE;
meta_window_get_frame_rect (window, &window_frame);
meta_window_get_frame_rect (focus_window, &focus_frame);
return meta_rectangle_intersect (&window_frame,
&focus_frame,
&overlap);
}
static void static void
avoid_being_obscured_as_second_modal_dialog (MetaWindow *window, avoid_being_obscured_as_second_modal_dialog (MetaWindow *window,
MetaFrameBorders *borders,
int *x, int *x,
int *y) int *y)
{ {
@@ -355,18 +340,17 @@ avoid_being_obscured_as_second_modal_dialog (MetaWindow *window,
*/ */
MetaWindow *focus_window; MetaWindow *focus_window;
MetaRectangle overlap;
focus_window = window->display->focus_window; focus_window = window->display->focus_window;
/* denied_focus_and_not_transient is only set when focus_window != NULL */
if (window->denied_focus_and_not_transient && if (window->denied_focus_and_not_transient &&
window->wm_state_modal && /* FIXME: Maybe do this for all transients? */ window->wm_state_modal && /* FIXME: Maybe do this for all transients? */
meta_window_same_application (window, focus_window) && meta_window_same_application (window, focus_window) &&
meta_rectangle_intersect (&window->rect, window_overlaps_focus_window (window))
&focus_window->rect,
&overlap))
{ {
find_most_freespace (window, borders, focus_window, *x, *y, x, y); find_most_freespace (window, focus_window, *x, *y, x, y);
meta_topic (META_DEBUG_PLACEMENT, meta_topic (META_DEBUG_PLACEMENT,
"Dialog window %s was denied focus but may be modal " "Dialog window %s was denied focus but may be modal "
"to the focus window; had to move it to avoid the " "to the focus window; had to move it to avoid the "
@@ -409,7 +393,7 @@ rectangle_overlaps_some_window (MetaRectangle *rect,
case META_WINDOW_UTILITY: case META_WINDOW_UTILITY:
case META_WINDOW_TOOLBAR: case META_WINDOW_TOOLBAR:
case META_WINDOW_MENU: case META_WINDOW_MENU:
meta_window_get_outer_rect (other, &other_rect); meta_window_get_frame_rect (other, &other_rect);
if (meta_rectangle_intersect (rect, &other_rect, &dest)) if (meta_rectangle_intersect (rect, &other_rect, &dest))
return TRUE; return TRUE;
@@ -427,20 +411,14 @@ leftmost_cmp (gconstpointer a, gconstpointer b)
{ {
MetaWindow *aw = (gpointer) a; MetaWindow *aw = (gpointer) a;
MetaWindow *bw = (gpointer) b; MetaWindow *bw = (gpointer) b;
MetaRectangle a_frame;
MetaRectangle b_frame;
int ax, bx; int ax, bx;
/* we're interested in the frame position for cascading, meta_window_get_frame_rect (aw, &a_frame);
* not meta_window_get_position() meta_window_get_frame_rect (bw, &b_frame);
*/ ax = a_frame.x;
if (aw->frame) bx = b_frame.x;
ax = aw->frame->rect.x;
else
ax = aw->rect.x;
if (bw->frame)
bx = bw->frame->rect.x;
else
bx = bw->rect.x;
if (ax < bx) if (ax < bx)
return -1; return -1;
@@ -455,20 +433,14 @@ topmost_cmp (gconstpointer a, gconstpointer b)
{ {
MetaWindow *aw = (gpointer) a; MetaWindow *aw = (gpointer) a;
MetaWindow *bw = (gpointer) b; MetaWindow *bw = (gpointer) b;
MetaRectangle a_frame;
MetaRectangle b_frame;
int ay, by; int ay, by;
/* we're interested in the frame position for cascading, meta_window_get_frame_rect (aw, &a_frame);
* not meta_window_get_position() meta_window_get_frame_rect (bw, &b_frame);
*/ ay = a_frame.y;
if (aw->frame) by = b_frame.y;
ay = aw->frame->rect.y;
else
ay = aw->rect.y;
if (bw->frame)
by = bw->frame->rect.y;
else
by = bw->rect.y;
if (ay < by) if (ay < by)
return -1; return -1;
@@ -506,7 +478,6 @@ center_tile_rect_in_area (MetaRectangle *rect,
*/ */
static gboolean static gboolean
find_first_fit (MetaWindow *window, find_first_fit (MetaWindow *window,
MetaFrameBorders *borders,
/* visible windows on relevant workspaces */ /* visible windows on relevant workspaces */
GList *windows, GList *windows,
int monitor, int monitor,
@@ -540,15 +511,8 @@ find_first_fit (MetaWindow *window,
right_sorted = g_list_copy (windows); right_sorted = g_list_copy (windows);
right_sorted = g_list_sort (right_sorted, topmost_cmp); right_sorted = g_list_sort (right_sorted, topmost_cmp);
right_sorted = g_list_sort (right_sorted, leftmost_cmp); right_sorted = g_list_sort (right_sorted, leftmost_cmp);
rect.width = window->rect.width; meta_window_get_frame_rect (window, &rect);
rect.height = window->rect.height;
if (borders)
{
rect.width += borders->visible.left + borders->visible.right;
rect.height += borders->visible.top + borders->visible.bottom;
}
#ifdef WITH_VERBOSE_MODE #ifdef WITH_VERBOSE_MODE
{ {
@@ -570,11 +534,6 @@ find_first_fit (MetaWindow *window,
{ {
*new_x = rect.x; *new_x = rect.x;
*new_y = rect.y; *new_y = rect.y;
if (borders)
{
*new_x += borders->visible.left;
*new_y += borders->visible.top;
}
retval = TRUE; retval = TRUE;
@@ -586,23 +545,18 @@ find_first_fit (MetaWindow *window,
while (tmp != NULL) while (tmp != NULL)
{ {
MetaWindow *w = tmp->data; MetaWindow *w = tmp->data;
MetaRectangle outer_rect; MetaRectangle frame_rect;
meta_window_get_outer_rect (w, &outer_rect); meta_window_get_frame_rect (w, &frame_rect);
rect.x = outer_rect.x; rect.x = frame_rect.x;
rect.y = outer_rect.y + outer_rect.height; rect.y = frame_rect.y + frame_rect.height;
if (meta_rectangle_contains_rect (&work_area, &rect) && if (meta_rectangle_contains_rect (&work_area, &rect) &&
!rectangle_overlaps_some_window (&rect, below_sorted)) !rectangle_overlaps_some_window (&rect, below_sorted))
{ {
*new_x = rect.x; *new_x = rect.x;
*new_y = rect.y; *new_y = rect.y;
if (borders)
{
*new_x += borders->visible.left;
*new_y += borders->visible.top;
}
retval = TRUE; retval = TRUE;
@@ -617,23 +571,18 @@ find_first_fit (MetaWindow *window,
while (tmp != NULL) while (tmp != NULL)
{ {
MetaWindow *w = tmp->data; MetaWindow *w = tmp->data;
MetaRectangle outer_rect; MetaRectangle frame_rect;
meta_window_get_outer_rect (w, &outer_rect); meta_window_get_frame_rect (w, &frame_rect);
rect.x = outer_rect.x + outer_rect.width; rect.x = frame_rect.x + frame_rect.width;
rect.y = outer_rect.y; rect.y = frame_rect.y;
if (meta_rectangle_contains_rect (&work_area, &rect) && if (meta_rectangle_contains_rect (&work_area, &rect) &&
!rectangle_overlaps_some_window (&rect, right_sorted)) !rectangle_overlaps_some_window (&rect, right_sorted))
{ {
*new_x = rect.x; *new_x = rect.x;
*new_y = rect.y; *new_y = rect.y;
if (borders)
{
*new_x += borders->visible.left;
*new_y += borders->visible.top;
}
retval = TRUE; retval = TRUE;
@@ -652,7 +601,6 @@ find_first_fit (MetaWindow *window,
void void
meta_window_place (MetaWindow *window, meta_window_place (MetaWindow *window,
MetaFrameBorders *borders,
int x, int x,
int y, int y,
int *new_x, int *new_x,
@@ -661,13 +609,6 @@ meta_window_place (MetaWindow *window,
GList *windows; GList *windows;
const MetaMonitorInfo *xi; const MetaMonitorInfo *xi;
/* frame member variables should NEVER be used in here, only
* MetaFrameBorders. But remember borders == NULL
* for undecorated windows. Also, this function should
* NEVER have side effects other than computing the
* placement coordinates.
*/
meta_topic (META_DEBUG_PLACEMENT, "Placing window %s\n", window->desc); meta_topic (META_DEBUG_PLACEMENT, "Placing window %s\n", window->desc);
windows = NULL; windows = NULL;
@@ -756,7 +697,7 @@ meta_window_place (MetaWindow *window,
{ {
meta_topic (META_DEBUG_PLACEMENT, meta_topic (META_DEBUG_PLACEMENT,
"Not placing window with PPosition or USPosition set\n"); "Not placing window with PPosition or USPosition set\n");
avoid_being_obscured_as_second_modal_dialog (window, borders, &x, &y); avoid_being_obscured_as_second_modal_dialog (window, &x, &y);
goto done_no_constraints; goto done_no_constraints;
} }
} }
@@ -775,29 +716,27 @@ meta_window_place (MetaWindow *window,
if (parent) if (parent)
{ {
int w; MetaRectangle frame_rect, parent_frame_rect;
meta_window_get_position (parent, &x, &y); meta_window_get_frame_rect (window, &frame_rect);
w = parent->rect.width; meta_window_get_frame_rect (parent, &parent_frame_rect);
y = parent_frame_rect.y;
/* center of parent */ /* center of parent */
x = x + w / 2; x = parent_frame_rect.x + parent_frame_rect.width / 2;
/* center of child over center of parent */ /* center of child over center of parent */
x -= window->rect.width / 2; x -= frame_rect.width / 2;
/* "visually" center window over parent, leaving twice as /* "visually" center window over parent, leaving twice as
* much space below as on top. * much space below as on top.
*/ */
y += (parent->rect.height - window->rect.height)/3; y += (parent_frame_rect.height - frame_rect.height)/3;
/* put top of child's frame, not top of child's client */
if (borders)
y += borders->visible.top;
meta_topic (META_DEBUG_PLACEMENT, "Centered window %s over transient parent\n", meta_topic (META_DEBUG_PLACEMENT, "Centered window %s over transient parent\n",
window->desc); window->desc);
avoid_being_obscured_as_second_modal_dialog (window, borders, &x, &y); avoid_being_obscured_as_second_modal_dialog (window, &x, &y);
goto done; goto done;
} }
@@ -813,6 +752,9 @@ meta_window_place (MetaWindow *window,
{ {
/* Center on current monitor */ /* Center on current monitor */
int w, h; int w, h;
MetaRectangle frame_rect;
meta_window_get_frame_rect (window, &frame_rect);
/* Warning, this function is a round trip! */ /* Warning, this function is a round trip! */
xi = meta_screen_get_current_monitor_info (window->screen); xi = meta_screen_get_current_monitor_info (window->screen);
@@ -820,8 +762,8 @@ meta_window_place (MetaWindow *window,
w = xi->rect.width; w = xi->rect.width;
h = xi->rect.height; h = xi->rect.height;
x = (w - window->rect.width) / 2; x = (w - frame_rect.width) / 2;
y = (h - window->rect.height) / 2; y = (h - frame_rect.height) / 2;
x += xi->rect.x; x += xi->rect.x;
y += xi->rect.y; y += xi->rect.y;
@@ -865,7 +807,7 @@ meta_window_place (MetaWindow *window,
x = xi->rect.x; x = xi->rect.x;
y = xi->rect.y; y = xi->rect.y;
if (find_first_fit (window, borders, windows, if (find_first_fit (window, windows,
xi->number, xi->number,
x, y, &x, &y)) x, y, &x, &y))
goto done_check_denied_focus; goto done_check_denied_focus;
@@ -878,17 +820,17 @@ meta_window_place (MetaWindow *window,
!window->fullscreen) !window->fullscreen)
{ {
MetaRectangle workarea; MetaRectangle workarea;
MetaRectangle outer; MetaRectangle frame_rect;
meta_window_get_work_area_for_monitor (window, meta_window_get_work_area_for_monitor (window,
xi->number, xi->number,
&workarea); &workarea);
meta_window_get_outer_rect (window, &outer); meta_window_get_frame_rect (window, &frame_rect);
/* If the window is bigger than the screen, then automaximize. Do NOT /* If the window is bigger than the screen, then automaximize. Do NOT
* auto-maximize the directions independently. See #419810. * auto-maximize the directions independently. See #419810.
*/ */
if (outer.width >= workarea.width && outer.height >= workarea.height) if (frame_rect.width >= workarea.width && frame_rect.height >= workarea.height)
{ {
window->maximize_horizontally_after_placement = TRUE; window->maximize_horizontally_after_placement = TRUE;
window->maximize_vertically_after_placement = TRUE; window->maximize_vertically_after_placement = TRUE;
@@ -899,7 +841,7 @@ meta_window_place (MetaWindow *window,
* fully overlapping window (e.g. starting multiple terminals) * fully overlapping window (e.g. starting multiple terminals)
* */ * */
if (x == xi->rect.x && y == xi->rect.y) if (x == xi->rect.x && y == xi->rect.y)
find_next_cascade (window, borders, windows, x, y, &x, &y); find_next_cascade (window, windows, x, y, &x, &y);
done_check_denied_focus: done_check_denied_focus:
/* If the window is being denied focus and isn't a transient of the /* If the window is being denied focus and isn't a transient of the
@@ -909,17 +851,14 @@ meta_window_place (MetaWindow *window,
*/ */
if (window->denied_focus_and_not_transient) if (window->denied_focus_and_not_transient)
{ {
gboolean found_fit;
MetaWindow *focus_window; MetaWindow *focus_window;
MetaRectangle overlap; gboolean found_fit;
focus_window = window->display->focus_window; focus_window = window->display->focus_window;
g_assert (focus_window != NULL); g_assert (focus_window != NULL);
/* No need to do anything if the window doesn't overlap at all */ /* No need to do anything if the window doesn't overlap at all */
found_fit = !meta_rectangle_intersect (&window->rect, found_fit = !window_overlaps_focus_window (window);
&focus_window->rect,
&overlap);
/* Try to do a first fit again, this time only taking into account the /* Try to do a first fit again, this time only taking into account the
* focus window. * focus window.
@@ -933,7 +872,7 @@ meta_window_place (MetaWindow *window,
x = xi->rect.x; x = xi->rect.x;
y = xi->rect.y; y = xi->rect.y;
found_fit = find_first_fit (window, borders, focus_window_list, found_fit = find_first_fit (window, focus_window_list,
xi->number, xi->number,
x, y, &x, &y); x, y, &x, &y);
g_list_free (focus_window_list); g_list_free (focus_window_list);
@@ -943,7 +882,7 @@ meta_window_place (MetaWindow *window,
* as possible. * as possible.
*/ */
if (!found_fit) if (!found_fit)
find_most_freespace (window, borders, focus_window, x, y, &x, &y); find_most_freespace (window, focus_window, x, y, &x, &y);
} }
done: done:

View File

@@ -28,7 +28,6 @@
#include "frame.h" #include "frame.h"
void meta_window_place (MetaWindow *window, void meta_window_place (MetaWindow *window,
MetaFrameBorders *borders,
int x, int x,
int y, int y,
int *new_x, int *new_x,

View File

@@ -476,6 +476,9 @@ create_guard_window (Display *xdisplay, MetaScreen *screen)
CWEventMask|CWOverrideRedirect|CWBackPixel, CWEventMask|CWOverrideRedirect|CWBackPixel,
&attributes); &attributes);
/* https://bugzilla.gnome.org/show_bug.cgi?id=710346 */
XStoreName (xdisplay, guard_window, "mutter guard window");
{ {
unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits }; XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };
@@ -856,9 +859,9 @@ meta_screen_free (MetaScreen *screen,
screen->wm_sn_selection_window); screen->wm_sn_selection_window);
if (screen->work_area_later != 0) if (screen->work_area_later != 0)
g_source_remove (screen->work_area_later); meta_later_remove (screen->work_area_later);
if (screen->check_fullscreen_later != 0) if (screen->check_fullscreen_later != 0)
g_source_remove (screen->check_fullscreen_later); meta_later_remove (screen->check_fullscreen_later);
if (screen->monitor_infos) if (screen->monitor_infos)
g_free (screen->monitor_infos); g_free (screen->monitor_infos);
@@ -1525,7 +1528,7 @@ meta_screen_tab_popup_create (MetaScreen *screen,
if (show_type == META_TAB_SHOW_INSTANTLY || if (show_type == META_TAB_SHOW_INSTANTLY ||
!entries[i].hidden || !entries[i].hidden ||
!meta_window_get_icon_geometry (window, &r)) !meta_window_get_icon_geometry (window, &r))
meta_window_get_outer_rect (window, &r); meta_window_get_frame_rect (window, &r);
entries[i].rect = r; entries[i].rect = r;
@@ -1908,7 +1911,7 @@ meta_screen_get_monitor_for_window (MetaScreen *screen,
{ {
MetaRectangle window_rect; MetaRectangle window_rect;
meta_window_get_outer_rect (window, &window_rect); meta_window_get_frame_rect (window, &window_rect);
return meta_screen_get_monitor_for_rect (screen, &window_rect); return meta_screen_get_monitor_for_rect (screen, &window_rect);
} }

View File

@@ -1465,7 +1465,7 @@ window_contains_point (MetaWindow *window,
{ {
MetaRectangle rect; MetaRectangle rect;
meta_window_get_outer_rect (window, &rect); meta_window_get_frame_rect (window, &rect);
return POINT_IN_RECT (root_x, root_y, rect); return POINT_IN_RECT (root_x, root_y, rect);
} }

View File

@@ -352,6 +352,12 @@ struct _MetaWindow
/* if non-NULL, the opaque region _NET_WM_OPAQUE_REGION */ /* if non-NULL, the opaque region _NET_WM_OPAQUE_REGION */
cairo_region_t *opaque_region; cairo_region_t *opaque_region;
/* the input shape region for picking */
cairo_region_t *input_region;
/* _NET_WM_WINDOW_OPACITY */
guint opacity;
/* if TRUE, the we have the new form of sync request counter which /* if TRUE, the we have the new form of sync request counter which
* also handles application frames */ * also handles application frames */
guint extended_sync_request_counter : 1; guint extended_sync_request_counter : 1;
@@ -512,6 +518,7 @@ void meta_window_update_fullscreen_monitors (MetaWindow *window,
unsigned long left, unsigned long left,
unsigned long right); unsigned long right);
/* args to move are window pos, not frame pos */ /* args to move are window pos, not frame pos */
void meta_window_move (MetaWindow *window, void meta_window_move (MetaWindow *window,
gboolean user_op, gboolean user_op,
@@ -655,6 +662,8 @@ void meta_window_recalc_features (MetaWindow *window);
void meta_window_recalc_window_type (MetaWindow *window); void meta_window_recalc_window_type (MetaWindow *window);
void meta_window_frame_size_changed (MetaWindow *window);
void meta_window_stack_just_below (MetaWindow *window, void meta_window_stack_just_below (MetaWindow *window,
MetaWindow *below_this_one); MetaWindow *below_this_one);
@@ -682,8 +691,16 @@ void meta_window_set_opaque_region (MetaWindow *window,
cairo_region_t *region); cairo_region_t *region);
void meta_window_update_opaque_region_x11 (MetaWindow *window); void meta_window_update_opaque_region_x11 (MetaWindow *window);
void meta_window_set_input_region (MetaWindow *window,
cairo_region_t *region);
void meta_window_update_input_region_x11 (MetaWindow *window);
void meta_window_set_shape_region (MetaWindow *window, void meta_window_set_shape_region (MetaWindow *window,
cairo_region_t *region); cairo_region_t *region);
void meta_window_update_shape_region_x11 (MetaWindow *window); void meta_window_update_shape_region_x11 (MetaWindow *window);
void meta_window_set_opacity (MetaWindow *window,
guint opacity);
Window meta_window_get_toplevel_xwindow (MetaWindow *window);
#endif #endif

View File

@@ -316,6 +316,9 @@ reload_gtk_frame_extents (MetaWindow *window,
{ {
window->has_custom_frame_extents = FALSE; window->has_custom_frame_extents = FALSE;
} }
if (!initial)
meta_window_queue(window, META_QUEUE_MOVE_RESIZE);
} }
static void static void
@@ -1706,6 +1709,20 @@ reload_bypass_compositor (MetaWindow *window,
window->bypass_compositor = requested_value; window->bypass_compositor = requested_value;
} }
static void
reload_window_opacity (MetaWindow *window,
MetaPropValue *value,
gboolean initial)
{
int requested_value = 0xFF;
if (value->type != META_PROP_VALUE_INVALID)
requested_value = (int) value->v.cardinal;
meta_window_set_opacity (window, requested_value);
}
#define RELOAD_STRING(var_name, propname) \ #define RELOAD_STRING(var_name, propname) \
static void \ static void \
reload_ ## var_name (MetaWindow *window, \ reload_ ## var_name (MetaWindow *window, \
@@ -1808,6 +1825,7 @@ meta_display_init_window_prop_hooks (MetaDisplay *display)
{ display->atom__NET_WM_STRUT, META_PROP_VALUE_INVALID, reload_struts, FALSE, FALSE }, { display->atom__NET_WM_STRUT, META_PROP_VALUE_INVALID, reload_struts, FALSE, FALSE },
{ display->atom__NET_WM_STRUT_PARTIAL, META_PROP_VALUE_INVALID, reload_struts, FALSE, FALSE }, { display->atom__NET_WM_STRUT_PARTIAL, META_PROP_VALUE_INVALID, reload_struts, FALSE, FALSE },
{ display->atom__NET_WM_BYPASS_COMPOSITOR, META_PROP_VALUE_CARDINAL, reload_bypass_compositor, FALSE, FALSE }, { display->atom__NET_WM_BYPASS_COMPOSITOR, META_PROP_VALUE_CARDINAL, reload_bypass_compositor, FALSE, FALSE },
{ display->atom__NET_WM_WINDOW_OPACITY, META_PROP_VALUE_CARDINAL, reload_window_opacity, TRUE, TRUE },
{ 0 }, { 0 },
}; };

View File

@@ -1194,12 +1194,15 @@ meta_window_new_with_attrs (MetaDisplay *display,
meta_display_register_x_window (display, &window->xwindow, window); meta_display_register_x_window (display, &window->xwindow, window);
meta_window_update_shape_region_x11 (window); meta_window_update_shape_region_x11 (window);
meta_window_update_input_region_x11 (window);
/* Assign this #MetaWindow a sequence number which can be used /* Assign this #MetaWindow a sequence number which can be used
* for sorting. * for sorting.
*/ */
window->stable_sequence = ++display->window_sequence_counter; window->stable_sequence = ++display->window_sequence_counter;
window->opacity = 0xFF;
/* assign the window to its group, or create a new group if needed /* assign the window to its group, or create a new group if needed
*/ */
window->group = NULL; window->group = NULL;
@@ -1444,9 +1447,6 @@ meta_window_new_with_attrs (MetaDisplay *display,
set_net_wm_state (window); set_net_wm_state (window);
} }
if (screen->display->compositor)
meta_compositor_add_window (screen->display->compositor, window);
/* Sync stack changes */ /* Sync stack changes */
meta_stack_thaw (window->screen->stack); meta_stack_thaw (window->screen->stack);
@@ -1669,8 +1669,6 @@ meta_window_unmanage (MetaWindow *window,
if (window->visible_to_compositor) if (window->visible_to_compositor)
meta_compositor_hide_window (window->display->compositor, window, meta_compositor_hide_window (window->display->compositor, window,
META_COMP_EFFECT_DESTROY); META_COMP_EFFECT_DESTROY);
meta_compositor_remove_window (window->display->compositor, window);
} }
if (window->display->window_with_menu == window) if (window->display->window_with_menu == window)
@@ -1869,6 +1867,8 @@ meta_window_unmanage (MetaWindow *window,
meta_window_ungrab_keys (window); meta_window_ungrab_keys (window);
meta_display_ungrab_window_buttons (window->display, window->xwindow); meta_display_ungrab_window_buttons (window->display, window->xwindow);
meta_display_ungrab_focus_window_button (window->display, window); meta_display_ungrab_focus_window_button (window->display, window);
if (window->display->autoraise_window == window)
meta_display_remove_autoraise_callback (window->display);
meta_display_unregister_x_window (window->display, window->xwindow); meta_display_unregister_x_window (window->display, window->xwindow);
@@ -2791,8 +2791,8 @@ static gboolean
windows_overlap (const MetaWindow *w1, const MetaWindow *w2) windows_overlap (const MetaWindow *w1, const MetaWindow *w2)
{ {
MetaRectangle w1rect, w2rect; MetaRectangle w1rect, w2rect;
meta_window_get_outer_rect (w1, &w1rect); meta_window_get_frame_rect (w1, &w1rect);
meta_window_get_outer_rect (w2, &w2rect); meta_window_get_frame_rect (w2, &w2rect);
return meta_rectangle_overlap (&w1rect, &w2rect); return meta_rectangle_overlap (&w1rect, &w2rect);
} }
@@ -3138,7 +3138,7 @@ meta_window_show (MetaWindow *window)
if (toplevel_now_mapped != toplevel_was_mapped) if (toplevel_now_mapped != toplevel_was_mapped)
{ {
if (window->display->compositor) if (window->display->compositor)
meta_compositor_window_mapped (window->display->compositor, window); meta_compositor_add_window (window->display->compositor, window);
} }
if (!window->visible_to_compositor) if (!window->visible_to_compositor)
@@ -3287,13 +3287,7 @@ meta_window_hide (MetaWindow *window)
if (toplevel_now_mapped != toplevel_was_mapped) if (toplevel_now_mapped != toplevel_was_mapped)
{ {
if (window->display->compositor) if (window->display->compositor)
{ meta_compositor_remove_window (window->display->compositor, window);
/* As above, we may be *mapping* live hidden windows */
if (toplevel_now_mapped)
meta_compositor_window_mapped (window->display->compositor, window);
else
meta_compositor_window_unmapped (window->display->compositor, window);
}
} }
set_net_wm_state (window); set_net_wm_state (window);
@@ -3593,11 +3587,11 @@ meta_window_maximize (MetaWindow *window,
MetaRectangle old_rect; MetaRectangle old_rect;
MetaRectangle new_rect; MetaRectangle new_rect;
meta_window_get_outer_rect (window, &old_rect); meta_window_get_frame_rect (window, &old_rect);
meta_window_move_resize_now (window); meta_window_move_resize_now (window);
meta_window_get_outer_rect (window, &new_rect); meta_window_get_frame_rect (window, &new_rect);
meta_compositor_maximize_window (window->display->compositor, meta_compositor_maximize_window (window->display->compositor,
window, window,
&old_rect, &old_rect,
@@ -3656,7 +3650,7 @@ meta_window_get_all_monitors (MetaWindow *window, gsize *length)
int i; int i;
monitors = g_array_new (FALSE, FALSE, sizeof (int)); monitors = g_array_new (FALSE, FALSE, sizeof (int));
meta_window_get_outer_rect (window, &window_rect); meta_window_get_frame_rect (window, &window_rect);
for (i = 0; i < window->screen->n_monitor_infos; i++) for (i = 0; i < window->screen->n_monitor_infos; i++)
{ {
@@ -3689,7 +3683,7 @@ meta_window_is_screen_sized (MetaWindow *window)
int screen_width, screen_height; int screen_width, screen_height;
meta_screen_get_size (window->screen, &screen_width, &screen_height); meta_screen_get_size (window->screen, &screen_width, &screen_height);
meta_window_get_outer_rect (window, &window_rect); meta_window_get_frame_rect (window, &window_rect);
if (window_rect.x == 0 && window_rect.y == 0 && if (window_rect.x == 0 && window_rect.y == 0 &&
window_rect.width == screen_width && window_rect.height == screen_height) window_rect.width == screen_width && window_rect.height == screen_height)
@@ -3718,7 +3712,7 @@ meta_window_is_monitor_sized (MetaWindow *window)
{ {
MetaRectangle window_rect, monitor_rect; MetaRectangle window_rect, monitor_rect;
meta_window_get_outer_rect (window, &window_rect); meta_window_get_frame_rect (window, &window_rect);
meta_screen_get_monitor_geometry (window->screen, window->monitor->number, &monitor_rect); meta_screen_get_monitor_geometry (window->screen, window->monitor->number, &monitor_rect);
if (meta_rectangle_equal (&window_rect, &monitor_rect)) if (meta_rectangle_equal (&window_rect, &monitor_rect))
@@ -3786,11 +3780,11 @@ meta_window_tile (MetaWindow *window)
MetaRectangle old_rect; MetaRectangle old_rect;
MetaRectangle new_rect; MetaRectangle new_rect;
meta_window_get_outer_rect (window, &old_rect); meta_window_get_frame_rect (window, &old_rect);
meta_window_move_resize_now (window); meta_window_move_resize_now (window);
meta_window_get_outer_rect (window, &new_rect); meta_window_get_frame_rect (window, &new_rect);
meta_compositor_maximize_window (window->display->compositor, meta_compositor_maximize_window (window->display->compositor,
window, window,
&old_rect, &old_rect,
@@ -3819,7 +3813,7 @@ meta_window_can_tile_side_by_side (MetaWindow *window)
{ {
int monitor; int monitor;
MetaRectangle tile_area; MetaRectangle tile_area;
MetaFrameBorders borders; MetaRectangle client_rect;
if (!meta_window_can_tile_maximized (window)) if (!meta_window_can_tile_maximized (window))
return FALSE; return FALSE;
@@ -3833,13 +3827,10 @@ meta_window_can_tile_side_by_side (MetaWindow *window)
tile_area.width /= 2; tile_area.width /= 2;
meta_frame_calc_borders (window->frame, &borders); meta_window_frame_rect_to_client_rect (window, &tile_area, &client_rect);
tile_area.width -= (borders.visible.left + borders.visible.right); return client_rect.width >= window->size_hints.min_width &&
tile_area.height -= (borders.visible.top + borders.visible.bottom); client_rect.height >= window->size_hints.min_height;
return tile_area.width >= window->size_hints.min_width &&
tile_area.height >= window->size_hints.min_height;
} }
static void static void
@@ -3900,8 +3891,10 @@ meta_window_unmaximize_internal (MetaWindow *window,
{ {
MetaRectangle target_rect; MetaRectangle target_rect;
MetaRectangle work_area; MetaRectangle work_area;
MetaRectangle old_rect;
meta_window_get_work_area_for_monitor (window, window->monitor->number, &work_area); meta_window_get_work_area_for_monitor (window, window->monitor->number, &work_area);
meta_window_get_frame_rect (window, &old_rect);
meta_topic (META_DEBUG_WINDOW_OPS, meta_topic (META_DEBUG_WINDOW_OPS,
"Unmaximizing %s%s\n", "Unmaximizing %s%s\n",
@@ -3915,6 +3908,12 @@ meta_window_unmaximize_internal (MetaWindow *window,
window->maximized_vertically = window->maximized_vertically =
window->maximized_vertically && !unmaximize_vertically; window->maximized_vertically && !unmaximize_vertically;
/* recalc_window_features() will eventually clear the cached frame
* extents, but we need the correct frame extents in the code below,
* so invalidate the old frame extents manually up front.
*/
meta_window_frame_size_changed (window);
/* Unmaximize to the saved_rect position in the direction(s) /* Unmaximize to the saved_rect position in the direction(s)
* being unmaximized. * being unmaximized.
*/ */
@@ -3959,9 +3958,7 @@ meta_window_unmaximize_internal (MetaWindow *window,
if (window->display->compositor) if (window->display->compositor)
{ {
MetaRectangle old_rect, new_rect; MetaRectangle new_rect;
meta_window_get_outer_rect (window, &old_rect);
meta_window_move_resize_internal (window, meta_window_move_resize_internal (window,
META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION, META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION,
@@ -3971,7 +3968,7 @@ meta_window_unmaximize_internal (MetaWindow *window,
target_rect.width, target_rect.width,
target_rect.height); target_rect.height);
meta_window_get_outer_rect (window, &new_rect); meta_window_get_frame_rect (window, &new_rect);
meta_compositor_unmaximize_window (window->display->compositor, meta_compositor_unmaximize_window (window->display->compositor,
window, window,
&old_rect, &old_rect,
@@ -4076,6 +4073,7 @@ meta_window_set_above (MetaWindow *window,
window->wm_state_above = new_value; window->wm_state_above = new_value;
meta_window_update_layer (window); meta_window_update_layer (window);
set_net_wm_state (window); set_net_wm_state (window);
meta_window_frame_size_changed (window);
g_object_notify (G_OBJECT (window), "above"); g_object_notify (G_OBJECT (window), "above");
} }
@@ -4215,6 +4213,7 @@ meta_window_shade (MetaWindow *window,
window->shaded = TRUE; window->shaded = TRUE;
meta_window_queue(window, META_QUEUE_MOVE_RESIZE | META_QUEUE_CALC_SHOWING); meta_window_queue(window, META_QUEUE_MOVE_RESIZE | META_QUEUE_CALC_SHOWING);
meta_window_frame_size_changed (window);
/* After queuing the calc showing, since _focus flushes it, /* After queuing the calc showing, since _focus flushes it,
* and we need to focus the frame * and we need to focus the frame
@@ -4240,6 +4239,7 @@ meta_window_unshade (MetaWindow *window,
{ {
window->shaded = FALSE; window->shaded = FALSE;
meta_window_queue(window, META_QUEUE_MOVE_RESIZE | META_QUEUE_CALC_SHOWING); meta_window_queue(window, META_QUEUE_MOVE_RESIZE | META_QUEUE_CALC_SHOWING);
meta_window_frame_size_changed (window);
/* focus the window */ /* focus the window */
meta_topic (META_DEBUG_FOCUS, meta_topic (META_DEBUG_FOCUS,
@@ -4967,7 +4967,6 @@ meta_window_move_resize_internal (MetaWindow *window,
did_placement = !window->placed && window->calc_placement; did_placement = !window->placed && window->calc_placement;
meta_window_constrain (window, meta_window_constrain (window,
window->frame ? &borders : NULL,
flags, flags,
gravity, gravity,
&old_rect, &old_rect,
@@ -5396,23 +5395,10 @@ meta_window_move_frame (MetaWindow *window,
int root_x_nw, int root_x_nw,
int root_y_nw) int root_y_nw)
{ {
int x = root_x_nw; MetaRectangle rect = { root_x_nw, root_y_nw, 0, 0 };
int y = root_y_nw;
if (window->frame) meta_window_frame_rect_to_client_rect (window, &rect, &rect);
{ meta_window_move (window, user_op, rect.x, rect.y);
MetaFrameBorders borders;
meta_frame_calc_borders (window->frame, &borders);
/* root_x_nw and root_y_nw correspond to where the top of
* the visible frame should be. Offset by the distance between
* the origin of the window and the origin of the enclosing
* window decorations.
*/
x += window->frame->child_x - borders.invisible.left;
y += window->frame->child_y - borders.invisible.top;
}
meta_window_move (window, user_op, x, y);
} }
static void static void
@@ -5460,18 +5446,10 @@ meta_window_move_resize_frame (MetaWindow *window,
int w, int w,
int h) int h)
{ {
MetaFrameBorders borders; MetaRectangle rect = { root_x_nw, root_y_nw, w, h };
meta_window_frame_rect_to_client_rect (window, &rect, &rect);
meta_frame_calc_borders (window->frame, &borders); meta_window_move_resize (window, user_op, rect.x, rect.y, rect.width, rect.height);
/* offset by the distance between the origin of the window
* and the origin of the enclosing window decorations ( + border)
*/
root_x_nw += borders.visible.left;
root_y_nw += borders.visible.top;
w -= borders.visible.left + borders.visible.right;
h -= borders.visible.top + borders.visible.bottom;
meta_window_move_resize (window, user_op, root_x_nw, root_y_nw, w, h);
} }
/** /**
@@ -5784,16 +5762,110 @@ meta_window_get_input_rect (const MetaWindow *window,
} }
/** /**
* meta_window_get_outer_rect: * meta_window_client_rect_to_frame_rect:
* @window: a #MetaWindow
* @client_rect: client rectangle in root coordinates
* @frame_rect: (out): location to store the computed corresponding frame bounds.
*
* Converts a desired bounds of the client window - what is passed to meta_window_move_resize() -
* into the corresponding bounds of the window frame (excluding invisible borders
* and client side shadows.)
*/
void
meta_window_client_rect_to_frame_rect (MetaWindow *window,
MetaRectangle *client_rect,
MetaRectangle *frame_rect)
{
if (!frame_rect)
return;
*frame_rect = *client_rect;
/* The support for G_MAXINT here to mean infinity is a convenience for
* constraints.c:get_size_limits() and not something that we provide
* in other locations or document.
*/
if (window->frame)
{
MetaFrameBorders borders;
meta_frame_calc_borders (window->frame, &borders);
frame_rect->x -= borders.visible.left;
frame_rect->y -= borders.visible.top;
if (frame_rect->width != G_MAXINT)
frame_rect->width += borders.visible.left + borders.visible.right;
if (frame_rect->height != G_MAXINT)
frame_rect->height += borders.visible.top + borders.visible.bottom;
}
else
{
if (window->has_custom_frame_extents)
{
const GtkBorder *extents = &window->custom_frame_extents;
frame_rect->x += extents->left;
frame_rect->y += extents->top;
if (frame_rect->width != G_MAXINT)
frame_rect->width -= extents->left + extents->right;
if (frame_rect->height != G_MAXINT)
frame_rect->height -= extents->top + extents->bottom;
}
}
}
/**
* meta_window_frame_rect_to_client_rect:
* @window: a #MetaWindow
* @frame_rect: desired frame bounds for the window
* @client_rect: (out): location to store the computed corresponding client rectangle.
*
* Converts a desired frame bounds for a window into the bounds of the client
* window - what is passed to meta_window_move_resize().
*/
void
meta_window_frame_rect_to_client_rect (MetaWindow *window,
MetaRectangle *frame_rect,
MetaRectangle *client_rect)
{
if (!client_rect)
return;
*client_rect = *frame_rect;
if (window->frame)
{
MetaFrameBorders borders;
meta_frame_calc_borders (window->frame, &borders);
client_rect->x += borders.visible.left;
client_rect->y += borders.visible.top;
client_rect->width -= borders.visible.left + borders.visible.right;
client_rect->height -= borders.visible.top + borders.visible.bottom;
}
else
{
if (window->has_custom_frame_extents)
{
const GtkBorder *extents = &window->custom_frame_extents;
client_rect->x -= extents->left;
client_rect->y -= extents->top;
client_rect->width += extents->left + extents->right;
client_rect->height += extents->top + extents->bottom;
}
}
}
/**
* meta_window_get_frame_rect:
* @window: a #MetaWindow * @window: a #MetaWindow
* @rect: (out): pointer to an allocated #MetaRectangle * @rect: (out): pointer to an allocated #MetaRectangle
* *
* Gets the rectangle that bounds @window that is responsive to mouse events. * Gets the rectangle that bounds @window that is what the user thinks of
* This includes only what is visible; it doesn't include any extra reactive * as the edge of the window. This doesn't include any extra reactive
* area we add to the edges of windows. * area that we or the client adds to the window, or any area that the
* client adds to draw a client-side shadow.
*/ */
void void
meta_window_get_outer_rect (const MetaWindow *window, meta_window_get_frame_rect (const MetaWindow *window,
MetaRectangle *rect) MetaRectangle *rect)
{ {
if (window->frame) if (window->frame)
@@ -5822,6 +5894,25 @@ meta_window_get_outer_rect (const MetaWindow *window,
} }
} }
/**
* meta_window_get_outer_rect:
* @window: a #MetaWindow
* @rect: (out): pointer to an allocated #MetaRectangle
*
* Gets the rectangle that bounds @window that is what the user thinks of
* as the edge of the window. This doesn't include any extra reactive
* area that we or the client adds to the window, or any area that the
* client adds to draw a client-side shadow.
*
* Deprecated: 3.12: Use meta_window_get_frame_rect() instead.
*/
void
meta_window_get_outer_rect (const MetaWindow *window,
MetaRectangle *rect)
{
meta_window_get_frame_rect (window, rect);
}
const char* const char*
meta_window_get_startup_id (MetaWindow *window) meta_window_get_startup_id (MetaWindow *window)
{ {
@@ -6043,6 +6134,7 @@ window_stick_impl (MetaWindow *window)
* toggled back off. * toggled back off.
*/ */
window->on_all_workspaces_requested = TRUE; window->on_all_workspaces_requested = TRUE;
meta_window_frame_size_changed (window);
meta_window_update_on_all_workspaces (window); meta_window_update_on_all_workspaces (window);
meta_window_queue(window, META_QUEUE_CALC_SHOWING); meta_window_queue(window, META_QUEUE_CALC_SHOWING);
@@ -6057,6 +6149,7 @@ window_unstick_impl (MetaWindow *window)
/* Revert to window->workspaces */ /* Revert to window->workspaces */
window->on_all_workspaces_requested = FALSE; window->on_all_workspaces_requested = FALSE;
meta_window_frame_size_changed (window);
meta_window_update_on_all_workspaces (window); meta_window_update_on_all_workspaces (window);
/* We change ourselves to the active workspace, since otherwise you'd get /* We change ourselves to the active workspace, since otherwise you'd get
@@ -6563,8 +6656,7 @@ meta_window_property_notify (MetaWindow *window,
void void
meta_window_change_workspace_by_index (MetaWindow *window, meta_window_change_workspace_by_index (MetaWindow *window,
gint space_index, gint space_index,
gboolean append, gboolean append)
guint32 timestamp)
{ {
MetaWorkspace *workspace; MetaWorkspace *workspace;
MetaScreen *screen; MetaScreen *screen;
@@ -6583,11 +6675,7 @@ meta_window_change_workspace_by_index (MetaWindow *window,
meta_screen_get_workspace_by_index (screen, space_index); meta_screen_get_workspace_by_index (screen, space_index);
if (!workspace && append) if (!workspace && append)
{ workspace = meta_screen_append_new_workspace (screen, FALSE, CurrentTime);
if (timestamp == CurrentTime)
timestamp = meta_display_get_current_time_roundtrip (window->display);
workspace = meta_screen_append_new_workspace (screen, FALSE, timestamp);
}
if (workspace) if (workspace)
{ {
@@ -7137,6 +7225,7 @@ static void
meta_window_appears_focused_changed (MetaWindow *window) meta_window_appears_focused_changed (MetaWindow *window)
{ {
set_net_wm_state (window); set_net_wm_state (window);
meta_window_frame_size_changed (window);
g_object_notify (G_OBJECT (window), "appears-focused"); g_object_notify (G_OBJECT (window), "appears-focused");
@@ -7717,6 +7806,91 @@ meta_window_set_shape_region (MetaWindow *window,
meta_compositor_window_shape_changed (window->display->compositor, window); meta_compositor_window_shape_changed (window->display->compositor, window);
} }
void
meta_window_update_input_region_x11 (MetaWindow *window)
{
cairo_region_t *region = NULL;
#ifdef HAVE_SHAPE
if (META_DISPLAY_HAS_SHAPE (window->display))
{
/* Translate the set of XShape rectangles that we
* get from the X server to a cairo_region. */
XRectangle *rects = NULL;
int n_rects, ordering;
int x_bounding, y_bounding, x_clip, y_clip;
unsigned w_bounding, h_bounding, w_clip, h_clip;
int bounding_shaped, clip_shaped;
meta_error_trap_push (window->display);
XShapeQueryExtents (window->display->xdisplay, window->xwindow,
&bounding_shaped, &x_bounding, &y_bounding,
&w_bounding, &h_bounding,
&clip_shaped, &x_clip, &y_clip,
&w_clip, &h_clip);
rects = XShapeGetRectangles (window->display->xdisplay,
window->xwindow,
ShapeInput,
&n_rects,
&ordering);
meta_error_trap_pop (window->display);
/* XXX: The x shape extension doesn't provide a way to only test if an
* input shape has been specified, so we have to query and throw away the
* rectangles. */
if (rects)
{
if (n_rects > 1 ||
(n_rects == 1 &&
(rects[0].x != x_bounding ||
rects[1].y != y_bounding ||
rects[2].width != w_bounding ||
rects[3].height != h_bounding)))
region = region_create_from_x_rectangles (rects, n_rects);
XFree (rects);
}
}
#endif /* HAVE_SHAPE */
if (region != NULL)
{
cairo_rectangle_int_t client_area;
client_area.x = 0;
client_area.y = 0;
client_area.width = window->rect.width;
client_area.height = window->rect.height;
/* The shape we get back from the client may have coordinates
* outside of the frame. The X SHAPE Extension requires that
* the overall shape the client provides never exceeds the
* "bounding rectangle" of the window -- the shape that the
* window would have gotten if it was unshaped. In our case,
* this is simply the client area.
*/
cairo_region_intersect_rectangle (region, &client_area);
}
meta_window_set_input_region (window, region);
cairo_region_destroy (region);
}
void
meta_window_set_input_region (MetaWindow *window,
cairo_region_t *region)
{
g_clear_pointer (&window->input_region, cairo_region_destroy);
if (region != NULL)
window->input_region = cairo_region_reference (region);
if (window->display->compositor)
meta_compositor_window_shape_changed (window->display->compositor, window);
}
void void
meta_window_update_shape_region_x11 (MetaWindow *window) meta_window_update_shape_region_x11 (MetaWindow *window)
{ {
@@ -8224,6 +8398,13 @@ recalc_window_type (MetaWindow *window)
} }
} }
void
meta_window_frame_size_changed (MetaWindow *window)
{
if (window->frame)
meta_frame_clear_cached_borders (window->frame);
}
static void static void
set_allowed_actions_hint (MetaWindow *window) set_allowed_actions_hint (MetaWindow *window)
{ {
@@ -8423,18 +8604,13 @@ recalc_window_features (MetaWindow *window)
if (window->has_maximize_func) if (window->has_maximize_func)
{ {
MetaRectangle work_area; MetaRectangle work_area, client_rect;
MetaFrameBorders borders;
int min_frame_width, min_frame_height;
meta_window_get_work_area_current_monitor (window, &work_area); meta_window_get_work_area_current_monitor (window, &work_area);
meta_frame_calc_borders (window->frame, &borders); meta_window_frame_rect_to_client_rect (window, &work_area, &client_rect);
min_frame_width = window->size_hints.min_width + borders.visible.left + borders.visible.right; if (window->size_hints.min_width >= client_rect.width ||
min_frame_height = window->size_hints.min_height + borders.visible.top + borders.visible.bottom; window->size_hints.min_height >= client_rect.height)
if (min_frame_width >= work_area.width ||
min_frame_height >= work_area.height)
window->has_maximize_func = FALSE; window->has_maximize_func = FALSE;
} }
@@ -8527,6 +8703,8 @@ recalc_window_features (MetaWindow *window)
if (window->has_resize_func != old_has_resize_func) if (window->has_resize_func != old_has_resize_func)
g_object_notify (G_OBJECT (window), "resizeable"); g_object_notify (G_OBJECT (window), "resizeable");
meta_window_frame_size_changed (window);
/* FIXME perhaps should ensure if we don't have a shade func, /* FIXME perhaps should ensure if we don't have a shade func,
* we aren't shaded, etc. * we aren't shaded, etc.
*/ */
@@ -8803,7 +8981,7 @@ meta_window_show_menu (MetaWindow *window,
void void
meta_window_shove_titlebar_onscreen (MetaWindow *window) meta_window_shove_titlebar_onscreen (MetaWindow *window)
{ {
MetaRectangle outer_rect; MetaRectangle frame_rect;
GList *onscreen_region; GList *onscreen_region;
int horiz_amount, vert_amount; int horiz_amount, vert_amount;
int newx, newy; int newx, newy;
@@ -8815,15 +8993,15 @@ meta_window_shove_titlebar_onscreen (MetaWindow *window)
return; return;
/* Get the basic info we need */ /* Get the basic info we need */
meta_window_get_outer_rect (window, &outer_rect); meta_window_get_frame_rect (window, &frame_rect);
onscreen_region = window->screen->active_workspace->screen_region; onscreen_region = window->screen->active_workspace->screen_region;
/* Extend the region (just in case the window is too big to fit on the /* Extend the region (just in case the window is too big to fit on the
* screen), then shove the window on screen, then return the region to * screen), then shove the window on screen, then return the region to
* normal. * normal.
*/ */
horiz_amount = outer_rect.width; horiz_amount = frame_rect.width;
vert_amount = outer_rect.height; vert_amount = frame_rect.height;
meta_rectangle_expand_region (onscreen_region, meta_rectangle_expand_region (onscreen_region,
horiz_amount, horiz_amount,
horiz_amount, horiz_amount,
@@ -8831,15 +9009,15 @@ meta_window_shove_titlebar_onscreen (MetaWindow *window)
vert_amount); vert_amount);
meta_rectangle_shove_into_region(onscreen_region, meta_rectangle_shove_into_region(onscreen_region,
FIXED_DIRECTION_X, FIXED_DIRECTION_X,
&outer_rect); &frame_rect);
meta_rectangle_expand_region (onscreen_region, meta_rectangle_expand_region (onscreen_region,
-horiz_amount, -horiz_amount,
-horiz_amount, -horiz_amount,
0, 0,
-vert_amount); -vert_amount);
newx = outer_rect.x + window->frame->child_x; newx = frame_rect.x + window->frame->child_x;
newy = outer_rect.y + window->frame->child_y; newy = frame_rect.y + window->frame->child_y;
meta_window_move_resize (window, meta_window_move_resize (window,
FALSE, FALSE,
newx, newx,
@@ -8864,7 +9042,7 @@ meta_window_titlebar_is_onscreen (MetaWindow *window)
return FALSE; return FALSE;
/* Get the rectangle corresponding to the titlebar */ /* Get the rectangle corresponding to the titlebar */
meta_window_get_outer_rect (window, &titlebar_rect); meta_window_get_frame_rect (window, &titlebar_rect);
titlebar_rect.height = window->frame->child_y; titlebar_rect.height = window->frame->child_y;
/* Run through the spanning rectangles for the screen and see if one of /* Run through the spanning rectangles for the screen and see if one of
@@ -9711,7 +9889,8 @@ meta_window_handle_mouse_grab_op_event (MetaWindow *window,
switch (xev->evtype) switch (xev->evtype)
{ {
case XI_ButtonRelease: case XI_ButtonRelease:
if (xev->detail == 1) if (xev->detail == 1 ||
xev->detail == meta_prefs_get_mouse_button_resize ())
{ {
meta_display_check_threshold_reached (window->display, meta_display_check_threshold_reached (window->display,
xev->root_x, xev->root_x,
@@ -10165,7 +10344,7 @@ warp_grab_pointer (MetaWindow *window,
/* We may not have done begin_grab_op yet, i.e. may not be in a grab /* We may not have done begin_grab_op yet, i.e. may not be in a grab
*/ */
meta_window_get_outer_rect (window, &rect); meta_window_get_frame_rect (window, &rect);
switch (grab_op) switch (grab_op)
{ {
@@ -10504,7 +10683,7 @@ meta_window_set_demands_attention (MetaWindow *window)
} }
else else
{ {
meta_window_get_outer_rect (window, &candidate_rect); meta_window_get_frame_rect (window, &candidate_rect);
/* The stack is sorted with the top windows first. */ /* The stack is sorted with the top windows first. */
@@ -10515,7 +10694,7 @@ meta_window_set_demands_attention (MetaWindow *window)
if (meta_window_located_on_workspace (other_window, window->workspace)) if (meta_window_located_on_workspace (other_window, window->workspace))
{ {
meta_window_get_outer_rect (other_window, &other_rect); meta_window_get_frame_rect (other_window, &other_rect);
if (meta_rectangle_overlap (&candidate_rect, &other_rect)) if (meta_rectangle_overlap (&candidate_rect, &other_rect))
{ {
@@ -11219,8 +11398,8 @@ meta_window_compute_tile_match (MetaWindow *window)
bottommost = match; bottommost = match;
} }
meta_window_get_outer_rect (bottommost, &bottommost_rect); meta_window_get_frame_rect (bottommost, &bottommost_rect);
meta_window_get_outer_rect (topmost, &topmost_rect); meta_window_get_frame_rect (topmost, &topmost_rect);
/* /*
* If there's a window stacked in between which is partially visible * If there's a window stacked in between which is partially visible
* behind the topmost tile we don't consider the tiles to match. * behind the topmost tile we don't consider the tiles to match.
@@ -11234,7 +11413,7 @@ meta_window_compute_tile_match (MetaWindow *window)
meta_window_get_workspace (above) != meta_window_get_workspace (window)) meta_window_get_workspace (above) != meta_window_get_workspace (window))
continue; continue;
meta_window_get_outer_rect (above, &above_rect); meta_window_get_frame_rect (above, &above_rect);
if (meta_rectangle_overlap (&above_rect, &bottommost_rect) && if (meta_rectangle_overlap (&above_rect, &bottommost_rect) &&
meta_rectangle_overlap (&above_rect, &topmost_rect)) meta_rectangle_overlap (&above_rect, &topmost_rect))
@@ -11250,3 +11429,19 @@ meta_window_can_close (MetaWindow *window)
{ {
return window->has_close_func; return window->has_close_func;
} }
Window
meta_window_get_toplevel_xwindow (MetaWindow *window)
{
return window->frame ? window->frame->xwindow : window->xwindow;
}
void
meta_window_set_opacity (MetaWindow *window,
guint opacity)
{
window->opacity = opacity;
if (window->display->compositor)
meta_compositor_window_opacity_changed (window->display->compositor, window);
}

View File

@@ -81,6 +81,7 @@ item(TIMESTAMP)
item(VERSION) item(VERSION)
item(ATOM_PAIR) item(ATOM_PAIR)
item(BACKLIGHT) item(BACKLIGHT)
item(hotplug_mode_update)
/* Oddities: These are used, and we need atoms for them, /* Oddities: These are used, and we need atoms for them,
* but when we need all _NET_WM hints (i.e. when we're making * but when we need all _NET_WM hints (i.e. when we're making
@@ -178,6 +179,7 @@ item(_NET_WM_BYPASS_COMPOSITOR)
item(_NET_WM_OPAQUE_REGION) item(_NET_WM_OPAQUE_REGION)
item(_NET_WM_FRAME_DRAWN) item(_NET_WM_FRAME_DRAWN)
item(_NET_WM_FRAME_TIMINGS) item(_NET_WM_FRAME_TIMINGS)
item(_NET_WM_WINDOW_OPACITY)
#if 0 #if 0
/* We apparently never use: */ /* We apparently never use: */

View File

@@ -66,6 +66,8 @@ void meta_compositor_unmanage_screen (MetaCompositor *compositor,
void meta_compositor_window_shape_changed (MetaCompositor *compositor, void meta_compositor_window_shape_changed (MetaCompositor *compositor,
MetaWindow *window); MetaWindow *window);
void meta_compositor_window_opacity_changed (MetaCompositor *compositor,
MetaWindow *window);
gboolean meta_compositor_process_event (MetaCompositor *compositor, gboolean meta_compositor_process_event (MetaCompositor *compositor,
XEvent *event, XEvent *event,
@@ -75,11 +77,10 @@ gboolean meta_compositor_filter_keybinding (MetaCompositor *compositor,
MetaScreen *screen, MetaScreen *screen,
MetaKeyBinding *binding); MetaKeyBinding *binding);
void meta_compositor_add_window (MetaCompositor *compositor, void meta_compositor_add_window (MetaCompositor *compositor,
MetaWindow *window); MetaWindow *window);
void meta_compositor_remove_window (MetaCompositor *compositor, void meta_compositor_remove_window (MetaCompositor *compositor,
MetaWindow *window); MetaWindow *window);
void meta_compositor_show_window (MetaCompositor *compositor, void meta_compositor_show_window (MetaCompositor *compositor,
MetaWindow *window, MetaWindow *window,
MetaCompEffect effect); MetaCompEffect effect);
@@ -101,10 +102,6 @@ void meta_compositor_unmaximize_window (MetaCompositor *compositor,
MetaRectangle *old_rect, MetaRectangle *old_rect,
MetaRectangle *new_rect); MetaRectangle *new_rect);
void meta_compositor_window_mapped (MetaCompositor *compositor,
MetaWindow *window);
void meta_compositor_window_unmapped (MetaCompositor *compositor,
MetaWindow *window);
void meta_compositor_sync_window_geometry (MetaCompositor *compositor, void meta_compositor_sync_window_geometry (MetaCompositor *compositor,
MetaWindow *window, MetaWindow *window,
gboolean did_placement); gboolean did_placement);

View File

@@ -35,13 +35,6 @@ gboolean meta_keybindings_set_custom_handler (const gchar *name,
gpointer user_data, gpointer user_data,
GDestroyNotify free_data); GDestroyNotify free_data);
void meta_keybindings_switch_window (MetaDisplay *display,
MetaScreen *screen,
MetaWindow *event_window,
XIDeviceEvent *event,
MetaKeyBinding *binding);
void meta_screen_ungrab_all_keys (MetaScreen *screen, guint32 timestamp); void meta_screen_ungrab_all_keys (MetaScreen *screen, guint32 timestamp);
gboolean meta_screen_grab_all_keys (MetaScreen *screen, guint32 timestamp); gboolean meta_screen_grab_all_keys (MetaScreen *screen, guint32 timestamp);
#endif #endif

View File

@@ -83,6 +83,8 @@ CoglTexture * meta_shaped_texture_get_texture (MetaShapedTexture *stex);
void meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex, void meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex,
CoglTexture *mask_texture); CoglTexture *mask_texture);
void meta_shaped_texture_set_input_shape_region (MetaShapedTexture *stex,
cairo_region_t *shape_region);
void meta_shaped_texture_set_clip_region (MetaShapedTexture *stex, void meta_shaped_texture_set_clip_region (MetaShapedTexture *stex,
cairo_region_t *clip_region); cairo_region_t *clip_region);

View File

@@ -258,6 +258,7 @@ void meta_prefs_set_ignore_request_hide_titlebar (gboolean whether);
* @META_KEYBINDING_ACTION_MOVE_TO_SIDE_W: FILLME * @META_KEYBINDING_ACTION_MOVE_TO_SIDE_W: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_CENTER: FILLME * @META_KEYBINDING_ACTION_MOVE_TO_CENTER: FILLME
* @META_KEYBINDING_ACTION_OVERLAY_KEY: FILLME * @META_KEYBINDING_ACTION_OVERLAY_KEY: FILLME
* @META_KEYBINDING_ACTION_ALWAYS_ON_TOP: FILLME
* @META_KEYBINDING_ACTION_LAST: FILLME * @META_KEYBINDING_ACTION_LAST: FILLME
*/ */
/* XXX FIXME This should be x-macroed, but isn't yet because it would be /* XXX FIXME This should be x-macroed, but isn't yet because it would be
@@ -351,6 +352,7 @@ typedef enum _MetaKeyBindingAction
META_KEYBINDING_ACTION_MOVE_TO_CENTER, META_KEYBINDING_ACTION_MOVE_TO_CENTER,
META_KEYBINDING_ACTION_OVERLAY_KEY, META_KEYBINDING_ACTION_OVERLAY_KEY,
META_KEYBINDING_ACTION_ISO_NEXT_GROUP, META_KEYBINDING_ACTION_ISO_NEXT_GROUP,
META_KEYBINDING_ACTION_ALWAYS_ON_TOP,
META_KEYBINDING_ACTION_LAST META_KEYBINDING_ACTION_LAST
} MetaKeyBindingAction; } MetaKeyBindingAction;

View File

@@ -100,7 +100,17 @@ gboolean meta_window_is_override_redirect (MetaWindow *window);
gboolean meta_window_is_skip_taskbar (MetaWindow *window); gboolean meta_window_is_skip_taskbar (MetaWindow *window);
MetaRectangle *meta_window_get_rect (MetaWindow *window); MetaRectangle *meta_window_get_rect (MetaWindow *window);
void meta_window_get_input_rect (const MetaWindow *window, MetaRectangle *rect); void meta_window_get_input_rect (const MetaWindow *window, MetaRectangle *rect);
void meta_window_get_outer_rect (const MetaWindow *window, MetaRectangle *rect);
void meta_window_get_frame_rect (const MetaWindow *window, MetaRectangle *rect);
void meta_window_get_outer_rect (const MetaWindow *window, MetaRectangle *rect) G_GNUC_DEPRECATED;
void meta_window_client_rect_to_frame_rect (MetaWindow *window,
MetaRectangle *client_rect,
MetaRectangle *frame_rect);
void meta_window_frame_rect_to_client_rect (MetaWindow *window,
MetaRectangle *frame_rect,
MetaRectangle *client_rect);
MetaScreen *meta_window_get_screen (MetaWindow *window); MetaScreen *meta_window_get_screen (MetaWindow *window);
MetaDisplay *meta_window_get_display (MetaWindow *window); MetaDisplay *meta_window_get_display (MetaWindow *window);
Window meta_window_get_xwindow (MetaWindow *window); Window meta_window_get_xwindow (MetaWindow *window);
@@ -140,8 +150,7 @@ void meta_window_unset_demands_attention (MetaWindow *window);
const char* meta_window_get_startup_id (MetaWindow *window); const char* meta_window_get_startup_id (MetaWindow *window);
void meta_window_change_workspace_by_index (MetaWindow *window, void meta_window_change_workspace_by_index (MetaWindow *window,
gint space_index, gint space_index,
gboolean append, gboolean append);
guint32 timestamp);
void meta_window_change_workspace (MetaWindow *window, void meta_window_change_workspace (MetaWindow *window,
MetaWorkspace *workspace); MetaWorkspace *workspace);
GObject *meta_window_get_compositor_private (MetaWindow *window); GObject *meta_window_get_compositor_private (MetaWindow *window);