Compare commits

..

60 Commits

Author SHA1 Message Date
eac32fb142 frame: disallow frame operations if the popup is open
If some device has a popped up menu, meta_frame_get_flags()
returns 0 to indicate other devices cannot trigger any
actions on the frame.
2011-08-02 18:39:33 +02:00
b93c72315d ui: Add a MetaDevice arg to meta_window_menu_popup()
This will be the device popping up the menu, gtk_menu_popup()
uses the current GTK+ event device, and that might not even be
filled up with mutter event bypassing.
2011-08-02 18:39:33 +02:00
f84637d31e window: Make MetaWindow keep a pointer to the popup menu
Multiple windows may now have different popup menus, responding
only to the device pair that popped it up.
2011-08-02 18:39:32 +02:00
48a88a33ef ui: enable multidevice on frame windows
This is so different pointers may have different
cursors on them.
2011-07-27 00:33:10 +02:00
8847281c31 frames: Use the triggering device when updating controls 2011-07-27 00:33:10 +02:00
d05297593f frames: Get coordinates from event
Don't spare a synchronous X call, instead translate
properly the XEvent coordinates in ui.c and use
the event coordinates in MetaFrames
2011-07-27 00:33:09 +02:00
a285b8ae44 meta: Add device.h
This is real proof noone tried the branch yet
2011-07-27 00:33:09 +02:00
e6ba5ec298 display: Make focus info persistent
It must not be freed (at least meanwhile the device pair
exists), so ensure it's kept around, and we don't create
info for a same keyboard twice.
2011-07-27 00:33:09 +02:00
f6d9b29ad0 window: make guess_grab_pointer() more reliable
Now either the current focus keyboard or the client pointer
(i.e. the pointer paired to the last keyboard that had the
window focus) are used to guess the pointer that should be
grabbed.
2011-07-27 00:33:09 +02:00
e6f0af9abc window: set the corresponding client pointer on focused windows.
The client window determines the device pair that is used for
core protocol calls such as XQueryPointer(), so different
clients using the core protocol can be focused by different
devices simultaneously.
2011-07-19 20:55:05 +02:00
d32c726967 core: Fix rebase glitch 2011-07-18 12:39:04 +02:00
2c873990d1 core: enable XInput2 by default
This is nothing but the beginning, things work with a single
pointer/keyboard pair, but will be largely broken with multiple
devices interacting simultaneously, so we first need a policy
to establish a sensible behavior for extra pointer/keyboard
pairs.

the MUTTER_USE_CORE_DEVICES envvar has been added to force use
of Xlib core events for devices in order to check for regressions.
2011-07-15 18:03:47 +02:00
f15993f940 xi2: Workaround some bugs in XI2 passive grabs
XIAllMasterDevices doesn't quite work for key grabs, so only do
this at the moment for the Virtual Core Keyboard
2011-07-15 18:03:47 +02:00
d482dbcd16 display: Ignore events from slave devices
Mutter only handles master devices.
2011-07-15 18:03:47 +02:00
f5334dd6cf compositor: use meta_device_grab() for pointer/keyboard grabs
These happen invariably on the VCP/VCK pair.
2011-07-15 18:03:47 +02:00
972a9d231f screen: Use meta_device_pointer_set_window_cursor() for startup sequence.
At the moment feedback is only provided for the Virtual Core Pointer
2011-07-15 18:03:47 +02:00
1dd50cf006 device-map: Add meta_device_map_list_devices()
This function returns a list of the devices currently handled by
the device map.
2011-07-15 18:03:47 +02:00
855095ad1a core: Make frame handle per-pointer cursors. 2011-07-15 18:03:46 +02:00
95b2e6fafc workspace: use triggering device to focus the default window on workspace switch 2011-07-15 18:03:46 +02:00
dfcd079ec2 screen: make "monitor under pointer" logic work for several devices 2011-07-15 18:03:46 +02:00
e0966e7499 window: query the guessed pointer's modifiers on _NET_WM_MOVERESIZE 2011-07-15 18:03:46 +02:00
38df2715f2 display: Use the grab pointer for delayed window raising 2011-07-15 18:03:46 +02:00
5ecbb3ec3b keybindings: use the right device for querying the modifier mask. 2011-07-15 18:03:46 +02:00
656fa71649 devices: make meta_device_pointer_query_position() return a boolean
like in XQueryPointer/XIQueryPointer, the return value tells whether
the pointer device is on the same screen than the passed window.
2011-07-15 18:03:46 +02:00
bde0d28f1b core: Make keyboard focus handling happen per-keyboard
MetaFocusInfo is a struct holding all necessary info, code has
been updated to use the per-keyboard focus info instead of the
old fields.
2011-07-15 18:03:46 +02:00
4cb9a5e3bf core: Add meta_device_keyboard_[gs]et_focus_window()
These functions are meant to replace X[GS]etInputFocus() calls across
the core.
2011-07-15 18:03:45 +02:00
90c25f0cfe display: Use meta_device_grab() for pointer active grabs. 2011-07-15 18:03:45 +02:00
2484e8cd64 keybindings: Use meta_device_grab() for keyboard active grabs 2011-07-15 18:03:45 +02:00
61a7789c83 window: Use meta_device_pointer_warp() 2011-07-15 18:03:45 +02:00
c352e1078e core: Keep track of per pointer/keyboard grabs
There is now a MetaGrabInfo struct, holding all information about
an ongoing grab, there were unfortunately no means of making this
commit smaller, as things are too intertwined to separate it,

On places where it was most obvious, the correct device has been
used (in reaction to events, for example), in other parts, the
private API has been extended to include the MetaDevice (or device
ID for core.h functions), in other places, the virtual core
pointer/keyboard are used out of cluelessness.
2011-07-15 18:00:01 +02:00
d664579115 ui: Use input-events.h to translate XEvents to GdkEvents
This is the only use in the UI part of core functions not
exported via core.h, but this is sort of a hack within a hack,
and still better than doing the XInput2 vs core dance again.
2011-07-15 17:58:49 +02:00
49dfb40b82 devices: Make MetaDevice/MetaDeviceMap partly public
MetaDevice is quite limited outside of the core, mostly useful
to represent a device, and get the paired one.
2011-07-15 17:58:49 +02:00
e08c4756eb keybindings: Replace XGrabKey() with meta_device_map_grab_key() 2011-07-15 17:58:49 +02:00
6378527458 display: Replace XGrabButton with meta_device_map_grab_button() 2011-07-15 17:58:49 +02:00
f0705e142c core: Add XInput2 device map implementation 2011-07-15 17:58:49 +02:00
3f7193e558 Replace XAllowEvents with meta_device_allow_events() 2011-07-15 17:58:48 +02:00
3af9de08ab Use meta_core_select_events() for input events 2011-07-15 17:58:48 +02:00
111c23a6e0 core: Add method to select events on a window
This function handles XInput2 vs core in input events.
2011-07-15 17:58:48 +02:00
db6ddc4a7f devices-xi2: Export function to translate event mask 2011-07-15 17:58:48 +02:00
884e13474b Add XInput2 input devices implementation 2011-07-15 17:58:45 +02:00
722420df3a input-events: Add method to get the device for an event 2011-07-15 17:57:24 +02:00
50cee11c53 core: Add device map object
It will contain the input devices available
2011-07-15 17:57:24 +02:00
a727114ac2 core: Add core devices implementation 2011-07-15 17:57:24 +02:00
722d2d6472 device: Add methods to pair devices 2011-07-15 17:57:24 +02:00
7b9a26fbd8 Add pointer/keyboard abstract classes 2011-07-15 17:57:24 +02:00
5819e74c22 compositor: Use helper functions for input events 2011-07-15 17:57:24 +02:00
36e237cf1e keybindings: Use input event helper functions 2011-07-15 17:57:24 +02:00
3b0aa9f881 window: use input event helper functions on notify_focus() 2011-07-15 17:57:23 +02:00
e6d09c9d0b window: use input event helper functions in grab operations. 2011-07-15 17:57:23 +02:00
e26bf9dcef display: get crossing/focus events details via helper functions 2011-07-11 19:00:46 +02:00
748954a15e display: get button event coordinates with the helper functions 2011-07-11 19:00:46 +02:00
4c4f21c001 display: get button events state from helper functions 2011-07-11 19:00:46 +02:00
166559059a display: get button number from helper input event function 2011-07-11 19:00:46 +02:00
7566b4ea17 display: Use helper function to get input events' timestamp 2011-07-11 19:00:45 +02:00
1b7a6ce912 display: Use helper functions for getting window/root in input events 2011-07-11 19:00:45 +02:00
dc4ecdd0d2 display: Get the right window/time for input events 2011-07-11 19:00:45 +02:00
d381c0465b display: separate input/non-input events handling in the event callback
We now use meta_input_event_get_type() to discern input events from the
others. This commit has involved plenty of indenting changes, so it's
better seen with git diff -b.
2011-07-11 19:00:45 +02:00
38a0aecf61 core: Add helper code to handle input events
These will be used with every input event out there so they're
dealt with uniformly.
2011-07-11 19:00:45 +02:00
7573aae855 display: Add XInput2 variables in private struct 2011-07-11 19:00:45 +02:00
684d40d1a1 configure: Check for XInput2 2011-07-11 19:00:45 +02:00
176 changed files with 54754 additions and 39073 deletions

10
.gitignore vendored
View File

@ -19,7 +19,6 @@ libtool
ltmain.sh
missing
.deps
src/50-mutter-windows.xml
src/mutter-wm.desktop
src/mutter.desktop
*.o
@ -41,7 +40,6 @@ stamp-h1
stamp-it
.intltool-merge-cache
POTFILES
po/*.pot
50-metacity-desktop-key.xml
50-metacity-key.xml
inlinepixbufs.h
@ -49,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
@ -59,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,

365
NEWS
View File

@ -1,368 +1,3 @@
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

29
README
View File

@ -18,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
@ -58,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:
@ -90,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

@ -1,8 +1,8 @@
AC_PREREQ(2.50)
m4_define([mutter_major_version], [3])
m4_define([mutter_minor_version], [5])
m4_define([mutter_micro_version], [4])
m4_define([mutter_minor_version], [1])
m4_define([mutter_micro_version], [3.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
$CLUTTER_PACKAGE >= 1.9.10
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,6 +171,44 @@ 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])
@ -199,41 +238,93 @@ if test x$have_xcursor = xyes; then
AC_DEFINE(HAVE_XCURSOR, , [Building with Xcursor support])
fi
PKG_CHECK_MODULES(MUTTER, $MUTTER_PC_MODULES)
XINPUT2_VERSION=1.4.0
# This is used for plugins
AC_SUBST(CLUTTER_PACKAGE)
PKG_CHECK_MODULES(CLUTTER, $CLUTTER_PACKAGE)
AC_ARG_ENABLE(xinput2,
AC_HELP_STRING([--disable-xinput2],
[disable XInput2 usage]),,
enable_xinput2=yes)
if test x$enable_xinput2 = xyes; then
AC_MSG_CHECKING([XInput2])
if $PKG_CONFIG --atleast-version $XINPUT2_VERSION xi; then
have_xinput2=yes
else
have_xinput2=no
fi
AC_MSG_RESULT($have_xinput2)
else
have_xinput2=no
fi
if test x$have_xinput2 = xyes; then
echo "Building with XInput2"
MUTTER_PC_MODULES="$MUTTER_PC_MODULES xi"
AC_DEFINE(HAVE_XINPUT2, , [Building with XInput2 support])
fi
AM_CONDITIONAL(HAVE_XINPUT2, test "$have_xinput2" = "yes")
PKG_CHECK_MODULES(MUTTER, $MUTTER_PC_MODULES)
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 +440,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])
@ -426,7 +529,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
@ -448,6 +551,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"
@ -464,6 +574,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}
@ -471,6 +584,7 @@ mutter-$VERSION
Shape extension: ${found_shape}
Xsync: ${found_xsync}
Xcursor: ${have_xcursor}
XInput2: ${have_xinput2}
"
@ -478,8 +592,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

@ -1,7 +1,7 @@
# List of source files containing translatable strings.
# Please keep this file sorted alphabetically.
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
@ -19,7 +19,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

1163
po/ar.po

File diff suppressed because it is too large Load Diff

3667
po/as.po

File diff suppressed because it is too large Load Diff

1208
po/be.po

File diff suppressed because it is too large Load Diff

904
po/bg.po

File diff suppressed because it is too large Load Diff

1589
po/ca.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1009
po/cs.po

File diff suppressed because it is too large Load Diff

2885
po/da.po

File diff suppressed because it is too large Load Diff

1253
po/de.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1153
po/eo.po

File diff suppressed because it is too large Load Diff

1668
po/es.po

File diff suppressed because it is too large Load Diff

480
po/et.po
View File

@ -7,39 +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-03-11 22:19+0000\n"
"PO-Revision-Date: 2012-03-12 00:47+0200\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"
"Language: et\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
msgid "Windows"
msgstr "Aknad"
msgid "Switch to workspace 1"
msgstr "Lülitumine 1. tööalale"
msgid "View split on left"
msgstr "Vaade poolitatakse vasakult"
msgid "Switch to workspace 2"
msgstr "Lülitumine 2. tööalale"
msgid "View split on right"
msgstr "Vaade poolitatakse paremalt"
msgid "Switch to workspace 3"
msgstr "Lülitumine 3. tööalale"
#. 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 "Switch to workspace 4"
msgstr "Lülitumine 4. tööalale"
msgid "Switch to workspace 5"
msgstr "Lülitumine 5. tööalale"
msgid "Switch to workspace 6"
msgstr "Lülitumine 6. tööalale"
msgid "Switch to workspace 7"
msgstr "Lülitumine 7. tööalale"
msgid "Switch to workspace 8"
msgstr "Lülitumine 8. tööalale"
msgid "Switch to workspace 9"
msgstr "Lülitumine 9. tööalale"
msgid "Switch to workspace 10"
msgstr "Lülitumine 10. tööalale"
msgid "Switch to workspace 11"
msgstr "Lülitumine 11. tööalale"
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üü aktiveerimine"
msgid "Toggle fullscreen mode"
msgstr "Täisekraanivaate sisse- ja väljalülitamine"
msgid "Toggle maximization state"
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 "Taasta akna suurus"
msgid "Toggle shaded state"
msgstr "Varjatud oleku lüliti"
msgid "Minimize window"
msgstr "Akna minimeerimine"
msgid "Close window"
msgstr "Akna sulgemine"
msgid "Move window"
msgstr "Teisalda aken"
msgid "Resize window"
msgstr "Muuda akna suurust"
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 "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 akende kohale"
msgid "Lower window below other windows"
msgstr "Saada aken teiste taha"
msgid "Maximize window vertically"
msgstr "Maksimeeri aken vertikaalselt"
msgid "Maximize window horizontally"
msgstr "Maksimeeri aken horisontaalselt"
msgid "Move window to north-west (top left) corner"
msgstr "Akna tõstmine ekraani loodepoolsesse (ülemisse vasakusse) nurka"
msgid "Move window to north-east (top right) corner"
msgstr "Akna tõstmine ekraani kirdepoolsesse (ülemisse paremasse) nurka"
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"
@ -48,13 +262,11 @@ 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 "<tt>%s</tt> is not responding."
msgstr "<tt>%s</tt> ei vasta."
msgid "Application is not responding."
msgstr "Rakendus ei vasta."
msgid ""
"You may choose to wait a short while for it to continue or force the "
"application to quit entirely."
@ -82,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"
@ -131,6 +364,39 @@ msgstr "Versiooni printimine"
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 "
"behave properly.\n"
@ -139,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 ""
@ -150,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 "
@ -159,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"
@ -258,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 ""
@ -295,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"
@ -324,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"
@ -342,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 "
@ -353,75 +640,6 @@ msgstr ""
"Kui märgitud, siis eraldi tiitliribade asemel on moodaalsed dialoogid "
"emaakna tiitliribade küljes ning liiguvad koos emaaknaga."
msgid "Live Hidden Windows"
msgstr "Varjatud akende aktiivsus"
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 "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 "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"
@ -659,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] "
@ -1317,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."

1199
po/eu.po

File diff suppressed because it is too large Load Diff

6070
po/fa.po

File diff suppressed because it is too large Load Diff

2222
po/fi.po

File diff suppressed because it is too large Load Diff

920
po/fr.po

File diff suppressed because it is too large Load Diff

1206
po/gl.po

File diff suppressed because it is too large Load Diff

1378
po/gu.po

File diff suppressed because it is too large Load Diff

1538
po/he.po

File diff suppressed because it is too large Load Diff

1147
po/hu.po

File diff suppressed because it is too large Load Diff

673
po/id.po

File diff suppressed because it is too large Load Diff

1290
po/it.po

File diff suppressed because it is too large Load Diff

1206
po/ja.po

File diff suppressed because it is too large Load Diff

1259
po/kn.po

File diff suppressed because it is too large Load Diff

912
po/ko.po

File diff suppressed because it is too large Load Diff

1979
po/lt.po

File diff suppressed because it is too large Load Diff

1331
po/lv.po

File diff suppressed because it is too large Load Diff

850
po/nb.po

File diff suppressed because it is too large Load Diff

1161
po/nl.po

File diff suppressed because it is too large Load Diff

1140
po/pa.po

File diff suppressed because it is too large Load Diff

840
po/pl.po

File diff suppressed because it is too large Load Diff

1139
po/pt.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1179
po/ru.po

File diff suppressed because it is too large Load Diff

899
po/sl.po

File diff suppressed because it is too large Load Diff

1323
po/sr.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1128
po/sv.po

File diff suppressed because it is too large Load Diff

1080
po/ta.po

File diff suppressed because it is too large Load Diff

2522
po/te.po

File diff suppressed because it is too large Load Diff

2558
po/th.po

File diff suppressed because it is too large Load Diff

1170
po/tr.po

File diff suppressed because it is too large Load Diff

269
po/ug.po
View File

@ -10,8 +10,8 @@ msgstr ""
"Project-Id-Version: mutter\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?"
"product=mutter&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2011-08-27 17:13+0000\n"
"PO-Revision-Date: 2011-08-08 16:52+0600\n"
"POT-Creation-Date: 2011-06-30 21:06+0000\n"
"PO-Revision-Date: 2011-06-27 11:17+0600\n"
"Last-Translator: Sahran <sahran.ug@gmail.com>\n"
"Language-Team: Uyghur Computer Science Association <UKIJ@yahoogroups.com>\n"
"MIME-Version: 1.0\n"
@ -20,13 +20,16 @@ msgstr ""
#. This probably means that a non-WM compositor like xcompmgr is running;
#. * we have no way to get it to exit
#: ../src/compositor/compositor.c:487
#, c-format
#: ../src/compositor/compositor.c:509
#, fuzzy, c-format
#| msgid ""
#| "Could not acquire window manager selection on screen %d display \"%s\"\n"
msgid ""
"Another compositing manager is already running on screen %i on display \"%s"
"\"."
msgstr ""
"كۆرسەتكۈچ \"%2$s\" نىڭدىكى ئېكران %1$d دا بۆلەك باشقۇرغۇچ ئىجرا قىلىنىۋاتىدۇ."
"كۆرسەتكۈچ \"%2$s\" نىڭدىكى ئېكران %1$d دا كۆزنەك باشقۇرغۇنىڭ تاللانمىسىنى "
"ئالغىلى بولمىدى\n"
#: ../src/core/all-keybindings.h:88
msgid "Switch to workspace 1"
@ -398,7 +401,7 @@ msgstr ""
#. Displayed when a keybinding which is
#. * supposed to launch a program fails.
#.
#: ../src/core/keybindings.c:2523
#: ../src/core/keybindings.c:2468
#, c-format
msgid ""
"There was an error running <tt>%s</tt>:\n"
@ -409,12 +412,12 @@ msgstr ""
"\n"
"%s"
#: ../src/core/keybindings.c:2613
#: ../src/core/keybindings.c:2558
#, c-format
msgid "No command %d has been defined.\n"
msgstr "بۇيرۇق %d بېكىتىلمىگەن.\n"
#: ../src/core/keybindings.c:3625
#: ../src/core/keybindings.c:3570
#, c-format
msgid "No terminal command has been defined.\n"
msgstr "تېرمىنال بۇيرۇققا ئېنىقلىما بېرىلمىگەن .\n"
@ -489,41 +492,41 @@ msgstr "پەش بىلەن ئايرىلغان تىزىم ۋە بىرىكمە رە
#. * (Empty comment follows so the translators don't see this.)
#.
#.
#: ../src/core/prefs.c:550 ../src/core/prefs.c:711
#: ../src/core/prefs.c:543 ../src/core/prefs.c:704
#, c-format
msgid "GConf key '%s' is set to an invalid value\n"
msgstr ""
"GConf نىڭ ئاچقۇچ سۆزى“%s” ئۈنۈمسىز \n"
" قىلىپ تەڭشەلگەن\n"
#: ../src/core/prefs.c:637 ../src/core/prefs.c:880
#: ../src/core/prefs.c:630 ../src/core/prefs.c:873
#, c-format
msgid "%d stored in GConf key %s is out of range %d to %d\n"
msgstr ""
"GConf نىڭ %2$s ئاچقۇچىنىڭ قىممىتى %1$d نىڭ دائىرىسى %3$d〜%4$d نىڭ ئىچىدە "
"ئەمەس\n"
#: ../src/core/prefs.c:681 ../src/core/prefs.c:758 ../src/core/prefs.c:806
#: ../src/core/prefs.c:870 ../src/core/prefs.c:1331 ../src/core/prefs.c:1347
#: ../src/core/prefs.c:1364 ../src/core/prefs.c:1380
#: ../src/core/prefs.c:674 ../src/core/prefs.c:751 ../src/core/prefs.c:799
#: ../src/core/prefs.c:863 ../src/core/prefs.c:1324 ../src/core/prefs.c:1340
#: ../src/core/prefs.c:1357 ../src/core/prefs.c:1373
#, c-format
msgid "GConf key \"%s\" is set to an invalid type\n"
msgstr ""
"GConf نىڭ ئاچقۇچلۇق سۆزى “%s” ئۈنۈمسىز تىپتىكى \n"
" قىلىپ تەڭشەلگەن\n"
#: ../src/core/prefs.c:1210
#: ../src/core/prefs.c:1203
#, c-format
msgid "GConf key %s is already in use and can't be used to override %s\n"
msgstr ""
"GConf ئاچقۇچى %s ئىشلىتىلىۋاتىدۇ، شۇڭا %s نى قاپلاشقا ئىشلەتكىلى بولمايدۇ\n"
#: ../src/core/prefs.c:1269
#: ../src/core/prefs.c:1262
#, c-format
msgid "Can't override GConf key, %s not found\n"
msgstr "GConf ئاچقۇچىنى قاپلىغىلى بولمىدى، %s تېپىلمىدى\n"
#: ../src/core/prefs.c:1454
#: ../src/core/prefs.c:1447
msgid ""
"Workarounds for broken applications disabled. Some applications may not "
"behave properly.\n"
@ -531,14 +534,14 @@ msgstr ""
"بۇزۇلغان پروگراممىلارنى تۈزىتىش-ياخشىلاش قوزغىتىلمىغان. بەزى پروگراممىلار "
"نورمال ئىشلىمەسلىكى مۇمكىن.\n"
#: ../src/core/prefs.c:1531
#: ../src/core/prefs.c:1524
#, c-format
msgid "Could not parse font description \"%s\" from GConf key %s\n"
msgstr ""
"خەت نۇسخىسىنىڭ چۈشەندۈرۈلۈشىنى ئانالىز قىلغىلى بولمىدى “%s” ( GConf دىكى "
"ئاچقۇچلۇق سۆز %s )\n"
#: ../src/core/prefs.c:1593
#: ../src/core/prefs.c:1586
#, c-format
msgid ""
"\"%s\" found in configuration database is not a valid value for mouse button "
@ -548,17 +551,17 @@ msgstr ""
"ئۈنۈملۈك قىممەت \n"
" ئەمەس\n"
#: ../src/core/prefs.c:2028
#: ../src/core/prefs.c:2016
#, c-format
msgid "Error setting number of workspaces to %d: %s\n"
msgstr "خىزمەت رايونى سانىنى %d قىلىپ تەڭشەشتە كۆرۈلگەن خاتالىق %s\n"
#: ../src/core/prefs.c:2212 ../src/core/prefs.c:2714
#: ../src/core/prefs.c:2200 ../src/core/prefs.c:2702
#, c-format
msgid "Workspace %d"
msgstr "خىزمەت بوشلۇقى %d"
#: ../src/core/prefs.c:2244 ../src/core/prefs.c:2422
#: ../src/core/prefs.c:2232 ../src/core/prefs.c:2410
#, c-format
msgid ""
"\"%s\" found in configuration database is not a valid value for keybinding "
@ -567,18 +570,18 @@ msgstr ""
"سەپلىمە ساندانىدىن تېپىلغان \"%s\"، \"%s\" كۇنۇپكا باغلانمىسىنىڭ ئىناۋەتلىك "
"قىممىتى ئەمەس\n"
#: ../src/core/prefs.c:2795
#: ../src/core/prefs.c:2783
#, c-format
msgid "Error setting name for workspace %d to \"%s\": %s\n"
msgstr "خىزمەت مۇھىتى %d غا \"%s\" دەپ ئائىت قويۇشتا خاتالىق كۆرۈلدى: %s\n"
#: ../src/core/prefs.c:3009
#: ../src/core/prefs.c:2997
#, c-format
msgid "Error setting live hidden windows status status: %s\n"
msgstr ""
"شۇئان يوشۇرۇنىدىغان كۆزنەك ھالىتىنى تەڭشەۋاتقاندا خاتالىق كۆرۈلدى: %s\n"
#: ../src/core/prefs.c:3044
#: ../src/core/prefs.c:3032
#, c-format
msgid "Error setting no tab popup status: %s\n"
msgstr "بەتكۈچ يوق قاڭقىش ھالىتىنى تەڭشەۋەتقاندا خاتالىق كۆرۈلدى: %s\n"
@ -718,7 +721,7 @@ msgid "Mutter"
msgstr "Mutter"
#. first time through
#: ../src/core/window.c:7019
#: ../src/core/window.c:6886
#, c-format
msgid ""
"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER "
@ -734,7 +737,7 @@ msgstr ""
#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain
#. * about these apps but make them work.
#.
#: ../src/core/window.c:7682
#: ../src/core/window.c:7549
#, c-format
msgid ""
"Window %s sets an MWM hint indicating it isn't resizable, but sets min size %"
@ -756,17 +759,12 @@ msgstr ""
msgid "%s (on %s)"
msgstr "%s (ھەققىدە %s)"
#: ../src/core/window-props.c:1481
#: ../src/core/window-props.c:1484
#, c-format
msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n"
msgstr ""
"%2$s گە بەلگىلەنگەن ئۈنۈمسىز WM_TRANSIENT_FOR كۆزنەك 0x%1$lx بولىدۇ.\n"
#: ../src/core/window-props.c:1492
#, c-format
msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n"
msgstr "%2$s نىڭ WM_TRANSIENT_FOR كۆزنەك0x%1$lx دەۋرىيلىك قۇرۇشى مۇمكىن.\n"
#: ../src/core/xprops.c:155
#, c-format
msgid ""
@ -817,24 +815,14 @@ msgstr ""
"ئېكرانغىلا قارىتىلغانلىقىنى جەزملەيدۇ."
#: ../src/mutter.schemas.in.h:4
msgid "Draggable border width"
msgstr ""
#: ../src/mutter.schemas.in.h:5
msgid "Live Hidden Windows"
msgstr "شۇئان يوشۇرۇنىدىغان كۆزنەكلەر"
#: ../src/mutter.schemas.in.h:6
#: ../src/mutter.schemas.in.h:5
msgid "Modifier to use for extended window management operations"
msgstr "كېڭەيتىلگەن كۆزنەك باشقۇرۇش مەشغۇلاتىغا ئىشلىتىلىدىغان ئۆزگەرتىش"
#: ../src/mutter.schemas.in.h:7
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 ""
#: ../src/mutter.schemas.in.h:8
#: ../src/mutter.schemas.in.h:6
msgid ""
"This key will initiate the \"overlay\", which is a combination window "
"overview and application launching system. The default is intended to be the "
@ -846,7 +834,7 @@ msgstr ""
"ئەھۋالدا يەككە كومپيۇتېردىكى \"Windows key\" كۇنۇپكىسىنى ئىشلىتىشنى تەلەپ "
"قىلىدۇ. بەلكىم كۆڭۈلدىكى ياكى بوش تىزىقنى ئىشلىتىدۇ."
#: ../src/mutter.schemas.in.h:9
#: ../src/mutter.schemas.in.h:7
msgid ""
"When true, instead of having independent titlebars, modal dialogs appear "
"attached to the titlebar of the parent window and are moved together with "
@ -855,7 +843,7 @@ msgstr ""
"true بولغاندا مودېل سۆزلەشكۈ ئاتا كۆزنەكنىڭ ماۋزۇ بالداققا يېپىشىپ كۆرۈنىدۇ "
"ھەمدە ئاتا كۆزنەككە ئەگىشىپ يۆتكىلىدۇ، ئايرىم ماۋزۇ بالدىقى بولمايدۇ."
#: ../src/mutter.schemas.in.h:10
#: ../src/mutter.schemas.in.h:8
msgid "Workspaces only on primary"
msgstr "ئاساسىي كۆزەتكۈچتىكى خىزمەت رايونىغىلا"
@ -864,47 +852,47 @@ msgstr "ئاساسىي كۆزەتكۈچتىكى خىزمەت رايونىغىل
msgid "Usage: %s\n"
msgstr "ئىشلىتىش ئۇسۇلى:%s\n"
#: ../src/ui/frames.c:1157
#: ../src/ui/frames.c:1280
msgid "Close Window"
msgstr "كۆزنەك ياپ"
#: ../src/ui/frames.c:1160
#: ../src/ui/frames.c:1283
msgid "Window Menu"
msgstr "كۆزنەك تىزىملىكى"
#: ../src/ui/frames.c:1163
#: ../src/ui/frames.c:1286
msgid "Minimize Window"
msgstr "كۆزنەكنى كىچىكلەت"
#: ../src/ui/frames.c:1166
#: ../src/ui/frames.c:1289
msgid "Maximize Window"
msgstr "كۆزنەكنى چوڭايت"
#: ../src/ui/frames.c:1169
#: ../src/ui/frames.c:1292
msgid "Restore Window"
msgstr "كۆزنەكنى ئەسلىگە كەلتۈر"
#: ../src/ui/frames.c:1172
#: ../src/ui/frames.c:1295
msgid "Roll Up Window"
msgstr "كۆزنەكنى تۈر"
#: ../src/ui/frames.c:1175
#: ../src/ui/frames.c:1298
msgid "Unroll Window"
msgstr "كۆزنەكنى تۈرمە"
#: ../src/ui/frames.c:1178
#: ../src/ui/frames.c:1301
msgid "Keep Window On Top"
msgstr "كۆزنەكنى چوققىلاشنى ساقلا"
#: ../src/ui/frames.c:1181
#: ../src/ui/frames.c:1304
msgid "Remove Window From Top"
msgstr "كۆزنەكنى چوققىلاشنى بىكار قىلىش"
#: ../src/ui/frames.c:1184
#: ../src/ui/frames.c:1307
msgid "Always On Visible Workspace"
msgstr "خىزمەت رايونىدا ئىزچىل كۆرۈنسۇن"
#: ../src/ui/frames.c:1187
#: ../src/ui/frames.c:1310
msgid "Put Window On Only One Workspace"
msgstr "بىر خىزمەت رايونىغا ئورۇنلاشتۇرۇش"
@ -1016,7 +1004,7 @@ msgstr "باشقا خىزمەت بوشلۇقىغا يۆتكە(_W)"
#.
#: ../src/ui/metaaccellabel.c:77
msgid "Shift"
msgstr "Shift"
msgstr "Shift كۇنۇپكىسى"
#. This is the text that should appear next to menu accelerators
#. * that use the control key. If the text on this key isn't typically
@ -1107,77 +1095,50 @@ msgstr "Mod5"
msgid "%d x %d"
msgstr "%d x %d"
#: ../src/ui/theme.c:253
#: ../src/ui/theme.c:255
msgid "top"
msgstr "چوققا"
#: ../src/ui/theme.c:255
#: ../src/ui/theme.c:257
msgid "bottom"
msgstr "ئاستى"
#: ../src/ui/theme.c:257
#: ../src/ui/theme.c:259
msgid "left"
msgstr "سول"
#: ../src/ui/theme.c:259
#: ../src/ui/theme.c:261
msgid "right"
msgstr "ئوڭ"
#: ../src/ui/theme.c:286
#: ../src/ui/theme.c:288
#, c-format
msgid "frame geometry does not specify \"%s\" dimension"
msgstr "كاندۇك گىيومېتىرىك جايلاشتۇرۇش \"%s\" نىڭ چوڭلۇقىنى بەلگىلىمىگەن"
#: ../src/ui/theme.c:305
#: ../src/ui/theme.c:307
#, c-format
msgid "frame geometry does not specify dimension \"%s\" for border \"%s\""
msgstr ""
"كاندۇك گىيومېتىرىك جايلاشتۇرۇش \"%s\" نىڭ چوڭلۇقىنى بەلگىلىمىگەن(\"%s\" "
"گىرۋىكىگە بەلگىلەنگەن)"
#: ../src/ui/theme.c:342
#: ../src/ui/theme.c:344
#, c-format
msgid "Button aspect ratio %g is not reasonable"
msgstr "كۇنۇپكا ئۇزۇنلۇق كەڭلىك نىسبىتى %g غا ماس كەلمەيدۇ"
#: ../src/ui/theme.c:354
#: ../src/ui/theme.c:356
#, c-format
msgid "Frame geometry does not specify size of buttons"
msgstr "كاندۇك گىيومېتىرىك جايلاشتۇرۇشتا تۈگمە چوڭلۇقى بەلگىلەنمىگەن"
#: ../src/ui/theme.c:1060
#: ../src/ui/theme.c:1064
#, c-format
msgid "Gradients should have at least two colors"
msgstr "تەدرىجىي ئۆزگىرىشتە ئاز دېگەندە ئىككى خىل رەڭ بولۇش كېرەك"
#: ../src/ui/theme.c:1212
#, 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 رەڭ ئۆلچىمىدە ھالەتتىن كېيىن چوقۇم رەڭ ئاتى ۋە زاپاس بولۇشى لازىم، "
"مەسىلەن، gtk:custom(foo,bar) ھالەت؛ \"%s\" نى تەھلىل قىلالمايدۇ"
#: ../src/ui/theme.c:1228
#, 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 پارامېتىرىدىكى ئىناۋەتسىز ھەرپ '%c'، پەقەت A-Za-z0-"
"9-_ نىلا ئىشلەتكىلى بولىدۇ"
#: ../src/ui/theme.c:1242
#, c-format
msgid ""
"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not "
"fit the format"
msgstr ""
"Gtk:custom نىڭ پىچىمى \"gtk:custom(color_name,fallback)\" بولۇپ، \"%s\" "
"پىچىمغا توغرا كەلمەيدۇ"
#: ../src/ui/theme.c:1287
#: ../src/ui/theme.c:1202
#, c-format
msgid ""
"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] "
@ -1186,7 +1147,7 @@ msgstr ""
"GTK رەڭ ئۆلچىمىدە ھالەت چوقۇم ئوتتۇرا تىرناققا ئېلىنىشى لازىم، مەسىلەن، gtk:"
"fg[NORMAL] بۇنىڭدىكى NORMAL ھالەت؛ \"%s\" نى تەھلىل قىلالمايدۇ"
#: ../src/ui/theme.c:1301
#: ../src/ui/theme.c:1216
#, c-format
msgid ""
"GTK color specification must have a close bracket after the state, e.g. gtk:"
@ -1195,17 +1156,17 @@ msgstr ""
"GTK رەڭ ئۆلچىمىدە ھالەتتىن كېيىن چوقۇم ئوتتۇرا تىرناق يېپىلىشى لازىم، "
"مەسىلەن، gtk:fg[NORMAL] بۇنىڭدىكى NORMAL ھالەت؛ \"%s\" نى تەھلىل قىلالمايدۇ"
#: ../src/ui/theme.c:1312
#: ../src/ui/theme.c:1227
#, c-format
msgid "Did not understand state \"%s\" in color specification"
msgstr "رەڭ بەلگىلىمىسىدىكى «%s» ھالەتنى چۈشەنگىلى بولمىدى"
#: ../src/ui/theme.c:1325
#: ../src/ui/theme.c:1240
#, c-format
msgid "Did not understand color component \"%s\" in color specification"
msgstr "رەڭ بەلگىلىمىسىدىكى «%s» رەڭ بۆلىكىنى چۈشەنگىلى بولمىدى"
#: ../src/ui/theme.c:1355
#: ../src/ui/theme.c:1270
#, c-format
msgid ""
"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the "
@ -1214,44 +1175,49 @@ msgstr ""
"بىرىكمە رەڭنىڭ فورماتى \"blend/bg_color/fg_color/alpha\"، \"%s\" بۇ "
"فورماتقا ماس كەلمىدى"
#: ../src/ui/theme.c:1366
#: ../src/ui/theme.c:1281
#, c-format
msgid "Could not parse alpha value \"%s\" in blended color"
msgstr "بىرىكمە رەڭدىكى ئالفا قىممىتى \"%s\" نى تەھلىل قىلغىلى بولمىدى"
#: ../src/ui/theme.c:1376
#: ../src/ui/theme.c:1291
#, c-format
msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0"
msgstr ""
"بىرىكمە رەڭنىڭ ئالفا قىممىتى \"%s\" نىڭ دائىرىسى 0.0 ~1.0 ئىچىدە ئەمەس"
#: ../src/ui/theme.c:1423
#: ../src/ui/theme.c:1338
#, c-format
msgid ""
"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format"
msgstr "سايە پىچىمى \"shade/base_color/factor\"، \"%s\" پىچىمغا توغرا كەلمەيدۇ"
#: ../src/ui/theme.c:1434
#: ../src/ui/theme.c:1349
#, c-format
msgid "Could not parse shade factor \"%s\" in shaded color"
msgstr "سايە رەڭگىدىكى سايە فاكتور «%s»نى تەھلىل قىلغىلى بولمىدى"
#: ../src/ui/theme.c:1444
#: ../src/ui/theme.c:1359
#, c-format
msgid "Shade factor \"%s\" in shaded color is negative"
msgstr "سايە رەڭگىدىكى سايە فاكتور “%s” مەنپىي سان"
#: ../src/ui/theme.c:1473
#: ../src/ui/theme.c:1388
#, c-format
msgid "Could not parse color \"%s\""
msgstr "رەڭنى تەھلىل قىلغىلى بولمىدى“%s”"
#: ../src/ui/theme.c:1784
#: ../src/ui/theme.c:1481
#, c-format
msgid "Failed to retrieve color %s[%s] from GTK+ theme.\n"
msgstr "GTK+ ئۆرنەكتىن رەڭ %s[%s] نى ئىزدىيەلمىدى\n"
#: ../src/ui/theme.c:1713
#, c-format
msgid "Coordinate expression contains character '%s' which is not allowed"
msgstr "كوئوردېنات ئىپادىسىنىڭ تەركىبىدە رۇخسەت قىلىنمىغان تېكىست '%s' بار"
#: ../src/ui/theme.c:1811
#: ../src/ui/theme.c:1740
#, c-format
msgid ""
"Coordinate expression contains floating point number '%s' which could not be "
@ -1260,54 +1226,54 @@ msgstr ""
"كوئوردېنات ئىپادىسىنىڭ تەركىبىدە تەھلىل قىلغىلى بولمايدىغان كەسىر سان '%s' "
"بار"
#: ../src/ui/theme.c:1825
#: ../src/ui/theme.c:1754
#, c-format
msgid "Coordinate expression contains integer '%s' which could not be parsed"
msgstr ""
"كوئوردېنات ئىپادىسىنىڭ تەركىبىدە تەھلىل قىلغىلى بولمايدىغان پۈتۈن سان '%s' "
"بار"
#: ../src/ui/theme.c:1947
#: ../src/ui/theme.c:1876
#, c-format
msgid ""
"Coordinate expression contained unknown operator at the start of this text: "
"\"%s\""
msgstr "كوئوردېنات ئىپادىسىنىڭ بېشىدا نامەلۇم ئەمەل بار: «%s»"
#: ../src/ui/theme.c:2004
#: ../src/ui/theme.c:1933
#, c-format
msgid "Coordinate expression was empty or not understood"
msgstr "كوئوردېناتنىڭ ئىپادىلەش شەكلى قۇرۇق ياكى چۈشىنىكسىز"
#: ../src/ui/theme.c:2115 ../src/ui/theme.c:2125 ../src/ui/theme.c:2159
#: ../src/ui/theme.c:2044 ../src/ui/theme.c:2054 ../src/ui/theme.c:2088
#, c-format
msgid "Coordinate expression results in division by zero"
msgstr "كوئوردېناتنىڭ ئىپادىلەش شەكلى 0 نى بۆلگۈچ قىلغان"
#: ../src/ui/theme.c:2167
#: ../src/ui/theme.c:2096
#, c-format
msgid ""
"Coordinate expression tries to use mod operator on a floating-point number"
msgstr "كوئوردېنات ئىپادىسى كەسىر سانغا mod ئەمىلىنى ئىشلەتمەكچى"
#: ../src/ui/theme.c:2223
#: ../src/ui/theme.c:2152
#, c-format
msgid ""
"Coordinate expression has an operator \"%s\" where an operand was expected"
msgstr ""
"كوئوردېنات ئىپادىسىنىڭ تەركىبىدە سان كېلىدىغان يەردە ئەمەل \"%s\" بار ئىكەن"
#: ../src/ui/theme.c:2232
#: ../src/ui/theme.c:2161
#, c-format
msgid "Coordinate expression had an operand where an operator was expected"
msgstr "كوئوردېنات ئىپادىسىنىڭ تەركىبىدە ئەمەل كېلىدىغان يەردە سان بار ئىكەن"
#: ../src/ui/theme.c:2240
#: ../src/ui/theme.c:2169
#, c-format
msgid "Coordinate expression ended with an operator instead of an operand"
msgstr "كوئوردېنات ئىپادىسى سان بىلەن ئاياغلاشماي ئەمەل بىلەن ئاياغلاشقان"
#: ../src/ui/theme.c:2250
#: ../src/ui/theme.c:2179
#, c-format
msgid ""
"Coordinate expression has operator \"%c\" following operator \"%c\" with no "
@ -1316,43 +1282,43 @@ msgstr ""
"كوئوردېنات ئىپادىسىنىڭ تەركىبىدە ئەمەل \"%2$c\" نىڭ ئارقىسىدىن ئەمەل \"%1$c"
"\" كېلىپتۇ، ئارىلىقتا سان يوق ئىكەن"
#: ../src/ui/theme.c:2401 ../src/ui/theme.c:2446
#: ../src/ui/theme.c:2330 ../src/ui/theme.c:2375
#, c-format
msgid "Coordinate expression had unknown variable or constant \"%s\""
msgstr ""
"كوئوردېنات ئىپادىسىنىڭ تەركىبىدە نامەلۇم ئۆزگەرگۈچى ياكى تۇراقلىق سان \"%s\" "
"بار ئىكەن"
#: ../src/ui/theme.c:2500
#: ../src/ui/theme.c:2429
#, c-format
msgid "Coordinate expression parser overflowed its buffer."
msgstr "كوئوردېنات ئىپادىسىنى تەھلىل قىلىۋاتقاندا يىغلەك تېشىپ كەتتى."
#: ../src/ui/theme.c:2529
#: ../src/ui/theme.c:2458
#, c-format
msgid "Coordinate expression had a close parenthesis with no open parenthesis"
msgstr ""
"كوئوردېنات ئىپادىسىنىڭ تەركىبىدىكى يېپىلغان تىرناققا ماس كېلىدىغان ئېچىلغان "
"تىرناق يوق"
#: ../src/ui/theme.c:2593
#: ../src/ui/theme.c:2522
#, c-format
msgid "Coordinate expression had an open parenthesis with no close parenthesis"
msgstr ""
"كوئوردېنات ئىپادىسىنىڭ تەركىبىدىكى ئېچىلغان تىرناققا ماس كېلىدىغان يېپىلغان "
"تىرناق يوق"
#: ../src/ui/theme.c:2604
#: ../src/ui/theme.c:2533
#, c-format
msgid "Coordinate expression doesn't seem to have any operators or operands"
msgstr "كوئوردېنات ئىپادىسىنىڭ تەركىبىدە ئەمەل(قوشۇش، ئېلىش...) ياكى سان يوق"
#: ../src/ui/theme.c:2816 ../src/ui/theme.c:2836 ../src/ui/theme.c:2856
#: ../src/ui/theme.c:2745 ../src/ui/theme.c:2765 ../src/ui/theme.c:2785
#, c-format
msgid "Theme contained an expression that resulted in an error: %s\n"
msgstr "تېما تەركىبىدە خاتالىق چىقىرىدىغان ئىپادە بار: %s\n"
#: ../src/ui/theme.c:4527
#: ../src/ui/theme.c:4482
#, c-format
msgid ""
"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be "
@ -1361,25 +1327,25 @@ msgstr ""
"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/>بۇ كۆزنەكنىڭ "
"ئۇسلۇبى ئۈچۈن بەلگىلىنىشى زۆرۈر"
#: ../src/ui/theme.c:5060 ../src/ui/theme.c:5085
#: ../src/ui/theme.c:5012 ../src/ui/theme.c:5037
#, c-format
msgid ""
"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>"
msgstr ""
"<frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/> يوق"
#: ../src/ui/theme.c:5133
#: ../src/ui/theme.c:5085
#, c-format
msgid "Failed to load theme \"%s\": %s\n"
msgstr "تېما “%s” نى كىرگۈزگىلى بولمىدى:%s\n"
#: ../src/ui/theme.c:5269 ../src/ui/theme.c:5276 ../src/ui/theme.c:5283
#: ../src/ui/theme.c:5290 ../src/ui/theme.c:5297
#: ../src/ui/theme.c:5221 ../src/ui/theme.c:5228 ../src/ui/theme.c:5235
#: ../src/ui/theme.c:5242 ../src/ui/theme.c:5249
#, c-format
msgid "No <%s> set for theme \"%s\""
msgstr "ئۇسلۇب \"%1$s\" نىڭ <%2$s> ئى بەلگىلەنمىگەن"
#: ../src/ui/theme.c:5305
#: ../src/ui/theme.c:5257
#, c-format
msgid ""
"No frame style set for window type \"%s\" in theme \"%s\", add a <window "
@ -1388,7 +1354,7 @@ msgstr ""
"كۆزنەك تىپى \"%s\" (\"%s\" تېمىدا)غا كاندۇك كۆزنەك تەڭشەلمىگەن، بىر <window "
"type=\"%s\" style_set=\"whatever\"/> ئېلېمېنتى قوشۇڭ"
#: ../src/ui/theme.c:5744 ../src/ui/theme.c:5806 ../src/ui/theme.c:5869
#: ../src/ui/theme.c:5707 ../src/ui/theme.c:5769 ../src/ui/theme.c:5832
#, c-format
msgid ""
"User-defined constants must begin with a capital letter; \"%s\" does not"
@ -1396,7 +1362,7 @@ msgstr ""
"ئىشلەتكۈچى بەلگىلىگەن تۇراقلىق مىقدار چوقۇم چوڭ ھەرپ بىلەن باشلانسۇن؛ «%s» "
"بولمايدۇ"
#: ../src/ui/theme.c:5752 ../src/ui/theme.c:5814 ../src/ui/theme.c:5877
#: ../src/ui/theme.c:5715 ../src/ui/theme.c:5777 ../src/ui/theme.c:5840
#, c-format
msgid "Constant \"%s\" has already been defined"
msgstr "تۇراقلىق سان “%s” غا ئېنىقلىما بېرىلگەن"
@ -1855,88 +1821,88 @@ msgstr "بۇ ئۈلگە سۆزلەشكۈسىدىكى مىسال ئۇچۇرى"
msgid "Fake menu item %d\n"
msgstr "مەۋھۇم تىزىملىك تۈرى %d\n"
#: ../src/ui/theme-viewer.c:371
#: ../src/ui/theme-viewer.c:370
msgid "Border-only window"
msgstr "گىرۋەكلىك كۆزنەك"
#: ../src/ui/theme-viewer.c:373
#: ../src/ui/theme-viewer.c:372
msgid "Bar"
msgstr "تۈۋرۈكسىمان دىئاگرامما"
#: ../src/ui/theme-viewer.c:390
#: ../src/ui/theme-viewer.c:389
msgid "Normal Application Window"
msgstr "ئادەتتىكى پروگرامما كۆزنىكى"
#: ../src/ui/theme-viewer.c:394
#: ../src/ui/theme-viewer.c:393
msgid "Dialog Box"
msgstr "سۆزلەشكۈ كۆزنەكچىسى"
#: ../src/ui/theme-viewer.c:398
#: ../src/ui/theme-viewer.c:397
msgid "Modal Dialog Box"
msgstr "ھالەت سۆزلەشكۈ رامكىسى"
#: ../src/ui/theme-viewer.c:402
#: ../src/ui/theme-viewer.c:401
msgid "Utility Palette"
msgstr "قورال كۇنۇپكىسى"
#: ../src/ui/theme-viewer.c:406
#: ../src/ui/theme-viewer.c:405
msgid "Torn-off Menu"
msgstr "بۆلىۋالغان تىزىملىك"
#: ../src/ui/theme-viewer.c:410
#: ../src/ui/theme-viewer.c:409
msgid "Border"
msgstr "گىرۋەك"
#: ../src/ui/theme-viewer.c:414
#: ../src/ui/theme-viewer.c:413
msgid "Attached Modal Dialog"
msgstr "قوشۇلغان Modal سۆزلەشكۈ"
#: ../src/ui/theme-viewer.c:747
#: ../src/ui/theme-viewer.c:744
#, c-format
msgid "Button layout test %d"
msgstr "كۇنۇپكا ئورۇنلاشتۇرۇلۇشىنى سىناش %d"
#: ../src/ui/theme-viewer.c:776
#: ../src/ui/theme-viewer.c:773
#, c-format
msgid "%g milliseconds to draw one window frame"
msgstr "%g مىللىسېكۇنت(بىر كۆزنەك كاندۇكىنى سىزىشقا كەتكەن ۋاقىت)"
#: ../src/ui/theme-viewer.c:821
#: ../src/ui/theme-viewer.c:818
#, c-format
msgid "Usage: metacity-theme-viewer [THEMENAME]\n"
msgstr "ئىشلىتىش ئۇسۇلى: metacity-theme-viewer [ئۇسلۇب ئاتى]\n"
#: ../src/ui/theme-viewer.c:828
#: ../src/ui/theme-viewer.c:825
#, c-format
msgid "Error loading theme: %s\n"
msgstr "تېما قاچىلاشتا خاتالىق كۆرۈلدى:%s\n"
#: ../src/ui/theme-viewer.c:834
#: ../src/ui/theme-viewer.c:831
#, c-format
msgid "Loaded theme \"%s\" in %g seconds\n"
msgstr "\"%s\" دېگەن ئۇسلۇبنى %g سېكۇنتتا ئوقۇدى\n"
#: ../src/ui/theme-viewer.c:878
#: ../src/ui/theme-viewer.c:875
msgid "Normal Title Font"
msgstr "ئادەتتىكى ماۋزۇ خەت نۇسخىسى"
#: ../src/ui/theme-viewer.c:884
#: ../src/ui/theme-viewer.c:881
msgid "Small Title Font"
msgstr "تارماق ماۋزۇ خەت نۇسخىسى"
#: ../src/ui/theme-viewer.c:890
#: ../src/ui/theme-viewer.c:887
msgid "Large Title Font"
msgstr "ماۋزۇ خەت نۇسخىسى"
#: ../src/ui/theme-viewer.c:895
#: ../src/ui/theme-viewer.c:892
msgid "Button Layouts"
msgstr "كۇنۇپكا ئورۇنلاشتۇرۇلۇشى"
#: ../src/ui/theme-viewer.c:900
#: ../src/ui/theme-viewer.c:897
msgid "Benchmark"
msgstr "ئاساسىي ئۆلچەم"
#: ../src/ui/theme-viewer.c:952
#: ../src/ui/theme-viewer.c:949
msgid "Window Title Goes Here"
msgstr "بۇ يەردە كۆزنەك ماۋزۇسى كۆرسىتىلىدۇ"
@ -1989,9 +1955,6 @@ msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n"
msgstr ""
"%d كوئوردېنات ئىپادىسى %g سېكۇنتتا تەھلىل قىلىندى(%g ئوتتۇرىچە سېكۇنت)\n"
#~ msgid "Failed to retrieve color %s[%s] from GTK+ theme.\n"
#~ msgstr "GTK+ ئۆرنەكتىن رەڭ %s[%s] نى ئىزدىيەلمىدى\n"
#~ msgid "Turn compositing on"
#~ msgstr "ئارىلاشتۇرۇشنى ئىچىش"

1131
po/uk.po

File diff suppressed because it is too large Load Diff

1433
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,15 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<KeyListEntries schema="org.gnome.mutter.keybindings"
group="system"
_name="Windows"
wm_name="Mutter"
package="mutter">
<KeyListEntry name="toggle-tiled-left"
_description="View split on left"/>
<KeyListEntry name="toggle-tiled-right"
_description="View split on right"/>
</KeyListEntries>

View File

@ -27,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
@ -43,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 \
@ -52,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 \
@ -65,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 \
@ -75,6 +75,20 @@ libmutter_la_SOURCES = \
core/constraints.h \
core/core.c \
core/delete.c \
core/device.c \
meta/device.h \
core/device-keyboard.c \
core/device-keyboard.h \
core/device-pointer.c \
core/device-pointer.h \
core/device-private.h \
core/device-map.c \
meta/device-map.h \
core/device-map-private.h \
core/device-map-core.c \
core/device-map-core.h \
core/devices-core.c \
core/devices-core.h \
core/display.c \
core/display-private.h \
meta/display.h \
@ -97,6 +111,8 @@ libmutter_la_SOURCES = \
meta/group.h \
core/iconcache.c \
core/iconcache.h \
core/input-events.c \
core/input-events.h \
core/keybindings.c \
core/keybindings-private.h \
core/main.c \
@ -130,6 +146,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 \
@ -147,10 +165,19 @@ 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)
if HAVE_XINPUT2
libmutter_la_SOURCES += \
core/device-map-xi2.c \
core/device-map-xi2.h \
core/devices-xi2.c \
core/devices-xi2.h
endif
libmutter_la_LDFLAGS = -no-undefined
libmutter_la_LIBADD = $(MUTTER_LIBS)
@ -161,15 +188,15 @@ libmutterinclude_base_headers = \
meta/common.h \
meta/compositor-mutter.h \
meta/compositor.h \
meta/device.h \
meta/device-map.h \
meta/display.h \
meta/errors.h \
meta/gradient.h \
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 \
@ -221,8 +248,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
@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 = \
@ -257,17 +284,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-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 \
@ -279,8 +309,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)
@ -297,18 +326,37 @@ 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

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;
@ -42,10 +41,6 @@ struct _MetaCompScreen
GHashTable *windows_by_xid;
Window output;
/* Used for unredirecting fullscreen windows */
guint disable_unredirect_count;
MetaWindowActor *unredirected_window;
/* Before we create the output window */
XserverRegion pending_input_region;
@ -55,6 +50,9 @@ struct _MetaCompScreen
};
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,

View File

@ -15,9 +15,11 @@
#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 "core.h" /* for meta_core_select_events() */
#include "input-events.h"
#include <X11/extensions/shape.h>
#include <X11/extensions/Xcomposite.h>
@ -109,6 +111,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 +149,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;
}
}
@ -155,7 +180,6 @@ get_output_window (MetaScreen *screen)
MetaDisplay *display = meta_screen_get_display (screen);
Display *xdisplay = meta_display_get_xdisplay (display);
Window output, xroot;
XWindowAttributes attr;
long event_mask;
xroot = meta_screen_get_xroot (screen);
@ -169,13 +193,7 @@ get_output_window (MetaScreen *screen)
KeyPressMask | KeyReleaseMask;
output = XCompositeGetOverlayWindow (xdisplay, xroot);
if (XGetWindowAttributes (xdisplay, output, &attr))
{
event_mask |= attr.your_event_mask;
}
XSelectInput (xdisplay, output, event_mask);
meta_core_select_events (xdisplay, output, event_mask, TRUE);
return output;
}
@ -279,12 +297,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);
}
@ -347,26 +359,34 @@ meta_begin_modal_for_plugin (MetaScreen *screen,
* merge the two.
*/
MetaDisplay *display = meta_screen_get_display (screen);
Display *xdpy = meta_display_get_xdisplay (display);
MetaCompositor *compositor = display->compositor;
gboolean pointer_grabbed = FALSE;
gboolean keyboard_grabbed = FALSE;
int result;
gboolean result;
MetaDevice *device;
MetaGrabInfo *grab_info;
if (compositor->modal_plugin != NULL || display->grab_op != META_GRAB_OP_NONE)
/* FIXME: need a real device here, and probably
* some exclusion mode for other devices */
device = meta_device_map_lookup (display->device_map,
META_CORE_POINTER_ID);
grab_info = meta_display_get_grab_info (display, device);
if (compositor->modal_plugin != NULL || grab_info != NULL)
return FALSE;
if ((options & META_MODAL_POINTER_ALREADY_GRABBED) == 0)
{
result = XGrabPointer (xdpy, grab_window,
False, /* owner_events */
(ButtonPressMask | ButtonReleaseMask |
EnterWindowMask | LeaveWindowMask | PointerMotionMask),
GrabModeAsync, GrabModeAsync,
None, /* confine to */
cursor,
timestamp);
if (result != Success)
result = meta_device_grab (device,
grab_window,
(ButtonPressMask | ButtonReleaseMask |
EnterWindowMask | LeaveWindowMask | PointerMotionMask),
cursor,
FALSE,
FALSE,
timestamp);
if (!result)
goto fail;
pointer_grabbed = TRUE;
@ -374,22 +394,25 @@ meta_begin_modal_for_plugin (MetaScreen *screen,
if ((options & META_MODAL_KEYBOARD_ALREADY_GRABBED) == 0)
{
result = XGrabKeyboard (xdpy, grab_window,
False, /* owner_events */
GrabModeAsync, GrabModeAsync,
timestamp);
if (result != Success)
result = meta_device_grab (meta_device_get_paired_device (device),
grab_window,
(KeyPressMask | KeyReleaseMask),
META_CURSOR_DEFAULT,
FALSE, FALSE,
timestamp);
if (!result)
goto fail;
keyboard_grabbed = TRUE;
}
display->grab_op = META_GRAB_OP_COMPOSITOR;
display->grab_window = NULL;
display->grab_screen = screen;
display->grab_have_pointer = TRUE;
display->grab_have_keyboard = TRUE;
grab_info = meta_display_create_grab_info (display, device);
grab_info->grab_op = META_GRAB_OP_COMPOSITOR;
grab_info->grab_window = NULL;
grab_info->grab_screen = screen;
grab_info->grab_have_pointer = TRUE;
grab_info->grab_have_keyboard = TRUE;
compositor->modal_plugin = plugin;
@ -397,9 +420,9 @@ meta_begin_modal_for_plugin (MetaScreen *screen,
fail:
if (pointer_grabbed)
XUngrabPointer (xdpy, timestamp);
meta_device_ungrab (device, timestamp);
if (keyboard_grabbed)
XUngrabKeyboard (xdpy, timestamp);
meta_device_ungrab (meta_device_get_paired_device (device), timestamp);
return FALSE;
}
@ -410,20 +433,19 @@ meta_end_modal_for_plugin (MetaScreen *screen,
guint32 timestamp)
{
MetaDisplay *display = meta_screen_get_display (screen);
Display *xdpy = meta_display_get_xdisplay (display);
MetaCompositor *compositor = display->compositor;
MetaDevice *device;
g_return_if_fail (compositor->modal_plugin == plugin);
XUngrabPointer (xdpy, timestamp);
XUngrabKeyboard (xdpy, timestamp);
/* FIXME: need a real device here */
device = meta_device_map_lookup (display->device_map,
META_CORE_POINTER_ID);
display->grab_op = META_GRAB_OP_NONE;
display->grab_window = NULL;
display->grab_screen = NULL;
display->grab_have_pointer = FALSE;
display->grab_have_keyboard = FALSE;
meta_device_ungrab (device, timestamp);
meta_device_ungrab (meta_device_get_paired_device (device), timestamp);
meta_display_remove_grab_info (display, device);
compositor->modal_plugin = NULL;
}
@ -456,7 +478,6 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
Window xroot = meta_screen_get_xroot (screen);
Window xwin;
gint width, height;
XWindowAttributes attr;
long event_mask;
guint n_retries;
guint max_retries;
@ -515,15 +536,13 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
meta_screen_set_cm_selection (screen);
info->stage = clutter_stage_new ();
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 |
@ -533,15 +552,10 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
KeyPressMask | KeyReleaseMask |
StructureNotifyMask;
if (XGetWindowAttributes (xdisplay, xwin, &attr))
{
event_mask |= attr.your_event_mask;
}
XSelectInput (xdisplay, xwin, event_mask);
meta_core_select_events (xdisplay, xwin, event_mask, TRUE);
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 ();
@ -557,7 +571,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
@ -604,47 +620,6 @@ meta_compositor_unmanage_screen (MetaCompositor *compositor,
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
meta_compositor_add_window (MetaCompositor *compositor,
MetaWindow *window)
@ -665,25 +640,12 @@ 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);
}
@ -695,9 +657,15 @@ meta_compositor_set_updates (MetaCompositor *compositor,
}
static gboolean
is_grabbed_event (XEvent *event)
is_grabbed_event (MetaDisplay *display,
XEvent *event)
{
switch (event->xany.type)
guint evtype;
if (!meta_input_event_get_type (display, event, &evtype))
return FALSE;
switch (evtype)
{
case ButtonPress:
case ButtonRelease:
@ -711,16 +679,6 @@ is_grabbed_event (XEvent *event)
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)
*
@ -730,7 +688,8 @@ meta_compositor_process_event (MetaCompositor *compositor,
XEvent *event,
MetaWindow *window)
{
if (compositor->modal_plugin && is_grabbed_event (event))
if (compositor->modal_plugin &&
is_grabbed_event (compositor->display, event))
{
MetaPluginClass *klass = META_PLUGIN_GET_CLASS (compositor->modal_plugin);
@ -800,6 +759,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;
}
@ -869,6 +835,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,
@ -1116,20 +1105,14 @@ 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),
@ -1140,36 +1123,6 @@ static void
pre_paint_windows (MetaCompScreen *info)
{
GList *l;
MetaWindowActor *top_window;
MetaWindowActor *expected_unredirected_window = 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);
@ -1273,37 +1226,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

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

@ -28,188 +28,76 @@
#define COGL_ENABLE_EXPERIMENTAL_API
#include <cogl/cogl-texture-pixmap-x11.h>
#define CLUTTER_ENABLE_EXPERIMENTAL_API
#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;
CoglHandle texture;
CoglMaterialWrapMode wrap_mode;
guint have_pixmap : 1;
};
struct _MetaBackgroundActorPrivate
{
MetaScreenBackground *background;
CoglHandle material;
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_material_set_layer_wrap_mode (priv->material, 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_material_set_layer (priv->material, 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 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
@ -218,9 +106,9 @@ 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;
@ -232,31 +120,40 @@ set_texture_to_stage_color (MetaScreenBackground *background)
texture = meta_create_color_texture_4ub (color.red, color.green,
color.blue, 0xff,
COGL_TEXTURE_NO_SLICING);
set_texture (background, texture);
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;
}
if (priv->material != COGL_INVALID_HANDLE)
if (self->screen != NULL)
{
cogl_handle_unref (priv->material);
priv->material = COGL_INVALID_HANDLE;
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;
}
G_OBJECT_CLASS (meta_background_actor_parent_class)->dispose (object);
}
static void
@ -266,15 +163,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
@ -285,10 +181,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;
@ -300,39 +195,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_material_set_color4ub (priv->material,
color_component,
color_component,
color_component,
opacity);
cogl_set_source (self->material);
cogl_set_source (priv->material);
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
@ -340,160 +228,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;
priv->material = 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
@ -503,9 +316,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;
@ -515,13 +327,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,
@ -542,31 +355,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);
}
/**
@ -582,46 +387,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));
}

View File

@ -46,20 +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);
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,21 +393,32 @@ 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;
@ -284,7 +427,7 @@ meta_plugin_manager_switch_workspace (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.
@ -293,20 +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 && klass->xevent_filter (plugin, xev))
return TRUE;
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,6 +66,10 @@ 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,

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

@ -130,7 +130,7 @@ MetaShadowClassInfo default_shadow_classes[] = {
{ "popup-menu", { 1, -1, 0, 1, 128 }, { 1, -1, 0, 1, 128 } },
{ "dropdown-menu", { 1, 10, 0, 1, 128 }, { 1, 10, 0, 1, 128 } },
{ "attached", { 2, -1, 0, 1, 255 }, { 1, -1, 0, 1, 128 } }
{ "attached", { 2, 50, 0, 1, 255 }, { 1, 50, 0, 1, 128 } }
};
G_DEFINE_TYPE (MetaShadowFactory, meta_shadow_factory, G_TYPE_OBJECT);
@ -360,7 +360,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,
@ -442,7 +442,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,37 +25,37 @@
#include <config.h>
#define CLUTTER_ENABLE_EXPERIMENTAL_API
#define COGL_ENABLE_EXPERIMENTAL_API
#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, \
@ -66,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;
};
@ -84,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));
}
@ -103,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;
}
@ -119,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);
@ -129,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)
{
@ -179,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)
{
@ -205,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))
@ -238,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 */
@ -256,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;
@ -294,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))
@ -304,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;
@ -315,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);
@ -330,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 *
@ -397,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;
@ -414,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;
@ -513,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
@ -574,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,101 +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>
#define CLUTTER_ENABLE_EXPERIMENTAL_API
#define COGL_ENABLE_EXPERIMENTAL_API
#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,22 +26,15 @@ 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_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);

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
{
@ -104,19 +103,12 @@ actor_is_untransformed (ClutterActor *actor,
static void
meta_window_group_paint (ClutterActor *actor)
{
cairo_region_t *visible_region;
cairo_region_t *unredirected_window_region = NULL;
ClutterActor *stage;
cairo_rectangle_int_t visible_rect, unredirected_rect;
GList *children, *l;
MetaWindowGroup *window_group = META_WINDOW_GROUP (actor);
MetaCompScreen *info = meta_screen_get_compositor_data (window_group->screen);
if (info->unredirected_window != NULL)
{
meta_window_actor_get_shape_bounds (META_WINDOW_ACTOR (info->unredirected_window), &unredirected_rect);
unredirected_window_region = cairo_region_create_rectangle (&unredirected_rect);
}
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
@ -125,49 +117,49 @@ 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 (unredirected_window_region)
cairo_region_subtract (visible_region, unredirected_window_region);
if (scissor_test)
{
GLint scissor_box[4];
glGetIntegerv (GL_SCISSOR_BOX, scissor_box);
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 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;
@ -196,9 +188,6 @@ meta_window_group_paint (ClutterActor *actor)
cairo_region_destroy (visible_region);
if (unredirected_window_region)
cairo_region_destroy (unredirected_window_region);
CLUTTER_ACTOR_CLASS (meta_window_group_parent_class)->paint (actor);
/* Now that we are done painting, unset the visible regions (they will
@ -209,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)
@ -239,27 +230,51 @@ bell_flash_window_frame (MetaWindow *window)
bell_unflash_frame, window->frame, NULL);
}
static MetaWindow *
get_flash_window (MetaDisplay *display,
XkbAnyEvent *xkb_ev)
{
XkbBellNotifyEvent *xkb_bell_event;
MetaWindow *window;
g_assert (xkb_ev->xkb_type == XkbBellNotify);
xkb_bell_event = (XkbBellNotifyEvent *) xkb_ev;
window = meta_display_lookup_x_window (display, xkb_bell_event->window);
if (!window &&
g_hash_table_size (display->focus_info) == 1)
{
GHashTableIter iter;
MetaFocusInfo *info;
/* If there is only one focused window, use it */
g_hash_table_iter_init (&iter, display->focus_info);
if (g_hash_table_iter_next (&iter, NULL, (gpointer *) &info) &&
info->focus_window && info->focus_window->frame)
window = info->focus_window;
}
return 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,
XkbAnyEvent *xkb_ev)
{
XkbBellNotifyEvent *xkb_bell_event = (XkbBellNotifyEvent *) xkb_ev;
MetaWindow *window;
g_assert (xkb_ev->xkb_type == XkbBellNotify);
window = meta_display_lookup_x_window (display, xkb_bell_event->window);
if (!window && (display->focus_window))
{
window = display->focus_window;
}
window = get_flash_window (display, xkb_ev);
if (window && window->frame)
{
bell_flash_window_frame (window);
@ -271,18 +286,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 +302,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 +319,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
@ -320,9 +335,7 @@ meta_bell_notify (MetaDisplay *display,
ca_proplist_sets (p, CA_PROP_EVENT_DESCRIPTION, _("Bell event"));
ca_proplist_sets (p, CA_PROP_CANBERRA_CACHE_CONTROL, "permanent");
window = meta_display_lookup_x_window (display, xkb_bell_event->window);
if (!window && (display->focus_window) && (display->focus_window->frame))
window = display->focus_window;
window = get_flash_window (display, xkb_ev);
if (window)
{
@ -420,13 +433,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.
*

View File

@ -625,6 +625,7 @@ meta_rectangle_get_minimal_spanning_set_for_region (
*temp_rect = *basic_rect;
ret = g_list_prepend (NULL, temp_rect);
strut_iter = all_struts;
for (strut_iter = all_struts; strut_iter; strut_iter = strut_iter->next)
{
GList *rect_iter;

View File

@ -118,8 +118,7 @@ typedef struct
{
MetaRectangle orig;
MetaRectangle current;
MetaFrameBorders *borders;
gboolean must_free_borders;
MetaFrameGeometry *fgeom;
ActionType action_type;
gboolean is_user_action;
@ -195,7 +194,7 @@ static gboolean constrain_partially_onscreen (MetaWindow *window,
static void setup_constraint_info (ConstraintInfo *info,
MetaWindow *window,
MetaFrameBorders *orig_borders,
MetaFrameGeometry *orig_fgeom,
MetaMoveResizeFlags flags,
int resize_gravity,
const MetaRectangle *orig,
@ -205,11 +204,11 @@ static void place_window_if_needed (MetaWindow *window,
static void update_onscreen_requirements (MetaWindow *window,
ConstraintInfo *info);
static void extend_by_frame (MetaRectangle *rect,
const MetaFrameBorders *borders);
const MetaFrameGeometry *fgeom);
static void unextend_by_frame (MetaRectangle *rect,
const MetaFrameBorders *borders);
const MetaFrameGeometry *fgeom);
static inline void get_size_limits (const MetaWindow *window,
const MetaFrameBorders *borders,
const MetaFrameGeometry *fgeom,
gboolean include_frame,
MetaRectangle *min_size,
MetaRectangle *max_size);
@ -280,7 +279,7 @@ do_all_constraints (MetaWindow *window,
void
meta_window_constrain (MetaWindow *window,
MetaFrameBorders *orig_borders,
MetaFrameGeometry *orig_fgeom,
MetaMoveResizeFlags flags,
int resize_gravity,
const MetaRectangle *orig,
@ -303,7 +302,7 @@ meta_window_constrain (MetaWindow *window,
setup_constraint_info (&info,
window,
orig_borders,
orig_fgeom,
flags,
resize_gravity,
orig,
@ -338,14 +337,14 @@ meta_window_constrain (MetaWindow *window,
* not gobject-style--gobject would be more pain than it's worth) or
* smart pointers would be so much nicer here. *shrug*
*/
if (info.must_free_borders)
g_free (info.borders);
if (!orig_fgeom)
g_free (info.fgeom);
}
static void
setup_constraint_info (ConstraintInfo *info,
MetaWindow *window,
MetaFrameBorders *orig_borders,
MetaFrameGeometry *orig_fgeom,
MetaMoveResizeFlags flags,
int resize_gravity,
const MetaRectangle *orig,
@ -358,16 +357,10 @@ setup_constraint_info (ConstraintInfo *info,
info->current = *new;
/* Create a fake frame geometry if none really exists */
if (orig_borders && !window->fullscreen)
{
info->borders = orig_borders;
info->must_free_borders = FALSE;
}
if (orig_fgeom && !window->fullscreen)
info->fgeom = orig_fgeom;
else
{
info->borders = g_new0 (MetaFrameBorders, 1);
info->must_free_borders = TRUE;
}
info->fgeom = g_new0 (MetaFrameGeometry, 1);
if (flags & META_IS_MOVE_ACTION && flags & META_IS_RESIZE_ACTION)
info->action_type = ACTION_MOVE_AND_RESIZE;
@ -446,13 +439,9 @@ setup_constraint_info (ConstraintInfo *info,
monitor_info->number);
/* Workaround braindead legacy apps that don't know how to
* fullscreen themselves properly - don't get fooled by
* windows which hide their titlebar when maximized; that's
* not the same as fullscreen, even if there are no struts
* making the workarea smaller than the monitor.
* fullscreen themselves properly.
*/
if (meta_prefs_get_force_fullscreen() &&
!window->hide_titlebar_when_maximized &&
meta_rectangle_equal (new, &monitor_info->rect) &&
window->has_fullscreen_func &&
!window->fullscreen)
@ -472,6 +461,7 @@ setup_constraint_info (ConstraintInfo *info,
"Setting up constraint info:\n"
" orig: %d,%d +%d,%d\n"
" new : %d,%d +%d,%d\n"
" fgeom: %d,%d,%d,%d\n"
" action_type : %s\n"
" is_user_action : %s\n"
" resize_gravity : %s\n"
@ -481,6 +471,8 @@ setup_constraint_info (ConstraintInfo *info,
info->orig.x, info->orig.y, info->orig.width, info->orig.height,
info->current.x, info->current.y,
info->current.width, info->current.height,
info->fgeom->left_width, info->fgeom->right_width,
info->fgeom->top_height, info->fgeom->bottom_height,
(info->action_type == ACTION_MOVE) ? "Move" :
(info->action_type == ACTION_RESIZE) ? "Resize" :
(info->action_type == ACTION_MOVE_AND_RESIZE) ? "Move&Resize" :
@ -521,7 +513,7 @@ place_window_if_needed(MetaWindow *window,
MetaWorkspace *cur_workspace;
const MetaMonitorInfo *monitor_info;
meta_window_place (window, info->borders, info->orig.x, info->orig.y,
meta_window_place (window, info->fgeom, info->orig.x, info->orig.y,
&placed_rect.x, &placed_rect.y);
did_placement = TRUE;
@ -580,8 +572,8 @@ place_window_if_needed(MetaWindow *window,
META_MAXIMIZE_VERTICAL : 0), &info->current);
/* maximization may have changed frame geometry */
if (!window->fullscreen)
meta_frame_calc_borders (window->frame, info->borders);
if (window->frame && !window->fullscreen)
meta_frame_calc_geometry (window->frame, info->fgeom);
if (window->fullscreen_after_placement)
{
@ -642,7 +634,7 @@ update_onscreen_requirements (MetaWindow *window,
/* The require onscreen/on-single-monitor and titlebar_visible
* stuff is relative to the outer window, not the inner
*/
extend_by_frame (&info->current, info->borders);
extend_by_frame (&info->current, info->fgeom);
/* Update whether we want future constraint runs to require the
* window to be on fully onscreen.
@ -678,7 +670,7 @@ update_onscreen_requirements (MetaWindow *window,
MetaRectangle titlebar_rect;
titlebar_rect = info->current;
titlebar_rect.height = info->borders->visible.top;
titlebar_rect.height = info->fgeom->top_height;
old = window->require_titlebar_visible;
window->require_titlebar_visible =
meta_rectangle_overlaps_with_region (info->usable_screen_region,
@ -691,32 +683,32 @@ update_onscreen_requirements (MetaWindow *window,
}
/* Don't forget to restore the position of the window */
unextend_by_frame (&info->current, info->borders);
unextend_by_frame (&info->current, info->fgeom);
}
static void
extend_by_frame (MetaRectangle *rect,
const MetaFrameBorders *borders)
const MetaFrameGeometry *fgeom)
{
rect->x -= borders->visible.left;
rect->y -= borders->visible.top;
rect->width += borders->visible.left + borders->visible.right;
rect->height += borders->visible.top + borders->visible.bottom;
rect->x -= fgeom->left_width;
rect->y -= fgeom->top_height;
rect->width += fgeom->left_width + fgeom->right_width;
rect->height += fgeom->top_height + fgeom->bottom_height;
}
static void
unextend_by_frame (MetaRectangle *rect,
const MetaFrameBorders *borders)
const MetaFrameGeometry *fgeom)
{
rect->x += borders->visible.left;
rect->y += borders->visible.top;
rect->width -= borders->visible.left + borders->visible.right;
rect->height -= borders->visible.top + borders->visible.bottom;
rect->x += fgeom->left_width;
rect->y += fgeom->top_height;
rect->width -= fgeom->left_width + fgeom->right_width;
rect->height -= fgeom->top_height + fgeom->bottom_height;
}
static inline void
get_size_limits (const MetaWindow *window,
const MetaFrameBorders *borders,
const MetaFrameGeometry *fgeom,
gboolean include_frame,
MetaRectangle *min_size,
MetaRectangle *max_size)
@ -731,8 +723,8 @@ get_size_limits (const MetaWindow *window,
if (include_frame)
{
int fw = borders->visible.left + borders->visible.right;
int fh = borders->visible.top + borders->visible.bottom;
int fw = fgeom->left_width + fgeom->right_width;
int fh = fgeom->top_height + fgeom->bottom_height;
min_size->width += fw;
min_size->height += fh;
@ -760,16 +752,27 @@ constrain_modal_dialog (MetaWindow *window,
MetaWindow *parent = meta_window_get_transient_for (window);
gboolean constraint_already_satisfied;
if (!meta_window_is_attached_dialog (window))
if (!meta_prefs_get_attach_modal_dialogs ())
return TRUE;
if (window->type != META_WINDOW_MODAL_DIALOG || !parent)
return TRUE;
x = parent->rect.x + (parent->rect.width / 2 - info->current.width / 2);
y = parent->rect.y + (parent->rect.height / 2 - info->current.height / 2);
y = 0;
if (parent->frame)
{
MetaFrameGeometry fgeom;
x += parent->frame->rect.x;
y += parent->frame->rect.y;
meta_frame_calc_geometry (parent->frame, &fgeom);
y += fgeom.top_height;
y += info->fgeom->top_height;
}
else
y = parent->rect.y + info->fgeom->top_height;
constraint_already_satisfied = (x == info->current.x) && (y == info->current.y);
@ -807,14 +810,8 @@ constrain_maximization (MetaWindow *window,
return TRUE;
/* Calculate target_size = maximized size of (window + frame) */
if (META_WINDOW_TILED_MAXIMIZED (window))
{
meta_window_get_current_tile_area (window, &target_size);
}
else if (META_WINDOW_MAXIMIZED (window))
{
target_size = info->work_area_monitor;
}
if (window->maximized_horizontally && window->maximized_vertically)
target_size = info->work_area_monitor;
else
{
/* Amount of maximization possible in a single direction depends
@ -834,19 +831,19 @@ constrain_maximization (MetaWindow *window,
active_workspace_struts = window->screen->active_workspace->all_struts;
target_size = info->current;
extend_by_frame (&target_size, info->borders);
extend_by_frame (&target_size, info->fgeom);
meta_rectangle_expand_to_avoiding_struts (&target_size,
&info->entire_monitor,
direction,
active_workspace_struts);
}
/* Now make target_size = maximized size of client window */
unextend_by_frame (&target_size, info->borders);
unextend_by_frame (&target_size, info->fgeom);
/* Check min size constraints; max size constraints are ignored for maximized
* windows, as per bug 327543.
*/
get_size_limits (window, info->borders, FALSE, &min_size, &max_size);
get_size_limits (window, info->fgeom, FALSE, &min_size, &max_size);
hminbad = target_size.width < min_size.width && window->maximized_horizontally;
vminbad = target_size.height < min_size.height && window->maximized_vertically;
if (hminbad || vminbad)
@ -888,6 +885,7 @@ constrain_tiling (MetaWindow *window,
gboolean hminbad, vminbad;
gboolean horiz_equal, vert_equal;
gboolean constraint_already_satisfied;
MetaDevice *pointer;
if (priority > PRIORITY_TILING)
return TRUE;
@ -896,16 +894,18 @@ constrain_tiling (MetaWindow *window,
if (!META_WINDOW_TILED_SIDE_BY_SIDE (window))
return TRUE;
pointer = meta_window_guess_grab_pointer (window);
/* Calculate target_size - as the tile previews need this as well, we
* use an external function for the actual calculation
*/
meta_window_get_current_tile_area (window, &target_size);
unextend_by_frame (&target_size, info->borders);
meta_window_get_current_tile_area (window, pointer, &target_size);
unextend_by_frame (&target_size, info->fgeom);
/* Check min size constraints; max size constraints are ignored as for
* maximized windows.
*/
get_size_limits (window, info->borders, FALSE, &min_size, &max_size);
get_size_limits (window, info->fgeom, FALSE, &min_size, &max_size);
hminbad = target_size.width < min_size.width;
vminbad = target_size.height < min_size.height;
if (hminbad || vminbad)
@ -948,7 +948,7 @@ constrain_fullscreen (MetaWindow *window,
monitor = info->entire_monitor;
get_size_limits (window, info->borders, FALSE, &min_size, &max_size);
get_size_limits (window, info->fgeom, FALSE, &min_size, &max_size);
too_big = !meta_rectangle_could_fit_rect (&monitor, &min_size);
too_small = !meta_rectangle_could_fit_rect (&max_size, &monitor);
if (too_big || too_small)
@ -1057,7 +1057,7 @@ constrain_size_limits (MetaWindow *window,
return TRUE;
/* Determine whether constraint is already satisfied; exit if it is */
get_size_limits (window, info->borders, FALSE, &min_size, &max_size);
get_size_limits (window, info->fgeom, FALSE, &min_size, &max_size);
/* We ignore max-size limits for maximized windows; see #327543 */
if (window->maximized_horizontally)
max_size.width = MAX (max_size.width, info->current.width);
@ -1249,8 +1249,8 @@ do_screen_and_monitor_relative_constraints (
/* Determine whether constraint applies; exit if it doesn't */
how_far_it_can_be_smushed = info->current;
get_size_limits (window, info->borders, TRUE, &min_size, &max_size);
extend_by_frame (&info->current, info->borders);
get_size_limits (window, info->fgeom, TRUE, &min_size, &max_size);
extend_by_frame (&info->current, info->fgeom);
if (info->action_type != ACTION_MOVE)
{
@ -1270,7 +1270,7 @@ do_screen_and_monitor_relative_constraints (
&info->current);
if (exit_early || constraint_satisfied || check_only)
{
unextend_by_frame (&info->current, info->borders);
unextend_by_frame (&info->current, info->fgeom);
return constraint_satisfied;
}
@ -1294,7 +1294,7 @@ do_screen_and_monitor_relative_constraints (
info->fixed_directions,
&info->current);
unextend_by_frame (&info->current, info->borders);
unextend_by_frame (&info->current, info->fgeom);
return TRUE;
}
@ -1365,15 +1365,18 @@ constrain_titlebar_visible (MetaWindow *window,
int bottom_amount;
int horiz_amount_offscreen, vert_amount_offscreen;
int horiz_amount_onscreen, vert_amount_onscreen;
MetaGrabInfo *grab_info;
if (priority > PRIORITY_TITLEBAR_VISIBLE)
return TRUE;
grab_info = window->cur_grab;
/* Allow the titlebar beyond the top of the screen only if the user wasn't
* clicking on the frame to start the move.
*/
unconstrained_user_action =
info->is_user_action && !window->display->grab_frame_action;
info->is_user_action && (!grab_info || !grab_info->grab_frame_action);
/* Exit early if we know the constraint won't apply--note that this constraint
* is only meant for normal windows (e.g. we don't want docks to be shoved
@ -1407,8 +1410,8 @@ constrain_titlebar_visible (MetaWindow *window,
*/
if (window->frame)
{
bottom_amount = info->current.height + info->borders->visible.bottom;
vert_amount_onscreen = info->borders->visible.top;
bottom_amount = info->current.height + info->fgeom->bottom_height;
vert_amount_onscreen = info->fgeom->top_height;
}
else
bottom_amount = vert_amount_offscreen;
@ -1482,8 +1485,8 @@ constrain_partially_onscreen (MetaWindow *window,
*/
if (window->frame)
{
bottom_amount = info->current.height + info->borders->visible.bottom;
vert_amount_onscreen = info->borders->visible.top;
bottom_amount = info->current.height + info->fgeom->bottom_height;
vert_amount_onscreen = info->fgeom->top_height;
}
else
bottom_amount = vert_amount_offscreen;

View File

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

View File

@ -30,6 +30,11 @@
#include <meta/prefs.h>
#include <meta/errors.h>
#ifdef HAVE_XINPUT2
#include <X11/extensions/XInput2.h>
#include "devices-xi2.h"
#endif
/* Looks up the MetaWindow representing the frame of the given X window.
* Used as a helper function by a bunch of the functions below.
*
@ -212,7 +217,7 @@ lower_window_and_transients (MetaWindow *window,
meta_window_foreach_transient (window, lower_window_and_transients, NULL);
if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK &&
if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK &&
meta_prefs_get_raise_on_click ())
{
/* Move window to the back of the focusing workspace's MRU list.
@ -245,9 +250,19 @@ lower_window_and_transients (MetaWindow *window,
void
meta_core_user_lower_and_unfocus (Display *xdisplay,
Window frame_xwindow,
int device_id,
guint32 timestamp)
{
MetaWindow *window = get_window (xdisplay, frame_xwindow);
MetaDevice *pointer;
pointer = meta_device_map_lookup (window->display->device_map, device_id);
if (pointer == NULL)
return;
if (!META_IS_DEVICE_POINTER (pointer))
pointer = meta_device_get_paired_device (pointer);
lower_window_and_transients (window, NULL);
@ -256,6 +271,7 @@ meta_core_user_lower_and_unfocus (Display *xdisplay,
* this will be invoked via keyboard action or by a mouse action;
* in either case the window or a modal child will have been focused.) */
meta_workspace_focus_default_window (window->screen->active_workspace,
pointer,
NULL,
timestamp);
}
@ -263,16 +279,21 @@ meta_core_user_lower_and_unfocus (Display *xdisplay,
void
meta_core_lower_beneath_grab_window (Display *xdisplay,
Window xwindow,
int device_id,
guint32 timestamp)
{
XWindowChanges changes;
MetaDisplay *display;
MetaScreen *screen;
MetaWindow *grab_window;
MetaDevice *pointer;
MetaGrabInfo *grab_info;
display = meta_display_for_x_display (xdisplay);
screen = meta_display_screen_for_xwindow (display, xwindow);
grab_window = display->grab_window;
pointer = meta_device_map_lookup (display->device_map, device_id);
grab_info = meta_display_get_grab_info (display, pointer);
grab_window = grab_info->grab_window;
if (grab_window == NULL)
return;
@ -491,18 +512,27 @@ meta_core_get_active_workspace (Screen *xscreen)
void
meta_core_show_window_menu (Display *xdisplay,
Window frame_xwindow,
int device_id,
int root_x,
int root_y,
int button,
guint32 timestamp)
{
MetaWindow *window = get_window (xdisplay, frame_xwindow);
MetaDevice *device;
/* There is already a menu popped up,
* most likely from another device
*/
if (window->menu)
return;
if (meta_prefs_get_raise_on_click ())
meta_window_raise (window);
meta_window_focus (window, timestamp);
meta_window_show_menu (window, root_x, root_y, button, timestamp);
device = meta_device_map_lookup (window->display->device_map, device_id);
meta_window_show_menu (window, device, root_x, root_y, button, timestamp);
}
void
@ -538,70 +568,70 @@ meta_core_get_menu_accelerator (MetaMenuOp menu_op,
break;
case META_MENU_OP_UNSTICK:
case META_MENU_OP_STICK:
name = "toggle-on-all-workspaces";
name = "toggle_on_all_workspaces";
break;
case META_MENU_OP_ABOVE:
case META_MENU_OP_UNABOVE:
name = "toggle-above";
name = "toggle_above";
break;
case META_MENU_OP_WORKSPACES:
switch (workspace)
{
case 1:
name = "move-to-workspace-1";
name = "move_to_workspace_1";
break;
case 2:
name = "move-to-workspace-2";
name = "move_to_workspace_2";
break;
case 3:
name = "move-to-workspace-3";
name = "move_to_workspace_3";
break;
case 4:
name = "move-to-workspace-4";
name = "move_to_workspace_4";
break;
case 5:
name = "move-to-workspace-5";
name = "move_to_workspace_5";
break;
case 6:
name = "move-to-workspace-6";
name = "move_to_workspace_6";
break;
case 7:
name = "move-to-workspace-7";
name = "move_to_workspace_7";
break;
case 8:
name = "move-to-workspace-8";
name = "move_to_workspace_8";
break;
case 9:
name = "move-to-workspace-9";
name = "move_to_workspace_9";
break;
case 10:
name = "move-to-workspace-10";
name = "move_to_workspace_10";
break;
case 11:
name = "move-to-workspace-11";
name = "move_to_workspace_11";
break;
case 12:
name = "move-to-workspace-12";
name = "move_to_workspace_12";
break;
}
break;
case META_MENU_OP_MOVE:
name = "begin-move";
name = "begin_move";
break;
case META_MENU_OP_RESIZE:
name = "begin-resize";
name = "begin_resize";
break;
case META_MENU_OP_MOVE_LEFT:
name = "move-to-workspace-left";
name = "move_to_workspace_left";
break;
case META_MENU_OP_MOVE_RIGHT:
name = "move-to-workspace-right";
name = "move_to_workspace_right";
break;
case META_MENU_OP_MOVE_UP:
name = "move-to-workspace-up";
name = "move_to_workspace_up";
break;
case META_MENU_OP_MOVE_DOWN:
name = "move-to-workspace-down";
name = "move_to_workspace_down";
break;
case META_MENU_OP_RECOVER:
/* No keybinding for this one */
@ -638,6 +668,7 @@ meta_core_get_workspace_name_with_index (Display *xdisplay,
gboolean
meta_core_begin_grab_op (Display *xdisplay,
Window frame_xwindow,
int device_id,
MetaGrabOp op,
gboolean pointer_already_grabbed,
gboolean frame_action,
@ -650,13 +681,16 @@ meta_core_begin_grab_op (Display *xdisplay,
MetaWindow *window = get_window (xdisplay, frame_xwindow);
MetaDisplay *display;
MetaScreen *screen;
MetaDevice *device;
display = meta_display_for_x_display (xdisplay);
screen = meta_display_screen_for_xwindow (display, frame_xwindow);
g_assert (screen != NULL);
return meta_display_begin_grab_op (display, screen, window,
device = meta_device_map_lookup (display->device_map, device_id);
return meta_display_begin_grab_op (display, screen, window, device,
op, pointer_already_grabbed,
frame_action,
button, modmask,
@ -665,57 +699,58 @@ meta_core_begin_grab_op (Display *xdisplay,
void
meta_core_end_grab_op (Display *xdisplay,
int device_id,
guint32 timestamp)
{
MetaDisplay *display;
display = meta_display_for_x_display (xdisplay);
MetaDevice *device;
meta_display_end_grab_op (display, timestamp);
display = meta_display_for_x_display (xdisplay);
device = meta_device_map_lookup (display->device_map, device_id);
meta_display_end_grab_op (display, device, timestamp);
}
MetaGrabOp
meta_core_get_grab_op (Display *xdisplay)
meta_core_frame_has_grab (Display *xdisplay,
Window frame_xwindow,
gint *device_id,
gint *button_ret)
{
MetaDisplay *display;
display = meta_display_for_x_display (xdisplay);
MetaWindow *window;
return display->grab_op;
window = get_window (xdisplay, frame_xwindow);
if (window != NULL &&
window->cur_grab != NULL)
{
if (button_ret)
*button_ret = window->cur_grab->grab_button;
if (device_id)
*device_id = meta_device_get_id (window->cur_grab->grab_pointer);
return window->cur_grab->grab_op;
}
return META_GRAB_OP_NONE;
}
Window
meta_core_get_grab_frame (Display *xdisplay)
meta_core_get_frame (Display *xdisplay,
Window client_xwindow)
{
MetaDisplay *display;
MetaWindow *window;
display = meta_display_for_x_display (xdisplay);
window = meta_display_lookup_x_window (display, client_xwindow);
g_assert (display != NULL);
g_assert (display->grab_op == META_GRAB_OP_NONE ||
display->grab_screen != NULL);
g_assert (display->grab_op == META_GRAB_OP_NONE ||
display->grab_screen->display->xdisplay == xdisplay);
if (display->grab_op != META_GRAB_OP_NONE &&
display->grab_window &&
display->grab_window->frame)
return display->grab_window->frame->xwindow;
else
return None;
}
if (window &&
window->frame)
return window->frame->xwindow;
int
meta_core_get_grab_button (Display *xdisplay)
{
MetaDisplay *display;
display = meta_display_for_x_display (xdisplay);
if (display->grab_op == META_GRAB_OP_NONE)
return -1;
return display->grab_button;
return None;
}
void
@ -731,13 +766,24 @@ meta_core_grab_buttons (Display *xdisplay,
}
void
meta_core_set_screen_cursor (Display *xdisplay,
Window frame_on_screen,
MetaCursor cursor)
meta_core_set_screen_cursor (Display *xdisplay,
Window frame_on_screen,
gint device_id,
MetaCursor cursor)
{
MetaWindow *window = get_window (xdisplay, frame_on_screen);
MetaDevice *pointer;
meta_frame_set_screen_cursor (window->frame, cursor);
pointer = meta_device_map_lookup (window->display->device_map,
device_id);
if (pointer == NULL)
return;
if (!META_IS_DEVICE_POINTER (pointer))
pointer = meta_device_get_paired_device (pointer);
meta_frame_set_screen_cursor (window->frame, pointer, cursor);
}
void
@ -775,3 +821,69 @@ meta_invalidate_default_icons (void)
g_slist_free (windows);
}
/* Selects events on an xwindow, using XInput2 if available/in use,
* this function doesn't require the xwindow to have a backing
* MetaWindow.
*/
void
meta_core_select_events (Display *xdisplay,
Window xwindow,
gint evmask,
gboolean preserve_old_mask)
{
MetaDisplay *display;
display = meta_display_for_x_display (xdisplay);
#ifdef HAVE_XINPUT2
if (display->have_xinput2)
{
XIEventMask mask;
mask.deviceid = XIAllMasterDevices;
mask.mask = meta_device_xi2_translate_event_mask (evmask,
&mask.mask_len);
if (preserve_old_mask)
{
XIEventMask *prev;
gint n_masks, i, j;
prev = XIGetSelectedEvents (xdisplay, xwindow, &n_masks);
for (i = 0; i < n_masks; i++)
{
if (prev[i].deviceid != XIAllMasterDevices)
continue;
for (j = 0; j < MIN (mask.mask_len, prev[i].mask_len); j++)
mask.mask[j] |= prev[i].mask[j];
}
XFree (prev);
}
XISelectEvents (xdisplay, xwindow, &mask, 1);
/* Unset any input event so they are only handled via XInput2 */
evmask &= ~(KeyPressMask | KeyReleaseMask |
ButtonPressMask | ButtonReleaseMask |
EnterWindowMask | LeaveWindowMask |
PointerMotionMask | PointerMotionHintMask |
Button1MotionMask | Button2MotionMask |
Button3MotionMask | Button4MotionMask |
Button5MotionMask | ButtonMotionMask |
FocusChangeMask);
}
#endif
if (preserve_old_mask)
{
XWindowAttributes attr;
if (XGetWindowAttributes (xdisplay, xwindow, &attr))
evmask |= attr.your_event_mask;
}
XSelectInput (xdisplay, xwindow, evmask);
}

View File

@ -110,6 +110,7 @@ void meta_core_user_raise (Display *xdisplay,
Window frame_xwindow);
void meta_core_user_lower_and_unfocus (Display *xdisplay,
Window frame_xwindow,
int device_id,
guint32 timestamp);
void meta_core_user_focus (Display *xdisplay,
@ -118,6 +119,7 @@ void meta_core_user_focus (Display *xdisplay,
void meta_core_lower_beneath_grab_window (Display *xdisplay,
Window xwindow,
int device_id,
guint32 timestamp);
void meta_core_minimize (Display *xdisplay,
@ -163,6 +165,7 @@ const char* meta_core_get_workspace_name_with_index (Display *xdisplay,
void meta_core_show_window_menu (Display *xdisplay,
Window frame_xwindow,
int device_id,
int root_x,
int root_y,
int button,
@ -175,6 +178,7 @@ void meta_core_get_menu_accelerator (MetaMenuOp menu_op,
gboolean meta_core_begin_grab_op (Display *xdisplay,
Window frame_xwindow,
int device_id,
MetaGrabOp op,
gboolean pointer_already_grabbed,
gboolean frame_action,
@ -184,18 +188,29 @@ gboolean meta_core_begin_grab_op (Display *xdisplay,
int root_x,
int root_y);
void meta_core_end_grab_op (Display *xdisplay,
int device_id,
guint32 timestamp);
MetaGrabOp meta_core_get_grab_op (Display *xdisplay);
Window meta_core_get_grab_frame (Display *xdisplay);
int meta_core_get_grab_button (Display *xdisplay);
MetaGrabOp meta_core_frame_has_grab (Display *xdisplay,
Window frame_xwindow,
gint *device_id,
gint *button_ret);
Window meta_core_get_frame (Display *xdisplay,
Window client_xwindow);
void meta_core_grab_buttons (Display *xdisplay,
Window frame_xwindow);
void meta_core_set_screen_cursor (Display *xdisplay,
Window frame_on_screen,
MetaCursor cursor);
void meta_core_set_screen_cursor (Display *xdisplay,
Window frame_on_screen,
int device_id,
MetaCursor cursor);
void meta_core_select_events (Display *xdisplay,
Window xwindow,
gint evmask,
gboolean preserve_old_mask);
/* Used because we ignore EnterNotify when a window is unmapped that
* really shouldn't cause focus changes, by comparing the event serial

View File

@ -108,12 +108,8 @@ delete_ping_timeout_func (MetaDisplay *display,
/* Translators: %s is a window title */
if (window_title)
{
gchar *bold;
bold = g_strconcat ("<tt>", window_title, "</tt>", NULL);
tmp = g_markup_printf_escaped (_("%s is not responding."), bold);
g_free (bold);
}
tmp = g_markup_printf_escaped (_("<tt>%s</tt> is not responding."),
window_title);
else
tmp = g_strdup (_("Application is not responding."));

View File

@ -0,0 +1,69 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* Keyboard device abstraction */
/*
* Copyright (C) 2011 Carlos Garnacho
*
* 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 "device-keyboard.h"
G_DEFINE_ABSTRACT_TYPE (MetaDeviceKeyboard,
meta_device_keyboard,
META_TYPE_DEVICE)
static void
meta_device_keyboard_class_init (MetaDeviceKeyboardClass *klass)
{
}
static void
meta_device_keyboard_init (MetaDeviceKeyboard *keyboard)
{
}
Window
meta_device_keyboard_get_focus_window (MetaDeviceKeyboard *keyboard)
{
MetaDeviceKeyboardClass *klass;
g_return_val_if_fail (META_IS_DEVICE_KEYBOARD (keyboard), None);
klass = META_DEVICE_KEYBOARD_GET_CLASS (keyboard);
if (!klass->get_focus_window)
return None;
return (klass->get_focus_window) (keyboard);
}
void
meta_device_keyboard_set_focus_window (MetaDeviceKeyboard *keyboard,
Window xwindow,
Time timestamp)
{
MetaDeviceKeyboardClass *klass;
g_return_if_fail (META_IS_DEVICE_KEYBOARD (keyboard));
klass = META_DEVICE_KEYBOARD_GET_CLASS (keyboard);
if (klass->set_focus_window)
(klass->set_focus_window) (keyboard, xwindow, timestamp);
}

View File

@ -0,0 +1,69 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/**
* \file device-keyboard.h Keyboard device abstraction
*
* Input devices.
* This file contains the internal abstraction of keyboard devices so
* XInput2/core events can be handled similarly.
*/
/*
* Copyright (C) 2011 Carlos Garnacho
*
* 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_DEVICE_KEYBOARD_H
#define META_DEVICE_KEYBOARD_H
#include "display-private.h"
#include "device-private.h"
#define META_TYPE_DEVICE_KEYBOARD (meta_device_keyboard_get_type ())
#define META_DEVICE_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_DEVICE_KEYBOARD, MetaDeviceKeyboard))
#define META_DEVICE_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_DEVICE_KEYBOARD, MetaDeviceKeyboardClass))
#define META_IS_DEVICE_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_DEVICE_KEYBOARD))
#define META_IS_DEVICE_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_DEVICE_KEYBOARD))
#define META_DEVICE_KEYBOARD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_DEVICE_KEYBOARD, MetaDeviceKeyboardClass))
typedef struct _MetaDeviceKeyboard MetaDeviceKeyboard;
typedef struct _MetaDeviceKeyboardClass MetaDeviceKeyboardClass;
struct _MetaDeviceKeyboard
{
MetaDevice parent_instance;
};
struct _MetaDeviceKeyboardClass
{
MetaDeviceClass parent_instance;
Window (* get_focus_window) (MetaDeviceKeyboard *keyboard);
void (* set_focus_window) (MetaDeviceKeyboard *keyboard,
Window xwindow,
Time timestamp);
};
GType meta_device_keyboard_get_type (void) G_GNUC_CONST;
Window meta_device_keyboard_get_focus_window (MetaDeviceKeyboard *keyboard);
void meta_device_keyboard_set_focus_window (MetaDeviceKeyboard *keyboard,
Window xwindow,
Time timestamp);
#endif /* META_DEVICE_KEYBOARD_H */

134
src/core/device-map-core.c Normal file
View File

@ -0,0 +1,134 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* Input device map, core protocol implementation */
/*
* Copyright (C) 2011 Carlos Garnacho
*
* 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 "device-map-core.h"
#include "devices-core.h"
G_DEFINE_TYPE (MetaDeviceMapCore, meta_device_map_core, META_TYPE_DEVICE_MAP)
static gboolean
meta_device_map_core_grab_key (MetaDeviceMap *device_map,
Window xwindow,
guint keycode,
guint modifiers,
gboolean sync)
{
MetaDisplay *display;
gint retval;
display = meta_device_map_get_display (device_map);
retval = XGrabKey (display->xdisplay, keycode, modifiers,
xwindow, True,
GrabModeAsync, /* Never care about the other device */
(sync) ? GrabModeSync : GrabModeAsync);
return (retval == Success);
}
static void
meta_device_map_core_ungrab_key (MetaDeviceMap *device_map,
Window xwindow,
guint keycode,
guint modifiers)
{
MetaDisplay *display;
display = meta_device_map_get_display (device_map);
XUngrabKey (display->xdisplay, keycode, modifiers, xwindow);
}
static gboolean
meta_device_map_core_grab_button (MetaDeviceMap *device_map,
Window xwindow,
guint n_button,
guint modifiers,
guint evmask,
gboolean sync)
{
MetaDisplay *display;
gint retval;
display = meta_device_map_get_display (device_map);
retval = XGrabButton (display->xdisplay, n_button,
modifiers, xwindow, False,
evmask,
(sync) ? GrabModeSync : GrabModeAsync,
GrabModeAsync, /* Never care about the other device */
None, None);
return (retval == Success);
}
static void
meta_device_map_core_ungrab_button (MetaDeviceMap *device_map,
Window xwindow,
guint n_button,
guint modifiers)
{
MetaDisplay *display;
display = meta_device_map_get_display (device_map);
XUngrabButton (display->xdisplay, n_button, modifiers, xwindow);
}
static void
meta_device_map_core_constructed (GObject *object)
{
MetaDeviceMap *device_map = META_DEVICE_MAP (object);
MetaDevice *pointer, *keyboard;
MetaDisplay *display;
display = meta_device_map_get_display (device_map);
/* Insert core devices */
pointer = meta_device_pointer_core_new (display);
meta_device_map_add_device (device_map, pointer);
keyboard = meta_device_keyboard_core_new (display);
meta_device_map_add_device (device_map, keyboard);
meta_device_pair_devices (pointer, keyboard);
g_object_unref (pointer);
g_object_unref (keyboard);
}
static void
meta_device_map_core_class_init (MetaDeviceMapCoreClass *klass)
{
MetaDeviceMapClass *device_map_class = META_DEVICE_MAP_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->constructed = meta_device_map_core_constructed;
device_map_class->grab_key = meta_device_map_core_grab_key;
device_map_class->ungrab_key = meta_device_map_core_ungrab_key;
device_map_class->grab_button = meta_device_map_core_grab_button;
device_map_class->ungrab_button = meta_device_map_core_ungrab_button;
}
static void
meta_device_map_core_init (MetaDeviceMapCore *device_map)
{
}

View File

@ -0,0 +1,56 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/**
* \file device-map-core.h device map for core devices
*
* Input devices.
* This file contains the core protocol implementation of the device map
*/
/*
* Copyright (C) 2011 Carlos Garnacho
*
* 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_DEVICE_MAP_CORE_H
#define META_DEVICE_MAP_CORE_H
typedef struct _MetaDeviceMapCore MetaDeviceMapCore;
typedef struct _MetaDeviceMapCoreClass MetaDeviceMapCoreClass;
#include "device-map-private.h"
#define META_TYPE_DEVICE_MAP_CORE (meta_device_map_core_get_type ())
#define META_DEVICE_MAP_CORE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_DEVICE_MAP_CORE, MetaDeviceMapCore))
#define META_DEVICE_MAP_CORE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_DEVICE_MAP_CORE, MetaDeviceMapCoreClass))
#define META_IS_DEVICE_MAP_CORE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_DEVICE_MAP_CORE))
#define META_IS_DEVICE_MAP_CORE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_DEVICE_MAP_CORE))
#define META_DEVICE_MAP_CORE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_DEVICE_MAP_CORE, MetaDeviceMapCoreClass))
struct _MetaDeviceMapCore
{
MetaDeviceMap parent_instance;
};
struct _MetaDeviceMapCoreClass
{
MetaDeviceMapClass parent_class;
};
GType meta_device_map_core_get_type (void) G_GNUC_CONST;
#endif /* META_DEVICE_MAP_CORE_H */

View File

@ -0,0 +1,111 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/**
* \file device-map.h object containing input devices
*
* Input devices.
* This file contains the device map, used to find out the device behind
* XInput2/core events.
*/
/*
* Copyright (C) 2011 Carlos Garnacho
*
* 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_DEVICE_MAP_PRIVATE_H
#define META_DEVICE_MAP_PRIVATE_H
#include <meta/device-map.h>
#include <meta/device.h>
#include "display-private.h"
#include "device-private.h"
/* Device IDs for Virtual Core Pointer/Keyboard,
* use only in case of emergency.
*/
#define META_CORE_POINTER_ID 2
#define META_CORE_KEYBOARD_ID 3
struct _MetaDeviceMap
{
GObject parent_instance;
gpointer priv;
};
struct _MetaDeviceMapClass
{
GObjectClass parent_instance;
void (* device_added) (MetaDeviceMap *device_map,
MetaDevice *device);
void (* device_removed) (MetaDeviceMap *device_map,
MetaDevice *device);
gboolean (* grab_key) (MetaDeviceMap *device_map,
Window xwindow,
guint keycode,
guint modifiers,
gboolean sync);
void (* ungrab_key) (MetaDeviceMap *device_map,
Window xwindow,
guint keycode,
guint modifiers);
gboolean (* grab_button) (MetaDeviceMap *device_map,
Window xwindow,
guint n_button,
guint modifiers,
guint evmask,
gboolean sync);
void (* ungrab_button) (MetaDeviceMap *pointer,
Window xwindow,
guint n_button,
guint modifiers);
};
GType meta_device_map_get_type (void) G_GNUC_CONST;
MetaDeviceMap * meta_device_map_new (MetaDisplay *display,
gboolean force_core);
void meta_device_map_add_device (MetaDeviceMap *device_map,
MetaDevice *device);
void meta_device_map_remove_device (MetaDeviceMap *device_map,
MetaDevice *device);
gboolean meta_device_map_grab_key (MetaDeviceMap *device_map,
Window xwindow,
guint keycode,
guint modifiers,
gboolean sync);
void meta_device_map_ungrab_key (MetaDeviceMap *device_map,
Window xwindow,
guint keycode,
guint modifiers);
gboolean meta_device_map_grab_button (MetaDeviceMap *device_map,
Window xwindow,
guint n_button,
guint modifiers,
guint evmask,
gboolean sync);
void meta_device_map_ungrab_button (MetaDeviceMap *device_map,
Window xwindow,
guint n_button,
guint modifiers);
#endif /* META_DEVICE_MAP_PRIVATE_H */

269
src/core/device-map-xi2.c Normal file
View File

@ -0,0 +1,269 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* Input device map, XInput2 implementation */
/*
* Copyright (C) 2011 Carlos Garnacho
*
* 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 "device-map-xi2.h"
#include <X11/extensions/XInput2.h>
#include "devices-xi2.h"
#define XINPUT2_VERSION_MAJOR 2
#define XINPUT2_VERSION_MINOR 0
G_DEFINE_TYPE (MetaDeviceMapXI2, meta_device_map_xi2, META_TYPE_DEVICE_MAP)
static gboolean
meta_device_map_xi2_grab_key (MetaDeviceMap *device_map,
Window xwindow,
guint keycode,
guint modifiers,
gboolean sync)
{
XIGrabModifiers mods = { modifiers, 0 };
MetaDisplay *display;
XIEventMask mask;
gint retval;
display = meta_device_map_get_display (device_map);
mask.deviceid = XIAllMasterDevices;
mask.mask = meta_device_xi2_translate_event_mask (KeyPressMask |
KeyReleaseMask,
&mask.mask_len);
/* FIXME: Doesn't seem to work with
* XIAllMasterDevices, use the VCK
* at the moment
*/
retval = XIGrabKeycode (display->xdisplay,
META_CORE_KEYBOARD_ID,
keycode, xwindow,
(sync) ? GrabModeSync : GrabModeAsync,
GrabModeAsync, /* Never care about the other device */
True, &mask, 1, &mods);
return (retval == Success);
}
static void
meta_device_map_xi2_ungrab_key (MetaDeviceMap *device_map,
Window xwindow,
guint keycode,
guint modifiers)
{
XIGrabModifiers mods = { modifiers, 0 };
MetaDisplay *display;
display = meta_device_map_get_display (device_map);
XIUngrabKeycode (display->xdisplay,
META_CORE_KEYBOARD_ID,
keycode, xwindow,
1, &mods);
}
static gboolean
meta_device_map_xi2_grab_button (MetaDeviceMap *device_map,
Window xwindow,
guint n_button,
guint modifiers,
guint evmask,
gboolean sync)
{
XIGrabModifiers mods = { modifiers, 0 };
XIEventMask mask;
MetaDisplay *display;
int retval;
display = meta_device_map_get_display (device_map);
mask.deviceid = XIAllMasterDevices;
mask.mask = meta_device_xi2_translate_event_mask (evmask, &mask.mask_len);
retval = XIGrabButton (display->xdisplay,
XIAllMasterDevices,
n_button, xwindow, None,
(sync) ? GrabModeSync : GrabModeAsync,
GrabModeAsync, /* Never care about the other device */
False, &mask, 1, &mods);
return (retval == Success);
}
static void
meta_device_map_xi2_ungrab_button (MetaDeviceMap *device_map,
Window xwindow,
guint n_button,
guint modifiers)
{
XIGrabModifiers mods = { modifiers, 0 };
MetaDisplay *display;
display = meta_device_map_get_display (device_map);
XIUngrabButton (display->xdisplay,
META_CORE_POINTER_ID,
//XIAllMasterDevices,
n_button, xwindow, 1, &mods);
}
static void
add_device_from_info (MetaDeviceMap *device_map,
gint use,
gint device_id)
{
MetaDevice *device;
MetaDisplay *display;
display = meta_device_map_get_display (device_map);
if (use == XIMasterPointer)
device = meta_device_pointer_xi2_new (display, device_id);
else if (use == XIMasterKeyboard)
device = meta_device_keyboard_xi2_new (display, device_id);
if (device)
{
meta_device_map_add_device (device_map, device);
g_object_unref (device);
}
}
static void
pair_devices (gpointer key,
gpointer value,
gpointer user_data)
{
MetaDevice *device1, *device2;
MetaDeviceMap *device_map;
device_map = user_data;
device1 = meta_device_map_lookup (device_map, GPOINTER_TO_INT (key));
device2 = meta_device_map_lookup (device_map, GPOINTER_TO_INT (value));
meta_device_pair_devices (device1, device2);
}
static void
meta_device_map_xi2_constructed (GObject *object)
{
MetaDeviceMap *device_map = META_DEVICE_MAP (object);
MetaDisplay *display;
XIDeviceInfo *info;
GHashTable *pairs;
int n_devices, i;
display = meta_device_map_get_display (device_map);
/* We're only interested in master devices,
* detached slave devices are left for applications
* to handle.
*/
info = XIQueryDevice (display->xdisplay, XIAllMasterDevices, &n_devices);
pairs = g_hash_table_new (NULL, NULL);
for (i = 0; i < n_devices; i++)
{
add_device_from_info (device_map, info[i].use, info[i].deviceid);
g_hash_table_insert (pairs,
GINT_TO_POINTER (info[i].deviceid),
GINT_TO_POINTER (info[i].attachment));
}
g_hash_table_foreach (pairs, pair_devices, device_map);
g_hash_table_destroy (pairs);
XIFreeDeviceInfo (info);
}
static void
meta_device_map_xi2_class_init (MetaDeviceMapXI2Class *klass)
{
MetaDeviceMapClass *device_map_class = META_DEVICE_MAP_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->constructed = meta_device_map_xi2_constructed;
device_map_class->grab_key = meta_device_map_xi2_grab_key;
device_map_class->ungrab_key = meta_device_map_xi2_ungrab_key;
device_map_class->grab_button = meta_device_map_xi2_grab_button;
device_map_class->ungrab_button = meta_device_map_xi2_ungrab_button;
}
static void
meta_device_map_xi2_init (MetaDeviceMapXI2 *device_map)
{
}
gboolean
meta_device_map_xi2_handle_hierarchy_event (MetaDeviceMapXI2 *device_map,
XEvent *ev)
{
MetaDisplay *display;
display = meta_device_map_get_display (META_DEVICE_MAP (device_map));
if (ev->type == GenericEvent &&
ev->xcookie.extension == display->xinput2_opcode)
{
XIHierarchyEvent *xev;
GHashTable *pairs;
gint i;
g_assert (display->have_xinput2 == TRUE);
xev = (XIHierarchyEvent *) ev->xcookie.data;
if (xev->evtype != XI_HierarchyChanged)
return FALSE;
pairs = g_hash_table_new (NULL, NULL);
for (i = 0; i < xev->num_info; i++)
{
if (xev->info[i].flags & XIMasterAdded)
{
add_device_from_info (META_DEVICE_MAP (device_map),
xev->info[i].use,
xev->info[i].deviceid);
g_hash_table_insert (pairs,
GINT_TO_POINTER (xev->info[i].deviceid),
GINT_TO_POINTER (xev->info[i].attachment));
}
else if (xev->info[i].flags & XIMasterRemoved)
{
MetaDevice *device;
device = meta_device_map_lookup (META_DEVICE_MAP (device_map),
xev->info[i].deviceid);
if (device)
meta_device_map_remove_device (META_DEVICE_MAP (device_map),
device);
}
}
g_hash_table_foreach (pairs, pair_devices, device_map);
g_hash_table_destroy (pairs);
return TRUE;
}
return FALSE;
}

59
src/core/device-map-xi2.h Normal file
View File

@ -0,0 +1,59 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/**
* \file device-map-xi2.h device map for XInput2 devices
*
* Input devices.
* This file contains the XInput2 implementation of the device map
*/
/*
* Copyright (C) 2011 Carlos Garnacho
*
* 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_DEVICE_MAP_XI2_H
#define META_DEVICE_MAP_XI2_H
typedef struct _MetaDeviceMapXI2 MetaDeviceMapXI2;
typedef struct _MetaDeviceMapXI2Class MetaDeviceMapXI2Class;
#include "device-map-private.h"
#define META_TYPE_DEVICE_MAP_XI2 (meta_device_map_xi2_get_type ())
#define META_DEVICE_MAP_XI2(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_DEVICE_MAP_XI2, MetaDeviceMapXI2))
#define META_DEVICE_MAP_XI2_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_DEVICE_MAP_XI2, MetaDeviceMapXI2Class))
#define META_IS_DEVICE_MAP_XI2(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_DEVICE_MAP_XI2))
#define META_IS_DEVICE_MAP_XI2_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_DEVICE_MAP_XI2))
#define META_DEVICE_MAP_XI2_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_DEVICE_MAP_XI2, MetaDeviceMapXI2Class))
struct _MetaDeviceMapXI2
{
MetaDeviceMap parent_instance;
};
struct _MetaDeviceMapXI2Class
{
MetaDeviceMapClass parent_class;
};
GType meta_device_map_xi2_get_type (void) G_GNUC_CONST;
gboolean meta_device_map_xi2_handle_hierarchy_event (MetaDeviceMapXI2 *device_map,
XEvent *ev);
#endif /* META_DEVICE_MAP_XI2_H */

390
src/core/device-map.c Normal file
View File

@ -0,0 +1,390 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* Input device map */
/*
* Copyright (C) 2011 Carlos Garnacho
*
* 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 "device-map-private.h"
#include "device-map-core.h"
#ifdef HAVE_XINPUT2
#include <X11/extensions/XInput2.h>
#include "device-map-xi2.h"
#define XINPUT2_VERSION_MAJOR 2
#define XINPUT2_VERSION_MINOR 0
#endif
G_DEFINE_TYPE (MetaDeviceMap, meta_device_map, G_TYPE_OBJECT)
typedef struct MetaDeviceMapPrivate MetaDeviceMapPrivate;
struct MetaDeviceMapPrivate
{
MetaDisplay *display;
GHashTable *devices;
};
enum {
PROP_0,
PROP_DISPLAY
};
enum {
DEVICE_ADDED,
DEVICE_REMOVED,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };
static void
meta_device_map_get_property (GObject *object,
guint param_id,
GValue *value,
GParamSpec *pspec)
{
MetaDeviceMapPrivate *priv;
priv = META_DEVICE_MAP (object)->priv;
switch (param_id)
{
case PROP_DISPLAY:
g_value_set_object (value, priv->display);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
}
}
static void
meta_device_map_set_property (GObject *object,
guint param_id,
const GValue *value,
GParamSpec *pspec)
{
MetaDeviceMapPrivate *priv;
priv = META_DEVICE_MAP (object)->priv;
switch (param_id)
{
case PROP_DISPLAY:
priv->display = g_value_get_object (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
}
}
static void
meta_device_map_finalize (GObject *object)
{
MetaDeviceMapPrivate *priv;
GHashTableIter iter;
MetaDevice *device;
priv = META_DEVICE_MAP (object)->priv;
g_hash_table_iter_init (&iter, priv->devices);
while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &device))
{
/* Detach the device */
g_hash_table_iter_steal (&iter);
g_signal_emit (object, signals[DEVICE_REMOVED], 0, device);
g_object_unref (device);
}
g_hash_table_destroy (priv->devices);
G_OBJECT_CLASS (meta_device_map_parent_class)->finalize (object);
}
static void
meta_device_map_class_init (MetaDeviceMapClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->get_property = meta_device_map_get_property;
object_class->set_property = meta_device_map_set_property;
object_class->finalize = meta_device_map_finalize;
g_object_class_install_property (object_class,
PROP_DISPLAY,
g_param_spec_object ("display",
"Display",
"Display",
META_TYPE_DISPLAY,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
signals[DEVICE_ADDED] =
g_signal_new ("device-added",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, META_TYPE_DEVICE);
signals[DEVICE_REMOVED] =
g_signal_new ("device-removed",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, META_TYPE_DEVICE);
g_type_class_add_private (klass, sizeof (MetaDeviceMapPrivate));
}
static void
meta_device_map_init (MetaDeviceMap *device_map)
{
MetaDeviceMapPrivate *priv;
priv = device_map->priv = G_TYPE_INSTANCE_GET_PRIVATE (device_map,
META_TYPE_DEVICE_MAP,
MetaDeviceMapPrivate);
priv->devices = g_hash_table_new_full (NULL, NULL, NULL,
(GDestroyNotify) g_object_unref);
}
void
meta_device_map_add_device (MetaDeviceMap *device_map,
MetaDevice *device)
{
MetaDeviceMapPrivate *priv;
priv = device_map->priv;
g_hash_table_insert (priv->devices,
GINT_TO_POINTER (meta_device_get_id (device)),
g_object_ref (device));
g_signal_emit (device_map, signals[DEVICE_ADDED], 0, device);
}
void
meta_device_map_remove_device (MetaDeviceMap *device_map,
MetaDevice *device)
{
MetaDeviceMapPrivate *priv;
priv = device_map->priv;
if (g_hash_table_steal (priv->devices,
GINT_TO_POINTER (meta_device_get_id (device))))
{
g_signal_emit (device_map, signals[DEVICE_REMOVED], 0, device);
g_object_unref (device);
}
}
#ifdef HAVE_XINPUT2
static gboolean
initialize_xinput (MetaDisplay *display)
{
int major, minor, opcode;
int unused;
if (!XQueryExtension (display->xdisplay,
"XInputExtension",
&opcode, &unused, &unused))
return FALSE;
major = XINPUT2_VERSION_MAJOR;
minor = XINPUT2_VERSION_MINOR;
XIQueryVersion (display->xdisplay, &major, &minor);
if (major == XINPUT2_VERSION_MAJOR &&
minor == XINPUT2_VERSION_MINOR)
{
display->have_xinput2 = TRUE;
display->xinput2_opcode = opcode;
return TRUE;
}
return FALSE;
}
#endif /* HAVE_XINPUT2 */
MetaDeviceMap *
meta_device_map_new (MetaDisplay *display,
gboolean force_core)
{
GType type = META_TYPE_DEVICE_MAP_CORE;
#ifdef HAVE_XINPUT2
if (!force_core &&
initialize_xinput (display))
type = META_TYPE_DEVICE_MAP_XI2;
#endif
return g_object_new (type,
"display", display,
NULL);
}
/**
* meta_device_map_lookup:
* @device_map: a #MetaDeviceMap
* @device_id: ID for a device
*
* returns the device corresponding to @device_id
*
* Returns: (transfer none): (allow-none): The matching device, or %NULL.
**/
MetaDevice *
meta_device_map_lookup (MetaDeviceMap *device_map,
gint device_id)
{
MetaDeviceMapPrivate *priv;
g_return_val_if_fail (META_IS_DEVICE_MAP (device_map), NULL);
priv = device_map->priv;
return g_hash_table_lookup (priv->devices,
GINT_TO_POINTER (device_id));
}
/**
* meta_device_map_get_display:
* @device_map: a #MetaDeviceMap
*
* Returns the #MetaDisplay to which @device_map belongs to.
*
* Returns: (transfer none): The #MetaDisplay.
**/
MetaDisplay *
meta_device_map_get_display (MetaDeviceMap *device_map)
{
MetaDeviceMapPrivate *priv;
g_return_val_if_fail (META_IS_DEVICE_MAP (device_map), NULL);
priv = device_map->priv;
return priv->display;
}
/**
* meta_device_map_list_devices:
* @device_map: a #MetaDeviceMap
*
* Returns the list of devices that @device_map holds.
*
* Returns: (element-type Meta.Device) (transfer container): the list
* of devices, the contained objects are owned by @device_map
* and should not be unref'ed. The list must be freed with
* g_list_free().
**/
GList *
meta_device_map_list_devices (MetaDeviceMap *device_map)
{
MetaDeviceMapPrivate *priv;
g_return_val_if_fail (META_IS_DEVICE_MAP (device_map), NULL);
priv = device_map->priv;
return g_hash_table_get_values (priv->devices);
}
gboolean
meta_device_map_grab_key (MetaDeviceMap *device_map,
Window xwindow,
guint keycode,
guint modifiers,
gboolean sync)
{
MetaDeviceMapClass *klass;
g_return_val_if_fail (META_IS_DEVICE_MAP (device_map), FALSE);
g_return_val_if_fail (xwindow != None, FALSE);
klass = META_DEVICE_MAP_GET_CLASS (device_map);
if (!klass->grab_key)
return FALSE;
return (klass->grab_key) (device_map, xwindow, keycode, modifiers, sync);
}
void
meta_device_map_ungrab_key (MetaDeviceMap *device_map,
Window xwindow,
guint keycode,
guint modifiers)
{
MetaDeviceMapClass *klass;
g_return_if_fail (META_IS_DEVICE_MAP (device_map));
g_return_if_fail (xwindow != None);
klass = META_DEVICE_MAP_GET_CLASS (device_map);
if (klass->ungrab_key)
(klass->ungrab_key) (device_map, xwindow, keycode, modifiers);
}
gboolean
meta_device_map_grab_button (MetaDeviceMap *device_map,
Window xwindow,
guint n_button,
guint modifiers,
guint evmask,
gboolean sync)
{
MetaDeviceMapClass *klass;
g_return_val_if_fail (META_IS_DEVICE_MAP (device_map), FALSE);
g_return_val_if_fail (xwindow != None, FALSE);
klass = META_DEVICE_MAP_GET_CLASS (device_map);
if (!klass->grab_button)
return FALSE;
return (klass->grab_button) (device_map, xwindow, n_button,
modifiers, evmask, sync);
}
void
meta_device_map_ungrab_button (MetaDeviceMap *device_map,
Window xwindow,
guint n_button,
guint modifiers)
{
MetaDeviceMapClass *klass;
g_return_if_fail (META_IS_DEVICE_MAP (device_map));
g_return_if_fail (xwindow != None);
klass = META_DEVICE_MAP_GET_CLASS (device_map);
if (klass->ungrab_button)
(klass->ungrab_button) (device_map, xwindow, n_button, modifiers);
}

124
src/core/device-pointer.c Normal file
View File

@ -0,0 +1,124 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* Pointer device abstraction */
/*
* Copyright (C) 2011 Carlos Garnacho
*
* 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 "device-pointer.h"
G_DEFINE_ABSTRACT_TYPE (MetaDevicePointer,
meta_device_pointer,
META_TYPE_DEVICE)
static void
meta_device_pointer_class_init (MetaDevicePointerClass *klass)
{
}
static void
meta_device_pointer_init (MetaDevicePointer *pointer)
{
}
void
meta_device_pointer_warp (MetaDevicePointer *pointer,
MetaScreen *screen,
gint x,
gint y)
{
MetaDevicePointerClass *klass;
g_return_if_fail (META_IS_DEVICE_POINTER (pointer));
g_return_if_fail (META_IS_SCREEN (screen));
klass = META_DEVICE_POINTER_GET_CLASS (pointer);
if (klass->warp)
(klass->warp) (pointer, screen, x, y);
}
void
meta_device_pointer_set_window_cursor (MetaDevicePointer *pointer,
Window xwindow,
MetaCursor cursor)
{
MetaDevicePointerClass *klass;
g_return_if_fail (META_IS_DEVICE_POINTER (pointer));
g_return_if_fail (xwindow != None);
klass = META_DEVICE_POINTER_GET_CLASS (pointer);
if (klass->set_window_cursor)
(klass->set_window_cursor) (pointer, xwindow, cursor);
}
gboolean
meta_device_pointer_query_position (MetaDevicePointer *pointer,
Window xwindow,
Window *root_ret,
Window *child_ret,
gint *root_x_ret,
gint *root_y_ret,
gint *x_ret,
gint *y_ret,
guint *mask_ret)
{
MetaDevicePointerClass *klass;
gint root_x, root_y, x, y;
Window root, child;
gboolean retval;
guint mask;
g_return_val_if_fail (META_IS_DEVICE_POINTER (pointer), FALSE);
g_return_val_if_fail (xwindow != None, FALSE);
klass = META_DEVICE_POINTER_GET_CLASS (pointer);
if (!klass->query_position)
return FALSE;
retval = (klass->query_position) (pointer, xwindow, &root, &child,
&root_x, &root_y, &x, &y, &mask);
if (root_ret)
*root_ret = root;
if (child_ret)
*child_ret = child;
if (root_x_ret)
*root_x_ret = root_x;
if (root_y_ret)
*root_y_ret = root_y;
if (x_ret)
*x_ret = x;
if (y_ret)
*y_ret = y;
if (mask_ret)
*mask_ret = mask;
return retval;
}

95
src/core/device-pointer.h Normal file
View File

@ -0,0 +1,95 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/**
* \file device-pointer.h Pointer device abstraction
*
* Input devices.
* This file contains the internal abstraction of pointer devices so
* XInput2/core events can be handled similarly.
*/
/*
* Copyright (C) 2011 Carlos Garnacho
*
* 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_DEVICE_POINTER_H
#define META_DEVICE_POINTER_H
#include "display-private.h"
#include <meta/screen.h>
#include "device-private.h"
#define META_TYPE_DEVICE_POINTER (meta_device_pointer_get_type ())
#define META_DEVICE_POINTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_DEVICE_POINTER, MetaDevicePointer))
#define META_DEVICE_POINTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_DEVICE_POINTER, MetaDevicePointerClass))
#define META_IS_DEVICE_POINTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_DEVICE_POINTER))
#define META_IS_DEVICE_POINTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_DEVICE_POINTER))
#define META_DEVICE_POINTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_DEVICE_POINTER, MetaDevicePointerClass))
typedef struct _MetaDevicePointer MetaDevicePointer;
typedef struct _MetaDevicePointerClass MetaDevicePointerClass;
struct _MetaDevicePointer
{
MetaDevice parent_instance;
};
struct _MetaDevicePointerClass
{
MetaDeviceClass parent_instance;
void (* warp) (MetaDevicePointer *pointer,
MetaScreen *screen,
gint x,
gint y);
void (* set_window_cursor) (MetaDevicePointer *pointer,
Window xwindow,
MetaCursor cursor);
gboolean (* query_position) (MetaDevicePointer *pointer,
Window xwindow,
Window *root,
Window *child,
gint *root_x,
gint *root_y,
gint *x,
gint *y,
guint *mask);
};
GType meta_device_pointer_get_type (void) G_GNUC_CONST;
void meta_device_pointer_warp (MetaDevicePointer *pointer,
MetaScreen *screen,
gint x,
gint y);
void meta_device_pointer_set_window_cursor (MetaDevicePointer *pointer,
Window xwindow,
MetaCursor cursor);
gboolean meta_device_pointer_query_position (MetaDevicePointer *pointer,
Window xwindow,
Window *root,
Window *child,
gint *root_x,
gint *root_y,
gint *x,
gint *y,
guint *mask);
#endif /* META_DEVICE_POINTER_H */

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