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 <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_PIXEL = 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;
139 };
140 
146  char *name;
147  char *output;
148 
150 };
151 
152 struct Ignore_Event {
153  int sequence;
155  time_t added;
156 
157  SLIST_ENTRY(Ignore_Event) ignore_events;
158 };
159 
167  char *id;
169  char *workspace;
171  SnLauncherContext *context;
174  time_t delete_at;
175 
176  TAILQ_ENTRY(Startup_Sequence) sequences;
177 };
178 
188 struct regex {
189  char *pattern;
190  pcre *regex;
191  pcre_extra *extra;
192 };
193 
194 /******************************************************************************
195  * Major types
196  *****************************************************************************/
197 
203 struct Binding {
206  enum {
207  /* This binding will only be executed upon KeyPress events */
208  B_UPON_KEYPRESS = 0,
209  /* This binding will be executed either upon a KeyRelease event, or… */
210  B_UPON_KEYRELEASE = 1,
211  /* …upon a KeyRelease event, even if the modifiers don’t match. This
212  * state is triggered from get_binding() when the corresponding
213  * KeyPress (!) happens, so that users can release the modifier keys
214  * before releasing the actual key. */
215  B_UPON_KEYRELEASE_IGNORE_MODS = 2,
216  } release;
217 
221  char *symbol;
222 
228  xcb_keycode_t *translated_to;
229 
230  uint32_t number_keycodes;
231 
233  uint32_t keycode;
234 
236  uint32_t mods;
237 
239  char *command;
240 
242 };
243 
251 struct Autostart {
253  char *command;
257  TAILQ_ENTRY(Autostart) autostarts;
258  TAILQ_ENTRY(Autostart) autostarts_always;
259 };
260 
268 struct xoutput {
270  xcb_randr_output_t id;
272  char *name;
273 
276 
279  bool active;
280 
283  bool changed;
285  bool primary;
286 
289 
290  TAILQ_ENTRY(xoutput) outputs;
291 };
292 
298 struct Window {
299  xcb_window_t id;
300 
303  xcb_window_t leader;
304  xcb_window_t transient_for;
305 
306  char *class_class;
308 
311 
315  char *role;
316 
319 
322 
325 
327  struct timeval urgent;
328 
332 
334  enum { W_NODOCK = 0, W_DOCK_TOP = 1, W_DOCK_BOTTOM = 2 } dock;
335 
337  struct reservedpx reserved;
338 
341  uint32_t nr_assignments;
343 
345  uint16_t depth;
346 };
347 
356 struct Match {
357  struct regex *title;
359  struct regex *class;
360  struct regex *instance;
361  struct regex *mark;
362  struct regex *role;
363  enum {
364  U_DONTCHECK = -1,
365  U_LATEST = 0,
366  U_OLDEST = 1
367  } urgent;
368  enum {
369  M_DONTCHECK = -1,
370  M_NODOCK = 0,
371  M_DOCK_ANY = 1,
372  M_DOCK_TOP = 2,
373  M_DOCK_BOTTOM = 3
374  } dock;
375  xcb_window_t id;
377  enum { M_ANY = 0, M_TILING, M_FLOATING } floating;
378 
379  /* Where the window looking for a match should be inserted:
380  *
381  * M_HERE = the matched container will be replaced by the window
382  * (layout saving)
383  * M_ASSIGN_WS = the matched container will be inserted in the target_ws.
384  * M_BELOW = the window will be inserted as a child of the matched container
385  * (dockareas)
386  *
387  */
388  enum { M_HERE = 0, M_ASSIGN_WS, M_BELOW } insert_where;
389 
390  /* Whether this match was generated when restarting i3 inplace.
391  * Leads to not setting focus when managing a new window, because the old
392  * focus stack should be restored. */
394 
395  TAILQ_ENTRY(Match) matches;
396 };
397 
406 struct Assignment {
418  enum {
419  A_ANY = 0,
420  A_COMMAND = (1 << 0),
421  A_TO_WORKSPACE = (1 << 1),
422  A_TO_OUTPUT = (1 << 2)
423  } type;
424 
427 
429  union {
430  char *command;
431  char *workspace;
432  char *output;
433  } dest;
434 
435  TAILQ_ENTRY(Assignment) assignments;
436 };
437 
442 struct Con {
443  bool mapped;
444  enum {
445  CT_ROOT = 0,
446  CT_OUTPUT = 1,
447  CT_CON = 2,
448  CT_FLOATING_CON = 3,
449  CT_WORKSPACE = 4,
450  CT_DOCKAREA = 5
451  } type;
452  struct Con *parent;
453 
454  struct Rect rect;
455  struct Rect window_rect;
456  struct Rect deco_rect;
458  struct Rect geometry;
459 
460  char *name;
461 
464  int num;
465 
466  /* a sticky-group is an identifier which bundles several containers to a
467  * group. The contents are shared between all of them, that is they are
468  * displayed on whichever of the containers is currently visible */
470 
471  /* user-definable mark to jump to this container later */
472  char *mark;
473 
474  double percent;
475 
476  /* proportional width/height, calculated from WM_NORMAL_HINTS, used to
477  * apply an aspect ratio to windows (think of MPlayer) */
480  /* the wanted size of the window, used in combination with size
481  * increments (see below). */
484 
485  /* 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  /* timer used for disabling urgency */
500  struct ev_timer *urgency_timer;
501 
502  /* ids/pixmap/graphics context for the frame window */
503  xcb_window_t frame;
504  xcb_pixmap_t pixmap;
505  xcb_gcontext_t pm_gc;
507 
510 
511  /* Only workspace-containers can have floating clients */
512  TAILQ_HEAD(floating_head, Con) floating_head;
513 
514  TAILQ_HEAD(nodes_head, Con) nodes_head;
515  TAILQ_HEAD(focus_head, Con) focus_head;
516 
517  TAILQ_HEAD(swallow_head, Match) swallow_head;
518 
519  enum { CF_NONE = 0, CF_OUTPUT = 1, CF_GLOBAL = 2 } fullscreen_mode;
520  /* layout is the layout of this container: one of split[v|h], stacked or
521  * tabbed. Special containers in the tree (above workspaces) have special
522  * layouts like dockarea or output.
523  *
524  * last_split_layout is one of splitv or splith to support the old "layout
525  * default" command which by now should be "layout splitv" or "layout
526  * splith" explicitly.
527  *
528  * workspace_layout is only for type == CT_WORKSPACE cons. When you change
529  * the layout of a workspace without any children, i3 cannot just set the
530  * layout (because workspaces need to be splitv/splith to allow focus
531  * parent and opening new containers). Instead, it stores the requested
532  * layout in workspace_layout and creates a new split container with that
533  * layout whenever a new container is attached to the workspace. */
534  enum {
535  L_DEFAULT = 0,
536  L_STACKED = 1,
537  L_TABBED = 2,
538  L_DOCKAREA = 3,
539  L_OUTPUT = 4,
540  L_SPLITV = 5,
541  L_SPLITH = 6
542  } layout, last_split_layout, workspace_layout;
550  enum {
551  FLOATING_AUTO_OFF = 0,
552  FLOATING_USER_OFF = 1,
553  FLOATING_AUTO_ON = 2,
554  FLOATING_USER_ON = 3
555  } floating;
556 
562  uint8_t ignore_unmap;
563 
564  TAILQ_ENTRY(Con) nodes;
565  TAILQ_ENTRY(Con) focused;
566  TAILQ_ENTRY(Con) all_cons;
567  TAILQ_ENTRY(Con) floating_windows;
568 
570  void(*on_remove_child)(Con *);
571 
572  enum {
573  SCRATCHPAD_NONE = 0,
574  SCRATCHPAD_FRESH = 1,
575  SCRATCHPAD_CHANGED = 2
576  } scratchpad_state;
577 
578  /* The ID of this container before restarting. Necessary to correctly
579  * interpret back-references in the JSON (such as the focus stack). */
580  int old_id;
581 };
582 
583 #endif