aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2022-04-03 19:33:52 +0800
committerPo Lu2022-04-03 19:34:06 +0800
commit1fb20a4dde8c63a1aae570b59bb4bbb02673bec9 (patch)
tree59ac2ac304fe6936dc46d90e15bb2ee080f694c8 /src
parent9ccaf35e0b52de2fdf906efe1ae935012745e832 (diff)
downloademacs-1fb20a4dde8c63a1aae570b59bb4bbb02673bec9.tar.gz
emacs-1fb20a4dde8c63a1aae570b59bb4bbb02673bec9.zip
Implement `drag-source' values of `track-mouse' on PGTK.
* src/frame.c (Fmouse_position, mouse_position) (Fmouse_pixel_position): Fix crashes when mouse_position_hook stores nil. * src/pgtkterm.c (pgtk_mouse_position): Behave appropriately.
Diffstat (limited to 'src')
-rw-r--r--src/frame.c30
-rw-r--r--src/pgtkterm.c28
2 files changed, 39 insertions, 19 deletions
diff --git a/src/frame.c b/src/frame.c
index e531891a8a3..7a9ed3302e4 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -2505,9 +2505,12 @@ vertical offset, measured in units of the frame's default character size.
2505If Emacs is running on a mouseless terminal or hasn't been programmed 2505If Emacs is running on a mouseless terminal or hasn't been programmed
2506to read the mouse position, it returns the selected frame for FRAME 2506to read the mouse position, it returns the selected frame for FRAME
2507and nil for X and Y. 2507and nil for X and Y.
2508If `mouse-position-function' is non-nil, `mouse-position' calls it, 2508
2509passing the normal return value to that function as an argument, 2509FRAME might be nil if `track-mouse' is set to `drag-source'. This
2510and returns whatever that function returns. */) 2510means there is no frame under the mouse. If `mouse-position-function'
2511is non-nil, `mouse-position' calls it, passing the normal return value
2512to that function as an argument, and returns whatever that function
2513returns. */)
2511 (void) 2514 (void)
2512{ 2515{
2513 return mouse_position (true); 2516 return mouse_position (true);
@@ -2534,7 +2537,7 @@ mouse_position (bool call_mouse_position_function)
2534 &time_dummy); 2537 &time_dummy);
2535 } 2538 }
2536 2539
2537 if (! NILP (x)) 2540 if (! NILP (x) && f)
2538 { 2541 {
2539 int col = XFIXNUM (x); 2542 int col = XFIXNUM (x);
2540 int row = XFIXNUM (y); 2543 int row = XFIXNUM (y);
@@ -2542,7 +2545,10 @@ mouse_position (bool call_mouse_position_function)
2542 XSETINT (x, col); 2545 XSETINT (x, col);
2543 XSETINT (y, row); 2546 XSETINT (y, row);
2544 } 2547 }
2545 XSETFRAME (lispy_dummy, f); 2548 if (f)
2549 XSETFRAME (lispy_dummy, f);
2550 else
2551 lispy_dummy = Qnil;
2546 retval = Fcons (lispy_dummy, Fcons (x, y)); 2552 retval = Fcons (lispy_dummy, Fcons (x, y));
2547 if (call_mouse_position_function && !NILP (Vmouse_position_function)) 2553 if (call_mouse_position_function && !NILP (Vmouse_position_function))
2548 retval = call1 (Vmouse_position_function, retval); 2554 retval = call1 (Vmouse_position_function, retval);
@@ -2555,9 +2561,11 @@ DEFUN ("mouse-pixel-position", Fmouse_pixel_position,
2555The position is given in pixel units, where (0, 0) is the 2561The position is given in pixel units, where (0, 0) is the
2556upper-left corner of the frame, X is the horizontal offset, and Y is 2562upper-left corner of the frame, X is the horizontal offset, and Y is
2557the vertical offset. 2563the vertical offset.
2558If Emacs is running on a mouseless terminal or hasn't been programmed 2564FRAME might be nil if `track-mouse' is set to `drag-source'. This
2559to read the mouse position, it returns the selected frame for FRAME 2565means there is no frame under the mouse. If Emacs is running on a
2560and nil for X and Y. */) 2566mouseless terminal or hasn't been programmed to read the mouse
2567position, it returns the selected frame for FRAME and nil for X and
2568Y. */)
2561 (void) 2569 (void)
2562{ 2570{
2563 struct frame *f; 2571 struct frame *f;
@@ -2578,7 +2586,11 @@ and nil for X and Y. */)
2578 &time_dummy); 2586 &time_dummy);
2579 } 2587 }
2580 2588
2581 XSETFRAME (lispy_dummy, f); 2589 if (f)
2590 XSETFRAME (lispy_dummy, f);
2591 else
2592 lispy_dummy = Qnil;
2593
2582 retval = Fcons (lispy_dummy, Fcons (x, y)); 2594 retval = Fcons (lispy_dummy, Fcons (x, y));
2583 if (!NILP (Vmouse_position_function)) 2595 if (!NILP (Vmouse_position_function))
2584 retval = call1 (Vmouse_position_function, retval); 2596 retval = call1 (Vmouse_position_function, retval);
diff --git a/src/pgtkterm.c b/src/pgtkterm.c
index 216b5ee7dd5..94587381424 100644
--- a/src/pgtkterm.c
+++ b/src/pgtkterm.c
@@ -3329,8 +3329,8 @@ pgtk_frame_up_to_date (struct frame *f)
3329 3329
3330static void 3330static void
3331pgtk_mouse_position (struct frame **fp, int insist, Lisp_Object * bar_window, 3331pgtk_mouse_position (struct frame **fp, int insist, Lisp_Object * bar_window,
3332 enum scroll_bar_part *part, Lisp_Object * x, 3332 enum scroll_bar_part *part, Lisp_Object *x,
3333 Lisp_Object * y, Time * timestamp) 3333 Lisp_Object *y, Time *timestamp)
3334{ 3334{
3335 struct frame *f1; 3335 struct frame *f1;
3336 struct pgtk_display_info *dpyinfo = FRAME_DISPLAY_INFO (*fp); 3336 struct pgtk_display_info *dpyinfo = FRAME_DISPLAY_INFO (*fp);
@@ -3339,6 +3339,7 @@ pgtk_mouse_position (struct frame **fp, int insist, Lisp_Object * bar_window,
3339 GdkDevice *device; 3339 GdkDevice *device;
3340 GdkModifierType mask; 3340 GdkModifierType mask;
3341 GdkWindow *win; 3341 GdkWindow *win;
3342 bool return_frame_flag = false;
3342 3343
3343 block_input (); 3344 block_input ();
3344 3345
@@ -3352,30 +3353,37 @@ pgtk_mouse_position (struct frame **fp, int insist, Lisp_Object * bar_window,
3352 3353
3353 dpyinfo->last_mouse_scroll_bar = NULL; 3354 dpyinfo->last_mouse_scroll_bar = NULL;
3354 3355
3355 if (gui_mouse_grabbed (dpyinfo)) 3356 if (gui_mouse_grabbed (dpyinfo)
3357 && (!EQ (track_mouse, Qdropping)
3358 && !EQ (track_mouse, Qdrag_source)))
3356 { 3359 {
3357 /* 1.1. use last_mouse_frame as frame where the pointer is on. */ 3360 /* 1.1. use last_mouse_frame as frame where the pointer is
3361 on. */
3358 f1 = dpyinfo->last_mouse_frame; 3362 f1 = dpyinfo->last_mouse_frame;
3359 } 3363 }
3360 else 3364 else
3361 { 3365 {
3362 f1 = *fp; 3366 f1 = *fp;
3363 /* 1.2. get frame where the pointer is on. */ 3367 /* 1.2. get frame where the pointer is on. */
3364 win = gtk_widget_get_window (FRAME_GTK_WIDGET (*fp)); 3368 win = gtk_widget_get_window (FRAME_GTK_WIDGET (*fp));
3365 seat = gdk_display_get_default_seat (dpyinfo->gdpy); 3369 seat = gdk_display_get_default_seat (dpyinfo->gdpy);
3366 device = gdk_seat_get_pointer (seat); 3370 device = gdk_seat_get_pointer (seat);
3367 win = 3371 win = gdk_window_get_device_position (win, device, &win_x,
3368 gdk_window_get_device_position (win, device, &win_x, &win_y, &mask); 3372 &win_y, &mask);
3369 if (win != NULL) 3373 if (win != NULL)
3370 f1 = pgtk_any_window_to_frame (win); 3374 f1 = pgtk_any_window_to_frame (win);
3371 else 3375 else
3372 { 3376 {
3373 /* crossing display server? */
3374 f1 = SELECTED_FRAME (); 3377 f1 = SELECTED_FRAME ();
3378
3379 if (!FRAME_PGTK_P (f1))
3380 f1 = dpyinfo->last_mouse_frame;
3381
3382 return_frame_flag = EQ (track_mouse, Qdrag_source);
3375 } 3383 }
3376 } 3384 }
3377 3385
3378 /* f1 can be a terminal frame. Bug#50322 */ 3386 /* F1 can be a terminal frame. (Bug#50322) */
3379 if (f1 == NULL || !FRAME_PGTK_P (f1)) 3387 if (f1 == NULL || !FRAME_PGTK_P (f1))
3380 { 3388 {
3381 unblock_input (); 3389 unblock_input ();
@@ -3399,7 +3407,7 @@ pgtk_mouse_position (struct frame **fp, int insist, Lisp_Object * bar_window,
3399 3407
3400 *bar_window = Qnil; 3408 *bar_window = Qnil;
3401 *part = 0; 3409 *part = 0;
3402 *fp = f1; 3410 *fp = !return_frame_flag ? f1 : NULL;
3403 XSETINT (*x, win_x); 3411 XSETINT (*x, win_x);
3404 XSETINT (*y, win_y); 3412 XSETINT (*y, win_y);
3405 *timestamp = dpyinfo->last_mouse_movement_time; 3413 *timestamp = dpyinfo->last_mouse_movement_time;