1 /* Marco X display handler */ 2 3 /* 4 * Copyright (C) 2001 Havoc Pennington 5 * Copyright (C) 2002 Red Hat, Inc. 6 * Copyright (C) 2003 Rob Adams 7 * Copyright (C) 2004-2006 Elijah Newren 8 * 9 * This program is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU General Public License as 11 * published by the Free Software Foundation; either version 2 of the 12 * License, or (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, but 15 * WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 22 * 02110-1301, USA. 23 */ 24 25 #ifndef META_DISPLAY_PRIVATE_H 26 #define META_DISPLAY_PRIVATE_H 27 28 #ifndef PACKAGE 29 #error "config.h not included" 30 #endif 31 32 #include <glib.h> 33 #include <X11/Xlib.h> 34 #include "eventqueue.h" 35 #include "common.h" 36 #include "boxes.h" 37 #include "display.h" 38 39 #ifdef HAVE_STARTUP_NOTIFICATION 40 #include <libsn/sn.h> 41 #endif 42 43 #ifdef HAVE_XSYNC 44 #include <X11/extensions/sync.h> 45 #endif 46 47 typedef struct _MetaKeyBinding MetaKeyBinding; 48 typedef struct _MetaStack MetaStack; 49 typedef struct _MetaUISlave MetaUISlave; 50 typedef struct _MetaWorkspace MetaWorkspace; 51 52 typedef struct _MetaGroupPropHooks MetaGroupPropHooks; 53 54 typedef struct MetaEdgeResistanceData MetaEdgeResistanceData; 55 56 typedef void (*MetaWindowPingFunc) (MetaDisplay* display, Window xwindow, guint32 timestamp, gpointer user_data); 57 58 #define _NET_WM_STATE_REMOVE 0 /* remove/unset property */ 59 #define _NET_WM_STATE_ADD 1 /* add/set property */ 60 #define _NET_WM_STATE_TOGGLE 2 /* toggle property */ 61 62 /* This is basically a bogus number, just has to be large enough 63 * to handle the expected case of the alt+tab operation, where 64 * we want to ignore serials from UnmapNotify on the tab popup, 65 * and the LeaveNotify/EnterNotify from the pointer ungrab 66 */ 67 #define N_IGNORED_SERIALS 4 68 69 typedef enum { 70 META_TILE_NONE, 71 META_TILE_LEFT, 72 META_TILE_RIGHT, 73 META_TILE_MAXIMIZED, /* only used for previews */ 74 META_TILE_TOP_LEFT, 75 META_TILE_TOP_RIGHT, 76 META_TILE_BOTTOM_LEFT, 77 META_TILE_BOTTOM_RIGHT 78 } MetaTileMode; 79 80 struct _MetaDisplay { 81 char* name; 82 Display* xdisplay; 83 84 Window leader_window; 85 Window timestamp_pinging_window; 86 87 /* Pull in all the names of atoms as fields; we will intern them when the 88 * class is constructed. 89 */ 90 #define item(x) Atom atom_##x; 91 #include "atomnames.h" 92 #undef item 93 94 /* This is the actual window from focus events, 95 * not the one we last set 96 */ 97 MetaWindow* focus_window; 98 99 /* window we are expecting a FocusIn event for or the current focus 100 * window if we are not expecting any FocusIn/FocusOut events; not 101 * perfect because applications can call XSetInputFocus directly. 102 * (It could also be messed up if a timestamp later than current 103 * time is sent to meta_display_set_input_focus_window, though that 104 * would be a programming error). See bug 154598 for more info. 105 */ 106 MetaWindow* expected_focus_window; 107 108 /* last timestamp passed to XSetInputFocus */ 109 guint32 last_focus_time; 110 111 /* last user interaction time in any app */ 112 guint32 last_user_time; 113 114 /* whether we're using mousenav (only relevant for sloppy&mouse focus modes; 115 * !mouse_mode means "keynav mode") 116 */ 117 guint mouse_mode: 1; 118 119 /* Helper var used when focus_new_windows setting is 'strict'; only 120 * relevant in 'strict' mode and if the focus window is a terminal. 121 * In that case, we don't allow new windows to take focus away from 122 * a terminal, but if the user explicitly did something that should 123 * allow a different window to gain focus (e.g. global keybinding or 124 * clicking on a dock), then we will allow the transfer. 125 */ 126 guint allow_terminal_deactivation: 1; 127 128 guint static_gravity_works: 1; 129 130 guint tab_popup_mouse_pressed : 1; 131 132 /*< private-ish >*/ 133 guint error_trap_synced_at_last_pop: 1; 134 MetaEventQueue* events; 135 GSList* screens; 136 MetaScreen* active_screen; 137 GHashTable* window_ids; 138 int error_traps; 139 int (*error_trap_handler) (Display* display, XErrorEvent* error); 140 int server_grab_count; 141 142 /* serials of leave/unmap events that may 143 * correspond to an enter event we should 144 * ignore 145 */ 146 unsigned long ignored_serials[N_IGNORED_SERIALS]; 147 Window ungrab_should_not_cause_focus_window; 148 149 guint32 current_time; 150 151 /* Pings which we're waiting for a reply from */ 152 GSList* pending_pings; 153 154 /* Pending autoraise */ 155 guint autoraise_timeout_id; 156 MetaWindow* autoraise_window; 157 158 /* Alt+click button grabs */ 159 unsigned int window_grab_modifiers; 160 161 /* current window operation */ 162 MetaGrabOp grab_op; 163 MetaScreen* grab_screen; 164 MetaWindow* grab_window; 165 Window grab_xwindow; 166 int grab_button; 167 int grab_anchor_root_x; 168 int grab_anchor_root_y; 169 MetaRectangle grab_anchor_window_pos; 170 MetaTileMode grab_tile_mode; 171 int grab_tile_monitor_number; 172 int grab_latest_motion_x; 173 int grab_latest_motion_y; 174 gulong grab_mask; 175 guint grab_have_pointer : 1; 176 guint grab_have_keyboard : 1; 177 guint grab_wireframe_active : 1; 178 guint grab_was_cancelled : 1; /* Only used in wireframe mode */ 179 guint grab_frame_action : 1; 180 MetaRectangle grab_wireframe_rect; 181 MetaRectangle grab_wireframe_last_xor_rect; 182 MetaRectangle grab_initial_window_pos; 183 int grab_initial_x, grab_initial_y; /* These are only relevant for */ 184 gboolean grab_threshold_movement_reached; /* raise_on_click == FALSE. */ 185 MetaResizePopup* grab_resize_popup; 186 gint64 grab_last_moveresize_time; 187 guint32 grab_motion_notify_time; 188 int grab_wireframe_last_display_width; 189 int grab_wireframe_last_display_height; 190 GList* grab_old_window_stacking; 191 MetaEdgeResistanceData* grab_edge_resistance_data; 192 unsigned int grab_last_user_action_was_snap; 193 194 /* we use property updates as sentinels for certain window focus events 195 * to avoid some race conditions on EnterNotify events 196 */ 197 int sentinel_counter; 198 199 #ifdef HAVE_XKB 200 int xkb_base_event_type; 201 guint32 last_bell_time; 202 #endif 203 204 #ifdef HAVE_XSYNC 205 /* alarm monitoring client's _NET_WM_SYNC_REQUEST_COUNTER */ 206 XSyncAlarm grab_sync_request_alarm; 207 #endif 208 209 int grab_resize_timeout_id; 210 211 /* Keybindings stuff */ 212 MetaKeyBinding* key_bindings; 213 int n_key_bindings; 214 int min_keycode; 215 int max_keycode; 216 KeySym* keymap; 217 int keysyms_per_keycode; 218 XModifierKeymap* modmap; 219 unsigned int ignored_modifier_mask; 220 unsigned int num_lock_mask; 221 unsigned int scroll_lock_mask; 222 unsigned int hyper_mask; 223 unsigned int super_mask; 224 unsigned int meta_mask; 225 226 /* Xinerama cache */ 227 unsigned int xinerama_cache_invalidated: 1; 228 229 /* Opening the display */ 230 unsigned int display_opening: 1; 231 232 /* Closing down the display */ 233 int closing; 234 235 /* To detect double clicks 236 * 237 * https://github.com/stefano-k/Mate-Desktop-Environment/commit/b0e5fb03eb21dae8f02692f11ef391bfc5ccba33 238 */ 239 guint button_click_number; 240 Window button_click_window; 241 int button_click_x; 242 int button_click_y; 243 guint32 button_click_time; 244 245 /* Managed by group.c */ 246 GHashTable* groups_by_leader; 247 248 /* currently-active window menu if any */ 249 MetaWindowMenu* window_menu; 250 MetaWindow* window_with_menu; 251 252 /* Managed by window-props.c */ 253 gpointer* prop_hooks_table; 254 GHashTable* prop_hooks; 255 256 /* Managed by group-props.c */ 257 MetaGroupPropHooks* group_prop_hooks; 258 259 /* Managed by compositor.c */ 260 MetaCompositor* compositor; 261 262 #ifdef HAVE_STARTUP_NOTIFICATION 263 SnDisplay* sn_display; 264 #endif 265 266 #ifdef HAVE_XSYNC 267 int xsync_event_base; 268 int xsync_error_base; 269 #endif 270 271 #ifdef HAVE_SHAPE 272 int shape_event_base; 273 int shape_error_base; 274 #endif 275 276 #ifdef HAVE_RENDER 277 int render_event_base; 278 int render_error_base; 279 #endif 280 281 #ifdef HAVE_COMPOSITE_EXTENSIONS 282 int composite_event_base; 283 int composite_error_base; 284 int damage_event_base; 285 int damage_error_base; 286 int xfixes_event_base; 287 int xfixes_error_base; 288 #endif 289 290 #ifdef HAVE_XSYNC 291 unsigned int have_xsync : 1; 292 #define META_DISPLAY_HAS_XSYNC(display) ((display)->have_xsync) 293 #else 294 #define META_DISPLAY_HAS_XSYNC(display) FALSE 295 #endif 296 297 #ifdef HAVE_SHAPE 298 unsigned int have_shape : 1; 299 #define META_DISPLAY_HAS_SHAPE(display) ((display)->have_shape) 300 #else 301 #define META_DISPLAY_HAS_SHAPE(display) FALSE 302 #endif 303 304 #ifdef HAVE_RENDER 305 unsigned int have_render : 1; 306 #define META_DISPLAY_HAS_RENDER(display) ((display)->have_render) 307 #else 308 #define META_DISPLAY_HAS_RENDER(display) FALSE 309 #endif 310 311 #ifdef HAVE_COMPOSITE_EXTENSIONS 312 unsigned int have_composite : 1; 313 unsigned int have_damage : 1; 314 unsigned int have_xfixes : 1; 315 #define META_DISPLAY_HAS_COMPOSITE(display) ((display)->have_composite) 316 #define META_DISPLAY_HAS_DAMAGE(display) ((display)->have_damage) 317 #define META_DISPLAY_HAS_XFIXES(display) ((display)->have_xfixes) 318 #else 319 #define META_DISPLAY_HAS_COMPOSITE(display) FALSE 320 #define META_DISPLAY_HAS_DAMAGE(display) FALSE 321 #define META_DISPLAY_HAS_XFIXES(display) FALSE 322 #endif 323 }; 324 325 /* Xserver time can wraparound, thus comparing two timestamps needs to take 326 * this into account. Here's a little macro to help out. If no wraparound 327 * has occurred, this is equivalent to 328 * time1 < time2 329 * Of course, the rest of the ugliness of this macro comes from accounting 330 * for the fact that wraparound can occur and the fact that a timestamp of 331 * 0 must be special-cased since it means older than anything else. 332 * 333 * Note that this is NOT an equivalent for time1 <= time2; if that's what 334 * you need then you'll need to swap the order of the arguments and negate 335 * the result. 336 */ 337 #define XSERVER_TIME_IS_BEFORE_ASSUMING_REAL_TIMESTAMPS(time1, time2) \ 338 ( (( (time1) < (time2) ) && ( (time2) - (time1) < ((guint32)-1)/2 )) || \ 339 (( (time1) > (time2) ) && ( (time1) - (time2) > ((guint32)-1)/2 )) \ 340 ) 341 #define XSERVER_TIME_IS_BEFORE(time1, time2) \ 342 ( (time1) == 0 || \ 343 (XSERVER_TIME_IS_BEFORE_ASSUMING_REAL_TIMESTAMPS(time1, time2) && \ 344 (time2) != 0) \ 345 ) 346 347 gboolean meta_display_open (void); 348 void meta_display_close (MetaDisplay *display, 349 guint32 timestamp); 350 MetaScreen* meta_display_screen_for_x_screen (MetaDisplay *display, 351 Screen *screen); 352 MetaScreen* meta_display_screen_for_xwindow (MetaDisplay *display, 353 Window xindow); 354 void meta_display_grab (MetaDisplay *display); 355 void meta_display_ungrab (MetaDisplay *display); 356 357 void meta_display_unmanage_screen (MetaDisplay *display, 358 MetaScreen *screen, 359 guint32 timestamp); 360 361 void meta_display_unmanage_windows_for_screen (MetaDisplay *display, 362 MetaScreen *screen, 363 guint32 timestamp); 364 365 /* Utility function to compare the stacking of two windows */ 366 int meta_display_stack_cmp (const void *a, 367 const void *b); 368 369 /* A given MetaWindow may have various X windows that "belong" 370 * to it, such as the frame window. 371 */ 372 MetaWindow* meta_display_lookup_x_window (MetaDisplay *display, 373 Window xwindow); 374 void meta_display_register_x_window (MetaDisplay *display, 375 Window *xwindowp, 376 MetaWindow *window); 377 void meta_display_unregister_x_window (MetaDisplay *display, 378 Window xwindow); 379 /* Return whether the xwindow is a no focus window for any of the screens */ 380 gboolean meta_display_xwindow_is_a_no_focus_window (MetaDisplay *display, 381 Window xwindow); 382 383 GSList* meta_display_list_windows (MetaDisplay *display); 384 385 MetaDisplay* meta_display_for_x_display (Display *xdisplay); 386 MetaDisplay* meta_get_display (void); 387 388 Cursor meta_display_create_x_cursor (MetaDisplay *display, 389 MetaCursor cursor); 390 391 void meta_display_set_grab_op_cursor (MetaDisplay *display, 392 MetaScreen *screen, 393 MetaGrabOp op, 394 gboolean change_pointer, 395 Window grab_xwindow, 396 guint32 timestamp); 397 398 gboolean meta_display_begin_grab_op (MetaDisplay *display, 399 MetaScreen *screen, 400 MetaWindow *window, 401 MetaGrabOp op, 402 gboolean pointer_already_grabbed, 403 gboolean frame_action, 404 int button, 405 gulong modmask, 406 guint32 timestamp, 407 int root_x, 408 int root_y); 409 void meta_display_end_grab_op (MetaDisplay *display, 410 guint32 timestamp); 411 412 void meta_display_check_threshold_reached (MetaDisplay *display, 413 int x, 414 int y); 415 void meta_display_grab_window_buttons (MetaDisplay *display, 416 Window xwindow); 417 void meta_display_ungrab_window_buttons (MetaDisplay *display, 418 Window xwindow); 419 420 void meta_display_grab_focus_window_button (MetaDisplay *display, 421 MetaWindow *window); 422 void meta_display_ungrab_focus_window_button (MetaDisplay *display, 423 MetaWindow *window); 424 425 /* Next two functions are defined in edge-resistance.c */ 426 void meta_display_cleanup_edges (MetaDisplay *display); 427 428 /* make a request to ensure the event serial has changed */ 429 void meta_display_increment_event_serial (MetaDisplay *display); 430 431 void meta_display_update_active_window_hint (MetaDisplay *display); 432 433 guint32 meta_display_get_current_time (MetaDisplay *display); 434 guint32 meta_display_get_current_time_roundtrip (MetaDisplay *display); 435 436 /* utility goo */ 437 const char* meta_event_mode_to_string (int m); 438 const char* meta_event_detail_to_string (int d); 439 440 void meta_display_queue_retheme_all_windows (MetaDisplay *display); 441 void meta_display_retheme_all (void); 442 443 void meta_display_set_cursor_theme (const char *theme, 444 int size); 445 446 void meta_display_ping_window (MetaDisplay *display, 447 MetaWindow *window, 448 guint32 timestamp, 449 MetaWindowPingFunc ping_reply_func, 450 MetaWindowPingFunc ping_timeout_func, 451 void *user_data); 452 gboolean meta_display_window_has_pending_pings (MetaDisplay *display, 453 MetaWindow *window); 454 455 typedef enum 456 { 457 META_TAB_LIST_NORMAL, 458 META_TAB_LIST_DOCKS, 459 META_TAB_LIST_GROUP, 460 META_TAB_LIST_NORMAL_ALL_WORKSPACES 461 } MetaTabList; 462 463 typedef enum 464 { 465 META_TAB_SHOW_ICON, /* Alt-Tab mode */ 466 META_TAB_SHOW_INSTANTLY /* Alt-Esc mode */ 467 } MetaTabShowType; 468 469 GList* meta_display_get_tab_list (MetaDisplay *display, 470 MetaTabList type, 471 MetaScreen *screen, 472 MetaWorkspace *workspace); 473 474 MetaWindow* meta_display_get_tab_next (MetaDisplay *display, 475 MetaTabList type, 476 MetaScreen *screen, 477 MetaWorkspace *workspace, 478 MetaWindow *window, 479 gboolean backward); 480 481 MetaWindow* meta_display_get_tab_current (MetaDisplay *display, 482 MetaTabList type, 483 MetaScreen *screen, 484 MetaWorkspace *workspace); 485 486 int meta_resize_gravity_from_grab_op (MetaGrabOp op); 487 488 gboolean meta_grab_op_is_moving (MetaGrabOp op); 489 gboolean meta_grab_op_is_resizing (MetaGrabOp op); 490 491 void meta_display_devirtualize_modifiers (MetaDisplay *display, 492 MetaVirtualModifier modifiers, 493 unsigned int *mask); 494 495 void meta_display_increment_focus_sentinel (MetaDisplay *display); 496 void meta_display_decrement_focus_sentinel (MetaDisplay *display); 497 gboolean meta_display_focus_sentinel_clear (MetaDisplay *display); 498 499 /* meta_display_set_input_focus_window is like XSetInputFocus, except 500 * that (a) it can't detect timestamps later than the current time, 501 * since Marco isn't part of the XServer, and thus gives erroneous 502 * behavior in this circumstance (so don't do it), (b) it uses 503 * display->last_focus_time since we don't have access to the true 504 * Xserver one, (c) it makes use of display->user_time since checking 505 * whether a window should be allowed to be focused should depend 506 * on user_time events (see bug 167358, comment 15 in particular) 507 */ 508 void meta_display_set_input_focus_window (MetaDisplay *display, 509 MetaWindow *window, 510 gboolean focus_frame, 511 guint32 timestamp); 512 513 /* meta_display_focus_the_no_focus_window is called when the 514 * designated no_focus_window should be focused, but is otherwise the 515 * same as meta_display_set_input_focus_window 516 */ 517 void meta_display_focus_the_no_focus_window (MetaDisplay *display, 518 MetaScreen *screen, 519 guint32 timestamp); 520 521 void meta_display_queue_autoraise_callback (MetaDisplay *display, 522 MetaWindow *window); 523 void meta_display_remove_autoraise_callback (MetaDisplay *display); 524 525 #endif /* META_DISPLAY_PRIVATE_H */ 526