2 #define I3__FILE__ "config_directives.c"
18 #define y(x, ...) yajl_gen_ ## x (cmd_output->json_gen, ##__VA_ARGS__)
19 #define ystr(str) yajl_gen_string(cmd_output->json_gen, (unsigned char*)str, strlen(str))
20 #define ysuccess(success) do { \
41 DLOG(
"Initializing criteria, current_match = %p, state = %d\n",
current_match, _state);
54 CFGFUN(criteria_add,
const char *ctype,
const char *cvalue) {
55 DLOG(
"ctype=*%s*, cvalue=*%s*\n", ctype, cvalue);
57 if (strcmp(ctype,
"class") == 0) {
62 if (strcmp(ctype,
"instance") == 0) {
67 if (strcmp(ctype,
"window_role") == 0) {
72 if (strcmp(ctype,
"con_id") == 0) {
74 long parsed = strtol(cvalue, &end, 10);
75 if (parsed == LONG_MIN ||
78 (end && *end !=
'\0')) {
79 ELOG(
"Could not parse con id \"%s\"\n", cvalue);
87 if (strcmp(ctype,
"id") == 0) {
89 long parsed = strtol(cvalue, &end, 10);
90 if (parsed == LONG_MIN ||
93 (end && *end !=
'\0')) {
94 ELOG(
"Could not parse window id \"%s\"\n", cvalue);
102 if (strcmp(ctype,
"con_mark") == 0) {
107 if (strcmp(ctype,
"title") == 0) {
112 if (strcmp(ctype,
"urgent") == 0) {
113 if (strcasecmp(cvalue,
"latest") == 0 ||
114 strcasecmp(cvalue,
"newest") == 0 ||
115 strcasecmp(cvalue,
"recent") == 0 ||
116 strcasecmp(cvalue,
"last") == 0) {
118 }
else if (strcasecmp(cvalue,
"oldest") == 0 ||
119 strcasecmp(cvalue,
"first") == 0) {
125 ELOG(
"Unknown criterion: %s\n", ctype);
135 return (strcasecmp(str,
"1") == 0 ||
136 strcasecmp(str,
"yes") == 0 ||
137 strcasecmp(str,
"true") == 0 ||
138 strcasecmp(str,
"on") == 0 ||
139 strcasecmp(str,
"enable") == 0 ||
140 strcasecmp(str,
"active") == 0);
149 if (strstr(str,
"Mod1") != NULL)
151 if (strstr(str,
"Mod2") != NULL)
153 if (strstr(str,
"Mod3") != NULL)
155 if (strstr(str,
"Mod4") != NULL)
157 if (strstr(str,
"Mod5") != NULL)
159 if (strstr(str,
"Control") != NULL ||
160 strstr(str,
"Ctrl") != NULL)
162 if (strstr(str,
"Shift") != NULL)
164 if (strstr(str,
"Mode_switch") != NULL)
181 CFGFUN(binding,
const char *bindtype,
const char *modifiers,
const char *key,
const char *release,
const char *command) {
183 DLOG(
"bindtype %s, modifiers %s, key %s, release %s\n", bindtype, modifiers, key, release);
184 new_binding->
release = (release != NULL ? B_UPON_KEYRELEASE : B_UPON_KEYPRESS);
185 if (strcmp(bindtype,
"bindsym") == 0) {
189 new_binding->
keycode = atoi(key);
190 if (new_binding->
keycode == 0) {
191 ELOG(
"Could not parse \"%s\" as a keycode, ignoring this binding.\n", key);
207 CFGFUN(mode_binding,
const char *bindtype,
const char *modifiers,
const char *key,
const char *release,
const char *command) {
209 DLOG(
"bindtype %s, modifiers %s, key %s, release %s\n", bindtype, modifiers, key, release);
210 new_binding->
release = (release != NULL ? B_UPON_KEYRELEASE : B_UPON_KEYPRESS);
211 if (strcmp(bindtype,
"bindsym") == 0) {
215 new_binding->
keycode = atoi(key);
216 if (new_binding->
keycode == 0) {
217 ELOG(
"Could not parse \"%s\" as a keycode, ignoring this binding.\n", key);
226 CFGFUN(enter_mode,
const char *modename) {
227 if (strcasecmp(modename,
"default") == 0) {
228 ELOG(
"You cannot use the name \"default\" for your mode\n");
231 DLOG(
"\t now in mode %s\n", modename);
240 CFGFUN(exec,
const char *exectype,
const char *no_startup_id,
const char *command) {
242 new->command =
sstrdup(command);
243 new->no_startup_id = (no_startup_id != NULL);
244 if (strcmp(exectype,
"exec") == 0) {
253 ELOG(
"Match is empty, ignoring this for_window statement\n");
256 DLOG(
"\t should execute command %s for the criteria mentioned above\n", command);
258 assignment->
type = A_COMMAND;
274 CFGFUN(floating_modifier,
const char *modifiers) {
278 CFGFUN(default_orientation,
const char *orientation) {
279 if (strcmp(orientation,
"horizontal") == 0)
281 else if (strcmp(orientation,
"vertical") == 0)
286 CFGFUN(workspace_layout,
const char *layout) {
287 if (strcmp(layout,
"default") == 0)
289 else if (strcmp(layout,
"stacking") == 0 ||
290 strcmp(layout,
"stacked") == 0)
295 CFGFUN(new_window,
const char *windowtype,
const char *border,
const long width) {
302 if (strcmp(border,
"1pixel") == 0) {
305 }
else if (strcmp(border,
"none") == 0) {
308 }
else if (strcmp(border,
"pixel") == 0) {
310 border_width =
width;
313 border_width =
width;
316 if (strcmp(windowtype,
"new_window") == 0) {
325 CFGFUN(hide_edge_borders,
const char *borders) {
326 if (strcmp(borders,
"vertical") == 0)
328 else if (strcmp(borders,
"horizontal") == 0)
330 else if (strcmp(borders,
"both") == 0)
332 else if (strcmp(borders,
"none") == 0)
339 CFGFUN(focus_follows_mouse,
const char *value) {
343 CFGFUN(force_xinerama,
const char *value) {
347 CFGFUN(force_focus_wrapping,
const char *value) {
359 CFGFUN(force_display_urgency_hint,
const long duration_ms) {
363 CFGFUN(workspace,
const char *workspace,
const char *output) {
364 DLOG(
"Assigning workspace \"%s\" to output \"%s\"\n", workspace, output);
369 bool duplicate =
false;
371 if (strcasecmp(assignment->
name, workspace) == 0) {
372 ELOG(
"You have a duplicate workspace assignment for workspace \"%s\"\n",
390 CFGFUN(restart_state,
const char *path) {
394 CFGFUN(popup_during_fullscreen,
const char *value) {
395 if (strcmp(value,
"ignore") == 0) {
397 }
else if (strcmp(value,
"leave_fullscreen") == 0) {
404 CFGFUN(color_single,
const char *colorclass,
const char *color) {
409 CFGFUN(color,
const char *colorclass,
const char *border,
const char *background,
const char *text,
const char *indicator) {
410 #define APPLY_COLORS(classname) \
412 if (strcmp(colorclass, "client." #classname) == 0) { \
413 config.client.classname.border = get_colorpixel(border); \
414 config.client.classname.background = get_colorpixel(background); \
415 config.client.classname.text = get_colorpixel(text); \
416 if (indicator != NULL) { \
417 config.client. classname .indicator = get_colorpixel(indicator); \
432 ELOG(
"Match is empty, ignoring this assignment\n");
435 DLOG(
"new assignment, using above criteria, to workspace %s\n", workspace);
438 assignment->
type = A_TO_WORKSPACE;
455 current_bar.
mode = (strcmp(mode,
"dock") == 0 ? M_DOCK : (strcmp(mode,
"hide") == 0 ? M_HIDE : M_INVISIBLE));
458 CFGFUN(bar_hidden_state,
const char *hidden_state) {
459 current_bar.
hidden_state = (strcmp(hidden_state,
"hide") == 0 ? S_HIDE : S_SHOW);
477 CFGFUN(bar_modifier,
const char *modifier) {
478 if (strcmp(modifier,
"Mod1") == 0)
480 else if (strcmp(modifier,
"Mod2") == 0)
482 else if (strcmp(modifier,
"Mod3") == 0)
484 else if (strcmp(modifier,
"Mod4") == 0)
486 else if (strcmp(modifier,
"Mod5") == 0)
488 else if (strcmp(modifier,
"Control") == 0 ||
489 strcmp(modifier,
"Ctrl") == 0)
491 else if (strcmp(modifier,
"Shift") == 0)
495 CFGFUN(bar_position,
const char *position) {
496 current_bar.
position = (strcmp(position,
"top") == 0 ? P_TOP : P_BOTTOM);
499 CFGFUN(bar_i3bar_command,
const char *i3bar_command) {
504 CFGFUN(bar_color,
const char *colorclass,
const char *border,
const char *background,
const char *text) {
505 #define APPLY_COLORS(classname) \
507 if (strcmp(colorclass, #classname) == 0) { \
508 if (text != NULL) { \
510 current_bar.colors. classname ## _border = sstrdup(border); \
511 current_bar.colors. classname ## _bg = sstrdup(background); \
512 current_bar.colors. classname ## _text = sstrdup(text); \
515 current_bar.colors. classname ## _bg = sstrdup(background); \
516 current_bar.colors. classname ## _text = sstrdup(border); \
529 CFGFUN(bar_socket_path,
const char *socket_path) {
539 CFGFUN(bar_color_single,
const char *colorclass,
const char *color) {
540 if (strcmp(colorclass,
"background") == 0)
542 else if (strcmp(colorclass,
"separator") == 0)
548 CFGFUN(bar_status_command,
const char *command) {
553 CFGFUN(bar_workspace_buttons,
const char *value) {
558 DLOG(
"\t new bar configuration finished, saving.\n");
572 memcpy(bar_config, ¤t_bar,
sizeof(
Barconfig));
575 memset(¤t_bar,
'\0',
sizeof(
Barconfig));
The configuration file can contain multiple sets of bindings.
char * font
Font specification for all text rendered on the bar.
border_style_t default_border
The default border style for new windows.
A 'Con' represents everything from the X11 root window down to a single X11 window.
char * symbol
Symbol the user specified in configfile, if any.
Stores which workspace (by name) goes to which output.
#define TAILQ_INSERT_TAIL(head, elm, field)
struct barconfig_head barconfigs
static struct bindings_head * current_bindings
const char * restart_state_path
bool force_focus_wrapping
Think of the following layout: Horizontal workspace with a tabbed con on the left of the screen and a...
An Assignment makes specific windows go to a specific workspace/output or run a command for that wind...
enum Barconfig::@5 mode
Bar display mode (hide unless modifier is pressed or show in dock mode or always hide in invisible mo...
bool disable_focus_follows_mouse
By default, focus follows mouse.
int32_t floating_maximum_width
Maximum and minimum dimensions of a floating window.
static char * font_pattern
static Barconfig current_bar
enum Barconfig::@8 position
Bar position (bottom by default).
char * sstrdup(const char *str)
Safe-wrapper around strdup which exits if malloc returns NULL (meaning that there is no more memory a...
bool match_is_empty(Match *match)
Check if a match is empty.
struct Barconfig::bar_colors colors
bool verbose
Enable verbose mode? Useful for debugging purposes.
union Assignment::@17 dest
destination workspace/output/command, depending on the type
char * fake_outputs
Overwrites output detection (for testing), see src/fake_outputs.c.
void * scalloc(size_t size)
Safe-wrapper around calloc which exits if malloc returns NULL (meaning that there is no more memory a...
struct Config::config_client client
bool force_xinerama
By default, use the RandR API for multi-monitor setups.
float workspace_urgency_timer
By default, urgency is cleared immediately when switching to another workspace leads to focusing the ...
void workspace_back_and_forth(void)
Focuses the previously focused workspace.
Holds a keybinding, consisting of a keycode combined with modifiers and the command which is executed...
uint32_t get_colorpixel(const char *hex) __attribute__((const ))
Returns the colorpixel to use for the given hex color (think of HTML).
void match_init(Match *match)
static bool eval_boolstr(const char *str)
uint32_t floating_modifier
The modifier which needs to be pressed in combination with your mouse buttons to do things with float...
int default_orientation
Default orientation for new containers.
char * command
Command, like in command mode.
struct ws_assignments_head ws_assignments
char * tray_output
Output on which the tray should be shown.
enum Binding::@10 release
If true, the binding should be executed upon a KeyRelease event, not a KeyPress (the default)...
struct outputs_head outputs
struct autostarts_head autostarts
char * id
Automatically generated ID for this bar config.
int sasprintf(char **strp, const char *fmt,...)
Safe-wrapper around asprintf which exits if it returns -1 (meaning that there is no more memory avail...
border_style_t default_floating_border
The default border style for new floating windows.
static int criteria_next_state
struct regex * regex_new(const char *pattern)
Creates a new 'regex' struct containing the given pattern and a PCRE compiled regular expression...
static Match current_match
#define APPLY_COLORS(classname)
enum Barconfig::@7 modifier
Bar modifier (to show bar when in hide mode).
void * smalloc(size_t size)
Safe-wrapper around malloc which exits if malloc returns NULL (meaning that there is no more memory a...
i3Font load_font(const char *pattern, const bool fallback)
Loads a font for usage, also getting its height.
struct autostarts_always_head autostarts_always
int32_t floating_minimum_width
int32_t floating_maximum_height
char * i3bar_command
Command that should be run to execute i3bar, give a full path if i3bar is not in your $PATH...
static uint32_t modifiers_from_str(const char *str)
adjacent_t hide_edge_borders
Remove borders if they are adjacent to the screen edge.
enum Barconfig::@6 hidden_state
void * srealloc(void *ptr, size_t size)
Safe-wrapper around realloc which exits if realloc returns NULL (meaning that there is no more memory...
uint32_t keycode
Keycode to bind.
#define TAILQ_FOREACH(var, head, field)
void match_copy(Match *dest, Match *src)
Copies the data of a match from src to dest.
uint32_t mods
Bitmask consisting of BIND_MOD_1, BIND_MODE_SWITCH, …
bool hide_workspace_buttons
Hide workspace buttons? Configuration option is 'workspace_buttons no' but we invert the bool to get ...
int32_t floating_minimum_height
bool workspace_auto_back_and_forth
Automatic workspace back and forth switching.
#define SLIST_INSERT_HEAD(head, elm, field)
char * command
Command, like in command mode.
char ** outputs
Outputs on which this bar should show up on.
struct bindings_head * bindings
enum Assignment::@16 type
type of this assignment:
struct bindings_head * bindings
Match match
the criteria to check if a window matches
void set_font(i3Font *font)
Defines the font to be used for the forthcoming calls.
char * status_command
Command that should be run to get a statusline, for example 'i3status'.
Holds the status bar configuration (i3bar).
char * socket_path
Path to the i3 IPC socket.
struct assignments_head assignments
Holds a command specified by either an:
enum Config::@4 popup_during_fullscreen
What should happen when a new popup is opened during fullscreen mode.
int num_outputs
Number of outputs in the outputs array.