diff --git a/src/bin/e_actions.c b/src/bin/e_actions.c index c817c78cc..a74564e6c 100644 --- a/src/bin/e_actions.c +++ b/src/bin/e_actions.c @@ -123,6 +123,19 @@ ACT_FN_END_MOUSE(window_move) e_border_act_move_end((E_Border *)obj, ev); } +ACT_FN_GO(window_move_keyboard) +{ + if (!obj) obj = E_OBJECT(e_border_focused_get()); + if (!obj) return; + if (obj->type != E_BORDER_TYPE) + { + obj = E_OBJECT(e_border_focused_get()); + if (!obj) return; + } + if (!((E_Border *)obj)->lock_user_location) + e_border_act_move_keyboard((E_Border *)obj); +} + /***************************************************************************/ ACT_FN_GO(window_resize) { @@ -174,6 +187,19 @@ ACT_FN_END_MOUSE(window_resize) e_border_act_resize_end((E_Border *)obj, ev); } +ACT_FN_GO(window_resize_keyboard) +{ + if (!obj) obj = E_OBJECT(e_border_focused_get()); + if (!obj) return; + if (obj->type != E_BORDER_TYPE) + { + obj = E_OBJECT(e_border_focused_get()); + if (!obj) return; + } + if (!((E_Border *)obj)->lock_user_size) + e_border_act_resize_keyboard((E_Border *)obj); +} + /***************************************************************************/ ACT_FN_GO(window_menu) { @@ -2254,6 +2280,11 @@ e_actions_init(void) ACT_GO_SIGNAL(window_move); ACT_END(window_move); ACT_END_MOUSE(window_move); + + ACT_GO(window_move_keyboard); + e_action_predef_name_set(_("Window : Actions"), _("Move with Keyboard"), + "window_move_keyboard", NULL, NULL, 0); + /* window_resize */ ACT_GO(window_resize); @@ -2265,6 +2296,10 @@ e_actions_init(void) ACT_END(window_resize); ACT_END_MOUSE(window_resize); + ACT_GO(window_resize_keyboard); + e_action_predef_name_set(_("Window : Actions"), _("Resize with Keyboard"), + "window_resize_keyboard", NULL, NULL, 0); + /* window_menu */ ACT_GO(window_menu); e_action_predef_name_set(_("Menu"), _("Window Menu"), diff --git a/src/bin/e_border.c b/src/bin/e_border.c index a1f129583..50c199758 100644 --- a/src/bin/e_border.c +++ b/src/bin/e_border.c @@ -2608,6 +2608,285 @@ e_border_client_list() return borders; } +static Ecore_X_Window action_input_win = 0; +static E_Border *action_border = NULL; +static Ecore_Event_Handler *action_handler_key = NULL; +static Ecore_Event_Handler *action_handler_mouse = NULL; +static Ecore_Timer *action_timer = NULL; +static Ecore_X_Rectangle action_orig; + +static int +_e_border_action_input_win_del(void) +{ + if (!action_input_win) + return 0; + + e_grabinput_release(action_input_win, action_input_win); + ecore_x_window_del(action_input_win); + action_input_win = 0; + return 1; +} + +static int +_e_border_action_input_win_new(E_Border *bd) +{ + if (!action_input_win) + { + Ecore_X_Window parent = bd->zone->container->win; + action_input_win = ecore_x_window_input_new(parent, 0, 0, 1, 1); + if (!action_input_win) + return 0; + } + + ecore_x_window_show(action_input_win); + if (e_grabinput_get(action_input_win, 0, action_input_win)) + return 1; + + _e_border_action_input_win_del(); + return 0; +} + +static int +_e_border_action_finish(void) +{ + _e_border_action_input_win_del(); + + if (action_timer) + { + ecore_timer_del(action_timer); + action_timer = NULL; + } + + if (action_handler_key) + { + ecore_event_handler_del(action_handler_key); + action_handler_key = NULL; + } + + if (action_handler_mouse) + { + ecore_event_handler_del(action_handler_mouse); + action_handler_mouse = NULL; + } + + action_border = NULL; +} + +static int +_e_border_action_timeout(void *data) +{ + _e_border_action_finish(); + return 0; +} + +static void +_e_border_action_timeout_add(void) +{ + if (action_timer) + ecore_timer_del(action_timer); + action_timer = ecore_timer_add(5.0, _e_border_action_timeout, NULL); +} + +static void +_e_border_action_init(E_Border *bd) +{ + action_orig.x = bd->x; + action_orig.y = bd->y; + action_orig.width = bd->w; + action_orig.height = bd->h; + + action_border = bd; + + _e_border_action_timeout_add(); +} + +static void +_e_border_action_restore_orig(E_Border *bd) +{ + if (action_border != bd) + return; + + e_border_move_resize(bd, action_orig.x, action_orig.y, action_orig.width, action_orig.height); +} + +#define E_BORDER_MOVE_KEY_DX 5 +#define E_BORDER_MOVE_KEY_DY 5 +static int +_e_border_move_key_down(void *data, int type, void *event) +{ + Ecore_X_Event_Key_Down *ev = event; + int x, y; + + if (ev->event_win != action_input_win) + return 1; + if (!action_border) + { + fputs("ERROR: no action_border!\n", stderr); + goto stop; + } + + x = action_border->x; + y = action_border->y; + + if (strcmp(ev->keysymbol, "Up") == 0) + y -= E_BORDER_MOVE_KEY_DY; + else if (strcmp(ev->keysymbol, "Down") == 0) + y += E_BORDER_MOVE_KEY_DY; + else if (strcmp(ev->keysymbol, "Left") == 0) + x -= E_BORDER_MOVE_KEY_DX; + else if (strcmp(ev->keysymbol, "Right") == 0) + x += E_BORDER_MOVE_KEY_DX; + else if (strcmp(ev->keysymbol, "Return") == 0) + goto stop; + else if (strcmp(ev->keysymbol, "Escape") == 0) + { + _e_border_action_restore_orig(action_border); + goto stop; + } + + e_border_move(action_border, x, y); + _e_border_action_timeout_add(); + + return 1; + + stop: + _e_border_move_end(action_border); + _e_border_action_finish(); + return 0; +} + +static int +_e_border_move_mouse_down(void *data, int type, void *event) +{ + Ecore_X_Event_Mouse_Button_Down *ev = event; + + if (ev->event_win != action_input_win) + return 1; + + if (!action_border) + fputs("ERROR: no action_border!\n", stderr); + + _e_border_move_end(action_border); + _e_border_action_finish(); + return 0; +} + +EAPI void +e_border_act_move_keyboard(E_Border *bd) +{ + if (!bd) + return; + + if (!_e_border_move_begin(bd)) + return; + + if (!_e_border_action_input_win_new(bd)) + { + _e_border_move_end(bd); + return; + } + + _e_border_action_init(bd); + + if (action_handler_key) + ecore_event_handler_del(action_handler_key); + action_handler_key = ecore_event_handler_add(ECORE_X_EVENT_KEY_DOWN, _e_border_move_key_down, NULL); + + if (action_handler_mouse) + ecore_event_handler_del(action_handler_mouse); + action_handler_mouse = ecore_event_handler_add(ECORE_X_EVENT_MOUSE_BUTTON_DOWN, _e_border_move_mouse_down, NULL); +} + +#define E_BORDER_RESIZE_KEY_DX 5 +#define E_BORDER_RESIZE_KEY_DY 5 +static int +_e_border_resize_key_down(void *data, int type, void *event) +{ + Ecore_X_Event_Key_Down *ev = event; + int w, h; + + if (ev->event_win != action_input_win) + return 1; + if (!action_border) + { + fputs("ERROR: no action_border!\n", stderr); + goto stop; + } + + w = action_border->w; + h = action_border->h; + + if (strcmp(ev->keysymbol, "Up") == 0) + h -= E_BORDER_RESIZE_KEY_DY; + else if (strcmp(ev->keysymbol, "Down") == 0) + h += E_BORDER_RESIZE_KEY_DY; + else if (strcmp(ev->keysymbol, "Left") == 0) + w -= E_BORDER_RESIZE_KEY_DX; + else if (strcmp(ev->keysymbol, "Right") == 0) + w += E_BORDER_RESIZE_KEY_DX; + else if (strcmp(ev->keysymbol, "Return") == 0) + goto stop; + else if (strcmp(ev->keysymbol, "Escape") == 0) + { + _e_border_action_restore_orig(action_border); + goto stop; + } + else + goto stop; + + e_border_resize(action_border, w, h); + _e_border_action_timeout_add(); + + return 1; + + stop: + _e_border_resize_end(action_border); + _e_border_action_finish(); + return 0; +} + +static int +_e_border_resize_mouse_down(void *data, int type, void *event) +{ + Ecore_X_Event_Mouse_Button_Down *ev = event; + + if (ev->event_win != action_input_win) + return 1; + + if (!action_border) + fputs("ERROR: no action_border!\n", stderr); + + _e_border_resize_end(action_border); + _e_border_action_finish(); + return 0; +} + +EAPI void +e_border_act_resize_keyboard(E_Border *bd) +{ + if (!bd) + return; + + if (!_e_border_resize_begin(bd)) + return; + + if (!_e_border_action_input_win_new(bd)) + { + _e_border_resize_end(bd); + return; + } + + _e_border_action_init(bd); + + if (action_handler_key) + ecore_event_handler_del(action_handler_key); + action_handler_key = ecore_event_handler_add(ECORE_X_EVENT_KEY_DOWN, _e_border_resize_key_down, NULL); + + if (action_handler_mouse) + ecore_event_handler_del(action_handler_mouse); + action_handler_mouse = ecore_event_handler_add(ECORE_X_EVENT_MOUSE_BUTTON_DOWN, _e_border_resize_mouse_down, NULL); +} + EAPI void e_border_act_move_begin(E_Border *bd, Ecore_X_Event_Mouse_Button_Down *ev) { diff --git a/src/bin/e_border.h b/src/bin/e_border.h index 29fc9abf1..6d239fb72 100644 --- a/src/bin/e_border.h +++ b/src/bin/e_border.h @@ -598,6 +598,9 @@ EAPI void e_border_idler_before(void); EAPI Evas_List *e_border_client_list(void); +EAPI void e_border_act_move_keyboard(E_Border *bd); +EAPI void e_border_act_resize_keyboard(E_Border *bd); + EAPI void e_border_act_move_begin(E_Border *bd, Ecore_X_Event_Mouse_Button_Down *ev); EAPI void e_border_act_move_end(E_Border *bd, Ecore_X_Event_Mouse_Button_Up *ev); EAPI void e_border_act_resize_begin(E_Border *bd, Ecore_X_Event_Mouse_Button_Down *ev);