509 lines
14 KiB
Diff
509 lines
14 KiB
Diff
From c3531efba873d603001a050a52895ab80e53f4ef Mon Sep 17 00:00:00 2001
|
|
From: Jeffy Chen <jeffy.chen@rock-chips.com>
|
|
Date: Thu, 7 May 2020 08:55:42 +0800
|
|
Subject: [PATCH 28/95] HACK: Support setting surface flags activate and alpha
|
|
|
|
Support setting surface flags activate and alpha through app_id or
|
|
title, for example:
|
|
|
|
xdg_toplevel_set_app_id("flags=stay-on-top|stay-on-bottom|no-focus")
|
|
xdg_toplevel_set_title("requests=activate")
|
|
xdg_toplevel_set_app_id("attrs=alpha:0.5")
|
|
|
|
Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
|
|
---
|
|
desktop-shell/shell.c | 58 ++++++++--
|
|
desktop-shell/shell.h | 2 +
|
|
include/libweston/libweston.h | 14 +++
|
|
libweston/compositor.c | 10 +-
|
|
libweston/desktop/surface.c | 195 ++++++++++++++++++++++++++++++++++
|
|
5 files changed, 267 insertions(+), 12 deletions(-)
|
|
|
|
diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c
|
|
index e7dca8f..971f07c 100644
|
|
--- a/desktop-shell/shell.c
|
|
+++ b/desktop-shell/shell.c
|
|
@@ -1711,10 +1711,17 @@ static void
|
|
shell_surface_update_layer(struct shell_surface *shsurf)
|
|
{
|
|
struct weston_layer_entry *new_layer_link;
|
|
+ struct weston_surface *surface =
|
|
+ weston_desktop_surface_get_surface(shsurf->desktop_surface);
|
|
|
|
new_layer_link = shell_surface_calculate_layer_link(shsurf);
|
|
assert(new_layer_link);
|
|
|
|
+ if (surface->flags & SURFACE_STAY_ON_TOP)
|
|
+ new_layer_link = &shsurf->shell->top_layer.view_list;
|
|
+ else if (surface->flags & SURFACE_STAY_ON_BOTTOM)
|
|
+ new_layer_link = &shsurf->shell->bottom_layer.view_list;
|
|
+
|
|
weston_view_move_to_layer(shsurf->view, new_layer_link);
|
|
shell_surface_update_child_surface_layers(shsurf);
|
|
}
|
|
@@ -1914,8 +1921,9 @@ shell_set_view_fullscreen(struct shell_surface *shsurf)
|
|
|
|
assert(weston_desktop_surface_get_fullscreen(shsurf->desktop_surface));
|
|
|
|
- weston_view_move_to_layer(shsurf->view,
|
|
- &shsurf->shell->fullscreen_layer.view_list);
|
|
+ shsurf->state.lowered = false;
|
|
+
|
|
+ shell_surface_update_layer(shsurf);
|
|
|
|
weston_shell_utils_center_on_output(shsurf->view, shsurf->output);
|
|
|
|
@@ -1923,12 +1931,11 @@ shell_set_view_fullscreen(struct shell_surface *shsurf)
|
|
shsurf->fullscreen.black_view =
|
|
weston_shell_utils_curtain_create(ec, &curtain_params);
|
|
}
|
|
+
|
|
weston_view_set_output(shsurf->fullscreen.black_view->view,
|
|
shsurf->fullscreen_output);
|
|
weston_view_move_to_layer(shsurf->fullscreen.black_view->view,
|
|
&shsurf->view->layer_link);
|
|
-
|
|
- shsurf->state.lowered = false;
|
|
}
|
|
|
|
static void
|
|
@@ -2378,6 +2385,17 @@ desktop_surface_committed(struct weston_desktop_surface *desktop_surface,
|
|
return;
|
|
}
|
|
|
|
+ if (surface->flags & SURFACE_ACTIVATE) {
|
|
+ struct weston_seat *seat;
|
|
+
|
|
+ surface->flags &= ~SURFACE_ACTIVATE;
|
|
+
|
|
+ wl_list_for_each(seat, &surface->compositor->seat_list,link) {
|
|
+ activate(shell, shsurf->view, seat,
|
|
+ WESTON_ACTIVATE_FLAG_CONFIGURE);
|
|
+ }
|
|
+ }
|
|
+
|
|
if (buf_offset.c.x == 0 && buf_offset.c.y == 0 &&
|
|
shsurf->last_width == surface->width &&
|
|
shsurf->last_height == surface->height &&
|
|
@@ -3105,6 +3123,10 @@ resume_desktop(struct desktop_shell *shell)
|
|
weston_layer_set_position(&shell->panel_layer,
|
|
WESTON_LAYER_POSITION_UI);
|
|
weston_layer_set_position(&ws->layer, WESTON_LAYER_POSITION_NORMAL);
|
|
+ weston_layer_set_position(&shell->top_layer,
|
|
+ WESTON_LAYER_POSITION_TOP_UI);
|
|
+ weston_layer_set_position(&shell->bottom_layer,
|
|
+ WESTON_LAYER_POSITION_BOTTOM_UI);
|
|
|
|
restore_focus_state(shell, get_current_workspace(shell));
|
|
|
|
@@ -3614,10 +3636,8 @@ void
|
|
lower_fullscreen_layer(struct desktop_shell *shell,
|
|
struct weston_output *lowering_output)
|
|
{
|
|
- struct workspace *ws;
|
|
struct weston_view *view, *prev;
|
|
|
|
- ws = get_current_workspace(shell);
|
|
wl_list_for_each_reverse_safe(view, prev,
|
|
&shell->fullscreen_layer.view_list.link,
|
|
layer_link.link) {
|
|
@@ -3635,10 +3655,10 @@ lower_fullscreen_layer(struct desktop_shell *shell,
|
|
if (shsurf->fullscreen.black_view)
|
|
weston_view_move_to_layer(shsurf->fullscreen.black_view->view, NULL);
|
|
|
|
- /* Lower the view to the workspace layer */
|
|
- weston_view_move_to_layer(view, &ws->layer.view_list);
|
|
-
|
|
shsurf->state.lowered = true;
|
|
+
|
|
+ /* Lower the view to the workspace layer */
|
|
+ shell_surface_update_layer(shsurf);
|
|
}
|
|
}
|
|
|
|
@@ -3662,7 +3682,7 @@ activate(struct desktop_shell *shell, struct weston_view *view,
|
|
struct weston_surface *main_surface;
|
|
struct focus_state *state;
|
|
struct workspace *ws;
|
|
- struct weston_surface *old_es;
|
|
+ struct weston_surface *old_es = NULL;
|
|
struct shell_surface *shsurf, *shsurf_child;
|
|
struct shell_seat *shseat = get_shell_seat(seat);
|
|
|
|
@@ -3682,6 +3702,9 @@ activate(struct desktop_shell *shell, struct weston_view *view,
|
|
if (shsurf->output)
|
|
lower_fullscreen_layer(shell, shsurf->output);
|
|
|
|
+ if (view->surface->flags & SURFACE_NO_FOCUS)
|
|
+ goto no_focus;
|
|
+
|
|
weston_view_activate_input(view, seat, flags);
|
|
|
|
if (shseat && shseat->focused_surface &&
|
|
@@ -3704,6 +3727,7 @@ activate(struct desktop_shell *shell, struct weston_view *view,
|
|
old_es = state->keyboard_focus;
|
|
focus_state_set_focus(state, es);
|
|
|
|
+no_focus:
|
|
if (weston_desktop_surface_get_fullscreen(shsurf->desktop_surface) &&
|
|
flags & WESTON_ACTIVATE_FLAG_CONFIGURE)
|
|
shell_set_view_fullscreen(shsurf);
|
|
@@ -3712,7 +3736,7 @@ activate(struct desktop_shell *shell, struct weston_view *view,
|
|
* order as appropriate. */
|
|
shell_surface_update_layer(shsurf);
|
|
|
|
- if (shell->focus_animation_type != ANIMATION_NONE) {
|
|
+ if (old_es && shell->focus_animation_type != ANIMATION_NONE) {
|
|
assert(shell->focus_animation_type == ANIMATION_DIM_LAYER);
|
|
ws = get_current_workspace(shell);
|
|
animate_focus_change(shell, ws, get_default_view(old_es), get_default_view(es));
|
|
@@ -3821,6 +3845,8 @@ lock(struct desktop_shell *shell)
|
|
if (shell->showing_input_panels)
|
|
weston_layer_unset_position(&shell->input_panel_layer);
|
|
weston_layer_unset_position(&ws->layer);
|
|
+ weston_layer_unset_position(&shell->top_layer);
|
|
+ weston_layer_unset_position(&shell->bottom_layer);
|
|
|
|
weston_layer_set_position(&shell->lock_layer,
|
|
WESTON_LAYER_POSITION_LOCK);
|
|
@@ -4598,6 +4624,8 @@ shell_for_each_layer(struct desktop_shell *shell,
|
|
func(shell, &shell->lock_layer, data);
|
|
func(shell, &shell->input_panel_layer, data);
|
|
func(shell, &shell->workspace.layer, data);
|
|
+ func(shell, &shell->top_layer, data);
|
|
+ func(shell, &shell->bottom_layer, data);
|
|
}
|
|
|
|
static void
|
|
@@ -4898,6 +4926,8 @@ shell_destroy(struct wl_listener *listener, void *data)
|
|
|
|
workspace_destroy(&shell->workspace);
|
|
|
|
+ desktop_shell_destroy_layer(&shell->bottom_layer);
|
|
+ desktop_shell_destroy_layer(&shell->top_layer);
|
|
desktop_shell_destroy_layer(&shell->panel_layer);
|
|
desktop_shell_destroy_layer(&shell->background_layer);
|
|
desktop_shell_destroy_layer(&shell->lock_layer);
|
|
@@ -5056,6 +5086,8 @@ wet_shell_init(struct weston_compositor *ec,
|
|
weston_layer_init(&shell->background_layer, ec);
|
|
weston_layer_init(&shell->lock_layer, ec);
|
|
weston_layer_init(&shell->input_panel_layer, ec);
|
|
+ weston_layer_init(&shell->top_layer, ec);
|
|
+ weston_layer_init(&shell->bottom_layer, ec);
|
|
|
|
weston_layer_set_position(&shell->fullscreen_layer,
|
|
WESTON_LAYER_POSITION_FULLSCREEN);
|
|
@@ -5063,6 +5095,10 @@ wet_shell_init(struct weston_compositor *ec,
|
|
WESTON_LAYER_POSITION_UI);
|
|
weston_layer_set_position(&shell->background_layer,
|
|
WESTON_LAYER_POSITION_BACKGROUND);
|
|
+ weston_layer_set_position(&shell->top_layer,
|
|
+ WESTON_LAYER_POSITION_TOP_UI);
|
|
+ weston_layer_set_position(&shell->bottom_layer,
|
|
+ WESTON_LAYER_POSITION_BOTTOM_UI);
|
|
|
|
wl_list_init(&shell->seat_list);
|
|
wl_list_init(&shell->shsurf_list);
|
|
diff --git a/desktop-shell/shell.h b/desktop-shell/shell.h
|
|
index fc34eb4..055fe97 100644
|
|
--- a/desktop-shell/shell.h
|
|
+++ b/desktop-shell/shell.h
|
|
@@ -97,6 +97,8 @@ struct desktop_shell {
|
|
struct weston_layer background_layer;
|
|
struct weston_layer lock_layer;
|
|
struct weston_layer input_panel_layer;
|
|
+ struct weston_layer top_layer;
|
|
+ struct weston_layer bottom_layer;
|
|
|
|
struct wl_listener pointer_focus_listener;
|
|
struct weston_surface *grab_surface;
|
|
diff --git a/include/libweston/libweston.h b/include/libweston/libweston.h
|
|
index e9e74ba..5342af8 100644
|
|
--- a/include/libweston/libweston.h
|
|
+++ b/include/libweston/libweston.h
|
|
@@ -1978,6 +1978,15 @@ struct weston_pointer_constraint {
|
|
struct wl_listener surface_activate_listener;
|
|
};
|
|
|
|
+enum weston_surface_flags {
|
|
+ SURFACE_NO_FOCUS = 1 << 0,
|
|
+ SURFACE_STAY_ON_TOP = 1 << 1,
|
|
+ SURFACE_STAY_ON_BOTTOM = 1 << 2,
|
|
+ SURFACE_BLOCKED = 1 << 3,
|
|
+ SURFACE_TRANS_INPUT = 1 << 4,
|
|
+ SURFACE_ACTIVATE = 1 << 5,
|
|
+};
|
|
+
|
|
struct weston_surface {
|
|
struct wl_resource *resource;
|
|
struct wl_signal destroy_signal; /* callback argument: this surface */
|
|
@@ -2102,6 +2111,11 @@ struct weston_surface {
|
|
* this list. */
|
|
struct wl_list cm_feedback_surface_resource_list;
|
|
struct wl_resource *cm_surface;
|
|
+
|
|
+ /* Hacky surface flags */
|
|
+ enum weston_surface_flags flags;
|
|
+
|
|
+ double alpha;
|
|
};
|
|
|
|
struct weston_subsurface {
|
|
diff --git a/libweston/compositor.c b/libweston/compositor.c
|
|
index d888bb0..463e211 100644
|
|
--- a/libweston/compositor.c
|
|
+++ b/libweston/compositor.c
|
|
@@ -727,7 +727,7 @@ weston_view_create_internal(struct weston_surface *surface)
|
|
|
|
pixman_region32_init(&view->visible);
|
|
|
|
- view->alpha = 1.0;
|
|
+ view->alpha = surface->alpha;
|
|
pixman_region32_init(&view->transform.opaque);
|
|
|
|
wl_list_init(&view->geometry.transformation_list);
|
|
@@ -1032,6 +1032,8 @@ weston_surface_create(struct weston_compositor *compositor)
|
|
surface->compositor = compositor;
|
|
surface->ref_count = 1;
|
|
|
|
+ surface->alpha = 1.0;
|
|
+
|
|
surface->buffer_viewport.buffer.transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
|
surface->buffer_viewport.buffer.scale = 1;
|
|
surface->buffer_viewport.buffer.src_width = wl_fixed_from_int(-1);
|
|
@@ -2660,6 +2662,12 @@ weston_compositor_pick_view(struct weston_compositor *compositor,
|
|
if (!weston_view_takes_input_at_point(view, surf_pos))
|
|
continue;
|
|
|
|
+ if (view->surface->flags & SURFACE_BLOCKED)
|
|
+ break;
|
|
+
|
|
+ if (view->surface->flags & SURFACE_TRANS_INPUT)
|
|
+ continue;
|
|
+
|
|
return view;
|
|
}
|
|
return NULL;
|
|
diff --git a/libweston/desktop/surface.c b/libweston/desktop/surface.c
|
|
index d365d95..2ab99ef 100644
|
|
--- a/libweston/desktop/surface.c
|
|
+++ b/libweston/desktop/surface.c
|
|
@@ -755,12 +755,204 @@ weston_desktop_surface_set_position(struct weston_desktop_surface *surface,
|
|
weston_view_set_position(view->view, pos);
|
|
}
|
|
|
|
+static bool
|
|
+weston_desktop_surface_set_flags(struct weston_desktop_surface *surface,
|
|
+ char *s)
|
|
+{
|
|
+ struct weston_surface *wsurface = surface->surface;
|
|
+ char *p;
|
|
+
|
|
+#define SURFACE_FLAG_PREFIX "flags="
|
|
+ s = strstr(s, SURFACE_FLAG_PREFIX);
|
|
+ if (!s)
|
|
+ return false;
|
|
+
|
|
+ s += strlen(SURFACE_FLAG_PREFIX);
|
|
+
|
|
+ p = strtok(s, "|");
|
|
+ while (p) {
|
|
+ enum weston_surface_flags flag = 0;
|
|
+ bool clear = false;
|
|
+
|
|
+ switch (p[0]) {
|
|
+ case ';':
|
|
+ /* fall through */
|
|
+ case '&':
|
|
+ return true;
|
|
+ case '-':
|
|
+ clear = true;
|
|
+ /* fall through */
|
|
+ case '+':
|
|
+ p++;
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ if (!strcmp(p, "no-focus"))
|
|
+ flag = SURFACE_NO_FOCUS;
|
|
+ else if (!strcmp(p, "stay-on-top"))
|
|
+ flag = SURFACE_STAY_ON_TOP;
|
|
+ else if (!strcmp(p, "stay-on-bottom"))
|
|
+ flag = SURFACE_STAY_ON_BOTTOM;
|
|
+ else if (!strcmp(p, "blocked"))
|
|
+ flag = SURFACE_BLOCKED;
|
|
+ else if (!strcmp(p, "trans-input"))
|
|
+ flag = SURFACE_TRANS_INPUT;
|
|
+ else
|
|
+ weston_log("%s: warning: unsupported flag: %s\n",
|
|
+ __func__, p);
|
|
+
|
|
+ if (clear)
|
|
+ wsurface->flags &= ~flag;
|
|
+ else
|
|
+ wsurface->flags |= flag;
|
|
+
|
|
+ p = strtok(NULL, "|");
|
|
+ };
|
|
+
|
|
+ return true;
|
|
+}
|
|
+
|
|
+static bool
|
|
+weston_desktop_surface_set_requests(struct weston_desktop_surface *surface,
|
|
+ char *s)
|
|
+{
|
|
+ struct weston_surface *wsurface = surface->surface;
|
|
+ char *p;
|
|
+
|
|
+#define SURFACE_REQUEST_PREFIX "requests="
|
|
+ s = strstr(s, SURFACE_REQUEST_PREFIX);
|
|
+ if (!s)
|
|
+ return false;
|
|
+
|
|
+ s += strlen(SURFACE_REQUEST_PREFIX);
|
|
+
|
|
+ p = strtok(s, "|");
|
|
+ while (p) {
|
|
+ switch (p[0]) {
|
|
+ case ';':
|
|
+ /* fall through */
|
|
+ case '&':
|
|
+ return true;
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ if (!strcmp(p, "activate")) {
|
|
+ struct weston_coord_surface zero;
|
|
+
|
|
+ wsurface->flags |= SURFACE_ACTIVATE;
|
|
+
|
|
+ zero = weston_coord_surface(0, 0, wsurface);
|
|
+ weston_desktop_api_committed(surface->desktop,
|
|
+ surface, zero);
|
|
+ } else {
|
|
+ weston_log("%s: warning: unsupported request: %s\n",
|
|
+ __func__, p);
|
|
+ }
|
|
+
|
|
+ p = strtok(NULL, "|");
|
|
+ };
|
|
+
|
|
+ return true;
|
|
+}
|
|
+
|
|
+static void
|
|
+weston_surface_set_alpha(struct weston_surface *wsurface, float alpha)
|
|
+{
|
|
+ struct weston_subsurface *sub;
|
|
+ struct weston_view *view;
|
|
+
|
|
+ wsurface->alpha = alpha;
|
|
+ wsurface->is_opaque = !(alpha < 1.0);
|
|
+
|
|
+ wl_list_for_each(view, &wsurface->views,
|
|
+ surface_link) {
|
|
+ view->alpha = alpha;
|
|
+ weston_view_geometry_dirty(view);
|
|
+ }
|
|
+
|
|
+ wl_list_for_each(sub, &wsurface->subsurface_list,
|
|
+ parent_link) {
|
|
+ if (sub->surface != wsurface)
|
|
+ weston_surface_set_alpha(sub->surface, alpha);
|
|
+ }
|
|
+}
|
|
+
|
|
+static bool
|
|
+weston_desktop_surface_set_attrs(struct weston_desktop_surface *surface,
|
|
+ char *s)
|
|
+{
|
|
+ struct weston_surface *wsurface = surface->surface;
|
|
+ char *p;
|
|
+
|
|
+#define SURFACE_ATTRS_PREFIX "attrs="
|
|
+ s = strstr(s, SURFACE_ATTRS_PREFIX);
|
|
+ if (!s)
|
|
+ return false;
|
|
+
|
|
+ s += strlen(SURFACE_ATTRS_PREFIX);
|
|
+
|
|
+ p = strtok(s, "|");
|
|
+ while (p) {
|
|
+ switch (p[0]) {
|
|
+ case ';':
|
|
+ /* fall through */
|
|
+ case '&':
|
|
+ return true;
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+
|
|
+#define SURFACE_ATTR_ALPHA "alpha:"
|
|
+ if (!strncmp(p, SURFACE_ATTR_ALPHA,
|
|
+ strlen(SURFACE_ATTR_ALPHA))) {
|
|
+ double alpha = atof(p + strlen(SURFACE_ATTR_ALPHA));
|
|
+
|
|
+ weston_surface_set_alpha(wsurface, alpha);
|
|
+ } else {
|
|
+ weston_log("%s: warning: unsupported attr: %s\n",
|
|
+ __func__, p);
|
|
+ }
|
|
+
|
|
+ p = strtok(NULL, "|");
|
|
+ };
|
|
+
|
|
+ return true;
|
|
+}
|
|
+
|
|
+static bool
|
|
+weston_desktop_surface_handle_config(struct weston_desktop_surface *surface,
|
|
+ const char *s)
|
|
+{
|
|
+ char *tmp;
|
|
+ bool handled = false;
|
|
+
|
|
+ tmp = strdup(s);
|
|
+ if (tmp == NULL)
|
|
+ return false;
|
|
+
|
|
+ handled |= weston_desktop_surface_set_flags(surface, tmp);
|
|
+
|
|
+ strcpy(tmp, s);
|
|
+ handled |= weston_desktop_surface_set_requests(surface, tmp);
|
|
+
|
|
+ strcpy(tmp, s);
|
|
+ handled |= weston_desktop_surface_set_attrs(surface, tmp);
|
|
+
|
|
+ free(tmp);
|
|
+ return handled;
|
|
+}
|
|
+
|
|
void
|
|
weston_desktop_surface_set_title(struct weston_desktop_surface *surface,
|
|
const char *title)
|
|
{
|
|
char *tmp, *old;
|
|
|
|
+ if (weston_desktop_surface_handle_config(surface, title))
|
|
+ return;
|
|
+
|
|
tmp = strdup(title);
|
|
if (tmp == NULL)
|
|
return;
|
|
@@ -777,6 +969,9 @@ weston_desktop_surface_set_app_id(struct weston_desktop_surface *surface,
|
|
{
|
|
char *tmp, *old;
|
|
|
|
+ if (weston_desktop_surface_handle_config(surface, app_id))
|
|
+ return;
|
|
+
|
|
tmp = strdup(app_id);
|
|
if (tmp == NULL)
|
|
return;
|
|
--
|
|
2.20.1
|
|
|