1 /* $Id$ 2 3 This program is free software; you can redistribute it and/or modify 4 it under the terms of the GNU General Public License as published by 5 the Free Software Foundation; either version 2, or (at your option) 6 any later version. 7 8 This program is distributed in the hope that it will be useful, 9 but WITHOUT ANY WARRANTY; without even the implied warranty of 10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 GNU General Public License for more details. 12 13 You should have received a copy of the GNU General Public License 14 along with this program; if not, write to the Free Software 15 Foundation, Inc., Inc., 51 Franklin Street, Fifth Floor, Boston, 16 MA 02110-1301, USA. 17 18 19 oroborus - (c) 2001 Ken Lynch 20 xfwm4 - (c) 2002-2011 Olivier Fourdan 21 22 */ 23 24 #ifdef HAVE_CONFIG_H 25 #include "config.h" 26 #endif 27 28 #include <stdlib.h> 29 #include <stdio.h> 30 #include <string.h> 31 #include <signal.h> 32 #include <unistd.h> 33 34 #include <X11/X.h> 35 #include <X11/Xlib.h> 36 #include <X11/Xutil.h> 37 #include <X11/Xmd.h> 38 #include <X11/cursorfont.h> 39 #include <X11/extensions/shape.h> 40 41 #include <glib.h> 42 #include <gtk/gtk.h> 43 #include <sys/time.h> 44 #include <time.h> 45 46 #include "screen.h" 47 #include "misc.h" 48 #include "hints.h" 49 #include "keyboard.h" 50 #include "mypixmap.h" 51 #include "mywindow.h" 52 #include "settings.h" 53 54 #ifndef INC_CLIENT_H 55 #define INC_CLIENT_H 56 57 #define APPLY +1 58 #define REMOVE -1 59 60 #define PLACEMENT_MOUSE 0 61 #define PLACEMENT_ROOT 1 62 63 #define NO_CFG_FLAG 0 64 #define CFG_CONSTRAINED (1<<0) 65 #define CFG_REQUEST (1<<1) 66 #define CFG_NOTIFY (1<<2) 67 #define CFG_KEEP_VISIBLE (1<<3) 68 #define CFG_FORCE_REDRAW (1<<4) 69 70 #define SEARCH_INCLUDE_HIDDEN (1<<0) 71 #define SEARCH_INCLUDE_SHADED (1<<1) 72 #define SEARCH_INCLUDE_ALL_WORKSPACES (1<<2) 73 #define SEARCH_INCLUDE_SKIP_FOCUS (1<<3) 74 #define SEARCH_INCLUDE_SKIP_PAGER (1<<4) 75 #define SEARCH_INCLUDE_SKIP_TASKBAR (1<<5) 76 #define SEARCH_SAME_APPLICATION (1<<6) 77 #define SEARCH_DIFFERENT_APPLICATION (1<<7) 78 79 #define NO_UPDATE_FLAG 0 80 #define UPDATE_BUTTON_GRABS (1<<0) 81 #define UPDATE_FRAME (1<<1) 82 #define UPDATE_GRAVITY (1<<2) 83 #define UPDATE_MAXIMIZE (1<<3) 84 #define UPDATE_CACHE (1<<4) 85 #define UPDATE_ALL (UPDATE_BUTTON_GRABS | \ 86 UPDATE_FRAME | \ 87 UPDATE_GRAVITY | \ 88 UPDATE_MAXIMIZE | \ 89 UPDATE_CACHE) 90 91 #define CLIENT_FILL_VERT (1L<<0) 92 #define CLIENT_FILL_HORIZ (1L<<1) 93 #define CLIENT_FILL (CLIENT_FILL_VERT | \ 94 CLIENT_FILL_HORIZ) 95 96 97 #define STRUTS_SIZE 12 98 99 #ifndef CLIENT_MIN_VISIBLE 100 #define CLIENT_MIN_VISIBLE 15 101 #endif 102 103 #ifndef CLIENT_XSYNC_TIMEOUT 104 #define CLIENT_XSYNC_TIMEOUT 500 /* ms */ 105 #endif 106 107 #ifndef CLIENT_BLINK_TIMEOUT 108 #define CLIENT_BLINK_TIMEOUT 500 /* ms */ 109 #endif 110 111 #ifndef CLIENT_PING_TIMEOUT 112 #define CLIENT_PING_TIMEOUT 3000 /* ms */ 113 #endif 114 115 #ifndef MAX_BLINK_ITERATIONS 116 #define MAX_BLINK_ITERATIONS 5 117 #endif 118 119 #ifndef MAX_SNAP_DRIFT 120 #define MAX_SNAP_DRIFT 15 121 #endif 122 123 #define XFWM_FLAG_HAS_BORDER (1L<<0) 124 #define XFWM_FLAG_HAS_MENU (1L<<1) 125 #define XFWM_FLAG_HAS_MAXIMIZE (1L<<2) 126 #define XFWM_FLAG_HAS_CLOSE (1L<<3) 127 #define XFWM_FLAG_HAS_HIDE (1L<<4) 128 #define XFWM_FLAG_HAS_MOVE (1L<<5) 129 #define XFWM_FLAG_HAS_RESIZE (1L<<6) 130 #define XFWM_FLAG_HAS_STICK (1L<<7) 131 #define XFWM_FLAG_FOCUS (1L<<8) 132 #define XFWM_FLAG_IS_RESIZABLE (1L<<9) 133 #define XFWM_FLAG_MAP_PENDING (1L<<10) 134 #define XFWM_FLAG_VISIBLE (1L<<11) 135 #define XFWM_FLAG_MANAGED (1L<<13) 136 #define XFWM_FLAG_SESSION_MANAGED (1L<<14) 137 #define XFWM_FLAG_WORKSPACE_SET (1L<<15) 138 #define XFWM_FLAG_WAS_SHOWN (1L<<16) 139 #define XFWM_FLAG_DRAW_ACTIVE (1L<<17) 140 #define XFWM_FLAG_SEEN_ACTIVE (1L<<18) 141 #define XFWM_FLAG_FIRST_MAP (1L<<19) 142 #define XFWM_FLAG_SAVED_POS (1L<<20) 143 #define XFWM_FLAG_MOVING_RESIZING (1L<<21) 144 #define XFWM_FLAG_NEEDS_REDRAW (1L<<22) 145 #define XFWM_FLAG_OPACITY_LOCKED (1L<<23) 146 147 #define CLIENT_FLAG_HAS_STRUT (1L<<0) 148 #define CLIENT_FLAG_HAS_STRUT_PARTIAL (1L<<1) 149 #define CLIENT_FLAG_HAS_USER_TIME (1L<<2) 150 #define CLIENT_FLAG_HAS_STARTUP_TIME (1L<<3) 151 #define CLIENT_FLAG_ABOVE (1L<<4) 152 #define CLIENT_FLAG_BELOW (1L<<5) 153 #define CLIENT_FLAG_FULLSCREEN (1L<<6) 154 #define CLIENT_FLAG_ICONIFIED (1L<<7) 155 #define CLIENT_FLAG_MAXIMIZED_VERT (1L<<8) 156 #define CLIENT_FLAG_MAXIMIZED_HORIZ (1L<<9) 157 #define CLIENT_FLAG_MAXIMIZED (CLIENT_FLAG_MAXIMIZED_VERT | \ 158 CLIENT_FLAG_MAXIMIZED_HORIZ) 159 #define CLIENT_FLAG_SHADED (1L<<10) 160 #define CLIENT_FLAG_SKIP_PAGER (1L<<11) 161 #define CLIENT_FLAG_SKIP_TASKBAR (1L<<12) 162 #define CLIENT_FLAG_STATE_MODAL (1L<<13) 163 #define CLIENT_FLAG_STICKY (1L<<15) 164 #define CLIENT_FLAG_NAME_CHANGED (1L<<16) 165 #define CLIENT_FLAG_DEMANDS_ATTENTION (1L<<17) 166 #define CLIENT_FLAG_HAS_SHAPE (1L<<18) 167 #define CLIENT_FLAG_FULLSCREEN_MONITORS (1L<<19) 168 #define CLIENT_FLAG_HAS_FRAME_EXTENTS (1L<<20) 169 #define CLIENT_FLAG_HIDE_TITLEBAR (1L<<21) 170 #define CLIENT_FLAG_XSYNC_WAITING (1L<<22) 171 #define CLIENT_FLAG_XSYNC_ENABLED (1L<<23) 172 #define CLIENT_FLAG_XSYNC_EXT_COUNTER (1L<<24) 173 #define CLIENT_FLAG_RESTORE_SIZE_POS (1L<<25) 174 175 #define WM_FLAG_DELETE (1L<<0) 176 #define WM_FLAG_INPUT (1L<<1) 177 #define WM_FLAG_TAKEFOCUS (1L<<2) 178 #define WM_FLAG_CONTEXT_HELP (1L<<3) 179 #define WM_FLAG_URGENT (1L<<4) 180 #define WM_FLAG_PING (1L<<5) 181 182 #define XFWM_FLAG_INITIAL_VALUES XFWM_FLAG_HAS_BORDER | \ 183 XFWM_FLAG_HAS_MENU | \ 184 XFWM_FLAG_HAS_MAXIMIZE | \ 185 XFWM_FLAG_HAS_STICK | \ 186 XFWM_FLAG_HAS_HIDE | \ 187 XFWM_FLAG_HAS_CLOSE | \ 188 XFWM_FLAG_HAS_MOVE | \ 189 XFWM_FLAG_HAS_RESIZE | \ 190 XFWM_FLAG_FIRST_MAP | \ 191 XFWM_FLAG_NEEDS_REDRAW 192 193 #define ALL_WORKSPACES (guint) 0xFFFFFFFF 194 195 #define CONSTRAINED_WINDOW(c) ((c->win_layer > WIN_LAYER_DESKTOP) && \ 196 !(c->type & (WINDOW_DESKTOP | WINDOW_DOCK))) 197 198 #define WINDOW_TYPE_DIALOG (WINDOW_DIALOG | \ 199 WINDOW_MODAL_DIALOG) 200 #define WINDOW_TYPE_DONT_PLACE (WINDOW_DESKTOP | \ 201 WINDOW_DOCK | \ 202 WINDOW_UTILITY | \ 203 WINDOW_SPLASHSCREEN) 204 #define WINDOW_REGULAR_FOCUSABLE (WINDOW_NORMAL | \ 205 WINDOW_TYPE_DIALOG | \ 206 WINDOW_UTILITY) 207 #define WINDOW_TYPE_DONT_FOCUS (WINDOW_SPLASHSCREEN | \ 208 WINDOW_DOCK) 209 #define WINDOW_TYPE_STATE_FOCUSED (WINDOW_SPLASHSCREEN | \ 210 WINDOW_DOCK ) 211 212 /* Which bits of opacity are applied */ 213 #define OPACITY_MOVE (1<<0) 214 #define OPACITY_RESIZE (1<<1) 215 #define OPACITY_INACTIVE (1<<2) 216 217 /* Convenient macros */ 218 #define FLAG_TEST(flag,bits) ((flag) & (bits)) 219 #define FLAG_TEST_ALL(flag,bits) (((flag) & (bits)) == (bits)) 220 #define FLAG_TEST_AND_NOT(flag,bits1,bits2) (((flag) & ((bits1) | (bits2))) == (bits1)) 221 #define FLAG_SET(flag,bits) (flag |= (bits)) 222 #define FLAG_UNSET(flag,bits) (flag &= ~(bits)) 223 #define FLAG_TOGGLE(flag,bits) (flag ^= (bits)) 224 225 #define CLIENT_CAN_HIDE_WINDOW(c) (FLAG_TEST(c->xfwm_flags, XFWM_FLAG_HAS_HIDE) && \ 226 !FLAG_TEST(c->flags, CLIENT_FLAG_SKIP_TASKBAR)) 227 #define CLIENT_CAN_MAXIMIZE_WINDOW(c) (FLAG_TEST_ALL(c->xfwm_flags, XFWM_FLAG_HAS_MAXIMIZE | \ 228 XFWM_FLAG_IS_RESIZABLE) && \ 229 !FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREEN)) 230 #define CLIENT_CAN_FILL_WINDOW(c) (FLAG_TEST(c->xfwm_flags, XFWM_FLAG_HAS_RESIZE | \ 231 XFWM_FLAG_IS_RESIZABLE) && \ 232 !FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREEN | \ 233 CLIENT_FLAG_MAXIMIZED | \ 234 CLIENT_FLAG_SHADED)) 235 #define CLIENT_CAN_TILE_WINDOW(c) (CLIENT_CAN_MAXIMIZE_WINDOW(c) && \ 236 !FLAG_TEST (c->flags, CLIENT_FLAG_SHADED) && \ 237 (c->type & WINDOW_NORMAL)) 238 #define CLIENT_HAS_FRAME(c) (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_HAS_BORDER) && \ 239 !FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREEN) && \ 240 (FLAG_TEST (c->flags, CLIENT_FLAG_SHADED) || \ 241 !FLAG_TEST_ALL (c->flags, CLIENT_FLAG_MAXIMIZED) || \ 242 !((FLAG_TEST (c->flags, CLIENT_FLAG_HIDE_TITLEBAR) || \ 243 (c->screen_info->params->titleless_maximize)) && \ 244 (c->screen_info->params->borderless_maximize)))) 245 246 typedef enum 247 { 248 UNSET = 0, 249 WINDOW_NORMAL = (1 << 0), 250 WINDOW_DESKTOP = (1 << 1), 251 WINDOW_DOCK = (1 << 2), 252 WINDOW_DIALOG = (1 << 3), 253 WINDOW_MODAL_DIALOG = (1 << 4), 254 WINDOW_TOOLBAR = (1 << 5), 255 WINDOW_MENU = (1 << 6), 256 WINDOW_UTILITY = (1 << 7), 257 WINDOW_SPLASHSCREEN = (1 << 8), 258 WINDOW_NOTIFICATION = (1 << 9) 259 } 260 netWindowType; 261 262 typedef enum 263 { 264 TILE_NONE = 0, 265 TILE_LEFT, 266 TILE_RIGHT, 267 TILE_DOWN, 268 TILE_UP, 269 TILE_DOWN_LEFT, 270 TILE_DOWN_RIGHT, 271 TILE_UP_LEFT, 272 TILE_UP_RIGHT 273 } 274 tilePositionType; 275 276 struct _Client 277 { 278 /* Reference to our screen structure */ 279 ScreenInfo *screen_info; 280 281 Window window; 282 Window frame; 283 Window transient_for; 284 Window user_time_win; 285 Window *cmap_windows; 286 Colormap cmap; 287 gint ncmap; 288 xfwmWindow title; 289 xfwmWindow sides[SIDE_COUNT]; 290 xfwmWindow corners[CORNER_COUNT]; 291 xfwmWindow buttons[BUTTON_COUNT]; 292 Window client_leader; 293 Window group_leader; 294 xfwmPixmap appmenu[STATE_TOGGLED]; 295 unsigned long win_layer; 296 unsigned long serial; 297 unsigned long initial_layer; 298 unsigned int ignore_unmap; 299 Atom type_atom; 300 Visual *visual; 301 XSizeHints *size; 302 XWMHints *wmhints; 303 XClassHint class; 304 Client *next; 305 Client *prev; 306 PropMwmHints *mwm_hints; 307 netWindowType type; 308 gint x; 309 gint y; 310 gint width; 311 gint height; 312 gint depth; 313 gint border_width; 314 gint gravity; 315 guint win_workspace; 316 GdkRectangle applied_geometry; 317 GdkRectangle saved_geometry; 318 GdkRectangle pre_fullscreen_geometry; 319 gint pre_fullscreen_layer; 320 gint pre_relayout_x; /* to restore original location with XRandR */ 321 gint pre_relayout_y; 322 gint frame_cache_width; /* to optimize frame rendering */ 323 gint frame_cache_height; 324 gint blink_iterations; 325 gint button_status[BUTTON_COUNT]; 326 gint struts[STRUTS_SIZE]; 327 gchar *hostname; 328 gchar *name; 329 guint32 user_time; 330 GPid pid; 331 guint32 ping_time; 332 unsigned long flags; 333 unsigned long wm_flags; 334 unsigned long xfwm_flags; 335 gint fullscreen_monitors[4]; 336 gint frame_extents[SIDE_COUNT]; 337 tilePositionType tile_mode; 338 339 /* Termination dialog */ 340 gint dialog_pid; 341 gint dialog_fd; 342 /* Timout for asynchronous icon update */ 343 guint icon_timeout_id; 344 /* Timout for asynchronous frame update */ 345 guint frame_timeout_id; 346 /* Timout to manage blinking decorations for urgent windows */ 347 guint blink_timeout_id; 348 /* Timout for asynchronous icon update */ 349 guint ping_timeout_id; 350 /* Opacity for the compositor */ 351 guint32 opacity; 352 guint32 opacity_applied; 353 guint opacity_flags; 354 355 #ifdef HAVE_LIBSTARTUP_NOTIFICATION 356 /* Startup notification */ 357 gchar *startup_id; 358 #endif /* HAVE_LIBSTARTUP_NOTIFICATION */ 359 360 #ifdef HAVE_XSYNC 361 XSyncAlarm xsync_alarm; 362 XSyncCounter xsync_counter; 363 XSyncValue xsync_value; 364 XSyncValue next_xsync_value; 365 guint xsync_timeout_id; 366 #endif /* HAVE_XSYNC */ 367 }; 368 369 extern Client *clients; 370 extern unsigned int client_count; 371 372 Display *clientGetXDisplay (Client *); 373 void clientClearLastOpTime (Client *); 374 void clientUpdateWinState (Client *, 375 XClientMessageEvent *); 376 void clientUpdateUrgency (Client *); 377 void clientCoordGravitate (Client *, 378 int, 379 int, 380 int *, 381 int *); 382 void clientAdjustCoordGravity (Client *, 383 int, 384 XWindowChanges *, 385 unsigned long *); 386 void clientSendConfigureNotify (Client *); 387 void clientConfigure (Client *, 388 XWindowChanges *, 389 unsigned long, 390 unsigned short); 391 void clientReconfigure (Client *, 392 unsigned short); 393 void clientMoveResizeWindow (Client *, 394 XWindowChanges *, 395 unsigned long); 396 void clientGetMWMHints (Client *); 397 void clientApplyMWMHints (Client *, 398 gboolean); 399 void clientGetWMNormalHints (Client *, 400 gboolean); 401 void clientGetWMProtocols (Client *); 402 void clientUpdateIcon (Client *); 403 void clientSaveSizePos (Client *); 404 gboolean clientRestoreSizePos (Client *); 405 Client *clientFrame (DisplayInfo *, 406 Window, 407 gboolean); 408 void clientUnframe (Client *, 409 gboolean); 410 void clientFrameAll (ScreenInfo *); 411 void clientUnframeAll (ScreenInfo *); 412 void clientInstallColormaps (Client *); 413 void clientUpdateColormaps (Client *); 414 void clientUpdateName (Client *); 415 void clientUpdateAllFrames (ScreenInfo *, 416 gboolean); 417 void clientGrabButtons (Client *); 418 void clientUngrabButtons (Client *); 419 Client *clientGetFromWindow (Client *, 420 Window, 421 unsigned short); 422 void clientShow (Client *, 423 gboolean); 424 void clientWithdraw (Client *, 425 guint, 426 gboolean); 427 void clientWithdrawAll (Client *, 428 guint); 429 void clientClearAllShowDesktop (ScreenInfo *); 430 void clientToggleShowDesktop (ScreenInfo *); 431 void clientActivate (Client *, 432 guint32, 433 gboolean); 434 void clientClose (Client *); 435 void clientKill (Client *); 436 void clientTerminate (Client *); 437 void clientEnterContextMenuState (Client *); 438 void clientSetLayer (Client *, 439 guint); 440 void clientSetWorkspace (Client *, 441 guint, 442 gboolean); 443 void clientShade (Client *); 444 void clientUnshade (Client *); 445 void clientToggleShaded (Client *); 446 void clientStick (Client *, 447 gboolean); 448 void clientUnstick (Client *, 449 gboolean); 450 void clientToggleSticky (Client *, 451 gboolean); 452 void clientUpdateFullscreenSize (Client *); 453 void clientToggleFullscreen (Client *); 454 void clientSetFullscreenMonitor (Client *, 455 gint, 456 gint, 457 gint, 458 gint); 459 void clientToggleLayerAbove (Client *); 460 void clientToggleLayerBelow (Client *); 461 void clientSetLayerNormal (Client *); 462 void clientRemoveMaximizeFlag (Client *); 463 void clientUpdateMaximizeSize (Client *); 464 gboolean clientToggleMaximized (Client *, 465 int, 466 gboolean); 467 gboolean clientToggleMaximizedAtPoint (Client *, 468 gint, 469 gint, 470 int, 471 gboolean); 472 gboolean clientTile (Client *, 473 gint, 474 gint, 475 tilePositionType, 476 gboolean, 477 gboolean); 478 void clientUntile (Client *); 479 gboolean clientToggleTile (Client *, 480 tilePositionType); 481 void clientUpdateTileSize (Client *); 482 void clientUpdateOpacity (Client *); 483 void clientUpdateAllOpacity (ScreenInfo *); 484 void clientSetOpacity (Client *, 485 guint32, 486 guint32, 487 guint32); 488 void clientIncOpacity (Client *); 489 void clientDecOpacity (Client *); 490 void clientUpdateCursor (Client *); 491 void clientUpdateAllCursor (ScreenInfo *); 492 void clientScreenResize (ScreenInfo *, 493 gboolean); 494 void clientButtonPress (Client *, 495 Window, 496 XfwmEventButton *); 497 xfwmPixmap * clientGetButtonPixmap (Client *, 498 int, 499 int); 500 int clientGetButtonState (Client *, 501 int, 502 int); 503 Client *clientGetLeader (Client *); 504 gboolean clientGetGtkFrameExtents (Client *); 505 gboolean clientGetGtkHideTitlebar (Client *); 506 #ifdef HAVE_LIBSTARTUP_NOTIFICATION 507 char *clientGetStartupId (Client *); 508 #endif /* HAVE_LIBSTARTUP_NOTIFICATION */ 509 510 #endif /* INC_CLIENT_H */ 511