diff options
| author | Po Lu | 2022-04-03 19:33:52 +0800 |
|---|---|---|
| committer | Po Lu | 2022-04-03 19:34:06 +0800 |
| commit | 1fb20a4dde8c63a1aae570b59bb4bbb02673bec9 (patch) | |
| tree | 59ac2ac304fe6936dc46d90e15bb2ee080f694c8 /src | |
| parent | 9ccaf35e0b52de2fdf906efe1ae935012745e832 (diff) | |
| download | emacs-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.c | 30 | ||||
| -rw-r--r-- | src/pgtkterm.c | 28 |
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. | |||
| 2505 | If Emacs is running on a mouseless terminal or hasn't been programmed | 2505 | If Emacs is running on a mouseless terminal or hasn't been programmed |
| 2506 | to read the mouse position, it returns the selected frame for FRAME | 2506 | to read the mouse position, it returns the selected frame for FRAME |
| 2507 | and nil for X and Y. | 2507 | and nil for X and Y. |
| 2508 | If `mouse-position-function' is non-nil, `mouse-position' calls it, | 2508 | |
| 2509 | passing the normal return value to that function as an argument, | 2509 | FRAME might be nil if `track-mouse' is set to `drag-source'. This |
| 2510 | and returns whatever that function returns. */) | 2510 | means there is no frame under the mouse. If `mouse-position-function' |
| 2511 | is non-nil, `mouse-position' calls it, passing the normal return value | ||
| 2512 | to that function as an argument, and returns whatever that function | ||
| 2513 | returns. */) | ||
| 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, | |||
| 2555 | The position is given in pixel units, where (0, 0) is the | 2561 | The position is given in pixel units, where (0, 0) is the |
| 2556 | upper-left corner of the frame, X is the horizontal offset, and Y is | 2562 | upper-left corner of the frame, X is the horizontal offset, and Y is |
| 2557 | the vertical offset. | 2563 | the vertical offset. |
| 2558 | If Emacs is running on a mouseless terminal or hasn't been programmed | 2564 | FRAME might be nil if `track-mouse' is set to `drag-source'. This |
| 2559 | to read the mouse position, it returns the selected frame for FRAME | 2565 | means there is no frame under the mouse. If Emacs is running on a |
| 2560 | and nil for X and Y. */) | 2566 | mouseless terminal or hasn't been programmed to read the mouse |
| 2567 | position, it returns the selected frame for FRAME and nil for X and | ||
| 2568 | Y. */) | ||
| 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 | ||
| 3330 | static void | 3330 | static void |
| 3331 | pgtk_mouse_position (struct frame **fp, int insist, Lisp_Object * bar_window, | 3331 | pgtk_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; |