Hmm. I don't know why you don't get the modifier, are you using UTF-8
mouse or not?

Looks reasonable but the nesting is way too much, that code needs to be
pulled out into a function.


> Mon, Jul 04, 2011 at 06:30:47AM +0200, marcel partap wrote:
> 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