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 _DATA_H
11 #define _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 <xcb/xcb_atom.h>
18 #include <stdbool.h>
19 #include <pcre.h>
20 #include <sys/time.h>
21 
22 #include "libi3.h"
23 #include "queue.h"
24 
25 /*
26  * To get the big concept: There are helper structures like struct
27  * Workspace_Assignment. Every struct which is also defined as type (see
28  * forward definitions) is considered to be a major structure, thus important.
29  *
30  * The following things are all stored in a 'Con', from very high level (the
31  * biggest Cons) to very small (a single window):
32  *
33  * 1) X11 root window (as big as all your outputs combined)
34  * 2) output (like LVDS1)
35  * 3) content container, dockarea containers
36  * 4) workspaces
37  * 5) split containers
38  * ... (you can arbitrarily nest split containers)
39  * 6) X11 window containers
40  *
41  */
42 
43 /* Forward definitions */
44 typedef struct Binding Binding;
45 typedef struct Rect Rect;
46 typedef struct xoutput Output;
47 typedef struct Con Con;
48 typedef struct Match Match;
49 typedef struct Assignment Assignment;
50 typedef struct Window i3Window;
51 
52 
53 /******************************************************************************
54  * Helper types
55  *****************************************************************************/
56 typedef enum { D_LEFT, D_RIGHT, D_UP, D_DOWN } direction_t;
57 typedef enum { NO_ORIENTATION = 0, HORIZ, VERT } orientation_t;
58 typedef enum { BS_NORMAL = 0, BS_NONE = 1, BS_1PIXEL = 2 } border_style_t;
59 
62 typedef enum { DONT_KILL_WINDOW = 0, KILL_WINDOW = 1, KILL_CLIENT = 2 } kill_window_t;
63 
65 typedef enum { ADJ_NONE = 0,
70 
71 enum {
72  BIND_NONE = 0,
73  BIND_SHIFT = XCB_MOD_MASK_SHIFT, /* (1 << 0) */
74  BIND_CONTROL = XCB_MOD_MASK_CONTROL, /* (1 << 2) */
75  BIND_MOD1 = XCB_MOD_MASK_1, /* (1 << 3) */
76  BIND_MOD2 = XCB_MOD_MASK_2, /* (1 << 4) */
77  BIND_MOD3 = XCB_MOD_MASK_3, /* (1 << 5) */
78  BIND_MOD4 = XCB_MOD_MASK_4, /* (1 << 6) */
79  BIND_MOD5 = XCB_MOD_MASK_5, /* (1 << 7) */
80  BIND_MODE_SWITCH = (1 << 8)
81 };
82 
95 struct Rect {
96  uint32_t x;
97  uint32_t y;
98  uint32_t width;
99  uint32_t height;
100 } __attribute__((packed));
107 struct reservedpx {
108  uint32_t left;
109  uint32_t right;
110  uint32_t top;
111  uint32_t bottom;
112 };
113 
119 struct width_height {
120  uint32_t w;
121  uint32_t h;
122 };
123 
136  uint32_t background;
138 };
139 
145  char *name;
146  char *output;
147 
149 };
150 
151 struct Ignore_Event {
152  int sequence;
154  time_t added;
155 
156  SLIST_ENTRY(Ignore_Event) ignore_events;
157 };
158 
166  char *id;
168  char *workspace;
170  SnLauncherContext *context;
173  time_t delete_at;
174 
175  TAILQ_ENTRY(Startup_Sequence) sequences;
176 };
177 
187 struct regex {
188  char *pattern;
189  pcre *regex;
190  pcre_extra *extra;
191 };
192 
193 /******************************************************************************
194  * Major types
195  *****************************************************************************/
196 
202 struct Binding {
205  enum {
206  /* This binding will only be executed upon KeyPress events */
207  B_UPON_KEYPRESS = 0,
208  /* This binding will be executed either upon a KeyRelease event, or… */
209  B_UPON_KEYRELEASE = 1,
210  /* …upon a KeyRelease event, even if the modifiers don’t match. This
211  * state is triggered from get_binding() when the corresponding
212  * KeyPress (!) happens, so that users can release the modifier keys
213  * before releasing the actual key. */
214  B_UPON_KEYRELEASE_IGNORE_MODS = 2,
215  } release;
216 
220  char *symbol;
221 
227  xcb_keycode_t *translated_to;
228 
229  uint32_t number_keycodes;
230 
232  uint32_t keycode;
233 
235  uint32_t mods;
236 
238  char *command;
239 
241 };
242 
250 struct Autostart {
252  char *command;
256  TAILQ_ENTRY(Autostart) autostarts;
257  TAILQ_ENTRY(Autostart) autostarts_always;
258 };
259 
267 struct xoutput {
269  xcb_randr_output_t id;
271  char *name;
272 
275 
278  bool active;
279 
282  bool changed;
284  bool primary;
285 
288 
289  TAILQ_ENTRY(xoutput) outputs;
290 };
291 
297 struct Window {
298  xcb_window_t id;
299 
302  xcb_window_t leader;
303  xcb_window_t transient_for;
304 
305  char *class_class;
307 
310 
314  char *role;
315 
318 
321 
324 
326  struct timeval urgent;
327 
331 
333  enum { W_NODOCK = 0, W_DOCK_TOP = 1, W_DOCK_BOTTOM = 2 } dock;
334 
336  struct reservedpx reserved;
337 
340  uint32_t nr_assignments;
342 
344  uint16_t depth;
345 };
346 
355 struct Match {
356  struct regex *title;
358  struct regex *class;
359  struct regex *instance;
360  struct regex *mark;
361  struct regex *role;
362  enum {
363  U_DONTCHECK = -1,
364  U_LATEST = 0,
365  U_OLDEST = 1
366  } urgent;
367  enum {
368  M_DONTCHECK = -1,
369  M_NODOCK = 0,
370  M_DOCK_ANY = 1,
371  M_DOCK_TOP = 2,
372  M_DOCK_BOTTOM = 3
373  } dock;
374  xcb_window_t id;
376  enum { M_ANY = 0, M_TILING, M_FLOATING } floating;
377 
378  /* Where the window looking for a match should be inserted:
379  *
380  * M_HERE = the matched container will be replaced by the window
381  * (layout saving)
382  * M_ASSIGN_WS = the matched container will be inserted in the target_ws.
383  * M_BELOW = the window will be inserted as a child of the matched container
384  * (dockareas)
385  *
386  */
387  enum { M_HERE = 0, M_ASSIGN_WS, M_BELOW } insert_where;
388 
389  /* Whether this match was generated when restarting i3 inplace.
390  * Leads to not setting focus when managing a new window, because the old
391  * focus stack should be restored. */
393 
394  TAILQ_ENTRY(Match) matches;
395 };
396 
405 struct Assignment {
417  enum {
418  A_ANY = 0,
419  A_COMMAND = (1 << 0),
420  A_TO_WORKSPACE = (1 << 1),
421  A_TO_OUTPUT = (1 << 2)
422  } type;
423 
426 
428  union {
429  char *command;
430  char *workspace;
431  char *output;
432  } dest;
433 
434  TAILQ_ENTRY(Assignment) assignments;
435 };
436 
441 struct Con {
442  bool mapped;
444  bool split;
445  enum {
446  CT_ROOT = 0,
447  CT_OUTPUT = 1,
448  CT_CON = 2,
449  CT_FLOATING_CON = 3,
450  CT_WORKSPACE = 4,
451  CT_DOCKAREA = 5
452  } type;
453  struct Con *parent;
454 
455  struct Rect rect;
456  struct Rect window_rect;
457  struct Rect deco_rect;
459  struct Rect geometry;
460 
461  char *name;
462 
465  int num;
466 
467  /* a sticky-group is an identifier which bundles several containers to a
468  * group. The contents are shared between all of them, that is they are
469  * displayed on whichever of the containers is currently visible */
471 
472  /* user-definable mark to jump to this container later */
473  char *mark;
474 
475  double percent;
476 
477  /* proportional width/height, calculated from WM_NORMAL_HINTS, used to
478  * apply an aspect ratio to windows (think of MPlayer) */
481  /* the wanted size of the window, used in combination with size
482  * increments (see below). */
485 
486  /* the x11 border pixel attribute */
488 
489  /* minimum increment size specified for the window (in pixels) */
492 
493  struct Window *window;
494 
495  /* Should this container be marked urgent? This gets set when the window
496  * inside this container (if any) sets the urgency hint, for example. */
497  bool urgent;
498 
499  /* ids/pixmap/graphics context for the frame window */
500  xcb_window_t frame;
501  xcb_pixmap_t pixmap;
502  xcb_gcontext_t pm_gc;
504 
507 
508  /* Only workspace-containers can have floating clients */
509  TAILQ_HEAD(floating_head, Con) floating_head;
510 
511  TAILQ_HEAD(nodes_head, Con) nodes_head;
512  TAILQ_HEAD(focus_head, Con) focus_head;
513 
514  TAILQ_HEAD(swallow_head, Match) swallow_head;
515 
516  enum { CF_NONE = 0, CF_OUTPUT = 1, CF_GLOBAL = 2 } fullscreen_mode;
517  /* layout is the layout of this container: one of split[v|h], stacked or
518  * tabbed. Special containers in the tree (above workspaces) have special
519  * layouts like dockarea or output.
520  *
521  * last_split_layout is one of splitv or splith to support the old "layout
522  * default" command which by now should be "layout splitv" or "layout
523  * splith" explicitly.
524  *
525  * workspace_layout is only for type == CT_WORKSPACE cons. When you change
526  * the layout of a workspace without any children, i3 cannot just set the
527  * layout (because workspaces need to be splitv/splith to allow focus
528  * parent and opening new containers). Instead, it stores the requested
529  * layout in workspace_layout and creates a new split container with that
530  * layout whenever a new container is attached to the workspace. */
531  enum {
532  L_DEFAULT = 0,
533  L_STACKED = 1,
534  L_TABBED = 2,
535  L_DOCKAREA = 3,
536  L_OUTPUT = 4,
537  L_SPLITV = 5,
538  L_SPLITH = 6
539  } layout, last_split_layout, workspace_layout;
547  enum {
548  FLOATING_AUTO_OFF = 0,
549  FLOATING_USER_OFF = 1,
550  FLOATING_AUTO_ON = 2,
551  FLOATING_USER_ON = 3
552  } floating;
553 
559  uint8_t ignore_unmap;
560 
561  TAILQ_ENTRY(Con) nodes;
562  TAILQ_ENTRY(Con) focused;
563  TAILQ_ENTRY(Con) all_cons;
564  TAILQ_ENTRY(Con) floating_windows;
565 
567  void(*on_remove_child)(Con *);
568 
569  enum {
570  SCRATCHPAD_NONE = 0,
571  SCRATCHPAD_FRESH = 1,
572  SCRATCHPAD_CHANGED = 2
573  } scratchpad_state;
574 
575  /* The ID of this container before restarting. Necessary to correctly
576  * interpret back-references in the JSON (such as the focus stack). */
577  int old_id;
578 };
579 
580 #endif