On Sun, Sep 14, 2008 at 4:13 PM, Ivan <[EMAIL PROTECTED]> wrote:
> On Sun, Sep 14, 2008 at 3:20 PM, Gustavo Sverzut Barbieri
> <[EMAIL PROTECTED]> wrote:
>> On Sun, Sep 14, 2008 at 2:07 AM, Gustavo Sverzut Barbieri
>> <[EMAIL PROTECTED]> wrote:
>>> On Sun, Sep 14, 2008 at 1:53 AM, Gustavo Sverzut Barbieri
>>> <[EMAIL PROTECTED]> wrote:
>>>> Guys,
>>>>
>>>> I really miss a feature from other window managers, at least KWin and
>>>> WindowMaker, that is the option to move and resize windows using just
>>>> the keyboard. Basically you activate a shortcut to enter the "action
>>>> mode", in which you use the keyboard arrows to move or resize the
>>>> window and then you hit "Enter" to confirm or "Escape" to rollback, if
>>>> you wait some seconds it will also confirm, since it's not a dangerous
>>>> option, it is more intuitive (you don't even need to know you need to
>>>> confirm)... if you say "Oh, sh*t" then you usually hit Escape and
>>>> you'll learn it will rollback.
>>>>
>>>> This is implemented in the attached patch. It's very rough and needs
>>>> some review, but it works nicely, except:
>>>>  - we'll have 2 items in the bindings for each action: "Move" and
>>>> "Move with keyboard", etc.
>>>>  - offsets are not configurable, they're fixed in 5px in each
>>>> direction for each operation;
>>>>  - timeout is not configurable, it's 5s;
>>>>  - no geometry window while moving or resizing windows.
>>>>
>>>> The first point is really easy to remove, but then I guess it would
>>>> impact the mouse bindings, anyone with more experience in that can
>>>> confirm?
>>>>
>>>> The second and third are easy to add, but maybe it's too much. I'll
>>>> add if required, but I want to avoid too much useless options going
>>>> in.
>>>>
>>>> The last point I haven't looked at it, but I guess i can learn it from
>>>> existing code. hints are welcome, of course.
>>>
>>> Ok, 4th point done, also fixed the check for locks (was using stack
>>> due copy&paste) and added that check on the api entrance as well.
>>>
>>> PS: funny that in less than 15min after mailing this at least 2 guys
>>> replied to me on IRC saying they liked the idea! Awesome :-)
>>
>> Ok, found one issue but no clue on how to fix it: on the first
>> move/resize the first move/resize popup is at a wrong position...
>> e_{move,resize}_begin() is correct, the values are correct, just the
>> position of the popup is off.
>>
>>
>> --
>> Gustavo Sverzut Barbieri
>> http://profusion.mobi embedded systems
>> --------------------------------------
>> MSN: [EMAIL PROTECTED]
>> Skype: gsbarbieri
>> Mobile: +55 (19) 9225-2202
>>
>> -------------------------------------------------------------------------
>> This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
>> Build the coolest Linux based applications with Moblin SDK & win great prizes
>> Grand prize is a trip for two to an Open Source event anywhere in the world
>> http://moblin-contest.org/redirect.php?banner_id=100&url=/
>> _______________________________________________
>> enlightenment-devel mailing list
>> [email protected]
>> https://lists.sourceforge.net/lists/listinfo/enlightenment-devel
>>
>
> You forgot to set the position of the popup as the normal move/resize do.
> Here is v3

thanks, I also noticed that there are _e_border_{move,resize}_begin()
and end to do that, with e_border_{move,resize}() calling the required
code to update the popups.

attached is a new version, that does that and also cares to listen to
mouse button down events and finish (confirm) the action.

-- 
Gustavo Sverzut Barbieri
http://profusion.mobi embedded systems
--------------------------------------
MSN: [EMAIL PROTECTED]
Skype: gsbarbieri
Mobile: +55 (19) 9225-2202
Index: src/bin/e_border.c
===================================================================
--- src/bin/e_border.c	(revision 35986)
+++ src/bin/e_border.c	(working copy)
@@ -2608,7 +2608,286 @@
    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)
 {
    E_OBJECT_CHECK(bd);
Index: src/bin/e_border.h
===================================================================
--- src/bin/e_border.h	(revision 35984)
+++ src/bin/e_border.h	(working copy)
@@ -598,6 +598,9 @@
 
 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);
Index: src/bin/e_actions.c
===================================================================
--- src/bin/e_actions.c	(revision 35984)
+++ src/bin/e_actions.c	(working copy)
@@ -123,6 +123,19 @@
    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 @@
    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 @@
    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 @@
    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"), 
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
enlightenment-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to