mirror of
https://github.com/labwc/labwc.git
synced 2026-03-11 05:33:49 -04:00
view: add view_array_append()
...to reduce code duplication. The function populates an array with views which meet any set of critera from: - current-workspace - no-always-on-top - no-skipWindowSwitcher (window-rule) Make src/osd.c use this new interface. Note that always-on-top views are still filtered out from the window-switcher and that desktop_cycle_view() needs to be re-worked before always-on-top views can be opted in.
This commit is contained in:
parent
58b33fb0c9
commit
57b9efeb45
4 changed files with 103 additions and 35 deletions
|
|
@ -168,6 +168,36 @@ struct xdg_toplevel_view {
|
||||||
struct wl_listener new_popup;
|
struct wl_listener new_popup;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum lab_view_criteria {
|
||||||
|
LAB_VIEW_CRITERIA_ALL = 0,
|
||||||
|
LAB_VIEW_CRITERIA_CURRENT_WORKSPACE = 1 << 0,
|
||||||
|
LAB_VIEW_CRITERIA_NO_ALWAYS_ON_TOP = 1 << 1,
|
||||||
|
LAB_VIEW_CRITERIA_NO_SKIP_WINDOW_SWITCHER = 1 << 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* view_array_append - append views that match criteria to array
|
||||||
|
* @server: server context
|
||||||
|
* @views: arrays to append to
|
||||||
|
* @criteria: criteria to match against
|
||||||
|
*
|
||||||
|
* Note: This array has a very short shelf-life so it is intended to be used
|
||||||
|
* with a single-use-throw-away approach.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
*
|
||||||
|
* struct view **view;
|
||||||
|
* struct wl_array views;
|
||||||
|
* wl_array_init(&views);
|
||||||
|
* view_array_append(server, &views, LAB_VIEW_CRITERIA_CURRENT_WORKSPACE);
|
||||||
|
* wl_array_for_each(view, &views) {
|
||||||
|
* // Do something with *view
|
||||||
|
* }
|
||||||
|
* wl_array_release(&views);
|
||||||
|
*/
|
||||||
|
void view_array_append(struct server *server, struct wl_array *views,
|
||||||
|
enum lab_view_criteria criteria);
|
||||||
|
|
||||||
bool view_inhibits_keybinds(struct view *view);
|
bool view_inhibits_keybinds(struct view *view);
|
||||||
void view_toggle_keybinds(struct view *view);
|
void view_toggle_keybinds(struct view *view);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -435,3 +435,4 @@ get_cursor_context(struct server *server)
|
||||||
wlr_log(WLR_ERROR, "Unknown node detected");
|
wlr_log(WLR_ERROR, "Unknown node detected");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
64
src/osd.c
64
src/osd.c
|
|
@ -258,12 +258,11 @@ get_title(struct view *view)
|
||||||
static void
|
static void
|
||||||
render_osd(struct server *server, cairo_t *cairo, int w, int h,
|
render_osd(struct server *server, cairo_t *cairo, int w, int h,
|
||||||
struct wl_list *node_list, bool show_workspace,
|
struct wl_list *node_list, bool show_workspace,
|
||||||
const char *workspace_name)
|
const char *workspace_name, enum lab_view_criteria criteria)
|
||||||
{
|
{
|
||||||
struct view *cycle_view = server->osd_state.cycle_view;
|
struct view *cycle_view = server->osd_state.cycle_view;
|
||||||
struct theme *theme = server->theme;
|
struct theme *theme = server->theme;
|
||||||
|
|
||||||
struct wlr_scene_node *node;
|
|
||||||
cairo_surface_t *surf = cairo_get_target(cairo);
|
cairo_surface_t *surf = cairo_get_target(cairo);
|
||||||
|
|
||||||
/* Draw background */
|
/* Draw background */
|
||||||
|
|
@ -317,17 +316,11 @@ render_osd(struct server *server, cairo_t *cairo, int w, int h,
|
||||||
- 2 * theme->osd_window_switcher_item_active_border_width;
|
- 2 * theme->osd_window_switcher_item_active_border_width;
|
||||||
|
|
||||||
/* Draw text for each node */
|
/* Draw text for each node */
|
||||||
wl_list_for_each_reverse(node, node_list, link) {
|
struct view **view;
|
||||||
if (!node->data) {
|
struct wl_array views;
|
||||||
/* We found some non-view, most likely the region overlay */
|
wl_array_init(&views);
|
||||||
continue;
|
desktop_views_append(server, &views, criteria);
|
||||||
}
|
wl_array_for_each(view, &views) {
|
||||||
struct view *view = node_view_from_node(node);
|
|
||||||
enum property skip = window_rules_get_property(view, "skipWindowSwitcher");
|
|
||||||
if (!isfocusable(view) || skip == LAB_PROP_TRUE) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* OSD border
|
* OSD border
|
||||||
* +---------------------------------+
|
* +---------------------------------+
|
||||||
|
|
@ -359,13 +352,13 @@ render_osd(struct server *server, cairo_t *cairo, int w, int h,
|
||||||
|
|
||||||
switch (field->content) {
|
switch (field->content) {
|
||||||
case LAB_FIELD_TYPE:
|
case LAB_FIELD_TYPE:
|
||||||
buf_add(&buf, get_type(view));
|
buf_add(&buf, get_type(*view));
|
||||||
break;
|
break;
|
||||||
case LAB_FIELD_APP_ID:
|
case LAB_FIELD_APP_ID:
|
||||||
buf_add(&buf, get_app_id(view));
|
buf_add(&buf, get_app_id(*view));
|
||||||
break;
|
break;
|
||||||
case LAB_FIELD_TITLE:
|
case LAB_FIELD_TITLE:
|
||||||
buf_add(&buf, get_title(view));
|
buf_add(&buf, get_title(*view));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
@ -379,7 +372,7 @@ render_osd(struct server *server, cairo_t *cairo, int w, int h,
|
||||||
x += field_width + theme->osd_window_switcher_item_padding_x;
|
x += field_width + theme->osd_window_switcher_item_padding_x;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (view == cycle_view) {
|
if (*view == cycle_view) {
|
||||||
/* Highlight current window */
|
/* Highlight current window */
|
||||||
struct wlr_fbox fbox = {
|
struct wlr_fbox fbox = {
|
||||||
.x = theme->osd_border_width + theme->osd_window_switcher_padding,
|
.x = theme->osd_border_width + theme->osd_window_switcher_padding,
|
||||||
|
|
@ -398,30 +391,23 @@ render_osd(struct server *server, cairo_t *cairo, int w, int h,
|
||||||
}
|
}
|
||||||
free(buf.buf);
|
free(buf.buf);
|
||||||
g_object_unref(layout);
|
g_object_unref(layout);
|
||||||
|
wl_array_release(&views);
|
||||||
|
|
||||||
cairo_surface_flush(surf);
|
cairo_surface_flush(surf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
get_osd_height(struct wl_list *node_list)
|
get_osd_height(struct server *server, enum lab_view_criteria criteria)
|
||||||
{
|
{
|
||||||
int height = 0;
|
int height = 0;
|
||||||
struct view *view;
|
struct wl_array views;
|
||||||
struct wlr_scene_node *node;
|
wl_array_init(&views);
|
||||||
wl_list_for_each(node, node_list, link) {
|
desktop_views_append(server, &views, criteria);
|
||||||
if (!node->data) {
|
|
||||||
/* We found some non-view, most likely the region overlay */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
view = node_view_from_node(node);
|
|
||||||
enum property skip = window_rules_get_property(view, "skipWindowSwitcher");
|
|
||||||
if (!isfocusable(view) || skip == LAB_PROP_TRUE) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Include item border width */
|
/* Includes item border width */
|
||||||
height += rc.theme->osd_window_switcher_item_height;
|
size_t len = views.size / sizeof(struct view *);
|
||||||
}
|
height += len * rc.theme->osd_window_switcher_item_height;
|
||||||
|
wl_array_release(&views);
|
||||||
|
|
||||||
/* Add OSD border width */
|
/* Add OSD border width */
|
||||||
height += 2 * rc.theme->osd_border_width;
|
height += 2 * rc.theme->osd_border_width;
|
||||||
|
|
@ -439,9 +425,16 @@ display_osd(struct output *output)
|
||||||
bool show_workspace = wl_list_length(&rc.workspace_config.workspaces) > 1;
|
bool show_workspace = wl_list_length(&rc.workspace_config.workspaces) > 1;
|
||||||
const char *workspace_name = server->workspace_current->name;
|
const char *workspace_name = server->workspace_current->name;
|
||||||
|
|
||||||
|
struct wl_array views;
|
||||||
|
wl_array_init(&views);
|
||||||
|
view_array_append(server, &views,
|
||||||
|
LAB_VIEW_CRITERIA_CURRENT_WORKSPACE
|
||||||
|
| LAB_VIEW_CRITERIA_NO_ALWAYS_ON_TOP
|
||||||
|
| LAB_VIEW_CRITERIA_NO_SKIP_WINDOW_SWITCHER);
|
||||||
|
|
||||||
float scale = output->wlr_output->scale;
|
float scale = output->wlr_output->scale;
|
||||||
int w = theme->osd_window_switcher_width;
|
int w = theme->osd_window_switcher_width;
|
||||||
int h = get_osd_height(node_list);
|
int h = get_osd_height(server, criteria);
|
||||||
if (show_workspace) {
|
if (show_workspace) {
|
||||||
/* workspace indicator */
|
/* workspace indicator */
|
||||||
h += theme->osd_window_switcher_item_height;
|
h += theme->osd_window_switcher_item_height;
|
||||||
|
|
@ -455,7 +448,8 @@ display_osd(struct output *output)
|
||||||
|
|
||||||
/* Render OSD image */
|
/* Render OSD image */
|
||||||
cairo_t *cairo = output->osd_buffer->cairo;
|
cairo_t *cairo = output->osd_buffer->cairo;
|
||||||
render_osd(server, cairo, w, h, node_list, show_workspace, workspace_name);
|
render_osd(server, cairo, w, h, node_list, show_workspace,
|
||||||
|
workspace_name, criteria);
|
||||||
|
|
||||||
struct wlr_scene_buffer *scene_buffer = wlr_scene_buffer_create(
|
struct wlr_scene_buffer *scene_buffer = wlr_scene_buffer_create(
|
||||||
output->osd_tree, &output->osd_buffer->base);
|
output->osd_tree, &output->osd_buffer->base);
|
||||||
|
|
|
||||||
43
src/view.c
43
src/view.c
|
|
@ -19,6 +19,48 @@
|
||||||
#define LAB_FALLBACK_WIDTH 640
|
#define LAB_FALLBACK_WIDTH 640
|
||||||
#define LAB_FALLBACK_HEIGHT 480
|
#define LAB_FALLBACK_HEIGHT 480
|
||||||
|
|
||||||
|
void
|
||||||
|
view_array_append(struct server *server, struct wl_array *views,
|
||||||
|
enum lab_view_criteria criteria)
|
||||||
|
{
|
||||||
|
struct view *view;
|
||||||
|
wl_list_for_each(view, &server->views, link)
|
||||||
|
{
|
||||||
|
if (!isfocusable(view)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (criteria & LAB_VIEW_CRITERIA_CURRENT_WORKSPACE) {
|
||||||
|
/*
|
||||||
|
* Always-on-top views are always on the current
|
||||||
|
* desktop and are special in that they live in a
|
||||||
|
* different tree.
|
||||||
|
*/
|
||||||
|
if (view_is_always_on_top(view)) {
|
||||||
|
goto next;
|
||||||
|
}
|
||||||
|
if (view->scene_tree->node.parent != server->workspace_current->tree) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
next:
|
||||||
|
if (criteria & LAB_VIEW_CRITERIA_NO_ALWAYS_ON_TOP) {
|
||||||
|
if (view_is_always_on_top(view)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (criteria & LAB_VIEW_CRITERIA_NO_SKIP_WINDOW_SWITCHER) {
|
||||||
|
if (window_rules_get_property(view, "skipWindowSwitcher")
|
||||||
|
== LAB_PROP_TRUE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct view **entry = wl_array_add(views, sizeof(*entry));
|
||||||
|
*entry = view;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All view_apply_xxx_geometry() functions must *not* modify
|
* All view_apply_xxx_geometry() functions must *not* modify
|
||||||
* any state besides repositioning or resizing the view.
|
* any state besides repositioning or resizing the view.
|
||||||
|
|
@ -1264,3 +1306,4 @@ view_destroy(struct view *view)
|
||||||
cursor_update_focus(server);
|
cursor_update_focus(server);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue