Extend minimize logic to work with XWayland and XDG applications (#132)
* Extend minimize logic * Removed redundant xwayland minimize logic * minor fixes * Fixed not properly checking if window is ran though XWayland * Added config option with default being off * Set scratchpad_minimize to true by default * Improve config dependant logic * Switch to using enable|disable instead of on|off
This commit is contained in:
parent
7d5d7a3022
commit
f2d29ceb6b
|
@ -26,6 +26,7 @@ Sway is an incredible window manager, and certainly one of the most well establi
|
||||||
- `dim_inactive_colors.urgent <hex color> ex, #900000FF`
|
- `dim_inactive_colors.urgent <hex color> ex, #900000FF`
|
||||||
+ Application saturation: `for_window [CRITERIA HERE] saturation <set|plus|minus> <val 0.0 <-> 2.0>`
|
+ Application saturation: `for_window [CRITERIA HERE] saturation <set|plus|minus> <val 0.0 <-> 2.0>`
|
||||||
+ Keep/remove separator border between titlebar and content: `titlebar_separator enable|disable`
|
+ Keep/remove separator border between titlebar and content: `titlebar_separator enable|disable`
|
||||||
|
+ Treat Scratchpad as minimized: `scratchpad_minimize enable|disable`
|
||||||
|
|
||||||
## Roadmap
|
## Roadmap
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,9 @@ dim_inactive 0.0
|
||||||
dim_inactive_colors.unfocused #000000FF
|
dim_inactive_colors.unfocused #000000FF
|
||||||
dim_inactive_colors.urgent #900000FF
|
dim_inactive_colors.urgent #900000FF
|
||||||
|
|
||||||
|
# Move minimized windows into Scratchpad (enable|disable)
|
||||||
|
scratchpad_minimize enable
|
||||||
|
|
||||||
### Output configuration
|
### Output configuration
|
||||||
#
|
#
|
||||||
# Default wallpaper (more resolutions are available in @datadir@/backgrounds/sway/)
|
# Default wallpaper (more resolutions are available in @datadir@/backgrounds/sway/)
|
||||||
|
|
|
@ -176,6 +176,7 @@ sway_cmd cmd_reload;
|
||||||
sway_cmd cmd_rename;
|
sway_cmd cmd_rename;
|
||||||
sway_cmd cmd_resize;
|
sway_cmd cmd_resize;
|
||||||
sway_cmd cmd_scratchpad;
|
sway_cmd cmd_scratchpad;
|
||||||
|
sway_cmd cmd_scratchpad_minimize;
|
||||||
sway_cmd cmd_seamless_mouse;
|
sway_cmd cmd_seamless_mouse;
|
||||||
sway_cmd cmd_set;
|
sway_cmd cmd_set;
|
||||||
sway_cmd cmd_shortcuts_inhibitor;
|
sway_cmd cmd_shortcuts_inhibitor;
|
||||||
|
|
|
@ -488,6 +488,7 @@ struct sway_config {
|
||||||
int shadow_blur_sigma;
|
int shadow_blur_sigma;
|
||||||
float shadow_color[4];
|
float shadow_color[4];
|
||||||
bool titlebar_separator;
|
bool titlebar_separator;
|
||||||
|
bool scratchpad_minimize;
|
||||||
|
|
||||||
char *swaynag_command;
|
char *swaynag_command;
|
||||||
struct swaynag_instance swaynag_config_errors;
|
struct swaynag_instance swaynag_config_errors;
|
||||||
|
|
|
@ -134,6 +134,7 @@ struct sway_xdg_shell_view {
|
||||||
struct wl_listener request_move;
|
struct wl_listener request_move;
|
||||||
struct wl_listener request_resize;
|
struct wl_listener request_resize;
|
||||||
struct wl_listener request_maximize;
|
struct wl_listener request_maximize;
|
||||||
|
struct wl_listener request_minimize;
|
||||||
struct wl_listener request_fullscreen;
|
struct wl_listener request_fullscreen;
|
||||||
struct wl_listener set_title;
|
struct wl_listener set_title;
|
||||||
struct wl_listener set_app_id;
|
struct wl_listener set_app_id;
|
||||||
|
|
|
@ -115,6 +115,7 @@ static const struct cmd_handler handlers[] = {
|
||||||
static const struct cmd_handler config_handlers[] = {
|
static const struct cmd_handler config_handlers[] = {
|
||||||
{ "default_orientation", cmd_default_orientation },
|
{ "default_orientation", cmd_default_orientation },
|
||||||
{ "include", cmd_include },
|
{ "include", cmd_include },
|
||||||
|
{ "scratchpad_minimize", cmd_scratchpad_minimize },
|
||||||
{ "swaybg_command", cmd_swaybg_command },
|
{ "swaybg_command", cmd_swaybg_command },
|
||||||
{ "swaynag_command", cmd_swaynag_command },
|
{ "swaynag_command", cmd_swaynag_command },
|
||||||
{ "workspace_layout", cmd_workspace_layout },
|
{ "workspace_layout", cmd_workspace_layout },
|
||||||
|
|
18
sway/commands/scratchpad_minimize.c
Normal file
18
sway/commands/scratchpad_minimize.c
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#include <string.h>
|
||||||
|
#include "sway/commands.h"
|
||||||
|
#include "sway/config.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "stringop.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
struct cmd_results *cmd_scratchpad_minimize(int argc, char **argv) {
|
||||||
|
struct cmd_results *error = checkarg(argc, "scratchpad_minimize", EXPECTED_AT_LEAST, 1);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
config->scratchpad_minimize = parse_boolean(argv[0], config->scratchpad_minimize);
|
||||||
|
|
||||||
|
return cmd_results_new(CMD_SUCCESS, NULL);
|
||||||
|
}
|
|
@ -344,6 +344,7 @@ static void config_defaults(struct sway_config *config) {
|
||||||
config->shadow_blur_sigma = 20.0f;
|
config->shadow_blur_sigma = 20.0f;
|
||||||
color_to_rgba(config->shadow_color, 0x0000007F);
|
color_to_rgba(config->shadow_color, 0x0000007F);
|
||||||
config->titlebar_separator = true;
|
config->titlebar_separator = true;
|
||||||
|
config->scratchpad_minimize = true;
|
||||||
|
|
||||||
// The keysym to keycode translation
|
// The keysym to keycode translation
|
||||||
struct xkb_rule_names rules = {0};
|
struct xkb_rule_names rules = {0};
|
||||||
|
|
|
@ -332,6 +332,24 @@ static void handle_request_maximize(struct wl_listener *listener, void *data) {
|
||||||
wlr_xdg_surface_schedule_configure(toplevel->base);
|
wlr_xdg_surface_schedule_configure(toplevel->base);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Minimize to scratchpad */
|
||||||
|
static void handle_request_minimize(struct wl_listener *listener, void *data) {
|
||||||
|
struct sway_xdg_shell_view *xdg_shell_view =
|
||||||
|
wl_container_of(listener, xdg_shell_view, request_minimize);
|
||||||
|
struct sway_container *container = xdg_shell_view->view.container;
|
||||||
|
if (!container->pending.workspace) {
|
||||||
|
while (container->pending.parent) {
|
||||||
|
container = container->pending.parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!container->scratchpad) {
|
||||||
|
root_scratchpad_add_container(container, NULL);
|
||||||
|
} else if (container->pending.workspace) {
|
||||||
|
root_scratchpad_hide(container);
|
||||||
|
}
|
||||||
|
transaction_commit_dirty();
|
||||||
|
}
|
||||||
|
|
||||||
static void handle_request_fullscreen(struct wl_listener *listener, void *data) {
|
static void handle_request_fullscreen(struct wl_listener *listener, void *data) {
|
||||||
struct sway_xdg_shell_view *xdg_shell_view =
|
struct sway_xdg_shell_view *xdg_shell_view =
|
||||||
wl_container_of(listener, xdg_shell_view, request_fullscreen);
|
wl_container_of(listener, xdg_shell_view, request_fullscreen);
|
||||||
|
@ -406,6 +424,9 @@ static void handle_unmap(struct wl_listener *listener, void *data) {
|
||||||
wl_list_remove(&xdg_shell_view->commit.link);
|
wl_list_remove(&xdg_shell_view->commit.link);
|
||||||
wl_list_remove(&xdg_shell_view->new_popup.link);
|
wl_list_remove(&xdg_shell_view->new_popup.link);
|
||||||
wl_list_remove(&xdg_shell_view->request_maximize.link);
|
wl_list_remove(&xdg_shell_view->request_maximize.link);
|
||||||
|
if (xdg_shell_view->request_minimize.notify) {
|
||||||
|
wl_list_remove(&xdg_shell_view->request_minimize.link);
|
||||||
|
}
|
||||||
wl_list_remove(&xdg_shell_view->request_fullscreen.link);
|
wl_list_remove(&xdg_shell_view->request_fullscreen.link);
|
||||||
wl_list_remove(&xdg_shell_view->request_move.link);
|
wl_list_remove(&xdg_shell_view->request_move.link);
|
||||||
wl_list_remove(&xdg_shell_view->request_resize.link);
|
wl_list_remove(&xdg_shell_view->request_resize.link);
|
||||||
|
@ -458,6 +479,12 @@ static void handle_map(struct wl_listener *listener, void *data) {
|
||||||
wl_signal_add(&toplevel->events.request_maximize,
|
wl_signal_add(&toplevel->events.request_maximize,
|
||||||
&xdg_shell_view->request_maximize);
|
&xdg_shell_view->request_maximize);
|
||||||
|
|
||||||
|
if (config->scratchpad_minimize) {
|
||||||
|
xdg_shell_view->request_minimize.notify = handle_request_minimize;
|
||||||
|
wl_signal_add(&toplevel->events.request_minimize,
|
||||||
|
&xdg_shell_view->request_minimize);
|
||||||
|
}
|
||||||
|
|
||||||
xdg_shell_view->request_fullscreen.notify = handle_request_fullscreen;
|
xdg_shell_view->request_fullscreen.notify = handle_request_fullscreen;
|
||||||
wl_signal_add(&toplevel->events.request_fullscreen,
|
wl_signal_add(&toplevel->events.request_fullscreen,
|
||||||
&xdg_shell_view->request_fullscreen);
|
&xdg_shell_view->request_fullscreen);
|
||||||
|
|
|
@ -575,6 +575,7 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data)
|
||||||
transaction_commit_dirty();
|
transaction_commit_dirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Minimize to scratchpad */
|
||||||
static void handle_request_minimize(struct wl_listener *listener, void *data) {
|
static void handle_request_minimize(struct wl_listener *listener, void *data) {
|
||||||
struct sway_xwayland_view *xwayland_view =
|
struct sway_xwayland_view *xwayland_view =
|
||||||
wl_container_of(listener, xwayland_view, request_minimize);
|
wl_container_of(listener, xwayland_view, request_minimize);
|
||||||
|
@ -585,6 +586,27 @@ static void handle_request_minimize(struct wl_listener *listener, void *data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_xwayland_minimize_event *e = data;
|
struct wlr_xwayland_minimize_event *e = data;
|
||||||
|
if (config->scratchpad_minimize) {
|
||||||
|
struct sway_container *container = view->container;
|
||||||
|
if (!container->pending.workspace) {
|
||||||
|
while (container->pending.parent) {
|
||||||
|
container = container->pending.parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(e->minimize) {
|
||||||
|
if (!container->scratchpad) {
|
||||||
|
root_scratchpad_add_container(container, NULL);
|
||||||
|
} else if (container->pending.workspace) {
|
||||||
|
root_scratchpad_hide(container);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(container->scratchpad) {
|
||||||
|
root_scratchpad_show(container);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
transaction_commit_dirty();
|
||||||
|
return;
|
||||||
|
}
|
||||||
struct sway_seat *seat = input_manager_current_seat();
|
struct sway_seat *seat = input_manager_current_seat();
|
||||||
bool focused = seat_get_focus(seat) == &view->container->node;
|
bool focused = seat_get_focus(seat) == &view->container->node;
|
||||||
wlr_xwayland_surface_set_minimized(xsurface, !focused && e->minimize);
|
wlr_xwayland_surface_set_minimized(xsurface, !focused && e->minimize);
|
||||||
|
|
|
@ -98,6 +98,7 @@ sway_sources = files(
|
||||||
'commands/resize.c',
|
'commands/resize.c',
|
||||||
'commands/saturation.c',
|
'commands/saturation.c',
|
||||||
'commands/scratchpad.c',
|
'commands/scratchpad.c',
|
||||||
|
'commands/scratchpad_minimize.c',
|
||||||
'commands/seat.c',
|
'commands/seat.c',
|
||||||
'commands/seat/attach.c',
|
'commands/seat/attach.c',
|
||||||
'commands/seat/cursor.c',
|
'commands/seat/cursor.c',
|
||||||
|
|
|
@ -71,6 +71,10 @@ The following commands may only be used in the configuration file.
|
||||||
*wordexp*(3) for details). The same include file can only be included once;
|
*wordexp*(3) for details). The same include file can only be included once;
|
||||||
subsequent attempts will be ignored.
|
subsequent attempts will be ignored.
|
||||||
|
|
||||||
|
*scratchpad_minimize* <value>
|
||||||
|
Adjusts if minimized windows should be moved into the scratchpad
|
||||||
|
(enable|disable). Must be set at config-time (when starting sway).
|
||||||
|
|
||||||
*swaybg_command* <command>
|
*swaybg_command* <command>
|
||||||
Executes custom background _command_. Default is _swaybg_. Refer to
|
Executes custom background _command_. Default is _swaybg_. Refer to
|
||||||
*sway-output*(5) for more information.
|
*sway-output*(5) for more information.
|
||||||
|
|
|
@ -55,6 +55,17 @@ void root_destroy(struct sway_root *root) {
|
||||||
free(root);
|
free(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set minimized state from scratchpad container `show` state */
|
||||||
|
static void root_scratchpad_set_minimize(struct sway_container *con, bool minimize) {
|
||||||
|
struct wlr_foreign_toplevel_handle_v1 *foreign_toplevel = con->view->foreign_toplevel;
|
||||||
|
if (wlr_surface_is_xwayland_surface(con->view->surface)) {
|
||||||
|
struct wlr_xwayland_surface *xsurface = wlr_xwayland_surface_from_wlr_surface(con->view->surface);
|
||||||
|
wlr_xwayland_surface_set_minimized(xsurface, minimize);
|
||||||
|
} else if (foreign_toplevel) {
|
||||||
|
wlr_foreign_toplevel_handle_v1_set_minimized(foreign_toplevel, minimize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void root_scratchpad_add_container(struct sway_container *con, struct sway_workspace *ws) {
|
void root_scratchpad_add_container(struct sway_container *con, struct sway_workspace *ws) {
|
||||||
if (!sway_assert(!con->scratchpad, "Container is already in scratchpad")) {
|
if (!sway_assert(!con->scratchpad, "Container is already in scratchpad")) {
|
||||||
return;
|
return;
|
||||||
|
@ -96,6 +107,11 @@ void root_scratchpad_add_container(struct sway_container *con, struct sway_works
|
||||||
seat_set_focus(seat, new_focus);
|
seat_set_focus(seat, new_focus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set minimize state to minimized
|
||||||
|
if (config->scratchpad_minimize) {
|
||||||
|
root_scratchpad_set_minimize(con, true);
|
||||||
|
}
|
||||||
|
|
||||||
ipc_event_window(con, "move");
|
ipc_event_window(con, "move");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,6 +157,11 @@ void root_scratchpad_show(struct sway_container *con) {
|
||||||
}
|
}
|
||||||
workspace_add_floating(new_ws, con);
|
workspace_add_floating(new_ws, con);
|
||||||
|
|
||||||
|
// Set minimize state to normalized
|
||||||
|
if (config->scratchpad_minimize) {
|
||||||
|
root_scratchpad_set_minimize(con, false);
|
||||||
|
}
|
||||||
|
|
||||||
// Make sure the container's center point overlaps this workspace
|
// Make sure the container's center point overlaps this workspace
|
||||||
double center_lx = con->pending.x + con->pending.width / 2;
|
double center_lx = con->pending.x + con->pending.width / 2;
|
||||||
double center_ly = con->pending.y + con->pending.height / 2;
|
double center_ly = con->pending.y + con->pending.height / 2;
|
||||||
|
@ -172,6 +193,11 @@ void root_scratchpad_hide(struct sway_container *con) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set minimize state to minimized
|
||||||
|
if (config->scratchpad_minimize) {
|
||||||
|
root_scratchpad_set_minimize(con, true);
|
||||||
|
}
|
||||||
|
|
||||||
disable_fullscreen(con, NULL);
|
disable_fullscreen(con, NULL);
|
||||||
container_for_each_child(con, disable_fullscreen, NULL);
|
container_for_each_child(con, disable_fullscreen, NULL);
|
||||||
container_detach(con);
|
container_detach(con);
|
||||||
|
|
|
@ -746,6 +746,9 @@ static void handle_foreign_destroy(
|
||||||
listener, view, foreign_destroy);
|
listener, view, foreign_destroy);
|
||||||
|
|
||||||
wl_list_remove(&view->foreign_activate_request.link);
|
wl_list_remove(&view->foreign_activate_request.link);
|
||||||
|
if (view->foreign_minimize.notify) {
|
||||||
|
wl_list_remove(&view->foreign_minimize.link);
|
||||||
|
}
|
||||||
wl_list_remove(&view->foreign_fullscreen_request.link);
|
wl_list_remove(&view->foreign_fullscreen_request.link);
|
||||||
wl_list_remove(&view->foreign_close_request.link);
|
wl_list_remove(&view->foreign_close_request.link);
|
||||||
wl_list_remove(&view->foreign_destroy.link);
|
wl_list_remove(&view->foreign_destroy.link);
|
||||||
|
@ -819,9 +822,11 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface,
|
||||||
view->foreign_destroy.notify = handle_foreign_destroy;
|
view->foreign_destroy.notify = handle_foreign_destroy;
|
||||||
wl_signal_add(&view->foreign_toplevel->events.destroy,
|
wl_signal_add(&view->foreign_toplevel->events.destroy,
|
||||||
&view->foreign_destroy);
|
&view->foreign_destroy);
|
||||||
view->foreign_minimize.notify = handle_foreign_minimize;
|
if (config->scratchpad_minimize) {
|
||||||
wl_signal_add(&view->foreign_toplevel->events.request_minimize,
|
view->foreign_minimize.notify = handle_foreign_minimize;
|
||||||
&view->foreign_minimize);
|
wl_signal_add(&view->foreign_toplevel->events.request_minimize,
|
||||||
|
&view->foreign_minimize);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct sway_container *container = view->container;
|
struct sway_container *container = view->container;
|
||||||
|
|
Loading…
Reference in a new issue