Compare commits

...

23 Commits

Author SHA1 Message Date
Florian Müllner
189f71f5d1 Bump version to 3.32.2
Update NEWS.
2019-05-14 14:01:28 +00:00
Carlos Garnacho
0a3cddeecf core: Check environment variables before giving to GAppLaunchContext
Depending on the type of session, one or the other might be NULL, which
is not meant to be handled by these functions. Check for both DISPLAY
envvars before setting them on the GAppLaunchContext.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/586
2019-05-07 16:07:34 +02:00
Jonas Ådahl
ee92e4fe13 idle-monitor: Postpone dispatching of idle timeout if not ready
If we update the ready time while the source is already in the
to-dispatch list, changing the ready time doesn't have any effect, and
the source will still be dispatched. This could cause incorrect idle
watch firing causing the power management plugin in
gnome-settings-daemon to sometimes turn off monitors due to it believing
the user had been idle for some time, while in fact, they just logged
back in.

Fix this by not actually dispatching the idle timeout if the ready time
is in the future when actually dispatching.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/543
2019-05-07 16:01:58 +02:00
Jonas Ådahl
6933ce0976 idle-monitor: Use G_SOURCE_CONTINUE instead of TRUE
Returning TRUE is confusing, as it doesn't carry any relevant meaning.
Use G_SOURCE_CONTINUE to make it clearer that the source is here to
stay.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/543
2019-05-07 16:01:58 +02:00
Carlos Garnacho
f9d6627fe0 backends: Fallback to builtin panel for devices where all heuristics fail
This is 1) relatively likely as not all touchscreens are nice enough to
report a device size that will help us here and 2) Better than nothing if
everything fails anyway, as it will break on multi-monitor and non-default
monitor rotations.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/581
2019-05-03 23:48:29 +02:00
Marco Trevisan (Treviño)
668c44e66b compositor: Disconnect from stage signals on destruction
From this point there's not any need for the compositor to listen to signals
so we can disconnect from the stage ones we are connected to.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/556


(cherry picked from commit 3ba79961fe)
2019-05-01 05:11:17 +00:00
Marco Trevisan (Treviño)
3495a43810 compositor: Destroy window actors list on destruction
When the compositor is destroyed we should cleanup the list of window actors we
created and destroy them.
Since all the actors are added to the window_group or top_window_group we can
just destroy these containers (together with the feedback_group), and simply
free the windows list.

This is particularly needed under X11 because before we destroy the display, we
might do some cleanups as detaching the surface pixmaps and freeing the damages
and if this happens at later point (for example when triggered by garbage
collector in gnome-shell), we might crash because the x11 dpy reference is
already gone.

Destroying the window actors instead, ensures we avoid any further call to X11
related functions and that we release the actors XServer resources.

Fixes https://gitlab.gnome.org/GNOME/mutter/issues/576


(cherry picked from commit 7718e67f5c)
2019-05-01 05:10:51 +00:00
Olivier Fourdan
9a795d3d0f input-settings: Use 0 initialized struct for kbd a11y
Make sure our keyboard accessibility settings structure is all zero
initialized, to avoid potential padding issues on some platform when
comparing settings.

Reported by Daniel van Vugt on IRC.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/552


(cherry picked from commit eccf7b105c)
2019-04-30 10:57:45 +00:00
Olivier Fourdan
abc3fdcc65 clutter/x11: disable mousekeys with Numlock ON
GNOME documentation on accessibility features states that mousekeys
work only when NumLock is OFF:

  https://help.gnome.org/users/gnome-help/stable/mouse-mousekeys.html

Change the clutter/x11 implementation to match the documentation, i.e.
disable mousekeys when NumLock in ON so that switching NumLock ON
restores the numeric keypad behaviour.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/530
(cherry picked from commit 251fa024c4)
2019-04-19 16:18:18 +02:00
Olivier Fourdan
4705a31049 clutter/evdev: disable mousekeys with Numlock ON
The clutter/evdev implementation of mousekeys is designed after the
current implementation in X11, and works when the setting is enabled
regardless of the status of NumLock.

The GNOME documentation on accessibility features states however that
mousekeys work only when NumLock is OFF:

  https://help.gnome.org/users/gnome-help/stable/mouse-mousekeys.html

Change the clutter/evdev implementation to match the documentation, i.e.
disable mousekeys when NumLock in ON so that switching NumLock ON
restores the numeric keypad behaviour.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/530
(cherry picked from commit 471b61bd14)
2019-04-19 16:18:12 +02:00
Florian Müllner
e3f3274bbf Bump version to 3.32.1
Update NEWS.
2019-04-17 19:40:01 +02:00
Olivier Fourdan
d2ca5cc26b display: Fix inconsistent behavior with demand attention
When focus stealing prevention kicks in, mutter would set the demand
attention flag on the window.

Focus stealing prevention would also prevent the window from being
raised and focused, which is expected as its precisely its purpose.

Yet, when that occurs, the user expects the window which has just been
prevented from being focused to be the next one in the MRU list, so
that pressing [Alt]-[Tab] would raise and give focus to that window.

This works fine when the window is placed on the primary monitor, but
not when placed on another monitor, in which case the window which has
been denied focus is placed ahead of the MRU list and pressing
[Alt]-[Tab] would leave the focus on the current window.

This is because of a mechanism in `meta_display_get_tab_list()` which
forces the windows with the demand attention flag set to be placed first
in the MRU list when they're placed on a workspace different from the
current one.

But because workspaces apply only to the primary monitor (by default),
the windows placed on other outputs have their workspace set to `NULL`
which forces them ahead of the MRU list by mistake.

Fix this by using the appropriate `meta_window_located_on_workspace()
function to check if the window is on another workspace.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/523
2019-04-17 18:53:04 +02:00
Carlos Garnacho
3de6f7ebfe core: Emit MetaStartupNotification::changed on sequence completion
This way handlers that want to know the get_complete() status will be able
to do so without further delays.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/541
2019-04-17 18:42:09 +02:00
Carlos Garnacho
38ff01d6d0 core: Add MetaStartupSequence::complete signal
It was a vfunc so far, but we want things subscribing to it.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/541
2019-04-17 18:42:04 +02:00
Carlos Garnacho
40103d6f41 core: Account for completed sequences in feedback updates
The sequences may stay completed in the list (eg. pending a focus request),
it's then confusing to show the "wait" cursor icon until they are really
gone.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/541
2019-04-17 18:42:00 +02:00
Carlos Garnacho
ab7ef5f8bf core: Fix differing sequence timestamp precision expectations
Calculations were being done at places accounting on usec precision,
however those are still treated as having msec precision at places. Let's
consolidate for the latter since it requires less changes across the board
and usec precision doesn't buy us anything here.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/541
2019-04-17 18:41:13 +02:00
Olivier Fourdan
2c1a951b6e wayland/output: Set user data of xdg_output resource
mutter would randomly crash in `send_xdg_output_events()` when changing
the fractional scaling:

  wl_resource_post_event ()
  zxdg_output_v1_send_logical_size ()
  send_xdg_output_events ()
  wayland_output_update_for_output ()
  meta_wayland_compositor_update_outputs ()
  on_monitors_changed ()
  g_closure_invoke ()
  signal_emit_unlocked_R ()
  g_signal_emit_valist ()
  _signal_emit ()
  meta_monitor_manager_notify_monitors_changed ()
  meta_monitor_manager_rebuild ()

This is because the xdg-output resource got freed but wasn't removed
from the list of resources.

Fix this by setting the user data of the xdg-output resource to the
corresponding `MetaWaylandOutput` so that the xdg-output resource
destructor can remove it from the list of resources.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/538
2019-04-15 15:41:47 +02:00
Jonas Dreßler
6ec330ccfa keybindings: Stop keybinding if a touch happens while Super is pressed
We use the combination of pressing Super and clicking+moving the mouse
to drag windows around and we also support pressing Super and using the
touchscreen to drag windows.

Since we don't want to show the overview when the Super key was used to
initiate a window drag, prevent showing the overview in case a
TOUCH_BEGIN or TOUCH_END event happened during the key was pressed.

Fixes https://gitlab.gnome.org/GNOME/mutter/issues/228

https://gitlab.gnome.org/GNOME/mutter/merge_requests/495
2019-04-15 11:10:47 +00:00
Daniel van Vugt
20c1295a33 cogl-winsys-glx: Fix frame notification race/leak
If a second `set_{sync,complete}_pending` was queued before the idle
handler had flushed the first then one of them would be forgotten.
It would stay queued forever and never emitted as a notification.

This could happen repeatedly causing a slow leak. But worse still,
`clutter-stage-cogl` would then have `pending_swaps` permanently stuck
above zero preventing the presentation timing logic from being used.

The problem is that a boolean can only count to one, but in some cases
(triple buffering, whether intentional or accidental #334) we need it to
count to two. So just change booleans to integers and count properly.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/216
2019-04-12 11:09:00 +08:00
Olivier Fourdan
fa4a787386 clutter/evdev: Toggle accessibility features from keyboard
The keyboard accessibility setting "enable" is actually even more
misleading that initially anticipated, as it does not control the
entire keyboard accessibility feature, but just the "enable by
keyboard" feature, i.e. being able to enable or disable stickykeys
or slowkeys using various keyboard actions.

Yet the accessibility features should still work even if the "enable"
setting is unset, those can be controlled by the accessibility menu in
GNOME Shell for example.

Change the clutter/evdev implementation to match that behavior as found
in the x11 backend, so both backends are now consistent.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/531
2019-04-11 13:51:43 +00:00
Olivier Fourdan
85b734fde8 clutter/device-manager: Small code cleanup
Use a `memcmp()` instead of checking every field in the structure to be
equal, it's both faster and less error prone.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/531
2019-04-11 13:51:43 +00:00
Pekka Paalanen
28419cdedf renderer/native: Check primary GPU supports EGL
Since "renderer/native: make EGL initialization failure not fatal" it is
possible, under specific failure conditions, to end up with a primary GPU whose
EGL initialization failed. That cannot work.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/521
2019-04-11 15:11:41 +03:00
Pekka Paalanen
3b46a8cd70 renderer/native: Make EGL initialization failure not fatal
The failure to initialize EGL does not necessarily mean the KMS device cannot
be used. The device could still be used as a "secondary GPU" with the CPU copy
mode.

If meta_renderer_native_create_renderer_gpu_data () fails,
meta_renderer_native_get_gpu_data () will return NULL, which may cause crashes.
This patch removes most of the failures, but does not fix the NULL dereferences
that will still happen if creating gpu data fails.

This patch reorders create_renderer_gpu_data_gbm () so that it fails hard only
if GBM device cannot be created, and otherwise always returns an initialized
gpu data structure. Users of the gpu data structure are responsible for
checking egl_display validity.

The GBM device creation failure is a hard failure because presumably GBM is
necessary for cursors.

Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/542
https://gitlab.gnome.org/GNOME/mutter/merge_requests/521
2019-04-11 15:11:41 +03:00
19 changed files with 306 additions and 99 deletions

41
NEWS
View File

@@ -1,3 +1,44 @@
3.32.2
======
* Disable mouse keys with Numlock on [Olivier; #530]
* Fix crash when restarting on X11 [Marco; #576]
* Fix mapping of touchscreens that don't report dimensions [Carlos; #581]
* Fix spurious idle signals that prevent session unblank [Jonas; !543]
* Misc. bug fixes and cleanups [Olivier, Marco, Carlos; !552, !557, #586]
Contributors:
Jonas Ådahl, Olivier Fourdan, Carlos Garnacho, Marco Trevisan (Treviño)
3.32.1
======
* Fix fallback app menu on wayland [Florian; #493]
* Fix elogind support [Tom; !491]
* Fix startup notifications not timing out [Carlos; #501]
* Fix keyboard accessibility toggle from keys
[Olivier, Carlos; !501, #529, !531]
* Fix touchscreen input on rotated displays [Carlos; #514]
* Work around hangul text input bug [Carlos; #1365]
* Fix blurry wallpaper scaling [Daniel; !505]
* Fix placement of window menu when using fractional scaling [Jan; #527]
* Fix repaint issues of offscreen effects on secondary monitors [Daniel; !511]
* Fix windows not getting focus after launch [Daniel; #505]
* Properly advertise support for 'underscan' property [Jonas; !507]
* Improve power-saving handling [Jonas; !506]
* Fix moving windows by super+touch [Jonas D.; !495]
* Misc. bug fixes and cleanups [Benjamin, Florian, Adam, Marco, Pablo,
Erik, Jonas, Heiher, Pekka, Daniel, Olivier, Carlos; !478, !475, !480,
!482, #490, !488, #491, #480, !477, !496, !492, !485, !515, !519, !521,
!216, !538, #541, #523]
Contributors:
Jonas Ådahl, Pablo Barciela, Benjamin Berg, Tom Briden, Jonas Dreßler,
Olivier Fourdan, Carlos Garnacho, Jan Alexander Steffens (heftig), Heiher,
Adam Jackson, Erik Kurzinger, Florian Müllner, Pekka Paalanen,
Marco Trevisan (Treviño), Daniel van Vugt
Translators:
Khaled Hosny [ar], Goran Vidović [hr], Daniel Mustieles [es]
3.32.0
======
* Fix deadlock when cancelling a theme sound [Andrea; !474]

View File

@@ -550,13 +550,7 @@ static gboolean
are_kbd_a11y_settings_equal (ClutterKbdA11ySettings *a,
ClutterKbdA11ySettings *b)
{
return (a->controls == b->controls &&
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);
return (memcmp (a, b, sizeof (ClutterKbdA11ySettings)) == 0);
}
void

View File

@@ -855,6 +855,14 @@ emulate_pointer_motion (ClutterInputDeviceEvdev *device,
clutter_virtual_input_device_notify_relative_motion (device->mousekeys_virtual_device,
time_us, dx_motion, dy_motion);
}
static gboolean
is_numlock_active (ClutterInputDeviceEvdev *device)
{
ClutterSeatEvdev *seat = device->seat;
return xkb_state_mod_name_is_active (seat->xkb,
"Mod2",
XKB_STATE_MODS_LOCKED);
}
static void
enable_mousekeys (ClutterInputDeviceEvdev *device)
@@ -1013,6 +1021,10 @@ handle_mousekeys_press (ClutterEvent *event,
if (!(event->key.flags & CLUTTER_EVENT_FLAG_SYNTHETIC))
stop_mousekeys_move (device);
/* Do not handle mousekeys if NumLock is ON */
if (is_numlock_active (device))
return FALSE;
/* Button selection */
switch (event->key.keyval)
{
@@ -1084,6 +1096,10 @@ static gboolean
handle_mousekeys_release (ClutterEvent *event,
ClutterInputDeviceEvdev *device)
{
/* Do not handle mousekeys if NumLock is ON */
if (is_numlock_active (device))
return FALSE;
switch (event->key.keyval)
{
case XKB_KEY_KP_0:
@@ -1132,13 +1148,13 @@ clutter_input_device_evdev_process_kbd_a11y_event (ClutterEvent *e
if (event->key.flags & CLUTTER_EVENT_FLAG_INPUT_METHOD)
goto emit_event;
if (!(device_evdev->a11y_flags & CLUTTER_A11Y_KEYBOARD_ENABLED))
goto emit_event;
if (event->type == CLUTTER_KEY_PRESS)
handle_enablekeys_press (event, device_evdev);
else
handle_enablekeys_release (event, device_evdev);
if (device_evdev->a11y_flags & CLUTTER_A11Y_KEYBOARD_ENABLED)
{
if (event->type == CLUTTER_KEY_PRESS)
handle_enablekeys_press (event, device_evdev);
else
handle_enablekeys_release (event, device_evdev);
}
if (device_evdev->a11y_flags & CLUTTER_A11Y_MOUSE_KEYS_ENABLED)
{

View File

@@ -54,6 +54,7 @@
#include "clutter-main.h"
#include "clutter-private.h"
#include "clutter-settings-private.h"
#include "clutter-xkb-a11y-x11.h"
G_DEFINE_TYPE (ClutterBackendX11, clutter_backend_x11, CLUTTER_TYPE_BACKEND)
@@ -276,6 +277,20 @@ clutter_backend_x11_create_device_manager (ClutterBackendX11 *backend_x11)
_clutter_backend_add_event_translator (backend, translator);
}
static void
on_keymap_state_change (ClutterKeymapX11 *keymap_x11,
gpointer data)
{
ClutterDeviceManager *device_manager = CLUTTER_DEVICE_MANAGER (data);
ClutterKbdA11ySettings kbd_a11y_settings;
/* On keymaps state change, just reapply the current settings, it'll
* take care of enabling/disabling mousekeys based on NumLock state.
*/
clutter_device_manager_get_kbd_a11y_settings (device_manager, &kbd_a11y_settings);
clutter_device_manager_x11_apply_kbd_a11y_settings (device_manager, &kbd_a11y_settings);
}
static void
clutter_backend_x11_create_keymap (ClutterBackendX11 *backend_x11)
{
@@ -292,6 +307,11 @@ clutter_backend_x11_create_keymap (ClutterBackendX11 *backend_x11)
backend = CLUTTER_BACKEND (backend_x11);
translator = CLUTTER_EVENT_TRANSLATOR (backend_x11->keymap);
_clutter_backend_add_event_translator (backend, translator);
g_signal_connect (backend_x11->keymap,
"state-changed",
G_CALLBACK (on_keymap_state_change),
backend->device_manager);
}
}

View File

@@ -241,8 +241,13 @@ clutter_device_manager_x11_apply_kbd_a11y_settings (ClutterDeviceManager *devi
}
/* mouse keys */
if (set_xkb_ctrl (desc, kbd_a11y_settings->controls,
CLUTTER_A11Y_MOUSE_KEYS_ENABLED, XkbMouseKeysMask | XkbMouseKeysAccelMask))
if (clutter_keymap_get_num_lock_state (CLUTTER_KEYMAP (backend_x11->keymap)))
{
/* Disable mousekeys when NumLock is ON */
desc->ctrls->enabled_ctrls &= ~(XkbMouseKeysMask | XkbMouseKeysAccelMask);
}
else if (set_xkb_ctrl (desc, kbd_a11y_settings->controls,
CLUTTER_A11Y_MOUSE_KEYS_ENABLED, XkbMouseKeysMask | XkbMouseKeysAccelMask))
{
gint mk_max_speed;
gint mk_accel_time;

View File

@@ -99,9 +99,9 @@ typedef struct _CoglOnscreenGLX
CoglOnscreenXlib _parent;
GLXDrawable glxwin;
uint32_t last_swap_vsync_counter;
gboolean pending_sync_notify;
gboolean pending_complete_notify;
gboolean pending_resize_notify;
uint32_t pending_sync_notify;
uint32_t pending_complete_notify;
uint32_t pending_resize_notify;
GThread *swap_wait_thread;
GQueue *swap_wait_queue;
@@ -347,35 +347,35 @@ flush_pending_notifications_cb (void *data,
{
CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
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
* potentially immediately queue a subsequent pending notify so
* we need to clear the flag before invoking the callback */
glx_onscreen->pending_sync_notify = FALSE;
glx_onscreen->pending_complete_notify = FALSE;
if (pending_sync_notify)
while (glx_onscreen->pending_sync_notify > 0 ||
glx_onscreen->pending_complete_notify > 0 ||
glx_onscreen->pending_resize_notify > 0)
{
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)
{
CoglFrameInfo *info = g_queue_pop_head (&onscreen->pending_frame_infos);
if (glx_onscreen->pending_complete_notify > 0)
{
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)
{
_cogl_onscreen_notify_resize (onscreen);
glx_onscreen->pending_resize_notify = FALSE;
if (glx_onscreen->pending_resize_notify > 0)
{
_cogl_onscreen_notify_resize (onscreen);
glx_onscreen->pending_resize_notify--;
}
}
}
}
@@ -417,7 +417,7 @@ set_sync_pending (CoglOnscreen *onscreen)
NULL);
}
glx_onscreen->pending_sync_notify = TRUE;
glx_onscreen->pending_sync_notify++;
}
static void
@@ -440,7 +440,7 @@ set_complete_pending (CoglOnscreen *onscreen)
NULL);
}
glx_onscreen->pending_complete_notify = TRUE;
glx_onscreen->pending_complete_notify++;
}
static void
@@ -533,7 +533,7 @@ notify_resize (CoglContext *context,
NULL);
}
glx_onscreen->pending_resize_notify = TRUE;
glx_onscreen->pending_resize_notify++;
if (!xlib_onscreen->is_foreign_xwin)
{

View File

@@ -1,5 +1,5 @@
project('mutter', 'c',
version: '3.32.0',
version: '3.32.2',
meson_version: '>= 0.48.0',
license: 'GPLv2+'
)

View File

@@ -316,11 +316,18 @@ idle_monitor_dispatch_timeout (GSource *source,
gpointer user_data)
{
MetaIdleMonitorWatch *watch = (MetaIdleMonitorWatch *) user_data;
int64_t now;
int64_t ready_time;
now = g_source_get_time (source);
ready_time = g_source_get_ready_time (source);
if (ready_time > now)
return G_SOURCE_CONTINUE;
_meta_idle_monitor_watch_fire (watch);
g_source_set_ready_time (watch->timeout_source, -1);
return TRUE;
return G_SOURCE_CONTINUE;
}
static GSourceFuncs idle_monitor_source_funcs = {

View File

@@ -381,7 +381,7 @@ guess_candidates (MetaInputMapper *mapper,
info->candidates[META_MATCH_SIZE] = matched_monitor;
}
if (input->builtin)
if (input->builtin || best == N_OUTPUT_MATCHES)
{
best = MIN (best, META_MATCH_IS_BUILTIN);
find_builtin_output (mapper, &info->candidates[META_MATCH_IS_BUILTIN]);

View File

@@ -1216,7 +1216,7 @@ load_keyboard_a11y_settings (MetaInputSettings *input_settings,
ClutterInputDevice *device)
{
MetaInputSettingsPrivate *priv = meta_input_settings_get_instance_private (input_settings);
ClutterKbdA11ySettings kbd_a11y_settings;
ClutterKbdA11ySettings kbd_a11y_settings = { 0 };
ClutterInputDevice *core_keyboard;
guint i;

View File

@@ -3787,16 +3787,13 @@ gpu_kms_is_hardware_rendering (MetaRendererNative *renderer_native,
return data->secondary.is_hardware_rendering;
}
static MetaRendererNativeGpuData *
create_renderer_gpu_data_gbm (MetaRendererNative *renderer_native,
MetaGpuKms *gpu_kms,
GError **error)
static EGLDisplay
init_gbm_egl_display (MetaRendererNative *renderer_native,
struct gbm_device *gbm_device,
GError **error)
{
MetaEgl *egl = meta_renderer_native_get_egl (renderer_native);
struct gbm_device *gbm_device;
EGLDisplay egl_display;
int kms_fd;
MetaRendererNativeGpuData *renderer_gpu_data;
if (!meta_egl_has_extensions (egl, EGL_NO_DISPLAY, NULL,
"EGL_MESA_platform_gbm",
@@ -3808,9 +3805,31 @@ create_renderer_gpu_data_gbm (MetaRendererNative *renderer_native,
g_set_error (error, G_IO_ERROR,
G_IO_ERROR_FAILED,
"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);
gbm_device = gbm_create_device (kms_fd);
@@ -3822,26 +3841,25 @@ create_renderer_gpu_data_gbm (MetaRendererNative *renderer_native,
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->renderer_native = renderer_native;
renderer_gpu_data->gbm.device = gbm_device;
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);
return renderer_gpu_data;
}
@@ -4134,8 +4152,8 @@ on_gpu_added (MetaMonitorManager *monitor_manager,
}
static MetaGpuKms *
choose_primary_gpu (MetaMonitorManager *manager,
MetaRendererNative *renderer_native)
choose_primary_gpu_unchecked (MetaMonitorManager *manager,
MetaRendererNative *renderer_native)
{
GList *gpus = meta_monitor_manager_get_gpus (manager);
GList *l;
@@ -4184,6 +4202,28 @@ choose_primary_gpu (MetaMonitorManager *manager,
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
meta_renderer_native_initable_init (GInitable *initable,
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);
renderer_native,
error);
if (!renderer_native->primary_gpu_kms)
return FALSE;
return TRUE;
}

View File

@@ -18,6 +18,9 @@ struct _MetaCompositor
guint pre_paint_func_id;
guint post_paint_func_id;
guint stage_presented_id;
guint stage_after_paint_id;
gint64 server_time_query_time;
gint64 server_time_offset;

View File

@@ -92,6 +92,10 @@ on_presented (ClutterStage *stage,
ClutterFrameInfo *frame_info,
MetaCompositor *compositor);
static void
on_top_window_actor_destroyed (MetaWindowActor *window_actor,
MetaCompositor *compositor);
static gboolean
is_modal (MetaDisplay *display)
{
@@ -131,9 +135,31 @@ meta_switch_workspace_completed (MetaCompositor *compositor)
void
meta_compositor_destroy (MetaCompositor *compositor)
{
g_signal_handler_disconnect (compositor->stage,
compositor->stage_after_paint_id);
g_signal_handler_disconnect (compositor->stage,
compositor->stage_presented_id);
compositor->stage_after_paint_id = 0;
compositor->stage_presented_id = 0;
compositor->stage = NULL;
clutter_threads_remove_repaint_func (compositor->pre_paint_func_id);
clutter_threads_remove_repaint_func (compositor->post_paint_func_id);
if (compositor->top_window_actor)
{
g_signal_handlers_disconnect_by_func (compositor->top_window_actor,
on_top_window_actor_destroyed,
compositor);
compositor->top_window_actor = NULL;
}
g_clear_pointer (&compositor->window_group, clutter_actor_destroy);
g_clear_pointer (&compositor->top_window_group, clutter_actor_destroy);
g_clear_pointer (&compositor->feedback_group, clutter_actor_destroy);
g_clear_pointer (&compositor->windows, g_list_free);
if (compositor->have_x11_sync_object)
meta_sync_ring_destroy ();
}
@@ -503,9 +529,10 @@ meta_compositor_manage (MetaCompositor *compositor)
compositor->stage = meta_backend_get_stage (backend);
g_signal_connect (compositor->stage, "presented",
G_CALLBACK (on_presented),
compositor);
compositor->stage_presented_id =
g_signal_connect (compositor->stage, "presented",
G_CALLBACK (on_presented),
compositor);
/* We use connect_after() here to accomodate code in GNOME Shell that,
* when benchmarking drawing performance, connects to ::after-paint
@@ -515,8 +542,9 @@ meta_compositor_manage (MetaCompositor *compositor)
* connections to ::after-paint, connect() vs. connect_after() doesn't
* matter.
*/
g_signal_connect_after (CLUTTER_STAGE (compositor->stage), "after-paint",
G_CALLBACK (after_stage_paint), compositor);
compositor->stage_after_paint_id =
g_signal_connect_after (compositor->stage, "after-paint",
G_CALLBACK (after_stage_paint), compositor);
clutter_stage_set_sync_delay (CLUTTER_STAGE (compositor->stage), META_SYNC_DELAY);

View File

@@ -2236,7 +2236,7 @@ meta_display_get_tab_list (MetaDisplay *display,
MetaWindow *l_window = w->data;
if (l_window->wm_state_demands_attention &&
l_window->workspace != workspace &&
!meta_window_located_on_workspace (l_window, workspace) &&
IN_TAB_CHAIN (l_window, type))
tab_list = g_list_prepend (tab_list, l_window);
}

View File

@@ -2214,6 +2214,8 @@ meta_keybindings_process_event (MetaDisplay *display,
{
case CLUTTER_BUTTON_PRESS:
case CLUTTER_BUTTON_RELEASE:
case CLUTTER_TOUCH_BEGIN:
case CLUTTER_TOUCH_END:
keys->overlay_key_only_pressed = FALSE;
return FALSE;

View File

@@ -110,13 +110,24 @@ static void
meta_launch_context_constructed (GObject *object)
{
MetaLaunchContext *context = META_LAUNCH_CONTEXT (object);
const char *x11_display, *wayland_display;
G_OBJECT_CLASS (meta_launch_context_parent_class)->constructed (object);
g_app_launch_context_setenv (G_APP_LAUNCH_CONTEXT (context),
"DISPLAY", getenv ("DISPLAY"));
g_app_launch_context_setenv (G_APP_LAUNCH_CONTEXT (context),
"WAYLAND_DISPLAY", getenv ("WAYLAND_DISPLAY"));
x11_display = getenv ("DISPLAY");
wayland_display = getenv ("WAYLAND_DISPLAY");
if (x11_display)
{
g_app_launch_context_setenv (G_APP_LAUNCH_CONTEXT (context),
"DISPLAY", x11_display);
}
if (wayland_display)
{
g_app_launch_context_setenv (G_APP_LAUNCH_CONTEXT (context),
"WAYLAND_DISPLAY", wayland_display);
}
}
static gchar *

View File

@@ -37,7 +37,7 @@
* OpenOffice or whatever seems to stop launching - people
* might decide they need to launch it again.
*/
#define STARTUP_TIMEOUT 15000000
#define STARTUP_TIMEOUT_MS 15000
enum
{
@@ -59,6 +59,12 @@ enum
N_SEQ_PROPS
};
enum
{
SEQ_COMPLETE,
N_SEQ_SIGNALS
};
enum
{
CHANGED,
@@ -67,6 +73,7 @@ enum
static guint sn_signals[N_SIGNALS];
static GParamSpec *sn_props[N_PROPS];
static guint seq_signals[N_SEQ_SIGNALS];
static GParamSpec *seq_props[N_SEQ_PROPS];
typedef struct
@@ -106,12 +113,26 @@ G_DEFINE_TYPE_WITH_PRIVATE (MetaStartupSequence,
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
meta_startup_notification_update_feedback (MetaStartupNotification *sn)
{
MetaDisplay *display = sn->display;
if (sn->startup_sequences != NULL)
if (meta_startup_notification_has_pending_sequences (sn))
{
meta_topic (META_DEBUG_STARTUP,
"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->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] =
g_param_spec_string ("id",
"ID",
@@ -317,7 +346,6 @@ meta_startup_sequence_get_timestamp (MetaStartupSequence *seq)
void
meta_startup_sequence_complete (MetaStartupSequence *seq)
{
MetaStartupSequenceClass *klass;
MetaStartupSequencePrivate *priv;
g_return_if_fail (META_IS_STARTUP_SEQUENCE (seq));
@@ -327,10 +355,7 @@ meta_startup_sequence_complete (MetaStartupSequence *seq)
return;
priv->completed = TRUE;
klass = META_STARTUP_SEQUENCE_GET_CLASS (seq);
if (klass->complete)
klass->complete (seq);
g_signal_emit (seq, seq_signals[SEQ_COMPLETE], 0);
}
gboolean
@@ -399,12 +424,22 @@ meta_startup_sequence_get_wmclass (MetaStartupSequence *seq)
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
meta_startup_notification_add_sequence (MetaStartupNotification *sn,
MetaStartupSequence *seq)
{
sn->startup_sequences = g_slist_prepend (sn->startup_sequences,
g_object_ref (seq));
g_signal_connect (seq, "complete",
G_CALLBACK (on_sequence_completed), sn);
meta_startup_notification_ensure_timeout (sn);
meta_startup_notification_update_feedback (sn);
@@ -425,10 +460,10 @@ collect_timed_out_foreach (void *element,
meta_topic (META_DEBUG_STARTUP,
"Sequence used %" G_GINT64_FORMAT " ms vs. %d max: %s\n",
elapsed, STARTUP_TIMEOUT,
elapsed, STARTUP_TIMEOUT_MS,
meta_startup_sequence_get_id (sequence));
if (elapsed > STARTUP_TIMEOUT)
if (elapsed > STARTUP_TIMEOUT_MS)
ctod->list = g_slist_prepend (ctod->list, sequence);
}
@@ -440,7 +475,7 @@ startup_sequence_timeout (void *data)
GSList *l;
ctod.list = NULL;
ctod.now = g_get_monotonic_time ();
ctod.now = g_get_monotonic_time () / 1000;
g_slist_foreach (sn->startup_sequences,
collect_timed_out_foreach,
&ctod);
@@ -494,6 +529,8 @@ meta_startup_notification_remove_sequence (MetaStartupNotification *sn,
sn->startup_sequences = g_slist_remove (sn->startup_sequences, seq);
meta_startup_notification_update_feedback (sn);
g_signal_handlers_disconnect_by_func (seq, on_sequence_completed, sn);
if (sn->startup_sequences == NULL &&
sn->startup_sequence_timeout != 0)
{

View File

@@ -624,14 +624,14 @@ meta_xdg_output_manager_get_xdg_output (struct wl_client *client,
wl_resource_get_version (resource),
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);
if (!wayland_output)
return;
wl_resource_set_implementation (xdg_output_resource,
&meta_xdg_output_interface,
wayland_output, meta_xdg_output_destructor);
wayland_output->xdg_output_resources =
g_list_prepend (wayland_output->xdg_output_resources, xdg_output_resource);

View File

@@ -151,7 +151,7 @@ meta_startup_sequence_x11_new (SnStartupSequence *seq)
{
gint64 timestamp;
timestamp = sn_startup_sequence_get_timestamp (seq) * 1000;
timestamp = sn_startup_sequence_get_timestamp (seq);
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),