Compare commits
13 Commits
wip/nielsd
...
wip/carlos
Author | SHA1 | Date | |
---|---|---|---|
![]() |
aea56b6f55 | ||
![]() |
217bd31531 | ||
![]() |
3de6f7ebfe | ||
![]() |
38ff01d6d0 | ||
![]() |
40103d6f41 | ||
![]() |
ab7ef5f8bf | ||
![]() |
2c1a951b6e | ||
![]() |
6ec330ccfa | ||
![]() |
20c1295a33 | ||
![]() |
fa4a787386 | ||
![]() |
85b734fde8 | ||
![]() |
28419cdedf | ||
![]() |
3b46a8cd70 |
@@ -550,13 +550,7 @@ static gboolean
|
|||||||
are_kbd_a11y_settings_equal (ClutterKbdA11ySettings *a,
|
are_kbd_a11y_settings_equal (ClutterKbdA11ySettings *a,
|
||||||
ClutterKbdA11ySettings *b)
|
ClutterKbdA11ySettings *b)
|
||||||
{
|
{
|
||||||
return (a->controls == b->controls &&
|
return (memcmp (a, b, sizeof (ClutterKbdA11ySettings)) == 0);
|
||||||
a->slowkeys_delay == b->slowkeys_delay &&
|
|
||||||
a->debounce_delay == b->debounce_delay &&
|
|
||||||
a->timeout_delay == b->timeout_delay &&
|
|
||||||
a->mousekeys_init_delay == b->mousekeys_init_delay &&
|
|
||||||
a->mousekeys_max_speed == b->mousekeys_max_speed &&
|
|
||||||
a->mousekeys_accel_time == b->mousekeys_accel_time);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@@ -1132,13 +1132,13 @@ clutter_input_device_evdev_process_kbd_a11y_event (ClutterEvent *e
|
|||||||
if (event->key.flags & CLUTTER_EVENT_FLAG_INPUT_METHOD)
|
if (event->key.flags & CLUTTER_EVENT_FLAG_INPUT_METHOD)
|
||||||
goto emit_event;
|
goto emit_event;
|
||||||
|
|
||||||
if (!(device_evdev->a11y_flags & CLUTTER_A11Y_KEYBOARD_ENABLED))
|
if (device_evdev->a11y_flags & CLUTTER_A11Y_KEYBOARD_ENABLED)
|
||||||
goto emit_event;
|
{
|
||||||
|
if (event->type == CLUTTER_KEY_PRESS)
|
||||||
if (event->type == CLUTTER_KEY_PRESS)
|
handle_enablekeys_press (event, device_evdev);
|
||||||
handle_enablekeys_press (event, device_evdev);
|
else
|
||||||
else
|
handle_enablekeys_release (event, device_evdev);
|
||||||
handle_enablekeys_release (event, device_evdev);
|
}
|
||||||
|
|
||||||
if (device_evdev->a11y_flags & CLUTTER_A11Y_MOUSE_KEYS_ENABLED)
|
if (device_evdev->a11y_flags & CLUTTER_A11Y_MOUSE_KEYS_ENABLED)
|
||||||
{
|
{
|
||||||
|
@@ -99,9 +99,9 @@ typedef struct _CoglOnscreenGLX
|
|||||||
CoglOnscreenXlib _parent;
|
CoglOnscreenXlib _parent;
|
||||||
GLXDrawable glxwin;
|
GLXDrawable glxwin;
|
||||||
uint32_t last_swap_vsync_counter;
|
uint32_t last_swap_vsync_counter;
|
||||||
gboolean pending_sync_notify;
|
uint32_t pending_sync_notify;
|
||||||
gboolean pending_complete_notify;
|
uint32_t pending_complete_notify;
|
||||||
gboolean pending_resize_notify;
|
uint32_t pending_resize_notify;
|
||||||
|
|
||||||
GThread *swap_wait_thread;
|
GThread *swap_wait_thread;
|
||||||
GQueue *swap_wait_queue;
|
GQueue *swap_wait_queue;
|
||||||
@@ -347,35 +347,35 @@ flush_pending_notifications_cb (void *data,
|
|||||||
{
|
{
|
||||||
CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
|
CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
|
||||||
CoglOnscreenGLX *glx_onscreen = onscreen->winsys;
|
CoglOnscreenGLX *glx_onscreen = onscreen->winsys;
|
||||||
gboolean pending_sync_notify = glx_onscreen->pending_sync_notify;
|
|
||||||
gboolean pending_complete_notify = glx_onscreen->pending_complete_notify;
|
|
||||||
|
|
||||||
/* If swap_region is called then notifying the sync event could
|
while (glx_onscreen->pending_sync_notify > 0 ||
|
||||||
* potentially immediately queue a subsequent pending notify so
|
glx_onscreen->pending_complete_notify > 0 ||
|
||||||
* we need to clear the flag before invoking the callback */
|
glx_onscreen->pending_resize_notify > 0)
|
||||||
glx_onscreen->pending_sync_notify = FALSE;
|
|
||||||
glx_onscreen->pending_complete_notify = FALSE;
|
|
||||||
|
|
||||||
if (pending_sync_notify)
|
|
||||||
{
|
{
|
||||||
CoglFrameInfo *info = g_queue_peek_head (&onscreen->pending_frame_infos);
|
if (glx_onscreen->pending_sync_notify > 0)
|
||||||
|
{
|
||||||
|
CoglFrameInfo *info =
|
||||||
|
g_queue_peek_head (&onscreen->pending_frame_infos);
|
||||||
|
|
||||||
_cogl_onscreen_notify_frame_sync (onscreen, info);
|
_cogl_onscreen_notify_frame_sync (onscreen, info);
|
||||||
}
|
glx_onscreen->pending_sync_notify--;
|
||||||
|
}
|
||||||
|
|
||||||
if (pending_complete_notify)
|
if (glx_onscreen->pending_complete_notify > 0)
|
||||||
{
|
{
|
||||||
CoglFrameInfo *info = g_queue_pop_head (&onscreen->pending_frame_infos);
|
CoglFrameInfo *info =
|
||||||
|
g_queue_pop_head (&onscreen->pending_frame_infos);
|
||||||
|
|
||||||
_cogl_onscreen_notify_complete (onscreen, info);
|
_cogl_onscreen_notify_complete (onscreen, info);
|
||||||
|
cogl_object_unref (info);
|
||||||
|
glx_onscreen->pending_complete_notify--;
|
||||||
|
}
|
||||||
|
|
||||||
cogl_object_unref (info);
|
if (glx_onscreen->pending_resize_notify > 0)
|
||||||
}
|
{
|
||||||
|
_cogl_onscreen_notify_resize (onscreen);
|
||||||
if (glx_onscreen->pending_resize_notify)
|
glx_onscreen->pending_resize_notify--;
|
||||||
{
|
}
|
||||||
_cogl_onscreen_notify_resize (onscreen);
|
|
||||||
glx_onscreen->pending_resize_notify = FALSE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -417,7 +417,7 @@ set_sync_pending (CoglOnscreen *onscreen)
|
|||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
glx_onscreen->pending_sync_notify = TRUE;
|
glx_onscreen->pending_sync_notify++;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -440,7 +440,7 @@ set_complete_pending (CoglOnscreen *onscreen)
|
|||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
glx_onscreen->pending_complete_notify = TRUE;
|
glx_onscreen->pending_complete_notify++;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -533,7 +533,7 @@ notify_resize (CoglContext *context,
|
|||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
glx_onscreen->pending_resize_notify = TRUE;
|
glx_onscreen->pending_resize_notify++;
|
||||||
|
|
||||||
if (!xlib_onscreen->is_foreign_xwin)
|
if (!xlib_onscreen->is_foreign_xwin)
|
||||||
{
|
{
|
||||||
|
@@ -46,9 +46,6 @@
|
|||||||
/* Building with SM support */
|
/* Building with SM support */
|
||||||
#mesondefine HAVE_SM
|
#mesondefine HAVE_SM
|
||||||
|
|
||||||
/* Building with startup notification support */
|
|
||||||
#mesondefine HAVE_STARTUP_NOTIFICATION
|
|
||||||
|
|
||||||
/* Path to Xwayland executable */
|
/* Path to Xwayland executable */
|
||||||
#mesondefine XWAYLAND_PATH
|
#mesondefine XWAYLAND_PATH
|
||||||
|
|
||||||
|
100
doc/meson.build
100
doc/meson.build
@@ -1,100 +0,0 @@
|
|||||||
# manpage
|
|
||||||
subdir('man')
|
|
||||||
|
|
||||||
# Reference manual
|
|
||||||
subdir('xml')
|
|
||||||
|
|
||||||
version_conf = configuration_data()
|
|
||||||
version_conf.set('VERSION', meson.project_version())
|
|
||||||
version_xml = configure_file(
|
|
||||||
input: 'version.xml.in',
|
|
||||||
output: 'version.xml',
|
|
||||||
configuration: version_conf
|
|
||||||
)
|
|
||||||
|
|
||||||
reference_ignored_headers = [
|
|
||||||
'config.h',
|
|
||||||
|
|
||||||
'bell.h',
|
|
||||||
'boxes-private.h',
|
|
||||||
'compositor-private.h',
|
|
||||||
'core.h',
|
|
||||||
'constraints.h',
|
|
||||||
'display-private.h',
|
|
||||||
'frame.h',
|
|
||||||
'frames.h',
|
|
||||||
'group-private.h',
|
|
||||||
'keybindings-private.h',
|
|
||||||
'main.h',
|
|
||||||
'meta-backend-private.h',
|
|
||||||
'meta-background-private.h',
|
|
||||||
'meta-barrier-private.h',
|
|
||||||
'meta-dnd-actor-private.h',
|
|
||||||
'meta-dnd-private.h',
|
|
||||||
'meta-feedback-actor-private.h',
|
|
||||||
'meta-gesture-tracker-private.h',
|
|
||||||
'meta-idle-monitor-private.h',
|
|
||||||
'meta-input-mapper-private.h',
|
|
||||||
'meta-input-settings-private.h',
|
|
||||||
'meta-monitor-manager-private.h',
|
|
||||||
'meta-remote-access-controller-private.h',
|
|
||||||
'meta-settings-private.h',
|
|
||||||
'meta-shaped-texture-private.h',
|
|
||||||
'meta-stage-private.h',
|
|
||||||
'meta-wayland-private.h',
|
|
||||||
'meta-window-actor-private.h',
|
|
||||||
'meta-window-group-private.h',
|
|
||||||
'meta-xwayland-private.h',
|
|
||||||
'meta-xwayland-selection-private.h',
|
|
||||||
'theme-private.h',
|
|
||||||
'util-private.h',
|
|
||||||
'window-private.h',
|
|
||||||
'window-x11-private.h',
|
|
||||||
'workspace-private.h',
|
|
||||||
# Test headers
|
|
||||||
'meta-backend-test.h',
|
|
||||||
'meta-monitor-manager-test.h',
|
|
||||||
'meta-wayland-egl-stream.h',
|
|
||||||
'meta-wayland-inhibit-shortcuts.h',
|
|
||||||
'meta-wayland-text-input.h',
|
|
||||||
'meta-xwayland-grab-keyboard.h',
|
|
||||||
]
|
|
||||||
|
|
||||||
# Make sure we ignore the wayland headers
|
|
||||||
if have_wayland
|
|
||||||
foreach proto : wayland_protocols
|
|
||||||
protocol_name = proto[0]
|
|
||||||
protocol_type = proto[1]
|
|
||||||
if protocol_type == 'stable'
|
|
||||||
output_base = protocol_name
|
|
||||||
elif protocol_type == 'private'
|
|
||||||
output_base = protocol_name
|
|
||||||
elif protocol_type == 'third-party'
|
|
||||||
output_base = protocol_name
|
|
||||||
else
|
|
||||||
protocol_version = proto[2]
|
|
||||||
output_base = '@0@-@1@-@2@'.format(protocol_name,
|
|
||||||
protocol_type,
|
|
||||||
protocol_version)
|
|
||||||
endif
|
|
||||||
|
|
||||||
proto_header = '@0@-server-protocol.h'.format(output_base)
|
|
||||||
reference_ignored_headers += proto_header
|
|
||||||
endforeach
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
|
||||||
gnome.gtkdoc(meson.project_name(),
|
|
||||||
main_sgml: 'mutter-docs.sgml',
|
|
||||||
src_dir: [
|
|
||||||
include_directories('../src'),
|
|
||||||
],
|
|
||||||
dependencies: _libmutter_public_symbols_dep,
|
|
||||||
gobject_typesfile: 'mutter.types',
|
|
||||||
scan_args: [
|
|
||||||
'--rebuild-types',
|
|
||||||
'--ignore-headers=' + ' '.join(reference_ignored_headers),
|
|
||||||
'--ignore-decorators=META_EXPORT|META_EXPORT_TEST',
|
|
||||||
],
|
|
||||||
install: true,
|
|
||||||
)
|
|
@@ -1,110 +0,0 @@
|
|||||||
<?xml version="1.0"?>
|
|
||||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
|
|
||||||
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
|
|
||||||
[
|
|
||||||
<!ENTITY % local.common.attrib "xmlns:xi CDATA #FIXED 'http://www.w3.org/2003/XInclude'">
|
|
||||||
<!ENTITY % gtkdocentities SYSTEM "xml/gtkdocentities.ent">
|
|
||||||
%gtkdocentities;
|
|
||||||
]>
|
|
||||||
<book id="index">
|
|
||||||
<bookinfo>
|
|
||||||
<title>Mutter Reference Manual</title>
|
|
||||||
<releaseinfo>
|
|
||||||
For &package_string;.
|
|
||||||
The latest version of this documentation can be found on-line at
|
|
||||||
<ulink role="online-location" url="http://[SERVER]/&package_name;/index.html">http://[SERVER]/&package_name;/</ulink>.
|
|
||||||
</releaseinfo>
|
|
||||||
</bookinfo>
|
|
||||||
|
|
||||||
<chapter>
|
|
||||||
<title>General</title>
|
|
||||||
<xi:include href="xml/meta-backend.xml"/>
|
|
||||||
<xi:include href="xml/meta-clutter-backend-native.xml"/>
|
|
||||||
<xi:include href="xml/meta-renderer.xml"/>
|
|
||||||
<xi:include href="xml/meta-stage.xml"/>
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
<chapter>
|
|
||||||
<title>Clutter actors</title>
|
|
||||||
<xi:include href="xml/meta-window-actor.xml"/>
|
|
||||||
<xi:include href="xml/meta-window-group.xml"/>
|
|
||||||
<xi:include href="xml/meta-background-actor.xml"/>
|
|
||||||
<xi:include href="xml/meta-background-group.xml"/>
|
|
||||||
<xi:include href="xml/meta-surface-actor.xml"/>
|
|
||||||
<xi:include href="xml/meta-shaped-texture.xml"/>
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
<chapter>
|
|
||||||
<title>Plugins</title>
|
|
||||||
<xi:include href="xml/meta-plugin.xml"/>
|
|
||||||
<xi:include href="xml/meta-plugin-manager.xml"/>
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
<chapter>
|
|
||||||
<title>Cursor management</title>
|
|
||||||
<xi:include href="xml/meta-cursor-tracker.xml"/>
|
|
||||||
<xi:include href="xml/meta-cursor.xml"/>
|
|
||||||
<xi:include href="xml/meta-cursor-renderer.xml"/>
|
|
||||||
<xi:include href="xml/meta-pointer-constraint.xml"/>
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
<chapter>
|
|
||||||
<title>Monitor management</title>
|
|
||||||
<xi:include href="xml/meta-monitor-manager.xml"/>
|
|
||||||
<xi:include href="xml/meta-monitor-manager-dummy.xml"/>
|
|
||||||
<xi:include href="xml/meta-monitor-config-manager.xml"/>
|
|
||||||
<xi:include href="xml/meta-logical-monitor.xml"/>
|
|
||||||
<xi:include href="xml/meta-monitor.xml"/>
|
|
||||||
<xi:include href="xml/meta-monitor-transform.xml"/>
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
<chapter>
|
|
||||||
<title>X11</title>
|
|
||||||
<xi:include href="xml/meta-backend-x11.xml"/>
|
|
||||||
<xi:include href="xml/meta-monitor-manager-xrandr.xml"/>
|
|
||||||
<xi:include href="xml/meta-window-actor-x11.xml"/>
|
|
||||||
<xi:include href="xml/meta-surface-actor-x11.xml"/>
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
<chapter>
|
|
||||||
<title>Native / Wayland</title>
|
|
||||||
<xi:include href="xml/meta-backend-native.xml"/>
|
|
||||||
<xi:include href="xml/meta-monitor-manager-kms.xml"/>
|
|
||||||
<xi:include href="xml/meta-renderer-native.xml"/>
|
|
||||||
<xi:include href="xml/meta-window-actor-wayland.xml"/>
|
|
||||||
<xi:include href="xml/meta-surface-actor-wayland.xml"/>
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
<chapter>
|
|
||||||
<title>Screencast</title>
|
|
||||||
<xi:include href="xml/meta-screen-cast.xml"/>
|
|
||||||
<xi:include href="xml/meta-screen-cast-session.xml"/>
|
|
||||||
<xi:include href="xml/meta-screen-cast-window.xml"/>
|
|
||||||
<xi:include href="xml/meta-screen-cast-stream.xml"/>
|
|
||||||
<xi:include href="xml/meta-screen-cast-window-stream.xml"/>
|
|
||||||
<xi:include href="xml/meta-screen-cast-monitor-stream.xml"/>
|
|
||||||
<xi:include href="xml/meta-screen-cast-stream-src.xml"/>
|
|
||||||
<xi:include href="xml/meta-screen-cast-window-stream-src.xml"/>
|
|
||||||
<xi:include href="xml/meta-screen-cast-monitor-stream-src.xml"/>
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
<chapter>
|
|
||||||
<title>Remote desktop</title>
|
|
||||||
<xi:include href="xml/meta-remote-desktop.xml"/>
|
|
||||||
<xi:include href="xml/meta-dbus-remote-desktop.xml"/>
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
<chapter id="object-tree">
|
|
||||||
<title>Object Hierarchy</title>
|
|
||||||
<xi:include href="xml/tree_index.sgml"/>
|
|
||||||
</chapter>
|
|
||||||
<index id="api-index-full">
|
|
||||||
<title>API Index</title>
|
|
||||||
<xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include>
|
|
||||||
</index>
|
|
||||||
<index id="deprecated-api-index" role="deprecated">
|
|
||||||
<title>Index of deprecated API</title>
|
|
||||||
<xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include>
|
|
||||||
</index>
|
|
||||||
<xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
|
|
||||||
</book>
|
|
@@ -1 +0,0 @@
|
|||||||
@VERSION@
|
|
@@ -1,7 +0,0 @@
|
|||||||
<!ENTITY package @PACKAGE@>
|
|
||||||
<!ENTITY package_bugreport @PACKAGE_BUGREPORT@>
|
|
||||||
<!ENTITY package_name @PACKAGE_NAME@>
|
|
||||||
<!ENTITY package_string @PACKAGE_STRING@>
|
|
||||||
<!ENTITY package_tarname @PACKAGE_TARNAME@>
|
|
||||||
<!ENTITY package_url @PACKAGE_URL@>
|
|
||||||
<!ENTITY package_version @PACKAGE_VERSION@>
|
|
@@ -1,13 +0,0 @@
|
|||||||
gtkdoc_entities_cdata = configuration_data()
|
|
||||||
gtkdoc_entities_cdata.set_quoted('PACKAGE', meson.project_name())
|
|
||||||
gtkdoc_entities_cdata.set_quoted('PACKAGE_BUGREPORT', 'https://gitlab.gnome.org/GNOME/mutter/issues/new')
|
|
||||||
gtkdoc_entities_cdata.set_quoted('PACKAGE_NAME', meson.project_name())
|
|
||||||
gtkdoc_entities_cdata.set_quoted('PACKAGE_STRING', '@0@ - @1@'.format(meson.project_name(), meson.project_version()))
|
|
||||||
gtkdoc_entities_cdata.set_quoted('PACKAGE_TARNAME', 'mutter.tar.xz')
|
|
||||||
gtkdoc_entities_cdata.set_quoted('PACKAGE_URL', 'https://gitlab.gnome.org/GNOME/mutter/')
|
|
||||||
gtkdoc_entities_cdata.set_quoted('PACKAGE_VERSION', meson.project_version())
|
|
||||||
configure_file(
|
|
||||||
input: 'gtkdocentities.ent.in',
|
|
||||||
output: 'gtkdocentities.ent',
|
|
||||||
configuration: gtkdoc_entities_cdata,
|
|
||||||
)
|
|
10
meson.build
10
meson.build
@@ -225,12 +225,6 @@ if have_pango_ft2
|
|||||||
pangoft2_dep = dependency('pangoft2')
|
pangoft2_dep = dependency('pangoft2')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
have_startup_notification = get_option('startup_notification')
|
|
||||||
if have_startup_notification
|
|
||||||
libstartup_notification_dep = dependency('libstartup-notification-1.0',
|
|
||||||
version: libstartup_notification_req)
|
|
||||||
endif
|
|
||||||
|
|
||||||
have_remote_desktop = get_option('remote_desktop')
|
have_remote_desktop = get_option('remote_desktop')
|
||||||
if have_remote_desktop
|
if have_remote_desktop
|
||||||
libpipewire_dep = dependency('libpipewire-0.2', version: libpipewire_req)
|
libpipewire_dep = dependency('libpipewire-0.2', version: libpipewire_req)
|
||||||
@@ -334,7 +328,6 @@ cdata.set('HAVE_WAYLAND_EGLSTREAM', have_wayland_eglstream)
|
|||||||
cdata.set('HAVE_LIBGUDEV', have_libgudev)
|
cdata.set('HAVE_LIBGUDEV', have_libgudev)
|
||||||
cdata.set('HAVE_LIBWACOM', have_libwacom)
|
cdata.set('HAVE_LIBWACOM', have_libwacom)
|
||||||
cdata.set('HAVE_SM', have_sm)
|
cdata.set('HAVE_SM', have_sm)
|
||||||
cdata.set('HAVE_STARTUP_NOTIFICATION', have_startup_notification)
|
|
||||||
cdata.set('HAVE_INTROSPECTION', have_introspection)
|
cdata.set('HAVE_INTROSPECTION', have_introspection)
|
||||||
|
|
||||||
xkb_base = xkeyboard_config_dep.get_pkgconfig_variable('xkb_base')
|
xkb_base = xkeyboard_config_dep.get_pkgconfig_variable('xkb_base')
|
||||||
@@ -370,7 +363,7 @@ subdir('clutter')
|
|||||||
subdir('data')
|
subdir('data')
|
||||||
subdir('src')
|
subdir('src')
|
||||||
subdir('po')
|
subdir('po')
|
||||||
subdir('doc')
|
subdir('doc/man')
|
||||||
|
|
||||||
output = [
|
output = [
|
||||||
'',
|
'',
|
||||||
@@ -399,7 +392,6 @@ output = [
|
|||||||
' gudev.................... ' + have_libgudev.to_string(),
|
' gudev.................... ' + have_libgudev.to_string(),
|
||||||
' Wacom.................... ' + have_libwacom.to_string(),
|
' Wacom.................... ' + have_libwacom.to_string(),
|
||||||
' SM....................... ' + have_sm.to_string(),
|
' SM....................... ' + have_sm.to_string(),
|
||||||
' Startup notification..... ' + have_startup_notification.to_string(),
|
|
||||||
' Introspection............ ' + have_introspection.to_string(),
|
' Introspection............ ' + have_introspection.to_string(),
|
||||||
'',
|
'',
|
||||||
' Tests:',
|
' Tests:',
|
||||||
|
@@ -20,7 +20,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SECTION:meta-cursor-tracker
|
* SECTION:cursor-tracker
|
||||||
* @title: MetaCursorTracker
|
* @title: MetaCursorTracker
|
||||||
* @short_description: Mutter cursor tracking helper. Originally only
|
* @short_description: Mutter cursor tracking helper. Originally only
|
||||||
* tracking the cursor image, now more of a "core
|
* tracking the cursor image, now more of a "core
|
||||||
|
@@ -3787,16 +3787,13 @@ gpu_kms_is_hardware_rendering (MetaRendererNative *renderer_native,
|
|||||||
return data->secondary.is_hardware_rendering;
|
return data->secondary.is_hardware_rendering;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MetaRendererNativeGpuData *
|
static EGLDisplay
|
||||||
create_renderer_gpu_data_gbm (MetaRendererNative *renderer_native,
|
init_gbm_egl_display (MetaRendererNative *renderer_native,
|
||||||
MetaGpuKms *gpu_kms,
|
struct gbm_device *gbm_device,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
MetaEgl *egl = meta_renderer_native_get_egl (renderer_native);
|
MetaEgl *egl = meta_renderer_native_get_egl (renderer_native);
|
||||||
struct gbm_device *gbm_device;
|
|
||||||
EGLDisplay egl_display;
|
EGLDisplay egl_display;
|
||||||
int kms_fd;
|
|
||||||
MetaRendererNativeGpuData *renderer_gpu_data;
|
|
||||||
|
|
||||||
if (!meta_egl_has_extensions (egl, EGL_NO_DISPLAY, NULL,
|
if (!meta_egl_has_extensions (egl, EGL_NO_DISPLAY, NULL,
|
||||||
"EGL_MESA_platform_gbm",
|
"EGL_MESA_platform_gbm",
|
||||||
@@ -3808,9 +3805,31 @@ create_renderer_gpu_data_gbm (MetaRendererNative *renderer_native,
|
|||||||
g_set_error (error, G_IO_ERROR,
|
g_set_error (error, G_IO_ERROR,
|
||||||
G_IO_ERROR_FAILED,
|
G_IO_ERROR_FAILED,
|
||||||
"Missing extension for GBM renderer: EGL_KHR_platform_gbm");
|
"Missing extension for GBM renderer: EGL_KHR_platform_gbm");
|
||||||
return NULL;
|
return EGL_NO_DISPLAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
egl_display = meta_egl_get_platform_display (egl,
|
||||||
|
EGL_PLATFORM_GBM_KHR,
|
||||||
|
gbm_device, NULL, error);
|
||||||
|
if (egl_display == EGL_NO_DISPLAY)
|
||||||
|
return EGL_NO_DISPLAY;
|
||||||
|
|
||||||
|
if (!meta_egl_initialize (egl, egl_display, error))
|
||||||
|
return EGL_NO_DISPLAY;
|
||||||
|
|
||||||
|
return egl_display;
|
||||||
|
}
|
||||||
|
|
||||||
|
static MetaRendererNativeGpuData *
|
||||||
|
create_renderer_gpu_data_gbm (MetaRendererNative *renderer_native,
|
||||||
|
MetaGpuKms *gpu_kms,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
struct gbm_device *gbm_device;
|
||||||
|
int kms_fd;
|
||||||
|
MetaRendererNativeGpuData *renderer_gpu_data;
|
||||||
|
g_autoptr (GError) local_error = NULL;
|
||||||
|
|
||||||
kms_fd = meta_gpu_kms_get_fd (gpu_kms);
|
kms_fd = meta_gpu_kms_get_fd (gpu_kms);
|
||||||
|
|
||||||
gbm_device = gbm_create_device (kms_fd);
|
gbm_device = gbm_create_device (kms_fd);
|
||||||
@@ -3822,26 +3841,25 @@ create_renderer_gpu_data_gbm (MetaRendererNative *renderer_native,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
egl_display = meta_egl_get_platform_display (egl,
|
|
||||||
EGL_PLATFORM_GBM_KHR,
|
|
||||||
gbm_device, NULL, error);
|
|
||||||
if (egl_display == EGL_NO_DISPLAY)
|
|
||||||
{
|
|
||||||
gbm_device_destroy (gbm_device);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!meta_egl_initialize (egl, egl_display, error))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
renderer_gpu_data = meta_create_renderer_native_gpu_data (gpu_kms);
|
renderer_gpu_data = meta_create_renderer_native_gpu_data (gpu_kms);
|
||||||
renderer_gpu_data->renderer_native = renderer_native;
|
renderer_gpu_data->renderer_native = renderer_native;
|
||||||
renderer_gpu_data->gbm.device = gbm_device;
|
renderer_gpu_data->gbm.device = gbm_device;
|
||||||
renderer_gpu_data->mode = META_RENDERER_NATIVE_MODE_GBM;
|
renderer_gpu_data->mode = META_RENDERER_NATIVE_MODE_GBM;
|
||||||
renderer_gpu_data->egl_display = egl_display;
|
|
||||||
|
renderer_gpu_data->egl_display = init_gbm_egl_display (renderer_native,
|
||||||
|
gbm_device,
|
||||||
|
&local_error);
|
||||||
|
if (renderer_gpu_data->egl_display == EGL_NO_DISPLAY)
|
||||||
|
{
|
||||||
|
g_debug ("GBM EGL init for %s failed: %s",
|
||||||
|
meta_gpu_kms_get_file_path (gpu_kms),
|
||||||
|
local_error->message);
|
||||||
|
|
||||||
|
init_secondary_gpu_data_cpu (renderer_gpu_data);
|
||||||
|
return renderer_gpu_data;
|
||||||
|
}
|
||||||
|
|
||||||
init_secondary_gpu_data (renderer_gpu_data);
|
init_secondary_gpu_data (renderer_gpu_data);
|
||||||
|
|
||||||
return renderer_gpu_data;
|
return renderer_gpu_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4134,8 +4152,8 @@ on_gpu_added (MetaMonitorManager *monitor_manager,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static MetaGpuKms *
|
static MetaGpuKms *
|
||||||
choose_primary_gpu (MetaMonitorManager *manager,
|
choose_primary_gpu_unchecked (MetaMonitorManager *manager,
|
||||||
MetaRendererNative *renderer_native)
|
MetaRendererNative *renderer_native)
|
||||||
{
|
{
|
||||||
GList *gpus = meta_monitor_manager_get_gpus (manager);
|
GList *gpus = meta_monitor_manager_get_gpus (manager);
|
||||||
GList *l;
|
GList *l;
|
||||||
@@ -4184,6 +4202,28 @@ choose_primary_gpu (MetaMonitorManager *manager,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static MetaGpuKms *
|
||||||
|
choose_primary_gpu (MetaMonitorManager *manager,
|
||||||
|
MetaRendererNative *renderer_native,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
MetaGpuKms *gpu_kms;
|
||||||
|
MetaRendererNativeGpuData *renderer_gpu_data;
|
||||||
|
|
||||||
|
gpu_kms = choose_primary_gpu_unchecked (manager, renderer_native);
|
||||||
|
renderer_gpu_data = meta_renderer_native_get_gpu_data (renderer_native,
|
||||||
|
gpu_kms);
|
||||||
|
if (renderer_gpu_data->egl_display == EGL_NO_DISPLAY)
|
||||||
|
{
|
||||||
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||||
|
"The GPU %s chosen as primary is not supported by EGL.",
|
||||||
|
meta_gpu_kms_get_file_path (gpu_kms));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return gpu_kms;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
meta_renderer_native_initable_init (GInitable *initable,
|
meta_renderer_native_initable_init (GInitable *initable,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
@@ -4207,7 +4247,10 @@ meta_renderer_native_initable_init (GInitable *initable,
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderer_native->primary_gpu_kms = choose_primary_gpu (monitor_manager,
|
renderer_native->primary_gpu_kms = choose_primary_gpu (monitor_manager,
|
||||||
renderer_native);
|
renderer_native,
|
||||||
|
error);
|
||||||
|
if (!renderer_native->primary_gpu_kms)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@@ -31,10 +31,6 @@
|
|||||||
#include <X11/extensions/sync.h>
|
#include <X11/extensions/sync.h>
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
|
|
||||||
#ifdef HAVE_STARTUP_NOTIFICATION
|
|
||||||
#include <libsn/sn.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "clutter/clutter.h"
|
#include "clutter/clutter.h"
|
||||||
#include "core/keybindings-private.h"
|
#include "core/keybindings-private.h"
|
||||||
#include "core/meta-gesture-tracker-private.h"
|
#include "core/meta-gesture-tracker-private.h"
|
||||||
|
@@ -2214,6 +2214,8 @@ meta_keybindings_process_event (MetaDisplay *display,
|
|||||||
{
|
{
|
||||||
case CLUTTER_BUTTON_PRESS:
|
case CLUTTER_BUTTON_PRESS:
|
||||||
case CLUTTER_BUTTON_RELEASE:
|
case CLUTTER_BUTTON_RELEASE:
|
||||||
|
case CLUTTER_TOUCH_BEGIN:
|
||||||
|
case CLUTTER_TOUCH_END:
|
||||||
keys->overlay_key_only_pressed = FALSE;
|
keys->overlay_key_only_pressed = FALSE;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
@@ -118,11 +118,6 @@ static void prefs_changed_callback (MetaPreference pref,
|
|||||||
static void
|
static void
|
||||||
meta_print_compilation_info (void)
|
meta_print_compilation_info (void)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_STARTUP_NOTIFICATION
|
|
||||||
meta_verbose ("Compiled with startup notification\n");
|
|
||||||
#else
|
|
||||||
meta_verbose ("Compiled without startup notification\n");
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -119,40 +119,37 @@ meta_launch_context_constructed (GObject *object)
|
|||||||
"WAYLAND_DISPLAY", getenv ("WAYLAND_DISPLAY"));
|
"WAYLAND_DISPLAY", getenv ("WAYLAND_DISPLAY"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gchar *
|
||||||
|
create_startup_notification_id (uint32_t timestamp)
|
||||||
|
{
|
||||||
|
gchar *uuid, *id;
|
||||||
|
|
||||||
|
uuid = g_uuid_string_random ();
|
||||||
|
id = g_strdup_printf ("%s_TIME%u", uuid, timestamp);
|
||||||
|
g_free (uuid);
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
static gchar *
|
static gchar *
|
||||||
meta_launch_context_get_startup_notify_id (GAppLaunchContext *launch_context,
|
meta_launch_context_get_startup_notify_id (GAppLaunchContext *launch_context,
|
||||||
GAppInfo *info,
|
GAppInfo *info,
|
||||||
GList *files)
|
GList *files)
|
||||||
{
|
{
|
||||||
MetaLaunchContext *context = META_LAUNCH_CONTEXT (launch_context);
|
MetaLaunchContext *context = META_LAUNCH_CONTEXT (launch_context);
|
||||||
MetaDisplay *display = context->display;
|
|
||||||
int workspace_idx = -1;
|
int workspace_idx = -1;
|
||||||
char *startup_id = NULL;
|
char *startup_id = NULL;
|
||||||
|
|
||||||
if (context->workspace)
|
if (context->workspace)
|
||||||
workspace_idx = meta_workspace_index (context->workspace);
|
workspace_idx = meta_workspace_index (context->workspace);
|
||||||
|
|
||||||
if (display->x11_display)
|
|
||||||
{
|
|
||||||
/* If there is a X11 display, we prefer going entirely through
|
|
||||||
* libsn, as SnMonitor expects to keep a view of the full lifetime
|
|
||||||
* of the startup sequence. We can't avoid it when launching and
|
|
||||||
* expect that a "remove" message from a X11 client will be handled.
|
|
||||||
*/
|
|
||||||
startup_id =
|
|
||||||
meta_x11_startup_notification_launch (display->x11_display,
|
|
||||||
info,
|
|
||||||
context->timestamp,
|
|
||||||
workspace_idx);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!startup_id)
|
if (!startup_id)
|
||||||
{
|
{
|
||||||
const char *application_id = NULL;
|
const char *application_id = NULL;
|
||||||
MetaStartupNotification *sn;
|
MetaStartupNotification *sn;
|
||||||
MetaStartupSequence *seq;
|
MetaStartupSequence *seq;
|
||||||
|
|
||||||
startup_id = g_uuid_string_random ();
|
startup_id = create_startup_notification_id (context->timestamp);
|
||||||
|
|
||||||
/* Fallback through inserting our own startup sequence, this
|
/* Fallback through inserting our own startup sequence, this
|
||||||
* will be enough for wayland clients.
|
* will be enough for wayland clients.
|
||||||
|
@@ -37,7 +37,7 @@
|
|||||||
* OpenOffice or whatever seems to stop launching - people
|
* OpenOffice or whatever seems to stop launching - people
|
||||||
* might decide they need to launch it again.
|
* might decide they need to launch it again.
|
||||||
*/
|
*/
|
||||||
#define STARTUP_TIMEOUT 15000000
|
#define STARTUP_TIMEOUT_MS 15000
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
@@ -59,6 +59,12 @@ enum
|
|||||||
N_SEQ_PROPS
|
N_SEQ_PROPS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
SEQ_COMPLETE,
|
||||||
|
N_SEQ_SIGNALS
|
||||||
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
CHANGED,
|
CHANGED,
|
||||||
@@ -67,6 +73,7 @@ enum
|
|||||||
|
|
||||||
static guint sn_signals[N_SIGNALS];
|
static guint sn_signals[N_SIGNALS];
|
||||||
static GParamSpec *sn_props[N_PROPS];
|
static GParamSpec *sn_props[N_PROPS];
|
||||||
|
static guint seq_signals[N_SEQ_SIGNALS];
|
||||||
static GParamSpec *seq_props[N_SEQ_PROPS];
|
static GParamSpec *seq_props[N_SEQ_PROPS];
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
@@ -106,12 +113,26 @@ G_DEFINE_TYPE_WITH_PRIVATE (MetaStartupSequence,
|
|||||||
|
|
||||||
static void meta_startup_notification_ensure_timeout (MetaStartupNotification *sn);
|
static void meta_startup_notification_ensure_timeout (MetaStartupNotification *sn);
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
meta_startup_notification_has_pending_sequences (MetaStartupNotification *sn)
|
||||||
|
{
|
||||||
|
GSList *l;
|
||||||
|
|
||||||
|
for (l = sn->startup_sequences; l; l = l->next)
|
||||||
|
{
|
||||||
|
if (!meta_startup_sequence_get_completed (l->data))
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_startup_notification_update_feedback (MetaStartupNotification *sn)
|
meta_startup_notification_update_feedback (MetaStartupNotification *sn)
|
||||||
{
|
{
|
||||||
MetaDisplay *display = sn->display;
|
MetaDisplay *display = sn->display;
|
||||||
|
|
||||||
if (sn->startup_sequences != NULL)
|
if (meta_startup_notification_has_pending_sequences (sn))
|
||||||
{
|
{
|
||||||
meta_topic (META_DEBUG_STARTUP,
|
meta_topic (META_DEBUG_STARTUP,
|
||||||
"Setting busy cursor\n");
|
"Setting busy cursor\n");
|
||||||
@@ -239,6 +260,14 @@ meta_startup_sequence_class_init (MetaStartupSequenceClass *klass)
|
|||||||
object_class->set_property = meta_startup_sequence_set_property;
|
object_class->set_property = meta_startup_sequence_set_property;
|
||||||
object_class->get_property = meta_startup_sequence_get_property;
|
object_class->get_property = meta_startup_sequence_get_property;
|
||||||
|
|
||||||
|
seq_signals[SEQ_COMPLETE] =
|
||||||
|
g_signal_new ("complete",
|
||||||
|
META_TYPE_STARTUP_SEQUENCE,
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
G_STRUCT_OFFSET (MetaStartupSequenceClass, complete),
|
||||||
|
NULL, NULL, NULL,
|
||||||
|
G_TYPE_NONE, 0);
|
||||||
|
|
||||||
seq_props[PROP_SEQ_ID] =
|
seq_props[PROP_SEQ_ID] =
|
||||||
g_param_spec_string ("id",
|
g_param_spec_string ("id",
|
||||||
"ID",
|
"ID",
|
||||||
@@ -317,7 +346,6 @@ meta_startup_sequence_get_timestamp (MetaStartupSequence *seq)
|
|||||||
void
|
void
|
||||||
meta_startup_sequence_complete (MetaStartupSequence *seq)
|
meta_startup_sequence_complete (MetaStartupSequence *seq)
|
||||||
{
|
{
|
||||||
MetaStartupSequenceClass *klass;
|
|
||||||
MetaStartupSequencePrivate *priv;
|
MetaStartupSequencePrivate *priv;
|
||||||
|
|
||||||
g_return_if_fail (META_IS_STARTUP_SEQUENCE (seq));
|
g_return_if_fail (META_IS_STARTUP_SEQUENCE (seq));
|
||||||
@@ -327,10 +355,7 @@ meta_startup_sequence_complete (MetaStartupSequence *seq)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
priv->completed = TRUE;
|
priv->completed = TRUE;
|
||||||
klass = META_STARTUP_SEQUENCE_GET_CLASS (seq);
|
g_signal_emit (seq, seq_signals[SEQ_COMPLETE], 0);
|
||||||
|
|
||||||
if (klass->complete)
|
|
||||||
klass->complete (seq);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
@@ -399,12 +424,22 @@ meta_startup_sequence_get_wmclass (MetaStartupSequence *seq)
|
|||||||
return priv->wmclass;
|
return priv->wmclass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_sequence_completed (MetaStartupSequence *seq,
|
||||||
|
MetaStartupNotification *sn)
|
||||||
|
{
|
||||||
|
meta_startup_notification_update_feedback (sn);
|
||||||
|
g_signal_emit (sn, sn_signals[CHANGED], 0, seq);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_startup_notification_add_sequence (MetaStartupNotification *sn,
|
meta_startup_notification_add_sequence (MetaStartupNotification *sn,
|
||||||
MetaStartupSequence *seq)
|
MetaStartupSequence *seq)
|
||||||
{
|
{
|
||||||
sn->startup_sequences = g_slist_prepend (sn->startup_sequences,
|
sn->startup_sequences = g_slist_prepend (sn->startup_sequences,
|
||||||
g_object_ref (seq));
|
g_object_ref (seq));
|
||||||
|
g_signal_connect (seq, "complete",
|
||||||
|
G_CALLBACK (on_sequence_completed), sn);
|
||||||
|
|
||||||
meta_startup_notification_ensure_timeout (sn);
|
meta_startup_notification_ensure_timeout (sn);
|
||||||
meta_startup_notification_update_feedback (sn);
|
meta_startup_notification_update_feedback (sn);
|
||||||
@@ -425,10 +460,10 @@ collect_timed_out_foreach (void *element,
|
|||||||
|
|
||||||
meta_topic (META_DEBUG_STARTUP,
|
meta_topic (META_DEBUG_STARTUP,
|
||||||
"Sequence used %" G_GINT64_FORMAT " ms vs. %d max: %s\n",
|
"Sequence used %" G_GINT64_FORMAT " ms vs. %d max: %s\n",
|
||||||
elapsed, STARTUP_TIMEOUT,
|
elapsed, STARTUP_TIMEOUT_MS,
|
||||||
meta_startup_sequence_get_id (sequence));
|
meta_startup_sequence_get_id (sequence));
|
||||||
|
|
||||||
if (elapsed > STARTUP_TIMEOUT)
|
if (elapsed > STARTUP_TIMEOUT_MS)
|
||||||
ctod->list = g_slist_prepend (ctod->list, sequence);
|
ctod->list = g_slist_prepend (ctod->list, sequence);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -440,7 +475,7 @@ startup_sequence_timeout (void *data)
|
|||||||
GSList *l;
|
GSList *l;
|
||||||
|
|
||||||
ctod.list = NULL;
|
ctod.list = NULL;
|
||||||
ctod.now = g_get_monotonic_time ();
|
ctod.now = g_get_monotonic_time () / 1000;
|
||||||
g_slist_foreach (sn->startup_sequences,
|
g_slist_foreach (sn->startup_sequences,
|
||||||
collect_timed_out_foreach,
|
collect_timed_out_foreach,
|
||||||
&ctod);
|
&ctod);
|
||||||
@@ -494,6 +529,8 @@ meta_startup_notification_remove_sequence (MetaStartupNotification *sn,
|
|||||||
sn->startup_sequences = g_slist_remove (sn->startup_sequences, seq);
|
sn->startup_sequences = g_slist_remove (sn->startup_sequences, seq);
|
||||||
meta_startup_notification_update_feedback (sn);
|
meta_startup_notification_update_feedback (sn);
|
||||||
|
|
||||||
|
g_signal_handlers_disconnect_by_func (seq, on_sequence_completed, sn);
|
||||||
|
|
||||||
if (sn->startup_sequences == NULL &&
|
if (sn->startup_sequences == NULL &&
|
||||||
sn->startup_sequence_timeout != 0)
|
sn->startup_sequence_timeout != 0)
|
||||||
{
|
{
|
||||||
|
@@ -55,12 +55,6 @@ if have_libgudev
|
|||||||
]
|
]
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if have_startup_notification
|
|
||||||
mutter_pkg_private_deps += [
|
|
||||||
libstartup_notification_dep,
|
|
||||||
]
|
|
||||||
endif
|
|
||||||
|
|
||||||
if have_libwacom
|
if have_libwacom
|
||||||
mutter_pkg_private_deps += [
|
mutter_pkg_private_deps += [
|
||||||
libwacom_dep,
|
libwacom_dep,
|
||||||
@@ -778,32 +772,6 @@ libmutter_dep = declare_dependency(
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
# Interal library for gtk-doc (we need symbol visibility)
|
|
||||||
_libmutter_public_symbols = library(libmutter_name + '-public-symbols',
|
|
||||||
sources: [
|
|
||||||
mutter_sources,
|
|
||||||
mutter_built_sources,
|
|
||||||
],
|
|
||||||
include_directories: mutter_includes,
|
|
||||||
c_args: mutter_c_args,
|
|
||||||
dependencies: [
|
|
||||||
libmutter_cogl_dep,
|
|
||||||
libmutter_clutter_dep,
|
|
||||||
mutter_deps,
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
_libmutter_public_symbols_dep = declare_dependency(
|
|
||||||
link_with: _libmutter_public_symbols,
|
|
||||||
include_directories: mutter_includes,
|
|
||||||
sources: mutter_built_sources,
|
|
||||||
dependencies: [
|
|
||||||
libmutter_cogl_dep,
|
|
||||||
libmutter_clutter_dep,
|
|
||||||
mutter_deps,
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
executable('mutter',
|
executable('mutter',
|
||||||
sources: [
|
sources: [
|
||||||
files('core/mutter.c'),
|
files('core/mutter.c'),
|
||||||
|
@@ -624,14 +624,14 @@ meta_xdg_output_manager_get_xdg_output (struct wl_client *client,
|
|||||||
wl_resource_get_version (resource),
|
wl_resource_get_version (resource),
|
||||||
id);
|
id);
|
||||||
|
|
||||||
wl_resource_set_implementation (xdg_output_resource,
|
|
||||||
&meta_xdg_output_interface,
|
|
||||||
NULL, meta_xdg_output_destructor);
|
|
||||||
|
|
||||||
wayland_output = wl_resource_get_user_data (output);
|
wayland_output = wl_resource_get_user_data (output);
|
||||||
if (!wayland_output)
|
if (!wayland_output)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
wl_resource_set_implementation (xdg_output_resource,
|
||||||
|
&meta_xdg_output_interface,
|
||||||
|
wayland_output, meta_xdg_output_destructor);
|
||||||
|
|
||||||
wayland_output->xdg_output_resources =
|
wayland_output->xdg_output_resources =
|
||||||
g_list_prepend (wayland_output->xdg_output_resources, xdg_output_resource);
|
g_list_prepend (wayland_output->xdg_output_resources, xdg_output_resource);
|
||||||
|
|
||||||
|
@@ -35,9 +35,6 @@
|
|||||||
|
|
||||||
typedef struct _MetaXWaylandSelection MetaXWaylandSelection;
|
typedef struct _MetaXWaylandSelection MetaXWaylandSelection;
|
||||||
|
|
||||||
/**
|
|
||||||
* MetaWaylandFrameCallback: (skip)
|
|
||||||
*/
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
|
@@ -26,266 +26,301 @@
|
|||||||
#include "meta/meta-x11-errors.h"
|
#include "meta/meta-x11-errors.h"
|
||||||
#include "x11/meta-x11-display-private.h"
|
#include "x11/meta-x11-display-private.h"
|
||||||
|
|
||||||
#ifdef HAVE_STARTUP_NOTIFICATION
|
#define MAX_MESSAGE_LENGTH 4096
|
||||||
|
#define CLIENT_MESSAGE_DATA_LENGTH 20
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
PROP_SEQ_X11_0,
|
MESSAGE_TYPE_NEW,
|
||||||
PROP_SEQ_X11_SEQ,
|
MESSAGE_TYPE_REMOVE,
|
||||||
N_SEQ_X11_PROPS
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _MetaStartupSequenceX11
|
|
||||||
{
|
|
||||||
MetaStartupSequence parent_instance;
|
|
||||||
SnStartupSequence *seq;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _MetaX11StartupNotification
|
struct _MetaX11StartupNotification
|
||||||
{
|
{
|
||||||
SnDisplay *sn_display;
|
Atom atom_net_startup_info_begin;
|
||||||
SnMonitorContext *sn_context;
|
Atom atom_net_startup_info;
|
||||||
|
GHashTable *messages;
|
||||||
|
MetaX11Display *x11_display;
|
||||||
};
|
};
|
||||||
|
|
||||||
static GParamSpec *seq_x11_props[N_SEQ_X11_PROPS];
|
typedef struct
|
||||||
|
|
||||||
G_DEFINE_TYPE (MetaStartupSequenceX11,
|
|
||||||
meta_startup_sequence_x11,
|
|
||||||
META_TYPE_STARTUP_SEQUENCE)
|
|
||||||
|
|
||||||
static void
|
|
||||||
meta_startup_sequence_x11_complete (MetaStartupSequence *seq)
|
|
||||||
{
|
{
|
||||||
MetaStartupSequenceX11 *seq_x11;
|
Window xwindow;
|
||||||
|
GString *data;
|
||||||
|
} StartupMessage;
|
||||||
|
|
||||||
seq_x11 = META_STARTUP_SEQUENCE_X11 (seq);
|
|
||||||
sn_startup_sequence_complete (seq_x11->seq);
|
static StartupMessage *
|
||||||
|
startup_message_new (Window window)
|
||||||
|
{
|
||||||
|
StartupMessage *message;
|
||||||
|
|
||||||
|
message = g_new0 (StartupMessage, 1);
|
||||||
|
message->xwindow = window;
|
||||||
|
message->data = g_string_new (NULL);
|
||||||
|
|
||||||
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_startup_sequence_x11_finalize (GObject *object)
|
startup_message_free (StartupMessage *message)
|
||||||
{
|
{
|
||||||
MetaStartupSequenceX11 *seq_x11;
|
g_string_free (message->data, TRUE);
|
||||||
|
g_free (message);
|
||||||
seq_x11 = META_STARTUP_SEQUENCE_X11 (object);
|
|
||||||
sn_startup_sequence_unref (seq_x11->seq);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (meta_startup_sequence_x11_parent_class)->finalize (object);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_startup_sequence_x11_set_property (GObject *object,
|
skip_whitespace (const gchar **str)
|
||||||
guint prop_id,
|
|
||||||
const GValue *value,
|
|
||||||
GParamSpec *pspec)
|
|
||||||
{
|
{
|
||||||
MetaStartupSequenceX11 *seq_x11;
|
while ((*str)[0] == ' ')
|
||||||
|
(*str)++;
|
||||||
|
}
|
||||||
|
|
||||||
seq_x11 = META_STARTUP_SEQUENCE_X11 (object);
|
static gchar *
|
||||||
|
parse_key (const gchar **str)
|
||||||
|
{
|
||||||
|
const gchar *start = *str;
|
||||||
|
|
||||||
switch (prop_id)
|
while (*str[0] != '\0' && *str[0] != '=')
|
||||||
|
(*str)++;
|
||||||
|
|
||||||
|
if (start == *str)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return g_strndup (start, *str - start);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gchar *
|
||||||
|
parse_value (const gchar **str)
|
||||||
|
{
|
||||||
|
const gchar *end;
|
||||||
|
gboolean escaped = FALSE, quoted = FALSE;
|
||||||
|
GString *value;
|
||||||
|
|
||||||
|
end = *str;
|
||||||
|
value = g_string_new (NULL);
|
||||||
|
|
||||||
|
while (end[0] != '\0')
|
||||||
{
|
{
|
||||||
case PROP_SEQ_X11_SEQ:
|
if (escaped)
|
||||||
seq_x11->seq = g_value_get_pointer (value);
|
{
|
||||||
sn_startup_sequence_ref (seq_x11->seq);
|
g_string_append_c (value, end[0]);
|
||||||
break;
|
escaped = FALSE;
|
||||||
default:
|
}
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
else
|
||||||
break;
|
{
|
||||||
}
|
if (!quoted && end[0] == ' ')
|
||||||
}
|
break;
|
||||||
|
else if (end[0] == '"')
|
||||||
|
quoted = !quoted;
|
||||||
|
else if (end[0] == '\\')
|
||||||
|
escaped = TRUE;
|
||||||
|
else
|
||||||
|
g_string_append_c (value, end[0]);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
end++;
|
||||||
meta_startup_sequence_x11_get_property (GObject *object,
|
|
||||||
guint prop_id,
|
|
||||||
GValue *value,
|
|
||||||
GParamSpec *pspec)
|
|
||||||
{
|
|
||||||
MetaStartupSequenceX11 *seq_x11;
|
|
||||||
|
|
||||||
seq_x11 = META_STARTUP_SEQUENCE_X11 (object);
|
|
||||||
|
|
||||||
switch (prop_id)
|
|
||||||
{
|
|
||||||
case PROP_SEQ_X11_SEQ:
|
|
||||||
g_value_set_pointer (value, seq_x11->seq);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
meta_startup_sequence_x11_init (MetaStartupSequenceX11 *seq)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
meta_startup_sequence_x11_class_init (MetaStartupSequenceX11Class *klass)
|
|
||||||
{
|
|
||||||
MetaStartupSequenceClass *seq_class;
|
|
||||||
GObjectClass *object_class;
|
|
||||||
|
|
||||||
seq_class = META_STARTUP_SEQUENCE_CLASS (klass);
|
|
||||||
seq_class->complete = meta_startup_sequence_x11_complete;
|
|
||||||
|
|
||||||
object_class = G_OBJECT_CLASS (klass);
|
|
||||||
object_class->finalize = meta_startup_sequence_x11_finalize;
|
|
||||||
object_class->set_property = meta_startup_sequence_x11_set_property;
|
|
||||||
object_class->get_property = meta_startup_sequence_x11_get_property;
|
|
||||||
|
|
||||||
seq_x11_props[PROP_SEQ_X11_SEQ] =
|
|
||||||
g_param_spec_pointer ("seq",
|
|
||||||
"Sequence",
|
|
||||||
"Sequence",
|
|
||||||
G_PARAM_READWRITE |
|
|
||||||
G_PARAM_CONSTRUCT_ONLY);
|
|
||||||
|
|
||||||
g_object_class_install_properties (object_class, N_SEQ_X11_PROPS,
|
|
||||||
seq_x11_props);
|
|
||||||
}
|
|
||||||
|
|
||||||
static MetaStartupSequence *
|
|
||||||
meta_startup_sequence_x11_new (SnStartupSequence *seq)
|
|
||||||
{
|
|
||||||
gint64 timestamp;
|
|
||||||
|
|
||||||
timestamp = sn_startup_sequence_get_timestamp (seq) * 1000;
|
|
||||||
return g_object_new (META_TYPE_STARTUP_SEQUENCE_X11,
|
|
||||||
"id", sn_startup_sequence_get_id (seq),
|
|
||||||
"icon-name", sn_startup_sequence_get_icon_name (seq),
|
|
||||||
"application-id", sn_startup_sequence_get_application_id (seq),
|
|
||||||
"wmclass", sn_startup_sequence_get_wmclass (seq),
|
|
||||||
"name", sn_startup_sequence_get_name (seq),
|
|
||||||
"workspace", sn_startup_sequence_get_workspace (seq),
|
|
||||||
"timestamp", timestamp,
|
|
||||||
"seq", seq,
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
sn_error_trap_push (SnDisplay *sn_display,
|
|
||||||
Display *xdisplay)
|
|
||||||
{
|
|
||||||
MetaDisplay *display;
|
|
||||||
|
|
||||||
display = meta_display_for_x_display (xdisplay);
|
|
||||||
if (display != NULL)
|
|
||||||
meta_x11_error_trap_push (display->x11_display);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
sn_error_trap_pop (SnDisplay *sn_display,
|
|
||||||
Display *xdisplay)
|
|
||||||
{
|
|
||||||
MetaDisplay *display;
|
|
||||||
|
|
||||||
display = meta_display_for_x_display (xdisplay);
|
|
||||||
if (display != NULL)
|
|
||||||
meta_x11_error_trap_pop (display->x11_display);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
meta_startup_notification_sn_event (SnMonitorEvent *event,
|
|
||||||
void *user_data)
|
|
||||||
{
|
|
||||||
MetaX11Display *x11_display = user_data;
|
|
||||||
MetaStartupNotification *sn = x11_display->display->startup_notification;
|
|
||||||
MetaStartupSequence *seq;
|
|
||||||
SnStartupSequence *sequence;
|
|
||||||
|
|
||||||
sequence = sn_monitor_event_get_startup_sequence (event);
|
|
||||||
|
|
||||||
sn_startup_sequence_ref (sequence);
|
|
||||||
|
|
||||||
switch (sn_monitor_event_get_type (event))
|
|
||||||
{
|
|
||||||
case SN_MONITOR_EVENT_INITIATED:
|
|
||||||
{
|
|
||||||
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),
|
|
||||||
wmclass ? wmclass : "(unset)");
|
|
||||||
|
|
||||||
seq = meta_startup_sequence_x11_new (sequence);
|
|
||||||
meta_startup_notification_add_sequence (sn, seq);
|
|
||||||
g_object_unref (seq);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SN_MONITOR_EVENT_COMPLETED:
|
|
||||||
{
|
|
||||||
meta_topic (META_DEBUG_STARTUP,
|
|
||||||
"Received startup completed for %s\n",
|
|
||||||
sn_startup_sequence_get_id (sequence));
|
|
||||||
|
|
||||||
seq = meta_startup_notification_lookup_sequence (sn, sn_startup_sequence_get_id (sequence));
|
|
||||||
if (seq)
|
|
||||||
{
|
|
||||||
meta_startup_sequence_complete (seq);
|
|
||||||
meta_startup_notification_remove_sequence (sn, seq);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SN_MONITOR_EVENT_CHANGED:
|
|
||||||
meta_topic (META_DEBUG_STARTUP,
|
|
||||||
"Received startup changed for %s\n",
|
|
||||||
sn_startup_sequence_get_id (sequence));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SN_MONITOR_EVENT_CANCELED:
|
|
||||||
meta_topic (META_DEBUG_STARTUP,
|
|
||||||
"Received startup canceled for %s\n",
|
|
||||||
sn_startup_sequence_get_id (sequence));
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sn_startup_sequence_unref (sequence);
|
*str = end;
|
||||||
|
|
||||||
|
if (value->len == 0)
|
||||||
|
{
|
||||||
|
g_string_free (value, TRUE);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return g_string_free (value, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
startup_message_parse (StartupMessage *message,
|
||||||
|
int *type,
|
||||||
|
gchar **id,
|
||||||
|
GHashTable **data)
|
||||||
|
{
|
||||||
|
const gchar *str = message->data->str;
|
||||||
|
|
||||||
|
if (strncmp (str, "new:", 4) == 0)
|
||||||
|
{
|
||||||
|
*type = MESSAGE_TYPE_NEW;
|
||||||
|
str += 4;
|
||||||
|
}
|
||||||
|
else if (strncmp (str, "remove:", 7) == 0)
|
||||||
|
{
|
||||||
|
*type = MESSAGE_TYPE_REMOVE;
|
||||||
|
str += 7;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*data = g_hash_table_new_full (g_str_hash,
|
||||||
|
g_str_equal,
|
||||||
|
g_free,
|
||||||
|
g_free);
|
||||||
|
while (str[0])
|
||||||
|
{
|
||||||
|
gchar *key, *value;
|
||||||
|
|
||||||
|
skip_whitespace (&str);
|
||||||
|
key = parse_key (&str);
|
||||||
|
if (!key)
|
||||||
|
break;
|
||||||
|
|
||||||
|
str++;
|
||||||
|
value = parse_value (&str);
|
||||||
|
|
||||||
|
if (!value)
|
||||||
|
{
|
||||||
|
g_free (key);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_hash_table_insert (*data, key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
*id = g_strdup (g_hash_table_lookup (*data, "ID"));
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
startup_message_add_data (StartupMessage *message,
|
||||||
|
const gchar *data)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
|
||||||
|
len = strnlen (data, CLIENT_MESSAGE_DATA_LENGTH);
|
||||||
|
g_string_append_len (message->data, data, len);
|
||||||
|
|
||||||
|
return (message->data->len > MAX_MESSAGE_LENGTH ||
|
||||||
|
len < CLIENT_MESSAGE_DATA_LENGTH);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_x11_startup_notification_init (MetaX11Display *x11_display)
|
meta_x11_startup_notification_init (MetaX11Display *x11_display)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_STARTUP_NOTIFICATION
|
|
||||||
MetaX11StartupNotification *x11_sn;
|
MetaX11StartupNotification *x11_sn;
|
||||||
|
|
||||||
x11_sn = g_new0 (MetaX11StartupNotification, 1);
|
x11_sn = g_new0 (MetaX11StartupNotification, 1);
|
||||||
x11_sn->sn_display = sn_display_new (x11_display->xdisplay,
|
x11_sn->atom_net_startup_info_begin = XInternAtom (x11_display->xdisplay,
|
||||||
sn_error_trap_push,
|
"_NET_STARTUP_INFO_BEGIN",
|
||||||
sn_error_trap_pop);
|
False);
|
||||||
x11_sn->sn_context =
|
x11_sn->atom_net_startup_info = XInternAtom (x11_display->xdisplay,
|
||||||
sn_monitor_context_new (x11_sn->sn_display,
|
"_NET_STARTUP_INFO",
|
||||||
meta_x11_display_get_screen_number (x11_display),
|
False);
|
||||||
meta_startup_notification_sn_event,
|
x11_sn->messages = g_hash_table_new_full (NULL, NULL, NULL,
|
||||||
x11_display,
|
(GDestroyNotify) startup_message_free);
|
||||||
NULL);
|
x11_sn->x11_display = x11_display;
|
||||||
|
|
||||||
x11_display->startup_notification = x11_sn;
|
x11_display->startup_notification = x11_sn;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_x11_startup_notification_release (MetaX11Display *x11_display)
|
meta_x11_startup_notification_release (MetaX11Display *x11_display)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_STARTUP_NOTIFICATION
|
|
||||||
MetaX11StartupNotification *x11_sn = x11_display->startup_notification;
|
MetaX11StartupNotification *x11_sn = x11_display->startup_notification;
|
||||||
|
|
||||||
x11_display->startup_notification = NULL;
|
x11_display->startup_notification = NULL;
|
||||||
|
|
||||||
if (x11_sn)
|
if (x11_sn)
|
||||||
{
|
{
|
||||||
sn_monitor_context_unref (x11_sn->sn_context);
|
g_hash_table_unref (x11_sn->messages);
|
||||||
sn_display_unref (x11_sn->sn_display);
|
|
||||||
g_free (x11_sn);
|
g_free (x11_sn);
|
||||||
}
|
}
|
||||||
#endif
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_message (MetaX11StartupNotification *x11_sn,
|
||||||
|
StartupMessage *message)
|
||||||
|
{
|
||||||
|
MetaStartupNotification *sn = x11_sn->x11_display->display->startup_notification;
|
||||||
|
MetaStartupSequence *seq;
|
||||||
|
GHashTable *data;
|
||||||
|
char *id;
|
||||||
|
int type;
|
||||||
|
|
||||||
|
if (message->data->len <= MAX_MESSAGE_LENGTH &&
|
||||||
|
g_utf8_validate (message->data->str, -1, NULL) &&
|
||||||
|
startup_message_parse (message, &type, &id, &data))
|
||||||
|
{
|
||||||
|
if (type == MESSAGE_TYPE_NEW)
|
||||||
|
{
|
||||||
|
uint64_t timestamp = 0;
|
||||||
|
int workspace = -1;
|
||||||
|
|
||||||
|
if (g_hash_table_contains (data, "DESKTOP"))
|
||||||
|
workspace = atoi (g_hash_table_lookup (data, "DESKTOP"));
|
||||||
|
if (g_hash_table_contains (data, "TIMESTAMP"))
|
||||||
|
timestamp = g_ascii_strtoull (g_hash_table_lookup (data, "TIMESTAMP"), NULL, 10);
|
||||||
|
|
||||||
|
seq = g_object_new (META_TYPE_STARTUP_SEQUENCE,
|
||||||
|
"id", id,
|
||||||
|
"icon-name", g_hash_table_lookup (data, "ICON_NAME"),
|
||||||
|
"application-id", g_hash_table_lookup (data, "APPLICATION_ID"),
|
||||||
|
"wmclass", g_hash_table_lookup (data, "WMCLASS"),
|
||||||
|
"name", g_hash_table_lookup (data, "NAME"),
|
||||||
|
"workspace", workspace,
|
||||||
|
"timestamp", timestamp,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
meta_topic (META_DEBUG_STARTUP,
|
||||||
|
"Received startup initiated for %s wmclass %s\n",
|
||||||
|
id, (gchar*) g_hash_table_lookup (data, "WMCLASS"));
|
||||||
|
|
||||||
|
meta_startup_notification_add_sequence (sn, seq);
|
||||||
|
g_object_unref (seq);
|
||||||
|
}
|
||||||
|
else if (type == MESSAGE_TYPE_REMOVE)
|
||||||
|
{
|
||||||
|
meta_topic (META_DEBUG_STARTUP,
|
||||||
|
"Received startup completed for %s\n", id);
|
||||||
|
seq = meta_startup_notification_lookup_sequence (sn, id);
|
||||||
|
|
||||||
|
if (seq)
|
||||||
|
{
|
||||||
|
meta_startup_sequence_complete (seq);
|
||||||
|
meta_startup_notification_remove_sequence (sn, seq);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_hash_table_unref (data);
|
||||||
|
g_free (id);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_hash_table_remove (x11_sn->messages, GINT_TO_POINTER (message->xwindow));
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
handle_startup_notification_event (MetaX11StartupNotification *x11_sn,
|
||||||
|
XClientMessageEvent *client_event)
|
||||||
|
{
|
||||||
|
StartupMessage *message;
|
||||||
|
|
||||||
|
if (client_event->message_type == x11_sn->atom_net_startup_info_begin)
|
||||||
|
{
|
||||||
|
message = startup_message_new (client_event->window);
|
||||||
|
g_hash_table_insert (x11_sn->messages,
|
||||||
|
GINT_TO_POINTER (client_event->window),
|
||||||
|
message);
|
||||||
|
if (startup_message_add_data (message, client_event->data.b))
|
||||||
|
handle_message (x11_sn, message);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else if (client_event->message_type == x11_sn->atom_net_startup_info)
|
||||||
|
{
|
||||||
|
message = g_hash_table_lookup (x11_sn->messages,
|
||||||
|
GINT_TO_POINTER (client_event->window));
|
||||||
|
if (message)
|
||||||
|
{
|
||||||
|
if (startup_message_add_data (message, client_event->data.b))
|
||||||
|
handle_message (x11_sn, message);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
@@ -297,74 +332,8 @@ meta_x11_startup_notification_handle_xevent (MetaX11Display *x11_display,
|
|||||||
if (!x11_sn)
|
if (!x11_sn)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
return sn_display_process_event (x11_sn->sn_display, xevent);
|
if (xevent->xany.type != ClientMessage)
|
||||||
}
|
return FALSE;
|
||||||
|
|
||||||
typedef void (* SetAppIdFunc) (SnLauncherContext *context,
|
return handle_startup_notification_event (x11_sn, &xevent->xclient);
|
||||||
const char *app_id);
|
|
||||||
|
|
||||||
gchar *
|
|
||||||
meta_x11_startup_notification_launch (MetaX11Display *x11_display,
|
|
||||||
GAppInfo *app_info,
|
|
||||||
uint32_t timestamp,
|
|
||||||
int workspace)
|
|
||||||
{
|
|
||||||
gchar *startup_id = NULL;
|
|
||||||
#ifdef HAVE_STARTUP_NOTIFICATION
|
|
||||||
MetaX11StartupNotification *x11_sn = x11_display->startup_notification;
|
|
||||||
SnLauncherContext *sn_launcher;
|
|
||||||
int screen;
|
|
||||||
|
|
||||||
screen = meta_x11_display_get_screen_number (x11_display);
|
|
||||||
sn_launcher = sn_launcher_context_new (x11_sn->sn_display, screen);
|
|
||||||
|
|
||||||
sn_launcher_context_set_name (sn_launcher, g_app_info_get_name (app_info));
|
|
||||||
sn_launcher_context_set_workspace (sn_launcher, workspace);
|
|
||||||
sn_launcher_context_set_binary_name (sn_launcher,
|
|
||||||
g_app_info_get_executable (app_info));
|
|
||||||
|
|
||||||
if (G_IS_DESKTOP_APP_INFO (app_info))
|
|
||||||
{
|
|
||||||
const char *application_id;
|
|
||||||
SetAppIdFunc func = NULL;
|
|
||||||
GModule *self;
|
|
||||||
|
|
||||||
application_id =
|
|
||||||
g_desktop_app_info_get_filename (G_DESKTOP_APP_INFO (app_info));
|
|
||||||
self = g_module_open (NULL, G_MODULE_BIND_MASK);
|
|
||||||
|
|
||||||
/* This here is a terrible workaround to bypass a libsn bug that is not
|
|
||||||
* likely to get fixed at this point.
|
|
||||||
* sn_launcher_context_set_application_id is correctly defined in the
|
|
||||||
* sn-launcher.h file, but it's mistakenly called
|
|
||||||
* sn_launcher_set_application_id in the C file.
|
|
||||||
*
|
|
||||||
* We look up the symbol instead, but still prefer the correctly named
|
|
||||||
* function, if one were ever to be added.
|
|
||||||
*/
|
|
||||||
if (!g_module_symbol (self, "sn_launcher_context_set_application_id",
|
|
||||||
(gpointer *) &func))
|
|
||||||
{
|
|
||||||
g_module_symbol (self, "sn_launcher_set_application_id",
|
|
||||||
(gpointer *) &func);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (func)
|
|
||||||
func (sn_launcher, application_id);
|
|
||||||
|
|
||||||
g_module_close (self);
|
|
||||||
}
|
|
||||||
|
|
||||||
sn_launcher_context_initiate (sn_launcher,
|
|
||||||
g_get_prgname (),
|
|
||||||
g_app_info_get_name (app_info),
|
|
||||||
timestamp);
|
|
||||||
|
|
||||||
startup_id = g_strdup (sn_launcher_context_get_startup_id (sn_launcher));
|
|
||||||
|
|
||||||
/* Fire and forget, we have a SnMonitor in addition */
|
|
||||||
sn_launcher_context_unref (sn_launcher);
|
|
||||||
#endif /* HAVE_STARTUP_NOTIFICATION */
|
|
||||||
|
|
||||||
return startup_id;
|
|
||||||
}
|
}
|
||||||
|
@@ -36,9 +36,4 @@ void meta_x11_startup_notification_release (MetaX11Display *x11_display);
|
|||||||
gboolean meta_x11_startup_notification_handle_xevent (MetaX11Display *x11_display,
|
gboolean meta_x11_startup_notification_handle_xevent (MetaX11Display *x11_display,
|
||||||
XEvent *xevent);
|
XEvent *xevent);
|
||||||
|
|
||||||
gchar * meta_x11_startup_notification_launch (MetaX11Display *x11_display,
|
|
||||||
GAppInfo *app_info,
|
|
||||||
uint32_t timestamp,
|
|
||||||
int workspace);
|
|
||||||
|
|
||||||
#endif /* META_X11_STARTUP_NOTIFICATION_H */
|
#endif /* META_X11_STARTUP_NOTIFICATION_H */
|
||||||
|
Reference in New Issue
Block a user