#include "e.h" /* local subsystem functions */ static Eina_Bool _e_grabinput_focus_check(void *data); static void _e_grabinput_focus_do(Ecore_Window win, E_Focus_Method method); static void _e_grabinput_focus(Ecore_Window win, E_Focus_Method method); /* local subsystem globals */ static Ecore_Window grab_mouse_win = 0; static Ecore_Window grab_key_win = 0; static Ecore_Window focus_win = 0; static E_Focus_Method focus_method = E_FOCUS_METHOD_NO_INPUT; static double last_focus_time = 0.0; static Ecore_Window focus_fix_win = 0; static Ecore_Timer *focus_fix_timer = NULL; static E_Focus_Method focus_fix_method = E_FOCUS_METHOD_NO_INPUT; /* externally accessible functions */ EINTERN int e_grabinput_init(void) { return 1; } EINTERN int e_grabinput_shutdown(void) { if (focus_fix_timer) { ecore_timer_del(focus_fix_timer); focus_fix_timer = NULL; } return 1; } EAPI int e_grabinput_get(Ecore_Window mouse_win, int confine_mouse, Ecore_Window key_win) { if (e_comp_get(NULL)->comp_type != E_PIXMAP_TYPE_X) return 1; if (grab_mouse_win) { #ifndef HAVE_WAYLAND_ONLY ecore_x_pointer_ungrab(); #endif grab_mouse_win = 0; } if (grab_key_win) { #ifndef HAVE_WAYLAND_ONLY ecore_x_keyboard_ungrab(); #endif grab_key_win = 0; focus_win = 0; } if (mouse_win) { int ret = 0; #ifndef HAVE_WAYLAND_ONLY if (confine_mouse) ret = ecore_x_pointer_confine_grab(mouse_win); else ret = ecore_x_pointer_grab(mouse_win); #endif if (!ret) return 0; grab_mouse_win = mouse_win; } if (key_win) { #ifndef HAVE_WAYLAND_ONLY int ret = 0; ret = ecore_x_keyboard_grab(key_win); if (!ret) { if (grab_mouse_win) { ecore_x_pointer_ungrab(); grab_mouse_win = 0; } return 0; } #endif grab_key_win = key_win; } #ifdef HAVE_WAYLAND_ONLY (void)confine_mouse; #endif return 1; } EAPI void e_grabinput_release(Ecore_Window mouse_win, Ecore_Window key_win) { if (e_comp_get(NULL)->comp_type != E_PIXMAP_TYPE_X) return; if (mouse_win == grab_mouse_win) { #ifndef HAVE_WAYLAND_ONLY ecore_x_pointer_ungrab(); #endif grab_mouse_win = 0; } if (key_win == grab_key_win) { #ifndef HAVE_WAYLAND_ONLY ecore_x_keyboard_ungrab(); #endif grab_key_win = 0; if (focus_win != 0) { /* fprintf(stderr, "release focus to %x\n", focus_win); */ _e_grabinput_focus(focus_win, focus_method); focus_win = 0; focus_method = E_FOCUS_METHOD_NO_INPUT; } } } EAPI void e_grabinput_focus(Ecore_Window win, E_Focus_Method method) { if (e_comp_get(NULL)->comp_type != E_PIXMAP_TYPE_X) return; if (grab_key_win != 0) { /* fprintf(stderr, "while grabbed focus changed to %x\n", win); */ focus_win = win; focus_method = method; } else { /* fprintf(stderr, "focus to %x\n", win); */ _e_grabinput_focus(win, method); } } EAPI double e_grabinput_last_focus_time_get(void) { return last_focus_time; } EAPI Ecore_Window e_grabinput_last_focus_win_get(void) { return focus_fix_win; } EAPI Ecore_Window e_grabinput_key_win_get(void) { return grab_key_win; } static Eina_Bool _e_grabinput_focus_check(void *data __UNUSED__) { #ifndef HAVE_WAYLAND_ONLY if (ecore_x_window_focus_get() != focus_fix_win) { /* fprintf(stderr, "foc do 2\n"); */ _e_grabinput_focus_do(focus_fix_win, focus_fix_method); } #endif focus_fix_timer = NULL; return EINA_FALSE; } static void _e_grabinput_focus_do(Ecore_Window win, E_Focus_Method method) { /* fprintf(stderr, "focus to %x method %i\n", win, method); */ switch (method) { case E_FOCUS_METHOD_NO_INPUT: break; case E_FOCUS_METHOD_LOCALLY_ACTIVE: #ifndef HAVE_WAYLAND_ONLY ecore_x_window_focus_at_time(win, ecore_x_current_time_get()); ecore_x_icccm_take_focus_send(win, ecore_x_current_time_get()); #endif break; case E_FOCUS_METHOD_GLOBALLY_ACTIVE: #ifndef HAVE_WAYLAND_ONLY ecore_x_icccm_take_focus_send(win, ecore_x_current_time_get()); #endif break; case E_FOCUS_METHOD_PASSIVE: #ifndef HAVE_WAYLAND_ONLY ecore_x_window_focus_at_time(win, ecore_x_current_time_get()); #endif break; default: break; } #ifdef HAVE_WAYLAND_ONLY (void)win; #endif } static void _e_grabinput_focus(Ecore_Window win, E_Focus_Method method) { focus_fix_win = win; focus_fix_method = method; /* fprintf(stderr, "foc do 1\n"); */ _e_grabinput_focus_do(win, method); last_focus_time = ecore_loop_time_get(); if (focus_fix_timer) ecore_timer_del(focus_fix_timer); focus_fix_timer = ecore_timer_add(0.2, _e_grabinput_focus_check, NULL); }