summaryrefslogtreecommitdiff
path: root/src/core/display-private.h
blob: 5757444760ab151d55595e2be12843fec289ff9e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */

/* Mutter X display handler */

/*
 * Copyright (C) 2001 Havoc Pennington
 * Copyright (C) 2002 Red Hat, Inc.
 * Copyright (C) 2003 Rob Adams
 * Copyright (C) 2004-2006 Elijah Newren
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 */

#ifndef META_DISPLAY_PRIVATE_H
#define META_DISPLAY_PRIVATE_H

#include "meta/display.h"

#include <glib.h>
#include <X11/extensions/sync.h>
#include <X11/Xlib.h>

#include "clutter/clutter.h"
#include "core/keybindings-private.h"
#include "core/meta-gesture-tracker-private.h"
#include "core/meta-pad-action-mapper.h"
#include "core/stack-tracker.h"
#include "core/startup-notification-private.h"
#include "meta/barrier.h"
#include "meta/boxes.h"
#include "meta/common.h"
#include "meta/meta-selection.h"
#include "meta/prefs.h"

typedef struct _MetaBell       MetaBell;
typedef struct _MetaStack      MetaStack;

typedef struct MetaEdgeResistanceData MetaEdgeResistanceData;

typedef enum
{
  META_LIST_DEFAULT                   = 0,      /* normal windows */
  META_LIST_INCLUDE_OVERRIDE_REDIRECT = 1 << 0, /* normal and O-R */
  META_LIST_SORTED                    = 1 << 1, /* sort list by mru */
} MetaListWindowsFlags;

#define _NET_WM_STATE_REMOVE        0    /* remove/unset property */
#define _NET_WM_STATE_ADD           1    /* add/set property */
#define _NET_WM_STATE_TOGGLE        2    /* toggle property  */

/* This is basically a bogus number, just has to be large enough
 * to handle the expected case of the alt+tab operation, where
 * we want to ignore serials from UnmapNotify on the tab popup,
 * and the LeaveNotify/EnterNotify from the pointer ungrab. It
 * also has to be big enough to hold ignored serials from the point
 * where we reshape the stage to the point where we get events back.
 */
#define N_IGNORED_CROSSING_SERIALS  10

typedef enum
{
  META_TILE_NONE,
  META_TILE_LEFT,
  META_TILE_RIGHT,
  META_TILE_MAXIMIZED
} MetaTileMode;

typedef enum
{
  /* Normal interaction where you're interacting with windows.
   * Events go to windows normally. */
  META_EVENT_ROUTE_NORMAL,

  /* In a window operation like moving or resizing. All events
   * goes to MetaWindow, but not to the actual client window. */
  META_EVENT_ROUTE_WINDOW_OP,

  /* A Wayland application has a popup open. All events go to
   * the Wayland application. */
  META_EVENT_ROUTE_WAYLAND_POPUP,

  /* The user is clicking on a window button. */
  META_EVENT_ROUTE_FRAME_BUTTON,
} MetaEventRoute;

typedef void (* MetaDisplayWindowFunc) (MetaWindow *window,
                                        gpointer    user_data);

struct _MetaDisplay
{
  GObject parent_instance;

  MetaX11Display *x11_display;

  int clutter_event_filter;

  /* 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), and the serial of the request
   * or event that caused this.
   */
  MetaWindow *focus_window;

  /* last timestamp passed to XSetInputFocus */
  guint32 last_focus_time;

  /* last user interaction time in any app */
  guint32 last_user_time;

  /* whether we're using mousenav (only relevant for sloppy&mouse focus modes;
   * !mouse_mode means "keynav mode")
   */
  guint mouse_mode : 1;

  /* Helper var used when focus_new_windows setting is 'strict'; only
   * relevant in 'strict' mode and if the focus window is a terminal.
   * In that case, we don't allow new windows to take focus away from
   * a terminal, but if the user explicitly did something that should
   * allow a different window to gain focus (e.g. global keybinding or
   * clicking on a dock), then we will allow the transfer.
   */
  guint allow_terminal_deactivation : 1;

  /*< private-ish >*/
  GHashTable *stamps;
  GHashTable *wayland_windows;

  /* serials of leave/unmap events that may
   * correspond to an enter event we should
   * ignore
   */
  unsigned long ignored_crossing_serials[N_IGNORED_CROSSING_SERIALS];

  guint32 current_time;

  /* We maintain a sequence counter, incremented for each #MetaWindow
   * created.  This is exposed by meta_window_get_stable_sequence()
   * but is otherwise not used inside mutter.
   *
   * It can be useful to plugins which want to sort windows in a
   * stable fashion.
   */
  guint32 window_sequence_counter;

  /* Pings which we're waiting for a reply from */
  GSList     *pending_pings;

  /* Pending focus change */
  guint       focus_timeout_id;

  /* Pending autoraise */
  guint       autoraise_timeout_id;
  MetaWindow* autoraise_window;

  /* Event routing */
  MetaEventRoute event_route;

  /* current window operation */
  MetaGrabOp  grab_op;
  MetaWindow *grab_window;
  int         grab_button;
  int         grab_anchor_root_x;
  int         grab_anchor_root_y;
  MetaRectangle grab_anchor_window_pos;
  MetaTileMode  grab_tile_mode;
  int           grab_tile_monitor_number;
  int         grab_latest_motion_x;
  int         grab_latest_motion_y;
  guint       grab_have_pointer : 1;
  guint       grab_have_keyboard : 1;
  guint       grab_frame_action : 1;
  MetaRectangle grab_initial_window_pos;
  int         grab_initial_x, grab_initial_y;  /* These are only relevant for */
  gboolean    grab_threshold_movement_reached; /* raise_on_click == FALSE.    */
  MetaEdgeResistanceData *grab_edge_resistance_data;
  unsigned int grab_last_edge_resistance_flags;
  unsigned int grab_move_resize_later_id;

  MetaKeyBindingManager key_binding_manager;

  /* Opening the display */
  unsigned int display_opening : 1;
  unsigned int grabbed_in_clutter : 1;

  /* Closing down the display */
  int closing;

  /* Managed by compositor.c */
  MetaCompositor *compositor;

  MetaGestureTracker *gesture_tracker;
  ClutterEventSequence *pointer_emulating_sequence;

  ClutterActor *current_pad_osd;
  MetaPadActionMapper *pad_action_mapper;

  MetaStartupNotification *startup_notification;

  MetaCursor current_cursor;

  MetaStack *stack;
  MetaStackTracker *stack_tracker;

  guint tile_preview_timeout_id;
  guint preview_tile_mode : 2;

  GSList *startup_sequences;

  guint work_area_later;
  guint check_fullscreen_later;

  MetaBell *bell;
  MetaWorkspaceManager *workspace_manager;

  MetaSoundPlayer *sound_player;

  MetaSelectionSource *selection_source;
  GBytes *saved_clipboard;
  gchar *saved_clipboard_mimetype;
  MetaSelection *selection;
};

struct _MetaDisplayClass
{
  GObjectClass parent_class;
};

#define XSERVER_TIME_IS_BEFORE_ASSUMING_REAL_TIMESTAMPS(time1, time2) \
  ( (( (time1) < (time2) ) && ( (time2) - (time1) < ((guint32)-1)/2 )) ||     \
    (( (time1) > (time2) ) && ( (time1) - (time2) > ((guint32)-1)/2 ))        \
  )
/**
 * XSERVER_TIME_IS_BEFORE:
 *
 * See the docs for meta_display_xserver_time_is_before().
 */
#define XSERVER_TIME_IS_BEFORE(time1, time2)                          \
  ( (time1) == 0 ||                                                     \
    (XSERVER_TIME_IS_BEFORE_ASSUMING_REAL_TIMESTAMPS(time1, time2) && \
     (time2) != 0)                                                      \
  )

MetaDisplay * meta_display_new (MetaContext  *context,
                                GError      **error);

void meta_display_manage_all_xwindows (MetaDisplay *display);
void meta_display_unmanage_windows   (MetaDisplay *display,
                                      guint32      timestamp);

/* Utility function to compare the stacking of two windows */
int           meta_display_stack_cmp           (const void *a,
                                                const void *b);

/* Each MetaWindow is uniquely identified by a 64-bit "stamp"; unlike a
 * a MetaWindow *, a stamp will never be recycled
 */
MetaWindow* meta_display_lookup_stamp     (MetaDisplay *display,
                                           guint64      stamp);
void        meta_display_register_stamp   (MetaDisplay *display,
                                           guint64     *stampp,
                                           MetaWindow  *window);
void        meta_display_unregister_stamp (MetaDisplay *display,
                                           guint64      stamp);

/* A "stack id" is a XID or a stamp */
#define META_STACK_ID_IS_X11(id) ((id) < G_GUINT64_CONSTANT(0x100000000))

META_EXPORT_TEST
MetaWindow* meta_display_lookup_stack_id   (MetaDisplay *display,
                                            guint64      stack_id);

/* for debug logging only; returns a human-description of the stack
 * ID - a small number of buffers are recycled, so the result must
 * be used immediately or copied */
const char *meta_display_describe_stack_id (MetaDisplay *display,
                                            guint64      stack_id);

void        meta_display_register_wayland_window   (MetaDisplay *display,
                                                    MetaWindow  *window);
void        meta_display_unregister_wayland_window (MetaDisplay *display,
                                                    MetaWindow  *window);

void        meta_display_notify_window_created (MetaDisplay  *display,
                                                MetaWindow   *window);

META_EXPORT_TEST
GSList*     meta_display_list_windows        (MetaDisplay          *display,
                                              MetaListWindowsFlags  flags);

MetaDisplay* meta_display_for_x_display  (Display     *xdisplay);

META_EXPORT_TEST
MetaDisplay* meta_get_display            (void);

void meta_display_reload_cursor (MetaDisplay *display);
void meta_display_update_cursor (MetaDisplay *display);

void    meta_display_check_threshold_reached (MetaDisplay *display,
                                              int          x,
                                              int          y);
void     meta_display_grab_window_buttons    (MetaDisplay *display,
                                              Window       xwindow);
void     meta_display_ungrab_window_buttons  (MetaDisplay *display,
                                              Window       xwindow);

void meta_display_grab_focus_window_button   (MetaDisplay *display,
                                              MetaWindow  *window);
void meta_display_ungrab_focus_window_button (MetaDisplay *display,
                                              MetaWindow  *window);

/* Next function is defined in edge-resistance.c */
void meta_display_cleanup_edges              (MetaDisplay *display);

/* utility goo */
const char* meta_event_mode_to_string   (int m);
const char* meta_event_detail_to_string (int d);

void meta_display_queue_retheme_all_windows (MetaDisplay *display);

void meta_display_ping_window      (MetaWindow  *window,
                                    guint32      serial);
void meta_display_pong_for_serial  (MetaDisplay *display,
                                    guint32      serial);

MetaGravity meta_resize_gravity_from_grab_op (MetaGrabOp op);

gboolean meta_grab_op_is_moving   (MetaGrabOp op);
gboolean meta_grab_op_is_resizing (MetaGrabOp op);
gboolean meta_grab_op_is_mouse    (MetaGrabOp op);
gboolean meta_grab_op_is_keyboard (MetaGrabOp op);

void meta_display_clear_grab_move_resize_later (MetaDisplay *display);

void meta_display_queue_autoraise_callback  (MetaDisplay *display,
                                             MetaWindow  *window);
void meta_display_remove_autoraise_callback (MetaDisplay *display);

void meta_display_overlay_key_activate (MetaDisplay *display);
void meta_display_accelerator_activate (MetaDisplay     *display,
                                        guint            action,
                                        ClutterKeyEvent *event);
gboolean meta_display_modifiers_accelerator_activate (MetaDisplay *display);

void meta_display_sync_wayland_input_focus (MetaDisplay *display);
void meta_display_update_focus_window (MetaDisplay *display,
                                       MetaWindow  *window);

void meta_display_sanity_check_timestamps (MetaDisplay *display,
                                           guint32      timestamp);
gboolean meta_display_timestamp_too_old (MetaDisplay *display,
                                         guint32     *timestamp);

void meta_display_remove_pending_pings_for_window (MetaDisplay *display,
                                                   MetaWindow  *window);

MetaGestureTracker * meta_display_get_gesture_tracker (MetaDisplay *display);

gboolean meta_display_show_restart_message (MetaDisplay *display,
                                            const char  *message);
gboolean meta_display_request_restart      (MetaDisplay *display);

gboolean meta_display_show_resize_popup (MetaDisplay *display,
                                         gboolean show,
                                         MetaRectangle *rect,
                                         int display_w,
                                         int display_h);

void meta_set_is_restart (gboolean whether);

void meta_display_cancel_touch (MetaDisplay *display);

gboolean meta_display_windows_are_interactable (MetaDisplay *display);

void meta_display_show_tablet_mapping_notification (MetaDisplay        *display,
                                                    ClutterInputDevice *pad,
                                                    const gchar        *pretty_name);

void meta_display_notify_pad_group_switch (MetaDisplay        *display,
                                           ClutterInputDevice *pad,
                                           const gchar        *pretty_name,
                                           guint               n_group,
                                           guint               n_mode,
                                           guint               n_modes);

void meta_display_foreach_window (MetaDisplay           *display,
                                  MetaListWindowsFlags   flags,
                                  MetaDisplayWindowFunc  func,
                                  gpointer               data);

void meta_display_restacked (MetaDisplay *display);


void meta_display_update_tile_preview (MetaDisplay *display,
                                       gboolean     delay);
void meta_display_hide_tile_preview   (MetaDisplay *display);

gboolean meta_display_apply_startup_properties (MetaDisplay *display,
                                                MetaWindow  *window);

void meta_display_queue_workarea_recalc  (MetaDisplay *display);
void meta_display_queue_check_fullscreen (MetaDisplay *display);

MetaWindow *meta_display_get_window_from_id (MetaDisplay *display,
                                             uint64_t     window_id);
uint64_t    meta_display_generate_window_id (MetaDisplay *display);

void meta_display_init_x11 (MetaDisplay         *display,
                            GCancellable        *cancellable,
                            GAsyncReadyCallback  callback,
                            gpointer             user_data);
gboolean meta_display_init_x11_finish (MetaDisplay   *display,
                                       GAsyncResult  *result,
                                       GError       **error);

void     meta_display_shutdown_x11 (MetaDisplay  *display);

void meta_display_queue_window (MetaDisplay   *display,
                                MetaWindow    *window,
                                MetaQueueType  queue_types);

void meta_display_unqueue_window (MetaDisplay   *display,
                                  MetaWindow    *window,
                                  MetaQueueType  queue_types);

void meta_display_flush_queued_window (MetaDisplay   *display,
                                       MetaWindow    *window,
                                       MetaQueueType  queue_types);

#endif