1From c4b8f02cca601a25767de29392940f0dc5ef2e24 Mon Sep 17 00:00:00 2001 2From: Jeffy Chen <jeffy.chen@rock-chips.com> 3Date: Thu, 7 May 2020 08:55:42 +0800 4Subject: [PATCH 20/79] HACK: Support setting surface flags activate and alpha 5 6Support setting surface flags activate and alpha through app_id or 7title, for example: 8 9xdg_toplevel_set_app_id("flags=stay-on-top|stay-on-bottom|no-focus") 10xdg_toplevel_set_title("requests=activate") 11xdg_toplevel_set_app_id("attrs=alpha:0.5") 12 13Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com> 14--- 15 desktop-shell/shell.c | 29 ++++- 16 desktop-shell/shell.h | 2 + 17 include/libweston/libweston.h | 13 +++ 18 libweston-desktop/surface.c | 193 ++++++++++++++++++++++++++++++++++ 19 libweston/compositor.c | 10 +- 20 5 files changed, 244 insertions(+), 3 deletions(-) 21 22diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c 23index 8b4ed45..4cb29dd 100644 24--- a/desktop-shell/shell.c 25+++ b/desktop-shell/shell.c 26@@ -1895,6 +1895,11 @@ shell_surface_update_layer(struct shell_surface *shsurf) 27 28 new_layer_link = shell_surface_calculate_layer_link(shsurf); 29 30+ if (surface->flags & SURFACE_STAY_ON_TOP) 31+ new_layer_link = &shsurf->shell->top_layer.view_list; 32+ else if (surface->flags & SURFACE_STAY_ON_BOTTOM) 33+ new_layer_link = &shsurf->shell->bottom_layer.view_list; 34+ 35 if (new_layer_link == NULL) 36 return; 37 if (new_layer_link == &shsurf->view->layer_link) 38@@ -3220,6 +3225,10 @@ resume_desktop(struct desktop_shell *shell) 39 weston_layer_set_position(&shell->panel_layer, 40 WESTON_LAYER_POSITION_UI); 41 weston_layer_set_position(&ws->layer, WESTON_LAYER_POSITION_NORMAL); 42+ weston_layer_set_position(&shell->top_layer, 43+ WESTON_LAYER_POSITION_TOP_UI); 44+ weston_layer_set_position(&shell->bottom_layer, 45+ WESTON_LAYER_POSITION_BOTTOM_UI); 46 47 restore_focus_state(shell, get_current_workspace(shell)); 48 49@@ -3781,7 +3790,7 @@ activate(struct desktop_shell *shell, struct weston_view *view, 50 struct weston_surface *main_surface; 51 struct focus_state *state; 52 struct workspace *ws; 53- struct weston_surface *old_es; 54+ struct weston_surface *old_es = NULL; 55 struct shell_surface *shsurf, *shsurf_child; 56 struct shell_seat *shseat = get_shell_seat(seat); 57 58@@ -3801,6 +3810,9 @@ activate(struct desktop_shell *shell, struct weston_view *view, 59 if (shsurf->output) 60 lower_fullscreen_layer(shell, shsurf->output); 61 62+ if (view->surface->flags & SURFACE_NO_FOCUS) 63+ goto no_focus; 64+ 65 weston_view_activate_input(view, seat, flags); 66 67 if (shseat && shseat->focused_surface) { 68@@ -3821,6 +3833,7 @@ activate(struct desktop_shell *shell, struct weston_view *view, 69 old_es = state->keyboard_focus; 70 focus_state_set_focus(state, es); 71 72+no_focus: 73 if (weston_desktop_surface_get_fullscreen(shsurf->desktop_surface) && 74 flags & WESTON_ACTIVATE_FLAG_CONFIGURE) 75 shell_configure_fullscreen(shsurf); 76@@ -3829,7 +3842,7 @@ activate(struct desktop_shell *shell, struct weston_view *view, 77 * order as appropriate. */ 78 shell_surface_update_layer(shsurf); 79 80- if (shell->focus_animation_type != ANIMATION_NONE) { 81+ if (old_es && shell->focus_animation_type != ANIMATION_NONE) { 82 ws = get_current_workspace(shell); 83 animate_focus_change(shell, ws, get_default_view(old_es), get_default_view(es)); 84 } 85@@ -3942,6 +3955,8 @@ lock(struct desktop_shell *shell) 86 if (shell->showing_input_panels) 87 weston_layer_unset_position(&shell->input_panel_layer); 88 weston_layer_unset_position(&ws->layer); 89+ weston_layer_unset_position(&shell->top_layer); 90+ weston_layer_unset_position(&shell->bottom_layer); 91 92 weston_layer_set_position(&shell->lock_layer, 93 WESTON_LAYER_POSITION_LOCK); 94@@ -4822,6 +4837,8 @@ shell_for_each_layer(struct desktop_shell *shell, 95 func(shell, &shell->background_layer, data); 96 func(shell, &shell->lock_layer, data); 97 func(shell, &shell->input_panel_layer, data); 98+ func(shell, &shell->top_layer, data); 99+ func(shell, &shell->bottom_layer, data); 100 101 wl_array_for_each(ws, &shell->workspaces.array) 102 func(shell, &(*ws)->layer, data); 103@@ -5115,6 +5132,8 @@ shell_destroy(struct wl_listener *listener, void *data) 104 workspace_destroy(*ws); 105 wl_array_release(&shell->workspaces.array); 106 107+ desktop_shell_destroy_layer(&shell->bottom_layer); 108+ desktop_shell_destroy_layer(&shell->top_layer); 109 desktop_shell_destroy_layer(&shell->panel_layer); 110 desktop_shell_destroy_layer(&shell->background_layer); 111 desktop_shell_destroy_layer(&shell->lock_layer); 112@@ -5270,6 +5289,8 @@ wet_shell_init(struct weston_compositor *ec, 113 weston_layer_init(&shell->background_layer, ec); 114 weston_layer_init(&shell->lock_layer, ec); 115 weston_layer_init(&shell->input_panel_layer, ec); 116+ weston_layer_init(&shell->top_layer, ec); 117+ weston_layer_init(&shell->bottom_layer, ec); 118 119 weston_layer_set_position(&shell->fullscreen_layer, 120 WESTON_LAYER_POSITION_FULLSCREEN); 121@@ -5277,6 +5298,10 @@ wet_shell_init(struct weston_compositor *ec, 122 WESTON_LAYER_POSITION_UI); 123 weston_layer_set_position(&shell->background_layer, 124 WESTON_LAYER_POSITION_BACKGROUND); 125+ weston_layer_set_position(&shell->top_layer, 126+ WESTON_LAYER_POSITION_TOP_UI); 127+ weston_layer_set_position(&shell->bottom_layer, 128+ WESTON_LAYER_POSITION_BOTTOM_UI); 129 130 wl_array_init(&shell->workspaces.array); 131 wl_list_init(&shell->workspaces.client_list); 132diff --git a/desktop-shell/shell.h b/desktop-shell/shell.h 133index b06b906..e0a0620 100644 134--- a/desktop-shell/shell.h 135+++ b/desktop-shell/shell.h 136@@ -148,6 +148,8 @@ struct desktop_shell { 137 struct weston_layer background_layer; 138 struct weston_layer lock_layer; 139 struct weston_layer input_panel_layer; 140+ struct weston_layer top_layer; 141+ struct weston_layer bottom_layer; 142 143 struct wl_listener pointer_focus_listener; 144 struct weston_surface *grab_surface; 145diff --git a/include/libweston/libweston.h b/include/libweston/libweston.h 146index 24e44a2..7bc01e3 100644 147--- a/include/libweston/libweston.h 148+++ b/include/libweston/libweston.h 149@@ -1469,6 +1469,14 @@ struct weston_pointer_constraint { 150 struct wl_listener surface_activate_listener; 151 }; 152 153+enum weston_surface_flags { 154+ SURFACE_NO_FOCUS = 1 << 0, 155+ SURFACE_STAY_ON_TOP = 1 << 1, 156+ SURFACE_STAY_ON_BOTTOM = 1 << 2, 157+ SURFACE_BLOCKED = 1 << 3, 158+ SURFACE_TRANS_INPUT = 1 << 4, 159+}; 160+ 161 struct weston_surface { 162 struct wl_resource *resource; 163 struct wl_signal destroy_signal; /* callback argument: this surface */ 164@@ -1575,6 +1583,11 @@ struct weston_surface { 165 166 /* Transparent hole region(excluding it's lower subsurface area) */ 167 pixman_region32_t hole; 168+ 169+ /* Hacky surface flags */ 170+ enum weston_surface_flags flags; 171+ 172+ double alpha; 173 }; 174 175 struct weston_subsurface { 176diff --git a/libweston-desktop/surface.c b/libweston-desktop/surface.c 177index 21ff080..e86ef52 100644 178--- a/libweston-desktop/surface.c 179+++ b/libweston-desktop/surface.c 180@@ -695,12 +695,202 @@ weston_desktop_surface_set_position(struct weston_desktop_surface *surface, 181 weston_view_set_position(view->view, x, y); 182 } 183 184+static bool 185+weston_desktop_surface_set_flags(struct weston_desktop_surface *surface, 186+ char *s) 187+{ 188+ struct weston_surface *wsurface = surface->surface; 189+ char *p; 190+ 191+#define SURFACE_FLAG_PREFIX "flags=" 192+ s = strstr(s, SURFACE_FLAG_PREFIX); 193+ if (!s) 194+ return false; 195+ 196+ s += strlen(SURFACE_FLAG_PREFIX); 197+ 198+ p = strtok(s, "|"); 199+ while (p) { 200+ enum weston_surface_flags flag = 0; 201+ bool clear = false; 202+ 203+ switch (p[0]) { 204+ case ';': 205+ /* fall through */ 206+ case '&': 207+ return true; 208+ case '-': 209+ clear = true; 210+ /* fall through */ 211+ case '+': 212+ p++; 213+ default: 214+ break; 215+ } 216+ 217+ if (!strcmp(p, "no-focus")) 218+ flag = SURFACE_NO_FOCUS; 219+ else if (!strcmp(p, "stay-on-top")) 220+ flag = SURFACE_STAY_ON_TOP; 221+ else if (!strcmp(p, "stay-on-bottom")) 222+ flag = SURFACE_STAY_ON_BOTTOM; 223+ else if (!strcmp(p, "blocked")) 224+ flag = SURFACE_BLOCKED; 225+ else if (!strcmp(p, "trans-input")) 226+ flag = SURFACE_TRANS_INPUT; 227+ else 228+ weston_log("%s: warning: unsupported flag: %s\n", 229+ __func__, p); 230+ 231+ if (clear) 232+ wsurface->flags &= ~flag; 233+ else 234+ wsurface->flags |= flag; 235+ 236+ p = strtok(NULL, "|"); 237+ }; 238+ 239+ return true; 240+} 241+ 242+static bool 243+weston_desktop_surface_set_requests(struct weston_desktop_surface *surface, 244+ char *s) 245+{ 246+ struct weston_surface *wsurface = surface->surface; 247+ char *p; 248+ 249+#define SURFACE_REQUEST_PREFIX "requests=" 250+ s = strstr(s, SURFACE_REQUEST_PREFIX); 251+ if (!s) 252+ return false; 253+ 254+ s += strlen(SURFACE_REQUEST_PREFIX); 255+ 256+ p = strtok(s, "|"); 257+ while (p) { 258+ switch (p[0]) { 259+ case ';': 260+ /* fall through */ 261+ case '&': 262+ return true; 263+ default: 264+ break; 265+ } 266+ 267+ if (!strcmp(p, "activate")) { 268+ if (weston_surface_is_mapped(wsurface)) 269+ weston_surface_unmap(wsurface); 270+ 271+ weston_desktop_api_committed(surface->desktop, 272+ surface, 0, 0); 273+ } else { 274+ weston_log("%s: warning: unsupported request: %s\n", 275+ __func__, p); 276+ } 277+ 278+ p = strtok(NULL, "|"); 279+ }; 280+ 281+ return true; 282+} 283+ 284+static void 285+weston_surface_set_alpha(struct weston_surface *wsurface, float alpha) 286+{ 287+ struct weston_subsurface *sub; 288+ struct weston_view *view; 289+ 290+ wsurface->alpha = alpha; 291+ wsurface->is_opaque = !(alpha < 1.0); 292+ 293+ wl_list_for_each(view, &wsurface->views, 294+ surface_link) { 295+ view->alpha = alpha; 296+ weston_view_geometry_dirty(view); 297+ } 298+ 299+ wl_list_for_each(sub, &wsurface->subsurface_list, 300+ parent_link) { 301+ if (sub->surface != wsurface) 302+ weston_surface_set_alpha(sub->surface, alpha); 303+ } 304+} 305+ 306+static bool 307+weston_desktop_surface_set_attrs(struct weston_desktop_surface *surface, 308+ char *s) 309+{ 310+ struct weston_surface *wsurface = surface->surface; 311+ char *p; 312+ 313+#define SURFACE_ATTRS_PREFIX "attrs=" 314+ s = strstr(s, SURFACE_ATTRS_PREFIX); 315+ if (!s) 316+ return false; 317+ 318+ s += strlen(SURFACE_ATTRS_PREFIX); 319+ 320+ p = strtok(s, "|"); 321+ while (p) { 322+ switch (p[0]) { 323+ case ';': 324+ /* fall through */ 325+ case '&': 326+ return true; 327+ default: 328+ break; 329+ } 330+ 331+#define SURFACE_ATTR_ALPHA "alpha:" 332+ if (!strncmp(p, SURFACE_ATTR_ALPHA, 333+ strlen(SURFACE_ATTR_ALPHA))) { 334+ double alpha = atof(p + strlen(SURFACE_ATTR_ALPHA)); 335+ 336+ weston_surface_set_alpha(wsurface, alpha); 337+ } else { 338+ weston_log("%s: warning: unsupported attr: %s\n", 339+ __func__, p); 340+ } 341+ 342+ p = strtok(NULL, "|"); 343+ }; 344+ 345+ return true; 346+} 347+ 348+static bool 349+weston_desktop_surface_handle_config(struct weston_desktop_surface *surface, 350+ const char *s) 351+{ 352+ char *tmp; 353+ bool handled = false; 354+ 355+ tmp = strdup(s); 356+ if (tmp == NULL) 357+ return false; 358+ 359+ handled |= weston_desktop_surface_set_flags(surface, tmp); 360+ 361+ strcpy(tmp, s); 362+ handled |= weston_desktop_surface_set_requests(surface, tmp); 363+ 364+ strcpy(tmp, s); 365+ handled |= weston_desktop_surface_set_attrs(surface, tmp); 366+ 367+ free(tmp); 368+ return handled; 369+} 370+ 371 void 372 weston_desktop_surface_set_title(struct weston_desktop_surface *surface, 373 const char *title) 374 { 375 char *tmp, *old; 376 377+ if (weston_desktop_surface_handle_config(surface, title)) 378+ return; 379+ 380 tmp = strdup(title); 381 if (tmp == NULL) 382 return; 383@@ -717,6 +907,9 @@ weston_desktop_surface_set_app_id(struct weston_desktop_surface *surface, 384 { 385 char *tmp, *old; 386 387+ if (weston_desktop_surface_handle_config(surface, app_id)) 388+ return; 389+ 390 tmp = strdup(app_id); 391 if (tmp == NULL) 392 return; 393diff --git a/libweston/compositor.c b/libweston/compositor.c 394index 0aa9d1a..b959424 100644 395--- a/libweston/compositor.c 396+++ b/libweston/compositor.c 397@@ -412,7 +412,7 @@ weston_view_create(struct weston_surface *surface) 398 399 pixman_region32_init(&view->clip); 400 401- view->alpha = 1.0; 402+ view->alpha = surface->alpha; 403 pixman_region32_init(&view->transform.opaque); 404 405 wl_list_init(&view->geometry.transformation_list); 406@@ -608,6 +608,8 @@ weston_surface_create(struct weston_compositor *compositor) 407 surface->compositor = compositor; 408 surface->ref_count = 1; 409 410+ surface->alpha = 1.0; 411+ 412 surface->buffer_viewport.buffer.transform = WL_OUTPUT_TRANSFORM_NORMAL; 413 surface->buffer_viewport.buffer.scale = 1; 414 surface->buffer_viewport.buffer.src_width = wl_fixed_from_int(-1); 415@@ -2217,6 +2219,12 @@ weston_compositor_pick_view(struct weston_compositor *compositor, 416 view_ix, view_iy, NULL)) 417 continue; 418 419+ if (view->surface->flags & SURFACE_BLOCKED) 420+ break; 421+ 422+ if (view->surface->flags & SURFACE_TRANS_INPUT) 423+ continue; 424+ 425 *vx = view_x; 426 *vy = view_y; 427 return view; 428-- 4292.20.1 430 431