Compare commits

...

47 Commits

Author SHA1 Message Date
Jasper St. Pierre
2a0dee9883 icons 2014-03-18 21:27:31 -04:00
Ryan Lortie
1502d2a79f Revert "hack autogen to allow automake 1.13"
This reverts commit f0c503b5a9.

01:08 < Jasper> desrt, can you revert that mutter-wayland commit for me?
                My laptop with git on it is out of commission.
2014-03-14 01:08:46 -04:00
Jasper St. Pierre
a9d8107c3d window: Replace meta_window_type_changed with meta_window_set_type
Which does the equality checking for us.
2014-03-13 17:14:28 -04:00
Jasper St. Pierre
a5d2c51392 window: Move recalc_type to window-x11.c
It's only used by the X11 codepath.
2014-03-13 17:14:28 -04:00
Jasper St. Pierre
d1ea17e6a4 meta-weston-launch: Adapt to Clutter's new evdev open callback 2014-03-13 12:47:11 -04:00
Jasper St. Pierre
b37ad66e9d xdg-shell: Update for new state change mechanism
We're still not properly going through the request system. This
will require a dense investigation of the code, but it will happen
soon...
2014-03-12 23:42:55 -04:00
Matthias Clasen
c1f15348a5 Revert "weston-launch: Pass the DRM device to Cogl"
This reverts commit 857561baed.

This broke the build, and was pushed prematurely.
2014-03-12 14:48:46 -04:00
Jasper St. Pierre
857561baed weston-launch: Pass the DRM device to Cogl
Open the device from weston-launch, and pass it to Cogl/Clutter.
This is a preliminary cleanup for our login1 integration.
2014-03-11 18:01:21 -04:00
Jasper St. Pierre
a44cc9ef47 wayland: Fix build 2014-03-11 18:01:17 -04:00
Jasper St. Pierre
d47b7ba038 Add meta_activate_session
This will be used on startup to switch to the newly activated session.
2014-03-11 17:25:40 -04:00
Jasper St. Pierre
f21312e2fd meta-weston-launch: Redraw and update the cursor when switching back 2014-03-11 17:25:40 -04:00
Jasper St. Pierre
394af33607 weston-launch: Allow activating our own VT by passing a negative value
This will be used to implement activate_session.
2014-03-11 17:25:40 -04:00
Jasper St. Pierre
7314cdac94 weston-launch: Always use sd_session_get_vt 2014-03-11 17:25:40 -04:00
Jasper St. Pierre
81025e37ea weston-launch: Stat the path before opening it 2014-03-11 17:25:39 -04:00
Jasper St. Pierre
1bb9f1e333 weston-launch: Remove unused prototypes 2014-03-11 17:25:39 -04:00
Jasper St. Pierre
b11c75c1c9 weston-launch: Rearrange code slightly
We need to initialize the main loops before our callback is called, so
this makes it make a slight bit of more sense.
2014-03-11 17:25:39 -04:00
Jasper St. Pierre
757b626aee wayland: Add a few comments, rename some strings 2014-03-11 17:25:02 -04:00
Jasper St. Pierre
fb3df5243f main: Add a --display-server option
This is an explicit option to launch mutter as a display server,
rather than relying on weston-launch.
2014-03-11 16:33:42 -04:00
Jasper St. Pierre
e34792d9f0 wayland: Remove needless indirection 2014-03-11 16:00:43 -04:00
Jasper St. Pierre
f397c32192 wayland: Make set_selection private
It's unused outside of us.
2014-03-11 15:42:37 -04:00
Jasper St. Pierre
f79314d7b5 wayland: Fix destroying data sources
The resource is not embedded in the source, it's separate. We need
to get the user data here to not crash.
2014-03-11 15:30:17 -04:00
Jasper St. Pierre
55c61259d8 wayland: Use g_slice_new0
And fix a leak.
2014-03-11 15:30:17 -04:00
Jasper St. Pierre
5298cf0a3a wayland: Pull in a fix for a FIXME from Weston 2014-03-11 15:30:17 -04:00
Jasper St. Pierre
f1dc1a0cbc wayland: Fix drag grabs
We need to have the seat here. This makes weston-dnd not crash when
clicking on an item.
2014-03-11 15:30:16 -04:00
Owen W. Taylor
2cf80bc647 Fix identification of CSD windows when checking whether to force fullscreen
We try to exempt CSD windows from being forced fullscreen if they are
undecorated and the size of the screen; however, we also catch almost
all windows that *do* need to be forced fullscreen in this check, since
they also have decorations turned off.

Identify actual CSD windows by checking whether _GTK_FRAME_EXTENTS is set -
GTK+ will always set this on CSD windows even if they have no invisible
borders or shadows at the current time.

We explicitly turn off the legacy-fullscreen check for native wayland windows
so we don't start legacy-fullscreening them if the new
meta_window_is_client_decorated() is later made more accurate.

https://bugzilla.gnome.org/show_bug.cgi?id=723029
2014-03-11 13:02:19 -04:00
Owen W. Taylor
40c15f6e2a Fix meta_window_titlebar_is_onscreen() for titlebar-less windows
Make the code correspond to the comment - the titlebar can't be
offscreen if there's no titlebar.

https://bugzilla.gnome.org/show_bug.cgi?id=723580
2014-03-11 13:02:19 -04:00
Jasper St. Pierre
a8849621c9 window: Always save the user_rect when resizing Wayland windows
The user_rect represents the unconstrainted window size, and lots
of code in mutter assumes it can resize to the user_rect at any
time. If we wait for an attach to ACK and save the user rect, we'll
see lots of flickering as code is resizing to the old user_rect
at any time.
2014-03-11 12:29:11 -04:00
Jasper St. Pierre
49c0be11d6 display: Rework event spewing
Make it a compile-time flag rather than a run-time flag, because
practically any time you're going to be debugging event spewing,
you're going to have to recompile anyway. Remove the WITH_VERBOSE_MODE
checks, too.
2014-03-11 10:24:13 -04:00
Jasper St. Pierre
9df8e831be xwayland: Make sure to clear an existing surface if we have one
This fixes an assert fail when redecorating an X11 client.
2014-03-11 10:24:13 -04:00
Jasper St. Pierre
84c6b2a3fa wayland: Remove an extra reset
We already reset the double-buffered state when we commit it, so this
is just superfluous.
2014-03-11 10:24:13 -04:00
Jasper St. Pierre
06cd669ccb wayland: Fix bad copy-paste error in unset_fullscreen
This was causing memory corruption and a bad crasher with simple-egl.
2014-03-10 16:45:05 -04:00
Jasper St. Pierre
81eb7d9537 Add META_GRAB_OP_WAYLAND_CLIENT
Which is used for Wayland popup grabs.

The issue here is that we don't want the code that raises or focuses
windows based on mouse ops to run while a client has a grab.

We still keep the "old" grab infrastructure in place for now, but
ideally we'd replace it eventually with a better grab-op infrastructure.
2014-03-10 15:11:03 -04:00
Jasper St. Pierre
dd8d8e436d wayland: Remove special code for modal grabs
Since we never pass any Clutter events to Wayland, it's not needed.
2014-03-10 15:10:44 -04:00
Jasper St. Pierre
d6b6b363ad seat: Add support for smooth scrolling 2014-03-10 11:36:36 -04:00
Jasper St. Pierre
254e2e993c seat: Redo scroll handling
To make way for smooth scrolling
2014-03-10 11:36:36 -04:00
Jasper St. Pierre
c595a9c29f seat: Reduce indentation 2014-03-10 11:36:36 -04:00
Rui Matos
dfc7f7222b wayland-keyboard: Remove unused modifier indexes
This was copied from weston where they're used for compositor
keybindings. Mutter has its own keybindings code which doesn't need
this.

https://bugzilla.gnome.org/show_bug.cgi?id=722847
2014-03-07 15:00:04 +01:00
Rui Matos
ef278eb547 meta-cursor-tracker: Initialize our position from MetaWaylandPointer's
Clutter's input device initial position defaults to (-1, -1) on most
backends but for the evdev backend we changed it to be inside the
stage to prevent the pointer from wandering outside the stage until it
first enters, after which our constraining callback won't let it go
out.

This makes us be in sync with the real position from the start.
2014-03-07 14:54:51 +01:00
Rui Matos
38e26e5cc3 keybindings: Plug a GSettings instance leak 2014-03-06 19:22:39 +01:00
Rui Matos
9773a879c3 cursor-tracker: Include gdk/gdkx.h
Needed for the call to gdk_x11_device_manager_lookup() introduced in
abd2abcde6 .
2014-03-06 19:22:39 +01:00
Adel Gadllah
abd2abcde6 cursor-tracker: Avoid unnecessary round trip 2014-03-06 17:31:08 +01:00
Giovanni Campagna
a8f4651c72 MetaCursorTracker: fix uninitialized screen variable
We must call gdk_device_get_pointer() unconditionally, because
that sets the GdkScreen argument we use to obtain the root window.
2014-03-06 17:27:11 +01:00
Florian Müllner
54df7934ea Bump version to 3.11.91
Update NEWS.
2014-03-05 23:48:33 +01:00
Florian Müllner
9052efb0d9 build: Use non-deprecated feature test macros
_SVID_SOURCE has been deprecated in newer versions of glibc breaking
-WError; the recommended replacement of _DEFAULT_SOURCE is fairly
new, so switch to _XOPEN_SOURCE instead.
2014-03-05 23:48:33 +01:00
Owen W. Taylor
b346f98eb0 Fix positioning error for manually positioned windows
The "original coordinates" passed into meta_window_place() were the
coordinates of the client rectangle not the frame rectangle. When
meta_window_place() didn't place because the window was manually
positioned (e.g., 'xterm -geometry +x+y') that resulted in a window
being offset by the frame dimensions.

https://bugzilla.gnome.org/show_bug.cgi?id=724049
2014-03-05 17:22:56 -05:00
Owen W. Taylor
365af53797 Fix handling of dynamic updates to colors/font/etc.
Since the introduction of frame sync in GTK+, updates to titlebar font and
colors haven't been working because GTK+ counts on the frame clock to
do style updates, and the frame clock doesn't run for an unmapped
GdkWindow. (It's possible that GtkStyleContext changes subsequent to
the introduction of the frame clock were also needed to fully break
things.)

We actually need to map the MetaFrames GdkWindow and let the
compositor code send out the frame sync messages in order to pick up
style changes.

Hopefully no bad side effects will occur from this - we make the window
override-redirect, 1x1, and outside the bounds of the screen.

https://bugzilla.gnome.org/show_bug.cgi?id=725751
2014-03-05 17:22:48 -05:00
Giovanni Campagna
bee59ec0e1 Use MetaCursorTracker to query the pointer position
Functionally equivalent in the X11 case, but also correct for
Wayland (where the X server doesn't have the updated pointer
position).

https://bugzilla.gnome.org/show_bug.cgi?id=725525
2014-03-05 23:09:48 +01:00
45 changed files with 683 additions and 1008 deletions

14
NEWS
View File

@@ -1,3 +1,17 @@
3.11.91
=======
* Don't use keysym to match keybindings [Rui; #678001]
* Fix message tray icons showing up blank (again) [Adel; #725180]
* Improve keybinding lookups [Rui; #725588]
* Fix dynamic updates of titlebar style properties [Owen; #725751]
* Fix positioning of manually positioned windows [Owen; #724049]
* Misc bug fixes and cleanups [Jasper, Carlos, Adel, Giovanni, Florian; #720631,
#724969, #725216, #724402, #722266, #725338, #725525]
Contributors:
Giovanni Campagna, Adel Gadllah, Carlos Garnacho, Rui Matos, Florian Müllner,
Jasper St. Pierre, Owen W. Taylor
3.11.90
=======
* Fix double-scaling on high DPI resolutions [Adel; #723931]

View File

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

View File

@@ -3,7 +3,7 @@ AC_CONFIG_MACRO_DIR([m4])
m4_define([mutter_major_version], [3])
m4_define([mutter_minor_version], [11])
m4_define([mutter_micro_version], [90])
m4_define([mutter_micro_version], [91])
m4_define([mutter_version],
[mutter_major_version.mutter_minor_version.mutter_micro_version])
@@ -142,11 +142,6 @@ AM_GLIB_GNU_GETTEXT
PKG_CHECK_MODULES(ALL, glib-2.0 >= 2.14.0)
PKG_CHECK_MODULES(MUTTER_LAUNCH, libdrm libsystemd-login)
saved_LIBS="$LIBS"
LIBS="$LIBS $MUTTER_LAUNCH"
AC_CHECK_FUNCS([sd_session_get_vt])
LIBS="$saved_LIBS"
# Unconditionally use this dir to avoid a circular dep with gnomecc
GNOME_KEYBINDINGS_KEYSDIR="${datadir}/gnome-control-center/keybindings"
AC_SUBST(GNOME_KEYBINDINGS_KEYSDIR)

View File

@@ -40,19 +40,22 @@
<enum name="version">
<description summary="latest protocol version">
Use this enum to check the protocol version, and it will be updated
automatically.
The 'current' member of this enum gives the version of the
protocol. Implementations can compare this to the version
they implement using static_assert to ensure the protocol and
implementation versions match.
</description>
<entry name="current" value="2" summary="Always the latest version"/>
<entry name="current" value="3" summary="Always the latest version"/>
</enum>
<request name="use_unstable_version">
<description summary="enable use of this unstable version">
Use this request in order to enable use of this interface.
Understand and agree that one is using an unstable interface,
that will likely change in the future, breaking the API.
Negotiate the unstable version of the interface. This
mechanism is in place to ensure client and server agree on the
unstable versions of the protocol that they speak or exit
cleanly if they don't agree. This request will go away once
the xdg-shell protocol is stable.
</description>
<arg name="version" type="int"/>
</request>
@@ -275,113 +278,87 @@
<arg name="output" type="object" interface="wl_output" allow-null="true"/>
</request>
<event name="request_set_fullscreen">
<description summary="server requests that the client set fullscreen">
Event sent from the compositor to the client requesting that the client
goes to a fullscreen state. It's the client job to call set_fullscreen
and really trigger the fullscreen state.
<enum name="state">
<description summary="types of state on the surface">
The different state values used on the surface. This is designed for
state values like maximized, fullscreen. It is paired with the
request_change_state event to ensure that both the client and the
compositor setting the state can be synchronized.
States set in this way are double-buffered. They will get applied on
the next commit.
Desktop environments may extend this enum by taking up a range of
values and documenting the range they chose in this description.
They are not required to document the values for the range that they
chose. Ideally, any good extensions from a desktop environment should
make its way into standardization into this enum.
The current reserved ranges are:
0x0000 - 0x0FFF: xdg-shell core values, documented below.
0x1000 - 0x1FFF: GNOME
</description>
</event>
<entry name="maximized" value="1" summary="the surface is maximized">
A non-zero value indicates the surface is maximized. Otherwise,
the surface is unmaximized.
</entry>
<entry name="fullscreen" value="2" summary="the surface is fullscreen">
A non-zero value indicates the surface is fullscreen. Otherwise,
the surface is not fullscreen.
</entry>
</enum>
<event name="request_unset_fullscreen">
<description summary="server requests that the client unset fullscreen">
Event sent from the compositor to the client requesting that the client
leaves the fullscreen state. It's the client job to call
unset_fullscreen and really leave the fullscreen state.
</description>
</event>
<request name="set_fullscreen">
<description summary="set the surface state as fullscreen">
Set the surface as fullscreen.
After this request, the compositor should send a configure event
informing the output size.
This request informs the compositor that the next attached buffer
committed will be in a fullscreen state. The buffer size should be the
same size as the size informed in the configure event, if the client
doesn't want to leave any empty area.
In other words: the next attached buffer after set_maximized is the new
maximized buffer. And the surface will be positioned at the maximized
position on commit.
A simple way to synchronize and wait for the correct configure event is
to use a wl_display.sync request right after the set_fullscreen
request. When the sync callback returns, the last configure event
received just before it will be the correct one, and should contain the
right size for the surface to maximize.
Setting one state won't unset another state. Use
xdg_surface.unset_fullscreen for unsetting it.
<request name="request_change_state">
<description summary="client requests to change a surface's state">
This asks the compositor to change the state. If the compositor wants
to change the state, it will send a change_state event with the same
state_type, value, and serial, and the event flow continues as if it
it was initiated by the compositor.
If the compositor does not want to change the state, it will send a
change_state to the client with the old value of the state.
</description>
<arg name="state_type" type="uint" summary="the state to set"/>
<arg name="value" type="uint" summary="the value to change the state to"/>
<arg name="serial" type="uint" summary="an event serial">
This serial is so the client can know which change_state event corresponds
to which request_change_state request it sent out.
</arg>
</request>
<request name="unset_fullscreen">
<description summary="unset the surface state as fullscreen">
Unset the surface fullscreen state.
Same negotiation as set_fullscreen must be used.
<event name="change_state">
<description summary="compositor wants to change a surface's state">
This event tells the client to change a surface's state. The client
should respond with an ack_change_state request to the compositor to
guarantee that the compositor knows that the client has seen it.
</description>
</request>
<event name="request_set_maximized">
<description summary="server requests that the client set maximized">
Event sent from the compositor to the client requesting that the client
goes to a maximized state. It's the client job to call set_maximized
and really trigger the maximized state.
</description>
<arg name="state_type" type="uint" summary="the state to set"/>
<arg name="value" type="uint" summary="the value to change the state to"/>
<arg name="serial" type="uint" summary="a serial for the compositor's own tracking"/>
</event>
<event name="request_unset_maximized">
<description summary="server requests that the client unset maximized">
Event sent from the compositor to the client requesting that the client
leaves the maximized state. It's the client job to call unset_maximized
and really leave the maximized state.
</description>
</event>
<request name="set_maximized">
<description summary="set the surface state as maximized">
Set the surface as maximized.
After this request, the compositor will send a configure event
informing the output size minus panel and other MW decorations.
This request informs the compositor that the next attached buffer
committed will be in a maximized state. The buffer size should be the
same size as the size informed in the configure event, if the client
doesn't want to leave any empty area.
In other words: the next attached buffer after set_maximized is the new
maximized buffer. And the surface will be positioned at the maximized
position on commit.
A simple way to synchronize and wait for the correct configure event is
to use a wl_display.sync request right after the set_maximized request.
When the sync callback returns, the last configure event received just
before it will be the correct one, and should contain the right size
for the surface to maximize.
Setting one state won't unset another state. Use
xdg_surface.unset_maximized for unsetting it.
</description>
</request>
<request name="unset_maximized">
<description summary="unset the surface state as maximized">
Unset the surface maximized state.
Same negotiation as set_maximized must be used.
<request name="ack_change_state">
<description summary="ack a change_state event">
When a change_state event is received, a client should then ack it
using the ack_change_state request to ensure that the compositor
knows the client has seen the event.
By this point, the state is confirmed, and the next attach should
contain the buffer drawn for the new state value.
The values here need to be the same as the values in the cooresponding
change_state event.
</description>
<arg name="state_type" type="uint" summary="the state to set"/>
<arg name="value" type="uint" summary="the value to change the state to"/>
<arg name="serial" type="uint" summary="a serial to pass to change_state"/>
</request>
<request name="set_minimized">
<description summary="set the surface state as minimized">
Set the surface minimized state.
Setting one state won't unset another state.
<description summary="minimize the surface">
Minimize the surface.
</description>
</request>

View File

@@ -128,8 +128,8 @@ libmutter_wayland_la_SOURCES = \
core/group-props.h \
core/group.c \
meta/group.h \
core/iconcache.c \
core/iconcache.h \
core/icons.c \
core/icons.h \
core/keybindings.c \
core/keybindings-private.h \
core/main.c \

View File

@@ -436,45 +436,6 @@ begin_modal_x11 (MetaScreen *screen,
return FALSE;
}
static gboolean
begin_modal_wayland (MetaScreen *screen,
MetaPlugin *plugin,
MetaModalOptions options,
guint32 timestamp)
{
MetaWaylandCompositor *compositor;
gboolean pointer_grabbed = FALSE;
gboolean keyboard_grabbed = FALSE;
compositor = meta_wayland_compositor_get_default ();
if ((options & META_MODAL_POINTER_ALREADY_GRABBED) == 0)
{
if (!meta_wayland_pointer_begin_modal (&compositor->seat->pointer))
goto fail;
pointer_grabbed = TRUE;
}
if ((options & META_MODAL_KEYBOARD_ALREADY_GRABBED) == 0)
{
if (!meta_wayland_keyboard_begin_modal (&compositor->seat->keyboard,
timestamp))
goto fail;
keyboard_grabbed = TRUE;
}
return TRUE;
fail:
if (pointer_grabbed)
meta_wayland_pointer_end_modal (&compositor->seat->pointer);
if (keyboard_grabbed)
meta_wayland_keyboard_end_modal (&compositor->seat->keyboard, timestamp);
return FALSE;
}
gboolean
meta_begin_modal_for_plugin (MetaScreen *screen,
MetaPlugin *plugin,
@@ -493,7 +454,7 @@ meta_begin_modal_for_plugin (MetaScreen *screen,
return FALSE;
if (meta_is_wayland_compositor ())
ok = begin_modal_wayland (screen, plugin, options, timestamp);
ok = TRUE;
else
ok = begin_modal_x11 (screen, plugin, options, timestamp);
if (!ok)
@@ -521,15 +482,7 @@ meta_end_modal_for_plugin (MetaScreen *screen,
g_return_if_fail (compositor->modal_plugin == plugin);
if (meta_is_wayland_compositor ())
{
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
meta_wayland_pointer_end_modal (&compositor->seat->pointer);
meta_wayland_keyboard_end_modal (&compositor->seat->keyboard,
timestamp);
}
else
if (!meta_is_wayland_compositor ())
{
XIUngrabDevice (xdpy, META_VIRTUAL_CORE_POINTER_ID, timestamp);
XIUngrabDevice (xdpy, META_VIRTUAL_CORE_KEYBOARD_ID, timestamp);

View File

@@ -425,8 +425,9 @@ setup_constraint_info (ConstraintInfo *info,
* the monitor.
*/
if (meta_prefs_get_force_fullscreen() &&
window->client_type != META_WINDOW_CLIENT_TYPE_WAYLAND &&
!window->hide_titlebar_when_maximized &&
window->decorated &&
(window->decorated || !meta_window_is_client_decorated (window)) &&
meta_rectangle_equal (new, &monitor_info->rect) &&
window->has_fullscreen_func &&
!window->fullscreen)
@@ -491,12 +492,17 @@ place_window_if_needed(MetaWindow *window,
!window->minimized &&
!window->fullscreen)
{
MetaRectangle orig_rect;
MetaRectangle placed_rect;
MetaWorkspace *cur_workspace;
const MetaMonitorInfo *monitor_info;
meta_window_get_frame_rect (window, &placed_rect);
meta_window_place (window, info->orig.x, info->orig.y,
orig_rect = info->orig;
extend_by_frame (window, &orig_rect);
meta_window_place (window, orig_rect.x, orig_rect.y,
&placed_rect.x, &placed_rect.y);
did_placement = TRUE;

View File

@@ -736,31 +736,6 @@ meta_core_increment_event_serial (Display *xdisplay)
meta_display_increment_event_serial (display);
}
void
meta_invalidate_default_icons (void)
{
MetaDisplay *display = meta_get_display ();
GSList *windows;
GSList *l;
if (display == NULL)
return; /* We can validly be called before the display is opened. */
windows = meta_display_list_windows (display, META_LIST_DEFAULT);
for (l = windows; l != NULL; l = l->next)
{
MetaWindow *window = (MetaWindow*)l->data;
if (window->icon_cache.origin == USING_FALLBACK_ICON)
{
meta_icon_cache_free (&(window->icon_cache));
meta_window_update_icon_now (window);
}
}
g_slist_free (windows);
}
void
meta_core_add_old_event_mask (Display *xdisplay,
Window xwindow,

View File

@@ -199,8 +199,6 @@ void meta_core_set_screen_cursor (Display *xdisplay,
*/
void meta_core_increment_event_serial (Display *display);
void meta_invalidate_default_icons (void);
void meta_core_add_old_event_mask (Display *xdisplay,
Window xwindow,
XIEventMask *mask);

View File

@@ -1295,10 +1295,6 @@ meta_get_display (void)
return the_display;
}
#ifdef WITH_VERBOSE_MODE
static gboolean dump_events = TRUE;
#endif
static gboolean
grab_op_is_mouse_only (MetaGrabOp op)
{
@@ -1418,6 +1414,20 @@ meta_grab_op_is_moving (MetaGrabOp op)
}
}
static gboolean
grab_op_should_block_mouse_events (MetaGrabOp op)
{
switch (op)
{
case META_GRAB_OP_WAYLAND_CLIENT:
case META_GRAB_OP_COMPOSITOR:
return TRUE;
default:
return FALSE;
}
}
/**
* meta_display_xserver_time_is_before:
* @display: a #MetaDisplay
@@ -2054,7 +2064,7 @@ meta_display_handle_event (MetaDisplay *display,
switch (event->type)
{
case CLUTTER_BUTTON_PRESS:
if (display->grab_op == META_GRAB_OP_COMPOSITOR)
if (grab_op_should_block_mouse_events (display->grab_op))
break;
display->overlay_key_only_pressed = FALSE;
@@ -2226,7 +2236,7 @@ meta_display_handle_event (MetaDisplay *display,
}
break;
case CLUTTER_BUTTON_RELEASE:
if (display->grab_op == META_GRAB_OP_COMPOSITOR)
if (grab_op_should_block_mouse_events (display->grab_op))
break;
display->overlay_key_only_pressed = FALSE;
@@ -2240,7 +2250,7 @@ meta_display_handle_event (MetaDisplay *display,
}
break;
case CLUTTER_MOTION:
if (display->grab_op == META_GRAB_OP_COMPOSITOR)
if (grab_op_should_block_mouse_events (display->grab_op))
break;
if (display->grab_window == window &&
@@ -2274,6 +2284,10 @@ meta_display_handle_event (MetaDisplay *display,
if (display->grab_op == META_GRAB_OP_COMPOSITOR)
bypass_wayland = TRUE;
/* If a Wayland client has a grab, don't pass that through to Clutter */
if (display->grab_op == META_GRAB_OP_WAYLAND_CLIENT)
bypass_clutter = TRUE;
if (compositor && !bypass_wayland)
{
if (meta_wayland_compositor_handle_event (compositor, event))
@@ -2974,9 +2988,8 @@ meta_display_handle_xevent (MetaDisplay *display,
MetaMonitorManager *monitor;
MetaScreen *screen;
#ifdef WITH_VERBOSE_MODE
if (dump_events)
meta_spew_event (display, event);
#if 0
meta_spew_event (display, event);
#endif
#ifdef HAVE_STARTUP_NOTIFICATION
@@ -3252,8 +3265,7 @@ event_get_time (MetaDisplay *display,
}
}
#ifdef WITH_VERBOSE_MODE
const char*
G_GNUC_UNUSED const char*
meta_event_detail_to_string (int d)
{
const char *detail = "???";
@@ -3289,10 +3301,8 @@ meta_event_detail_to_string (int d)
return detail;
}
#endif /* WITH_VERBOSE_MODE */
#ifdef WITH_VERBOSE_MODE
const char*
G_GNUC_UNUSED const char*
meta_event_mode_to_string (int m)
{
const char *mode = "???";
@@ -3314,10 +3324,8 @@ meta_event_mode_to_string (int m)
return mode;
}
#endif /* WITH_VERBOSE_MODE */
#ifdef WITH_VERBOSE_MODE
static const char*
G_GNUC_UNUSED static const char*
stack_mode_to_string (int mode)
{
switch (mode)
@@ -3336,11 +3344,9 @@ stack_mode_to_string (int mode)
return "Unknown";
}
#endif /* WITH_VERBOSE_MODE */
#ifdef HAVE_XSYNC
#ifdef WITH_VERBOSE_MODE
static gint64
G_GNUC_UNUSED static gint64
sync_value_to_64 (const XSyncValue *value)
{
gint64 v;
@@ -3350,10 +3356,8 @@ sync_value_to_64 (const XSyncValue *value)
return v;
}
#endif /* WITH_VERBOSE_MODE */
#ifdef WITH_VERBOSE_MODE
static const char*
G_GNUC_UNUSED static const char*
alarm_state_to_string (XSyncAlarmState state)
{
switch (state)
@@ -3368,12 +3372,9 @@ alarm_state_to_string (XSyncAlarmState state)
return "(unknown)";
}
}
#endif /* WITH_VERBOSE_MODE */
#endif /* HAVE_XSYNC */
#ifdef WITH_VERBOSE_MODE
static void
G_GNUC_UNUSED static void
meta_spew_xi2_event (MetaDisplay *display,
XIEvent *input_event,
const char **name_p,
@@ -3433,7 +3434,7 @@ meta_spew_xi2_event (MetaDisplay *display,
*extra_p = extra;
}
static void
G_GNUC_UNUSED static void
meta_spew_core_event (MetaDisplay *display,
XEvent *event,
const char **name_p,
@@ -3657,7 +3658,7 @@ meta_spew_core_event (MetaDisplay *display,
*extra_p = extra;
}
static void
G_GNUC_UNUSED static void
meta_spew_event (MetaDisplay *display,
XEvent *event)
{
@@ -3666,9 +3667,6 @@ meta_spew_event (MetaDisplay *display,
char *winname;
MetaScreen *screen;
XIEvent *input_event;
if (!meta_is_verbose())
return;
/* filter overnumerous events */
if (event->type == Expose || event->type == MotionNotify ||
@@ -3698,18 +3696,16 @@ meta_spew_event (MetaDisplay *display,
else
winname = g_strdup_printf ("0x%lx", event->xany.window);
meta_topic (META_DEBUG_EVENTS,
"%s on %s%s %s %sserial %lu\n", name, winname,
extra ? ":" : "", extra ? extra : "",
event->xany.send_event ? "SEND " : "",
event->xany.serial);
g_print ("%s on %s%s %s %sserial %lu\n", name, winname,
extra ? ":" : "", extra ? extra : "",
event->xany.send_event ? "SEND " : "",
event->xany.serial);
g_free (winname);
if (extra)
g_free (extra);
}
#endif /* WITH_VERBOSE_MODE */
MetaWindow*
meta_display_lookup_x_window (MetaDisplay *display,

View File

@@ -3916,6 +3916,7 @@ init_builtin_key_bindings (MetaDisplay *display)
g_object_unref (common_keybindings);
g_object_unref (mutter_keybindings);
g_object_unref (mutter_wayland_keybindings);
}
void

View File

@@ -42,7 +42,7 @@
*/
#define _GNU_SOURCE
#define _SVID_SOURCE /* for putenv() and some signal-related functions */
#define _XOPEN_SOURCE /* for putenv() and some signal-related functions */
#include <config.h>
#include <meta/main.h>
@@ -190,6 +190,7 @@ static gboolean opt_replace_wm;
static gboolean opt_disable_sm;
static gboolean opt_sync;
static gboolean opt_wayland;
static gboolean opt_display_server;
static GOptionEntry meta_options[] = {
{
@@ -233,6 +234,11 @@ static GOptionEntry meta_options[] = {
N_("Run as a wayland compositor"),
NULL
},
{
"display-server", 0, 0, G_OPTION_ARG_NONE,
&opt_display_server,
N_("Run as a full display server, rather than nested")
},
{NULL}
};
@@ -401,8 +407,7 @@ meta_init (void)
if (g_getenv ("MUTTER_DEBUG"))
meta_set_debugging (TRUE);
/* We consider running from mutter-launch equivalent to running from bare metal. */
if (getenv ("WESTON_LAUNCHER_SOCK"))
if (opt_display_server)
clutter_set_windowing_backend (CLUTTER_WINDOWING_EGL);
meta_set_is_wayland_compositor (opt_wayland);
@@ -497,6 +502,32 @@ meta_register_with_session (void)
g_free (opt_client_id);
}
/**
* meta_activate_session:
*
* Tells mutter to activate the session. When mutter is a
* Wayland compositor, this tells logind to switch over to
* the new session.
*/
gboolean
meta_activate_session (void)
{
if (meta_is_wayland_compositor ())
{
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
GError *error = NULL;
if (!meta_wayland_compositor_activate_session (compositor, &error))
{
g_warning ("Could not activate session: %s\n", error->message);
g_error_free (error);
return FALSE;
}
}
return TRUE;
}
/**
* meta_run: (skip)
*

View File

@@ -43,4 +43,7 @@ void meta_cursor_tracker_update_position (MetaCursorTracker *tracker,
int new_x,
int new_y);
void meta_cursor_tracker_paint (MetaCursorTracker *tracker);
void meta_cursor_tracker_force_update (MetaCursorTracker *tracker);
#endif

View File

@@ -39,6 +39,7 @@
#include <gbm.h>
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
#include <X11/cursorfont.h>
#include <X11/extensions/Xfixes.h>
@@ -569,6 +570,9 @@ make_wayland_cursor_tracker (MetaScreen *screen)
compositor = meta_wayland_compositor_get_default ();
compositor->seat->cursor_tracker = self;
meta_cursor_tracker_update_position (self,
wl_fixed_to_int (compositor->seat->pointer.x),
wl_fixed_to_int (compositor->seat->pointer.y));
#if defined(CLUTTER_WINDOWING_EGL)
if (clutter_check_windowing_backend (CLUTTER_WINDOWING_EGL))
@@ -1074,12 +1078,13 @@ get_pointer_position_gdk (int *x,
GdkScreen *gscreen;
gmanager = gdk_display_get_device_manager (gdk_display_get_default ());
gdevice = gdk_device_manager_get_client_pointer (gmanager);
gdevice = gdk_x11_device_manager_lookup (gmanager, META_VIRTUAL_CORE_POINTER_ID);
gdk_device_get_position (gdevice, &gscreen, x, y);
gdk_device_get_state (gdevice,
gdk_screen_get_root_window (gscreen),
NULL, (GdkModifierType*)mods);
if (mods)
gdk_device_get_state (gdevice,
gdk_screen_get_root_window (gscreen),
NULL, (GdkModifierType*)mods);
}
static void
@@ -1095,9 +1100,12 @@ get_pointer_position_clutter (int *x,
cdevice = clutter_device_manager_get_core_device (cmanager, CLUTTER_POINTER_DEVICE);
clutter_input_device_get_coords (cdevice, NULL, &point);
*x = point.x;
*y = point.y;
*mods = clutter_input_device_get_modifier_state (cdevice);
if (x)
*x = point.x;
if (y)
*y = point.y;
if (mods)
*mods = clutter_input_device_get_modifier_state (cdevice);
}
void
@@ -1139,3 +1147,12 @@ meta_cursor_tracker_set_pointer_visible (MetaCursorTracker *tracker,
tracker->screen->xroot);
}
}
void
meta_cursor_tracker_force_update (MetaCursorTracker *tracker)
{
g_assert (meta_is_wayland_compositor ());
update_hw_cursor (tracker);
sync_cursor (tracker);
}

View File

@@ -1514,38 +1514,19 @@ meta_screen_get_mouse_window (MetaScreen *screen,
MetaWindow *not_this_one)
{
MetaWindow *window;
Window root_return, child_return;
double root_x_return, root_y_return;
double win_x_return, win_y_return;
XIButtonState buttons;
XIModifierState mods;
XIGroupState group;
int x, y;
if (not_this_one)
meta_topic (META_DEBUG_FOCUS,
"Focusing mouse window excluding %s\n", not_this_one->desc);
meta_error_trap_push (screen->display);
XIQueryPointer (screen->display->xdisplay,
META_VIRTUAL_CORE_POINTER_ID,
screen->xroot,
&root_return,
&child_return,
&root_x_return,
&root_y_return,
&win_x_return,
&win_y_return,
&buttons,
&mods,
&group);
meta_error_trap_pop (screen->display);
free (buttons.mask);
meta_cursor_tracker_get_pointer (screen->cursor_tracker,
&x, &y, NULL);
window = meta_stack_get_default_focus_window_at_point (screen->stack,
screen->active_workspace,
not_this_one,
root_x_return,
root_y_return);
x, y);
return window;
}
@@ -1827,28 +1808,11 @@ meta_screen_get_current_monitor (MetaScreen *screen)
if (screen->display->monitor_cache_invalidated)
{
Window root_return, child_return;
double win_x_return, win_y_return;
double root_x_return, root_y_return;
XIButtonState buttons;
XIModifierState mods;
XIGroupState group;
int x, y;
XIQueryPointer (screen->display->xdisplay,
META_VIRTUAL_CORE_POINTER_ID,
screen->xroot,
&root_return,
&child_return,
&root_x_return,
&root_y_return,
&win_x_return,
&win_y_return,
&buttons,
&mods,
&group);
free (buttons.mask);
meta_screen_get_current_monitor_for_pos (screen, root_x_return, root_y_return);
meta_cursor_tracker_get_pointer (screen->cursor_tracker,
&x, &y, NULL);
meta_screen_get_current_monitor_for_pos (screen, x, y);
}
return screen->last_monitor_index;

View File

@@ -92,7 +92,6 @@ struct _MetaWindow
char *icon_name;
GdkPixbuf *icon;
GdkPixbuf *mini_icon;
MetaIconCache icon_cache;
Pixmap wm_hints_pixmap;
Pixmap wm_hints_mask;
@@ -684,9 +683,8 @@ void meta_window_update_layer (MetaWindow *window);
void meta_window_recalc_features (MetaWindow *window);
/* recalc_window_type is x11 only, wayland does its thing and then calls type_changed */
void meta_window_recalc_window_type (MetaWindow *window);
void meta_window_type_changed (MetaWindow *window);
void meta_window_set_type (MetaWindow *window,
MetaWindowType type);
void meta_window_frame_size_changed (MetaWindow *window);
@@ -751,4 +749,6 @@ void meta_window_activate_full (MetaWindow *window,
MetaClientType source_indication,
MetaWorkspace *workspace);
gboolean meta_window_is_client_decorated (MetaWindow *window);
#endif

View File

@@ -35,7 +35,7 @@
*/
#define _GNU_SOURCE
#define _SVID_SOURCE /* for gethostname() */
#define _XOPEN_SOURCE 500 /* for gethostname() */
#include <config.h>
#include "window-props.h"
@@ -237,9 +237,6 @@ static void
reload_icon (MetaWindow *window,
Atom atom)
{
meta_icon_cache_property_changed (&window->icon_cache,
window->display,
atom);
meta_window_queue(window, META_QUEUE_UPDATE_ICON);
}
@@ -727,7 +724,7 @@ reload_net_wm_state (MetaWindow *window,
meta_verbose ("Reloaded _NET_WM_STATE for %s\n",
window->desc);
meta_window_recalc_window_type (window);
meta_window_x11_recalc_window_type (window);
meta_window_recalc_features (window);
}
@@ -1503,10 +1500,6 @@ reload_wm_hints (MetaWindow *window,
if (!initial && window->wm_hints_urgent && !old_urgent)
g_signal_emit_by_name (window->display, "window-marked-urgent", window);
meta_icon_cache_property_changed (&window->icon_cache,
window->display,
XA_WM_HINTS);
meta_window_queue (window, META_QUEUE_UPDATE_ICON | META_QUEUE_MOVE_RESIZE);
}

View File

@@ -38,6 +38,7 @@
#include <meta/common.h>
#include <meta/errors.h>
#include <meta/prefs.h>
#include <meta/meta-cursor-tracker.h>
#include "window-private.h"
#include "window-props.h"
@@ -225,7 +226,7 @@ meta_window_x11_update_net_wm_type (MetaWindow *window)
meta_XFree (str);
}
meta_window_recalc_window_type (window);
meta_window_x11_recalc_window_type (window);
}
void
@@ -673,35 +674,19 @@ meta_window_x11_property_notify (MetaWindow *window,
static int
query_pressed_buttons (MetaWindow *window)
{
double x, y, query_root_x, query_root_y;
Window root, child;
XIButtonState buttons;
XIModifierState mods;
XIGroupState group;
ClutterModifierType mods;
int button = 0;
meta_error_trap_push (window->display);
XIQueryPointer (window->display->xdisplay,
META_VIRTUAL_CORE_POINTER_ID,
window->xwindow,
&root, &child,
&query_root_x, &query_root_y,
&x, &y,
&buttons, &mods, &group);
meta_cursor_tracker_get_pointer (window->screen->cursor_tracker,
NULL, NULL, &mods);
if (meta_error_trap_pop_with_return (window->display) != Success)
goto out;
if (XIMaskIsSet (buttons.mask, Button1))
if (mods & CLUTTER_BUTTON1_MASK)
button |= 1 << 1;
if (XIMaskIsSet (buttons.mask, Button2))
if (mods & CLUTTER_BUTTON2_MASK)
button |= 1 << 2;
if (XIMaskIsSet (buttons.mask, Button3))
if (mods & CLUTTER_BUTTON3_MASK)
button |= 1 << 3;
free (buttons.mask);
out:
return button;
}
@@ -887,7 +872,7 @@ meta_window_x11_client_message (MetaWindow *window,
(action == _NET_WM_STATE_ADD) ||
(action == _NET_WM_STATE_TOGGLE && !window->wm_state_modal);
meta_window_recalc_window_type (window);
meta_window_x11_recalc_window_type (window);
meta_window_queue(window, META_QUEUE_MOVE_RESIZE);
}
@@ -1521,3 +1506,114 @@ error:
meta_error_trap_pop (display);
return NULL;
}
void
meta_window_x11_recalc_window_type (MetaWindow *window)
{
MetaWindowType type;
if (window->type_atom != None)
{
if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DESKTOP)
type = META_WINDOW_DESKTOP;
else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DOCK)
type = META_WINDOW_DOCK;
else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_TOOLBAR)
type = META_WINDOW_TOOLBAR;
else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_MENU)
type = META_WINDOW_MENU;
else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_UTILITY)
type = META_WINDOW_UTILITY;
else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_SPLASH)
type = META_WINDOW_SPLASHSCREEN;
else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DIALOG)
type = META_WINDOW_DIALOG;
else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_NORMAL)
type = META_WINDOW_NORMAL;
/* The below are *typically* override-redirect windows, but the spec does
* not disallow using them for managed windows.
*/
else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DROPDOWN_MENU)
type = META_WINDOW_DROPDOWN_MENU;
else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_POPUP_MENU)
type = META_WINDOW_POPUP_MENU;
else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_TOOLTIP)
type = META_WINDOW_TOOLTIP;
else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_NOTIFICATION)
type = META_WINDOW_NOTIFICATION;
else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_COMBO)
type = META_WINDOW_COMBO;
else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DND)
type = META_WINDOW_DND;
else
{
char *atom_name;
/*
* Fallback on a normal type, and print warning. Don't abort.
*/
type = META_WINDOW_NORMAL;
meta_error_trap_push (window->display);
atom_name = XGetAtomName (window->display->xdisplay,
window->type_atom);
meta_error_trap_pop (window->display);
meta_warning ("Unrecognized type atom [%s] set for %s \n",
atom_name ? atom_name : "unknown",
window->desc);
if (atom_name)
XFree (atom_name);
}
}
else if (window->transient_for != NULL)
{
type = META_WINDOW_DIALOG;
}
else
{
type = META_WINDOW_NORMAL;
}
if (type == META_WINDOW_DIALOG &&
window->wm_state_modal)
type = META_WINDOW_MODAL_DIALOG;
/* We don't want to allow override-redirect windows to have decorated-window
* types since that's just confusing.
*/
if (window->override_redirect)
{
switch (window->type)
{
/* Decorated types */
case META_WINDOW_NORMAL:
case META_WINDOW_DIALOG:
case META_WINDOW_MODAL_DIALOG:
case META_WINDOW_MENU:
case META_WINDOW_UTILITY:
type = META_WINDOW_OVERRIDE_OTHER;
break;
/* Undecorated types, normally not override-redirect */
case META_WINDOW_DESKTOP:
case META_WINDOW_DOCK:
case META_WINDOW_TOOLBAR:
case META_WINDOW_SPLASHSCREEN:
/* Undecorated types, normally override-redirect types */
case META_WINDOW_DROPDOWN_MENU:
case META_WINDOW_POPUP_MENU:
case META_WINDOW_TOOLTIP:
case META_WINDOW_NOTIFICATION:
case META_WINDOW_COMBO:
case META_WINDOW_DND:
/* To complete enum */
case META_WINDOW_OVERRIDE_OTHER:
break;
}
}
meta_verbose ("Calculated type %u for %s, old type %u\n",
type, window->desc, type);
meta_window_set_type (window, type);
}

View File

@@ -35,6 +35,8 @@ void meta_window_x11_update_opaque_region (MetaWindow *window);
void meta_window_x11_update_input_region (MetaWindow *window);
void meta_window_x11_update_shape_region (MetaWindow *window);
void meta_window_x11_recalc_window_type (MetaWindow *window);
gboolean meta_window_x11_configure_request (MetaWindow *window,
XEvent *event);
gboolean meta_window_x11_property_notify (MetaWindow *window,

View File

@@ -233,8 +233,6 @@ meta_window_finalize (GObject *object)
if (window->transient_for)
g_object_unref (window->transient_for);
meta_icon_cache_free (&window->icon_cache);
g_free (window->sm_client_id);
g_free (window->wm_client_machine);
g_free (window->startup_id);
@@ -818,7 +816,6 @@ _meta_window_shared_new (MetaDisplay *display,
window->icon_name = NULL;
window->icon = NULL;
window->mini_icon = NULL;
meta_icon_cache_init (&window->icon_cache);
window->wm_hints_pixmap = None;
window->wm_hints_mask = None;
window->wm_hints_urgent = FALSE;
@@ -3120,6 +3117,9 @@ meta_window_maximize_internal (MetaWindow *window,
meta_window_recalc_features (window);
set_net_wm_state (window);
if (window->surface && window->maximized_horizontally && window->maximized_vertically)
meta_wayland_surface_send_maximized (window->surface);
g_object_freeze_notify (G_OBJECT (window));
g_object_notify (G_OBJECT (window), "maximized-horizontally");
g_object_notify (G_OBJECT (window), "maximized-vertically");
@@ -3605,10 +3605,13 @@ meta_window_unmaximize_internal (MetaWindow *window,
set_net_wm_state (window);
}
g_object_freeze_notify (G_OBJECT (window));
g_object_notify (G_OBJECT (window), "maximized-horizontally");
g_object_notify (G_OBJECT (window), "maximized-vertically");
g_object_thaw_notify (G_OBJECT (window));
if (window->surface && !window->maximized_horizontally && !window->maximized_vertically)
meta_wayland_surface_send_unmaximized (window->surface);
g_object_freeze_notify (G_OBJECT (window));
g_object_notify (G_OBJECT (window), "maximized-horizontally");
g_object_notify (G_OBJECT (window), "maximized-vertically");
g_object_thaw_notify (G_OBJECT (window));
}
void
@@ -3711,6 +3714,9 @@ meta_window_make_fullscreen_internal (MetaWindow *window)
/* For the auto-minimize feature, if we fail to get focus */
meta_screen_queue_check_fullscreen (window->screen);
if (window->surface)
meta_wayland_surface_send_fullscreened (window->surface);
g_object_notify (G_OBJECT (window), "fullscreen");
}
}
@@ -3767,6 +3773,9 @@ meta_window_unmake_fullscreen (MetaWindow *window)
meta_window_update_layer (window);
if (window->surface)
meta_wayland_surface_send_unfullscreened (window->surface);
g_object_notify (G_OBJECT (window), "fullscreen");
}
}
@@ -5082,6 +5091,7 @@ meta_window_move_resize_wayland (MetaWindow *window,
meta_window_move_resize_internal (window, flags, NorthWestGravity,
x, y, width, height);
save_user_window_placement (window);
}
/**
@@ -6780,25 +6790,13 @@ meta_window_update_icon_now (MetaWindow *window)
icon = NULL;
mini_icon = NULL;
if (meta_read_icons (window->screen,
window->xwindow,
&window->icon_cache,
window->wm_hints_pixmap,
window->wm_hints_mask,
&icon,
META_ICON_WIDTH, META_ICON_HEIGHT,
&mini_icon,
META_MINI_ICON_WIDTH,
META_MINI_ICON_HEIGHT))
if (read_icons (window->screen,
window->xwindow,
window->wm_hints_pixmap,
window->wm_hints_mask,
&window->icon))
{
if (window->icon)
g_object_unref (G_OBJECT (window->icon));
if (window->mini_icon)
g_object_unref (G_OBJECT (window->mini_icon));
window->icon = icon;
window->mini_icon = mini_icon;
g_object_freeze_notify (G_OBJECT (window));
g_object_notify (G_OBJECT (window), "icon");
@@ -7051,122 +7049,7 @@ meta_window_update_struts (MetaWindow *window)
}
}
void
meta_window_recalc_window_type (MetaWindow *window)
{
MetaWindowType old_type;
old_type = window->type;
if (window->type_atom != None)
{
if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DESKTOP)
window->type = META_WINDOW_DESKTOP;
else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DOCK)
window->type = META_WINDOW_DOCK;
else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_TOOLBAR)
window->type = META_WINDOW_TOOLBAR;
else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_MENU)
window->type = META_WINDOW_MENU;
else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_UTILITY)
window->type = META_WINDOW_UTILITY;
else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_SPLASH)
window->type = META_WINDOW_SPLASHSCREEN;
else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DIALOG)
window->type = META_WINDOW_DIALOG;
else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_NORMAL)
window->type = META_WINDOW_NORMAL;
/* The below are *typically* override-redirect windows, but the spec does
* not disallow using them for managed windows.
*/
else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DROPDOWN_MENU)
window->type = META_WINDOW_DROPDOWN_MENU;
else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_POPUP_MENU)
window->type = META_WINDOW_POPUP_MENU;
else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_TOOLTIP)
window->type = META_WINDOW_TOOLTIP;
else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_NOTIFICATION)
window->type = META_WINDOW_NOTIFICATION;
else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_COMBO)
window->type = META_WINDOW_COMBO;
else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DND)
window->type = META_WINDOW_DND;
else
{
char *atom_name;
/*
* Fallback on a normal type, and print warning. Don't abort.
*/
window->type = META_WINDOW_NORMAL;
meta_error_trap_push (window->display);
atom_name = XGetAtomName (window->display->xdisplay,
window->type_atom);
meta_error_trap_pop (window->display);
meta_warning ("Unrecognized type atom [%s] set for %s \n",
atom_name ? atom_name : "unknown",
window->desc);
if (atom_name)
XFree (atom_name);
}
}
else if (window->transient_for != NULL)
{
window->type = META_WINDOW_DIALOG;
}
else
{
window->type = META_WINDOW_NORMAL;
}
if (window->type == META_WINDOW_DIALOG &&
window->wm_state_modal)
window->type = META_WINDOW_MODAL_DIALOG;
/* We don't want to allow override-redirect windows to have decorated-window
* types since that's just confusing.
*/
if (window->override_redirect)
{
switch (window->type)
{
/* Decorated types */
case META_WINDOW_NORMAL:
case META_WINDOW_DIALOG:
case META_WINDOW_MODAL_DIALOG:
case META_WINDOW_MENU:
case META_WINDOW_UTILITY:
window->type = META_WINDOW_OVERRIDE_OTHER;
break;
/* Undecorated types, normally not override-redirect */
case META_WINDOW_DESKTOP:
case META_WINDOW_DOCK:
case META_WINDOW_TOOLBAR:
case META_WINDOW_SPLASHSCREEN:
/* Undecorated types, normally override-redirect types */
case META_WINDOW_DROPDOWN_MENU:
case META_WINDOW_POPUP_MENU:
case META_WINDOW_TOOLTIP:
case META_WINDOW_NOTIFICATION:
case META_WINDOW_COMBO:
case META_WINDOW_DND:
/* To complete enum */
case META_WINDOW_OVERRIDE_OTHER:
break;
}
}
meta_verbose ("Calculated type %u for %s, old type %u\n",
window->type, window->desc, old_type);
if (old_type != window->type)
meta_window_type_changed (window);
}
void
static void
meta_window_type_changed (MetaWindow *window)
{
gboolean old_decorated = window->decorated;
@@ -7199,6 +7082,17 @@ meta_window_type_changed (MetaWindow *window)
g_object_thaw_notify (object);
}
void
meta_window_set_type (MetaWindow *window,
MetaWindowType type)
{
if (window->type == type)
return;
window->type = type;
meta_window_type_changed (window);
}
void
meta_window_frame_size_changed (MetaWindow *window)
{
@@ -7840,7 +7734,7 @@ meta_window_titlebar_is_onscreen (MetaWindow *window)
/* Titlebar can't be offscreen if there is no titlebar... */
if (!window->frame)
return FALSE;
return TRUE;
/* Get the rectangle corresponding to the titlebar */
meta_window_get_frame_rect (window, &titlebar_rect);
@@ -8855,6 +8749,34 @@ meta_window_same_application (MetaWindow *window,
group==other_group;
}
/**
* meta_window_is_client_decorated:
*
* Check if if the window has decorations drawn by the client.
* (window->decorated refers only to whether we should add decorations)
*/
gboolean
meta_window_is_client_decorated (MetaWindow *window)
{
if (window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND)
{
/* Assume all Wayland clients draw decorations - not strictly
* true but good enough for current purposes.
*/
return TRUE;
}
else
{
/* Currently the implementation here is hackish -
* has_custom_frame_extents() is set if _GTK_FRAME_EXTENTS is set
* to any value even 0. GTK+ always sets _GTK_FRAME_EXTENTS for
* client-side-decorated window, even if the value is 0 because
* the window is maxized and has no invisible borders or shadows.
*/
return window->has_custom_frame_extents;
}
}
void
meta_window_refresh_resize_popup (MetaWindow *window)
{
@@ -10217,7 +10139,8 @@ meta_window_set_transient_for (MetaWindow *window,
meta_window_propagate_focus_appearance (window, FALSE);
/* may now be a dialog */
meta_window_recalc_window_type (window);
if (window->client_type == META_WINDOW_CLIENT_TYPE_X11)
meta_window_x11_recalc_window_type (window);
if (!window->constructing)
{
@@ -10343,25 +10266,15 @@ window_focus_on_pointer_rest_callback (gpointer data)
MetaWindow *window = focus_data->window;
MetaDisplay *display = window->display;
MetaScreen *screen = window->screen;
Window root, child;
double root_x, root_y, x, y;
int root_x, root_y;
guint32 timestamp;
XIButtonState buttons;
XIModifierState mods;
XIGroupState group;
ClutterActor *child;
if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK)
goto out;
meta_error_trap_push (display);
XIQueryPointer (display->xdisplay,
META_VIRTUAL_CORE_POINTER_ID,
screen->xroot,
&root, &child,
&root_x, &root_y, &x, &y,
&buttons, &mods, &group);
meta_error_trap_pop (display);
free (buttons.mask);
meta_cursor_tracker_get_pointer (screen->cursor_tracker,
&root_x, &root_y, NULL);
if (root_x != focus_data->pointer_x ||
root_y != focus_data->pointer_y)
@@ -10371,17 +10284,15 @@ window_focus_on_pointer_rest_callback (gpointer data)
return TRUE;
}
/* Explicitly check for the overlay window, as get_focus_window_at_point()
* may return windows that extend underneath the chrome (like
* override-redirect or DESKTOP windows)
*/
if (child == meta_get_overlay_window (screen))
child = clutter_stage_get_actor_at_pos (CLUTTER_STAGE (clutter_stage_get_default ()),
CLUTTER_PICK_REACTIVE, root_x, root_y);
if (!META_IS_SURFACE_ACTOR (child))
goto out;
window =
meta_stack_get_default_focus_window_at_point (screen->stack,
screen->active_workspace,
None, root_x, root_y);
NULL, root_x, root_y);
if (window == NULL)
goto out;

View File

@@ -228,7 +228,10 @@ typedef enum
META_GRAB_OP_CLICKING_UNSTICK,
/* Special grab op when the compositor asked for a grab */
META_GRAB_OP_COMPOSITOR
META_GRAB_OP_COMPOSITOR,
/* For when a client takes a popup grab */
META_GRAB_OP_WAYLAND_CLIENT,
} MetaGrabOp;
/**
@@ -489,12 +492,6 @@ struct _MetaFrameBorders
/* sets all dimensions to zero */
void meta_frame_borders_clear (MetaFrameBorders *self);
/* should investigate changing these to whatever most apps use */
#define META_ICON_WIDTH 96
#define META_ICON_HEIGHT 96
#define META_MINI_ICON_WIDTH 16
#define META_MINI_ICON_HEIGHT 16
#define META_DEFAULT_ICON_NAME "window"
/* Main loop priorities determine when activity in the GLib

View File

@@ -28,6 +28,7 @@ GOptionContext *meta_get_option_context (void);
void meta_init (void);
int meta_run (void);
void meta_register_with_session (void);
gboolean meta_activate_session (void);
gboolean meta_get_replace_current_wm (void); /* Actually defined in util.c */
void meta_set_wm_name (const char *wm_name);

View File

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

View File

@@ -44,8 +44,6 @@
static void meta_frames_destroy (GtkWidget *object);
static void meta_frames_finalize (GObject *object);
static void meta_frames_style_updated (GtkWidget *widget);
static void meta_frames_map (GtkWidget *widget);
static void meta_frames_unmap (GtkWidget *widget);
static void meta_frames_update_prelit_control (MetaFrames *frames,
MetaUIFrame *frame,
@@ -134,9 +132,6 @@ meta_frames_class_init (MetaFramesClass *class)
widget_class->style_updated = meta_frames_style_updated;
widget_class->map = meta_frames_map;
widget_class->unmap = meta_frames_unmap;
widget_class->draw = meta_frames_draw;
widget_class->destroy_event = meta_frames_destroy_event;
widget_class->button_press_event = meta_frames_button_press_event;
@@ -231,6 +226,7 @@ meta_frames_init (MetaFrames *frames)
frames->style_variants = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, g_object_unref);
update_style_contexts (frames);
gtk_widget_set_double_buffered (GTK_WIDGET (frames), FALSE);
@@ -522,13 +518,26 @@ MetaFrames*
meta_frames_new (int screen_number)
{
GdkScreen *screen;
MetaFrames *frames;
screen = gdk_display_get_screen (gdk_display_get_default (),
screen_number);
return g_object_new (META_TYPE_FRAMES,
"screen", screen,
NULL);
frames = g_object_new (META_TYPE_FRAMES,
"screen", screen,
"type", GTK_WINDOW_POPUP,
NULL);
/* Put the window at an arbitrary offscreen location; the one place
* it can't be is at -100x-100, since the meta_window_new() will
* mistake it for a window created via meta_create_offscreen_window()
* and ignore it, and we need this window to get frame-synchronization
* messages so that GTK+'s style change handling works.
*/
gtk_window_move (GTK_WINDOW (frames), -200, -200);
gtk_window_resize (GTK_WINDOW (frames), 1, 1);
return frames;
}
/* In order to use a style with a window it has to be attached to that
@@ -635,22 +644,6 @@ meta_frames_unmanage_window (MetaFrames *frames,
meta_warning ("Frame 0x%lx not managed, can't unmanage\n", xwindow);
}
static void
meta_frames_map (GtkWidget *widget)
{
/* We override the parent map function to a no-op because we don't
* want to actually show the GDK window. But GTK needs to think that
* the widget is mapped or it won't deliver the events we care about.
*/
gtk_widget_set_mapped (widget, TRUE);
}
static void
meta_frames_unmap (GtkWidget *widget)
{
gtk_widget_set_mapped (widget, FALSE);
}
static MetaUIFrame*
meta_frames_lookup_window (MetaFrames *frames,
Window xwindow)

View File

@@ -295,9 +295,12 @@ meta_ui_new (Display *xdisplay,
g_assert (gdisplay == gdk_display_get_default ());
ui->frames = meta_frames_new (XScreenNumberOfScreen (screen));
/* This does not actually show any widget. MetaFrames has been hacked so
* that showing it doesn't actually do anything. But we need the flags
* set for GTK to deliver events properly. */
/* GTK+ needs the frame-sync protocol to work in order to properly
* handle style changes. This means that the dummy widget we create
* to get the style for title bars actually needs to be mapped
* and fully tracked as a MetaWindow. Horrible, but mostly harmless -
* the window is a 1x1 overide redirect window positioned offscreen.
*/
gtk_widget_show (GTK_WIDGET (ui->frames));
g_object_set_data (G_OBJECT (gdisplay), "meta-ui", ui);
@@ -595,76 +598,6 @@ meta_gdk_pixbuf_get_from_pixmap (Pixmap xpixmap,
return retval;
}
GdkPixbuf*
meta_ui_get_default_window_icon (MetaUI *ui)
{
static GdkPixbuf *default_icon = NULL;
if (default_icon == NULL)
{
GtkIconTheme *theme;
gboolean icon_exists;
theme = gtk_icon_theme_get_default ();
icon_exists = gtk_icon_theme_has_icon (theme, META_DEFAULT_ICON_NAME);
if (icon_exists)
default_icon = gtk_icon_theme_load_icon (theme,
META_DEFAULT_ICON_NAME,
META_ICON_WIDTH,
0,
NULL);
else
default_icon = gtk_icon_theme_load_icon (theme,
"image-missing",
META_ICON_WIDTH,
0,
NULL);
g_assert (default_icon);
}
g_object_ref (G_OBJECT (default_icon));
return default_icon;
}
GdkPixbuf*
meta_ui_get_default_mini_icon (MetaUI *ui)
{
static GdkPixbuf *default_icon = NULL;
if (default_icon == NULL)
{
GtkIconTheme *theme;
gboolean icon_exists;
theme = gtk_icon_theme_get_default ();
icon_exists = gtk_icon_theme_has_icon (theme, META_DEFAULT_ICON_NAME);
if (icon_exists)
default_icon = gtk_icon_theme_load_icon (theme,
META_DEFAULT_ICON_NAME,
META_MINI_ICON_WIDTH,
0,
NULL);
else
default_icon = gtk_icon_theme_load_icon (theme,
"image-missing",
META_MINI_ICON_WIDTH,
0,
NULL);
g_assert (default_icon);
}
g_object_ref (G_OBJECT (default_icon));
return default_icon;
}
gboolean
meta_ui_window_should_not_cause_focus (Display *xdisplay,
Window xwindow)
@@ -772,7 +705,6 @@ void
meta_ui_set_current_theme (const char *name)
{
meta_theme_set_current (name);
meta_invalidate_default_icons ();
}
gboolean

View File

@@ -143,9 +143,6 @@ GdkPixbuf* meta_gdk_pixbuf_get_from_pixmap (Pixmap xpixmap,
int width,
int height);
GdkPixbuf* meta_ui_get_default_window_icon (MetaUI *ui);
GdkPixbuf* meta_ui_get_default_mini_icon (MetaUI *ui);
gboolean meta_ui_window_should_not_cause_focus (Display *xdisplay,
Window xwindow);

View File

@@ -48,7 +48,7 @@ data_offer_accept (struct wl_client *client,
* this be a wl_data_device request? */
if (offer->source)
offer->source->accept (offer->source, serial, mime_type);
wl_data_source_send_target (offer->source->resource, mime_type);
}
static void
@@ -58,9 +58,9 @@ data_offer_receive (struct wl_client *client, struct wl_resource *resource,
MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource);
if (offer->source)
offer->source->send (offer->source, mime_type, fd);
else
close (fd);
wl_data_source_send_send (offer->source->resource, mime_type, fd);
close (fd);
}
static void
@@ -82,7 +82,8 @@ destroy_data_offer (struct wl_resource *resource)
if (offer->source)
wl_list_remove (&offer->source_destroy_listener.link);
free (offer);
g_slice_free (MetaWaylandDataOffer, offer);
}
static void
@@ -99,13 +100,9 @@ static struct wl_resource *
meta_wayland_data_source_send_offer (MetaWaylandDataSource *source,
struct wl_resource *target)
{
MetaWaylandDataOffer *offer;
MetaWaylandDataOffer *offer = g_slice_new0 (MetaWaylandDataOffer);
char **p;
offer = malloc (sizeof *offer);
if (offer == NULL)
return NULL;
offer->source = source;
offer->source_destroy_listener.notify = destroy_offer_data_source;
@@ -318,8 +315,12 @@ data_device_start_drag (struct wl_client *client,
{
MetaWaylandSeat *seat = wl_resource_get_user_data (resource);
MetaWaylandDragGrab *drag_grab;
/* FIXME: Check that client has implicit grab on the origin
* surface that matches the given time. */
if ((seat->pointer.button_count == 0 ||
seat->pointer.grab_serial != serial ||
!seat->pointer.focus_surface ||
seat->pointer.focus_surface != wl_resource_get_user_data (origin_resource)))
return;
/* FIXME: Check that the data source type array isn't empty. */
@@ -332,6 +333,7 @@ data_device_start_drag (struct wl_client *client,
drag_grab->generic.pointer = &seat->pointer;
drag_grab->drag_client = client;
drag_grab->seat = seat;
if (source_resource)
{
@@ -375,7 +377,7 @@ destroy_selection_data_source (struct wl_listener *listener, void *data)
}
}
void
static void
meta_wayland_seat_set_selection (MetaWaylandSeat *seat,
MetaWaylandDataSource *source,
guint32 serial)
@@ -389,7 +391,7 @@ meta_wayland_seat_set_selection (MetaWaylandSeat *seat,
if (seat->selection_data_source)
{
seat->selection_data_source->cancel (seat->selection_data_source);
wl_data_source_send_cancelled (seat->selection_data_source->resource);
wl_list_remove (&seat->selection_data_source_listener.link);
seat->selection_data_source = NULL;
}
@@ -449,47 +451,21 @@ static const struct wl_data_device_interface data_device_interface = {
static void
destroy_data_source (struct wl_resource *resource)
{
MetaWaylandDataSource *source = wl_container_of (resource, source, resource);
MetaWaylandDataSource *source = wl_resource_get_user_data (resource);
char **p;
wl_array_for_each (p, &source->mime_types) free (*p);
wl_array_release (&source->mime_types);
}
static void
client_source_accept (MetaWaylandDataSource *source,
guint32 time, const char *mime_type)
{
wl_data_source_send_target (source->resource, mime_type);
}
static void
client_source_send (MetaWaylandDataSource *source,
const char *mime_type, int32_t fd)
{
wl_data_source_send_send (source->resource, mime_type, fd);
close (fd);
}
static void
client_source_cancel (MetaWaylandDataSource *source)
{
wl_data_source_send_cancelled (source->resource);
g_slice_free (MetaWaylandDataSource, source);
}
static void
create_data_source (struct wl_client *client,
struct wl_resource *resource, guint32 id)
{
MetaWaylandDataSource *source;
source = malloc (sizeof *source);
if (source == NULL)
{
wl_resource_post_no_memory (resource);
return;
}
MetaWaylandDataSource *source = g_slice_new0 (MetaWaylandDataSource);
source->resource = wl_resource_create (client, &wl_data_source_interface,
MIN (META_WL_DATA_SOURCE_VERSION,
@@ -497,10 +473,6 @@ create_data_source (struct wl_client *client,
wl_resource_set_implementation (source->resource, &data_source_interface,
source, destroy_data_source);
source->accept = client_source_accept;
source->send = client_source_send;
source->cancel = client_source_cancel;
wl_array_init (&source->mime_types);
}

View File

@@ -33,10 +33,4 @@ meta_wayland_data_device_set_keyboard_focus (MetaWaylandSeat *seat);
int
meta_wayland_data_device_manager_init (struct wl_display *display);
void
meta_wayland_seat_set_selection (MetaWaylandSeat *seat,
MetaWaylandDataSource *source,
uint32_t serial);
#endif /* __META_WAYLAND_DATA_DEVICE_H__ */

View File

@@ -142,20 +142,6 @@ meta_wayland_keyboard_take_keymap (MetaWaylandKeyboard *keyboard,
xkb_keymap_unref (xkb_info->keymap);
xkb_info->keymap = keymap;
xkb_info->shift_mod =
xkb_map_mod_get_index (xkb_info->keymap, XKB_MOD_NAME_SHIFT);
xkb_info->caps_mod =
xkb_map_mod_get_index (xkb_info->keymap, XKB_MOD_NAME_CAPS);
xkb_info->ctrl_mod =
xkb_map_mod_get_index (xkb_info->keymap, XKB_MOD_NAME_CTRL);
xkb_info->alt_mod =
xkb_map_mod_get_index (xkb_info->keymap, XKB_MOD_NAME_ALT);
xkb_info->mod2_mod = xkb_map_mod_get_index (xkb_info->keymap, "Mod2");
xkb_info->mod3_mod = xkb_map_mod_get_index (xkb_info->keymap, "Mod3");
xkb_info->super_mod =
xkb_map_mod_get_index (xkb_info->keymap, XKB_MOD_NAME_LOGO);
xkb_info->mod5_mod = xkb_map_mod_get_index (xkb_info->keymap, "Mod5");
keymap_str = xkb_map_get_as_string (xkb_info->keymap);
if (keymap_str == NULL)
{
@@ -295,31 +281,6 @@ static const MetaWaylandKeyboardGrabInterface
default_grab_modifiers,
};
static gboolean
modal_key (MetaWaylandKeyboardGrab *grab,
uint32_t time,
uint32_t key,
uint32_t state)
{
/* FALSE means: let the event through to clutter */
return FALSE;
}
static void
modal_modifiers (MetaWaylandKeyboardGrab *grab,
uint32_t serial,
uint32_t mods_depressed,
uint32_t mods_latched,
uint32_t mods_locked,
uint32_t group)
{
}
static MetaWaylandKeyboardGrabInterface modal_grab = {
modal_key,
modal_modifiers,
};
gboolean
meta_wayland_keyboard_init (MetaWaylandKeyboard *keyboard,
struct wl_display *display)
@@ -535,26 +496,13 @@ meta_wayland_keyboard_set_focus (MetaWaylandKeyboard *keyboard,
struct wl_display *display = wl_client_get_display (client);
uint32_t serial = wl_display_next_serial (display);
/* If we're in a modal grab, the client is focused but doesn't see
modifiers or pressed keys (and fix that up when we exit the modal) */
if (keyboard->grab->interface == &modal_grab)
{
struct wl_array empty;
wl_array_init (&empty);
wl_keyboard_send_modifiers (keyboard->focus_resource, serial, 0, 0, 0, 0);
wl_keyboard_send_enter (keyboard->focus_resource, serial, keyboard->focus_surface->resource, &empty);
}
else
{
wl_keyboard_send_modifiers (keyboard->focus_resource, serial,
keyboard->modifier_state.mods_depressed,
keyboard->modifier_state.mods_latched,
keyboard->modifier_state.mods_locked,
keyboard->modifier_state.group);
wl_keyboard_send_enter (keyboard->focus_resource, serial, keyboard->focus_surface->resource,
&keyboard->keys);
}
wl_keyboard_send_modifiers (keyboard->focus_resource, serial,
keyboard->modifier_state.mods_depressed,
keyboard->modifier_state.mods_latched,
keyboard->modifier_state.mods_locked,
keyboard->modifier_state.group);
wl_keyboard_send_enter (keyboard->focus_resource, serial, keyboard->focus_surface->resource,
&keyboard->keys);
wl_resource_add_destroy_listener (keyboard->focus_resource, &keyboard->focus_resource_listener);
keyboard->focus_serial = serial;
@@ -588,85 +536,6 @@ meta_wayland_keyboard_release (MetaWaylandKeyboard *keyboard)
wl_array_release (&keyboard->keys);
}
gboolean
meta_wayland_keyboard_begin_modal (MetaWaylandKeyboard *keyboard,
guint32 timestamp)
{
MetaWaylandKeyboardGrab *grab;
uint32_t *end = (void *) ((char *) keyboard->keys.data +
keyboard->keys.size);
uint32_t *k;
uint32_t serial;
meta_verbose ("Asked to acquire modal keyboard grab, timestamp %d\n", timestamp);
if (keyboard->grab != &keyboard->default_grab)
return FALSE;
if (keyboard->focus_surface)
{
/* Fake key release events for the focused app */
serial = wl_display_next_serial (keyboard->display);
keyboard->grab->interface->modifiers (keyboard->grab,
serial,
0, 0, 0, 0);
for (k = keyboard->keys.data; k < end; k++)
{
keyboard->grab->interface->key (keyboard->grab,
timestamp,
*k, 0);
}
}
grab = g_slice_new0 (MetaWaylandKeyboardGrab);
grab->interface = &modal_grab;
meta_wayland_keyboard_start_grab (keyboard, grab);
meta_verbose ("Acquired modal keyboard grab, timestamp %d\n", timestamp);
return TRUE;
}
void
meta_wayland_keyboard_end_modal (MetaWaylandKeyboard *keyboard,
guint32 timestamp)
{
MetaWaylandKeyboardGrab *grab;
uint32_t *end = (void *) ((char *) keyboard->keys.data +
keyboard->keys.size);
uint32_t *k;
uint32_t serial;
grab = keyboard->grab;
g_assert (grab->interface == &modal_grab);
meta_wayland_keyboard_end_grab (keyboard);
g_slice_free (MetaWaylandKeyboardGrab, grab);
if (keyboard->focus_surface)
{
/* Fake key press events for the focused app */
serial = wl_display_next_serial (keyboard->display);
keyboard->grab->interface->modifiers (keyboard->grab,
serial,
keyboard->modifier_state.mods_depressed,
keyboard->modifier_state.mods_latched,
keyboard->modifier_state.mods_locked,
keyboard->modifier_state.group);
for (k = keyboard->keys.data; k < end; k++)
{
keyboard->grab->interface->key (keyboard->grab,
timestamp,
*k, 1);
}
}
meta_verbose ("Released modal keyboard grab, timestamp %d\n", timestamp);
}
void
meta_wayland_keyboard_set_keymap_names (MetaWaylandKeyboard *keyboard,
const char *rules,

View File

@@ -72,14 +72,6 @@ typedef struct
int keymap_fd;
size_t keymap_size;
char *keymap_area;
xkb_mod_index_t shift_mod;
xkb_mod_index_t caps_mod;
xkb_mod_index_t ctrl_mod;
xkb_mod_index_t alt_mod;
xkb_mod_index_t mod2_mod;
xkb_mod_index_t mod3_mod;
xkb_mod_index_t super_mod;
xkb_mod_index_t mod5_mod;
} MetaWaylandXkbInfo;
typedef struct
@@ -150,13 +142,6 @@ meta_wayland_keyboard_start_grab (MetaWaylandKeyboard *device,
void
meta_wayland_keyboard_end_grab (MetaWaylandKeyboard *keyboard);
gboolean
meta_wayland_keyboard_begin_modal (MetaWaylandKeyboard *keyboard,
guint32 timestamp);
void
meta_wayland_keyboard_end_modal (MetaWaylandKeyboard *keyboard,
guint32 timestamp);
void
meta_wayland_keyboard_release (MetaWaylandKeyboard *keyboard);

View File

@@ -398,61 +398,6 @@ meta_wayland_pointer_end_grab (MetaWaylandPointer *pointer)
interface->focus (pointer->grab, pointer->current, NULL);
}
static void
modal_focus (MetaWaylandPointerGrab *grab,
MetaWaylandSurface *surface,
const ClutterEvent *event)
{
}
static void
modal_motion (MetaWaylandPointerGrab *grab,
const ClutterEvent *event)
{
}
static void
modal_button (MetaWaylandPointerGrab *grab,
const ClutterEvent *event)
{
}
static MetaWaylandPointerGrabInterface modal_grab = {
modal_focus,
modal_motion,
modal_button
};
gboolean
meta_wayland_pointer_begin_modal (MetaWaylandPointer *pointer)
{
MetaWaylandPointerGrab *grab;
if (pointer->grab != &pointer->default_grab)
return FALSE;
meta_wayland_pointer_set_focus (pointer, NULL);
grab = g_slice_new0 (MetaWaylandPointerGrab);
grab->interface = &modal_grab;
meta_wayland_pointer_start_grab (pointer, grab);
return TRUE;
}
void
meta_wayland_pointer_end_modal (MetaWaylandPointer *pointer)
{
MetaWaylandPointerGrab *grab;
grab = pointer->grab;
g_assert (grab->interface == &modal_grab);
meta_wayland_pointer_end_grab (pointer);
g_slice_free (MetaWaylandPointerGrab, grab);
}
typedef struct {
MetaWaylandPointerGrab generic;
@@ -533,6 +478,12 @@ meta_wayland_pointer_end_popup_grab (MetaWaylandPointer *pointer)
g_slice_free (MetaWaylandPopup, popup);
}
{
MetaDisplay *display = meta_get_display ();
meta_display_end_grab_op (display,
meta_display_get_current_time_roundtrip (display));
}
meta_wayland_pointer_end_grab (pointer);
g_slice_free (MetaWaylandPopupGrab, popup_grab);
}
@@ -572,6 +523,8 @@ meta_wayland_pointer_start_popup_grab (MetaWaylandPointer *pointer,
if (pointer->grab == &pointer->default_grab)
{
MetaWindow *window = surface->window;
grab = g_slice_new0 (MetaWaylandPopupGrab);
grab->generic.interface = &popup_grab_interface;
grab->generic.pointer = pointer;
@@ -579,6 +532,19 @@ meta_wayland_pointer_start_popup_grab (MetaWaylandPointer *pointer,
wl_list_init (&grab->all_popups);
meta_wayland_pointer_start_grab (pointer, (MetaWaylandPointerGrab*)grab);
meta_display_begin_grab_op (window->display,
window->screen,
window,
META_GRAB_OP_WAYLAND_CLIENT,
FALSE, /* pointer_already_grabbed */
FALSE, /* frame_action */
1, /* button. XXX? */
0, /* modmask */
meta_display_get_current_time_roundtrip (window->display),
wl_fixed_to_int (pointer->grab_x),
wl_fixed_to_int (pointer->grab_y));
}
else
grab = (MetaWaylandPopupGrab*)pointer->grab;
@@ -593,7 +559,6 @@ meta_wayland_pointer_start_popup_grab (MetaWaylandPointer *pointer,
wl_resource_add_destroy_listener (surface->wl_shell_surface.resource, &popup->surface_destroy_listener);
wl_list_insert (&grab->all_popups, &popup->link);
return TRUE;
}

View File

@@ -85,11 +85,6 @@ meta_wayland_pointer_start_grab (MetaWaylandPointer *pointer,
void
meta_wayland_pointer_end_grab (MetaWaylandPointer *pointer);
gboolean
meta_wayland_pointer_begin_modal (MetaWaylandPointer *pointer);
void
meta_wayland_pointer_end_modal (MetaWaylandPointer *pointer);
gboolean
meta_wayland_pointer_start_popup_grab (MetaWaylandPointer *pointer,
MetaWaylandSurface *popup);

View File

@@ -276,42 +276,53 @@ static void
handle_scroll_event (MetaWaylandSeat *seat,
const ClutterEvent *event)
{
enum wl_pointer_axis axis;
wl_fixed_t value;
wl_fixed_t x_value = 0, y_value = 0;
notify_motion (seat, event);
if (!seat->pointer.focus_resource)
return;
if (clutter_event_is_pointer_emulated (event))
return;
switch (clutter_event_get_scroll_direction (event))
{
case CLUTTER_SCROLL_UP:
axis = WL_POINTER_AXIS_VERTICAL_SCROLL;
value = -DEFAULT_AXIS_STEP_DISTANCE;
y_value = -DEFAULT_AXIS_STEP_DISTANCE;
break;
case CLUTTER_SCROLL_DOWN:
axis = WL_POINTER_AXIS_VERTICAL_SCROLL;
value = DEFAULT_AXIS_STEP_DISTANCE;
y_value = DEFAULT_AXIS_STEP_DISTANCE;
break;
case CLUTTER_SCROLL_LEFT:
axis = WL_POINTER_AXIS_HORIZONTAL_SCROLL;
value = -DEFAULT_AXIS_STEP_DISTANCE;
x_value = -DEFAULT_AXIS_STEP_DISTANCE;
break;
case CLUTTER_SCROLL_RIGHT:
axis = WL_POINTER_AXIS_HORIZONTAL_SCROLL;
value = DEFAULT_AXIS_STEP_DISTANCE;
x_value = DEFAULT_AXIS_STEP_DISTANCE;
break;
case CLUTTER_SCROLL_SMOOTH:
{
double dx, dy;
clutter_event_get_scroll_delta (event, &dx, &dy);
x_value = wl_fixed_from_double (dx);
y_value = wl_fixed_from_double (dy);
}
break;
default:
return;
}
if (seat->pointer.focus_resource)
wl_pointer_send_axis (seat->pointer.focus_resource,
clutter_event_get_time (event),
axis,
value);
if (x_value)
wl_pointer_send_axis (seat->pointer.focus_resource, clutter_event_get_time (event),
WL_POINTER_AXIS_HORIZONTAL_SCROLL, x_value);
if (y_value)
wl_pointer_send_axis (seat->pointer.focus_resource, clutter_event_get_time (event),
WL_POINTER_AXIS_VERTICAL_SCROLL, y_value);
}
static int

View File

@@ -43,12 +43,6 @@ struct _MetaWaylandDataSource
{
struct wl_resource *resource;
struct wl_array mime_types;
void (*accept) (MetaWaylandDataSource * source,
uint32_t serial, const char *mime_type);
void (*send) (MetaWaylandDataSource * source,
const char *mime_type, int32_t fd);
void (*cancel) (MetaWaylandDataSource * source);
};
struct _MetaWaylandSeat

View File

@@ -336,22 +336,6 @@ toplevel_surface_commit (MetaWaylandSurface *surface,
if (pending->frame_extents_changed)
meta_window_set_custom_frame_extents (surface->window, &pending->frame_extents);
if (pending->maximized.changed)
{
if (pending->maximized.value)
meta_window_maximize (surface->window, META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL);
else
meta_window_unmaximize (surface->window, META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL);
}
if (pending->fullscreen.changed)
{
if (pending->fullscreen.value)
meta_window_make_fullscreen (surface->window);
else
meta_window_unmake_fullscreen (surface->window);
}
}
static void
@@ -377,8 +361,6 @@ double_buffered_state_init (MetaWaylandDoubleBufferedState *state)
wl_list_init (&state->frame_callback_list);
state->frame_extents_changed = FALSE;
state->maximized.changed = FALSE;
state->fullscreen.changed = FALSE;
}
static void
@@ -861,44 +843,44 @@ xdg_surface_set_output (struct wl_client *client,
}
static void
xdg_surface_set_fullscreen (struct wl_client *client,
struct wl_resource *resource)
xdg_surface_request_change_state (struct wl_client *client,
struct wl_resource *resource,
uint32_t state_type,
uint32_t value,
uint32_t serial)
{
MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
surface->pending.fullscreen.changed = TRUE;
surface->pending.fullscreen.value = TRUE;
surface->state_changed_serial = serial;
switch (state_type)
{
case XDG_SURFACE_STATE_MAXIMIZED:
if (value)
meta_window_maximize (surface->window, META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL);
else
meta_window_unmaximize (surface->window, META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL);
break;
case XDG_SURFACE_STATE_FULLSCREEN:
if (value)
meta_window_make_fullscreen (surface->window);
else
meta_window_unmake_fullscreen (surface->window);
}
}
static void
xdg_surface_unset_fullscreen (struct wl_client *client,
struct wl_resource *resource)
xdg_surface_ack_change_state (struct wl_client *client,
struct wl_resource *resource,
uint32_t state_type,
uint32_t value,
uint32_t serial)
{
MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource);
MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface);
surface->pending.fullscreen.changed = TRUE;
surface->pending.fullscreen.value = FALSE;
}
static void
xdg_surface_set_maximized (struct wl_client *client,
struct wl_resource *resource)
{
MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
surface->pending.maximized.changed = TRUE;
surface->pending.maximized.value = TRUE;
}
static void
xdg_surface_unset_maximized (struct wl_client *client,
struct wl_resource *resource)
{
MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
surface->pending.maximized.changed = TRUE;
surface->pending.maximized.value = FALSE;
/* Do nothing for now. In the future, we'd imagine that
* we'd ignore attaches when we have a state pending that
* we haven't had the client ACK'd, to prevent a race
* condition when we have an in-flight attach when the
* client gets the new state. */
}
static void
@@ -919,10 +901,8 @@ static const struct xdg_surface_interface meta_wayland_xdg_surface_interface = {
xdg_surface_move,
xdg_surface_resize,
xdg_surface_set_output,
xdg_surface_set_fullscreen,
xdg_surface_unset_fullscreen,
xdg_surface_set_maximized,
xdg_surface_unset_maximized,
xdg_surface_request_change_state,
xdg_surface_ack_change_state,
xdg_surface_set_minimized,
};
@@ -1011,8 +991,7 @@ xdg_shell_get_xdg_popup (struct wl_client *client,
surface->window->placed = TRUE;
meta_window_set_transient_for (surface->window, parent_surf->window);
surface->window->type = META_WINDOW_DROPDOWN_MENU;
meta_window_type_changed (surface->window);
meta_window_set_type (surface->window, META_WINDOW_DROPDOWN_MENU);
meta_wayland_pointer_start_popup_grab (&seat->pointer, surface);
}
@@ -1465,8 +1444,6 @@ subsurface_parent_surface_committed (MetaWaylandSurface *surface)
if (surface->sub.synchronous)
commit_double_buffered_state (surface, pending_surface_state);
double_buffered_state_reset (pending_surface_state);
}
static void
@@ -1738,6 +1715,55 @@ meta_wayland_surface_configure_notify (MetaWaylandSurface *surface,
0, new_width, new_height);
}
static void
send_change_state (MetaWaylandSurface *surface,
uint32_t state_type,
uint32_t value)
{
if (surface->xdg_surface.resource)
{
uint32_t serial;
if (surface->state_changed_serial != 0)
{
serial = surface->state_changed_serial;
surface->state_changed_serial = 0;
}
else
{
struct wl_client *client = wl_resource_get_client (surface->xdg_surface.resource);
struct wl_display *display = wl_client_get_display (client);
serial = wl_display_next_serial (display);
}
xdg_surface_send_change_state (surface->xdg_surface.resource, state_type, value, serial);
}
}
void
meta_wayland_surface_send_maximized (MetaWaylandSurface *surface)
{
send_change_state (surface, XDG_SURFACE_STATE_MAXIMIZED, TRUE);
}
void
meta_wayland_surface_send_unmaximized (MetaWaylandSurface *surface)
{
send_change_state (surface, XDG_SURFACE_STATE_MAXIMIZED, FALSE);
}
void
meta_wayland_surface_send_fullscreened (MetaWaylandSurface *surface)
{
send_change_state (surface, XDG_SURFACE_STATE_FULLSCREEN, TRUE);
}
void
meta_wayland_surface_send_unfullscreened (MetaWaylandSurface *surface)
{
send_change_state (surface, XDG_SURFACE_STATE_FULLSCREEN, FALSE);
}
void
meta_wayland_surface_activated (MetaWaylandSurface *surface)
{

View File

@@ -41,12 +41,6 @@ struct _MetaWaylandBuffer
uint32_t ref_count;
};
typedef struct
{
guint changed : 1;
guint value : 1;
} MetaWaylandStateFlag;
typedef struct
{
/* wl_surface.attach */
@@ -67,9 +61,6 @@ typedef struct
gboolean frame_extents_changed;
GtkBorder frame_extents;
MetaWaylandStateFlag fullscreen;
MetaWaylandStateFlag maximized;
} MetaWaylandDoubleBufferedState;
typedef struct
@@ -107,6 +98,8 @@ struct _MetaWaylandSurface
GSList *pending_placement_ops;
} sub;
uint32_t state_changed_serial;
/* All the pending state, that wl_surface.commit will apply. */
MetaWaylandDoubleBufferedState pending;
};
@@ -124,6 +117,10 @@ void meta_wayland_surface_window_unmanaged (MetaWaylandSurface *s
void meta_wayland_surface_configure_notify (MetaWaylandSurface *surface,
int width,
int height);
void meta_wayland_surface_send_maximized (MetaWaylandSurface *surface);
void meta_wayland_surface_send_unmaximized (MetaWaylandSurface *surface);
void meta_wayland_surface_send_fullscreened (MetaWaylandSurface *surface);
void meta_wayland_surface_send_unfullscreened (MetaWaylandSurface *surface);
void meta_wayland_surface_activated (MetaWaylandSurface *surface);
void meta_wayland_surface_deactivated (MetaWaylandSurface *surface);

View File

@@ -643,6 +643,8 @@ meta_wayland_init (void)
clutter_wayland_set_compositor_display (compositor->wayland_display);
/* If we're running on bare metal, we're a display server,
* so start talking to weston-launch. */
#if defined(CLUTTER_WINDOWING_EGL)
if (clutter_check_windowing_backend (CLUTTER_WINDOWING_EGL))
compositor->launcher = meta_launcher_new ();
@@ -728,7 +730,22 @@ meta_wayland_compositor_activate_vt (MetaWaylandCompositor *compositor,
}
else
{
g_debug ("Ignoring VT switch keybinding, not running as VT manager");
g_debug ("Ignoring VT switch keybinding, not running as display server");
return TRUE;
}
}
gboolean
meta_wayland_compositor_activate_session (MetaWaylandCompositor *compositor,
GError **error)
{
if (compositor->launcher)
{
return meta_launcher_activate_vt (compositor->launcher, -1, error);
}
else
{
g_debug ("Ignoring activate_session, not running as display server");
return TRUE;
}
}

View File

@@ -46,6 +46,8 @@ void meta_wayland_compositor_paint_finished (MetaWaylandComp
gboolean meta_wayland_compositor_activate_vt (MetaWaylandCompositor *compositor,
int vt,
GError **error);
gboolean meta_wayland_compositor_activate_session (MetaWaylandCompositor *compositor,
GError **error);
#endif

View File

@@ -41,6 +41,8 @@
#include <xf86drm.h>
#include <xf86drmMode.h>
#include "meta-wayland-private.h"
#include "meta-cursor-tracker-private.h"
#include "meta-weston-launch.h"
struct _MetaLauncher
@@ -179,11 +181,11 @@ meta_launcher_set_drm_fd (MetaLauncher *self,
return ok;
}
int
static int
meta_launcher_open_input_device (MetaLauncher *self,
const char *name,
int flags,
GError **error)
const char *name,
int flags,
GError **error)
{
struct weston_launcher_open *message;
GSocketControlMessage *cmsg;
@@ -232,6 +234,17 @@ meta_launcher_enter (MetaLauncher *launcher)
cogl_kms_display_queue_modes_reset (cogl_display);
clutter_evdev_reclaim_devices ();
{
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
/* When we mode-switch back, we need to immediately queue a redraw
* in case nothing else queued one for us, and force the cursor to
* update. */
clutter_actor_queue_redraw (compositor->stage);
meta_cursor_tracker_force_update (compositor->seat->cursor_tracker);
}
}
static void
@@ -251,6 +264,13 @@ on_evdev_device_open (const char *path,
return meta_launcher_open_input_device (launcher, path, flags, error);
}
static void
on_evdev_device_close (int fd,
gpointer user_data)
{
close (fd);
}
static void
handle_vt_enter (MetaLauncher *launcher)
{
@@ -354,8 +374,6 @@ meta_launcher_new (void)
self->weston_launch = g_socket_new_from_fd (launch_fd, NULL);
clutter_evdev_set_open_callback (on_evdev_device_open, self);
self->nested_context = g_main_context_new ();
self->nested_loop = g_main_loop_new (self->nested_context, FALSE);
@@ -369,6 +387,10 @@ meta_launcher_new (void)
g_source_attach (self->inner_source, self->nested_context);
g_source_unref (self->inner_source);
clutter_evdev_set_device_callbacks (on_evdev_device_open,
on_evdev_device_close,
self);
return self;
}
@@ -388,7 +410,7 @@ meta_launcher_free (MetaLauncher *launcher)
gboolean
meta_launcher_activate_vt (MetaLauncher *launcher,
int vt,
signed char vt,
GError **error)
{
struct weston_launcher_activate_vt message;

View File

@@ -29,18 +29,10 @@ MetaLauncher *meta_launcher_new (void);
void meta_launcher_free (MetaLauncher *self);
gboolean meta_launcher_activate_vt (MetaLauncher *self,
int number,
signed char vt,
GError **error);
gboolean meta_launcher_set_drm_fd (MetaLauncher *self,
int drm_fd,
GError **error);
gboolean meta_launcher_set_master (MetaLauncher *self,
gboolean master,
GError **error);
int meta_launcher_open_input_device (MetaLauncher *self,
const char *name,
int flags,
GError **error);
#endif

View File

@@ -47,6 +47,13 @@ xserver_set_window_id (struct wl_client *client,
if (!window)
return;
/* If the window has an existing surface, like if we're
* undecorating or decorating the window, then we need
* to detach the window from its old surface.
*/
if (window->surface)
window->surface->window = NULL;
meta_wayland_surface_make_toplevel (surface);
surface->window = window;

View File

@@ -80,6 +80,7 @@ struct weston_launch {
struct termios terminal_attributes;
int kb_mode;
enum vt_state vt_state;
unsigned vt;
int drm_fd;
};
@@ -274,6 +275,7 @@ 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;
@@ -285,7 +287,13 @@ handle_activate_vt(struct weston_launch *wl, struct msghdr *msg, ssize_t len)
message = msg->msg_iov->iov_base;
reply.ret = ioctl(wl->tty, VT_ACTIVATE, message->vt);
/* 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;
@@ -331,6 +339,13 @@ handle_open(struct weston_launch *wl, struct msghdr *msg, ssize_t len)
goto err0;
}
if (major(s.st_rdev) != INPUT_MAJOR) {
fprintf(stderr, "Device %s is not an input device\n",
message->path);
reply.ret = -EPERM;
goto err0;
}
fd = open(message->path, message->flags);
if (fd < 0) {
fprintf(stderr, "Error opening device %s: %m\n",
@@ -339,15 +354,6 @@ handle_open(struct weston_launch *wl, struct msghdr *msg, ssize_t len)
goto err0;
}
if (major(s.st_rdev) != INPUT_MAJOR) {
close(fd);
fd = -1;
fprintf(stderr, "Device %s is not an input device\n",
message->path);
reply.ret = -EPERM;
goto err0;
}
err0:
memset(&nmsg, 0, sizeof nmsg);
nmsg.msg_iov = &iov;
@@ -554,7 +560,7 @@ setup_tty(struct weston_launch *wl)
struct stat buf;
struct termios raw_attributes;
struct vt_mode mode = { 0 };
char *session, *tty;
char *session;
char path[PATH_MAX];
int ok;
@@ -562,44 +568,13 @@ setup_tty(struct weston_launch *wl)
if (ok < 0)
error(1, -ok, "could not determine current session");
ok = sd_session_get_tty(session, &tty);
if (ok == 0) {
/* Old systemd only has the tty name in the TTY
field, new one has the full char device path.
Check what we have and fix it properly.
*/
if (strncmp(tty, "/dev", strlen("/dev")) == 0) {
strncpy(path, tty, PATH_MAX);
path[PATH_MAX-1] = 0;
} else {
snprintf(path, PATH_MAX, "/dev/%s", tty);
}
wl->tty = open(path, O_RDWR | O_NOCTTY | O_CLOEXEC);
free(tty);
#ifdef HAVE_SD_SESSION_GET_VT
} else if (ok == -ENOENT) {
unsigned vt;
/* Negative errnos are cool, right?
So cool that we can't distinguish "session not found"
from "key does not exist in the session file"!
Let's assume the latter, as we got the value
from sd_pid_get_session()...
*/
ok = sd_session_get_vt(session, &vt);
if (ok < 0)
error(1, -ok, "could not determine current TTY");
snprintf(path, PATH_MAX, "/dev/tty%u", vt);
wl->tty = open(path, O_RDWR | O_NOCTTY | O_CLOEXEC);
free(tty);
#endif
} else
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");

View File

@@ -53,7 +53,7 @@ struct weston_launcher_open {
struct weston_launcher_activate_vt {
struct weston_launcher_message header;
int vt;
signed char vt;
};
struct weston_launcher_reply {