diff --git a/README.md b/README.md index 87ae370..6648459 100644 --- a/README.md +++ b/README.md @@ -184,6 +184,11 @@ ninja -C build For every release after 1.0.5, hashes will be provided. +1.7.0 + + * sha 256: 5af11b84e61a82a1a276e8f91f6ebc6baafd2c98d22be3da1d01734cc9d55faa + * sha 512: 45474115fb4c28fe1ee91ad54706bfe521b6e70bd8ea619b94a3f50bae426891bf6a0387aa9b2f7f6d18349280c4e84973e4e433d50c090e5a764c64fa67795d + 1.6.0 * sha 256: aef473eae73454429afb158d66a7bd9aec75ef915845b7508de5448820357aa8 @@ -413,6 +418,10 @@ Adds options to disable or enable outputs. See Issue 22 in Bugs.md and Issue #2 Adds support for non-build dependencies and an option for builds without pandoc. +### Release 1.7.0 + +Improve window ordering. + ## Contributors * Aisha Tammy diff --git a/cagebreak.c b/cagebreak.c index 0e3b9bb..6e16dc2 100644 --- a/cagebreak.c +++ b/cagebreak.c @@ -308,7 +308,7 @@ main(int argc, char *argv[]) { set_sig_handler(SIGCHLD, sig_chld_handler); - backend = wlr_backend_autocreate(server.wl_display, NULL); + backend = wlr_backend_autocreate(server.wl_display); if(!backend) { wlr_log(WLR_ERROR, "Unable to create the wlroots backend"); ret = 1; diff --git a/fuzz/fuzz-lib.c b/fuzz/fuzz-lib.c index c916777..cc7b6a4 100644 --- a/fuzz/fuzz-lib.c +++ b/fuzz/fuzz-lib.c @@ -181,7 +181,7 @@ LLVMFuzzerInitialize(int *argc, char ***argv) { server.backend = backend; struct wlr_backend *headless_backend = - wlr_headless_backend_create(server.wl_display, NULL); + wlr_headless_backend_create(server.wl_display); if(!headless_backend) { wlr_log(WLR_ERROR, "Unable to create the wlroots headless backend"); ret = 1; diff --git a/keybinding.c b/keybinding.c index 29739a4..005b87a 100644 --- a/keybinding.c +++ b/keybinding.c @@ -174,7 +174,7 @@ swap_tile(struct cg_tile *tile, tile->view = swap_tile->view; swap_tile->view = tmp_view; if(tile->view != NULL) { - view_maximize(tile->view, &tile->tile); + view_maximize(tile->view, tile); view_damage_whole(tile->view); } else { wlr_output_damage_add_box(tile->workspace->output->damage, &tile->tile); @@ -183,7 +183,7 @@ swap_tile(struct cg_tile *tile, server->curr_output->workspaces[server->curr_output->curr_workspace], swap_tile); if(swap_tile->view != NULL) { - view_maximize(swap_tile->view, &swap_tile->tile); + view_maximize(swap_tile->view, swap_tile); view_damage_whole(swap_tile->view); } else { wlr_output_damage_add_box(tile->workspace->output->damage, &tile->tile); @@ -342,7 +342,7 @@ resize(struct cg_tile *tile, const struct cg_tile *parent, int coord_offset, .height = tile->tile.y == 0 ? tile->tile.height : coord_offset}; wlr_output_damage_add_box(tile->workspace->output->damage, &damage_box); if(tile->view != NULL) { - view_maximize(tile->view, &tile->tile); + view_maximize(tile->view, tile); } } @@ -456,6 +456,13 @@ keybinding_workspace_fullscreen(struct cg_server *server) { return; } + struct cg_view *it_view; + wl_list_for_each(it_view, + &output->workspaces[output->curr_workspace]->views, link) { + it_view->tile = + output->workspaces[output->curr_workspace]->focused_tile; + } + seat_set_focus(server->seat, current_view); } @@ -537,11 +544,11 @@ keybinding_split_output(struct cg_output *output, bool vertical) { workspace_focus_tile(curr_workspace, curr_workspace->focused_tile); if(next_view != NULL) { - view_maximize(next_view, &new_tile->tile); + view_maximize(next_view, new_tile); } if(original_view != NULL) { - view_maximize(original_view, &curr_workspace->focused_tile->tile); + view_maximize(original_view, curr_workspace->focused_tile); } } @@ -601,46 +608,40 @@ keybinding_cycle_views(struct cg_server *server, bool reverse) { server->curr_output->workspaces[server->curr_output->curr_workspace]; struct cg_view *current_view = curr_workspace->focused_tile->view; - struct cg_view *new_view; - // We are focused on the desktop if(current_view == NULL) { - current_view = wl_container_of(&curr_workspace->views, new_view, link); - if(reverse) { - new_view = - wl_container_of(curr_workspace->views.prev, new_view, link); - } else { - new_view = - wl_container_of(curr_workspace->views.next, new_view, link); - } - } else { - if(reverse) { - new_view = wl_container_of(current_view->link.prev, new_view, link); - } else { - new_view = wl_container_of(current_view->link.next, new_view, link); - } + current_view = + wl_container_of(&curr_workspace->views, current_view, link); } - while(&new_view->link != ¤t_view->link && - (&new_view->link == &curr_workspace->views || - view_is_visible(new_view))) { - if(reverse) { - new_view = wl_container_of(new_view->link.prev, new_view, link); - } else { - new_view = wl_container_of(new_view->link.next, new_view, link); + struct cg_view *it_view, *next_view = NULL; + if(reverse) { + next_view = view_get_prev_view(current_view); + } else { + struct wl_list *it; + it = current_view->link.next; + while(it != ¤t_view->link) { + if(it == &curr_workspace->views) { + it = it->next; + continue; + } + it_view = wl_container_of(it, it_view, link); + if(!view_is_visible(it_view)) { + next_view = it_view; + break; + } + it = it->next; } } - if(&new_view->link == &curr_workspace->views) { + + if(next_view == NULL) { return; } wlr_output_damage_add_box(curr_workspace->output->damage, &curr_workspace->focused_tile->tile); - seat_set_focus(server->seat, new_view); - /* Move the previous view to the end of the list unless we are focused on - * the desktop*/ - if(!reverse && ¤t_view->link != &curr_workspace->views) { - wl_list_remove(¤t_view->link); - wl_list_insert(curr_workspace->views.prev, ¤t_view->link); - } + /* Prevent seat_set_focus from reordering the views */ + curr_workspace->focused_tile->view = wl_container_of( + next_view->link.prev, curr_workspace->focused_tile->view, link); + seat_set_focus(server->seat, next_view); } void @@ -717,7 +718,8 @@ keybinding_move_view_to_next_output(struct cg_server *server) { ->focused_tile->view = view; view->workspace = server->curr_output ->workspaces[server->curr_output->curr_workspace]; - view_position(view); + view->tile = view->workspace->focused_tile; + view_maximize(view, view->tile); seat_set_focus(server->seat, view); } } @@ -824,7 +826,7 @@ keybinding_move_view_to_workspace(struct cg_server *server, uint32_t ws) { view->workspace = ws; wl_list_insert(&ws->views, &view->link); ws->focused_tile->view = view; - view_maximize(view, &ws->focused_tile->tile); + view_maximize(view, ws->focused_tile); seat_set_focus(server->seat, view); } } diff --git a/man/cagebreak-config.5.md b/man/cagebreak-config.5.md index 693215d..94aaa74 100644 --- a/man/cagebreak-config.5.md +++ b/man/cagebreak-config.5.md @@ -1,4 +1,4 @@ -% CAGEBREAK-CONFIG(1) Version 1.6.0 | Cagebreak Manual +% CAGEBREAK-CONFIG(1) Version 1.7.0 | Cagebreak Manual # NAME diff --git a/man/cagebreak.1.md b/man/cagebreak.1.md index 6b6e381..3485d07 100644 --- a/man/cagebreak.1.md +++ b/man/cagebreak.1.md @@ -1,4 +1,4 @@ -% CAGEBREAK(1) Version 1.6.0 | Cagebreak Manual +% CAGEBREAK(1) Version 1.7.0 | Cagebreak Manual # NAME diff --git a/meson.build b/meson.build index e61eedc..5adc690 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('cagebreak', 'c', - version: '1.6.0', + version: '1.7.0', license: 'MIT', default_options: [ 'c_std=c11', @@ -53,7 +53,7 @@ if is_freebsd ) endif -wlroots = dependency('wlroots', version: '>= 0.12.0') +wlroots = dependency('wlroots', version: '>= 0.13.0') wayland_protos = dependency('wayland-protocols', version: '>=1.14') wayland_server = dependency('wayland-server') wayland_cursor = dependency('wayland-cursor') @@ -198,13 +198,13 @@ reproducible_build_versions = { 'wayland_server': '1.19.0', 'wayland_client': '1.19.0', 'wayland_cursor': '1.19.0', - 'wlroots': '0.12.0', - 'xkbcommon': '1.1.0', - 'fontconfig': '2.13.91', + 'wlroots': '0.13.0', + 'xkbcommon': '1.2.1', + 'fontconfig': '2.13.93', 'pixman': '0.40.0', - 'pango': '1.48.2', + 'pango': '1.48.4', 'cairo': '1.17.4', - 'pangocairo': '1.48.2', + 'pangocairo': '1.48.4', 'math': '-1' } diff --git a/message.c b/message.c index b88a562..acf1ffc 100644 --- a/message.c +++ b/message.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -85,7 +86,7 @@ create_message_texture(const char *string, const struct cg_output *output) { int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width); struct wlr_renderer *renderer = wlr_backend_get_renderer(output->wlr_output->backend); - texture = wlr_texture_from_pixels(renderer, WL_SHM_FORMAT_ARGB8888, stride, + texture = wlr_texture_from_pixels(renderer, DRM_FORMAT_ARGB8888, stride, width, height, data); cairo_surface_destroy(surface); g_object_unref(pango); diff --git a/output.c b/output.c index 6ec3c11..028f8b8 100644 --- a/output.c +++ b/output.c @@ -226,8 +226,12 @@ scan_out_primary_view(struct cg_output *output) { } } - struct cg_view *view = - output->workspaces[output->curr_workspace]->focused_tile->view; + struct cg_workspace *ws = output->workspaces[output->curr_workspace]; + if(ws->focused_tile->next != ws->focused_tile) { + return false; + } + + struct cg_view *view = ws->focused_tile->view; if(view == NULL || view->wlr_surface == NULL) { return false; } @@ -261,6 +265,9 @@ scan_out_primary_view(struct cg_output *output) { } wlr_output_attach_buffer(wlr_output, &surface->buffer->base); + if(!wlr_output_test(wlr_output)) { + return false; + } return wlr_output_commit(wlr_output); } @@ -361,17 +368,23 @@ handle_output_damage_frame(struct wl_listener *listener, void *data) { } static void -handle_output_transform(struct wl_listener *listener, void *data) { - struct cg_output *output = wl_container_of(listener, output, transform); +handle_output_commit(struct wl_listener *listener, void *data) { + struct cg_output *output = wl_container_of(listener, output, commit); + struct wlr_output_event_commit *event = data; if(!output->wlr_output->enabled || output->workspaces == NULL) { return; } - struct cg_view *view; - wl_list_for_each(view, &output->workspaces[output->curr_workspace]->views, - link) { - view_position(view); + if(event->committed & + (WLR_OUTPUT_STATE_TRANSFORM | WLR_OUTPUT_STATE_SCALE)) { + struct cg_view *view; + wl_list_for_each( + view, &output->workspaces[output->curr_workspace]->views, link) { + if(view_is_visible(view)) { + view_maximize(view, view->tile); + } + } } } @@ -386,7 +399,9 @@ handle_output_mode(struct wl_listener *listener, void *data) { struct cg_view *view; wl_list_for_each(view, &output->workspaces[output->curr_workspace]->views, link) { - view_position(view); + if(view_is_visible(view)) { + view_maximize(view, view->tile); + } } } @@ -429,6 +444,10 @@ output_clear(struct cg_output *output) { view->workspace = server->curr_output ->workspaces[server->curr_output->curr_workspace]; + view->tile = + server->curr_output + ->workspaces[server->curr_output->curr_workspace] + ->focused_tile; if(server->seat->focused_view == NULL) { seat_set_focus(server->seat, view); } @@ -448,6 +467,10 @@ output_clear(struct cg_output *output) { view->workspace = server->curr_output ->workspaces[server->curr_output->curr_workspace]; + view->tile = + server->curr_output + ->workspaces[server->curr_output->curr_workspace] + ->focused_tile; } } } @@ -460,7 +483,7 @@ output_destroy(struct cg_output *output) { wl_list_remove(&output->destroy.link); wl_list_remove(&output->mode.link); - wl_list_remove(&output->transform.link); + wl_list_remove(&output->commit.link); wl_list_remove(&output->damage_frame.link); wl_list_remove(&output->damage_destroy.link); @@ -605,8 +628,8 @@ handle_new_output(struct wl_listener *listener, void *data) { output->mode.notify = handle_output_mode; wl_signal_add(&wlr_output->events.mode, &output->mode); - output->transform.notify = handle_output_transform; - wl_signal_add(&wlr_output->events.transform, &output->transform); + output->commit.notify = handle_output_commit; + wl_signal_add(&wlr_output->events.commit, &output->commit); output->destroy.notify = handle_output_destroy; wl_signal_add(&wlr_output->events.destroy, &output->destroy); output->damage_frame.notify = handle_output_damage_frame; diff --git a/output.h b/output.h index a11d4be..42cb629 100644 --- a/output.h +++ b/output.h @@ -16,7 +16,7 @@ struct cg_output { struct wlr_output_damage *damage; struct wl_listener mode; - struct wl_listener transform; + struct wl_listener commit; struct wl_listener destroy; struct wl_listener damage_frame; struct wl_listener damage_destroy; diff --git a/render.c b/render.c index 6aadf50..80c769b 100644 --- a/render.c +++ b/render.c @@ -135,7 +135,6 @@ render_view_toplevels(struct cg_view *view, struct cg_output *output, .tile_width = 0, .tile_height = 0, }; - // TODO: improve run time behaviour of view_get_tile struct cg_tile *view_tile = view_get_tile(view); if(view_tile != NULL) { if(view_tile->tile.width != view->wlr_surface->current.width || diff --git a/seat.c b/seat.c index fc22669..51450ac 100644 --- a/seat.c +++ b/seat.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #if CG_HAS_XWAYLAND @@ -55,9 +56,6 @@ view_at(const struct cg_view *view, double lx, double ly, struct wlr_box *output_layout_box = wlr_output_layout_get_box( view->server->output_layout, view->workspace->output->wlr_output); if(output_layout_box == NULL) { - fprintf(stderr, "OUTPUT:%d\n", - view->workspace->output->wlr_output->enabled); - return output_layout_box->x; return false; } @@ -333,7 +331,8 @@ handle_key_event(struct cg_keyboard_group *group, struct cg_seat *seat, bool handled = false; for(int i = 0; i < nsyms; ++i) { - if(event->state == WLR_KEY_PRESSED && !key_is_modifier(syms[i])) { + if(event->state == WL_KEYBOARD_KEY_STATE_PRESSED && + !key_is_modifier(syms[i])) { uint32_t modifiers = wlr_keyboard_get_modifiers(device->keyboard); /* Get the consumed_modifiers and remove them from the modifier list */ @@ -961,13 +960,18 @@ seat_set_focus(struct cg_seat *seat, struct cg_view *view) { #endif { /* Always resize the view, even if prev_view == view */ + struct cg_workspace *curr_workspace = + server->curr_output + ->workspaces[server->curr_output->curr_workspace]; + view_maximize(view, curr_workspace->focused_tile); if(!view_is_visible(view)) { - struct cg_workspace *curr_workspace = - server->curr_output - ->workspaces[server->curr_output->curr_workspace]; - view_maximize(view, &curr_workspace->focused_tile->tile); wl_list_remove(&view->link); - wl_list_insert(&curr_workspace->views, &view->link); + if(curr_workspace->focused_tile->view != NULL) { + wl_list_insert(&curr_workspace->focused_tile->view->link, + &view->link); + } else { + wl_list_insert(curr_workspace->views.prev, &view->link); + } curr_workspace->focused_tile->view = view; } } @@ -997,6 +1001,7 @@ seat_set_focus(struct cg_seat *seat, struct cg_view *view) { free(title); struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(wlr_seat); + wlr_seat_keyboard_end_grab(wlr_seat); if(keyboard) { wlr_seat_keyboard_notify_enter( wlr_seat, view->wlr_surface, keyboard->keycodes, diff --git a/signatures/1.6.0.sig b/signatures/1.6.0.sig new file mode 100644 index 0000000..3ade030 Binary files /dev/null and b/signatures/1.6.0.sig differ diff --git a/signatures/cagebreak.sig b/signatures/cagebreak.sig index 3ade030..eebdb6c 100644 Binary files a/signatures/cagebreak.sig and b/signatures/cagebreak.sig differ diff --git a/view.c b/view.c index f9bfcc3..410a746 100644 --- a/view.c +++ b/view.c @@ -32,13 +32,20 @@ view_get_prev_view(struct cg_view *view) { struct cg_view *prev = NULL; struct cg_view *it_view; - wl_list_for_each(it_view, &view->workspace->views, link) { - if(!view_is_visible(it_view) && view != it_view) { + struct wl_list *it; + it = view->link.prev; + while(it != &view->link) { + if(it == &view->workspace->views) { + it = it->prev; + continue; + } + it_view = wl_container_of(it, it_view, link); + if(!view_is_visible(it_view)) { prev = it_view; break; } + it = it->prev; } - return prev; } @@ -197,15 +204,11 @@ view_is_primary(const struct cg_view *view) { struct cg_tile * view_get_tile(const struct cg_view *view) { - bool first = true; - for(struct cg_tile *tile = view->workspace->focused_tile; - first || view->workspace->focused_tile != tile; tile = tile->next) { - first = false; - if(tile->view == view) { - return tile; - } + if(view->tile != NULL && view->tile->view == view) { + return view->tile; + } else { + return NULL; } - return NULL; } bool @@ -224,7 +227,7 @@ view_damage(struct cg_view *view, bool whole) { if(view_tile != NULL && (view->wlr_surface->current.width != view_tile->tile.width || view->wlr_surface->current.height != view_tile->tile.height)) { - view_maximize(view, &view_tile->tile); + view_maximize(view, view_tile); } output_damage_surface(view->workspace->output, view->wlr_surface, view->ox, view->oy, whole); @@ -248,20 +251,11 @@ view_activate(struct cg_view *view, bool activate) { } void -view_maximize(struct cg_view *view, const struct wlr_box *tile_box) { - view->ox = tile_box->x; - view->oy = tile_box->y; - view->impl->maximize(view, tile_box->width, tile_box->height); -} - -void -view_position(struct cg_view *view) { - struct wlr_box *tile_workspace_box = - &view->workspace->output - ->workspaces[view->workspace->output->curr_workspace] - ->focused_tile->tile; - - view_maximize(view, tile_workspace_box); +view_maximize(struct cg_view *view, struct cg_tile *tile) { + view->ox = tile->tile.x; + view->oy = tile->tile.y; + view->impl->maximize(view, tile->tile.width, tile->tile.height); + view->tile = tile; } void @@ -309,7 +303,7 @@ view_unmap(struct cg_view *view) { &view_tile->tile); view_tile->view = prev; if(prev != NULL) { - view_maximize(prev, &view_tile->tile); + view_maximize(prev, view_tile); } } } @@ -361,7 +355,8 @@ view_map(struct cg_view *view, struct wlr_surface *surface, } else #endif { - view_position(view); + view->tile = view->workspace->focused_tile; + view_maximize(view, view->tile); wl_list_insert(&ws->views, &view->link); } seat_set_focus(output->server->seat, view); @@ -384,6 +379,7 @@ void view_init(struct cg_view *view, enum cg_view_type type, const struct cg_view_impl *impl, struct cg_server *server) { view->workspace = NULL; + view->tile = NULL; view->server = server; view->type = type; view->impl = impl; diff --git a/view.h b/view.h index 65958b0..add26b0 100644 --- a/view.h +++ b/view.h @@ -23,6 +23,7 @@ struct cg_view { struct wl_list link; // server::views struct wl_list children; // cg_view_child::link struct wlr_surface *wlr_surface; + struct cg_tile *tile; /* The view has a position in output coordinates. */ int ox, oy; @@ -35,8 +36,6 @@ struct cg_view { struct cg_view_impl { char *(*get_title)(const struct cg_view *view); - void (*get_geometry)(const struct cg_view *view, int *width_out, - int *height_out); bool (*is_primary)(const struct cg_view *view); void (*activate)(struct cg_view *view, bool activate); void (*close)(struct cg_view *view); @@ -90,8 +89,6 @@ view_damage_child(struct cg_view_child *view, bool whole); void view_activate(struct cg_view *view, bool activate); void -view_position(struct cg_view *view); -void view_for_each_surface(struct cg_view *view, wlr_surface_iterator_func_t iterator, void *data); void @@ -100,7 +97,7 @@ view_for_each_popup(struct cg_view *view, wlr_surface_iterator_func_t iterator, void view_unmap(struct cg_view *view); void -view_maximize(struct cg_view *view, const struct wlr_box *tile_box); +view_maximize(struct cg_view *view, struct cg_tile *tile); void view_map(struct cg_view *view, struct wlr_surface *surface, struct cg_workspace *ws); @@ -119,5 +116,7 @@ view_child_finish(struct cg_view_child *child); void view_child_init(struct cg_view_child *child, struct cg_view_child *parent, struct cg_view *view, struct wlr_surface *wlr_surface); +struct cg_view * +view_get_prev_view(struct cg_view *view); #endif diff --git a/xdg_shell.c b/xdg_shell.c index 514ce97..0e76dc4 100644 --- a/xdg_shell.c +++ b/xdg_shell.c @@ -183,17 +183,6 @@ get_title(const struct cg_view *view) { return xdg_shell_view->xdg_surface->toplevel->title; } -static void -get_geometry(const struct cg_view *view, int *width_out, int *height_out) { - const struct cg_xdg_shell_view *xdg_shell_view = - xdg_shell_view_from_const_view(view); - struct wlr_box geom; - - wlr_xdg_surface_get_geometry(xdg_shell_view->xdg_surface, &geom); - *width_out = geom.width; - *height_out = geom.height; -} - static bool is_primary(const struct cg_view *view) { const struct cg_xdg_shell_view *xdg_shell_view = @@ -246,7 +235,8 @@ static void for_each_popup(struct cg_view *view, wlr_surface_iterator_func_t iterator, void *data) { struct cg_xdg_shell_view *xdg_shell_view = xdg_shell_view_from_view(view); - wlr_xdg_surface_for_each_popup(xdg_shell_view->xdg_surface, iterator, data); + wlr_xdg_surface_for_each_popup_surface(xdg_shell_view->xdg_surface, + iterator, data); } static struct wlr_surface * @@ -324,7 +314,6 @@ handle_xdg_shell_surface_destroy(struct wl_listener *listener, void *_data) { static const struct cg_view_impl xdg_shell_view_impl = { .get_title = get_title, - .get_geometry = get_geometry, .is_primary = is_primary, .activate = activate, .close = close, diff --git a/xwayland.c b/xwayland.c index e5f505b..b790527 100644 --- a/xwayland.c +++ b/xwayland.c @@ -48,14 +48,6 @@ get_title(const struct cg_view *view) { return xwayland_view->xwayland_surface->title; } -static void -get_geometry(const struct cg_view *view, int *width_out, int *height_out) { - const struct cg_xwayland_view *xwayland_view = - xwayland_view_from_const_view(view); - *width_out = xwayland_view->xwayland_surface->width; - *height_out = xwayland_view->xwayland_surface->height; -} - static bool is_primary(const struct cg_view *view) { const struct cg_xwayland_view *xwayland_view = @@ -210,7 +202,6 @@ handle_xwayland_surface_destroy(struct wl_listener *listener, void *_data) { static const struct cg_view_impl xwayland_view_impl = { .get_title = get_title, - .get_geometry = get_geometry, .is_primary = is_primary, .activate = activate, .close = close,