From 0769addabd59debf48a8f0a61dee42ae7d24be77 Mon Sep 17 00:00:00 2001 From: Keith Bowes Date: Thu, 24 Feb 2022 11:00:25 -0500 Subject: [PATCH] Ability to minimize; Iconify action --- data/autostart | 11 +++++--- data/environment | 2 +- data/meson.build | 2 +- data/rc.xml | 29 ++++++++++++--------- include/waybox/output.h | 7 +++-- waybox/config.c | 2 ++ waybox/config.h | 1 + waybox/seat.c | 28 +++++++++++++++++--- waybox/xdg_shell.c | 58 +++++++++++++++++++++++++++++------------ 9 files changed, 100 insertions(+), 40 deletions(-) diff --git a/data/autostart b/data/autostart index 29548d7..242f5be 100644 --- a/data/autostart +++ b/data/autostart @@ -19,13 +19,18 @@ cairo-dock & # Start a panel (waybar || yambar) & +# Start a notification daemon +mako & + # Load a random wallpaper oldifs=$IFS IFS=: -for wpdir in ${XDG_DATA_DIRS:-${datadir:-/usr/share}}:${XDG_DATA_HOME:-~/.local/share}; +data_dirs=${XDG_DATA_DIRS:-${datadir:-/usr/share}}:${XDG_DATA_HOME:-~/.local/share} +for data_dir in $data_dirs; do - find $wpdir -path '*/backgrounds/*.jpg' -o -path '*/backgrounds/*.png' -o -path '*/backgrounds/*.svg' \ - -o -path '*/wallpapers/*.jpg' -o -path '*/wallpapers/*.png' -o -path '*/wallpapers/*.svg'; + wpdir="$data_dir/wallpapers" + test -d "$wpdir" && \ + find $wpdir -name '*.jpg' -o -name '*.png' -o -name '*.svg' done | (shuf -n 1 || tail -n 1) | xargs swaybg -m fill -i & IFS=$oldifs diff --git a/data/environment b/data/environment index a484c76..eb26fe2 100644 --- a/data/environment +++ b/data/environment @@ -1,5 +1,5 @@ # -# Environment variables here for Waybox +# Set environment variables here for Waybox # Copy to $XDG_CONFIG_HOME/waybox/environment to customize # diff --git a/data/meson.build b/data/meson.build index a82ec0a..7f6f74a 100644 --- a/data/meson.build +++ b/data/meson.build @@ -2,7 +2,7 @@ cfdata = configuration_data() cfdata.set('libexecdir', get_option('prefix') / get_option('libexecdir')) cfdata.set('localedir', get_option('prefix') / get_option('localedir')) cfdata.set('sysconfdir', get_option('prefix') / get_option('sysconfdir')) -cfdata.set('package', meson.project_name()) +cfdata.set('package', meson.project_name().to_lower()) configure_file( configuration: cfdata, diff --git a/data/rc.xml b/data/rc.xml index 45030fc..0cdd69b 100644 --- a/data/rc.xml +++ b/data/rc.xml @@ -10,11 +10,6 @@ evdev dvorak --> - - - terminal - - @@ -22,10 +17,11 @@ - - - grim "$(xdg-user-dir PICTURES)/$(date +'%Y-%m-%d-%H%M%S_grim_fs.png')" - + + + + + @@ -44,14 +40,21 @@ + + + $TERMINAL + + + + + grim "$(xdg-user-dir PICTURES)/$(date +'%Y-%m-%d-%H%M%S_grim_fs.png')" + + obrun l - - - konqueror || falkon @@ -59,7 +62,7 @@ - terminal -e mc + $TERMINAL -e mc diff --git a/include/waybox/output.h b/include/waybox/output.h index 5fd3033..ec4afda 100644 --- a/include/waybox/output.h +++ b/include/waybox/output.h @@ -31,18 +31,21 @@ struct wb_view { #endif struct wlr_xdg_toplevel_decoration_v1 *decoration; + int decoration_height; struct wl_listener map; struct wl_listener unmap; struct wl_listener destroy; struct wl_listener new_popup; struct wl_listener request_maximize; + struct wl_listener request_minimize; struct wl_listener request_move; struct wl_listener request_resize; struct wl_listener surface_commit; bool mapped; - int x, y; - struct wlr_box origdim; + + int width, height, x, y; + struct wlr_box previous_position; }; void output_frame_notify(struct wl_listener* listener, void *data); diff --git a/waybox/config.c b/waybox/config.c index 50142d8..0afdfe3 100644 --- a/waybox/config.c +++ b/waybox/config.c @@ -101,6 +101,8 @@ static bool parse_key_bindings(struct wb_config *config, xmlXPathContextPtr ctxt key_bind->action = ACTION_CLOSE; else if (strcmp(action, "ToggleMaximize") == 0) key_bind->action = ACTION_TOGGLE_MAXIMIZE; + else if (strcmp(action, "Iconify") == 0) + key_bind->action = ACTION_ICONIFY; else if (strcmp(action, "Exit") == 0) key_bind->action = ACTION_EXIT; else if (strcmp(action, "Reconfigure") == 0) diff --git a/waybox/config.h b/waybox/config.h index d867814..83d7779 100644 --- a/waybox/config.h +++ b/waybox/config.h @@ -8,6 +8,7 @@ enum action_type { ACTION_CLOSE, ACTION_EXECUTE, ACTION_EXIT, + ACTION_ICONIFY, ACTION_NEXT_WINDOW, ACTION_PREVIOUS_WINDOW, ACTION_RECONFIGURE, diff --git a/waybox/seat.c b/waybox/seat.c index 44f491e..a02a33a 100644 --- a/waybox/seat.c +++ b/waybox/seat.c @@ -3,15 +3,22 @@ #include "waybox/seat.h" #include "waybox/xdg_shell.h" +static void deiconify_view(struct wb_view *view) { + + if (view->xdg_toplevel->requested.minimized) { + view->xdg_toplevel->requested.minimized = false; + wl_signal_emit(&view->xdg_toplevel->events.request_minimize, view->xdg_toplevel->base); + } +} + static bool cycle_views(struct wb_server *server) { /* Cycle to the next view */ - if (wl_list_length(&server->views) < 2) { + if (wl_list_length(&server->views) < 1) { return false; } struct wb_view *current_view = wl_container_of( server->views.prev, current_view, link); - struct wb_view *prev_view = wl_container_of( - server->views.next, prev_view, link); + deiconify_view(current_view); focus_view(current_view, current_view->xdg_toplevel->base->surface); /* Move the current view to the beginning of the list */ wl_list_remove(¤t_view->link); @@ -21,13 +28,14 @@ static bool cycle_views(struct wb_server *server) { static bool cycle_views_reverse(struct wb_server *server) { /* Cycle to the previous view */ - if (wl_list_length(&server->views) < 2) { + if (wl_list_length(&server->views) < 1) { return false; } struct wb_view *current_view = wl_container_of( server->views.next, current_view, link); struct wb_view *next_view = wl_container_of( current_view->link.next, next_view, link); + deiconify_view(next_view); focus_view(next_view, next_view->xdg_toplevel->base->surface); /* Move the current view to after the previous view in the list */ wl_list_remove(¤t_view->link); @@ -94,6 +102,18 @@ static bool handle_keybinding(struct wb_server *server, xkb_keysym_t sym, uint32 if (wlr_surface_is_xdg_surface(view->xdg_toplevel->base->surface)) wl_signal_emit(&view->xdg_toplevel->events.request_maximize, view->xdg_toplevel->base); return true; + case ACTION_ICONIFY: + { + struct wb_view *view = wl_container_of(server->views.next, view, link); + if (wlr_surface_is_xdg_surface(view->xdg_toplevel->base->surface)) + { + view->xdg_toplevel->requested.minimized = true; + wl_signal_emit(&view->xdg_toplevel->events.request_minimize, view->xdg_toplevel->base); + struct wb_view *previous_view = wl_container_of(server->views.prev, previous_view, link); + focus_view(previous_view, previous_view->xdg_toplevel->base->surface); + } + return true; + } } case ACTION_RECONFIGURE: deinit_config(server->config); diff --git a/waybox/xdg_shell.c b/waybox/xdg_shell.c index 84f9b31..d10395e 100644 --- a/waybox/xdg_shell.c +++ b/waybox/xdg_shell.c @@ -53,15 +53,18 @@ static void xdg_surface_commit(struct wl_listener *listener, void *data) { /* Called after the surface is committed */ struct wb_view *view = wl_container_of(listener, view, surface_commit); struct wlr_xdg_surface *xdg_surface = view->xdg_toplevel->base; - if (xdg_surface->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL) + if (xdg_surface->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL || + xdg_surface->toplevel->requested.minimized) return; struct wlr_box geo_box = {0}; wlr_xdg_surface_get_geometry(xdg_surface, &geo_box); if (geo_box.x < 0 && view->x < 1) view->x += -geo_box.x; - if (geo_box.y < 0 && view->y < 1) - view->y += -geo_box.y; + if (geo_box.y < 0 && view->y < 1) { + view->decoration_height = -geo_box.y; + view->y += view->decoration_height; + } } static void xdg_surface_map(struct wl_listener *listener, void *data) { @@ -73,6 +76,10 @@ static void xdg_surface_map(struct wl_listener *listener, void *data) { struct wlr_box geo_box = {0}; wlr_xdg_surface_get_geometry(view->xdg_toplevel->base, &geo_box); + view->height = geo_box.height; + view->width = geo_box.width; + view->x = geo_box.x; + view->y = geo_box.y; #if WLR_CHECK_VERSION(0, 16, 0) wlr_xdg_toplevel_set_size(view->xdg_toplevel, geo_box.width, geo_box.height); #else @@ -119,26 +126,24 @@ static void xdg_toplevel_request_maximize(struct wl_listener *listener, void *da struct wb_view *view = wl_container_of(listener, view, request_maximize); double closest_x, closest_y; - struct wlr_box geo_box; struct wlr_output *output = NULL; - wlr_xdg_surface_get_geometry(surface, &geo_box); - wlr_output_layout_closest_point(view->server->output_layout, output, view->x + geo_box.width / 2, view->y + geo_box.height / 2, &closest_x, &closest_y); + wlr_output_layout_closest_point(view->server->output_layout, output, view->x + view->width / 2, view->y + view->height / 2, &closest_x, &closest_y); output = wlr_output_layout_output_at(view->server->output_layout, closest_x, closest_y); bool is_maximized = surface->toplevel->current.maximized; struct wlr_box usable_area = {0}; if (!is_maximized) { wlr_output_effective_resolution(output, &usable_area.width, &usable_area.height); - view->origdim.height = geo_box.height; - view->origdim.width = geo_box.width; - view->origdim.x = view->x; - view->origdim.y = view->y; + view->previous_position.height = view->height; + view->previous_position.width = view->width; + view->previous_position.x = view->x; + view->previous_position.y = view->y; view->x = 0; - view->y = 0; + view->y = 0 + view->decoration_height; } else { - usable_area = view->origdim; - view->x = view->origdim.x; - view->y = view->origdim.y; + usable_area = view->previous_position; + view->x = view->previous_position.x; + view->y = view->previous_position.y; } #if WLR_CHECK_VERSION(0, 16, 0) wlr_xdg_toplevel_set_size(surface->toplevel, usable_area.width, usable_area.height); @@ -149,6 +154,24 @@ static void xdg_toplevel_request_maximize(struct wl_listener *listener, void *da #endif } +static void xdg_toplevel_request_minimize(struct wl_listener *listener, void *data) { + struct wlr_xdg_surface *surface = data; + struct wb_view *view = wl_container_of(listener, view, request_minimize); + bool minimize_requested = surface->toplevel->requested.minimized; + if (minimize_requested) { + view->previous_position.height = view->height; + view->previous_position.width = view->width; + view->previous_position.x = view->x; + view->previous_position.y = view->y; + view->y = 0 - view->decoration_height * 2 - view->height; + } else { + view->height = view->previous_position.height; + view->width = view->previous_position.width; + view->x = view->previous_position.x; + view->y = view->previous_position.y; + } +} + static void begin_interactive(struct wb_view *view, enum wb_cursor_mode mode, uint32_t edges) { /* This function sets up an interactive move or resize operation, where the @@ -261,6 +284,8 @@ static void handle_new_xdg_surface(struct wl_listener *listener, void *data) { struct wlr_xdg_toplevel *toplevel = view->xdg_toplevel; view->request_maximize.notify = xdg_toplevel_request_maximize; wl_signal_add(&toplevel->events.request_maximize, &view->request_maximize); + view->request_minimize.notify = xdg_toplevel_request_minimize; + wl_signal_add(&toplevel->events.request_minimize, &view->request_minimize); view->request_move.notify = xdg_toplevel_request_move; wl_signal_add(&toplevel->events.request_move, &view->request_move); view->request_resize.notify = xdg_toplevel_request_resize; @@ -281,13 +306,14 @@ bool view_at(struct wb_view *view, * surface pointer to that wlr_surface and the sx and sy coordinates to the * coordinates relative to that surface's top-left corner. */ + if (view->xdg_toplevel->base->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL) + return false; + double view_sx = lx - view->x; double view_sy = ly - view->y; double _sx, _sy; struct wlr_surface *_surface = NULL; - if (view->xdg_toplevel->base->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL) - return false; _surface = wlr_xdg_surface_surface_at( view->xdg_toplevel->base, view_sx, view_sy, &_sx, &_sy);