Compare commits

...

139 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
47b432bf89 Improve shadow defaults.
- menus have a very subtle shadow, define the outline better. Required for gtk theming.
- focused windows are better identified now as unfocused windows have a subtle shadow.

https://bugzilla.gnome.org/show_bug.cgi?id=649374
2011-07-11 16:00:03 +02:00
b70ccd2a56 Updated Spanish translation 2011-07-10 13:00:04 +02:00
be8df20675 Fix typo when computing shadow bounds
A x/y typo that was causing shadow bounds to be incorrectly
computed and trails to be left in some circumstances. Behavior
noted by Jakub Steiner.

https://bugzilla.gnome.org/show_bug.cgi?id=649374
2011-07-08 22:38:12 -04:00
4a10c95e76 core: Replace lower_beneath_focus_window()
The code assumed that the focus window was always the one at the
top of the window stack, which is not true if an unfocused window
has the above hint set.

Rather than fixing this assumption, rename the function to
lower_beneath_grab_window() and use the display's grab window - the
function is only used for displaying the tile previews, which means
that we want the grab window anyway.

https://bugzilla.gnome.org/show_bug.cgi?id=650661
2011-07-09 01:08:58 +02:00
54b2fab849 theme: Allow using custom colors from the GTK+ theme
Add an additional color type to pick up colors defined with
@define-color in the GTK+ theme's CSS:

  gtk:custom(name,fallback)

(where "name" refers to the name defined in GTK+'s CSS, and fallback
refers to an alternative color spec which is used when the color
referenced by "name" is not found)

The main intent of the change is to allow designers to improve
Adwaita's dark theme variant without having to compromise on colors
which work in the light variant as well.

https://bugzilla.gnome.org/show_bug.cgi?id=648709
2011-07-08 22:40:43 +02:00
8033184134 Fix out-of-tree build.
This patch fixes an issue encountered when building mutter
out-of-tree:

  * When generating mutter-enum-types.[ch], the glib-mkenums command is
    executed from $(srcdir), so it is wrong to prepend $(srcdir) to the
    template file.

https://bugzilla.gnome.org/show_bug.cgi?id=624910
2011-07-08 16:33:12 -04:00
d95da2dfbe theme: Port from GtkStateType to GtkStateFlags
We now use GtkStyleContext exclusively, so it's a bit weird to store
widget state as GtkStateType and translate it always to GtkStateFlags.
Just use GtkStateFlags instead of GtkStateType.

https://bugzilla.gnome.org/show_bug.cgi?id=650586
2011-07-08 21:40:55 +02:00
03457029f7 draw-workspace: Update to current GTK style API
Move from GtkStyle to GtkStyleContext.

https://bugzilla.gnome.org/show_bug.cgi?id=650586
2011-07-08 21:40:55 +02:00
f8d900c3ea theme: Add helper functions for light/dark colors
GtkStyleContext no longer has dark/light colors GtkStyle used to
have. We already have compatibility code for them in theme.c, so
add two helper functions to make it available outside theme.c.

https://bugzilla.gnome.org/show_bug.cgi?id=650586
2011-07-08 21:40:55 +02:00
e16beba111 mutter-window-demo: Port from GdkColor to GdkRGBA
GdkColor is about to be deprecated, so move to GdkRGBA instead.

https://bugzilla.gnome.org/show_bug.cgi?id=650586
2011-07-08 21:40:54 +02:00
60ee25d8d5 theme-viewer: Port from GdkColor to GdkRGBA
GdkColor is about to be deprecated, so move to GdkRGBA instead.

https://bugzilla.gnome.org/show_bug.cgi?id=650586
2011-07-08 21:40:54 +02:00
ce1369609f theme: Port from GdkColor to GdkRGBA
GdkColor is about to be deprecated, so move to GdkRGBA instead.

https://bugzilla.gnome.org/show_bug.cgi?id=650586
2011-07-08 01:29:54 +02:00
8199699e7c gradient: Port from GdkColor to GdkRGBA
GdkColor is about to be deprecated, so move to GdkRGBA instead.
It might be worth considering using cairo patterns for the gradients
rather than using custom code to render gradients to a pixbuf which
is then drawn with cairo, but for now this is just a straight port
of the existing code.

https://bugzilla.gnome.org/show_bug.cgi?id=650586
2011-07-08 01:29:54 +02:00
48cabd1364 window: fix appears-focused propagation with attached grandchildren
When detaching/attaching a dialog, we were only updating
appears-focused on the parent if the child itself was focused, but in
fact, we need to do it if the child has an attached child which is
focused too.

To simplify the case of detaching a focused subtree from its parent,
we change meta_window_propagate_focus_appearance() to use
@window->display->focus_window as the window to add/remove as the
attached_focus_window, and @window only as the starting point to
propagate from. That way we can propagate focus-removal up to
@window's (soon-to-be-ex-)ancestors without having to remove it from
its descendants as well.

https://bugzilla.gnome.org/show_bug.cgi?id=647712
2011-07-07 16:51:36 -04:00
6dc79ce60a reload_transient_for: avoid xtransient_for loops
Don't set a window's xtransient_for if it would create a loop. Since
this is the only place we ever set xtransient_for, we can therefore
assume everywhere else that it does not loop.

https://bugzilla.gnome.org/show_bug.cgi?id=647712
2011-07-07 16:51:36 -04:00
a8cfdc19e2 Added UG translation 2011-07-07 17:12:59 +02:00
db4ae415e3 Updated Galician translations 2011-07-04 22:23:27 +02:00
7842d92995 Updated Slovenian translation 2011-07-02 20:32:15 +02:00
b34c01a95a po/vi: spelling fixes 2011-07-02 13:49:25 +07:00
e4546829e3 Updated Spanish translation 2011-07-02 07:07:44 +02:00
8dc3de87ad Updated Spanish translation 2011-07-02 07:05:16 +02:00
e3094ace05 Updated Japanese translation. 2011-07-02 10:22:29 +09:00
6f49a00bbe Bump version to 3.1.3.1
Update NEWS
2011-07-01 19:26:50 -04:00
b5f277bd7b Freeze api_version to 3.0
Back the API version down to 3.0; since we don't make any stability
guarantees, there's no reason to have a merry-go-round of different
directories and filenames that people have to keep up with.
2011-07-01 19:19:11 -04:00
f798144bea Updated Norwegian bokmål translation 2011-07-02 00:16:49 +02:00
699fb0d0f1 Updated Hebrew translation. 2011-07-01 19:39:11 +03:00
5b84f62a89 Updated Turkish translation 2011-07-01 01:52:44 +03:00
3209e88c6f Bump version to 3.1.3
Update NEWS
2011-06-30 17:03:19 -04:00
0202a0837d Adding missing file to POTFILES.in 2011-06-30 17:03:17 -04:00
2b93c19328 Clip the shaped region to the bounding region
According to the XShape specification, the shaped region should always be
a subset of the bounding region. Certain programs such as wine depended
on this behavior.

https://bugzilla.gnome.org/show_bug.cgi?id=627880
2011-06-30 16:35:13 -04:00
66a830fd46 Fixes for compositor replacement
* When unmanaging a screen, stop redirecting subwindows explicitly,
  so that we do that before destroying the window manager selection
  window.
* Improve comment in the retry code
* When exiting because the previous compositor couldn't be replaced,
  don't g_error() and drop a core file.

https://bugzilla.gnome.org/show_bug.cgi?id=653121
2011-06-30 16:26:10 -04:00
d752096cdf Fix XShape
Commit c3a04bf unintentionally broke XShape handling. By studying the code
extremely carefully, I found this inconsistency with the code that was
there before.

https://bugzilla.gnome.org/show_bug.cgi?id=635268
2011-06-29 16:07:34 -04:00
fe12294b92 Create the 1x1 texture for the root background unsliced
When there was no root background pixmap, we were using a 1x1 repeating
texture as a simple way of drawing a solid color without adding a
second code path. However, when that 1x1 texture was combined into
a larger "atlas texture", hardware repeat couldn't be used, so a
small inefficiency from this approach became an enormous inefficiency
as clutter drew every pixel of the background as a separate rectangle.

https://bugzilla.gnome.org/show_bug.cgi?id=652507
2011-06-29 12:27:02 -04:00
61b5cfece4 Updated Belarusian translation. 2011-06-28 01:36:02 +03:00
ec5fb2a4ad Updated Turkish translation file header 2011-06-26 03:50:55 +03:00
cdabd517fa Updated Turkish translation 2011-06-26 00:27:38 +03:00
ebfe9a0355 Updated Belarusian translation. 2011-06-25 21:55:02 +03:00
c1a5261e2f Updated Serbian translation 2011-06-25 01:01:27 +02:00
c18940a5a2 compositor: Loop and retry to get compositor selection when replacing
There are unavoidable race conditions here when another process is
replacing us.  As a band aid, loop for 5 seconds.

https://bugzilla.gnome.org/show_bug.cgi?id=653121
2011-06-21 15:22:31 -04:00
b533ad2669 core: Remove META_CORE_IS_TITLEBAR_ONSCREEN
The functionality is no longer needed outside of core/, so remove
the getter.

https://bugzilla.gnome.org/show_bug.cgi?id=652369
2011-06-15 21:34:04 +02:00
526bc34bba frames: Always start grab operation on left click
When left-clicking the frame border with the titlebar being
off-screen, rather than starting the expected grab operation the
window menu was popped up.
This behavior is pretty confusing, especially since the menu button
was removed from the default layout, making right-clicking the only
way to get to the window menu.

https://bugzilla.gnome.org/show_bug.cgi?id=652369
2011-06-15 21:34:04 +02:00
35d300b916 Updated Slovenian translation 2011-06-10 20:15:46 +02:00
c70087db0c meta_quit: ignore repeated calls after it's already quitting
meta_run() calls meta_finalize() after the main loop exits, which ends
up calling meta_display_close(), which calls
meta_quit(META_EXIT_SUCCESS), meaning that any exit status passed to
the original meta_quit() call is lost.

Fix this by ignoring meta_quit() calls after the main loop is no
longer running.

https://bugzilla.gnome.org/show_bug.cgi?id=652010
2011-06-06 16:22:39 -04:00
9804841adb Updated Galician translations 2011-06-06 11:23:06 +02:00
aa92aa08bd Updated Galician translations 2011-06-06 11:13:00 +02:00
15e55b2ca1 Updated Hebrew translation. 2011-06-03 11:22:38 +03:00
4257b8deff window: Expose minimized state as property
Track the minimized state in a property, so that we can receive
change notifications.

https://bugzilla.gnome.org/show_bug.cgi?id=651568
2011-05-31 21:20:42 +02:00
e21e2c892a [l10n]Updated Catalan (Valencian) translation 2011-05-29 18:56:56 +02:00
05662b678e Fix crash in meta_display_get_above_tab_keycode
https://bugzilla.gnome.org/show_bug.cgi?id=647777
2011-05-25 14:20:06 -04:00
64f37a3769 window: Add wm-class property and notify it when changed.
https://bugzilla.gnome.org/show_bug.cgi?id=649315
2011-05-25 12:10:03 -04:00
7c9f492584 Updated Spanish translation 2011-05-21 09:32:57 +02:00
7577437167 ui-frames: Delay attaching the style to new frames
Like the setting of new frames' background is delayed until the
frame is associated with its window, delay attaching the initial
style, so that the correct style variant is picked.

https://bugzilla.gnome.org/show_bug.cgi?id=645355
2011-05-18 23:07:23 +02:00
be6775767c core: Update frame style when _GTK_THEME_VARIANT changes
When the _GTK_THEME_VARIANT property changes, rather than just
updating the window's theme_variant property, update its frame
style as well, so that the window decoration reflects the requested
variant. As the initial properties of a window may be read before
its frame is created, there will be cases where the change is not
picked up initially.

https://bugzilla.gnome.org/show_bug.cgi?id=645355
2011-05-18 23:07:23 +02:00
0d9a9b8d3b theme: Do not create temporary GtkStyle objects
In order to pick up colors from a GtkStyleContext, a temporary
GtkStyle object was created from the context and destroyed after
copying the requested GdkColor. This is slightly inefficient, so
get the appropriate GdkRGBA from the context and translate it to
a GdkColor, based on the compatibility code in gtkstyle.c.

https://bugzilla.gnome.org/show_bug.cgi?id=645355
2011-05-18 23:07:23 +02:00
4affd22817 ui-frame: Add support for style variants
Rather than sharing a single style context between all frames, use
a default style and one style per encountered variant (as determined
by the _GTK_THEME_VARIANT property), so that colors from the GTK+ style
are picked from the correct theme variant.

https://bugzilla.gnome.org/show_bug.cgi?id=645355
2011-05-18 23:07:23 +02:00
eb17cd9ba9 ui: Add meta_ui_update_frame_style()
This method allows forcing a style update of a particular frame
from the core, so that it can pick up style variants.

https://bugzilla.gnome.org/show_bug.cgi?id=645355
2011-05-18 23:07:23 +02:00
0cdac78bd5 core: Allow retrieving the theme variant via core_get()
To associate frames with the correct style variant, the UI will
need access to the window's theme variant property.

https://bugzilla.gnome.org/show_bug.cgi?id=645355
2011-05-18 23:07:23 +02:00
4f3b03e13b window: Parse _GTK_THEME_VARIANT property
Since version 3.0, GTK+ has support for style variants. At the moment,
themes may provide a dark variant, which can be requested by
applications via GtkSettings. The requested variant is exported to
X11 via the _GTK_THEME_VARIANT property - support this property, in
order to pick up the correct style variant in the future.

https://bugzilla.gnome.org/show_bug.cgi?id=645355
2011-05-18 23:07:23 +02:00
da4486b833 theme: Get GTK+ colors from style context
Rather than using a single widget's style for GTK+ colors in themes,
use the style context parameter of the drawing functions for those
colors. Right now, a single style context is shared between frames,
but this will change to support different style variants.

https://bugzilla.gnome.org/show_bug.cgi?id=645355
2011-05-18 23:07:22 +02:00
37aeb5baf1 frame: Delay updating the background until the frame is ready
To determine the correct background style, the UI needs to access
some frame properties via meta_core_get(); this call will bail out
early if window->frame is unset, so delay the call until the
association is made.

https://bugzilla.gnome.org/show_bug.cgi?id=645355
2011-05-18 23:07:22 +02:00
a2cb38b382 tile-preview: Use gdk_cairo_set_source_rgba()
gdk_cairo_set_source_rgba() is a convenience function which was
added to GTK+-3.0 after the port to GtkStyleContext, so we ended
up using cairo_set_source_rgba() instead. Save a couple of lines ...
2011-05-18 23:07:22 +02:00
c573523c4d Filter mirrored monitors from the monitors list
For the purposes of window placement or arranging window manager or
plugin controls, screens that are just mirrors of other screens should
be ignored, so filter them out of the monitors list.

https://bugzilla.gnome.org/show_bug.cgi?id=649299
2011-05-18 13:00:11 -04:00
64e6b77dc3 window: don't allow side-by-side tiling of non-maximizable windows
If a window is not maximizable, then that probably means it looks dumb
at very large sizes. Even if its hints would allow you to manually
resize it to a large size, don't allow automatically tiling it to half
the screen.

https://bugzilla.gnome.org/show_bug.cgi?id=647901
2011-05-16 10:16:12 -04:00
d0414a3ea6 theme.c: Squash memory leak
When converting a token to a different type, we need to free its
string.

https://bugzilla.gnome.org/show_bug.cgi?id=649500
2011-05-11 14:15:48 -04:00
6596374886 region-utils.c: Squash a memory leak
"chunk" was an allocated but unused variable.

https://bugzilla.gnome.org/show_bug.cgi?id=649504
2011-05-11 14:15:48 -04:00
7d70343c6d Updated Slovenian translation 2011-05-09 20:23:20 +02:00
cb87908dca Updated Hebrew translation. 2011-05-09 00:22:54 +03:00
95f33b36a7 Updated Spanish translation 2011-05-04 19:50:12 +02:00
d246d1c971 Uploaded Ukranian 2011-05-03 22:46:17 +03:00
89dbef9eb3 Fix crash with non-responding application with no title
If a window had no title property set, then the
application-not-responding dialog would cause Mutter to crash
because window->title was NULL; handle that case and use the
string "Application is not responding."

https://bugzilla.gnome.org/show_bug.cgi?id=649114
2011-05-03 11:01:05 -04:00
60dd31ed48 Fix escaping for application-not-responding dialog
We need to escape markup in the title, or a title "<i>Italic</i>"
will be displayed as italic.

https://bugzilla.gnome.org/show_bug.cgi?id=649114
2011-05-03 11:01:05 -04:00
40f51114b5 meta_show_dialog: fix encoding of command line arguments
Command line arguments are supposed to be in the locale encoding,
not UTF-8, and Zenity decodes command line string command line
arguments with this assumption using GOption.

There was a half-hearted attempt to deal with this in delete.c,
but it wasn't correct since it immediately mixed the window title,
converted to the locale encoding with a UTF-8 message.

https://bugzilla.gnome.org/show_bug.cgi?id=649114
2011-05-03 11:01:05 -04:00
d9007a08c9 Don't call textdomain()
As a library, libmutter should not be setting the default translation
domain to point to itself.

Also, move the bindtextdomain() call earlier
(meta_get_option_context), so that translations of command-line
options will be available.

We could call textdomain() in mutter.c, but there's no need to, since
mutter uses dgettext() everywhere anyway.

https://bugzilla.gnome.org/show_bug.cgi?id=649202
2011-05-02 14:37:47 -04:00
3d05405a78 Added UG translation 2011-05-02 18:48:30 +02:00
1ca697a130 Updated Japanese translation. 2011-05-01 13:04:13 +09:00
c248c57b6e Make session saving work a bit better
Previously, the restart command hardcoded "mutter" as the binary name.
This commit changes it to use g_get_prgname() which has a better chance
of being correct (and it does fix session saving for gnome-shell).

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

https://bugzilla.gnome.org/show_bug.cgi?id=648828
2011-04-29 07:23:30 -04:00
67c3c93b8f Only shadow ARGB windows with a frame outside the frame
An ARGB window with a frame is likely something like a transparent
terminal. It looks awful (and breaks transparency) to draw a big
opaque black shadow under the window, so clip out the region under
the terminal from the shadow we draw.

Add meta_window_get_frame_bounds() to get a cairo region for the
outer bounds of the frame of a window, and modify the frame handling
code to notice changes to the frame shape and discard a cached
region. meta_frames_apply_shapes() is refactored so we can extract
meta_frames_get_frame_bounds() from it.

https://bugzilla.gnome.org/show_bug.cgi?id=635268
2011-04-26 15:10:02 -04:00
c3a04bf394 Convert frame region handling to cairo regions
It's useful to get frame shapes and manipulate them within Mutter, for
example so that the compositor can use them to clip drawing.
For this, we'll need the regions as cairo regions not X regions, so
convert frame shaping code to work in terms of cairo_region_t.

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

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

https://bugzilla.gnome.org/show_bug.cgi?id=648613
2011-04-26 15:10:02 -04:00
97 changed files with 16127 additions and 11320 deletions

71
NEWS
View File

@ -1,3 +1,74 @@
3.1.3.1
=======
* Back API version down to "3.0" - the change to Meta-3.1.gir
was unintentional [Owen]
Translations:
Yaron Shahrabani [he], Kjartan Maraas [nb], Muhammet Kara [tr]
3.1.3
=====
* Support dark window theme variants for windows with a dark
widget theme; this is selected by the _GTK_THEME_VARIANT
property [Florian, #645355]
* Don't draw a shadow under windows with an alpha-channel - this
fixes transparency for GNOME Terminal [Owen, Jasper; #635268]
* Add a MetaWindow:wm-class property for notification [Jasper; #649315]
* Add a MetaWindow:minimized property for notification [Florian]
* Fix handing of unusual window shapes that Wine was setting
causing some applications to draw wrong [Jasper; #627880]
* Improve replacing another compositor and being replaced:
release compositor selection in the right order and wait for
compositors that get it wrong. [Colin, Owen; #653121]
* Remove behavior where left clicking on a window border with
the titlebar offscreen gave the window menu [Florian; #652369]
* Don't set the global default textdomain, since Mutter is
a library as well as an application [Dan; #649202]
* Exit with the right (success or failure) exit status [Dan]
* Code cleanup [Florian]
* Miscellaneous bug fixes [Owen; #649114, #652507]
Contributors:
Florian Müllner, Jasper St. Pierre, Owen Taylor, Colin Walters, Dan Winship
Translations:
Ihar Hrachyshka [be], Daniel Mustieles [es], Yaron Shahrabani [he],
Carles Ferrando [ca@valencia], Takeshi Aihana [ja], Fran Diéguez [gl],
Matej Urbančič [sl], Miroslav Nikolic [sr], Muhammet Kara [tr],
Daniel Korostil [uk]
3.0.2.1
=======
* When saving the session, use the "program name" rather than
harcoding mutter, fixing session saving for gnome-shell [Matthias]
https://bugzilla.gnome.org/show_bug.cgi?id=648828
Contributors:
Matthias Clasen
3.0.2
=====
* Fix a crash when running without XKB support [Adam]
https://bugzilla.gnome.org/show_bug.cgi?id=647777
* Fix smallish memory leaks [Colin]
https://bugzilla.gnome.org/show_bug.cgi?id=649500
https://bugzilla.gnome.org/show_bug.cgi?id=649504
* Ignore mirrored monitors when listing monitors, fixing
drag-and-drop problems in GNOME Shell [Owen]
https://bugzilla.gnome.org/show_bug.cgi?id=649299
* Don't allow side-by-side tiling of non-maximizable windows
like dialogs and utility windows [Dan]
* Fix interaction of _NET_WM_WINDOW_OPACITY with window effects,
making it work again with GNOME Shell
https://bugzilla.gnome.org/show_bug.cgi?id=648613
Contributors:
Adam Jackson, Colin Walters, Dan Winship
Translations:
Abduxukur Abdurixit [ug]
3.0.1
=====

View File

@ -1,8 +1,8 @@
AC_PREREQ(2.50)
m4_define([mutter_major_version], [3])
m4_define([mutter_minor_version], [0])
m4_define([mutter_micro_version], [1])
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])
@ -215,7 +215,12 @@ GOBJECT_INTROSPECTION_CHECK([$INTROSPECTION_VERSION])
if test x$found_introspection != xno; then
AC_DEFINE(HAVE_INTROSPECTION, 1, [Define if GObject introspection is available])
MUTTER_PC_MODULES="$MUTTER_PC_MODULES gobject-introspection-1.0"
META_GIR=[Meta_]mutter_major_version[_]mutter_minor_version[_gir]
# Since we don't make any guarantees about stability and we don't support
# parallel install, there's no real reason to change directories, filenames,
# etc. as we change the Mutter tarball version. Note that this must match
# api_version in src/Makefile.am
META_GIR=Meta_3_0_gir
# META_GIR=[Meta_]mutter_major_version[_]mutter_minor_version[_gir]
AC_SUBST(META_GIR)
fi
@ -233,6 +238,33 @@ if test x$have_xcursor = xyes; then
AC_DEFINE(HAVE_XCURSOR, , [Building with Xcursor support])
fi
XINPUT2_VERSION=1.4.0
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
@ -552,6 +584,7 @@ mutter-$VERSION
Shape extension: ${found_shape}
Xsync: ${found_xsync}
Xcursor: ${have_xcursor}
XInput2: ${have_xinput2}
"

View File

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

View File

@ -1,5 +1,6 @@
# List of source files containing translatable strings.
# Please keep this file sorted alphabetically.
src/compositor/compositor.c
src/core/all-keybindings.h
src/core/bell.c
src/core/core.c

3959
po/be.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

296
po/es.po
View File

@ -14,14 +14,25 @@ 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: 2011-03-21 19:31+0000\n"
"PO-Revision-Date: 2011-03-21 20:48+0100\n"
"POT-Creation-Date: 2011-07-08 20:41+0000\n"
"PO-Revision-Date: 2011-07-10 12:59+0200\n"
"Last-Translator: Jorge González <jorgegonz@svn.gnome.org>\n"
"Language-Team: Español <gnome-es-list@gnome.org>\n"
"Language-Team: Español; Castellano <gnome-es-list@gnome.org>\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"
"Content-Transfer-Encoding: 8bits\n"
"Plural-Forms: nplurals=2; plural=(n!=1);\n"
#. 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:509
#, c-format
msgid ""
"Another compositing manager is already running on screen %i on display \"%s"
"\"."
msgstr ""
"Ya existe un gestor de composición ejecutándose en la monitor %i, pantalla "
"«%s»."
#: ../src/core/all-keybindings.h:88
msgid "Switch to workspace 1"
@ -345,13 +356,16 @@ msgstr "Evento de campana"
msgid "Unknown window information request: %d"
msgstr "Petición de información de ventana desconocida: %d"
#. Translators: %s is a window title
#: ../src/core/delete.c:94
#: ../src/core/delete.c:111
#, c-format
msgid "<tt>%s</tt> is not responding."
msgstr "<tt>%s</tt> no está respondiendo."
#: ../src/core/delete.c:99
#: ../src/core/delete.c:114
msgid "Application is not responding."
msgstr "La aplicación no está respondiendo."
#: ../src/core/delete.c:119
msgid ""
"You may choose to wait a short while for it to continue or force the "
"application to quit entirely."
@ -359,11 +373,11 @@ msgstr ""
"Puede elegir esperar un rato para ver si continua o forzar la aplicación "
"para cerrarla completamente."
#: ../src/core/delete.c:108
#: ../src/core/delete.c:126
msgid "_Wait"
msgstr "_Esperar"
#: ../src/core/delete.c:108
#: ../src/core/delete.c:126
msgid "_Force Quit"
msgstr "_Forzar la salida"
@ -434,12 +448,12 @@ msgstr "Inicializar sesión desde el archivo de salvaguarda"
msgid "Make X calls synchronous"
msgstr "Hacer que las llamadas a las X sean síncronas"
#: ../src/core/main.c:506
#: ../src/core/main.c:504
#, c-format
msgid "Failed to scan themes directory: %s\n"
msgstr "Falló al inspeccionar el directorio de temas: %s\n"
#: ../src/core/main.c:522
#: ../src/core/main.c:520
#, c-format
msgid ""
"Could not find a theme! Be sure %s exists and contains the usual themes.\n"
@ -573,12 +587,12 @@ msgid "Error setting no tab popup status: %s\n"
msgstr ""
"Error al establecer el estado de las pestañas en ventanas emergentes: %s\n"
#: ../src/core/screen.c:623
#: ../src/core/screen.c:663
#, c-format
msgid "Screen %d on display '%s' is invalid\n"
msgstr "La ventana %d en la pantalla «%s» no es válida\n"
#: ../src/core/screen.c:639
#: ../src/core/screen.c:679
#, c-format
msgid ""
"Screen %d on display \"%s\" already has a window manager; try using the --"
@ -587,7 +601,7 @@ msgstr ""
"La ventana %d en la pantalla «%s» ya tiene un gestor de ventanas, intente "
"usar la opción «--replace» para reemplazar el gestor de ventanas activo.\n"
#: ../src/core/screen.c:666
#: ../src/core/screen.c:706
#, c-format
msgid ""
"Could not acquire window manager selection on screen %d display \"%s\"\n"
@ -595,65 +609,65 @@ msgstr ""
"No se ha podido obtener la selección del gestor de ventanas en la ventana %d "
"en la pantalla «%s»\n"
#: ../src/core/screen.c:721
#: ../src/core/screen.c:761
#, c-format
msgid "Screen %d on display \"%s\" already has a window manager\n"
msgstr "La ventana %d en la pantalla «%s» ya tiene un gestor de ventanas\n"
#: ../src/core/screen.c:906
#: ../src/core/screen.c:946
#, c-format
msgid "Could not release screen %d on display \"%s\"\n"
msgstr "No se ha podido liberar el monitor %d en la pantalla «%s»\n"
#: ../src/core/session.c:837 ../src/core/session.c:844
#: ../src/core/session.c:843 ../src/core/session.c:850
#, c-format
msgid "Could not create directory '%s': %s\n"
msgstr "No se ha podido crear el directorio «%s»: %s\n"
#: ../src/core/session.c:854
#: ../src/core/session.c:860
#, c-format
msgid "Could not open session file '%s' for writing: %s\n"
msgstr "No se ha podido abrir para escritura el archivo de sesión «%s»: %s\n"
#: ../src/core/session.c:995
#: ../src/core/session.c:1001
#, c-format
msgid "Error writing session file '%s': %s\n"
msgstr "Ocurrió un error al escribir en el archivo de sesión «%s»: %s\n"
#: ../src/core/session.c:1000
#: ../src/core/session.c:1006
#, c-format
msgid "Error closing session file '%s': %s\n"
msgstr "Ocurrió un error al cerrar el archivo de sesión «%s»: %s\n"
#: ../src/core/session.c:1130
#: ../src/core/session.c:1136
#, c-format
msgid "Failed to parse saved session file: %s\n"
msgstr "Ocurrió un error al interpretar el archivo de sesión guardado: %s\n"
#: ../src/core/session.c:1179
#: ../src/core/session.c:1185
#, c-format
msgid "<mutter_session> attribute seen but we already have the session ID"
msgstr ""
"Se ha visto el atributo <mutter_session> pero ya tenemos el ID de la sesión"
#: ../src/core/session.c:1192 ../src/core/session.c:1267
#: ../src/core/session.c:1299 ../src/core/session.c:1371
#: ../src/core/session.c:1431
#: ../src/core/session.c:1198 ../src/core/session.c:1273
#: ../src/core/session.c:1305 ../src/core/session.c:1377
#: ../src/core/session.c:1437
#, c-format
msgid "Unknown attribute %s on <%s> element"
msgstr "Atributo desconocido %s en el elemento <%s>"
#: ../src/core/session.c:1209
#: ../src/core/session.c:1215
#, c-format
msgid "nested <window> tag"
msgstr "etiqueta <window> anidada"
#: ../src/core/session.c:1451
#: ../src/core/session.c:1457
#, c-format
msgid "Unknown element %s"
msgstr "Elemento desconocido %s"
#: ../src/core/session.c:1803
#: ../src/core/session.c:1809
msgid ""
"These windows do not support &quot;save current setup&quot; and will have to "
"be restarted manually next time you log in."
@ -699,13 +713,13 @@ msgid "Window manager error: "
msgstr "Error del gestor de ventanas: "
#. Translators: This is the title used on dialog boxes
#: ../src/core/util.c:615 ../src/mutter.desktop.in.h:1
#: ../src/core/util.c:632 ../src/mutter.desktop.in.h:1
#: ../src/mutter-wm.desktop.in.h:1
msgid "Mutter"
msgstr "Mutter"
#. first time through
#: ../src/core/window.c:6752
#: ../src/core/window.c:6903
#, c-format
msgid ""
"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER "
@ -721,7 +735,7 @@ msgstr ""
#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain
#. * about these apps but make them work.
#.
#: ../src/core/window.c:7415
#: ../src/core/window.c:7566
#, c-format
msgid ""
"Window %s sets an MWM hint indicating it isn't resizable, but sets min size "
@ -741,12 +755,18 @@ msgstr "La aplicación establecio un _NET_WM_PID %lu erróneo\n"
msgid "%s (on %s)"
msgstr "%s (on %s)"
#: ../src/core/window-props.c:1479
#: ../src/core/window-props.c:1488
#, c-format
msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n"
msgstr ""
"WM_TRANSIENT_FOR inválido para la ventana 0x%lx especificada para %s.\n"
#: ../src/core/window-props.c:1500
#, c-format
#| msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n"
msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n"
msgstr "WM_TRANSIENT_FOR ventana 0x%lx para %s crearía un bucle.\n"
#: ../src/core/xprops.c:155
#, c-format
msgid ""
@ -788,9 +808,6 @@ msgstr ""
"otros escritorios distintos del actual) deberían mantenerse activas."
#: ../src/mutter.schemas.in.h:3
#| msgid ""
#| "Determines whether workspace switching should happen for windows on all "
#| "monitors or only the primary window."
msgid ""
"Determines whether workspace switching should happen for windows on all "
"monitors or only for windows on the primary monitor."
@ -839,47 +856,47 @@ msgstr "Áreas de trabajo sólo en el primario"
msgid "Usage: %s\n"
msgstr "Uso: %s\n"
#: ../src/ui/frames.c:1099
#: ../src/ui/frames.c:1280
msgid "Close Window"
msgstr "Cerrar la ventana"
#: ../src/ui/frames.c:1102
#: ../src/ui/frames.c:1283
msgid "Window Menu"
msgstr "Menú de la ventana"
#: ../src/ui/frames.c:1105
#: ../src/ui/frames.c:1286
msgid "Minimize Window"
msgstr "Minimizar la ventana"
#: ../src/ui/frames.c:1108
#: ../src/ui/frames.c:1289
msgid "Maximize Window"
msgstr "Maximizar la ventana"
#: ../src/ui/frames.c:1111
#: ../src/ui/frames.c:1292
msgid "Restore Window"
msgstr "Restablecer la ventana"
#: ../src/ui/frames.c:1114
#: ../src/ui/frames.c:1295
msgid "Roll Up Window"
msgstr "Enrollar ventana"
#: ../src/ui/frames.c:1117
#: ../src/ui/frames.c:1298
msgid "Unroll Window"
msgstr "Desenrollar ventana"
#: ../src/ui/frames.c:1120
#: ../src/ui/frames.c:1301
msgid "Keep Window On Top"
msgstr "Mantener la ventana encima"
#: ../src/ui/frames.c:1123
#: ../src/ui/frames.c:1304
msgid "Remove Window From Top"
msgstr "Quitar ventana de encima"
#: ../src/ui/frames.c:1126
#: ../src/ui/frames.c:1307
msgid "Always On Visible Workspace"
msgstr "Siempre en el área de trabajo visible"
#: ../src/ui/frames.c:1129
#: ../src/ui/frames.c:1310
msgid "Put Window On Only One Workspace"
msgstr "Poner la ventana sólo en un área de trabajo"
@ -1082,49 +1099,83 @@ msgstr "Mod5"
msgid "%d x %d"
msgstr "%d x %d"
#: ../src/ui/theme.c:255
#: ../src/ui/theme.c:252
msgid "top"
msgstr "superior"
#: ../src/ui/theme.c:257
#: ../src/ui/theme.c:254
msgid "bottom"
msgstr "inferior"
#: ../src/ui/theme.c:259
#: ../src/ui/theme.c:256
msgid "left"
msgstr "izquierda"
#: ../src/ui/theme.c:261
#: ../src/ui/theme.c:258
msgid "right"
msgstr "derecha"
#: ../src/ui/theme.c:288
#: ../src/ui/theme.c:285
#, c-format
msgid "frame geometry does not specify \"%s\" dimension"
msgstr "La geometría del marco no especifica la dimensión «%s»"
#: ../src/ui/theme.c:307
#: ../src/ui/theme.c:304
#, c-format
msgid "frame geometry does not specify dimension \"%s\" for border \"%s\""
msgstr ""
"La geometría del marco no especifica la dimensión «%s» para el borde «%s»"
#: ../src/ui/theme.c:344
#: ../src/ui/theme.c:341
#, c-format
msgid "Button aspect ratio %g is not reasonable"
msgstr "La proporción del botón %g no es razonable"
#: ../src/ui/theme.c:356
#: ../src/ui/theme.c:353
#, c-format
msgid "Frame geometry does not specify size of buttons"
msgstr "La geometría del marco no especifica el tamaño de los botones"
#: ../src/ui/theme.c:1064
#: ../src/ui/theme.c:1061
#, c-format
msgid "Gradients should have at least two colors"
msgstr "Los degradados deben tener al menos dos colores"
#: ../src/ui/theme.c:1202
#: ../src/ui/theme.c:1206
#, c-format
#| msgid ""
#| "GTK color specification must have a close bracket after the state, e.g. "
#| "gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\""
msgid ""
"GTK custom color specification must have color name and fallback in "
"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\""
msgstr ""
"La especificación de color GTK debe tener un nombre de color y nombre "
"alternativo entre paréntesis, ejemplo: gtk:custom(foo,bar); no se pudo "
"analizar «%s»"
#: ../src/ui/theme.c:1222
#, c-format
msgid ""
"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-"
"_ are valid"
msgstr ""
"Caracter «%c» no válido en el parámetro «color_name» de «gtk:custom», sólo "
"«A-Za-z0-9-_» son válidos"
#: ../src/ui/theme.c:1236
#, c-format
#| msgid ""
#| "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the "
#| "format"
msgid ""
"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not "
"fit the format"
msgstr ""
"El formato de «gtk:custom» es «gtk:custom(nombre_de_color,"
"nombre_alternativo)», «%s» no respeta el formato"
#: ../src/ui/theme.c:1272
#, c-format
msgid ""
"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] "
@ -1134,7 +1185,7 @@ msgstr ""
"ejemplo. gtk:fg[NORMAL] donde NORMAL es el estado ; no se ha podido "
"interpretar «%s»"
#: ../src/ui/theme.c:1216
#: ../src/ui/theme.c:1286
#, c-format
msgid ""
"GTK color specification must have a close bracket after the state, e.g. gtk:"
@ -1144,18 +1195,18 @@ msgstr ""
"estado, ejemplo. gtk:fg[NORMAL] donde NORMAL es el estado ; no se ha podido "
"interpretar «%s»"
#: ../src/ui/theme.c:1227
#: ../src/ui/theme.c:1297
#, c-format
msgid "Did not understand state \"%s\" in color specification"
msgstr "No se entiende el estado «%s» en la especificación del color"
#: ../src/ui/theme.c:1240
#: ../src/ui/theme.c:1310
#, c-format
msgid "Did not understand color component \"%s\" in color specification"
msgstr ""
"No se entiende el componente de color «%s» en la especificación del color"
#: ../src/ui/theme.c:1270
#: ../src/ui/theme.c:1340
#, c-format
msgid ""
"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the "
@ -1164,17 +1215,17 @@ msgstr ""
"El formato de blend es «blend/bg_color/fg_color/alfa», «%s» no cumple con el "
"formato"
#: ../src/ui/theme.c:1281
#: ../src/ui/theme.c:1351
#, c-format
msgid "Could not parse alpha value \"%s\" in blended color"
msgstr "No se ha podido interpretar el valor alfa «%s» en el color mezclado"
#: ../src/ui/theme.c:1291
#: ../src/ui/theme.c:1361
#, c-format
msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0"
msgstr "El valor alfa «%s» en el color mezclado no está entre 0.0 y 1.0"
#: ../src/ui/theme.c:1338
#: ../src/ui/theme.c:1408
#, c-format
msgid ""
"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format"
@ -1182,31 +1233,31 @@ msgstr ""
"El formato de sombreado es «shade/base_color/factor», «%s» no coincide con "
"el formato"
#: ../src/ui/theme.c:1349
#: ../src/ui/theme.c:1419
#, c-format
msgid "Could not parse shade factor \"%s\" in shaded color"
msgstr ""
"No se ha podido interpretar el factor de sombreado «%s» en el color del "
"sombreado"
#: ../src/ui/theme.c:1359
#: ../src/ui/theme.c:1429
#, c-format
msgid "Shade factor \"%s\" in shaded color is negative"
msgstr "El factor de sombreado «%s» en el color sombreado es negativo"
#: ../src/ui/theme.c:1388
#: ../src/ui/theme.c:1458
#, c-format
msgid "Could not parse color \"%s\""
msgstr "No se ha podido interpretar el color «%s»"
#: ../src/ui/theme.c:1646
#: ../src/ui/theme.c:1769
#, c-format
msgid "Coordinate expression contains character '%s' which is not allowed"
msgstr ""
"La expresión de coordenadas contenía un carácter «%s» en cual no está "
"permitido"
#: ../src/ui/theme.c:1673
#: ../src/ui/theme.c:1796
#, c-format
msgid ""
"Coordinate expression contains floating point number '%s' which could not be "
@ -1215,13 +1266,13 @@ msgstr ""
"La expresión de coordenadas contenía un número de coma flotante «%s» en cual "
"no pudo ser analizado"
#: ../src/ui/theme.c:1687
#: ../src/ui/theme.c:1810
#, c-format
msgid "Coordinate expression contains integer '%s' which could not be parsed"
msgstr ""
"La expresión de coordenadas contenía un entero «%s» que no pudo ser analizado"
#: ../src/ui/theme.c:1809
#: ../src/ui/theme.c:1932
#, c-format
msgid ""
"Coordinate expression contained unknown operator at the start of this text: "
@ -1230,17 +1281,17 @@ msgstr ""
"La expresión de coordenadas contenía un operador inválido al inicio de su "
"texto: «%s»"
#: ../src/ui/theme.c:1866
#: ../src/ui/theme.c:1989
#, c-format
msgid "Coordinate expression was empty or not understood"
msgstr "La expresión de coordenadas estaba vacía o no fue entendida"
#: ../src/ui/theme.c:1977 ../src/ui/theme.c:1987 ../src/ui/theme.c:2021
#: ../src/ui/theme.c:2100 ../src/ui/theme.c:2110 ../src/ui/theme.c:2144
#, c-format
msgid "Coordinate expression results in division by zero"
msgstr "La expresión de coordenadas resultó en un error de división por cero"
#: ../src/ui/theme.c:2029
#: ../src/ui/theme.c:2152
#, c-format
msgid ""
"Coordinate expression tries to use mod operator on a floating-point number"
@ -1248,7 +1299,7 @@ msgstr ""
"La expresión de coordenadas intentó usar un operador mod con un número de "
"coma flotante"
#: ../src/ui/theme.c:2085
#: ../src/ui/theme.c:2208
#, c-format
msgid ""
"Coordinate expression has an operator \"%s\" where an operand was expected"
@ -1256,19 +1307,19 @@ msgstr ""
"La expresión de coordenadas tiene un operador «%s» donde se esperaba un "
"operando"
#: ../src/ui/theme.c:2094
#: ../src/ui/theme.c:2217
#, c-format
msgid "Coordinate expression had an operand where an operator was expected"
msgstr ""
"La expresión de coordenadas tiene un operando donde se esperaba un operador"
#: ../src/ui/theme.c:2102
#: ../src/ui/theme.c:2225
#, c-format
msgid "Coordinate expression ended with an operator instead of an operand"
msgstr ""
"La expresión de coordenadas termina con una operador en vez de un operando"
#: ../src/ui/theme.c:2112
#: ../src/ui/theme.c:2235
#, c-format
msgid ""
"Coordinate expression has operator \"%c\" following operator \"%c\" with no "
@ -1277,42 +1328,42 @@ msgstr ""
"La expresión de coordenadas tiene el operador «%c» seguido del operador «%c» "
"sin un operando entre ellos"
#: ../src/ui/theme.c:2263 ../src/ui/theme.c:2308
#: ../src/ui/theme.c:2386 ../src/ui/theme.c:2431
#, c-format
msgid "Coordinate expression had unknown variable or constant \"%s\""
msgstr ""
"La expresión de coordenadas tenía una variable o constante desconocida «%s»"
#: ../src/ui/theme.c:2362
#: ../src/ui/theme.c:2485
#, c-format
msgid "Coordinate expression parser overflowed its buffer."
msgstr "El parser de la expresión de coordenadas desbordó su búfer."
#: ../src/ui/theme.c:2391
#: ../src/ui/theme.c:2514
#, c-format
msgid "Coordinate expression had a close parenthesis with no open parenthesis"
msgstr ""
"La expresión de coordenadas tenía un paréntesis cerrado sin un paréntesis "
"abierto"
#: ../src/ui/theme.c:2455
#: ../src/ui/theme.c:2578
#, c-format
msgid "Coordinate expression had an open parenthesis with no close parenthesis"
msgstr ""
"La expresión de coordenadas tenía un paréntesis abierto sin un paréntesis "
"cerrado"
#: ../src/ui/theme.c:2466
#: ../src/ui/theme.c:2589
#, c-format
msgid "Coordinate expression doesn't seem to have any operators or operands"
msgstr "La expresión de coordenadas no parece tener ni operadores ni operandos"
#: ../src/ui/theme.c:2676 ../src/ui/theme.c:2696 ../src/ui/theme.c:2716
#: ../src/ui/theme.c:2801 ../src/ui/theme.c:2821 ../src/ui/theme.c:2841
#, c-format
msgid "Theme contained an expression that resulted in an error: %s\n"
msgstr "El tema contenía una expresión que ha resultado en un error: %s\n"
#: ../src/ui/theme.c:4410
#: ../src/ui/theme.c:4512
#, c-format
msgid ""
"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be "
@ -1321,25 +1372,25 @@ msgstr ""
"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> debe ser "
"especificado para este estilo de marco"
#: ../src/ui/theme.c:4940 ../src/ui/theme.c:4965
#: ../src/ui/theme.c:5042 ../src/ui/theme.c:5067
#, c-format
msgid ""
"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>"
msgstr ""
"Falta <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>"
#: ../src/ui/theme.c:5013
#: ../src/ui/theme.c:5115
#, c-format
msgid "Failed to load theme \"%s\": %s\n"
msgstr "Ocurrió un error al cargar el tema «%s»: %s\n"
#: ../src/ui/theme.c:5149 ../src/ui/theme.c:5156 ../src/ui/theme.c:5163
#: ../src/ui/theme.c:5170 ../src/ui/theme.c:5177
#: ../src/ui/theme.c:5251 ../src/ui/theme.c:5258 ../src/ui/theme.c:5265
#: ../src/ui/theme.c:5272 ../src/ui/theme.c:5279
#, c-format
msgid "No <%s> set for theme \"%s\""
msgstr "No se configuró <%s> para el tema «%s»"
#: ../src/ui/theme.c:5185
#: ../src/ui/theme.c:5287
#, c-format
msgid ""
"No frame style set for window type \"%s\" in theme \"%s\", add a <window "
@ -1348,7 +1399,7 @@ msgstr ""
"No hay un estilo de marco para el tipo de ventana «%s» en el tema «%s», "
"añada un elemento <window type=\"%s\" style_set=\"whatever\"/>"
#: ../src/ui/theme.c:5635 ../src/ui/theme.c:5697 ../src/ui/theme.c:5760
#: ../src/ui/theme.c:5737 ../src/ui/theme.c:5799 ../src/ui/theme.c:5862
#, c-format
msgid ""
"User-defined constants must begin with a capital letter; \"%s\" does not"
@ -1356,7 +1407,7 @@ msgstr ""
"Las constantes definidas por el usuario deben comenzar con una letra "
"mayúscula; «%s» no lo hace"
#: ../src/ui/theme.c:5643 ../src/ui/theme.c:5705 ../src/ui/theme.c:5768
#: ../src/ui/theme.c:5745 ../src/ui/theme.c:5807 ../src/ui/theme.c:5870
#, c-format
msgid "Constant \"%s\" has already been defined"
msgstr "La constante «%s» ya ha sido definida"
@ -1817,92 +1868,92 @@ msgstr "Esto es un mensaje de ejemplo en un diálogo de ejemplo"
msgid "Fake menu item %d\n"
msgstr "Elemento de menú de pega %d\n"
#: ../src/ui/theme-viewer.c:370
#: ../src/ui/theme-viewer.c:371
msgid "Border-only window"
msgstr "Ventana con sólo borde"
#: ../src/ui/theme-viewer.c:372
#: ../src/ui/theme-viewer.c:373
msgid "Bar"
msgstr "Barra"
#: ../src/ui/theme-viewer.c:389
#: ../src/ui/theme-viewer.c:390
msgid "Normal Application Window"
msgstr "Ventana de aplicación normal"
#: ../src/ui/theme-viewer.c:393
#: ../src/ui/theme-viewer.c:394
msgid "Dialog Box"
msgstr "Caja de diálogo"
#: ../src/ui/theme-viewer.c:397
#: ../src/ui/theme-viewer.c:398
msgid "Modal Dialog Box"
msgstr "Caja de diálogo modal"
#: ../src/ui/theme-viewer.c:401
#: ../src/ui/theme-viewer.c:402
msgid "Utility Palette"
msgstr "Paleta de utilidades"
#: ../src/ui/theme-viewer.c:405
#: ../src/ui/theme-viewer.c:406
msgid "Torn-off Menu"
msgstr "Menú apagado"
#: ../src/ui/theme-viewer.c:409
#: ../src/ui/theme-viewer.c:410
msgid "Border"
msgstr "Borde"
#: ../src/ui/theme-viewer.c:413
#: ../src/ui/theme-viewer.c:414
msgid "Attached Modal Dialog"
msgstr "Diálogo modal adjunto"
#: ../src/ui/theme-viewer.c:744
#: ../src/ui/theme-viewer.c:747
#, c-format
msgid "Button layout test %d"
msgstr "Test de distribución de botones %d"
#: ../src/ui/theme-viewer.c:773
#: ../src/ui/theme-viewer.c:776
#, c-format
msgid "%g milliseconds to draw one window frame"
msgstr "%g milisegundos para dibujar un marco de ventana"
#: ../src/ui/theme-viewer.c:818
#: ../src/ui/theme-viewer.c:821
#, c-format
msgid "Usage: metacity-theme-viewer [THEMENAME]\n"
msgstr "Uso: metacity-theme-viewer [NOMBRETEMA]\n"
#: ../src/ui/theme-viewer.c:825
#: ../src/ui/theme-viewer.c:828
#, c-format
msgid "Error loading theme: %s\n"
msgstr "Ocurrió un error al cargar el tema:«%s»\n"
#: ../src/ui/theme-viewer.c:831
#: ../src/ui/theme-viewer.c:834
#, c-format
msgid "Loaded theme \"%s\" in %g seconds\n"
msgstr "Se cargó el tema «%s» en %g segundos\n"
#: ../src/ui/theme-viewer.c:875
#: ../src/ui/theme-viewer.c:878
msgid "Normal Title Font"
msgstr "Tipografía de título normal"
#: ../src/ui/theme-viewer.c:881
#: ../src/ui/theme-viewer.c:884
msgid "Small Title Font"
msgstr "Tipografía de título pequeña"
#: ../src/ui/theme-viewer.c:887
#: ../src/ui/theme-viewer.c:890
msgid "Large Title Font"
msgstr "Tipografía de título grande"
#: ../src/ui/theme-viewer.c:892
#: ../src/ui/theme-viewer.c:895
msgid "Button Layouts"
msgstr "Distribución de botones"
#: ../src/ui/theme-viewer.c:897
#: ../src/ui/theme-viewer.c:900
msgid "Benchmark"
msgstr "Banco de pruebas"
#: ../src/ui/theme-viewer.c:949
#: ../src/ui/theme-viewer.c:952
msgid "Window Title Goes Here"
msgstr "El título de la ventana va aquí"
#: ../src/ui/theme-viewer.c:1055
#: ../src/ui/theme-viewer.c:1058
#, c-format
msgid ""
"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g "
@ -1913,47 +1964,50 @@ msgstr ""
"marco) y %g segundos de tiempo estándar incluyendo recursos del servidor X "
"(%g milisegundos por marco)\n"
#: ../src/ui/theme-viewer.c:1274
#: ../src/ui/theme-viewer.c:1277
msgid "position expression test returned TRUE but set error"
msgstr ""
"prueba de expresión de la posición devolvió TRUE pero estableció un error"
#: ../src/ui/theme-viewer.c:1276
#: ../src/ui/theme-viewer.c:1279
msgid "position expression test returned FALSE but didn't set error"
msgstr ""
"prueba de expresión de la posición devolvió FASE pero no estableció un error"
#: ../src/ui/theme-viewer.c:1280
#: ../src/ui/theme-viewer.c:1283
msgid "Error was expected but none given"
msgstr "Se esperaba un error, pero no se dio ninguno"
#: ../src/ui/theme-viewer.c:1282
#: ../src/ui/theme-viewer.c:1285
#, c-format
msgid "Error %d was expected but %d given"
msgstr "Se esperaba el error %d pero se dio el %d"
#: ../src/ui/theme-viewer.c:1288
#: ../src/ui/theme-viewer.c:1291
#, c-format
msgid "Error not expected but one was returned: %s"
msgstr "No se esperaba un error pero se devolvió uno: %s"
#: ../src/ui/theme-viewer.c:1292
#: ../src/ui/theme-viewer.c:1295
#, c-format
msgid "x value was %d, %d was expected"
msgstr "el valor x era %d, se esperaba %d"
#: ../src/ui/theme-viewer.c:1295
#: ../src/ui/theme-viewer.c:1298
#, c-format
msgid "y value was %d, %d was expected"
msgstr "el valor y era %d, se esperaba %d"
#: ../src/ui/theme-viewer.c:1360
#: ../src/ui/theme-viewer.c:1363
#, c-format
msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n"
msgstr ""
"%d expresiones de coordenadas interpretadas en %g segundos (%g segundos de "
"media)\n"
#~ msgid "Failed to retrieve color %s[%s] from GTK+ theme.\n"
#~ msgstr "Falló al obtener el color %s[%s] del tema de GTK+.\n"
#~ msgid ""
#~ "Don't make fullscreen windows that are maximized and have no decorations"
#~ msgstr ""

154
po/gl.po
View File

@ -9,13 +9,14 @@
# Mancomún - Centro de Referencia e Servizos de Software Libre <g11n@mancomun.org>, 2009.
# Fran Dieguez <fran.dieguez@glug.es>, 2009.
# Fran Diéguez <frandieguez@gnome.org>, 2010, 2011.
#
msgid ""
msgstr ""
"Project-Id-Version: gl\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-03-22 00:53+0100\n"
"PO-Revision-Date: 2011-03-22 00:54+0100\n"
"Last-Translator: \n"
"POT-Creation-Date: 2011-07-04 22:23+0200\n"
"PO-Revision-Date: 2011-07-04 22:23+0200\n"
"Last-Translator: Fran Diéguez <frandieguez@gnome.org>\n"
"Language-Team: Galician <gnome-l10n-gl@gnome.org>\n"
"Language: gl\n"
"MIME-Version: 1.0\n"
@ -24,6 +25,17 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Lokalize 1.2\n"
#. 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:509
#, c-format
msgid ""
"Another compositing manager is already running on screen %i on display \"%s"
"\"."
msgstr ""
"Non foi posíbel obter a selección do xestor de xanelas na pantalla %i na "
"visualización «%s»"
#: ../src/core/all-keybindings.h:88
msgid "Switch to workspace 1"
msgstr "Cambiar ao espazo de traballo 1"
@ -348,13 +360,16 @@ msgstr "Evento de campá"
msgid "Unknown window information request: %d"
msgstr "Petición de información de xanela descoñecida: %d"
#. Translators: %s is a window title
#: ../src/core/delete.c:94
#: ../src/core/delete.c:111
#, c-format
msgid "<tt>%s</tt> is not responding."
msgstr "<tt>%s</tt> non está respondendo."
#: ../src/core/delete.c:99
#: ../src/core/delete.c:114
msgid "Application is not responding."
msgstr "O Aplicativo non está respondendo."
#: ../src/core/delete.c:119
msgid ""
"You may choose to wait a short while for it to continue or force the "
"application to quit entirely."
@ -362,11 +377,11 @@ msgstr ""
"Pode elixir esperar un momento para ver se continúa ou forzar ao aplicativo "
"a pechar completamente."
#: ../src/core/delete.c:108
#: ../src/core/delete.c:126
msgid "_Wait"
msgstr "Espe_rar"
#: ../src/core/delete.c:108
#: ../src/core/delete.c:126
msgid "_Force Quit"
msgstr "_Forzar a saída"
@ -437,12 +452,12 @@ msgstr "Iniciar sesión desde o ficheiro de salvagarda"
msgid "Make X calls synchronous"
msgstr "Facer que as chamadas a X sexan sincrónicas"
#: ../src/core/main.c:506
#: ../src/core/main.c:504
#, c-format
msgid "Failed to scan themes directory: %s\n"
msgstr "Fallou ao dixitalizar o directorio de temas: %s\n"
#: ../src/core/main.c:522
#: ../src/core/main.c:520
#, c-format
msgid ""
"Could not find a theme! Be sure %s exists and contains the usual themes.\n"
@ -574,12 +589,12 @@ msgstr ""
"Produciuse un erro ao estabelecer o estado das lapelas en xanelas emerxentes "
"%s\n"
#: ../src/core/screen.c:623
#: ../src/core/screen.c:663
#, c-format
msgid "Screen %d on display '%s' is invalid\n"
msgstr "A pantalla %d na visualización «%s» non é válida\n"
#: ../src/core/screen.c:639
#: ../src/core/screen.c:679
#, c-format
msgid ""
"Screen %d on display \"%s\" already has a window manager; try using the --"
@ -588,7 +603,7 @@ msgstr ""
"A visualización %d na pantalla «%s» ten xa un xestor de xanelas, tente usar "
"a opción --replace para substituír o xestor de xanelas.\n"
#: ../src/core/screen.c:666
#: ../src/core/screen.c:706
#, c-format
msgid ""
"Could not acquire window manager selection on screen %d display \"%s\"\n"
@ -596,64 +611,64 @@ msgstr ""
"Non foi posíbel obter a selección do xestor de xanelas na pantalla %d na "
"visualización «%s»\n"
#: ../src/core/screen.c:721
#: ../src/core/screen.c:761
#, c-format
msgid "Screen %d on display \"%s\" already has a window manager\n"
msgstr "A visualización %d na pantalla «%s» ten xa un xestor de xanelas\n"
#: ../src/core/screen.c:906
#: ../src/core/screen.c:946
#, c-format
msgid "Could not release screen %d on display \"%s\"\n"
msgstr "Non foi posíbel liberar a visualización %d na pantalla «%s»\n"
#: ../src/core/session.c:837 ../src/core/session.c:844
#: ../src/core/session.c:843 ../src/core/session.c:850
#, c-format
msgid "Could not create directory '%s': %s\n"
msgstr "Non foi posíbel crear o directorio «%s»: %s\n"
#: ../src/core/session.c:854
#: ../src/core/session.c:860
#, c-format
msgid "Could not open session file '%s' for writing: %s\n"
msgstr "Non foi posíbel abrir o ficheiro de sesión «%s» para escritura: %s\n"
#: ../src/core/session.c:995
#: ../src/core/session.c:1001
#, c-format
msgid "Error writing session file '%s': %s\n"
msgstr "Erro ao escribir o ficheiro de sesión «%s»: %s\n"
#: ../src/core/session.c:1000
#: ../src/core/session.c:1006
#, c-format
msgid "Error closing session file '%s': %s\n"
msgstr "Erro ao pechar o ficheiro de sesión «%s»: %s\n"
#: ../src/core/session.c:1130
#: ../src/core/session.c:1136
#, c-format
msgid "Failed to parse saved session file: %s\n"
msgstr "Produciuse un fallo ao analizar o ficheiro de sesión gardado: %s\n"
#: ../src/core/session.c:1179
#: ../src/core/session.c:1185
#, c-format
msgid "<mutter_session> attribute seen but we already have the session ID"
msgstr "O atributo <mutter_session> foi visto pero xa temos o ID de sesión"
#: ../src/core/session.c:1192 ../src/core/session.c:1267
#: ../src/core/session.c:1299 ../src/core/session.c:1371
#: ../src/core/session.c:1431
#: ../src/core/session.c:1198 ../src/core/session.c:1273
#: ../src/core/session.c:1305 ../src/core/session.c:1377
#: ../src/core/session.c:1437
#, c-format
msgid "Unknown attribute %s on <%s> element"
msgstr "Atributo descoñecido %s no elemento <%s>"
#: ../src/core/session.c:1209
#: ../src/core/session.c:1215
#, c-format
msgid "nested <window> tag"
msgstr "etiqueta <window> aniñada"
#: ../src/core/session.c:1451
#: ../src/core/session.c:1457
#, c-format
msgid "Unknown element %s"
msgstr "Elemento descoñecido %s"
#: ../src/core/session.c:1803
#: ../src/core/session.c:1809
msgid ""
"These windows do not support &quot;save current setup&quot; and will have to "
"be restarted manually next time you log in."
@ -698,13 +713,13 @@ msgid "Window manager error: "
msgstr "Erro do xestor de xanelas: "
#. Translators: This is the title used on dialog boxes
#: ../src/core/util.c:615 ../src/mutter.desktop.in.h:1
#: ../src/core/util.c:632 ../src/mutter.desktop.in.h:1
#: ../src/mutter-wm.desktop.in.h:1
msgid "Mutter"
msgstr "Mutter"
#. first time through
#: ../src/core/window.c:6752
#: ../src/core/window.c:6886
#, c-format
msgid ""
"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER "
@ -720,7 +735,7 @@ msgstr ""
#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain
#. * about these apps but make them work.
#.
#: ../src/core/window.c:7415
#: ../src/core/window.c:7549
#, c-format
msgid ""
"Window %s sets an MWM hint indicating it isn't resizable, but sets min size "
@ -740,7 +755,7 @@ msgstr "O aplicativo configurou un _NET_WM_PID %lu falso\n"
msgid "%s (on %s)"
msgstr "%s (en %s)"
#: ../src/core/window-props.c:1479
#: ../src/core/window-props.c:1484
#, c-format
msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n"
msgstr ""
@ -834,47 +849,47 @@ msgstr "Espazos de traballo só no principal"
msgid "Usage: %s\n"
msgstr "Uso: %s\n"
#: ../src/ui/frames.c:1099
#: ../src/ui/frames.c:1280
msgid "Close Window"
msgstr "Pechar a xanela"
#: ../src/ui/frames.c:1102
#: ../src/ui/frames.c:1283
msgid "Window Menu"
msgstr "Menú da xanela"
#: ../src/ui/frames.c:1105
#: ../src/ui/frames.c:1286
msgid "Minimize Window"
msgstr "Minimizar a xanela"
#: ../src/ui/frames.c:1108
#: ../src/ui/frames.c:1289
msgid "Maximize Window"
msgstr "Maximizar a xanela"
#: ../src/ui/frames.c:1111
#: ../src/ui/frames.c:1292
msgid "Restore Window"
msgstr "Restaurar a xanela"
#: ../src/ui/frames.c:1114
#: ../src/ui/frames.c:1295
msgid "Roll Up Window"
msgstr "Pregar a xanela"
#: ../src/ui/frames.c:1117
#: ../src/ui/frames.c:1298
msgid "Unroll Window"
msgstr "Despregar a xanela"
#: ../src/ui/frames.c:1120
#: ../src/ui/frames.c:1301
msgid "Keep Window On Top"
msgstr "Manter a xanela na parte superior"
#: ../src/ui/frames.c:1123
#: ../src/ui/frames.c:1304
msgid "Remove Window From Top"
msgstr "Quitar a xanela da parte superior"
#: ../src/ui/frames.c:1126
#: ../src/ui/frames.c:1307
msgid "Always On Visible Workspace"
msgstr "Sempre no espazo de traballo visíbel"
#: ../src/ui/frames.c:1129
#: ../src/ui/frames.c:1310
msgid "Put Window On Only One Workspace"
msgstr "Pór a xanela nun só espazo de traballo"
@ -1189,13 +1204,18 @@ msgstr "O factor de sombreado «%s» na cor sombreada é negativo"
msgid "Could not parse color \"%s\""
msgstr "Non foi posíbel analizar a cor «%s»"
#: ../src/ui/theme.c:1646
#: ../src/ui/theme.c:1481
#, c-format
msgid "Failed to retrieve color %s[%s] from GTK+ theme.\n"
msgstr "Produciuse un fallo ao obter a cor %s[%s] desde o tema de GTK+.\n"
#: ../src/ui/theme.c:1713
#, c-format
msgid "Coordinate expression contains character '%s' which is not allowed"
msgstr ""
"A expresión de coordenadas contén un carácter «%s» que non está permitido"
#: ../src/ui/theme.c:1673
#: ../src/ui/theme.c:1740
#, c-format
msgid ""
"Coordinate expression contains floating point number '%s' which could not be "
@ -1204,14 +1224,14 @@ msgstr ""
"A expresión de coordenadas contén un número de coma flotante «%s» que non "
"foi posíbel analizar"
#: ../src/ui/theme.c:1687
#: ../src/ui/theme.c:1754
#, c-format
msgid "Coordinate expression contains integer '%s' which could not be parsed"
msgstr ""
"A expresión de coordenadas contén un enteiro «%s» que non foi posíbel "
"analizar"
#: ../src/ui/theme.c:1809
#: ../src/ui/theme.c:1876
#, c-format
msgid ""
"Coordinate expression contained unknown operator at the start of this text: "
@ -1220,17 +1240,17 @@ msgstr ""
"A expresión de coordenadas contén un operador non válido ao inicio do seu "
"texto: «%s»"
#: ../src/ui/theme.c:1866
#: ../src/ui/theme.c:1933
#, c-format
msgid "Coordinate expression was empty or not understood"
msgstr "A expresión de coordenadas está baleira ou non se entendeu"
#: ../src/ui/theme.c:1977 ../src/ui/theme.c:1987 ../src/ui/theme.c:2021
#: ../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 "A expresión de coordenadas resultou nun erro de división por cero"
#: ../src/ui/theme.c:2029
#: ../src/ui/theme.c:2096
#, c-format
msgid ""
"Coordinate expression tries to use mod operator on a floating-point number"
@ -1238,25 +1258,25 @@ msgstr ""
"A expresión de coordenadas tentou usar un operador mod cun número de coma "
"flotante"
#: ../src/ui/theme.c:2085
#: ../src/ui/theme.c:2152
#, c-format
msgid ""
"Coordinate expression has an operator \"%s\" where an operand was expected"
msgstr ""
"A expresión de coordenadas ten un operador «%s» onde se esperaba un operando"
#: ../src/ui/theme.c:2094
#: ../src/ui/theme.c:2161
#, c-format
msgid "Coordinate expression had an operand where an operator was expected"
msgstr ""
"A expresión de coordenadas ten un operando onde se esperaba un operador"
#: ../src/ui/theme.c:2102
#: ../src/ui/theme.c:2169
#, c-format
msgid "Coordinate expression ended with an operator instead of an operand"
msgstr "A expresión de coordenadas remata cun operador en vez dun operando"
#: ../src/ui/theme.c:2112
#: ../src/ui/theme.c:2179
#, c-format
msgid ""
"Coordinate expression has operator \"%c\" following operator \"%c\" with no "
@ -1265,42 +1285,42 @@ msgstr ""
"A expresión de coordenadas ten un operador \"%c\" seguido do operador \"%c\" "
"sen un operando entre eles"
#: ../src/ui/theme.c:2263 ../src/ui/theme.c:2308
#: ../src/ui/theme.c:2330 ../src/ui/theme.c:2375
#, c-format
msgid "Coordinate expression had unknown variable or constant \"%s\""
msgstr ""
"A expresión de coordenadas ten unha variábel ou constante descoñecida «%s»"
#: ../src/ui/theme.c:2362
#: ../src/ui/theme.c:2429
#, c-format
msgid "Coordinate expression parser overflowed its buffer."
msgstr "O analizador da expresión de coordenadas desbordou o seu búfer."
#: ../src/ui/theme.c:2391
#: ../src/ui/theme.c:2458
#, c-format
msgid "Coordinate expression had a close parenthesis with no open parenthesis"
msgstr ""
"A expresión de coordenadas ten unha paréntese pechada sen unha paréntese "
"aberta"
#: ../src/ui/theme.c:2455
#: ../src/ui/theme.c:2522
#, c-format
msgid "Coordinate expression had an open parenthesis with no close parenthesis"
msgstr ""
"A expresión de coordenadas ten unha paréntese aberta sen unha paréntese "
"pechada"
#: ../src/ui/theme.c:2466
#: ../src/ui/theme.c:2533
#, c-format
msgid "Coordinate expression doesn't seem to have any operators or operands"
msgstr "A expresión de coordenadas non parece ter nin operadores nin operandos"
#: ../src/ui/theme.c:2676 ../src/ui/theme.c:2696 ../src/ui/theme.c:2716
#: ../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 "O tema contiña unha expresión que resultou ser un erro: %s\n"
#: ../src/ui/theme.c:4410
#: ../src/ui/theme.c:4482
#, c-format
msgid ""
"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be "
@ -1309,24 +1329,24 @@ msgstr ""
"<button function=«%s» state=«%s» draw_ops=\"whatever\"/> débese especificar "
"para este estilo de marco"
#: ../src/ui/theme.c:4940 ../src/ui/theme.c:4965
#: ../src/ui/theme.c:5012 ../src/ui/theme.c:5037
#, c-format
msgid ""
"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>"
msgstr "Falta <frame state=«%s» resize=«%s» focus=«%s» style=\"whatever\"/>"
#: ../src/ui/theme.c:5013
#: ../src/ui/theme.c:5085
#, c-format
msgid "Failed to load theme \"%s\": %s\n"
msgstr "Produciuse un fallo ao cargar o tema «%s»: %s\n"
#: ../src/ui/theme.c:5149 ../src/ui/theme.c:5156 ../src/ui/theme.c:5163
#: ../src/ui/theme.c:5170 ../src/ui/theme.c:5177
#: ../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 "Non se configurou <%s> para o tema «%s»"
#: ../src/ui/theme.c:5185
#: ../src/ui/theme.c:5257
#, c-format
msgid ""
"No frame style set for window type \"%s\" in theme \"%s\", add a <window "
@ -1335,7 +1355,7 @@ msgstr ""
"Non hai un estilo de marco para o tipo de xanela «%s» no tema «%s», engada "
"un elemento <window type=«%s» style_set=\"whatever\"/>"
#: ../src/ui/theme.c:5635 ../src/ui/theme.c:5697 ../src/ui/theme.c:5760
#: ../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"
@ -1343,7 +1363,7 @@ msgstr ""
"As constantes definidas polo usuario deben comezar cunha letra maiúscula; "
"«%s» non o fai"
#: ../src/ui/theme.c:5643 ../src/ui/theme.c:5705 ../src/ui/theme.c:5768
#: ../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 "A constante «%s» xa foi definida"

198
po/he.po
View File

@ -9,62 +9,72 @@ msgid ""
msgstr ""
"Project-Id-Version: metacity.HEAD.he\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-03-26 00:34+0200\n"
"PO-Revision-Date: 2011-03-26 00:35+0200\n"
"POT-Creation-Date: 2011-07-01 19:31+0300\n"
"PO-Revision-Date: 2011-07-01 19:33+0200\n"
"Last-Translator: Yaron Shahrabani <sh.yaron@gmail.com>\n"
"Language-Team: Hebrew <he@li.org>\n"
"Language: he\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: KBabel 1.10.2\n"
#. 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:509
#, c-format
msgid ""
"Another compositing manager is already running on screen %i on display \"%s"
"\"."
msgstr "מנהל תצוגת חלונות אחר כבר פועל במסך %i בתצוגה \"%s\"."
#: ../src/core/all-keybindings.h:88
msgid "Switch to workspace 1"
msgstr "Switch to workspace 1"
msgstr "מעבר למרחב עבודה 1"
#: ../src/core/all-keybindings.h:90
msgid "Switch to workspace 2"
msgstr "Switch to workspace 2"
msgstr "מעבר למרחב עבודה 2"
#: ../src/core/all-keybindings.h:92
msgid "Switch to workspace 3"
msgstr "Switch to workspace 3"
msgstr "מעבר למרחב עבודה 3"
#: ../src/core/all-keybindings.h:94
msgid "Switch to workspace 4"
msgstr "Switch to workspace 4"
msgstr "מעבר למרחב עבודה 4"
#: ../src/core/all-keybindings.h:96
msgid "Switch to workspace 5"
msgstr "Switch to workspace 5"
msgstr "מעבר למרחב עבודה 5"
#: ../src/core/all-keybindings.h:98
msgid "Switch to workspace 6"
msgstr "Switch to workspace 6"
msgstr "מעבר למרחב עבודה 6"
#: ../src/core/all-keybindings.h:100
msgid "Switch to workspace 7"
msgstr "Switch to workspace 7"
msgstr "מעבר למרחב עבודה 7"
#: ../src/core/all-keybindings.h:102
msgid "Switch to workspace 8"
msgstr "Switch to workspace 8"
msgstr "מעבר למרחב עבודה 8"
#: ../src/core/all-keybindings.h:104
msgid "Switch to workspace 9"
msgstr "Switch to workspace 9"
msgstr "מעבר למרחב עבודה 9"
#: ../src/core/all-keybindings.h:106
msgid "Switch to workspace 10"
msgstr "Switch to workspace 10"
msgstr "מעבר למרחב עבודה 10"
#: ../src/core/all-keybindings.h:108
msgid "Switch to workspace 11"
msgstr "Switch to workspace 11"
msgstr "מעבר למרחב עבודה 11"
#: ../src/core/all-keybindings.h:110
msgid "Switch to workspace 12"
msgstr "Switch to workspace 12"
msgstr "מעבר למרחב עבודה 12"
#: ../src/core/all-keybindings.h:122
msgid "Switch to workspace on the left of the current workspace"
@ -136,7 +146,7 @@ msgstr "Hide all normal windows and set focus to the desktop"
#: ../src/core/all-keybindings.h:206
msgid "Show the panel's main menu"
msgstr "Show the panel's main menu"
msgstr "הצגת התפריט הראשי של הלוח"
#: ../src/core/all-keybindings.h:209
msgid "Show the panel's \"Run Application\" dialog box"
@ -144,31 +154,31 @@ msgstr "Show the panel's \"Run Application\" dialog box"
#: ../src/core/all-keybindings.h:211
msgid "Start or stop recording the session"
msgstr "התחלה או עצירה של צילום ההפעלה"
msgstr "התחלה או עצירה של הקלטת ההפעלה"
#: ../src/core/all-keybindings.h:252
msgid "Take a screenshot"
msgstr "Take a screenshot"
msgstr "צילום תמונת מסך"
#: ../src/core/all-keybindings.h:254
msgid "Take a screenshot of a window"
msgstr "Take a screenshot of a window"
msgstr "צילום החלון"
#: ../src/core/all-keybindings.h:256
msgid "Run a terminal"
msgstr "Run a terminal"
msgstr "הפעלת מסוף"
#: ../src/core/all-keybindings.h:271
msgid "Activate the window menu"
msgstr "Activate the window menu"
msgstr "הפעלת תפריט החלון"
#: ../src/core/all-keybindings.h:274
msgid "Toggle fullscreen mode"
msgstr "Toggle fullscreen mode"
msgstr "כניסה למצב מסך מלא"
#: ../src/core/all-keybindings.h:276
msgid "Toggle maximization state"
msgstr "Toggle maximization state"
msgstr "הפעלה/כיבוי מצב הגדלה"
#: ../src/core/all-keybindings.h:278
msgid "Toggle whether a window will always be visible over other windows"
@ -335,24 +345,27 @@ msgstr "אירוע פעמון"
msgid "Unknown window information request: %d"
msgstr "Unknown window information request: %d"
#. Translators: %s is a window title
#: ../src/core/delete.c:94
#: ../src/core/delete.c:111
#, c-format
msgid "<tt>%s</tt> is not responding."
msgstr " <tt>%s</tt> אינו מגיב"
#: ../src/core/delete.c:99
#: ../src/core/delete.c:114
msgid "Application is not responding."
msgstr "היישום אינו מגיב."
#: ../src/core/delete.c:119
msgid ""
"You may choose to wait a short while for it to continue or force the "
"application to quit entirely."
msgstr ""
"באפשרותך להמתין זמן קצר ולתת ליישום להמשיך או להכריח את היישום להסתיים."
#: ../src/core/delete.c:108
#: ../src/core/delete.c:126
msgid "_Wait"
msgstr "ה_מתנה"
#: ../src/core/delete.c:108
#: ../src/core/delete.c:126
msgid "_Force Quit"
msgstr "_אילוץ סגירה"
@ -421,12 +434,12 @@ msgstr "Initialize session from savefile"
msgid "Make X calls synchronous"
msgstr "Make X calls synchronous"
#: ../src/core/main.c:506
#: ../src/core/main.c:504
#, c-format
msgid "Failed to scan themes directory: %s\n"
msgstr "Failed to scan themes directory: %s\n"
#: ../src/core/main.c:522
#: ../src/core/main.c:520
#, c-format
msgid ""
"Could not find a theme! Be sure %s exists and contains the usual themes.\n"
@ -549,12 +562,12 @@ msgstr "שגיאה בהגדרת מצב מצב החלונות החיים המוס
msgid "Error setting no tab popup status: %s\n"
msgstr "שגיאה בהגדרת מצב ללא לשוניות מוקפצות: %s\n"
#: ../src/core/screen.c:624
#: ../src/core/screen.c:663
#, c-format
msgid "Screen %d on display '%s' is invalid\n"
msgstr "Screen %d on display '%s' is invalid\n"
#: ../src/core/screen.c:640
#: ../src/core/screen.c:679
#, c-format
msgid ""
"Screen %d on display \"%s\" already has a window manager; try using the --"
@ -563,71 +576,71 @@ msgstr ""
"Screen %d on display \"%s\" already has a window manager; try using the --"
"replace option to replace the current window manager.\n"
#: ../src/core/screen.c:667
#: ../src/core/screen.c:706
#, c-format
msgid ""
"Could not acquire window manager selection on screen %d display \"%s\"\n"
msgstr ""
"Could not acquire window manager selection on screen %d display \"%s\"\n"
#: ../src/core/screen.c:722
#: ../src/core/screen.c:761
#, c-format
msgid "Screen %d on display \"%s\" already has a window manager\n"
msgstr "Screen %d on display \"%s\" already has a window manager\n"
#: ../src/core/screen.c:907
#: ../src/core/screen.c:946
#, c-format
msgid "Could not release screen %d on display \"%s\"\n"
msgstr "Could not release screen %d on display \"%s\"\n"
#: ../src/core/session.c:837 ../src/core/session.c:844
#: ../src/core/session.c:843 ../src/core/session.c:850
#, c-format
msgid "Could not create directory '%s': %s\n"
msgstr "Could not create directory '%s': %s\n"
#: ../src/core/session.c:854
#: ../src/core/session.c:860
#, c-format
msgid "Could not open session file '%s' for writing: %s\n"
msgstr "Could not open session file '%s' for writing: %s\n"
#: ../src/core/session.c:995
#: ../src/core/session.c:1001
#, c-format
msgid "Error writing session file '%s': %s\n"
msgstr "Error writing session file '%s': %s\n"
#: ../src/core/session.c:1000
#: ../src/core/session.c:1006
#, c-format
msgid "Error closing session file '%s': %s\n"
msgstr "Error closing session file '%s': %s\n"
#: ../src/core/session.c:1130
#: ../src/core/session.c:1136
#, c-format
msgid "Failed to parse saved session file: %s\n"
msgstr "Failed to parse saved session file: %s\n"
#: ../src/core/session.c:1179
#: ../src/core/session.c:1185
#, c-format
msgid "<mutter_session> attribute seen but we already have the session ID"
msgstr "התכונה <mutter_session> מופיעה אך כבר יש בידינו את מספר זיהוי ההפעלה"
#: ../src/core/session.c:1192 ../src/core/session.c:1267
#: ../src/core/session.c:1299 ../src/core/session.c:1371
#: ../src/core/session.c:1431
#: ../src/core/session.c:1198 ../src/core/session.c:1273
#: ../src/core/session.c:1305 ../src/core/session.c:1377
#: ../src/core/session.c:1437
#, c-format
msgid "Unknown attribute %s on <%s> element"
msgstr "Unknown attribute %s on <%s> element"
#: ../src/core/session.c:1209
#: ../src/core/session.c:1215
#, c-format
msgid "nested <window> tag"
msgstr "nested <window> tag"
#: ../src/core/session.c:1451
#: ../src/core/session.c:1457
#, c-format
msgid "Unknown element %s"
msgstr "Unknown element %s"
#: ../src/core/session.c:1803
#: ../src/core/session.c:1809
msgid ""
"These windows do not support &quot;save current setup&quot; and will have to "
"be restarted manually next time you log in."
@ -672,13 +685,13 @@ msgid "Window manager error: "
msgstr "Window manager error: "
#. Translators: This is the title used on dialog boxes
#: ../src/core/util.c:615 ../src/mutter.desktop.in.h:1
#: ../src/core/util.c:632 ../src/mutter.desktop.in.h:1
#: ../src/mutter-wm.desktop.in.h:1
msgid "Mutter"
msgstr "Mutter"
#. first time through
#: ../src/core/window.c:6795
#: ../src/core/window.c:6886
#, c-format
msgid ""
"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER "
@ -694,14 +707,14 @@ msgstr ""
#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain
#. * about these apps but make them work.
#.
#: ../src/core/window.c:7458
#: ../src/core/window.c:7549
#, c-format
msgid ""
"Window %s sets an MWM hint indicating it isn't resizable, but sets min size %"
"d x %d and max size %d x %d; this doesn't make much sense.\n"
"Window %s sets an MWM hint indicating it isn't resizable, but sets min size "
"%d x %d and max size %d x %d; this doesn't make much sense.\n"
msgstr ""
"Window %s sets an MWM hint indicating it isn't resizable, but sets min size %"
"d x %d and max size %d x %d; this doesn't make much sense.\n"
"Window %s sets an MWM hint indicating it isn't resizable, but sets min size "
"%d x %d and max size %d x %d; this doesn't make much sense.\n"
#: ../src/core/window-props.c:309
#, c-format
@ -713,7 +726,7 @@ msgstr "Application set a bogus _NET_WM_PID %lu\n"
msgid "%s (on %s)"
msgstr "%s (מעל %s)"
#: ../src/core/window-props.c:1479
#: ../src/core/window-props.c:1484
#, c-format
msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n"
msgstr "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n"
@ -804,47 +817,47 @@ msgstr "Workspaces only on primary"
msgid "Usage: %s\n"
msgstr "שימוש: %s\n"
#: ../src/ui/frames.c:1099
#: ../src/ui/frames.c:1280
msgid "Close Window"
msgstr "סגור חלון"
#: ../src/ui/frames.c:1102
#: ../src/ui/frames.c:1283
msgid "Window Menu"
msgstr "תפריט חלון"
#: ../src/ui/frames.c:1105
#: ../src/ui/frames.c:1286
msgid "Minimize Window"
msgstr "מזער חלון"
#: ../src/ui/frames.c:1108
#: ../src/ui/frames.c:1289
msgid "Maximize Window"
msgstr "הגדל חלון"
#: ../src/ui/frames.c:1111
#: ../src/ui/frames.c:1292
msgid "Restore Window"
msgstr "שחזר חלון"
#: ../src/ui/frames.c:1114
#: ../src/ui/frames.c:1295
msgid "Roll Up Window"
msgstr "גלול חלון מעלה"
#: ../src/ui/frames.c:1117
#: ../src/ui/frames.c:1298
msgid "Unroll Window"
msgstr "בטל גלילה"
#: ../src/ui/frames.c:1120
#: ../src/ui/frames.c:1301
msgid "Keep Window On Top"
msgstr "שמור על החלון גלוי"
#: ../src/ui/frames.c:1123
#: ../src/ui/frames.c:1304
msgid "Remove Window From Top"
msgstr "בטל שמירת החלון גלוי"
#: ../src/ui/frames.c:1126
#: ../src/ui/frames.c:1307
msgid "Always On Visible Workspace"
msgstr "הראה בכל סביבות העבודה"
#: ../src/ui/frames.c:1129
#: ../src/ui/frames.c:1310
msgid "Put Window On Only One Workspace"
msgstr "הראה את החלון על סביבת עבודה אחת בלבד"
@ -1157,12 +1170,17 @@ msgstr "Shade factor \"%s\" in shaded color is negative"
msgid "Could not parse color \"%s\""
msgstr "Could not parse color \"%s\""
#: ../src/ui/theme.c:1646
#: ../src/ui/theme.c:1481
#, c-format
msgid "Failed to retrieve color %s[%s] from GTK+ theme.\n"
msgstr "Failed to retrieve color %s[%s] from GTK+ theme.\n"
#: ../src/ui/theme.c:1713
#, c-format
msgid "Coordinate expression contains character '%s' which is not allowed"
msgstr "Coordinate expression contains character '%s' which is not allowed"
#: ../src/ui/theme.c:1673
#: ../src/ui/theme.c:1740
#, c-format
msgid ""
"Coordinate expression contains floating point number '%s' which could not be "
@ -1171,12 +1189,12 @@ msgstr ""
"Coordinate expression contains floating point number '%s' which could not be "
"parsed"
#: ../src/ui/theme.c:1687
#: ../src/ui/theme.c:1754
#, c-format
msgid "Coordinate expression contains integer '%s' which could not be parsed"
msgstr "Coordinate expression contains integer '%s' which could not be parsed"
#: ../src/ui/theme.c:1809
#: ../src/ui/theme.c:1876
#, c-format
msgid ""
"Coordinate expression contained unknown operator at the start of this text: "
@ -1185,41 +1203,41 @@ msgstr ""
"Coordinate expression contained unknown operator at the start of this text: "
"\"%s\""
#: ../src/ui/theme.c:1866
#: ../src/ui/theme.c:1933
#, c-format
msgid "Coordinate expression was empty or not understood"
msgstr "Coordinate expression was empty or not understood"
#: ../src/ui/theme.c:1977 ../src/ui/theme.c:1987 ../src/ui/theme.c:2021
#: ../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 "Coordinate expression results in division by zero"
#: ../src/ui/theme.c:2029
#: ../src/ui/theme.c:2096
#, c-format
msgid ""
"Coordinate expression tries to use mod operator on a floating-point number"
msgstr ""
"Coordinate expression tries to use mod operator on a floating-point number"
#: ../src/ui/theme.c:2085
#: ../src/ui/theme.c:2152
#, c-format
msgid ""
"Coordinate expression has an operator \"%s\" where an operand was expected"
msgstr ""
"Coordinate expression has an operator \"%s\" where an operand was expected"
#: ../src/ui/theme.c:2094
#: ../src/ui/theme.c:2161
#, c-format
msgid "Coordinate expression had an operand where an operator was expected"
msgstr "Coordinate expression had an operand where an operator was expected"
#: ../src/ui/theme.c:2102
#: ../src/ui/theme.c:2169
#, c-format
msgid "Coordinate expression ended with an operator instead of an operand"
msgstr "Coordinate expression ended with an operator instead of an operand"
#: ../src/ui/theme.c:2112
#: ../src/ui/theme.c:2179
#, c-format
msgid ""
"Coordinate expression has operator \"%c\" following operator \"%c\" with no "
@ -1228,38 +1246,38 @@ msgstr ""
"Coordinate expression has operator \"%c\" following operator \"%c\" with no "
"operand in between"
#: ../src/ui/theme.c:2263 ../src/ui/theme.c:2308
#: ../src/ui/theme.c:2330 ../src/ui/theme.c:2375
#, c-format
msgid "Coordinate expression had unknown variable or constant \"%s\""
msgstr "Coordinate expression had unknown variable or constant \"%s\""
#: ../src/ui/theme.c:2362
#: ../src/ui/theme.c:2429
#, c-format
msgid "Coordinate expression parser overflowed its buffer."
msgstr "Coordinate expression parser overflowed its buffer."
#: ../src/ui/theme.c:2391
#: ../src/ui/theme.c:2458
#, c-format
msgid "Coordinate expression had a close parenthesis with no open parenthesis"
msgstr "Coordinate expression had a close parenthesis with no open parenthesis"
#: ../src/ui/theme.c:2455
#: ../src/ui/theme.c:2522
#, c-format
msgid "Coordinate expression had an open parenthesis with no close parenthesis"
msgstr ""
"Coordinate expression had an open parenthesis with no close parenthesis"
#: ../src/ui/theme.c:2466
#: ../src/ui/theme.c:2533
#, c-format
msgid "Coordinate expression doesn't seem to have any operators or operands"
msgstr "Coordinate expression doesn't seem to have any operators or operands"
#: ../src/ui/theme.c:2676 ../src/ui/theme.c:2696 ../src/ui/theme.c:2716
#: ../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 "Theme contained an expression that resulted in an error: %s\n"
#: ../src/ui/theme.c:4410
#: ../src/ui/theme.c:4482
#, c-format
msgid ""
"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be "
@ -1268,25 +1286,25 @@ msgstr ""
"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be "
"specified for this frame style"
#: ../src/ui/theme.c:4940 ../src/ui/theme.c:4965
#: ../src/ui/theme.c:5012 ../src/ui/theme.c:5037
#, c-format
msgid ""
"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>"
msgstr ""
"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>"
#: ../src/ui/theme.c:5013
#: ../src/ui/theme.c:5085
#, c-format
msgid "Failed to load theme \"%s\": %s\n"
msgstr "Failed to load theme \"%s\": %s\n"
#: ../src/ui/theme.c:5149 ../src/ui/theme.c:5156 ../src/ui/theme.c:5163
#: ../src/ui/theme.c:5170 ../src/ui/theme.c:5177
#: ../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 "No <%s> set for theme \"%s\""
#: ../src/ui/theme.c:5185
#: ../src/ui/theme.c:5257
#, c-format
msgid ""
"No frame style set for window type \"%s\" in theme \"%s\", add a <window "
@ -1295,14 +1313,14 @@ msgstr ""
"No frame style set for window type \"%s\" in theme \"%s\", add a <window "
"type=\"%s\" style_set=\"whatever\"/> element"
#: ../src/ui/theme.c:5635 ../src/ui/theme.c:5697 ../src/ui/theme.c:5760
#: ../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"
msgstr ""
"User-defined constants must begin with a capital letter; \"%s\" does not"
#: ../src/ui/theme.c:5643 ../src/ui/theme.c:5705 ../src/ui/theme.c:5768
#: ../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 "Constant \"%s\" has already been defined"

2119
po/ja.po

File diff suppressed because it is too large Load Diff

153
po/nb.po
View File

@ -6,8 +6,8 @@ msgid ""
msgstr ""
"Project-Id-Version: mutter 2.91.x\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-03-22 11:13+0100\n"
"PO-Revision-Date: 2011-03-22 11:13+0100\n"
"POT-Creation-Date: 2011-07-02 00:15+0200\n"
"PO-Revision-Date: 2011-07-02 00:16+0200\n"
"Last-Translator: Kjartan Maraas <kmaraas@gnome.org>\n"
"Language-Team: Norwegian bokmål <i18n-no@lister.ping.uio.no>\n"
"Language: \n"
@ -15,6 +15,15 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#. 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:509
#, c-format
msgid ""
"Another compositing manager is already running on screen %i on display \"%s"
"\"."
msgstr "En annen compositing manager kjører skjerm %i på display «%s»."
#: ../src/core/all-keybindings.h:88
msgid "Switch to workspace 1"
msgstr "Bytt til arbeidsområde 1"
@ -332,13 +341,16 @@ msgstr "Klokkehendelse"
msgid "Unknown window information request: %d"
msgstr "Ukjent forespørsel om vindusinformasjon: %d"
#. Translators: %s is a window title
#: ../src/core/delete.c:94
#: ../src/core/delete.c:111
#, c-format
msgid "<tt>%s</tt> is not responding."
msgstr "<tt>%s</tt> svarer ikke."
#: ../src/core/delete.c:99
#: ../src/core/delete.c:114
msgid "Application is not responding."
msgstr "Programmet svarer ikke."
#: ../src/core/delete.c:119
msgid ""
"You may choose to wait a short while for it to continue or force the "
"application to quit entirely."
@ -346,11 +358,11 @@ msgstr ""
"Du kan velge å vente en kort stund for å se om det fortsetter eller tvinge "
"programmet til å avslutte helt."
#: ../src/core/delete.c:108
#: ../src/core/delete.c:126
msgid "_Wait"
msgstr "_Vent"
#: ../src/core/delete.c:108
#: ../src/core/delete.c:126
msgid "_Force Quit"
msgstr "_Tvungen nedstenging"
@ -421,12 +433,12 @@ msgstr "Initier sesjonen fra en lagret fil"
msgid "Make X calls synchronous"
msgstr "Gjør X-kall synkrone"
#: ../src/core/main.c:506
#: ../src/core/main.c:504
#, c-format
msgid "Failed to scan themes directory: %s\n"
msgstr "Feil under søk i temakatalog: %s\n"
#: ../src/core/main.c:522
#: ../src/core/main.c:520
#, c-format
msgid ""
"Could not find a theme! Be sure %s exists and contains the usual themes.\n"
@ -552,12 +564,12 @@ msgstr ""
msgid "Error setting no tab popup status: %s\n"
msgstr "Feil under setting av status for popup uten faner: %s\n"
#: ../src/core/screen.c:623
#: ../src/core/screen.c:663
#, c-format
msgid "Screen %d on display '%s' is invalid\n"
msgstr "Skjerm %d på display «%s» er ugyldig\n"
#: ../src/core/screen.c:639
#: ../src/core/screen.c:679
#, c-format
msgid ""
"Screen %d on display \"%s\" already has a window manager; try using the --"
@ -566,71 +578,71 @@ msgstr ""
"Skjerm %d på display «%s» har allerede en vindushåndterer; prøv å bruke "
"flagget --replace for å erstatte aktiv vindushåndterer.\n"
#: ../src/core/screen.c:666
#: ../src/core/screen.c:706
#, c-format
msgid ""
"Could not acquire window manager selection on screen %d display \"%s\"\n"
msgstr ""
"Kunne ikke hente utvalg fra vinduhåndterer på skjerm %d, display «%s»\n"
#: ../src/core/screen.c:721
#: ../src/core/screen.c:761
#, c-format
msgid "Screen %d on display \"%s\" already has a window manager\n"
msgstr "Skjerm %d på display «%s» har allerede en vinduhåndterer\n"
#: ../src/core/screen.c:906
#: ../src/core/screen.c:946
#, c-format
msgid "Could not release screen %d on display \"%s\"\n"
msgstr "Kunne ikke slippe skjerm %d på display «%s»\n"
#: ../src/core/session.c:837 ../src/core/session.c:844
#: ../src/core/session.c:843 ../src/core/session.c:850
#, c-format
msgid "Could not create directory '%s': %s\n"
msgstr "Kunne ikke opprette katalog «%s»: %s\n"
#: ../src/core/session.c:854
#: ../src/core/session.c:860
#, c-format
msgid "Could not open session file '%s' for writing: %s\n"
msgstr "Kunne ikke åpne sesjonsfil «%s» for skriving: %s\n"
#: ../src/core/session.c:995
#: ../src/core/session.c:1001
#, c-format
msgid "Error writing session file '%s': %s\n"
msgstr "Feil under skriving av sesjonsfil «%s»: %s\n"
#: ../src/core/session.c:1000
#: ../src/core/session.c:1006
#, c-format
msgid "Error closing session file '%s': %s\n"
msgstr "Feil under lukking av sesjonsfil «%s»: %s\n"
#: ../src/core/session.c:1130
#: ../src/core/session.c:1136
#, c-format
msgid "Failed to parse saved session file: %s\n"
msgstr "Feil under tolking av lagret sesjonsfil: %s\n"
#: ../src/core/session.c:1179
#: ../src/core/session.c:1185
#, c-format
msgid "<mutter_session> attribute seen but we already have the session ID"
msgstr "<mutter_session>-attributt sett men vi har allerede sesjons-ID"
#: ../src/core/session.c:1192 ../src/core/session.c:1267
#: ../src/core/session.c:1299 ../src/core/session.c:1371
#: ../src/core/session.c:1431
#: ../src/core/session.c:1198 ../src/core/session.c:1273
#: ../src/core/session.c:1305 ../src/core/session.c:1377
#: ../src/core/session.c:1437
#, c-format
msgid "Unknown attribute %s on <%s> element"
msgstr "Ukjent attributt %s på <%s>-element"
#: ../src/core/session.c:1209
#: ../src/core/session.c:1215
#, c-format
msgid "nested <window> tag"
msgstr "<window> tag med flere nivåer"
#: ../src/core/session.c:1451
#: ../src/core/session.c:1457
#, c-format
msgid "Unknown element %s"
msgstr "Ukjent element %s"
#: ../src/core/session.c:1803
#: ../src/core/session.c:1809
msgid ""
"These windows do not support &quot;save current setup&quot; and will have to "
"be restarted manually next time you log in."
@ -675,13 +687,13 @@ msgid "Window manager error: "
msgstr "Feil i vindushåndterer: "
#. Translators: This is the title used on dialog boxes
#: ../src/core/util.c:615 ../src/mutter.desktop.in.h:1
#: ../src/core/util.c:632 ../src/mutter.desktop.in.h:1
#: ../src/mutter-wm.desktop.in.h:1
msgid "Mutter"
msgstr "Mutter"
#. first time through
#: ../src/core/window.c:6795
#: ../src/core/window.c:6886
#, c-format
msgid ""
"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER "
@ -697,7 +709,7 @@ msgstr ""
#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain
#. * about these apps but make them work.
#.
#: ../src/core/window.c:7458
#: ../src/core/window.c:7549
#, c-format
msgid ""
"Window %s sets an MWM hint indicating it isn't resizable, but sets min size "
@ -717,7 +729,7 @@ msgstr "Programmet satte en feil _NET_WM_PID %lu\n"
msgid "%s (on %s)"
msgstr "%s (på %s)"
#: ../src/core/window-props.c:1479
#: ../src/core/window-props.c:1484
#, c-format
msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n"
msgstr "Ugyldig WM_TRANSIENT_FOR vindu 0x%lx oppgitt for %s.\n"
@ -766,7 +778,9 @@ msgstr ""
msgid ""
"Determines whether workspace switching should happen for windows on all "
"monitors or only for windows on the primary monitor."
msgstr "Bestemmer om bytting mellom arbeidsområder skal skje for vinduer på alle skjermer eller kun på primær skjerm."
msgstr ""
"Bestemmer om bytting mellom arbeidsområder skal skje for vinduer på alle "
"skjermer eller kun på primær skjerm."
#: ../src/mutter.schemas.in.h:4
msgid "Live Hidden Windows"
@ -807,47 +821,47 @@ msgstr "Arbeidsområder kun på primær skjerm"
msgid "Usage: %s\n"
msgstr " Bruk: %s\n"
#: ../src/ui/frames.c:1099
#: ../src/ui/frames.c:1280
msgid "Close Window"
msgstr "Lukk vindu"
#: ../src/ui/frames.c:1102
#: ../src/ui/frames.c:1283
msgid "Window Menu"
msgstr "Vindumeny"
#: ../src/ui/frames.c:1105
#: ../src/ui/frames.c:1286
msgid "Minimize Window"
msgstr "Minimer vindu"
#: ../src/ui/frames.c:1108
#: ../src/ui/frames.c:1289
msgid "Maximize Window"
msgstr "Maksimer vindu"
#: ../src/ui/frames.c:1111
#: ../src/ui/frames.c:1292
msgid "Restore Window"
msgstr "Gjenopprett vindu"
#: ../src/ui/frames.c:1114
#: ../src/ui/frames.c:1295
msgid "Roll Up Window"
msgstr "Rull opp vindu"
#: ../src/ui/frames.c:1117
#: ../src/ui/frames.c:1298
msgid "Unroll Window"
msgstr "Rull ned vindu"
#: ../src/ui/frames.c:1120
#: ../src/ui/frames.c:1301
msgid "Keep Window On Top"
msgstr "Plasser vindu i forgrunnen"
#: ../src/ui/frames.c:1123
#: ../src/ui/frames.c:1304
msgid "Remove Window From Top"
msgstr "Fjern vindu fra forgrunnen"
#: ../src/ui/frames.c:1126
#: ../src/ui/frames.c:1307
msgid "Always On Visible Workspace"
msgstr "Alltid på synlig arbeidsområde"
#: ../src/ui/frames.c:1129
#: ../src/ui/frames.c:1310
msgid "Put Window On Only One Workspace"
msgstr "Plasser vindu kun på ett arbeidsområde"
@ -1160,24 +1174,29 @@ msgstr "Skyggefaktor «%s» i skyggelagt farge er negativ"
msgid "Could not parse color \"%s\""
msgstr "Kunne ikke lese farge «%s»"
#: ../src/ui/theme.c:1646
#: ../src/ui/theme.c:1481
#, c-format
msgid "Failed to retrieve color %s[%s] from GTK+ theme.\n"
msgstr "Klarte ikke å hente farge %s[%s] fra GTK+-tema.\n"
#: ../src/ui/theme.c:1713
#, c-format
msgid "Coordinate expression contains character '%s' which is not allowed"
msgstr "Koordinatuttrykk inneholder tegn «%s» som ikke er tillatt"
#: ../src/ui/theme.c:1673
#: ../src/ui/theme.c:1740
#, c-format
msgid ""
"Coordinate expression contains floating point number '%s' which could not be "
"parsed"
msgstr "Koordinatuttrykk inneholder flyttall «%s» som ikke kunne tolkes"
#: ../src/ui/theme.c:1687
#: ../src/ui/theme.c:1754
#, c-format
msgid "Coordinate expression contains integer '%s' which could not be parsed"
msgstr "Koordinatuttrykk inneholder heltall «%s» som ikke kunne tolkes"
#: ../src/ui/theme.c:1809
#: ../src/ui/theme.c:1876
#, c-format
msgid ""
"Coordinate expression contained unknown operator at the start of this text: "
@ -1186,39 +1205,39 @@ msgstr ""
"Koordinatuttrykket inneholdt en ukjent operator ved begynnelsen av denne "
"teksten: «%s»"
#: ../src/ui/theme.c:1866
#: ../src/ui/theme.c:1933
#, c-format
msgid "Coordinate expression was empty or not understood"
msgstr "Koordinatuttrykket var tomt eller ble ikke forstått"
#: ../src/ui/theme.c:1977 ../src/ui/theme.c:1987 ../src/ui/theme.c:2021
#: ../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 "Koordinatuttrykket resulterer i divisjon med null"
#: ../src/ui/theme.c:2029
#: ../src/ui/theme.c:2096
#, c-format
msgid ""
"Coordinate expression tries to use mod operator on a floating-point number"
msgstr "Koordinatuttrykket prøver å bruke mod-operator på et flyttall"
#: ../src/ui/theme.c:2085
#: ../src/ui/theme.c:2152
#, c-format
msgid ""
"Coordinate expression has an operator \"%s\" where an operand was expected"
msgstr "Koordinatuttrykket har en operator «%s» hvor en operand var ventet"
#: ../src/ui/theme.c:2094
#: ../src/ui/theme.c:2161
#, c-format
msgid "Coordinate expression had an operand where an operator was expected"
msgstr "Koordinatuttrykket hadde en operand hvor en operator var ventet"
#: ../src/ui/theme.c:2102
#: ../src/ui/theme.c:2169
#, c-format
msgid "Coordinate expression ended with an operator instead of an operand"
msgstr "Koordinatuttrykket sluttet med en operator i stedet for en operand"
#: ../src/ui/theme.c:2112
#: ../src/ui/theme.c:2179
#, c-format
msgid ""
"Coordinate expression has operator \"%c\" following operator \"%c\" with no "
@ -1227,38 +1246,38 @@ msgstr ""
"Koordinatuttrykket har en operator «%c» etter en operator «%c» og ingen "
"operand mellom dem."
#: ../src/ui/theme.c:2263 ../src/ui/theme.c:2308
#: ../src/ui/theme.c:2330 ../src/ui/theme.c:2375
#, c-format
msgid "Coordinate expression had unknown variable or constant \"%s\""
msgstr "Koordinatuttrykket haddeen ukjent variabel eller konstant «%s»"
#: ../src/ui/theme.c:2362
#: ../src/ui/theme.c:2429
#, c-format
msgid "Coordinate expression parser overflowed its buffer."
msgstr "Tolkeren for koordinatuttrykk oversteg buffergrensen."
#: ../src/ui/theme.c:2391
#: ../src/ui/theme.c:2458
#, c-format
msgid "Coordinate expression had a close parenthesis with no open parenthesis"
msgstr "Koordinatuttrykket hadde en parantes slutt uten parantes start"
#: ../src/ui/theme.c:2455
#: ../src/ui/theme.c:2522
#, c-format
msgid "Coordinate expression had an open parenthesis with no close parenthesis"
msgstr "Koordinatuttrykket hadde en åpen parantes uten en avsluttende parantes"
#: ../src/ui/theme.c:2466
#: ../src/ui/theme.c:2533
#, c-format
msgid "Coordinate expression doesn't seem to have any operators or operands"
msgstr ""
"Koordinatuttrykket ser ikke ut til å ha noen operatorer eller operander"
#: ../src/ui/theme.c:2676 ../src/ui/theme.c:2696 ../src/ui/theme.c:2716
#: ../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 "Tema inneholdt et uttrykk som resulterte i en feil: %s\n"
#: ../src/ui/theme.c:4410
#: ../src/ui/theme.c:4482
#, c-format
msgid ""
"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be "
@ -1267,25 +1286,25 @@ msgstr ""
"<button function=«%s» state=«%s» draw_ops=«ett-eller-annet»/> må "
"spesifiseres for denne rammestilen"
#: ../src/ui/theme.c:4940 ../src/ui/theme.c:4965
#: ../src/ui/theme.c:5012 ../src/ui/theme.c:5037
#, c-format
msgid ""
"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>"
msgstr ""
"Mangler <frame state=«%s» resize=«%s» focus=«%s» stil=«ett-eller-annet»/>"
#: ../src/ui/theme.c:5013
#: ../src/ui/theme.c:5085
#, c-format
msgid "Failed to load theme \"%s\": %s\n"
msgstr "Klarte ikke å laste tema «%s»: %s\n"
#: ../src/ui/theme.c:5149 ../src/ui/theme.c:5156 ../src/ui/theme.c:5163
#: ../src/ui/theme.c:5170 ../src/ui/theme.c:5177
#: ../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 "<%s> er ikke satt for tema «%s»"
#: ../src/ui/theme.c:5185
#: ../src/ui/theme.c:5257
#, c-format
msgid ""
"No frame style set for window type \"%s\" in theme \"%s\", add a <window "
@ -1294,14 +1313,14 @@ msgstr ""
"Ingen rammestil satt for vindutype «%s» i tema «%s», legg til et <window "
"type=«%s» style_set=«ett-eller-annet»/>-element"
#: ../src/ui/theme.c:5635 ../src/ui/theme.c:5697 ../src/ui/theme.c:5760
#: ../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"
msgstr ""
"Brukerdefinerte konstanter må begynne med stor bokstav; «%s» gjør ikke det"
#: ../src/ui/theme.c:5643 ../src/ui/theme.c:5705 ../src/ui/theme.c:5768
#: ../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 "Konstant «%s» er allerede definert"

191
po/sl.po
View File

@ -10,8 +10,8 @@ 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: 2011-03-22 10:13+0000\n"
"PO-Revision-Date: 2011-03-22 21:47+0100\n"
"POT-Creation-Date: 2011-07-02 06:54+0000\n"
"PO-Revision-Date: 2011-07-02 20:25+0100\n"
"Last-Translator: Matej Urbančič <mateju@svn.gnome.org>\n"
"Language-Team: Slovenian GNOME Translation Team <gnome-si@googlegroups.com>\n"
"Language: \n"
@ -23,6 +23,13 @@ msgstr ""
"X-Poedit-Country: SLOVENIA\n"
"X-Poedit-SourceCharset: utf-8\n"
#. 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:509
#, c-format
msgid "Another compositing manager is already running on screen %i on display \"%s\"."
msgstr "Drug upravljalnik sestavljanja je že zagnan na zaslonu %i prikaza \"%s\"."
#: ../src/core/all-keybindings.h:88
msgid "Switch to workspace 1"
msgstr "Preklopi na delovno površino 1"
@ -345,21 +352,24 @@ msgstr "Dogodek zvonjenja"
msgid "Unknown window information request: %d"
msgstr "Zahteva izpisa podrobnosti neznanega okna: %d"
#. Translators: %s is a window title
#: ../src/core/delete.c:94
#: ../src/core/delete.c:111
#, c-format
msgid "<tt>%s</tt> is not responding."
msgstr "<tt>%s</tt> se ne odziva."
#: ../src/core/delete.c:99
#: ../src/core/delete.c:114
msgid "Application is not responding."
msgstr "Program se ne odziva."
#: ../src/core/delete.c:119
msgid "You may choose to wait a short while for it to continue or force the application to quit entirely."
msgstr "Lahko še malo počakate, če program morda spet začne delovati, ali pa vsilite končanje delovanja."
#: ../src/core/delete.c:108
#: ../src/core/delete.c:126
msgid "_Wait"
msgstr "_Počakaj"
#: ../src/core/delete.c:108
#: ../src/core/delete.c:126
msgid "_Force Quit"
msgstr "_Vsili konec"
@ -427,12 +437,12 @@ msgstr "Začni sejo iz shranjene datoteke"
msgid "Make X calls synchronous"
msgstr "Uskladi klice X"
#: ../src/core/main.c:506
#: ../src/core/main.c:504
#, c-format
msgid "Failed to scan themes directory: %s\n"
msgstr "Ni mogoče preiskati mape tem: %s\n"
#: ../src/core/main.c:522
#: ../src/core/main.c:520
#, c-format
msgid "Could not find a theme! Be sure %s exists and contains the usual themes.\n"
msgstr "Ni mogoče najti teme! Prepričajte se, da %s obstaja in vsebuje običajni zapis teme.\n"
@ -551,84 +561,84 @@ msgstr "Napaka med nastavljanjem stanja skritih oken: %s\n"
msgid "Error setting no tab popup status: %s\n"
msgstr "Napaka med nastavljanjem stanja pojavnih oken: %s\n"
#: ../src/core/screen.c:623
#: ../src/core/screen.c:663
#, c-format
msgid "Screen %d on display '%s' is invalid\n"
msgstr "Zaslon %d na prikazu '%s' ni veljaven\n"
#: ../src/core/screen.c:639
#: ../src/core/screen.c:679
#, c-format
msgid "Screen %d on display \"%s\" already has a window manager; try using the --replace option to replace the current window manager.\n"
msgstr "Zaslon %d na prikazu \"%s\" je že upravljan z upravljalnikom oken; poskušajte uporabiti možnost --replace za zamenjavo trenutnega.\n"
#: ../src/core/screen.c:666
#: ../src/core/screen.c:706
#, c-format
msgid "Could not acquire window manager selection on screen %d display \"%s\"\n"
msgstr "Ni mogoče dobiti izbire upravljalnika oken na zaslonu %d prikaza \"%s\"\n"
#: ../src/core/screen.c:721
#: ../src/core/screen.c:761
#, c-format
msgid "Screen %d on display \"%s\" already has a window manager\n"
msgstr "Zaslon %d na prikazu \"%s\" je že upravljan z upravljalnikom oken\n"
#: ../src/core/screen.c:906
#: ../src/core/screen.c:946
#, c-format
msgid "Could not release screen %d on display \"%s\"\n"
msgstr "Ni mogoče opustiti zaslona %d na prikazu \"%s\"\n"
#: ../src/core/session.c:837
#: ../src/core/session.c:844
#: ../src/core/session.c:843
#: ../src/core/session.c:850
#, c-format
msgid "Could not create directory '%s': %s\n"
msgstr "Ni mogoče ustvariti imenika '%s': %s\n"
# G:2 K:0 O:0
#: ../src/core/session.c:854
#: ../src/core/session.c:860
#, c-format
msgid "Could not open session file '%s' for writing: %s\n"
msgstr "Ni mogoče odpreti datoteke seje '%s' za pisanje: %s\n"
#: ../src/core/session.c:995
#: ../src/core/session.c:1001
#, c-format
msgid "Error writing session file '%s': %s\n"
msgstr "Napaka med zapisovanjem datoteke seje '%s': %s\n"
#: ../src/core/session.c:1000
#: ../src/core/session.c:1006
#, c-format
msgid "Error closing session file '%s': %s\n"
msgstr "Napaka med zapiranjem datoteke seje '%s': %s\n"
#: ../src/core/session.c:1130
#: ../src/core/session.c:1136
#, c-format
msgid "Failed to parse saved session file: %s\n"
msgstr "Ni mogoče razčleniti datoteke shranjene seje: %s\n"
#: ../src/core/session.c:1179
#: ../src/core/session.c:1185
#, c-format
msgid "<mutter_session> attribute seen but we already have the session ID"
msgstr "atribut <mutter_session> je zaznan, vendar pa ima sistem že določen ID seje"
#: ../src/core/session.c:1192
#: ../src/core/session.c:1267
#: ../src/core/session.c:1299
#: ../src/core/session.c:1371
#: ../src/core/session.c:1431
#: ../src/core/session.c:1198
#: ../src/core/session.c:1273
#: ../src/core/session.c:1305
#: ../src/core/session.c:1377
#: ../src/core/session.c:1437
#, c-format
msgid "Unknown attribute %s on <%s> element"
msgstr "Neznan atribut %s predmeta <%s>"
#: ../src/core/session.c:1209
#: ../src/core/session.c:1215
#, c-format
msgid "nested <window> tag"
msgstr "gnezdena označba <window>"
#: ../src/core/session.c:1451
#: ../src/core/session.c:1457
#, c-format
msgid "Unknown element %s"
msgstr "Neznan predmet %s"
# G:2 K:6 O:0
#: ../src/core/session.c:1803
#: ../src/core/session.c:1809
msgid "These windows do not support &quot;save current setup&quot; and will have to be restarted manually next time you log in."
msgstr "Ta okna ne podpirajo možnosti &quot;shranjevanja trenutnih nastavitev&quot;, zato jih bo treba ob naslednji prijavi zagnati ročno."
@ -671,14 +681,14 @@ msgid "Window manager error: "
msgstr "Napaka upravljalnika oken: "
#. Translators: This is the title used on dialog boxes
#: ../src/core/util.c:615
#: ../src/core/util.c:632
#: ../src/mutter.desktop.in.h:1
#: ../src/mutter-wm.desktop.in.h:1
msgid "Mutter"
msgstr "Mutter"
#. first time through
#: ../src/core/window.c:6795
#: ../src/core/window.c:6886
#, c-format
msgid "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER window as specified in the ICCCM.\n"
msgstr "Okno %s nastavi svoj SM_CLIENT_ID, namesto, da bi nastavilo WM_CLIENT_LEADER kot je zavedeno v ICCCM.\n"
@ -690,7 +700,7 @@ msgstr "Okno %s nastavi svoj SM_CLIENT_ID, namesto, da bi nastavilo WM_CLIENT_LE
#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain
#. * about these apps but make them work.
#.
#: ../src/core/window.c:7458
#: ../src/core/window.c:7549
#, c-format
msgid "Window %s sets an MWM hint indicating it isn't resizable, but sets min size %d x %d and max size %d x %d; this doesn't make much sense.\n"
msgstr "Okno %s določi namig MWM, ki pove, da ni mogoče spremeniti velikosti, hkrati pa določi najmanjšo velikost na %d x %d in največjo na %d x %d; vrednost ni smiselna.\n"
@ -705,7 +715,7 @@ msgstr "Program je nastavil pokvarjen _NET_WM_PID %lu\n"
msgid "%s (on %s)"
msgstr "%s (na %s)"
#: ../src/core/window-props.c:1479
#: ../src/core/window-props.c:1484
#, c-format
msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n"
msgstr "Neveljaven WM_TRANSIENT_FOR za okno 0x%lx naveden za %s.\n"
@ -772,51 +782,51 @@ msgstr "Delovne površine le na prvem zaslonu"
msgid "Usage: %s\n"
msgstr "Uporaba: %s\n"
#: ../src/ui/frames.c:1099
#: ../src/ui/frames.c:1280
msgid "Close Window"
msgstr "Zapri okno"
# G:1 K:1 O:0
#: ../src/ui/frames.c:1102
#: ../src/ui/frames.c:1283
msgid "Window Menu"
msgstr "Meni okna"
# G:0 K:1 O:0
#: ../src/ui/frames.c:1105
#: ../src/ui/frames.c:1286
msgid "Minimize Window"
msgstr "Skrči okno"
#: ../src/ui/frames.c:1108
#: ../src/ui/frames.c:1289
msgid "Maximize Window"
msgstr "Razpni okno"
#: ../src/ui/frames.c:1111
#: ../src/ui/frames.c:1292
msgid "Restore Window"
msgstr "Obnovi okno"
# G:2 K:0 O:0
#: ../src/ui/frames.c:1114
#: ../src/ui/frames.c:1295
msgid "Roll Up Window"
msgstr "Zavij okno"
#: ../src/ui/frames.c:1117
#: ../src/ui/frames.c:1298
msgid "Unroll Window"
msgstr "Odvij okno"
#: ../src/ui/frames.c:1120
#: ../src/ui/frames.c:1301
msgid "Keep Window On Top"
msgstr "Ohrani okno na vrhu"
#: ../src/ui/frames.c:1123
#: ../src/ui/frames.c:1304
msgid "Remove Window From Top"
msgstr "Odstrani okno z vrha"
# G:1 K:0 O:0
#: ../src/ui/frames.c:1126
#: ../src/ui/frames.c:1307
msgid "Always On Visible Workspace"
msgstr "Vedno na vidni delovni površini"
#: ../src/ui/frames.c:1129
#: ../src/ui/frames.c:1310
msgid "Put Window On Only One Workspace"
msgstr "Postavi okno na samo eno delovno površino"
@ -1138,136 +1148,141 @@ msgstr "V senčeni barvi je vrednost senčenja \"%s\" negativna"
msgid "Could not parse color \"%s\""
msgstr "Ni mogoče razčleniti barve \"%s\""
#: ../src/ui/theme.c:1646
#: ../src/ui/theme.c:1481
#, c-format
msgid "Failed to retrieve color %s[%s] from GTK+ theme.\n"
msgstr "Pridobivanje barve %s[%s] iz teme GTK+ je spodletelo.\n"
#: ../src/ui/theme.c:1713
#, c-format
msgid "Coordinate expression contains character '%s' which is not allowed"
msgstr "Izraz koordinat vsebuje znak '%s', ki pa ni dovoljen"
#: ../src/ui/theme.c:1673
#: ../src/ui/theme.c:1740
#, c-format
msgid "Coordinate expression contains floating point number '%s' which could not be parsed"
msgstr "Izraz koordinat vsebuje številko s plavajočo vejico '%s', ki je ni mogoče razčleniti"
#: ../src/ui/theme.c:1687
#: ../src/ui/theme.c:1754
#, c-format
msgid "Coordinate expression contains integer '%s' which could not be parsed"
msgstr "Izraz koordinat vsebuje celo število '%s', ki ga ni mogoče razčleniti"
#: ../src/ui/theme.c:1809
#: ../src/ui/theme.c:1876
#, c-format
msgid "Coordinate expression contained unknown operator at the start of this text: \"%s\""
msgstr "Izraz koordinat vsebuje neznan operator na začetku besedila: \"%s\""
#: ../src/ui/theme.c:1866
#: ../src/ui/theme.c:1933
#, c-format
msgid "Coordinate expression was empty or not understood"
msgstr "Izraz koordinat je prazen ali pa ni v razumljivem zapisu"
#: ../src/ui/theme.c:1977
#: ../src/ui/theme.c:1987
#: ../src/ui/theme.c:2021
#: ../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 "Izraz koordinat povzroči deljenje z vrednostjo nič"
#: ../src/ui/theme.c:2029
#: ../src/ui/theme.c:2096
#, c-format
msgid "Coordinate expression tries to use mod operator on a floating-point number"
msgstr "Izraz koordinat poskuša uporabiti operator mod ali številko s plavajočo vejico"
#: ../src/ui/theme.c:2085
#: ../src/ui/theme.c:2152
#, c-format
msgid "Coordinate expression has an operator \"%s\" where an operand was expected"
msgstr "Izraz koordinat vsebuje operator \"%s\", kjer je pričakovan operand"
#: ../src/ui/theme.c:2094
#: ../src/ui/theme.c:2161
#, c-format
msgid "Coordinate expression had an operand where an operator was expected"
msgstr "Izraz koordinat vsebuje operand kjer je pričakovan operator"
#: ../src/ui/theme.c:2102
#: ../src/ui/theme.c:2169
#, c-format
msgid "Coordinate expression ended with an operator instead of an operand"
msgstr "Izraz koordinat se konča z operatorjem namesto z operandom"
#: ../src/ui/theme.c:2112
#: ../src/ui/theme.c:2179
#, c-format
msgid "Coordinate expression has operator \"%c\" following operator \"%c\" with no operand in between"
msgstr "Izraz koordinat vsebuje operator \"%c\", ki sledi operatorju \"%c\", brez vmesnega operanda"
#: ../src/ui/theme.c:2263
#: ../src/ui/theme.c:2308
#: ../src/ui/theme.c:2330
#: ../src/ui/theme.c:2375
#, c-format
msgid "Coordinate expression had unknown variable or constant \"%s\""
msgstr "Izraz koordinat vsebuje neznano spremenljivko ali konstanto \"%s\""
#: ../src/ui/theme.c:2362
#: ../src/ui/theme.c:2429
#, c-format
msgid "Coordinate expression parser overflowed its buffer."
msgstr "Razčlenjevalnik izrazov koordinat je preplavil medpomnilnik."
#: ../src/ui/theme.c:2391
#: ../src/ui/theme.c:2458
#, c-format
msgid "Coordinate expression had a close parenthesis with no open parenthesis"
msgstr "Izraz koordinat vsebuje zaklepaj, ne pa tudi uklepaja"
#: ../src/ui/theme.c:2455
#: ../src/ui/theme.c:2522
#, c-format
msgid "Coordinate expression had an open parenthesis with no close parenthesis"
msgstr "Izraz koordinat vsebuje uklepaj, vendar je brez zaklepaja"
#: ../src/ui/theme.c:2466
#: ../src/ui/theme.c:2533
#, c-format
msgid "Coordinate expression doesn't seem to have any operators or operands"
msgstr "Videti je, da izraz koordinat ne vsebuje operatorjev ali operandov"
#: ../src/ui/theme.c:2676
#: ../src/ui/theme.c:2696
#: ../src/ui/theme.c:2716
#: ../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 "Tema vsebuje izraz, ki povzroča napako: %s\n"
#: ../src/ui/theme.c:4410
#: ../src/ui/theme.c:4482
#, c-format
msgid "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be specified for this frame style"
msgstr "Za ta slog okvirja mora biti naveden <button function=\"%s\" state=\"%s\" draw_ops=\"karkoli\"/>"
#: ../src/ui/theme.c:4940
#: ../src/ui/theme.c:4965
#: ../src/ui/theme.c:5012
#: ../src/ui/theme.c:5037
#, c-format
msgid "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>"
msgstr "Manjka <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"karkoli\"/>"
#: ../src/ui/theme.c:5013
#: ../src/ui/theme.c:5085
#, c-format
msgid "Failed to load theme \"%s\": %s\n"
msgstr "Napaka med nalaganjem teme \"%s\": %s\n"
#: ../src/ui/theme.c:5149
#: ../src/ui/theme.c:5156
#: ../src/ui/theme.c:5163
#: ../src/ui/theme.c:5170
#: ../src/ui/theme.c:5177
#: ../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 "Ni nastavljena vrednost <%s> za temo \"%s\""
#: ../src/ui/theme.c:5185
#: ../src/ui/theme.c:5257
#, c-format
msgid "No frame style set for window type \"%s\" in theme \"%s\", add a <window type=\"%s\" style_set=\"whatever\"/> element"
msgstr "Ni določenega sloga okvirja okna vrste \"%s\" v temi \"%s\". Dodajte predmet <window type=\"%s\" style_set=\"whatever\"/>"
#: ../src/ui/theme.c:5635
#: ../src/ui/theme.c:5697
#: ../src/ui/theme.c:5760
#: ../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"
msgstr "Uporabniško določene konstante se morajo začeti z veliko črko; vrednost \"%s\" se ne"
#: ../src/ui/theme.c:5643
#: ../src/ui/theme.c:5705
#: ../src/ui/theme.c:5768
#: ../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 "Konstanta \"%s\" je že določena"
@ -1838,25 +1853,35 @@ msgstr "%d izjav koordinat razčlenjenih v %g sekundah (%g sekund v povprečju)\
#~ msgid "Turn compositing on"
#~ msgstr "Vključi skladanje"
#~ msgid "Turn compositing off"
#~ msgstr "Izključi skladanje"
#~ msgid ""
#~ "Don't make fullscreen windows that are maximized and have no decorations"
#~ msgstr "Ne ustvari celozaslonskih oken, ki so razpeti in nimajo gumbov"
#~ msgid "Whether window popup/frame should be shown when cycling windows."
#~ msgstr "Ali naj bo prikazan okvir okna med kroženjem oken."
#~ msgid "Internal argument for GObject introspection"
#~ msgstr "Notranji argument za GObject"
#~ msgid "Failed to restart: %s\n"
#~ msgstr "Spodletelo začenjanje: %s\n"
#~ msgid "Error setting compositor status: %s\n"
#~ msgstr "Napaka med nastavljanjem stanja skladanja: %s\n"
#~ msgid "Error setting clutter plugin list: %s\n"
#~ msgstr "Napaka med nastavljanjem seznama vstavkov clutter: %s\n"
#~ msgid "Clutter Plugins"
#~ msgstr "Vstavki Clutter"
#~ msgid "Plugins to load for the Clutter-based compositing manager."
#~ msgstr "Vstavki za Clutter upravljalnik sestavljanja"
#~ msgid ""
#~ "Lost connection to the display '%s';\n"
#~ "most likely the X server was shut down or you killed/destroyed\n"
@ -1865,6 +1890,6 @@ msgstr "%d izjav koordinat razčlenjenih v %g sekundah (%g sekund v povprečju)\
#~ "Izgubljena povezava z zaslonom '%s';\n"
#~ "najverjetneje se je strežnik X končal ali pa je vsiljeno izklopljen\n"
#~ "upravljalnik oken.\n"
#~ msgid "Fatal IO error %d (%s) on display '%s'.\n"
#~ msgstr "Usodna napaka VI %d (%s) na zaslonu '%s'.\n"

1316
po/sr.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

160
po/tr.po
View File

@ -4,6 +4,7 @@
# Sinan İmamoğlu <sinan@myrealbox.com>, 2003.
# Baris Cicek <baris@teamforce.name.tr>, 2004, 2005, 2008, 2009.
# İlker DAĞLI <ilker@ilkerdagli.info>, 2011.
# Muhammed EKEN <gnome@m-eken.com>, 2011.
# Muhammet Kara <muhammet.k@gmail.com>, 2011.
#
msgid ""
@ -11,8 +12,8 @@ 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: 2011-04-20 18:41+0000\n"
"PO-Revision-Date: 2011-04-23 02:03+0300\n"
"POT-Creation-Date: 2011-06-30 21:06+0000\n"
"PO-Revision-Date: 2011-07-01 01:50+0300\n"
"Last-Translator: Muhammet Kara <muhammet.k@gmail.com>\n"
"Language-Team: Turkish <gnome-turk@gnome.org>\n"
"MIME-Version: 1.0\n"
@ -21,6 +22,19 @@ msgstr ""
"X-Generator: Lokalize 1.1\n"
"Plural-Forms: nplurals=1; plural=0;\n"
#. 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:509
#, 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\" monitöründeki %1$i ekranında zaten başka bir birleştirme yöneticisi "
"çalışıyor."
#: ../src/core/all-keybindings.h:88
msgid "Switch to workspace 1"
msgstr "Çalışma alanı 1'e geç"
@ -345,13 +359,16 @@ msgstr "Etkinlik zili"
msgid "Unknown window information request: %d"
msgstr "Bilinmeyen pencere bilgi isteği: %d"
#. Translators: %s is a window title
#: ../src/core/delete.c:94
#: ../src/core/delete.c:111
#, c-format
msgid "<tt>%s</tt> is not responding."
msgstr "<tt>%s</tt> cevap vermiyor."
#: ../src/core/delete.c:99
#: ../src/core/delete.c:114
msgid "Application is not responding."
msgstr "Uygulama cevap vermiyor"
#: ../src/core/delete.c:119
msgid ""
"You may choose to wait a short while for it to continue or force the "
"application to quit entirely."
@ -359,11 +376,11 @@ msgstr ""
"Uygulamanın devam etmesi için bir müddet bekleyi seçebilirsiniz ya d a "
"uygulamanın tamamen çıkması için onu zorlayabilirsiniz."
#: ../src/core/delete.c:108
#: ../src/core/delete.c:126
msgid "_Wait"
msgstr "_Bekle"
#: ../src/core/delete.c:108
#: ../src/core/delete.c:126
msgid "_Force Quit"
msgstr "_Sonlandır"
@ -434,12 +451,12 @@ msgstr "Ortamı kayıtlı dosyadan başlat"
msgid "Make X calls synchronous"
msgstr "X çağrılarını eşazamanlı yap"
#: ../src/core/main.c:506
#: ../src/core/main.c:504
#, c-format
msgid "Failed to scan themes directory: %s\n"
msgstr "Tema dizini taranırken hata oluştu: %s\n"
#: ../src/core/main.c:522
#: ../src/core/main.c:520
#, c-format
msgid ""
"Could not find a theme! Be sure %s exists and contains the usual themes.\n"
@ -558,19 +575,19 @@ msgstr "%d çalışma alanının adının \"%s\" yapılmasında hata: %s\n"
#: ../src/core/prefs.c:2997
#, c-format
msgid "Error setting live hidden windows status status: %s\n"
msgstr ""
msgstr "Aktif gizli pencere durumu ayarlanırken oluşan hata: %s\n"
#: ../src/core/prefs.c:3032
#, c-format
msgid "Error setting no tab popup status: %s\n"
msgstr "Sekmesiz açılır pencere durumu ayarlanırken hata: %s\n"
#: ../src/core/screen.c:624
#: ../src/core/screen.c:663
#, c-format
msgid "Screen %d on display '%s' is invalid\n"
msgstr "'%2$s' X oturumundaki ekran %1$d geçersiz\n"
#: ../src/core/screen.c:640
#: ../src/core/screen.c:679
#, c-format
msgid ""
"Screen %d on display \"%s\" already has a window manager; try using the --"
@ -580,7 +597,7 @@ msgstr ""
"geçerli pencere yöneticisinin yerine bir başkasını koymak için --replace "
"seçeneğini kullanmayı deneyin.\n"
#: ../src/core/screen.c:667
#: ../src/core/screen.c:706
#, c-format
msgid ""
"Could not acquire window manager selection on screen %d display \"%s\"\n"
@ -588,67 +605,67 @@ msgstr ""
"\"%2$s\" X oturumundaki ekran %1$d hangi pencere yöneticisine "
"sahipöğrenilemedi\n"
#: ../src/core/screen.c:722
#: ../src/core/screen.c:761
#, c-format
msgid "Screen %d on display \"%s\" already has a window manager\n"
msgstr ""
"\"%2$s\" X oturumundaki ekran %1$d bir pencere yöneticisine zaten sahip\n"
#: ../src/core/screen.c:907
#: ../src/core/screen.c:946
#, c-format
msgid "Could not release screen %d on display \"%s\"\n"
msgstr "\"%2$s\" X oturumundaki ekran %1$d serberst bırakılamadı\"\n"
#: ../src/core/session.c:837 ../src/core/session.c:844
#: ../src/core/session.c:843 ../src/core/session.c:850
#, c-format
msgid "Could not create directory '%s': %s\n"
msgstr "'%s' dizini oluşturulamadı: %s\n"
#: ../src/core/session.c:854
#: ../src/core/session.c:860
#, c-format
msgid "Could not open session file '%s' for writing: %s\n"
msgstr "'%s' oturum dosyası yazma için açılamadı: %s\n"
#: ../src/core/session.c:995
#: ../src/core/session.c:1001
#, c-format
msgid "Error writing session file '%s': %s\n"
msgstr "'%s' oturum dosyasına yazmada hata: %s\n"
#: ../src/core/session.c:1000
#: ../src/core/session.c:1006
#, c-format
msgid "Error closing session file '%s': %s\n"
msgstr "'%s' oturum dosyasını kapamada hata: %s\n"
#: ../src/core/session.c:1130
#: ../src/core/session.c:1136
#, c-format
msgid "Failed to parse saved session file: %s\n"
msgstr "Kaydedilmiş oturum dosyası ayrıştırırken hata: %s\n"
#: ../src/core/session.c:1179
#: ../src/core/session.c:1185
#, c-format
msgid "<mutter_session> attribute seen but we already have the session ID"
msgstr ""
"Geçerli bir oturum kimliği bulunmasına karşın <metacity_session> "
"özniteliğiyle karşılaşıldı"
#: ../src/core/session.c:1192 ../src/core/session.c:1267
#: ../src/core/session.c:1299 ../src/core/session.c:1371
#: ../src/core/session.c:1431
#: ../src/core/session.c:1198 ../src/core/session.c:1273
#: ../src/core/session.c:1305 ../src/core/session.c:1377
#: ../src/core/session.c:1437
#, c-format
msgid "Unknown attribute %s on <%s> element"
msgstr "Bilinmeyen öznitelik %2$s üzerinde <%1$s> öğesi"
#: ../src/core/session.c:1209
#: ../src/core/session.c:1215
#, c-format
msgid "nested <window> tag"
msgstr "iç içe <window> imi"
#: ../src/core/session.c:1451
#: ../src/core/session.c:1457
#, c-format
msgid "Unknown element %s"
msgstr "Bilinmeyen öğe %s"
#: ../src/core/session.c:1803
#: ../src/core/session.c:1809
msgid ""
"These windows do not support &quot;save current setup&quot; and will have to "
"be restarted manually next time you log in."
@ -693,13 +710,13 @@ msgid "Window manager error: "
msgstr "Pencere yöneticisi hatası: "
#. Translators: This is the title used on dialog boxes
#: ../src/core/util.c:615 ../src/mutter.desktop.in.h:1
#: ../src/core/util.c:632 ../src/mutter.desktop.in.h:1
#: ../src/mutter-wm.desktop.in.h:1
msgid "Mutter"
msgstr "Mutter"
#. first time through
#: ../src/core/window.c:6850
#: ../src/core/window.c:6886
#, c-format
msgid ""
"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER "
@ -715,7 +732,7 @@ msgstr ""
#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain
#. * about these apps but make them work.
#.
#: ../src/core/window.c:7513
#: ../src/core/window.c:7549
#, c-format
msgid ""
"Window %s sets an MWM hint indicating it isn't resizable, but sets min size "
@ -735,7 +752,7 @@ msgstr "Uygulama geçersiz _NET_WM_PID %lu atadı\n"
msgid "%s (on %s)"
msgstr "%s (%s üzerinde)"
#: ../src/core/window-props.c:1482
#: ../src/core/window-props.c:1484
#, c-format
msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n"
msgstr "Geçersiz WM_TRANSIENT_FOR pencere 0x%lx belirtilen %s.\n"
@ -803,6 +820,10 @@ msgid ""
"\"Windows key\" on PC hardware. It's expected that this binding either the "
"default or set to the empty string."
msgstr ""
"Bu anahtar, pencere genel görünümü ve uygulama başlatma sisteminin bir "
"birleşimi olan \"bindirme\" işlemini başlatır. Öntanımlı olarak PC "
"donanımındaki \"windows tuşu\" olması tasarlanmıştır. Bağlayıcı varsayılan "
"olarak veya boş dize olarak ayarlanması beklenir."
#: ../src/mutter.schemas.in.h:7
msgid ""
@ -823,47 +844,47 @@ msgstr "Sadece birincil monitördeki çalışma alanları"
msgid "Usage: %s\n"
msgstr "Kullanım: %s\n"
#: ../src/ui/frames.c:1099
#: ../src/ui/frames.c:1280
msgid "Close Window"
msgstr "Pencereyi Kapat"
#: ../src/ui/frames.c:1102
#: ../src/ui/frames.c:1283
msgid "Window Menu"
msgstr "Pencere Menüsü"
#: ../src/ui/frames.c:1105
#: ../src/ui/frames.c:1286
msgid "Minimize Window"
msgstr "Pencereyi Küçült"
#: ../src/ui/frames.c:1108
#: ../src/ui/frames.c:1289
msgid "Maximize Window"
msgstr "Pencereyi Büyült"
#: ../src/ui/frames.c:1111
#: ../src/ui/frames.c:1292
msgid "Restore Window"
msgstr "Pencere Geri Getir"
#: ../src/ui/frames.c:1114
#: ../src/ui/frames.c:1295
msgid "Roll Up Window"
msgstr "Pencereyi Yukarı Sar"
#: ../src/ui/frames.c:1117
#: ../src/ui/frames.c:1298
msgid "Unroll Window"
msgstr "Pencereyi Geri Sar"
#: ../src/ui/frames.c:1120
#: ../src/ui/frames.c:1301
msgid "Keep Window On Top"
msgstr "Pencereyi Üstte Tut"
#: ../src/ui/frames.c:1123
#: ../src/ui/frames.c:1304
msgid "Remove Window From Top"
msgstr "Pencereyi Üstten Kaldır"
#: ../src/ui/frames.c:1126
#: ../src/ui/frames.c:1307
msgid "Always On Visible Workspace"
msgstr "Her Zaman Görünen Çalışma Alanında"
#: ../src/ui/frames.c:1129
#: ../src/ui/frames.c:1310
msgid "Put Window On Only One Workspace"
msgstr "Pencereyi Sadece Bir Çalışma Alanına Yerleştir"
@ -1180,12 +1201,17 @@ msgstr "Gölgeli rengin gölge katsayısı olan \"%s\", negatif"
msgid "Could not parse color \"%s\""
msgstr "\"%s\" rengi ayrıştırılamadı"
#: ../src/ui/theme.c:1646
#: ../src/ui/theme.c:1481
#, c-format
msgid "Failed to retrieve color %s[%s] from GTK+ theme.\n"
msgstr "GTK+ temasından %s[%s] renginin alınması başarısız oldu.\n"
#: ../src/ui/theme.c:1713
#, c-format
msgid "Coordinate expression contains character '%s' which is not allowed"
msgstr "Kordinat ifadesi izin verilmeyen '%s' karakterini içeriyor"
#: ../src/ui/theme.c:1673
#: ../src/ui/theme.c:1740
#, c-format
msgid ""
"Coordinate expression contains floating point number '%s' which could not be "
@ -1193,12 +1219,12 @@ msgid ""
msgstr ""
"Kordinat ifadesi '%s' gerçel sayısını içeriyor ve bu sayı ayrıştırılamıyor"
#: ../src/ui/theme.c:1687
#: ../src/ui/theme.c:1754
#, c-format
msgid "Coordinate expression contains integer '%s' which could not be parsed"
msgstr "Kordinat ifadesi ayrıştırılamayan '%s' tamsayısını içeriyor"
#: ../src/ui/theme.c:1809
#: ../src/ui/theme.c:1876
#, c-format
msgid ""
"Coordinate expression contained unknown operator at the start of this text: "
@ -1206,17 +1232,17 @@ msgid ""
msgstr ""
"Kordinat ifadesi bu metnin başında bilinmeyen bir işleç içeriyor: \"%s\""
#: ../src/ui/theme.c:1866
#: ../src/ui/theme.c:1933
#, c-format
msgid "Coordinate expression was empty or not understood"
msgstr "Kordinat ifadesi boş ya da anlaşılamadı"
#: ../src/ui/theme.c:1977 ../src/ui/theme.c:1987 ../src/ui/theme.c:2021
#: ../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 "Kordinat ifadesi sıfıra bölümle sonuçlanıyor"
#: ../src/ui/theme.c:2029
#: ../src/ui/theme.c:2096
#, c-format
msgid ""
"Coordinate expression tries to use mod operator on a floating-point number"
@ -1224,23 +1250,23 @@ msgstr ""
"Kordinat ifadesi bir gerçel sayı üzerinde mod (kalan bulma) işlecini "
"kullanmaya çalıştı"
#: ../src/ui/theme.c:2085
#: ../src/ui/theme.c:2152
#, c-format
msgid ""
"Coordinate expression has an operator \"%s\" where an operand was expected"
msgstr "Kordinat ifadesi işleneni beklenen \"%s\", işlecini içeriyor"
#: ../src/ui/theme.c:2094
#: ../src/ui/theme.c:2161
#, c-format
msgid "Coordinate expression had an operand where an operator was expected"
msgstr "Kordinat ifadesi işleci beklenen bir işlenen içeriyor"
#: ../src/ui/theme.c:2102
#: ../src/ui/theme.c:2169
#, c-format
msgid "Coordinate expression ended with an operator instead of an operand"
msgstr "Kordinat ifadesi bir işlenen yerine işleçle bitiyor"
#: ../src/ui/theme.c:2112
#: ../src/ui/theme.c:2179
#, c-format
msgid ""
"Coordinate expression has operator \"%c\" following operator \"%c\" with no "
@ -1249,38 +1275,38 @@ msgstr ""
"Kordinat ifadesi birbirlerinin izleyen ve aralarında işlenen olmayan \"%2$c"
"\" ve \"%1$c\" işleçlerini içeriyor"
#: ../src/ui/theme.c:2263 ../src/ui/theme.c:2308
#: ../src/ui/theme.c:2330 ../src/ui/theme.c:2375
#, c-format
msgid "Coordinate expression had unknown variable or constant \"%s\""
msgstr ""
"Kordinat ifadesi bilinmeyen bir değişken ya da sabit olan \"%s\" içeriyor"
#: ../src/ui/theme.c:2362
#: ../src/ui/theme.c:2429
#, c-format
msgid "Coordinate expression parser overflowed its buffer."
msgstr "Kordinat belirtim ayrıştırıcısı tamponundan taştı."
#: ../src/ui/theme.c:2391
#: ../src/ui/theme.c:2458
#, c-format
msgid "Coordinate expression had a close parenthesis with no open parenthesis"
msgstr "Kordinat ifadesi sol parantezi olmayan bir sağ parantez içeriyor"
#: ../src/ui/theme.c:2455
#: ../src/ui/theme.c:2522
#, c-format
msgid "Coordinate expression had an open parenthesis with no close parenthesis"
msgstr "Kordinat ifadesi sağ parantezi olmayan bir sol parantez içeriyor"
#: ../src/ui/theme.c:2466
#: ../src/ui/theme.c:2533
#, c-format
msgid "Coordinate expression doesn't seem to have any operators or operands"
msgstr "Kordinat ifadesi göründüğü kadarıyla ne işleç ne de işlenen içeriyor"
#: ../src/ui/theme.c:2676 ../src/ui/theme.c:2696 ../src/ui/theme.c:2716
#: ../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 "Tema bir hata ile sonuçlanan ifadeye sahip: %s\n"
#: ../src/ui/theme.c:4410
#: ../src/ui/theme.c:4482
#, c-format
msgid ""
"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be "
@ -1289,25 +1315,25 @@ msgstr ""
"Bu çerçeve biçeminde <button function=\"%s\" state=\"%s\" draw_ops=\"her "
"neyse\"/> belirtilmek zorunda"
#: ../src/ui/theme.c:4940 ../src/ui/theme.c:4965
#: ../src/ui/theme.c:5012 ../src/ui/theme.c:5037
#, c-format
msgid ""
"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>"
msgstr ""
"Eksik <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"her neyse\"/>"
#: ../src/ui/theme.c:5013
#: ../src/ui/theme.c:5085
#, c-format
msgid "Failed to load theme \"%s\": %s\n"
msgstr "\"%s\" teması yüklenemedi: %s\n"
#: ../src/ui/theme.c:5149 ../src/ui/theme.c:5156 ../src/ui/theme.c:5163
#: ../src/ui/theme.c:5170 ../src/ui/theme.c:5177
#: ../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 "\"%2$s\" temasında hiç <%1$s> atanmamış"
#: ../src/ui/theme.c:5185
#: ../src/ui/theme.c:5257
#, c-format
msgid ""
"No frame style set for window type \"%s\" in theme \"%s\", add a <window "
@ -1316,14 +1342,14 @@ msgstr ""
"\"%2$s\" temasında \"%1$s\" pencere türüne çerçeve biçemi atanmamış, bir "
"<window type=\"%3$s\" style_set=\"her neyse\"/> öğesi ekleyin"
#: ../src/ui/theme.c:5635 ../src/ui/theme.c:5697 ../src/ui/theme.c:5760
#: ../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"
msgstr ""
"Kullanıcı tanımlı sabitler büyük harfle başlamalıdır; \"%s\" buna uymuyor"
#: ../src/ui/theme.c:5643 ../src/ui/theme.c:5705 ../src/ui/theme.c:5768
#: ../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\" sabit değeri zaten tanımlanmış"

562
po/ug.po

File diff suppressed because it is too large Load Diff

View File

@ -6,8 +6,8 @@ msgid ""
msgstr ""
"Project-Id-Version: metacity\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-03-23 15:51+0200\n"
"PO-Revision-Date: 2011-03-23 15:52+0300\n"
"POT-Creation-Date: 2011-05-03 22:43+0300\n"
"PO-Revision-Date: 2011-05-03 22:46+0300\n"
"Last-Translator: Korostil Daniel <ted.korostiled@gmail.com>\n"
"Language-Team: translation@linux.org.ua\n"
"Language: uk\n"
@ -337,24 +337,27 @@ msgstr "Подія гудка"
msgid "Unknown window information request: %d"
msgstr "Запит інформації невідомого вікна: %d"
#. Translators: %s is a window title
#: ../src/core/delete.c:94
#: ../src/core/delete.c:111
#, c-format
msgid "<tt>%s</tt> is not responding."
msgstr "<tt>%s</tt> не відповідає."
#: ../src/core/delete.c:99
#: ../src/core/delete.c:114
msgid "Application is not responding."
msgstr "Програма не відповідає."
#: ../src/core/delete.c:119
msgid ""
"You may choose to wait a short while for it to continue or force the "
"application to quit entirely."
msgstr ""
"Можете трошки зачекати відновлення активності або примусово закрити програму."
#: ../src/core/delete.c:108
#: ../src/core/delete.c:126
msgid "_Wait"
msgstr "_Зачекати"
#: ../src/core/delete.c:108
#: ../src/core/delete.c:126
msgid "_Force Quit"
msgstr "_Завершити примусово"
@ -423,12 +426,12 @@ msgstr "Розпочати сеанс зі збереженого файла"
msgid "Make X calls synchronous"
msgstr "Зробити виклики X синхронними"
#: ../src/core/main.c:506
#: ../src/core/main.c:504
#, c-format
msgid "Failed to scan themes directory: %s\n"
msgstr "Помилка зчитування каталогу тем: %s\n"
#: ../src/core/main.c:522
#: ../src/core/main.c:520
#, c-format
msgid ""
"Could not find a theme! Be sure %s exists and contains the usual themes.\n"
@ -553,12 +556,12 @@ msgstr "Помилка налаштування стану схованих ві
msgid "Error setting no tab popup status: %s\n"
msgstr "Помилка налаштування стану контекстних вкладок: %s\n"
#: ../src/core/screen.c:623
#: ../src/core/screen.c:624
#, c-format
msgid "Screen %d on display '%s' is invalid\n"
msgstr "Екран %d на дисплеї «%s» не правильний\n"
#: ../src/core/screen.c:639
#: ../src/core/screen.c:640
#, c-format
msgid ""
"Screen %d on display \"%s\" already has a window manager; try using the --"
@ -567,7 +570,7 @@ msgstr ""
"Екран %d на дисплеї «%s» вже має менеджера вікон; спробуйте вказати параметр "
"--replace, щоб замінити поточний менеджер вікон.\n"
#: ../src/core/screen.c:666
#: ../src/core/screen.c:667
#, c-format
msgid ""
"Could not acquire window manager selection on screen %d display \"%s\"\n"
@ -575,64 +578,64 @@ msgstr ""
"Не вдалось одержати функцію виділення менеджеру вікон на екрані %d дисплею "
"«%s»\n"
#: ../src/core/screen.c:721
#: ../src/core/screen.c:722
#, c-format
msgid "Screen %d on display \"%s\" already has a window manager\n"
msgstr "Екран %d на дисплеї «%s» вже має менеджера вікон\n"
#: ../src/core/screen.c:906
#: ../src/core/screen.c:907
#, c-format
msgid "Could not release screen %d on display \"%s\"\n"
msgstr "Не вдалось відпустити екран %d на дисплеї «%s»\n"
#: ../src/core/session.c:837 ../src/core/session.c:844
#: ../src/core/session.c:843 ../src/core/session.c:850
#, c-format
msgid "Could not create directory '%s': %s\n"
msgstr "Не вдалось створити каталог «%s»: %s\n"
#: ../src/core/session.c:854
#: ../src/core/session.c:860
#, c-format
msgid "Could not open session file '%s' for writing: %s\n"
msgstr "Не вдалось відкрити для запису файл сеансу «%s»: %s\n"
#: ../src/core/session.c:995
#: ../src/core/session.c:1001
#, c-format
msgid "Error writing session file '%s': %s\n"
msgstr "Помилка запису файла сеансу \"%s\": %s\n"
#: ../src/core/session.c:1000
#: ../src/core/session.c:1006
#, c-format
msgid "Error closing session file '%s': %s\n"
msgstr "Помилка закриття файла сеансу «%s»: %s\n"
#: ../src/core/session.c:1130
#: ../src/core/session.c:1136
#, c-format
msgid "Failed to parse saved session file: %s\n"
msgstr "Збій аналізування збереженого файла сеансу: %s\n"
#: ../src/core/session.c:1179
#: ../src/core/session.c:1185
#, c-format
msgid "<mutter_session> attribute seen but we already have the session ID"
msgstr "Прочитано атрибут <mutter_session>, але вже є ідентифікатор сеансу"
#: ../src/core/session.c:1192 ../src/core/session.c:1267
#: ../src/core/session.c:1299 ../src/core/session.c:1371
#: ../src/core/session.c:1431
#: ../src/core/session.c:1198 ../src/core/session.c:1273
#: ../src/core/session.c:1305 ../src/core/session.c:1377
#: ../src/core/session.c:1437
#, c-format
msgid "Unknown attribute %s on <%s> element"
msgstr "Невідомий атрибут %s у елементі <%s>"
#: ../src/core/session.c:1209
#: ../src/core/session.c:1215
#, c-format
msgid "nested <window> tag"
msgstr "вкладена мітка <window>"
#: ../src/core/session.c:1451
#: ../src/core/session.c:1457
#, c-format
msgid "Unknown element %s"
msgstr "Невідомий елемент %s"
#: ../src/core/session.c:1803
#: ../src/core/session.c:1809
msgid ""
"These windows do not support &quot;save current setup&quot; and will have to "
"be restarted manually next time you log in."
@ -677,13 +680,13 @@ msgid "Window manager error: "
msgstr "Помилка віконного менеджера:"
#. Translators: This is the title used on dialog boxes
#: ../src/core/util.c:615 ../src/mutter.desktop.in.h:1
#: ../src/core/util.c:632 ../src/mutter.desktop.in.h:1
#: ../src/mutter-wm.desktop.in.h:1
msgid "Mutter"
msgstr "Mutter"
#. first time through
#: ../src/core/window.c:6795
#: ../src/core/window.c:6860
#, c-format
msgid ""
"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER "
@ -699,7 +702,7 @@ msgstr ""
#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain
#. * about these apps but make them work.
#.
#: ../src/core/window.c:7458
#: ../src/core/window.c:7523
#, c-format
msgid ""
"Window %s sets an MWM hint indicating it isn't resizable, but sets min size "
@ -719,7 +722,7 @@ msgstr "Програма встановила неправильне значе
msgid "%s (on %s)"
msgstr "%s (на %s)"
#: ../src/core/window-props.c:1479
#: ../src/core/window-props.c:1482
#, c-format
msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n"
msgstr "Неправильний параметр WM_TRANSIENT_FOR вікна 0x%lx вказано для %s.\n"
@ -810,47 +813,47 @@ msgstr "Робочий простір лише на первинному"
msgid "Usage: %s\n"
msgstr "Використання: %s\n"
#: ../src/ui/frames.c:1099
#: ../src/ui/frames.c:1177
msgid "Close Window"
msgstr "Закрити вікно"
#: ../src/ui/frames.c:1102
#: ../src/ui/frames.c:1180
msgid "Window Menu"
msgstr "Меню вікна"
#: ../src/ui/frames.c:1105
#: ../src/ui/frames.c:1183
msgid "Minimize Window"
msgstr "Згорнути вікно"
#: ../src/ui/frames.c:1108
#: ../src/ui/frames.c:1186
msgid "Maximize Window"
msgstr "Розгорнути вікно"
#: ../src/ui/frames.c:1111
#: ../src/ui/frames.c:1189
msgid "Restore Window"
msgstr "Відновити вікно"
#: ../src/ui/frames.c:1114
#: ../src/ui/frames.c:1192
msgid "Roll Up Window"
msgstr "Скотити вікно"
#: ../src/ui/frames.c:1117
#: ../src/ui/frames.c:1195
msgid "Unroll Window"
msgstr "Розкотити вікно"
#: ../src/ui/frames.c:1120
#: ../src/ui/frames.c:1198
msgid "Keep Window On Top"
msgstr "Тримати вікно нагорі"
#: ../src/ui/frames.c:1123
#: ../src/ui/frames.c:1201
msgid "Remove Window From Top"
msgstr "Прибрати вікно з гори"
#: ../src/ui/frames.c:1126
#: ../src/ui/frames.c:1204
msgid "Always On Visible Workspace"
msgstr "Завжди на видимому робочому просторі"
#: ../src/ui/frames.c:1129
#: ../src/ui/frames.c:1207
msgid "Put Window On Only One Workspace"
msgstr "Розміщувати вікно лише на одному робочому просторі"

View File

@ -709,9 +709,8 @@ msgid ""
"Window %s sets an MWM hint indicating it isn't resizable, but sets min size %"
"d x %d and max size %d x %d; this doesn't make much sense.\n"
msgstr ""
"Cửa sổ %s gọi ý MWM nói rằng nó không thể bị thay đổi kích thước, nhưng đặt "
"kích thước tối thiểu %d x %d và tối đa %d x %d; điều này có vẻ cũng hơi hợp "
"lý.\n"
"Cửa sổ %s đặt gợi ý MWM rằng nó không thể bị thay đổi kích thước, nhưng đặt "
"kích thước tối thiểu %d x %d và tối đa %d x %d; không hợp lý lắm.\n"
#: ../src/core/window-props.c:309
#, c-format

View File

@ -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 \
@ -154,6 +170,14 @@ libmutter_la_SOURCES = \
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)
@ -164,6 +188,8 @@ 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 \
@ -204,7 +230,11 @@ mutter_LDADD = $(MUTTER_LIBS) libmutter.la
if HAVE_INTROSPECTION
include $(INTROSPECTION_MAKEFILE)
api_version = $(MUTTER_MAJOR_VERSION).$(MUTTER_MINOR_VERSION)
# Since we don't make any guarantees about stability and we don't support
# parallel install, there's no real reason to change directories, filenames,
# etc. as we change the Mutter tarball version.
#api_version = $(MUTTER_MAJOR_VERSION).$(MUTTER_MINOR_VERSION)
api_version = 3.0
# These files are in package-private directories, even though they may be used
# by plugins. If you're writing a plugin, use g-ir-compiler --add-include-path
@ -332,7 +362,7 @@ mutter-enum-types.h: stamp-mutter-enum-types.h Makefile
stamp-mutter-enum-types.h: $(libmutterinclude_base_headers) mutter-enum-types.h.in
$(AM_V_GEN) ( cd $(srcdir) && \
$(GLIB_MKENUMS) \
--template $(srcdir)/mutter-enum-types.h.in \
--template mutter-enum-types.h.in \
$(libmutterinclude_base_headers) ) >> xgen-teth && \
(cmp -s xgen-teth mutter-enum-types.h || cp xgen-teth mutter-enum-types.h) && \
rm -f xgen-teth && \
@ -341,7 +371,7 @@ stamp-mutter-enum-types.h: $(libmutterinclude_base_headers) mutter-enum-types.h.
mutter-enum-types.c: stamp-mutter-enum-types.h mutter-enum-types.c.in
$(AM_V_GEN) ( cd $(srcdir) && \
$(GLIB_MKENUMS) \
--template $(srcdir)/mutter-enum-types.c.in \
--template mutter-enum-types.c.in \
$(libmutterinclude_base_headers) ) >> xgen-tetc && \
cp xgen-tetc mutter-enum-types.c && \
rm -f xgen-tetc

View File

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

View File

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

View File

@ -11,12 +11,15 @@
#include <meta/compositor-mutter.h>
#include "xprops.h"
#include <meta/prefs.h>
#include <meta/main.h>
#include <meta/meta-shadow-factory.h>
#include "meta-window-actor-private.h"
#include "meta-window-group.h"
#include "meta-background-actor.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>
@ -177,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);
@ -191,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;
}
@ -363,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;
@ -390,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;
@ -413,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;
}
@ -426,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;
}
@ -472,22 +478,44 @@ 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;
/* Check if the screen is already managed */
if (meta_screen_get_compositor_data (screen))
return;
meta_error_trap_push_with_return (display);
XCompositeRedirectSubwindows (xdisplay, xroot, CompositeRedirectManual);
XSync (xdisplay, FALSE);
if (meta_get_replace_current_wm ())
max_retries = 5;
else
max_retries = 1;
if (meta_error_trap_pop_with_return (display))
n_retries = 0;
/* Some compositors (like old versions of Mutter) might not properly unredirect
* subwindows before destroying the WM selection window; so we wait a while
* for such a compositor to exit before giving up.
*/
while (TRUE)
{
g_warning ("Another compositing manager is running on screen %i",
screen_number);
return;
meta_error_trap_push_with_return (display);
XCompositeRedirectSubwindows (xdisplay, xroot, CompositeRedirectManual);
XSync (xdisplay, FALSE);
if (!meta_error_trap_pop_with_return (display))
break;
if (n_retries == max_retries)
{
/* This probably means that a non-WM compositor like xcompmgr is running;
* we have no way to get it to exit */
meta_fatal (_("Another compositing manager is already running on screen %i on display \"%s\"."),
screen_number, display->name);
}
n_retries++;
g_usleep (G_USEC_PER_SEC);
}
info = g_new0 (MetaCompScreen, 1);
@ -524,12 +552,7 @@ 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 (screen);
@ -587,6 +610,14 @@ void
meta_compositor_unmanage_screen (MetaCompositor *compositor,
MetaScreen *screen)
{
MetaDisplay *display = meta_screen_get_display (screen);
Display *xdisplay = meta_display_get_xdisplay (display);
Window xroot = meta_screen_get_xroot (screen);
/* This is the most important part of cleanup - we have to do this
* before giving up the window manager selection or the next
* window manager won't be able to redirect subwindows */
XCompositeUnredirectSubwindows (xdisplay, xroot, CompositeRedirectManual);
}
void
@ -626,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:
@ -651,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);

View File

@ -113,8 +113,13 @@ set_texture_to_stage_color (MetaBackgroundActor *self)
CoglHandle texture;
clutter_stage_get_color (CLUTTER_STAGE (stage), &color);
/* Slicing will prevent COGL from using hardware texturing for
* the tiled 1x1 pixmap, and will cause it to draw the window
* background in millions of separate 1x1 rectangles */
texture = meta_create_color_texture_4ub (color.red, color.green,
color.blue, 0xff);
color.blue, 0xff,
COGL_TEXTURE_NO_SLICING);
set_texture (self, texture);
cogl_handle_unref (texture);
}

View File

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

View File

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

View File

@ -411,8 +411,6 @@ meta_window_actor_constructed (GObject *object)
if (format && format->type == PictTypeDirect && format->direct.alphaMask)
priv->argb32 = TRUE;
meta_window_actor_update_opacity (self);
if (!priv->actor)
{
priv->actor = meta_shaped_texture_new ();
@ -442,7 +440,7 @@ meta_window_actor_constructed (GObject *object)
clutter_actor_raise_top (priv->actor);
}
meta_window_actor_update_opacity (self);
meta_window_actor_update_shape (self, priv->shaped);
}
@ -704,6 +702,26 @@ meta_window_actor_get_shadow_bounds (MetaWindowActor *self,
}
#endif
/* If we have an ARGB32 window that we decorate with a frame, it's
* probably something like a translucent terminal - something where
* the alpha channel represents transparency rather than a shape. We
* don't want to show the shadow through the translucent areas since
* the shadow is wrong for translucent windows (it should be
* translucent itself and colored), and not only that, will /look/
* horribly wrong - a misplaced big black blob. As a hack, what we
* want to do is just draw the shadow as normal outside the frame, and
* inside the frame draw no shadow. This is also not even close to
* the right result, but looks OK. We also apply this approach to
* windows set to be partially translucent with _NET_WM_WINDOW_OPACITY.
*/
static gboolean
clip_shadow_under_window (MetaWindowActor *self)
{
MetaWindowActorPrivate *priv = self->priv;
return (priv->argb32 || priv->opacity != 0xff) && priv->window->frame;
}
static void
meta_window_actor_paint (ClutterActor *actor)
{
@ -716,17 +734,36 @@ meta_window_actor_paint (ClutterActor *actor)
{
MetaShadowParams params;
cairo_rectangle_int_t shape_bounds;
cairo_region_t *clip = priv->shadow_clip;
meta_window_actor_get_shape_bounds (self, &shape_bounds);
meta_window_actor_get_shadow_params (self, appears_focused, &params);
/* The frame bounds are already subtracted from priv->shadow_clip
* if that exists.
*/
if (!clip && clip_shadow_under_window (self))
{
cairo_region_t *frame_bounds = meta_window_get_frame_bounds (priv->window);
cairo_rectangle_int_t bounds;
meta_window_actor_get_shadow_bounds (self, appears_focused, &bounds);
clip = cairo_region_create_rectangle (&bounds);
cairo_region_subtract (clip, frame_bounds);
}
meta_shadow_paint (shadow,
params.x_offset + shape_bounds.x,
params.y_offset + shape_bounds.y,
shape_bounds.width,
shape_bounds.height,
(clutter_actor_get_paint_opacity (actor) * params.opacity) / 255,
priv->shadow_clip);
(clutter_actor_get_paint_opacity (actor) * params.opacity * priv->opacity) / (255 * 255),
clip,
clip_shadow_under_window (self)); /* clip_strictly - not just as an optimization */
if (clip && clip != priv->shadow_clip)
cairo_region_destroy (clip);
}
CLUTTER_ACTOR_CLASS (meta_window_actor_parent_class)->paint (actor);
@ -1646,13 +1683,22 @@ meta_window_actor_update_bounding_region (MetaWindowActor *self,
priv->bounding_region = cairo_region_create_rectangle (&bounding_rectangle);
/* When we're shaped, we use the shape region to generate the shadow; the shape
* region only changes when we get ShapeNotify event; but for unshaped windows
* we generate the shadow from the bounding region, so we need to recompute
* the shadow when the size changes.
*/
if (!priv->shaped)
meta_window_actor_invalidate_shadow (self);
if (priv->shaped)
{
/* If we're shaped, the implicit shape region clipping we need to do needs
* to be updated.
*/
meta_window_actor_update_shape (self, TRUE);
}
else
{
/* When we're shaped, we use the shape region to generate the shadow; the shape
* region only changes when we get ShapeNotify event; but for unshaped windows
* we generate the shadow from the bounding region, so we need to recompute
* the shadow when the size changes.
*/
meta_window_actor_invalidate_shadow (self);
}
g_signal_emit (self, signals[SIZE_CHANGED], 0);
}
@ -1673,6 +1719,20 @@ meta_window_actor_update_shape_region (MetaWindowActor *self,
cairo_rectangle_int_t rect = { rects[i].x, rects[i].y, rects[i].width, rects[i].height };
cairo_region_union_rectangle (priv->shape_region, &rect);
}
/* Our "shape_region" is called the "bounding region" in the X Shape
* Extension Documentation.
*
* Our "bounding_region" is called the "bounding rectangle", which defines
* the shape of the window as if it the window was unshaped.
*
* The X Shape extension requires that the "bounding region" can never
* extend outside the "bounding rectangle", and says it must be implicitly
* clipped before rendering. The region we get back hasn't been clipped.
* We explicitly clip the region here.
*/
if (priv->bounding_region != NULL)
cairo_region_intersect (priv->shape_region, priv->bounding_region);
}
/**
@ -1690,7 +1750,7 @@ meta_window_actor_get_obscured_region (MetaWindowActor *self)
{
MetaWindowActorPrivate *priv = self->priv;
if (!priv->argb32 && priv->back_pixmap)
if (!priv->argb32 && priv->opacity == 0xff && priv->back_pixmap)
{
if (priv->shaped)
return priv->shape_region;
@ -1789,6 +1849,12 @@ meta_window_actor_set_visible_region_beneath (MetaWindowActor *self,
{
meta_window_actor_clear_shadow_clip (self);
priv->shadow_clip = cairo_region_copy (beneath_region);
if (clip_shadow_under_window (self))
{
cairo_region_t *frame_bounds = meta_window_get_frame_bounds (priv->window);
cairo_region_subtract (priv->shadow_clip, frame_bounds);
}
}
}
@ -2147,5 +2213,5 @@ meta_window_actor_update_opacity (MetaWindowActor *self)
opacity = 255;
self->priv->opacity = opacity;
clutter_actor_set_opacity (CLUTTER_ACTOR (self), opacity);
clutter_actor_set_opacity (self->priv->actor, opacity);
}

View File

@ -248,7 +248,6 @@ expand_region_inverse (cairo_region_t *region,
MetaRegionBuilder builder;
MetaRegionIterator iter;
cairo_rectangle_int_t extents;
cairo_region_t *chunk;
int last_x;
@ -268,16 +267,11 @@ expand_region_inverse (cairo_region_t *region,
extents.x, extents.y + extents.height, extents.width, 1,
x_amount, y_amount, flip);
chunk = NULL;
last_x = extents.x;
for (meta_region_iterator_init (&iter, region);
!meta_region_iterator_at_end (&iter);
meta_region_iterator_next (&iter))
{
if (chunk == NULL)
chunk = cairo_region_create ();
if (iter.rectangle.x > last_x)
add_expanded_rect (&builder,
last_x, iter.rectangle.y,

View File

@ -76,6 +76,8 @@ compute_above_tab_keycode (Display *xdisplay)
keyboard = XkbGetKeyboard (xdisplay,
XkbGBN_ClientSymbolsMask | XkbGBN_KeyNamesMask | XkbGBN_GeometryMask,
XkbUseCoreKbd);
if (!keyboard)
return best_keycode;
geometry = keyboard->geom;

View File

@ -230,6 +230,35 @@ 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;
}
/**
* Flashes the frame of the focussed window. If there is no focussed window,
* flashes the screen.
@ -241,15 +270,11 @@ 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);
@ -310,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)
{

View File

@ -754,7 +754,7 @@ constrain_modal_dialog (MetaWindow *window,
if (!meta_prefs_get_attach_modal_dialogs ())
return TRUE;
if (window->type != META_WINDOW_MODAL_DIALOG || !parent || parent == window)
if (window->type != META_WINDOW_MODAL_DIALOG || !parent)
return TRUE;
x = parent->rect.x + (parent->rect.width / 2 - info->current.width / 2);
@ -885,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;
@ -893,10 +894,12 @@ 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);
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
@ -1362,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

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.
*
@ -107,9 +112,6 @@ meta_core_get (Display *xdisplay,
case META_CORE_GET_CLIENT_HEIGHT:
*((gint*)answer) = window->rect.height;
break;
case META_CORE_IS_TITLEBAR_ONSCREEN:
*((gboolean*)answer) = meta_window_titlebar_is_onscreen (window);
break;
case META_CORE_GET_CLIENT_XWINDOW:
*((Window*)answer) = window->xwindow;
break;
@ -146,6 +148,9 @@ meta_core_get (Display *xdisplay,
case META_CORE_GET_FRAME_HEIGHT:
*((gint*)answer) = window->frame->rect.height;
break;
case META_CORE_GET_THEME_VARIANT:
*((char**)answer) = window->gtk_theme_variant;
break;
case META_CORE_GET_SCREEN_WIDTH:
*((gint*)answer) = window->screen->rect.width;
break;
@ -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,30 +271,36 @@ 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);
}
void
meta_core_lower_beneath_focus_window (Display *xdisplay,
Window xwindow,
guint32 timestamp)
meta_core_lower_beneath_grab_window (Display *xdisplay,
Window xwindow,
int device_id,
guint32 timestamp)
{
XWindowChanges changes;
MetaDisplay *display;
MetaScreen *screen;
MetaWindow *focus_window;
MetaWindow *grab_window;
MetaDevice *pointer;
MetaGrabInfo *grab_info;
display = meta_display_for_x_display (xdisplay);
screen = meta_display_screen_for_xwindow (display, xwindow);
focus_window = meta_stack_get_top (screen->stack);
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 (focus_window == NULL)
if (grab_window == NULL)
return;
changes.stack_mode = Below;
changes.sibling = focus_window->frame ? focus_window->frame->xwindow
: focus_window->xwindow;
changes.sibling = grab_window->frame ? grab_window->frame->xwindow
: grab_window->xwindow;
meta_stack_tracker_record_lower_below (screen->stack_tracker,
xwindow,
@ -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
@ -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

@ -35,7 +35,6 @@ typedef enum
META_CORE_WINDOW_HAS_FRAME,
META_CORE_GET_CLIENT_WIDTH,
META_CORE_GET_CLIENT_HEIGHT,
META_CORE_IS_TITLEBAR_ONSCREEN,
META_CORE_GET_CLIENT_XWINDOW,
META_CORE_GET_FRAME_FLAGS,
META_CORE_GET_FRAME_TYPE,
@ -48,6 +47,7 @@ typedef enum
META_CORE_GET_FRAME_Y,
META_CORE_GET_FRAME_WIDTH,
META_CORE_GET_FRAME_HEIGHT,
META_CORE_GET_THEME_VARIANT,
META_CORE_GET_SCREEN_WIDTH,
META_CORE_GET_SCREEN_HEIGHT,
} MetaCoreGetType;
@ -110,15 +110,17 @@ 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,
Window frame_xwindow,
guint32 timestamp);
void meta_core_lower_beneath_focus_window (Display *xdisplay,
Window xwindow,
guint32 timestamp);
void meta_core_lower_beneath_grab_window (Display *xdisplay,
Window xwindow,
int device_id,
guint32 timestamp);
void meta_core_minimize (Display *xdisplay,
Window frame_xwindow);
@ -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

@ -88,19 +88,37 @@ delete_ping_timeout_func (MetaDisplay *display,
return;
}
window_title = g_locale_from_utf8 (window->title, -1, NULL, NULL, NULL);
/* This is to get a better string if the title isn't representable
* in the locale encoding; actual conversion to UTF-8 is done inside
* meta_show_dialog */
if (window->title && window->title[0])
{
tmp = g_locale_from_utf8 (window->title, -1, NULL, NULL, NULL);
if (tmp == NULL)
window_title = NULL;
else
window_title = window->title;
g_free (tmp);
}
else
{
window_title = NULL;
}
/* Translators: %s is a window title */
tmp = g_strdup_printf (_("<tt>%s</tt> is not responding."),
window_title);
if (window_title)
tmp = g_markup_printf_escaped (_("<tt>%s</tt> is not responding."),
window_title);
else
tmp = g_strdup (_("Application is not responding."));
window_content = g_strdup_printf (
"<big><b>%s</b></big>\n\n<i>%s</i>",
tmp,
_("You may choose to wait a short while for it to "
"continue or force the application to quit entirely."));
g_free (window_title);
dialog_pid =
meta_show_dialog ("--question",
window_content, NULL,

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 */

80
src/core/device-private.h Normal file
View File

@ -0,0 +1,80 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/**
* \file device.h Input device abstraction
*
* Input devices.
* This file contains the internal abstraction of input 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_PRIVATE_H
#define META_DEVICE_PRIVATE_H
#include <meta/device.h>
#include "display-private.h"
struct _MetaDevice
{
GObject parent_instance;
gpointer priv;
};
struct _MetaDeviceClass
{
GObjectClass parent_instance;
void (* allow_events) (MetaDevice *device,
int mode,
Time time);
gboolean (* grab) (MetaDevice *device,
Window xwindow,
guint evmask,
MetaCursor cursor,
gboolean owner_events,
gboolean sync,
Time time);
void (* ungrab) (MetaDevice *device,
Time time);
};
GType meta_device_get_type (void) G_GNUC_CONST;
void meta_device_allow_events (MetaDevice *device,
int mode,
Time time);
gboolean meta_device_grab (MetaDevice *device,
Window xwindow,
guint evmask,
MetaCursor cursor,
gboolean owner_events,
gboolean sync,
Time time);
void meta_device_ungrab (MetaDevice *device,
Time time);
void meta_device_pair_devices (MetaDevice *device,
MetaDevice *other_device);
#endif /* META_DEVICE_PRIVATE_H */

270
src/core/device.c Normal file
View File

@ -0,0 +1,270 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* Input 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-private.h"
G_DEFINE_ABSTRACT_TYPE (MetaDevice, meta_device, G_TYPE_OBJECT)
enum {
PROP_0,
PROP_DEVICE_ID,
PROP_DISPLAY,
PROP_PAIRED_DEVICE
};
typedef struct MetaDevicePrivate MetaDevicePrivate;
struct MetaDevicePrivate
{
MetaDisplay *display;
MetaDevice *paired_device;
gint device_id;
};
static void
meta_device_get_property (GObject *object,
guint param_id,
GValue *value,
GParamSpec *pspec)
{
switch (param_id)
{
case PROP_DEVICE_ID:
g_value_set_int (value,
meta_device_get_id (META_DEVICE (object)));
break;
case PROP_DISPLAY:
g_value_set_object (value,
meta_device_get_display (META_DEVICE (object)));
break;
case PROP_PAIRED_DEVICE:
g_value_set_object (value,
meta_device_get_paired_device (META_DEVICE (object)));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
}
}
static void
meta_device_set_property (GObject *object,
guint param_id,
const GValue *value,
GParamSpec *pspec)
{
MetaDevicePrivate *priv = META_DEVICE (object)->priv;
switch (param_id)
{
case PROP_DEVICE_ID:
priv->device_id = g_value_get_int (value);
break;
case PROP_DISPLAY:
priv->display = g_value_get_object (value);
break;
case PROP_PAIRED_DEVICE:
meta_device_pair_devices (META_DEVICE (object),
g_value_get_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
}
}
static void
meta_device_class_init (MetaDeviceClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->get_property = meta_device_get_property;
object_class->set_property = meta_device_set_property;
g_object_class_install_property (object_class,
PROP_DEVICE_ID,
g_param_spec_int ("device-id",
"Device ID",
"Device ID",
2, G_MAXINT, 2,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
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));
g_object_class_install_property (object_class,
PROP_PAIRED_DEVICE,
g_param_spec_object ("paired-device",
"Paired device",
"Paired device",
META_TYPE_DEVICE,
G_PARAM_READWRITE));
g_type_class_add_private (klass, sizeof (MetaDevicePrivate));
}
static void
meta_device_init (MetaDevice *device)
{
device->priv = G_TYPE_INSTANCE_GET_PRIVATE (device,
META_TYPE_DEVICE,
MetaDevicePrivate);
}
int
meta_device_get_id (MetaDevice *device)
{
MetaDevicePrivate *priv;
g_return_val_if_fail (META_IS_DEVICE (device), 0);
priv = device->priv;
return priv->device_id;
}
/**
* meta_device_get_display:
* @device: a #MetaDevice
*
* Returns the #MetaDisplay to which the device belongs
*
* Returns: (transfer none): the #MetaDisplay to which the device belongs
**/
MetaDisplay *
meta_device_get_display (MetaDevice *device)
{
MetaDevicePrivate *priv;
g_return_val_if_fail (META_IS_DEVICE (device), NULL);
priv = device->priv;
return priv->display;
}
void
meta_device_allow_events (MetaDevice *device,
int mode,
Time time)
{
MetaDeviceClass *klass;
g_return_if_fail (META_IS_DEVICE (device));
klass = META_DEVICE_GET_CLASS (device);
if (klass->allow_events)
(klass->allow_events) (device, mode, time);
}
gboolean
meta_device_grab (MetaDevice *device,
Window xwindow,
guint evmask,
MetaCursor cursor,
gboolean owner_events,
gboolean sync,
Time time)
{
MetaDeviceClass *klass;
g_return_val_if_fail (META_IS_DEVICE (device), FALSE);
g_return_val_if_fail (xwindow != None, FALSE);
klass = META_DEVICE_GET_CLASS (device);
if (!klass->grab)
return FALSE;
return (klass->grab) (device, xwindow, evmask, cursor,
owner_events, sync, time);
}
void
meta_device_ungrab (MetaDevice *device,
Time time)
{
MetaDeviceClass *klass;
g_return_if_fail (META_IS_DEVICE (device));
klass = META_DEVICE_GET_CLASS (device);
if (klass->ungrab)
(klass->ungrab) (device, time);
}
void
meta_device_pair_devices (MetaDevice *device,
MetaDevice *other_device)
{
MetaDevicePrivate *priv1, *priv2;
g_return_if_fail (META_IS_DEVICE (device));
g_return_if_fail (META_IS_DEVICE (other_device));
priv1 = device->priv;
priv2 = other_device->priv;
/* Consider safe multiple calls
* on already paired devices
*/
if (priv1->paired_device != NULL &&
priv2->paired_device != NULL &&
priv1->paired_device == other_device &&
priv2->paired_device == device)
return;
g_return_if_fail (priv1->paired_device == NULL);
g_return_if_fail (priv2->paired_device == NULL);
priv1->paired_device = g_object_ref (other_device);
priv2->paired_device = g_object_ref (device);
g_object_notify (G_OBJECT (device), "paired-device");
g_object_notify (G_OBJECT (other_device), "paired-device");
}
/**
* meta_device_get_paired_device:
* @device: a #MetaDevice
*
* Returns the paired device. Devices come in keyboard/pointer pairs.
*
* Returns: (transfer none): The paired device.
**/
MetaDevice *
meta_device_get_paired_device (MetaDevice *device)
{
MetaDevicePrivate *priv;
g_return_val_if_fail (META_IS_DEVICE (device), NULL);
priv = device->priv;
return priv->paired_device;
}

256
src/core/devices-core.c Normal file
View File

@ -0,0 +1,256 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* Core input devices 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 "screen-private.h"
#include "devices-core.h"
#include "device-map-private.h"
/* Common functions */
static void
meta_device_core_common_allow_events (MetaDevice *device,
int mode,
Time time)
{
MetaDisplay *display;
display = meta_device_get_display (device);
XAllowEvents (display->xdisplay, mode, time);
}
/* Core pointer */
G_DEFINE_TYPE (MetaDevicePointerCore,
meta_device_pointer_core,
META_TYPE_DEVICE_POINTER)
static gboolean
meta_device_pointer_core_grab (MetaDevice *device,
Window xwindow,
guint evmask,
MetaCursor cursor,
gboolean owner_events,
gboolean sync,
Time time)
{
MetaDisplay *display;
Cursor xcursor;
int retval;
display = meta_device_get_display (device);
xcursor = meta_display_create_x_cursor (display, cursor);
retval = XGrabPointer (display->xdisplay,
xwindow, owner_events,
evmask,
(sync) ? GrabModeSync : GrabModeAsync,
(sync) ? GrabModeSync : GrabModeAsync,
None, xcursor, time);
if (xcursor != None)
XFreeCursor (display->xdisplay, xcursor);
return (retval == Success);
}
static void
meta_device_pointer_core_ungrab (MetaDevice *device,
Time time)
{
MetaDisplay *display;
display = meta_device_get_display (device);
XUngrabPointer (display->xdisplay, time);
}
static void
meta_device_pointer_core_warp (MetaDevicePointer *pointer,
MetaScreen *screen,
gint x,
gint y)
{
MetaDisplay *display;
display = meta_device_get_display (META_DEVICE (pointer));
XWarpPointer (display->xdisplay,
None, screen->xroot,
0, 0, 0, 0, x, y);
}
static void
meta_device_pointer_core_set_window_cursor (MetaDevicePointer *pointer,
Window xwindow,
MetaCursor cursor)
{
MetaDisplay *display;
Cursor xcursor;
display = meta_device_get_display (META_DEVICE (pointer));
xcursor = meta_display_create_x_cursor (display, cursor);
XDefineCursor (display->xdisplay, xwindow, xcursor);
if (xcursor != None)
XFreeCursor (display->xdisplay, xcursor);
}
static gboolean
meta_device_pointer_core_query_position (MetaDevicePointer *pointer,
Window xwindow,
Window *root,
Window *child,
gint *root_x,
gint *root_y,
gint *x,
gint *y,
guint *mask)
{
MetaDisplay *display;
display = meta_device_get_display (META_DEVICE (pointer));
return XQueryPointer (display->xdisplay, xwindow,
root, child, root_x, root_y,
x, y, mask);
}
static void
meta_device_pointer_core_class_init (MetaDevicePointerCoreClass *klass)
{
MetaDevicePointerClass *pointer_class = META_DEVICE_POINTER_CLASS (klass);
MetaDeviceClass *device_class = META_DEVICE_CLASS (klass);
device_class->allow_events = meta_device_core_common_allow_events;
device_class->grab = meta_device_pointer_core_grab;
device_class->ungrab = meta_device_pointer_core_ungrab;
pointer_class->warp = meta_device_pointer_core_warp;
pointer_class->set_window_cursor = meta_device_pointer_core_set_window_cursor;
pointer_class->query_position = meta_device_pointer_core_query_position;
}
static void
meta_device_pointer_core_init (MetaDevicePointerCore *pointer)
{
}
MetaDevice *
meta_device_pointer_core_new (MetaDisplay *display)
{
return g_object_new (META_TYPE_DEVICE_POINTER_CORE,
"device-id", META_CORE_POINTER_ID,
"display", display,
NULL);
}
/* Core Keyboard */
G_DEFINE_TYPE (MetaDeviceKeyboardCore,
meta_device_keyboard_core,
META_TYPE_DEVICE_KEYBOARD)
static gboolean
meta_device_keyboard_core_grab (MetaDevice *device,
Window xwindow,
guint evmask,
MetaCursor cursor,
gboolean owner_events,
gboolean sync,
Time time)
{
MetaDisplay *display;
gint retval;
display = meta_device_get_display (device);
retval = XGrabKeyboard (display->xdisplay, xwindow, owner_events,
(sync) ? GrabModeSync : GrabModeAsync,
(sync) ? GrabModeSync : GrabModeAsync,
time);
return (retval == Success);
}
static void
meta_device_keyboard_core_ungrab (MetaDevice *device,
Time time)
{
MetaDisplay *display;
display = meta_device_get_display (device);
XUngrabKeyboard (display->xdisplay, time);
}
static Window
meta_device_keyboard_core_get_focus_window (MetaDeviceKeyboard *keyboard)
{
MetaDisplay *display;
Window xwindow;
int unused;
display = meta_device_get_display (META_DEVICE (keyboard));
XGetInputFocus (display->xdisplay, &xwindow, &unused);
return xwindow;
}
static void
meta_device_keyboard_core_set_focus_window (MetaDeviceKeyboard *keyboard,
Window xwindow,
Time timestamp)
{
MetaDisplay *display;
display = meta_device_get_display (META_DEVICE (keyboard));
XSetInputFocus (display->xdisplay,
xwindow,
RevertToPointerRoot,
timestamp);
}
static void
meta_device_keyboard_core_class_init (MetaDeviceKeyboardCoreClass *klass)
{
MetaDeviceKeyboardClass *keyboard_class = META_DEVICE_KEYBOARD_CLASS (klass);
MetaDeviceClass *device_class = META_DEVICE_CLASS (klass);
keyboard_class->get_focus_window = meta_device_keyboard_core_get_focus_window;
keyboard_class->set_focus_window = meta_device_keyboard_core_set_focus_window;
device_class->allow_events = meta_device_core_common_allow_events;
device_class->grab = meta_device_keyboard_core_grab;
device_class->ungrab = meta_device_keyboard_core_ungrab;
}
static void
meta_device_keyboard_core_init (MetaDeviceKeyboardCore *keyboard)
{
}
MetaDevice *
meta_device_keyboard_core_new (MetaDisplay *display)
{
return g_object_new (META_TYPE_DEVICE_KEYBOARD_CORE,
"device-id", META_CORE_KEYBOARD_ID,
"display", display,
NULL);
}

85
src/core/devices-core.h Normal file
View File

@ -0,0 +1,85 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/**
* \file devices-core.h Core input devices implementation
*
* Input devices.
* This file contains the core X protocol implementation of input devices.
*/
/*
* 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_DEVICES_CORE_H
#define META_DEVICES_CORE_H
#include "device-pointer.h"
#include "device-keyboard.h"
/* Pointer */
#define META_TYPE_DEVICE_POINTER_CORE (meta_device_pointer_core_get_type ())
#define META_DEVICE_POINTER_CORE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_DEVICE_POINTER_CORE, MetaDevicePointerCore))
#define META_DEVICE_POINTER_CORE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_DEVICE_POINTER_CORE, MetaDevicePointerCoreClass))
#define META_IS_DEVICE_POINTER_CORE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_DEVICE_POINTER_CORE))
#define META_IS_DEVICE_POINTER_CORE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_DEVICE_POINTER_CORE))
#define META_DEVICE_POINTER_CORE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_DEVICE_POINTER_CORE, MetaDevicePointerCoreClass))
typedef struct _MetaDevicePointerCore MetaDevicePointerCore;
typedef struct _MetaDevicePointerCoreClass MetaDevicePointerCoreClass;
struct _MetaDevicePointerCore
{
MetaDevicePointer parent_instance;
};
struct _MetaDevicePointerCoreClass
{
MetaDevicePointerClass parent_class;
};
GType meta_device_pointer_core_get_type (void) G_GNUC_CONST;
MetaDevice *meta_device_pointer_core_new (MetaDisplay *display);
/* Keyboard */
#define META_TYPE_DEVICE_KEYBOARD_CORE (meta_device_keyboard_core_get_type ())
#define META_DEVICE_KEYBOARD_CORE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_DEVICE_KEYBOARD_CORE, MetaDeviceKeyboardCore))
#define META_DEVICE_KEYBOARD_CORE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_DEVICE_KEYBOARD_CORE, MetaDeviceKeyboardCoreClass))
#define META_IS_DEVICE_KEYBOARD_CORE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_DEVICE_KEYBOARD_CORE))
#define META_IS_DEVICE_KEYBOARD_CORE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_DEVICE_KEYBOARD_CORE))
#define META_DEVICE_KEYBOARD_CORE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_DEVICE_KEYBOARD_CORE, MetaDeviceKeyboardCoreClass))
typedef struct _MetaDeviceKeyboardCore MetaDeviceKeyboardCore;
typedef struct _MetaDeviceKeyboardCoreClass MetaDeviceKeyboardCoreClass;
struct _MetaDeviceKeyboardCore
{
MetaDeviceKeyboard parent_instance;
};
struct _MetaDeviceKeyboardCoreClass
{
MetaDeviceKeyboardClass parent_class;
};
GType meta_device_keyboard_core_get_type (void) G_GNUC_CONST;
MetaDevice *meta_device_keyboard_core_new (MetaDisplay *display);
#endif /* META_DEVICES_CORE_H */

343
src/core/devices-xi2.c Normal file
View File

@ -0,0 +1,343 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* XInput2 devices 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 "devices-xi2.h"
#include "display-private.h"
#include "screen-private.h"
#include <X11/extensions/XInput2.h>
/* Common functions */
static void
meta_device_xi2_common_allow_events (MetaDevice *device,
int mode,
Time time)
{
MetaDisplay *display;
gint device_id;
display = meta_device_get_display (device);
device_id = meta_device_get_id (device);
switch (mode)
{
case AsyncPointer:
case AsyncKeyboard:
mode = XIAsyncDevice;
break;
case SyncPointer:
case SyncKeyboard:
mode = XISyncDevice;
break;
case ReplayPointer:
case ReplayKeyboard:
mode = XIReplayDevice;
break;
case AsyncBoth:
mode = XIAsyncPair;
break;
case SyncBoth:
mode = XISyncPair;
break;
}
XIAllowEvents (display->xdisplay, device_id, mode, time);
}
guchar *
meta_device_xi2_translate_event_mask (guint evmask,
gint *len)
{
guchar *mask;
*len = XIMaskLen (XI_LASTEVENT);
mask = g_new0 (guchar, *len);
if (evmask & KeyPressMask)
XISetMask (mask, XI_KeyPress);
if (evmask & KeyReleaseMask)
XISetMask (mask, XI_KeyRelease);
if (evmask & ButtonPressMask)
XISetMask (mask, XI_ButtonPress);
if (evmask & ButtonReleaseMask)
XISetMask (mask, XI_ButtonRelease);
if (evmask & EnterWindowMask)
XISetMask (mask, XI_Enter);
if (evmask & LeaveWindowMask)
XISetMask (mask, XI_Leave);
/* No motion hints in XI2 at the moment... */
if (evmask & PointerMotionMask ||
evmask & PointerMotionHintMask)
XISetMask (mask, XI_Motion);
if (evmask & FocusChangeMask)
{
XISetMask (mask, XI_FocusIn);
XISetMask (mask, XI_FocusOut);
}
return mask;
}
static gboolean
meta_device_xi2_common_grab (MetaDevice *device,
Window xwindow,
guint evmask,
MetaCursor cursor,
gboolean owner_events,
gboolean sync,
Time time)
{
MetaDisplay *display;
XIEventMask mask;
gint device_id, retval;
Cursor xcursor;
display = meta_device_get_display (device);
device_id = meta_device_get_id (device);
xcursor = meta_display_create_x_cursor (display, cursor);
mask.deviceid = device_id;
mask.mask = meta_device_xi2_translate_event_mask (evmask, &mask.mask_len);
retval = XIGrabDevice (display->xdisplay,
device_id, xwindow,
time, xcursor,
(sync) ? GrabModeSync : GrabModeAsync,
(sync) ? GrabModeSync : GrabModeAsync,
owner_events, &mask);
if (xcursor != None)
XFreeCursor (display->xdisplay, xcursor);
return (retval == Success);
}
static void
meta_device_xi2_common_ungrab (MetaDevice *device,
Time time)
{
MetaDisplay *display;
gint device_id;
display = meta_device_get_display (device);
device_id = meta_device_get_id (device);
XIUngrabDevice (display->xdisplay, device_id, time);
}
/* Pointer */
G_DEFINE_TYPE (MetaDevicePointerXI2,
meta_device_pointer_xi2,
META_TYPE_DEVICE_POINTER)
static void
meta_device_pointer_xi2_warp (MetaDevicePointer *pointer,
MetaScreen *screen,
gint x,
gint y)
{
MetaDisplay *display;
int device_id;
display = meta_device_get_display (META_DEVICE (pointer));
device_id = meta_device_get_id (META_DEVICE (pointer));
XIWarpPointer (display->xdisplay,
device_id,
None, screen->xroot,
0, 0, 0, 0, x, y);
}
static void
meta_device_pointer_xi2_set_window_cursor (MetaDevicePointer *pointer,
Window xwindow,
MetaCursor cursor)
{
MetaDisplay *display;
Cursor xcursor;
int device_id;
display = meta_device_get_display (META_DEVICE (pointer));
device_id = meta_device_get_id (META_DEVICE (pointer));
xcursor = meta_display_create_x_cursor (display, cursor);
if (xcursor != None)
{
XIDefineCursor (display->xdisplay, device_id, xwindow, xcursor);
XFreeCursor (display->xdisplay, xcursor);
}
else
XIUndefineCursor (display->xdisplay, device_id, xwindow);
}
static gboolean
meta_device_pointer_xi2_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)
{
MetaDisplay *display;
XIModifierState mods;
XIGroupState group_unused;
XIButtonState buttons;
gdouble root_x, root_y, x, y;
int device_id;
gboolean retval;
display = meta_device_get_display (META_DEVICE (pointer));
device_id = meta_device_get_id (META_DEVICE (pointer));
retval = XIQueryPointer (display->xdisplay,
device_id, xwindow,
root_ret, child_ret,
&root_x, &root_y, &x, &y,
&buttons, &mods,
&group_unused);
if (mask_ret)
{
*mask_ret = mods.effective;
if (XIMaskIsSet (buttons.mask, 1))
*mask_ret |= Button1Mask;
else if (XIMaskIsSet (buttons.mask, 2))
*mask_ret |= Button2Mask;
else if (XIMaskIsSet (buttons.mask, 3))
*mask_ret |= Button3Mask;
}
if (root_x_ret)
*root_x_ret = (int) root_x;
if (root_y_ret)
*root_y_ret = (int) root_y;
if (x_ret)
*x_ret = (int) x;
if (y_ret)
*y_ret = (int) y;
return retval;
}
static void
meta_device_pointer_xi2_class_init (MetaDevicePointerXI2Class *klass)
{
MetaDevicePointerClass *pointer_class = META_DEVICE_POINTER_CLASS (klass);
MetaDeviceClass *device_class = META_DEVICE_CLASS (klass);
device_class->allow_events = meta_device_xi2_common_allow_events;
device_class->grab = meta_device_xi2_common_grab;
device_class->ungrab = meta_device_xi2_common_ungrab;
pointer_class->warp = meta_device_pointer_xi2_warp;
pointer_class->set_window_cursor = meta_device_pointer_xi2_set_window_cursor;
pointer_class->query_position = meta_device_pointer_xi2_query_position;
}
static void
meta_device_pointer_xi2_init (MetaDevicePointerXI2 *pointer)
{
}
MetaDevice *
meta_device_pointer_xi2_new (MetaDisplay *display,
gint device_id)
{
return g_object_new (META_TYPE_DEVICE_POINTER_XI2,
"device-id", device_id,
"display", display,
NULL);
}
/* Keyboard */
G_DEFINE_TYPE (MetaDeviceKeyboardXI2,
meta_device_keyboard_xi2,
META_TYPE_DEVICE_KEYBOARD)
static Window
meta_device_keyboard_xi2_get_focus_window (MetaDeviceKeyboard *keyboard)
{
MetaDisplay *display;
Window xwindow;
display = meta_device_get_display (META_DEVICE (keyboard));
XIGetFocus (display->xdisplay,
meta_device_get_id (META_DEVICE (keyboard)),
&xwindow);
return xwindow;
}
static void
meta_device_keyboard_xi2_set_focus_window (MetaDeviceKeyboard *keyboard,
Window xwindow,
Time timestamp)
{
MetaDisplay *display;
display = meta_device_get_display (META_DEVICE (keyboard));
XISetFocus (display->xdisplay,
meta_device_get_id (META_DEVICE (keyboard)),
xwindow,
timestamp);
}
static void
meta_device_keyboard_xi2_class_init (MetaDeviceKeyboardXI2Class *klass)
{
MetaDeviceKeyboardClass *keyboard_class = META_DEVICE_KEYBOARD_CLASS (klass);
MetaDeviceClass *device_class = META_DEVICE_CLASS (klass);
keyboard_class->get_focus_window = meta_device_keyboard_xi2_get_focus_window;
keyboard_class->set_focus_window = meta_device_keyboard_xi2_set_focus_window;
device_class->allow_events = meta_device_xi2_common_allow_events;
device_class->grab = meta_device_xi2_common_grab;
device_class->ungrab = meta_device_xi2_common_ungrab;
}
static void
meta_device_keyboard_xi2_init (MetaDeviceKeyboardXI2 *keyboard)
{
}
MetaDevice *
meta_device_keyboard_xi2_new (MetaDisplay *display,
gint device_id)
{
return g_object_new (META_TYPE_DEVICE_KEYBOARD_XI2,
"device-id", device_id,
"display", display,
NULL);
}

92
src/core/devices-xi2.h Normal file
View File

@ -0,0 +1,92 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/**
* \file devices-xi2.h XInput2 input devices implementation
*
* Input devices.
* This file contains the XInput2 implementation of input devices.
*/
/*
* 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_DEVICES_XI2_H
#define META_DEVICES_XI2_H
#include "device-pointer.h"
#include "device-keyboard.h"
/* Pointer */
#define META_TYPE_DEVICE_POINTER_XI2 (meta_device_pointer_xi2_get_type ())
#define META_DEVICE_POINTER_XI2(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_DEVICE_POINTER_XI2, MetaDevicePointerXI2))
#define META_DEVICE_POINTER_XI2_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_DEVICE_POINTER_XI2, MetaDevicePointerXI2Class))
#define META_IS_DEVICE_POINTER_XI2(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_DEVICE_POINTER_XI2))
#define META_IS_DEVICE_POINTER_XI2_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_DEVICE_POINTER_XI2))
#define META_DEVICE_POINTER_XI2_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_DEVICE_POINTER_XI2, MetaDevicePointerXI2Class))
typedef struct _MetaDevicePointerXI2 MetaDevicePointerXI2;
typedef struct _MetaDevicePointerXI2Class MetaDevicePointerXI2Class;
struct _MetaDevicePointerXI2
{
MetaDevicePointer parent_instance;
};
struct _MetaDevicePointerXI2Class
{
MetaDevicePointerClass parent_class;
};
GType meta_device_pointer_xi2_get_type (void) G_GNUC_CONST;
MetaDevice *meta_device_pointer_xi2_new (MetaDisplay *display,
gint device_id);
/* Keyboard */
#define META_TYPE_DEVICE_KEYBOARD_XI2 (meta_device_keyboard_xi2_get_type ())
#define META_DEVICE_KEYBOARD_XI2(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_DEVICE_KEYBOARD_XI2, MetaDeviceKeyboardXI2))
#define META_DEVICE_KEYBOARD_XI2_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_DEVICE_KEYBOARD_XI2, MetaDeviceKeyboardXI2Class))
#define META_IS_DEVICE_KEYBOARD_XI2(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_DEVICE_KEYBOARD_XI2))
#define META_IS_DEVICE_KEYBOARD_XI2_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_DEVICE_KEYBOARD_XI2))
#define META_DEVICE_KEYBOARD_XI2_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_DEVICE_KEYBOARD_XI2, MetaDeviceKeyboardXI2Class))
typedef struct _MetaDeviceKeyboardXI2 MetaDeviceKeyboardXI2;
typedef struct _MetaDeviceKeyboardXI2Class MetaDeviceKeyboardXI2Class;
struct _MetaDeviceKeyboardXI2
{
MetaDeviceKeyboard parent_instance;
};
struct _MetaDeviceKeyboardXI2Class
{
MetaDeviceKeyboardClass parent_class;
};
GType meta_device_keyboard_xi2_get_type (void) G_GNUC_CONST;
MetaDevice *meta_device_keyboard_xi2_new (MetaDisplay *display,
gint device_id);
/* Helper function for translating event masks */
guchar * meta_device_xi2_translate_event_mask (guint evmask,
gint *len);
#endif /* META_DEVICES_XI2_H */

View File

@ -38,6 +38,7 @@
#include <meta/boxes.h>
#include <meta/display.h>
#include "keybindings-private.h"
#include "device-map-private.h"
#include <meta/prefs.h>
#ifdef HAVE_STARTUP_NOTIFICATION
@ -56,6 +57,9 @@ typedef struct _MetaWindowPropHooks MetaWindowPropHooks;
typedef struct MetaEdgeResistanceData MetaEdgeResistanceData;
typedef struct _MetaGrabInfo MetaGrabInfo;
typedef struct _MetaFocusInfo MetaFocusInfo;
typedef void (* MetaWindowPingFunc) (MetaDisplay *display,
Window xwindow,
guint32 timestamp,
@ -84,6 +88,65 @@ typedef enum {
META_TILE_MAXIMIZED
} MetaTileMode;
struct _MetaGrabInfo
{
MetaDevice *grab_pointer;
MetaDevice *grab_keyboard;
MetaGrabOp grab_op;
MetaScreen *grab_screen;
MetaWindow *grab_window;
Window grab_xwindow;
int grab_button;
int grab_anchor_root_x;
int grab_anchor_root_y;
MetaRectangle grab_anchor_window_pos;
MetaTileMode grab_tile_mode;
int grab_latest_motion_x;
int grab_latest_motion_y;
gulong grab_mask;
guint grab_have_pointer : 1;
guint grab_have_keyboard : 1;
guint grab_frame_action : 1;
/* During a resize operation, the directions in which we've broken
* out of the initial maximization state */
guint grab_resize_unmaximize : 2; /* MetaMaximizeFlags */
MetaRectangle grab_initial_window_pos;
int grab_initial_x, grab_initial_y; /* These are only relevant for */
gboolean grab_threshold_movement_reached; /* raise_on_click == FALSE. */
MetaResizePopup *grab_resize_popup;
GTimeVal grab_last_moveresize_time;
guint32 grab_motion_notify_time;
GList* grab_old_window_stacking;
unsigned int grab_last_user_action_was_snap;
#ifdef HAVE_XSYNC
/* alarm monitoring client's _NET_WM_SYNC_REQUEST_COUNTER */
XSyncAlarm grab_sync_request_alarm;
#endif
int grab_resize_timeout_id;
};
struct _MetaFocusInfo
{
/* This is the actual window from focus events,
* not the one we last set
*/
MetaWindow *focus_window;
/* window we are expecting a FocusIn event for or the current focus
* window if we are not expecting any FocusIn/FocusOut events; not
* perfect because applications can call XSetInputFocus directly.
* (It could also be messed up if a timestamp later than current
* time is sent to meta_display_set_input_focus_window, though that
* would be a programming error). See bug 154598 for more info.
*/
MetaWindow *expected_focus_window;
/* last timestamp passed to XSetInputFocus */
guint32 last_focus_time;
};
struct _MetaDisplay
{
GObject parent_instance;
@ -102,22 +165,8 @@ struct _MetaDisplay
#include <meta/atomnames.h>
#undef item
/* This is the actual window from focus events,
* not the one we last set
*/
MetaWindow *focus_window;
/* window we are expecting a FocusIn event for or the current focus
* window if we are not expecting any FocusIn/FocusOut events; not
* perfect because applications can call XSetInputFocus directly.
* (It could also be messed up if a timestamp later than current
* time is sent to meta_display_set_input_focus_window, though that
* would be a programming error). See bug 154598 for more info.
*/
MetaWindow *expected_focus_window;
/* last timestamp passed to XSetInputFocus */
guint32 last_focus_time;
/* keyboard -> MetaFocusInfo hashtable */
GHashTable *focus_info;
/* last user interaction time in any app */
guint32 last_user_time;
@ -177,34 +226,11 @@ struct _MetaDisplay
/* Alt+click button grabs */
unsigned int window_grab_modifiers;
/* current window operation */
MetaGrabOp grab_op;
MetaScreen *grab_screen;
MetaWindow *grab_window;
Window grab_xwindow;
int grab_button;
int grab_anchor_root_x;
int grab_anchor_root_y;
MetaRectangle grab_anchor_window_pos;
MetaTileMode grab_tile_mode;
int grab_latest_motion_x;
int grab_latest_motion_y;
gulong grab_mask;
guint grab_have_pointer : 1;
guint grab_have_keyboard : 1;
guint grab_frame_action : 1;
/* During a resize operation, the directions in which we've broken
* out of the initial maximization state */
guint grab_resize_unmaximize : 2; /* MetaMaximizeFlags */
MetaRectangle grab_initial_window_pos;
int grab_initial_x, grab_initial_y; /* These are only relevant for */
gboolean grab_threshold_movement_reached; /* raise_on_click == FALSE. */
MetaResizePopup *grab_resize_popup;
GTimeVal grab_last_moveresize_time;
guint32 grab_motion_notify_time;
GList* grab_old_window_stacking;
MetaEdgeResistanceData *grab_edge_resistance_data;
unsigned int grab_last_user_action_was_snap;
/* per-device current window operation */
GHashTable *current_grabs;
/* per-screen edge resistance cache */
GHashTable *edge_resistance_info;
/* we use property updates as sentinels for certain window focus events
* to avoid some race conditions on EnterNotify events
@ -215,11 +241,6 @@ struct _MetaDisplay
int xkb_base_event_type;
guint32 last_bell_time;
#endif
#ifdef HAVE_XSYNC
/* alarm monitoring client's _NET_WM_SYNC_REQUEST_COUNTER */
XSyncAlarm grab_sync_request_alarm;
#endif
int grab_resize_timeout_id;
/* Keybindings stuff */
MetaKeyBinding *key_bindings;
@ -266,6 +287,9 @@ struct _MetaDisplay
/* Managed by compositor.c */
MetaCompositor *compositor;
/* Managed by device-map.c */
MetaDeviceMap *device_map;
int render_event_base;
int render_error_base;
@ -289,6 +313,12 @@ struct _MetaDisplay
int shape_event_base;
int shape_error_base;
#endif
#ifdef HAVE_XINPUT2
int xinput2_opcode;
unsigned int have_xinput2 : 1;
#endif
#ifdef HAVE_XSYNC
unsigned int have_xsync : 1;
#define META_DISPLAY_HAS_XSYNC(display) ((display)->have_xsync)
@ -378,12 +408,14 @@ Cursor meta_display_create_x_cursor (MetaDisplay *display,
void meta_display_set_grab_op_cursor (MetaDisplay *display,
MetaScreen *screen,
MetaDevice *device,
MetaGrabOp op,
gboolean change_pointer,
Window grab_xwindow,
guint32 timestamp);
void meta_display_check_threshold_reached (MetaDisplay *display,
MetaDevice *device,
int x,
int y);
void meta_display_grab_window_buttons (MetaDisplay *display,
@ -397,7 +429,8 @@ void meta_display_ungrab_focus_window_button (MetaDisplay *display,
MetaWindow *window);
/* Next function is defined in edge-resistance.c */
void meta_display_cleanup_edges (MetaDisplay *display);
void meta_display_cleanup_edges (MetaDisplay *display,
MetaScreen *screen);
/* make a request to ensure the event serial has changed */
void meta_display_increment_event_serial (MetaDisplay *display);
@ -445,4 +478,15 @@ void meta_display_overlay_key_activate (MetaDisplay *display);
/* In above-tab-keycode.c */
guint meta_display_get_above_tab_keycode (MetaDisplay *display);
MetaGrabInfo * meta_display_create_grab_info (MetaDisplay *display,
MetaDevice *device);
void meta_display_remove_grab_info (MetaDisplay *display,
MetaDevice *device);
MetaGrabInfo * meta_display_get_grab_info (MetaDisplay *display,
MetaDevice *device);
MetaFocusInfo * meta_display_get_focus_info (MetaDisplay *display,
MetaDevice *device);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -30,12 +30,12 @@
/* A simple macro for whether a given window's edges are potentially
* relevant for resistance/snapping during a move/resize operation
*/
#define WINDOW_EDGES_RELEVANT(window, display) \
meta_window_should_be_showing (window) && \
window->screen == display->grab_screen && \
window != display->grab_window && \
window->type != META_WINDOW_DESKTOP && \
window->type != META_WINDOW_MENU && \
#define WINDOW_EDGES_RELEVANT(window, display, screen) \
meta_window_should_be_showing (window) && \
window->screen == screen && \
window->cur_grab == NULL && \
window->type != META_WINDOW_DESKTOP && \
window->type != META_WINDOW_MENU && \
window->type != META_WINDOW_SPLASHSCREEN
struct ResistanceDataForAnEdge
@ -44,8 +44,9 @@ struct ResistanceDataForAnEdge
guint timeout_id;
int timeout_edge_pos;
gboolean timeout_over;
GSourceFunc timeout_func;
MetaEdgeResistanceFunc timeout_func;
MetaWindow *window;
MetaDevice *device;
int keyboard_buildup;
};
typedef struct ResistanceDataForAnEdge ResistanceDataForAnEdge;
@ -63,7 +64,9 @@ struct MetaEdgeResistanceData
ResistanceDataForAnEdge bottom_data;
};
static void compute_resistance_and_snapping_edges (MetaDisplay *display);
static MetaEdgeResistanceData *
compute_resistance_and_snapping_edges (MetaDisplay *display,
MetaScreen *screen);
/* !WARNING!: this function can return invalid indices (namely, either -1 or
* edges->len); this is by design, but you need to remember this.
@ -318,20 +321,22 @@ edge_resistance_timeout (gpointer data)
resistance_data->timeout_over = TRUE;
resistance_data->timeout_id = 0;
(*resistance_data->timeout_func)(resistance_data->window);
(*resistance_data->timeout_func) (resistance_data->window,
resistance_data->device);
return FALSE;
}
static int
apply_edge_resistance (MetaWindow *window,
MetaDevice *device,
int old_pos,
int new_pos,
const MetaRectangle *old_rect,
const MetaRectangle *new_rect,
GArray *edges,
ResistanceDataForAnEdge *resistance_data,
GSourceFunc timeout_func,
MetaEdgeResistanceFunc timeout_func,
gboolean xdir,
gboolean keyboard_op)
{
@ -445,6 +450,7 @@ apply_edge_resistance (MetaWindow *window,
resistance_data->timeout_over = FALSE;
resistance_data->timeout_func = timeout_func;
resistance_data->window = window;
resistance_data->device = device;
}
if (!resistance_data->timeout_over &&
timeout_length_ms != 0)
@ -533,29 +539,28 @@ apply_edge_snapping (int old_pos,
* a proposed new position (ignoring edge resistance/snapping), and then
* applies edge resistance to EACH edge (separately) updating new_outer.
* It returns true if new_outer is modified, false otherwise.
*
* display->grab_edge_resistance_data MUST already be setup or calling this
* function will cause a crash.
*/
static gboolean
apply_edge_resistance_to_each_side (MetaDisplay *display,
MetaWindow *window,
const MetaRectangle *old_outer,
MetaRectangle *new_outer,
GSourceFunc timeout_func,
gboolean auto_snap,
gboolean keyboard_op,
gboolean is_resize)
apply_edge_resistance_to_each_side (MetaDisplay *display,
MetaWindow *window,
MetaDevice *device,
const MetaRectangle *old_outer,
MetaRectangle *new_outer,
MetaEdgeResistanceFunc timeout_func,
gboolean auto_snap,
gboolean keyboard_op,
gboolean is_resize)
{
MetaEdgeResistanceData *edge_data;
MetaRectangle modified_rect;
gboolean modified;
int new_left, new_right, new_top, new_bottom;
if (display->grab_edge_resistance_data == NULL)
compute_resistance_and_snapping_edges (display);
edge_data = g_hash_table_lookup (display->edge_resistance_info,
window->screen);
edge_data = display->grab_edge_resistance_data;
if (!edge_data)
edge_data = compute_resistance_and_snapping_edges (display, window->screen);
if (auto_snap)
{
@ -601,7 +606,7 @@ apply_edge_resistance_to_each_side (MetaDisplay *display,
if (!is_resize || window->size_hints.width_inc == 1)
{
/* Now, apply the normal horizontal edge resistance */
new_left = apply_edge_resistance (window,
new_left = apply_edge_resistance (window, device,
BOX_LEFT (*old_outer),
BOX_LEFT (*new_outer),
old_outer,
@ -611,7 +616,7 @@ apply_edge_resistance_to_each_side (MetaDisplay *display,
timeout_func,
TRUE,
keyboard_op);
new_right = apply_edge_resistance (window,
new_right = apply_edge_resistance (window, device,
BOX_RIGHT (*old_outer),
BOX_RIGHT (*new_outer),
old_outer,
@ -630,7 +635,7 @@ apply_edge_resistance_to_each_side (MetaDisplay *display,
/* Same for vertical resizes... */
if (!is_resize || window->size_hints.height_inc == 1)
{
new_top = apply_edge_resistance (window,
new_top = apply_edge_resistance (window, device,
BOX_TOP (*old_outer),
BOX_TOP (*new_outer),
old_outer,
@ -640,7 +645,7 @@ apply_edge_resistance_to_each_side (MetaDisplay *display,
timeout_func,
FALSE,
keyboard_op);
new_bottom = apply_edge_resistance (window,
new_bottom = apply_edge_resistance (window, device,
BOX_BOTTOM (*old_outer),
BOX_BOTTOM (*new_outer),
old_outer,
@ -669,15 +674,20 @@ apply_edge_resistance_to_each_side (MetaDisplay *display,
}
void
meta_display_cleanup_edges (MetaDisplay *display)
meta_display_cleanup_edges (MetaDisplay *display,
MetaScreen *screen)
{
guint i,j;
MetaEdgeResistanceData *edge_data = display->grab_edge_resistance_data;
MetaEdgeResistanceData *edge_data;
GHashTable *edges_to_be_freed;
edge_data = g_hash_table_lookup (display->edge_resistance_info, screen);
if (edge_data == NULL) /* Not currently cached */
return;
g_hash_table_steal (display->edge_resistance_info, screen);
/* We first need to clean out any window edges */
edges_to_be_freed = g_hash_table_new_full (g_direct_hash, g_direct_equal,
g_free, NULL);
@ -750,8 +760,7 @@ meta_display_cleanup_edges (MetaDisplay *display)
edge_data->bottom_data.timeout_id != 0)
g_source_remove (edge_data->bottom_data.timeout_id);
g_free (display->grab_edge_resistance_data);
display->grab_edge_resistance_data = NULL;
g_free (edge_data);
}
static int
@ -763,8 +772,9 @@ stupid_sort_requiring_extra_pointer_dereference (gconstpointer a,
return meta_rectangle_edge_cmp_ignore_type (*a_edge, *b_edge);
}
static void
static MetaEdgeResistanceData *
cache_edges (MetaDisplay *display,
MetaScreen *screen,
GList *window_edges,
GList *monitor_edges,
GList *screen_edges)
@ -848,9 +858,8 @@ cache_edges (MetaDisplay *display,
/*
* 2nd: Allocate the edges
*/
g_assert (display->grab_edge_resistance_data == NULL);
display->grab_edge_resistance_data = g_new0 (MetaEdgeResistanceData, 1);
edge_data = display->grab_edge_resistance_data;
edge_data = g_new0 (MetaEdgeResistanceData, 1);
edge_data->left_edges = g_array_sized_new (FALSE,
FALSE,
sizeof(MetaEdge*),
@ -917,21 +926,21 @@ cache_edges (MetaDisplay *display,
* avoided this sort by sticking them into the array with some simple
* merging of the lists).
*/
g_array_sort (display->grab_edge_resistance_data->left_edges,
g_array_sort (edge_data->left_edges,
stupid_sort_requiring_extra_pointer_dereference);
g_array_sort (display->grab_edge_resistance_data->right_edges,
g_array_sort (edge_data->right_edges,
stupid_sort_requiring_extra_pointer_dereference);
g_array_sort (display->grab_edge_resistance_data->top_edges,
g_array_sort (edge_data->top_edges,
stupid_sort_requiring_extra_pointer_dereference);
g_array_sort (display->grab_edge_resistance_data->bottom_edges,
g_array_sort (edge_data->bottom_edges,
stupid_sort_requiring_extra_pointer_dereference);
return edge_data;
}
static void
initialize_grab_edge_resistance_data (MetaDisplay *display)
initialize_grab_edge_resistance_data (MetaEdgeResistanceData *edge_data)
{
MetaEdgeResistanceData *edge_data = display->grab_edge_resistance_data;
edge_data->left_data.timeout_setup = FALSE;
edge_data->right_data.timeout_setup = FALSE;
edge_data->top_data.timeout_setup = FALSE;
@ -943,8 +952,9 @@ initialize_grab_edge_resistance_data (MetaDisplay *display)
edge_data->bottom_data.keyboard_buildup = 0;
}
static void
compute_resistance_and_snapping_edges (MetaDisplay *display)
static MetaEdgeResistanceData *
compute_resistance_and_snapping_edges (MetaDisplay *display,
MetaScreen *screen)
{
GList *stacked_windows;
GList *cur_window_iter;
@ -956,18 +966,17 @@ compute_resistance_and_snapping_edges (MetaDisplay *display)
* in the layer that we are working on
*/
GSList *rem_windows, *rem_win_stacking;
MetaEdgeResistanceData *edge_data;
g_assert (display->grab_window != NULL);
meta_topic (META_DEBUG_WINDOW_OPS,
"Computing edges to resist-movement or snap-to for %s.\n",
display->grab_window->desc);
"Computing edges to resist-movement or snap-to for screen %s.\n",
screen->screen_name);
/*
* 1st: Get the list of relevant windows, from bottom to top
*/
stacked_windows =
meta_stack_list_windows (display->grab_screen->stack,
display->grab_screen->active_workspace);
meta_stack_list_windows (screen->stack, screen->active_workspace);
/*
* 2nd: we need to separate that stacked list into a list of windows that
@ -981,7 +990,7 @@ compute_resistance_and_snapping_edges (MetaDisplay *display)
while (cur_window_iter != NULL)
{
MetaWindow *cur_window = cur_window_iter->data;
if (WINDOW_EDGES_RELEVANT (cur_window, display))
if (WINDOW_EDGES_RELEVANT (cur_window, display, screen))
{
MetaRectangle *new_rect;
new_rect = g_new (MetaRectangle, 1);
@ -1016,7 +1025,7 @@ compute_resistance_and_snapping_edges (MetaDisplay *display)
* resistance (note that dock edges are considered screen edges
* which are handled separately
*/
if (WINDOW_EDGES_RELEVANT (cur_window, display) &&
if (WINDOW_EDGES_RELEVANT (cur_window, display, screen) &&
cur_window->type != META_WINDOW_DOCK)
{
GList *new_edges;
@ -1028,7 +1037,7 @@ compute_resistance_and_snapping_edges (MetaDisplay *display)
* by other windows or DOCKS, but that's handled below).
*/
meta_rectangle_intersect (&cur_rect,
&display->grab_screen->rect,
&screen->rect,
&reduced);
new_edges = NULL;
@ -1123,32 +1132,36 @@ compute_resistance_and_snapping_edges (MetaDisplay *display)
* monitor edges in an array for quick access. Free the edges since
* they've been cached elsewhere.
*/
cache_edges (display,
edges,
display->grab_screen->active_workspace->monitor_edges,
display->grab_screen->active_workspace->screen_edges);
edge_data = cache_edges (display, screen,
edges,
screen->active_workspace->monitor_edges,
screen->active_workspace->screen_edges);
g_list_free (edges);
/*
* 6th: Initialize the resistance timeouts and buildups
*/
initialize_grab_edge_resistance_data (display);
initialize_grab_edge_resistance_data (edge_data);
return edge_data;
}
/* Note that old_[xy] and new_[xy] are with respect to inner positions of
* the window.
*/
void
meta_window_edge_resistance_for_move (MetaWindow *window,
int old_x,
int old_y,
int *new_x,
int *new_y,
GSourceFunc timeout_func,
gboolean snap,
gboolean is_keyboard_op)
meta_window_edge_resistance_for_move (MetaWindow *window,
MetaDevice *device,
int old_x,
int old_y,
int *new_x,
int *new_y,
MetaEdgeResistanceFunc timeout_func,
gboolean snap,
gboolean is_keyboard_op)
{
MetaRectangle old_outer, proposed_outer, new_outer;
MetaGrabInfo *grab_info;
gboolean is_resize;
meta_window_get_outer_rect (window, &old_outer);
@ -1158,10 +1171,14 @@ meta_window_edge_resistance_for_move (MetaWindow *window,
proposed_outer.y += (*new_y - old_y);
new_outer = proposed_outer;
window->display->grab_last_user_action_was_snap = snap;
grab_info = meta_display_get_grab_info (window->display, device);
g_assert (grab_info != NULL);
grab_info->grab_last_user_action_was_snap = snap;
is_resize = FALSE;
if (apply_edge_resistance_to_each_side (window->display,
window,
device,
&old_outer,
&new_outer,
timeout_func,
@ -1223,18 +1240,20 @@ meta_window_edge_resistance_for_move (MetaWindow *window,
* sizes of the inner window.
*/
void
meta_window_edge_resistance_for_resize (MetaWindow *window,
int old_width,
int old_height,
int *new_width,
int *new_height,
int gravity,
GSourceFunc timeout_func,
gboolean snap,
gboolean is_keyboard_op)
meta_window_edge_resistance_for_resize (MetaWindow *window,
MetaDevice *device,
int old_width,
int old_height,
int *new_width,
int *new_height,
int gravity,
MetaEdgeResistanceFunc timeout_func,
gboolean snap,
gboolean is_keyboard_op)
{
MetaRectangle old_outer, new_outer;
int proposed_outer_width, proposed_outer_height;
MetaGrabInfo *grab_info;
gboolean is_resize;
meta_window_get_outer_rect (window, &old_outer);
@ -1246,10 +1265,14 @@ meta_window_edge_resistance_for_resize (MetaWindow *window,
proposed_outer_width,
proposed_outer_height);
window->display->grab_last_user_action_was_snap = snap;
grab_info = meta_display_get_grab_info (window->display, device);
g_assert (grab_info != NULL);
grab_info->grab_last_user_action_was_snap = snap;
is_resize = TRUE;
if (apply_edge_resistance_to_each_side (window->display,
window,
device,
&old_outer,
&new_outer,
timeout_func,

View File

@ -26,23 +26,28 @@
#include "window-private.h"
void meta_window_edge_resistance_for_move (MetaWindow *window,
int old_x,
int old_y,
int *new_x,
int *new_y,
GSourceFunc timeout_func,
gboolean snap,
gboolean is_keyboard_op);
void meta_window_edge_resistance_for_resize (MetaWindow *window,
int old_width,
int old_height,
int *new_width,
int *new_height,
int gravity,
GSourceFunc timeout_func,
gboolean snap,
gboolean is_keyboard_op);
typedef gboolean (* MetaEdgeResistanceFunc) (MetaWindow *window,
MetaDevice *device);
void meta_window_edge_resistance_for_move (MetaWindow *window,
MetaDevice *device,
int old_x,
int old_y,
int *new_x,
int *new_y,
MetaEdgeResistanceFunc func,
gboolean snap,
gboolean is_keyboard_op);
void meta_window_edge_resistance_for_resize (MetaWindow *window,
MetaDevice *device,
int old_width,
int old_height,
int *new_width,
int *new_height,
int gravity,
MetaEdgeResistanceFunc func,
gboolean snap,
gboolean is_keyboard_op);
#endif /* META_EDGE_RESISTANCE_H */

View File

@ -28,6 +28,7 @@
#include "bell.h"
#include <meta/errors.h>
#include "keybindings-private.h"
#include "device-pointer.h"
#include <X11/extensions/Xrender.h>
@ -64,7 +65,7 @@ meta_window_ensure_frame (MetaWindow *window)
frame->child_y = 0;
frame->bottom_height = 0;
frame->right_width = 0;
frame->current_cursor = 0;
frame->cursors = g_hash_table_new (NULL, NULL);
frame->mapped = FALSE;
frame->need_reapply_frame_shape = TRUE;
@ -117,11 +118,6 @@ meta_window_ensure_frame (MetaWindow *window)
meta_display_register_x_window (window->display, &frame->xwindow, window);
/* Now that frame->xwindow is registered with window, we can set its
* background.
*/
meta_ui_reset_frame_bg (window->screen->ui, frame->xwindow);
/* Reparent the client window; it may be destroyed,
* thus the error trap. We'll get a destroy notify later
* and free everything. Comment in FVWM source code says
@ -157,6 +153,12 @@ meta_window_ensure_frame (MetaWindow *window)
/* stick frame to the window */
window->frame = frame;
/* Now that frame->xwindow is registered with window, we can set its
* style and background.
*/
meta_ui_update_frame_style (window->screen->ui, frame->xwindow);
meta_ui_reset_frame_bg (window->screen->ui, frame->xwindow);
if (window->title)
meta_ui_set_frame_title (window->screen->ui,
@ -228,9 +230,10 @@ meta_window_destroy_frame (MetaWindow *window)
/* Move keybindings to window instead of frame */
meta_window_grab_keys (window);
g_hash_table_destroy (frame->cursors);
g_free (frame);
/* Put our state back where it should be */
meta_window_queue (window, META_QUEUE_CALC_SHOWING);
meta_window_queue (window, META_QUEUE_MOVE_RESIZE);
@ -244,6 +247,12 @@ meta_frame_get_flags (MetaFrame *frame)
flags = 0;
/* Disallow frame operations
* while the popup menu is open.
*/
if (frame->window->menu)
return flags;
if (frame->window->border_only)
{
; /* FIXME this may disable the _function_ as well as decor
@ -328,7 +337,7 @@ meta_frame_calc_geometry (MetaFrame *frame,
*geomp = geom;
}
static void
static gboolean
update_shape (MetaFrame *frame)
{
if (frame->need_reapply_frame_shape)
@ -339,10 +348,14 @@ update_shape (MetaFrame *frame)
frame->rect.height,
frame->window->has_shape);
frame->need_reapply_frame_shape = FALSE;
return TRUE;
}
else
return FALSE;
}
void
gboolean
meta_frame_sync_to_window (MetaFrame *frame,
int resize_gravity,
gboolean need_move,
@ -350,8 +363,7 @@ meta_frame_sync_to_window (MetaFrame *frame,
{
if (!(need_move || need_resize))
{
update_shape (frame);
return;
return update_shape (frame);
}
meta_topic (META_DEBUG_GEOMETRY,
@ -396,11 +408,21 @@ meta_frame_sync_to_window (MetaFrame *frame,
/* If we're interactively resizing the frame, repaint
* it immediately so we don't start to lag.
*/
if (frame->window->display->grab_window ==
frame->window)
if (frame->window->cur_grab != NULL)
meta_ui_repaint_frame (frame->window->screen->ui,
frame->xwindow);
}
return need_resize;
}
cairo_region_t *
meta_frame_get_frame_bounds (MetaFrame *frame)
{
return meta_ui_get_frame_bounds (frame->window->screen->ui,
frame->xwindow,
frame->rect.width,
frame->rect.height);
}
void
@ -411,22 +433,22 @@ meta_frame_queue_draw (MetaFrame *frame)
}
void
meta_frame_set_screen_cursor (MetaFrame *frame,
MetaCursor cursor)
meta_frame_set_screen_cursor (MetaFrame *frame,
MetaDevice *pointer,
MetaCursor cursor)
{
Cursor xcursor;
if (cursor == frame->current_cursor)
MetaCursor old_cursor;
old_cursor = GPOINTER_TO_UINT (g_hash_table_lookup (frame->cursors, pointer));
if (cursor == old_cursor)
return;
frame->current_cursor = cursor;
if (cursor == META_CURSOR_DEFAULT)
XUndefineCursor (frame->window->display->xdisplay, frame->xwindow);
else
{
xcursor = meta_display_create_x_cursor (frame->window->display, cursor);
XDefineCursor (frame->window->display->xdisplay, frame->xwindow, xcursor);
XFlush (frame->window->display->xdisplay);
XFreeCursor (frame->window->display->xdisplay, xcursor);
}
g_hash_table_insert (frame->cursors, pointer,
GUINT_TO_POINTER (cursor));
meta_device_pointer_set_window_cursor (META_DEVICE_POINTER (pointer),
frame->xwindow, cursor);
XFlush (frame->window->display->xdisplay);
}
Window

View File

@ -45,7 +45,7 @@ struct _MetaFrame
/* reparent window */
Window xwindow;
MetaCursor current_cursor;
GHashTable *cursors;
/* This rect is trusted info from where we put the
* frame, not the result of ConfigureNotify
@ -73,12 +73,15 @@ Window meta_frame_get_xwindow (MetaFrame *frame);
/* These should ONLY be called from meta_window_move_resize_internal */
void meta_frame_calc_geometry (MetaFrame *frame,
MetaFrameGeometry *geomp);
void meta_frame_sync_to_window (MetaFrame *frame,
gboolean meta_frame_sync_to_window (MetaFrame *frame,
int gravity,
gboolean need_move,
gboolean need_resize);
void meta_frame_set_screen_cursor (MetaFrame *frame,
cairo_region_t *meta_frame_get_frame_bounds (MetaFrame *frame);
void meta_frame_set_screen_cursor (MetaFrame *frame,
MetaDevice *pointer,
MetaCursor cursor);
#endif

677
src/core/input-events.c Normal file
View File

@ -0,0 +1,677 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* XEvent utility methods */
/*
* 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 "input-events.h"
#include "devices-core.h"
#include "device-map-private.h"
#include <X11/Xlib.h>
#ifdef HAVE_XINPUT2
#include <X11/extensions/XInput2.h>
#endif
/* Quite a hack: normalizes XI2 events to their
* core event equivalent, so most code is shared
* for both implementations, code handling input
* events should use the helper functions so
* the actual event is treated correctly.
*/
gboolean
meta_input_event_get_type (MetaDisplay *display,
XEvent *ev,
guint *ev_type)
{
guint type = 0; /* Silence gcc */
gboolean retval = TRUE;
#ifdef HAVE_XINPUT2
if (display->have_xinput2 &&
ev->type == GenericEvent &&
ev->xcookie.extension == display->xinput2_opcode)
{
XIEvent *xev;
/* NB: GDK event filters already have generic events
* allocated, so no need to do XGetEventData() on our own
*/
xev = (XIEvent *) ev->xcookie.data;
switch (xev->evtype)
{
case XI_Motion:
type = MotionNotify;
break;
case XI_ButtonPress:
type = ButtonPress;
break;
case XI_ButtonRelease:
type = ButtonRelease;
break;
case XI_KeyPress:
type = KeyPress;
break;
case XI_KeyRelease:
type = KeyRelease;
break;
case XI_FocusIn:
type = FocusIn;
break;
case XI_FocusOut:
type = FocusOut;
break;
case XI_Enter:
type = EnterNotify;
break;
case XI_Leave:
type = LeaveNotify;
break;
default:
retval = FALSE;
break;
}
}
else
#endif /* HAVE_XINPUT2 */
{
switch (ev->type)
{
case MotionNotify:
case ButtonPress:
case ButtonRelease:
case KeyPress:
case KeyRelease:
case FocusIn:
case FocusOut:
case EnterNotify:
case LeaveNotify:
type = ev->type;
break;
default:
retval = FALSE;
break;
}
}
if (retval)
{
if (ev_type)
*ev_type = type;
return TRUE;
}
else
return FALSE;
}
gboolean
meta_input_event_is_type (MetaDisplay *display,
XEvent *ev,
guint ev_type)
{
guint type;
if (!meta_input_event_get_type (display, ev, &type))
return FALSE;
return (type == ev_type);
}
Window
meta_input_event_get_window (MetaDisplay *display,
XEvent *ev)
{
#ifdef HAVE_XINPUT2
if (ev->type == GenericEvent &&
ev->xcookie.extension == display->xinput2_opcode)
{
XIEvent *xev;
g_assert (display->have_xinput2 == TRUE);
/* GDK event filters already have generic events allocated */
xev = (XIEvent *) ev->xcookie.data;
switch (xev->evtype)
{
case XI_Motion:
case XI_ButtonPress:
case XI_ButtonRelease:
case XI_KeyPress:
case XI_KeyRelease:
return ((XIDeviceEvent *) xev)->event;
case XI_FocusIn:
case XI_FocusOut:
case XI_Enter:
case XI_Leave:
return ((XIEnterEvent *) xev)->event;
default:
return None;
}
}
else
#endif /* HAVE_XINPUT2 */
return ev->xany.window;
}
Window
meta_input_event_get_root_window (MetaDisplay *display,
XEvent *ev)
{
#ifdef HAVE_XINPUT2
if (ev->type == GenericEvent &&
ev->xcookie.extension == display->xinput2_opcode)
{
XIEvent *xev;
g_assert (display->have_xinput2 == TRUE);
xev = (XIEvent *) ev->xcookie.data;
switch (xev->evtype)
{
case XI_Motion:
case XI_ButtonPress:
case XI_ButtonRelease:
case XI_KeyPress:
case XI_KeyRelease:
return ((XIDeviceEvent *) xev)->root;
case XI_FocusIn:
case XI_FocusOut:
case XI_Enter:
case XI_Leave:
return ((XIEnterEvent *) xev)->root;
default:
break;
}
}
else
#endif /* HAVE_XINPUT2 */
{
switch (ev->type)
{
case KeyPress:
case KeyRelease:
return ev->xkey.root;
case ButtonPress:
case ButtonRelease:
return ev->xbutton.root;
case EnterNotify:
case LeaveNotify:
return ev->xcrossing.root;
case MotionNotify:
return ev->xbutton.root;
default:
break;
}
}
return None;
}
Time
meta_input_event_get_time (MetaDisplay *display,
XEvent *ev)
{
#ifdef HAVE_XINPUT2
if (ev->type == GenericEvent &&
ev->xcookie.extension == display->xinput2_opcode)
{
XIEvent *xev;
g_assert (display->have_xinput2 == TRUE);
xev = (XIEvent *) ev->xcookie.data;
switch (xev->evtype)
{
case XI_Motion:
case XI_ButtonPress:
case XI_ButtonRelease:
case XI_KeyPress:
case XI_KeyRelease:
return ((XIDeviceEvent *) xev)->time;
case XI_FocusIn:
case XI_FocusOut:
case XI_Enter:
case XI_Leave:
return ((XIEnterEvent *) xev)->time;
default:
break;
}
}
else
#endif /* HAVE_XINPUT2 */
{
switch (ev->type)
{
case KeyPress:
case KeyRelease:
return ev->xkey.time;
case ButtonPress:
case ButtonRelease:
return ev->xbutton.time;
case EnterNotify:
case LeaveNotify:
return ev->xcrossing.time;
case MotionNotify:
return ev->xmotion.time;
default:
break;
}
}
return CurrentTime;
}
gboolean
meta_input_event_get_coordinates (MetaDisplay *display,
XEvent *ev,
gdouble *x_ret,
gdouble *y_ret,
gdouble *x_root_ret,
gdouble *y_root_ret)
{
gdouble x, y, x_root, y_root;
gboolean retval = TRUE;
#ifdef HAVE_XINPUT2
if (ev->type == GenericEvent &&
ev->xcookie.extension == display->xinput2_opcode)
{
XIEvent *xev;
g_assert (display->have_xinput2 == TRUE);
xev = (XIEvent *) ev->xcookie.data;
switch (xev->evtype)
{
case XI_Motion:
case XI_ButtonPress:
case XI_ButtonRelease:
case XI_KeyPress:
case XI_KeyRelease:
{
XIDeviceEvent *event = (XIDeviceEvent *) xev;
x = event->event_x;
y = event->event_y;
x_root = event->root_x;
y_root = event->root_y;
}
break;
case XI_FocusIn:
case XI_FocusOut:
case XI_Enter:
case XI_Leave:
{
XIEnterEvent *event = (XIEnterEvent *) xev;
x = event->event_x;
y = event->event_y;
x_root = event->root_x;
y_root = event->root_y;
}
break;
default:
retval = FALSE;
break;
}
}
else
#endif /* HAVE_XINPUT2 */
{
switch (ev->type)
{
case KeyPress:
case KeyRelease:
x = ev->xkey.x;
y = ev->xkey.y;
x_root = ev->xkey.x_root;
y_root = ev->xkey.y_root;
break;
case ButtonPress:
case ButtonRelease:
x = ev->xbutton.x;
y = ev->xbutton.y;
x_root = ev->xbutton.x_root;
y_root = ev->xbutton.y_root;
break;
case EnterNotify:
case LeaveNotify:
x = ev->xcrossing.x;
y = ev->xcrossing.y;
x_root = ev->xcrossing.x_root;
y_root = ev->xcrossing.y_root;
break;
case MotionNotify:
x = ev->xmotion.x;
y = ev->xmotion.y;
x_root = ev->xmotion.x_root;
y_root = ev->xmotion.y_root;
break;
default:
retval = FALSE;
break;
}
}
if (retval)
{
if (x_ret)
*x_ret = x;
if (y_ret)
*y_ret = y;
if (x_root_ret)
*x_root_ret = x_root;
if (y_root_ret)
*y_root_ret = y_root;
}
return retval;
}
gboolean
meta_input_event_get_state (MetaDisplay *display,
XEvent *ev,
guint *state)
{
gboolean retval = TRUE;
guint s;
#ifdef HAVE_XINPUT2
if (ev->type == GenericEvent &&
ev->xcookie.extension == display->xinput2_opcode)
{
XIEvent *xev;
g_assert (display->have_xinput2 == TRUE);
xev = (XIEvent *) ev->xcookie.data;
switch (xev->evtype)
{
case XI_Motion:
case XI_ButtonPress:
case XI_ButtonRelease:
case XI_KeyPress:
case XI_KeyRelease:
s = ((XIDeviceEvent *) xev)->mods.effective;
break;
case XI_FocusIn:
case XI_FocusOut:
case XI_Enter:
case XI_Leave:
s = ((XIDeviceEvent *) xev)->mods.effective;
break;
default:
retval = FALSE;
break;
}
}
else
#endif /* HAVE_XINPUT2 */
{
switch (ev->type)
{
case KeyPress:
case KeyRelease:
s = ev->xkey.state;
break;
case ButtonPress:
case ButtonRelease:
s = ev->xbutton.state;
break;
case EnterNotify:
case LeaveNotify:
s = ev->xcrossing.state;
break;
case MotionNotify:
s = ev->xmotion.state;
break;
default:
retval = FALSE;
break;
}
}
if (retval && state)
*state = s;
return retval;
}
gboolean
meta_input_event_get_keycode (MetaDisplay *display,
XEvent *ev,
guint *keycode)
{
#ifdef HAVE_XINPUT2
if (ev->type == GenericEvent &&
ev->xcookie.extension == display->xinput2_opcode)
{
XIEvent *xev;
g_assert (display->have_xinput2 == TRUE);
xev = (XIEvent *) ev->xcookie.data;
if (xev->evtype == XI_KeyPress ||
xev->evtype == XI_KeyRelease)
{
if (keycode)
{
/* The detail field contains keycode for key events */
*keycode = ((XIDeviceEvent *) xev)->detail;
}
return TRUE;
}
}
else
#endif /* HAVE_XINPUT2 */
{
if (ev->type == KeyPress ||
ev->type == KeyRelease)
{
if (keycode)
*keycode = ev->xkey.keycode;
return TRUE;
}
}
return FALSE;
}
gboolean
meta_input_event_get_button (MetaDisplay *display,
XEvent *ev,
guint *button)
{
#ifdef HAVE_XINPUT2
if (ev->type == GenericEvent &&
ev->xcookie.extension == display->xinput2_opcode)
{
XIEvent *xev;
g_assert (display->have_xinput2 == TRUE);
xev = (XIEvent *) ev->xcookie.data;
if (xev->evtype == XI_ButtonPress ||
xev->evtype == XI_ButtonRelease)
{
if (button)
{
/* The detail field contains
* button number for button events
*/
*button = ((XIDeviceEvent *) xev)->detail;
}
return TRUE;
}
}
else
#endif /* HAVE_XINPUT2 */
{
if (ev->type == ButtonPress ||
ev->type == ButtonRelease)
{
if (button)
*button = ev->xbutton.button;
return TRUE;
}
}
return FALSE;
}
/* NB: Also works for focus in/out events */
gboolean
meta_input_event_get_crossing_details (MetaDisplay *display,
XEvent *ev,
guint *mode_out,
guint *detail_out)
{
gboolean retval = TRUE;
guint mode, detail;
#ifdef HAVE_XINPUT2
if (ev->type == GenericEvent &&
ev->xcookie.extension == display->xinput2_opcode)
{
XIEvent *xev;
g_assert (display->have_xinput2 == TRUE);
xev = (XIEvent *) ev->xcookie.data;
if (xev->evtype == XI_Enter ||
xev->evtype == XI_Leave ||
xev->evtype == XI_FocusIn ||
xev->evtype == XI_FocusOut)
{
mode = ((XIEnterEvent *) xev)->mode;
detail = ((XIEnterEvent *) xev)->detail;
}
else
retval = FALSE;
}
else
#endif /* HAVE_XINPUT2 */
{
if (ev->type == EnterNotify ||
ev->type == LeaveNotify)
{
mode = ev->xcrossing.mode;
detail = ev->xcrossing.detail;
}
else if (ev->type == FocusIn ||
ev->type == FocusOut)
{
mode = ev->xfocus.mode;
detail = ev->xfocus.detail;
}
else
retval = FALSE;
}
if (retval)
{
if (mode_out)
*mode_out = mode;
if (detail_out)
*detail_out = detail;
}
return retval;
}
MetaDevice *
meta_input_event_get_device (MetaDisplay *display,
XEvent *ev)
{
guint evtype;
if (!meta_input_event_get_type (display, ev, &evtype))
return NULL;
#ifdef HAVE_XINPUT2
if (ev->type == GenericEvent &&
ev->xcookie.extension == display->xinput2_opcode)
{
XIEvent *xev;
g_assert (display->have_xinput2 == TRUE);
xev = (XIEvent *) ev->xcookie.data;
switch (evtype)
{
case XI_Motion:
case XI_ButtonPress:
case XI_ButtonRelease:
case XI_KeyPress:
case XI_KeyRelease:
return meta_device_map_lookup (display->device_map,
((XIDeviceEvent *) xev)->deviceid);
case XI_FocusIn:
case XI_FocusOut:
case XI_Enter:
case XI_Leave:
return meta_device_map_lookup (display->device_map,
((XIEnterEvent *) xev)->deviceid);
default:
break;
}
}
else
#endif
{
switch (ev->type)
{
case KeyPress:
case KeyRelease:
case FocusIn:
case FocusOut:
return meta_device_map_lookup (display->device_map,
META_CORE_KEYBOARD_ID);
default:
/* All other events are pointers' */
return meta_device_map_lookup (display->device_map,
META_CORE_POINTER_ID);
}
}
return NULL;
}

78
src/core/input-events.h Normal file
View File

@ -0,0 +1,78 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/**
* \file event.h Utility functions for handling events
*
* Handling events.
* This file contains helper methods to handle events, specially
* input events, which can be either core or XInput2.
*/
/*
* 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_EVENT_H
#define META_EVENT_H
#include <config.h>
#include <X11/Xlib.h>
#include "display-private.h"
#include <meta/device-map.h>
gboolean meta_input_event_get_type (MetaDisplay *display,
XEvent *ev,
guint *ev_type);
gboolean meta_input_event_is_type (MetaDisplay *display,
XEvent *ev,
guint ev_type);
Window meta_input_event_get_window (MetaDisplay *display,
XEvent *ev);
Window meta_input_event_get_root_window (MetaDisplay *display,
XEvent *ev);
Time meta_input_event_get_time (MetaDisplay *display,
XEvent *ev);
gboolean meta_input_event_get_coordinates (MetaDisplay *display,
XEvent *ev,
gdouble *x_ret,
gdouble *y_ret,
gdouble *x_root_ret,
gdouble *y_root_ret);
gboolean meta_input_event_get_state (MetaDisplay *display,
XEvent *ev,
guint *state);
gboolean meta_input_event_get_keycode (MetaDisplay *display,
XEvent *ev,
guint *keycode);
gboolean meta_input_event_get_button (MetaDisplay *display,
XEvent *event,
guint *button);
gboolean meta_input_event_get_crossing_details (MetaDisplay *display,
XEvent *ev,
guint *mode_out,
guint *detail_out);
MetaDevice *meta_input_event_get_device (MetaDisplay *display,
XEvent *ev);
#endif /* META_EVENT_H */

View File

@ -36,14 +36,18 @@ void meta_display_shutdown_keys (MetaDisplay *display);
void meta_screen_grab_keys (MetaScreen *screen);
void meta_screen_ungrab_keys (MetaScreen *screen);
gboolean meta_screen_grab_all_keys (MetaScreen *screen,
MetaDevice *device,
guint32 timestamp);
void meta_screen_ungrab_all_keys (MetaScreen *screen,
void meta_screen_ungrab_all_keys (MetaScreen *screen,
MetaDevice *device,
guint32 timestamp);
void meta_window_grab_keys (MetaWindow *window);
void meta_window_ungrab_keys (MetaWindow *window);
gboolean meta_window_grab_all_keys (MetaWindow *window,
MetaDevice *device,
guint32 timestamp);
void meta_window_ungrab_all_keys (MetaWindow *window,
MetaDevice *device,
guint32 timestamp);
gboolean meta_display_process_key_event (MetaDisplay *display,
MetaWindow *window,

File diff suppressed because it is too large Load Diff

View File

@ -251,6 +251,11 @@ meta_get_option_context (void)
{
GOptionContext *ctx;
if (setlocale (LC_ALL, "") == NULL)
meta_warning ("Locale not understood by C library, internationalization will not work\n");
bindtextdomain (GETTEXT_PACKAGE, MUTTER_LOCALEDIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
ctx = g_option_context_new (NULL);
g_option_context_add_main_entries (ctx, meta_options, GETTEXT_PACKAGE);
g_option_context_add_group (ctx, clutter_get_option_group_without_init ());
@ -306,9 +311,12 @@ static GSourceFuncs event_funcs = {
static void
meta_clutter_init (void)
{
if (!meta_get_use_core_devices ())
clutter_x11_enable_xinput ();
clutter_x11_set_display (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
clutter_x11_disable_event_retrieval ();
if (CLUTTER_INIT_SUCCESS == clutter_init (NULL, NULL))
{
GSource *source = g_source_new (&event_funcs, sizeof (GSource));
@ -385,9 +393,6 @@ meta_init (void)
sigset_t empty_mask;
GIOChannel *channel;
if (setlocale (LC_ALL, "") == NULL)
meta_warning ("Locale not understood by C library, internationalization will not work\n");
g_type_init ();
sigemptyset (&empty_mask);
@ -422,6 +427,8 @@ meta_init (void)
meta_set_verbose (TRUE);
if (g_getenv ("MUTTER_DEBUG"))
meta_set_debugging (TRUE);
if (g_getenv ("MUTTER_USE_CORE_DEVICES"))
meta_set_use_core_devices (TRUE);
if (g_get_home_dir ())
if (chdir (g_get_home_dir ()) < 0)
@ -430,10 +437,6 @@ meta_init (void)
meta_print_self_identity ();
bindtextdomain (GETTEXT_PACKAGE, MUTTER_LOCALEDIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE);
#ifdef HAVE_INTROSPECTION
g_irepository_prepend_search_path (MUTTER_PKGLIBDIR);
#endif
@ -573,10 +576,11 @@ meta_run (void)
void
meta_quit (MetaExitCode code)
{
meta_exit_code = code;
if (g_main_loop_is_running (meta_main_loop))
g_main_loop_quit (meta_main_loop);
{
meta_exit_code = code;
g_main_loop_quit (meta_main_loop);
}
}
/**

View File

@ -90,6 +90,7 @@ northwestcmp (gconstpointer a, gconstpointer b)
static void
find_next_cascade (MetaWindow *window,
MetaDevice *pointer,
MetaFrameGeometry *fgeom,
/* visible windows on relevant workspaces */
GList *windows,
@ -136,7 +137,7 @@ find_next_cascade (MetaWindow *window,
* of NW corner of window frame.
*/
current = meta_screen_get_current_monitor (window->screen);
current = meta_screen_get_current_monitor (window->screen, pointer);
meta_window_get_work_area_for_monitor (window, current->number, &work_area);
cascade_x = MAX (0, work_area.x);
@ -354,10 +355,17 @@ avoid_being_obscured_as_second_modal_dialog (MetaWindow *window,
* know about the modal-to-the-main-window part.
*/
MetaWindow *focus_window;
MetaWindow *focus_window = NULL;
MetaFocusInfo *focus_info;
MetaRectangle overlap;
MetaDevice *pointer, *keyboard;
focus_window = window->display->focus_window;
pointer = meta_window_guess_grab_pointer (window);
keyboard = meta_device_get_paired_device (pointer);
focus_info = meta_display_get_focus_info (window->display, keyboard);
if (focus_window)
focus_window = focus_info->focus_window;
if (window->denied_focus_and_not_transient &&
window->wm_state_modal && /* FIXME: Maybe do this for all transients? */
@ -660,6 +668,7 @@ meta_window_place (MetaWindow *window,
{
GList *windows;
const MetaMonitorInfo *xi;
MetaDevice *pointer, *keyboard;
/* frame member variables should NEVER be used in here, only
* MetaFrameGeometry. But remember fgeom == NULL
@ -671,7 +680,9 @@ meta_window_place (MetaWindow *window,
meta_topic (META_DEBUG_PLACEMENT, "Placing window %s\n", window->desc);
windows = NULL;
pointer = meta_window_guess_grab_pointer (window);
keyboard = meta_device_get_paired_device (pointer);
switch (window->type)
{
/* Run placement algorithm on these. */
@ -815,7 +826,7 @@ meta_window_place (MetaWindow *window,
int w, h;
/* Warning, this function is a round trip! */
xi = meta_screen_get_current_monitor (window->screen);
xi = meta_screen_get_current_monitor (window->screen, pointer);
w = xi->rect.width;
h = xi->rect.height;
@ -860,8 +871,8 @@ meta_window_place (MetaWindow *window,
}
/* Warning, this is a round trip! */
xi = meta_screen_get_current_monitor (window->screen);
xi = meta_screen_get_current_monitor (window->screen, pointer);
/* "Origin" placement algorithm */
x = xi->rect.x;
y = xi->rect.y;
@ -899,8 +910,8 @@ meta_window_place (MetaWindow *window,
/* If no placement has been done, revert to cascade to avoid
* fully overlapping window (e.g. starting multiple terminals)
* */
if (x == xi->rect.x && y == xi->rect.y)
find_next_cascade (window, fgeom, windows, x, y, &x, &y);
if (x == xi->rect.x && y == xi->rect.y)
find_next_cascade (window, pointer, fgeom, windows, x, y, &x, &y);
done_check_denied_focus:
/* If the window is being denied focus and isn't a transient of the
@ -913,8 +924,12 @@ meta_window_place (MetaWindow *window,
gboolean found_fit;
MetaWindow *focus_window;
MetaRectangle overlap;
MetaFocusInfo *focus_info;
focus_window = window->display->focus_window;
focus_info = meta_display_get_focus_info (window->display, keyboard);
g_assert (focus_info != NULL);
focus_window = focus_info->focus_window;
g_assert (focus_window != NULL);
/* No need to do anything if the window doesn't overlap at all */

View File

@ -90,7 +90,8 @@ struct _MetaScreen
MetaStack *stack;
MetaStackTracker *stack_tracker;
MetaCursor current_cursor;
/* per-pointer cursors */
GHashTable *cursors;
Window flash_window;
@ -158,8 +159,10 @@ void meta_screen_queue_frame_redraws (MetaScreen *scree
void meta_screen_queue_window_resizes (MetaScreen *screen);
void meta_screen_set_cursor (MetaScreen *screen,
MetaDevice *pointer,
MetaCursor cursor);
void meta_screen_update_cursor (MetaScreen *screen);
void meta_screen_update_cursor (MetaScreen *screen,
MetaDevice *pointer);
void meta_screen_tab_popup_create (MetaScreen *screen,
MetaTabList list_type,
@ -182,9 +185,11 @@ void meta_screen_tile_preview_update (MetaScreen *screen,
void meta_screen_tile_preview_hide (MetaScreen *screen);
MetaWindow* meta_screen_get_mouse_window (MetaScreen *screen,
MetaDevice *pointer,
MetaWindow *not_this_one);
const MetaMonitorInfo* meta_screen_get_current_monitor (MetaScreen *screen);
const MetaMonitorInfo* meta_screen_get_current_monitor (MetaScreen *screen,
MetaDevice *pointer);
const MetaMonitorInfo* meta_screen_get_monitor_for_rect (MetaScreen *screen,
MetaRectangle *rect);
const MetaMonitorInfo* meta_screen_get_monitor_for_window (MetaScreen *screen,

View File

@ -37,10 +37,12 @@
#include "workspace-private.h"
#include "keybindings-private.h"
#include "stack.h"
#include "core.h"
#include "xprops.h"
#include <meta/compositor.h>
#include "mutter-marshal.h"
#include "mutter-enum-types.h"
#include "device-pointer.h"
#ifdef HAVE_SOLARIS_XINERAMA
#include <X11/extensions/xinerama.h>
@ -349,6 +351,43 @@ set_wm_icon_size_hint (MetaScreen *screen)
#undef N_VALS
}
/* The list of monitors reported by the windowing system might include
* mirrored monitors with identical bounds. Since mirrored monitors
* shouldn't be treated as separate monitors for most purposes, we
* filter them out here. (We ignore the possibility of partially
* overlapping monitors because they are rare and it's hard to come
* up with any sensible interpretation.)
*/
static void
filter_mirrored_monitors (MetaScreen *screen)
{
int i, j;
/* Currently always true and simplifies things */
g_assert (screen->primary_monitor_index == 0);
for (i = 1; i < screen->n_monitor_infos; i++)
{
/* In case we've filtered previous monitors */
screen->monitor_infos[i].number = i;
for (j = 0; j < i; j++)
{
if (meta_rectangle_equal (&screen->monitor_infos[i].rect,
&screen->monitor_infos[j].rect))
{
memmove (&screen->monitor_infos[i],
&screen->monitor_infos[i + 1],
(screen->n_monitor_infos - i - 1) * sizeof (MetaMonitorInfo));
screen->n_monitor_infos--;
i--;
continue;
}
}
}
}
static void
reload_monitor_infos (MetaScreen *screen)
{
@ -538,6 +577,8 @@ reload_monitor_infos (MetaScreen *screen)
screen->monitor_infos[0].rect = screen->rect;
}
filter_mirrored_monitors (screen);
g_assert (screen->n_monitor_infos > 0);
g_assert (screen->monitor_infos != NULL);
}
@ -593,7 +634,6 @@ meta_screen_new (MetaDisplay *display,
MetaScreen *screen;
Window xroot;
Display *xdisplay;
XWindowAttributes attr;
Window new_wm_sn_owner;
Window current_wm_sn_owner;
gboolean replace_current_wm;
@ -708,15 +748,15 @@ meta_screen_new (MetaDisplay *display,
/* We need to or with the existing event mask since
* gtk+ may be interested in other events.
*/
XGetWindowAttributes (xdisplay, xroot, &attr);
XSelectInput (xdisplay,
xroot,
SubstructureRedirectMask | SubstructureNotifyMask |
ColormapChangeMask | PropertyChangeMask |
LeaveWindowMask | EnterWindowMask |
KeyPressMask | KeyReleaseMask |
FocusChangeMask | StructureNotifyMask |
ExposureMask | attr.your_event_mask);
meta_core_select_events (xdisplay, xroot,
(SubstructureRedirectMask | SubstructureNotifyMask |
ColormapChangeMask | PropertyChangeMask |
LeaveWindowMask | EnterWindowMask |
KeyPressMask | KeyReleaseMask |
FocusChangeMask | StructureNotifyMask |
ExposureMask),
TRUE);
if (meta_error_trap_pop_with_return (display) != Success)
{
meta_warning (_("Screen %d on display \"%s\" already has a window manager\n"),
@ -738,10 +778,10 @@ meta_screen_new (MetaDisplay *display,
screen->rect.x = screen->rect.y = 0;
screen->rect.width = WidthOfScreen (screen->xscreen);
screen->rect.height = HeightOfScreen (screen->xscreen);
screen->current_cursor = -1; /* invalid/unset */
screen->default_xvisual = DefaultVisualOfScreen (screen->xscreen);
screen->default_depth = DefaultDepthOfScreen (screen->xscreen);
screen->flash_window = None;
screen->cursors = g_hash_table_new (NULL, NULL);
screen->wm_sn_selection_window = new_wm_sn_owner;
screen->wm_sn_atom = wm_sn_atom;
@ -766,8 +806,6 @@ meta_screen_new (MetaDisplay *display,
screen->last_monitor_index = 0;
reload_monitor_infos (screen);
meta_screen_set_cursor (screen, META_CURSOR_DEFAULT);
/* Handle creating a no_focus_window for this screen */
screen->no_focus_window =
@ -902,7 +940,10 @@ meta_screen_free (MetaScreen *screen,
meta_stack_tracker_free (screen->stack_tracker);
meta_error_trap_push_with_return (screen->display);
XSelectInput (screen->display->xdisplay, screen->xroot, 0);
meta_core_select_events (screen->display->xdisplay,
screen->xroot, NoEventMask,
FALSE);
if (meta_error_trap_pop_with_return (screen->display) != Success)
meta_warning (_("Could not release screen %d on display \"%s\"\n"),
screen->number, screen->display->name);
@ -926,6 +967,8 @@ meta_screen_free (MetaScreen *screen,
g_free (screen->screen_name);
g_hash_table_destroy (screen->cursors);
g_object_unref (screen);
XFlush (display->xdisplay);
@ -1539,31 +1582,33 @@ update_focus_mode (MetaScreen *screen)
void
meta_screen_set_cursor (MetaScreen *screen,
MetaDevice *pointer,
MetaCursor cursor)
{
Cursor xcursor;
MetaCursor old_cursor;
if (cursor == screen->current_cursor)
old_cursor = GPOINTER_TO_UINT (g_hash_table_lookup (screen->cursors, pointer));
if (cursor == old_cursor)
return;
screen->current_cursor = cursor;
xcursor = meta_display_create_x_cursor (screen->display, cursor);
XDefineCursor (screen->display->xdisplay, screen->xroot, xcursor);
XFlush (screen->display->xdisplay);
XFreeCursor (screen->display->xdisplay, xcursor);
g_hash_table_insert (screen->cursors, pointer,
GUINT_TO_POINTER (cursor));
meta_screen_update_cursor (screen, pointer);
}
void
meta_screen_update_cursor (MetaScreen *screen)
meta_screen_update_cursor (MetaScreen *screen,
MetaDevice *pointer)
{
Cursor xcursor;
MetaCursor cursor;
xcursor = meta_display_create_x_cursor (screen->display,
screen->current_cursor);
XDefineCursor (screen->display->xdisplay, screen->xroot, xcursor);
cursor = GPOINTER_TO_UINT (g_hash_table_lookup (screen->cursors, pointer));
meta_device_pointer_set_window_cursor (META_DEVICE_POINTER (pointer),
screen->xroot,
cursor);
XFlush (screen->display->xdisplay);
XFreeCursor (screen->display->xdisplay, xcursor);
}
void
@ -1817,9 +1862,21 @@ static gboolean
meta_screen_tile_preview_update_timeout (gpointer data)
{
MetaScreen *screen = data;
MetaWindow *window = screen->display->grab_window;
MetaWindow *window = NULL;
gboolean composited = screen->display->compositor != NULL;
gboolean needs_preview = FALSE;
MetaGrabInfo *grab_info;
MetaDevice *pointer = NULL;
GHashTableIter iter;
/* FIXME: we're just handling the first grab we find */
g_hash_table_iter_init (&iter, screen->display->current_grabs);
if (g_hash_table_iter_next (&iter, NULL, (gpointer *) &grab_info))
{
window = grab_info->grab_window;
pointer = grab_info->grab_pointer;
}
screen->tile_preview_timeout_id = 0;
@ -1862,8 +1919,8 @@ meta_screen_tile_preview_update_timeout (gpointer data)
{
MetaRectangle tile_rect;
meta_window_get_current_tile_area (window, &tile_rect);
meta_tile_preview_show (screen->tile_preview, &tile_rect);
meta_window_get_current_tile_area (window, pointer, &tile_rect);
meta_tile_preview_show (screen->tile_preview, pointer, &tile_rect);
}
else
meta_tile_preview_hide (screen->tile_preview);
@ -1908,28 +1965,23 @@ meta_screen_tile_preview_hide (MetaScreen *screen)
MetaWindow*
meta_screen_get_mouse_window (MetaScreen *screen,
MetaDevice *pointer,
MetaWindow *not_this_one)
{
MetaWindow *window;
Window root_return, child_return;
int root_x_return, root_y_return;
int win_x_return, win_y_return;
unsigned int mask_return;
if (not_this_one)
meta_topic (META_DEBUG_FOCUS,
"Focusing mouse window excluding %s\n", not_this_one->desc);
meta_error_trap_push (screen->display);
XQueryPointer (screen->display->xdisplay,
screen->xroot,
&root_return,
&child_return,
&root_x_return,
&root_y_return,
&win_x_return,
&win_y_return,
&mask_return);
meta_device_pointer_query_position (META_DEVICE_POINTER (pointer),
screen->xroot,
NULL, NULL,
&root_x_return,
&root_y_return,
NULL, NULL, NULL);
meta_error_trap_pop (screen->display);
window = meta_stack_get_default_focus_window_at_point (screen->stack,
@ -2025,6 +2077,7 @@ meta_screen_get_natural_monitor_list (MetaScreen *screen,
const MetaMonitorInfo* current;
const MetaMonitorInfo* tmp;
GQueue* monitor_queue;
MetaDevice *pointer;
int* visited;
int cur = 0;
int i;
@ -2032,6 +2085,9 @@ meta_screen_get_natural_monitor_list (MetaScreen *screen,
*n_monitors = screen->n_monitor_infos;
*monitors_list = g_new (int, screen->n_monitor_infos);
pointer = meta_device_map_lookup (screen->display->device_map,
META_CORE_POINTER_ID);
/* we calculate a natural ordering by which to choose monitors for
* window placement. We start at the current monitor, and perform
* a breadth-first search of the monitors starting from that
@ -2046,7 +2102,7 @@ meta_screen_get_natural_monitor_list (MetaScreen *screen,
visited[i] = FALSE;
}
current = meta_screen_get_current_monitor (screen);
current = meta_screen_get_current_monitor (screen, pointer);
monitor_queue = g_queue_new ();
g_queue_push_tail (monitor_queue, (gpointer) current);
visited[current->number] = TRUE;
@ -2113,7 +2169,8 @@ meta_screen_get_natural_monitor_list (MetaScreen *screen,
}
const MetaMonitorInfo*
meta_screen_get_current_monitor (MetaScreen *screen)
meta_screen_get_current_monitor (MetaScreen *screen,
MetaDevice *pointer)
{
if (screen->n_monitor_infos == 1)
return &screen->monitor_infos[0];
@ -2123,24 +2180,18 @@ meta_screen_get_current_monitor (MetaScreen *screen)
if (screen->display->monitor_cache_invalidated)
{
Window root_return, child_return;
int win_x_return, win_y_return;
unsigned int mask_return;
int i;
MetaRectangle pointer_position;
screen->display->monitor_cache_invalidated = FALSE;
pointer_position.width = pointer_position.height = 1;
XQueryPointer (screen->display->xdisplay,
screen->xroot,
&root_return,
&child_return,
&pointer_position.x,
&pointer_position.y,
&win_x_return,
&win_y_return,
&mask_return);
meta_device_pointer_query_position (META_DEVICE_POINTER (pointer),
screen->xroot,
NULL, NULL,
&pointer_position.x,
&pointer_position.y,
NULL, NULL, NULL);
screen->last_monitor_index = 0;
for (i = 0; i < screen->n_monitor_infos; i++)
@ -3007,17 +3058,22 @@ static gboolean startup_sequence_timeout (void *data);
static void
update_startup_feedback (MetaScreen *screen)
{
MetaDevice *pointer;
pointer = meta_device_map_lookup (screen->display->device_map,
META_CORE_POINTER_ID);
if (screen->startup_sequences != NULL)
{
meta_topic (META_DEBUG_STARTUP,
"Setting busy cursor\n");
meta_screen_set_cursor (screen, META_CURSOR_BUSY);
meta_screen_set_cursor (screen, pointer, META_CURSOR_BUSY);
}
else
{
meta_topic (META_DEBUG_STARTUP,
"Setting default cursor\n");
meta_screen_set_cursor (screen, META_CURSOR_DEFAULT);
meta_screen_set_cursor (screen, pointer, META_CURSOR_DEFAULT);
}
}

View File

@ -308,13 +308,16 @@ meta_session_init (const char *previous_client_id,
*/
char hint = SmRestartIfRunning;
char priority = 20; /* low to run before other apps */
const char *prgname;
prgname = g_get_prgname ();
prop1.name = SmProgram;
prop1.type = SmARRAY8;
prop1.num_vals = 1;
prop1.vals = &prop1val;
prop1val.value = "mutter";
prop1val.length = strlen ("mutter");
prop1val.value = (char *)prgname;
prop1val.length = strlen (prgname);
/* twm sets getuid() for this, but the SM spec plainly
* says pw_name, twm is on crack
@ -573,6 +576,9 @@ set_clone_restart_commands (void)
char *discardv[10];
int i;
SmProp prop1, prop2, prop3, *props[3];
const char *prgname;
prgname = g_get_prgname ();
/* Restart (use same client ID) */
@ -582,7 +588,7 @@ set_clone_restart_commands (void)
g_return_if_fail (client_id);
i = 0;
restartv[i] = "mutter";
restartv[i] = (char *)prgname;
++i;
restartv[i] = "--sm-client-id";
++i;
@ -603,7 +609,7 @@ set_clone_restart_commands (void)
/* Clone (no client ID) */
i = 0;
clonev[i] = "mutter";
clonev[i] = (char *)prgname;
++i;
clonev[i] = NULL;

View File

@ -211,13 +211,23 @@ meta_stack_thaw (MetaStack *stack)
stack_sync_to_server (stack);
}
typedef struct _FocusedForeachData FocusedForeachData;
struct _FocusedForeachData
{
MetaWindow *window;
gboolean focused_transient;
};
static gboolean
is_focused_foreach (MetaWindow *window,
void *data)
{
if (window == window->display->expected_focus_window)
FocusedForeachData *focused_data = data;
if (window == focused_data->window)
{
*((gboolean*) data) = TRUE;
focused_data->focused_transient = TRUE;
return FALSE;
}
return TRUE;
@ -240,6 +250,9 @@ get_standalone_layer (MetaWindow *window)
{
MetaStackLayer layer;
gboolean focused_transient = FALSE;
MetaFocusInfo *focus_info;
MetaDevice *keyboard;
FocusedForeachData focused_data = { 0 };
switch (window->type)
{
@ -263,20 +276,30 @@ get_standalone_layer (MetaWindow *window)
case META_WINDOW_OVERRIDE_OTHER:
layer = META_LAYER_OVERRIDE_REDIRECT;
break;
default:
default:
/* FIXME: How about other keyboards? should
* we allow fullscreen for non-VCP/K anyway?
*/
keyboard = meta_device_map_lookup (window->display->device_map,
META_CORE_KEYBOARD_ID);
focus_info = meta_display_get_focus_info (window->display, keyboard);
focused_data.window = focus_info->expected_focus_window;
meta_window_foreach_transient (window,
is_focused_foreach,
&focused_transient);
&focused_data);
if (window->wm_state_below)
layer = META_LAYER_BOTTOM;
else if (window->fullscreen &&
(focused_transient ||
window == window->display->expected_focus_window ||
window->display->expected_focus_window == NULL ||
(window->display->expected_focus_window != NULL &&
!focus_info ||
window == focus_info->expected_focus_window ||
focus_info->expected_focus_window == NULL ||
(focus_info->expected_focus_window != NULL &&
windows_on_different_monitor (window,
window->display->expected_focus_window))))
focus_info->expected_focus_window))))
layer = META_LAYER_FULLSCREEN;
else if (window->wm_state_above)
layer = META_LAYER_TOP;

View File

@ -81,6 +81,7 @@ meta_print_backtrace (void)
static gint verbose_topics = 0;
static gboolean is_debugging = FALSE;
static gboolean replace_current = FALSE;
static gboolean use_core_devices = FALSE;
static int no_prefix = 0;
#ifdef WITH_VERBOSE_MODE
@ -209,6 +210,18 @@ meta_set_debugging (gboolean setting)
is_debugging = setting;
}
gboolean
meta_get_use_core_devices (void)
{
return use_core_devices;
}
void
meta_set_use_core_devices (gboolean setting)
{
use_core_devices = setting;
}
gboolean
meta_get_replace_current_wm (void)
{
@ -584,6 +597,25 @@ meta_gravity_to_string (int gravity)
}
}
/* Command line arguments are passed in the locale encoding; in almost
* all cases, we'd hope that is UTF-8 and no conversion is necessary.
* If it's not UTF-8, then it's possible that the message isn't
* representable in the locale encoding.
*/
static void
append_argument (GPtrArray *args,
const char *arg)
{
char *locale_arg = g_locale_from_utf8 (arg, -1, NULL, NULL, NULL);
/* This is cheesy, but it's better to have a few ???'s in the dialog
* for an unresponsive application than no dialog at all appear */
if (!locale_arg)
locale_arg = g_strdup ("???");
g_ptr_array_add (args, locale_arg);
}
GPid
meta_show_dialog (const char *type,
const char *message,
@ -597,59 +629,57 @@ meta_show_dialog (const char *type,
{
GError *error = NULL;
GSList *tmp;
int i=0;
GPid child_pid;
const char **argvl = g_malloc(sizeof (char*) *
(17 +
g_slist_length (columns)*2 +
g_slist_length (entries)));
GPtrArray *args;
argvl[i++] = "zenity";
argvl[i++] = type;
argvl[i++] = "--display";
argvl[i++] = display;
argvl[i++] = "--class";
argvl[i++] = "mutter-dialog";
argvl[i++] = "--title";
args = g_ptr_array_new ();
append_argument (args, "zenity");
append_argument (args, type);
append_argument (args, "--display");
append_argument (args, display);
append_argument (args, "--class");
append_argument (args, "mutter-dialog");
append_argument (args, "--title");
/* Translators: This is the title used on dialog boxes */
argvl[i++] = _("Mutter");
argvl[i++] = "--text";
argvl[i++] = message;
append_argument (args, _("Mutter"));
append_argument (args, "--text");
append_argument (args, message);
if (timeout)
{
argvl[i++] = "--timeout";
argvl[i++] = timeout;
append_argument (args, "--timeout");
append_argument (args, timeout);
}
if (ok_text)
{
argvl[i++] = "--ok-label";
argvl[i++] = ok_text;
append_argument (args, "--ok-label");
append_argument (args, ok_text);
}
if (cancel_text)
{
argvl[i++] = "--cancel-label";
argvl[i++] = cancel_text;
append_argument (args, "--cancel-label");
append_argument (args, cancel_text);
}
tmp = columns;
while (tmp)
{
argvl[i++] = "--column";
argvl[i++] = tmp->data;
append_argument (args, "--column");
append_argument (args, tmp->data);
tmp = tmp->next;
}
tmp = entries;
while (tmp)
{
argvl[i++] = tmp->data;
append_argument (args, tmp->data);
tmp = tmp->next;
}
argvl[i] = NULL;
g_ptr_array_add (args, NULL); /* NULL-terminate */
if (transient_for)
{
@ -660,7 +690,7 @@ meta_show_dialog (const char *type,
g_spawn_async (
"/",
(gchar**) argvl, /* ugh */
(gchar**) args->pdata,
NULL,
G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
NULL, NULL,
@ -671,7 +701,7 @@ meta_show_dialog (const char *type,
if (transient_for)
unsetenv ("WINDOWID");
g_free (argvl);
g_ptr_array_free (args, TRUE);
if (error)
{

View File

@ -42,6 +42,7 @@
#include "stack.h"
#include "iconcache.h"
#include <X11/Xutil.h>
#include <cairo.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
typedef struct _MetaWindowQueue MetaWindowQueue;
@ -98,6 +99,7 @@ struct _MetaWindow
char *wm_client_machine;
char *startup_id;
char *mutter_hints;
char *gtk_theme_variant;
int net_wm_pid;
@ -105,6 +107,10 @@ struct _MetaWindow
Window xgroup_leader;
Window xclient_leader;
/* window menu if any, and the pointer that popped it up */
MetaWindowMenu *menu;
MetaDevice *menu_device;
/* Initial workspace property */
int initial_workspace;
@ -316,6 +322,15 @@ struct _MetaWindow
/* if TRUE, application is buggy and SYNC resizing is turned off */
guint disable_sync : 1;
/* if TRUE, window didn't yet get the FocusIn for window->focus_keyboard */
guint expecting_focus_in : 1;
/* Keyboard currently owning the window focus, or NULL */
MetaDevice *focus_keyboard;
/* if non-NULL, the bounds of the window frame */
cairo_region_t *frame_bounds;
/* Note: can be NULL */
GSList *struts;
@ -390,6 +405,12 @@ struct _MetaWindow
/* Focused window that is (directly or indirectly) attached to this one */
MetaWindow *attached_focus_window;
/* Current grab op for this window, or NULL */
MetaGrabInfo *cur_grab;
/* Focus info if the window is focused, or NULL */
MetaFocusInfo *cur_focus;
};
struct _MetaWindowClass
@ -559,6 +580,7 @@ void meta_window_set_current_workspace_hint (MetaWindow *window);
unsigned long meta_window_get_net_wm_desktop (MetaWindow *window);
void meta_window_show_menu (MetaWindow *window,
MetaDevice *device,
int root_x,
int root_y,
int button,
@ -587,6 +609,7 @@ void meta_window_get_work_area_all_monitors (MetaWindow *window,
MetaRectangle *area);
void meta_window_get_current_tile_area (MetaWindow *window,
MetaDevice *device,
MetaRectangle *tile_area);
@ -608,13 +631,16 @@ void meta_window_free_delete_dialog (MetaWindow *window);
void meta_window_begin_grab_op (MetaWindow *window,
MetaDevice *device,
MetaGrabOp op,
gboolean frame_action,
guint32 timestamp);
void meta_window_update_keyboard_resize (MetaWindow *window,
MetaDevice *device,
gboolean update_cursor);
void meta_window_update_keyboard_move (MetaWindow *window);
void meta_window_update_keyboard_move (MetaWindow *window,
MetaDevice *device);
void meta_window_update_layer (MetaWindow *window);
@ -636,6 +662,13 @@ void meta_window_update_monitor (MetaWindow *window);
void meta_window_update_on_all_workspaces (MetaWindow *window);
void meta_window_propagate_focus_appearance (MetaWindow *window,
MetaDevice *keyboard,
gboolean focused);
void meta_window_set_client_pointer (MetaWindow *window,
MetaDevice *pointer);
MetaDevice * meta_window_get_client_pointer (MetaWindow *window);
MetaDevice * meta_window_guess_grab_pointer (MetaWindow *window);
#endif

View File

@ -845,6 +845,8 @@ reload_wm_class (MetaWindow *window,
if (value->v.class_hint.res_class)
window->res_class = g_strdup (value->v.class_hint.res_class);
g_object_notify (G_OBJECT (window), "wm-class");
}
meta_verbose ("Window %s class: '%s' name: '%s'\n",
@ -1466,8 +1468,12 @@ reload_transient_for (MetaWindow *window,
MetaPropValue *value,
gboolean initial)
{
if (window->has_focus && window->xtransient_for != None)
meta_window_propagate_focus_appearance (window, FALSE);
MetaWindow *parent = NULL;
if (meta_window_appears_focused (window) && window->xtransient_for != None)
meta_window_propagate_focus_appearance (window,
window->focus_keyboard,
FALSE);
window->xtransient_for = None;
@ -1475,14 +1481,33 @@ reload_transient_for (MetaWindow *window,
window->xtransient_for = value->v.xwindow;
/* Make sure transient_for is valid */
if (window->xtransient_for != None &&
meta_display_lookup_x_window (window->display,
window->xtransient_for) == NULL)
if (window->xtransient_for != None)
{
meta_warning (_("Invalid WM_TRANSIENT_FOR window 0x%lx specified "
"for %s.\n"),
window->xtransient_for, window->desc);
window->xtransient_for = None;
parent = meta_display_lookup_x_window (window->display,
window->xtransient_for);
if (!parent)
{
meta_warning (_("Invalid WM_TRANSIENT_FOR window 0x%lx specified "
"for %s.\n"),
window->xtransient_for, window->desc);
window->xtransient_for = None;
}
}
/* Make sure there is not a loop */
while (parent)
{
if (parent == window)
{
meta_warning (_("WM_TRANSIENT_FOR window 0x%lx for %s "
"would create loop.\n"),
window->xtransient_for, window->desc);
window->xtransient_for = None;
break;
}
parent = meta_display_lookup_x_window (parent->display,
parent->xtransient_for);
}
window->transient_parent_is_root_window =
@ -1513,8 +1538,39 @@ reload_transient_for (MetaWindow *window,
if (!window->constructing && !window->override_redirect)
meta_window_queue (window, META_QUEUE_MOVE_RESIZE);
if (window->has_focus && window->xtransient_for != None)
meta_window_propagate_focus_appearance (window, TRUE);
if (meta_window_appears_focused (window) && window->xtransient_for != None)
meta_window_propagate_focus_appearance (window,
window->focus_keyboard,
TRUE);
}
static void
reload_gtk_theme_variant (MetaWindow *window,
MetaPropValue *value,
gboolean initial)
{
char *requested_variant = NULL;
char *current_variant = window->gtk_theme_variant;
if (value->type != META_PROP_VALUE_INVALID)
{
requested_variant = value->v.str;
meta_verbose ("Requested \"%s\" theme variant for window %s.\n",
requested_variant, window->desc);
}
if (g_strcmp0 (requested_variant, current_variant))
{
g_free (current_variant);
if (requested_variant)
window->gtk_theme_variant = g_strdup (requested_variant);
else
window->gtk_theme_variant = NULL;
if (window->frame)
meta_ui_update_frame_style (window->screen->ui, window->frame->xwindow);
}
}
/**
@ -1569,6 +1625,7 @@ meta_display_init_window_prop_hooks (MetaDisplay *display)
{ display->atom__NET_WM_STATE, META_PROP_VALUE_ATOM_LIST, reload_net_wm_state, TRUE, FALSE },
{ display->atom__MOTIF_WM_HINTS, META_PROP_VALUE_MOTIF_HINTS, reload_mwm_hints, TRUE, FALSE },
{ XA_WM_TRANSIENT_FOR, META_PROP_VALUE_WINDOW, reload_transient_for, TRUE, FALSE },
{ display->atom__GTK_THEME_VARIANT, META_PROP_VALUE_UTF8, reload_gtk_theme_variant, TRUE, FALSE },
{ display->atom__NET_WM_USER_TIME_WINDOW, META_PROP_VALUE_WINDOW, reload_net_wm_user_time_window, TRUE, FALSE },
{ display->atom_WM_STATE, META_PROP_VALUE_INVALID, NULL, FALSE, FALSE },
{ display->atom__NET_WM_ICON, META_PROP_VALUE_INVALID, reload_net_wm_icon, FALSE, FALSE },

File diff suppressed because it is too large Load Diff

View File

@ -85,6 +85,7 @@ GList* meta_workspace_get_onmonitor_region (MetaWorkspace *workspace,
int which_monitor);
void meta_workspace_focus_default_window (MetaWorkspace *workspace,
MetaDevice *pointer,
MetaWindow *not_this_one,
guint32 timestamp);

View File

@ -538,7 +538,9 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace,
MetaWorkspaceLayout layout1, layout2;
gint num_workspaces, current_space, new_space;
MetaMotionDirection direction;
MetaGrabInfo *grab_info;
GHashTableIter iter;
meta_verbose ("Activating workspace %d\n",
meta_workspace_index (workspace));
@ -547,7 +549,7 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace,
/* Free any cached pointers to the workspaces's edges from
* a current resize or move operation */
meta_display_cleanup_edges (workspace->screen->display);
meta_display_cleanup_edges (workspace->screen->display, workspace->screen);
if (workspace->screen->active_workspace)
workspace_switch_sound (workspace->screen->active_workspace, workspace);
@ -570,10 +572,22 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace,
return;
move_window = NULL;
if (workspace->screen->display->grab_op == META_GRAB_OP_MOVING ||
workspace->screen->display->grab_op == META_GRAB_OP_KEYBOARD_MOVING)
move_window = workspace->screen->display->grab_window;
/* FIXME: not quite multidevice friendly, but the whole
* "move window to another workspace" isn't.
*/
g_hash_table_iter_init (&iter, workspace->screen->display->current_grabs);
while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &grab_info))
{
if (grab_info->grab_op == META_GRAB_OP_MOVING ||
grab_info->grab_op == META_GRAB_OP_KEYBOARD_MOVING)
{
move_window = grab_info->grab_window;
break;
}
}
if (move_window != NULL)
{
if (move_window->on_all_workspaces)
@ -673,8 +687,13 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace,
}
else
{
MetaDevice *pointer;
pointer = meta_device_map_lookup (screen->display->device_map,
META_CORE_POINTER_ID);
meta_topic (META_DEBUG_FOCUS, "Focusing default window on new workspace\n");
meta_workspace_focus_default_window (workspace, NULL, timestamp);
meta_workspace_focus_default_window (workspace, pointer,
NULL, timestamp);
}
/* Emit switched signal from screen.c */
@ -774,7 +793,7 @@ meta_workspace_invalidate_work_area (MetaWorkspace *workspace)
/* If we are in the middle of a resize or move operation, we
* might have cached pointers to the workspace's edges */
if (workspace == workspace->screen->active_workspace)
meta_display_cleanup_edges (workspace->screen->display);
meta_display_cleanup_edges (workspace->screen->display, workspace->screen);
g_free (workspace->work_area_monitor);
workspace->work_area_monitor = NULL;
@ -1191,6 +1210,7 @@ meta_workspace_get_name (MetaWorkspace *workspace)
void
meta_workspace_focus_default_window (MetaWorkspace *workspace,
MetaDevice *pointer,
MetaWindow *not_this_one,
guint32 timestamp)
{
@ -1207,7 +1227,8 @@ meta_workspace_focus_default_window (MetaWorkspace *workspace,
else
{
MetaWindow * window;
window = meta_screen_get_mouse_window (workspace->screen, not_this_one);
window = meta_screen_get_mouse_window (workspace->screen,
pointer, not_this_one);
if (window &&
window->type != META_WINDOW_DOCK &&
window->type != META_WINDOW_DESKTOP)

View File

@ -58,6 +58,7 @@ item(_MUTTER_RELOAD_THEME_MESSAGE)
item(_MUTTER_SET_KEYBINDINGS_MESSAGE)
item(_MUTTER_TOGGLE_VERBOSE)
item(_MUTTER_HINTS)
item(_GTK_THEME_VARIANT)
item(_GNOME_WM_KEYBINDINGS)
item(_GNOME_PANEL_ACTION)
item(_GNOME_PANEL_ACTION_MAIN_MENU)

46
src/meta/device-map.h Normal file
View File

@ -0,0 +1,46 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* 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_H
#define META_DEVICE_MAP_H
#include <glib-object.h>
#include <meta/types.h>
#include <meta/device.h>
#define META_TYPE_DEVICE_MAP (meta_device_map_get_type ())
#define META_DEVICE_MAP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_DEVICE_MAP, MetaDeviceMap))
#define META_DEVICE_MAP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_DEVICE_MAP, MetaDeviceMapClass))
#define META_IS_DEVICE_MAP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_DEVICE_MAP))
#define META_IS_DEVICE_MAP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_DEVICE_MAP))
#define META_DEVICE_MAP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_DEVICE_MAP, MetaDeviceMapClass))
typedef struct _MetaDeviceMapClass MetaDeviceMapClass;
GType meta_device_map_get_type (void) G_GNUC_CONST;
MetaDevice * meta_device_map_lookup (MetaDeviceMap *device_map,
gint device_id);
MetaDisplay * meta_device_map_get_display (MetaDeviceMap *device_map);
GList * meta_device_map_list_devices (MetaDeviceMap *device_map);
#endif

44
src/meta/device.h Normal file
View File

@ -0,0 +1,44 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* 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_H
#define META_DEVICE_H
#include <glib-object.h>
#include <meta/types.h>
#define META_TYPE_DEVICE (meta_device_get_type ())
#define META_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_DEVICE, MetaDevice))
#define META_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_DEVICE, MetaDeviceClass))
#define META_IS_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_DEVICE))
#define META_IS_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_DEVICE))
#define META_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_DEVICE, MetaDeviceClass))
typedef struct _MetaDeviceClass MetaDeviceClass;
GType meta_device_get_type (void) G_GNUC_CONST;
int meta_device_get_id (MetaDevice *device);
MetaDisplay *meta_device_get_display (MetaDevice *device);
MetaDevice * meta_device_get_paired_device (MetaDevice *device);
#endif

View File

@ -28,6 +28,7 @@
#include <meta/types.h>
#include <meta/prefs.h>
#include <meta/common.h>
#include <meta/device-map.h>
typedef enum
{
@ -74,6 +75,9 @@ gboolean meta_display_has_shape (MetaDisplay *display);
MetaScreen *meta_display_screen_for_root (MetaDisplay *display,
Window xroot);
MetaWindow *meta_display_get_keyboard_focus_window (MetaDisplay *display,
MetaDevice *keyboard);
MetaWindow *meta_display_get_focus_window (MetaDisplay *display);
gboolean meta_display_xwindow_is_a_no_focus_window (MetaDisplay *display,
@ -108,9 +112,30 @@ MetaWindow* meta_display_get_tab_current (MetaDisplay *display,
MetaScreen *screen,
MetaWorkspace *workspace);
GList* meta_display_get_device_tab_list (MetaDisplay *display,
MetaTabList type,
MetaScreen *screen,
MetaWorkspace *workspace,
MetaDevice *device);
MetaWindow* meta_display_get_device_tab_next (MetaDisplay *display,
MetaTabList type,
MetaScreen *screen,
MetaWorkspace *workspace,
MetaWindow *window,
MetaDevice *device,
gboolean backward);
MetaWindow* meta_display_get_device_tab_current (MetaDisplay *display,
MetaTabList type,
MetaScreen *screen,
MetaWorkspace *workspace,
MetaDevice *device);
gboolean meta_display_begin_grab_op (MetaDisplay *display,
MetaScreen *screen,
MetaWindow *window,
MetaDevice *device,
MetaGrabOp op,
gboolean pointer_already_grabbed,
gboolean frame_action,
@ -120,14 +145,28 @@ gboolean meta_display_begin_grab_op (MetaDisplay *display,
int root_x,
int root_y);
void meta_display_end_grab_op (MetaDisplay *display,
MetaDevice *device,
guint32 timestamp);
MetaGrabOp meta_display_get_grab_op (MetaDisplay *display);
MetaGrabOp meta_display_get_device_grab_op (MetaDisplay *display,
MetaDevice *device);
MetaKeyBindingAction meta_display_get_keybinding_action (MetaDisplay *display,
unsigned int keycode,
unsigned long mask);
void meta_display_set_keyboard_focus (MetaDisplay *display,
MetaWindow *window,
MetaDevice *keyboard,
gboolean focus_frame,
guint32 timestamp);
void meta_display_unset_keyboard_focus (MetaDisplay *display,
MetaScreen *screen,
MetaDevice *keyboard,
guint32 timestamp);
/* meta_display_set_input_focus_window is like XSetInputFocus, except
* that (a) it can't detect timestamps later than the current time,
* since Mutter isn't part of the XServer, and thus gives erroneous
@ -155,4 +194,6 @@ GSList *meta_display_sort_windows_by_stacking (MetaDisplay *display,
Window meta_display_get_leader_window (MetaDisplay *display);
MetaDeviceMap * meta_display_get_device_map (MetaDisplay *display);
#endif

View File

@ -37,19 +37,19 @@ typedef enum
GdkPixbuf* meta_gradient_create_simple (int width,
int height,
const GdkColor *from,
const GdkColor *to,
const GdkRGBA *from,
const GdkRGBA *to,
MetaGradientType style);
GdkPixbuf* meta_gradient_create_multi (int width,
int height,
const GdkColor *colors,
const GdkRGBA *colors,
int n_colors,
MetaGradientType style);
GdkPixbuf* meta_gradient_create_interwoven (int width,
int height,
const GdkColor colors1[2],
const GdkRGBA colors1[2],
int thickness1,
const GdkColor colors2[2],
const GdkRGBA colors2[2],
int thickness2);

View File

@ -67,6 +67,10 @@ void meta_keybindings_switch_window (MetaDisplay *display,
MetaKeyBinding *binding);
void meta_screen_ungrab_all_keys (MetaScreen *screen, guint32 timestamp);
gboolean meta_screen_grab_all_keys (MetaScreen *screen, guint32 timestamp);
void meta_screen_ungrab_all_keys (MetaScreen *screen,
MetaDevice *device,
guint32 timestamp);
gboolean meta_screen_grab_all_keys (MetaScreen *screen,
MetaDevice *device,
guint32 timestamp);
#endif

View File

@ -32,6 +32,8 @@ typedef struct _MetaFrame MetaFrame;
typedef struct _MetaScreen MetaScreen;
typedef struct _MetaWindow MetaWindow;
typedef struct _MetaWorkspace MetaWorkspace;
typedef struct _MetaDevice MetaDevice;
typedef struct _MetaDeviceMap MetaDeviceMap;
/**
* MetaGroup: (skip)
*

View File

@ -38,6 +38,9 @@ gboolean meta_is_syncing (void);
void meta_set_syncing (gboolean setting);
void meta_set_replace_current_wm (gboolean setting);
gboolean meta_get_use_core_devices (void);
void meta_set_use_core_devices (gboolean setting);
void meta_debug_spew_real (const char *format,
...) G_GNUC_PRINTF (1, 2);
void meta_verbose_real (const char *format,

View File

@ -23,6 +23,7 @@
#define META_WINDOW_H
#include <glib-object.h>
#include <cairo.h>
#include <X11/Xlib.h>
#include <meta/boxes.h>
@ -156,4 +157,6 @@ const char *meta_window_get_mutter_hints (MetaWindow *window);
MetaFrameType meta_window_get_frame_type (MetaWindow *window);
cairo_region_t *meta_window_get_frame_bounds (MetaWindow *window);
#endif

View File

@ -682,7 +682,7 @@ desktop_cb (GtkAction *action,
{
GtkWidget *window;
GtkWidget *label;
GdkColor desktop_color;
GdkRGBA desktop_color;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
set_gtk_window_type (GTK_WINDOW (window), "_NET_WM_WINDOW_TYPE_DESKTOP");
@ -691,11 +691,12 @@ desktop_cb (GtkAction *action,
gdk_screen_width (), gdk_screen_height ());
gtk_window_move (GTK_WINDOW (window), 0, 0);
desktop_color.red = 0x5144;
desktop_color.green = 0x75D6;
desktop_color.blue = 0xA699;
desktop_color.red = 0.32;
desktop_color.green = 0.46;
desktop_color.blue = 0.65;
desktop_color.alpha = 1.0;
gtk_widget_modify_bg (window, GTK_STATE_NORMAL, &desktop_color);
gtk_widget_override_background_color (window, 0, &desktop_color);
label = focus_label (window);

View File

@ -26,6 +26,7 @@
*/
#include "draw-workspace.h"
#include "theme-private.h"
static void
@ -70,13 +71,13 @@ draw_window (GtkWidget *widget,
cairo_t *cr,
const WnckWindowDisplayInfo *win,
const GdkRectangle *winrect,
GtkStateType state)
GtkStateFlags state)
{
GdkPixbuf *icon;
int icon_x, icon_y, icon_w, icon_h;
gboolean is_active;
GdkColor *color;
GtkStyle *style;
GdkRGBA color;
GtkStyleContext *style;
is_active = win->is_active;
@ -85,15 +86,12 @@ draw_window (GtkWidget *widget,
cairo_rectangle (cr, winrect->x, winrect->y, winrect->width, winrect->height);
cairo_clip (cr);
style = gtk_widget_get_style (widget);
style = gtk_widget_get_style_context (widget);
if (is_active)
color = &style->light[state];
meta_gtk_style_get_light_color (style, state, &color);
else
color = &style->bg[state];
cairo_set_source_rgb (cr,
color->red / 65535.,
color->green / 65535.,
color->blue / 65535.);
gtk_style_context_get_background_color (style, state, &color);
gdk_cairo_set_source_rgba (cr, &color);
cairo_rectangle (cr,
winrect->x + 1, winrect->y + 1,
@ -144,15 +142,8 @@ draw_window (GtkWidget *widget,
cairo_restore (cr);
}
if (is_active)
color = &style->fg[state];
else
color = &style->fg[state];
cairo_set_source_rgb (cr,
color->red / 65535.,
color->green / 65535.,
color->blue / 65535.);
gtk_style_context_get_color (style, state, &color);
gdk_cairo_set_source_rgba (cr, &color);
cairo_set_line_width (cr, 1.0);
cairo_rectangle (cr,
winrect->x + 0.5, winrect->y + 0.5,
@ -178,8 +169,8 @@ wnck_draw_workspace (GtkWidget *widget,
{
int i;
GdkRectangle workspace_rect;
GtkStateType state;
GtkStyle *style;
GtkStateFlags state;
GtkStyleContext *style;
workspace_rect.x = x;
workspace_rect.y = y;
@ -187,13 +178,13 @@ wnck_draw_workspace (GtkWidget *widget,
workspace_rect.height = height;
if (is_active)
state = GTK_STATE_SELECTED;
state = GTK_STATE_FLAG_SELECTED;
else if (workspace_background)
state = GTK_STATE_PRELIGHT;
state = GTK_STATE_FLAG_PRELIGHT;
else
state = GTK_STATE_NORMAL;
state = GTK_STATE_FLAG_NORMAL;
style = gtk_widget_get_style (widget);
style = gtk_widget_get_style_context (widget);
cairo_save (cr);
@ -204,7 +195,10 @@ wnck_draw_workspace (GtkWidget *widget,
}
else
{
gdk_cairo_set_source_color (cr, &style->dark[state]);
GdkRGBA color;
meta_gtk_style_get_dark_color (style,state, &color);
gdk_cairo_set_source_rgba (cr, &color);
cairo_rectangle (cr, x, y, width, height);
cairo_fill (cr);
}

View File

@ -25,6 +25,7 @@
#include <config.h>
#include <math.h>
#include <string.h>
#include <meta/boxes.h>
#include "frames.h"
#include <meta/util.h>
@ -51,6 +52,7 @@ static void meta_frames_unmap (GtkWidget *widget);
static void meta_frames_update_prelit_control (MetaFrames *frames,
MetaUIFrame *frame,
GdkDevice *device,
MetaFrameControl control);
static gboolean meta_frames_button_press_event (GtkWidget *widget,
GdkEventButton *event);
@ -187,6 +189,74 @@ prefs_changed_callback (MetaPreference pref,
}
}
static GtkStyleContext *
create_style_context (MetaFrames *frames,
const gchar *variant)
{
GtkStyleContext *style;
GdkScreen *screen;
char *theme_name;
screen = gtk_widget_get_screen (GTK_WIDGET (frames));
g_object_get (gtk_settings_get_for_screen (screen),
"gtk-theme-name", &theme_name,
NULL);
style = gtk_style_context_new ();
gtk_style_context_set_path (style,
gtk_widget_get_path (GTK_WIDGET (frames)));
if (theme_name && *theme_name)
{
GtkCssProvider *provider;
provider = gtk_css_provider_get_named (theme_name, variant);
gtk_style_context_add_provider (style,
GTK_STYLE_PROVIDER (provider),
GTK_STYLE_PROVIDER_PRIORITY_THEME);
}
g_free (theme_name);
return style;
}
static GtkStyleContext *
meta_frames_get_theme_variant (MetaFrames *frames,
const gchar *variant)
{
GtkStyleContext *style;
style = g_hash_table_lookup (frames->style_variants, variant);
if (style == NULL)
{
style = create_style_context (frames, variant);
g_hash_table_insert (frames->style_variants, g_strdup (variant), style);
}
return style;
}
static void
update_style_contexts (MetaFrames *frames)
{
GtkStyleContext *style;
GList *variants, *variant;
if (frames->normal_style)
g_object_unref (frames->normal_style);
frames->normal_style = create_style_context (frames, NULL);
variants = g_hash_table_get_keys (frames->style_variants);
for (variant = variants; variant; variant = variants->next)
{
style = create_style_context (frames, (char *)variant->data);
g_hash_table_insert (frames->style_variants,
g_strdup (variant->data), style);
}
g_list_free (variants);
}
static void
meta_frames_init (MetaFrames *frames)
{
@ -202,6 +272,9 @@ meta_frames_init (MetaFrames *frames)
frames->invalidate_frames = NULL;
frames->cache = g_hash_table_new (g_direct_hash, g_direct_equal);
frames->style_variants = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, g_object_unref);
gtk_widget_set_double_buffered (GTK_WIDGET (frames), FALSE);
meta_prefs_add_listener (prefs_changed_callback, frames);
@ -241,6 +314,9 @@ meta_frames_destroy (GtkWidget *object)
}
g_slist_free (winlist);
g_object_unref (frames->normal_style);
g_hash_table_destroy (frames->style_variants);
GTK_WIDGET_CLASS (meta_frames_parent_class)->destroy (object);
}
@ -429,6 +505,8 @@ meta_frames_style_updated (GtkWidget *widget)
meta_frames_font_changed (frames);
update_style_contexts (frames);
g_hash_table_foreach (frames->frames,
reattach_style_func, frames);
@ -574,10 +652,23 @@ static void
meta_frames_attach_style (MetaFrames *frames,
MetaUIFrame *frame)
{
gboolean has_frame;
char *variant = NULL;
if (frame->style != NULL)
g_object_unref (frame->style);
frame->style = g_object_ref (gtk_widget_get_style_context (GTK_WIDGET (frames)));
meta_core_get (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
frame->xwindow,
META_CORE_WINDOW_HAS_FRAME, &has_frame,
META_CORE_GET_THEME_VARIANT, &variant,
META_CORE_GET_END);
if (variant == NULL || strcmp(variant, "normal") == 0)
frame->style = g_object_ref (frames->normal_style);
else
frame->style = g_object_ref (meta_frames_get_theme_variant (frames,
variant));
}
void
@ -596,7 +687,6 @@ meta_frames_manage_window (MetaFrames *frames,
gdk_window_set_user_data (frame->window, frames);
frame->style = NULL;
meta_frames_attach_style (frames, frame);
/* Don't set event mask here, it's in frame.c */
@ -636,10 +726,18 @@ meta_frames_unmanage_window (MetaFrames *frames,
*/
invalidate_all_caches (frames);
#if 0
/* This function is only called when destroying the frame
* in core/frame.c, ideally this should be done for every
* device with a cursor on the frame, but in practical
* effects it doesn't matter.
*/
/* restore the cursor */
meta_core_set_screen_cursor (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
frame->xwindow,
META_CURSOR_DEFAULT);
#endif
gdk_window_set_user_data (frame->window, NULL);
@ -764,6 +862,155 @@ meta_frames_unflicker_bg (MetaFrames *frames,
set_background_none (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), frame->xwindow);
}
#ifdef HAVE_SHAPE
static void
apply_cairo_region_to_window (Display *display,
Window xwindow,
cairo_region_t *region,
int op)
{
int n_rects, i;
XRectangle *rects;
n_rects = cairo_region_num_rectangles (region);
rects = g_new (XRectangle, n_rects);
for (i = 0; i < n_rects; i++)
{
cairo_rectangle_int_t rect;
cairo_region_get_rectangle (region, i, &rect);
rects[i].x = rect.x;
rects[i].y = rect.y;
rects[i].width = rect.width;
rects[i].height = rect.height;
}
XShapeCombineRectangles (display, xwindow,
ShapeBounding, 0, 0, rects, n_rects,
op, YXBanded);
g_free (rects);
}
#endif
static cairo_region_t *
get_bounds_region (MetaFrames *frames,
MetaUIFrame *frame,
MetaFrameGeometry *fgeom,
int window_width,
int window_height)
{
cairo_region_t *corners_region;
cairo_region_t *bounds_region;
cairo_rectangle_int_t rect;
corners_region = cairo_region_create ();
if (fgeom->top_left_corner_rounded_radius != 0)
{
const int corner = fgeom->top_left_corner_rounded_radius;
const float radius = sqrt(corner) + corner;
int i;
for (i=0; i<corner; i++)
{
const int width = floor(0.5 + radius - sqrt(radius*radius - (radius-(i+0.5))*(radius-(i+0.5))));
rect.x = 0;
rect.y = i;
rect.width = width;
rect.height = 1;
cairo_region_union_rectangle (corners_region, &rect);
}
}
if (fgeom->top_right_corner_rounded_radius != 0)
{
const int corner = fgeom->top_right_corner_rounded_radius;
const float radius = sqrt(corner) + corner;
int i;
for (i=0; i<corner; i++)
{
const int width = floor(0.5 + radius - sqrt(radius*radius - (radius-(i+0.5))*(radius-(i+0.5))));
rect.x = window_width - width;
rect.y = i;
rect.width = width;
rect.height = 1;
cairo_region_union_rectangle (corners_region, &rect);
}
}
if (fgeom->bottom_left_corner_rounded_radius != 0)
{
const int corner = fgeom->bottom_left_corner_rounded_radius;
const float radius = sqrt(corner) + corner;
int i;
for (i=0; i<corner; i++)
{
const int width = floor(0.5 + radius - sqrt(radius*radius - (radius-(i+0.5))*(radius-(i+0.5))));
rect.x = 0;
rect.y = window_height - i - 1;
rect.width = width;
rect.height = 1;
cairo_region_union_rectangle (corners_region, &rect);
}
}
if (fgeom->bottom_right_corner_rounded_radius != 0)
{
const int corner = fgeom->bottom_right_corner_rounded_radius;
const float radius = sqrt(corner) + corner;
int i;
for (i=0; i<corner; i++)
{
const int width = floor(0.5 + radius - sqrt(radius*radius - (radius-(i+0.5))*(radius-(i+0.5))));
rect.x = window_width - width;
rect.y = window_height - i - 1;
rect.width = width;
rect.height = 1;
cairo_region_union_rectangle (corners_region, &rect);
}
}
bounds_region = cairo_region_create ();
rect.x = 0;
rect.y = 0;
rect.width = window_width;
rect.height = window_height;
cairo_region_union_rectangle (bounds_region, &rect);
cairo_region_subtract (bounds_region, corners_region);
cairo_region_destroy (corners_region);
return bounds_region;
}
static cairo_region_t *
get_client_region (MetaFrameGeometry *fgeom,
int window_width,
int window_height)
{
cairo_rectangle_int_t rect;
rect.x = fgeom->left_width;
rect.y = fgeom->top_height;
rect.width = window_width - fgeom->right_width - rect.x;
rect.height = window_height - fgeom->bottom_height - rect.y;
return cairo_region_create_rectangle (&rect);
}
void
meta_frames_apply_shapes (MetaFrames *frames,
Window xwindow,
@ -775,9 +1022,7 @@ meta_frames_apply_shapes (MetaFrames *frames,
/* Apply shapes as if window had new_window_width, new_window_height */
MetaUIFrame *frame;
MetaFrameGeometry fgeom;
XRectangle xrect;
Region corners_xregion;
Region window_xregion;
cairo_region_t *window_region;
Display *display;
frame = meta_frames_lookup_window (frames, xwindow);
@ -798,7 +1043,7 @@ meta_frames_apply_shapes (MetaFrames *frames,
meta_topic (META_DEBUG_SHAPES,
"Unsetting shape mask on frame 0x%lx\n",
frame->xwindow);
XShapeCombineMask (display, frame->xwindow,
ShapeBounding, 0, 0, None, ShapeSet);
frame->shape_applied = FALSE;
@ -809,97 +1054,14 @@ meta_frames_apply_shapes (MetaFrames *frames,
"Frame 0x%lx still doesn't need a shape mask\n",
frame->xwindow);
}
return; /* nothing to do */
}
corners_xregion = XCreateRegion ();
if (fgeom.top_left_corner_rounded_radius != 0)
{
const int corner = fgeom.top_left_corner_rounded_radius;
const float radius = sqrt(corner) + corner;
int i;
for (i=0; i<corner; i++)
{
const int width = floor(0.5 + radius - sqrt(radius*radius - (radius-(i+0.5))*(radius-(i+0.5))));
xrect.x = 0;
xrect.y = i;
xrect.width = width;
xrect.height = 1;
XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
}
}
window_region = get_bounds_region (frames, frame,
&fgeom,
new_window_width, new_window_height);
if (fgeom.top_right_corner_rounded_radius != 0)
{
const int corner = fgeom.top_right_corner_rounded_radius;
const float radius = sqrt(corner) + corner;
int i;
for (i=0; i<corner; i++)
{
const int width = floor(0.5 + radius - sqrt(radius*radius - (radius-(i+0.5))*(radius-(i+0.5))));
xrect.x = new_window_width - width;
xrect.y = i;
xrect.width = width;
xrect.height = 1;
XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
}
}
if (fgeom.bottom_left_corner_rounded_radius != 0)
{
const int corner = fgeom.bottom_left_corner_rounded_radius;
const float radius = sqrt(corner) + corner;
int i;
for (i=0; i<corner; i++)
{
const int width = floor(0.5 + radius - sqrt(radius*radius - (radius-(i+0.5))*(radius-(i+0.5))));
xrect.x = 0;
xrect.y = new_window_height - i - 1;
xrect.width = width;
xrect.height = 1;
XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
}
}
if (fgeom.bottom_right_corner_rounded_radius != 0)
{
const int corner = fgeom.bottom_right_corner_rounded_radius;
const float radius = sqrt(corner) + corner;
int i;
for (i=0; i<corner; i++)
{
const int width = floor(0.5 + radius - sqrt(radius*radius - (radius-(i+0.5))*(radius-(i+0.5))));
xrect.x = new_window_width - width;
xrect.y = new_window_height - i - 1;
xrect.width = width;
xrect.height = 1;
XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
}
}
window_xregion = XCreateRegion ();
xrect.x = 0;
xrect.y = 0;
xrect.width = new_window_width;
xrect.height = new_window_height;
XUnionRectWithRegion (&xrect, window_xregion, window_xregion);
XSubtractRegion (window_xregion, corners_xregion, window_xregion);
XDestroyRegion (corners_xregion);
if (window_has_shape)
{
/* The client window is oclock or something and has a shape
@ -911,7 +1073,7 @@ meta_frames_apply_shapes (MetaFrames *frames,
XSetWindowAttributes attrs;
Window shape_window;
Window client_window;
Region client_xregion;
cairo_region_t *client_region;
GdkScreen *screen;
int screen_number;
@ -951,21 +1113,16 @@ meta_frames_apply_shapes (MetaFrames *frames,
/* Punch the client area out of the normal frame shape,
* then union it with the shape_window's existing shape
*/
client_xregion = XCreateRegion ();
xrect.x = fgeom.left_width;
xrect.y = fgeom.top_height;
xrect.width = new_window_width - fgeom.right_width - xrect.x;
xrect.height = new_window_height - fgeom.bottom_height - xrect.y;
client_region = get_client_region (&fgeom,
new_window_width,
new_window_height);
XUnionRectWithRegion (&xrect, client_xregion, client_xregion);
XSubtractRegion (window_xregion, client_xregion, window_xregion);
cairo_region_subtract (window_region, client_region);
XDestroyRegion (client_xregion);
XShapeCombineRegion (display, shape_window,
ShapeBounding, 0, 0, window_xregion, ShapeUnion);
cairo_region_destroy (client_region);
apply_cairo_region_to_window (display, shape_window,
window_region, ShapeUnion);
/* Now copy shape_window shape to the real frame */
XShapeCombineShape (display, frame->xwindow, ShapeBounding,
@ -984,16 +1141,35 @@ meta_frames_apply_shapes (MetaFrames *frames,
"Frame 0x%lx has shaped corners\n",
frame->xwindow);
XShapeCombineRegion (display, frame->xwindow,
ShapeBounding, 0, 0, window_xregion, ShapeSet);
apply_cairo_region_to_window (display, frame->xwindow,
window_region, ShapeSet);
}
frame->shape_applied = TRUE;
XDestroyRegion (window_xregion);
cairo_region_destroy (window_region);
#endif /* HAVE_SHAPE */
}
cairo_region_t *
meta_frames_get_frame_bounds (MetaFrames *frames,
Window xwindow,
int window_width,
int window_height)
{
MetaUIFrame *frame;
MetaFrameGeometry fgeom;
frame = meta_frames_lookup_window (frames, xwindow);
g_return_val_if_fail (frame != NULL, NULL);
meta_frames_calc_geometry (frames, frame, &fgeom);
return get_bounds_region (frames, frame,
&fgeom,
window_width, window_height);
}
void
meta_frames_move_resize_frame (MetaFrames *frames,
Window xwindow,
@ -1048,6 +1224,20 @@ meta_frames_set_title (MetaFrames *frames,
invalidate_whole_window (frames, frame);
}
void
meta_frames_update_frame_style (MetaFrames *frames,
Window xwindow)
{
MetaUIFrame *frame;
frame = meta_frames_lookup_window (frames, xwindow);
g_assert (frame);
meta_frames_attach_style (frames, frame);
invalidate_whole_window (frames, frame);
}
void
meta_frames_repaint_frame (MetaFrames *frames,
Window xwindow)
@ -1235,10 +1425,12 @@ meta_frame_titlebar_event (MetaUIFrame *frame,
int action)
{
MetaFrameFlags flags;
GdkDevice *pointer;
Display *display;
display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
pointer = gdk_event_get_device ((GdkEvent *) event);
switch (action)
{
case META_ACTION_TITLEBAR_TOGGLE_SHADE:
@ -1320,12 +1512,14 @@ meta_frame_titlebar_event (MetaUIFrame *frame,
case META_ACTION_TITLEBAR_LOWER:
meta_core_user_lower_and_unfocus (display,
frame->xwindow,
gdk_x11_device_get_id (pointer),
event->time);
break;
case META_ACTION_TITLEBAR_MENU:
meta_core_show_window_menu (display,
frame->xwindow,
gdk_x11_device_get_id (pointer),
event->x_root,
event->y_root,
event->button,
@ -1374,7 +1568,9 @@ meta_frames_button_press_event (GtkWidget *widget,
MetaFrames *frames;
MetaFrameControl control;
Display *display;
GdkDevice *device;
int device_id;
frames = META_FRAMES (widget);
display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
@ -1407,7 +1603,10 @@ meta_frames_button_press_event (GtkWidget *widget,
/* don't do the rest of this if on client area */
if (control == META_FRAME_CONTROL_CLIENT_AREA)
return FALSE; /* not on the frame, just passed through from client */
device = gdk_event_get_device ((GdkEvent *) event);
device_id = gdk_x11_device_get_id (device);
/* We want to shade even if we have a GrabOp, since we'll have a move grab
* if we double click the titlebar.
*/
@ -1415,13 +1614,13 @@ meta_frames_button_press_event (GtkWidget *widget,
event->button == 1 &&
event->type == GDK_2BUTTON_PRESS)
{
meta_core_end_grab_op (display, event->time);
meta_core_end_grab_op (display, device_id, event->time);
return meta_frame_double_click_event (frame, event);
}
if (meta_core_get_grab_op (display) !=
if (meta_core_frame_has_grab (display, frame->xwindow, NULL, NULL) !=
META_GRAB_OP_NONE)
return FALSE; /* already up to something */
return FALSE; /* already up to something */
if (event->button == 1 &&
(control == META_FRAME_CONTROL_MAXIMIZE ||
@ -1480,6 +1679,7 @@ meta_frames_button_press_event (GtkWidget *widget,
meta_core_begin_grab_op (display,
frame->xwindow,
device_id,
op,
TRUE,
TRUE,
@ -1512,6 +1712,7 @@ meta_frames_button_press_event (GtkWidget *widget,
meta_core_show_window_menu (display,
frame->xwindow,
device_id,
rect->x + dx,
rect->y + rect->height + dy,
event->button,
@ -1529,7 +1730,6 @@ meta_frames_button_press_event (GtkWidget *widget,
control == META_FRAME_CONTROL_RESIZE_W))
{
MetaGrabOp op;
gboolean titlebar_is_onscreen;
op = META_GRAB_OP_NONE;
@ -1564,28 +1764,17 @@ meta_frames_button_press_event (GtkWidget *widget,
break;
}
meta_core_get (display, frame->xwindow,
META_CORE_IS_TITLEBAR_ONSCREEN, &titlebar_is_onscreen,
META_CORE_GET_END);
if (!titlebar_is_onscreen)
meta_core_show_window_menu (display,
frame->xwindow,
event->x_root,
event->y_root,
event->button,
event->time);
else
meta_core_begin_grab_op (display,
frame->xwindow,
op,
TRUE,
TRUE,
event->button,
0,
event->time,
event->x_root,
event->y_root);
meta_core_begin_grab_op (display,
frame->xwindow,
device_id,
op,
TRUE,
TRUE,
event->button,
0,
event->time,
event->x_root,
event->y_root);
}
else if (control == META_FRAME_CONTROL_TITLE &&
event->button == 1)
@ -1600,6 +1789,7 @@ meta_frames_button_press_event (GtkWidget *widget,
{
meta_core_begin_grab_op (display,
frame->xwindow,
device_id,
META_GRAB_OP_MOVING,
TRUE,
TRUE,
@ -1623,28 +1813,28 @@ meta_frames_button_press_event (GtkWidget *widget,
}
void
meta_frames_notify_menu_hide (MetaFrames *frames)
meta_frames_notify_menu_hide (MetaFrames *frames,
Window client_xwindow)
{
Display *display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
if (meta_core_get_grab_op (display) ==
Window frame_xwindow;
int device_id;
frame_xwindow = meta_core_get_frame (display, client_xwindow);
if (frame_xwindow != None &&
meta_core_frame_has_grab (display, frame_xwindow, &device_id, NULL) ==
META_GRAB_OP_CLICKING_MENU)
{
Window grab_frame;
MetaUIFrame *frame;
grab_frame = meta_core_get_grab_frame (display);
frame = meta_frames_lookup_window (frames, frame_xwindow);
if (grab_frame != None)
if (frame)
{
MetaUIFrame *frame;
frame = meta_frames_lookup_window (frames, grab_frame);
if (frame)
{
redraw_control (frames, frame,
META_FRAME_CONTROL_MENU);
meta_core_end_grab_op (display, CurrentTime);
}
redraw_control (frames, frame,
META_FRAME_CONTROL_MENU);
meta_core_end_grab_op (display, device_id, CurrentTime);
}
}
}
@ -1657,7 +1847,10 @@ meta_frames_button_release_event (GtkWidget *widget,
MetaFrames *frames;
MetaGrabOp op;
Display *display;
int grab_button;
GdkDevice *device;
int device_id, grab_device_id;
frames = META_FRAMES (widget);
display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
@ -1667,17 +1860,21 @@ meta_frames_button_release_event (GtkWidget *widget,
clear_tip (frames);
op = meta_core_get_grab_op (display);
op = meta_core_frame_has_grab (display, frame->xwindow,
&grab_device_id, &grab_button);
if (op == META_GRAB_OP_NONE)
device = gdk_event_get_device ((GdkEvent *) event);
device_id = gdk_x11_device_get_id (device);
if (op == META_GRAB_OP_NONE ||
grab_device_id != device_id)
return FALSE;
/* We only handle the releases we handled the presses for (things
* involving frame controls). Window ops that don't require a
* frame are handled in the Xlib part of the code, display.c/window.c
*/
if (frame->xwindow == meta_core_get_grab_frame (display) &&
((int) event->button) == meta_core_get_grab_button (display))
if (((int) event->button) == grab_button)
{
MetaFrameControl control;
@ -1688,8 +1885,8 @@ meta_frames_button_release_event (GtkWidget *widget,
case META_GRAB_OP_CLICKING_MINIMIZE:
if (control == META_FRAME_CONTROL_MINIMIZE)
meta_core_minimize (display, frame->xwindow);
meta_core_end_grab_op (display, event->time);
meta_core_end_grab_op (display, device_id, event->time);
break;
case META_GRAB_OP_CLICKING_MAXIMIZE:
@ -1701,67 +1898,67 @@ meta_frames_button_release_event (GtkWidget *widget,
event->time);
meta_core_maximize (display, frame->xwindow);
}
meta_core_end_grab_op (display, event->time);
meta_core_end_grab_op (display, device_id, event->time);
break;
case META_GRAB_OP_CLICKING_UNMAXIMIZE:
if (control == META_FRAME_CONTROL_UNMAXIMIZE)
meta_core_unmaximize (display, frame->xwindow);
meta_core_end_grab_op (display, event->time);
meta_core_end_grab_op (display, device_id, event->time);
break;
case META_GRAB_OP_CLICKING_DELETE:
if (control == META_FRAME_CONTROL_DELETE)
meta_core_delete (display, frame->xwindow, event->time);
meta_core_end_grab_op (display, event->time);
meta_core_end_grab_op (display, device_id, event->time);
break;
case META_GRAB_OP_CLICKING_MENU:
meta_core_end_grab_op (display, event->time);
meta_core_end_grab_op (display, device_id, event->time);
break;
case META_GRAB_OP_CLICKING_SHADE:
if (control == META_FRAME_CONTROL_SHADE)
meta_core_shade (display, frame->xwindow, event->time);
meta_core_end_grab_op (display, event->time);
meta_core_end_grab_op (display, device_id, event->time);
break;
case META_GRAB_OP_CLICKING_UNSHADE:
if (control == META_FRAME_CONTROL_UNSHADE)
meta_core_unshade (display, frame->xwindow, event->time);
meta_core_end_grab_op (display, event->time);
meta_core_end_grab_op (display, device_id, event->time);
break;
case META_GRAB_OP_CLICKING_ABOVE:
if (control == META_FRAME_CONTROL_ABOVE)
meta_core_make_above (display, frame->xwindow);
meta_core_end_grab_op (display, event->time);
meta_core_end_grab_op (display, device_id, event->time);
break;
case META_GRAB_OP_CLICKING_UNABOVE:
if (control == META_FRAME_CONTROL_UNABOVE)
meta_core_unmake_above (display, frame->xwindow);
meta_core_end_grab_op (display, event->time);
meta_core_end_grab_op (display, device_id, event->time);
break;
case META_GRAB_OP_CLICKING_STICK:
if (control == META_FRAME_CONTROL_STICK)
meta_core_stick (display, frame->xwindow);
meta_core_end_grab_op (display, event->time);
meta_core_end_grab_op (display, device_id, event->time);
break;
case META_GRAB_OP_CLICKING_UNSTICK:
if (control == META_FRAME_CONTROL_UNSTICK)
meta_core_unstick (display, frame->xwindow);
meta_core_end_grab_op (display, event->time);
meta_core_end_grab_op (display, device_id, event->time);
break;
default:
@ -1773,7 +1970,9 @@ meta_frames_button_release_event (GtkWidget *widget,
* prelit so to let the user know that it can now be pressed.
* :)
*/
meta_frames_update_prelit_control (frames, frame, control);
meta_frames_update_prelit_control (frames, frame,
gdk_event_get_device ((GdkEvent *) event),
control);
}
return TRUE;
@ -1782,12 +1981,12 @@ meta_frames_button_release_event (GtkWidget *widget,
static void
meta_frames_update_prelit_control (MetaFrames *frames,
MetaUIFrame *frame,
GdkDevice *device,
MetaFrameControl control)
{
MetaFrameControl old_control;
MetaCursor cursor;
meta_verbose ("Updating prelit control from %u to %u\n",
frame->prelit_control, control);
@ -1852,6 +2051,7 @@ meta_frames_update_prelit_control (MetaFrames *frames,
/* set/unset the prelight cursor */
meta_core_set_screen_cursor (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
frame->xwindow,
gdk_x11_device_get_id (device),
cursor);
switch (control)
@ -1907,8 +2107,8 @@ meta_frames_motion_notify_event (GtkWidget *widget,
frames->last_motion_frame = frame;
grab_op = meta_core_get_grab_op (display);
grab_op = meta_core_frame_has_grab (display, frame->xwindow, NULL, NULL);
switch (grab_op)
{
case META_GRAB_OP_CLICKING_MENU:
@ -1924,9 +2124,9 @@ meta_frames_motion_notify_event (GtkWidget *widget,
case META_GRAB_OP_CLICKING_UNSTICK:
{
MetaFrameControl control;
int x, y;
gdk_window_get_pointer (frame->window, &x, &y, NULL);
gdouble x, y;
gdk_event_get_coords ((GdkEvent *) event, &x, &y);
/* Control is set to none unless it matches
* the current grab
@ -1957,7 +2157,9 @@ meta_frames_motion_notify_event (GtkWidget *widget,
control = META_FRAME_CONTROL_NONE;
/* Update prelit control and cursor */
meta_frames_update_prelit_control (frames, frame, control);
meta_frames_update_prelit_control (frames, frame,
gdk_event_get_device ((GdkEvent *) event),
control);
/* No tooltip while in the process of clicking */
}
@ -1965,14 +2167,15 @@ meta_frames_motion_notify_event (GtkWidget *widget,
case META_GRAB_OP_NONE:
{
MetaFrameControl control;
int x, y;
gdk_window_get_pointer (frame->window, &x, &y, NULL);
gdouble x, y;
gdk_event_get_coords ((GdkEvent *) event, &x, &y);
control = get_control (frames, frame, x, y);
/* Update prelit control and cursor */
meta_frames_update_prelit_control (frames, frame, control);
meta_frames_update_prelit_control (frames, frame,
gdk_event_get_device ((GdkEvent *) event),
control);
queue_tip (frames);
}
@ -2304,7 +2507,6 @@ meta_frames_paint (MetaFrames *frames,
GdkPixbuf *icon;
int w, h;
MetaButtonState button_states[META_BUTTON_TYPE_LAST];
Window grab_frame;
int i;
MetaButtonLayout button_layout;
MetaGrabOp grab_op;
@ -2316,11 +2518,8 @@ meta_frames_paint (MetaFrames *frames,
for (i = 0; i < META_BUTTON_TYPE_LAST; i++)
button_states[i] = META_BUTTON_STATE_NORMAL;
grab_frame = meta_core_get_grab_frame (display);
grab_op = meta_core_get_grab_op (display);
if (grab_frame != frame->xwindow)
grab_op = META_GRAB_OP_NONE;
grab_op = meta_core_frame_has_grab (display, frame->xwindow, NULL, NULL);
/* Set prelight state */
switch (frame->prelit_control)
{
@ -2444,11 +2643,11 @@ meta_frames_set_window_background (MetaFrames *frames,
if (frame_exists && style->window_background_color != NULL)
{
GdkColor color;
GdkRGBA color;
GdkVisual *visual;
meta_color_spec_render (style->window_background_color,
GTK_WIDGET (frames),
frame->style,
&color);
/* Set A in ARGB to window_background_alpha, if we have ARGB */
@ -2456,11 +2655,10 @@ meta_frames_set_window_background (MetaFrames *frames,
visual = gtk_widget_get_visual (GTK_WIDGET (frames));
if (gdk_visual_get_depth (visual) == 32) /* we have ARGB */
{
color.pixel = (color.pixel & 0xffffff) &
style->window_background_alpha << 24;
color.alpha = style->window_background_alpha / 255.0;
}
gdk_window_set_background (frame->window, &color);
gdk_window_set_background_rgba (frame->window, &color);
}
else
{
@ -2483,7 +2681,9 @@ meta_frames_enter_notify_event (GtkWidget *widget,
return FALSE;
control = get_control (frames, frame, event->x, event->y);
meta_frames_update_prelit_control (frames, frame, control);
meta_frames_update_prelit_control (frames, frame,
gdk_event_get_device ((GdkEvent *) event),
control);
return TRUE;
}
@ -2501,7 +2701,9 @@ meta_frames_leave_notify_event (GtkWidget *widget,
if (frame == NULL)
return FALSE;
meta_frames_update_prelit_control (frames, frame, META_FRAME_CONTROL_NONE);
meta_frames_update_prelit_control (frames, frame,
gdk_event_get_device ((GdkEvent *) event),
META_FRAME_CONTROL_NONE);
clear_tip (frames);

View File

@ -98,6 +98,9 @@ struct _MetaFrames
guint tooltip_timeout;
MetaUIFrame *last_motion_frame;
GtkStyleContext *normal_style;
GHashTable *style_variants;
int expose_delay_count;
int invalidate_cache_timeout_id;
@ -124,6 +127,9 @@ void meta_frames_set_title (MetaFrames *frames,
Window xwindow,
const char *title);
void meta_frames_update_frame_style (MetaFrames *frames,
Window xwindow);
void meta_frames_repaint_frame (MetaFrames *frames,
Window xwindow);
@ -144,6 +150,10 @@ void meta_frames_apply_shapes (MetaFrames *frames,
int new_window_width,
int new_window_height,
gboolean window_has_shape);
cairo_region_t *meta_frames_get_frame_bounds (MetaFrames *frames,
Window xwindow,
int window_width,
int window_height);
void meta_frames_move_resize_frame (MetaFrames *frames,
Window xwindow,
int x,
@ -153,7 +163,8 @@ void meta_frames_move_resize_frame (MetaFrames *frames,
void meta_frames_queue_draw (MetaFrames *frames,
Window xwindow);
void meta_frames_notify_menu_hide (MetaFrames *frames);
void meta_frames_notify_menu_hide (MetaFrames *frames,
Window client_xwindow);
Window meta_frames_get_moving_frame (MetaFrames *frames);

View File

@ -31,27 +31,27 @@
*/
static GdkPixbuf* meta_gradient_create_horizontal (int width,
int height,
const GdkColor *from,
const GdkColor *to);
const GdkRGBA *from,
const GdkRGBA *to);
static GdkPixbuf* meta_gradient_create_vertical (int width,
int height,
const GdkColor *from,
const GdkColor *to);
const GdkRGBA *from,
const GdkRGBA *to);
static GdkPixbuf* meta_gradient_create_diagonal (int width,
int height,
const GdkColor *from,
const GdkColor *to);
const GdkRGBA *from,
const GdkRGBA *to);
static GdkPixbuf* meta_gradient_create_multi_horizontal (int width,
int height,
const GdkColor *colors,
const GdkRGBA *colors,
int count);
static GdkPixbuf* meta_gradient_create_multi_vertical (int width,
int height,
const GdkColor *colors,
const GdkRGBA *colors,
int count);
static GdkPixbuf* meta_gradient_create_multi_diagonal (int width,
int height,
const GdkColor *colors,
const GdkRGBA *colors,
int count);
@ -100,8 +100,8 @@ blank_pixbuf (int width, int height, gboolean no_padding)
GdkPixbuf*
meta_gradient_create_simple (int width,
int height,
const GdkColor *from,
const GdkColor *to,
const GdkRGBA *from,
const GdkRGBA *to,
MetaGradientType style)
{
switch (style)
@ -136,7 +136,7 @@ meta_gradient_create_simple (int width,
GdkPixbuf*
meta_gradient_create_multi (int width,
int height,
const GdkColor *colors,
const GdkRGBA *colors,
int n_colors,
MetaGradientType style)
{
@ -181,9 +181,9 @@ meta_gradient_create_multi (int width,
GdkPixbuf*
meta_gradient_create_interwoven (int width,
int height,
const GdkColor colors1[2],
const GdkRGBA colors1[2],
int thickness1,
const GdkColor colors2[2],
const GdkRGBA colors2[2],
int thickness2)
{
@ -202,21 +202,21 @@ meta_gradient_create_interwoven (int width,
pixels = gdk_pixbuf_get_pixels (pixbuf);
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
r1 = colors1[0].red<<8;
g1 = colors1[0].green<<8;
b1 = colors1[0].blue<<8;
r1 = (long)(colors1[0].red*0xffffff);
g1 = (long)(colors1[0].green*0xffffff);
b1 = (long)(colors1[0].blue*0xffffff);
r2 = colors2[0].red<<8;
g2 = colors2[0].green<<8;
b2 = colors2[0].blue<<8;
r2 = (long)(colors2[0].red*0xffffff);
g2 = (long)(colors2[0].green*0xffffff);
b2 = (long)(colors2[0].blue*0xffffff);
dr1 = ((colors1[1].red-colors1[0].red)<<8)/(int)height;
dg1 = ((colors1[1].green-colors1[0].green)<<8)/(int)height;
db1 = ((colors1[1].blue-colors1[0].blue)<<8)/(int)height;
dr1 = ((colors1[1].red-colors1[0].red)*0xffffff)/(int)height;
dg1 = ((colors1[1].green-colors1[0].green)*0xffffff)/(int)height;
db1 = ((colors1[1].blue-colors1[0].blue)*0xffffff)/(int)height;
dr2 = ((colors2[1].red-colors2[0].red)<<8)/(int)height;
dg2 = ((colors2[1].green-colors2[0].green)<<8)/(int)height;
db2 = ((colors2[1].blue-colors2[0].blue)<<8)/(int)height;
dr2 = ((colors2[1].red-colors2[0].red)*0xffffff)/(int)height;
dg2 = ((colors2[1].green-colors2[0].green)*0xffffff)/(int)height;
db2 = ((colors2[1].blue-colors2[0].blue)*0xffffff)/(int)height;
for (i=0,k=0,l=0,ll=thickness1; i<height; i++)
{
@ -280,8 +280,8 @@ meta_gradient_create_interwoven (int width,
*/
static GdkPixbuf*
meta_gradient_create_horizontal (int width, int height,
const GdkColor *from,
const GdkColor *to)
const GdkRGBA *from,
const GdkRGBA *to)
{
int i;
long r, g, b, dr, dg, db;
@ -300,12 +300,12 @@ meta_gradient_create_horizontal (int width, int height,
ptr = pixels;
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
r0 = (guchar) (from->red / 256.0);
g0 = (guchar) (from->green / 256.0);
b0 = (guchar) (from->blue / 256.0);
rf = (guchar) (to->red / 256.0);
gf = (guchar) (to->green / 256.0);
bf = (guchar) (to->blue / 256.0);
r0 = (guchar) (from->red * 0xff);
g0 = (guchar) (from->green * 0xff);
b0 = (guchar) (from->blue * 0xff);
rf = (guchar) (to->red * 0xff);
gf = (guchar) (to->green * 0xff);
bf = (guchar) (to->blue * 0xff);
r = r0 << 16;
g = g0 << 16;
@ -348,8 +348,8 @@ meta_gradient_create_horizontal (int width, int height,
*/
static GdkPixbuf*
meta_gradient_create_vertical (int width, int height,
const GdkColor *from,
const GdkColor *to)
const GdkRGBA *from,
const GdkRGBA *to)
{
int i, j;
long r, g, b, dr, dg, db;
@ -367,12 +367,12 @@ meta_gradient_create_vertical (int width, int height,
pixels = gdk_pixbuf_get_pixels (pixbuf);
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
r0 = (guchar) (from->red / 256.0);
g0 = (guchar) (from->green / 256.0);
b0 = (guchar) (from->blue / 256.0);
rf = (guchar) (to->red / 256.0);
gf = (guchar) (to->green / 256.0);
bf = (guchar) (to->blue / 256.0);
r0 = (guchar) (from->red * 0xff);
g0 = (guchar) (from->green * 0xff);
b0 = (guchar) (from->blue * 0xff);
rf = (guchar) (to->red * 0xff);
gf = (guchar) (to->green * 0xff);
bf = (guchar) (to->blue * 0xff);
r = r0<<16;
g = g0<<16;
@ -419,8 +419,8 @@ meta_gradient_create_vertical (int width, int height,
static GdkPixbuf*
meta_gradient_create_diagonal (int width, int height,
const GdkColor *from,
const GdkColor *to)
const GdkRGBA *from,
const GdkRGBA *to)
{
GdkPixbuf *pixbuf, *tmp;
int j;
@ -467,7 +467,7 @@ meta_gradient_create_diagonal (int width, int height,
static GdkPixbuf*
meta_gradient_create_multi_horizontal (int width, int height,
const GdkColor *colors,
const GdkRGBA *colors,
int count)
{
int i, j, k;
@ -498,16 +498,16 @@ meta_gradient_create_multi_horizontal (int width, int height,
k = 0;
r = colors[0].red << 8;
g = colors[0].green << 8;
b = colors[0].blue << 8;
r = (long)(colors[0].red * 0xffffff);
g = (long)(colors[0].green * 0xffffff);
b = (long)(colors[0].blue * 0xffffff);
/* render the first line */
for (i=1; i<count; i++)
{
dr = ((int)(colors[i].red - colors[i-1].red) <<8)/(int)width2;
dg = ((int)(colors[i].green - colors[i-1].green)<<8)/(int)width2;
db = ((int)(colors[i].blue - colors[i-1].blue) <<8)/(int)width2;
dr = (int)((colors[i].red - colors[i-1].red) *0xffffff)/(int)width2;
dg = (int)((colors[i].green - colors[i-1].green)*0xffffff)/(int)width2;
db = (int)((colors[i].blue - colors[i-1].blue) *0xffffff)/(int)width2;
for (j=0; j<width2; j++)
{
*ptr++ = (unsigned char)(r>>16);
@ -518,9 +518,9 @@ meta_gradient_create_multi_horizontal (int width, int height,
b += db;
k++;
}
r = colors[i].red << 8;
g = colors[i].green << 8;
b = colors[i].blue << 8;
r = (long)(colors[i].red * 0xffffff);
g = (long)(colors[i].green * 0xffffff);
b = (long)(colors[i].blue * 0xffffff);
}
for (j=k; j<width; j++)
{
@ -539,7 +539,7 @@ meta_gradient_create_multi_horizontal (int width, int height,
static GdkPixbuf*
meta_gradient_create_multi_vertical (int width, int height,
const GdkColor *colors,
const GdkRGBA *colors,
int count)
{
int i, j, k;
@ -570,15 +570,15 @@ meta_gradient_create_multi_vertical (int width, int height,
k = 0;
r = colors[0].red << 8;
g = colors[0].green << 8;
b = colors[0].blue << 8;
r = (long)(colors[0].red * 0xffffff);
g = (long)(colors[0].green * 0xffffff);
b = (long)(colors[0].blue * 0xffffff);
for (i=1; i<count; i++)
{
dr = ((int)(colors[i].red - colors[i-1].red) <<8)/(int)height2;
dg = ((int)(colors[i].green - colors[i-1].green)<<8)/(int)height2;
db = ((int)(colors[i].blue - colors[i-1].blue) <<8)/(int)height2;
dr = (int)((colors[i].red - colors[i-1].red) *0xffffff)/(int)height2;
dg = (int)((colors[i].green - colors[i-1].green)*0xffffff)/(int)height2;
db = (int)((colors[i].blue - colors[i-1].blue) *0xffffff)/(int)height2;
for (j=0; j<height2; j++)
{
@ -597,9 +597,9 @@ meta_gradient_create_multi_vertical (int width, int height,
b += db;
k++;
}
r = colors[i].red << 8;
g = colors[i].green << 8;
b = colors[i].blue << 8;
r = (long)(colors[i].red * 0xffffff);
g = (long)(colors[i].green * 0xffffff);
b = (long)(colors[i].blue * 0xffffff);
}
if (k<height)
@ -629,7 +629,7 @@ meta_gradient_create_multi_vertical (int width, int height,
static GdkPixbuf*
meta_gradient_create_multi_diagonal (int width, int height,
const GdkColor *colors,
const GdkRGBA *colors,
int count)
{
GdkPixbuf *pixbuf, *tmp;

View File

@ -137,7 +137,7 @@ menu_closed (GtkMenu *widget,
menu = data;
meta_frames_notify_menu_hide (menu->frames);
meta_frames_notify_menu_hide (menu->frames, menu->client_xwindow);
(* menu->func) (menu,
GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
menu->client_xwindow,
@ -157,7 +157,7 @@ activate_cb (GtkWidget *menuitem, gpointer data)
md = data;
meta_frames_notify_menu_hide (md->menu->frames);
meta_frames_notify_menu_hide (md->menu->frames, md->menu->client_xwindow);
(* md->menu->func) (md->menu,
GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
md->menu->client_xwindow,
@ -498,13 +498,17 @@ meta_window_menu_new (MetaFrames *frames,
void
meta_window_menu_popup (MetaWindowMenu *menu,
MetaDevice *device,
int root_x,
int root_y,
int button,
guint32 timestamp)
{
GdkDeviceManager *device_manager;
GdkDevice *gdkdevice;
GdkDisplay *display;
GdkPoint *pt;
pt = g_new (GdkPoint, 1);
g_object_set_data_full (G_OBJECT (menu->menu),
@ -514,12 +518,18 @@ meta_window_menu_popup (MetaWindowMenu *menu,
pt->x = root_x;
pt->y = root_y;
gtk_menu_popup (GTK_MENU (menu->menu),
NULL, NULL,
popup_position_func, pt,
button,
timestamp);
display = gtk_widget_get_display (menu->menu);
device_manager = gdk_display_get_device_manager (display);
gdkdevice = gdk_x11_device_manager_lookup (device_manager,
meta_device_get_id (device));
gtk_menu_popup_for_device (GTK_MENU (menu->menu),
gdkdevice,
NULL, NULL,
popup_position_func, pt, NULL,
button,
timestamp);
if (!gtk_widget_get_visible (menu->menu))
meta_warning ("GtkMenu failed to grab the pointer\n");

View File

@ -25,6 +25,7 @@
#define META_MENU_H
#include <gtk/gtk.h>
#include <meta/device.h>
#include "frames.h"
/* Stock icons */
@ -52,6 +53,7 @@ MetaWindowMenu* meta_window_menu_new (MetaFrames *frames,
MetaWindowMenuFunc func,
gpointer data);
void meta_window_menu_popup (MetaWindowMenu *menu,
MetaDevice *device,
int root_x,
int root_y,
int button,

View File

@ -858,12 +858,21 @@ static WnckWindowDisplayInfo
meta_convert_meta_to_wnck (MetaWindow *window, MetaScreen *screen)
{
WnckWindowDisplayInfo wnck_window;
MetaFocusInfo *focus_info;
GHashTableIter iter;
wnck_window.icon = window->icon;
wnck_window.mini_icon = window->mini_icon;
wnck_window.is_active = FALSE;
if (window == window->display->expected_focus_window)
wnck_window.is_active = TRUE;
g_hash_table_iter_init (&iter, window->display->focus_info);
while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &focus_info))
{
if (window == focus_info->expected_focus_window)
wnck_window.is_active = TRUE;
}
if (window->frame)
{

View File

@ -33,18 +33,20 @@ draw_checkerboard (cairo_t *cr,
int height)
{
gint i, j, xcount, ycount;
GdkColor color1, color2;
GdkRGBA color1, color2;
#define CHECK_SIZE 10
#define SPACING 2
color1.red = 30000;
color1.green = 30000;
color1.blue = 30000;
color1.red = 30000. / 65535.;
color1.green = 30000. / 65535.;
color1.blue = 30000. / 65535.;
color1.alpha = 1.0;
color2.red = 50000;
color2.green = 50000;
color2.blue = 50000;
color2.red = 50000. / 65535.;
color2.green = 50000. / 65535.;
color2.blue = 50000. / 65535.;
color2.alpha = 1.0;
xcount = 0;
i = SPACING;
@ -55,9 +57,9 @@ draw_checkerboard (cairo_t *cr,
while (j < height)
{
if (ycount % 2)
gdk_cairo_set_source_color (cr, &color1);
gdk_cairo_set_source_rgba (cr, &color1);
else
gdk_cairo_set_source_color (cr, &color2);
gdk_cairo_set_source_rgba (cr, &color2);
/* If we're outside event->area, this will do nothing.
* It might be mildly more efficient if we handled
@ -82,10 +84,10 @@ render_simple (cairo_t *cr,
gboolean with_alpha)
{
GdkPixbuf *pixbuf;
GdkColor from, to;
GdkRGBA from, to;
gdk_color_parse ("blue", &from);
gdk_color_parse ("green", &to);
gdk_rgba_parse (&from, "blue");
gdk_rgba_parse (&to, "green");
pixbuf = meta_gradient_create_simple (width, height,
&from, &to,
@ -153,13 +155,13 @@ render_multi (cairo_t *cr,
{
GdkPixbuf *pixbuf;
#define N_COLORS 5
GdkColor colors[N_COLORS];
GdkRGBA colors[N_COLORS];
gdk_color_parse ("red", &colors[0]);
gdk_color_parse ("blue", &colors[1]);
gdk_color_parse ("orange", &colors[2]);
gdk_color_parse ("pink", &colors[3]);
gdk_color_parse ("green", &colors[4]);
gdk_rgba_parse (&colors[0], "red");
gdk_rgba_parse (&colors[1], "blue");
gdk_rgba_parse (&colors[2], "orange");
gdk_rgba_parse (&colors[3], "pink");
gdk_rgba_parse (&colors[4], "green");
pixbuf = meta_gradient_create_multi (width, height,
colors, N_COLORS,
@ -200,12 +202,12 @@ render_interwoven_func (cairo_t *cr,
{
GdkPixbuf *pixbuf;
#define N_COLORS 4
GdkColor colors[N_COLORS];
GdkRGBA colors[N_COLORS];
gdk_color_parse ("red", &colors[0]);
gdk_color_parse ("blue", &colors[1]);
gdk_color_parse ("pink", &colors[2]);
gdk_color_parse ("green", &colors[3]);
gdk_rgba_parse (&colors[0], "red");
gdk_rgba_parse (&colors[1], "blue");
gdk_rgba_parse (&colors[2], "pink");
gdk_rgba_parse (&colors[3], "green");
pixbuf = meta_gradient_create_interwoven (width, height,
colors, height / 10,
@ -234,7 +236,7 @@ draw_callback (GtkWidget *widget,
gtk_style_context_lookup_color (style, "foreground-color", &color);
gtk_style_context_restore (style);
cairo_set_source_rgba (cr, color.red, color.green, color.blue, color.alpha);
gdk_cairo_set_source_rgba (cr, &color);
(* func) (cr,
gtk_widget_get_allocated_width (widget),

View File

@ -38,7 +38,7 @@
* look out for.
*/
#define THEME_MAJOR_VERSION 3
#define THEME_MINOR_VERSION 3
#define THEME_MINOR_VERSION 4
#define THEME_VERSION (1000 * THEME_MAJOR_VERSION + THEME_MINOR_VERSION)
#define METACITY_THEME_FILENAME_FORMAT "metacity-theme-%d.xml"
@ -2320,7 +2320,7 @@ parse_draw_op_element (GMarkupParseContext *context,
const char *height;
const char *filled;
gboolean filled_val;
GtkStateType state_val;
GtkStateFlags state_val;
GtkShadowType shadow_val;
GtkArrowType arrow_val;
@ -2410,7 +2410,7 @@ parse_draw_op_element (GMarkupParseContext *context,
const char *y;
const char *width;
const char *height;
GtkStateType state_val;
GtkStateFlags state_val;
GtkShadowType shadow_val;
if (!locate_attributes (context, element_name, attribute_names, attribute_values,
@ -2478,7 +2478,7 @@ parse_draw_op_element (GMarkupParseContext *context,
const char *x;
const char *y1;
const char *y2;
GtkStateType state_val;
GtkStateFlags state_val;
if (!locate_attributes (context, element_name, attribute_names, attribute_values,
error,

View File

@ -281,6 +281,7 @@ typedef enum
{
META_COLOR_SPEC_BASIC,
META_COLOR_SPEC_GTK,
META_COLOR_SPEC_GTK_CUSTOM,
META_COLOR_SPEC_BLEND,
META_COLOR_SPEC_SHADE
} MetaColorSpecType;
@ -304,24 +305,28 @@ struct _MetaColorSpec
union
{
struct {
GdkColor color;
GdkRGBA color;
} basic;
struct {
MetaGtkColorComponent component;
GtkStateType state;
GtkStateFlags state;
} gtk;
struct {
char *color_name;
MetaColorSpec *fallback;
} gtkcustom;
struct {
MetaColorSpec *foreground;
MetaColorSpec *background;
double alpha;
GdkColor color;
GdkRGBA color;
} blend;
struct {
MetaColorSpec *base;
double factor;
GdkColor color;
GdkRGBA color;
} shade;
} data;
};
@ -553,7 +558,7 @@ struct _MetaDrawOp
} image;
struct {
GtkStateType state;
GtkStateFlags state;
GtkShadowType shadow;
GtkArrowType arrow;
gboolean filled;
@ -565,7 +570,7 @@ struct _MetaDrawOp
} gtk_arrow;
struct {
GtkStateType state;
GtkStateFlags state;
GtkShadowType shadow;
MetaDrawSpec *x;
MetaDrawSpec *y;
@ -574,7 +579,7 @@ struct _MetaDrawOp
} gtk_box;
struct {
GtkStateType state;
GtkStateFlags state;
MetaDrawSpec *x;
MetaDrawSpec *y1;
MetaDrawSpec *y2;
@ -958,11 +963,11 @@ MetaColorSpec* meta_color_spec_new (MetaColorSpecType type);
MetaColorSpec* meta_color_spec_new_from_string (const char *str,
GError **err);
MetaColorSpec* meta_color_spec_new_gtk (MetaGtkColorComponent component,
GtkStateType state);
GtkStateFlags state);
void meta_color_spec_free (MetaColorSpec *spec);
void meta_color_spec_render (MetaColorSpec *spec,
GtkWidget *widget,
GdkColor *color);
GtkStyleContext *style_gtk,
GdkRGBA *color);
MetaDrawOp* meta_draw_op_new (MetaDrawType type);
@ -1006,7 +1011,7 @@ gboolean meta_draw_op_list_contains (MetaDrawOpList *op_list,
MetaGradientSpec* meta_gradient_spec_new (MetaGradientType type);
void meta_gradient_spec_free (MetaGradientSpec *desc);
GdkPixbuf* meta_gradient_spec_render (const MetaGradientSpec *desc,
GtkWidget *widget,
GtkStyleContext *gtk_style,
int width,
int height);
gboolean meta_gradient_spec_validate (MetaGradientSpec *spec,
@ -1208,8 +1213,8 @@ const char* meta_frame_focus_to_string (MetaFrameFocus f
MetaFrameType meta_frame_type_from_string (const char *str);
MetaGradientType meta_gradient_type_from_string (const char *str);
const char* meta_gradient_type_to_string (MetaGradientType type);
GtkStateType meta_gtk_state_from_string (const char *str);
const char* meta_gtk_state_to_string (GtkStateType state);
GtkStateFlags meta_gtk_state_from_string (const char *str);
const char* meta_gtk_state_to_string (GtkStateFlags state);
GtkShadowType meta_gtk_shadow_from_string (const char *str);
const char* meta_gtk_shadow_to_string (GtkShadowType shadow);
GtkArrowType meta_gtk_arrow_from_string (const char *str);
@ -1217,6 +1222,13 @@ const char* meta_gtk_arrow_to_string (GtkArrowType a
MetaImageFillType meta_image_fill_type_from_string (const char *str);
const char* meta_image_fill_type_to_string (MetaImageFillType fill_type);
void meta_gtk_style_get_light_color (GtkStyleContext *style,
GtkStateFlags state,
GdkRGBA *color);
void meta_gtk_style_get_dark_color (GtkStyleContext *style,
GtkStateFlags state,
GdkRGBA *color);
guint meta_theme_earliest_version_with_button (MetaButtonType type);

View File

@ -355,14 +355,15 @@ border_only_contents (void)
GtkWidget *event_box;
GtkWidget *vbox;
GtkWidget *w;
GdkColor color;
GdkRGBA color;
event_box = gtk_event_box_new ();
color.red = 40000;
color.red = 0.6;
color.green = 0;
color.blue = 40000;
gtk_widget_modify_bg (event_box, GTK_STATE_NORMAL, &color);
color.blue = 0.6;
color.alpha = 1.0;
gtk_widget_override_background_color (event_box, 0, &color);
vbox = gtk_vbox_new (FALSE, 0);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 3);
@ -477,7 +478,7 @@ preview_collection (int font_size,
{
GtkWidget *box;
GtkWidget *sw;
GdkColor desktop_color;
GdkRGBA desktop_color;
int i;
GtkWidget *eventbox;
@ -495,11 +496,12 @@ preview_collection (int font_size,
gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (sw), eventbox);
desktop_color.red = 0x5144;
desktop_color.green = 0x75D6;
desktop_color.blue = 0xA699;
desktop_color.red = 0.32;
desktop_color.green = 0.46;
desktop_color.blue = 0.65;
desktop_color.alpha = 1.0;
gtk_widget_modify_bg (eventbox, GTK_STATE_NORMAL, &desktop_color);
gtk_widget_override_background_color (eventbox, 0, &desktop_color);
i = 0;
while (i < META_FRAME_TYPE_LAST)
@ -694,7 +696,7 @@ previews_of_button_layouts (void)
static gboolean initted = FALSE;
GtkWidget *box;
GtkWidget *sw;
GdkColor desktop_color;
GdkRGBA desktop_color;
int i;
GtkWidget *eventbox;
@ -718,11 +720,12 @@ previews_of_button_layouts (void)
gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (sw), eventbox);
desktop_color.red = 0x5144;
desktop_color.green = 0x75D6;
desktop_color.blue = 0xA699;
desktop_color.red = 0.32;
desktop_color.green = 0.46;
desktop_color.blue = 0.65;
desktop_color.alpha = 1.0;
gtk_widget_modify_bg (eventbox, GTK_STATE_NORMAL, &desktop_color);
gtk_widget_override_background_color (eventbox, 0, &desktop_color);
i = 0;
while (i < BUTTON_LAYOUT_COMBINATIONS)

View File

@ -63,14 +63,14 @@
#define GDK_COLOR_RGBA(color) \
((guint32) (0xff | \
(((color).red / 256) << 24) | \
(((color).green / 256) << 16) | \
(((color).blue / 256) << 8)))
((int)((color).red * 255) << 24) | \
((int)((color).green * 255) << 16) | \
((int)((color).blue * 255) << 8)))
#define GDK_COLOR_RGB(color) \
((guint32) ((((color).red / 256) << 16) | \
(((color).green / 256) << 8) | \
(((color).blue / 256))))
((guint32) (((int)((color).red * 255) << 16) | \
((int)((color).green * 255) << 8) | \
((int)((color).blue * 255))))
#define ALPHA_TO_UCHAR(d) ((unsigned char) ((d) * 255))
@ -78,8 +78,8 @@
#define CLAMP_UCHAR(v) ((guchar) (CLAMP (((int)v), (int)0, (int)255)))
#define INTENSITY(r, g, b) ((r) * 0.30 + (g) * 0.59 + (b) * 0.11)
static void gtk_style_shade (GdkColor *a,
GdkColor *b,
static void gtk_style_shade (GdkRGBA *a,
GdkRGBA *b,
gdouble k);
static void rgb_to_hls (gdouble *r,
gdouble *g,
@ -95,7 +95,7 @@ static MetaTheme *meta_current_theme = NULL;
static GdkPixbuf *
colorize_pixbuf (GdkPixbuf *orig,
GdkColor *new_color)
GdkRGBA *new_color)
{
GdkPixbuf *pixbuf;
double intensity;
@ -138,16 +138,16 @@ colorize_pixbuf (GdkPixbuf *orig,
if (intensity <= 0.5)
{
/* Go from black at intensity = 0.0 to new_color at intensity = 0.5 */
dr = (new_color->red * intensity * 2.0) / 65535.0;
dg = (new_color->green * intensity * 2.0) / 65535.0;
db = (new_color->blue * intensity * 2.0) / 65535.0;
dr = new_color->red * intensity * 2.0;
dg = new_color->green * intensity * 2.0;
db = new_color->blue * intensity * 2.0;
}
else
{
/* Go from new_color at intensity = 0.5 to white at intensity = 1.0 */
dr = (new_color->red + (65535 - new_color->red) * (intensity - 0.5) * 2.0) / 65535.0;
dg = (new_color->green + (65535 - new_color->green) * (intensity - 0.5) * 2.0) / 65535.0;
db = (new_color->blue + (65535 - new_color->blue) * (intensity - 0.5) * 2.0) / 65535.0;
dr = new_color->red + (1.0 - new_color->red) * (intensity - 0.5) * 2.0;
dg = new_color->green + (1.0 - new_color->green) * (intensity - 0.5) * 2.0;
db = new_color->blue + (1.0 - new_color->blue) * (intensity - 0.5) * 2.0;
}
dest[0] = CLAMP_UCHAR (255 * dr);
@ -172,18 +172,15 @@ colorize_pixbuf (GdkPixbuf *orig,
}
static void
color_composite (const GdkColor *bg,
const GdkColor *fg,
double alpha_d,
GdkColor *color)
color_composite (const GdkRGBA *bg,
const GdkRGBA *fg,
double alpha,
GdkRGBA *color)
{
guint16 alpha;
*color = *bg;
alpha = alpha_d * 0xffff;
color->red = color->red + (((fg->red - color->red) * alpha + 0x8000) >> 16);
color->green = color->green + (((fg->green - color->green) * alpha + 0x8000) >> 16);
color->blue = color->blue + (((fg->blue - color->blue) * alpha + 0x8000) >> 16);
color->red = color->red + (fg->red - color->red) * alpha;
color->green = color->green + (fg->green - color->green) * alpha;
color->blue = color->blue + (fg->blue - color->blue) * alpha;
}
/**
@ -1015,12 +1012,12 @@ meta_gradient_spec_free (MetaGradientSpec *spec)
GdkPixbuf*
meta_gradient_spec_render (const MetaGradientSpec *spec,
GtkWidget *widget,
GtkStyleContext *style,
int width,
int height)
{
int n_colors;
GdkColor *colors;
GdkRGBA *colors;
GSList *tmp;
int i;
GdkPixbuf *pixbuf;
@ -1030,13 +1027,13 @@ meta_gradient_spec_render (const MetaGradientSpec *spec,
if (n_colors == 0)
return NULL;
colors = g_new (GdkColor, n_colors);
colors = g_new (GdkRGBA, n_colors);
i = 0;
tmp = spec->color_specs;
while (tmp != NULL)
{
meta_color_spec_render (tmp->data, widget, &colors[i]);
meta_color_spec_render (tmp->data, style, &colors[i]);
tmp = tmp->next;
++i;
@ -1121,6 +1118,10 @@ meta_color_spec_new (MetaColorSpecType type)
size += sizeof (dummy.data.gtk);
break;
case META_COLOR_SPEC_GTK_CUSTOM:
size += sizeof (dummy.data.gtkcustom);
break;
case META_COLOR_SPEC_BLEND:
size += sizeof (dummy.data.blend);
break;
@ -1152,6 +1153,14 @@ meta_color_spec_free (MetaColorSpec *spec)
DEBUG_FILL_STRUCT (&spec->data.gtk);
break;
case META_COLOR_SPEC_GTK_CUSTOM:
if (spec->data.gtkcustom.color_name)
g_free (spec->data.gtkcustom.color_name);
if (spec->data.gtkcustom.fallback)
meta_color_spec_free (spec->data.gtkcustom.fallback);
DEBUG_FILL_STRUCT (&spec->data.gtkcustom);
break;
case META_COLOR_SPEC_BLEND:
if (spec->data.blend.foreground)
meta_color_spec_free (spec->data.blend.foreground);
@ -1182,13 +1191,74 @@ meta_color_spec_new_from_string (const char *str,
spec = NULL;
if (str[0] == 'g' && str[1] == 't' && str[2] == 'k' && str[3] == ':')
if (str[0] == 'g' && str[1] == 't' && str[2] == 'k' && str[3] == ':' &&
str[4] == 'c' && str[5] == 'u' && str[6] == 's' && str[7] == 't' &&
str[8] == 'o' && str[9] == 'm')
{
const char *color_name_start, *fallback_str_start, *end;
char *color_name, *fallback_str;
MetaColorSpec *fallback = NULL;
if (str[10] != '(')
{
g_set_error (err, META_THEME_ERROR,
META_THEME_ERROR_FAILED,
_("GTK custom color specification must have color name and fallback in parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\""),
str);
return NULL;
}
color_name_start = str + 11;
fallback_str_start = color_name_start;
while (*fallback_str_start && *fallback_str_start != ',')
{
if (!(g_ascii_isalnum (*fallback_str_start)
|| *fallback_str_start == '-'
|| *fallback_str_start == '_'))
{
g_set_error (err, META_THEME_ERROR,
META_THEME_ERROR_FAILED,
_("Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-_ are valid"),
*fallback_str_start);
return NULL;
}
fallback_str_start++;
}
fallback_str_start++;
end = strrchr (str, ')');
if (color_name_start == NULL || fallback_str_start == NULL || end == NULL)
{
g_set_error (err, META_THEME_ERROR,
META_THEME_ERROR_FAILED,
_("Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not fit the format"),
str);
return NULL;
}
fallback_str = g_strndup (fallback_str_start, end - fallback_str_start);
fallback = meta_color_spec_new_from_string (fallback_str, err);
g_free (fallback_str);
if (fallback == NULL)
return NULL;
color_name = g_strndup (color_name_start,
fallback_str_start - color_name_start - 1);
spec = meta_color_spec_new (META_COLOR_SPEC_GTK_CUSTOM);
spec->data.gtkcustom.color_name = color_name;
spec->data.gtkcustom.fallback = fallback;
}
else if (str[0] == 'g' && str[1] == 't' && str[2] == 'k' && str[3] == ':')
{
/* GTK color */
const char *bracket;
const char *end_bracket;
char *tmp;
GtkStateType state;
GtkStateFlags state;
MetaGtkColorComponent component;
bracket = str;
@ -1381,7 +1451,7 @@ meta_color_spec_new_from_string (const char *str,
{
spec = meta_color_spec_new (META_COLOR_SPEC_BASIC);
if (!gdk_color_parse (str, &spec->data.basic.color))
if (!gdk_rgba_parse (&spec->data.basic.color, str))
{
g_set_error (err, META_THEME_ERROR,
META_THEME_ERROR_FAILED,
@ -1403,7 +1473,7 @@ meta_color_spec_new_from_string (const char *str,
*/
MetaColorSpec*
meta_color_spec_new_gtk (MetaGtkColorComponent component,
GtkStateType state)
GtkStateFlags state)
{
MetaColorSpec *spec;
@ -1415,18 +1485,90 @@ meta_color_spec_new_gtk (MetaGtkColorComponent component,
return spec;
}
/* Based on set_color() in gtkstyle.c */
#define LIGHTNESS_MULT 1.3
#define DARKNESS_MULT 0.7
void
meta_color_spec_render (MetaColorSpec *spec,
GtkWidget *widget,
GdkColor *color)
meta_gtk_style_get_light_color (GtkStyleContext *style,
GtkStateFlags state,
GdkRGBA *color)
{
GtkStyle *style;
gtk_style_context_get_background_color (style, state, color);
gtk_style_shade (color, color, LIGHTNESS_MULT);
}
style = gtk_widget_get_style (widget);
void
meta_gtk_style_get_dark_color (GtkStyleContext *style,
GtkStateFlags state,
GdkRGBA *color)
{
gtk_style_context_get_background_color (style, state, color);
gtk_style_shade (color, color, DARKNESS_MULT);
}
static void
meta_set_color_from_style (GdkRGBA *color,
GtkStyleContext *context,
GtkStateFlags state,
MetaGtkColorComponent component)
{
GdkRGBA other;
switch (component)
{
case META_GTK_COLOR_BG:
case META_GTK_COLOR_BASE:
gtk_style_context_get_background_color (context, state, color);
break;
case META_GTK_COLOR_FG:
case META_GTK_COLOR_TEXT:
gtk_style_context_get_color (context, state, color);
break;
case META_GTK_COLOR_TEXT_AA:
gtk_style_context_get_color (context, state, color);
meta_set_color_from_style (&other, context, state, META_GTK_COLOR_BASE);
color->red = (color->red + other.red) / 2;
color->green = (color->green + other.green) / 2;
color->blue = (color->blue + other.blue) / 2;
break;
case META_GTK_COLOR_MID:
meta_gtk_style_get_light_color (context, state, color);
meta_gtk_style_get_dark_color (context, state, &other);
color->red = (color->red + other.red) / 2;
color->green = (color->green + other.green) / 2;
color->blue = (color->blue + other.blue) / 2;
break;
case META_GTK_COLOR_LIGHT:
meta_gtk_style_get_light_color (context, state, color);
break;
case META_GTK_COLOR_DARK:
meta_gtk_style_get_dark_color (context, state, color);
break;
case META_GTK_COLOR_LAST:
g_assert_not_reached ();
break;
}
}
static void
meta_set_custom_color_from_style (GdkRGBA *color,
GtkStyleContext *context,
char *color_name,
MetaColorSpec *fallback)
{
if (!gtk_style_context_lookup_color (context, color_name, color))
meta_color_spec_render (fallback, context, color);
}
void
meta_color_spec_render (MetaColorSpec *spec,
GtkStyleContext *context,
GdkRGBA *color)
{
g_return_if_fail (spec != NULL);
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (style != NULL);
g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
switch (spec->type)
{
@ -1435,44 +1577,25 @@ meta_color_spec_render (MetaColorSpec *spec,
break;
case META_COLOR_SPEC_GTK:
switch (spec->data.gtk.component)
{
case META_GTK_COLOR_BG:
*color = style->bg[spec->data.gtk.state];
break;
case META_GTK_COLOR_FG:
*color = style->fg[spec->data.gtk.state];
break;
case META_GTK_COLOR_BASE:
*color = style->base[spec->data.gtk.state];
break;
case META_GTK_COLOR_TEXT:
*color = style->text[spec->data.gtk.state];
break;
case META_GTK_COLOR_LIGHT:
*color = style->light[spec->data.gtk.state];
break;
case META_GTK_COLOR_DARK:
*color = style->dark[spec->data.gtk.state];
break;
case META_GTK_COLOR_MID:
*color = style->mid[spec->data.gtk.state];
break;
case META_GTK_COLOR_TEXT_AA:
*color = style->text_aa[spec->data.gtk.state];
break;
case META_GTK_COLOR_LAST:
g_assert_not_reached ();
break;
}
meta_set_color_from_style (color,
context,
spec->data.gtk.state,
spec->data.gtk.component);
break;
case META_COLOR_SPEC_GTK_CUSTOM:
meta_set_custom_color_from_style (color,
context,
spec->data.gtkcustom.color_name,
spec->data.gtkcustom.fallback);
break;
case META_COLOR_SPEC_BLEND:
{
GdkColor bg, fg;
GdkRGBA bg, fg;
meta_color_spec_render (spec->data.blend.background, widget, &bg);
meta_color_spec_render (spec->data.blend.foreground, widget, &fg);
meta_color_spec_render (spec->data.blend.background, context, &bg);
meta_color_spec_render (spec->data.blend.foreground, context, &fg);
color_composite (&bg, &fg, spec->data.blend.alpha,
&spec->data.blend.color);
@ -1483,7 +1606,7 @@ meta_color_spec_render (MetaColorSpec *spec,
case META_COLOR_SPEC_SHADE:
{
meta_color_spec_render (spec->data.shade.base, widget,
meta_color_spec_render (spec->data.shade.base, context,
&spec->data.shade.color);
gtk_style_shade (&spec->data.shade.color,
@ -2639,11 +2762,13 @@ meta_theme_replace_constants (MetaTheme *theme,
{
if (meta_theme_lookup_int_constant (theme, t->d.v.name, &ival))
{
g_free (t->d.v.name);
t->type = POS_TOKEN_INT;
t->d.i.val = ival;
}
else if (meta_theme_lookup_float_constant (theme, t->d.v.name, &dval))
{
g_free (t->d.v.name);
t->type = POS_TOKEN_DOUBLE;
t->d.d.val = dval;
}
@ -3253,7 +3378,7 @@ scale_and_alpha_pixbuf (GdkPixbuf *src,
static GdkPixbuf*
draw_op_as_pixbuf (const MetaDrawOp *op,
GtkWidget *widget,
GtkStyleContext *context,
const MetaDrawInfo *info,
int width,
int height)
@ -3274,10 +3399,10 @@ draw_op_as_pixbuf (const MetaDrawOp *op,
case META_DRAW_RECTANGLE:
if (op->data.rectangle.filled)
{
GdkColor color;
GdkRGBA color;
meta_color_spec_render (op->data.rectangle.color_spec,
widget,
context,
&color);
pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
@ -3296,12 +3421,12 @@ draw_op_as_pixbuf (const MetaDrawOp *op,
case META_DRAW_TINT:
{
GdkColor color;
GdkRGBA color;
guint32 rgba;
gboolean has_alpha;
meta_color_spec_render (op->data.rectangle.color_spec,
widget,
context,
&color);
has_alpha =
@ -3344,7 +3469,7 @@ draw_op_as_pixbuf (const MetaDrawOp *op,
case META_DRAW_GRADIENT:
{
pixbuf = meta_gradient_spec_render (op->data.gradient.gradient_spec,
widget, width, height);
context, width, height);
pixbuf = apply_alpha (pixbuf,
op->data.gradient.alpha_spec,
@ -3357,10 +3482,10 @@ draw_op_as_pixbuf (const MetaDrawOp *op,
{
if (op->data.image.colorize_spec)
{
GdkColor color;
GdkRGBA color;
meta_color_spec_render (op->data.image.colorize_spec,
widget, &color);
context, &color);
if (op->data.image.colorize_cache_pixbuf == NULL ||
op->data.image.colorize_cache_pixel != GDK_COLOR_RGB (color))
@ -3472,29 +3597,6 @@ fill_env (MetaPositionExprEnv *env,
env->theme = meta_current_theme;
}
static GtkStateFlags
state_flags_from_gtk_state (GtkStateType state)
{
switch (state)
{
case GTK_STATE_NORMAL:
return 0;
case GTK_STATE_PRELIGHT:
return GTK_STATE_FLAG_PRELIGHT;
case GTK_STATE_ACTIVE:
return GTK_STATE_FLAG_ACTIVE;
case GTK_STATE_SELECTED:
return GTK_STATE_FLAG_SELECTED;
case GTK_STATE_INSENSITIVE:
return GTK_STATE_FLAG_INSENSITIVE;
case GTK_STATE_INCONSISTENT:
return GTK_STATE_FLAG_INCONSISTENT;
case GTK_STATE_FOCUSED:
return GTK_STATE_FLAG_FOCUSED;
}
return 0;
}
/* This code was originally rendering anti-aliased using X primitives, and
* now has been switched to draw anti-aliased using cairo. In general, the
@ -3516,7 +3618,7 @@ meta_draw_op_draw_with_env (const MetaDrawOp *op,
MetaRectangle rect,
MetaPositionExprEnv *env)
{
GdkColor color;
GdkRGBA color;
cairo_save (cr);
gtk_style_context_save (style_gtk);
@ -3529,8 +3631,8 @@ meta_draw_op_draw_with_env (const MetaDrawOp *op,
{
int x1, x2, y1, y2;
meta_color_spec_render (op->data.line.color_spec, widget, &color);
gdk_cairo_set_source_color (cr, &color);
meta_color_spec_render (op->data.line.color_spec, style_gtk, &color);
gdk_cairo_set_source_rgba (cr, &color);
if (op->data.line.width > 0)
cairo_set_line_width (cr, op->data.line.width);
@ -3604,8 +3706,9 @@ meta_draw_op_draw_with_env (const MetaDrawOp *op,
{
int rx, ry, rwidth, rheight;
meta_color_spec_render (op->data.rectangle.color_spec, widget, &color);
gdk_cairo_set_source_color (cr, &color);
meta_color_spec_render (op->data.rectangle.color_spec,
style_gtk, &color);
gdk_cairo_set_source_rgba (cr, &color);
rx = parse_x_position_unchecked (op->data.rectangle.x, env);
ry = parse_y_position_unchecked (op->data.rectangle.y, env);
@ -3634,8 +3737,8 @@ meta_draw_op_draw_with_env (const MetaDrawOp *op,
double start_angle, end_angle;
double center_x, center_y;
meta_color_spec_render (op->data.arc.color_spec, widget, &color);
gdk_cairo_set_source_color (cr, &color);
meta_color_spec_render (op->data.arc.color_spec, style_gtk, &color);
gdk_cairo_set_source_rgba (cr, &color);
rx = parse_x_position_unchecked (op->data.arc.x, env);
ry = parse_y_position_unchecked (op->data.arc.y, env);
@ -3689,8 +3792,9 @@ meta_draw_op_draw_with_env (const MetaDrawOp *op,
if (!needs_alpha)
{
meta_color_spec_render (op->data.tint.color_spec, widget, &color);
gdk_cairo_set_source_color (cr, &color);
meta_color_spec_render (op->data.tint.color_spec,
style_gtk, &color);
gdk_cairo_set_source_rgba (cr, &color);
cairo_rectangle (cr, rx, ry, rwidth, rheight);
cairo_fill (cr);
@ -3699,7 +3803,7 @@ meta_draw_op_draw_with_env (const MetaDrawOp *op,
{
GdkPixbuf *pixbuf;
pixbuf = draw_op_as_pixbuf (op, widget, info,
pixbuf = draw_op_as_pixbuf (op, style_gtk, info,
rwidth, rheight);
if (pixbuf)
@ -3723,7 +3827,7 @@ meta_draw_op_draw_with_env (const MetaDrawOp *op,
rwidth = parse_size_unchecked (op->data.gradient.width, env);
rheight = parse_size_unchecked (op->data.gradient.height, env);
pixbuf = draw_op_as_pixbuf (op, widget, info,
pixbuf = draw_op_as_pixbuf (op, style_gtk, info,
rwidth, rheight);
if (pixbuf)
@ -3750,7 +3854,7 @@ meta_draw_op_draw_with_env (const MetaDrawOp *op,
rwidth = parse_size_unchecked (op->data.image.width, env);
rheight = parse_size_unchecked (op->data.image.height, env);
pixbuf = draw_op_as_pixbuf (op, widget, info,
pixbuf = draw_op_as_pixbuf (op, style_gtk, info,
rwidth, rheight);
if (pixbuf)
@ -3796,8 +3900,7 @@ meta_draw_op_draw_with_env (const MetaDrawOp *op,
return;
}
gtk_style_context_set_state (style_gtk,
state_flags_from_gtk_state (op->data.gtk_arrow.state));
gtk_style_context_set_state (style_gtk, op->data.gtk_arrow.state);
gtk_render_arrow (style_gtk, cr, angle, rx, ry, size);
}
break;
@ -3811,8 +3914,7 @@ meta_draw_op_draw_with_env (const MetaDrawOp *op,
rwidth = parse_size_unchecked (op->data.gtk_box.width, env);
rheight = parse_size_unchecked (op->data.gtk_box.height, env);
gtk_style_context_set_state (style_gtk,
state_flags_from_gtk_state (op->data.gtk_box.state));
gtk_style_context_set_state (style_gtk, op->data.gtk_box.state);
gtk_render_background (style_gtk, cr, rx, ry, rwidth, rheight);
gtk_render_frame (style_gtk, cr, rx, ry, rwidth, rheight);
}
@ -3826,8 +3928,7 @@ meta_draw_op_draw_with_env (const MetaDrawOp *op,
ry1 = parse_y_position_unchecked (op->data.gtk_vline.y1, env);
ry2 = parse_y_position_unchecked (op->data.gtk_vline.y2, env);
gtk_style_context_set_state (style_gtk,
state_flags_from_gtk_state (op->data.gtk_vline.state));
gtk_style_context_set_state (style_gtk, op->data.gtk_vline.state);
gtk_render_line (style_gtk, cr, rx, ry1, rx, ry2);
}
break;
@ -3840,7 +3941,7 @@ meta_draw_op_draw_with_env (const MetaDrawOp *op,
rwidth = parse_size_unchecked (op->data.icon.width, env);
rheight = parse_size_unchecked (op->data.icon.height, env);
pixbuf = draw_op_as_pixbuf (op, widget, info,
pixbuf = draw_op_as_pixbuf (op, style_gtk, info,
rwidth, rheight);
if (pixbuf)
@ -3862,8 +3963,9 @@ meta_draw_op_draw_with_env (const MetaDrawOp *op,
int rx, ry;
PangoRectangle ink_rect, logical_rect;
meta_color_spec_render (op->data.title.color_spec, widget, &color);
gdk_cairo_set_source_color (cr, &color);
meta_color_spec_render (op->data.title.color_spec,
style_gtk, &color);
gdk_cairo_set_source_rgba (cr, &color);
rx = parse_x_position_unchecked (op->data.title.x, env);
ry = parse_y_position_unchecked (op->data.title.y, env);
@ -6312,45 +6414,45 @@ meta_gradient_type_to_string (MetaGradientType type)
return "<unknown>";
}
GtkStateType
GtkStateFlags
meta_gtk_state_from_string (const char *str)
{
if (g_ascii_strcasecmp ("normal", str) == 0)
return GTK_STATE_NORMAL;
return GTK_STATE_FLAG_NORMAL;
else if (g_ascii_strcasecmp ("prelight", str) == 0)
return GTK_STATE_PRELIGHT;
return GTK_STATE_FLAG_PRELIGHT;
else if (g_ascii_strcasecmp ("active", str) == 0)
return GTK_STATE_ACTIVE;
return GTK_STATE_FLAG_ACTIVE;
else if (g_ascii_strcasecmp ("selected", str) == 0)
return GTK_STATE_SELECTED;
return GTK_STATE_FLAG_SELECTED;
else if (g_ascii_strcasecmp ("insensitive", str) == 0)
return GTK_STATE_INSENSITIVE;
return GTK_STATE_FLAG_INSENSITIVE;
else if (g_ascii_strcasecmp ("inconsistent", str) == 0)
return GTK_STATE_INCONSISTENT;
return GTK_STATE_FLAG_INCONSISTENT;
else if (g_ascii_strcasecmp ("focused", str) == 0)
return GTK_STATE_FOCUSED;
return GTK_STATE_FLAG_FOCUSED;
else
return -1; /* hack */
}
const char*
meta_gtk_state_to_string (GtkStateType state)
meta_gtk_state_to_string (GtkStateFlags state)
{
switch (state)
{
case GTK_STATE_NORMAL:
case GTK_STATE_FLAG_NORMAL:
return "NORMAL";
case GTK_STATE_PRELIGHT:
case GTK_STATE_FLAG_PRELIGHT:
return "PRELIGHT";
case GTK_STATE_ACTIVE:
case GTK_STATE_FLAG_ACTIVE:
return "ACTIVE";
case GTK_STATE_SELECTED:
case GTK_STATE_FLAG_SELECTED:
return "SELECTED";
case GTK_STATE_INSENSITIVE:
case GTK_STATE_FLAG_INSENSITIVE:
return "INSENSITIVE";
case GTK_STATE_INCONSISTENT:
case GTK_STATE_FLAG_INCONSISTENT:
return "INCONSISTENT";
case GTK_STATE_FOCUSED:
case GTK_STATE_FLAG_FOCUSED:
return "FOCUSED";
}
@ -6480,17 +6582,17 @@ meta_image_fill_type_to_string (MetaImageFillType fill_type)
* \param k amount to scale lightness and saturation by
*/
static void
gtk_style_shade (GdkColor *a,
GdkColor *b,
gtk_style_shade (GdkRGBA *a,
GdkRGBA *b,
gdouble k)
{
gdouble red;
gdouble green;
gdouble blue;
red = (gdouble) a->red / 65535.0;
green = (gdouble) a->green / 65535.0;
blue = (gdouble) a->blue / 65535.0;
red = a->red;
green = a->green;
blue = a->blue;
rgb_to_hls (&red, &green, &blue);
@ -6508,9 +6610,9 @@ gtk_style_shade (GdkColor *a,
hls_to_rgb (&red, &green, &blue);
b->red = red * 65535.0;
b->green = green * 65535.0;
b->blue = blue * 65535.0;
b->red = red;
b->green = green;
b->blue = blue;
}
/**
@ -6697,7 +6799,7 @@ draw_bg_solid_composite (const MetaTextureSpec *bg,
int width,
int height)
{
GdkColor bg_color;
GdkRGBA bg_color;
g_assert (bg->type == META_TEXTURE_SOLID);
g_assert (fg->type != META_TEXTURE_COMPOSITE);
@ -6711,7 +6813,7 @@ draw_bg_solid_composite (const MetaTextureSpec *bg,
{
case META_TEXTURE_SOLID:
{
GdkColor fg_color;
GdkRGBA fg_color;
meta_color_spec_render (fg->data.solid.color_spec,
widget,

View File

@ -55,11 +55,7 @@ meta_tile_preview_draw (GtkWidget *widget,
if (preview->has_alpha)
{
/* Fill the preview area with a transparent color */
cairo_set_source_rgba (cr,
preview->preview_color->red,
preview->preview_color->green,
preview->preview_color->blue,
preview->preview_color->alpha);
gdk_cairo_set_source_rgba (cr, preview->preview_color);
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
cairo_paint (cr);
@ -175,6 +171,7 @@ meta_tile_preview_free (MetaTilePreview *preview)
void
meta_tile_preview_show (MetaTilePreview *preview,
MetaDevice *pointer,
MetaRectangle *tile_rect)
{
GdkWindow *window;
@ -189,9 +186,10 @@ meta_tile_preview_show (MetaTilePreview *preview,
gtk_widget_show (preview->preview_window);
window = gtk_widget_get_window (preview->preview_window);
meta_core_lower_beneath_focus_window (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
GDK_WINDOW_XID (window),
gtk_get_current_event_time ());
meta_core_lower_beneath_grab_window (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
GDK_WINDOW_XID (window),
meta_device_get_id (pointer),
gtk_get_current_event_time ());
old_rect.x = old_rect.y = 0;
old_rect.width = preview->tile_rect.width;

View File

@ -24,6 +24,7 @@
#define META_TILE_PREVIEW_H
#include <meta/boxes.h>
#include <meta/device.h>
typedef struct _MetaTilePreview MetaTilePreview;
@ -31,6 +32,7 @@ MetaTilePreview *meta_tile_preview_new (int screen_number,
gboolean composited);
void meta_tile_preview_free (MetaTilePreview *preview);
void meta_tile_preview_show (MetaTilePreview *preview,
MetaDevice *pointer,
MetaRectangle *rect);
void meta_tile_preview_hide (MetaTilePreview *preview);
Window meta_tile_preview_get_xwindow (MetaTilePreview *preview,

View File

@ -30,6 +30,7 @@
#include "menu.h"
#include "core.h"
#include "theme-private.h"
#include "input-events.h"
#include "inlinepixbufs.h"
@ -60,15 +61,8 @@ struct _MetaUI
void
meta_ui_init (void)
{
/* As of 2.91.7, Gdk uses XI2 by default, which conflicts with the
* direct X calls we use - in particular, events caused by calls to
* XGrabPointer/XGrabKeyboard are no longer understood by GDK, while
* GDK will no longer generate the core XEvents we process.
* So at least for now, enforce the previous behavior.
*/
#if GTK_CHECK_VERSION(2, 91, 7)
gdk_disable_multidevice ();
#endif
if (meta_get_use_core_devices ())
gdk_disable_multidevice ();
if (!gtk_init_check (NULL, NULL))
meta_fatal ("Unable to open X display %s\n", XDisplayName (NULL));
@ -102,27 +96,30 @@ maybe_redirect_mouse_event (XEvent *xevent)
{
GdkDisplay *gdisplay;
GdkDeviceManager *gmanager;
GdkDevice *gdevice;
MetaUI *ui;
GdkEvent *gevent;
GdkWindow *gdk_window;
Window window;
MetaDisplay *display;
MetaDevice *device;
gdouble x, y, x_root, y_root;
guint evtype, n_button;
Time evtime;
switch (xevent->type)
{
case ButtonPress:
case ButtonRelease:
window = xevent->xbutton.window;
break;
case MotionNotify:
window = xevent->xmotion.window;
break;
case EnterNotify:
case LeaveNotify:
window = xevent->xcrossing.window;
break;
default:
return FALSE;
}
display = meta_display_for_x_display (xevent->xany.display);
if (!meta_input_event_get_type (display, xevent, &evtype))
return FALSE;
if (evtype != ButtonPress &&
evtype != ButtonRelease &&
evtype != EnterNotify &&
evtype != LeaveNotify &&
evtype != MotionNotify)
return FALSE;
window = meta_input_event_get_window (display, xevent);
gdisplay = gdk_x11_lookup_xdisplay (xevent->xany.display);
ui = g_object_get_data (G_OBJECT (gdisplay), "meta-ui");
@ -133,18 +130,32 @@ maybe_redirect_mouse_event (XEvent *xevent)
if (gdk_window == NULL)
return FALSE;
device = meta_input_event_get_device (display, xevent);
if (!device)
return FALSE;
gmanager = gdk_display_get_device_manager (gdisplay);
gdevice = gdk_x11_device_manager_lookup (gmanager,
meta_device_get_id (device));
/* If GDK already thinks it has a grab, we better let it see events; this
* is the menu-navigation case and events need to get sent to the appropriate
* (client-side) subwindow for individual menu items.
*/
if (gdk_display_pointer_is_grabbed (gdisplay))
if (gdk_display_device_is_grabbed (gdisplay, gdevice))
return FALSE;
switch (xevent->type)
evtime = meta_input_event_get_time (display, xevent);
meta_input_event_get_coordinates (display, xevent,
&x, &y, &x_root, &y_root);
switch (evtype)
{
case ButtonPress:
case ButtonRelease:
if (xevent->type == ButtonPress)
meta_input_event_get_button (display, xevent, &n_button);
if (evtype == ButtonPress)
{
GtkSettings *settings = gtk_settings_get_default ();
int double_click_time;
@ -155,11 +166,11 @@ maybe_redirect_mouse_event (XEvent *xevent)
"gtk-double-click-distance", &double_click_distance,
NULL);
if (xevent->xbutton.button == ui->button_click_number &&
xevent->xbutton.window == ui->button_click_window &&
xevent->xbutton.time < ui->button_click_time + double_click_time &&
ABS (xevent->xbutton.x - ui->button_click_x) <= double_click_distance &&
ABS (xevent->xbutton.y - ui->button_click_y) <= double_click_distance)
if (n_button == ui->button_click_number &&
window == ui->button_click_window &&
evtime < ui->button_click_time + double_click_time &&
ABS ((int) x - ui->button_click_x) <= double_click_distance &&
ABS ((int) y - ui->button_click_y) <= double_click_distance)
{
gevent = gdk_event_new (GDK_2BUTTON_PRESS);
@ -168,11 +179,11 @@ maybe_redirect_mouse_event (XEvent *xevent)
else
{
gevent = gdk_event_new (GDK_BUTTON_PRESS);
ui->button_click_number = xevent->xbutton.button;
ui->button_click_window = xevent->xbutton.window;
ui->button_click_time = xevent->xbutton.time;
ui->button_click_x = xevent->xbutton.x;
ui->button_click_y = xevent->xbutton.y;
ui->button_click_number = n_button;
ui->button_click_window = window;
ui->button_click_time = evtime;
ui->button_click_x = (int) x;
ui->button_click_y = (int) y;
}
}
else
@ -181,25 +192,29 @@ maybe_redirect_mouse_event (XEvent *xevent)
}
gevent->button.window = g_object_ref (gdk_window);
gevent->button.button = xevent->xbutton.button;
gevent->button.time = xevent->xbutton.time;
gevent->button.x = xevent->xbutton.x;
gevent->button.y = xevent->xbutton.y;
gevent->button.x_root = xevent->xbutton.x_root;
gevent->button.y_root = xevent->xbutton.y_root;
gevent->button.button = n_button;
gevent->button.time = evtime;
gevent->button.x = x;
gevent->button.y = y;
gevent->button.x_root = x_root;
gevent->button.y_root = y_root;
break;
case MotionNotify:
gevent = gdk_event_new (GDK_MOTION_NOTIFY);
gevent->motion.type = GDK_MOTION_NOTIFY;
gevent->motion.window = g_object_ref (gdk_window);
gevent->motion.x = x;
gevent->motion.y = y;
gevent->motion.x_root = x_root;
gevent->motion.y_root = y_root;
break;
case EnterNotify:
case LeaveNotify:
gevent = gdk_event_new (xevent->type == EnterNotify ? GDK_ENTER_NOTIFY : GDK_LEAVE_NOTIFY);
gevent = gdk_event_new (evtype == EnterNotify ? GDK_ENTER_NOTIFY : GDK_LEAVE_NOTIFY);
gevent->crossing.window = g_object_ref (gdk_window);
gevent->crossing.x = xevent->xcrossing.x;
gevent->crossing.y = xevent->xcrossing.y;
gevent->crossing.x = x;
gevent->crossing.y = y;
break;
default:
g_assert_not_reached ();
@ -207,8 +222,7 @@ maybe_redirect_mouse_event (XEvent *xevent)
}
/* If we've gotten here, we've created the gdk_event and should send it on */
gmanager = gdk_display_get_device_manager (gdisplay);
gdk_event_set_device (gevent, gdk_device_manager_get_client_pointer (gmanager));
gdk_event_set_device (gevent, gdevice);
gtk_main_do_event (gevent);
gdk_event_free (gevent);
@ -382,7 +396,8 @@ meta_ui_create_frame_window (MetaUI *ui,
&attrs, attributes_mask);
gdk_window_resize (window, width, height);
gdk_window_set_support_multidevice (window, TRUE);
meta_frames_manage_window (ui->frames, GDK_WINDOW_XID (window), window);
return GDK_WINDOW_XID (window);
@ -444,6 +459,13 @@ meta_ui_unflicker_frame_bg (MetaUI *ui,
target_width, target_height);
}
void
meta_ui_update_frame_style (MetaUI *ui,
Window xwindow)
{
meta_frames_update_frame_style (ui->frames, xwindow);
}
void
meta_ui_repaint_frame (MetaUI *ui,
Window xwindow)
@ -470,6 +492,16 @@ meta_ui_apply_frame_shape (MetaUI *ui,
window_has_shape);
}
cairo_region_t *
meta_ui_get_frame_bounds (MetaUI *ui,
Window xwindow,
int window_width,
int window_height)
{
return meta_frames_get_frame_bounds (ui->frames, xwindow,
window_width, window_height);
}
void
meta_ui_queue_frame_draw (MetaUI *ui,
Window xwindow)
@ -506,12 +538,13 @@ meta_ui_window_menu_new (MetaUI *ui,
void
meta_ui_window_menu_popup (MetaWindowMenu *menu,
MetaDevice *device,
int root_x,
int root_y,
int button,
guint32 timestamp)
{
meta_window_menu_popup (menu, root_x, root_y, button, timestamp);
meta_window_menu_popup (menu, device, root_x, root_y, button, timestamp);
}
void

View File

@ -26,8 +26,10 @@
/* Don't include gtk.h or gdk.h here */
#include <meta/common.h>
#include <meta/device.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <cairo.h>
#include <glib.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
@ -104,6 +106,11 @@ void meta_ui_apply_frame_shape (MetaUI *ui,
int new_window_height,
gboolean window_has_shape);
cairo_region_t *meta_ui_get_frame_bounds (MetaUI *ui,
Window xwindow,
int window_width,
int window_height);
void meta_ui_queue_frame_draw (MetaUI *ui,
Window xwindow);
@ -111,6 +118,9 @@ void meta_ui_set_frame_title (MetaUI *ui,
Window xwindow,
const char *title);
void meta_ui_update_frame_style (MetaUI *ui,
Window window);
void meta_ui_repaint_frame (MetaUI *ui,
Window xwindow);
@ -123,6 +133,7 @@ MetaWindowMenu* meta_ui_window_menu_new (MetaUI *ui,
MetaWindowMenuFunc func,
gpointer data);
void meta_ui_window_menu_popup (MetaWindowMenu *menu,
MetaDevice *device,
int root_x,
int root_y,
int button,