Fix NETWM Activate issue where the window would not raise or focus. This

works wrt fullscreen windows also.
Fix issues wrt hide/show race conditions that raster pointed out.
Fix issue where previous window was not shown again.



SVN revision: 46397
This commit is contained in:
Christopher Michael 2010-02-23 18:15:00 +00:00
parent 84301f2dde
commit 536cc819b1
5 changed files with 91 additions and 47 deletions

View File

@ -208,8 +208,10 @@ struct _E_Illume_Policy
void (*border_activate) (E_Border *bd); void (*border_activate) (E_Border *bd);
/**< pointer to the function that Illume will call when E signals a border post fetch. */ /**< pointer to the function that Illume will call when E signals a border post fetch. */
void (*border_post_fetch) (E_Border *bd); void (*border_post_fetch) (E_Border *bd);
/**< pointer to the funcion that Illume will call when E signals a border post assign. */ /**< pointer to the function that Illume will call when E signals a border post assign. */
void (*border_post_assign) (E_Border *bd); void (*border_post_assign) (E_Border *bd);
/**< pointer to the function that Illume will call when a border gets shown. */
void (*border_show) (E_Border *bd);
/**< pointer to the function that Illume will call when a Zone needs to update it's layout. */ /**< pointer to the function that Illume will call when a Zone needs to update it's layout. */
void (*zone_layout) (E_Zone *zone); void (*zone_layout) (E_Zone *zone);
/**< pointer to the function that Illume will call when a Zone gets moved or resized. */ /**< pointer to the function that Illume will call when a Zone gets moved or resized. */

View File

@ -11,6 +11,7 @@ static int _e_mod_policy_cb_border_add(void *data __UNUSED__, int type __UNUSED_
static int _e_mod_policy_cb_border_del(void *data __UNUSED__, int type __UNUSED__, void *event); static int _e_mod_policy_cb_border_del(void *data __UNUSED__, int type __UNUSED__, void *event);
static int _e_mod_policy_cb_border_focus_in(void *data __UNUSED__, int type __UNUSED__, void *event); static int _e_mod_policy_cb_border_focus_in(void *data __UNUSED__, int type __UNUSED__, void *event);
static int _e_mod_policy_cb_border_focus_out(void *data __UNUSED__, int type __UNUSED__, void *event); static int _e_mod_policy_cb_border_focus_out(void *data __UNUSED__, int type __UNUSED__, void *event);
static int _e_mod_policy_cb_border_show(void *data __UNUSED__, int type __UNUSED__, void *event);
static int _e_mod_policy_cb_zone_move_resize(void *data __UNUSED__, int type __UNUSED__, void *event); static int _e_mod_policy_cb_zone_move_resize(void *data __UNUSED__, int type __UNUSED__, void *event);
static int _e_mod_policy_cb_client_message(void *data __UNUSED__, int type __UNUSED__, void *event); static int _e_mod_policy_cb_client_message(void *data __UNUSED__, int type __UNUSED__, void *event);
static int _e_mod_policy_cb_window_property(void *data __UNUSED__, int type __UNUSED__, void *event); static int _e_mod_policy_cb_window_property(void *data __UNUSED__, int type __UNUSED__, void *event);
@ -246,6 +247,11 @@ _e_mod_policy_handlers_add(void)
ecore_event_handler_add(E_EVENT_BORDER_FOCUS_OUT, ecore_event_handler_add(E_EVENT_BORDER_FOCUS_OUT,
_e_mod_policy_cb_border_focus_out, _e_mod_policy_cb_border_focus_out,
NULL)); NULL));
_policy_hdls =
eina_list_append(_policy_hdls,
ecore_event_handler_add(E_EVENT_BORDER_SHOW,
_e_mod_policy_cb_border_show,
NULL));
_policy_hdls = _policy_hdls =
eina_list_append(_policy_hdls, eina_list_append(_policy_hdls,
ecore_event_handler_add(E_EVENT_ZONE_MOVE_RESIZE, ecore_event_handler_add(E_EVENT_ZONE_MOVE_RESIZE,
@ -350,6 +356,18 @@ _e_mod_policy_cb_border_focus_out(void *data __UNUSED__, int type __UNUSED__, vo
return 1; return 1;
} }
static int
_e_mod_policy_cb_border_show(void *data __UNUSED__, int type __UNUSED__, void *event)
{
E_Event_Border_Show *ev;
ev = event;
if ((_policy) && (_policy->funcs.border_show))
_policy->funcs.border_show(ev->border);
return 1;
}
static int static int
_e_mod_policy_cb_zone_move_resize(void *data __UNUSED__, int type __UNUSED__, void *event) _e_mod_policy_cb_zone_move_resize(void *data __UNUSED__, int type __UNUSED__, void *event)
{ {
@ -497,7 +515,8 @@ _e_mod_policy_cb_hook_layout(void *data __UNUSED__, void *data2 __UNUSED__)
EINA_LIST_FOREACH(e_border_client_list(), l, bd) EINA_LIST_FOREACH(e_border_client_list(), l, bd)
{ {
if ((bd->new_client) || (bd->pending_move_resize) || if ((bd->new_client) || (bd->pending_move_resize) ||
(bd->changes.pos) || (bd->changes.size) || (bd->changes.visible)) (bd->changes.pos) || (bd->changes.size) || (bd->changes.visible) ||
(bd->need_shape_export) || (bd->need_shape_merge))
{ {
/* NB: this border changed. add it's zone to list of what needs /* NB: this border changed. add it's zone to list of what needs
* updating. This is done so we do not waste cpu cycles * updating. This is done so we do not waste cpu cycles

View File

@ -19,6 +19,7 @@ e_illume_policy_init(E_Illume_Policy *p)
p->funcs.border_activate = _policy_border_activate; p->funcs.border_activate = _policy_border_activate;
p->funcs.border_post_fetch = _policy_border_post_fetch; p->funcs.border_post_fetch = _policy_border_post_fetch;
p->funcs.border_post_assign = _policy_border_post_assign; p->funcs.border_post_assign = _policy_border_post_assign;
p->funcs.border_show = _policy_border_show;
p->funcs.zone_layout = _policy_zone_layout; p->funcs.zone_layout = _policy_zone_layout;
p->funcs.zone_move_resize = _policy_zone_move_resize; p->funcs.zone_move_resize = _policy_zone_move_resize;
p->funcs.zone_mode_change = _policy_zone_mode_change; p->funcs.zone_mode_change = _policy_zone_mode_change;
@ -43,6 +44,7 @@ e_illume_policy_shutdown(E_Illume_Policy *p)
p->funcs.border_activate = NULL; p->funcs.border_activate = NULL;
p->funcs.border_post_fetch = NULL; p->funcs.border_post_fetch = NULL;
p->funcs.border_post_assign = NULL; p->funcs.border_post_assign = NULL;
p->funcs.border_show = NULL;
p->funcs.zone_layout = NULL; p->funcs.zone_layout = NULL;
p->funcs.zone_move_resize = NULL; p->funcs.zone_move_resize = NULL;
p->funcs.zone_mode_change = NULL; p->funcs.zone_mode_change = NULL;

View File

@ -72,13 +72,14 @@ _policy_border_set_focus(E_Border *bd)
* *
* This is potentially useless as THIS policy * This is potentially useless as THIS policy
* makes all windows borderless anyway, but it's in here for * makes all windows borderless anyway, but it's in here for
* completeness */ * completeness
e_border_focus_latest_set(bd); e_border_focus_latest_set(bd);
if (bd->bg_object) if (bd->bg_object)
edje_object_signal_emit(bd->bg_object, "e,state,focused", "e"); edje_object_signal_emit(bd->bg_object, "e,state,focused", "e");
if (bd->icon_object) if (bd->icon_object)
edje_object_signal_emit(bd->icon_object, "e,state,focused", "e"); edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
e_focus_event_focus_in(bd); e_focus_event_focus_in(bd);
*/
} }
} }
} }
@ -118,7 +119,7 @@ _policy_border_hide_below(E_Border *bd)
int pos = 0, i; int pos = 0, i;
// printf("Hide Borders Below: %s %d %d\n", // printf("Hide Borders Below: %s %d %d\n",
// bd->client.icccm.class, bd->x, bd->y); // bd->client.icccm.name, bd->x, bd->y);
/* determine layering position */ /* determine layering position */
if (bd->layer <= 0) pos = 0; if (bd->layer <= 0) pos = 0;
@ -129,7 +130,7 @@ _policy_border_hide_below(E_Border *bd)
else pos = 5; else pos = 5;
/* Find the windows below this one */ /* Find the windows below this one */
for (i = pos; i >= 0; i--) for (i = pos; i >= 2; i--)
{ {
Eina_List *l; Eina_List *l;
E_Border *b; E_Border *b;
@ -155,7 +156,7 @@ _policy_border_hide_below(E_Border *bd)
else else
{ {
/* we need to check x/y position */ /* we need to check x/y position */
if ((b->x == bd->x) && (b->y == bd->y)) if (E_CONTAINS(bd->x, bd->y, bd->w, bd->h, b->x, b->y, b->w, b->h))
{ {
if (b->visible) e_border_hide(b, 2); if (b->visible) e_border_hide(b, 2);
} }
@ -181,7 +182,7 @@ _policy_border_show_below(E_Border *bd)
else pos = 5; else pos = 5;
/* Find the windows below this one */ /* Find the windows below this one */
for (i = pos; i >= 0; i--) for (i = pos; i >= 2; i--)
{ {
Eina_List *l; Eina_List *l;
E_Border *b; E_Border *b;
@ -204,14 +205,16 @@ _policy_border_show_below(E_Border *bd)
{ {
if (!b->visible) e_border_show(b); if (!b->visible) e_border_show(b);
_policy_border_set_focus(b); _policy_border_set_focus(b);
return;
} }
else else
{ {
/* need to check x/y position */ /* need to check x/y position */
if ((b->x == bd->x) && (b->y == bd->y)) if (E_CONTAINS(bd->x, bd->y, bd->w, bd->h, b->x, b->y, b->w, b->h))
{ {
if (!b->visible) e_border_show(b); if (!b->visible) e_border_show(b);
_policy_border_set_focus(b); _policy_border_set_focus(b);
return;
} }
} }
} }
@ -535,9 +538,6 @@ _policy_zone_layout_fullscreen(E_Border *bd)
/* set layer if needed */ /* set layer if needed */
if (bd->layer != POL_FULLSCREEN_LAYER) if (bd->layer != POL_FULLSCREEN_LAYER)
e_border_layer_set(bd, POL_FULLSCREEN_LAYER); e_border_layer_set(bd, POL_FULLSCREEN_LAYER);
/* hide any apps/windows below this one */
_policy_border_hide_below(bd);
} }
static void static void
@ -571,9 +571,6 @@ _policy_zone_layout_app_single(E_Border *bd, E_Illume_Config_Zone *cz)
/* set layer if needed */ /* set layer if needed */
if (bd->layer != POL_APP_LAYER) if (bd->layer != POL_APP_LAYER)
e_border_layer_set(bd, POL_APP_LAYER); e_border_layer_set(bd, POL_APP_LAYER);
/* hide any apps/windows below this one */
_policy_border_hide_below(bd);
} }
static void static void
@ -641,9 +638,6 @@ _policy_zone_layout_app_dual_top(E_Border *bd, E_Illume_Config_Zone *cz)
/* set layer if needed */ /* set layer if needed */
if (bd->layer != POL_APP_LAYER) if (bd->layer != POL_APP_LAYER)
e_border_layer_set(bd, POL_APP_LAYER); e_border_layer_set(bd, POL_APP_LAYER);
/* hide any apps/windows below this one */
_policy_border_hide_below(bd);
} }
static void static void
@ -684,9 +678,6 @@ _policy_zone_layout_app_dual_custom(E_Border *bd, E_Illume_Config_Zone *cz)
/* set layer if needed */ /* set layer if needed */
if (bd->layer != POL_APP_LAYER) if (bd->layer != POL_APP_LAYER)
e_border_layer_set(bd, POL_APP_LAYER); e_border_layer_set(bd, POL_APP_LAYER);
/* hide any apps/windows below this one */
_policy_border_hide_below(bd);
} }
static void static void
@ -729,9 +720,6 @@ _policy_zone_layout_app_dual_left(E_Border *bd, E_Illume_Config_Zone *cz)
/* set layer if needed */ /* set layer if needed */
if (bd->layer != POL_APP_LAYER) if (bd->layer != POL_APP_LAYER)
e_border_layer_set(bd, POL_APP_LAYER); e_border_layer_set(bd, POL_APP_LAYER);
/* hide any apps/windows below this one */
_policy_border_hide_below(bd);
} }
static void static void
@ -866,9 +854,6 @@ _policy_zone_layout_conformant_single(E_Border *bd, E_Illume_Config_Zone *cz)
/* set layer if needed */ /* set layer if needed */
if (bd->layer != POL_CONFORMANT_LAYER) if (bd->layer != POL_CONFORMANT_LAYER)
e_border_layer_set(bd, POL_CONFORMANT_LAYER); e_border_layer_set(bd, POL_CONFORMANT_LAYER);
/* hide any apps/windows below this one */
_policy_border_hide_below(bd);
} }
static void static void
@ -897,9 +882,6 @@ _policy_zone_layout_conformant_dual_top(E_Border *bd, E_Illume_Config_Zone *cz)
/* set layer if needed */ /* set layer if needed */
if (bd->layer != POL_CONFORMANT_LAYER) if (bd->layer != POL_CONFORMANT_LAYER)
e_border_layer_set(bd, POL_CONFORMANT_LAYER); e_border_layer_set(bd, POL_CONFORMANT_LAYER);
/* hide any apps/windows below this one */
_policy_border_hide_below(bd);
} }
static void static void
@ -928,9 +910,6 @@ _policy_zone_layout_conformant_dual_custom(E_Border *bd, E_Illume_Config_Zone *c
/* set layer if needed */ /* set layer if needed */
if (bd->layer != POL_CONFORMANT_LAYER) if (bd->layer != POL_CONFORMANT_LAYER)
e_border_layer_set(bd, POL_CONFORMANT_LAYER); e_border_layer_set(bd, POL_CONFORMANT_LAYER);
/* hide any apps/windows below this one */
_policy_border_hide_below(bd);
} }
static void static void
@ -958,9 +937,6 @@ _policy_zone_layout_conformant_dual_left(E_Border *bd, E_Illume_Config_Zone *cz)
/* set layer if needed */ /* set layer if needed */
if (bd->layer != POL_CONFORMANT_LAYER) if (bd->layer != POL_CONFORMANT_LAYER)
e_border_layer_set(bd, POL_CONFORMANT_LAYER); e_border_layer_set(bd, POL_CONFORMANT_LAYER);
/* hide any apps/windows below this one */
_policy_border_hide_below(bd);
} }
@ -1022,7 +998,7 @@ _policy_border_del(E_Border *bd)
} }
} }
/* show borders below this one */ /* show the border below this one */
_policy_border_show_below(bd); _policy_border_show_below(bd);
} }
@ -1060,7 +1036,7 @@ _policy_border_activate(E_Border *bd)
// printf("Border Activate: %s\n", bd->client.icccm.name); // printf("Border Activate: %s\n", bd->client.icccm.name);
/* NB: stolen borders may or may not need focus call...have to test */ /* NB: stolen borders may or may not need focus call...have to test */
// if (bd->stolen) return; if (bd->stolen) return;
/* conformant windows hide the softkey */ /* conformant windows hide the softkey */
sft = e_illume_border_softkey_get(bd->zone); sft = e_illume_border_softkey_get(bd->zone);
@ -1076,8 +1052,42 @@ _policy_border_activate(E_Border *bd)
} }
} }
/* set focus on new border is we can */ /* NB: We cannot use our set_focus function here because it does,
_policy_border_set_focus(bd); * occasionally fall through wrt E's focus policy, so cherry pick the good
* parts and use here :) */
/* if the border is iconified then uniconify */
if (bd->iconic)
{
/* if the user is allowed to uniconify, then do it */
if (!bd->lock_user_iconify) e_border_uniconify(bd);
}
/* set very high layer for this window as it needs attention and thus
* should show above everything */
e_border_layer_set(bd, 250);
/* if we can raise the border do it */
if (!bd->lock_user_stacking) e_border_raise(bd);
/* focus the border */
e_border_focus_set(bd, 1, 1);
/* NB: since we skip needless border evals when container layout
* is called (to save cpu cycles), we need to
* signal this border that it's focused so that the edj gets
* updated.
*
* This is potentially useless as THIS policy
* makes all windows borderless anyway, but it's in here for
* completeness
e_border_focus_latest_set(bd);
if (bd->bg_object)
edje_object_signal_emit(bd->bg_object, "e,state,focused", "e");
if (bd->icon_object)
edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
e_focus_event_focus_in(bd);
*/
} }
void void
@ -1131,6 +1141,21 @@ _policy_border_post_assign(E_Border *bd)
bd->lock_border = 1; bd->lock_border = 1;
} }
void
_policy_border_show(E_Border *bd)
{
/* make sure we have a name so that we don't handle windows like E's root */
if (!bd->client.icccm.name) return;
/* trap for special windows so we can ignore hides below them */
if (e_illume_border_is_indicator(bd)) return;
if (e_illume_border_is_softkey(bd)) return;
if (e_illume_border_is_quickpanel(bd)) return;
if (e_illume_border_is_keyboard(bd)) return;
_policy_border_hide_below(bd);
}
void void
_policy_zone_layout(E_Zone *zone) _policy_zone_layout(E_Zone *zone)
{ {
@ -1154,7 +1179,8 @@ _policy_zone_layout(E_Zone *zone)
/* only update layout for this border if it really needs it */ /* only update layout for this border if it really needs it */
if ((!bd->new_client) && (!bd->changes.pos) && (!bd->changes.size) && if ((!bd->new_client) && (!bd->changes.pos) && (!bd->changes.size) &&
(!bd->changes.visible) && (!bd->pending_move_resize)) continue; (!bd->changes.visible) && (!bd->pending_move_resize) &&
(!bd->need_shape_export) && (!bd->need_shape_merge)) continue;
/* are we laying out an indicator ? */ /* are we laying out an indicator ? */
if (e_illume_border_is_indicator(bd)) if (e_illume_border_is_indicator(bd))
@ -1259,7 +1285,6 @@ _policy_zone_layout(E_Zone *zone)
_policy_zone_layout_app_dual_left(bd, cz); _policy_zone_layout_app_dual_left(bd, cz);
} }
} }
} }
} }
@ -1356,9 +1381,6 @@ _policy_zone_close(E_Zone *zone)
/* close this border */ /* close this border */
e_border_act_close_begin(bd); e_border_act_close_begin(bd);
/* revert focus to previous border (if possible) */
_policy_focus_back(zone);
} }
void void
@ -1476,9 +1498,7 @@ _policy_focus_home(E_Zone *zone)
if (!bd->visible) e_border_show(bd); if (!bd->visible) e_border_show(bd);
/* no point in calling set_focus here as home windows do not accept it _policy_border_set_focus(bd);
* anyway, so just raise */
e_border_raise(bd);
} }
void void

View File

@ -20,6 +20,7 @@ void _policy_border_focus_out(E_Border *bd);
void _policy_border_activate(E_Border *bd); void _policy_border_activate(E_Border *bd);
void _policy_border_post_fetch(E_Border *bd); void _policy_border_post_fetch(E_Border *bd);
void _policy_border_post_assign(E_Border *bd); void _policy_border_post_assign(E_Border *bd);
void _policy_border_show(E_Border *bd);
void _policy_zone_layout(E_Zone *zone); void _policy_zone_layout(E_Zone *zone);
void _policy_zone_move_resize(E_Zone *zone); void _policy_zone_move_resize(E_Zone *zone);
void _policy_zone_mode_change(E_Zone *zone, Ecore_X_Atom mode); void _policy_zone_mode_change(E_Zone *zone, Ecore_X_Atom mode);