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