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