diff options
| author | Yuuki Harano | 2020-09-06 23:27:45 +0900 |
|---|---|---|
| committer | Jeff Walsh | 2020-11-24 12:24:40 +1100 |
| commit | 28073ba59bbabec1194977d654b471800ce63f45 (patch) | |
| tree | 967c439b8f95894da3e573b0897d28b3b4d6c6d2 /src | |
| parent | e75ce0302d4c907c8ff56fb15fc7dd12b48e7370 (diff) | |
| download | emacs-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.c | 1 | ||||
| -rw-r--r-- | src/emacsgtkfixed.h | 5 | ||||
| -rw-r--r-- | src/gtkutil.c | 162 | ||||
| -rw-r--r-- | src/gtkutil.h | 3 | ||||
| -rw-r--r-- | src/pgtkfns.c | 67 | ||||
| -rw-r--r-- | src/pgtkterm.c | 307 | ||||
| -rw-r--r-- | src/pgtkterm.h | 3 |
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, | |||
| 51 | static void emacs_fixed_get_preferred_height (GtkWidget *widget, | 51 | static void emacs_fixed_get_preferred_height (GtkWidget *widget, |
| 52 | gint *minimum, | 52 | gint *minimum, |
| 53 | gint *natural); | 53 | gint *natural); |
| 54 | static GType emacs_fixed_get_type (void); | ||
| 55 | G_DEFINE_TYPE (EmacsFixed, emacs_fixed, GTK_TYPE_FIXED) | 54 | G_DEFINE_TYPE (EmacsFixed, emacs_fixed, GTK_TYPE_FIXED) |
| 56 | 55 | ||
| 57 | static EmacsFixed * | 56 | static 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 | ||
| 28 | G_BEGIN_DECLS | 28 | G_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 | |||
| 30 | struct frame; | 33 | struct frame; |
| 31 | 34 | ||
| 32 | typedef struct _EmacsFixedPrivate EmacsFixedPrivate; | 35 | typedef struct _EmacsFixedPrivate EmacsFixedPrivate; |
| @@ -44,6 +47,8 @@ struct _EmacsFixedClass | |||
| 44 | GtkFixedClass parent_class; | 47 | GtkFixedClass parent_class; |
| 45 | }; | 48 | }; |
| 46 | 49 | ||
| 50 | extern GType emacs_fixed_get_type (void); | ||
| 51 | |||
| 47 | extern GtkWidget *emacs_fixed_new (struct frame *f); | 52 | extern GtkWidget *emacs_fixed_new (struct frame *f); |
| 48 | 53 | ||
| 49 | G_END_DECLS | 54 | G_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 | ||
| 1586 | void | ||
| 1587 | xg_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 | |||
| 1549 | void | 1686 | void |
| 1550 | xg_free_frame_widgets (struct frame *f) | 1687 | xg_free_frame_widgets (struct frame *f) |
| 1551 | { | 1688 | { |
| @@ -1784,10 +1921,17 @@ void | |||
| 1784 | xg_set_skip_taskbar (struct frame *f, Lisp_Object skip_taskbar) | 1921 | xg_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 | |||
| 1812 | xg_set_no_accept_focus (struct frame *f, Lisp_Object no_accept_focus) | 1956 | xg_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); | |||
| 179 | extern bool xg_check_special_colors (struct frame *f, | 179 | extern 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 | ||
| 183 | extern void xg_create_frame_outer_widgets (struct frame *f); | ||
| 184 | #endif | ||
| 182 | 185 | ||
| 183 | #ifndef HAVE_PGTK | 186 | #ifndef HAVE_PGTK |
| 184 | extern void xg_set_frame_icon (struct frame *f, | 187 | extern 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) | |||
| 231 | static void | 231 | static void |
| 232 | pgtk_set_name_internal (struct frame *f, Lisp_Object name) | 232 | pgtk_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. */); | |||
| 3799 | Value is a pair (COLUMNS . ROWS). Text larger than this is clipped. */); | 3822 | Value 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. | ||
| 3827 | If this is nil, resize child frames like any other frames. This is the | ||
| 3828 | default and usually works with most desktops. Some desktop environments | ||
| 3829 | (GNOME shell in particular when using the mutter window manager), | ||
| 3830 | however, may refuse to resize a child frame when Emacs is built with | ||
| 3831 | GTK3. For those environments, the two settings below are provided. | ||
| 3832 | |||
| 3833 | If this equals the symbol 'hide', Emacs temporarily hides the child | ||
| 3834 | frame during resizing. This approach seems to work reliably, may | ||
| 3835 | however induce some flicker when the frame is made visible again. | ||
| 3836 | |||
| 3837 | If this equals the symbol 'resize-mode', Emacs uses GTK's resize mode to | ||
| 3838 | always trigger an immediate resize of the child frame. This method is | ||
| 3839 | deprecated by GTK and may not work in future versions of that toolkit. | ||
| 3840 | It also may freeze Emacs when used with other desktop environments. It | ||
| 3841 | avoids, however, the unpleasant flicker induced by the hiding approach. | ||
| 3842 | |||
| 3843 | This variable is considered a temporary workaround and will be hopefully | ||
| 3844 | eliminated 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 | |||
| 293 | static void | ||
| 294 | x_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) | |||
| 2900 | bool | 3053 | bool |
| 2901 | pgtk_text_icon (struct frame *f, const char *icon_name) | 3054 | pgtk_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) | |||
| 4392 | static void | 4547 | static void |
| 4393 | set_fullscreen_state (struct frame *f) | 4548 | set_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 | ||
| 4798 | static void | 4964 | static 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 | ||
| 4817 | static bool | 4987 | static 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 | |||
| 5071 | static void | 5244 | static void |
| 5072 | print_widget_tree_recursive (GtkWidget * w, gpointer user_data) | 5245 | print_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 | |||
| 5111 | static gboolean | 5286 | static gboolean |
| 5112 | pgtk_handle_draw (GtkWidget * widget, cairo_t * cr, gpointer * data) | 5287 | pgtk_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) |