1 /* A Gtk Widget that inherits GtkFixed, but can be shrunk.
2 This file is only use when compiling with Gtk+ 3.
4 Copyright (C) 2011-2017 Free Software Foundation, Inc.
6 This file is part of GNU Emacs.
8 GNU Emacs is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or (at
11 your option) any later version.
13 GNU Emacs is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
27 #include "emacsgtkfixed.h"
29 /* Silence a bogus diagnostic; see GNOME bug 683906. */
30 #if GNUC_PREREQ (4, 7, 0) && ! GLIB_CHECK_VERSION (2, 35, 7)
31 # pragma GCC diagnostic push
32 # pragma GCC diagnostic ignored "-Wunused-local-typedefs"
35 typedef struct _EmacsFixed EmacsFixed
;
36 typedef struct _EmacsFixedClass EmacsFixedClass
;
38 struct _EmacsFixedPrivate
44 static void emacs_fixed_get_preferred_width (GtkWidget
*widget
,
47 static void emacs_fixed_get_preferred_height (GtkWidget
*widget
,
50 static GType
emacs_fixed_get_type (void);
51 G_DEFINE_TYPE (EmacsFixed
, emacs_fixed
, GTK_TYPE_FIXED
)
54 EMACS_FIXED (GtkWidget
*widget
)
56 return G_TYPE_CHECK_INSTANCE_CAST (widget
, emacs_fixed_get_type (),
62 static EmacsFixedClass
*
63 EMACS_FIXED_GET_CLASS (GtkWidget
*widget
)
65 return G_TYPE_INSTANCE_GET_CLASS (widget
, emacs_fixed_get_type (),
69 struct GtkFixedPrivateL
75 emacs_fixed_gtk_widget_size_allocate (GtkWidget
*widget
,
76 GtkAllocation
*allocation
)
80 This basically re-implements the base class method and adds an
81 additional case for an xwidget view.
83 It would be nicer if the bse class method could be called first,
84 and the xview modification only would remain here. It wasn't
85 possible to solve it that way yet. */
86 EmacsFixedClass
*klass
;
87 GtkWidgetClass
*parent_class
;
88 struct GtkFixedPrivateL
*priv
;
90 klass
= EMACS_FIXED_GET_CLASS (widget
);
91 parent_class
= g_type_class_peek_parent (klass
);
92 parent_class
->size_allocate (widget
, allocation
);
94 priv
= G_TYPE_INSTANCE_GET_PRIVATE (widget
, GTK_TYPE_FIXED
,
95 struct GtkFixedPrivateL
);
97 gtk_widget_set_allocation (widget
, allocation
);
99 if (gtk_widget_get_has_window (widget
))
101 if (gtk_widget_get_realized (widget
))
102 gdk_window_move_resize (gtk_widget_get_window (widget
),
109 for (GList
*children
= priv
->children
; children
; children
= children
->next
)
111 GtkFixedChild
*child
= children
->data
;
113 if (!gtk_widget_get_visible (child
->widget
))
116 GtkRequisition child_requisition
;
117 gtk_widget_get_preferred_size (child
->widget
, &child_requisition
, NULL
);
119 GtkAllocation child_allocation
;
120 child_allocation
.x
= child
->x
;
121 child_allocation
.y
= child
->y
;
123 if (!gtk_widget_get_has_window (widget
))
125 child_allocation
.x
+= allocation
->x
;
126 child_allocation
.y
+= allocation
->y
;
129 child_allocation
.width
= child_requisition
.width
;
130 child_allocation
.height
= child_requisition
.height
;
132 struct xwidget_view
*xv
133 = g_object_get_data (G_OBJECT (child
->widget
), XG_XWIDGET_VIEW
);
136 child_allocation
.width
= xv
->clip_right
;
137 child_allocation
.height
= xv
->clip_bottom
- xv
->clip_top
;
140 gtk_widget_size_allocate (child
->widget
, &child_allocation
);
144 #endif /* HAVE_XWIDGETS */
147 emacs_fixed_class_init (EmacsFixedClass
*klass
)
149 GtkWidgetClass
*widget_class
;
151 widget_class
= (GtkWidgetClass
*) klass
;
153 widget_class
->get_preferred_width
= emacs_fixed_get_preferred_width
;
154 widget_class
->get_preferred_height
= emacs_fixed_get_preferred_height
;
156 widget_class
->size_allocate
= emacs_fixed_gtk_widget_size_allocate
;
158 g_type_class_add_private (klass
, sizeof (EmacsFixedPrivate
));
162 emacs_fixed_init (EmacsFixed
*fixed
)
164 fixed
->priv
= G_TYPE_INSTANCE_GET_PRIVATE (fixed
, emacs_fixed_get_type (),
170 emacs_fixed_new (struct frame
*f
)
172 EmacsFixed
*fixed
= g_object_new (emacs_fixed_get_type (), NULL
);
173 EmacsFixedPrivate
*priv
= fixed
->priv
;
175 return GTK_WIDGET (fixed
);
179 emacs_fixed_get_preferred_width (GtkWidget
*widget
,
183 EmacsFixed
*fixed
= EMACS_FIXED (widget
);
184 EmacsFixedPrivate
*priv
= fixed
->priv
;
185 int w
= priv
->f
->output_data
.x
->size_hints
.min_width
;
186 if (minimum
) *minimum
= w
;
187 if (natural
) *natural
= w
;
191 emacs_fixed_get_preferred_height (GtkWidget
*widget
,
195 EmacsFixed
*fixed
= EMACS_FIXED (widget
);
196 EmacsFixedPrivate
*priv
= fixed
->priv
;
197 int h
= priv
->f
->output_data
.x
->size_hints
.min_height
;
198 if (minimum
) *minimum
= h
;
199 if (natural
) *natural
= h
;
203 /* Override the X function so we can intercept Gtk+ 3 calls.
204 Use our values for min_width/height so that KDE don't freak out
205 (Bug#8919), and so users can resize our frames as they wish. */
208 XSetWMSizeHints (Display
*d
,
213 struct x_display_info
*dpyinfo
= x_display_info_for_display (d
);
214 struct frame
*f
= x_top_window_to_frame (dpyinfo
, w
);
216 data
[0] = hints
->flags
;
219 data
[3] = hints
->width
;
220 data
[4] = hints
->height
;
221 data
[5] = hints
->min_width
;
222 data
[6] = hints
->min_height
;
223 data
[7] = hints
->max_width
;
224 data
[8] = hints
->max_height
;
225 data
[9] = hints
->width_inc
;
226 data
[10] = hints
->height_inc
;
227 data
[11] = hints
->min_aspect
.x
;
228 data
[12] = hints
->min_aspect
.y
;
229 data
[13] = hints
->max_aspect
.x
;
230 data
[14] = hints
->max_aspect
.y
;
231 data
[15] = hints
->base_width
;
232 data
[16] = hints
->base_height
;
233 data
[17] = hints
->win_gravity
;
235 if ((hints
->flags
& PMinSize
) && f
)
237 int w
= f
->output_data
.x
->size_hints
.min_width
;
238 int h
= f
->output_data
.x
->size_hints
.min_height
;
243 XChangeProperty (d
, w
, prop
, XA_WM_SIZE_HINTS
, 32, PropModeReplace
,
244 (unsigned char *) data
, 18);
247 /* Override this X11 function.
248 This function is in the same X11 file as the one above. So we must
252 XSetWMNormalHints (Display
*d
, Window w
, XSizeHints
*hints
)
254 XSetWMSizeHints (d
, w
, hints
, XA_WM_NORMAL_HINTS
);