[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [RP] adding some basic mouse support to switch frame
From: |
Julien Pagès |
Subject: |
Re: [RP] adding some basic mouse support to switch frame |
Date: |
Wed, 01 Feb 2017 15:01:27 +0100 |
User-agent: |
mu4e 0.9.17; emacs 25.1.1 |
Spiros Bousbouras writes:
> On Wednesday 2017-01-25 Julien Pagès wrote :
>> I would like to add some basic support to be able to switch frame using
>> the mouse. It should be configurable, I do not intend to change the
>> default behavior. I was thinking about a new variable, let's say
>> 'mousefocuspolicy', which could take some values:
>>
>> - "none": this is the current behavior
>> - "click": allow to select the frame under the mouse when the user click
>> - "move": (maybe this can be done later, I am not sure of that yet) this
>> would select the frame automatically under the mouse, when the user
>> move it
>>
>> It could then be used easily in the configuration file:
>>
>> set mousefocuspolicy click
>
> BLASPHEMY ! HERESY ! ;-)
>
> No , actually this is a good idea ; I would find useful both the "click" and
> "move" functionalities so I say go for it.
Excellent, you got me on the first line :D
So I wrote a patch for the click feature. It seems to work pretty well,
I tried it on a laptop connected to an external screen and it seems OK
to me. Note that the frames are selected (not the windows) which I
believe is better.
I am not sure for the "mouse" policy, but I don't plan to do it right
now - it seems to be a bit more complicated than what I expected :).
Once you are happy with the attached patch (note it is also available on
my github account,
https://github.com/parkouss/ratpoison/commit/15c2a0ab6cfe944d65c3d0831cc7c01219ea1839),
I would be happy to write another patch for the documentation/changelog
(I am not sure what I should change yet, and I am not a native English
speaker, but I would be glad to do my best!).
Cheers,
>From 15c2a0ab6cfe944d65c3d0831cc7c01219ea1839 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Pag=C3=A8s?= <address@hidden>
Date: Sun, 29 Jan 2017 14:23:47 +0100
Subject: [PATCH] add basic support for the mouse
Basic support for the mouse is provided to be able to activate a frame
when clicking on it.
To activate the behavior, the mousefocuspolicy variable must be set:
set mousefocuspolicy click
Currently mousefocuspolicy only accept two values: none (no mouse
support at all) and click (activate a frame on click).
---
src/actions.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/data.h | 3 +++
src/events.c | 20 ++++++++++++++++++-
src/globals.h | 4 ++++
src/main.c | 2 ++
src/screen.c | 2 +-
src/split.c | 21 ++++++++++++++++++++
src/split.h | 1 +
8 files changed, 113 insertions(+), 2 deletions(-)
diff --git a/src/actions.c b/src/actions.c
index ef856cf..7a511ba 100644
--- a/src/actions.c
+++ b/src/actions.c
@@ -162,6 +162,7 @@ static cmdret * set_inputwidth (struct cmdarg **args);
static cmdret * set_waitcursor (struct cmdarg **args);
static cmdret * set_winfmt (struct cmdarg **args);
static cmdret * set_winname (struct cmdarg **args);
+static cmdret * set_mousefocuspolicy (struct cmdarg **args);
static cmdret * set_framefmt (struct cmdarg **args);
static cmdret * set_fgcolor (struct cmdarg **args);
static cmdret * set_bgcolor (struct cmdarg **args);
@@ -373,6 +374,7 @@ init_set_vars (void)
add_set_var ("wingravity", set_wingravity, 1, "", arg_GRAVITY);
add_set_var ("winliststyle", set_winliststyle, 1, "", arg_STRING);
add_set_var ("winname", set_winname, 1, "", arg_STRING);
+ add_set_var ("mousefocuspolicy", set_mousefocuspolicy, 1, "", arg_STRING);
}
/* i_nrequired is the number required when called
@@ -1258,6 +1260,30 @@ ungrab_rat (void)
XUngrabPointer (dpy, CurrentTime);
}
+static void
+grab_button (void)
+{
+ int j;
+ for (j=0; j<num_screens; j++)
+ {
+ rp_screen *screen = &screens[j];
+ XGrabButton(dpy, AnyButton, AnyModifier, screen->root,
+ True, ButtonPressMask,
+ GrabModeSync, GrabModeAsync, None, None);
+ }
+}
+
+static void
+ungrab_button (void)
+{
+ int j;
+ for (j=0; j<num_screens; j++)
+ {
+ rp_screen *screen = &screens[j];
+ XUngrabButton(dpy, AnyButton, AnyModifier, screen->root);
+ }
+}
+
/* Unmanage window */
cmdret *
cmd_unmanage (int interactive, struct cmdarg **args)
@@ -4304,6 +4330,42 @@ set_winname (struct cmdarg **args)
}
static cmdret *
+set_mousefocuspolicy(struct cmdarg **args)
+{
+ char *policy;
+
+ if (args[0] == NULL)
+ switch (defaults.mouse_focus_policy)
+ {
+ case MOUSE_FOCUS_POLICY_NONE:
+ return cmdret_new (RET_SUCCESS, "none");
+ case MOUSE_FOCUS_POLICY_CLICK:
+ return cmdret_new (RET_SUCCESS, "click");
+ default:
+ PRINT_DEBUG (("Unknown mouse_focus_policy\n"));
+ return cmdret_new (RET_FAILURE, "unknown");
+ }
+
+ policy = ARG_STRING(0);
+
+ if (!strncmp (policy, "none", sizeof ("none")))
+ {
+ defaults.mouse_focus_policy = MOUSE_FOCUS_POLICY_NONE;
+ ungrab_button();
+ }
+ else if (!strncmp (policy, "click", sizeof ("click")))
+ {
+ defaults.mouse_focus_policy = MOUSE_FOCUS_POLICY_CLICK;
+ grab_button();
+ }
+ else
+ return cmdret_new (RET_FAILURE,
+ "set mousefocuspolicy: invalid argument `%s'", policy);
+
+ return cmdret_new (RET_SUCCESS, NULL);
+}
+
+static cmdret *
set_framefmt (struct cmdarg **args)
{
if (args[0] == NULL)
diff --git a/src/data.h b/src/data.h
index 52aaa42..da8cffa 100644
--- a/src/data.h
+++ b/src/data.h
@@ -275,6 +275,9 @@ struct rp_defaults
/* Frame indicator format */
char *frame_fmt;
+
+ /* Window focus policy for the mouse: none or click */
+ int mouse_focus_policy;
};
/* Information about a child process. */
diff --git a/src/events.c b/src/events.c
index 814e1ef..fd96fcd 100644
--- a/src/events.c
+++ b/src/events.c
@@ -793,6 +793,19 @@ selection_clear (void)
selection.len = 0;
}
+static void
+button_press (XButtonEvent * ev)
+{
+ rp_frame * frame;
+
+ if (defaults.mouse_focus_policy == MOUSE_FOCUS_POLICY_CLICK)
+ {
+ frame = find_frame_at_cursor_pos (ev->x_root, ev->y_root);
+ if (frame)
+ set_active_frame(frame, 1);
+ }
+}
+
/* Given an event, call the correct function to handle it. */
static void
delegate_event (XEvent *ev)
@@ -871,7 +884,12 @@ delegate_event (XEvent *ev)
PRINT_DEBUG (("--- Handling ConfigureNotify ---\n"));
configure_notify( &ev->xconfigure );
break;
-
+
+ case ButtonPress:
+ XAllowEvents (dpy, ReplayPointer, CurrentTime); /* ReplayPointer resends
the mouse event */
+ button_press(&ev->xbutton);
+ break;
+
case MapNotify:
case Expose:
case MotionNotify:
diff --git a/src/globals.h b/src/globals.h
index 8f0d048..5b98f9b 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -57,6 +57,10 @@
#define WIN_NAME_RES_CLASS 1
#define WIN_NAME_RES_NAME 2
+/* Possible values for defaults.mouse_focus_policy */
+#define MOUSE_FOCUS_POLICY_NONE 0
+#define MOUSE_FOCUS_POLICY_CLICK 1
+
/* Possible directions to traverse the completions list. */
#define COMPLETION_NEXT 0
#define COMPLETION_PREVIOUS 1
diff --git a/src/main.c b/src/main.c
index 3c2b300..7175a0b 100644
--- a/src/main.c
+++ b/src/main.c
@@ -583,6 +583,8 @@ init_defaults (void)
defaults.history_expansion = False;
defaults.frame_selectors = xstrdup ("");
defaults.maxundos = 20;
+
+ defaults.mouse_focus_policy = MOUSE_FOCUS_POLICY_NONE;
}
int
diff --git a/src/screen.c b/src/screen.c
index 0afdee0..9e5866f 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -269,7 +269,7 @@ init_screen (rp_screen *s, int screen_num)
XSelectInput(dpy, RootWindow (dpy, screen_num),
PropertyChangeMask | ColormapChangeMask
| SubstructureRedirectMask | SubstructureNotifyMask
- | StructureNotifyMask);
+ | StructureNotifyMask | ButtonPressMask);
XSync (dpy, False);
/* Set the numset for the frames to our global numset. */
diff --git a/src/split.c b/src/split.c
index b36b99e..4f95296 100644
--- a/src/split.c
+++ b/src/split.c
@@ -1088,3 +1088,24 @@ find_frame_number (int num)
return NULL;
}
+
+rp_frame *
+find_frame_at_cursor_pos (int x, int y)
+{
+ int i;
+ rp_frame *cur;
+
+ for (i=0; i<num_screens; i++)
+ {
+ rp_screen *s = &screens[i];
+
+ list_for_each_entry (cur, &s->frames, node)
+ {
+ if (x >= (s->left + cur->x) && x <= (s->left + cur->x + cur->width)
+ && y >= (s->top + cur->y) && y <= (s->top + cur->y +
cur->height))
+ return cur;
+ }
+ }
+
+ return NULL;
+}
diff --git a/src/split.h b/src/split.h
index 87bb660..a65fc91 100644
--- a/src/split.h
+++ b/src/split.h
@@ -56,5 +56,6 @@ rp_frame *find_last_frame (void);
rp_frame * find_frame_number (int num);
rp_frame *current_frame (void);
+rp_frame *find_frame_at_cursor_pos (int x, int y);
#endif
--
2.7.4
--
~Julien
- Re: [RP] adding some basic mouse support to switch frame,
Julien Pagès <=