xcb_atom_t a_utf8_string;
xcb_atom_t a_swm_iconic;
xcb_atom_t a_swm_ws;
-volatile sig_atomic_t running = 1;
-volatile sig_atomic_t restart_wm = 0;
+volatile sig_atomic_t running = 1;
+volatile sig_atomic_t restart_wm = 0;
xcb_timestamp_t last_event_time = 0;
int outputs = 0;
int other_wm;
#define SWM_BAR_JUSTIFY_CENTER (1)
#define SWM_BAR_JUSTIFY_RIGHT (2)
#define SWM_BAR_OFFSET (4)
-#define SWM_BAR_FONTS "-*-terminus-medium-*-*-*-12-*-*-*-*-*-*-*,"\
- "-*-profont-*-*-*-*-12-*-*-*-*-*-*-*,"\
- "-*-times-medium-r-*-*-12-*-*-*-*-*-*-*,"\
- "-misc-fixed-medium-r-*-*-12-*-*-*-*-*-*-*,"\
+#define SWM_BAR_FONTS "-*-terminus-medium-*-*-*-12-*-*-*-*-*-*-*," \
+ "-*-profont-*-*-*-*-12-*-*-*-*-*-*-*," \
+ "-*-times-medium-r-*-*-12-*-*-*-*-*-*-*," \
+ "-misc-fixed-medium-r-*-*-12-*-*-*-*-*-*-*," \
"-*-*-*-r-*-*-*-*-*-*-*-*-*-*"
#ifdef X_HAVE_UTF8_STRING
struct swm_geometry g; /* current geometry */
struct swm_geometry g_float; /* region coordinates */
int g_floatvalid; /* g_float geometry validity */
- int floatmaxed; /* whether maxed by max_stack */
int floating;
int manual;
int32_t mapped;
int32_t iconic;
+ int32_t maximized;
int bordered;
unsigned int ewmh_flags;
int font_size_boundary[SWM_MAX_FONT_STEPS];
struct swm_region *old_r; /* may be NULL */
struct ws_win_list winlist; /* list of windows in ws */
struct ws_win_list unmanagedlist; /* list of dead windows in ws */
+ int32_t state;
char stacker[10]; /* display stacker and layout */
/* stacker state */
};
enum {
+ SWM_WS_STATE_HIDDEN,
+ SWM_WS_STATE_MAPPING,
+ SWM_WS_STATE_MAPPED,
+};
+
+enum {
SWM_S_COLOR_BAR,
SWM_S_COLOR_BAR_BORDER,
SWM_S_COLOR_BAR_BORDER_UNFOCUS,
char *name;
xcb_atom_t atom;
} ewmh[SWM_EWMH_HINT_MAX] = {
- /* must be in same order as in the enum */
- {"_NET_ACTIVE_WINDOW", XCB_ATOM_NONE},
- {"_NET_CLOSE_WINDOW", XCB_ATOM_NONE},
- {"_NET_MOVERESIZE_WINDOW", XCB_ATOM_NONE},
- {"_NET_WM_ACTION_ABOVE", XCB_ATOM_NONE},
- {"_NET_WM_ACTION_CLOSE", XCB_ATOM_NONE},
- {"_NET_WM_ACTION_FULLSCREEN", XCB_ATOM_NONE},
- {"_NET_WM_ACTION_MOVE", XCB_ATOM_NONE},
- {"_NET_WM_ACTION_RESIZE", XCB_ATOM_NONE},
- {"_NET_WM_ALLOWED_ACTIONS", XCB_ATOM_NONE},
- {"_NET_WM_NAME", XCB_ATOM_NONE},
- {"_NET_WM_STATE", XCB_ATOM_NONE},
- {"_NET_WM_STATE_ABOVE", XCB_ATOM_NONE},
- {"_NET_WM_STATE_FULLSCREEN", XCB_ATOM_NONE},
- {"_NET_WM_STATE_HIDDEN", XCB_ATOM_NONE},
- {"_NET_WM_STATE_MAXIMIZED_HORZ", XCB_ATOM_NONE},
- {"_NET_WM_STATE_MAXIMIZED_VERT", XCB_ATOM_NONE},
- {"_NET_WM_STATE_SKIP_PAGER", XCB_ATOM_NONE},
- {"_NET_WM_STATE_SKIP_TASKBAR", XCB_ATOM_NONE},
- {"_NET_WM_WINDOW_TYPE", XCB_ATOM_NONE},
- {"_NET_WM_WINDOW_TYPE_DIALOG", XCB_ATOM_NONE},
- {"_NET_WM_WINDOW_TYPE_DOCK", XCB_ATOM_NONE},
- {"_NET_WM_WINDOW_TYPE_NORMAL", XCB_ATOM_NONE},
- {"_NET_WM_WINDOW_TYPE_SPLASH", XCB_ATOM_NONE},
- {"_NET_WM_WINDOW_TYPE_TOOLBAR", XCB_ATOM_NONE},
- {"_NET_WM_WINDOW_TYPE_UTILITY", XCB_ATOM_NONE},
- {"_SWM_WM_STATE_MANUAL", XCB_ATOM_NONE},
+ /* must be in same order as in the enum */
+ {"_NET_ACTIVE_WINDOW", XCB_ATOM_NONE},
+ {"_NET_CLOSE_WINDOW", XCB_ATOM_NONE},
+ {"_NET_MOVERESIZE_WINDOW", XCB_ATOM_NONE},
+ {"_NET_WM_ACTION_ABOVE", XCB_ATOM_NONE},
+ {"_NET_WM_ACTION_CLOSE", XCB_ATOM_NONE},
+ {"_NET_WM_ACTION_FULLSCREEN", XCB_ATOM_NONE},
+ {"_NET_WM_ACTION_MOVE", XCB_ATOM_NONE},
+ {"_NET_WM_ACTION_RESIZE", XCB_ATOM_NONE},
+ {"_NET_WM_ALLOWED_ACTIONS", XCB_ATOM_NONE},
+ {"_NET_WM_NAME", XCB_ATOM_NONE},
+ {"_NET_WM_STATE", XCB_ATOM_NONE},
+ {"_NET_WM_STATE_ABOVE", XCB_ATOM_NONE},
+ {"_NET_WM_STATE_FULLSCREEN", XCB_ATOM_NONE},
+ {"_NET_WM_STATE_HIDDEN", XCB_ATOM_NONE},
+ {"_NET_WM_STATE_MAXIMIZED_HORZ", XCB_ATOM_NONE},
+ {"_NET_WM_STATE_MAXIMIZED_VERT", XCB_ATOM_NONE},
+ {"_NET_WM_STATE_SKIP_PAGER", XCB_ATOM_NONE},
+ {"_NET_WM_STATE_SKIP_TASKBAR", XCB_ATOM_NONE},
+ {"_NET_WM_WINDOW_TYPE", XCB_ATOM_NONE},
+ {"_NET_WM_WINDOW_TYPE_DIALOG", XCB_ATOM_NONE},
+ {"_NET_WM_WINDOW_TYPE_DOCK", XCB_ATOM_NONE},
+ {"_NET_WM_WINDOW_TYPE_NORMAL", XCB_ATOM_NONE},
+ {"_NET_WM_WINDOW_TYPE_SPLASH", XCB_ATOM_NONE},
+ {"_NET_WM_WINDOW_TYPE_TOOLBAR", XCB_ATOM_NONE},
+ {"_NET_WM_WINDOW_TYPE_UTILITY", XCB_ATOM_NONE},
+ {"_SWM_WM_STATE_MANUAL", XCB_ATOM_NONE},
};
/* Cursors */
KF_FOCUS_NEXT,
KF_FOCUS_PREV,
KF_FOCUS_URGENT,
+ KF_MAXIMIZE_TOGGLE,
KF_HEIGHT_GROW,
KF_HEIGHT_SHRINK,
KF_ICONIFY,
};
struct key {
- RB_ENTRY(key) entry;
- unsigned int mod;
- KeySym keysym;
- enum keyfuncid funcid;
- char *spawn_name;
+ RB_ENTRY(key) entry;
+ unsigned int mod;
+ KeySym keysym;
+ enum keyfuncid funcid;
+ char *spawn_name;
};
RB_HEAD(key_tree, key);
/* function prototypes */
-void adjust_font(struct ws_win *);
+void adjust_font(struct ws_win *);
char *argsep(char **);
-void bar_cleanup(struct swm_region *);
-void bar_extra_setup(void);
-void bar_extra_stop(void);
-int bar_extra_update(void);
-void bar_fmt(const char *, char *, struct swm_region *, size_t);
-void bar_fmt_expand(char *, size_t);
-void bar_draw(void);
-void bar_print(struct swm_region *, const char *);
-void bar_print_legacy(struct swm_region *, const char *);
-void bar_replace(char *, char *, struct swm_region *, size_t);
-void bar_replace_pad(char *, int *, size_t);
+void bar_cleanup(struct swm_region *);
+void bar_extra_setup(void);
+void bar_extra_stop(void);
+int bar_extra_update(void);
+void bar_fmt(const char *, char *, struct swm_region *, size_t);
+void bar_fmt_expand(char *, size_t);
+void bar_draw(void);
+void bar_print(struct swm_region *, const char *);
+void bar_print_legacy(struct swm_region *, const char *);
+void bar_replace(char *, char *, struct swm_region *, size_t);
+void bar_replace_pad(char *, int *, size_t);
char *bar_replace_seq(char *, char *, struct swm_region *, size_t *, size_t);
-void bar_setup(struct swm_region *);
-void bar_toggle(struct swm_region *, union arg *);
-void bar_urgent(char *, size_t);
-void bar_window_class(char *, size_t, struct swm_region *);
-void bar_window_class_instance(char *, size_t, struct swm_region *);
-void bar_window_float(char *, size_t, struct swm_region *);
-void bar_window_instance(char *, size_t, struct swm_region *);
-void bar_window_name(char *, size_t, struct swm_region *);
-void bar_workspace_name(char *, size_t, struct swm_region *);
-void buttonpress(xcb_button_press_event_t *);
-void check_conn(void);
-void clear_keys(void);
-void clientmessage(xcb_client_message_event_t *);
-void client_msg(struct ws_win *, xcb_atom_t, xcb_timestamp_t);
-int conf_load(const char *, int);
-void configurenotify(xcb_configure_notify_event_t *);
-void configurerequest(xcb_configure_request_event_t *);
-void config_win(struct ws_win *, xcb_configure_request_event_t *);
-void constrain_window(struct ws_win *, struct swm_geometry *, int *);
-int count_win(struct workspace *, int);
-void cursors_cleanup(void);
-void cursors_load(void);
-void custom_region(const char *);
-void cyclerg(struct swm_region *, union arg *);
-void cyclews(struct swm_region *, union arg *);
-void cycle_layout(struct swm_region *, union arg *);
-void destroynotify(xcb_destroy_notify_event_t *);
-void dumpwins(struct swm_region *, union arg *);
-int enable_wm(void);
-void enternotify(xcb_enter_notify_event_t *);
-void event_drain(uint8_t);
-void event_error(xcb_generic_error_t *);
-void event_handle(xcb_generic_event_t *);
-void ewmh_autoquirk(struct ws_win *);
-void ewmh_get_win_state(struct ws_win *);
-int ewmh_set_win_fullscreen(struct ws_win *, int);
-void ewmh_update_actions(struct ws_win *);
-void ewmh_update_win_state(struct ws_win *, xcb_atom_t, long);
+void bar_setup(struct swm_region *);
+void bar_toggle(struct swm_region *, union arg *);
+void bar_urgent(char *, size_t);
+void bar_window_class(char *, size_t, struct swm_region *);
+void bar_window_class_instance(char *, size_t, struct swm_region *);
+void bar_window_float(char *, size_t, struct swm_region *);
+void bar_window_instance(char *, size_t, struct swm_region *);
+void bar_window_name(char *, size_t, struct swm_region *);
+void bar_window_state(char *, size_t, struct swm_region *);
+void bar_workspace_name(char *, size_t, struct swm_region *);
+void buttonpress(xcb_button_press_event_t *);
+void check_conn(void);
+void clear_keys(void);
+int clear_maximized(struct workspace *);
+void clientmessage(xcb_client_message_event_t *);
+void client_msg(struct ws_win *, xcb_atom_t, xcb_timestamp_t);
+int conf_load(const char *, int);
+void configurenotify(xcb_configure_notify_event_t *);
+void configurerequest(xcb_configure_request_event_t *);
+void config_win(struct ws_win *, xcb_configure_request_event_t *);
+void constrain_window(struct ws_win *, struct swm_geometry *, int *);
+int count_win(struct workspace *, int);
+void cursors_cleanup(void);
+void cursors_load(void);
+void custom_region(const char *);
+void cyclerg(struct swm_region *, union arg *);
+void cyclews(struct swm_region *, union arg *);
+void cycle_layout(struct swm_region *, union arg *);
+void destroynotify(xcb_destroy_notify_event_t *);
+void dumpwins(struct swm_region *, union arg *);
+int enable_wm(void);
+void enternotify(xcb_enter_notify_event_t *);
+void event_drain(uint8_t);
+void event_error(xcb_generic_error_t *);
+void event_handle(xcb_generic_event_t *);
+void ewmh_autoquirk(struct ws_win *);
+void ewmh_get_win_state(struct ws_win *);
+int ewmh_set_win_fullscreen(struct ws_win *, int);
+void ewmh_update_actions(struct ws_win *);
+void ewmh_update_win_state(struct ws_win *, xcb_atom_t, long);
char *expand_tilde(const char *);
-void expose(xcb_expose_event_t *);
-void fake_keypress(struct ws_win *, xcb_keysym_t, uint16_t);
-void floating_toggle(struct swm_region *, union arg *);
-int floating_toggle_win(struct ws_win *);
-void focus(struct swm_region *, union arg *);
-void focus_flush(void);
-void focus_region(struct swm_region *);
-void focusrg(struct swm_region *, union arg *);
-void focus_win(struct ws_win *);
-void fontset_init(void);
-void free_window(struct ws_win *);
-void search_do_resp(void);
-void search_resp_name_workspace(const char *, size_t);
-void search_resp_search_window(const char *);
-void search_resp_search_workspace(const char *);
-void search_resp_uniconify(const char *, size_t);
-void search_win(struct swm_region *, union arg *);
-void search_win_cleanup(void);
-void search_workspace(struct swm_region *, union arg *);
-void send_to_rg(struct swm_region *, union arg *);
-void send_to_ws(struct swm_region *, union arg *);
-void set_region(struct swm_region *);
-int setautorun(const char *, const char *, int);
-int setconfbinding(const char *, const char *, int);
-int setconfcolor(const char *, const char *, int);
-int setconfmodkey(const char *, const char *, int);
-int setconfquirk(const char *, const char *, int);
-int setconfregion(const char *, const char *, int);
-int setconfspawn(const char *, const char *, int);
-int setconfvalue(const char *, const char *, int);
-void setkeybinding(unsigned int, KeySym, enum keyfuncid, const char *);
-int setkeymapping(const char *, const char *, int);
-int setlayout(const char *, const char *, int);
-void setquirk(const char *, const char *, const char *,unsigned long);
-void setscreencolor(const char *, int, int);
-void setspawn(const char *, const char *, int);
-void setup_ewmh(void);
-void setup_globals(void);
-void setup_keys(void);
-void setup_quirks(void);
-void setup_screens(void);
-void setup_spawn(void);
-void set_child_transient(struct ws_win *, xcb_window_t *);
-void set_swm_iconic(struct ws_win *, int);
-void set_win_state(struct ws_win *, uint16_t);
-void shutdown_cleanup(void);
-void sighdlr(int);
-void socket_setnonblock(int);
-void sort_windows(struct ws_win_list *);
-void spawn(int, union arg *, int);
-void spawn_custom(struct swm_region *, union arg *, const char *);
-int spawn_expand(struct swm_region *, union arg *, const char *, char ***);
-void spawn_insert(const char *, const char *, int);
-int32_t get_swm_iconic(struct ws_win *);
-char *get_win_name(xcb_window_t);
-void get_wm_protocols(struct ws_win *);
-int get_ws_idx(xcb_window_t);
-void grabbuttons(struct ws_win *);
-void grabkeys(void);
-void grab_windows(void);
-void iconify(struct swm_region *, union arg *);
-int isxlfd(char *);
-void keypress(xcb_key_press_event_t *);
-int key_cmp(struct key *, struct key *);
-void key_insert(unsigned int, KeySym, enum keyfuncid, const char *);
-void key_remove(struct key *);
-void key_replace(struct key *, unsigned int, KeySym, enum keyfuncid,
- const char *);
-void kill_bar_extra_atexit(void);
-void kill_refs(struct ws_win *);
-void load_float_geom(struct ws_win *);
-void map_window(struct ws_win *, xcb_window_t);
-void mapnotify(xcb_map_notify_event_t *);
-void mappingnotify(xcb_mapping_notify_event_t *);
-void maprequest(xcb_map_request_event_t *);
-void motionnotify(xcb_motion_notify_event_t *);
-void move(struct ws_win *, union arg *);
-void move_step(struct swm_region *, union arg *);
-uint32_t name_to_pixel(int, const char *);
-void name_workspace(struct swm_region *, union arg *);
-void new_region(struct swm_screen *, int, int, int, int);
-int parsekeys(const char *, unsigned int, unsigned int *, KeySym *);
-int parsequirks(const char *, unsigned long *);
-int parse_rgb(const char *, uint16_t *, uint16_t *, uint16_t *);
-void pressbutton(struct swm_region *, union arg *);
-void priorws(struct swm_region *, union arg *);
-void propertynotify(xcb_property_notify_event_t *);
-void quirk_free(struct quirk *);
-void quirk_insert(const char *, const char *, const char *,unsigned long);
-void quirk_remove(struct quirk *);
-void quirk_replace(struct quirk *, const char *, const char *, const char *,
- unsigned long);
-void quit(struct swm_region *, union arg *);
-void raise_toggle(struct swm_region *, union arg *);
-void region_containment(struct ws_win *, struct swm_region *, int);
-void regionize(struct ws_win *, int, int);
-void resize(struct ws_win *, union arg *);
-void resize_step(struct swm_region *, union arg *);
-void restart(struct swm_region *, union arg *);
-void screenchange(xcb_randr_screen_change_notify_event_t *);
-void scan_xrandr(int);
-void spawn_remove(struct spawn_prog *);
-void spawn_replace(struct spawn_prog *, const char *, const char *, int);
-void spawn_select(struct swm_region *, union arg *, const char *, int *);
-void stack_config(struct swm_region *, union arg *);
-void stack_floater(struct ws_win *, struct swm_region *);
-void stack_master(struct workspace *, struct swm_geometry *, int, int);
-void store_float_geom(struct ws_win *);
-char *strdupsafe(const char *);
-void swapwin(struct swm_region *, union arg *);
-void switchws(struct swm_region *, union arg *);
-void teardown_ewmh(void);
-void unescape_selector(char *);
-void unfocus_win(struct ws_win *);
-void uniconify(struct swm_region *, union arg *);
-void unmanage_window(struct ws_win *);
-void unmapnotify(xcb_unmap_notify_event_t *);
-void unmap_all(void);
-void unmap_window(struct ws_win *);
-void updatenumlockmask(void);
-void update_modkey(unsigned int);
-void update_window(struct ws_win *);
-void validate_spawns(void);
-int validate_win(struct ws_win *);
-int validate_ws(struct workspace *);
-void version(struct swm_region *, union arg *);
-void win_to_ws(struct ws_win *, int, int);
-pid_t window_get_pid(xcb_window_t);
-void wkill(struct swm_region *, union arg *);
-void workaround(void);
-void xft_init(struct swm_region *);
-void _add_startup_exception(const char *, va_list);
-void add_startup_exception(const char *, ...);
-#ifdef SWM_DEBUG
-void focusin(xcb_focus_in_event_t *);
-void focusout(xcb_focus_out_event_t *);
-void leavenotify(xcb_leave_notify_event_t *);
-void print_win_geom(xcb_window_t);
-#endif
-
+void expose(xcb_expose_event_t *);
+void fake_keypress(struct ws_win *, xcb_keysym_t, uint16_t);
struct pid_e *find_pid(pid_t);
struct ws_win *find_unmanaged_window(xcb_window_t);
struct ws_win *find_window(xcb_window_t);
-struct ws_win *get_focus_magic(struct ws_win *);
-struct ws_win *get_focus_prev(struct ws_win *);
+void floating_toggle(struct swm_region *, union arg *);
+int floating_toggle_win(struct ws_win *);
+void focus(struct swm_region *, union arg *);
+#ifdef SWM_DEBUG
+void focusin(xcb_focus_in_event_t *);
+void focusout(xcb_focus_out_event_t *);
+#endif
+void focus_flush(void);
+void focus_region(struct swm_region *);
+void focusrg(struct swm_region *, union arg *);
+void focus_win(struct ws_win *);
+void fontset_init(void);
+void free_window(struct ws_win *);
+xcb_atom_t get_atom_from_string(const char *);
+#ifdef SWM_DEBUG
+char *get_atom_name(xcb_atom_t);
+#endif
+struct ws_win *get_focus_magic(struct ws_win *);
+struct ws_win *get_focus_prev(struct ws_win *);
+#ifdef SWM_DEBUG
+char *get_notify_detail_label(uint8_t);
+char *get_notify_mode_label(uint8_t);
+#endif
struct ws_win *get_pointer_win(xcb_window_t);
struct ws_win *get_region_focus(struct swm_region *);
-struct ws_win *manage_window(xcb_window_t, uint16_t);
-int get_region_index(struct swm_region *);
-xcb_atom_t get_atom_from_string(const char *);
+int get_region_index(struct swm_region *);
xcb_screen_t *get_screen(int);
-xcb_window_t get_sibling(struct ws_win *, int);
-int get_screen_count(void);
-uint32_t getstate(xcb_window_t);
+xcb_window_t get_sibling(struct ws_win *, int);
+int get_screen_count(void);
+#ifdef SWM_DEBUG
+char *get_stack_mode_name(uint8_t);
+#endif
+int32_t get_swm_iconic(struct ws_win *);
+char *get_win_name(xcb_window_t);
+void get_wm_protocols(struct ws_win *);
+int get_ws_idx(xcb_window_t);
+uint32_t getstate(xcb_window_t);
+void grabbuttons(struct ws_win *);
+void grabkeys(void);
+void grab_windows(void);
+void iconify(struct swm_region *, union arg *);
+int isxlfd(char *);
+void keypress(xcb_key_press_event_t *);
+int key_cmp(struct key *, struct key *);
+void key_insert(unsigned int, KeySym, enum keyfuncid, const char *);
struct key *key_lookup(unsigned int, KeySym);
+void key_remove(struct key *);
+void key_replace(struct key *, unsigned int, KeySym, enum keyfuncid,
+ const char *);
+void kill_bar_extra_atexit(void);
+void kill_refs(struct ws_win *);
#ifdef SWM_DEBUG
-char *get_atom_name(xcb_atom_t);
-char *get_notify_detail_label(uint8_t);
-char *get_notify_mode_label(uint8_t);
-char *get_stack_mode_name(uint8_t);
+void leavenotify(xcb_leave_notify_event_t *);
#endif
-
+void load_float_geom(struct ws_win *);
+struct ws_win *manage_window(xcb_window_t, uint16_t);
+void map_window(struct ws_win *);
+void mapnotify(xcb_map_notify_event_t *);
+void mappingnotify(xcb_mapping_notify_event_t *);
+void maprequest(xcb_map_request_event_t *);
+void maximize_toggle(struct swm_region *, union arg *);
+void motionnotify(xcb_motion_notify_event_t *);
+void move(struct ws_win *, union arg *);
+void move_step(struct swm_region *, union arg *);
+uint32_t name_to_pixel(int, const char *);
+void name_workspace(struct swm_region *, union arg *);
+void new_region(struct swm_screen *, int, int, int, int);
+int parsekeys(const char *, unsigned int, unsigned int *, KeySym *);
+int parsequirks(const char *, unsigned long *);
+int parse_rgb(const char *, uint16_t *, uint16_t *, uint16_t *);
+void pressbutton(struct swm_region *, union arg *);
+void priorws(struct swm_region *, union arg *);
+#ifdef SWM_DEBUG
+void print_win_geom(xcb_window_t);
+#endif
+void propertynotify(xcb_property_notify_event_t *);
+void quirk_free(struct quirk *);
+void quirk_insert(const char *, const char *, const char *,unsigned long);
+void quirk_remove(struct quirk *);
+void quirk_replace(struct quirk *, const char *, const char *, const char *,
+ unsigned long);
+void quit(struct swm_region *, union arg *);
+void raise_toggle(struct swm_region *, union arg *);
+void region_containment(struct ws_win *, struct swm_region *, int);
struct swm_region *region_under(struct swm_screen *, int, int);
+void regionize(struct ws_win *, int, int);
+void resize(struct ws_win *, union arg *);
+void resize_step(struct swm_region *, union arg *);
+void restart(struct swm_region *, union arg *);
struct swm_region *root_to_region(xcb_window_t, int);
+void screenchange(xcb_randr_screen_change_notify_event_t *);
+void scan_xrandr(int);
+void search_do_resp(void);
+void search_resp_name_workspace(const char *, size_t);
+void search_resp_search_window(const char *);
+void search_resp_search_workspace(const char *);
+void search_resp_uniconify(const char *, size_t);
+void search_win(struct swm_region *, union arg *);
+void search_win_cleanup(void);
+void search_workspace(struct swm_region *, union arg *);
+void send_to_rg(struct swm_region *, union arg *);
+void send_to_ws(struct swm_region *, union arg *);
+void set_region(struct swm_region *);
+int setautorun(const char *, const char *, int);
+int setconfbinding(const char *, const char *, int);
+int setconfcolor(const char *, const char *, int);
+int setconfmodkey(const char *, const char *, int);
+int setconfquirk(const char *, const char *, int);
+int setconfregion(const char *, const char *, int);
+int setconfspawn(const char *, const char *, int);
+int setconfvalue(const char *, const char *, int);
+void setkeybinding(unsigned int, KeySym, enum keyfuncid, const char *);
+int setkeymapping(const char *, const char *, int);
+int setlayout(const char *, const char *, int);
+void setquirk(const char *, const char *, const char *,unsigned long);
+void setscreencolor(const char *, int, int);
+void setspawn(const char *, const char *, int);
+void setup_ewmh(void);
+void setup_globals(void);
+void setup_keys(void);
+void setup_quirks(void);
+void setup_screens(void);
+void setup_spawn(void);
+void set_child_transient(struct ws_win *, xcb_window_t *);
+void set_swm_iconic(struct ws_win *, int);
+void set_win_state(struct ws_win *, uint16_t);
+void shutdown_cleanup(void);
+void sighdlr(int);
+void socket_setnonblock(int);
+void sort_windows(struct ws_win_list *);
+void spawn(int, union arg *, int);
+void spawn_custom(struct swm_region *, union arg *, const char *);
+int spawn_expand(struct swm_region *, union arg *, const char *, char ***);
+void spawn_insert(const char *, const char *, int);
struct spawn_prog *spawn_find(const char *);
+void spawn_remove(struct spawn_prog *);
+void spawn_replace(struct spawn_prog *, const char *, const char *, int);
+void spawn_select(struct swm_region *, union arg *, const char *, int *);
+void stack_config(struct swm_region *, union arg *);
+void stack_floater(struct ws_win *);
+void stack_master(struct workspace *, struct swm_geometry *, int, int);
+void reorder_window(struct ws_win *, uint32_t);
+void store_float_geom(struct ws_win *);
+char *strdupsafe(const char *);
+void swapwin(struct swm_region *, union arg *);
+void switchws(struct swm_region *, union arg *);
+void teardown_ewmh(void);
+void unescape_selector(char *);
+void unfocus_win(struct ws_win *);
+void uniconify(struct swm_region *, union arg *);
+void unmanage_window(struct ws_win *);
+void unmapnotify(xcb_unmap_notify_event_t *);
+void unmap_all(void);
+void unmap_window(struct ws_win *);
+void updatenumlockmask(void);
+void update_modkey(unsigned int);
+void update_window(struct ws_win *);
+void validate_spawns(void);
+int validate_win(struct ws_win *);
+int validate_ws(struct workspace *);
+void version(struct swm_region *, union arg *);
+void win_to_ws(struct ws_win *, int, int);
+pid_t window_get_pid(xcb_window_t);
+void wkill(struct swm_region *, union arg *);
+void workaround(void);
+void xft_init(struct swm_region *);
+void _add_startup_exception(const char *, va_list);
+void add_startup_exception(const char *, ...);
RB_PROTOTYPE(key_tree, key, entry, key_cmp);
RB_GENERATE(key_tree, key, entry, key_cmp);
-struct key_tree keys;
+struct key_tree keys;
void
cursors_load(void)
char *
expand_tilde(const char *s)
{
- struct passwd *ppwd;
- int i;
+ struct passwd *ppwd;
+ int i;
long max;
- char *user;
- const char *sc = s;
+ char *user;
+ const char *sc = s;
char *result;
if (s == NULL)
ewmh[_NET_WM_ALLOWED_ACTIONS].atom, XCB_ATOM_ATOM, 32, 1, actions);
}
-#define _NET_WM_STATE_REMOVE 0 /* remove/unset property */
-#define _NET_WM_STATE_ADD 1 /* add/set property */
-#define _NET_WM_STATE_TOGGLE 2 /* toggle property */
+#define _NET_WM_STATE_REMOVE 0 /* remove/unset property */
+#define _NET_WM_STATE_ADD 1 /* add/set property */
+#define _NET_WM_STATE_TOGGLE 2 /* toggle property */
void
ewmh_update_win_state(struct ws_win *win, xcb_atom_t state, long action)
unsigned int mask = 0;
unsigned int changed = 0;
unsigned int orig_flags;
+#ifdef SWM_DEBUG
+ char *name;
+#endif
if (win == NULL)
return;
- DNPRINTF(SWM_D_PROP, "ewmh_update_win_state: window: 0x%x, state: %ld, "
- "action: %ld\n", win->id, (unsigned long)state, action);
+#ifdef SWM_DEBUG
+ name = get_atom_name(state);
+ DNPRINTF(SWM_D_PROP, "ewmh_update_win_state: window: 0x%x, state: %s, "
+ "action: %ld\n", win->id, name, action);
+ free(name);
+#endif
if (state == ewmh[_NET_WM_STATE_FULLSCREEN].atom)
mask = EWMH_F_FULLSCREEN;
void
bar_print(struct swm_region *r, const char *s)
{
- size_t len;
- xcb_rectangle_t rect;
- uint32_t gcv[1];
- int32_t x = 0;
- XGlyphInfo info;
- XftDraw *draw;
+ size_t len;
+ xcb_rectangle_t rect;
+ uint32_t gcv[1];
+ int32_t x = 0;
+ XGlyphInfo info;
+ XftDraw *draw;
len = strlen(s);
}
void
-bar_window_float(char *s, size_t sz, struct swm_region *r)
+bar_window_state(char *s, size_t sz, struct swm_region *r)
{
if (r == NULL || r ->ws == NULL || r->ws->focus == NULL)
return;
- if (r->ws->focus->floating)
+ if (r->ws->focus->maximized)
+ strlcat(s, "(m)", sz);
+ else if (r->ws->focus->floating)
strlcat(s, "(f)", sz);
}
strlcat(fmtnew, "+T+4<", sz);
}
if (window_name_enabled) {
- if (r->ws->focus->floating)
+ if (r->ws->focus->floating || r->ws->focus->maximized)
strlcat(fmtnew, "+F ", sz);
strlcat(fmtnew, "+64W ", sz);
}
bar_workspace_name(tmp, sizeof tmp, r);
break;
case 'F':
- bar_window_float(tmp, sizeof tmp, r);
+ bar_window_state(tmp, sizeof tmp, r);
break;
case 'I':
snprintf(tmp, sizeof tmp, "%d", r->ws->idx + 1);
}
void
-map_window(struct ws_win *win, xcb_window_t sibling)
+reorder_window(struct ws_win *win, uint32_t mode)
{
- uint16_t mode = XCB_CONFIG_WINDOW_STACK_MODE;
+ struct ws_win *w = win;
+ struct swm_region *r;
+ struct workspace *ws;
uint32_t val[2];
- int i = 0;
- /* If sibling is specified, stack right above it. */
- if (sibling != XCB_WINDOW_NONE) {
- mode |= XCB_CONFIG_WINDOW_SIBLING;
- val[i++] = sibling;
+ if (win == NULL || (r = win->ws->r) == NULL)
+ return;
+ ws = win->ws;
+
+ DNPRINTF(SWM_D_EVENT, "reorder_window: win 0x%x, mode: %d\n",
+ win->id, mode);
+
+ switch (mode) {
+ case SWM_STACK_TOP:
+ /* Position above top-most sibling. */
+ TAILQ_FOREACH_REVERSE(w, &ws->winlist, ws_win_list, entry) {
+ if (w == win || w->iconic)
+ continue;
+ if ((win->ewmh_flags & EWMH_F_FULLSCREEN) !=
+ (w->ewmh_flags & EWMH_F_FULLSCREEN))
+ continue;
+ if (!win->maximized && w->maximized)
+ continue;
+ if (win->maximized) {
+ if (w->floating)
+ break;
+ continue;
+ }
+ if (win->floating == w->floating)
+ break;
+ }
+ break;
+ case SWM_STACK_ABOVE:
+ /* Stack above win directly prior. */
+ while ((w = TAILQ_PREV(w, ws_win_list, entry)) != NULL) {
+ if (w == win || w->iconic)
+ continue;
+ if ((win->ewmh_flags & EWMH_F_FULLSCREEN) !=
+ (w->ewmh_flags & EWMH_F_FULLSCREEN))
+ continue;
+ if (win->maximized != w->maximized)
+ continue;
+ if (win->floating == w->floating)
+ break;
+ }
+ break;
+ case SWM_STACK_BELOW:
+ /* Stack above win directly prior. */
+ while ((w = TAILQ_NEXT(w, entry)) != NULL) {
+ if (w == win || w->iconic)
+ continue;
+ if ((win->ewmh_flags & EWMH_F_FULLSCREEN) !=
+ (w->ewmh_flags & EWMH_F_FULLSCREEN))
+ continue;
+ if (win->maximized != w->maximized)
+ continue;
+ if (win->floating == w->floating)
+ break;
+ }
+ break;
+ case SWM_STACK_BOTTOM:
+ /* Position above top-most sibling. */
+ TAILQ_FOREACH(w, &ws->winlist, entry) {
+ if (w == win || w->iconic)
+ continue;
+ if ((win->ewmh_flags & EWMH_F_FULLSCREEN) !=
+ (w->ewmh_flags & EWMH_F_FULLSCREEN))
+ continue;
+ if (win->maximized != w->maximized)
+ continue;
+ if (win->floating == w->floating)
+ break;
+ }
+ break;
+ }
+
+ if (w == NULL) {
+ if (win->floating || (win->ewmh_flags & EWMH_F_FULLSCREEN)
+ || win->maximized)
+ val[0] = r->bar->id;
+ else
+ val[0] = r->id;
+ } else {
+ val[0] = w->id;
}
+ DNPRINTF(SWM_D_EVENT, "reorder_window: sibling: 0x%x\n", val[0]);
- val[i] = XCB_STACK_MODE_ABOVE;
+ val[1] = XCB_STACK_MODE_ABOVE;
+ xcb_configure_window(conn, win->id, XCB_CONFIG_WINDOW_STACK_MODE |
+ XCB_CONFIG_WINDOW_SIBLING, val);
+}
+
+void
+map_window(struct ws_win *win)
+{
if (win == NULL)
return;
- DNPRINTF(SWM_D_EVENT, "map_window: win 0x%x, mapped: %s, "
- "sibling: 0x%x\n", win->id, YESNO(win->mapped), sibling);
-
- xcb_configure_window(conn, win->id, mode, val);
+ DNPRINTF(SWM_D_EVENT, "map_window: win 0x%x, mapped: %s\n",
+ win->id, YESNO(win->mapped));
if (win->mapped)
return;
return (1);
}
-xcb_window_t
-get_sibling(struct ws_win *win, int mode)
-{
- struct ws_win *w = win;
-
- switch (mode) {
- case SWM_STACK_TOP:
- TAILQ_FOREACH_REVERSE(w, &w->ws->winlist, ws_win_list, entry)
- if (w != win && !w->floating && !w->iconic)
- break;
- break;
- case SWM_STACK_ABOVE:
- do {
- w = TAILQ_NEXT(w, entry);
- } while (w != NULL && (w == win || w->floating || w->iconic));
- break;
- case SWM_STACK_BELOW:
- do {
- w = TAILQ_PREV(w, ws_win_list, entry);
- } while (w != NULL && (w == win || w->floating || w->iconic));
- break;
- case SWM_STACK_BOTTOM:
- TAILQ_FOREACH(w, &w->ws->winlist, entry)
- if (w != win && !w->floating && !w->iconic)
- break;
- break;
- default:
- w = NULL;
- }
-
- if (w == NULL)
- return (win->ws->r->id);
- else
- return (w->id);
-}
-
void
unfocus_win(struct ws_win *win)
{
}
if (win->ws->focus == win) {
- if (tile_gap < 0 && !win->floating)
- map_window(win, get_sibling(win, SWM_STACK_BELOW));
+ if (tile_gap < 0 && !win->floating && !win->maximized)
+ reorder_window(win, SWM_STACK_ABOVE);
win->ws->focus = NULL;
win->ws->focus_prev = win;
}
ws->always_raise) {
/* If a parent exists, map it first. */
if (parent) {
- map_window(parent, XCB_WINDOW_NONE);
+ reorder_window(parent, SWM_STACK_TOP);
+ map_window(parent);
/* Map siblings next. */
TAILQ_FOREACH(w, &ws->winlist, entry)
if (w != win && !w->iconic &&
- w->transient == parent->id)
- map_window(w, XCB_WINDOW_NONE);
+ w->transient == parent->id) {
+ reorder_window(w, SWM_STACK_ABOVE);
+ map_window(w);
+ }
}
/* Map focused window. */
- map_window(win, XCB_WINDOW_NONE);
+ reorder_window(win, SWM_STACK_TOP);
+ map_window(win);
/* Finally, map children of focus window. */
TAILQ_FOREACH(w, &ws->winlist, entry)
- if (w->transient == win->id && !w->iconic)
- map_window(w, XCB_WINDOW_NONE);
+ if (w->transient == win->id && !w->iconic) {
+ reorder_window(w, SWM_STACK_ABOVE);
+ map_window(w);
+ }
} else if (tile_gap < 0 && !win->floating) {
/*
* Windows overlap in the layout.
* Raise focused win above all tiled wins.
*/
- if (tile_gap < 0 && !win->floating)
- map_window(win,
- get_sibling(win, SWM_STACK_TOP));
+ reorder_window(win, SWM_STACK_TOP);
+ map_window(win);
}
set_region(ws->r);
new_ws->focus_prev = NULL;
}
+ new_ws->state = SWM_WS_STATE_MAPPING;
stack();
/* unmap old windows */
- if (unmap_old)
+ if (unmap_old) {
TAILQ_FOREACH(win, &old_ws->winlist, entry)
unmap_window(win);
+ old_ws->state = SWM_WS_STATE_HIDDEN;
+ }
/* if workspaces were swapped, then don't wait to set focus */
if (old_ws->r && focus_mode != SWM_FOCUS_FOLLOW) {
}
focus_flush();
+ new_ws->state = SWM_WS_STATE_MAPPED;
DNPRINTF(SWM_D_WS, "switchws: done.\n");
}
void
priorws(struct swm_region *r, union arg *args)
{
- union arg a;
+ union arg a;
(void)args;
if (cur_focus == NULL)
return;
+ clear_maximized(r->ws);
+
source = cur_focus;
wl = &source->ws->winlist;
wl = &ws->winlist;
cur_focus = ws->focus;
- DNPRINTF(SWM_D_FOCUS, "get_focus_prev: window: 0x%x, cur_focus: 0x%x\n",
- WINID(win), WINID(cur_focus));
+ DNPRINTF(SWM_D_FOCUS, "get_focus_prev: window: 0x%x, cur_focus: 0x%x, "
+ "focus_prev: 0x%x\n", WINID(win), WINID(cur_focus),
+ WINID(ws->focus_prev));
/* pickle, just focus on whatever */
if (cur_focus == NULL) {
/* use prev_focus if valid */
- if (ws->focus_prev && ws->focus_prev != cur_focus &&
- find_window(WINID(ws->focus_prev)))
+ if (ws->focus_prev && find_window(ws->focus_prev->id))
winfocus = ws->focus_prev;
goto done;
}
goto out;
}
+ if (clear_maximized(ws) > 0)
+ stack();
+
focus_win(get_focus_magic(winfocus));
focus_flush();
if (ws->cur_layout->l_stack == NULL)
ws->cur_layout = &layouts[0];
+ clear_maximized(ws);
+
stack();
bar_draw();
DNPRINTF(SWM_D_STACK, "stack_config: id: %d workspace: %d\n",
args->id, ws->idx);
+ if (clear_maximized(ws) > 0)
+ stack();
+
if (ws->cur_layout->l_config != NULL)
ws->cur_layout->l_config(ws, args->id);
j = 0;
#endif
TAILQ_FOREACH(r, &screens[i].rl, entry) {
- DNPRINTF(SWM_D_STACK, "stack: workspace: %d "
- "(screen: %d, region: %d)\n", r->ws->idx, i, j++);
-
/* Adjust stack area for region bar and padding. */
g = r->g;
g.x += region_padding;
g.y += bar_height;
g.h -= bar_height;
}
+
+ DNPRINTF(SWM_D_STACK, "stack: workspace: %d (screen: "
+ "%d, region: %d), (x,y) WxH: (%d,%d) %d x %d\n",
+ r->ws->idx, i, j++, g.x, g.y, g.w, g.h);
+
r->ws->cur_layout->l_stack(r->ws, &g);
r->ws->cur_layout->l_string(r->ws);
/* save r so we can track region changes */
}
void
-stack_floater(struct ws_win *win, struct swm_region *r)
+stack_floater(struct ws_win *win)
{
+ struct workspace *ws;
+ struct swm_region *r;
+
if (win == NULL)
return;
- DNPRINTF(SWM_D_MISC, "stack_floater: window: 0x%x\n", win->id);
+ ws = win->ws;
- /*
- * to allow windows to change their size (e.g. mplayer fs) only retrieve
- * geom on ws switches or return from max mode
- */
- if (win->floatmaxed || (r != r->ws->old_r &&
- !(win->ewmh_flags & EWMH_F_FULLSCREEN))) {
- /* update geometry for the new region */
- load_float_geom(win);
- }
+ if ((r = ws->r) == NULL)
+ return;
- win->floatmaxed = 0;
+ DNPRINTF(SWM_D_MISC, "stack_floater: window: 0x%x\n", win->id);
- /*
- * if set to fullscreen mode, configure window to maximum size.
- */
if (win->ewmh_flags & EWMH_F_FULLSCREEN) {
+ /* _NET_WM_FULLSCREEN: fullscreen without border. */
if (!win->g_floatvalid)
store_float_geom(win);
win->g = r->g;
- }
+ win->bordered = 0;
+ } else if (win->maximized) {
+ /* Maximize: like a single stacked window. */
+ if (!win->g_floatvalid)
+ store_float_geom(win);
- /*
- * remove border on fullscreen floater when in fullscreen mode or when
- * the quirk is present.
- */
- if ((win->ewmh_flags & EWMH_F_FULLSCREEN) ||
- ((win->quirks & SWM_Q_FULLSCREEN) &&
- (WIDTH(win) >= WIDTH(r)) && (HEIGHT(win) >= HEIGHT(r)))) {
- if (win->bordered) {
+ win->g = r->g;
+
+ if (bar_enabled && ws->bar_enabled) {
+ win->bordered = 1;
+ if (!bar_at_bottom)
+ Y(win) += bar_height;
+ HEIGHT(win) -= bar_height;
+ } else if (disable_border) {
win->bordered = 0;
- X(win) += border_width;
- Y(win) += border_width;
+ } else {
+ win->bordered = 1;
}
- } else if (!win->bordered) {
- win->bordered = 1;
- X(win) -= border_width;
- Y(win) -= border_width;
- }
-
- if (win->transient && (win->quirks & SWM_Q_TRANSSZ)) {
- WIDTH(win) = (double)WIDTH(r) * dialog_ratio;
- HEIGHT(win) = (double)HEIGHT(r) * dialog_ratio;
- }
- if (!win->manual && !(win->ewmh_flags & EWMH_F_FULLSCREEN) &&
- !(win->quirks & SWM_Q_ANYWHERE)) {
- /*
- * floaters and transients are auto-centred unless moved,
- * resized or ANYWHERE quirk is set.
- */
- X(win) = X(r) + (WIDTH(r) - WIDTH(win)) / 2 - BORDER(win);
- Y(win) = Y(r) + (HEIGHT(r) - HEIGHT(win)) / 2 - BORDER(win);
+ if (win->bordered) {
+ HEIGHT(win) -= 2 * border_width;
+ WIDTH(win) -= 2 * border_width;
+ }
+ } else {
+ /* Normal floating window. */
+ /* Update geometry if new region. */
+ if (r != ws->old_r)
+ load_float_geom(win);
+
+ if ((win->quirks & SWM_Q_FULLSCREEN) &&
+ WIDTH(win) >= WIDTH(r) && HEIGHT(win) >= HEIGHT(r)) {
+ /* Remove border for FULLSCREEN quirk. */
+ win->bordered = 0;
+ } else if (!win->manual) {
+ if (win->transient && (win->quirks & SWM_Q_TRANSSZ)) {
+ /* Adjust size on TRANSSZ quirk. */
+ WIDTH(win) = (double)WIDTH(r) * dialog_ratio;
+ HEIGHT(win) = (double)HEIGHT(r) * dialog_ratio;
+ }
- store_float_geom(win);
+ if (!(win->quirks & SWM_Q_ANYWHERE)) {
+ /*
+ * Floaters and transients are auto-centred
+ * unless manually moved, resized or ANYWHERE
+ * quirk is set.
+ */
+ X(win) = X(r) + (WIDTH(r) - WIDTH(win)) / 2 -
+ BORDER(win);
+ Y(win) = Y(r) + (HEIGHT(r) - HEIGHT(win)) / 2 -
+ BORDER(win);
+ store_float_geom(win);
+ }
+ }
}
/* Ensure at least 1 pixel of the window is in the region. */
stack_master(struct workspace *ws, struct swm_geometry *g, int rot, int flip)
{
struct swm_geometry win_g, r_g = *g;
- struct ws_win *win, *fs_win = NULL;
+ struct ws_win *win, *fs_win = NULL, *max_win = NULL;
int i, j, s, stacks;
int w_inc = 1, h_inc, w_base = 1, h_base;
int hrh, extra = 0, h_slice, last_h = 0;
if (winno == 0 && count_win(ws, 1) == 0)
return;
+ /* Find first tiled window. */
TAILQ_FOREACH(win, &ws->winlist, entry)
if (!win->transient && !win->floating && !win->iconic)
break;
continue;
}
+ if (win->maximized) {
+ max_win = win;
+ continue;
+ }
+
if (split && i == split) {
colno = (winno - mwin) / stacks;
if (s <= (winno - mwin) % stacks)
update_window(win);
}
- map_window(win, get_sibling(win, SWM_STACK_BELOW));
+ reorder_window(win, SWM_STACK_ABOVE);
+ map_window(win);
last_h = win_g.h;
i++;
}
/* Map/raise focused tiled window to top if windows could overlap. */
- if (tile_gap < 0 && ws->focus != NULL && !ws->focus->floating)
- map_window(ws->focus, get_sibling(ws->focus, SWM_STACK_TOP));
+ if (tile_gap < 0 && ws->focus != NULL && !ws->focus->floating &&
+ !ws->focus->maximized) {
+ reorder_window(ws->focus, SWM_STACK_TOP);
+ map_window(ws->focus);
+ }
notiles:
/* now, stack all the floaters and transients */
TAILQ_FOREACH(win, &ws->winlist, entry) {
- if (!win->transient && !win->floating)
- continue;
- if (win->iconic)
+ if ((!win->transient && !win->floating) || win->iconic)
continue;
+
if (win->ewmh_flags & EWMH_F_FULLSCREEN) {
fs_win = win;
continue;
}
- stack_floater(win, ws->r);
- map_window(win, XCB_WINDOW_NONE);
+ if (win->maximized) {
+ max_win = win;
+ continue;
+ }
+
+ stack_floater(win);
+ reorder_window(win, SWM_STACK_ABOVE);
+ map_window(win);
}
- /* Make sure fs_win is stacked last so it's on top. */
+ /* Make sure fs_win is stacked on top. */
if (fs_win) {
- stack_floater(fs_win, ws->r);
- map_window(fs_win, XCB_WINDOW_NONE);
+ stack_floater(fs_win);
+ reorder_window(fs_win, SWM_STACK_TOP);
+ map_window(fs_win);
+ } else if (max_win) {
+ stack_floater(max_win);
+ reorder_window(max_win, SWM_STACK_TOP);
+ map_window(max_win);
}
+
+ DNPRINTF(SWM_D_STACK, "stack_master: max_win: 0x%x\n", WINID(max_win));
}
void
if (w->transient || w->iconic)
continue;
- if (!w->mapped && w != win)
- map_window(w, XCB_WINDOW_NONE);
+ if (!w->mapped && w != win) {
+ reorder_window(w, SWM_STACK_TOP);
+ map_window(w);
+ }
- if (w->floating && !w->floatmaxed) {
+ if (w->floating && !w->maximized) {
/*
* retain geometry for retrieval on exit from
* max_stack mode
*/
store_float_geom(w);
- w->floatmaxed = 1;
+ w->maximized = 1;
}
/* only reconfigure if necessary */
/* If a parent exists, map/raise it first. */
if (parent) {
- map_window(parent, XCB_WINDOW_NONE);
+ reorder_window(parent, SWM_STACK_TOP);
+ map_window(parent);
/* Map siblings next. */
TAILQ_FOREACH(w, &ws->winlist, entry)
if (w != win && !w->iconic &&
w->transient == parent->id) {
- stack_floater(w, ws->r);
- map_window(w, XCB_WINDOW_NONE);
+ stack_floater(w);
+ reorder_window(w, SWM_STACK_ABOVE);
+ map_window(w);
}
}
/* Map/raise focused window. */
- map_window(win, XCB_WINDOW_NONE);
+ reorder_window(win, SWM_STACK_TOP);
+ map_window(win);
/* Finally, map/raise children of focus window. */
TAILQ_FOREACH(w, &ws->winlist, entry)
if (w->transient == win->id && !w->iconic) {
- stack_floater(w, ws->r);
- map_window(w, XCB_WINDOW_NONE);
+ stack_floater(w);
+ reorder_window(w, SWM_STACK_ABOVE);
+ map_window(w);
}
}
DNPRINTF(SWM_D_MOVE, "send_to_ws: win 0x%x, ws %d\n", win->id, wsid);
+ if (wsid >= workspace_limit)
+ return;
+
+ if (win->ws->idx == wsid)
+ return;
+
win_to_ws(win, wsid, 1);
+ win->maximized = 0;
+
/* Restack and set new focus. */
stack();
if (r == NULL || r->ws == NULL)
return;
+ if (r->ws->focus && r->ws->focus->maximized)
+ return;
+
r->ws->always_raise = !r->ws->always_raise;
/* bring floaters back to top */
}
int
-floating_toggle_win(struct ws_win *win)
+clear_maximized(struct workspace *ws)
+{
+ struct ws_win *w;
+ int count = 0;
+
+ /* Clear any maximized win(s) on ws. */
+ TAILQ_FOREACH(w, &ws->winlist, entry)
+ if (w->maximized) {
+ w->maximized = 0;
+ if (w->floating)
+ load_float_geom(w);
+ ++count;
+ }
+
+ return count;
+}
+
+void
+maximize_toggle(struct swm_region *r, union arg *args)
{
+ struct ws_win *win = r->ws->focus;
+
+ /* suppress unused warning since var is needed */
+ (void)args;
+
if (win == NULL)
- return (0);
+ return;
- if (win->ws->r == NULL)
+ DNPRINTF(SWM_D_MISC, "maximize_toggle: win %#x\n", win->id);
+
+ if (win->ewmh_flags & EWMH_F_FULLSCREEN)
+ return;
+
+ if (win->ws->cur_layout == &layouts[SWM_MAX_STACK])
+ return;
+
+ if (win->floating) {
+ if (win->maximized)
+ load_float_geom(win);
+ else
+ store_float_geom(win);
+ }
+
+ win->maximized = !win->maximized;
+
+ stack();
+
+ if (win == win->ws->focus)
+ focus_win(win);
+
+ focus_flush();
+ DNPRINTF(SWM_D_MISC, "maximize_toggle: done\n");
+}
+
+int
+floating_toggle_win(struct ws_win *win)
+{
+ if (win == NULL)
return (0);
/* reject floating toggles in max stack mode */
if (win->ws->cur_layout == &layouts[SWM_MAX_STACK])
return (0);
+ if (win->ws->r == NULL)
+ return (0);
+
if (win->floating) {
- if (!win->floatmaxed) {
- /* retain position for refloat */
+ if (!win->maximized)
store_float_geom(win);
- }
- win->floating = 0;
} else {
load_float_geom(win);
- win->floating = 1;
}
+ win->floating = !win->floating;
+ win->maximized = 0;
+
ewmh_update_actions(win);
return (1);
if (!win->transient && !win->floating)
return;
- /* reject resizes in max mode for floaters (transient ok) */
- if (win->floatmaxed)
+ /* In max_stack mode, should only resize transients. */
+ if (win->ws->cur_layout == &layouts[SWM_MAX_STACK] && !win->transient)
return;
- win->manual = 1;
- ewmh_update_win_state(win, ewmh[_SWM_WM_STATE_MANUAL].atom,
- _NET_WM_STATE_ADD);
+ win->maximized = 0;
+
+ if (!win->manual) {
+ win->manual = 1;
+ ewmh_update_win_state(win, ewmh[_SWM_WM_STATE_MANUAL].atom,
+ _NET_WM_STATE_ADD);
+ }
stack();
if (win->ws->cur_layout == &layouts[SWM_MAX_STACK] && !win->transient)
return;
+ win->maximized = 0;
+
if (!win->manual) {
win->manual = 1;
ewmh_update_win_state(win, ewmh[_SWM_WM_STATE_MANUAL].atom,
{ "focus_next", focus, {.id = SWM_ARG_ID_FOCUSNEXT} },
{ "focus_prev", focus, {.id = SWM_ARG_ID_FOCUSPREV} },
{ "focus_urgent", focus, {.id = SWM_ARG_ID_FOCUSURGENT} },
+ { "maximize_toggle", maximize_toggle,{0} },
{ "height_grow", resize_step, {.id = SWM_ARG_ID_HEIGHTGROW} },
{ "height_shrink", resize_step, {.id = SWM_ARG_ID_HEIGHTSHRINK} },
{ "iconify", iconify, {0} },
setkeybinding(MODKEY, XK_k, KF_FOCUS_PREV, NULL);
setkeybinding(MODKEY_SHIFT, XK_Tab, KF_FOCUS_PREV, NULL);
setkeybinding(MODKEY, XK_u, KF_FOCUS_URGENT,NULL);
+ setkeybinding(MODKEY, XK_e, KF_MAXIMIZE_TOGGLE,NULL);
setkeybinding(MODKEY_SHIFT, XK_equal, KF_HEIGHT_GROW,NULL);
setkeybinding(MODKEY_SHIFT, XK_minus, KF_HEIGHT_SHRINK,NULL);
setkeybinding(MODKEY, XK_w, KF_ICONIFY, NULL);
Y(win) = gr->y + gr->border_width - border_width;
win->bordered = 1;
win->mapped = mapped;
- win->floatmaxed = 0;
+ win->maximized = 0;
win->ewmh_flags = 0;
win->s = r->s; /* this never changes */
xcb_flush(conn);
}
} else if ((!win->manual || win->quirks & SWM_Q_ANYWHERE) &&
- !(win->ewmh_flags & EWMH_F_FULLSCREEN)) {
+ !(win->ewmh_flags & EWMH_F_FULLSCREEN) && !win->maximized) {
if (win->ws->r)
r = win->ws->r;
else if (win->ws->old_r)
win->g_floatvalid = 1;
if (win->floating && r && (win->transient ||
- win->ws->cur_layout != &layouts[SWM_MAX_STACK])) {
+ win->ws->cur_layout != &layouts[SWM_MAX_STACK])
+ && !win->maximized) {
WIDTH(win) = win->g_float.w;
HEIGHT(win) = win->g_float.h;
if (r) {
- stack_floater(win, r);
+ stack_floater(win);
focus_flush();
}
} else {
void
mapnotify(xcb_map_notify_event_t *e)
{
- struct ws_win *win;
+ struct ws_win *win, *parent = NULL;
+ struct workspace *ws;
DNPRINTF(SWM_D_EVENT, "mapnotify: window: 0x%x\n", e->window);
if ((win = manage_window(e->window, 1)) == NULL)
return;
+ ws = win->ws;
+
+ /* Need to know if win was mapped due to ws switch. */
+ if (ws->state == SWM_WS_STATE_MAPPED) {
+ if (ws->focus_pending && ws->focus_pending->transient)
+ parent = find_window(win->transient);
+
+ /* If window's parent is maximized, don't clear it. */
+ if ((parent == NULL) || !parent->maximized)
+ if (clear_maximized(ws) > 0)
+ stack();
+ }
win->mapped = 1;
set_win_state(win, XCB_ICCCM_WM_STATE_NORMAL);
if (focus_mode != SWM_FOCUS_FOLLOW && WS_FOCUSED(win->ws)) {
- if (win->ws->focus_pending == win) {
+ if (ws->focus_pending == win) {
focus_win(win);
- win->ws->focus_pending = NULL;
+ ws->focus_pending = NULL;
focus_flush();
}
}
void
clientmessage(xcb_client_message_event_t *e)
{
- struct ws_win *win;
+ struct ws_win *win;
xcb_map_request_event_t mre;
#ifdef SWM_DEBUG
char *name;
if (ws == NULL)
errx(1, "new_region: no free workspaces");
+ if (ws->state == SWM_WS_STATE_HIDDEN)
+ ws->state = SWM_WS_STATE_MAPPING;
+
X(r) = x;
Y(r) = y;
WIDTH(r) = w;
TAILQ_FOREACH(r, &screens[i].orl, entry) {
TAILQ_FOREACH(win, &r->ws->winlist, entry)
unmap_window(win);
+ r->ws->state = SWM_WS_STATE_HIDDEN;
/* The screen shouldn't focus on an unused region. */
if (screens[i].r_focus == r)
bar_draw();
focus_flush();
+
+ /* Update workspace state on all regions. */
+ for (i = 0; i < num_screens; i++)
+ TAILQ_FOREACH(r, &screens[i].rl, entry)
+ r->ws->state = SWM_WS_STATE_MAPPED;
}
void
void
setup_screens(void)
{
- int i, j, k, num_screens;
- struct workspace *ws;
- uint32_t gcv[1], wa[1];
- const xcb_query_extension_reply_t *qep;
+ int i, j, k, num_screens;
+ struct workspace *ws;
+ uint32_t gcv[1], wa[1];
+ const xcb_query_extension_reply_t *qep;
xcb_screen_t *screen;
xcb_randr_query_version_cookie_t c;
xcb_randr_query_version_reply_t *r;
ws->focus_pending = NULL;
ws->r = NULL;
ws->old_r = NULL;
+ ws->state = SWM_WS_STATE_HIDDEN;
TAILQ_INIT(&ws->winlist);
TAILQ_INIT(&ws->unmanagedlist);
int xfd, i, num_screens, startup = 1;
struct sigaction sact;
xcb_generic_event_t *evt;
- struct timeval tv;
+ struct timeval tv;
fd_set rd;
int rd_max;
int stdin_ready = 0;