Support TTY child frames with GPM mouse
* lisp/frame.el (x-list-fonts): Delete `frame-at', to move to C implementation. * lisp/xt-mouse.el (xterm-mouse-event): Call new `tty-frame-at'. * src/term.c (tty_frame_at, Ftty_frame_at): New C function, replacing `frame-at' only for TTYs. (term_mouse_position): Use last_mouse_frame when it is set. (handle_one_term_event): Call tty_frame_at to get frame under mouse, store it in last_mouse_frame. Alter event coordinates based on mouse frame. (syms_of_term): Add tty-frame-at, last_mouse_frame. * src/termhooks.h: Make Gpm_Event parameter const.
This commit is contained in:
parent
2f63dab3ee
commit
d018a26f9c
4 changed files with 60 additions and 21 deletions
|
@ -1506,13 +1506,6 @@ FRAME defaults to the selected frame."
|
|||
(let ((edges (frame-edges frame 'outer-edges)))
|
||||
(- (nth 3 edges) (nth 1 edges))))
|
||||
|
||||
(defun frame-at (x y)
|
||||
"Return frame containing pixel position X, Y."
|
||||
(cl-loop for frame in (frame-list-z-order)
|
||||
as (x0 y0 x1 y1) = (frame-edges frame)
|
||||
when (and (<= x0 x (1- x1)) (<= y0 y (1- y1)))
|
||||
return frame))
|
||||
|
||||
(declare-function x-list-fonts "xfaces.c"
|
||||
(pattern &optional face frame maximum width))
|
||||
|
||||
|
|
|
@ -298,7 +298,7 @@ which is the \"1006\" extension implemented in Xterm >= 277."
|
|||
;; FIXME: The test for running in batch mode is here solely
|
||||
;; for the sake of xt-mouse-tests where the only frame is
|
||||
;; the initial frame.
|
||||
(frame (unless noninteractive (frame-at x y)))
|
||||
(frame (unless noninteractive (tty-frame-at x y)))
|
||||
;;(_ (message (format "*** %S" frame)))
|
||||
(frame-pos (frame-position frame))
|
||||
;;(_ (message (format "*** %S" frame-pos)))
|
||||
|
|
70
src/term.c
70
src/term.c
|
@ -141,6 +141,7 @@ static int max_frame_cols;
|
|||
struct tty_display_info *gpm_tty = NULL;
|
||||
|
||||
/* Last recorded mouse coordinates. */
|
||||
static Lisp_Object last_mouse_frame;
|
||||
static int last_mouse_x, last_mouse_y;
|
||||
#endif /* HAVE_GPM */
|
||||
|
||||
|
@ -2593,6 +2594,35 @@ tty_draw_row_with_mouse_face (struct window *w, struct glyph_row *row,
|
|||
|
||||
#endif
|
||||
|
||||
static Lisp_Object
|
||||
tty_frame_at (int x, int y)
|
||||
{
|
||||
for (Lisp_Object frames = Ftty_frame_list_z_order (Qnil); frames != Qnil;
|
||||
frames = Fcdr (frames))
|
||||
{
|
||||
Lisp_Object frame = Fcar (frames);
|
||||
struct frame *f = XFRAME (frame);
|
||||
|
||||
if (f->left_pos <= x && x < f->left_pos + f->pixel_width &&
|
||||
f->top_pos <= y && y < f->top_pos + f->pixel_height)
|
||||
return frame;
|
||||
}
|
||||
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
DEFUN ("tty-frame-at", Ftty_frame_at, Stty_frame_at,
|
||||
2, 2, 0,
|
||||
doc: /* Return tty frame containing pixel position X, Y. */)
|
||||
(Lisp_Object x, Lisp_Object y)
|
||||
{
|
||||
if (! FIXNUMP (x) || ! FIXNUMP (y))
|
||||
/* Coordinates this big can not correspond to any frame. */
|
||||
return Qnil;
|
||||
|
||||
return tty_frame_at (XFIXNUM (x), XFIXNUM (y));
|
||||
}
|
||||
|
||||
#ifdef HAVE_GPM
|
||||
|
||||
void
|
||||
|
@ -2638,7 +2668,12 @@ term_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
|
|||
enum scroll_bar_part *part, Lisp_Object *x,
|
||||
Lisp_Object *y, Time *timeptr)
|
||||
{
|
||||
*fp = SELECTED_FRAME ();
|
||||
/* If we've gotten no GPM mouse events yet, last_mouse_frame won't be
|
||||
set. Perhaps `gpm-mouse-mode' was never active. */
|
||||
if (! FRAMEP (last_mouse_frame))
|
||||
return;
|
||||
|
||||
*fp = XFRAME (last_mouse_frame);
|
||||
(*fp)->mouse_moved = 0;
|
||||
|
||||
*bar_window = Qnil;
|
||||
|
@ -2713,9 +2748,14 @@ term_mouse_click (struct input_event *result, Gpm_Event *event,
|
|||
}
|
||||
|
||||
int
|
||||
handle_one_term_event (struct tty_display_info *tty, Gpm_Event *event)
|
||||
handle_one_term_event (struct tty_display_info *tty, const Gpm_Event *event_in)
|
||||
{
|
||||
struct frame *f = XFRAME (tty->top_frame);
|
||||
Lisp_Object frame = tty_frame_at (event_in->x, event_in->y);
|
||||
struct frame *f = decode_live_frame (frame);
|
||||
Gpm_Event event = *event_in;
|
||||
event.x -= f->left_pos;
|
||||
event.y -= f->top_pos;
|
||||
|
||||
struct input_event ie;
|
||||
int count = 0;
|
||||
|
||||
|
@ -2723,30 +2763,34 @@ handle_one_term_event (struct tty_display_info *tty, Gpm_Event *event)
|
|||
ie.kind = NO_EVENT;
|
||||
ie.arg = Qnil;
|
||||
|
||||
if (event->type & (GPM_MOVE | GPM_DRAG))
|
||||
if (event.type & (GPM_MOVE | GPM_DRAG))
|
||||
{
|
||||
Gpm_DrawPointer (event->x, event->y, fileno (tty->output));
|
||||
/* The pointer must be drawn using screen coordinates (x,y), not
|
||||
frame coordinates. Use event_in which has an unmodified event
|
||||
directly from GPM. */
|
||||
Gpm_DrawPointer (event_in->x, event_in->y, fileno (tty->output));
|
||||
|
||||
/* Has the mouse moved off the glyph it was on at the last
|
||||
sighting? */
|
||||
if (event->x != last_mouse_x || event->y != last_mouse_y)
|
||||
if (event.x != last_mouse_x || event.y != last_mouse_y)
|
||||
{
|
||||
/* FIXME: These three lines can not be moved into
|
||||
/* FIXME: These four lines can not be moved into
|
||||
update_mouse_position unless xterm-mouse gets updated to
|
||||
generate mouse events via C code. See
|
||||
https://lists.gnu.org/archive/html/emacs-devel/2020-11/msg00163.html */
|
||||
last_mouse_x = event->x;
|
||||
last_mouse_y = event->y;
|
||||
last_mouse_frame = frame;
|
||||
last_mouse_x = event.x;
|
||||
last_mouse_y = event.y;
|
||||
f->mouse_moved = 1;
|
||||
|
||||
count += update_mouse_position (f, event->x, event->y);
|
||||
count += update_mouse_position (f, event.x, event.y);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
f->mouse_moved = 0;
|
||||
term_mouse_click (&ie, event, f);
|
||||
ie.arg = tty_handle_tab_bar_click (f, event->x, event->y,
|
||||
term_mouse_click (&ie, &event, f);
|
||||
ie.arg = tty_handle_tab_bar_click (f, event.x, event.y,
|
||||
(ie.modifiers & down_modifier) != 0, &ie);
|
||||
kbd_buffer_store_event (&ie);
|
||||
count++;
|
||||
|
@ -4967,9 +5011,11 @@ trigger redisplay. */);
|
|||
defsubr (&Stty__set_output_buffer_size);
|
||||
defsubr (&Stty__output_buffer_size);
|
||||
#endif /* !HAVE_ANDROID */
|
||||
defsubr (&Stty_frame_at);
|
||||
#ifdef HAVE_GPM
|
||||
defsubr (&Sgpm_mouse_start);
|
||||
defsubr (&Sgpm_mouse_stop);
|
||||
staticpro (&last_mouse_frame);
|
||||
#endif /* HAVE_GPM */
|
||||
|
||||
defsubr (&Stty_frame_geometry);
|
||||
|
|
|
@ -458,7 +458,7 @@ enum {
|
|||
|
||||
#ifdef HAVE_GPM
|
||||
#include <gpm.h>
|
||||
extern int handle_one_term_event (struct tty_display_info *, Gpm_Event *);
|
||||
extern int handle_one_term_event (struct tty_display_info *, const Gpm_Event *);
|
||||
extern void term_mouse_moveto (int, int);
|
||||
|
||||
/* The device for which we have enabled gpm support. */
|
||||
|
|
Loading…
Add table
Reference in a new issue