Release 1.7.0

- Improve window ordering
- Update dependency versions (adapt to wlroots 0.13.0)
This commit is contained in:
Cagebreak Signing Key 3 2021-04-19 22:15:16 +02:00
commit ed29a49be7
18 changed files with 142 additions and 128 deletions

View file

@ -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

View file

@ -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;

View file

@ -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;

View file

@ -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);
}
current_view =
wl_container_of(&curr_workspace->views, current_view, link);
}
struct cg_view *it_view, *next_view = NULL;
if(reverse) {
next_view = view_get_prev_view(current_view);
} 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);
struct wl_list *it;
it = current_view->link.next;
while(it != &current_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;
}
}
while(&new_view->link != &current_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);
}
}
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 && &current_view->link != &curr_workspace->views) {
wl_list_remove(&current_view->link);
wl_list_insert(curr_workspace->views.prev, &current_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);
}
}

View file

@ -1,4 +1,4 @@
% CAGEBREAK-CONFIG(1) Version 1.6.0 | Cagebreak Manual
% CAGEBREAK-CONFIG(1) Version 1.7.0 | Cagebreak Manual
# NAME

View file

@ -1,4 +1,4 @@
% CAGEBREAK(1) Version 1.6.0 | Cagebreak Manual
% CAGEBREAK(1) Version 1.7.0 | Cagebreak Manual
# NAME

View file

@ -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'
}

View file

@ -1,4 +1,5 @@
#include <cairo/cairo.h>
#include <drm_fourcc.h>
#include <pango/pangocairo.h>
#include <unistd.h>
#include <wlr/backend.h>
@ -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);

View file

@ -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 @@ frame_done:
}
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;

View file

@ -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;

View file

@ -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 ||

23
seat.c
View file

@ -24,6 +24,7 @@
#include <wlr/types/wlr_primary_selection.h>
#include <wlr/types/wlr_seat.h>
#include <wlr/types/wlr_surface.h>
#include <wlr/types/wlr_touch.h>
#include <wlr/types/wlr_xcursor_manager.h>
#include <wlr/util/log.h>
#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,

BIN
signatures/1.6.0.sig Normal file

Binary file not shown.

Binary file not shown.

52
view.c
View file

@ -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;

9
view.h
View file

@ -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

View file

@ -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,

View file

@ -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,