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
This commit is contained in:
Gwanglim Lee 2014-06-09 13:30:04 -04:00 committed by Mike Blumenkrantz
parent fc7e06807d
commit 571a696ab8
4 changed files with 205 additions and 115 deletions

View File

@ -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);

View File

@ -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

View File

@ -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;
}
}
}
}

View File

@ -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;