diff options
| author | Gregory Heytings | 2022-11-24 14:21:30 +0100 |
|---|---|---|
| committer | Gregory Heytings | 2022-11-24 14:21:30 +0100 |
| commit | ba9315b1641b483f2bf843c38dcdba0cd1643a55 (patch) | |
| tree | d119cae86c7386db66be72972d90f6c83215974d /src/pgtkterm.c | |
| parent | aef803d6c3d61004f15d0bc82fa7bf9952302312 (diff) | |
| parent | a3b654e069e563b0a2a6335ec310ada51400ac09 (diff) | |
| download | emacs-ba9315b1641b483f2bf843c38dcdba0cd1643a55.tar.gz emacs-ba9315b1641b483f2bf843c38dcdba0cd1643a55.zip | |
Merge master into feature/improved-locked-narrowing.
Diffstat (limited to 'src/pgtkterm.c')
| -rw-r--r-- | src/pgtkterm.c | 257 |
1 files changed, 175 insertions, 82 deletions
diff --git a/src/pgtkterm.c b/src/pgtkterm.c index 491ba338821..13f6c6c3c4d 100644 --- a/src/pgtkterm.c +++ b/src/pgtkterm.c | |||
| @@ -511,16 +511,16 @@ pgtk_free_frame_resources (struct frame *f) | |||
| 511 | 511 | ||
| 512 | if (FRAME_X_OUTPUT (f)->scrollbar_foreground_css_provider != NULL) | 512 | if (FRAME_X_OUTPUT (f)->scrollbar_foreground_css_provider != NULL) |
| 513 | { | 513 | { |
| 514 | GtkCssProvider *old = | 514 | GtkCssProvider *old |
| 515 | FRAME_X_OUTPUT (f)->scrollbar_foreground_css_provider; | 515 | = FRAME_X_OUTPUT (f)->scrollbar_foreground_css_provider; |
| 516 | g_object_unref (old); | 516 | g_object_unref (old); |
| 517 | FRAME_X_OUTPUT (f)->scrollbar_foreground_css_provider = NULL; | 517 | FRAME_X_OUTPUT (f)->scrollbar_foreground_css_provider = NULL; |
| 518 | } | 518 | } |
| 519 | 519 | ||
| 520 | if (FRAME_X_OUTPUT (f)->scrollbar_background_css_provider != NULL) | 520 | if (FRAME_X_OUTPUT (f)->scrollbar_background_css_provider != NULL) |
| 521 | { | 521 | { |
| 522 | GtkCssProvider *old = | 522 | GtkCssProvider *old |
| 523 | FRAME_X_OUTPUT (f)->scrollbar_background_css_provider; | 523 | = FRAME_X_OUTPUT (f)->scrollbar_background_css_provider; |
| 524 | g_object_unref (old); | 524 | g_object_unref (old); |
| 525 | FRAME_X_OUTPUT (f)->scrollbar_background_css_provider = NULL; | 525 | FRAME_X_OUTPUT (f)->scrollbar_background_css_provider = NULL; |
| 526 | } | 526 | } |
| @@ -714,40 +714,42 @@ pgtk_set_window_size (struct frame *f, bool change_gravity, | |||
| 714 | 714 | ||
| 715 | void | 715 | void |
| 716 | pgtk_iconify_frame (struct frame *f) | 716 | pgtk_iconify_frame (struct frame *f) |
| 717 | /* -------------------------------------------------------------------------- | ||
| 718 | External: Iconify window | ||
| 719 | -------------------------------------------------------------------------- */ | ||
| 720 | { | 717 | { |
| 718 | GtkWindow *window; | ||
| 719 | |||
| 721 | /* Don't keep the highlight on an invisible frame. */ | 720 | /* Don't keep the highlight on an invisible frame. */ |
| 721 | |||
| 722 | if (FRAME_DISPLAY_INFO (f)->highlight_frame == f) | 722 | if (FRAME_DISPLAY_INFO (f)->highlight_frame == f) |
| 723 | FRAME_DISPLAY_INFO (f)->highlight_frame = 0; | 723 | FRAME_DISPLAY_INFO (f)->highlight_frame = NULL; |
| 724 | |||
| 725 | /* If the frame is already iconified, return. */ | ||
| 724 | 726 | ||
| 725 | if (FRAME_ICONIFIED_P (f)) | 727 | if (FRAME_ICONIFIED_P (f)) |
| 726 | return; | 728 | return; |
| 727 | 729 | ||
| 728 | block_input (); | 730 | /* Child frames on PGTK have no outer widgets. In that case, simply |
| 731 | refuse to iconify the frame. */ | ||
| 729 | 732 | ||
| 730 | if (FRAME_GTK_OUTER_WIDGET (f)) | 733 | if (FRAME_GTK_OUTER_WIDGET (f)) |
| 731 | { | 734 | { |
| 732 | if (!FRAME_VISIBLE_P (f)) | 735 | if (!FRAME_VISIBLE_P (f)) |
| 733 | gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f)); | 736 | gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f)); |
| 734 | 737 | ||
| 735 | gtk_window_iconify (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f))); | 738 | window = GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)); |
| 736 | SET_FRAME_VISIBLE (f, 0); | ||
| 737 | SET_FRAME_ICONIFIED (f, true); | ||
| 738 | unblock_input (); | ||
| 739 | return; | ||
| 740 | } | ||
| 741 | 739 | ||
| 742 | /* Make sure the X server knows where the window should be positioned, | 740 | gtk_window_iconify (window); |
| 743 | in case the user deiconifies with the window manager. */ | ||
| 744 | if (!FRAME_VISIBLE_P (f) && !FRAME_ICONIFIED_P (f)) | ||
| 745 | pgtk_set_offset (f, f->left_pos, f->top_pos, 0); | ||
| 746 | 741 | ||
| 747 | SET_FRAME_ICONIFIED (f, true); | 742 | /* Don't make the frame iconified here. Doing so will cause it |
| 748 | SET_FRAME_VISIBLE (f, 0); | 743 | to be skipped by redisplay, until GDK says it is deiconified |
| 744 | (see window_state_event for more details). However, if the | ||
| 745 | window server rejects the iconification request, GDK will | ||
| 746 | never tell Emacs about the iconification not happening, | ||
| 747 | leading to the frame not being redisplayed until the next | ||
| 748 | window state change. */ | ||
| 749 | 749 | ||
| 750 | unblock_input (); | 750 | /* SET_FRAME_VISIBLE (f, 0); |
| 751 | SET_FRAME_ICONIFIED (f, true); */ | ||
| 752 | } | ||
| 751 | } | 753 | } |
| 752 | 754 | ||
| 753 | static gboolean | 755 | static gboolean |
| @@ -1331,8 +1333,8 @@ fill_background_by_face (struct frame *f, struct face *face, int x, int y, | |||
| 1331 | 1333 | ||
| 1332 | if (face->stipple != 0) | 1334 | if (face->stipple != 0) |
| 1333 | { | 1335 | { |
| 1334 | cairo_pattern_t *mask = | 1336 | cairo_pattern_t *mask |
| 1335 | FRAME_DISPLAY_INFO (f)->bitmaps[face->stipple - 1].pattern; | 1337 | = FRAME_DISPLAY_INFO (f)->bitmaps[face->stipple - 1].pattern; |
| 1336 | 1338 | ||
| 1337 | double r = ((face->foreground >> 16) & 0xff) / 255.0; | 1339 | double r = ((face->foreground >> 16) & 0xff) / 255.0; |
| 1338 | double g = ((face->foreground >> 8) & 0xff) / 255.0; | 1340 | double g = ((face->foreground >> 8) & 0xff) / 255.0; |
| @@ -1604,8 +1606,8 @@ pgtk_draw_glyphless_glyph_string_foreground (struct glyph_string *s) | |||
| 1604 | 1606 | ||
| 1605 | /* It is assured that all LEN characters in STR is ASCII. */ | 1607 | /* It is assured that all LEN characters in STR is ASCII. */ |
| 1606 | for (j = 0; j < len; j++) | 1608 | for (j = 0; j < len; j++) |
| 1607 | char2b[j] = | 1609 | char2b[j] |
| 1608 | s->font->driver->encode_char (s->font, str[j]) & 0xFFFF; | 1610 | = s->font->driver->encode_char (s->font, str[j]) & 0xFFFF; |
| 1609 | s->font->driver->draw (s, 0, upper_len, | 1611 | s->font->driver->draw (s, 0, upper_len, |
| 1610 | x + glyph->slice.glyphless.upper_xoff, | 1612 | x + glyph->slice.glyphless.upper_xoff, |
| 1611 | s->ybase + glyph->slice.glyphless.upper_yoff, | 1613 | s->ybase + glyph->slice.glyphless.upper_yoff, |
| @@ -2956,8 +2958,8 @@ pgtk_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, int x, | |||
| 2956 | 2958 | ||
| 2957 | if (w == XWINDOW (f->selected_window)) | 2959 | if (w == XWINDOW (f->selected_window)) |
| 2958 | { | 2960 | { |
| 2959 | int frame_x = | 2961 | int frame_x = (WINDOW_TO_FRAME_PIXEL_X (w, x) |
| 2960 | WINDOW_TO_FRAME_PIXEL_X (w, x) + WINDOW_LEFT_FRINGE_WIDTH (w); | 2962 | + WINDOW_LEFT_FRINGE_WIDTH (w)); |
| 2961 | int frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, y); | 2963 | int frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, y); |
| 2962 | pgtk_im_set_cursor_location (f, frame_x, frame_y, | 2964 | pgtk_im_set_cursor_location (f, frame_x, frame_y, |
| 2963 | w->phys_cursor_width, | 2965 | w->phys_cursor_width, |
| @@ -4516,16 +4518,29 @@ pgtk_free_pixmap (struct frame *f, Emacs_Pixmap pixmap) | |||
| 4516 | void | 4518 | void |
| 4517 | pgtk_focus_frame (struct frame *f, bool noactivate) | 4519 | pgtk_focus_frame (struct frame *f, bool noactivate) |
| 4518 | { | 4520 | { |
| 4519 | struct pgtk_display_info *dpyinfo = FRAME_DISPLAY_INFO (f); | 4521 | struct pgtk_display_info *dpyinfo; |
| 4522 | GtkWidget *widget; | ||
| 4523 | GtkWindow *window; | ||
| 4520 | 4524 | ||
| 4521 | GtkWidget *wid = FRAME_WIDGET (f); | 4525 | dpyinfo = FRAME_DISPLAY_INFO (f); |
| 4522 | 4526 | ||
| 4523 | if (dpyinfo->x_focus_frame != f && wid != NULL) | 4527 | if (FRAME_GTK_OUTER_WIDGET (f) && !noactivate) |
| 4524 | { | 4528 | { |
| 4525 | block_input (); | 4529 | /* The user says it is okay to activate the frame. Call |
| 4526 | gtk_widget_grab_focus (wid); | 4530 | gtk_window_present_with_time. If the timestamp specified |
| 4527 | unblock_input (); | 4531 | (actually a display serial on Wayland) is new enough, then |
| 4532 | any Wayland compositor supporting gtk_surface1_present will | ||
| 4533 | cause the frame to be activated. */ | ||
| 4534 | |||
| 4535 | window = GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)); | ||
| 4536 | gtk_window_present_with_time (window, dpyinfo->last_user_time); | ||
| 4537 | return; | ||
| 4528 | } | 4538 | } |
| 4539 | |||
| 4540 | widget = FRAME_WIDGET (f); | ||
| 4541 | |||
| 4542 | if (widget) | ||
| 4543 | gtk_widget_grab_focus (widget); | ||
| 4529 | } | 4544 | } |
| 4530 | 4545 | ||
| 4531 | static void | 4546 | static void |
| @@ -5142,13 +5157,15 @@ static gboolean | |||
| 5142 | key_press_event (GtkWidget *widget, GdkEvent *event, gpointer *user_data) | 5157 | key_press_event (GtkWidget *widget, GdkEvent *event, gpointer *user_data) |
| 5143 | { | 5158 | { |
| 5144 | union buffered_input_event inev; | 5159 | union buffered_input_event inev; |
| 5145 | ptrdiff_t nbytes = 0; | 5160 | ptrdiff_t nbytes; |
| 5146 | Mouse_HLInfo *hlinfo; | 5161 | Mouse_HLInfo *hlinfo; |
| 5147 | struct frame *f; | 5162 | struct frame *f; |
| 5163 | struct pgtk_display_info *dpyinfo; | ||
| 5148 | 5164 | ||
| 5149 | f = pgtk_any_window_to_frame (gtk_widget_get_window (widget)); | 5165 | f = pgtk_any_window_to_frame (gtk_widget_get_window (widget)); |
| 5150 | EVENT_INIT (inev.ie); | 5166 | EVENT_INIT (inev.ie); |
| 5151 | hlinfo = MOUSE_HL_INFO (f); | 5167 | hlinfo = MOUSE_HL_INFO (f); |
| 5168 | nbytes = 0; | ||
| 5152 | 5169 | ||
| 5153 | /* If mouse-highlight is an integer, input clears out | 5170 | /* If mouse-highlight is an integer, input clears out |
| 5154 | mouse highlighting. */ | 5171 | mouse highlighting. */ |
| @@ -5179,6 +5196,12 @@ key_press_event (GtkWidget *widget, GdkEvent *event, gpointer *user_data) | |||
| 5179 | Lisp_Object c; | 5196 | Lisp_Object c; |
| 5180 | guint state; | 5197 | guint state; |
| 5181 | 5198 | ||
| 5199 | dpyinfo = FRAME_DISPLAY_INFO (f); | ||
| 5200 | |||
| 5201 | /* Set the last user time for pgtk_focus_frame to work | ||
| 5202 | correctly. */ | ||
| 5203 | dpyinfo->last_user_time = event->key.time; | ||
| 5204 | |||
| 5182 | state = event->key.state; | 5205 | state = event->key.state; |
| 5183 | 5206 | ||
| 5184 | /* While super is pressed, the input method will always always | 5207 | /* While super is pressed, the input method will always always |
| @@ -5212,8 +5235,8 @@ key_press_event (GtkWidget *widget, GdkEvent *event, gpointer *user_data) | |||
| 5212 | 5235 | ||
| 5213 | /* Common for all keysym input events. */ | 5236 | /* Common for all keysym input events. */ |
| 5214 | XSETFRAME (inev.ie.frame_or_window, f); | 5237 | XSETFRAME (inev.ie.frame_or_window, f); |
| 5215 | inev.ie.modifiers = | 5238 | inev.ie.modifiers |
| 5216 | pgtk_gtk_to_emacs_modifiers (FRAME_DISPLAY_INFO (f), modifiers); | 5239 | = pgtk_gtk_to_emacs_modifiers (FRAME_DISPLAY_INFO (f), modifiers); |
| 5217 | inev.ie.timestamp = event->key.time; | 5240 | inev.ie.timestamp = event->key.time; |
| 5218 | 5241 | ||
| 5219 | /* First deal with keysyms which have defined | 5242 | /* First deal with keysyms which have defined |
| @@ -5361,11 +5384,37 @@ done: | |||
| 5361 | return TRUE; | 5384 | return TRUE; |
| 5362 | } | 5385 | } |
| 5363 | 5386 | ||
| 5387 | static struct pgtk_display_info * | ||
| 5388 | pgtk_display_info_for_display (GdkDisplay *dpy) | ||
| 5389 | { | ||
| 5390 | struct pgtk_display_info *dpyinfo; | ||
| 5391 | |||
| 5392 | for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next) | ||
| 5393 | { | ||
| 5394 | if (dpyinfo->display == dpy) | ||
| 5395 | return dpyinfo; | ||
| 5396 | } | ||
| 5397 | |||
| 5398 | return NULL; | ||
| 5399 | } | ||
| 5400 | |||
| 5364 | static gboolean | 5401 | static gboolean |
| 5365 | key_release_event (GtkWidget *widget, | 5402 | key_release_event (GtkWidget *widget, |
| 5366 | GdkEvent *event, | 5403 | GdkEvent *event, |
| 5367 | gpointer *user_data) | 5404 | gpointer *user_data) |
| 5368 | { | 5405 | { |
| 5406 | GdkDisplay *display; | ||
| 5407 | struct pgtk_display_info *dpyinfo; | ||
| 5408 | |||
| 5409 | display = gtk_widget_get_display (widget); | ||
| 5410 | dpyinfo = pgtk_display_info_for_display (display); | ||
| 5411 | |||
| 5412 | if (dpyinfo) | ||
| 5413 | /* This is needed on Wayland because of some brain dead | ||
| 5414 | compositors. Without them, we would not have to keep track of | ||
| 5415 | the serial of key release events. */ | ||
| 5416 | dpyinfo->last_user_time = event->key.time; | ||
| 5417 | |||
| 5369 | return TRUE; | 5418 | return TRUE; |
| 5370 | } | 5419 | } |
| 5371 | 5420 | ||
| @@ -5420,9 +5469,7 @@ map_event (GtkWidget *widget, | |||
| 5420 | /* Check if fullscreen was specified before we where mapped the | 5469 | /* Check if fullscreen was specified before we where mapped the |
| 5421 | first time, i.e. from the command line. */ | 5470 | first time, i.e. from the command line. */ |
| 5422 | if (!FRAME_X_OUTPUT (f)->has_been_visible) | 5471 | if (!FRAME_X_OUTPUT (f)->has_been_visible) |
| 5423 | { | 5472 | set_fullscreen_state (f); |
| 5424 | set_fullscreen_state (f); | ||
| 5425 | } | ||
| 5426 | 5473 | ||
| 5427 | if (!iconified) | 5474 | if (!iconified) |
| 5428 | { | 5475 | { |
| @@ -5465,24 +5512,6 @@ window_state_event (GtkWidget *widget, | |||
| 5465 | inev.ie.kind = NO_EVENT; | 5512 | inev.ie.kind = NO_EVENT; |
| 5466 | inev.ie.arg = Qnil; | 5513 | inev.ie.arg = Qnil; |
| 5467 | 5514 | ||
| 5468 | if (f) | ||
| 5469 | { | ||
| 5470 | if (new_state & GDK_WINDOW_STATE_FOCUSED) | ||
| 5471 | { | ||
| 5472 | if (FRAME_ICONIFIED_P (f)) | ||
| 5473 | { | ||
| 5474 | /* Gnome shell does not iconify us when C-z is pressed. | ||
| 5475 | It hides the frame. So if our state says we aren't | ||
| 5476 | hidden anymore, treat it as deiconified. */ | ||
| 5477 | SET_FRAME_VISIBLE (f, 1); | ||
| 5478 | SET_FRAME_ICONIFIED (f, false); | ||
| 5479 | FRAME_X_OUTPUT (f)->has_been_visible = true; | ||
| 5480 | inev.ie.kind = DEICONIFY_EVENT; | ||
| 5481 | XSETFRAME (inev.ie.frame_or_window, f); | ||
| 5482 | } | ||
| 5483 | } | ||
| 5484 | } | ||
| 5485 | |||
| 5486 | if (new_state & GDK_WINDOW_STATE_FULLSCREEN) | 5515 | if (new_state & GDK_WINDOW_STATE_FULLSCREEN) |
| 5487 | store_frame_param (f, Qfullscreen, Qfullboth); | 5516 | store_frame_param (f, Qfullscreen, Qfullboth); |
| 5488 | else if (new_state & GDK_WINDOW_STATE_MAXIMIZED) | 5517 | else if (new_state & GDK_WINDOW_STATE_MAXIMIZED) |
| @@ -5500,14 +5529,37 @@ window_state_event (GtkWidget *widget, | |||
| 5500 | else | 5529 | else |
| 5501 | store_frame_param (f, Qfullscreen, Qnil); | 5530 | store_frame_param (f, Qfullscreen, Qnil); |
| 5502 | 5531 | ||
| 5532 | /* The Wayland protocol provides no way for the client to know | ||
| 5533 | whether or not one of its toplevels has actually been | ||
| 5534 | deiconified. It only provides a request for clients to iconify a | ||
| 5535 | toplevel, without even the ability to determine whether or not | ||
| 5536 | the iconification request was rejected by the display server. | ||
| 5537 | |||
| 5538 | GDK computes the iconified state by sending a window state event | ||
| 5539 | containing only GDK_WINDOW_STATE_ICONIFIED immediately after | ||
| 5540 | gtk_window_iconify is called. That is error-prone if the request | ||
| 5541 | to iconify the frame was rejected by the display server, but is | ||
| 5542 | not the main problem here, as Wayland compositors only rarely | ||
| 5543 | reject such requests. GDK also assumes that it can clear the | ||
| 5544 | iconified state upon receiving the next toplevel configure event | ||
| 5545 | from the display server. Unfortunately, such events can be sent | ||
| 5546 | by Wayland compositors while the frame is iconified, and may also | ||
| 5547 | not be sent upon deiconification. So, no matter what Emacs does, | ||
| 5548 | the iconification state of a frame is likely to be wrong under | ||
| 5549 | one situation or another. */ | ||
| 5550 | |||
| 5503 | if (new_state & GDK_WINDOW_STATE_ICONIFIED) | 5551 | if (new_state & GDK_WINDOW_STATE_ICONIFIED) |
| 5504 | SET_FRAME_ICONIFIED (f, true); | 5552 | { |
| 5553 | SET_FRAME_ICONIFIED (f, true); | ||
| 5554 | SET_FRAME_VISIBLE (f, false); | ||
| 5555 | } | ||
| 5505 | else | 5556 | else |
| 5506 | { | 5557 | { |
| 5507 | FRAME_X_OUTPUT (f)->has_been_visible = true; | 5558 | FRAME_X_OUTPUT (f)->has_been_visible = true; |
| 5508 | inev.ie.kind = DEICONIFY_EVENT; | 5559 | inev.ie.kind = DEICONIFY_EVENT; |
| 5509 | XSETFRAME (inev.ie.frame_or_window, f); | 5560 | XSETFRAME (inev.ie.frame_or_window, f); |
| 5510 | SET_FRAME_ICONIFIED (f, false); | 5561 | SET_FRAME_ICONIFIED (f, false); |
| 5562 | SET_FRAME_VISIBLE (f, true); | ||
| 5511 | } | 5563 | } |
| 5512 | 5564 | ||
| 5513 | if (new_state & GDK_WINDOW_STATE_STICKY) | 5565 | if (new_state & GDK_WINDOW_STATE_STICKY) |
| @@ -5899,9 +5951,10 @@ construct_mouse_click (struct input_event *result, | |||
| 5899 | result->kind = MOUSE_CLICK_EVENT; | 5951 | result->kind = MOUSE_CLICK_EVENT; |
| 5900 | result->code = event->button - 1; | 5952 | result->code = event->button - 1; |
| 5901 | result->timestamp = event->time; | 5953 | result->timestamp = event->time; |
| 5902 | result->modifiers = | 5954 | result->modifiers = (pgtk_gtk_to_emacs_modifiers (FRAME_DISPLAY_INFO (f), |
| 5903 | (pgtk_gtk_to_emacs_modifiers (FRAME_DISPLAY_INFO (f), event->state) | | 5955 | event->state) |
| 5904 | (event->type == GDK_BUTTON_RELEASE ? up_modifier : down_modifier)); | 5956 | | (event->type == GDK_BUTTON_RELEASE |
| 5957 | ? up_modifier : down_modifier)); | ||
| 5905 | 5958 | ||
| 5906 | XSETINT (result->x, event->x); | 5959 | XSETINT (result->x, event->x); |
| 5907 | XSETINT (result->y, event->y); | 5960 | XSETINT (result->y, event->y); |
| @@ -5966,6 +6019,10 @@ button_event (GtkWidget *widget, GdkEvent *event, | |||
| 5966 | } | 6019 | } |
| 5967 | } | 6020 | } |
| 5968 | 6021 | ||
| 6022 | /* Set the last user time, used to activate the frame in | ||
| 6023 | pgtk_focus_frame. */ | ||
| 6024 | dpyinfo->last_user_time = event->button.time; | ||
| 6025 | |||
| 5969 | if (f) | 6026 | if (f) |
| 5970 | { | 6027 | { |
| 5971 | /* Is this in the tab-bar? */ | 6028 | /* Is this in the tab-bar? */ |
| @@ -5984,10 +6041,7 @@ button_event (GtkWidget *widget, GdkEvent *event, | |||
| 5984 | (f, x, y, event->type == GDK_BUTTON_PRESS, | 6041 | (f, x, y, event->type == GDK_BUTTON_PRESS, |
| 5985 | pgtk_gtk_to_emacs_modifiers (dpyinfo, event->button.state)); | 6042 | pgtk_gtk_to_emacs_modifiers (dpyinfo, event->button.state)); |
| 5986 | } | 6043 | } |
| 5987 | } | ||
| 5988 | 6044 | ||
| 5989 | if (f) | ||
| 5990 | { | ||
| 5991 | if (!(tab_bar_p && NILP (tab_bar_arg)) && !tool_bar_p) | 6045 | if (!(tab_bar_p && NILP (tab_bar_arg)) && !tool_bar_p) |
| 5992 | { | 6046 | { |
| 5993 | if (ignore_next_mouse_click_timeout) | 6047 | if (ignore_next_mouse_click_timeout) |
| @@ -6055,8 +6109,8 @@ scroll_event (GtkWidget *widget, GdkEvent *event, gpointer *user_data) | |||
| 6055 | 6109 | ||
| 6056 | inev.ie.kind = NO_EVENT; | 6110 | inev.ie.kind = NO_EVENT; |
| 6057 | inev.ie.timestamp = event->scroll.time; | 6111 | inev.ie.timestamp = event->scroll.time; |
| 6058 | inev.ie.modifiers = | 6112 | inev.ie.modifiers |
| 6059 | pgtk_gtk_to_emacs_modifiers (FRAME_DISPLAY_INFO (f), event->scroll.state); | 6113 | = pgtk_gtk_to_emacs_modifiers (FRAME_DISPLAY_INFO (f), event->scroll.state); |
| 6060 | XSETINT (inev.ie.x, event->scroll.x); | 6114 | XSETINT (inev.ie.x, event->scroll.x); |
| 6061 | XSETINT (inev.ie.y, event->scroll.y); | 6115 | XSETINT (inev.ie.y, event->scroll.y); |
| 6062 | XSETFRAME (inev.ie.frame_or_window, f); | 6116 | XSETFRAME (inev.ie.frame_or_window, f); |
| @@ -6594,6 +6648,44 @@ pgtk_selection_event (GtkWidget *widget, GdkEvent *event, | |||
| 6594 | return FALSE; | 6648 | return FALSE; |
| 6595 | } | 6649 | } |
| 6596 | 6650 | ||
| 6651 | /* Display a warning message if the PGTK port is being used under X; | ||
| 6652 | that is not supported. */ | ||
| 6653 | |||
| 6654 | static void | ||
| 6655 | pgtk_display_x_warning (GdkDisplay *display) | ||
| 6656 | { | ||
| 6657 | GtkWidget *dialog_widget, *label, *content_area; | ||
| 6658 | GtkDialog *dialog; | ||
| 6659 | GtkWindow *window; | ||
| 6660 | GdkScreen *screen; | ||
| 6661 | |||
| 6662 | /* Do this instead of GDK_IS_X11_DISPLAY because the GDK X header | ||
| 6663 | pulls in Xlib, which conflicts with definitions in pgtkgui.h. */ | ||
| 6664 | if (strcmp (G_OBJECT_TYPE_NAME (display), | ||
| 6665 | "GdkX11Display")) | ||
| 6666 | return; | ||
| 6667 | |||
| 6668 | dialog_widget = gtk_dialog_new (); | ||
| 6669 | dialog = GTK_DIALOG (dialog_widget); | ||
| 6670 | window = GTK_WINDOW (dialog_widget); | ||
| 6671 | screen = gdk_display_get_default_screen (display); | ||
| 6672 | content_area = gtk_dialog_get_content_area (dialog); | ||
| 6673 | |||
| 6674 | gtk_window_set_title (window, "Warning"); | ||
| 6675 | gtk_window_set_screen (window, screen); | ||
| 6676 | |||
| 6677 | label = gtk_label_new ("You are trying to run Emacs configured with" | ||
| 6678 | " the \"pure-GTK\" interface under the X Window" | ||
| 6679 | " System. That configuration is unsupported and" | ||
| 6680 | " will lead to sporadic crashes during transfer of" | ||
| 6681 | " large selection data. It will also lead to" | ||
| 6682 | " various problems with keyboard input."); | ||
| 6683 | gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); | ||
| 6684 | gtk_container_add (GTK_CONTAINER (content_area), label); | ||
| 6685 | gtk_widget_show (label); | ||
| 6686 | gtk_widget_show (dialog_widget); | ||
| 6687 | } | ||
| 6688 | |||
| 6597 | /* Open a connection to X display DISPLAY_NAME, and return | 6689 | /* Open a connection to X display DISPLAY_NAME, and return |
| 6598 | the structure that describes the open display. | 6690 | the structure that describes the open display. |
| 6599 | If we cannot contact the display, return null. */ | 6691 | If we cannot contact the display, return null. */ |
| @@ -6697,6 +6789,9 @@ pgtk_term_init (Lisp_Object display_name, char *resource_name) | |||
| 6697 | return 0; | 6789 | return 0; |
| 6698 | } | 6790 | } |
| 6699 | 6791 | ||
| 6792 | /* If the PGTK port is being used under X, complain very loudly, as | ||
| 6793 | that isn't supported. */ | ||
| 6794 | pgtk_display_x_warning (dpy); | ||
| 6700 | 6795 | ||
| 6701 | dpyinfo = xzalloc (sizeof *dpyinfo); | 6796 | dpyinfo = xzalloc (sizeof *dpyinfo); |
| 6702 | pgtk_initialize_display_info (dpyinfo); | 6797 | pgtk_initialize_display_info (dpyinfo); |
| @@ -6940,10 +7035,9 @@ pgtk_parse_color (struct frame *f, const char *color_name, | |||
| 6940 | color->red = rgba.red * 65535; | 7035 | color->red = rgba.red * 65535; |
| 6941 | color->green = rgba.green * 65535; | 7036 | color->green = rgba.green * 65535; |
| 6942 | color->blue = rgba.blue * 65535; | 7037 | color->blue = rgba.blue * 65535; |
| 6943 | color->pixel = | 7038 | color->pixel = ((color->red >> 8) << 16 |
| 6944 | (color->red >> 8) << 16 | | 7039 | | (color->green >> 8) << 8 |
| 6945 | (color->green >> 8) << 8 | | 7040 | | (color->blue >> 8) << 0); |
| 6946 | (color->blue >> 8) << 0; | ||
| 6947 | return 1; | 7041 | return 1; |
| 6948 | } | 7042 | } |
| 6949 | return 0; | 7043 | return 0; |
| @@ -7072,10 +7166,9 @@ If set to a non-float value, there will be no wait at all. */); | |||
| 7072 | Vpgtk_wait_for_event_timeout = make_float (0.1); | 7166 | Vpgtk_wait_for_event_timeout = make_float (0.1); |
| 7073 | 7167 | ||
| 7074 | DEFVAR_LISP ("pgtk-keysym-table", Vpgtk_keysym_table, | 7168 | DEFVAR_LISP ("pgtk-keysym-table", Vpgtk_keysym_table, |
| 7075 | doc: /* Hash table of character codes indexed by X keysym codes. */); | 7169 | doc: /* Hash table of character codes indexed by X keysym codes. */); |
| 7076 | Vpgtk_keysym_table = | 7170 | Vpgtk_keysym_table = make_hash_table (hashtest_eql, 900, DEFAULT_REHASH_SIZE, |
| 7077 | make_hash_table (hashtest_eql, 900, DEFAULT_REHASH_SIZE, | 7171 | DEFAULT_REHASH_THRESHOLD, Qnil, false); |
| 7078 | DEFAULT_REHASH_THRESHOLD, Qnil, false); | ||
| 7079 | 7172 | ||
| 7080 | window_being_scrolled = Qnil; | 7173 | window_being_scrolled = Qnil; |
| 7081 | staticpro (&window_being_scrolled); | 7174 | staticpro (&window_being_scrolled); |
| @@ -7113,13 +7206,13 @@ pgtk_begin_cr_clip (struct frame *f) | |||
| 7113 | 7206 | ||
| 7114 | if (!cr) | 7207 | if (!cr) |
| 7115 | { | 7208 | { |
| 7116 | cairo_surface_t *surface = | 7209 | cairo_surface_t *surface |
| 7117 | gdk_window_create_similar_surface (gtk_widget_get_window | 7210 | = gdk_window_create_similar_surface (gtk_widget_get_window |
| 7118 | (FRAME_GTK_WIDGET (f)), | 7211 | (FRAME_GTK_WIDGET (f)), |
| 7119 | CAIRO_CONTENT_COLOR_ALPHA, | 7212 | CAIRO_CONTENT_COLOR_ALPHA, |
| 7120 | FRAME_CR_SURFACE_DESIRED_WIDTH (f), | 7213 | FRAME_CR_SURFACE_DESIRED_WIDTH (f), |
| 7121 | FRAME_CR_SURFACE_DESIRED_HEIGHT | 7214 | FRAME_CR_SURFACE_DESIRED_HEIGHT |
| 7122 | (f)); | 7215 | (f)); |
| 7123 | 7216 | ||
| 7124 | cr = FRAME_CR_CONTEXT (f) = cairo_create (surface); | 7217 | cr = FRAME_CR_CONTEXT (f) = cairo_create (surface); |
| 7125 | cairo_surface_destroy (surface); | 7218 | cairo_surface_destroy (surface); |