i3
data.h
Go to the documentation of this file.
1 /*
2  * vim:ts=4:sw=4:expandtab
3  *
4  * i3 - an improved dynamic tiling window manager
5  * © 2009-2012 Michael Stapelberg and contributors (see also: LICENSE)
6  *
7  * include/data.h: This file defines all data structures used by i3
8  *
9  */
10 #ifndef I3_DATA_H
11 #define I3_DATA_H
12 
13 #define SN_API_NOT_YET_FROZEN 1
14 #include <libsn/sn-launcher.h>
15 
16 #include <xcb/randr.h>
17 #include <stdbool.h>
18 #include <pcre.h>
19 #include <sys/time.h>
20 
21 #include "libi3.h"
22 #include "queue.h"
23 
24 /*
25  * To get the big concept: There are helper structures like struct
26  * Workspace_Assignment. Every struct which is also defined as type (see
27  * forward definitions) is considered to be a major structure, thus important.
28  *
29  * The following things are all stored in a 'Con', from very high level (the
30  * biggest Cons) to very small (a single window):
31  *
32  * 1) X11 root window (as big as all your outputs combined)
33  * 2) output (like LVDS1)
34  * 3) content container, dockarea containers
35  * 4) workspaces
36  * 5) split containers
37  * ... (you can arbitrarily nest split containers)
38  * 6) X11 window containers
39  *
40  */
41 
42 /* Forward definitions */
43 typedef struct Binding Binding;
44 typedef struct Rect Rect;
45 typedef struct xoutput Output;
46 typedef struct Con Con;
47 typedef struct Match Match;
48 typedef struct Assignment Assignment;
49 typedef struct Window i3Window;
50 
51 
52 /******************************************************************************
53  * Helper types
54  *****************************************************************************/
55 typedef enum { D_LEFT, D_RIGHT, D_UP, D_DOWN } direction_t;
56 typedef enum { NO_ORIENTATION = 0, HORIZ, VERT } orientation_t;
57 typedef enum { BS_NORMAL = 0, BS_NONE = 1, BS_PIXEL = 2 } border_style_t;
58 
61 typedef enum { DONT_KILL_WINDOW = 0, KILL_WINDOW = 1, KILL_CLIENT = 2 } kill_window_t;
62 
64 typedef enum { ADJ_NONE = 0,
69 
70 enum {
71  BIND_NONE = 0,
72  BIND_SHIFT = XCB_MOD_MASK_SHIFT, /* (1 << 0) */
73  BIND_CONTROL = XCB_MOD_MASK_CONTROL, /* (1 << 2) */
74  BIND_MOD1 = XCB_MOD_MASK_1, /* (1 << 3) */
75  BIND_MOD2 = XCB_MOD_MASK_2, /* (1 << 4) */
76  BIND_MOD3 = XCB_MOD_MASK_3, /* (1 << 5) */
77  BIND_MOD4 = XCB_MOD_MASK_4, /* (1 << 6) */
78  BIND_MOD5 = XCB_MOD_MASK_5, /* (1 << 7) */
79  BIND_MODE_SWITCH = (1 << 8)
80 };
81 
85 typedef enum {
86  L_DEFAULT = 0,
87  L_STACKED = 1,
88  L_TABBED = 2,
90  L_OUTPUT = 4,
91  L_SPLITV = 5,
93 } layout_t;
94 
107 struct Rect {
108  uint32_t x;
109  uint32_t y;
110  uint32_t width;
111  uint32_t height;
112 } __attribute__((packed));
113 
119 struct reservedpx {
120  uint32_t left;
121  uint32_t right;
122  uint32_t top;
123  uint32_t bottom;
124 };
125 
131 struct width_height {
132  uint32_t w;
133  uint32_t h;
134 };
135 
148  uint32_t background;
151 };
152 
158  char *name;
159  char *output;
160 
162 };
163 
164 struct Ignore_Event {
165  int sequence;
167  time_t added;
168 
169  SLIST_ENTRY(Ignore_Event) ignore_events;
170 };
171 
179  char *id;
181  char *workspace;
183  SnLauncherContext *context;
186  time_t delete_at;
187 
188  TAILQ_ENTRY(Startup_Sequence) sequences;
189 };
190 
200 struct regex {
201  char *pattern;
202  pcre *regex;
203  pcre_extra *extra;
204 };
205 
206 /******************************************************************************
207  * Major types
208  *****************************************************************************/
209 
216 struct Binding {
219  enum {
220  /* This binding will only be executed upon KeyPress events */
221  B_UPON_KEYPRESS = 0,
222  /* This binding will be executed either upon a KeyRelease event, or… */
223  B_UPON_KEYRELEASE = 1,
224  /* …upon a KeyRelease event, even if the modifiers don’t match. This
225  * state is triggered from get_binding() when the corresponding
226  * KeyPress (!) happens, so that users can release the modifier keys
227  * before releasing the actual key. */
228  B_UPON_KEYRELEASE_IGNORE_MODS = 2,
229  } release;
230 
231  uint32_t number_keycodes;
232 
234  uint32_t keycode;
235 
237  uint32_t mods;
238 
242  char *symbol;
243 
249  xcb_keycode_t *translated_to;
250 
251 
253  char *command;
254 
256 };
257 
265 struct Autostart {
267  char *command;
271  TAILQ_ENTRY(Autostart) autostarts;
272  TAILQ_ENTRY(Autostart) autostarts_always;
273 };
274 
282 struct xoutput {
284  xcb_randr_output_t id;
285 
288  bool active;
289 
292  bool changed;
294  bool primary;
295 
297  char *name;
298 
301 
304 
305  TAILQ_ENTRY(xoutput) outputs;
306 };
307 
313 struct Window {
314  xcb_window_t id;
315 
318  xcb_window_t leader;
319  xcb_window_t transient_for;
320 
323  uint32_t nr_assignments;
325 
326  char *class_class;
328 
331 
335  char *role;
336 
339 
342 
345 
349 
351  enum { W_NODOCK = 0, W_DOCK_TOP = 1, W_DOCK_BOTTOM = 2 } dock;
352 
354  struct timeval urgent;
355 
357  struct reservedpx reserved;
358 
360  uint16_t depth;
361 };
362 
371 struct Match {
372  struct regex *title;
374  struct regex *class;
375  struct regex *instance;
376  struct regex *mark;
377  struct regex *role;
378  enum {
379  U_DONTCHECK = -1,
380  U_LATEST = 0,
381  U_OLDEST = 1
382  } urgent;
383  enum {
384  M_DONTCHECK = -1,
385  M_NODOCK = 0,
386  M_DOCK_ANY = 1,
387  M_DOCK_TOP = 2,
388  M_DOCK_BOTTOM = 3
389  } dock;
390  xcb_window_t id;
391  enum { M_ANY = 0, M_TILING, M_FLOATING } floating;
393 
394  /* Where the window looking for a match should be inserted:
395  *
396  * M_HERE = the matched container will be replaced by the window
397  * (layout saving)
398  * M_ASSIGN_WS = the matched container will be inserted in the target_ws.
399  * M_BELOW = the window will be inserted as a child of the matched container
400  * (dockareas)
401  *
402  */
403  enum { M_HERE = 0, M_ASSIGN_WS, M_BELOW } insert_where;
404 
405  TAILQ_ENTRY(Match) matches;
406 
407  /* Whether this match was generated when restarting i3 inplace.
408  * Leads to not setting focus when managing a new window, because the old
409  * focus stack should be restored. */
410  bool restart_mode;
411 };
412 
421 struct Assignment {
433  enum {
434  A_ANY = 0,
435  A_COMMAND = (1 << 0),
436  A_TO_WORKSPACE = (1 << 1),
437  A_TO_OUTPUT = (1 << 2)
438  } type;
439 
442 
444  union {
445  char *command;
446  char *workspace;
447  char *output;
448  } dest;
449 
450  TAILQ_ENTRY(Assignment) assignments;
451 };
452 
457 struct Con {
458  bool mapped;
459 
460  /* Should this container be marked urgent? This gets set when the window
461  * inside this container (if any) sets the urgency hint, for example. */
462  bool urgent;
463 
469  uint8_t ignore_unmap;
470 
471  /* ids/pixmap/graphics context for the frame window */
473  xcb_window_t frame;
474  xcb_pixmap_t pixmap;
475  xcb_gcontext_t pm_gc;
476 
477  enum {
478  CT_ROOT = 0,
479  CT_OUTPUT = 1,
480  CT_CON = 2,
481  CT_FLOATING_CON = 3,
482  CT_WORKSPACE = 4,
483  CT_DOCKAREA = 5
484  } type;
485 
488  int num;
489 
490  struct Con *parent;
491 
492  struct Rect rect;
493  struct Rect window_rect;
494  struct Rect deco_rect;
496  struct Rect geometry;
497 
498  char *name;
499 
500  /* a sticky-group is an identifier which bundles several containers to a
501  * group. The contents are shared between all of them, that is they are
502  * displayed on whichever of the containers is currently visible */
504 
505  /* user-definable mark to jump to this container later */
506  char *mark;
507 
508  double percent;
509 
510  /* aspect ratio from WM_NORMAL_HINTS (MPlayer uses this for example) */
511  double aspect_ratio;
512  /* the wanted size of the window, used in combination with size
513  * increments (see below). */
516 
517  /* the x11 border pixel attribute */
520 
521  /* minimum increment size specified for the window (in pixels) */
524 
525  struct Window *window;
526 
527  /* timer used for disabling urgency */
528  struct ev_timer *urgency_timer;
529 
532 
533  /* Only workspace-containers can have floating clients */
534  TAILQ_HEAD(floating_head, Con) floating_head;
535 
536  TAILQ_HEAD(nodes_head, Con) nodes_head;
537  TAILQ_HEAD(focus_head, Con) focus_head;
538 
539  TAILQ_HEAD(swallow_head, Match) swallow_head;
540 
541  enum { CF_NONE = 0, CF_OUTPUT = 1, CF_GLOBAL = 2 } fullscreen_mode;
542  /* layout is the layout of this container: one of split[v|h], stacked or
543  * tabbed. Special containers in the tree (above workspaces) have special
544  * layouts like dockarea or output.
545  *
546  * last_split_layout is one of splitv or splith to support the old "layout
547  * default" command which by now should be "layout splitv" or "layout
548  * splith" explicitly.
549  *
550  * workspace_layout is only for type == CT_WORKSPACE cons. When you change
551  * the layout of a workspace without any children, i3 cannot just set the
552  * layout (because workspaces need to be splitv/splith to allow focus
553  * parent and opening new containers). Instead, it stores the requested
554  * layout in workspace_layout and creates a new split container with that
555  * layout whenever a new container is attached to the workspace. */
556  layout_t layout, last_split_layout, workspace_layout;
564  enum {
565  FLOATING_AUTO_OFF = 0,
566  FLOATING_USER_OFF = 1,
567  FLOATING_AUTO_ON = 2,
568  FLOATING_USER_ON = 3
569  } floating;
570 
571  TAILQ_ENTRY(Con) nodes;
572  TAILQ_ENTRY(Con) focused;
573  TAILQ_ENTRY(Con) all_cons;
574  TAILQ_ENTRY(Con) floating_windows;
575 
577  void(*on_remove_child)(Con *);
578 
579  enum {
580  /* Not a scratchpad window. */
581  SCRATCHPAD_NONE = 0,
582 
583  /* Just moved to scratchpad, not resized by the user yet.
584  * Window will be auto-centered and sized appropriately. */
585  SCRATCHPAD_FRESH = 1,
586 
587  /* The user changed position/size of the scratchpad window. */
588  SCRATCHPAD_CHANGED = 2
589  } scratchpad_state;
590 
591  /* The ID of this container before restarting. Necessary to correctly
592  * interpret back-references in the JSON (such as the focus stack). */
593  int old_id;
594 
595  /* Depth of the container window */
596  uint16_t depth;
597 };
598 
599 #endif