mirror of
https://github.com/wizbright/waybox.git
synced 2025-10-29 05:40:20 -04:00
Some bug fixes
1. The "crash when exiting an application while moving it" bug. See https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3372 2. The crash when there's no previous view to focus. This wasn't a problem before the migration to the scene graph API due to a logic error on my part. 3. The crash if <margins> is missing from rc.xml. 4. I'm now reusing code from focus_view() in seat_focus_surface(). 5. I'm now using the dimensions of the output layout box instead of the current view (which was clearly wrong) for unconstraining layer-shell popups. 6. I fixed setting the background color, so that it won't interfere with the layer_shell helper.
This commit is contained in:
parent
5a3ac6055d
commit
579a2d2084
8 changed files with 52 additions and 46 deletions
|
|
@ -23,9 +23,8 @@ struct wb_output {
|
|||
struct wlr_scene_node *shell_top;
|
||||
} layers;
|
||||
|
||||
#if !WLR_CHECK_VERSION(0, 16, 0)
|
||||
struct wlr_scene_rect *scene_rect;
|
||||
#endif
|
||||
struct wlr_scene_rect *background;
|
||||
struct wlr_box geometry;
|
||||
|
||||
struct wl_listener destroy;
|
||||
struct wl_listener frame;
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ struct wb_keyboard {
|
|||
|
||||
struct wb_server;
|
||||
struct wb_seat *wb_seat_create(struct wb_server *server);
|
||||
void seat_focus_surface(struct wb_seat *seat, struct wlr_surface *surface);
|
||||
void seat_set_focus_layer(struct wb_seat *seat, struct wlr_layer_surface_v1 *layer);
|
||||
void wb_seat_destroy(struct wb_seat *seat);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -3,6 +3,12 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
static unsigned long strtoulong(char *s) {
|
||||
if (s)
|
||||
return strtoul(s, (char **) NULL, 10);
|
||||
else return 0;
|
||||
}
|
||||
|
||||
static char *parse_xpath_expr(char *expr, xmlXPathContextPtr ctxt) {
|
||||
xmlXPathObjectPtr object = xmlXPathEvalExpression((xmlChar *) expr, ctxt);
|
||||
if (object == NULL) {
|
||||
|
|
@ -175,10 +181,10 @@ bool init_config(struct wb_server *server) {
|
|||
return false;
|
||||
}
|
||||
|
||||
config->margins.bottom = strtoul(parse_xpath_expr("//ob:margins/ob:bottom", ctxt), NULL, 10);
|
||||
config->margins.left = strtoul(parse_xpath_expr("//ob:margins/ob:left", ctxt), NULL, 10);
|
||||
config->margins.right = strtoul(parse_xpath_expr("//ob:margins/ob:right", ctxt), NULL, 10);
|
||||
config->margins.top = strtoul(parse_xpath_expr("//ob:margins/ob:top", ctxt), NULL, 10);
|
||||
config->margins.bottom = strtoulong(parse_xpath_expr("//ob:margins/ob:bottom", ctxt));
|
||||
config->margins.left = strtoulong(parse_xpath_expr("//ob:margins/ob:left", ctxt));
|
||||
config->margins.right = strtoulong(parse_xpath_expr("//ob:margins/ob:right", ctxt));
|
||||
config->margins.top = strtoulong(parse_xpath_expr("//ob:margins/ob:top", ctxt));
|
||||
|
||||
server->config = config;
|
||||
|
||||
|
|
|
|||
|
|
@ -7,8 +7,10 @@ static void process_cursor_move(struct wb_server *server) {
|
|||
struct wb_view *view = server->grabbed_view;
|
||||
view->current_position.x = server->cursor->cursor->x - server->grab_x;
|
||||
view->current_position.y = server->cursor->cursor->y - server->grab_y;
|
||||
wlr_scene_node_set_position(view->scene_node,
|
||||
view->current_position.x, view->current_position.y);
|
||||
if (view->scene_node->parent->type == WLR_SCENE_NODE_ROOT) {
|
||||
wlr_scene_node_set_position(view->scene_node,
|
||||
view->current_position.x, view->current_position.y);
|
||||
}
|
||||
}
|
||||
|
||||
static void process_cursor_resize(struct wb_server *server) {
|
||||
|
|
|
|||
|
|
@ -237,12 +237,11 @@ static void popup_unconstrain(struct wb_layer_popup *popup) {
|
|||
|
||||
/* the output box expressed in the coordinate system of the toplevel parent
|
||||
* of the popup */
|
||||
struct wb_view *view = wl_container_of(output->server->views.next, view, link);
|
||||
struct wlr_box output_toplevel_sx_box = {
|
||||
.x = view->current_position.x - lx,
|
||||
.y = view->current_position.y - ly,
|
||||
.width = output->wlr_output->width,
|
||||
.height = output->wlr_output->height,
|
||||
.x = output->geometry.x - lx,
|
||||
.y = output->geometry.y - ly,
|
||||
.width = output->geometry.width,
|
||||
.height = output->geometry.height,
|
||||
};
|
||||
|
||||
wlr_xdg_popup_unconstrain_from_box(wlr_popup, &output_toplevel_sx_box);
|
||||
|
|
|
|||
|
|
@ -1,20 +1,30 @@
|
|||
#include "waybox/output.h"
|
||||
|
||||
void output_frame_notify(struct wl_listener *listener, void *data) {
|
||||
/* This function is called every time an output is ready to display a frame,
|
||||
* generally at the output's refresh rate (e.g. 60Hz). */
|
||||
struct wb_output *output = wl_container_of(listener, output, frame);
|
||||
struct wlr_scene *scene = output->server->scene;
|
||||
|
||||
struct wlr_scene_output *scene_output = wlr_scene_get_scene_output(
|
||||
scene, output->wlr_output);
|
||||
|
||||
#if !WLR_CHECK_VERSION(0, 16, 0)
|
||||
wlr_scene_rect_set_size(output->scene_rect,
|
||||
output->wlr_output->width, output->wlr_output->height);
|
||||
#if WLR_CHECK_VERSION(0, 16, 0)
|
||||
wlr_output_layout_get_box(output->server->output_layout,
|
||||
output->wlr_output, &output->geometry);
|
||||
#else
|
||||
output->geometry = *wlr_output_layout_get_box(
|
||||
output->server->output_layout, output->wlr_output);
|
||||
#endif
|
||||
/* Update the background for the current output size. */
|
||||
wlr_scene_rect_set_size(output->background,
|
||||
output->geometry.width, output->geometry.height);
|
||||
|
||||
/* Render the scene if needed and commit the output */
|
||||
wlr_scene_output_commit(scene_output);
|
||||
|
||||
/* This lets the client know that we've displayed that frame and it can
|
||||
* prepare another one now if it likes. */
|
||||
struct timespec now;
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
wlr_scene_output_send_frame_done(scene_output, &now);
|
||||
|
|
@ -65,12 +75,10 @@ void new_output_notify(struct wl_listener *listener, void *data) {
|
|||
output->wlr_output = wlr_output;
|
||||
wlr_output->data = output;
|
||||
|
||||
#if !WLR_CHECK_VERSION(0, 16, 0)
|
||||
/* Allows setting the traditional background color. However, it
|
||||
* interferes with the wlr_scene layer shell helper in 0.16.0+. */
|
||||
/* Set the background color */
|
||||
float color[4] = {0.1875, 0.1875, 0.1875, 1.0};
|
||||
output->scene_rect = wlr_scene_rect_create(&server->scene->node, 0, 0, color);
|
||||
#endif
|
||||
output->background = wlr_scene_rect_create(&server->scene->node, 0, 0, color);
|
||||
wlr_scene_node_lower_to_bottom(&output->background->node);
|
||||
|
||||
/* Initializes the layers */
|
||||
size_t num_layers = sizeof(output->layers) / sizeof(struct wlr_scene_node *);
|
||||
|
|
|
|||
|
|
@ -274,7 +274,8 @@ void seat_focus_surface(struct wb_seat *seat, struct wlr_surface *surface) {
|
|||
wlr_seat_keyboard_notify_clear_focus(seat->seat);
|
||||
return;
|
||||
}
|
||||
struct wlr_keyboard *kb = (struct wlr_keyboard *) seat->keyboards.next;
|
||||
|
||||
struct wlr_keyboard *kb = wlr_seat_get_keyboard(seat->seat);
|
||||
wlr_seat_keyboard_notify_enter(seat->seat, surface, kb->keycodes,
|
||||
kb->num_keycodes, &kb->modifiers);
|
||||
}
|
||||
|
|
@ -327,6 +328,7 @@ struct wb_seat *wb_seat_create(struct wb_server *server) {
|
|||
}
|
||||
|
||||
void wb_seat_destroy(struct wb_seat *seat) {
|
||||
wl_list_remove(&seat->keyboards);
|
||||
wl_list_remove(&seat->request_set_primary_selection.link);
|
||||
wl_list_remove(&seat->request_set_selection.link);
|
||||
wlr_seat_destroy(seat->seat);
|
||||
|
|
|
|||
|
|
@ -52,7 +52,6 @@ void focus_view(struct wb_view *view, struct wlr_surface *surface) {
|
|||
wlr_xdg_toplevel_set_activated(previous, false);
|
||||
#endif
|
||||
}
|
||||
struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(seat);
|
||||
/* Move the view to the front */
|
||||
wlr_scene_node_raise_to_top(view->scene_node);
|
||||
wl_list_remove(&view->link);
|
||||
|
|
@ -68,8 +67,7 @@ void focus_view(struct wb_view *view, struct wlr_surface *surface) {
|
|||
* track of this and automatically send key events to the appropriate
|
||||
* clients without additional work on your part.
|
||||
*/
|
||||
wlr_seat_keyboard_notify_enter(seat, view->xdg_toplevel->base->surface,
|
||||
keyboard->keycodes, keyboard->num_keycodes, &keyboard->modifiers);
|
||||
seat_focus_surface(server->seat, view->xdg_toplevel->base->surface);
|
||||
}
|
||||
|
||||
static struct wlr_box get_usable_area(struct wb_view *view) {
|
||||
|
|
@ -126,15 +124,9 @@ static void xdg_toplevel_unmap(struct wl_listener *listener, void *data) {
|
|||
if (view->xdg_toplevel->base->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL)
|
||||
return;
|
||||
|
||||
/* Focus the next view, if any. */
|
||||
struct wb_view *next_view = wl_container_of(view->link.next, next_view, link);
|
||||
/* If the current view is mapped, focus it. */
|
||||
if (view->scene_node->state.enabled) {
|
||||
wlr_log(WLR_INFO, "%s: %s", _("Focusing current view"),
|
||||
view->xdg_toplevel->app_id);
|
||||
focus_view(view, view->xdg_toplevel->base->surface);
|
||||
}
|
||||
/* Otherwise, focus the next view, if any. */
|
||||
else if (next_view && next_view->scene_node && next_view->scene_node->state.enabled) {
|
||||
if (next_view && next_view->scene_node && next_view->scene_node->state.enabled) {
|
||||
wlr_log(WLR_INFO, "%s: %s", _("Focusing next view"),
|
||||
next_view->xdg_toplevel->app_id);
|
||||
focus_view(next_view, next_view->xdg_toplevel->base->surface);
|
||||
|
|
@ -148,6 +140,7 @@ static void xdg_toplevel_destroy(struct wl_listener *listener, void *data) {
|
|||
wl_list_remove(&view->map.link);
|
||||
wl_list_remove(&view->unmap.link);
|
||||
wl_list_remove(&view->destroy.link);
|
||||
wl_list_remove(&view->new_popup.link);
|
||||
|
||||
if (view->xdg_toplevel->base->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL) {
|
||||
wl_list_remove(&view->request_minimize.link);
|
||||
|
|
@ -269,22 +262,18 @@ static void xdg_toplevel_request_resize(
|
|||
static void handle_new_popup(struct wl_listener *listener, void *data) {
|
||||
struct wlr_xdg_popup *popup = data;
|
||||
struct wb_view *view = wl_container_of(listener, view, new_popup);
|
||||
struct wlr_output_layout *output_layout = view->server->output_layout;
|
||||
|
||||
struct wlr_output *wlr_output = wlr_output_layout_output_at(output_layout,
|
||||
struct wlr_output *wlr_output = wlr_output_layout_output_at(
|
||||
view->server->output_layout,
|
||||
view->current_position.x + popup->geometry.x,
|
||||
view->current_position.y + popup->geometry.y);
|
||||
struct wlr_box output_box;
|
||||
#if WLR_CHECK_VERSION(0, 16, 0)
|
||||
wlr_output_layout_get_box(output_layout, wlr_output, &output_box);
|
||||
#else
|
||||
output_box = (*wlr_output_layout_get_box(output_layout, wlr_output));
|
||||
#endif
|
||||
struct wb_output *output = wlr_output->data;
|
||||
|
||||
struct wlr_box output_toplevel_box = {
|
||||
.x = output_box.x - view->current_position.x,
|
||||
.y = output_box.y - view->current_position.y,
|
||||
.width = output_box.width,
|
||||
.height = output_box.height,
|
||||
.x = output->geometry.x - view->current_position.x,
|
||||
.y = output->geometry.y - view->current_position.y,
|
||||
.width = output->geometry.width,
|
||||
.height = output->geometry.height,
|
||||
};
|
||||
wlr_xdg_popup_unconstrain_from_box(popup, &output_toplevel_box);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue