mirror of
https://github.com/labwc/labwc.git
synced 2025-11-03 09:01:51 -05:00
view: refactor view_next()
This commit is contained in:
parent
b8fd4fed53
commit
afaf78aa72
7 changed files with 50 additions and 65 deletions
|
|
@ -128,6 +128,7 @@ struct view {
|
||||||
|
|
||||||
bool mapped;
|
bool mapped;
|
||||||
bool been_mapped;
|
bool been_mapped;
|
||||||
|
bool minimized;
|
||||||
int x, y, w, h;
|
int x, y, w, h;
|
||||||
bool show_server_side_deco;
|
bool show_server_side_deco;
|
||||||
|
|
||||||
|
|
@ -178,8 +179,7 @@ struct wlr_box view_get_surface_geometry(struct view *view);
|
||||||
struct wlr_box view_geometry(struct view *view);
|
struct wlr_box view_geometry(struct view *view);
|
||||||
void view_resize(struct view *view, struct wlr_box geo);
|
void view_resize(struct view *view, struct wlr_box geo);
|
||||||
void view_focus(struct view *view);
|
void view_focus(struct view *view);
|
||||||
struct view *view_front_toplevel(struct server *server);
|
struct view *view_next(struct view *current);
|
||||||
struct view *next_toplevel(struct view *current);
|
|
||||||
bool view_hasfocus(struct view *view);
|
bool view_hasfocus(struct view *view);
|
||||||
struct view *view_at(struct server *server, double lx, double ly,
|
struct view *view_at(struct server *server, double lx, double ly,
|
||||||
struct wlr_surface **surface, double *sx, double *sy,
|
struct wlr_surface **surface, double *sx, double *sy,
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ void action(struct server *server, struct keybind *keybind)
|
||||||
if (!strcasecmp(keybind->action, "Exit")) {
|
if (!strcasecmp(keybind->action, "Exit")) {
|
||||||
wl_display_terminate(server->wl_display);
|
wl_display_terminate(server->wl_display);
|
||||||
} else if (!strcasecmp(keybind->action, "NextWindow")) {
|
} else if (!strcasecmp(keybind->action, "NextWindow")) {
|
||||||
server->cycle_view = next_toplevel(view_front_toplevel(server));
|
server->cycle_view = view_next(server->cycle_view);
|
||||||
} else if (!strcasecmp(keybind->action, "Execute")) {
|
} else if (!strcasecmp(keybind->action, "Execute")) {
|
||||||
spawn_async_no_shell(keybind->command);
|
spawn_async_no_shell(keybind->command);
|
||||||
} else if (!strcasecmp(keybind->action, "debug-views")) {
|
} else if (!strcasecmp(keybind->action, "debug-views")) {
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,10 @@ static void show_one_xwl_view(struct view *view)
|
||||||
|
|
||||||
void dbg_show_one_view(struct view *view)
|
void dbg_show_one_view(struct view *view)
|
||||||
{
|
{
|
||||||
|
if (!view->surface)
|
||||||
|
return;
|
||||||
|
if (!view->mapped && !view->minimized)
|
||||||
|
return;
|
||||||
if (view->type == LAB_XDG_SHELL_VIEW)
|
if (view->type == LAB_XDG_SHELL_VIEW)
|
||||||
show_one_xdg_view(view);
|
show_one_xdg_view(view);
|
||||||
else if (view->type == LAB_XWAYLAND_VIEW)
|
else if (view->type == LAB_XWAYLAND_VIEW)
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ static void keyboard_handle_key(struct wl_listener *listener, void *data)
|
||||||
server->cycle_view = NULL;
|
server->cycle_view = NULL;
|
||||||
} else if (event->state == WLR_KEY_PRESSED) {
|
} else if (event->state == WLR_KEY_PRESSED) {
|
||||||
/* cycle to next */
|
/* cycle to next */
|
||||||
server->cycle_view = next_toplevel(server->cycle_view);
|
server->cycle_view = view_next(server->cycle_view);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
97
src/view.c
97
src/view.c
|
|
@ -1,19 +1,6 @@
|
||||||
#include "labwc.h"
|
#include "labwc.h"
|
||||||
#include "common/bug-on.h"
|
#include "common/bug-on.h"
|
||||||
|
|
||||||
static bool is_toplevel(struct view *view)
|
|
||||||
{
|
|
||||||
if (!view)
|
|
||||||
return false;
|
|
||||||
switch (view->type) {
|
|
||||||
case LAB_XDG_SHELL_VIEW:
|
|
||||||
return view->xdg_surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL;
|
|
||||||
case LAB_XWAYLAND_VIEW:
|
|
||||||
return view->xwayland_surface->parent == NULL;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void view_init_position(struct view *view)
|
void view_init_position(struct view *view)
|
||||||
{
|
{
|
||||||
/* If surface already has a 'desired' position, don't touch it */
|
/* If surface already has a 'desired' position, don't touch it */
|
||||||
|
|
@ -112,39 +99,6 @@ bool view_hasfocus(struct view *view)
|
||||||
return (view->surface == seat->keyboard_state.focused_surface);
|
return (view->surface == seat->keyboard_state.focused_surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct wlr_xwayland_surface *top_parent(struct view *view)
|
|
||||||
{
|
|
||||||
struct wlr_xwayland_surface *s = view->xwayland_surface;
|
|
||||||
while (s->parent)
|
|
||||||
s = s->parent;
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void move_xwayland_decendants_to_front(struct view *parent)
|
|
||||||
{
|
|
||||||
if (!parent || parent->type != LAB_XWAYLAND_VIEW)
|
|
||||||
return;
|
|
||||||
struct view *view, *next;
|
|
||||||
wl_list_for_each_reverse_safe(view, next, &parent->server->views, link)
|
|
||||||
{
|
|
||||||
/* need to stop here, otherwise loops keeps going forever */
|
|
||||||
if (view == parent)
|
|
||||||
break;
|
|
||||||
if (view->type != LAB_XWAYLAND_VIEW)
|
|
||||||
continue;
|
|
||||||
if (!view->mapped)
|
|
||||||
continue;
|
|
||||||
if (top_parent(view) != parent->xwayland_surface)
|
|
||||||
continue;
|
|
||||||
move_to_front(view);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Note that if 'view' is not a toplevel view, the 'front' toplevel view
|
|
||||||
* will be focussed on; but if 'view' is a toplevel view, the 'next'
|
|
||||||
* will be focussed on.
|
|
||||||
*/
|
|
||||||
void view_focus(struct view *view)
|
void view_focus(struct view *view)
|
||||||
{
|
{
|
||||||
/* Note: this function only deals with keyboard focus. */
|
/* Note: this function only deals with keyboard focus. */
|
||||||
|
|
@ -183,27 +137,56 @@ void view_focus(struct view *view)
|
||||||
keyboard->num_keycodes,
|
keyboard->num_keycodes,
|
||||||
&keyboard->modifiers);
|
&keyboard->modifiers);
|
||||||
|
|
||||||
move_xwayland_decendants_to_front(view);
|
/* TODO: move xwayland decendants to front */
|
||||||
}
|
}
|
||||||
|
|
||||||
struct view *view_front_toplevel(struct server *server)
|
static struct view *first_view(void)
|
||||||
{
|
{
|
||||||
struct view *view;
|
struct view *view;
|
||||||
wl_list_for_each (view, &server->views, link) {
|
view = wl_container_of(server.views.next, view, link);
|
||||||
if (is_toplevel(view))
|
return view;
|
||||||
return view;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct view *next_toplevel(struct view *current)
|
/*
|
||||||
|
* Some xwayland apps produce unmapped surfaces on startup and also leave
|
||||||
|
* some unmapped surfaces kicking around on 'close' (for example * leafpad's
|
||||||
|
* "about" dialogue). Whilst this is not normally a problem, we have to be
|
||||||
|
* careful when cycling between views. The only view's we should focus are
|
||||||
|
* those that are already mapped and those that have been minimized.
|
||||||
|
*/
|
||||||
|
static bool isfocusable(struct view *view)
|
||||||
{
|
{
|
||||||
if (!current)
|
/* filter out those xwayland surfaces that have never been mapped */
|
||||||
|
if (!view->surface)
|
||||||
|
return false;
|
||||||
|
return (view->mapped || view->minimized);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int has_focusable_view(struct wl_list *wl_list)
|
||||||
|
{
|
||||||
|
struct view *view;
|
||||||
|
wl_list_for_each (view, wl_list, link) {
|
||||||
|
if (isfocusable(view))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return next view. If NULL provided, return second view from front.
|
||||||
|
*/
|
||||||
|
/* TODO: rename function */
|
||||||
|
struct view *view_next(struct view *current)
|
||||||
|
{
|
||||||
|
if (!has_focusable_view(&server.views))
|
||||||
return NULL;
|
return NULL;
|
||||||
struct view *view = current;
|
|
||||||
|
struct view *view = current ? current : first_view();
|
||||||
|
|
||||||
|
/* Replacement for wl_list_for_each_from() */
|
||||||
do {
|
do {
|
||||||
view = wl_container_of(view->link.next, view, link);
|
view = wl_container_of(view->link.next, view, link);
|
||||||
} while (!is_toplevel(view));
|
} while (&view->link == &server.views || !isfocusable(view));
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -148,7 +148,7 @@ static void xdg_toplevel_view_unmap(struct view *view)
|
||||||
{
|
{
|
||||||
view->mapped = false;
|
view->mapped = false;
|
||||||
wl_list_remove(&view->commit.link);
|
wl_list_remove(&view->commit.link);
|
||||||
view_focus(next_toplevel(view));
|
view_focus(view_next(view));
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct view_impl xdg_toplevel_view_impl = {
|
static const struct view_impl xdg_toplevel_view_impl = {
|
||||||
|
|
|
||||||
|
|
@ -57,8 +57,6 @@ static void _close(struct view *view)
|
||||||
|
|
||||||
static bool want_ssd(struct view *view)
|
static bool want_ssd(struct view *view)
|
||||||
{
|
{
|
||||||
if (view->xwayland_surface->override_redirect)
|
|
||||||
return false;
|
|
||||||
if (view->xwayland_surface->decorations !=
|
if (view->xwayland_surface->decorations !=
|
||||||
WLR_XWAYLAND_SURFACE_DECORATIONS_ALL)
|
WLR_XWAYLAND_SURFACE_DECORATIONS_ALL)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -89,7 +87,7 @@ static void unmap(struct view *view)
|
||||||
{
|
{
|
||||||
view->mapped = false;
|
view->mapped = false;
|
||||||
wl_list_remove(&view->commit.link);
|
wl_list_remove(&view->commit.link);
|
||||||
view_focus(next_toplevel(view));
|
view_focus(view_next(view));
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct view_impl xwl_view_impl = {
|
static const struct view_impl xwl_view_impl = {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue