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");
66 bool 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)
167 DLOG(
"con = %p\n", con);
201 DLOG(
"closing %p, kill_window = %d\n", con, kill_window);
202 Con *child, *nextchild;
203 bool abort_kill =
false;
208 DLOG(
"killing child=%p\n", child);
216 DLOG(
"One of the children could not be killed immediately (WM_DELETE sent), aborting.\n");
220 if (con->
window != NULL) {
225 xcb_void_cookie_t cookie;
230 XCB_CW_EVENT_MASK, (uint32_t[]){XCB_NONE});
240 long data[] = {XCB_ICCCM_WM_STATE_WITHDRAWN, XCB_NONE};
241 cookie = xcb_change_property(
conn, XCB_PROP_MODE_REPLACE,
242 con->
window->
id, A_WM_STATE, A_WM_STATE, 32, 2, data);
249 xcb_change_save_set(
conn, XCB_SET_MODE_DELETE, con->
window->
id);
276 DLOG(
"Removing urgency timer of con %p\n", con);
282 if (con->
type != CT_FLOATING_CON) {
296 if (!dont_kill_parent)
303 DLOG(
"Closing workspace container %s, updating EWMH atoms\n", ws->
name);
312 DLOG(
"not changing focus, the container was not focused before\n");
316 if (!dont_kill_parent)
317 CALL(parent, on_remove_child);
329 DLOG(
"Floating containers can't be split.\n");
333 if (con->
type == CT_WORKSPACE) {
336 DLOG(
"Changing workspace_layout to L_DEFAULT\n");
339 DLOG(
"Changing orientation of workspace\n");
361 DLOG(
"Just changing orientation of existing container\n");
365 DLOG(
"Splitting in orientation %d\n", orientation);
371 new->parent = parent;
398 ELOG(
"'focus parent': Focus is already on the workspace, cannot go higher than that.\n");
413 DLOG(
"cannot go down\n");
415 }
else if (next->
type == CT_FLOATING_CON) {
420 DLOG(
"cannot go down\n");
436 if (con->
type == CT_WORKSPACE) {
453 DLOG(
"-- BEGIN RENDERING --\n");
462 DLOG(
"-- END RENDERING --\n");
467 DLOG(
"Cannot change workspace while in global fullscreen mode.\n");
472 if (!current_output) {
484 Con *workspace = NULL;
499 Con *first_wrap = NULL;
501 if (con->
type == CT_WORKSPACE) {
504 goto handle_workspace;
507 while (con->
type != CT_WORKSPACE) {
520 if (con->
type == CT_FLOATING_CON) {
521 if (orientation !=
HORIZ) {
527 Con *next = previous ?
TAILQ_PREV(con, floating_head, floating_windows)
541 Con *
const next = previous ?
TAILQ_PREV(con, nodes_head, nodes)
571 assert(con->
type == CT_WORKSPACE);
578 return workspace ? workspace : first_wrap;
590 if (next->
type == CT_WORKSPACE) {
599 if (focus_tiling != next) {
600 focus = focus_tiling;
608 }
else if (next->
type == CT_FLOATING_CON) {
650 Con *current, *child, *parent = con->
parent;
651 DLOG(
"Checking if I can flatten con = %p / %s\n", con, con->
name);
654 if (con->
type != CT_CON ||
661 if (child == NULL ||
TAILQ_NEXT(child, nodes) != NULL)
664 DLOG(
"child = %p, con = %p, parent = %p\n", child, con, parent);
676 DLOG(
"Alright, I have to flatten this situation now. Stay calm.\n");
680 DLOG(
"detaching...\n");
684 DLOG(
"detaching current=%p / %s\n", current, current->
name);
686 DLOG(
"re-attaching\n");
693 DLOG(
"attaching to focus list\n");
697 DLOG(
"re-attached all\n");
700 if (focus_next != NULL &&
702 DLOG(
"restoring focus to focus_next=%p\n", focus_next);
705 DLOG(
"restored focus.\n");
709 DLOG(
"closing redundant cons\n");
723 while (current != NULL) {
730 while (current != NULL) {
void con_free(Con *con)
Frees the specified container.
void window_free(i3Window *win)
Frees an i3Window and all its members.
Con * con
Pointer to the Con which represents this output.
void con_fix_percent(Con *con)
Updates the percent attribute of the children of the given container.
bool tree_restore(const char *path, xcb_get_geometry_reply_t *geometry)
Loads tree from ~/.i3/_restart.json (used for in-place restarts).
void con_detach(Con *con)
Detaches the given container from its current parent.
void tree_append_json(Con *con, const char *buf, const size_t len, char **errormsg)
struct ev_timer * urgency_timer
#define TAILQ_HEAD_INITIALIZER(head)
#define TAILQ_FOREACH(var, head, field)
void x_con_kill(Con *con)
Kills the window decoration associated with the given container.
static Con * get_tree_next(Con *con, direction_t direction)
void x_set_warp_to(Rect *rect)
Set warp_to coordinates.
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, in "container".
void add_ignore_event(const int sequence, const int response_type)
Adds the given sequence to the list of events which are ignored.
An Output is a physical output on your graphics driver.
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 restore_open_placeholder_windows(Con *parent)
Open placeholder windows for all children of parent.
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...
Con * output_get_content(Con *output)
Returns the output container below the given output container.
#define CALL(obj, member,...)
static Con * get_tree_next_workspace(Con *con, direction_t direction)
layout_t workspace_layout
#define GREP_FIRST(dest, head, condition)
char * resolve_tilde(const char *path)
This function resolves ~ in pathnames.
void tree_render(void)
Renders the tree, that is rendering all outputs using render_con() and pushing the changes to X11 usi...
orientation_t orientation_from_direction(direction_t direction)
Convert a direction to its corresponding orientation.
char * sstrdup(const char *str)
Safe-wrapper around strdup which exits if malloc returns NULL (meaning that there is no more memory a...
bool level_up(void)
Moves focus one level up.
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 tree_flatten(Con *con)
tree_flatten() removes pairs of redundant split containers, e.g.
kill_window_t
parameter to specify whether tree_close_internal() and x_window_kill() should kill only this specific...
xcb_connection_t * conn
XCB connection and root screen.
Con * con_get_workspace(Con *con)
Gets the workspace container this node is on.
int con_num_children(Con *con)
Returns the number of children of this container.
bool con_is_floating(Con *con)
Returns true if the node is floating.
#define TAILQ_EMPTY(head)
bool level_down(void)
Moves focus one level down.
Con * con_next_focused(Con *con)
Returns the container which will be focused next when the given container is not available anymore...
orientation_t con_orientation(Con *con)
Returns the orientation of the given container (for stacked containers, vertical orientation is used ...
#define TAILQ_LAST(head, headname)
A 'Con' represents everything from the X11 root window down to a single X11 window.
static void mark_unmapped(Con *con)
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.
#define TAILQ_INSERT_HEAD(head, elm, field)
void con_set_urgency(Con *con, bool urgent)
Set urgency flag to the container, all the parent containers and the workspace.
bool con_is_split(Con *con)
Returns true if a container should be considered split.
#define TAILQ_NEXT(elm, field)
bool con_fullscreen_permits_focusing(Con *con)
Returns true if changing the focus to con would be allowed considering the fullscreen focus constrain...
#define TAILQ_PREV(elm, headname, field)
Con * workspace_encapsulate(Con *ws)
Creates a new container and re-parents all of children from the given workspace into it...
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_push_changes(Con *con)
Pushes all changes (state of each node, see x_push_node() and the window stack) to X11...
void tree_next(Con *con, direction_t direction)
Changes focus in the given direction.
#define TAILQ_INSERT_BEFORE(listelm, elm, field)
char * output_primary_name(Output *output)
Retrieves the primary name of an output.
bool tree_close_internal(Con *con, kill_window_t kill_window, bool dont_kill_parent)
Closes the given container including all children.
void workspace_show(Con *workspace)
Switches to the given workspace.
Con * con_descend_focused(Con *con)
Returns the focused con inside this client, descending the tree as far as possible.
#define TAILQ_REPLACE(head, elm, elm2, field)
Con * con_new(Con *parent, i3Window *window)
A wrapper for con_new_skeleton, to retain the old con_new behaviour.
#define TAILQ_INSERT_TAIL(head, elm, field)
fullscreen_mode_t fullscreen_mode
void ewmh_update_desktop_properties(void)
Updates all the EWMH desktop properties.
Con * con_get_fullscreen_con(Con *con, fullscreen_mode_t fullscreen_mode)
Returns the first fullscreen node below this node.
void render_con(Con *con, bool already_inset)
"Renders" the given container (and its children), meaning that all rects are updated correctly...
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...
void tree_split(Con *con, orientation_t orientation)
Splits (horizontally or vertically) the given container by creating a new container which contains th...
bool workspace_is_visible(Con *ws)
Returns true if the workspace is currently visible.
struct all_cons_head all_cons
void con_attach(Con *con, Con *parent, bool ignore_focus)
Attaches the given container to the given parent.
Con * con_descend_tiling_focused(Con *con)
Returns the focused con inside this client, descending the tree as far as possible.
void con_activate(Con *con)
Sets input focus to the given container and raises it to the top.
Con * get_tree_next_sibling(Con *con, position_t direction)
Get the previous / next sibling.
focus_wrapping_t focus_wrapping
When focus wrapping is enabled (the default), attempting to move focus past the edge of the screen (i...
int num
the workspace number, if this Con is of type CT_WORKSPACE and the workspace is not a named workspace ...
A 'Window' is a type which contains an xcb_window_t and all the related information (hints like _NET_...
void workspace_update_urgent_flag(Con *ws)
Goes through all clients on the given workspace and updates the workspace’s urgent flag accordingly...
#define TAILQ_FIRST(head)
void con_force_split_parents_redraw(Con *con)
force parent split containers to be redrawn
static Con * _create___i3(void)
#define TAILQ_REMOVE(head, elm, field)
struct ev_loop * main_loop
bool path_exists(const char *path)
Checks if the given path exists by calling stat().
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 * tree_open_con(Con *con, i3Window *window)
Opens an empty container in the current container.
position_t position_from_direction(direction_t direction)
Convert a direction to its corresponding position.