i3
|
00001 /* 00002 * vim:ts=8:expandtab 00003 * 00004 * i3 - an improved dynamic tiling window manager 00005 * 00006 * © 2009-2010 Michael Stapelberg and contributors 00007 * 00008 * See file LICENSE for license information. 00009 * 00010 * include/data.h: This file defines all data structures used by i3 00011 * 00012 */ 00013 #include <xcb/xcb.h> 00014 #include <xcb/randr.h> 00015 #include <xcb/xcb_atom.h> 00016 #include <stdbool.h> 00017 00018 #ifndef _DATA_H 00019 #define _DATA_H 00020 #include "queue.h" 00021 00022 /* 00023 * To get the big concept: There are helper structures like struct Colorpixel 00024 * or struct Stack_Window. Everything which is also defined as type (see 00025 * forward definitions) is considered to be a major structure, thus important. 00026 * 00027 * Let’s start from the biggest to the smallest: 00028 * 00029 * - An Output is a physical output on your graphics driver. Outputs which 00030 * are currently in use have (output->active == true). Each output has a 00031 * position and a mode. An output usually corresponds to one connected 00032 * screen (except if you are running multiple screens in clone mode). 00033 * 00034 * - Each Output contains Workspaces. The concept is known from various 00035 * other window managers. Basically, a workspace is a specific set of 00036 * windows, usually grouped thematically (irc, www, work, …). You can switch 00037 * between these. 00038 * 00039 * - Each Workspace has a table, which is our layout abstraction. You manage 00040 * your windows by moving them around in your table. It grows as necessary. 00041 * 00042 * - Each cell of the table has a container, which can be in default or 00043 * stacking mode. In default mode, each client is given equally much space 00044 * in the container. In stacking mode, only one client is shown at a time, 00045 * but all the titlebars are rendered at the top. 00046 * 00047 * - Inside the container are clients, which is X11-speak for a window. 00048 * 00049 */ 00050 00051 /* Forward definitions */ 00052 typedef struct Cell Cell; 00053 typedef struct Font i3Font; 00054 typedef struct Container Container; 00055 typedef struct Client Client; 00056 typedef struct Binding Binding; 00057 typedef struct Workspace Workspace; 00058 typedef struct Rect Rect; 00059 typedef struct xoutput Output; 00060 00061 /****************************************************************************** 00062 * Helper types 00063 *****************************************************************************/ 00064 typedef enum { D_LEFT, D_RIGHT, D_UP, D_DOWN } direction_t; 00065 00066 enum { 00067 BIND_NONE = 0, 00068 BIND_SHIFT = XCB_MOD_MASK_SHIFT, /* (1 << 0) */ 00069 BIND_CONTROL = XCB_MOD_MASK_CONTROL, /* (1 << 2) */ 00070 BIND_MOD1 = XCB_MOD_MASK_1, /* (1 << 3) */ 00071 BIND_MOD2 = XCB_MOD_MASK_2, /* (1 << 4) */ 00072 BIND_MOD3 = XCB_MOD_MASK_3, /* (1 << 5) */ 00073 BIND_MOD4 = XCB_MOD_MASK_4, /* (1 << 6) */ 00074 BIND_MOD5 = XCB_MOD_MASK_5, /* (1 << 7) */ 00075 BIND_MODE_SWITCH = (1 << 8) 00076 }; 00077 00096 struct Rect { 00097 uint32_t x; 00098 uint32_t y; 00099 uint32_t width; 00100 uint32_t height; 00101 } __attribute__((packed)); 00102 00107 struct Cell { 00108 int row; 00109 int column; 00110 }; 00111 00116 struct Colorpixel { 00117 uint32_t pixel; 00118 char *hex; 00119 SLIST_ENTRY(Colorpixel) colorpixels; 00120 }; 00121 00122 struct Cached_Pixmap { 00123 xcb_pixmap_t id; 00124 00125 /* We’re going to paint on it, so a graphics context will be needed */ 00126 xcb_gcontext_t gc; 00127 00128 /* The rect with which the pixmap was created */ 00129 Rect rect; 00130 00131 /* The rect of the object to which this pixmap belongs. Necessary to 00132 * find out when we need to re-create the pixmap. */ 00133 Rect *referred_rect; 00134 00135 xcb_drawable_t referred_drawable; 00136 }; 00137 00143 struct Stack_Window { 00144 xcb_window_t window; 00145 struct Cached_Pixmap pixmap; 00146 Rect rect; 00147 00149 Container *container; 00150 00151 SLIST_ENTRY(Stack_Window) stack_windows; 00152 }; 00153 00154 struct Ignore_Event { 00155 int sequence; 00156 time_t added; 00157 00158 SLIST_ENTRY(Ignore_Event) ignore_events; 00159 }; 00160 00166 struct keyvalue_element { 00167 uint32_t key; 00168 void *value; 00169 TAILQ_ENTRY(keyvalue_element) elements; 00170 }; 00171 00172 /****************************************************************************** 00173 * Major types 00174 *****************************************************************************/ 00175 00182 struct Workspace { 00184 int num; 00185 00187 char *utf8_name; 00188 00190 char *name; 00191 00193 int name_len; 00194 00196 int text_width; 00197 00199 Rect rect; 00200 00202 int cols; 00204 int rows; 00205 00208 int current_row; 00211 int current_col; 00212 00214 bool auto_float; 00216 bool floating_hidden; 00217 00219 char *preferred_output; 00220 00222 bool urgent; 00223 00226 Client *fullscreen_client; 00227 00231 SLIST_HEAD(focus_stack_head, Client) focus_stack; 00232 00236 TAILQ_HEAD(floating_clients_head, Client) floating_clients; 00237 00239 Output *output; 00240 00244 Container ***table; 00245 00250 float *width_factor; 00251 float *height_factor; 00252 00253 TAILQ_ENTRY(Workspace) workspaces; 00254 }; 00255 00261 struct Binding { 00265 char *symbol; 00266 00272 xcb_keycode_t *translated_to; 00273 00274 uint32_t number_keycodes; 00275 00277 uint32_t keycode; 00278 00280 uint32_t mods; 00281 00283 char *command; 00284 00285 TAILQ_ENTRY(Binding) bindings; 00286 }; 00287 00292 struct Autostart { 00294 char *command; 00295 TAILQ_ENTRY(Autostart) autostarts; 00296 }; 00297 00303 struct Assignment { 00304 char *windowclass_title; 00308 enum { 00309 ASSIGN_FLOATING_NO, /* don’t float, but put on a workspace */ 00310 ASSIGN_FLOATING_ONLY, /* float, but don’t assign on a workspace */ 00311 ASSIGN_FLOATING /* float and put on a workspace */ 00312 } floating; 00313 00315 int workspace; 00316 TAILQ_ENTRY(Assignment) assignments; 00317 }; 00318 00325 struct Font { 00327 char *name; 00329 char *pattern; 00331 int height; 00333 xcb_font_t id; 00334 00335 TAILQ_ENTRY(Font) fonts; 00336 }; 00337 00342 struct Client { 00346 bool initialized; 00347 00350 Cell old_position; 00351 00353 Container *container; 00356 Workspace *workspace; 00357 00359 Rect rect; 00362 Rect floating_rect; 00364 Rect child_rect; 00365 00368 int proportional_height; 00369 int proportional_width; 00370 00371 int base_height; 00372 int base_width; 00373 00375 int border_width; 00376 00379 int width_increment; 00380 int height_increment; 00381 00384 int desired_height; 00385 00387 char *name; 00393 int name_len; 00396 bool uses_net_wm_name; 00397 00400 char *window_class_instance; 00401 char *window_class_class; 00402 00404 char *mark; 00405 00408 xcb_window_t leader; 00409 00411 bool fullscreen; 00412 00419 enum { FLOATING_AUTO_OFF = 0, FLOATING_USER_OFF = 1, FLOATING_AUTO_ON = 2, FLOATING_USER_ON = 3 } floating; 00420 00423 enum { TITLEBAR_TOP = 0, TITLEBAR_LEFT, TITLEBAR_RIGHT, TITLEBAR_BOTTOM, TITLEBAR_OFF } titlebar_position; 00424 00427 bool borderless; 00428 00431 bool dock; 00432 00434 bool urgent; 00435 00436 /* After leaving fullscreen mode, a client needs to be reconfigured 00437 * (configuration = setting X, Y, width and height). By setting the 00438 * force_reconfigure flag, render_layout() will reconfigure the 00439 * client. */ 00440 bool force_reconfigure; 00441 00442 /* When reparenting a window, an unmap-notify is sent. As we delete 00443 * windows when they’re unmapped, we need to ignore that 00444 * one. Therefore, this flag is set when reparenting. */ 00445 bool awaiting_useless_unmap; 00446 00447 /* XCB contexts */ 00448 xcb_window_t frame; 00450 xcb_gcontext_t titlegc; 00452 xcb_window_t child; 00456 CIRCLEQ_ENTRY(Client) clients; 00457 SLIST_ENTRY(Client) dock_clients; 00458 SLIST_ENTRY(Client) focus_clients; 00459 TAILQ_ENTRY(Client) floating_clients; 00460 }; 00461 00467 struct Container { 00468 /* Those are speaking for themselves: */ 00469 Client *currently_focused; 00470 int colspan; 00471 int rowspan; 00472 00473 /* Position of the container inside our table */ 00474 int row; 00475 int col; 00476 /* Xinerama: X/Y of the container */ 00477 int x; 00478 int y; 00479 /* Width/Height of the container. Changeable by the user */ 00480 int width; 00481 int height; 00482 00483 /* When in stacking mode, we draw the titlebars of each client onto a 00484 * separate window */ 00485 struct Stack_Window stack_win; 00486 00487 /* Backpointer to the workspace this container is in */ 00488 Workspace *workspace; 00489 00490 /* Ensure MODE_DEFAULT maps to 0 because we use calloc for 00491 * initialization later */ 00492 enum { MODE_DEFAULT = 0, MODE_STACK, MODE_TABBED } mode; 00493 00494 /* When in stacking, one can either have unlimited windows inside the 00495 * container or set a limit for the rows or columns the stack window 00496 * should display to use the screen more efficiently. */ 00497 enum { STACK_LIMIT_NONE = 0, STACK_LIMIT_COLS, STACK_LIMIT_ROWS } stack_limit; 00498 00499 /* The number of columns or rows to limit to, see stack_limit */ 00500 int stack_limit_value; 00501 00502 CIRCLEQ_HEAD(client_head, Client) clients; 00503 }; 00504 00512 struct xoutput { 00514 xcb_randr_output_t id; 00516 char *name; 00517 00520 bool active; 00521 00524 bool changed; 00525 bool to_be_disabled; 00526 00528 Workspace *current_workspace; 00529 00531 Rect rect; 00532 00534 xcb_window_t bar; 00535 xcb_gcontext_t bargc; 00536 00539 SLIST_HEAD(dock_clients_head, Client) dock_clients; 00540 00541 TAILQ_ENTRY(xoutput) outputs; 00542 }; 00543 00544 #endif