aboutsummaryrefslogtreecommitdiffstats
path: root/src/pgtkterm.c
diff options
context:
space:
mode:
authorYuuki Harano2020-09-06 23:27:45 +0900
committerJeff Walsh2020-11-24 12:24:40 +1100
commit28073ba59bbabec1194977d654b471800ce63f45 (patch)
tree967c439b8f95894da3e573b0897d28b3b4d6c6d2 /src/pgtkterm.c
parente75ce0302d4c907c8ff56fb15fc7dd12b48e7370 (diff)
downloademacs-28073ba59bbabec1194977d654b471800ce63f45.tar.gz
emacs-28073ba59bbabec1194977d654b471800ce63f45.zip
Re-implement childframe with emacsgtkfixed
* src/emacsgtkfixed.c (G_DEFINE_TYPE): Make emacs_fixed_get_type public. * src/emacsgtkfixed.h (EMACS_TYPE_FIXED): Make emacs_fixed_get_type public. * src/gtkutil.c (xg_frame_set_char_size): Call appropriate functions by whether the frame is a child frame or not. (xg_create_frame_widgets): Use GTK_WINDOW_TOPLEVEL when creating child frame. (xg_create_frame_outer_widgets): New function. (xg_set_skip_taskbar): Call only when top-level frame. (xg_set_no_accept_focus): See appropriate widget. * src/gtkutil.h: New declaration. * src/pgtkfns.c (pgtk_set_name_internal): Do only when top-level frame. (Fx_create_frame): Reparent the frame. (frame_geometry): Call appropriate functions (syms_of_pgtkfns): Port from X code. * src/pgtkterm.c (x_free_frame_resources): Destroy appropriate widget. (x_calc_absolute_position): Port from X code. (x_set_offset): Re-port from X code. (pgtk_set_window_size): Use appropriate widget. (pgtk_make_frame_visible): Use appropriate widget. (pgtk_make_frame_invisible): Use appropriate widget. (x_set_parent_frame): Reparent the frame. (x_set_z_group): Process only when top-level frame. (pgtk_text_icon): Process only when top-level frame. (set_fullscreen_state): Process only when top-level frame. (frame_highlight): Hold ref. (frame_unhighlight): Hold ref. (pgtk_window_is_of_frame_recursive): Prune child frames. (pgtk_window_is_of_frame): Prune child frames. (print_widget_tree_recursive): Don't call this when not debugging. (pgtk_handle_draw): Don't call this when not debugging. (pgtk_set_event_handler): expect map-event for edit_widget not outer widget. * src/pgtkterm.h (FRAME_WIDGET): New macro.
Diffstat (limited to 'src/pgtkterm.c')
-rw-r--r--src/pgtkterm.c307
1 files changed, 242 insertions, 65 deletions
diff --git a/src/pgtkterm.c b/src/pgtkterm.c
index 6d8b1ece877..d62e2a3b16d 100644
--- a/src/pgtkterm.c
+++ b/src/pgtkterm.c
@@ -60,6 +60,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
60#include "font.h" 60#include "font.h"
61#include "xsettings.h" 61#include "xsettings.h"
62#include "pgtkselect.h" 62#include "pgtkselect.h"
63#include "emacsgtkfixed.h"
63 64
64#define STORE_KEYSYM_FOR_DEBUG(keysym) ((void)0) 65#define STORE_KEYSYM_FOR_DEBUG(keysym) ((void)0)
65 66
@@ -227,10 +228,10 @@ x_free_frame_resources (struct frame *f)
227 228
228 if (FRAME_X_OUTPUT (f)->border_color_css_provider != NULL) 229 if (FRAME_X_OUTPUT (f)->border_color_css_provider != NULL)
229 { 230 {
230 GtkStyleContext *ctxt = 231 GtkStyleContext *ctxt = gtk_widget_get_style_context (FRAME_WIDGET (f));
231 gtk_widget_get_style_context (FRAME_GTK_OUTER_WIDGET (f));
232 GtkCssProvider *old = FRAME_X_OUTPUT (f)->border_color_css_provider; 232 GtkCssProvider *old = FRAME_X_OUTPUT (f)->border_color_css_provider;
233 gtk_style_context_remove_provider (ctxt, GTK_STYLE_PROVIDER (old)); 233 gtk_style_context_remove_provider (ctxt, GTK_STYLE_PROVIDER (old));
234 g_object_unref (old);
234 FRAME_X_OUTPUT (f)->border_color_css_provider = NULL; 235 FRAME_X_OUTPUT (f)->border_color_css_provider = NULL;
235 } 236 }
236 237
@@ -250,7 +251,7 @@ x_free_frame_resources (struct frame *f)
250 FRAME_X_OUTPUT (f)->scrollbar_background_css_provider = NULL; 251 FRAME_X_OUTPUT (f)->scrollbar_background_css_provider = NULL;
251 } 252 }
252 253
253 gtk_widget_destroy (FRAME_GTK_OUTER_WIDGET (f)); 254 gtk_widget_destroy (FRAME_WIDGET (f));
254 255
255 if (FRAME_X_OUTPUT (f)->cr_surface_visible_bell != NULL) 256 if (FRAME_X_OUTPUT (f)->cr_surface_visible_bell != NULL)
256 { 257 {
@@ -286,6 +287,80 @@ x_destroy_window (struct frame *f)
286 dpyinfo->reference_count--; 287 dpyinfo->reference_count--;
287} 288}
288 289
290/* Calculate the absolute position in frame F
291 from its current recorded position values and gravity. */
292
293static void
294x_calc_absolute_position (struct frame *f)
295{
296 int flags = f->size_hint_flags;
297 struct frame *p = FRAME_PARENT_FRAME (f);
298
299 /* We have nothing to do if the current position
300 is already for the top-left corner. */
301 if (! ((flags & XNegative) || (flags & YNegative)))
302 return;
303
304 /* Treat negative positions as relative to the leftmost bottommost
305 position that fits on the screen. */
306 if ((flags & XNegative) && (f->left_pos <= 0))
307 {
308 int width = FRAME_PIXEL_WIDTH (f);
309
310 /* A frame that has been visible at least once should have outer
311 edges. */
312 if (f->output_data.pgtk->has_been_visible && !p)
313 {
314 Lisp_Object frame;
315 Lisp_Object edges = Qnil;
316
317 XSETFRAME (frame, f);
318 edges = Fpgtk_frame_edges (frame, Qouter_edges);
319 if (!NILP (edges))
320 width = (XFIXNUM (Fnth (make_fixnum (2), edges))
321 - XFIXNUM (Fnth (make_fixnum (0), edges)));
322 }
323
324 if (p)
325 f->left_pos = (FRAME_PIXEL_WIDTH (p) - width - 2 * f->border_width
326 + f->left_pos);
327 else
328 f->left_pos = (x_display_pixel_width (FRAME_DISPLAY_INFO (f))
329 - width + f->left_pos);
330
331 }
332
333 if ((flags & YNegative) && (f->top_pos <= 0))
334 {
335 int height = FRAME_PIXEL_HEIGHT (f);
336
337 if (f->output_data.pgtk->has_been_visible && !p)
338 {
339 Lisp_Object frame;
340 Lisp_Object edges = Qnil;
341
342 XSETFRAME (frame, f);
343 if (NILP (edges))
344 edges = Fpgtk_frame_edges (frame, Qouter_edges);
345 if (!NILP (edges))
346 height = (XFIXNUM (Fnth (make_fixnum (3), edges))
347 - XFIXNUM (Fnth (make_fixnum (1), edges)));
348 }
349
350 if (p)
351 f->top_pos = (FRAME_PIXEL_HEIGHT (p) - height - 2 * f->border_width
352 + f->top_pos);
353 else
354 f->top_pos = (x_display_pixel_height (FRAME_DISPLAY_INFO (f))
355 - height + f->top_pos);
356 }
357
358 /* The left_pos and top_pos
359 are now relative to the top and left screen edges,
360 so the flags should correspond. */
361 f->size_hint_flags &= ~ (XNegative | YNegative);
362}
363
289/* CHANGE_GRAVITY is 1 when calling from Fset_frame_position, 364/* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
290 to really change the position, and 0 when calling from 365 to really change the position, and 0 when calling from
291 x_make_frame_visible (in that case, XOFF and YOFF are the current 366 x_make_frame_visible (in that case, XOFF and YOFF are the current
@@ -300,48 +375,60 @@ x_set_offset (struct frame *f, int xoff, int yoff, int change_gravity)
300{ 375{
301 PGTK_TRACE ("x_set_offset: %d,%d,%d.", xoff, yoff, change_gravity); 376 PGTK_TRACE ("x_set_offset: %d,%d,%d.", xoff, yoff, change_gravity);
302 377
303 struct frame *parent = FRAME_PARENT_FRAME (f); 378 int modified_top, modified_left;
304 GtkAllocation a = { 0 };
305 int surface_pos_x = 0;
306 int surface_pos_y = 0;
307
308 if (parent)
309 {
310 /* determing the "height" of the titlebar, by finding the
311 location of the "emacsfixed" widget on the surface/window */
312 GtkWidget *w = FRAME_GTK_WIDGET (parent);
313 gtk_widget_get_allocation (w, &a);
314 }
315 379
316 if (change_gravity > 0) 380 if (change_gravity > 0)
317 { 381 {
318 f->size_hint_flags &= ~(XNegative | YNegative);
319 f->left_pos = xoff;
320 f->top_pos = yoff; 382 f->top_pos = yoff;
321 383 f->left_pos = xoff;
384 f->size_hint_flags &= ~ (XNegative | YNegative);
322 if (xoff < 0) 385 if (xoff < 0)
323 { 386 f->size_hint_flags |= XNegative;
324 f->size_hint_flags |= XNegative;
325 }
326 if (yoff < 0) 387 if (yoff < 0)
327 { 388 f->size_hint_flags |= YNegative;
328 f->size_hint_flags |= YNegative;
329 }
330 f->win_gravity = NorthWestGravity; 389 f->win_gravity = NorthWestGravity;
331 } 390 }
332 391
392 x_calc_absolute_position (f);
393
333 block_input (); 394 block_input ();
334 surface_pos_y = f->top_pos + a.y; 395 x_wm_set_size_hint (f, 0, false);
335 surface_pos_x = f->left_pos + a.x;
336 396
337 /* When a position change was requested and the outer GTK widget 397 if (x_gtk_use_window_move)
338 has been realized already, leave it to gtk_window_move to DTRT 398 {
339 and return. Used for Bug#25851 and Bug#25943. */ 399 if (change_gravity != 0)
340 if (change_gravity != 0 && FRAME_GTK_OUTER_WIDGET (f)) 400 {
401 if (FRAME_GTK_OUTER_WIDGET (f))
402 {
403 gtk_window_move (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
404 f->left_pos, f->top_pos);
405 }
406 else
407 {
408 GtkWidget *fixed = FRAME_GTK_WIDGET (f);
409 GtkWidget *parent = gtk_widget_get_parent (fixed);
410 gtk_fixed_move (GTK_FIXED (parent), fixed,
411 f->left_pos, f->top_pos);
412 }
413 }
414 unblock_input ();
415 return;
416 }
417
418 modified_left = f->left_pos;
419 modified_top = f->top_pos;
420
421 if (FRAME_GTK_OUTER_WIDGET (f))
341 { 422 {
342 PGTK_TRACE ("x_set_offset: move to %d,%d.", surface_pos_x, surface_pos_y);
343 gtk_window_move (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), 423 gtk_window_move (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
344 surface_pos_x, surface_pos_y); 424 modified_left, modified_top);
425 }
426 else
427 {
428 GtkWidget *fixed = FRAME_GTK_WIDGET (f);
429 GtkWidget *parent = gtk_widget_get_parent (fixed);
430 gtk_fixed_move (GTK_FIXED (parent), fixed,
431 modified_left, modified_top);
345 } 432 }
346 433
347 unblock_input (); 434 unblock_input ();
@@ -397,7 +484,7 @@ pgtk_set_window_size (struct frame *f,
397 x_wm_set_size_hint (f, 0, 0); 484 x_wm_set_size_hint (f, 0, 0);
398 xg_frame_set_char_size (f, FRAME_PIXEL_TO_TEXT_WIDTH (f, pixelwidth), 485 xg_frame_set_char_size (f, FRAME_PIXEL_TO_TEXT_WIDTH (f, pixelwidth),
399 FRAME_PIXEL_TO_TEXT_HEIGHT (f, pixelheight)); 486 FRAME_PIXEL_TO_TEXT_HEIGHT (f, pixelheight));
400 gtk_widget_queue_resize (FRAME_GTK_OUTER_WIDGET (f)); 487 gtk_widget_queue_resize (FRAME_WIDGET (f));
401 488
402 unblock_input (); 489 unblock_input ();
403} 490}
@@ -488,8 +575,9 @@ pgtk_make_frame_visible (struct frame *f)
488 575
489 if (!FRAME_VISIBLE_P (f)) 576 if (!FRAME_VISIBLE_P (f))
490 { 577 {
491 gtk_widget_show (win); 578 gtk_widget_show (FRAME_WIDGET (f));
492 gtk_window_deiconify (GTK_WINDOW (win)); 579 if (win)
580 gtk_window_deiconify (GTK_WINDOW (win));
493 581
494 if (FLOATP (Vpgtk_wait_for_event_timeout)) 582 if (FLOATP (Vpgtk_wait_for_event_timeout))
495 { 583 {
@@ -498,7 +586,7 @@ pgtk_make_frame_visible (struct frame *f)
498 int found = 0; 586 int found = 0;
499 int timed_out = 0; 587 int timed_out = 0;
500 gulong id = 588 gulong id =
501 g_signal_connect (win, "map-event", 589 g_signal_connect (FRAME_WIDGET (f), "map-event",
502 G_CALLBACK 590 G_CALLBACK
503 (pgtk_make_frame_visible_wait_for_map_event_cb), 591 (pgtk_make_frame_visible_wait_for_map_event_cb),
504 &found); 592 &found);
@@ -508,7 +596,7 @@ pgtk_make_frame_visible (struct frame *f)
508 &timed_out); 596 &timed_out);
509 while (!found && !timed_out) 597 while (!found && !timed_out)
510 gtk_main_iteration (); 598 gtk_main_iteration ();
511 g_signal_handler_disconnect (win, id); 599 g_signal_handler_disconnect (FRAME_WIDGET (f), id);
512 if (!timed_out) 600 if (!timed_out)
513 g_source_remove (src); 601 g_source_remove (src);
514 } 602 }
@@ -524,9 +612,7 @@ pgtk_make_frame_invisible (struct frame *f)
524{ 612{
525 PGTK_TRACE ("pgtk_make_frame_invisible"); 613 PGTK_TRACE ("pgtk_make_frame_invisible");
526 614
527 GtkWidget *win = FRAME_OUTPUT_DATA (f)->widget; 615 gtk_widget_hide (FRAME_WIDGET (f));
528
529 gtk_widget_hide (win);
530 616
531 SET_FRAME_VISIBLE (f, 0); 617 SET_FRAME_VISIBLE (f, 0);
532 SET_FRAME_ICONIFIED (f, false); 618 SET_FRAME_ICONIFIED (f, false);
@@ -668,25 +754,89 @@ x_set_parent_frame (struct frame *f, Lisp_Object new_value,
668 -------------------------------------------------------------------------- */ 754 -------------------------------------------------------------------------- */
669{ 755{
670 struct frame *p = NULL; 756 struct frame *p = NULL;
671 PGTK_TRACE ("x_set_parent_frame x: %d, y: %d", f->left_pos, f->top_pos);
672 757
673 if (!NILP (new_value) 758 if (!NILP (new_value)
674 && (!FRAMEP (new_value) 759 && (!FRAMEP (new_value)
675 || !FRAME_LIVE_P (p = XFRAME (new_value)) || !FRAME_PGTK_P (p))) 760 || !FRAME_LIVE_P (p = XFRAME (new_value))
761 || !FRAME_PGTK_P (p)))
676 { 762 {
677 store_frame_param (f, Qparent_frame, old_value); 763 store_frame_param (f, Qparent_frame, old_value);
678 error ("Invalid specification of `parent-frame'"); 764 error ("Invalid specification of `parent-frame'");
679 } 765 }
680 766
681 if (p != FRAME_PARENT_FRAME (f) && (p != NULL)) 767 if (p != FRAME_PARENT_FRAME (f))
682 { 768 {
683 block_input (); 769 block_input ();
684 gtk_window_set_transient_for (FRAME_NATIVE_WINDOW (f), 770
685 FRAME_NATIVE_WINDOW (p)); 771 if (p != NULL)
686 gtk_window_set_attached_to (FRAME_NATIVE_WINDOW (f), 772 {
687 FRAME_GTK_WIDGET (p)); 773 if (FRAME_DISPLAY_INFO (f) != FRAME_DISPLAY_INFO (p))
688 gtk_window_move (FRAME_NATIVE_WINDOW (f), f->left_pos, f->top_pos); 774 error ("Cross display reparent.");
689 gtk_window_set_keep_above (FRAME_NATIVE_WINDOW (f), true); 775 }
776
777 GtkWidget *fixed = FRAME_GTK_WIDGET (f);
778
779 GtkAllocation alloc;
780 gtk_widget_get_allocation(fixed, &alloc);
781 g_object_ref (fixed);
782
783 GtkCssProvider *provider = FRAME_X_OUTPUT (f)->border_color_css_provider;
784
785 {
786 GtkWidget *whbox_of_f = gtk_widget_get_parent (fixed);
787 gtk_container_remove (GTK_CONTAINER (whbox_of_f), fixed);
788
789 GtkStyleContext *ctxt = gtk_widget_get_style_context (FRAME_WIDGET (f));
790 gtk_style_context_remove_provider (ctxt, GTK_STYLE_PROVIDER (provider));
791
792 if (FRAME_GTK_OUTER_WIDGET (f))
793 {
794 gtk_widget_destroy (FRAME_GTK_OUTER_WIDGET (f));
795 FRAME_GTK_OUTER_WIDGET (f) = NULL;
796 FRAME_OUTPUT_DATA (f)->vbox_widget = NULL;
797 FRAME_OUTPUT_DATA (f)->hbox_widget = NULL;
798 FRAME_OUTPUT_DATA (f)->menubar_widget = NULL;
799 FRAME_OUTPUT_DATA (f)->toolbar_widget = NULL;
800 FRAME_OUTPUT_DATA (f)->ttip_widget = NULL;
801 FRAME_OUTPUT_DATA (f)->ttip_lbl = NULL;
802 FRAME_OUTPUT_DATA (f)->ttip_window = NULL;
803 }
804 }
805
806 if (p == NULL)
807 {
808 xg_create_frame_outer_widgets (f);
809 pgtk_set_event_handler (f);
810 gtk_box_pack_start (GTK_BOX (f->output_data.pgtk->hbox_widget), fixed, TRUE, TRUE, 0);
811 f->output_data.pgtk->preferred_width = alloc.width;
812 f->output_data.pgtk->preferred_height = alloc.height;
813 x_wm_set_size_hint (f, 0, 0);
814 xg_frame_set_char_size (f, FRAME_PIXEL_TO_TEXT_WIDTH (f, alloc.width),
815 FRAME_PIXEL_TO_TEXT_HEIGHT (f, alloc.height));
816 gtk_widget_queue_resize (FRAME_WIDGET (f));
817 gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f));
818 }
819 else
820 {
821 GtkWidget *fixed_of_p = FRAME_GTK_WIDGET (p);
822 gtk_fixed_put (GTK_FIXED (fixed_of_p), fixed, f->left_pos, f->top_pos);
823 gtk_widget_set_size_request (fixed, alloc.width, alloc.height);
824 gtk_widget_show_all (fixed);
825 }
826
827 GtkStyleContext *ctxt = gtk_widget_get_style_context (FRAME_WIDGET (f));
828 gtk_style_context_add_provider (ctxt, GTK_STYLE_PROVIDER (provider),
829 GTK_STYLE_PROVIDER_PRIORITY_USER);
830
831 g_object_unref (fixed);
832
833 if (FRAME_GTK_OUTER_WIDGET (f)) {
834 if (EQ (x_gtk_resize_child_frames, Qresize_mode))
835 gtk_container_set_resize_mode
836 (GTK_CONTAINER (FRAME_GTK_OUTER_WIDGET (f)),
837 p ? GTK_RESIZE_IMMEDIATE : GTK_RESIZE_QUEUE);
838 }
839
690 unblock_input (); 840 unblock_input ();
691 841
692 fset_parent_frame (f, new_value); 842 fset_parent_frame (f, new_value);
@@ -748,6 +898,9 @@ x_set_z_group (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
748 /* doesn't work on wayland. */ 898 /* doesn't work on wayland. */
749 PGTK_TRACE ("x_set_z_group"); 899 PGTK_TRACE ("x_set_z_group");
750 900
901 if (!FRAME_GTK_OUTER_WIDGET (f))
902 return;
903
751 if (NILP (new_value)) 904 if (NILP (new_value))
752 { 905 {
753 gtk_window_set_keep_above (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), 906 gtk_window_set_keep_above (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
@@ -2900,8 +3053,10 @@ pgtk_bitmap_icon (struct frame *f, Lisp_Object file)
2900bool 3053bool
2901pgtk_text_icon (struct frame *f, const char *icon_name) 3054pgtk_text_icon (struct frame *f, const char *icon_name)
2902{ 3055{
2903 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), NULL); 3056 if (FRAME_GTK_OUTER_WIDGET (f)) {
2904 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), icon_name); 3057 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), NULL);
3058 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), icon_name);
3059 }
2905 3060
2906 return false; 3061 return false;
2907} 3062}
@@ -4392,6 +4547,9 @@ pgtk_judge_scroll_bars (struct frame *f)
4392static void 4547static void
4393set_fullscreen_state (struct frame *f) 4548set_fullscreen_state (struct frame *f)
4394{ 4549{
4550 if (!FRAME_GTK_OUTER_WIDGET (f))
4551 return;
4552
4395 GtkWindow *widget = GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)); 4553 GtkWindow *widget = GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f));
4396 switch (f->want_fullscreen) 4554 switch (f->want_fullscreen)
4397 { 4555 {
@@ -4571,24 +4729,27 @@ frame_highlight (struct frame *f)
4571 using that same window-manager binary for ever. Let's not crash just 4729 using that same window-manager binary for ever. Let's not crash just
4572 because of this (bug#9310). */ 4730 because of this (bug#9310). */
4573 4731
4732 GtkWidget *w = FRAME_WIDGET (f);
4733
4574 char *css = 4734 char *css =
4575 g_strdup_printf ("decoration { border: solid %dpx #%06x; }", 4735 g_strdup_printf ("decoration { border: solid %dpx #%06x; }",
4576 f->border_width, 4736 f->border_width,
4577 (unsigned int) FRAME_X_OUTPUT (f)-> 4737 (unsigned int) FRAME_X_OUTPUT (f)->border_pixel & 0x00ffffff);
4578 border_pixel & 0x00ffffff); 4738
4579 GtkStyleContext *ctxt = 4739 GtkStyleContext *ctxt = gtk_widget_get_style_context (w);
4580 gtk_widget_get_style_context (FRAME_GTK_OUTER_WIDGET (f));
4581 GtkCssProvider *css_provider = gtk_css_provider_new (); 4740 GtkCssProvider *css_provider = gtk_css_provider_new ();
4582 gtk_css_provider_load_from_data (css_provider, css, -1, NULL); 4741 gtk_css_provider_load_from_data (css_provider, css, -1, NULL);
4583 gtk_style_context_add_provider (ctxt, GTK_STYLE_PROVIDER (css_provider), 4742 gtk_style_context_add_provider (ctxt, GTK_STYLE_PROVIDER (css_provider),
4584 GTK_STYLE_PROVIDER_PRIORITY_USER); 4743 GTK_STYLE_PROVIDER_PRIORITY_USER);
4585 g_object_unref (css_provider);
4586 g_free (css); 4744 g_free (css);
4587 4745
4588 GtkCssProvider *old = FRAME_X_OUTPUT (f)->border_color_css_provider; 4746 GtkCssProvider *old = FRAME_X_OUTPUT (f)->border_color_css_provider;
4589 FRAME_X_OUTPUT (f)->border_color_css_provider = css_provider; 4747 FRAME_X_OUTPUT (f)->border_color_css_provider = css_provider;
4590 if (old != NULL) 4748 if (old != NULL)
4591 gtk_style_context_remove_provider (ctxt, GTK_STYLE_PROVIDER (old)); 4749 {
4750 gtk_style_context_remove_provider (ctxt, GTK_STYLE_PROVIDER (old));
4751 g_object_unref (old);
4752 }
4592 4753
4593 unblock_input (); 4754 unblock_input ();
4594 gui_update_cursor (f, true); 4755 gui_update_cursor (f, true);
@@ -4605,22 +4766,26 @@ frame_unhighlight (struct frame *f)
4605 block_input (); 4766 block_input ();
4606 /* Same as above for XSetWindowBorder (bug#9310). */ 4767 /* Same as above for XSetWindowBorder (bug#9310). */
4607 4768
4769 GtkWidget *w = FRAME_WIDGET (f);
4770
4608 char *css = 4771 char *css =
4609 g_strdup_printf ("decoration { border: dotted %dpx #ffffff; }", 4772 g_strdup_printf ("decoration { border: dotted %dpx #ffffff; }",
4610 f->border_width); 4773 f->border_width);
4611 GtkStyleContext *ctxt = 4774
4612 gtk_widget_get_style_context (FRAME_GTK_OUTER_WIDGET (f)); 4775 GtkStyleContext *ctxt = gtk_widget_get_style_context (w);
4613 GtkCssProvider *css_provider = gtk_css_provider_new (); 4776 GtkCssProvider *css_provider = gtk_css_provider_new ();
4614 gtk_css_provider_load_from_data (css_provider, css, -1, NULL); 4777 gtk_css_provider_load_from_data (css_provider, css, -1, NULL);
4615 gtk_style_context_add_provider (ctxt, GTK_STYLE_PROVIDER (css_provider), 4778 gtk_style_context_add_provider (ctxt, GTK_STYLE_PROVIDER (css_provider),
4616 GTK_STYLE_PROVIDER_PRIORITY_USER); 4779 GTK_STYLE_PROVIDER_PRIORITY_USER);
4617 g_object_unref (css_provider);
4618 g_free (css); 4780 g_free (css);
4619 4781
4620 GtkCssProvider *old = FRAME_X_OUTPUT (f)->border_color_css_provider; 4782 GtkCssProvider *old = FRAME_X_OUTPUT (f)->border_color_css_provider;
4621 FRAME_X_OUTPUT (f)->border_color_css_provider = css_provider; 4783 FRAME_X_OUTPUT (f)->border_color_css_provider = css_provider;
4622 if (old != NULL) 4784 if (old != NULL)
4623 gtk_style_context_remove_provider (ctxt, GTK_STYLE_PROVIDER (old)); 4785 {
4786 gtk_style_context_remove_provider (ctxt, GTK_STYLE_PROVIDER (old));
4787 g_object_unref (old);
4788 }
4624 4789
4625 unblock_input (); 4790 unblock_input ();
4626 gui_update_cursor (f, true); 4791 gui_update_cursor (f, true);
@@ -4793,6 +4958,7 @@ struct pgtk_window_is_of_frame_recursive_t
4793{ 4958{
4794 GdkWindow *window; 4959 GdkWindow *window;
4795 bool result; 4960 bool result;
4961 GtkWidget *emacs_gtk_fixed; // stop on emacsgtkfixed other than this.
4796}; 4962};
4797 4963
4798static void 4964static void
@@ -4803,15 +4969,19 @@ pgtk_window_is_of_frame_recursive (GtkWidget * widget, gpointer data)
4803 if (datap->result) 4969 if (datap->result)
4804 return; 4970 return;
4805 4971
4972 if (EMACS_IS_FIXED (widget) && widget != datap->emacs_gtk_fixed)
4973 return;
4974
4806 if (gtk_widget_get_window (widget) == datap->window) 4975 if (gtk_widget_get_window (widget) == datap->window)
4807 { 4976 {
4808 datap->result = true; 4977 datap->result = true;
4809 return; 4978 return;
4810 } 4979 }
4811 4980
4812 if (GTK_IS_CONTAINER (widget)) 4981 if (GTK_IS_CONTAINER (widget)) {
4813 gtk_container_foreach (GTK_CONTAINER (widget), 4982 gtk_container_foreach (GTK_CONTAINER (widget),
4814 pgtk_window_is_of_frame_recursive, datap); 4983 pgtk_window_is_of_frame_recursive, datap);
4984 }
4815} 4985}
4816 4986
4817static bool 4987static bool
@@ -4820,7 +4990,8 @@ pgtk_window_is_of_frame (struct frame *f, GdkWindow * window)
4820 struct pgtk_window_is_of_frame_recursive_t data; 4990 struct pgtk_window_is_of_frame_recursive_t data;
4821 data.window = window; 4991 data.window = window;
4822 data.result = false; 4992 data.result = false;
4823 pgtk_window_is_of_frame_recursive (FRAME_GTK_OUTER_WIDGET (f), &data); 4993 data.emacs_gtk_fixed = FRAME_GTK_WIDGET (f);
4994 pgtk_window_is_of_frame_recursive (FRAME_WIDGET (f), &data);
4824 return data.result; 4995 return data.result;
4825} 4996}
4826 4997
@@ -5068,6 +5239,8 @@ pgtk_clear_under_internal_border (struct frame *f)
5068 } 5239 }
5069} 5240}
5070 5241
5242#ifdef HAVE_PGTK
5243
5071static void 5244static void
5072print_widget_tree_recursive (GtkWidget * w, gpointer user_data) 5245print_widget_tree_recursive (GtkWidget * w, gpointer user_data)
5073{ 5246{
@@ -5108,6 +5281,8 @@ print_widget_tree (GtkWidget * w)
5108 print_widget_tree_recursive (w, indent); 5281 print_widget_tree_recursive (w, indent);
5109} 5282}
5110 5283
5284#endif
5285
5111static gboolean 5286static gboolean
5112pgtk_handle_draw (GtkWidget * widget, cairo_t * cr, gpointer * data) 5287pgtk_handle_draw (GtkWidget * widget, cairo_t * cr, gpointer * data)
5113{ 5288{
@@ -5115,7 +5290,9 @@ pgtk_handle_draw (GtkWidget * widget, cairo_t * cr, gpointer * data)
5115 5290
5116 PGTK_TRACE ("pgtk_handle_draw"); 5291 PGTK_TRACE ("pgtk_handle_draw");
5117 5292
5293#ifdef HAVE_PGTK
5118 print_widget_tree (widget); 5294 print_widget_tree (widget);
5295#endif
5119 5296
5120 GdkWindow *win = gtk_widget_get_window (widget); 5297 GdkWindow *win = gtk_widget_get_window (widget);
5121 5298
@@ -6385,11 +6562,11 @@ pgtk_set_event_handler (struct frame *f)
6385 NULL); 6562 NULL);
6386 g_signal_connect (G_OBJECT (FRAME_GTK_OUTER_WIDGET (f)), "delete-event", 6563 g_signal_connect (G_OBJECT (FRAME_GTK_OUTER_WIDGET (f)), "delete-event",
6387 G_CALLBACK (delete_event), NULL); 6564 G_CALLBACK (delete_event), NULL);
6388 g_signal_connect (G_OBJECT (FRAME_GTK_OUTER_WIDGET (f)), "map-event",
6389 G_CALLBACK (map_event), NULL);
6390 g_signal_connect (G_OBJECT (FRAME_GTK_OUTER_WIDGET (f)), "event", 6565 g_signal_connect (G_OBJECT (FRAME_GTK_OUTER_WIDGET (f)), "event",
6391 G_CALLBACK (pgtk_handle_event), NULL); 6566 G_CALLBACK (pgtk_handle_event), NULL);
6392 6567
6568 g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "map-event",
6569 G_CALLBACK (map_event), NULL);
6393 g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "size-allocate", 6570 g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "size-allocate",
6394 G_CALLBACK (size_allocate), NULL); 6571 G_CALLBACK (size_allocate), NULL);
6395 g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "key-press-event", 6572 g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "key-press-event",