diff options
-rw-r--r-- | main.scm | 78 | ||||
-rw-r--r-- | schewm.c | 67 | ||||
-rw-r--r-- | wm.scm | 85 |
3 files changed, 198 insertions, 32 deletions
@@ -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)) - @@ -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); @@ -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) '()) |