diff --git a/data/rc.xml b/data/rc.xml index ca67617..af37c1a 100644 --- a/data/rc.xml +++ b/data/rc.xml @@ -1,5 +1,7 @@ + 0 0 diff --git a/include/waybox/server.h b/include/waybox/server.h index d8cb6c4..5fb7c5b 100644 --- a/include/waybox/server.h +++ b/include/waybox/server.h @@ -3,6 +3,8 @@ #include +#define MAX(a, b) ((a > b) ? (a) : (b)) +#define MIN(a, b) ((a < b) ? (a) : (b)) #include #define WLR_CHECK_VERSION(major, minor, micro) (WLR_VERSION_NUM >= ((major << 16) | (minor << 8) | (micro))) diff --git a/meson.build b/meson.build index 1420582..e33fb75 100644 --- a/meson.build +++ b/meson.build @@ -1,7 +1,7 @@ project( 'Waybox', 'c', - version: '0.1.0', + version: '0.2.0', license: 'MIT', meson_version: '>=0.52.0', default_options: [ diff --git a/waybox/main.c b/waybox/main.c index 3c1c34a..ae34ead 100644 --- a/waybox/main.c +++ b/waybox/main.c @@ -24,8 +24,7 @@ bool show_help(char *name) struct wb_server server = {0}; void signal_handler(int sig) { - switch (sig) - { + switch (sig) { case SIGINT: case SIGTERM: wl_display_terminate(server.wl_display); diff --git a/waybox/seat.c b/waybox/seat.c index e387fe7..8394576 100644 --- a/waybox/seat.c +++ b/waybox/seat.c @@ -4,10 +4,9 @@ #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); + wl_signal_emit(&view->xdg_toplevel->events.request_minimize, NULL); } } @@ -50,7 +49,6 @@ static bool handle_keybinding(struct wb_server *server, xkb_keysym_t sym, uint32 * Returns true if the keybinding is handled, false to send it to the * client. */ - if (!server->config) { /* Some default key bindings, when the rc.xml file can't be * parsed. */ @@ -76,7 +74,7 @@ static bool handle_keybinding(struct wb_server *server, xkb_keysym_t sym, uint32 if (key_binding->action & ACTION_CLOSE) { struct wb_view *current_view = wl_container_of( server->views.next, current_view, link); - if (wlr_surface_is_xdg_surface(current_view->xdg_toplevel->base->surface)) + if (current_view->mapped) #if WLR_CHECK_VERSION(0, 16, 0) wlr_xdg_toplevel_send_close(current_view->xdg_toplevel); #else @@ -90,21 +88,21 @@ static bool handle_keybinding(struct wb_server *server, xkb_keysym_t sym, uint32 } if (key_binding->action & 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); + if (view->mapped) + wl_signal_emit(&view->xdg_toplevel->events.request_maximize, NULL); } if (key_binding->action & 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)) { + if (view->mapped) { view->xdg_toplevel->requested.minimized = true; - wl_signal_emit(&view->xdg_toplevel->events.request_minimize, view->xdg_toplevel->base); + wl_signal_emit(&view->xdg_toplevel->events.request_minimize, NULL); struct wb_view *previous_view = wl_container_of(server->views.prev, previous_view, link); focus_view(previous_view, previous_view->xdg_toplevel->base->surface); } } if (key_binding->action & ACTION_SHADE) { struct wb_view *view = wl_container_of(server->views.next, view, link); - if (wlr_surface_is_xdg_surface(view->xdg_toplevel->base->surface)) { + if (view->mapped) { view->previous_position = view->current_position; #if WLR_CHECK_VERSION(0, 16, 0) wlr_xdg_toplevel_set_size(view->xdg_toplevel, @@ -117,7 +115,7 @@ static bool handle_keybinding(struct wb_server *server, xkb_keysym_t sym, uint32 } if (key_binding->action & ACTION_UNSHADE) { struct wb_view *view = wl_container_of(server->views.next, view, link); - if (wlr_surface_is_xdg_surface(view->xdg_toplevel->base->surface)) { + if (view->mapped) { #if WLR_CHECK_VERSION(0, 16, 0) wlr_xdg_toplevel_set_size(view->xdg_toplevel, view->previous_position.width, view->previous_position.height); diff --git a/waybox/xdg_shell.c b/waybox/xdg_shell.c index 0cb5ee6..e80b50d 100644 --- a/waybox/xdg_shell.c +++ b/waybox/xdg_shell.c @@ -49,6 +49,19 @@ void focus_view(struct wb_view *view, struct wlr_surface *surface) { keyboard->keycodes, keyboard->num_keycodes, &keyboard->modifiers); } +static struct wlr_box get_usable_area(struct wb_view *view) { + double closest_x, closest_y; + struct wlr_output *output = NULL; + struct wlr_box usable_area = {0}; + wlr_output_layout_closest_point(view->server->output_layout, output, + view->current_position.x + view->current_position.width / 2, + view->current_position.y + view->current_position.height / 2, + &closest_x, &closest_y); + output = wlr_output_layout_output_at(view->server->output_layout, closest_x, closest_y); + wlr_output_effective_resolution(output, &usable_area.width, &usable_area.height); + return usable_area; +} + 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); @@ -57,11 +70,20 @@ static void xdg_surface_commit(struct wl_listener *listener, void *data) { xdg_surface->toplevel->requested.minimized) return; + struct wb_config *config = view->server->config; + int left_margin, top_margin; + if (config) { + left_margin = config->margins.left; + top_margin = config->margins.top; + } else { + left_margin = 0; + top_margin = 0; + } struct wlr_box geo_box = {0}; wlr_xdg_surface_get_geometry(xdg_surface, &geo_box); - if (geo_box.x < 0 && view->current_position.x - view->server->config->margins.left < 1) + if (geo_box.x < 0 && view->current_position.x - left_margin < 1) view->current_position.x += -geo_box.x; - if (geo_box.y < 0 && view->current_position.y - view->server->config->margins.top < 1) { + if (geo_box.y < 0 && view->current_position.y - top_margin < 1) { view->decoration_height = -geo_box.y; view->current_position.y += view->decoration_height; } @@ -78,12 +100,19 @@ 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->current_position = geo_box; - view->current_position.x = config->margins.left; - view->current_position.y = config->margins.top; + if (config) { + struct wlr_box usable_area = get_usable_area(view); + view->current_position.height = MIN(view->current_position.height, + usable_area.height - config->margins.top - config->margins.bottom); + view->current_position.width = MIN(view->current_position.width, + usable_area.width - config->margins.left - config->margins.right); + view->current_position.x = config->margins.left; + view->current_position.y = config->margins.top; + } #if WLR_CHECK_VERSION(0, 16, 0) - wlr_xdg_toplevel_set_size(view->xdg_toplevel, geo_box.width, geo_box.height); + wlr_xdg_toplevel_set_size(view->xdg_toplevel, view->current_position.width, view->current_position.height); #else - wlr_xdg_toplevel_set_size(view->xdg_surface, geo_box.width, geo_box.height); + wlr_xdg_toplevel_set_size(view->xdg_surface, view->current_position.width, view->current_position.height); #endif focus_view(view, view->xdg_toplevel->base->surface); } @@ -122,45 +151,39 @@ static void xdg_surface_destroy(struct wl_listener *listener, void *data) { } 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); + struct wlr_box usable_area = get_usable_area(view); - double closest_x, closest_y; - struct wlr_output *output = NULL; - wlr_output_layout_closest_point(view->server->output_layout, output, - view->current_position.x + view->current_position.width / 2, - view->current_position.y + view->current_position.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}; + bool is_maximized = view->xdg_toplevel->current.maximized; if (!is_maximized) { struct wb_config *config = view->server->config; - wlr_output_effective_resolution(output, &usable_area.width, &usable_area.height); view->previous_position = view->current_position; - view->current_position.x = config->margins.left; - view->current_position.y = config->margins.top + view->decoration_height; - usable_area.height -= config->margins.top + config->margins.bottom; - usable_area.width -= config->margins.left + config->margins.right; + if (config) { + view->current_position.x = config->margins.left; + view->current_position.y = config->margins.top + view->decoration_height; + usable_area.height -= config->margins.top + config->margins.bottom; + usable_area.width -= config->margins.left + config->margins.right; + } else { + view->current_position.x = 0; + view->current_position.y = view->decoration_height; + } } else { usable_area = view->previous_position; view->current_position.x = view->previous_position.x; view->current_position.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); - wlr_xdg_toplevel_set_maximized(surface->toplevel, !is_maximized); + wlr_xdg_toplevel_set_size(view->xdg_toplevel, usable_area.width, usable_area.height); + wlr_xdg_toplevel_set_maximized(view->xdg_toplevel, !is_maximized); #else - wlr_xdg_toplevel_set_size(surface, usable_area.width, usable_area.height); - wlr_xdg_toplevel_set_maximized(surface, !is_maximized); + wlr_xdg_toplevel_set_size(view->xdg_surface, usable_area.width, usable_area.height); + wlr_xdg_toplevel_set_maximized(view->xdg_surface, !is_maximized); #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; + bool minimize_requested = view->xdg_toplevel->requested.minimized; if (minimize_requested) { view->previous_position.height = view->current_position.height; view->current_position.y = 0 - @@ -279,8 +302,7 @@ static void handle_new_xdg_surface(struct wl_listener *listener, void *data) { view->new_popup.notify = handle_new_popup; wl_signal_add(&xdg_surface->events.new_popup, &view->new_popup); - if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL) - { + if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL) { 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);