Compare commits

..

10 Commits

Author SHA1 Message Date
75af6fc40c Bump version to 3.0.2.1
Update NEWS
2011-05-25 15:42:10 -04:00
bbfcde1caa Make session saving work a bit better
Previously, the restart command hardcoded "mutter" as the binary name.
This commit changes it to use g_get_prgname() which has a better chance
of being correct (and it does fix session saving for gnome-shell).

Now that mutter is a library, it might be more correct (but also
much higher overhead) to add api for setting these things from
the outside.

https://bugzilla.gnome.org/show_bug.cgi?id=648828
2011-05-25 15:39:23 -04:00
31e6cdf345 Bump version to 3.0.2
Update NEWS
2011-05-25 14:40:58 -04:00
c8aaa5e33e Fix crash in meta_display_get_above_tab_keycode
https://bugzilla.gnome.org/show_bug.cgi?id=647777
2011-05-25 14:22:57 -04:00
65aa3e3927 window: don't allow side-by-side tiling of non-maximizable windows
If a window is not maximizable, then that probably means it looks dumb
at very large sizes. Even if its hints would allow you to manually
resize it to a large size, don't allow automatically tiling it to half
the screen.

https://bugzilla.gnome.org/show_bug.cgi?id=647901
2011-05-23 23:50:14 -04:00
b192771b93 Filter mirrored monitors from the monitors list
For the purposes of window placement or arranging window manager or
plugin controls, screens that are just mirrors of other screens should
be ignored, so filter them out of the monitors list.

https://bugzilla.gnome.org/show_bug.cgi?id=649299
2011-05-23 23:49:58 -04:00
c1977b6532 region-utils.c: Squash a memory leak
"chunk" was an allocated but unused variable.

https://bugzilla.gnome.org/show_bug.cgi?id=649504
2011-05-23 23:49:33 -04:00
50d1b53267 theme.c: Squash memory leak
When converting a token to a different type, we need to free its
string.

https://bugzilla.gnome.org/show_bug.cgi?id=649500
2011-05-23 23:49:10 -04:00
cbec96a62f Make _NET_WM_WINDOW_OPACITY orthogonal to window actor opacity
Using MetaWindowActor.opacity for _NET_WM_WINDOW_OPACITY makes it
difficult to implement effects like fading a window in on map.
Instead, set the opacity on the MetaShadedTexture child and use
it when drawing the shadow.

Since the check MetaWindowGroup does on meta_actor_get_paint_opacity()
no longer covers this, we need to handle the opacity in
meta_window_actor_get_obscured_region() explicitly.

https://bugzilla.gnome.org/show_bug.cgi?id=648613
2011-05-23 23:48:48 -04:00
a28a5749db Added UG translation 2011-05-02 18:48:56 +02:00
177 changed files with 73101 additions and 61925 deletions

12
.gitignore vendored
View File

@ -19,9 +19,6 @@ libtool
ltmain.sh
missing
.deps
src/50-mutter-navigation.xml
src/50-mutter-system.xml
src/50-mutter-windows.xml
src/mutter-wm.desktop
src/mutter.desktop
*.o
@ -43,7 +40,6 @@ stamp-h1
stamp-it
.intltool-merge-cache
POTFILES
po/*.pot
50-metacity-desktop-key.xml
50-metacity-key.xml
inlinepixbufs.h
@ -51,8 +47,7 @@ libmutter.pc
mutter
mutter-theme-viewer
mutter.desktop
org.gnome.mutter.gschema.valid
org.gnome.mutter.gschema.xml
mutter.schemas
testasyncgetprop
testboxes
testgradient
@ -61,13 +56,10 @@ mutter-mag
mutter-message
mutter-window-demo
focus-window
test-attached
test-gravity
test-resizing
test-size-hints
# We can't say just "wm-tester" here or it will ignore the directory
# rather than the binary
src/wm-tester/wm-tester
wm-tester
INSTALL
mkinstalldirs
src/mutter-enum-types.[ch]

View File

@ -42,10 +42,10 @@ Minimal Building/Testing Environment
build a development version of Metacity -- odds are, you may be able
to build metacity from CVS without building any other modules.
As long as you have gtk+ >= 3.0 and GIO >= 2.25.10 with your distro
(gtk+ >= 2.6 if you manually revert the change from bug 348633), you
should be able to install your distro's development packages
(e.g. gtk2-devel, glib-devel, startup-notification-devel on
As long as you have gtk+ >= 2.10 and GConf with your distro (gtk+ >=
2.6 if you manually revert the change from bug 348633), you should
be able to install your distro's development packages
(e.g. gtk2-devel, GConf2-devel, startup-notification-devel on
Fedora; also, remember to install the gnome-common package which is
needed for building cvs versions of Gnome modules like Metacity) as
well as the standard development tools (gcc, autoconf, automake,

564
NEWS
View File

@ -1,570 +1,8 @@
3.7.4
=====
* Add support for bypass compositor hints [Adel; #683020]
* Make automaximization optional [Adel; #680990]
* Add method for checking if the application is responding [Giovanni; #684340]
* Expose the xinput opcode [Jasper; #690590]
* Rebrand "minimize" as "hide" [Florian; #682887]
* Misc bug fixes and cleanups [Giovanni, Ray, Jasper, Matthias, Debarshi,
Florian, Rui; #690454, #690573, #690593, #690956, #691363, #690609, #690317,
#689263]
Contributors:
Giovanni Campagna, Matthias Clasen, Adel Gadllah, Rui Matos, Florian Müllner,
Debarshi Ray, Jasper St. Pierre, Ray Strode
Translations:
Mattias Põldaru [et], Yaron Shahrabani [he], Daniel Mustieles [es],
Khaled Hosny [ar], Fran Diéguez [gl], A S Alam [pa], Piotr Drąg [pl],
Rafael Ferreira [pt_BR], Nilamdyuti Goswami [as], Alexander Shopov [bg],
Matej Urbančič [sl]
3.7.3
=====
* Fix maximized windows jumping to other monitors [Alban; #556696]
* Add 'switch-applications' keybinding [Florian; #688913]
* Add a convenience method to focus the default window [Jasper; #689652]
* Increase typical icon size to 96 [Jasper; #689651]
* Port to XInput2 [Jasper; #688779]
* Give dynamic keybindings a keybinding action [Florian; #682315]
* Misc. fixes and cleanups [Jasper, Rui; #688777]
Contributors:
Alban Crequy, Rui Matos, Florian Müllner, Jasper St. Pierre
Translations:
Nilamdyuti Goswami [as], Piotr Drąg [pl], Yaron Shahrabani [he],
Dr.T.Vasudevan [ta], ManojKumar Giri [or], Shankar Prasad [kn]
3.7.2
=====
* Fix spurious focus changes when showing desktop [Florian; #686928]
* MetaPluginManager: don't send events to Clutter twice [Owen; #686406]
* Add the ability to add shader hooks to MetaBackgroundActor [Giovanni; #669798]
* Only process keyboard mapping events for the core X keyboard [Rui; #674859]
* Import keybinding files from Metacity [Florian; #687672]
* Add compositor hook to process keybindings selectively [Florian; #688202]
* MetaBackgroundActor: add a setter for GLSL uniforms [Giovanni; #682536]
* Misc. fixes and cleanups [Jasper, Rui, Florian, Rico; #688182]
Contributors:
Giovanni Campagna, Rui Matos, Florian Müllner, Jasper St. Pierre,
Owen Taylor, Rico Tzschichholz
Translations:
Rafael Ferreira [pt_BR], Tobias Endrigkeit [de], Yaron Shahrabani [he]
3.7.1
=====
* screen: Ignore num-workspaces when using dynamic workspaces [Florian; #685439]
Contributors:
Florian Müllner
Translations:
Mattias Põldaru [et], Kjartan Maraas [nb], Мирослав Николић [sr, sr@latin],
Marek Černocký [cs], Andika Triwidada [id], Daniel Mustieles [es],
Fran Diéguez [gl], Matej Urbančič [sl]
3.6.1
=====
* Fix crash when opening large popup menus [Jasper; #681676]
* window: Don't move the desktop window after monitor hotplug [Jasper; #681159]
* Expose MetaPlugin to introspection [Evan; #671098]
* Optionally delay focus changes in focus-follows-mouse mode [Florian; #678169]
* Resize the guard window when the X screen is resized [Benjamin; #670396]
* display: Only manage the default X screen [Jürg; #648156]
* Misc cleanups: [Owen; #587255]
Contributors:
Benjamin Berg, Jürg Billeter, Evan Broder, Florian Müllner, Jasper St. Pierre,
Owen Taylor
Translations:
Alexandre Franke [fr], Theppitak Karoonboonyanan [th], Sayak Sarkar [bn_IN],
Sandeep Sheshrao Shedmake [mr], Ask H. Larsen [da], Shankar Prasad [kn],
Alexander Shopov [bg], Aurimas Černius [lt], Ihar Hrachyshka [be],
Kjartan Maraas [nb], Daniel Mustieles [es], Changwoo Ryu [ko],
Yuri Myasoedov [ru], Tom Tryfonidis [el], Rūdolfs Mazurs [lv],
Chris Leonard [en_GB], Piotr Drąg [pl], Fran Diéguez [gl], Gil Forcada [ca],
Matej Urbančič [sl], Andika Triwidada [id], Carles Ferrando [ca]
3.6.0
=====
Translations:
Alexander Shopov [bg], Daniel Korostil [uk], Rajesh Ranjan [hi],
Krishnababu Krothapalli [te], Ani Peter [ml], Rūdolfs Mazurs [lv],
Sweta Kothari [gu], Ihar Hrachyshka [be], Noriko Mizumoto [ja],
Timo Jyrinki [fi], Mattias Põldaru [et]
3.5.92
======
* screen: Allow NULL out arguments in meta_screen_get_size [Tomeu]
* display: Add API to set wm_name / wm_keybindings [Florian; #671010]
* Improve the not responding dialog [Jon, Florian; #684306]
* Misc. bugfixes [Jasper]
Contributors:
William Jon McCann, Florian Müllner, Jasper St. Pierre, Tomeu Vizoso
Translations:
Gabor Kelemen [hu], Piotr Drąg [pl], Dr.T.Vasudevan [ta], Bruce Cowan [en_GB],
Alexandre Franke [fr], Theppitak Karoonboonyanan [th], Gil Forcada [ca],
Carles Ferrando [ca@valencia], Tobias Endrigkeit [de], Tom Tryfonidis [el],
Nguyễn Thái Ngọc Duy [vi], Changwoo Ryu [ko], Ask H. Larsen [da],
Rafael Ferreira [pt_BR], Marek Černocký [cs]
3.5.91
======
* Do not include markup in app not responding dialog [Alex]
* Fix subtracting unredirected windows from visible region [Jasper; #677116]
* Minor improvements and bugfixes [Jasper, Florian; #682648, #682993]
Contributors:
Alexander Larsson, Florian Müllner, Jasper St. Pierre
Translations:
Dirgita [id], Piotr Drąg [pl], A S Alam [pa], Yuri Myasoedov [ru],
Milo Casagrande [it], Nilamdyuti Goswami [as], Tom Tryfonidis [el],
Duarte Loreto [pt], Fran Diéguez [gl], Nguyễn Thái Ngọc Duy [vi],
Aurimas Černius [lt], Daniel Nylander [sv]
3.5.90
======
* Fix logic for handling translations of the windows group [Owen; #681221]
* Handle painting inside a Clutter clone [Owen; #681953]
* Update overlay-key on settings changes [Florian; #681906]
* Add keybinding for overlay-key [Florian; #665547]
* Minor fixes and improvements [Javier, Florian]
Contributors:
Javier Jardón, Florian Müllner, Owen Taylor
Translations:
Sweta Kothari [gu], Muhammet Kara [tr], Khaled Hosny [ar],
Sandeep Sheshrao Shedmake [mr]
3.5.5
=====
* Fix flickering around windows when using window group [Tom; #681221]
Contributor(s):
Tom Beckmann
Translations:
Chao-Hsiung Liao [zh_HK, zh_TW], Matej Urbančič [sl], Fran Diéguez [gl],
Мирослав Николић [sr, sr@latin], Yaron Shahrabani [he], Kjartan Maraas [nb]
3.5.4
=====
* Make it possible to reimplement move-to-workspace keybindings from plugins
[Giovanni; #674104]
* Add a preference to ignore hide-titlebar-when-maximized hint [Rico; #678947]
* window: Also use hide-titlebar-when-maximized when tiled [Florian; #679290]
* Center modal dialogs on their parent instead [Florian; #674499]
* Reduce amount of markup in translated messages [Matthias; #679660]
* Fix focus problem after closing a window with focus-follows-mouse
[Jasper; #675982]
* Handle changes of the attach-modal-dialogs preference [Florian; #679904]
* Do not restore tiling on unmaximize [Florian; #677565]
* Misc. fixes and cleanups [Jasper Adriaanse, Jasper, Debarshi, Pavel;
#679153, 673824]
Contributors:
Jasper Lievisse Adriaanse, Giovanni Campagna, Matthias Clasen, Florian Müllner,
Debarshi Ray, Jasper St. Pierre, Rico Tzschichholz, Pavel Vasin
Translations:
Alexander Shopov [bg], Kjartan Maraas [nb], Yaron Shahrabani [he],
Nilamdyuti Goswami [as], Ihar Hrachyshka [be], Daniel Mustieles [es]
3.5.3
=====
* Simplify plugin system [Jasper; #676855]
* meta-window-actor: Don't unredirect shaped windows [Jasper; #677657]
* screen: Add new public meta_screen_get_current_monitor API [Tim; #642591]
* frames: Increase the size of resize corners [Jasper; #677669]
* window: Make some window methods public [Jasper; #678126]
* Fix crash when running mutter stand-alone [Jasper; #678238]
* meta-window-actor: Fix potential crash in shaping code [Jasper; #677977]
* Misc. fixes [Jasper, Marc-Antoine, Rico]
Contributors:
Tim L, Marc-Antoine Perennou, Jasper St. Pierre, Rico Tzschichholz
Translations:
Daniel Mustieles [es], Matej Urbančič [sl], Khaled Hosny [ar],
Bruno Brouard [fr], Fran Diéguez [gl]
3.5.2
=====
* keybindings: Remove 'toggle-recording' binding [Florian; #674376]
* Switch to gtk-doc syntax [Jasper; #673752]
* shaped-texture: never slice shape mask texture [Robert; #674731]
* Make Mutter stop relying on Cogl including a GL header [Neil; #672711]
* Make support for "XFree86" Xinerama mandatory [Owen; #674727]
* meta_window_move_frame(): fix crash when frame is NULL [Owen; #675254]
* Fix memory leaks [Pavel; #672640]
* Code cleanups [Jasper; #671104 #674876 #676052]
* Look for themes in XDG user data dir [Jasper; #675316]
* Remove frame pixel caching [Jasper; #675111]
* stack: Ignore keep-on-top property on maximized windows [Florian; #673581]
* Misc. fixes [Javier, Jasper, Owen, Rico]
Contributors:
Robert Bragg, Javier Járdon, Florian Müllner, Neil Roberts, Jasper St. Pierre,
Owen Taylor, Rico Tzschichholz, Pavel Vasin
Translations:
Praveen Illa [te], Luca Ferretti [it], Daniel Mustieles [es]
3.4.1
=====
* API change: the meta_display_add_keybinding() function added in 3.4
wasn't usable from a GNOME Shell extension, so has been changed to take
a GSettings object rather than the name of a schema [Jasper; #673014]
* Don't try to auto-maximize not-maximizable windows; this fixes the problem
with the Nautilus desktop window being mis-positioned when enabled
[Owen; #673566]
* Fix a crash in the default plugin (not used in GNOME) [Giovanni; #673809]
* Make the <Super> key work when set as the mouse button modifier
[Florian; #662476]
Contributors:
Giovanni Campagna, Florian Muellner, Jasper St. Pierre, Owen Taylor
Translations:
Khaled Hosny [ar], Jordi Serratosa [ca], Carles Ferrando [ca@valencia],
Christian Kirbach [de], Kristjan Schmidt [eo], Arash Mousavi [fa],
Jiro Matsuzawa [ja], Shankar Prasad [kn], Aurimas Černius [lt],
Yinghua Wang [zh_CN]
3.4.0
=====
* Fix crash when a full-screen window is opened [Jasper; #672797]
* Fix memory leaks [Pavel; #672640]
Contributors:
Jasper St. Pierre, Pavel Vasin
Translations:
Marek Černocký, Petr Kovar [cz], Bruno Brouard [fr], Sweta Kothari [gu],
Yaron Shahrabani [he], Changwoo Ryu [kr], Enrico Nicoletto [pt_BR],
Yuri Myasoedov [ru], Muhammet Kara [tr], Nguyễn Thái Ngọc Duy [vi]
3.3.92
======
* Automaximize large windows on map [Adel; #671677]
* When unmaximizing windows, make sure the unminimized size
is signficantly less than the maximized size [Adel; #671677]
* Don't offer maximize option for windows larger than the screen
[Jasper; #643606]
* Always focus the window immediately underneath without restacking
when closing a window [Jasper; #620744]
* Avoid drawing shadows when two windows are tiled together [Rui; #643075]
* Remove tooltips for window decorations [Florian; #645101]
* Add org.gnome.mutter.dynamic-workspaces GSetting - when this is set
to true, workspace counts are never saved to GSettings, avoiding
pointless disk traffic for GNOME dynamic workspaces [Florian; #671568]
* Add ::grab-op-begin, ::grab-op-end signals to MetaDisplay [Jasper; #670658]
* Add meta_display_get_ignored_modifier_mask() [Florian; #665215]
* Remove pointless wrapper methods on MetaPlugin [Jasper; #671103]
* Fix frame drawing with 3.3.x GTK+ releases [Florian; #671796]
* Build fixes [Jasper, Rico, Rui]
* Misc bug fixes [Damien, Jasper, Lionel, Marius, Owen, Rui;
#661256, #667437, #671601, #671087, #672374]
Contributors:
Stefano Facchini, Adel Gadllah, Lionel Landwerlin, Mariusz Libera,
Rui Matos, Florian Müllner, Jasper St. Pierre, Damien Radtke, Owen Taylor,
Rico Tzschichholz
Translations:
Nilamdyuti Goswami [as], Ihar Hrachyshka [be], Alexander Shopov [bg],
David Planella [ca], Carles Ferrando [ca@valencia], Kenneth Nielsen [dk],
Bruce Cowan [en_GB], Daniel Mustieles [es], Mattias Põldaru [et],
Inaki Larranaga Murgoitio [eu], Timo Jyrinki [fi], Fran Diéguez [gl],
Gabor Kelemen [hu], Changwoo Ryu [ko], Anita Reitere [lv],
Kjartan Maraas [nb], Wouter Bolsterlee [nl], A S Alam [pa], Piotr Drąg [pl],
Duarte Loreto [pt], Yuri Myasoedov [ru], Daniel Nylander [se],
Matej Urbančič [sl], Miroslav Nikolić [sr], Tirumurti Vasudevan [ta],
Sasi Bhushan [te], Daniel Korostil [uk], Nguyễn Thái Ngọc Duy [vi],
YunQiang Su [zh_CN], Chao-Hsiung Liao [zh_HK, zh_TW]
3.3.90
======
* Update for Cogl API changes [Robert]
* Bug fixes [Adel, Jasper; #659643]
* Build fixes [Jasper, Owen]
Contributors:
Robert Bragg, Adel Gadllah, Jasper St. Pierre, Owen Taylor
Translations:
Ask H. Larsen [dk], Miroslav Nikolić [sr]
3.3.5
=====
* MetaShapedTexture no longer is a ClutterTexture subclass [Jasper; #660941]
* Add meta_shaped_texture_get_image() [Jasper; #660941]
* Cleanups [Rui, Jasper; #657639]
* Depend on GTK+ 3.3.7 [Rico]
Contributors:
Rui Matos, Jasper St. Pierre, Rico Tzschichholz
Translations:
Kjartan Maraas [nb], Chao-Hsiung Liao [zh_HK, zh_TW]
3.3.4
=====
* Adapt to changes in GtkStateFlags [Owen]
* Redo properties for applications menu corresponding to GTK+ changes -
they are now _GTK_* not DBUS_*. [Ryan]
* Fix crash on gnome-shell restart when a modal dialog is open [Owen; #668299]
* Code cleanup [Florian; #666039]
Contributors:
Ryan Lortie, Florian Müllner, Owen Taylor
Translations:
Alexander Shopov [bg], Fran Diéguez [gl]
3.3.3
=====
* Add keybindings for tiling to left or right [Florian; #648700]
* Support GTK+'s hide-titlebar-when-maximized hint [Florian; #665617]
* Load _DBUS_APPLICATION_ID, _DBUS_UNIQUE_NAME, _DBUS_OBJECT_PATH
property [Colin, Ryan; #664851]
* Handle changes to workspaces-only-on-primary GSetting [Florian; #664853]
* Don't use the Clutter default stage [Jasper; #664028]
* Fix compilation with --disable-introspection [Lionel; #661871]
* Fix problem where stage could end up mis-sized on startup with
multiple monitors [Lionel]
* Misc bug fixes [Adel, Lionel, Jasper; #666015]
Contributors:
Adel Gadllah, Lionel Landwerlin, Florian Müllner, Jasper St. Pierre
Translations:
Daniel Mustieles [es], Yaron Shahrabani [he], Kjartan Maraas [nb],
Matej Urbančič [sk], Muhammet Kara [tr]
3.3.2
=====
* Move from GConf to GSettings for preferences [Florian; #635378]
* Add meta_display_add_keybinding()/meta_display_remove_keybinding()
to allow creating new keybindings at runtime [Florian; #663428]
* Add suport for new _NET_WM_STATE_FOCUSED atom in _NET_WM_STATE
to allow applications to draw unfocused windows differently
[Rui; #661427]
* Add meta_window_move_resize_frame() to allow specifying the
size and position of a window via the outside dimensions of the
window frame.
* Don't activate window tiling when moving in snap mode
[Rui; #662270]
* Remove the ability to resize a window from the inner edge of
the titlebar [Jasper; #660129]
* Fix for deprecations in GTK+ [Jasper, Rico; #662574, #662895]
* Misc bug fixes [Jasper, Rico, Rui; #662895, #642652, #660941, #662225]
Contributors:
Tim Cuthbertson, Rui Matos, Florian Müllner, Jasper St. Pierre, Rico Tzschichholz
Translations:
Jorge González (es), Kjartan Maraas (nb), Krishnababu Krothapalli (te), Nguyễn Thái Ngọc Duy (vi)
3.2.1
=====
* Allow keyboard window switching (alt-Tab) during drag-and-drop
[Matthias, #660457]
* Don't add invisible resize borders to fullscreen windows
[Jasper, Owen; #659854]
* Fix crash when toplevel windows were set to unexpected window types
[Owen; #599988]
* Correct problems with windows moving when restarting or switching
window managers [Jasper; #660848]
* Fix interaction of tiled windows with multiple monitors
[Rui; #642580, #657519]
* Make meta_display_unmanage_screen() public [Jasper; #660848]
* Fix problem with turning off window decorations on the fly [Rui; #660773]
* Fix spurious assertion failures with themes such as Nodoka [Sandro; #661286]
* Misc bug fixes [Adel, Jasper, Rui; #660464, #660854, #662053]
Contributors:
Matthias Clasen, Sandro Mani, Rui Matos, Jasper St. Pierre, Owen Taylor
Translations:
Tommi Vainikainen [fi], Miroslav Nikolić [sr, sr@latin], Muhammet Kara [tr]
3.2.0
=====
* Fix _NET_WM_FRAME_EXTENTS not to include invisible borders [Jasper; #659848]
* Fix application-specified window placement (-geometry) for
invisible borders [Jasper; #659848]
Contributors:
Jasper St. Pierre
Translations:
Nilamdyuti Goswami [as], Carles Ferrando [ca@valencia], Petr Kovar [cz],
Mario Blättermann [de], Inaki Larranaga [eu], Gabor Kelemen [hu],
Takayoshi Okano [ja], Changwoo Ryu [ko], Djavan Fagundes [pt_BR]
3.1.92
======
* Fix bug with unredirecting full-screen windows on multi-monitor -
notably affected gnome-screensaver [Adel; #657869]
* Disable top resizing of attached dialogs [Jasper; #657795]
* Code cleanup [Jasper, Rui]
* Misc bug fixes [Adel, Florian, Jasper, Rui;
#658069, #659266, #659523, #659477]
Contributors:
Adel Gadllah, Rui Matos, Florian Müllner, Jasper St. Pierre
Translations:
Joan Duran [ca], Joe Hansen [dk], Jiro Matsuzawa [ja], Daniel Korostil [uk]
3.1.91.1
========
* Fix problem where certain application updates would get lost [#657071, Owen]
* Fix a problem where after resuming from the screensaver, things got
slow [#658228, Jasper, Adel]
* When a monitor is plugged or unplugged, keep existing windows on their
current monitor [#645408, Alex]
* Remove 'Mutter' title from alerts such as
"The widow '%s' is not responding" [Matthias]
* Remove pointless warning:
Received a _NET_WM_MOVERESIZE message for %s; these
messages lack timestamps and therefore suck.
[Rui]
* Misc bug fixes [Jasper]
* Build fixes [Javier]
Contributors:
Matthias Clasen, Adel Gadllah, Javier Jardón, Alex Larsson, Rui Matos,
Jasper St. Pierre, Owen Taylor
Translations:
Ihar Hrachyshka [be], Bruce Cowan [en_FB], Daniel Mustieles [es],
Claude Paroz [fr], Andika Triwidada [id], Luca Ferretti [it],
Rudolfs Mazurs [lt], Piotr Drąg [pl], Duarte Loreto [pt],
Matej Urbančič [sl], Tirumurti Vasudevan [ta], Chao-Hsiung Liao [zh_KH, TW]
3.1.90.1
========
* Fix crash when no windows are open [Adel; #657692]
* Fix annotations for new strictness in gobject-introspection [Jasper, Owen]
* Fix some errors with rounded frame drawing [Jasper; #657661]
Contributors:
Adel Gadllah, Jasper St. Pierre, Owen Taylor
3.1.90
======
* Extend the draggable portion of window borders outside the visible frame
for easy resizing with thin borders. (New draggable_border_width GConf key
controls the total width of visible and invisible borders.)
[Jasper; #644930]
* Draw rounded window corners with antialising [Jasper; #628195]
* Unredirect override-redirect fullscreen windows, such as full-screen
3D games to avoid any performance impact [Adel; #597014]
* Add :resizable and :above properties to MetaWindow. [Tim; #653858]
* Add MUTTER_DISABLE_FALLBACK_COLOR environment variable to allow visualizing
places where a color is missing for gtk:custom() colors [Florian; #656112]
* Don't attach modal dialogs to special windows like the desktop;
add meta_window_is_attached_dialog() [Dan, #646761]
* Make MetaBackgroundActor public, allow creating multiple instances
(sharing a common texture), and add a :dim-factor property
[Rui, Owen; #656433]
* Fix attached dialogs to not be resizable from the top and to be
position correctly [Jasper; #656619]
* Misc bug fixes [Jasper, Rui; #656335, #657583]
Contributors:
Tim Cuthbertson, Adel Gadllah, Rui Matos, Florian Müllner, Jasper St. Pierre,
Owen Taylor, Dan Winship
Translations:
Alexander Shopov [bg], Jorge González [es], Fran Dieguez [gl],
Yaron Shahrabani [he], Takeshi Aihana [ja], Aurimas Černius [lt],
Kjartan Maraas [nb], A S Alam [pa], Yuri Kozlov [ru], Daniel Nylander [se],
Theppitak Karoonboonyanan [th], Abduxukur Abdurixit [ug], Aron Xu [zh_CN]
3.1.4
=====
* Use better, much more subtle shadow definitions [Jakub; #649374]
* Add the ability to use named GTK+ colors in theme files as
gtk:custom(name,fallback) [Florian; #648709]
* Port from GdkColor to GdkRGBA and from GtkStyle to GtkStyleContext
[Florian; #650586]
* Try to fix window bindings using the Super key [Owen; #624869]
* Update to using more modern Cogl and Clutter APIs
[Adel, Emmanuele, Neil; #654551 #654729 #654730 #655064]
* Fix for srcdir != builddir builds [Thierry; #624910]
* Make handling of focus appearance for attached dialogs more robust
[Dan; #647712]
* Misc bug fixes
[Dan, Florian, Jasper, Owen, Rui; #642957 #649374 #650661 #654489 #654539]
Contributors:
Emmanuele Bassi, Adel Gadllah, Rui Matos, Florian Müllner, Neil Roberts,
Jasper St. Pierre, Jakub Steiner, Owen Taylor
Translations:
Ihar Hrachyshka [be], Jorge González, Daniel Mustieles [es],
Fran Dieguez [gl], Yaron Shahrabani [he], Takeshi Aihana [ja],
Kjartan Maraas [nb], Rudolfs Mazurs [lv], Matej Urbančič [sl],
Abduxukur Abdurixit [ug], Nguyễn Thái Ngọc Duy [vi]
3.1.3.1
=======
* Back API version down to "3.0" - the change to Meta-3.1.gir
was unintentional [Owen]
Translations:
Yaron Shahrabani [he], Kjartan Maraas [nb], Muhammet Kara [tr]
3.1.3
=====
* Support dark window theme variants for windows with a dark
widget theme; this is selected by the _GTK_THEME_VARIANT
property [Florian, #645355]
* Don't draw a shadow under windows with an alpha-channel - this
fixes transparency for GNOME Terminal [Owen, Jasper; #635268]
* Add a MetaWindow:wm-class property for notification [Jasper; #649315]
* Add a MetaWindow:minimized property for notification [Florian]
* Fix handing of unusual window shapes that Wine was setting
causing some applications to draw wrong [Jasper; #627880]
* Improve replacing another compositor and being replaced:
release compositor selection in the right order and wait for
compositors that get it wrong. [Colin, Owen; #653121]
* Remove behavior where left clicking on a window border with
the titlebar offscreen gave the window menu [Florian; #652369]
* Don't set the global default textdomain, since Mutter is
a library as well as an application [Dan; #649202]
* Exit with the right (success or failure) exit status [Dan]
* Code cleanup [Florian]
* Miscellaneous bug fixes [Owen; #649114, #652507]
Contributors:
Florian Müllner, Jasper St. Pierre, Owen Taylor, Colin Walters, Dan Winship
Translations:
Ihar Hrachyshka [be], Daniel Mustieles [es], Yaron Shahrabani [he],
Carles Ferrando [ca@valencia], Takeshi Aihana [ja], Fran Diéguez [gl],
Matej Urbančič [sl], Miroslav Nikolic [sr], Muhammet Kara [tr],
Daniel Korostil [uk]
3.0.2.1
=======
* When saving the session, use the "program name" rather than
harcoding mutter, fixing session saving for gnome-shell [Matthias]
https://bugzilla.gnome.org/show_bug.cgi?id=648828
https://bugzilla.gnome.org/show_bug.cgi?id=648828
Contributors:
Matthias Clasen

47
README
View File

@ -1,10 +1,16 @@
The original codebase named "Metacity" is not a meta-City as in an
urban center, but rather Meta-ness as in the state of being
meta. i.e. metacity : meta as opacity : opaque. Also it may have
something to do with the Meta key on UNIX keyboards.
Metacity is not a meta-City as in an urban center, but rather
Meta-ness as in the state of being meta. i.e. metacity : meta as
opacity : opaque. Also it may have something to do with the Meta key
on UNIX keyboards.
Since then, it has been renamed mutter after a rebase on top of
clutter as a compositing manager.
The first release of Metacity was version 2.3. Metacity has no need for
your petty hangups about version numbers.
The stable releases so far are 2.4.x, 2.6.x, 2.8.[01], 2.8.1.x, 2.8.5-,
2.10.x, 2.12.x, 2.14.x, 2.16.x.
Unstable branches are 2.3.x, 2.5.x, 2.8.2-4, 2.9.x, 2.11.x, 2.13.x,
2.15.x, 2.17.x.
COMPILING MUTTER
===
@ -12,7 +18,8 @@ COMPILING MUTTER
You need GTK+ 2.2. For startup notification to work you need
libstartup-notification at
http://www.freedesktop.org/software/startup-notification/ or on the
GNOME ftp site.
GNOME ftp site. You also need GConf 1.2 (unless building a funky
extra-small embedded metacity with --disable-gconf, see below).
You need Clutter 1.0. You need gobject-introspection 0.6.3.
REPORTING BUGS AND SUBMITTING PATCHES
@ -52,24 +59,25 @@ MUTTER FEATURES
and should work with KWin, fvwm2, and other EWMH-compliant WMs.)
- Has a simple theme system and a couple of extra themes come with it.
Change themes via gsettings:
gsettings set org.gnome.desktop.wm.preferences theme Crux
gsettings set org.gnome.desktop.wm.preferences theme Gorilla
gsettings set org.gnome.desktop.wm.preferences theme Atlanta
gsettings set org.gnome.desktop.wm.preferences theme Bright
Change themes via gconf-editor or gconftool or GNOME themes control
panel:
gconftool-2 --type=string --set /apps/metacity/general/theme Crux
gconftool-2 --type=string --set /apps/metacity/general/theme Gorilla
gconftool-2 --type=string --set /apps/metacity/general/theme Atlanta
gconftool-2 --type=string --set /apps/metacity/general/theme Bright
See theme-format.txt for docs on the theme format. Use
metacity-theme-viewer to preview themes.
- Change number of workspaces via gsettings:
gsettings set org.gnome.desktop.wm.preferences num-workspaces 5
- Change number of workspaces via gconf-editor or gconftool:
gconftool-2 --type=int --set /apps/metacity/general/num_workspaces 5
Can also change workspaces from GNOME 2 pager.
- Change focus mode:
gsettings set org.gnome.desktop.wm.preferences focus-mode mouse
gsettings set org.gnome.desktop.wm.preferences focus-mode sloppy
gsettings set org.gnome.desktop.wm.preferences focus-mode click
gconftool-2 --type=string --set /apps/metacity/general/focus_mode mouse
gconftool-2 --type=string --set /apps/metacity/general/focus_mode sloppy
gconftool-2 --type=string --set /apps/metacity/general/focus_mode click
- Global keybinding defaults include:
@ -84,9 +92,10 @@ MUTTER FEATURES
Change keybindings for example:
gsettings set org.gnome.desktop.wm.keybindings switch-to-workspace-1 '[<Alt>F1]'
unst gconftool-2 --type=string --set /apps/metacity/global_keybindings/switch_to_workspace_1 '<Alt>F1'
Also try the GNOME keyboard shortcuts control panel.
Also try the GNOME keyboard shortcuts control panel, or
gconf-editor.
- Window keybindings:

View File

@ -7,7 +7,7 @@ test -z "$srcdir" && srcdir=.
PKG_NAME="mutter"
REQUIRED_AUTOMAKE_VERSION=1.10
(test -f $srcdir/configure.ac \
(test -f $srcdir/configure.in \
&& test -d $srcdir/src) || {
echo -n "**Error**: Directory "\`$srcdir\'" does not look like the"
echo " top-level metacity directory"

View File

@ -1,8 +1,8 @@
AC_PREREQ(2.50)
m4_define([mutter_major_version], [3])
m4_define([mutter_minor_version], [7])
m4_define([mutter_micro_version], [4])
m4_define([mutter_minor_version], [0])
m4_define([mutter_micro_version], [2.1])
m4_define([mutter_version],
[mutter_major_version.mutter_minor_version.mutter_micro_version])
@ -15,9 +15,9 @@ AC_INIT([mutter], [mutter_version],
AC_CONFIG_SRCDIR(src/core/display.c)
AC_CONFIG_HEADERS(config.h)
AM_INIT_AUTOMAKE([1.11 no-dist-gzip dist-xz tar-ustar])
AM_INIT_AUTOMAKE([dist-bzip2 no-dist-gzip])
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])],)
AM_MAINTAINER_MODE([enable])
AM_MAINTAINER_MODE
MUTTER_MAJOR_VERSION=mutter_major_version
MUTTER_MINOR_VERSION=mutter_minor_version
@ -61,23 +61,21 @@ AC_CHECK_SIZEOF(__int64)
## byte order
AC_C_BIGENDIAN
GTK_MIN_VERSION=2.91.7
CANBERRA_GTK=libcanberra-gtk3
CANBERRA_GTK_VERSION=0.26
CLUTTER_PACKAGE=clutter-1.0
MUTTER_PC_MODULES="gtk+-3.0 >= $GTK_MIN_VERSION pango >= 1.2.0 cairo >= 1.10.0"
MUTTER_PC_MODULES="
gtk+-3.0 >= 3.3.7
gio-2.0 >= 2.25.10
pango >= 1.2.0
cairo >= 1.10.0
gsettings-desktop-schemas >= 3.3.0
xcomposite >= 0.2 xfixes xrender xdamage xi >= 1.6.0
$CLUTTER_PACKAGE >= 1.13.2
cogl-1.0 >= 1.9.6
"
AC_ARG_ENABLE(gconf,
AC_HELP_STRING([--disable-gconf],
[disable gconf usage, for embedded/size-sensitive non-GNOME builds]),,
enable_gconf=yes)
GLIB_GSETTINGS
if test x$enable_gconf = xyes; then
AC_DEFINE(HAVE_GCONF,1,[Build with gconf support])
MUTTER_PC_MODULES="$MUTTER_PC_MODULES gconf-2.0 >= 1.2.0"
fi
AC_ARG_ENABLE(verbose-mode,
AC_HELP_STRING([--disable-verbose-mode],
@ -113,14 +111,17 @@ AC_ARG_ENABLE(shape,
[disable mutter's use of the shaped window extension]),,
enable_shape=auto)
## try definining HAVE_BACKTRACE
AC_CHECK_HEADERS(execinfo.h, [AC_CHECK_FUNCS(backtrace)])
AM_GLIB_GNU_GETTEXT
## here we get the flags we'll actually use
# GRegex requires Glib-2.14.0
PKG_CHECK_MODULES(ALL, glib-2.0 >= 2.14.0)
# gtk_window_set_icon_name requires gtk2+-2.6.0
PKG_CHECK_MODULES(MUTTER_MESSAGE, gtk+-3.0)
PKG_CHECK_MODULES(MUTTER_WINDOW_DEMO, gtk+-3.0)
PKG_CHECK_MODULES(MUTTER_MESSAGE, gtk+-3.0 >= $GTK_MIN_VERSION)
PKG_CHECK_MODULES(MUTTER_WINDOW_DEMO, gtk+-3.0 >= $GTK_MIN_VERSION)
# Unconditionally use this dir to avoid a circular dep with gnomecc
GNOME_KEYBINDINGS_KEYSDIR="${datadir}/gnome-control-center/keybindings"
@ -170,18 +171,51 @@ else
fi
fi
XCOMPOSITE_VERSION=0.2
AC_MSG_CHECKING([Xcomposite >= $XCOMPOSITE_VERSION])
if $PKG_CONFIG --atleast-version $XCOMPOSITE_VERSION xcomposite; then
MUTTER_PC_MODULES="$MUTTER_PC_MODULES xcomposite >= $XCOMPOSITE_VERSION xfixes xrender xdamage"
AC_DEFINE(HAVE_COMPOSITE_EXTENSIONS, 1, [Building with compositing manager support])
echo "Building with compositing manager"
## force on render also
have_xrender=yes
else
AC_MSG_ERROR([no. Mutter requires the Xcomposite extension to build.])
fi
CLUTTER_VERSION=1.2.0
CLUTTER_PACKAGE=clutter-1.0
AC_SUBST(CLUTTER_PACKAGE)
if $PKG_CONFIG --atleast-version $CLUTTER_VERSION $CLUTTER_PACKAGE ; then
MUTTER_PC_MODULES="$MUTTER_PC_MODULES $CLUTTER_PACKAGE "
PKG_CHECK_MODULES(CLUTTER, $CLUTTER_PACKAGE)
AC_DEFINE(WITH_CLUTTER, , [Building with Clutter compositor])
dnl Check for the clutter-glx-texture-pixmap header
mutter_save_cppflags="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $CLUTTER_CFLAGS"
AC_CHECK_HEADER([clutter/glx/clutter-glx-texture-pixmap.h],
[have_glx_texture_pixmap=yes],
[have_glx_texture_pixmap=no])
CPPFLAGS="$mutter_save_cppflags"
if test x$have_glx_texture_pixmap = xyes; then
AC_DEFINE(HAVE_GLX_TEXTURE_PIXMAP, ,
[Is ClutterGLXTexturePixmap available?])
fi
else
AC_MSG_ERROR([no. Mutter requires Clutter version $CLUTTER_VERSION.])
fi
INTROSPECTION_VERSION=0.9.5
GOBJECT_INTROSPECTION_CHECK([$INTROSPECTION_VERSION])
if test x$found_introspection != xno; then
AC_DEFINE(HAVE_INTROSPECTION, 1, [Define if GObject introspection is available])
MUTTER_PC_MODULES="$MUTTER_PC_MODULES gobject-introspection-1.0"
# Since we don't make any guarantees about stability and we don't support
# parallel install, there's no real reason to change directories, filenames,
# etc. as we change the Mutter tarball version. Note that this must match
# api_version in src/Makefile.am
META_GIR=Meta_3_0_gir
# META_GIR=[Meta_]mutter_major_version[_]mutter_minor_version[_gir]
META_GIR=[Meta_]mutter_major_version[_]mutter_minor_version[_gir]
AC_SUBST(META_GIR)
fi
@ -201,39 +235,64 @@ fi
PKG_CHECK_MODULES(MUTTER, $MUTTER_PC_MODULES)
# This is used for plugins
AC_SUBST(CLUTTER_PACKAGE)
PKG_CHECK_MODULES(CLUTTER, $CLUTTER_PACKAGE)
AC_PATH_XTRA
ALL_X_LIBS="$X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS"
# Check for Xinerama extension - we only support the "XFree86" style,
# and not the older Solaris-only version; recent Solaris supports the
# XFree86 style.
# Check for Xinerama extension (Solaris impl or Xfree impl)
mutter_save_cppflags="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $X_CFLAGS"
have_xinerama=yes
AC_CHECK_LIB(Xinerama, XineramaQueryExtension,
[AC_CHECK_HEADER(X11/extensions/Xinerama.h,
[X_EXTRA_LIBS="-lXinerama $X_EXTRA_LIBS"
if test -z "`echo $ALL_X_LIBS | grep "\-lXext" 2> /dev/null`"; then
X_EXTRA_LIBS="-lXext $X_EXTRA_LIBS"
fi],
have_xinerama=no,
[#include <X11/Xlib.h>])],
have_xinerama=no, -lXext $ALL_X_LIBS)
AC_MSG_CHECKING(for Xinerama support)
AC_MSG_RESULT($have_xinerama)
AC_ARG_ENABLE(xinerama,
AC_HELP_STRING([--disable-xinerama],
[disable mutter's use of the Xinerama extension]),
try_xinerama=$enable_xinerama,try_xinerama=yes)
use_solaris_xinerama=no
use_xfree_xinerama=no
if test "${try_xinerama}" != no; then
case "$host" in
*-*-solaris*)
# Check for solaris
use_solaris_xinerama=yes
AC_CHECK_LIB(Xext, XineramaGetInfo,
use_solaris_xinerama=yes, use_solaris_xinerama=no,
$ALL_X_LIBS)
if test "x$use_solaris_xinerama" = "xyes"; then
AC_CHECK_HEADER(X11/extensions/xinerama.h,
if test -z "`echo $ALL_X_LIBS | grep "\-lXext" 2> /dev/null`"; then
X_EXTRA_LIBS="-lXext $X_EXTRA_LIBS"
fi
AC_DEFINE(HAVE_SOLARIS_XINERAMA, , [Have Solaris-style Xinerama])
AC_DEFINE(HAVE_XINERAMA, , [Have some version of Xinerama]),
use_solaris_xinerama=no,
[#include <X11/Xlib.h>])
fi
AC_MSG_CHECKING(for Xinerama support on Solaris)
AC_MSG_RESULT($use_solaris_xinerama);
;;
*)
# Check for XFree
use_xfree_xinerama=yes
AC_CHECK_LIB(Xinerama, XineramaQueryExtension,
[AC_CHECK_HEADER(X11/extensions/Xinerama.h,
X_EXTRA_LIBS="-lXinerama $X_EXTRA_LIBS"
if test -z "`echo $ALL_X_LIBS | grep "\-lXext" 2> /dev/null`"; then
X_EXTRA_LIBS="-lXext $X_EXTRA_LIBS"
fi
AC_DEFINE(HAVE_XFREE_XINERAMA, , [Have XFree86-style Xinerama])
AC_DEFINE(HAVE_XINERAMA,, [Have some version of Xinerama]),
use_xfree_xinerama=no,
[#include <X11/Xlib.h>])],
use_xfree_xinerama=no, -lXext $ALL_X_LIBS)
AC_MSG_CHECKING(for Xinerama support on XFree86)
AC_MSG_RESULT($use_xfree_xinerama);
;;
esac
fi
CPPFLAGS="$mutter_save_cppflags"
if test x$have_xinerama = xno; then
AC_MSG_ERROR([Xinerama extension was not found])
fi
SHAPE_LIBS=
found_shape=no
AC_CHECK_LIB(Xext, XShapeQueryExtension,
@ -349,6 +408,18 @@ fi
AC_SUBST(GDK_PIXBUF_CSOURCE)
if test x$enable_gconf = xyes; then
AC_PATH_PROG(GCONFTOOL, gconftool-2, no)
if test x"$GCONFTOOL" = xno; then
AC_MSG_ERROR([gconftool-2 executable not found in your path - should be installed with GConf])
fi
AM_GCONF_SOURCE_2
else
GCONF_SCHEMAS_INSTALL_TRUE='#'
GCONF_SCHEMAS_INSTALL_FALSE=
fi
AC_PATH_PROG(ZENITY, zenity, no)
if test x"$ZENITY" = xno; then
AC_MSG_ERROR([zenity not found in your path - needed for dialogs])
@ -361,6 +432,12 @@ if test "x$enable_debug" = "xyes"; then
CFLAGS="$CFLAGS -g -O"
fi
# For fix-meta-rectangle.py
AM_PATH_PYTHON([2.5])
# Use gnome-doc-utils:
GNOME_DOC_INIT([0.8.0])
#### Warnings (last since -Werror can disturb other tests)
# Stay command-line compatible with the gnome-common configure option. Here
@ -420,7 +497,7 @@ if test "$enable_compile_warnings" != no ; then
if test "$enable_compile_warnings" = error; then
case " $CFLAGS " in
*[\ \ ]-Werror[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -Werror -Wno-error=deprecated-declarations" ;;
*) CFLAGS="$CFLAGS -Werror" ;;
esac
fi
fi
@ -442,6 +519,13 @@ po/Makefile.in
AC_OUTPUT
if test x$enable_gconf = xno; then
echo "*** WARNING WARNING WARNING WARNING WARNING"
echo "*** Building without GConf. This means there's no"
echo "*** way to change prefs except hacking source code."
echo "*** This is intended for embedded systems etc., not for normal use."
fi
if test x$enable_verbose_mode = xno; then
echo "*** WARNING WARNING WARNING WARNING WARNING"
echo "*** Building without verbose mode"
@ -458,6 +542,9 @@ mutter-$VERSION
source code location: ${srcdir}
compiler: ${CC}
GConf: ${enable_gconf}
XFree86 Xinerama: ${use_xfree_xinerama}
Solaris Xinerama: ${use_solaris_xinerama}
Startup notification: ${have_startup_notification}
libcanberra: ${have_libcanberra}
Introspection: ${found_introspection}
@ -472,8 +559,8 @@ MUTTER_MINOR_VERSION=mutter_minor_version
if expr $MUTTER_MINOR_VERSION % 2 > /dev/null ; then
stable_version=`expr $MUTTER_MINOR_VERSION - 1`
echo "This is the UNSTABLE branch of mutter"
echo -n "Use 3.$stable_version.x for stable "
echo "(gnome-3-$stable_version branch in git)"
echo -n "Use 2.$stable_version.x for stable "
echo "(gnome-2-$stable_version branch in git)"
else
echo "This is the stable branch of mutter"
fi

View File

@ -31,7 +31,8 @@ workspaces. In these cases, there needs to be a rule consistent with
the above about the new window to choose.
Focus method Behavior
click Focus the window on top
click Focus the most recently used window (same as the window
on top)
sloppy Focus the window containing the pointer if there is such
a window, otherwise focus the most recently used window.
mouse Focus the non-DESKTOP window containing the pointer if

View File

@ -46,13 +46,13 @@ because the original program does not have a manual page.
Restart \fBmutter\fP(1) which is running.
.TP
.B reload-theme
Reload a theme which is specified on gsettings database.
Reload a theme which is specified on gconf database.
.TP
.B enable-keybindings
Enable all of keybindings which is specified on gsettings database.
Enable all of keybindings which is specified on gconf database.
.TP
.B disable-keybindings
Disable all of keybindings which is specified on gsettings database.
Disable all of keybindings which is specified on gconf database.
.SH SEE ALSO
.BR mutter (1)
.SH AUTHOR

View File

@ -51,7 +51,7 @@ Print the version number.
.B \-?, \-\-help
Show summary of options.
.SH CONFIGURATION
\fBmutter\fP configuration can be found under \fIPreferences\fP->\fIWindows\fP and \fIPreferences\fP->\fIKeyboard Shortcuts\fP on the menu-panel. Advanced configuration can be achieved directly through gsettings.
\fBmutter\fP configuration can be found under \fIPreferences\fP->\fIWindows\fP and \fIPreferences\fP->\fIKeyboard Shortcuts\fP on the menu-panel. Advanced configuration can be achieved directly through gconf editing (gconf-editor or gconftool-2).
.SH SEE ALSO
.BR mutter-message (1)
.SH AUTHOR

View File

@ -22,18 +22,6 @@ This document has separate sections for each format version. You may
want to read the document in reverse order, since the base features
are discussed under version 1.
New Features in Theme Format Version 3.4
========================================
An additional color type is added to pick up custom colors defined
in the GTK+ theme's CSS:
gtk:custom(name,fallback)
where <name> refers to a custom color defined with @define-color in
the GTK+ theme, and <fallback> provides an alternative color definition
in case the color referenced by <name> is not found.
New Features in Theme Format Version 3.3
========================================

View File

@ -39,11 +39,4 @@ environment.</description>
<gnome:userid>otaylor</gnome:userid>
</foaf:Person>
</maintainer>
<maintainer>
<foaf:Person>
<foaf:name>Florian Müllner</foaf:name>
<foaf:mbox rdf:resource="mailto:fmuellner@gnome.org" />
<gnome:userid>fmuellner</gnome:userid>
</foaf:Person>
</maintainer>
</Project>

View File

@ -1,9 +1,6 @@
# List of source files containing translatable strings.
# Please keep this file sorted alphabetically.
src/50-mutter-navigation.xml.in
src/50-mutter-system.xml.in
src/50-mutter-windows.xml.in
src/compositor/compositor.c
src/core/all-keybindings.h
src/core/bell.c
src/core/core.c
src/core/delete.c
@ -21,7 +18,7 @@ src/core/window-props.c
src/core/xprops.c
src/mutter.desktop.in
src/mutter-wm.desktop.in
src/org.gnome.mutter.gschema.xml.in
src/mutter.schemas.in
src/tools/mutter-message.c
src/ui/frames.c
src/ui/menu.c

1153
po/ar.po

File diff suppressed because it is too large Load Diff

3891
po/as.po

File diff suppressed because it is too large Load Diff

184
po/ast.po
View File

@ -37,6 +37,7 @@ msgstr "Petición d'información ventana desconocida: %d"
#. Translators: %s is a window title
#: ../src/core/delete.c:95
#, c-format
#, c-format
msgid "<tt>%s</tt> is not responding."
msgstr "<tt>%s</tt> nun ta respondiendo."
@ -121,6 +122,7 @@ msgstr "Comandu de terminal nun definíu.\n"
#: ../src/core/main.c:130
#, c-format
#, c-format
msgid ""
"mutter %s\n"
"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n"
@ -259,6 +261,7 @@ msgstr "Error axustando númberu d'arees de trabayu a %d: %s\n"
#: ../src/core/prefs.c:2028 ../src/core/prefs.c:2531
#, c-format
#, c-format
msgid "Workspace %d"
msgstr "Espaciu de Trabayu %d"
@ -272,6 +275,7 @@ msgstr "\"%s\" atopau na base de datos de configuración nun ye un valor válidu
#: ../src/core/prefs.c:2612
#, c-format
#, c-format
msgid "Error setting name for workspace %d to \"%s\": %s\n"
msgstr "Fallu al afitar nome pal espaciu de trabayu %d a \"%s\": %s\n"
@ -282,16 +286,19 @@ msgstr "Fallu al afitar l'estáu del compositor: %s\n"
#: ../src/core/prefs.c:2845
#, c-format
#, c-format
msgid "Error setting clutter plugin list: %s\n"
msgstr "Fallu al afitar la llista desordenada de plugin: %s\n"
#: ../src/core/prefs.c:2889
#, c-format
#, c-format
msgid "Error setting live hidden windows status status: %s\n"
msgstr "Fallu al afitar l'estáu de les ventanes anubríes: %s\n"
#: ../src/core/prefs.c:2917
#, c-format
#, c-format
msgid "Error setting no tab popup status: %s\n"
msgstr "Fallu al afitar l'estáu de les llingüetes emerxentes: %s\n"
@ -351,6 +358,7 @@ msgstr "Falló analizar ficheru de sesión guardáu: %s\n"
#: ../src/core/session.c:1198
#, c-format
#, c-format
msgid "<mutter_session> attribute seen but we already have the session ID"
msgstr "Vióse l'atributu <mutter_session> pero yá tenemos la ID de sesión"
@ -396,6 +404,7 @@ msgstr "Abiertu archivu log %s\n"
#: ../src/core/util.c:139 ../src/tools/mutter-message.c:176
#, c-format
#, c-format
msgid "Mutter was compiled without support for verbose mode\n"
msgstr "Mutter compilose ensin sofitu pal mou testu\n"
@ -490,19 +499,19 @@ msgid ""
msgstr "La propiedá %s del ventanu 0x%lx contien un códigu UTF-8 non válidu pal "
"elementu %d na llista\n"
#: ../src/include/all-keybindings.h:88 ../src/50-mutter-navigation.xml.in.h:18
#: ../src/include/all-keybindings.h:88
msgid "Switch to workspace 1"
msgstr "Cambiar a espaciu de trabayu 1"
#: ../src/include/all-keybindings.h:90 ../src/50-mutter-navigation.xml.in.h:19
#: ../src/include/all-keybindings.h:90
msgid "Switch to workspace 2"
msgstr "Cambiar a espaciu de trabayu 2"
#: ../src/include/all-keybindings.h:92 ../src/50-mutter-navigation.xml.in.h:20
#: ../src/include/all-keybindings.h:92
msgid "Switch to workspace 3"
msgstr "Cambiar a espaciu de trabayu 3"
#: ../src/include/all-keybindings.h:94 ../src/50-mutter-navigation.xml.in.h:21
#: ../src/include/all-keybindings.h:94
msgid "Switch to workspace 4"
msgstr "Cambiar a espaciu de trabayu 4"
@ -631,57 +640,47 @@ msgstr "Saca una semeya d'una ventana"
msgid "Run a terminal"
msgstr "Executar una terminal"
#: ../src/include/all-keybindings.h:271 ../src/50-mutter-windows.xml.in.h:1
#: ../src/include/all-keybindings.h:271
msgid "Activate the window menu"
msgstr "Activar el menú de la ventana"
#: ../src/include/all-keybindings.h:274 ../src/50-mutter-windows.xml.in.h:13
#, fuzzy
#: ../src/include/all-keybindings.h:274
msgid "Toggle fullscreen mode"
msgstr ""
"#-#-#-#-# ast.po (metacity) #-#-#-#-#\n"
"Camudar a modu pantalla completa\n"
"#-#-#-#-# ast.po (metacity) #-#-#-#-#\n"
"Camudar a mou pantalla completa"
msgstr "Camudar a modu pantalla completa"
#: ../src/include/all-keybindings.h:276 ../src/50-mutter-windows.xml.in.h:14
#, fuzzy
#: ../src/include/all-keybindings.h:276
msgid "Toggle maximization state"
msgstr ""
"#-#-#-#-# ast.po (metacity) #-#-#-#-#\n"
"Camudar a estáu maximizáu\n"
"#-#-#-#-# ast.po (metacity) #-#-#-#-#\n"
"Conmutar l'estáu maximizáu"
msgstr "Camudar a estáu maximizáu"
#: ../src/include/all-keybindings.h:278
msgid "Toggle whether a window will always be visible over other windows"
msgstr "Conmutar si una ventana siempres se verá encima d'otres ventanes"
#: ../src/include/all-keybindings.h:280 ../src/50-mutter-windows.xml.in.h:4
#: ../src/include/all-keybindings.h:280
msgid "Maximize window"
msgstr "Maximizar ventana"
#: ../src/include/all-keybindings.h:282 ../src/50-mutter-windows.xml.in.h:12
#: ../src/include/all-keybindings.h:282
msgid "Restore window"
msgstr "Restaurar la ventana"
#: ../src/include/all-keybindings.h:284 ../src/50-mutter-windows.xml.in.h:15
#: ../src/include/all-keybindings.h:284
msgid "Toggle shaded state"
msgstr "Activa estáu endolcáu"
#: ../src/include/all-keybindings.h:286 ../src/50-mutter-windows.xml.in.h:7
#: ../src/include/all-keybindings.h:286
msgid "Minimize window"
msgstr "Minimizar ventana"
#: ../src/include/all-keybindings.h:288 ../src/50-mutter-windows.xml.in.h:2
#: ../src/include/all-keybindings.h:288
msgid "Close window"
msgstr "Zarrar ventana"
#: ../src/include/all-keybindings.h:290 ../src/50-mutter-windows.xml.in.h:8
#: ../src/include/all-keybindings.h:290
msgid "Move window"
msgstr "Mover ventana"
#: ../src/include/all-keybindings.h:292 ../src/50-mutter-windows.xml.in.h:11
#: ../src/include/all-keybindings.h:292
msgid "Resize window"
msgstr "Cambiar el tamañu la ventana"
@ -690,22 +689,18 @@ msgid "Toggle whether window is on all workspaces or just one"
msgstr "Conmutar si la ventana apaez en toles árees de trabayu o namái nuna"
#: ../src/include/all-keybindings.h:299
#: ../src/50-mutter-navigation.xml.in.h:10
msgid "Move window to workspace 1"
msgstr "Mover ventana al espaciu de trabayu 1"
#: ../src/include/all-keybindings.h:302
#: ../src/50-mutter-navigation.xml.in.h:11
msgid "Move window to workspace 2"
msgstr "Mover ventana al espaciu de trabayu 2"
#: ../src/include/all-keybindings.h:305
#: ../src/50-mutter-navigation.xml.in.h:12
msgid "Move window to workspace 3"
msgstr "Mover ventana al espaciu de trabayu 3"
#: ../src/include/all-keybindings.h:308
#: ../src/50-mutter-navigation.xml.in.h:13
msgid "Move window to workspace 4"
msgstr "Mover ventana al espaciu de trabayu 4"
@ -741,24 +736,19 @@ msgstr "Mover ventana al espaciu de trabayu 11"
msgid "Move window to workspace 12"
msgstr "Mover ventana al espaciu de trabayu 12"
#: ../src/include/all-keybindings.h:344 ../src/50-mutter-navigation.xml.in.h:7
#: ../src/include/all-keybindings.h:344
msgid "Move window one workspace to the left"
msgstr "Mover ventana un espaciu de trabayu a manzorga"
#: ../src/include/all-keybindings.h:347 ../src/50-mutter-navigation.xml.in.h:8
#, fuzzy
#: ../src/include/all-keybindings.h:347
msgid "Move window one workspace to the right"
msgstr ""
"#-#-#-#-# ast.po (metacity) #-#-#-#-#\n"
"Mover ventana un espaciu de trabayu a derecha\n"
"#-#-#-#-# ast.po (metacity) #-#-#-#-#\n"
"Mover ventana un espaciu de trabayu a madrecha"
msgstr "Mover ventana un espaciu de trabayu a derecha"
#: ../src/include/all-keybindings.h:350 ../src/50-mutter-navigation.xml.in.h:9
#: ../src/include/all-keybindings.h:350
msgid "Move window one workspace up"
msgstr "Mover ventana un espaciu de trabayu p'arriba"
#: ../src/include/all-keybindings.h:353 ../src/50-mutter-navigation.xml.in.h:6
#: ../src/include/all-keybindings.h:353
msgid "Move window one workspace down"
msgstr "Mover ventana un espaciu de trabayu p'abaxo"
@ -767,29 +757,19 @@ msgid "Raise window if it's covered by another window, otherwise lower it"
msgstr ""
"Llevantar la ventana si ta cubierta por otra ventana, minimizala n'otru casu"
#: ../src/include/all-keybindings.h:358 ../src/50-mutter-windows.xml.in.h:9
#, fuzzy
#: ../src/include/all-keybindings.h:358
msgid "Raise window above other windows"
msgstr ""
"#-#-#-#-# ast.po (metacity) #-#-#-#-#\n"
"Poner el ventanu en primer planu\n"
"#-#-#-#-# ast.po (metacity) #-#-#-#-#\n"
"Poner la ventana en primer planu"
msgstr "Poner el ventanu en primer planu"
#: ../src/include/all-keybindings.h:360 ../src/50-mutter-windows.xml.in.h:3
#, fuzzy
#: ../src/include/all-keybindings.h:360
msgid "Lower window below other windows"
msgstr ""
"#-#-#-#-# ast.po (metacity) #-#-#-#-#\n"
"Ventanu más baxu per debaxo d'otros ventanos\n"
"#-#-#-#-# ast.po (metacity) #-#-#-#-#\n"
"Ventana más baxa per debaxo d'otres ventanes"
msgstr "Ventanu más baxu per debaxo d'otros ventanos"
#: ../src/include/all-keybindings.h:364 ../src/50-mutter-windows.xml.in.h:6
#: ../src/include/all-keybindings.h:364
msgid "Maximize window vertically"
msgstr "Maximizar ventana verticalmente"
#: ../src/include/all-keybindings.h:368 ../src/50-mutter-windows.xml.in.h:5
#: ../src/include/all-keybindings.h:368
msgid "Maximize window horizontally"
msgstr "Maximizar ventana horizontalmente"
@ -1003,6 +983,7 @@ msgstr "Espaciu de Trabayu %d%n"
#: ../src/ui/menu.c:213
#, c-format
#, c-format
msgid "Workspace 1_0"
msgstr "Espaciu de Trabayu 1_0"
@ -1743,6 +1724,7 @@ msgstr "Nun se permite testu dientro del elementu <%s>"
#: ../src/ui/theme-parser.c:3748 ../src/ui/theme-parser.c:3760
#: ../src/ui/theme-parser.c:3772
#, c-format
#, c-format
msgid "<%s> specified twice for this theme"
msgstr "<%s> especificáu dos vegaes pa esti tema"
@ -1954,96 +1936,6 @@ msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n"
msgstr "%d espresiones de coordenaes interpretaes en %g segundos (%g segundos de "
"media)\n"
#: ../src/50-mutter-navigation.xml.in.h:1
#, fuzzy
msgid "Hide all normal windows"
msgstr "Anubrir toles ventanes normales"
#: ../src/50-mutter-navigation.xml.in.h:2
#, fuzzy
msgid "Move to workspace above"
msgstr "Mover al área de trabayu d'arriba"
#: ../src/50-mutter-navigation.xml.in.h:3
#, fuzzy
msgid "Move to workspace below"
msgstr "Mover al área de trabayu d'abaxo"
#: ../src/50-mutter-navigation.xml.in.h:4
#, fuzzy
msgid "Move to workspace left"
msgstr "Mover al área de trabayu de la izquierda"
#: ../src/50-mutter-navigation.xml.in.h:5
#, fuzzy
msgid "Move to workspace right"
msgstr "Mover al área de trabayu de la derecha"
#: ../src/50-mutter-navigation.xml.in.h:14
#, fuzzy
msgid "Navigation"
msgstr "Navegación"
#: ../src/50-mutter-navigation.xml.in.h:15
#, fuzzy
msgid "Switch applications"
msgstr "Movese ente aplicaciones"
#: ../src/50-mutter-navigation.xml.in.h:16
#, fuzzy
msgid "Switch system controls"
msgstr "Cambiar ente controles del sistema"
#: ../src/50-mutter-navigation.xml.in.h:17
#, fuzzy
msgid "Switch system controls directly"
msgstr "Movese ente los controles del sistema direutamente"
#: ../src/50-mutter-navigation.xml.in.h:22
#, fuzzy
msgid "Switch windows directly"
msgstr "Cambiar ventanes direutamente"
#: ../src/50-mutter-navigation.xml.in.h:23
#, fuzzy
msgid "Switch windows of an app directly"
msgstr "Movese ente les ventanes d'una aplicación direutamente"
#: ../src/50-mutter-navigation.xml.in.h:24
#, fuzzy
msgid "Switch windows of an application"
msgstr "Movese ente les ventanes d'una aplicación"
#: ../src/50-mutter-system.xml.in.h:1
#, fuzzy
msgid "Show the activities overview"
msgstr "Amosar el resume d'actividaes"
#: ../src/50-mutter-system.xml.in.h:2
#, fuzzy
msgid "Show the run command prompt"
msgstr "Amosar l'elementu «executar comando»"
#: ../src/50-mutter-system.xml.in.h:3
#, fuzzy
msgid "System"
msgstr "Sistema"
#: ../src/50-mutter-windows.xml.in.h:10
#, fuzzy
msgid "Raise window if covered, otherwise lower it"
msgstr "Llevantar la ventana si ta cubierta, minimizala n'otru casu"
#: ../src/50-mutter-windows.xml.in.h:16
#, fuzzy
msgid "Toggle window on all workspaces or one"
msgstr "Conmutar la ventana en toles árees de trabayu o namái nuna"
#: ../src/50-mutter-windows.xml.in.h:17
#, fuzzy
msgid "Windows"
msgstr "Ventanes"
#~ msgid "Desktop"
#~ msgstr "Escritoriu"

3448
po/be.po

File diff suppressed because it is too large Load Diff

987
po/bg.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1448
po/ca.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1309
po/cs.po

File diff suppressed because it is too large Load Diff

3117
po/da.po

File diff suppressed because it is too large Load Diff

1407
po/de.po

File diff suppressed because it is too large Load Diff

1366
po/el.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1342
po/eo.po

File diff suppressed because it is too large Load Diff

1736
po/es.po

File diff suppressed because it is too large Load Diff

564
po/et.po
View File

@ -7,171 +7,253 @@
#
# Tõivo Leedjärv <toivo linux ee>, 2004.
# Ivar Smolin <okul linux ee>, 2005, 2006, 20092011.
# Mattias Põldaru <mahfiaz@gmail.com>, 20082011, 2012.
# Mattias Põldaru <mahfiaz gmail com>, 20082011.
#
msgid ""
msgstr ""
"Project-Id-Version: mutter MASTER\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?"
"product=mutter&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2012-12-18 22:30+0000\n"
"PO-Revision-Date: 2012-12-19 18:06+0300\n"
"Last-Translator: Mattias Põldaru <mahfiaz@gmail.com>\n"
"Language-Team: Estonian <>\n"
"Language: et\n"
"product=mutter&component=general\n"
"POT-Creation-Date: 2011-03-07 23:35+0000\n"
"PO-Revision-Date: 2011-03-09 06:41+0200\n"
"Last-Translator: Ivar Smolin <okul@linux.ee>\n"
"Language-Team: Estonian <gnome-et@linux.ee>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n!=1);\n"
msgid "Navigation"
msgstr "Navigeerimine"
msgid "Move window to workspace 1"
msgstr "Akna liigutamine 1. tööalale"
msgid "Move window to workspace 2"
msgstr "Akna liigutamine 2. tööalale"
msgid "Move window to workspace 3"
msgstr "Akna liigutamine 3. tööalale"
msgid "Move window to workspace 4"
msgstr "Akna liigutamine 4. tööalale"
msgid "Move window one workspace to the left"
msgstr "Akna tõstmine vasakpoolsele tööalale"
msgid "Move window one workspace to the right"
msgstr "Akna tõstmine parempoolsele tööalale"
msgid "Move window one workspace up"
msgstr "Akna tõstmine ülemisele tööalale"
msgid "Move window one workspace down"
msgstr "Akna tõstmine alumisele tööalale"
msgid "Switch applications"
msgstr "Rakenduste vahetamine"
msgid "Switch windows"
msgstr "Akende vahetamine"
msgid "Switch windows of an application"
msgstr "Rakenduse akende vahetamine"
msgid "Switch system controls"
msgstr "Süsteemi juhtalade vahetamine"
msgid "Switch windows directly"
msgstr "Akende kohene vahetamine"
msgid "Switch windows of an app directly"
msgstr "Rakenduse akende kohene vahetamine"
msgid "Switch system controls directly"
msgstr "Süsteemi juhtalade kohene vahetamine"
msgid "Hide all normal windows"
msgstr "Kõigi tavaliste akende peitmine"
"Language: et\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
msgid "Switch to workspace 1"
msgstr "1. tööalale liikumine"
msgstr "Lülitumine 1. tööalale"
msgid "Switch to workspace 2"
msgstr "2. tööalale liikumine"
msgstr "Lülitumine 2. tööalale"
msgid "Switch to workspace 3"
msgstr "3. tööalale liikumine"
msgstr "Lülitumine 3. tööalale"
msgid "Switch to workspace 4"
msgstr "4. tööalale liikumine"
msgstr "Lülitumine 4. tööalale"
msgid "Move to workspace left"
msgstr "Vasakpoolsele tööalale liikumine"
msgid "Switch to workspace 5"
msgstr "Lülitumine 5. tööalale"
msgid "Move to workspace right"
msgstr "Parempoolsele tööalale liikumine"
msgid "Switch to workspace 6"
msgstr "Lülitumine 6. tööalale"
msgid "Move to workspace above"
msgstr "Ülemisele tööalale liikumine"
msgid "Switch to workspace 7"
msgstr "Lülitumine 7. tööalale"
msgid "Move to workspace below"
msgstr "Alumisele tööalale liikumine"
msgid "Switch to workspace 8"
msgstr "Lülitumine 8. tööalale"
msgid "System"
msgstr "Süsteem"
msgid "Switch to workspace 9"
msgstr "Lülitumine 9. tööalale"
msgid "Show the run command prompt"
msgstr "Käsuviiba kuvamine"
msgid "Switch to workspace 10"
msgstr "Lülitumine 10. tööalale"
msgid "Show the activities overview"
msgstr "Tegevuste ülevaate avamine"
msgid "Switch to workspace 11"
msgstr "Lülitumine 11. tööalale"
msgid "Windows"
msgstr "Aknad"
msgid "Switch to workspace 12"
msgstr "Lülitumine 12. tööalale"
msgid "Switch to workspace on the left of the current workspace"
msgstr "Lülitumine sellest tööalast vasakul olevale tööalale"
msgid "Switch to workspace on the right of the current workspace"
msgstr "Lülitumine sellest tööalast paremal olevale tööalale"
msgid "Switch to workspace above the current workspace"
msgstr "Lülitumine selle tööala kohal olevale tööalale"
msgid "Switch to workspace below the current workspace"
msgstr "Lülitumine selle tööala all olevale tööalale"
msgid "Move between windows of an application, using a popup window"
msgstr "Liigu rakenduse akende vahel, hüpikaknaga"
msgid "Move backward between windows of an application, using a popup window"
msgstr "Liigu rakenduse akende vahel tagasisuunas, hüpikaknaga"
msgid "Move between windows, using a popup window"
msgstr "Liigu akende vahel, hüpikaknaga"
msgid "Move backward between windows, using a popup window"
msgstr "Liigu akende vahel tagasisuunas, hüpikaknaga"
msgid "Move between panels and the desktop, using a popup window"
msgstr "Liigu paneelide ja töölaua vahel, hüpikaknaga"
msgid "Move backward between panels and the desktop, using a popup window"
msgstr "Liigu tagasisuunas paneelide ja töölaua vahel, hüpikaknaga"
msgid "Move between windows of an application immediately"
msgstr "Liigu koheselt rakenduse akende vahel"
msgid "Move backward between windows of an application immediately"
msgstr "Liigu koheselt rakenduse akende vahel tagasisuunas"
msgid "Move between windows immediately"
msgstr "Liigu koheselt akende vahel"
msgid "Move backward between windows immediately"
msgstr "Liigu koheselt akende vahel tagasisuunas"
msgid "Move between panels and the desktop immediately"
msgstr "Liigu koheselt paneeli ja töölaua vahel"
msgid "Move backward between panels and the desktop immediately"
msgstr "Liigu koheselt tagasisuunas paneelide ja töölaua vahel"
msgid "Hide all normal windows and set focus to the desktop"
msgstr "Peida kõik tavalised aknad ja fokuseeri töölaud"
msgid "Show the panel's main menu"
msgstr "Paneeli peamenüü näitamine"
msgid "Show the panel's \"Run Application\" dialog box"
msgstr "Paneeli dialoogi \"Käivita rakendus\" näitamine"
msgid "Start or stop recording the session"
msgstr "Seansi salvestamise käivitamine või seiskamine"
msgid "Take a screenshot"
msgstr "Kuvatõmmise võtmine"
msgid "Take a screenshot of a window"
msgstr "Kuvatõmmise võtmine aknast"
msgid "Run a terminal"
msgstr "Terminali käivitamine"
msgid "Activate the window menu"
msgstr "Aknamenüü avamine"
msgstr "Aknamenüü aktiveerimine"
msgid "Toggle fullscreen mode"
msgstr "Täisekraanoleku vahetamine"
msgstr "Täisekraanivaate sisse- ja väljalülitamine"
msgid "Toggle maximization state"
msgstr "Maksimeeritud oleku vahetamine"
msgstr "Maksimeeritud oleku sisse- ja väljalülitamine"
msgid "Toggle whether a window will always be visible over other windows"
msgstr "Lüliti määrab, kas aken on alati teiste akende kohal nähtav"
msgid "Maximize window"
msgstr "Akna maksimeerimine"
msgid "Restore window"
msgstr "Akna taastamine"
msgstr "Taasta akna suurus"
msgid "Toggle shaded state"
msgstr "Varjatud oleku vahetamine"
msgid "Close window"
msgstr "Akna sulgemine"
msgstr "Varjatud oleku lüliti"
msgid "Minimize window"
msgstr "Akna minimeerimine"
msgid "Close window"
msgstr "Akna sulgemine"
msgid "Move window"
msgstr "Akna liigutamine"
msgstr "Teisalda aken"
msgid "Resize window"
msgstr "Akna suuruse muutmine"
msgstr "Muuda akna suurust"
msgid "Toggle window on all workspaces or one"
msgstr "Akna kõigil või ühel tööalal olemise vahetamine"
msgid "Toggle whether window is on all workspaces or just one"
msgstr "Lüliti määrab, kas aken on kõigil tööaladel või ainult ühel"
msgid "Raise window if covered, otherwise lower it"
msgstr "Akna tõstmine, kui see on kaetud, muul juhul langetamine"
msgid "Move window to workspace 1"
msgstr "Akna tõstmine 1. tööalale"
msgid "Move window to workspace 2"
msgstr "Akna tõstmine 2. tööalale"
msgid "Move window to workspace 3"
msgstr "Akna tõstmine 3. tööalale"
msgid "Move window to workspace 4"
msgstr "Akna tõstmine 4. tööalale"
msgid "Move window to workspace 5"
msgstr "Akna tõstmine 5. tööalale"
msgid "Move window to workspace 6"
msgstr "Akna tõstmine 6. tööalale"
msgid "Move window to workspace 7"
msgstr "Akna tõstmine 7. tööalale"
msgid "Move window to workspace 8"
msgstr "Akna tõstmine 8. tööalale"
msgid "Move window to workspace 9"
msgstr "Akna tõstmine 9. tööalale"
msgid "Move window to workspace 10"
msgstr "Akna tõstmine 10. tööalale"
msgid "Move window to workspace 11"
msgstr "Akna tõstmine 11. tööalale"
msgid "Move window to workspace 12"
msgstr "Akna tõstmine 12. tööalale"
msgid "Move window one workspace to the left"
msgstr "Akna tõstmine ühe tööala võrra vasakule"
msgid "Move window one workspace to the right"
msgstr "Akna tõstmine ühe tööala võrra paremale"
msgid "Move window one workspace up"
msgstr "Akna tõstmine ühe tööala võrra ülespoole"
msgid "Move window one workspace down"
msgstr "Akna tõstmine ühe tööala võrra allapoole"
msgid "Raise window if it's covered by another window, otherwise lower it"
msgstr "Tõsta aken, kui seda katab teine aken, muul juhul vii tahapoole"
msgid "Raise window above other windows"
msgstr "Akna tõstmine teiste kohale"
msgstr "Akna tõstmine teiste akende kohale"
msgid "Lower window below other windows"
msgstr "Akna langetamine teiste taha"
msgstr "Saada aken teiste taha"
msgid "Maximize window vertically"
msgstr "Akna vertikaalne maksimeerimine"
msgstr "Maksimeeri aken vertikaalselt"
msgid "Maximize window horizontally"
msgstr "Akna horisontaalne maksimeerimine"
msgstr "Maksimeeri aken horisontaalselt"
msgid "View split on left"
msgstr "Vaade poolitatakse vasakult"
msgid "Move window to north-west (top left) corner"
msgstr "Akna tõstmine ekraani loodepoolsesse (ülemisse vasakusse) nurka"
msgid "View split on right"
msgstr "Vaade poolitatakse paremalt"
msgid "Move window to north-east (top right) corner"
msgstr "Akna tõstmine ekraani kirdepoolsesse (ülemisse paremasse) nurka"
#. This probably means that a non-WM compositor like xcompmgr is running;
#. * we have no way to get it to exit
#, c-format
msgid ""
"Another compositing manager is already running on screen %i on display \"%s"
"\"."
msgstr "Teine komposiithaldur juba töötab ekraani %i kuval \"%s\"."
msgid "Move window to south-west (bottom left) corner"
msgstr "Akna tõstmine ekraani edelapoolsesse (alumisse vasakusse) nurka"
msgid "Move window to south-east (bottom right) corner"
msgstr "Akna tõstmine ekraani kagupoolsesse (alumisse paremasse) nurka"
msgid "Move window to north (top) side of screen"
msgstr "Akna tõstmine ekraani põhjapoolsesse (ülemisse) serva"
msgid "Move window to south (bottom) side of screen"
msgstr "Akna tõstmine ekraani lõunapoolsesse (alumisse) serva"
msgid "Move window to east (right) side of screen"
msgstr "Akna tõstmine ekraani idapoolsesse (paremasse) serva"
msgid "Move window to west (left) side of screen"
msgstr "Akna tõstmine ekraani läänepoolsesse (vasakusse) serva"
msgid "Move window to center of screen"
msgstr "Akna tõstmine ekraani keskele"
msgid "Bell event"
msgstr "Helina sündmus"
@ -180,12 +262,10 @@ msgstr "Helina sündmus"
msgid "Unknown window information request: %d"
msgstr "Tundmatu aknateabe päring: %d"
#. Translators: %s is a window title
#, c-format
msgid "“%s” is not responding."
msgstr "„%s” ei vasta."
msgid "Application is not responding."
msgstr "Rakendus ei vasta."
msgid "<tt>%s</tt> is not responding."
msgstr "<tt>%s</tt> ei vasta."
msgid ""
"You may choose to wait a short while for it to continue or force the "
@ -214,6 +294,27 @@ msgstr ""
"Mõni teine programm juba kasutab klahvi %s koos muuteklahvidega %x "
"kiirklahvina\n"
#. Displayed when a keybinding which is
#. * supposed to launch a program fails.
#.
#, c-format
msgid ""
"There was an error running <tt>%s</tt>:\n"
"\n"
"%s"
msgstr ""
"<tt>%s</tt> käivitamisel esines viga:\n"
"\n"
"%s"
#, c-format
msgid "No command %d has been defined.\n"
msgstr "Käsku %d pole defineeritud.\n"
#, c-format
msgid "No terminal command has been defined.\n"
msgstr "Terminalikäsku pole defineeritud.\n"
msgid "Disable connection to session manager"
msgstr "Seansihalduriga ühendumise keelamine"
@ -260,8 +361,41 @@ msgstr ""
msgid "Print version"
msgstr "Versiooni printimine"
msgid "Mutter plugin to use"
msgstr "Millist Mutteri pluginat kasutada"
msgid "Comma-separated list of compositor plugins"
msgstr "Komaga eraldatud nimekiri komposiitmontaaži pluginatest"
#.
#. * We found it, but it was invalid. Complain.
#. *
#. * FIXME: This replicates the original behaviour, but in the future
#. * we might consider reverting invalid keys to their original values.
#. * (We know the old value, so we can look up a suitable string in
#. * the symtab.)
#. *
#. * (Empty comment follows so the translators don't see this.)
#.
#.
#, c-format
msgid "GConf key '%s' is set to an invalid value\n"
msgstr "GConf võtme '%s' väärtus on vigane\n"
#, c-format
msgid "%d stored in GConf key %s is out of range %d to %d\n"
msgstr ""
"%d, mis on salvestatud GConf võtmes %s, on väljaspool piirkonda %d - %d\n"
#, c-format
msgid "GConf key \"%s\" is set to an invalid type\n"
msgstr "GConf-i võti \"%s\" on määratud vigase tüübiga\n"
#, c-format
msgid "GConf key %s is already in use and can't be used to override %s\n"
msgstr ""
"GConfi võti %s on juba kasutusel ja sellega ei saa tühistada võtit %s\n"
#, c-format
msgid "Can't override GConf key, %s not found\n"
msgstr "GConfi võtit pole võimalik tühistada, võtit %s ei leitud\n"
msgid ""
"Workarounds for broken applications disabled. Some applications may not "
@ -271,8 +405,8 @@ msgstr ""
"ei pruugi õigesti käituda.\n"
#, c-format
msgid "Could not parse font description \"%s\" from GSettings key %s\n"
msgstr "Fondi kirjeldust \"%s\" GSettings võtmest %s pole võimalik töödelda\n"
msgid "Could not parse font description \"%s\" from GConf key %s\n"
msgstr "Fondi kirjeldust \"%s\" GConf võtmest %s ei saa töödelda\n"
#, c-format
msgid ""
@ -282,6 +416,14 @@ msgstr ""
"Seadistuste andmebaasist leitud \"%s\" ei ole sobiv väärtus hiireklahvi "
"modifikaatoriks\n"
#, c-format
msgid "Error setting number of workspaces to %d: %s\n"
msgstr "Viga tööalade arvuks %d määramisel: %s\n"
#, c-format
msgid "Workspace %d"
msgstr "Tööala %d"
#, c-format
msgid ""
"\"%s\" found in configuration database is not a valid value for keybinding "
@ -291,8 +433,16 @@ msgstr ""
"\"\n"
#, c-format
msgid "Workspace %d"
msgstr "Tööala %d"
msgid "Error setting name for workspace %d to \"%s\": %s\n"
msgstr "Viga tööalale %d nime \"%s\" määramisel: %s\n"
#, c-format
msgid "Error setting live hidden windows status status: %s\n"
msgstr "Viga varjus elushoitavate akende oleku määramisel: %s\n"
#, c-format
msgid "Error setting no tab popup status: %s\n"
msgstr ""
#, c-format
msgid "Screen %d on display '%s' is invalid\n"
@ -390,6 +540,10 @@ msgstr "Aknahalduri hoiatus: "
msgid "Window manager error: "
msgstr "Aknahalduri viga: "
#. Translators: This is the title used on dialog boxes
msgid "Mutter"
msgstr "Mutter"
#. first time through
#, c-format
msgid ""
@ -427,12 +581,6 @@ msgstr "%s (masinas %s)"
msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n"
msgstr "Vigane WM_TRANSIENT_FOR aknale 0x%lx määratud %s jaoks.\n"
#, c-format
msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n"
msgstr ""
"WM_TRANSIENT_FOR aknale 0x%lx määratud %s jaoks tekitaks tsüklilise "
"korduse.\n"
#, c-format
msgid ""
"Window 0x%lx has property %s\n"
@ -456,8 +604,18 @@ msgid ""
"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n"
msgstr "Omadus %s aknal 0x%lx sisaldab vigast UTF-8 %d kirjele nimekirjas\n"
msgid "Mutter"
msgstr "Mutter"
msgid "Attach modal dialogs"
msgstr "Modaaldialoogide kinnistamine"
msgid ""
"Determines whether hidden windows (i.e., minimized windows and windows on "
"other workspaces than the current one) should be kept alive."
msgstr ""
"Määrab, kas varjatud aknaid (nt minimeeritud ja teistel tööaladel aknad) "
"hoitakse elus."
msgid "Live Hidden Windows"
msgstr "Varjatud akende aktiivsus"
msgid "Modifier to use for extended window management operations"
msgstr "Laiendatud aknaoperatsioonide korral kasutatav muuteklahv"
@ -474,9 +632,6 @@ msgstr ""
"klahv\". Eeldatavasti määratakse selle seose väärtuseks vaikimisi või tühi "
"sõne."
msgid "Attach modal dialogs"
msgstr "Modaaldialoogide kinnistamine"
msgid ""
"When true, instead of having independent titlebars, modal dialogs appear "
"attached to the titlebar of the parent window and are moved together with "
@ -485,80 +640,43 @@ msgstr ""
"Kui märgitud, siis eraldi tiitliribade asemel on moodaalsed dialoogid "
"emaakna tiitliribade küljes ning liiguvad koos emaaknaga."
msgid "Enable edge tiling when dropping windows on screen edges"
msgstr "Akna ümberpaigutamine selle lohistamisel ekraani serva"
msgid ""
"If enabled, dropping windows on vertical screen edges maximizes them "
"vertically and resizes them horizontally to cover half of the available "
"area. Dropping windows on the top screen edge maximizes them completely."
msgstr ""
"Kui märgitud, siis akna lohistamine ekraani külgservale maksimeerib selle "
"vertikaalselt ja laius katab pool saadaolevast laiusest. Akna lohistamine "
"ekraani ülaserva maksimeerib akna täielikult."
msgid "Workspaces are managed dynamically"
msgstr "Tööalade dünaamiline haldus"
msgid ""
"Determines whether workspaces are managed dynamically or whether there's a "
"static number of workspaces (determined by the num-workspaces key in org."
"gnome.desktop.wm.preferences)."
msgstr ""
"Määrab, kas tööalasid hallatakse dünaamiliselt või on nende arv staatiline "
"(arvu määrab org.gnome.desktop.wm.preferences all võti num-workspaces)."
msgid "Workspaces only on primary"
msgstr "Tööalad ainult peamisel"
msgid ""
"Determines whether workspace switching should happen for windows on all "
"monitors or only for windows on the primary monitor."
msgstr ""
"Määrab, kas tööalade vahetamine mõjutab kõiki aknaid kõigil monitoridel või "
"ainult aknaid peamisel monitoril."
msgid "No tab popup"
msgstr "Tabulaatoril pole hüpikakent"
msgid ""
"Determines whether the use of popup and highlight frame should be disabled "
"for window cycling."
msgstr ""
"Kui märgitud, siis on hüpikaken ja esiletõstmise raam keelatud akende "
"vahetamisel."
msgid "Delay focus changes until the pointer stops moving"
msgstr "Fookusemuutused lükatakse edasi kuni kursor peatub"
msgid ""
"If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then "
"the focus will not be changed immediately when entering a window, but only "
"after the pointer stops moving."
msgstr ""
"Kui tõene ning fookusrežiim on kas \"sloppy\" või \"mouse\", siis fookust ei "
"vahetata kohe, kui kursor aknale liigub, vaid alles pärast kursori peatumist."
msgid "Draggable border width"
msgstr "Lohistatava äärise laius."
msgid ""
"The amount of total draggable borders. If the theme's visible borders are "
"not enough, invisible borders will be added to meet this value."
msgstr ""
"Lohistatava äärise laius. Kui kujunduse nähtavatest ääristest ei piisa, "
"lisatakse puuduoleva osa jaoks nähtamatu ääris."
msgid "Select window from tab popup"
msgstr "Akna valimine tabulaatori hüpikaknalt"
msgid "Cancel tab popup"
msgstr "Tabulaatori hüpikakna katkestamine"
#, c-format
msgid "Usage: %s\n"
msgstr "Kasutamine: %s\n"
msgid "Close Window"
msgstr "Sulge aken"
msgid "Window Menu"
msgstr "Aknamenüü"
msgid "Minimize Window"
msgstr "Akna minimeerimine"
msgid "Maximize Window"
msgstr "Akna maksimeerimine"
msgid "Restore Window"
msgstr "Akna taastamine"
msgid "Roll Up Window"
msgstr "Akna kokkukerimine"
msgid "Unroll Window"
msgstr "Akna lahtikerimine"
msgid "Keep Window On Top"
msgstr "Akna kõige pealmiseks määramine"
msgid "Remove Window From Top"
msgstr "Eemalda aken kõige pealmise kohalt"
msgid "Always On Visible Workspace"
msgstr "Alati nähtaval tööalal"
msgid "Put Window On Only One Workspace"
msgstr "Tõsta aken ainult ühele tööalale"
#. Translators: Translate this string the same way as you do in libwnck!
msgid "Mi_nimize"
msgstr "_Minimeeri"
@ -759,30 +877,6 @@ msgstr "Raami geomeetria ei määra nuppude suurust"
msgid "Gradients should have at least two colors"
msgstr "Värviüleminekus peaks olema vähemalt kaks värvi"
#, c-format
msgid ""
"GTK custom color specification must have color name and fallback in "
"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\""
msgstr ""
"GTK kohandatud värvi määrang peab sisaldama sulgudes värvi nimetust ning "
"varuvärvi, nt gtk:custom(foo,bar); väärtust \"%s\" pole võimalik töödelda"
#, c-format
msgid ""
"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-"
"_ are valid"
msgstr ""
"gtk:custom color_name parameetris sobimatu märk '%c', lubatud on ainult A-Za-"
"z0-9-_"
#, c-format
msgid ""
"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not "
"fit the format"
msgstr ""
"Gtk:custom vorming on \"gtk:custom(värvi_nimi,varuvärv)\", \"%s\" ei sobi "
"selle vorminguga"
#, c-format
msgid ""
"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] "
@ -1417,3 +1511,25 @@ msgstr "y väärtus oli %d, oodati väärtust %d"
msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n"
msgstr ""
"%d koordinaatide avaldis töödeldi %g sekundiga (keskmine %g sekundit)\n"
#~ msgid ""
#~ "Don't make fullscreen windows that are maximized and have no decorations"
#~ msgstr "Ei tehta maksimeeritud ilma raamita täisekraanaknaid."
#~ msgid "Whether window popup/frame should be shown when cycling windows."
#~ msgstr "Kas hüpikakent/raami näidatakse akende vahetamisel."
#~ msgid "Internal argument for GObject introspection"
#~ msgstr "GObject enesevaatluse siseargument"
#~ msgid "Failed to restart: %s\n"
#~ msgstr "Tõrge taaskäivitamisel: %s\n"
#~ msgid "Error setting clutter plugin list: %s\n"
#~ msgstr "Viga clutteri pluginate nimekirja määramisel: %s\n"
#~ msgid "Clutter Plugins"
#~ msgstr "Clutteri pluginad"
#~ msgid "Plugins to load for the Clutter-based compositing manager."
#~ msgstr "Clutteril põhineva komposiitmontaažihalduri laadimise pluginad."

1340
po/eu.po

File diff suppressed because it is too large Load Diff

6282
po/fa.po

File diff suppressed because it is too large Load Diff

2277
po/fi.po

File diff suppressed because it is too large Load Diff

1218
po/fr.po

File diff suppressed because it is too large Load Diff

1312
po/gl.po

File diff suppressed because it is too large Load Diff

1455
po/gu.po

File diff suppressed because it is too large Load Diff

1682
po/he.po

File diff suppressed because it is too large Load Diff

2968
po/hi.po

File diff suppressed because it is too large Load Diff

1436
po/hu.po

File diff suppressed because it is too large Load Diff

1145
po/id.po

File diff suppressed because it is too large Load Diff

1641
po/it.po

File diff suppressed because it is too large Load Diff

2647
po/ja.po

File diff suppressed because it is too large Load Diff

1611
po/kn.po

File diff suppressed because it is too large Load Diff

1156
po/ko.po

File diff suppressed because it is too large Load Diff

3734
po/lt.po

File diff suppressed because it is too large Load Diff

1702
po/lv.po

File diff suppressed because it is too large Load Diff

4490
po/ml.po

File diff suppressed because it is too large Load Diff

3183
po/mr.po

File diff suppressed because it is too large Load Diff

956
po/nb.po

File diff suppressed because it is too large Load Diff

1298
po/nl.po

File diff suppressed because it is too large Load Diff

3028
po/or.po

File diff suppressed because it is too large Load Diff

1268
po/pa.po

File diff suppressed because it is too large Load Diff

1077
po/pl.po

File diff suppressed because it is too large Load Diff

1370
po/pt.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1944,33 +1944,6 @@ msgstr ""
"Expresiile pentru coordonate %d parsate în %g secunde (o medie de %g "
"secunde)\n"
#: ../src/50-mutter-launchers.xml.in.h:1
#, fuzzy
msgid "Launchers"
msgstr "Lansatori"
#: ../src/50-mutter-navigation.xml.in.h:1
#, fuzzy
msgid "Navigation"
msgstr "Navigare"
#: ../src/50-mutter-screenshot.xml.in.h:1
#, fuzzy
#| msgid "Take a screenshot"
msgid "Screenshots"
msgstr "Capturi de ecran"
#: ../src/50-mutter-system.xml.in.h:1
#, fuzzy
msgid "System"
msgstr "Sistem"
#: ../src/50-mutter-windows.xml.in.h:1
#, fuzzy
#| msgid "/_Windows"
msgid "Windows"
msgstr "Ferestre"
#~ msgid "Window Management"
#~ msgstr "Administrare ferestre"

1566
po/ru.po

File diff suppressed because it is too large Load Diff

1445
po/sl.po

File diff suppressed because it is too large Load Diff

3523
po/sr.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1324
po/sv.po

File diff suppressed because it is too large Load Diff

1379
po/ta.po

File diff suppressed because it is too large Load Diff

2732
po/te.po

File diff suppressed because it is too large Load Diff

2680
po/th.po

File diff suppressed because it is too large Load Diff

1241
po/tr.po

File diff suppressed because it is too large Load Diff

1658
po/ug.po

File diff suppressed because it is too large Load Diff

1355
po/uk.po

File diff suppressed because it is too large Load Diff

1736
po/vi.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,80 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<KeyListEntries schema="org.gnome.desktop.wm.keybindings"
group="system"
_name="Navigation"
wm_name="Mutter"
package="mutter">
<KeyListEntry name="move-to-workspace-1"
_description="Move window to workspace 1" />
<KeyListEntry name="move-to-workspace-2"
_description="Move window to workspace 2" />
<KeyListEntry name="move-to-workspace-3"
_description="Move window to workspace 3" />
<KeyListEntry name="move-to-workspace-4"
_description="Move window to workspace 4" />
<KeyListEntry name="move-to-workspace-left"
_description="Move window one workspace to the left" />
<KeyListEntry name="move-to-workspace-right"
_description="Move window one workspace to the right" />
<KeyListEntry name="move-to-workspace-up"
_description="Move window one workspace up" />
<KeyListEntry name="move-to-workspace-down"
_description="Move window one workspace down" />
<KeyListEntry name="switch-applications"
_description="Switch applications"/>
<KeyListEntry name="switch-windows"
_description="Switch windows"/>
<KeyListEntry name="switch-group"
_description="Switch windows of an application"/>
<KeyListEntry name="switch-panels"
_description="Switch system controls"/>
<KeyListEntry name="cycle-windows"
_description="Switch windows directly"/>
<KeyListEntry name="cycle-group"
_description="Switch windows of an app directly"/>
<KeyListEntry name="cycle-panels"
_description="Switch system controls directly"/>
<KeyListEntry name="show-desktop"
_description="Hide all normal windows"/>
<KeyListEntry name="switch-to-workspace-1"
_description="Switch to workspace 1" />
<KeyListEntry name="switch-to-workspace-2"
_description="Switch to workspace 2" />
<KeyListEntry name="switch-to-workspace-3"
_description="Switch to workspace 3" />
<KeyListEntry name="switch-to-workspace-4"
_description="Switch to workspace 4" />
<KeyListEntry name="switch-to-workspace-left"
_description="Move to workspace left" />
<KeyListEntry name="switch-to-workspace-right"
_description="Move to workspace right" />
<KeyListEntry name="switch-to-workspace-up"
_description="Move to workspace above" />
<KeyListEntry name="switch-to-workspace-down"
_description="Move to workspace below" />
</KeyListEntries>

View File

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<KeyListEntries schema="org.gnome.desktop.wm.keybindings"
group="system"
_name="System"
wm_name="Mutter"
package="mutter">
<KeyListEntry name="panel-run-dialog" _description="Show the run command prompt"/>
<KeyListEntry name="panel-main-menu" _description="Show the activities overview"/>
</KeyListEntries>

View File

@ -1,50 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<KeyListEntries schema="org.gnome.desktop.wm.keybindings"
group="system"
_name="Windows"
wm_name="Mutter"
package="mutter">
<KeyListEntry name="activate-window-menu" _description="Activate the window menu"/>
<KeyListEntry name="toggle-fullscreen" _description="Toggle fullscreen mode"/>
<KeyListEntry name="toggle-maximized" _description="Toggle maximization state"/>
<KeyListEntry name="maximize" _description="Maximize window"/>
<KeyListEntry name="unmaximize" _description="Restore window"/>
<KeyListEntry name="toggle-shaded" _description="Toggle shaded state"/>
<KeyListEntry name="close" _description="Close window"/>
<KeyListEntry name="minimize" _description="Hide window"/>
<KeyListEntry name="begin-move" _description="Move window"/>
<KeyListEntry name="begin-resize" _description="Resize window"/>
<KeyListEntry name="toggle-on-all-workspaces"
_description="Toggle window on all workspaces or one"/>
<KeyListEntry name="raise-or-lower" _description="Raise window if covered, otherwise lower it"/>
<KeyListEntry name="raise" _description="Raise window above other windows"/>
<KeyListEntry name="lower" _description="Lower window below other windows"/>
<KeyListEntry name="maximize-vertically" _description="Maximize window vertically"/>
<KeyListEntry name="maximize-horizontally" _description="Maximize window horizontally"/>
<KeyListEntry name="toggle-tiled-left"
schema="org.gnome.mutter.keybindings"
_description="View split on left"/>
<KeyListEntry name="toggle-tiled-right"
schema="org.gnome.mutter.keybindings"
_description="View split on right"/>
</KeyListEntries>

View File

@ -6,8 +6,6 @@ lib_LTLIBRARIES = libmutter.la
SUBDIRS=wm-tester tools compositor/plugins
INCLUDES= \
-DCLUTTER_ENABLE_EXPERIMENTAL_API \
-DCOGL_ENABLE_EXPERIMENTAL_API \
$(MUTTER_CFLAGS) \
-I$(srcdir) \
-I$(srcdir)/core \
@ -29,6 +27,8 @@ INCLUDES= \
-DGETTEXT_PACKAGE=\"$(GETTEXT_PACKAGE)\"
mutter_built_sources = \
mutter-marshal.h \
mutter-marshal.c \
mutter-enum-types.h \
mutter-enum-types.c
@ -45,7 +45,7 @@ libmutter_la_SOURCES = \
compositor/compositor.c \
compositor/compositor-private.h \
compositor/meta-background-actor.c \
compositor/meta-background-actor-private.h \
compositor/meta-background-actor.h \
compositor/meta-module.c \
compositor/meta-module.h \
compositor/meta-plugin.c \
@ -54,8 +54,7 @@ libmutter_la_SOURCES = \
compositor/meta-shadow-factory.c \
compositor/meta-shadow-factory-private.h \
compositor/meta-shaped-texture.c \
compositor/meta-texture-rectangle.c \
compositor/meta-texture-rectangle.h \
compositor/meta-shaped-texture.h \
compositor/meta-texture-tower.c \
compositor/meta-texture-tower.h \
compositor/meta-window-actor.c \
@ -67,7 +66,6 @@ libmutter_la_SOURCES = \
compositor/region-utils.c \
compositor/region-utils.h \
meta/compositor.h \
meta/meta-background-actor.h \
meta/meta-plugin.h \
meta/meta-shadow-factory.h \
meta/meta-window-actor.h \
@ -132,6 +130,8 @@ libmutter_la_SOURCES = \
core/core.h \
ui/ui.h \
inlinepixbufs.h \
ui/fixedtip.c \
ui/fixedtip.h \
ui/frames.c \
ui/frames.h \
ui/menu.c \
@ -149,6 +149,7 @@ libmutter_la_SOURCES = \
meta/theme.h \
ui/theme-private.h \
ui/ui.c \
core/all-keybindings.h \
meta/preview-widget.h \
ui/preview-widget.c \
$(mutter_built_sources)
@ -169,9 +170,7 @@ libmutterinclude_base_headers = \
meta/group.h \
meta/keybindings.h \
meta/main.h \
meta/meta-background-actor.h \
meta/meta-plugin.h \
meta/meta-shaped-texture.h \
meta/meta-shadow-factory.h \
meta/meta-window-actor.h \
meta/prefs.h \
@ -205,11 +204,7 @@ mutter_LDADD = $(MUTTER_LIBS) libmutter.la
if HAVE_INTROSPECTION
include $(INTROSPECTION_MAKEFILE)
# Since we don't make any guarantees about stability and we don't support
# parallel install, there's no real reason to change directories, filenames,
# etc. as we change the Mutter tarball version.
#api_version = $(MUTTER_MAJOR_VERSION).$(MUTTER_MINOR_VERSION)
api_version = 3.0
api_version = $(MUTTER_MAJOR_VERSION).$(MUTTER_MINOR_VERSION)
# These files are in package-private directories, even though they may be used
# by plugins. If you're writing a plugin, use g-ir-compiler --add-include-path
@ -223,8 +218,8 @@ typelib_DATA = Meta-$(api_version).typelib
INTROSPECTION_GIRS = Meta-$(api_version).gir
Meta-$(api_version).gir: libmutter.la
@META_GIR@_INCLUDES = GObject-2.0 GDesktopEnums-3.0 Gdk-3.0 Gtk-3.0 Clutter-1.0 xlib-2.0 xfixes-4.0 Cogl-1.0
@META_GIR@_EXPORT_PACKAGES = libmutter
@META_GIR@_INCLUDES = GObject-2.0 Gdk-3.0 Gtk-3.0 Clutter-1.0 xlib-2.0 xfixes-4.0
@META_GIR@_PACKAGES = clutter-1.0 gtk+-3.0
@META_GIR@_CFLAGS = $(INCLUDES)
@META_GIR@_LIBS = libmutter.la
@META_GIR@_FILES = \
@ -259,19 +254,20 @@ wmproperties_in_files=mutter-wm.desktop.in
wmproperties_files=$(wmproperties_in_files:.desktop.in=.desktop)
wmproperties_DATA = $(wmproperties_files)
xmldir = @GNOME_KEYBINDINGS_KEYSDIR@
xml_in_files = \
50-mutter-navigation.xml.in \
50-mutter-system.xml.in \
50-mutter-windows.xml.in
xml_DATA = $(xml_in_files:.xml.in=.xml)
schemadir = $(GCONF_SCHEMA_FILE_DIR)
schema_in_files = mutter.schemas.in
schema_DATA = $(schema_in_files:.schemas.in=.schemas)
gsettings_SCHEMAS = org.gnome.mutter.gschema.xml
@INTLTOOL_XML_NOMERGE_RULE@
@GSETTINGS_RULES@
convertdir = $(datadir)/GConf/gsettings
convert_DATA = mutter-schemas.convert
@INTLTOOL_SCHEMAS_RULE@
if GCONF_SCHEMAS_INSTALL
install-data-local:
GCONF_CONFIG_SOURCE=$(GCONF_SCHEMA_CONFIG_SOURCE) $(GCONFTOOL) --makefile-install-rule $(schema_DATA)
else
install-data-local:
endif
IMAGES=stock_maximize.png stock_minimize.png stock_delete.png
VARIABLES=stock_maximize_data $(srcdir)/stock_maximize.png \
@ -283,8 +279,7 @@ CLEANFILES = \
inlinepixbufs.h \
mutter.desktop \
mutter-wm.desktop \
org.gnome.mutter.gschema.xml \
$(xml_DATA) \
mutter.schemas \
$(mutter_built_sources) \
$(typelib_DATA) \
$(gir_DATA)
@ -301,24 +296,43 @@ EXTRA_DIST=$(desktopfiles_files) \
$(IMAGES) \
$(desktopfiles_in_files) \
$(wmproperties_in_files) \
$(xml_in_files) \
org.gnome.mutter.gschema.xml.in \
mutter-schemas.convert \
$(schema_in_files) \
libmutter.pc.in \
mutter-plugins.pc.in \
mutter-enum-types.h.in \
mutter-enum-types.c.in
mutter-enum-types.c.in \
mutter-marshal.list
BUILT_SOURCES += $(mutter_built_sources)
MUTTER_STAMP_FILES = stamp-mutter-enum-types.h
MUTTER_STAMP_FILES = stamp-mutter-marshal.h stamp-mutter-enum-types.h
CLEANFILES += $(MUTTER_STAMP_FILES)
mutter-marshal.h: stamp-mutter-marshal.h
@true
stamp-mutter-marshal.h: Makefile mutter-marshal.list
$(AM_V_GEN) $(GLIB_GENMARSHAL) \
--prefix=_mutter_marshal \
--header \
$(srcdir)/mutter-marshal.list > xgen-tmh && \
(cmp -s xgen-tmh mutter-marshal.h || cp -f xgen-tmh mutter-marshal.h) && \
rm -f xgen-tmh && \
echo timestamp > $(@F)
mutter-marshal.c: Makefile mutter-marshal.list
$(AM_V_GEN) (echo "#include \"mutter-marshal.h\"" ; \
$(GLIB_GENMARSHAL) \
--prefix=_mutter_marshal \
--body \
$(srcdir)/mutter-marshal.list ) > xgen-tmc && \
cp -f xgen-tmc mutter-marshal.c && \
rm -f xgen-tmc
mutter-enum-types.h: stamp-mutter-enum-types.h Makefile
@true
stamp-mutter-enum-types.h: $(libmutterinclude_base_headers) mutter-enum-types.h.in
$(AM_V_GEN) ( cd $(srcdir) && \
$(GLIB_MKENUMS) \
--template mutter-enum-types.h.in \
--template $(srcdir)/mutter-enum-types.h.in \
$(libmutterinclude_base_headers) ) >> xgen-teth && \
(cmp -s xgen-teth mutter-enum-types.h || cp xgen-teth mutter-enum-types.h) && \
rm -f xgen-teth && \
@ -327,7 +341,7 @@ stamp-mutter-enum-types.h: $(libmutterinclude_base_headers) mutter-enum-types.h.
mutter-enum-types.c: stamp-mutter-enum-types.h mutter-enum-types.c.in
$(AM_V_GEN) ( cd $(srcdir) && \
$(GLIB_MKENUMS) \
--template mutter-enum-types.c.in \
--template $(srcdir)/mutter-enum-types.c.in \
$(libmutterinclude_base_headers) ) >> xgen-tetc && \
cp xgen-tetc mutter-enum-types.c && \
rm -f xgen-tetc

View File

@ -29,10 +29,6 @@
* @green:
* @blue:
* @alpha:
* @flags: Optional flags for the texture, or %COGL_TEXTURE_NONE;
* %COGL_TEXTURE_NO_SLICING is useful if the texture will be
* repeated to create a constant color fill, since hardware
* repeat can't be used for a sliced texture.
*
* Creates a texture that is a single pixel with the specified
* unpremultiplied color components.
@ -40,11 +36,10 @@
* Return value: (transfer full): a newly created Cogl texture
*/
CoglHandle
meta_create_color_texture_4ub (guint8 red,
guint8 green,
guint8 blue,
guint8 alpha,
CoglTextureFlags flags)
meta_create_color_texture_4ub (guint8 red,
guint8 green,
guint8 blue,
guint8 alpha)
{
CoglColor color;
guint8 pixel[4];
@ -58,7 +53,7 @@ meta_create_color_texture_4ub (guint8 red,
pixel[3] = cogl_color_get_alpha_byte (&color);
return cogl_texture_new_from_data (1, 1,
flags,
COGL_TEXTURE_NONE,
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
COGL_PIXEL_FORMAT_ANY,
4, pixel);
@ -93,8 +88,7 @@ meta_create_texture_material (CoglHandle src_texture)
{
CoglHandle dummy_texture;
dummy_texture = meta_create_color_texture_4ub (0xff, 0xff, 0xff, 0xff,
COGL_TEXTURE_NONE);
dummy_texture = meta_create_color_texture_4ub (0xff, 0xff, 0xff, 0xff);
texture_material_template = cogl_material_new ();
cogl_material_set_layer (texture_material_template, 0, dummy_texture);

View File

@ -25,11 +25,10 @@
#include <cogl/cogl.h>
CoglHandle meta_create_color_texture_4ub (guint8 red,
guint8 green,
guint8 blue,
guint8 alpha,
CoglTextureFlags flags);
CoglHandle meta_create_color_texture_4ub (guint8 red,
guint8 green,
guint8 blue,
guint8 alpha);
CoglHandle meta_create_texture_material (CoglHandle src_texture);
#endif /* __META_COGL_UTILS_H__ */

View File

@ -8,7 +8,6 @@
#include <meta/compositor.h>
#include <meta/display.h>
#include "meta-plugin-manager.h"
#include "meta-window-actor-private.h"
#include <clutter/clutter.h>
typedef struct _MetaCompScreen MetaCompScreen;
@ -18,6 +17,7 @@ struct _MetaCompositor
MetaDisplay *display;
Atom atom_x_root_pixmap;
Atom atom_x_set_root;
Atom atom_net_wm_window_opacity;
guint repaint_func_id;
@ -25,13 +25,9 @@ struct _MetaCompositor
MetaPlugin *modal_plugin;
gint64 server_time_query_time;
gint64 server_time_offset;
guint server_time_is_monotonic_time : 1;
guint show_redraw : 1;
guint debug : 1;
guint no_mipmaps : 1;
gboolean show_redraw : 1;
gboolean debug : 1;
gboolean no_mipmaps : 1;
};
struct _MetaCompScreen
@ -45,13 +41,6 @@ struct _MetaCompScreen
GHashTable *windows_by_xid;
Window output;
CoglOnscreen *onscreen;
CoglFrameClosure *frame_closure;
/* Used for unredirecting fullscreen windows */
guint disable_unredirect_count;
MetaWindowActor *unredirected_window;
/* Before we create the output window */
XserverRegion pending_input_region;
@ -60,9 +49,10 @@ struct _MetaCompScreen
MetaPluginManager *plugin_mgr;
};
#define META_SYNC_DELAY 2
void meta_switch_workspace_completed (MetaScreen *screen);
void meta_set_stage_input_region (MetaScreen *screen,
XserverRegion region);
void meta_empty_stage_input_region (MetaScreen *screen);
gboolean meta_begin_modal_for_plugin (MetaScreen *screen,
MetaPlugin *plugin,
@ -74,9 +64,6 @@ void meta_end_modal_for_plugin (MetaScreen *screen,
MetaPlugin *plugin,
guint32 timestamp);
gint64 meta_compositor_monotonic_time_to_server_time (MetaDisplay *display,
gint64 monotonic_time);
void meta_check_end_modal (MetaScreen *screen);
#endif /* META_COMPOSITOR_PRIVATE_H */

View File

@ -11,11 +11,10 @@
#include <meta/compositor-mutter.h>
#include "xprops.h"
#include <meta/prefs.h>
#include <meta/main.h>
#include <meta/meta-shadow-factory.h>
#include "meta-window-actor-private.h"
#include "meta-window-group.h"
#include "meta-background-actor-private.h"
#include "meta-background-actor.h"
#include "window-private.h" /* to check window->hidden */
#include "display-private.h" /* for meta_display_lookup_x_window() */
#include <X11/extensions/shape.h>
@ -109,6 +108,28 @@ process_damage (MetaCompositor *compositor,
meta_window_actor_process_damage (window_actor, event);
}
#ifdef HAVE_SHAPE
static void
process_shape (MetaCompositor *compositor,
XShapeEvent *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;
if (event->kind == ShapeBounding)
{
meta_window_actor_update_shape (window_actor, event->shaped);
}
}
#endif
static void
process_property_notify (MetaCompositor *compositor,
XPropertyEvent *event,
@ -125,7 +146,8 @@ process_property_notify (MetaCompositor *compositor,
MetaScreen *screen = l->data;
if (event->window == meta_screen_get_xroot (screen))
{
meta_background_actor_update (screen);
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
meta_background_actor_update (META_BACKGROUND_ACTOR (info->background_actor));
return;
}
}
@ -157,26 +179,23 @@ get_output_window (MetaScreen *screen)
Window output, xroot;
XWindowAttributes attr;
long event_mask;
unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };
xroot = meta_screen_get_xroot (screen);
event_mask = FocusChangeMask |
ExposureMask |
EnterWindowMask | LeaveWindowMask |
PointerMotionMask |
PropertyChangeMask |
ButtonPressMask | ButtonReleaseMask |
KeyPressMask | KeyReleaseMask;
output = XCompositeGetOverlayWindow (xdisplay, xroot);
XISetMask (mask.mask, XI_KeyPress);
XISetMask (mask.mask, XI_KeyRelease);
XISetMask (mask.mask, XI_ButtonPress);
XISetMask (mask.mask, XI_ButtonRelease);
XISetMask (mask.mask, XI_Enter);
XISetMask (mask.mask, XI_Leave);
XISetMask (mask.mask, XI_FocusIn);
XISetMask (mask.mask, XI_FocusOut);
XISetMask (mask.mask, XI_Motion);
XISelectEvents (xdisplay, output, &mask, 1);
event_mask = ExposureMask | PropertyChangeMask;
if (XGetWindowAttributes (xdisplay, output, &attr))
event_mask |= attr.your_event_mask;
{
event_mask |= attr.your_event_mask;
}
XSelectInput (xdisplay, output, event_mask);
@ -282,12 +301,6 @@ do_set_stage_input_region (MetaScreen *screen,
Window xstage = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage));
XFixesSetWindowShapeRegion (xdpy, xstage, ShapeInput, 0, 0, region);
/* It's generally a good heuristic that when a crossing event is generated because
* we reshape the overlay, we don't want it to affect focus-follows-mouse focus -
* it's not the user doing something, it's the environment changing under the user.
*/
meta_display_add_ignored_crossing_serial (display, XNextRequest (xdpy));
XFixesSetWindowShapeRegion (xdpy, info->output, ShapeInput, 0, 0, region);
}
@ -361,23 +374,14 @@ meta_begin_modal_for_plugin (MetaScreen *screen,
if ((options & META_MODAL_POINTER_ALREADY_GRABBED) == 0)
{
unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };
XISetMask (mask.mask, XI_ButtonPress);
XISetMask (mask.mask, XI_ButtonRelease);
XISetMask (mask.mask, XI_Enter);
XISetMask (mask.mask, XI_Leave);
XISetMask (mask.mask, XI_Motion);
result = XIGrabDevice (xdpy,
META_VIRTUAL_CORE_POINTER_ID,
grab_window,
timestamp,
cursor,
XIGrabModeAsync, XIGrabModeAsync,
result = XGrabPointer (xdpy, grab_window,
False, /* owner_events */
&mask);
(ButtonPressMask | ButtonReleaseMask |
EnterWindowMask | LeaveWindowMask | PointerMotionMask),
GrabModeAsync, GrabModeAsync,
None, /* confine to */
cursor,
timestamp);
if (result != Success)
goto fail;
@ -386,20 +390,10 @@ meta_begin_modal_for_plugin (MetaScreen *screen,
if ((options & META_MODAL_KEYBOARD_ALREADY_GRABBED) == 0)
{
unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };
XISetMask (mask.mask, XI_KeyPress);
XISetMask (mask.mask, XI_KeyRelease);
result = XIGrabDevice (xdpy,
META_VIRTUAL_CORE_KEYBOARD_ID,
grab_window,
timestamp,
None,
XIGrabModeAsync, XIGrabModeAsync,
False, /* owner_events */
&mask);
result = XGrabKeyboard (xdpy, grab_window,
False, /* owner_events */
GrabModeAsync, GrabModeAsync,
timestamp);
if (result != Success)
goto fail;
@ -419,9 +413,9 @@ meta_begin_modal_for_plugin (MetaScreen *screen,
fail:
if (pointer_grabbed)
XIUngrabDevice (xdpy, META_VIRTUAL_CORE_POINTER_ID, timestamp);
XUngrabPointer (xdpy, timestamp);
if (keyboard_grabbed)
XIUngrabDevice (xdpy, META_VIRTUAL_CORE_KEYBOARD_ID, timestamp);
XUngrabKeyboard (xdpy, timestamp);
return FALSE;
}
@ -437,8 +431,8 @@ meta_end_modal_for_plugin (MetaScreen *screen,
g_return_if_fail (compositor->modal_plugin == plugin);
XIUngrabDevice (xdpy, META_VIRTUAL_CORE_POINTER_ID, timestamp);
XIUngrabDevice (xdpy, META_VIRTUAL_CORE_KEYBOARD_ID, timestamp);
XUngrabPointer (xdpy, timestamp);
XUngrabKeyboard (xdpy, timestamp);
display->grab_op = META_GRAB_OP_NONE;
display->grab_window = NULL;
@ -467,16 +461,6 @@ meta_check_end_modal (MetaScreen *screen)
}
}
static void
after_stage_paint (ClutterActor *stage,
MetaCompScreen *info)
{
GList *l;
for (l = info->windows; l; l = l->next)
meta_window_actor_post_paint (l->data);
}
void
meta_compositor_manage_screen (MetaCompositor *compositor,
MetaScreen *screen)
@ -488,43 +472,22 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
Window xroot = meta_screen_get_xroot (screen);
Window xwin;
gint width, height;
guint n_retries;
guint max_retries;
XWindowAttributes attr;
long event_mask;
/* Check if the screen is already managed */
if (meta_screen_get_compositor_data (screen))
return;
if (meta_get_replace_current_wm ())
max_retries = 5;
else
max_retries = 1;
meta_error_trap_push_with_return (display);
XCompositeRedirectSubwindows (xdisplay, xroot, CompositeRedirectManual);
XSync (xdisplay, FALSE);
n_retries = 0;
/* Some compositors (like old versions of Mutter) might not properly unredirect
* subwindows before destroying the WM selection window; so we wait a while
* for such a compositor to exit before giving up.
*/
while (TRUE)
if (meta_error_trap_pop_with_return (display))
{
meta_error_trap_push_with_return (display);
XCompositeRedirectSubwindows (xdisplay, xroot, CompositeRedirectManual);
XSync (xdisplay, FALSE);
if (!meta_error_trap_pop_with_return (display))
break;
if (n_retries == max_retries)
{
/* This probably means that a non-WM compositor like xcompmgr is running;
* we have no way to get it to exit */
meta_fatal (_("Another compositing manager is already running on screen %i on display \"%s\"."),
screen_number, display->name);
}
n_retries++;
g_usleep (G_USEC_PER_SEC);
g_warning ("Another compositing manager is running on screen %i",
screen_number);
return;
}
info = g_new0 (MetaCompScreen, 1);
@ -545,46 +508,31 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
meta_screen_set_cm_selection (screen);
info->stage = clutter_stage_new ();
g_signal_connect_after (info->stage, "paint",
G_CALLBACK (after_stage_paint), info);
/* Wait 6-ms after vblank before starting to draw next frame */
clutter_stage_set_sync_delay (CLUTTER_STAGE (info->stage), META_SYNC_DELAY);
info->stage = clutter_stage_get_default ();
meta_screen_get_size (screen, &width, &height);
clutter_actor_realize (info->stage);
clutter_actor_set_size (info->stage, width, height);
xwin = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage));
XResizeWindow (xdisplay, xwin, width, height);
event_mask = FocusChangeMask |
ExposureMask |
EnterWindowMask | LeaveWindowMask |
PointerMotionMask |
PropertyChangeMask |
ButtonPressMask | ButtonReleaseMask |
KeyPressMask | KeyReleaseMask |
StructureNotifyMask;
{
long event_mask;
unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };
XWindowAttributes attr;
if (XGetWindowAttributes (xdisplay, xwin, &attr))
{
event_mask |= attr.your_event_mask;
}
XISetMask (mask.mask, XI_KeyPress);
XISetMask (mask.mask, XI_KeyRelease);
XISetMask (mask.mask, XI_ButtonPress);
XISetMask (mask.mask, XI_ButtonRelease);
XISetMask (mask.mask, XI_Enter);
XISetMask (mask.mask, XI_Leave);
XISetMask (mask.mask, XI_FocusIn);
XISetMask (mask.mask, XI_FocusOut);
XISetMask (mask.mask, XI_Motion);
XISelectEvents (xdisplay, xwin, &mask, 1);
event_mask = ExposureMask | PropertyChangeMask | StructureNotifyMask;
if (XGetWindowAttributes (xdisplay, xwin, &attr))
event_mask |= attr.your_event_mask;
XSelectInput (xdisplay, xwin, event_mask);
}
XSelectInput (xdisplay, xwin, event_mask);
info->window_group = meta_window_group_new (screen);
info->background_actor = meta_background_actor_new_for_screen (screen);
info->background_actor = meta_background_actor_new (screen);
info->overlay_group = clutter_group_new ();
info->hidden_group = clutter_group_new ();
@ -600,7 +548,9 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
clutter_actor_hide (info->hidden_group);
info->plugin_mgr = meta_plugin_manager_new (screen);
info->plugin_mgr =
meta_plugin_manager_get (screen);
meta_plugin_manager_initialize (info->plugin_mgr);
/*
* Delay the creation of the overlay window as long as we can, to avoid
@ -637,55 +587,6 @@ void
meta_compositor_unmanage_screen (MetaCompositor *compositor,
MetaScreen *screen)
{
MetaDisplay *display = meta_screen_get_display (screen);
Display *xdisplay = meta_display_get_xdisplay (display);
Window xroot = meta_screen_get_xroot (screen);
/* This is the most important part of cleanup - we have to do this
* before giving up the window manager selection or the next
* window manager won't be able to redirect subwindows */
XCompositeUnredirectSubwindows (xdisplay, xroot, CompositeRedirectManual);
}
/*
* Shapes the cow so that the given window is exposed,
* when metaWindow is NULL it clears the shape again
*/
static void
meta_shape_cow_for_window (MetaScreen *screen,
MetaWindow *metaWindow)
{
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
Display *xdisplay = meta_display_get_xdisplay (meta_screen_get_display (screen));
if (metaWindow == NULL)
XFixesSetWindowShapeRegion (xdisplay, info->output, ShapeBounding, 0, 0, None);
else
{
XserverRegion output_region;
XRectangle screen_rect, window_bounds;
int width, height;
MetaRectangle rect;
meta_window_get_outer_rect (metaWindow, &rect);
window_bounds.x = rect.x;
window_bounds.y = rect.y;
window_bounds.width = rect.width;
window_bounds.height = rect.height;
meta_screen_get_size (screen, &width, &height);
screen_rect.x = 0;
screen_rect.y = 0;
screen_rect.width = width;
screen_rect.height = height;
output_region = XFixesCreateRegion (xdisplay, &window_bounds, 1);
XFixesInvertRegion (xdisplay, output_region, &screen_rect, output_region);
XFixesSetWindowShapeRegion (xdisplay, info->output, ShapeBounding, 0, 0, output_region);
XFixesDestroyRegion (xdisplay, output_region);
}
}
void
@ -708,75 +609,39 @@ meta_compositor_remove_window (MetaCompositor *compositor,
MetaWindow *window)
{
MetaWindowActor *window_actor = NULL;
MetaScreen *screen;
MetaCompScreen *info;
DEBUG_TRACE ("meta_compositor_remove_window\n");
window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
if (!window_actor)
return;
screen = meta_window_get_screen (window);
info = meta_screen_get_compositor_data (screen);
if (window_actor == info->unredirected_window)
{
meta_window_actor_set_redirected (window_actor, TRUE);
meta_shape_cow_for_window (meta_window_get_screen (meta_window_actor_get_meta_window (info->unredirected_window)),
NULL);
info->unredirected_window = NULL;
}
meta_window_actor_destroy (window_actor);
}
void
meta_compositor_set_updates_frozen (MetaCompositor *compositor,
MetaWindow *window,
gboolean updates_frozen)
meta_compositor_set_updates (MetaCompositor *compositor,
MetaWindow *window,
gboolean updates)
{
MetaWindowActor *window_actor;
DEBUG_TRACE ("meta_compositor_set_updates_frozen\n");
window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
if (!window_actor)
return;
meta_window_actor_set_updates_frozen (window_actor, updates_frozen);
}
static gboolean
is_grabbed_event (MetaDisplay *display,
XEvent *event)
is_grabbed_event (XEvent *event)
{
if (event->type == GenericEvent &&
event->xcookie.extension == display->xinput_opcode)
switch (event->xany.type)
{
XIEvent *xev = (XIEvent *) event->xcookie.data;
switch (xev->evtype)
{
case XI_Motion:
case XI_ButtonPress:
case XI_ButtonRelease:
case XI_KeyPress:
case XI_KeyRelease:
return TRUE;
}
case ButtonPress:
case ButtonRelease:
case EnterNotify:
case LeaveNotify:
case MotionNotify:
case KeyPress:
case KeyRelease:
return TRUE;
}
return FALSE;
}
void
meta_compositor_window_shape_changed (MetaCompositor *compositor,
MetaWindow *window)
{
MetaWindowActor *window_actor;
window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
meta_window_actor_update_shape (window_actor);
}
/**
* meta_compositor_process_event: (skip)
*
@ -786,7 +651,7 @@ meta_compositor_process_event (MetaCompositor *compositor,
XEvent *event,
MetaWindow *window)
{
if (compositor->modal_plugin && is_grabbed_event (compositor->display, event))
if (compositor->modal_plugin && is_grabbed_event (event))
{
MetaPluginClass *klass = META_PLUGIN_GET_CLASS (compositor->modal_plugin);
@ -856,6 +721,13 @@ meta_compositor_process_event (MetaCompositor *compositor,
DEBUG_TRACE ("meta_compositor_process_event (process_damage)\n");
process_damage (compositor, (XDamageNotifyEvent *) event, window);
}
#ifdef HAVE_SHAPE
else if (event->type == meta_display_get_shape_event_base (compositor->display) + ShapeNotify)
{
DEBUG_TRACE ("meta_compositor_process_event (process_shape)\n");
process_shape (compositor, (XShapeEvent *) event, window);
}
#endif /* HAVE_SHAPE */
break;
}
@ -871,19 +743,6 @@ meta_compositor_process_event (MetaCompositor *compositor,
return FALSE;
}
gboolean
meta_compositor_filter_keybinding (MetaCompositor *compositor,
MetaScreen *screen,
MetaKeyBinding *binding)
{
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
if (info->plugin_mgr)
return meta_plugin_manager_filter_keybinding (info->plugin_mgr, binding);
return FALSE;
}
void
meta_compositor_show_window (MetaCompositor *compositor,
MetaWindow *window,
@ -938,6 +797,29 @@ meta_compositor_unmaximize_window (MetaCompositor *compositor,
meta_window_actor_unmaximize (window_actor, old_rect, new_rect);
}
void
meta_compositor_update_workspace_geometry (MetaCompositor *compositor,
MetaWorkspace *workspace)
{
#if 0
/* FIXME -- should do away with this function in favour of MetaWorkspace
* signal.
*/
MetaScreen *screen = meta_workspace_get_screen (workspace);
MetaCompScreen *info;
MetaPluginManager *mgr;
DEBUG_TRACE ("meta_compositor_update_workspace_geometry\n");
info = meta_screen_get_compositor_data (screen);
mgr = info->plugin_mgr;
if (!mgr || !workspace)
return;
meta_plugin_manager_update_workspace (mgr, workspace);
#endif
}
void
meta_compositor_switch_workspace (MetaCompositor *compositor,
MetaScreen *screen,
@ -1185,102 +1067,24 @@ meta_compositor_sync_screen_size (MetaCompositor *compositor,
guint width,
guint height)
{
MetaDisplay *display = meta_screen_get_display (screen);
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
Display *xdisplay;
Window xwin;
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
DEBUG_TRACE ("meta_compositor_sync_screen_size\n");
g_return_if_fail (info);
xdisplay = meta_display_get_xdisplay (display);
xwin = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage));
clutter_actor_set_size (info->stage, width, height);
XResizeWindow (xdisplay, xwin, width, height);
meta_background_actor_screen_size_changed (screen);
meta_background_actor_screen_size_changed (META_BACKGROUND_ACTOR (info->background_actor));
meta_verbose ("Changed size for stage on screen %d to %dx%d\n",
meta_screen_get_screen_number (screen),
width, height);
}
static void
frame_callback (CoglOnscreen *onscreen,
CoglFrameEvent event,
CoglFrameInfo *frame_info,
void *user_data)
{
MetaCompScreen *info = user_data;
GList *l;
if (event == COGL_FRAME_EVENT_COMPLETE)
{
gint64 presentation_time_cogl = cogl_frame_info_get_presentation_time (frame_info);
gint64 presentation_time;
if (presentation_time_cogl != 0)
{
CoglContext *context = cogl_framebuffer_get_context (COGL_FRAMEBUFFER (onscreen));
gint64 current_time_cogl = cogl_get_clock_time (context);
gint64 now = g_get_monotonic_time ();
presentation_time =
now + (presentation_time_cogl - current_time_cogl) / 1000;
}
else
{
presentation_time = 0;
}
for (l = info->windows; l; l = l->next)
meta_window_actor_frame_complete (l->data, frame_info, presentation_time);
}
}
static void
pre_paint_windows (MetaCompScreen *info)
{
GList *l;
MetaWindowActor *top_window;
MetaWindowActor *expected_unredirected_window = NULL;
if (info->onscreen == NULL)
{
info->onscreen = COGL_ONSCREEN (cogl_get_draw_framebuffer ());
info->frame_closure = cogl_onscreen_add_frame_callback (info->onscreen,
frame_callback,
info,
NULL);
}
if (info->windows == NULL)
return;
top_window = g_list_last (info->windows)->data;
if (meta_window_actor_should_unredirect (top_window) &&
info->disable_unredirect_count == 0)
expected_unredirected_window = top_window;
if (info->unredirected_window != expected_unredirected_window)
{
if (info->unredirected_window != NULL)
{
meta_window_actor_set_redirected (info->unredirected_window, TRUE);
meta_shape_cow_for_window (meta_window_get_screen (meta_window_actor_get_meta_window (info->unredirected_window)),
NULL);
}
if (expected_unredirected_window != NULL)
{
meta_shape_cow_for_window (meta_window_get_screen (meta_window_actor_get_meta_window (top_window)),
meta_window_actor_get_meta_window (top_window));
meta_window_actor_set_redirected (top_window, FALSE);
}
info->unredirected_window = expected_unredirected_window;
}
for (l = info->windows; l; l = l->next)
meta_window_actor_pre_paint (l->data);
@ -1335,6 +1139,7 @@ meta_compositor_new (MetaDisplay *display)
{
char *atom_names[] = {
"_XROOTPMAP_ID",
"_XSETROOT_ID",
"_NET_WM_WINDOW_OPACITY",
};
Atom atoms[G_N_ELEMENTS(atom_names)];
@ -1361,7 +1166,8 @@ meta_compositor_new (MetaDisplay *display)
compositor);
compositor->atom_x_root_pixmap = atoms[0];
compositor->atom_net_wm_window_opacity = atoms[1];
compositor->atom_x_set_root = atoms[1];
compositor->atom_net_wm_window_opacity = atoms[2];
compositor->repaint_func_id = clutter_threads_add_repaint_func (meta_repaint_func,
compositor,
@ -1382,37 +1188,6 @@ meta_get_overlay_window (MetaScreen *screen)
return info->output;
}
/**
* meta_disable_unredirect_for_screen:
* @screen: a #MetaScreen
*
* Disables unredirection, can be usefull in situations where having
* unredirected windows is undesireable like when recording a video.
*
*/
void
meta_disable_unredirect_for_screen (MetaScreen *screen)
{
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
if (info != NULL)
info->disable_unredirect_count = info->disable_unredirect_count + 1;
}
/**
* meta_enable_unredirect_for_screen:
* @screen: a #MetaScreen
*
* Enables unredirection which reduces the overhead for apps like games.
*
*/
void
meta_enable_unredirect_for_screen (MetaScreen *screen)
{
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
if (info != NULL)
info->disable_unredirect_count = MAX(0, info->disable_unredirect_count - 1);
}
#define FLASH_TIME_MS 50
static void
@ -1456,51 +1231,3 @@ meta_compositor_flash_screen (MetaCompositor *compositor,
"signal-after::completed", flash_in_completed, flash,
NULL);
}
/**
* meta_compositor_monotonic_time_to_server_time:
* @display: a #MetaDisplay
* @monotonic_time: time in the units of g_get_monotonic_time()
*
* _NET_WM_FRAME_DRAWN and _NET_WM_FRAME_TIMINGS messages represent time
* as a "high resolution server time" - this is the server time interpolated
* to microsecond resolution. The advantage of this time representation
* is that if X server is running on the same computer as a client, and
* the Xserver uses 'clock_gettime(CLOCK_MONOTONIC, ...)' for the server
* time, the client can detect this, and all such clients will share a
* a time representation with high accuracy. If there is not a common
* time source, then the time synchronization will be less accurate.
*/
gint64
meta_compositor_monotonic_time_to_server_time (MetaDisplay *display,
gint64 monotonic_time)
{
MetaCompositor *compositor = display->compositor;
if (compositor->server_time_query_time == 0 ||
(!compositor->server_time_is_monotonic_time &&
monotonic_time > compositor->server_time_query_time + 10000000)) /* 10 seconds */
{
guint32 server_time = meta_display_get_current_time_roundtrip (display);
gint64 server_time_usec = (gint64)server_time * 1000;
gint64 current_monotonic_time = g_get_monotonic_time ();
compositor->server_time_query_time = current_monotonic_time;
/* If the server time is within a second of the monotonic time,
* we assume that they are identical. This seems like a big margin,
* but we want to be as robust as possible even if the system
* is under load and our processing of the server response is
* delayed.
*/
if (server_time_usec > current_monotonic_time - 1000000 &&
server_time_usec < current_monotonic_time + 1000000)
compositor->server_time_is_monotonic_time = TRUE;
compositor->server_time_offset = server_time_usec - current_monotonic_time;
}
if (compositor->server_time_is_monotonic_time)
return monotonic_time;
else
return monotonic_time + compositor->server_time_offset;
}

View File

@ -1,15 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
#ifndef META_BACKGROUND_ACTOR_PRIVATE_H
#define META_BACKGROUND_ACTOR_PRIVATE_H
#include <meta/screen.h>
#include <meta/meta-background-actor.h>
void meta_background_actor_set_visible_region (MetaBackgroundActor *self,
cairo_region_t *visible_region);
void meta_background_actor_update (MetaScreen *screen);
void meta_background_actor_screen_size_changed (MetaScreen *screen);
#endif /* META_BACKGROUND_ACTOR_PRIVATE_H */

View File

@ -25,191 +25,80 @@
#include <config.h>
#define COGL_ENABLE_EXPERIMENTAL_API
#include <cogl/cogl-texture-pixmap-x11.h>
#include <clutter/clutter.h>
#include <X11/Xatom.h>
#include "cogl-utils.h"
#include "compositor-private.h"
#include <meta/errors.h>
#include "meta-background-actor-private.h"
#include "meta-background-actor.h"
/* We allow creating multiple MetaBackgroundActors for the same MetaScreen to
* allow different rendering options to be set for different copies.
* But we want to share the same underlying CoglTexture for efficiency and
* to avoid driver bugs that might occur if we created multiple CoglTexturePixmaps
* for the same pixmap.
*
* This structure holds common information.
*/
typedef struct _MetaScreenBackground MetaScreenBackground;
struct _MetaScreenBackground
struct _MetaBackgroundActorClass
{
MetaScreen *screen;
GSList *actors;
ClutterActorClass parent_class;
};
struct _MetaBackgroundActor
{
ClutterActor parent;
CoglHandle material;
MetaScreen *screen;
cairo_region_t *visible_region;
float texture_width;
float texture_height;
CoglTexture *texture;
CoglMaterialWrapMode wrap_mode;
guint have_pixmap : 1;
};
struct _MetaBackgroundActorPrivate
{
MetaScreenBackground *background;
CoglPipeline *pipeline;
cairo_region_t *visible_region;
float dim_factor;
};
enum
{
PROP_0,
PROP_DIM_FACTOR,
PROP_LAST
};
static GParamSpec *obj_props[PROP_LAST];
G_DEFINE_TYPE (MetaBackgroundActor, meta_background_actor, CLUTTER_TYPE_ACTOR);
static void set_texture (MetaScreenBackground *background,
CoglHandle texture);
static void set_texture_to_stage_color (MetaScreenBackground *background);
static void
on_notify_stage_color (GObject *stage,
GParamSpec *pspec,
MetaScreenBackground *background)
update_wrap_mode (MetaBackgroundActor *self)
{
if (!background->have_pixmap)
set_texture_to_stage_color (background);
}
static void
free_screen_background (MetaScreenBackground *background)
{
set_texture (background, COGL_INVALID_HANDLE);
if (background->screen != NULL)
{
ClutterActor *stage = meta_get_stage_for_screen (background->screen);
g_signal_handlers_disconnect_by_func (stage,
(gpointer) on_notify_stage_color,
background);
background->screen = NULL;
}
}
static MetaScreenBackground *
meta_screen_background_get (MetaScreen *screen)
{
MetaScreenBackground *background;
background = g_object_get_data (G_OBJECT (screen), "meta-screen-background");
if (background == NULL)
{
ClutterActor *stage;
background = g_new0 (MetaScreenBackground, 1);
background->screen = screen;
g_object_set_data_full (G_OBJECT (screen), "meta-screen-background",
background, (GDestroyNotify) free_screen_background);
stage = meta_get_stage_for_screen (screen);
g_signal_connect (stage, "notify::color",
G_CALLBACK (on_notify_stage_color), background);
meta_background_actor_update (screen);
}
return background;
}
static void
update_wrap_mode_of_actor (MetaBackgroundActor *self)
{
MetaBackgroundActorPrivate *priv = self->priv;
cogl_pipeline_set_layer_wrap_mode (priv->pipeline, 0, priv->background->wrap_mode);
}
static void
update_wrap_mode (MetaScreenBackground *background)
{
GSList *l;
int width, height;
CoglMaterialWrapMode wrap_mode;
meta_screen_get_size (background->screen, &width, &height);
meta_screen_get_size (self->screen, &width, &height);
/* We turn off repeating when we have a full-screen pixmap to keep from
* getting artifacts from one side of the image sneaking into the other
* side of the image via bilinear filtering.
*/
if (width == background->texture_width && height == background->texture_height)
background->wrap_mode = COGL_MATERIAL_WRAP_MODE_CLAMP_TO_EDGE;
if (width == self->texture_width && height == self->texture_height)
wrap_mode = COGL_MATERIAL_WRAP_MODE_CLAMP_TO_EDGE;
else
background->wrap_mode = COGL_MATERIAL_WRAP_MODE_REPEAT;
wrap_mode = COGL_MATERIAL_WRAP_MODE_REPEAT;
for (l = background->actors; l; l = l->next)
update_wrap_mode_of_actor (l->data);
cogl_material_set_layer_wrap_mode (self->material, 0, wrap_mode);
}
static void
set_texture_on_actor (MetaBackgroundActor *self)
set_texture (MetaBackgroundActor *self,
CoglHandle texture)
{
MetaBackgroundActorPrivate *priv = self->priv;
MetaDisplay *display = meta_screen_get_display (priv->background->screen);
MetaDisplay *display;
display = meta_screen_get_display (self->screen);
/* This may trigger destruction of an old texture pixmap, which, if
* the underlying X pixmap is already gone has the tendency to trigger
* X errors inside DRI. For safety, trap errors */
meta_error_trap_push (display);
cogl_pipeline_set_layer_texture (priv->pipeline, 0, priv->background->texture);
cogl_material_set_layer (self->material, 0, texture);
meta_error_trap_pop (display);
self->texture_width = cogl_texture_get_width (texture);
self->texture_height = cogl_texture_get_height (texture);
update_wrap_mode (self);
clutter_actor_queue_redraw (CLUTTER_ACTOR (self));
}
static void
set_texture (MetaScreenBackground *background,
CoglHandle texture)
{
MetaDisplay *display = meta_screen_get_display (background->screen);
GSList *l;
/* This may trigger destruction of an old texture pixmap, which, if
* the underlying X pixmap is already gone has the tendency to trigger
* X errors inside DRI. For safety, trap errors */
meta_error_trap_push (display);
if (background->texture != COGL_INVALID_HANDLE)
{
cogl_handle_unref (background->texture);
background->texture = COGL_INVALID_HANDLE;
}
meta_error_trap_pop (display);
if (texture != COGL_INVALID_HANDLE)
background->texture = cogl_handle_ref (texture);
background->texture_width = cogl_texture_get_width (background->texture);
background->texture_height = cogl_texture_get_height (background->texture);
for (l = background->actors; l; l = l->next)
set_texture_on_actor (l->data);
update_wrap_mode (background);
}
/* Sets our pipeline to paint with a 1x1 texture of the stage's background
/* Sets our material to paint with a 1x1 texture of the stage's background
* color; doing this when we have no pixmap allows the application to turn
* off painting the stage. There might be a performance benefit to
* painting in this case with a solid color, but the normal solid color
@ -217,41 +106,49 @@ set_texture (MetaScreenBackground *background,
* actually pick up the (small?) performance win. This is just a fallback.
*/
static void
set_texture_to_stage_color (MetaScreenBackground *background)
set_texture_to_stage_color (MetaBackgroundActor *self)
{
ClutterActor *stage = meta_get_stage_for_screen (background->screen);
ClutterActor *stage = meta_get_stage_for_screen (self->screen);
ClutterColor color;
CoglHandle texture;
clutter_stage_get_color (CLUTTER_STAGE (stage), &color);
/* Slicing will prevent COGL from using hardware texturing for
* the tiled 1x1 pixmap, and will cause it to draw the window
* background in millions of separate 1x1 rectangles */
texture = meta_create_color_texture_4ub (color.red, color.green,
color.blue, 0xff,
COGL_TEXTURE_NO_SLICING);
set_texture (background, texture);
color.blue, 0xff);
set_texture (self, texture);
cogl_handle_unref (texture);
}
static void
on_notify_stage_color (GObject *stage,
GParamSpec *pspec,
MetaBackgroundActor *self)
{
if (!self->have_pixmap)
set_texture_to_stage_color (self);
}
static void
meta_background_actor_dispose (GObject *object)
{
MetaBackgroundActor *self = META_BACKGROUND_ACTOR (object);
MetaBackgroundActorPrivate *priv = self->priv;
meta_background_actor_set_visible_region (self, NULL);
if (priv->background != NULL)
if (self->material != COGL_INVALID_HANDLE)
{
priv->background->actors = g_slist_remove (priv->background->actors, self);
priv->background = NULL;
cogl_handle_unref (self->material);
self->material = COGL_INVALID_HANDLE;
}
g_clear_pointer(&priv->pipeline, cogl_object_unref);
G_OBJECT_CLASS (meta_background_actor_parent_class)->dispose (object);
if (self->screen != NULL)
{
ClutterActor *stage = meta_get_stage_for_screen (self->screen);
g_signal_handlers_disconnect_by_func (stage,
(gpointer) on_notify_stage_color,
self);
self->screen = NULL;
}
}
static void
@ -261,15 +158,14 @@ meta_background_actor_get_preferred_width (ClutterActor *actor,
gfloat *natural_width_p)
{
MetaBackgroundActor *self = META_BACKGROUND_ACTOR (actor);
MetaBackgroundActorPrivate *priv = self->priv;
int width, height;
meta_screen_get_size (priv->background->screen, &width, &height);
meta_screen_get_size (self->screen, &width, &height);
if (min_width_p)
*min_width_p = width;
if (natural_width_p)
*natural_width_p = width;
*natural_width_p = height;
}
static void
@ -280,10 +176,9 @@ meta_background_actor_get_preferred_height (ClutterActor *actor,
{
MetaBackgroundActor *self = META_BACKGROUND_ACTOR (actor);
MetaBackgroundActorPrivate *priv = self->priv;
int width, height;
meta_screen_get_size (priv->background->screen, &width, &height);
meta_screen_get_size (self->screen, &width, &height);
if (min_height_p)
*min_height_p = height;
@ -295,39 +190,32 @@ static void
meta_background_actor_paint (ClutterActor *actor)
{
MetaBackgroundActor *self = META_BACKGROUND_ACTOR (actor);
MetaBackgroundActorPrivate *priv = self->priv;
guint8 opacity = clutter_actor_get_paint_opacity (actor);
guint8 color_component;
guchar opacity = clutter_actor_get_paint_opacity (actor);
int width, height;
meta_screen_get_size (priv->background->screen, &width, &height);
meta_screen_get_size (self->screen, &width, &height);
color_component = (int)(0.5 + opacity * priv->dim_factor);
cogl_material_set_color4ub (self->material,
opacity, opacity, opacity, opacity);
cogl_pipeline_set_color4ub (priv->pipeline,
color_component,
color_component,
color_component,
opacity);
cogl_set_source (self->material);
cogl_set_source (priv->pipeline);
if (priv->visible_region)
if (self->visible_region)
{
int n_rectangles = cairo_region_num_rectangles (priv->visible_region);
int n_rectangles = cairo_region_num_rectangles (self->visible_region);
int i;
for (i = 0; i < n_rectangles; i++)
{
cairo_rectangle_int_t rect;
cairo_region_get_rectangle (priv->visible_region, i, &rect);
cairo_region_get_rectangle (self->visible_region, i, &rect);
cogl_rectangle_with_texture_coords (rect.x, rect.y,
rect.x + rect.width, rect.y + rect.height,
rect.x / priv->background->texture_width,
rect.y / priv->background->texture_height,
(rect.x + rect.width) / priv->background->texture_width,
(rect.y + rect.height) / priv->background->texture_height);
rect.x / self->texture_width,
rect.y / self->texture_height,
(rect.x + rect.width) / self->texture_width,
(rect.y + rect.height) / self->texture_height);
}
}
else
@ -335,161 +223,85 @@ meta_background_actor_paint (ClutterActor *actor)
cogl_rectangle_with_texture_coords (0.0f, 0.0f,
width, height,
0.0f, 0.0f,
width / priv->background->texture_width,
height / priv->background->texture_height);
width / self->texture_width,
height / self->texture_height);
}
}
#if CLUTTER_CHECK_VERSION(1, 5, 2)
static gboolean
meta_background_actor_get_paint_volume (ClutterActor *actor,
ClutterPaintVolume *volume)
{
MetaBackgroundActor *self = META_BACKGROUND_ACTOR (actor);
MetaBackgroundActorPrivate *priv = self->priv;
int width, height;
meta_screen_get_size (priv->background->screen, &width, &height);
meta_screen_get_size (self->screen, &width, &height);
clutter_paint_volume_set_width (volume, width);
clutter_paint_volume_set_height (volume, height);
return TRUE;
}
static void
meta_background_actor_set_dim_factor (MetaBackgroundActor *self,
gfloat dim_factor)
{
MetaBackgroundActorPrivate *priv = self->priv;
if (priv->dim_factor == dim_factor)
return;
priv->dim_factor = dim_factor;
clutter_actor_queue_redraw (CLUTTER_ACTOR (self));
g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_DIM_FACTOR]);
}
static void
meta_background_actor_get_property(GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
MetaBackgroundActor *self = META_BACKGROUND_ACTOR (object);
MetaBackgroundActorPrivate *priv = self->priv;
switch (prop_id)
{
case PROP_DIM_FACTOR:
g_value_set_float (value, priv->dim_factor);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
meta_background_actor_set_property(GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
MetaBackgroundActor *self = META_BACKGROUND_ACTOR (object);
switch (prop_id)
{
case PROP_DIM_FACTOR:
meta_background_actor_set_dim_factor (self, g_value_get_float (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
#endif
static void
meta_background_actor_class_init (MetaBackgroundActorClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
GParamSpec *pspec;
g_type_class_add_private (klass, sizeof (MetaBackgroundActorPrivate));
object_class->dispose = meta_background_actor_dispose;
object_class->get_property = meta_background_actor_get_property;
object_class->set_property = meta_background_actor_set_property;
actor_class->get_preferred_width = meta_background_actor_get_preferred_width;
actor_class->get_preferred_height = meta_background_actor_get_preferred_height;
actor_class->paint = meta_background_actor_paint;
#if CLUTTER_CHECK_VERSION(1, 5, 2)
actor_class->get_paint_volume = meta_background_actor_get_paint_volume;
/**
* MetaBackgroundActor:dim-factor:
*
* Factor to dim the background by, between 0.0 (black) and 1.0 (original
* colors)
*/
pspec = g_param_spec_float ("dim-factor",
"Dim factor",
"Factor to dim the background by",
0.0, 1.0,
1.0,
G_PARAM_READWRITE);
obj_props[PROP_DIM_FACTOR] = pspec;
g_object_class_install_property (object_class, PROP_DIM_FACTOR, pspec);
#endif
}
static void
meta_background_actor_init (MetaBackgroundActor *self)
meta_background_actor_init (MetaBackgroundActor *background_actor)
{
MetaBackgroundActorPrivate *priv;
priv = self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
META_TYPE_BACKGROUND_ACTOR,
MetaBackgroundActorPrivate);
priv->dim_factor = 1.0;
}
/**
* meta_background_actor_new:
* @screen: the #MetaScreen
* meta_background_actor_new:
*
* Creates a new actor to draw the background for the given screen.
*
* Return value: the newly created background actor
* Return value: (transfer none): the newly created background actor
*/
ClutterActor *
meta_background_actor_new_for_screen (MetaScreen *screen)
meta_background_actor_new (MetaScreen *screen)
{
MetaBackgroundActor *self;
MetaBackgroundActorPrivate *priv;
ClutterActor *stage;
g_return_val_if_fail (META_IS_SCREEN (screen), NULL);
self = g_object_new (META_TYPE_BACKGROUND_ACTOR, NULL);
priv = self->priv;
priv->background = meta_screen_background_get (screen);
priv->background->actors = g_slist_prepend (priv->background->actors, self);
self->screen = screen;
/* A CoglMaterial and a CoglPipeline are the same thing */
priv->pipeline = (CoglPipeline*) meta_create_texture_material (NULL);
self->material = meta_create_texture_material (NULL);
cogl_material_set_layer_wrap_mode (self->material, 0,
COGL_MATERIAL_WRAP_MODE_REPEAT);
set_texture_on_actor (self);
update_wrap_mode_of_actor (self);
stage = meta_get_stage_for_screen (self->screen);
g_signal_connect (stage, "notify::color",
G_CALLBACK (on_notify_stage_color), self);
meta_background_actor_update (self);
return CLUTTER_ACTOR (self);
}
/**
* meta_background_actor_update:
* @screen: a #MetaScreen
* @self: a #MetaBackgroundActor
*
* Refetches the _XROOTPMAP_ID property for the root window and updates
* the contents of the background actor based on that. There's no attempt
@ -499,9 +311,8 @@ meta_background_actor_new_for_screen (MetaScreen *screen)
* a PropertyNotify event for the property.
*/
void
meta_background_actor_update (MetaScreen *screen)
meta_background_actor_update (MetaBackgroundActor *self)
{
MetaScreenBackground *background;
MetaDisplay *display;
MetaCompositor *compositor;
Atom type;
@ -511,13 +322,14 @@ meta_background_actor_update (MetaScreen *screen)
guchar *data;
Pixmap root_pixmap_id;
background = meta_screen_background_get (screen);
display = meta_screen_get_display (screen);
g_return_if_fail (META_IS_BACKGROUND_ACTOR (self));
display = meta_screen_get_display (self->screen);
compositor = meta_display_get_compositor (display);
root_pixmap_id = None;
if (!XGetWindowProperty (meta_display_get_xdisplay (display),
meta_screen_get_xroot (screen),
meta_screen_get_xroot (self->screen),
compositor->atom_x_root_pixmap,
0, LONG_MAX,
False,
@ -538,31 +350,23 @@ meta_background_actor_update (MetaScreen *screen)
if (root_pixmap_id != None)
{
CoglHandle texture;
CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
GError *error = NULL;
meta_error_trap_push (display);
texture = cogl_texture_pixmap_x11_new (ctx, root_pixmap_id, FALSE, &error);
texture = cogl_texture_pixmap_x11_new (root_pixmap_id, FALSE);
meta_error_trap_pop (display);
if (texture != COGL_INVALID_HANDLE)
{
set_texture (background, texture);
set_texture (self, texture);
cogl_handle_unref (texture);
background->have_pixmap = True;
self->have_pixmap = True;
return;
}
else
{
g_warning ("Failed to create background texture from pixmap: %s",
error->message);
g_error_free (error);
}
}
background->have_pixmap = False;
set_texture_to_stage_color (background);
self->have_pixmap = False;
set_texture_to_stage_color (self);
}
/**
@ -578,126 +382,37 @@ void
meta_background_actor_set_visible_region (MetaBackgroundActor *self,
cairo_region_t *visible_region)
{
MetaBackgroundActorPrivate *priv;
g_return_if_fail (META_IS_BACKGROUND_ACTOR (self));
priv = self->priv;
if (priv->visible_region)
if (self->visible_region)
{
cairo_region_destroy (priv->visible_region);
priv->visible_region = NULL;
cairo_region_destroy (self->visible_region);
self->visible_region = NULL;
}
if (visible_region)
{
cairo_rectangle_int_t screen_rect = { 0 };
meta_screen_get_size (priv->background->screen, &screen_rect.width, &screen_rect.height);
meta_screen_get_size (self->screen, &screen_rect.width, &screen_rect.height);
/* Doing the intersection here is probably unnecessary - MetaWindowGroup
* should never compute a visible area that's larger than the root screen!
* but it's not that expensive and adds some extra robustness.
*/
priv->visible_region = cairo_region_create_rectangle (&screen_rect);
cairo_region_intersect (priv->visible_region, visible_region);
self->visible_region = cairo_region_create_rectangle (&screen_rect);
cairo_region_intersect (self->visible_region, visible_region);
}
}
/**
* meta_background_actor_screen_size_changed:
* @screen: a #MetaScreen
* @self: a #MetaBackgroundActor
*
* Called by the compositor when the size of the #MetaScreen changes
*/
void
meta_background_actor_screen_size_changed (MetaScreen *screen)
meta_background_actor_screen_size_changed (MetaBackgroundActor *self)
{
MetaScreenBackground *background = meta_screen_background_get (screen);
GSList *l;
update_wrap_mode (background);
for (l = background->actors; l; l = l->next)
clutter_actor_queue_relayout (l->data);
update_wrap_mode (self);
clutter_actor_queue_relayout (CLUTTER_ACTOR (self));
}
/**
* meta_background_actor_add_glsl_snippet:
* @actor: a #MetaBackgroundActor
* @hook: where to insert the code
* @declarations: GLSL declarations
* @code: GLSL code
* @is_replace: wheter Cogl code should be replaced by the custom shader
*
* Adds a GLSL snippet to the pipeline used for drawing the background.
* See #CoglSnippet for details.
*/
void
meta_background_actor_add_glsl_snippet (MetaBackgroundActor *actor,
MetaSnippetHook hook,
const char *declarations,
const char *code,
gboolean is_replace)
{
MetaBackgroundActorPrivate *priv;
CoglSnippet *snippet;
g_return_if_fail (META_IS_BACKGROUND_ACTOR (actor));
priv = actor->priv;
if (is_replace)
{
snippet = cogl_snippet_new (hook, declarations, NULL);
cogl_snippet_set_replace (snippet, code);
}
else
{
snippet = cogl_snippet_new (hook, declarations, code);
}
if (hook == META_SNIPPET_HOOK_VERTEX ||
hook == META_SNIPPET_HOOK_FRAGMENT)
cogl_pipeline_add_snippet (priv->pipeline, snippet);
else
cogl_pipeline_add_layer_snippet (priv->pipeline, 0, snippet);
cogl_object_unref (snippet);
}
/**
* meta_background_actor_set_uniform_float:
* @actor: a #MetaBackgroundActor
* @uniform_name:
* @n_components: number of components (for vector uniforms)
* @count: number of uniforms (for array uniforms)
* @uniform: (array length=uniform_length): the float values to set
* @uniform_length: the length of @uniform. Must be exactly @n_components x @count,
* and is provided mainly for language bindings.
*
* Sets a new GLSL uniform to the provided value. This is mostly
* useful in congiunction with meta_background_actor_add_glsl_snippet().
*/
void
meta_background_actor_set_uniform_float (MetaBackgroundActor *actor,
const char *uniform_name,
int n_components,
int count,
const float *uniform,
int uniform_length)
{
MetaBackgroundActorPrivate *priv;
g_return_if_fail (META_IS_BACKGROUND_ACTOR (actor));
g_return_if_fail (uniform_length == n_components * count);
priv = actor->priv;
cogl_pipeline_set_uniform_float (priv->pipeline,
cogl_pipeline_get_uniform_location (priv->pipeline,
uniform_name),
n_components, count, uniform);
}

View File

@ -46,55 +46,13 @@ typedef struct _MetaBackgroundActor MetaBackgroundActor;
typedef struct _MetaBackgroundActorClass MetaBackgroundActorClass;
typedef struct _MetaBackgroundActorPrivate MetaBackgroundActorPrivate;
struct _MetaBackgroundActorClass
{
ClutterActorClass parent_class;
};
struct _MetaBackgroundActor
{
ClutterActor parent;
MetaBackgroundActorPrivate *priv;
};
GType meta_background_actor_get_type (void);
ClutterActor *meta_background_actor_new_for_screen (MetaScreen *screen);
ClutterActor *meta_background_actor_new (MetaScreen *screen);
/**
* MetaSnippetHook:
* Temporary hack to work around Cogl not exporting CoglSnippetHook in
* the 1.0 API. Don't use.
*/
typedef enum {
/* Per pipeline vertex hooks */
META_SNIPPET_HOOK_VERTEX = 0,
META_SNIPPET_HOOK_VERTEX_TRANSFORM,
/* Per pipeline fragment hooks */
META_SNIPPET_HOOK_FRAGMENT = 2048,
/* Per layer vertex hooks */
META_SNIPPET_HOOK_TEXTURE_COORD_TRANSFORM = 4096,
/* Per layer fragment hooks */
META_SNIPPET_HOOK_LAYER_FRAGMENT = 6144,
META_SNIPPET_HOOK_TEXTURE_LOOKUP
} MetaSnippetHook;
void meta_background_actor_add_glsl_snippet (MetaBackgroundActor *actor,
MetaSnippetHook hook,
const char *declarations,
const char *code,
gboolean is_replace);
void meta_background_actor_set_uniform_float (MetaBackgroundActor *actor,
const char *uniform_name,
int n_components,
int count,
const float *uniform,
int uniform_length);
void meta_background_actor_update (MetaBackgroundActor *actor);
void meta_background_actor_set_visible_region (MetaBackgroundActor *self,
cairo_region_t *visible_region);
void meta_background_actor_screen_size_changed (MetaBackgroundActor *self);
#endif /* META_BACKGROUND_ACTOR_H */

View File

@ -35,32 +35,34 @@
#include <clutter/x11/clutter-x11.h>
static GType plugin_type = G_TYPE_NONE;
static GSList *plugin_types;
/*
* We have one "default plugin manager" that acts for the first screen,
* but also can be used before we open any screens, and additional
* plugin managers for each screen. (This is ugly. Probably we should
* have one plugin manager and only make the plugins per-screen.)
*/
static MetaPluginManager *default_plugin_manager;
struct MetaPluginManager
{
MetaScreen *screen;
MetaPlugin *plugin;
MetaScreen *screen;
GList /* MetaPlugin */ *plugins; /* TODO -- maybe use hash table */
};
void
meta_plugin_manager_set_plugin_type (GType gtype)
{
if (plugin_type != G_TYPE_NONE)
meta_fatal ("Mutter plugin already set: %s", g_type_name (plugin_type));
plugin_type = gtype;
}
/*
* Loads the given plugin.
*/
void
meta_plugin_manager_load (const gchar *plugin_name)
meta_plugin_manager_load (MetaPluginManager *plugin_mgr,
const gchar *plugin_name)
{
const gchar *dpath = MUTTER_PLUGIN_DIR "/";
gchar *path;
MetaModule *module;
GType plugin_type;
if (g_path_is_absolute (plugin_name))
path = g_strdup (plugin_name);
@ -79,57 +81,162 @@ meta_plugin_manager_load (const gchar *plugin_name)
exit (1);
}
meta_plugin_manager_set_plugin_type (meta_module_get_plugin_type (module));
plugin_type = meta_module_get_plugin_type (module);
meta_plugin_manager_register (plugin_mgr, plugin_type);
g_type_module_unuse (G_TYPE_MODULE (module));
g_free (path);
}
MetaPluginManager *
/*
* Registers the given plugin type
*/
void
meta_plugin_manager_register (MetaPluginManager *plugin_mgr,
GType plugin_type)
{
MetaPlugin *plugin;
plugin_types = g_slist_prepend (plugin_types, GSIZE_TO_POINTER (plugin_type));
plugin = g_object_new (plugin_type, NULL);
plugin_mgr->plugins = g_list_prepend (plugin_mgr->plugins, plugin);
}
void
meta_plugin_manager_initialize (MetaPluginManager *plugin_mgr)
{
GList *iter;
if (!plugin_mgr->plugins)
{
/*
* If no plugins are specified, load the default plugin.
*/
meta_plugin_manager_load (plugin_mgr, "default");
}
for (iter = plugin_mgr->plugins; iter; iter = iter->next)
{
MetaPlugin *plugin = (MetaPlugin*) iter->data;
MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
g_object_set (plugin,
"screen", plugin_mgr->screen,
NULL);
if (klass->start)
klass->start (plugin);
}
}
static MetaPluginManager *
meta_plugin_manager_new (MetaScreen *screen)
{
MetaPluginManager *plugin_mgr;
MetaPluginClass *klass;
MetaPlugin *plugin;
plugin_mgr = g_new0 (MetaPluginManager, 1);
plugin_mgr->screen = screen;
plugin_mgr->plugin = plugin = g_object_new (plugin_type, "screen", screen, NULL);
klass = META_PLUGIN_GET_CLASS (plugin);
if (klass->start)
klass->start (plugin);
if (screen)
g_object_set_data (G_OBJECT (screen), "meta-plugin-manager", plugin_mgr);
return plugin_mgr;
}
MetaPluginManager *
meta_plugin_manager_get_default (void)
{
if (!default_plugin_manager)
{
default_plugin_manager = meta_plugin_manager_new (NULL);
}
return default_plugin_manager;
}
MetaPluginManager *
meta_plugin_manager_get (MetaScreen *screen)
{
MetaPluginManager *plugin_mgr;
plugin_mgr = g_object_get_data (G_OBJECT (screen), "meta-plugin-manager");
if (plugin_mgr)
return plugin_mgr;
if (!default_plugin_manager)
meta_plugin_manager_get_default ();
if (!default_plugin_manager->screen)
{
/* The default plugin manager is so far unused, we can recycle it */
default_plugin_manager->screen = screen;
g_object_set_data (G_OBJECT (screen), "meta-plugin-manager", default_plugin_manager);
return default_plugin_manager;
}
else
{
GSList *iter;
GType plugin_type;
MetaPlugin *plugin;
plugin_mgr = meta_plugin_manager_new (screen);
for (iter = plugin_types; iter; iter = iter->next)
{
plugin_type = (GType)GPOINTER_TO_SIZE (iter->data);
plugin = g_object_new (plugin_type, "screen", screen, NULL);
plugin_mgr->plugins = g_list_prepend (plugin_mgr->plugins, plugin);
}
return plugin_mgr;
}
}
static void
meta_plugin_manager_kill_window_effects (MetaPluginManager *plugin_mgr,
MetaWindowActor *actor)
{
MetaPlugin *plugin = plugin_mgr->plugin;
MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
GList *l = plugin_mgr->plugins;
if (klass->kill_window_effects)
klass->kill_window_effects (plugin, actor);
while (l)
{
MetaPlugin *plugin = l->data;
MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
if (!meta_plugin_disabled (plugin)
&& klass->kill_window_effects)
klass->kill_window_effects (plugin, actor);
l = l->next;
}
}
static void
meta_plugin_manager_kill_switch_workspace (MetaPluginManager *plugin_mgr)
{
MetaPlugin *plugin = plugin_mgr->plugin;
MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
GList *l = plugin_mgr->plugins;
if (klass->kill_switch_workspace)
klass->kill_switch_workspace (plugin);
while (l)
{
MetaPlugin *plugin = l->data;
MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
if (!meta_plugin_disabled (plugin)
&& (meta_plugin_features (plugin) & META_PLUGIN_SWITCH_WORKSPACE)
&& klass->kill_switch_workspace)
klass->kill_switch_workspace (plugin);
l = l->next;
}
}
/*
* Public method that the compositor hooks into for events that require
* no additional parameters.
*
* Returns TRUE if the plugin handled the event type (i.e.,
* Returns TRUE if at least one of the plugins handled the event type (i.e.,
* if the return value is FALSE, there will be no subsequent call to the
* manager completed() callback, and the compositor must ensure that any
* appropriate post-effect cleanup is carried out.
@ -139,48 +246,60 @@ meta_plugin_manager_event_simple (MetaPluginManager *plugin_mgr,
MetaWindowActor *actor,
unsigned long event)
{
MetaPlugin *plugin = plugin_mgr->plugin;
MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
MetaDisplay *display = meta_screen_get_display (plugin_mgr->screen);
GList *l = plugin_mgr->plugins;
gboolean retval = FALSE;
MetaDisplay *display = meta_screen_get_display (plugin_mgr->screen);
if (display->display_opening)
return FALSE;
switch (event)
while (l)
{
case META_PLUGIN_MINIMIZE:
if (klass->minimize)
{
retval = TRUE;
meta_plugin_manager_kill_window_effects (plugin_mgr,
actor);
MetaPlugin *plugin = l->data;
MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
_meta_plugin_effect_started (plugin);
klass->minimize (plugin, actor);
}
break;
case META_PLUGIN_MAP:
if (klass->map)
if (!meta_plugin_disabled (plugin) &&
(meta_plugin_features (plugin) & event))
{
retval = TRUE;
meta_plugin_manager_kill_window_effects (plugin_mgr,
actor);
_meta_plugin_effect_started (plugin);
klass->map (plugin, actor);
switch (event)
{
case META_PLUGIN_MINIMIZE:
if (klass->minimize)
{
meta_plugin_manager_kill_window_effects (
plugin_mgr,
actor);
_meta_plugin_effect_started (plugin);
klass->minimize (plugin, actor);
}
break;
case META_PLUGIN_MAP:
if (klass->map)
{
meta_plugin_manager_kill_window_effects (
plugin_mgr,
actor);
_meta_plugin_effect_started (plugin);
klass->map (plugin, actor);
}
break;
case META_PLUGIN_DESTROY:
if (klass->destroy)
{
_meta_plugin_effect_started (plugin);
klass->destroy (plugin, actor);
}
break;
default:
g_warning ("Incorrect handler called for event %lu", event);
}
}
break;
case META_PLUGIN_DESTROY:
if (klass->destroy)
{
retval = TRUE;
_meta_plugin_effect_started (plugin);
klass->destroy (plugin, actor);
}
break;
default:
g_warning ("Incorrect handler called for event %lu", event);
l = l->next;
}
return retval;
@ -190,7 +309,7 @@ meta_plugin_manager_event_simple (MetaPluginManager *plugin_mgr,
* The public method that the compositor hooks into for maximize and unmaximize
* events.
*
* Returns TRUE if the plugin handled the event type (i.e.,
* Returns TRUE if at least one of the plugins handled the event type (i.e.,
* if the return value is FALSE, there will be no subsequent call to the
* manager completed() callback, and the compositor must ensure that any
* appropriate post-effect cleanup is carried out.
@ -204,44 +323,57 @@ meta_plugin_manager_event_maximize (MetaPluginManager *plugin_mgr,
gint target_width,
gint target_height)
{
MetaPlugin *plugin = plugin_mgr->plugin;
MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
MetaDisplay *display = meta_screen_get_display (plugin_mgr->screen);
GList *l = plugin_mgr->plugins;
gboolean retval = FALSE;
MetaDisplay *display = meta_screen_get_display (plugin_mgr->screen);
if (display->display_opening)
return FALSE;
switch (event)
while (l)
{
case META_PLUGIN_MAXIMIZE:
if (klass->maximize)
MetaPlugin *plugin = l->data;
MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
if (!meta_plugin_disabled (plugin) &&
(meta_plugin_features (plugin) & event))
{
retval = TRUE;
meta_plugin_manager_kill_window_effects (plugin_mgr,
actor);
_meta_plugin_effect_started (plugin);
klass->maximize (plugin, actor,
target_x, target_y,
target_width, target_height);
}
break;
case META_PLUGIN_UNMAXIMIZE:
if (klass->unmaximize)
{
retval = TRUE;
meta_plugin_manager_kill_window_effects (plugin_mgr,
actor);
switch (event)
{
case META_PLUGIN_MAXIMIZE:
if (klass->maximize)
{
meta_plugin_manager_kill_window_effects (
plugin_mgr,
actor);
_meta_plugin_effect_started (plugin);
klass->unmaximize (plugin, actor,
target_x, target_y,
target_width, target_height);
_meta_plugin_effect_started (plugin);
klass->maximize (plugin, actor,
target_x, target_y,
target_width, target_height);
}
break;
case META_PLUGIN_UNMAXIMIZE:
if (klass->unmaximize)
{
meta_plugin_manager_kill_window_effects (
plugin_mgr,
actor);
_meta_plugin_effect_started (plugin);
klass->unmaximize (plugin, actor,
target_x, target_y,
target_width, target_height);
}
break;
default:
g_warning ("Incorrect handler called for event %lu", event);
}
}
break;
default:
g_warning ("Incorrect handler called for event %lu", event);
l = l->next;
}
return retval;
@ -250,7 +382,7 @@ meta_plugin_manager_event_maximize (MetaPluginManager *plugin_mgr,
/*
* The public method that the compositor hooks into for desktop switching.
*
* Returns TRUE if the plugin handled the event type (i.e.,
* Returns TRUE if at least one of the plugins handled the event type (i.e.,
* if the return value is FALSE, there will be no subsequent call to the
* manager completed() callback, and the compositor must ensure that any
* appropriate post-effect cleanup is carried out.
@ -261,43 +393,41 @@ meta_plugin_manager_switch_workspace (MetaPluginManager *plugin_mgr,
gint to,
MetaMotionDirection direction)
{
MetaPlugin *plugin = plugin_mgr->plugin;
MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
MetaDisplay *display = meta_screen_get_display (plugin_mgr->screen);
GList *l = plugin_mgr->plugins;
gboolean retval = FALSE;
MetaDisplay *display = meta_screen_get_display (plugin_mgr->screen);
if (display->display_opening)
return FALSE;
if (klass->switch_workspace)
while (l)
{
retval = TRUE;
meta_plugin_manager_kill_switch_workspace (plugin_mgr);
MetaPlugin *plugin = l->data;
MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
_meta_plugin_effect_started (plugin);
klass->switch_workspace (plugin, from, to, direction);
if (!meta_plugin_disabled (plugin) &&
(meta_plugin_features (plugin) & META_PLUGIN_SWITCH_WORKSPACE))
{
if (klass->switch_workspace)
{
retval = TRUE;
meta_plugin_manager_kill_switch_workspace (plugin_mgr);
_meta_plugin_effect_started (plugin);
klass->switch_workspace (plugin, from, to, direction);
}
}
l = l->next;
}
return retval;
}
gboolean
meta_plugin_manager_filter_keybinding (MetaPluginManager *plugin_mgr,
MetaKeyBinding *binding)
{
MetaPlugin *plugin = plugin_mgr->plugin;
MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
if (klass->keybinding_filter)
return klass->keybinding_filter (plugin, binding);
return FALSE;
}
/*
* The public method that the compositor hooks into for desktop switching.
*
* Returns TRUE if the plugin handled the event type (i.e.,
* Returns TRUE if at least one of the plugins handled the event type (i.e.,
* if the return value is FALSE, there will be no subsequent call to the
* manager completed() callback, and the compositor must ensure that any
* appropriate post-effect cleanup is carried out.
@ -306,17 +436,49 @@ gboolean
meta_plugin_manager_xevent_filter (MetaPluginManager *plugin_mgr,
XEvent *xev)
{
MetaPlugin *plugin = plugin_mgr->plugin;
MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
GList *l;
gboolean have_plugin_xevent_func;
if (!plugin_mgr)
return FALSE;
l = plugin_mgr->plugins;
/* We need to make sure that clutter gets certain events, like
* ConfigureNotify on the stage window. If there is a plugin that
* provides an xevent_filter function, then it's the responsibility
* of that plugin to pass events to Clutter. Otherwise, we send the
* event directly to Clutter ourselves.
*
* What happens if there are two plugins with xevent_filter functions
* is undefined; in general, multiple competing plugins are something
* we don't support well or care much about.
*
* FIXME: Really, we should just always handle sending the event to
* clutter if a plugin doesn't report the event as handled by
* returning TRUE, but it doesn't seem worth breaking compatibility
* of the plugin interface right now to achieve this; the way it is
* now works fine in practice.
*/
if (klass->xevent_filter)
return klass->xevent_filter (plugin, xev);
else
have_plugin_xevent_func = FALSE;
while (l)
{
MetaPlugin *plugin = l->data;
MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
if (klass->xevent_filter)
{
have_plugin_xevent_func = TRUE;
if (klass->xevent_filter (plugin, xev) == TRUE)
return TRUE;
}
l = l->next;
}
if (!have_plugin_xevent_func)
return clutter_x11_handle_event (xev) != CLUTTER_X11_FILTER_CONTINUE;
return FALSE;
}

View File

@ -46,9 +46,14 @@
*/
typedef struct MetaPluginManager MetaPluginManager;
MetaPluginManager * meta_plugin_manager_new (MetaScreen *screen);
MetaPluginManager * meta_plugin_manager_get (MetaScreen *screen);
MetaPluginManager * meta_plugin_manager_get_default (void);
void meta_plugin_manager_load (const gchar *plugin_name);
void meta_plugin_manager_load (MetaPluginManager *mgr,
const gchar *plugin_name);
void meta_plugin_manager_register (MetaPluginManager *mgr,
GType plugin_type);
void meta_plugin_manager_initialize (MetaPluginManager *mgr);
gboolean meta_plugin_manager_event_simple (MetaPluginManager *mgr,
MetaWindowActor *actor,
@ -61,15 +66,16 @@ gboolean meta_plugin_manager_event_maximize (MetaPluginManager *mgr,
gint target_y,
gint target_width,
gint target_height);
void meta_plugin_manager_update_workspaces (MetaPluginManager *mgr);
void meta_plugin_manager_update_workspace (MetaPluginManager *mgr,
MetaWorkspace *w);
gboolean meta_plugin_manager_switch_workspace (MetaPluginManager *mgr,
gint from,
gint to,
MetaMotionDirection direction);
gboolean meta_plugin_manager_filter_keybinding (MetaPluginManager *mgr,
MetaKeyBinding *binding);
gboolean meta_plugin_manager_xevent_filter (MetaPluginManager *mgr,
XEvent *xev);

View File

@ -44,17 +44,74 @@ enum
{
PROP_0,
PROP_SCREEN,
PROP_FEATURES,
PROP_DISABLED,
PROP_DEBUG_MODE,
};
struct _MetaPluginPrivate
{
MetaScreen *screen;
gulong features;
gint running;
gboolean disabled : 1;
gboolean debug : 1;
};
static void
meta_plugin_set_features (MetaPlugin *plugin)
{
MetaPluginPrivate *priv = plugin->priv;
MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
priv->features = 0;
/*
* Feature flags: identify events that the plugin can handle; a plugin can
* handle one or more events.
*/
if (klass->minimize)
priv->features |= META_PLUGIN_MINIMIZE;
if (klass->maximize)
priv->features |= META_PLUGIN_MAXIMIZE;
if (klass->unmaximize)
priv->features |= META_PLUGIN_UNMAXIMIZE;
if (klass->map)
priv->features |= META_PLUGIN_MAP;
if (klass->destroy)
priv->features |= META_PLUGIN_DESTROY;
if (klass->switch_workspace)
priv->features |= META_PLUGIN_SWITCH_WORKSPACE;
}
static void
meta_plugin_constructed (GObject *object)
{
meta_plugin_set_features (META_PLUGIN (object));
if (G_OBJECT_CLASS (meta_plugin_parent_class)->constructed)
G_OBJECT_CLASS (meta_plugin_parent_class)->constructed (object);
}
static void
meta_plugin_dispose (GObject *object)
{
G_OBJECT_CLASS (meta_plugin_parent_class)->dispose (object);
}
static void
meta_plugin_finalize (GObject *object)
{
G_OBJECT_CLASS (meta_plugin_parent_class)->finalize (object);
}
static void
meta_plugin_set_property (GObject *object,
guint prop_id,
@ -68,6 +125,9 @@ meta_plugin_set_property (GObject *object,
case PROP_SCREEN:
priv->screen = g_value_get_object (value);
break;
case PROP_DISABLED:
priv->disabled = g_value_get_boolean (value);
break;
case PROP_DEBUG_MODE:
priv->debug = g_value_get_boolean (value);
break;
@ -90,9 +150,15 @@ meta_plugin_get_property (GObject *object,
case PROP_SCREEN:
g_value_set_object (value, priv->screen);
break;
case PROP_DISABLED:
g_value_set_boolean (value, priv->disabled);
break;
case PROP_DEBUG_MODE:
g_value_set_boolean (value, priv->debug);
break;
case PROP_FEATURES:
g_value_set_ulong (value, priv->features);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -105,6 +171,9 @@ meta_plugin_class_init (MetaPluginClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->constructed = meta_plugin_constructed;
gobject_class->finalize = meta_plugin_finalize;
gobject_class->dispose = meta_plugin_dispose;
gobject_class->set_property = meta_plugin_set_property;
gobject_class->get_property = meta_plugin_get_property;
@ -116,6 +185,22 @@ meta_plugin_class_init (MetaPluginClass *klass)
META_TYPE_SCREEN,
G_PARAM_READWRITE));
g_object_class_install_property (gobject_class,
PROP_FEATURES,
g_param_spec_ulong ("features",
"Features",
"Plugin Features",
0 , G_MAXULONG, 0,
G_PARAM_READABLE));
g_object_class_install_property (gobject_class,
PROP_DISABLED,
g_param_spec_boolean ("disabled",
"Plugin disabled",
"Plugin disabled",
FALSE,
G_PARAM_READWRITE));
g_object_class_install_property (gobject_class,
PROP_DEBUG_MODE,
g_param_spec_boolean ("debug-mode",
@ -135,6 +220,22 @@ meta_plugin_init (MetaPlugin *self)
self->priv = priv = META_PLUGIN_GET_PRIVATE (self);
}
gulong
meta_plugin_features (MetaPlugin *plugin)
{
MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv;
return priv->features;
}
gboolean
meta_plugin_disabled (MetaPlugin *plugin)
{
MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv;
return priv->disabled;
}
gboolean
meta_plugin_running (MetaPlugin *plugin)
{
@ -162,6 +263,38 @@ meta_plugin_get_info (MetaPlugin *plugin)
return NULL;
}
ClutterActor *
meta_plugin_get_overlay_group (MetaPlugin *plugin)
{
MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv;
return meta_get_overlay_group_for_screen (priv->screen);
}
ClutterActor *
meta_plugin_get_stage (MetaPlugin *plugin)
{
MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv;
return meta_get_stage_for_screen (priv->screen);
}
ClutterActor *
meta_plugin_get_window_group (MetaPlugin *plugin)
{
MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv;
return meta_get_window_group_for_screen (priv->screen);
}
ClutterActor *
meta_plugin_get_background_actor (MetaPlugin *plugin)
{
MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv;
return meta_get_background_actor_for_screen (priv->screen);
}
/**
* _meta_plugin_effect_started:
* @plugin: the plugin
@ -182,7 +315,7 @@ meta_plugin_switch_workspace_completed (MetaPlugin *plugin)
{
MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv;
MetaScreen *screen = priv->screen;
MetaScreen *screen = meta_plugin_get_screen (plugin);
if (priv->running-- < 0)
{
@ -256,6 +389,80 @@ meta_plugin_destroy_completed (MetaPlugin *plugin,
meta_plugin_window_effect_completed (plugin, actor, META_PLUGIN_DESTROY);
}
void
meta_plugin_query_screen_size (MetaPlugin *plugin,
int *width,
int *height)
{
MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv;
meta_screen_get_size (priv->screen, width, height);
}
void
meta_plugin_set_stage_reactive (MetaPlugin *plugin,
gboolean reactive)
{
MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv;
MetaScreen *screen = priv->screen;
if (reactive)
meta_set_stage_input_region (screen, None);
else
meta_empty_stage_input_region (screen);
}
void
meta_plugin_set_stage_input_area (MetaPlugin *plugin,
gint x, gint y, gint width, gint height)
{
MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv;
MetaScreen *screen = priv->screen;
MetaDisplay *display = meta_screen_get_display (screen);
Display *xdpy = meta_display_get_xdisplay (display);
XRectangle rect;
XserverRegion region;
rect.x = x;
rect.y = y;
rect.width = width;
rect.height = height;
region = XFixesCreateRegion (xdpy, &rect, 1);
meta_set_stage_input_region (screen, region);
XFixesDestroyRegion (xdpy, region);
}
void
meta_plugin_set_stage_input_region (MetaPlugin *plugin,
XserverRegion region)
{
MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv;
MetaScreen *screen = priv->screen;
meta_set_stage_input_region (screen, region);
}
/**
* meta_plugin_get_window_actors:
* @plugin: A #MetaPlugin
*
* This function returns all of the #MetaWindowActor objects referenced by Mutter, including
* override-redirect windows. The returned list is a snapshot of Mutter's current
* stacking order, with the topmost window last.
*
* The 'restacked' signal of #MetaScreen signals when this value has changed.
*
* Returns: (transfer none) (element-type MetaWindowActor): Windows in stacking order, topmost last
*/
GList *
meta_plugin_get_window_actors (MetaPlugin *plugin)
{
MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv;
return meta_get_window_actors (priv->screen);
}
/**
* meta_plugin_begin_modal:
* @plugin: a #MetaPlugin
@ -295,7 +502,7 @@ meta_plugin_begin_modal (MetaPlugin *plugin,
}
/**
* meta_plugin_end_modal:
* meta_plugin_end_modal
* @plugin: a #MetaPlugin
* @timestamp: the time used for releasing grabs
*
@ -314,6 +521,16 @@ meta_plugin_end_modal (MetaPlugin *plugin,
meta_end_modal_for_plugin (priv->screen, plugin, timestamp);
}
Display *
meta_plugin_get_xdisplay (MetaPlugin *plugin)
{
MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv;
MetaDisplay *display = meta_screen_get_display (priv->screen);
Display *xdpy = meta_display_get_xdisplay (display);
return xdpy;
}
/**
* meta_plugin_get_screen:
* @plugin: a #MetaPlugin
@ -331,3 +548,19 @@ meta_plugin_get_screen (MetaPlugin *plugin)
return priv->screen;
}
/**
* meta_plugin_type_register:
* @plugin_type: a #MetaPlugin type
*
* Register @plugin_type as a compositor plugin type to be used.
* You must call this before calling meta_init().
*/
void
meta_plugin_type_register (GType plugin_type)
{
MetaPluginManager *plugin_manager;
plugin_manager = meta_plugin_manager_get_default ();
meta_plugin_manager_register (plugin_manager, plugin_type);
}

View File

@ -47,8 +47,7 @@ void meta_shadow_paint (MetaShadow *shadow,
int window_width,
int window_height,
guint8 opacity,
cairo_region_t *clip,
gboolean clip_strictly);
cairo_region_t *clip);
void meta_shadow_get_bounds (MetaShadow *shadow,
int window_x,
int window_y,

View File

@ -120,17 +120,17 @@ static guint signals[LAST_SIGNAL] = { 0 };
/* The first element in this array also defines the default parameters
* for newly created classes */
MetaShadowClassInfo default_shadow_classes[] = {
{ "normal", { 6, -1, 0, 3, 255 }, { 3, -1, 0, 3, 128 } },
{ "dialog", { 6, -1, 0, 3, 255 }, { 3, -1, 0, 3, 128 } },
{ "modal_dialog", { 6, -1, 0, 1, 255 }, { 3, -1, 0, 3, 128 } },
{ "utility", { 3, -1, 0, 1, 255 }, { 3, -1, 0, 1, 128 } },
{ "border", { 6, -1, 0, 3, 255 }, { 3, -1, 0, 3, 128 } },
{ "menu", { 6, -1, 0, 3, 255 }, { 3, -1, 0, 0, 128 } },
{ "normal", { 12, -1, 0, 8, 255 }, { 6, -1, 0, 4, 255 } },
{ "dialog", { 12, -1, 0, 8, 255 }, { 6, -1, 0, 4, 255 } },
{ "modal_dialog", { 12, -1, 0, 8, 255 }, { 6, -1, 0, 4, 255 } },
{ "utility", { 12, -1, 0, 8, 255 }, { 6, -1, 0, 4, 255 } },
{ "border", { 12, -1, 0, 8, 255 }, { 6, -1, 0, 4, 255 } },
{ "menu", { 12, -1, 0, 8, 255 }, { 6, -1, 0, 4, 255 } },
{ "popup-menu", { 1, -1, 0, 1, 128 }, { 1, -1, 0, 1, 128 } },
{ "popup-menu", { 6, -1, 0, 4, 255 }, { 6, -1, 0, 4, 255 } },
{ "dropdown-menu", { 1, 10, 0, 1, 128 }, { 1, 10, 0, 1, 128 } },
{ "attached", { 1, -1, 0, 1, 128 }, { 1, -1, 0, 1, 128 } }
{ "dropdown-menu", { 6, 25, 0, 4, 255 }, { 6, 100, 0, 4, 255 } },
{ "attached", { 6, 25, 0, 4, 255 }, { 6, 100, 0, 4, 255 } }
};
G_DEFINE_TYPE (MetaShadowFactory, meta_shadow_factory, G_TYPE_OBJECT);
@ -189,10 +189,8 @@ meta_shadow_unref (MetaShadow *shadow)
* @window_width: actual width of the region to paint a shadow for
* @window_height: actual height of the region to paint a shadow for
* @clip: (allow-none): if non-%NULL specifies the visible portion
* of the shadow.
* @clip_strictly: if %TRUE, drawing will be clipped strictly
* to @clip, otherwise, it will be only used to optimize
* drawing.
* of the shadow. Drawing won't be strictly clipped to this region
* but it will be used to optimize what is drawn.
*
* Paints the shadow at the given position, for the specified actual
* size of the region. (Since a #MetaShadow can be shared between
@ -206,8 +204,7 @@ meta_shadow_paint (MetaShadow *shadow,
int window_width,
int window_height,
guint8 opacity,
cairo_region_t *clip,
gboolean clip_strictly)
cairo_region_t *clip)
{
float texture_width = cogl_texture_get_width (shadow->texture);
float texture_height = cogl_texture_get_height (shadow->texture);
@ -279,9 +276,6 @@ meta_shadow_paint (MetaShadow *shadow,
dest_rect.y = dest_y[j];
dest_rect.height = dest_y[j + 1] - dest_y[j];
if (dest_rect.height == 0)
continue;
for (i = 0; i < n_x; i++)
{
cairo_region_overlap_t overlap;
@ -289,64 +283,16 @@ meta_shadow_paint (MetaShadow *shadow,
dest_rect.x = dest_x[i];
dest_rect.width = dest_x[i + 1] - dest_x[i];
if (dest_rect.width == 0)
continue;
if (clip)
overlap = cairo_region_contains_rectangle (clip, &dest_rect);
else
overlap = CAIRO_REGION_OVERLAP_IN;
overlap = CAIRO_REGION_OVERLAP_PART;
/* There's quite a bit of overhead from allocating a new
* region in order to find an exact intersection and
* generating more geometry - we make the assumption that
* unless we have to clip strictly it will be cheaper to
* just draw the entire rectangle.
*/
if (overlap == CAIRO_REGION_OVERLAP_IN ||
(overlap == CAIRO_REGION_OVERLAP_PART && !clip_strictly))
{
cogl_rectangle_with_texture_coords (dest_x[i], dest_y[j],
dest_x[i + 1], dest_y[j + 1],
src_x[i], src_y[j],
src_x[i + 1], src_y[j + 1]);
}
else if (overlap == CAIRO_REGION_OVERLAP_PART)
{
cairo_region_t *intersection;
int n_rectangles, k;
intersection = cairo_region_create_rectangle (&dest_rect);
cairo_region_intersect (intersection, clip);
n_rectangles = cairo_region_num_rectangles (intersection);
for (k = 0; k < n_rectangles; k++)
{
cairo_rectangle_int_t rect;
float src_x1, src_x2, src_y1, src_y2;
cairo_region_get_rectangle (intersection, k, &rect);
/* Separately linear interpolate X and Y coordinates in the source
* based on the destination X and Y coordinates */
src_x1 = (src_x[i] * (dest_rect.x + dest_rect.width - rect.x) +
src_x[i + 1] * (rect.x - dest_rect.x)) / dest_rect.width;
src_x2 = (src_x[i] * (dest_rect.x + dest_rect.width - (rect.x + rect.width)) +
src_x[i + 1] * (rect.x + rect.width - dest_rect.x)) / dest_rect.width;
src_y1 = (src_y[j] * (dest_rect.y + dest_rect.height - rect.y) +
src_y[j + 1] * (rect.y - dest_rect.y)) / dest_rect.height;
src_y2 = (src_y[j] * (dest_rect.y + dest_rect.height - (rect.y + rect.height)) +
src_y[j + 1] * (rect.y + rect.height - dest_rect.y)) / dest_rect.height;
cogl_rectangle_with_texture_coords (rect.x, rect.y,
rect.x + rect.width, rect.y + rect.height,
src_x1, src_y1, src_x2, src_y2);
}
cairo_region_destroy (intersection);
}
if (overlap != CAIRO_REGION_OVERLAP_OUT)
cogl_rectangle_with_texture_coords (dest_x[i], dest_y[j],
dest_x[i + 1], dest_y[j + 1],
src_x[i], src_y[j],
src_x[i + 1], src_y[j + 1]);
}
}
}
@ -360,7 +306,7 @@ meta_shadow_paint (MetaShadow *shadow,
* @window_height: actual height of the region to paint a shadow for
*
* Computes the bounds of the pixels that will be affected by
* meta_shadow_paint()
* meta_shadow_paints()
*/
void
meta_shadow_get_bounds (MetaShadow *shadow,
@ -371,7 +317,7 @@ meta_shadow_get_bounds (MetaShadow *shadow,
cairo_rectangle_int_t *bounds)
{
bounds->x = window_x - shadow->outer_border_left;
bounds->y = window_y - shadow->outer_border_top;
bounds->y = window_x - shadow->outer_border_top;
bounds->width = window_width + shadow->outer_border_left + shadow->outer_border_right;
bounds->height = window_height + shadow->outer_border_top + shadow->outer_border_bottom;
}
@ -442,7 +388,8 @@ meta_shadow_factory_class_init (MetaShadowFactoryClass *klass)
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
}

View File

@ -1,13 +1,11 @@
/*
* shaped texture
*
* An actor to draw a masked texture.
* An actor to draw a texture clipped to a list of rectangles
*
* Authored By Neil Roberts <neil@linux.intel.com>
* and Jasper St. Pierre <jstpierre@mecheye.net>
*
* Copyright (C) 2008 Intel Corporation
* Copyright (C) 2012 Red Hat, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@ -27,34 +25,37 @@
#include <config.h>
#include <meta/meta-shaped-texture.h>
#include "meta-shaped-texture.h"
#include "meta-texture-tower.h"
#include <clutter/clutter.h>
#include <cogl/cogl.h>
#include <cogl/cogl-texture-pixmap-x11.h>
#include <gdk/gdk.h> /* for gdk_rectangle_intersect() */
#include <string.h>
static void meta_shaped_texture_dispose (GObject *object);
static void meta_shaped_texture_finalize (GObject *object);
static void meta_shaped_texture_notify (GObject *object,
GParamSpec *pspec);
static void meta_shaped_texture_paint (ClutterActor *actor);
static void meta_shaped_texture_pick (ClutterActor *actor,
const ClutterColor *color);
static void meta_shaped_texture_get_preferred_width (ClutterActor *self,
gfloat for_height,
gfloat *min_width_p,
gfloat *natural_width_p);
static void meta_shaped_texture_update_area (ClutterX11TexturePixmap *texture,
int x,
int y,
int width,
int height);
static void meta_shaped_texture_get_preferred_height (ClutterActor *self,
gfloat for_width,
gfloat *min_height_p,
gfloat *natural_height_p);
static gboolean meta_shaped_texture_get_paint_volume (ClutterActor *self, ClutterPaintVolume *volume);
static void meta_shaped_texture_dirty_mask (MetaShapedTexture *stex);
#ifdef HAVE_GLX_TEXTURE_PIXMAP
G_DEFINE_TYPE (MetaShapedTexture, meta_shaped_texture,
CLUTTER_TYPE_ACTOR);
CLUTTER_GLX_TYPE_TEXTURE_PIXMAP);
#else /* HAVE_GLX_TEXTURE_PIXMAP */
G_DEFINE_TYPE (MetaShapedTexture, meta_shaped_texture,
CLUTTER_X11_TYPE_TEXTURE_PIXMAP);
#endif /* HAVE_GLX_TEXTURE_PIXMAP */
#define META_SHAPED_TEXTURE_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), META_TYPE_SHAPED_TEXTURE, \
@ -63,15 +64,15 @@ G_DEFINE_TYPE (MetaShapedTexture, meta_shaped_texture,
struct _MetaShapedTexturePrivate
{
MetaTextureTower *paint_tower;
Pixmap pixmap;
CoglHandle texture;
CoglHandle mask_texture;
CoglHandle material;
CoglHandle material_unshaped;
cairo_region_t *clip_region;
guint tex_width, tex_height;
guint mask_width, mask_height;
GArray *rectangles;
guint create_mipmaps : 1;
};
@ -81,14 +82,16 @@ meta_shaped_texture_class_init (MetaShapedTextureClass *klass)
{
GObjectClass *gobject_class = (GObjectClass *) klass;
ClutterActorClass *actor_class = (ClutterActorClass *) klass;
ClutterX11TexturePixmapClass *x11_texture_class = (ClutterX11TexturePixmapClass *) klass;
gobject_class->dispose = meta_shaped_texture_dispose;
gobject_class->finalize = meta_shaped_texture_finalize;
gobject_class->notify = meta_shaped_texture_notify;
actor_class->get_preferred_width = meta_shaped_texture_get_preferred_width;
actor_class->get_preferred_height = meta_shaped_texture_get_preferred_height;
actor_class->paint = meta_shaped_texture_paint;
actor_class->pick = meta_shaped_texture_pick;
actor_class->get_paint_volume = meta_shaped_texture_get_paint_volume;
x11_texture_class->update_area = meta_shaped_texture_update_area;
g_type_class_add_private (klass, sizeof (MetaShapedTexturePrivate));
}
@ -100,8 +103,9 @@ meta_shaped_texture_init (MetaShapedTexture *self)
priv = self->priv = META_SHAPED_TEXTURE_GET_PRIVATE (self);
priv->rectangles = g_array_new (FALSE, FALSE, sizeof (XRectangle));
priv->paint_tower = meta_texture_tower_new ();
priv->texture = COGL_INVALID_HANDLE;
priv->mask_texture = COGL_INVALID_HANDLE;
priv->create_mipmaps = TRUE;
}
@ -116,6 +120,8 @@ meta_shaped_texture_dispose (GObject *object)
meta_texture_tower_free (priv->paint_tower);
priv->paint_tower = NULL;
meta_shaped_texture_dirty_mask (self);
if (priv->material != COGL_INVALID_HANDLE)
{
cogl_handle_unref (priv->material);
@ -126,18 +132,167 @@ meta_shaped_texture_dispose (GObject *object)
cogl_handle_unref (priv->material_unshaped);
priv->material_unshaped = COGL_INVALID_HANDLE;
}
if (priv->texture != COGL_INVALID_HANDLE)
{
cogl_handle_unref (priv->texture);
priv->texture = COGL_INVALID_HANDLE;
}
meta_shaped_texture_set_mask_texture (self, COGL_INVALID_HANDLE);
meta_shaped_texture_set_clip_region (self, NULL);
G_OBJECT_CLASS (meta_shaped_texture_parent_class)->dispose (object);
}
static void
meta_shaped_texture_finalize (GObject *object)
{
MetaShapedTexture *self = (MetaShapedTexture *) object;
MetaShapedTexturePrivate *priv = self->priv;
g_array_free (priv->rectangles, TRUE);
G_OBJECT_CLASS (meta_shaped_texture_parent_class)->finalize (object);
}
static void
meta_shaped_texture_notify (GObject *object,
GParamSpec *pspec)
{
if (G_OBJECT_CLASS (meta_shaped_texture_parent_class)->notify)
G_OBJECT_CLASS (meta_shaped_texture_parent_class)->notify (object, pspec);
/* It seems like we could just do this out of update_area(), but unfortunately,
* clutter_glx_texture_pixmap() doesn't call through the vtable on the
* initial update_area, so we need to look for changes to the texture
* explicitly.
*/
if (strcmp (pspec->name, "cogl-texture") == 0)
{
MetaShapedTexture *stex = (MetaShapedTexture *) object;
MetaShapedTexturePrivate *priv = stex->priv;
meta_shaped_texture_clear (stex);
if (priv->create_mipmaps)
meta_texture_tower_set_base_texture (priv->paint_tower,
clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (stex)));
}
}
static void
meta_shaped_texture_dirty_mask (MetaShapedTexture *stex)
{
MetaShapedTexturePrivate *priv = stex->priv;
if (priv->mask_texture != COGL_INVALID_HANDLE)
{
GLuint mask_gl_tex;
GLenum mask_gl_target;
cogl_texture_get_gl_texture (priv->mask_texture,
&mask_gl_tex, &mask_gl_target);
#ifdef GL_TEXTURE_RECTANGLE_ARB
if (mask_gl_target == GL_TEXTURE_RECTANGLE_ARB)
glDeleteTextures (1, &mask_gl_tex);
#endif
cogl_handle_unref (priv->mask_texture);
priv->mask_texture = COGL_INVALID_HANDLE;
if (priv->material != COGL_INVALID_HANDLE)
cogl_material_set_layer (priv->material, 1, COGL_INVALID_HANDLE);
}
}
static void
meta_shaped_texture_ensure_mask (MetaShapedTexture *stex)
{
MetaShapedTexturePrivate *priv = stex->priv;
CoglHandle paint_tex;
guint tex_width, tex_height;
paint_tex = clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (stex));
if (paint_tex == COGL_INVALID_HANDLE)
return;
tex_width = cogl_texture_get_width (paint_tex);
tex_height = cogl_texture_get_height (paint_tex);
/* If the mask texture we have was created for a different size then
recreate it */
if (priv->mask_texture != COGL_INVALID_HANDLE
&& (priv->mask_width != tex_width || priv->mask_height != tex_height))
meta_shaped_texture_dirty_mask (stex);
/* If we don't have a mask texture yet then create one */
if (priv->mask_texture == COGL_INVALID_HANDLE)
{
guchar *mask_data;
const XRectangle *rect;
GLenum paint_gl_target;
/* Create data for an empty image */
mask_data = g_malloc0 (tex_width * tex_height);
/* Cut out a hole for each rectangle */
for (rect = (XRectangle *) priv->rectangles->data
+ priv->rectangles->len;
rect-- > (XRectangle *) priv->rectangles->data;)
{
gint x1 = rect->x, x2 = x1 + rect->width;
gint y1 = rect->y, y2 = y1 + rect->height;
guchar *p;
/* Clip the rectangle to the size of the texture */
x1 = CLAMP (x1, 0, (gint) tex_width - 1);
x2 = CLAMP (x2, x1, (gint) tex_width);
y1 = CLAMP (y1, 0, (gint) tex_height - 1);
y2 = CLAMP (y2, y1, (gint) tex_height);
/* Fill the rectangle */
for (p = mask_data + y1 * tex_width + x1;
y1 < y2;
y1++, p += tex_width)
memset (p, 255, x2 - x1);
}
cogl_texture_get_gl_texture (paint_tex, NULL, &paint_gl_target);
#ifdef GL_TEXTURE_RECTANGLE_ARB
if (paint_gl_target == GL_TEXTURE_RECTANGLE_ARB)
{
GLuint tex;
glGenTextures (1, &tex);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, tex);
glPixelStorei (GL_UNPACK_ROW_LENGTH, tex_width);
glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
glPixelStorei (GL_UNPACK_SKIP_ROWS, 0);
glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0,
GL_ALPHA, tex_width, tex_height,
0, GL_ALPHA, GL_UNSIGNED_BYTE, mask_data);
priv->mask_texture
= cogl_texture_new_from_foreign (tex,
GL_TEXTURE_RECTANGLE_ARB,
tex_width, tex_height,
0, 0,
COGL_PIXEL_FORMAT_A_8);
}
else
#endif /* GL_TEXTURE_RECTANGLE_ARB */
priv->mask_texture = cogl_texture_new_from_data (tex_width, tex_height,
COGL_TEXTURE_NONE,
COGL_PIXEL_FORMAT_A_8,
COGL_PIXEL_FORMAT_ANY,
tex_width,
mask_data);
g_free (mask_data);
priv->mask_width = tex_width;
priv->mask_height = tex_height;
}
}
static void
meta_shaped_texture_paint (ClutterActor *actor)
{
@ -176,20 +331,20 @@ meta_shaped_texture_paint (ClutterActor *actor)
if (priv->create_mipmaps)
paint_tex = meta_texture_tower_get_paint_texture (priv->paint_tower);
else
paint_tex = priv->texture;
paint_tex = clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (stex));
if (paint_tex == COGL_INVALID_HANDLE)
return;
tex_width = priv->tex_width;
tex_height = priv->tex_height;
tex_width = cogl_texture_get_width (paint_tex);
tex_height = cogl_texture_get_height (paint_tex);
if (tex_width == 0 || tex_height == 0) /* no contents yet */
return;
if (priv->mask_texture == COGL_INVALID_HANDLE)
if (priv->rectangles->len < 1)
{
/* Use a single-layer texture if we don't have a mask. */
/* If there are no rectangles use a single-layer texture */
if (priv->material_unshaped == COGL_INVALID_HANDLE)
{
@ -202,6 +357,8 @@ meta_shaped_texture_paint (ClutterActor *actor)
}
else
{
meta_shaped_texture_ensure_mask (stex);
if (priv->material == COGL_INVALID_HANDLE)
{
if (G_UNLIKELY (material_template == COGL_INVALID_HANDLE))
@ -235,7 +392,6 @@ meta_shaped_texture_paint (ClutterActor *actor)
{
int n_rects;
int i;
cairo_rectangle_int_t tex_rect = { 0, 0, tex_width, tex_height };
/* Limit to how many separate rectangles we'll draw; beyond this just
* fall back and draw the whole thing */
@ -253,9 +409,6 @@ meta_shaped_texture_paint (ClutterActor *actor)
cairo_region_get_rectangle (priv->clip_region, i, &rect);
if (!gdk_rectangle_intersect (&tex_rect, &rect, &rect))
continue;
x1 = rect.x;
y1 = rect.y;
x2 = rect.x + rect.width;
@ -291,8 +444,8 @@ meta_shaped_texture_pick (ClutterActor *actor,
MetaShapedTexture *stex = (MetaShapedTexture *) actor;
MetaShapedTexturePrivate *priv = stex->priv;
/* If there is no region then use the regular pick */
if (priv->mask_texture == COGL_INVALID_HANDLE)
/* If there are no rectangles then use the regular pick */
if (priv->rectangles->len < 1)
CLUTTER_ACTOR_CLASS (meta_shaped_texture_parent_class)
->pick (actor, color);
else if (clutter_actor_should_pick_paint (actor))
@ -301,7 +454,7 @@ meta_shaped_texture_pick (ClutterActor *actor,
ClutterActorBox alloc;
guint tex_width, tex_height;
paint_tex = priv->texture;
paint_tex = clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (stex));
if (paint_tex == COGL_INVALID_HANDLE)
return;
@ -312,6 +465,8 @@ meta_shaped_texture_pick (ClutterActor *actor,
if (tex_width == 0 || tex_height == 0) /* no contents yet */
return;
meta_shaped_texture_ensure_mask (stex);
cogl_set_source_color4ub (color->red, color->green, color->blue,
color->alpha);
@ -327,48 +482,19 @@ meta_shaped_texture_pick (ClutterActor *actor,
}
static void
meta_shaped_texture_get_preferred_width (ClutterActor *self,
gfloat for_height,
gfloat *min_width_p,
gfloat *natural_width_p)
meta_shaped_texture_update_area (ClutterX11TexturePixmap *texture,
int x,
int y,
int width,
int height)
{
MetaShapedTexturePrivate *priv;
MetaShapedTexture *stex = (MetaShapedTexture *) texture;
MetaShapedTexturePrivate *priv = stex->priv;
g_return_if_fail (META_IS_SHAPED_TEXTURE (self));
CLUTTER_X11_TEXTURE_PIXMAP_CLASS (meta_shaped_texture_parent_class)->update_area (texture,
x, y, width, height);
priv = META_SHAPED_TEXTURE (self)->priv;
if (min_width_p)
*min_width_p = 0;
if (natural_width_p)
*natural_width_p = priv->tex_width;
}
static void
meta_shaped_texture_get_preferred_height (ClutterActor *self,
gfloat for_width,
gfloat *min_height_p,
gfloat *natural_height_p)
{
MetaShapedTexturePrivate *priv;
g_return_if_fail (META_IS_SHAPED_TEXTURE (self));
priv = META_SHAPED_TEXTURE (self)->priv;
if (min_height_p)
*min_height_p = 0;
if (natural_height_p)
*natural_height_p = priv->tex_height;
}
static gboolean
meta_shaped_texture_get_paint_volume (ClutterActor *self,
ClutterPaintVolume *volume)
{
return clutter_paint_volume_set_from_allocation (volume, self);
meta_texture_tower_update_area (priv->paint_tower, x, y, width, height);
}
ClutterActor *
@ -394,16 +520,34 @@ meta_shaped_texture_set_create_mipmaps (MetaShapedTexture *stex,
if (create_mipmaps != priv->create_mipmaps)
{
CoglHandle base_texture;
priv->create_mipmaps = create_mipmaps;
base_texture = create_mipmaps ?
priv->texture : COGL_INVALID_HANDLE;
clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (stex)) : COGL_INVALID_HANDLE;
meta_texture_tower_set_base_texture (priv->paint_tower, base_texture);
}
}
/* This is a workaround for deficiencies in the hack tower:
*
* When we call clutter_x11_texture_pixmap_set_pixmap(tp, None),
* ClutterX11TexturePixmap knows that it has to get rid of the old texture, but
* clutter_texture_set_cogl_texture(texture, COGL_INVALID_HANDLE) isn't allowed, so
* it grabs the material for the texture and manually sets the texture in it. This means
* that the "cogl-texture" property isn't notified, so we don't find out about it.
*
* And if we keep the CoglX11TexturePixmap around after the X pixmap is freed, then
* we'll trigger X errors when we actually try to free it.
*
* The only correct thing to do here is to change our code to derive
* from ClutterActor and get rid of the inheritance hack tower. Once
* we want to depend on Clutter-1.4 (which has CoglTexturePixmapX11),
* that will be very easy to do.
*/
void
meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex,
CoglHandle mask_texture)
meta_shaped_texture_clear (MetaShapedTexture *stex)
{
MetaShapedTexturePrivate *priv;
@ -411,98 +555,17 @@ meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex,
priv = stex->priv;
if (priv->mask_texture != COGL_INVALID_HANDLE)
{
cogl_handle_unref (priv->mask_texture);
priv->mask_texture = COGL_INVALID_HANDLE;
}
if (mask_texture != COGL_INVALID_HANDLE)
{
priv->mask_texture = mask_texture;
cogl_handle_ref (priv->mask_texture);
}
clutter_actor_queue_redraw (CLUTTER_ACTOR (stex));
}
void
meta_shaped_texture_update_area (MetaShapedTexture *stex,
int x,
int y,
int width,
int height)
{
MetaShapedTexturePrivate *priv;
const cairo_rectangle_int_t clip = { x, y, width, height };
priv = stex->priv;
if (priv->texture == COGL_INVALID_HANDLE)
return;
cogl_texture_pixmap_x11_update_area (priv->texture, x, y, width, height);
meta_texture_tower_update_area (priv->paint_tower, x, y, width, height);
clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stex), &clip);
}
static void
set_cogl_texture (MetaShapedTexture *stex,
CoglHandle cogl_tex)
{
MetaShapedTexturePrivate *priv;
guint width, height;
g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
priv = stex->priv;
if (priv->texture != COGL_INVALID_HANDLE)
cogl_handle_unref (priv->texture);
priv->texture = cogl_tex;
meta_texture_tower_set_base_texture (priv->paint_tower, COGL_INVALID_HANDLE);
if (priv->material != COGL_INVALID_HANDLE)
cogl_material_set_layer (priv->material, 0, cogl_tex);
cogl_material_set_layer (priv->material, 0, COGL_INVALID_HANDLE);
if (priv->material_unshaped != COGL_INVALID_HANDLE)
cogl_material_set_layer (priv->material_unshaped, 0, cogl_tex);
if (cogl_tex != COGL_INVALID_HANDLE)
{
width = cogl_texture_get_width (cogl_tex);
height = cogl_texture_get_height (cogl_tex);
if (width != priv->tex_width ||
height != priv->tex_height)
{
priv->tex_width = width;
priv->tex_height = height;
clutter_actor_queue_relayout (CLUTTER_ACTOR (stex));
}
}
else
{
/* size changed to 0 going to an invalid handle */
priv->tex_width = 0;
priv->tex_height = 0;
clutter_actor_queue_relayout (CLUTTER_ACTOR (stex));
}
clutter_actor_queue_redraw (CLUTTER_ACTOR (stex));
cogl_material_set_layer (priv->material_unshaped, 0, COGL_INVALID_HANDLE);
}
/**
* meta_shaped_texture_set_pixmap:
* @stex: The #MetaShapedTexture
* @pixmap: The pixmap you want the stex to assume
*/
void
meta_shaped_texture_set_pixmap (MetaShapedTexture *stex,
Pixmap pixmap)
meta_shaped_texture_clear_rectangles (MetaShapedTexture *stex)
{
MetaShapedTexturePrivate *priv;
@ -510,42 +573,43 @@ meta_shaped_texture_set_pixmap (MetaShapedTexture *stex,
priv = stex->priv;
if (priv->pixmap == pixmap)
return;
priv->pixmap = pixmap;
if (pixmap != None)
{
CoglContext *ctx =
clutter_backend_get_cogl_context (clutter_get_default_backend ());
set_cogl_texture (stex, cogl_texture_pixmap_x11_new (ctx, pixmap, FALSE, NULL));
}
else
set_cogl_texture (stex, COGL_INVALID_HANDLE);
if (priv->create_mipmaps)
meta_texture_tower_set_base_texture (priv->paint_tower, priv->texture);
g_array_set_size (priv->rectangles, 0);
meta_shaped_texture_dirty_mask (stex);
clutter_actor_queue_redraw (CLUTTER_ACTOR (stex));
}
/**
* meta_shaped_texture_get_texture:
* @stex: The #MetaShapedTexture
*
* Returns: (transfer none): the unshaped texture
*/
CoglHandle
meta_shaped_texture_get_texture (MetaShapedTexture *stex)
void
meta_shaped_texture_add_rectangle (MetaShapedTexture *stex,
const XRectangle *rect)
{
g_return_val_if_fail (META_IS_SHAPED_TEXTURE (stex), COGL_INVALID_HANDLE);
return stex->priv->texture;
g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
meta_shaped_texture_add_rectangles (stex, 1, rect);
}
void
meta_shaped_texture_add_rectangles (MetaShapedTexture *stex,
size_t num_rects,
const XRectangle *rects)
{
MetaShapedTexturePrivate *priv;
g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
priv = stex->priv;
g_array_append_vals (priv->rectangles, rects, num_rects);
meta_shaped_texture_dirty_mask (stex);
clutter_actor_queue_redraw (CLUTTER_ACTOR (stex));
}
/**
* meta_shaped_texture_set_clip_region:
* @stex: a #MetaShapedTexture
* @frame: a #TidyTextureframe
* @clip_region: (transfer full): the region of the texture that
* is visible and should be painted.
* is visible and should be painted. OWNERSHIP IS ASSUMED BY
* THE FUNCTION (for efficiency to avoid a copy.)
*
* Provides a hint to the texture about what areas of the texture
* are not completely obscured and thus need to be painted. This
@ -571,106 +635,5 @@ meta_shaped_texture_set_clip_region (MetaShapedTexture *stex,
priv->clip_region = NULL;
}
if (clip_region)
priv->clip_region = cairo_region_copy (clip_region);
else
priv->clip_region = NULL;
}
/**
* meta_shaped_texture_get_image:
* @stex: A #MetaShapedTexture
* @clip: A clipping rectangle, to help prevent extra processing.
* In the case that the clipping rectangle is partially or fully
* outside the bounds of the texture, the rectangle will be clipped.
*
* Flattens the two layers of the shaped texture into one ARGB32
* image by alpha blending the two images, and returns the flattened
* image.
*
* Returns: (transfer full): a new cairo surface to be freed with
* cairo_surface_destroy().
*/
cairo_surface_t *
meta_shaped_texture_get_image (MetaShapedTexture *stex,
cairo_rectangle_int_t *clip)
{
CoglHandle texture, mask_texture;
cairo_rectangle_int_t texture_rect = { 0, 0, 0, 0 };
cairo_surface_t *surface;
g_return_val_if_fail (META_IS_SHAPED_TEXTURE (stex), NULL);
texture = stex->priv->texture;
if (texture == NULL)
return NULL;
texture_rect.width = cogl_texture_get_width (texture);
texture_rect.height = cogl_texture_get_height (texture);
if (clip != NULL)
{
/* GdkRectangle is just a typedef of cairo_rectangle_int_t,
* so we can use the gdk_rectangle_* APIs on these. */
if (!gdk_rectangle_intersect (&texture_rect, clip, clip))
return NULL;
}
if (clip != NULL)
texture = cogl_texture_new_from_sub_texture (texture,
clip->x,
clip->y,
clip->width,
clip->height);
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
cogl_texture_get_width (texture),
cogl_texture_get_height (texture));
cogl_texture_get_data (texture, CLUTTER_CAIRO_FORMAT_ARGB32,
cairo_image_surface_get_stride (surface),
cairo_image_surface_get_data (surface));
cairo_surface_mark_dirty (surface);
if (clip != NULL)
cogl_object_unref (texture);
mask_texture = stex->priv->mask_texture;
if (mask_texture != COGL_INVALID_HANDLE)
{
cairo_t *cr;
cairo_surface_t *mask_surface;
if (clip != NULL)
mask_texture = cogl_texture_new_from_sub_texture (mask_texture,
clip->x,
clip->y,
clip->width,
clip->height);
mask_surface = cairo_image_surface_create (CAIRO_FORMAT_A8,
cogl_texture_get_width (mask_texture),
cogl_texture_get_height (mask_texture));
cogl_texture_get_data (mask_texture, COGL_PIXEL_FORMAT_A_8,
cairo_image_surface_get_stride (mask_surface),
cairo_image_surface_get_data (mask_surface));
cairo_surface_mark_dirty (mask_surface);
cr = cairo_create (surface);
cairo_set_source_surface (cr, mask_surface, 0, 0);
cairo_set_operator (cr, CAIRO_OPERATOR_DEST_IN);
cairo_paint (cr);
cairo_destroy (cr);
cairo_surface_destroy (mask_surface);
if (clip != NULL)
cogl_object_unref (mask_texture);
}
return surface;
priv->clip_region = clip_region;
}

View File

@ -26,8 +26,14 @@
#ifndef __META_SHAPED_TEXTURE_H__
#define __META_SHAPED_TEXTURE_H__
#include <config.h>
#include <clutter/clutter.h>
#include <X11/Xlib.h>
#ifdef HAVE_GLX_TEXTURE_PIXMAP
#include <clutter/glx/clutter-glx.h>
#else
#include <clutter/x11/clutter-x11.h>
#endif /* HAVE_GLX_TEXTURE_PIXMAP */
G_BEGIN_DECLS
@ -44,12 +50,20 @@ typedef struct _MetaShapedTexturePrivate MetaShapedTexturePrivate;
struct _MetaShapedTextureClass
{
ClutterActorClass parent_class;
#ifdef HAVE_GLX_TEXTURE_PIXMAP
ClutterGLXTexturePixmapClass parent_class;
#else
ClutterX11TexturePixmapClass parent_class;
#endif
};
struct _MetaShapedTexture
{
ClutterActor parent;
#ifdef HAVE_GLX_TEXTURE_PIXMAP
ClutterGLXTexturePixmap parent;
#else
ClutterX11TexturePixmap parent;
#endif
MetaShapedTexturePrivate *priv;
};
@ -61,27 +75,20 @@ ClutterActor *meta_shaped_texture_new (void);
void meta_shaped_texture_set_create_mipmaps (MetaShapedTexture *stex,
gboolean create_mipmaps);
void meta_shaped_texture_update_area (MetaShapedTexture *stex,
int x,
int y,
int width,
int height);
void meta_shaped_texture_clear (MetaShapedTexture *stex);
void meta_shaped_texture_set_pixmap (MetaShapedTexture *stex,
Pixmap pixmap);
void meta_shaped_texture_clear_rectangles (MetaShapedTexture *stex);
CoglHandle meta_shaped_texture_get_texture (MetaShapedTexture *stex);
void meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex,
CoglHandle mask_texture);
void meta_shaped_texture_add_rectangle (MetaShapedTexture *stex,
const XRectangle *rect);
void meta_shaped_texture_add_rectangles (MetaShapedTexture *stex,
size_t num_rects,
const XRectangle *rects);
/* Assumes ownership of clip_region */
void meta_shaped_texture_set_clip_region (MetaShapedTexture *stex,
cairo_region_t *clip_region);
cairo_surface_t * meta_shaped_texture_get_image (MetaShapedTexture *stex,
cairo_rectangle_int_t *clip);
G_END_DECLS
#endif /* __META_SHAPED_TEXTURE_H__ */

View File

@ -1,98 +0,0 @@
/*
* texture rectangle
*
* A small utility function to help create a rectangle texture
*
* Authored By Neil Roberts <neil@linux.intel.com>
*
* Copyright (C) 2011, 2012 Intel Corporation
*
* 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.
*/
#include <config.h>
#include <clutter/clutter.h>
#include "meta-texture-rectangle.h"
CoglTexture *
meta_texture_rectangle_new (unsigned int width,
unsigned int height,
CoglPixelFormat format,
CoglPixelFormat internal_format,
unsigned int rowstride,
const guint8 *data,
GError **error)
{
ClutterBackend *backend =
clutter_get_default_backend ();
CoglContext *context =
clutter_backend_get_cogl_context (backend);
CoglTextureRectangle *tex_rect;
tex_rect = cogl_texture_rectangle_new_with_size (context,
width, height,
internal_format,
error);
if (tex_rect == NULL)
return NULL;
if (data)
cogl_texture_set_region (COGL_TEXTURE (tex_rect),
0, 0, /* src_x/y */
0, 0, /* dst_x/y */
width, height, /* dst_width/height */
width, height, /* width/height */
format,
rowstride,
data);
return COGL_TEXTURE (tex_rect);
}
static void
texture_rectangle_check_cb (CoglTexture *sub_texture,
const float *sub_texture_coords,
const float *meta_coords,
void *user_data)
{
gboolean *result = user_data;
if (cogl_is_texture_rectangle (sub_texture))
*result = TRUE;
}
/* Determines if the given texture is using a rectangle texture as its
* primitive texture type. Eventually this function could be replaced
* with cogl_texture_get_type if Cogl makes that public.
*
* http://git.gnome.org/browse/cogl/commit/?h=8012eee31
*/
gboolean
meta_texture_rectangle_check (CoglTexture *texture)
{
gboolean result = FALSE;
cogl_meta_texture_foreach_in_region (COGL_META_TEXTURE (texture),
0.0f, 0.0f, /* tx_1 / ty_1 */
1.0f, 1.0f, /* tx_2 / ty_2 */
COGL_PIPELINE_WRAP_MODE_REPEAT,
COGL_PIPELINE_WRAP_MODE_REPEAT,
texture_rectangle_check_cb,
&result);
return result;
}

View File

@ -1,47 +0,0 @@
/*
* texture rectangle
*
* A small utility function to help create a rectangle texture
*
* Authored By Neil Roberts <neil@linux.intel.com>
*
* Copyright (C) 2011 Intel Corporation
*
* 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.
*/
#ifndef __META_TEXTURE_RECTANGLE_H__
#define __META_TEXTURE_RECTANGLE_H__
#include <cogl/cogl.h>
G_BEGIN_DECLS
CoglTexture *
meta_texture_rectangle_new (unsigned int width,
unsigned int height,
CoglPixelFormat format,
CoglPixelFormat internal_format,
unsigned int rowstride,
const guint8 *data,
GError **error);
gboolean
meta_texture_rectangle_check (CoglTexture *texture);
G_END_DECLS
#endif /* __META_TEXTURE_RECTANGLE_H__ */

View File

@ -26,7 +26,6 @@
#include <string.h>
#include "meta-texture-tower.h"
#include "meta-texture-rectangle.h"
#ifndef M_LOG2E
#define M_LOG2E 1.4426950408889634074
@ -98,9 +97,37 @@ meta_texture_tower_free (MetaTextureTower *tower)
g_slice_free (MetaTextureTower, tower);
}
#ifdef GL_TEXTURE_RECTANGLE_ARB
static gboolean
texture_is_rectangle (CoglHandle texture)
{
GLuint gl_tex;
GLenum gl_target;
cogl_texture_get_gl_texture (texture, &gl_tex, &gl_target);
return gl_target == GL_TEXTURE_RECTANGLE_ARB;
}
#endif /* GL_TEXTURE_RECTANGLE_ARB */
static void
free_texture (CoglHandle texture)
{
#ifdef GL_TEXTURE_RECTANGLE_ARB
GLuint gl_tex;
GLenum gl_target;
cogl_texture_get_gl_texture (texture, &gl_tex, &gl_target);
if (gl_target == GL_TEXTURE_RECTANGLE_ARB)
glDeleteTextures (1, &gl_tex);
#endif /* GL_TEXTURE_RECTANGLE_ARB */
cogl_handle_unref (texture);
}
/**
* meta_texture_tower_set_base_texture:
* @tower: a #MetaTextureTower
* meta_texture_tower_update_area:
* @tower: a MetaTextureTower
* @texture: the new texture used as a base for scaled down versions
*
* Sets the base texture that is the scaled texture that the
@ -125,7 +152,7 @@ meta_texture_tower_set_base_texture (MetaTextureTower *tower,
{
if (tower->textures[i] != COGL_INVALID_HANDLE)
{
cogl_handle_unref (tower->textures[i]);
free_texture (tower->textures[i]);
tower->textures[i] = COGL_INVALID_HANDLE;
}
@ -163,7 +190,7 @@ meta_texture_tower_set_base_texture (MetaTextureTower *tower,
/**
* meta_texture_tower_update_area:
* @tower: a #MetaTextureTower
* @tower: a MetaTextureTower
* @x: X coordinate of upper left of rectangle that changed
* @y: Y coordinate of upper left of rectangle that changed
* @width: width of rectangle that changed
@ -186,9 +213,6 @@ meta_texture_tower_update_area (MetaTextureTower *tower,
g_return_if_fail (tower != NULL);
if (tower->textures[0] == COGL_INVALID_HANDLE)
return;
texture_width = cogl_texture_get_width (tower->textures[0]);
texture_height = cogl_texture_get_height (tower->textures[0]);
@ -342,11 +366,13 @@ get_paint_level (int width, int height)
return (int)(0.5 + lambda);
}
#ifdef GL_TEXTURE_RECTANGLE_ARB
static gboolean
is_power_of_two (int x)
{
return (x & (x - 1)) == 0;
}
#endif /* GL_TEXTURE_RECTANGLE_ARB */
static void
texture_tower_create_texture (MetaTextureTower *tower,
@ -354,23 +380,30 @@ texture_tower_create_texture (MetaTextureTower *tower,
int width,
int height)
{
#ifdef GL_TEXTURE_RECTANGLE_ARB
if ((!is_power_of_two (width) || !is_power_of_two (height)) &&
meta_texture_rectangle_check (tower->textures[level - 1]))
texture_is_rectangle (tower->textures[level - 1]))
{
tower->textures[level] =
meta_texture_rectangle_new (width, height,
/* data format */
TEXTURE_FORMAT,
/* internal cogl format */
TEXTURE_FORMAT,
/* rowstride */
width * 4,
/* data */
NULL,
/* error */
NULL);
GLuint tex = 0;
glGenTextures (1, &tex);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, tex);
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0,
GL_RGBA, width,height,
#if TEXTURE_FORMAT == COGL_PIXEL_FORMAT_BGRA_8888_PRE
0, GL_BGRA, GL_UNSIGNED_BYTE,
#else /* assume big endian */
0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
#endif
NULL);
tower->textures[level] = cogl_texture_new_from_foreign (tex, GL_TEXTURE_RECTANGLE_ARB,
width, height,
0, 0,
TEXTURE_FORMAT);
}
else
#endif /* GL_TEXTURE_RECTANGLE_ARB */
{
tower->textures[level] = cogl_texture_new_with_size (width, height,
COGL_TEXTURE_NO_AUTO_MIPMAP,
@ -397,7 +430,12 @@ texture_tower_revalidate_fbo (MetaTextureTower *tower,
CoglMatrix modelview;
if (tower->fbos[level] == COGL_INVALID_HANDLE)
tower->fbos[level] = cogl_offscreen_new_to_texture (dest_texture);
{
/* Work around http://bugzilla.openedhand.com/show_bug.cgi?id=2110 */
cogl_flush();
tower->fbos[level] = cogl_offscreen_new_to_texture (dest_texture);
}
if (tower->fbos[level] == COGL_INVALID_HANDLE)
return FALSE;
@ -546,7 +584,7 @@ texture_tower_revalidate_client (MetaTextureTower *tower,
4 * dest_width,
dest_data);
if (dest_texture_height < source_texture_height)
if (dest_height < source_texture_height)
{
g_free (source_tmp1);
g_free (source_tmp2);
@ -566,7 +604,7 @@ texture_tower_revalidate (MetaTextureTower *tower,
/**
* meta_texture_tower_get_paint_texture:
* @tower: a #MetaTextureTower
* @tower: a MetaTextureTower
*
* Gets the texture from the tower that best matches the current
* rendering scale. (On the assumption here the texture is going to

View File

@ -26,31 +26,18 @@ void meta_window_actor_unmaximize (MetaWindowActor *self,
void meta_window_actor_process_damage (MetaWindowActor *self,
XDamageNotifyEvent *event);
void meta_window_actor_pre_paint (MetaWindowActor *self);
void meta_window_actor_post_paint (MetaWindowActor *self);
void meta_window_actor_frame_complete (MetaWindowActor *self,
CoglFrameInfo *frame_info,
gint64 presentation_time);
void meta_window_actor_invalidate_shadow (MetaWindowActor *self);
void meta_window_actor_set_redirected (MetaWindowActor *self, gboolean state);
gboolean meta_window_actor_should_unredirect (MetaWindowActor *self);
void meta_window_actor_get_shape_bounds (MetaWindowActor *self,
cairo_rectangle_int_t *bounds);
gboolean meta_window_actor_effect_in_progress (MetaWindowActor *self);
void meta_window_actor_sync_actor_position (MetaWindowActor *self);
void meta_window_actor_sync_visibility (MetaWindowActor *self);
void meta_window_actor_update_shape (MetaWindowActor *self);
void meta_window_actor_update_shape (MetaWindowActor *self,
gboolean shaped);
void meta_window_actor_update_opacity (MetaWindowActor *self);
void meta_window_actor_mapped (MetaWindowActor *self);
void meta_window_actor_unmapped (MetaWindowActor *self);
void meta_window_actor_set_updates_frozen (MetaWindowActor *self,
gboolean updates_frozen);
cairo_region_t *meta_window_actor_get_obscured_region (MetaWindowActor *self);

File diff suppressed because it is too large Load Diff

View File

@ -7,10 +7,9 @@
#include <gdk/gdk.h> /* for gdk_rectangle_intersect() */
#include "compositor-private.h"
#include "meta-window-actor-private.h"
#include "meta-window-group.h"
#include "meta-background-actor-private.h"
#include "meta-background-actor.h"
struct _MetaWindowGroupClass
{
@ -26,28 +25,9 @@ struct _MetaWindowGroup
G_DEFINE_TYPE (MetaWindowGroup, meta_window_group, CLUTTER_TYPE_GROUP);
/* This file uses pixel-aligned region computation to determine what
* can be clipped out. This only really works if everything is aligned
* to the pixel grid - not scaled or rotated and at integer offsets.
*
* (This could be relaxed - if we turned off filtering for unscaled
* windows then windows would be, by definition aligned to the pixel
* grid. And for rectangular windows without a shape, the outline that
* we draw for an unrotated window is always a rectangle because we
* don't use antialasing for the window boundary - with or without
* filtering, with or without a scale. But figuring out exactly
* what pixels will be drawn by the graphics system in these cases
* gets tricky, so we just go for the easiest part - no scale,
* and at integer offsets.)
*
* The way we check for pixel-aligned is by looking at the
* transformation into screen space of the allocation box of an actor
* and and checking if the corners are "close enough" to integral
* pixel values.
*/
/* The definition of "close enough" to integral pixel values is
* equality when we convert to 24.8 fixed-point.
/* We want to find out if the window is "close enough" to
* 1:1 transform. We do that by converting the transformed coordinates
* to 24.8 fixed-point before checking if they look right.
*/
static inline int
round_to_fixed (float x)
@ -55,24 +35,41 @@ round_to_fixed (float x)
return roundf (x * 256);
}
/* This helper function checks if (according to our fixed point precision)
* the vertices @verts form a box of width @widthf and height @heightf
* located at integral coordinates. These coordinates are returned
* in @x_origin and @y_origin.
/* We can only (easily) apply our logic for figuring out what a window
* obscures if is not transformed. This function does that check and
* as a side effect gets the position of the upper-left corner of the
* actors.
*
* (We actually could handle scaled and non-integrally positioned actors
* too as long as they weren't shaped - no filtering is done at the
* edges so a rectangle stays a rectangle. But the gain from that is
* small, especally since most of our windows are shaped. The simple
* case we handle here is the case that matters when the user is just
* using the desktop normally.)
*
* If we assume that the window group is untransformed (it better not
* be!) then we could also make this determination by checking directly
* if the actor itself is rotated, scaled, or at a non-integral position.
* However, the criterion for "close enough" in that case get trickier,
* since, for example, the allowed rotation depends on the size of
* actor. The approach we take here is to just require everything
* to be within 1/256th of a pixel.
*/
static gboolean
vertices_are_untransformed (ClutterVertex *verts,
float widthf,
float heightf,
int *x_origin,
int *y_origin)
actor_is_untransformed (ClutterActor *actor,
int *x_origin,
int *y_origin)
{
gfloat widthf, heightf;
int width, height;
ClutterVertex verts[4];
int v0x, v0y, v1x, v1y, v2x, v2y, v3x, v3y;
int x, y;
clutter_actor_get_size (actor, &widthf, &heightf);
width = round_to_fixed (widthf); height = round_to_fixed (heightf);
clutter_actor_get_abs_allocation_vertices (actor, verts);
v0x = round_to_fixed (verts[0].x); v0y = round_to_fixed (verts[0].y);
v1x = round_to_fixed (verts[1].x); v1y = round_to_fixed (verts[1].y);
v2x = round_to_fixed (verts[2].x); v2y = round_to_fixed (verts[2].y);
@ -103,117 +100,15 @@ vertices_are_untransformed (ClutterVertex *verts,
return TRUE;
}
/* Check if an actor is "untransformed" - which actually means transformed by
* at most a integer-translation. The integer translation, if any, is returned.
*/
static gboolean
actor_is_untransformed (ClutterActor *actor,
int *x_origin,
int *y_origin)
{
gfloat widthf, heightf;
ClutterVertex verts[4];
clutter_actor_get_size (actor, &widthf, &heightf);
clutter_actor_get_abs_allocation_vertices (actor, verts);
return vertices_are_untransformed (verts, widthf, heightf, x_origin, y_origin);
}
/* Help macros to scale from OpenGL <-1,1> coordinates system to
* window coordinates ranging [0,window-size]. Borrowed from clutter-utils.c
*/
#define MTX_GL_SCALE_X(x,w,v1,v2) ((((((x) / (w)) + 1.0f) / 2.0f) * (v1)) + (v2))
#define MTX_GL_SCALE_Y(y,w,v1,v2) ((v1) - (((((y) / (w)) + 1.0f) / 2.0f) * (v1)) + (v2))
/* Check if we're painting the MetaWindowGroup "untransformed". This can
* differ from the result of actor_is_untransformed(window_group) if we're
* inside a clone paint. The integer translation, if any, is returned.
*/
static gboolean
painting_untransformed (MetaWindowGroup *window_group,
int *x_origin,
int *y_origin)
{
CoglMatrix modelview, projection, modelview_projection;
ClutterVertex vertices[4];
int width, height;
float viewport[4];
int i;
cogl_get_modelview_matrix (&modelview);
cogl_get_projection_matrix (&projection);
cogl_matrix_multiply (&modelview_projection,
&projection,
&modelview);
meta_screen_get_size (window_group->screen, &width, &height);
vertices[0].x = 0;
vertices[0].y = 0;
vertices[0].z = 0;
vertices[1].x = width;
vertices[1].y = 0;
vertices[1].z = 0;
vertices[2].x = 0;
vertices[2].y = height;
vertices[2].z = 0;
vertices[3].x = width;
vertices[3].y = height;
vertices[3].z = 0;
cogl_get_viewport (viewport);
for (i = 0; i < 4; i++)
{
float w = 1;
cogl_matrix_transform_point (&modelview_projection, &vertices[i].x, &vertices[i].y, &vertices[i].z, &w);
vertices[i].x = MTX_GL_SCALE_X (vertices[i].x, w,
viewport[2], viewport[0]);
vertices[i].y = MTX_GL_SCALE_Y (vertices[i].y, w,
viewport[3], viewport[1]);
}
return vertices_are_untransformed (vertices, width, height, x_origin, y_origin);
}
static void
meta_window_group_paint (ClutterActor *actor)
{
cairo_region_t *visible_region;
ClutterActor *stage;
cairo_rectangle_int_t visible_rect;
GList *children, *l;
int paint_x_origin, paint_y_origin;
int actor_x_origin, actor_y_origin;
int paint_x_offset, paint_y_offset;
MetaWindowGroup *window_group = META_WINDOW_GROUP (actor);
MetaCompScreen *info = meta_screen_get_compositor_data (window_group->screen);
/* Normally we expect an actor to be drawn at it's position on the screen.
* However, if we're inside the paint of a ClutterClone, that won't be the
* case and we need to compensate. We look at the position of the window
* group under the current model-view matrix and the position of the actor.
* If they are both simply integer translations, then we can compensate
* easily, otherwise we give up.
*
* Possible cleanup: work entirely in paint space - we can compute the
* combination of the model-view matrix with the local matrix for each child
* actor and get a total transformation for that actor for how we are
* painting currently, and never worry about how actors are positioned
* on the stage.
*/
if (!painting_untransformed (window_group, &paint_x_origin, &paint_y_origin) ||
!actor_is_untransformed (actor, &actor_x_origin, &actor_y_origin))
{
CLUTTER_ACTOR_CLASS (meta_window_group_parent_class)->paint (actor);
return;
}
paint_x_offset = paint_x_origin - actor_x_origin;
paint_y_offset = paint_y_origin - actor_y_origin;
cairo_region_t *visible_region;
GLboolean scissor_test;
cairo_rectangle_int_t screen_rect = { 0 };
cairo_rectangle_int_t scissor_rect;
GList *children, *l;
/* We walk the list from top to bottom (opposite of painting order),
* and subtract the opaque area of each window out of the visible
@ -222,65 +117,53 @@ meta_window_group_paint (ClutterActor *actor)
children = clutter_container_get_children (CLUTTER_CONTAINER (actor));
children = g_list_reverse (children);
/* Get the clipped redraw bounds from Clutter so that we can avoid
* painting shadows on windows that don't need to be painted in this
* frame. In the case of a multihead setup with mismatched monitor
* sizes, we could intersect this with an accurate union of the
* monitors to avoid painting shadows that are visible only in the
* holes. */
stage = clutter_actor_get_stage (actor);
clutter_stage_get_redraw_clip_bounds (CLUTTER_STAGE (stage),
&visible_rect);
/* Start off with the full screen area (for a multihead setup, we
* might want to use a more accurate union of the monitors to avoid
* painting in holes from mismatched monitor sizes. That's just an
* optimization, however.)
*/
meta_screen_get_size (window_group->screen, &screen_rect.width, &screen_rect.height);
visible_region = cairo_region_create_rectangle (&visible_rect);
/* When doing a partial stage paint, Clutter will set the GL scissor
* box to the clip rectangle for the partial repaint. We combine the screen
* rectangle with the scissor box to get the region we need to
* paint. (Strangely, the scissor box sometimes seems to be bigger
* than the stage ... Clutter should probably be clampimg)
*/
glGetBooleanv (GL_SCISSOR_TEST, &scissor_test);
if (info->unredirected_window != NULL)
if (scissor_test)
{
cairo_rectangle_int_t unredirected_rect;
MetaWindow *window = meta_window_actor_get_meta_window (info->unredirected_window);
GLint scissor_box[4];
glGetIntegerv (GL_SCISSOR_BOX, scissor_box);
meta_window_get_outer_rect (window, (MetaRectangle *)&unredirected_rect);
cairo_region_subtract_rectangle (visible_region, &unredirected_rect);
scissor_rect.x = scissor_box[0];
scissor_rect.y = screen_rect.height - (scissor_box[1] + scissor_box[3]);
scissor_rect.width = scissor_box[2];
scissor_rect.height = scissor_box[3];
gdk_rectangle_intersect (&scissor_rect, &screen_rect, &scissor_rect);
}
else
{
scissor_rect = screen_rect;
}
visible_region = cairo_region_create_rectangle (&scissor_rect);
for (l = children; l; l = l->next)
{
if (!CLUTTER_ACTOR_IS_VISIBLE (l->data))
continue;
if (l->data == 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 (l->data))
continue;
if (META_IS_WINDOW_ACTOR (l->data))
{
MetaWindowActor *window_actor = l->data;
int x, y;
gboolean x, y;
if (!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 (visible_region, - x, - y);
@ -299,17 +182,7 @@ meta_window_group_paint (ClutterActor *actor)
else if (META_IS_BACKGROUND_ACTOR (l->data))
{
MetaBackgroundActor *background_actor = l->data;
int x, y;
if (!actor_is_untransformed (CLUTTER_ACTOR (background_actor), &x, &y))
continue;
x += paint_x_offset;
y += paint_y_offset;
cairo_region_translate (visible_region, - x, - y);
meta_background_actor_set_visible_region (background_actor, visible_region);
cairo_region_translate (visible_region, x, y);
}
}
@ -325,6 +198,7 @@ meta_window_group_paint (ClutterActor *actor)
if (META_IS_WINDOW_ACTOR (l->data))
{
MetaWindowActor *window_actor = l->data;
window_actor = l->data;
meta_window_actor_reset_visible_regions (window_actor);
}
else if (META_IS_BACKGROUND_ACTOR (l->data))

View File

@ -16,9 +16,3 @@ pkglib_LTLIBRARIES = default.la
install-exec-hook:
-rm $(DESTDIR)$(pkglibdir)/*.a
-rm $(DESTDIR)$(pkglibdir)/*.la
# Since we removed the .la file, 'make uninstall' doesn't work properly,
# since it counts on libtool to remove the .la files, so just kill the
# .so file manually.
uninstall-local:
-rm -f $(DESTDIR)$(pkglibdir)/default.so

View File

@ -112,6 +112,8 @@ struct _MetaDefaultPluginPrivate
ClutterActor *desktop2;
MetaPluginInfo info;
gboolean debug_mode : 1;
};
/*
@ -180,6 +182,34 @@ meta_default_plugin_get_property (GObject *object,
}
}
static void
start (MetaPlugin *plugin)
{
MetaDefaultPluginPrivate *priv = META_DEFAULT_PLUGIN (plugin)->priv;
guint destroy_timeout = DESTROY_TIMEOUT;
guint minimize_timeout = MINIMIZE_TIMEOUT;
guint maximize_timeout = MAXIMIZE_TIMEOUT;
guint map_timeout = MAP_TIMEOUT;
guint switch_timeout = SWITCH_TIMEOUT;
if (meta_plugin_debug_mode (plugin))
{
g_debug ("Plugin %s: Entering debug mode.", priv->info.name);
priv->debug_mode = TRUE;
/*
* Double the effect duration to make them easier to observe.
*/
destroy_timeout *= 2;
minimize_timeout *= 2;
maximize_timeout *= 2;
map_timeout *= 2;
switch_timeout *= 2;
}
}
static void
meta_default_plugin_class_init (MetaDefaultPluginClass *klass)
{
@ -191,6 +221,7 @@ meta_default_plugin_class_init (MetaDefaultPluginClass *klass)
gobject_class->set_property = meta_default_plugin_set_property;
gobject_class->get_property = meta_default_plugin_get_property;
plugin_class->start = start;
plugin_class->map = map;
plugin_class->minimize = minimize;
plugin_class->maximize = maximize;
@ -253,8 +284,7 @@ on_switch_workspace_effect_complete (ClutterTimeline *timeline, gpointer data)
{
MetaPlugin *plugin = META_PLUGIN (data);
MetaDefaultPluginPrivate *priv = META_DEFAULT_PLUGIN (plugin)->priv;
MetaScreen *screen = meta_plugin_get_screen (plugin);
GList *l = meta_get_window_actors (screen);
GList *l = meta_plugin_get_window_actors (plugin);
while (l)
{
@ -287,7 +317,6 @@ switch_workspace (MetaPlugin *plugin,
gint from, gint to,
MetaMotionDirection direction)
{
MetaScreen *screen;
MetaDefaultPluginPrivate *priv = META_DEFAULT_PLUGIN (plugin)->priv;
GList *l;
ClutterActor *workspace0 = clutter_group_new ();
@ -296,13 +325,11 @@ switch_workspace (MetaPlugin *plugin,
int screen_width, screen_height;
ClutterAnimation *animation;
screen = meta_plugin_get_screen (plugin);
stage = meta_get_stage_for_screen (screen);
meta_screen_get_size (screen,
&screen_width,
&screen_height);
stage = meta_plugin_get_stage (plugin);
meta_plugin_query_screen_size (plugin,
&screen_width,
&screen_height);
clutter_actor_set_anchor_point (workspace1,
screen_width,
screen_height);
@ -321,7 +348,7 @@ switch_workspace (MetaPlugin *plugin,
return;
}
l = g_list_last (meta_get_window_actors (screen));
l = g_list_last (meta_plugin_get_window_actors (plugin));
while (l)
{
@ -419,19 +446,12 @@ static void
minimize (MetaPlugin *plugin, MetaWindowActor *window_actor)
{
MetaWindowType type;
MetaRectangle icon_geometry;
MetaWindow *meta_window = meta_window_actor_get_meta_window (window_actor);
ClutterActor *actor = CLUTTER_ACTOR (window_actor);
type = meta_window_get_window_type (meta_window);
if (!meta_window_get_icon_geometry(meta_window, &icon_geometry))
{
icon_geometry.x = 0;
icon_geometry.y = 0;
}
if (type == META_WINDOW_NORMAL)
{
ClutterAnimation *animation;
@ -448,8 +468,6 @@ minimize (MetaPlugin *plugin, MetaWindowActor *window_actor)
MINIMIZE_TIMEOUT,
"scale-x", 0.0,
"scale-y", 0.0,
"x", (double)icon_geometry.x,
"y", (double)icon_geometry.y,
NULL);
apriv->tml_minimize = clutter_animation_get_timeline (animation);
data->plugin = plugin;

View File

@ -43,17 +43,34 @@
/* Optimium performance seems to be with MAX_CHUNK_RECTANGLES=4; 8 is about 10% slower.
* But using 8 may be more robust to systems with slow malloc(). */
#define MAX_CHUNK_RECTANGLES 8
#define MAX_LEVELS 16
void
typedef struct
{
/* To merge regions in binary tree order, we need to keep track of
* the regions that we've already merged together at different
* levels of the tree. We fill in an array in the pattern:
*
* |a |
* |b |a |
* |c | |ab |
* |d |c |ab |
* |e | | |abcd|
*/
cairo_region_t *levels[MAX_LEVELS];
int n_levels;
} MetaRegionBuilder;
static void
meta_region_builder_init (MetaRegionBuilder *builder)
{
int i;
for (i = 0; i < META_REGION_BUILDER_MAX_LEVELS; i++)
for (i = 0; i < MAX_LEVELS; i++)
builder->levels[i] = NULL;
builder->n_levels = 1;
}
void
static void
meta_region_builder_add_rectangle (MetaRegionBuilder *builder,
int x,
int y,
@ -78,7 +95,7 @@ meta_region_builder_add_rectangle (MetaRegionBuilder *builder,
{
if (builder->levels[i] == NULL)
{
if (i < META_REGION_BUILDER_MAX_LEVELS)
if (i < MAX_LEVELS)
{
builder->levels[i] = builder->levels[i - 1];
builder->levels[i - 1] = NULL;
@ -98,7 +115,7 @@ meta_region_builder_add_rectangle (MetaRegionBuilder *builder,
}
}
cairo_region_t *
static cairo_region_t *
meta_region_builder_finish (MetaRegionBuilder *builder)
{
cairo_region_t *result = NULL;

View File

@ -63,32 +63,6 @@ struct _MetaRegionIterator {
cairo_rectangle_int_t next_rectangle;
};
typedef struct _MetaRegionBuilder MetaRegionBuilder;
#define META_REGION_BUILDER_MAX_LEVELS 16
struct _MetaRegionBuilder {
/* To merge regions in binary tree order, we need to keep track of
* the regions that we've already merged together at different
* levels of the tree. We fill in an array in the pattern:
*
* |a |
* |b |a |
* |c | |ab |
* |d |c |ab |
* |e | | |abcd|
*/
cairo_region_t *levels[META_REGION_BUILDER_MAX_LEVELS];
int n_levels;
};
void meta_region_builder_init (MetaRegionBuilder *builder);
void meta_region_builder_add_rectangle (MetaRegionBuilder *builder,
int x,
int y,
int width,
int height);
cairo_region_t * meta_region_builder_finish (MetaRegionBuilder *builder);
void meta_region_iterator_init (MetaRegionIterator *iter,
cairo_region_t *region);
gboolean meta_region_iterator_at_end (MetaRegionIterator *iter);

400
src/core/all-keybindings.h Normal file
View File

@ -0,0 +1,400 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (C) 2008 Thomas Thurman
*
* 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.
*/
/**
* A list of screen keybinding information.
*
* Each action which can have a keystroke bound to it is listed below.
* To use this file, define keybind() to be a seven-argument macro (you can
* throw any of the arguments you please away), include this file,
* and then undefine the macro again.
*
* (If you aren't familiar with this technique, sometimes called "x-macros",
* see DDJ of May 2001: <http://www.ddj.com/cpp/184401387>.)
*
* This makes it possible to keep all information about all the keybindings
* in the same place. The only exception is the code to run when an action
* is actually invoked; while we *could* have put that in this file, it would
* have made debugging ridiculously difficult. Instead, each action should
* have a corresponding static function named handle_<name>() in
* keybindings.c.
*
* The arguments to keybind() are:
* 1) the name of the binding; a bareword identifier
* (it's fine if it happens to clash with a C reserved word)
* 2) the name of the function which implements it.
* Clearly we could have guessed this from the binding very often,
* but we choose to write it in full for the benefit of grep.
* 3) an integer parameter to pass to the handler
* 4) a set of boolean flags, ORed together:
* BINDING_PER_WINDOW - this is a window-based binding.
* It is only valid if there is a
* current window, and will operate in
* some way on that window.
* BINDING_REVERSES - the binding can reverse if you hold down Shift
* BINDING_IS_REVERSED - the same, but the senses are reversed from the
* handler's point of view (let me know if I should
* explain this better)
* or 0 if no flag applies.
*
* 5) a string representing the default binding.
* If this is NULL, the action is unbound by default.
* Please use NULL and not "disabled".
* 6) a short description.
* It must be marked translatable (i.e. inside "_(...)").
*
* Don't try to do XML entity escaping anywhere in the strings.
*/
#ifndef keybind
#error "keybind () must be defined when you include screen-bindings.h"
#endif
/***********************************/
#ifndef _BINDINGS_DEFINED_CONSTANTS
#define _BINDINGS_DEFINED_CONSTANTS 1
#define BINDING_PER_WINDOW 0x01
#define BINDING_REVERSES 0x02
#define BINDING_IS_REVERSED 0x04
#endif /* _BINDINGS_DEFINED_CONSTANTS */
/***********************************/
/* convenience, since in this file they must always be set together */
#define REVERSES_AND_REVERSED (BINDING_REVERSES | BINDING_IS_REVERSED)
keybind (switch_to_workspace_1, handle_switch_to_workspace, 0, 0, NULL,
_("Switch to workspace 1"))
keybind (switch_to_workspace_2, handle_switch_to_workspace, 1, 0, NULL,
_("Switch to workspace 2"))
keybind (switch_to_workspace_3, handle_switch_to_workspace, 2, 0, NULL,
_("Switch to workspace 3"))
keybind (switch_to_workspace_4, handle_switch_to_workspace, 3, 0, NULL,
_("Switch to workspace 4"))
keybind (switch_to_workspace_5, handle_switch_to_workspace, 4, 0, NULL,
_("Switch to workspace 5"))
keybind (switch_to_workspace_6, handle_switch_to_workspace, 5, 0, NULL,
_("Switch to workspace 6"))
keybind (switch_to_workspace_7, handle_switch_to_workspace, 6, 0, NULL,
_("Switch to workspace 7"))
keybind (switch_to_workspace_8, handle_switch_to_workspace, 7, 0, NULL,
_("Switch to workspace 8"))
keybind (switch_to_workspace_9, handle_switch_to_workspace, 8, 0, NULL,
_("Switch to workspace 9"))
keybind (switch_to_workspace_10, handle_switch_to_workspace, 9, 0, NULL,
_("Switch to workspace 10"))
keybind (switch_to_workspace_11, handle_switch_to_workspace, 10, 0, NULL,
_("Switch to workspace 11"))
keybind (switch_to_workspace_12, handle_switch_to_workspace, 11, 0, NULL,
_("Switch to workspace 12"))
/* META_MOTION_* are negative, and so distinct from workspace numbers,
* which are always zero or positive.
* If you make use of these constants, you will need to include workspace.h
* (which you're probably using already for other reasons anyway).
* If your definition of keybind() throws them away, you don't need to include
* workspace.h, of course.
*/
keybind (switch_to_workspace_left, handle_switch_to_workspace,
META_MOTION_LEFT, 0, "<Control><Alt>Left",
_("Switch to workspace on the left of the current workspace"))
keybind (switch_to_workspace_right, handle_switch_to_workspace,
META_MOTION_RIGHT, 0, "<Control><Alt>Right",
_("Switch to workspace on the right of the current workspace"))
keybind (switch_to_workspace_up, handle_switch_to_workspace,
META_MOTION_UP, 0, "<Control><Alt>Up",
_("Switch to workspace above the current workspace"))
keybind (switch_to_workspace_down, handle_switch_to_workspace,
META_MOTION_DOWN, 0, "<Control><Alt>Down",
_("Switch to workspace below the current workspace"))
/***********************************/
/* The ones which have inverses. These can't be bound to any keystroke
* containing Shift because Shift will invert their "backward" state.
*
* TODO: "NORMAL" and "DOCKS" should be renamed to the same name as their
* action, for obviousness.
*
* TODO: handle_switch and handle_cycle should probably really be the
* same function checking a bit in the parameter for difference.
*/
keybind (switch_group, handle_switch, META_TAB_LIST_GROUP,
BINDING_REVERSES, "<Alt>Above_Tab",
_("Move between windows of an application, using a popup window"))
keybind (switch_group_backward, handle_switch, META_TAB_LIST_GROUP,
REVERSES_AND_REVERSED, NULL,
_("Move backward between windows of an application, "
"using a popup window"))
keybind (switch_windows, handle_switch, META_TAB_LIST_NORMAL,
BINDING_REVERSES, "<Alt>Tab",
_("Move between windows, using a popup window"))
keybind (switch_windows_backward, handle_switch, META_TAB_LIST_NORMAL,
REVERSES_AND_REVERSED, NULL,
_("Move backward between windows, using a popup window"))
keybind (switch_panels, handle_switch, META_TAB_LIST_DOCKS,
BINDING_REVERSES, "<Control><Alt>Tab",
_("Move between panels and the desktop, using a popup window"))
keybind (switch_panels_backward, handle_switch, META_TAB_LIST_DOCKS,
REVERSES_AND_REVERSED, NULL,
_("Move backward between panels and the desktop, "
"using a popup window"))
keybind (cycle_group, handle_cycle, META_TAB_LIST_GROUP,
BINDING_REVERSES, "<Alt>F6",
_("Move between windows of an application immediately"))
keybind (cycle_group_backward, handle_cycle, META_TAB_LIST_GROUP,
REVERSES_AND_REVERSED, NULL,
_("Move backward between windows of an application immediately"))
keybind (cycle_windows, handle_cycle, META_TAB_LIST_NORMAL,
BINDING_REVERSES, "<Alt>Escape",
_("Move between windows immediately"))
keybind (cycle_windows_backward, handle_cycle, META_TAB_LIST_NORMAL,
REVERSES_AND_REVERSED, NULL,
_("Move backward between windows immediately"))
keybind (cycle_panels, handle_cycle, META_TAB_LIST_DOCKS,
BINDING_REVERSES, "<Control><Alt>Escape",
_("Move between panels and the desktop immediately"))
keybind (cycle_panels_backward, handle_cycle, META_TAB_LIST_DOCKS,
REVERSES_AND_REVERSED, NULL,
_("Move backward between panels and the desktop immediately"))
/***********************************/
/* These two are special pseudo-bindings that are provided for allowing
* custom handlers, but will never be bound to a key. While a tab
* grab is in effect, they are invoked for releasing the primary modifier
* or pressing some unbound key, respectively.
*/
keybind (tab_popup_select, handle_tab_popup_select, 0, 0, NULL,
"Select window from tab popup")
keybind (tab_popup_cancel, handle_tab_popup_cancel, 0, 0, NULL,
"Cancel tab popup")
/***********************************/
keybind (show_desktop, handle_show_desktop, 0, 0, "<Control><Alt>d",
_("Hide all normal windows and set focus to the desktop"))
keybind (panel_main_menu, handle_panel,
META_KEYBINDING_ACTION_PANEL_MAIN_MENU, 0, "<Alt>F1",
_("Show the panel's main menu"))
keybind (panel_run_dialog, handle_panel,
META_KEYBINDING_ACTION_PANEL_RUN_DIALOG, 0, "<Alt>F2",
_("Show the panel's \"Run Application\" dialog box"))
keybind (toggle_recording, handle_toggle_recording, 0, 0, "<Control><Shift><Alt>r",
_("Start or stop recording the session"))
/* Yes, the param is offset by one. Historical reasons. (Maybe worth fixing
* at some point.) The description is NULL here because the stanza is
* irregularly shaped in mutter.schemas.in. This will probably be fixed
* as well.
*/
keybind (run_command_1, handle_run_command, 0, 0, NULL, NULL)
keybind (run_command_2, handle_run_command, 1, 0, NULL, NULL)
keybind (run_command_3, handle_run_command, 2, 0, NULL, NULL)
keybind (run_command_4, handle_run_command, 3, 0, NULL, NULL)
keybind (run_command_5, handle_run_command, 4, 0, NULL, NULL)
keybind (run_command_6, handle_run_command, 5, 0, NULL, NULL)
keybind (run_command_7, handle_run_command, 6, 0, NULL, NULL)
keybind (run_command_8, handle_run_command, 7, 0, NULL, NULL)
keybind (run_command_9, handle_run_command, 8, 0, NULL, NULL)
keybind (run_command_10, handle_run_command, 9, 0, NULL, NULL)
keybind (run_command_11, handle_run_command, 10, 0, NULL, NULL)
keybind (run_command_12, handle_run_command, 11, 0, NULL, NULL)
keybind (run_command_13, handle_run_command, 12, 0, NULL, NULL)
keybind (run_command_14, handle_run_command, 13, 0, NULL, NULL)
keybind (run_command_15, handle_run_command, 14, 0, NULL, NULL)
keybind (run_command_16, handle_run_command, 15, 0, NULL, NULL)
keybind (run_command_17, handle_run_command, 16, 0, NULL, NULL)
keybind (run_command_18, handle_run_command, 17, 0, NULL, NULL)
keybind (run_command_19, handle_run_command, 18, 0, NULL, NULL)
keybind (run_command_20, handle_run_command, 19, 0, NULL, NULL)
keybind (run_command_21, handle_run_command, 20, 0, NULL, NULL)
keybind (run_command_22, handle_run_command, 21, 0, NULL, NULL)
keybind (run_command_23, handle_run_command, 22, 0, NULL, NULL)
keybind (run_command_24, handle_run_command, 23, 0, NULL, NULL)
keybind (run_command_25, handle_run_command, 24, 0, NULL, NULL)
keybind (run_command_26, handle_run_command, 25, 0, NULL, NULL)
keybind (run_command_27, handle_run_command, 26, 0, NULL, NULL)
keybind (run_command_28, handle_run_command, 27, 0, NULL, NULL)
keybind (run_command_29, handle_run_command, 28, 0, NULL, NULL)
keybind (run_command_30, handle_run_command, 29, 0, NULL, NULL)
keybind (run_command_31, handle_run_command, 30, 0, NULL, NULL)
keybind (run_command_32, handle_run_command, 31, 0, NULL, NULL)
keybind (run_command_screenshot, handle_run_command, 32, 0, "Print",
_("Take a screenshot"))
keybind (run_command_window_screenshot, handle_run_command, 33, 0,"<Alt>Print",
_("Take a screenshot of a window"))
keybind (run_command_terminal, handle_run_terminal, 0, 0, NULL, _("Run a terminal"))
/* No description because this is undocumented */
keybind (set_spew_mark, handle_set_spew_mark, 0, 0, NULL, NULL)
#undef REVERSES_AND_REVERSED
/************************ PER WINDOW BINDINGS ************************/
/* These take a window as an extra parameter; they have no effect
* if no window is active.
*/
keybind (activate_window_menu, handle_activate_window_menu, 0,
BINDING_PER_WINDOW, "<Alt>space",
_("Activate the window menu"))
keybind (toggle_fullscreen, handle_toggle_fullscreen, 0, BINDING_PER_WINDOW,
NULL,
_("Toggle fullscreen mode"))
keybind (toggle_maximized, handle_toggle_maximized, 0, BINDING_PER_WINDOW, "<Alt>F10",
_("Toggle maximization state"))
keybind (toggle_above, handle_toggle_above, 0, BINDING_PER_WINDOW, NULL,
_("Toggle whether a window will always be visible over other windows"))
keybind (maximize, handle_maximize, 0, BINDING_PER_WINDOW, NULL,
_("Maximize window"))
keybind (unmaximize, handle_unmaximize, 0, BINDING_PER_WINDOW, "<Alt>F5",
_("Restore window"))
keybind (toggle_shaded, handle_toggle_shaded, 0, BINDING_PER_WINDOW, NULL,
_("Toggle shaded state"))
keybind (minimize, handle_minimize, 0, BINDING_PER_WINDOW, "<Alt>F9",
_("Minimize window"))
keybind (close, handle_close, 0, BINDING_PER_WINDOW, "<Alt>F4",
_("Close window"))
keybind (begin_move, handle_begin_move, 0, BINDING_PER_WINDOW, "<Alt>F7",
_("Move window"))
keybind (begin_resize, handle_begin_resize, 0, BINDING_PER_WINDOW, "<Alt>F8",
_("Resize window"))
keybind (toggle_on_all_workspaces, handle_toggle_on_all_workspaces, 0,
BINDING_PER_WINDOW, NULL,
_("Toggle whether window is on all workspaces or just one"))
keybind (move_to_workspace_1, handle_move_to_workspace, 0, BINDING_PER_WINDOW,
NULL,
_("Move window to workspace 1"))
keybind (move_to_workspace_2, handle_move_to_workspace, 1, BINDING_PER_WINDOW,
NULL,
_("Move window to workspace 2"))
keybind (move_to_workspace_3, handle_move_to_workspace, 2, BINDING_PER_WINDOW,
NULL,
_("Move window to workspace 3"))
keybind (move_to_workspace_4, handle_move_to_workspace, 3, BINDING_PER_WINDOW,
NULL,
_("Move window to workspace 4"))
keybind (move_to_workspace_5, handle_move_to_workspace, 4, BINDING_PER_WINDOW,
NULL,
_("Move window to workspace 5"))
keybind (move_to_workspace_6, handle_move_to_workspace, 5, BINDING_PER_WINDOW,
NULL,
_("Move window to workspace 6"))
keybind (move_to_workspace_7, handle_move_to_workspace, 6, BINDING_PER_WINDOW,
NULL,
_("Move window to workspace 7"))
keybind (move_to_workspace_8, handle_move_to_workspace, 7, BINDING_PER_WINDOW,
NULL,
_("Move window to workspace 8"))
keybind (move_to_workspace_9, handle_move_to_workspace, 8, BINDING_PER_WINDOW,
NULL,
_("Move window to workspace 9"))
keybind (move_to_workspace_10, handle_move_to_workspace, 9, BINDING_PER_WINDOW,
NULL,
_("Move window to workspace 10"))
keybind (move_to_workspace_11, handle_move_to_workspace, 10, BINDING_PER_WINDOW,
NULL,
_("Move window to workspace 11"))
keybind (move_to_workspace_12, handle_move_to_workspace, 11, BINDING_PER_WINDOW,
NULL,
_("Move window to workspace 12"))
/* META_MOTION_* are negative, and so distinct from workspace numbers,
* which are always zero or positive.
* If you make use of these constants, you will need to include workspace.h
* (which you're probably using already for other reasons anyway).
* If your definition of keybind() throws them away, you don't need to include
* workspace.h, of course.
*/
keybind (move_to_workspace_left, handle_move_to_workspace,
META_MOTION_LEFT, BINDING_PER_WINDOW, "<Control><Shift><Alt>Left",
_("Move window one workspace to the left"))
keybind (move_to_workspace_right, handle_move_to_workspace,
META_MOTION_RIGHT, BINDING_PER_WINDOW, "<Control><Shift><Alt>Right",
_("Move window one workspace to the right"))
keybind (move_to_workspace_up, handle_move_to_workspace,
META_MOTION_UP, BINDING_PER_WINDOW, "<Control><Shift><Alt>Up",
_("Move window one workspace up"))
keybind (move_to_workspace_down, handle_move_to_workspace,
META_MOTION_DOWN, BINDING_PER_WINDOW, "<Control><Shift><Alt>Down",
_("Move window one workspace down"))
keybind (raise_or_lower, handle_raise_or_lower, 0, BINDING_PER_WINDOW, NULL,
_("Raise window if it's covered by another window, otherwise lower it"))
keybind (raise, handle_raise, 0, BINDING_PER_WINDOW, NULL,
_("Raise window above other windows"))
keybind (lower, handle_lower, 0, BINDING_PER_WINDOW, NULL,
_("Lower window below other windows"))
keybind (maximize_vertically, handle_maximize_vertically, 0,
BINDING_PER_WINDOW, NULL,
_("Maximize window vertically"))
keybind (maximize_horizontally, handle_maximize_horizontally, 0,
BINDING_PER_WINDOW, NULL,
_("Maximize window horizontally"))
keybind (move_to_corner_nw, handle_move_to_corner_nw, 0,
BINDING_PER_WINDOW, NULL,
_("Move window to north-west (top left) corner"))
keybind (move_to_corner_ne, handle_move_to_corner_ne, 0,
BINDING_PER_WINDOW, NULL,
_("Move window to north-east (top right) corner"))
keybind (move_to_corner_sw, handle_move_to_corner_sw, 0,
BINDING_PER_WINDOW, NULL,
_("Move window to south-west (bottom left) corner"))
keybind (move_to_corner_se, handle_move_to_corner_se, 0,
BINDING_PER_WINDOW, NULL,
_("Move window to south-east (bottom right) corner"))
keybind (move_to_side_n, handle_move_to_side_n, 0,
BINDING_PER_WINDOW, NULL,
_("Move window to north (top) side of screen"))
keybind (move_to_side_s, handle_move_to_side_s, 0,
BINDING_PER_WINDOW, NULL,
_("Move window to south (bottom) side of screen"))
keybind (move_to_side_e, handle_move_to_side_e, 0,
BINDING_PER_WINDOW, NULL,
_("Move window to east (right) side of screen"))
keybind (move_to_side_w, handle_move_to_side_w, 0,
BINDING_PER_WINDOW, NULL,
_("Move window to west (left) side of screen"))
keybind (move_to_center, handle_move_to_center, 0,
BINDING_PER_WINDOW, NULL,
_("Move window to center of screen"))
/* eof all-keybindings.h */

View File

@ -23,8 +23,7 @@
*/
/**
* SECTION:Bell
* @short_description: Ring the bell or flash the screen
* \file bell.c Ring the bell or flash the screen
*
* Sometimes, X programs "ring the bell", whatever that means. Mutter lets
* the user configure the bell to be audible or visible (aka visual), and
@ -58,10 +57,6 @@
#endif
/**
* bell_flash_screen:
* @display: The display which owns the screen (rather redundant)
* @screen: The screen to flash
*
* Flashes one entire screen. This is done by making a window the size of the
* whole screen (or reusing the old one, if it's still around), mapping it,
* painting it white and then black, and then unmapping it. We set saveunder so
@ -70,12 +65,14 @@
* Unlike frame flashes, we don't do fullscreen flashes with a timeout; rather,
* we do them in one go, because we don't have to rely on the theme code
* redrawing the frame for us in order to do the flash.
*/
/*
* Bug: The way I read it, this appears not to do the flash
*
* \param display The display which owns the screen (rather redundant)
* \param screen The screen to flash
*
* \bug The way I read it, this appears not to do the flash
* the first time we flash a particular display. Am I wrong?
*
* Bug: This appears to destroy our current XSync status.
* \bug This appears to destroy our current XSync status.
*/
static void
bell_flash_screen (MetaDisplay *display,
@ -133,22 +130,21 @@ bell_flash_screen (MetaDisplay *display,
XFreeGC (display->xdisplay, gc);
}
if (meta_prefs_get_focus_mode () != G_DESKTOP_FOCUS_MODE_CLICK &&
if (meta_prefs_get_focus_mode () != META_FOCUS_MODE_CLICK &&
!display->mouse_mode)
meta_display_increment_focus_sentinel (display);
XFlush (display->xdisplay);
}
/**
* bell_flash_fullscreen:
* @display: The display the event came in on
* @xkb_ev: The bell event
*
* Flashes one screen, or all screens, in response to a bell event.
* If the event is on a particular window, flash the screen that
* window is on. Otherwise, flash every screen on this display.
*
* If the configure script found we had no XKB, this does not exist.
*
* \param display The display the event came in on
* \param xkb_ev The bell event
*/
#ifdef HAVE_XKB
static void
@ -186,21 +182,17 @@ bell_flash_fullscreen (MetaDisplay *display,
}
/**
* bell_unflash_frame:
* @data: The frame to unflash, cast to a gpointer so it can go into
* a callback function.
*
* Makes a frame be not flashed; this is the timeout half of
* bell_flash_window_frame(). This is done simply by clearing the
* flash flag and queuing a redraw of the frame.
*
* If the configure script found we had no XKB, this does not exist.
*
* Returns: Always FALSE, so we don't get called again.
*/
/*
* Bug: This is the parallel to bell_flash_window_frame(), so it should
* \param data The frame to unflash, cast to a gpointer so it can go into
* a callback function.
* \return Always FALSE, so we don't get called again.
*
* \bug This is the parallel to bell_flash_window_frame(), so it should
* really be called meta_bell_unflash_window_frame().
*/
static gboolean
@ -213,9 +205,6 @@ bell_unflash_frame (gpointer data)
}
/**
* bell_flash_window_frame:
* @window: The window to flash
*
* Makes a frame flash and then return to normal shortly afterwards.
* This is done by setting a flag so that the theme
* code will temporarily draw the frame as focussed if it's unfocussed and
@ -223,6 +212,8 @@ bell_unflash_frame (gpointer data)
* that the flag can be unset and the frame re-redrawn.
*
* If the configure script found we had no XKB, this does not exist.
*
* \param window The window to flash
*/
static void
bell_flash_window_frame (MetaWindow *window)
@ -240,12 +231,11 @@ bell_flash_window_frame (MetaWindow *window)
}
/**
* bell_flash_frame:
* @display: The display the bell event came in on
* @xkb_ev: The bell event we just received
*
* Flashes the frame of the focussed window. If there is no focussed window,
* flashes the screen.
*
* \param display The display the bell event came in on
* \param xkb_ev The bell event we just received
*/
static void
bell_flash_frame (MetaDisplay *display,
@ -271,18 +261,15 @@ bell_flash_frame (MetaDisplay *display,
}
/**
* bell_visual_notify:
* @display: The display the bell event came in on
* @xkb_ev: The bell event we just received
*
* Gives the user some kind of visual bell substitute, in response to a
* bell event. What this is depends on the "visual bell type" pref.
*
* If the configure script found we had no XKB, this does not exist.
*/
/*
* Bug: This should be merged with meta_bell_notify().
*
* \param display The display the bell event came in on
* \param xkb_ev The bell event we just received
*
* \bug This should be merged with meta_bell_notify().
*/
static void
bell_visual_notify (MetaDisplay *display,
@ -290,12 +277,15 @@ bell_visual_notify (MetaDisplay *display,
{
switch (meta_prefs_get_visual_bell_type ())
{
case G_DESKTOP_VISUAL_BELL_FULLSCREEN_FLASH:
case META_VISUAL_BELL_FULLSCREEN_FLASH:
bell_flash_fullscreen (display, xkb_ev);
break;
case G_DESKTOP_VISUAL_BELL_FRAME_FLASH:
case META_VISUAL_BELL_FRAME_FLASH:
bell_flash_frame (display, xkb_ev); /* does nothing yet */
break;
case META_VISUAL_BELL_INVALID:
/* do nothing */
break;
}
}
@ -304,7 +294,7 @@ meta_bell_notify (MetaDisplay *display,
XkbAnyEvent *xkb_ev)
{
/* flash something */
if (meta_prefs_get_visual_bell ())
if (meta_prefs_get_visual_bell ())
bell_visual_notify (display, xkb_ev);
#ifdef HAVE_LIBCANBERRA
@ -420,13 +410,12 @@ meta_bell_shutdown (MetaDisplay *display)
}
/**
* meta_bell_notify_frame_destroy:
* @frame: The frame which is being destroyed
*
* Deals with a frame being destroyed. This is important because if we're
* using a visual bell, we might be flashing the edges of the frame, and
* so we'd have a timeout function waiting ready to un-flash them. If the
* frame's going away, we can tell the timeout not to bother.
*
* \param frame The frame which is being destroyed
*/
void
meta_bell_notify_frame_destroy (MetaFrame *frame)

View File

@ -1,5 +1,17 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/**
* \file bell.h Ring the bell or flash the screen
*
* Sometimes, X programs "ring the bell", whatever that means. Mutter lets
* the user configure the bell to be audible or visible (aka visual), and
* if it's visual it can be configured to be frame-flash or fullscreen-flash.
* We never get told about audible bells; X handles them just fine by itself.
*
* The visual bell was the result of a discussion in Bugzilla here:
* <http://bugzilla.gnome.org/show_bug.cgi?id=99886>.
*/
/*
* Copyright (C) 2002 Sun Microsystems Inc.
*

Some files were not shown because too many files have changed in this diff Show More