1From b88835ba3042212cba6c5ecc9c8069f2f6525e4a 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 23/93] 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/compositor.c | 10 +- 19 libweston/desktop/surface.c | 193 ++++++++++++++++++++++++++++++++++ 20 5 files changed, 244 insertions(+), 3 deletions(-) 21 22diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c 23index be36b70..463c64e 100644 24--- a/desktop-shell/shell.c 25+++ b/desktop-shell/shell.c 26@@ -1431,6 +1431,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@@ -2787,6 +2792,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@@ -3360,7 +3369,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@@ -3380,6 +3389,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@@ -3402,6 +3414,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@@ -3410,7 +3423,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@@ -3504,6 +3517,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@@ -4318,6 +4333,8 @@ shell_for_each_layer(struct desktop_shell *shell, 95 func(shell, &shell->lock_layer, data); 96 func(shell, &shell->input_panel_layer, data); 97 func(shell, &shell->workspace.layer, data); 98+ func(shell, &shell->top_layer, data); 99+ func(shell, &shell->bottom_layer, data); 100 } 101 102 static void 103@@ -4615,6 +4632,8 @@ shell_destroy(struct wl_listener *listener, void *data) 104 105 workspace_destroy(&shell->workspace); 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@@ -4742,6 +4761,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@@ -4749,6 +4770,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_list_init(&shell->seat_list); 131 132diff --git a/desktop-shell/shell.h b/desktop-shell/shell.h 133index e9e123e..6876cf3 100644 134--- a/desktop-shell/shell.h 135+++ b/desktop-shell/shell.h 136@@ -100,6 +100,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 84b16fe..a41ffba 100644 147--- a/include/libweston/libweston.h 148+++ b/include/libweston/libweston.h 149@@ -1635,6 +1635,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@@ -1741,6 +1749,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/compositor.c b/libweston/compositor.c 177index 877e7a7..09d4805 100644 178--- a/libweston/compositor.c 179+++ b/libweston/compositor.c 180@@ -415,7 +415,7 @@ weston_view_create(struct weston_surface *surface) 181 182 pixman_region32_init(&view->clip); 183 184- view->alpha = 1.0; 185+ view->alpha = surface->alpha; 186 pixman_region32_init(&view->transform.opaque); 187 188 wl_list_init(&view->geometry.transformation_list); 189@@ -611,6 +611,8 @@ weston_surface_create(struct weston_compositor *compositor) 190 surface->compositor = compositor; 191 surface->ref_count = 1; 192 193+ surface->alpha = 1.0; 194+ 195 surface->buffer_viewport.buffer.transform = WL_OUTPUT_TRANSFORM_NORMAL; 196 surface->buffer_viewport.buffer.scale = 1; 197 surface->buffer_viewport.buffer.src_width = wl_fixed_from_int(-1); 198@@ -2253,6 +2255,12 @@ weston_compositor_pick_view(struct weston_compositor *compositor, 199 view_ix, view_iy, NULL)) 200 continue; 201 202+ if (view->surface->flags & SURFACE_BLOCKED) 203+ break; 204+ 205+ if (view->surface->flags & SURFACE_TRANS_INPUT) 206+ continue; 207+ 208 *vx = view_x; 209 *vy = view_y; 210 return view; 211diff --git a/libweston/desktop/surface.c b/libweston/desktop/surface.c 212index 54e493c..aeac8f7 100644 213--- a/libweston/desktop/surface.c 214+++ b/libweston/desktop/surface.c 215@@ -705,12 +705,202 @@ weston_desktop_surface_set_position(struct weston_desktop_surface *surface, 216 weston_view_set_position(view->view, x, y); 217 } 218 219+static bool 220+weston_desktop_surface_set_flags(struct weston_desktop_surface *surface, 221+ char *s) 222+{ 223+ struct weston_surface *wsurface = surface->surface; 224+ char *p; 225+ 226+#define SURFACE_FLAG_PREFIX "flags=" 227+ s = strstr(s, SURFACE_FLAG_PREFIX); 228+ if (!s) 229+ return false; 230+ 231+ s += strlen(SURFACE_FLAG_PREFIX); 232+ 233+ p = strtok(s, "|"); 234+ while (p) { 235+ enum weston_surface_flags flag = 0; 236+ bool clear = false; 237+ 238+ switch (p[0]) { 239+ case ';': 240+ /* fall through */ 241+ case '&': 242+ return true; 243+ case '-': 244+ clear = true; 245+ /* fall through */ 246+ case '+': 247+ p++; 248+ default: 249+ break; 250+ } 251+ 252+ if (!strcmp(p, "no-focus")) 253+ flag = SURFACE_NO_FOCUS; 254+ else if (!strcmp(p, "stay-on-top")) 255+ flag = SURFACE_STAY_ON_TOP; 256+ else if (!strcmp(p, "stay-on-bottom")) 257+ flag = SURFACE_STAY_ON_BOTTOM; 258+ else if (!strcmp(p, "blocked")) 259+ flag = SURFACE_BLOCKED; 260+ else if (!strcmp(p, "trans-input")) 261+ flag = SURFACE_TRANS_INPUT; 262+ else 263+ weston_log("%s: warning: unsupported flag: %s\n", 264+ __func__, p); 265+ 266+ if (clear) 267+ wsurface->flags &= ~flag; 268+ else 269+ wsurface->flags |= flag; 270+ 271+ p = strtok(NULL, "|"); 272+ }; 273+ 274+ return true; 275+} 276+ 277+static bool 278+weston_desktop_surface_set_requests(struct weston_desktop_surface *surface, 279+ char *s) 280+{ 281+ struct weston_surface *wsurface = surface->surface; 282+ char *p; 283+ 284+#define SURFACE_REQUEST_PREFIX "requests=" 285+ s = strstr(s, SURFACE_REQUEST_PREFIX); 286+ if (!s) 287+ return false; 288+ 289+ s += strlen(SURFACE_REQUEST_PREFIX); 290+ 291+ p = strtok(s, "|"); 292+ while (p) { 293+ switch (p[0]) { 294+ case ';': 295+ /* fall through */ 296+ case '&': 297+ return true; 298+ default: 299+ break; 300+ } 301+ 302+ if (!strcmp(p, "activate")) { 303+ if (weston_surface_is_mapped(wsurface)) 304+ weston_surface_unmap(wsurface); 305+ 306+ weston_desktop_api_committed(surface->desktop, 307+ surface, 0, 0); 308+ } else { 309+ weston_log("%s: warning: unsupported request: %s\n", 310+ __func__, p); 311+ } 312+ 313+ p = strtok(NULL, "|"); 314+ }; 315+ 316+ return true; 317+} 318+ 319+static void 320+weston_surface_set_alpha(struct weston_surface *wsurface, float alpha) 321+{ 322+ struct weston_subsurface *sub; 323+ struct weston_view *view; 324+ 325+ wsurface->alpha = alpha; 326+ wsurface->is_opaque = !(alpha < 1.0); 327+ 328+ wl_list_for_each(view, &wsurface->views, 329+ surface_link) { 330+ view->alpha = alpha; 331+ weston_view_geometry_dirty(view); 332+ } 333+ 334+ wl_list_for_each(sub, &wsurface->subsurface_list, 335+ parent_link) { 336+ if (sub->surface != wsurface) 337+ weston_surface_set_alpha(sub->surface, alpha); 338+ } 339+} 340+ 341+static bool 342+weston_desktop_surface_set_attrs(struct weston_desktop_surface *surface, 343+ char *s) 344+{ 345+ struct weston_surface *wsurface = surface->surface; 346+ char *p; 347+ 348+#define SURFACE_ATTRS_PREFIX "attrs=" 349+ s = strstr(s, SURFACE_ATTRS_PREFIX); 350+ if (!s) 351+ return false; 352+ 353+ s += strlen(SURFACE_ATTRS_PREFIX); 354+ 355+ p = strtok(s, "|"); 356+ while (p) { 357+ switch (p[0]) { 358+ case ';': 359+ /* fall through */ 360+ case '&': 361+ return true; 362+ default: 363+ break; 364+ } 365+ 366+#define SURFACE_ATTR_ALPHA "alpha:" 367+ if (!strncmp(p, SURFACE_ATTR_ALPHA, 368+ strlen(SURFACE_ATTR_ALPHA))) { 369+ double alpha = atof(p + strlen(SURFACE_ATTR_ALPHA)); 370+ 371+ weston_surface_set_alpha(wsurface, alpha); 372+ } else { 373+ weston_log("%s: warning: unsupported attr: %s\n", 374+ __func__, p); 375+ } 376+ 377+ p = strtok(NULL, "|"); 378+ }; 379+ 380+ return true; 381+} 382+ 383+static bool 384+weston_desktop_surface_handle_config(struct weston_desktop_surface *surface, 385+ const char *s) 386+{ 387+ char *tmp; 388+ bool handled = false; 389+ 390+ tmp = strdup(s); 391+ if (tmp == NULL) 392+ return false; 393+ 394+ handled |= weston_desktop_surface_set_flags(surface, tmp); 395+ 396+ strcpy(tmp, s); 397+ handled |= weston_desktop_surface_set_requests(surface, tmp); 398+ 399+ strcpy(tmp, s); 400+ handled |= weston_desktop_surface_set_attrs(surface, tmp); 401+ 402+ free(tmp); 403+ return handled; 404+} 405+ 406 void 407 weston_desktop_surface_set_title(struct weston_desktop_surface *surface, 408 const char *title) 409 { 410 char *tmp, *old; 411 412+ if (weston_desktop_surface_handle_config(surface, title)) 413+ return; 414+ 415 tmp = strdup(title); 416 if (tmp == NULL) 417 return; 418@@ -727,6 +917,9 @@ weston_desktop_surface_set_app_id(struct weston_desktop_surface *surface, 419 { 420 char *tmp, *old; 421 422+ if (weston_desktop_surface_handle_config(surface, app_id)) 423+ return; 424+ 425 tmp = strdup(app_id); 426 if (tmp == NULL) 427 return; 428-- 4292.20.1 430 431