diff --git a/data/rc.xml b/data/rc.xml index def15e3..45030fc 100644 --- a/data/rc.xml +++ b/data/rc.xml @@ -27,6 +27,9 @@ grim "$(xdg-user-dir PICTURES)/$(date +'%Y-%m-%d-%H%M%S_grim_fs.png')" + + + diff --git a/data/waybox.sh b/data/waybox.sh index 9aa088a..cb87f34 100644 --- a/data/waybox.sh +++ b/data/waybox.sh @@ -80,12 +80,14 @@ then WB_RC_XML=$WB_SYS_CONF_DIR/rc.xml elif test -f $OB_USER_CONF_DIR/rc.xml; then + _ "WARNING: Using files from Openbox. These may not work correctly." WB_RC_XML=$OB_USER_CONF_DIR/rc.xml elif test -f $OB_SYS_CONF_DIR/rc.xml; then + _ "WARNING: Using files from Openbox. These may not work correctly." WB_RC_XML=$OB_SYS_CONF_DIR/rc.xml; else - _ "ERROR: No configuration file found." + _ "ERROR: No configuration file found." >&2 exit 1 fi export WB_RC_XML diff --git a/data/xdg-autostart b/data/xdg-autostart index 00cbfea..5c11397 100644 --- a/data/xdg-autostart +++ b/data/xdg-autostart @@ -28,7 +28,7 @@ do elif cat "$f" | grep -q "^Hidden\s*=\s*true$"; then show_in=0 - # Value of WAYBOX: run all programs + # Value of all: run all programs elif test "$WB_AUTOSTART_ENVIRONMENT" = "all"; then show_in=1 diff --git a/include/waybox/output.h b/include/waybox/output.h index 98251a1..c053b93 100644 --- a/include/waybox/output.h +++ b/include/waybox/output.h @@ -32,14 +32,16 @@ struct wb_view { struct wlr_xdg_toplevel_decoration_v1 *decoration; - struct wl_listener ack_configure; struct wl_listener map; struct wl_listener unmap; struct wl_listener destroy; + struct wl_listener request_maximize; struct wl_listener request_move; struct wl_listener request_resize; - bool configured, mapped; + struct wl_listener surface_commit; + bool mapped; int x, y; + struct wlr_box origdim; }; void output_frame_notify(struct wl_listener* listener, void *data); diff --git a/waybox/config.c b/waybox/config.c index 6151a0a..50142d8 100644 --- a/waybox/config.c +++ b/waybox/config.c @@ -72,9 +72,8 @@ static bool parse_key_bindings(struct wb_config *config, xmlXPathContextPtr ctxt modifiers |= WLR_MODIFIER_SHIFT; else if (strcmp(s, "W") == 0 || strcmp(s, "Logo") == 0) modifiers |= WLR_MODIFIER_LOGO; - else - key_bind->sym = xkb_keysym_from_name(s, 0); key_bind->modifiers = modifiers; + key_bind->sym = xkb_keysym_from_name(s, 0); sym = NULL; } @@ -100,6 +99,8 @@ static bool parse_key_bindings(struct wb_config *config, xmlXPathContextPtr ctxt key_bind->action = ACTION_PREVIOUS_WINDOW; else if (strcmp(action, "Close") == 0) key_bind->action = ACTION_CLOSE; + else if (strcmp(action, "ToggleMaximize") == 0) + key_bind->action = ACTION_TOGGLE_MAXIMIZE; 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 e90c8f9..d867814 100644 --- a/waybox/config.h +++ b/waybox/config.h @@ -10,7 +10,8 @@ enum action_type { ACTION_EXIT, ACTION_NEXT_WINDOW, ACTION_PREVIOUS_WINDOW, - ACTION_RECONFIGURE + ACTION_RECONFIGURE, + ACTION_TOGGLE_MAXIMIZE, }; struct wb_config { diff --git a/waybox/seat.c b/waybox/seat.c index 290cff1..44f491e 100644 --- a/waybox/seat.c +++ b/waybox/seat.c @@ -88,6 +88,13 @@ static bool handle_keybinding(struct wb_server *server, xkb_keysym_t sym, uint32 execl("/bin/sh", "/bin/sh", "-c", key_binding->cmd, (char *) NULL); } return true; + case ACTION_TOGGLE_MAXIMIZE: + { + struct wb_view *view = wl_container_of(server->views.next, view, link); + 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_RECONFIGURE: deinit_config(server->config); init_config(server); diff --git a/waybox/xdg_shell.c b/waybox/xdg_shell.c index 11f6c8d..f5b5f3f 100644 --- a/waybox/xdg_shell.c +++ b/waybox/xdg_shell.c @@ -49,39 +49,29 @@ void focus_view(struct wb_view *view, struct wlr_surface *surface) { keyboard->keycodes, keyboard->num_keycodes, &keyboard->modifiers); } -static void xdg_surface_ack_configure(struct wl_listener *listener, void *data) { - /* Called after the surface is configured */ - struct wb_view *view = wl_container_of(listener, view, ack_configure); - - /* If there's no decoration, there's no need to change the size and - * cause endless reconfigures. */ - if (!view->decoration) - return; - - if (!view->configured) - { - /* With client-side decorations, after setting the size, it'll - * return a negative y value, which can be used to determine the - * size of the CSD titlebar. */ - struct wlr_box geo_box; - wlr_xdg_surface_get_geometry(view->xdg_toplevel->base, &geo_box); - if (geo_box.y < 0) - view->y = geo_box.y * -1; - view->configured = view->y > 0; - - /* Set size here, so the view->y value will be known */ -#if WLR_CHECK_VERSION(0, 16, 0) - wlr_xdg_toplevel_set_size(view->xdg_toplevel, geo_box.width - view->x, geo_box.height - view->y); -#else - wlr_xdg_toplevel_set_size(view->xdg_surface, geo_box.width - view->x, geo_box.height - view->y); -#endif - } +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; + 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; } static void xdg_surface_map(struct wl_listener *listener, void *data) { /* Called when the surface is mapped, or ready to display on-screen. */ struct wb_view *view = wl_container_of(listener, view, map); view->mapped = true; + struct wlr_box geo_box = {0}; + wlr_xdg_surface_get_geometry(view->xdg_toplevel->base, &geo_box); +#if WLR_CHECK_VERSION(0, 16, 0) + wlr_xdg_toplevel_set_size(view->xdg_toplevel, geo_box.width, geo_box.height); +#else + wlr_xdg_toplevel_set_size(view->xdg_surface, geo_box.width, geo_box.height); +#endif focus_view(view, view->xdg_toplevel->base->surface); } @@ -115,6 +105,41 @@ static void xdg_surface_destroy(struct wl_listener *listener, void *data) { free(view); } +static void xdg_toplevel_request_maximize(struct wl_listener *listener, void *data) { + struct wlr_xdg_surface *surface = data; + 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); + 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->x = 0; + view->y = 0; + } else { + usable_area = view->origdim; + view->x = view->origdim.x; + view->y = view->origdim.y; + } +#if WLR_CHECK_VERSION(0, 16, 0) + wlr_xdg_toplevel_set_size(surface->toplevel, usable_area.width, usable_area.height); + wlr_xdg_toplevel_set_maximized(surface->toplevel, !is_maximized); +#else + wlr_xdg_toplevel_set_size(surface, usable_area.width, usable_area.height); + wlr_xdg_toplevel_set_maximized(surface, !is_maximized); +#endif +} + 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 @@ -185,12 +210,13 @@ static void handle_new_xdg_surface(struct wl_listener *listener, void *data) { view->server = server; view->xdg_toplevel = xdg_surface->toplevel; #if !WLR_CHECK_VERSION(0, 16, 0) - view->xdg_surface = view->xdg_toplevel->base; + view->xdg_surface = xdg_surface; #endif /* Listen to the various events it can emit */ - view->ack_configure.notify = xdg_surface_ack_configure; - wl_signal_add(&xdg_surface->events.ack_configure, &view->ack_configure); + view->surface_commit.notify = xdg_surface_commit; + wl_signal_add(&xdg_surface->surface->events.commit, &view->surface_commit); + view->map.notify = xdg_surface_map; wl_signal_add(&xdg_surface->events.map, &view->map); view->unmap.notify = xdg_surface_unmap; @@ -198,10 +224,13 @@ static void handle_new_xdg_surface(struct wl_listener *listener, void *data) { view->destroy.notify = xdg_surface_destroy; wl_signal_add(&xdg_surface->events.destroy, &view->destroy); + 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_move.notify = xdg_toplevel_request_move; - wl_signal_add(&view->xdg_toplevel->events.request_move, &view->request_move); + wl_signal_add(&toplevel->events.request_move, &view->request_move); view->request_resize.notify = xdg_toplevel_request_resize; - wl_signal_add(&view->xdg_toplevel->events.request_resize, &view->request_resize); + wl_signal_add(&toplevel->events.request_resize, &view->request_resize); /* Add it to the list of views. */ wl_list_insert(&server->views, &view->link);