From 91091f83e56f2663b50b57812a08b485ffc9c5e7 Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Mon, 20 Jun 2005 08:56:54 +0000 Subject: [PATCH] grabinput handling that allows winlist to pop up FROM the menu etc. hmm - maybe i should have a stack of these too in grabinput that sends the input back to the previous owner if its still there... and also actually send pings around to clients every 10 seconds or so - if they dont respond, we have a function that can do something - but right now it does nothing. shoudl mark the window as "hung" SVN revision: 15445 --- TODO | 4 ++- src/bin/Makefile.am | 4 ++- src/bin/e_border.c | 58 +++++++++++++++++++++++++++++++++--- src/bin/e_border.h | 37 +++++++++++++---------- src/bin/e_grabinput.c | 68 +++++++++++++++++++++++++++++++++++++++++++ src/bin/e_grabinput.h | 16 ++++++++++ src/bin/e_includes.h | 1 + src/bin/e_main.c | 7 +++++ src/bin/e_manager.c | 2 +- src/bin/e_menu.c | 12 ++++---- src/bin/e_winlist.c | 4 +-- 11 files changed, 183 insertions(+), 30 deletions(-) create mode 100644 src/bin/e_grabinput.c create mode 100644 src/bin/e_grabinput.h diff --git a/TODO b/TODO index 469994419..0765b15e6 100644 --- a/TODO +++ b/TODO @@ -55,6 +55,8 @@ Also look at all the .c files - they have their own localized TODO lists These are in no particular order: +* ctrl+alt+backspace will leave e in 100% cpu infinite look printing out errors +* "run command" typebuffer thing * pager problems. Seems to loose or mess up windows sometimes. * add fullscreen support (e16 xvidmode or xrandr style) * implement thses maximise/fullscreen modes: @@ -88,7 +90,7 @@ These are in no particular order: fullscreen. is this correct? * netwm window types and states need addressing (do special/appropriate things) for each of them. -* use ecore_x_netwm_ping_send() to windowsthat suport it regularly to see if +* use ecore_x_netwm_ping_send() to windows that suport it regularly to see if they are dead or not (do this all the time - like every few seconds) to be able to inform users of dead applications about the time they die, not some time afterwards. (also ask if u want to kill the process then) diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am index 20a32d7dc..ab4f9c4f5 100644 --- a/src/bin/Makefile.am +++ b/src/bin/Makefile.am @@ -61,7 +61,8 @@ e_datastore.h \ e_msg.h \ e_winlist.h \ e_alert.h \ -e_maximize.h +e_maximize.h \ +e_grabinput.h enlightenment_SOURCES = \ e_main.c \ @@ -113,6 +114,7 @@ e_msg.c \ e_winlist.c \ e_alert.c \ e_maximize.c \ +e_grabinput.c \ $(ENLIGHTENMENTHEADERS) enlightenment_LDFLAGS = -export-dynamic @e_libs@ @x_libs@ @dlopen_libs@ diff --git a/src/bin/e_border.c b/src/bin/e_border.c index 2f9b59ede..b31fae309 100644 --- a/src/bin/e_border.c +++ b/src/bin/e_border.c @@ -116,6 +116,7 @@ static int _e_border_move_end(E_Border *bd); static void _e_border_move_update(E_Border *bd); static int _e_border_cb_focus_fix(void *data); +static int _e_border_cb_ping_timer(void *data); static char *_e_border_winid_str_get(Ecore_X_Window win); @@ -1537,6 +1538,16 @@ e_border_clients_get() return borders; } +void +e_border_ping(E_Border *bd) +{ + bd->ping_ok = 0; + ecore_x_netwm_ping_send(bd->client.win); + bd->ping = ecore_time_get(); + if (bd->ping_timer) ecore_timer_del(bd->ping_timer); + bd->ping_timer = ecore_timer_add(10.0, _e_border_cb_ping_timer, bd); +} + void e_border_act_move_begin(E_Border *bd, Ecore_X_Event_Mouse_Button_Down *ev) { @@ -1645,12 +1656,10 @@ e_border_act_close_begin(E_Border *bd) { if (bd->client.icccm.delete_request) { + bd->delete_requested = 1; ecore_x_window_delete_request_send(bd->client.win); if (bd->client.netwm.ping) - { - ecore_x_netwm_ping_send(bd->client.win); - bd->ping = ecore_time_get(); - } + e_border_ping(bd); } else e_border_act_kill_begin(bd); @@ -1806,6 +1815,11 @@ _e_border_free(E_Border *bd) ecore_timer_del(bd->dangling_ref_check); bd->dangling_ref_check = NULL; } + if (bd->ping_timer) + { + ecore_timer_del(bd->ping_timer); + bd->ping_timer = NULL; + } if (bd->raise_timer) { ecore_timer_del(bd->raise_timer); @@ -3602,6 +3616,13 @@ _e_border_eval(E_Border *bd) } free(proto); } + if (bd->client.netwm.ping) + e_border_ping(bd); + else + { + if (bd->ping_timer) ecore_timer_del(bd->ping_timer); + bd->ping_timer = NULL; + } bd->client.icccm.fetch.protocol = 0; } if (bd->client.mwm.fetch.hints) @@ -5235,6 +5256,34 @@ _e_border_cb_focus_fix(void *data) return 1; } +static int +_e_border_cb_ping_timer(void *data) +{ + E_Border *bd; + + bd = data; + if (bd->ping_ok) + { + /* FIXME: if hung, reset hung state to normal */ + e_border_ping(bd); + } + else + { + /* FIXME: if !hung, set hung state then... */ + if (bd->delete_requested) + { + printf("DELETE REQ HUNG: BORDER %p [%s] not responding to ping!!!!\n", + bd, bd->client.icccm.title); + } + else + { + printf("HUNG APP: BORDER %p [%s] not responding to ping!!!!\n", + bd, bd->client.icccm.title); + } + } + return 1; +} + static char * _e_border_winid_str_get(Ecore_X_Window win) { @@ -5254,3 +5303,4 @@ _e_border_winid_str_get(Ecore_X_Window win) id[8] = 0; return id; } + diff --git a/src/bin/e_border.h b/src/bin/e_border.h index baaaa1c7b..4fe3749c4 100644 --- a/src/bin/e_border.h +++ b/src/bin/e_border.h @@ -256,23 +256,25 @@ struct _E_Border E_Container_Shape *shape; - unsigned char visible : 1; - unsigned char moving : 1; - unsigned char focused : 1; - unsigned char new_client : 1; - unsigned char re_manage : 1; - unsigned char shading : 1; - unsigned char shaded : 1; + unsigned int visible : 1; + unsigned int moving : 1; + unsigned int focused : 1; + unsigned int new_client : 1; + unsigned int re_manage : 1; + unsigned int shading : 1; + unsigned int shaded : 1; + unsigned int iconic : 1; + unsigned int sticky : 1; + unsigned int shaped : 1; + unsigned int need_shape_merge : 1; + unsigned int need_shape_export : 1; + unsigned int fullscreen : 1; + unsigned int already_unparented : 1; + unsigned int need_reparent : 1; + unsigned int button_grabbed : 1; + unsigned int delete_requested : 1; + unsigned int ping_ok : 1; E_Maximize maximized; - unsigned char iconic : 1; - unsigned char sticky : 1; - unsigned char shaped : 1; - unsigned char need_shape_merge : 1; - unsigned char need_shape_export : 1; - unsigned char fullscreen : 1; - unsigned char already_unparented : 1; - unsigned char need_reparent : 1; - unsigned char button_grabbed : 1; double ping; @@ -319,6 +321,7 @@ struct _E_Border unsigned int layer; E_Action *cur_mouse_action; Ecore_Timer *raise_timer; + Ecore_Timer *ping_timer; Ecore_Timer *dangling_ref_check; }; @@ -464,6 +467,8 @@ EAPI void e_border_button_bindings_grab_all(void); EAPI Evas_List *e_border_focus_stack_get(void); EAPI Evas_List *e_border_lost_windows_get(E_Zone *zone); +EAPI void e_border_ping(E_Border *bd); + extern EAPI int E_EVENT_BORDER_RESIZE; extern EAPI int E_EVENT_BORDER_MOVE; extern EAPI int E_EVENT_BORDER_ADD; diff --git a/src/bin/e_grabinput.c b/src/bin/e_grabinput.c new file mode 100644 index 000000000..7969d909d --- /dev/null +++ b/src/bin/e_grabinput.c @@ -0,0 +1,68 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ +#include "e.h" + +/* local subsystem functions */ + +/* local subsystem globals */ +Ecore_X_Window grab_mouse_win = 0; +Ecore_X_Window grab_key_win = 0; + +/* externally accessible functions */ +int +e_grabinput_init(void) +{ + return 1; +} + +int +e_grabinput_shutdown(void) +{ + return 1; +} + +void +e_grabinput_get(Ecore_X_Window mouse_win, int confine_mouse, Ecore_X_Window key_win) +{ + if (grab_mouse_win) + { + ecore_x_pointer_ungrab(); + grab_mouse_win = 0; + } + if (grab_key_win) + { + ecore_x_keyboard_ungrab(); + grab_key_win = 0; + } + if (mouse_win) + { + if (confine_mouse) + ecore_x_pointer_confine_grab(mouse_win); + else + ecore_x_pointer_grab(mouse_win); + grab_mouse_win = mouse_win; + } + if (key_win) + { + ecore_x_keyboard_grab(key_win); + grab_key_win = key_win; + } +} + +void +e_grabinput_release(Ecore_X_Window mouse_win, Ecore_X_Window key_win) +{ + if (mouse_win == grab_mouse_win) + { + ecore_x_pointer_ungrab(); + mouse_win = 0; + } + if (key_win == grab_key_win) + { + ecore_x_keyboard_ungrab(); + grab_key_win = 0; + } +} + +/* local subsystem functions */ diff --git a/src/bin/e_grabinput.h b/src/bin/e_grabinput.h new file mode 100644 index 000000000..57defac21 --- /dev/null +++ b/src/bin/e_grabinput.h @@ -0,0 +1,16 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ +#ifdef E_TYPEDEFS + +#else +#ifndef E_GRABINPUT_H +#define E_GRABINPUT_H + +EAPI int e_grabinput_init(void); +EAPI int e_grabinput_shutdown(void); +EAPI void e_grabinput_get(Ecore_X_Window mouse_win, int confine_mouse, Ecore_X_Window key_win); +EAPI void e_grabinput_release(Ecore_X_Window mouse_win, Ecore_X_Window key_win); + +#endif +#endif diff --git a/src/bin/e_includes.h b/src/bin/e_includes.h index 7a5ef67d1..b274a7c87 100644 --- a/src/bin/e_includes.h +++ b/src/bin/e_includes.h @@ -49,3 +49,4 @@ #include "e_winlist.h" #include "e_alert.h" #include "e_maximize.h" +#include "e_grabinput.h" diff --git a/src/bin/e_main.c b/src/bin/e_main.c index 5be0e7514..bba1b33b5 100644 --- a/src/bin/e_main.c +++ b/src/bin/e_main.c @@ -429,6 +429,13 @@ main(int argc, char **argv) _e_main_shutdown(-1); } _e_main_shutdown_push(e_dnd_shutdown); + /* setup input grabbing co-operation system */ + if (!e_grabinput_init()) + { + e_error_message_show(_("Enlightenment cannot set up its inptu grab handling system.")); + _e_main_shutdown(-1); + } + _e_main_shutdown_push(e_grabinput_shutdown); /* setup module loading etc */ if (!e_module_init()) { diff --git a/src/bin/e_manager.c b/src/bin/e_manager.c index e09ec5544..a877878b3 100644 --- a/src/bin/e_manager.c +++ b/src/bin/e_manager.c @@ -527,7 +527,7 @@ _e_manager_cb_ping(void *data, int ev_type __UNUSED__, void *ev) bd = e_border_find_by_client_window(e->event_win); if (!bd) return 1; - printf("PING response: %f\n", ecore_time_get() - bd->ping); + bd->ping_ok = 1; return 1; } diff --git a/src/bin/e_menu.c b/src/bin/e_menu.c index f50d95259..97a69c4f2 100644 --- a/src/bin/e_menu.c +++ b/src/bin/e_menu.c @@ -792,8 +792,12 @@ e_menu_idler_before(void) } if (!_e_active_menus) { - ecore_x_window_del(_e_menu_win); - _e_menu_win = 0; + if (_e_menu_win) + { + ecore_x_window_del(_e_menu_win); + e_grabinput_release(_e_menu_win, _e_menu_win); + _e_menu_win = 0; + } } } @@ -1465,9 +1469,7 @@ _e_menu_activate_internal(E_Menu *m, E_Zone *zone) zone->x, zone->y, zone->w, zone->h); ecore_x_window_show(_e_menu_win); - /* need menu event win (input win) and grab to that */ - ecore_x_pointer_confine_grab(_e_menu_win); - ecore_x_keyboard_grab(_e_menu_win); + e_grabinput_get(_e_menu_win, 1, _e_menu_win); } if ((m->zone) && (m->zone->container != zone->container)) { diff --git a/src/bin/e_winlist.c b/src/bin/e_winlist.c index 8aa41b55a..906668013 100644 --- a/src/bin/e_winlist.c +++ b/src/bin/e_winlist.c @@ -140,8 +140,7 @@ e_winlist_show(E_Zone *zone) input_window = ecore_x_window_input_new(zone->container->win, 0, 0, 1, 1); ecore_x_window_show(input_window); - ecore_x_pointer_grab(input_window); - ecore_x_keyboard_grab(input_window); + e_grabinput_get(input_window, 0, input_window); handlers = evas_list_append (handlers, ecore_event_handler_add (E_EVENT_BORDER_ADD, _e_winlist_cb_event_border_add, NULL)); @@ -214,6 +213,7 @@ e_winlist_hide(void) handlers = evas_list_remove_list(handlers, handlers); } ecore_x_window_del(input_window); + e_grabinput_release(input_window, input_window); input_window = 0; if (warp_timer) {