2008-01-13 01:10:12 +00:00
|
|
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
2006-10-01 22:30:10 +00:00
|
|
|
|
2014-05-02 13:34:02 +00:00
|
|
|
/*
|
2001-05-30 15:36:31 +00:00
|
|
|
* Copyright (C) 2001 Havoc Pennington
|
Fix bug 143333, support for update counter spec, and 109362, schedule
Sat Jun 19 02:21:08 2004 Soeren Sandmann <sandmann@daimi.au.dk>
Fix bug 143333, support for update counter spec, and 109362,
schedule compensation events when events are ignored.
* src/display.c (meta_display_open): Add _NET_WM_SYNC_REQUEST and
_NET_WM_SYNC_REQUEST_COUNTER atoms. Remove the old
METACITY_SYNC_COUNTER stuff.
(meta_display_begin_op): Setup the sync counter
* src/xprops.c, src/xprops.h, src/window-props.c, src/display.h:
Add new atoms.
* src/window.c (send_sync_request): new function.
(meta_window_move_resize_internal): send a sync request before
resizing.
(check_move_resize_frequence): Rework logic to also check the SYNC
case. If an event is ignored return the remaining time.
(update_resize_timeout): Timeout that gets called when a
compensation event is scheduled.
(uddate_resize): schedule compensation events when an event is
ignored.
(meta_window_handle_mouse_grap_op_event): When an alarm is
received and sync was turned off, turn it back on.
* src/window.h (struct MetaWindow) Add some variables
2004-06-19 00:45:24 +00:00
|
|
|
* Copyright (C) 2002, 2003, 2004 Red Hat, Inc.
|
2004-02-23 01:48:29 +00:00
|
|
|
* Copyright (C) 2003, 2004 Rob Adams
|
2006-01-10 19:43:21 +00:00
|
|
|
* Copyright (C) 2004-2006 Elijah Newren
|
2014-05-02 13:34:02 +00:00
|
|
|
*
|
2001-05-30 15:36:31 +00:00
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License as
|
|
|
|
* published by the Free Software Foundation; either version 2 of the
|
|
|
|
* License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful, but
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* General Public License for more details.
|
2014-05-02 13:34:02 +00:00
|
|
|
*
|
2001-05-30 15:36:31 +00:00
|
|
|
* You should have received a copy of the GNU General Public License
|
2014-01-12 01:42:06 +00:00
|
|
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
2001-05-30 15:36:31 +00:00
|
|
|
*/
|
|
|
|
|
2013-03-11 15:52:36 +00:00
|
|
|
/**
|
2023-03-28 14:35:11 +00:00
|
|
|
* MetaDisplay:
|
2023-05-23 18:25:54 +00:00
|
|
|
*
|
2023-03-28 14:35:11 +00:00
|
|
|
* Mutter display representation
|
2008-01-08 03:59:12 +00:00
|
|
|
*
|
2011-11-02 15:34:45 +00:00
|
|
|
* The display is represented as a #MetaDisplay struct.
|
2008-01-08 03:59:12 +00:00
|
|
|
*/
|
|
|
|
|
2018-07-10 08:36:24 +00:00
|
|
|
#include "config.h"
|
2012-02-10 15:27:14 +00:00
|
|
|
|
2018-07-10 08:36:24 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <unistd.h>
|
2001-05-30 15:36:31 +00:00
|
|
|
|
2019-10-24 19:19:36 +00:00
|
|
|
#include "backends/meta-backend-private.h"
|
2018-07-10 08:36:24 +00:00
|
|
|
#include "backends/meta-cursor-sprite-xcursor.h"
|
|
|
|
#include "backends/meta-cursor-tracker-private.h"
|
2022-04-27 08:50:43 +00:00
|
|
|
#include "backends/meta-input-capture.h"
|
2020-03-06 13:53:45 +00:00
|
|
|
#include "backends/meta-input-device-private.h"
|
2020-08-04 12:17:39 +00:00
|
|
|
#include "backends/meta-input-mapper-private.h"
|
2018-07-10 08:36:24 +00:00
|
|
|
#include "backends/meta-stage-private.h"
|
2019-05-24 19:36:50 +00:00
|
|
|
#include "compositor/compositor-private.h"
|
2020-02-17 17:32:35 +00:00
|
|
|
#include "cogl/cogl.h"
|
2018-07-10 08:36:24 +00:00
|
|
|
#include "core/bell.h"
|
|
|
|
#include "core/boxes-private.h"
|
|
|
|
#include "core/display-private.h"
|
|
|
|
#include "core/events.h"
|
|
|
|
#include "core/frame.h"
|
|
|
|
#include "core/keybindings-private.h"
|
2018-11-19 18:57:15 +00:00
|
|
|
#include "core/meta-clipboard-manager.h"
|
2018-07-10 08:36:24 +00:00
|
|
|
#include "core/meta-workspace-manager-private.h"
|
|
|
|
#include "core/util-private.h"
|
|
|
|
#include "core/window-private.h"
|
|
|
|
#include "core/workspace-private.h"
|
|
|
|
#include "meta/compositor-mutter.h"
|
|
|
|
#include "meta/compositor.h"
|
|
|
|
#include "meta/main.h"
|
|
|
|
#include "meta/meta-backend.h"
|
|
|
|
#include "meta/meta-enum-types.h"
|
2018-12-09 11:44:20 +00:00
|
|
|
#include "meta/meta-sound-player.h"
|
2018-07-10 08:36:24 +00:00
|
|
|
#include "meta/prefs.h"
|
2022-05-31 09:57:37 +00:00
|
|
|
|
|
|
|
#ifdef HAVE_X11_CLIENT
|
|
|
|
#include "backends/x11/meta-backend-x11.h"
|
|
|
|
#include "backends/x11/meta-clutter-backend-x11.h"
|
|
|
|
#include "backends/x11/meta-event-x11.h"
|
|
|
|
#include "backends/x11/cm/meta-backend-x11-cm.h"
|
|
|
|
#include "backends/x11/nested/meta-backend-x11-nested.h"
|
|
|
|
#include "compositor/meta-compositor-x11.h"
|
|
|
|
#include "meta/meta-x11-errors.h"
|
2018-08-22 18:57:04 +00:00
|
|
|
#include "x11/meta-startup-notification-x11.h"
|
2018-07-10 08:36:24 +00:00
|
|
|
#include "x11/meta-x11-display-private.h"
|
2014-03-19 01:56:45 +00:00
|
|
|
#include "x11/window-x11.h"
|
|
|
|
#include "x11/xprops.h"
|
2022-05-31 09:57:37 +00:00
|
|
|
#endif
|
2014-03-19 01:56:45 +00:00
|
|
|
|
2014-08-14 00:19:35 +00:00
|
|
|
#ifdef HAVE_WAYLAND
|
2019-09-12 20:07:20 +00:00
|
|
|
#include "compositor/meta-compositor-native.h"
|
2019-08-19 08:24:17 +00:00
|
|
|
#include "compositor/meta-compositor-server.h"
|
2022-06-13 08:09:26 +00:00
|
|
|
#include "wayland/meta-wayland.h"
|
|
|
|
#include "wayland/meta-wayland-input-device.h"
|
|
|
|
#include "wayland/meta-wayland-private.h"
|
2016-06-22 17:10:13 +00:00
|
|
|
#include "wayland/meta-wayland-tablet-seat.h"
|
|
|
|
#include "wayland/meta-wayland-tablet-pad.h"
|
2022-06-13 08:09:26 +00:00
|
|
|
#include "wayland/meta-wayland-tablet-manager.h"
|
|
|
|
#include "wayland/meta-wayland-touch.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_XWAYLAND
|
|
|
|
#include "wayland/meta-xwayland-private.h"
|
2014-08-14 00:19:35 +00:00
|
|
|
#endif
|
2013-08-12 13:31:18 +00:00
|
|
|
|
2018-07-10 08:36:24 +00:00
|
|
|
#ifdef HAVE_NATIVE_BACKEND
|
|
|
|
#include "backends/native/meta-backend-native.h"
|
|
|
|
#endif
|
|
|
|
|
2014-02-15 16:33:12 +00:00
|
|
|
/*
|
|
|
|
* SECTION:pings
|
|
|
|
*
|
|
|
|
* Sometimes we want to see whether a window is responding,
|
|
|
|
* so we send it a "ping" message and see whether it sends us back a "pong"
|
|
|
|
* message within a reasonable time. Here we have a system which lets us
|
|
|
|
* nominate one function to be called if we get the pong in time and another
|
|
|
|
* function if we don't. The system is rather more complicated than it needs
|
|
|
|
* to be, since we only ever use it to destroy windows which are asked to
|
|
|
|
* close themselves and don't do so within a reasonable amount of time, and
|
|
|
|
* therefore we always use the same callbacks. It's possible that we might
|
|
|
|
* use it for other things in future, or on the other hand we might decide
|
|
|
|
* that we're never going to do so and simplify it a bit.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* MetaPingData:
|
|
|
|
*
|
|
|
|
* Describes a ping on a window. When we send a ping to a window, we build
|
|
|
|
* one of these structs, and it eventually gets passed to the timeout function
|
|
|
|
* or to the function which handles the response from the window. If the window
|
|
|
|
* does or doesn't respond to the ping, we use this information to deal with
|
|
|
|
* these facts; we have a handler function for each.
|
|
|
|
*/
|
|
|
|
typedef struct
|
|
|
|
{
|
2014-05-20 18:48:08 +00:00
|
|
|
MetaWindow *window;
|
|
|
|
guint32 serial;
|
|
|
|
guint ping_timeout_id;
|
2014-02-15 16:33:12 +00:00
|
|
|
} MetaPingData;
|
|
|
|
|
2022-05-13 21:04:56 +00:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
MetaDisplay *display;
|
|
|
|
int queue_idx;
|
|
|
|
} MetaQueueRunData;
|
|
|
|
|
2021-03-03 15:05:09 +00:00
|
|
|
typedef struct _MetaDisplayPrivate
|
|
|
|
{
|
|
|
|
MetaContext *context;
|
2022-01-28 23:49:50 +00:00
|
|
|
|
|
|
|
guint queue_later_ids[META_N_QUEUE_TYPES];
|
|
|
|
GList *queue_windows[META_N_QUEUE_TYPES];
|
2022-04-27 08:50:43 +00:00
|
|
|
|
|
|
|
gboolean enable_input_capture;
|
2021-03-03 15:05:09 +00:00
|
|
|
} MetaDisplayPrivate;
|
|
|
|
|
|
|
|
G_DEFINE_TYPE_WITH_PRIVATE (MetaDisplay, meta_display, G_TYPE_OBJECT)
|
2008-12-02 22:58:07 +00:00
|
|
|
|
2008-12-02 23:13:11 +00:00
|
|
|
/* Signals */
|
|
|
|
enum
|
|
|
|
{
|
2017-08-26 16:37:29 +00:00
|
|
|
CURSOR_UPDATED,
|
2019-09-11 20:26:49 +00:00
|
|
|
X11_DISPLAY_SETUP,
|
2018-06-30 06:55:48 +00:00
|
|
|
X11_DISPLAY_OPENED,
|
|
|
|
X11_DISPLAY_CLOSING,
|
2008-12-02 23:13:11 +00:00
|
|
|
OVERLAY_KEY,
|
2012-08-28 13:28:11 +00:00
|
|
|
ACCELERATOR_ACTIVATED,
|
2013-04-10 11:34:26 +00:00
|
|
|
MODIFIERS_ACCELERATOR_ACTIVATED,
|
2009-07-30 21:33:11 +00:00
|
|
|
FOCUS_WINDOW,
|
2009-10-13 14:34:34 +00:00
|
|
|
WINDOW_CREATED,
|
2009-10-28 17:19:24 +00:00
|
|
|
WINDOW_DEMANDS_ATTENTION,
|
2009-11-17 10:24:18 +00:00
|
|
|
WINDOW_MARKED_URGENT,
|
2012-02-10 15:27:14 +00:00
|
|
|
GRAB_OP_BEGIN,
|
|
|
|
GRAB_OP_END,
|
2014-05-08 22:35:49 +00:00
|
|
|
SHOW_RESTART_MESSAGE,
|
|
|
|
RESTART,
|
2014-12-30 01:20:07 +00:00
|
|
|
SHOW_RESIZE_POPUP,
|
2016-05-20 17:22:23 +00:00
|
|
|
GL_VIDEO_MEMORY_PURGED,
|
2016-06-22 17:14:35 +00:00
|
|
|
SHOW_PAD_OSD,
|
2016-12-28 11:03:29 +00:00
|
|
|
SHOW_OSD,
|
2016-12-28 12:00:18 +00:00
|
|
|
PAD_MODE_SWITCH,
|
2017-08-26 19:10:38 +00:00
|
|
|
WINDOW_ENTERED_MONITOR,
|
|
|
|
WINDOW_LEFT_MONITOR,
|
2017-08-26 19:39:46 +00:00
|
|
|
WORKSPACE_ADDED,
|
|
|
|
WORKSPACE_REMOVED,
|
|
|
|
WORKSPACE_SWITCHED,
|
2017-08-26 20:29:10 +00:00
|
|
|
ACTIVE_WORKSPACE_CHANGED,
|
2017-08-26 19:10:38 +00:00
|
|
|
IN_FULLSCREEN_CHANGED,
|
2017-08-26 20:29:10 +00:00
|
|
|
SHOWING_DESKTOP_CHANGED,
|
2017-08-26 17:03:51 +00:00
|
|
|
RESTACKED,
|
2017-08-26 19:10:38 +00:00
|
|
|
WORKAREAS_CHANGED,
|
2019-11-01 12:14:39 +00:00
|
|
|
CLOSING,
|
2019-07-19 22:22:13 +00:00
|
|
|
INIT_XSERVER,
|
2022-01-28 23:49:50 +00:00
|
|
|
WINDOW_VISIBILITY_UPDATED,
|
2008-12-02 23:13:11 +00:00
|
|
|
LAST_SIGNAL
|
|
|
|
};
|
|
|
|
|
2018-12-19 08:04:25 +00:00
|
|
|
enum
|
|
|
|
{
|
2009-07-30 21:33:11 +00:00
|
|
|
PROP_0,
|
|
|
|
|
2021-01-29 19:56:46 +00:00
|
|
|
PROP_COMPOSITOR_MODIFIERS,
|
2017-08-27 19:02:40 +00:00
|
|
|
PROP_FOCUS_WINDOW
|
2009-07-30 21:33:11 +00:00
|
|
|
};
|
|
|
|
|
2008-12-02 23:13:11 +00:00
|
|
|
static guint display_signals [LAST_SIGNAL] = { 0 };
|
|
|
|
|
2017-08-26 16:37:29 +00:00
|
|
|
static void on_monitors_changed_internal (MetaMonitorManager *monitor_manager,
|
|
|
|
MetaDisplay *display);
|
|
|
|
|
2002-10-07 23:14:40 +00:00
|
|
|
static void prefs_changed_callback (MetaPreference pref,
|
|
|
|
void *data);
|
2014-04-24 14:48:47 +00:00
|
|
|
|
2014-09-29 22:01:17 +00:00
|
|
|
static int mru_cmp (gconstpointer a,
|
|
|
|
gconstpointer b);
|
|
|
|
|
2021-08-02 16:22:46 +00:00
|
|
|
static void
|
|
|
|
meta_display_show_osd (MetaDisplay *display,
|
|
|
|
gint monitor_idx,
|
|
|
|
const gchar *icon_name,
|
|
|
|
const gchar *message);
|
|
|
|
|
2022-05-27 20:27:07 +00:00
|
|
|
static MetaBackend *
|
|
|
|
backend_from_display (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
MetaContext *context = meta_display_get_context (display);
|
|
|
|
|
|
|
|
return meta_context_get_backend (context);
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef HAVE_WAYLAND
|
|
|
|
static MetaWaylandCompositor *
|
|
|
|
wayland_compositor_from_display (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
MetaContext *context = meta_display_get_context (display);
|
|
|
|
|
|
|
|
return meta_context_get_wayland_compositor (context);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2009-07-30 21:33:11 +00:00
|
|
|
static void
|
|
|
|
meta_display_get_property(GObject *object,
|
|
|
|
guint prop_id,
|
|
|
|
GValue *value,
|
|
|
|
GParamSpec *pspec)
|
|
|
|
{
|
|
|
|
MetaDisplay *display = META_DISPLAY (object);
|
|
|
|
|
|
|
|
switch (prop_id)
|
|
|
|
{
|
2021-01-29 19:56:46 +00:00
|
|
|
case PROP_COMPOSITOR_MODIFIERS:
|
|
|
|
g_value_set_flags (value, meta_display_get_compositor_modifiers (display));
|
|
|
|
break;
|
2009-07-30 21:33:11 +00:00
|
|
|
case PROP_FOCUS_WINDOW:
|
|
|
|
g_value_set_object (value, display->focus_window);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
meta_display_set_property(GObject *object,
|
|
|
|
guint prop_id,
|
|
|
|
const GValue *value,
|
|
|
|
GParamSpec *pspec)
|
|
|
|
{
|
|
|
|
switch (prop_id)
|
|
|
|
{
|
|
|
|
default:
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-12-02 22:58:07 +00:00
|
|
|
static void
|
|
|
|
meta_display_class_init (MetaDisplayClass *klass)
|
|
|
|
{
|
2009-07-30 21:33:11 +00:00
|
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
|
|
|
|
|
|
object_class->get_property = meta_display_get_property;
|
|
|
|
object_class->set_property = meta_display_set_property;
|
|
|
|
|
2017-08-26 16:37:29 +00:00
|
|
|
display_signals[CURSOR_UPDATED] =
|
|
|
|
g_signal_new ("cursor-updated",
|
|
|
|
G_TYPE_FROM_CLASS (klass),
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
0,
|
|
|
|
NULL, NULL, NULL,
|
|
|
|
G_TYPE_NONE, 0);
|
|
|
|
|
2019-09-11 20:26:49 +00:00
|
|
|
display_signals[X11_DISPLAY_SETUP] =
|
|
|
|
g_signal_new ("x11-display-setup",
|
|
|
|
G_TYPE_FROM_CLASS (klass),
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
0,
|
|
|
|
NULL, NULL, NULL,
|
|
|
|
G_TYPE_NONE, 0);
|
|
|
|
|
2018-06-30 06:55:48 +00:00
|
|
|
display_signals[X11_DISPLAY_OPENED] =
|
|
|
|
g_signal_new ("x11-display-opened",
|
|
|
|
G_TYPE_FROM_CLASS (klass),
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
0,
|
|
|
|
NULL, NULL, NULL,
|
|
|
|
G_TYPE_NONE, 0);
|
|
|
|
|
|
|
|
display_signals[X11_DISPLAY_CLOSING] =
|
|
|
|
g_signal_new ("x11-display-closing",
|
|
|
|
G_TYPE_FROM_CLASS (klass),
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
0,
|
|
|
|
NULL, NULL, NULL,
|
|
|
|
G_TYPE_NONE, 0);
|
|
|
|
|
2008-12-02 23:13:11 +00:00
|
|
|
display_signals[OVERLAY_KEY] =
|
|
|
|
g_signal_new ("overlay-key",
|
|
|
|
G_TYPE_FROM_CLASS (klass),
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
0,
|
2011-10-18 22:06:14 +00:00
|
|
|
NULL, NULL, NULL,
|
2009-07-30 21:33:11 +00:00
|
|
|
G_TYPE_NONE, 0);
|
|
|
|
|
2012-08-28 13:28:11 +00:00
|
|
|
display_signals[ACCELERATOR_ACTIVATED] =
|
|
|
|
g_signal_new ("accelerator-activated",
|
|
|
|
G_TYPE_FROM_CLASS (klass),
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
0,
|
|
|
|
NULL, NULL, NULL,
|
2019-07-08 09:42:06 +00:00
|
|
|
G_TYPE_NONE, 3, G_TYPE_UINT, CLUTTER_TYPE_INPUT_DEVICE, G_TYPE_UINT);
|
2012-08-28 13:28:11 +00:00
|
|
|
|
2013-04-10 11:34:26 +00:00
|
|
|
/**
|
|
|
|
* MetaDisplay::modifiers-accelerator-activated:
|
|
|
|
* @display: the #MetaDisplay instance
|
|
|
|
*
|
|
|
|
* The ::modifiers-accelerator-activated signal will be emitted when
|
|
|
|
* a special modifiers-only keybinding is activated.
|
|
|
|
*
|
|
|
|
* Returns: %TRUE means that the keyboard device should remain
|
|
|
|
* frozen and %FALSE for the default behavior of unfreezing the
|
|
|
|
* keyboard.
|
|
|
|
*/
|
|
|
|
display_signals[MODIFIERS_ACCELERATOR_ACTIVATED] =
|
|
|
|
g_signal_new ("modifiers-accelerator-activated",
|
|
|
|
G_TYPE_FROM_CLASS (klass),
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
0,
|
|
|
|
g_signal_accumulator_first_wins, NULL, NULL,
|
|
|
|
G_TYPE_BOOLEAN, 0);
|
|
|
|
|
2009-10-13 14:34:34 +00:00
|
|
|
display_signals[WINDOW_CREATED] =
|
|
|
|
g_signal_new ("window-created",
|
|
|
|
G_TYPE_FROM_CLASS (klass),
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
0,
|
2011-10-18 22:06:14 +00:00
|
|
|
NULL, NULL, NULL,
|
2009-10-13 14:34:34 +00:00
|
|
|
G_TYPE_NONE, 1, META_TYPE_WINDOW);
|
|
|
|
|
2009-10-28 17:19:24 +00:00
|
|
|
display_signals[WINDOW_DEMANDS_ATTENTION] =
|
|
|
|
g_signal_new ("window-demands-attention",
|
|
|
|
G_TYPE_FROM_CLASS (klass),
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
0,
|
2011-10-18 22:06:14 +00:00
|
|
|
NULL, NULL, NULL,
|
2009-10-28 17:19:24 +00:00
|
|
|
G_TYPE_NONE, 1, META_TYPE_WINDOW);
|
2009-10-13 14:34:34 +00:00
|
|
|
|
2009-11-17 10:24:18 +00:00
|
|
|
display_signals[WINDOW_MARKED_URGENT] =
|
|
|
|
g_signal_new ("window-marked-urgent",
|
|
|
|
G_TYPE_FROM_CLASS (klass),
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
0,
|
2011-10-18 22:06:14 +00:00
|
|
|
NULL, NULL, NULL,
|
2009-11-17 10:24:18 +00:00
|
|
|
G_TYPE_NONE, 1,
|
|
|
|
META_TYPE_WINDOW);
|
|
|
|
|
2012-02-10 15:27:14 +00:00
|
|
|
display_signals[GRAB_OP_BEGIN] =
|
|
|
|
g_signal_new ("grab-op-begin",
|
|
|
|
G_TYPE_FROM_CLASS (klass),
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
0,
|
|
|
|
NULL, NULL, NULL,
|
2021-02-18 11:14:47 +00:00
|
|
|
G_TYPE_NONE, 2,
|
2012-02-10 15:27:14 +00:00
|
|
|
META_TYPE_WINDOW,
|
|
|
|
META_TYPE_GRAB_OP);
|
|
|
|
|
|
|
|
display_signals[GRAB_OP_END] =
|
|
|
|
g_signal_new ("grab-op-end",
|
|
|
|
G_TYPE_FROM_CLASS (klass),
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
0,
|
|
|
|
NULL, NULL, NULL,
|
2021-02-18 11:14:47 +00:00
|
|
|
G_TYPE_NONE, 2,
|
2012-02-10 15:27:14 +00:00
|
|
|
META_TYPE_WINDOW,
|
|
|
|
META_TYPE_GRAB_OP);
|
|
|
|
|
2014-05-08 22:35:49 +00:00
|
|
|
/**
|
|
|
|
* MetaDisplay::show-restart-message:
|
|
|
|
* @display: the #MetaDisplay instance
|
|
|
|
* @message: (allow-none): The message to display, or %NULL
|
|
|
|
* to clear a previous restart message.
|
|
|
|
*
|
2023-03-28 14:35:11 +00:00
|
|
|
* The signal will be emitted to indicate that the compositor
|
|
|
|
* should show a message during restart.
|
2023-05-23 18:25:54 +00:00
|
|
|
*
|
2023-03-28 14:35:11 +00:00
|
|
|
* This is emitted when [func@Meta.restart] is called, either by Mutter
|
|
|
|
* internally or by the embedding compositor. The message should be
|
2014-05-08 22:35:49 +00:00
|
|
|
* immediately added to the Clutter stage in its final form -
|
2023-03-28 14:35:11 +00:00
|
|
|
* [signal@Meta.Display::restart] will be emitted to exit the application and leave the
|
2014-05-08 22:35:49 +00:00
|
|
|
* stage contents frozen as soon as the the stage is painted again.
|
|
|
|
*
|
|
|
|
* On case of failure to restart, this signal will be emitted again
|
|
|
|
* with %NULL for @message.
|
|
|
|
*
|
|
|
|
* Returns: %TRUE means the message was added to the stage; %FALSE
|
|
|
|
* indicates that the compositor did not show the message.
|
|
|
|
*/
|
|
|
|
display_signals[SHOW_RESTART_MESSAGE] =
|
|
|
|
g_signal_new ("show-restart-message",
|
|
|
|
G_TYPE_FROM_CLASS (klass),
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
0,
|
|
|
|
g_signal_accumulator_true_handled,
|
|
|
|
NULL, NULL,
|
|
|
|
G_TYPE_BOOLEAN, 1,
|
|
|
|
G_TYPE_STRING);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* MetaDisplay::restart:
|
|
|
|
* @display: the #MetaDisplay instance
|
|
|
|
*
|
2023-03-28 14:35:11 +00:00
|
|
|
* The signal is emitted to indicate that compositor
|
|
|
|
* should reexec the process.
|
2023-05-23 18:25:54 +00:00
|
|
|
*
|
2023-03-28 14:35:11 +00:00
|
|
|
* This is emitted when [func@Meta.restart] is called,
|
|
|
|
* either by Mutter internally or by the embedding compositor.
|
2023-05-23 18:25:54 +00:00
|
|
|
*
|
2023-03-28 14:35:11 +00:00
|
|
|
* See also [signal@Meta.Display::show-restart-message].
|
2014-05-08 22:35:49 +00:00
|
|
|
*
|
|
|
|
* Returns: %FALSE to indicate that the compositor could not
|
|
|
|
* be restarted. When the compositor is restarted, the signal
|
|
|
|
* should not return.
|
|
|
|
*/
|
|
|
|
display_signals[RESTART] =
|
|
|
|
g_signal_new ("restart",
|
|
|
|
G_TYPE_FROM_CLASS (klass),
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
0,
|
|
|
|
g_signal_accumulator_true_handled,
|
|
|
|
NULL, NULL,
|
|
|
|
G_TYPE_BOOLEAN, 0);
|
|
|
|
|
2014-12-30 01:20:07 +00:00
|
|
|
display_signals[SHOW_RESIZE_POPUP] =
|
|
|
|
g_signal_new ("show-resize-popup",
|
|
|
|
G_TYPE_FROM_CLASS (klass),
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
0,
|
|
|
|
g_signal_accumulator_true_handled,
|
|
|
|
NULL, NULL,
|
|
|
|
G_TYPE_BOOLEAN, 4,
|
|
|
|
G_TYPE_BOOLEAN, META_TYPE_RECTANGLE, G_TYPE_INT, G_TYPE_INT);
|
|
|
|
|
2016-05-20 17:22:23 +00:00
|
|
|
display_signals[GL_VIDEO_MEMORY_PURGED] =
|
|
|
|
g_signal_new ("gl-video-memory-purged",
|
|
|
|
G_TYPE_FROM_CLASS (klass),
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
0,
|
|
|
|
NULL, NULL, NULL,
|
|
|
|
G_TYPE_NONE, 0);
|
|
|
|
|
2016-06-22 17:14:35 +00:00
|
|
|
/**
|
|
|
|
* MetaDisplay::show-pad-osd:
|
|
|
|
* @display: the #MetaDisplay instance
|
|
|
|
* @pad: the pad device
|
|
|
|
* @settings: the pad device settings
|
2016-06-22 17:17:40 +00:00
|
|
|
* @layout_path: path to the layout image
|
2016-06-22 17:14:35 +00:00
|
|
|
* @edition_mode: Whether the OSD should be shown in edition mode
|
2016-06-22 17:17:40 +00:00
|
|
|
* @monitor_idx: Monitor to show the OSD on
|
2016-06-22 17:14:35 +00:00
|
|
|
*
|
|
|
|
* Requests the pad button mapping OSD to be shown.
|
|
|
|
*
|
|
|
|
* Returns: (transfer none) (nullable): The OSD actor
|
|
|
|
*/
|
|
|
|
display_signals[SHOW_PAD_OSD] =
|
|
|
|
g_signal_new ("show-pad-osd",
|
|
|
|
G_TYPE_FROM_CLASS (klass),
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
0, NULL, NULL, NULL,
|
2016-06-22 17:17:40 +00:00
|
|
|
CLUTTER_TYPE_ACTOR, 5, CLUTTER_TYPE_INPUT_DEVICE,
|
|
|
|
G_TYPE_SETTINGS, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_INT);
|
2016-06-22 17:14:35 +00:00
|
|
|
|
2016-12-28 11:03:29 +00:00
|
|
|
display_signals[SHOW_OSD] =
|
|
|
|
g_signal_new ("show-osd",
|
|
|
|
G_TYPE_FROM_CLASS (klass),
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
0, NULL, NULL, NULL,
|
|
|
|
G_TYPE_NONE, 3, G_TYPE_INT, G_TYPE_STRING, G_TYPE_STRING);
|
|
|
|
|
2016-12-28 12:00:18 +00:00
|
|
|
display_signals[PAD_MODE_SWITCH] =
|
|
|
|
g_signal_new ("pad-mode-switch",
|
|
|
|
G_TYPE_FROM_CLASS (klass),
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
0, NULL, NULL, NULL,
|
|
|
|
G_TYPE_NONE, 3, CLUTTER_TYPE_INPUT_DEVICE,
|
|
|
|
G_TYPE_UINT, G_TYPE_UINT);
|
|
|
|
|
2017-08-26 19:10:38 +00:00
|
|
|
display_signals[WINDOW_ENTERED_MONITOR] =
|
|
|
|
g_signal_new ("window-entered-monitor",
|
|
|
|
G_TYPE_FROM_CLASS (klass),
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
0, NULL, NULL, NULL,
|
|
|
|
G_TYPE_NONE, 2,
|
|
|
|
G_TYPE_INT,
|
|
|
|
META_TYPE_WINDOW);
|
|
|
|
|
|
|
|
display_signals[WINDOW_LEFT_MONITOR] =
|
|
|
|
g_signal_new ("window-left-monitor",
|
|
|
|
G_TYPE_FROM_CLASS (klass),
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
0, NULL, NULL, NULL,
|
|
|
|
G_TYPE_NONE, 2,
|
|
|
|
G_TYPE_INT,
|
|
|
|
META_TYPE_WINDOW);
|
|
|
|
|
|
|
|
display_signals[IN_FULLSCREEN_CHANGED] =
|
|
|
|
g_signal_new ("in-fullscreen-changed",
|
|
|
|
G_TYPE_FROM_CLASS (klass),
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
0, NULL, NULL, NULL,
|
|
|
|
G_TYPE_NONE, 0);
|
|
|
|
|
2017-08-26 20:29:10 +00:00
|
|
|
display_signals[SHOWING_DESKTOP_CHANGED] =
|
|
|
|
g_signal_new ("showing-desktop-changed",
|
|
|
|
G_TYPE_FROM_CLASS (klass),
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
0,
|
|
|
|
NULL, NULL, NULL,
|
|
|
|
G_TYPE_NONE, 0);
|
|
|
|
|
2017-08-26 17:03:51 +00:00
|
|
|
display_signals[RESTACKED] =
|
|
|
|
g_signal_new ("restacked",
|
|
|
|
G_TYPE_FROM_CLASS (klass),
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
0, NULL, NULL, NULL,
|
|
|
|
G_TYPE_NONE, 0);
|
|
|
|
|
2017-08-26 19:10:38 +00:00
|
|
|
display_signals[WORKAREAS_CHANGED] =
|
|
|
|
g_signal_new ("workareas-changed",
|
|
|
|
G_TYPE_FROM_CLASS (klass),
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
0, NULL, NULL, NULL,
|
|
|
|
G_TYPE_NONE, 0);
|
2019-11-01 12:14:39 +00:00
|
|
|
display_signals[CLOSING] =
|
|
|
|
g_signal_new ("closing",
|
|
|
|
G_TYPE_FROM_CLASS (klass),
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
0, NULL, NULL, NULL,
|
|
|
|
G_TYPE_NONE, 0);
|
2017-08-26 19:10:38 +00:00
|
|
|
|
2019-07-19 22:22:13 +00:00
|
|
|
display_signals[INIT_XSERVER] =
|
|
|
|
g_signal_new ("init-xserver",
|
|
|
|
G_TYPE_FROM_CLASS (klass),
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
0, g_signal_accumulator_first_wins,
|
|
|
|
NULL, NULL,
|
|
|
|
G_TYPE_BOOLEAN, 1, G_TYPE_TASK);
|
|
|
|
|
2022-01-28 23:49:50 +00:00
|
|
|
display_signals[WINDOW_VISIBILITY_UPDATED] =
|
|
|
|
g_signal_new ("window-visibility-updated",
|
|
|
|
G_TYPE_FROM_CLASS (klass),
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
0, NULL, NULL, NULL,
|
|
|
|
G_TYPE_NONE, 3,
|
|
|
|
G_TYPE_POINTER,
|
|
|
|
G_TYPE_POINTER,
|
|
|
|
G_TYPE_POINTER);
|
|
|
|
|
2021-01-29 19:56:46 +00:00
|
|
|
g_object_class_install_property (object_class,
|
|
|
|
PROP_COMPOSITOR_MODIFIERS,
|
2023-06-28 12:02:43 +00:00
|
|
|
g_param_spec_flags ("compositor-modifiers", NULL, NULL,
|
2021-01-29 19:56:46 +00:00
|
|
|
CLUTTER_TYPE_MODIFIER_TYPE,
|
|
|
|
0,
|
|
|
|
G_PARAM_READABLE));
|
|
|
|
|
2009-07-30 21:33:11 +00:00
|
|
|
g_object_class_install_property (object_class,
|
|
|
|
PROP_FOCUS_WINDOW,
|
2023-06-28 12:02:43 +00:00
|
|
|
g_param_spec_object ("focus-window", NULL, NULL,
|
2009-07-30 21:33:11 +00:00
|
|
|
META_TYPE_WINDOW,
|
|
|
|
G_PARAM_READABLE));
|
2017-08-26 19:39:46 +00:00
|
|
|
|
2008-12-02 22:58:07 +00:00
|
|
|
}
|
|
|
|
|
2014-02-15 16:33:12 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* ping_data_free:
|
|
|
|
*
|
|
|
|
* Destructor for #MetaPingData structs. Will destroy the
|
|
|
|
* event source for the struct as well.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
ping_data_free (MetaPingData *ping_data)
|
|
|
|
{
|
|
|
|
/* Remove the timeout */
|
2019-11-21 23:25:30 +00:00
|
|
|
g_clear_handle_id (&ping_data->ping_timeout_id, g_source_remove);
|
2014-02-15 16:33:12 +00:00
|
|
|
|
|
|
|
g_free (ping_data);
|
|
|
|
}
|
|
|
|
|
2014-07-08 16:16:11 +00:00
|
|
|
void
|
|
|
|
meta_display_remove_pending_pings_for_window (MetaDisplay *display,
|
|
|
|
MetaWindow *window)
|
2014-02-15 16:33:12 +00:00
|
|
|
{
|
|
|
|
GSList *tmp;
|
|
|
|
GSList *dead;
|
|
|
|
|
|
|
|
/* could obviously be more efficient, don't care */
|
|
|
|
|
|
|
|
/* build list to be removed */
|
|
|
|
dead = NULL;
|
|
|
|
for (tmp = display->pending_pings; tmp; tmp = tmp->next)
|
|
|
|
{
|
|
|
|
MetaPingData *ping_data = tmp->data;
|
|
|
|
|
2014-07-08 16:16:11 +00:00
|
|
|
if (ping_data->window == window)
|
2014-02-15 16:33:12 +00:00
|
|
|
dead = g_slist_prepend (dead, ping_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* remove what we found */
|
|
|
|
for (tmp = dead; tmp; tmp = tmp->next)
|
|
|
|
{
|
|
|
|
MetaPingData *ping_data = tmp->data;
|
|
|
|
|
|
|
|
display->pending_pings = g_slist_remove (display->pending_pings, ping_data);
|
|
|
|
ping_data_free (ping_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_slist_free (dead);
|
|
|
|
}
|
|
|
|
|
2019-08-19 08:24:17 +00:00
|
|
|
static MetaCompositor *
|
|
|
|
create_compositor (MetaDisplay *display)
|
|
|
|
{
|
2022-05-27 20:27:07 +00:00
|
|
|
MetaBackend *backend = backend_from_display (display);
|
2019-09-12 20:07:20 +00:00
|
|
|
|
2020-04-16 17:14:21 +00:00
|
|
|
#ifdef HAVE_WAYLAND
|
2019-09-12 20:07:20 +00:00
|
|
|
#ifdef HAVE_NATIVE_BACKEND
|
|
|
|
if (META_IS_BACKEND_NATIVE (backend))
|
2020-04-16 17:14:21 +00:00
|
|
|
return META_COMPOSITOR (meta_compositor_native_new (display, backend));
|
2019-09-12 20:07:20 +00:00
|
|
|
#endif
|
2022-05-31 09:57:37 +00:00
|
|
|
#ifdef HAVE_XWAYLAND
|
2019-09-12 20:07:20 +00:00
|
|
|
if (META_IS_BACKEND_X11_NESTED (backend))
|
2020-04-16 17:14:21 +00:00
|
|
|
return META_COMPOSITOR (meta_compositor_server_new (display, backend));
|
2019-08-19 08:24:17 +00:00
|
|
|
#endif
|
2022-05-31 09:57:37 +00:00
|
|
|
#endif/* HAVE_WAYLAND */
|
|
|
|
#ifdef HAVE_X11
|
2020-04-16 17:14:21 +00:00
|
|
|
return META_COMPOSITOR (meta_compositor_x11_new (display, backend));
|
2022-05-31 09:57:37 +00:00
|
|
|
#else
|
|
|
|
g_assert_not_reached ();
|
|
|
|
#endif
|
2019-08-19 08:24:17 +00:00
|
|
|
}
|
2014-02-15 16:33:12 +00:00
|
|
|
|
2008-12-02 22:58:07 +00:00
|
|
|
static void
|
2022-05-31 09:42:47 +00:00
|
|
|
meta_display_init (MetaDisplay *display)
|
2008-12-02 22:58:07 +00:00
|
|
|
{
|
|
|
|
/* Some stuff could go in here that's currently in _open,
|
|
|
|
* but it doesn't really matter. */
|
|
|
|
}
|
|
|
|
|
2014-07-22 00:07:19 +00:00
|
|
|
void
|
2014-07-22 00:07:19 +00:00
|
|
|
meta_display_cancel_touch (MetaDisplay *display)
|
|
|
|
{
|
2014-08-14 00:19:35 +00:00
|
|
|
#ifdef HAVE_WAYLAND
|
2014-07-22 00:07:19 +00:00
|
|
|
MetaWaylandCompositor *compositor;
|
|
|
|
|
|
|
|
if (!meta_is_wayland_compositor ())
|
|
|
|
return;
|
|
|
|
|
2022-05-27 20:27:07 +00:00
|
|
|
compositor = wayland_compositor_from_display (display);
|
2016-04-01 08:39:30 +00:00
|
|
|
meta_wayland_touch_cancel (compositor->seat->touch);
|
2014-08-14 00:19:35 +00:00
|
|
|
#endif
|
2014-07-22 00:07:19 +00:00
|
|
|
}
|
|
|
|
|
2014-06-19 21:13:38 +00:00
|
|
|
static void
|
|
|
|
gesture_tracker_state_changed (MetaGestureTracker *tracker,
|
|
|
|
ClutterEventSequence *sequence,
|
|
|
|
MetaSequenceState state,
|
|
|
|
MetaDisplay *display)
|
|
|
|
{
|
2019-10-24 19:19:36 +00:00
|
|
|
switch (state)
|
2014-07-21 23:46:42 +00:00
|
|
|
{
|
2019-10-24 19:19:36 +00:00
|
|
|
case META_SEQUENCE_NONE:
|
|
|
|
case META_SEQUENCE_PENDING_END:
|
|
|
|
return;
|
|
|
|
case META_SEQUENCE_ACCEPTED:
|
|
|
|
meta_display_cancel_touch (display);
|
|
|
|
|
2020-01-09 16:54:28 +00:00
|
|
|
G_GNUC_FALLTHROUGH;
|
2019-10-24 19:19:36 +00:00
|
|
|
case META_SEQUENCE_REJECTED:
|
|
|
|
{
|
|
|
|
MetaBackend *backend;
|
|
|
|
|
2022-05-27 20:27:07 +00:00
|
|
|
backend = backend_from_display (display);
|
2019-10-24 19:19:36 +00:00
|
|
|
meta_backend_finish_touch_sequence (backend, sequence, state);
|
|
|
|
break;
|
|
|
|
}
|
2014-07-21 23:46:42 +00:00
|
|
|
}
|
2014-06-19 21:13:38 +00:00
|
|
|
}
|
|
|
|
|
2018-07-06 17:22:26 +00:00
|
|
|
static void
|
|
|
|
on_ui_scaling_factor_changed (MetaSettings *settings,
|
|
|
|
MetaDisplay *display)
|
|
|
|
{
|
|
|
|
meta_display_reload_cursor (display);
|
|
|
|
}
|
|
|
|
|
2021-08-02 16:22:46 +00:00
|
|
|
static void
|
|
|
|
on_monitor_privacy_screen_changed (MetaDisplay *display,
|
|
|
|
MetaLogicalMonitor *logical_monitor,
|
|
|
|
gboolean enabled)
|
|
|
|
{
|
|
|
|
meta_display_show_osd (display,
|
|
|
|
logical_monitor->number,
|
|
|
|
enabled ? "screen-privacy-symbolic"
|
|
|
|
: "screen-privacy-disabled-symbolic",
|
|
|
|
enabled ? _("Privacy Screen Enabled")
|
|
|
|
: _("Privacy Screen Disabled"));
|
|
|
|
}
|
|
|
|
|
2022-04-27 08:50:43 +00:00
|
|
|
gboolean
|
|
|
|
meta_display_process_captured_input (MetaDisplay *display,
|
|
|
|
const ClutterEvent *event)
|
|
|
|
{
|
|
|
|
MetaDisplayPrivate *priv = meta_display_get_instance_private (display);
|
|
|
|
MetaContext *context = priv->context;
|
|
|
|
MetaBackend *backend = meta_context_get_backend (context);
|
|
|
|
MetaInputCapture *input_capture = meta_backend_get_input_capture (backend);
|
|
|
|
|
|
|
|
if (!priv->enable_input_capture)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
/* Check for the cancel key combo, but let the event flow through, so
|
|
|
|
* that meta_input_capture_process_event() can account for all press
|
|
|
|
* and release events, even the one from the key combo itself.
|
|
|
|
*/
|
|
|
|
meta_display_process_keybinding_event (display,
|
|
|
|
"cancel-input-capture",
|
|
|
|
event);
|
|
|
|
|
|
|
|
return meta_input_capture_process_event (input_capture, event);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
meta_display_cancel_input_capture (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
MetaDisplayPrivate *priv = meta_display_get_instance_private (display);
|
|
|
|
MetaContext *context = priv->context;
|
|
|
|
MetaBackend *backend = meta_context_get_backend (context);
|
|
|
|
MetaInputCapture *input_capture = meta_backend_get_input_capture (backend);
|
|
|
|
|
|
|
|
meta_input_capture_notify_cancelled (input_capture);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
enable_input_capture (MetaInputCapture *input_capture,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
MetaDisplay *display = META_DISPLAY (user_data);
|
|
|
|
MetaDisplayPrivate *priv = meta_display_get_instance_private (display);
|
|
|
|
|
|
|
|
g_return_if_fail (!priv->enable_input_capture);
|
|
|
|
|
|
|
|
priv->enable_input_capture = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
disable_input_capture (MetaInputCapture *input_capture,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
MetaDisplay *display = META_DISPLAY (user_data);
|
|
|
|
MetaDisplayPrivate *priv = meta_display_get_instance_private (display);
|
|
|
|
|
|
|
|
g_return_if_fail (priv->enable_input_capture);
|
|
|
|
|
|
|
|
priv->enable_input_capture = FALSE;
|
|
|
|
}
|
|
|
|
|
2022-05-31 09:42:47 +00:00
|
|
|
#ifdef HAVE_X11_CLIENT
|
2019-11-19 16:32:27 +00:00
|
|
|
static gboolean
|
|
|
|
meta_display_init_x11_display (MetaDisplay *display,
|
|
|
|
GError **error)
|
|
|
|
{
|
|
|
|
MetaX11Display *x11_display;
|
|
|
|
|
|
|
|
x11_display = meta_x11_display_new (display, error);
|
|
|
|
if (!x11_display)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
display->x11_display = x11_display;
|
|
|
|
g_signal_emit (display, display_signals[X11_DISPLAY_SETUP], 0);
|
|
|
|
|
|
|
|
meta_x11_display_create_guard_window (x11_display);
|
|
|
|
|
|
|
|
if (!display->display_opening)
|
2022-05-31 09:57:37 +00:00
|
|
|
g_signal_emit (display, display_signals[X11_DISPLAY_OPENED], 0);
|
2019-11-19 16:32:27 +00:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
2022-05-31 09:57:37 +00:00
|
|
|
#endif
|
2019-11-19 16:32:27 +00:00
|
|
|
|
2022-05-31 09:57:37 +00:00
|
|
|
#ifdef HAVE_XWAYLAND
|
2018-12-10 12:40:54 +00:00
|
|
|
gboolean
|
2019-11-19 16:32:27 +00:00
|
|
|
meta_display_init_x11_finish (MetaDisplay *display,
|
|
|
|
GAsyncResult *result,
|
|
|
|
GError **error)
|
2018-12-10 12:40:54 +00:00
|
|
|
{
|
|
|
|
MetaX11Display *x11_display;
|
|
|
|
|
2019-11-19 16:32:27 +00:00
|
|
|
g_assert (g_task_get_source_tag (G_TASK (result)) == meta_display_init_x11);
|
|
|
|
|
|
|
|
if (!g_task_propagate_boolean (G_TASK (result), error))
|
2020-03-02 14:49:07 +00:00
|
|
|
{
|
|
|
|
if (*error == NULL)
|
|
|
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Unknown error");
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2019-11-19 16:32:27 +00:00
|
|
|
if (display->x11_display)
|
|
|
|
return TRUE;
|
2018-12-10 12:40:54 +00:00
|
|
|
|
|
|
|
x11_display = meta_x11_display_new (display, error);
|
|
|
|
if (!x11_display)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
display->x11_display = x11_display;
|
2019-09-11 20:26:49 +00:00
|
|
|
g_signal_emit (display, display_signals[X11_DISPLAY_SETUP], 0);
|
2019-05-24 19:36:50 +00:00
|
|
|
|
2018-12-10 12:40:54 +00:00
|
|
|
meta_x11_display_create_guard_window (x11_display);
|
|
|
|
|
|
|
|
if (!display->display_opening)
|
2022-05-31 09:57:37 +00:00
|
|
|
g_signal_emit (display, display_signals[X11_DISPLAY_OPENED], 0);
|
2019-05-24 19:04:56 +00:00
|
|
|
|
2018-12-10 12:40:54 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2022-06-13 08:09:26 +00:00
|
|
|
#ifdef HAVE_XWAYLAND
|
2019-11-18 13:04:24 +00:00
|
|
|
static void
|
|
|
|
on_xserver_started (MetaXWaylandManager *manager,
|
|
|
|
GAsyncResult *result,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
g_autoptr (GTask) task = user_data;
|
2019-07-19 22:22:13 +00:00
|
|
|
MetaDisplay *display = g_task_get_source_object (task);
|
2019-11-18 13:04:24 +00:00
|
|
|
GError *error = NULL;
|
2019-07-19 22:22:13 +00:00
|
|
|
gboolean retval = FALSE;
|
2019-11-18 13:04:24 +00:00
|
|
|
|
2019-07-19 22:22:13 +00:00
|
|
|
if (!meta_xwayland_start_xserver_finish (manager, result, &error))
|
|
|
|
{
|
|
|
|
if (error)
|
|
|
|
g_task_return_error (task, error);
|
|
|
|
else
|
|
|
|
g_task_return_boolean (task, FALSE);
|
2019-11-18 13:04:24 +00:00
|
|
|
|
2019-07-19 22:22:13 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_signal_emit (display, display_signals[INIT_XSERVER], 0, task, &retval);
|
|
|
|
|
|
|
|
if (!retval)
|
|
|
|
{
|
|
|
|
/* No handlers for this signal, proceed right away */
|
|
|
|
g_task_return_boolean (task, TRUE);
|
|
|
|
}
|
2019-11-18 13:04:24 +00:00
|
|
|
}
|
2022-06-13 08:09:26 +00:00
|
|
|
#endif /* HAVE_XWAYLAND */
|
2019-11-18 13:04:24 +00:00
|
|
|
|
2019-11-19 16:32:27 +00:00
|
|
|
void
|
|
|
|
meta_display_init_x11 (MetaDisplay *display,
|
|
|
|
GCancellable *cancellable,
|
|
|
|
GAsyncReadyCallback callback,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
2019-11-18 13:04:24 +00:00
|
|
|
g_autoptr (GTask) task = NULL;
|
2022-06-13 08:09:26 +00:00
|
|
|
#ifdef HAVE_XWAYLAND
|
|
|
|
MetaWaylandCompositor *compositor;
|
|
|
|
#endif
|
2019-11-19 16:32:27 +00:00
|
|
|
|
|
|
|
task = g_task_new (display, cancellable, callback, user_data);
|
|
|
|
g_task_set_source_tag (task, meta_display_init_x11);
|
|
|
|
|
2022-06-13 08:09:26 +00:00
|
|
|
#ifdef HAVE_XWAYLAND
|
|
|
|
compositor = wayland_compositor_from_display (display);
|
|
|
|
|
2019-11-18 13:04:24 +00:00
|
|
|
meta_xwayland_start_xserver (&compositor->xwayland_manager,
|
|
|
|
cancellable,
|
|
|
|
(GAsyncReadyCallback) on_xserver_started,
|
|
|
|
g_steal_pointer (&task));
|
2022-06-13 08:09:26 +00:00
|
|
|
#endif
|
2019-11-19 16:32:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
on_x11_initialized (MetaDisplay *display,
|
|
|
|
GAsyncResult *result,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
2020-03-02 14:49:07 +00:00
|
|
|
g_autoptr (GError) error = NULL;
|
|
|
|
|
|
|
|
if (!meta_display_init_x11_finish (display, result, &error))
|
|
|
|
g_critical ("Failed to init X11 display: %s", error->message);
|
2019-11-19 16:32:27 +00:00
|
|
|
}
|
2022-05-31 09:57:37 +00:00
|
|
|
#endif /* HAVE_XWAYLAND */
|
2019-11-19 16:32:27 +00:00
|
|
|
|
2018-12-10 12:40:54 +00:00
|
|
|
void
|
|
|
|
meta_display_shutdown_x11 (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
if (!display->x11_display)
|
|
|
|
return;
|
|
|
|
|
2022-11-20 19:17:58 +00:00
|
|
|
meta_stack_freeze (display->stack);
|
2018-12-10 12:40:54 +00:00
|
|
|
g_signal_emit (display, display_signals[X11_DISPLAY_CLOSING], 0);
|
|
|
|
g_object_run_dispose (G_OBJECT (display->x11_display));
|
|
|
|
g_clear_object (&display->x11_display);
|
2022-11-20 19:17:58 +00:00
|
|
|
meta_stack_thaw (display->stack);
|
2018-12-10 12:40:54 +00:00
|
|
|
}
|
|
|
|
|
2021-03-03 14:12:19 +00:00
|
|
|
MetaDisplay *
|
2021-03-03 15:05:09 +00:00
|
|
|
meta_display_new (MetaContext *context,
|
|
|
|
GError **error)
|
2001-05-30 15:36:31 +00:00
|
|
|
{
|
2022-04-27 10:12:33 +00:00
|
|
|
MetaBackend *backend = meta_context_get_backend (context);
|
2014-07-10 21:58:58 +00:00
|
|
|
MetaDisplay *display;
|
2021-03-03 15:05:09 +00:00
|
|
|
MetaDisplayPrivate *priv;
|
Fix issues on 64-bit machines with timestamps by using guint32 (like gtk+
2006-09-13 Elijah Newren <newren gmail com>
* src/common.h (MetaWindowMenuFunc):
* src/core.[ch] (meta_core_user_lower_and_unfocus,
meta_core_user_focus, meta_core_show_window_menu,
meta_core_begin_grab_op, meta_core_end_grab_op):
* src/delete.c (delete_ping_reply_func, delete_ping_timeout_func,
meta_window_delete):
* src/display.[ch] (struct MetaDisplay, struct MetaPingData,
sanity_check_timestamps, meta_display_open, event_callback,
meta_spew_event, meta_display_set_grab_op_cursor,
meta_display_begin_grab_op, meta_display_end_grab_op,
meta_display_ping_timeout, meta_display_ping_window,
process_pong_message, timestamp_too_old,
meta_display_set_input_focus_window):
* src/keybindings.[ch] (grab_keyboard, ungrab_keyboard,
meta_screen_grab_all_keys, meta_window_grab_all_keys,
meta_window_ungrab_all_keys, error_on_generic_command,
error_on_command, error_on_terminal_command):
* src/metacity-dialog.c (on_realize, warn_about_no_sm_support,
error_about_command, main):
* src/screen.[ch] (struct _MetaScreen, meta_screen_new,
meta_screen_show_desktop, meta_screen_apply_startup_properties):
* src/session.c (warn_about_lame_clients_and_finish_interact):
* src/window.[ch] (struct _MetaWindow,
intervening_user_event_occurred, window_activate,
meta_window_delete, meta_window_focus,
meta_window_send_icccm_message, meta_window_client_message,
menu_callback, meta_window_show_menu, struct EventScannerData,
check_use_this_motion_notify, meta_window_begin_grab_op,
meta_window_set_user_time):
* src/workspace.[ch] (focus_ancestor_or_mru_window,
meta_workspace_activate_with_focus, meta_workspace_activate,
meta_workspace_focus_default_window,
focus_ancestor_or_mru_window):
Fix issues on 64-bit machines with timestamps by using guint32
(like gtk+ does) instead of Time. #348305
2006-09-13 16:32:33 +00:00
|
|
|
guint32 timestamp;
|
2022-05-31 09:57:37 +00:00
|
|
|
#ifdef HAVE_X11_CLIENT
|
2016-05-10 21:36:51 +00:00
|
|
|
Window old_active_xwindow = None;
|
2022-05-31 09:57:37 +00:00
|
|
|
#endif
|
2017-08-26 16:37:29 +00:00
|
|
|
MetaMonitorManager *monitor_manager;
|
2018-07-06 17:22:26 +00:00
|
|
|
MetaSettings *settings;
|
2022-04-27 08:50:43 +00:00
|
|
|
MetaInputCapture *input_capture;
|
2008-05-02 18:49:01 +00:00
|
|
|
|
2022-09-07 22:06:44 +00:00
|
|
|
display = g_object_new (META_TYPE_DISPLAY, NULL);
|
2001-06-03 01:33:27 +00:00
|
|
|
|
2021-03-03 15:05:09 +00:00
|
|
|
priv = meta_display_get_instance_private (display);
|
|
|
|
priv->context = context;
|
|
|
|
|
2014-07-10 21:58:58 +00:00
|
|
|
display->closing = 0;
|
|
|
|
display->display_opening = TRUE;
|
|
|
|
|
|
|
|
display->pending_pings = NULL;
|
|
|
|
display->autoraise_timeout_id = 0;
|
|
|
|
display->autoraise_window = NULL;
|
|
|
|
display->focus_window = NULL;
|
2017-08-27 18:52:42 +00:00
|
|
|
display->workspace_manager = NULL;
|
2017-08-26 16:24:46 +00:00
|
|
|
display->x11_display = NULL;
|
2014-07-10 21:58:58 +00:00
|
|
|
|
2017-08-26 16:37:29 +00:00
|
|
|
display->current_cursor = -1; /* invalid/unset */
|
2017-08-26 19:10:38 +00:00
|
|
|
display->check_fullscreen_later = 0;
|
|
|
|
display->work_area_later = 0;
|
2017-08-26 16:37:29 +00:00
|
|
|
|
2014-07-10 21:58:58 +00:00
|
|
|
display->mouse_mode = TRUE; /* Only relevant for mouse or sloppy focus */
|
2014-05-02 13:34:02 +00:00
|
|
|
|
2017-08-26 20:24:21 +00:00
|
|
|
display->current_time = META_CURRENT_TIME;
|
2017-08-26 16:24:46 +00:00
|
|
|
|
2014-07-10 21:58:58 +00:00
|
|
|
meta_display_init_keys (display);
|
2001-06-09 05:14:43 +00:00
|
|
|
|
2014-07-10 21:58:58 +00:00
|
|
|
meta_prefs_add_listener (prefs_changed_callback, display);
|
Merge compositor branch.
2007-12-18 Iain Holmes <iain@gnome.org>
* configure.in, src/theme.c, src/display.c,
src/theme.h, src/display.h, src/theme-parser.c,
src/compositor.c, src/c-screen.c, src/compositor.h,
src/c-screen.h, src/ui.c, src/screen.c, src/ui.h,
src/screen.h, src/c-window.c, src/c-window.h,
src/theme-viewer.c, src/Makefile.am: Merge compositor branch.
svn path=/trunk/; revision=3483
2007-12-19 03:49:50 +00:00
|
|
|
|
2017-08-26 16:24:46 +00:00
|
|
|
/* Get events */
|
|
|
|
meta_display_init_events (display);
|
|
|
|
|
|
|
|
display->stamps = g_hash_table_new (g_int64_hash,
|
|
|
|
g_int64_equal);
|
|
|
|
display->wayland_windows = g_hash_table_new (NULL, NULL);
|
|
|
|
|
2017-08-26 16:37:29 +00:00
|
|
|
monitor_manager = meta_backend_get_monitor_manager (backend);
|
|
|
|
g_signal_connect (monitor_manager, "monitors-changed-internal",
|
|
|
|
G_CALLBACK (on_monitors_changed_internal), display);
|
2021-08-02 16:22:46 +00:00
|
|
|
g_signal_connect_object (monitor_manager, "monitor-privacy-screen-changed",
|
|
|
|
G_CALLBACK (on_monitor_privacy_screen_changed),
|
|
|
|
display, G_CONNECT_SWAPPED);
|
2017-08-26 16:37:29 +00:00
|
|
|
|
2020-07-15 20:38:00 +00:00
|
|
|
display->pad_action_mapper = meta_pad_action_mapper_new (monitor_manager);
|
|
|
|
|
2022-04-27 08:50:43 +00:00
|
|
|
input_capture = meta_backend_get_input_capture (backend);
|
|
|
|
meta_input_capture_set_event_router (input_capture,
|
|
|
|
enable_input_capture,
|
|
|
|
disable_input_capture,
|
|
|
|
display);
|
|
|
|
|
2018-07-06 17:22:26 +00:00
|
|
|
settings = meta_backend_get_settings (backend);
|
|
|
|
g_signal_connect (settings, "ui-scaling-factor-changed",
|
|
|
|
G_CALLBACK (on_ui_scaling_factor_changed), display);
|
|
|
|
|
2020-03-03 08:27:33 +00:00
|
|
|
display->compositor = create_compositor (display);
|
|
|
|
|
2017-08-26 16:37:29 +00:00
|
|
|
meta_display_set_cursor (display, META_CURSOR_DEFAULT);
|
|
|
|
|
2017-08-26 20:43:28 +00:00
|
|
|
display->stack = meta_stack_new (display);
|
|
|
|
display->stack_tracker = meta_stack_tracker_new (display);
|
|
|
|
|
2017-08-27 18:52:42 +00:00
|
|
|
display->workspace_manager = meta_workspace_manager_new (display);
|
|
|
|
|
2018-08-22 20:51:26 +00:00
|
|
|
display->startup_notification = meta_startup_notification_new (display);
|
2017-08-26 20:35:18 +00:00
|
|
|
|
|
|
|
display->bell = meta_bell_new (display);
|
|
|
|
|
2018-11-19 17:15:24 +00:00
|
|
|
display->selection = meta_selection_new (display);
|
2018-11-19 18:57:15 +00:00
|
|
|
meta_clipboard_manager_init (display);
|
2018-11-19 17:15:24 +00:00
|
|
|
|
2019-11-19 16:32:27 +00:00
|
|
|
#ifdef HAVE_WAYLAND
|
|
|
|
if (meta_is_wayland_compositor ())
|
2017-08-27 18:44:58 +00:00
|
|
|
{
|
2022-06-01 08:35:29 +00:00
|
|
|
#ifdef HAVE_XWAYLAND
|
2021-03-23 15:47:45 +00:00
|
|
|
MetaWaylandCompositor *wayland_compositor =
|
2022-05-27 20:27:07 +00:00
|
|
|
wayland_compositor_from_display (display);
|
2022-05-31 09:42:47 +00:00
|
|
|
MetaX11DisplayPolicy x11_display_policy;
|
|
|
|
|
2023-05-15 18:33:11 +00:00
|
|
|
meta_xwayland_init_display (&wayland_compositor->xwayland_manager,
|
|
|
|
display);
|
|
|
|
|
2021-04-16 18:34:29 +00:00
|
|
|
x11_display_policy = meta_context_get_x11_display_policy (context);
|
|
|
|
if (x11_display_policy == META_X11_DISPLAY_POLICY_MANDATORY)
|
2019-11-19 16:32:27 +00:00
|
|
|
{
|
|
|
|
meta_display_init_x11 (display, NULL,
|
|
|
|
(GAsyncReadyCallback) on_x11_initialized,
|
|
|
|
NULL);
|
|
|
|
}
|
2022-05-31 09:42:47 +00:00
|
|
|
#endif /* HAVE_XWAYLAND */
|
2019-11-19 16:32:27 +00:00
|
|
|
timestamp = meta_display_get_current_time_roundtrip (display);
|
2017-08-27 18:44:58 +00:00
|
|
|
}
|
|
|
|
else
|
2022-05-31 09:42:47 +00:00
|
|
|
#endif /* HAVE_WAYLAND */
|
|
|
|
#ifdef HAVE_X11
|
2017-08-27 18:44:58 +00:00
|
|
|
{
|
2021-02-25 20:03:54 +00:00
|
|
|
if (!meta_display_init_x11_display (display, error))
|
|
|
|
{
|
|
|
|
g_object_unref (display);
|
2021-03-03 14:12:19 +00:00
|
|
|
return NULL;
|
2021-02-25 20:03:54 +00:00
|
|
|
}
|
2019-11-19 16:32:27 +00:00
|
|
|
|
|
|
|
timestamp = display->x11_display->timestamp;
|
2017-08-27 18:44:58 +00:00
|
|
|
}
|
2022-05-31 09:42:47 +00:00
|
|
|
#else
|
|
|
|
{
|
|
|
|
g_assert_not_reached ();
|
|
|
|
}
|
|
|
|
#endif
|
2017-08-26 16:24:46 +00:00
|
|
|
|
2014-07-10 21:58:58 +00:00
|
|
|
display->last_focus_time = timestamp;
|
|
|
|
display->last_user_time = timestamp;
|
2013-10-03 22:31:09 +00:00
|
|
|
|
2022-05-31 09:57:37 +00:00
|
|
|
#ifdef HAVE_X11
|
2016-05-10 21:36:51 +00:00
|
|
|
if (!meta_is_wayland_compositor ())
|
2017-08-26 18:51:28 +00:00
|
|
|
meta_prop_get_window (display->x11_display,
|
|
|
|
display->x11_display->xroot,
|
2017-08-26 16:26:30 +00:00
|
|
|
display->x11_display->atom__NET_ACTIVE_WINDOW,
|
2016-05-10 21:36:51 +00:00
|
|
|
&old_active_xwindow);
|
2022-05-31 09:57:37 +00:00
|
|
|
#endif
|
2016-05-10 21:36:51 +00:00
|
|
|
|
2021-02-25 20:03:54 +00:00
|
|
|
if (!meta_compositor_do_manage (display->compositor, error))
|
2020-03-03 08:27:33 +00:00
|
|
|
{
|
2021-02-25 20:03:54 +00:00
|
|
|
g_object_unref (display);
|
2021-03-03 14:12:19 +00:00
|
|
|
return NULL;
|
2020-03-03 08:27:33 +00:00
|
|
|
}
|
2006-01-13 19:41:01 +00:00
|
|
|
|
2022-05-31 09:57:37 +00:00
|
|
|
#ifdef HAVE_X11_CLIENT
|
2017-08-26 20:24:21 +00:00
|
|
|
if (display->x11_display)
|
2019-03-01 11:03:46 +00:00
|
|
|
{
|
2019-09-11 20:26:49 +00:00
|
|
|
g_signal_emit (display, display_signals[X11_DISPLAY_OPENED], 0);
|
2019-03-01 11:03:46 +00:00
|
|
|
meta_x11_display_restore_active_workspace (display->x11_display);
|
|
|
|
meta_x11_display_create_guard_window (display->x11_display);
|
|
|
|
}
|
2022-05-31 09:57:37 +00:00
|
|
|
#endif
|
2014-02-08 00:52:34 +00:00
|
|
|
|
2014-06-19 20:28:48 +00:00
|
|
|
/* Set up touch support */
|
2014-07-10 21:58:58 +00:00
|
|
|
display->gesture_tracker = meta_gesture_tracker_new ();
|
|
|
|
g_signal_connect (display->gesture_tracker, "state-changed",
|
|
|
|
G_CALLBACK (gesture_tracker_state_changed), display);
|
2014-06-19 20:28:48 +00:00
|
|
|
|
2014-02-08 00:52:34 +00:00
|
|
|
/* We know that if mutter is running as a Wayland compositor,
|
|
|
|
* we start out with no windows.
|
|
|
|
*/
|
2022-05-31 09:57:37 +00:00
|
|
|
#ifdef HAVE_X11_CLIENT
|
2014-02-08 00:52:34 +00:00
|
|
|
if (!meta_is_wayland_compositor ())
|
2019-05-25 10:00:47 +00:00
|
|
|
meta_display_manage_all_xwindows (display);
|
2002-07-24 15:41:44 +00:00
|
|
|
|
2016-05-10 21:36:51 +00:00
|
|
|
if (old_active_xwindow != None)
|
|
|
|
{
|
2017-08-26 16:56:44 +00:00
|
|
|
MetaWindow *old_active_window;
|
|
|
|
old_active_window = meta_x11_display_lookup_x_window (display->x11_display,
|
|
|
|
old_active_xwindow);
|
2016-05-10 21:36:51 +00:00
|
|
|
if (old_active_window)
|
|
|
|
meta_window_focus (old_active_window, timestamp);
|
|
|
|
else
|
2018-12-30 20:23:07 +00:00
|
|
|
meta_display_unset_input_focus (display, timestamp);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
meta_display_unset_input_focus (display, timestamp);
|
2016-05-10 21:36:51 +00:00
|
|
|
}
|
2022-05-31 09:57:37 +00:00
|
|
|
#else
|
|
|
|
meta_display_unset_input_focus (display, timestamp);
|
|
|
|
#endif
|
|
|
|
|
2013-08-14 11:51:05 +00:00
|
|
|
|
2018-12-09 11:44:20 +00:00
|
|
|
display->sound_player = g_object_new (META_TYPE_SOUND_PLAYER, NULL);
|
|
|
|
|
2006-10-01 21:59:09 +00:00
|
|
|
/* Done opening new display */
|
2014-07-10 21:58:58 +00:00
|
|
|
display->display_opening = FALSE;
|
2006-10-01 21:59:09 +00:00
|
|
|
|
2021-03-03 14:12:19 +00:00
|
|
|
return display;
|
2001-05-30 15:36:31 +00:00
|
|
|
}
|
|
|
|
|
2001-06-03 18:33:59 +00:00
|
|
|
static gint
|
|
|
|
ptrcmp (gconstpointer a, gconstpointer b)
|
|
|
|
{
|
|
|
|
if (a < b)
|
|
|
|
return -1;
|
|
|
|
else if (a > b)
|
|
|
|
return 1;
|
|
|
|
else
|
|
|
|
return 0;
|
2001-05-30 15:36:31 +00:00
|
|
|
}
|
|
|
|
|
2009-06-15 19:32:23 +00:00
|
|
|
/**
|
|
|
|
* meta_display_list_windows:
|
|
|
|
* @display: a #MetaDisplay
|
|
|
|
* @flags: options for listing
|
|
|
|
*
|
|
|
|
* Lists windows for the display, the @flags parameter for
|
|
|
|
* now determines whether override-redirect windows will be
|
|
|
|
* included.
|
|
|
|
*
|
|
|
|
* Return value: (transfer container): the list of windows.
|
|
|
|
*/
|
2001-06-24 08:09:10 +00:00
|
|
|
GSList*
|
2009-06-15 19:32:23 +00:00
|
|
|
meta_display_list_windows (MetaDisplay *display,
|
|
|
|
MetaListWindowsFlags flags)
|
2001-05-30 15:36:31 +00:00
|
|
|
{
|
2001-06-03 18:33:59 +00:00
|
|
|
GSList *winlist;
|
2001-06-24 08:09:10 +00:00
|
|
|
GSList *prev;
|
2013-10-03 22:31:09 +00:00
|
|
|
GSList *tmp;
|
2009-06-15 19:32:23 +00:00
|
|
|
GHashTableIter iter;
|
|
|
|
gpointer key, value;
|
|
|
|
|
2001-06-03 18:33:59 +00:00
|
|
|
winlist = NULL;
|
2009-06-15 19:32:23 +00:00
|
|
|
|
2022-05-31 09:57:37 +00:00
|
|
|
#ifdef HAVE_X11_CLIENT
|
2017-08-26 16:56:44 +00:00
|
|
|
if (display->x11_display)
|
2009-06-15 19:32:23 +00:00
|
|
|
{
|
2017-08-26 16:56:44 +00:00
|
|
|
g_hash_table_iter_init (&iter, display->x11_display->xids);
|
|
|
|
while (g_hash_table_iter_next (&iter, &key, &value))
|
|
|
|
{
|
|
|
|
MetaWindow *window = value;
|
2009-06-15 19:32:23 +00:00
|
|
|
|
2017-08-26 16:56:44 +00:00
|
|
|
if (!META_IS_WINDOW (window) || window->unmanaging)
|
|
|
|
continue;
|
2012-07-30 18:57:53 +00:00
|
|
|
|
2017-08-26 16:56:44 +00:00
|
|
|
if (!window->override_redirect ||
|
|
|
|
(flags & META_LIST_INCLUDE_OVERRIDE_REDIRECT) != 0)
|
|
|
|
winlist = g_slist_prepend (winlist, window);
|
|
|
|
}
|
2009-06-15 19:32:23 +00:00
|
|
|
}
|
2022-05-31 09:57:37 +00:00
|
|
|
#endif
|
2001-06-03 18:33:59 +00:00
|
|
|
|
2013-09-16 09:24:01 +00:00
|
|
|
g_hash_table_iter_init (&iter, display->wayland_windows);
|
|
|
|
while (g_hash_table_iter_next (&iter, &key, &value))
|
|
|
|
{
|
|
|
|
MetaWindow *window = value;
|
|
|
|
|
2014-10-07 15:13:15 +00:00
|
|
|
if (!META_IS_WINDOW (window) || window->unmanaging)
|
2013-09-16 09:24:01 +00:00
|
|
|
continue;
|
|
|
|
|
|
|
|
if (!window->override_redirect ||
|
|
|
|
(flags & META_LIST_INCLUDE_OVERRIDE_REDIRECT) != 0)
|
|
|
|
winlist = g_slist_prepend (winlist, window);
|
|
|
|
}
|
|
|
|
|
2001-06-24 08:09:10 +00:00
|
|
|
/* Uniquify the list, since both frame windows and plain
|
|
|
|
* windows are in the hash
|
|
|
|
*/
|
2001-06-03 18:33:59 +00:00
|
|
|
winlist = g_slist_sort (winlist, ptrcmp);
|
|
|
|
|
2001-06-24 08:09:10 +00:00
|
|
|
prev = NULL;
|
|
|
|
tmp = winlist;
|
|
|
|
while (tmp != NULL)
|
|
|
|
{
|
|
|
|
GSList *next;
|
|
|
|
|
|
|
|
next = tmp->next;
|
2014-05-02 13:34:02 +00:00
|
|
|
|
2001-06-24 08:09:10 +00:00
|
|
|
if (next &&
|
|
|
|
next->data == tmp->data)
|
|
|
|
{
|
|
|
|
/* Delete tmp from list */
|
|
|
|
|
|
|
|
if (prev)
|
|
|
|
prev->next = next;
|
|
|
|
|
|
|
|
if (tmp == winlist)
|
|
|
|
winlist = next;
|
2014-05-02 13:34:02 +00:00
|
|
|
|
2001-06-24 08:09:10 +00:00
|
|
|
g_slist_free_1 (tmp);
|
|
|
|
|
|
|
|
/* leave prev unchanged */
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
prev = tmp;
|
|
|
|
}
|
2014-05-02 13:34:02 +00:00
|
|
|
|
2001-06-24 08:09:10 +00:00
|
|
|
tmp = next;
|
|
|
|
}
|
|
|
|
|
2014-09-29 22:01:17 +00:00
|
|
|
if (flags & META_LIST_SORTED)
|
|
|
|
winlist = g_slist_sort (winlist, mru_cmp);
|
|
|
|
|
2001-06-24 08:09:10 +00:00
|
|
|
return winlist;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
Partial audit to fix timestamp usage. One step towards fixing #355180; see
2006-09-18 Elijah Newren <newren gmail com>
Partial audit to fix timestamp usage. One step towards fixing
#355180; see important comments in that bug.
* src/core.[ch] (meta_core_unshade, meta_core_shade):
* src/delete.c (meta_window_present_delete_dialog,
delete_ping_timeout_func):
* src/display.[ch] (meta_display_open, meta_display_close,
event_callback, meta_display_begin_grab_op,
process_selection_clear, meta_display_unmanage_screen,
meta_display_unmanage_windows_for_screen):
* src/frames.c (meta_frames_button_press_event):
* src/keybindings.c (handle_toggle_shade):
* src/main.c (main):
* src/screen.[ch] (update_num_workspaces, meta_screen_new,
meta_screen_free, prefs_changed_callback):
* src/window.[ch] (meta_window_free, finish_minimize,
implement_showing, meta_window_show, meta_window_maximize,
meta_window_make_fullscreen_internal,
meta_window_unmake_fullscreen, meta_window_shade,
meta_window_unshade, window_activate, send_sync_request,
meta_window_client_message, menu_callback,
meta_window_update_keyboard_resize):
Remove usage of CurrentTime, meta_display_get_current_time() and
meta_display_get_current_time_roundtrip() where possible, or
document why it isn't possible, or at very least add a FIXME with
some explanation of my laziness and what needs to be done.
2006-09-18 17:27:24 +00:00
|
|
|
meta_display_close (MetaDisplay *display,
|
|
|
|
guint32 timestamp)
|
2001-06-24 08:09:10 +00:00
|
|
|
{
|
2022-05-30 21:16:16 +00:00
|
|
|
MetaCompositor *compositor;
|
|
|
|
MetaLaters *laters;
|
MetaDisplay becomes a singleton. The static variable which holds this
2008-03-25 Thomas Thurman <tthurman@gnome.org>
* src/core/display.c (meta_display_queue_retheme_all_windows,
meta_set_syncing, meta_display_set_cursor_theme, disable_compositor,
meta_display_for_x_display, meta_display_open, meta_display_close,
meta_display_ungrab): MetaDisplay becomes a singleton. The static
variable which holds this singleton is renamed "the_display" so as
not to mask the this parameter in the methods.
* src/core/main.c (main):
* src/core/session.c (warn_about_lame_clients_and_finish_inte,
save_state, io_from_warning_dialog):
* src/core/core.c (meta_core_increment_event_serial):
* src/core/delete.c (release_window_with_fd, search_and_destroy_window):
sympathy changes for this, and consequent simplification.
Closes #499301.
svn path=/trunk/; revision=3663
2008-03-25 03:39:13 +00:00
|
|
|
|
2008-03-27 12:32:50 +00:00
|
|
|
if (display->closing != 0)
|
MetaDisplay becomes a singleton. The static variable which holds this
2008-03-25 Thomas Thurman <tthurman@gnome.org>
* src/core/display.c (meta_display_queue_retheme_all_windows,
meta_set_syncing, meta_display_set_cursor_theme, disable_compositor,
meta_display_for_x_display, meta_display_open, meta_display_close,
meta_display_ungrab): MetaDisplay becomes a singleton. The static
variable which holds this singleton is renamed "the_display" so as
not to mask the this parameter in the methods.
* src/core/main.c (main):
* src/core/session.c (warn_about_lame_clients_and_finish_inte,
save_state, io_from_warning_dialog):
* src/core/core.c (meta_core_increment_event_serial):
* src/core/delete.c (release_window_with_fd, search_and_destroy_window):
sympathy changes for this, and consequent simplification.
Closes #499301.
svn path=/trunk/; revision=3663
2008-03-25 03:39:13 +00:00
|
|
|
{
|
2008-03-27 12:32:50 +00:00
|
|
|
/* The display's already been closed. */
|
MetaDisplay becomes a singleton. The static variable which holds this
2008-03-25 Thomas Thurman <tthurman@gnome.org>
* src/core/display.c (meta_display_queue_retheme_all_windows,
meta_set_syncing, meta_display_set_cursor_theme, disable_compositor,
meta_display_for_x_display, meta_display_open, meta_display_close,
meta_display_ungrab): MetaDisplay becomes a singleton. The static
variable which holds this singleton is renamed "the_display" so as
not to mask the this parameter in the methods.
* src/core/main.c (main):
* src/core/session.c (warn_about_lame_clients_and_finish_inte,
save_state, io_from_warning_dialog):
* src/core/core.c (meta_core_increment_event_serial):
* src/core/delete.c (release_window_with_fd, search_and_destroy_window):
sympathy changes for this, and consequent simplification.
Closes #499301.
svn path=/trunk/; revision=3663
2008-03-25 03:39:13 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2002-06-22 05:11:04 +00:00
|
|
|
display->closing += 1;
|
2002-10-07 23:14:40 +00:00
|
|
|
|
2019-11-01 12:14:39 +00:00
|
|
|
g_signal_emit (display, display_signals[CLOSING], 0);
|
|
|
|
|
2018-06-29 10:44:17 +00:00
|
|
|
meta_display_unmanage_windows (display, timestamp);
|
display: Unmanage windows before compositor
Prior to 'compositor: Destroy actors when unmanaging', window actors
were destroyed when the compositor object was destroyed, long after the
windows were unmanaged, however, when this instead changed to happen
when unmanaging, with the original goal to avoid having these actors try
to interact with the disposed MetaCompositor instance, it caused an
issue where window actors would be indirectly destroyed as a side effect
of their parents being destroyed, which caused some fallout in the logic
handling window-close animation tracking, which relies on
meta_window_actor_queue_destroy() being called before a window actor is
actually destroyed.
Fix this by unmanaging windows before unmanaging the compositor.
From an X11 point of view, this should be harmless, since all it really
do is call XCompositeUnredirectSubwindows().
For the native backend and the common behavior, all unmanaging the
compositor instance does is destroy clutter actors, so doing so after
window actors were already cleaned up should not be a problem, as this
was the case before too.
Fixes: 35ac3a096d84de97c1da9a54d99aebf7640c1c07
Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/5330
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2403>
2022-05-06 15:49:50 +00:00
|
|
|
meta_compositor_unmanage (display->compositor);
|
2018-06-29 10:44:17 +00:00
|
|
|
|
2002-10-07 23:14:40 +00:00
|
|
|
meta_prefs_remove_listener (prefs_changed_callback, display);
|
2014-05-02 13:34:02 +00:00
|
|
|
|
2004-10-04 21:09:08 +00:00
|
|
|
meta_display_remove_autoraise_callback (display);
|
2005-01-24 05:58:30 +00:00
|
|
|
|
2014-06-19 21:13:38 +00:00
|
|
|
g_clear_object (&display->gesture_tracker);
|
|
|
|
|
2019-11-21 23:25:30 +00:00
|
|
|
g_clear_handle_id (&display->focus_timeout_id, g_source_remove);
|
2017-08-26 19:10:38 +00:00
|
|
|
|
2022-05-30 21:16:16 +00:00
|
|
|
compositor = meta_display_get_compositor (display);
|
|
|
|
laters = meta_compositor_get_laters (compositor);
|
2017-08-26 19:10:38 +00:00
|
|
|
if (display->work_area_later != 0)
|
2022-05-30 21:16:16 +00:00
|
|
|
meta_laters_remove (laters, display->work_area_later);
|
2017-08-26 19:10:38 +00:00
|
|
|
if (display->check_fullscreen_later != 0)
|
2022-05-30 21:16:16 +00:00
|
|
|
meta_laters_remove (laters, display->check_fullscreen_later);
|
2017-08-26 19:10:38 +00:00
|
|
|
|
2001-06-20 03:01:26 +00:00
|
|
|
/* Stop caring about events */
|
2014-03-20 19:29:30 +00:00
|
|
|
meta_display_free_events (display);
|
2014-05-02 13:34:02 +00:00
|
|
|
|
2019-06-04 09:47:06 +00:00
|
|
|
meta_display_shutdown_x11 (display);
|
|
|
|
|
|
|
|
g_clear_object (&display->stack);
|
|
|
|
g_clear_pointer (&display->stack_tracker,
|
|
|
|
meta_stack_tracker_free);
|
|
|
|
|
2022-05-30 21:15:01 +00:00
|
|
|
g_clear_pointer (&display->compositor, meta_compositor_destroy);
|
|
|
|
|
2008-11-07 09:57:00 +00:00
|
|
|
/* Must be after all calls to meta_window_unmanage() since they
|
2001-06-04 04:58:22 +00:00
|
|
|
* unregister windows
|
|
|
|
*/
|
2014-05-07 16:24:43 +00:00
|
|
|
g_hash_table_destroy (display->wayland_windows);
|
2017-11-06 19:38:43 +00:00
|
|
|
g_hash_table_destroy (display->stamps);
|
2001-06-09 21:58:30 +00:00
|
|
|
|
2017-08-26 16:24:46 +00:00
|
|
|
meta_display_shutdown_keys (display);
|
2014-05-02 13:34:02 +00:00
|
|
|
|
2017-08-26 20:35:18 +00:00
|
|
|
g_clear_object (&display->bell);
|
|
|
|
g_clear_object (&display->startup_notification);
|
2017-08-27 18:52:42 +00:00
|
|
|
g_clear_object (&display->workspace_manager);
|
2018-12-09 11:44:20 +00:00
|
|
|
g_clear_object (&display->sound_player);
|
2017-08-26 20:35:18 +00:00
|
|
|
|
2018-11-19 18:57:15 +00:00
|
|
|
meta_clipboard_manager_shutdown (display);
|
2020-01-30 08:54:02 +00:00
|
|
|
g_clear_object (&display->selection);
|
2020-07-15 20:38:00 +00:00
|
|
|
g_clear_object (&display->pad_action_mapper);
|
2001-05-31 06:42:58 +00:00
|
|
|
}
|
|
|
|
|
2014-04-20 15:41:22 +00:00
|
|
|
gboolean
|
2014-04-20 15:45:38 +00:00
|
|
|
meta_grab_op_is_mouse (MetaGrabOp op)
|
2006-08-21 18:38:21 +00:00
|
|
|
{
|
2014-08-15 18:05:04 +00:00
|
|
|
return (op & META_GRAB_OP_WINDOW_FLAG_KEYBOARD) == 0;
|
2006-08-21 18:38:21 +00:00
|
|
|
}
|
|
|
|
|
2014-03-20 19:29:30 +00:00
|
|
|
gboolean
|
|
|
|
meta_grab_op_is_keyboard (MetaGrabOp op)
|
2001-07-26 03:14:45 +00:00
|
|
|
{
|
2014-08-15 18:05:04 +00:00
|
|
|
return (op & META_GRAB_OP_WINDOW_FLAG_KEYBOARD) != 0;
|
2001-07-26 03:14:45 +00:00
|
|
|
}
|
|
|
|
|
2002-12-10 03:23:04 +00:00
|
|
|
gboolean
|
|
|
|
meta_grab_op_is_resizing (MetaGrabOp op)
|
|
|
|
{
|
2023-02-27 11:57:32 +00:00
|
|
|
return (op & META_GRAB_OP_WINDOW_DIR_MASK) != 0 ||
|
|
|
|
(op & META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN) ==
|
|
|
|
META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN;
|
2002-12-10 03:23:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
meta_grab_op_is_moving (MetaGrabOp op)
|
|
|
|
{
|
2015-01-20 16:09:31 +00:00
|
|
|
return !meta_grab_op_is_resizing (op);
|
2002-12-10 03:23:04 +00:00
|
|
|
}
|
|
|
|
|
2014-04-12 07:13:57 +00:00
|
|
|
/**
|
2016-03-10 15:48:45 +00:00
|
|
|
* meta_display_windows_are_interactable:
|
2014-04-12 07:13:57 +00:00
|
|
|
* @op: A #MetaGrabOp
|
|
|
|
*
|
2014-08-15 17:12:22 +00:00
|
|
|
* Whether windows can be interacted with.
|
2014-04-12 07:13:57 +00:00
|
|
|
*/
|
2014-03-17 19:53:19 +00:00
|
|
|
gboolean
|
2014-08-15 17:12:22 +00:00
|
|
|
meta_display_windows_are_interactable (MetaDisplay *display)
|
2014-03-17 19:53:19 +00:00
|
|
|
{
|
2022-05-27 20:27:07 +00:00
|
|
|
MetaBackend *backend = backend_from_display (display);
|
2022-12-09 17:40:47 +00:00
|
|
|
MetaStage *stage = META_STAGE (meta_backend_get_stage (backend));
|
|
|
|
|
|
|
|
if (clutter_stage_get_grab_actor (CLUTTER_STAGE (stage)))
|
|
|
|
return FALSE;
|
|
|
|
|
2022-10-21 10:56:24 +00:00
|
|
|
return TRUE;
|
2014-03-17 19:53:19 +00:00
|
|
|
}
|
|
|
|
|
2010-04-17 18:43:08 +00:00
|
|
|
/**
|
|
|
|
* meta_display_xserver_time_is_before:
|
|
|
|
* @display: a #MetaDisplay
|
|
|
|
* @time1: An event timestamp
|
|
|
|
* @time2: An event timestamp
|
|
|
|
*
|
|
|
|
* Xserver time can wraparound, thus comparing two timestamps needs to take
|
|
|
|
* this into account. If no wraparound has occurred, this is equivalent to
|
|
|
|
* time1 < time2
|
|
|
|
* Otherwise, we need to account for the fact that wraparound can occur
|
|
|
|
* and the fact that a timestamp of 0 must be special-cased since it
|
|
|
|
* means "older than anything else".
|
|
|
|
*
|
|
|
|
* Note that this is NOT an equivalent for time1 <= time2; if that's what
|
|
|
|
* you need then you'll need to swap the order of the arguments and negate
|
|
|
|
* the result.
|
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
meta_display_xserver_time_is_before (MetaDisplay *display,
|
|
|
|
guint32 time1,
|
|
|
|
guint32 time2)
|
|
|
|
{
|
|
|
|
return XSERVER_TIME_IS_BEFORE(time1, time2);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* meta_display_get_last_user_time:
|
|
|
|
* @display: a #MetaDisplay
|
|
|
|
*
|
|
|
|
* Returns: Timestamp of the last user interaction event with a window
|
|
|
|
*/
|
|
|
|
guint32
|
|
|
|
meta_display_get_last_user_time (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
return display->last_user_time;
|
|
|
|
}
|
|
|
|
|
2002-01-03 23:28:19 +00:00
|
|
|
/* Get time of current event, or CurrentTime if none. */
|
|
|
|
guint32
|
|
|
|
meta_display_get_current_time (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
return display->current_time;
|
|
|
|
}
|
|
|
|
|
Fix a variety of focus race conditions in all focus modes, or at least
2004-10-04 Elijah Newren <newren@math.utah.edu>
Fix a variety of focus race conditions in all focus modes, or at
least make them harder to trigger (fixes #152000)
* src/core.[ch] (meta_core_user_lower_and_unfocus): add a
timestamp parameter; pass it along to
meta_workspace_focus_default_window
* src/display.[ch] (meta_display_get_current_time_roundtrip): new
function
* src/display.c (event_callback): pass a timestamp to the
meta_workspace_activate and meta_workspace_focus_default_window
function calls
* src/frames.c (meta_frames_button_press_event): pass a timestamp
to meta_core_user_lower_and_unfocus
* src/keybindings.c (handle_activate_workspace): pass a timestamp
to meta_workspace_activate, (process_workspace_switch_grab): pass
a timestamp to meta_workspace_focus_default_window and
meta_workspace_activate, (handle_toggle_desktop): pass a timestamp
to meta_workspace_focus_default_window,
(do_handle_move_to_workspace): pass a timestamp to
meta_workspace_activate_with_focus, (handle_workspace_switch):
meta_workspace_activate
* src/screen.c (meta_screen_new): pass a timestamp to
meta_workspace_activate
* src/window.c (meta_window_free): pass a timestamp to
meta_workspace_focus_default_window, (idle_calc_showing): don't
increment the focus sentinel here, (meta_window_minimize): pass a
timestamp to meta_workspace_focus_default_window,
(meta_window_client_message), pass a timestamp to
meta_workspace_focus_default_window
* src/workspace.h (meta_workspace_activate): add timestamp
parameter, (meta_workspace_activate_with_focus): add timestamp
parameter, (meta_workspace_focus_default_window): add timestamp
parameter
* src/workspace.c (meta_workspace_focus_mru_window): make this
function take a timestamp and use it for meta_window_focus or
XSetInputFocus, (meta_workspace_activate_with_focus): make this
function take a timestamp and pass it along to meta_window_focus
and meta_workspace_focus_default_window,
(meta_workspace_activate): make this function take a timestamp and
pass it to meta_workspace_activate_with_focus),
(meta_workspace_focus_default_window): make this function take a
timestamp, warn if its 0 but try to handle that case sanely, and
pass the timestamp on to meta_window_focus or
meta_workspace_focus_mru_window or XSetInputFocus
2004-10-04 20:32:59 +00:00
|
|
|
guint32
|
|
|
|
meta_display_get_current_time_roundtrip (MetaDisplay *display)
|
|
|
|
{
|
2017-08-26 20:24:21 +00:00
|
|
|
if (meta_is_wayland_compositor ())
|
|
|
|
/* Xwayland uses monotonic clock, so lets use it here as well */
|
|
|
|
return (guint32) (g_get_monotonic_time () / 1000);
|
|
|
|
else
|
2022-05-31 09:57:37 +00:00
|
|
|
#ifdef HAVE_X11_CLIENT
|
2017-08-26 20:24:21 +00:00
|
|
|
return meta_x11_display_get_current_time_roundtrip (display->x11_display);
|
2022-05-31 09:57:37 +00:00
|
|
|
#else
|
|
|
|
g_assert_not_reached ();
|
|
|
|
#endif
|
Fix a variety of focus race conditions in all focus modes, or at least
2004-10-04 Elijah Newren <newren@math.utah.edu>
Fix a variety of focus race conditions in all focus modes, or at
least make them harder to trigger (fixes #152000)
* src/core.[ch] (meta_core_user_lower_and_unfocus): add a
timestamp parameter; pass it along to
meta_workspace_focus_default_window
* src/display.[ch] (meta_display_get_current_time_roundtrip): new
function
* src/display.c (event_callback): pass a timestamp to the
meta_workspace_activate and meta_workspace_focus_default_window
function calls
* src/frames.c (meta_frames_button_press_event): pass a timestamp
to meta_core_user_lower_and_unfocus
* src/keybindings.c (handle_activate_workspace): pass a timestamp
to meta_workspace_activate, (process_workspace_switch_grab): pass
a timestamp to meta_workspace_focus_default_window and
meta_workspace_activate, (handle_toggle_desktop): pass a timestamp
to meta_workspace_focus_default_window,
(do_handle_move_to_workspace): pass a timestamp to
meta_workspace_activate_with_focus, (handle_workspace_switch):
meta_workspace_activate
* src/screen.c (meta_screen_new): pass a timestamp to
meta_workspace_activate
* src/window.c (meta_window_free): pass a timestamp to
meta_workspace_focus_default_window, (idle_calc_showing): don't
increment the focus sentinel here, (meta_window_minimize): pass a
timestamp to meta_workspace_focus_default_window,
(meta_window_client_message), pass a timestamp to
meta_workspace_focus_default_window
* src/workspace.h (meta_workspace_activate): add timestamp
parameter, (meta_workspace_activate_with_focus): add timestamp
parameter, (meta_workspace_focus_default_window): add timestamp
parameter
* src/workspace.c (meta_workspace_focus_mru_window): make this
function take a timestamp and use it for meta_window_focus or
XSetInputFocus, (meta_workspace_activate_with_focus): make this
function take a timestamp and pass it along to meta_window_focus
and meta_workspace_focus_default_window,
(meta_workspace_activate): make this function take a timestamp and
pass it to meta_workspace_activate_with_focus),
(meta_workspace_focus_default_window): make this function take a
timestamp, warn if its 0 but try to handle that case sanely, and
pass the timestamp on to meta_window_focus or
meta_workspace_focus_mru_window or XSetInputFocus
2004-10-04 20:32:59 +00:00
|
|
|
}
|
|
|
|
|
2014-05-02 13:34:02 +00:00
|
|
|
static gboolean
|
2002-05-24 02:23:46 +00:00
|
|
|
window_raise_with_delay_callback (void *data)
|
|
|
|
{
|
2013-10-16 04:19:33 +00:00
|
|
|
MetaWindow *window = data;
|
2002-05-24 02:23:46 +00:00
|
|
|
|
2013-10-16 04:19:33 +00:00
|
|
|
window->display->autoraise_timeout_id = 0;
|
|
|
|
window->display->autoraise_window = NULL;
|
2002-05-24 02:23:46 +00:00
|
|
|
|
|
|
|
/* If we aren't already on top, check whether the pointer is inside
|
|
|
|
* the window and raise the window if so.
|
2014-05-02 13:34:02 +00:00
|
|
|
*/
|
2017-08-26 17:03:51 +00:00
|
|
|
if (meta_stack_get_top (window->display->stack) != window)
|
2002-05-24 02:23:46 +00:00
|
|
|
{
|
2014-06-12 21:01:13 +00:00
|
|
|
if (meta_window_has_pointer (window))
|
2002-05-24 02:23:46 +00:00
|
|
|
meta_window_raise (window);
|
|
|
|
else
|
2014-05-02 13:34:02 +00:00
|
|
|
meta_topic (META_DEBUG_FOCUS,
|
2020-10-02 15:47:22 +00:00
|
|
|
"Pointer not inside window, not raising %s",
|
2002-05-24 02:23:46 +00:00
|
|
|
window->desc);
|
|
|
|
}
|
|
|
|
|
2014-06-12 21:02:14 +00:00
|
|
|
return G_SOURCE_REMOVE;
|
2002-05-24 02:23:46 +00:00
|
|
|
}
|
|
|
|
|
2004-10-04 21:09:08 +00:00
|
|
|
void
|
|
|
|
meta_display_queue_autoraise_callback (MetaDisplay *display,
|
|
|
|
MetaWindow *window)
|
|
|
|
{
|
2014-05-02 13:34:02 +00:00
|
|
|
meta_topic (META_DEBUG_FOCUS,
|
2020-10-02 15:47:22 +00:00
|
|
|
"Queuing an autoraise timeout for %s with delay %d",
|
2014-05-02 13:34:02 +00:00
|
|
|
window->desc,
|
2004-10-04 21:09:08 +00:00
|
|
|
meta_prefs_get_auto_raise_delay ());
|
2014-05-02 13:34:02 +00:00
|
|
|
|
2019-11-21 23:25:30 +00:00
|
|
|
g_clear_handle_id (&display->autoraise_timeout_id, g_source_remove);
|
2004-10-04 21:09:08 +00:00
|
|
|
|
2014-05-02 13:34:02 +00:00
|
|
|
display->autoraise_timeout_id =
|
2004-10-04 21:09:08 +00:00
|
|
|
g_timeout_add_full (G_PRIORITY_DEFAULT,
|
|
|
|
meta_prefs_get_auto_raise_delay (),
|
|
|
|
window_raise_with_delay_callback,
|
2013-10-16 04:19:33 +00:00
|
|
|
window, NULL);
|
2014-04-10 16:58:58 +00:00
|
|
|
g_source_set_name_by_id (display->autoraise_timeout_id, "[mutter] window_raise_with_delay_callback");
|
2004-10-04 21:09:08 +00:00
|
|
|
display->autoraise_window = window;
|
|
|
|
}
|
|
|
|
|
2014-03-11 17:45:39 +00:00
|
|
|
void
|
|
|
|
meta_display_sync_wayland_input_focus (MetaDisplay *display)
|
|
|
|
{
|
2014-08-14 00:19:35 +00:00
|
|
|
#ifdef HAVE_WAYLAND
|
2022-05-27 20:27:07 +00:00
|
|
|
MetaWaylandCompositor *compositor = wayland_compositor_from_display (display);
|
2014-03-25 15:27:09 +00:00
|
|
|
MetaWindow *focus_window = NULL;
|
2022-05-27 20:27:07 +00:00
|
|
|
MetaBackend *backend = backend_from_display (display);
|
2020-12-22 17:00:44 +00:00
|
|
|
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
|
|
|
ClutterSeat *seat = clutter_backend_get_default_seat (clutter_backend);
|
2015-03-24 16:40:10 +00:00
|
|
|
MetaStage *stage = META_STAGE (meta_backend_get_stage (backend));
|
2019-04-14 15:15:06 +00:00
|
|
|
gboolean is_no_focus_xwindow = FALSE;
|
2017-08-26 20:24:21 +00:00
|
|
|
|
2022-05-31 09:57:37 +00:00
|
|
|
#ifdef HAVE_X11_CLIENT
|
2017-08-26 20:24:21 +00:00
|
|
|
if (display->x11_display)
|
2019-04-14 15:15:06 +00:00
|
|
|
is_no_focus_xwindow = meta_x11_display_xwindow_is_a_no_focus_window (display->x11_display,
|
|
|
|
display->x11_display->focus_xwindow);
|
2022-05-31 09:57:37 +00:00
|
|
|
#endif
|
2014-03-11 17:45:39 +00:00
|
|
|
|
2014-08-15 17:12:22 +00:00
|
|
|
if (!meta_display_windows_are_interactable (display))
|
2014-03-11 17:45:39 +00:00
|
|
|
focus_window = NULL;
|
2019-04-14 15:15:06 +00:00
|
|
|
else if (is_no_focus_xwindow)
|
2014-03-11 17:45:39 +00:00
|
|
|
focus_window = NULL;
|
2022-05-18 11:51:44 +00:00
|
|
|
else if (display->focus_window &&
|
|
|
|
meta_window_get_wayland_surface (display->focus_window))
|
2014-03-11 17:45:39 +00:00
|
|
|
focus_window = display->focus_window;
|
|
|
|
else
|
|
|
|
meta_topic (META_DEBUG_FOCUS, "Focus change has no effect, because there is no matching wayland surface");
|
|
|
|
|
|
|
|
meta_wayland_compositor_set_input_focus (compositor, focus_window);
|
|
|
|
|
2020-12-22 17:00:44 +00:00
|
|
|
clutter_stage_repick_device (CLUTTER_STAGE (stage),
|
|
|
|
clutter_seat_get_pointer (seat));
|
2014-08-14 00:19:35 +00:00
|
|
|
#endif
|
2014-03-11 17:45:39 +00:00
|
|
|
}
|
|
|
|
|
2021-08-05 19:00:22 +00:00
|
|
|
static void
|
|
|
|
meta_window_set_inactive_since (MetaWindow *window,
|
|
|
|
int64_t inactive_since_us)
|
|
|
|
{
|
|
|
|
GFile *file = NULL;
|
|
|
|
g_autoptr (GFileInfo) file_info = NULL;
|
|
|
|
g_autofree char *timestamp = NULL;
|
|
|
|
|
|
|
|
timestamp = g_strdup_printf ("%" G_GINT64_FORMAT, inactive_since_us);
|
|
|
|
|
|
|
|
file = meta_window_get_unit_cgroup (window);
|
|
|
|
if (!file)
|
|
|
|
return;
|
|
|
|
|
|
|
|
file_info = g_file_info_new ();
|
|
|
|
g_file_info_set_attribute_string (file_info,
|
|
|
|
"xattr::xdg.inactive-since", timestamp);
|
|
|
|
|
|
|
|
if (!g_file_set_attributes_from_info (file, file_info,
|
|
|
|
G_FILE_QUERY_INFO_NONE,
|
|
|
|
NULL, NULL))
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-03-20 19:29:30 +00:00
|
|
|
void
|
|
|
|
meta_display_update_focus_window (MetaDisplay *display,
|
2018-12-30 17:25:08 +00:00
|
|
|
MetaWindow *window)
|
2011-04-26 12:12:04 +00:00
|
|
|
{
|
2021-08-05 19:00:22 +00:00
|
|
|
MetaWindow *previous = NULL;
|
|
|
|
|
2018-12-30 17:25:08 +00:00
|
|
|
if (display->focus_window == window)
|
2011-04-26 12:12:04 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
if (display->focus_window)
|
|
|
|
{
|
|
|
|
meta_topic (META_DEBUG_FOCUS,
|
2020-10-02 15:47:22 +00:00
|
|
|
"%s is now the previous focus window due to being focused out or unmapped",
|
2011-04-26 12:12:04 +00:00
|
|
|
display->focus_window->desc);
|
|
|
|
|
|
|
|
/* Make sure that signals handlers invoked by
|
|
|
|
* meta_window_set_focused_internal() don't see
|
|
|
|
* display->focus_window->has_focus == FALSE
|
|
|
|
*/
|
|
|
|
previous = display->focus_window;
|
|
|
|
display->focus_window = NULL;
|
|
|
|
|
|
|
|
meta_window_set_focused_internal (previous, FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
display->focus_window = window;
|
|
|
|
|
|
|
|
if (display->focus_window)
|
|
|
|
{
|
2020-10-02 15:47:22 +00:00
|
|
|
meta_topic (META_DEBUG_FOCUS, "* Focus --> %s",
|
2018-12-30 17:25:08 +00:00
|
|
|
display->focus_window->desc);
|
2011-04-26 12:12:04 +00:00
|
|
|
meta_window_set_focused_internal (display->focus_window, TRUE);
|
|
|
|
}
|
|
|
|
else
|
2020-10-02 15:47:22 +00:00
|
|
|
meta_topic (META_DEBUG_FOCUS, "* Focus --> NULL");
|
2011-04-26 12:12:04 +00:00
|
|
|
|
2021-08-05 19:00:22 +00:00
|
|
|
if (!previous || !display->focus_window ||
|
|
|
|
!meta_window_unit_cgroup_equal (previous, display->focus_window))
|
|
|
|
{
|
|
|
|
if (previous)
|
|
|
|
meta_window_set_inactive_since (previous, g_get_monotonic_time ());
|
|
|
|
if (display->focus_window)
|
|
|
|
meta_window_set_inactive_since (display->focus_window, -1);
|
|
|
|
}
|
|
|
|
|
2013-08-12 16:04:34 +00:00
|
|
|
if (meta_is_wayland_compositor ())
|
2014-03-11 17:45:39 +00:00
|
|
|
meta_display_sync_wayland_input_focus (display);
|
2013-08-12 16:04:34 +00:00
|
|
|
|
2011-04-26 12:12:04 +00:00
|
|
|
g_object_notify (G_OBJECT (display), "focus-window");
|
|
|
|
}
|
|
|
|
|
2014-03-20 20:06:24 +00:00
|
|
|
gboolean
|
|
|
|
meta_display_timestamp_too_old (MetaDisplay *display,
|
|
|
|
guint32 *timestamp)
|
2013-05-23 19:54:39 +00:00
|
|
|
{
|
|
|
|
/* FIXME: If Soeren's suggestion in bug 151984 is implemented, it will allow
|
|
|
|
* us to sanity check the timestamp here and ensure it doesn't correspond to
|
|
|
|
* a future time (though we would want to rename to
|
|
|
|
* timestamp_too_old_or_in_future).
|
|
|
|
*/
|
|
|
|
|
2017-08-26 20:24:21 +00:00
|
|
|
if (*timestamp == META_CURRENT_TIME)
|
2013-05-23 19:54:39 +00:00
|
|
|
{
|
|
|
|
*timestamp = meta_display_get_current_time_roundtrip (display);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
else if (XSERVER_TIME_IS_BEFORE (*timestamp, display->last_focus_time))
|
|
|
|
{
|
|
|
|
if (XSERVER_TIME_IS_BEFORE (*timestamp, display->last_user_time))
|
|
|
|
return TRUE;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
*timestamp = display->last_focus_time;
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2018-12-30 20:23:07 +00:00
|
|
|
void
|
|
|
|
meta_display_set_input_focus (MetaDisplay *display,
|
|
|
|
MetaWindow *window,
|
|
|
|
gboolean focus_frame,
|
|
|
|
guint32 timestamp)
|
|
|
|
{
|
|
|
|
if (meta_display_timestamp_too_old (display, ×tamp))
|
|
|
|
return;
|
|
|
|
|
2022-05-31 09:57:37 +00:00
|
|
|
#ifdef HAVE_X11_CLIENT
|
2023-02-08 12:54:45 +00:00
|
|
|
if (display->x11_display)
|
2018-12-30 20:23:07 +00:00
|
|
|
{
|
2019-09-05 11:17:21 +00:00
|
|
|
meta_x11_display_set_input_focus (display->x11_display, window,
|
|
|
|
focus_frame, timestamp);
|
2018-12-30 20:23:07 +00:00
|
|
|
}
|
2022-05-31 09:57:37 +00:00
|
|
|
#endif
|
2018-12-30 20:23:07 +00:00
|
|
|
|
|
|
|
meta_display_update_focus_window (display, window);
|
|
|
|
|
|
|
|
display->last_focus_time = timestamp;
|
|
|
|
|
|
|
|
if (window == NULL || window != display->autoraise_window)
|
|
|
|
meta_display_remove_autoraise_callback (display);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
meta_display_unset_input_focus (MetaDisplay *display,
|
|
|
|
guint32 timestamp)
|
|
|
|
{
|
|
|
|
meta_display_set_input_focus (display, NULL, FALSE, timestamp);
|
|
|
|
}
|
|
|
|
|
2014-03-20 19:29:30 +00:00
|
|
|
void
|
|
|
|
meta_display_register_wayland_window (MetaDisplay *display,
|
|
|
|
MetaWindow *window)
|
2013-10-03 19:23:24 +00:00
|
|
|
{
|
2014-03-20 19:29:30 +00:00
|
|
|
g_hash_table_add (display->wayland_windows, window);
|
|
|
|
}
|
2013-10-03 19:23:24 +00:00
|
|
|
|
2014-03-20 19:29:30 +00:00
|
|
|
void
|
|
|
|
meta_display_unregister_wayland_window (MetaDisplay *display,
|
|
|
|
MetaWindow *window)
|
|
|
|
{
|
|
|
|
g_hash_table_remove (display->wayland_windows, window);
|
|
|
|
}
|
2013-10-03 19:23:24 +00:00
|
|
|
|
2014-09-09 01:20:14 +00:00
|
|
|
MetaWindow*
|
|
|
|
meta_display_lookup_stamp (MetaDisplay *display,
|
|
|
|
guint64 stamp)
|
|
|
|
{
|
|
|
|
return g_hash_table_lookup (display->stamps, &stamp);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
meta_display_register_stamp (MetaDisplay *display,
|
|
|
|
guint64 *stampp,
|
|
|
|
MetaWindow *window)
|
|
|
|
{
|
|
|
|
g_return_if_fail (g_hash_table_lookup (display->stamps, stampp) == NULL);
|
|
|
|
|
|
|
|
g_hash_table_insert (display->stamps, stampp, window);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
meta_display_unregister_stamp (MetaDisplay *display,
|
|
|
|
guint64 stamp)
|
|
|
|
{
|
|
|
|
g_return_if_fail (g_hash_table_lookup (display->stamps, &stamp) != NULL);
|
|
|
|
|
|
|
|
g_hash_table_remove (display->stamps, &stamp);
|
|
|
|
}
|
|
|
|
|
|
|
|
MetaWindow*
|
|
|
|
meta_display_lookup_stack_id (MetaDisplay *display,
|
|
|
|
guint64 stack_id)
|
|
|
|
{
|
2022-05-31 09:57:37 +00:00
|
|
|
#ifdef HAVE_X11_CLIENT
|
2014-09-09 01:20:14 +00:00
|
|
|
if (META_STACK_ID_IS_X11 (stack_id))
|
2019-08-15 11:59:01 +00:00
|
|
|
{
|
|
|
|
if (!display->x11_display)
|
|
|
|
return NULL;
|
|
|
|
return meta_x11_display_lookup_x_window (display->x11_display,
|
|
|
|
(Window)stack_id);
|
|
|
|
}
|
2022-05-31 09:57:37 +00:00
|
|
|
#endif
|
|
|
|
return meta_display_lookup_stamp (display, stack_id);
|
2014-09-09 01:20:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* We return a pointer into a ring of static buffers. This is to make
|
2020-08-26 09:49:50 +00:00
|
|
|
* using this function for debug-logging convenient and avoid temporary
|
2014-09-09 01:20:14 +00:00
|
|
|
* strings that must be freed. */
|
|
|
|
const char *
|
|
|
|
meta_display_describe_stack_id (MetaDisplay *display,
|
|
|
|
guint64 stack_id)
|
|
|
|
{
|
|
|
|
/* 0x<64-bit: 16 characters> (<10 characters of title>)\0' */
|
|
|
|
static char buffer[5][32];
|
|
|
|
MetaWindow *window;
|
|
|
|
static int pos = 0;
|
|
|
|
char *result;
|
|
|
|
|
|
|
|
result = buffer[pos];
|
|
|
|
pos = (pos + 1) % 5;
|
|
|
|
|
|
|
|
window = meta_display_lookup_stack_id (display, stack_id);
|
|
|
|
|
|
|
|
if (window && window->title)
|
|
|
|
snprintf (result, sizeof(buffer[0]), "%#" G_GINT64_MODIFIER "x (%.10s)", stack_id, window->title);
|
|
|
|
else
|
|
|
|
snprintf (result, sizeof(buffer[0]), "%#" G_GINT64_MODIFIER "x", stack_id);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2014-03-20 19:29:30 +00:00
|
|
|
void
|
|
|
|
meta_display_notify_window_created (MetaDisplay *display,
|
|
|
|
MetaWindow *window)
|
|
|
|
{
|
2019-08-29 17:34:18 +00:00
|
|
|
COGL_TRACE_BEGIN_SCOPED (MetaDisplayNotifyWindowCreated,
|
|
|
|
"Display (notify window created)");
|
2014-03-20 19:29:30 +00:00
|
|
|
g_signal_emit (display, display_signals[WINDOW_CREATED], 0, window);
|
|
|
|
}
|
2013-10-03 22:03:53 +00:00
|
|
|
|
2017-08-26 16:37:29 +00:00
|
|
|
static void
|
|
|
|
root_cursor_prepare_at (MetaCursorSpriteXcursor *sprite_xcursor,
|
2020-07-10 10:25:12 +00:00
|
|
|
float best_scale,
|
2017-08-26 16:37:29 +00:00
|
|
|
int x,
|
|
|
|
int y,
|
|
|
|
MetaDisplay *display)
|
|
|
|
{
|
|
|
|
MetaCursorSprite *cursor_sprite = META_CURSOR_SPRITE (sprite_xcursor);
|
2022-05-27 20:27:07 +00:00
|
|
|
MetaBackend *backend = backend_from_display (display);
|
2017-08-26 16:37:29 +00:00
|
|
|
|
2022-05-27 18:30:37 +00:00
|
|
|
if (meta_backend_is_stage_views_scaled (backend))
|
2017-08-26 16:37:29 +00:00
|
|
|
{
|
2020-07-10 10:25:12 +00:00
|
|
|
if (best_scale != 0.0f)
|
2017-08-26 16:37:29 +00:00
|
|
|
{
|
2017-10-20 10:00:06 +00:00
|
|
|
float ceiled_scale;
|
|
|
|
|
2020-07-10 10:25:12 +00:00
|
|
|
ceiled_scale = ceilf (best_scale);
|
2017-10-20 10:00:06 +00:00
|
|
|
meta_cursor_sprite_xcursor_set_theme_scale (sprite_xcursor,
|
|
|
|
(int) ceiled_scale);
|
|
|
|
meta_cursor_sprite_set_texture_scale (cursor_sprite,
|
|
|
|
1.0 / ceiled_scale);
|
2017-08-26 16:37:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
MetaMonitorManager *monitor_manager =
|
|
|
|
meta_backend_get_monitor_manager (backend);
|
|
|
|
MetaLogicalMonitor *logical_monitor;
|
|
|
|
|
|
|
|
logical_monitor =
|
|
|
|
meta_monitor_manager_get_logical_monitor_at (monitor_manager, x, y);
|
|
|
|
|
|
|
|
/* Reload the cursor texture if the scale has changed. */
|
|
|
|
if (logical_monitor)
|
|
|
|
{
|
|
|
|
meta_cursor_sprite_xcursor_set_theme_scale (sprite_xcursor,
|
|
|
|
logical_monitor->scale);
|
|
|
|
meta_cursor_sprite_set_texture_scale (cursor_sprite, 1.0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
manage_root_cursor_sprite_scale (MetaDisplay *display,
|
|
|
|
MetaCursorSpriteXcursor *sprite_xcursor)
|
|
|
|
{
|
2021-07-05 14:19:05 +00:00
|
|
|
meta_cursor_sprite_set_prepare_func (META_CURSOR_SPRITE (sprite_xcursor),
|
|
|
|
(MetaCursorPrepareFunc) root_cursor_prepare_at,
|
|
|
|
display);
|
2017-08-26 16:37:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
meta_display_reload_cursor (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
MetaCursor cursor = display->current_cursor;
|
|
|
|
MetaCursorSpriteXcursor *sprite_xcursor;
|
2022-05-27 20:27:07 +00:00
|
|
|
MetaBackend *backend = backend_from_display (display);
|
2017-08-26 16:37:29 +00:00
|
|
|
MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
|
|
|
|
|
2021-11-15 13:24:53 +00:00
|
|
|
sprite_xcursor = meta_cursor_sprite_xcursor_new (cursor, cursor_tracker);
|
2017-08-26 16:37:29 +00:00
|
|
|
|
|
|
|
if (meta_is_wayland_compositor ())
|
|
|
|
manage_root_cursor_sprite_scale (display, sprite_xcursor);
|
|
|
|
|
|
|
|
meta_cursor_tracker_set_root_cursor (cursor_tracker,
|
|
|
|
META_CURSOR_SPRITE (sprite_xcursor));
|
|
|
|
g_object_unref (sprite_xcursor);
|
|
|
|
|
|
|
|
g_signal_emit (display, display_signals[CURSOR_UPDATED], 0, display);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
meta_display_set_cursor (MetaDisplay *display,
|
|
|
|
MetaCursor cursor)
|
|
|
|
{
|
|
|
|
if (cursor == display->current_cursor)
|
|
|
|
return;
|
|
|
|
|
|
|
|
display->current_cursor = cursor;
|
|
|
|
meta_display_reload_cursor (display);
|
|
|
|
}
|
|
|
|
|
2009-08-28 15:25:51 +00:00
|
|
|
/**
|
2022-09-29 12:12:42 +00:00
|
|
|
* meta_display_is_grabbed:
|
2013-02-15 18:42:08 +00:00
|
|
|
* @display: The #MetaDisplay that the window is on
|
|
|
|
|
2022-09-29 12:12:42 +00:00
|
|
|
* Returns %TRUE if there is an ongoing grab operation.
|
2009-08-28 15:25:51 +00:00
|
|
|
*
|
2022-09-29 12:12:42 +00:00
|
|
|
* Return value: Whether there is an active display grab operation.
|
2009-08-28 15:25:51 +00:00
|
|
|
*/
|
2022-09-29 12:12:42 +00:00
|
|
|
gboolean
|
|
|
|
meta_display_is_grabbed (MetaDisplay *display)
|
2009-08-28 15:25:51 +00:00
|
|
|
{
|
2022-10-21 10:56:24 +00:00
|
|
|
return meta_compositor_get_current_window_drag (display->compositor) != NULL;
|
2009-08-28 15:25:51 +00:00
|
|
|
}
|
|
|
|
|
2002-02-07 03:25:34 +00:00
|
|
|
void
|
|
|
|
meta_display_queue_retheme_all_windows (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
GSList* windows;
|
|
|
|
GSList *tmp;
|
|
|
|
|
2009-06-15 19:32:23 +00:00
|
|
|
windows = meta_display_list_windows (display, META_LIST_DEFAULT);
|
2002-02-07 03:25:34 +00:00
|
|
|
tmp = windows;
|
|
|
|
while (tmp != NULL)
|
|
|
|
{
|
|
|
|
MetaWindow *window = tmp->data;
|
2014-05-02 13:34:02 +00:00
|
|
|
|
Refactor thrice-duplicated queue code in window.c. Closes #376760.
2007-06-10 Thomas Thurman <thomas@thurman.org.uk>
Refactor thrice-duplicated queue code in window.c. Closes #376760.
* src/window.c (meta_window_queue, meta_window_unqueue):
New functions.
* src/window.[ch] (meta_window_unqueue_*, meta_window_queue_*):
Removed functions.
* src/window.c (meta_window_new_with_attrs, meta_window_free,
meta_window_flush_calc_showing, queue_calc_showing_func,
meta_window_minimize, meta_window_unminimize, meta_window_maximize,
meta_window_make_fullscreen, meta_window_shade,
meta_window_unshade, meta_window_move_resize_internal,
window_stick_impl, window_unstick_impl,
meta_window_client_message, process_property_notify): Modified to
use new queueing functions.
* src/window.c (idle_move_resize, idle_update_icon,
idle_calc_showing): update to receive queue number from pointer.
* src/window.h (MetaQueueType): new enum.
* src/window.h (MetaWindow): *_queued replaced with is_in_queue
bitfield.
* src/core.c (meta_core_queue_frame_resize):
* src/display.c (event_callback,
meta_display_queue_retheme_all_windows): Using new queueing functions.
* src/frame.c (meta_window_destroy_frame): Using new queueing functions.
* src/screen.c (queue_resize, meta_screen_resize_func,
queue_windows_showing): Using new queueing functions.
* src/window-props.c (reload_mwm_hints, reload_wm_hints,
reload_transient_for): Using new queueing functions.
* src/workspace.c (meta_workspace_add_window,
meta_workspace_remove_window, meta_workspace_queue_calc_showing,
meta_workspace_invalidate_work_area): Using new queueing functions.
svn path=/trunk/; revision=3236
2007-06-11 01:15:33 +00:00
|
|
|
meta_window_queue (window, META_QUEUE_MOVE_RESIZE);
|
2013-11-15 22:37:50 +00:00
|
|
|
meta_window_frame_size_changed (window);
|
2014-05-02 13:34:02 +00:00
|
|
|
|
2002-02-07 03:25:34 +00:00
|
|
|
tmp = tmp->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_slist_free (windows);
|
|
|
|
}
|
|
|
|
|
2014-02-15 16:33:12 +00:00
|
|
|
/**
|
|
|
|
* meta_display_ping_timeout:
|
|
|
|
* @data: All the information about this ping. It is a #MetaPingData
|
|
|
|
* cast to a #gpointer in order to be passable to a timeout function.
|
|
|
|
* This function will also free this parameter.
|
|
|
|
*
|
|
|
|
* Does whatever it is we decided to do when a window didn't respond
|
|
|
|
* to a ping. We also remove the ping from the display's list of
|
|
|
|
* pending pings. This function is called by the event loop when the timeout
|
|
|
|
* times out which we created at the start of the ping.
|
|
|
|
*
|
|
|
|
* Returns: Always returns %FALSE, because this function is called as a
|
|
|
|
* timeout and we don't want to run the timer again.
|
|
|
|
*/
|
|
|
|
static gboolean
|
|
|
|
meta_display_ping_timeout (gpointer data)
|
|
|
|
{
|
|
|
|
MetaPingData *ping_data = data;
|
2014-05-20 18:48:08 +00:00
|
|
|
MetaWindow *window = ping_data->window;
|
|
|
|
MetaDisplay *display = window->display;
|
|
|
|
|
|
|
|
meta_window_set_alive (window, FALSE);
|
2021-09-03 21:38:12 +00:00
|
|
|
meta_window_show_close_dialog (window);
|
2014-02-15 16:33:12 +00:00
|
|
|
|
|
|
|
ping_data->ping_timeout_id = 0;
|
|
|
|
|
|
|
|
meta_topic (META_DEBUG_PING,
|
2020-10-02 15:47:22 +00:00
|
|
|
"Ping %u on window %s timed out",
|
2014-05-20 18:48:08 +00:00
|
|
|
ping_data->serial, ping_data->window->desc);
|
2014-02-15 16:33:12 +00:00
|
|
|
|
|
|
|
display->pending_pings = g_slist_remove (display->pending_pings, ping_data);
|
|
|
|
ping_data_free (ping_data);
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* meta_display_ping_window:
|
|
|
|
* @display: The #MetaDisplay that the window is on
|
|
|
|
* @window: The #MetaWindow to send the ping to
|
|
|
|
* @timestamp: The timestamp of the ping. Used for uniqueness.
|
|
|
|
* Cannot be CurrentTime; use a real timestamp!
|
|
|
|
*
|
|
|
|
* Sends a ping request to a window. The window must respond to
|
|
|
|
* the request within a certain amount of time. If it does, we
|
|
|
|
* will call one callback; if the time passes and we haven't had
|
|
|
|
* a response, we call a different callback. The window must have
|
|
|
|
* the hint showing that it can respond to a ping; if it doesn't,
|
|
|
|
* we call the "got a response" callback immediately and return.
|
|
|
|
* This function returns straight away after setting things up;
|
|
|
|
* the callbacks will be called from the event loop.
|
|
|
|
*/
|
|
|
|
void
|
2014-05-20 18:48:08 +00:00
|
|
|
meta_display_ping_window (MetaWindow *window,
|
2019-12-07 14:23:34 +00:00
|
|
|
guint32 serial)
|
2014-02-15 16:33:12 +00:00
|
|
|
{
|
2019-12-07 14:24:31 +00:00
|
|
|
GSList *l;
|
2014-02-15 16:33:12 +00:00
|
|
|
MetaDisplay *display = window->display;
|
|
|
|
MetaPingData *ping_data;
|
2020-02-21 20:03:16 +00:00
|
|
|
unsigned int check_alive_timeout;
|
|
|
|
|
|
|
|
check_alive_timeout = meta_prefs_get_check_alive_timeout ();
|
|
|
|
if (check_alive_timeout == 0)
|
|
|
|
return;
|
2014-02-15 16:33:12 +00:00
|
|
|
|
2014-05-20 18:48:08 +00:00
|
|
|
if (serial == 0)
|
2014-02-15 16:33:12 +00:00
|
|
|
{
|
2020-10-02 15:47:22 +00:00
|
|
|
meta_warning ("Tried to ping window %s with a bad serial! Not allowed.",
|
2019-12-07 14:23:34 +00:00
|
|
|
window->desc);
|
2014-02-15 16:33:12 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-01-30 19:41:11 +00:00
|
|
|
if (!meta_window_can_ping (window))
|
2014-05-20 18:48:08 +00:00
|
|
|
return;
|
2014-02-15 16:33:12 +00:00
|
|
|
|
2019-12-07 14:24:31 +00:00
|
|
|
for (l = display->pending_pings; l; l = l->next)
|
|
|
|
{
|
|
|
|
MetaPingData *ping_data = l->data;
|
|
|
|
|
2020-01-22 14:59:29 +00:00
|
|
|
if (window == ping_data->window)
|
|
|
|
{
|
|
|
|
meta_topic (META_DEBUG_PING,
|
2020-10-02 15:47:22 +00:00
|
|
|
"Window %s already is being pinged with serial %u",
|
2020-01-22 14:59:29 +00:00
|
|
|
window->desc, ping_data->serial);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-12-07 14:24:31 +00:00
|
|
|
if (serial == ping_data->serial)
|
|
|
|
{
|
|
|
|
meta_warning ("Ping serial %u was reused for window %s, "
|
2020-10-02 15:47:22 +00:00
|
|
|
"previous use was for window %s.",
|
2019-12-07 14:24:31 +00:00
|
|
|
serial, window->desc, ping_data->window->desc);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-15 16:33:12 +00:00
|
|
|
ping_data = g_new (MetaPingData, 1);
|
|
|
|
ping_data->window = window;
|
2014-05-20 18:48:08 +00:00
|
|
|
ping_data->serial = serial;
|
2020-02-21 20:03:16 +00:00
|
|
|
ping_data->ping_timeout_id =
|
|
|
|
g_timeout_add (check_alive_timeout,
|
|
|
|
meta_display_ping_timeout,
|
|
|
|
ping_data);
|
2014-04-10 16:58:58 +00:00
|
|
|
g_source_set_name_by_id (ping_data->ping_timeout_id, "[mutter] meta_display_ping_timeout");
|
2014-02-15 16:33:12 +00:00
|
|
|
|
|
|
|
display->pending_pings = g_slist_prepend (display->pending_pings, ping_data);
|
|
|
|
|
|
|
|
meta_topic (META_DEBUG_PING,
|
2020-10-02 15:47:22 +00:00
|
|
|
"Sending ping with serial %u to window %s",
|
2014-05-20 18:48:08 +00:00
|
|
|
serial, window->desc);
|
2014-02-15 16:33:12 +00:00
|
|
|
|
2014-05-20 18:48:08 +00:00
|
|
|
META_WINDOW_GET_CLASS (window)->ping (window, serial);
|
2021-09-03 21:38:12 +00:00
|
|
|
|
|
|
|
window->events_during_ping = 0;
|
2014-02-15 16:33:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* meta_display_pong_for_serial:
|
|
|
|
* @display: the display we got the pong from
|
2020-08-26 09:49:50 +00:00
|
|
|
* @serial: the serial in the pong response
|
2014-02-15 16:33:12 +00:00
|
|
|
*
|
|
|
|
* Process the pong (the response message) from the ping we sent
|
|
|
|
* to the window. This involves removing the timeout, calling the
|
|
|
|
* reply handler function, and freeing memory.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
meta_display_pong_for_serial (MetaDisplay *display,
|
|
|
|
guint32 serial)
|
|
|
|
{
|
|
|
|
GSList *tmp;
|
|
|
|
|
2020-10-02 15:47:22 +00:00
|
|
|
meta_topic (META_DEBUG_PING, "Received a pong with serial %u", serial);
|
2014-02-15 16:33:12 +00:00
|
|
|
|
|
|
|
for (tmp = display->pending_pings; tmp; tmp = tmp->next)
|
|
|
|
{
|
|
|
|
MetaPingData *ping_data = tmp->data;
|
|
|
|
|
2014-05-20 18:48:08 +00:00
|
|
|
if (serial == ping_data->serial)
|
2014-02-15 16:33:12 +00:00
|
|
|
{
|
|
|
|
meta_topic (META_DEBUG_PING,
|
2020-10-02 15:47:22 +00:00
|
|
|
"Matching ping found for pong %u",
|
2014-05-20 18:48:08 +00:00
|
|
|
ping_data->serial);
|
2014-02-15 16:33:12 +00:00
|
|
|
|
|
|
|
/* Remove the ping data from the list */
|
|
|
|
display->pending_pings = g_slist_remove (display->pending_pings,
|
|
|
|
ping_data);
|
|
|
|
|
|
|
|
/* Remove the timeout */
|
2019-11-21 23:25:30 +00:00
|
|
|
g_clear_handle_id (&ping_data->ping_timeout_id, g_source_remove);
|
2014-02-15 16:33:12 +00:00
|
|
|
|
2014-05-20 18:48:08 +00:00
|
|
|
meta_window_set_alive (ping_data->window, TRUE);
|
2014-02-15 16:33:12 +00:00
|
|
|
ping_data_free (ping_data);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-19 00:57:32 +00:00
|
|
|
static MetaGroup *
|
|
|
|
get_focused_group (MetaDisplay *display)
|
2006-04-15 02:05:44 +00:00
|
|
|
{
|
|
|
|
if (display->focus_window)
|
|
|
|
return display->focus_window->group;
|
|
|
|
else
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define IN_TAB_CHAIN(w,t) (((t) == META_TAB_LIST_NORMAL && META_WINDOW_IN_NORMAL_TAB_CHAIN (w)) \
|
|
|
|
|| ((t) == META_TAB_LIST_DOCKS && META_WINDOW_IN_DOCK_TAB_CHAIN (w)) \
|
2014-03-19 00:57:32 +00:00
|
|
|
|| ((t) == META_TAB_LIST_GROUP && META_WINDOW_IN_GROUP_TAB_CHAIN (w, get_focused_group (w->display))) \
|
2012-03-12 22:00:12 +00:00
|
|
|
|| ((t) == META_TAB_LIST_NORMAL_ALL && META_WINDOW_IN_NORMAL_TAB_CHAIN_TYPE (w)))
|
2002-04-05 15:52:49 +00:00
|
|
|
|
2002-03-12 04:34:17 +00:00
|
|
|
static MetaWindow*
|
|
|
|
find_tab_forward (MetaDisplay *display,
|
2002-04-05 15:52:49 +00:00
|
|
|
MetaTabList type,
|
2002-03-12 04:34:17 +00:00
|
|
|
MetaWorkspace *workspace,
|
2004-10-25 16:17:19 +00:00
|
|
|
GList *start,
|
|
|
|
gboolean skip_first)
|
2002-03-12 04:34:17 +00:00
|
|
|
{
|
|
|
|
GList *tmp;
|
|
|
|
|
|
|
|
g_return_val_if_fail (start != NULL, NULL);
|
2003-08-15 22:09:55 +00:00
|
|
|
g_return_val_if_fail (workspace != NULL, NULL);
|
2002-05-11 06:59:54 +00:00
|
|
|
|
2004-10-25 16:17:19 +00:00
|
|
|
tmp = start;
|
|
|
|
if (skip_first)
|
|
|
|
tmp = tmp->next;
|
|
|
|
|
2002-03-12 04:34:17 +00:00
|
|
|
while (tmp != NULL)
|
|
|
|
{
|
|
|
|
MetaWindow *window = tmp->data;
|
|
|
|
|
2013-10-03 22:31:09 +00:00
|
|
|
if (IN_TAB_CHAIN (window, type))
|
2002-03-12 04:34:17 +00:00
|
|
|
return window;
|
|
|
|
|
|
|
|
tmp = tmp->next;
|
|
|
|
}
|
|
|
|
|
2003-08-15 22:09:55 +00:00
|
|
|
tmp = workspace->mru_list;
|
2002-03-12 04:34:17 +00:00
|
|
|
while (tmp != start)
|
|
|
|
{
|
|
|
|
MetaWindow *window = tmp->data;
|
|
|
|
|
2003-08-15 22:09:55 +00:00
|
|
|
if (IN_TAB_CHAIN (window, type))
|
2002-03-12 04:34:17 +00:00
|
|
|
return window;
|
|
|
|
|
|
|
|
tmp = tmp->next;
|
2014-05-02 13:34:02 +00:00
|
|
|
}
|
2002-03-12 04:34:17 +00:00
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static MetaWindow*
|
|
|
|
find_tab_backward (MetaDisplay *display,
|
2002-04-05 15:52:49 +00:00
|
|
|
MetaTabList type,
|
2002-03-12 04:34:17 +00:00
|
|
|
MetaWorkspace *workspace,
|
2004-10-25 16:17:19 +00:00
|
|
|
GList *start,
|
|
|
|
gboolean skip_last)
|
2002-03-12 04:34:17 +00:00
|
|
|
{
|
|
|
|
GList *tmp;
|
|
|
|
|
|
|
|
g_return_val_if_fail (start != NULL, NULL);
|
2003-08-15 22:09:55 +00:00
|
|
|
g_return_val_if_fail (workspace != NULL, NULL);
|
2004-10-25 16:17:19 +00:00
|
|
|
|
|
|
|
tmp = start;
|
2014-05-02 13:34:02 +00:00
|
|
|
if (skip_last)
|
2004-10-25 16:17:19 +00:00
|
|
|
tmp = tmp->prev;
|
2002-03-12 04:34:17 +00:00
|
|
|
while (tmp != NULL)
|
|
|
|
{
|
|
|
|
MetaWindow *window = tmp->data;
|
|
|
|
|
2013-10-03 22:31:09 +00:00
|
|
|
if (IN_TAB_CHAIN (window, type))
|
2002-03-12 04:34:17 +00:00
|
|
|
return window;
|
|
|
|
|
|
|
|
tmp = tmp->prev;
|
|
|
|
}
|
|
|
|
|
2003-08-15 22:09:55 +00:00
|
|
|
tmp = g_list_last (workspace->mru_list);
|
2002-03-12 04:34:17 +00:00
|
|
|
while (tmp != start)
|
|
|
|
{
|
|
|
|
MetaWindow *window = tmp->data;
|
|
|
|
|
2003-08-15 22:09:55 +00:00
|
|
|
if (IN_TAB_CHAIN (window, type))
|
2002-03-12 04:34:17 +00:00
|
|
|
return window;
|
|
|
|
|
|
|
|
tmp = tmp->prev;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2012-12-03 16:59:11 +00:00
|
|
|
static int
|
|
|
|
mru_cmp (gconstpointer a,
|
|
|
|
gconstpointer b)
|
|
|
|
{
|
|
|
|
guint32 time_a, time_b;
|
|
|
|
|
|
|
|
time_a = meta_window_get_user_time ((MetaWindow *)a);
|
|
|
|
time_b = meta_window_get_user_time ((MetaWindow *)b);
|
|
|
|
|
|
|
|
if (time_a > time_b)
|
|
|
|
return -1;
|
|
|
|
else if (time_a < time_b)
|
|
|
|
return 1;
|
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-12-15 18:02:24 +00:00
|
|
|
/**
|
|
|
|
* meta_display_list_all_windows:
|
|
|
|
* @display: a #MetaDisplay
|
|
|
|
*
|
|
|
|
* List all windows, including override-redirect ones. The windows are
|
|
|
|
* in no particular order.
|
|
|
|
*
|
|
|
|
* Returns: (transfer container) (element-type Meta.Window): List of windows
|
|
|
|
*/
|
|
|
|
GList *
|
|
|
|
meta_display_list_all_windows (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
GList *all_windows = NULL;
|
|
|
|
g_autoptr (GSList) windows = NULL;
|
|
|
|
GSList *l;
|
|
|
|
|
|
|
|
windows = meta_display_list_windows (display,
|
|
|
|
META_LIST_INCLUDE_OVERRIDE_REDIRECT);
|
|
|
|
|
|
|
|
/* Yay for mixing GList and GSList in the API */
|
|
|
|
for (l = windows; l; l = l->next)
|
|
|
|
all_windows = g_list_prepend (all_windows, l->data);
|
|
|
|
return all_windows;
|
|
|
|
}
|
|
|
|
|
2010-09-01 19:39:53 +00:00
|
|
|
/**
|
|
|
|
* meta_display_get_tab_list:
|
|
|
|
* @display: a #MetaDisplay
|
|
|
|
* @type: type of tab list
|
2014-05-28 19:44:23 +00:00
|
|
|
* @workspace: (nullable): origin workspace
|
2010-09-01 19:39:53 +00:00
|
|
|
*
|
|
|
|
* Determine the list of windows that should be displayed for Alt-TAB
|
|
|
|
* functionality. The windows are returned in most recently used order.
|
2020-08-26 09:49:50 +00:00
|
|
|
* If @workspace is not %NULL, the list only contains windows that are on
|
2012-12-03 16:59:11 +00:00
|
|
|
* @workspace or have the demands-attention hint set; otherwise it contains
|
2014-06-03 12:40:15 +00:00
|
|
|
* all windows.
|
2010-09-01 19:39:53 +00:00
|
|
|
*
|
|
|
|
* Returns: (transfer container) (element-type Meta.Window): List of windows
|
|
|
|
*/
|
2003-03-15 02:16:21 +00:00
|
|
|
GList*
|
2002-03-12 04:34:17 +00:00
|
|
|
meta_display_get_tab_list (MetaDisplay *display,
|
2002-04-05 15:52:49 +00:00
|
|
|
MetaTabList type,
|
2002-03-12 04:34:17 +00:00
|
|
|
MetaWorkspace *workspace)
|
|
|
|
{
|
2012-12-03 23:05:22 +00:00
|
|
|
GList *tab_list = NULL;
|
2012-12-03 16:59:11 +00:00
|
|
|
GList *global_mru_list = NULL;
|
|
|
|
GList *mru_list, *tmp;
|
2012-12-03 23:05:22 +00:00
|
|
|
GSList *windows = meta_display_list_windows (display, META_LIST_DEFAULT);
|
|
|
|
GSList *w;
|
2002-03-12 04:34:17 +00:00
|
|
|
|
2012-12-03 16:59:11 +00:00
|
|
|
if (workspace == NULL)
|
|
|
|
{
|
|
|
|
/* Yay for mixing GList and GSList in the API */
|
|
|
|
for (w = windows; w; w = w->next)
|
|
|
|
global_mru_list = g_list_prepend (global_mru_list, w->data);
|
|
|
|
global_mru_list = g_list_sort (global_mru_list, mru_cmp);
|
|
|
|
}
|
|
|
|
|
|
|
|
mru_list = workspace ? workspace->mru_list : global_mru_list;
|
2002-04-05 15:52:49 +00:00
|
|
|
|
2014-10-01 23:28:45 +00:00
|
|
|
/* Windows sellout mode - MRU order. Collect unminimized windows
|
|
|
|
* then minimized so minimized windows aren't in the way so much.
|
2002-10-24 05:15:28 +00:00
|
|
|
*/
|
2012-12-03 16:59:11 +00:00
|
|
|
for (tmp = mru_list; tmp; tmp = tmp->next)
|
2012-12-03 23:05:22 +00:00
|
|
|
{
|
|
|
|
MetaWindow *window = tmp->data;
|
2002-10-24 05:15:28 +00:00
|
|
|
|
2014-10-01 23:28:45 +00:00
|
|
|
if (!window->minimized && IN_TAB_CHAIN (window, type))
|
|
|
|
tab_list = g_list_prepend (tab_list, window);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (tmp = mru_list; tmp; tmp = tmp->next)
|
|
|
|
{
|
|
|
|
MetaWindow *window = tmp->data;
|
|
|
|
|
|
|
|
if (window->minimized && IN_TAB_CHAIN (window, type))
|
2012-12-03 23:05:22 +00:00
|
|
|
tab_list = g_list_prepend (tab_list, window);
|
|
|
|
}
|
2008-02-02 04:05:16 +00:00
|
|
|
|
2012-12-03 23:05:22 +00:00
|
|
|
tab_list = g_list_reverse (tab_list);
|
2008-02-02 04:05:16 +00:00
|
|
|
|
2012-12-03 16:59:11 +00:00
|
|
|
/* If filtering by workspace, include windows from
|
|
|
|
* other workspaces that demand attention
|
|
|
|
*/
|
|
|
|
if (workspace)
|
|
|
|
for (w = windows; w; w = w->next)
|
|
|
|
{
|
|
|
|
MetaWindow *l_window = w->data;
|
2008-02-02 04:05:16 +00:00
|
|
|
|
2012-12-03 16:59:11 +00:00
|
|
|
if (l_window->wm_state_demands_attention &&
|
2019-04-17 10:28:57 +00:00
|
|
|
!meta_window_located_on_workspace (l_window, workspace) &&
|
2012-12-03 16:59:11 +00:00
|
|
|
IN_TAB_CHAIN (l_window, type))
|
2012-12-03 23:05:22 +00:00
|
|
|
tab_list = g_list_prepend (tab_list, l_window);
|
2012-12-03 16:59:11 +00:00
|
|
|
}
|
2012-03-23 08:45:50 +00:00
|
|
|
|
2012-12-03 16:59:11 +00:00
|
|
|
g_list_free (global_mru_list);
|
2012-12-03 23:05:22 +00:00
|
|
|
g_slist_free (windows);
|
2014-05-02 13:34:02 +00:00
|
|
|
|
2002-03-12 04:34:17 +00:00
|
|
|
return tab_list;
|
|
|
|
}
|
|
|
|
|
2010-09-01 19:39:53 +00:00
|
|
|
/**
|
|
|
|
* meta_display_get_tab_next:
|
|
|
|
* @display: a #MetaDisplay
|
|
|
|
* @type: type of tab list
|
|
|
|
* @workspace: origin workspace
|
2014-05-28 19:44:23 +00:00
|
|
|
* @window: (nullable): starting window
|
2014-05-02 13:34:02 +00:00
|
|
|
* @backward: If %TRUE, look for the previous window.
|
2010-09-01 19:39:53 +00:00
|
|
|
*
|
|
|
|
* Determine the next window that should be displayed for Alt-TAB
|
|
|
|
* functionality.
|
|
|
|
*
|
|
|
|
* Returns: (transfer none): Next window
|
|
|
|
*
|
|
|
|
*/
|
2002-03-12 04:34:17 +00:00
|
|
|
MetaWindow*
|
|
|
|
meta_display_get_tab_next (MetaDisplay *display,
|
2002-04-05 15:52:49 +00:00
|
|
|
MetaTabList type,
|
2002-03-12 04:34:17 +00:00
|
|
|
MetaWorkspace *workspace,
|
|
|
|
MetaWindow *window,
|
|
|
|
gboolean backward)
|
|
|
|
{
|
2004-10-25 16:17:19 +00:00
|
|
|
gboolean skip;
|
2003-03-15 02:16:21 +00:00
|
|
|
GList *tab_list;
|
2006-01-20 22:03:56 +00:00
|
|
|
MetaWindow *ret;
|
2014-06-03 12:40:15 +00:00
|
|
|
tab_list = meta_display_get_tab_list (display, type, workspace);
|
2003-03-15 02:16:21 +00:00
|
|
|
|
|
|
|
if (tab_list == NULL)
|
2002-03-12 04:34:17 +00:00
|
|
|
return NULL;
|
2014-05-02 13:34:02 +00:00
|
|
|
|
2002-03-12 04:34:17 +00:00
|
|
|
if (window != NULL)
|
|
|
|
{
|
|
|
|
g_assert (window->display == display);
|
2014-05-02 13:34:02 +00:00
|
|
|
|
2002-03-12 04:34:17 +00:00
|
|
|
if (backward)
|
2013-10-03 22:31:09 +00:00
|
|
|
ret = find_tab_backward (display, type, workspace, g_list_find (tab_list, window), TRUE);
|
2006-01-20 22:03:56 +00:00
|
|
|
else
|
2013-10-03 22:31:09 +00:00
|
|
|
ret = find_tab_forward (display, type, workspace, g_list_find (tab_list, window), TRUE);
|
2002-03-12 04:34:17 +00:00
|
|
|
}
|
|
|
|
else
|
2006-01-20 22:03:56 +00:00
|
|
|
{
|
2014-05-02 13:34:02 +00:00
|
|
|
skip = display->focus_window != NULL &&
|
2009-02-07 23:05:42 +00:00
|
|
|
tab_list->data == display->focus_window;
|
2006-01-20 22:03:56 +00:00
|
|
|
if (backward)
|
2013-10-03 22:31:09 +00:00
|
|
|
ret = find_tab_backward (display, type, workspace, tab_list, skip);
|
2006-01-20 22:03:56 +00:00
|
|
|
else
|
2013-10-03 22:31:09 +00:00
|
|
|
ret = find_tab_forward (display, type, workspace, tab_list, skip);
|
2006-01-20 22:03:56 +00:00
|
|
|
}
|
2003-03-15 02:16:21 +00:00
|
|
|
|
|
|
|
g_list_free (tab_list);
|
2006-01-20 22:03:56 +00:00
|
|
|
return ret;
|
2002-03-12 04:34:17 +00:00
|
|
|
}
|
2002-03-17 17:22:23 +00:00
|
|
|
|
2010-09-01 19:39:53 +00:00
|
|
|
/**
|
|
|
|
* meta_display_get_tab_current:
|
|
|
|
* @display: a #MetaDisplay
|
|
|
|
* @type: type of tab list
|
|
|
|
* @workspace: origin workspace
|
|
|
|
*
|
|
|
|
* Determine the active window that should be displayed for Alt-TAB.
|
|
|
|
*
|
|
|
|
* Returns: (transfer none): Current window
|
|
|
|
*
|
|
|
|
*/
|
2002-09-04 04:15:46 +00:00
|
|
|
MetaWindow*
|
|
|
|
meta_display_get_tab_current (MetaDisplay *display,
|
|
|
|
MetaTabList type,
|
|
|
|
MetaWorkspace *workspace)
|
|
|
|
{
|
|
|
|
MetaWindow *window;
|
|
|
|
|
|
|
|
window = display->focus_window;
|
2014-05-02 13:34:02 +00:00
|
|
|
|
2002-09-04 04:15:46 +00:00
|
|
|
if (window != NULL &&
|
|
|
|
IN_TAB_CHAIN (window, type) &&
|
|
|
|
(workspace == NULL ||
|
2004-12-23 00:20:33 +00:00
|
|
|
meta_window_located_on_workspace (window, workspace)))
|
2002-09-04 04:15:46 +00:00
|
|
|
return window;
|
|
|
|
else
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2020-02-14 08:44:43 +00:00
|
|
|
MetaGravity
|
2002-03-17 17:22:23 +00:00
|
|
|
meta_resize_gravity_from_grab_op (MetaGrabOp op)
|
|
|
|
{
|
2020-02-14 08:44:43 +00:00
|
|
|
MetaGravity gravity;
|
2014-05-02 13:34:02 +00:00
|
|
|
|
2022-09-29 13:55:11 +00:00
|
|
|
op &= ~(META_GRAB_OP_WINDOW_FLAG_UNCONSTRAINED);
|
|
|
|
|
2002-03-17 17:22:23 +00:00
|
|
|
gravity = -1;
|
|
|
|
switch (op)
|
|
|
|
{
|
|
|
|
case META_GRAB_OP_RESIZING_SE:
|
|
|
|
case META_GRAB_OP_KEYBOARD_RESIZING_SE:
|
2020-02-14 08:44:43 +00:00
|
|
|
gravity = META_GRAVITY_NORTH_WEST;
|
2002-03-17 17:22:23 +00:00
|
|
|
break;
|
|
|
|
case META_GRAB_OP_KEYBOARD_RESIZING_S:
|
|
|
|
case META_GRAB_OP_RESIZING_S:
|
2020-02-14 08:44:43 +00:00
|
|
|
gravity = META_GRAVITY_NORTH;
|
2002-03-17 17:22:23 +00:00
|
|
|
break;
|
|
|
|
case META_GRAB_OP_KEYBOARD_RESIZING_SW:
|
|
|
|
case META_GRAB_OP_RESIZING_SW:
|
2020-02-14 08:44:43 +00:00
|
|
|
gravity = META_GRAVITY_NORTH_EAST;
|
2002-03-17 17:22:23 +00:00
|
|
|
break;
|
|
|
|
case META_GRAB_OP_KEYBOARD_RESIZING_N:
|
|
|
|
case META_GRAB_OP_RESIZING_N:
|
2020-02-14 08:44:43 +00:00
|
|
|
gravity = META_GRAVITY_SOUTH;
|
2002-03-17 17:22:23 +00:00
|
|
|
break;
|
|
|
|
case META_GRAB_OP_KEYBOARD_RESIZING_NE:
|
|
|
|
case META_GRAB_OP_RESIZING_NE:
|
2020-02-14 08:44:43 +00:00
|
|
|
gravity = META_GRAVITY_SOUTH_WEST;
|
2002-03-17 17:22:23 +00:00
|
|
|
break;
|
|
|
|
case META_GRAB_OP_KEYBOARD_RESIZING_NW:
|
|
|
|
case META_GRAB_OP_RESIZING_NW:
|
2020-02-14 08:44:43 +00:00
|
|
|
gravity = META_GRAVITY_SOUTH_EAST;
|
2002-03-17 17:22:23 +00:00
|
|
|
break;
|
|
|
|
case META_GRAB_OP_KEYBOARD_RESIZING_E:
|
|
|
|
case META_GRAB_OP_RESIZING_E:
|
2020-02-14 08:44:43 +00:00
|
|
|
gravity = META_GRAVITY_WEST;
|
2002-03-17 17:22:23 +00:00
|
|
|
break;
|
|
|
|
case META_GRAB_OP_KEYBOARD_RESIZING_W:
|
|
|
|
case META_GRAB_OP_RESIZING_W:
|
2020-02-14 08:44:43 +00:00
|
|
|
gravity = META_GRAVITY_EAST;
|
2002-03-17 17:22:23 +00:00
|
|
|
break;
|
2002-06-19 04:12:49 +00:00
|
|
|
case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN:
|
2020-02-14 08:44:43 +00:00
|
|
|
gravity = META_GRAVITY_CENTER;
|
2002-06-19 04:12:49 +00:00
|
|
|
break;
|
2002-03-17 17:22:23 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return gravity;
|
|
|
|
}
|
2002-05-24 02:23:46 +00:00
|
|
|
|
2022-05-31 09:57:37 +00:00
|
|
|
#ifdef HAVE_X11_CLIENT
|
2017-08-26 17:03:51 +00:00
|
|
|
void
|
2019-05-25 10:00:47 +00:00
|
|
|
meta_display_manage_all_xwindows (MetaDisplay *display)
|
2017-08-26 17:03:51 +00:00
|
|
|
{
|
|
|
|
guint64 *_children;
|
|
|
|
guint64 *children;
|
|
|
|
int n_children, i;
|
|
|
|
|
|
|
|
meta_stack_freeze (display->stack);
|
|
|
|
meta_stack_tracker_get_stack (display->stack_tracker, &_children, &n_children);
|
|
|
|
|
|
|
|
/* Copy the stack as it will be modified as part of the loop */
|
2021-02-04 17:45:59 +00:00
|
|
|
children = g_memdup2 (_children, sizeof (uint64_t) * n_children);
|
2017-08-26 17:03:51 +00:00
|
|
|
|
|
|
|
for (i = 0; i < n_children; ++i)
|
|
|
|
{
|
2019-05-25 10:00:47 +00:00
|
|
|
if (!META_STACK_ID_IS_X11 (children[i]))
|
|
|
|
continue;
|
2017-08-26 17:03:51 +00:00
|
|
|
meta_window_x11_new (display, children[i], TRUE,
|
|
|
|
META_COMP_EFFECT_NONE);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_free (children);
|
|
|
|
meta_stack_thaw (display->stack);
|
|
|
|
}
|
2022-05-31 09:57:37 +00:00
|
|
|
#endif
|
2017-08-26 17:03:51 +00:00
|
|
|
|
2002-06-08 23:55:27 +00:00
|
|
|
void
|
2018-06-29 10:44:17 +00:00
|
|
|
meta_display_unmanage_windows (MetaDisplay *display,
|
|
|
|
guint32 timestamp)
|
2002-06-08 23:55:27 +00:00
|
|
|
{
|
|
|
|
GSList *tmp;
|
|
|
|
GSList *winlist;
|
|
|
|
|
2009-06-15 19:32:23 +00:00
|
|
|
winlist = meta_display_list_windows (display,
|
|
|
|
META_LIST_INCLUDE_OVERRIDE_REDIRECT);
|
2007-04-16 04:57:32 +00:00
|
|
|
winlist = g_slist_sort (winlist, meta_display_stack_cmp);
|
2012-01-19 19:06:57 +00:00
|
|
|
g_slist_foreach (winlist, (GFunc)g_object_ref, NULL);
|
2002-06-08 23:55:27 +00:00
|
|
|
|
|
|
|
/* Unmanage all windows */
|
|
|
|
tmp = winlist;
|
|
|
|
while (tmp != NULL)
|
Partial audit to fix timestamp usage. One step towards fixing #355180; see
2006-09-18 Elijah Newren <newren gmail com>
Partial audit to fix timestamp usage. One step towards fixing
#355180; see important comments in that bug.
* src/core.[ch] (meta_core_unshade, meta_core_shade):
* src/delete.c (meta_window_present_delete_dialog,
delete_ping_timeout_func):
* src/display.[ch] (meta_display_open, meta_display_close,
event_callback, meta_display_begin_grab_op,
process_selection_clear, meta_display_unmanage_screen,
meta_display_unmanage_windows_for_screen):
* src/frames.c (meta_frames_button_press_event):
* src/keybindings.c (handle_toggle_shade):
* src/main.c (main):
* src/screen.[ch] (update_num_workspaces, meta_screen_new,
meta_screen_free, prefs_changed_callback):
* src/window.[ch] (meta_window_free, finish_minimize,
implement_showing, meta_window_show, meta_window_maximize,
meta_window_make_fullscreen_internal,
meta_window_unmake_fullscreen, meta_window_shade,
meta_window_unshade, window_activate, send_sync_request,
meta_window_client_message, menu_callback,
meta_window_update_keyboard_resize):
Remove usage of CurrentTime, meta_display_get_current_time() and
meta_display_get_current_time_roundtrip() where possible, or
document why it isn't possible, or at very least add a FIXME with
some explanation of my laziness and what needs to be done.
2006-09-18 17:27:24 +00:00
|
|
|
{
|
2012-01-19 19:06:57 +00:00
|
|
|
MetaWindow *window = tmp->data;
|
|
|
|
|
|
|
|
/* Check if already unmanaged for safety - in particular, catch
|
|
|
|
* the case where unmanaging a parent window can cause attached
|
|
|
|
* dialogs to be (temporarily) unmanaged.
|
|
|
|
*/
|
|
|
|
if (!window->unmanaging)
|
|
|
|
meta_window_unmanage (window, timestamp);
|
|
|
|
g_object_unref (window);
|
2014-05-02 13:34:02 +00:00
|
|
|
|
2002-06-08 23:55:27 +00:00
|
|
|
tmp = tmp->next;
|
|
|
|
}
|
|
|
|
g_slist_free (winlist);
|
|
|
|
}
|
2002-10-07 23:14:40 +00:00
|
|
|
|
2007-04-16 04:57:32 +00:00
|
|
|
int
|
|
|
|
meta_display_stack_cmp (const void *a,
|
|
|
|
const void *b)
|
|
|
|
{
|
|
|
|
MetaWindow *aw = (void*) a;
|
|
|
|
MetaWindow *bw = (void*) b;
|
|
|
|
|
2017-08-26 17:03:51 +00:00
|
|
|
return meta_stack_windows_cmp (aw->display->stack, aw, bw);
|
2007-04-16 04:57:32 +00:00
|
|
|
}
|
|
|
|
|
2010-04-24 21:18:01 +00:00
|
|
|
/**
|
|
|
|
* meta_display_sort_windows_by_stacking:
|
|
|
|
* @display: a #MetaDisplay
|
|
|
|
* @windows: (element-type MetaWindow): Set of windows
|
|
|
|
*
|
|
|
|
* Sorts a set of windows according to their current stacking order. If windows
|
|
|
|
* from multiple screens are present in the set of input windows, then all the
|
|
|
|
* windows on screen 0 are sorted below all the windows on screen 1, and so forth.
|
|
|
|
* Since the stacking order of override-redirect windows isn't controlled by
|
|
|
|
* Metacity, if override-redirect windows are in the input, the result may not
|
|
|
|
* correspond to the actual stacking order in the X server.
|
|
|
|
*
|
|
|
|
* An example of using this would be to sort the list of transient dialogs for a
|
|
|
|
* window into their current stacking order.
|
|
|
|
*
|
2011-08-30 16:54:49 +00:00
|
|
|
* Returns: (transfer container) (element-type MetaWindow): Input windows sorted by stacking order, from lowest to highest
|
2010-04-24 21:18:01 +00:00
|
|
|
*/
|
|
|
|
GSList *
|
|
|
|
meta_display_sort_windows_by_stacking (MetaDisplay *display,
|
|
|
|
GSList *windows)
|
|
|
|
{
|
|
|
|
GSList *copy = g_slist_copy (windows);
|
|
|
|
|
|
|
|
copy = g_slist_sort (copy, meta_display_stack_cmp);
|
|
|
|
|
|
|
|
return copy;
|
|
|
|
}
|
|
|
|
|
2002-10-07 23:14:40 +00:00
|
|
|
static void
|
|
|
|
prefs_changed_callback (MetaPreference pref,
|
|
|
|
void *data)
|
|
|
|
{
|
2006-02-16 20:26:05 +00:00
|
|
|
MetaDisplay *display = data;
|
2014-05-02 13:34:02 +00:00
|
|
|
|
2021-02-25 14:58:56 +00:00
|
|
|
switch (pref)
|
2014-04-24 14:48:47 +00:00
|
|
|
{
|
2021-02-25 14:58:56 +00:00
|
|
|
case META_PREF_DRAGGABLE_BORDER_WIDTH:
|
|
|
|
meta_display_queue_retheme_all_windows (display);
|
|
|
|
break;
|
|
|
|
case META_PREF_CURSOR_THEME:
|
|
|
|
case META_PREF_CURSOR_SIZE:
|
2017-08-26 16:37:29 +00:00
|
|
|
meta_display_reload_cursor (display);
|
2021-02-25 14:58:56 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
2014-04-24 14:48:47 +00:00
|
|
|
}
|
2002-10-07 23:14:40 +00:00
|
|
|
}
|
2003-05-30 20:24:00 +00:00
|
|
|
|
2014-03-20 19:29:30 +00:00
|
|
|
void
|
|
|
|
meta_display_sanity_check_timestamps (MetaDisplay *display,
|
|
|
|
guint32 timestamp)
|
Big patch to cover about 6 different issues in order to correct rare
2005-02-20 Elijah Newren <newren@gmail.com>
Big patch to cover about 6 different issues in order to correct
rare problems with timestamps (make sure window selected in
tasklist actually gets focus, sanity check timestamps to avoid
rogue apps hosing the system, correct the updating of
net_wm_user_time, correctly handle timestamps of 0 when comparing
xserver timestamps for those who have had their systems up for
over 25 days or so, add some debugging information to verbose
logs, some code cleanups). Fixes all issues listed in #167358.
* src/display.h: (struct _MetaDisplay): clarify comment on
last_focus_time, introduce a new variable--last_user_time,
(XSERVER_TIME_IS_BEFORE macro): put this functionality into a
separate macro and then introduce a new macro with this name that
uses the old one but adds additional special-case checks for
timestamps that are 0, (comment to
meta_display_set_input_focus_window): add information about how
last_user_time should be used in this function
* src/display.c (santiy_check_timestamps): new function,
(meta_display_open): intialize display->last_user_time,
(meta_display_get_current_time_roundtrip): use the timestamp,
which is known to be good, in order to sanity_check_timestamps,
(event_callback): use the new meta_window_ste_user_time() function
in order to correct problems, use the timestamp of KeyPress and
ButtonPress events, which are known to be good, in order to
sanity_check_timestamps, (timestamp_too_old): new function for
common behavior of meta_display_focus_the_no_focus_window and
meta_display_set_input_focus_window, with added checking for
display->last_user_time in addition to display->last_focus_time,
(meta_display_set_input_focus_window): replace some of the code
with a call to timestamp_too_old(),
(meta_display_focus_the_no_focus_window): replace some of th ecode
with a call to timestamp_too_old()
* src/window.h: (meta_window_set_user_time): new function to
abstract the many things that need to be done when updating the
net_wm_user_time of any window
* src/window.c: (meta_window_activate): add debugging spew, make
sure the comparison is made with last_user_time NOT
last_focus_time, use meta_window_set_user_time() function in order
to correct problems, (meta_window_client_message): add a newline
to a debugging message to make them easier to read,
(meta_window_set_user_time): new function
* src/window-props.c (reload_net_wm_user_time): use the new
meta_window_ste_user_time() function in order to correct problems
2005-02-20 17:14:16 +00:00
|
|
|
{
|
|
|
|
if (XSERVER_TIME_IS_BEFORE (timestamp, display->last_focus_time))
|
|
|
|
{
|
Fix issues on 64-bit machines with timestamps by using guint32 (like gtk+
2006-09-13 Elijah Newren <newren gmail com>
* src/common.h (MetaWindowMenuFunc):
* src/core.[ch] (meta_core_user_lower_and_unfocus,
meta_core_user_focus, meta_core_show_window_menu,
meta_core_begin_grab_op, meta_core_end_grab_op):
* src/delete.c (delete_ping_reply_func, delete_ping_timeout_func,
meta_window_delete):
* src/display.[ch] (struct MetaDisplay, struct MetaPingData,
sanity_check_timestamps, meta_display_open, event_callback,
meta_spew_event, meta_display_set_grab_op_cursor,
meta_display_begin_grab_op, meta_display_end_grab_op,
meta_display_ping_timeout, meta_display_ping_window,
process_pong_message, timestamp_too_old,
meta_display_set_input_focus_window):
* src/keybindings.[ch] (grab_keyboard, ungrab_keyboard,
meta_screen_grab_all_keys, meta_window_grab_all_keys,
meta_window_ungrab_all_keys, error_on_generic_command,
error_on_command, error_on_terminal_command):
* src/metacity-dialog.c (on_realize, warn_about_no_sm_support,
error_about_command, main):
* src/screen.[ch] (struct _MetaScreen, meta_screen_new,
meta_screen_show_desktop, meta_screen_apply_startup_properties):
* src/session.c (warn_about_lame_clients_and_finish_interact):
* src/window.[ch] (struct _MetaWindow,
intervening_user_event_occurred, window_activate,
meta_window_delete, meta_window_focus,
meta_window_send_icccm_message, meta_window_client_message,
menu_callback, meta_window_show_menu, struct EventScannerData,
check_use_this_motion_notify, meta_window_begin_grab_op,
meta_window_set_user_time):
* src/workspace.[ch] (focus_ancestor_or_mru_window,
meta_workspace_activate_with_focus, meta_workspace_activate,
meta_workspace_focus_default_window,
focus_ancestor_or_mru_window):
Fix issues on 64-bit machines with timestamps by using guint32
(like gtk+ does) instead of Time. #348305
2006-09-13 16:32:33 +00:00
|
|
|
meta_warning ("last_focus_time (%u) is greater than comparison "
|
|
|
|
"timestamp (%u). This most likely represents a buggy "
|
Big patch to cover about 6 different issues in order to correct rare
2005-02-20 Elijah Newren <newren@gmail.com>
Big patch to cover about 6 different issues in order to correct
rare problems with timestamps (make sure window selected in
tasklist actually gets focus, sanity check timestamps to avoid
rogue apps hosing the system, correct the updating of
net_wm_user_time, correctly handle timestamps of 0 when comparing
xserver timestamps for those who have had their systems up for
over 25 days or so, add some debugging information to verbose
logs, some code cleanups). Fixes all issues listed in #167358.
* src/display.h: (struct _MetaDisplay): clarify comment on
last_focus_time, introduce a new variable--last_user_time,
(XSERVER_TIME_IS_BEFORE macro): put this functionality into a
separate macro and then introduce a new macro with this name that
uses the old one but adds additional special-case checks for
timestamps that are 0, (comment to
meta_display_set_input_focus_window): add information about how
last_user_time should be used in this function
* src/display.c (santiy_check_timestamps): new function,
(meta_display_open): intialize display->last_user_time,
(meta_display_get_current_time_roundtrip): use the timestamp,
which is known to be good, in order to sanity_check_timestamps,
(event_callback): use the new meta_window_ste_user_time() function
in order to correct problems, use the timestamp of KeyPress and
ButtonPress events, which are known to be good, in order to
sanity_check_timestamps, (timestamp_too_old): new function for
common behavior of meta_display_focus_the_no_focus_window and
meta_display_set_input_focus_window, with added checking for
display->last_user_time in addition to display->last_focus_time,
(meta_display_set_input_focus_window): replace some of the code
with a call to timestamp_too_old(),
(meta_display_focus_the_no_focus_window): replace some of th ecode
with a call to timestamp_too_old()
* src/window.h: (meta_window_set_user_time): new function to
abstract the many things that need to be done when updating the
net_wm_user_time of any window
* src/window.c: (meta_window_activate): add debugging spew, make
sure the comparison is made with last_user_time NOT
last_focus_time, use meta_window_set_user_time() function in order
to correct problems, (meta_window_client_message): add a newline
to a debugging message to make them easier to read,
(meta_window_set_user_time): new function
* src/window-props.c (reload_net_wm_user_time): use the new
meta_window_ste_user_time() function in order to correct problems
2005-02-20 17:14:16 +00:00
|
|
|
"client sending inaccurate timestamps in messages such as "
|
2020-10-02 15:47:22 +00:00
|
|
|
"_NET_ACTIVE_WINDOW. Trying to work around...",
|
Fix issues on 64-bit machines with timestamps by using guint32 (like gtk+
2006-09-13 Elijah Newren <newren gmail com>
* src/common.h (MetaWindowMenuFunc):
* src/core.[ch] (meta_core_user_lower_and_unfocus,
meta_core_user_focus, meta_core_show_window_menu,
meta_core_begin_grab_op, meta_core_end_grab_op):
* src/delete.c (delete_ping_reply_func, delete_ping_timeout_func,
meta_window_delete):
* src/display.[ch] (struct MetaDisplay, struct MetaPingData,
sanity_check_timestamps, meta_display_open, event_callback,
meta_spew_event, meta_display_set_grab_op_cursor,
meta_display_begin_grab_op, meta_display_end_grab_op,
meta_display_ping_timeout, meta_display_ping_window,
process_pong_message, timestamp_too_old,
meta_display_set_input_focus_window):
* src/keybindings.[ch] (grab_keyboard, ungrab_keyboard,
meta_screen_grab_all_keys, meta_window_grab_all_keys,
meta_window_ungrab_all_keys, error_on_generic_command,
error_on_command, error_on_terminal_command):
* src/metacity-dialog.c (on_realize, warn_about_no_sm_support,
error_about_command, main):
* src/screen.[ch] (struct _MetaScreen, meta_screen_new,
meta_screen_show_desktop, meta_screen_apply_startup_properties):
* src/session.c (warn_about_lame_clients_and_finish_interact):
* src/window.[ch] (struct _MetaWindow,
intervening_user_event_occurred, window_activate,
meta_window_delete, meta_window_focus,
meta_window_send_icccm_message, meta_window_client_message,
menu_callback, meta_window_show_menu, struct EventScannerData,
check_use_this_motion_notify, meta_window_begin_grab_op,
meta_window_set_user_time):
* src/workspace.[ch] (focus_ancestor_or_mru_window,
meta_workspace_activate_with_focus, meta_workspace_activate,
meta_workspace_focus_default_window,
focus_ancestor_or_mru_window):
Fix issues on 64-bit machines with timestamps by using guint32
(like gtk+ does) instead of Time. #348305
2006-09-13 16:32:33 +00:00
|
|
|
display->last_focus_time, timestamp);
|
Big patch to cover about 6 different issues in order to correct rare
2005-02-20 Elijah Newren <newren@gmail.com>
Big patch to cover about 6 different issues in order to correct
rare problems with timestamps (make sure window selected in
tasklist actually gets focus, sanity check timestamps to avoid
rogue apps hosing the system, correct the updating of
net_wm_user_time, correctly handle timestamps of 0 when comparing
xserver timestamps for those who have had their systems up for
over 25 days or so, add some debugging information to verbose
logs, some code cleanups). Fixes all issues listed in #167358.
* src/display.h: (struct _MetaDisplay): clarify comment on
last_focus_time, introduce a new variable--last_user_time,
(XSERVER_TIME_IS_BEFORE macro): put this functionality into a
separate macro and then introduce a new macro with this name that
uses the old one but adds additional special-case checks for
timestamps that are 0, (comment to
meta_display_set_input_focus_window): add information about how
last_user_time should be used in this function
* src/display.c (santiy_check_timestamps): new function,
(meta_display_open): intialize display->last_user_time,
(meta_display_get_current_time_roundtrip): use the timestamp,
which is known to be good, in order to sanity_check_timestamps,
(event_callback): use the new meta_window_ste_user_time() function
in order to correct problems, use the timestamp of KeyPress and
ButtonPress events, which are known to be good, in order to
sanity_check_timestamps, (timestamp_too_old): new function for
common behavior of meta_display_focus_the_no_focus_window and
meta_display_set_input_focus_window, with added checking for
display->last_user_time in addition to display->last_focus_time,
(meta_display_set_input_focus_window): replace some of the code
with a call to timestamp_too_old(),
(meta_display_focus_the_no_focus_window): replace some of th ecode
with a call to timestamp_too_old()
* src/window.h: (meta_window_set_user_time): new function to
abstract the many things that need to be done when updating the
net_wm_user_time of any window
* src/window.c: (meta_window_activate): add debugging spew, make
sure the comparison is made with last_user_time NOT
last_focus_time, use meta_window_set_user_time() function in order
to correct problems, (meta_window_client_message): add a newline
to a debugging message to make them easier to read,
(meta_window_set_user_time): new function
* src/window-props.c (reload_net_wm_user_time): use the new
meta_window_ste_user_time() function in order to correct problems
2005-02-20 17:14:16 +00:00
|
|
|
display->last_focus_time = timestamp;
|
|
|
|
}
|
|
|
|
if (XSERVER_TIME_IS_BEFORE (timestamp, display->last_user_time))
|
|
|
|
{
|
|
|
|
GSList *windows;
|
|
|
|
GSList *tmp;
|
|
|
|
|
Fix issues on 64-bit machines with timestamps by using guint32 (like gtk+
2006-09-13 Elijah Newren <newren gmail com>
* src/common.h (MetaWindowMenuFunc):
* src/core.[ch] (meta_core_user_lower_and_unfocus,
meta_core_user_focus, meta_core_show_window_menu,
meta_core_begin_grab_op, meta_core_end_grab_op):
* src/delete.c (delete_ping_reply_func, delete_ping_timeout_func,
meta_window_delete):
* src/display.[ch] (struct MetaDisplay, struct MetaPingData,
sanity_check_timestamps, meta_display_open, event_callback,
meta_spew_event, meta_display_set_grab_op_cursor,
meta_display_begin_grab_op, meta_display_end_grab_op,
meta_display_ping_timeout, meta_display_ping_window,
process_pong_message, timestamp_too_old,
meta_display_set_input_focus_window):
* src/keybindings.[ch] (grab_keyboard, ungrab_keyboard,
meta_screen_grab_all_keys, meta_window_grab_all_keys,
meta_window_ungrab_all_keys, error_on_generic_command,
error_on_command, error_on_terminal_command):
* src/metacity-dialog.c (on_realize, warn_about_no_sm_support,
error_about_command, main):
* src/screen.[ch] (struct _MetaScreen, meta_screen_new,
meta_screen_show_desktop, meta_screen_apply_startup_properties):
* src/session.c (warn_about_lame_clients_and_finish_interact):
* src/window.[ch] (struct _MetaWindow,
intervening_user_event_occurred, window_activate,
meta_window_delete, meta_window_focus,
meta_window_send_icccm_message, meta_window_client_message,
menu_callback, meta_window_show_menu, struct EventScannerData,
check_use_this_motion_notify, meta_window_begin_grab_op,
meta_window_set_user_time):
* src/workspace.[ch] (focus_ancestor_or_mru_window,
meta_workspace_activate_with_focus, meta_workspace_activate,
meta_workspace_focus_default_window,
focus_ancestor_or_mru_window):
Fix issues on 64-bit machines with timestamps by using guint32
(like gtk+ does) instead of Time. #348305
2006-09-13 16:32:33 +00:00
|
|
|
meta_warning ("last_user_time (%u) is greater than comparison "
|
|
|
|
"timestamp (%u). This most likely represents a buggy "
|
Big patch to cover about 6 different issues in order to correct rare
2005-02-20 Elijah Newren <newren@gmail.com>
Big patch to cover about 6 different issues in order to correct
rare problems with timestamps (make sure window selected in
tasklist actually gets focus, sanity check timestamps to avoid
rogue apps hosing the system, correct the updating of
net_wm_user_time, correctly handle timestamps of 0 when comparing
xserver timestamps for those who have had their systems up for
over 25 days or so, add some debugging information to verbose
logs, some code cleanups). Fixes all issues listed in #167358.
* src/display.h: (struct _MetaDisplay): clarify comment on
last_focus_time, introduce a new variable--last_user_time,
(XSERVER_TIME_IS_BEFORE macro): put this functionality into a
separate macro and then introduce a new macro with this name that
uses the old one but adds additional special-case checks for
timestamps that are 0, (comment to
meta_display_set_input_focus_window): add information about how
last_user_time should be used in this function
* src/display.c (santiy_check_timestamps): new function,
(meta_display_open): intialize display->last_user_time,
(meta_display_get_current_time_roundtrip): use the timestamp,
which is known to be good, in order to sanity_check_timestamps,
(event_callback): use the new meta_window_ste_user_time() function
in order to correct problems, use the timestamp of KeyPress and
ButtonPress events, which are known to be good, in order to
sanity_check_timestamps, (timestamp_too_old): new function for
common behavior of meta_display_focus_the_no_focus_window and
meta_display_set_input_focus_window, with added checking for
display->last_user_time in addition to display->last_focus_time,
(meta_display_set_input_focus_window): replace some of the code
with a call to timestamp_too_old(),
(meta_display_focus_the_no_focus_window): replace some of th ecode
with a call to timestamp_too_old()
* src/window.h: (meta_window_set_user_time): new function to
abstract the many things that need to be done when updating the
net_wm_user_time of any window
* src/window.c: (meta_window_activate): add debugging spew, make
sure the comparison is made with last_user_time NOT
last_focus_time, use meta_window_set_user_time() function in order
to correct problems, (meta_window_client_message): add a newline
to a debugging message to make them easier to read,
(meta_window_set_user_time): new function
* src/window-props.c (reload_net_wm_user_time): use the new
meta_window_ste_user_time() function in order to correct problems
2005-02-20 17:14:16 +00:00
|
|
|
"client sending inaccurate timestamps in messages such as "
|
2020-10-02 15:47:22 +00:00
|
|
|
"_NET_ACTIVE_WINDOW. Trying to work around...",
|
Fix issues on 64-bit machines with timestamps by using guint32 (like gtk+
2006-09-13 Elijah Newren <newren gmail com>
* src/common.h (MetaWindowMenuFunc):
* src/core.[ch] (meta_core_user_lower_and_unfocus,
meta_core_user_focus, meta_core_show_window_menu,
meta_core_begin_grab_op, meta_core_end_grab_op):
* src/delete.c (delete_ping_reply_func, delete_ping_timeout_func,
meta_window_delete):
* src/display.[ch] (struct MetaDisplay, struct MetaPingData,
sanity_check_timestamps, meta_display_open, event_callback,
meta_spew_event, meta_display_set_grab_op_cursor,
meta_display_begin_grab_op, meta_display_end_grab_op,
meta_display_ping_timeout, meta_display_ping_window,
process_pong_message, timestamp_too_old,
meta_display_set_input_focus_window):
* src/keybindings.[ch] (grab_keyboard, ungrab_keyboard,
meta_screen_grab_all_keys, meta_window_grab_all_keys,
meta_window_ungrab_all_keys, error_on_generic_command,
error_on_command, error_on_terminal_command):
* src/metacity-dialog.c (on_realize, warn_about_no_sm_support,
error_about_command, main):
* src/screen.[ch] (struct _MetaScreen, meta_screen_new,
meta_screen_show_desktop, meta_screen_apply_startup_properties):
* src/session.c (warn_about_lame_clients_and_finish_interact):
* src/window.[ch] (struct _MetaWindow,
intervening_user_event_occurred, window_activate,
meta_window_delete, meta_window_focus,
meta_window_send_icccm_message, meta_window_client_message,
menu_callback, meta_window_show_menu, struct EventScannerData,
check_use_this_motion_notify, meta_window_begin_grab_op,
meta_window_set_user_time):
* src/workspace.[ch] (focus_ancestor_or_mru_window,
meta_workspace_activate_with_focus, meta_workspace_activate,
meta_workspace_focus_default_window,
focus_ancestor_or_mru_window):
Fix issues on 64-bit machines with timestamps by using guint32
(like gtk+ does) instead of Time. #348305
2006-09-13 16:32:33 +00:00
|
|
|
display->last_user_time, timestamp);
|
Big patch to cover about 6 different issues in order to correct rare
2005-02-20 Elijah Newren <newren@gmail.com>
Big patch to cover about 6 different issues in order to correct
rare problems with timestamps (make sure window selected in
tasklist actually gets focus, sanity check timestamps to avoid
rogue apps hosing the system, correct the updating of
net_wm_user_time, correctly handle timestamps of 0 when comparing
xserver timestamps for those who have had their systems up for
over 25 days or so, add some debugging information to verbose
logs, some code cleanups). Fixes all issues listed in #167358.
* src/display.h: (struct _MetaDisplay): clarify comment on
last_focus_time, introduce a new variable--last_user_time,
(XSERVER_TIME_IS_BEFORE macro): put this functionality into a
separate macro and then introduce a new macro with this name that
uses the old one but adds additional special-case checks for
timestamps that are 0, (comment to
meta_display_set_input_focus_window): add information about how
last_user_time should be used in this function
* src/display.c (santiy_check_timestamps): new function,
(meta_display_open): intialize display->last_user_time,
(meta_display_get_current_time_roundtrip): use the timestamp,
which is known to be good, in order to sanity_check_timestamps,
(event_callback): use the new meta_window_ste_user_time() function
in order to correct problems, use the timestamp of KeyPress and
ButtonPress events, which are known to be good, in order to
sanity_check_timestamps, (timestamp_too_old): new function for
common behavior of meta_display_focus_the_no_focus_window and
meta_display_set_input_focus_window, with added checking for
display->last_user_time in addition to display->last_focus_time,
(meta_display_set_input_focus_window): replace some of the code
with a call to timestamp_too_old(),
(meta_display_focus_the_no_focus_window): replace some of th ecode
with a call to timestamp_too_old()
* src/window.h: (meta_window_set_user_time): new function to
abstract the many things that need to be done when updating the
net_wm_user_time of any window
* src/window.c: (meta_window_activate): add debugging spew, make
sure the comparison is made with last_user_time NOT
last_focus_time, use meta_window_set_user_time() function in order
to correct problems, (meta_window_client_message): add a newline
to a debugging message to make them easier to read,
(meta_window_set_user_time): new function
* src/window-props.c (reload_net_wm_user_time): use the new
meta_window_ste_user_time() function in order to correct problems
2005-02-20 17:14:16 +00:00
|
|
|
display->last_user_time = timestamp;
|
|
|
|
|
2009-06-15 19:32:23 +00:00
|
|
|
windows = meta_display_list_windows (display, META_LIST_DEFAULT);
|
Big patch to cover about 6 different issues in order to correct rare
2005-02-20 Elijah Newren <newren@gmail.com>
Big patch to cover about 6 different issues in order to correct
rare problems with timestamps (make sure window selected in
tasklist actually gets focus, sanity check timestamps to avoid
rogue apps hosing the system, correct the updating of
net_wm_user_time, correctly handle timestamps of 0 when comparing
xserver timestamps for those who have had their systems up for
over 25 days or so, add some debugging information to verbose
logs, some code cleanups). Fixes all issues listed in #167358.
* src/display.h: (struct _MetaDisplay): clarify comment on
last_focus_time, introduce a new variable--last_user_time,
(XSERVER_TIME_IS_BEFORE macro): put this functionality into a
separate macro and then introduce a new macro with this name that
uses the old one but adds additional special-case checks for
timestamps that are 0, (comment to
meta_display_set_input_focus_window): add information about how
last_user_time should be used in this function
* src/display.c (santiy_check_timestamps): new function,
(meta_display_open): intialize display->last_user_time,
(meta_display_get_current_time_roundtrip): use the timestamp,
which is known to be good, in order to sanity_check_timestamps,
(event_callback): use the new meta_window_ste_user_time() function
in order to correct problems, use the timestamp of KeyPress and
ButtonPress events, which are known to be good, in order to
sanity_check_timestamps, (timestamp_too_old): new function for
common behavior of meta_display_focus_the_no_focus_window and
meta_display_set_input_focus_window, with added checking for
display->last_user_time in addition to display->last_focus_time,
(meta_display_set_input_focus_window): replace some of the code
with a call to timestamp_too_old(),
(meta_display_focus_the_no_focus_window): replace some of th ecode
with a call to timestamp_too_old()
* src/window.h: (meta_window_set_user_time): new function to
abstract the many things that need to be done when updating the
net_wm_user_time of any window
* src/window.c: (meta_window_activate): add debugging spew, make
sure the comparison is made with last_user_time NOT
last_focus_time, use meta_window_set_user_time() function in order
to correct problems, (meta_window_client_message): add a newline
to a debugging message to make them easier to read,
(meta_window_set_user_time): new function
* src/window-props.c (reload_net_wm_user_time): use the new
meta_window_ste_user_time() function in order to correct problems
2005-02-20 17:14:16 +00:00
|
|
|
tmp = windows;
|
|
|
|
while (tmp != NULL)
|
|
|
|
{
|
|
|
|
MetaWindow *window = tmp->data;
|
2014-05-02 13:34:02 +00:00
|
|
|
|
Big patch to cover about 6 different issues in order to correct rare
2005-02-20 Elijah Newren <newren@gmail.com>
Big patch to cover about 6 different issues in order to correct
rare problems with timestamps (make sure window selected in
tasklist actually gets focus, sanity check timestamps to avoid
rogue apps hosing the system, correct the updating of
net_wm_user_time, correctly handle timestamps of 0 when comparing
xserver timestamps for those who have had their systems up for
over 25 days or so, add some debugging information to verbose
logs, some code cleanups). Fixes all issues listed in #167358.
* src/display.h: (struct _MetaDisplay): clarify comment on
last_focus_time, introduce a new variable--last_user_time,
(XSERVER_TIME_IS_BEFORE macro): put this functionality into a
separate macro and then introduce a new macro with this name that
uses the old one but adds additional special-case checks for
timestamps that are 0, (comment to
meta_display_set_input_focus_window): add information about how
last_user_time should be used in this function
* src/display.c (santiy_check_timestamps): new function,
(meta_display_open): intialize display->last_user_time,
(meta_display_get_current_time_roundtrip): use the timestamp,
which is known to be good, in order to sanity_check_timestamps,
(event_callback): use the new meta_window_ste_user_time() function
in order to correct problems, use the timestamp of KeyPress and
ButtonPress events, which are known to be good, in order to
sanity_check_timestamps, (timestamp_too_old): new function for
common behavior of meta_display_focus_the_no_focus_window and
meta_display_set_input_focus_window, with added checking for
display->last_user_time in addition to display->last_focus_time,
(meta_display_set_input_focus_window): replace some of the code
with a call to timestamp_too_old(),
(meta_display_focus_the_no_focus_window): replace some of th ecode
with a call to timestamp_too_old()
* src/window.h: (meta_window_set_user_time): new function to
abstract the many things that need to be done when updating the
net_wm_user_time of any window
* src/window.c: (meta_window_activate): add debugging spew, make
sure the comparison is made with last_user_time NOT
last_focus_time, use meta_window_set_user_time() function in order
to correct problems, (meta_window_client_message): add a newline
to a debugging message to make them easier to read,
(meta_window_set_user_time): new function
* src/window-props.c (reload_net_wm_user_time): use the new
meta_window_ste_user_time() function in order to correct problems
2005-02-20 17:14:16 +00:00
|
|
|
if (XSERVER_TIME_IS_BEFORE (timestamp, window->net_wm_user_time))
|
|
|
|
{
|
|
|
|
meta_warning ("%s appears to be one of the offending windows "
|
2020-10-02 15:47:22 +00:00
|
|
|
"with a timestamp of %u. Working around...",
|
Big patch to cover about 6 different issues in order to correct rare
2005-02-20 Elijah Newren <newren@gmail.com>
Big patch to cover about 6 different issues in order to correct
rare problems with timestamps (make sure window selected in
tasklist actually gets focus, sanity check timestamps to avoid
rogue apps hosing the system, correct the updating of
net_wm_user_time, correctly handle timestamps of 0 when comparing
xserver timestamps for those who have had their systems up for
over 25 days or so, add some debugging information to verbose
logs, some code cleanups). Fixes all issues listed in #167358.
* src/display.h: (struct _MetaDisplay): clarify comment on
last_focus_time, introduce a new variable--last_user_time,
(XSERVER_TIME_IS_BEFORE macro): put this functionality into a
separate macro and then introduce a new macro with this name that
uses the old one but adds additional special-case checks for
timestamps that are 0, (comment to
meta_display_set_input_focus_window): add information about how
last_user_time should be used in this function
* src/display.c (santiy_check_timestamps): new function,
(meta_display_open): intialize display->last_user_time,
(meta_display_get_current_time_roundtrip): use the timestamp,
which is known to be good, in order to sanity_check_timestamps,
(event_callback): use the new meta_window_ste_user_time() function
in order to correct problems, use the timestamp of KeyPress and
ButtonPress events, which are known to be good, in order to
sanity_check_timestamps, (timestamp_too_old): new function for
common behavior of meta_display_focus_the_no_focus_window and
meta_display_set_input_focus_window, with added checking for
display->last_user_time in addition to display->last_focus_time,
(meta_display_set_input_focus_window): replace some of the code
with a call to timestamp_too_old(),
(meta_display_focus_the_no_focus_window): replace some of th ecode
with a call to timestamp_too_old()
* src/window.h: (meta_window_set_user_time): new function to
abstract the many things that need to be done when updating the
net_wm_user_time of any window
* src/window.c: (meta_window_activate): add debugging spew, make
sure the comparison is made with last_user_time NOT
last_focus_time, use meta_window_set_user_time() function in order
to correct problems, (meta_window_client_message): add a newline
to a debugging message to make them easier to read,
(meta_window_set_user_time): new function
* src/window-props.c (reload_net_wm_user_time): use the new
meta_window_ste_user_time() function in order to correct problems
2005-02-20 17:14:16 +00:00
|
|
|
window->desc, window->net_wm_user_time);
|
2009-09-04 00:58:19 +00:00
|
|
|
meta_window_set_user_time (window, timestamp);
|
Big patch to cover about 6 different issues in order to correct rare
2005-02-20 Elijah Newren <newren@gmail.com>
Big patch to cover about 6 different issues in order to correct
rare problems with timestamps (make sure window selected in
tasklist actually gets focus, sanity check timestamps to avoid
rogue apps hosing the system, correct the updating of
net_wm_user_time, correctly handle timestamps of 0 when comparing
xserver timestamps for those who have had their systems up for
over 25 days or so, add some debugging information to verbose
logs, some code cleanups). Fixes all issues listed in #167358.
* src/display.h: (struct _MetaDisplay): clarify comment on
last_focus_time, introduce a new variable--last_user_time,
(XSERVER_TIME_IS_BEFORE macro): put this functionality into a
separate macro and then introduce a new macro with this name that
uses the old one but adds additional special-case checks for
timestamps that are 0, (comment to
meta_display_set_input_focus_window): add information about how
last_user_time should be used in this function
* src/display.c (santiy_check_timestamps): new function,
(meta_display_open): intialize display->last_user_time,
(meta_display_get_current_time_roundtrip): use the timestamp,
which is known to be good, in order to sanity_check_timestamps,
(event_callback): use the new meta_window_ste_user_time() function
in order to correct problems, use the timestamp of KeyPress and
ButtonPress events, which are known to be good, in order to
sanity_check_timestamps, (timestamp_too_old): new function for
common behavior of meta_display_focus_the_no_focus_window and
meta_display_set_input_focus_window, with added checking for
display->last_user_time in addition to display->last_focus_time,
(meta_display_set_input_focus_window): replace some of the code
with a call to timestamp_too_old(),
(meta_display_focus_the_no_focus_window): replace some of th ecode
with a call to timestamp_too_old()
* src/window.h: (meta_window_set_user_time): new function to
abstract the many things that need to be done when updating the
net_wm_user_time of any window
* src/window.c: (meta_window_activate): add debugging spew, make
sure the comparison is made with last_user_time NOT
last_focus_time, use meta_window_set_user_time() function in order
to correct problems, (meta_window_client_message): add a newline
to a debugging message to make them easier to read,
(meta_window_set_user_time): new function
* src/window-props.c (reload_net_wm_user_time): use the new
meta_window_ste_user_time() function in order to correct problems
2005-02-20 17:14:16 +00:00
|
|
|
}
|
2009-09-04 00:58:19 +00:00
|
|
|
|
Big patch to cover about 6 different issues in order to correct rare
2005-02-20 Elijah Newren <newren@gmail.com>
Big patch to cover about 6 different issues in order to correct
rare problems with timestamps (make sure window selected in
tasklist actually gets focus, sanity check timestamps to avoid
rogue apps hosing the system, correct the updating of
net_wm_user_time, correctly handle timestamps of 0 when comparing
xserver timestamps for those who have had their systems up for
over 25 days or so, add some debugging information to verbose
logs, some code cleanups). Fixes all issues listed in #167358.
* src/display.h: (struct _MetaDisplay): clarify comment on
last_focus_time, introduce a new variable--last_user_time,
(XSERVER_TIME_IS_BEFORE macro): put this functionality into a
separate macro and then introduce a new macro with this name that
uses the old one but adds additional special-case checks for
timestamps that are 0, (comment to
meta_display_set_input_focus_window): add information about how
last_user_time should be used in this function
* src/display.c (santiy_check_timestamps): new function,
(meta_display_open): intialize display->last_user_time,
(meta_display_get_current_time_roundtrip): use the timestamp,
which is known to be good, in order to sanity_check_timestamps,
(event_callback): use the new meta_window_ste_user_time() function
in order to correct problems, use the timestamp of KeyPress and
ButtonPress events, which are known to be good, in order to
sanity_check_timestamps, (timestamp_too_old): new function for
common behavior of meta_display_focus_the_no_focus_window and
meta_display_set_input_focus_window, with added checking for
display->last_user_time in addition to display->last_focus_time,
(meta_display_set_input_focus_window): replace some of the code
with a call to timestamp_too_old(),
(meta_display_focus_the_no_focus_window): replace some of th ecode
with a call to timestamp_too_old()
* src/window.h: (meta_window_set_user_time): new function to
abstract the many things that need to be done when updating the
net_wm_user_time of any window
* src/window.c: (meta_window_activate): add debugging spew, make
sure the comparison is made with last_user_time NOT
last_focus_time, use meta_window_set_user_time() function in order
to correct problems, (meta_window_client_message): add a newline
to a debugging message to make them easier to read,
(meta_window_set_user_time): new function
* src/window-props.c (reload_net_wm_user_time): use the new
meta_window_ste_user_time() function in order to correct problems
2005-02-20 17:14:16 +00:00
|
|
|
tmp = tmp->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_slist_free (windows);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-10-04 21:09:08 +00:00
|
|
|
void
|
|
|
|
meta_display_remove_autoraise_callback (MetaDisplay *display)
|
|
|
|
{
|
2019-11-21 23:25:30 +00:00
|
|
|
g_clear_handle_id (&display->autoraise_timeout_id, g_source_remove);
|
|
|
|
display->autoraise_window = NULL;
|
2004-10-04 21:09:08 +00:00
|
|
|
}
|
2008-05-19 00:00:09 +00:00
|
|
|
|
2008-12-02 23:13:11 +00:00
|
|
|
void
|
|
|
|
meta_display_overlay_key_activate (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
g_signal_emit (display, display_signals[OVERLAY_KEY], 0);
|
|
|
|
}
|
|
|
|
|
2012-08-28 13:28:11 +00:00
|
|
|
void
|
2022-04-13 09:38:08 +00:00
|
|
|
meta_display_accelerator_activate (MetaDisplay *display,
|
|
|
|
guint action,
|
|
|
|
const ClutterKeyEvent *event)
|
2012-08-28 13:28:11 +00:00
|
|
|
{
|
2019-07-08 14:23:26 +00:00
|
|
|
g_signal_emit (display, display_signals[ACCELERATOR_ACTIVATED], 0,
|
|
|
|
action,
|
2022-04-13 09:38:08 +00:00
|
|
|
clutter_event_get_source_device ((const ClutterEvent *) event),
|
2019-07-08 14:23:26 +00:00
|
|
|
event->time);
|
2012-08-28 13:28:11 +00:00
|
|
|
}
|
|
|
|
|
2013-04-10 11:34:26 +00:00
|
|
|
gboolean
|
|
|
|
meta_display_modifiers_accelerator_activate (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
gboolean freeze;
|
|
|
|
|
|
|
|
g_signal_emit (display, display_signals[MODIFIERS_ACCELERATOR_ACTIVATED], 0, &freeze);
|
|
|
|
|
|
|
|
return freeze;
|
|
|
|
}
|
|
|
|
|
2012-07-30 18:57:53 +00:00
|
|
|
/**
|
|
|
|
* meta_display_supports_extended_barriers:
|
|
|
|
* @display: a #MetaDisplay
|
|
|
|
*
|
2015-01-16 08:50:51 +00:00
|
|
|
* Returns: whether pointer barriers can be supported.
|
|
|
|
*
|
|
|
|
* When running as an X compositor the X server needs XInput 2
|
|
|
|
* version 2.3. When running as a display server it is supported
|
|
|
|
* when running on the native backend.
|
2012-07-30 18:57:53 +00:00
|
|
|
*
|
|
|
|
* Clients should use this method to determine whether their
|
|
|
|
* interfaces should depend on new barrier features.
|
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
meta_display_supports_extended_barriers (MetaDisplay *display)
|
|
|
|
{
|
2022-03-14 21:45:34 +00:00
|
|
|
MetaContext *context = meta_display_get_context (display);
|
|
|
|
MetaBackend *backend = meta_context_get_backend (context);
|
2015-01-16 08:50:51 +00:00
|
|
|
|
2022-03-14 21:45:34 +00:00
|
|
|
return !!(meta_backend_get_capabilities (backend) &
|
|
|
|
META_BACKEND_CAPABILITY_BARRIERS);
|
2012-07-30 18:57:53 +00:00
|
|
|
}
|
|
|
|
|
2021-03-03 15:05:09 +00:00
|
|
|
/**
|
|
|
|
* meta_display_get_context:
|
|
|
|
* @display: a #MetaDisplay
|
|
|
|
*
|
|
|
|
* Returns: (transfer none): the #MetaContext
|
|
|
|
*/
|
|
|
|
MetaContext *
|
|
|
|
meta_display_get_context (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
MetaDisplayPrivate *priv = meta_display_get_instance_private (display);
|
|
|
|
|
|
|
|
return priv->context;
|
|
|
|
}
|
|
|
|
|
2010-09-01 19:39:53 +00:00
|
|
|
/**
|
2022-09-07 16:25:09 +00:00
|
|
|
* meta_display_get_compositor:
|
2013-02-15 18:42:08 +00:00
|
|
|
* @display: a #MetaDisplay
|
2010-09-01 19:39:53 +00:00
|
|
|
*
|
2022-09-07 16:25:09 +00:00
|
|
|
* Returns: (transfer none): the #MetaCompositor
|
2010-09-01 19:39:53 +00:00
|
|
|
*/
|
2008-05-19 00:00:09 +00:00
|
|
|
MetaCompositor *
|
|
|
|
meta_display_get_compositor (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
return display->compositor;
|
|
|
|
}
|
|
|
|
|
2017-08-26 16:24:46 +00:00
|
|
|
/**
|
|
|
|
* meta_display_get_x11_display: (skip)
|
|
|
|
* @display: a #MetaDisplay
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
MetaX11Display *
|
|
|
|
meta_display_get_x11_display (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
return display->x11_display;
|
|
|
|
}
|
|
|
|
|
2017-08-26 16:37:29 +00:00
|
|
|
/**
|
|
|
|
* meta_display_get_size:
|
|
|
|
* @display: A #MetaDisplay
|
|
|
|
* @width: (out): The width of the screen
|
|
|
|
* @height: (out): The height of the screen
|
|
|
|
*
|
|
|
|
* Retrieve the size of the display.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
meta_display_get_size (MetaDisplay *display,
|
|
|
|
int *width,
|
|
|
|
int *height)
|
|
|
|
{
|
2022-05-27 20:27:07 +00:00
|
|
|
MetaBackend *backend = backend_from_display (display);
|
2017-08-27 18:44:38 +00:00
|
|
|
MetaMonitorManager *monitor_manager =
|
|
|
|
meta_backend_get_monitor_manager (backend);
|
|
|
|
int display_width, display_height;
|
|
|
|
|
|
|
|
meta_monitor_manager_get_screen_size (monitor_manager,
|
|
|
|
&display_width,
|
|
|
|
&display_height);
|
|
|
|
|
2017-08-26 16:37:29 +00:00
|
|
|
if (width != NULL)
|
2017-08-27 18:44:38 +00:00
|
|
|
*width = display_width;
|
2017-08-26 16:37:29 +00:00
|
|
|
|
|
|
|
if (height != NULL)
|
2017-08-27 18:44:38 +00:00
|
|
|
*height = display_height;
|
2017-08-26 16:37:29 +00:00
|
|
|
}
|
|
|
|
|
2008-11-17 21:34:28 +00:00
|
|
|
/**
|
|
|
|
* meta_display_get_focus_window:
|
|
|
|
* @display: a #MetaDisplay
|
|
|
|
*
|
2011-04-26 12:12:04 +00:00
|
|
|
* Get our best guess as to the "currently" focused window (that is,
|
|
|
|
* the window that we expect will be focused at the point when the X
|
|
|
|
* server processes our next request).
|
2008-11-17 21:34:28 +00:00
|
|
|
*
|
|
|
|
* Return Value: (transfer none): The current focus window
|
|
|
|
*/
|
2008-05-19 00:00:09 +00:00
|
|
|
MetaWindow *
|
|
|
|
meta_display_get_focus_window (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
return display->focus_window;
|
|
|
|
}
|
|
|
|
|
2012-04-14 13:12:48 +00:00
|
|
|
/**
|
|
|
|
* meta_display_clear_mouse_mode:
|
|
|
|
* @display: a #MetaDisplay
|
|
|
|
*
|
|
|
|
* Sets the mouse-mode flag to %FALSE, which means that motion events are
|
|
|
|
* no longer ignored in mouse or sloppy focus.
|
|
|
|
* This is an internal function. It should be used only for reimplementing
|
|
|
|
* keybindings, and only in a manner compatible with core code.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
meta_display_clear_mouse_mode (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
display->mouse_mode = FALSE;
|
|
|
|
}
|
2014-04-23 14:41:09 +00:00
|
|
|
|
2014-06-19 20:28:48 +00:00
|
|
|
MetaGestureTracker *
|
|
|
|
meta_display_get_gesture_tracker (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
return display->gesture_tracker;
|
|
|
|
}
|
2014-05-08 22:35:49 +00:00
|
|
|
|
|
|
|
gboolean
|
|
|
|
meta_display_show_restart_message (MetaDisplay *display,
|
|
|
|
const char *message)
|
|
|
|
{
|
|
|
|
gboolean result = FALSE;
|
|
|
|
|
|
|
|
g_signal_emit (display,
|
|
|
|
display_signals[SHOW_RESTART_MESSAGE], 0,
|
|
|
|
message, &result);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
meta_display_request_restart (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
gboolean result = FALSE;
|
|
|
|
|
|
|
|
g_signal_emit (display,
|
|
|
|
display_signals[RESTART], 0,
|
|
|
|
&result);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
2014-07-21 23:14:14 +00:00
|
|
|
|
2014-12-30 01:20:07 +00:00
|
|
|
gboolean
|
|
|
|
meta_display_show_resize_popup (MetaDisplay *display,
|
|
|
|
gboolean show,
|
|
|
|
MetaRectangle *rect,
|
|
|
|
int display_w,
|
|
|
|
int display_h)
|
|
|
|
{
|
|
|
|
gboolean result = FALSE;
|
|
|
|
|
|
|
|
g_signal_emit (display,
|
|
|
|
display_signals[SHOW_RESIZE_POPUP], 0,
|
|
|
|
show, rect, display_w, display_h, &result);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2014-07-21 23:14:14 +00:00
|
|
|
/**
|
|
|
|
* meta_display_is_pointer_emulating_sequence:
|
|
|
|
* @display: the display
|
|
|
|
* @sequence: (nullable): a #ClutterEventSequence
|
|
|
|
*
|
|
|
|
* Tells whether the event sequence is the used for pointer emulation
|
|
|
|
* and single-touch interaction.
|
|
|
|
*
|
|
|
|
* Returns: #TRUE if the sequence emulates pointer behavior
|
|
|
|
**/
|
|
|
|
gboolean
|
|
|
|
meta_display_is_pointer_emulating_sequence (MetaDisplay *display,
|
|
|
|
ClutterEventSequence *sequence)
|
|
|
|
{
|
|
|
|
if (!sequence)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
return display->pointer_emulating_sequence == sequence;
|
|
|
|
}
|
2014-09-11 14:09:43 +00:00
|
|
|
|
2016-06-22 17:17:40 +00:00
|
|
|
void
|
|
|
|
meta_display_request_pad_osd (MetaDisplay *display,
|
|
|
|
ClutterInputDevice *pad,
|
|
|
|
gboolean edition_mode)
|
|
|
|
{
|
2022-05-27 20:27:07 +00:00
|
|
|
MetaBackend *backend = backend_from_display (display);
|
2020-08-04 12:17:39 +00:00
|
|
|
MetaInputMapper *input_mapper;
|
2016-06-22 17:17:40 +00:00
|
|
|
const gchar *layout_path = NULL;
|
|
|
|
ClutterActor *osd;
|
2016-11-25 06:31:38 +00:00
|
|
|
MetaLogicalMonitor *logical_monitor;
|
2016-06-22 17:17:40 +00:00
|
|
|
GSettings *settings;
|
|
|
|
#ifdef HAVE_LIBWACOM
|
|
|
|
WacomDevice *wacom_device;
|
|
|
|
#endif
|
|
|
|
|
2016-10-17 16:02:50 +00:00
|
|
|
/* Avoid emitting the signal while there is an OSD being currently
|
|
|
|
* displayed, the first OSD will have to be dismissed before showing
|
|
|
|
* any other one.
|
|
|
|
*/
|
2016-06-22 17:17:40 +00:00
|
|
|
if (display->current_pad_osd)
|
2016-10-17 16:02:50 +00:00
|
|
|
return;
|
|
|
|
|
2022-05-27 20:27:07 +00:00
|
|
|
input_mapper = meta_backend_get_input_mapper (backend_from_display (display));
|
2016-06-22 17:17:40 +00:00
|
|
|
|
2020-08-04 12:17:39 +00:00
|
|
|
if (input_mapper)
|
2016-06-22 17:17:40 +00:00
|
|
|
{
|
2020-08-04 12:17:39 +00:00
|
|
|
settings = meta_input_mapper_get_tablet_settings (input_mapper, pad);
|
2016-11-25 06:31:38 +00:00
|
|
|
logical_monitor =
|
2020-08-04 12:17:39 +00:00
|
|
|
meta_input_mapper_get_device_logical_monitor (input_mapper, pad);
|
2016-06-22 17:17:40 +00:00
|
|
|
#ifdef HAVE_LIBWACOM
|
2020-03-06 13:53:45 +00:00
|
|
|
wacom_device = meta_input_device_get_wacom_device (META_INPUT_DEVICE (pad));
|
2016-06-22 17:17:40 +00:00
|
|
|
layout_path = libwacom_get_layout_filename (wacom_device);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!layout_path || !settings)
|
|
|
|
return;
|
|
|
|
|
2016-12-01 04:55:21 +00:00
|
|
|
if (!logical_monitor)
|
2016-12-01 04:59:47 +00:00
|
|
|
logical_monitor = meta_backend_get_current_logical_monitor (backend);
|
2016-06-22 17:17:40 +00:00
|
|
|
|
|
|
|
g_signal_emit (display, display_signals[SHOW_PAD_OSD], 0,
|
|
|
|
pad, settings, layout_path,
|
2016-12-01 04:55:21 +00:00
|
|
|
edition_mode, logical_monitor->number, &osd);
|
2016-06-22 17:17:40 +00:00
|
|
|
|
|
|
|
if (osd)
|
|
|
|
{
|
|
|
|
display->current_pad_osd = osd;
|
|
|
|
g_object_add_weak_pointer (G_OBJECT (display->current_pad_osd),
|
|
|
|
(gpointer *) &display->current_pad_osd);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-22 17:10:13 +00:00
|
|
|
gchar *
|
|
|
|
meta_display_get_pad_action_label (MetaDisplay *display,
|
|
|
|
ClutterInputDevice *pad,
|
2023-05-16 09:24:21 +00:00
|
|
|
MetaPadFeatureType feature,
|
2016-06-22 17:10:13 +00:00
|
|
|
guint action_number)
|
|
|
|
{
|
|
|
|
gchar *label;
|
|
|
|
|
|
|
|
/* First, lookup the action, as imposed by settings */
|
2020-07-15 20:38:00 +00:00
|
|
|
label = meta_pad_action_mapper_get_action_label (display->pad_action_mapper,
|
2023-05-16 09:24:21 +00:00
|
|
|
pad, feature,
|
2020-07-15 20:38:00 +00:00
|
|
|
action_number);
|
2017-07-05 11:35:31 +00:00
|
|
|
if (label)
|
|
|
|
return label;
|
2016-06-22 17:10:13 +00:00
|
|
|
|
|
|
|
#ifdef HAVE_WAYLAND
|
|
|
|
/* Second, if this wayland, lookup the actions set by the clients */
|
|
|
|
if (meta_is_wayland_compositor ())
|
|
|
|
{
|
|
|
|
MetaWaylandCompositor *compositor;
|
|
|
|
MetaWaylandTabletSeat *tablet_seat;
|
|
|
|
MetaWaylandTabletPad *tablet_pad = NULL;
|
|
|
|
|
2022-05-27 20:27:07 +00:00
|
|
|
compositor = wayland_compositor_from_display (display);
|
2016-06-22 17:10:13 +00:00
|
|
|
tablet_seat = meta_wayland_tablet_manager_ensure_seat (compositor->tablet_manager,
|
|
|
|
compositor->seat);
|
|
|
|
if (tablet_seat)
|
|
|
|
tablet_pad = meta_wayland_tablet_seat_lookup_pad (tablet_seat, pad);
|
|
|
|
|
|
|
|
if (tablet_pad)
|
|
|
|
{
|
2023-05-16 09:24:21 +00:00
|
|
|
label = meta_wayland_tablet_pad_get_label (tablet_pad, feature,
|
2016-06-22 17:10:13 +00:00
|
|
|
action_number);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (label)
|
|
|
|
return label;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
2016-12-28 11:03:29 +00:00
|
|
|
|
|
|
|
static void
|
|
|
|
meta_display_show_osd (MetaDisplay *display,
|
|
|
|
gint monitor_idx,
|
|
|
|
const gchar *icon_name,
|
|
|
|
const gchar *message)
|
|
|
|
{
|
|
|
|
g_signal_emit (display, display_signals[SHOW_OSD], 0,
|
|
|
|
monitor_idx, icon_name, message);
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
|
|
lookup_tablet_monitor (MetaDisplay *display,
|
|
|
|
ClutterInputDevice *device)
|
|
|
|
{
|
2020-08-04 12:17:39 +00:00
|
|
|
MetaInputMapper *input_mapper;
|
2016-12-28 11:03:29 +00:00
|
|
|
MetaLogicalMonitor *monitor;
|
|
|
|
gint monitor_idx = -1;
|
|
|
|
|
2022-05-27 20:27:07 +00:00
|
|
|
input_mapper = meta_backend_get_input_mapper (backend_from_display (display));
|
2020-08-04 12:17:39 +00:00
|
|
|
if (!input_mapper)
|
2016-12-28 11:03:29 +00:00
|
|
|
return -1;
|
|
|
|
|
2020-08-04 12:17:39 +00:00
|
|
|
monitor = meta_input_mapper_get_device_logical_monitor (input_mapper, device);
|
2016-12-28 11:03:29 +00:00
|
|
|
|
|
|
|
if (monitor)
|
|
|
|
{
|
2017-08-26 19:22:34 +00:00
|
|
|
monitor_idx = meta_display_get_monitor_index_for_rect (display,
|
|
|
|
&monitor->rect);
|
2016-12-28 11:03:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return monitor_idx;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
meta_display_show_tablet_mapping_notification (MetaDisplay *display,
|
|
|
|
ClutterInputDevice *pad,
|
|
|
|
const gchar *pretty_name)
|
|
|
|
{
|
|
|
|
if (!pretty_name)
|
|
|
|
pretty_name = clutter_input_device_get_device_name (pad);
|
|
|
|
meta_display_show_osd (display, lookup_tablet_monitor (display, pad),
|
|
|
|
"input-tablet-symbolic", pretty_name);
|
|
|
|
}
|
2016-12-28 11:10:23 +00:00
|
|
|
|
|
|
|
void
|
|
|
|
meta_display_notify_pad_group_switch (MetaDisplay *display,
|
|
|
|
ClutterInputDevice *pad,
|
|
|
|
const gchar *pretty_name,
|
|
|
|
guint n_group,
|
|
|
|
guint n_mode,
|
|
|
|
guint n_modes)
|
|
|
|
{
|
|
|
|
GString *message;
|
|
|
|
guint i;
|
|
|
|
|
|
|
|
if (!pretty_name)
|
|
|
|
pretty_name = clutter_input_device_get_device_name (pad);
|
|
|
|
|
|
|
|
message = g_string_new (pretty_name);
|
2021-10-27 11:04:15 +00:00
|
|
|
g_string_append (message, "\n\n");
|
2016-12-28 11:10:23 +00:00
|
|
|
for (i = 0; i < n_modes; i++)
|
2021-10-27 11:04:15 +00:00
|
|
|
{
|
|
|
|
if (i > 0)
|
|
|
|
g_string_append_c (message, ' ');
|
|
|
|
g_string_append (message, (i == n_mode) ? "●" : "○");
|
|
|
|
}
|
2016-12-28 11:10:23 +00:00
|
|
|
|
|
|
|
meta_display_show_osd (display, lookup_tablet_monitor (display, pad),
|
|
|
|
"input-tablet-symbolic", message->str);
|
|
|
|
|
2016-12-28 12:00:18 +00:00
|
|
|
g_signal_emit (display, display_signals[PAD_MODE_SWITCH], 0, pad,
|
|
|
|
n_group, n_mode);
|
|
|
|
|
2016-12-28 11:10:23 +00:00
|
|
|
g_string_free (message, TRUE);
|
|
|
|
}
|
2017-08-26 16:37:29 +00:00
|
|
|
|
|
|
|
void
|
|
|
|
meta_display_foreach_window (MetaDisplay *display,
|
|
|
|
MetaListWindowsFlags flags,
|
|
|
|
MetaDisplayWindowFunc func,
|
|
|
|
gpointer data)
|
|
|
|
{
|
|
|
|
GSList *windows;
|
|
|
|
|
|
|
|
/* If we end up doing this often, just keeping a list
|
|
|
|
* of windows might be sensible.
|
|
|
|
*/
|
|
|
|
|
|
|
|
windows = meta_display_list_windows (display, flags);
|
|
|
|
|
|
|
|
g_slist_foreach (windows, (GFunc) func, data);
|
|
|
|
|
|
|
|
g_slist_free (windows);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
meta_display_resize_func (MetaWindow *window,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
if (window->struts)
|
|
|
|
{
|
|
|
|
meta_window_update_struts (window);
|
|
|
|
}
|
|
|
|
meta_window_queue (window, META_QUEUE_MOVE_RESIZE);
|
|
|
|
|
|
|
|
meta_window_recalc_features (window);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
on_monitors_changed_internal (MetaMonitorManager *monitor_manager,
|
|
|
|
MetaDisplay *display)
|
|
|
|
{
|
2017-08-27 19:02:40 +00:00
|
|
|
meta_workspace_manager_reload_work_areas (display->workspace_manager);
|
2017-08-26 19:39:46 +00:00
|
|
|
|
2017-08-26 16:37:29 +00:00
|
|
|
/* Fix up monitor for all windows on this display */
|
|
|
|
meta_display_foreach_window (display, META_LIST_INCLUDE_OVERRIDE_REDIRECT,
|
|
|
|
(MetaDisplayWindowFunc)
|
|
|
|
meta_window_update_for_monitors_changed, 0);
|
|
|
|
|
|
|
|
/* Queue a resize on all the windows */
|
|
|
|
meta_display_foreach_window (display, META_LIST_DEFAULT,
|
|
|
|
meta_display_resize_func, 0);
|
|
|
|
|
2017-08-26 19:10:38 +00:00
|
|
|
meta_display_queue_check_fullscreen (display);
|
2017-08-26 16:37:29 +00:00
|
|
|
}
|
|
|
|
|
2017-08-26 17:03:51 +00:00
|
|
|
void
|
|
|
|
meta_display_restacked (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
g_signal_emit (display, display_signals[RESTACKED], 0);
|
|
|
|
}
|
2017-08-26 19:10:38 +00:00
|
|
|
|
2018-08-25 11:21:43 +00:00
|
|
|
static MetaStartupSequence *
|
|
|
|
find_startup_sequence_by_wmclass (MetaDisplay *display,
|
|
|
|
MetaWindow *window)
|
|
|
|
{
|
|
|
|
GSList *startup_sequences, *l;
|
|
|
|
|
|
|
|
startup_sequences =
|
|
|
|
meta_startup_notification_get_sequences (display->startup_notification);
|
|
|
|
|
|
|
|
for (l = startup_sequences; l; l = l->next)
|
|
|
|
{
|
|
|
|
MetaStartupSequence *sequence = l->data;
|
|
|
|
const char *wmclass;
|
|
|
|
|
|
|
|
wmclass = meta_startup_sequence_get_wmclass (sequence);
|
|
|
|
|
|
|
|
if (wmclass != NULL &&
|
|
|
|
((window->res_class &&
|
|
|
|
strcmp (wmclass, window->res_class) == 0) ||
|
|
|
|
(window->res_name &&
|
|
|
|
strcmp (wmclass, window->res_name) == 0)))
|
|
|
|
return sequence;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2017-08-26 19:10:38 +00:00
|
|
|
/* Sets the initial_timestamp and initial_workspace properties
|
|
|
|
* of a window according to information given us by the
|
|
|
|
* startup-notification library.
|
|
|
|
*
|
|
|
|
* Returns TRUE if startup properties have been applied, and
|
|
|
|
* FALSE if they have not (for example, if they had already
|
|
|
|
* been applied.)
|
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
meta_display_apply_startup_properties (MetaDisplay *display,
|
|
|
|
MetaWindow *window)
|
|
|
|
{
|
|
|
|
const char *startup_id;
|
2018-08-25 11:21:43 +00:00
|
|
|
MetaStartupSequence *sequence = NULL;
|
2017-08-26 19:10:38 +00:00
|
|
|
|
|
|
|
/* Does the window have a startup ID stored? */
|
|
|
|
startup_id = meta_window_get_startup_id (window);
|
|
|
|
|
|
|
|
meta_topic (META_DEBUG_STARTUP,
|
2020-10-02 15:47:22 +00:00
|
|
|
"Applying startup props to %s id \"%s\"",
|
2017-08-26 19:10:38 +00:00
|
|
|
window->desc,
|
|
|
|
startup_id ? startup_id : "(none)");
|
|
|
|
|
|
|
|
if (!startup_id)
|
|
|
|
{
|
|
|
|
/* No startup ID stored for the window. Let's ask the
|
|
|
|
* startup-notification library whether there's anything
|
|
|
|
* stored for the resource name or resource class hints.
|
|
|
|
*/
|
2018-08-25 11:21:43 +00:00
|
|
|
sequence = find_startup_sequence_by_wmclass (display, window);
|
2017-08-26 19:10:38 +00:00
|
|
|
|
2018-08-25 11:21:43 +00:00
|
|
|
if (sequence)
|
|
|
|
{
|
|
|
|
g_assert (window->startup_id == NULL);
|
|
|
|
window->startup_id = g_strdup (meta_startup_sequence_get_id (sequence));
|
|
|
|
startup_id = window->startup_id;
|
2017-08-26 19:10:38 +00:00
|
|
|
|
2018-08-25 11:21:43 +00:00
|
|
|
meta_topic (META_DEBUG_STARTUP,
|
2020-10-02 15:47:22 +00:00
|
|
|
"Ending legacy sequence %s due to window %s",
|
2018-08-25 11:21:43 +00:00
|
|
|
meta_startup_sequence_get_id (sequence),
|
|
|
|
window->desc);
|
2017-08-26 19:10:38 +00:00
|
|
|
|
2018-08-25 11:21:43 +00:00
|
|
|
meta_startup_sequence_complete (sequence);
|
2017-08-26 19:10:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Still no startup ID? Bail. */
|
|
|
|
if (!startup_id)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
/* We might get this far and not know the sequence ID (if the window
|
|
|
|
* already had a startup ID stored), so let's look for one if we don't
|
|
|
|
* already know it.
|
|
|
|
*/
|
|
|
|
if (sequence == NULL)
|
|
|
|
{
|
2018-08-25 11:21:43 +00:00
|
|
|
sequence =
|
|
|
|
meta_startup_notification_lookup_sequence (display->startup_notification,
|
|
|
|
startup_id);
|
2017-08-26 19:10:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (sequence != NULL)
|
|
|
|
{
|
|
|
|
gboolean changed_something = FALSE;
|
|
|
|
|
|
|
|
meta_topic (META_DEBUG_STARTUP,
|
2020-10-02 15:47:22 +00:00
|
|
|
"Found startup sequence for window %s ID \"%s\"",
|
2017-08-26 19:10:38 +00:00
|
|
|
window->desc, startup_id);
|
|
|
|
|
|
|
|
if (!window->initial_workspace_set)
|
|
|
|
{
|
2018-08-22 21:33:03 +00:00
|
|
|
int space = meta_startup_sequence_get_workspace (sequence);
|
2017-08-26 19:10:38 +00:00
|
|
|
if (space >= 0)
|
|
|
|
{
|
|
|
|
meta_topic (META_DEBUG_STARTUP,
|
2020-10-02 15:47:22 +00:00
|
|
|
"Setting initial window workspace to %d based on startup info",
|
2017-08-26 19:10:38 +00:00
|
|
|
space);
|
|
|
|
|
|
|
|
window->initial_workspace_set = TRUE;
|
|
|
|
window->initial_workspace = space;
|
|
|
|
changed_something = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!window->initial_timestamp_set)
|
|
|
|
{
|
2018-08-22 21:33:03 +00:00
|
|
|
guint32 timestamp = meta_startup_sequence_get_timestamp (sequence);
|
2017-08-26 19:10:38 +00:00
|
|
|
meta_topic (META_DEBUG_STARTUP,
|
2020-10-02 15:47:22 +00:00
|
|
|
"Setting initial window timestamp to %u based on startup info",
|
2017-08-26 19:10:38 +00:00
|
|
|
timestamp);
|
|
|
|
|
|
|
|
window->initial_timestamp_set = TRUE;
|
|
|
|
window->initial_timestamp = timestamp;
|
|
|
|
changed_something = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return changed_something;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
meta_topic (META_DEBUG_STARTUP,
|
2020-10-02 15:47:22 +00:00
|
|
|
"Did not find startup sequence for window %s ID \"%s\"",
|
2017-08-26 19:10:38 +00:00
|
|
|
window->desc, startup_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
set_work_area_later_func (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
meta_topic (META_DEBUG_WORKAREA,
|
2020-10-02 15:47:22 +00:00
|
|
|
"Running work area hint computation function");
|
2017-08-26 19:10:38 +00:00
|
|
|
|
|
|
|
display->work_area_later = 0;
|
|
|
|
|
2017-08-26 20:41:16 +00:00
|
|
|
g_signal_emit (display, display_signals[WORKAREAS_CHANGED], 0);
|
2017-08-26 19:10:38 +00:00
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
meta_display_queue_workarea_recalc (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
/* Recompute work area later before redrawing */
|
|
|
|
if (display->work_area_later == 0)
|
|
|
|
{
|
2022-05-30 21:16:16 +00:00
|
|
|
MetaLaters *laters = meta_compositor_get_laters (display->compositor);
|
|
|
|
|
2017-08-26 19:10:38 +00:00
|
|
|
meta_topic (META_DEBUG_WORKAREA,
|
2020-10-02 15:47:22 +00:00
|
|
|
"Adding work area hint computation function");
|
2017-08-26 19:10:38 +00:00
|
|
|
display->work_area_later =
|
2022-05-30 21:16:16 +00:00
|
|
|
meta_laters_add (laters, META_LATER_BEFORE_REDRAW,
|
|
|
|
(GSourceFunc) set_work_area_later_func,
|
|
|
|
display,
|
|
|
|
NULL);
|
2017-08-26 19:10:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
check_fullscreen_func (gpointer data)
|
|
|
|
{
|
|
|
|
MetaDisplay *display = data;
|
2022-05-27 20:27:07 +00:00
|
|
|
MetaBackend *backend = backend_from_display (display);
|
2017-08-26 19:10:38 +00:00
|
|
|
MetaMonitorManager *monitor_manager =
|
|
|
|
meta_backend_get_monitor_manager (backend);
|
|
|
|
GList *logical_monitors, *l;
|
|
|
|
MetaWindow *window;
|
|
|
|
GSList *fullscreen_monitors = NULL;
|
|
|
|
GSList *obscured_monitors = NULL;
|
|
|
|
gboolean in_fullscreen_changed = FALSE;
|
|
|
|
|
|
|
|
display->check_fullscreen_later = 0;
|
|
|
|
|
|
|
|
logical_monitors =
|
|
|
|
meta_monitor_manager_get_logical_monitors (monitor_manager);
|
|
|
|
|
|
|
|
/* We consider a monitor in fullscreen if it contains a fullscreen window;
|
|
|
|
* however we make an exception for maximized windows above the fullscreen
|
|
|
|
* one, as in that case window+chrome fully obscure the fullscreen window.
|
|
|
|
*/
|
|
|
|
for (window = meta_stack_get_top (display->stack);
|
|
|
|
window;
|
|
|
|
window = meta_stack_get_below (display->stack, window, FALSE))
|
|
|
|
{
|
|
|
|
gboolean covers_monitors = FALSE;
|
|
|
|
|
|
|
|
if (window->hidden)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (window->fullscreen)
|
|
|
|
{
|
|
|
|
covers_monitors = TRUE;
|
|
|
|
}
|
|
|
|
else if (window->override_redirect)
|
|
|
|
{
|
|
|
|
/* We want to handle the case where an application is creating an
|
|
|
|
* override-redirect window the size of the screen (monitor) and treat
|
|
|
|
* it similarly to a fullscreen window, though it doesn't have fullscreen
|
|
|
|
* window management behavior. (Being O-R, it's not managed at all.)
|
|
|
|
*/
|
|
|
|
if (meta_window_is_monitor_sized (window))
|
|
|
|
covers_monitors = TRUE;
|
|
|
|
}
|
|
|
|
else if (window->maximized_horizontally &&
|
|
|
|
window->maximized_vertically)
|
|
|
|
{
|
|
|
|
MetaLogicalMonitor *logical_monitor;
|
|
|
|
|
|
|
|
logical_monitor = meta_window_get_main_logical_monitor (window);
|
|
|
|
if (!g_slist_find (obscured_monitors, logical_monitor))
|
|
|
|
obscured_monitors = g_slist_prepend (obscured_monitors,
|
|
|
|
logical_monitor);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (covers_monitors)
|
|
|
|
{
|
|
|
|
MetaRectangle window_rect;
|
|
|
|
|
|
|
|
meta_window_get_frame_rect (window, &window_rect);
|
|
|
|
|
|
|
|
for (l = logical_monitors; l; l = l->next)
|
|
|
|
{
|
|
|
|
MetaLogicalMonitor *logical_monitor = l->data;
|
|
|
|
|
|
|
|
if (meta_rectangle_overlap (&window_rect,
|
|
|
|
&logical_monitor->rect) &&
|
|
|
|
!g_slist_find (fullscreen_monitors, logical_monitor) &&
|
|
|
|
!g_slist_find (obscured_monitors, logical_monitor))
|
|
|
|
fullscreen_monitors = g_slist_prepend (fullscreen_monitors,
|
|
|
|
logical_monitor);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
g_slist_free (obscured_monitors);
|
|
|
|
|
|
|
|
for (l = logical_monitors; l; l = l->next)
|
|
|
|
{
|
|
|
|
MetaLogicalMonitor *logical_monitor = l->data;
|
|
|
|
gboolean in_fullscreen;
|
|
|
|
|
|
|
|
in_fullscreen = g_slist_find (fullscreen_monitors,
|
|
|
|
logical_monitor) != NULL;
|
|
|
|
if (in_fullscreen != logical_monitor->in_fullscreen)
|
|
|
|
{
|
|
|
|
logical_monitor->in_fullscreen = in_fullscreen;
|
|
|
|
in_fullscreen_changed = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
g_slist_free (fullscreen_monitors);
|
|
|
|
|
|
|
|
if (in_fullscreen_changed)
|
|
|
|
{
|
|
|
|
/* DOCK window stacking depends on the monitor's fullscreen
|
|
|
|
status so we need to trigger a re-layering. */
|
|
|
|
MetaWindow *window = meta_stack_get_top (display->stack);
|
|
|
|
if (window)
|
|
|
|
meta_stack_update_layer (display->stack, window);
|
|
|
|
|
|
|
|
g_signal_emit (display, display_signals[IN_FULLSCREEN_CHANGED], 0, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
meta_display_queue_check_fullscreen (MetaDisplay *display)
|
|
|
|
{
|
2022-05-30 21:16:16 +00:00
|
|
|
MetaLaters *laters;
|
|
|
|
|
|
|
|
if (display->check_fullscreen_later)
|
|
|
|
return;
|
|
|
|
|
|
|
|
laters = meta_compositor_get_laters (display->compositor);
|
|
|
|
display->check_fullscreen_later = meta_laters_add (laters,
|
|
|
|
META_LATER_CHECK_FULLSCREEN,
|
|
|
|
check_fullscreen_func,
|
|
|
|
display, NULL);
|
2017-08-26 19:10:38 +00:00
|
|
|
}
|
2017-08-26 19:22:34 +00:00
|
|
|
|
|
|
|
int
|
|
|
|
meta_display_get_monitor_index_for_rect (MetaDisplay *display,
|
|
|
|
MetaRectangle *rect)
|
|
|
|
{
|
2022-05-27 20:27:07 +00:00
|
|
|
MetaBackend *backend = backend_from_display (display);
|
2017-08-26 19:22:34 +00:00
|
|
|
MetaMonitorManager *monitor_manager =
|
|
|
|
meta_backend_get_monitor_manager (backend);
|
|
|
|
MetaLogicalMonitor *logical_monitor;
|
|
|
|
|
|
|
|
logical_monitor =
|
|
|
|
meta_monitor_manager_get_logical_monitor_from_rect (monitor_manager, rect);
|
|
|
|
if (!logical_monitor)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
return logical_monitor->number;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
meta_display_get_monitor_neighbor_index (MetaDisplay *display,
|
|
|
|
int which_monitor,
|
|
|
|
MetaDisplayDirection direction)
|
|
|
|
{
|
2022-05-27 20:27:07 +00:00
|
|
|
MetaBackend *backend = backend_from_display (display);
|
2017-08-26 19:22:34 +00:00
|
|
|
MetaMonitorManager *monitor_manager =
|
|
|
|
meta_backend_get_monitor_manager (backend);
|
|
|
|
MetaLogicalMonitor *logical_monitor;
|
|
|
|
MetaLogicalMonitor *neighbor;
|
|
|
|
|
|
|
|
logical_monitor =
|
|
|
|
meta_monitor_manager_get_logical_monitor_from_number (monitor_manager,
|
|
|
|
which_monitor);
|
|
|
|
neighbor = meta_monitor_manager_get_logical_monitor_neighbor (monitor_manager,
|
|
|
|
logical_monitor,
|
|
|
|
direction);
|
|
|
|
return neighbor ? neighbor->number : -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* meta_display_get_current_monitor:
|
|
|
|
* @display: a #MetaDisplay
|
|
|
|
*
|
|
|
|
* Gets the index of the monitor that currently has the mouse pointer.
|
|
|
|
*
|
|
|
|
* Return value: a monitor index
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
meta_display_get_current_monitor (MetaDisplay *display)
|
|
|
|
{
|
2022-05-27 20:27:07 +00:00
|
|
|
MetaBackend *backend = backend_from_display (display);
|
2017-08-26 19:22:34 +00:00
|
|
|
MetaLogicalMonitor *logical_monitor;
|
|
|
|
|
|
|
|
logical_monitor = meta_backend_get_current_logical_monitor (backend);
|
|
|
|
|
|
|
|
/* Pretend its the first when there is no actual current monitor. */
|
|
|
|
if (!logical_monitor)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
return logical_monitor->number;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* meta_display_get_n_monitors:
|
|
|
|
* @display: a #MetaDisplay
|
|
|
|
*
|
|
|
|
* Gets the number of monitors that are joined together to form @display.
|
|
|
|
*
|
|
|
|
* Return value: the number of monitors
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
meta_display_get_n_monitors (MetaDisplay *display)
|
|
|
|
{
|
2022-05-27 20:27:07 +00:00
|
|
|
MetaBackend *backend = backend_from_display (display);
|
2017-08-26 19:22:34 +00:00
|
|
|
MetaMonitorManager *monitor_manager =
|
|
|
|
meta_backend_get_monitor_manager (backend);
|
|
|
|
|
|
|
|
g_return_val_if_fail (META_IS_DISPLAY (display), 0);
|
|
|
|
|
|
|
|
return meta_monitor_manager_get_num_logical_monitors (monitor_manager);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* meta_display_get_primary_monitor:
|
|
|
|
* @display: a #MetaDisplay
|
|
|
|
*
|
|
|
|
* Gets the index of the primary monitor on this @display.
|
|
|
|
*
|
|
|
|
* Return value: a monitor index
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
meta_display_get_primary_monitor (MetaDisplay *display)
|
|
|
|
{
|
2022-05-27 20:27:07 +00:00
|
|
|
MetaBackend *backend = backend_from_display (display);
|
2017-08-26 19:22:34 +00:00
|
|
|
MetaMonitorManager *monitor_manager =
|
|
|
|
meta_backend_get_monitor_manager (backend);
|
|
|
|
MetaLogicalMonitor *logical_monitor;
|
|
|
|
|
|
|
|
g_return_val_if_fail (META_IS_DISPLAY (display), 0);
|
|
|
|
|
|
|
|
logical_monitor =
|
|
|
|
meta_monitor_manager_get_primary_logical_monitor (monitor_manager);
|
|
|
|
if (logical_monitor)
|
|
|
|
return logical_monitor->number;
|
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* meta_display_get_monitor_geometry:
|
|
|
|
* @display: a #MetaDisplay
|
|
|
|
* @monitor: the monitor number
|
|
|
|
* @geometry: (out): location to store the monitor geometry
|
|
|
|
*
|
2017-08-01 22:57:46 +00:00
|
|
|
* Stores the location and size of the indicated @monitor in @geometry.
|
2017-08-26 19:22:34 +00:00
|
|
|
*/
|
|
|
|
void
|
|
|
|
meta_display_get_monitor_geometry (MetaDisplay *display,
|
|
|
|
int monitor,
|
|
|
|
MetaRectangle *geometry)
|
|
|
|
{
|
2022-05-27 20:27:07 +00:00
|
|
|
MetaBackend *backend = backend_from_display (display);
|
2017-08-26 19:22:34 +00:00
|
|
|
MetaMonitorManager *monitor_manager =
|
|
|
|
meta_backend_get_monitor_manager (backend);
|
|
|
|
MetaLogicalMonitor *logical_monitor;
|
|
|
|
#ifndef G_DISABLE_CHECKS
|
|
|
|
int n_logical_monitors =
|
|
|
|
meta_monitor_manager_get_num_logical_monitors (monitor_manager);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
g_return_if_fail (META_IS_DISPLAY (display));
|
|
|
|
g_return_if_fail (monitor >= 0 && monitor < n_logical_monitors);
|
|
|
|
g_return_if_fail (geometry != NULL);
|
|
|
|
|
|
|
|
logical_monitor =
|
|
|
|
meta_monitor_manager_get_logical_monitor_from_number (monitor_manager,
|
|
|
|
monitor);
|
|
|
|
*geometry = logical_monitor->rect;
|
|
|
|
}
|
|
|
|
|
2017-08-01 18:38:41 +00:00
|
|
|
/**
|
|
|
|
* meta_display_get_monitor_scale:
|
|
|
|
* @display: a #MetaDisplay
|
|
|
|
* @monitor: the monitor number
|
|
|
|
*
|
|
|
|
* Gets the monitor scaling value for the given @monitor.
|
|
|
|
*
|
|
|
|
* Return value: the monitor scaling value
|
|
|
|
*/
|
|
|
|
float
|
|
|
|
meta_display_get_monitor_scale (MetaDisplay *display,
|
|
|
|
int monitor)
|
|
|
|
{
|
2022-05-27 20:27:07 +00:00
|
|
|
MetaBackend *backend = backend_from_display (display);
|
2017-08-01 18:38:41 +00:00
|
|
|
MetaMonitorManager *monitor_manager =
|
|
|
|
meta_backend_get_monitor_manager (backend);
|
|
|
|
MetaLogicalMonitor *logical_monitor;
|
|
|
|
#ifndef G_DISABLE_CHECKS
|
|
|
|
int n_logical_monitors =
|
|
|
|
meta_monitor_manager_get_num_logical_monitors (monitor_manager);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
g_return_val_if_fail (META_IS_DISPLAY (display), 1.0f);
|
|
|
|
g_return_val_if_fail (monitor >= 0 && monitor < n_logical_monitors, 1.0f);
|
|
|
|
|
|
|
|
logical_monitor =
|
|
|
|
meta_monitor_manager_get_logical_monitor_from_number (monitor_manager,
|
|
|
|
monitor);
|
|
|
|
return logical_monitor->scale;
|
|
|
|
}
|
|
|
|
|
2017-08-26 19:22:34 +00:00
|
|
|
/**
|
|
|
|
* meta_display_get_monitor_in_fullscreen:
|
|
|
|
* @display: a #MetaDisplay
|
|
|
|
* @monitor: the monitor number
|
|
|
|
*
|
|
|
|
* Determines whether there is a fullscreen window obscuring the specified
|
|
|
|
* monitor. If there is a fullscreen window, the desktop environment will
|
|
|
|
* typically hide any controls that might obscure the fullscreen window.
|
|
|
|
*
|
|
|
|
* You can get notification when this changes by connecting to
|
|
|
|
* MetaDisplay::in-fullscreen-changed.
|
|
|
|
*
|
|
|
|
* Returns: %TRUE if there is a fullscreen window covering the specified monitor.
|
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
meta_display_get_monitor_in_fullscreen (MetaDisplay *display,
|
|
|
|
int monitor)
|
|
|
|
{
|
2022-05-27 20:27:07 +00:00
|
|
|
MetaBackend *backend = backend_from_display (display);
|
2017-08-26 19:22:34 +00:00
|
|
|
MetaMonitorManager *monitor_manager =
|
|
|
|
meta_backend_get_monitor_manager (backend);
|
|
|
|
MetaLogicalMonitor *logical_monitor;
|
|
|
|
#ifndef G_DISABLE_CHECKS
|
|
|
|
int n_logical_monitors =
|
|
|
|
meta_monitor_manager_get_num_logical_monitors (monitor_manager);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
g_return_val_if_fail (META_IS_DISPLAY (display), FALSE);
|
|
|
|
g_return_val_if_fail (monitor >= 0 &&
|
|
|
|
monitor < n_logical_monitors, FALSE);
|
|
|
|
|
|
|
|
logical_monitor =
|
|
|
|
meta_monitor_manager_get_logical_monitor_from_number (monitor_manager,
|
|
|
|
monitor);
|
|
|
|
|
|
|
|
/* We use -1 as a flag to mean "not known yet" for notification
|
|
|
|
purposes */ return logical_monitor->in_fullscreen == TRUE;
|
|
|
|
}
|
2017-08-26 19:35:28 +00:00
|
|
|
|
2017-08-26 19:39:46 +00:00
|
|
|
void
|
|
|
|
meta_display_focus_default_window (MetaDisplay *display,
|
|
|
|
guint32 timestamp)
|
|
|
|
{
|
2017-08-27 19:02:40 +00:00
|
|
|
MetaWorkspaceManager *workspace_manager = display->workspace_manager;
|
|
|
|
|
|
|
|
meta_workspace_focus_default_window (workspace_manager->active_workspace,
|
2017-08-26 19:39:46 +00:00
|
|
|
NULL,
|
|
|
|
timestamp);
|
|
|
|
}
|
|
|
|
|
2018-01-03 05:09:41 +00:00
|
|
|
/**
|
|
|
|
* meta_display_get_workspace_manager:
|
|
|
|
* @display: a #MetaDisplay
|
|
|
|
*
|
2018-07-16 14:25:20 +00:00
|
|
|
* Returns: (transfer none): The workspace manager of the display
|
2018-01-03 05:09:41 +00:00
|
|
|
*/
|
2017-08-27 18:52:42 +00:00
|
|
|
MetaWorkspaceManager *
|
|
|
|
meta_display_get_workspace_manager (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
return display->workspace_manager;
|
|
|
|
}
|
2018-08-22 20:56:18 +00:00
|
|
|
|
|
|
|
MetaStartupNotification *
|
|
|
|
meta_display_get_startup_notification (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
return display->startup_notification;
|
|
|
|
}
|
2018-09-21 15:49:36 +00:00
|
|
|
|
|
|
|
MetaWindow *
|
|
|
|
meta_display_get_window_from_id (MetaDisplay *display,
|
|
|
|
uint64_t window_id)
|
|
|
|
{
|
|
|
|
g_autoptr (GSList) windows = NULL;
|
|
|
|
GSList *l;
|
|
|
|
|
|
|
|
windows = meta_display_list_windows (display, META_LIST_DEFAULT);
|
|
|
|
for (l = windows; l; l = l->next)
|
|
|
|
{
|
|
|
|
MetaWindow *window = l->data;
|
|
|
|
|
|
|
|
if (window->id == window_id)
|
|
|
|
return window;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t
|
|
|
|
meta_display_generate_window_id (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
static uint64_t base_window_id;
|
|
|
|
static uint64_t last_window_id;
|
|
|
|
|
|
|
|
if (!base_window_id)
|
|
|
|
base_window_id = g_random_int () + 1;
|
|
|
|
|
|
|
|
/* We can overflow here, that's fine */
|
|
|
|
return (base_window_id + last_window_id++);
|
|
|
|
}
|
2018-12-09 11:44:20 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* meta_display_get_sound_player:
|
|
|
|
* @display: a #MetaDisplay
|
|
|
|
*
|
|
|
|
* Returns: (transfer none): The sound player of the display
|
|
|
|
*/
|
|
|
|
MetaSoundPlayer *
|
|
|
|
meta_display_get_sound_player (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
return display->sound_player;
|
|
|
|
}
|
2018-11-19 17:15:24 +00:00
|
|
|
|
2018-11-23 10:48:53 +00:00
|
|
|
/**
|
|
|
|
* meta_display_get_selection:
|
|
|
|
* @display: a #MetaDisplay
|
|
|
|
*
|
|
|
|
* Returns: (transfer none): The selection manager of the display
|
|
|
|
*/
|
2018-11-19 17:15:24 +00:00
|
|
|
MetaSelection *
|
|
|
|
meta_display_get_selection (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
return display->selection;
|
|
|
|
}
|
2022-01-28 23:49:50 +00:00
|
|
|
|
|
|
|
#ifdef WITH_VERBOSE_MODE
|
|
|
|
static const char* meta_window_queue_names[META_N_QUEUE_TYPES] =
|
|
|
|
{
|
|
|
|
"calc-showing",
|
|
|
|
"move-resize",
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static int
|
|
|
|
window_stack_cmp (gconstpointer a,
|
|
|
|
gconstpointer b)
|
|
|
|
{
|
|
|
|
MetaWindow *aw = (gpointer) a;
|
|
|
|
MetaWindow *bw = (gpointer) b;
|
|
|
|
|
|
|
|
return meta_stack_windows_cmp (aw->display->stack,
|
|
|
|
aw, bw);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
warn_on_incorrectly_unmanaged_window (MetaWindow *window)
|
|
|
|
{
|
|
|
|
g_warn_if_fail (!window->unmanaging);
|
|
|
|
}
|
|
|
|
|
2022-05-13 21:04:56 +00:00
|
|
|
static void
|
|
|
|
update_window_visibilities (MetaDisplay *display,
|
|
|
|
GList *windows)
|
2022-01-28 23:49:50 +00:00
|
|
|
{
|
|
|
|
g_autoptr (GList) unplaced = NULL;
|
|
|
|
g_autoptr (GList) should_show = NULL;
|
|
|
|
g_autoptr (GList) should_hide = NULL;
|
|
|
|
GList *l;
|
|
|
|
|
|
|
|
COGL_TRACE_BEGIN_SCOPED (MetaDisplayUpdateVisibility,
|
|
|
|
"Display: Update visibility");
|
|
|
|
|
|
|
|
for (l = windows; l; l = l->next)
|
|
|
|
{
|
|
|
|
MetaWindow *window = l->data;
|
|
|
|
|
|
|
|
if (!window->placed)
|
|
|
|
unplaced = g_list_prepend (unplaced, window);
|
|
|
|
else if (meta_window_should_be_showing (window))
|
|
|
|
should_show = g_list_prepend (should_show, window);
|
|
|
|
else
|
|
|
|
should_hide = g_list_prepend (should_hide, window);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Sort bottom to top */
|
|
|
|
unplaced = g_list_sort (unplaced, window_stack_cmp);
|
|
|
|
should_hide = g_list_sort (should_hide, window_stack_cmp);
|
|
|
|
|
|
|
|
/* Sort top to bottom */
|
|
|
|
should_show = g_list_sort (should_show, window_stack_cmp);
|
|
|
|
should_show = g_list_reverse (should_show);
|
|
|
|
|
|
|
|
COGL_TRACE_BEGIN (MetaDisplayShowUnplacedWindows,
|
|
|
|
"Display: Show unplaced windows");
|
|
|
|
g_list_foreach (unplaced, (GFunc) meta_window_update_visibility, NULL);
|
|
|
|
COGL_TRACE_END (MetaDisplayShowUnplacedWindows);
|
|
|
|
|
|
|
|
meta_stack_freeze (display->stack);
|
|
|
|
|
|
|
|
COGL_TRACE_BEGIN (MetaDisplayShowWindows, "Display: Show windows");
|
|
|
|
g_list_foreach (should_show, (GFunc) meta_window_update_visibility, NULL);
|
|
|
|
COGL_TRACE_END (MetaDisplayShowWindows);
|
|
|
|
|
2022-05-13 21:02:37 +00:00
|
|
|
COGL_TRACE_BEGIN (MetaDisplayHideWindows, "Display: Hide windows");
|
2022-01-28 23:49:50 +00:00
|
|
|
g_list_foreach (should_hide, (GFunc) meta_window_update_visibility, NULL);
|
|
|
|
COGL_TRACE_END (MetaDisplayHideWindows);
|
|
|
|
|
|
|
|
meta_stack_thaw (display->stack);
|
|
|
|
|
|
|
|
g_list_foreach (windows, (GFunc) meta_window_clear_queued, NULL);
|
|
|
|
|
|
|
|
g_signal_emit (display, display_signals[WINDOW_VISIBILITY_UPDATED], 0,
|
|
|
|
unplaced, should_show, should_hide);
|
|
|
|
|
|
|
|
g_list_foreach (windows, (GFunc) warn_on_incorrectly_unmanaged_window, NULL);
|
2022-05-13 21:04:56 +00:00
|
|
|
}
|
2022-01-28 23:49:50 +00:00
|
|
|
|
2022-05-13 21:04:56 +00:00
|
|
|
static void
|
|
|
|
move_resize (MetaDisplay *display,
|
|
|
|
GList *windows)
|
|
|
|
{
|
|
|
|
g_list_foreach (windows, (GFunc) meta_window_update_layout, NULL);
|
|
|
|
g_list_foreach (windows, (GFunc) warn_on_incorrectly_unmanaged_window, NULL);
|
2022-01-28 23:49:50 +00:00
|
|
|
}
|
|
|
|
|
2022-05-13 21:04:56 +00:00
|
|
|
typedef void (* WindowQueueFunc) (MetaDisplay *display,
|
|
|
|
GList *windows);
|
|
|
|
|
|
|
|
static const WindowQueueFunc window_queue_func[META_N_QUEUE_TYPES] =
|
|
|
|
{
|
|
|
|
update_window_visibilities,
|
|
|
|
move_resize,
|
|
|
|
};
|
|
|
|
|
2022-01-28 23:49:50 +00:00
|
|
|
static gboolean
|
2022-05-13 21:04:56 +00:00
|
|
|
window_queue_run_later_func (gpointer user_data)
|
2022-01-28 23:49:50 +00:00
|
|
|
{
|
2022-05-13 21:04:56 +00:00
|
|
|
MetaQueueRunData *run_data = user_data;
|
|
|
|
MetaDisplay *display = run_data->display;
|
2022-01-28 23:49:50 +00:00
|
|
|
MetaDisplayPrivate *priv = meta_display_get_instance_private (display);
|
|
|
|
g_autoptr (GList) windows = NULL;
|
2022-05-13 21:04:56 +00:00
|
|
|
int queue_idx = run_data->queue_idx;
|
2022-01-28 23:49:50 +00:00
|
|
|
|
|
|
|
windows = g_steal_pointer (&priv->queue_windows[queue_idx]);
|
2022-05-13 21:04:56 +00:00
|
|
|
|
2022-01-28 23:49:50 +00:00
|
|
|
priv->queue_later_ids[queue_idx] = 0;
|
|
|
|
|
2022-05-13 21:04:56 +00:00
|
|
|
window_queue_func[queue_idx] (display, windows);
|
2022-01-28 23:49:50 +00:00
|
|
|
|
|
|
|
return G_SOURCE_REMOVE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
meta_display_queue_window (MetaDisplay *display,
|
|
|
|
MetaWindow *window,
|
|
|
|
MetaQueueType queue_types)
|
|
|
|
{
|
|
|
|
MetaDisplayPrivate *priv = meta_display_get_instance_private (display);
|
|
|
|
MetaCompositor *compositor = display->compositor;
|
|
|
|
MetaLaters *laters = meta_compositor_get_laters (compositor);
|
|
|
|
int queue_idx;
|
|
|
|
|
|
|
|
for (queue_idx = 0; queue_idx < META_N_QUEUE_TYPES; queue_idx++)
|
|
|
|
{
|
|
|
|
const MetaLaterType window_queue_later_when[META_N_QUEUE_TYPES] =
|
|
|
|
{
|
|
|
|
META_LATER_CALC_SHOWING,
|
|
|
|
META_LATER_RESIZE,
|
|
|
|
};
|
|
|
|
|
|
|
|
if (!(queue_types & 1 << queue_idx))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
meta_topic (META_DEBUG_WINDOW_STATE,
|
|
|
|
"Queueing %s for window '%s'",
|
|
|
|
meta_window_queue_names[queue_idx],
|
|
|
|
meta_window_get_description (window));
|
|
|
|
|
|
|
|
priv->queue_windows[queue_idx] =
|
|
|
|
g_list_prepend (priv->queue_windows[queue_idx], window);
|
|
|
|
|
|
|
|
if (!priv->queue_later_ids[queue_idx])
|
|
|
|
{
|
2022-05-13 21:04:56 +00:00
|
|
|
MetaQueueRunData *run_data;
|
|
|
|
|
|
|
|
run_data = g_new0 (MetaQueueRunData, 1);
|
|
|
|
run_data->display = display;
|
|
|
|
run_data->queue_idx = queue_idx;
|
2022-05-13 17:08:31 +00:00
|
|
|
priv->queue_later_ids[queue_idx] =
|
|
|
|
meta_laters_add (laters,
|
|
|
|
window_queue_later_when[queue_idx],
|
|
|
|
window_queue_run_later_func,
|
|
|
|
run_data, g_free);
|
2022-01-28 23:49:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
meta_display_unqueue_window (MetaDisplay *display,
|
|
|
|
MetaWindow *window,
|
|
|
|
MetaQueueType queue_types)
|
|
|
|
{
|
|
|
|
MetaDisplayPrivate *priv = meta_display_get_instance_private (display);
|
|
|
|
MetaCompositor *compositor = display->compositor;
|
|
|
|
MetaLaters *laters = meta_compositor_get_laters (compositor);
|
|
|
|
int queue_idx;
|
|
|
|
|
|
|
|
for (queue_idx = 0; queue_idx < META_N_QUEUE_TYPES; queue_idx++)
|
|
|
|
{
|
|
|
|
if (!(queue_types & 1 << queue_idx))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
meta_topic (META_DEBUG_WINDOW_STATE,
|
|
|
|
"Unqueuing %s for window '%s'",
|
|
|
|
meta_window_queue_names[queue_idx],
|
|
|
|
window->desc);
|
|
|
|
|
|
|
|
priv->queue_windows[queue_idx] =
|
|
|
|
g_list_remove (priv->queue_windows[queue_idx], window);
|
|
|
|
|
|
|
|
if (!priv->queue_windows[queue_idx] && priv->queue_later_ids[queue_idx])
|
|
|
|
{
|
|
|
|
meta_laters_remove (laters,
|
|
|
|
priv->queue_later_ids[queue_idx]);
|
|
|
|
priv->queue_later_ids[queue_idx] = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-05-13 21:04:56 +00:00
|
|
|
|
|
|
|
void
|
|
|
|
meta_display_flush_queued_window (MetaDisplay *display,
|
|
|
|
MetaWindow *window,
|
|
|
|
MetaQueueType queue_types)
|
|
|
|
{
|
|
|
|
g_autoptr (GList) windows = NULL;
|
|
|
|
int queue_idx;
|
|
|
|
|
|
|
|
meta_display_unqueue_window (display, window, queue_types);
|
|
|
|
|
|
|
|
windows = g_list_prepend (windows, window);
|
|
|
|
|
|
|
|
for (queue_idx = 0; queue_idx < META_N_QUEUE_TYPES; queue_idx++)
|
|
|
|
{
|
|
|
|
if (!(queue_types & 1 << queue_idx))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
meta_topic (META_DEBUG_WINDOW_STATE,
|
|
|
|
"Running %s for window '%s'",
|
|
|
|
meta_window_queue_names[queue_idx],
|
|
|
|
window->desc);
|
|
|
|
|
|
|
|
window_queue_func[queue_idx] (display, windows);
|
|
|
|
}
|
|
|
|
}
|