Skip to content

Commit

Permalink
rdp fontend/backend/shell: keep compositor sleep until window is crea…
Browse files Browse the repository at this point in the history
…ted (#128)

Co-authored-by: Hideyuki Nagase <[email protected]>
  • Loading branch information
hideyukn88 and Hideyuki Nagase authored Jan 10, 2023
1 parent 321f799 commit f0c83cf
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 67 deletions.
3 changes: 2 additions & 1 deletion compositor/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -3607,7 +3607,8 @@ wet_main(int argc, char *argv[])
if (argc > 1)
goto out;

weston_compositor_wake(wet.compositor);
/* Until RDP connection is established, keep compositor sleep state */
weston_compositor_sleep(wet.compositor);

wl_display_run(display);

Expand Down
10 changes: 10 additions & 0 deletions libweston/backend-rdp/rdp.c
Original file line number Diff line number Diff line change
Expand Up @@ -750,6 +750,9 @@ rdp_peer_context_free(freerdp_peer* client, RdpPeerContext* context)

b = context->rdpBackend;

/* While RDP client is disconnected, keep compositor sleep state */
weston_compositor_sleep(b->compositor);

wl_list_remove(&context->item.link);

for (i = 0; i < ARRAY_LENGTH(context->events); i++) {
Expand Down Expand Up @@ -1059,6 +1062,13 @@ xf_peer_activate(freerdp_peer* client)
rdp_debug_error(b, "HiDef-RAIL is requested from client, but RAIL-shell is not used\n");
return FALSE;
}

/* do not wake up compositor yet, since in RAIL mode, there is no
need to paint 'desktop', thus defer until window is created */
} else {
/* update RDP connection, wake up compositor to repaint 'desktop' */
weston_compositor_wake(b->compositor);
weston_compositor_damage_all(b->compositor);
}

/* override settings by env variables */
Expand Down
110 changes: 51 additions & 59 deletions libweston/backend-rdp/rdprail.c
Original file line number Diff line number Diff line change
Expand Up @@ -3191,6 +3191,44 @@ disp_client_monitor_layout_change(DispServerContext *context, const DISPLAY_CONT
return CHANNEL_RC_OK;
}

static void
rdp_rail_idle_handler(struct wl_listener *listener, void *data)
{
RAIL_POWER_DISPLAY_REQUEST displayRequest;
RdpPeerContext *peer_ctx = container_of(listener, RdpPeerContext,
idle_listener);
struct rdp_backend *b = peer_ctx->rdpBackend;
RailServerContext *rail_ctx = peer_ctx->rail_server_context;

assert_compositor_thread(b);

rdp_debug(b, "%s is called on peer_ctx:%p\n", __func__, peer_ctx);

if (peer_ctx->clientStatusFlags & TS_RAIL_CLIENTSTATUS_POWER_DISPLAY_REQUEST_SUPPORTED) {
displayRequest.active = FALSE;
rail_ctx->ServerPowerDisplayRequest(rail_ctx, &displayRequest);
}
}

static void
rdp_rail_wake_handler(struct wl_listener *listener, void *data)
{
RAIL_POWER_DISPLAY_REQUEST displayRequest;
RdpPeerContext *peer_ctx = container_of(listener, RdpPeerContext,
wake_listener);
struct rdp_backend *b = peer_ctx->rdpBackend;
RailServerContext *rail_ctx = peer_ctx->rail_server_context;

assert_compositor_thread(b);

rdp_debug(b, "%s is called on peer_ctx:%p\n", __func__, peer_ctx);

if (peer_ctx->clientStatusFlags & TS_RAIL_CLIENTSTATUS_POWER_DISPLAY_REQUEST_SUPPORTED) {
displayRequest.active = TRUE;
rail_ctx->ServerPowerDisplayRequest(rail_ctx, &displayRequest);
}
}

bool
rdp_rail_peer_activate(freerdp_peer* client)
{
Expand Down Expand Up @@ -3368,6 +3406,12 @@ rdp_rail_peer_activate(freerdp_peer* client)
WTSVirtualChannelManagerCheckFileDescriptor(peer_ctx->vcm);
}

/* subscribe idle/wake signal from compositor */
peer_ctx->idle_listener.notify = rdp_rail_idle_handler;
wl_signal_add(&b->compositor->idle_signal, &peer_ctx->idle_listener);
peer_ctx->wake_listener.notify = rdp_rail_wake_handler;
wl_signal_add(&b->compositor->wake_signal, &peer_ctx->wake_listener);

return TRUE;

error_exit:
Expand Down Expand Up @@ -3420,40 +3464,6 @@ rdp_rail_peer_activate(freerdp_peer* client)
return FALSE;
}

static void
rdp_rail_idle_handler(struct wl_listener *listener, void *data)
{
RAIL_POWER_DISPLAY_REQUEST displayRequest;
RdpPeerContext *peer_ctx = container_of(listener, RdpPeerContext,
idle_listener);
struct rdp_backend *b = peer_ctx->rdpBackend;
RailServerContext *rail_ctx = peer_ctx->rail_server_context;

assert_compositor_thread(b);

rdp_debug(b, "%s is called on peer_ctx:%p\n", __func__, peer_ctx);

displayRequest.active = FALSE;
rail_ctx->ServerPowerDisplayRequest(rail_ctx, &displayRequest);
}

static void
rdp_rail_wake_handler(struct wl_listener *listener, void *data)
{
RAIL_POWER_DISPLAY_REQUEST displayRequest;
RdpPeerContext *peer_ctx = container_of(listener, RdpPeerContext,
wake_listener);
struct rdp_backend *b = peer_ctx->rdpBackend;
RailServerContext *rail_ctx = peer_ctx->rail_server_context;

assert_compositor_thread(b);

rdp_debug(b, "%s is called on peer_ctx:%p\n", __func__, peer_ctx);

displayRequest.active = TRUE;
rail_ctx->ServerPowerDisplayRequest(rail_ctx, &displayRequest);
}

static void
rdp_rail_notify_window_proxy_surface(struct weston_surface *proxy_surface)
{
Expand Down Expand Up @@ -3577,36 +3587,19 @@ rdp_rail_sync_window_status(freerdp_peer *client)
if (rail_state && rail_state->window_id) {
if (api && api->request_window_icon)
api->request_window_icon(surface);
}
wl_list_for_each(sub, &surface->subsurface_list, parent_link) {
struct weston_surface_rail_state *sub_rail_state = sub->surface->backend_state;

if (sub->surface == surface)
continue;
if (!sub_rail_state || sub_rail_state->window_id == 0)
rdp_rail_create_window(NULL, sub->surface);
wl_list_for_each(sub, &surface->subsurface_list, parent_link) {
struct weston_surface_rail_state *sub_rail_state = sub->surface->backend_state;
if (sub->surface == surface)
continue;
if (!sub_rail_state || sub_rail_state->window_id == 0)
rdp_rail_create_window(NULL, sub->surface);
}
}
}
}

/* this assume repaint to be scheduled on idle loop, not directly from here */
weston_compositor_damage_all(b->compositor);

if (peer_ctx->clientStatusFlags & TS_RAIL_CLIENTSTATUS_POWER_DISPLAY_REQUEST_SUPPORTED) {
RAIL_POWER_DISPLAY_REQUEST displayRequest;

/* subscribe idle/wake signal from compositor */
peer_ctx->idle_listener.notify = rdp_rail_idle_handler;
wl_signal_add(&b->compositor->idle_signal, &peer_ctx->idle_listener);
peer_ctx->wake_listener.notify = rdp_rail_wake_handler;
wl_signal_add(&b->compositor->wake_signal, &peer_ctx->wake_listener);

displayRequest.active = TRUE;
rail_ctx->ServerPowerDisplayRequest(rail_ctx, &displayRequest);

/* Upon client connection, make sure compositor is in wake state */
weston_compositor_wake(b->compositor);
}
}

void
Expand Down Expand Up @@ -3831,7 +3824,6 @@ rdp_rail_peer_context_free(freerdp_peer *client, RdpPeerContext *context)
#ifdef HAVE_FREERDP_RDPAPPLIST_H
if (context->applist_server_context) {
struct rdp_backend *b = context->rdpBackend;

if (context->isAppListEnabled)
context->rdpBackend->rdprail_shell_api->stop_app_list_update(context->rdpBackend->rdprail_shell_context);
context->applist_server_context->Close(context->applist_server_context);
Expand Down
26 changes: 19 additions & 7 deletions rdprail-shell/shell.c
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,8 @@ shell_backend_request_window_activate(void *shell_context, struct weston_seat *s
static void
shell_backend_request_window_close(struct weston_surface *surface);

static void launch_desktop_shell_process(void *data);

#define ICON_STRIDE( W, BPP ) ((((W) * (BPP) + 31) / 32) * 4)

#define TITLEBAR_GRAB_MARGIN_X (30)
Expand Down Expand Up @@ -2172,7 +2174,7 @@ handle_metadata_change(struct wl_listener *listener, void *data)

static void
desktop_surface_added(struct weston_desktop_surface *desktop_surface,
void *shell)
void *data)
{
struct weston_desktop_client *client =
weston_desktop_surface_get_client(desktop_surface);
Expand All @@ -2182,6 +2184,10 @@ desktop_surface_added(struct weston_desktop_surface *desktop_surface,
struct shell_surface *shsurf;
struct weston_surface *surface =
weston_desktop_surface_get_surface(desktop_surface);
struct desktop_shell *shell =
(struct desktop_shell *)data;
struct weston_compositor *ec = shell->compositor;
struct wl_event_loop *loop;

view = weston_desktop_surface_create_view(desktop_surface);
if (!view)
Expand All @@ -2199,7 +2205,7 @@ desktop_surface_added(struct weston_desktop_surface *desktop_surface,

weston_surface_set_label_func(surface, shell_surface_get_label);

shsurf->shell = (struct desktop_shell *) shell;
shsurf->shell = shell;
shsurf->unresponsive = 0;
shsurf->saved_position_valid = false;
shsurf->saved_rotation_valid = false;
Expand All @@ -2208,8 +2214,7 @@ desktop_surface_added(struct weston_desktop_surface *desktop_surface,
shsurf->fullscreen.black_view = NULL;
wl_list_init(&shsurf->fullscreen.transform.link);

shell_surface_set_output(
shsurf, get_default_output(shsurf->shell->compositor));
shell_surface_set_output(shsurf, get_default_output(ec));

wl_signal_init(&shsurf->destroy_signal);

Expand All @@ -2231,6 +2236,14 @@ desktop_surface_added(struct weston_desktop_surface *desktop_surface,
shsurf->metadata_listener.notify = handle_metadata_change;
weston_desktop_surface_add_metadata_listener(desktop_surface,
&shsurf->metadata_listener);

/* when surface is added, compositor is in wake state */
weston_compositor_wake(ec);
/* and, shell process (= focus_proxy) is running */
if (!shell->child.client) {
loop = wl_display_get_event_loop(ec->wl_display);
wl_event_loop_add_idle(loop, launch_desktop_shell_process, shell);
}
}

static void
Expand Down Expand Up @@ -3967,6 +3980,7 @@ launch_desktop_shell_process(void *data)
{
struct desktop_shell *shell = data;

assert(!shell->child.client);
shell->child.client = weston_client_start(shell->compositor,
shell->client);

Expand Down Expand Up @@ -4618,7 +4632,6 @@ wet_shell_init(struct weston_compositor *ec,
struct desktop_shell *shell;
struct workspace **pws;
unsigned int i;
struct wl_event_loop *loop;
char *debug_level;

shell = zalloc(sizeof *shell);
Expand Down Expand Up @@ -4701,8 +4714,7 @@ wet_shell_init(struct weston_compositor *ec,

setup_output_destroy_handler(ec, shell);

loop = wl_display_get_event_loop(ec->wl_display);
wl_event_loop_add_idle(loop, launch_desktop_shell_process, shell);
shell->child.client = NULL;

wl_list_for_each(seat, &ec->seat_list, link)
handle_seat_created(NULL, seat);
Expand Down

0 comments on commit f0c83cf

Please sign in to comment.