forked from enlightenment/enlightenment
break out desklock into display server-able hooks
if we're running in a non-X environment, we can't very well expect that using X calls to hide/show windows for desklock is going to work as expected. now a compositor backend can add a pre or post desklock hook to hide/show its clients as necessary
This commit is contained in:
parent
3948c1c910
commit
a31e8a70fb
|
@ -24,6 +24,10 @@ struct _Frame_Extents
|
||||||
|
|
||||||
struct _E_Comp_Data
|
struct _E_Comp_Data
|
||||||
{
|
{
|
||||||
|
Ecore_X_Window lock_win;
|
||||||
|
Ecore_X_Window lock_grab_break_wnd;
|
||||||
|
Ecore_Event_Handler *lock_key_handler;
|
||||||
|
|
||||||
Eina_List *retry_clients;
|
Eina_List *retry_clients;
|
||||||
Ecore_Timer *retry_timer;
|
Ecore_Timer *retry_timer;
|
||||||
Eina_Bool restack : 1;
|
Eina_Bool restack : 1;
|
||||||
|
@ -4623,6 +4627,91 @@ _e_comp_x_grab_cb(E_Comp *c)
|
||||||
ecore_x_ungrab();
|
ecore_x_ungrab();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_e_comp_x_desklock_key_down(E_Comp *comp, int t EINA_UNUSED, Ecore_Event_Key *ev)
|
||||||
|
{
|
||||||
|
return (ev->window == comp->comp_data->lock_win);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_e_comp_x_desklock_hide(void)
|
||||||
|
{
|
||||||
|
E_Comp *comp;
|
||||||
|
const Eina_List *l;
|
||||||
|
|
||||||
|
EINA_LIST_FOREACH(e_comp_list(), l, comp)
|
||||||
|
{
|
||||||
|
if (comp->comp_data->lock_win)
|
||||||
|
{
|
||||||
|
e_grabinput_release(comp->comp_data->lock_win, comp->comp_data->lock_win);
|
||||||
|
ecore_x_window_free(comp->comp_data->lock_win);
|
||||||
|
comp->comp_data->lock_win = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (comp->comp_data->lock_grab_break_wnd)
|
||||||
|
ecore_x_window_show(comp->comp_data->lock_grab_break_wnd);
|
||||||
|
comp->comp_data->lock_grab_break_wnd = 0;
|
||||||
|
E_FREE_FUNC(comp->comp_data->lock_key_handler, ecore_event_handler_del);
|
||||||
|
e_comp_override_del(comp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_e_comp_x_desklock_show(void)
|
||||||
|
{
|
||||||
|
E_Comp *comp;
|
||||||
|
const Eina_List *l;
|
||||||
|
|
||||||
|
EINA_LIST_FOREACH(e_comp_list(), l, comp)
|
||||||
|
{
|
||||||
|
Ecore_X_Window win;
|
||||||
|
|
||||||
|
win = comp->comp_data->lock_win =
|
||||||
|
ecore_x_window_input_new(comp->man->root, 0, 0, 1, 1);
|
||||||
|
ecore_x_window_show(win);
|
||||||
|
if (!e_grabinput_get(win, 0, win))
|
||||||
|
{
|
||||||
|
Ecore_X_Window *windows;
|
||||||
|
int wnum, i;
|
||||||
|
|
||||||
|
windows = ecore_x_window_children_get(comp->man->root, &wnum);
|
||||||
|
if (!windows) goto fail;
|
||||||
|
for (i = 0; i < wnum; i++)
|
||||||
|
{
|
||||||
|
Ecore_X_Window_Attributes att;
|
||||||
|
|
||||||
|
memset(&att, 0, sizeof(Ecore_X_Window_Attributes));
|
||||||
|
ecore_x_window_attributes_get(windows[i], &att);
|
||||||
|
if (att.visible)
|
||||||
|
{
|
||||||
|
ecore_x_window_hide(windows[i]);
|
||||||
|
if (e_grabinput_get(win, 0, win))
|
||||||
|
{
|
||||||
|
comp->comp_data->lock_grab_break_wnd = windows[i];
|
||||||
|
free(windows);
|
||||||
|
goto works;
|
||||||
|
}
|
||||||
|
ecore_x_window_show(windows[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(windows);
|
||||||
|
}
|
||||||
|
works:
|
||||||
|
e_comp_override_add(comp);
|
||||||
|
e_comp_ignore_win_add(E_PIXMAP_TYPE_X, comp->comp_data->lock_win);
|
||||||
|
comp->comp_data->lock_key_handler =
|
||||||
|
ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, (Ecore_Event_Handler_Cb)_e_comp_x_desklock_key_down, comp);
|
||||||
|
}
|
||||||
|
return EINA_TRUE;
|
||||||
|
fail:
|
||||||
|
/* everything failed - can't lock */
|
||||||
|
e_util_dialog_show(_("Lock Failed"),
|
||||||
|
_("Locking the desktop failed because some application<br>"
|
||||||
|
"has grabbed either the keyboard or the mouse or both<br>"
|
||||||
|
"and their grab is unable to be broken."));
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static Eina_Bool
|
static Eina_Bool
|
||||||
_e_comp_x_setup(E_Comp *c, Ecore_X_Window root, int w, int h)
|
_e_comp_x_setup(E_Comp *c, Ecore_X_Window root, int w, int h)
|
||||||
{
|
{
|
||||||
|
@ -4933,7 +5022,8 @@ e_comp_x_init(void)
|
||||||
e_client_hook_add(E_CLIENT_HOOK_FOCUS_UNSET, _e_comp_x_hook_client_focus_unset, NULL);
|
e_client_hook_add(E_CLIENT_HOOK_FOCUS_UNSET, _e_comp_x_hook_client_focus_unset, NULL);
|
||||||
e_client_hook_add(E_CLIENT_HOOK_EVAL_END, _e_comp_x_hook_client_eval_end, NULL);
|
e_client_hook_add(E_CLIENT_HOOK_EVAL_END, _e_comp_x_hook_client_eval_end, NULL);
|
||||||
|
|
||||||
|
e_desklock_show_hook_add(_e_comp_x_desklock_show);
|
||||||
|
e_desklock_hide_hook_add(_e_comp_x_desklock_hide);
|
||||||
if (!e_randr_init()) return 0;
|
if (!e_randr_init()) return 0;
|
||||||
if (!e_atoms_init()) return 0;
|
if (!e_atoms_init()) return 0;
|
||||||
if (!_e_comp_x_screens_setup()) return EINA_FALSE;
|
if (!_e_comp_x_screens_setup()) return EINA_FALSE;
|
||||||
|
|
|
@ -30,10 +30,8 @@ struct _E_Desklock_Popup_Data
|
||||||
struct _E_Desklock_Data
|
struct _E_Desklock_Data
|
||||||
{
|
{
|
||||||
Eina_List *elock_wnd_list;
|
Eina_List *elock_wnd_list;
|
||||||
Ecore_X_Window elock_wnd;
|
|
||||||
Eina_List *handlers;
|
Eina_List *handlers;
|
||||||
Ecore_Event_Handler *move_handler;
|
Ecore_Event_Handler *move_handler;
|
||||||
Ecore_X_Window elock_grab_break_wnd;
|
|
||||||
char passwd[PASSWD_LEN];
|
char passwd[PASSWD_LEN];
|
||||||
int state;
|
int state;
|
||||||
Eina_Bool selected : 1;
|
Eina_Bool selected : 1;
|
||||||
|
@ -77,6 +75,9 @@ static Ecore_Event_Handler *_e_desklock_run_handler = NULL;
|
||||||
static Ecore_Job *job = NULL;
|
static Ecore_Job *job = NULL;
|
||||||
static Eina_List *tasks = NULL;
|
static Eina_List *tasks = NULL;
|
||||||
|
|
||||||
|
static Eina_List *show_cbs = NULL;
|
||||||
|
static Eina_List *hide_cbs = NULL;
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
|
||||||
static Eina_Bool _e_desklock_cb_key_down(void *data, int type, void *event);
|
static Eina_Bool _e_desklock_cb_key_down(void *data, int type, void *event);
|
||||||
|
@ -197,6 +198,34 @@ _user_wallpaper_get(E_Zone *zone)
|
||||||
return e_theme_edje_file_get("base/theme/desklock", "e/desklock/background");
|
return e_theme_edje_file_get("base/theme/desklock", "e/desklock/background");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EAPI void
|
||||||
|
e_desklock_show_hook_add(E_Desklock_Show_Cb cb)
|
||||||
|
{
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN(cb);
|
||||||
|
show_cbs = eina_list_append(show_cbs, cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI void
|
||||||
|
e_desklock_show_hook_del(E_Desklock_Show_Cb cb)
|
||||||
|
{
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN(cb);
|
||||||
|
show_cbs = eina_list_remove(show_cbs, cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI void
|
||||||
|
e_desklock_hide_hook_add(E_Desklock_Hide_Cb cb)
|
||||||
|
{
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN(cb);
|
||||||
|
hide_cbs = eina_list_append(hide_cbs, cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI void
|
||||||
|
e_desklock_hide_hook_del(E_Desklock_Hide_Cb cb)
|
||||||
|
{
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN(cb);
|
||||||
|
hide_cbs = eina_list_remove(hide_cbs, cb);
|
||||||
|
}
|
||||||
|
|
||||||
EAPI int
|
EAPI int
|
||||||
e_desklock_show_autolocked(void)
|
e_desklock_show_autolocked(void)
|
||||||
{
|
{
|
||||||
|
@ -208,12 +237,14 @@ e_desklock_show_autolocked(void)
|
||||||
EAPI int
|
EAPI int
|
||||||
e_desklock_show(Eina_Bool suspend)
|
e_desklock_show(Eina_Bool suspend)
|
||||||
{
|
{
|
||||||
Eina_List *managers, *l, *l3;
|
Eina_List *l, *l3;
|
||||||
E_Manager *man;
|
E_Manager *man;
|
||||||
int total_zone_num;
|
int total_zone_num;
|
||||||
E_Event_Desklock *ev;
|
E_Event_Desklock *ev;
|
||||||
|
E_Desklock_Show_Cb show_cb;
|
||||||
|
E_Desklock_Hide_Cb hide_cb;
|
||||||
|
|
||||||
if (_e_custom_desklock_exe) return 0;
|
if (_e_desklock_state) return EINA_TRUE;
|
||||||
|
|
||||||
if (e_config->desklock_use_custom_desklock && e_config->desklock_custom_desklock_cmd && e_config->desklock_custom_desklock_cmd[0])
|
if (e_config->desklock_use_custom_desklock && e_config->desklock_custom_desklock_cmd && e_config->desklock_custom_desklock_cmd[0])
|
||||||
{
|
{
|
||||||
|
@ -260,58 +291,14 @@ e_desklock_show(Eina_Bool suspend)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
e_menu_hide_all();
|
||||||
|
EINA_LIST_FOREACH(show_cbs, l, show_cb)
|
||||||
|
{
|
||||||
|
if (!show_cb()) goto fail;
|
||||||
|
}
|
||||||
edd = E_NEW(E_Desklock_Data, 1);
|
edd = E_NEW(E_Desklock_Data, 1);
|
||||||
if (!edd) return 0;
|
if (!edd) return 0;
|
||||||
edd->elock_wnd = ecore_x_window_input_new(e_manager_current_get()->root, 0, 0, 1, 1);
|
|
||||||
ecore_x_window_show(edd->elock_wnd);
|
|
||||||
managers = e_manager_list();
|
|
||||||
e_menu_hide_all();
|
|
||||||
if (!e_grabinput_get(edd->elock_wnd, 0, edd->elock_wnd))
|
|
||||||
{
|
|
||||||
EINA_LIST_FOREACH(managers, l, man)
|
|
||||||
{
|
|
||||||
Ecore_X_Window *windows;
|
|
||||||
int wnum;
|
|
||||||
|
|
||||||
windows = ecore_x_window_children_get(man->root, &wnum);
|
|
||||||
if (windows)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < wnum; i++)
|
|
||||||
{
|
|
||||||
Ecore_X_Window_Attributes att;
|
|
||||||
|
|
||||||
memset(&att, 0, sizeof(Ecore_X_Window_Attributes));
|
|
||||||
ecore_x_window_attributes_get(windows[i], &att);
|
|
||||||
if (att.visible)
|
|
||||||
{
|
|
||||||
ecore_x_window_hide(windows[i]);
|
|
||||||
if (e_grabinput_get(edd->elock_wnd, 0, edd->elock_wnd))
|
|
||||||
{
|
|
||||||
edd->elock_grab_break_wnd = windows[i];
|
|
||||||
free(windows);
|
|
||||||
goto works;
|
|
||||||
}
|
|
||||||
ecore_x_window_show(windows[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free(windows);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* everything failed - can't lock */
|
|
||||||
e_util_dialog_show(_("Lock Failed"),
|
|
||||||
_("Locking the desktop failed because some application<br>"
|
|
||||||
"has grabbed either the keyboard or the mouse or both<br>"
|
|
||||||
"and their grab is unable to be broken."));
|
|
||||||
ecore_x_window_free(edd->elock_wnd);
|
|
||||||
E_FREE(edd);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
works:
|
|
||||||
//e_comp_block_window_add();
|
//e_comp_block_window_add();
|
||||||
E_LIST_FOREACH(e_comp_list(), e_comp_override_add);
|
|
||||||
e_comp_ignore_win_add(E_PIXMAP_TYPE_X, edd->elock_wnd);
|
|
||||||
if (e_config->desklock_language)
|
if (e_config->desklock_language)
|
||||||
e_intl_language_set(e_config->desklock_language);
|
e_intl_language_set(e_config->desklock_language);
|
||||||
|
|
||||||
|
@ -319,7 +306,7 @@ works:
|
||||||
e_xkb_layout_set(e_config->xkb.lock_layout);
|
e_xkb_layout_set(e_config->xkb.lock_layout);
|
||||||
|
|
||||||
total_zone_num = _e_desklock_zone_num_get();
|
total_zone_num = _e_desklock_zone_num_get();
|
||||||
EINA_LIST_FOREACH(managers, l, man)
|
EINA_LIST_FOREACH(e_manager_list(), l, man)
|
||||||
{
|
{
|
||||||
E_Zone *zone;
|
E_Zone *zone;
|
||||||
EINA_LIST_FOREACH(man->comp->zones, l3, zone)
|
EINA_LIST_FOREACH(man->comp->zones, l3, zone)
|
||||||
|
@ -346,12 +333,19 @@ works:
|
||||||
e_util_env_set("E_DESKLOCK_LOCKED", "locked");
|
e_util_env_set("E_DESKLOCK_LOCKED", "locked");
|
||||||
_e_desklock_state = EINA_TRUE;
|
_e_desklock_state = EINA_TRUE;
|
||||||
return 1;
|
return 1;
|
||||||
|
fail:
|
||||||
|
EINA_LIST_FOREACH(hide_cbs, l, hide_cb)
|
||||||
|
hide_cb();
|
||||||
|
E_FREE(edd);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
EAPI void
|
EAPI void
|
||||||
e_desklock_hide(void)
|
e_desklock_hide(void)
|
||||||
{
|
{
|
||||||
|
Eina_List *l;
|
||||||
E_Event_Desklock *ev;
|
E_Event_Desklock *ev;
|
||||||
|
E_Desklock_Hide_Cb hide_cb;
|
||||||
|
|
||||||
if ((!edd) && (!_e_custom_desklock_exe)) return;
|
if ((!edd) && (!_e_custom_desklock_exe)) return;
|
||||||
|
|
||||||
|
@ -380,16 +374,14 @@ e_desklock_hide(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!edd) return;
|
if (!edd) return;
|
||||||
if (edd->elock_grab_break_wnd)
|
|
||||||
ecore_x_window_show(edd->elock_grab_break_wnd);
|
EINA_LIST_FOREACH(hide_cbs, l, hide_cb)
|
||||||
|
hide_cb();
|
||||||
|
|
||||||
E_FREE_LIST(edd->elock_wnd_list, _e_desklock_popup_free);
|
E_FREE_LIST(edd->elock_wnd_list, _e_desklock_popup_free);
|
||||||
E_FREE_LIST(edd->handlers, ecore_event_handler_del);
|
E_FREE_LIST(edd->handlers, ecore_event_handler_del);
|
||||||
if (edd->move_handler) ecore_event_handler_del(edd->move_handler);
|
if (edd->move_handler) ecore_event_handler_del(edd->move_handler);
|
||||||
|
|
||||||
e_grabinput_release(edd->elock_wnd, edd->elock_wnd);
|
|
||||||
ecore_x_window_free(edd->elock_wnd);
|
|
||||||
|
|
||||||
E_FREE(edd);
|
E_FREE(edd);
|
||||||
|
|
||||||
if (_e_desklock_autolock_time > 0.0)
|
if (_e_desklock_autolock_time > 0.0)
|
||||||
|
@ -615,8 +607,7 @@ _e_desklock_cb_key_down(void *data __UNUSED__, int type __UNUSED__, void *event)
|
||||||
{
|
{
|
||||||
Ecore_Event_Key *ev = event;
|
Ecore_Event_Key *ev = event;
|
||||||
|
|
||||||
if ((ev->window != edd->elock_wnd) ||
|
if (edd->state == E_DESKLOCK_STATE_CHECKING) return ECORE_CALLBACK_DONE;
|
||||||
(edd->state == E_DESKLOCK_STATE_CHECKING)) return 1;
|
|
||||||
|
|
||||||
if (!strcmp(ev->key, "Escape"))
|
if (!strcmp(ev->key, "Escape"))
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#ifdef E_TYPEDEFS
|
#ifdef E_TYPEDEFS
|
||||||
|
|
||||||
typedef struct _E_Event_Desklock E_Event_Desklock;
|
typedef struct _E_Event_Desklock E_Event_Desklock;
|
||||||
|
typedef Eina_Bool (*E_Desklock_Show_Cb)(void);
|
||||||
|
typedef void (*E_Desklock_Hide_Cb)(void);
|
||||||
|
|
||||||
typedef enum _E_Desklock_Background_Method {
|
typedef enum _E_Desklock_Background_Method {
|
||||||
E_DESKLOCK_BACKGROUND_METHOD_THEME_DESKLOCK = 0,
|
E_DESKLOCK_BACKGROUND_METHOD_THEME_DESKLOCK = 0,
|
||||||
|
@ -26,6 +28,11 @@ EAPI int e_desklock_show_autolocked(void);
|
||||||
EAPI void e_desklock_hide(void);
|
EAPI void e_desklock_hide(void);
|
||||||
EAPI Eina_Bool e_desklock_state_get(void);
|
EAPI Eina_Bool e_desklock_state_get(void);
|
||||||
|
|
||||||
|
EAPI void e_desklock_show_hook_add(E_Desklock_Show_Cb cb);
|
||||||
|
EAPI void e_desklock_show_hook_del(E_Desklock_Show_Cb cb);
|
||||||
|
EAPI void e_desklock_hide_hook_add(E_Desklock_Hide_Cb cb);
|
||||||
|
EAPI void e_desklock_hide_hook_del(E_Desklock_Hide_Cb cb);
|
||||||
|
|
||||||
extern EAPI int E_EVENT_DESKLOCK;
|
extern EAPI int E_EVENT_DESKLOCK;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue