summaryrefslogtreecommitdiff
path: root/schewm.c
diff options
context:
space:
mode:
Diffstat (limited to 'schewm.c')
-rw-r--r--schewm.c151
1 files changed, 117 insertions, 34 deletions
diff --git a/schewm.c b/schewm.c
index 350ed80..126ab2f 100644
--- a/schewm.c
+++ b/schewm.c
@@ -9,6 +9,7 @@
#include <xcb/xcb_ewmh.h>
#include <xcb/xcb_icccm.h>
#include <xcb/xcb_keysyms.h>
+#include <X11/Xlib.h>
#include <X11/keysym.h>
// Workspace values which are special for us
@@ -23,6 +24,11 @@ const uint16_t RESIZE_GLYPH = 120;
const uint16_t MOD_META = XCB_MOD_MASK_4;
const uint16_t MOD_SHIFT = XCB_MOD_MASK_SHIFT;
+uint32_t
+keysym_from_str(const char *s) {
+ return (uint32_t) XStringToKeysym(s);
+}
+
// General utility functions
uint32_t
parse_color(const char *s) {
@@ -1033,6 +1039,16 @@ dpy_grab_key(uint16_t mod, xcb_keysym_t keysym) {
}
}
+static uint16_t
+dpy_clean_mod(uint16_t mod) {
+ return mod & ~(dpy.num_lock | dpy.caps_lock | dpy.scroll_lock);
+}
+
+static xcb_keysym_t
+dpy_keysym_from_keycode(xcb_keycode_t keycode) {
+ return xcb_key_symbols_get_keysym(dpy.keysyms, keycode, 0);
+}
+
static void
dpy_set_workspace(uint32_t workspace) {
xcb_ewmh_set_current_desktop(dpy.ewmh, dpy.screen_num, workspace);
@@ -1353,21 +1369,24 @@ dpy_should_ignore_window(xcb_window_t window) {
cookie,
&window_type,
NULL);
+ if (!reply) {
+ return false;
+ }
+
+ // Figure out from window type if we should ignore it
bool should_ignore = false;
- if (reply) {
- // Figure out from window type if we should ignore it
- for (uint32_t i = 0; i < window_type.atoms_len; i++) {
- xcb_atom_t atom = window_type.atoms[i];
- if (atom == dpy.ewmh->_NET_WM_WINDOW_TYPE_TOOLBAR
- || atom == dpy.ewmh->_NET_WM_WINDOW_TYPE_DESKTOP
- || atom == dpy.ewmh->_NET_WM_WINDOW_TYPE_DOCK) {
- // Ignore those windows
- should_ignore = true;
- break;
- }
+ for (uint32_t i = 0; i < window_type.atoms_len; i++) {
+ xcb_atom_t atom = window_type.atoms[i];
+ if (atom == dpy.ewmh->_NET_WM_WINDOW_TYPE_TOOLBAR
+ || atom == dpy.ewmh->_NET_WM_WINDOW_TYPE_DESKTOP
+ || atom == dpy.ewmh->_NET_WM_WINDOW_TYPE_DOCK) {
+ // Ignore those windows
+ should_ignore = true;
+ break;
}
- xcb_ewmh_get_atoms_reply_wipe(&window_type);
}
+ // TODO: test/check if this is necessary only if reply is valid
+ xcb_ewmh_get_atoms_reply_wipe(&window_type);
return should_ignore;
}
@@ -1530,6 +1549,32 @@ wm_erase_client(xcb_window_t id) {
}
}
+bool
+wm_apply_size_hints(struct Client *client) {
+ if (client->state != WS_NORMAL) {
+ return false;
+ }
+
+ bool any_change = false;
+ if (client->min_width > 0 && client->width < client->min_width) {
+ client->width = client->min_width;
+ any_change = true;
+ }
+ if (client->max_width > 0 && client->width > client->max_width) {
+ client->width = client->max_width;
+ any_change = true;
+ }
+ if (client->min_height > 0 && client->height < client->min_height) {
+ client->height = client->min_height;
+ any_change = true;
+ }
+ if (client->max_height > 0 && client->height > client->max_height) {
+ client->height = client->max_height;
+ any_change = true;
+ }
+ return any_change;
+}
+
void
wm_set_focus(struct Client *client) {
if (wm.focus != NULL) {
@@ -1625,39 +1670,77 @@ wm_client_monitor_size(const struct Client *client,
}
}
+void
+wm_set_client_state(struct Client *client, enum WindowState state) {
+ if (state == client->state) {
+ return;
+ }
+
+ switch (state) {
+ case WS_NORMAL:
+ if (client->state == WS_ICONIFIED) {
+ dpy_map_window(client->id);
+ // TODO: check size restoration
+ }
+ client_restore_size(client);
+ dpy_update_window_geometry(client);
+ break;
+ case WS_ICONIFIED:
+ dpy_unmap_window(client->id);
+ break;
+ case WS_MAXIMIZED:
+ client_store_size(client);
+ {
+ struct Rect mon_rect;
+ wm_client_monitor_size(client, true, &mon_rect);
+ client->x = mon_rect.x;
+ client->y = mon_rect.y;
+ client->width = mon_rect.width;
+ client->height = mon_rect.height;
+ }
+ dpy_update_window_geometry(client);
+ break;
+ case WS_FULLSCREEN:
+ break;
+ }
+ client->prev_state = client->state;
+ client->state = state;
+ dpy_set_window_state(client->id, client->state);
+}
+
bool
wm_fit_client(struct Client *client) {
if (client->state == WS_ICONIFIED) {
return false;
}
- struct Rect mon_size;
- wm_client_monitor_size(client, true, &mon_size);
+ struct Rect mon_rect;
+ wm_client_monitor_size(client, true, &mon_rect);
// Check if client *looks* maximized, event though it is not
if (client->state == WS_NORMAL
- && client->width >= mon_size.width
- && client->height >= mon_size.height) {
+ && client->width >= mon_rect.width
+ && client->height >= mon_rect.height) {
wm_set_client_state(client, WS_MAXIMIZED);
return true;
}
bool should_move = false;
// Check if client is located outside monitor coords
- if (client->x > mon_size.x + mon_size.width) {
- client->x = mon_size.x + mon_size.width - client->width - cfg.inner_border_width * 2;
+ if (client->x > mon_rect.x + mon_rect.width) {
+ client->x = mon_rect.x + mon_rect.width - client->width - cfg.inner_border_width * 2;
should_move = true;
}
- if (client->y > mon_size.y + mon_size.height) {
- client->y = mon_size.y + mon_size.height - client->height - cfg.inner_border_width * 2;
+ if (client->y > mon_rect.y + mon_rect.height) {
+ client->y = mon_rect.y + mon_rect.height - client->height - cfg.inner_border_width * 2;
should_move = true;
}
- if (client->x < mon_size.x) {
- client->x = mon_size.x;
+ if (client->x < mon_rect.x) {
+ client->x = mon_rect.x;
should_move = true;
}
- if (client->y < mon_size.y) {
- client->y = mon_size.y;
+ if (client->y < mon_rect.y) {
+ client->y = mon_rect.y;
should_move = true;
}
@@ -1665,22 +1748,22 @@ wm_fit_client(struct Client *client) {
// resize to fill
bool should_resize = wm_apply_size_hints(client);
uint16_t border_width = client->should_ignore_borders ? 0 : cfg.inner_border_width;
- if (client->width + border_width * 2 > mon_size.width) {
- client->x = mon_size.x;
- client->width = mon_size.width - border_width * 2;
+ if (client->width + border_width * 2 > mon_rect.width) {
+ client->x = mon_rect.x;
+ client->width = mon_rect.width - border_width * 2;
should_move = true;
should_resize = true;
- } else if (client->x + client->width + border_width * 2 > mon_size.x + mon_size.width) {
- client->x = mon_size.x + mon_size.width - (client->width + border_width * 2);
+ } else if (client->x + client->width + border_width * 2 > mon_rect.x + mon_rect.width) {
+ client->x = mon_rect.x + mon_rect.width - (client->width + border_width * 2);
should_move = true;
}
- if (client->height + border_width * 2 > mon_size.height) {
- client->y = mon_size.y;
- client->height = mon_size.height - border_width * 2;
+ if (client->height + border_width * 2 > mon_rect.height) {
+ client->y = mon_rect.y;
+ client->height = mon_rect.height - border_width * 2;
should_move = true;
should_resize = true;
- } else if (client->y + client->height + border_width * 2 > mon_size.y + mon_size.height) {
- client->y = mon_size.y + mon_size.height - (client->height + border_width * 2);
+ } else if (client->y + client->height + border_width * 2 > mon_rect.y + mon_rect.height) {
+ client->y = mon_rect.y + mon_rect.height - (client->height + border_width * 2);
should_move = true;
}