X-Git-Url: https://code.delx.au/spectrwm/blobdiff_plain/f82969b59c414218f709b1d95a799fae6fc40f49..HEAD:/spectrwm.c diff --git a/spectrwm.c b/spectrwm.c index d67d875..285bac9 100644 --- a/spectrwm.c +++ b/spectrwm.c @@ -69,6 +69,7 @@ #include #include #include +#include #include #include #include @@ -824,6 +825,7 @@ enum actionid { FN_FOCUS_NEXT, FN_FOCUS_PREV, FN_FOCUS_URGENT, + FN_FULLSCREEN_TOGGLE, FN_MAXIMIZE_TOGGLE, FN_HEIGHT_GROW, FN_HEIGHT_SHRINK, @@ -1061,6 +1063,7 @@ void focusout(xcb_focus_out_event_t *); void focusrg(struct binding *, struct swm_region *, union arg *); void fontset_init(void); void free_window(struct ws_win *); +void fullscreen_toggle(struct binding *, struct swm_region *, union arg *); xcb_atom_t get_atom_from_string(const char *); #ifdef SWM_DEBUG char *get_atom_name(xcb_atom_t); @@ -3710,7 +3713,16 @@ spawn(int ws_idx, union arg *args, bool close_fd) close(xcb_get_file_descriptor(conn)); - setenv("LD_PRELOAD", SWM_LIB, 1); + if ((ret = getenv("LD_PRELOAD"))) { + if (asprintf(&ret, "%s:%s", SWM_LIB, ret) == -1) { + warn("spawn: asprintf LD_PRELOAD"); + _exit(1); + } + setenv("LD_PRELOAD", ret, 1); + free(ret); + } else { + setenv("LD_PRELOAD", SWM_LIB, 1); + } if (asprintf(&ret, "%d", ws_idx) == -1) { warn("spawn: asprintf SWM_WS"); @@ -4133,6 +4145,10 @@ set_region(struct swm_region *r) r->s->r_focus = r; + /* Update the focus window frame on the now unfocused region. */ + if (rf && rf->ws->focus) + draw_frame(rf->ws->focus); + ewmh_update_current_desktop(); } @@ -6552,6 +6568,32 @@ floating_toggle(struct binding *bp, struct swm_region *r, union arg *args) DNPRINTF(SWM_D_MISC, "floating_toggle: done\n"); } +void +fullscreen_toggle(struct binding *bp, struct swm_region *r, union arg *args) +{ + struct ws_win *w = r->ws->focus; + + /* suppress unused warning since var is needed */ + (void)bp; + (void)args; + + if (w == NULL) + return; + + DNPRINTF(SWM_D_MISC, "fullscreen_toggle: win %#x\n", w->id); + + ewmh_apply_flags(w, w->ewmh_flags ^ EWMH_F_FULLSCREEN); + ewmh_update_wm_state(w); + + stack(r); + + if (w == w->ws->focus) + focus_win(w); + + center_pointer(r); + focus_flush(); + DNPRINTF(SWM_D_MISC, "fullscreen_toggle: done\n"); +} void region_containment(struct ws_win *win, struct swm_region *r, int opts) { @@ -7338,6 +7380,7 @@ struct action { { "focus_next", focus, 0, {.id = SWM_ARG_ID_FOCUSNEXT} }, { "focus_prev", focus, 0, {.id = SWM_ARG_ID_FOCUSPREV} }, { "focus_urgent", focus, 0, {.id = SWM_ARG_ID_FOCUSURGENT} }, + { "fullscreen_toggle", fullscreen_toggle, 0, {0} }, { "maximize_toggle", maximize_toggle,0, {0} }, { "height_grow", resize, 0, {.id = SWM_ARG_ID_HEIGHTGROW} }, { "height_shrink", resize, 0, {.id = SWM_ARG_ID_HEIGHTSHRINK} }, @@ -8124,6 +8167,7 @@ setup_keybindings(void) BINDKEY(MODKEY, XK_k, FN_FOCUS_PREV); BINDKEY(MODSHIFT, XK_Tab, FN_FOCUS_PREV); BINDKEY(MODKEY, XK_u, FN_FOCUS_URGENT); + BINDKEY(MODSHIFT, XK_e, FN_FULLSCREEN_TOGGLE); BINDKEY(MODKEY, XK_e, FN_MAXIMIZE_TOGGLE); BINDKEY(MODSHIFT, XK_equal, FN_HEIGHT_GROW); BINDKEY(MODSHIFT, XK_minus, FN_HEIGHT_SHRINK); @@ -11053,7 +11097,7 @@ reparentnotify(xcb_reparent_notify_event_t *e) if (win->state == SWM_WIN_STATE_REPARENTING) { win->state = SWM_WIN_STATE_REPARENTED; - if (win->ws->r) + if (win->ws->r && !ICONIC(win)) map_window(win); else unmap_window(win); @@ -11479,7 +11523,6 @@ scan_randr(int idx) int ncrtc = 0; #endif /* SWM_XRR_HAS_CRTC */ struct swm_region *r; - struct ws_win *win; int num_screens; xcb_randr_get_screen_resources_current_cookie_t src; xcb_randr_get_screen_resources_current_reply_t *srr; @@ -11554,13 +11597,8 @@ scan_randr(int idx) screen->height_in_pixels); out: - /* Cleanup unused previously visible workspaces. */ + /* The screen shouldn't focus on unused regions. */ TAILQ_FOREACH(r, &screens[idx].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[idx].r_focus == r) screens[idx].r_focus = NULL; } @@ -11572,7 +11610,9 @@ void screenchange(xcb_randr_screen_change_notify_event_t *e) { struct swm_region *r; - int i, num_screens; + struct workspace *ws; + struct ws_win *win; + int i, j, num_screens; DNPRINTF(SWM_D_EVENT, "screenchange: root: %#x\n", e->root); @@ -11605,6 +11645,16 @@ screenchange(xcb_randr_screen_change_notify_event_t *e) focus_region(r); } + /* Cleanup unused previously visible workspaces. */ + for (j = 0; j < workspace_limit; j++) { + ws = &screens[i].ws[j]; + if (ws->r == NULL && ws->state != SWM_WS_STATE_HIDDEN) { + TAILQ_FOREACH(win, &ws->winlist, entry) + unmap_window(win); + ws->state = SWM_WS_STATE_HIDDEN; + } + } + focus_flush(); /* Update workspace state and bar on all regions. */