Compare commits

..

432 Commits

Author SHA1 Message Date
Jasper St. Pierre
7947bcb0b0 dnd 2 2014-09-01 14:34:33 -07:00
Jasper St. Pierre
308cccc72c dnd 2014-09-01 14:34:33 -07:00
Jasper St. Pierre
074946ac0b hot offs 2014-09-01 14:34:33 -07:00
Jasper St. Pierre
9688a0d7bc wayland: Record the offset position
This is needed for DND surfaces. We should probably test to see if it's
used for cursor surfaces at all.
2014-09-01 14:34:33 -07:00
Jasper St. Pierre
604d2155ba window: Don't map the client window before placing it
A lot of applications assume that the window is fully positioned when it
gets the MapNotify, especially simple applications. Make sure that the
window is only mapped through the calc_showing logic.
2014-09-01 11:46:12 -07:00
Jasper St. Pierre
e7727d698f window: Make calc_showing private 2014-09-01 11:42:21 -07:00
Claude Paroz
a3f75f401c Updated French translation 2014-08-30 11:59:53 +02:00
Maria Mavridou
d342f7c429 Updated Greek translation 2014-08-28 19:33:49 +00:00
Yosef Or Boczko
bb2b26ca44 Updated Hebrew translation 2014-08-28 18:18:21 +03:00
Jasper St. Pierre
2f9840a51c compositor: Conditionalize some more Wayland support 2014-08-27 12:56:39 -04:00
Jasper St. Pierre
09aefdba43 compositor: Conditionalize more Wayland support 2014-08-27 12:41:26 -04:00
Jasper St. Pierre
4c8a408afc Only build Wayland protocols when we have Wayland 2014-08-27 12:07:11 -04:00
Jasper St. Pierre
4c08d9a53b configure: Don't conditionalize gbm
Let's just say it's required for now.
2014-08-27 12:05:00 -04:00
Jasper St. Pierre
b091cbf361 shaped-texture: Don't set a small minimum size
The shaped-texture is effectively fixed size. It doesn't make sense to
have less allocation than requested.
2014-08-27 10:00:19 -04:00
Jasper St. Pierre
a6fcda69ac shaped-texture: Remove the use of MetaWindowActor internals
I want to make this class an independent helper.
2014-08-27 10:00:19 -04:00
Jasper St. Pierre
9063e4568c configure: Conditionalize libinput and gbm too 2014-08-27 09:57:43 -04:00
Jasper St. Pierre
3d37b5d696 configure: Conditionalize WAYLAND_SCANNER too
It seems we forgot this.
2014-08-26 16:58:13 -04:00
Adel Gadllah
3a8bad1e6f meta-surface-actor: Fix is_argb32 for unredirected windows
meta_surface_actor_is_argb32 assumes that lack of stex means that a window is
ARGB32. When we unredirect a window we detach the texture so we end up without
a texture. Given that should_unredirect returns FALSE when a window is argb32,
we know that this window is indeed not ARGB32.

Returing TRUE in that case causes us to flip between redirected and
unredirected on every paint.

So fix that by returning FALSE in that case.
2014-08-26 18:59:02 +02:00
Carlos Garnacho
e822e51752 surface: Don't calculate geometry for buffer-less subsurfaces
A wl_surface may have a wl_subsurface interface, but no buffers attached
yet, even though the geometry calculation code for surfaces/subsurfaces
assumes everything has already a buffer.

Just skip subsurfaces that don't have a buffer, those can't be set
a geometry yet, and right now it's crashing accessing the texture from
the NULL surface->buffer.

https://bugzilla.gnome.org/show_bug.cgi?id=735452
2014-08-26 16:58:59 +02:00
Fran Diéguez
f9818f890b Updated Galician translations 2014-08-25 22:42:41 +02:00
Jasper St. Pierre
6526118d9f shaped-texture: Fix a typo in a comment 2014-08-25 10:52:07 -04:00
Jasper St. Pierre
c15b3b4a09 shaped-texture: Fix the logic when the blended region is empty
When the blended region was empty, meaning we didn't have to paint
anything blended -- the case for an app update -- was drawing the
entire window blended, because of a think-o in the complex and
complicated logic.

Fix this so that we don't draw anything for the blended region when
empty.
2014-08-25 09:30:15 -04:00
Jasper St. Pierre
e1acb69cf1 workspace: Don't try to move O-R windows when relocating workspaces
All we'll get for it is spam.
2014-08-25 09:00:00 -04:00
Jasper St. Pierre
8f757c7b80 workspace: Smarten assert in light of O-R windows
O-R windows appear in workspace->windows, which aren't relocatable,
so we can't simply check if the workspace is empty after relocating
all normal windows, since those windows remain.

Make sure that the only windows we have are those that are
on_all_workspaces.
2014-08-25 08:57:13 -04:00
Jasper St. Pierre
01a47c7d6d shaped-texture: If we have too many rectangles, don't paint the opaque
region first

If we're going to render the entire texture blended, then don't bother
painting the unblended stuff, since we're just going to draw on top
anyway.
2014-08-24 12:38:29 -04:00
Jasper St. Pierre
3ee09c6251 meta-monitor-xrandr: Assign a name to the mode
Based on a downstream Endless patch. They use this to show a proper mode
name to the users.
2014-08-23 08:54:06 -04:00
Kjartan Maraas
bb54f91dd1 Updated Norwegian bokmål translation. 2014-08-23 13:37:47 +02:00
Enrico Nicoletto
41a79530e9 Updated Brazilian Portuguese translation 2014-08-22 19:23:37 +00:00
Jasper St. Pierre
31f5a916f4 wayland: Tie XDG surfaces together with the Shell that created them
This means that we don't leak when a client binds an XdgShell for a
client more than once, and we send pings/pongs to the correct shell
interface.
2014-08-22 12:52:21 -04:00
Jasper St. Pierre
5657a671c1 xdg-shell: Bump unstable version 2014-08-22 12:07:56 -04:00
Rico Tzschichholz
ecc254c659 surface-actor-x11: Fix "incompatible pointer type" error
Caused by e73c46ce03
2014-08-22 07:38:08 +02:00
Jasper St. Pierre
9cb1c95e49 surface-actor: Call process_damage even when the actor is invisible
Otherwise, surface-actor-x11 won't be marked as having received damage,
which is vital to updating the actual surface.
2014-08-21 18:30:56 -04:00
Jasper St. Pierre
e73c46ce03 surface-actor-x11: Use the existing check for "visibility"
Instead of doing our own thing here.
2014-08-21 18:30:35 -04:00
Jasper St. Pierre
952e9c52bc surface-actor-x11: Merge a simple function inline
This is a one-liner, only used in one place.
2014-08-21 18:30:17 -04:00
Jasper St. Pierre
b879af46b3 stage: Refine our assertions for overlays in MetaStage
We indeed call this function if we're not an X11 compositor, but in this
case we're simply calling it to say that we have no cursor overlay. Make
sure not to assert fail in this case.
2014-08-21 18:06:53 -04:00
Jasper St. Pierre
9feb9d6bca events: Update the pointer position here
Rather than in the Wayland front-end, since it's really a core operation.
2014-08-21 17:00:55 -04:00
Jasper St. Pierre
dc0437a5b5 surface-actor-wayland: Pass in a CoglTexture, as well
This makes it so that MetaSurfaceActorWayland is effectively just a
wrapper actor around MetaShapedTexture with some extra scaling. I think
the MetaSurfaceActor subclassing was a bad idea -- we really should have
these abstractions in much higher levels in the stack than the
compositor.
2014-08-21 16:34:29 -04:00
Jasper St. Pierre
55331a0678 surface-actor-wayland: Don't store the buffer
We don't need to anymore -- we're purely texture based.
2014-08-21 16:24:30 -04:00
Jasper St. Pierre
f5580f61f9 wayland: Update the CoglTexture in the MetaWaylandSurface
It doesn't make sense to update it in the surface actor. It's also
theoretically wrong to update the buffer's texture on surface commit,
too, because it's buffer state, not surface state, but I don't think
there's any place we use a wl_buffer without a wl_surface.
2014-08-21 16:22:53 -04:00
Jasper St. Pierre
30953cf2d7 stage: Make the API take a CoglTexture
MetaCursorReference doesn't really need to be part of the API.
2014-08-21 15:04:58 -04:00
Jasper St. Pierre
c7fa446ee7 stage: Refactor the cursor drawing code into a generic "overlay" system
This isn't really anything but a really small actor system. This will be
used for DND cursors as well.
2014-08-21 15:04:57 -04:00
Jasper St. Pierre
9ecbac365b configure: Group X11 libraries at the end 2014-08-21 10:24:46 -04:00
Jasper St. Pierre
80f6fb6329 configure: Depend on at least libxkbcommon 0.4.3
This fixes a few bugs which we need for keybindings to work in mutter.
2014-08-21 10:13:30 -04:00
Jasper St. Pierre
1b596a114d configure: Add x11-xcb to required packages
We need to link against this library now because we're using
XGetXCBConnection. Whoops.
2014-08-21 10:12:51 -04:00
Chao-Hsiung Liao
265c00235b Updated Traditional Chinese translation(Hong Kong and Taiwan) 2014-08-21 18:55:35 +08:00
Florian Müllner
fae37222a7 Bump version to 3.13.90
Update NEWS.
2014-08-20 01:35:22 +02:00
Jasper St. Pierre
d41449b578 wayland: Initialize SHM again
Uh, whoops. I accidentally removed this when revamping the
initialization sequence. This causes bad things to happen.
2014-08-19 18:27:21 -04:00
Jasper St. Pierre
34979c3fe8 window: Don't try to map / unmap OR windows by ourselves
This is bad behavior, and can also cause us to get in an infinite loop
if an OR window is mapped and unmapped in quick succession. This
sequence causes a MapNotify followed by an UnmapNotify, and when
processing the events, we'll call XMapWindow, XUnmapWindow, which will
put another set of MapNotify, UnmapNotify events in our queue, which we
then process by calling XMapWindow, XUnmapWindow, and so it goes
forever, or at least some scheduler uncorks us by making us call
XMapWindow when the window is already mapped, or XUnmapWindow when the
window is already unmapped.

We can stop this madness by simply making sure never to call neither
XMapWindow or XUnmapWindow on OR windows, which is the correct thing to
do anyway.
2014-08-19 16:04:40 -04:00
Jasper St. Pierre
711f0c0c50 common: Make UNKNOWN a flag, not a combination of all directions
This was the original intention, but it was thought to be easier
to mark this as a combination of all directions. It turned out to
instead cause subtle bugs since code that blindly checked & DIR_WEST or
similar turned out to get it wrong when it was UNKNOWN, so just make
it an explicit flag.

This fixes the cursor appearing in the wrong place when starting a
keyboard resize.
2014-08-19 15:11:10 -04:00
Jasper St. Pierre
933d05a565 window: Fix the north/south cursor position when keyboard resizing
We got these backwards...
2014-08-19 15:10:55 -04:00
Jasper St. Pierre
8a0da1cb07 keybindings: Make sure to filter out the virtualized mod itself
When devirtualizing the modifier, we can't include the virtualized mod
itself, otherwise our grab won't have the correct mask.
2014-08-19 14:58:47 -04:00
Jasper St. Pierre
1445903a34 prefs: Don't crash when we get a preference changed we don't know about
We commonly used the generic, undetailed signal 'changed' to track
changes to preferences. Since we crash on unknown preference types,
this can be dangerous if somebody adds a new setting that has a
type we're unfamiliar with, and something else changes it.

Instead of crashing, just fizzle out doing nothing.
2014-08-19 14:07:55 -04:00
Jasper St. Pierre
5d9386df0c stack: Reindent 2014-08-19 14:03:43 -04:00
Jasper St. Pierre
6fd1de226b window: Add a hack to correct dragging from the top panel in gnome-shell
In gnome-shell, we have a feature where the user can unmaximize windows
by dragging them from the panel above the window. With accurate
anchoring, this looks really weird as the cursor is now "detached" from
the window. Detect this case and put the cursor in the middle of the
window titlebar instead.
2014-08-19 13:59:39 -04:00
Jasper St. Pierre
ac099343da window: Increase the height of CSD titlebars
This seems to be more accurate with what we currently see in
GNOME. Without having the app expose this information to us, it might be
a better idea to use the default frame style for this information instead.
2014-08-19 13:59:34 -04:00
Jasper St. Pierre
bce5f3f108 window: Fix cursor anchoring issues when drag-unmaximizing windows
The cursor was anchored wrongly when trying to unmaximize windows from
dragging them from the top of the screen because of a few think-o's and
some code that forgot to be updated when we moved to the frame rect
coordinate system.

The cursor is still offset for windows that start dragging from the top
panel. This is technically correct, but looks wrong. We'll fix this in
the next commit.
2014-08-19 13:48:00 -04:00
Jasper St. Pierre
35e0982e35 xrandr: Port some checks to XCB so we don't have to deal with BadName
RandR's QueryOutputProperty request makes the incredible decision of
throwing a BadName if you pass a property that doesn't exist, which
means that trying to check if a property exists is a royal pain when
using Xlib.

XCB's interface is much more friendly about errors and not having global
state and things like that, so use that instead to query our backlight
property.
2014-08-19 11:08:44 -04:00
Daniel Mustieles
767455e8d8 Updated Spanish translation 2014-08-19 13:03:41 +02:00
Jasper St. Pierre
6b8dda0d00 bell: Clean up the bell code
Fix some old comments and rework it so that it's based on MetaWindow,
not the XKB event structs.
2014-08-18 19:49:09 -04:00
Jasper St. Pierre
277df44cfb xrandr: Fix build
Gah, I keep forgetting to squash for some reason.
2014-08-18 18:01:04 -04:00
Jasper St. Pierre
2dded1e510 xrandr: Don't use RRQueryOutputProperty to fetch hotplug_mode_update
If the property doesn't exist, a BadName error will be generated. This
is a terrible API, but it's what we're stuck with. Use
RRGetOutputProperty instead.
2014-08-18 18:00:33 -04:00
Jasper St. Pierre
a7b1b1da80 main: Clean up the initialization sequence
The initialization sequence before was quite icky, initializing Clutter
in a few different places depending on what was going on.

Put that all back into main.c
2014-08-18 16:57:00 -04:00
Jasper St. Pierre
de69678085 main: Clutter does not have to be initialized after the UI
I'm not sure this was ever true. Clutter can be (and should be!)
initialized beforehand.
2014-08-18 16:50:05 -04:00
Jasper St. Pierre
5f7b81eb95 keybindings: Use a less hacky method of getting the proper modifier mask
This is the method Ran suggests as a workaround in
https://github.com/xkbcommon/libxkbcommon/pull/10
2014-08-18 15:54:34 -04:00
Jasper St. Pierre
f4f70afe31 window-x11: Fix the coordinates we use in the synthetic ConfigureNotify
Before, we were using the root window coordinates of the client window,
rather than the toplevel frame window. This caused various Java programs
and programs like VirtualBox and WINE to get confused about where their
window actually is, and make bad ConfigureRequests when trying to
position their windows in the future.

Remove the mass of code here by just using window->rect.
2014-08-18 14:41:36 -04:00
ngoswami
116957b339 Updated Assamese translation 2014-08-18 16:09:20 +00:00
Jasper St. Pierre
1af0033368 keybindings: Rewrite the keymap code so that it uses libxkbcommon
This way we aren't depending on Xwayland for native key mapping support,
and are instead using the native interfaces.
2014-08-18 09:11:50 -04:00
Jasper St. Pierre
3645c63c08 keybindings: Rewrite the modmap code so that it uses libxkbcommon
This removes our Xwayland dependency in the native path. The direct
grabs are still there for the X11 backend and are a bit disgusting,
but that's OK. We can refactor it out later.

This introduces some pretty lousy hackery because it depends on
https://github.com/xkbcommon/libxkbcommon/pull/10 , and I really
don't want to wait on that to squash this dep.
2014-08-18 09:11:50 -04:00
Christophe Fergeau
04ddfe0a6f Don't remove meta/meta-version.h during make clean
meta/meta-version.h is generated by configure, so it should be removed
with make distclean, not make clean. This is the heuristic described in
https://www.gnu.org/software/automake/manual/html_node/Clean.html

Cleaning it in make clean means that configure; make clean; make won't
work properly as meta/meta-version.h will be removed and not
regenerated.

https://bugzilla.gnome.org/show_bug.cgi?id=734960
2014-08-18 10:17:57 +02:00
Christophe Fergeau
ec3dc4a607 Don't list meta/meta-version.h in mutter_built_sources
It's already listed in libmutterinclude_built_headers.

https://bugzilla.gnome.org/show_bug.cgi?id=734960
2014-08-18 10:17:57 +02:00
Jasper St. Pierre
0b98fbab0a Remove a few extra "ui.h" includes 2014-08-17 23:02:15 -04:00
Jasper St. Pierre
5b8dc37c31 prefs: Fix indentation 2014-08-17 23:00:05 -04:00
Jasper St. Pierre
f42258327b util: Move the text direction stuff out of MetaUI
GTK+ doesn't need to be initialized to get locale direction,
which means we can do this without bringing up MetaUI at all.
2014-08-17 22:59:43 -04:00
Jasper St. Pierre
7d1ef3f447 keybindings: Remove unused includes 2014-08-17 22:53:42 -04:00
Jasper St. Pierre
652fe57cdd prefs: Completely remove references to REVERSES
And fill up the gap in the flags as well
2014-08-17 22:48:51 -04:00
Christophe Fergeau
20a6243c85 Remove use of META_KEY_BINDING_REVERSES
Now that the internal mutter bindings and gnome-shell stopped using
META_KEY_BINDING_REVERSES, and after moving the 'adding shift reverses
the keybinding action' logic to gnome-control-center, we can remove
META_KEY_BINDING_REVERSES from mutter.

Plugin API is broken as this constant is removed from the exported
headers. ABI is broken as using this flag is now a noop.

https://bugzilla.gnome.org/show_bug.cgi?id=732385
2014-08-17 19:29:43 +02:00
Christophe Fergeau
679edac9c3 Add hidden -backward bindings to 50-mutter-navigation.xml
This makes the gnome-control-center keyboard panel aware of these
bindings so that it can warn about conflicting bindings if the
user tries to use one of these bindings for a different action.

https://bugzilla.gnome.org/show_bug.cgi?id=732385
2014-08-17 19:29:43 +02:00
Christophe Fergeau
bb59b8c249 Don't automatically add bindings for -backward actions
Currently the bindings for {switch,cycle}.* actions are created with the
META_KEY_BINDING_REVERSES flag so that <shift>+binding triggers the
reverse action. However, gnome-control-center does not know about this
kind of implicit bindings, and, for example, cannot warn when the user
tries to setup a conflicting <shift>+xxx binding.

These backward <shift> bindings are being explicitly set in
gsettings-desktop-schemas, so the META_KEY_BINDING_REVERSES annotation
can be removed for them from mutter.

https://bugzilla.gnome.org/show_bug.cgi?id=732385
2014-08-17 19:29:43 +02:00
Christophe Fergeau
c5c6b2257f Add meta_key_binding_is_reversed()
MetaKeyBinding can be marked as being reversed
(META_KEY_BINDING_IS_REVERSED), but MetaKeyHandlerFunc callbacks
cannot check whether this flag was set or not on the MetaKeyBinding
which triggered the callback.

https://bugzilla.gnome.org/show_bug.cgi?id=732295
2014-08-17 19:29:43 +02:00
Lasse Liehu
6acf7b06f4 Finnish translation update 2014-08-17 14:36:30 +03:00
Jasper St. Pierre
d0c004c93c common: Don't define _WGO_BASE inside the enum
Doing this causes gobject-introspection to mess up and think that
the enum prefix is the empty string. Just use the long name within
the enum defines.
2014-08-16 15:50:39 -04:00
Jasper St. Pierre
53876d2b62 wayland-pointer: Squash warning
This should never happen.
2014-08-16 15:38:25 -04:00
Jasper St. Pierre
2b63b17327 wayland-pointer: Insert missing break;s 2014-08-16 15:38:15 -04:00
Jasper St. Pierre
226a09b38c display: Fix inversion for meta_grab_op_is_*
*sigh*, the inline function was supposed to prevent mistakes like this.
2014-08-16 15:24:05 -04:00
Jasper St. Pierre
527c53a2a0 workspace: Rewrite workspace management code
The existing workspace management code is quite hairy, with plenty of
logic inline in all of window.c, workspace.c, and screen.c, making it
hard to understand or make changes to, since you might forget to change
several of the other places the code was around.

Rewrite the internal workspace management logic so that it's
centralized and all in window.c. Document the invariants we need to
maintain, and ensure that these invariants are properly kept, with
asserts in various places.

Extensive testing on gnome-shell did not bring up any issues, and this
is a considerable cleanup.
2014-08-16 14:59:13 -04:00
Jasper St. Pierre
19795c1681 workspace: Add a "workspace-index" property to MetaWorkspace
This will be used to replace some of the hooks that are used to call
into window.c, so that the workspace index property is properly kept up
to date.

We can't name the property "index" since it causes conflicts with the
meta_workspace_index method. This should really be called
meta_workspace_get_index, but oh well.
2014-08-16 14:56:38 -04:00
Jasper St. Pierre
1999fcaa8f workspace: Use G_PARAM_STATIC_STRINGS 2014-08-16 14:53:58 -04:00
Jasper St. Pierre
6b5ff8fd74 workspace: Use g_object_class_install_properties 2014-08-16 14:53:58 -04:00
Jasper St. Pierre
821d946a72 workspace: Use for loops instead of whiles to iterate through lists 2014-08-16 14:53:58 -04:00
Jasper St. Pierre
5f7c901727 workspace: Make the code for removing windows easier to read
Repeatedly pop off the head of the list rather than iterating through
it.
2014-08-16 14:53:58 -04:00
Jasper St. Pierre
7b8ee4ee1e workspace: Replace a boolean ^ with !=
This is a lot easier to understand.
2014-08-16 14:53:57 -04:00
Jasper St. Pierre
32cf4afb04 screen: Fix workspace removal
I accidentally broke this in commit a119ea9. The code was considerably
more complicated than it needs to be, so let's replace it with a
g_list_find and nothing more.
2014-08-16 14:53:57 -04:00
Jasper St. Pierre
e0c92befd5 prefs: Actually insert the SCHEMA_MOUSE settings 2014-08-15 20:24:11 -04:00
Jasper St. Pierre
827e0341ab screen: Add the list window flags to meta_screen_foreach_window
So we can ditch a manual use of list_windows.
2014-08-15 20:21:39 -04:00
Jasper St. Pierre
8627b65f8d screen: Drop the MetaScreen parameter from the foreach function
It's unused.
2014-08-15 20:19:40 -04:00
Jasper St. Pierre
9c62a907c5 screen: Make meta_screen_foreach_window scan Wayland windows
Scanning over the hash table of XIDs is a terrible idea. Not only were
we excluding Wayland windows, but we were also looking at alarms and
barriers, too. We were lucky that that only contained GObjects where
our checks would work.
2014-08-15 20:13:59 -04:00
Jasper St. Pierre
a119ea96a3 screen: Use the standard for-loop iteration for iterating over lists 2014-08-15 19:52:16 -04:00
Jasper St. Pierre
06d55bf019 screen: Remove a bunch of screen checks
Now that we only manage one screen, this isn't necessary anymore.
2014-08-15 19:43:08 -04:00
Jasper St. Pierre
320f38de47 screen: Simplify meta_screen_get_workspace_by_index 2014-08-15 19:41:37 -04:00
Jasper St. Pierre
7adfaceccf screen: Remove blank and unused function 2014-08-15 19:35:42 -04:00
Jasper St. Pierre
67be4e2bf3 window: Don't use GTK+ to fetch the drag threshold
Just look it up in GSettings ourselves.
2014-08-15 18:35:20 -04:00
Jasper St. Pierre
c3e87ee896 display: Replace the inline logic with a static inline
So we won't get it wrong in the future.
2014-08-15 17:44:25 -04:00
Jasper St. Pierre
f2283ec634 display: Fix the base type check inside is_keyboard 2014-08-15 17:43:26 -04:00
Jasper St. Pierre
d06e4beb7f display: Use a named mask constant inside is_moving / is_resizing
This helps clear up what's going on a bit.
2014-08-15 17:43:00 -04:00
Jasper St. Pierre
e24863d175 display: Remove meta_grab_op_is_moving_or_resizing
It's unused.
2014-08-15 17:42:24 -04:00
Jasper St. Pierre
2de2241690 display: Fix meta_grab_op_is_moving 2014-08-15 17:40:01 -04:00
Jasper St. Pierre
977de8c5d4 events: Fix get_window_for_event for the new route logic
I forgot to write the new logic for this function.
2014-08-15 17:40:01 -04:00
Jasper St. Pierre
fb6438cdd4 keybindings: Hardcode Mod2Mask for Num Lock
This is actually part of the XKB specification, so we don't need to look
for it at runtime.
2014-08-15 16:22:16 -04:00
Jasper St. Pierre
517e8f6fbd common: Create a better encoding for MetaGrabOp
MetaGrabOp is painful and tedious to work with, because it's a
sequential series of values, meaning we have to use a giant unreadable
switch statement to figure out some basic things about the value.

To solve this, modify the encoding for MetaGrabOp and for the specific
window grab operations so that they're a set of bitflags that we can
easily check.
2014-08-15 16:08:49 -04:00
Jasper St. Pierre
0e758a9e65 display: Establish a separate state variable for routing events
We've long used a switch statement on the grab operation to determine
where events should go. The issue with MetaGrabOp is that it's a mixture
of a few different things, including event routing, state management,
and the behavior to choose during operations.

This leads to poorly defined event routing and hard-to-follow logic,
since it's sometimes unclear what should point where, and our utility
methods for determining grab operations apart can be poorly named.

To fix this, establish the concept of a "event route", which describes
where events should be routed to.
2014-08-15 16:08:49 -04:00
Jasper St. Pierre
64a915a68d window: Fix build
I break things a lot now.
2014-08-15 16:08:25 -04:00
Jasper St. Pierre
d233238c64 window: Be better at filtering window grab mods
It turns out that Clutter doesn't actually filter NumLock / ScrollLock /
CapsLock from button events due to its terrible event translation code.

Check only the grab mods to check if it's unmodified.
2014-08-15 16:06:54 -04:00
Jasper St. Pierre
71a4fe746e pointer: Update an old function reference
We renamed this and I forgot to rename it here.
2014-08-15 13:49:40 -04:00
Jasper St. Pierre
f28c7835a1 workspace: Fix build
Forgot to squash, sigh.
2014-08-15 13:48:25 -04:00
Jasper St. Pierre
cecf7f4bf0 events: Revert a local change I accidentally made 2014-08-15 13:47:57 -04:00
Jasper St. Pierre
c687cf9db6 display: Simplify yet even more grab op code 2014-08-15 13:46:54 -04:00
Jasper St. Pierre
54d2218ac2 workspace: Simplify some more grab op code 2014-08-15 13:46:54 -04:00
Jasper St. Pierre
471e6b9e13 cursor-renderer: Popups need to set cursors, too
Popups could not set the cursor image, because the cursor tracker would
ignore window cursors if we had a popup active. The correct condition to
check for is already in should_block_wayland. Rename this to the more
sensible name windows_are_interactable, and use it in the cursor tracker.
2014-08-15 13:46:54 -04:00
Jasper St. Pierre
f8dcea3975 window-x11: Simplify some grab op code 2014-08-15 13:46:54 -04:00
Jasper St. Pierre
d931af33c4 display: Init X11 events separately 2014-08-15 13:46:53 -04:00
Jasper St. Pierre
a0e3c05428 display: Don't bother recording the grab timestamp
It's not used anywhere.
2014-08-15 13:09:18 -04:00
Jasper St. Pierre
b8c13cc426 window-x11: Fix stage window check when running under non-X11 backends
This code also runs when under the native backend for XWayland, so we
can't crash on an invalid cast there.
2014-08-15 12:38:15 -04:00
Adel Gadllah
38253a9f73 window-x11: The x11 backend window is our window as well
Since commit 467465c99c we use meta_stage even on x11 which sets
clutter_stage_set_user_resizable to FALSE.

This messes things up because we ought to ignore the properties on the window
but we apperently didn't.

There is no reason why we'd want to manage the stage window.

https://bugzilla.gnome.org/show_bug.cgi?id=734852
2014-08-15 17:53:27 +02:00
Jasper St. Pierre
cbc92b847f meta-stage: Remove an unused variable 2014-08-15 10:00:53 -04:00
Jasper St. Pierre
a5f993f269 window: Filter out buttons when checking if the event is unmodified 2014-08-15 08:41:10 -04:00
Jasper St. Pierre
31361e464a events: Make the ungrabbed button press handling more bullet proof
Instead of returning a value based on whether or not we handled it, we
have this logic: either we have taken a grab on the window, in which
case we have a grab op and have handled it ourselves, or we did not take
a grab and *need* to replay the event to the window.

Handle this in events.c by checking the grab operation in the same way
that we check the other grab ops.
2014-08-15 08:41:10 -04:00
Jasper St. Pierre
bb977c00ca window: Don't mark the event as handled for odd event combinations
This is an accidental regression from 7a109a1. If we mark the event as
handled, then we *need* to set grab_op, or do some other sort of
behavior, since we have a grab.
2014-08-15 08:41:09 -04:00
Jasper St. Pierre
39f65f9f86 backend: Add a keymap-changed signal 2014-08-14 17:36:29 -04:00
Jasper St. Pierre
bda2d6d1ac backend-x11: Don't leak the keymap
meta_backend_get_keymap is supposed to return a static keymap, not a new
one every time. Cache it internally. We don't update it when the keymap
changes on the server, but we'll do this soon.
2014-08-14 17:35:49 -04:00
Jasper St. Pierre
1e225ecdaf keybindings: Add a helper for taking the standard three-button grab 2014-08-14 17:35:49 -04:00
Jasper St. Pierre
cfb85d9a9a keybindings: Seal off the keybindings manager into its own structure
This helps clean up MetaDisplay, and also helps us move it into a
backend-specific thing in the future.
2014-08-14 17:35:48 -04:00
Jasper St. Pierre
f88c20f335 keybindings: Add an accessor for window grab modifiers
Since we're going to seal it away in the future.
2014-08-14 17:35:24 -04:00
Jasper St. Pierre
c98824bc9e window: Centralize the checks for the window grab modifiers
The code in the grab code was only checking for one of the modifiers to
be down, instead of all of them.
2014-08-14 17:35:24 -04:00
Jasper St. Pierre
69a35bb85f Remove support for the debugging window grabs feature
mutter doesn't really run nested in a useful way anymore.
2014-08-14 17:35:23 -04:00
Jasper St. Pierre
a3bb6c12e5 keybindings: Make devirtualize_modifiers a private function
This is now only used internally in keybindings.c
2014-08-14 17:35:23 -04:00
Jasper St. Pierre
586f118279 keybindings: Move the button grabs to here as well 2014-08-14 17:35:23 -04:00
Jasper St. Pierre
31081e5dac keybindings: Simplify a bit more code 2014-08-14 17:35:23 -04:00
Jasper St. Pierre
ef363e9d2e display: Simplify the regrab on focus mode 2014-08-14 17:35:23 -04:00
Jasper St. Pierre
9fa77acb8c display: Move devirtualize_modifiers into keybindings
It's mostly only used here.
2014-08-14 17:35:23 -04:00
Jasper St. Pierre
1e30db64d1 keybindings: Don't bother not reloading keymaps for MappingModifier
Now that we always use XKB, it's very unlikely that we'll get a
MappingNotifier without a subsequence XkbKeymapNotify event. Just
do all the work always.

This will also help us considerably for the future when we'll be
putting the keymap event in the backend.
2014-08-14 17:35:08 -04:00
Jasper St. Pierre
e830b66604 Remove a few extra HAVE_XKBs 2014-08-14 14:19:31 -04:00
Jasper St. Pierre
5f0fab2156 Conditionalize Wayland support again 2014-08-13 20:28:22 -04:00
Jasper St. Pierre
467465c99c backend: Create the stage in the backend, rather than the compositor
This allows creating the stage much earlier than it otherwise would have
been. Our initialization sequence has always been a bit haphazard, with
first the MetaBackend created, then the MetaDisplay, and inside of that,
the MetaScreen and MetaCompositor.

Refactor this out so that the MetaBackend creates the Clutter
stage. Besides the clarity of early initialization, we now have much
easier access to the stage, allowing us to use it for things such as
key focus and beyond.
2014-08-13 20:08:46 -04:00
Jasper St. Pierre
e935b52e51 display: Move composite version checks here 2014-08-13 19:32:39 -04:00
Jasper St. Pierre
879407c10c window: Kill off a now-unnecessary state variable 2014-08-13 18:25:46 -04:00
Jasper St. Pierre
e76be14dbb stack: Rewrite to not be based on X11 xtransient_for properties
This fixes some stacking issues with Wayland windows.
2014-08-13 18:25:34 -04:00
Jasper St. Pierre
7fa15c74b4 window: Fix some minor constant type issues 2014-08-13 18:14:15 -04:00
Jasper St. Pierre
c3950699bf wayland: Don't assert fail when dealing with popup windows 2014-08-13 18:09:55 -04:00
Jasper St. Pierre
e6b950e31b wayland: Fix minor style issue 2014-08-13 17:49:53 -04:00
Emmanuele Bassi
9440bdb1aa core: Select the X11 backend of Clutter
Mutter depends on the X11 windowing backend of Clutter, unless it's used
as a Wayland display server.

This allows Mutter to run without breaking in case Clutter changes the
order with which windowing backends are selected, like it was the case
for bug https://bugzilla.gnome.org/show_bug.cgi?id=734587

The order of selection of the Clutter backends has not been made public,
so it cannot be relied upon since the introduction of the multiple
backends support; since Mutter requires the X11 backend functionality,
it should select the X11 windowing system, in the same way it selects
the EGL backend when compiled and run as a Wayland display server.
2014-08-13 14:27:20 +01:00
Jasper St. Pierre
e320b06aaa texture-tower: Fix error case in meta-texture-tower
If we for some reason have an error trying to allocate the framebuffer,
we'll still mark the tower as revalidated. Move the validation to the
end of the actual revalidation code to solve this.
2014-08-08 17:29:26 -04:00
Jasper St. Pierre
b284126d3b background: Don't bother attaching a paint node if the region is empty 2014-08-07 14:59:59 -04:00
Jasper St. Pierre
6858cb261f background-actor: Don't bother clipping to the content box
We already clip to the content box when we go to paint the content.
2014-08-07 14:58:18 -04:00
Jasper St. Pierre
2d6954186e background: Don't render with blending when we don't need to
If we have an opaque background image, then we shouldn't need to blend
against anything for it to work. Turn off blending in this case.
2014-08-07 14:01:14 -04:00
Jasper St. Pierre
d72bf0cd5d compositor: Don't use cogl_texture_new_with_data in the obvious cases
It's a deprecated API that can surprise us. Namely, when the internal
format passed is COGL_PIXEL_FORMAT_ANY, it will *always* allocate an
RGBA8888 pixel format texture, even if we only passed it a RGB format
or even an A8 format.

cogl_texture_2d_new_with_data is the newer, better API and doesn't have
these warts.
2014-08-07 14:01:14 -04:00
Jasper St. Pierre
584460deec background: Merge the code for creating the color texture into here
It's unused anywhere else.
2014-08-07 13:49:16 -04:00
Jasper St. Pierre
e3d5969282 background: Don't bother supporting alpha channels for gradients 2014-08-07 13:39:21 -04:00
Owen W. Taylor
249468bbea MetaTextureTower: actually mark revalidated levels as valid
We were never actually clearing the invalid area on the smaller levels
of the texture tower, so we recomputed those levels every time.

https://bugzilla.gnome.org/show_bug.cgi?id=734400
2014-08-07 15:56:28 +02:00
Inaki Larranaga Murgoitio
f0f4c31d96 Updated Basque language 2014-08-07 15:21:06 +02:00
Inaki Larranaga Murgoitio
27f012ffad Updated Basque language 2014-08-07 15:18:24 +02:00
Rui Matos
7d54631ebf backends: Make MetaBackend available to introspection
This moves meta-backend.h under meta/ and, for now, just exposes to
introspection the methods that we actually need in gnome-shell.

https://bugzilla.gnome.org/show_bug.cgi?id=734301
2014-08-07 11:31:59 +02:00
Rui Matos
513628e4ad wayland-keyboard: Use the backend's keymap
Instead of getting it from xwayland, let's just keep a reference to
the backend's keymap.

https://bugzilla.gnome.org/show_bug.cgi?id=734301
2014-08-07 11:24:24 +02:00
Rui Matos
101b215d6b backends: Add methods to handle keymaps
These methods allow us to set and get xkbcommon keymaps as well as
locking a specific layout in a layout group.

With this, we introduce dependencies on xkeyboard-config, xkbfile,
xkbcommon-x11 and a libX11 new enough to have xcb support.

https://bugzilla.gnome.org/show_bug.cgi?id=734301
2014-08-07 11:24:24 +02:00
Rui Matos
6af48de0b8 Use libX11's Xkb* API unconditionally
At this point there shouldn't be any system capable of running mutter
that doesn't have it and we're introducing functionality like setting
the keymap that has an hard requirement on it.

https://bugzilla.gnome.org/show_bug.cgi?id=734301
2014-08-06 14:53:10 +02:00
Jasper St. Pierre
e5c4fedd55 wayland: Use the send event wrappers
Rather than raw post_event.
2014-08-05 16:12:29 -04:00
Jasper St. Pierre
2ce23072d3 wayland: Use wl_display_add_socket_auto 2014-08-05 16:12:29 -04:00
Rui Matos
97f4eb6b75 wayland-keyboard: Send modifiers after the keymap
Clients have to re-create their modifier state when getting a new
keymap so modifiers have to be sent after the keymap, not before.
2014-08-05 18:11:53 +02:00
Rui Matos
75cbf3d730 wayland-keyboard: Send keymap events also to focused resources
We move focused resources out of the global list when we focus a
client's surface so we need to send events for those separately.
2014-08-05 18:11:53 +02:00
Rui Matos
bf9fdf448d wayland-keyboard: Make update_pressed_keys() more generic
It will allow us to re-use this function next. Also rename the keys
array to pressed_keys since we'll need to add a different one.

https://bugzilla.gnome.org/show_bug.cgi?id=727178
2014-08-05 18:11:53 +02:00
Jasper St. Pierre
63c627ec18 wayland: Add a few statics we forgot before 2014-08-04 10:28:44 -04:00
Jasper St. Pierre
dadbd793be wayland: Fix naming scheme for request handlers
Our implementations should take the name of the request.
2014-08-04 10:27:26 -04:00
Jasper St. Pierre
75b6e917ad wayland: Simplify global version management
libwayland-server already checks the bounds of the bind for versioning,
meaning that the value that we pass to wl_global_create is all we need.
2014-08-04 10:25:23 -04:00
Jasper St. Pierre
ab53c0e943 wayland: Simplify slave version management
Slave objects should always be the same version as their parent
constructor, except for the generic wl_registry.bind.
2014-08-04 10:25:20 -04:00
Jasper St. Pierre
c2fe6a18ad shadow-factory: Comment fixes 2014-08-02 18:55:44 -04:00
Florian Müllner
b7119c55a6 window-props: Add FORCE_INIT flag to force hooks for unset properties
Since commit a7b7213017, we rely on the standard property
system to initialize the window type (and likewise for the window
role since commit 031154a400). However as property hooks are
never run for properties that are not set, we end up not initializing
the window type correctly for windows with no _NET_WM_WINDOW_TYPE
property (which includes virtually all OR windows, causing them to
show up in pagers and the Shell overview and resulting in frequent
crashes due to breaking reasonable assumptions all over the place).

Introduce a new FORCE_INIT flag to allow forcing hooks to run
even when the corresponding property is unset, and use it for
both _NET_WM_WINDOW_TYPE and _NET_WM_WINDOW_ROLE.
2014-08-02 20:26:00 +02:00
Giovanni Campagna
d0f2c6be6d ui: always set the frame background to None
This way the xserver never paints the frame background, even if
the client window is destroyed. This allows us to have clean
destroy window animation.

There is no problem with interactive resizing because applications
are using the XSync protocol, so we're not painting unless the
client has redrawn.

https://bugzilla.gnome.org/show_bug.cgi?id=734054
2014-07-31 17:54:38 +02:00
Piotr Drąg
3a535b6722 doap: add <programming-language> 2014-07-31 17:50:28 +02:00
Jasper St. Pierre
f9a77aec3f shadow-factory: Fix style 2014-07-31 17:49:13 +02:00
Jasper St. Pierre
bee6d2b240 shadow-factory: Untabify 2014-07-31 17:49:13 +02:00
Jasper St. Pierre
9a6a189e36 window-actor: Rebuild the shape and mask when the surface updates
Connecting to size-changed is wrong -- size-changed tells us when
we *told* the X server or resize the window. For X11, we're sort of
guaranteed that the surface will be updated at some point before the
next frame, but for Xwayland, we can't be sure that the new surface is
attached at this point.

This fixes weird artifacts when resizing apps like xclock.
2014-07-31 17:49:13 +02:00
Jasper St. Pierre
505eabb78c surface-actor: Remove unused APIs 2014-07-31 17:49:13 +02:00
Giovanni Campagna
b0ba325f0e MetaShapedTexture: fix critical warnings with fully obscured windows
If a window is fully obscured, it could have a negative paint volume
width/height. Normalize that to 0x0.
2014-07-31 16:21:32 +02:00
Jasper St. Pierre
6fbd21001b window-actor: Base the paint volume on our children, not our shape
This was wrong for subsurfaces that extend beyond the parent's shape,
since the paint volume would be wrong in this case. Instead of using the
shape region which can be out of date and wrong, just use the union of
our children's volumes, which is a lot easier to manage.
2014-07-30 17:15:00 +02:00
Jasper St. Pierre
626e4965b1 shaped-texture: Remove silly ClutterPaintVolume code with slightly less silly ClutterActorBox code 2014-07-30 17:09:23 +02:00
Olav Vitters
a15042b7e5 doap category core 2014-07-30 16:34:23 +02:00
Giovanni Campagna
e56f963574 MetaWaylandTouch: fix running without touch hardware
Refuse to create a touch resource if we don't have the capability
(for misbehaving clients), and don't attempt to use touch data
structures that are not initialized.
2014-07-30 15:46:19 +02:00
Jasper St. Pierre
65a8f9100c window-wayland: Only fizzle out configures when we do pending moves
This is a terrible hack. We need to figure out a better way to do
interactive resizes.

This fixes weird resizing from the left bugs when using GTK+, which is
really slow at acking configures.
2014-07-28 12:04:23 +02:00
Jasper St. Pierre
6954d23444 window-actor: Don't connect to allocation-changed
This can cause allocation loops. Connect to size-changed to update the
shape instead.
2014-07-28 11:32:52 +02:00
Jasper St. Pierre
6c624e1c26 window-wayland: Update the buffer rect size immediately 2014-07-28 11:30:15 +02:00
Jasper St. Pierre
cc839029b9 window: Don't leak the input region 2014-07-28 11:23:38 +02:00
Jasper St. Pierre
25f8eaf1ac shaped-texture: Clean up slightly 2014-07-28 11:23:36 +02:00
Jasper St. Pierre
8fdd226b8b wayland-surface: Fix coordinates for xdg_surface.show_window_menu 2014-07-28 10:22:50 +02:00
Jasper St. Pierre
6c5595fa9c window-wayland: Don't insist if the window gives us a bad buffer
This is an easy way to get into an infinite loop where we're constantly
re-sending stuff to the window. If it worked once, it probably won't
work again.
2014-07-27 18:38:56 +02:00
Jasper St. Pierre
e6558f838e window-wayland: Clean up code that pends moves 2014-07-27 18:09:12 +02:00
Jasper St. Pierre
57037a45b8 wayland-surface: Don't do pending move/resizes on all commits
We assume in meta_window_wayland_move_resize that the next commit that
changes the geometry will always be for our next pending operation, so
if we have a move pending on a resize, the next commit will trigger the
move. This is, of course, fundamentally wrong.

We broke this assumption even more now that we don't fizzle out calls to
meta_window_move_resize_internal and now call it on every commit, which
means that a simple damage and then commit would complete a pending
move.

This was even broken by apps like weston-terminal, which, when clicking
on the maximize button, first redraws the terminal with the maximize
button state back on hover on press, and would only redraw when it got
the configure event with the coordinates.

To track the correct commit to apply the move for, we implement the
ack_configure request and ignore all move/resizes that happen before
that.

Right now, we actually fizzle out the entire move/resize if there's a
future pending configure we're waiting on.
2014-07-27 18:09:12 +02:00
Jasper St. Pierre
c844611052 window-wayland: Rename saved_pos to pending_move
This is really what it is -- if we make the move/resize at the same time
as a move, we need to pend the move until the client submits the resize.
2014-07-27 18:09:12 +02:00
Jasper St. Pierre
b60e02956d wayland-surface: Add some extra protection
Make sure we're not configuring some sort of weird surface.
2014-07-27 18:09:12 +02:00
Jasper St. Pierre
4fe66ce0a9 prefs: Scale the root window cursor by the scale factor
This fixes small cursors on HiDPI displays.
2014-07-27 18:09:12 +02:00
Jasper St. Pierre
4b5a503cee backend-x11: Make sure to not crash during initialization
Sometimes we can get a host event without having the display up and
running yet. Just don't pass it to the compositor in that case, since it
won't be possible for it to have any event that matters.
2014-07-27 16:14:46 +02:00
Jasper St. Pierre
817995d97f wayland-surface: Make sure to zero out the geometry
Otherwise our implicit surface geometry calculation will be junk.
2014-07-27 15:23:00 +02:00
Jasper St. Pierre
0e7221c361 window: Clean up keyboard-resizing code path 2014-07-27 15:03:38 +02:00
Jasper St. Pierre
938fb8e6c8 cursor-tracker: Reindent 2014-07-27 07:54:06 -04:00
Rico Tzschichholz
fd8c49ff0a configure: Require wayland-server >= 1.5.90
Needed for wl_keyboard_send_repeat_info, introduced with
4f55e16fe9
2014-07-27 09:56:47 +02:00
Cosimo Cecchi
cd84317346 compositor: add support for unminimize compositor effects
https://bugzilla.gnome.org/show_bug.cgi?id=733789
2014-07-26 17:26:40 +02:00
Jasper St. Pierre
4f55e16fe9 wayland-keyboard: Add support for the repeat_info event in Wayland v4 2014-07-25 09:25:01 -04:00
Jasper St. Pierre
c30ef668de events: Fix compilation when disabling the native backend 2014-07-24 14:54:38 -04:00
Carlos Garnacho
62e0c42803 events: Do not swallow touch events on windows
Those might eventually trigger a gesture into recognition.

https://bugzilla.gnome.org/show_bug.cgi?id=733631
2014-07-24 18:07:31 +02:00
Carlos Garnacho
70aee2d95e display: cancel wayland client touches when the compositor is grabbed
When a compositor grab begins, clients will stop receiving events, so any
ongoing sequence at that time must be cancelled.

https://bugzilla.gnome.org/show_bug.cgi?id=733631
2014-07-24 18:07:30 +02:00
Carlos Garnacho
63c7591698 events: Simplify gesture event management
MetaGestureTracker has been separating the "did I handle an event?" and the
"should the event be filtered out?" questions, merge this and make
handle_event() reply to "should the event be only handled by me?".

If a sequence wasn't accepted yet by the gesture tracker, the event will
go through (eg. not handled exclusively by the gesture tracker) and it'll
still be processed by Clutter, triggering gesture actions, and maybe
changing the sequence into other state.

https://bugzilla.gnome.org/show_bug.cgi?id=733631
2014-07-24 18:05:56 +02:00
Carlos Garnacho
930361b988 wayland: Handle window drags for touch events
The grabbing state is now checked for both pointer/touch devices
within the seat, and the grab start coordinates returned by
meta_wayland_seat_get_grab_info().

https://bugzilla.gnome.org/show_bug.cgi?id=733631
2014-07-24 18:05:56 +02:00
Carlos Garnacho
baadb75a5e wayland: Clear hashtable pointers on meta_wayland_touch_release()
Just in case they are poked while no touch interface is available;

https://bugzilla.gnome.org/show_bug.cgi?id=733631
2014-07-24 18:05:56 +02:00
Carlos Garnacho
f28f5dc0b6 window: Implement single-touch window dragging
On X11 this works because only emulated pointer events are listened for. On
wayland, the single touch behavior must be enforced in touch events, ignoring
every other sequence.

https://bugzilla.gnome.org/show_bug.cgi?id=733631
2014-07-24 18:05:56 +02:00
Carlos Garnacho
41fdc4ac2e display: Add meta_display_is_pointer_emulating_sequence()
This function tells the obvious on X11, and implements a similar mechanism
on wayland to determine the "pointer emulating" sequence, or one to stick
with when implementing single-touch behavior.

https://bugzilla.gnome.org/show_bug.cgi?id=733631
2014-07-24 18:05:56 +02:00
Carlos Garnacho
177ec27cca gesture-tracker: Add meta_gesture_tracker_get_n_current_touches()
Due to the way the MetaGestureTracker processes every touch event, this
will tell as closely to Clutter as possible the current number of touches
happening on the stage.

Even though, this is subject to windowing behavior, on X11, rejected touches
will be soon followed by a XI_TouchEnd event, so the compositor will stop
seeing touch sequences that are still operating on clients. On wayland, touch
sequences are processed by the compositor during all their lifetime, so these
will stay on the MetaGestureTracker with META_SEQUENCE_PENDING_END state, yet
still tracked.

https://bugzilla.gnome.org/show_bug.cgi?id=733631
2014-07-24 18:05:56 +02:00
Adel Gadllah
37652ca2cf background: Do not assume GLSL is available
Some hardware does not support it causing crashes in cogl during paint.

https://bugzilla.gnome.org/show_bug.cgi?id=733623
2014-07-24 16:51:53 +02:00
Carlos Garnacho
6c22759d29 display: Add forgotten meta_display_cancel_touch 2014-07-23 18:37:51 -04:00
Carlos Garnacho
25b6a40ad4 display: Implement gesture-induced touch cancellation for wayland
On wayland, touches are initially both handled by the compositor and sent
to clients, proceeding to cancellation on clients only after the compositor
claims the sequence for itself. Implement the cancellation detail through
MetaGestureTracker::state-changed.

https://bugzilla.gnome.org/show_bug.cgi?id=733631
2014-07-24 00:17:04 +02:00
Carlos Garnacho
fbea59b326 wayland: set the current serial on touch down/up notifications
Do just like pointer button events, and do not bump the serial, so serials
match on window drag/move requests triggered from touch events.

https://bugzilla.gnome.org/show_bug.cgi?id=733631
2014-07-24 00:16:23 +02:00
Carlos Garnacho
38e4906f72 window: Use event data getters in event handling code
This makes these functions more independent wrt touch vs pointer events

https://bugzilla.gnome.org/show_bug.cgi?id=733631
2014-07-24 00:15:51 +02:00
Carlos Garnacho
029d69919b wayland: Rename touch_handle_cancel_event() to meta_wayland_touch_cancel()
This will serve as a generic call to issue touch cancellation on clients,
useful for the gesture tracker support.

https://bugzilla.gnome.org/show_bug.cgi?id=733631
2014-07-24 00:14:03 +02:00
Carlos Garnacho
5e395fb676 wayland: Fix infinite loop in touch_handle_cancel_event()
https://bugzilla.gnome.org/show_bug.cgi?id=733631
2014-07-24 00:13:26 +02:00
Carlos Garnacho
ac448bd42b seat: Listen for ClutterDeviceManager signals in order to update capabilities
The capability flags are determined from the device types of the slave devices
that are currently attached. This also happens whenever a device is added or
removed, so the capabilities are kept up to date, and clients know about these.

On VT switch, all slave devices are temporarily removed, so the cascade of
signals will make the seat end up with capabililities=0 while input is suspended.

https://bugzilla.gnome.org/show_bug.cgi?id=733563
2014-07-23 22:07:16 +02:00
Rui Matos
f55737ec06 compositor: Sync X drawing only once per frame
We only need to call XSync() once per frame to synchronize X with GL
drawing.

https://bugzilla.gnome.org/show_bug.cgi?id=728464
2014-07-23 13:59:18 -04:00
Kjartan Maraas
80de15face Updated Norwegian bokmål translation. 2014-07-23 15:02:43 +02:00
Carlos Garnacho
32565e096d wayland: Notify modifiers after keymap changes
Anytime the keymap is changed, either directly, or indirectly through the
keyboard capability being released/initialized, there should be a
notification of the modifiers being changed too.

https://bugzilla.gnome.org/show_bug.cgi?id=733563
2014-07-23 14:53:46 +02:00
Florian Müllner
1d8e4bdd6d Bump version to 3.13.4
Update NEWS.
2014-07-23 11:45:52 +02:00
Carlos Garnacho
1677a068ce wayland: Unset keyboard/pointer focus when releasing the data for these devices
Otherwise the focus_surface_listener list element becomes stale, and then
mangled if the devices' data is initialized again, and the memory memset().

https://bugzilla.gnome.org/show_bug.cgi?id=733563
2014-07-22 18:01:29 +02:00
Carlos Garnacho
a02b8441b1 wayland: set the interface vfuncs when declaring the touch interface
Otherwise the NULL vtable would be accessed when trying to release the touch
device.

https://bugzilla.gnome.org/show_bug.cgi?id=733563
2014-07-22 18:01:29 +02:00
Carlos Garnacho
dfe1c106f2 wayland: set the interface vfuncs when declaring the keyboard interface
Otherwise the NULL vtable would be accessed when trying to release the keyboard.

https://bugzilla.gnome.org/show_bug.cgi?id=733563
2014-07-22 18:01:29 +02:00
Jasper St. Pierre
e49bbe2ed8 cursor-tracker: Don't require a screen
This allows us to do initialization earlier and not have to poke into
Wayland internals from the cursor tracker.
2014-07-22 11:10:14 -04:00
Adel Gadllah
6ee5a1437c x11: Move event filter to backend connection 2014-07-19 18:51:26 +02:00
Enrico Nicoletto
93a3383e60 Updated Brazilian Portuguese translation 2014-07-18 17:55:31 +00:00
Jasper St. Pierre
c9a2a561f8 wayland: Use a named #define for the xdg-shell version 2014-07-17 17:48:30 -04:00
Jasper St. Pierre
ac0b2fdc6f wayland: Use our named #define for the wl_shell version 2014-07-17 17:47:14 -04:00
Jasper St. Pierre
46b9984414 wayland: Don't leak an extra xdg_shell resource
No idea how this happened...
2014-07-17 17:47:10 -04:00
Jasper St. Pierre
f9743e2174 wayland: Fix indentation 2014-07-17 17:39:43 -04:00
Jasper St. Pierre
a3c55c2692 wayland: Don't emit SIZE_CHANGED on every commit
Save a little bit of effort here.
2014-07-17 17:27:52 -04:00
Jasper St. Pierre
692eb4d957 wayland: Replace set_margin with set_window_geometry 2014-07-17 16:45:37 -04:00
Jasper St. Pierre
826751429b wayland: Treat the size in the configure event as frame rect coordinates 2014-07-17 16:45:37 -04:00
Jasper St. Pierre
5621d3c0c7 wayland: Fix the sign for the geometry coordinates
I got the spaces for window geometry coordinates vs. surface coordinates
mixed up.
2014-07-17 16:42:41 -04:00
Jasper St. Pierre
b5f46c9171 wayland: Calculate the window geometry based on all subsurfaces
Not just the main surface.
2014-07-17 16:20:19 -04:00
Jasper St. Pierre
166b8c042c wayland: Don't fizzle out attaches 2014-07-17 16:18:01 -04:00
Jasper St. Pierre
d34ece6f1a wayland: Don't send superfluous configures for uninteresting grab ops 2014-07-17 16:03:03 -04:00
Jasper St. Pierre
679844f791 display: Call meta_window_grab_op_ended after everything else is reset
This properly sends the resizing state to the correct Wayland surface.
2014-07-17 16:03:01 -04:00
Jasper St. Pierre
9316256e10 wayland: Use the variables we already have 2014-07-17 15:27:47 -04:00
Jasper St. Pierre
90d7737fc1 wayland: Don't require a new buffer to move windows with dx/dy
This doesn't match what Weston does. I don't know of any apps that this
fixes (we don't have any apps that even use non-zero dx/dy, I don't
think), but this is part of a cleanup for window geometry.
2014-07-17 14:51:23 -04:00
Jasper St. Pierre
567ca15610 xdg-shell: Update to latest 2014-07-17 14:51:12 -04:00
Jasper St. Pierre
558b323485 xdg-shell: Fix typo 2014-07-17 14:50:40 -04:00
Jasper St. Pierre
1a05da8296 Update .gitignore 2014-07-17 14:49:47 -04:00
Jasper St. Pierre
5df59f75cd restart: Fix pointer/XID confusion
This causes an error in recent gcc.
2014-07-17 11:50:58 -04:00
Adel Gadllah
029673d0ee Revert "backend-x11: Take the touch grab on the stage window"
This reverts commit 3b85e4b2b9.

This breaks touch support; reverting would break wayland
(is what this patch tried to fix; we should find a better solution
that works on both).
2014-07-17 17:18:08 +02:00
Owen W. Taylor
3a57f843d5 Add a framework for restarting the compositor with nice visuals
The current GNOME Shell Alt-F2 restart looks very messy and also
provides no indication to the user what is going on. We need to
restart the compositor to switch in and out of stereo mode, so
add a framework for doing this more cleanly:

Additions:

 meta_restart(): restarts the compositor with a message
 MetaDisplay::show-restart-message: signal the embedding
    shell to show a message
 MetaDisplay::restart: signal the embedding shell to restart
    itself.
 meta_is_restart(): indicates whether the current instance is a
                    restart so we can suppress login animations.

A helper program meta-restart-helper holds the composite overlay
window up during the restart to avoid visual artifacts.

https://bugzilla.gnome.org/show_bug.cgi?id=733026
2014-07-16 18:09:25 -04:00
Owen W. Taylor
182a267f69 Connect to ClutterStage::after-paint with connect_after()
Use connect_after() to accomodate code in GNOME Shell that,
when benchmarking drawing performance, connects to ::after-paint
and calls glFinish(). The timing information from that will be
more accurate if we hold off until that completes before we signal
apps to begin drawing the next frame. If there are no other
connections to ::after-paint, connect() vs. connect_after() doesn't
matter.

https://bugzilla.gnome.org/show_bug.cgi?id=732350
2014-07-16 13:38:15 -04:00
MarMav
3de40434fa Updated Greek translation 2014-07-16 10:55:38 +00:00
Jasper St. Pierre
bc8328d7c2 screen: Select for events on the guard window on the backend connection
Otherwise, we'll never see them. This fixes the background menu not
working in gnome-shell.
2014-07-15 17:18:37 -04:00
Jasper St. Pierre
12c1a06e60 screen: Don't select for key and motion events on the root window
These aren't necessary, and we'll never see these events anyway, since
we don't process input events on the frontend connection.
2014-07-15 17:18:37 -04:00
Jasper St. Pierre
b11405570a compositor: Don't bother selecting for events on the COW
We already select all the events we need on the stage window instead.
2014-07-15 17:18:37 -04:00
Jasper St. Pierre
3b85e4b2b9 backend-x11: Take the touch grab on the stage window
So we don't get assert fails when touching the screen on mutter nested.
2014-07-14 17:24:31 -04:00
Jasper St. Pierre
c5abf5ddbb window: Fix meta_window_move_resize_internal for the case of a sole ack
When a Wayland window acks our arrangement and we don't really have
anything to modify, we'll pass a sole flag of META_IS_WAYLAND_RESIZE
to meta_window_move_resize_internal using a garbage rect. The existing
code to calculate the new rectangle couldn't really handle this case,
and so the garbage rectangle accidentally got stored. Revamp the flag
checks to be more clear about it.

This fixes the weird positioning issues that sometimes appear when
resizing weston-terminal among others.
2014-07-14 17:07:31 -04:00
Jasper St. Pierre
2a3d4b62a7 keybindings: Fix backend check in change_keygrabs
We really can't do this unless the backend X server is the same as the
frontend X server, as we pass a frontend XID to the backend, which is
only the case when we're not a Wayland compositor.
2014-07-14 15:31:19 -04:00
Jasper St. Pierre
8ff81bcc37 window: Force updating icons when initially loading them
Otherwise, Wayland windows will never get an icon.
2014-07-14 15:28:37 -04:00
Jasper St. Pierre
7159d3bc35 window: Remove the concept of surface_mapped
The implementation was just wrong. We now consider it an error to attach
a NULL buffer to an xdg_surface. Users should destroy the surface properly.
2014-07-14 14:49:58 -04:00
Jasper St. Pierre
941d202938 window: Move X11-specific icon code to MetaWindowX11 2014-07-14 12:15:23 -04:00
Jasper St. Pierre
5ea0cf8bab iconcache: Remove a useless icon_cache_free
All it does is poke a few fields. There is no point to it.
2014-07-14 12:02:58 -04:00
Jasper St. Pierre
df9a5f867f core: Remove useless meta_invalidate_default_icons implementation
This code was supposed to refresh our default icons when the theme
changed, but it actually was a no-op, since the default icons are cached
in a static variable in MetaUI.

I'm not sure the fact that the fallback icons don't update when the
theme changes is an important enough use case to keep working, but I'm
keeping the skeleton function there in case somebody wants to actually
fix it properly.
2014-07-14 12:00:34 -04:00
Jasper St. Pierre
06e4778072 iconcache: Group declarations where they're used 2014-07-14 11:30:03 -04:00
Jasper St. Pierre
92388892b3 iconcache: Remove dead code 2014-07-14 11:27:51 -04:00
Jasper St. Pierre
5d124ac00a iconcache: Remove commented out code 2014-07-14 11:27:51 -04:00
Jasper St. Pierre
a57c3ae105 iconcache: Remove want_fallback hint
It's unused, and if it was ever set, it would cause an assert fail.
2014-07-14 11:27:50 -04:00
Jasper St. Pierre
55354f5c38 Take the touch grab in MetaBackendX11
This means that it won't trigger when we're running as a Wayland
compositor, which will cause a few warnings and possibly more
brokenness.
2014-07-14 09:41:10 -04:00
Jasper St. Pierre
379bb0a77d screen: Don't make a round-trip to fetch a value we know to be empty 2014-07-14 09:40:43 -04:00
Jasper St. Pierre
39357fc242 window-props: Don't make another round-trip to fetch the opaque region
We already have the property value from our property fetching.
2014-07-13 22:51:25 -04:00
Jasper St. Pierre
799de4f0f4 frames: Don't make a round trip to the X server for every MotionNotify
Instead, simply use the coordinates that were passed to us from the
MotionNotify event.
2014-07-13 17:34:08 -04:00
Jasper St. Pierre
c34b5c1cf0 Makefile: Disable Clutter / Cogl deprecation warnings
These just spam up our logs, and they aren't getting fixed any time
soon for a variety of reasons. Just disable them to ensure that really
important warnings get noticed and fixed.
2014-07-13 11:46:13 -04:00
Jasper St. Pierre
46361c3e28 events: Return early if we close the display
This is so we won't poke into the MetaDisplay, which is invalid memory,
and crash. This can sometimes work right now because GSlice might not
deallocate the object immediately, but it's still not a fun thing to do.
2014-07-13 11:43:28 -04:00
Jasper St. Pierre
f9d33b2efc display: Add an extra check inside meta_display_close
For clarity of what the expected input to this function is.
2014-07-13 11:37:31 -04:00
Jasper St. Pierre
2185904fcb display: Use a local here instead of the global the_display
This will make it easier to split some of this functionality out into
other subfunctions.
2014-07-13 11:35:38 -04:00
Jasper St. Pierre
eb952819c2 monitor: Don't use wl_output_transform in our APIs
Invent our own API so we can build without Wayland headers.
2014-07-13 11:35:01 -04:00
Jasper St. Pierre
d7d8c92a9a Remove unused Wayland includes 2014-07-13 11:35:01 -04:00
Owen W. Taylor
88a7790d44 MetaDisplay: remove meta_display_grab()/ungrab()
Now that we have two connections to the X server, the idea of a
ref-counted server grab that might be held across extended portions
of code is very dangerous since we might try to use the backend
connection while the frontend connection is grabbed.

Replace the only usage (which was local) with direct
XGrabServer/XUngrabServer usage and remove the meta_display_grab()
API.

https://bugzilla.gnome.org/show_bug.cgi?id=733068
2014-07-11 13:39:07 -04:00
Owen W. Taylor
806dabe2d7 Don't grab the server when unmanaging the screen
There's no obvious reason for grabbing the X server when unmanaging
a screen - the only race conditions a server grab solves are those
related to querying and then acting on the results of the query.

Our shutdown sequence is correctly ordered according to the ICCCM -
we first unselect on the root window, and then we destroy the
window owning WM_S<n> so removing the grab should not cause any
problems when we are being replaced with another window manager.

https://bugzilla.gnome.org/show_bug.cgi?id=733068
2014-07-11 13:39:07 -04:00
Jasper St. Pierre
740e7ddd69 window: Manage after setting the OR special case properties 2014-07-10 17:08:14 -04:00
Jasper St. Pierre
bee97ab6a7 window-props: Make sure that recalc_window_type is always called 2014-07-10 17:07:52 -04:00
Jasper St. Pierre
59fc17c355 util: Turn STACK debugging back off
Snuck in by accident.
2014-07-10 16:54:48 -04:00
Jasper St. Pierre
5f25ca0c3a stack-tracker: More small cleanups 2014-07-10 16:29:35 -04:00
Jasper St. Pierre
41b4a079c7 stack-tracker: Remove unused variable 2014-07-10 16:29:35 -04:00
Jasper St. Pierre
e4235376d8 stack-tracker: Add some more debug output 2014-07-10 16:29:34 -04:00
Jasper St. Pierre
043a201f90 stack-tracker: Clean up dumping 2014-07-10 16:29:18 -04:00
Jasper St. Pierre
d1a588a94f stack-tracker: Fix the case where the serial is too old
The code here before was just flat out wrong, and made us consistently
requery the server at startup.
2014-07-10 16:02:01 -04:00
Jasper St. Pierre
01b6d9bfe2 stack-tracker: Fix code style 2014-07-10 16:00:38 -04:00
Jasper St. Pierre
9711d95996 stack-tracker: Fix comments 2014-07-10 16:00:38 -04:00
Jasper St. Pierre
b87db00fdb window-props: Fizzle out PropertyNotifies that happen after initial map
Properties like _NET_WM_DESKTOP and _NET_WM_STATE are supposed to be
ignored after the initial map of the window, so ignore any
PropertyNotifies for these.
2014-07-10 15:05:42 -04:00
Jasper St. Pierre
6190b65056 window-props: Use a flags-based approach for our prop hooks
This allows us to extend the table better with newer flags.
2014-07-10 15:05:42 -04:00
Jasper St. Pierre
10fe91d704 window-props: Don't load WM_STATE
Since we don't do anything with it.
2014-07-10 15:05:42 -04:00
Jasper St. Pierre
36bb05b10e window-props: Fix assert testing
I have *no* idea how this even compiled in the first place. What the hell?
2014-07-10 15:05:42 -04:00
Jasper St. Pierre
a7b7213017 window-props: Use the standard property type system for _NET_WM_WINDOW_TYPE 2014-07-10 15:05:40 -04:00
Jasper St. Pierre
031154a400 window-props: Use the standard property type system for WM_WINDOW_ROLE
There seems to be no reason we can't just use this.
2014-07-10 14:56:23 -04:00
Jasper St. Pierre
463b50e746 screen: Fetch the COW window up-front
XGetCompositeOverlayWindow is a round trip to the X server. We shouldn't
be doing it on every MapWindow.
2014-07-10 14:18:02 -04:00
Jasper St. Pierre
1749a85e96 frame: Only XSync when we're on the X11 compositor backend
The only case we have is the case where the two X11 connections are the
same. When on Wayland, the XSync is costly and expensive, and we should
minimize it.
2014-07-10 13:31:26 -04:00
Jasper St. Pierre
1af9e92e91 Don't add in our old input event mask when we select input events
This causes a round-trip to the server, and just isn't necessary, since
we're always in charge of our event mask.
2014-07-10 13:30:05 -04:00
Jasper St. Pierre
12d0c98fb5 wayland: Remove an unused field from MetaWaylandFrameCallback 2014-07-10 13:30:05 -04:00
Jasper St. Pierre
817c6986a0 wayland: Remove a few unused fields from MetaWaylandCompositor 2014-07-10 13:30:05 -04:00
Jasper St. Pierre
7c68aaea4c data-device: Put the DataDevice implementation in its own struct 2014-07-10 13:30:05 -04:00
Jasper St. Pierre
6fea46e0cf data-device: Use a better variable name than "resource" 2014-07-10 13:30:05 -04:00
Jasper St. Pierre
59fa74fed1 data-device: Don't look up the same client twice in two different ways 2014-07-10 13:30:05 -04:00
Jasper St. Pierre
581335fbea data-device: Start a cleanup 2014-07-10 13:30:04 -04:00
Jasper St. Pierre
9b5d6cc008 wayland: Remove seat->display
It's unused.
2014-07-10 13:30:04 -04:00
Jasper St. Pierre
d0f98ec1ba wayland: Fix include ordering
This puts it in the same order as the types in the struct.
2014-07-10 13:30:04 -04:00
Jasper St. Pierre
a977fcf3d0 wayland: Add a wrapper for set_input_focus
So we're not poking into seat internals.
2014-07-10 13:30:04 -04:00
Jasper St. Pierre
664f6ef420 wayland: Move DataOffer / DataSource into data-device internals 2014-07-10 13:30:04 -04:00
Florian Müllner
06a31992e3 screen: Tweak workspace initialization (again)
Commit 8100cefd4c fixed a crash during workspace initialization by
tweaking the startup sequence; as a result, the plugin (like gnome-shell)
is now started before workspaces are fully initialized, which breaks
some reasonable assumptions (like always having an active workspace).
This is particularly problematic considering that the code making those
assumptions is not necessarily our own (extensions!), so return to
fully initialize workspaces before the compositor again.
At the same time, make sure to only call meta_workspace_activate()
once during initialization to avoid reintroducing the crash.

https://bugzilla.gnome.org/show_bug.cgi?id=732695
2014-07-10 17:50:59 +02:00
Jasper St. Pierre
4e2092d593 gesture-tracker: Rename files to include the meta- prefix 2014-07-08 13:30:26 -04:00
Jasper St. Pierre
9755f308e5 gesture-tracker: Update documentation format 2014-07-08 13:28:48 -04:00
Jasper St. Pierre
09610daea1 gesture-tracker: Don't pass an autodeny-timeout
Just use the default value of 250.
2014-07-08 13:27:38 -04:00
Jasper St. Pierre
13b7fa4eba ui: Bring back the is_input_event helper
This makes the logic clearer and easier to reason about.
2014-07-08 12:59:35 -04:00
Jasper St. Pierre
909a46087f ui: Fix the check for the XInput opcode
When converting is_input_event to be the opposite, I forgot to make this
change.
2014-07-08 12:58:43 -04:00
Jasper St. Pierre
c10c8649f5 window: Reformat a comment 2014-07-08 12:45:34 -04:00
Jasper St. Pierre
82dce6758a window: Remove pending pings in unmanage
This makes sure that we see them for Wayland clients as well, and don't
time out and crash when we're accessing an invalid window / surface.

Spotted-by: Rui Matos <tiagomatos@gmail.com>
2014-07-08 12:17:08 -04:00
Jasper St. Pierre
024652bfb4 window: Set the surface to NULL when unmanaging 2014-07-08 12:14:20 -04:00
Carlos Garnacho
789608b637 gesture-tracker: Implement threshold-based sequence rejection
If a sequence moves past a certain distance without being used by a
gesture, reject it so clients may see and react to it ASAP. This makes
gestures to be began by initially quasi-static touchpoints, in addition to
quasi-simultaneous.
2014-07-08 11:30:12 -04:00
Carlos Garnacho
d05b750b8d frames: Keep information about the ongoing grab operation, and retry if needed.
When a passive touch grab is rejected over the frame, management is punted to
the frame itself, and pointer events emulated, but the attempt to transfer the
grab from the GDK connection to the Clutter one fails with AlreadyGrabbed, and
will fail until the Clutter connection receives the XI_TouchEnd resulting from
XIRejectTouch, gotten after the XI_ButtonPress on the GDK connection.

In order to bypass this shortcoming, store the current grab operation on the
frame as long as the button is pressed, so it is retried once on the next
motion event happening during frame dragging, that will have a recent enough
timestamp to succeed. If no grabbing succeeded, the current grab operation
data will be reset on GDK_BUTTON_RELEASE.
2014-07-08 11:21:36 -04:00
Carlos Garnacho
704cae1de3 backend: Use the most recent event time on replayed touch events
When a touch sequence is passively grabbed and later rejected, events
will be replayed on the next client in propagation order, although those
events (either transformed to pointer events or not) will contain the
original timestamps, this will make grabs fail with InvalidTime if triggered
from the replayed ButtonPress/TouchBegin handler.

In order to work around this, store the most recent event time (presumably
gotten from the XI_TouchEnd caused by the passive grab being rejected), and
use that time on the events being replayed afterwards and grabs, so we don't
possibly fail with InvalidTime if those events result in a compositor grab.
2014-07-08 11:21:29 -04:00
Carlos Garnacho
23b074481a display: Set an X11 passive touch grab on the root window
Touch events will be caught first by the compositor this way,
whenever the MetaGestureTracker notifies of the accepted/rejected
state of a sequence, XIAllowTouchEvents() will be called on it
accordingly, so it is handled exclusively by the compositor or
punted to clients.
2014-07-08 11:21:29 -04:00
Carlos Garnacho
5dc8fa6690 events: Hook MetaGestureTracker to display event processing
Events aren't actually consumed by the MetaGestureTracker, but it
rather defines whether the event will reach clients, or the stage.
2014-07-08 11:21:29 -04:00
Carlos Garnacho
a9ba98686f display: Add a global MetaGestureTracker 2014-07-08 11:21:28 -04:00
Carlos Garnacho
59382bace2 core: Add MetaGestureTracker
This object tracks both touch sequences happening on the stage and
gestures attached to the stage actor. When a gesture emits
::gesture-begin, All triggering sequences and future ones will be
marked as "accepted" by the compositor, and events will be listened
for meanwhile there are active gestures.

If a sequence goes unclaimed for a short time, it will be
automatically "denied", and punted to the client or shell element
below.
2014-07-08 11:21:28 -04:00
Jasper St. Pierre
2edf822bc6 ui: Fill in more fields on our emulated motion / crossing events
This will be required by the gestures work.
2014-07-08 11:21:24 -04:00
Jasper St. Pierre
355621b0ab ui: Remove a superfluous set on emulated motion events
This is already set by the gdk_event_new above.
2014-07-08 11:20:35 -04:00
Jasper St. Pierre
a307e13a63 ui: Filter out touch events 2014-07-08 10:50:09 -04:00
Giovanni Campagna
f807207b65 window: expose meta_window_is_client_decorated() in the API 2014-07-08 12:10:54 +02:00
Jasper St. Pierre
30b54aae34 frame: Don't select for core events on the frame window
We override these with XI2 event types anyway. There's no point to
selecting to them.
2014-07-07 19:22:09 -04:00
Carlos Garnacho
79e682bcd0 compositor: emit grab-op-begin/end signals on plugin grabs
This makes it possible to track there grabs triggered this way, in
addition to the ones handled by mutter.
2014-07-07 19:18:21 -04:00
Carlos Garnacho
a05ae8654c events: Update current time on CLUTTER_TOUCH_BEGIN events
Just as with key/button press events, update the current interaction
time when a touch begins on a window.
2014-07-07 19:17:06 -04:00
Carlos Garnacho
0db172edbf ui: Remove XI_TouchBegin handling from window frame event handlers
This is now unnecessary as only pointer events are selected, so pointer
emulation will take care of sending only pointer events.
2014-07-07 19:17:06 -04:00
Carlos Garnacho
7b0930f798 frame: Only select for ButtonPress/Release/Motion/Crossing
Touch events are largely ignored on GdkEvent emulation, so only
make frames receive pointer events, only the pointer emulating
touch will be reported, and any other further touches will be
ignored, which is about the behavior we want. This makes window
dragging possible again on touch.
2014-07-07 19:17:06 -04:00
Carlos Garnacho
0919b37c34 ui: Remove unneeded code
There's no way now that GDK will hold a grab, so it is safe to remove
this now.
2014-07-07 19:17:05 -04:00
Carlos Garnacho
faf55c4627 backend-x11: Ensure touch event coordinates are translated to the stage's
Now that those events are going to be received, coordinates translation
should also happen on those.
2014-07-07 19:17:03 -04:00
Carlos Garnacho
f351c5d304 backend-x11: Remove pointless goto
The function is not as complex as needing that, plus it always jumped
anytime bypass_clutter is TRUE, so make all conditional code depend on
that.
2014-07-07 19:15:48 -04:00
Jasper St. Pierre
63bca17ab6 backend-x11: Only spoof the event when we're passing it to Clutter
There's no need to do so otherwise.
2014-07-07 19:13:31 -04:00
Jasper St. Pierre
c2abe43ee7 window: Only update the unconstrained rect when we actually moved/resized
Since Wayland configures are more of a hint to the client than anything,
we don't want to save the unconstrained rect when we're just hinting to
the client that it should resize, since it could ignore us. This would
get us stuck in a loop, since meta_window_move_resize_now would use the
unconstrained_rect to resize, and we don't remove the resize from the
queue if we have an outstanding request like that.

This fixes a bunch of traffic / CPU usage when trying to resize
weston-terminal.
2014-07-07 14:11:14 -04:00
Jasper St. Pierre
1de2fd7122 window-wayland: Check to update the buffer_rect separately
When frame extents change, we might not update the frame rect, but the
buffer rect still needs to be updated. Split out the check for this to
be independent of the check for the frame rect.

This fixes issues that could happen when the window was maximized while
it was in the top-left corner.
2014-07-07 13:07:37 -04:00
Jasper St. Pierre
e377e82cfd theme: Remove bogus comment
This isn't happening anytime soon.
2014-07-07 12:54:36 -04:00
Rico Tzschichholz
fa8174a200 gradient: Fix warning/typo
In addition to c068c2122d
2014-07-07 10:59:23 +02:00
Aurimas Černius
d22448731c Updated Lithuanian translation 2014-07-05 13:57:20 +03:00
Florian Müllner
ef95133b1c theme: Also support alpha values in blend/shade functions
This doesn't appear to be used currently, but fix it while at it ...
2014-07-03 20:09:49 +02:00
Florian Müllner
c068c2122d gradient: Support alpha values in colors
Designers got used to RGBA support in GTK+, so the colors we pick
up from there might well have an alpha channel; update our gradient
rendering to support this - eventually we should probably port that
code to cairo ...
2014-07-03 20:01:51 +02:00
Florian Müllner
d8c47b0abd gradient: Remove unused parameter 2014-07-03 20:01:51 +02:00
Jasper St. Pierre
66eb4bc34c wayland-surface: Make sure to apply the margin before moving the window 2014-07-03 10:31:26 -04:00
Fran Diéguez
bce812ecbc Updated Galician translations 2014-07-01 21:58:20 +02:00
Jasper St. Pierre
02220ed6c7 window: Don't eat events on O-R windows
For XWayland, we need to make sure to send out mouse events on O-R
windows, otherwise they won't get motion or button events.

The comment mentions being eaten for the compositor, but we already
bypass the compositor for all events that have a window. The return
value just controls whether we pass them to Wayland.
2014-07-01 14:41:38 -04:00
Giovanni Campagna
8d08851f28 compositor: show the stage after we set the size
So that it is actually respected
2014-07-01 20:28:00 +02:00
Jasper St. Pierre
af135c0b0b monitor-manager: Rename output_id to winsys_id
The output_id is more of an opaque identifier for the monitor, based on
its underlying ID from the windowing system. Since we also use the term
"output_id" for the output's index, rename our use of the opaque cookie
"output_id" to "winsys_id".
2014-07-01 13:24:34 -04:00
Jasper St. Pierre
42c972735e window: Don't treat an output_id of 0 as an invalid ID 2014-07-01 13:18:31 -04:00
Jasper St. Pierre
110c79d10e monitor-manager: Rename output_id to output_index
The term "output_id" is already used as an opaque ID.
2014-07-01 13:01:02 -04:00
Jasper St. Pierre
b9d867cb86 monitor-manager: Remove duplicate variable definition 2014-07-01 13:00:57 -04:00
Jasper St. Pierre
ea3b961e43 window-wayland: Make sure the size of the buffer rect is kept up to date
When we changed the setting of the buffer rect to be inside the moving
code to make sure it was updated in places we were moving directly
without any round-trip needed, I removed a code to set the buffer rect
without remembering that's where the size of it was updated.

Add back the code to update the buffer rect.

This fixes Wayland windows not appearing.
2014-07-01 11:27:26 -04:00
Owen W. Taylor
bc510378b3 Switch to using ClutterStage::after-paint
The experimental API clutter_stage_set_paint_callback() is replaced
with an ::after-paint signal as of Clutter 1.19.5.
2014-06-27 14:36:32 -04:00
Jasper St. Pierre
0a47d135ac screen: Fix up last commit
Forgot to squash after building.
2014-06-27 14:05:38 -04:00
Jasper St. Pierre
ec8ed1dbb0 screen: Set a black background for testing purposes 2014-06-27 12:38:11 -04:00
Jasper St. Pierre
203e5335ab window-x11: Fizzle out changes to the three different regions
GTK+ likes to set these, well, _NET_WM_OPAQUE_REGION in particular, to
the same value. Save some expensive and processing when this happens. We
should probably make GTK+ smarter.
2014-06-27 12:18:42 -04:00
Jasper St. Pierre
f1d8428650 window: Fix get_client_area_rect for the frame rect conversion
Specifically for CSD windows -- this was just absolutely wrong
before. This fixes weird painting and clipping artifacts for
CSD windows.
2014-06-27 11:58:39 -04:00
Owen W. Taylor
8d29d22e99 meta_accelerator_parse(): handle keysyms without the XF86 prefix
The GDK and hence GNOME standard is that keys that begin with XF86 according to
libxkbcommon not prefixed with XF86, though gdk_keyval_from_name() strips XF86
if provided. If libxkbcommon doesn't recognize the accelerator name without
XF86, try again adding XF86 to the start.

This restores compatibility with gnome-settings-daemon, schemas, and existing
user configuration.

https://bugzilla.gnome.org/show_bug.cgi?id=727993
2014-06-27 10:37:42 -04:00
Owen W. Taylor
9c6e527d4b Add ::first-frame signal to MetaWindowActor
This signal is emitted the first time a frame of contents of the
window is completed by the application and has been drawn on the
screen. This is meant to be used for performance measurement of
application startup.

https://bugzilla.gnome.org/show_bug.cgi?id=732343
2014-06-27 10:37:42 -04:00
Jasper St. Pierre
077606c057 window-wayland: Correct the buffer rect for frame extents 2014-06-26 13:58:11 -04:00
Jasper St. Pierre
a615f93060 window: Set custom frame extents to 0 if we don't have any
This is just a quick code cleanup.
2014-06-26 13:58:11 -04:00
Giovanni Campagna
c562657f1e main: kill custom log handler
It just gets in the way of gnome-shell's log handler (which
includes gjs backtraces optionally), it requires people to understand
what 8 or 16 mean as log levels, and it loses the log domain.
2014-06-26 19:10:28 +02:00
Giovanni Campagna
7b3922f8e9 build: link against libinput explicitly
We use its symbol, we should link against it - or strict linkers
like gold complain.
2014-06-26 19:10:28 +02:00
Marek Chalupa
c14382181f wayland window: update buffer_rect when moving
Update both - rect and buffer_rect positions when moving wayland window

https://bugzilla.gnome.org/show_bug.cgi?id=731237
2014-06-26 10:50:29 -04:00
Marek Chalupa
b2183dfda7 wayland-pointer: fix condition for grabbing
It returns FALSE when button_count is not 0. But grabbing for
move/resize is activated by clicking the button, so this condition
disallows the wayland clients to be moved/resized.

https://bugzilla.gnome.org/show_bug.cgi?id=731237
2014-06-26 10:50:29 -04:00
Jasper St. Pierre
bb92054c86 window: Use g_object_notify_by_pspec 2014-06-26 10:31:22 -04:00
Jasper St. Pierre
4e4a6eb5d7 window: Use g_object_class_install_properties 2014-06-26 10:31:01 -04:00
Tom Beckmann
692acbd986 window: Add a property for on_all_workspaces
Some plugins and extensions want to be able to know when the sticky
field of a window changes, so add a property for it and allow them
to connect to the notify::on-all-workspaces signal.
2014-06-26 10:31:00 -04:00
Yuri Myasoedov
901901825c Updated Russian translation 2014-06-25 22:37:50 +04:00
Florian Müllner
97f2de37e1 Bump version to 3.13.3
Update NEWS.
2014-06-24 23:42:06 +02:00
Florian Müllner
967b6c33df window: Add user_op parameter to update_monitor()
When workspaces-only-on-primary is set and a window is moved back to the
primary, we also move it to the active workspace to avoid the confusion
of a visible window suddenly disappearing when crossing the monitor border.
However when the window is not actually moved by the user, preserving the
workspace makes more sense - we already do this in some cases (e.g. when
moving between primary monitors), but miss others (unplugging the previous
monitor); just add an explicit user_op parameter as used elsewhere to cover
all exceptions.

https://bugzilla.gnome.org/show_bug.cgi?id=731760
2014-06-24 23:42:06 +02:00
Florian Müllner
00c7a27732 window: Keep track of preferred output
Remember the last monitor a window was moved to by user action and
try to move it back on monitor changes; this should match user
expectations much better when a monitor is unplugged temporarily.

https://bugzilla.gnome.org/show_bug.cgi?id=731760
2014-06-24 23:42:06 +02:00
Florian Müllner
048ba353c4 window: Don't make windows on non-primaries sticky on restart
When workspaces-only-on-primary is set, a window can be on all
workspaces either because it is on a non-primary workspace, or
because it was explicitly made sticky. Only the latter is reflected
in _NET_WM_STATE, but both will result in a "magic" _NET_WM_DESKTOP,
which we (and probably other WMs) use to set the initial sticky state.
So to avoid confusing other WMs (or ourselves), make sure to only
have _NET_WM_STATE_STICKY reflected in _NET_WM_DESKTOP when unmanaging.
2014-06-24 23:01:59 +02:00
Florian Müllner
555e2f6de2 Revert "window: Move placement code from the constraints path"
Window state like maximization and minimization should be preserved
over restarts - in a patch review, this would qualify as "needs-work",
so revert the cleanup until the issues are fixed.

This reverts commit dc6decefb5.
2014-06-24 22:59:06 +02:00
Jasper St. Pierre
ff8d5281f0 frames: Simplify the clip region calculation
Since GTK+ already clips to the extended region for us, there's no need
to combine the two. This does lose the fast-path, but I don't actually
expect this to fire, as when we're composited, we really won't ever get
partial exposes.
2014-06-21 13:50:44 -04:00
Jasper St. Pierre
4f9b994e73 frames: Don't bother painting the background
GDK (and also GTK+!) do this for us already.
2014-06-21 13:50:43 -04:00
Jasper St. Pierre
b8b0dc5c78 frames: Hackily adapt to GTK+ drawing changes
mutter is quite bad at using GTK+ correctly, relying on dumb things
like the single-buffering stuff. Hack up a temporary fix for the
newer GTK+ rendering changes.
2014-06-21 13:50:36 -04:00
Nikita Churaev
d0cafab836 Change shadow radiuses to match new Adwaita more or less
Exact simmilarity is not possible yet due to different blurring algorithms.

https://bugzilla.gnome.org/show_bug.cgi?id=731866
2014-06-19 11:55:24 +02:00
Jasper St. Pierre
24d7c5ebe3 compositor: Simplify meta_window_actor_set_updates_frozen
Since we always call it with the same value, just push that
value into the implementation.
2014-06-17 13:10:42 -04:00
Jasper St. Pierre
dc6decefb5 window: Move placement code from the constraints path
This way, it's implemented as a special case in move_resize_internal,
which makes it a lot easier to manage.
2014-06-17 11:40:49 -04:00
Jasper St. Pierre
25d7e48077 constraints: Clean up logical operations
The logical version of the bitwise XOR operator ^ is !=. I don't
know why XOR was even used in the first place.
2014-06-17 11:21:25 -04:00
Jasper St. Pierre
b0b8f37240 window: Save the buffer_rect internally
Rather than calculate it speculatively with the current properties
which may be too new or too out of date, make sure it always fits
with the proper definition. We update it when we update the toplevel
window for X11, and when a Wayland surface is committed with a newly
attached buffer.
2014-06-17 11:15:32 -04:00
Jasper St. Pierre
188e4e1b92 window: Rename get_input_rect to get_buffer_rect
With get_input_region existing, get_input_rect is a misnomer. Really,
it's about the geometry of the output surface, and it's only used that
way in the compositor code.

Way back when in GNOME 3.2, get_input_rect was added when we added
invisible borders. get_outer_rect was always synonymous with server-side
geometry of the toplevel. get_outer_rect was used for both user-side
policy (the "frame rect") and to get the geometry of the window.

Invisible borders were meant to extend the input region of the frame
window silently. Since most users of get_outer_rect cared about the
frame rect, we kept that the same and added a new method, get_input_rect
to get the full rect of the framed window with all invisible borders for
input kept on.

As time went on and CSD and Wayland became a reality, the relationship
between the server-side geometry and the "frame rect" became more
complicated, as can be evidenced by the recent commits. Since clients
don't tend to be framed anymore, they set their own input region.

get_buffer_rect is also sort of a poor name, since X11 doesn't really
have buffers, but we don't really have many other alternatives.

This doesn't change any of the code, nor the meaning. It will always
refer to the rectangle where the toplevel should be placed.
2014-06-17 10:33:52 -04:00
Jasper St. Pierre
9d5273bb15 window: Fix get_input_rect in a hacky way
All of the users of get_input_rect don't actually want a synthesized
input rect based off of the current margins. What they really want is
the last-configured size of the toplevel window.

Since we don't properly track this anymore in the generic MetaWindow,
use XGetWindowAttributes to fetch a server-side rectangle. This is a
bad layer violation, but since the window geometry code will have to
be rewritten anyway for the Wayland set_window_geometry, let's just
push a hacky fix for now.
2014-06-16 18:34:07 -04:00
Jasper St. Pierre
3c0fae74f1 window: Move get_toplevel_xwindow to window-x11 2014-06-16 18:29:38 -04:00
Jasper St. Pierre
86dae6d4c7 theme: Replace char array element comparisons with strncmp
https://bugzilla.gnome.org/show_bug.cgi?id=662962
2014-06-14 14:12:53 -04:00
Jasper St. Pierre
d06600aeb0 theme: Remove dead code
While the comment claims that we may want to keep this around
for optimization purposes, the operations are raw bitmap operations
that would be cleaner done in cairo.

https://bugzilla.gnome.org/show_bug.cgi?id=662962
2014-06-14 14:12:52 -04:00
Jasper St. Pierre
895a3d1f39 theme: Properly indent code
s/tabs/spaces/

https://bugzilla.gnome.org/show_bug.cgi?id=662962
2014-06-14 14:11:32 -04:00
Jasper St. Pierre
381ef5c683 theme: Consolidate unused ops
https://bugzilla.gnome.org/show_bug.cgi?id=662962
2014-06-14 14:11:00 -04:00
Jasper St. Pierre
62097897be theme: Remove unused RECTANGLE code
https://bugzilla.gnome.org/show_bug.cgi?id=662962
2014-06-14 14:04:59 -04:00
Jasper St. Pierre
2d2c47ba49 display: Remove unused variable 2014-06-12 17:46:23 -04:00
Jasper St. Pierre
89cdfc9194 display: Use G_SOURCE_CONTINUE / G_SOURCE_REMOVE 2014-06-12 17:46:23 -04:00
Jasper St. Pierre
ad60ea9e0e display: Use meta_window_has_pointer instead of XQueryPointer 2014-06-12 17:46:23 -04:00
Florian Müllner
a7350475e8 workspace: Extend builtin struts to screen edge when possible
Struts are defined in terms of screen edges, so expand the rectangles
we get via set_builtin_struts() accordingly. However we do want to
allow chrome on edges between monitors, in which case the expansion
would render an entire monitor unusable - don't expand the rectangles
in that case, which means we will only use them for constraining
windows but ignore them for the client-visible _NET_WORKAREA property.

https://bugzilla.gnome.org/show_bug.cgi?id=730527
2014-06-12 15:28:46 +02:00
Florian Müllner
f3d7c9cff9 testboxes: Update test cases
Who cares? We do now ...

https://bugzilla.gnome.org/show_bug.cgi?id=730527
2014-06-12 15:28:46 +02:00
Florian Müllner
906cbeed61 boxes: Ignore struts that don't attach to the side they claim
Like the _NET_WM_STRUT/_NET_WM_STRUT_PARTIAL client properties,
_NET_WORKAREA is defined in terms of screen geometry rather than
taking individual monitors into account. However we do want to
allow system chrome to be attached to a monitor edge rather than
a screen edges under some circumstances. As not all clients can
be assumed to deal gracefully with the resulting workarea, use
those "struts" only internally for constraining windows, but
ignore them when exporting _NET_WORKAREA.

https://bugzilla.gnome.org/show_bug.cgi?id=730527
2014-06-12 15:28:42 +02:00
Florian Müllner
0fccb0fc86 testboxes: Fix find_closest_point_to_line() test
Eeeks, testing floating points for equality ...
2014-06-12 01:39:54 +02:00
Florian Müllner
8100cefd4c screen: Split workspace initialization from meta_screen_new()
Since commit 8b2b65246a, we assume that the compositor always
exists. Alas, the assumption is wrong - the compositor is currently
initialized after the screen, but meta_screen_new() itself may
call a compositor function if initialization involves a workspace
switch (which will happen when meta_workspace_activate() is called
more than once and for different workspaces - or in other words,
when _NET_CURRENT_DESKTOP is set and not 0).
So carefully split out the offending bits and only call them after
the compositor has been initialized.

https://bugzilla.gnome.org/show_bug.cgi?id=731332
2014-06-11 23:35:34 +02:00
Florian Müllner
d7e99a3f86 prefs: Queue change notification when app menu visibility changed
Toggling the option should have an immediate effect, not only on
frame/state changes.
2014-06-11 23:34:09 +02:00
Jasper St. Pierre
6af944fe2c native: Add a warp_pointer implementation
Use the new clutter_evdev_warp_pointer method to implement it.
2014-06-11 16:42:05 -04:00
Jasper St. Pierre
12fc394b92 display: Fix the logic for moving attached dialogs
If we have a tree of a window, a non-attached dialog, and then an
attached dialog, we want to move the second window, not the attached
dialog or the topmost. In other words, we want to move the first
non-attached window, or the first "freefloating window".

This happens in Firefox, whose Preferences dialog is freefloating,
but suboptions of those are modal dialogs.
2014-06-11 16:42:05 -04:00
Jasper St. Pierre
53814fefc1 Move all X11 event processing to a new file in x11/ 2014-06-11 16:28:45 -04:00
Jasper St. Pierre
e87a01c80b wayland-touch: Rearrange header slightly 2014-06-11 16:28:45 -04:00
Jasper St. Pierre
21d7c1a850 wayland-pointer: Remove useless initialization
There is no way this value will ever be read, because we set the
cursor_surface to NULL, this is set at the same time as cursor_surface,
and it's only read if cursor_surface is non-NULL.
2014-06-11 15:15:58 -04:00
Jasper St. Pierre
e33c58297d wayland-surface: Subsurfaces start out in synchronous mode 2014-06-11 12:34:44 -04:00
Jasper St. Pierre
5350120db4 wayland-surface: Fix whitespace 2014-06-11 12:34:17 -04:00
Jasper St. Pierre
0997cf7fee Update .gitignore
These aren't generated in the data/ subdir.
2014-06-11 09:24:59 -04:00
Florian Müllner
af3aae7295 meta-window-actor: Don't add shadows to popups if the toolkit already does
GTK+ will add its own shadows client-side, so we don't need to anymore.

https://bugzilla.gnome.org/show_bug.cgi?id=731353
2014-06-10 13:40:33 +02:00
Florian Müllner
98e219da4b shadow-factory: Make sure to never use a negative spread
The smallest possible spread corresponds to an unblurred shadow, which
neither grows nor shrinks - thus the spread should be zero not negative
as returned by our current calculation.

https://bugzilla.gnome.org/show_bug.cgi?id=731353
2014-06-10 13:40:32 +02:00
Florian Müllner
fba022cc06 window-x11: Handle legacy fullscreen requests
Doing this on the actual resize requests makes more sense than
handling it as a window-manager imposed constraints, so move
the code accordingly.

https://bugzilla.gnome.org/show_bug.cgi?id=730681
2014-06-09 22:27:33 +02:00
Florian Müllner
3f6c6f1dd9 constraints: Translate frame to client rect for legacy fullscreen check
Stupid apps fullscreen themselves by resizing the client window to
monitor size. A monitor-sized frame rect on the other hand is perfectly
normal on monitors without struts - stop force-fullscreening those
and catch the real baddies instead.

https://bugzilla.gnome.org/show_bug.cgi?id=730681
2014-06-09 21:28:50 +02:00
Florian Müllner
ebc2e7221b window-x11: Fix silly regression
First we figure out the window type, then we ignore it - ouch.
2014-06-07 12:00:17 +02:00
Rico Tzschichholz
7cb30ced23 configure.ac: Modernize autoconf/libtool dependencies and macro usage 2014-06-05 18:05:19 +02:00
Rico Tzschichholz
7b449ac56c configure.ac: Group hard-dependencies together rather than split them up 2014-06-05 18:05:14 +02:00
Rico Tzschichholz
724953101d configure.ac: Drop obsolete shape/xsync confflags
In addition to 20a0eb9809
2014-06-05 18:04:59 +02:00
Rico Tzschichholz
8734477d52 meta: Add generated meta-version.h
Avoid populating *_VERSION constants through cflags in pkg-config-file
which could be overridden by the project using it. Properly prefix the
defines with META_ to make gi-scanner happy.
2014-06-05 14:05:16 +02:00
Rico Tzschichholz
ec8ba4b5f9 build: Move data files to their dedicated subfolder 2014-06-05 10:50:15 +02:00
Carlos Garnacho
2250865eb6 wayland: Implement the server side bits of wl_touch_interface
Clutter touch events are translated into events being sent down
the interface resource, with the exception of FRAME/CANCEL events,
which are handled directly via an evdev event filter.

The seat now announces invariably the WL_SEAT_CAPABILITY_TOUCH
capability, this should be eventually updated as devices come and
go.

The creation of MetaWaylandTouchSurface structs is dynamic, attached
to the lifetime of first/last touch on the client surface, and only
if the surface requests the wl_touch interface. MetaWaylandTouchInfo
structs are created to track individual touches, and are locked to
a single MetaWaylandTouchSurface (the implicit grab surface) determined
on CLUTTER_TOUCH_BEGIN.

https://bugzilla.gnome.org/show_bug.cgi?id=724442
2014-06-04 23:37:45 +02:00
Rico Tzschichholz
847a3bbee3 build: Fix some warnings and clean up a bit 2014-06-04 19:31:37 +02:00
Rico Tzschichholz
410a002ddd build: Do not distribute generated desktop-files 2014-06-04 16:13:11 +02:00
Rico Tzschichholz
8766db2593 common: Do not leak MetaResizePopup to the public api 2014-06-04 15:53:29 +02:00
Jasper St. Pierre
e362227514 window-x11: Don't ever send ConfigureNotifies for OR windows
There's a race here. If an OR window hides itself, moves, and then shows
itself, we will send a ConfigureNotify for the old size of the window
and might receive it after the client moves itself, causing us to show
the window at the wrong location.

Simply not sending the ConfigureNotify is the easiest thing to do.
2014-06-03 11:35:20 -04:00
Jasper St. Pierre
da311f266d window: Make sure to update client_rect for OR windows too
Before we unmanage, we send a ConfigureNotify to clients to let them
know if their frame is destroyed. We do this for OR windows too, even if
we really probably shouldn't.

This is based off of the client_rect. Since we listen to ConfigureNotify
on OR windows, we'll receive the event. If we don't ever update the
client_rect when moving or resizing OR windows, then we'll send
ourselves a ConfigureNotify for a 0x0 size and then think that the
client chose a new size for itself. Since our get_paint_volume is based
on that rectangle, but the TFP code inside Cogl uses XGetGeometry
itself, we get weird flickering artifacts.
2014-06-03 11:35:19 -04:00
Rico Tzschichholz
f5a4e996a8 display: Remove the screen from get_tab_list 2014-06-03 14:40:15 +02:00
Florian Müllner
a7f083897f frames: Only skip updating prelight when both control and state match
prelit_control is used for both prelight and pressed states, so the early
return in update_prelit_control() misses the case where prelit_control
already matches the control we are updating, but its state is PRESSED
rather than PRELIGHT. Fix the condition to not have pressed controls
linger around erroneously.

https://bugzilla.gnome.org/show_bug.cgi?id=731058
2014-06-02 23:49:48 +02:00
Florian Müllner
e2105dc721 frames: Fix pressed state of window menu buttons
Since window menus have been moved to the compositor, the pressed
state of the corresponding window buttons is messed up, as it is
reset immediately when getting a LeaveNotify event due to the
compositor taking a grab. Fix this by ignoring that particular
event.

https://bugzilla.gnome.org/show_bug.cgi?id=731058
2014-06-02 23:49:48 +02:00
Florian Müllner
b64548ee1f Pass button_rect when opening window menu from button
When opening the window menu without an associated control - e.g.
by right-clicking the titlebar or by keyboard - using coordinates
for the menu position is appropriate. However when the menu is
associated with a window button, the expected behavior in the
shell can be implemented much easier with the full button geometry:
the menu will point to the center of the button's bottom edge
rather than align to the left/right side of the titlebar as it
does now, and the clickable area where a release event does not
dismiss the menu will match the actual clickable area in mutter.

So add an additional show_window_menu_for_rect() function and
use it when opening the menu from a button.

https://bugzilla.gnome.org/show_bug.cgi?id=731058
2014-06-02 23:49:48 +02:00
Jasper St. Pierre
53425fa721 window: Make sure not to respond to input events on OR windows
This can happen since we select for events on the root window, and
clients themselves might not select for input, meaning the X server
will bubble up. Just do nothing and ignore the event in this case.

This should hopefully fix some of the

Window manager warning: Log level 8: meta_window_raise: assertion '!window->override_redirect' failed
Window manager warning: Log level 8: meta_window_focus: assertion '!window->override_redirect' failed

spam that people have been seeing.
2014-06-02 15:51:41 -04:00
160 changed files with 17724 additions and 19337 deletions

View File

@@ -1,35 +0,0 @@
Makefile
Makefile.in
aclocal.m4
confdefs.h
config.cache
config.guess
config.h
config.log
config.status
config.sub
configure
configure.scan
libtool
ltconfig
ltmain.sh
stamp-h
stamp-h.in
stamp-h1
stamp.h
version.h
config.h.in
install-sh
missing
mkinstalldirs
INSTALL
intl
ABOUT-NLS
COPYING
intltool-*
metacity.spec
autom4te.cache
compile
depcomp
omf.make
xmldocs.make

32
.gitignore vendored
View File

@@ -3,6 +3,7 @@ Makefile.in
Makefile.in.in
aclocal.m4
autom4te.cache
build-aux
compile
config.guess
config.h
@@ -19,11 +20,11 @@ libtool
ltmain.sh
missing
.deps
src/50-mutter-navigation.xml
src/50-mutter-system.xml
src/50-mutter-windows.xml
src/mutter.desktop
src/mutter-wayland.desktop
50-mutter-navigation.xml
50-mutter-system.xml
50-mutter-windows.xml
mutter.desktop
mutter-wayland.desktop
*.o
*.a
*.lo
@@ -32,10 +33,6 @@ src/mutter-wayland.desktop
*.swp
*.gir
*.typelib
tidy-enum-types.[ch]
tidy-marshal.[ch]
stamp-tidy-enum-types.h
stamp-tidy-marshal.h
stamp-h1
*.gmo
*.make
@@ -44,10 +41,9 @@ stamp-it
.intltool-merge-cache
POTFILES
po/*.pot
50-metacity-desktop-key.xml
50-metacity-key.xml
libmutter.pc
mutter
mutter-restart-helper
org.gnome.mutter.gschema.valid
org.gnome.mutter.gschema.xml
org.gnome.mutter.wayland.gschema.valid
@@ -56,19 +52,6 @@ testasyncgetprop
testboxes
testgradient
m4/*
mutter-grayscale
mutter-mag
mutter-message
mutter-window-demo
focus-window
test-attached
test-focus
test-gravity
test-resizing
test-size-hints
# We can't say just "wm-tester" here or it will ignore the directory
# rather than the binary
src/wm-tester/wm-tester
INSTALL
mkinstalldirs
src/mutter-enum-types.[ch]
@@ -84,6 +67,7 @@ src/xdg-shell-protocol.c
src/xdg-shell-server-protocol.h
src/xserver-protocol.c
src/xserver-server-protocol.h
src/meta/meta-version.h
doc/reference/*.args
doc/reference/*.bak
doc/reference/*.hierarchy

View File

@@ -1,10 +1,13 @@
SUBDIRS=src po doc
SUBDIRS = data src po doc
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
DISTCLEANFILES = intltool-extract intltool-merge intltool-update po/stamp-it po/.intltool-merge-cache
DISTCLEANFILES = \
intltool-extract \
intltool-merge \
intltool-update \
po/stamp-it \
po/.intltool-merge-cache
DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}

59
NEWS
View File

@@ -1,3 +1,62 @@
3.13.90
=======
* Only call XSync() once per frame [Rui; #728464]
* Update capabilities on device list changes [Carlos; #733563]
* Make use of GLSL optional [Adel; #733623]
* Handle gestures and touch events on wayland [Carlos; #733631]
* Add support for unminimize compositor effects [Cosimo; #733789]
* Always set the frame background to None [Giovanni; #734054]
* Add backend methods to handle keymaps [Rui; #734301]
* Actually mark revalidated MetaTextureTower levels as valid [Owen; #734400]
* Rely on explicit -backward switcher keybindings instead of <shift>-magic
[Christophe; #732295, #732385]
* Misc. bug fixes and cleanups [Rui, Adel, Christophe; #727178, #734852,
#734960]
Contributors:
Emmanuele Bassi, Giovanni Campagna, Cosimo Cecchi, Piotr Drąg,
Christophe Fergeau, Adel Gadllah, Carlos Garnacho, Rui Matos,
Florian Müllner, Jasper St. Pierre, Rico Tzschichholz, Olav Vitters,
Owen W. Taylor
Translations:
Kjartan Maraas [nb], Inaki Larranaga Murgoitio [eu], Lasse Liehu [fi],
ngoswami [as], Daniel Mustieles [es]
3.13.4
======
* Fix move/resize operations for wayland clients [Marek; #731237]
* Add ::first-frame signal to MetaWindowActor [Owen; #732343]
* Handle keysyms without the XF86 prefix [Owen; #727993]
* Add touch gesture support [Carlos]
* Fix a deadlock when exiting [Owen; #733068]
* Add framework for restarting the compositor with nice visuals
[Owen; #733026]
* Toggle seat capabilities on VT switch [Carlos; #733563]
* Misc bug fixes [Florian, Owen; #732695, #732350]
Contributors:
Tom Beckmann, Giovanni Campagna, Marek Chalupa, Adel Gadllah,
Carlos Garnacho, Florian Müllner, Jasper St. Pierre, Rico Tzschichholz,
Owen W. Taylor
Translations:
Yuri Myasoedov [ru], Fran Diéguez [gl], Aurimas Černius [lt], MarMav [el],
Enrico Nicoletto [pt_BR]
3.13.3
======
* Improve behavior of window buttons with compositor menus [Florian; #731058]
* Implement touch support on wayland [Carlos; #724442]
* Update window shadows [Nikita; #731866]
* Keep windows on the preferred output [Florian; #731760]
* Misc bug fixes [Jonas, Florian, Jasper; #729601, #730681, #731353, #731332,
#730527, #662962]
Contributors:
Jonas Ådahl, Nikita Churaev, Carlos Garnacho, Florian Müllner,
Jasper St. Pierre, Rico Tzschichholz
3.13.2
======
* Add basic HiDPI support on wayland [Adel; #728902]

View File

@@ -5,7 +5,7 @@ srcdir=`dirname $0`
test -z "$srcdir" && srcdir=.
PKG_NAME="mutter"
REQUIRED_AUTOMAKE_VERSION=1.10
REQUIRED_AUTOMAKE_VERSION=1.11
(test -f $srcdir/configure.ac \
&& test -d $srcdir/src) || {

View File

@@ -1,9 +1,8 @@
AC_PREREQ(2.50)
AC_CONFIG_MACRO_DIR([m4])
AC_PREREQ(2.62)
m4_define([mutter_major_version], [3])
m4_define([mutter_minor_version], [13])
m4_define([mutter_micro_version], [2])
m4_define([mutter_micro_version], [90])
m4_define([mutter_version],
[mutter_major_version.mutter_minor_version.mutter_micro_version])
@@ -14,6 +13,7 @@ AC_INIT([mutter], [mutter_version],
[http://bugzilla.gnome.org/enter_bug.cgi?product=mutter])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_SRCDIR(src/core/display.c)
AC_CONFIG_HEADERS(config.h)
@@ -40,12 +40,14 @@ GETTEXT_PACKAGE=mutter
AC_SUBST(GETTEXT_PACKAGE)
AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE",[Name of default gettext domain])
IT_PROG_INTLTOOL([0.34.90])
LT_PREREQ([2.2.6])
LT_INIT([disable-static])
IT_PROG_INTLTOOL([0.41])
AC_PROG_CC
AC_ISC_POSIX
AC_PROG_CC_C_O
AC_PROG_INSTALL
AC_HEADER_STDC
AC_LIBTOOL_WIN32_DLL
AM_PROG_LIBTOOL
PKG_PROG_PKG_CONFIG([0.21])
# Sets GLIB_GENMARSHAL and GLIB_MKENUMS
AM_PATH_GLIB_2_0()
@@ -70,15 +72,28 @@ CLUTTER_PACKAGE=clutter-1.0
MUTTER_PC_MODULES="
gtk+-3.0 >= 3.9.11
gio-2.0 >= 2.25.10
gio-unix-2.0 >= 2.25.10
pango >= 1.2.0
cairo >= 1.10.0
gsettings-desktop-schemas >= 3.7.3
xcomposite >= 0.2 xfixes xext xdamage xi >= 1.6.0
$CLUTTER_PACKAGE >= 1.17.5
$CLUTTER_PACKAGE >= 1.19.5
clutter-egl-1.0
cogl-1.0 >= 1.17.1
gbm
upower-glib >= 0.99.0
gnome-desktop-3.0
xcomposite >= 0.2
xcursor
xdamage
xext
xfixes
xi >= 1.6.0
xkbfile
xkeyboard-config
xkbcommon >= 0.4.3
xkbcommon-x11
x11-xcb
xcb-randr
"
GLIB_GSETTINGS
@@ -107,26 +122,12 @@ AC_ARG_WITH(libcanberra,
[disable the use of libcanberra for playing sounds]),,
with_libcanberra=auto)
AC_ARG_ENABLE(xsync,
AC_HELP_STRING([--disable-xsync],
[disable mutter's use of the XSync extension]),,
enable_xsync=auto)
AC_ARG_ENABLE(shape,
AC_HELP_STRING([--disable-shape],
[disable mutter's use of the shaped window extension]),,
enable_shape=auto)
AC_ARG_WITH([xwayland-path],
[AS_HELP_STRING([--with-xwayland-path], [Absolute path for an X Wayland server])],
[XWAYLAND_PATH="$withval"],
[XWAYLAND_PATH="$bindir/Xwayland"])
AM_GLIB_GNU_GETTEXT
## here we get the flags we'll actually use
# GRegex requires Glib-2.14.0
PKG_CHECK_MODULES(ALL, glib-2.0 >= 2.14.0)
# Unconditionally use this dir to avoid a circular dep with gnomecc
GNOME_KEYBINDINGS_KEYSDIR="${datadir}/gnome-control-center/keybindings"
@@ -191,23 +192,27 @@ if test x$found_introspection != xno; then
AC_SUBST(META_GIR)
fi
MUTTER_PC_MODULES="$MUTTER_PC_MODULES xcursor"
AC_PATH_PROG([WAYLAND_SCANNER],[wayland-scanner],[no])
AS_IF([test "x$WAYLAND_SCANNER" = "xno"],
AC_MSG_ERROR([Could not find wayland-scanner in your PATH, required for parsing wayland extension protocols]))
AC_SUBST([WAYLAND_SCANNER])
AC_SUBST(XWAYLAND_PATH)
MUTTER_PC_MODULES="$MUTTER_PC_MODULES clutter-wayland-1.0 clutter-wayland-compositor-1.0 clutter-egl-1.0 wayland-server >= 1.4.93"
PKG_CHECK_MODULES(MUTTER, $MUTTER_PC_MODULES)
PKG_CHECK_MODULES(MUTTER_NATIVE_BACKEND, [libdrm libsystemd], [have_native_backend=yes], [have_native_backend=no])
PKG_CHECK_MODULES(MUTTER_NATIVE_BACKEND, [libdrm libsystemd libinput], [have_native_backend=yes], [have_native_backend=no])
if test $have_native_backend = yes; then
AC_DEFINE([HAVE_NATIVE_BACKEND],[1],[Define if you want to enable the native (KMS) backend based on systemd])
fi
AM_CONDITIONAL([HAVE_NATIVE_BACKEND],[test $have_native_backend = yes])
PKG_CHECK_MODULES(MUTTER_WAYLAND, [clutter-wayland-1.0 clutter-wayland-compositor-1.0 wayland-server >= 1.5.90], [have_wayland=yes], [have_wayland=no])
if test $have_wayland = yes; then
AC_PATH_PROG([WAYLAND_SCANNER],[wayland-scanner],[no])
AS_IF([test $WAYLAND_SCANNER = "no"],
AC_MSG_ERROR([Could not find wayland-scanner in your PATH, required for parsing wayland extension protocols]))
AC_SUBST([WAYLAND_SCANNER])
AC_DEFINE([HAVE_WAYLAND],[1],[Define if you want to enable Wayland support])
fi
AM_CONDITIONAL([HAVE_WAYLAND],[test $have_wayland = yes])
PKG_CHECK_EXISTS([xi >= 1.6.99.1],
AC_DEFINE([HAVE_XI23],[1],[Define if you have support for XInput 2.3 or greater]))
@@ -244,16 +249,8 @@ if test x$have_xinerama = xno; then
AC_MSG_ERROR([Xinerama extension was not found])
fi
found_xkb=no
AC_CHECK_LIB(X11, XkbQueryExtension,
[AC_CHECK_HEADER(X11/XKBlib.h,
found_xkb=yes)],
, $ALL_X_LIBS)
if test "x$found_xkb" = "xyes"; then
AC_DEFINE(HAVE_XKB, , [Have keyboard extension library])
fi
AC_DEFINE_UNQUOTED([XKB_BASE], ["`$PKG_CONFIG --variable xkb_base xkeyboard-config`"],
[XKB base dir])
RANDR_LIBS=
found_randr=no
@@ -299,17 +296,6 @@ fi
AM_CONDITIONAL(HAVE_SM, test "$found_sm" = "yes")
HOST_ALIAS=$host_alias
AC_SUBST(HOST_ALIAS)
AC_PATH_PROG(GDK_PIXBUF_CSOURCE, gdk-pixbuf-csource, no)
if test x"$GDK_PIXBUF_CSOURCE" = xno; then
AC_MSG_ERROR([gdk-pixbuf-csource executable not found in your path - should be installed with GTK])
fi
AC_SUBST(GDK_PIXBUF_CSOURCE)
AC_PATH_PROG(ZENITY, zenity, no)
if test x"$ZENITY" = xno; then
AC_MSG_ERROR([zenity not found in your path - needed for dialogs])
@@ -324,11 +310,6 @@ fi
GTK_DOC_CHECK([1.15], [--flavour no-tmpl])
AC_CHECK_DECL([GL_EXT_x11_sync_object],
[],
[AC_MSG_ERROR([GL_EXT_x11_sync_object definition not found, please update your GL headers])],
[#include <GL/glx.h>])
#### Warnings (last since -Werror can disturb other tests)
# Stay command-line compatible with the gnome-common configure option. Here
@@ -397,6 +378,7 @@ changequote([,])dnl
AC_CONFIG_FILES([
Makefile
data/Makefile
doc/Makefile
doc/man/Makefile
doc/reference/Makefile
@@ -404,6 +386,7 @@ doc/reference/meta-docs.sgml
src/Makefile
src/libmutter.pc
src/compositor/plugins/Makefile
src/meta/meta-version.h
po/Makefile.in
])

View File

@@ -45,26 +45,68 @@
_description="Move window one monitor down" />
<KeyListEntry name="switch-applications"
reverse-entry="switch-applications-backward"
_description="Switch applications"/>
<KeyListEntry name="switch-applications-backward"
reverse-entry="switch-applications"
hidden="true"
_description="Switch to previous application"/>
<KeyListEntry name="switch-windows"
reverse-entry="switch-windows-backward"
_description="Switch windows"/>
<KeyListEntry name="switch-windows-backward"
reverse-entry="switch-windows"
hidden="true"
_description="Switch to previous window"/>
<KeyListEntry name="switch-group"
reverse-entry="switch-group-backward"
_description="Switch windows of an application"/>
<KeyListEntry name="switch-group-backward"
reverse-entry="switch-group"
hidden="true"
_description="Switch to previous window of an application"/>
<KeyListEntry name="switch-panels"
reverse-entry="switch-panels-backward"
_description="Switch system controls"/>
<KeyListEntry name="switch-panels-backward"
reverse-entry="switch-panels"
hidden="true"
_description="Switch to previous system control"/>
<KeyListEntry name="cycle-windows"
reverse-entry="cycle-windows-backward"
_description="Switch windows directly"/>
<KeyListEntry name="cycle-windows-backward"
reverse-entry="cycle-windows"
hidden="true"
_description="Switch directly to previous window"/>
<KeyListEntry name="cycle-group"
reverse-entry="cycle-group-backward"
_description="Switch windows of an app directly"/>
<KeyListEntry name="cycle-group-backward"
reverse-entry="cycle-group"
hidden="true"
_description="Switch directly to previous window of an app"/>
<KeyListEntry name="cycle-panels"
reverse-entry="cycle-panels-backward"
_description="Switch system controls directly"/>
<KeyListEntry name="cycle-panels-backward"
reverse-entry="cycle-panels"
hidden="true"
_description="Switch directly to previous system control"/>
<KeyListEntry name="show-desktop"
_description="Hide all normal windows"/>

View File

@@ -1,3 +1,36 @@
defaultcursordir = $(datadir)/mutter/cursors
desktopfiles_in_files = \
mutter.desktop.in \
mutter-wayland.desktop.in
desktopfilesdir = $(datadir)/applications
desktopfiles_DATA = $(desktopfiles_in_files:.desktop.in=.desktop)
dist_defaultcursor_DATA = left_ptr.png
@INTLTOOL_DESKTOP_RULE@
xml_in_files = \
50-mutter-navigation.xml.in \
50-mutter-system.xml.in \
50-mutter-windows.xml.in
xmldir = $(GNOME_KEYBINDINGS_KEYSDIR)
xml_DATA = $(xml_in_files:.xml.in=.xml)
gschema_in_files = \
org.gnome.mutter.gschema.xml.in \
org.gnome.mutter.wayland.gschema.xml.in
gsettings_SCHEMAS = $(gschema_in_files:.xml.in=.xml)
@INTLTOOL_XML_NOMERGE_RULE@
@GSETTINGS_RULES@
convertdir = $(datadir)/GConf/gsettings
convert_DATA = mutter-schemas.convert
CLEANFILES = \
$(desktopfiles_DATA) \
$(gsettings_SCHEMAS) \
$(xml_DATA)
EXTRA_DIST = \
$(convert_DATA) \
$(desktopfiles_in_files) \
$(gschema_in_files) \
$(xml_in_files)

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -300,6 +300,7 @@ MetaPluginVersion
META_PLUGIN_DECLARE
meta_plugin_switch_workspace_completed
meta_plugin_minimize_completed
meta_plugin_unminimize_completed
meta_plugin_maximize_completed
meta_plugin_unmaximize_completed
meta_plugin_map_completed
@@ -555,7 +556,7 @@ meta_window_is_monitor_sized
meta_window_is_override_redirect
meta_window_is_skip_taskbar
meta_window_get_rect
meta_window_get_input_rect
meta_window_get_buffer_rect
meta_window_get_frame_rect
meta_window_get_outer_rect
meta_window_client_rect_to_frame_rect

View File

@@ -23,7 +23,8 @@ environment.</description>
<download-page rdf:resource="http://download.gnome.org/sources/mutter/" />
<bug-database rdf:resource="http://bugzilla.gnome.org/browse.cgi?product=mutter" />
<category rdf:resource="http://api.gnome.org/doap-extensions#desktop" />
<category rdf:resource="http://api.gnome.org/doap-extensions#core" />
<programming-language>C</programming-language>
<maintainer>
<foaf:Person>

View File

@@ -1,8 +1,11 @@
# List of source files containing translatable strings.
# Please keep this file sorted alphabetically.
src/50-mutter-navigation.xml.in
src/50-mutter-system.xml.in
src/50-mutter-windows.xml.in
data/50-mutter-navigation.xml.in
data/50-mutter-system.xml.in
data/50-mutter-windows.xml.in
data/mutter.desktop.in
data/org.gnome.mutter.gschema.xml.in
data/org.gnome.mutter.wayland.gschema.xml.in
src/backends/meta-monitor-manager.c
src/compositor/compositor.c
src/compositor/meta-background.c
@@ -18,9 +21,6 @@ src/core/prefs.c
src/core/screen.c
src/core/util.c
src/core/window.c
src/mutter.desktop.in
src/org.gnome.mutter.gschema.xml.in
src/org.gnome.mutter.wayland.gschema.xml.in
src/ui/frames.c
src/ui/resizepopup.c
src/ui/theme.c

View File

@@ -1,2 +1 @@
src/metacity.schemas.in
src/mutter-wayland.desktop.in
data/mutter-wayland.desktop.in

1520
po/as.po

File diff suppressed because it is too large Load Diff

3490
po/el.po

File diff suppressed because it is too large Load Diff

895
po/es.po

File diff suppressed because it is too large Load Diff

1259
po/eu.po

File diff suppressed because it is too large Load Diff

1421
po/fi.po

File diff suppressed because it is too large Load Diff

1056
po/fr.po

File diff suppressed because it is too large Load Diff

886
po/gl.po

File diff suppressed because it is too large Load Diff

880
po/he.po

File diff suppressed because it is too large Load Diff

1094
po/lt.po

File diff suppressed because it is too large Load Diff

1028
po/nb.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1383
po/ru.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -5,44 +5,46 @@ lib_LTLIBRARIES = libmutter.la
SUBDIRS=compositor/plugins
INCLUDES= \
AM_CPPFLAGS = \
-DCLUTTER_ENABLE_COMPOSITOR_API \
-DCLUTTER_ENABLE_EXPERIMENTAL_API \
-DCOGL_ENABLE_EXPERIMENTAL_API \
-DCOGL_ENABLE_EXPERIMENTAL_2_0_API \
-DCLUTTER_DISABLE_DEPRECATION_WARNINGS \
-DCOGL_DISABLE_DEPRECATION_WARNINGS \
$(MUTTER_CFLAGS) \
$(MUTTER_NATIVE_BACKEND_CFLAGS) \
-I$(builddir) \
-I$(srcdir) \
-I$(srcdir)/backends \
-I$(srcdir)/core \
-I$(srcdir)/ui \
-I$(srcdir)/compositor \
-DMUTTER_LIBEXECDIR=\"$(libexecdir)\" \
-DHOST_ALIAS=\"@HOST_ALIAS@\" \
-DMUTTER_LOCALEDIR=\"$(prefix)/@DATADIRNAME@/locale\" \
-DMUTTER_LOCALEDIR=\"$(localedir)\" \
-DMUTTER_PKGDATADIR=\"$(pkgdatadir)\" \
-DMUTTER_DATADIR=\"$(datadir)\" \
-DG_LOG_DOMAIN=\"mutter\" \
-DSN_API_NOT_YET_FROZEN=1 \
-DMUTTER_MAJOR_VERSION=$(MUTTER_MAJOR_VERSION) \
-DMUTTER_MINOR_VERSION=$(MUTTER_MINOR_VERSION) \
-DMUTTER_MICRO_VERSION=$(MUTTER_MICRO_VERSION) \
-DMUTTER_PLUGIN_API_VERSION=$(MUTTER_PLUGIN_API_VERSION) \
-DMUTTER_PKGLIBDIR=\"$(pkglibdir)\" \
-DMUTTER_PLUGIN_DIR=\"@MUTTER_PLUGIN_DIR@\" \
-DMUTTER_PLUGIN_DIR=\"$(MUTTER_PLUGIN_DIR)\" \
-DGETTEXT_PACKAGE=\"$(GETTEXT_PACKAGE)\" \
-DXWAYLAND_PATH='"@XWAYLAND_PATH@"'
-DXWAYLAND_PATH=\"$(XWAYLAND_PATH)\"
mutter_built_sources = \
$(dbus_idle_built_sources) \
$(dbus_display_config_built_sources) \
$(dbus_login1_built_sources) \
mutter-enum-types.h \
mutter-enum-types.c \
mutter-enum-types.c
if HAVE_WAYLAND
mutter_built_sources += \
gtk-shell-protocol.c \
gtk-shell-server-protocol.h \
xdg-shell-protocol.c \
xdg-shell-server-protocol.h
endif
wayland_protocols = \
wayland/protocol/gtk-shell.xml \
@@ -50,7 +52,7 @@ wayland_protocols = \
libmutter_la_SOURCES = \
backends/meta-backend.c \
backends/meta-backend.h \
meta/meta-backend.h \
backends/meta-backend-private.h \
backends/meta-cursor.c \
backends/meta-cursor.h \
@@ -70,6 +72,8 @@ libmutter_la_SOURCES = \
backends/meta-monitor-manager.h \
backends/meta-monitor-manager-dummy.c \
backends/meta-monitor-manager-dummy.h \
backends/meta-stage.h \
backends/meta-stage.c \
backends/edid-parse.c \
backends/edid.h \
backends/x11/meta-backend-x11.c \
@@ -114,12 +118,6 @@ libmutter_la_SOURCES = \
compositor/meta-surface-actor.h \
compositor/meta-surface-actor-x11.c \
compositor/meta-surface-actor-x11.h \
compositor/meta-surface-actor-wayland.c \
compositor/meta-surface-actor-wayland.h \
compositor/meta-stage.h \
compositor/meta-stage.c \
compositor/meta-sync-ring.c \
compositor/meta-sync-ring.h \
compositor/meta-texture-rectangle.c \
compositor/meta-texture-rectangle.h \
compositor/meta-texture-tower.c \
@@ -157,6 +155,8 @@ libmutter_la_SOURCES = \
core/frame.h \
ui/gradient.c \
meta/gradient.h \
core/meta-gesture-tracker.c \
core/meta-gesture-tracker-private.h \
core/keybindings.c \
core/keybindings-private.h \
core/main.c \
@@ -168,6 +168,7 @@ libmutter_la_SOURCES = \
core/screen-private.h \
meta/screen.h \
meta/types.h \
core/restart.c \
core/stack.c \
core/stack.h \
core/stack-tracker.c \
@@ -196,6 +197,8 @@ libmutter_la_SOURCES = \
x11/iconcache.h \
x11/async-getprop.c \
x11/async-getprop.h \
x11/events.c \
x11/events.h \
x11/group-private.h \
x11/group-props.c \
x11/group-props.h \
@@ -210,7 +213,12 @@ libmutter_la_SOURCES = \
x11/window-x11-private.h \
x11/xprops.c \
x11/xprops.h \
x11/mutter-Xatomtype.h \
x11/mutter-Xatomtype.h
if HAVE_WAYLAND
libmutter_la_SOURCES += \
compositor/meta-surface-actor-wayland.c \
compositor/meta-surface-actor-wayland.h \
wayland/meta-wayland.c \
wayland/meta-wayland.h \
wayland/meta-wayland-private.h \
@@ -225,6 +233,8 @@ libmutter_la_SOURCES = \
wayland/meta-wayland-pointer.h \
wayland/meta-wayland-seat.c \
wayland/meta-wayland-seat.h \
wayland/meta-wayland-touch.c \
wayland/meta-wayland-touch.h \
wayland/meta-wayland-surface.c \
wayland/meta-wayland-surface.h \
wayland/meta-wayland-types.h \
@@ -233,6 +243,7 @@ libmutter_la_SOURCES = \
wayland/meta-wayland-outputs.h \
wayland/window-wayland.c \
wayland/window-wayland.h
endif
if HAVE_NATIVE_BACKEND
libmutter_la_SOURCES += \
@@ -258,7 +269,7 @@ libmutter_la_LIBADD = $(MUTTER_LIBS) $(MUTTER_NATIVE_BACKEND_LIBS)
# Headers installed for plugins; introspected information will
# be extracted into Mutter-<version>.gir
libmutterinclude_base_headers = \
libmutterinclude_headers = \
meta/barrier.h \
meta/boxes.h \
meta/common.h \
@@ -270,6 +281,7 @@ libmutterinclude_base_headers = \
meta/group.h \
meta/keybindings.h \
meta/main.h \
meta/meta-backend.h \
meta/meta-background-actor.h \
meta/meta-background-group.h \
meta/meta-background.h \
@@ -287,6 +299,13 @@ libmutterinclude_base_headers = \
meta/window.h \
meta/workspace.h
libmutterinclude_built_headers = \
meta/meta-version.h
libmutterinclude_base_headers = \
$(libmutterinclude_headers) \
$(libmutterinclude_built_headers)
# Excluded from scanning for introspection but installed
# atomnames.h: macros cause problems for scanning process
libmutterinclude_extra_headers = \
@@ -295,14 +314,21 @@ libmutterinclude_extra_headers = \
libmutterincludedir = $(includedir)/mutter/meta
libmutterinclude_HEADERS = \
$(libmutterinclude_base_headers) \
$(libmutterinclude_headers) \
$(libmutterinclude_extra_headers)
nodist_libmutterinclude_HEADERS = \
$(libmutterinclude_built_headers)
bin_PROGRAMS=mutter
mutter_SOURCES = core/mutter.c
mutter_LDADD = $(MUTTER_LIBS) libmutter.la
libexec_PROGRAMS = mutter-restart-helper
mutter_restart_helper_SOURCES = core/restart-helper.c
mutter_restart_helper_LDADD = $(MUTTER_LIBS)
if HAVE_INTROSPECTION
include $(INTROSPECTION_MAKEFILE)
@@ -326,7 +352,7 @@ INTROSPECTION_GIRS = Meta-$(api_version).gir
Meta-$(api_version).gir: libmutter.la
@META_GIR@_INCLUDES = GObject-2.0 GDesktopEnums-3.0 Gdk-3.0 Gtk-3.0 Clutter-1.0 xlib-2.0 xfixes-4.0 Cogl-1.0
@META_GIR@_EXPORT_PACKAGES = libmutter
@META_GIR@_CFLAGS = $(INCLUDES)
@META_GIR@_CFLAGS = $(AM_CPPFLAGS)
@META_GIR@_LIBS = libmutter.la
@META_GIR@_FILES = \
mutter-enum-types.h \
@@ -346,53 +372,21 @@ testboxes_LDADD = $(MUTTER_LIBS) libmutter.la
testgradient_LDADD = $(MUTTER_LIBS) libmutter.la
testasyncgetprop_LDADD = $(MUTTER_LIBS) libmutter.la
@INTLTOOL_DESKTOP_RULE@
desktopfilesdir=$(datadir)/applications
desktopfiles_in_files=mutter.desktop.in
desktopfiles_files=$(desktopfiles_in_files:.desktop.in=.desktop)
desktopfiles_DATA = $(desktopfiles_files)
xmldir = @GNOME_KEYBINDINGS_KEYSDIR@
xml_in_files = \
50-mutter-navigation.xml.in \
50-mutter-system.xml.in \
50-mutter-windows.xml.in
xml_DATA = $(xml_in_files:.xml.in=.xml)
dbus_idle_built_sources = meta-dbus-idle-monitor.c meta-dbus-idle-monitor.h
gsettings_SCHEMAS = org.gnome.mutter.gschema.xml org.gnome.mutter.wayland.gschema.xml
@INTLTOOL_XML_NOMERGE_RULE@
@GSETTINGS_RULES@
convertdir = $(datadir)/GConf/gsettings
convert_DATA = mutter-schemas.convert
CLEANFILES = \
mutter.desktop \
mutter-wm.desktop \
org.gnome.mutter.gschema.xml \
org.gnome.mutter.wayland.gschema.xml \
$(xml_DATA) \
$(mutter_built_sources) \
$(typelib_DATA) \
$(gir_DATA)
pkgconfigdir = $(libdir)/pkgconfig
DISTCLEANFILES = \
$(libmutterinclude_built_headers)
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libmutter.pc
EXTRA_DIST=$(desktopfiles_files) \
$(wmproperties_files) \
$(IMAGES) \
$(desktopfiles_in_files) \
$(wmproperties_in_files) \
$(xml_in_files) \
EXTRA_DIST = \
$(wayland_protocols) \
org.gnome.mutter.gschema.xml.in \
org.gnome.mutter.wayland.gschema.xml.in \
mutter-schemas.convert \
libmutter.pc.in \
mutter-enum-types.h.in \
mutter-enum-types.c.in \
@@ -400,7 +394,10 @@ EXTRA_DIST=$(desktopfiles_files) \
org.gnome.Mutter.DisplayConfig.xml \
org.gnome.Mutter.IdleMonitor.xml
BUILT_SOURCES = $(mutter_built_sources)
BUILT_SOURCES = \
$(mutter_built_sources) \
$(libmutterinclude_built_headers)
MUTTER_STAMP_FILES = stamp-mutter-enum-types.h
CLEANFILES += $(MUTTER_STAMP_FILES)

View File

@@ -28,7 +28,15 @@
#include <glib-object.h>
#include "meta-backend.h"
#include <xkbcommon/xkbcommon.h>
#include <meta/meta-backend.h>
#include <meta/meta-idle-monitor.h>
#include "meta-cursor-renderer.h"
#include "meta-monitor-manager.h"
#define DEFAULT_XKB_RULES_FILE "evdev"
#define DEFAULT_XKB_MODEL "pc105+inet"
#define META_TYPE_BACKEND (meta_backend_get_type ())
#define META_BACKEND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_BACKEND, MetaBackend))
@@ -66,6 +74,37 @@ struct _MetaBackendClass
void (* warp_pointer) (MetaBackend *backend,
int x,
int y);
void (* set_keymap) (MetaBackend *backend,
const char *layouts,
const char *variants,
const char *options);
struct xkb_keymap * (* get_keymap) (MetaBackend *backend);
void (* lock_layout_group) (MetaBackend *backend,
guint idx);
void (* update_screen_size) (MetaBackend *backend, int width, int height);
void (* select_stage_events) (MetaBackend *backend);
};
MetaIdleMonitor * meta_backend_get_idle_monitor (MetaBackend *backend,
int device_id);
MetaMonitorManager * meta_backend_get_monitor_manager (MetaBackend *backend);
MetaCursorRenderer * meta_backend_get_cursor_renderer (MetaBackend *backend);
gboolean meta_backend_grab_device (MetaBackend *backend,
int device_id,
uint32_t timestamp);
gboolean meta_backend_ungrab_device (MetaBackend *backend,
int device_id,
uint32_t timestamp);
void meta_backend_warp_pointer (MetaBackend *backend,
int x,
int y);
struct xkb_keymap * meta_backend_get_keymap (MetaBackend *backend);
#endif /* META_BACKEND_PRIVATE_H */

View File

@@ -24,12 +24,11 @@
#include "config.h"
#include "meta-backend.h"
#include <meta/meta-backend.h>
#include "meta-backend-private.h"
#include <clutter/clutter.h>
#include "backends/x11/meta-backend-x11.h"
#include "meta-stage.h"
#ifdef HAVE_NATIVE_BACKEND
#include "backends/native/meta-backend-native.h"
@@ -37,6 +36,13 @@
static MetaBackend *_backend;
/**
* meta_get_backend:
*
* Accessor for the singleton MetaBackend.
*
* Returns: (transfer none): The only #MetaBackend there is.
*/
MetaBackend *
meta_get_backend (void)
{
@@ -47,6 +53,8 @@ struct _MetaBackendPrivate
{
MetaMonitorManager *monitor_manager;
MetaCursorRenderer *cursor_renderer;
ClutterActor *stage;
};
typedef struct _MetaBackendPrivate MetaBackendPrivate;
@@ -70,12 +78,40 @@ meta_backend_finalize (GObject *object)
G_OBJECT_CLASS (meta_backend_parent_class)->finalize (object);
}
static void
meta_backend_sync_screen_size (MetaBackend *backend)
{
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
int width, height;
meta_monitor_manager_get_screen_size (priv->monitor_manager, &width, &height);
META_BACKEND_GET_CLASS (backend)->update_screen_size (backend, width, height);
}
static void
on_monitors_changed (MetaMonitorManager *monitors,
gpointer user_data)
{
MetaBackend *backend = META_BACKEND (user_data);
meta_backend_sync_screen_size (backend);
}
static void
meta_backend_real_post_init (MetaBackend *backend)
{
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
priv->stage = meta_stage_new ();
clutter_actor_realize (priv->stage);
META_BACKEND_GET_CLASS (backend)->select_stage_events (backend);
priv->monitor_manager = META_BACKEND_GET_CLASS (backend)->create_monitor_manager (backend);
g_signal_connect (priv->monitor_manager, "monitors-changed",
G_CALLBACK (on_monitors_changed), backend);
meta_backend_sync_screen_size (backend);
priv->cursor_renderer = META_BACKEND_GET_CLASS (backend)->create_cursor_renderer (backend);
}
@@ -104,9 +140,16 @@ meta_backend_real_ungrab_device (MetaBackend *backend,
}
static void
meta_backend_real_warp_pointer (MetaBackend *backend,
int x,
int y)
meta_backend_real_update_screen_size (MetaBackend *backend,
int width, int height)
{
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
clutter_actor_set_size (priv->stage, width, height);
}
static void
meta_backend_real_select_stage_events (MetaBackend *backend)
{
/* Do nothing */
}
@@ -122,7 +165,15 @@ meta_backend_class_init (MetaBackendClass *klass)
klass->create_cursor_renderer = meta_backend_real_create_cursor_renderer;
klass->grab_device = meta_backend_real_grab_device;
klass->ungrab_device = meta_backend_real_ungrab_device;
klass->warp_pointer = meta_backend_real_warp_pointer;
klass->update_screen_size = meta_backend_real_update_screen_size;
klass->select_stage_events = meta_backend_real_select_stage_events;
g_signal_new ("keymap-changed",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 0);
}
static void
@@ -154,6 +205,9 @@ meta_backend_post_init (MetaBackend *backend)
META_BACKEND_GET_CLASS (backend)->post_init (backend);
}
/**
* meta_backend_get_idle_monitor: (skip)
*/
MetaIdleMonitor *
meta_backend_get_idle_monitor (MetaBackend *backend,
int device_id)
@@ -169,6 +223,9 @@ meta_backend_get_idle_monitor (MetaBackend *backend,
return backend->device_monitors[device_id];
}
/**
* meta_backend_get_monitor_manager: (skip)
*/
MetaMonitorManager *
meta_backend_get_monitor_manager (MetaBackend *backend)
{
@@ -177,6 +234,9 @@ meta_backend_get_monitor_manager (MetaBackend *backend)
return priv->monitor_manager;
}
/**
* meta_backend_get_cursor_renderer: (skip)
*/
MetaCursorRenderer *
meta_backend_get_cursor_renderer (MetaBackend *backend)
{
@@ -185,6 +245,9 @@ meta_backend_get_cursor_renderer (MetaBackend *backend)
return priv->cursor_renderer;
}
/**
* meta_backend_grab_device: (skip)
*/
gboolean
meta_backend_grab_device (MetaBackend *backend,
int device_id,
@@ -193,6 +256,9 @@ meta_backend_grab_device (MetaBackend *backend,
return META_BACKEND_GET_CLASS (backend)->grab_device (backend, device_id, timestamp);
}
/**
* meta_backend_ungrab_device: (skip)
*/
gboolean
meta_backend_ungrab_device (MetaBackend *backend,
int device_id,
@@ -201,6 +267,9 @@ meta_backend_ungrab_device (MetaBackend *backend,
return META_BACKEND_GET_CLASS (backend)->ungrab_device (backend, device_id, timestamp);
}
/**
* meta_backend_warp_pointer: (skip)
*/
void
meta_backend_warp_pointer (MetaBackend *backend,
int x,
@@ -209,6 +278,47 @@ meta_backend_warp_pointer (MetaBackend *backend,
META_BACKEND_GET_CLASS (backend)->warp_pointer (backend, x, y);
}
void
meta_backend_set_keymap (MetaBackend *backend,
const char *layouts,
const char *variants,
const char *options)
{
META_BACKEND_GET_CLASS (backend)->set_keymap (backend, layouts, variants, options);
}
/**
* meta_backend_get_keymap: (skip)
*/
struct xkb_keymap *
meta_backend_get_keymap (MetaBackend *backend)
{
return META_BACKEND_GET_CLASS (backend)->get_keymap (backend);
}
void
meta_backend_lock_layout_group (MetaBackend *backend,
guint idx)
{
META_BACKEND_GET_CLASS (backend)->lock_layout_group (backend, idx);
}
/**
* meta_backend_get_stage:
* @backend: A #MetaBackend
*
* Gets the global #ClutterStage that's managed by this backend.
*
* Returns: (transfer none): the #ClutterStage
*/
ClutterActor *
meta_backend_get_stage (MetaBackend *backend)
{
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
return priv->stage;
}
static GType
get_backend_type (void)
{
@@ -281,6 +391,9 @@ static GSourceFuncs event_funcs = {
event_dispatch
};
/**
* meta_clutter_init: (skip)
*/
void
meta_clutter_init (void)
{

View File

@@ -30,7 +30,7 @@
typedef struct {
CoglTexture2D *texture;
struct gbm_bo *bo;
int hot_x, hot_y;
int offset_x, offset_y;
} MetaCursorImage;
struct _MetaCursorReference {
@@ -41,11 +41,11 @@ struct _MetaCursorReference {
};
CoglTexture *meta_cursor_reference_get_cogl_texture (MetaCursorReference *cursor,
int *hot_x,
int *hot_y);
int *offset_x,
int *offset_y);
struct gbm_bo *meta_cursor_reference_get_gbm_bo (MetaCursorReference *cursor,
int *hot_x,
int *hot_y);
int *offset_x,
int *offset_y);
#endif /* META_CURSOR_PRIVATE_H */

View File

@@ -27,21 +27,29 @@
#include "meta-cursor-renderer.h"
#include "meta-cursor-private.h"
#include <meta/meta-backend.h>
#include <meta/util.h>
#include <cogl/cogl.h>
#include <cogl/cogl-wayland-server.h>
#include <clutter/clutter.h>
#include "meta-stage.h"
#include "wayland/meta-wayland-private.h"
typedef struct
{
CoglTexture *texture;
MetaRectangle current_rect;
gboolean handled_by_backend;
} MetaCursorLayer;
struct _MetaCursorRendererPrivate
{
int current_x, current_y;
MetaRectangle current_rect;
MetaCursorLayer core_layer;
MetaCursorLayer dnd_layer;
MetaCursorReference *displayed_cursor;
gboolean handled_by_backend;
};
typedef struct _MetaCursorRendererPrivate MetaCursorRendererPrivate;
@@ -51,17 +59,16 @@ static void
queue_redraw (MetaCursorRenderer *renderer)
{
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
ClutterActor *stage = compositor->stage;
MetaBackend *backend = meta_get_backend ();
ClutterActor *stage = meta_backend_get_stage (backend);
/* During early initialization, we can have no stage */
if (!stage)
return;
if (priv->handled_by_backend)
meta_stage_set_cursor (META_STAGE (stage), NULL, &priv->current_rect);
else
meta_stage_set_cursor (META_STAGE (stage), priv->displayed_cursor, &priv->current_rect);
if (priv->core_layer.texture && !priv->core_layer.handled_by_backend)
meta_stage_set_cursor (META_STAGE (stage), layer->texture, &priv->current_rect);
meta_stage_set_dnd_surface (META_STAGE (stage),
}
static gboolean
@@ -81,33 +88,68 @@ meta_cursor_renderer_init (MetaCursorRenderer *renderer)
{
}
static void
update_layer (MetaCursorRenderer *renderer,
MetaCursorLayer *layer,
CoglTexture *texture,
int offset_x,
int offset_y)
{
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
layer->texture = texture;
if (layer->texture)
{
layer->current_rect.x = priv->current_x + offset_x;
layer->current_rect.y = priv->current_y + offset_y;
layer->current_rect.width = cogl_texture_get_width (layer->texture);
layer->current_rect.height = cogl_texture_get_height (layer->texture);
}
else
{
layer->current_rect.x = 0;
layer->current_rect.y = 0;
layer->current_rect.width = 0;
layer->current_rect.height = 0;
}
}
static void
update_cursor (MetaCursorRenderer *renderer)
{
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
gboolean handled_by_backend;
gboolean should_redraw = FALSE;
CoglTexture *texture;
int hot_x, hot_y;
if (priv->displayed_cursor)
{
<<<<<<< HEAD
CoglTexture *texture;
int hot_x, hot_y;
int offset_x, offset_y;
texture = meta_cursor_reference_get_cogl_texture (priv->displayed_cursor, &hot_x, &hot_y);
texture = meta_cursor_reference_get_cogl_texture (priv->displayed_cursor, &offset_x, &offset_y);
priv->current_rect.x = priv->current_x - hot_x;
priv->current_rect.y = priv->current_y - hot_y;
priv->current_rect.x = priv->current_x + offset_x;
priv->current_rect.y = priv->current_y + offset_y;
priv->current_rect.width = cogl_texture_get_width (COGL_TEXTURE (texture));
priv->current_rect.height = cogl_texture_get_height (COGL_TEXTURE (texture));
=======
texture = meta_cursor_reference_get_cogl_texture (priv->displayed_cursor, &hot_x, &hot_y);
>>>>>>> 75e7834... dnd 2
}
else
{
priv->current_rect.x = 0;
priv->current_rect.y = 0;
priv->current_rect.width = 0;
priv->current_rect.height = 0;
texture = NULL;
hot_x = 0;
hot_y = 0;
}
update_layer (renderer, &priv->core_layer, texture, hot_x, hot_y);
update_layer (renderer, &priv->
handled_by_backend = META_CURSOR_RENDERER_GET_CLASS (renderer)->update_cursor (renderer);
if (handled_by_backend != priv->handled_by_backend)
{
@@ -141,6 +183,17 @@ meta_cursor_renderer_set_cursor (MetaCursorRenderer *renderer,
update_cursor (renderer);
}
void
meta_cursor_renderer_set_dnd_surface (MetaCursorRenderer *renderer,
CoglTexture *texture,
int offset_x,
int offset_y)
{
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
update_layer (renderer, &priv->dnd_layer,
}
void
meta_cursor_renderer_set_position (MetaCursorRenderer *renderer,
int x, int y)
@@ -168,5 +221,5 @@ meta_cursor_renderer_get_rect (MetaCursorRenderer *renderer)
{
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
return &priv->current_rect;
return &priv->core_layer.current_rect;
}

View File

@@ -23,8 +23,6 @@
#define META_CURSOR_TRACKER_PRIVATE_H
#include <meta/meta-cursor-tracker.h>
#include <wayland-server.h>
#include <gbm.h>
#include "meta-cursor.h"
#include "meta-cursor-renderer.h"
@@ -32,7 +30,6 @@
struct _MetaCursorTracker {
GObject parent_instance;
MetaScreen *screen;
MetaCursorRenderer *renderer;
gboolean is_showing;

View File

@@ -34,25 +34,21 @@
#include <meta/errors.h>
#include <cogl/cogl.h>
#include <cogl/cogl-wayland-server.h>
#include <clutter/clutter.h>
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
#include "meta-backend.h"
#include "meta-backend-private.h"
#include "meta-cursor-private.h"
#include "meta-cursor-tracker-private.h"
#include "screen-private.h"
#include "wayland/meta-wayland-private.h"
G_DEFINE_TYPE (MetaCursorTracker, meta_cursor_tracker, G_TYPE_OBJECT);
enum {
CURSOR_CHANGED,
LAST_SIGNAL
CURSOR_CHANGED,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL];
@@ -60,10 +56,12 @@ static guint signals[LAST_SIGNAL];
static MetaCursorReference *
get_displayed_cursor (MetaCursorTracker *tracker)
{
MetaDisplay *display = meta_get_display ();
if (!tracker->is_showing)
return NULL;
if (tracker->screen->display->grab_op == META_GRAB_OP_NONE)
if (meta_display_windows_are_interactable (display))
{
if (tracker->has_window_cursor)
return tracker->window_cursor;
@@ -97,6 +95,9 @@ sync_cursor (MetaCursorTracker *tracker)
static void
meta_cursor_tracker_init (MetaCursorTracker *self)
{
MetaBackend *backend = meta_get_backend ();
self->renderer = meta_backend_get_cursor_renderer (backend);
self->is_showing = TRUE;
}
@@ -129,47 +130,9 @@ meta_cursor_tracker_class_init (MetaCursorTrackerClass *klass)
}
static MetaCursorTracker *
make_wayland_cursor_tracker (MetaScreen *screen)
meta_cursor_tracker_new (void)
{
MetaBackend *backend = meta_get_backend ();
MetaWaylandCompositor *compositor;
MetaCursorTracker *self;
self = g_object_new (META_TYPE_CURSOR_TRACKER, NULL);
self->screen = screen;
self->renderer = meta_backend_get_cursor_renderer (backend);
compositor = meta_wayland_compositor_get_default ();
compositor->seat->pointer.cursor_tracker = self;
meta_cursor_tracker_update_position (self, 0, 0);
return self;
}
static MetaCursorTracker *
make_x11_cursor_tracker (MetaScreen *screen)
{
MetaBackend *backend = meta_get_backend ();
MetaCursorTracker *self;
self = g_object_new (META_TYPE_CURSOR_TRACKER, NULL);
self->screen = screen;
self->renderer = meta_backend_get_cursor_renderer (backend);
XFixesSelectCursorInput (screen->display->xdisplay,
screen->xroot,
XFixesDisplayCursorNotifyMask);
return self;
}
static MetaCursorTracker *
meta_cursor_tracker_new (MetaScreen *screen)
{
if (meta_is_wayland_compositor ())
return make_wayland_cursor_tracker (screen);
else
return make_x11_cursor_tracker (screen);
return g_object_new (META_TYPE_CURSOR_TRACKER, NULL);
}
static MetaCursorTracker *_cursor_tracker;
@@ -186,7 +149,7 @@ MetaCursorTracker *
meta_cursor_tracker_get_for_screen (MetaScreen *screen)
{
if (!_cursor_tracker)
_cursor_tracker = meta_cursor_tracker_new (screen);
_cursor_tracker = meta_cursor_tracker_new ();
return _cursor_tracker;
}
@@ -207,12 +170,13 @@ gboolean
meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker,
XEvent *xevent)
{
MetaDisplay *display = meta_get_display ();
XFixesCursorNotifyEvent *notify_event;
if (meta_is_wayland_compositor ())
return FALSE;
if (xevent->xany.type != tracker->screen->display->xfixes_event_base + XFixesCursorNotify)
if (xevent->xany.type != display->xfixes_event_base + XFixesCursorNotify)
return FALSE;
notify_event = (XFixesCursorNotifyEvent *)xevent;
@@ -243,6 +207,7 @@ meta_cursor_reference_take_texture (CoglTexture2D *texture,
static void
ensure_xfixes_cursor (MetaCursorTracker *tracker)
{
MetaDisplay *display = meta_get_display ();
XFixesCursorImage *cursor_image;
CoglTexture2D *sprite;
guint8 *cursor_data;
@@ -252,7 +217,7 @@ ensure_xfixes_cursor (MetaCursorTracker *tracker)
if (tracker->xfixes_cursor)
return;
cursor_image = XFixesGetCursorImage (tracker->screen->display->xdisplay);
cursor_image = XFixesGetCursorImage (display->xdisplay);
if (!cursor_image)
return;
@@ -345,6 +310,7 @@ meta_cursor_tracker_get_hot (MetaCursorTracker *tracker,
int *y)
{
MetaCursorReference *cursor;
int offset_x, offset_y;
g_return_if_fail (META_IS_CURSOR_TRACKER (tracker));
@@ -359,14 +325,19 @@ meta_cursor_tracker_get_hot (MetaCursorTracker *tracker,
}
if (cursor)
meta_cursor_reference_get_cogl_texture (cursor, x, y);
{
meta_cursor_reference_get_cogl_texture (cursor, &offset_x, &offset_y);
}
else
{
if (x)
*x = 0;
if (y)
*y = 0;
offset_x = 0;
offset_y = 0;
}
if (x)
*x = -offset_x;
if (y)
*y = -offset_y;
}
void

View File

@@ -27,7 +27,7 @@
#include "display-private.h"
#include "screen-private.h"
#include "meta-backend.h"
#include "meta-backend-private.h"
#ifdef HAVE_NATIVE_BACKEND
#include "backends/native/meta-cursor-renderer-native.h"
@@ -39,7 +39,9 @@
#include <X11/extensions/Xfixes.h>
#include <X11/Xcursor/Xcursor.h>
#ifdef HAVE_WAYLAND
#include <cogl/cogl-wayland-server.h>
#endif
MetaCursorReference *
meta_cursor_reference_ref (MetaCursorReference *self)
@@ -247,6 +249,7 @@ meta_cursor_reference_from_theme (MetaCursor cursor)
return self;
}
#ifdef HAVE_WAYLAND
static void
meta_cursor_image_load_from_buffer (MetaCursorImage *image,
struct wl_resource *buffer,
@@ -345,28 +348,29 @@ meta_cursor_reference_from_buffer (struct wl_resource *buffer,
return self;
}
#endif
CoglTexture *
meta_cursor_reference_get_cogl_texture (MetaCursorReference *cursor,
int *hot_x,
int *hot_y)
int *offset_x,
int *offset_y)
{
if (hot_x)
*hot_x = cursor->image.hot_x;
if (hot_y)
*hot_y = cursor->image.hot_y;
if (offset_x)
*offset_x = cursor->image.offset_x;
if (offset_y)
*offset_y = cursor->image.offset_y;
return COGL_TEXTURE (cursor->image.texture);
}
struct gbm_bo *
meta_cursor_reference_get_gbm_bo (MetaCursorReference *cursor,
int *hot_x,
int *hot_y)
int *offset_x,
int *offset_y)
{
if (hot_x)
*hot_x = cursor->image.hot_x;
if (hot_y)
*hot_y = cursor->image.hot_y;
if (offset_x)
*offset_x = cursor->image.offset_x;
if (offset_y)
*offset_y = cursor->image.offset_y;
return cursor->image.bo;
}

View File

@@ -28,13 +28,14 @@ MetaCursorReference * meta_cursor_reference_ref (MetaCursorReference *cursor);
void meta_cursor_reference_unref (MetaCursorReference *cursor);
#include <meta/common.h>
#include <wayland-server.h>
MetaCursorReference * meta_cursor_reference_from_theme (MetaCursor cursor);
#ifdef HAVE_WAYLAND
#include <wayland-server.h>
MetaCursorReference * meta_cursor_reference_from_buffer (struct wl_resource *buffer,
int hot_x,
int hot_y);
int offset_x, int offset_y);
#endif
MetaCursor meta_cursor_reference_get_meta_cursor (MetaCursorReference *cursor);

View File

@@ -38,7 +38,7 @@
#include <meta/meta-idle-monitor.h>
#include "meta-idle-monitor-private.h"
#include "meta-idle-monitor-dbus.h"
#include "meta-backend.h"
#include "meta-backend-private.h"
G_STATIC_ASSERT(sizeof(unsigned long) == sizeof(gpointer));

View File

@@ -60,7 +60,7 @@ typedef struct {
gboolean enabled;
MetaRectangle rect;
float refresh_rate;
enum wl_output_transform transform;
MetaMonitorTransform transform;
gboolean is_primary;
gboolean is_presentation;
@@ -656,20 +656,20 @@ handle_text (GMarkupParseContext *context,
else if (strcmp (parser->output_field, "rotation") == 0)
{
if (strncmp (text, "normal", text_len) == 0)
parser->output.transform = WL_OUTPUT_TRANSFORM_NORMAL;
parser->output.transform = META_MONITOR_TRANSFORM_NORMAL;
else if (strncmp (text, "left", text_len) == 0)
parser->output.transform = WL_OUTPUT_TRANSFORM_90;
parser->output.transform = META_MONITOR_TRANSFORM_90;
else if (strncmp (text, "upside_down", text_len) == 0)
parser->output.transform = WL_OUTPUT_TRANSFORM_180;
parser->output.transform = META_MONITOR_TRANSFORM_180;
else if (strncmp (text, "right", text_len) == 0)
parser->output.transform = WL_OUTPUT_TRANSFORM_270;
parser->output.transform = META_MONITOR_TRANSFORM_270;
else
g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
"Invalid rotation type %.*s", (int)text_len, text);
}
else if (strcmp (parser->output_field, "reflect_x") == 0)
parser->output.transform += read_bool (text, text_len, error) ?
WL_OUTPUT_TRANSFORM_FLIPPED : 0;
META_MONITOR_TRANSFORM_FLIPPED : 0;
else if (strcmp (parser->output_field, "reflect_y") == 0)
{
/* FIXME (look at the rotation map in monitor.c) */
@@ -1115,7 +1115,7 @@ make_default_config (MetaMonitorConfig *self,
ret->outputs[0].rect.width = outputs[0].preferred_mode->width;
ret->outputs[0].rect.height = outputs[0].preferred_mode->height;
ret->outputs[0].refresh_rate = outputs[0].preferred_mode->refresh_rate;
ret->outputs[0].transform = WL_OUTPUT_TRANSFORM_NORMAL;
ret->outputs[0].transform = META_MONITOR_TRANSFORM_NORMAL;
ret->outputs[0].is_primary = TRUE;
return ret;
@@ -1167,7 +1167,7 @@ make_default_config (MetaMonitorConfig *self,
ret->outputs[j].rect.width = outputs[0].preferred_mode->width;
ret->outputs[j].rect.height = outputs[0].preferred_mode->height;
ret->outputs[j].refresh_rate = outputs[0].preferred_mode->refresh_rate;
ret->outputs[j].transform = WL_OUTPUT_TRANSFORM_NORMAL;
ret->outputs[j].transform = META_MONITOR_TRANSFORM_NORMAL;
ret->outputs[j].is_primary = FALSE;
ret->outputs[j].is_presentation = FALSE;
}
@@ -1202,7 +1202,7 @@ make_default_config (MetaMonitorConfig *self,
ret->outputs[i].rect.width = output->preferred_mode->width;
ret->outputs[i].rect.height = output->preferred_mode->height;
ret->outputs[i].refresh_rate = output->preferred_mode->refresh_rate;
ret->outputs[i].transform = WL_OUTPUT_TRANSFORM_NORMAL;
ret->outputs[i].transform = META_MONITOR_TRANSFORM_NORMAL;
ret->outputs[i].is_primary = (output == primary);
/* Disable outputs that would go beyond framebuffer limits */
@@ -1250,7 +1250,7 @@ ensure_at_least_one_output (MetaMonitorConfig *self,
ret->outputs[i].rect.width = output->preferred_mode->width;
ret->outputs[i].rect.height = output->preferred_mode->height;
ret->outputs[i].refresh_rate = output->preferred_mode->refresh_rate;
ret->outputs[i].transform = WL_OUTPUT_TRANSFORM_NORMAL;
ret->outputs[i].transform = META_MONITOR_TRANSFORM_NORMAL;
ret->outputs[i].is_primary = TRUE;
}
else
@@ -1512,7 +1512,7 @@ meta_monitor_config_save (MetaMonitorConfig *self)
output->rect.x,
output->rect.y,
rotation_map[output->transform & 0x3],
output->transform >= WL_OUTPUT_TRANSFORM_FLIPPED ? "yes" : "no",
output->transform >= META_MONITOR_TRANSFORM_FLIPPED ? "yes" : "no",
output->is_primary ? "yes" : "no",
output->is_presentation ? "yes" : "no");
}
@@ -1621,13 +1621,13 @@ output_supports_mode (MetaOutput *output,
}
static gboolean
crtc_assignment_assign (CrtcAssignment *assign,
MetaCRTC *crtc,
MetaMonitorMode *mode,
int x,
int y,
enum wl_output_transform transform,
MetaOutput *output)
crtc_assignment_assign (CrtcAssignment *assign,
MetaCRTC *crtc,
MetaMonitorMode *mode,
int x,
int y,
MetaMonitorTransform transform,
MetaOutput *output)
{
MetaCRTCInfo *info = g_hash_table_lookup (assign->info, crtc);

View File

@@ -27,7 +27,7 @@
#include "meta-monitor-manager-dummy.h"
#define ALL_WL_TRANSFORMS ((1 << (WL_OUTPUT_TRANSFORM_FLIPPED_270 + 1)) - 1)
#define ALL_TRANSFORMS ((1 << (META_MONITOR_TRANSFORM_FLIPPED_270 + 1)) - 1)
struct _MetaMonitorManagerDummy
{
@@ -66,8 +66,8 @@ meta_monitor_manager_dummy_read_current (MetaMonitorManager *manager)
manager->crtcs[0].rect.width = manager->modes[0].width;
manager->crtcs[0].rect.height = manager->modes[0].height;
manager->crtcs[0].current_mode = &manager->modes[0];
manager->crtcs[0].transform = WL_OUTPUT_TRANSFORM_NORMAL;
manager->crtcs[0].all_transforms = ALL_WL_TRANSFORMS;
manager->crtcs[0].transform = META_MONITOR_TRANSFORM_NORMAL;
manager->crtcs[0].all_transforms = ALL_TRANSFORMS;
manager->crtcs[0].is_dirty = FALSE;
manager->crtcs[0].logical_monitor = NULL;
@@ -75,7 +75,7 @@ meta_monitor_manager_dummy_read_current (MetaMonitorManager *manager)
manager->n_outputs = 1;
manager->outputs[0].crtc = &manager->crtcs[0];
manager->outputs[0].output_id = 1;
manager->outputs[0].winsys_id = 1;
manager->outputs[0].name = g_strdup ("LVDS");
manager->outputs[0].vendor = g_strdup ("MetaProducts Inc.");
manager->outputs[0].product = g_strdup ("unknown");

View File

@@ -37,7 +37,7 @@
#include <meta/errors.h>
#include "meta-monitor-config.h"
#include "backends/x11/meta-monitor-manager-xrandr.h"
#include "meta-backend.h"
#include "meta-backend-private.h"
enum {
CONFIRM_DISPLAY_CHANGE,
@@ -125,7 +125,7 @@ make_logical_config (MetaMonitorManager *manager)
*/
info.is_presentation = TRUE;
info.in_fullscreen = -1;
info.output_id = 0;
info.winsys_id = 0;
g_array_append_val (monitor_infos, info);
@@ -156,8 +156,8 @@ make_logical_config (MetaMonitorManager *manager)
info->is_primary = info->is_primary || output->is_primary;
info->is_presentation = info->is_presentation && output->is_presentation;
if (output->is_primary || info->output_id == 0)
info->output_id = output->output_id;
if (output->is_primary || info->winsys_id == 0)
info->winsys_id = output->winsys_id;
if (info->is_primary)
manager->primary_monitor_index = info->number;
@@ -477,7 +477,7 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
GVariantBuilder transforms;
g_variant_builder_init (&transforms, G_VARIANT_TYPE ("au"));
for (j = 0; j <= WL_OUTPUT_TRANSFORM_FLIPPED_270; j++)
for (j = 0; j <= META_MONITOR_TRANSFORM_FLIPPED_270; j++)
if (crtc->all_transforms & (1 << j))
g_variant_builder_add (&transforms, "u", j);
@@ -560,7 +560,7 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
g_variant_builder_add (&output_builder, "(uxiausauaua{sv})",
i, /* ID */
(gint64)output->output_id,
(gint64)output->winsys_id,
(int)(output->crtc ? output->crtc - manager->crtcs : -1),
&crtcs,
output->name,
@@ -667,7 +667,7 @@ meta_monitor_manager_handle_apply_configuration (MetaDBusDisplayConfig *skeleto
int new_mode, x, y;
int new_screen_width, new_screen_height;
guint transform;
guint output_id;
guint output_index;
GPtrArray *crtc_infos, *output_infos;
if (serial != manager->serial)
@@ -694,7 +694,6 @@ meta_monitor_manager_handle_apply_configuration (MetaDBusDisplayConfig *skeleto
MetaOutput *first_output;
MetaCRTC *crtc;
MetaMonitorMode *mode;
guint output_id;
crtc_info = g_slice_new (MetaCRTCInfo);
crtc_info->outputs = g_ptr_array_new ();
@@ -756,8 +755,8 @@ meta_monitor_manager_handle_apply_configuration (MetaDBusDisplayConfig *skeleto
crtc_info->y = 0;
}
if (transform < WL_OUTPUT_TRANSFORM_NORMAL ||
transform > WL_OUTPUT_TRANSFORM_FLIPPED_270 ||
if (transform < META_MONITOR_TRANSFORM_NORMAL ||
transform > META_MONITOR_TRANSFORM_FLIPPED_270 ||
((crtc->all_transforms & (1 << transform)) == 0))
{
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
@@ -768,18 +767,18 @@ meta_monitor_manager_handle_apply_configuration (MetaDBusDisplayConfig *skeleto
crtc_info->transform = transform;
first_output = NULL;
while (g_variant_iter_loop (nested_outputs, "u", &output_id))
while (g_variant_iter_loop (nested_outputs, "u", &output_index))
{
MetaOutput *output;
if (output_id >= manager->n_outputs)
if (output_index >= manager->n_outputs)
{
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_INVALID_ARGS,
"Invalid output id");
return TRUE;
}
output = &manager->outputs[output_id];
output = &manager->outputs[output_index];
if (!output_can_config (output, crtc, mode))
{
@@ -824,12 +823,12 @@ meta_monitor_manager_handle_apply_configuration (MetaDBusDisplayConfig *skeleto
}
g_variant_iter_init (&output_iter, outputs);
while (g_variant_iter_loop (&output_iter, "(u@a{sv})", &output_id, &properties))
while (g_variant_iter_loop (&output_iter, "(u@a{sv})", &output_index, &properties))
{
MetaOutputInfo *output_info;
gboolean primary, presentation;
if (output_id >= manager->n_outputs)
if (output_index >= manager->n_outputs)
{
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_INVALID_ARGS,
@@ -838,7 +837,7 @@ meta_monitor_manager_handle_apply_configuration (MetaDBusDisplayConfig *skeleto
}
output_info = g_slice_new0 (MetaOutputInfo);
output_info->output = &manager->outputs[output_id];
output_info->output = &manager->outputs[output_index];
if (g_variant_lookup (properties, "primary", "b", &primary))
output_info->is_primary = primary;
@@ -909,7 +908,7 @@ static gboolean
meta_monitor_manager_handle_change_backlight (MetaDBusDisplayConfig *skeleton,
GDBusMethodInvocation *invocation,
guint serial,
guint output_id,
guint output_index,
gint value)
{
MetaMonitorManager *manager = META_MONITOR_MANAGER (skeleton);
@@ -923,14 +922,14 @@ meta_monitor_manager_handle_change_backlight (MetaDBusDisplayConfig *skeleton,
return TRUE;
}
if (output_id >= manager->n_outputs)
if (output_index >= manager->n_outputs)
{
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_INVALID_ARGS,
"Invalid output id");
return TRUE;
}
output = &manager->outputs[output_id];
output = &manager->outputs[output_index];
if (value < 0 || value > 100)
{

View File

@@ -41,8 +41,6 @@
#include "display-private.h"
#include <meta/screen.h>
#include "stack-tracker.h"
#include "ui.h"
#include <wayland-server.h>
#include "meta-display-config-shared.h"
#include "meta-dbus-display-config.h"
@@ -60,12 +58,23 @@ typedef struct _MetaMonitorInfo MetaMonitorInfo;
typedef struct _MetaCRTCInfo MetaCRTCInfo;
typedef struct _MetaOutputInfo MetaOutputInfo;
typedef enum {
META_MONITOR_TRANSFORM_NORMAL,
META_MONITOR_TRANSFORM_90,
META_MONITOR_TRANSFORM_180,
META_MONITOR_TRANSFORM_270,
META_MONITOR_TRANSFORM_FLIPPED,
META_MONITOR_TRANSFORM_FLIPPED_90,
META_MONITOR_TRANSFORM_FLIPPED_180,
META_MONITOR_TRANSFORM_FLIPPED_270,
} MetaMonitorTransform;
struct _MetaOutput
{
/* The CRTC driving this output, NULL if the output is not enabled */
MetaCRTC *crtc;
/* The low-level ID of this output, used to apply back configuration */
glong output_id;
glong winsys_id;
char *name;
char *vendor;
char *product;
@@ -114,7 +123,7 @@ struct _MetaCRTC
glong crtc_id;
MetaRectangle rect;
MetaMonitorMode *current_mode;
enum wl_output_transform transform;
MetaMonitorTransform transform;
unsigned int all_transforms;
/* Only used to build the logical configuration
@@ -162,14 +171,14 @@ struct _MetaMonitorInfo
gboolean in_fullscreen;
/* The primary or first output for this monitor, 0 if we can't figure out.
It can be matched to an output_id of a MetaOutput.
It can be matched to a winsys_id of a MetaOutput.
This is used as an opaque token on reconfiguration when switching from
clone to extened, to decide on what output the windows should go next
(it's an attempt to keep windows on the same monitor, and preferably on
the primary one).
*/
glong output_id;
glong winsys_id;
};
/*
@@ -185,7 +194,7 @@ struct _MetaCRTCInfo {
MetaMonitorMode *mode;
int x;
int y;
enum wl_output_transform transform;
MetaMonitorTransform transform;
GPtrArray *outputs;
};
@@ -339,7 +348,7 @@ gboolean meta_monitor_manager_has_hotplug_mode_update (MetaMonitorMana
/* Returns true if transform causes width and height to be inverted
This is true for the odd transforms in the enum */
static inline gboolean
meta_monitor_transform_is_rotated (enum wl_output_transform transform)
meta_monitor_transform_is_rotated (MetaMonitorTransform transform)
{
return (transform % 2);
}

214
src/backends/meta-stage.c Normal file
View File

@@ -0,0 +1,214 @@
/*
* Copyright (C) 2014 Red Hat
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Written by:
* Jasper St. Pierre <jstpierre@mecheye.net>
*/
#include <config.h>
#include "meta-stage.h"
#include "meta-cursor-private.h"
#include <meta/meta-backend.h>
#include <meta/util.h>
typedef struct {
gboolean enabled;
CoglPipeline *pipeline;
CoglTexture *texture;
MetaRectangle current_rect;
MetaRectangle previous_rect;
gboolean previous_is_valid;
} MetaOverlay;
struct _MetaStagePrivate {
MetaOverlay dnd_overlay;
MetaOverlay cursor_overlay;
};
typedef struct _MetaStagePrivate MetaStagePrivate;
G_DEFINE_TYPE_WITH_PRIVATE (MetaStage, meta_stage, CLUTTER_TYPE_STAGE);
static void
meta_overlay_init (MetaOverlay *overlay)
{
CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
overlay->pipeline = cogl_pipeline_new (ctx);
}
static void
meta_overlay_free (MetaOverlay *overlay)
{
if (overlay->pipeline)
cogl_object_unref (overlay->pipeline);
}
static void
meta_overlay_set (MetaOverlay *overlay,
CoglTexture *texture,
MetaRectangle *rect)
{
if (overlay->texture != texture)
{
overlay->texture = texture;
if (texture)
{
cogl_pipeline_set_layer_texture (overlay->pipeline, 0, texture);
overlay->enabled = TRUE;
}
else
{
cogl_pipeline_set_layer_texture (overlay->pipeline, 0, NULL);
overlay->enabled = FALSE;
}
}
overlay->current_rect = *rect;
}
static void
meta_overlay_paint (MetaOverlay *overlay)
{
if (!overlay->enabled)
return;
g_assert (meta_is_wayland_compositor ());
cogl_framebuffer_draw_rectangle (cogl_get_draw_framebuffer (),
overlay->pipeline,
overlay->current_rect.x,
overlay->current_rect.y,
overlay->current_rect.x +
overlay->current_rect.width,
overlay->current_rect.y +
overlay->current_rect.height);
overlay->previous_rect = overlay->current_rect;
overlay->previous_is_valid = TRUE;
}
static void
meta_stage_finalize (GObject *object)
{
MetaStage *stage = META_STAGE (object);
MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
meta_overlay_free (&priv->dnd_overlay);
meta_overlay_free (&priv->cursor_overlay);
}
static void
meta_stage_paint (ClutterActor *actor)
{
MetaStage *stage = META_STAGE (actor);
MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
CLUTTER_ACTOR_CLASS (meta_stage_parent_class)->paint (actor);
meta_overlay_paint (&priv->dnd_overlay);
meta_overlay_paint (&priv->cursor_overlay);
}
static void
meta_stage_class_init (MetaStageClass *klass)
{
ClutterActorClass *actor_class = (ClutterActorClass *) klass;
GObjectClass *object_class = (GObjectClass *) klass;
object_class->finalize = meta_stage_finalize;
actor_class->paint = meta_stage_paint;
}
static void
meta_stage_init (MetaStage *stage)
{
MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
meta_overlay_init (&priv->dnd_overlay);
meta_overlay_init (&priv->cursor_overlay);
clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), FALSE);
}
ClutterActor *
meta_stage_new (void)
{
return g_object_new (META_TYPE_STAGE,
"cursor-visible", FALSE,
NULL);
}
static void
queue_redraw_for_overlay (MetaStage *stage,
MetaOverlay *overlay)
{
cairo_rectangle_int_t clip;
/* Clear the location the overlay was at before, if we need to. */
if (overlay->previous_is_valid)
{
clip.x = overlay->previous_rect.x;
clip.y = overlay->previous_rect.y;
clip.width = overlay->previous_rect.width;
clip.height = overlay->previous_rect.height;
clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stage), &clip);
overlay->previous_is_valid = FALSE;
}
/* Draw the overlay at the new position */
if (overlay->enabled)
{
clip.x = overlay->current_rect.x;
clip.y = overlay->current_rect.y;
clip.width = overlay->current_rect.width;
clip.height = overlay->current_rect.height;
clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stage), &clip);
}
}
void
meta_stage_set_dnd_surface (MetaStage *stage,
CoglTexture *texture,
MetaRectangle *rect)
{
MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
g_assert (meta_is_wayland_compositor ());
meta_overlay_set (&priv->dnd_overlay, texture, rect);
queue_redraw_for_overlay (stage, &priv->dnd_overlay);
}
void
meta_stage_set_cursor (MetaStage *stage,
CoglTexture *texture,
MetaRectangle *rect)
{
MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
g_assert (meta_is_wayland_compositor () || texture == NULL);
meta_overlay_set (&priv->cursor_overlay, texture, rect);
queue_redraw_for_overlay (stage, &priv->cursor_overlay);
}

View File

@@ -51,9 +51,14 @@ GType meta_stage_get_type (void) G_GNUC_CONST;
ClutterActor *meta_stage_new (void);
void meta_stage_set_cursor (MetaStage *stage,
MetaCursorReference *cursor,
MetaRectangle *rect);
void meta_stage_set_dnd_surface (MetaStage *stage,
CoglTexture *texture,
MetaRectangle *rect);
void meta_stage_set_cursor (MetaStage *stage,
CoglTexture *texture,
MetaRectangle *rect);
G_END_DECLS
#endif /* META_STAGE_H */

View File

@@ -174,6 +174,63 @@ meta_backend_native_create_cursor_renderer (MetaBackend *backend)
return g_object_new (META_TYPE_CURSOR_RENDERER_NATIVE, NULL);
}
static void
meta_backend_native_warp_pointer (MetaBackend *backend,
int x,
int y)
{
ClutterDeviceManager *manager = clutter_device_manager_get_default ();
ClutterInputDevice *device = clutter_device_manager_get_core_device (manager, CLUTTER_POINTER_DEVICE);
/* XXX */
guint32 time_ = 0;
clutter_evdev_warp_pointer (device, time_, x, y);
}
static void
meta_backend_native_set_keymap (MetaBackend *backend,
const char *layouts,
const char *variants,
const char *options)
{
ClutterDeviceManager *manager = clutter_device_manager_get_default ();
struct xkb_rule_names names;
struct xkb_keymap *keymap;
struct xkb_context *context;
names.rules = DEFAULT_XKB_RULES_FILE;
names.model = DEFAULT_XKB_MODEL;
names.layout = layouts;
names.variant = variants;
names.options = options;
context = xkb_context_new (XKB_CONTEXT_NO_FLAGS);
keymap = xkb_keymap_new_from_names (context, &names, XKB_KEYMAP_COMPILE_NO_FLAGS);
xkb_context_unref (context);
clutter_evdev_set_keyboard_map (manager, keymap);
g_signal_emit_by_name (backend, "keymap-changed", 0);
xkb_keymap_unref (keymap);
}
static struct xkb_keymap *
meta_backend_native_get_keymap (MetaBackend *backend)
{
ClutterDeviceManager *manager = clutter_device_manager_get_default ();
return clutter_evdev_get_keyboard_map (manager);
}
static void
meta_backend_native_lock_layout_group (MetaBackend *backend,
guint idx)
{
ClutterDeviceManager *manager = clutter_device_manager_get_default ();
clutter_evdev_set_keyboard_layout_index (manager, idx);
}
static void
meta_backend_native_class_init (MetaBackendNativeClass *klass)
{
@@ -183,6 +240,11 @@ meta_backend_native_class_init (MetaBackendNativeClass *klass)
backend_class->create_idle_monitor = meta_backend_native_create_idle_monitor;
backend_class->create_monitor_manager = meta_backend_native_create_monitor_manager;
backend_class->create_cursor_renderer = meta_backend_native_create_cursor_renderer;
backend_class->warp_pointer = meta_backend_native_warp_pointer;
backend_class->set_keymap = meta_backend_native_set_keymap;
backend_class->get_keymap = meta_backend_native_get_keymap;
backend_class->lock_layout_group = meta_backend_native_lock_layout_group;
}
static void

View File

@@ -72,16 +72,16 @@ set_crtc_cursor (MetaCursorRendererNative *native,
struct gbm_bo *bo;
union gbm_bo_handle handle;
int width, height;
int hot_x, hot_y;
int offset_x, offset_y;
bo = meta_cursor_reference_get_gbm_bo (cursor, &hot_x, &hot_y);
bo = meta_cursor_reference_get_gbm_bo (cursor, &offset_x, &offset_y);
handle = gbm_bo_get_handle (bo);
width = gbm_bo_get_width (bo);
height = gbm_bo_get_height (bo);
drmModeSetCursor2 (priv->drm_fd, crtc->crtc_id, handle.u32,
width, height, hot_x, hot_y);
width, height, -offset_x, -offset_y);
}
else
{

View File

@@ -41,8 +41,7 @@
#include "dbus-utils.h"
#include "meta-dbus-login1.h"
#include "wayland/meta-wayland-private.h"
#include "backends/meta-backend.h"
#include "backends/meta-backend-private.h"
#include "meta-cursor-renderer-native.h"
struct _MetaLauncher
@@ -101,15 +100,15 @@ session_unpause (void)
clutter_egl_thaw_master_clock ();
{
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
MetaBackend *backend = meta_get_backend ();
MetaCursorRenderer *renderer = meta_backend_get_cursor_renderer (backend);
ClutterActor *stage = meta_backend_get_stage (backend);
/* When we mode-switch back, we need to immediately queue a redraw
* in case nothing else queued one for us, and force the cursor to
* update. */
clutter_actor_queue_redraw (compositor->stage);
clutter_actor_queue_redraw (stage);
meta_cursor_renderer_native_force_update (META_CURSOR_RENDERER_NATIVE (renderer));
}
}

View File

@@ -40,8 +40,6 @@
#include <meta/errors.h>
#include "edid.h"
#define ALL_WL_TRANSFORMS ((1 << (WL_OUTPUT_TRANSFORM_FLIPPED_270 + 1)) - 1)
typedef struct {
drmModeConnector *connector;
@@ -259,7 +257,7 @@ find_output_by_id (MetaOutput *outputs,
unsigned i;
for (i = 0; i < n_outputs; i++)
if (outputs[i].output_id == id)
if (outputs[i].winsys_id == id)
return &outputs[i];
return NULL;
@@ -363,9 +361,9 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
meta_crtc->rect.width = crtc->width;
meta_crtc->rect.height = crtc->height;
meta_crtc->is_dirty = FALSE;
meta_crtc->transform = WL_OUTPUT_TRANSFORM_NORMAL;
meta_crtc->transform = META_MONITOR_TRANSFORM_NORMAL;
/* FIXME: implement! */
meta_crtc->all_transforms = 1 << WL_OUTPUT_TRANSFORM_NORMAL;
meta_crtc->all_transforms = 1 << META_MONITOR_TRANSFORM_NORMAL;
if (crtc->mode_valid)
{
@@ -408,7 +406,7 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
meta_output->driver_private = output_kms = g_slice_new0 (MetaOutputKms);
meta_output->driver_notify = (GDestroyNotify)meta_output_destroy_notify;
meta_output->output_id = connector->connector_id;
meta_output->winsys_id = connector->connector_id;
meta_output->name = make_output_name (connector);
meta_output->width_mm = connector->mmWidth;
meta_output->height_mm = connector->mmHeight;
@@ -491,7 +489,7 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
meta_output->crtc = NULL;
old_output = find_output_by_id (old_outputs, n_old_outputs,
meta_output->output_id);
meta_output->winsys_id);
if (old_output)
{
meta_output->is_primary = old_output->is_primary;
@@ -667,7 +665,7 @@ meta_monitor_manager_kms_set_power_save_mode (MetaMonitorManager *manager,
if (output_kms->dpms_prop_id != 0)
{
int ok = drmModeConnectorSetProperty(manager_kms->fd, meta_output->output_id,
int ok = drmModeConnectorSetProperty(manager_kms->fd, meta_output->winsys_id,
output_kms->dpms_prop_id, state);
if (ok < 0)
@@ -748,7 +746,7 @@ meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager,
{
MetaOutput *output = g_ptr_array_index (crtc_info->outputs, j);
connectors[j] = output->output_id;
connectors[j] = output->winsys_id;
output->is_dirty = TRUE;
output->crtc = crtc;

View File

@@ -24,11 +24,18 @@
#include "config.h"
#include <string.h>
#include <stdlib.h>
#include "meta-backend-x11.h"
#include <clutter/x11/clutter-x11.h>
#include <X11/extensions/sync.h>
#include <X11/XKBlib.h>
#include <X11/extensions/XKBrules.h>
#include <X11/Xlib-xcb.h>
#include <xkbcommon/xkbcommon-x11.h>
#include "meta-idle-monitor-xsync.h"
#include "meta-monitor-manager-xrandr.h"
@@ -43,6 +50,7 @@ struct _MetaBackendX11Private
{
/* The host X11 display */
Display *xdisplay;
xcb_connection_t *xcb;
GSource *source;
int xsync_event_base;
@@ -51,6 +59,12 @@ struct _MetaBackendX11Private
int xinput_opcode;
int xinput_event_base;
int xinput_error_base;
Time latest_evtime;
uint8_t xkb_event_base;
uint8_t xkb_error_base;
struct xkb_keymap *keymap;
};
typedef struct _MetaBackendX11Private MetaBackendX11Private;
@@ -71,6 +85,7 @@ static void
translate_device_event (MetaBackendX11 *x11,
XIDeviceEvent *device_event)
{
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
Window stage_window = meta_backend_x11_get_xwindow (x11);
if (device_event->event != stage_window)
@@ -88,6 +103,21 @@ translate_device_event (MetaBackendX11 *x11,
device_event->event_x = device_event->root_x;
device_event->event_y = device_event->root_y;
}
if (!device_event->send_event && device_event->time != CurrentTime)
{
if (device_event->time < priv->latest_evtime)
{
/* Emulated pointer events received after XIRejectTouch is received
* on a passive touch grab will contain older timestamps, update those
* so we dont get InvalidTime at grabs.
*/
device_event->time = priv->latest_evtime;
}
/* Update the internal latest evtime, for any possible later use */
priv->latest_evtime = device_event->time;
}
}
/* Clutter makes the assumption that there is only one X window
@@ -117,6 +147,9 @@ maybe_spoof_event_as_stage_event (MetaBackendX11 *x11,
case XI_ButtonRelease:
case XI_KeyPress:
case XI_KeyRelease:
case XI_TouchBegin:
case XI_TouchUpdate:
case XI_TouchEnd:
translate_device_event (x11, (XIDeviceEvent *) input_event);
break;
default:
@@ -125,6 +158,21 @@ maybe_spoof_event_as_stage_event (MetaBackendX11 *x11,
}
}
static void
keymap_changed (MetaBackend *backend)
{
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
if (priv->keymap)
{
xkb_keymap_unref (priv->keymap);
priv->keymap = NULL;
}
g_signal_emit_by_name (backend, "keymap-changed", 0);
}
static void
handle_host_xevent (MetaBackend *backend,
XEvent *event)
@@ -135,24 +183,49 @@ handle_host_xevent (MetaBackend *backend,
XGetEventData (priv->xdisplay, &event->xcookie);
{
MetaDisplay *display = meta_get_display ();
if (display)
{
MetaCompositor *compositor = display->compositor;
if (meta_plugin_manager_xevent_filter (compositor->plugin_mgr, event))
bypass_clutter = TRUE;
}
}
if (event->type == (priv->xsync_event_base + XSyncAlarmNotify))
handle_alarm_notify (backend, event);
if (event->type == priv->xkb_event_base)
{
XkbAnyEvent *xkb_ev = (XkbAnyEvent *) event;
if (xkb_ev->device == META_VIRTUAL_CORE_KEYBOARD_ID)
{
switch (xkb_ev->xkb_type)
{
case XkbNewKeyboardNotify:
case XkbMapNotify:
keymap_changed (backend);
default:
break;
}
}
}
{
MetaMonitorManager *manager = meta_backend_get_monitor_manager (backend);
if (META_IS_MONITOR_MANAGER_XRANDR (manager) &&
meta_monitor_manager_xrandr_handle_xevent (META_MONITOR_MANAGER_XRANDR (manager), event))
{
bypass_clutter = TRUE;
goto out;
}
bypass_clutter = TRUE;
}
maybe_spoof_event_as_stage_event (x11, event);
out:
if (!bypass_clutter)
clutter_x11_handle_event (event);
{
maybe_spoof_event_as_stage_event (x11, event);
clutter_x11_handle_event (event);
}
XFreeEventData (priv->xdisplay, &event->xcookie);
}
@@ -235,6 +308,24 @@ x_event_source_new (MetaBackend *backend)
return source;
}
static void
take_touch_grab (MetaBackend *backend)
{
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
XIEventMask mask = { META_VIRTUAL_CORE_POINTER_ID, sizeof (mask_bits), mask_bits };
XIGrabModifiers mods = { XIAnyModifier, 0 };
XISetMask (mask.mask, XI_TouchBegin);
XISetMask (mask.mask, XI_TouchUpdate);
XISetMask (mask.mask, XI_TouchEnd);
XIGrabTouchBegin (priv->xdisplay, META_VIRTUAL_CORE_POINTER_ID,
DefaultRootWindow (priv->xdisplay),
False, &mask, 1, &mods);
}
static void
meta_backend_x11_post_init (MetaBackend *backend)
{
@@ -272,6 +363,19 @@ meta_backend_x11_post_init (MetaBackend *backend)
meta_fatal ("X server doesn't have the XInput extension, version 2.2 or newer\n");
}
take_touch_grab (backend);
priv->xcb = XGetXCBConnection (priv->xdisplay);
if (!xkb_x11_setup_xkb_extension (priv->xcb,
XKB_X11_MIN_MAJOR_XKB_VERSION,
XKB_X11_MIN_MINOR_XKB_VERSION,
XKB_X11_SETUP_XKB_EXTENSION_NO_FLAGS,
NULL, NULL,
&priv->xkb_event_base,
&priv->xkb_error_base))
meta_fatal ("X server doesn't have the XKB extension, version %d.%d or newer\n",
XKB_X11_MIN_MAJOR_XKB_VERSION, XKB_X11_MIN_MINOR_XKB_VERSION);
META_BACKEND_CLASS (meta_backend_x11_parent_class)->post_init (backend);
}
@@ -313,6 +417,9 @@ meta_backend_x11_grab_device (MetaBackend *backend,
XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };
int ret;
if (timestamp != CurrentTime)
timestamp = MAX (timestamp, priv->latest_evtime);
XISetMask (mask.mask, XI_ButtonPress);
XISetMask (mask.mask, XI_ButtonRelease);
XISetMask (mask.mask, XI_Enter);
@@ -362,6 +469,198 @@ meta_backend_x11_warp_pointer (MetaBackend *backend,
x, y);
}
static void
get_xkbrf_var_defs (Display *xdisplay,
const char *layouts,
const char *variants,
const char *options,
char **rules_p,
XkbRF_VarDefsRec *var_defs)
{
char *rules = NULL;
/* Get it from the X property or fallback on defaults */
if (!XkbRF_GetNamesProp (xdisplay, &rules, var_defs) || !rules)
{
rules = strdup (DEFAULT_XKB_RULES_FILE);
var_defs->model = strdup (DEFAULT_XKB_MODEL);
var_defs->layout = NULL;
var_defs->variant = NULL;
var_defs->options = NULL;
}
/* Swap in our new options... */
free (var_defs->layout);
var_defs->layout = strdup (layouts);
free (var_defs->variant);
var_defs->variant = strdup (variants);
free (var_defs->options);
var_defs->options = strdup (options);
/* Sometimes, the property is a file path, and sometimes it's
not. Normalize it so it's always a file path. */
if (rules[0] == '/')
*rules_p = g_strdup (rules);
else
*rules_p = g_build_filename (XKB_BASE, "rules", rules, NULL);
free (rules);
}
static void
free_xkbrf_var_defs (XkbRF_VarDefsRec *var_defs)
{
free (var_defs->model);
free (var_defs->layout);
free (var_defs->variant);
free (var_defs->options);
}
static void
free_xkb_component_names (XkbComponentNamesRec *p)
{
free (p->keymap);
free (p->keycodes);
free (p->types);
free (p->compat);
free (p->symbols);
free (p->geometry);
}
static void
upload_xkb_description (Display *xdisplay,
const gchar *rules_file_path,
XkbRF_VarDefsRec *var_defs,
XkbComponentNamesRec *comp_names)
{
XkbDescRec *xkb_desc;
gchar *rules_file;
/* Upload it to the X server using the same method as setxkbmap */
xkb_desc = XkbGetKeyboardByName (xdisplay,
XkbUseCoreKbd,
comp_names,
XkbGBN_AllComponentsMask,
XkbGBN_AllComponentsMask &
(~XkbGBN_GeometryMask), True);
if (!xkb_desc)
{
g_warning ("Couldn't upload new XKB keyboard description");
return;
}
XkbFreeKeyboard (xkb_desc, 0, True);
rules_file = g_path_get_basename (rules_file_path);
if (!XkbRF_SetNamesProp (xdisplay, rules_file, var_defs))
g_warning ("Couldn't update the XKB root window property");
g_free (rules_file);
}
static void
meta_backend_x11_set_keymap (MetaBackend *backend,
const char *layouts,
const char *variants,
const char *options)
{
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
XkbRF_RulesRec *xkb_rules;
XkbRF_VarDefsRec xkb_var_defs = { 0 };
gchar *rules_file_path;
get_xkbrf_var_defs (priv->xdisplay,
layouts,
variants,
options,
&rules_file_path,
&xkb_var_defs);
xkb_rules = XkbRF_Load (rules_file_path, NULL, True, True);
if (xkb_rules)
{
XkbComponentNamesRec xkb_comp_names = { 0 };
XkbRF_GetComponents (xkb_rules, &xkb_var_defs, &xkb_comp_names);
upload_xkb_description (priv->xdisplay, rules_file_path, &xkb_var_defs, &xkb_comp_names);
free_xkb_component_names (&xkb_comp_names);
XkbRF_Free (xkb_rules, True);
}
else
{
g_warning ("Couldn't load XKB rules");
}
free_xkbrf_var_defs (&xkb_var_defs);
g_free (rules_file_path);
}
static struct xkb_keymap *
meta_backend_x11_get_keymap (MetaBackend *backend)
{
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
if (priv->keymap == NULL)
{
struct xkb_context *context = xkb_context_new (XKB_CONTEXT_NO_FLAGS);
priv->keymap = xkb_x11_keymap_new_from_device (context,
priv->xcb,
xkb_x11_get_core_keyboard_device_id (priv->xcb),
XKB_KEYMAP_COMPILE_NO_FLAGS);
xkb_context_unref (context);
}
return priv->keymap;
}
static void
meta_backend_x11_lock_layout_group (MetaBackend *backend,
guint idx)
{
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
XkbLockGroup (priv->xdisplay, XkbUseCoreKbd, idx);
}
static void
meta_backend_x11_update_screen_size (MetaBackend *backend,
int width, int height)
{
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
Window xwin = meta_backend_x11_get_xwindow (x11);
XResizeWindow (priv->xdisplay, xwin, width, height);
}
static void
meta_backend_x11_select_stage_events (MetaBackend *backend)
{
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
Window xwin = meta_backend_x11_get_xwindow (x11);
unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };
XISetMask (mask.mask, XI_KeyPress);
XISetMask (mask.mask, XI_KeyRelease);
XISetMask (mask.mask, XI_ButtonPress);
XISetMask (mask.mask, XI_ButtonRelease);
XISetMask (mask.mask, XI_Enter);
XISetMask (mask.mask, XI_Leave);
XISetMask (mask.mask, XI_FocusIn);
XISetMask (mask.mask, XI_FocusOut);
XISetMask (mask.mask, XI_Motion);
XIClearMask (mask.mask, XI_TouchBegin);
XIClearMask (mask.mask, XI_TouchEnd);
XIClearMask (mask.mask, XI_TouchUpdate);
XISelectEvents (priv->xdisplay, xwin, &mask, 1);
}
static void
meta_backend_x11_class_init (MetaBackendX11Class *klass)
{
@@ -371,10 +670,14 @@ meta_backend_x11_class_init (MetaBackendX11Class *klass)
backend_class->create_idle_monitor = meta_backend_x11_create_idle_monitor;
backend_class->create_monitor_manager = meta_backend_x11_create_monitor_manager;
backend_class->create_cursor_renderer = meta_backend_x11_create_cursor_renderer;
backend_class->grab_device = meta_backend_x11_grab_device;
backend_class->ungrab_device = meta_backend_x11_ungrab_device;
backend_class->warp_pointer = meta_backend_x11_warp_pointer;
backend_class->set_keymap = meta_backend_x11_set_keymap;
backend_class->get_keymap = meta_backend_x11_get_keymap;
backend_class->lock_layout_group = meta_backend_x11_lock_layout_group;
backend_class->update_screen_size = meta_backend_x11_update_screen_size;
backend_class->select_stage_events = meta_backend_x11_select_stage_events;
}
static void
@@ -395,12 +698,6 @@ meta_backend_x11_get_xdisplay (MetaBackendX11 *x11)
Window
meta_backend_x11_get_xwindow (MetaBackendX11 *x11)
{
MetaDisplay *display = meta_get_display ();
MetaCompositor *compositor = display->compositor;
if (compositor == NULL)
return None;
ClutterStage *stage = CLUTTER_STAGE (compositor->stage);
return clutter_x11_get_stage_window (stage);
ClutterActor *stage = meta_backend_get_stage (META_BACKEND (x11));
return clutter_x11_get_stage_window (CLUTTER_STAGE (stage));
}

View File

@@ -35,6 +35,8 @@
#include <X11/Xatom.h>
#include <X11/extensions/Xrandr.h>
#include <X11/extensions/dpms.h>
#include <X11/Xlib-xcb.h>
#include <xcb/randr.h>
#include "meta-backend-x11.h"
#include <meta/main.h>
@@ -42,7 +44,7 @@
#include "edid.h"
#include "meta-monitor-config.h"
#define ALL_WL_TRANSFORMS ((1 << (WL_OUTPUT_TRANSFORM_FLIPPED_270 + 1)) - 1)
#define ALL_TRANSFORMS ((1 << (META_MONITOR_TRANSFORM_FLIPPED_270 + 1)) - 1)
/* Look for DPI_FALLBACK in:
* http://git.gnome.org/browse/gnome-settings-daemon/tree/plugins/xsettings/gsd-xsettings-manager.c
@@ -67,31 +69,31 @@ struct _MetaMonitorManagerXrandrClass
G_DEFINE_TYPE (MetaMonitorManagerXrandr, meta_monitor_manager_xrandr, META_TYPE_MONITOR_MANAGER);
static enum wl_output_transform
wl_transform_from_xrandr (Rotation rotation)
static MetaMonitorTransform
meta_monitor_transform_from_xrandr (Rotation rotation)
{
static const enum wl_output_transform y_reflected_map[4] = {
WL_OUTPUT_TRANSFORM_FLIPPED_180,
WL_OUTPUT_TRANSFORM_FLIPPED_90,
WL_OUTPUT_TRANSFORM_FLIPPED,
WL_OUTPUT_TRANSFORM_FLIPPED_270
static const MetaMonitorTransform y_reflected_map[4] = {
META_MONITOR_TRANSFORM_FLIPPED_180,
META_MONITOR_TRANSFORM_FLIPPED_90,
META_MONITOR_TRANSFORM_FLIPPED,
META_MONITOR_TRANSFORM_FLIPPED_270
};
enum wl_output_transform ret;
MetaMonitorTransform ret;
switch (rotation & 0x7F)
{
default:
case RR_Rotate_0:
ret = WL_OUTPUT_TRANSFORM_NORMAL;
ret = META_MONITOR_TRANSFORM_NORMAL;
break;
case RR_Rotate_90:
ret = WL_OUTPUT_TRANSFORM_90;
ret = META_MONITOR_TRANSFORM_90;
break;
case RR_Rotate_180:
ret = WL_OUTPUT_TRANSFORM_180;
ret = META_MONITOR_TRANSFORM_180;
break;
case RR_Rotate_270:
ret = WL_OUTPUT_TRANSFORM_270;
ret = META_MONITOR_TRANSFORM_270;
break;
}
@@ -105,42 +107,42 @@ wl_transform_from_xrandr (Rotation rotation)
#define ALL_ROTATIONS (RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270)
static unsigned int
wl_transform_from_xrandr_all (Rotation rotation)
static MetaMonitorTransform
meta_monitor_transform_from_xrandr_all (Rotation rotation)
{
unsigned ret;
/* Handle the common cases first (none or all) */
if (rotation == 0 || rotation == RR_Rotate_0)
return (1 << WL_OUTPUT_TRANSFORM_NORMAL);
return (1 << META_MONITOR_TRANSFORM_NORMAL);
/* All rotations and one reflection -> all of them by composition */
if ((rotation & ALL_ROTATIONS) &&
((rotation & RR_Reflect_X) || (rotation & RR_Reflect_Y)))
return ALL_WL_TRANSFORMS;
return ALL_TRANSFORMS;
ret = 1 << WL_OUTPUT_TRANSFORM_NORMAL;
ret = 1 << META_MONITOR_TRANSFORM_NORMAL;
if (rotation & RR_Rotate_90)
ret |= 1 << WL_OUTPUT_TRANSFORM_90;
ret |= 1 << META_MONITOR_TRANSFORM_90;
if (rotation & RR_Rotate_180)
ret |= 1 << WL_OUTPUT_TRANSFORM_180;
ret |= 1 << META_MONITOR_TRANSFORM_180;
if (rotation & RR_Rotate_270)
ret |= 1 << WL_OUTPUT_TRANSFORM_270;
ret |= 1 << META_MONITOR_TRANSFORM_270;
if (rotation & (RR_Rotate_0 | RR_Reflect_X))
ret |= 1 << WL_OUTPUT_TRANSFORM_FLIPPED;
ret |= 1 << META_MONITOR_TRANSFORM_FLIPPED;
if (rotation & (RR_Rotate_90 | RR_Reflect_X))
ret |= 1 << WL_OUTPUT_TRANSFORM_FLIPPED_90;
ret |= 1 << META_MONITOR_TRANSFORM_FLIPPED_90;
if (rotation & (RR_Rotate_180 | RR_Reflect_X))
ret |= 1 << WL_OUTPUT_TRANSFORM_FLIPPED_180;
ret |= 1 << META_MONITOR_TRANSFORM_FLIPPED_180;
if (rotation & (RR_Rotate_270 | RR_Reflect_X))
ret |= 1 << WL_OUTPUT_TRANSFORM_FLIPPED_270;
ret |= 1 << META_MONITOR_TRANSFORM_FLIPPED_270;
return ret;
}
static gboolean
output_get_presentation_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
MetaOutput *output)
output_get_boolean_property (MetaMonitorManagerXrandr *manager_xrandr,
MetaOutput *output, const char *propname)
{
gboolean value;
Atom atom, actual_type;
@@ -148,9 +150,9 @@ output_get_presentation_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
unsigned long nitems, bytes_after;
unsigned char *buffer;
atom = XInternAtom (manager_xrandr->xdisplay, "_MUTTER_PRESENTATION_OUTPUT", False);
atom = XInternAtom (manager_xrandr->xdisplay, propname, False);
XRRGetOutputProperty (manager_xrandr->xdisplay,
(XID)output->output_id,
(XID)output->winsys_id,
atom,
0, G_MAXLONG, False, False, XA_CARDINAL,
&actual_type, &actual_format,
@@ -166,6 +168,13 @@ output_get_presentation_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
return value;
}
static gboolean
output_get_presentation_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
MetaOutput *output)
{
return output_get_boolean_property (manager_xrandr, output, "_MUTTER_PRESENTATION_OUTPUT");
}
static int
normalize_backlight (MetaOutput *output,
int hw_value)
@@ -186,7 +195,7 @@ output_get_backlight_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
atom = XInternAtom (manager_xrandr->xdisplay, "Backlight", False);
XRRGetOutputProperty (manager_xrandr->xdisplay,
(XID)output->output_id,
(XID)output->winsys_id,
atom,
0, G_MAXLONG, False, False, XA_INTEGER,
&actual_type, &actual_format,
@@ -207,30 +216,34 @@ output_get_backlight_limits_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
MetaOutput *output)
{
Atom atom;
XRRPropertyInfo *info;
xcb_connection_t *xcb_conn;
xcb_randr_query_output_property_reply_t *reply;
atom = XInternAtom (manager_xrandr->xdisplay, "Backlight", False);
info = XRRQueryOutputProperty (manager_xrandr->xdisplay,
(XID)output->output_id,
atom);
if (info == NULL)
{
meta_verbose ("could not get output property for %s\n", output->name);
return;
}
xcb_conn = XGetXCBConnection (manager_xrandr->xdisplay);
reply = xcb_randr_query_output_property_reply (xcb_conn,
xcb_randr_query_output_property (xcb_conn,
(xcb_randr_output_t) output->winsys_id,
(xcb_atom_t) atom),
NULL);
if (!info->range || info->num_values != 2)
/* This can happen on systems without backlights. */
if (reply == NULL)
return;
if (!reply->range || reply->length != 2)
{
meta_verbose ("backlight %s was not range\n", output->name);
goto out;
}
output->backlight_min = info->values[0];
output->backlight_max = info->values[1];
int32_t *values = xcb_randr_query_output_property_valid_values (reply);
output->backlight_min = values[0];
output->backlight_max = values[1];
out:
XFree (info);
free (reply);
}
static int
@@ -278,25 +291,25 @@ get_edid_property (Display *dpy,
static GBytes *
read_output_edid (MetaMonitorManagerXrandr *manager_xrandr,
XID output_id)
XID winsys_id)
{
Atom edid_atom;
guint8 *result;
gsize len;
edid_atom = XInternAtom (manager_xrandr->xdisplay, "EDID", FALSE);
result = get_edid_property (manager_xrandr->xdisplay, output_id, edid_atom, &len);
result = get_edid_property (manager_xrandr->xdisplay, winsys_id, edid_atom, &len);
if (!result)
{
edid_atom = XInternAtom (manager_xrandr->xdisplay, "EDID_DATA", FALSE);
result = get_edid_property (manager_xrandr->xdisplay, output_id, edid_atom, &len);
result = get_edid_property (manager_xrandr->xdisplay, winsys_id, edid_atom, &len);
}
if (!result)
{
edid_atom = XInternAtom (manager_xrandr->xdisplay, "XFree86_DDC_EDID1_RAWDATA", FALSE);
result = get_edid_property (manager_xrandr->xdisplay, output_id, edid_atom, &len);
result = get_edid_property (manager_xrandr->xdisplay, winsys_id, edid_atom, &len);
}
if (result)
@@ -312,25 +325,25 @@ read_output_edid (MetaMonitorManagerXrandr *manager_xrandr,
static gboolean
output_get_hotplug_mode_update (MetaMonitorManagerXrandr *manager_xrandr,
XID output_id)
MetaOutput *output)
{
Atom atom;
XRRPropertyInfo *info;
gboolean result = FALSE;
atom = XInternAtom (manager_xrandr->xdisplay, "hotplug_mode_update", False);
info = XRRQueryOutputProperty (manager_xrandr->xdisplay, output_id,
atom);
if (info)
{
result = TRUE;
XFree (info);
}
return result;
return output_get_boolean_property (manager_xrandr, output, "hotplug_mode_update");
}
static char *
get_xmode_name (XRRModeInfo *xmode)
{
int width = xmode->width;
int height = xmode->height;
if (xmode->hSkew != 0)
{
width += 2 * (xmode->hSkew >> 8);
height += 2 * (xmode->hSkew & 0xff);
}
return g_strdup_printf ("%dx%d", width, height);
}
static void
meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
@@ -417,6 +430,7 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
mode->height = xmode->height;
mode->refresh_rate = (xmode->dotClock /
((float)xmode->hTotal * xmode->vTotal));
mode->name = get_xmode_name (xmode);
}
for (i = 0; i < (unsigned)resources->ncrtc; i++)
@@ -434,8 +448,8 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
meta_crtc->rect.width = crtc->width;
meta_crtc->rect.height = crtc->height;
meta_crtc->is_dirty = FALSE;
meta_crtc->transform = wl_transform_from_xrandr (crtc->rotation);
meta_crtc->all_transforms = wl_transform_from_xrandr_all (crtc->rotations);
meta_crtc->transform = meta_monitor_transform_from_xrandr (crtc->rotation);
meta_crtc->all_transforms = meta_monitor_transform_from_xrandr_all (crtc->rotations);
for (j = 0; j < (unsigned)resources->nmode; j++)
{
@@ -467,10 +481,10 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
GBytes *edid;
MonitorInfo *parsed_edid;
meta_output->output_id = resources->outputs[i];
meta_output->winsys_id = resources->outputs[i];
meta_output->name = g_strdup (output->name);
edid = read_output_edid (manager_xrandr, meta_output->output_id);
edid = read_output_edid (manager_xrandr, meta_output->winsys_id);
if (edid)
{
gsize len;
@@ -503,8 +517,7 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
meta_output->width_mm = output->mm_width;
meta_output->height_mm = output->mm_height;
meta_output->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN;
meta_output->hotplug_mode_update =
output_get_hotplug_mode_update (manager_xrandr, meta_output->output_id);
meta_output->hotplug_mode_update = output_get_hotplug_mode_update (manager_xrandr, meta_output);
meta_output->n_modes = output->nmode;
meta_output->modes = g_new0 (MetaMonitorMode *, meta_output->n_modes);
@@ -556,7 +569,7 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
meta_output->possible_clones[j] = GINT_TO_POINTER (output->clones[j]);
}
meta_output->is_primary = ((XID)meta_output->output_id == primary_output);
meta_output->is_primary = ((XID)meta_output->winsys_id == primary_output);
meta_output->is_presentation = output_get_presentation_xrandr (manager_xrandr, meta_output);
output_get_backlight_limits_xrandr (manager_xrandr, meta_output);
@@ -589,7 +602,7 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
for (k = 0; k < manager->n_outputs; k++)
{
if (clone == (XID)manager->outputs[k].output_id)
if (clone == (XID)manager->outputs[k].winsys_id)
{
meta_output->possible_clones[j] = &manager->outputs[k];
break;
@@ -605,7 +618,7 @@ meta_monitor_manager_xrandr_read_edid (MetaMonitorManager *manager,
{
MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (manager);
return read_output_edid (manager_xrandr, output->output_id);
return read_output_edid (manager_xrandr, output->winsys_id);
}
static void
@@ -637,25 +650,25 @@ meta_monitor_manager_xrandr_set_power_save_mode (MetaMonitorManager *manager,
}
static Rotation
wl_transform_to_xrandr (enum wl_output_transform transform)
meta_monitor_transform_to_xrandr (MetaMonitorTransform transform)
{
switch (transform)
{
case WL_OUTPUT_TRANSFORM_NORMAL:
case META_MONITOR_TRANSFORM_NORMAL:
return RR_Rotate_0;
case WL_OUTPUT_TRANSFORM_90:
case META_MONITOR_TRANSFORM_90:
return RR_Rotate_90;
case WL_OUTPUT_TRANSFORM_180:
case META_MONITOR_TRANSFORM_180:
return RR_Rotate_180;
case WL_OUTPUT_TRANSFORM_270:
case META_MONITOR_TRANSFORM_270:
return RR_Rotate_270;
case WL_OUTPUT_TRANSFORM_FLIPPED:
case META_MONITOR_TRANSFORM_FLIPPED:
return RR_Reflect_X | RR_Rotate_0;
case WL_OUTPUT_TRANSFORM_FLIPPED_90:
case META_MONITOR_TRANSFORM_FLIPPED_90:
return RR_Reflect_X | RR_Rotate_90;
case WL_OUTPUT_TRANSFORM_FLIPPED_180:
case META_MONITOR_TRANSFORM_FLIPPED_180:
return RR_Reflect_X | RR_Rotate_180;
case WL_OUTPUT_TRANSFORM_FLIPPED_270:
case META_MONITOR_TRANSFORM_FLIPPED_270:
return RR_Reflect_X | RR_Rotate_270;
}
@@ -672,7 +685,7 @@ output_set_presentation_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
atom = XInternAtom (manager_xrandr->xdisplay, "_MUTTER_PRESENTATION_OUTPUT", False);
XRRChangeOutputProperty (manager_xrandr->xdisplay,
(XID)output->output_id,
(XID)output->winsys_id,
atom,
XA_CARDINAL, 32, PropModeReplace,
(unsigned char*) &value, 1);
@@ -828,7 +841,7 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
output->crtc = crtc;
new_controlled_mask |= 1UL << j;
outputs[j] = output->output_id;
outputs[j] = output->winsys_id;
}
if (crtc->current_mode == mode &&
@@ -847,7 +860,7 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
manager_xrandr->time,
crtc_info->x, crtc_info->y,
(XID)mode->mode_id,
wl_transform_to_xrandr (crtc_info->transform),
meta_monitor_transform_to_xrandr (crtc_info->transform),
outputs, n_outputs);
if (ok != Success)
@@ -891,7 +904,7 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
{
XRRSetOutputPrimary (manager_xrandr->xdisplay,
DefaultRootWindow (manager_xrandr->xdisplay),
(XID)output_info->output->output_id);
(XID)output_info->output->winsys_id);
}
output_set_presentation_xrandr (manager_xrandr,
@@ -934,7 +947,7 @@ meta_monitor_manager_xrandr_change_backlight (MetaMonitorManager *manager,
atom = XInternAtom (manager_xrandr->xdisplay, "Backlight", False);
XRRChangeOutputProperty (manager_xrandr->xdisplay,
(XID)output->output_id,
(XID)output->winsys_id,
atom,
XA_INTEGER, 32, PropModeReplace,
(unsigned char *) &hw_value, 1);

View File

@@ -22,48 +22,6 @@
#include <clutter/clutter.h>
#include "cogl-utils.h"
/**
* meta_create_color_texture_4ub:
* @red: red component
* @green: green component
* @blue: blue component
* @alpha: alpha component
* @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.
*
* Return value: (transfer full): a newly created Cogl texture
*/
CoglTexture *
meta_create_color_texture_4ub (guint8 red,
guint8 green,
guint8 blue,
guint8 alpha,
CoglTextureFlags flags)
{
CoglColor color;
guint8 pixel[4];
cogl_color_init_from_4ub (&color, red, green, blue, alpha);
cogl_color_premultiply (&color);
pixel[0] = cogl_color_get_red_byte (&color);
pixel[1] = cogl_color_get_green_byte (&color);
pixel[2] = cogl_color_get_blue_byte (&color);
pixel[3] = cogl_color_get_alpha_byte (&color);
return cogl_texture_new_from_data (1, 1,
flags,
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
COGL_PIXEL_FORMAT_ANY,
4, pixel);
}
/* Based on gnome-shell/src/st/st-private.c:_st_create_texture_material.c */
/**

View File

@@ -23,11 +23,6 @@
#include <cogl/cogl.h>
CoglTexture * meta_create_color_texture_4ub (guint8 red,
guint8 green,
guint8 blue,
guint8 alpha,
CoglTextureFlags flags);
CoglPipeline * meta_create_texture_pipeline (CoglTexture *texture);
#endif /* __META_COGL_UTILS_H__ */

View File

@@ -15,8 +15,7 @@ struct _MetaCompositor
{
MetaDisplay *display;
guint pre_paint_func_id;
guint post_paint_func_id;
guint repaint_func_id;
gint64 server_time_query_time;
gint64 server_time_offset;
@@ -41,7 +40,6 @@ struct _MetaCompositor
MetaPluginManager *plugin_mgr;
gboolean frame_has_updated_xsurfaces;
gboolean have_x11_sync_object;
};
/* Wait 2ms after vblank before starting to draw next frame */

View File

@@ -67,41 +67,29 @@
#include <meta/compositor-mutter.h>
#include <meta/prefs.h>
#include <meta/main.h>
#include <meta/meta-backend.h>
#include <meta/meta-background-actor.h>
#include <meta/meta-background-group.h>
#include <meta/meta-shadow-factory.h>
#include "meta-window-actor-private.h"
#include "meta-window-group.h"
#include "meta-stage.h"
#include "window-private.h" /* to check window->hidden */
#include "display-private.h" /* for meta_display_lookup_x_window() */
#include "display-private.h" /* for meta_display_lookup_x_window() and meta_display_cancel_touch() */
#include "util-private.h"
#include "frame.h"
#include <X11/extensions/shape.h>
#include <X11/extensions/Xcomposite.h>
#include "meta-sync-ring.h"
#include "backends/meta-backend.h"
#include "backends/x11/meta-backend-x11.h"
#ifdef HAVE_WAYLAND
#include "wayland/meta-wayland-private.h"
#endif
static gboolean
is_modal (MetaDisplay *display)
{
return display->grab_op == META_GRAB_OP_COMPOSITOR;
}
static inline gboolean
composite_at_least_version (MetaDisplay *display, int maj, int min)
{
static int major = -1;
static int minor = -1;
if (major == -1)
meta_display_get_compositor_version (display, &major, &minor);
return (major > maj || (major == maj && minor >= min));
return display->event_route == META_EVENT_ROUTE_COMPOSITOR_GRAB;
}
static void sync_actor_stacking (MetaCompositor *compositor);
@@ -137,11 +125,7 @@ meta_switch_workspace_completed (MetaCompositor *compositor)
void
meta_compositor_destroy (MetaCompositor *compositor)
{
clutter_threads_remove_repaint_func (compositor->pre_paint_func_id);
clutter_threads_remove_repaint_func (compositor->post_paint_func_id);
if (compositor->have_x11_sync_object)
meta_sync_ring_destroy ();
clutter_threads_remove_repaint_func (compositor->repaint_func_id);
}
static void
@@ -155,33 +139,6 @@ process_damage (MetaCompositor *compositor,
compositor->frame_has_updated_xsurfaces = TRUE;
}
static Window
get_output_window (MetaCompositor *compositor)
{
MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ());
Display *xdisplay = meta_backend_x11_get_xdisplay (backend);
Window output;
unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };
output = XCompositeGetOverlayWindow (xdisplay, DefaultRootWindow (xdisplay));
meta_core_add_old_event_mask (xdisplay, output, &mask);
XISetMask (mask.mask, XI_KeyPress);
XISetMask (mask.mask, XI_KeyRelease);
XISetMask (mask.mask, XI_ButtonPress);
XISetMask (mask.mask, XI_ButtonRelease);
XISetMask (mask.mask, XI_Enter);
XISetMask (mask.mask, XI_Leave);
XISetMask (mask.mask, XI_FocusIn);
XISetMask (mask.mask, XI_FocusOut);
XISetMask (mask.mask, XI_Motion);
XISelectEvents (xdisplay, output, &mask, 1);
return output;
}
/* compat helper */
static MetaCompositor *
get_compositor_for_screen (MetaScreen *screen)
@@ -388,12 +345,20 @@ meta_begin_modal_for_plugin (MetaCompositor *compositor,
return FALSE;
display->grab_op = META_GRAB_OP_COMPOSITOR;
display->event_route = META_EVENT_ROUTE_COMPOSITOR_GRAB;
display->grab_window = NULL;
display->grab_have_pointer = TRUE;
display->grab_have_keyboard = TRUE;
g_signal_emit_by_name (display, "grab-op-begin",
meta_plugin_get_screen (plugin),
display->grab_window, display->grab_op);
if (meta_is_wayland_compositor ())
meta_display_sync_wayland_input_focus (display);
{
meta_display_sync_wayland_input_focus (display);
meta_display_cancel_touch (display);
}
return TRUE;
}
@@ -408,7 +373,12 @@ meta_end_modal_for_plugin (MetaCompositor *compositor,
g_return_if_fail (is_modal (display));
g_signal_emit_by_name (display, "grab-op-end",
meta_plugin_get_screen (plugin),
display->grab_window, display->grab_op);
display->grab_op = META_GRAB_OP_NONE;
display->event_route = META_EVENT_ROUTE_NORMAL;
display->grab_window = NULL;
display->grab_have_pointer = FALSE;
display->grab_have_keyboard = FALSE;
@@ -430,8 +400,10 @@ after_stage_paint (ClutterStage *stage,
for (l = compositor->windows; l; l = l->next)
meta_window_actor_post_paint (l->data);
#ifdef HAVE_WAYLAND
if (meta_is_wayland_compositor ())
meta_wayland_compositor_paint_finished (meta_wayland_compositor_get_default ());
#endif
}
static void
@@ -483,62 +455,24 @@ meta_compositor_manage (MetaCompositor *compositor)
MetaDisplay *display = compositor->display;
Display *xdisplay = display->xdisplay;
MetaScreen *screen = display->screen;
Window xwin = 0;
gint width, height;
meta_screen_set_cm_selection (display->screen);
if (meta_is_wayland_compositor ())
{
MetaWaylandCompositor *wayland_compositor = meta_wayland_compositor_get_default ();
{
MetaBackend *backend = meta_get_backend ();
compositor->stage = meta_backend_get_stage (backend);
}
compositor->stage = meta_stage_new ();
clutter_actor_show (compositor->stage);
wayland_compositor->stage = compositor->stage;
meta_screen_get_size (screen, &width, &height);
clutter_actor_set_size (compositor->stage, width, height);
}
else
{
compositor->stage = clutter_stage_new ();
meta_screen_get_size (screen, &width, &height);
clutter_actor_realize (compositor->stage);
xwin = clutter_x11_get_stage_window (CLUTTER_STAGE (compositor->stage));
XResizeWindow (xdisplay, xwin, width, height);
{
MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ());
Display *backend_xdisplay = meta_backend_x11_get_xdisplay (backend);
unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };
meta_core_add_old_event_mask (backend_xdisplay, xwin, &mask);
XISetMask (mask.mask, XI_KeyPress);
XISetMask (mask.mask, XI_KeyRelease);
XISetMask (mask.mask, XI_ButtonPress);
XISetMask (mask.mask, XI_ButtonRelease);
XISetMask (mask.mask, XI_Enter);
XISetMask (mask.mask, XI_Leave);
XISetMask (mask.mask, XI_FocusIn);
XISetMask (mask.mask, XI_FocusOut);
XISetMask (mask.mask, XI_Motion);
XIClearMask (mask.mask, XI_TouchBegin);
XIClearMask (mask.mask, XI_TouchEnd);
XIClearMask (mask.mask, XI_TouchUpdate);
XISelectEvents (backend_xdisplay, xwin, &mask, 1);
}
}
clutter_stage_set_paint_callback (CLUTTER_STAGE (compositor->stage),
after_stage_paint,
compositor,
NULL);
/* We use connect_after() here to accomodate code in GNOME Shell that,
* when benchmarking drawing performance, connects to ::after-paint
* and calls glFinish(). The timing information from that will be
* more accurate if we hold off until that completes before we signal
* apps to begin drawing the next frame. If there are no other
* connections to ::after-paint, connect() vs. connect_after() doesn't
* matter.
*/
g_signal_connect_after (CLUTTER_STAGE (compositor->stage), "after-paint",
G_CALLBACK (after_stage_paint), compositor);
clutter_stage_set_sync_delay (CLUTTER_STAGE (compositor->stage), META_SYNC_DELAY);
@@ -557,7 +491,12 @@ meta_compositor_manage (MetaCompositor *compositor)
}
else
{
compositor->output = get_output_window (compositor);
Window xwin;
compositor->output = screen->composite_overlay_window;
xwin = meta_backend_x11_get_xwindow (META_BACKEND_X11 (meta_get_backend ()));
XReparentWindow (xdisplay, xwin, compositor->output, 0, 0);
meta_empty_stage_input_region (screen);
@@ -576,8 +515,6 @@ meta_compositor_manage (MetaCompositor *compositor)
* contents until we show the stage.
*/
XMapWindow (xdisplay, compositor->output);
compositor->have_x11_sync_object = meta_sync_ring_init (display);
}
redirect_windows (display->screen);
@@ -700,12 +637,11 @@ meta_compositor_remove_window (MetaCompositor *compositor,
}
void
meta_compositor_set_updates_frozen (MetaCompositor *compositor,
MetaWindow *window,
gboolean updates_frozen)
meta_compositor_sync_updates_frozen (MetaCompositor *compositor,
MetaWindow *window)
{
MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
meta_window_actor_set_updates_frozen (window_actor, updates_frozen);
meta_window_actor_sync_updates_frozen (window_actor);
}
void
@@ -765,9 +701,6 @@ meta_compositor_process_event (MetaCompositor *compositor,
XEvent *event,
MetaWindow *window)
{
if (meta_plugin_manager_xevent_filter (compositor->plugin_mgr, event))
return TRUE;
if (!meta_is_wayland_compositor () &&
event->type == meta_display_get_damage_event_base (compositor->display) + XDamageNotify)
{
@@ -789,10 +722,6 @@ meta_compositor_process_event (MetaCompositor *compositor,
if (!meta_is_wayland_compositor () && event->type == MapNotify)
clutter_x11_handle_event (event);
if (compositor->have_x11_sync_object &&
event->type == (compositor->display->xsync_event_base + XSyncAlarmNotify))
meta_sync_ring_handle_event ((XSyncAlarmNotifyEvent *) event);
/* The above handling is basically just "observing" the events, so we return
* FALSE to indicate that the event should not be filtered out; if we have
* GTK+ windows in the same process, GTK+ needs the ConfigureNotify event, for example.
@@ -1059,43 +988,6 @@ meta_compositor_sync_window_geometry (MetaCompositor *compositor,
meta_window_actor_sync_actor_geometry (window_actor, did_placement);
}
void
meta_compositor_sync_screen_size (MetaCompositor *compositor,
guint width,
guint height)
{
MetaDisplay *display = compositor->display;
if (meta_is_wayland_compositor ())
{
/* FIXME: when we support a sliced stage, this is the place to do it
But! This is not the place to apply KMS config, here we only
notify Clutter/Cogl/GL that the framebuffer sizes changed.
And because for now clutter does not do sliced, we use one
framebuffer the size of the whole screen, and when running on
bare metal MetaMonitorManager will do the necessary tricks to
show the right portions on the right screens.
*/
clutter_actor_set_size (compositor->stage, width, height);
}
else
{
Display *xdisplay;
Window xwin;
xdisplay = meta_display_get_xdisplay (display);
xwin = clutter_x11_get_stage_window (CLUTTER_STAGE (compositor->stage));
XResizeWindow (xdisplay, xwin, width, height);
}
meta_verbose ("Changed size for stage on screen %d to %dx%d\n",
meta_screen_get_screen_number (display->screen),
width, height);
}
static void
frame_callback (CoglOnscreen *onscreen,
CoglFrameEvent event,
@@ -1138,12 +1030,11 @@ frame_callback (CoglOnscreen *onscreen,
}
}
static gboolean
meta_pre_paint_func (gpointer data)
static void
pre_paint_windows (MetaCompositor *compositor)
{
GList *l;
MetaWindowActor *top_window;
MetaCompositor *compositor = data;
if (compositor->onscreen == NULL)
{
@@ -1155,7 +1046,7 @@ meta_pre_paint_func (gpointer data)
}
if (compositor->windows == NULL)
return TRUE;
return;
top_window = g_list_last (compositor->windows)->data;
@@ -1172,12 +1063,10 @@ meta_pre_paint_func (gpointer data)
{
/* We need to make sure that any X drawing that happens before
* the XDamageSubtract() for each window above is visible to
* subsequent GL rendering; the standardized way to do this is
* GL_EXT_X11_sync_object. Since this isn't implemented yet in
* mesa, we also have a path that relies on the implementation
* of the open source drivers.
*
* Anything else, we just hope for the best.
* subsequent GL rendering; the only standardized way to do this
* is EXT_x11_sync_object, which isn't yet widely available. For
* now, we count on details of Xorg and the open source drivers,
* and hope for the best otherwise.
*
* Xorg and open source driver specifics:
*
@@ -1192,28 +1081,17 @@ meta_pre_paint_func (gpointer data)
* round trip request at this point is sufficient to flush the
* GLX buffers.
*/
if (compositor->have_x11_sync_object)
compositor->have_x11_sync_object = meta_sync_ring_insert_wait ();
else
XSync (compositor->display->xdisplay, False);
}
return TRUE;
}
static gboolean
meta_post_paint_func (gpointer data)
{
MetaCompositor *compositor = data;
if (compositor->frame_has_updated_xsurfaces)
{
if (compositor->have_x11_sync_object)
compositor->have_x11_sync_object = meta_sync_ring_after_frame ();
XSync (compositor->display->xdisplay, False);
compositor->frame_has_updated_xsurfaces = FALSE;
}
}
static gboolean
meta_repaint_func (gpointer data)
{
MetaCompositor *compositor = data;
pre_paint_windows (compositor);
return TRUE;
}
@@ -1237,11 +1115,7 @@ meta_compositor_new (MetaDisplay *display)
{
MetaCompositor *compositor;
if (!composite_at_least_version (display, 0, 3))
return NULL;
compositor = g_new0 (MetaCompositor, 1);
compositor->display = display;
if (g_getenv("META_DISABLE_MIPMAPS"))
@@ -1252,16 +1126,10 @@ meta_compositor_new (MetaDisplay *display)
G_CALLBACK (on_shadow_factory_changed),
compositor);
compositor->pre_paint_func_id =
clutter_threads_add_repaint_func_full (CLUTTER_REPAINT_FLAGS_PRE_PAINT,
meta_pre_paint_func,
compositor,
NULL);
compositor->post_paint_func_id =
clutter_threads_add_repaint_func_full (CLUTTER_REPAINT_FLAGS_POST_PAINT,
meta_post_paint_func,
compositor,
NULL);
compositor->repaint_func_id = clutter_threads_add_repaint_func (meta_repaint_func,
compositor,
NULL);
return compositor;
}
@@ -1426,3 +1294,12 @@ meta_compositor_show_window_menu (MetaCompositor *compositor,
{
meta_plugin_manager_show_window_menu (compositor->plugin_mgr, window, menu, x, y);
}
void
meta_compositor_show_window_menu_for_rect (MetaCompositor *compositor,
MetaWindow *window,
MetaWindowMenuType menu,
MetaRectangle *rect)
{
meta_plugin_manager_show_window_menu_for_rect (compositor->plugin_mgr, window, menu, rect);
}

View File

@@ -185,7 +185,7 @@ cullable_iface_init (MetaCullableInterface *iface)
* meta_background_actor_get_clip_region:
* @self: a #MetaBackgroundActor
*
* Return value (transfer full): a #cairo_region_t that represents the part of
* Return value (transfer none): a #cairo_region_t that represents the part of
* the background not obscured by other #MetaBackgroundActor or
* #MetaWindowActor objects.
*/
@@ -193,24 +193,5 @@ cairo_region_t *
meta_background_actor_get_clip_region (MetaBackgroundActor *self)
{
MetaBackgroundActorPrivate *priv = self->priv;
ClutterActorBox content_box;
cairo_rectangle_int_t content_area = { 0 };
cairo_region_t *clip_region;
g_return_val_if_fail (META_IS_BACKGROUND_ACTOR (self), NULL);
if (!priv->clip_region)
return NULL;
clutter_actor_get_content_box (CLUTTER_ACTOR (self), &content_box);
content_area.x = content_box.x1;
content_area.y = content_box.y1;
content_area.width = content_box.x2 - content_box.x1;
content_area.height = content_box.y2 - content_box.y1;
clip_region = cairo_region_create_rectangle (&content_area);
cairo_region_intersect (clip_region, priv->clip_region);
return clip_region;
return priv->clip_region;
}

View File

@@ -288,6 +288,26 @@ get_wrap_mode (MetaBackground *self)
}
}
static gboolean
texture_has_alpha (CoglTexture *texture)
{
if (!texture)
return FALSE;
switch (cogl_texture_get_components (texture))
{
case COGL_TEXTURE_COMPONENTS_A:
case COGL_TEXTURE_COMPONENTS_RGBA:
return TRUE;
case COGL_TEXTURE_COMPONENTS_RG:
case COGL_TEXTURE_COMPONENTS_RGB:
case COGL_TEXTURE_COMPONENTS_DEPTH:
return FALSE;
default:
g_assert_not_reached ();
}
}
static ClutterPaintNode *
meta_background_paint_node_new (MetaBackground *self,
ClutterActor *actor)
@@ -296,6 +316,7 @@ meta_background_paint_node_new (MetaBackground *self,
ClutterPaintNode *node;
guint8 opacity;
guint8 color_component;
gboolean needs_blending;
opacity = clutter_actor_get_paint_opacity (actor);
color_component = (guint8) (0.5 + opacity * priv->brightness);
@@ -308,6 +329,13 @@ meta_background_paint_node_new (MetaBackground *self,
node = clutter_pipeline_node_new (priv->pipeline);
needs_blending = (opacity < 255) || (texture_has_alpha (priv->texture));
if (needs_blending)
cogl_pipeline_set_blend (priv->pipeline, "RGBA = ADD (SRC_COLOR, DST_COLOR*(1-SRC_COLOR[A]))", NULL);
else
cogl_pipeline_set_blend (priv->pipeline, "RGBA = ADD (SRC_COLOR, 0)", NULL);
return node;
}
@@ -382,8 +410,6 @@ meta_background_paint_content (ClutterContent *content,
if (priv->texture == NULL)
return;
node = meta_background_paint_node_new (self, actor);
clutter_actor_get_content_box (actor, &actor_box);
/* First figure out where on the monitor the texture is supposed to be painted.
@@ -413,12 +439,14 @@ meta_background_paint_content (ClutterContent *content,
clip_region = meta_background_actor_get_clip_region (META_BACKGROUND_ACTOR (actor));
if (clip_region != NULL)
{
cairo_region_intersect (paintable_region, clip_region);
cairo_region_destroy (clip_region);
}
cairo_region_intersect (paintable_region, clip_region);
}
if (cairo_region_is_empty (paintable_region))
goto out;
node = meta_background_paint_node_new (self, actor);
/* Finally, split the paintable region up into distinct areas
* and paint each area one by one
*/
@@ -441,10 +469,11 @@ meta_background_paint_content (ClutterContent *content,
clutter_paint_node_add_texture_rectangle (node, &texture_rectangle, tx1, ty1, tx2, ty2);
}
cairo_region_destroy (paintable_region);
clutter_paint_node_add_child (root, node);
clutter_paint_node_unref (node);
out:
cairo_region_destroy (paintable_region);
}
static void
@@ -498,7 +527,8 @@ set_brightness (MetaBackground *self,
priv->brightness = brightness;
if (priv->effects & META_BACKGROUND_EFFECTS_VIGNETTE)
if (clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL) &&
priv->effects & META_BACKGROUND_EFFECTS_VIGNETTE)
{
ensure_pipeline (self);
cogl_pipeline_set_uniform_1f (priv->pipeline,
@@ -506,6 +536,14 @@ set_brightness (MetaBackground *self,
"brightness"),
priv->brightness);
}
else
{
ensure_pipeline (self);
CoglColor blend_color;
cogl_color_init_from_4f (&blend_color, brightness, brightness, brightness, 1.0);
cogl_pipeline_set_layer_combine (priv->pipeline, 1, "RGB=MODULATE(PREVIOUS, CONSTANT) A=REPLACE(PREVIOUS)", NULL);
cogl_pipeline_set_layer_combine_constant (priv->pipeline, 1, &blend_color);
}
clutter_content_invalidate (CLUTTER_CONTENT (self));
@@ -523,6 +561,9 @@ set_vignette_sharpness (MetaBackground *self,
priv->vignette_sharpness = sharpness;
if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
return;
if (priv->effects & META_BACKGROUND_EFFECTS_VIGNETTE)
{
ensure_pipeline (self);
@@ -543,6 +584,9 @@ add_vignette (MetaBackground *self)
MetaBackgroundPrivate *priv = self->priv;
static CoglSnippet *snippet = NULL;
if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
return;
ensure_pipeline (self);
/* Cogl automatically caches pipelines with no eviction policy,
@@ -770,6 +814,8 @@ meta_background_load_gradient (MetaBackground *self,
ClutterColor *color,
ClutterColor *second_color)
{
ClutterBackend *backend = clutter_get_default_backend ();
CoglContext *ctx = clutter_backend_get_cogl_context (backend);
MetaBackgroundPrivate *priv = self->priv;
CoglTexture *texture;
guint width, height;
@@ -799,18 +845,17 @@ meta_background_load_gradient (MetaBackground *self,
pixels[0] = color->red;
pixels[1] = color->green;
pixels[2] = color->blue;
pixels[3] = color->alpha;
pixels[3] = 0xFF;
pixels[4] = second_color->red;
pixels[5] = second_color->green;
pixels[6] = second_color->blue;
pixels[7] = second_color->alpha;
pixels[7] = 0xFF;
texture = cogl_texture_new_from_data (width, height,
COGL_TEXTURE_NO_SLICING,
COGL_PIXEL_FORMAT_RGBA_8888,
COGL_PIXEL_FORMAT_ANY,
4,
pixels);
texture = COGL_TEXTURE (cogl_texture_2d_new_from_data (ctx, width, height,
COGL_PIXEL_FORMAT_RGB_888,
4,
pixels,
NULL));
set_texture (self, COGL_TEXTURE (texture));
}
@@ -828,10 +873,13 @@ void
meta_background_load_color (MetaBackground *self,
ClutterColor *color)
{
ClutterBackend *backend = clutter_get_default_backend ();
CoglContext *ctx = clutter_backend_get_cogl_context (backend);
MetaBackgroundPrivate *priv = self->priv;
CoglTexture *texture;
ClutterActor *stage = meta_get_stage_for_screen (priv->screen);
ClutterColor stage_color;
uint8_t pixels[4];
ensure_pipeline (self);
@@ -844,11 +892,16 @@ meta_background_load_color (MetaBackground *self,
color = &stage_color;
}
texture = meta_create_color_texture_4ub (color->red,
color->green,
color->blue,
0xff,
COGL_TEXTURE_NO_SLICING);
pixels[0] = color->red;
pixels[1] = color->green;
pixels[2] = color->blue;
pixels[3] = 0xFF;
texture = COGL_TEXTURE (cogl_texture_2d_new_from_data (ctx, 1, 1,
COGL_PIXEL_FORMAT_RGB_888,
4,
pixels,
NULL));
set_texture (self, COGL_TEXTURE (texture));
}
@@ -946,6 +999,8 @@ meta_background_load_file_finish (MetaBackground *self,
GAsyncResult *result,
GError **error)
{
ClutterBackend *backend = clutter_get_default_backend ();
CoglContext *ctx = clutter_backend_get_cogl_context (backend);
GTask *task;
LoadFileTaskData *task_data;
CoglTexture *texture;
@@ -954,6 +1009,7 @@ meta_background_load_file_finish (MetaBackground *self,
guchar *pixels;
gboolean has_alpha;
gboolean loaded = FALSE;
CoglPixelFormat pixel_format;
g_return_val_if_fail (g_task_is_valid (result, self), FALSE);
@@ -972,15 +1028,13 @@ meta_background_load_file_finish (MetaBackground *self,
pixels = gdk_pixbuf_get_pixels (pixbuf);
has_alpha = gdk_pixbuf_get_has_alpha (pixbuf);
texture = cogl_texture_new_from_data (width,
height,
COGL_TEXTURE_NO_ATLAS,
has_alpha ?
COGL_PIXEL_FORMAT_RGBA_8888 :
COGL_PIXEL_FORMAT_RGB_888,
COGL_PIXEL_FORMAT_ANY,
row_stride,
pixels);
pixel_format = has_alpha ? COGL_PIXEL_FORMAT_RGBA_8888 : COGL_PIXEL_FORMAT_RGB_888;
texture = COGL_TEXTURE (cogl_texture_2d_new_from_data (ctx, width, height,
pixel_format,
row_stride,
pixels,
NULL));
if (texture == NULL)
{

View File

@@ -20,6 +20,7 @@
*/
#include <meta/meta-plugin.h>
#include <meta/meta-version.h>
#include "meta-module.h"
#include <gmodule.h>
@@ -68,7 +69,7 @@ meta_module_load (GTypeModule *gmodule)
(gpointer *)(void *)&register_type) &&
info && register_type)
{
if (info->version_api != MUTTER_PLUGIN_API_VERSION)
if (info->version_api != META_PLUGIN_API_VERSION)
g_warning ("Plugin API mismatch for [%s]", priv->path);
else
{

View File

@@ -170,6 +170,15 @@ meta_plugin_manager_event_simple (MetaPluginManager *plugin_mgr,
klass->minimize (plugin, actor);
}
break;
case META_PLUGIN_UNMINIMIZE:
if (klass->unminimize)
{
retval = TRUE;
meta_plugin_manager_kill_window_effects (plugin_mgr,
actor);
klass->unminimize (plugin, actor);
}
break;
case META_PLUGIN_MAP:
if (klass->map)
{
@@ -374,3 +383,20 @@ meta_plugin_manager_show_window_menu (MetaPluginManager *plugin_mgr,
if (klass->show_window_menu)
klass->show_window_menu (plugin, window, menu, x, y);
}
void
meta_plugin_manager_show_window_menu_for_rect (MetaPluginManager *plugin_mgr,
MetaWindow *window,
MetaWindowMenuType menu,
MetaRectangle *rect)
{
MetaPlugin *plugin = plugin_mgr->plugin;
MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
MetaDisplay *display = plugin_mgr->compositor->display;
if (display->display_opening)
return;
if (klass->show_window_menu_for_rect)
klass->show_window_menu_for_rect (plugin, window, menu, rect);
}

View File

@@ -35,6 +35,7 @@
#define META_PLUGIN_MAP (1<<3)
#define META_PLUGIN_DESTROY (1<<4)
#define META_PLUGIN_SWITCH_WORKSPACE (1<<5)
#define META_PLUGIN_UNMINIMIZE (1<<6)
#define META_PLUGIN_ALL_EFFECTS (~0)
@@ -87,5 +88,10 @@ void meta_plugin_manager_show_window_menu (MetaPluginManager *mgr,
int x,
int y);
void meta_plugin_manager_show_window_menu_for_rect (MetaPluginManager *mgr,
MetaWindow *window,
MetaWindowMenuType menu,
MetaRectangle *rect);
#endif

View File

@@ -110,6 +110,13 @@ meta_plugin_minimize_completed (MetaPlugin *plugin,
meta_plugin_window_effect_completed (plugin, actor, META_PLUGIN_MINIMIZE);
}
void
meta_plugin_unminimize_completed (MetaPlugin *plugin,
MetaWindowActor *actor)
{
meta_plugin_window_effect_completed (plugin, actor, META_PLUGIN_UNMINIMIZE);
}
void
meta_plugin_maximize_completed (MetaPlugin *plugin,
MetaWindowActor *actor)

View File

@@ -121,17 +121,17 @@ static guint signals[LAST_SIGNAL] = { 0 };
/* The first element in this array also defines the default parameters
* for newly created classes */
MetaShadowClassInfo default_shadow_classes[] = {
{ "normal", { 6, -1, 0, 3, 128 }, { 3, -1, 0, 3, 32 } },
{ "dialog", { 6, -1, 0, 3, 128 }, { 3, -1, 0, 3, 32 } },
{ "modal_dialog", { 6, -1, 0, 1, 128 }, { 3, -1, 0, 3, 32 } },
{ "normal", { 3, -1, 0, 3, 128 }, { 3, -1, 0, 3, 32 } },
{ "dialog", { 3, -1, 0, 3, 128 }, { 3, -1, 0, 3, 32 } },
{ "modal_dialog", { 3, -1, 0, 1, 128 }, { 3, -1, 0, 3, 32 } },
{ "utility", { 3, -1, 0, 1, 128 }, { 3, -1, 0, 1, 32 } },
{ "border", { 6, -1, 0, 3, 128 }, { 3, -1, 0, 3, 32 } },
{ "menu", { 6, -1, 0, 3, 128 }, { 3, -1, 0, 0, 32 } },
{ "border", { 3, -1, 0, 3, 128 }, { 3, -1, 0, 3, 32 } },
{ "menu", { 3, -1, 0, 3, 128 }, { 3, -1, 0, 0, 32 } },
{ "popup-menu", { 1, -1, 0, 1, 128 }, { 1, -1, 0, 1, 128 } },
{ "popup-menu", { 1, 0, 0, 1, 128 }, { 1, -1, 0, 1, 128 } },
{ "dropdown-menu", { 1, 10, 0, 1, 128 }, { 1, 10, 0, 1, 128 } },
{ "attached", { 1, -1, 0, 1, 128 }, { 1, -1, 0, 1, 128 } }
{ "attached", { 1, 0, 0, 1, 128 }, { 1, -1, 0, 1, 128 } }
};
G_DEFINE_TYPE (MetaShadowFactory, meta_shadow_factory, G_TYPE_OBJECT);
@@ -496,7 +496,12 @@ get_box_filter_size (int radius)
static int
get_shadow_spread (int radius)
{
int d = get_box_filter_size (radius);
int d;
if (radius == 0)
return 0;
d = get_box_filter_size (radius);
if (d % 2 == 1)
return 3 * (d / 2);
@@ -536,7 +541,7 @@ blur_xspan (guchar *row,
* be well predicted and there are enough different possibilities
* that trying to write this as a series of unconditional loops
* is hard and not an obvious win. The main slow down here seems
* to be the integer division for pixel; one possible optimization
* to be the integer division per pixel; one possible optimization
* would be to accumulate into two 16-bit integer buffers and
* only divide down after all three passes. (SSE parallel implementation
* of the divide step is possible.)
@@ -544,27 +549,27 @@ blur_xspan (guchar *row,
for (i = x0 - d + offset; i < x1 + offset; i++)
{
if (i >= 0 && i < row_width)
sum += row[i];
sum += row[i];
if (i >= x0 + offset)
{
if (i >= d)
sum -= row[i - d];
{
if (i >= d)
sum -= row[i - d];
tmp_buffer[i - offset] = (sum + d / 2) / d;
}
tmp_buffer[i - offset] = (sum + d / 2) / d;
}
}
memcpy(row + x0, tmp_buffer + x0, x1 - x0);
memcpy (row + x0, tmp_buffer + x0, x1 - x0);
}
static void
blur_rows (cairo_region_t *convolve_region,
int x_offset,
int y_offset,
guchar *buffer,
int buffer_width,
int buffer_height,
guchar *buffer,
int buffer_width,
int buffer_height,
int d)
{
int i, j;
@@ -581,30 +586,30 @@ blur_rows (cairo_region_t *convolve_region,
cairo_region_get_rectangle (convolve_region, i, &rect);
for (j = y_offset + rect.y; j < y_offset + rect.y + rect.height; j++)
{
guchar *row = buffer + j * buffer_width;
int x0 = x_offset + rect.x;
int x1 = x0 + rect.width;
{
guchar *row = buffer + j * buffer_width;
int x0 = x_offset + rect.x;
int x1 = x0 + rect.width;
/* We want to produce a symmetric blur that spreads a pixel
* equally far to the left and right. If d is odd that happens
* naturally, but for d even, we approximate by using a blur
* on either side and then a centered blur of size d + 1.
* (techique also from the SVG specification)
* (technique also from the SVG specification)
*/
if (d % 2 == 1)
{
blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d, 0);
blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d, 0);
blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d, 0);
}
else
{
blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d, 1);
blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d, -1);
blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d + 1, 0);
}
}
if (d % 2 == 1)
{
blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d, 0);
blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d, 0);
blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d, 0);
}
else
{
blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d, 1);
blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d, -1);
blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d + 1, 0);
}
}
}
g_free (tmp_buffer);
@@ -629,7 +634,7 @@ fade_bytes (guchar *bytes,
*/
static guchar *
flip_buffer (guchar *buffer,
int width,
int width,
int height)
{
/* Working in blocks increases cache efficiency, compared to reading
@@ -641,33 +646,33 @@ flip_buffer (guchar *buffer,
int i0, j0;
for (j0 = 0; j0 < height; j0 += BLOCK_SIZE)
for (i0 = 0; i0 <= j0; i0 += BLOCK_SIZE)
{
int max_j = MIN(j0 + BLOCK_SIZE, height);
int max_i = MIN(i0 + BLOCK_SIZE, width);
int i, j;
for (i0 = 0; i0 <= j0; i0 += BLOCK_SIZE)
{
int max_j = MIN(j0 + BLOCK_SIZE, height);
int max_i = MIN(i0 + BLOCK_SIZE, width);
int i, j;
if (i0 == j0)
{
for (j = j0; j < max_j; j++)
for (i = i0; i < j; i++)
{
guchar tmp = buffer[j * width + i];
buffer[j * width + i] = buffer[i * width + j];
buffer[i * width + j] = tmp;
}
}
else
{
for (j = j0; j < max_j; j++)
for (i = i0; i < max_i; i++)
{
guchar tmp = buffer[j * width + i];
buffer[j * width + i] = buffer[i * width + j];
buffer[i * width + j] = tmp;
}
}
}
if (i0 == j0)
{
for (j = j0; j < max_j; j++)
for (i = i0; i < j; i++)
{
guchar tmp = buffer[j * width + i];
buffer[j * width + i] = buffer[i * width + j];
buffer[i * width + j] = tmp;
}
}
else
{
for (j = j0; j < max_j; j++)
for (i = i0; i < max_i; i++)
{
guchar tmp = buffer[j * width + i];
buffer[j * width + i] = buffer[i * width + j];
buffer[i * width + j] = tmp;
}
}
}
return buffer;
}
@@ -678,15 +683,15 @@ flip_buffer (guchar *buffer,
for (i0 = 0; i0 < width; i0 += BLOCK_SIZE)
for (j0 = 0; j0 < height; j0 += BLOCK_SIZE)
{
int max_j = MIN(j0 + BLOCK_SIZE, height);
int max_i = MIN(i0 + BLOCK_SIZE, width);
int i, j;
{
int max_j = MIN(j0 + BLOCK_SIZE, height);
int max_i = MIN(i0 + BLOCK_SIZE, width);
int i, j;
for (i = i0; i < max_i; i++)
for (j = j0; j < max_j; j++)
new_buffer[i * height + j] = buffer[j * width + i];
}
new_buffer[i * height + j] = buffer[j * width + i];
}
g_free (buffer);
@@ -699,6 +704,8 @@ static void
make_shadow (MetaShadow *shadow,
cairo_region_t *region)
{
ClutterBackend *backend = clutter_get_default_backend ();
CoglContext *ctx = clutter_backend_get_cogl_context (backend);
int d = get_box_filter_size (shadow->key.radius);
int spread = get_shadow_spread (shadow->key.radius);
cairo_rectangle_int_t extents;
@@ -758,7 +765,7 @@ make_shadow (MetaShadow *shadow,
cairo_region_get_rectangle (region, k, &rect);
for (j = y_offset + rect.y; j < y_offset + rect.y + rect.height; j++)
memset (buffer + buffer_width * j + x_offset + rect.x, 255, rect.width);
memset (buffer + buffer_width * j + x_offset + rect.x, 255, rect.width);
}
/* Step 2: swap rows and columns */
@@ -788,15 +795,15 @@ make_shadow (MetaShadow *shadow,
* in the case of top_fade >= 0. We also account for padding at the left for symmetry
* though that doesn't currently occur.
*/
shadow->texture = cogl_texture_new_from_data (shadow->outer_border_left + extents.width + shadow->outer_border_right,
shadow->outer_border_top + extents.height + shadow->outer_border_bottom,
COGL_TEXTURE_NONE,
COGL_PIXEL_FORMAT_A_8,
COGL_PIXEL_FORMAT_ANY,
buffer_width,
(buffer +
(y_offset - shadow->outer_border_top) * buffer_width +
(x_offset - shadow->outer_border_left)));
shadow->texture = COGL_TEXTURE (cogl_texture_2d_new_from_data (ctx,
shadow->outer_border_left + extents.width + shadow->outer_border_right,
shadow->outer_border_top + extents.height + shadow->outer_border_bottom,
COGL_PIXEL_FORMAT_A_8,
buffer_width,
(buffer +
(y_offset - shadow->outer_border_top) * buffer_width +
(x_offset - shadow->outer_border_left)),
NULL));
cairo_region_destroy (row_convolve_region);
cairo_region_destroy (column_convolve_region);

View File

@@ -32,8 +32,6 @@
ClutterActor *meta_shaped_texture_new (void);
void meta_shaped_texture_set_texture (MetaShapedTexture *stex,
CoglTexture *texture);
gboolean meta_shaped_texture_get_unobscured_bounds (MetaShapedTexture *stex,
cairo_rectangle_int_t *unobscured_bounds);
gboolean meta_shaped_texture_is_obscured (MetaShapedTexture *self);
#endif

View File

@@ -28,16 +28,14 @@
#include <config.h>
#include <meta/meta-shaped-texture.h>
#include <meta/util.h>
#include "meta-shaped-texture-private.h"
#include <cogl/cogl.h>
#include <gdk/gdk.h> /* for gdk_rectangle_intersect() */
#include "clutter-utils.h"
#include "meta-texture-tower.h"
#include "meta-shaped-texture-private.h"
#include "meta-window-actor-private.h"
#include <clutter/clutter.h>
#include <cogl/cogl.h>
#include <gdk/gdk.h> /* for gdk_rectangle_intersect() */
#include "meta-cullable.h"
static void meta_shaped_texture_dispose (GObject *object);
@@ -65,6 +63,14 @@ G_DEFINE_TYPE_WITH_CODE (MetaShapedTexture, meta_shaped_texture, CLUTTER_TYPE_AC
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), META_TYPE_SHAPED_TEXTURE, \
MetaShapedTexturePrivate))
enum {
SIZE_CHANGED,
LAST_SIGNAL,
};
static guint signals[LAST_SIGNAL];
struct _MetaShapedTexturePrivate
{
MetaTextureTower *paint_tower;
@@ -97,6 +103,13 @@ meta_shaped_texture_class_init (MetaShapedTextureClass *klass)
actor_class->paint = meta_shaped_texture_paint;
actor_class->get_paint_volume = meta_shaped_texture_get_paint_volume;
signals[SIZE_CHANGED] = g_signal_new ("size-changed",
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 0);
g_type_class_add_private (klass, sizeof (MetaShapedTexturePrivate));
}
@@ -249,22 +262,20 @@ set_cogl_texture (MetaShapedTexture *stex,
cogl_object_ref (cogl_tex);
width = cogl_texture_get_width (COGL_TEXTURE (cogl_tex));
height = cogl_texture_get_height (COGL_TEXTURE (cogl_tex));
if (width != priv->tex_width ||
height != priv->tex_height)
{
priv->tex_width = width;
priv->tex_height = height;
clutter_actor_queue_relayout (CLUTTER_ACTOR (stex));
}
}
else
{
/* size changed to 0 going to an invalid handle */
priv->tex_width = 0;
priv->tex_height = 0;
width = 0;
height = 0;
}
if (priv->tex_width != width ||
priv->tex_height != height)
{
priv->tex_width = width;
priv->tex_height = height;
clutter_actor_queue_relayout (CLUTTER_ACTOR (stex));
g_signal_emit (stex, signals[SIZE_CHANGED], 0);
}
/* NB: We don't queue a redraw of the actor here because we don't
@@ -285,10 +296,8 @@ meta_shaped_texture_paint (ClutterActor *actor)
guchar opacity;
CoglContext *ctx;
CoglFramebuffer *fb;
CoglPipeline *pipeline = NULL;
CoglTexture *paint_tex;
ClutterActorBox alloc;
cairo_region_t *blended_region = NULL;
CoglPipelineFilter filter;
if (priv->clip_region && cairo_region_is_empty (priv->clip_region))
@@ -326,6 +335,8 @@ meta_shaped_texture_paint (ClutterActor *actor)
if (tex_width == 0 || tex_height == 0) /* no contents yet */
return;
cairo_rectangle_int_t tex_rect = { 0, 0, tex_width, tex_height };
/* Use nearest-pixel interpolation if the texture is unscaled. This
* improves performance, especially with software rendering.
*/
@@ -341,7 +352,45 @@ meta_shaped_texture_paint (ClutterActor *actor)
opacity = clutter_actor_get_paint_opacity (actor);
clutter_actor_get_allocation_box (actor, &alloc);
if (priv->opaque_region != NULL && opacity == 255)
cairo_region_t *blended_region;
gboolean use_opaque_region = (priv->opaque_region != NULL && opacity == 255);
if (use_opaque_region)
{
if (priv->clip_region != NULL)
blended_region = cairo_region_copy (priv->clip_region);
else
blended_region = cairo_region_create_rectangle (&tex_rect);
cairo_region_subtract (blended_region, priv->opaque_region);
}
else
{
if (priv->clip_region != NULL)
blended_region = cairo_region_reference (priv->clip_region);
else
blended_region = NULL;
}
/* Limit to how many separate rectangles we'll draw; beyond this just
* fall back and draw the whole thing */
#define MAX_RECTS 16
if (blended_region != NULL)
{
int n_rects = cairo_region_num_rectangles (blended_region);
if (n_rects > MAX_RECTS)
{
/* Fall back to taking the fully blended path. */
use_opaque_region = FALSE;
cairo_region_destroy (blended_region);
blended_region = NULL;
}
}
/* First, paint the unblended parts, which are part of the opaque region. */
if (use_opaque_region)
{
CoglPipeline *opaque_pipeline;
cairo_region_t *region;
@@ -358,103 +407,87 @@ meta_shaped_texture_paint (ClutterActor *actor)
region = cairo_region_reference (priv->opaque_region);
}
if (cairo_region_is_empty (region))
goto paint_blended;
opaque_pipeline = get_unblended_pipeline (ctx);
cogl_pipeline_set_layer_texture (opaque_pipeline, 0, paint_tex);
cogl_pipeline_set_layer_filters (opaque_pipeline, 0, filter, filter);
n_rects = cairo_region_num_rectangles (region);
for (i = 0; i < n_rects; i++)
if (!cairo_region_is_empty (region))
{
cairo_rectangle_int_t rect;
cairo_region_get_rectangle (region, i, &rect);
paint_clipped_rectangle (fb, opaque_pipeline, &rect, &alloc);
opaque_pipeline = get_unblended_pipeline (ctx);
cogl_pipeline_set_layer_texture (opaque_pipeline, 0, paint_tex);
cogl_pipeline_set_layer_filters (opaque_pipeline, 0, filter, filter);
n_rects = cairo_region_num_rectangles (region);
for (i = 0; i < n_rects; i++)
{
cairo_rectangle_int_t rect;
cairo_region_get_rectangle (region, i, &rect);
paint_clipped_rectangle (fb, opaque_pipeline, &rect, &alloc);
}
cogl_object_unref (opaque_pipeline);
}
cogl_object_unref (opaque_pipeline);
if (priv->clip_region != NULL)
{
blended_region = cairo_region_copy (priv->clip_region);
}
else
{
cairo_rectangle_int_t rect = { 0, 0, tex_width, tex_height };
blended_region = cairo_region_create_rectangle (&rect);
}
cairo_region_subtract (blended_region, priv->opaque_region);
paint_blended:
cairo_region_destroy (region);
}
if (blended_region == NULL && priv->clip_region != NULL)
blended_region = cairo_region_reference (priv->clip_region);
/* Now, go ahead and paint the blended parts. */
if (blended_region != NULL && cairo_region_is_empty (blended_region))
goto out;
if (priv->mask_texture == NULL)
/* We have three cases:
* 1) blended_region has rectangles - paint the rectangles.
* 2) blended_region is empty - don't paint anything
* 3) blended_region is NULL - paint fully-blended.
*
* 1) and 3) are the times where we have to paint stuff. This tests
* for 1) and 3).
*/
if (blended_region == NULL || !cairo_region_is_empty (blended_region))
{
pipeline = get_unmasked_pipeline (ctx);
}
else
{
pipeline = get_masked_pipeline (ctx);
cogl_pipeline_set_layer_texture (pipeline, 1, priv->mask_texture);
cogl_pipeline_set_layer_filters (pipeline, 1, filter, filter);
}
CoglPipeline *blended_pipeline;
cogl_pipeline_set_layer_texture (pipeline, 0, paint_tex);
cogl_pipeline_set_layer_filters (pipeline, 0, filter, filter);
if (priv->mask_texture == NULL)
{
blended_pipeline = get_unmasked_pipeline (ctx);
}
else
{
blended_pipeline = get_masked_pipeline (ctx);
cogl_pipeline_set_layer_texture (blended_pipeline, 1, priv->mask_texture);
cogl_pipeline_set_layer_filters (blended_pipeline, 1, filter, filter);
}
{
CoglColor color;
cogl_color_init_from_4ub (&color, opacity, opacity, opacity, opacity);
cogl_pipeline_set_color (pipeline, &color);
}
cogl_pipeline_set_layer_texture (blended_pipeline, 0, paint_tex);
cogl_pipeline_set_layer_filters (blended_pipeline, 0, filter, filter);
if (blended_region != NULL)
{
int n_rects;
CoglColor color;
cogl_color_init_from_4ub (&color, opacity, opacity, opacity, opacity);
cogl_pipeline_set_color (blended_pipeline, &color);
/* Limit to how many separate rectangles we'll draw; beyond this just
* fall back and draw the whole thing */
# define MAX_RECTS 16
n_rects = cairo_region_num_rectangles (blended_region);
if (n_rects <= MAX_RECTS)
{
if (blended_region != NULL)
{
/* 1) blended_region is not empty. Paint the rectangles. */
int i;
cairo_rectangle_int_t tex_rect = { 0, 0, tex_width, tex_height };
int n_rects = cairo_region_num_rectangles (blended_region);
for (i = 0; i < n_rects; i++)
{
cairo_rectangle_int_t rect;
for (i = 0; i < n_rects; i++)
{
cairo_rectangle_int_t rect;
cairo_region_get_rectangle (blended_region, i, &rect);
cairo_region_get_rectangle (blended_region, i, &rect);
if (!gdk_rectangle_intersect (&tex_rect, &rect, &rect))
continue;
if (!gdk_rectangle_intersect (&tex_rect, &rect, &rect))
continue;
paint_clipped_rectangle (fb, pipeline, &rect, &alloc);
paint_clipped_rectangle (fb, blended_pipeline, &rect, &alloc);
}
}
else
{
/* 3) blended_region is NULL. Do a full paint. */
cogl_framebuffer_draw_rectangle (fb, blended_pipeline,
0, 0,
alloc.x2 - alloc.x1,
alloc.y2 - alloc.y1);
}
goto out;
}
cogl_object_unref (blended_pipeline);
}
cogl_framebuffer_draw_rectangle (fb, pipeline,
0, 0,
alloc.x2 - alloc.x1,
alloc.y2 - alloc.y1);
out:
if (pipeline != NULL)
cogl_object_unref (pipeline);
if (blended_region != NULL)
cairo_region_destroy (blended_region);
}
@@ -472,7 +505,7 @@ meta_shaped_texture_get_preferred_width (ClutterActor *self,
priv = META_SHAPED_TEXTURE (self)->priv;
if (min_width_p)
*min_width_p = 0;
*min_width_p = priv->tex_width;
if (natural_width_p)
*natural_width_p = priv->tex_width;
@@ -491,43 +524,70 @@ meta_shaped_texture_get_preferred_height (ClutterActor *self,
priv = META_SHAPED_TEXTURE (self)->priv;
if (min_height_p)
*min_height_p = 0;
*min_height_p = priv->tex_height;
if (natural_height_p)
*natural_height_p = priv->tex_height;
}
static cairo_region_t *
effective_unobscured_region (MetaShapedTexture *self)
{
MetaShapedTexturePrivate *priv = self->priv;
ClutterActor *actor;
/* Fail if we have any mapped clones. */
actor = CLUTTER_ACTOR (self);
do
{
if (clutter_actor_has_mapped_clones (actor))
return NULL;
actor = clutter_actor_get_parent (actor);
}
while (actor != NULL);
return priv->unobscured_region;
}
static gboolean
get_unobscured_bounds (MetaShapedTexture *self,
cairo_rectangle_int_t *unobscured_bounds)
{
cairo_region_t *unobscured_region = effective_unobscured_region (self);
if (unobscured_region)
{
cairo_region_get_extents (unobscured_region, unobscured_bounds);
return TRUE;
}
else
return FALSE;
}
static gboolean
meta_shaped_texture_get_paint_volume (ClutterActor *actor,
ClutterPaintVolume *volume)
{
MetaShapedTexture *self = META_SHAPED_TEXTURE (actor);
ClutterActorBox box;
cairo_rectangle_int_t unobscured_bounds;
if (!clutter_paint_volume_set_from_allocation (volume, actor))
if (!clutter_actor_has_allocation (actor))
return FALSE;
if (meta_shaped_texture_get_unobscured_bounds (self, &unobscured_bounds))
clutter_actor_get_allocation_box (actor, &box);
if (get_unobscured_bounds (self, &unobscured_bounds))
{
ClutterVertex origin;
cairo_rectangle_int_t bounds;
/* I hate ClutterPaintVolume so much... */
clutter_paint_volume_get_origin (volume, &origin);
bounds.x = origin.x;
bounds.y = origin.y;
bounds.width = clutter_paint_volume_get_width (volume);
bounds.height = clutter_paint_volume_get_height (volume);
gdk_rectangle_intersect (&bounds, &unobscured_bounds, &bounds);
origin.x = bounds.x;
origin.y = bounds.y;
clutter_paint_volume_set_origin (volume, &origin);
clutter_paint_volume_set_width (volume, bounds.width);
clutter_paint_volume_set_height (volume, bounds.height);
box.x1 = MAX (unobscured_bounds.x, box.x1);
box.x2 = MIN (unobscured_bounds.x + unobscured_bounds.width, box.x2);
box.y1 = MAX (unobscured_bounds.y, box.y1);
box.y2 = MIN (unobscured_bounds.y + unobscured_bounds.height, box.y2);
}
box.x2 = MAX (box.x2, box.x1);
box.y2 = MAX (box.y2, box.y1);
clutter_paint_volume_union_box (volume, &box);
return TRUE;
}
@@ -573,39 +633,6 @@ meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex,
clutter_actor_queue_redraw (CLUTTER_ACTOR (stex));
}
static cairo_region_t *
effective_unobscured_region (MetaShapedTexture *self)
{
MetaShapedTexturePrivate *priv = self->priv;
ClutterActor *parent = clutter_actor_get_parent (CLUTTER_ACTOR (self));
if (clutter_actor_has_mapped_clones (CLUTTER_ACTOR (self)))
return NULL;
while (parent && !META_IS_WINDOW_ACTOR (parent))
parent = clutter_actor_get_parent (parent);
if (parent && clutter_actor_has_mapped_clones (parent))
return NULL;
return priv->unobscured_region;
}
gboolean
meta_shaped_texture_get_unobscured_bounds (MetaShapedTexture *self,
cairo_rectangle_int_t *unobscured_bounds)
{
cairo_region_t *unobscured_region = effective_unobscured_region (self);
if (unobscured_region)
{
cairo_region_get_extents (unobscured_region, unobscured_bounds);
return TRUE;
}
else
return FALSE;
}
gboolean
meta_shaped_texture_is_obscured (MetaShapedTexture *self)
{

View File

@@ -1,176 +0,0 @@
/*
* Copyright (C) 2014 Red Hat
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Written by:
* Jasper St. Pierre <jstpierre@mecheye.net>
*/
#include <config.h>
#include "meta-stage.h"
#include "meta-cursor-private.h"
#include "meta-backend.h"
#include <meta/util.h>
struct _MetaStagePrivate {
CoglPipeline *pipeline;
gboolean should_paint_cursor;
MetaCursorReference *cursor;
MetaRectangle current_rect;
MetaRectangle previous_rect;
gboolean previous_is_valid;
};
typedef struct _MetaStagePrivate MetaStagePrivate;
G_DEFINE_TYPE_WITH_PRIVATE (MetaStage, meta_stage, CLUTTER_TYPE_STAGE);
static void
update_pipeline (MetaStage *stage)
{
MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
if (priv->cursor)
{
CoglTexture *texture = meta_cursor_reference_get_cogl_texture (priv->cursor, NULL, NULL);
cogl_pipeline_set_layer_texture (priv->pipeline, 0, texture);
}
else
cogl_pipeline_set_layer_texture (priv->pipeline, 0, NULL);
}
static void
meta_stage_finalize (GObject *object)
{
MetaStage *stage = META_STAGE (object);
MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
if (priv->pipeline)
cogl_object_unref (priv->pipeline);
}
static void
paint_cursor (MetaStage *stage)
{
MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
g_assert (meta_is_wayland_compositor ());
if (!priv->cursor)
return;
cogl_framebuffer_draw_rectangle (cogl_get_draw_framebuffer (),
priv->pipeline,
priv->current_rect.x,
priv->current_rect.y,
priv->current_rect.x +
priv->current_rect.width,
priv->current_rect.y +
priv->current_rect.height);
priv->previous_rect = priv->current_rect;
priv->previous_is_valid = TRUE;
}
static void
meta_stage_paint (ClutterActor *actor)
{
MetaStage *stage = META_STAGE (actor);
CLUTTER_ACTOR_CLASS (meta_stage_parent_class)->paint (actor);
if (meta_is_wayland_compositor ())
paint_cursor (stage);
}
static void
meta_stage_class_init (MetaStageClass *klass)
{
ClutterActorClass *actor_class = (ClutterActorClass *) klass;
GObjectClass *object_class = (GObjectClass *) klass;
object_class->finalize = meta_stage_finalize;
actor_class->paint = meta_stage_paint;
}
static void
meta_stage_init (MetaStage *stage)
{
CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
priv->pipeline = cogl_pipeline_new (ctx);
clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), FALSE);
}
ClutterActor *
meta_stage_new (void)
{
return g_object_new (META_TYPE_STAGE,
"cursor-visible", FALSE,
NULL);
}
static void
queue_redraw (MetaStage *stage)
{
MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
cairo_rectangle_int_t clip;
/* Clear the location the cursor was at before, if we need to. */
if (priv->previous_is_valid)
{
clip.x = priv->previous_rect.x;
clip.y = priv->previous_rect.y;
clip.width = priv->previous_rect.width;
clip.height = priv->previous_rect.height;
clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stage), &clip);
priv->previous_is_valid = FALSE;
}
/* And queue a redraw for the current cursor location. */
if (priv->cursor)
{
clip.x = priv->current_rect.x;
clip.y = priv->current_rect.y;
clip.width = priv->current_rect.width;
clip.height = priv->current_rect.height;
clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stage), &clip);
}
}
void
meta_stage_set_cursor (MetaStage *stage,
MetaCursorReference *cursor,
MetaRectangle *rect)
{
MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
if (priv->cursor != cursor)
{
priv->cursor = cursor;
update_pipeline (stage);
}
priv->current_rect = *rect;
queue_redraw (stage);
}

View File

@@ -34,45 +34,15 @@
struct _MetaSurfaceActorWaylandPrivate
{
MetaWaylandSurface *surface;
MetaWaylandBuffer *buffer;
struct wl_listener buffer_destroy_listener;
};
typedef struct _MetaSurfaceActorWaylandPrivate MetaSurfaceActorWaylandPrivate;
G_DEFINE_TYPE_WITH_PRIVATE (MetaSurfaceActorWayland, meta_surface_actor_wayland, META_TYPE_SURFACE_ACTOR)
static void
meta_surface_actor_handle_buffer_destroy (struct wl_listener *listener, void *data)
{
MetaSurfaceActorWaylandPrivate *priv = wl_container_of (listener, priv, buffer_destroy_listener);
/* If the buffer is destroyed while we're attached to it,
* we want to unset priv->buffer so we don't access freed
* memory. Keep the texture set however so the user doesn't
* see the window disappear. */
priv->buffer = NULL;
}
static void
meta_surface_actor_wayland_process_damage (MetaSurfaceActor *actor,
int x, int y, int width, int height)
{
MetaSurfaceActorWayland *self = META_SURFACE_ACTOR_WAYLAND (actor);
MetaSurfaceActorWaylandPrivate *priv = meta_surface_actor_wayland_get_instance_private (self);
if (priv->buffer)
{
struct wl_resource *resource = priv->buffer->resource;
struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get (resource);
if (shm_buffer)
{
CoglTexture2D *texture = COGL_TEXTURE_2D (priv->buffer->texture);
cogl_wayland_texture_set_region_from_shm_buffer (texture, x, y, width, height, shm_buffer, x, y, 0, NULL);
}
meta_surface_actor_update_area (META_SURFACE_ACTOR (self), x, y, width, height);
}
}
static void
@@ -109,7 +79,7 @@ meta_surface_actor_wayland_is_unredirected (MetaSurfaceActor *actor)
}
static int
get_output_scale (int output_id)
get_output_scale (int winsys_id)
{
MetaMonitorManager *monitor_manager = meta_monitor_manager_get ();
MetaOutput *outputs;
@@ -120,7 +90,7 @@ get_output_scale (int output_id)
for (i = 0; i < n_outputs; i++)
{
if (outputs[i].output_id == output_id)
if (outputs[i].winsys_id == winsys_id)
{
output_scale = outputs[i].scale;
break;
@@ -150,7 +120,7 @@ meta_surface_actor_wayland_get_scale (MetaSurfaceActorWayland *actor)
/* XXX: We do not handle x11 clients yet */
if (window && window->client_type != META_WINDOW_CLIENT_TYPE_X11)
output_scale = get_output_scale (window->monitor->output_id);
output_scale = get_output_scale (window->monitor->winsys_id);
return (double)output_scale / (double)priv->surface->scale;
}
@@ -213,7 +183,7 @@ meta_surface_actor_wayland_dispose (GObject *object)
{
MetaSurfaceActorWayland *self = META_SURFACE_ACTOR_WAYLAND (object);
meta_surface_actor_wayland_set_buffer (self, NULL);
meta_surface_actor_wayland_set_texture (self, NULL);
G_OBJECT_CLASS (meta_surface_actor_wayland_parent_class)->dispose (object);
}
@@ -244,9 +214,6 @@ meta_surface_actor_wayland_class_init (MetaSurfaceActorWaylandClass *klass)
static void
meta_surface_actor_wayland_init (MetaSurfaceActorWayland *self)
{
MetaSurfaceActorWaylandPrivate *priv = meta_surface_actor_wayland_get_instance_private (self);
priv->buffer_destroy_listener.notify = meta_surface_actor_handle_buffer_destroy;
}
MetaSurfaceActor *
@@ -263,24 +230,11 @@ meta_surface_actor_wayland_new (MetaWaylandSurface *surface)
}
void
meta_surface_actor_wayland_set_buffer (MetaSurfaceActorWayland *self,
MetaWaylandBuffer *buffer)
meta_surface_actor_wayland_set_texture (MetaSurfaceActorWayland *self,
CoglTexture *texture)
{
MetaSurfaceActorWaylandPrivate *priv = meta_surface_actor_wayland_get_instance_private (self);
MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self));
if (priv->buffer)
wl_list_remove (&priv->buffer_destroy_listener.link);
priv->buffer = buffer;
if (priv->buffer)
{
wl_signal_add (&priv->buffer->destroy_signal, &priv->buffer_destroy_listener);
meta_shaped_texture_set_texture (stex, priv->buffer->texture);
}
else
meta_shaped_texture_set_texture (stex, NULL);
meta_shaped_texture_set_texture (stex, texture);
}
MetaWaylandSurface *

View File

@@ -58,8 +58,8 @@ GType meta_surface_actor_wayland_get_type (void);
MetaSurfaceActor * meta_surface_actor_wayland_new (MetaWaylandSurface *surface);
MetaWaylandSurface * meta_surface_actor_wayland_get_surface (MetaSurfaceActorWayland *self);
void meta_surface_actor_wayland_set_buffer (MetaSurfaceActorWayland *self,
MetaWaylandBuffer *buffer);
void meta_surface_actor_wayland_set_texture (MetaSurfaceActorWayland *self,
CoglTexture *texture);
double meta_surface_actor_wayland_get_scale (MetaSurfaceActorWayland *actor);

View File

@@ -34,6 +34,7 @@
#include "window-private.h"
#include "meta-shaped-texture-private.h"
#include "meta-cullable.h"
#include "x11/window-x11.h"
struct _MetaSurfaceActorX11Private
{
@@ -143,7 +144,7 @@ update_pixmap (MetaSurfaceActorX11 *self)
if (priv->pixmap == None)
{
Pixmap new_pixmap;
Window xwindow = meta_window_get_toplevel_xwindow (priv->window);
Window xwindow = meta_window_x11_get_toplevel_xwindow (priv->window);
meta_error_trap_push (display);
new_pixmap = XCompositeNameWindowPixmap (xdisplay, xwindow);
@@ -178,19 +179,6 @@ is_visible (MetaSurfaceActorX11 *self)
return (priv->pixmap != None) && !priv->unredirected;
}
static void
damage_area (MetaSurfaceActorX11 *self,
int x, int y, int width, int height)
{
MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self);
if (!is_visible (self))
return;
cogl_texture_pixmap_x11_update_area (priv->texture, x, y, width, height);
meta_surface_actor_update_area (META_SURFACE_ACTOR (self), x, y, width, height);
}
static void
meta_surface_actor_x11_process_damage (MetaSurfaceActor *actor,
int x, int y, int width, int height)
@@ -217,11 +205,10 @@ meta_surface_actor_x11_process_damage (MetaSurfaceActor *actor,
priv->does_full_damage = TRUE;
}
/* Drop damage event for unredirected windows */
if (priv->unredirected)
if (!is_visible (self))
return;
damage_area (self, x, y, width, height);
cogl_texture_pixmap_x11_update_area (priv->texture, x, y, width, height);
}
static void
@@ -292,7 +279,7 @@ sync_unredirected (MetaSurfaceActorX11 *self)
MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self);
MetaDisplay *display = priv->display;
Display *xdisplay = meta_display_get_xdisplay (display);
Window xwindow = meta_window_get_toplevel_xwindow (priv->window);
Window xwindow = meta_window_x11_get_toplevel_xwindow (priv->window);
meta_error_trap_push (display);
@@ -384,7 +371,7 @@ create_damage (MetaSurfaceActorX11 *self)
{
MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self);
Display *xdisplay = meta_display_get_xdisplay (priv->display);
Window xwindow = meta_window_get_toplevel_xwindow (priv->window);
Window xwindow = meta_window_x11_get_toplevel_xwindow (priv->window);
priv->damage = XDamageCreate (xdisplay, xwindow, XDamageReportBoundingBox);
}

View File

@@ -36,20 +36,13 @@ G_DEFINE_ABSTRACT_TYPE_WITH_CODE (MetaSurfaceActor, meta_surface_actor, CLUTTER_
enum {
REPAINT_SCHEDULED,
SIZE_CHANGED,
LAST_SIGNAL,
};
static guint signals[LAST_SIGNAL];
gboolean
meta_surface_actor_get_unobscured_bounds (MetaSurfaceActor *self,
cairo_rectangle_int_t *unobscured_bounds)
{
MetaSurfaceActorPrivate *priv = self->priv;
return meta_shaped_texture_get_unobscured_bounds (priv->texture, unobscured_bounds);
}
static void
meta_surface_actor_pick (ClutterActor *actor,
const ClutterColor *color)
@@ -128,6 +121,13 @@ meta_surface_actor_class_init (MetaSurfaceActorClass *klass)
NULL, NULL, NULL,
G_TYPE_NONE, 0);
signals[SIZE_CHANGED] = g_signal_new ("size-changed",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 0);
g_type_class_add_private (klass, sizeof (MetaSurfaceActorPrivate));
}
@@ -152,6 +152,14 @@ cullable_iface_init (MetaCullableInterface *iface)
iface->reset_culling = meta_surface_actor_reset_culling;
}
static void
texture_size_changed (MetaShapedTexture *texture,
gpointer user_data)
{
MetaSurfaceActor *actor = META_SURFACE_ACTOR (user_data);
g_signal_emit (actor, signals[SIZE_CHANGED], 0);
}
static void
meta_surface_actor_init (MetaSurfaceActor *self)
{
@@ -162,6 +170,8 @@ meta_surface_actor_init (MetaSurfaceActor *self)
MetaSurfaceActorPrivate);
priv->texture = META_SHAPED_TEXTURE (meta_shaped_texture_new ());
g_signal_connect_object (priv->texture, "size-changed",
G_CALLBACK (texture_size_changed), self, 0);
clutter_actor_add_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->texture));
}
@@ -178,7 +188,7 @@ meta_surface_actor_get_texture (MetaSurfaceActor *self)
return self->priv->texture;
}
void
static void
meta_surface_actor_update_area (MetaSurfaceActor *self,
int x, int y, int width, int height)
{
@@ -252,6 +262,9 @@ meta_surface_actor_process_damage (MetaSurfaceActor *self,
}
META_SURFACE_ACTOR_GET_CLASS (self)->process_damage (self, x, y, width, height);
if (meta_surface_actor_is_visible (self))
meta_surface_actor_update_area (self, x, y, width, height);
}
void
@@ -267,9 +280,15 @@ meta_surface_actor_is_argb32 (MetaSurfaceActor *self)
CoglTexture *texture = meta_shaped_texture_get_texture (stex);
/* If we don't have a texture, like during initialization, assume
* that we're ARGB32. */
* that we're ARGB32.
*
* If we are unredirected and we have no texture assume that we are
* not ARGB32 otherwise we wouldn't be unredirected in the first
* place. This prevents us from continually redirecting and
* unredirecting on every paint.
*/
if (!texture)
return TRUE;
return !meta_surface_actor_is_unredirected (self);
switch (cogl_texture_get_components (texture))
{

View File

@@ -55,17 +55,12 @@ MetaShapedTexture *meta_surface_actor_get_texture (MetaSurfaceActor *self);
MetaWindow *meta_surface_actor_get_window (MetaSurfaceActor *self);
gboolean meta_surface_actor_is_obscured (MetaSurfaceActor *self);
gboolean meta_surface_actor_get_unobscured_bounds (MetaSurfaceActor *self,
cairo_rectangle_int_t *unobscured_bounds);
void meta_surface_actor_set_input_region (MetaSurfaceActor *self,
cairo_region_t *region);
void meta_surface_actor_set_opaque_region (MetaSurfaceActor *self,
cairo_region_t *region);
void meta_surface_actor_update_area (MetaSurfaceActor *actor,
int x, int y, int width, int height);
void meta_surface_actor_process_damage (MetaSurfaceActor *actor,
int x, int y, int width, int height);
void meta_surface_actor_pre_paint (MetaSurfaceActor *actor);

View File

@@ -1,574 +0,0 @@
/*
* This is based on an original C++ implementation for compiz that
* carries the following copyright notice:
*
*
* Copyright © 2011 NVIDIA Corporation
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
* appear in supporting documentation, and that the name of NVIDIA
* Corporation not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior
* permission. NVIDIA Corporation makes no representations about the
* suitability of this software for any purpose. It is provided "as
* is" without express or implied warranty.
*
* NVIDIA CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*
* Authors: James Jones <jajones@nvidia.com>
*/
#include <string.h>
#include <GL/gl.h>
#include <GL/glx.h>
#include <cogl/cogl.h>
#include <meta/display.h>
#include <meta/util.h>
#include "meta-sync-ring.h"
/* Theory of operation:
*
* We use a ring of NUM_SYNCS fence objects. On each frame we advance
* to the next fence in the ring. For each fence we do:
*
* 1. fence is XSyncTriggerFence()'d and glWaitSync()'d
* 2. NUM_SYNCS / 2 frames later, fence should be triggered
* 3. fence is XSyncResetFence()'d
* 4. NUM_SYNCS / 2 frames later, fence should be reset
* 5. go back to 1 and re-use fence
*
* glClientWaitSync() and XAlarms are used in steps 2 and 4,
* respectively, to double-check the expectections.
*/
#define NUM_SYNCS 10
#define MAX_SYNC_WAIT_TIME (1 * 1000 * 1000 * 1000) /* one sec */
#define MAX_REBOOT_ATTEMPTS 2
typedef enum
{
META_SYNC_STATE_READY,
META_SYNC_STATE_WAITING,
META_SYNC_STATE_DONE,
META_SYNC_STATE_RESET_PENDING,
} MetaSyncState;
typedef struct
{
Display *xdisplay;
XSyncFence xfence;
GLsync glsync;
XSyncCounter xcounter;
XSyncAlarm xalarm;
XSyncValue next_counter_value;
MetaSyncState state;
} MetaSync;
typedef struct
{
MetaDisplay *display;
GHashTable *alarm_to_sync;
MetaSync *syncs_array[NUM_SYNCS];
guint current_sync_idx;
MetaSync *current_sync;
guint warmup_syncs;
guint reboots;
} MetaSyncRing;
static MetaSyncRing meta_sync_ring = { 0 };
static XSyncValue SYNC_VALUE_ZERO;
static XSyncValue SYNC_VALUE_ONE;
static void (*meta_gl_get_integerv) (GLenum pname,
GLint *params);
static const char* (*meta_gl_get_stringi) (GLenum name,
GLuint index);
static void (*meta_gl_delete_sync) (GLsync sync);
static GLenum (*meta_gl_client_wait_sync) (GLsync sync,
GLbitfield flags,
GLuint64 timeout);
static void (*meta_gl_wait_sync) (GLsync sync,
GLbitfield flags,
GLuint64 timeout);
static GLsync (*meta_gl_import_sync) (GLenum external_sync_type,
GLintptr external_sync,
GLbitfield flags);
static GLenum (*meta_gl_get_error) (void);
static GLboolean (*meta_gl_is_sync) (GLsync sync);
static MetaSyncRing *
meta_sync_ring_get (void)
{
if (meta_sync_ring.reboots > MAX_REBOOT_ATTEMPTS)
return NULL;
return &meta_sync_ring;
}
static gboolean
load_gl_symbol (const char *name,
void **func)
{
*func = cogl_get_proc_address (name);
if (!*func)
{
meta_verbose ("MetaSyncRing: failed to resolve required GL symbol \"%s\"\n", name);
return FALSE;
}
return TRUE;
}
static gboolean
check_gl_extensions (void)
{
int num_extensions, i;
gboolean sync = FALSE;
gboolean x11_sync_object = FALSE;
meta_gl_get_integerv (GL_NUM_EXTENSIONS, &num_extensions);
for (i = 0; i < num_extensions; ++i)
{
const char *ext = meta_gl_get_stringi (GL_EXTENSIONS, i);
if (g_strcmp0 ("GL_ARB_sync", ext) == 0)
sync = TRUE;
else if (g_strcmp0 ("GL_EXT_x11_sync_object", ext) == 0)
x11_sync_object = TRUE;
}
return sync && x11_sync_object;
}
static gboolean
load_required_symbols (void)
{
static gboolean success = FALSE;
if (success)
return TRUE;
/* We don't link against libGL directly because cogl may want to
* use something else. This assumes that cogl has been initialized
* and dynamically loaded libGL at this point.
*/
if (!load_gl_symbol ("glGetIntegerv", (void **) &meta_gl_get_integerv))
goto out;
if (!load_gl_symbol ("glGetStringi", (void **) &meta_gl_get_stringi))
goto out;
if (!check_gl_extensions ())
{
meta_verbose ("MetaSyncRing: couldn't find required GL extensions\n");
goto out;
}
if (!load_gl_symbol ("glDeleteSync", (void **) &meta_gl_delete_sync))
goto out;
if (!load_gl_symbol ("glClientWaitSync", (void **) &meta_gl_client_wait_sync))
goto out;
if (!load_gl_symbol ("glWaitSync", (void **) &meta_gl_wait_sync))
goto out;
if (!load_gl_symbol ("glImportSyncEXT", (void **) &meta_gl_import_sync))
goto out;
if (!load_gl_symbol ("glGetError", (void **) &meta_gl_get_error))
goto out;
if (!load_gl_symbol ("glIsSync", (void **) &meta_gl_is_sync))
goto out;
success = TRUE;
out:
return success;
}
static void
print_gl_error (void)
{
GLenum e;
switch (e = meta_gl_get_error ())
{
case GL_NO_ERROR:
meta_warning ("GL_NO_ERROR\n");
break;
case GL_INVALID_ENUM:
meta_warning ("GL_INVALID_ENUM\n");
break;
case GL_INVALID_VALUE:
meta_warning ("GL_INVALID_VALUE\n");
break;
case GL_INVALID_OPERATION:
meta_warning ("GL_INVALID_OPERATION\n");
break;
case GL_INVALID_FRAMEBUFFER_OPERATION:
meta_warning ("GL_INVALID_FRAMEBUFFER_OPERATION\n");
break;
case GL_OUT_OF_MEMORY:
meta_warning ("GL_OUT_OF_MEMORY\n");
break;
case GL_STACK_OVERFLOW:
meta_warning ("GL_STACK_OVERFLOW\n");
break;
case GL_STACK_UNDERFLOW:
meta_warning ("GL_STACK_UNDERFLOW\n");
break;
default:
meta_warning ("GL error 0x%x\n", e);
break;
}
}
static void
meta_sync_insert (MetaSync *self)
{
g_return_if_fail (self->state == META_SYNC_STATE_READY);
XSyncTriggerFence (self->xdisplay, self->xfence);
XFlush (self->xdisplay);
meta_gl_wait_sync (self->glsync, 0, GL_TIMEOUT_IGNORED);
self->state = META_SYNC_STATE_WAITING;
}
static GLenum
meta_sync_check_update_finished (MetaSync *self,
GLuint64 timeout)
{
GLenum status = GL_WAIT_FAILED;
switch (self->state)
{
case META_SYNC_STATE_DONE:
status = GL_ALREADY_SIGNALED;
break;
case META_SYNC_STATE_WAITING:
status = meta_gl_client_wait_sync (self->glsync, 0, timeout);
if (status == GL_ALREADY_SIGNALED || status == GL_CONDITION_SATISFIED)
self->state = META_SYNC_STATE_DONE;
break;
default:
break;
}
g_warn_if_fail (status != GL_WAIT_FAILED);
return status;
}
static void
meta_sync_reset (MetaSync *self)
{
XSyncAlarmAttributes attrs;
int overflow;
g_return_if_fail (self->state == META_SYNC_STATE_DONE);
XSyncResetFence (self->xdisplay, self->xfence);
attrs.trigger.wait_value = self->next_counter_value;
XSyncChangeAlarm (self->xdisplay, self->xalarm, XSyncCAValue, &attrs);
XSyncSetCounter (self->xdisplay, self->xcounter, self->next_counter_value);
XSyncValueAdd (&self->next_counter_value,
self->next_counter_value,
SYNC_VALUE_ONE,
&overflow);
self->state = META_SYNC_STATE_RESET_PENDING;
}
static void
meta_sync_handle_event (MetaSync *self,
XSyncAlarmNotifyEvent *event)
{
g_return_if_fail (event->alarm == self->xalarm);
g_return_if_fail (self->state == META_SYNC_STATE_RESET_PENDING);
self->state = META_SYNC_STATE_READY;
}
static MetaSync *
meta_sync_new (Display *xdisplay)
{
MetaSync *self;
XSyncAlarmAttributes attrs;
self = g_malloc0 (sizeof (MetaSync));
self->xdisplay = xdisplay;
self->xfence = XSyncCreateFence (xdisplay, DefaultRootWindow (xdisplay), FALSE);
meta_warning ("created X fence 0x%x\n", self->xfence);
self->glsync = meta_gl_import_sync (GL_SYNC_X11_FENCE_EXT, self->xfence, 0);
print_gl_error ();
self->xcounter = XSyncCreateCounter (xdisplay, SYNC_VALUE_ZERO);
attrs.trigger.counter = self->xcounter;
attrs.trigger.value_type = XSyncAbsolute;
attrs.trigger.wait_value = SYNC_VALUE_ONE;
attrs.trigger.test_type = XSyncPositiveTransition;
attrs.events = TRUE;
self->xalarm = XSyncCreateAlarm (xdisplay,
XSyncCACounter |
XSyncCAValueType |
XSyncCAValue |
XSyncCATestType |
XSyncCAEvents,
&attrs);
XSyncIntToValue (&self->next_counter_value, 1);
self->state = META_SYNC_STATE_READY;
return self;
}
static Bool
alarm_event_predicate (Display *dpy,
XEvent *event,
XPointer data)
{
int xsync_event_base;
MetaSyncRing *ring = meta_sync_ring_get ();
if (!ring)
return False;
xsync_event_base = meta_display_get_sync_event_base (ring->display);
if (event->type == xsync_event_base + XSyncAlarmNotify)
{
if (((MetaSync *) data)->xalarm == ((XSyncAlarmNotifyEvent *) event)->alarm)
return True;
}
return False;
}
static void
meta_sync_free (MetaSync *self)
{
/* When our assumptions don't hold, something has gone wrong but we
* don't know what, so we reboot the ring. While doing that, we
* trigger fences before deleting them to try to get ourselves out
* of a potentially stuck GPU state.
*/
switch (self->state)
{
case META_SYNC_STATE_WAITING:
case META_SYNC_STATE_DONE:
/* nothing to do */
break;
case META_SYNC_STATE_RESET_PENDING:
{
XEvent event;
XIfEvent (self->xdisplay, &event, alarm_event_predicate, (XPointer) self);
meta_sync_handle_event (self, (XSyncAlarmNotifyEvent *) &event);
}
/* fall through */
case META_SYNC_STATE_READY:
XSyncTriggerFence (self->xdisplay, self->xfence);
XFlush (self->xdisplay);
break;
default:
break;
}
meta_gl_delete_sync (self->glsync);
XSyncDestroyFence (self->xdisplay, self->xfence);
XSyncDestroyCounter (self->xdisplay, self->xcounter);
XSyncDestroyAlarm (self->xdisplay, self->xalarm);
g_free (self);
}
gboolean
meta_sync_ring_init (MetaDisplay *display)
{
guint i;
MetaSyncRing *ring = meta_sync_ring_get ();
if (!ring)
return FALSE;
g_return_val_if_fail (display != NULL, FALSE);
g_return_val_if_fail (ring->display == NULL, FALSE);
if (!load_required_symbols ())
return FALSE;
if (!meta_display_has_sync (display))
return FALSE;
print_gl_error ();
XSyncIntToValue (&SYNC_VALUE_ZERO, 0);
XSyncIntToValue (&SYNC_VALUE_ONE, 1);
ring->display = display;
ring->alarm_to_sync = g_hash_table_new (NULL, NULL);
for (i = 0; i < NUM_SYNCS; ++i)
{
MetaSync *sync = meta_sync_new (meta_display_get_xdisplay (display));
ring->syncs_array[i] = sync;
g_hash_table_replace (ring->alarm_to_sync, (gpointer) sync->xalarm, sync);
}
ring->current_sync_idx = 0;
ring->current_sync = ring->syncs_array[0];
ring->warmup_syncs = 0;
return TRUE;
}
void
meta_sync_ring_destroy (void)
{
guint i;
MetaSyncRing *ring = meta_sync_ring_get ();
if (!ring)
return;
g_return_if_fail (ring->display != NULL);
ring->current_sync_idx = 0;
ring->current_sync = NULL;
ring->warmup_syncs = 0;
for (i = 0; i < NUM_SYNCS; ++i)
meta_sync_free (ring->syncs_array[i]);
g_hash_table_destroy (ring->alarm_to_sync);
ring->display = NULL;
}
static gboolean
meta_sync_ring_reboot (MetaDisplay *display)
{
MetaSyncRing *ring = meta_sync_ring_get ();
if (!ring)
return FALSE;
meta_sync_ring_destroy ();
ring->reboots += 1;
if (!meta_sync_ring_get ())
{
meta_warning ("MetaSyncRing: Too many reboots -- disabling\n");
return FALSE;
}
return meta_sync_ring_init (display);
}
gboolean
meta_sync_ring_after_frame (void)
{
MetaSyncRing *ring = meta_sync_ring_get ();
if (!ring)
return FALSE;
g_return_if_fail (ring->display != NULL);
if (ring->warmup_syncs >= NUM_SYNCS / 2)
{
guint reset_sync_idx = (ring->current_sync_idx + NUM_SYNCS - (NUM_SYNCS / 2)) % NUM_SYNCS;
MetaSync *sync_to_reset = ring->syncs_array[reset_sync_idx];
GLenum status = meta_sync_check_update_finished (sync_to_reset, 0);
if (status == GL_TIMEOUT_EXPIRED)
{
meta_warning ("MetaSyncRing: We should never wait for a sync -- add more syncs?\n");
status = meta_sync_check_update_finished (sync_to_reset, MAX_SYNC_WAIT_TIME);
}
if (status != GL_ALREADY_SIGNALED && status != GL_CONDITION_SATISFIED)
{
meta_warning ("MetaSyncRing: Timed out waiting for sync object.\n");
return meta_sync_ring_reboot (ring->display);
}
meta_sync_reset (sync_to_reset);
}
else
{
ring->warmup_syncs += 1;
}
ring->current_sync_idx += 1;
ring->current_sync_idx %= NUM_SYNCS;
ring->current_sync = ring->syncs_array[ring->current_sync_idx];
return TRUE;
}
gboolean
meta_sync_ring_insert_wait (void)
{
MetaSyncRing *ring = meta_sync_ring_get ();
if (!ring)
return FALSE;
g_return_if_fail (ring->display != NULL);
if (ring->current_sync->state != META_SYNC_STATE_READY)
{
meta_warning ("MetaSyncRing: Sync object is not ready -- were events handled properly?\n");
if (!meta_sync_ring_reboot (ring->display))
return FALSE;
}
meta_sync_insert (ring->current_sync);
return TRUE;
}
void
meta_sync_ring_handle_event (XSyncAlarmNotifyEvent *event)
{
MetaSync *sync;
MetaSyncRing *ring = meta_sync_ring_get ();
if (!ring)
return;
g_return_if_fail (ring->display != NULL);
sync = g_hash_table_lookup (ring->alarm_to_sync, (gpointer) event->alarm);
if (sync)
meta_sync_handle_event (sync, event);
}

View File

@@ -1,17 +0,0 @@
#ifndef _META_SYNC_RING_H_
#define _META_SYNC_RING_H_
#include <glib.h>
#include <X11/Xlib.h>
#include <X11/extensions/sync.h>
#include <meta/display.h>
gboolean meta_sync_ring_init (MetaDisplay *dpy);
void meta_sync_ring_destroy (void);
gboolean meta_sync_ring_after_frame (void);
gboolean meta_sync_ring_insert_wait (void);
void meta_sync_ring_handle_event (XSyncAlarmNotifyEvent *event);
#endif /* _META_SYNC_RING_H_ */

View File

@@ -378,8 +378,8 @@ texture_tower_create_texture (MetaTextureTower *tower,
}
static void
texture_tower_revalidate_fbo (MetaTextureTower *tower,
int level)
texture_tower_revalidate (MetaTextureTower *tower,
int level)
{
CoglTexture *source_texture = tower->textures[level - 1];
int source_texture_width = cogl_texture_get_width (source_texture);
@@ -425,13 +425,9 @@ texture_tower_revalidate_fbo (MetaTextureTower *tower,
(2. * invalid->y2) / source_texture_height);
cogl_object_unref (pipeline);
}
static void
texture_tower_revalidate (MetaTextureTower *tower,
int level)
{
texture_tower_revalidate_fbo (tower, level);
tower->invalid[level].x1 = tower->invalid[level].x2 = 0;
tower->invalid[level].y1 = tower->invalid[level].y2 = 0;
}
/**

View File

@@ -51,8 +51,7 @@ void meta_window_actor_update_shape (MetaWindowActor *self);
void meta_window_actor_update_opacity (MetaWindowActor *self);
void meta_window_actor_mapped (MetaWindowActor *self);
void meta_window_actor_unmapped (MetaWindowActor *self);
void meta_window_actor_set_updates_frozen (MetaWindowActor *self,
gboolean updates_frozen);
void meta_window_actor_sync_updates_frozen (MetaWindowActor *self);
void meta_window_actor_queue_frame_drawn (MetaWindowActor *self,
gboolean no_delay_frame);

View File

@@ -32,9 +32,17 @@
#include "meta-surface-actor.h"
#include "meta-surface-actor-x11.h"
#include "meta-surface-actor-wayland.h"
#ifdef HAVE_WAYLAND
#include "meta-surface-actor-wayland.h"
#include "wayland/meta-wayland-surface.h"
#endif
typedef enum {
INITIALLY_FROZEN,
DRAWING_FIRST_FRAME,
EMITTED_FIRST_FRAME
} FirstFrameState;
struct _MetaWindowActorPrivate
{
@@ -70,7 +78,7 @@ struct _MetaWindowActorPrivate
gint64 frame_drawn_time;
guint repaint_scheduled_id;
guint allocation_changed_id;
guint size_changed_id;
/*
* These need to be counters rather than flags, since more plugins
@@ -78,6 +86,7 @@ struct _MetaWindowActorPrivate
* might be dubious, but we have to at least handle it correctly.
*/
gint minimize_in_progress;
gint unminimize_in_progress;
gint maximize_in_progress;
gint unmaximize_in_progress;
gint map_in_progress;
@@ -104,6 +113,7 @@ struct _MetaWindowActorPrivate
guint no_shadow : 1;
guint updates_frozen : 1;
guint first_frame_state : 2; /* FirstFrameState */
};
typedef struct _FrameData FrameData;
@@ -115,6 +125,14 @@ struct _FrameData
gint64 frame_drawn_time;
};
enum
{
FIRST_FRAME,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };
enum
{
PROP_META_WINDOW = 1,
@@ -181,6 +199,31 @@ meta_window_actor_class_init (MetaWindowActorClass *klass)
actor_class->paint = meta_window_actor_paint;
actor_class->get_paint_volume = meta_window_actor_get_paint_volume;
/**
* MetaWindowActor::first-frame:
* @actor: the #MetaWindowActor instance
*
* The ::first-frame signal will be emitted the first time a frame
* of window contents has been drawn by the application and Mutter
* has had the chance to drawn that frame to the screen. If the
* window starts off initially hidden, obscured, or on on a
* different workspace, the ::first-frame signal will be emitted
* even though the user doesn't see the contents.
*
* MetaDisplay::window-created is a good place to connect to this
* signal - at that point, the MetaWindowActor for the window
* exists, but the window has reliably not yet been drawn.
* Connecting to an existing window that has already been drawn to
* the screen is not useful.
*/
signals[FIRST_FRAME] =
g_signal_new ("first-frame",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 0);
pspec = g_param_spec_object ("meta-window",
"MetaWindow",
"The displayed MetaWindow",
@@ -232,12 +275,11 @@ window_appears_focused_notify (MetaWindow *mw,
}
static void
surface_allocation_changed_notify (ClutterActor *actor,
const ClutterActorBox *allocation,
ClutterAllocationFlags flags,
MetaWindowActor *self)
surface_size_changed (MetaSurfaceActor *actor,
gpointer user_data)
{
meta_window_actor_sync_actor_geometry (self, FALSE);
MetaWindowActor *self = META_WINDOW_ACTOR (user_data);
meta_window_actor_update_shape (self);
}
@@ -306,6 +348,9 @@ meta_window_actor_thaw (MetaWindowActor *self)
if (priv->freeze_count > 0)
return;
if (priv->first_frame_state == INITIALLY_FROZEN)
priv->first_frame_state = DRAWING_FIRST_FRAME;
if (priv->surface)
meta_surface_actor_set_frozen (priv->surface, FALSE);
@@ -326,9 +371,8 @@ set_surface (MetaWindowActor *self,
if (priv->surface)
{
g_signal_handler_disconnect (priv->surface, priv->repaint_scheduled_id);
g_signal_handler_disconnect (priv->surface, priv->size_changed_id);
priv->repaint_scheduled_id = 0;
g_signal_handler_disconnect (priv->surface, priv->allocation_changed_id);
priv->allocation_changed_id = 0;
clutter_actor_remove_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface));
g_object_unref (priv->surface);
}
@@ -340,14 +384,17 @@ set_surface (MetaWindowActor *self,
g_object_ref_sink (priv->surface);
priv->repaint_scheduled_id = g_signal_connect (priv->surface, "repaint-scheduled",
G_CALLBACK (surface_repaint_scheduled), self);
priv->allocation_changed_id = g_signal_connect (priv->surface, "allocation-changed",
G_CALLBACK (surface_allocation_changed_notify), self);
priv->size_changed_id = g_signal_connect (priv->surface, "size-changed",
G_CALLBACK (surface_size_changed), self);
clutter_actor_add_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface));
/* If the previous surface actor was frozen, start out
* frozen as well... */
meta_surface_actor_set_frozen (priv->surface, priv->freeze_count > 0);
if (!is_frozen (self) && priv->first_frame_state == INITIALLY_FROZEN)
priv->first_frame_state = DRAWING_FIRST_FRAME;
meta_window_actor_update_shape (self);
}
}
@@ -359,9 +406,12 @@ meta_window_actor_update_surface (MetaWindowActor *self)
MetaWindow *window = priv->window;
MetaSurfaceActor *surface_actor;
#ifdef HAVE_WAYLAND
if (window->surface)
surface_actor = window->surface->surface_actor;
else if (!meta_is_wayland_compositor ())
else
#endif
if (!meta_is_wayland_compositor ())
surface_actor = meta_surface_actor_x11_new (window);
else
surface_actor = NULL;
@@ -551,6 +601,7 @@ meta_window_actor_get_shape_bounds (MetaWindowActor *self,
cairo_region_get_extents (priv->shape_region, bounds);
#ifdef HAVE_WAYLAND
if (META_IS_SURFACE_ACTOR_WAYLAND (priv->surface))
{
double scale = priv->surface ?
@@ -560,6 +611,7 @@ meta_window_actor_get_shape_bounds (MetaWindowActor *self,
bounds->width *= scale;
bounds->height *= scale;
}
#endif
}
static void
@@ -667,25 +719,16 @@ meta_window_actor_get_paint_volume (ClutterActor *actor,
{
MetaWindowActor *self = META_WINDOW_ACTOR (actor);
MetaWindowActorPrivate *priv = self->priv;
cairo_rectangle_int_t unobscured_bounds, bounds;
gboolean appears_focused = meta_window_appears_focused (priv->window);
ClutterVertex origin;
/* The paint volume is computed before paint functions are called
* so our bounds might not be updated yet. Force an update. */
meta_window_actor_handle_updates (self);
meta_window_actor_get_shape_bounds (self, &bounds);
if (priv->surface)
{
if (meta_surface_actor_get_unobscured_bounds (priv->surface, &unobscured_bounds))
gdk_rectangle_intersect (&bounds, &unobscured_bounds, &bounds);
}
if (appears_focused ? priv->focused_shadow : priv->unfocused_shadow)
{
cairo_rectangle_int_t shadow_bounds;
ClutterActorBox shadow_box;
/* We could compute an full clip region as we do for the window
* texture, but the shadow is relatively cheap to draw, and
@@ -695,16 +738,24 @@ meta_window_actor_get_paint_volume (ClutterActor *actor,
*/
meta_window_actor_get_shadow_bounds (self, appears_focused, &shadow_bounds);
gdk_rectangle_union (&bounds, &shadow_bounds, &bounds);
shadow_box.x1 = shadow_bounds.x;
shadow_box.x2 = shadow_bounds.x + shadow_bounds.width;
shadow_box.y1 = shadow_bounds.y;
shadow_box.y2 = shadow_bounds.y + shadow_bounds.height;
clutter_paint_volume_union_box (volume, &shadow_box);
}
origin.x = bounds.x;
origin.y = bounds.y;
origin.z = 0.0f;
clutter_paint_volume_set_origin (volume, &origin);
if (priv->surface)
{
const ClutterPaintVolume *child_volume;
clutter_paint_volume_set_width (volume, bounds.width);
clutter_paint_volume_set_height (volume, bounds.height);
child_volume = clutter_actor_get_transformed_paint_volume (CLUTTER_ACTOR (priv->surface), actor);
if (!child_volume)
return FALSE;
clutter_paint_volume_union (volume, child_volume);
}
return TRUE;
}
@@ -746,9 +797,11 @@ meta_window_actor_has_shadow (MetaWindowActor *self)
return FALSE;
/*
* Add shadows to override redirect windows (e.g., Gtk menus).
* Add shadows to override redirect windows on X11 unless the toolkit
* indicates that it is handling shadows itself (e.g., Gtk menus).
*/
if (priv->window->override_redirect)
if (priv->window->override_redirect &&
!priv->window->has_custom_frame_extents)
return TRUE;
return FALSE;
@@ -851,7 +904,7 @@ queue_send_frame_messages_timeout (MetaWindowActor *self)
outputs = meta_monitor_manager_get_outputs (monitor_manager, &n_outputs);
for (i = 0; i < n_outputs; i++)
{
if (outputs[i].output_id == window->monitor->output_id && outputs[i].crtc)
if (outputs[i].winsys_id == window->monitor->winsys_id && outputs[i].crtc)
{
refresh_rate = outputs[i].crtc->current_mode->refresh_rate;
break;
@@ -960,6 +1013,9 @@ start_simple_effect (MetaWindowActor *self,
case META_PLUGIN_MINIMIZE:
counter = &priv->minimize_in_progress;
break;
case META_PLUGIN_UNMINIMIZE:
counter = &priv->unminimize_in_progress;
break;
case META_PLUGIN_MAP:
counter = &priv->map_in_progress;
break;
@@ -1030,6 +1086,16 @@ meta_window_actor_effect_completed (MetaWindowActor *self,
}
}
break;
case META_PLUGIN_UNMINIMIZE:
{
priv->unminimize_in_progress--;
if (priv->unminimize_in_progress < 0)
{
g_warning ("Error in unminimize accounting.");
priv->unminimize_in_progress = 0;
}
}
break;
case META_PLUGIN_MAP:
/*
* Make sure that the actor is at the correct place in case
@@ -1150,7 +1216,7 @@ meta_window_actor_sync_actor_geometry (MetaWindowActor *self,
MetaWindowActorPrivate *priv = self->priv;
MetaRectangle window_rect;
meta_window_get_input_rect (priv->window, &window_rect);
meta_window_get_buffer_rect (priv->window, &window_rect);
/* When running as a Wayland compositor we catch size changes when new
* buffers are attached */
@@ -1195,8 +1261,7 @@ meta_window_actor_show (MetaWindowActor *self,
event = META_PLUGIN_MAP;
break;
case META_COMP_EFFECT_UNMINIMIZE:
/* FIXME: should have META_PLUGIN_UNMINIMIZE */
event = META_PLUGIN_MAP;
event = META_PLUGIN_UNMINIMIZE;
break;
case META_COMP_EFFECT_NONE:
break;
@@ -1324,7 +1389,12 @@ meta_window_actor_new (MetaWindow *window)
priv = self->priv;
meta_window_actor_set_updates_frozen (self, meta_window_updates_are_frozen (priv->window));
meta_window_actor_sync_updates_frozen (self);
if (is_frozen (self))
priv->first_frame_state = INITIALLY_FROZEN;
else
priv->first_frame_state = DRAWING_FIRST_FRAME;
/* If a window doesn't start off with updates frozen, we should
* we should send a _NET_WM_FRAME_DRAWN immediately after the first drawn.
@@ -1594,6 +1664,8 @@ build_and_scan_frame_mask (MetaWindowActor *self,
cairo_rectangle_int_t *client_area,
cairo_region_t *shape_region)
{
ClutterBackend *backend = clutter_get_default_backend ();
CoglContext *ctx = clutter_backend_get_cogl_context (backend);
MetaWindowActorPrivate *priv = self->priv;
guchar *mask_data;
guint tex_width, tex_height;
@@ -1656,10 +1728,7 @@ build_and_scan_frame_mask (MetaWindowActor *self,
if (meta_texture_rectangle_check (paint_tex))
{
ClutterBackend *backend = clutter_get_default_backend ();
CoglContext *context = clutter_backend_get_cogl_context (backend);
mask_texture = COGL_TEXTURE (cogl_texture_rectangle_new_with_size (context, tex_width, tex_height));
mask_texture = COGL_TEXTURE (cogl_texture_rectangle_new_with_size (ctx, tex_width, tex_height));
cogl_texture_set_components (mask_texture, COGL_TEXTURE_COMPONENTS_A);
cogl_texture_set_region (mask_texture,
0, 0, /* src_x/y */
@@ -1671,15 +1740,9 @@ build_and_scan_frame_mask (MetaWindowActor *self,
}
else
{
/* Note: we don't allow slicing for this texture because we
* need to use it with multi-texturing which doesn't support
* sliced textures */
mask_texture = cogl_texture_new_from_data (tex_width, tex_height,
COGL_TEXTURE_NO_SLICING,
COGL_PIXEL_FORMAT_A_8,
COGL_PIXEL_FORMAT_ANY,
stride,
mask_data);
mask_texture = COGL_TEXTURE (cogl_texture_2d_new_from_data (ctx, tex_width, tex_height,
COGL_PIXEL_FORMAT_A_8,
stride, mask_data, NULL));
}
meta_shaped_texture_set_mask_texture (stex, mask_texture);
@@ -1908,6 +1971,12 @@ meta_window_actor_post_paint (MetaWindowActor *self)
do_send_frame_drawn (self, priv->frames->data);
priv->needs_frame_drawn = FALSE;
}
if (priv->first_frame_state == DRAWING_FIRST_FRAME)
{
priv->first_frame_state = EMITTED_FIRST_FRAME;
g_signal_emit (self, signals[FIRST_FRAME], 0);
}
}
static void
@@ -2020,7 +2089,7 @@ meta_window_actor_update_opacity (MetaWindowActor *self)
clutter_actor_set_opacity (CLUTTER_ACTOR (priv->surface), window->opacity);
}
void
static void
meta_window_actor_set_updates_frozen (MetaWindowActor *self,
gboolean updates_frozen)
{
@@ -2037,3 +2106,12 @@ meta_window_actor_set_updates_frozen (MetaWindowActor *self,
meta_window_actor_thaw (self);
}
}
void
meta_window_actor_sync_updates_frozen (MetaWindowActor *self)
{
MetaWindowActorPrivate *priv = self->priv;
MetaWindow *window = priv->window;
meta_window_actor_set_updates_frozen (self, meta_window_updates_are_frozen (window));
}

View File

@@ -1,12 +1,22 @@
pkglibdir=@MUTTER_PLUGIN_DIR@
pkglibdir = $(MUTTER_PLUGIN_DIR)
INCLUDES=@MUTTER_CFLAGS@ -I $(top_srcdir)/src -DMUTTER_LIBEXECDIR=\"$(libexecdir)\" -DHOST_ALIAS=\"@HOST_ALIAS@\" -DMUTTER_LOCALEDIR=\"$(prefix)/@DATADIRNAME@/locale\" -DMUTTER_PKGDATADIR=\"$(pkgdatadir)\" -DMUTTER_DATADIR=\"$(datadir)\" -DG_LOG_DOMAIN=\"mutter\" -DSN_API_NOT_YET_FROZEN=1 -DMUTTER_MAJOR_VERSION=$(MUTTER_MAJOR_VERSION) -DMUTTER_MINOR_VERSION=$(MUTTER_MINOR_VERSION) -DMUTTER_MICRO_VERSION=$(MUTTER_MICRO_VERSION) -DMUTTER_PLUGIN_API_VERSION=$(MUTTER_PLUGIN_API_VERSION) -DMUTTER_PLUGIN_DIR=\"@MUTTER_PLUGIN_DIR@\"
AM_CPPFLAGS = \
$(MUTTER_CFLAGS) \
-I$(top_builddir)/src \
-I$(top_srcdir)/src \
-DMUTTER_LIBEXECDIR=\"$(libexecdir)\" \
-DMUTTER_LOCALEDIR=\"$(localedir)\" \
-DMUTTER_PKGDATADIR=\"$(pkgdatadir)\" \
-DMUTTER_DATADIR=\"$(datadir)\" \
-DG_LOG_DOMAIN=\"mutter\" \
-DSN_API_NOT_YET_FROZEN=1 \
-DMUTTER_PLUGIN_DIR=\"$(MUTTER_PLUGIN_DIR)\"
default_la_CFLAGS = -fPIC
default_la_SOURCES = default.c
default_la_LDFLAGS = -module -avoid-version -no-undefined
default_la_LIBADD = @CLUTTER_LIBS@
default_la_LIBADD = $(CLUTTER_LIBS)
pkglib_LTLIBRARIES = default.la

View File

@@ -69,12 +69,9 @@
*
* If the configure script found we had no XKB, this does not exist.
*/
#ifdef HAVE_XKB
static void
bell_flash_fullscreen (MetaDisplay *display,
XkbAnyEvent *xkb_ev)
bell_flash_fullscreen (MetaDisplay *display)
{
g_assert (xkb_ev->xkb_type == XkbBellNotify);
meta_compositor_flash_screen (display->compositor, display->screen);
}
@@ -139,30 +136,17 @@ bell_flash_window_frame (MetaWindow *window)
* @display: The display the bell event came in on
* @xkb_ev: The bell event we just received
*
* Flashes the frame of the focussed window. If there is no focussed window,
* Flashes the frame of the focused window. If there is no focused window,
* flashes the screen.
*/
static void
bell_flash_frame (MetaDisplay *display,
XkbAnyEvent *xkb_ev)
MetaWindow *window)
{
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;
}
if (window && window->frame)
{
bell_flash_window_frame (window);
}
else /* revert to fullscreen flash if there's no focussed window */
{
bell_flash_fullscreen (display, xkb_ev);
}
bell_flash_window_frame (window);
else
bell_flash_fullscreen (display);
}
/**
@@ -172,69 +156,73 @@ bell_flash_frame (MetaDisplay *display,
*
* Gives the user some kind of visual bell substitute, in response to a
* bell event. What this is depends on the "visual bell type" pref.
*
* If the configure script found we had no XKB, this does not exist.
*/
/*
* Bug: This should be merged with meta_bell_notify().
*/
static void
bell_visual_notify (MetaDisplay *display,
XkbAnyEvent *xkb_ev)
MetaWindow *window)
{
switch (meta_prefs_get_visual_bell_type ())
{
case G_DESKTOP_VISUAL_BELL_FULLSCREEN_FLASH:
bell_flash_fullscreen (display, xkb_ev);
bell_flash_fullscreen (display);
break;
case G_DESKTOP_VISUAL_BELL_FRAME_FLASH:
bell_flash_frame (display, xkb_ev); /* does nothing yet */
bell_flash_frame (display, window);
break;
}
}
static gboolean
bell_audible_notify (MetaDisplay *display,
MetaWindow *window)
{
#ifdef HAVE_LIBCANBERRA
ca_proplist *p;
int res;
ca_proplist_create (&p);
ca_proplist_sets (p, CA_PROP_EVENT_ID, "bell-window-system");
ca_proplist_sets (p, CA_PROP_EVENT_DESCRIPTION, _("Bell event"));
ca_proplist_sets (p, CA_PROP_CANBERRA_CACHE_CONTROL, "permanent");
if (window)
{
ca_proplist_sets (p, CA_PROP_WINDOW_NAME, window->title);
ca_proplist_setf (p, CA_PROP_WINDOW_X11_XID, "%lu", (unsigned long)window->xwindow);
ca_proplist_sets (p, CA_PROP_APPLICATION_NAME, window->res_name);
ca_proplist_setf (p, CA_PROP_APPLICATION_PROCESS_ID, "%d", window->net_wm_pid);
}
res = ca_context_play_full (ca_gtk_context_get (), 1, p, NULL, NULL);
ca_proplist_destroy (p);
return res == CA_SUCCESS || res == CA_ERROR_DISABLED;
#endif /* HAVE_LIBCANBERRA */
return FALSE;
}
void
meta_bell_notify (MetaDisplay *display,
XkbAnyEvent *xkb_ev)
{
MetaWindow *window;
XkbBellNotifyEvent *xkb_bell_event = (XkbBellNotifyEvent*) xkb_ev;
window = meta_display_lookup_x_window (display, xkb_bell_event->window);
if (!window && display->focus_window && display->focus_window->frame)
window = display->focus_window;
/* flash something */
if (meta_prefs_get_visual_bell ())
bell_visual_notify (display, xkb_ev);
bell_visual_notify (display, window);
#ifdef HAVE_LIBCANBERRA
if (meta_prefs_bell_is_audible ())
{
ca_proplist *p;
XkbBellNotifyEvent *xkb_bell_event = (XkbBellNotifyEvent*) xkb_ev;
MetaWindow *window;
int res;
ca_proplist_create (&p);
ca_proplist_sets (p, CA_PROP_EVENT_ID, "bell-window-system");
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;
if (window)
if (!bell_audible_notify (display, window))
{
ca_proplist_sets (p, CA_PROP_WINDOW_NAME, window->title);
ca_proplist_setf (p, CA_PROP_WINDOW_X11_XID, "%lu", (unsigned long)window->xwindow);
ca_proplist_sets (p, CA_PROP_APPLICATION_NAME, window->res_name);
ca_proplist_setf (p, CA_PROP_APPLICATION_PROCESS_ID, "%d", window->net_wm_pid);
}
/* First, we try to play a real sound ... */
res = ca_context_play_full (ca_gtk_context_get (), 1, p, NULL, NULL);
ca_proplist_destroy (p);
if (res != CA_SUCCESS && res != CA_ERROR_DISABLED)
{
/* ...and in case that failed we use the classic X11 bell. */
/* Force a classic bell if the libcanberra bell failed. */
XkbForceDeviceBell (display->xdisplay,
xkb_bell_event->device,
xkb_bell_event->bell_class,
@@ -242,14 +230,11 @@ meta_bell_notify (MetaDisplay *display,
xkb_bell_event->percent);
}
}
#endif /* HAVE_LIBCANBERRA */
}
#endif /* HAVE_XKB */
void
meta_bell_set_audible (MetaDisplay *display, gboolean audible)
{
#ifdef HAVE_XKB
#ifdef HAVE_LIBCANBERRA
/* When we are playing sounds using libcanberra support, we handle the
* bell whether its an audible bell or a visible bell */
@@ -262,13 +247,11 @@ meta_bell_set_audible (MetaDisplay *display, gboolean audible)
XkbUseCoreKbd,
XkbAudibleBellMask,
enable_system_bell ? XkbAudibleBellMask : 0);
#endif /* HAVE_XKB */
}
gboolean
meta_bell_init (MetaDisplay *display)
{
#ifdef HAVE_XKB
int xkb_base_error_type, xkb_opcode;
if (!XkbQueryExtension (display->xdisplay, &xkb_opcode,
@@ -298,20 +281,17 @@ meta_bell_init (MetaDisplay *display)
}
return TRUE;
}
#endif
return FALSE;
}
void
meta_bell_shutdown (MetaDisplay *display)
{
#ifdef HAVE_XKB
/* TODO: persist initial bell state in display, reset here */
XkbChangeEnabledControls (display->xdisplay,
XkbUseCoreKbd,
XkbAudibleBellMask,
XkbAudibleBellMask);
#endif
}
/**

View File

@@ -18,13 +18,10 @@
*/
#include <X11/Xlib.h>
#ifdef HAVE_XKB
#include <X11/XKBlib.h>
#endif
#include "display-private.h"
#include "frame.h"
#ifdef HAVE_XKB
/**
* meta_bell_notify:
* @display: The display the bell event came in on
@@ -37,7 +34,6 @@
* If the configure script found we had no XKB, this does not exist.
*/
void meta_bell_notify (MetaDisplay *display, XkbAnyEvent *xkb_ev);
#endif
/**
* meta_bell_set_audible:
@@ -61,12 +57,6 @@ void meta_bell_set_audible (MetaDisplay *display, gboolean audible);
* to send us bell notifications, and then also switching
* off the audible bell if we're using a visual one ourselves.
*
* Unlike most X extensions we use, we only initialise XKB here
* (rather than in main()). It's possible that XKB is not
* installed at all, but if that was known at build time
* we will have HAVE_XKB undefined, which will cause this
* function to be a no-op.
*
* \bug There is a line of code that's never run that tells
* XKB to reset the bell status after we quit. Bill H said
* (<http://bugzilla.gnome.org/show_bug.cgi?id=99886#c12>)

View File

@@ -546,6 +546,26 @@ compare_rect_areas (gconstpointer a, gconstpointer b)
return b_area - a_area; /* positive ret value denotes b > a, ... */
}
/* ... and another helper for get_minimal_spanning_set_for_region()... */
static gboolean
check_strut_align (MetaStrut *strut, const MetaRectangle *rect)
{
/* Check whether @strut actually aligns to the side of @rect it claims */
switch (strut->side)
{
case META_SIDE_TOP:
return BOX_TOP (strut->rect) <= BOX_TOP (*rect);
case META_SIDE_BOTTOM:
return BOX_BOTTOM (strut->rect) >= BOX_BOTTOM (*rect);
case META_SIDE_LEFT:
return BOX_LEFT (strut->rect) <= BOX_LEFT (*rect);
case META_SIDE_RIGHT:
return BOX_RIGHT (strut->rect) >= BOX_RIGHT (*rect);
default:
return FALSE;
}
}
/**
* meta_rectangle_get_minimal_spanning_set_for_region:
* @basic_rect: Input rectangle
@@ -630,7 +650,8 @@ meta_rectangle_get_minimal_spanning_set_for_region (
for (strut_iter = all_struts; strut_iter; strut_iter = strut_iter->next)
{
GList *rect_iter;
MetaRectangle *strut_rect = &((MetaStrut*)strut_iter->data)->rect;
MetaStrut *strut = (MetaStrut*)strut_iter->data;
MetaRectangle *strut_rect = &strut->rect;
tmp_list = ret;
ret = NULL;
@@ -638,7 +659,9 @@ meta_rectangle_get_minimal_spanning_set_for_region (
while (rect_iter)
{
MetaRectangle *rect = (MetaRectangle*) rect_iter->data;
if (!meta_rectangle_overlap (rect, strut_rect))
if (!meta_rectangle_overlap (strut_rect, rect) ||
!check_strut_align (strut, basic_rect))
ret = g_list_prepend (ret, rect);
else
{

View File

@@ -404,31 +404,6 @@ setup_constraint_info (ConstraintInfo *info,
meta_workspace_get_onmonitor_region (cur_workspace,
monitor_info->number);
/* Workaround braindead legacy apps that don't know how to
* fullscreen themselves properly - don't get fooled by
* windows which hide their titlebar when maximized or which are
* client decorated; that's not the same as fullscreen, even
* if there are no struts making the workarea smaller than
* the monitor.
*/
if (meta_prefs_get_force_fullscreen() &&
window->client_type != META_WINDOW_CLIENT_TYPE_WAYLAND &&
!window->hide_titlebar_when_maximized &&
(window->decorated || !meta_window_is_client_decorated (window)) &&
meta_rectangle_equal (new, &monitor_info->rect) &&
window->has_fullscreen_func &&
!window->fullscreen)
{
/*
meta_topic (META_DEBUG_GEOMETRY,
*/
meta_warning (
"Treating resize request of legacy application %s as a "
"fullscreen request\n",
window->desc);
meta_window_make_fullscreen_internal (window);
}
/* Log all this information for debugging */
meta_topic (META_DEBUG_GEOMETRY,
"Setting up constraint info:\n"
@@ -613,7 +588,7 @@ update_onscreen_requirements (MetaWindow *window,
window->require_fully_onscreen =
meta_rectangle_contained_in_region (info->usable_screen_region,
&info->current);
if (old ^ window->require_fully_onscreen)
if (old != window->require_fully_onscreen)
meta_topic (META_DEBUG_GEOMETRY,
"require_fully_onscreen for %s toggled to %s\n",
window->desc,
@@ -626,7 +601,7 @@ update_onscreen_requirements (MetaWindow *window,
window->require_on_single_monitor =
meta_rectangle_contained_in_region (info->usable_monitor_region,
&info->current);
if (old ^ window->require_on_single_monitor)
if (old != window->require_on_single_monitor)
meta_topic (META_DEBUG_GEOMETRY,
"require_on_single_monitor for %s toggled to %s\n",
window->desc,
@@ -645,7 +620,7 @@ update_onscreen_requirements (MetaWindow *window,
window->require_titlebar_visible =
meta_rectangle_overlaps_with_region (info->usable_screen_region,
&titlebar_rect);
if (old ^ window->require_titlebar_visible)
if (old != window->require_titlebar_visible)
meta_topic (META_DEBUG_GEOMETRY,
"require_titlebar_visible for %s toggled to %s\n",
window->desc,

View File

@@ -392,6 +392,22 @@ meta_core_show_window_menu (Display *xdisplay,
meta_window_show_menu (window, menu, root_x, root_y);
}
void
meta_core_show_window_menu_for_rect (Display *xdisplay,
Window frame_xwindow,
MetaWindowMenuType menu,
MetaRectangle *rect,
guint32 timestamp)
{
MetaWindow *window = get_window (xdisplay, frame_xwindow);
if (meta_prefs_get_raise_on_click ())
meta_window_raise (window);
meta_window_focus (window, timestamp);
meta_window_show_menu_for_rect (window, menu, rect);
}
const char*
meta_core_get_workspace_name_with_index (Display *xdisplay,
Window xroot,
@@ -479,46 +495,5 @@ meta_core_set_screen_cursor (Display *xdisplay,
void
meta_invalidate_default_icons (void)
{
MetaDisplay *display = meta_get_display ();
GSList *windows;
GSList *l;
if (display == NULL)
return; /* We can validly be called before the display is opened. */
windows = meta_display_list_windows (display, META_LIST_DEFAULT);
for (l = windows; l != NULL; l = l->next)
{
MetaWindow *window = (MetaWindow*)l->data;
if (window->icon_cache.origin == USING_FALLBACK_ICON)
{
meta_icon_cache_free (&(window->icon_cache));
meta_window_update_icon_now (window);
}
}
g_slist_free (windows);
}
void
meta_core_add_old_event_mask (Display *xdisplay,
Window xwindow,
XIEventMask *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);
/* XXX: Actually invalidate the icons when they're used. */
}

View File

@@ -26,6 +26,7 @@
/* Don't include core headers here */
#include <gdk/gdkx.h>
#include <meta/common.h>
#include <meta/boxes.h>
typedef enum
{
@@ -138,6 +139,12 @@ void meta_core_show_window_menu (Display *xdisplay,
int root_y,
guint32 timestamp);
void meta_core_show_window_menu_for_rect (Display *xdisplay,
Window frame_xwindow,
MetaWindowMenuType menu,
MetaRectangle *rect,
guint32 timestamp);
gboolean meta_core_begin_grab_op (Display *xdisplay,
Window frame_xwindow,
MetaGrabOp op,
@@ -162,8 +169,4 @@ void meta_core_set_screen_cursor (Display *xdisplay,
void meta_invalidate_default_icons (void);
void meta_core_add_old_event_mask (Display *xdisplay,
Window xwindow,
XIEventMask *mask);
#endif

View File

@@ -37,8 +37,6 @@
#include <stdlib.h>
#include <stdio.h>
#include "wayland/meta-wayland-surface.h"
static void
dialog_exited (GPid pid, int status, gpointer user_data)
{

View File

@@ -35,6 +35,7 @@
#include <meta/boxes.h>
#include <meta/display.h>
#include "keybindings-private.h"
#include "meta-gesture-tracker-private.h"
#include <meta/prefs.h>
#include <meta/barrier.h>
#include <clutter/clutter.h>
@@ -78,6 +79,24 @@ typedef enum {
META_TILE_MAXIMIZED
} MetaTileMode;
typedef enum {
/* Normal interaction where you're interacting with windows.
* Events go to windows normally. */
META_EVENT_ROUTE_NORMAL,
/* In a compositor grab operation. All events go to the
* compositor plugin. */
META_EVENT_ROUTE_COMPOSITOR_GRAB,
/* A Wayland application has a popup open. All events go to
* the Wayland application. */
META_EVENT_ROUTE_WAYLAND_POPUP,
/* In a window operation like moving or resizing. All events
* goes to MetaWindow, but not to the actual client window. */
META_EVENT_ROUTE_WINDOW_OP,
} MetaEventRoute;
struct _MetaDisplay
{
GObject parent_instance;
@@ -145,8 +164,6 @@ struct _MetaDisplay
GHashTable *xids;
GHashTable *wayland_windows;
int server_grab_count;
/* serials of leave/unmap events that may
* correspond to an enter event we should
* ignore
@@ -175,13 +192,12 @@ struct _MetaDisplay
guint autoraise_timeout_id;
MetaWindow* autoraise_window;
/* Alt+click button grabs */
ClutterModifierType window_grab_modifiers;
/* Event routing */
MetaEventRoute event_route;
/* current window operation */
MetaGrabOp grab_op;
MetaWindow *grab_window;
Window grab_xwindow;
int grab_button;
int grab_anchor_root_x;
int grab_anchor_root_y;
@@ -202,34 +218,17 @@ struct _MetaDisplay
GTimeVal grab_last_moveresize_time;
MetaEdgeResistanceData *grab_edge_resistance_data;
unsigned int grab_last_user_action_was_snap;
guint32 grab_timestamp;
/* we use property updates as sentinels for certain window focus events
* to avoid some race conditions on EnterNotify events
*/
int sentinel_counter;
#ifdef HAVE_XKB
int xkb_base_event_type;
guint32 last_bell_time;
#endif
int grab_resize_timeout_id;
/* Keybindings stuff */
GHashTable *key_bindings;
GHashTable *key_bindings_index;
int min_keycode;
int max_keycode;
KeySym *keymap;
int keysyms_per_keycode;
unsigned int ignored_modifier_mask;
unsigned int hyper_mask;
unsigned int super_mask;
unsigned int meta_mask;
MetaKeyCombo overlay_key_combo;
gboolean overlay_key_only_pressed;
MetaKeyCombo *iso_next_group_combos;
int n_iso_next_group_combos;
MetaKeyBindingManager key_binding_manager;
/* Monitor cache */
unsigned int monitor_cache_invalidated : 1;
@@ -254,6 +253,9 @@ struct _MetaDisplay
/* Managed by compositor.c */
MetaCompositor *compositor;
MetaGestureTracker *gesture_tracker;
ClutterEventSequence *pointer_emulating_sequence;
int composite_event_base;
int composite_error_base;
int composite_major_version;
@@ -312,8 +314,6 @@ struct _MetaDisplayClass
gboolean meta_display_open (void);
void meta_display_close (MetaDisplay *display,
guint32 timestamp);
void meta_display_grab (MetaDisplay *display);
void meta_display_ungrab (MetaDisplay *display);
void meta_display_unmanage_windows_for_screen (MetaDisplay *display,
MetaScreen *screen,
@@ -398,14 +398,8 @@ int meta_resize_gravity_from_grab_op (MetaGrabOp op);
gboolean meta_grab_op_is_moving (MetaGrabOp op);
gboolean meta_grab_op_is_resizing (MetaGrabOp op);
gboolean meta_grab_op_is_moving_or_resizing (MetaGrabOp op);
gboolean meta_grab_op_is_mouse (MetaGrabOp op);
gboolean meta_grab_op_is_keyboard (MetaGrabOp op);
gboolean meta_grab_op_should_block_wayland (MetaGrabOp op);
void meta_display_devirtualize_modifiers (MetaDisplay *display,
MetaVirtualModifier modifiers,
unsigned int *mask);
void meta_display_increment_focus_sentinel (MetaDisplay *display);
void meta_display_decrement_focus_sentinel (MetaDisplay *display);
@@ -443,4 +437,20 @@ void meta_display_sanity_check_timestamps (MetaDisplay *display,
gboolean meta_display_timestamp_too_old (MetaDisplay *display,
guint32 *timestamp);
void meta_display_remove_pending_pings_for_window (MetaDisplay *display,
MetaWindow *window);
MetaGestureTracker * meta_display_get_gesture_tracker (MetaDisplay *display);
gboolean meta_display_show_restart_message (MetaDisplay *display,
const char *message);
gboolean meta_display_request_restart (MetaDisplay *display);
void meta_restart_init (void);
void meta_restart_finish (void);
void meta_display_cancel_touch (MetaDisplay *display);
gboolean meta_display_windows_are_interactable (MetaDisplay *display);
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -29,4 +29,3 @@ void meta_display_init_events (MetaDisplay *display);
void meta_display_free_events (MetaDisplay *display);
#endif

View File

@@ -26,14 +26,11 @@
#include "bell.h"
#include <meta/errors.h>
#include "keybindings-private.h"
#include "backends/x11/meta-backend-x11.h"
#define EVENT_MASK (SubstructureRedirectMask | \
StructureNotifyMask | SubstructureNotifyMask | \
ExposureMask | \
ButtonPressMask | ButtonReleaseMask | \
PointerMotionMask | PointerMotionHintMask | \
EnterWindowMask | LeaveWindowMask | \
FocusChangeMask)
ExposureMask | FocusChangeMask)
void
meta_window_ensure_frame (MetaWindow *window)
@@ -109,6 +106,19 @@ meta_window_ensure_frame (MetaWindow *window)
XChangeWindowAttributes (window->display->xdisplay,
frame->xwindow, CWEventMask, &attrs);
{
unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };
XISetMask (mask.mask, XI_ButtonPress);
XISetMask (mask.mask, XI_ButtonRelease);
XISetMask (mask.mask, XI_Motion);
XISetMask (mask.mask, XI_Enter);
XISetMask (mask.mask, XI_Leave);
XISelectEvents (window->display->xdisplay, frame->xwindow, &mask, 1);
}
meta_display_register_x_window (window->display, &frame->xwindow, window);
meta_error_trap_push (window->display);
@@ -141,7 +151,6 @@ meta_window_ensure_frame (MetaWindow *window)
* 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,
@@ -150,10 +159,16 @@ meta_window_ensure_frame (MetaWindow *window)
meta_ui_map_frame (frame->window->screen->ui, frame->xwindow);
/* Since the backend takes keygrabs on another connection, make sure
* to sync the GTK+ connection to ensure that the frame window has
* been created on the server at this point. */
XSync (window->display->xdisplay, False);
{
MetaBackend *backend = meta_get_backend ();
if (META_IS_BACKEND_X11 (backend))
{
/* Since the backend takes keygrabs on another connection, make sure
* to sync the GTK+ connection to ensure that the frame window has
* been created on the server at this point. */
XSync (window->display->xdisplay, False);
}
}
/* Move keybindings to frame instead of window */
meta_window_grab_keys (window);
@@ -356,15 +371,6 @@ meta_frame_sync_to_window (MetaFrame *frame,
frame->rect.x + frame->rect.width,
frame->rect.y + frame->rect.height);
/* set bg to none to avoid flicker */
if (need_resize)
{
meta_ui_unflicker_frame_bg (frame->window->screen->ui,
frame->xwindow,
frame->rect.width,
frame->rect.height);
}
meta_ui_move_resize_frame (frame->window->screen->ui,
frame->xwindow,
frame->rect.x,
@@ -374,9 +380,6 @@ meta_frame_sync_to_window (MetaFrame *frame,
if (need_resize)
{
meta_ui_reset_frame_bg (frame->window->screen->ui,
frame->xwindow);
/* If we're interactively resizing the frame, repaint
* it immediately so we don't start to lag.
*/

View File

@@ -29,6 +29,7 @@
#include <gio/gio.h>
#include <meta/keybindings.h>
#include <xkbcommon/xkbcommon.h>
typedef struct _MetaKeyHandler MetaKeyHandler;
struct _MetaKeyHandler
@@ -80,9 +81,6 @@ typedef struct
*/
GSList *combos;
/* for keybindings that can have shift or not like Alt+Tab */
gboolean add_shift:1;
/* for keybindings that apply only to a window */
gboolean per_window:1;
@@ -90,6 +88,23 @@ typedef struct
gboolean builtin:1;
} MetaKeyPref;
typedef struct
{
GHashTable *key_bindings;
GHashTable *key_bindings_index;
xkb_mod_mask_t ignored_modifier_mask;
xkb_mod_mask_t hyper_mask;
xkb_mod_mask_t super_mask;
xkb_mod_mask_t meta_mask;
MetaKeyCombo overlay_key_combo;
gboolean overlay_key_only_pressed;
MetaKeyCombo *iso_next_group_combos;
int n_iso_next_group_combos;
/* Alt+click button grabs */
ClutterModifierType window_grab_modifiers;
} MetaKeyBindingManager;
void meta_display_init_keys (MetaDisplay *display);
void meta_display_shutdown_keys (MetaDisplay *display);
void meta_screen_grab_keys (MetaScreen *screen);
@@ -103,8 +118,8 @@ void meta_window_ungrab_all_keys (MetaWindow *window,
gboolean meta_keybindings_process_event (MetaDisplay *display,
MetaWindow *window,
const ClutterEvent *event);
void meta_display_process_mapping_event (MetaDisplay *display,
XEvent *event);
ClutterModifierType meta_display_get_window_grab_modifiers (MetaDisplay *display);
gboolean meta_prefs_add_keybinding (const char *name,
GSettings *settings,

File diff suppressed because it is too large Load Diff

View File

@@ -52,6 +52,7 @@
#include "ui.h"
#include <meta/prefs.h>
#include <meta/compositor.h>
#include <meta/meta-backend.h>
#include <glib-object.h>
#include <glib-unix.h>
@@ -77,8 +78,9 @@
#include "x11/session.h"
#ifdef HAVE_WAYLAND
#include "wayland/meta-wayland.h"
#include "backends/meta-backend.h"
#endif
/*
* The exit code we'll return to our parent process when we eventually die.
@@ -94,26 +96,6 @@ static GMainLoop *meta_main_loop = NULL;
static void prefs_changed_callback (MetaPreference pref,
gpointer data);
/**
* log_handler:
* @log_domain: the domain the error occurred in (we ignore this)
* @log_level: the log level so that we can filter out less
* important messages
* @message: the message to log
* @user_data: arbitrary data (we ignore this)
*
* Prints log messages. If Mutter was compiled with backtrace support,
* also prints a backtrace (see meta_print_backtrace()).
*/
static void
log_handler (const gchar *log_domain,
GLogLevelFlags log_level,
const gchar *message,
gpointer user_data)
{
meta_warning ("Log level %d: %s\n", log_level, message);
}
/**
* meta_print_compilation_info:
*
@@ -180,7 +162,9 @@ static gchar *opt_client_id;
static gboolean opt_replace_wm;
static gboolean opt_disable_sm;
static gboolean opt_sync;
#ifdef HAVE_WAYLAND
static gboolean opt_wayland;
#endif
#ifdef HAVE_NATIVE_BACKEND
static gboolean opt_display_server;
#endif
@@ -221,12 +205,14 @@ static GOptionEntry meta_options[] = {
N_("Make X calls synchronous"),
NULL
},
#ifdef HAVE_WAYLAND
{
"wayland", 0, 0, G_OPTION_ARG_NONE,
&opt_wayland,
N_("Run as a wayland compositor"),
NULL
},
#endif
#ifdef HAVE_NATIVE_BACKEND
{
"display-server", 0, 0, G_OPTION_ARG_NONE,
@@ -291,8 +277,10 @@ meta_finalize (void)
meta_display_close (display,
CurrentTime); /* I doubt correct timestamps matter here */
#ifdef HAVE_WAYLAND
if (meta_is_wayland_compositor ())
meta_wayland_finalize ();
#endif
}
static gboolean
@@ -339,9 +327,13 @@ meta_init (void)
#if defined(CLUTTER_WINDOWING_EGL) && defined(HAVE_NATIVE_BACKEND)
if (opt_display_server)
clutter_set_windowing_backend (CLUTTER_WINDOWING_EGL);
else
#endif
clutter_set_windowing_backend (CLUTTER_WINDOWING_X11);
#ifdef HAVE_WAYLAND
meta_set_is_wayland_compositor (opt_wayland);
#endif
if (g_get_home_dir ())
if (chdir (g_get_home_dir ()) < 0)
@@ -354,15 +346,24 @@ meta_init (void)
g_irepository_prepend_search_path (MUTTER_PKGLIBDIR);
#endif
#ifdef HAVE_WAYLAND
if (meta_is_wayland_compositor ())
{
/* NB: When running as a hybrid wayland compositor we run our own headless X
* server so the user can't control the X display to connect too. */
meta_wayland_init ();
}
else
meta_wayland_pre_clutter_init ();
#endif
/* NB: When running as a hybrid wayland compositor we run our own headless X
* server so the user can't control the X display to connect too. */
if (!meta_is_wayland_compositor ())
meta_select_display (opt_display_name);
meta_clutter_init ();
#ifdef HAVE_WAYLAND
/* Bring up Wayland. This also launches Xwayland and sets DISPLAY as well... */
if (meta_is_wayland_compositor ())
meta_wayland_init ();
#endif
meta_set_syncing (opt_sync || (g_getenv ("MUTTER_SYNC") != NULL));
if (opt_replace_wm)
@@ -375,17 +376,7 @@ meta_init (void)
meta_ui_init ();
/* If we are running with wayland then we don't wait until we have
* an X connection before initializing clutter we instead initialize
* it earlier since we need to initialize the GL driver so the driver
* can register any needed wayland extensions. */
if (!meta_is_wayland_compositor ())
{
/*
* Clutter can only be initialized after the UI.
*/
meta_clutter_init ();
}
meta_restart_init ();
/*
* XXX: We cannot handle high dpi scaling yet, so fix the scale to 1
@@ -444,24 +435,10 @@ meta_register_with_session (void)
int
meta_run (void)
{
const gchar *log_domains[] = {
NULL, G_LOG_DOMAIN, "Gtk", "Gdk", "GLib",
"Pango", "GLib-GObject", "GThread"
};
guint i;
/* Load prefs */
meta_prefs_init ();
meta_prefs_add_listener (prefs_changed_callback, NULL);
for (i=0; i<G_N_ELEMENTS(log_domains); i++)
g_log_set_handler (log_domains[i],
G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
log_handler, NULL);
if (g_getenv ("MUTTER_G_FATAL_WARNINGS") != NULL)
g_log_set_always_fatal (G_LOG_LEVEL_MASK);
meta_ui_set_current_theme (meta_prefs_get_theme ());
/* Try to find some theme that'll work if the theme preference

View File

@@ -309,9 +309,16 @@ accelerator_parse (const gchar *accelerator,
keyval = xkb_keysym_from_name (accelerator, XKB_KEYSYM_CASE_INSENSITIVE);
if (keyval == XKB_KEY_NoSymbol)
{
error = TRUE;
goto out;
}
char *with_xf86 = g_strconcat ("XF86", accelerator, NULL);
keyval = xkb_keysym_from_name (with_xf86, XKB_KEYSYM_CASE_INSENSITIVE);
g_free (with_xf86);
if (keyval == XKB_KEY_NoSymbol)
{
error = TRUE;
goto out;
}
}
}
accelerator += len;

View File

@@ -0,0 +1,75 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (C) 2014 Red Hat
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Author: Carlos Garnacho <carlosg@gnome.org>
*/
#ifndef META_GESTURE_TRACKER_PRIVATE_H
#define META_GESTURE_TRACKER_PRIVATE_H
#include <glib-object.h>
#include <clutter/clutter.h>
#include <meta/window.h>
#define META_TYPE_GESTURE_TRACKER (meta_gesture_tracker_get_type ())
#define META_GESTURE_TRACKER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_GESTURE_TRACKER, MetaGestureTracker))
#define META_GESTURE_TRACKER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_GESTURE_TRACKER, MetaGestureTrackerClass))
#define META_IS_GESTURE_TRACKER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_GESTURE_TRACKER))
#define META_IS_GESTURE_TRACKER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_GESTURE_TRACKER))
#define META_GESTURE_TRACKER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_GESTURE_TRACKER, MetaGestureTrackerClass))
typedef struct _MetaGestureTracker MetaGestureTracker;
typedef struct _MetaGestureTrackerClass MetaGestureTrackerClass;
typedef enum {
META_SEQUENCE_NONE,
META_SEQUENCE_ACCEPTED,
META_SEQUENCE_REJECTED,
META_SEQUENCE_PENDING_END
} MetaSequenceState;
struct _MetaGestureTracker
{
GObject parent_instance;
};
struct _MetaGestureTrackerClass
{
GObjectClass parent_class;
void (* state_changed) (MetaGestureTracker *tracker,
ClutterEventSequence *sequence,
MetaSequenceState state);
};
GType meta_gesture_tracker_get_type (void) G_GNUC_CONST;
MetaGestureTracker * meta_gesture_tracker_new (void);
gboolean meta_gesture_tracker_handle_event (MetaGestureTracker *tracker,
const ClutterEvent *event);
gboolean meta_gesture_tracker_set_sequence_state (MetaGestureTracker *tracker,
ClutterEventSequence *sequence,
MetaSequenceState state);
MetaSequenceState meta_gesture_tracker_get_sequence_state (MetaGestureTracker *tracker,
ClutterEventSequence *sequence);
gint meta_gesture_tracker_get_n_current_touches (MetaGestureTracker *tracker);
#endif /* META_GESTURE_TRACKER_PRIVATE_H */

View File

@@ -0,0 +1,582 @@
/*
* Copyright (C) 2014 Red Hat
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Author: Carlos Garnacho <carlosg@gnome.org>
*/
/**
* SECTION:gesture-tracker
* @Title: MetaGestureTracker
* @Short_Description: Manages gestures on windows/desktop
*
* Forwards touch events to clutter actors, and accepts/rejects touch sequences
* based on the outcome of those.
*/
#include "config.h"
#include "meta-gesture-tracker-private.h"
#include "meta-surface-actor.h"
#define DISTANCE_THRESHOLD 30
typedef struct _MetaGestureTrackerPrivate MetaGestureTrackerPrivate;
typedef struct _GestureActionData GestureActionData;
typedef struct _MetaSequenceInfo MetaSequenceInfo;
struct _MetaSequenceInfo
{
MetaGestureTracker *tracker;
ClutterEventSequence *sequence;
MetaSequenceState state;
guint autodeny_timeout_id;
gfloat start_x;
gfloat start_y;
};
struct _GestureActionData
{
ClutterGestureAction *gesture;
MetaSequenceState state;
guint gesture_begin_id;
guint gesture_end_id;
guint gesture_cancel_id;
};
struct _MetaGestureTrackerPrivate
{
GHashTable *sequences; /* Hashtable of ClutterEventSequence->MetaSequenceInfo */
MetaSequenceState stage_state;
GArray *stage_gestures; /* Array of GestureActionData */
GList *listeners; /* List of ClutterGestureAction */
guint autodeny_timeout;
};
enum {
PROP_0,
PROP_AUTODENY_TIMEOUT,
LAST_PROP,
};
static GParamSpec *obj_props[LAST_PROP];
enum {
STATE_CHANGED,
N_SIGNALS
};
static guint signals[N_SIGNALS] = { 0 };
#define DEFAULT_AUTODENY_TIMEOUT 150
static void meta_gesture_tracker_untrack_stage (MetaGestureTracker *tracker);
G_DEFINE_TYPE_WITH_PRIVATE (MetaGestureTracker, meta_gesture_tracker, G_TYPE_OBJECT)
static void
meta_gesture_tracker_finalize (GObject *object)
{
MetaGestureTrackerPrivate *priv;
priv = meta_gesture_tracker_get_instance_private (META_GESTURE_TRACKER (object));
g_hash_table_destroy (priv->sequences);
g_array_free (priv->stage_gestures, TRUE);
g_list_free (priv->listeners);
G_OBJECT_CLASS (meta_gesture_tracker_parent_class)->finalize (object);
}
static void
meta_gesture_tracker_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
MetaGestureTrackerPrivate *priv;
priv = meta_gesture_tracker_get_instance_private (META_GESTURE_TRACKER (object));
switch (prop_id)
{
case PROP_AUTODENY_TIMEOUT:
priv->autodeny_timeout = g_value_get_uint (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
meta_gesture_tracker_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
MetaGestureTrackerPrivate *priv;
priv = meta_gesture_tracker_get_instance_private (META_GESTURE_TRACKER (object));
switch (prop_id)
{
case PROP_AUTODENY_TIMEOUT:
g_value_set_uint (value, priv->autodeny_timeout);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
meta_gesture_tracker_class_init (MetaGestureTrackerClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = meta_gesture_tracker_finalize;
object_class->set_property = meta_gesture_tracker_set_property;
object_class->get_property = meta_gesture_tracker_get_property;
obj_props[PROP_AUTODENY_TIMEOUT] = g_param_spec_uint ("autodeny-timeout",
"Auto-deny timeout",
"Auto-deny timeout",
0, G_MAXUINT, DEFAULT_AUTODENY_TIMEOUT,
G_PARAM_STATIC_STRINGS |
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY);
g_object_class_install_properties (object_class, LAST_PROP, obj_props);
signals[STATE_CHANGED] =
g_signal_new ("state-changed",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (MetaGestureTrackerClass, state_changed),
NULL, NULL, NULL,
G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_UINT);
}
static gboolean
autodeny_sequence (gpointer user_data)
{
MetaSequenceInfo *info = user_data;
/* Deny the sequence automatically after the given timeout */
if (info->state == META_SEQUENCE_NONE)
meta_gesture_tracker_set_sequence_state (info->tracker, info->sequence,
META_SEQUENCE_REJECTED);
info->autodeny_timeout_id = 0;
return G_SOURCE_REMOVE;
}
static MetaSequenceInfo *
meta_sequence_info_new (MetaGestureTracker *tracker,
const ClutterEvent *event)
{
MetaGestureTrackerPrivate *priv;
MetaSequenceInfo *info;
guint ms;
priv = meta_gesture_tracker_get_instance_private (tracker);
ms = priv->autodeny_timeout;
info = g_slice_new0 (MetaSequenceInfo);
info->tracker = tracker;
info->sequence = event->touch.sequence;
info->state = META_SEQUENCE_NONE;
info->autodeny_timeout_id = g_timeout_add (ms, autodeny_sequence, info);
clutter_event_get_coords (event, &info->start_x, &info->start_y);
return info;
}
static void
meta_sequence_info_free (MetaSequenceInfo *info)
{
if (info->autodeny_timeout_id)
g_source_remove (info->autodeny_timeout_id);
if (info->state == META_SEQUENCE_NONE)
meta_gesture_tracker_set_sequence_state (info->tracker, info->sequence,
META_SEQUENCE_REJECTED);
g_slice_free (MetaSequenceInfo, info);
}
static gboolean
state_is_applicable (MetaSequenceState prev_state,
MetaSequenceState state)
{
if (prev_state == META_SEQUENCE_PENDING_END)
return FALSE;
/* Don't allow reverting to none */
if (state == META_SEQUENCE_NONE)
return FALSE;
/* PENDING_END state is final */
if (prev_state == META_SEQUENCE_PENDING_END)
return FALSE;
/* Sequences must be accepted/denied before PENDING_END */
if (prev_state == META_SEQUENCE_NONE &&
state == META_SEQUENCE_PENDING_END)
return FALSE;
/* Make sequences stick to their accepted/denied state */
if (state != META_SEQUENCE_PENDING_END &&
prev_state != META_SEQUENCE_NONE)
return FALSE;
return TRUE;
}
static gboolean
meta_gesture_tracker_set_state (MetaGestureTracker *tracker,
MetaSequenceState state)
{
MetaGestureTrackerPrivate *priv;
ClutterEventSequence *sequence;
GHashTableIter iter;
priv = meta_gesture_tracker_get_instance_private (tracker);
if (priv->stage_state != state &&
!state_is_applicable (priv->stage_state, state))
return FALSE;
g_hash_table_iter_init (&iter, priv->sequences);
priv->stage_state = state;
while (g_hash_table_iter_next (&iter, (gpointer*) &sequence, NULL))
meta_gesture_tracker_set_sequence_state (tracker, sequence, state);
return TRUE;
}
static gboolean
gesture_begin_cb (ClutterGestureAction *gesture,
ClutterActor *actor,
MetaGestureTracker *tracker)
{
MetaGestureTrackerPrivate *priv;
priv = meta_gesture_tracker_get_instance_private (tracker);
if (!g_list_find (priv->listeners, gesture) &&
meta_gesture_tracker_set_state (tracker, META_SEQUENCE_ACCEPTED))
priv->listeners = g_list_prepend (priv->listeners, gesture);
return TRUE;
}
static void
gesture_end_cb (ClutterGestureAction *gesture,
ClutterActor *actor,
MetaGestureTracker *tracker)
{
MetaGestureTrackerPrivate *priv;
priv = meta_gesture_tracker_get_instance_private (tracker);
priv->listeners = g_list_remove (priv->listeners, gesture);
if (!priv->listeners)
meta_gesture_tracker_untrack_stage (tracker);
}
static void
gesture_cancel_cb (ClutterGestureAction *gesture,
ClutterActor *actor,
MetaGestureTracker *tracker)
{
MetaGestureTrackerPrivate *priv;
priv = meta_gesture_tracker_get_instance_private (tracker);
if (g_list_find (priv->listeners, gesture))
{
priv->listeners = g_list_remove (priv->listeners, gesture);
if (!priv->listeners)
meta_gesture_tracker_set_state (tracker, META_SEQUENCE_PENDING_END);
}
}
static gboolean
cancel_and_unref_gesture_cb (ClutterGestureAction *action)
{
clutter_gesture_action_cancel (action);
g_object_unref (action);
return G_SOURCE_REMOVE;
}
static void
clear_gesture_data (GestureActionData *data)
{
g_signal_handler_disconnect (data->gesture, data->gesture_begin_id);
g_signal_handler_disconnect (data->gesture, data->gesture_end_id);
g_signal_handler_disconnect (data->gesture, data->gesture_cancel_id);
/* Defer cancellation to an idle, as it may happen within event handling */
g_idle_add ((GSourceFunc) cancel_and_unref_gesture_cb, data->gesture);
}
static void
meta_gesture_tracker_init (MetaGestureTracker *tracker)
{
MetaGestureTrackerPrivate *priv;
priv = meta_gesture_tracker_get_instance_private (tracker);
priv->sequences = g_hash_table_new_full (NULL, NULL, NULL,
(GDestroyNotify) meta_sequence_info_free);
priv->stage_gestures = g_array_new (FALSE, FALSE, sizeof (GestureActionData));
g_array_set_clear_func (priv->stage_gestures, (GDestroyNotify) clear_gesture_data);
}
MetaGestureTracker *
meta_gesture_tracker_new (void)
{
return g_object_new (META_TYPE_GESTURE_TRACKER, NULL);
}
static void
meta_gesture_tracker_track_stage (MetaGestureTracker *tracker,
ClutterActor *stage)
{
MetaGestureTrackerPrivate *priv;
GList *actions, *l;
priv = meta_gesture_tracker_get_instance_private (tracker);
actions = clutter_actor_get_actions (stage);
for (l = actions; l; l = l->next)
{
GestureActionData data;
if (!CLUTTER_IS_GESTURE_ACTION (l->data))
continue;
data.gesture = g_object_ref (l->data);
data.state = META_SEQUENCE_NONE;
data.gesture_begin_id =
g_signal_connect (data.gesture, "gesture-begin",
G_CALLBACK (gesture_begin_cb), tracker);
data.gesture_end_id =
g_signal_connect (data.gesture, "gesture-end",
G_CALLBACK (gesture_end_cb), tracker);
data.gesture_cancel_id =
g_signal_connect (data.gesture, "gesture-cancel",
G_CALLBACK (gesture_cancel_cb), tracker);
g_array_append_val (priv->stage_gestures, data);
}
g_list_free (actions);
}
static void
meta_gesture_tracker_untrack_stage (MetaGestureTracker *tracker)
{
MetaGestureTrackerPrivate *priv;
priv = meta_gesture_tracker_get_instance_private (tracker);
priv->stage_state = META_SEQUENCE_NONE;
g_hash_table_remove_all (priv->sequences);
if (priv->stage_gestures->len > 0)
g_array_remove_range (priv->stage_gestures, 0, priv->stage_gestures->len);
g_list_free (priv->listeners);
priv->listeners = NULL;
}
gboolean
meta_gesture_tracker_handle_event (MetaGestureTracker *tracker,
const ClutterEvent *event)
{
MetaGestureTrackerPrivate *priv;
ClutterEventSequence *sequence;
MetaSequenceState state;
MetaSequenceInfo *info;
ClutterActor *stage;
gfloat x, y;
sequence = clutter_event_get_event_sequence (event);
if (!sequence)
return FALSE;
priv = meta_gesture_tracker_get_instance_private (tracker);
stage = CLUTTER_ACTOR (clutter_event_get_stage (event));
switch (event->type)
{
case CLUTTER_TOUCH_BEGIN:
if (g_hash_table_size (priv->sequences) == 0)
meta_gesture_tracker_track_stage (tracker, stage);
info = meta_sequence_info_new (tracker, event);
g_hash_table_insert (priv->sequences, sequence, info);
if (priv->stage_gestures->len == 0)
{
/* If no gestures are attached, reject the sequence right away */
meta_gesture_tracker_set_sequence_state (tracker, sequence,
META_SEQUENCE_REJECTED);
}
else if (priv->stage_state != META_SEQUENCE_NONE)
{
/* Make the sequence state match the general state */
meta_gesture_tracker_set_sequence_state (tracker, sequence,
priv->stage_state);
}
state = info->state;
break;
case CLUTTER_TOUCH_END:
info = g_hash_table_lookup (priv->sequences, sequence);
if (!info)
return FALSE;
/* If nothing was done yet about the sequence, reject it so X11
* clients may see it
*/
if (info->state == META_SEQUENCE_NONE)
meta_gesture_tracker_set_sequence_state (tracker, sequence,
META_SEQUENCE_REJECTED);
state = info->state;
g_hash_table_remove (priv->sequences, sequence);
if (g_hash_table_size (priv->sequences) == 0)
meta_gesture_tracker_untrack_stage (tracker);
break;
case CLUTTER_TOUCH_UPDATE:
info = g_hash_table_lookup (priv->sequences, sequence);
if (!info)
return FALSE;
clutter_event_get_coords (event, &x, &y);
if (info->state == META_SEQUENCE_NONE &&
(ABS (info->start_x - x) > DISTANCE_THRESHOLD ||
ABS (info->start_y - y) > DISTANCE_THRESHOLD))
meta_gesture_tracker_set_sequence_state (tracker, sequence,
META_SEQUENCE_REJECTED);
state = info->state;
break;
default:
return FALSE;
break;
}
/* As soon as a sequence is accepted, we replay it to
* the stage as a captured event, and make sure it's never
* propagated anywhere else. Since ClutterGestureAction does
* all its event handling from a captured-event handler on
* the stage, this effectively acts as a "sequence grab" on
* gesture actions.
*
* Sequences that aren't (yet or never) in an accepted state
* will go through, these events will get processed through
* the compositor, and eventually through clutter, still
* triggering the gestures capturing events on the stage, and
* possibly resulting in MetaSequenceState changes.
*/
if (state == META_SEQUENCE_ACCEPTED)
{
clutter_actor_event (CLUTTER_ACTOR (clutter_event_get_stage (event)),
event, TRUE);
return TRUE;
}
return FALSE;
}
gboolean
meta_gesture_tracker_set_sequence_state (MetaGestureTracker *tracker,
ClutterEventSequence *sequence,
MetaSequenceState state)
{
MetaGestureTrackerPrivate *priv;
MetaSequenceInfo *info;
g_return_val_if_fail (META_IS_GESTURE_TRACKER (tracker), FALSE);
priv = meta_gesture_tracker_get_instance_private (tracker);
info = g_hash_table_lookup (priv->sequences, sequence);
if (!info)
return FALSE;
else if (state == info->state)
return TRUE;
if (!state_is_applicable (info->state, state))
return FALSE;
/* Unset autodeny timeout */
if (info->autodeny_timeout_id)
{
g_source_remove (info->autodeny_timeout_id);
info->autodeny_timeout_id = 0;
}
info->state = state;
g_signal_emit (tracker, signals[STATE_CHANGED], 0, sequence, info->state);
/* If the sequence was denied, set immediately to PENDING_END after emission */
if (state == META_SEQUENCE_REJECTED)
{
info->state = META_SEQUENCE_PENDING_END;
g_signal_emit (tracker, signals[STATE_CHANGED], 0, sequence, info->state);
}
return TRUE;
}
MetaSequenceState
meta_gesture_tracker_get_sequence_state (MetaGestureTracker *tracker,
ClutterEventSequence *sequence)
{
MetaGestureTrackerPrivate *priv;
MetaSequenceInfo *info;
g_return_val_if_fail (META_IS_GESTURE_TRACKER (tracker), META_SEQUENCE_PENDING_END);
priv = meta_gesture_tracker_get_instance_private (tracker);
info = g_hash_table_lookup (priv->sequences, sequence);
if (!info)
return META_SEQUENCE_PENDING_END;
return info->state;
}
gint
meta_gesture_tracker_get_n_current_touches (MetaGestureTracker *tracker)
{
MetaGestureTrackerPrivate *priv;
g_return_val_if_fail (META_IS_GESTURE_TRACKER (tracker), 0);
priv = meta_gesture_tracker_get_instance_private (tracker);
return g_hash_table_size (priv->sequences);
}

View File

@@ -28,7 +28,6 @@
#include <config.h>
#include <meta/prefs.h>
#include "ui.h"
#include "util-private.h"
#include "meta-plugin-manager.h"
#include <glib.h>
@@ -67,6 +66,7 @@
#define SCHEMA_INTERFACE "org.gnome.desktop.interface"
#define SCHEMA_INPUT_SOURCES "org.gnome.desktop.input-sources"
#define SCHEMA_XSETTINGS "org.gnome.settings-daemon.plugins.xsettings"
#define SCHEMA_MOUSE "org.gnome.settings-daemon.peripherals.mouse"
#define SETTINGS(s) g_hash_table_lookup (settings_schemas, (s))
@@ -101,6 +101,7 @@ static gboolean gnome_animations = TRUE;
static char *cursor_theme = NULL;
static int cursor_size = 24;
static int draggable_border_width = 10;
static int drag_threshold;
static gboolean resize_with_right_button = FALSE;
static gboolean edge_tiling = FALSE;
static gboolean force_fullscreen = TRUE;
@@ -492,6 +493,13 @@ static MetaIntPreference preferences_int[] =
},
&draggable_border_width
},
{
{ "drag-threshold",
SCHEMA_MOUSE,
META_PREF_DRAG_THRESHOLD,
},
&drag_threshold
},
{ { NULL, 0, 0 }, NULL },
};
@@ -978,6 +986,10 @@ meta_prefs_init (void)
g_signal_connect (settings, "changed", G_CALLBACK (settings_changed), NULL);
g_hash_table_insert (settings_schemas, g_strdup (SCHEMA_MUTTER), settings);
settings = g_settings_new (SCHEMA_MOUSE);
g_signal_connect (settings, "changed", G_CALLBACK (settings_changed), NULL);
g_hash_table_insert (settings_schemas, g_strdup (SCHEMA_MOUSE), settings);
/* Individual keys we watch outside of our schemas */
settings = g_settings_new (SCHEMA_INTERFACE);
g_signal_connect (settings, "changed::" KEY_GNOME_ACCESSIBILITY,
@@ -1198,8 +1210,9 @@ settings_changed (GSettings *settings,
}
else
{
/* Someone added a preference of an unhandled type */
g_assert_not_reached ();
/* Unknown preference type. This quite likely simply isn't
* a preference we track changes to. */
return;
}
g_variant_unref (value);
@@ -1234,6 +1247,7 @@ xsettings_overrides_changed (GSettings *settings,
GVariant *value;
GVariantDict overrides;
int shell_shows_app_menu = 1;
gboolean changed = FALSE;
if (!g_settings_get_boolean (settings, "active"))
goto out;
@@ -1247,8 +1261,13 @@ xsettings_overrides_changed (GSettings *settings,
"Gtk/ShellShowsAppMenu", "i", &shell_shows_app_menu);
g_variant_dict_clear (&overrides);
changed = (show_fallback_app_menu == !!shell_shows_app_menu);
out:
show_fallback_app_menu = !shell_shows_app_menu;
if (changed)
queue_changed (META_PREF_BUTTON_LAYOUT);
}
/**
@@ -1328,10 +1347,26 @@ meta_prefs_get_cursor_theme (void)
return cursor_theme;
}
static int
get_scale_factor (void)
{
GdkScreen *screen;
GValue value = G_VALUE_INIT;
g_value_init (&value, G_TYPE_INT);
/* XXX: Should this be in ui/ ? Or MetaMonitorManager? */
screen = gdk_screen_get_default ();
if (gdk_screen_get_setting (screen, "gdk-window-scaling-factor", &value))
return g_value_get_int (&value);
else
return 1;
}
int
meta_prefs_get_cursor_size (void)
{
return cursor_size;
return cursor_size * get_scale_factor ();
}
@@ -1662,43 +1697,43 @@ button_layout_handler (GVariant *value,
g_strfreev (sides);
/* Invert the button layout for RTL languages */
if (meta_ui_get_direction() == META_UI_DIRECTION_RTL)
{
MetaButtonLayout rtl_layout;
int j;
if (meta_get_locale_direction() == META_LOCALE_DIRECTION_RTL)
{
MetaButtonLayout rtl_layout;
int j;
for (i = 0; new_layout.left_buttons[i] != META_BUTTON_FUNCTION_LAST; i++);
for (j = 0; j < i; j++)
{
rtl_layout.right_buttons[j] = new_layout.left_buttons[i - j - 1];
if (j == 0)
rtl_layout.right_buttons_has_spacer[i - 1] = new_layout.left_buttons_has_spacer[i - j - 1];
else
rtl_layout.right_buttons_has_spacer[j - 1] = new_layout.left_buttons_has_spacer[i - j - 1];
}
for (; j < MAX_BUTTONS_PER_CORNER; j++)
{
rtl_layout.right_buttons[j] = META_BUTTON_FUNCTION_LAST;
rtl_layout.right_buttons_has_spacer[j] = FALSE;
}
for (i = 0; new_layout.left_buttons[i] != META_BUTTON_FUNCTION_LAST; i++);
for (j = 0; j < i; j++)
{
rtl_layout.right_buttons[j] = new_layout.left_buttons[i - j - 1];
if (j == 0)
rtl_layout.right_buttons_has_spacer[i - 1] = new_layout.left_buttons_has_spacer[i - j - 1];
else
rtl_layout.right_buttons_has_spacer[j - 1] = new_layout.left_buttons_has_spacer[i - j - 1];
}
for (; j < MAX_BUTTONS_PER_CORNER; j++)
{
rtl_layout.right_buttons[j] = META_BUTTON_FUNCTION_LAST;
rtl_layout.right_buttons_has_spacer[j] = FALSE;
}
for (i = 0; new_layout.right_buttons[i] != META_BUTTON_FUNCTION_LAST; i++);
for (j = 0; j < i; j++)
{
rtl_layout.left_buttons[j] = new_layout.right_buttons[i - j - 1];
if (j == 0)
rtl_layout.left_buttons_has_spacer[i - 1] = new_layout.right_buttons_has_spacer[i - j - 1];
else
rtl_layout.left_buttons_has_spacer[j - 1] = new_layout.right_buttons_has_spacer[i - j - 1];
}
for (; j < MAX_BUTTONS_PER_CORNER; j++)
{
rtl_layout.left_buttons[j] = META_BUTTON_FUNCTION_LAST;
rtl_layout.left_buttons_has_spacer[j] = FALSE;
}
for (i = 0; new_layout.right_buttons[i] != META_BUTTON_FUNCTION_LAST; i++);
for (j = 0; j < i; j++)
{
rtl_layout.left_buttons[j] = new_layout.right_buttons[i - j - 1];
if (j == 0)
rtl_layout.left_buttons_has_spacer[i - 1] = new_layout.right_buttons_has_spacer[i - j - 1];
else
rtl_layout.left_buttons_has_spacer[j - 1] = new_layout.right_buttons_has_spacer[i - j - 1];
}
for (; j < MAX_BUTTONS_PER_CORNER; j++)
{
rtl_layout.left_buttons[j] = META_BUTTON_FUNCTION_LAST;
rtl_layout.left_buttons_has_spacer[j] = FALSE;
}
new_layout = rtl_layout;
}
new_layout = rtl_layout;
}
if (!button_layout_equal (&button_layout, &new_layout))
{
@@ -1902,6 +1937,9 @@ meta_preference_to_string (MetaPreference pref)
case META_PREF_DRAGGABLE_BORDER_WIDTH:
return "DRAGGABLE_BORDER_WIDTH";
case META_PREF_DRAG_THRESHOLD:
return "DRAG_TRHESHOLD";
case META_PREF_DYNAMIC_WORKSPACES:
return "DYNAMIC_WORKSPACES";
@@ -1995,23 +2033,6 @@ update_binding (MetaKeyPref *binding,
continue;
}
/* Bug 329676: Bindings which can be shifted must not have no modifiers,
* nor only SHIFT as a modifier.
*/
if (binding->add_shift &&
0 != keysym &&
(META_VIRTUAL_SHIFT_MASK == mods || 0 == mods))
{
meta_warning ("Cannot bind \"%s\" to %s: it needs a modifier "
"such as Ctrl or Alt.\n",
binding->name, strokes[i]);
/* Value is kept and will thus be removed next time we save the key.
* Changing the key in response to a modification could lead to cyclic calls. */
continue;
}
combo = g_malloc0 (sizeof (MetaKeyCombo));
combo->keysym = keysym;
combo->keycode = keycode;
@@ -2187,7 +2208,6 @@ meta_prefs_add_keybinding (const char *name,
pref->settings = g_object_ref (settings);
pref->action = action;
pref->combos = NULL;
pref->add_shift = (flags & META_KEY_BINDING_REVERSES) != 0;
pref->per_window = (flags & META_KEY_BINDING_PER_WINDOW) != 0;
pref->builtin = (flags & META_KEY_BINDING_BUILTIN) != 0;
@@ -2367,6 +2387,12 @@ meta_prefs_get_draggable_border_width (void)
return draggable_border_width;
}
int
meta_prefs_get_drag_threshold (void)
{
return drag_threshold;
}
void
meta_prefs_set_force_fullscreen (gboolean whether)
{

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