26 __i3->
type = CT_OUTPUT;
29 x_set_name(__i3,
"[i3 con] pseudo-output __i3");
39 DLOG(
"adding main content container\n");
41 content->
type = CT_CON;
51 ws->
type = CT_WORKSPACE;
56 x_set_name(ws,
"[i3 con] workspace __i3_scratch");
66bool tree_restore(
const char *path, xcb_get_geometry_reply_t *geometry) {
72 LOG(
"%s does not exist, not restoring tree\n", globbed);
77 if ((len =
slurp(globbed, &buf)) < 0) {
93 DLOG(
"appended tree, using new root\n");
101 DLOG(
"out = %p\n", out);
103 DLOG(
"ws = %p\n", ws);
107 if (strcmp(out->
name,
"__i3") != 0) {
108 DLOG(
"Adding pseudo-output __i3 during inplace restart\n");
162 if (con->
type == CT_FLOATING_CON) {
164 if (con->
type != CT_WORKSPACE) {
168 DLOG(
"con = %p\n", con);
202 DLOG(
"closing %p, kill_window = %d\n", con, kill_window);
203 Con *child, *nextchild;
204 bool abort_kill =
false;
207 for (child =
TAILQ_FIRST(&(con->nodes_head)); child;) {
209 DLOG(
"killing child=%p\n", child);
217 DLOG(
"One of the children could not be killed immediately (WM_DELETE sent), aborting.\n");
221 if (con->
window != NULL) {
226 xcb_void_cookie_t cookie;
231 XCB_CW_EVENT_MASK, (uint32_t[]){XCB_NONE});
241 long data[] = {XCB_ICCCM_WM_STATE_WITHDRAWN, XCB_NONE};
242 cookie = xcb_change_property(
conn, XCB_PROP_MODE_REPLACE,
243 con->
window->
id, A_WM_STATE, A_WM_STATE, 32, 2, data);
250 xcb_change_save_set(
conn, XCB_SET_MODE_DELETE, con->
window->
id);
277 DLOG(
"Removing urgency timer of con %p\n", con);
283 if (con->
type != CT_FLOATING_CON) {
297 if (!dont_kill_parent) {
305 DLOG(
"Closing workspace container %s, updating EWMH atoms\n", ws->
name);
314 DLOG(
"not changing focus, the container was not focused before\n");
318 if (!dont_kill_parent) {
319 CALL(parent, on_remove_child);
332 DLOG(
"Floating containers can't be split.\n");
336 if (con->
type == CT_WORKSPACE) {
339 DLOG(
"Changing workspace_layout to L_DEFAULT\n");
342 DLOG(
"Changing orientation of workspace\n");
364 DLOG(
"Just changing orientation of existing container\n");
368 DLOG(
"Splitting in orientation %d\n", orientation);
374 new->parent = parent;
401 ELOG(
"'focus parent': Focus is already on the workspace, cannot go higher than that.\n");
416 DLOG(
"cannot go down\n");
418 }
else if (next->
type == CT_FLOATING_CON) {
422 if (child ==
TAILQ_END(&(next->focus_head))) {
423 DLOG(
"cannot go down\n");
441 if (con->
type == CT_WORKSPACE) {
444 TAILQ_FOREACH (current, &(con->floating_head), floating_windows) {
460 DLOG(
"-- BEGIN RENDERING --\n");
469 DLOG(
"-- END RENDERING --\n");
474 DLOG(
"Cannot change workspace while in global fullscreen mode.\n");
483 if (!current_output) {
495 Con *workspace = NULL;
510 Con *first_wrap = NULL;
512 if (con->
type == CT_WORKSPACE) {
515 goto handle_workspace;
518 while (con->
type != CT_WORKSPACE) {
531 if (con->
type == CT_FLOATING_CON) {
532 if (orientation !=
HORIZ) {
538 Con *next = previous ?
TAILQ_PREV(con, floating_head, floating_windows)
542 next = previous ?
TAILQ_LAST(&(parent->floating_head), floating_head)
552 Con *
const next = previous ?
TAILQ_PREV(con, nodes_head, nodes)
558 Con *
const wrap = previous ?
TAILQ_LAST(&(parent->nodes_head), nodes_head)
582 assert(con->
type == CT_WORKSPACE);
589 return workspace ? workspace : first_wrap;
601 if (next->
type == CT_WORKSPACE) {
610 if (focus_tiling != next) {
611 focus = focus_tiling;
619 }
else if (next->
type == CT_FLOATING_CON) {
623 while (
TAILQ_LAST(&(parent->floating_head), floating_head) != next) {
624 Con *last =
TAILQ_LAST(&(parent->floating_head), floating_head);
625 TAILQ_REMOVE(&(parent->floating_head), last, floating_windows);
661 Con *current, *child, *parent = con->
parent;
662 DLOG(
"Checking if I can flatten con = %p / %s\n", con, con->
name);
665 if (con->
type != CT_CON ||
673 if (child == NULL ||
TAILQ_NEXT(child, nodes) != NULL) {
677 DLOG(
"child = %p, con = %p, parent = %p\n", child, con, parent);
690 DLOG(
"Alright, I have to flatten this situation now. Stay calm.\n");
694 DLOG(
"detaching...\n");
698 DLOG(
"detaching current=%p / %s\n", current, current->
name);
700 DLOG(
"re-attaching\n");
707 DLOG(
"attaching to focus list\n");
711 DLOG(
"re-attached all\n");
714 if (focus_next != NULL &&
716 DLOG(
"restoring focus to focus_next=%p\n", focus_next);
719 DLOG(
"restored focus.\n");
723 DLOG(
"closing redundant cons\n");
737 while (current != NULL) {
744 while (current != NULL) {
Con * con_get_fullscreen_con(Con *con, fullscreen_mode_t fullscreen_mode)
Returns the first fullscreen node below this node.
void con_set_urgency(Con *con, bool urgent)
Set urgency flag to the container, all the parent containers and the workspace.
bool con_is_floating(Con *con)
Returns true if the node is floating.
orientation_t con_orientation(Con *con)
Returns the orientation of the given container (for stacked containers, vertical orientation is used ...
void con_force_split_parents_redraw(Con *con)
force parent split containers to be redrawn
void con_update_parents_urgency(Con *con)
Make all parent containers urgent if con is urgent or clear the urgent flag of all parent containers ...
Con * con_new(Con *parent, i3Window *window)
A wrapper for con_new_skeleton, to retain the old con_new behaviour.
Con * con_get_workspace(Con *con)
Gets the workspace container this node is on.
bool con_is_split(Con *con)
Returns true if a container should be considered split.
Con * con_descend_tiling_focused(Con *con)
Returns the focused con inside this client, descending the tree as far as possible.
bool con_fullscreen_permits_focusing(Con *con)
Returns true if changing the focus to con would be allowed considering the fullscreen focus constrain...
void con_detach(Con *con)
Detaches the given container from its current parent.
void con_fix_percent(Con *con)
Updates the percent attribute of the children of the given container.
void con_attach(Con *con, Con *parent, bool ignore_focus)
Attaches the given container to the given parent.
void con_free(Con *con)
Frees the specified container.
int con_num_children(Con *con)
Returns the number of children of this container.
void con_activate(Con *con)
Sets input focus to the given container and raises it to the top.
Con * con_next_focused(Con *con)
Returns the container which will be focused next when the given container is not available anymore.
Con * con_descend_focused(Con *con)
Returns the focused con inside this client, descending the tree as far as possible.
void ewmh_update_desktop_properties(void)
Updates all the EWMH desktop properties.
void tree_append_json(Con *con, const char *buf, const size_t len, char **errormsg)
char * output_primary_name(Output *output)
Retrieves the primary name of an output.
Con * output_get_content(Con *output)
Returns the output container below the given output container.
Output * get_output_containing(unsigned int x, unsigned int y)
Returns the active (!) output which contains the coordinates x, y or NULL if there is no output which...
Output * get_output_next(direction_t direction, Output *current, output_close_far_t close_far)
Gets the output which is the next one in the given direction.
void render_con(Con *con)
"Renders" the given container (and its children), meaning that all rects are updated correctly.
void restore_open_placeholder_windows(Con *parent)
Open placeholder windows for all children of parent.
void tree_flatten(Con *con)
tree_flatten() removes pairs of redundant split containers, e.g.: [workspace, horizontal] [v-split] [...
bool tree_restore(const char *path, xcb_get_geometry_reply_t *geometry)
Loads tree from ~/.i3/_restart.json (used for in-place restarts).
static Con * get_tree_next_workspace(Con *con, direction_t direction)
void tree_next(Con *con, direction_t direction)
Changes focus in the given direction.
bool level_up(void)
Moves focus one level up.
static Con * _create___i3(void)
static Con * get_tree_next(Con *con, direction_t direction)
bool level_down(void)
Moves focus one level down.
Con * tree_open_con(Con *con, i3Window *window)
Opens an empty container in the current container.
bool tree_close_internal(Con *con, kill_window_t kill_window, bool dont_kill_parent)
Closes the given container including all children.
static void mark_unmapped(Con *con)
void tree_init(xcb_get_geometry_reply_t *geometry)
Initializes the tree by creating the root node, adding all RandR outputs to the tree (that means rand...
struct all_cons_head all_cons
void tree_render(void)
Renders the tree, that is rendering all outputs using render_con() and pushing the changes to X11 usi...
void tree_split(Con *con, orientation_t orientation)
Splits (horizontally or vertically) the given container by creating a new container which contains th...
Con * get_tree_next_sibling(Con *con, position_t direction)
Get the previous / next sibling.
orientation_t orientation_from_direction(direction_t direction)
Convert a direction to its corresponding orientation.
position_t position_from_direction(direction_t direction)
Convert a direction to its corresponding position.
ssize_t slurp(const char *path, char **buf)
Slurp reads path in its entirety into buf, returning the length of the file or -1 if the file could n...
void window_free(i3Window *win)
Frees an i3Window and all its members.
void workspace_update_urgent_flag(Con *ws)
Goes through all clients on the given workspace and updates the workspace’s urgent flag accordingly.
void workspace_show(Con *workspace)
Switches to the given workspace.
bool workspace_is_visible(Con *ws)
Returns true if the workspace is currently visible.
Con * workspace_encapsulate(Con *ws)
Creates a new container and re-parents all of children from the given workspace into it.
void x_set_warp_to(Rect *rect)
Set warp_to coordinates.
void x_window_kill(xcb_window_t window, kill_window_t kill_window)
Kills the given X11 window using WM_DELETE_WINDOW (if supported).
void x_set_name(Con *con, const char *name)
Sets the WM_NAME property (so, no UTF8, but used only for debugging anyways) of the given name.
void x_push_changes(Con *con)
Pushes all changes (state of each node, see x_push_node() and the window stack) to X11.
void x_con_kill(Con *con)
Kills the window decoration associated with the given container.
void ipc_send_window_event(const char *property, Con *con)
For the window events we send, along the usual "change" field, also the window container,...
xcb_connection_t * conn
XCB connection and root screen.
struct ev_loop * main_loop
@ FOCUS_WRAPPING_WORKSPACE
kill_window_t
parameter to specify whether tree_close_internal() and x_window_kill() should kill only this specific...
void add_ignore_event(const int sequence, const int response_type)
Adds the given sequence to the list of events which are ignored.
char * resolve_tilde(const char *path)
This function resolves ~ in pathnames.
char * sstrdup(const char *str)
Safe-wrapper around strdup which exits if malloc returns NULL (meaning that there is no more memory a...
bool path_exists(const char *path)
Checks if the given path exists by calling stat().
#define TAILQ_FOREACH(var, head, field)
#define TAILQ_INSERT_TAIL(head, elm, field)
#define TAILQ_PREV(elm, headname, field)
#define TAILQ_REPLACE(head, elm, elm2, field)
#define TAILQ_FIRST(head)
#define TAILQ_REMOVE(head, elm, field)
#define TAILQ_NEXT(elm, field)
#define TAILQ_HEAD_INITIALIZER(head)
#define TAILQ_EMPTY(head)
#define TAILQ_INSERT_BEFORE(listelm, elm, field)
#define TAILQ_LAST(head, headname)
#define TAILQ_INSERT_HEAD(head, elm, field)
#define CALL(obj, member,...)
#define GREP_FIRST(dest, head, condition)
focus_wrapping_t focus_wrapping
When focus wrapping is enabled (the default), attempting to move focus past the edge of the screen (i...
An Output is a physical output on your graphics driver.
Con * con
Pointer to the Con which represents this output.
A 'Window' is a type which contains an xcb_window_t and all the related information (hints like _NET_...
A 'Con' represents everything from the X11 root window down to a single X11 window.
layout_t workspace_layout
int num
the workspace number, if this Con is of type CT_WORKSPACE and the workspace is not a named workspace ...
struct ev_timer * urgency_timer
fullscreen_mode_t fullscreen_mode