discomfitor pushed a commit to branch master. http://git.enlightenment.org/core/enlightenment.git/commit/?id=571a696ab864b8f9aa3fd46abff6a8bcf4c59b88
commit 571a696ab864b8f9aa3fd46abff6a8bcf4c59b88 Author: Gwanglim Lee <[email protected]> Date: Mon Jun 9 13:30:04 2014 -0400 fix visibility issues related to desktop window profile Summary: 1. fix window profile change request with wrong x window id 2. refactoring desktop window profile codes to handle e_client_desk_set correctly Test Plan: 1. enlightenment: Settings Panel -> Screen -> Virtual Desktops -> Check "Use desktop window profile" -> Apply 2. open an efl app on 1st desktop (0-0) 3. set a window remember on efl app window 4. go to 2nd desktop (1-0) 5. open an efl app again. it should be positioned on the previous desktop (0-0) Reviewers: zmike, raster CC: cedric Differential Revision: https://phab.enlightenment.org/D926 --- src/bin/e_client.c | 110 +++++++++++++++++++++++++--- src/bin/e_client.h | 14 ++-- src/bin/e_comp_canvas.c | 8 ++- src/bin/e_comp_x.c | 188 ++++++++++++++++++++++++------------------------ 4 files changed, 205 insertions(+), 115 deletions(-) diff --git a/src/bin/e_client.c b/src/bin/e_client.c index c517ae5..a2bb7a7 100644 --- a/src/bin/e_client.c +++ b/src/bin/e_client.c @@ -184,6 +184,41 @@ _e_client_cb_drag_finished(E_Drag *drag, int dropped EINA_UNUSED) e_object_unref(E_OBJECT(ec)); client_drag = NULL; } + +static void +_e_client_desk_window_profile_wait_desk_delfn(void *data, void *obj) +{ + E_Client *ec = data; + E_Desk *desk = obj, *new_desk; + const char *p; + int i; + + if (e_object_is_del(E_OBJECT(ec))) return; + + ec->e.state.profile.wait_desk_delfn = NULL; + eina_stringshare_replace(&ec->e.state.profile.wait, NULL); + ec->e.state.profile.wait_desk = NULL; + ec->e.state.profile.wait_for_done = 0; + + if (!ec->e.state.profile.use) return; + + new_desk = e_comp_desk_window_profile_get(ec->comp, desk->window_profile); + if (new_desk) + e_client_desk_set(ec, new_desk); + else + { + for (i = 0; i < ec->e.state.profile.num; i++) + { + p = ec->e.state.profile.available_list[i]; + new_desk = e_comp_desk_window_profile_get(ec->comp, p); + if (new_desk) + { + e_client_desk_set(ec, new_desk); + break; + } + } + } +} //////////////////////////////////////////////// @@ -412,6 +447,8 @@ _e_client_free(E_Client *ec) ec->comp->new_clients--; if (ec->e.state.profile.use) { + e_client_desk_window_profile_wait_desk_set(ec, NULL); + if (ec->e.state.profile.available_list) { int i; @@ -422,6 +459,8 @@ _e_client_free(E_Client *ec) ec->e.state.profile.num = 0; + eina_stringshare_replace(&ec->e.state.profile.set, NULL); + eina_stringshare_replace(&ec->e.state.profile.wait, NULL); eina_stringshare_replace(&ec->e.state.profile.name, NULL); ec->e.state.profile.wait_for_done = 0; ec->e.state.profile.use = 0; @@ -2393,6 +2432,56 @@ e_client_new(E_Comp *c, E_Pixmap *cp, int first_map, int internal) return ec; } +EAPI Eina_Bool +e_client_desk_window_profile_available_check(E_Client *ec, const char *profile) +{ + int i; + + E_OBJECT_CHECK_RETURN(ec, EINA_FALSE); + E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(profile, EINA_FALSE); + EINA_SAFETY_ON_FALSE_RETURN_VAL(ec->e.state.profile.use, EINA_FALSE); + if (ec->e.state.profile.num == 0) return EINA_TRUE; + + for (i = 0; i < ec->e.state.profile.num; i++) + { + if (!e_util_strcmp(ec->e.state.profile.available_list[i], + profile)) + return EINA_TRUE; + } + + return EINA_FALSE; +} + +EAPI void +e_client_desk_window_profile_wait_desk_set(E_Client *ec, E_Desk *desk) +{ + E_OBJECT_CHECK(ec); + E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE); + E_OBJECT_CHECK(desk); + E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE); + + if (ec->e.state.profile.wait_desk == desk) return; + + if (ec->e.state.profile.wait_desk_delfn) + { + if (ec->e.state.profile.wait_desk) + e_object_delfn_del(E_OBJECT(ec->e.state.profile.wait_desk), + ec->e.state.profile.wait_desk_delfn); + ec->e.state.profile.wait_desk_delfn = NULL; + } + + if (desk) + { + ec->e.state.profile.wait_desk_delfn = + e_object_delfn_add(E_OBJECT(desk), + _e_client_desk_window_profile_wait_desk_delfn, + ec); + } + + ec->e.state.profile.wait_desk = desk; +} + EAPI void e_client_desk_set(E_Client *ec, E_Desk *desk) { @@ -2407,20 +2496,19 @@ e_client_desk_set(E_Client *ec, E_Desk *desk) if ((e_config->use_desktop_window_profile) && (ec->e.state.profile.use)) { - ec->e.state.profile.desk_num = desk->x + (desk->y * desk->zone->desk_x_count); - ec->e.state.profile.zone_num = desk->zone->num; - ec->e.state.profile.comp_num = desk->zone->comp->man->num; - if (ec->e.state.profile.name != desk->window_profile) + if (e_util_strcmp(ec->e.state.profile.name, desk->window_profile)) { - eina_stringshare_refplace(&ec->e.state.profile.set, desk->window_profile); - EC_CHANGED(ec); - return; + if (e_client_desk_window_profile_available_check(ec, desk->window_profile)) + { + eina_stringshare_replace(&ec->e.state.profile.set, desk->window_profile); + eina_stringshare_replace(&ec->e.state.profile.wait, NULL); + ec->e.state.profile.wait_for_done = 0; + e_client_desk_window_profile_wait_desk_set(ec, desk); + EC_CHANGED(ec); + } } - if (ec->e.state.profile.wait_for_done) return; } - ec->e.state.profile.desk_num = - ec->e.state.profile.zone_num = - ec->e.state.profile.comp_num = -1; + if (ec->fullscreen) { ec->desk->fullscreen_clients = eina_list_remove(ec->desk->fullscreen_clients, ec); diff --git a/src/bin/e_client.h b/src/bin/e_client.h index 43183cd..67698a1 100644 --- a/src/bin/e_client.h +++ b/src/bin/e_client.h @@ -498,12 +498,12 @@ struct E_Client Eina_Stringshare *name; Eina_Stringshare **available_list; Eina_Stringshare *set; - char desk_num; - char zone_num; - char comp_num; - int num; - unsigned char wait_for_done : 1; - unsigned char use : 1; + Eina_Stringshare *wait; + E_Desk *wait_desk; + E_Object_Delfn *wait_desk_delfn; + int num; + unsigned char wait_for_done : 1; + unsigned char use : 1; } profile; unsigned char centered : 1; unsigned char video : 1; @@ -810,5 +810,7 @@ EAPI int e_client_pointer_warp_to_center_now(E_Client *ec); EAPI int e_client_pointer_warp_to_center(E_Client *ec); EAPI void e_client_redirected_set(E_Client *ec, Eina_Bool set); EAPI Eina_Bool e_client_is_stacking(const E_Client *ec); +EAPI Eina_Bool e_client_desk_window_profile_available_check(E_Client *ec, const char *profile); +EAPI void e_client_desk_window_profile_wait_desk_set(E_Client *ec, E_Desk *desk); #include "e_client.x" #endif diff --git a/src/bin/e_comp_canvas.c b/src/bin/e_comp_canvas.c index b2efecf..d04bcb9 100644 --- a/src/bin/e_comp_canvas.c +++ b/src/bin/e_comp_canvas.c @@ -265,8 +265,12 @@ e_comp_desk_window_profile_get(E_Comp *c, const char *profile) for (y = 0; y < zone->desk_y_count; y++) { E_Desk *desk = e_desk_at_xy_get(zone, x, y); - if (!e_util_strcmp(desk->window_profile, profile)) - return desk; + if (desk) + { + if (e_object_is_del(E_OBJECT(desk))) continue; + if (!e_util_strcmp(desk->window_profile, profile)) + return desk; + } } } } diff --git a/src/bin/e_comp_x.c b/src/bin/e_comp_x.c index fc0f420..7231a56 100644 --- a/src/bin/e_comp_x.c +++ b/src/bin/e_comp_x.c @@ -1864,18 +1864,16 @@ _e_comp_x_message(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_X_Event_Cl { if (ec->e.state.profile.use) { - char *profile; - profile = ecore_x_atom_name_get(ev->data.l[1]); - ecore_x_e_window_profile_change_request_send(e_client_util_pwin_get(ec), profile); - eina_stringshare_replace(&ec->e.state.profile.set, profile); - ec->e.state.profile.wait_for_done = 1; - if (ec->desk && (!e_util_strcmp(ec->desk->window_profile, profile))) + char *p = ecore_x_atom_name_get(ev->data.l[1]); + if (e_client_desk_window_profile_available_check(ec, p)) { - ec->e.state.profile.desk_num = ec->desk->x + (ec->desk->y * ec->desk->zone->desk_x_count); - ec->e.state.profile.zone_num = ec->desk->zone->num; - ec->e.state.profile.comp_num = ec->desk->zone->comp->man->num; + if (e_util_strcmp(p, ec->desk->window_profile)) + { + E_Desk *desk = e_comp_desk_window_profile_get(ec->comp, p); + if (desk) e_client_desk_set(ec, desk); + } } - free(profile); + free(p); } } else if (ev->message_type == ECORE_X_ATOM_NET_ACTIVE_WINDOW) @@ -1919,36 +1917,21 @@ _e_comp_x_message(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_X_Event_Cl if ((ec->e.state.profile.use) && (ec->e.state.profile.wait_for_done)) { - char *profile; - - profile = ecore_x_atom_name_get(ev->data.l[1]); - if ((!e_util_strcmp(profile, ec->e.state.profile.set)) && (ec->e.state.profile.desk_num != -1)) + char *p = ecore_x_atom_name_get(ev->data.l[1]); + if (!e_util_strcmp(ec->e.state.profile.wait, p)) { - E_Desk *desk; - E_Comp *comp; - E_Zone *zone; - unsigned int d, z, c; - - c = MIN(ec->e.state.profile.comp_num, eina_list_count(e_comp_list()) - 1); - comp = eina_list_nth(e_comp_list(), c); - z = MIN(ec->e.state.profile.zone_num, eina_list_count(comp->zones) - 1); - zone = e_comp_zone_number_get(comp, z); - d = MIN(ec->e.state.profile.desk_num, (zone->desk_x_count * zone->desk_y_count) - 1); - desk = zone->desks[d]; - - if (profile) - eina_stringshare_replace(&ec->e.state.profile.name, profile); - + eina_stringshare_replace(&ec->e.state.profile.wait, NULL); ec->e.state.profile.wait_for_done = 0; - - if ((!ec->desk) || e_util_strcmp(ec->desk->window_profile, ec->e.state.profile.name) || (ec->desk != desk)) + E_Desk *desk = ec->e.state.profile.wait_desk; + if ((desk) && (desk != ec->desk)) { - if (ec->e.state.profile.name == desk->window_profile) - e_client_desk_set(ec, desk); + eina_stringshare_replace(&ec->e.state.profile.name, + desk->window_profile); + e_client_desk_set(ec, desk); } + e_client_desk_window_profile_wait_desk_set(ec, NULL); } - eina_stringshare_replace(&ec->e.state.profile.set, NULL); - free(profile); + free(p); } } return ECORE_CALLBACK_PASS_ON; @@ -2955,6 +2938,8 @@ _e_comp_x_hook_client_fetch(void *d EINA_UNUSED, E_Client *ec) int n, i, res; unsigned int use; + ec->e.state.profile.use = 0; + if (ec->e.state.profile.name) { eina_stringshare_del(ec->e.state.profile.name); @@ -2991,7 +2976,7 @@ _e_comp_x_hook_client_fetch(void *d EINA_UNUSED, E_Client *ec) char *name = ecore_x_atom_name_get(val); if (name) { - ec->e.state.profile.name = eina_stringshare_add(name); + ec->e.state.profile.set = eina_stringshare_add(name); free(name); } } @@ -3010,12 +2995,6 @@ _e_comp_x_hook_client_fetch(void *d EINA_UNUSED, E_Client *ec) ec->e.fetch.profile = 0; } - if (ec->e.state.profile.set) - { - ecore_x_e_window_profile_change_request_send(e_client_util_pwin_get(ec), - ec->e.state.profile.set); - ec->e.state.profile.wait_for_done = 1; - } if (ec->changes.prop || ec->netwm.fetch.type) { e_hints_window_type_get(ec); @@ -3853,60 +3832,6 @@ _e_comp_x_hook_client_fetch(void *d EINA_UNUSED, E_Client *ec) } ec->netwm.update.state = 0; } - - if ((e_config->use_desktop_window_profile) && (need_desk_set)) - { - E_Desk *desk_use = NULL; - - if (!(ec->e.state.profile.name) && - (ec->e.state.profile.num >= 1)) - { - const char *p = NULL; - int i; - for (i = 0; i < ec->e.state.profile.num; i++) - { - if (!ec->e.state.profile.available_list[i]) - continue; - p = ec->e.state.profile.available_list[i]; - if (!e_util_strcmp(ec->desk->window_profile, p)) - { - desk_use = ec->desk; - break; - } - } - - if (!desk_use) - { - E_Comp *c = ec->comp; - E_Desk *desk = NULL; - - for (i = 0; i < ec->e.state.profile.num; i++) - { - if (!ec->e.state.profile.available_list[i]) - continue; - p = ec->e.state.profile.available_list[i]; - desk = e_comp_desk_window_profile_get(c, p); - if ((desk) && (ec->desk != desk)) - { - desk_use = desk; - break; - } - } - } - } - - if (!desk_use) - desk_use = ec->desk; - ec->e.state.profile.desk_num = desk_use->x + (desk_use->y * desk_use->zone->desk_x_count); - ec->e.state.profile.zone_num = desk_use->zone->num; - ec->e.state.profile.comp_num = desk_use->zone->comp->man->num; - eina_stringshare_refplace(&ec->e.state.profile.name, desk_use->window_profile); - eina_stringshare_refplace(&ec->e.state.profile.set, desk_use->window_profile); - - ecore_x_e_window_profile_change_request_send(win, - ec->e.state.profile.name); - ec->e.state.profile.wait_for_done = 1; - } if (ec->comp_data->fetch_exe) { E_Exec_Instance *inst; @@ -4025,6 +3950,77 @@ _e_comp_x_hook_client_fetch(void *d EINA_UNUSED, E_Client *ec) } ec->comp_data->fetch_exe = 0; } + if ((e_config->use_desktop_window_profile) && (need_desk_set)) + { + E_Desk *desk = NULL; + const char *p, *p2; + Eina_Bool set = EINA_FALSE; + int i; + + /* set desktop using given initial profile */ + p = ec->e.state.profile.set; + if (p) + { + if (!e_util_strcmp(p, ec->desk->window_profile)) + { + e_client_desk_window_profile_wait_desk_set(ec, ec->desk); + set = EINA_TRUE; + } + else + { + desk = e_comp_desk_window_profile_get(ec->comp, p); + if (desk) + { + e_client_desk_set(ec, desk); + set = EINA_TRUE; + } + } + } + + if (!set) + { + /* try to find desktop using available profile list */ + for (i = 0; i < ec->e.state.profile.num; i++) + { + p2 = ec->e.state.profile.available_list[i]; + if (!e_util_strcmp(p2, ec->desk->window_profile)) + { + eina_stringshare_replace(&ec->e.state.profile.set, p2); + e_client_desk_window_profile_wait_desk_set(ec, ec->desk); + set = EINA_TRUE; + break; + } + } + if (!set) + { + for (i = 0; i < ec->e.state.profile.num; i++) + { + p2 = ec->e.state.profile.available_list[i]; + desk = e_comp_desk_window_profile_get(ec->comp, p2); + if (desk) + { + e_client_desk_set(ec, desk); + set = EINA_TRUE; + break; + } + } + } + } + + if (!set) + { + eina_stringshare_replace(&ec->e.state.profile.set, ec->desk->window_profile); + e_client_desk_window_profile_wait_desk_set(ec, ec->desk); + } + } + if (ec->e.state.profile.set) + { + ecore_x_e_window_profile_change_request_send(e_client_util_win_get(ec), + ec->e.state.profile.set); + eina_stringshare_replace(&ec->e.state.profile.wait, ec->e.state.profile.set); + ec->e.state.profile.wait_for_done = 1; + eina_stringshare_replace(&ec->e.state.profile.set, NULL); + } ec->changes.prop = 0; if (rem_change) e_remember_update(ec); if (!ec->comp_data->reparented) ec->changes.border = 0; --
