From 903becf571607d3d310b2f877445cfff0a31ce5c Mon Sep 17 00:00:00 2001 From: Gwanglim Lee Date: Fri, 26 Jul 2019 21:07:07 +0900 Subject: [PATCH] e_service_launcher: added shared widget feature Change-Id: Iee243f3854603e3ea1524a0f918dbf035d923959 --- src/bin/e_policy_wl.c | 160 +++++++++++++++ src/bin/e_policy_wl.h | 3 + src/bin/services/e_service_launcher.c | 375 ++++++++++++++++++++++++++++++++-- src/bin/services/e_service_launcher.h | 1 + 4 files changed, 519 insertions(+), 20 deletions(-) diff --git a/src/bin/e_policy_wl.c b/src/bin/e_policy_wl.c index 1a7c702..ee1857a 100644 --- a/src/bin/e_policy_wl.c +++ b/src/bin/e_policy_wl.c @@ -5586,6 +5586,165 @@ _tzsh_iface_cb_softkey_get(struct wl_client *client, struct wl_resource *res_tzs _tzsh_cb_softkey_destroy); } +// -------------------------------------------------------- +// tizen_ws_shell_interface::shared_widget_launch +// -------------------------------------------------------- +EINTERN Eina_Bool +e_tzsh_shared_widget_launch_prepare_send(E_Client *callee_ec, + uint32_t state) +{ + E_Policy_Wl_Tzsh_Client *tzsh_client; + Eina_List *l; + Eina_Bool res = EINA_FALSE; + + EINA_SAFETY_ON_NULL_RETURN_VAL(callee_ec, EINA_FALSE); + EINA_SAFETY_ON_TRUE_RETURN_VAL(e_object_is_del(E_OBJECT(callee_ec)), EINA_FALSE); + + EINA_LIST_FOREACH(polwl->tzsh_clients, l, tzsh_client) + { + if (!tzsh_client->tzsh) continue; + if (!tzsh_client->tzsh->ec) continue; + if (tzsh_client->tzsh->ec != callee_ec) continue; + + tws_shared_widget_launch_send_prepare_shared_widget(tzsh_client->res_tzsh_client, + state); + + res = EINA_TRUE; + break; + } + + return res; +} + +static void +_tzsh_swl_iface_cb_release(struct wl_client *client, + struct wl_resource *res_tzsh_swl) +{ + wl_resource_destroy(res_tzsh_swl); +} + +static void +_tzsh_swl_iface_cb_prepare_shared_widget_done(struct wl_client *client, + struct wl_resource *res_tzsh_swl, + const char *shared_widget_info, + uint32_t state) +{ + E_Policy_Wl_Tzsh_Client *tzsh_client; + + ELOGF("TZSH_SWL", "Done", NULL); + + tzsh_client = wl_resource_get_user_data(res_tzsh_swl); + EINA_SAFETY_ON_NULL_RETURN(tzsh_client); + EINA_SAFETY_ON_NULL_RETURN(tzsh_client->tzsh); + EINA_SAFETY_ON_NULL_RETURN(tzsh_client->tzsh->ec); + EINA_SAFETY_ON_NULL_RETURN(eina_list_data_find(polwl->tzsh_clients, tzsh_client)); + + // send prepare event to caller + e_service_launcher_prepare_send_with_shared_widget_info(tzsh_client->tzsh->ec, + shared_widget_info, + state); +} + +static const struct tws_shared_widget_launch_interface _tzsh_swl_iface = +{ + _tzsh_swl_iface_cb_release, + _tzsh_swl_iface_cb_prepare_shared_widget_done, +}; + +static void +_tzsh_cb_swl_destroy(struct wl_resource *res_tzsh_swl) +{ + E_Policy_Wl_Tzsh_Client *tzsh_client; + + tzsh_client = wl_resource_get_user_data(res_tzsh_swl); + EINA_SAFETY_ON_NULL_RETURN(tzsh_client); + + _e_policy_wl_tzsh_client_del(tzsh_client); +} + +static void +_tzsh_iface_cb_shared_widget_launch_get(struct wl_client *client, + struct wl_resource *res_tzsh, + uint32_t id, + uint32_t surf_id) +{ + E_Policy_Wl_Tzsh *tzsh; + E_Policy_Wl_Tzsh_Client *tzsh_client; + struct wl_resource *res_tzsh_swl; + E_Client *ec; + E_Pixmap *cp; + pid_t pid; + uid_t uid; + + tzsh = wl_resource_get_user_data(res_tzsh); + if (!tzsh) + { + wl_resource_post_error + (res_tzsh, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "Invalid res_tzsh's user data"); + return; + } + + wl_client_get_credentials(client, &pid, &uid, NULL); + if (!e_security_privilege_check(pid, uid, E_PRIVILEGE_SOFTKEY)) + { + ERR("Could not get privilege of resource: %m"); + tizen_ws_shell_send_error(tzsh->res_tzsh, TIZEN_WS_SHELL_ERROR_PERMISSION_DENIED); + return; + } + else + tizen_ws_shell_send_error(tzsh->res_tzsh, TIZEN_WS_SHELL_ERROR_NONE); + + cp = _e_policy_wl_e_pixmap_get_from_id(client, surf_id); + if (!cp) + { + wl_resource_post_error + (res_tzsh, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "Invalid surface id"); + return; + } + + ec = e_pixmap_client_get(cp); + if (ec) + { + if (!_e_policy_wl_e_client_is_valid(ec)) + { + wl_resource_post_error + (res_tzsh, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "Invalid surface id"); + return; + } + } + + res_tzsh_swl = wl_resource_create(client, + &tws_shared_widget_launch_interface, + wl_resource_get_version(res_tzsh), + id); + if (!res_tzsh_swl) + { + ERR("Could not create tws_shared_widget_launch resource: %m"); + wl_client_post_no_memory(client); + return; + } + + _e_policy_wl_tzsh_data_set(tzsh, TZSH_TYPE_CLIENT, cp, ec); + + tzsh_client = _e_policy_wl_tzsh_client_add(tzsh, res_tzsh_swl); + if (!tzsh_client) + { + ERR("Could not create tzsh_client"); + wl_client_post_no_memory(client); + return; + } + + wl_resource_set_implementation(res_tzsh_swl, + &_tzsh_swl_iface, + tzsh_client, + _tzsh_cb_swl_destroy); +} // -------------------------------------------------------- // tizen_ws_shell_interface @@ -5605,6 +5764,7 @@ static const struct tizen_ws_shell_interface _tzsh_iface = _tzsh_iface_cb_tvsrv_get, _tzsh_iface_cb_extension_get, _tzsh_iface_cb_softkey_get, + _tzsh_iface_cb_shared_widget_launch_get, }; static void diff --git a/src/bin/e_policy_wl.h b/src/bin/e_policy_wl.h index b6ff506..fc59319 100644 --- a/src/bin/e_policy_wl.h +++ b/src/bin/e_policy_wl.h @@ -75,6 +75,9 @@ EINTERN void e_tzsh_indicator_srv_property_change_send(E_Client *ec, int angle); EINTERN void e_tzsh_indicator_srv_property_update(E_Client *ec); EINTERN void e_tzsh_indicator_srv_ower_win_update(E_Zone *zone); +/* tzsh shared widget launch */ +EINTERN Eina_Bool e_tzsh_shared_widget_launch_prepare_send(E_Client *callee_ec, uint32_t state); + /* indicator */ void e_policy_wl_indicator_flick_send(E_Client *ec); diff --git a/src/bin/services/e_service_launcher.c b/src/bin/services/e_service_launcher.c index 83651aa..891faab 100644 --- a/src/bin/services/e_service_launcher.c +++ b/src/bin/services/e_service_launcher.c @@ -1,4 +1,5 @@ #include "e.h" +#include "e_policy_wl.h" #include #include "services/e_service_launcher.h" @@ -14,6 +15,7 @@ typedef enum LAUNCHER_STATE_LAUNCHING_WAIT_BUFFER, LAUNCHER_STATE_DONE, LAUNCHER_STATE_CANCELED, + LAUNCHER_STATE_WAIT_RESPONSE_FROM_CALLEE, } Launcher_State; struct _E_Service_Launcher @@ -41,6 +43,8 @@ struct _E_Service_Launcher E_Object_Delfn *launched_delfn; //del callback of launched_ec Ecore_Event_Handler *buff_attach; //event handler for BUFFER_CHANGE + + Eina_Bool with_swl; }; struct _E_Service_Launcher_Handler @@ -110,6 +114,8 @@ _launcher_state_to_str(Launcher_State state) return "LAUNCH_DONE"; case LAUNCHER_STATE_CANCELED: return "LAUNCH_CANCELED"; + case LAUNCHER_STATE_WAIT_RESPONSE_FROM_CALLEE: + return "WAIT_FOR_RESPONSE_FROM_CALLEE"; } return "UNKNOWN"; } @@ -228,8 +234,9 @@ _launcher_stop_send(E_Service_Launcher *lc) static Eina_Bool _launcher_prepare_send(E_Service_Launcher *lc, - E_Client *target_ec, - int x, int y) + E_Client *target_ec, + int x, int y, + const char *shared_widget_info) { uint32_t res_id = 0; @@ -310,14 +317,16 @@ _launcher_prepare_send(E_Service_Launcher *lc, } - ELOGF("LAUNCHER_SRV", "Send PREPARE event(%d) direction:%s target(ec:%p type:%d res:%d path:%s pos(%d,%d))", - lc->ec, lc->serial, lc->direction?"BACKWARD":"FORWARD", target_ec, target_type, res_id, target_path?:"N/A", x, y); + ELOGF("LAUNCHER_SRV", "Send PREPARE event(%d) direction:%s target(ec:%p type:%d res:%d path:%s pos(%d,%d) widget:%s)", + lc->ec, lc->serial, lc->direction?"BACKWARD":"FORWARD", target_ec, target_type, res_id, target_path?:"N/A", x, y, shared_widget_info); tws_service_launcher_send_prepare(lc->res, target_type, &info_array, lc->direction, - x, y, lc->serial); + x, y, + shared_widget_info ? shared_widget_info : "None", + lc->serial); wl_array_release(&info_array); return EINA_TRUE; @@ -327,6 +336,99 @@ fail: } static Eina_Bool +_launcher_prepare_shared_widget_forward_send(E_Service_Launcher *lc, + E_Client *target_ec) +{ + Eina_Bool sent = EINA_FALSE; + + EINA_SAFETY_ON_NULL_RETURN_VAL(lc, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(target_ec, EINA_FALSE); + if(e_object_is_del(E_OBJECT(target_ec))) return EINA_FALSE; + + e_policy_animatable_lock(target_ec, E_POLICY_ANIMATABLE_CUSTOMIZED, 1); + e_comp_client_override_add(target_ec); + + // grab uniconify job of target_ec + if (target_ec->iconic) + { + lc->target.vis_grab = + e_policy_visibility_client_filtered_grab_get + (target_ec, + (E_VIS_JOB_TYPE_UNICONIFY | E_VIS_JOB_TYPE_UNICONIFY_BY_VISIBILITY), + __func__); + } + + _launcher_launched_ec_set(lc, NULL); + _launcher_target_ec_set(lc, target_ec); + + sent = e_tzsh_shared_widget_launch_prepare_send(target_ec, + TWS_SHARED_WIDGET_LAUNCH_PREPARE_STATE_WIDGET_HIDE); + if (!sent) + { + ELOGF("LAUNCHER_SRV", "Failed to send event(PREPARE:FORWARD)", lc->ec); + _launcher_post_forward(lc, EINA_FALSE); + } + + return sent; +} + +static Eina_Bool +_launcher_prepare_shared_widget_backward_send(E_Service_Launcher *lc, + E_Client *activity, + E_Client *target_ec, + E_Vis_Job_Type job_type) +{ + int x, y; + Eina_Bool sent = EINA_FALSE; + + EINA_SAFETY_ON_NULL_RETURN_VAL(lc, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(activity, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(target_ec, EINA_FALSE); + + if (e_object_is_del(E_OBJECT(target_ec))) + { + // do nothing if ec is deleted and there's no delay_del_ref as well. + if (!e_object_delay_del_ref_get(E_OBJECT(target_ec))) + return EINA_FALSE; + } + + e_object_delay_del_ref(E_OBJECT(target_ec)); + lc->target.delay_del = EINA_TRUE; + + e_policy_animatable_lock(target_ec, E_POLICY_ANIMATABLE_CUSTOMIZED, 1); + e_comp_client_override_add(target_ec); + + if (activity == target_ec) + { + lc->vis_grab = e_policy_visibility_client_filtered_grab_get(lc->ec, job_type, __func__); + lc->target.vis_grab = e_policy_visibility_client_filtered_grab_get(target_ec, E_VIS_JOB_TYPE_ALL, __func__); + } + else + { + lc->target.vis_grab = e_policy_visibility_client_filtered_grab_get(target_ec, job_type, __func__); + } + + _launcher_launched_ec_set(lc, NULL); + _launcher_target_ec_set(lc, target_ec); + + lc->serial = wl_display_next_serial(e_comp_wl->wl.disp); + lc->direction = TWS_SERVICE_LAUNCHER_DIRECTION_BACKWARD; + e_client_pos_get(target_ec, &x, &y); + + sent = e_tzsh_shared_widget_launch_prepare_send(target_ec, + TWS_SHARED_WIDGET_LAUNCH_PREPARE_STATE_WIDGET_HIDE); + + // fail to send protocol event + if (!sent) + { + ELOGF("LAUNCHER_SRV", "Failed to send event(PREPARE:BACKWARD)", lc->ec); + _launcher_post_backward(lc, EINA_FALSE); + } + + return sent; +} + +static Eina_Bool _launcher_prepare_forward_send(E_Service_Launcher *lc, E_Client *target_ec) { @@ -355,7 +457,7 @@ _launcher_prepare_forward_send(E_Service_Launcher *lc, lc->serial = wl_display_next_serial(e_comp_wl->wl.disp); e_client_pos_get(target_ec, &x, &y); - sent = _launcher_prepare_send(lc, target_ec, x, y); + sent = _launcher_prepare_send(lc, target_ec, x, y, NULL); //fail to send protocol event if (!sent) @@ -410,7 +512,7 @@ _launcher_prepare_backward_send(E_Service_Launcher *lc, lc->direction = TWS_SERVICE_LAUNCHER_DIRECTION_BACKWARD; e_client_pos_get(target_ec, &x, &y); - sent = _launcher_prepare_send(lc, target_ec, x, y); + sent = _launcher_prepare_send(lc, target_ec, x, y, NULL); //fail to send protocol event if (!sent) @@ -687,6 +789,86 @@ send_stop: } static void +_launcher_cb_launch_with_shared_widget(struct wl_client *client EINA_UNUSED, + struct wl_resource *res_tws_lc, + const char *app_id, + const char *instance_id, + int32_t pid) +{ + E_Service_Launcher *lc; + E_Service_Launcher *runner, *pre_runner; + E_Client *target_ec; + Eina_List *ecs, *l; + Eina_Bool sent = EINA_FALSE; + + lc = wl_resource_get_user_data(res_tws_lc); + EINA_SAFETY_ON_NULL_RETURN(lc); + EINA_SAFETY_ON_NULL_RETURN(lc->ec); + + ELOGF("LAUNCHER_SRV", + "Recieved request(launcher_launch_with_shared_widget) appid:%s instance id:%s pid:%d", + lc->ec, app_id?:"NONE", instance_id?:"NONE", pid); + + EINA_SAFETY_ON_TRUE_GOTO(lc->ec->visibility.obscured == E_VISIBILITY_FULLY_OBSCURED, send_stop); + EINA_SAFETY_ON_TRUE_GOTO(pid < 0, send_stop); + + // check current state of lc + runner = _launcher_handler_launcher_runner_get(); + if (runner == lc) + { + ELOGF("LAUNCHER_SRV", + "Launcher(%s) requests LAUNCH again without cancel, ignore this.", + lc->ec, _launcher_state_to_str(lc->state)); + + tws_service_launcher_send_error(lc->res, + TWS_SERVICE_LAUNCHER_ERROR_WRONG_REQUEST, + lc->serial); + return; + } + + pre_runner = _launcher_handler_launcher_pre_runner_get(); + if (pre_runner == lc) + { + _launcher_handler_launcher_pre_runner_set(NULL); + _launcher_launched_ec_set(lc, NULL); + } + + lc->with_swl = EINA_TRUE; /* set swl flag */ + lc->target.pid = pid; + + ecs = _launcher_clients_find_by_pid(pid); + EINA_LIST_FOREACH(ecs, l, target_ec) + { + if (e_object_is_del(E_OBJECT(target_ec))) continue; + if (e_client_util_ignored_get(target_ec)) continue; + + ELOGF("LAUNCHER_SRV", "Found target_ec:%p", lc->ec, target_ec); + + // send prepare_shared_widget event to callee + sent = _launcher_prepare_shared_widget_forward_send(lc, target_ec); + EINA_SAFETY_ON_FALSE_GOTO(sent, send_stop); + + _launcher_state_set(lc, LAUNCHER_STATE_WAIT_RESPONSE_FROM_CALLEE); + break; + } + eina_list_free(ecs); + + if (!lc->target.ec) + { + ELOGF("LAUNCHER_SRV", "Can't find target_ec, Start Monitoring", lc->ec); + _launcher_state_set(lc, LAUNCHER_STATE_MONITORING); + } + + _launcher_handler_launcher_runner_set(lc); + + return; + +send_stop: + ELOGF("LAUNCHER_SRV", "can't process request(launcher_launch)", lc->ec); + _launcher_stop_send(lc); +} + +static void _launcher_cb_launching(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tws_lc, uint32_t serial) @@ -743,10 +925,25 @@ _launcher_cb_launch_done(struct wl_client *client EINA_UNUSED, return; } + if ((lc->direction == TWS_SERVICE_LAUNCHER_DIRECTION_FORWARD) && + (lc->with_swl)) + { + e_tzsh_shared_widget_launch_prepare_send(lc->target.ec, + TWS_SHARED_WIDGET_LAUNCH_PREPARE_STATE_WIDGET_SHOW); + return; + } + if (lc->direction == TWS_SERVICE_LAUNCHER_DIRECTION_FORWARD) - _launcher_post_forward(lc, EINA_TRUE); + { + _launcher_post_forward(lc, EINA_TRUE); + } else if (lc->direction == TWS_SERVICE_LAUNCHER_DIRECTION_BACKWARD) - _launcher_post_backward(lc, EINA_TRUE); + { + if (lc->with_swl) + e_tzsh_shared_widget_launch_prepare_send(lc->target.ec, + TWS_SHARED_WIDGET_LAUNCH_PREPARE_STATE_WIDGET_SHOW); + _launcher_post_backward(lc, EINA_TRUE); + } _launcher_handler_launcher_runner_unset(lc); _launcher_handler_launcher_pre_runner_set(lc); @@ -791,11 +988,39 @@ static const struct tws_service_launcher_interface _launcher_iface = { _launcher_cb_destroy, _launcher_cb_launch, + _launcher_cb_launch_with_shared_widget, _launcher_cb_launching, _launcher_cb_launch_done, _launcher_cb_launch_cancel, }; +static E_Client * +_launcher_handler_rsm_provider_client_find(E_Client *rsm_consumer_ec) +{ + E_Client *prov_ec = NULL; + Eina_List *tzrs_provs, *l; + + if (!rsm_consumer_ec->remote_surface.consumer) return NULL; + + tzrs_provs = e_comp_wl_remote_surface_providers_get(rsm_consumer_ec); + if (!tzrs_provs) return NULL; + + EINA_LIST_FOREACH(tzrs_provs, l, prov_ec) + { + /* check remote surface provider */ + if (!prov_ec->remote_surface.provider) continue; + if (prov_ec->visible) continue; + if (evas_object_visible_get(prov_ec->frame)) continue; + if (prov_ec->comp_data->mapped) continue; + + ELOGF("LAUNCHER_SRV", "Found prov_ec:%p", rsm_consumer_ec, prov_ec); + break; + } + eina_list_free(tzrs_provs); + + return prov_ec; +} + static E_Service_Launcher * _launcher_handler_launcher_find(E_Client *ec) { @@ -945,9 +1170,20 @@ _launcher_handler_cb_hook_vis_uniconify_render_running(void *data EINA_UNUSED, E { E_Service_Launcher *lc = NULL; E_Service_Launcher *runner, *pre_runner = NULL; - E_Client *activity = NULL; + E_Client *activity = NULL, *prov_ec = NULL; lc = _launcher_handler_launcher_find(ec); + if (!lc) + { + prov_ec = _launcher_handler_rsm_provider_client_find(ec); + if (prov_ec) + { + /* find launcher handler again with provider ec */ + lc = _launcher_handler_launcher_find(prov_ec); + /* set rsm provider ec pointer value to given ec (rsm consumer) */ + ec = prov_ec; + } + } EINA_SAFETY_ON_NULL_RETURN_VAL(lc, EINA_TRUE); activity = e_policy_visibility_main_activity_get(); @@ -981,9 +1217,17 @@ _launcher_handler_cb_hook_vis_uniconify_render_running(void *data EINA_UNUSED, E _launcher_handler_launcher_pre_runner_set(NULL); } - sent = _launcher_prepare_backward_send(lc, activity, activity, - (E_VIS_JOB_TYPE_UNICONIFY | - E_VIS_JOB_TYPE_UNICONIFY_BY_VISIBILITY)); + if (lc->with_swl) + sent = _launcher_prepare_shared_widget_backward_send + (lc, activity, activity, + (E_VIS_JOB_TYPE_UNICONIFY | + E_VIS_JOB_TYPE_UNICONIFY_BY_VISIBILITY)); + else + sent = _launcher_prepare_backward_send + (lc, activity, activity, + (E_VIS_JOB_TYPE_UNICONIFY | + E_VIS_JOB_TYPE_UNICONIFY_BY_VISIBILITY)); + if (!sent) return EINA_FALSE; _launcher_state_set(lc, LAUNCHER_STATE_PREPARING); @@ -999,12 +1243,21 @@ _launcher_handler_cb_hook_vis_lower(void *data EINA_UNUSED, E_Client *ec) { E_Service_Launcher *lc = NULL; E_Service_Launcher *runner, *pre_runner; - E_Client *activity = NULL; + E_Client *activity = NULL, *prov_ec = NULL; activity = e_policy_visibility_main_activity_get(); EINA_SAFETY_ON_NULL_RETURN_VAL(activity, EINA_FALSE); lc = _launcher_handler_launcher_find(activity); + if (!lc) + { + prov_ec = _launcher_handler_rsm_provider_client_find(activity); + if (prov_ec) + { + /* find launcher handler again with provider activity */ + lc = _launcher_handler_launcher_find(prov_ec); + } + } EINA_SAFETY_ON_NULL_RETURN_VAL(lc, EINA_FALSE); if (ec->visibility.obscured != E_VISIBILITY_UNOBSCURED) return EINA_FALSE; @@ -1030,7 +1283,11 @@ _launcher_handler_cb_hook_vis_lower(void *data EINA_UNUSED, E_Client *ec) _launcher_handler_launcher_pre_runner_set(NULL); } - sent = _launcher_prepare_backward_send(lc, activity, ec, E_VIS_JOB_TYPE_LOWER); + if (lc->with_swl) + sent = _launcher_prepare_shared_widget_backward_send(lc, activity, ec, E_VIS_JOB_TYPE_LOWER); + else + sent = _launcher_prepare_backward_send(lc, activity, ec, E_VIS_JOB_TYPE_LOWER); + if (!sent) return EINA_FALSE; _launcher_state_set(lc, LAUNCHER_STATE_PREPARING); @@ -1045,12 +1302,21 @@ _launcher_handler_cb_hook_vis_hide(void *data EINA_UNUSED, E_Client *ec) { E_Service_Launcher *lc = NULL; E_Service_Launcher *runner, *pre_runner; - E_Client *activity = NULL; + E_Client *activity = NULL, *prov_ec = NULL; activity = e_policy_visibility_main_activity_get(); EINA_SAFETY_ON_NULL_RETURN_VAL(activity, EINA_FALSE); lc = _launcher_handler_launcher_find(activity); + if (!lc) + { + prov_ec = _launcher_handler_rsm_provider_client_find(activity); + if (prov_ec) + { + /* find launcher handler again with provider ec */ + lc = _launcher_handler_launcher_find(prov_ec); + } + } EINA_SAFETY_ON_NULL_RETURN_VAL(lc, EINA_FALSE); if (ec->visibility.obscured != E_VISIBILITY_UNOBSCURED) return EINA_FALSE; @@ -1076,7 +1342,10 @@ _launcher_handler_cb_hook_vis_hide(void *data EINA_UNUSED, E_Client *ec) _launcher_handler_launcher_pre_runner_set(NULL); } - sent = _launcher_prepare_backward_send(lc, activity, ec, E_VIS_JOB_TYPE_HIDE); + if (lc->with_swl) + sent = _launcher_prepare_shared_widget_backward_send(lc, activity, ec, E_VIS_JOB_TYPE_HIDE); + else + sent = _launcher_prepare_backward_send(lc, activity, ec, E_VIS_JOB_TYPE_HIDE); if (!sent) return EINA_FALSE; _launcher_state_set(lc, LAUNCHER_STATE_PREPARING); @@ -1124,6 +1393,7 @@ _launcher_handler_cb_hook_intercept_show_helper(void *data, E_Client *ec) goto show_deny; break; case LAUNCHER_STATE_PREPARING: //waiting launcher client's preparation + case LAUNCHER_STATE_WAIT_RESPONSE_FROM_CALLEE: if (ec == runner->target.ec) goto show_deny; break; case LAUNCHER_STATE_LAUNCHING: //doing animation @@ -1134,10 +1404,20 @@ _launcher_handler_cb_hook_intercept_show_helper(void *data, E_Client *ec) if (ec->netwm.pid != runner->target.pid) goto show_allow; if (e_object_is_del(E_OBJECT(ec))) goto show_allow; - sent = _launcher_prepare_forward_send(runner, ec); - EINA_SAFETY_ON_FALSE_GOTO(sent, send_stop); + if (runner->with_swl) + { + sent = _launcher_prepare_shared_widget_forward_send(runner, ec); + EINA_SAFETY_ON_FALSE_GOTO(sent, send_stop); + + _launcher_state_set(runner, LAUNCHER_STATE_WAIT_RESPONSE_FROM_CALLEE); + } + else + { + sent = _launcher_prepare_forward_send(runner, ec); + EINA_SAFETY_ON_FALSE_GOTO(sent, send_stop); - _launcher_state_set(runner, LAUNCHER_STATE_PREPARING); + _launcher_state_set(runner, LAUNCHER_STATE_PREPARING); + } goto show_deny; default: goto show_allow; @@ -1388,3 +1668,58 @@ e_service_launcher_client_unset(E_Client *ec) _laundler = NULL; } } + +EINTERN void +e_service_launcher_prepare_send_with_shared_widget_info(E_Client *target_ec, + const char *shared_widget_info, + uint32_t state) +{ + E_Service_Launcher *lc = NULL; + Eina_Bool sent; + int x, y; + Eina_Iterator *hash_iter; + Eina_Bool found = EINA_FALSE; + + /* look for launcher service object which has given target_ec */ + hash_iter = eina_hash_iterator_data_new(_laundler->launcher_hash); + EINA_ITERATOR_FOREACH(hash_iter, lc) + { + if (lc->target.ec != target_ec) continue; + found = EINA_TRUE; + break; + } + eina_iterator_free(hash_iter); + + EINA_SAFETY_ON_FALSE_RETURN(found); + EINA_SAFETY_ON_NULL_RETURN(lc); + + if (state == TWS_SHARED_WIDGET_LAUNCH_PREPARE_STATE_WIDGET_HIDE) + { + e_client_pos_get(target_ec, &x, &y); + + sent = _launcher_prepare_send(lc, target_ec, x, y, shared_widget_info); + EINA_SAFETY_ON_FALSE_GOTO(sent, error); + + _launcher_state_set(lc, LAUNCHER_STATE_PREPARING); + } + else if (state == TWS_SHARED_WIDGET_LAUNCH_PREPARE_STATE_WIDGET_SHOW) + { + if (lc->direction == TWS_SERVICE_LAUNCHER_DIRECTION_FORWARD) + _launcher_post_forward(lc, EINA_TRUE); + else if (lc->direction == TWS_SERVICE_LAUNCHER_DIRECTION_BACKWARD) + _launcher_post_backward(lc, EINA_TRUE); + + _launcher_handler_launcher_runner_unset(lc); + _launcher_handler_launcher_pre_runner_set(lc); + _launcher_state_set(lc, LAUNCHER_STATE_DONE); + + tws_service_launcher_send_cleanup(lc->res, + lc->serial); + } + + return; + +error: + ELOGF("LAUNCHER_SRV", "Failed to send event(PREPARE:FORWARD)", lc->ec); + _launcher_post_forward(lc, EINA_FALSE); +} diff --git a/src/bin/services/e_service_launcher.h b/src/bin/services/e_service_launcher.h index 8f085c1..8ba60bf 100644 --- a/src/bin/services/e_service_launcher.h +++ b/src/bin/services/e_service_launcher.h @@ -7,5 +7,6 @@ EINTERN void e_service_launcher_resource_set(E_Client *ec, struct wl_resource *res_tws_lc); EINTERN void e_service_launcher_client_set(E_Client *ec); EINTERN void e_service_launcher_client_unset(E_Client *ec); +EINTERN void e_service_launcher_prepare_send_with_shared_widget_info(E_Client *target_ec, const char *shared_widget_info, uint32_t state); #endif -- 2.7.4