#define _COMMANDS_H
bool focus_window_in_container(xcb_connection_t *conn, Container *container, direction_t direction);
+
+/** Switches to the given workspace */
void show_workspace(xcb_connection_t *conn, int workspace);
+
+/** Parses a command, see file CMDMODE for more information */
void parse_command(xcb_connection_t *conn, const char *command);
#endif
const char *font;
};
+/**
+ * Reads the configuration from ~/.i3/config or /etc/i3/config if not found.
+ *
+ * If you specify override_configpath, only this path is used to look for a
+ * configuration file.
+ *
+ */
void load_configuration(const char *override_configfile);
#endif
#ifndef _HANDLERS_H
#define _HANDLERS_H
+/**
+ * Due to bindings like Mode_switch + <a>, we need to bind some keys in XCB_GRAB_MODE_SYNC.
+ * Therefore, we just replay all key presses.
+ *
+ */
int handle_key_release(void *ignored, xcb_connection_t *conn, xcb_key_release_event_t *event);
+
+/**
+ * There was a key press. We compare this key code with our bindings table and pass
+ * the bound action to parse_command().
+ *
+ */
int handle_key_press(void *ignored, xcb_connection_t *conn, xcb_key_press_event_t *event);
+
+/**
+ * When the user moves the mouse pointer onto a window, this callback gets called.
+ *
+ */
int handle_enter_notify(void *ignored, xcb_connection_t *conn, xcb_enter_notify_event_t *event);
+
+/**
+ * Checks if the button press was on a stack window, handles focus setting and returns true
+ * if so, or false otherwise.
+ *
+ */
int handle_button_press(void *ignored, xcb_connection_t *conn, xcb_button_press_event_t *event);
+
+/**
+ * A new window appeared on the screen (=was mapped), so let’s manage it.
+ *
+ */
int handle_map_request(void *prophs, xcb_connection_t *conn, xcb_map_request_event_t *event);
+
+/**
+ * Configuration notifies are only handled because we need to set up ignore for the following
+ * enter notify events
+ *
+ */
int handle_configure_event(void *prophs, xcb_connection_t *conn, xcb_configure_notify_event_t *event);
+
+/**
+ * Configure requests are received when the application wants to resize windows on their own.
+ *
+ * We generate a synthethic configure notify event to signalize the client its "new" position.
+ *
+ */
int handle_configure_request(void *prophs, xcb_connection_t *conn, xcb_configure_request_event_t *event);
+
+/**
+ * Our window decorations were unmapped. That means, the window will be killed now,
+ * so we better clean up before.
+ *
+ */
int handle_unmap_notify_event(void *data, xcb_connection_t *conn, xcb_unmap_notify_event_t *event);
+
+/**
+ * Called when a window changes its title
+ *
+ */
int handle_windowname_change(void *data, xcb_connection_t *conn, uint8_t state,
xcb_window_t window, xcb_atom_t atom, xcb_get_property_reply_t *prop);
+
+/**
+ * We handle legacy window names (titles) which are in COMPOUND_TEXT encoding. However, we
+ * just pass them along, so when containing non-ASCII characters, those will be rendering
+ * incorrectly. In order to correctly render unicode window titles in i3, an application
+ * has to set _NET_WM_NAME, which is in UTF-8 encoding.
+ *
+ * On every update, a message is put out to the user, so he may improve the situation and
+ * update applications which display filenames in their title to correctly use
+ * _NET_WM_NAME and therefore support unicode.
+ *
+ */
int handle_windowname_change_legacy(void *data, xcb_connection_t *conn, uint8_t state,
xcb_window_t window, xcb_atom_t atom, xcb_get_property_reply_t *prop);
+
+/**
+ * Expose event means we should redraw our windows (= title bar)
+ *
+ */
int handle_expose_event(void *data, xcb_connection_t *conn, xcb_expose_event_t *event);
+
+/**
+ * Handle client messages (EWMH)
+ *
+ */
int handle_client_message(void *data, xcb_connection_t *conn, xcb_client_message_event_t *event);
+
+/**
+ * Handles _NET_WM_WINDOW_TYPE changes
+ *
+ */
int handle_window_type(void *data, xcb_connection_t *conn, uint8_t state, xcb_window_t window,
xcb_atom_t atom, xcb_get_property_reply_t *property);
+
+/**
+ * Handles the size hints set by a window, but currently only the part necessary for displaying
+ * clients proportionally inside their frames (mplayer for example)
+ *
+ * See ICCCM 4.1.2.3 for more details
+ *
+ */
int handle_normal_hints(void *data, xcb_connection_t *conn, uint8_t state, xcb_window_t window,
xcb_atom_t name, xcb_get_property_reply_t *reply);
#ifndef _LAYOUT_H
#define _LAYOUT_H
-Rect get_unoccupied_space(Workspace *workspace);
+/**
+ * (Re-)draws window decorations for a given Client onto the given drawable/graphic context.
+ * When in stacking mode, the window decorations are drawn onto an own window.
+ *
+ */
void decorate_window(xcb_connection_t *conn, Client *client, xcb_drawable_t drawable, xcb_gcontext_t gc, int offset);
+
+/**
+ * Redecorates the given client correctly by checking if it’s in a stacking container and
+ * re-rendering the stack window or just calling decorate_window if it’s not in a stacking
+ * container.
+ *
+ */
void redecorate_window(xcb_connection_t *conn, Client *client);
+
+/**
+ * Renders the given container. Is called by render_layout() or individually (for example
+ * when focus changes in a stacking container)
+ *
+ */
void render_container(xcb_connection_t *conn, Container *container);
+
+/**
+ * Modifies the event mask of all clients on the given workspace to either ignore or to handle
+ * enter notifies. It is handy to ignore notifies because they will be sent when a window is mapped
+ * under the cursor, thus when the user didn’t enter the window actively at all.
+ *
+ */
void ignore_enter_notify_forall(xcb_connection_t *conn, Workspace *workspace, bool ignore_enter_notify);
+
+/**
+ * Renders the whole layout, that is: Go through each screen, each workspace, each container
+ * and render each client. This also renders the bars.
+ *
+ * If you don’t need to render *everything*, you should call render_container on the container
+ * you want to refresh.
+ *
+ */
void render_layout(xcb_connection_t *conn);
#endif
extern int current_col;
extern int current_row;
+/** Initialize table */
void init_table();
+
+/** Add one row to the table */
void expand_table_rows(Workspace *workspace);
+
+/** Adds one row at the head of the table */
void expand_table_rows_at_head(Workspace *workspace);
+
+/** Add one column to the table */
void expand_table_cols(Workspace *workspace);
+
+/** Inserts one column at the table’s head */
void expand_table_cols_at_head(Workspace *workspace);
+
+/** Performs simple bounds checking for the given column/row */
bool cell_exists(int col, int row);
+
+/** Shrinks the table by "compacting" it, that is, removing completely empty rows/columns */
void cleanup_table(xcb_connection_t *conn, Workspace *workspace);
+
+/** Fixes col/rowspan (makes sure there are no overlapping windows) */
void fix_colrowspan(xcb_connection_t *conn, Workspace *workspace);
+
+/** Prints the table’s contents in human-readable form for debugging */
void dump_table(xcb_connection_t *conn, Workspace *workspace);
#endif
int min(int a, int b);
int max(int a, int b);
+
+/**
+ * Logs the given message to stdout while prefixing the current time to it.
+ * This is to be called by LOG() which includes filename/linenumber
+ *
+ */
void slog(char *fmt, ...);
+
+/**
+ * Prints the message (see printf()) to stderr, then exits the program.
+ *
+ */
void die(char *fmt, ...);
+
+/**
+ * Safe-wrapper around malloc which exits if malloc returns NULL (meaning that there
+ * is no more memory available)
+ *
+ */
void *smalloc(size_t size);
+
+/**
+ * Safe-wrapper around calloc which exits if malloc returns NULL (meaning that there
+ * is no more memory available)
+ *
+ */
void *scalloc(size_t size);
+
+/**
+ * Safe-wrapper around strdup which exits if malloc returns NULL (meaning that there
+ * is no more memory available)
+ *
+ */
char *sstrdup(const char *str);
+
+/**
+ * Starts the given application by passing it through a shell. We use double fork
+ * to avoid zombie processes. As the started application’s parent exits (immediately),
+ * the application is reparented to init (process-id 1), which correctly handles
+ * childs, so we don’t have to do it :-).
+ *
+ * The shell is determined by looking for the SHELL environment variable. If it
+ * does not exist, /bin/sh is used.
+ *
+ */
void start_application(const char *command);
+
+/**
+ * Checks a generic cookie for errors and quits with the given message if there
+ * was an error.
+ *
+ */
void check_error(xcb_connection_t *conn, xcb_void_cookie_t cookie, char *err_message);
+
+/**
+ * Converts the given string to UCS-2 big endian for use with
+ * xcb_image_text_16(). The amount of real glyphs is stored in real_strlen,
+ * a buffer containing the UCS-2 encoded string (16 bit per glyph) is
+ * returned. It has to be freed when done.
+ *
+ */
char *convert_utf8_to_ucs2(char *input, int *real_strlen);
+
+/**
+ * Removes the given client from the container, either because it will be inserted into another
+ * one or because it was unmapped
+ *
+ */
void remove_client_from_container(xcb_connection_t *conn, Client *client, Container *container);
+
+/**
+ * Sets the given client as focused by updating the data structures correctly,
+ * updating the X input focus and finally re-decorating both windows (to signalize
+ * the user the new focus situation)
+ *
+ */
void set_focus(xcb_connection_t *conn, Client *client, bool set_anyways);
+
+/**
+ * Called when the user switches to another mode or when the container is
+ * destroyed and thus needs to be cleaned up.
+ *
+ */
void leave_stack_mode(xcb_connection_t *conn, Container *container);
+
+/**
+ * Switches the layout of the given container taking care of the necessary house-keeping
+ *
+ */
void switch_layout_mode(xcb_connection_t *conn, Container *container, int mode);
+
+/**
+ * Warps the pointer into the given client (in the middle of it, to be specific), therefore
+ * selecting it
+ *
+ */
void warp_pointer_into(xcb_connection_t *conn, Client *client);
+
+/**
+ * Toggles fullscreen mode for the given client. It updates the data structures and
+ * reconfigures (= resizes/moves) the client and its frame to the full size of the
+ * screen. When leaving fullscreen, re-rendering the layout is forced.
+ *
+ */
void toggle_fullscreen(xcb_connection_t *conn, Client *client);
+
+/**
+ * Kills the given window using WM_DELETE_WINDOW or xcb_kill_window
+ *
+ */
void kill_window(xcb_connection_t *conn, Client *window);
#endif
extern unsigned int xcb_numlock_mask;
+/**
+ * Loads a font for usage, getting its height. This function is used very often, so it
+ * maintains a cache.
+ *
+ */
i3Font *load_font(xcb_connection_t *conn, const char *pattern);
+
+/**
+ * Returns the colorpixel to use for the given hex color (think of HTML).
+ *
+ * The hex_color has to start with #, for example #FF00FF.
+ *
+ * NOTE that get_colorpixel() does _NOT_ check the given color code for validity.
+ * This has to be done by the caller.
+ *
+ */
uint32_t get_colorpixel(xcb_connection_t *conn, char *hex);
+
+/**
+ * Convenience wrapper around xcb_create_window which takes care of depth, generating an ID and checking
+ * for errors.
+ *
+ */
xcb_window_t create_window(xcb_connection_t *conn, Rect r, uint16_t window_class, int cursor,
uint32_t mask, uint32_t *values);
+
+/**
+ * Changes a single value in the graphic context (so one doesn’t have to define an array of values)
+ *
+ */
void xcb_change_gc_single(xcb_connection_t *conn, xcb_gcontext_t gc, uint32_t mask, uint32_t value);
+
+/**
+ * Draws a line from x,y to to_x,to_y using the given color
+ *
+ */
void xcb_draw_line(xcb_connection_t *conn, xcb_drawable_t drawable, xcb_gcontext_t gc,
uint32_t colorpixel, uint32_t x, uint32_t y, uint32_t to_x, uint32_t to_y);
+
+/**
+ * Draws a rectangle from x,y with width,height using the given color
+ *
+ */
void xcb_draw_rect(xcb_connection_t *conn, xcb_drawable_t drawable, xcb_gcontext_t gc,
uint32_t colorpixel, uint32_t x, uint32_t y, uint32_t width, uint32_t height);
+
+/**
+ * Generates a configure_notify event and sends it to the given window
+ * Applications need this to think they’ve configured themselves correctly.
+ * The truth is, however, that we will manage them.
+ *
+ */
void fake_configure_notify(xcb_connection_t *conn, Rect r, xcb_window_t window);
+
+/**
+ * Finds out which modifier mask is the one for numlock, as the user may change this.
+ *
+ */
void xcb_get_numlock_mask(xcb_connection_t *conn);
#endif
TAILQ_HEAD(screens_head, Screen);
extern struct screens_head *virtual_screens;
+/**
+ * We have just established a connection to the X server and need the initial Xinerama
+ * information to setup workspaces for each screen.
+ *
+ */
void initialize_xinerama(xcb_connection_t *conn);
+
+/**
+ * This is called when the rootwindow receives a configure_notify event and therefore the
+ * number/position of the Xinerama screens could have changed.
+ *
+ */
void xinerama_requery_screens(xcb_connection_t *conn);
+
+/**
+ * Looks in virtual_screens for the i3Screen whose start coordinates are x, y
+ *
+ */
i3Screen *get_screen_at(int x, int y, struct screens_head *screenlist);
+
+/**
+ * Looks in virtual_screens for the i3Screen which contains coordinates x, y
+ *
+ */
i3Screen *get_screen_containing(int x, int y);
+
+/**
+ * Gets the screen which is the last one in the given direction, for example the screen
+ * on the most bottom when direction == D_DOWN, the screen most right when direction == D_RIGHT
+ * and so on.
+ *
+ * This function always returns a screen.
+ *
+ */
i3Screen *get_screen_most(direction_t direction);
#endif
--- /dev/null
+# Doxyfile 1.5.6
+#
+# You can use this file with doxygen to create a pseudo-documentation
+# automatically from source. doxygen-comments are not used very extensively
+# in i3, mostly for the reason that it clutters the source code and has no
+# real use (doxygen’s output looks really ugly).
+#
+# So, if you want to use it, here you go. This is however not a supported
+# document, and I recommend you have a look at the docs/ folder or at
+# http://i3.zekjur.net/ for more, real documentation.
+#
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+DOXYFILE_ENCODING = UTF-8
+PROJECT_NAME = i3
+PROJECT_NUMBER =
+OUTPUT_DIRECTORY = pseudo-doc
+OUTPUT_LANGUAGE = English
+BRIEF_MEMBER_DESC = YES
+REPEAT_BRIEF = YES
+ALWAYS_DETAILED_SEC = YES
+FULL_PATH_NAMES = YES
+SHORT_NAMES = YES
+JAVADOC_AUTOBRIEF = YES
+TAB_SIZE = 8
+OPTIMIZE_OUTPUT_FOR_C = YES
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+EXTRACT_ALL = YES
+EXTRACT_PRIVATE = NO
+EXTRACT_STATIC = YES
+EXTRACT_LOCAL_CLASSES = YES
+CASE_SENSE_NAMES = YES
+SHOW_INCLUDE_FILES = YES
+SORT_MEMBER_DOCS = YES
+SORT_BRIEF_DOCS = NO
+SORT_GROUP_NAMES = NO
+SORT_BY_SCOPE_NAME = NO
+SHOW_USED_FILES = YES
+SHOW_FILES = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+QUIET = NO
+WARNINGS = YES
+WARN_IF_UNDOCUMENTED = YES
+WARN_IF_DOC_ERROR = YES
+WARN_NO_PARAMDOC = NO
+WARN_FORMAT = "$file:$line: $text"
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+INPUT = src include
+INPUT_ENCODING = UTF-8
+RECURSIVE = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+SOURCE_BROWSER = YES
+INLINE_SOURCES = NO
+
+STRIP_CODE_COMMENTS = YES
+
+REFERENCED_BY_RELATION = YES
+REFERENCES_RELATION = YES
+REFERENCES_LINK_SOURCE = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+ALPHABETICAL_INDEX = NO
+COLS_IN_ALPHA_INDEX = 5
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+GENERATE_HTML = YES
+HTML_OUTPUT = html
+HTML_FILE_EXTENSION = .html
+HTML_ALIGN_MEMBERS = YES
+HTML_DYNAMIC_SECTIONS = NO
+FORMULA_FONTSIZE = 10
+
+GENERATE_LATEX = NO
+GENERATE_RTF = NO
+GENERATE_MAN = NO
+GENERATE_XML = NO
+GENERATE_AUTOGEN_DEF = NO
+GENERATE_PERLMOD = NO
+
+ENABLE_PREPROCESSING = YES
+MACRO_EXPANSION = NO
+EXPAND_ONLY_PREDEF = NO
+SEARCH_INCLUDES = YES
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+CLASS_DIAGRAMS = YES
+HAVE_DOT = YES
+DOT_FONTNAME = FreeSans
+DOT_FONTPATH =
+CLASS_GRAPH = YES
+COLLABORATION_GRAPH = YES
+GROUP_GRAPHS = YES
+UML_LOOK = NO
+INCLUDE_GRAPH = YES
+INCLUDED_BY_GRAPH = YES
+CALL_GRAPH = YES
+CALLER_GRAPH = NO
+GRAPHICAL_HIERARCHY = YES
+DIRECTORY_GRAPH = YES
+DOT_IMAGE_FORMAT = png
+DOT_GRAPH_MAX_NODES = 50
+MAX_DOT_GRAPH_DEPTH = 0
+DOT_TRANSPARENT = YES
+DOT_MULTI_TARGETS = NO
+GENERATE_LEGEND = YES
+DOT_CLEANUP = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine
+#---------------------------------------------------------------------------
+
+SEARCHENGINE = NO
}
}
+/*
+ * Renders the whole layout, that is: Go through each screen, each workspace, each container
+ * and render each client. This also renders the bars.
+ *
+ * If you don’t need to render *everything*, you should call render_container on the container
+ * you want to refresh.
+ *
+ */
void render_layout(xcb_connection_t *conn) {
i3Screen *screen;
i3Font *font = load_font(conn, config.font);
}
}
+/*
+ * Prints the table’s contents in human-readable form for debugging
+ *
+ */
void dump_table(xcb_connection_t *conn, Workspace *workspace) {
LOG("dump_table()\n");
FOR_TABLE(workspace) {