summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.scm78
-rw-r--r--schewm.c67
-rw-r--r--wm.scm85
3 files changed, 198 insertions, 32 deletions
diff --git a/main.scm b/main.scm
index f77acf2..92b9362 100644
--- a/main.scm
+++ b/main.scm
@@ -1,39 +1,74 @@
-(use-modules (srfi srfi-9)
- (wm))
-
-(define-record-type <wm-config>
- (make-config
- inner-border-width
- outer-border-width
- magnet-border-width
- offset-x
- offset-y
- offset-width
- offset-height)
- wm-config?
- (inner-border-width config-inner-border-width set-config-inner-border-width!)
- (outer-border-width config-outer-border-width set-config-outer-border-width!)
- (magnet-border-width config-magnet-border-width set-config-magnet-border-width!)
- (offset-x config-offset-x set-config-offset-x!)
- (offset-y config-offset-y set-config-offset-y!)
- (offset-width config-offset-width set-config-offset-width!)
- (offset-height config-offset-height set-config-offset-height!))
+(use-modules (wm))
(define config
(make-config
+ ;; Border sizes
2 ; inner-border-width
0 ; outer-border-width
16 ; magnet-border-width
+ ;; Margins
0 ; offset-x
0 ; offset-y
0 ; offset-width
0 ; offset-height
+ ;; Colors
+ "#35586c" ; focused-color
+ "#333333" ; unfocused-color
+ "#ff6666" ; unkillable-color
+ "#000000" ; empty-color
+ "#0d131a" ; outer-color
))
(define wm-keybindings
`((,(make-shift-key "q") . ,wm-quit)
+ (,(make-key "q") . ,wm-focus-close)
+ ;; Focus
(,(make-key "Tab") . ,wm-focus-prev)
- (,(make-shift-key "Tab") . ,wm-focus-next)))
+ (,(make-shift-key "Tab") . ,wm-focus-next)
+ (,(make-key "k") . ,wm-focus-prev)
+ (,(make-key "j") . ,wm-focus-next)
+ ;; Packing
+ (,(make-shift-key "Left") . ,wm-pack-left)
+ (,(make-shift-key "Right") . ,wm-pack-left)
+ (,(make-shift-key "Up") . ,wm-pack-top)
+ (,(make-shift-key "Down") . ,wm-pack-bottom)
+ ;; Toggle between normal and tiled in a certain position
+ (,(make-key "s") . ,wm-toggle-maximize)
+ (,(make-key "a") . ,wm-toggle-half-left)
+ (,(make-key "Left") . ,wm-toggle-half-left)
+ (,(make-key "d") . ,wm-toggle-half-right)
+ (,(make-key "Right") . ,wm-toggle-half-right)
+ (,(make-key "w") . ,wm-toggle-half-top)
+ (,(make-key "Up") . ,wm-toggle-half-top)
+ (,(make-key "x") . ,wm-toggle-half-bottom)
+ (,(make-key "Down") . ,wm-toggle-half-bottom)
+ (,(make-key "q") . ,wm-toggle-top-left)
+ (,(make-key "e") . ,wm-toggle-top-right)
+ (,(make-key "z") . ,wm-toggle-bottom-left)
+ (,(make-key "c") . ,wm-toggle-bottom-right)
+ ;; Set current workspace
+ (,(make-key "1") . ,wm-set-workspace)
+ (,(make-key "2") . ,wm-set-workspace)
+ (,(make-key "3") . ,wm-set-workspace)
+ (,(make-key "4") . ,wm-set-workspace)
+ (,(make-key "5") . ,wm-set-workspace)
+ (,(make-key "6") . ,wm-set-workspace)
+ (,(make-key "7") . ,wm-set-workspace)
+ (,(make-key "8") . ,wm-set-workspace)
+ (,(make-key "9") . ,wm-set-workspace)
+ ;; Send client to workspace
+ (,(make-shift-key "1") . ,wm-set-client-workspace)
+ (,(make-shift-key "2") . ,wm-set-client-workspace)
+ (,(make-shift-key "3") . ,wm-set-client-workspace)
+ (,(make-shift-key "4") . ,wm-set-client-workspace)
+ (,(make-shift-key "5") . ,wm-set-client-workspace)
+ (,(make-shift-key "6") . ,wm-set-client-workspace)
+ (,(make-shift-key "7") . ,wm-set-client-workspace)
+ (,(make-shift-key "8") . ,wm-set-client-workspace)
+ (,(make-shift-key "9") . ,wm-set-client-workspace)
+ ;; Send client to monitor
+ (,(make-shift-key "i") . ,wm-client-monitor-prev)
+ (,(make-shift-key "o") . ,wm-client-monitor-next)))
(when (wm-init)
(wm-grab-keys wm-keybindings)
@@ -43,4 +78,3 @@
(newline)))
(wm-run)
(wm-quit))
-
diff --git a/schewm.c b/schewm.c
index 0129888..72e6ea8 100644
--- a/schewm.c
+++ b/schewm.c
@@ -432,7 +432,6 @@ static struct {
uint16_t inner_border_width, outer_border_width, magnet_border_width;
int16_t offset_x, offset_y;
uint16_t offset_width, offset_height;
- uint32_t pointer_motion_interval;
struct {
uint32_t focused, unfocused, unkillable, empty, outer;
} colors;
@@ -469,7 +468,6 @@ static struct {
struct Client *focus;
struct ClientsMap *clients;
struct Workspace *workspaces;
- struct xcb_connection_t *conn;
generic_event_handler_t events[XCB_NO_OPERATION];
} wm;
@@ -598,6 +596,34 @@ dpy_has_error() {
return dpy.has_error || xcb_connection_has_error(dpy.conn) > 0;
}
+bool
+dpy_is_protocol_supported(xcb_window_t window, xcb_atom_t atom) {
+ xcb_get_property_cookie_t cookie =
+ xcb_icccm_get_wm_protocols_unchecked(
+ dpy.conn,
+ window,
+ dpy.ewmh->WM_PROTOCOLS);
+ xcb_icccm_get_wm_protocols_reply_t protocols;
+ uint8_t reply = xcb_icccm_get_wm_protocols_reply(
+ dpy.conn,
+ cookie,
+ &protocols,
+ NULL);
+ if (!reply) {
+ return false;
+ }
+
+ bool is_supported = false;
+ for (uint32_t i = 0; i < protocols.atoms_len; i++) {
+ if (protocols.atoms[i] == atom) {
+ is_supported = true;
+ break;
+ }
+ }
+ xcb_icccm_get_wm_protocols_reply_wipe(&protocols);
+ return is_supported;
+}
+
struct Monitor *
dpy_find_monitor(xcb_randr_output_t id) {
if (dpy.monitors == NULL) {
@@ -617,6 +643,12 @@ dpy_find_monitor(xcb_randr_output_t id) {
return NULL;
}
+bool
+dpy_should_update_outputs(const xcb_generic_event_t *event) {
+ return dpy.has_randr
+ && event->response_type == dpy.randr_base + XCB_RANDR_SCREEN_CHANGE_NOTIFY;
+}
+
static bool
dpy_update_output(xcb_randr_output_t output,
xcb_timestamp_t timestamp,
@@ -1482,6 +1514,13 @@ dpy_destroy() {
xcb_key_symbols_free(dpy.keysyms);
}
+ struct Monitor *monitor = dpy.monitors;
+ while (dpy.monitors != NULL) {
+ dpy.monitors = monitor_ring_erase(dpy.monitors, monitor);
+ free(monitor);
+ monitor = dpy.monitors;
+ }
+
if (!dpy_has_error()) {
xcb_free_cursor(dpy.conn, dpy.fleur_cursor);
xcb_free_cursor(dpy.conn, dpy.sizing_cursor);
@@ -1505,7 +1544,7 @@ bool wm_update_outputs();
bool wm_has_error();
bool wm_init();
void wm_quit();
-void wm_close_client();
+void wm_focus_close();
void wm_begin_move_client();
void wm_begin_resize_client();
void wm_focus_prev();
@@ -1935,6 +1974,28 @@ wm_destroy() {
}
void
+wm_close(struct Client *client) {
+ if (client->is_unkillable) {
+ return;
+ }
+
+ if (dpy_is_protocol_supported(client->id, dpy.delete_window_atom)) {
+ dpy_send_window_message(client->id, dpy.delete_window_atom);
+ } else {
+ dpy_kill_window(client->id);
+ }
+}
+
+void
+wm_focus_close() {
+ if (wm.focus == NULL) {
+ return;
+ }
+
+ wm_close(wm.focus);
+}
+
+void
wm_raise_and_center_cursor(struct Client *client) {
dpy_raise_window(client->id);
dpy_center_cursor_client(client);
diff --git a/wm.scm b/wm.scm
index 744c408..bdbc6dd 100644
--- a/wm.scm
+++ b/wm.scm
@@ -1,6 +1,8 @@
(define-module (wm)
+ #:use-module (srfi srfi-9)
#:use-module (system foreign)
#:export (wm-init
+ make-config
make-key
make-shift-key
wm-grab-keys
@@ -9,14 +11,64 @@
wm-set-key-press-handler!
wm-focus-prev
wm-focus-next
+ wm-focus-close
+ wm-pack-left
+ wm-pack-right
+ wm-pack-top
+ wm-pack-bottom
+ wm-toggle-maximize
+ wm-toggle-half-left
+ wm-toggle-half-right
+ wm-toggle-half-top
+ wm-toggle-half-bottom
+ wm-toggle-top-left
+ wm-toggle-top-right
+ wm-toggle-bottom-left
+ wm-toggle-bottom-right
+ wm-set-workspace
+ wm-set-client-workspace
+ wm-client-monitor-prev
+ wm-client-monitor-next
wm-run
wm-quit))
-(define libschewm (dynamic-link "libschewm"))
-
+;; Configuration record
+(define-record-type <wm-config>
+ (make-config
+ inner-border-width
+ outer-border-width
+ magnet-border-width
+ offset-x
+ offset-y
+ offset-width
+ offset-height
+ focused-color
+ unfocused-color
+ unkillable-color
+ empty-color
+ outer-color)
+ wm-config?
+ (inner-border-width config-inner-border-width set-config-inner-border-width!)
+ (outer-border-width config-outer-border-width set-config-outer-border-width!)
+ (magnet-border-width config-magnet-border-width set-config-magnet-border-width!)
+ (offset-x config-offset-x set-config-offset-x!)
+ (offset-y config-offset-y set-config-offset-y!)
+ (offset-width config-offset-width set-config-offset-width!)
+ (offset-height config-offset-height set-config-offset-height!)
+ (focused-color config-focused-color set-config-focused-color!)
+ (unfocused-color config-unfocused-color set-config-unfocused-color!)
+ (unkillable-color config-unkillable-color set-config-unkillable-color)
+ (empty-color config-empty-color set-config-empty-color)
+ (outer-color config-outer-color set-config-outer-color))
+
+;; Misc. utility functions
(define (uint8-as-bool i)
(not (eq? 0 i)))
+;; Link to schewm shared lib
+(define libschewm (dynamic-link "libschewm"))
+
+;; Helper to easily define calls into schewm C code
(define (schewm-func return-type name args)
(pointer->procedure
return-type
@@ -35,19 +87,19 @@
(define wm-run
(schewm-func void "wm_run" '()))
-(define c/key-from-str
+(define c/keysym-from-str
(schewm-func uint32
"keysym_from_str"
(list '*)))
-(define (key-from-str s)
- (c/key-from-str (string->pointer s)))
+(define (string->key s)
+ (c/keysym-from-str (string->pointer s)))
(define (make-key key)
- (list #f (key-from-str key)))
+ (list #f (string->key key)))
(define (make-shift-key key)
- (list #t (key-from-str key)))
+ (list #t (string->key key)))
(define wm-grab-key-with-mod
(schewm-func void "wm_grab_key_with_mod"
@@ -88,3 +140,22 @@
handler
(list uint16 uint8))))
+;; XXX: Dummy
+(define (wm-focus-close) '())
+(define (wm-pack-left) '())
+(define (wm-pack-right) '())
+(define (wm-pack-top) '())
+(define (wm-pack-bottom) '())
+(define (wm-toggle-maximize) '())
+(define (wm-toggle-half-left) '())
+(define (wm-toggle-half-right) '())
+(define (wm-toggle-half-top) '())
+(define (wm-toggle-half-bottom) '())
+(define (wm-toggle-top-left) '())
+(define (wm-toggle-top-right) '())
+(define (wm-toggle-bottom-left) '())
+(define (wm-toggle-bottom-right) '())
+(define (wm-set-workspace) '())
+(define (wm-set-client-workspace) '())
+(define (wm-client-monitor-prev) '())
+(define (wm-client-monitor-next) '())