aboutsummaryrefslogtreecommitdiffstats
path: root/src
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
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')
-rw-r--r--src/emacsgtkfixed.c1
-rw-r--r--src/emacsgtkfixed.h5
-rw-r--r--src/gtkutil.c162
-rw-r--r--src/gtkutil.h3
-rw-r--r--src/pgtkfns.c67
-rw-r--r--src/pgtkterm.c307
-rw-r--r--src/pgtkterm.h3
7 files changed, 465 insertions, 83 deletions
diff --git a/src/emacsgtkfixed.c b/src/emacsgtkfixed.c
index 4128f81cce9..d2a7fcbbc10 100644
--- a/src/emacsgtkfixed.c
+++ b/src/emacsgtkfixed.c
@@ -51,7 +51,6 @@ static void emacs_fixed_get_preferred_width (GtkWidget *widget,
51static void emacs_fixed_get_preferred_height (GtkWidget *widget, 51static void emacs_fixed_get_preferred_height (GtkWidget *widget,
52 gint *minimum, 52 gint *minimum,
53 gint *natural); 53 gint *natural);
54static GType emacs_fixed_get_type (void);
55G_DEFINE_TYPE (EmacsFixed, emacs_fixed, GTK_TYPE_FIXED) 54G_DEFINE_TYPE (EmacsFixed, emacs_fixed, GTK_TYPE_FIXED)
56 55
57static EmacsFixed * 56static EmacsFixed *
diff --git a/src/emacsgtkfixed.h b/src/emacsgtkfixed.h
index b230a4d4d8a..f2fb1f269a2 100644
--- a/src/emacsgtkfixed.h
+++ b/src/emacsgtkfixed.h
@@ -27,6 +27,9 @@ struct frame;
27 27
28G_BEGIN_DECLS 28G_BEGIN_DECLS
29 29
30#define EMACS_TYPE_FIXED (emacs_fixed_get_type ())
31#define EMACS_IS_FIXED(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EMACS_TYPE_FIXED))
32
30struct frame; 33struct frame;
31 34
32typedef struct _EmacsFixedPrivate EmacsFixedPrivate; 35typedef struct _EmacsFixedPrivate EmacsFixedPrivate;
@@ -44,6 +47,8 @@ struct _EmacsFixedClass
44 GtkFixedClass parent_class; 47 GtkFixedClass parent_class;
45}; 48};
46 49
50extern GType emacs_fixed_get_type (void);
51
47extern GtkWidget *emacs_fixed_new (struct frame *f); 52extern GtkWidget *emacs_fixed_new (struct frame *f);
48 53
49G_END_DECLS 54G_END_DECLS
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 3956c581d9d..0f1a51fbbbb 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -1060,8 +1060,20 @@ xg_frame_set_char_size (struct frame *f, int width, int height)
1060 if (FRAME_PIXEL_HEIGHT (f) == 0) 1060 if (FRAME_PIXEL_HEIGHT (f) == 0)
1061 return; 1061 return;
1062 1062
1063#ifndef HAVE_PGTK
1063 gtk_window_get_size (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), 1064 gtk_window_get_size (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
1064 &gwidth, &gheight); 1065 &gwidth, &gheight);
1066#else
1067 if (FRAME_GTK_OUTER_WIDGET (f)) {
1068 gtk_window_get_size (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
1069 &gwidth, &gheight);
1070 } else {
1071 GtkAllocation alloc;
1072 gtk_widget_get_allocation (FRAME_GTK_WIDGET (f), &alloc);
1073 gwidth = alloc.width;
1074 gheight = alloc.height;
1075 }
1076#endif
1065 1077
1066 /* Do this before resize, as we don't know yet if we will be resized. */ 1078 /* Do this before resize, as we don't know yet if we will be resized. */
1067 FRAME_RIF (f)->clear_under_internal_border (f); 1079 FRAME_RIF (f)->clear_under_internal_border (f);
@@ -1101,11 +1113,7 @@ xg_frame_set_char_size (struct frame *f, int width, int height)
1101 else if (FRAME_PARENT_FRAME (f) && FRAME_VISIBLE_P (f)) 1113 else if (FRAME_PARENT_FRAME (f) && FRAME_VISIBLE_P (f))
1102 { 1114 {
1103 was_visible = true; 1115 was_visible = true;
1104#ifndef HAVE_PGTK
1105 hide_child_frame = EQ (x_gtk_resize_child_frames, Qhide); 1116 hide_child_frame = EQ (x_gtk_resize_child_frames, Qhide);
1106#else
1107 hide_child_frame = true;
1108#endif // !HAVE_PGTK
1109 1117
1110 if (totalwidth != gwidth || totalheight != gheight) 1118 if (totalwidth != gwidth || totalheight != gheight)
1111 { 1119 {
@@ -1116,17 +1124,35 @@ xg_frame_set_char_size (struct frame *f, int width, int height)
1116 if (hide_child_frame) 1124 if (hide_child_frame)
1117 { 1125 {
1118 block_input (); 1126 block_input ();
1127#ifndef HAVE_PGTK
1119 gtk_widget_hide (FRAME_GTK_OUTER_WIDGET (f)); 1128 gtk_widget_hide (FRAME_GTK_OUTER_WIDGET (f));
1129#else
1130 gtk_widget_hide (FRAME_WIDGET (f));
1131#endif
1120 unblock_input (); 1132 unblock_input ();
1121 } 1133 }
1122 1134
1135#ifndef HAVE_PGTK
1123 gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), 1136 gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
1124 totalwidth, totalheight); 1137 totalwidth, totalheight);
1138#else
1139 if (FRAME_GTK_OUTER_WIDGET (f)) {
1140 gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
1141 totalwidth, totalheight);
1142 } else {
1143 gtk_widget_set_size_request (FRAME_GTK_WIDGET (f),
1144 totalwidth, totalheight);
1145 }
1146#endif
1125 1147
1126 if (hide_child_frame) 1148 if (hide_child_frame)
1127 { 1149 {
1128 block_input (); 1150 block_input ();
1151#ifndef HAVE_PGTK
1129 gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f)); 1152 gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f));
1153#else
1154 gtk_widget_show_all (FRAME_WIDGET (f));
1155#endif
1130 unblock_input (); 1156 unblock_input ();
1131 } 1157 }
1132 1158
@@ -1138,8 +1164,18 @@ xg_frame_set_char_size (struct frame *f, int width, int height)
1138 frame_size_history_add 1164 frame_size_history_add
1139 (f, Qxg_frame_set_char_size_3, width, height, 1165 (f, Qxg_frame_set_char_size_3, width, height,
1140 list2i (totalwidth, totalheight)); 1166 list2i (totalwidth, totalheight));
1167#ifndef HAVE_PGTK
1141 gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), 1168 gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
1142 totalwidth, totalheight); 1169 totalwidth, totalheight);
1170#else
1171 if (FRAME_GTK_OUTER_WIDGET (f)) {
1172 gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
1173 totalwidth, totalheight);
1174 } else {
1175 gtk_widget_set_size_request (FRAME_GTK_WIDGET (f),
1176 totalwidth, totalheight);
1177 }
1178#endif
1143 fullscreen = Qnil; 1179 fullscreen = Qnil;
1144 } 1180 }
1145 1181
@@ -1355,7 +1391,7 @@ xg_create_frame_widgets (struct frame *f)
1355 else 1391 else
1356 wtop = gtk_window_new (type); 1392 wtop = gtk_window_new (type);
1357#else 1393#else
1358 if (!NILP(f->parent_frame) || f->tooltip) 1394 if (f->tooltip)
1359 { 1395 {
1360 type = GTK_WINDOW_POPUP; 1396 type = GTK_WINDOW_POPUP;
1361 } 1397 }
@@ -1546,6 +1582,107 @@ xg_create_frame_widgets (struct frame *f)
1546 return 1; 1582 return 1;
1547} 1583}
1548 1584
1585#ifdef HAVE_PGTK
1586void
1587xg_create_frame_outer_widgets (struct frame *f)
1588{
1589 GtkWidget *wtop;
1590 GtkWidget *wvbox, *whbox;
1591 GtkWindowType type = GTK_WINDOW_TOPLEVEL;
1592 char *title = 0;
1593
1594 PGTK_TRACE ("xg_create_frame_outer_widgets.");
1595 block_input ();
1596
1597 wtop = gtk_window_new (type);
1598 gtk_widget_add_events(wtop, GDK_ALL_EVENTS_MASK);
1599
1600 xg_set_screen (wtop, f);
1601
1602 wvbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
1603 whbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
1604 gtk_box_set_homogeneous (GTK_BOX (wvbox), FALSE);
1605 gtk_box_set_homogeneous (GTK_BOX (whbox), FALSE);
1606
1607 /* Use same names as the Xt port does. I.e. Emacs.pane.emacs by default */
1608 gtk_widget_set_name (wtop, EMACS_CLASS);
1609 gtk_widget_set_name (wvbox, "pane");
1610
1611 /* If this frame has a title or name, set it in the title bar. */
1612 if (! NILP (f->title))
1613 title = SSDATA (ENCODE_UTF_8 (f->title));
1614 else if (! NILP (f->name))
1615 title = SSDATA (ENCODE_UTF_8 (f->name));
1616
1617 if (title)
1618 gtk_window_set_title (GTK_WINDOW (wtop), title);
1619
1620 if (FRAME_UNDECORATED (f))
1621 {
1622 gtk_window_set_decorated (GTK_WINDOW (wtop), FALSE);
1623 store_frame_param (f, Qundecorated, Qt);
1624 }
1625
1626 FRAME_GTK_OUTER_WIDGET (f) = wtop;
1627 f->output_data.xp->vbox_widget = wvbox;
1628 f->output_data.xp->hbox_widget = whbox;
1629
1630 gtk_container_add (GTK_CONTAINER (wtop), wvbox);
1631 gtk_box_pack_start (GTK_BOX (wvbox), whbox, TRUE, TRUE, 0);
1632
1633 if (FRAME_EXTERNAL_TOOL_BAR (f))
1634 update_frame_tool_bar (f);
1635
1636#if ! GTK_CHECK_VERSION (3, 22, 0)
1637 gtk_window_set_wmclass (GTK_WINDOW (wtop),
1638 SSDATA (Vx_resource_name),
1639 SSDATA (Vx_resource_class));
1640#endif
1641
1642 /* Convert our geometry parameters into a geometry string
1643 and specify it.
1644 GTK will itself handle calculating the real position this way. */
1645 xg_set_geometry (f);
1646 f->win_gravity
1647 = gtk_window_get_gravity (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)));
1648
1649 gtk_window_set_resizable (GTK_WINDOW (wtop), TRUE);
1650
1651 if (FRAME_OVERRIDE_REDIRECT (f))
1652 {
1653 GdkWindow *gwin = gtk_widget_get_window (wtop);
1654
1655 if (gwin)
1656 gdk_window_set_override_redirect (gwin, TRUE);
1657 }
1658
1659 /* Steal a tool tip window we can move ourselves. */
1660 f->output_data.xp->ttip_widget = 0;
1661 f->output_data.xp->ttip_lbl = 0;
1662 f->output_data.xp->ttip_window = 0;
1663 gtk_widget_set_tooltip_text (wtop, "Dummy text");
1664 g_signal_connect (wtop, "query-tooltip", G_CALLBACK (qttip_cb), f);
1665
1666 {
1667 GdkScreen *screen = gtk_widget_get_screen (wtop);
1668 GtkSettings *gs = gtk_settings_get_for_screen (screen);
1669 /* Only connect this signal once per screen. */
1670 if (! g_signal_handler_find (G_OBJECT (gs),
1671 G_SIGNAL_MATCH_FUNC,
1672 0, 0, 0,
1673 (gpointer) G_CALLBACK (style_changed_cb),
1674 0))
1675 {
1676 g_signal_connect (G_OBJECT (gs), "notify::gtk-theme-name",
1677 G_CALLBACK (style_changed_cb),
1678 gdk_screen_get_display (screen));
1679 }
1680 }
1681
1682 unblock_input ();
1683}
1684#endif
1685
1549void 1686void
1550xg_free_frame_widgets (struct frame *f) 1687xg_free_frame_widgets (struct frame *f)
1551{ 1688{
@@ -1784,10 +1921,17 @@ void
1784xg_set_skip_taskbar (struct frame *f, Lisp_Object skip_taskbar) 1921xg_set_skip_taskbar (struct frame *f, Lisp_Object skip_taskbar)
1785{ 1922{
1786 block_input (); 1923 block_input ();
1924#ifndef HAVE_PGTK
1787 if (FRAME_GTK_WIDGET (f)) 1925 if (FRAME_GTK_WIDGET (f))
1788 gdk_window_set_skip_taskbar_hint 1926 gdk_window_set_skip_taskbar_hint
1789 (gtk_widget_get_window (FRAME_GTK_OUTER_WIDGET (f)), 1927 (gtk_widget_get_window (FRAME_GTK_OUTER_WIDGET (f)),
1790 NILP (skip_taskbar) ? FALSE : TRUE); 1928 NILP (skip_taskbar) ? FALSE : TRUE);
1929#else
1930 if (FRAME_GTK_OUTER_WIDGET (f))
1931 gdk_window_set_skip_taskbar_hint
1932 (gtk_widget_get_window (FRAME_GTK_OUTER_WIDGET (f)),
1933 NILP (skip_taskbar) ? FALSE : TRUE);
1934#endif
1791 unblock_input (); 1935 unblock_input ();
1792} 1936}
1793 1937
@@ -1812,7 +1956,13 @@ void
1812xg_set_no_accept_focus (struct frame *f, Lisp_Object no_accept_focus) 1956xg_set_no_accept_focus (struct frame *f, Lisp_Object no_accept_focus)
1813{ 1957{
1814 block_input (); 1958 block_input ();
1815 if (FRAME_GTK_WIDGET (f)) 1959 if (
1960#ifndef HAVE_PGTK
1961 FRAME_GTK_WIDGET (f)
1962#else
1963 FRAME_GTK_OUTER_WIDGET (f)
1964#endif
1965 )
1816 { 1966 {
1817 GtkWindow *gwin = GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)); 1967 GtkWindow *gwin = GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f));
1818 gboolean g_no_accept_focus = NILP (no_accept_focus) ? TRUE : FALSE; 1968 gboolean g_no_accept_focus = NILP (no_accept_focus) ? TRUE : FALSE;
diff --git a/src/gtkutil.h b/src/gtkutil.h
index b7f67ba9281..04007343f27 100644
--- a/src/gtkutil.h
+++ b/src/gtkutil.h
@@ -179,6 +179,9 @@ extern void xg_set_background_color (struct frame *f, unsigned long bg);
179extern bool xg_check_special_colors (struct frame *f, 179extern bool xg_check_special_colors (struct frame *f,
180 const char *color_name, 180 const char *color_name,
181 Emacs_Color *color); 181 Emacs_Color *color);
182#ifdef HAVE_PGTK
183extern void xg_create_frame_outer_widgets (struct frame *f);
184#endif
182 185
183#ifndef HAVE_PGTK 186#ifndef HAVE_PGTK
184extern void xg_set_frame_icon (struct frame *f, 187extern void xg_set_frame_icon (struct frame *f,
diff --git a/src/pgtkfns.c b/src/pgtkfns.c
index 06fb4e206f4..c6909ba3d63 100644
--- a/src/pgtkfns.c
+++ b/src/pgtkfns.c
@@ -231,7 +231,7 @@ x_set_cursor_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
231static void 231static void
232pgtk_set_name_internal (struct frame *f, Lisp_Object name) 232pgtk_set_name_internal (struct frame *f, Lisp_Object name)
233{ 233{
234 if (FRAME_GTK_WIDGET (f)) 234 if (FRAME_GTK_OUTER_WIDGET (f))
235 { 235 {
236 block_input (); 236 block_input ();
237 { 237 {
@@ -1523,18 +1523,32 @@ This function is an internal primitive--use `make-frame' instead. */ )
1523 struct frame *p = XFRAME (parent_frame); 1523 struct frame *p = XFRAME (parent_frame);
1524 1524
1525 block_input (); 1525 block_input ();
1526
1526 PGTK_TRACE ("x_set_parent_frame x: %d, y: %d", f->left_pos, f->top_pos); 1527 PGTK_TRACE ("x_set_parent_frame x: %d, y: %d", f->left_pos, f->top_pos);
1527 gtk_window_set_transient_for (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), 1528 GtkWidget *fixed = FRAME_GTK_WIDGET (f);
1528 GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (p))); 1529 GtkWidget *fixed_of_p = FRAME_GTK_WIDGET (p);
1529 gtk_window_set_attached_to (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), 1530 GtkWidget *whbox_of_f = gtk_widget_get_parent (fixed);
1530 FRAME_GTK_WIDGET (p)); 1531 g_object_ref (fixed);
1531 gtk_window_set_destroy_with_parent (GTK_WINDOW 1532 gtk_container_remove (GTK_CONTAINER (whbox_of_f), fixed);
1532 (FRAME_GTK_OUTER_WIDGET (f)), TRUE); 1533 gtk_fixed_put (GTK_FIXED (fixed_of_p), fixed, f->left_pos, f->top_pos);
1533 gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f)); 1534 gtk_widget_show_all (fixed);
1535 g_object_unref (fixed);
1536
1537 gtk_widget_destroy (FRAME_GTK_OUTER_WIDGET (f));
1538 FRAME_GTK_OUTER_WIDGET (f) = NULL;
1539 FRAME_OUTPUT_DATA (f)->vbox_widget = NULL;
1540 FRAME_OUTPUT_DATA (f)->hbox_widget = NULL;
1541 FRAME_OUTPUT_DATA (f)->menubar_widget = NULL;
1542 FRAME_OUTPUT_DATA (f)->toolbar_widget = NULL;
1543 FRAME_OUTPUT_DATA (f)->ttip_widget = NULL;
1544 FRAME_OUTPUT_DATA (f)->ttip_lbl = NULL;
1545 FRAME_OUTPUT_DATA (f)->ttip_window = NULL;
1546
1534 unblock_input (); 1547 unblock_input ();
1535 } 1548 }
1536 1549
1537 gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f)); 1550 if (FRAME_GTK_OUTER_WIDGET (f))
1551 gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f));
1538 1552
1539 gui_default_parameter (f, parms, Qno_focus_on_map, Qnil, 1553 gui_default_parameter (f, parms, Qno_focus_on_map, Qnil,
1540 NULL, NULL, RES_TYPE_BOOLEAN); 1554 NULL, NULL, RES_TYPE_BOOLEAN);
@@ -3298,8 +3312,15 @@ frame_geometry (Lisp_Object frame, Lisp_Object attribute)
3298 3312
3299 /* Get these here because they can't be got in configure_event(). */ 3313 /* Get these here because they can't be got in configure_event(). */
3300 int left_pos, top_pos; 3314 int left_pos, top_pos;
3301 gtk_window_get_position (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), 3315 if (FRAME_GTK_OUTER_WIDGET (f)) {
3302 &left_pos, &top_pos); 3316 gtk_window_get_position (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
3317 &left_pos, &top_pos);
3318 } else {
3319 GtkAllocation alloc;
3320 gtk_widget_get_allocation (FRAME_GTK_WIDGET (f), &alloc);
3321 left_pos = alloc.x;
3322 top_pos = alloc.y;
3323 }
3303 3324
3304 int native_left = left_pos + border; 3325 int native_left = left_pos + border;
3305 int native_top = top_pos + border + title_height; 3326 int native_top = top_pos + border + title_height;
@@ -3647,6 +3668,8 @@ syms_of_pgtkfns (void)
3647 DEFSYM (Qframe_title_format, "frame-title-format"); 3668 DEFSYM (Qframe_title_format, "frame-title-format");
3648 DEFSYM (Qicon_title_format, "icon-title-format"); 3669 DEFSYM (Qicon_title_format, "icon-title-format");
3649 DEFSYM (Qdark, "dark"); 3670 DEFSYM (Qdark, "dark");
3671 DEFSYM (Qhide, "hide");
3672 DEFSYM (Qresize_mode, "resize-mode");
3650 3673
3651 DEFVAR_LISP ("x-cursor-fore-pixel", Vx_cursor_fore_pixel, 3674 DEFVAR_LISP ("x-cursor-fore-pixel", Vx_cursor_fore_pixel,
3652 doc: /* A string indicating the foreground color of the cursor box. */); 3675 doc: /* A string indicating the foreground color of the cursor box. */);
@@ -3799,6 +3822,28 @@ When using Gtk+ tooltips, the tooltip face is not used. */);
3799Value is a pair (COLUMNS . ROWS). Text larger than this is clipped. */); 3822Value is a pair (COLUMNS . ROWS). Text larger than this is clipped. */);
3800 Vx_max_tooltip_size = Fcons (make_fixnum (80), make_fixnum (40)); 3823 Vx_max_tooltip_size = Fcons (make_fixnum (80), make_fixnum (40));
3801 3824
3825 DEFVAR_LISP ("x-gtk-resize-child-frames", x_gtk_resize_child_frames,
3826 doc: /* If non-nil, resize child frames specially with GTK builds.
3827If this is nil, resize child frames like any other frames. This is the
3828default and usually works with most desktops. Some desktop environments
3829(GNOME shell in particular when using the mutter window manager),
3830however, may refuse to resize a child frame when Emacs is built with
3831GTK3. For those environments, the two settings below are provided.
3832
3833If this equals the symbol 'hide', Emacs temporarily hides the child
3834frame during resizing. This approach seems to work reliably, may
3835however induce some flicker when the frame is made visible again.
3836
3837If this equals the symbol 'resize-mode', Emacs uses GTK's resize mode to
3838always trigger an immediate resize of the child frame. This method is
3839deprecated by GTK and may not work in future versions of that toolkit.
3840It also may freeze Emacs when used with other desktop environments. It
3841avoids, however, the unpleasant flicker induced by the hiding approach.
3842
3843This variable is considered a temporary workaround and will be hopefully
3844eliminated in future versions of Emacs. */);
3845 x_gtk_resize_child_frames = Qnil;
3846
3802 3847
3803 DEFSYM (Qmono, "mono"); 3848 DEFSYM (Qmono, "mono");
3804 DEFSYM (Qassq_delete_all, "assq-delete-all"); 3849 DEFSYM (Qassq_delete_all, "assq-delete-all");
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",
diff --git a/src/pgtkterm.h b/src/pgtkterm.h
index cff16332921..ad66039648b 100644
--- a/src/pgtkterm.h
+++ b/src/pgtkterm.h
@@ -428,6 +428,9 @@ enum
428#define FRAME_FONT(f) (FRAME_X_OUTPUT(f)->font) 428#define FRAME_FONT(f) (FRAME_X_OUTPUT(f)->font)
429#define FRAME_GTK_OUTER_WIDGET(f) (FRAME_X_OUTPUT(f)->widget) 429#define FRAME_GTK_OUTER_WIDGET(f) (FRAME_X_OUTPUT(f)->widget)
430#define FRAME_GTK_WIDGET(f) (FRAME_X_OUTPUT(f)->edit_widget) 430#define FRAME_GTK_WIDGET(f) (FRAME_X_OUTPUT(f)->edit_widget)
431#define FRAME_WIDGET(f) (FRAME_GTK_OUTER_WIDGET(f) ? \
432 FRAME_GTK_OUTER_WIDGET(f) : \
433 FRAME_GTK_WIDGET(f))
431 434
432/* aliases */ 435/* aliases */
433#define FRAME_PGTK_VIEW(f) FRAME_GTK_WIDGET(f) 436#define FRAME_PGTK_VIEW(f) FRAME_GTK_WIDGET(f)