Thx, already had been looking at the received event without sign of modifier:
int k;
for (k=1; k<512; k*=2)
   log_debug("%s %d: (mouse.b & %d)=%d, (last_mouse.b & %d)=%d", __func__, __LINE__, k, 
(mouse->b & k), k, (c->last_mouse.b & k));

http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Mouse%20Tracking
So sad:
Note however that the shift and control bits are normally unavailable because 
xterm
uses the control modifier with mouse for popup menus, and the shift modifier is 
used
in the default translations for button events.

Well, now double middle click kills window. Actually, the second click has to be a mid click, first doesn't matter. Documentation challenge ^^ Going to unbreak this intermediate patch further and want to wrap whole block after
if (key == KEYC_MOUSE)
in a server_client_handle_mouse_event() func, but right now, sleep(&self).
#best.
--- server-client.c.orig        2011-07-02 05:41:16.745038555 +0200
+++ server-client.c     2011-07-04 05:57:49.580528530 +0200
@@ -64,6 +64,8 @@
        if (gettimeofday(&c->creation_time, NULL) != 0)
                fatal("gettimeofday failed");
        memcpy(&c->activity_time, &c->creation_time, sizeof c->activity_time);
+       memcpy(&c->dblclick_start, &c->creation_time, sizeof c->dblclick_start);
+       c->dblclick_start.tv_usec -= DBLCLICK_USEC;
 
        c->stdin_event = NULL;
        c->stdout_event = NULL;
@@ -259,6 +261,26 @@
        }
 }
 
+/* Check if mouse click is double click. */
+int
+server_client_is_double_click(struct mouse_event *mouse, struct client *c)
+{
+       struct timeval  tv;
+       u_int           diff_usec;
+
+       if (mouse->b != MOUSE_UP)
+               return (0);
+       /* Measure time since last click, update click start time. */
+       gettimeofday(&tv, NULL);
+       diff_usec  = tv.tv_usec - c->dblclick_start.tv_usec;
+       diff_usec += (tv.tv_sec - c->dblclick_start.tv_sec) * 1000000;
+       memcpy(&c->dblclick_start, &tv, sizeof c->dblclick_start);
+
+       /* Is double click if within DBLCLICK_USEC time. */
+       return (diff_usec <= DBLCLICK_USEC);
+}
+
+
 /* Handle data key input from client. */
 void
 server_client_handle_key(int key, struct mouse_event *mouse, void *data)
@@ -267,12 +289,15 @@
        struct session          *s;
        struct window           *w;
        struct window_pane      *wp;
+       struct winlink          *wl;
        struct options          *oo;
+       struct cmd_ctx           ctx;
        struct timeval           tv;
        struct key_binding      *bd;
        struct keylist          *keylist;
-       int                      xtimeout, isprefix;
+       int                      xtimeout, isprefix, winidx, dblclick, midclick;
        u_int                    i;
+       char                    *cause;
 
        /* Check the client is good to accept input. */
        if ((c->flags & (CLIENT_DEAD|CLIENT_SUSPENDED)) != 0)
@@ -314,6 +339,12 @@
 
        /* Check for mouse keys. */
        if (key == KEYC_MOUSE) {
+               dblclick = server_client_is_double_click(mouse, c);
+               midclick = (c->last_mouse.b & MOUSE_BUTTON) == MOUSE_2;
+               /* debug code: evidence that no modifiers r transmitted :( */
+               int k;
+               for (k=1; k<512; k*=2)
+                       log_debug("%s %d: (mouse.b & %d)=%d, (last_mouse.b & 
%d)=%d", __func__, __LINE__, k, (mouse->b & k), k, (c->last_mouse.b & k));
                if (c->flags & CLIENT_READONLY)
                        return;
                if (options_get_number(oo, "mouse-select-pane") &&
@@ -332,8 +363,35 @@
                    options_get_number(oo, "status")) {
                        if (mouse->b == MOUSE_UP &&
                            c->last_mouse.b != MOUSE_UP) {
-                               status_set_window_at(c, mouse->x);
-                               return;
+                               winidx = status_find_window_at(s, mouse->x);
+                               if (winidx == -1 && dblclick && !midclick) {
+                                       wl = session_new(s, NULL, "", c->cwd, 
-1, &cause);
+                                       if (wl == NULL) {
+                                               memset(&ctx, 0, sizeof ctx);
+                                               ctx.cmdclient = c;
+                                               server_client_msg_error(&ctx, 
"%s", cause);
+                                               xfree(cause);
+                                       }
+                                       else {
+                                               session_select(s, wl->idx);
+                                               server_redraw_session(s);
+                                       }
+                                       return;
+                               }
+                               if (winidx != -1) {
+                                       wl = winlink_find_by_index(&s->windows, 
winidx);
+                                       if (!midclick && session_select(s, 
winidx) != -1) {
+                                               server_redraw_session(s);
+                                               return;
+                                       }
+                                       if (midclick && dblclick) {
+                                               server_kill_window(wl->window);
+                                               recalculate_sizes();
+                                               return;
+                                       }
+
+                               }
+                               /* 80 column wrap frenzy ?! */
                        }
                        if (mouse->b & MOUSE_45) {
                                if ((mouse->b & MOUSE_BUTTON) == MOUSE_1) {
--- tmux.h.orig 2011-07-02 05:41:16.749038497 +0200
+++ tmux.h      2011-07-03 02:05:17.122512753 +0200
@@ -1188,6 +1188,8 @@
        struct session  *last_session;
 
        struct mouse_event last_mouse;
+       struct timeval     dblclick_start;
+#define DBLCLICK_USEC 500000
 
        int              references;
 };
@@ -1694,7 +1696,7 @@
 RB_PROTOTYPE(status_out_tree, status_out, entry, status_out_cmp);
 void    status_free_jobs(struct status_out_tree *);
 void    status_update_jobs(struct client *);
-void    status_set_window_at(struct client *, u_int);
+int     status_find_window_at(struct session *, u_int);
 int     status_redraw(struct client *);
 char   *status_replace(struct client *, struct session *,
             struct winlink *, struct window_pane *, const char *, time_t, int);
--- status.c.orig       2011-07-02 05:41:16.747038527 +0200
+++ status.c    2011-07-03 03:35:07.862500610 +0200
@@ -120,21 +120,19 @@
        return (right);
 }
 
-/* Set window at window list position. */
-void
-status_set_window_at(struct client *c, u_int x)
+/* Find window at window list coordinate. */
+int
+status_find_window_at(struct session *s, u_int x)
 {
-       struct session  *s = c->session;
        struct winlink  *wl;
 
        x += s->wlmouse;
        RB_FOREACH(wl, winlinks, &s->windows) {
-               if (x < wl->status_width &&
-                       session_select(s, wl->idx) == 0) {
-                       server_redraw_session(s);
-               }
+               if (x < wl->status_width)
+                       return wl->idx;
                x -= wl->status_width + 1;
        }
+       return -1;
 }
 
 /* Draw status for client on the last lines of given context. */
------------------------------------------------------------------------------
All of the data generated in your IT infrastructure is seriously valuable.
Why? It contains a definitive record of application performance, security 
threats, fraudulent activity, and more. Splunk takes this data and makes 
sense of it. IT sense. And common sense.
http://p.sf.net/sfu/splunk-d2d-c2
_______________________________________________
tmux-users mailing list
tmux-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tmux-users

Reply via email to