Compare commits

...

141 Commits

Author SHA1 Message Date
43762da9d3 Bump version to 3.13.2
Update NEWS.
2014-05-27 21:18:25 +02:00
266166a2d6 window: Make meta_window_unmaximize_with_gravity internal 2014-05-27 15:15:57 -04:00
3a0af0faae window: Add a meta_window_get_titlebar_rect 2014-05-27 15:15:56 -04:00
0890eaa3fe window: Rename get_geometry to get_session_geometry 2014-05-27 15:15:56 -04:00
d4058d947b window: Remove meta_window_get_rect
It's a bad API that returns weird results you wouldn't expect.
2014-05-27 15:15:41 -04:00
b704659899 backend: Add an XIWarpPointer wrapper
This makes Alt+F7 / Alt+F8 work respectively under X11 nested mode.
For the native backend implementation, we'll need a special Clutter
function, so don't implement that for now.
2014-05-27 14:28:35 -04:00
0a9187a6e9 window: Add accessor method for gtk_theme_variant
This is useful information for UI associated with a window, so add
a corresponding method.

https://bugzilla.gnome.org/show_bug.cgi?id=730752
2014-05-27 19:40:06 +02:00
31db32e826 Actually implement opening the app menu
The last commit added support for the "appmenu" button in decorations,
but didn't actually implement it. Add a new MetaWindowMenuType parameter
to the show_window_menu () functions and use it to ask the compositor
to display the app menu when the new button is activated.

https://bugzilla.gnome.org/show_bug.cgi?id=730752
2014-05-27 19:40:06 +02:00
c2ea650b3c Add support for app-menu button in window decorations
We want to synchronize the button layouts of our server side
decorations and GTK+'s client side ones. However each currently
may contain buttons not supported by the other, which makes this
unnecessarily tricky.
So add support for a new "appmenu" button in the layout, to display
the fallback app menu in the decorations.

https://bugzilla.gnome.org/show_bug.cgi?id=730752
2014-05-27 19:40:05 +02:00
969131f00e core: Reindent 2014-05-27 13:25:25 -04:00
c98090c061 constraints: Remove improper frame_rect_to_client_rect for placement
Constriants are now in frame rect coordinates.
2014-05-26 13:27:54 -04:00
3168d3b5e6 window: Move the extents storage above the rects
So all the rects are grouped together.
2014-05-24 20:47:56 -04:00
efcd7d86e7 wayland: Add support for show_window_menu 2014-05-24 15:56:04 -04:00
04449923bd Remove MetaMenuIconType
Unused since 2006, quick, before we hit the 10-year mark!
2014-05-23 20:45:55 +02:00
47b3336ffa monitor-manager-xrandr: Make sure to XFlush the XUngrabServer
Otherwise, the server may not receive our request, meaning that
we'll hang onto the server grab forever.
2014-05-22 17:39:46 -04:00
0f37c1b58e keybindings: Replace the incomprehensible set of flags with a gravity param 2014-05-22 16:09:14 -04:00
a3747725ed window-wayland: Don't use meta_window_get_position 2014-05-22 15:47:30 -04:00
c448650a60 keybindings: Correct move_to_corner_backend
meta_window_get_position() returns the client rect position, which
we then pass to meta_window_move_frame. Just use the existing frame
rect coordinates.
2014-05-22 15:47:30 -04:00
c45f616fdc keybindings: Fix code style 2014-05-22 15:47:30 -04:00
9402691aaa window-x11: Remove a use of meta_window_get_position 2014-05-22 15:47:29 -04:00
cbffbb0be0 window: Rename the requested_rect to the unconstrained_rect
The requested_rect is a strange name for it, because it's not actually
the rect that the user or client requested all the time: in the case of
a simple move or a simple resize, we calculate some of the fields
ourselves.

To the MetaWindow subclass implementations, it just means "the rect
before we constrained it", so just use the name unconstrained_rect.
This also makes it match the name of the MetaWindow field.
2014-05-22 15:39:10 -04:00
9df5b17940 window: Allow passing garbage window sizes for move-only actions
We'll just fix them up in meta_window_move_resize_internal.
2014-05-22 15:39:10 -04:00
feae23506b window-x11: Move the comment about StaticGravity resizing down 2014-05-22 15:39:09 -04:00
6408e59c7c wayland: Move checks for grabbing into a central location
This means that we won't have as much work to do to introduce similar
checks for touch.
2014-05-22 10:58:07 -04:00
47d72680ff keybindings: Correct coords for window menu for CSD windows 2014-05-22 10:51:05 -04:00
6513cbb470 Add back coordinates to the window menu
It looks weird to have Alt+Space pop up under the cursor instead
of the top-left corner of the window, and the Wayland request will
pass through the coordinates as well.

Add it to the compositor interface, and extend the
_GTK_SHOW_WINDOW_MENU ClientMessage to support it as well.
2014-05-22 10:50:57 -04:00
50b81fe4b9 x11: Add support for a new _GTK_SHOW_WINDOW_MENU request
To show the window menu from a client-side decoration.
2014-05-21 18:55:47 -04:00
f38c1f6ab4 window: Fix delayed mouse mode on X
On X, basing the check whether the pointer is on the window on
Clutter events does not work, as the relevant events are handled
by GDK instead.
So add an X-specific window_has_pointer() implementation to also
fix mouse mode when running as X compositor.

https://bugzilla.gnome.org/show_bug.cgi?id=730541
2014-05-21 22:56:14 +02:00
f159611fab window: Fix delayed mouse mode
Using clutter_actor_has_pointer() to test whether the pointer is
on the window makes for clean and nice-looking code, but does not
work in practice - ClutterActor:has-pointer is not recursive, so
we miss when the pointer is on the associated surface actor rather
than the actor itself.
Instead, check whether the window actor contains the core pointer's
pointer actor, which actually works.

https://bugzilla.gnome.org/show_bug.cgi?id=730541
2014-05-21 22:56:14 +02:00
f1a7231ac2 window: Remove another comment reference to StaticGravity 2014-05-21 13:20:10 -04:00
21991a7edb window: Remove some overcomplicated uses of meta_window_move_resize
Replace them with meta_window_move_frame, since that's all we need
to do.
2014-05-21 13:15:49 -04:00
3f1b6ddc8f window-x11: Rearrange locals a tiny bit 2014-05-21 13:03:39 -04:00
aa84813400 window-x11: Calculate size_dx / size_dy before assigning to window->rect
This makes sure that we grow / shrink the frame and window in the
correct order.
2014-05-21 13:02:26 -04:00
dd243813e1 window-x11: Simplify leftovers from the static gravity code removal 2014-05-21 12:52:44 -04:00
d8c2933c58 window-x11: Don't bother calculating the actual deltas for the frame
It's not necessary. All we care about is whether the size / position
has changed.
2014-05-21 12:25:27 -04:00
2b798511de window-x11: Consistently include the bottom border on shaded windows
We already do it in the theme code, but not the actual WM code. Since
we include the left/right borders, it only seems fair to include the
bottom border.

This effectively makes it so that shading a window means that the
client window "slot" has 0 height.
2014-05-21 12:21:05 -04:00
6c37f6e601 window: Remove meta_window_resize
It's unused, and it's a poor API. resize_with_gravity and resize_frame
are better.
2014-05-21 12:16:56 -04:00
92e9f3d467 window: Reindent slightly 2014-05-21 12:16:56 -04:00
05419b8450 frame: Make sure to XSync before grabbing keybindings
Otherwise, the X server might read the backend's connection before
GTK+'s, meaning that it sees the XIGrabKeycode requests before the
CreateWindow.

This fixes keybindings on windows not working immediately.

Thanks to Rui Matos <tiagomatos@gmail.com> and
Julien Cristau <jcristau@debian.org> for helping track down the issue.
2014-05-21 11:29:36 -04:00
e215c07439 window: Make border_width private to X11 2014-05-20 15:59:17 -04:00
5b7dff7a57 window: Move constructors to the respective header files 2014-05-20 15:59:17 -04:00
1a3aa75385 window: Move meta_window_wayland_new to window-wayland.c 2014-05-20 15:59:17 -04:00
41880778b5 window-wayland: Change the state on grab op transitions
This could affect the RESIZING state.
2014-05-20 15:59:17 -04:00
ecb4e09ec5 window-x11: Make sure to chain up in grab_op_began / ended
To make sure shaken_loose gets reset.
2014-05-20 15:59:16 -04:00
d02505852d window: Move _NET_WM_DESKTOP setting to window-x11 2014-05-20 15:59:16 -04:00
3941dc7537 core: Remove some unused meta_core_get requests 2014-05-20 15:59:16 -04:00
e790c45303 place: Don't require checking for changing
The only time this can change is if find_first_fit returns TRUE,
at which point we already jump out.
2014-05-20 15:59:16 -04:00
ae4e553ddb place: Move maximization path above first fit finding 2014-05-20 15:59:15 -04:00
809568280b place: Simplify control flow and fix a crash 2014-05-20 15:59:15 -04:00
4053c92abf Rework timestamp pinging
If a window temporarily goes unresponsive, and then returns later, we
should hide the kill dialog that we showed to the user.
2014-05-20 15:59:15 -04:00
56906a29e0 window: Make propagate_focus_appearance internal to MetaWindow
It's an internal helper function. The public interface is
meta_window_activate or meta_window_focus.
2014-05-20 15:59:15 -04:00
2c0ad5bef7 window: Replace the user_rect with the unconstrained_rect
Realistically, the user rect contains the unconstrained window
rectangle coordinates that we want to be displaying, in case
something in the constraints change.

Rename it to the "unconstrained_rect", and change the code to always
save it, regardless of current state.

When metacity was originally being built, the purpose of the user
rect was a lot less clear. The code only saved it on user actions,
with various other calls to save_user_window_placement() and a force
mechanism sprinkled in to avoid windows being snapped back to odd
places when constraints changed.

This could lead to odd bugs. For instance, if the user uses some
extension which automatically tiles windows and didn't pass
user_action=TRUE, and then the struts changed, the window would be
placed back at the last place a user moved it to, rather than where
the window was tiled to.

The META_IS_USER_ACTION flag is still used in the constraints code
to determine whether we should allow shoving windows offscreen, so
we can't remove it completely, but we should think about splitting
out the constrainment policies it commands for a bit more
fine-grained control.

https://bugzilla.gnome.org/show_bug.cgi?id=726714
2014-05-20 15:59:14 -04:00
4a7939268c build: Add org.freedesktop.login1.xml to EXTRA_DIST 2014-05-20 18:50:33 +02:00
80266d3071 keybindings: Clean up code a tiny bit 2014-05-20 12:25:41 -04:00
8e5cfccf49 Revert "launcher: Put in some markers to help diff make a readable patch"
The markers have fulfilled their purpose.
2014-05-19 15:09:23 -04:00
dcf64ca167 launcher: Replace mutter-launch with logind integration
This uses David Herrmann's new logind sessions interface to retrieve
fds for input devices, rather than using a custom setuid helper to do
the management. This vastly simplifies the interface.

This requires systemd v210, at least.

https://bugzilla.gnome.org/show_bug.cgi?id=724604
2014-05-19 15:09:23 -04:00
f93fc1506b launcher: Put in some markers to help diff make a readable patch 2014-05-19 15:09:22 -04:00
4ee8fb8154 launcher: Pause Clutter during VT switches 2014-05-19 15:09:20 -04:00
446b75907e launcher: Remove the "VT-switched lock"
We'll replace it by pausing the Clutter master clock.
2014-05-19 15:03:06 -04:00
550f1989ff window: Complete moving enter/leave handling here 2014-05-19 15:03:05 -04:00
91a6f42345 Drop leftover menu.h/metaaccellabel.h references
In addition to 8640982e68
2014-05-18 15:51:14 +02:00
e97cae0eb3 Updated POTFILES.in 2014-05-18 01:05:15 +02:00
8640982e68 Convert window menus to a compositor implementation 2014-05-17 15:16:23 -04:00
480a853263 x11: Add simple cursor renderer 2014-05-17 13:27:16 -04:00
b05953d960 cursor: Add a META_CURSOR_NONE
This is for cases where we have a MetaCursorReference that does
not have an X cursor equivalent... we have to return something!
2014-05-17 13:27:16 -04:00
3a0de6a4f1 cursor: Correct switching between fallback and backend cursors
When switching from the stage cursor to the native cursor, we
forgot to repaint the stage to get rid of the old cursor. Fix
this by having the abstract cursor renderer class track whether
we're using the backend, rather than doing chain-up shenanigans.
2014-05-17 13:27:15 -04:00
fb9f22c02f cursor-renderer-native: Don't move the cursor when we don't need to 2014-05-17 10:58:49 -04:00
10ac1000f7 cursor-renderer: We always use a MetaStage 2014-05-17 10:50:44 -04:00
c81a0dede2 keybindings: Don't crash if we don't have any windows to activate
Pressing Alt+Tab when we have no windows should not crash your
desktop, especially when it's so easy to hit when trying to test
switching VTs.
2014-05-15 15:50:31 -04:00
fc8a2b8a42 keybindings: Rename initial_selection to window
Since we removed the tabpopup, this name doesn't make much sense
anymore.
2014-05-15 15:50:31 -04:00
2ae0a72dad wayland: Don't try to autostart gnome-session
It won't work.
2014-05-15 14:16:38 -04:00
5b17c72047 backend: Create the cursor renderer after the monitor manager
The native cursor renderer needs to connect to the monitor manager's
signals.
2014-05-15 14:16:37 -04:00
8d9653dece pointer: Update the button count after repicking
The default focus interface uses the button count to determine
whether we should update the pointer focused surface. When releasing
an implicit grab, we need to send the button release events to the
implicitly grabbed surface, so we can't reset the focus surface too
soon. We already explicitly set the focus at the end of implicit
grabs, so counting the buttons after is perfectly fine.
2014-05-15 13:59:28 -04:00
e2b7b26f28 wayland: Use meta_window_move to position xdg_popup windows
This makes sure we set the user rect as well, which is necessary to
have things not "snap back" to weird locations.
2014-05-14 12:01:11 -04:00
ff2eb77fcd configure: Require a newer wayland-server 2014-05-14 09:52:37 -04:00
0588399ac7 configure: Remove old, unused configure arg 2014-05-14 09:52:37 -04:00
71544fbf4e display: Replace set_grab_op_cursor with update_cursor
Now that we don't have to regrab to change the cursor, since it's
simply the cursor on the root window, all we have to do is update
the cursor on the screen.
2014-05-14 09:20:49 -04:00
c8f3820956 backend-x11: Always pass None for the cursor
This means we fall back to what's defined on the root window, which
will give us our properly set cursor.
2014-05-13 16:20:03 -04:00
f57b0726a0 cursor-tracker: Remove the grab cursor
We expect that meta_screen_set_cursor while grabbed will properly
set the cursor on the root window. Make sure this works by simply
always using the root cursor when we have an active grab.
2014-05-13 16:20:03 -04:00
da175bca52 cursor-tracker: Use a separate cursor for xfixes cursor tracking 2014-05-13 16:20:03 -04:00
33cb7f4a2c wayland: Send a correct width / height for state changes
If we send out a configure notify for a window and then have some
other kind of state change, we need to make sure that we continue
to send out that new size, rather than the last size the client
sent us a buffer for.

In particular, a client might give us a 250x250 buffer and then
immediately request fullscreen. We send out a configure for the
monitor size and a state that tells it it's full-screen, but then
it takes focus, and since the client hasn't sent us a buffer for
the new size, we tell it it's fullscreen at 250x250.

Fix this.
2014-05-12 18:25:24 -04:00
7732447abc wayland: Update to latest xdg-shell protocol 2014-05-12 18:25:23 -04:00
c49c37999c wayland: Move appears-focused changed handling to window-wayland 2014-05-12 18:25:19 -04:00
91f35d6a01 wayland: Use standard SINCE version definitions 2014-05-12 17:01:00 -04:00
549df04ed8 Updated Spanish translation 2014-05-10 19:56:26 +02:00
4334135c52 events: Make sure to reset current_time after handling events
Otherwise, we'll have a stale value leftover in current_time that
won't be reset until the next event.
2014-05-09 11:51:28 -04:00
03c4de5590 events: Set display->current_time when we start processing the event
Otherwise, the time will be refetched during processing.
2014-05-09 11:51:28 -04:00
7a109a18af events: Move window button handling to window.c
Look at how clean GCD is now!!!
2014-05-08 15:34:27 -04:00
d9b72b0f43 events: Clean up event replay code 2014-05-08 15:30:09 -04:00
a7ea54bd7d events: Swallow all events directly on windows
This is how the X11 mode works.
2014-05-08 15:28:06 -04:00
df642b96e2 events: Replace a switch statement with a simple if test 2014-05-08 15:28:06 -04:00
f56cc1f733 events: Remove extra check for certain grab op
We already explicitly test that there's no grab op right below.
2014-05-08 15:28:06 -04:00
f5bff4b7f3 events: Move the overlay_key_only_pressed handling to keybindings.c
Now the switch statement is entirely about window operations.
2014-05-08 15:28:06 -04:00
bbfdf5dd2a events: Move keybindings event handling out of the giant switch 2014-05-08 15:28:06 -04:00
9b95eda42a events: Remove an unnecessary check 2014-05-08 15:28:06 -04:00
2d225a3386 events: Don't check if we have the grab to raise / focus a window
It isn't necessary. As an X11 compositor, we'll only see the event
if we have the grab on the window, anyway.

This was causing issues moving windows as a Wayland compositor.
2014-05-08 14:19:22 -04:00
7b3cdc8f96 display: Correct check for grab_window_buttons
When we're a Wayland compositor, we get all the events, no exceptions,
so we don't need to grab.

This was masking focusing and raising issues under nested that showed
up under native.
2014-05-08 14:19:22 -04:00
b6f9500ccc wayland: Only send wl_output.scale event if supported by the client
'scale' was introduced in version 2, so only send such an event to
clients which has bound a new enough version of wl_output.

https://bugzilla.gnome.org/show_bug.cgi?id=729602
2014-05-07 22:09:30 +02:00
ea354e96cb xprops: free the text list content too
A text list is an array of pointers into a buffer. Freeing the
array is not enough, we need to free the buffer too.

https://bugzilla.gnome.org/show_bug.cgi?id=729732
2014-05-07 19:04:54 +02:00
098c8908ed MetaStackTracker: make sure all stack ops are freed eventually
If we apply a prediction immediately instead of queueing, we should
also free the operation immediately.
If we discard the prediction queue because we resync fully, we
need to free each operation too.

https://bugzilla.gnome.org/show_bug.cgi?id=729732
2014-05-07 19:04:54 +02:00
ab632e36a5 default: free the option context after parsing
We don't need it, we should free it.

https://bugzilla.gnome.org/show_bug.cgi?id=729732
2014-05-07 19:04:54 +02:00
1427d20922 MetaDisplay: free the wayland windows table at close
Like we do for the XID table.

https://bugzilla.gnome.org/show_bug.cgi?id=729732
2014-05-07 19:04:54 +02:00
aed671810c MetaIdleMonitorDBus: unref the objects after exporting them
The object manager already has a reference.

https://bugzilla.gnome.org/show_bug.cgi?id=729732
2014-05-07 19:04:54 +02:00
324d7d720d keybindings: Don't mark a replayed keypress event as handled
This is needed so it goes to Wayland clients.
2014-05-07 09:30:22 -04:00
413e39ecbb keybindings: Fix <Super> key crash
If we exit early as not handled, then the normal process_event
handler will fire, and trigger the overlay-key binding. As that's
a special binding that doesn't have a handler, trying to trigger
that handler will crash mutter.

Instead of returning early, just check for xdisplay every time
we try to drive the X grab state machine. We really need a better
solution for this on the Wayland side.
2014-05-07 09:30:21 -04:00
2ca2c18c2a MetaMonitorConfig: don't always restore the previous config when opening the laptop lid
Only do it if the current configuration was actually created
as the result of closing the laptop lid.

https://bugzilla.gnome.org/show_bug.cgi?id=725637
2014-05-06 21:28:41 +02:00
01cd4b2ba0 MetaMonitorConfig: don't keep a previous config with the wrong outputs
We can only apply a configuration if its outputs match the connected
ones, so discard the current configuration if the set of output changes
(for example for hotplug), otherwise we will crash trying to apply
the bogus previous configuration.

https://bugzilla.gnome.org/show_bug.cgi?id=725637
2014-05-06 21:27:50 +02:00
bca210db45 Revert "Update to latest xdg-shell protocol"
This reverts commit fd5c14550a.

Again, pushed by accident, whoops.
2014-05-05 19:09:07 -04:00
66d6f73af2 Revert "ui: Remove maybe_redirect_mouse_event"
This reverts commit 6c7a51378f.

It seems we still have issues with GDK's grab tracking getting confused.
That's unfortunate.
2014-05-05 19:06:57 -04:00
bc8799d7d7 constraints: Complete fix for size hints constrainment 2014-05-05 19:06:56 -04:00
fd5c14550a Update to latest xdg-shell protocol 2014-05-05 14:15:03 -04:00
a5cca5296c window: Make sure not to eat any events that end grab ops
We need to send the button press / button release that ended a grab
op to Wayland clients so their tracking don't get confused.
2014-05-05 14:15:03 -04:00
f4ef4b79f9 constraints: Size increments need to be applied to the client rect
Not the frame rect.
2014-05-05 13:10:01 -04:00
6c7a51378f ui: Remove maybe_redirect_mouse_event
There's no cross-talk between grabs now that the backend fully manages
input properly.
2014-05-04 16:38:38 -04:00
9c4908b44a xwayland: Don't crash when the window disappears from under us
If we attach to a MetaWindow that disappears before the idle fires,
we'll notice that we can't associate the window properly again and
try to access data on the MetaWindow struct, which might crash.

Install a weak ref that ties the lifetime of the idle to the lifetime
of the MetaWindow.

It seems every GTK+ app does this for some reason at startup. This
is really unfortunate, since we'll have to create and destroy a new
MetaWindow really quickly.
2014-05-04 15:51:53 -04:00
afaab8aef2 wayland-surface: Fix warnings 2014-05-04 15:33:38 -04:00
845fdda22c keybindings: Make sure not to call meta_change_keygrab under Wayland 2014-05-03 12:50:19 -04:00
fa29a1a99e Fix last commit
Actually do the changes from the review ... pushed old version of the
patch :/
2014-05-03 12:00:27 +02:00
f9bffae9fd wayland: Scale native surfaces for hidpi
Scale surfaces based on output scale and the buffer scale set by them.
We pick the scale factor of the monitor there are mostly on.

We only handle native i.e non xwayland / legacy clients yet.

https://bugzilla.gnome.org/show_bug.cgi?id=728902
2014-05-03 10:11:55 +02:00
31c925c602 wayland: Add basic hidpi support
Advertise the scale factor on the output and transform pointer and damage
events as well as input and opaque regions for clients
that scale up by themselves i.e use set_buffer_scale.

We do not scale any 'legacy' apps yet.

https://bugzilla.gnome.org/show_bug.cgi?id=728902
2014-05-03 10:11:51 +02:00
5d310e06ba display: Remove some more unnecessary NULL checks
Instead, replace them with another assert precondition.
2014-05-02 09:37:01 -04:00
25a16c3379 Remove trailing whitespace 2014-05-02 09:34:48 -04:00
730ed6f75f [l10n] Update Catalan translation 2014-05-02 12:43:57 +02:00
a6601e92aa display: Don't grab transient's parent unconditionally
Since commit 6e8d1d79d, move operations are always performed for
the (toplevel) parent of all transient, which is just plain silly
if the dialog is not actually attached to its parent (either because
the dialog is not modal or the setting is disabled).
2014-05-02 12:27:39 +02:00
f3a2bb7779 window: Clean up old_rect handling a tiny bit
We need the old rect for two purposes: to find the x/y in a resize-only
action, and to pass into the constraints code for nefarious purposes.

The constraints code takes a frame rectangle, so we convert the original
client rect into a frame rect, but never convert it back since it's
unused for the rest of the function.

Instead of playing games with the variables, just have two,
separately-scoped variables. One is the client rect, the other is the
frame rect.
2014-05-01 19:50:39 -04:00
73e2d7049a window: Rearrange code a tiny bit 2014-05-01 19:50:38 -04:00
a6353944f6 constraints: Remove a lie
The orig / new now are about the frame rect, not the inner window
rect.
2014-05-01 19:50:38 -04:00
43d6088ebb window: Change meta_window_move_resize_internal to take a MetaRectangle
We construct one anyway, and most callers already pass in a rectangle
the long way around, so why not change the internal API?
2014-05-01 19:13:33 -04:00
e3001794f2 window-x11: Clean up formatting a bit more 2014-05-01 19:11:17 -04:00
e97ca325e6 window-x11: Clean up a bit 2014-05-01 19:10:48 -04:00
c9c6645284 window-x11: Fix a copy/paste error
We need to use the explicitly passed-in gravity here, rather
than the window's existing gravity.
2014-05-01 19:09:36 -04:00
57bb297450 window-wayland: Fix interactive resizing from the top/left once more
Ugh. So in the fullscreen case, we need to make sure to specify that
it's a MOVE_ACTION so that we move to the saved position, but we
can't do that in the resizing case since we need to use the resized
rectangle.

The flags are really hurting us here. Perhaps we should make it the
client's responsibility to specify a complete rectangle which we
could resize to; then the weird-o logic would be self-contained in
each front-end.

I'm not convinced this covers all cases, especially when we could have
a dangling weird state pointer, but it fixes our existing two testcases.
2014-05-01 18:59:17 -04:00
06ca99c3a3 window: Remove some ugly debug logging 2014-05-01 17:59:50 -04:00
4b5593c67f window: Make the x/y position in the requested_rect more accurate
For gravity-based resizing, we need to make sure that the requested
rectangle has the proper x/y position given by the gravity resize,
rather than the bogus root_x_nw / root_y_nw parameter.

Make the test for this more explicit.
2014-05-01 17:59:50 -04:00
acb3dc6754 window: Move adjust_for_gravity to window-x11
This removes the weirdness about which edge cases are where in the
move_resize_internal API, and we now always pass in client top-left
coordinates.
2014-05-01 17:59:49 -04:00
4c21a46452 window: Move the session restoration and post-manage move_resize to window-x11 2014-05-01 17:59:49 -04:00
900ae2c1fa window: Remove the borders parameter from adjust_for_gravity
We can simply use the existing cached borders.
2014-05-01 17:59:49 -04:00
01b6445708 window: Simplify adjust_for_gravity 2014-05-01 17:59:49 -04:00
292d502205 window: Fix typo in comment 2014-05-01 17:59:49 -04:00
adf2e44a82 core: Remove a few unused meta_core functions 2014-05-01 17:59:48 -04:00
b075d576a0 Updated POTFILES.skip
mutter-wayland may be dead, but src/mutter-wayland.desktop.in file
is alive and kicking.
2014-04-30 22:10:42 +02:00
142 changed files with 5184 additions and 7080 deletions

2
.gitignore vendored
View File

@ -48,7 +48,6 @@ po/*.pot
50-metacity-key.xml
libmutter.pc
mutter
mutter-launch
org.gnome.mutter.gschema.valid
org.gnome.mutter.gschema.xml
org.gnome.mutter.wayland.gschema.valid
@ -78,6 +77,7 @@ src/mutter-marshal.[ch]
src/stamp-mutter-marshal.h
src/meta-dbus-display-config.[ch]
src/meta-dbus-idle-monitor.[ch]
src/meta-dbus-login1.[ch]
src/gtk-shell-protocol.c
src/gtk-shell-server-protocol.h
src/xdg-shell-protocol.c

18
NEWS
View File

@ -1,3 +1,21 @@
3.13.2
======
* Add basic HiDPI support on wayland [Adel; #728902]
* Fix crash when monitors change during suspend [Giovanni; #725637]
* Replace mutter-launch with logind integration [Jasper; #724604]
* Move window menu into the compositor [Jasper; #726352]
* Fix delayed focus-follows-mouse support [Florian; #730541]
* Support fallback app menu in window decorations [Florian; #730752]
* Misc. bug fixes and cleanups [Giovanni, Jonas, Jasper; #729732, #729602,
#726714]
Contributors:
Jonas Ådahl, Giovanni Campagna, Adel Gadllah, Florian Müllner,
Jasper St. Pierre, Rico Tzschichholz
Translations:
Pau Iranzo [ca], Daniel Mustieles [es]
3.13.1
======
* Fix opacity values from _NET_WM_WINDOW_OPACITY [Nirbheek; #727874]

View File

@ -3,7 +3,7 @@ AC_CONFIG_MACRO_DIR([m4])
m4_define([mutter_major_version], [3])
m4_define([mutter_minor_version], [13])
m4_define([mutter_micro_version], [1])
m4_define([mutter_micro_version], [2])
m4_define([mutter_version],
[mutter_major_version.mutter_minor_version.mutter_micro_version])
@ -117,16 +117,6 @@ AC_ARG_ENABLE(shape,
[disable mutter's use of the shaped window extension]),,
enable_shape=auto)
## Wayland support requires the xserver.xml protocol extension found in the weston
## repository but since there aren't currently established conventions for
## installing and discovering these we simply require a location to be given
## explicitly...
AC_ARG_WITH([wayland-protocols],
[AS_HELP_STRING([--with-wayland-protocols], [Location for wayland extension protocol specs])],
[
],
[])
AC_ARG_WITH([xwayland-path],
[AS_HELP_STRING([--with-xwayland-path], [Absolute path for an X Wayland server])],
[XWAYLAND_PATH="$withval"],
@ -137,7 +127,6 @@ 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)
PKG_CHECK_MODULES(MUTTER_LAUNCH, libdrm libsystemd-login)
# Unconditionally use this dir to avoid a circular dep with gnomecc
GNOME_KEYBINDINGS_KEYSDIR="${datadir}/gnome-control-center/keybindings"
@ -210,7 +199,7 @@ AS_IF([test "x$WAYLAND_SCANNER" = "xno"],
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 libdrm"
MUTTER_PC_MODULES="$MUTTER_PC_MODULES clutter-wayland-1.0 clutter-wayland-compositor-1.0 clutter-egl-1.0 wayland-server >= 1.4.93 libdrm libsystemd"
PKG_CHECK_MODULES(MUTTER, $MUTTER_PC_MODULES)
PKG_CHECK_EXISTS([xi >= 1.6.99.1],

View File

@ -79,8 +79,6 @@ IGNORE_HFILES= \
iconcache.h \
inlinepixbufs.h \
keybindings-private.h \
menu.h \
metaaccellabel.h \
meta-background-actor-private.h \
meta-background-group-private.h \
meta-module.h \

View File

@ -22,8 +22,6 @@ 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/menu.c
src/ui/metaaccellabel.c
src/ui/resizepopup.c
src/ui/theme.c
src/ui/theme-parser.c

View File

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

531
po/ca.po

File diff suppressed because it is too large Load Diff

148
po/es.po
View File

@ -14,16 +14,16 @@ msgstr ""
"Project-Id-Version: mutter.master\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?"
"product=mutter&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2014-04-09 22:40+0000\n"
"PO-Revision-Date: 2014-04-10 11:04+0200\n"
"POT-Creation-Date: 2014-05-08 09:39+0000\n"
"PO-Revision-Date: 2014-05-10 19:21+0200\n"
"Last-Translator: Daniel Mustieles <daniel.mustieles@gmail.com>\n"
"Language-Team: Español <gnome-es-list@gnome.org>\n"
"Language-Team: Español; Castellano <gnome-es-list@gnome.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n!=1);\n"
"X-Generator: Gtranslator 2.91.5\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Gtranslator 2.91.6\n"
#: ../src/50-mutter-navigation.xml.in.h:1
msgid "Navigation"
@ -46,98 +46,108 @@ msgid "Move window to workspace 4"
msgstr "Mover la ventana al área de trabajo 4"
#: ../src/50-mutter-navigation.xml.in.h:6
#| msgid "Move window to workspace 1"
msgid "Move window to last workspace"
msgstr "Mover la ventana a la última área de trabajo"
#: ../src/50-mutter-navigation.xml.in.h:7
msgid "Move window one workspace to the left"
msgstr "Mover la ventana un área de trabajo a la izquierda"
#: ../src/50-mutter-navigation.xml.in.h:7
#: ../src/50-mutter-navigation.xml.in.h:8
msgid "Move window one workspace to the right"
msgstr "Mover la ventana un área de trabajo a la derecha"
#: ../src/50-mutter-navigation.xml.in.h:8
#: ../src/50-mutter-navigation.xml.in.h:9
msgid "Move window one workspace up"
msgstr "Subir la ventana un área de trabajo"
#: ../src/50-mutter-navigation.xml.in.h:9
#: ../src/50-mutter-navigation.xml.in.h:10
msgid "Move window one workspace down"
msgstr "Bajar la ventana un área de trabajo"
#: ../src/50-mutter-navigation.xml.in.h:10
#: ../src/50-mutter-navigation.xml.in.h:11
msgid "Move window one monitor to the left"
msgstr "Mover la ventana una pantalla a la izquierda"
#: ../src/50-mutter-navigation.xml.in.h:11
#: ../src/50-mutter-navigation.xml.in.h:12
msgid "Move window one monitor to the right"
msgstr "Mover la ventana una pantalla a la derecha"
#: ../src/50-mutter-navigation.xml.in.h:12
#: ../src/50-mutter-navigation.xml.in.h:13
msgid "Move window one monitor up"
msgstr "Subir la ventana una pantalla"
#: ../src/50-mutter-navigation.xml.in.h:13
#: ../src/50-mutter-navigation.xml.in.h:14
msgid "Move window one monitor down"
msgstr "Bajar la ventana una pantalla"
#: ../src/50-mutter-navigation.xml.in.h:14
#: ../src/50-mutter-navigation.xml.in.h:15
msgid "Switch applications"
msgstr "Cambiar entre aplicaciones"
#: ../src/50-mutter-navigation.xml.in.h:15
#: ../src/50-mutter-navigation.xml.in.h:16
msgid "Switch windows"
msgstr "Cambiar entre ventanas"
#: ../src/50-mutter-navigation.xml.in.h:16
#: ../src/50-mutter-navigation.xml.in.h:17
msgid "Switch windows of an application"
msgstr "Cambiar entre ventanas de una aplicación"
#: ../src/50-mutter-navigation.xml.in.h:17
#: ../src/50-mutter-navigation.xml.in.h:18
msgid "Switch system controls"
msgstr "Cambiar entre controles del sistema"
#: ../src/50-mutter-navigation.xml.in.h:18
#: ../src/50-mutter-navigation.xml.in.h:19
msgid "Switch windows directly"
msgstr "Cambiar entre ventanas directamente"
#: ../src/50-mutter-navigation.xml.in.h:19
#: ../src/50-mutter-navigation.xml.in.h:20
msgid "Switch windows of an app directly"
msgstr "Cambiar entre ventanas de una aplicación directamente"
#: ../src/50-mutter-navigation.xml.in.h:20
#: ../src/50-mutter-navigation.xml.in.h:21
msgid "Switch system controls directly"
msgstr "Cambiar entre controles del sistema directamente"
#: ../src/50-mutter-navigation.xml.in.h:21
#: ../src/50-mutter-navigation.xml.in.h:22
msgid "Hide all normal windows"
msgstr "Ocultar todas las ventanas normales"
#: ../src/50-mutter-navigation.xml.in.h:22
#: ../src/50-mutter-navigation.xml.in.h:23
msgid "Switch to workspace 1"
msgstr "Cambiar al área de trabajo 1"
#: ../src/50-mutter-navigation.xml.in.h:23
#: ../src/50-mutter-navigation.xml.in.h:24
msgid "Switch to workspace 2"
msgstr "Cambiar al área de trabajo 2"
#: ../src/50-mutter-navigation.xml.in.h:24
#: ../src/50-mutter-navigation.xml.in.h:25
msgid "Switch to workspace 3"
msgstr "Cambiar al área de trabajo 3"
#: ../src/50-mutter-navigation.xml.in.h:25
#: ../src/50-mutter-navigation.xml.in.h:26
msgid "Switch to workspace 4"
msgstr "Cambiar al área de trabajo 4"
#: ../src/50-mutter-navigation.xml.in.h:26
#: ../src/50-mutter-navigation.xml.in.h:27
#| msgid "Switch to workspace 1"
msgid "Switch to last workspace"
msgstr "Cambiar a la útima área de trabajo"
#: ../src/50-mutter-navigation.xml.in.h:28
msgid "Move to workspace left"
msgstr "Mover al área de trabajo de la izquierda"
#: ../src/50-mutter-navigation.xml.in.h:27
#: ../src/50-mutter-navigation.xml.in.h:29
msgid "Move to workspace right"
msgstr "Mover al área de trabajo de la derecha"
#: ../src/50-mutter-navigation.xml.in.h:28
#: ../src/50-mutter-navigation.xml.in.h:30
msgid "Move to workspace above"
msgstr "Mover al área de trabajo de la arriba"
#: ../src/50-mutter-navigation.xml.in.h:29
#: ../src/50-mutter-navigation.xml.in.h:31
msgid "Move to workspace below"
msgstr "Mover al área de trabajo de abajo"
@ -229,29 +239,29 @@ msgstr "Ver división a la izquierda"
msgid "View split on right"
msgstr "Ver división a la derecha"
#: ../src/backends/meta-monitor-manager.c:465
#: ../src/backends/meta-monitor-manager.c:412
msgid "Built-in display"
msgstr "Pantalla integrada"
#: ../src/backends/meta-monitor-manager.c:490
#: ../src/backends/meta-monitor-manager.c:437
msgid "Unknown"
msgstr "Desconocida"
#: ../src/backends/meta-monitor-manager.c:492
#: ../src/backends/meta-monitor-manager.c:439
msgid "Unknown Display"
msgstr "Pantalla desconocida"
#. TRANSLATORS: this is a monitor vendor name, followed by a
#. * size in inches, like 'Dell 15"'
#.
#: ../src/backends/meta-monitor-manager.c:500
#: ../src/backends/meta-monitor-manager.c:447
#, c-format
msgid "%s %s"
msgstr "%s %s"
#. This probably means that a non-WM compositor like xcompmgr is running;
#. * we have no way to get it to exit
#: ../src/compositor/compositor.c:505
#: ../src/compositor/compositor.c:464
#, c-format
msgid ""
"Another compositing manager is already running on screen %i on display \"%s"
@ -264,7 +274,7 @@ msgstr ""
msgid "background texture could not be created from file"
msgstr "no se pudo crear la textura de fondo a partir de archivo"
#: ../src/core/bell.c:213
#: ../src/core/bell.c:215
msgid "Bell event"
msgstr "Evento de campana"
@ -293,49 +303,49 @@ msgstr "_Esperar"
msgid "_Force Quit"
msgstr "_Forzar la salida"
#: ../src/core/display.c:453
#: ../src/core/display.c:451
#, c-format
msgid "Failed to open X Window System display '%s'\n"
msgstr "Ocurrió un error al abrir la pantalla de X Window System «%s»\n"
#: ../src/core/main.c:200
#: ../src/core/main.c:190
msgid "Disable connection to session manager"
msgstr "Desactivar conexión al gestor de sesión"
#: ../src/core/main.c:206
#: ../src/core/main.c:196
msgid "Replace the running window manager"
msgstr "Reemplazar el gestor de ventanas en ejecución"
#: ../src/core/main.c:212
#: ../src/core/main.c:202
msgid "Specify session management ID"
msgstr "Especificar el ID se gestión de sesión"
#: ../src/core/main.c:217
#: ../src/core/main.c:207
msgid "X Display to use"
msgstr "Pantalla X que usar"
#: ../src/core/main.c:223
#: ../src/core/main.c:213
msgid "Initialize session from savefile"
msgstr "Inicializar sesión desde el archivo de salvaguarda"
#: ../src/core/main.c:229
#: ../src/core/main.c:219
msgid "Make X calls synchronous"
msgstr "Hacer que las llamadas a las X sean síncronas"
#: ../src/core/main.c:235
#: ../src/core/main.c:225
msgid "Run as a wayland compositor"
msgstr "Ejecutar como compositor Wayland"
#: ../src/core/main.c:241
#: ../src/core/main.c:231
msgid "Run as a full display server, rather than nested"
msgstr "Ejecutar como servidor completo, en lugar de anidado"
#: ../src/core/main.c:486
#: ../src/core/main.c:476
#, c-format
msgid "Failed to scan themes directory: %s\n"
msgstr "Falló al inspeccionar la carpeta de temas: %s\n"
#: ../src/core/main.c:502
#: ../src/core/main.c:492
#, c-format
msgid ""
"Could not find a theme! Be sure %s exists and contains the usual themes.\n"
@ -366,17 +376,17 @@ msgstr "Imprimir versión"
msgid "Mutter plugin to use"
msgstr "Complemento de mutter que usar"
#: ../src/core/prefs.c:1985
#: ../src/core/prefs.c:2005
#, c-format
msgid "Workspace %d"
msgstr "Área de trabajo %d"
#: ../src/core/screen.c:543
#: ../src/core/screen.c:529
#, c-format
msgid "Screen %d on display '%s' is invalid\n"
msgstr "La ventana %d en la pantalla «%s» no es válida\n"
#: ../src/core/screen.c:559
#: ../src/core/screen.c:545
#, c-format
msgid ""
"Screen %d on display \"%s\" already has a window manager; try using the --"
@ -385,7 +395,7 @@ msgstr ""
"La ventana %d en la pantalla «%s» ya tiene un gestor de ventanas, intente "
"usar la opción «--replace» para reemplazar el gestor de ventanas activo.\n"
#: ../src/core/screen.c:664
#: ../src/core/screen.c:650
#, c-format
msgid "Screen %d on display \"%s\" already has a window manager\n"
msgstr "La ventana %d en la pantalla «%s» ya tiene un gestor de ventanas\n"
@ -398,10 +408,6 @@ msgstr "Mutter fue compilado sin soporte para modo prolijo\n"
msgid "Mutter"
msgstr "Mutter"
#: ../src/mutter-wayland.desktop.in.h:1
msgid "Mutter (wayland compositor)"
msgstr "Mutter (compositor Wayland)"
#: ../src/org.gnome.mutter.gschema.xml.in.h:1
msgid "Modifier to use for extended window management operations"
msgstr ""
@ -530,45 +536,50 @@ msgstr ""
"la pantalla, se maximizan."
#: ../src/org.gnome.mutter.gschema.xml.in.h:19
msgid "Place new windows in the center"
msgstr "Colocar las ventanas nuevas en el centro"
#: ../src/org.gnome.mutter.gschema.xml.in.h:20
msgid ""
"When true, the new windows will always be put in the center of the active "
"screen of the monitor."
msgstr ""
"Cuando es cierto, las ventanas nuevas se colocarán siempre en el centro de "
"la pantalla activa del monitor."
#: ../src/org.gnome.mutter.gschema.xml.in.h:21
msgid "Select window from tab popup"
msgstr "Seleccionar ventana de la pestaña emergente"
#: ../src/org.gnome.mutter.gschema.xml.in.h:20
#: ../src/org.gnome.mutter.gschema.xml.in.h:22
msgid "Cancel tab popup"
msgstr "Cancelar pestaña emergente"
#: ../src/org.gnome.mutter.wayland.gschema.xml.in.h:1
#| msgid "Switch to workspace 1"
msgid "Switch to VT 1"
msgstr "Cambiar al VT 1"
#: ../src/org.gnome.mutter.wayland.gschema.xml.in.h:2
#| msgid "Switch to workspace 2"
msgid "Switch to VT 2"
msgstr "Cambiar al VT 2"
#: ../src/org.gnome.mutter.wayland.gschema.xml.in.h:3
#| msgid "Switch to workspace 3"
msgid "Switch to VT 3"
msgstr "Cambiar al VT 3"
#: ../src/org.gnome.mutter.wayland.gschema.xml.in.h:4
#| msgid "Switch to workspace 4"
msgid "Switch to VT 4"
msgstr "Cambiar al VT 4"
#: ../src/org.gnome.mutter.wayland.gschema.xml.in.h:5
#| msgid "Switch to workspace 5"
msgid "Switch to VT 5"
msgstr "Cambiar al VT 5"
#: ../src/org.gnome.mutter.wayland.gschema.xml.in.h:6
#| msgid "Switch to workspace 6"
msgid "Switch to VT 6"
msgstr "Cambiar al VT 6"
#: ../src/org.gnome.mutter.wayland.gschema.xml.in.h:7
#| msgid "Switch to workspace 7"
msgid "Switch to VT 7"
msgstr "Cambiar al VT 7"
@ -654,22 +665,22 @@ msgstr "Mover al área de trabajo de a_bajo"
msgid "_Close"
msgstr "_Cerrar"
#: ../src/ui/menu.c:200
#: ../src/ui/menu.c:198
#, c-format
msgid "Workspace %d%n"
msgstr "Área de trabajo %d%n"
#: ../src/ui/menu.c:210
#: ../src/ui/menu.c:208
#, c-format
msgid "Workspace 1_0"
msgstr "Área de trabajo 1_0"
#: ../src/ui/menu.c:212
#: ../src/ui/menu.c:210
#, c-format
msgid "Workspace %s%d"
msgstr "Área de trabajo %s%d"
#: ../src/ui/menu.c:382
#: ../src/ui/menu.c:380
msgid "Move to Another _Workspace"
msgstr "Mover a _otro área de trabajo"
@ -1482,6 +1493,9 @@ msgstr ""
msgid "%s (on %s)"
msgstr "%s (on %s)"
#~ msgid "Mutter (wayland compositor)"
#~ msgstr "Mutter (compositor Wayland)"
#~ msgid "Unknown window information request: %d"
#~ msgstr "Petición de información de ventana desconocida: %d"
@ -2015,11 +2029,11 @@ msgstr "%s (on %s)"
#~ msgid "GConf key %s is already in use and can't be used to override %s\n"
#~ msgstr ""
#~ "La clave de GConf %s ya está en uso y no se puede usar para sobreescribir "
#~ "La clave de GConf %s ya está en uso y no se puede usar para sobrescribir "
#~ "%s\n"
#~ msgid "Can't override GConf key, %s not found\n"
#~ msgstr "No se puede sobreescribir la clave de GConf, no se encontró %s\n"
#~ msgstr "No se puede sobrescribir la clave de GConf, no se encontró %s\n"
#~ msgid "Error setting number of workspaces to %d: %s\n"
#~ msgstr ""

View File

@ -35,6 +35,7 @@ INCLUDES= \
mutter_built_sources = \
$(dbus_idle_built_sources) \
$(dbus_display_config_built_sources) \
$(dbus_login1_built_sources) \
mutter-enum-types.h \
mutter-enum-types.c \
gtk-shell-protocol.c \
@ -80,8 +81,12 @@ libmutter_la_SOURCES = \
backends/native/meta-monitor-manager-kms.h \
backends/native/meta-launcher.c \
backends/native/meta-launcher.h \
backends/native/dbus-utils.c \
backends/native/dbus-utils.h \
backends/x11/meta-backend-x11.c \
backends/x11/meta-backend-x11.h \
backends/x11/meta-cursor-renderer-x11.c \
backends/x11/meta-cursor-renderer-x11.h \
backends/x11/meta-idle-monitor-xsync.c \
backends/x11/meta-idle-monitor-xsync.h \
backends/x11/meta-monitor-manager-xrandr.c \
@ -189,10 +194,6 @@ libmutter_la_SOURCES = \
ui/ui.h \
ui/frames.c \
ui/frames.h \
ui/menu.c \
ui/menu.h \
ui/metaaccellabel.c \
ui/metaaccellabel.h \
ui/resizepopup.c \
ui/resizepopup.h \
ui/theme-parser.c \
@ -295,19 +296,6 @@ bin_PROGRAMS=mutter
mutter_SOURCES = core/mutter.c
mutter_LDADD = $(MUTTER_LIBS) libmutter.la
bin_PROGRAMS+=mutter-launch
mutter_launch_SOURCES = \
backends/native/weston-launch.c \
backends/native/weston-launch.h
mutter_launch_CFLAGS = $(MUTTER_LAUNCH_CFLAGS) -DLIBDIR=\"$(libdir)\"
mutter_launch_LDFLAGS = $(MUTTER_LAUNCH_LIBS) -lpam
install-exec-hook:
-chown root $(DESTDIR)$(bindir)/mutter-launch
-chmod u+s $(DESTDIR)$(bindir)/mutter-launch
if HAVE_INTROSPECTION
include $(INTROSPECTION_MAKEFILE)
@ -401,6 +389,7 @@ EXTRA_DIST=$(desktopfiles_files) \
libmutter.pc.in \
mutter-enum-types.h.in \
mutter-enum-types.c.in \
org.freedesktop.login1.xml \
org.gnome.Mutter.DisplayConfig.xml \
org.gnome.Mutter.IdleMonitor.xml
@ -444,6 +433,15 @@ $(dbus_idle_built_sources) : Makefile.am org.gnome.Mutter.IdleMonitor.xml
--c-generate-object-manager \
$(srcdir)/org.gnome.Mutter.IdleMonitor.xml
dbus_login1_built_sources = meta-dbus-login1.c meta-dbus-login1.h
$(dbus_login1_built_sources) : Makefile.am org.freedesktop.login1.xml
$(AM_V_GEN)gdbus-codegen \
--interface-prefix org.freedesktop.login1 \
--c-namespace Login1 \
--generate-c-code meta-dbus-login1 \
$(srcdir)/org.freedesktop.login1.xml
%-protocol.c : $(srcdir)/wayland/protocol/%.xml
$(AM_V_GEN)$(WAYLAND_SCANNER) code < $< > $@
%-server-protocol.h : $(srcdir)/wayland/protocol/%.xml

View File

@ -179,7 +179,7 @@ decode_display_parameters (const uchar *edid, MonitorInfo *info)
else if (edid[0x16] == 0)
{
info->width_mm = -1;
info->height_mm = -1;
info->height_mm = -1;
info->aspect_ratio = 100.0 / (edid[0x15] + 99);
}
else if (edid[0x15] == 0)
@ -267,7 +267,7 @@ decode_color_characteristics (const uchar *edid, MonitorInfo *info)
static int
decode_established_timings (const uchar *edid, MonitorInfo *info)
{
static const Timing established[][8] =
static const Timing established[][8] =
{
{
{ 800, 600, 60 },

View File

@ -1,9 +1,9 @@
/* edid.h
*
* Copyright 2007, 2008, Red Hat, Inc.
*
*
* This file is part of the Gnome Library.
*
*
* The Gnome Library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2 of the
@ -13,12 +13,12 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
*
* You should have received a copy of the GNU Library General Public
* License along with the Gnome Library; see the file COPYING.LIB. If not,
* write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*
*
* Author: Soren Sandmann <sandmann@redhat.com>
*/
@ -177,7 +177,7 @@ struct MonitorInfo
DetailedTiming detailed_timings[4]; /* If monitor has a preferred
* mode, it is the first one
* (whether it has, is
* determined by the
* determined by the
* preferred_timing_includes
* bit.
*/

View File

@ -62,6 +62,10 @@ struct _MetaBackendClass
gboolean (* ungrab_device) (MetaBackend *backend,
int device_id,
uint32_t timestamp);
void (* warp_pointer) (MetaBackend *backend,
int x,
int y);
};
#endif /* META_BACKEND_PRIVATE_H */

View File

@ -72,8 +72,8 @@ meta_backend_real_post_init (MetaBackend *backend)
{
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
priv->cursor_renderer = META_BACKEND_GET_CLASS (backend)->create_cursor_renderer (backend);
priv->monitor_manager = META_BACKEND_GET_CLASS (backend)->create_monitor_manager (backend);
priv->cursor_renderer = META_BACKEND_GET_CLASS (backend)->create_cursor_renderer (backend);
}
static MetaCursorRenderer *
@ -100,6 +100,14 @@ meta_backend_real_ungrab_device (MetaBackend *backend,
return TRUE;
}
static void
meta_backend_real_warp_pointer (MetaBackend *backend,
int x,
int y)
{
/* Do nothing */
}
static void
meta_backend_class_init (MetaBackendClass *klass)
{
@ -111,6 +119,7 @@ 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;
}
static void
@ -189,6 +198,14 @@ meta_backend_ungrab_device (MetaBackend *backend,
return META_BACKEND_GET_CLASS (backend)->ungrab_device (backend, device_id, timestamp);
}
void
meta_backend_warp_pointer (MetaBackend *backend,
int x,
int y)
{
META_BACKEND_GET_CLASS (backend)->warp_pointer (backend, x, y);
}
static GType
get_backend_type (void)
{

View File

@ -50,6 +50,10 @@ gboolean meta_backend_ungrab_device (MetaBackend *backend,
int device_id,
uint32_t timestamp);
void meta_backend_warp_pointer (MetaBackend *backend,
int x,
int y);
void meta_clutter_init (void);
#endif /* META_BACKEND_H */

View File

@ -41,6 +41,7 @@ struct _MetaCursorRendererPrivate
MetaRectangle current_rect;
MetaCursorReference *displayed_cursor;
gboolean handled_by_backend;
};
typedef struct _MetaCursorRendererPrivate MetaCursorRendererPrivate;
@ -57,19 +58,16 @@ queue_redraw (MetaCursorRenderer *renderer)
if (!stage)
return;
/* If we're not using a MetaStage, quit early */
if (!META_IS_STAGE (stage))
return;
meta_stage_set_cursor (META_STAGE (stage),
priv->displayed_cursor,
&priv->current_rect);
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);
}
static void
static gboolean
meta_cursor_renderer_real_update_cursor (MetaCursorRenderer *renderer)
{
queue_redraw (renderer);
return FALSE;
}
static void
@ -87,6 +85,8 @@ static void
update_cursor (MetaCursorRenderer *renderer)
{
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
gboolean handled_by_backend;
gboolean should_redraw = FALSE;
if (priv->displayed_cursor)
{
@ -108,7 +108,18 @@ update_cursor (MetaCursorRenderer *renderer)
priv->current_rect.height = 0;
}
META_CURSOR_RENDERER_GET_CLASS (renderer)->update_cursor (renderer);
handled_by_backend = META_CURSOR_RENDERER_GET_CLASS (renderer)->update_cursor (renderer);
if (handled_by_backend != priv->handled_by_backend)
{
priv->handled_by_backend = handled_by_backend;
should_redraw = TRUE;
}
if (!handled_by_backend)
should_redraw = TRUE;
if (should_redraw)
queue_redraw (renderer);
}
MetaCursorRenderer *

View File

@ -51,7 +51,7 @@ struct _MetaCursorRendererClass
{
GObjectClass parent_class;
void (* update_cursor) (MetaCursorRenderer *renderer);
gboolean (* update_cursor) (MetaCursorRenderer *renderer);
};
GType meta_cursor_renderer_get_type (void) G_GNUC_CONST;

View File

@ -37,23 +37,9 @@ struct _MetaCursorTracker {
gboolean is_showing;
/* The cursor tracker stores the cursor for the current grab
* operation, the cursor for the window with pointer focus, and
* the cursor for the root window, which contains either the
* default arrow cursor or the 'busy' hourglass if we're launching
* an app.
*
* We choose the first one available -- if there's a grab cursor,
* we choose that cursor, if there's window cursor, we choose that,
* otherwise we choose the root cursor.
*
* The displayed_cursor contains the chosen cursor.
*/
MetaCursorReference *displayed_cursor;
MetaCursorReference *grab_cursor;
/* Wayland clients can set a NULL buffer as their cursor
/* Wayland clients can set a NULL buffer as their cursor
* explicitly, which means that we shouldn't display anything.
* So, we can't simply store a NULL in window_cursor to
* determine an unset window cursor; we need an extra boolean.
@ -62,6 +48,9 @@ struct _MetaCursorTracker {
MetaCursorReference *window_cursor;
MetaCursorReference *root_cursor;
/* The cursor from the X11 server. */
MetaCursorReference *xfixes_cursor;
};
struct _MetaCursorTrackerClass {
@ -71,8 +60,6 @@ struct _MetaCursorTrackerClass {
gboolean meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker,
XEvent *xevent);
void meta_cursor_tracker_set_grab_cursor (MetaCursorTracker *tracker,
MetaCursorReference *cursor);
void meta_cursor_tracker_set_window_cursor (MetaCursorTracker *tracker,
MetaCursorReference *cursor);
void meta_cursor_tracker_unset_window_cursor (MetaCursorTracker *tracker);

View File

@ -1,8 +1,8 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
/*
* Copyright 2013 Red Hat, Inc.
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
@ -12,7 +12,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*
@ -63,11 +63,11 @@ get_displayed_cursor (MetaCursorTracker *tracker)
if (!tracker->is_showing)
return NULL;
if (tracker->grab_cursor)
return tracker->grab_cursor;
if (tracker->has_window_cursor)
return tracker->window_cursor;
if (tracker->screen->display->grab_op == META_GRAB_OP_NONE)
{
if (tracker->has_window_cursor)
return tracker->window_cursor;
}
return tracker->root_cursor;
}
@ -97,11 +97,6 @@ sync_cursor (MetaCursorTracker *tracker)
static void
meta_cursor_tracker_init (MetaCursorTracker *self)
{
/* (JS) Best (?) that can be assumed since XFixes doesn't provide a way of
detecting if the system mouse cursor is showing or not.
On wayland we start with the cursor showing
*/
self->is_showing = TRUE;
}
@ -224,7 +219,7 @@ meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker,
if (notify_event->subtype != XFixesDisplayCursorNotify)
return FALSE;
set_window_cursor (tracker, FALSE, NULL);
g_clear_pointer (&tracker->xfixes_cursor, meta_cursor_reference_unref);
return TRUE;
}
@ -254,7 +249,7 @@ ensure_xfixes_cursor (MetaCursorTracker *tracker)
gboolean free_cursor_data;
CoglContext *ctx;
if (tracker->has_window_cursor)
if (tracker->xfixes_cursor)
return;
cursor_image = XFixesGetCursorImage (tracker->screen->display->xdisplay);
@ -304,7 +299,7 @@ ensure_xfixes_cursor (MetaCursorTracker *tracker)
MetaCursorReference *cursor = meta_cursor_reference_take_texture (sprite,
cursor_image->xhot,
cursor_image->yhot);
set_window_cursor (tracker, TRUE, cursor);
tracker->xfixes_cursor = cursor;
}
XFree (cursor_image);
}
@ -317,13 +312,22 @@ ensure_xfixes_cursor (MetaCursorTracker *tracker)
CoglTexture *
meta_cursor_tracker_get_sprite (MetaCursorTracker *tracker)
{
MetaCursorReference *cursor;
g_return_val_if_fail (META_IS_CURSOR_TRACKER (tracker), NULL);
if (!meta_is_wayland_compositor ())
ensure_xfixes_cursor (tracker);
if (meta_is_wayland_compositor ())
{
cursor = tracker->displayed_cursor;
}
else
{
ensure_xfixes_cursor (tracker);
cursor = tracker->xfixes_cursor;
}
if (tracker->displayed_cursor)
return meta_cursor_reference_get_cogl_texture (tracker->displayed_cursor, NULL, NULL);
if (cursor)
return meta_cursor_reference_get_cogl_texture (cursor, NULL, NULL);
else
return NULL;
}
@ -340,13 +344,22 @@ meta_cursor_tracker_get_hot (MetaCursorTracker *tracker,
int *x,
int *y)
{
MetaCursorReference *cursor;
g_return_if_fail (META_IS_CURSOR_TRACKER (tracker));
if (!meta_is_wayland_compositor ())
ensure_xfixes_cursor (tracker);
if (meta_is_wayland_compositor ())
{
cursor = tracker->displayed_cursor;
}
else
{
ensure_xfixes_cursor (tracker);
cursor = tracker->xfixes_cursor;
}
if (tracker->displayed_cursor)
meta_cursor_reference_get_cogl_texture (tracker->displayed_cursor, x, y);
if (cursor)
meta_cursor_reference_get_cogl_texture (cursor, x, y);
else
{
if (x)
@ -356,17 +369,6 @@ meta_cursor_tracker_get_hot (MetaCursorTracker *tracker,
}
}
void
meta_cursor_tracker_set_grab_cursor (MetaCursorTracker *tracker,
MetaCursorReference *cursor)
{
g_clear_pointer (&tracker->grab_cursor, meta_cursor_reference_unref);
if (cursor)
tracker->grab_cursor = meta_cursor_reference_ref (cursor);
sync_cursor (tracker);
}
void
meta_cursor_tracker_set_window_cursor (MetaCursorTracker *tracker,
MetaCursorReference *cursor)
@ -466,19 +468,7 @@ meta_cursor_tracker_set_pointer_visible (MetaCursorTracker *tracker,
return;
tracker->is_showing = visible;
if (meta_is_wayland_compositor ())
{
sync_cursor (tracker);
}
else
{
if (visible)
XFixesShowCursor (tracker->screen->display->xdisplay,
tracker->screen->xroot);
else
XFixesHideCursor (tracker->screen->display->xdisplay,
tracker->screen->xroot);
}
sync_cursor (tracker);
}
MetaCursorReference *

View File

@ -1,7 +1,7 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
/*
* Copyright (C) 2013 Red Hat Inc.
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
@ -11,7 +11,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*/

View File

@ -180,6 +180,9 @@ create_monitor_skeleton (GDBusObjectManagerServer *manager,
meta_dbus_object_skeleton_set_idle_monitor (object, skeleton);
g_dbus_object_manager_server_export (manager, G_DBUS_OBJECT_SKELETON (object));
g_object_unref (skeleton);
g_object_unref (object);
}
static void

View File

@ -1,8 +1,8 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
/*
* Copyright 2013 Red Hat, Inc.
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
@ -12,7 +12,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*

View File

@ -1,8 +1,8 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
/*
* Copyright 2013 Red Hat, Inc.
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
@ -12,7 +12,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*

View File

@ -1,6 +1,6 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
/*
* Copyright (C) 2001, 2002 Havoc Pennington
* Copyright (C) 2002, 2003 Red Hat Inc.
* Some ICCCM manager selection code derived from fvwm2,
@ -8,7 +8,7 @@
* Copyright (C) 2003 Rob Adams
* Copyright (C) 2004-2006 Elijah Newren
* Copyright (C) 2013 Red Hat Inc.
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
@ -18,7 +18,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*/
@ -78,6 +78,7 @@ struct _MetaMonitorConfig {
GHashTable *configs;
MetaConfiguration *current;
gboolean current_is_stored;
gboolean current_is_for_laptop_lid;
MetaConfiguration *previous;
GFile *file;
@ -570,7 +571,7 @@ is_all_whitespace (const char *text,
gsize text_len)
{
gsize i;
for (i = 0; i < text_len; i++)
if (!g_ascii_isspace (text[i]))
return FALSE;
@ -877,7 +878,8 @@ apply_configuration (MetaMonitorConfig *self,
/* Stored (persistent) configurations override the previous one always.
Also, we clear the previous configuration if the current one (which is
about to become previous) is stored.
about to become previous) is stored, or if the current one has
different outputs.
*/
if (stored ||
(self->current && self->current_is_stored))
@ -888,11 +890,27 @@ apply_configuration (MetaMonitorConfig *self,
}
else
{
self->previous = self->current;
/* Despite the name, config_equal() only checks the set of outputs,
not their modes
*/
if (self->current && config_equal (self->current, config))
{
self->previous = self->current;
}
else
{
if (self->current)
config_free (self->current);
self->previous = NULL;
}
}
self->current = config;
self->current_is_stored = stored;
/* If true, we'll be overridden at the end of this call
inside turn_off_laptop_display()
*/
self->current_is_for_laptop_lid = FALSE;
if (self->current == self->previous)
self->previous = NULL;
@ -1009,8 +1027,16 @@ meta_monitor_config_apply_stored (MetaMonitorConfig *self,
if (self->lid_is_closed &&
stored->n_outputs > 1 &&
laptop_display_is_on (stored))
return apply_configuration (self, make_laptop_lid_config (stored),
manager, FALSE);
{
if (apply_configuration (self, make_laptop_lid_config (stored),
manager, FALSE))
{
self->current_is_for_laptop_lid = TRUE;
return TRUE;
}
else
return FALSE;
}
else
return apply_configuration (self, stored, manager, TRUE);
}
@ -1357,6 +1383,7 @@ turn_off_laptop_display (MetaMonitorConfig *self,
new = make_laptop_lid_config (self->current);
apply_configuration (self, new, manager, FALSE);
self->current_is_for_laptop_lid = TRUE;
}
static void
@ -1376,7 +1403,7 @@ power_client_changed_cb (UpClient *client,
if (is_closed)
turn_off_laptop_display (self, manager);
else
else if (self->current_is_for_laptop_lid)
meta_monitor_config_restore_previous (self, manager);
}
}

View File

@ -1,6 +1,6 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
/*
* Copyright (C) 2001, 2002 Havoc Pennington
* Copyright (C) 2002, 2003 Red Hat Inc.
* Some ICCCM manager selection code derived from fvwm2,
@ -8,7 +8,7 @@
* Copyright (C) 2003 Rob Adams
* Copyright (C) 2004-2006 Elijah Newren
* Copyright (C) 2013 Red Hat Inc.
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
@ -18,7 +18,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*/
@ -852,7 +852,7 @@ meta_monitor_manager_handle_apply_configuration (MetaDBusDisplayConfig *skeleto
/* If we were in progress of making a persistent change and we see a
new request, it's likely that the old one failed in some way, so
don't save it, but also don't queue for restoring it.
*/
*/
if (manager->persistent_timeout_id && persistent)
{
g_source_remove (manager->persistent_timeout_id);

View File

@ -12,12 +12,12 @@
* at MetaScreen instead.
*/
/*
/*
* Copyright (C) 2001 Havoc Pennington
* Copyright (C) 2003 Rob Adams
* Copyright (C) 2004-2006 Elijah Newren
* Copyright (C) 2013 Red Hat Inc.
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
@ -27,7 +27,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*/
@ -73,6 +73,7 @@ struct _MetaOutput
int width_mm;
int height_mm;
CoglSubpixelOrder subpixel_order;
int scale;
MetaMonitorMode *preferred_mode;
MetaMonitorMode **modes;

View File

@ -0,0 +1,107 @@
/* -*- 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.
*
* Written by:
* Jasper St. Pierre <jstpierre@mecheye.net>
*/
#include "config.h"
#include "dbus-utils.h"
#include <glib.h>
/* Stolen from tp_escape_as_identifier, from tp-glib,
* which follows the same escaping convention as systemd.
*/
static inline gboolean
_esc_ident_bad (gchar c, gboolean is_first)
{
return ((c < 'a' || c > 'z') &&
(c < 'A' || c > 'Z') &&
(c < '0' || c > '9' || is_first));
}
static gchar *
escape_dbus_component (const gchar *name)
{
gboolean bad = FALSE;
size_t len = 0;
GString *op;
const gchar *ptr, *first_ok;
g_return_val_if_fail (name != NULL, NULL);
/* fast path for empty name */
if (name[0] == '\0')
return g_strdup ("_");
for (ptr = name; *ptr; ptr++)
{
if (_esc_ident_bad (*ptr, ptr == name))
{
bad = TRUE;
len += 3;
}
else
len++;
}
/* fast path if it's clean */
if (!bad)
return g_strdup (name);
/* If strictly less than ptr, first_ok is the first uncopied safe character.
*/
first_ok = name;
op = g_string_sized_new (len);
for (ptr = name; *ptr; ptr++)
{
if (_esc_ident_bad (*ptr, ptr == name))
{
/* copy preceding safe characters if any */
if (first_ok < ptr)
{
g_string_append_len (op, first_ok, ptr - first_ok);
}
/* escape the unsafe character */
g_string_append_printf (op, "_%02x", (unsigned char)(*ptr));
/* restart after it */
first_ok = ptr + 1;
}
}
/* copy trailing safe characters if any */
if (first_ok < ptr)
{
g_string_append_len (op, first_ok, ptr - first_ok);
}
return g_string_free (op, FALSE);
}
char *
get_escaped_dbus_path (const char *prefix,
const char *component)
{
char *escaped_component = escape_dbus_component (component);
char *path = g_strconcat (prefix, "/", escaped_component, NULL);
g_free (escaped_component);
return path;
}

View File

@ -0,0 +1,32 @@
/* -*- 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.
*
* Written by:
* Jasper St. Pierre <jstpierre@mecheye.net>
*/
#ifndef DBUS_UTILS_H
#define DBUS_UTILS_H
char *
get_escaped_dbus_path (const char *prefix,
const char *component);
#endif /* DBUS_UTILS_H */

View File

@ -120,7 +120,7 @@ update_hw_cursor (MetaCursorRendererNative *native,
set_crtc_cursor (native, &crtcs[i], crtc_cursor, force);
if (cursor)
if (crtc_cursor)
{
drmModeMoveCursor (priv->drm_fd, crtcs[i].crtc_id,
cursor_rect->x - crtc_rect->x,
@ -140,7 +140,7 @@ should_have_hw_cursor (MetaCursorRenderer *renderer)
return FALSE;
}
static void
static gboolean
meta_cursor_renderer_native_update_cursor (MetaCursorRenderer *renderer)
{
MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer);
@ -148,10 +148,7 @@ meta_cursor_renderer_native_update_cursor (MetaCursorRenderer *renderer)
priv->has_hw_cursor = should_have_hw_cursor (renderer);
update_hw_cursor (native, FALSE);
/* Fall back to the stage-based cursor if we don't have HW cursors. */
if (!priv->has_hw_cursor)
META_CURSOR_RENDERER_CLASS (meta_cursor_renderer_native_parent_class)->update_cursor (renderer);
return priv->has_hw_cursor;
}
static void

View File

@ -20,9 +20,8 @@
#include "config.h"
#include "meta-launcher.h"
#include "weston-launch.h"
#include <gio/gunixfdmessage.h>
#include <gio/gunixfdlist.h>
#include <clutter/clutter.h>
#include <clutter/egl/clutter-egl.h>
@ -30,10 +29,17 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <malloc.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <systemd/sd-login.h>
#include "dbus-utils.h"
#include "meta-dbus-login1.h"
#include "wayland/meta-wayland-private.h"
#include "backends/meta-backend.h"
@ -41,156 +47,42 @@
struct _MetaLauncher
{
GSocket *weston_launch;
Login1Session *session_proxy;
Login1Seat *seat_proxy;
gboolean vt_switched;
GMainContext *nested_context;
GMainLoop *nested_loop;
GSource *inner_source;
GSource *outer_source;
gboolean session_active;
};
static void handle_request_vt_switch (MetaLauncher *self);
static gboolean
request_vt_switch_idle (gpointer user_data)
static Login1Session *
get_session_proxy (GCancellable *cancellable)
{
handle_request_vt_switch (user_data);
char *proxy_path;
char *session_id;
Login1Session *session_proxy;
return FALSE;
if (sd_pid_get_session (getpid (), &session_id) < 0)
return NULL;
proxy_path = get_escaped_dbus_path ("/org/freedesktop/login1/session", session_id);
session_proxy = login1_session_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
"org.freedesktop.login1",
proxy_path,
cancellable, NULL);
free (proxy_path);
return session_proxy;
}
static gboolean
send_message_to_wl (MetaLauncher *self,
void *message,
gsize size,
GSocketControlMessage *out_cmsg,
GSocketControlMessage **in_cmsg,
GError **error)
static Login1Seat *
get_seat_proxy (GCancellable *cancellable)
{
struct weston_launcher_reply reply;
GInputVector in_iov = { &reply, sizeof (reply) };
GOutputVector out_iov = { message, size };
GSocketControlMessage *out_all_cmsg[2];
GSocketControlMessage **in_all_cmsg;
int flags = 0;
int i;
out_all_cmsg[0] = out_cmsg;
out_all_cmsg[1] = NULL;
if (g_socket_send_message (self->weston_launch, NULL,
&out_iov, 1,
out_all_cmsg, -1,
flags, NULL, error) != (gssize)size)
return FALSE;
if (g_socket_receive_message (self->weston_launch, NULL,
&in_iov, 1,
&in_all_cmsg, NULL,
&flags, NULL, error) != sizeof (reply))
return FALSE;
while (reply.header.opcode != ((struct weston_launcher_message*)message)->opcode)
{
guint id;
/* There were events queued */
g_assert ((reply.header.opcode & WESTON_LAUNCHER_EVENT) == WESTON_LAUNCHER_EVENT);
/* This can never happen, because the only time mutter-launch can queue
this event is after confirming a VT switch, and we don't make requests
during that time.
Note that getting this event would be really bad, because we would be
in the wrong loop/context.
*/
g_assert (reply.header.opcode != WESTON_LAUNCHER_SERVER_VT_ENTER);
switch (reply.header.opcode)
{
case WESTON_LAUNCHER_SERVER_REQUEST_VT_SWITCH:
id = g_idle_add (request_vt_switch_idle, self);
g_source_set_name_by_id (id, "[mutter] request_vt_switch_idle");
break;
default:
g_assert_not_reached ();
}
if (g_socket_receive_message (self->weston_launch, NULL,
&in_iov, 1,
NULL, NULL,
&flags, NULL, error) != sizeof (reply))
return FALSE;
}
if (reply.ret != 0)
{
if (reply.ret == -1)
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Got failure from weston-launch");
else
g_set_error (error, G_IO_ERROR, g_io_error_from_errno (-reply.ret),
"Got failure from weston-launch: %s", strerror (-reply.ret));
for (i = 0; in_all_cmsg && in_all_cmsg[i]; i++)
g_object_unref (in_all_cmsg[i]);
g_free (in_all_cmsg);
return FALSE;
}
if (in_all_cmsg && in_all_cmsg[0])
{
for (i = 1; in_all_cmsg[i]; i++)
g_object_unref (in_all_cmsg[i]);
*in_cmsg = in_all_cmsg[0];
}
g_free (in_all_cmsg);
return TRUE;
}
static int
meta_launcher_open_device (MetaLauncher *self,
const char *name,
int flags,
GError **error)
{
struct weston_launcher_open *message;
GSocketControlMessage *cmsg;
gboolean ok;
gsize size;
int *fds, n_fd;
int ret;
size = sizeof (struct weston_launcher_open) + strlen (name) + 1;
message = g_malloc (size);
message->header.opcode = WESTON_LAUNCHER_OPEN;
message->flags = flags;
strcpy (message->path, name);
message->path[strlen(name)] = 0;
ok = send_message_to_wl (self, message, size, NULL, &cmsg, error);
if (ok)
{
g_assert (G_IS_UNIX_FD_MESSAGE (cmsg));
fds = g_unix_fd_message_steal_fds (G_UNIX_FD_MESSAGE (cmsg), &n_fd);
g_assert (n_fd == 1);
ret = fds[0];
g_free (fds);
g_object_unref (cmsg);
}
else
ret = -1;
g_free (message);
return ret;
return login1_seat_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
"org.freedesktop.login1",
"/org/freedesktop/login1/seat/self",
cancellable, NULL);
}
static void
@ -206,6 +98,7 @@ session_unpause (void)
cogl_kms_display_queue_modes_reset (cogl_display);
clutter_evdev_reclaim_devices ();
clutter_egl_thaw_master_clock ();
{
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
@ -225,6 +118,92 @@ static void
session_pause (void)
{
clutter_evdev_release_devices ();
clutter_egl_freeze_master_clock ();
}
static gboolean
take_device (Login1Session *session_proxy,
int dev_major,
int dev_minor,
int *out_fd,
GCancellable *cancellable,
GError **error)
{
gboolean ret = FALSE;
GVariant *fd_variant = NULL;
int fd = -1;
GUnixFDList *fd_list;
if (!login1_session_call_take_device_sync (session_proxy,
dev_major,
dev_minor,
NULL,
&fd_variant,
NULL, /* paused */
&fd_list,
cancellable,
error))
goto out;
fd = g_unix_fd_list_get (fd_list, g_variant_get_handle (fd_variant), error);
if (fd == -1)
goto out;
*out_fd = fd;
ret = TRUE;
out:
if (fd_variant)
g_variant_unref (fd_variant);
if (fd_list)
g_object_unref (fd_list);
return ret;
}
static gboolean
get_device_info_from_path (const char *path,
int *out_major,
int *out_minor)
{
gboolean ret = FALSE;
int r;
struct stat st;
r = stat (path, &st);
if (r < 0)
goto out;
if (!S_ISCHR (st.st_mode))
goto out;
*out_major = major (st.st_rdev);
*out_minor = minor (st.st_rdev);
ret = TRUE;
out:
return ret;
}
static gboolean
get_device_info_from_fd (int fd,
int *out_major,
int *out_minor)
{
gboolean ret = FALSE;
int r;
struct stat st;
r = fstat (fd, &st);
if (r < 0)
goto out;
if (!S_ISCHR (st.st_mode))
goto out;
*out_major = major (st.st_rdev);
*out_minor = minor (st.st_rdev);
ret = TRUE;
out:
return ret;
}
static int
@ -233,169 +212,151 @@ on_evdev_device_open (const char *path,
gpointer user_data,
GError **error)
{
MetaLauncher *launcher = user_data;
MetaLauncher *self = user_data;
int fd;
int major, minor;
return meta_launcher_open_device (launcher, path, flags, error);
if (!get_device_info_from_path (path, &major, &minor))
{
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_NOT_FOUND,
"Could not get device info for path %s: %m", path);
return -1;
}
if (!take_device (self->session_proxy, major, minor, &fd, NULL, error))
return -1;
return fd;
}
static void
on_evdev_device_close (int fd,
gpointer user_data)
{
close (fd);
MetaLauncher *self = user_data;
int major, minor;
GError *error = NULL;
if (!get_device_info_from_fd (fd, &major, &minor))
{
g_warning ("Could not get device info for fd %d: %m", fd);
return;
}
if (!login1_session_call_release_device_sync (self->session_proxy,
major, minor,
NULL, &error))
{
g_warning ("Could not release device %d,%d: %s", major, minor, error->message);
}
}
static void
handle_vt_enter (MetaLauncher *launcher)
sync_active (MetaLauncher *self)
{
g_assert (launcher->vt_switched);
g_main_loop_quit (launcher->nested_loop);
session_unpause ();
}
static void
handle_request_vt_switch (MetaLauncher *launcher)
{
struct weston_launcher_message message;
GError *error;
gboolean ok;
session_pause ();
message.opcode = WESTON_LAUNCHER_CONFIRM_VT_SWITCH;
error = NULL;
ok = send_message_to_wl (launcher, &message, sizeof (message), NULL, NULL, &error);
if (!ok) {
g_warning ("Failed to acknowledge VT switch: %s", error->message);
g_error_free (error);
gboolean active = login1_session_get_active (LOGIN1_SESSION (self->session_proxy));
if (active == self->session_active)
return;
}
g_assert (!launcher->vt_switched);
launcher->vt_switched = TRUE;
self->session_active = active;
/* We can't do anything at this point, because we don't
have input devices and we don't have the DRM master,
so let's run a nested busy loop until the VT is reentered */
g_main_loop_run (launcher->nested_loop);
if (active)
session_unpause ();
else
session_pause ();
}
g_assert (launcher->vt_switched);
launcher->vt_switched = FALSE;
session_unpause ();
static void
on_active_changed (Login1Session *session,
GParamSpec *pspec,
gpointer user_data)
{
MetaLauncher *self = user_data;
sync_active (self);
}
static gboolean
on_socket_readable (GSocket *socket,
GIOCondition condition,
gpointer user_data)
get_kms_fd (Login1Session *session_proxy,
int *fd_out)
{
MetaLauncher *launcher = user_data;
struct weston_launcher_event event;
gssize read;
GError *error;
int major, minor;
int fd;
GError *error = NULL;
if ((condition & G_IO_IN) == 0)
return TRUE;
error = NULL;
read = g_socket_receive (socket, (char*)&event, sizeof(event), NULL, &error);
if (read < (gssize)sizeof(event))
/* XXX -- use udev to find the DRM master device */
if (!get_device_info_from_path ("/dev/dri/card0", &major, &minor))
{
g_warning ("Error reading from weston-launcher socket: %s", error->message);
g_warning ("Could not stat /dev/dri/card0: %m");
return FALSE;
}
if (!take_device (session_proxy, major, minor, &fd, NULL, &error))
{
g_warning ("Could not open DRM device: %s\n", error->message);
g_error_free (error);
return TRUE;
return FALSE;
}
switch (event.header.opcode)
{
case WESTON_LAUNCHER_SERVER_REQUEST_VT_SWITCH:
handle_request_vt_switch (launcher);
break;
case WESTON_LAUNCHER_SERVER_VT_ENTER:
handle_vt_enter (launcher);
break;
}
*fd_out = fd;
return TRUE;
}
static int
env_get_fd (const char *env)
{
const char *value;
value = g_getenv (env);
if (value == NULL)
return -1;
else
return g_ascii_strtoll (value, NULL, 10);
}
MetaLauncher *
meta_launcher_new (void)
{
MetaLauncher *self = g_slice_new0 (MetaLauncher);
MetaLauncher *self;
Login1Session *session_proxy;
GError *error = NULL;
int launch_fd;
int kms_fd;
launch_fd = env_get_fd ("WESTON_LAUNCHER_SOCK");
if (launch_fd < 0)
g_error ("Invalid mutter-launch socket");
session_proxy = get_session_proxy (NULL);
if (!login1_session_call_take_control_sync (session_proxy, FALSE, NULL, &error))
{
g_warning ("Could not take control: %s", error->message);
g_error_free (error);
return NULL;
}
self->weston_launch = g_socket_new_from_fd (launch_fd, NULL);
if (!get_kms_fd (session_proxy, &kms_fd))
return NULL;
self->nested_context = g_main_context_new ();
self->nested_loop = g_main_loop_new (self->nested_context, FALSE);
self = g_slice_new0 (MetaLauncher);
self->session_proxy = session_proxy;
self->seat_proxy = get_seat_proxy (NULL);
self->outer_source = g_socket_create_source (self->weston_launch, G_IO_IN, NULL);
g_source_set_callback (self->outer_source, (GSourceFunc)on_socket_readable, self, NULL);
g_source_attach (self->outer_source, NULL);
g_source_unref (self->outer_source);
self->inner_source = g_socket_create_source (self->weston_launch, G_IO_IN, NULL);
g_source_set_callback (self->inner_source, (GSourceFunc)on_socket_readable, self, NULL);
g_source_attach (self->inner_source, self->nested_context);
g_source_unref (self->inner_source);
kms_fd = meta_launcher_open_device (self, "/dev/dri/card0", O_RDWR, &error);
if (error)
g_error ("Failed to open /dev/dri/card0: %s", error->message);
self->session_active = TRUE;
clutter_egl_set_kms_fd (kms_fd);
clutter_evdev_set_device_callbacks (on_evdev_device_open,
on_evdev_device_close,
self);
g_signal_connect (self->session_proxy, "notify::active", G_CALLBACK (on_active_changed), self);
return self;
}
void
meta_launcher_free (MetaLauncher *launcher)
meta_launcher_free (MetaLauncher *self)
{
g_source_destroy (launcher->outer_source);
g_source_destroy (launcher->inner_source);
g_main_loop_unref (launcher->nested_loop);
g_main_context_unref (launcher->nested_context);
g_object_unref (launcher->weston_launch);
g_slice_free (MetaLauncher, launcher);
g_object_unref (self->seat_proxy);
g_object_unref (self->session_proxy);
g_slice_free (MetaLauncher, self);
}
gboolean
meta_launcher_activate_session (MetaLauncher *launcher,
GError **error)
{
return meta_launcher_activate_vt (launcher, -1, error);
if (!login1_session_call_activate_sync (launcher->session_proxy, NULL, error))
return FALSE;
sync_active (launcher);
return TRUE;
}
gboolean
@ -403,10 +364,5 @@ meta_launcher_activate_vt (MetaLauncher *launcher,
signed char vt,
GError **error)
{
struct weston_launcher_activate_vt message;
message.header.opcode = WESTON_LAUNCHER_ACTIVATE_VT;
message.vt = vt;
return send_message_to_wl (launcher, &message, sizeof (message), NULL, NULL, error);
return login1_seat_call_switch_to_sync (launcher->seat_proxy, vt, NULL, error);
}

View File

@ -1,8 +1,8 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
/*
* Copyright (C) 2013 Red Hat Inc.
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
@ -12,7 +12,7 @@
* 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

View File

@ -1,711 +0,0 @@
/*
* Copyright © 2012 Benjamin Franzke
*
* 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 the copyright holders not be used in
* advertising or publicity pertaining to distribution of the software
* without specific, written prior permission. The copyright holders make
* no representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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.
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <poll.h>
#include <errno.h>
#include <error.h>
#include <getopt.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <sys/signalfd.h>
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
#include <limits.h>
#include <termios.h>
#include <linux/vt.h>
#include <linux/major.h>
#include <linux/kd.h>
#include <pwd.h>
#include <grp.h>
#include <xf86drm.h>
#include <systemd/sd-login.h>
#include "weston-launch.h"
#define MAX_ARGV_SIZE 256
#define DRM_MAJOR 226
enum vt_state {
VT_HAS_VT,
VT_PENDING_CONFIRM,
VT_NOT_HAVE_VT,
};
struct weston_launch {
int tty;
int ttynr;
int sock[2];
struct passwd *pw;
int signalfd;
pid_t child;
int verbose;
struct termios terminal_attributes;
int kb_mode;
enum vt_state vt_state;
unsigned vt;
int drm_fd;
};
union cmsg_data { unsigned char b[4]; int fd; };
static void quit (struct weston_launch *wl, int status);
static int
weston_launch_allowed(struct weston_launch *wl)
{
char *session, *seat;
int err;
if (getuid() == 0)
return 1;
err = sd_pid_get_session(getpid(), &session);
if (err == 0 && session) {
if (sd_session_is_active(session) &&
sd_session_get_seat(session, &seat) == 0) {
free(seat);
free(session);
return 1;
}
free(session);
}
return 0;
}
static int
setup_launcher_socket(struct weston_launch *wl)
{
if (socketpair(AF_LOCAL, SOCK_DGRAM, 0, wl->sock) < 0)
error(1, errno, "socketpair failed");
fcntl(wl->sock[0], F_SETFD, O_CLOEXEC);
return 0;
}
static int
setup_signals(struct weston_launch *wl)
{
int ret;
sigset_t mask;
struct sigaction sa;
memset(&sa, 0, sizeof sa);
sa.sa_handler = SIG_DFL;
sa.sa_flags = SA_NOCLDSTOP | SA_RESTART;
ret = sigaction(SIGCHLD, &sa, NULL);
assert(ret == 0);
sa.sa_handler = SIG_IGN;
sa.sa_flags = 0;
sigaction(SIGHUP, &sa, NULL);
ret = sigemptyset(&mask);
assert(ret == 0);
sigaddset(&mask, SIGCHLD);
sigaddset(&mask, SIGINT);
sigaddset(&mask, SIGTERM);
sigaddset(&mask, SIGUSR1);
ret = sigprocmask(SIG_BLOCK, &mask, NULL);
assert(ret == 0);
wl->signalfd = signalfd(-1, &mask, SFD_NONBLOCK | SFD_CLOEXEC);
if (wl->signalfd < 0)
return -errno;
return 0;
}
static void
setenv_fd(const char *env, int fd)
{
char buf[32];
snprintf(buf, sizeof buf, "%d", fd);
setenv(env, buf, 1);
}
static int
handle_confirm_vt_switch(struct weston_launch *wl, struct msghdr *msg, ssize_t len)
{
struct weston_launcher_reply reply;
reply.header.opcode = WESTON_LAUNCHER_CONFIRM_VT_SWITCH;
reply.ret = -1;
if (wl->vt_state != VT_PENDING_CONFIRM) {
error(0, 0, "unexpected CONFIRM_VT_SWITCH");
goto out;
}
if (wl->drm_fd != -1) {
int ret;
ret = drmDropMaster(wl->drm_fd);
if (ret < 0) {
fprintf(stderr, "failed to drop DRM master: %m\n");
} else if (wl->verbose) {
fprintf(stderr, "dropped DRM master for VT switch\n");
}
}
wl->vt_state = VT_NOT_HAVE_VT;
ioctl(wl->tty, VT_RELDISP, 1);
if (wl->verbose)
fprintf(stderr, "mutter-launcher: confirmed VT switch\n");
reply.ret = 0;
out:
do {
len = send(wl->sock[0], &reply, sizeof reply, 0);
} while (len < 0 && errno == EINTR);
if (len < 0)
return -1;
return 0;
}
static int
handle_activate_vt(struct weston_launch *wl, struct msghdr *msg, ssize_t len)
{
struct weston_launcher_reply reply;
struct weston_launcher_activate_vt *message;
unsigned vt;
reply.header.opcode = WESTON_LAUNCHER_ACTIVATE_VT;
reply.ret = -1;
if (len != sizeof(*message)) {
error(0, 0, "missing value in activate_vt request");
goto out;
}
message = msg->msg_iov->iov_base;
/* Negative values mean that we're activating our own VT */
if (message->vt > 0)
vt = message->vt;
else
vt = wl->vt;
reply.ret = ioctl(wl->tty, VT_ACTIVATE, vt);
if (reply.ret < 0)
reply.ret = -errno;
if (wl->verbose)
fprintf(stderr, "mutter-launch: activate VT, ret: %d\n", reply.ret);
out:
do {
len = send(wl->sock[0], &reply, sizeof reply, 0);
} while (len < 0 && errno == EINTR);
if (len < 0)
return -1;
return 0;
}
static int
handle_open(struct weston_launch *wl, struct msghdr *msg, ssize_t len)
{
struct weston_launcher_reply reply;
int fd = -1;
char control[CMSG_SPACE(sizeof(fd))];
struct cmsghdr *cmsg;
struct stat s;
struct msghdr nmsg;
struct iovec iov;
struct weston_launcher_open *message;
union cmsg_data *data;
int dev_major;
reply.header.opcode = WESTON_LAUNCHER_OPEN;
reply.ret = -1;
message = msg->msg_iov->iov_base;
if ((size_t)len < sizeof(*message))
goto err0;
/* Ensure path is null-terminated */
((char *) message)[len-1] = '\0';
if (stat(message->path, &s) < 0) {
reply.ret = -errno;
goto err0;
}
dev_major = major(s.st_rdev);
if (dev_major != INPUT_MAJOR &&
dev_major != DRM_MAJOR) {
fprintf(stderr, "Device %s is not an input or DRM device\n",
message->path);
reply.ret = -EPERM;
goto err0;
}
if (dev_major == DRM_MAJOR && wl->drm_fd != -1) {
fprintf(stderr, "Already have a DRM device open\n");
reply.ret = -EPERM;
goto err0;
}
fd = open(message->path, message->flags);
if (fd < 0) {
fprintf(stderr, "Error opening device %s: %m\n",
message->path);
reply.ret = -errno;
goto err0;
}
if (dev_major == DRM_MAJOR) {
wl->drm_fd = fd;
}
err0:
memset(&nmsg, 0, sizeof nmsg);
nmsg.msg_iov = &iov;
nmsg.msg_iovlen = 1;
if (fd != -1) {
nmsg.msg_control = control;
nmsg.msg_controllen = sizeof control;
cmsg = CMSG_FIRSTHDR(&nmsg);
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS;
cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
data = (union cmsg_data *) CMSG_DATA(cmsg);
data->fd = fd;
nmsg.msg_controllen = cmsg->cmsg_len;
reply.ret = 0;
}
iov.iov_base = &reply;
iov.iov_len = sizeof reply;
if (wl->verbose)
fprintf(stderr, "mutter-launch: opened %s: ret: %d, fd: %d\n",
message->path, reply.ret, fd);
do {
len = sendmsg(wl->sock[0], &nmsg, 0);
} while (len < 0 && errno == EINTR);
close(fd);
if (len < 0)
return -1;
return 0;
}
static int
handle_socket_msg(struct weston_launch *wl)
{
char control[CMSG_SPACE(sizeof(int))];
char buf[BUFSIZ];
struct msghdr msg;
struct iovec iov;
int ret = -1;
ssize_t len;
struct weston_launcher_message *message;
memset(&msg, 0, sizeof(msg));
iov.iov_base = buf;
iov.iov_len = sizeof buf;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = control;
msg.msg_controllen = sizeof control;
do {
len = recvmsg(wl->sock[0], &msg, 0);
} while (len < 0 && errno == EINTR);
if (len < 1)
return -1;
message = (void *) buf;
switch (message->opcode) {
case WESTON_LAUNCHER_OPEN:
ret = handle_open(wl, &msg, len);
break;
case WESTON_LAUNCHER_CONFIRM_VT_SWITCH:
ret = handle_confirm_vt_switch(wl, &msg, len);
break;
case WESTON_LAUNCHER_ACTIVATE_VT:
ret = handle_activate_vt(wl, &msg, len);
break;
}
return ret;
}
static void
tty_reset(struct weston_launch *wl)
{
struct vt_mode mode = { 0 };
if (ioctl(wl->tty, KDSKBMODE, wl->kb_mode))
fprintf(stderr, "failed to restore keyboard mode: %m\n");
if (ioctl(wl->tty, KDSETMODE, KD_TEXT))
fprintf(stderr, "failed to set KD_TEXT mode on tty: %m\n");
if (tcsetattr(wl->tty, TCSANOW, &wl->terminal_attributes) < 0)
fprintf(stderr, "could not restore terminal to canonical mode\n");
mode.mode = VT_AUTO;
if (ioctl(wl->tty, VT_SETMODE, &mode) < 0)
fprintf(stderr, "could not reset vt handling\n");
}
static void
quit(struct weston_launch *wl, int status)
{
if (wl->child > 0)
kill(wl->child, SIGKILL);
close(wl->signalfd);
close(wl->sock[0]);
if (wl->drm_fd > 0)
close(wl->drm_fd);
tty_reset(wl);
exit(status);
}
static int
handle_vt_switch(struct weston_launch *wl)
{
struct weston_launcher_event message;
ssize_t len;
if (wl->vt_state == VT_HAS_VT) {
wl->vt_state = VT_PENDING_CONFIRM;
message.header.opcode = WESTON_LAUNCHER_SERVER_REQUEST_VT_SWITCH;
} else if (wl->vt_state == VT_NOT_HAVE_VT) {
wl->vt_state = VT_HAS_VT;
ioctl(wl->tty, VT_RELDISP, VT_ACKACQ);
if (wl->drm_fd != -1) {
int ret;
ret = drmSetMaster(wl->drm_fd);
if (ret < 0) {
fprintf(stderr, "failed to become DRM master: %m\n");
/* This is very, very bad, and the compositor will crash soon,
but oh well... */
} else if (wl->verbose) {
fprintf(stderr, "became DRM master after VT switch\n");
}
}
message.header.opcode = WESTON_LAUNCHER_SERVER_VT_ENTER;
} else
return -1;
message.detail = 0;
do {
len = send(wl->sock[0], &message, sizeof(message), 0);
} while (len < 0 && errno == EINTR);
return 0;
}
static int
handle_signal(struct weston_launch *wl)
{
struct signalfd_siginfo sig;
int pid, status, ret;
if (read(wl->signalfd, &sig, sizeof sig) != sizeof sig) {
error(0, errno, "reading signalfd failed");
return -1;
}
switch (sig.ssi_signo) {
case SIGCHLD:
pid = waitpid(-1, &status, 0);
if (pid == wl->child) {
wl->child = 0;
if (WIFEXITED(status))
ret = WEXITSTATUS(status);
else if (WIFSIGNALED(status))
/*
* If weston dies because of signal N, we
* return 10+N. This is distinct from
* weston-launch dying because of a signal
* (128+N).
*/
ret = 10 + WTERMSIG(status);
else
ret = 0;
quit(wl, ret);
}
break;
case SIGTERM:
case SIGINT:
if (wl->child)
kill(wl->child, sig.ssi_signo);
break;
case SIGUSR1:
return handle_vt_switch(wl);
default:
return -1;
}
return 0;
}
static int
setup_tty(struct weston_launch *wl)
{
struct stat buf;
struct termios raw_attributes;
struct vt_mode mode = { 0 };
char *session;
char path[PATH_MAX];
int ok;
ok = sd_pid_get_session(getpid(), &session);
if (ok < 0)
error(1, -ok, "could not determine current session");
ok = sd_session_get_vt(session, &wl->vt);
if (ok < 0)
error(1, -ok, "could not determine current TTY");
snprintf(path, PATH_MAX, "/dev/tty%u", wl->vt);
wl->tty = open(path, O_RDWR | O_NOCTTY | O_CLOEXEC);
if (wl->tty < 0)
error(1, errno, "failed to open tty");
if (fstat(wl->tty, &buf) < 0)
error(1, errno, "stat %s failed", path);
if (major(buf.st_rdev) != TTY_MAJOR)
error(1, 0, "invalid tty device: %s", path);
wl->ttynr = minor(buf.st_rdev);
if (tcgetattr(wl->tty, &wl->terminal_attributes) < 0)
error(1, errno, "could not get terminal attributes");
/* Ignore control characters and disable echo */
raw_attributes = wl->terminal_attributes;
cfmakeraw(&raw_attributes);
/* Fix up line endings to be normal (cfmakeraw hoses them) */
raw_attributes.c_oflag |= OPOST | OCRNL;
/* Don't generate ttou signals */
raw_attributes.c_oflag &= ~TOSTOP;
if (tcsetattr(wl->tty, TCSANOW, &raw_attributes) < 0)
error(1, errno, "could not put terminal into raw mode");
ioctl(wl->tty, KDGKBMODE, &wl->kb_mode);
ok = ioctl(wl->tty, KDSKBMODE, K_OFF);
if (ok < 0) {
ok = ioctl(wl->tty, KDSKBMODE, K_RAW);
if (ok < 0)
error(1, errno, "failed to set keyboard mode on tty");
}
ok = ioctl(wl->tty, KDSETMODE, KD_GRAPHICS);
if (ok < 0)
error(1, errno, "failed to set KD_GRAPHICS mode on tty");
wl->vt_state = VT_HAS_VT;
mode.mode = VT_PROCESS;
mode.relsig = SIGUSR1;
mode.acqsig = SIGUSR1;
ok = ioctl(wl->tty, VT_SETMODE, &mode);
if (ok < 0)
error(1, errno, "failed to take control of vt handling");
return 0;
}
static void
drop_privileges(struct weston_launch *wl)
{
if (setgid(wl->pw->pw_gid) < 0 ||
#ifdef HAVE_INITGROUPS
initgroups(wl->pw->pw_name, wl->pw->pw_gid) < 0 ||
#endif
setuid(wl->pw->pw_uid) < 0)
error(1, errno, "dropping privileges failed");
}
static void
launch_compositor(struct weston_launch *wl, int argc, char *argv[])
{
char command[PATH_MAX];
char *child_argv[MAX_ARGV_SIZE];
sigset_t mask;
int i;
if (wl->verbose)
printf("weston-launch: spawned weston with pid: %d\n", getpid());
drop_privileges(wl);
setenv_fd("WESTON_LAUNCHER_SOCK", wl->sock[1]);
setenv("LD_LIBRARY_PATH", LIBDIR, 1);
unsetenv("DISPLAY");
/* Do not give our signal mask to the new process. */
sigemptyset(&mask);
sigaddset(&mask, SIGTERM);
sigaddset(&mask, SIGCHLD);
sigaddset(&mask, SIGINT);
sigaddset(&mask, SIGUSR1);
sigprocmask(SIG_UNBLOCK, &mask, NULL);
snprintf (command, PATH_MAX, "%s \"$@\"", argv[0]);
child_argv[0] = wl->pw->pw_shell;
child_argv[1] = "-l";
child_argv[2] = "-c";
child_argv[3] = command;
for (i = 0; i < argc; ++i)
child_argv[4 + i] = argv[i];
child_argv[4 + i] = NULL;
execv(child_argv[0], child_argv);
error(1, errno, "exec failed");
}
static void
help(const char *name)
{
fprintf(stderr, "Usage: %s [args...] [-- [weston args..]]\n", name);
fprintf(stderr, " -u, --user Start session as specified username\n");
fprintf(stderr, " -v, --verbose Be verbose\n");
fprintf(stderr, " -h, --help Display this help message\n");
}
int
main(int argc, char *argv[])
{
struct weston_launch wl;
int i, c;
struct option opts[] = {
{ "verbose", no_argument, NULL, 'v' },
{ "help", no_argument, NULL, 'h' },
{ 0, 0, NULL, 0 }
};
memset(&wl, 0, sizeof wl);
wl.drm_fd = -1;
while ((c = getopt_long(argc, argv, "u:t::vh", opts, &i)) != -1) {
switch (c) {
case 'v':
wl.verbose = 1;
break;
case 'h':
help("mutter-launch");
exit(EXIT_FAILURE);
}
}
if ((argc - optind) > (MAX_ARGV_SIZE - 6))
error(1, E2BIG, "Too many arguments to pass to weston");
if (optind >= argc)
error(1, 0, "Expected program argument");
wl.pw = getpwuid(getuid());
if (wl.pw == NULL)
error(1, errno, "failed to get username");
if (!weston_launch_allowed(&wl))
error(1, 0, "Permission denied. You must run from an active and local (systemd) session.");
if (setup_tty(&wl) < 0)
exit(EXIT_FAILURE);
if (setup_launcher_socket(&wl) < 0)
exit(EXIT_FAILURE);
if (setup_signals(&wl) < 0)
exit(EXIT_FAILURE);
wl.child = fork();
if (wl.child == -1) {
error(1, errno, "fork failed");
exit(EXIT_FAILURE);
}
if (wl.child == 0)
launch_compositor(&wl, argc - optind, argv + optind);
close(wl.sock[1]);
while (1) {
struct pollfd fds[2];
int n;
fds[0].fd = wl.sock[0];
fds[0].events = POLLIN;
fds[1].fd = wl.signalfd;
fds[1].events = POLLIN;
n = poll(fds, 2, -1);
if (n < 0)
error(0, errno, "poll failed");
if (fds[0].revents & POLLIN)
handle_socket_msg(&wl);
if (fds[1].revents)
handle_signal(&wl);
}
return 0;
}

View File

@ -1,68 +0,0 @@
/*
* Copyright © 2012 Benjamin Franzke
* 2013 Red Hat, Inc.
*
* 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 the copyright holders not be used in
* advertising or publicity pertaining to distribution of the software
* without specific, written prior permission. The copyright holders make
* no representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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.
*/
#ifndef _WESTON_LAUNCH_H_
#define _WESTON_LAUNCH_H_
enum weston_launcher_message_type {
WESTON_LAUNCHER_REQUEST,
WESTON_LAUNCHER_EVENT,
};
enum weston_launcher_opcode {
WESTON_LAUNCHER_OPEN = (1 << 1 | WESTON_LAUNCHER_REQUEST),
WESTON_LAUNCHER_ACTIVATE_VT = (2 << 1 | WESTON_LAUNCHER_REQUEST),
WESTON_LAUNCHER_CONFIRM_VT_SWITCH = (3 << 1 | WESTON_LAUNCHER_REQUEST),
};
enum weston_launcher_server_opcode {
WESTON_LAUNCHER_SERVER_REQUEST_VT_SWITCH = (1 << 1 | WESTON_LAUNCHER_EVENT),
WESTON_LAUNCHER_SERVER_VT_ENTER = (2 << 1 | WESTON_LAUNCHER_EVENT),
};
struct weston_launcher_message {
int opcode;
};
struct weston_launcher_open {
struct weston_launcher_message header;
int flags;
char path[0];
};
struct weston_launcher_activate_vt {
struct weston_launcher_message header;
signed char vt;
};
struct weston_launcher_reply {
struct weston_launcher_message header;
int ret;
};
struct weston_launcher_event {
struct weston_launcher_message header;
int detail; /* unused, but makes sure replies and events are serialized the same */
};
#endif

View File

@ -33,9 +33,8 @@
#include "meta-idle-monitor-xsync.h"
#include "meta-monitor-manager-xrandr.h"
#include "backends/meta-monitor-manager-dummy.h"
#include "meta-cursor-renderer-x11.h"
#include "meta-cursor-tracker-private.h"
#include "meta-cursor.h"
#include <meta/util.h>
#include "display-private.h"
#include "compositor/compositor-private.h"
@ -68,21 +67,11 @@ handle_alarm_notify (MetaBackend *backend,
meta_idle_monitor_xsync_handle_xevent (backend->device_monitors[i], (XSyncAlarmNotifyEvent*) event);
}
static Window
get_stage_window (MetaBackendX11 *x11)
{
MetaDisplay *display = meta_get_display ();
MetaCompositor *compositor = display->compositor;
ClutterStage *stage = CLUTTER_STAGE (compositor->stage);
return clutter_x11_get_stage_window (stage);
}
static void
translate_device_event (MetaBackendX11 *x11,
XIDeviceEvent *device_event)
{
Window stage_window = get_stage_window (x11);
Window stage_window = meta_backend_x11_get_xwindow (x11);
if (device_event->event != stage_window)
{
@ -307,6 +296,12 @@ meta_backend_x11_create_monitor_manager (MetaBackend *backend)
return g_object_new (META_TYPE_MONITOR_MANAGER_XRANDR, NULL);
}
static MetaCursorRenderer *
meta_backend_x11_create_cursor_renderer (MetaBackend *backend)
{
return g_object_new (META_TYPE_CURSOR_RENDERER_X11, NULL);
}
static gboolean
meta_backend_x11_grab_device (MetaBackend *backend,
int device_id,
@ -326,14 +321,10 @@ meta_backend_x11_grab_device (MetaBackend *backend,
XISetMask (mask.mask, XI_KeyPress);
XISetMask (mask.mask, XI_KeyRelease);
MetaCursorTracker *tracker = meta_cursor_tracker_get_for_screen (NULL);
MetaCursorReference *cursor_ref = meta_cursor_tracker_get_displayed_cursor (tracker);
MetaCursor cursor = meta_cursor_reference_get_meta_cursor (cursor_ref);
ret = XIGrabDevice (priv->xdisplay, device_id,
get_stage_window (x11),
meta_backend_x11_get_xwindow (x11),
timestamp,
meta_cursor_create_x_cursor (priv->xdisplay, cursor),
None,
XIGrabModeAsync, XIGrabModeAsync,
False, /* owner_events */
&mask);
@ -355,6 +346,22 @@ meta_backend_x11_ungrab_device (MetaBackend *backend,
return (ret == Success);
}
static void
meta_backend_x11_warp_pointer (MetaBackend *backend,
int x,
int y)
{
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
XIWarpPointer (priv->xdisplay,
META_VIRTUAL_CORE_POINTER_ID,
None,
meta_backend_x11_get_xwindow (x11),
0, 0, 0, 0,
x, y);
}
static void
meta_backend_x11_class_init (MetaBackendX11Class *klass)
{
@ -363,9 +370,11 @@ meta_backend_x11_class_init (MetaBackendX11Class *klass)
backend_class->post_init = meta_backend_x11_post_init;
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;
}
static void
@ -383,3 +392,15 @@ meta_backend_x11_get_xdisplay (MetaBackendX11 *x11)
return priv->xdisplay;
}
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);
}

View File

@ -53,4 +53,6 @@ GType meta_backend_x11_get_type (void) G_GNUC_CONST;
Display * meta_backend_x11_get_xdisplay (MetaBackendX11 *backend);
Window meta_backend_x11_get_xwindow (MetaBackendX11 *backend);
#endif /* META_BACKEND_X11_H */

View File

@ -0,0 +1,99 @@
/* -*- 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.
*
* Written by:
* Jasper St. Pierre <jstpierre@mecheye.net>
*/
#include "config.h"
#include "meta-cursor-renderer-x11.h"
#include "meta-backend-x11.h"
#include "meta-stage.h"
struct _MetaCursorRendererX11Private
{
gboolean server_cursor_visible;
};
typedef struct _MetaCursorRendererX11Private MetaCursorRendererX11Private;
G_DEFINE_TYPE_WITH_PRIVATE (MetaCursorRendererX11, meta_cursor_renderer_x11, META_TYPE_CURSOR_RENDERER);
static gboolean
meta_cursor_renderer_x11_update_cursor (MetaCursorRenderer *renderer)
{
MetaCursorRendererX11 *x11 = META_CURSOR_RENDERER_X11 (renderer);
MetaCursorRendererX11Private *priv = meta_cursor_renderer_x11_get_instance_private (x11);
MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ());
Window xwindow = meta_backend_x11_get_xwindow (backend);
if (xwindow == None)
return FALSE;
Display *xdisplay = meta_backend_x11_get_xdisplay (backend);
MetaCursorReference *cursor_ref = meta_cursor_renderer_get_cursor (renderer);
gboolean has_server_cursor = FALSE;
if (cursor_ref)
{
MetaCursor cursor = meta_cursor_reference_get_meta_cursor (cursor_ref);
if (cursor != META_CURSOR_NONE)
{
Cursor xcursor = meta_cursor_create_x_cursor (xdisplay, cursor);
XDefineCursor (xdisplay, xwindow, xcursor);
XFlush (xdisplay);
XFreeCursor (xdisplay, xcursor);
has_server_cursor = TRUE;
}
}
if (has_server_cursor != priv->server_cursor_visible)
{
if (has_server_cursor)
XFixesShowCursor (xdisplay, xwindow);
else
XFixesHideCursor (xdisplay, xwindow);
priv->server_cursor_visible = has_server_cursor;
}
return priv->server_cursor_visible;
}
static void
meta_cursor_renderer_x11_class_init (MetaCursorRendererX11Class *klass)
{
MetaCursorRendererClass *renderer_class = META_CURSOR_RENDERER_CLASS (klass);
renderer_class->update_cursor = meta_cursor_renderer_x11_update_cursor;
}
static void
meta_cursor_renderer_x11_init (MetaCursorRendererX11 *x11)
{
MetaCursorRendererX11Private *priv = meta_cursor_renderer_x11_get_instance_private (x11);
/* XFixes has no way to retrieve the current cursor visibility. */
priv->server_cursor_visible = TRUE;
}

View File

@ -0,0 +1,52 @@
/* -*- 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.
*
* Written by:
* Jasper St. Pierre <jstpierre@mecheye.net>
*/
#ifndef META_CURSOR_RENDERER_X11_H
#define META_CURSOR_RENDERER_X11_H
#include "meta-cursor-renderer.h"
#define META_TYPE_CURSOR_RENDERER_X11 (meta_cursor_renderer_x11_get_type ())
#define META_CURSOR_RENDERER_X11(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_CURSOR_RENDERER_X11, MetaCursorRendererX11))
#define META_CURSOR_RENDERER_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_CURSOR_RENDERER_X11, MetaCursorRendererX11Class))
#define META_IS_CURSOR_RENDERER_X11(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_CURSOR_RENDERER_X11))
#define META_IS_CURSOR_RENDERER_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_CURSOR_RENDERER_X11))
#define META_CURSOR_RENDERER_X11_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_CURSOR_RENDERER_X11, MetaCursorRendererX11Class))
typedef struct _MetaCursorRendererX11 MetaCursorRendererX11;
typedef struct _MetaCursorRendererX11Class MetaCursorRendererX11Class;
struct _MetaCursorRendererX11
{
MetaCursorRenderer parent;
};
struct _MetaCursorRendererX11Class
{
MetaCursorRendererClass parent_class;
};
GType meta_cursor_renderer_x11_get_type (void) G_GNUC_CONST;
#endif /* META_CURSOR_RENDERER_X11_H */

View File

@ -1,6 +1,6 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
/*
* Copyright (C) 2001, 2002 Havoc Pennington
* Copyright (C) 2002, 2003 Red Hat Inc.
* Some ICCCM manager selection code derived from fvwm2,
@ -8,7 +8,7 @@
* Copyright (C) 2003 Rob Adams
* Copyright (C) 2004-2006 Elijah Newren
* Copyright (C) 2013 Red Hat Inc.
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
@ -18,7 +18,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*/
@ -272,7 +272,7 @@ get_edid_property (Display *dpy,
}
XFree (prop);
return result;
}
@ -918,6 +918,7 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
}
XUngrabServer (manager_xrandr->xdisplay);
XFlush (manager_xrandr->xdisplay);
}
static void

View File

@ -555,10 +555,10 @@ meta_compositor_manage (MetaCompositor *compositor)
meta_empty_stage_input_region (screen);
/* Make sure there isn't any left-over output shape on the
/* Make sure there isn't any left-over output shape on the
* overlay window by setting the whole screen to be an
* output region.
*
*
* Note: there doesn't seem to be any real chance of that
* because the X server will destroy the overlay window
* when the last client using it exits.
@ -746,9 +746,9 @@ meta_compositor_window_surface_changed (MetaCompositor *compositor,
/**
* meta_compositor_process_event: (skip)
* @compositor:
* @event:
* @window:
* @compositor:
* @event:
* @window:
*
*/
gboolean
@ -1356,3 +1356,13 @@ meta_compositor_hide_tile_preview (MetaCompositor *compositor)
{
meta_plugin_manager_hide_tile_preview (compositor->plugin_mgr);
}
void
meta_compositor_show_window_menu (MetaCompositor *compositor,
MetaWindow *window,
MetaWindowMenuType menu,
int x,
int y)
{
meta_plugin_manager_show_window_menu (compositor->plugin_mgr, window, menu, x, y);
}

View File

@ -356,3 +356,21 @@ meta_plugin_manager_hide_tile_preview (MetaPluginManager *plugin_mgr)
return FALSE;
}
void
meta_plugin_manager_show_window_menu (MetaPluginManager *plugin_mgr,
MetaWindow *window,
MetaWindowMenuType menu,
int x,
int y)
{
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)
klass->show_window_menu (plugin, window, menu, x, y);
}

View File

@ -80,4 +80,12 @@ gboolean meta_plugin_manager_show_tile_preview (MetaPluginManager *mgr,
MetaRectangle *tile_rect,
int tile_monitor_number);
gboolean meta_plugin_manager_hide_tile_preview (MetaPluginManager *mgr);
void meta_plugin_manager_show_window_menu (MetaPluginManager *mgr,
MetaWindow *window,
MetaWindowMenuType menu,
int x,
int y);
#endif

View File

@ -108,6 +108,62 @@ meta_surface_actor_wayland_is_unredirected (MetaSurfaceActor *actor)
return FALSE;
}
static int
get_output_scale (int output_id)
{
MetaMonitorManager *monitor_manager = meta_monitor_manager_get ();
MetaOutput *outputs;
guint n_outputs, i;
int output_scale = 1;
outputs = meta_monitor_manager_get_outputs (monitor_manager, &n_outputs);
for (i = 0; i < n_outputs; i++)
{
if (outputs[i].output_id == output_id)
{
output_scale = outputs[i].scale;
break;
}
}
return output_scale;
}
double
meta_surface_actor_wayland_get_scale (MetaSurfaceActorWayland *actor)
{
MetaSurfaceActorWaylandPrivate *priv = meta_surface_actor_wayland_get_instance_private (actor);
MetaWaylandSurface *surface = priv->surface;
MetaWindow *window = surface->window;
int output_scale = 1;
while (surface)
{
if (surface->window)
{
window = surface->window;
break;
}
surface = surface->sub.parent;
}
/* 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);
return (double)output_scale / (double)priv->surface->scale;
}
void
meta_surface_actor_wayland_scale_texture (MetaSurfaceActorWayland *actor)
{
MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (actor));
double output_scale = meta_surface_actor_wayland_get_scale (actor);
clutter_actor_set_scale (CLUTTER_ACTOR (stex), output_scale, output_scale);
}
static MetaWindow *
meta_surface_actor_wayland_get_window (MetaSurfaceActor *actor)
{
@ -116,6 +172,42 @@ meta_surface_actor_wayland_get_window (MetaSurfaceActor *actor)
return priv->surface->window;
}
static void
meta_surface_actor_wayland_get_preferred_width (ClutterActor *self,
gfloat for_height,
gfloat *min_width_p,
gfloat *natural_width_p)
{
MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self));
double scale = meta_surface_actor_wayland_get_scale (META_SURFACE_ACTOR_WAYLAND (self));
clutter_actor_get_preferred_width (CLUTTER_ACTOR (stex), for_height, min_width_p, natural_width_p);
if (min_width_p)
*min_width_p *= scale;
if (natural_width_p)
*natural_width_p *= scale;
}
static void
meta_surface_actor_wayland_get_preferred_height (ClutterActor *self,
gfloat for_width,
gfloat *min_height_p,
gfloat *natural_height_p)
{
MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self));
double scale = meta_surface_actor_wayland_get_scale (META_SURFACE_ACTOR_WAYLAND (self));
clutter_actor_get_preferred_height (CLUTTER_ACTOR (stex), for_width, min_height_p, natural_height_p);
if (min_height_p)
*min_height_p *= scale;
if (natural_height_p)
*natural_height_p *= scale;
}
static void
meta_surface_actor_wayland_dispose (GObject *object)
{
@ -130,8 +222,12 @@ static void
meta_surface_actor_wayland_class_init (MetaSurfaceActorWaylandClass *klass)
{
MetaSurfaceActorClass *surface_actor_class = META_SURFACE_ACTOR_CLASS (klass);
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
actor_class->get_preferred_width = meta_surface_actor_wayland_get_preferred_width;
actor_class->get_preferred_height = meta_surface_actor_wayland_get_preferred_height;
surface_actor_class->process_damage = meta_surface_actor_wayland_process_damage;
surface_actor_class->pre_paint = meta_surface_actor_wayland_pre_paint;
surface_actor_class->is_visible = meta_surface_actor_wayland_is_visible;

View File

@ -61,6 +61,9 @@ MetaWaylandSurface * meta_surface_actor_wayland_get_surface (MetaSurfaceActorWay
void meta_surface_actor_wayland_set_buffer (MetaSurfaceActorWayland *self,
MetaWaylandBuffer *buffer);
double meta_surface_actor_wayland_get_scale (MetaSurfaceActorWayland *actor);
void meta_surface_actor_wayland_scale_texture (MetaSurfaceActorWayland *actor);
G_END_DECLS
#endif /* __META_SURFACE_ACTOR_WAYLAND_H__ */

View File

@ -32,6 +32,7 @@
#include "meta-surface-actor.h"
#include "meta-surface-actor-x11.h"
#include "meta-surface-actor-wayland.h"
#include "wayland/meta-wayland-surface.h"
@ -549,6 +550,16 @@ meta_window_actor_get_shape_bounds (MetaWindowActor *self,
MetaWindowActorPrivate *priv = self->priv;
cairo_region_get_extents (priv->shape_region, bounds);
if (META_IS_SURFACE_ACTOR_WAYLAND (priv->surface))
{
double scale = priv->surface ?
meta_surface_actor_wayland_get_scale (META_SURFACE_ACTOR_WAYLAND (priv->surface)) : 1.;
bounds->x *= scale;
bounds->y *= scale;
bounds->width *= scale;
bounds->height *= scale;
}
}
static void

View File

@ -121,7 +121,7 @@ meta_region_builder_finish (MetaRegionBuilder *builder)
return result;
}
/* MetaRegionIterator */
@ -171,7 +171,7 @@ meta_region_iterator_next (MetaRegionIterator *iter)
iter->line_end = TRUE;
}
}
static void
add_expanded_rect (MetaRegionBuilder *builder,
int x,

View File

@ -2,10 +2,10 @@
/* Mutter visual bell */
/*
/*
* Copyright (C) 2002 Sun Microsystems Inc.
* Copyright (C) 2005, 2006 Elijah Newren
*
*
* 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
@ -15,7 +15,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*/
@ -71,7 +71,7 @@
*/
#ifdef HAVE_XKB
static void
bell_flash_fullscreen (MetaDisplay *display,
bell_flash_fullscreen (MetaDisplay *display,
XkbAnyEvent *xkb_ev)
{
g_assert (xkb_ev->xkb_type == XkbBellNotify);
@ -96,7 +96,7 @@ bell_flash_fullscreen (MetaDisplay *display,
* Bug: This is the parallel to bell_flash_window_frame(), so it should
* really be called meta_bell_unflash_window_frame().
*/
static gboolean
static gboolean
bell_unflash_frame (gpointer data)
{
MetaFrame *frame = (MetaFrame *) data;
@ -143,12 +143,12 @@ bell_flash_window_frame (MetaWindow *window)
* flashes the screen.
*/
static void
bell_flash_frame (MetaDisplay *display,
bell_flash_frame (MetaDisplay *display,
XkbAnyEvent *xkb_ev)
{
XkbBellNotifyEvent *xkb_bell_event = (XkbBellNotifyEvent *) xkb_ev;
MetaWindow *window;
g_assert (xkb_ev->xkb_type == XkbBellNotify);
window = meta_display_lookup_x_window (display, xkb_bell_event->window);
if (!window && (display->focus_window))
@ -180,10 +180,10 @@ bell_flash_frame (MetaDisplay *display,
* Bug: This should be merged with meta_bell_notify().
*/
static void
bell_visual_notify (MetaDisplay *display,
bell_visual_notify (MetaDisplay *display,
XkbAnyEvent *xkb_ev)
{
switch (meta_prefs_get_visual_bell_type ())
switch (meta_prefs_get_visual_bell_type ())
{
case G_DESKTOP_VISUAL_BELL_FULLSCREEN_FLASH:
bell_flash_fullscreen (display, xkb_ev);
@ -195,7 +195,7 @@ bell_visual_notify (MetaDisplay *display,
}
void
meta_bell_notify (MetaDisplay *display,
meta_bell_notify (MetaDisplay *display,
XkbAnyEvent *xkb_ev)
{
/* flash something */
@ -271,19 +271,19 @@ meta_bell_init (MetaDisplay *display)
#ifdef HAVE_XKB
int xkb_base_error_type, xkb_opcode;
if (!XkbQueryExtension (display->xdisplay, &xkb_opcode,
&display->xkb_base_event_type,
&xkb_base_error_type,
if (!XkbQueryExtension (display->xdisplay, &xkb_opcode,
&display->xkb_base_event_type,
&xkb_base_error_type,
NULL, NULL))
{
display->xkb_base_event_type = -1;
g_message ("could not find XKB extension.");
return FALSE;
}
else
else
{
unsigned int mask = XkbBellNotifyMask;
gboolean visual_bell_auto_reset = FALSE;
gboolean visual_bell_auto_reset = FALSE;
/* TRUE if and when non-broken version is available */
XkbSelectEvents (display->xdisplay,
XkbUseCoreKbd,
@ -326,6 +326,6 @@ meta_bell_shutdown (MetaDisplay *display)
void
meta_bell_notify_frame_destroy (MetaFrame *frame)
{
if (frame->is_flashing)
if (frame->is_flashing)
g_source_remove_by_funcs_user_data (&g_timeout_funcs, frame);
}

View File

@ -1,8 +1,8 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
/*
* Copyright (C) 2002 Sun Microsystems Inc.
*
*
* 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
@ -12,7 +12,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*/
@ -28,7 +28,7 @@
/**
* meta_bell_notify:
* @display: The display the bell event came in on
* @xkb_ev: The bell event we just received
* @xkb_ev: The bell event we just received
*
* Gives the user some kind of visual bell; in fact, this is our response
* to any kind of bell request, but we set it up so that we only get

View File

@ -2,9 +2,9 @@
/* Simple box operations */
/*
/*
* Copyright (C) 2005, 2006 Elijah Newren
*
*
* 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
@ -14,7 +14,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*/
@ -43,7 +43,7 @@ typedef enum
* region_to_string: (RECT_LENGTH+strlen(separator_string)) *
* g_list_length (region)
* edge_to_string: EDGE_LENGTH
* edge_list_to_...: (EDGE_LENGTH+strlen(separator_string)) *
* edge_list_to_...: (EDGE_LENGTH+strlen(separator_string)) *
* g_list_length (edge_list)
*/
#define RECT_LENGTH 27
@ -181,7 +181,7 @@ void meta_rectangle_find_linepoint_closest_to_point (double x1, double y1,
/* Return whether an edge overlaps or is adjacent to the rectangle in the
* nonzero-width dimension of the edge.
*/
gboolean meta_rectangle_edge_aligns (const MetaRectangle *rect,
gboolean meta_rectangle_edge_aligns (const MetaRectangle *rect,
const MetaEdge *edge);
/* Compare two edges, so that sorting functions can put a list of edges in

View File

@ -6,14 +6,14 @@
* @Short_Description: Simple box operations
*/
/*
/*
* Copyright (C) 2005, 2006 Elijah Newren
* [meta_rectangle_intersect() is copyright the GTK+ Team according to Havoc,
* see gdkrectangle.c. As far as Havoc knows, he probably wrote
* meta_rectangle_equal(), and I'm guessing it's (C) Red Hat. So...]
* Copyright (C) 1995-2000 GTK+ Team
* Copyright (C) 2002 Red Hat, Inc.
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
@ -23,7 +23,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*/
@ -69,7 +69,7 @@ meta_rectangle_to_string (const MetaRectangle *rect,
* Should be more than enough space. Note that of this space, the
* trailing \0 will be overwritten for all but the last rectangle.
*/
g_snprintf (output, RECT_LENGTH, "%d,%d +%d,%d",
g_snprintf (output, RECT_LENGTH, "%d,%d +%d,%d",
rect->x, rect->y, rect->width, rect->height);
return output;
@ -96,7 +96,7 @@ meta_rectangle_region_to_string (GList *region,
while (tmp)
{
MetaRectangle *rect = tmp->data;
g_snprintf (rect_string, RECT_LENGTH, "[%d,%d +%d,%d]",
g_snprintf (rect_string, RECT_LENGTH, "[%d,%d +%d,%d]",
rect->x, rect->y, rect->width, rect->height);
cur = g_stpcpy (cur, rect_string);
tmp = tmp->next;
@ -118,7 +118,7 @@ meta_rectangle_edge_to_string (const MetaEdge *edge,
* Plus 2 for parenthesis, 4 for 2 more numbers, 2 more commas, and
* 2 more spaces, for a total of 10 more.
*/
g_snprintf (output, EDGE_LENGTH, "[%d,%d +%d,%d], %2d, %2d",
g_snprintf (output, EDGE_LENGTH, "[%d,%d +%d,%d], %2d, %2d",
edge->rect.x, edge->rect.y, edge->rect.width, edge->rect.height,
edge->side_type, edge->edge_type);
@ -150,7 +150,7 @@ meta_rectangle_edge_list_to_string (GList *edge_list,
{
MetaEdge *edge = tmp->data;
MetaRectangle *rect = &edge->rect;
g_snprintf (rect_string, EDGE_LENGTH, "([%d,%d +%d,%d], %2d, %2d)",
g_snprintf (rect_string, EDGE_LENGTH, "([%d,%d +%d,%d], %2d, %2d)",
rect->x, rect->y, rect->width, rect->height,
edge->side_type, edge->edge_type);
cur = g_stpcpy (cur, rect_string);
@ -210,7 +210,7 @@ meta_rectangle_intersect (const MetaRectangle *src1,
dest_y = MAX (src1->y, src2->y);
dest_w = MIN (src1->x + src1->width, src2->x + src2->width) - dest_x;
dest_h = MIN (src1->y + src1->height, src2->y + src2->height) - dest_y;
if (dest_w > 0 && dest_h > 0)
{
dest->x = dest_x;
@ -320,7 +320,7 @@ gboolean
meta_rectangle_contains_rect (const MetaRectangle *outer_rect,
const MetaRectangle *inner_rect)
{
return
return
inner_rect->x >= outer_rect->x &&
inner_rect->y >= outer_rect->y &&
inner_rect->x + inner_rect->width <= outer_rect->x + outer_rect->width &&
@ -339,7 +339,7 @@ meta_rectangle_resize_with_gravity (const MetaRectangle *old_rect,
* boxes.h has a good comment, but I'm not sure if the below info is also
* helpful on top of that (or whether it has superfluous info).
*/
/* These formulas may look overly simplistic at first but you can work
* everything out with a left_frame_with, right_frame_width,
* border_width, and old and new client area widths (instead of old total
@ -389,7 +389,7 @@ meta_rectangle_resize_with_gravity (const MetaRectangle *old_rect,
break;
}
rect->width = new_width;
/* Next, the y direction */
switch (gravity)
{
@ -629,7 +629,7 @@ meta_rectangle_get_minimal_spanning_set_for_region (
for (strut_iter = all_struts; strut_iter; strut_iter = strut_iter->next)
{
GList *rect_iter;
GList *rect_iter;
MetaRectangle *strut_rect = &((MetaStrut*)strut_iter->data)->rect;
tmp_list = ret;
@ -764,7 +764,7 @@ meta_rectangle_expand_to_avoiding_struts (MetaRectangle *rect,
*/
g_assert ((direction == META_DIRECTION_HORIZONTAL) ^
(direction == META_DIRECTION_VERTICAL ));
if (direction == META_DIRECTION_HORIZONTAL)
{
rect->x = expand_to->x;
@ -776,12 +776,12 @@ meta_rectangle_expand_to_avoiding_struts (MetaRectangle *rect,
rect->height = expand_to->height;
}
/* Run over all struts */
for (strut_iter = all_struts; strut_iter; strut_iter = strut_iter->next)
{
MetaStrut *strut = (MetaStrut*) strut_iter->data;
/* Skip struts that don't overlap */
if (!meta_rectangle_overlap (&strut->rect, rect))
continue;
@ -822,7 +822,7 @@ meta_rectangle_expand_to_avoiding_struts (MetaRectangle *rect,
void
meta_rectangle_free_list_and_elements (GList *filled_list)
{
g_list_foreach (filled_list,
g_list_foreach (filled_list,
(void (*)(gpointer,gpointer))&g_free, /* ew, for ugly */
NULL);
g_list_free (filled_list);
@ -900,20 +900,20 @@ meta_rectangle_clamp_to_fit_into_region (const GList *spanning_rects,
{
MetaRectangle *compare_rect = temp->data;
int maximal_overlap_amount_for_compare;
/* If x is fixed and the entire width of rect doesn't fit in compare,
* skip this rectangle.
*/
if ((fixed_directions & FIXED_DIRECTION_X) &&
(compare_rect->x > rect->x ||
(compare_rect->x > rect->x ||
compare_rect->x + compare_rect->width < rect->x + rect->width))
continue;
/* If y is fixed and the entire height of rect doesn't fit in compare,
* skip this rectangle.
*/
if ((fixed_directions & FIXED_DIRECTION_Y) &&
(compare_rect->y > rect->y ||
(compare_rect->y > rect->y ||
compare_rect->y + compare_rect->height < rect->y + rect->height))
continue;
@ -970,20 +970,20 @@ meta_rectangle_clip_to_region (const GList *spanning_rects,
MetaRectangle *compare_rect = temp->data;
MetaRectangle overlap;
int maximal_overlap_amount_for_compare;
/* If x is fixed and the entire width of rect doesn't fit in compare,
* skip the rectangle.
*/
if ((fixed_directions & FIXED_DIRECTION_X) &&
(compare_rect->x > rect->x ||
(compare_rect->x > rect->x ||
compare_rect->x + compare_rect->width < rect->x + rect->width))
continue;
/* If y is fixed and the entire height of rect doesn't fit in compare,
* skip the rectangle.
*/
if ((fixed_directions & FIXED_DIRECTION_Y) &&
(compare_rect->y > rect->y ||
(compare_rect->y > rect->y ||
compare_rect->y + compare_rect->height < rect->y + rect->height))
continue;
@ -1043,26 +1043,26 @@ meta_rectangle_shove_into_region (const GList *spanning_rects,
/* First, find best rectangle from spanning_rects to which we will shove
* rect into.
*/
for (temp = spanning_rects; temp; temp = temp->next)
{
MetaRectangle *compare_rect = temp->data;
int maximal_overlap_amount_for_compare;
int dist_to_compare;
/* If x is fixed and the entire width of rect doesn't fit in compare,
* skip this rectangle.
*/
if ((fixed_directions & FIXED_DIRECTION_X) &&
(compare_rect->x > rect->x ||
(compare_rect->x > rect->x ||
compare_rect->x + compare_rect->width < rect->x + rect->width))
continue;
/* If y is fixed and the entire height of rect doesn't fit in compare,
* skip this rectangle.
*/
if ((fixed_directions & FIXED_DIRECTION_Y) &&
(compare_rect->y > rect->y ||
(compare_rect->y > rect->y ||
compare_rect->y + compare_rect->height < rect->y + rect->height))
continue;
@ -1218,7 +1218,7 @@ meta_rectangle_edge_aligns (const MetaRectangle *rect, const MetaEdge *edge)
}
static GList*
get_rect_minus_overlap (const GList *rect_in_list,
get_rect_minus_overlap (const GList *rect_in_list,
MetaRectangle *overlap)
{
MetaRectangle *temp;
@ -1263,7 +1263,7 @@ get_rect_minus_overlap (const GList *rect_in_list,
}
static GList*
replace_rect_with_list (GList *old_element,
replace_rect_with_list (GList *old_element,
GList *new_list)
{
GList *ret;
@ -1475,7 +1475,7 @@ rectangle_and_edge_intersection (const MetaRectangle *rect,
overlap->edge_type = -1;
overlap->side_type = -1;
/* Figure out what the intersection is */
/* Figure out what the intersection is */
result->x = MAX (rect->x, rect2->x);
result->y = MAX (rect->y, rect2->y);
result->width = MIN (BOX_RIGHT (*rect), BOX_RIGHT (*rect2)) - result->x;
@ -1546,7 +1546,7 @@ rectangle_and_edge_intersection (const MetaRectangle *rect,
* TOP<->BOTTOM).
*/
static GList*
add_edges (GList *cur_edges,
add_edges (GList *cur_edges,
const MetaRectangle *rect,
gboolean rect_is_internal)
{
@ -1560,23 +1560,23 @@ add_edges (GList *cur_edges,
switch (i)
{
case 0:
temp_edge->side_type =
temp_edge->side_type =
rect_is_internal ? META_SIDE_LEFT : META_SIDE_RIGHT;
temp_edge->rect.width = 0;
break;
case 1:
temp_edge->side_type =
temp_edge->side_type =
rect_is_internal ? META_SIDE_RIGHT : META_SIDE_LEFT;
temp_edge->rect.x += temp_edge->rect.width;
temp_edge->rect.width = 0;
break;
case 2:
temp_edge->side_type =
temp_edge->side_type =
rect_is_internal ? META_SIDE_TOP : META_SIDE_BOTTOM;
temp_edge->rect.height = 0;
break;
case 3:
temp_edge->side_type =
temp_edge->side_type =
rect_is_internal ? META_SIDE_BOTTOM : META_SIDE_TOP;
temp_edge->rect.y += temp_edge->rect.height;
temp_edge->rect.height = 0;
@ -1593,8 +1593,8 @@ add_edges (GList *cur_edges,
* edges to cur_list. Return cur_list when finished.
*/
static GList*
split_edge (GList *cur_list,
const MetaEdge *old_edge,
split_edge (GList *cur_list,
const MetaEdge *old_edge,
const MetaEdge *remove)
{
MetaEdge *temp_edge;
@ -1653,7 +1653,7 @@ split_edge (GList *cur_list,
* if and how rect and edge intersect.
*/
static void
fix_up_edges (MetaRectangle *rect, MetaEdge *edge,
fix_up_edges (MetaRectangle *rect, MetaEdge *edge,
GList **strut_edges, GList **edge_splits,
gboolean *edge_needs_removal)
{
@ -1777,7 +1777,7 @@ meta_rectangle_find_onscreen_edges (const MetaRectangle *basic_rect,
{
GList *ret;
GList *fixed_strut_rects;
GList *edge_iter;
GList *edge_iter;
const GList *strut_rect_iter;
/* The algorithm is basically as follows:
@ -1817,7 +1817,7 @@ meta_rectangle_find_onscreen_edges (const MetaRectangle *basic_rect,
GList *splits_of_cur_edge = NULL;
gboolean edge_needs_removal = FALSE;
fix_up_edges (strut_rect, cur_edge,
fix_up_edges (strut_rect, cur_edge,
&new_strut_edges, &splits_of_cur_edge,
&edge_needs_removal);
@ -1981,7 +1981,7 @@ meta_rectangle_find_nonintersected_monitor_edges (
for (; all_struts; all_struts = all_struts->next)
temp_rects = g_slist_prepend (temp_rects,
&((MetaStrut*)all_struts->data)->rect);
ret = meta_rectangle_remove_intersections_with_boxes_from_edges (ret,
ret = meta_rectangle_remove_intersections_with_boxes_from_edges (ret,
temp_rects);
g_slist_free (temp_rects);

View File

@ -42,7 +42,7 @@
// "constrain_whatever".
// 3) Add your function to the all_constraints and all_constraint_names
// arrays (the latter of which is for debugging purposes)
//
//
// An example constraint function, constrain_whatever:
//
// /* constrain_whatever does the following:
@ -246,7 +246,7 @@ do_all_constraints (MetaWindow *window,
/* Log how the constraint modified the position */
meta_topic (META_DEBUG_GEOMETRY,
"info->current is %d,%d +%d,%d after %s\n",
info->current.x, info->current.y,
info->current.x, info->current.y,
info->current.width, info->current.height,
constraint->name);
}
@ -275,11 +275,6 @@ meta_window_constrain (MetaWindow *window,
ConstraintPriority priority = PRIORITY_MINIMUM;
gboolean satisfied = FALSE;
/* WARNING: orig and new specify positions and sizes of the inner window,
* not the outer. This is a common gotcha since half the constraints
* deal with inner window position/size and half deal with outer. See
* doc/how-constraints-works.txt for more information.
*/
meta_topic (META_DEBUG_GEOMETRY,
"Constraining %s in move from %d,%d %dx%d to %d,%d %dx%d\n",
window->desc,
@ -287,7 +282,7 @@ meta_window_constrain (MetaWindow *window,
new->x, new->y, new->width, new->height);
setup_constraint_info (&info,
window,
window,
flags,
resize_gravity,
orig,
@ -300,7 +295,7 @@ meta_window_constrain (MetaWindow *window,
/* Individually enforce all the high-enough priority constraints */
do_all_constraints (window, &info, priority, !check_only);
/* Check if all high-enough priority constraints are simultaneously
/* Check if all high-enough priority constraints are simultaneously
* satisfied
*/
satisfied = do_all_constraints (window, &info, priority, check_only);
@ -403,10 +398,10 @@ setup_constraint_info (ConstraintInfo *info,
}
cur_workspace = window->screen->active_workspace;
info->usable_screen_region =
info->usable_screen_region =
meta_workspace_get_onscreen_region (cur_workspace);
info->usable_monitor_region =
meta_workspace_get_onmonitor_region (cur_workspace,
info->usable_monitor_region =
meta_workspace_get_onmonitor_region (cur_workspace,
monitor_info->number);
/* Workaround braindead legacy apps that don't know how to
@ -446,7 +441,7 @@ setup_constraint_info (ConstraintInfo *info,
" work_area_monitor: %d,%d +%d,%d\n"
" entire_monitor : %d,%d +%d,%d\n",
info->orig.x, info->orig.y, info->orig.width, info->orig.height,
info->current.x, info->current.y,
info->current.x, info->current.y,
info->current.width, info->current.height,
(info->action_type == ACTION_MOVE) ? "Move" :
(info->action_type == ACTION_RESIZE) ? "Resize" :
@ -459,7 +454,7 @@ setup_constraint_info (ConstraintInfo *info,
(info->fixed_directions == FIXED_DIRECTION_Y) ? "Y fixed" :
"Freakin' Invalid Stupid",
info->work_area_monitor.x, info->work_area_monitor.y,
info->work_area_monitor.width,
info->work_area_monitor.width,
info->work_area_monitor.height,
info->entire_monitor.x, info->entire_monitor.y,
info->entire_monitor.width, info->entire_monitor.height);
@ -507,12 +502,10 @@ place_window_if_needed(MetaWindow *window,
monitor_info->number,
&info->work_area_monitor);
cur_workspace = window->screen->active_workspace;
info->usable_monitor_region =
meta_workspace_get_onmonitor_region (cur_workspace,
info->usable_monitor_region =
meta_workspace_get_onmonitor_region (cur_workspace,
monitor_info->number);
meta_window_frame_rect_to_client_rect (window, &placed_rect, &placed_rect);
info->current.x = placed_rect.x;
info->current.y = placed_rect.y;
@ -544,14 +537,14 @@ place_window_if_needed(MetaWindow *window,
.083 * info->work_area_monitor.height;
}
/* idle_move_resize() uses the user_rect, so make sure it uses the
* placed coordinates (bug #556696).
/* idle_move_resize() uses the unconstrained_rect, so make sure it
* uses the placed coordinates (bug #556696).
*/
window->user_rect = info->current;
window->unconstrained_rect = info->current;
if (window->maximize_horizontally_after_placement ||
window->maximize_vertically_after_placement)
meta_window_maximize_internal (window,
meta_window_maximize_internal (window,
(window->maximize_horizontally_after_placement ?
META_MAXIMIZE_HORIZONTAL : 0 ) |
(window->maximize_vertically_after_placement ?
@ -636,7 +629,7 @@ update_onscreen_requirements (MetaWindow *window,
if (old ^ window->require_on_single_monitor)
meta_topic (META_DEBUG_GEOMETRY,
"require_on_single_monitor for %s toggled to %s\n",
window->desc,
window->desc,
window->require_on_single_monitor ? "TRUE" : "FALSE");
/* Update whether we want future constraint runs to require the
@ -644,13 +637,10 @@ update_onscreen_requirements (MetaWindow *window,
*/
if (window->frame && window->decorated)
{
MetaFrameBorders borders;
MetaRectangle titlebar_rect;
meta_frame_calc_borders (window->frame, &borders);
meta_window_get_titlebar_rect (window, &titlebar_rect);
titlebar_rect = info->current;
titlebar_rect.height = borders.visible.top;
old = window->require_titlebar_visible;
window->require_titlebar_visible =
meta_rectangle_overlaps_with_region (info->usable_screen_region,
@ -910,38 +900,41 @@ constrain_size_increments (MetaWindow *window,
int new_width, new_height;
gboolean constraint_already_satisfied;
MetaRectangle *start_rect;
MetaRectangle client_rect;
if (priority > PRIORITY_SIZE_HINTS_INCREMENTS)
return TRUE;
/* Determine whether constraint applies; exit if it doesn't */
if (META_WINDOW_MAXIMIZED (window) || window->fullscreen ||
if (META_WINDOW_MAXIMIZED (window) || window->fullscreen ||
META_WINDOW_TILED_SIDE_BY_SIDE (window) ||
info->action_type == ACTION_MOVE)
return TRUE;
meta_window_frame_rect_to_client_rect (window, &info->current, &client_rect);
/* Determine whether constraint is already satisfied; exit if it is */
bh = window->size_hints.base_height;
hi = window->size_hints.height_inc;
bw = window->size_hints.base_width;
wi = window->size_hints.width_inc;
extra_height = (info->current.height - bh) % hi;
extra_width = (info->current.width - bw) % wi;
extra_height = (client_rect.height - bh) % hi;
extra_width = (client_rect.width - bw) % wi;
/* ignore size increments for maximized windows */
if (window->maximized_horizontally)
extra_width *= 0;
if (window->maximized_vertically)
extra_height *= 0;
/* constraint is satisfied iff there is no extra height or width */
constraint_already_satisfied =
constraint_already_satisfied =
(extra_height == 0 && extra_width == 0);
if (check_only || constraint_already_satisfied)
return constraint_already_satisfied;
/*** Enforce constraint ***/
new_width = info->current.width - extra_width;
new_height = info->current.height - extra_height;
new_width = client_rect.width - extra_width;
new_height = client_rect.height - extra_height;
/* Adjusting down instead of up (as done in the above two lines) may
* violate minimum size constraints; fix the adjustment if this
@ -952,6 +945,14 @@ constrain_size_increments (MetaWindow *window,
if (new_height < window->size_hints.min_height)
new_height += ((window->size_hints.min_height - new_height)/hi + 1)*hi;
{
client_rect.width = new_width;
client_rect.height = new_height;
meta_window_client_rect_to_frame_rect (window, &client_rect, &client_rect);
new_width = client_rect.width;
new_height = client_rect.height;
}
/* Figure out what original rect to pass to meta_rectangle_resize_with_gravity
* See bug 448183
*/
@ -959,10 +960,10 @@ constrain_size_increments (MetaWindow *window,
start_rect = &info->current;
else
start_rect = &info->orig;
/* Resize to the new size */
meta_rectangle_resize_with_gravity (start_rect,
&info->current,
&info->current,
info->resize_gravity,
new_width,
new_height);
@ -1007,7 +1008,7 @@ constrain_size_limits (MetaWindow *window,
/*** Enforce constraint ***/
new_width = CLAMP (info->current.width, min_size.width, max_size.width);
new_height = CLAMP (info->current.height, min_size.height, max_size.height);
/* Figure out what original rect to pass to meta_rectangle_resize_with_gravity
* See bug 448183
*/
@ -1015,9 +1016,9 @@ constrain_size_limits (MetaWindow *window,
start_rect = &info->current;
else
start_rect = &info->orig;
meta_rectangle_resize_with_gravity (start_rect,
&info->current,
&info->current,
info->resize_gravity,
new_width,
new_height);
@ -1047,7 +1048,7 @@ constrain_aspect_ratio (MetaWindow *window,
(double)window->size_hints.max_aspect.y;
constraints_are_inconsistent = minr > maxr;
if (constraints_are_inconsistent ||
META_WINDOW_MAXIMIZED (window) || window->fullscreen ||
META_WINDOW_MAXIMIZED (window) || window->fullscreen ||
META_WINDOW_TILED_SIDE_BY_SIDE (window) ||
info->action_type == ACTION_MOVE)
return TRUE;
@ -1087,7 +1088,7 @@ constrain_aspect_ratio (MetaWindow *window,
fudge = 1;
break;
}
constraint_already_satisfied =
constraint_already_satisfied =
info->current.width - (info->current.height * minr ) > -minr*fudge &&
info->current.width - (info->current.height * maxr ) < maxr*fudge;
if (check_only || constraint_already_satisfied)
@ -1151,7 +1152,7 @@ constrain_aspect_ratio (MetaWindow *window,
start_rect = &info->orig;
meta_rectangle_resize_with_gravity (start_rect,
&info->current,
&info->current,
info->resize_gravity,
new_width,
new_height);
@ -1199,7 +1200,7 @@ do_screen_and_monitor_relative_constraints (
exit_early = TRUE;
/* Determine whether constraint is already satisfied; exit if it is */
constraint_satisfied =
constraint_satisfied =
meta_rectangle_contained_in_region (region_spanning_rectangles,
&info->current);
if (exit_early || constraint_satisfied || check_only)
@ -1238,7 +1239,7 @@ constrain_to_single_monitor (MetaWindow *window,
return TRUE;
/* Exit early if we know the constraint won't apply--note that this constraint
* is only meant for normal windows (e.g. we don't want docks to be shoved
* is only meant for normal windows (e.g. we don't want docks to be shoved
* "onscreen" by their own strut) and we can't apply it to frameless windows
* or else users will be unable to move windows such as XMMS across monitors.
*/
@ -1251,7 +1252,7 @@ constrain_to_single_monitor (MetaWindow *window,
return TRUE;
/* Have a helper function handle the constraint for us */
return do_screen_and_monitor_relative_constraints (window,
return do_screen_and_monitor_relative_constraints (window,
info->usable_monitor_region,
info,
check_only);
@ -1267,18 +1268,18 @@ constrain_fully_onscreen (MetaWindow *window,
return TRUE;
/* Exit early if we know the constraint won't apply--note that this constraint
* is only meant for normal windows (e.g. we don't want docks to be shoved
* is only meant for normal windows (e.g. we don't want docks to be shoved
* "onscreen" by their own strut).
*/
if (window->type == META_WINDOW_DESKTOP ||
window->type == META_WINDOW_DOCK ||
window->fullscreen ||
!window->require_fully_onscreen ||
!window->require_fully_onscreen ||
info->is_user_action)
return TRUE;
/* Have a helper function handle the constraint for us */
return do_screen_and_monitor_relative_constraints (window,
return do_screen_and_monitor_relative_constraints (window,
info->usable_screen_region,
info,
check_only);
@ -1306,7 +1307,7 @@ constrain_titlebar_visible (MetaWindow *window,
info->is_user_action && !window->display->grab_frame_action;
/* Exit early if we know the constraint won't apply--note that this constraint
* is only meant for normal windows (e.g. we don't want docks to be shoved
* is only meant for normal windows (e.g. we don't want docks to be shoved
* "onscreen" by their own strut).
*/
if (window->type == META_WINDOW_DESKTOP ||
@ -1350,13 +1351,13 @@ constrain_titlebar_visible (MetaWindow *window,
*/
meta_rectangle_expand_region_conditionally (info->usable_screen_region,
horiz_amount_offscreen,
horiz_amount_offscreen,
horiz_amount_offscreen,
0, /* Don't let titlebar off */
bottom_amount,
horiz_amount_onscreen,
vert_amount_onscreen);
retval =
do_screen_and_monitor_relative_constraints (window,
do_screen_and_monitor_relative_constraints (window,
info->usable_screen_region,
info,
check_only);
@ -1386,7 +1387,7 @@ constrain_partially_onscreen (MetaWindow *window,
return TRUE;
/* Exit early if we know the constraint won't apply--note that this constraint
* is only meant for normal windows (e.g. we don't want docks to be shoved
* is only meant for normal windows (e.g. we don't want docks to be shoved
* "onscreen" by their own strut).
*/
if (window->type == META_WINDOW_DESKTOP ||
@ -1428,13 +1429,13 @@ constrain_partially_onscreen (MetaWindow *window,
*/
meta_rectangle_expand_region_conditionally (info->usable_screen_region,
horiz_amount_offscreen,
horiz_amount_offscreen,
horiz_amount_offscreen,
top_amount,
bottom_amount,
horiz_amount_onscreen,
vert_amount_onscreen);
retval =
do_screen_and_monitor_relative_constraints (window,
do_screen_and_monitor_relative_constraints (window,
info->usable_screen_region,
info,
check_only);

View File

@ -2,10 +2,10 @@
/* Mutter size/position constraints */
/*
/*
* Copyright (C) 2002 Red Hat, Inc.
* Copyright (C) 2005 Elijah Newren
*
*
* 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
@ -15,7 +15,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*/

View File

@ -2,11 +2,11 @@
/* Mutter interface used by GTK+ UI to talk to core */
/*
/*
* Copyright (C) 2001 Havoc Pennington
* Copyright (C) 2003 Rob Adams
* Copyright (C) 2004-2006 Elijah Newren
*
*
* 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
@ -16,7 +16,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*/
@ -46,7 +46,7 @@ get_window (Display *xdisplay,
{
MetaDisplay *display;
MetaWindow *window;
display = meta_display_for_x_display (xdisplay);
window = meta_display_lookup_x_window (display, frame_xwindow);
@ -86,78 +86,56 @@ meta_core_get (Display *xdisplay,
*/
if (request != META_CORE_WINDOW_HAS_FRAME &&
(window == NULL || window->frame == NULL)) {
meta_bug ("No such frame window 0x%lx!\n", xwindow);
goto out;
}
while (request != META_CORE_GET_END) {
gpointer answer = va_arg (args, gpointer);
switch (request) {
case META_CORE_WINDOW_HAS_FRAME:
*((gboolean*)answer) = window != NULL && window->frame != NULL;
if (!*((gboolean*)answer)) goto out; /* see above */
break;
case META_CORE_GET_CLIENT_WIDTH:
*((gint*)answer) = window->rect.width;
break;
case META_CORE_GET_CLIENT_HEIGHT:
*((gint*)answer) = window->rect.height;
break;
case META_CORE_GET_CLIENT_XWINDOW:
*((Window*)answer) = window->xwindow;
break;
case META_CORE_GET_FRAME_FLAGS:
*((MetaFrameFlags*)answer) = meta_frame_get_flags (window->frame);
break;
case META_CORE_GET_FRAME_TYPE:
*((MetaFrameType*)answer) = meta_window_get_frame_type (window);
break;
case META_CORE_GET_MINI_ICON:
*((GdkPixbuf**)answer) = window->mini_icon;
break;
case META_CORE_GET_ICON:
*((GdkPixbuf**)answer) = window->icon;
break;
case META_CORE_GET_X:
meta_window_get_position (window, (int*)answer, NULL);
break;
case META_CORE_GET_Y:
meta_window_get_position (window, NULL, (int*)answer);
break;
case META_CORE_GET_FRAME_WORKSPACE:
*((gint*)answer) = meta_window_get_net_wm_desktop (window);
break;
case META_CORE_GET_FRAME_X:
*((gint*)answer) = window->frame->rect.x;
break;
case META_CORE_GET_FRAME_Y:
*((gint*)answer) = window->frame->rect.y;
break;
case META_CORE_GET_FRAME_WIDTH:
*((gint*)answer) = window->frame->rect.width;
break;
case META_CORE_GET_FRAME_HEIGHT:
*((gint*)answer) = window->frame->rect.height;
break;
case META_CORE_GET_THEME_VARIANT:
*((char**)answer) = window->gtk_theme_variant;
break;
case META_CORE_GET_SCREEN_WIDTH:
*((gint*)answer) = window->screen->rect.width;
break;
case META_CORE_GET_SCREEN_HEIGHT:
*((gint*)answer) = window->screen->rect.height;
break;
default:
meta_warning("Unknown window information request: %d\n", request);
(window == NULL || window->frame == NULL))
{
meta_bug ("No such frame window 0x%lx!\n", xwindow);
goto out;
}
request = va_arg (args, MetaCoreGetType);
}
while (request != META_CORE_GET_END)
{
gpointer answer = va_arg (args, gpointer);
switch (request)
{
case META_CORE_WINDOW_HAS_FRAME:
*((gboolean*)answer) = window != NULL && window->frame != NULL;
if (!*((gboolean*)answer)) goto out; /* see above */
break;
case META_CORE_GET_CLIENT_WIDTH:
*((gint*)answer) = window->rect.width;
break;
case META_CORE_GET_CLIENT_HEIGHT:
*((gint*)answer) = window->rect.height;
break;
case META_CORE_GET_FRAME_FLAGS:
*((MetaFrameFlags*)answer) = meta_frame_get_flags (window->frame);
break;
case META_CORE_GET_FRAME_TYPE:
*((MetaFrameType*)answer) = meta_window_get_frame_type (window);
break;
case META_CORE_GET_MINI_ICON:
*((GdkPixbuf**)answer) = window->mini_icon;
break;
case META_CORE_GET_ICON:
*((GdkPixbuf**)answer) = window->icon;
break;
case META_CORE_GET_FRAME_WIDTH:
*((gint*)answer) = window->frame->rect.width;
break;
case META_CORE_GET_FRAME_HEIGHT:
*((gint*)answer) = window->frame->rect.height;
break;
case META_CORE_GET_THEME_VARIANT:
*((char**)answer) = window->gtk_theme_variant;
break;
default:
meta_warning("Unknown window information request: %d\n", request);
}
request = va_arg (args, MetaCoreGetType);
}
out:
va_end (args);
@ -173,38 +151,6 @@ meta_core_queue_frame_resize (Display *xdisplay,
meta_window_frame_size_changed (window);
}
void
meta_core_user_move (Display *xdisplay,
Window frame_xwindow,
int x,
int y)
{
MetaWindow *window = get_window (xdisplay, frame_xwindow);
meta_window_move (window, TRUE, x, y);
}
void
meta_core_user_resize (Display *xdisplay,
Window frame_xwindow,
int gravity,
int width,
int height)
{
MetaWindow *window = get_window (xdisplay, frame_xwindow);
meta_window_resize_with_gravity (window, TRUE, width, height, gravity);
}
void
meta_core_user_raise (Display *xdisplay,
Window frame_xwindow)
{
MetaWindow *window = get_window (xdisplay, frame_xwindow);
meta_window_raise (window);
}
static gboolean
lower_window_and_transients (MetaWindow *window,
gpointer data)
@ -221,21 +167,21 @@ lower_window_and_transients (MetaWindow *window,
* (Borrowed from window.c.)
*/
if (window->screen->active_workspace &&
meta_window_located_on_workspace (window,
meta_window_located_on_workspace (window,
window->screen->active_workspace))
{
GList* link;
link = g_list_find (window->screen->active_workspace->mru_list,
link = g_list_find (window->screen->active_workspace->mru_list,
window);
g_assert (link);
window->screen->active_workspace->mru_list =
window->screen->active_workspace->mru_list =
g_list_remove_link (window->screen->active_workspace->mru_list,
link);
g_list_free (link);
window->screen->active_workspace->mru_list =
g_list_append (window->screen->active_workspace->mru_list,
window->screen->active_workspace->mru_list =
g_list_append (window->screen->active_workspace->mru_list,
window);
}
}
@ -267,7 +213,7 @@ meta_core_user_focus (Display *xdisplay,
guint32 timestamp)
{
MetaWindow *window = get_window (xdisplay, frame_xwindow);
meta_window_focus (window, timestamp);
}
@ -355,7 +301,7 @@ meta_core_delete (Display *xdisplay,
guint32 timestamp)
{
MetaWindow *window = get_window (xdisplay, frame_xwindow);
meta_window_delete (window, timestamp);
}
@ -375,7 +321,7 @@ meta_core_shade (Display *xdisplay,
guint32 timestamp)
{
MetaWindow *window = get_window (xdisplay, frame_xwindow);
meta_window_shade (window, timestamp);
}
@ -428,134 +374,20 @@ meta_core_change_workspace (Display *xdisplay,
}
void
meta_core_show_window_menu (Display *xdisplay,
Window frame_xwindow,
int root_x,
int root_y,
int button,
guint32 timestamp)
meta_core_show_window_menu (Display *xdisplay,
Window frame_xwindow,
MetaWindowMenuType menu,
int root_x,
int root_y,
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 (window, root_x, root_y, button, timestamp);
}
void
meta_core_get_menu_accelerator (MetaMenuOp menu_op,
int workspace,
unsigned int *keysym,
MetaVirtualModifier *modifiers)
{
const char *name;
name = NULL;
switch (menu_op)
{
case META_MENU_OP_NONE:
/* No keybinding for this one */
break;
case META_MENU_OP_DELETE:
name = "close";
break;
case META_MENU_OP_MINIMIZE:
name = "minimize";
break;
case META_MENU_OP_UNMAXIMIZE:
name = "unmaximize";
break;
case META_MENU_OP_MAXIMIZE:
name = "maximize";
break;
case META_MENU_OP_UNSHADE:
case META_MENU_OP_SHADE:
name = "toggle_shaded";
break;
case META_MENU_OP_UNSTICK:
case META_MENU_OP_STICK:
name = "toggle-on-all-workspaces";
break;
case META_MENU_OP_ABOVE:
case META_MENU_OP_UNABOVE:
name = "toggle-above";
break;
case META_MENU_OP_WORKSPACES:
switch (workspace)
{
case 1:
name = "move-to-workspace-1";
break;
case 2:
name = "move-to-workspace-2";
break;
case 3:
name = "move-to-workspace-3";
break;
case 4:
name = "move-to-workspace-4";
break;
case 5:
name = "move-to-workspace-5";
break;
case 6:
name = "move-to-workspace-6";
break;
case 7:
name = "move-to-workspace-7";
break;
case 8:
name = "move-to-workspace-8";
break;
case 9:
name = "move-to-workspace-9";
break;
case 10:
name = "move-to-workspace-10";
break;
case 11:
name = "move-to-workspace-11";
break;
case 12:
name = "move-to-workspace-12";
break;
}
break;
case META_MENU_OP_MOVE:
name = "begin-move";
break;
case META_MENU_OP_RESIZE:
name = "begin-resize";
break;
case META_MENU_OP_MOVE_LEFT:
name = "move-to-workspace-left";
break;
case META_MENU_OP_MOVE_RIGHT:
name = "move-to-workspace-right";
break;
case META_MENU_OP_MOVE_UP:
name = "move-to-workspace-up";
break;
case META_MENU_OP_MOVE_DOWN:
name = "move-to-workspace-down";
break;
case META_MENU_OP_RECOVER:
/* No keybinding for this one */
break;
}
if (name)
{
meta_prefs_get_window_binding (name, keysym, modifiers);
}
else
{
*keysym = 0;
*modifiers = 0;
}
meta_window_show_menu (window, menu, root_x, root_y);
}
const char*
@ -586,12 +418,12 @@ meta_core_begin_grab_op (Display *xdisplay,
MetaWindow *window = get_window (xdisplay, frame_xwindow);
MetaDisplay *display;
MetaScreen *screen;
display = meta_display_for_x_display (xdisplay);
screen = display->screen;
g_assert (screen != NULL);
return meta_display_begin_grab_op (display, screen, window,
op, pointer_already_grabbed,
frame_action,
@ -604,7 +436,7 @@ meta_core_end_grab_op (Display *xdisplay,
guint32 timestamp)
{
MetaDisplay *display;
display = meta_display_for_x_display (xdisplay);
meta_display_end_grab_op (display, timestamp);
@ -614,7 +446,7 @@ MetaGrabOp
meta_core_get_grab_op (Display *xdisplay)
{
MetaDisplay *display;
display = meta_display_for_x_display (xdisplay);
return display->grab_op;
@ -625,7 +457,7 @@ meta_core_grab_buttons (Display *xdisplay,
Window frame_xwindow)
{
MetaDisplay *display;
display = meta_display_for_x_display (xdisplay);
meta_verbose ("Grabbing buttons on frame 0x%lx\n", frame_xwindow);

View File

@ -2,10 +2,10 @@
/* Mutter interface used by GTK+ UI to talk to core */
/*
/*
* Copyright (C) 2001 Havoc Pennington
* Copyright (C) 2005 Elijah Newren
*
*
* 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
@ -15,7 +15,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*/
@ -33,21 +33,13 @@ typedef enum
META_CORE_WINDOW_HAS_FRAME,
META_CORE_GET_CLIENT_WIDTH,
META_CORE_GET_CLIENT_HEIGHT,
META_CORE_GET_CLIENT_XWINDOW,
META_CORE_GET_FRAME_FLAGS,
META_CORE_GET_FRAME_TYPE,
META_CORE_GET_MINI_ICON,
META_CORE_GET_ICON,
META_CORE_GET_X,
META_CORE_GET_Y,
META_CORE_GET_FRAME_WORKSPACE,
META_CORE_GET_FRAME_X,
META_CORE_GET_FRAME_Y,
META_CORE_GET_FRAME_WIDTH,
META_CORE_GET_FRAME_HEIGHT,
META_CORE_GET_THEME_VARIANT,
META_CORE_GET_SCREEN_WIDTH,
META_CORE_GET_SCREEN_HEIGHT,
} MetaCoreGetType;
/* General information function about the given window. Pass in a sequence of
@ -56,8 +48,8 @@ typedef enum
* For example:
*
* meta_core_get (my_display, my_window,
* META_CORE_GET_X, &x,
* META_CORE_GET_Y, &y,
* META_CORE_GET_FRAME_WIDTH, &width,
* META_CORE_GET_FRAME_HEIGHT, &height,
* META_CORE_GET_END);
*
* If the window doesn't have a frame, this will raise a meta_bug. To suppress
@ -93,19 +85,6 @@ void meta_core_get (Display *xdisplay,
void meta_core_queue_frame_resize (Display *xdisplay,
Window frame_xwindow);
/* Move as a result of user operation */
void meta_core_user_move (Display *xdisplay,
Window frame_xwindow,
int x,
int y);
void meta_core_user_resize (Display *xdisplay,
Window frame_xwindow,
int gravity,
int width,
int height);
void meta_core_user_raise (Display *xdisplay,
Window frame_xwindow);
void meta_core_user_lower_and_unfocus (Display *xdisplay,
Window frame_xwindow,
guint32 timestamp);
@ -153,17 +132,12 @@ const char* meta_core_get_workspace_name_with_index (Display *xdisplay,
Window xroot,
int index);
void meta_core_show_window_menu (Display *xdisplay,
Window frame_xwindow,
int root_x,
int root_y,
int button,
guint32 timestamp);
void meta_core_get_menu_accelerator (MetaMenuOp menu_op,
int workspace,
unsigned int *keysym,
MetaVirtualModifier *modifiers);
void meta_core_show_window_menu (Display *xdisplay,
Window frame_xwindow,
MetaWindowMenuType menu,
int root_x,
int root_y,
guint32 timestamp);
gboolean meta_core_begin_grab_op (Display *xdisplay,
Window frame_xwindow,

View File

@ -2,10 +2,10 @@
/* Mutter window deletion */
/*
/*
* Copyright (C) 2001, 2002 Havoc Pennington
* Copyright (C) 2004 Elijah Newren
*
*
* 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
@ -15,7 +15,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*/
@ -39,47 +39,70 @@
#include "wayland/meta-wayland-surface.h"
static void meta_window_present_delete_dialog (MetaWindow *window,
guint32 timestamp);
static void
delete_ping_reply_func (MetaWindow *window,
guint32 timestamp,
void *user_data)
{
meta_topic (META_DEBUG_PING, "Got reply to delete ping for %s\n", window->desc);
/* we do nothing */
}
static void
dialog_exited (GPid pid, int status, gpointer user_data)
{
MetaWindow *ours = (MetaWindow*) user_data;
MetaWindow *window = user_data;
ours->dialog_pid = -1;
window->dialog_pid = -1;
/* exit status of 1 means the user pressed "Force Quit" */
if (WIFEXITED (status) && WEXITSTATUS (status) == 1)
meta_window_kill (ours);
meta_window_kill (window);
}
static void
delete_ping_timeout_func (MetaWindow *window,
guint32 timestamp,
void *user_data)
present_existing_delete_dialog (MetaWindow *window,
guint32 timestamp)
{
meta_topic (META_DEBUG_PING,
"Presenting existing ping dialog for %s\n",
window->desc);
if (window->dialog_pid >= 0)
{
GSList *windows;
GSList *tmp;
/* Activate transient for window that belongs to
* mutter-dialog
*/
windows = meta_display_list_windows (window->display, META_LIST_DEFAULT);
tmp = windows;
while (tmp != NULL)
{
MetaWindow *w = tmp->data;
if (w->transient_for == window && w->res_class &&
g_ascii_strcasecmp (w->res_class, "mutter-dialog") == 0)
{
meta_window_activate (w, timestamp);
break;
}
tmp = tmp->next;
}
g_slist_free (windows);
}
}
static void
show_delete_dialog (MetaWindow *window,
guint32 timestamp)
{
char *window_title;
gchar *window_content, *tmp;
GPid dialog_pid;
meta_topic (META_DEBUG_PING,
"Got delete ping timeout for %s\n",
window->desc);
if (window->dialog_pid >= 0)
{
meta_window_present_delete_dialog (window, timestamp);
present_existing_delete_dialog (window, timestamp);
return;
}
@ -128,15 +151,33 @@ delete_ping_timeout_func (MetaWindow *window,
g_child_watch_add (dialog_pid, dialog_exited, window);
}
static void
kill_delete_dialog (MetaWindow *window)
{
if (window->dialog_pid > -1)
kill (window->dialog_pid, SIGTERM);
}
void
meta_window_set_alive (MetaWindow *window,
gboolean is_alive)
{
if (window->is_alive == is_alive)
return;
window->is_alive = is_alive;
if (window->is_alive)
kill_delete_dialog (window);
else
show_delete_dialog (window, CurrentTime);
}
void
meta_window_check_alive (MetaWindow *window,
guint32 timestamp)
{
meta_display_ping_window (window,
timestamp,
delete_ping_reply_func,
delete_ping_timeout_func,
NULL);
meta_display_ping_window (window, timestamp);
}
void
@ -149,7 +190,7 @@ meta_window_delete (MetaWindow *window,
if (window->has_focus)
{
/* FIXME Clean this up someday
/* FIXME Clean this up someday
* http://bugzilla.gnome.org/show_bug.cgi?id=108706
*/
#if 0
@ -191,39 +232,3 @@ meta_window_free_delete_dialog (MetaWindow *window)
window->dialog_pid = -1;
}
}
static void
meta_window_present_delete_dialog (MetaWindow *window, guint32 timestamp)
{
meta_topic (META_DEBUG_PING,
"Presenting existing ping dialog for %s\n",
window->desc);
if (window->dialog_pid >= 0)
{
GSList *windows;
GSList *tmp;
/* Activate transient for window that belongs to
* mutter-dialog
*/
windows = meta_display_list_windows (window->display, META_LIST_DEFAULT);
tmp = windows;
while (tmp != NULL)
{
MetaWindow *w = tmp->data;
if (w->transient_for == window && w->res_class &&
g_ascii_strcasecmp (w->res_class, "mutter-dialog") == 0)
{
meta_window_activate (w, timestamp);
break;
}
tmp = tmp->next;
}
g_slist_free (windows);
}
}

View File

@ -2,12 +2,12 @@
/* Mutter X display handler */
/*
/*
* Copyright (C) 2001 Havoc Pennington
* Copyright (C) 2002 Red Hat, Inc.
* Copyright (C) 2003 Rob Adams
* Copyright (C) 2004-2006 Elijah Newren
*
*
* 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
@ -17,7 +17,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*/
@ -53,10 +53,6 @@ typedef struct _MetaWindowPropHooks MetaWindowPropHooks;
typedef struct MetaEdgeResistanceData MetaEdgeResistanceData;
typedef void (* MetaWindowPingFunc) (MetaWindow *window,
guint32 timestamp,
gpointer user_data);
typedef enum {
META_LIST_DEFAULT = 0, /* normal windows */
META_LIST_INCLUDE_OVERRIDE_REDIRECT = 1 << 0, /* normal and O-R */
@ -85,7 +81,7 @@ typedef enum {
struct _MetaDisplay
{
GObject parent_instance;
char *name;
Display *xdisplay;
@ -143,7 +139,7 @@ struct _MetaDisplay
* multiple events with the same serial.
*/
guint focused_by_us : 1;
/*< private-ish >*/
MetaScreen *screen;
GHashTable *xids;
@ -157,7 +153,7 @@ struct _MetaDisplay
*/
unsigned long ignored_crossing_serials[N_IGNORED_CROSSING_SERIALS];
Window ungrab_should_not_cause_focus_window;
guint32 current_time;
/* We maintain a sequence counter, incremented for each #MetaWindow
@ -181,7 +177,7 @@ struct _MetaDisplay
/* Alt+click button grabs */
ClutterModifierType window_grab_modifiers;
/* current window operation */
MetaGrabOp grab_op;
MetaWindow *grab_window;
@ -234,7 +230,7 @@ struct _MetaDisplay
gboolean overlay_key_only_pressed;
MetaKeyCombo *iso_next_group_combos;
int n_iso_next_group_combos;
/* Monitor cache */
unsigned int monitor_cache_invalidated : 1;
@ -247,10 +243,6 @@ struct _MetaDisplay
/* Managed by group.c */
GHashTable *groups_by_leader;
/* currently-active window menu if any */
MetaWindowMenu *window_menu;
MetaWindow *window_with_menu;
/* Managed by window-props.c */
MetaWindowPropHooks *prop_hooks_table;
GHashTable *prop_hooks;
@ -367,9 +359,7 @@ MetaDisplay* meta_get_display (void);
Cursor meta_display_create_x_cursor (MetaDisplay *display,
MetaCursor cursor);
void meta_display_set_grab_op_cursor (MetaDisplay *display,
MetaGrabOp op,
guint32 timestamp);
void meta_display_update_cursor (MetaDisplay *display);
void meta_display_check_threshold_reached (MetaDisplay *display,
int x,
@ -399,13 +389,10 @@ const char* meta_event_detail_to_string (int d);
void meta_display_queue_retheme_all_windows (MetaDisplay *display);
void meta_display_retheme_all (void);
void meta_display_ping_window (MetaWindow *window,
guint32 timestamp,
MetaWindowPingFunc ping_reply_func,
MetaWindowPingFunc ping_timeout_func,
void *user_data);
void meta_display_pong_for_serial (MetaDisplay *display,
guint32 serial);
void meta_display_ping_window (MetaWindow *window,
guint32 serial);
void meta_display_pong_for_serial (MetaDisplay *display,
guint32 serial);
int meta_resize_gravity_from_grab_op (MetaGrabOp op);

View File

@ -1,11 +1,11 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
/*
* Copyright (C) 2001 Havoc Pennington
* Copyright (C) 2002, 2003, 2004 Red Hat, Inc.
* Copyright (C) 2003, 2004 Rob Adams
* Copyright (C) 2004-2006 Elijah Newren
*
*
* 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
@ -15,7 +15,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*/
@ -98,12 +98,9 @@
*/
typedef struct
{
MetaWindow *window;
guint32 timestamp;
MetaWindowPingFunc ping_reply_func;
MetaWindowPingFunc ping_timeout_func;
void *user_data;
guint ping_timeout_id;
MetaWindow *window;
guint32 serial;
guint ping_timeout_id;
} MetaPingData;
G_DEFINE_TYPE(MetaDisplay, meta_display, G_TYPE_OBJECT);
@ -441,11 +438,11 @@ meta_display_open (void)
#undef item
};
Atom atoms[G_N_ELEMENTS(atom_names)];
meta_verbose ("Opening display '%s'\n", XDisplayName (NULL));
xdisplay = meta_ui_get_display ();
if (xdisplay == NULL)
{
meta_warning (_("Failed to open X Window System display '%s'\n"),
@ -458,12 +455,12 @@ meta_display_open (void)
if (meta_is_syncing ())
XSynchronize (xdisplay, True);
g_assert (the_display == NULL);
the_display = g_object_new (META_TYPE_DISPLAY, NULL);
the_display->closing = 0;
/* here we use XDisplayName which is what the user
* probably put in, vs. DisplayString(display) which is
* canonicalized by XOpenDisplay()
@ -484,7 +481,7 @@ meta_display_open (void)
the_display->mouse_mode = TRUE; /* Only relevant for mouse or sloppy focus */
the_display->allow_terminal_deactivation = TRUE; /* Only relevant for when a
terminal has the focus */
meta_bell_init (the_display);
meta_display_init_keys (the_display);
@ -497,7 +494,7 @@ meta_display_open (void)
XInternAtoms (the_display->xdisplay, atom_names, G_N_ELEMENTS (atom_names),
False, atoms);
{
int i = 0;
int i = 0;
#define item(x) the_display->atom_##x = atoms[i++];
#include <meta/atomnames.h>
#undef item
@ -507,7 +504,7 @@ meta_display_open (void)
meta_display_init_window_prop_hooks (the_display);
the_display->group_prop_hooks = NULL;
meta_display_init_group_prop_hooks (the_display);
/* Offscreen unmapped window used for _NET_SUPPORTING_WM_CHECK,
* created in screen_new
*/
@ -518,11 +515,8 @@ meta_display_open (void)
the_display->groups_by_leader = NULL;
the_display->window_with_menu = NULL;
the_display->window_menu = NULL;
the_display->screen = NULL;
#ifdef HAVE_STARTUP_NOTIFICATION
the_display->sn_display = sn_display_new (the_display->xdisplay,
sn_error_trap_push,
@ -543,14 +537,14 @@ meta_display_open (void)
++i;
}
the_display->ungrab_should_not_cause_focus_window = None;
the_display->current_time = CurrentTime;
the_display->sentinel_counter = 0;
the_display->grab_resize_timeout_id = 0;
the_display->grab_have_keyboard = FALSE;
#ifdef HAVE_XKB
#ifdef HAVE_XKB
the_display->last_bell_time = 0;
#endif
@ -565,14 +559,14 @@ meta_display_open (void)
int major, minor;
the_display->have_xsync = FALSE;
the_display->xsync_error_base = 0;
the_display->xsync_event_base = 0;
/* I don't think we really have to fill these in */
major = SYNC_MAJOR_VERSION;
minor = SYNC_MINOR_VERSION;
if (!XSyncQueryExtension (the_display->xdisplay,
&the_display->xsync_event_base,
&the_display->xsync_error_base) ||
@ -596,10 +590,10 @@ meta_display_open (void)
{
the_display->have_shape = FALSE;
the_display->shape_error_base = 0;
the_display->shape_event_base = 0;
if (!XShapeQueryExtension (the_display->xdisplay,
&the_display->shape_event_base,
&the_display->shape_error_base))
@ -609,7 +603,7 @@ meta_display_open (void)
}
else
the_display->have_shape = TRUE;
meta_verbose ("Attempted to init Shape, found error base %d event base %d\n",
the_display->shape_error_base,
the_display->shape_event_base);
@ -627,7 +621,7 @@ meta_display_open (void)
{
the_display->composite_error_base = 0;
the_display->composite_event_base = 0;
}
}
else
{
the_display->composite_major_version = 0;
@ -647,7 +641,7 @@ meta_display_open (void)
meta_verbose ("Attempted to init Composite, found error base %d event base %d "
"extn ver %d %d\n",
the_display->composite_error_base,
the_display->composite_error_base,
the_display->composite_event_base,
the_display->composite_major_version,
the_display->composite_minor_version);
@ -663,12 +657,12 @@ meta_display_open (void)
{
the_display->damage_error_base = 0;
the_display->damage_event_base = 0;
}
}
else
the_display->have_damage = TRUE;
meta_verbose ("Attempted to init Damage, found error base %d event base %d\n",
the_display->damage_error_base,
the_display->damage_error_base,
the_display->damage_event_base);
the_display->xfixes_error_base = 0;
@ -691,7 +685,7 @@ meta_display_open (void)
}
meta_verbose ("Attempted to init XFixes, found error base %d event base %d\n",
the_display->xfixes_error_base,
the_display->xfixes_error_base,
the_display->xfixes_event_base);
}
@ -751,7 +745,7 @@ meta_display_open (void)
the_display->leader_window,
the_display->atom__GNOME_WM_KEYBINDINGS,
gnome_wm_keybindings);
meta_prop_set_utf8_string_hint (the_display,
the_display->leader_window,
the_display->atom__MUTTER_VERSION,
@ -937,7 +931,7 @@ meta_display_list_windows (MetaDisplay *display,
GSList *next;
next = tmp->next;
if (next &&
next->data == tmp->data)
{
@ -948,7 +942,7 @@ meta_display_list_windows (MetaDisplay *display,
if (tmp == winlist)
winlist = next;
g_slist_free_1 (tmp);
/* leave prev unchanged */
@ -957,7 +951,7 @@ meta_display_list_windows (MetaDisplay *display,
{
prev = tmp;
}
tmp = next;
}
@ -979,7 +973,7 @@ meta_display_close (MetaDisplay *display,
display->closing += 1;
meta_prefs_remove_listener (prefs_changed_callback, display);
meta_display_remove_autoraise_callback (display);
if (display->focus_timeout_id)
@ -988,7 +982,7 @@ meta_display_close (MetaDisplay *display,
/* Stop caring about events */
meta_display_free_events (display);
meta_screen_free (display->screen, timestamp);
#ifdef HAVE_STARTUP_NOTIFICATION
@ -998,11 +992,12 @@ meta_display_close (MetaDisplay *display,
display->sn_display = NULL;
}
#endif
/* Must be after all calls to meta_window_unmanage() since they
* unregister windows
*/
g_hash_table_destroy (display->xids);
g_hash_table_destroy (display->wayland_windows);
if (display->leader_window != None)
XDestroyWindow (display->xdisplay, display->leader_window);
@ -1011,14 +1006,14 @@ meta_display_close (MetaDisplay *display,
meta_display_free_window_prop_hooks (display);
meta_display_free_group_prop_hooks (display);
g_free (display->name);
meta_display_shutdown_keys (display);
if (display->compositor)
meta_compositor_destroy (display->compositor);
g_object_unref (display);
the_display = NULL;
@ -1054,7 +1049,7 @@ meta_display_ungrab (MetaDisplay *display)
{
if (display->server_grab_count == 0)
meta_bug ("Ungrabbed non-grabbed server\n");
display->server_grab_count -= 1;
if (display->server_grab_count == 0)
{
@ -1090,7 +1085,7 @@ meta_display_for_x_display (Display *xdisplay)
meta_warning ("Could not find display for X display %p, probably going to crash\n",
xdisplay);
return NULL;
}
@ -1115,8 +1110,8 @@ meta_grab_op_is_mouse (MetaGrabOp op)
{
case META_GRAB_OP_MOVING:
case META_GRAB_OP_RESIZING_SE:
case META_GRAB_OP_RESIZING_S:
case META_GRAB_OP_RESIZING_SW:
case META_GRAB_OP_RESIZING_S:
case META_GRAB_OP_RESIZING_SW:
case META_GRAB_OP_RESIZING_N:
case META_GRAB_OP_RESIZING_NE:
case META_GRAB_OP_RESIZING_NW:
@ -1157,8 +1152,8 @@ meta_grab_op_is_resizing (MetaGrabOp op)
switch (op)
{
case META_GRAB_OP_RESIZING_SE:
case META_GRAB_OP_RESIZING_S:
case META_GRAB_OP_RESIZING_SW:
case META_GRAB_OP_RESIZING_S:
case META_GRAB_OP_RESIZING_SW:
case META_GRAB_OP_RESIZING_N:
case META_GRAB_OP_RESIZING_NE:
case META_GRAB_OP_RESIZING_NW:
@ -1188,7 +1183,7 @@ meta_grab_op_is_moving (MetaGrabOp op)
case META_GRAB_OP_MOVING:
case META_GRAB_OP_KEYBOARD_MOVING:
return TRUE;
default:
return FALSE;
}
@ -1282,7 +1277,7 @@ guint32
meta_display_get_current_time_roundtrip (MetaDisplay *display)
{
guint32 timestamp;
timestamp = meta_display_get_current_time (display);
if (timestamp == CurrentTime)
{
@ -1323,7 +1318,7 @@ meta_display_add_ignored_crossing_serial (MetaDisplay *display,
/* don't add the same serial more than once */
if (display->ignored_crossing_serials[N_IGNORED_CROSSING_SERIALS-1] == serial)
return;
/* shift serials to the left */
i = 0;
while (i < (N_IGNORED_CROSSING_SERIALS - 1))
@ -1335,7 +1330,7 @@ meta_display_add_ignored_crossing_serial (MetaDisplay *display,
display->ignored_crossing_serials[i] = serial;
}
static gboolean
static gboolean
window_raise_with_delay_callback (void *data)
{
MetaWindow *window = data;
@ -1345,8 +1340,8 @@ window_raise_with_delay_callback (void *data)
/* If we aren't already on top, check whether the pointer is inside
* the window and raise the window if so.
*/
if (meta_stack_get_top (window->screen->stack) != window)
*/
if (meta_stack_get_top (window->screen->stack) != window)
{
int x, y, root_x, root_y;
Window root, child;
@ -1367,8 +1362,8 @@ window_raise_with_delay_callback (void *data)
if (same_screen && point_in_window)
meta_window_raise (window);
else
meta_topic (META_DEBUG_FOCUS,
"Pointer not inside window, not raising %s\n",
meta_topic (META_DEBUG_FOCUS,
"Pointer not inside window, not raising %s\n",
window->desc);
}
@ -1379,15 +1374,15 @@ void
meta_display_queue_autoraise_callback (MetaDisplay *display,
MetaWindow *window)
{
meta_topic (META_DEBUG_FOCUS,
"Queuing an autoraise timeout for %s with delay %d\n",
window->desc,
meta_topic (META_DEBUG_FOCUS,
"Queuing an autoraise timeout for %s with delay %d\n",
window->desc,
meta_prefs_get_auto_raise_delay ());
if (display->autoraise_timeout_id != 0)
g_source_remove (display->autoraise_timeout_id);
display->autoraise_timeout_id =
display->autoraise_timeout_id =
g_timeout_add_full (G_PRIORITY_DEFAULT,
meta_prefs_get_auto_raise_delay (),
window_raise_with_delay_callback,
@ -1561,7 +1556,7 @@ meta_display_register_x_window (MetaDisplay *display,
MetaWindow *window)
{
g_return_if_fail (g_hash_table_lookup (display->xids, xwindowp) == NULL);
g_hash_table_insert (display->xids, xwindowp, window);
}
@ -1695,23 +1690,9 @@ meta_cursor_for_grab_op (MetaGrabOp op)
}
void
meta_display_set_grab_op_cursor (MetaDisplay *display,
MetaGrabOp op,
guint32 timestamp)
meta_display_update_cursor (MetaDisplay *display)
{
/* Set root cursor */
MetaBackend *backend = meta_get_backend ();
MetaCursorTracker *tracker = meta_cursor_tracker_get_for_screen (display->screen);
MetaCursor cursor = meta_cursor_for_grab_op (op);
MetaCursorReference *cursor_ref;
cursor_ref = meta_cursor_reference_from_theme (cursor);
meta_cursor_tracker_set_grab_cursor (tracker, cursor_ref);
if (cursor_ref)
meta_cursor_reference_unref (cursor_ref);
if (meta_backend_grab_device (backend, META_VIRTUAL_CORE_POINTER_ID, timestamp))
display->grab_have_pointer = TRUE;
meta_screen_set_cursor (display->screen, meta_cursor_for_grab_op (display->grab_op));
}
static MetaWindow *
@ -1739,24 +1720,25 @@ meta_display_begin_grab_op (MetaDisplay *display,
int root_x,
int root_y)
{
MetaBackend *backend = meta_get_backend ();
MetaWindow *grab_window = NULL;
g_assert (window != NULL);
meta_topic (META_DEBUG_WINDOW_OPS,
"Doing grab op %u on window %s button %d pointer already grabbed: %d pointer pos %d,%d\n",
op, window ? window->desc : "none", button, pointer_already_grabbed,
op, window->desc, button, pointer_already_grabbed,
root_x, root_y);
if (display->grab_op != META_GRAB_OP_NONE)
{
if (window)
meta_warning ("Attempt to perform window operation %u on window %s when operation %u on %s already in effect\n",
op, window->desc, display->grab_op,
display->grab_window ? display->grab_window->desc : "none");
meta_warning ("Attempt to perform window operation %u on window %s when operation %u on %s already in effect\n",
op, window->desc, display->grab_op,
display->grab_window ? display->grab_window->desc : "none");
return FALSE;
}
if (window &&
(meta_grab_op_is_moving (op) || meta_grab_op_is_resizing (op)))
if (meta_grab_op_is_moving (op) || meta_grab_op_is_resizing (op))
{
if (meta_prefs_get_raise_on_click ())
meta_window_raise (window);
@ -1773,7 +1755,7 @@ meta_display_begin_grab_op (MetaDisplay *display,
/* If window is a modal dialog attached to its parent,
* grab the parent instead for moving.
*/
if (meta_grab_op_is_moving (op))
if (meta_window_is_attached_dialog (window) && meta_grab_op_is_moving (op))
grab_window = get_toplevel_transient_for (window);
g_assert (grab_window != NULL);
@ -1793,7 +1775,8 @@ meta_display_begin_grab_op (MetaDisplay *display,
timestamp);
XSync (display->xdisplay, False);
meta_display_set_grab_op_cursor (display, op, timestamp);
if (meta_backend_grab_device (backend, META_VIRTUAL_CORE_POINTER_ID, timestamp))
display->grab_have_pointer = TRUE;
if (!display->grab_have_pointer && !meta_grab_op_is_keyboard (op))
{
@ -1808,7 +1791,6 @@ meta_display_begin_grab_op (MetaDisplay *display,
if (!display->grab_have_keyboard)
{
MetaBackend *backend = meta_get_backend ();
meta_topic (META_DEBUG_WINDOW_OPS, "grabbing all keys failed, ungrabbing pointer\n");
meta_backend_ungrab_device (backend, META_VIRTUAL_CORE_POINTER_ID, timestamp);
display->grab_have_pointer = FALSE;
@ -1832,6 +1814,8 @@ meta_display_begin_grab_op (MetaDisplay *display,
display->grab_resize_unmaximize = 0;
display->grab_timestamp = timestamp;
meta_display_update_cursor (display);
if (display->grab_resize_timeout_id)
{
g_source_remove (display->grab_resize_timeout_id);
@ -1861,8 +1845,6 @@ void
meta_display_end_grab_op (MetaDisplay *display,
guint32 timestamp)
{
MetaCursorTracker *tracker;
meta_topic (META_DEBUG_WINDOW_OPS,
"Ending grab op %u at time %u\n", display->grab_op, timestamp);
@ -1903,15 +1885,14 @@ meta_display_end_grab_op (MetaDisplay *display,
meta_window_ungrab_all_keys (display->grab_window, timestamp);
}
tracker = meta_cursor_tracker_get_for_screen (display->screen);
meta_cursor_tracker_set_grab_cursor (tracker, NULL);
display->grab_timestamp = 0;
display->grab_window = NULL;
display->grab_tile_mode = META_TILE_NONE;
display->grab_tile_monitor_number = -1;
display->grab_op = META_GRAB_OP_NONE;
meta_display_update_cursor (display);
if (display->grab_resize_timeout_id)
{
g_source_remove (display->grab_resize_timeout_id);
@ -1990,7 +1971,7 @@ meta_change_button_grab (MetaDisplay *display,
mods = (XIGrabModifiers) { modmask | ignored_mask, 0 };
/* GrabModeSync means freeze until XAllowEvents */
if (grab)
XIGrabButton (xdisplay,
META_VIRTUAL_CORE_POINTER_ID,
@ -2010,11 +1991,8 @@ meta_change_button_grab (MetaDisplay *display,
void
meta_display_grab_window_buttons (MetaDisplay *display,
Window xwindow)
{
MetaBackend *backend = meta_get_backend ();
/* Do nothing under non-X11 backends */
if (!META_IS_BACKEND_X11 (backend))
{
if (meta_is_wayland_compositor ())
return;
/* Grab Alt + button1 for moving window.
@ -2023,7 +2001,7 @@ meta_display_grab_window_buttons (MetaDisplay *display,
* Grab Alt + Shift + button1 for snap-moving window.
*/
meta_verbose ("Grabbing window buttons for 0x%lx\n", xwindow);
/* FIXME If we ignored errors here instead of spewing, we could
* put one big error trap around the loop and avoid a bunch of
* XSync()
@ -2038,8 +2016,8 @@ meta_display_grab_window_buttons (MetaDisplay *display,
meta_change_button_grab (display, xwindow,
TRUE,
FALSE,
i, display->window_grab_modifiers);
i, display->window_grab_modifiers);
/* This is for debugging, since I end up moving the Xnest
* otherwise ;-)
*/
@ -2067,18 +2045,15 @@ void
meta_display_ungrab_window_buttons (MetaDisplay *display,
Window xwindow)
{
MetaBackend *backend = meta_get_backend ();
/* Do nothing under non-X11 backends */
if (!META_IS_BACKEND_X11 (backend))
return;
gboolean debug;
int i;
if (meta_is_wayland_compositor ())
return;
if (display->window_grab_modifiers == 0)
return;
debug = g_getenv ("MUTTER_DEBUG_BUTTON_GRABS") != NULL;
i = 1;
while (i < 4)
@ -2086,11 +2061,11 @@ meta_display_ungrab_window_buttons (MetaDisplay *display,
meta_change_button_grab (display, xwindow,
FALSE, FALSE, i,
display->window_grab_modifiers);
if (debug)
meta_change_button_grab (display, xwindow,
FALSE, FALSE, i, ControlMask);
++i;
}
}
@ -2101,10 +2076,7 @@ void
meta_display_grab_focus_window_button (MetaDisplay *display,
MetaWindow *window)
{
MetaBackend *backend = meta_get_backend ();
/* Do nothing under non-X11 backends */
if (!META_IS_BACKEND_X11 (backend))
if (meta_is_wayland_compositor ())
return;
/* Grab button 1 for activating unfocused windows */
@ -2124,18 +2096,18 @@ meta_display_grab_focus_window_button (MetaDisplay *display,
return;
}
#endif
if (window->have_focus_click_grab)
{
meta_verbose (" (well, not grabbing since we already have the grab)\n");
return;
}
/* FIXME If we ignored errors here instead of spewing, we could
* put one big error trap around the loop and avoid a bunch of
* XSync()
*/
{
int i = 1;
while (i < MAX_FOCUS_BUTTON)
@ -2144,7 +2116,7 @@ meta_display_grab_focus_window_button (MetaDisplay *display,
window->xwindow,
TRUE, TRUE,
i, 0);
++i;
}
@ -2156,24 +2128,21 @@ void
meta_display_ungrab_focus_window_button (MetaDisplay *display,
MetaWindow *window)
{
MetaBackend *backend = meta_get_backend ();
/* Do nothing under non-X11 backends */
if (!META_IS_BACKEND_X11 (backend))
if (meta_is_wayland_compositor ())
return;
meta_verbose ("Ungrabbing unfocused window buttons for %s\n", window->desc);
if (!window->have_focus_click_grab)
return;
{
int i = 1;
while (i < MAX_FOCUS_BUTTON)
{
meta_change_button_grab (display, window->xwindow,
FALSE, FALSE, i, 0);
++i;
}
@ -2218,14 +2187,14 @@ meta_display_queue_retheme_all_windows (MetaDisplay *display)
while (tmp != NULL)
{
MetaWindow *window = tmp->data;
meta_window_queue (window, META_QUEUE_MOVE_RESIZE);
meta_window_frame_size_changed (window);
if (window->frame)
{
meta_frame_queue_draw (window->frame);
}
tmp = tmp->next;
}
@ -2331,15 +2300,16 @@ static gboolean
meta_display_ping_timeout (gpointer data)
{
MetaPingData *ping_data = data;
MetaDisplay *display = ping_data->window->display;
MetaWindow *window = ping_data->window;
MetaDisplay *display = window->display;
meta_window_set_alive (window, FALSE);
ping_data->ping_timeout_id = 0;
meta_topic (META_DEBUG_PING,
"Ping %u on window %s timed out\n",
ping_data->timestamp, ping_data->window->desc);
(* ping_data->ping_timeout_func) (ping_data->window, ping_data->timestamp, ping_data->user_data);
ping_data->serial, ping_data->window->desc);
display->pending_pings = g_slist_remove (display->pending_pings, ping_data);
ping_data_free (ping_data);
@ -2353,11 +2323,6 @@ meta_display_ping_timeout (gpointer data)
* @window: The #MetaWindow to send the ping to
* @timestamp: The timestamp of the ping. Used for uniqueness.
* Cannot be CurrentTime; use a real timestamp!
* @ping_reply_func: The callback to call if we get a response.
* @ping_timeout_func: The callback to call if we don't get a response.
* @user_data: Arbitrary data that will be passed to the callback
* function. (In practice it's often a pointer to
* the window.)
*
* Sends a ping request to a window. The window must respond to
* the request within a certain amount of time. If it does, we
@ -2369,35 +2334,24 @@ meta_display_ping_timeout (gpointer data)
* the callbacks will be called from the event loop.
*/
void
meta_display_ping_window (MetaWindow *window,
guint32 timestamp,
MetaWindowPingFunc ping_reply_func,
MetaWindowPingFunc ping_timeout_func,
gpointer user_data)
meta_display_ping_window (MetaWindow *window,
guint32 serial)
{
MetaDisplay *display = window->display;
MetaPingData *ping_data;
if (timestamp == CurrentTime)
if (serial == 0)
{
meta_warning ("Tried to ping a window with CurrentTime! Not allowed.\n");
meta_warning ("Tried to ping a window with a bad serial! Not allowed.\n");
return;
}
if (!window->can_ping)
{
if (ping_reply_func)
(* ping_reply_func) (window, timestamp, user_data);
return;
}
return;
ping_data = g_new (MetaPingData, 1);
ping_data->window = window;
ping_data->timestamp = timestamp;
ping_data->ping_reply_func = ping_reply_func;
ping_data->ping_timeout_func = ping_timeout_func;
ping_data->user_data = user_data;
ping_data->serial = serial;
ping_data->ping_timeout_id = g_timeout_add (PING_TIMEOUT_DELAY,
meta_display_ping_timeout,
ping_data);
@ -2406,10 +2360,10 @@ meta_display_ping_window (MetaWindow *window,
display->pending_pings = g_slist_prepend (display->pending_pings, ping_data);
meta_topic (META_DEBUG_PING,
"Sending ping with timestamp %u to window %s\n",
timestamp, window->desc);
"Sending ping with serial %u to window %s\n",
serial, window->desc);
META_WINDOW_GET_CLASS (window)->ping (window, timestamp);
META_WINDOW_GET_CLASS (window)->ping (window, serial);
}
/**
@ -2433,11 +2387,11 @@ meta_display_pong_for_serial (MetaDisplay *display,
{
MetaPingData *ping_data = tmp->data;
if (serial == ping_data->timestamp)
if (serial == ping_data->serial)
{
meta_topic (META_DEBUG_PING,
"Matching ping found for pong %u\n",
ping_data->timestamp);
ping_data->serial);
/* Remove the ping data from the list */
display->pending_pings = g_slist_remove (display->pending_pings,
@ -2450,13 +2404,8 @@ meta_display_pong_for_serial (MetaDisplay *display,
ping_data->ping_timeout_id = 0;
}
/* Call callback */
(* ping_data->ping_reply_func) (ping_data->window,
ping_data->timestamp,
ping_data->user_data);
meta_window_set_alive (ping_data->window, TRUE);
ping_data_free (ping_data);
break;
}
}
@ -2511,7 +2460,7 @@ find_tab_forward (MetaDisplay *display,
return window;
tmp = tmp->next;
}
}
return NULL;
}
@ -2529,7 +2478,7 @@ find_tab_backward (MetaDisplay *display,
g_return_val_if_fail (workspace != NULL, NULL);
tmp = start;
if (skip_last)
if (skip_last)
tmp = tmp->prev;
while (tmp != NULL)
{
@ -2637,7 +2586,7 @@ meta_display_get_tab_list (MetaDisplay *display,
g_list_free (global_mru_list);
g_slist_free (windows);
return tab_list;
}
@ -2646,8 +2595,8 @@ meta_display_get_tab_list (MetaDisplay *display,
* @display: a #MetaDisplay
* @type: type of tab list
* @workspace: origin workspace
* @window: (allow-none): starting window
* @backward: If %TRUE, look for the previous window.
* @window: (allow-none): starting window
* @backward: If %TRUE, look for the previous window.
*
* Determine the next window that should be displayed for Alt-TAB
* functionality.
@ -2669,11 +2618,11 @@ meta_display_get_tab_next (MetaDisplay *display,
if (tab_list == NULL)
return NULL;
if (window != NULL)
{
g_assert (window->display == display);
if (backward)
ret = find_tab_backward (display, type, workspace, g_list_find (tab_list, window), TRUE);
else
@ -2681,7 +2630,7 @@ meta_display_get_tab_next (MetaDisplay *display,
}
else
{
skip = display->focus_window != NULL &&
skip = display->focus_window != NULL &&
tab_list->data == display->focus_window;
if (backward)
ret = find_tab_backward (display, type, workspace, tab_list, skip);
@ -2712,7 +2661,7 @@ meta_display_get_tab_current (MetaDisplay *display,
MetaWindow *window;
window = display->focus_window;
if (window != NULL &&
IN_TAB_CHAIN (window, type) &&
(workspace == NULL ||
@ -2726,7 +2675,7 @@ int
meta_resize_gravity_from_grab_op (MetaGrabOp op)
{
int gravity;
gravity = -1;
switch (op)
{
@ -2808,7 +2757,7 @@ meta_display_unmanage_windows_for_screen (MetaDisplay *display,
if (!window->unmanaging)
meta_window_unmanage (window, timestamp);
g_object_unref (window);
tmp = tmp->next;
}
g_slist_free (winlist);
@ -2858,7 +2807,7 @@ meta_display_devirtualize_modifiers (MetaDisplay *display,
unsigned int *mask)
{
*mask = 0;
if (modifiers & META_VIRTUAL_SHIFT_MASK)
*mask |= ShiftMask;
if (modifiers & META_VIRTUAL_CONTROL_MASK)
@ -2878,7 +2827,7 @@ meta_display_devirtualize_modifiers (MetaDisplay *display,
if (modifiers & META_VIRTUAL_MOD4_MASK)
*mask |= Mod4Mask;
if (modifiers & META_VIRTUAL_MOD5_MASK)
*mask |= Mod5Mask;
*mask |= Mod5Mask;
}
static void
@ -2886,11 +2835,11 @@ update_window_grab_modifiers (MetaDisplay *display)
{
MetaVirtualModifier virtual_mods;
unsigned int mods;
virtual_mods = meta_prefs_get_mouse_button_mods ();
meta_display_devirtualize_modifiers (display, virtual_mods,
&mods);
display->window_grab_modifiers = mods;
}
@ -2899,7 +2848,7 @@ prefs_changed_callback (MetaPreference pref,
void *data)
{
MetaDisplay *display = data;
/* It may not be obvious why we regrab on focus mode
* change; it's because we handle focus clicks a
* bit differently for the different focus modes.
@ -2910,9 +2859,9 @@ prefs_changed_callback (MetaPreference pref,
MetaDisplay *display = data;
GSList *windows;
GSList *tmp;
windows = meta_display_list_windows (display, META_LIST_DEFAULT);
/* Ungrab all */
tmp = windows;
while (tmp != NULL)
@ -2959,13 +2908,13 @@ meta_display_increment_focus_sentinel (MetaDisplay *display)
unsigned long data[1];
data[0] = meta_display_get_current_time (display);
XChangeProperty (display->xdisplay,
display->screen->xroot,
display->atom__MUTTER_SENTINEL,
XA_CARDINAL,
32, PropModeReplace, (guchar*) data, 1);
display->sentinel_counter += 1;
}
@ -3014,7 +2963,7 @@ meta_display_sanity_check_timestamps (MetaDisplay *display,
while (tmp != NULL)
{
MetaWindow *window = tmp->data;
if (XSERVER_TIME_IS_BEFORE (timestamp, window->net_wm_user_time))
{
meta_warning ("%s appears to be one of the offending windows "
@ -3031,7 +2980,7 @@ meta_display_sanity_check_timestamps (MetaDisplay *display,
}
void
meta_display_set_input_focus_window (MetaDisplay *display,
meta_display_set_input_focus_window (MetaDisplay *display,
MetaWindow *window,
gboolean focus_frame,
guint32 timestamp)
@ -3187,7 +3136,7 @@ meta_display_get_focus_window (MetaDisplay *display)
return display->focus_window;
}
int
int
meta_display_get_damage_event_base (MetaDisplay *display)
{
return display->damage_event_base;

View File

@ -2,9 +2,9 @@
/* Edge resistance for move/resize operations */
/*
/*
* Copyright (C) 2005, 2006 Elijah Newren
*
*
* 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
@ -14,7 +14,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*/
@ -245,8 +245,8 @@ find_nearest_position (const GArray *edges,
{
edge = g_array_index (edges, MetaEdge*, i);
compare = horizontal ? edge->rect.x : edge->rect.y;
edges_align = horizontal ?
edges_align = horizontal ?
meta_rectangle_vert_overlap (&edge->rect, new_rect) :
meta_rectangle_horiz_overlap (&edge->rect, new_rect);
@ -269,8 +269,8 @@ find_nearest_position (const GArray *edges,
{
edge = g_array_index (edges, MetaEdge*, i);
compare = horizontal ? edge->rect.x : edge->rect.y;
edges_align = horizontal ?
edges_align = horizontal ?
meta_rectangle_vert_overlap (&edge->rect, new_rect) :
meta_rectangle_horiz_overlap (&edge->rect, new_rect);
@ -433,7 +433,7 @@ apply_edge_resistance (MetaWindow *window,
if (!resistance_data->timeout_setup &&
timeout_length_ms != 0)
{
resistance_data->timeout_id =
resistance_data->timeout_id =
g_timeout_add (timeout_length_ms,
edge_resistance_timeout,
resistance_data);
@ -536,7 +536,7 @@ apply_edge_snapping (int old_pos,
* display->grab_edge_resistance_data MUST already be setup or calling this
* function will cause a crash.
*/
static gboolean
static gboolean
apply_edge_resistance_to_each_side (MetaDisplay *display,
MetaWindow *window,
const MetaRectangle *old_outer,
@ -658,7 +658,7 @@ apply_edge_resistance_to_each_side (MetaDisplay *display,
}
/* Determine whether anything changed, and save the changes */
modified_rect = meta_rect (new_left,
modified_rect = meta_rect (new_left,
new_top,
new_right - new_left,
new_bottom - new_top);
@ -754,7 +754,7 @@ meta_display_cleanup_edges (MetaDisplay *display)
}
static int
stupid_sort_requiring_extra_pointer_dereference (gconstpointer a,
stupid_sort_requiring_extra_pointer_dereference (gconstpointer a,
gconstpointer b)
{
const MetaEdge * const *a_edge = a;
@ -779,7 +779,7 @@ cache_edges (MetaDisplay *display,
#ifdef WITH_VERBOSE_MODE
if (meta_is_verbose())
{
int max_edges = MAX (MAX( g_list_length (window_edges),
int max_edges = MAX (MAX( g_list_length (window_edges),
g_list_length (monitor_edges)),
g_list_length (screen_edges));
char big_buffer[(EDGE_LENGTH+2)*max_edges];
@ -916,13 +916,13 @@ cache_edges (MetaDisplay *display,
* avoided this sort by sticking them into the array with some simple
* merging of the lists).
*/
g_array_sort (display->grab_edge_resistance_data->left_edges,
g_array_sort (display->grab_edge_resistance_data->left_edges,
stupid_sort_requiring_extra_pointer_dereference);
g_array_sort (display->grab_edge_resistance_data->right_edges,
g_array_sort (display->grab_edge_resistance_data->right_edges,
stupid_sort_requiring_extra_pointer_dereference);
g_array_sort (display->grab_edge_resistance_data->top_edges,
g_array_sort (display->grab_edge_resistance_data->top_edges,
stupid_sort_requiring_extra_pointer_dereference);
g_array_sort (display->grab_edge_resistance_data->bottom_edges,
g_array_sort (display->grab_edge_resistance_data->bottom_edges,
stupid_sort_requiring_extra_pointer_dereference);
}
@ -986,7 +986,7 @@ compute_resistance_and_snapping_edges (MetaDisplay *display)
new_rect = g_new (MetaRectangle, 1);
meta_window_get_frame_rect (cur_window, new_rect);
obscuring_windows = g_slist_prepend (obscuring_windows, new_rect);
window_stacking =
window_stacking =
g_slist_prepend (window_stacking, GINT_TO_POINTER (stack_position));
}
@ -1026,7 +1026,7 @@ compute_resistance_and_snapping_edges (MetaDisplay *display)
* is offscreen (we also don't care about parts of edges covered
* by other windows or DOCKS, but that's handled below).
*/
meta_rectangle_intersect (&cur_rect,
meta_rectangle_intersect (&cur_rect,
&display->screen->rect,
&reduced);
@ -1052,7 +1052,7 @@ compute_resistance_and_snapping_edges (MetaDisplay *display)
new_edge->side_type = META_SIDE_LEFT;
new_edge->edge_type = META_EDGE_WINDOW;
new_edges = g_list_prepend (new_edges, new_edge);
/* Top side of this window is resistance for the bottom edge of
* the window being moved.
*/
@ -1077,7 +1077,7 @@ compute_resistance_and_snapping_edges (MetaDisplay *display)
/* Update the remaining windows to only those at a higher
* stacking position than this one.
*/
while (rem_win_stacking &&
while (rem_win_stacking &&
stack_position >= GPOINTER_TO_INT (rem_win_stacking->data))
{
rem_windows = rem_windows->next;
@ -1085,7 +1085,7 @@ compute_resistance_and_snapping_edges (MetaDisplay *display)
}
/* Remove edge portions overlapped by rem_windows and rem_docks */
new_edges =
new_edges =
meta_rectangle_remove_intersections_with_boxes_from_edges (
new_edges,
rem_windows);
@ -1107,7 +1107,7 @@ compute_resistance_and_snapping_edges (MetaDisplay *display)
/* FIXME: Shouldn't there be a helper function to make this one line of code
* to free a list instead of four ugly ones?
*/
g_slist_foreach (obscuring_windows,
g_slist_foreach (obscuring_windows,
(void (*)(gpointer,gpointer))&g_free, /* ew, for ugly */
NULL);
g_slist_free (obscuring_windows);
@ -1205,7 +1205,7 @@ meta_window_edge_resistance_for_move (MetaWindow *window,
else
smaller_y_change = bottom_change;
*new_x = old_x + smaller_x_change +
*new_x = old_x + smaller_x_change +
(BOX_LEFT (*reference) - BOX_LEFT (old_outer));
*new_y = old_y + smaller_y_change +
(BOX_TOP (*reference) - BOX_TOP (old_outer));
@ -1239,7 +1239,7 @@ meta_window_edge_resistance_for_resize (MetaWindow *window,
meta_window_get_frame_rect (window, &old_outer);
proposed_outer_width = old_outer.width + (*new_width - old_width);
proposed_outer_height = old_outer.height + (*new_height - old_height);
meta_rectangle_resize_with_gravity (&old_outer,
meta_rectangle_resize_with_gravity (&old_outer,
&new_outer,
gravity,
proposed_outer_width,

View File

@ -2,9 +2,9 @@
/* Edge resistance for move/resize operations */
/*
/*
* Copyright (C) 2005 Elijah Newren
*
*
* 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
@ -14,7 +14,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*/

View File

@ -1,9 +1,9 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
/*
* Copyright (C) 2001 Havoc Pennington, error trapping inspired by GDK
* code copyrighted by the GTK team.
*
*
* 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
@ -13,7 +13,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*/

View File

@ -888,22 +888,17 @@ handle_input_xevent (MetaDisplay *display,
enter_event->time,
enter_event->root_x,
enter_event->root_y);
if (window->type == META_WINDOW_DOCK)
meta_window_raise (window);
}
break;
case XI_Leave:
if (display->grab_op == META_GRAB_OP_COMPOSITOR)
break;
if (window != NULL)
if (window != NULL &&
enter_event->mode != XINotifyGrab &&
enter_event->mode != XINotifyUngrab)
{
if (window->type == META_WINDOW_DOCK &&
enter_event->mode != XINotifyGrab &&
enter_event->mode != XINotifyUngrab &&
!window->has_focus)
meta_window_lower (window);
meta_window_handle_leave (window);
}
break;
case XI_FocusIn:
@ -1683,20 +1678,6 @@ handle_other_xevent (MetaDisplay *display,
return bypass_gtk;
}
static gboolean
grab_op_should_block_mouse_events (MetaGrabOp op)
{
switch (op)
{
case META_GRAB_OP_WAYLAND_POPUP:
case META_GRAB_OP_COMPOSITOR:
return TRUE;
default:
return FALSE;
}
}
static gboolean
window_has_xwindow (MetaWindow *window,
Window xwindow)
@ -1743,6 +1724,7 @@ meta_display_handle_xevent (MetaDisplay *display,
}
#endif
display->current_time = event_get_time (display, event);
display->monitor_cache_invalidated = TRUE;
if (display->focused_by_us &&
@ -1838,7 +1820,7 @@ meta_display_handle_xevent (MetaDisplay *display,
bypass_gtk = TRUE;
}
display->current_time = event_get_time (display, event);
display->current_time = CurrentTime;
return bypass_gtk;
}
@ -1927,196 +1909,48 @@ meta_display_handle_event (MetaDisplay *display,
}
}
switch (event->type)
/* For key events, it's important to enforce single-handling, or
* we can get into a confused state. So if a keybinding is
* handled (because it's one of our hot-keys, or because we are
* in a keyboard-grabbed mode like moving a window, we don't
* want to pass the key event to the compositor or Wayland at all.
*/
if (meta_keybindings_process_event (display, window, event))
{
case CLUTTER_BUTTON_PRESS:
if (grab_op_should_block_mouse_events (display->grab_op))
break;
bypass_clutter = TRUE;
bypass_wayland = TRUE;
goto out;
}
display->overlay_key_only_pressed = FALSE;
if (window)
{
/* Swallow all events on windows that come our way. */
bypass_clutter = TRUE;
if (window && display->grab_op == META_GRAB_OP_NONE)
{
ClutterModifierType grab_mask;
gboolean unmodified;
gboolean fully_modified;
grab_mask = display->window_grab_modifiers;
if (g_getenv ("MUTTER_DEBUG_BUTTON_GRABS"))
grab_mask |= CLUTTER_CONTROL_MASK;
/* We have three passive button grabs:
* - on any button, without modifiers => focuses and maybe raises the window
* - on resize button, with modifiers => start an interactive resizing
* (normally <Super>middle)
* - on move button, with modifiers => start an interactive move
* (normally <Super>left)
* - on menu button, with modifiers => show the window menu
* (normally <Super>right)
*
* We may get here because we actually have a button
* grab on the window, or because we're a wayland
* compositor and thus we see all the events, so we
* need to check if the event is interesting.
* We want an event that is not modified, for a window
* that has (or would have, the wayland case) the
* button grab active.
*
* We may have other events on the window, for example
* a click on a frame button, but that's not for us to
* care about. Just let the event through.
*/
unmodified = (event->button.modifier_state & grab_mask) == 0;
fully_modified = grab_mask && (event->button.modifier_state & grab_mask) == grab_mask;
if (unmodified && window && window->have_focus_click_grab)
{
if (meta_prefs_get_raise_on_click ())
meta_window_raise (window);
else
meta_topic (META_DEBUG_FOCUS,
"Not raising window on click due to don't-raise-on-click option\n");
/* Don't focus panels--they must explicitly request focus.
* See bug 160470
*/
if (window->type != META_WINDOW_DOCK)
{
meta_topic (META_DEBUG_FOCUS,
"Focusing %s due to unmodified button %u press (display.c)\n",
window->desc, event->button.button);
meta_window_focus (window, event->any.time);
}
else
/* However, do allow terminals to lose focus due to new
* window mappings after the user clicks on a panel.
*/
display->allow_terminal_deactivation = TRUE;
meta_verbose ("Allowing events time %u\n",
(unsigned int)event->button.time);
{
MetaBackend *backend = meta_get_backend ();
if (META_IS_BACKEND_X11 (backend))
{
Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
XIAllowEvents (xdisplay, clutter_input_device_get_device_id (event->button.device),
XIReplayDevice, event->button.time);
}
}
bypass_clutter = TRUE;
}
else if (fully_modified && (int) event->button.button == meta_prefs_get_mouse_button_resize ())
{
if (window->has_resize_func)
{
gboolean north, south;
gboolean west, east;
MetaRectangle frame_rect;
MetaGrabOp op;
meta_window_get_frame_rect (window, &frame_rect);
west = event->button.x < (frame_rect.x + 1 * frame_rect.width / 3);
east = event->button.x > (frame_rect.x + 2 * frame_rect.width / 3);
north = event->button.y < (frame_rect.y + 1 * frame_rect.height / 3);
south = event->button.y > (frame_rect.y + 2 * frame_rect.height / 3);
if (north && west)
op = META_GRAB_OP_RESIZING_NW;
else if (north && east)
op = META_GRAB_OP_RESIZING_NE;
else if (south && west)
op = META_GRAB_OP_RESIZING_SW;
else if (south && east)
op = META_GRAB_OP_RESIZING_SE;
else if (north)
op = META_GRAB_OP_RESIZING_N;
else if (west)
op = META_GRAB_OP_RESIZING_W;
else if (east)
op = META_GRAB_OP_RESIZING_E;
else if (south)
op = META_GRAB_OP_RESIZING_S;
else /* Middle region is no-op to avoid user triggering wrong action */
op = META_GRAB_OP_NONE;
if (op != META_GRAB_OP_NONE)
meta_display_begin_grab_op (display,
window->screen,
window,
op,
TRUE,
FALSE,
event->button.button,
0,
event->any.time,
event->button.x,
event->button.y);
}
bypass_clutter = TRUE;
bypass_wayland = TRUE;
}
else if (fully_modified && (int) event->button.button == meta_prefs_get_mouse_button_menu ())
{
if (meta_prefs_get_raise_on_click ())
meta_window_raise (window);
meta_window_show_menu (window,
event->button.x,
event->button.y,
event->button.button,
event->any.time);
bypass_clutter = TRUE;
bypass_wayland = TRUE;
}
else if (fully_modified && (int) event->button.button == 1)
{
if (window->has_move_func)
{
meta_display_begin_grab_op (display,
window->screen,
window,
META_GRAB_OP_MOVING,
TRUE,
FALSE,
event->button.button,
0,
event->any.time,
event->button.x,
event->button.y);
}
bypass_clutter = TRUE;
bypass_wayland = TRUE;
}
}
break;
case CLUTTER_BUTTON_RELEASE:
if (grab_op_should_block_mouse_events (display->grab_op))
break;
display->overlay_key_only_pressed = FALSE;
break;
case CLUTTER_KEY_PRESS:
case CLUTTER_KEY_RELEASE:
/* For key events, it's important to enforce single-handling, or
* we can get into a confused state. So if a keybinding is
* handled (because it's one of our hot-keys, or because we are
* in a keyboard-grabbed mode like moving a window, we don't
* want to pass the key event to the compositor or Wayland at all.
/* Under X11, we have a Sync grab and in order to send it back to
* clients, we have to explicitly replay it.
*
* Under Wayland, we retrieve all events and we have to make sure
* to filter them out from Wayland clients.
*/
if (meta_display_process_key_event (display, window, (ClutterKeyEvent *) event))
if (meta_window_handle_ungrabbed_event (window, event))
{
bypass_clutter = TRUE;
bypass_wayland = TRUE;
}
break;
else
{
MetaBackend *backend = meta_get_backend ();
if (META_IS_BACKEND_X11 (backend))
{
Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
meta_verbose ("Allowing events time %u\n",
(unsigned int)event->button.time);
XIAllowEvents (xdisplay, clutter_event_get_device_id (event),
XIReplayDevice, event->button.time);
}
}
default:
break;
goto out;
}
out:
@ -2134,6 +1968,7 @@ meta_display_handle_event (MetaDisplay *display,
bypass_clutter = TRUE;
}
display->current_time = CurrentTime;
return bypass_clutter;
}

View File

@ -2,11 +2,11 @@
/* Mutter X window decorations */
/*
/*
* Copyright (C) 2001 Havoc Pennington
* Copyright (C) 2003, 2004 Red Hat, Inc.
* Copyright (C) 2005 Elijah Newren
*
*
* 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
@ -16,7 +16,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*/
@ -43,10 +43,10 @@ meta_window_ensure_frame (MetaWindow *window)
Visual *visual;
gulong create_serial;
MetaStackWindow stack_window;
if (window->frame)
return;
frame = g_new (MetaFrame, 1);
frame->window = window;
@ -61,7 +61,7 @@ meta_window_ensure_frame (MetaWindow *window)
frame->is_flashing = FALSE;
frame->borders_cached = FALSE;
meta_verbose ("Framing window %s: visual %s default, depth %d default depth %d\n",
window->desc,
XVisualIDFromVisual (window->xvisual) ==
@ -71,7 +71,7 @@ meta_window_ensure_frame (MetaWindow *window)
meta_verbose ("Frame geometry %d,%d %dx%d\n",
frame->rect.x, frame->rect.y,
frame->rect.width, frame->rect.height);
/* Default depth/visual handles clients with weird visuals; they can
* always be children of the root depth/visual obviously, but
* e.g. DRI games can't be children of a parent that has the same
@ -80,7 +80,7 @@ meta_window_ensure_frame (MetaWindow *window)
* We look for an ARGB visual if we can find one, otherwise use
* the default of NULL.
*/
/* Special case for depth 32 windows (assumed to be ARGB),
* we use the window's visual. Otherwise we just use the system visual.
*/
@ -88,7 +88,7 @@ meta_window_ensure_frame (MetaWindow *window)
visual = window->xvisual;
else
visual = NULL;
frame->xwindow = meta_ui_create_frame_window (window->screen->ui,
window->display->xdisplay,
visual,
@ -108,7 +108,7 @@ meta_window_ensure_frame (MetaWindow *window)
attrs.event_mask = EVENT_MASK;
XChangeWindowAttributes (window->display->xdisplay,
frame->xwindow, CWEventMask, &attrs);
meta_display_register_x_window (window->display, &frame->xwindow, window);
meta_error_trap_push (window->display);
@ -136,7 +136,7 @@ meta_window_ensure_frame (MetaWindow *window)
window->rect.y);
/* FIXME handle this error */
meta_error_trap_pop (window->display);
/* stick frame to the window */
window->frame = frame;
@ -145,16 +145,21 @@ meta_window_ensure_frame (MetaWindow *window)
*/
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,
window->frame->xwindow,
window->title);
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);
/* Move keybindings to frame instead of window */
meta_window_grab_keys (window);
meta_ui_map_frame (frame->window->screen->ui, frame->xwindow);
}
void
@ -163,18 +168,18 @@ meta_window_destroy_frame (MetaWindow *window)
MetaFrame *frame;
MetaFrameBorders borders;
MetaStackWindow stack_window;
if (window->frame == NULL)
return;
meta_verbose ("Unframing window %s\n", window->desc);
frame = window->frame;
meta_frame_calc_borders (frame, &borders);
meta_bell_notify_frame_destroy (frame);
/* Unparent the client window; it may be destroyed,
* thus the error trap.
*/
@ -209,7 +214,7 @@ meta_window_destroy_frame (MetaWindow *window)
meta_display_unregister_x_window (window->display,
frame->xwindow);
window->frame = NULL;
if (window->frame_bounds)
{
@ -219,9 +224,9 @@ meta_window_destroy_frame (MetaWindow *window)
/* Move keybindings to window instead of frame */
meta_window_grab_keys (window);
g_free (frame);
/* Put our state back where it should be */
meta_window_queue (window, META_QUEUE_CALC_SHOWING);
meta_window_queue (window, META_QUEUE_MOVE_RESIZE);
@ -244,20 +249,24 @@ meta_frame_get_flags (MetaFrame *frame)
else
{
flags |= META_FRAME_ALLOWS_MENU;
if (meta_prefs_get_show_fallback_app_menu () &&
frame->window->gtk_app_menu_object_path)
flags |= META_FRAME_ALLOWS_APPMENU;
if (frame->window->has_close_func)
flags |= META_FRAME_ALLOWS_DELETE;
if (frame->window->has_maximize_func)
flags |= META_FRAME_ALLOWS_MAXIMIZE;
if (frame->window->has_minimize_func)
flags |= META_FRAME_ALLOWS_MINIMIZE;
if (frame->window->has_shade_func)
flags |= META_FRAME_ALLOWS_SHADE;
}
}
if (META_WINDOW_ALLOWS_MOVE (frame->window))
flags |= META_FRAME_ALLOWS_MOVE;
@ -266,7 +275,7 @@ meta_frame_get_flags (MetaFrame *frame)
if (META_WINDOW_ALLOWS_VERTICAL_RESIZE (frame->window))
flags |= META_FRAME_ALLOWS_VERTICAL_RESIZE;
if (meta_window_appears_focused (frame->window))
flags |= META_FRAME_HAS_FOCUS;
@ -296,7 +305,7 @@ meta_frame_get_flags (MetaFrame *frame)
if (frame->window->wm_state_above)
flags |= META_FRAME_ABOVE;
return flags;
}
@ -418,7 +427,7 @@ meta_frame_set_screen_cursor (MetaFrame *frame,
if (cursor == META_CURSOR_DEFAULT)
XUndefineCursor (frame->window->display->xdisplay, frame->xwindow);
else
{
{
xcursor = meta_display_create_x_cursor (frame->window->display, cursor);
XDefineCursor (frame->window->display->xdisplay, frame->xwindow, xcursor);
XFlush (frame->window->display->xdisplay);

View File

@ -2,9 +2,9 @@
/* Mutter X window decorations */
/*
/*
* Copyright (C) 2001 Havoc Pennington
*
*
* 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
@ -14,7 +14,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*/

View File

@ -7,9 +7,9 @@
* the one to close a window. It also deals with incoming key events.
*/
/*
/*
* Copyright (C) 2001 Havoc Pennington
*
*
* 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
@ -19,7 +19,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*/
@ -100,9 +100,9 @@ gboolean meta_window_grab_all_keys (MetaWindow *window,
guint32 timestamp);
void meta_window_ungrab_all_keys (MetaWindow *window,
guint32 timestamp);
gboolean meta_display_process_key_event (MetaDisplay *display,
MetaWindow *window,
ClutterKeyEvent *event);
gboolean meta_keybindings_process_event (MetaDisplay *display,
MetaWindow *window,
const ClutterEvent *event);
void meta_display_process_mapping_event (MetaDisplay *display,
XEvent *event);

View File

@ -1081,7 +1081,7 @@ typedef struct
{
MetaDisplay *display;
Window xwindow;
gboolean binding_per_window;
gboolean only_per_window;
gboolean grab;
} ChangeKeygrabData;
@ -1092,29 +1092,31 @@ change_keygrab_foreach (gpointer key,
{
ChangeKeygrabData *data = user_data;
MetaKeyBinding *binding = value;
gboolean binding_is_per_window = (binding->flags & META_KEY_BINDING_PER_WINDOW) != 0;
if (!!data->binding_per_window ==
!!(binding->flags & META_KEY_BINDING_PER_WINDOW) &&
binding->keycode != 0)
{
meta_change_keygrab (data->display, data->xwindow, data->grab,
binding->keysym,
binding->keycode,
binding->mask);
}
if (data->only_per_window != binding_is_per_window)
return;
if (binding->keycode == 0)
return;
meta_change_keygrab (data->display, data->xwindow, data->grab,
binding->keysym,
binding->keycode,
binding->mask);
}
static void
change_binding_keygrabs (MetaDisplay *display,
Window xwindow,
gboolean binding_per_window,
gboolean grab)
change_binding_keygrabs (MetaDisplay *display,
Window xwindow,
gboolean only_per_window,
gboolean grab)
{
ChangeKeygrabData data;
data.display = display;
data.xwindow = xwindow;
data.binding_per_window = binding_per_window;
data.only_per_window = only_per_window;
data.grab = grab;
g_hash_table_foreach (display->key_bindings, change_keygrab_foreach, &data);
@ -1259,6 +1261,7 @@ guint
meta_display_grab_accelerator (MetaDisplay *display,
const char *accelerator)
{
MetaBackend *backend = meta_get_backend ();
MetaKeyBinding *binding;
MetaKeyGrab *grab;
guint keysym = 0;
@ -1284,7 +1287,8 @@ meta_display_grab_accelerator (MetaDisplay *display,
if (display_get_keybinding (display, keycode, mask))
return META_KEYBINDING_ACTION_NONE;
meta_change_keygrab (display, display->screen->xroot, TRUE, keysym, keycode, mask);
if (META_IS_BACKEND_X11 (backend))
meta_change_keygrab (display, display->screen->xroot, TRUE, keysym, keycode, mask);
grab = g_new0 (MetaKeyGrab, 1);
grab->action = next_dynamic_keybinding_action ();
@ -1314,6 +1318,7 @@ gboolean
meta_display_ungrab_accelerator (MetaDisplay *display,
guint action)
{
MetaBackend *backend = meta_get_backend ();
MetaKeyBinding *binding;
MetaKeyGrab *grab;
char *key;
@ -1335,10 +1340,11 @@ meta_display_ungrab_accelerator (MetaDisplay *display,
{
guint32 index_key;
meta_change_keygrab (display, display->screen->xroot, FALSE,
binding->keysym,
binding->keycode,
binding->mask);
if (META_IS_BACKEND_X11 (backend))
meta_change_keygrab (display, display->screen->xroot, FALSE,
binding->keysym,
binding->keycode,
binding->mask);
index_key = key_binding_key (binding->keycode, binding->mask);
g_hash_table_remove (display->key_bindings_index, GINT_TO_POINTER (index_key));
@ -1594,11 +1600,12 @@ process_overlay_key (MetaDisplay *display,
MetaWindow *window)
{
MetaBackend *backend = meta_get_backend ();
Display *xdisplay;
if (!META_IS_BACKEND_X11 (backend))
return FALSE;
Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
if (META_IS_BACKEND_X11 (backend))
xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
else
xdisplay = NULL;
if (display->overlay_key_only_pressed)
{
@ -1624,17 +1631,22 @@ process_overlay_key (MetaDisplay *display,
* binding, we unfreeze the keyboard but keep the grab
* (this is important for something like cycling
* windows */
XIAllowEvents (xdisplay,
clutter_input_device_get_device_id (event->device),
XIAsyncDevice, event->time);
if (xdisplay)
XIAllowEvents (xdisplay,
clutter_input_device_get_device_id (event->device),
XIAsyncDevice, event->time);
}
else
{
/* Replay the event so it gets delivered to our
* per-window key bindings or to the application */
XIAllowEvents (xdisplay,
clutter_input_device_get_device_id (event->device),
XIReplayDevice, event->time);
if (xdisplay)
XIAllowEvents (xdisplay,
clutter_input_device_get_device_id (event->device),
XIReplayDevice, event->time);
return FALSE;
}
}
else if (event->type == CLUTTER_KEY_RELEASE)
@ -1645,9 +1657,10 @@ process_overlay_key (MetaDisplay *display,
/* We want to unfreeze events, but keep the grab so that if the user
* starts typing into the overlay we get all the keys */
XIAllowEvents (xdisplay,
clutter_input_device_get_device_id (event->device),
XIAsyncDevice, event->time);
if (xdisplay)
XIAllowEvents (xdisplay,
clutter_input_device_get_device_id (event->device),
XIAsyncDevice, event->time);
binding = display_get_keybinding (display,
display->overlay_key_combo.keycode,
@ -1671,9 +1684,10 @@ process_overlay_key (MetaDisplay *display,
*
* https://bugzilla.gnome.org/show_bug.cgi?id=666101
*/
XIAllowEvents (xdisplay,
clutter_input_device_get_device_id (event->device),
XIAsyncDevice, event->time);
if (xdisplay)
XIAllowEvents (xdisplay,
clutter_input_device_get_device_id (event->device),
XIAsyncDevice, event->time);
}
return TRUE;
@ -1684,9 +1698,10 @@ process_overlay_key (MetaDisplay *display,
display->overlay_key_only_pressed = TRUE;
/* We keep the keyboard frozen - this allows us to use ReplayKeyboard
* on the next event if it's not the release of the overlay key */
XIAllowEvents (xdisplay,
clutter_input_device_get_device_id (event->device),
XISyncDevice, event->time);
if (xdisplay)
XIAllowEvents (xdisplay,
clutter_input_device_get_device_id (event->device),
XISyncDevice, event->time);
return TRUE;
}
@ -1725,24 +1740,10 @@ process_iso_next_group (MetaDisplay *display,
return activate;
}
/* Handle a key event. May be called recursively: some key events cause
* grabs to be ended and then need to be processed again in their own
* right. This cannot cause infinite recursion because we never call
* ourselves when there wasn't a grab, and we always clear the grab
* first; the invariant is enforced using an assertion. See #112560.
*
* The return value is whether we handled the key event.
*
* FIXME: We need to prove there are no race conditions here.
* FIXME: Does it correctly handle alt-Tab being followed by another
* grabbing keypress without letting go of alt?
* FIXME: An iterative solution would probably be simpler to understand
* (and help us solve the other fixmes).
*/
gboolean
meta_display_process_key_event (MetaDisplay *display,
MetaWindow *window,
ClutterKeyEvent *event)
static gboolean
process_key_event (MetaDisplay *display,
MetaWindow *window,
ClutterKeyEvent *event)
{
gboolean keep_grab;
gboolean all_keys_grabbed;
@ -1840,6 +1841,41 @@ meta_display_process_key_event (MetaDisplay *display,
return process_event (display, screen, window, event);
}
/* Handle a key event. May be called recursively: some key events cause
* grabs to be ended and then need to be processed again in their own
* right. This cannot cause infinite recursion because we never call
* ourselves when there wasn't a grab, and we always clear the grab
* first; the invariant is enforced using an assertion. See #112560.
*
* The return value is whether we handled the key event.
*
* FIXME: We need to prove there are no race conditions here.
* FIXME: Does it correctly handle alt-Tab being followed by another
* grabbing keypress without letting go of alt?
* FIXME: An iterative solution would probably be simpler to understand
* (and help us solve the other fixmes).
*/
gboolean
meta_keybindings_process_event (MetaDisplay *display,
MetaWindow *window,
const ClutterEvent *event)
{
switch (event->type)
{
case CLUTTER_BUTTON_PRESS:
case CLUTTER_BUTTON_RELEASE:
display->overlay_key_only_pressed = FALSE;
return FALSE;
case CLUTTER_KEY_PRESS:
case CLUTTER_KEY_RELEASE:
return process_key_event (display, window, (ClutterKeyEvent *) event);
default:
return FALSE;
}
}
static gboolean
process_mouse_move_resize_grab (MetaDisplay *display,
MetaScreen *screen,
@ -2455,46 +2491,58 @@ handle_always_on_top (MetaDisplay *display,
meta_window_unmake_above (window);
}
/* Move a window to a corner; to_bottom/to_right are FALSE for the
* top or left edge, or TRUE for the bottom/right edge. xchange/ychange
* are FALSE if that dimension is not to be changed, TRUE otherwise.
* Together they describe which of the four corners, or four sides,
* is desired.
*/
static void
handle_move_to_corner_backend (MetaDisplay *display,
MetaScreen *screen,
MetaWindow *window,
gboolean xchange,
gboolean ychange,
gboolean to_right,
gboolean to_bottom,
gpointer dummy)
handle_move_to_corner_backend (MetaDisplay *display,
MetaScreen *screen,
MetaWindow *window,
int gravity)
{
MetaRectangle work_area;
MetaRectangle frame_rect;
int orig_x, orig_y;
int new_x, new_y;
meta_window_get_work_area_all_monitors (window, &work_area);
meta_window_get_frame_rect (window, &frame_rect);
meta_window_get_position (window, &orig_x, &orig_y);
if (xchange) {
new_x = work_area.x + (to_right ?
work_area.width - frame_rect.width :
0);
} else {
new_x = orig_x;
}
switch (gravity)
{
case NorthWestGravity:
case WestGravity:
case SouthWestGravity:
new_x = work_area.x;
break;
case NorthGravity:
case SouthGravity:
new_x = frame_rect.x;
break;
case NorthEastGravity:
case EastGravity:
case SouthEastGravity:
new_x = work_area.x + work_area.width - frame_rect.width;
break;
default:
g_assert_not_reached ();
}
if (ychange) {
new_y = work_area.y + (to_bottom ?
work_area.height - frame_rect.height :
0);
} else {
new_y = orig_y;
}
switch (gravity)
{
case NorthWestGravity:
case NorthGravity:
case NorthEastGravity:
new_y = work_area.y;
break;
case WestGravity:
case EastGravity:
new_y = frame_rect.y;
break;
case SouthWestGravity:
case SouthGravity:
case SouthEastGravity:
new_y = work_area.y + work_area.height - frame_rect.height;
break;
default:
g_assert_not_reached ();
}
meta_window_move_frame (window,
TRUE,
@ -2510,7 +2558,7 @@ handle_move_to_corner_nw (MetaDisplay *display,
MetaKeyBinding *binding,
gpointer dummy)
{
handle_move_to_corner_backend (display, screen, window, TRUE, TRUE, FALSE, FALSE, dummy);
handle_move_to_corner_backend (display, screen, window, NorthWestGravity);
}
static void
@ -2521,7 +2569,7 @@ handle_move_to_corner_ne (MetaDisplay *display,
MetaKeyBinding *binding,
gpointer dummy)
{
handle_move_to_corner_backend (display, screen, window, TRUE, TRUE, TRUE, FALSE, dummy);
handle_move_to_corner_backend (display, screen, window, NorthEastGravity);
}
static void
@ -2532,7 +2580,7 @@ handle_move_to_corner_sw (MetaDisplay *display,
MetaKeyBinding *binding,
gpointer dummy)
{
handle_move_to_corner_backend (display, screen, window, TRUE, TRUE, FALSE, TRUE, dummy);
handle_move_to_corner_backend (display, screen, window, SouthWestGravity);
}
static void
@ -2543,7 +2591,7 @@ handle_move_to_corner_se (MetaDisplay *display,
MetaKeyBinding *binding,
gpointer dummy)
{
handle_move_to_corner_backend (display, screen, window, TRUE, TRUE, TRUE, TRUE, dummy);
handle_move_to_corner_backend (display, screen, window, SouthEastGravity);
}
static void
@ -2554,7 +2602,7 @@ handle_move_to_side_n (MetaDisplay *display,
MetaKeyBinding *binding,
gpointer dummy)
{
handle_move_to_corner_backend (display, screen, window, FALSE, TRUE, FALSE, FALSE, dummy);
handle_move_to_corner_backend (display, screen, window, NorthGravity);
}
static void
@ -2565,7 +2613,7 @@ handle_move_to_side_s (MetaDisplay *display,
MetaKeyBinding *binding,
gpointer dummy)
{
handle_move_to_corner_backend (display, screen, window, FALSE, TRUE, FALSE, TRUE, dummy);
handle_move_to_corner_backend (display, screen, window, SouthGravity);
}
static void
@ -2576,7 +2624,7 @@ handle_move_to_side_e (MetaDisplay *display,
MetaKeyBinding *binding,
gpointer dummy)
{
handle_move_to_corner_backend (display, screen, window, TRUE, FALSE, TRUE, FALSE, dummy);
handle_move_to_corner_backend (display, screen, window, EastGravity);
}
static void
@ -2587,7 +2635,7 @@ handle_move_to_side_w (MetaDisplay *display,
MetaKeyBinding *binding,
gpointer dummy)
{
handle_move_to_corner_backend (display, screen, window, TRUE, FALSE, FALSE, FALSE, dummy);
handle_move_to_corner_backend (display, screen, window, WestGravity);
}
static void
@ -2600,22 +2648,14 @@ handle_move_to_center (MetaDisplay *display,
{
MetaRectangle work_area;
MetaRectangle frame_rect;
int orig_x, orig_y;
int frame_width, frame_height;
meta_window_get_work_area_all_monitors (window, &work_area);
meta_window_get_frame_rect (window, &frame_rect);
meta_window_get_position (window, &orig_x, &orig_y);
frame_width = (window->frame ? window->frame->child_x : 0);
frame_height = (window->frame ? window->frame->child_y : 0);
meta_window_move_resize (window,
TRUE,
work_area.x + (work_area.width +frame_width -frame_rect.width )/2,
work_area.y + (work_area.height+frame_height-frame_rect.height)/2,
window->rect.width,
window->rect.height);
meta_window_move_frame (window,
TRUE,
work_area.x + (work_area.width - frame_rect.width ) / 2,
work_area.y + (work_area.height - frame_rect.height) / 2);
}
static void
@ -2700,17 +2740,18 @@ handle_activate_window_menu (MetaDisplay *display,
if (display->focus_window)
{
int x, y;
MetaRectangle frame_rect;
cairo_rectangle_int_t child_rect;
meta_window_get_position (display->focus_window,
&x, &y);
meta_window_get_frame_rect (display->focus_window, &frame_rect);
meta_window_get_client_area_rect (display->focus_window, &child_rect);
x = frame_rect.x + child_rect.x;
if (meta_ui_get_direction() == META_UI_DIRECTION_RTL)
x += display->focus_window->rect.width;
x += child_rect.width;
meta_window_show_menu (display->focus_window,
x, y,
0,
event->time);
y = frame_rect.y + child_rect.y;
meta_window_show_menu (display->focus_window, META_WINDOW_MENU_WM, x, y);
}
}
@ -2723,7 +2764,7 @@ do_choose_window (MetaDisplay *display,
gboolean backward)
{
MetaTabList type = binding->handler->data;
MetaWindow *initial_selection;
MetaWindow *window;
meta_topic (META_DEBUG_KEYBINDINGS,
"Tab list = %u\n", type);
@ -2732,13 +2773,14 @@ do_choose_window (MetaDisplay *display,
if (event->modifier_state & CLUTTER_SHIFT_MASK)
backward = !backward;
initial_selection = meta_display_get_tab_next (display,
type,
screen->active_workspace,
NULL,
backward);
window = meta_display_get_tab_next (display,
type,
screen->active_workspace,
NULL,
backward);
meta_window_activate (initial_selection, event->time);
if (window)
meta_window_activate (window, event->time);
}
static void

View File

@ -2,10 +2,10 @@
/* Mutter main() */
/*
/*
* Copyright (C) 2001 Havoc Pennington
* Copyright (C) 2006 Elijah Newren
*
*
* 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
@ -15,7 +15,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*/
@ -160,7 +160,7 @@ meta_print_self_identity (void)
g_date_strftime (buf, sizeof (buf), "%x", &d);
meta_verbose ("Mutter version %s running on %s\n",
VERSION, buf);
/* Locale and encoding. */
g_get_charset (&charset);
meta_verbose ("Running in locale \"%s\" with encoding \"%s\"\n",
@ -343,7 +343,7 @@ meta_init (void)
g_get_home_dir ());
meta_print_self_identity ();
#ifdef HAVE_INTROSPECTION
g_irepository_prepend_search_path (MUTTER_PKGLIBDIR);
#endif
@ -358,13 +358,13 @@ meta_init (void)
meta_select_display (opt_display_name);
meta_set_syncing (opt_sync || (g_getenv ("MUTTER_SYNC") != NULL));
if (opt_replace_wm)
meta_set_replace_current_wm (TRUE);
if (opt_save_file && opt_client_id)
meta_fatal ("Can't specify both SM save file and SM client id\n");
meta_main_loop = g_main_loop_new (NULL, FALSE);
meta_ui_init ();
@ -455,7 +455,7 @@ meta_run (void)
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
@ -464,37 +464,37 @@ meta_run (void)
*/
if (!meta_ui_have_a_theme ())
meta_ui_set_current_theme ("Simple");
if (!meta_ui_have_a_theme ())
{
const char *dir_entry = NULL;
GError *err = NULL;
GDir *themes_dir = NULL;
if (!(themes_dir = g_dir_open (MUTTER_DATADIR"/themes", 0, &err)))
{
meta_fatal (_("Failed to scan themes directory: %s\n"), err->message);
g_error_free (err);
}
else
}
else
{
while (((dir_entry = g_dir_read_name (themes_dir)) != NULL) &&
while (((dir_entry = g_dir_read_name (themes_dir)) != NULL) &&
(!meta_ui_have_a_theme ()))
{
meta_ui_set_current_theme (dir_entry);
}
g_dir_close (themes_dir);
}
}
if (!meta_ui_have_a_theme ())
meta_fatal (_("Could not find a theme! Be sure %s exists and contains the usual themes.\n"),
MUTTER_DATADIR"/themes");
if (!meta_display_open ())
meta_exit (META_EXIT_ERROR);
g_main_loop_run (meta_main_loop);
meta_finalize ();

View File

@ -12,7 +12,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*/
@ -75,6 +75,7 @@ main (int argc, char **argv)
g_printerr ("mutter: %s\n", error->message);
exit (1);
}
g_option_context_free (ctx);
if (plugin)
meta_plugin_manager_load (plugin);

View File

@ -2,12 +2,12 @@
/* Mutter window placement */
/*
/*
* Copyright (C) 2001 Havoc Pennington
* Copyright (C) 2002, 2003 Red Hat, Inc.
* Copyright (C) 2003 Rob Adams
* Copyright (C) 2005 Elijah Newren
*
*
* 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
@ -17,7 +17,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*/
@ -57,11 +57,11 @@ northwestcmp (gconstpointer a, gconstpointer b)
ay = a_frame.y;
bx = b_frame.x;
by = b_frame.y;
/* probably there's a fast good-enough-guess we could use here. */
from_origin_a = sqrt (ax * ax + ay * ay);
from_origin_b = sqrt (bx * bx + by * by);
if (from_origin_a < from_origin_b)
return -1;
else if (from_origin_a > from_origin_b)
@ -82,40 +82,31 @@ find_next_cascade (MetaWindow *window,
GList *tmp;
GList *sorted;
int cascade_x, cascade_y;
MetaRectangle titlebar_rect;
int x_threshold, y_threshold;
MetaRectangle frame_rect;
int window_width, window_height;
int cascade_stage;
MetaRectangle work_area;
int current;
sorted = g_list_copy (windows);
sorted = g_list_sort (sorted, northwestcmp);
/* This is a "fuzzy" cascade algorithm.
/* This is a "fuzzy" cascade algorithm.
* For each window in the list, we find where we'd cascade a
* new window after it. If a window is already nearly at that
* position, we move on.
*/
/* arbitrary-ish threshold, honors user attempts to
* manually cascade.
*/
#define CASCADE_FUZZ 15
if (window->frame)
{
MetaFrameBorders borders;
meta_window_get_titlebar_rect (window, &titlebar_rect);
x_threshold = MAX (titlebar_rect.x, CASCADE_FUZZ);
y_threshold = MAX (titlebar_rect.y, CASCADE_FUZZ);
meta_frame_calc_borders (window->frame, &borders);
x_threshold = MAX (borders.visible.left, CASCADE_FUZZ);
y_threshold = MAX (borders.visible.top, CASCADE_FUZZ);
}
else
{
x_threshold = CASCADE_FUZZ;
y_threshold = CASCADE_FUZZ;
}
/* Find furthest-SE origin of all workspaces.
* cascade_x, cascade_y are the target position
* of NW corner of window frame.
@ -126,13 +117,13 @@ find_next_cascade (MetaWindow *window,
cascade_x = MAX (0, work_area.x);
cascade_y = MAX (0, work_area.y);
/* Find first cascade position that's not used. */
meta_window_get_frame_rect (window, &frame_rect);
window_width = frame_rect.width;
window_height = frame_rect.height;
cascade_stage = 0;
tmp = sorted;
while (tmp != NULL)
@ -140,25 +131,23 @@ find_next_cascade (MetaWindow *window,
MetaWindow *w;
MetaRectangle w_frame_rect;
int wx, wy;
w = tmp->data;
/* we want frame position, not window position */
meta_window_get_frame_rect (w, &w_frame_rect);
wx = w_frame_rect.x;
wy = w_frame_rect.y;
if (ABS (wx - cascade_x) < x_threshold &&
ABS (wy - cascade_y) < y_threshold)
{
/* This window is "in the way", move to next cascade
* point. The new window frame should go at the origin
* of the client window we're stacking above.
*/
meta_window_get_position (w, &wx, &wy);
cascade_x = wx;
cascade_y = wy;
meta_window_get_titlebar_rect (w, &titlebar_rect);
/* Cascade the window evenly by the titlebar height; this isn't a typo. */
cascade_x = wx + titlebar_rect.height;
cascade_y = wy + titlebar_rect.height;
/* If we go off the screen, start over with a new cascade */
if (((cascade_x + window_width) >
(work_area.x + work_area.width)) ||
@ -167,11 +156,11 @@ find_next_cascade (MetaWindow *window,
{
cascade_x = MAX (0, work_area.x);
cascade_y = MAX (0, work_area.y);
#define CASCADE_INTERVAL 50 /* space between top-left corners of cascades */
cascade_stage += 1;
cascade_x += CASCADE_INTERVAL * cascade_stage;
/* start over with a new cascade translated to the right, unless
* we are out of space
*/
@ -193,14 +182,14 @@ find_next_cascade (MetaWindow *window,
{
/* Keep searching for a further-down-the-diagonal window. */
}
tmp = tmp->next;
}
/* cascade_x and cascade_y will match the last window in the list
* that was "in the way" (in the approximate cascade diagonal)
*/
g_list_free (sorted);
*new_x = cascade_x;
@ -376,12 +365,12 @@ rectangle_overlaps_some_window (MetaRectangle *rect,
{
GList *tmp;
MetaRectangle dest;
tmp = windows;
while (tmp != NULL)
{
MetaWindow *other = tmp->data;
MetaRectangle other_rect;
MetaRectangle other_rect;
switch (other->type)
{
@ -405,12 +394,12 @@ rectangle_overlaps_some_window (MetaRectangle *rect,
case META_WINDOW_TOOLBAR:
case META_WINDOW_MENU:
meta_window_get_frame_rect (other, &other_rect);
if (meta_rectangle_intersect (rect, &other_rect, &dest))
return TRUE;
break;
}
tmp = tmp->next;
}
@ -503,20 +492,20 @@ find_first_fit (MetaWindow *window,
* the bottom of each existing window, and then to the right
* of each existing window, aligned with the left/top of the
* existing window in each of those cases.
*/
*/
int retval;
GList *below_sorted;
GList *right_sorted;
GList *tmp;
MetaRectangle rect;
MetaRectangle work_area;
retval = FALSE;
/* Below each window */
below_sorted = g_list_copy (windows);
below_sorted = g_list_sort (below_sorted, leftmost_cmp);
below_sorted = g_list_sort (below_sorted, topmost_cmp);
below_sorted = g_list_sort (below_sorted, topmost_cmp);
/* To the right of each window */
right_sorted = g_list_copy (windows);
@ -545,9 +534,9 @@ find_first_fit (MetaWindow *window,
{
*new_x = rect.x;
*new_y = rect.y;
retval = TRUE;
goto out;
}
@ -559,18 +548,18 @@ find_first_fit (MetaWindow *window,
MetaRectangle frame_rect;
meta_window_get_frame_rect (w, &frame_rect);
rect.x = frame_rect.x;
rect.y = frame_rect.y + frame_rect.height;
if (meta_rectangle_contains_rect (&work_area, &rect) &&
!rectangle_overlaps_some_window (&rect, below_sorted))
{
*new_x = rect.x;
*new_y = rect.y;
retval = TRUE;
goto out;
}
@ -583,26 +572,26 @@ find_first_fit (MetaWindow *window,
{
MetaWindow *w = tmp->data;
MetaRectangle frame_rect;
meta_window_get_frame_rect (w, &frame_rect);
rect.x = frame_rect.x + frame_rect.width;
rect.y = frame_rect.y;
if (meta_rectangle_contains_rect (&work_area, &rect) &&
!rectangle_overlaps_some_window (&rect, right_sorted))
{
*new_x = rect.x;
*new_y = rect.y;
retval = TRUE;
goto out;
}
tmp = tmp->next;
}
out:
g_list_free (below_sorted);
@ -617,13 +606,11 @@ meta_window_place (MetaWindow *window,
int *new_x,
int *new_y)
{
GList *windows;
GList *windows = NULL;
const MetaMonitorInfo *xi;
meta_topic (META_DEBUG_PLACEMENT, "Placing window %s\n", window->desc);
windows = NULL;
switch (window->type)
{
/* Run placement algorithm on these. */
@ -632,7 +619,7 @@ meta_window_place (MetaWindow *window,
case META_WINDOW_MODAL_DIALOG:
case META_WINDOW_SPLASHSCREEN:
break;
/* Assume the app knows best how to place these, no placement
* algorithm ever (other than "leave them as-is")
*/
@ -649,7 +636,7 @@ meta_window_place (MetaWindow *window,
case META_WINDOW_COMBO:
case META_WINDOW_DND:
case META_WINDOW_OVERRIDE_OTHER:
goto done_no_constraints;
goto done;
}
if (meta_prefs_get_disable_workarounds ())
@ -675,7 +662,7 @@ meta_window_place (MetaWindow *window,
case META_WINDOW_MODAL_DIALOG:
case META_WINDOW_SPLASHSCREEN:
break;
/* Assume the app knows best how to place these. */
case META_WINDOW_DESKTOP:
case META_WINDOW_DOCK:
@ -694,7 +681,7 @@ meta_window_place (MetaWindow *window,
{
meta_topic (META_DEBUG_PLACEMENT,
"Not placing non-normal non-dialog window with PPosition set\n");
goto done_no_constraints;
goto done;
}
break;
}
@ -702,14 +689,14 @@ meta_window_place (MetaWindow *window,
else
{
/* workarounds enabled */
if ((window->size_hints.flags & PPosition) ||
(window->size_hints.flags & USPosition))
{
meta_topic (META_DEBUG_PLACEMENT,
"Not placing window with PPosition or USPosition set\n");
avoid_being_obscured_as_second_modal_dialog (window, &x, &y);
goto done_no_constraints;
goto done;
}
}
@ -739,17 +726,17 @@ meta_window_place (MetaWindow *window,
meta_topic (META_DEBUG_PLACEMENT, "Centered window %s over transient parent\n",
window->desc);
avoid_being_obscured_as_second_modal_dialog (window, &x, &y);
goto done;
}
}
/* FIXME UTILITY with transient set should be stacked up
* on the sides of the parent window or something.
*/
if (window_place_centered (window))
{
/* Center on current monitor */
@ -769,13 +756,13 @@ meta_window_place (MetaWindow *window,
x += xi->rect.x;
y += xi->rect.y;
meta_topic (META_DEBUG_PLACEMENT, "Centered window %s on screen %d monitor %d\n",
window->desc, window->screen->number, xi->number);
goto done_check_denied_focus;
}
/* Find windows that matter (not minimized, on same workspace
* as placed window, may be shaded - if shaded we pretend it isn't
* for placement purposes)
@ -783,7 +770,7 @@ meta_window_place (MetaWindow *window,
{
GSList *all_windows;
GSList *tmp;
all_windows = meta_display_list_windows (window->display, META_LIST_DEFAULT);
tmp = all_windows;
@ -804,19 +791,10 @@ meta_window_place (MetaWindow *window,
/* Warning, this is a round trip! */
xi = meta_screen_get_current_monitor_info (window->screen);
/* "Origin" placement algorithm */
x = xi->rect.x;
y = xi->rect.y;
if (find_first_fit (window, windows,
xi->number,
x, y, &x, &y))
goto done_check_denied_focus;
/* Maximize windows if they are too big for their work area (bit of
* a hack here). Assume undecorated windows probably don't intend to
* be maximized.
* be maximized.
*/
if (window->has_maximize_func && window->decorated &&
!window->fullscreen)
@ -826,9 +804,9 @@ meta_window_place (MetaWindow *window,
meta_window_get_work_area_for_monitor (window,
xi->number,
&workarea);
&workarea);
meta_window_get_frame_rect (window, &frame_rect);
/* If the window is bigger than the screen, then automaximize. Do NOT
* auto-maximize the directions independently. See #419810.
*/
@ -839,11 +817,17 @@ meta_window_place (MetaWindow *window,
}
}
/* If no placement has been done, revert to cascade to avoid
* fully overlapping window (e.g. starting multiple terminals)
* */
if (x == xi->rect.x && y == xi->rect.y)
find_next_cascade (window, windows, x, y, &x, &y);
/* "Origin" placement algorithm */
x = xi->rect.x;
y = xi->rect.y;
if (find_first_fit (window, windows,
xi->number,
x, y, &x, &y))
goto done_check_denied_focus;
/* No good fit? Fall back to cascading... */
find_next_cascade (window, windows, x, y, &x, &y);
done_check_denied_focus:
/* If the window is being denied focus and isn't a transient of the
@ -886,11 +870,10 @@ meta_window_place (MetaWindow *window,
if (!found_fit)
find_most_freespace (window, focus_window, x, y, &x, &y);
}
done:
g_list_free (windows);
done_no_constraints:
if (windows)
g_list_free (windows);
*new_x = x;
*new_y = y;

View File

@ -2,9 +2,9 @@
/* Mutter window placement */
/*
/*
* Copyright (C) 2001 Havoc Pennington
*
*
* 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
@ -14,7 +14,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*/

View File

@ -1,6 +1,6 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
/*
* Copyright (C) 2001 Havoc Pennington, Copyright (C) 2002 Red Hat Inc.
* Copyright (C) 2006 Elijah Newren
* Copyright (C) 2008 Thomas Thurman
@ -15,7 +15,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*/
@ -55,6 +55,7 @@
#define KEY_GNOME_CURSOR_THEME "cursor-theme"
#define KEY_GNOME_CURSOR_SIZE "cursor-size"
#define KEY_XKB_OPTIONS "xkb-options"
#define KEY_XSETTINGS_OVERRIDES "overrides"
#define KEY_OVERLAY_KEY "overlay-key"
#define KEY_WORKSPACES_ONLY_ON_PRIMARY "workspaces-only-on-primary"
@ -65,6 +66,7 @@
#define SCHEMA_MUTTER "org.gnome.mutter"
#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 SETTINGS(s) g_hash_table_lookup (settings_schemas, (s))
@ -104,6 +106,7 @@ static gboolean edge_tiling = FALSE;
static gboolean force_fullscreen = TRUE;
static gboolean ignore_request_hide_titlebar = FALSE;
static gboolean auto_maximize = TRUE;
static gboolean show_fallback_app_menu = FALSE;
static GDesktopVisualBellType visual_bell_type = G_DESKTOP_VISUAL_BELL_FULLSCREEN_FLASH;
static MetaButtonLayout button_layout;
@ -129,6 +132,10 @@ static void bindings_changed (GSettings *settings,
gchar *key,
gpointer data);
static void xsettings_overrides_changed (GSettings *settings,
gchar *key,
gpointer data);
static void queue_changed (MetaPreference pref);
static void maybe_give_disable_workarounds_warning (void);
@ -615,7 +622,7 @@ handle_preference_init_int (void)
{
MetaIntPreference *cursor = preferences_int;
while (cursor->base.key != NULL)
{
if (cursor->target)
@ -671,7 +678,7 @@ handle_preference_update_bool (GSettings *settings,
* store the current value away.
*/
old_value = *((gboolean *) cursor->target);
/* Now look it up... */
*((gboolean *) cursor->target) =
g_settings_get_boolean (SETTINGS (cursor->base.schema), key);
@ -802,7 +809,7 @@ handle_preference_update_int (GSettings *settings,
}
}
/****************************************************************************/
/* Listeners. */
/****************************************************************************/
@ -851,7 +858,7 @@ meta_prefs_remove_listener (MetaPrefsChangedFunc func,
return;
}
tmp = tmp->next;
}
@ -866,9 +873,9 @@ emit_changed (MetaPreference pref)
meta_topic (META_DEBUG_PREFS, "Notifying listeners that pref %s changed\n",
meta_preference_to_string (pref));
copy = g_list_copy (listeners);
tmp = copy;
while (tmp != NULL)
@ -890,24 +897,24 @@ changed_idle_handler (gpointer data)
GList *copy;
changed_idle = 0;
copy = g_list_copy (changes); /* reentrancy paranoia */
g_list_free (changes);
changes = NULL;
tmp = copy;
while (tmp != NULL)
{
MetaPreference pref = GPOINTER_TO_INT (tmp->data);
emit_changed (pref);
tmp = tmp->next;
}
g_list_free (copy);
return FALSE;
}
@ -915,7 +922,7 @@ static void
queue_changed (MetaPreference pref)
{
meta_topic (META_DEBUG_PREFS, "Queueing change of pref %s\n",
meta_preference_to_string (pref));
meta_preference_to_string (pref));
if (g_list_find (changes, GINT_TO_POINTER (pref)) == NULL)
changes = g_list_prepend (changes, GINT_TO_POINTER (pref));
@ -931,11 +938,29 @@ queue_changed (MetaPreference pref)
}
}
/****************************************************************************/
/* Initialisation. */
/****************************************************************************/
static GSettings *
get_xsettings_settings (void)
{
GSettings *settings = NULL;
GSettingsSchema *schema;
schema = g_settings_schema_source_lookup (g_settings_schema_source_get_default (),
SCHEMA_XSETTINGS, FALSE);
if (schema)
{
settings = g_settings_new_full (schema, NULL, NULL);
g_settings_schema_unref (schema);
}
return settings;
}
void
meta_prefs_init (void)
{
@ -965,6 +990,16 @@ meta_prefs_init (void)
G_CALLBACK (settings_changed), NULL);
g_hash_table_insert (settings_schemas, g_strdup (SCHEMA_INTERFACE), settings);
settings = get_xsettings_settings ();
if (settings)
{
g_signal_connect (settings, "changed::" KEY_XSETTINGS_OVERRIDES,
G_CALLBACK (xsettings_overrides_changed), NULL);
g_hash_table_insert (settings_schemas, g_strdup (SCHEMA_XSETTINGS), settings);
xsettings_overrides_changed (settings, KEY_XSETTINGS_OVERRIDES, NULL);
}
settings = g_settings_new (SCHEMA_INPUT_SOURCES);
g_signal_connect (settings, "changed::" KEY_XKB_OPTIONS,
G_CALLBACK (settings_changed), NULL);
@ -1117,7 +1152,7 @@ meta_prefs_override_preference_schema (const char *key, const char *schema)
do_override (overridden->key, overridden->new_schema);
}
/****************************************************************************/
/* Updates. */
/****************************************************************************/
@ -1184,6 +1219,38 @@ bindings_changed (GSettings *settings,
g_strfreev (strokes);
}
/* The fallback app menu should be enabled if either we are not
* showing the app menu (e.g. when using the default plugin) or
* with a corresponding XSettings override; we ignore the former
* and assume that we always show the app menu, not least
* because we rely on the compositor implementation to display
* the fallback ...
*/
static void
xsettings_overrides_changed (GSettings *settings,
gchar *key,
gpointer data)
{
GVariant *value;
GVariantDict overrides;
int shell_shows_app_menu = 1;
if (!g_settings_get_boolean (settings, "active"))
goto out;
value = g_settings_get_value (settings, KEY_XSETTINGS_OVERRIDES);
g_variant_dict_init (&overrides, value);
g_variant_unref (value);
g_variant_dict_lookup (&overrides,
"Gtk/ShellShowsAppMenu", "i", &shell_shows_app_menu);
g_variant_dict_clear (&overrides);
out:
show_fallback_app_menu = !shell_shows_app_menu;
}
/**
* maybe_give_disable_workaround_warning:
*
@ -1194,7 +1261,7 @@ static void
maybe_give_disable_workarounds_warning (void)
{
static gboolean first_disable = TRUE;
if (first_disable && disable_workarounds)
{
first_disable = FALSE;
@ -1243,6 +1310,12 @@ meta_prefs_get_raise_on_click (void)
return raise_on_click || focus_mode == G_DESKTOP_FOCUS_MODE_CLICK;
}
gboolean
meta_prefs_get_show_fallback_app_menu (void)
{
return show_fallback_app_menu;
}
const char*
meta_prefs_get_theme (void)
{
@ -1261,7 +1334,7 @@ meta_prefs_get_cursor_size (void)
return cursor_size;
}
/****************************************************************************/
/* Handlers for string preferences. */
/****************************************************************************/
@ -1345,7 +1418,7 @@ mouse_button_mods_handler (GVariant *value,
{
meta_topic (META_DEBUG_KEYBINDINGS,
"Failed to parse new GSettings value\n");
meta_warning ("\"%s\" found in configuration database is "
"not a valid value for mouse button modifier\n",
string_value);
@ -1369,7 +1442,7 @@ mouse_button_mods_handler (GVariant *value,
static gboolean
button_layout_equal (const MetaButtonLayout *a,
const MetaButtonLayout *b)
{
{
int i;
i = 0;
@ -1398,6 +1471,8 @@ button_function_from_string (const char *str)
{
if (strcmp (str, "menu") == 0)
return META_BUTTON_FUNCTION_MENU;
else if (strcmp (str, "appmenu") == 0)
return META_BUTTON_FUNCTION_APPMENU;
else if (strcmp (str, "minimize") == 0)
return META_BUTTON_FUNCTION_MINIMIZE;
else if (strcmp (str, "maximize") == 0)
@ -1410,7 +1485,7 @@ button_function_from_string (const char *str)
return META_BUTTON_FUNCTION_ABOVE;
else if (strcmp (str, "stick") == 0)
return META_BUTTON_FUNCTION_STICK;
else
else
/* don't know; give up */
return META_BUTTON_FUNCTION_LAST;
}
@ -1535,7 +1610,7 @@ button_layout_handler (GVariant *value,
new_layout.right_buttons_has_spacer[i] = FALSE;
++i;
}
buttons = g_strsplit (sides[1], ",", -1);
i = 0;
b = 0;
@ -1571,7 +1646,7 @@ button_layout_handler (GVariant *value,
buttons[b]);
}
}
++b;
}
@ -1585,13 +1660,13 @@ 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;
for (i = 0; new_layout.left_buttons[i] != META_BUTTON_FUNCTION_LAST; i++);
for (j = 0; j < i; j++)
{
@ -1606,7 +1681,7 @@ button_layout_handler (GVariant *value,
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++)
{
@ -1751,7 +1826,7 @@ meta_preference_to_string (MetaPreference pref)
case META_PREF_RAISE_ON_CLICK:
return "RAISE_ON_CLICK";
case META_PREF_THEME:
return "THEME";
@ -1778,7 +1853,7 @@ meta_preference_to_string (MetaPreference pref)
case META_PREF_AUTO_RAISE:
return "AUTO_RAISE";
case META_PREF_AUTO_RAISE_DELAY:
return "AUTO_RAISE_DELAY";
@ -2021,7 +2096,7 @@ meta_prefs_change_workspace_name (int num,
{
GVariantBuilder builder;
int n_workspace_names, i;
g_return_if_fail (num >= 0);
meta_topic (META_DEBUG_PREFS,
@ -2181,7 +2256,7 @@ meta_prefs_get_keybindings ()
return g_hash_table_get_values (key_bindings);
}
void
void
meta_prefs_get_overlay_binding (MetaKeyCombo *combo)
{
*combo = overlay_key_combo;
@ -2262,43 +2337,6 @@ meta_prefs_get_keybinding_action (const char *name)
: META_KEYBINDING_ACTION_NONE;
}
/* This is used by the menu system to decide what key binding
* to display next to an option. We return the first non-disabled
* binding, if any.
*/
void
meta_prefs_get_window_binding (const char *name,
unsigned int *keysym,
MetaVirtualModifier *modifiers)
{
MetaKeyPref *pref = g_hash_table_lookup (key_bindings, name);
if (pref->per_window)
{
GSList *s = pref->combos;
while (s)
{
MetaKeyCombo *c = s->data;
if (c->keysym != 0 || c->modifiers != 0)
{
*keysym = c->keysym;
*modifiers = c->modifiers;
return;
}
s = s->next;
}
/* Not found; return the disabled value */
*keysym = *modifiers = 0;
return;
}
g_assert_not_reached ();
}
gint
meta_prefs_get_mouse_button_resize (void)
{

View File

@ -9,11 +9,11 @@
* which the rest of the world is allowed to use.)
*/
/*
/*
* Copyright (C) 2001 Havoc Pennington
* Copyright (C) 2003 Rob Adams
* Copyright (C) 2004-2006 Elijah Newren
*
*
* 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
@ -23,7 +23,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*/
@ -73,7 +73,7 @@ struct _MetaScreen
* any actual clients
*/
Window no_focus_window;
GList *workspaces;
MetaStack *stack;
@ -110,11 +110,11 @@ struct _MetaScreen
MetaScreenCorner starting_corner;
guint vertical_workspaces : 1;
guint workspace_layout_overridden : 1;
guint keys_grabbed : 1;
int closing;
/* Instead of unmapping withdrawn windows we can leave them mapped
* and restack them below a guard window. When using a compositor
* this allows us to provide live previews of unmapped windows */

View File

@ -1,13 +1,13 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
/*
* Copyright (C) 2001, 2002 Havoc Pennington
* Copyright (C) 2002, 2003 Red Hat Inc.
* Some ICCCM manager selection code derived from fvwm2,
* Copyright (C) 2001 Dominik Vogt, Matthias Clasen, and fvwm2 team
* Copyright (C) 2003 Rob Adams
* Copyright (C) 2004-2006 Elijah Newren
*
*
* 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
@ -17,7 +17,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*/
@ -52,6 +52,7 @@
#include <stdio.h>
#include <stdlib.h>
#include "x11/window-x11.h"
#include "x11/xprops.h"
static char* get_screen_name (MetaDisplay *display,
@ -267,7 +268,7 @@ set_wm_check_hint (MetaScreen *screen)
unsigned long data[1];
g_return_val_if_fail (screen->display->leader_window != None, 0);
data[0] = screen->display->leader_window;
XChangeProperty (screen->display->xdisplay, screen->xroot,
@ -281,7 +282,7 @@ set_wm_check_hint (MetaScreen *screen)
static void
unset_wm_check_hint (MetaScreen *screen)
{
XDeleteProperty (screen->display->xdisplay, screen->xroot,
XDeleteProperty (screen->display->xdisplay, screen->xroot,
screen->display->atom__NET_SUPPORTING_WM_CHECK);
}
@ -296,6 +297,7 @@ set_supported_hint (MetaScreen *screen)
#undef EWMH_ATOMS_ONLY
screen->display->atom__GTK_FRAME_EXTENTS,
screen->display->atom__GTK_SHOW_WINDOW_MENU,
};
XChangeProperty (screen->display->xdisplay, screen->xroot,
@ -303,7 +305,7 @@ set_supported_hint (MetaScreen *screen)
XA_ATOM,
32, PropModeReplace,
(guchar*) atoms, G_N_ELEMENTS(atoms));
return Success;
}
@ -327,12 +329,12 @@ set_wm_icon_size_hint (MetaScreen *screen)
vals[4] = 0;
vals[5] = 0;
#undef LEGACY_ICON_SIZE
XChangeProperty (screen->display->xdisplay, screen->xroot,
screen->display->atom_WM_ICON_SIZE,
XA_CARDINAL,
32, PropModeReplace, (guchar*) vals, N_VALS);
return Success;
#undef N_VALS
}
@ -411,7 +413,7 @@ reload_monitor_infos (MetaScreen *screen)
MetaWorkspace *space = tmp->data;
meta_workspace_invalidate_work_area (space);
tmp = tmp->next;
}
@ -506,16 +508,16 @@ meta_screen_new (MetaDisplay *display,
guint32 manager_timestamp;
gulong current_workspace;
MetaMonitorManager *manager;
replace_current_wm = meta_get_replace_current_wm ();
/* Only display->name, display->xdisplay, and display->error_traps
* can really be used in this function, since normally screens are
* created from the MetaDisplay constructor
*/
xdisplay = display->xdisplay;
meta_verbose ("Trying screen %d on display '%s'\n",
number, display->name);
@ -532,14 +534,14 @@ meta_screen_new (MetaDisplay *display,
}
sprintf (buf, "WM_S%d", number);
wm_sn_atom = XInternAtom (xdisplay, buf, False);
wm_sn_atom = XInternAtom (xdisplay, buf, False);
current_wm_sn_owner = XGetSelectionOwner (xdisplay, wm_sn_atom);
if (current_wm_sn_owner != None)
{
XSetWindowAttributes attrs;
if (!replace_current_wm)
{
meta_warning (_("Screen %d on display \"%s\" already has a window manager; try using the --replace option to replace the current window manager.\n"),
@ -563,7 +565,7 @@ meta_screen_new (MetaDisplay *display,
new_wm_sn_owner = meta_create_offscreen_window (xdisplay, xroot, NoEventMask);
manager_timestamp = timestamp;
XSetSelectionOwner (xdisplay, wm_sn_atom, new_wm_sn_owner,
manager_timestamp);
@ -573,14 +575,14 @@ meta_screen_new (MetaDisplay *display,
number, display->name);
XDestroyWindow (xdisplay, new_wm_sn_owner);
return NULL;
}
{
/* Send client message indicating that we are now the WM */
XClientMessageEvent ev;
ev.type = ClientMessage;
ev.window = xroot;
ev.message_type = display->atom_MANAGER;
@ -597,7 +599,7 @@ meta_screen_new (MetaDisplay *display,
XEvent event;
/* We sort of block infinitely here which is probably lame. */
meta_verbose ("Waiting for old window manager to exit\n");
do
{
@ -606,7 +608,7 @@ meta_screen_new (MetaDisplay *display,
}
while (event.type != DestroyNotify);
}
/* select our root window events */
meta_error_trap_push (display);
@ -651,13 +653,13 @@ meta_screen_new (MetaDisplay *display,
number, display->name);
XDestroyWindow (xdisplay, new_wm_sn_owner);
return NULL;
}
screen = g_object_new (META_TYPE_SCREEN, NULL);
screen->closing = 0;
screen->display = display;
screen->number = number;
screen->screen_name = get_screen_name (display, number);
@ -681,8 +683,8 @@ meta_screen_new (MetaDisplay *display,
screen->wm_sn_atom = wm_sn_atom;
screen->wm_sn_timestamp = manager_timestamp;
screen->wm_cm_selection_window = meta_create_offscreen_window (xdisplay,
xroot,
screen->wm_cm_selection_window = meta_create_offscreen_window (xdisplay,
xroot,
NoEventMask);
screen->work_area_later = 0;
screen->check_fullscreen_later = 0;
@ -699,18 +701,18 @@ meta_screen_new (MetaDisplay *display,
meta_screen_set_cursor (screen, META_CURSOR_DEFAULT);
/* Handle creating a no_focus_window for this screen */
/* Handle creating a no_focus_window for this screen */
screen->no_focus_window =
meta_create_offscreen_window (display->xdisplay,
screen->xroot,
FocusChangeMask|KeyPressMask|KeyReleaseMask);
XMapWindow (display->xdisplay, screen->no_focus_window);
/* Done with no_focus_window stuff */
set_wm_icon_size_hint (screen);
set_supported_hint (screen);
set_wm_check_hint (screen);
set_desktop_viewport_hint (screen);
@ -729,13 +731,13 @@ meta_screen_new (MetaDisplay *display,
(int) current_workspace);
else
meta_verbose ("No _NET_CURRENT_DESKTOP present\n");
/* Screens must have at least one workspace at all times,
* so create that required workspace.
*/
meta_workspace_activate (meta_workspace_new (screen), timestamp);
update_num_workspaces (screen, timestamp);
set_workspace_names (screen);
screen->keys_grabbed = FALSE;
@ -765,10 +767,10 @@ meta_screen_new (MetaDisplay *display,
/* Switch to the _NET_CURRENT_DESKTOP workspace */
{
MetaWorkspace *space;
space = meta_screen_get_workspace_by_index (screen,
current_workspace);
if (space != NULL)
meta_workspace_activate (space, timestamp);
}
@ -788,15 +790,15 @@ meta_screen_free (MetaScreen *screen,
display = screen->display;
screen->closing += 1;
meta_display_grab (display);
meta_compositor_unmanage (screen->display->compositor);
meta_display_unmanage_windows_for_screen (display, screen, timestamp);
meta_prefs_remove_listener (prefs_changed_callback, screen);
meta_screen_ungrab_keys (screen);
#ifdef HAVE_STARTUP_NOTIFICATION
@ -816,7 +818,7 @@ meta_screen_free (MetaScreen *screen,
screen->sn_context = NULL;
}
#endif
meta_ui_free (screen->ui);
meta_stack_free (screen->stack);
@ -832,7 +834,7 @@ meta_screen_free (MetaScreen *screen,
XDestroyWindow (screen->display->xdisplay,
screen->wm_sn_selection_window);
if (screen->work_area_later != 0)
meta_later_remove (screen->work_area_later);
if (screen->check_fullscreen_later != 0)
@ -887,7 +889,7 @@ prefs_changed_callback (MetaPreference pref,
gpointer data)
{
MetaScreen *screen = data;
if ((pref == META_PREF_NUM_WORKSPACES ||
pref == META_PREF_DYNAMIC_WORKSPACES) &&
!meta_prefs_get_dynamic_workspaces ())
@ -895,7 +897,7 @@ prefs_changed_callback (MetaPreference pref,
/* GSettings doesn't provide timestamps, but luckily update_num_workspaces
* often doesn't need it...
*/
guint32 timestamp =
guint32 timestamp =
meta_display_get_current_time_roundtrip (screen->display);
update_num_workspaces (screen, timestamp);
}
@ -917,7 +919,7 @@ get_screen_name (MetaDisplay *display,
char *p;
char *dname;
char *scr;
/* DisplayString gives us a sort of canonical display,
* vs. the user-entered name from XDisplayName()
*/
@ -932,7 +934,7 @@ get_screen_name (MetaDisplay *display,
if (p)
*p = '\0';
}
scr = g_strdup_printf ("%s.%d", dname, number);
g_free (dname);
@ -955,7 +957,7 @@ static void
listify_func (gpointer key, gpointer value, gpointer data)
{
GSList **listp;
listp = data;
*listp = g_slist_prepend (*listp, value);
@ -981,14 +983,14 @@ meta_screen_foreach_window (MetaScreen *screen,
/* If we end up doing this often, just keeping a list
* of windows might be sensible.
*/
winlist = NULL;
g_hash_table_foreach (screen->display->xids,
listify_func,
&winlist);
winlist = g_slist_sort (winlist, ptrcmp);
tmp = winlist;
while (tmp != NULL)
{
@ -1005,7 +1007,7 @@ meta_screen_foreach_window (MetaScreen *screen,
!window->override_redirect)
(* func) (screen, window, data);
}
tmp = tmp->next;
}
g_slist_free (winlist);
@ -1039,7 +1041,7 @@ meta_screen_get_workspace_by_index (MetaScreen *screen,
/* should be robust, idx is maybe from an app */
if (idx < 0)
return NULL;
i = 0;
tmp = screen->workspaces;
while (tmp != NULL)
@ -1258,7 +1260,7 @@ update_num_workspaces (MetaScreen *screen,
GList *extras;
MetaWorkspace *last_remaining;
gboolean need_change_space;
if (meta_prefs_get_dynamic_workspaces ())
{
int n_items;
@ -1301,14 +1303,14 @@ update_num_workspaces (MetaScreen *screen,
extras = g_list_prepend (extras, w);
else
last_remaining = w;
++i;
tmp = tmp->next;
}
old_num = i;
g_assert (last_remaining);
/* Get rid of the extra workspaces by moving all their windows
* to last_remaining, then activating last_remaining if
* one of the removed workspaces was active. This will be a bit
@ -1321,11 +1323,11 @@ update_num_workspaces (MetaScreen *screen,
{
MetaWorkspace *w = tmp->data;
meta_workspace_relocate_windows (w, last_remaining);
meta_workspace_relocate_windows (w, last_remaining);
if (w == screen->active_workspace)
need_change_space = TRUE;
tmp = tmp->next;
}
@ -1551,7 +1553,7 @@ meta_screen_get_monitor_for_window (MetaScreen *screen,
MetaWindow *window)
{
MetaRectangle window_rect;
meta_window_get_frame_rect (window, &window_rect);
return meta_screen_get_monitor_for_rect (screen, &window_rect);
@ -1565,7 +1567,7 @@ meta_screen_get_monitor_index_for_rect (MetaScreen *screen,
return monitor->number;
}
const MetaMonitorInfo*
const MetaMonitorInfo*
meta_screen_get_monitor_neighbor (MetaScreen *screen,
int which_monitor,
MetaScreenDirection direction)
@ -1578,23 +1580,23 @@ meta_screen_get_monitor_neighbor (MetaScreen *screen,
{
current = screen->monitor_infos + i;
if ((direction == META_SCREEN_RIGHT &&
if ((direction == META_SCREEN_RIGHT &&
current->rect.x == input->rect.x + input->rect.width &&
meta_rectangle_vert_overlap(&current->rect, &input->rect)) ||
(direction == META_SCREEN_LEFT &&
(direction == META_SCREEN_LEFT &&
input->rect.x == current->rect.x + current->rect.width &&
meta_rectangle_vert_overlap(&current->rect, &input->rect)) ||
(direction == META_SCREEN_UP &&
(direction == META_SCREEN_UP &&
input->rect.y == current->rect.y + current->rect.height &&
meta_rectangle_horiz_overlap(&current->rect, &input->rect)) ||
(direction == META_SCREEN_DOWN &&
(direction == META_SCREEN_DOWN &&
current->rect.y == input->rect.y + input->rect.height &&
meta_rectangle_horiz_overlap(&current->rect, &input->rect)))
{
return current;
}
}
return NULL;
}
@ -1634,7 +1636,7 @@ meta_screen_get_natural_monitor_list (MetaScreen *screen,
while (!g_queue_is_empty (monitor_queue))
{
current = (const MetaMonitorInfo*)
current = (const MetaMonitorInfo*)
g_queue_pop_head (monitor_queue);
(*monitors_list)[cur++] = current->number;
@ -1775,10 +1777,10 @@ meta_screen_get_current_monitor (MetaScreen *screen)
if (screen->n_monitor_infos == 1)
return 0;
/* Sadly, we have to do it this way. Yuck.
*/
if (screen->display->monitor_cache_invalidated)
{
int x, y;
@ -1858,7 +1860,7 @@ meta_screen_update_workspace_layout (MetaScreen *screen)
if (screen->workspace_layout_overridden)
return;
list = NULL;
n_items = 0;
@ -1870,7 +1872,7 @@ meta_screen_update_workspace_layout (MetaScreen *screen)
if (n_items == 3 || n_items == 4)
{
int cols, rows;
switch (list[0])
{
case _NET_WM_ORIENTATION_HORZ:
@ -1897,7 +1899,7 @@ meta_screen_update_workspace_layout (MetaScreen *screen)
screen->rows_of_workspaces = rows;
else
screen->rows_of_workspaces = -1;
if (cols > 0)
screen->columns_of_workspaces = cols;
else
@ -2007,10 +2009,10 @@ set_workspace_names (MetaScreen *screen)
strlen (name) + 1);
else
g_string_append_len (flattened, "", 1);
++i;
}
meta_error_trap_push (screen->display);
XChangeProperty (screen->display->xdisplay,
screen->xroot,
@ -2019,7 +2021,7 @@ set_workspace_names (MetaScreen *screen)
8, PropModeReplace,
(unsigned char *)flattened->str, flattened->len);
meta_error_trap_pop (screen->display);
g_string_free (flattened, TRUE);
}
@ -2033,7 +2035,7 @@ meta_screen_update_workspace_names (MetaScreen *screen)
/* this updates names in prefs when the root window property changes,
* iff the new property contents don't match what's already in prefs
*/
names = NULL;
n_names = 0;
if (!meta_prop_get_utf8_list (screen->display,
@ -2053,10 +2055,10 @@ meta_screen_update_workspace_names (MetaScreen *screen)
"Setting workspace %d name to \"%s\" due to _NET_DESKTOP_NAMES change\n",
i, names[i] ? names[i] : "null");
meta_prefs_change_workspace_name (i, names[i]);
++i;
}
g_strfreev (names);
}
@ -2073,7 +2075,7 @@ meta_create_offscreen_window (Display *xdisplay,
*/
attrs.override_redirect = True;
attrs.event_mask = valuemask;
return XCreateWindow (xdisplay,
parent,
-100, -100, 1, 1,
@ -2092,12 +2094,12 @@ set_work_area_hint (MetaScreen *screen)
GList *tmp_list;
unsigned long *data, *tmp;
MetaRectangle area;
num_workspaces = meta_screen_get_n_workspaces (screen);
data = g_new (unsigned long, num_workspaces * 4);
tmp_list = screen->workspaces;
tmp = data;
while (tmp_list != NULL)
{
MetaWorkspace *workspace = tmp_list->data;
@ -2112,10 +2114,10 @@ set_work_area_hint (MetaScreen *screen)
tmp += 4;
}
tmp_list = tmp_list->next;
}
meta_error_trap_push (screen->display);
XChangeProperty (screen->display->xdisplay, screen->xroot,
screen->display->atom__NET_WORKAREA,
@ -2132,11 +2134,11 @@ set_work_area_later_func (MetaScreen *screen)
{
meta_topic (META_DEBUG_WORKAREA,
"Running work area hint computation function\n");
screen->work_area_later = 0;
set_work_area_hint (screen);
return FALSE;
}
@ -2188,7 +2190,7 @@ meta_screen_calc_workspace_layout (MetaScreen *screen,
int *grid;
int i, r, c;
int current_row, current_col;
rows = screen->rows_of_workspaces;
cols = screen->columns_of_workspaces;
if (rows <= 0 && cols <= 0)
@ -2206,58 +2208,58 @@ meta_screen_calc_workspace_layout (MetaScreen *screen,
cols = 1;
g_assert (rows != 0 && cols != 0);
grid_area = rows * cols;
meta_verbose ("Getting layout rows = %d cols = %d current = %d "
"num_spaces = %d vertical = %s corner = %s\n",
rows, cols, current_space, num_workspaces,
screen->vertical_workspaces ? "(true)" : "(false)",
meta_screen_corner_to_string (screen->starting_corner));
/* ok, we want to setup the distances in the workspace array to go
* in each direction. Remember, there are many ways that a workspace
* array can be setup.
* see http://www.freedesktop.org/standards/wm-spec/1.2/html/x109.html
* and look at the _NET_DESKTOP_LAYOUT section for details.
/* ok, we want to setup the distances in the workspace array to go
* in each direction. Remember, there are many ways that a workspace
* array can be setup.
* see http://www.freedesktop.org/standards/wm-spec/1.2/html/x109.html
* and look at the _NET_DESKTOP_LAYOUT section for details.
* For instance:
*/
/* starting_corner = META_SCREEN_TOPLEFT
/* starting_corner = META_SCREEN_TOPLEFT
* vertical_workspaces = 0 vertical_workspaces=1
* 1234 1357
* 5678 2468
*
* starting_corner = META_SCREEN_TOPRIGHT
* 1234 1357
* 5678 2468
*
* starting_corner = META_SCREEN_TOPRIGHT
* vertical_workspaces = 0 vertical_workspaces=1
* 4321 7531
* 8765 8642
*
* starting_corner = META_SCREEN_BOTTOMLEFT
* 4321 7531
* 8765 8642
*
* starting_corner = META_SCREEN_BOTTOMLEFT
* vertical_workspaces = 0 vertical_workspaces=1
* 5678 2468
* 1234 1357
*
* starting_corner = META_SCREEN_BOTTOMRIGHT
* 5678 2468
* 1234 1357
*
* starting_corner = META_SCREEN_BOTTOMRIGHT
* vertical_workspaces = 0 vertical_workspaces=1
* 8765 8642
* 4321 7531
* 8765 8642
* 4321 7531
*
*/
/* keep in mind that we could have a ragged layout, e.g. the "8"
* in the above grids could be missing
*/
grid = g_new (int, grid_area);
current_row = -1;
current_col = -1;
i = 0;
switch (screen->starting_corner)
switch (screen->starting_corner)
{
case META_SCREEN_TOPLEFT:
if (screen->vertical_workspaces)
if (screen->vertical_workspaces)
{
c = 0;
while (c < cols)
@ -2289,7 +2291,7 @@ meta_screen_calc_workspace_layout (MetaScreen *screen,
}
break;
case META_SCREEN_TOPRIGHT:
if (screen->vertical_workspaces)
if (screen->vertical_workspaces)
{
c = cols - 1;
while (c >= 0)
@ -2321,7 +2323,7 @@ meta_screen_calc_workspace_layout (MetaScreen *screen,
}
break;
case META_SCREEN_BOTTOMLEFT:
if (screen->vertical_workspaces)
if (screen->vertical_workspaces)
{
c = 0;
while (c < cols)
@ -2353,7 +2355,7 @@ meta_screen_calc_workspace_layout (MetaScreen *screen,
}
break;
case META_SCREEN_BOTTOMRIGHT:
if (screen->vertical_workspaces)
if (screen->vertical_workspaces)
{
c = cols - 1;
while (c >= 0)
@ -2384,12 +2386,12 @@ meta_screen_calc_workspace_layout (MetaScreen *screen,
}
}
break;
}
}
if (i != grid_area)
meta_bug ("did not fill in the whole workspace grid in %s (%d filled)\n",
G_STRFUNC, i);
current_row = 0;
current_col = 0;
r = 0;
@ -2525,7 +2527,7 @@ meta_screen_update_showing_desktop_hint (MetaScreen *screen)
unsigned long data[1];
data[0] = screen->active_workspace->showing_desktop ? 1 : 0;
meta_error_trap_push (screen->display);
XChangeProperty (screen->display->xdisplay, screen->xroot,
screen->display->atom__NET_SHOWING_DESKTOP,
@ -2553,7 +2555,7 @@ queue_windows_showing (MetaScreen *screen)
if (w->screen == screen)
meta_window_queue (w, META_QUEUE_CALC_SHOWING);
tmp = tmp->next;
}
@ -2568,32 +2570,32 @@ meta_screen_minimize_all_on_active_workspace_except (MetaScreen *screen,
GList *tmp;
windows = screen->active_workspace->windows;
tmp = windows;
while (tmp != NULL)
{
MetaWindow *w = tmp->data;
if (w->screen == screen &&
w->has_minimize_func &&
w != keep)
meta_window_minimize (w);
tmp = tmp->next;
}
}
void
meta_screen_show_desktop (MetaScreen *screen,
meta_screen_show_desktop (MetaScreen *screen,
guint32 timestamp)
{
GList *windows;
if (screen->active_workspace->showing_desktop)
return;
screen->active_workspace->showing_desktop = TRUE;
queue_windows_showing (screen);
/* Focus the most recently used META_WINDOW_DESKTOP window, if there is one;
@ -2603,18 +2605,18 @@ meta_screen_show_desktop (MetaScreen *screen,
while (windows != NULL)
{
MetaWindow *w = windows->data;
if (w->screen == screen &&
if (w->screen == screen &&
w->type == META_WINDOW_DESKTOP)
{
meta_window_focus (w, timestamp);
break;
}
windows = windows->next;
}
meta_screen_update_showing_desktop_hint (screen);
}
@ -2685,7 +2687,7 @@ remove_sequence (MetaScreen *screen,
meta_topic (META_DEBUG_STARTUP,
"Removing sequence %s\n",
sn_startup_sequence_get_id (sequence));
screen->startup_sequences = g_slist_remove (screen->startup_sequences,
sequence);
@ -2722,7 +2724,7 @@ collect_timed_out_foreach (void *element,
SnStartupSequence *sequence = element;
long tv_sec, tv_usec;
double elapsed;
sn_startup_sequence_get_last_active_time (sequence, &tv_sec, &tv_usec);
elapsed =
@ -2733,7 +2735,7 @@ collect_timed_out_foreach (void *element,
"Sequence used %g seconds vs. %g max: %s\n",
elapsed, (double) STARTUP_TIMEOUT,
sn_startup_sequence_get_id (sequence));
if (elapsed > STARTUP_TIMEOUT)
ctod->list = g_slist_prepend (ctod->list, sequence);
}
@ -2744,7 +2746,7 @@ startup_sequence_timeout (void *data)
MetaScreen *screen = data;
CollectTimedOutData ctod;
GSList *tmp;
ctod.list = NULL;
g_get_current_time (&ctod.now);
g_slist_foreach (screen->startup_sequences,
@ -2759,14 +2761,14 @@ startup_sequence_timeout (void *data)
meta_topic (META_DEBUG_STARTUP,
"Timed out sequence %s\n",
sn_startup_sequence_get_id (sequence));
sn_startup_sequence_complete (sequence);
tmp = tmp->next;
}
g_slist_free (ctod.list);
if (screen->startup_sequences != NULL)
{
return TRUE;
@ -2785,7 +2787,7 @@ meta_screen_sn_event (SnMonitorEvent *event,
{
MetaScreen *screen;
SnStartupSequence *sequence;
screen = user_data;
sequence = sn_monitor_event_get_startup_sequence (event);
@ -2799,7 +2801,7 @@ meta_screen_sn_event (SnMonitorEvent *event,
const char *wmclass;
wmclass = sn_startup_sequence_get_wmclass (sequence);
meta_topic (META_DEBUG_STARTUP,
"Received startup initiated for %s wmclass %s\n",
sn_startup_sequence_get_id (sequence),
@ -2865,7 +2867,7 @@ meta_screen_apply_startup_properties (MetaScreen *screen,
const char *startup_id;
GSList *tmp;
SnStartupSequence *sequence;
/* Does the window have a startup ID stored? */
startup_id = meta_window_get_startup_id (window);
@ -2873,7 +2875,7 @@ meta_screen_apply_startup_properties (MetaScreen *screen,
"Applying startup props to %s id \"%s\"\n",
window->desc,
startup_id ? startup_id : "(none)");
sequence = NULL;
if (startup_id == NULL)
{
@ -2904,11 +2906,11 @@ meta_screen_apply_startup_properties (MetaScreen *screen,
"Ending legacy sequence %s due to window %s\n",
sn_startup_sequence_get_id (sequence),
window->desc);
sn_startup_sequence_complete (sequence);
break;
}
tmp = tmp->next;
}
}
@ -2916,7 +2918,7 @@ meta_screen_apply_startup_properties (MetaScreen *screen,
/* Still no startup ID? Bail. */
if (startup_id == NULL)
return FALSE;
/* We might get this far and not know the sequence ID (if the window
* already had a startup ID stored), so let's look for one if we don't
* already know it.
@ -2927,15 +2929,15 @@ meta_screen_apply_startup_properties (MetaScreen *screen,
while (tmp != NULL)
{
const char *id;
id = sn_startup_sequence_get_id (tmp->data);
if (strcmp (id, startup_id) == 0)
{
sequence = tmp->data;
break;
}
tmp = tmp->next;
}
}
@ -2943,7 +2945,7 @@ meta_screen_apply_startup_properties (MetaScreen *screen,
if (sequence != NULL)
{
gboolean changed_something = FALSE;
meta_topic (META_DEBUG_STARTUP,
"Found startup sequence for window %s ID \"%s\"\n",
window->desc, startup_id);
@ -2956,7 +2958,7 @@ meta_screen_apply_startup_properties (MetaScreen *screen,
meta_topic (META_DEBUG_STARTUP,
"Setting initial window workspace to %d based on startup info\n",
space);
window->initial_workspace_set = TRUE;
window->initial_workspace = space;
changed_something = TRUE;
@ -2969,7 +2971,7 @@ meta_screen_apply_startup_properties (MetaScreen *screen,
meta_topic (META_DEBUG_STARTUP,
"Setting initial window timestamp to %u based on startup info\n",
timestamp);
window->initial_timestamp_set = TRUE;
window->initial_timestamp = timestamp;
changed_something = TRUE;
@ -2983,7 +2985,7 @@ meta_screen_apply_startup_properties (MetaScreen *screen,
"Did not find startup sequence for window %s ID \"%s\"\n",
window->desc, startup_id);
}
#endif /* HAVE_STARTUP_NOTIFICATION */
return FALSE;
@ -2998,10 +3000,10 @@ meta_screen_get_screen_number (MetaScreen *screen)
/**
* meta_screen_get_display:
* @screen: A #MetaScreen
*
*
* Retrieve the display associated with screen.
*
* Returns: (transfer none): Display
* Returns: (transfer none): Display
*/
MetaDisplay *
meta_screen_get_display (MetaScreen *screen)
@ -3028,7 +3030,7 @@ meta_screen_get_xroot (MetaScreen *screen)
*
* Retrieve the size of the screen.
*/
void
void
meta_screen_get_size (MetaScreen *screen,
int *width,
int *height)
@ -3052,7 +3054,7 @@ meta_screen_set_cm_selection (MetaScreen *screen)
g_snprintf (selection, sizeof(selection), "_NET_WM_CM_S%d", screen->number);
meta_verbose ("Setting selection: %s\n", selection);
a = XInternAtom (screen->display->xdisplay, selection, FALSE);
XSetSelectionOwner (screen->display->xdisplay, a,
XSetSelectionOwner (screen->display->xdisplay, a,
screen->wm_cm_selection_window, screen->wm_cm_timestamp);
}
@ -3141,11 +3143,11 @@ meta_screen_set_active_workspace_hint (MetaScreen *screen)
*/
if (screen->closing > 0)
return;
data[0] = meta_workspace_index (screen->active_workspace);
meta_verbose ("Setting _NET_CURRENT_DESKTOP to %lu\n", data[0]);
meta_error_trap_push (screen->display);
XChangeProperty (screen->display->xdisplay, screen->xroot,
screen->display->atom__NET_CURRENT_DESKTOP,

View File

@ -541,6 +541,8 @@ static void
stack_tracker_apply_prediction (MetaStackTracker *tracker,
MetaStackOp *op)
{
gboolean free_at_end = FALSE;
/* If this is a wayland operation then it's implicitly verified so
* we can apply it immediately so long as it doesn't depend on any
* unverified X operations...
@ -550,6 +552,8 @@ stack_tracker_apply_prediction (MetaStackTracker *tracker,
{
if (meta_stack_op_apply (op, tracker->verified_stack))
meta_stack_tracker_queue_sync_stack (tracker);
free_at_end = TRUE;
}
else
{
@ -561,6 +565,9 @@ stack_tracker_apply_prediction (MetaStackTracker *tracker,
meta_stack_op_apply (op, tracker->predicted_stack))
meta_stack_tracker_queue_sync_stack (tracker);
if (free_at_end)
meta_stack_op_free (op);
meta_stack_tracker_dump (tracker);
}
@ -895,7 +902,10 @@ resync_verified_stack_with_xserver_stack (MetaStackTracker *tracker)
requery_xserver_stack (tracker);
for (l = tracker->unverified_predictions->head; l; l = l->next)
meta_stack_op_apply (l->data, tracker->verified_stack);
{
meta_stack_op_apply (l->data, tracker->verified_stack);
meta_stack_op_free (l->data);
}
g_queue_clear (tracker->unverified_predictions);
j = 0;
@ -921,7 +931,7 @@ resync_verified_stack_with_xserver_stack (MetaStackTracker *tracker)
MetaStackWindow new;
MetaStackWindow *expected;
int expected_index;
/* If the current window corresponds to a window that's not
* in xserver_stack any more then the least disruptive thing
* we can do is to simply remove it and take another look at

View File

@ -5,12 +5,12 @@
* @short_description: Which windows cover which other windows
*/
/*
/*
* Copyright (C) 2001 Havoc Pennington
* Copyright (C) 2002, 2003 Red Hat, Inc.
* Copyright (C) 2004 Rob Adams
* Copyright (C) 2004, 2005 Elijah Newren
*
*
* 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
@ -20,7 +20,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*/
@ -67,7 +67,7 @@ MetaStack*
meta_stack_new (MetaScreen *screen)
{
MetaStack *stack;
stack = g_new (MetaStack, 1);
stack->screen = screen;
@ -85,7 +85,7 @@ meta_stack_new (MetaScreen *screen)
stack->need_resort = FALSE;
stack->need_relayer = FALSE;
stack->need_constrain = FALSE;
return stack;
}
@ -107,7 +107,7 @@ meta_stack_free (MetaStack *stack)
if (stack->last_all_root_children_stacked)
free_last_all_root_children_stacked_cache (stack);
g_free (stack);
}
@ -119,7 +119,7 @@ meta_stack_add (MetaStack *stack,
if (window->stack_position >= 0)
meta_bug ("Window %s had stack position already\n", window->desc);
stack->added = g_list_prepend (stack->added, window);
window->stack_position = stack->n_positions;
@ -127,7 +127,7 @@ meta_stack_add (MetaStack *stack,
meta_topic (META_DEBUG_STACK,
"Window %s has stack_position initialized to %d\n",
window->desc, window->stack_position);
stack_sync_to_xserver (stack);
meta_stack_update_window_tile_matches (stack, window->screen->active_workspace);
}
@ -148,7 +148,7 @@ meta_stack_remove (MetaStack *stack,
meta_window_set_stack_position_no_sync (window,
stack->n_positions - 1);
window->stack_position = -1;
stack->n_positions -= 1;
stack->n_positions -= 1;
/* We don't know if it's been moved from "added" to "stack" yet */
stack->added = g_list_remove (stack->added, window);
@ -163,7 +163,7 @@ meta_stack_remove (MetaStack *stack,
if (window->frame)
stack->removed = g_list_prepend (stack->removed,
GUINT_TO_POINTER (window->frame->xwindow));
stack_sync_to_xserver (stack);
meta_stack_update_window_tile_matches (stack, window->screen->active_workspace);
}
@ -173,7 +173,7 @@ meta_stack_update_layer (MetaStack *stack,
MetaWindow *window)
{
stack->need_relayer = TRUE;
stack_sync_to_xserver (stack);
meta_stack_update_window_tile_matches (stack, window->screen->active_workspace);
}
@ -183,7 +183,7 @@ meta_stack_update_transient (MetaStack *stack,
MetaWindow *window)
{
stack->need_constrain = TRUE;
stack_sync_to_xserver (stack);
meta_stack_update_window_tile_matches (stack, window->screen->active_workspace);
}
@ -240,7 +240,7 @@ meta_stack_lower (MetaStack *stack,
return;
meta_window_set_stack_position_no_sync (window, min_stack_position);
stack_sync_to_xserver (stack);
meta_stack_update_window_tile_matches (stack, window->screen->active_workspace);
}
@ -255,7 +255,7 @@ void
meta_stack_thaw (MetaStack *stack)
{
g_return_if_fail (stack->freeze_count > 0);
stack->freeze_count -= 1;
stack_sync_to_xserver (stack);
meta_stack_update_window_tile_matches (stack, NULL);
@ -333,7 +333,7 @@ get_standalone_layer (MetaWindow *window)
case META_WINDOW_OVERRIDE_OTHER:
layer = META_LAYER_OVERRIDE_REDIRECT;
break;
default:
default:
meta_window_foreach_transient (window,
is_focused_foreach,
&focused_transient);
@ -369,16 +369,16 @@ get_maximum_layer_in_group (MetaWindow *window)
GSList *tmp;
MetaStackLayer max;
MetaStackLayer layer;
max = META_LAYER_DESKTOP;
group = meta_window_get_group (window);
if (group != NULL)
members = meta_group_list_windows (group);
else
members = NULL;
tmp = members;
while (tmp != NULL)
{
@ -390,12 +390,12 @@ get_maximum_layer_in_group (MetaWindow *window)
if (layer > max)
max = layer;
}
tmp = tmp->next;
}
g_slist_free (members);
return max;
}
@ -405,7 +405,7 @@ compute_layer (MetaWindow *window)
MetaStackLayer old_layer = window->layer;
window->layer = get_standalone_layer (window);
/* We can only do promotion-due-to-group for dialogs and other
* transients, or weird stuff happens like the desktop window and
* nautilus windows getting in the same layer, or all gnome-terminal
@ -422,11 +422,11 @@ compute_layer (MetaWindow *window)
* and a dialog transient for the normal window; you don't want the dialog
* above the dock if it wouldn't normally be.
*/
MetaStackLayer group_max;
group_max = get_maximum_layer_in_group (window);
if (group_max > window->layer)
{
meta_topic (META_DEBUG_STACK,
@ -467,10 +467,10 @@ compare_window_position (void *a,
else
return 0; /* not reached */
}
/*
* Stacking constraints
*
*
* Assume constraints of the form "AB" meaning "window A must be
* below window B"
*
@ -487,14 +487,14 @@ compare_window_position (void *a,
* apply BC: ABC
*
* but apply constraints in the wrong order and it breaks:
*
*
* start: BCA
* apply BC: BCA
* apply AB: CAB
*
* We make a directed graph of the constraints by linking
* from "above windows" to "below windows as follows:
*
*
* AB -> BC -> CD
* \
* CE
@ -519,7 +519,7 @@ struct Constraint
/* used to create the graph. */
GSList *next_nodes;
/* constraint has been applied, used
* to detect cycles.
*/
@ -547,7 +547,7 @@ add_constraint (Constraint **constraints,
Constraint *c;
g_assert (above->screen == below->screen);
/* check if constraint is a duplicate */
c = constraints[below->stack_position];
while (c != NULL)
@ -574,7 +574,7 @@ create_constraints (Constraint **constraints,
GList *windows)
{
GList *tmp;
tmp = windows;
while (tmp != NULL)
{
@ -587,7 +587,7 @@ create_constraints (Constraint **constraints,
tmp = tmp->next;
continue;
}
if (WINDOW_TRANSIENT_FOR_WHOLE_GROUP (w))
{
GSList *group_windows;
@ -600,9 +600,9 @@ create_constraints (Constraint **constraints,
group_windows = meta_group_list_windows (group);
else
group_windows = NULL;
tmp2 = group_windows;
while (tmp2 != NULL)
{
MetaWindow *group_window = tmp2->data;
@ -614,7 +614,7 @@ create_constraints (Constraint **constraints,
tmp2 = tmp2->next;
continue;
}
#if 0
/* old way of doing it */
if (!(meta_window_is_ancestor_of_transient (w, group_window)) &&
@ -630,7 +630,7 @@ create_constraints (Constraint **constraints,
w->desc, group_window->desc);
add_constraint (constraints, w, group_window);
}
tmp2 = tmp2->next;
}
@ -640,7 +640,7 @@ create_constraints (Constraint **constraints,
!w->transient_parent_is_root_window)
{
MetaWindow *parent;
parent =
meta_display_lookup_x_window (w->display, w->xtransient_for);
@ -652,7 +652,7 @@ create_constraints (Constraint **constraints,
add_constraint (constraints, w, parent);
}
}
tmp = tmp->next;
}
}
@ -671,12 +671,12 @@ graph_constraints (Constraint **constraints,
/* If we have "A below B" and "B below C" then AB -> BC so we
* add BC to next_nodes in AB.
*/
c = constraints[i];
while (c != NULL)
{
Constraint *n;
g_assert (c->below->stack_position == i);
/* Constraints where ->above is below are our
@ -689,10 +689,10 @@ graph_constraints (Constraint **constraints,
n);
/* c is a previous node of n */
n->has_prev = TRUE;
n = n->next;
}
c = c->next;
}
@ -710,16 +710,16 @@ free_constraints (Constraint **constraints,
while (i < n_constraints)
{
Constraint *c;
c = constraints[i];
while (c != NULL)
{
Constraint *next = c->next;
g_slist_free (c->next_nodes);
g_free (c);
c = next;
}
@ -730,7 +730,7 @@ free_constraints (Constraint **constraints,
static void
ensure_above (MetaWindow *above,
MetaWindow *below)
{
{
if (WINDOW_HAS_TRANSIENT_TYPE(above) &&
above->layer < below->layer)
{
@ -758,10 +758,10 @@ traverse_constraint (Constraint *c)
if (c->applied)
return;
ensure_above (c->above, c->below);
c->applied = TRUE;
tmp = c->next_nodes;
while (tmp != NULL)
{
@ -785,13 +785,13 @@ apply_constraints (Constraint **constraints,
while (i < n_constraints)
{
Constraint *c;
c = constraints[i];
while (c != NULL)
{
if (!c->has_prev)
heads = g_slist_prepend (heads, c);
c = c->next;
}
@ -805,7 +805,7 @@ apply_constraints (Constraint **constraints,
Constraint *c = tmp->data;
traverse_constraint (c);
tmp = tmp->next;
}
@ -826,7 +826,7 @@ stack_do_window_deletions (MetaStack *stack)
*/
GList *tmp;
int i;
tmp = stack->removed;
while (tmp != NULL)
{
@ -840,7 +840,7 @@ stack_do_window_deletions (MetaStack *stack)
while (i > 0)
{
--i;
/* there's no guarantee we'll actually find windows to
* remove, e.g. the same xwindow could have been
* added/removed before we ever synced, and we put
@ -877,34 +877,34 @@ stack_do_window_additions (MetaStack *stack)
meta_topic (META_DEBUG_STACK,
"Adding %d windows to sorted list\n",
n_added);
old_size = stack->xwindows->len;
g_array_set_size (stack->xwindows, old_size + n_added);
end = &g_array_index (stack->xwindows, Window, old_size);
/* stack->added has the most recent additions at the
* front of the list, so we need to reverse it
*/
stack->added = g_list_reverse (stack->added);
i = 0;
tmp = stack->added;
while (tmp != NULL)
{
MetaWindow *w;
w = tmp->data;
end[i] = w->xwindow;
/* add to the main list */
stack->sorted = g_list_prepend (stack->sorted, w);
++i;
tmp = tmp->next;
}
stack->need_resort = TRUE; /* may not be needed as we add to top */
stack->need_constrain = TRUE;
stack->need_relayer = TRUE;
@ -923,13 +923,13 @@ static void
stack_do_relayer (MetaStack *stack)
{
GList *tmp;
if (!stack->need_relayer)
return;
meta_topic (META_DEBUG_STACK,
"Recomputing layers\n");
tmp = stack->sorted;
while (tmp != NULL)
@ -954,7 +954,7 @@ stack_do_relayer (MetaStack *stack)
* not layer
*/
}
tmp = tmp->next;
}
@ -973,7 +973,7 @@ stack_do_constrain (MetaStack *stack)
Constraint **constraints;
/* It'd be nice if this were all faster, probably */
if (!stack->need_constrain)
return;
@ -988,10 +988,10 @@ stack_do_constrain (MetaStack *stack)
graph_constraints (constraints, stack->n_positions);
apply_constraints (constraints, stack->n_positions);
free_constraints (constraints, stack->n_positions);
g_free (constraints);
stack->need_constrain = FALSE;
}
@ -1005,10 +1005,10 @@ stack_do_resort (MetaStack *stack)
{
if (!stack->need_resort)
return;
meta_topic (META_DEBUG_STACK,
"Sorting stack list\n");
stack->sorted = g_list_sort (stack->sorted,
(GCompareFunc) compare_window_position);
@ -1248,12 +1248,12 @@ stack_sync_to_xserver (MetaStack *stack)
GArray *x11_hidden_stack_windows;
int n_override_redirect = 0;
MetaStackWindow guard_stack_window;
/* Bail out if frozen */
if (stack->freeze_count > 0)
return;
meta_topic (META_DEBUG_STACK, "Syncing window stack to server\n");
meta_topic (META_DEBUG_STACK, "Syncing window stack to server\n");
stack_ensure_sorted (stack);
@ -1284,7 +1284,7 @@ stack_sync_to_xserver (MetaStack *stack)
MetaStackWindow stack_window;
stack_window.any.type = w->client_type;
meta_topic (META_DEBUG_STACK, "%u:%d - %s ",
w->layer, w->stack_position, w->desc);
@ -1293,7 +1293,7 @@ stack_sync_to_xserver (MetaStack *stack)
n_override_redirect++;
else
g_array_prepend_val (x11_stacked, w->xwindow);
if (w->frame)
top_level_window = w->frame->xwindow;
else
@ -1336,12 +1336,12 @@ stack_sync_to_xserver (MetaStack *stack)
if (x11_stacked->len != stack->xwindows->len - n_override_redirect)
meta_bug ("%u windows stacked, %u windows exist in stack\n",
x11_stacked->len, stack->xwindows->len);
/* Sync to server */
meta_topic (META_DEBUG_STACK, "Restacking %u windows\n",
all_root_children_stacked->len);
meta_error_trap_push (stack->screen->display);
if (stack->last_all_root_children_stacked == NULL)
@ -1425,7 +1425,7 @@ stack_sync_to_xserver (MetaStack *stack)
/* In this case we have an X window that we need to
* put below a wayland window and this is the
* topmost X window. */
/* In X terms (because this is the topmost X window)
* we want to
* raise_window_relative_to_managed_windows() to
@ -1452,7 +1452,7 @@ stack_sync_to_xserver (MetaStack *stack)
* *newp, then we fail to restack *newp; but on
* unmanaging last_xwindow, we'll fix it up.
*/
meta_topic (META_DEBUG_STACK, "Placing window 0x%lx below 0x%lx\n",
newp->any.type == META_WINDOW_CLIENT_TYPE_X11 ? newp->x11.xwindow : 0,
last_xwindow);
@ -1572,7 +1572,7 @@ stack_sync_to_xserver (MetaStack *stack)
* get removed from the stacking list when we unmanage it
* and we'll fix stacking at that time.
*/
/* Sync _NET_CLIENT_LIST and _NET_CLIENT_LIST_STACKING */
XChangeProperty (stack->screen->display->xdisplay,
@ -1633,9 +1633,9 @@ meta_stack_get_above (MetaStack *stack,
{
GList *link;
MetaWindow *above;
stack_ensure_sorted (stack);
link = g_list_find (stack->sorted, window);
if (link == NULL)
return NULL;
@ -1658,7 +1658,7 @@ meta_stack_get_below (MetaStack *stack,
{
GList *link;
MetaWindow *below;
stack_ensure_sorted (stack);
link = g_list_find (stack->sorted, window);
@ -1667,7 +1667,7 @@ meta_stack_get_below (MetaStack *stack,
return NULL;
if (link->next == NULL)
return NULL;
below = link->next->data;
if (only_within_layer &&
@ -1801,22 +1801,22 @@ meta_stack_list_windows (MetaStack *stack,
{
GList *workspace_windows = NULL;
GList *link;
stack_ensure_sorted (stack); /* do adds/removes */
link = stack->sorted;
while (link)
{
MetaWindow *window = link->data;
if (window &&
(workspace == NULL || meta_window_located_on_workspace (window, workspace)))
{
workspace_windows = g_list_prepend (workspace_windows,
window);
}
link = link->next;
}
@ -1833,7 +1833,7 @@ meta_stack_windows_cmp (MetaStack *stack,
/* -1 means a below b */
stack_ensure_sorted (stack); /* update constraints, layers */
if (window_a->layer < window_b->layer)
return -1;
else if (window_a->layer > window_b->layer)
@ -1883,7 +1883,7 @@ compare_pointers (gconstpointer a,
return 1;
else if (a < b)
return -1;
else
else
return 0;
}
@ -1921,7 +1921,7 @@ meta_stack_set_positions (MetaStack *stack,
/* Make sure any adds or removes aren't in limbo -- is this needed? */
stack_ensure_sorted (stack);
if (!lists_contain_same_windows (windows, stack->sorted))
{
meta_warning ("This list of windows has somehow changed; not resetting "
@ -1934,7 +1934,7 @@ meta_stack_set_positions (MetaStack *stack,
stack->need_resort = TRUE;
stack->need_constrain = TRUE;
i = 0;
tmp = windows;
while (tmp != NULL)
@ -1943,7 +1943,7 @@ meta_stack_set_positions (MetaStack *stack,
w->stack_position = i++;
tmp = tmp->next;
}
meta_topic (META_DEBUG_STACK,
"Reset the stack positions of (nearly) all windows\n");
@ -1957,7 +1957,7 @@ meta_window_set_stack_position_no_sync (MetaWindow *window,
{
int low, high, delta;
GList *tmp;
g_return_if_fail (window->screen->stack != NULL);
g_return_if_fail (window->stack_position >= 0);
g_return_if_fail (position >= 0);
@ -1972,7 +1972,7 @@ meta_window_set_stack_position_no_sync (MetaWindow *window,
window->screen->stack->need_resort = TRUE;
window->screen->stack->need_constrain = TRUE;
if (position < window->stack_position)
{
low = position;
@ -1997,7 +1997,7 @@ meta_window_set_stack_position_no_sync (MetaWindow *window,
tmp = tmp->next;
}
window->stack_position = position;
meta_topic (META_DEBUG_STACK,

View File

@ -1,9 +1,9 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
/*
* Copyright (C) 2001 Havoc Pennington
* Copyright (C) 2005 Elijah Newren
*
*
* 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
@ -13,7 +13,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*/
@ -26,7 +26,7 @@
* @short_description: Which windows cover which other windows
*
* There are two factors that determine window position.
*
*
* One is window->stack_position, which is a unique integer
* indicating how windows are ordered with respect to one
* another. The ordering here transcends layers; it isn't changed
@ -34,7 +34,7 @@
* windows from one layer to another, while preserving the relative
* order of the moved windows. Also, it allows us to restore
* the stacking order from a saved session.
*
*
* However when actually stacking windows on the screen, the
* layer overrides the stack_position; windows are first sorted
* by layer, then by stack_position within each layer.
@ -82,7 +82,7 @@ struct _MetaStack
* The order of the elements in this list is not important.
*/
GList *removed;
/**
* If this is zero, the local stack oughtn't to be brought up to date with
* the X server's stack, because it is in the middle of being updated.

View File

@ -2,9 +2,9 @@
/* Mutter box operation testing program */
/*
/*
* Copyright (C) 2005 Elijah Newren
*
*
* 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
@ -14,7 +14,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*/
@ -363,7 +363,7 @@ test_merge_regions ()
* uniformly distributed location of center of struts (within screen)
* merge all regions that are possible
* print stats on problem setup
* number of (non-completely-occluded?) struts
* number of (non-completely-occluded?) struts
* percentage of screen covered
* length of resulting non-minimal spanning set
* length of resulting minimal spanning set
@ -508,11 +508,11 @@ test_merge_regions ()
compare = compare->next;
}
printf (" Num rectangles contained in others : %d\n",
printf (" Num rectangles contained in others : %d\n",
num_contains);
printf (" Num rectangles partially contained in others: %d\n",
printf (" Num rectangles partially contained in others: %d\n",
num_part_contains);
printf (" Num rectangles adjacent to others : %d\n",
printf (" Num rectangles adjacent to others : %d\n",
num_adjacent);
printf (" Num rectangles merged with others : %d\n",
num_merged);
@ -583,9 +583,9 @@ test_regions_okay ()
GList* region;
GList* tmp;
/*************************************************************/
/*************************************************************/
/* Make sure test region 0 has the right spanning rectangles */
/*************************************************************/
/*************************************************************/
region = get_screen_region (0);
tmp = NULL;
tmp = g_list_prepend (tmp, new_meta_rect (0, 0, 1600, 1200));
@ -593,9 +593,9 @@ test_regions_okay ()
meta_rectangle_free_list_and_elements (tmp);
meta_rectangle_free_list_and_elements (region);
/*************************************************************/
/*************************************************************/
/* Make sure test region 1 has the right spanning rectangles */
/*************************************************************/
/*************************************************************/
region = get_screen_region (1);
tmp = NULL;
tmp = g_list_prepend (tmp, new_meta_rect (0, 20, 400, 1180));
@ -606,7 +606,7 @@ test_regions_okay ()
/*************************************************************/
/* Make sure test region 2 has the right spanning rectangles */
/*************************************************************/
/*************************************************************/
region = get_screen_region (2);
tmp = NULL;
tmp = g_list_prepend (tmp, new_meta_rect ( 0, 20, 300, 1180));
@ -620,7 +620,7 @@ test_regions_okay ()
/*************************************************************/
/* Make sure test region 3 has the right spanning rectangles */
/*************************************************************/
/*************************************************************/
region = get_screen_region (3);
tmp = NULL;
tmp = g_list_prepend (tmp, new_meta_rect ( 380, 675, 420, 525)); /* 220500 */
@ -646,7 +646,7 @@ test_regions_okay ()
/*************************************************************/
/* Make sure test region 4 has the right spanning rectangles */
/*************************************************************/
/*************************************************************/
region = get_screen_region (4);
tmp = NULL;
tmp = g_list_prepend (tmp, new_meta_rect ( 800, 20, 800, 1180));
@ -656,7 +656,7 @@ test_regions_okay ()
/*************************************************************/
/* Make sure test region 5 has the right spanning rectangles */
/*************************************************************/
/*************************************************************/
printf ("The next test intentionally causes a warning, "
"but it can be ignored.\n");
region = get_screen_region (5);
@ -1020,9 +1020,9 @@ test_find_onscreen_edges ()
int top = META_DIRECTION_TOP;
int bottom = META_DIRECTION_BOTTOM;
/*************************************************/
/*************************************************/
/* Make sure test region 0 has the correct edges */
/*************************************************/
/*************************************************/
edges = get_screen_edges (0);
tmp = NULL;
tmp = g_list_prepend (tmp, new_screen_edge ( 0, 1200, 1600, 0, bottom));
@ -1033,9 +1033,9 @@ test_find_onscreen_edges ()
meta_rectangle_free_list_and_elements (tmp);
meta_rectangle_free_list_and_elements (edges);
/*************************************************/
/*************************************************/
/* Make sure test region 1 has the correct edges */
/*************************************************/
/*************************************************/
edges = get_screen_edges (1);
tmp = NULL;
tmp = g_list_prepend (tmp, new_screen_edge ( 0, 1200, 400, 0, bottom));
@ -1048,9 +1048,9 @@ test_find_onscreen_edges ()
meta_rectangle_free_list_and_elements (tmp);
meta_rectangle_free_list_and_elements (edges);
/*************************************************/
/*************************************************/
/* Make sure test region 2 has the correct edges */
/*************************************************/
/*************************************************/
edges = get_screen_edges (2);
tmp = NULL;
tmp = g_list_prepend (tmp, new_screen_edge (1200, 1200, 400, 0, bottom));
@ -1069,9 +1069,9 @@ test_find_onscreen_edges ()
meta_rectangle_free_list_and_elements (tmp);
meta_rectangle_free_list_and_elements (edges);
/*************************************************/
/*************************************************/
/* Make sure test region 3 has the correct edges */
/*************************************************/
/*************************************************/
edges = get_screen_edges (3);
tmp = NULL;
tmp = g_list_prepend (tmp, new_screen_edge (1200, 1200, 400, 0, bottom));
@ -1096,7 +1096,7 @@ test_find_onscreen_edges ()
char big_buffer1[(EDGE_LENGTH+2)*FUDGE], big_buffer2[(EDGE_LENGTH+2)*FUDGE];
meta_rectangle_edge_list_to_string (edges, "\n ", big_buffer1);
meta_rectangle_edge_list_to_string (tmp, "\n ", big_buffer2);
printf("Generated edge list:\n %s\nComparison edges list:\n %s\n",
printf("Generated edge list:\n %s\nComparison edges list:\n %s\n",
big_buffer1, big_buffer2);
#endif
@ -1104,9 +1104,9 @@ test_find_onscreen_edges ()
meta_rectangle_free_list_and_elements (tmp);
meta_rectangle_free_list_and_elements (edges);
/*************************************************/
/*************************************************/
/* Make sure test region 4 has the correct edges */
/*************************************************/
/*************************************************/
edges = get_screen_edges (4);
tmp = NULL;
tmp = g_list_prepend (tmp, new_screen_edge ( 800, 1200, 800, 0, bottom));
@ -1117,18 +1117,18 @@ test_find_onscreen_edges ()
meta_rectangle_free_list_and_elements (tmp);
meta_rectangle_free_list_and_elements (edges);
/*************************************************/
/*************************************************/
/* Make sure test region 5 has the correct edges */
/*************************************************/
/*************************************************/
edges = get_screen_edges (5);
tmp = NULL;
verify_edge_lists_are_equal (edges, tmp);
meta_rectangle_free_list_and_elements (tmp);
meta_rectangle_free_list_and_elements (edges);
/*************************************************/
/*************************************************/
/* Make sure test region 6 has the correct edges */
/*************************************************/
/*************************************************/
edges = get_screen_edges (6);
tmp = NULL;
tmp = g_list_prepend (tmp, new_screen_edge ( 0, 1200, 1600, 0, bottom));
@ -1153,18 +1153,18 @@ test_find_nonintersected_monitor_edges ()
int top = META_DIRECTION_TOP;
int bottom = META_DIRECTION_BOTTOM;
/*************************************************************************/
/*************************************************************************/
/* Make sure test monitor set 0 for with region 0 has the correct edges */
/*************************************************************************/
/*************************************************************************/
edges = get_monitor_edges (0, 0);
tmp = NULL;
verify_edge_lists_are_equal (edges, tmp);
meta_rectangle_free_list_and_elements (tmp);
meta_rectangle_free_list_and_elements (edges);
/*************************************************************************/
/*************************************************************************/
/* Make sure test monitor set 2 for with region 1 has the correct edges */
/*************************************************************************/
/*************************************************************************/
edges = get_monitor_edges (2, 1);
tmp = NULL;
tmp = g_list_prepend (tmp, new_monitor_edge ( 0, 600, 1600, 0, bottom));
@ -1173,9 +1173,9 @@ test_find_nonintersected_monitor_edges ()
meta_rectangle_free_list_and_elements (tmp);
meta_rectangle_free_list_and_elements (edges);
/*************************************************************************/
/*************************************************************************/
/* Make sure test monitor set 1 for with region 2 has the correct edges */
/*************************************************************************/
/*************************************************************************/
edges = get_monitor_edges (1, 2);
tmp = NULL;
tmp = g_list_prepend (tmp, new_monitor_edge ( 800, 20, 0, 1080, right));
@ -1185,16 +1185,16 @@ test_find_nonintersected_monitor_edges ()
char big_buffer1[(EDGE_LENGTH+2)*FUDGE], big_buffer2[(EDGE_LENGTH+2)*FUDGE];
meta_rectangle_edge_list_to_string (edges, "\n ", big_buffer1);
meta_rectangle_edge_list_to_string (tmp, "\n ", big_buffer2);
printf("Generated edge list:\n %s\nComparison edges list:\n %s\n",
printf("Generated edge list:\n %s\nComparison edges list:\n %s\n",
big_buffer1, big_buffer2);
#endif
verify_edge_lists_are_equal (edges, tmp);
meta_rectangle_free_list_and_elements (tmp);
meta_rectangle_free_list_and_elements (edges);
/*************************************************************************/
/*************************************************************************/
/* Make sure test monitor set 3 for with region 3 has the correct edges */
/*************************************************************************/
/*************************************************************************/
edges = get_monitor_edges (3, 3);
tmp = NULL;
tmp = g_list_prepend (tmp, new_monitor_edge ( 900, 600, 700, 0, bottom));
@ -1207,9 +1207,9 @@ test_find_nonintersected_monitor_edges ()
meta_rectangle_free_list_and_elements (tmp);
meta_rectangle_free_list_and_elements (edges);
/*************************************************************************/
/*************************************************************************/
/* Make sure test monitor set 3 for with region 4 has the correct edges */
/*************************************************************************/
/*************************************************************************/
edges = get_monitor_edges (3, 4);
tmp = NULL;
tmp = g_list_prepend (tmp, new_monitor_edge ( 800, 600, 800, 0, bottom));
@ -1219,9 +1219,9 @@ test_find_nonintersected_monitor_edges ()
meta_rectangle_free_list_and_elements (tmp);
meta_rectangle_free_list_and_elements (edges);
/*************************************************************************/
/*************************************************************************/
/* Make sure test monitor set 3 for with region 5has the correct edges */
/*************************************************************************/
/*************************************************************************/
edges = get_monitor_edges (3, 5);
tmp = NULL;
verify_edge_lists_are_equal (edges, tmp);

View File

@ -2,10 +2,10 @@
/* Mutter utilities */
/*
/*
* Copyright (C) 2001 Havoc Pennington
* Copyright (C) 2005 Elijah Newren
*
*
* 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
@ -15,7 +15,7 @@
* 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

View File

@ -1,9 +1,9 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
/*
* Copyright (C) 2001 Havoc Pennington
* Copyright (C) 2005 Elijah Newren
*
*
* 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
@ -13,7 +13,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*/
@ -67,7 +67,7 @@ ensure_logfile (void)
char *tmpl;
int fd;
GError *err;
tmpl = g_strdup_printf ("mutter-%d-debug-log-XXXXXX",
(int) getpid ());
@ -77,7 +77,7 @@ ensure_logfile (void)
&err);
g_free (tmpl);
if (err != NULL)
{
meta_warning ("Failed to open debug log: %s\n",
@ -85,9 +85,9 @@ ensure_logfile (void)
g_error_free (err);
return;
}
logfile = fdopen (fd, "w");
if (logfile == NULL)
{
meta_warning ("Failed to fdopen() log file %s: %s\n",
@ -98,7 +98,7 @@ ensure_logfile (void)
{
g_printerr ("Opened log file %s\n", filename);
}
g_free (filename);
}
}
@ -116,7 +116,7 @@ meta_set_verbose (gboolean setting)
#ifndef WITH_VERBOSE_MODE
if (setting)
meta_fatal (_("Mutter was compiled without support for verbose mode\n"));
#else
#else
if (setting)
ensure_logfile ();
#endif
@ -225,7 +225,7 @@ utf8_fputs (const char *str,
{
char *l;
int retval;
l = g_locale_from_utf8 (str, -1, NULL, NULL, NULL);
if (l == NULL)
@ -259,24 +259,24 @@ meta_debug_spew_real (const char *format, ...)
va_list args;
gchar *str;
FILE *out;
g_return_if_fail (format != NULL);
if (!is_debugging)
return;
va_start (args, format);
str = g_strdup_vprintf (format, args);
va_end (args);
out = logfile ? logfile : stderr;
if (no_prefix == 0)
utf8_fputs ("Window manager: ", out);
utf8_fputs (str, out);
fflush (out);
g_free (str);
}
#endif /* WITH_VERBOSE_MODE */
@ -381,11 +381,11 @@ meta_topic_real_valist (MetaDebugTopic topic,
++sync_count;
fprintf (out, "%d: ", sync_count);
}
utf8_fputs (str, out);
fflush (out);
g_free (str);
}
@ -410,7 +410,7 @@ meta_bug (const char *format, ...)
FILE *out;
g_return_if_fail (format != NULL);
va_start (args, format);
str = g_strdup_vprintf (format, args);
va_end (args);
@ -426,9 +426,9 @@ meta_bug (const char *format, ...)
utf8_fputs (str, out);
fflush (out);
g_free (str);
/* stop us in a debugger */
abort ();
}
@ -439,9 +439,9 @@ meta_warning (const char *format, ...)
va_list args;
gchar *str;
FILE *out;
g_return_if_fail (format != NULL);
va_start (args, format);
str = g_strdup_vprintf (format, args);
va_end (args);
@ -457,7 +457,7 @@ meta_warning (const char *format, ...)
utf8_fputs (str, out);
fflush (out);
g_free (str);
}
@ -467,9 +467,9 @@ meta_fatal (const char *format, ...)
va_list args;
gchar *str;
FILE *out;
g_return_if_fail (format != NULL);
va_start (args, format);
str = g_strdup_vprintf (format, args);
va_end (args);
@ -485,7 +485,7 @@ meta_fatal (const char *format, ...)
utf8_fputs (str, out);
fflush (out);
g_free (str);
meta_exit (META_EXIT_ERROR);
@ -508,7 +508,7 @@ meta_pop_no_msg_prefix (void)
void
meta_exit (MetaExitCode code)
{
exit (code);
}

View File

@ -9,12 +9,12 @@
* which the rest of the world is allowed to use.)
*/
/*
/*
* Copyright (C) 2001 Havoc Pennington
* Copyright (C) 2002 Red Hat, Inc.
* Copyright (C) 2003, 2004 Rob Adams
* Copyright (C) 2004-2006 Elijah Newren
*
*
* 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
@ -24,7 +24,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*/
@ -74,11 +74,10 @@ typedef enum {
typedef enum
{
META_IS_CONFIGURE_REQUEST = 1 << 0,
META_DO_GRAVITY_ADJUST = 1 << 1,
META_IS_USER_ACTION = 1 << 2,
META_IS_MOVE_ACTION = 1 << 3,
META_IS_RESIZE_ACTION = 1 << 4,
META_IS_WAYLAND_RESIZE = 1 << 5
META_IS_USER_ACTION = 1 << 1,
META_IS_MOVE_ACTION = 1 << 2,
META_IS_RESIZE_ACTION = 1 << 3,
META_IS_WAYLAND_RESIZE = 1 << 4,
} MetaMoveResizeFlags;
typedef enum
@ -91,7 +90,7 @@ typedef enum
struct _MetaWindow
{
GObject parent_instance;
MetaDisplay *display;
MetaScreen *screen;
const MetaMonitorInfo *monitor;
@ -135,18 +134,18 @@ struct _MetaWindow
int hide_titlebar_when_maximized;
int net_wm_pid;
Window xtransient_for;
Window xgroup_leader;
Window xclient_leader;
MetaWindow *transient_for;
/* Initial workspace property */
int initial_workspace;
int initial_workspace;
/* Initial timestamp property */
guint32 initial_timestamp;
guint32 initial_timestamp;
/* Whether this is an override redirect window or not */
guint override_redirect : 1;
@ -185,7 +184,7 @@ struct _MetaWindow
* these monitors. If not, this is the single monitor which the window's
* origin is on. */
gint fullscreen_monitors[4];
/* Whether we're trying to constrain the window to be fully onscreen */
guint require_fully_onscreen : 1;
@ -214,7 +213,7 @@ struct _MetaWindow
* see also unmaps_pending
*/
guint mapped : 1;
/* Whether window has been hidden from view by lowering it to the bottom
* of window stack.
*/
@ -248,23 +247,23 @@ struct _MetaWindow
/* whether an initial workspace was explicitly set */
guint initial_workspace_set : 1;
/* whether an initial timestamp was explicitly set */
guint initial_timestamp_set : 1;
/* whether net_wm_user_time has been set yet */
guint net_wm_user_time_set : 1;
/* whether net_wm_icon_geometry has been set */
guint icon_geometry_set : 1;
/* These are the flags from WM_PROTOCOLS */
guint take_focus : 1;
guint delete_window : 1;
guint can_ping : 1;
/* Globally active / No input */
guint input : 1;
/* MWM hints about features of window */
guint mwm_decorated : 1;
guint mwm_border_only : 1;
@ -273,7 +272,7 @@ struct _MetaWindow
guint mwm_has_maximize_func : 1;
guint mwm_has_move_func : 1;
guint mwm_has_resize_func : 1;
/* Computed features of window */
guint decorated : 1;
guint border_only : 1;
@ -296,16 +295,13 @@ struct _MetaWindow
/* EWHH demands attention flag */
guint wm_state_demands_attention : 1;
/* TRUE iff window == window->display->focus_window */
guint has_focus : 1;
/* Have we placed this window? */
guint placed : 1;
/* Must we force_save_user_window_placement? */
guint force_save_user_rect : 1;
/* Is this not a transient of the focus window which is being denied focus? */
guint denied_focus_and_not_transient : 1;
@ -317,15 +313,15 @@ struct _MetaWindow
/* Are we in meta_window_new()? */
guint constructing : 1;
/* Are we in the various queues? (Bitfield: see META_WINDOW_IS_IN_QUEUE) */
guint is_in_queues : NUMBER_OF_QUEUES;
/* Used by keybindings.c */
guint keys_grabbed : 1; /* normal keybindings grabbed */
guint grab_on_frame : 1; /* grabs are on the frame */
guint all_keys_grabbed : 1; /* AnyKey grabbed */
/* Set if the reason for unmanaging the window is that
* it was withdrawn
*/
@ -338,7 +334,7 @@ struct _MetaWindow
/* Transient parent is a root window */
guint transient_parent_is_root_window : 1;
/* if TRUE, window was maximized at start of current grab op */
guint shaken_loose : 1;
@ -387,7 +383,7 @@ struct _MetaWindow
guint sync_request_timeout_id;
/* alarm monitoring client's _NET_WM_SYNC_REQUEST_COUNTER */
XSyncAlarm sync_request_alarm;
/* Number of UnmapNotify that are caused by us, if
* we get UnmapNotify with none pending then the client
* is withdrawing the window.
@ -403,19 +399,19 @@ struct _MetaWindow
/* window that gets updated net_wm_user_time values */
Window user_time_window;
gboolean has_custom_frame_extents;
GtkBorder custom_frame_extents;
/* The size we set the window to last (i.e. what we believe
* to be its actual size on the server). The x, y are
* the actual server-side x,y so are relative to the frame
* (meaning that they just hold the frame width and height)
* (meaning that they just hold the frame width and height)
* or the root window (meaning they specify the location
* of the top left of the inner window) as appropriate.
*/
MetaRectangle rect;
gboolean has_custom_frame_extents;
GtkBorder custom_frame_extents;
/* The geometry to restore when we unmaximize. The position is in
* root window coords, even if there's a frame, which contrasts with
* window->rect above. Note that this gives the position and size
@ -423,31 +419,29 @@ struct _MetaWindow
*/
MetaRectangle saved_rect;
/* This is the geometry the window had after the last user-initiated
* move/resize operations. We use this whenever we are moving the
* implicitly (for example, if we move to avoid a panel, we can snap
* back to this position if the panel moves again). Note that this
* gives the position and size of the client window (i.e. ignoring
* the frame).
/* This is the geometry the window will have if no constraints have
* applied. We use this whenever we are moving implicitly (for example,
* if we move to avoid a panel, we can snap back to this position if
* the panel moves again). Note that this gives the position and size
* of the client window (i.e. ignoring the frame).
*
* Position always in root coords, unlike window->rect.
*/
MetaRectangle user_rect;
MetaRectangle unconstrained_rect;
/* Cached net_wm_icon_geometry */
MetaRectangle icon_geometry;
/* Requested geometry */
int border_width;
/* x/y/w/h here get filled with ConfigureRequest values */
XSizeHints size_hints;
/* Managed by stack.c */
MetaStackLayer layer;
int stack_position; /* see comment in stack.h */
/* Current dialog open for this window */
/* Managed by delete.c */
int dialog_pid;
guint is_alive : 1;
/* maintained by group.c */
MetaGroup *group;
@ -481,9 +475,10 @@ struct _MetaWindowClass
MetaGrabOp op);
void (*grab_op_ended) (MetaWindow *window,
MetaGrabOp op);
void (*current_workspace_changed) (MetaWindow *window);
void (*move_resize_internal) (MetaWindow *window,
int gravity,
MetaRectangle requested_rect,
MetaRectangle unconstrained_rect,
MetaRectangle constrained_rect,
MetaMoveResizeFlags flags,
MetaMoveResizeResultFlags *result);
@ -527,13 +522,6 @@ MetaWindow * _meta_window_shared_new (MetaDisplay *display,
MetaCompEffect effect,
XWindowAttributes *attrs);
MetaWindow * meta_window_x11_new (MetaDisplay *display,
Window xwindow,
gboolean must_be_viewable,
MetaCompEffect effect);
MetaWindow * meta_window_wayland_new (MetaDisplay *display,
MetaWaylandSurface *surface);
void meta_window_unmanage (MetaWindow *window,
guint32 timestamp);
void meta_window_calc_showing (MetaWindow *window);
@ -543,11 +531,6 @@ void meta_window_tile (MetaWindow *window);
void meta_window_maximize_internal (MetaWindow *window,
MetaMaximizeFlags directions,
MetaRectangle *saved_rect);
void meta_window_unmaximize_with_gravity (MetaWindow *window,
MetaMaximizeFlags directions,
int new_width,
int new_height,
int gravity);
void meta_window_make_fullscreen_internal (MetaWindow *window);
void meta_window_update_fullscreen_monitors (MetaWindow *window,
@ -562,10 +545,6 @@ void meta_window_move (MetaWindow *window,
gboolean user_op,
int root_x_nw,
int root_y_nw);
void meta_window_resize (MetaWindow *window,
gboolean user_op,
int w,
int h);
void meta_window_move_resize (MetaWindow *window,
gboolean user_op,
int root_x_nw,
@ -608,7 +587,7 @@ void meta_window_get_gravity_position (MetaWindow *window,
/* Get geometry for saving in the session; x/y are gravity
* position, and w/h are in resize inc above the base size.
*/
void meta_window_get_geometry (MetaWindow *window,
void meta_window_get_session_geometry (MetaWindow *window,
int *x,
int *y,
int *width,
@ -619,15 +598,12 @@ void meta_window_update_unfocused_button_grabs (MetaWindow *window);
void meta_window_set_focused_internal (MetaWindow *window,
gboolean focused);
void meta_window_set_current_workspace_hint (MetaWindow *window);
void meta_window_current_workspace_changed (MetaWindow *window);
unsigned long meta_window_get_net_wm_desktop (MetaWindow *window);
void meta_window_show_menu (MetaWindow *window,
int root_x,
int root_y,
int button,
guint32 timestamp);
void meta_window_show_menu (MetaWindow *window,
MetaWindowMenuType menu,
int x,
int y);
gboolean meta_window_handle_mouse_grab_op_event (MetaWindow *window,
const ClutterEvent *event);
@ -677,9 +653,6 @@ void meta_window_update_icon_now (MetaWindow *window);
void meta_window_update_for_monitors_changed (MetaWindow *window);
void meta_window_update_on_all_workspaces (MetaWindow *window);
void meta_window_propagate_focus_appearance (MetaWindow *window,
gboolean focused);
gboolean meta_window_should_attach_to_parent (MetaWindow *window);
gboolean meta_window_can_tile_side_by_side (MetaWindow *window);
@ -713,6 +686,10 @@ void meta_window_handle_enter (MetaWindow *window,
guint32 timestamp,
guint root_x,
guint root_y);
void meta_window_handle_leave (MetaWindow *window);
gboolean meta_window_handle_ungrabbed_event (MetaWindow *window,
const ClutterEvent *event);
void meta_window_set_surface_mapped (MetaWindow *window,
gboolean surface_mapped);
@ -721,6 +698,8 @@ Window meta_window_get_toplevel_xwindow (MetaWindow *window);
void meta_window_get_client_area_rect (const MetaWindow *window,
cairo_rectangle_int_t *rect);
void meta_window_get_titlebar_rect (MetaWindow *window,
MetaRectangle *titlebar_rect);
void meta_window_activate_full (MetaWindow *window,
guint32 timestamp,
@ -742,13 +721,11 @@ void meta_window_update_resize (MetaWindow *window,
void meta_window_move_resize_internal (MetaWindow *window,
MetaMoveResizeFlags flags,
int gravity,
int root_x_nw,
int root_y_nw,
int w,
int h);
void meta_window_save_user_window_placement (MetaWindow *window);
MetaRectangle client_rect);
void meta_window_grab_op_began (MetaWindow *window, MetaGrabOp op);
void meta_window_grab_op_ended (MetaWindow *window, MetaGrabOp op);
void meta_window_set_alive (MetaWindow *window, gboolean is_alive);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -10,10 +10,10 @@
* are unmapped.
*/
/*
/*
* Copyright (C) 2001 Havoc Pennington
* Copyright (C) 2004, 2005 Elijah Newren
*
*
* 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
@ -23,7 +23,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*/
@ -38,7 +38,7 @@ struct _MetaWorkspace
{
GObject parent_instance;
MetaScreen *screen;
GList *windows;
/* The "MRU list", or "most recently used" list, is a list of

View File

@ -1,10 +1,10 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
/*
* Copyright (C) 2001 Havoc Pennington
* Copyright (C) 2003 Rob Adams
* Copyright (C) 2004, 2005 Elijah Newren
*
*
* 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
@ -14,7 +14,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*/
@ -197,7 +197,7 @@ meta_workspace_new (MetaScreen *screen)
workspace->all_struts = NULL;
workspace->showing_desktop = FALSE;
return workspace;
}
@ -219,7 +219,7 @@ workspace_free_all_struts (MetaWorkspace *workspace)
{
if (workspace->all_struts == NULL)
return;
g_slist_foreach (workspace->all_struts, free_this, NULL);
g_slist_free (workspace->all_struts);
workspace->all_struts = NULL;
@ -236,7 +236,7 @@ workspace_free_builtin_struts (MetaWorkspace *workspace)
{
if (workspace->builtin_struts == NULL)
return;
g_slist_foreach (workspace->builtin_struts, free_this, NULL);
g_slist_free (workspace->builtin_struts);
workspace->builtin_struts = NULL;
@ -254,7 +254,7 @@ meta_workspace_remove (MetaWorkspace *workspace)
/* Here we assume all the windows are already on another workspace
* as well, so they won't be "orphaned"
*/
tmp = workspace->windows;
while (tmp != NULL)
{
@ -272,10 +272,10 @@ meta_workspace_remove (MetaWorkspace *workspace)
g_assert (workspace->windows == NULL);
screen = workspace->screen;
workspace->screen->workspaces =
g_list_remove (workspace->screen->workspaces, workspace);
g_free (workspace->work_area_monitor);
g_list_free (workspace->mru_list);
@ -313,11 +313,11 @@ meta_workspace_add_window (MetaWorkspace *workspace,
MetaWindow *window)
{
g_return_if_fail (window->workspace == NULL);
/* If the window is on all workspaces, we want to add it to all mru
* lists, otherwise just add it to this workspaces mru list
*/
if (window->on_all_workspaces)
if (window->on_all_workspaces)
{
if (window->workspace == NULL)
{
@ -342,8 +342,8 @@ meta_workspace_add_window (MetaWorkspace *workspace,
window->workspace = workspace;
meta_window_set_current_workspace_hint (window);
meta_window_current_workspace_changed (window);
if (window->struts)
{
meta_topic (META_DEBUG_WORKAREA,
@ -371,10 +371,10 @@ meta_workspace_remove_window (MetaWorkspace *workspace,
window->workspace = NULL;
/* If the window is on all workspaces, we don't want to remove it
* from the MRU list unless this causes it to be removed from all
* from the MRU list unless this causes it to be removed from all
* workspaces
*/
if (window->on_all_workspaces)
if (window->on_all_workspaces)
{
GList* tmp = window->screen->workspaces;
while (tmp)
@ -391,8 +391,8 @@ meta_workspace_remove_window (MetaWorkspace *workspace,
g_assert (g_list_find (workspace->mru_list, window) == NULL);
}
meta_window_set_current_workspace_hint (window);
meta_window_current_workspace_changed (window);
if (window->struts)
{
meta_topic (META_DEBUG_WORKAREA,
@ -416,12 +416,12 @@ meta_workspace_relocate_windows (MetaWorkspace *workspace,
{
GList *tmp;
GList *copy;
g_return_if_fail (workspace != new_home);
/* can't modify list we're iterating over */
copy = g_list_copy (workspace->windows);
tmp = copy;
while (tmp != NULL)
{
@ -429,12 +429,12 @@ meta_workspace_relocate_windows (MetaWorkspace *workspace,
meta_workspace_remove_window (workspace, window);
meta_workspace_add_window (new_home, window);
tmp = tmp->next;
}
g_list_free (copy);
g_assert (workspace->windows == NULL);
}
@ -547,10 +547,10 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace,
MetaWorkspaceLayout layout1, layout2;
gint num_workspaces, current_space, new_space;
MetaMotionDirection direction;
meta_verbose ("Activating workspace %d\n",
meta_workspace_index (workspace));
if (workspace->screen->active_workspace == workspace)
return;
@ -582,7 +582,7 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace,
if (workspace->screen->display->grab_op == META_GRAB_OP_MOVING ||
workspace->screen->display->grab_op == META_GRAB_OP_KEYBOARD_MOVING)
move_window = workspace->screen->display->grab_window;
if (move_window != NULL)
{
if (move_window->on_all_workspaces)
@ -718,7 +718,7 @@ meta_workspace_update_window_hints (MetaWorkspace *workspace)
{
MetaWindow *win = l->data;
meta_window_set_current_workspace_hint (win);
meta_window_current_workspace_changed (win);
l = l->next;
}
@ -739,7 +739,7 @@ meta_workspace_list_windows (MetaWorkspace *workspace)
GSList *display_windows;
GSList *tmp;
GList *workspace_windows;
display_windows = meta_display_list_windows (workspace->screen->display,
META_LIST_DEFAULT);
@ -767,7 +767,7 @@ meta_workspace_invalidate_work_area (MetaWorkspace *workspace)
GList *tmp;
GList *windows;
int i;
if (workspace->work_areas_invalid)
{
meta_topic (META_DEBUG_WORKAREA,
@ -787,7 +787,7 @@ meta_workspace_invalidate_work_area (MetaWorkspace *workspace)
g_free (workspace->work_area_monitor);
workspace->work_area_monitor = NULL;
workspace_free_all_struts (workspace);
for (i = 0; i < workspace->screen->n_monitor_infos; i++)
@ -800,7 +800,7 @@ meta_workspace_invalidate_work_area (MetaWorkspace *workspace)
workspace->screen_region = NULL;
workspace->screen_edges = NULL;
workspace->monitor_edges = NULL;
workspace->work_areas_invalid = TRUE;
/* redo the size/position constraints on all windows */
@ -811,7 +811,7 @@ meta_workspace_invalidate_work_area (MetaWorkspace *workspace)
MetaWindow *w = tmp->data;
meta_window_queue (w, META_QUEUE_MOVE_RESIZE);
tmp = tmp->next;
}
@ -876,7 +876,7 @@ ensure_work_areas_validated (MetaWorkspace *workspace)
/* STEP 2: Get the maximal/spanning rects for the onscreen and
* on-single-monitor regions
*/
*/
g_assert (workspace->monitor_region == NULL);
g_assert (workspace->screen_region == NULL);
@ -948,7 +948,7 @@ ensure_work_areas_validated (MetaWorkspace *workspace)
workspace->work_area_screen.x,
workspace->work_area_screen.y,
workspace->work_area_screen.width,
workspace->work_area_screen.height);
workspace->work_area_screen.height);
/* Now find the work areas for each monitor */
g_free (workspace->work_area_monitor);
@ -983,7 +983,7 @@ ensure_work_areas_validated (MetaWorkspace *workspace)
/* STEP 4: Make sure the screen_region is nonempty (separate from step 2
* since it relies on step 3).
*/
*/
if (workspace->screen_region == NULL)
{
MetaRectangle *nonempty_region;
@ -1070,7 +1070,7 @@ meta_workspace_get_work_area_for_monitor (MetaWorkspace *workspace,
ensure_work_areas_validated (workspace);
g_assert (which_monitor < workspace->screen->n_monitor_infos);
*area = workspace->work_area_monitor[which_monitor];
}
@ -1086,7 +1086,7 @@ meta_workspace_get_work_area_all_monitors (MetaWorkspace *workspace,
MetaRectangle *area)
{
ensure_work_areas_validated (workspace);
*area = workspace->work_area_screen;
}
@ -1151,7 +1151,7 @@ MetaWorkspace*
meta_workspace_get_neighbor (MetaWorkspace *workspace,
MetaMotionDirection direction)
{
MetaWorkspaceLayout layout;
MetaWorkspaceLayout layout;
int i, current_space, num_workspaces;
gboolean ltr;
@ -1162,10 +1162,10 @@ meta_workspace_get_neighbor (MetaWorkspace *workspace,
meta_verbose ("Getting neighbor of %d in direction %s\n",
current_space, meta_motion_direction_to_string (direction));
ltr = meta_ui_get_direction() == META_UI_DIRECTION_LTR;
switch (direction)
switch (direction)
{
case META_MOTION_LEFT:
layout.current_col -= ltr ? 1 : -1;
@ -1199,12 +1199,12 @@ meta_workspace_get_neighbor (MetaWorkspace *workspace,
if (i >= num_workspaces)
meta_bug ("calc_workspace_layout left an invalid (too-high) workspace number %d in the grid\n",
i);
meta_verbose ("Neighbor workspace is %d at row %d col %d\n",
i, layout.current_row, layout.current_col);
meta_screen_free_workspace_layout (&layout);
return meta_screen_get_workspace_by_index (workspace->screen, i);
}
@ -1258,7 +1258,7 @@ meta_workspace_focus_default_window (MetaWorkspace *workspace,
}
if (workspace->screen->display->autoraise_window != window &&
meta_prefs_get_auto_raise ())
meta_prefs_get_auto_raise ())
{
meta_display_queue_autoraise_callback (workspace->screen->display,
window);
@ -1303,7 +1303,7 @@ focus_ancestor_or_top_window (MetaWorkspace *workspace,
meta_topic (META_DEBUG_FOCUS,
"Focusing MRU window\n");
/* First, check to see if we need to focus an ancestor of a window */
/* First, check to see if we need to focus an ancestor of a window */
if (not_this_one)
{
MetaWindow *ancestor;
@ -1314,9 +1314,9 @@ focus_ancestor_or_top_window (MetaWorkspace *workspace,
meta_window_showing_on_its_workspace (ancestor))
{
meta_topic (META_DEBUG_FOCUS,
"Focusing %s, ancestor of %s\n",
"Focusing %s, ancestor of %s\n",
ancestor->desc, not_this_one->desc);
meta_window_focus (ancestor, timestamp);
/* Also raise the window if in click-to-focus */
@ -1335,7 +1335,7 @@ focus_ancestor_or_top_window (MetaWorkspace *workspace,
{
meta_topic (META_DEBUG_FOCUS,
"Focusing workspace MRU window %s\n", window->desc);
meta_window_focus (window, timestamp);
/* Also raise the window if in click-to-focus */

View File

@ -62,6 +62,7 @@ item(_GTK_WINDOW_OBJECT_PATH)
item(_GTK_APP_MENU_OBJECT_PATH)
item(_GTK_MENUBAR_OBJECT_PATH)
item(_GTK_FRAME_EXTENTS)
item(_GTK_SHOW_WINDOW_MENU)
item(_GNOME_WM_KEYBINDINGS)
item(_GNOME_PANEL_ACTION)
item(_GNOME_PANEL_ACTION_MAIN_MENU)

View File

@ -2,9 +2,9 @@
/* Simple box operations */
/*
/*
* Copyright (C) 2005, 2006 Elijah Newren
*
*
* 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
@ -14,7 +14,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*/

View File

@ -4,10 +4,10 @@
* PLEASE KEEP IN SYNC WITH GSETTINGS SCHEMAS!
*/
/*
/*
* Copyright (C) 2001 Havoc Pennington
* Copyright (C) 2005 Elijah Newren
*
*
* 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
@ -17,7 +17,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*/
@ -49,6 +49,7 @@ typedef struct _MetaResizePopup MetaResizePopup;
* MetaFrameFlags:
* @META_FRAME_ALLOWS_DELETE: frame allows delete
* @META_FRAME_ALLOWS_MENU: frame allows menu
* @META_FRAME_ALLOWS_APPMENU: frame allows (fallback) app menu
* @META_FRAME_ALLOWS_MINIMIZE: frame allows minimize
* @META_FRAME_ALLOWS_MAXIMIZE: frame allows maximize
* @META_FRAME_ALLOWS_VERTICAL_RESIZE: frame allows vertical resize
@ -69,78 +70,24 @@ typedef enum
{
META_FRAME_ALLOWS_DELETE = 1 << 0,
META_FRAME_ALLOWS_MENU = 1 << 1,
META_FRAME_ALLOWS_MINIMIZE = 1 << 2,
META_FRAME_ALLOWS_MAXIMIZE = 1 << 3,
META_FRAME_ALLOWS_VERTICAL_RESIZE = 1 << 4,
META_FRAME_ALLOWS_HORIZONTAL_RESIZE = 1 << 5,
META_FRAME_HAS_FOCUS = 1 << 6,
META_FRAME_SHADED = 1 << 7,
META_FRAME_STUCK = 1 << 8,
META_FRAME_MAXIMIZED = 1 << 9,
META_FRAME_ALLOWS_SHADE = 1 << 10,
META_FRAME_ALLOWS_MOVE = 1 << 11,
META_FRAME_FULLSCREEN = 1 << 12,
META_FRAME_IS_FLASHING = 1 << 13,
META_FRAME_ABOVE = 1 << 14,
META_FRAME_TILED_LEFT = 1 << 15,
META_FRAME_TILED_RIGHT = 1 << 16
META_FRAME_ALLOWS_APPMENU = 1 << 2,
META_FRAME_ALLOWS_MINIMIZE = 1 << 3,
META_FRAME_ALLOWS_MAXIMIZE = 1 << 4,
META_FRAME_ALLOWS_VERTICAL_RESIZE = 1 << 5,
META_FRAME_ALLOWS_HORIZONTAL_RESIZE = 1 << 6,
META_FRAME_HAS_FOCUS = 1 << 7,
META_FRAME_SHADED = 1 << 8,
META_FRAME_STUCK = 1 << 9,
META_FRAME_MAXIMIZED = 1 << 10,
META_FRAME_ALLOWS_SHADE = 1 << 11,
META_FRAME_ALLOWS_MOVE = 1 << 12,
META_FRAME_FULLSCREEN = 1 << 13,
META_FRAME_IS_FLASHING = 1 << 14,
META_FRAME_ABOVE = 1 << 15,
META_FRAME_TILED_LEFT = 1 << 16,
META_FRAME_TILED_RIGHT = 1 << 17
} MetaFrameFlags;
/**
* MetaMenuOp:
* @META_MENU_OP_NONE: No menu operation
* @META_MENU_OP_DELETE: Menu operation delete
* @META_MENU_OP_MINIMIZE: Menu operation minimize
* @META_MENU_OP_UNMAXIMIZE: Menu operation unmaximize
* @META_MENU_OP_MAXIMIZE: Menu operation maximize
* @META_MENU_OP_UNSHADE: Menu operation unshade
* @META_MENU_OP_SHADE: Menu operation shade
* @META_MENU_OP_UNSTICK: Menu operation unstick
* @META_MENU_OP_STICK: Menu operation stick
* @META_MENU_OP_WORKSPACES: Menu operation workspaces
* @META_MENU_OP_MOVE: Menu operation move
* @META_MENU_OP_RESIZE: Menu operation resize
* @META_MENU_OP_ABOVE: Menu operation above
* @META_MENU_OP_UNABOVE: Menu operation unabove
* @META_MENU_OP_MOVE_LEFT: Menu operation left
* @META_MENU_OP_MOVE_RIGHT: Menu operation right
* @META_MENU_OP_MOVE_UP: Menu operation up
* @META_MENU_OP_MOVE_DOWN: Menu operation down
* @META_MENU_OP_RECOVER: Menu operation recover
*/
typedef enum
{
META_MENU_OP_NONE = 0,
META_MENU_OP_DELETE = 1 << 0,
META_MENU_OP_MINIMIZE = 1 << 1,
META_MENU_OP_UNMAXIMIZE = 1 << 2,
META_MENU_OP_MAXIMIZE = 1 << 3,
META_MENU_OP_UNSHADE = 1 << 4,
META_MENU_OP_SHADE = 1 << 5,
META_MENU_OP_UNSTICK = 1 << 6,
META_MENU_OP_STICK = 1 << 7,
META_MENU_OP_WORKSPACES = 1 << 8,
META_MENU_OP_MOVE = 1 << 9,
META_MENU_OP_RESIZE = 1 << 10,
META_MENU_OP_ABOVE = 1 << 11,
META_MENU_OP_UNABOVE = 1 << 12,
META_MENU_OP_MOVE_LEFT = 1 << 13,
META_MENU_OP_MOVE_RIGHT = 1 << 14,
META_MENU_OP_MOVE_UP = 1 << 15,
META_MENU_OP_MOVE_DOWN = 1 << 16,
META_MENU_OP_RECOVER = 1 << 17
} MetaMenuOp;
typedef struct _MetaWindowMenu MetaWindowMenu;
typedef void (* MetaWindowMenuFunc) (MetaWindowMenu *menu,
Display *xdisplay,
Window client_xwindow,
guint32 timestamp,
MetaMenuOp op,
int workspace,
gpointer user_data);
/**
* MetaGrabOp:
* @META_GRAB_OP_NONE: None
@ -226,6 +173,7 @@ typedef enum
*/
typedef enum
{
META_CURSOR_NONE = 0,
META_CURSOR_DEFAULT,
META_CURSOR_NORTH_RESIZE,
META_CURSOR_SOUTH_RESIZE,
@ -290,7 +238,7 @@ typedef enum
*/
META_VIRTUAL_SHIFT_MASK = 1 << 5,
META_VIRTUAL_CONTROL_MASK = 1 << 6,
META_VIRTUAL_ALT_MASK = 1 << 7,
META_VIRTUAL_ALT_MASK = 1 << 7,
META_VIRTUAL_META_MASK = 1 << 8,
META_VIRTUAL_SUPER_MASK = 1 << 9,
META_VIRTUAL_HYPER_MASK = 1 << 10,
@ -413,6 +361,7 @@ typedef enum
META_BUTTON_FUNCTION_UNSHADE,
META_BUTTON_FUNCTION_UNABOVE,
META_BUTTON_FUNCTION_UNSTICK,
META_BUTTON_FUNCTION_APPMENU,
META_BUTTON_FUNCTION_LAST
} MetaButtonFunction;
@ -421,10 +370,10 @@ typedef enum
/* Keep array size in sync with MAX_BUTTONS_PER_CORNER */
/**
* MetaButtonLayout:
* @left_buttons: (array fixed-size=10):
* @right_buttons: (array fixed-size=10):
* @left_buttons_has_spacer: (array fixed-size=10):
* @right_buttons_has_spacer: (array fixed-size=10):
* @left_buttons: (array fixed-size=11):
* @right_buttons: (array fixed-size=11):
* @left_buttons_has_spacer: (array fixed-size=11):
* @right_buttons_has_spacer: (array fixed-size=11):
*/
typedef struct _MetaButtonLayout MetaButtonLayout;
struct _MetaButtonLayout
@ -438,6 +387,19 @@ struct _MetaButtonLayout
gboolean right_buttons_has_spacer[MAX_BUTTONS_PER_CORNER];
};
/**
* MetaWindowMenuType:
* @META_WINDOW_MENU_WM: the window manager menu
* @META_WINDOW_MENU_APP: the (fallback) app menu
*
* Menu the compositor should display for a given window
*/
typedef enum
{
META_WINDOW_MENU_WM,
META_WINDOW_MENU_APP
} MetaWindowMenuType;
/**
* MetaFrameBorders:
* @visible: inner visible portion of frame border

View File

@ -122,5 +122,10 @@ void meta_compositor_show_tile_preview (MetaCompositor *compositor,
MetaRectangle *tile_rect,
int tile_monitor_number);
void meta_compositor_hide_tile_preview (MetaCompositor *compositor);
void meta_compositor_show_window_menu (MetaCompositor *compositor,
MetaWindow *window,
MetaWindowMenuType menu,
int x,
int y);
#endif /* META_COMPOSITOR_H */

View File

@ -2,9 +2,9 @@
/* Mutter X error handling */
/*
/*
* Copyright (C) 2001 Havoc Pennington
*
*
* 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
@ -14,7 +14,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*/

View File

@ -2,10 +2,10 @@
/* Mutter gradient rendering */
/*
/*
* Copyright (C) 2001 Havoc Pennington, 99% copied from wrlib in
* WindowMaker, Copyright (C) 1997-2000 Dan Pascu and Alfredo Kojima
*
*
* 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
@ -15,7 +15,7 @@
* 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, see <http://www.gnu.org/licenses/>. */

View File

@ -2,9 +2,9 @@
/* Mutter window groups */
/*
/*
* Copyright (C) 2002 Red Hat Inc.
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
@ -14,7 +14,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*/

View File

@ -2,9 +2,9 @@
/* Mutter main */
/*
/*
* Copyright (C) 2001 Havoc Pennington
*
*
* 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
@ -14,7 +14,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*/

View File

@ -164,6 +164,12 @@ struct _MetaPluginClass
int tile_monitor_number);
void (*hide_tile_preview) (MetaPlugin *plugin);
void (*show_window_menu) (MetaPlugin *plugin,
MetaWindow *window,
MetaWindowMenuType menu,
int x,
int y);
/**
* MetaPluginClass::kill_window_effects:
* @actor: a #MetaWindowActor

View File

@ -2,10 +2,10 @@
/* Mutter preferences */
/*
/*
* Copyright (C) 2001 Havoc Pennington
* Copyright (C) 2006 Elijah Newren
*
*
* 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
@ -15,7 +15,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*/
@ -141,6 +141,7 @@ gboolean meta_prefs_get_gnome_animations (void);
gboolean meta_prefs_get_edge_tiling (void);
gboolean meta_prefs_get_auto_maximize (void);
gboolean meta_prefs_get_center_new_windows (void);
gboolean meta_prefs_get_show_fallback_app_menu (void);
void meta_prefs_get_button_layout (MetaButtonLayout *button_layout);
@ -171,95 +172,95 @@ void meta_prefs_set_ignore_request_hide_titlebar (gboolean whether);
/**
* MetaKeyBindingAction:
* @META_KEYBINDING_ACTION_NONE: FILLME
* @META_KEYBINDING_ACTION_WORKSPACE_1: FILLME
* @META_KEYBINDING_ACTION_WORKSPACE_2: FILLME
* @META_KEYBINDING_ACTION_WORKSPACE_3: FILLME
* @META_KEYBINDING_ACTION_WORKSPACE_4: FILLME
* @META_KEYBINDING_ACTION_WORKSPACE_5: FILLME
* @META_KEYBINDING_ACTION_WORKSPACE_6: FILLME
* @META_KEYBINDING_ACTION_WORKSPACE_7: FILLME
* @META_KEYBINDING_ACTION_WORKSPACE_8: FILLME
* @META_KEYBINDING_ACTION_WORKSPACE_9: FILLME
* @META_KEYBINDING_ACTION_WORKSPACE_10: FILLME
* @META_KEYBINDING_ACTION_WORKSPACE_11: FILLME
* @META_KEYBINDING_ACTION_WORKSPACE_12: FILLME
* @META_KEYBINDING_ACTION_WORKSPACE_LEFT: FILLME
* @META_KEYBINDING_ACTION_WORKSPACE_RIGHT: FILLME
* @META_KEYBINDING_ACTION_WORKSPACE_UP: FILLME
* @META_KEYBINDING_ACTION_WORKSPACE_DOWN: FILLME
* @META_KEYBINDING_ACTION_WORKSPACE_LAST: FILLME
* @META_KEYBINDING_ACTION_SWITCH_APPLICATIONS: FILLME
* @META_KEYBINDING_ACTION_SWITCH_APPLICATIONS_BACKWARD: FILLME
* @META_KEYBINDING_ACTION_SWITCH_GROUP: FILLME
* @META_KEYBINDING_ACTION_SWITCH_GROUP_BACKWARD: FILLME
* @META_KEYBINDING_ACTION_SWITCH_WINDOWS: FILLME
* @META_KEYBINDING_ACTION_SWITCH_WINDOWS_BACKWARD: FILLME
* @META_KEYBINDING_ACTION_SWITCH_PANELS: FILLME
* @META_KEYBINDING_ACTION_SWITCH_PANELS_BACKWARD: FILLME
* @META_KEYBINDING_ACTION_CYCLE_GROUP: FILLME
* @META_KEYBINDING_ACTION_CYCLE_GROUP_BACKWARD: FILLME
* @META_KEYBINDING_ACTION_CYCLE_WINDOWS: FILLME
* @META_KEYBINDING_ACTION_CYCLE_WINDOWS_BACKWARD: FILLME
* @META_KEYBINDING_ACTION_CYCLE_PANELS: FILLME
* @META_KEYBINDING_ACTION_CYCLE_PANELS_BACKWARD: FILLME
* @META_KEYBINDING_ACTION_SHOW_DESKTOP: FILLME
* @META_KEYBINDING_ACTION_PANEL_MAIN_MENU: FILLME
* @META_KEYBINDING_ACTION_PANEL_RUN_DIALOG: FILLME
* @META_KEYBINDING_ACTION_TOGGLE_RECORDING: FILLME
* @META_KEYBINDING_ACTION_SET_SPEW_MARK: FILLME
* @META_KEYBINDING_ACTION_ACTIVATE_WINDOW_MENU: FILLME
* @META_KEYBINDING_ACTION_TOGGLE_FULLSCREEN: FILLME
* @META_KEYBINDING_ACTION_TOGGLE_MAXIMIZED: FILLME
* @META_KEYBINDING_ACTION_TOGGLE_TILED_LEFT: FILLME
* @META_KEYBINDING_ACTION_TOGGLE_TILED_RIGHT: FILLME
* @META_KEYBINDING_ACTION_TOGGLE_ABOVE: FILLME
* @META_KEYBINDING_ACTION_MAXIMIZE: FILLME
* @META_KEYBINDING_ACTION_UNMAXIMIZE: FILLME
* @META_KEYBINDING_ACTION_TOGGLE_SHADED: FILLME
* @META_KEYBINDING_ACTION_MINIMIZE: FILLME
* @META_KEYBINDING_ACTION_CLOSE: FILLME
* @META_KEYBINDING_ACTION_BEGIN_MOVE: FILLME
* @META_KEYBINDING_ACTION_BEGIN_RESIZE: FILLME
* @META_KEYBINDING_ACTION_TOGGLE_ON_ALL_WORKSPACES: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_1: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_2: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_3: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_4: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_5: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_6: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_7: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_8: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_9: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_10: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_11: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_12: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_LEFT: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_RIGHT: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_UP: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_DOWN: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_LAST: FILLME
* @META_KEYBINDING_ACTION_NONE: FILLME
* @META_KEYBINDING_ACTION_WORKSPACE_1: FILLME
* @META_KEYBINDING_ACTION_WORKSPACE_2: FILLME
* @META_KEYBINDING_ACTION_WORKSPACE_3: FILLME
* @META_KEYBINDING_ACTION_WORKSPACE_4: FILLME
* @META_KEYBINDING_ACTION_WORKSPACE_5: FILLME
* @META_KEYBINDING_ACTION_WORKSPACE_6: FILLME
* @META_KEYBINDING_ACTION_WORKSPACE_7: FILLME
* @META_KEYBINDING_ACTION_WORKSPACE_8: FILLME
* @META_KEYBINDING_ACTION_WORKSPACE_9: FILLME
* @META_KEYBINDING_ACTION_WORKSPACE_10: FILLME
* @META_KEYBINDING_ACTION_WORKSPACE_11: FILLME
* @META_KEYBINDING_ACTION_WORKSPACE_12: FILLME
* @META_KEYBINDING_ACTION_WORKSPACE_LEFT: FILLME
* @META_KEYBINDING_ACTION_WORKSPACE_RIGHT: FILLME
* @META_KEYBINDING_ACTION_WORKSPACE_UP: FILLME
* @META_KEYBINDING_ACTION_WORKSPACE_DOWN: FILLME
* @META_KEYBINDING_ACTION_WORKSPACE_LAST: FILLME
* @META_KEYBINDING_ACTION_SWITCH_APPLICATIONS: FILLME
* @META_KEYBINDING_ACTION_SWITCH_APPLICATIONS_BACKWARD: FILLME
* @META_KEYBINDING_ACTION_SWITCH_GROUP: FILLME
* @META_KEYBINDING_ACTION_SWITCH_GROUP_BACKWARD: FILLME
* @META_KEYBINDING_ACTION_SWITCH_WINDOWS: FILLME
* @META_KEYBINDING_ACTION_SWITCH_WINDOWS_BACKWARD: FILLME
* @META_KEYBINDING_ACTION_SWITCH_PANELS: FILLME
* @META_KEYBINDING_ACTION_SWITCH_PANELS_BACKWARD: FILLME
* @META_KEYBINDING_ACTION_CYCLE_GROUP: FILLME
* @META_KEYBINDING_ACTION_CYCLE_GROUP_BACKWARD: FILLME
* @META_KEYBINDING_ACTION_CYCLE_WINDOWS: FILLME
* @META_KEYBINDING_ACTION_CYCLE_WINDOWS_BACKWARD: FILLME
* @META_KEYBINDING_ACTION_CYCLE_PANELS: FILLME
* @META_KEYBINDING_ACTION_CYCLE_PANELS_BACKWARD: FILLME
* @META_KEYBINDING_ACTION_SHOW_DESKTOP: FILLME
* @META_KEYBINDING_ACTION_PANEL_MAIN_MENU: FILLME
* @META_KEYBINDING_ACTION_PANEL_RUN_DIALOG: FILLME
* @META_KEYBINDING_ACTION_TOGGLE_RECORDING: FILLME
* @META_KEYBINDING_ACTION_SET_SPEW_MARK: FILLME
* @META_KEYBINDING_ACTION_ACTIVATE_WINDOW_MENU: FILLME
* @META_KEYBINDING_ACTION_TOGGLE_FULLSCREEN: FILLME
* @META_KEYBINDING_ACTION_TOGGLE_MAXIMIZED: FILLME
* @META_KEYBINDING_ACTION_TOGGLE_TILED_LEFT: FILLME
* @META_KEYBINDING_ACTION_TOGGLE_TILED_RIGHT: FILLME
* @META_KEYBINDING_ACTION_TOGGLE_ABOVE: FILLME
* @META_KEYBINDING_ACTION_MAXIMIZE: FILLME
* @META_KEYBINDING_ACTION_UNMAXIMIZE: FILLME
* @META_KEYBINDING_ACTION_TOGGLE_SHADED: FILLME
* @META_KEYBINDING_ACTION_MINIMIZE: FILLME
* @META_KEYBINDING_ACTION_CLOSE: FILLME
* @META_KEYBINDING_ACTION_BEGIN_MOVE: FILLME
* @META_KEYBINDING_ACTION_BEGIN_RESIZE: FILLME
* @META_KEYBINDING_ACTION_TOGGLE_ON_ALL_WORKSPACES: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_1: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_2: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_3: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_4: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_5: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_6: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_7: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_8: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_9: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_10: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_11: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_12: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_LEFT: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_RIGHT: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_UP: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_DOWN: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_LAST: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_MONITOR_LEFT: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_MONITOR_RIGHT: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_MONITOR_UP: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_MONITOR_DOWN: FILLME
* @META_KEYBINDING_ACTION_RAISE_OR_LOWER: FILLME
* @META_KEYBINDING_ACTION_RAISE: FILLME
* @META_KEYBINDING_ACTION_LOWER: FILLME
* @META_KEYBINDING_ACTION_MAXIMIZE_VERTICALLY: FILLME
* @META_KEYBINDING_ACTION_MAXIMIZE_HORIZONTALLY: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_CORNER_NW: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_CORNER_NE: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_CORNER_SW: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_CORNER_SE: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_SIDE_N: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_SIDE_S: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_SIDE_E: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_SIDE_W: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_CENTER: FILLME
* @META_KEYBINDING_ACTION_OVERLAY_KEY: FILLME
* @META_KEYBINDING_ACTION_ALWAYS_ON_TOP: FILLME
* @META_KEYBINDING_ACTION_LAST: FILLME
* @META_KEYBINDING_ACTION_RAISE_OR_LOWER: FILLME
* @META_KEYBINDING_ACTION_RAISE: FILLME
* @META_KEYBINDING_ACTION_LOWER: FILLME
* @META_KEYBINDING_ACTION_MAXIMIZE_VERTICALLY: FILLME
* @META_KEYBINDING_ACTION_MAXIMIZE_HORIZONTALLY: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_CORNER_NW: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_CORNER_NE: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_CORNER_SW: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_CORNER_SE: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_SIDE_N: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_SIDE_S: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_SIDE_E: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_SIDE_W: FILLME
* @META_KEYBINDING_ACTION_MOVE_TO_CENTER: FILLME
* @META_KEYBINDING_ACTION_OVERLAY_KEY: FILLME
* @META_KEYBINDING_ACTION_ALWAYS_ON_TOP: FILLME
* @META_KEYBINDING_ACTION_LAST: FILLME
*/
/* XXX FIXME This should be x-macroed, but isn't yet because it would be
* difficult (or perhaps impossible) to add the suffixes using the current
@ -399,10 +400,6 @@ GType meta_key_binding_get_type (void);
MetaKeyBindingAction meta_prefs_get_keybinding_action (const char *name);
void meta_prefs_get_window_binding (const char *name,
unsigned int *keysym,
MetaVirtualModifier *modifiers);
gboolean meta_prefs_get_visual_bell (void);
gboolean meta_prefs_bell_is_audible (void);
GDesktopVisualBellType meta_prefs_get_visual_bell_type (void);

View File

@ -2,9 +2,9 @@
/* Metacity Theme Rendering */
/*
/*
* Copyright (C) 2001 Havoc Pennington
*
*
* 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
@ -14,7 +14,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*/

View File

@ -2,10 +2,10 @@
/* Mutter utilities */
/*
/*
* Copyright (C) 2001 Havoc Pennington
* Copyright (C) 2005 Elijah Newren
*
*
* 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
@ -15,7 +15,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*/

View File

@ -108,7 +108,6 @@ gboolean meta_window_appears_focused (MetaWindow *window);
gboolean meta_window_is_shaded (MetaWindow *window);
gboolean meta_window_is_override_redirect (MetaWindow *window);
gboolean meta_window_is_skip_taskbar (MetaWindow *window);
MetaRectangle *meta_window_get_rect (MetaWindow *window);
void meta_window_get_input_rect (const MetaWindow *window, MetaRectangle *rect);
void meta_window_get_frame_rect (const MetaWindow *window, MetaRectangle *rect);
@ -140,6 +139,7 @@ const char * meta_window_get_wm_class (MetaWindow *window);
const char * meta_window_get_wm_class_instance (MetaWindow *window);
gboolean meta_window_showing_on_its_workspace (MetaWindow *window);
const char * meta_window_get_gtk_theme_variant (MetaWindow *window);
const char * meta_window_get_gtk_application_id (MetaWindow *window);
const char * meta_window_get_gtk_unique_bus_name (MetaWindow *window);
const char * meta_window_get_gtk_application_object_path (MetaWindow *window);
@ -151,7 +151,6 @@ void meta_window_move(MetaWindow *window, gboolean user_op, int root_x_nw, int r
void meta_window_move_frame(MetaWindow *window, gboolean user_op, int root_x_nw, int root_y_nw);
void meta_window_move_resize_frame (MetaWindow *window, gboolean user_op, int root_x_nw, int root_y_nw, int w, int h);
void meta_window_move_to_monitor (MetaWindow *window, int monitor);
void meta_window_resize(MetaWindow *window, gboolean user_op, int w, int h);
void meta_window_set_demands_attention (MetaWindow *window);
void meta_window_unset_demands_attention (MetaWindow *window);

View File

@ -1,7 +1,7 @@
[Desktop Entry]
Type=Application
_Name=Mutter (wayland compositor)
Exec=mutter-launch -- mutter --wayland --display-server
Exec=mutter --wayland --display-server
NoDisplay=true
# name of loadable control center module
X-GNOME-WMSettingsModule=metacity

View File

@ -0,0 +1,44 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.freedesktop.login1.Session">
<property name="Active" type="b" access="read" />
<method name="Activate">
</method>
<method name="TakeControl">
<arg name="force" type="b"/>
</method>
<method name="TakeDevice">
<annotation name="org.gtk.GDBus.C.UnixFD" value="true"/>
<arg name="major" type="u" direction="in"/>
<arg name="minor" type="u" direction="in"/>
<arg name="fd" type="h" direction="out"/>
<arg name="paused" type="b" direction="out"/>
</method>
<method name="ReleaseDevice">
<arg name="major" type="u"/>
<arg name="minor" type="u"/>
</method>
<method name="PauseDeviceComplete">
<arg name="major" type="u"/>
<arg name="minor" type="u"/>
</method>
<signal name="PauseDevice">
<arg name="major" type="u"/>
<arg name="minor" type="u"/>
<arg name="type" type="s"/>
</signal>
<signal name="ResumeDevice">
<arg name="major" type="u"/>
<arg name="minor" type="u"/>
<arg name="fd" type="h"/>
</signal>
</interface>
<interface name="org.freedesktop.login1.Seat">
<method name="SwitchTo">
<arg name="vt" type="u"/>
</method>
</interface>
</node>

View File

@ -2,11 +2,11 @@
/* Metacity window frame manager widget */
/*
/*
* Copyright (C) 2001 Havoc Pennington
* Copyright (C) 2003 Red Hat, Inc.
* Copyright (C) 2005, 2006 Elijah Newren
*
*
* 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
@ -16,7 +16,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*/
@ -28,7 +28,6 @@
#include "frames.h"
#include <meta/util.h>
#include "core.h"
#include "menu.h"
#include <meta/theme.h>
#include <meta/prefs.h>
#include "ui.h"
@ -129,7 +128,7 @@ meta_frames_class_init (MetaFramesClass *class)
widget_class->style_updated = meta_frames_style_updated;
widget_class->draw = meta_frames_draw;
widget_class->destroy_event = meta_frames_destroy_event;
widget_class->destroy_event = meta_frames_destroy_event;
widget_class->button_press_event = meta_frames_button_press_event;
widget_class->button_release_event = meta_frames_button_release_event;
widget_class->motion_notify_event = meta_frames_motion_notify_event;
@ -217,7 +216,7 @@ static void
meta_frames_init (MetaFrames *frames)
{
frames->text_heights = g_hash_table_new (NULL, NULL);
frames->frames = g_hash_table_new (unsigned_long_hash, unsigned_long_equal);
frames->style_variants = g_hash_table_new_full (g_str_hash, g_str_equal,
@ -245,7 +244,7 @@ meta_frames_destroy (GtkWidget *object)
GSList *winlist;
GSList *tmp;
MetaFrames *frames;
frames = META_FRAMES (object);
winlist = NULL;
@ -281,13 +280,13 @@ static void
meta_frames_finalize (GObject *object)
{
MetaFrames *frames;
frames = META_FRAMES (object);
meta_prefs_remove_listener (prefs_changed_callback, frames);
g_hash_table_destroy (frames->text_heights);
g_assert (g_hash_table_size (frames->frames) == 0);
g_hash_table_destroy (frames->frames);
@ -308,7 +307,7 @@ queue_recalc_func (gpointer key, gpointer value, gpointer data)
* in case of color change.
*/
meta_frames_set_window_background (frames, frame);
invalidate_whole_window (frames, frame);
meta_core_queue_frame_resize (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
frame->xwindow);
@ -316,7 +315,7 @@ queue_recalc_func (gpointer key, gpointer value, gpointer data)
{
/* save title to recreate layout */
g_free (frame->title);
frame->title = g_strdup (pango_layout_get_text (frame->layout));
g_object_unref (G_OBJECT (frame->layout));
@ -332,7 +331,7 @@ meta_frames_font_changed (MetaFrames *frames)
g_hash_table_destroy (frames->text_heights);
frames->text_heights = g_hash_table_new (NULL, NULL);
}
/* Queue a draw/resize on all frames */
g_hash_table_foreach (frames->frames,
queue_recalc_func, frames);
@ -405,7 +404,7 @@ meta_frames_ensure_layout (MetaFrames *frames,
widget = GTK_WIDGET (frames);
g_return_if_fail (gtk_widget_get_realized (widget));
meta_core_get (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), frame->xwindow,
META_CORE_GET_FRAME_FLAGS, &flags,
META_CORE_GET_FRAME_TYPE, &type,
@ -420,7 +419,7 @@ meta_frames_ensure_layout (MetaFrames *frames,
{
/* save title to recreate layout */
g_free (frame->title);
frame->title = g_strdup (pango_layout_get_text (frame->layout));
g_object_unref (G_OBJECT (frame->layout));
@ -429,18 +428,18 @@ meta_frames_ensure_layout (MetaFrames *frames,
}
frame->cache_style = style;
if (frame->layout == NULL)
{
gpointer key, value;
PangoFontDescription *font_desc;
double scale;
int size;
scale = meta_theme_get_title_scale (meta_theme_get_current (),
type,
flags);
frame->layout = gtk_widget_create_pango_layout (widget, frame->title);
pango_layout_set_ellipsize (frame->layout, PANGO_ELLIPSIZE_END);
@ -468,10 +467,10 @@ meta_frames_ensure_layout (MetaFrames *frames,
GINT_TO_POINTER (size),
GINT_TO_POINTER (frame->text_height));
}
pango_layout_set_font_description (frame->layout,
pango_layout_set_font_description (frame->layout,
font_desc);
pango_font_description_free (font_desc);
/* Save some RAM */
@ -489,7 +488,7 @@ meta_frames_calc_geometry (MetaFrames *frames,
MetaFrameFlags flags;
MetaFrameType type;
MetaButtonLayout button_layout;
meta_core_get (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), frame->xwindow,
META_CORE_GET_CLIENT_WIDTH, &width,
META_CORE_GET_CLIENT_HEIGHT, &height,
@ -500,7 +499,7 @@ meta_frames_calc_geometry (MetaFrames *frames,
meta_frames_ensure_layout (frames, frame);
meta_prefs_get_button_layout (&button_layout);
meta_theme_calc_geometry (meta_theme_get_current (),
type,
frame->text_height,
@ -575,7 +574,7 @@ meta_frames_manage_window (MetaFrames *frames,
g_assert (window);
frame = g_new (MetaUIFrame, 1);
frame->window = window;
gdk_window_set_user_data (frame->window, frames);
@ -583,7 +582,7 @@ meta_frames_manage_window (MetaFrames *frames,
frame->style = NULL;
/* Don't set event mask here, it's in frame.c */
frame->xwindow = xwindow;
frame->cache_style = NULL;
frame->layout = NULL;
@ -596,9 +595,9 @@ meta_frames_manage_window (MetaFrames *frames,
* registered with its MetaWindow, which happens after this function
* and meta_ui_create_frame_window() return to meta_window_ensure_frame().
*/
meta_core_grab_buttons (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), frame->xwindow);
g_hash_table_replace (frames->frames, &frame->xwindow, frame);
}
@ -621,7 +620,7 @@ meta_frames_unmanage_window (MetaFrames *frames,
if (frames->last_motion_frame == frame)
frames->last_motion_frame = NULL;
g_hash_table_remove (frames->frames, &frame->xwindow);
g_object_unref (frame->style);
@ -633,7 +632,7 @@ meta_frames_unmanage_window (MetaFrames *frames,
if (frame->title)
g_free (frame->title);
g_free (frame);
}
else
@ -667,7 +666,7 @@ meta_ui_frame_get_borders (MetaFrames *frames,
g_return_if_fail (type < META_FRAME_TYPE_LAST);
meta_frames_ensure_layout (frames, frame);
/* We can't get the full geometry, because that depends on
* the client window size and probably we're being called
* by the core move/resize code to decide on the client
@ -731,7 +730,7 @@ meta_frames_reset_bg (MetaFrames *frames,
Window xwindow)
{
MetaUIFrame *frame;
frame = meta_frames_lookup_window (frames, xwindow);
meta_frames_set_window_background (frames, frame);
@ -755,7 +754,7 @@ meta_frames_unflicker_bg (MetaFrames *frames,
int target_height)
{
MetaUIFrame *frame;
frame = meta_frames_lookup_window (frames, xwindow);
g_return_if_fail (frame != NULL);
@ -807,7 +806,7 @@ get_visible_region (MetaFrames *frames,
corners_region = cairo_region_create ();
get_visible_frame_rect (fgeom, window_width, window_height, &frame_rect);
if (fgeom->top_left_corner_rounded_radius != 0)
{
const int corner = fgeom->top_left_corner_rounded_radius;
@ -821,7 +820,7 @@ get_visible_region (MetaFrames *frames,
rect.y = frame_rect.y + i;
rect.width = width;
rect.height = 1;
cairo_region_union_rectangle (corners_region, &rect);
}
}
@ -839,7 +838,7 @@ get_visible_region (MetaFrames *frames,
rect.y = frame_rect.y + i;
rect.width = width;
rect.height = 1;
cairo_region_union_rectangle (corners_region, &rect);
}
}
@ -857,7 +856,7 @@ get_visible_region (MetaFrames *frames,
rect.y = frame_rect.y + frame_rect.height - i - 1;
rect.width = width;
rect.height = 1;
cairo_region_union_rectangle (corners_region, &rect);
}
}
@ -875,11 +874,11 @@ get_visible_region (MetaFrames *frames,
rect.y = frame_rect.y + frame_rect.height - i - 1;
rect.width = width;
rect.height = 1;
cairo_region_union_rectangle (corners_region, &rect);
}
}
visible_region = cairo_region_create_rectangle (&frame_rect);
cairo_region_subtract (visible_region, corners_region);
cairo_region_destroy (corners_region);
@ -916,7 +915,7 @@ meta_frames_move_resize_frame (MetaFrames *frames,
{
MetaUIFrame *frame = meta_frames_lookup_window (frames, xwindow);
int old_width, old_height;
old_width = gdk_window_get_width (frame->window);
old_height = gdk_window_get_height (frame->window);
@ -931,7 +930,7 @@ meta_frames_queue_draw (MetaFrames *frames,
Window xwindow)
{
MetaUIFrame *frame;
frame = meta_frames_lookup_window (frames, xwindow);
invalidate_whole_window (frames, frame);
@ -943,14 +942,14 @@ meta_frames_set_title (MetaFrames *frames,
const char *title)
{
MetaUIFrame *frame;
frame = meta_frames_lookup_window (frames, xwindow);
g_assert (frame);
g_free (frame->title);
frame->title = g_strdup (title);
if (frame->layout)
{
g_object_unref (frame->layout);
@ -979,7 +978,7 @@ meta_frames_repaint_frame (MetaFrames *frames,
Window xwindow)
{
MetaUIFrame *frame;
frame = meta_frames_lookup_window (frames, xwindow);
g_assert (frame);
@ -997,7 +996,7 @@ redraw_control (MetaFrames *frames,
{
MetaFrameGeometry fgeom;
GdkRectangle *rect;
meta_frames_calc_geometry (frames, frame, &fgeom);
rect = control_rect (control, &fgeom);
@ -1014,7 +1013,7 @@ meta_frame_titlebar_event (MetaUIFrame *frame,
Display *display;
display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
switch (action)
{
case G_DESKTOP_TITLEBAR_ACTION_TOGGLE_SHADE:
@ -1022,7 +1021,7 @@ meta_frame_titlebar_event (MetaUIFrame *frame,
meta_core_get (display, frame->xwindow,
META_CORE_GET_FRAME_FLAGS, &flags,
META_CORE_GET_END);
if (flags & META_FRAME_ALLOWS_SHADE)
{
if (flags & META_FRAME_SHADED)
@ -1035,14 +1034,14 @@ meta_frame_titlebar_event (MetaUIFrame *frame,
event->time);
}
}
break;
break;
case G_DESKTOP_TITLEBAR_ACTION_TOGGLE_MAXIMIZE:
{
meta_core_get (display, frame->xwindow,
META_CORE_GET_FRAME_FLAGS, &flags,
META_CORE_GET_END);
if (flags & META_FRAME_ALLOWS_MAXIMIZE)
{
meta_core_toggle_maximize (display, frame->xwindow);
@ -1055,7 +1054,7 @@ meta_frame_titlebar_event (MetaUIFrame *frame,
meta_core_get (display, frame->xwindow,
META_CORE_GET_FRAME_FLAGS, &flags,
META_CORE_GET_END);
if (flags & META_FRAME_ALLOWS_MAXIMIZE)
{
meta_core_toggle_maximize_horizontally (display, frame->xwindow);
@ -1068,7 +1067,7 @@ meta_frame_titlebar_event (MetaUIFrame *frame,
meta_core_get (display, frame->xwindow,
META_CORE_GET_FRAME_FLAGS, &flags,
META_CORE_GET_END);
if (flags & META_FRAME_ALLOWS_MAXIMIZE)
{
meta_core_toggle_maximize_vertically (display, frame->xwindow);
@ -1081,7 +1080,7 @@ meta_frame_titlebar_event (MetaUIFrame *frame,
meta_core_get (display, frame->xwindow,
META_CORE_GET_FRAME_FLAGS, &flags,
META_CORE_GET_END);
if (flags & META_FRAME_ALLOWS_MINIMIZE)
{
meta_core_minimize (display, frame->xwindow);
@ -1092,7 +1091,7 @@ meta_frame_titlebar_event (MetaUIFrame *frame,
case G_DESKTOP_TITLEBAR_ACTION_NONE:
/* Yaay, a sane user that doesn't use that other weird crap! */
break;
case G_DESKTOP_TITLEBAR_ACTION_LOWER:
meta_core_user_lower_and_unfocus (display,
frame->xwindow,
@ -1102,13 +1101,13 @@ meta_frame_titlebar_event (MetaUIFrame *frame,
case G_DESKTOP_TITLEBAR_ACTION_MENU:
meta_core_show_window_menu (display,
frame->xwindow,
META_WINDOW_MENU_WM,
event->x_root,
event->y_root,
event->button,
event->time);
break;
}
return TRUE;
}
@ -1117,7 +1116,7 @@ meta_frame_double_click_event (MetaUIFrame *frame,
GdkEventButton *event)
{
int action = meta_prefs_get_action_double_click_titlebar ();
return meta_frame_titlebar_event (frame, event, action);
}
@ -1126,7 +1125,7 @@ meta_frame_middle_click_event (MetaUIFrame *frame,
GdkEventButton *event)
{
int action = meta_prefs_get_action_middle_click_titlebar();
return meta_frame_titlebar_event (frame, event, action);
}
@ -1135,7 +1134,7 @@ meta_frame_right_click_event(MetaUIFrame *frame,
GdkEventButton *event)
{
int action = meta_prefs_get_action_right_click_titlebar();
return meta_frame_titlebar_event (frame, event, action);
}
@ -1147,14 +1146,14 @@ meta_frames_button_press_event (GtkWidget *widget,
MetaFrames *frames;
MetaFrameControl control;
Display *display;
frames = META_FRAMES (widget);
display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
/* Remember that the display may have already done something with this event.
* If so there's probably a GrabOp in effect.
*/
frame = meta_frames_lookup_window (frames, GDK_WINDOW_XID (event->window));
if (frame == NULL)
return FALSE;
@ -1172,13 +1171,13 @@ meta_frames_button_press_event (GtkWidget *widget,
frame->xwindow);
meta_core_user_focus (display,
frame->xwindow,
event->time);
event->time);
}
/* don't do the rest of this if on client area */
if (control == META_FRAME_CONTROL_CLIENT_AREA)
return FALSE; /* not on the frame, just passed through from client */
/* We want to shade even if we have a GrabOp, since we'll have a move grab
* if we double click the titlebar.
*/
@ -1191,7 +1190,7 @@ meta_frames_button_press_event (GtkWidget *widget,
}
if (meta_core_get_grab_op (display) != META_GRAB_OP_NONE)
return FALSE; /* already up to something */
return FALSE; /* already up to something */
if (event->button == 1 &&
(control == META_FRAME_CONTROL_MAXIMIZE ||
@ -1204,7 +1203,8 @@ meta_frames_button_press_event (GtkWidget *widget,
control == META_FRAME_CONTROL_UNABOVE ||
control == META_FRAME_CONTROL_STICK ||
control == META_FRAME_CONTROL_UNSTICK ||
control == META_FRAME_CONTROL_MENU))
control == META_FRAME_CONTROL_MENU ||
control == META_FRAME_CONTROL_APPMENU))
{
frames->grab_xwindow = frame->xwindow;
@ -1213,29 +1213,34 @@ meta_frames_button_press_event (GtkWidget *widget,
frame->prelit_control = control;
redraw_control (frames, frame, control);
if (control == META_FRAME_CONTROL_MENU)
if (control == META_FRAME_CONTROL_MENU ||
control == META_FRAME_CONTROL_APPMENU)
{
MetaFrameGeometry fgeom;
GdkRectangle *rect;
MetaWindowMenuType menu;
int dx, dy;
meta_frames_calc_geometry (frames, frame, &fgeom);
rect = control_rect (META_FRAME_CONTROL_MENU, &fgeom);
rect = control_rect (control, &fgeom);
/* get delta to convert to root coords */
dx = event->x_root - event->x;
dy = event->y_root - event->y;
/* Align to the right end of the menu rectangle if RTL */
if (meta_ui_get_direction() == META_UI_DIRECTION_RTL)
dx += rect->width;
menu = control == META_FRAME_CONTROL_MENU ? META_WINDOW_MENU_WM
: META_WINDOW_MENU_APP;
meta_core_show_window_menu (display,
frame->xwindow,
menu,
rect->x + dx,
rect->y + rect->height + dy,
event->button,
event->time);
}
}
@ -1250,7 +1255,7 @@ meta_frames_button_press_event (GtkWidget *widget,
control == META_FRAME_CONTROL_RESIZE_W))
{
MetaGrabOp op;
op = META_GRAB_OP_NONE;
switch (control)
@ -1305,7 +1310,7 @@ meta_frames_button_press_event (GtkWidget *widget,
META_CORE_GET_END);
if (flags & META_FRAME_ALLOWS_MOVE)
{
{
meta_core_begin_grab_op (display,
frame->xwindow,
META_GRAB_OP_MOVING,
@ -1326,7 +1331,7 @@ meta_frames_button_press_event (GtkWidget *widget,
{
return meta_frame_right_click_event (frame, event);
}
return TRUE;
}
@ -1337,7 +1342,7 @@ meta_frames_button_release_event (GtkWidget *widget,
MetaUIFrame *frame;
MetaFrames *frames;
Display *display;
frames = META_FRAMES (widget);
display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
@ -1360,7 +1365,7 @@ meta_frames_button_release_event (GtkWidget *widget,
break;
case META_FRAME_CONTROL_MAXIMIZE:
/* Focus the window on the maximize */
meta_core_user_focus (display, frame->xwindow, event->time);
meta_core_user_focus (display, frame->xwindow, event->time);
meta_core_maximize (display, frame->xwindow);
break;
case META_FRAME_CONTROL_UNMAXIMIZE:
@ -1399,7 +1404,7 @@ meta_frames_button_release_event (GtkWidget *widget,
MetaFrameControl control = get_control (frames, frame, event->x, event->y);
meta_frames_update_prelit_control (frames, frame, control);
}
return TRUE;
}
@ -1413,9 +1418,9 @@ meta_frames_update_prelit_control (MetaFrames *frames,
meta_verbose ("Updating prelit control from %u to %u\n",
frame->prelit_control, control);
cursor = META_CURSOR_DEFAULT;
switch (control)
{
case META_FRAME_CONTROL_CLIENT_AREA:
@ -1428,6 +1433,8 @@ meta_frames_update_prelit_control (MetaFrames *frames,
break;
case META_FRAME_CONTROL_MENU:
break;
case META_FRAME_CONTROL_APPMENU:
break;
case META_FRAME_CONTROL_MINIMIZE:
break;
case META_FRAME_CONTROL_MAXIMIZE:
@ -1470,16 +1477,17 @@ meta_frames_update_prelit_control (MetaFrames *frames,
case META_FRAME_CONTROL_RESIZE_E:
cursor = META_CURSOR_EAST_RESIZE;
break;
}
}
/* set/unset the prelight cursor */
meta_core_set_screen_cursor (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
frame->xwindow,
cursor);
cursor);
switch (control)
{
case META_FRAME_CONTROL_MENU:
case META_FRAME_CONTROL_APPMENU:
case META_FRAME_CONTROL_MINIMIZE:
case META_FRAME_CONTROL_MAXIMIZE:
case META_FRAME_CONTROL_DELETE:
@ -1496,7 +1504,7 @@ meta_frames_update_prelit_control (MetaFrames *frames,
/* Only prelight buttons */
control = META_FRAME_CONTROL_NONE;
break;
}
}
if (control == frame->prelit_control)
return;
@ -1546,7 +1554,7 @@ meta_frames_motion_notify_event (GtkWidget *widget,
/* Update prelit control and cursor */
meta_frames_update_prelit_control (frames, frame, control);
}
return TRUE;
}
@ -1562,7 +1570,7 @@ meta_frames_destroy_event (GtkWidget *widget,
frame = meta_frames_lookup_window (frames, GDK_WINDOW_XID (event->window));
if (frame == NULL)
return FALSE;
return TRUE;
}
@ -1600,7 +1608,7 @@ clip_region_to_visible_frame_border (cairo_region_t *region,
MetaFrameBorders borders;
Display *display;
int frame_width, frame_height;
display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
meta_core_get (display, frame->xwindow,
@ -1611,7 +1619,7 @@ clip_region_to_visible_frame_border (cairo_region_t *region,
META_CORE_GET_END);
meta_theme_get_frame_borders (meta_theme_get_current (),
type, frame->text_height, flags,
type, frame->text_height, flags,
&borders);
/* Visible frame rect */
@ -1768,7 +1776,7 @@ meta_frames_draw (GtkWidget *widget,
out:
cairo_region_destroy (region);
return TRUE;
}
@ -1792,13 +1800,16 @@ meta_frames_paint (MetaFrames *frames,
for (i = 0; i < META_BUTTON_TYPE_LAST; i++)
button_states[i] = META_BUTTON_STATE_NORMAL;
/* Set prelight state */
switch (frame->prelit_control)
{
case META_FRAME_CONTROL_MENU:
button_type = META_BUTTON_TYPE_MENU;
break;
case META_FRAME_CONTROL_APPMENU:
button_type = META_BUTTON_TYPE_APPMENU;
break;
case META_FRAME_CONTROL_MINIMIZE:
button_type = META_BUTTON_TYPE_MINIMIZE;
break;
@ -1915,7 +1926,7 @@ meta_frames_enter_notify_event (GtkWidget *widget,
MetaUIFrame *frame;
MetaFrames *frames;
MetaFrameControl control;
frames = META_FRAMES (widget);
frame = meta_frames_lookup_window (frames, GDK_WINDOW_XID (event->window));
@ -1924,7 +1935,7 @@ meta_frames_enter_notify_event (GtkWidget *widget,
control = get_control (frames, frame, event->x, event->y);
meta_frames_update_prelit_control (frames, frame, control);
return TRUE;
}
@ -1942,7 +1953,7 @@ meta_frames_leave_notify_event (GtkWidget *widget,
return FALSE;
meta_frames_update_prelit_control (frames, frame, META_FRAME_CONTROL_NONE);
return TRUE;
}
@ -1951,7 +1962,7 @@ control_rect (MetaFrameControl control,
MetaFrameGeometry *fgeom)
{
GdkRectangle *rect;
rect = NULL;
switch (control)
{
@ -1964,6 +1975,9 @@ control_rect (MetaFrameControl control,
case META_FRAME_CONTROL_MENU:
rect = &fgeom->menu_rect.visible;
break;
case META_FRAME_CONTROL_APPMENU:
rect = &fgeom->appmenu_rect.visible;
break;
case META_FRAME_CONTROL_MINIMIZE:
rect = &fgeom->min_rect.visible;
break;
@ -2033,7 +2047,7 @@ get_control (MetaFrames *frames,
if (POINT_IN_RECT (x, y, client))
return META_FRAME_CONTROL_CLIENT_AREA;
if (POINT_IN_RECT (x, y, fgeom.close_rect.clickable))
return META_FRAME_CONTROL_DELETE;
@ -2043,6 +2057,9 @@ get_control (MetaFrames *frames,
if (POINT_IN_RECT (x, y, fgeom.menu_rect.clickable))
return META_FRAME_CONTROL_MENU;
if (POINT_IN_RECT (x, y, fgeom.appmenu_rect.clickable))
return META_FRAME_CONTROL_APPMENU;
meta_core_get (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
frame->xwindow,
META_CORE_GET_FRAME_FLAGS, &flags,
@ -2068,7 +2085,7 @@ get_control (MetaFrames *frames,
else
return META_FRAME_CONTROL_MAXIMIZE;
}
if (POINT_IN_RECT (x, y, fgeom.shade_rect.clickable))
{
return META_FRAME_CONTROL_SHADE;

View File

@ -2,9 +2,9 @@
/* Metacity window frame manager widget */
/*
/*
* Copyright (C) 2001 Havoc Pennington
*
*
* 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
@ -14,7 +14,7 @@
* 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, see <http://www.gnu.org/licenses/>.
*/
@ -33,6 +33,7 @@ typedef enum
META_FRAME_CONTROL_TITLE,
META_FRAME_CONTROL_DELETE,
META_FRAME_CONTROL_MENU,
META_FRAME_CONTROL_APPMENU,
META_FRAME_CONTROL_MINIMIZE,
META_FRAME_CONTROL_MAXIMIZE,
META_FRAME_CONTROL_UNMAXIMIZE,
@ -79,7 +80,7 @@ struct _MetaUIFrame
int text_height;
char *title; /* NULL once we have a layout */
guint shape_applied : 1;
/* FIXME get rid of this, it can just be in the MetaFrames struct */
MetaFrameControl prelit_control;
MetaButtonState button_state;
@ -89,7 +90,7 @@ struct _MetaUIFrame
struct _MetaFrames
{
GtkWindow parent_instance;
GHashTable *text_heights;
GHashTable *frames;

View File

@ -1,10 +1,10 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
/*
* Copyright (C) 2001 Havoc Pennington, 99% copied from wrlib in
* WindowMaker, Copyright (C) 1997-2000 Dan Pascu and Alfredo Kojima
* Copyright (C) 2005 Elijah Newren
*
*
* 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
@ -14,7 +14,7 @@
* 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, see <http://www.gnu.org/licenses/>. */
@ -76,7 +76,7 @@ blank_pixbuf (int width, int height, gboolean no_padding)
if (no_padding)
rowstride = width * 3;
else
/* Always align rows to 32-bit boundaries */
/* Always align rows to 32-bit boundaries */
rowstride = 4 * ((3 * width + 3) / 4);
buf = g_try_malloc (height * rowstride);
@ -194,7 +194,7 @@ meta_gradient_create_interwoven (int width,
const GdkRGBA colors2[2],
int thickness2)
{
int i, j, k, l, ll;
long r1, g1, b1, dr1, dg1, db1;
long r2, g2, b2, dr2, dg2, db2;
@ -202,14 +202,14 @@ meta_gradient_create_interwoven (int width,
unsigned char *ptr;
unsigned char *pixels;
int rowstride;
pixbuf = blank_pixbuf (width, height, FALSE);
if (pixbuf == NULL)
return NULL;
pixels = gdk_pixbuf_get_pixels (pixbuf);
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
r1 = (long)(colors1[0].red*0xffffff);
g1 = (long)(colors1[0].green*0xffffff);
b1 = (long)(colors1[0].blue*0xffffff);
@ -229,7 +229,7 @@ meta_gradient_create_interwoven (int width,
for (i=0,k=0,l=0,ll=thickness1; i<height; i++)
{
ptr = pixels + i * rowstride;
if (k == 0)
{
ptr[0] = (unsigned char) (r1>>16);
@ -264,7 +264,7 @@ meta_gradient_create_interwoven (int width,
r1+=dr1;
g1+=dg1;
b1+=db1;
r2+=dr2;
g2+=dg2;
b2+=db2;
@ -277,20 +277,20 @@ meta_gradient_create_interwoven (int width,
*----------------------------------------------------------------------
* meta_gradient_create_horizontal--
* Renders a horizontal linear gradient of the specified size in the
* GdkPixbuf format with a border of the specified type.
*
* GdkPixbuf format with a border of the specified type.
*
* Returns:
* A 24bit GdkPixbuf with the gradient (no alpha channel).
*
*
* Side effects:
* None
*----------------------------------------------------------------------
*----------------------------------------------------------------------
*/
static GdkPixbuf*
meta_gradient_create_horizontal (int width, int height,
const GdkRGBA *from,
const GdkRGBA *to)
{
{
int i;
long r, g, b, dr, dg, db;
GdkPixbuf *pixbuf;
@ -303,22 +303,22 @@ meta_gradient_create_horizontal (int width, int height,
pixbuf = blank_pixbuf (width, height, FALSE);
if (pixbuf == NULL)
return NULL;
pixels = gdk_pixbuf_get_pixels (pixbuf);
ptr = pixels;
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
r0 = (guchar) (from->red * 0xff);
g0 = (guchar) (from->green * 0xff);
b0 = (guchar) (from->blue * 0xff);
rf = (guchar) (to->red * 0xff);
gf = (guchar) (to->green * 0xff);
bf = (guchar) (to->blue * 0xff);
r = r0 << 16;
g = g0 << 16;
b = b0 << 16;
dr = ((rf-r0)<<16)/(int)width;
dg = ((gf-g0)<<16)/(int)width;
db = ((bf-b0)<<16)/(int)width;
@ -367,21 +367,21 @@ meta_gradient_create_vertical (int width, int height,
int rf, gf, bf;
int rowstride;
unsigned char *pixels;
pixbuf = blank_pixbuf (width, height, FALSE);
if (pixbuf == NULL)
return NULL;
pixels = gdk_pixbuf_get_pixels (pixbuf);
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
r0 = (guchar) (from->red * 0xff);
g0 = (guchar) (from->green * 0xff);
b0 = (guchar) (from->blue * 0xff);
rf = (guchar) (to->red * 0xff);
gf = (guchar) (to->green * 0xff);
bf = (guchar) (to->blue * 0xff);
r = r0<<16;
g = g0<<16;
b = b0<<16;
@ -393,7 +393,7 @@ meta_gradient_create_vertical (int width, int height,
for (i=0; i<height; i++)
{
ptr = pixels + i * rowstride;
ptr[0] = (unsigned char)(r>>16);
ptr[1] = (unsigned char)(g>>16);
ptr[2] = (unsigned char)(b>>16);
@ -436,7 +436,7 @@ meta_gradient_create_diagonal (int width, int height,
unsigned char *ptr;
unsigned char *pixels;
int rowstride;
if (width == 1)
return meta_gradient_create_vertical (width, height, from, to);
else if (height == 1)
@ -445,7 +445,7 @@ meta_gradient_create_diagonal (int width, int height,
pixbuf = blank_pixbuf (width, height, FALSE);
if (pixbuf == NULL)
return NULL;
pixels = gdk_pixbuf_get_pixels (pixbuf);
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
@ -483,27 +483,27 @@ meta_gradient_create_multi_horizontal (int width, int height,
GdkPixbuf *pixbuf;
unsigned char *ptr;
unsigned char *pixels;
int width2;
int width2;
int rowstride;
g_return_val_if_fail (count > 2, NULL);
pixbuf = blank_pixbuf (width, height, FALSE);
if (pixbuf == NULL)
return NULL;
pixels = gdk_pixbuf_get_pixels (pixbuf);
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
ptr = pixels;
if (count > width)
count = width;
if (count > 1)
width2 = width/(count-1);
else
width2 = width;
k = 0;
r = (long)(colors[0].red * 0xffffff);
@ -536,7 +536,7 @@ meta_gradient_create_multi_horizontal (int width, int height,
*ptr++ = (unsigned char)(g>>16);
*ptr++ = (unsigned char)(b>>16);
}
/* copy the first line to the other lines */
for (i=1; i<height; i++)
{
@ -557,25 +557,25 @@ meta_gradient_create_multi_vertical (int width, int height,
int height2;
int x;
int rowstride;
g_return_val_if_fail (count > 2, NULL);
pixbuf = blank_pixbuf (width, height, FALSE);
if (pixbuf == NULL)
return NULL;
pixels = gdk_pixbuf_get_pixels (pixbuf);
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
ptr = pixels;
if (count > height)
count = height;
if (count > 1)
height2 = height/(count-1);
else
height2 = height;
k = 0;
r = (long)(colors[0].red * 0xffffff);
@ -599,7 +599,7 @@ meta_gradient_create_multi_vertical (int width, int height,
memcpy (&(ptr[x*3]), ptr, (width - x)*3);
ptr += rowstride;
r += dr;
g += dg;
b += db;
@ -623,14 +623,14 @@ meta_gradient_create_multi_vertical (int width, int height,
memcpy (&(ptr[x*3]), ptr, (width - x)*3);
ptr += rowstride;
for (j=k+1; j<height; j++)
{
memcpy (ptr, tmp, rowstride);
ptr += rowstride;
}
}
return pixbuf;
}
@ -646,7 +646,7 @@ meta_gradient_create_multi_diagonal (int width, int height,
unsigned char *ptr;
unsigned char *pixels;
int rowstride;
g_return_val_if_fail (count > 2, NULL);
if (width == 1)
@ -658,10 +658,10 @@ meta_gradient_create_multi_diagonal (int width, int height,
width, height);
if (pixbuf == NULL)
return NULL;
pixels = gdk_pixbuf_get_pixels (pixbuf);
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
if (count > width)
count = width;
if (count > height)
@ -708,12 +708,12 @@ simple_multiply_alpha (GdkPixbuf *pixbuf,
int row;
g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
if (alpha == 255)
return;
g_assert (gdk_pixbuf_get_has_alpha (pixbuf));
pixels = gdk_pixbuf_get_pixels (pixbuf);
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
height = gdk_pixbuf_get_height (pixbuf);
@ -738,7 +738,7 @@ simple_multiply_alpha (GdkPixbuf *pixbuf,
*/
/* ((*p / 255.0) * (alpha / 255.0)) * 255; */
*p = (guchar) (((int) *p * (int) alpha) / (int) 255);
++p; /* skip A */
}
@ -755,13 +755,13 @@ meta_gradient_add_alpha_horizontal (GdkPixbuf *pixbuf,
long a, da;
unsigned char *p;
unsigned char *pixels;
int width2;
int width2;
int rowstride;
int width, height;
unsigned char *gradient;
unsigned char *gradient_p;
unsigned char *gradient_end;
g_return_if_fail (n_alphas > 0);
if (n_alphas == 1)
@ -770,24 +770,24 @@ meta_gradient_add_alpha_horizontal (GdkPixbuf *pixbuf,
simple_multiply_alpha (pixbuf, alphas[0]);
return;
}
width = gdk_pixbuf_get_width (pixbuf);
height = gdk_pixbuf_get_height (pixbuf);
gradient = g_new (unsigned char, width);
gradient_end = gradient + width;
if (n_alphas > width)
n_alphas = width;
if (n_alphas > 1)
width2 = width / (n_alphas - 1);
else
width2 = width;
a = alphas[0] << 8;
gradient_p = gradient;
/* render the gradient into an array */
for (i = 1; i < n_alphas; i++)
{
@ -796,7 +796,7 @@ meta_gradient_add_alpha_horizontal (GdkPixbuf *pixbuf,
for (j = 0; j < width2; j++)
{
*gradient_p++ = (a >> 8);
a += da;
}
@ -808,11 +808,11 @@ meta_gradient_add_alpha_horizontal (GdkPixbuf *pixbuf,
{
*gradient_p++ = a >> 8;
}
/* Now for each line of the pixbuf, fill in with the gradient */
pixels = gdk_pixbuf_get_pixels (pixbuf);
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
p = pixels;
i = 0;
while (i < height)
@ -838,7 +838,7 @@ meta_gradient_add_alpha_horizontal (GdkPixbuf *pixbuf,
p = row_end;
++i;
}
g_free (gradient);
}
@ -851,21 +851,21 @@ meta_gradient_add_alpha (GdkPixbuf *pixbuf,
g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
g_return_if_fail (gdk_pixbuf_get_has_alpha (pixbuf));
g_return_if_fail (n_alphas > 0);
switch (type)
{
case META_GRADIENT_HORIZONTAL:
meta_gradient_add_alpha_horizontal (pixbuf, alphas, n_alphas);
break;
case META_GRADIENT_VERTICAL:
g_printerr ("metacity: vertical alpha channel gradient not implemented yet\n");
break;
case META_GRADIENT_DIAGONAL:
g_printerr ("metacity: diagonal alpha channel gradient not implemented yet\n");
break;
case META_GRADIENT_LAST:
g_assert_not_reached ();
break;

View File

@ -1,516 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* Mutter window menu */
/*
* Copyright (C) 2001 Havoc Pennington
* Copyright (C) 2004 Rob Adams
* Copyright (C) 2005 Elijah Newren
*
* 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, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include <stdio.h>
#include <string.h>
#include "menu.h"
#include <meta/main.h>
#include "util-private.h"
#include "core.h"
#include "metaaccellabel.h"
#include "ui.h"
typedef struct _MenuItem MenuItem;
typedef struct _MenuData MenuData;
typedef enum
{
MENU_ITEM_SEPARATOR = 0,
MENU_ITEM_NORMAL,
MENU_ITEM_CHECKBOX,
MENU_ITEM_RADIOBUTTON,
MENU_ITEM_WORKSPACE_LIST,
} MetaMenuItemType;
struct _MenuItem
{
MetaMenuOp op;
MetaMenuItemType type;
const gboolean checked;
const char *label;
};
struct _MenuData
{
MetaWindowMenu *menu;
MetaMenuOp op;
};
static void activate_cb (GtkWidget *menuitem, gpointer data);
static MenuItem menuitems[] = {
/* Translators: Translate this string the same way as you do in libwnck! */
{ META_MENU_OP_MINIMIZE, MENU_ITEM_NORMAL, FALSE, N_("Mi_nimize") },
/* Translators: Translate this string the same way as you do in libwnck! */
{ META_MENU_OP_MAXIMIZE, MENU_ITEM_NORMAL, FALSE, N_("Ma_ximize") },
/* Translators: Translate this string the same way as you do in libwnck! */
{ META_MENU_OP_UNMAXIMIZE, MENU_ITEM_NORMAL, FALSE, N_("Unma_ximize") },
/* Translators: Translate this string the same way as you do in libwnck! */
{ META_MENU_OP_SHADE, MENU_ITEM_NORMAL, FALSE, N_("Roll _Up") },
/* Translators: Translate this string the same way as you do in libwnck! */
{ META_MENU_OP_UNSHADE, MENU_ITEM_NORMAL, FALSE, N_("_Unroll") },
/* Translators: Translate this string the same way as you do in libwnck! */
{ META_MENU_OP_MOVE, MENU_ITEM_NORMAL, FALSE, N_("_Move") },
/* Translators: Translate this string the same way as you do in libwnck! */
{ META_MENU_OP_RESIZE, MENU_ITEM_NORMAL, FALSE, N_("_Resize") },
/* Translators: Translate this string the same way as you do in libwnck! */
{ META_MENU_OP_RECOVER, MENU_ITEM_NORMAL, FALSE, N_("Move Titlebar On_screen") },
{ META_MENU_OP_WORKSPACES, MENU_ITEM_SEPARATOR, FALSE, NULL }, /* separator */
/* Translators: Translate this string the same way as you do in libwnck! */
{ META_MENU_OP_ABOVE, MENU_ITEM_CHECKBOX, FALSE, N_("Always on _Top") },
/* Translators: Translate this string the same way as you do in libwnck! */
{ META_MENU_OP_UNABOVE, MENU_ITEM_CHECKBOX, TRUE, N_("Always on _Top") },
/* Translators: Translate this string the same way as you do in libwnck! */
{ META_MENU_OP_STICK, MENU_ITEM_RADIOBUTTON, FALSE, N_("_Always on Visible Workspace") },
/* Translators: Translate this string the same way as you do in libwnck! */
{ META_MENU_OP_UNSTICK, MENU_ITEM_RADIOBUTTON, FALSE, N_("_Only on This Workspace") },
/* Translators: Translate this string the same way as you do in libwnck! */
{ META_MENU_OP_MOVE_LEFT, MENU_ITEM_NORMAL, FALSE, N_("Move to Workspace _Left") },
/* Translators: Translate this string the same way as you do in libwnck! */
{ META_MENU_OP_MOVE_RIGHT, MENU_ITEM_NORMAL, FALSE, N_("Move to Workspace R_ight") },
/* Translators: Translate this string the same way as you do in libwnck! */
{ META_MENU_OP_MOVE_UP, MENU_ITEM_NORMAL, FALSE, N_("Move to Workspace _Up") },
/* Translators: Translate this string the same way as you do in libwnck! */
{ META_MENU_OP_MOVE_DOWN, MENU_ITEM_NORMAL, FALSE, N_("Move to Workspace _Down") },
{ 0, MENU_ITEM_WORKSPACE_LIST, FALSE, NULL },
{ 0, MENU_ITEM_SEPARATOR, FALSE, NULL }, /* separator */
/* Translators: Translate this string the same way as you do in libwnck! */
{ META_MENU_OP_DELETE, MENU_ITEM_NORMAL, FALSE, N_("_Close") }
};
static void
popup_position_func (GtkMenu *menu,
gint *x,
gint *y,
gboolean *push_in,
gpointer user_data)
{
GtkRequisition req;
GdkPoint *pos;
pos = user_data;
gtk_widget_get_preferred_size (GTK_WIDGET (menu), &req, NULL);
*x = pos->x;
*y = pos->y;
if (meta_ui_get_direction() == META_UI_DIRECTION_RTL)
*x = MAX (0, *x - req.width);
/* Ensure onscreen */
*x = CLAMP (*x, 0, MAX (0, gdk_screen_width () - req.width));
*y = CLAMP (*y, 0, MAX (0, gdk_screen_height () - req.height));
}
static void
menu_closed (GtkMenu *widget,
gpointer data)
{
MetaWindowMenu *menu;
menu = data;
(* menu->func) (menu,
GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
menu->client_xwindow,
gtk_get_current_event_time (),
0, 0,
menu->data);
/* menu may now be freed */
}
static void
activate_cb (GtkWidget *menuitem, gpointer data)
{
MenuData *md;
g_return_if_fail (GTK_IS_WIDGET (menuitem));
md = data;
(* md->menu->func) (md->menu,
GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
md->menu->client_xwindow,
gtk_get_current_event_time (),
md->op,
GPOINTER_TO_INT (g_object_get_data (G_OBJECT (menuitem),
"workspace")),
md->menu->data);
/* menu may now be freed */
}
/*
* Given a Display and an index, get the workspace name and add any
* accelerators. At the moment this means adding a _ if the name is of
* the form "Workspace n" where n is less than 10, and escaping any
* other '_'s so they do not create inadvertant accelerators.
*
* The calling code owns the string, and is reponsible to free the
* memory after use.
*
* See also http://mail.gnome.org/archives/gnome-i18n/2008-March/msg00380.html
* which discusses possible i18n concerns.
*/
static char*
get_workspace_name_with_accel (Display *display,
Window xroot,
int index)
{
const char *name;
int number;
int charcount=0;
name = meta_core_get_workspace_name_with_index (display, xroot, index);
g_assert (name != NULL);
/*
* If the name is of the form "Workspace x" where x is an unsigned
* integer, insert a '_' before the number if it is less than 10 and
* return it
*/
number = 0;
if (sscanf (name, _("Workspace %d%n"), &number, &charcount) != 0 &&
*(name + charcount)=='\0')
{
char *new_name;
/*
* Above name is a pointer into the Workspace struct. Here we make
* a copy copy so we can have our wicked way with it.
*/
if (number == 10)
new_name = g_strdup_printf (_("Workspace 1_0"));
else
new_name = g_strdup_printf (_("Workspace %s%d"),
number < 10 ? "_" : "",
number);
return new_name;
}
else
{
/*
* Otherwise this is just a normal name. Escape any _ characters so that
* the user's workspace names do not get mangled. If the number is less
* than 10 we provide an accelerator.
*/
char *new_name;
const char *source;
char *dest;
/*
* Assume the worst case, that every character is a _. We also
* provide memory for " (_#)"
*/
new_name = g_malloc0 (strlen (name) * 2 + 6 + 1);
/*
* Now iterate down the strings, adding '_' to escape as we go
*/
dest = new_name;
source = name;
while (*source != '\0')
{
if (*source == '_')
*dest++ = '_';
*dest++ = *source++;
}
/* People don't start at workspace 0, but workspace 1 */
if (index < 9)
{
g_snprintf (dest, 6, " (_%d)", index + 1);
}
else if (index == 9)
{
g_snprintf (dest, 6, " (_0)");
}
return new_name;
}
}
static GtkWidget *
menu_item_new (MenuItem *menuitem, int workspace_id)
{
unsigned int key;
MetaVirtualModifier mods;
const char *i18n_label;
GtkWidget *mi;
GtkWidget *accel_label;
if (menuitem->type == MENU_ITEM_NORMAL)
{
mi = gtk_menu_item_new ();
}
else if (menuitem->type == MENU_ITEM_CHECKBOX)
{
mi = gtk_check_menu_item_new ();
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (mi),
menuitem->checked);
}
else if (menuitem->type == MENU_ITEM_RADIOBUTTON)
{
mi = gtk_check_menu_item_new ();
gtk_check_menu_item_set_draw_as_radio (GTK_CHECK_MENU_ITEM (mi),
TRUE);
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (mi),
menuitem->checked);
}
else if (menuitem->type == MENU_ITEM_WORKSPACE_LIST)
return NULL;
else
return gtk_separator_menu_item_new ();
i18n_label = _(menuitem->label);
meta_core_get_menu_accelerator (menuitem->op, workspace_id, &key, &mods);
accel_label = meta_accel_label_new_with_mnemonic (i18n_label);
gtk_misc_set_alignment (GTK_MISC (accel_label), 0.0, 0.5);
gtk_container_add (GTK_CONTAINER (mi), accel_label);
gtk_widget_show (accel_label);
meta_accel_label_set_accelerator (META_ACCEL_LABEL (accel_label),
key, mods);
return mi;
}
MetaWindowMenu*
meta_window_menu_new (MetaFrames *frames,
MetaMenuOp ops,
MetaMenuOp insensitive,
Window client_xwindow,
unsigned long active_workspace,
int n_workspaces,
MetaWindowMenuFunc func,
gpointer data)
{
int i;
MetaWindowMenu *menu;
/* FIXME: Modifications to 'ops' should happen in meta_window_show_menu */
if (n_workspaces < 2)
ops &= ~(META_MENU_OP_STICK | META_MENU_OP_UNSTICK | META_MENU_OP_WORKSPACES);
else if (n_workspaces == 2)
/* #151183: If we only have two workspaces, disable the menu listing them. */
ops &= ~(META_MENU_OP_WORKSPACES);
menu = g_new (MetaWindowMenu, 1);
menu->frames = frames;
menu->client_xwindow = client_xwindow;
menu->func = func;
menu->data = data;
menu->ops = ops;
menu->insensitive = insensitive;
menu->menu = gtk_menu_new ();
gtk_menu_set_screen (GTK_MENU (menu->menu),
gtk_widget_get_screen (GTK_WIDGET (frames)));
for (i = 0; i < (int) G_N_ELEMENTS (menuitems); i++)
{
MenuItem menuitem = menuitems[i];
if (ops & menuitem.op || menuitem.op == 0)
{
GtkWidget *mi;
MenuData *md;
unsigned int key;
MetaVirtualModifier mods;
mi = menu_item_new (&menuitem, -1);
/* Set the activeness of radiobuttons. */
switch (menuitem.op)
{
case META_MENU_OP_STICK:
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (mi),
active_workspace == 0xFFFFFFFF);
break;
case META_MENU_OP_UNSTICK:
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (mi),
active_workspace != 0xFFFFFFFF);
break;
default:
break;
}
if (menuitem.type == MENU_ITEM_WORKSPACE_LIST)
{
if (ops & META_MENU_OP_WORKSPACES)
{
Display *display;
Window xroot;
GdkScreen *screen;
GdkWindow *window;
GtkWidget *submenu;
int j;
MenuItem to_another_workspace = {
0, MENU_ITEM_NORMAL, FALSE,
N_("Move to Another _Workspace")
};
meta_verbose ("Creating %d-workspace menu current space %lu\n",
n_workspaces, active_workspace);
window = gtk_widget_get_window (GTK_WIDGET (frames));
display = GDK_WINDOW_XDISPLAY (window);
screen = gdk_window_get_screen (window);
xroot = GDK_WINDOW_XID (gdk_screen_get_root_window (screen));
submenu = gtk_menu_new ();
g_assert (mi==NULL);
mi = menu_item_new (&to_another_workspace, -1);
gtk_menu_item_set_submenu (GTK_MENU_ITEM (mi), submenu);
for (j = 0; j < n_workspaces; j++)
{
char *label;
MenuData *md;
unsigned int key;
MetaVirtualModifier mods;
MenuItem moveitem;
GtkWidget *submi;
meta_core_get_menu_accelerator (META_MENU_OP_WORKSPACES,
j + 1,
&key, &mods);
label = get_workspace_name_with_accel (display, xroot, j);
moveitem.type = MENU_ITEM_NORMAL;
moveitem.op = META_MENU_OP_WORKSPACES;
moveitem.label = label;
submi = menu_item_new (&moveitem, j + 1);
g_free (label);
if ((active_workspace == (unsigned)j) && (ops & META_MENU_OP_UNSTICK))
gtk_widget_set_sensitive (submi, FALSE);
md = g_new (MenuData, 1);
md->menu = menu;
md->op = META_MENU_OP_WORKSPACES;
g_object_set_data (G_OBJECT (submi),
"workspace",
GINT_TO_POINTER (j));
g_signal_connect_data (G_OBJECT (submi),
"activate",
G_CALLBACK (activate_cb),
md,
(GClosureNotify) g_free, 0);
gtk_menu_shell_append (GTK_MENU_SHELL (submenu), submi);
gtk_widget_show (submi);
}
}
else
meta_verbose ("not creating workspace menu\n");
}
else if (menuitem.type != MENU_ITEM_SEPARATOR)
{
meta_core_get_menu_accelerator (menuitems[i].op, -1,
&key, &mods);
if (insensitive & menuitem.op)
gtk_widget_set_sensitive (mi, FALSE);
md = g_new (MenuData, 1);
md->menu = menu;
md->op = menuitem.op;
g_signal_connect_data (G_OBJECT (mi),
"activate",
G_CALLBACK (activate_cb),
md,
(GClosureNotify) g_free, 0);
}
if (mi)
{
gtk_menu_shell_append (GTK_MENU_SHELL (menu->menu), mi);
gtk_widget_show (mi);
}
}
}
g_signal_connect (menu->menu, "selection_done",
G_CALLBACK (menu_closed), menu);
return menu;
}
void
meta_window_menu_popup (MetaWindowMenu *menu,
int root_x,
int root_y,
int button,
guint32 timestamp)
{
GdkPoint *pt;
pt = g_new (GdkPoint, 1);
g_object_set_data_full (G_OBJECT (menu->menu),
"destroy-point",
pt,
g_free);
pt->x = root_x;
pt->y = root_y;
gtk_menu_popup (GTK_MENU (menu->menu),
NULL, NULL,
popup_position_func, pt,
button,
timestamp);
if (!gtk_widget_get_visible (menu->menu))
meta_warning ("GtkMenu failed to grab the pointer\n");
}
void
meta_window_menu_free (MetaWindowMenu *menu)
{
gtk_widget_destroy (menu->menu);
g_free (menu);
}

View File

@ -1,55 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* Mutter window menu */
/*
* Copyright (C) 2001 Havoc Pennington
*
* 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, see <http://www.gnu.org/licenses/>.
*/
#ifndef META_MENU_H
#define META_MENU_H
#include <gtk/gtk.h>
#include "frames.h"
struct _MetaWindowMenu
{
MetaFrames *frames;
Window client_xwindow;
GtkWidget *menu;
MetaWindowMenuFunc func;
gpointer data;
MetaMenuOp ops;
MetaMenuOp insensitive;
};
MetaWindowMenu* meta_window_menu_new (MetaFrames *frames,
MetaMenuOp ops,
MetaMenuOp insensitive,
Window client_xwindow,
unsigned long active_workspace,
int n_workspaces,
MetaWindowMenuFunc func,
gpointer data);
void meta_window_menu_popup (MetaWindowMenu *menu,
int root_x,
int root_y,
int button,
guint32 timestamp);
void meta_window_menu_free (MetaWindowMenu *menu);
#endif

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