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-2016 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
11 (at 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 <http://www.gnu.org/licenses/>. */
29 #include "emacsgtkfixed.h"
31 /* Silence a bogus diagnostic; see GNOME bug 683906. */
32 #if 4 < __GNUC__ + (7 <= __GNUC_MINOR__)
33 # pragma GCC diagnostic push
34 # pragma GCC diagnostic ignored "-Wunused-local-typedefs"
37 typedef struct _EmacsFixed EmacsFixed
;
38 typedef struct _EmacsFixedPrivate EmacsFixedPrivate
;
39 typedef struct _EmacsFixedClass EmacsFixedClass
;
41 struct _EmacsFixedPrivate
47 static void emacs_fixed_get_preferred_width (GtkWidget
*widget
,
50 static void emacs_fixed_get_preferred_height (GtkWidget
*widget
,
54 static GType
emacs_fixed_get_type (void);
55 G_DEFINE_TYPE (EmacsFixed
, emacs_fixed
, GTK_TYPE_FIXED
)
58 EMACS_FIXED (GtkWidget
*widget
)
60 return G_TYPE_CHECK_INSTANCE_CAST (widget
, emacs_fixed_get_type (),
66 static EmacsFixedClass
*
67 EMACS_FIXED_GET_CLASS (GtkWidget
*widget
)
69 return G_TYPE_INSTANCE_GET_CLASS (widget
, emacs_fixed_get_type (),
73 struct GtkFixedPrivateL
78 static void emacs_fixed_gtk_widget_size_allocate (GtkWidget
*widget
,
79 GtkAllocation
*allocation
)
83 // This basically re-implements the base class method and adds an
84 // additional case for an xwidget view.
86 // It would be nicer if the bse class method could be called first,
87 // and the the xview modification only would remain here. It wasn't
88 // possible to solve it that way yet.
89 EmacsFixedClass
*klass
;
90 GtkWidgetClass
*parent_class
;
91 struct GtkFixedPrivateL
* priv
;
93 klass
= EMACS_FIXED_GET_CLASS (widget
);
94 parent_class
= g_type_class_peek_parent (klass
);
95 parent_class
->size_allocate (widget
, allocation
);
97 priv
= G_TYPE_INSTANCE_GET_PRIVATE (widget
,
99 struct GtkFixedPrivateL
);
101 gtk_widget_set_allocation (widget
, allocation
);
103 if (gtk_widget_get_has_window (widget
))
105 if (gtk_widget_get_realized (widget
))
106 gdk_window_move_resize (gtk_widget_get_window (widget
),
113 for (GList
*children
= priv
->children
; children
; children
= children
->next
)
115 GtkFixedChild
*child
= children
->data
;
117 if (!gtk_widget_get_visible (child
->widget
))
120 GtkRequisition child_requisition
;
121 gtk_widget_get_preferred_size (child
->widget
, &child_requisition
, NULL
);
123 GtkAllocation child_allocation
;
124 child_allocation
.x
= child
->x
;
125 child_allocation
.y
= child
->y
;
127 if (!gtk_widget_get_has_window (widget
))
129 child_allocation
.x
+= allocation
->x
;
130 child_allocation
.y
+= allocation
->y
;
133 child_allocation
.width
= child_requisition
.width
;
134 child_allocation
.height
= child_requisition
.height
;
136 struct xwidget_view
*xv
137 = g_object_get_data (G_OBJECT (child
->widget
), XG_XWIDGET_VIEW
);
140 child_allocation
.width
= xv
->clip_right
;
141 child_allocation
.height
= xv
->clip_bottom
- xv
->clip_top
;
144 gtk_widget_size_allocate (child
->widget
, &child_allocation
);
148 #endif /* HAVE_XWIDGETS */
151 emacs_fixed_class_init (EmacsFixedClass
*klass
)
153 GtkWidgetClass
*widget_class
;
155 widget_class
= (GtkWidgetClass
*) klass
;
158 widget_class
->get_preferred_width
= emacs_fixed_get_preferred_width
;
159 widget_class
->get_preferred_height
= emacs_fixed_get_preferred_height
;
161 widget_class
->size_allocate
= emacs_fixed_gtk_widget_size_allocate
;
163 g_type_class_add_private (klass
, sizeof (EmacsFixedPrivate
));
168 emacs_fixed_init (EmacsFixed
*fixed
)
170 fixed
->priv
= G_TYPE_INSTANCE_GET_PRIVATE (fixed
, emacs_fixed_get_type (),
178 * Creates a new #EmacsFixed.
180 * Returns: a new #EmacsFixed.
183 emacs_fixed_new (struct frame
*f
)
185 EmacsFixed
*fixed
= g_object_new (emacs_fixed_get_type (), NULL
);
186 EmacsFixedPrivate
*priv
= fixed
->priv
;
188 return GTK_WIDGET (fixed
);
192 emacs_fixed_get_preferred_width (GtkWidget
*widget
,
196 EmacsFixed
*fixed
= EMACS_FIXED (widget
);
197 EmacsFixedPrivate
*priv
= fixed
->priv
;
198 int w
= priv
->f
->output_data
.x
->size_hints
.min_width
;
199 if (minimum
) *minimum
= w
;
200 if (natural
) *natural
= w
;
204 emacs_fixed_get_preferred_height (GtkWidget
*widget
,
208 EmacsFixed
*fixed
= EMACS_FIXED (widget
);
209 EmacsFixedPrivate
*priv
= fixed
->priv
;
210 int h
= priv
->f
->output_data
.x
->size_hints
.min_height
;
211 if (minimum
) *minimum
= h
;
212 if (natural
) *natural
= h
;
216 /* Override the X function so we can intercept Gtk+ 3 calls.
217 Use our values for min_width/height so that KDE don't freak out
218 (Bug#8919), and so users can resize our frames as they wish. */
221 XSetWMSizeHints (Display
* d
,
226 struct x_display_info
*dpyinfo
= x_display_info_for_display (d
);
227 struct frame
*f
= x_top_window_to_frame (dpyinfo
, w
);
229 data
[0] = hints
->flags
;
232 data
[3] = hints
->width
;
233 data
[4] = hints
->height
;
234 data
[5] = hints
->min_width
;
235 data
[6] = hints
->min_height
;
236 data
[7] = hints
->max_width
;
237 data
[8] = hints
->max_height
;
238 data
[9] = hints
->width_inc
;
239 data
[10] = hints
->height_inc
;
240 data
[11] = hints
->min_aspect
.x
;
241 data
[12] = hints
->min_aspect
.y
;
242 data
[13] = hints
->max_aspect
.x
;
243 data
[14] = hints
->max_aspect
.y
;
244 data
[15] = hints
->base_width
;
245 data
[16] = hints
->base_height
;
246 data
[17] = hints
->win_gravity
;
248 if ((hints
->flags
& PMinSize
) && f
)
250 int w
= f
->output_data
.x
->size_hints
.min_width
;
251 int h
= f
->output_data
.x
->size_hints
.min_height
;
256 XChangeProperty (d
, w
, prop
, XA_WM_SIZE_HINTS
, 32, PropModeReplace
,
257 (unsigned char *) data
, 18);
260 /* Override this X11 function.
261 This function is in the same X11 file as the one above. So we must
265 XSetWMNormalHints (Display
*d
, Window w
, XSizeHints
*hints
)
267 XSetWMSizeHints (d
, w
, hints
, XA_WM_NORMAL_HINTS
);