diff --git a/compositor/main.c b/compositor/main.c index c6d84c12e..929f57d3d 100644 --- a/compositor/main.c +++ b/compositor/main.c @@ -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); diff --git a/libweston/backend-rdp/rdp.c b/libweston/backend-rdp/rdp.c index b8c0a77ee..70f54c963 100644 --- a/libweston/backend-rdp/rdp.c +++ b/libweston/backend-rdp/rdp.c @@ -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++) { @@ -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 */ diff --git a/libweston/backend-rdp/rdprail.c b/libweston/backend-rdp/rdprail.c index ef748d23a..32907c2cd 100644 --- a/libweston/backend-rdp/rdprail.c +++ b/libweston/backend-rdp/rdprail.c @@ -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) { @@ -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: @@ -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) { @@ -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 @@ -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); diff --git a/rdprail-shell/shell.c b/rdprail-shell/shell.c index 53c1c7431..93662c5d7 100644 --- a/rdprail-shell/shell.c +++ b/rdprail-shell/shell.c @@ -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) @@ -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); @@ -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) @@ -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; @@ -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); @@ -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 @@ -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); @@ -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); @@ -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);