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/>. */
27 #include "emacsgtkfixed.h"
29 /* Silence a bogus diagnostic; see GNOME bug 683906. */
30 #if 4 < __GNUC__ + (7 <= __GNUC_MINOR__)
31 # pragma GCC diagnostic push
32 # pragma GCC diagnostic ignored "-Wunused-local-typedefs"
35 typedef struct _EmacsFixed EmacsFixed
;
36 typedef struct _EmacsFixedPrivate EmacsFixedPrivate
;
37 typedef struct _EmacsFixedClass EmacsFixedClass
;
39 struct _EmacsFixedPrivate
45 static void emacs_fixed_get_preferred_width (GtkWidget
*widget
,
48 static void emacs_fixed_get_preferred_height (GtkWidget
*widget
,
51 static GType
emacs_fixed_get_type (void);
52 G_DEFINE_TYPE (EmacsFixed
, emacs_fixed
, GTK_TYPE_FIXED
)
55 EMACS_FIXED (GtkWidget
*widget
)
57 return G_TYPE_CHECK_INSTANCE_CAST (widget
, emacs_fixed_get_type (),
63 static EmacsFixedClass
*
64 EMACS_FIXED_GET_CLASS (GtkWidget
*widget
)
66 return G_TYPE_INSTANCE_GET_CLASS (widget
, emacs_fixed_get_type (),
70 struct GtkFixedPrivateL
76 emacs_fixed_gtk_widget_size_allocate (GtkWidget
*widget
,
77 GtkAllocation
*allocation
)
81 This basically re-implements the base class method and adds an
82 additional case for an xwidget view.
84 It would be nicer if the bse class method could be called first,
85 and the the xview modification only would remain here. It wasn't
86 possible to solve it that way yet. */
87 EmacsFixedClass
*klass
;
88 GtkWidgetClass
*parent_class
;
89 struct GtkFixedPrivateL
*priv
;
91 klass
= EMACS_FIXED_GET_CLASS (widget
);
92 parent_class
= g_type_class_peek_parent (klass
);
93 parent_class
->size_allocate (widget
, allocation
);
95 priv
= G_TYPE_INSTANCE_GET_PRIVATE (widget
, GTK_TYPE_FIXED
,
96 struct GtkFixedPrivateL
);
98 gtk_widget_set_allocation (widget
, allocation
);
100 if (gtk_widget_get_has_window (widget
))
102 if (gtk_widget_get_realized (widget
))
103 gdk_window_move_resize (gtk_widget_get_window (widget
),
110 for (GList
*children
= priv
->children
; children
; children
= children
->next
)
112 GtkFixedChild
*child
= children
->data
;
114 if (!gtk_widget_get_visible (child
->widget
))
117 GtkRequisition child_requisition
;
118 gtk_widget_get_preferred_size (child
->widget
, &child_requisition
, NULL
);
120 GtkAllocation child_allocation
;
121 child_allocation
.x
= child
->x
;
122 child_allocation
.y
= child
->y
;
124 if (!gtk_widget_get_has_window (widget
))
126 child_allocation
.x
+= allocation
->x
;
127 child_allocation
.y
+= allocation
->y
;
130 child_allocation
.width
= child_requisition
.width
;
131 child_allocation
.height
= child_requisition
.height
;
133 struct xwidget_view
*xv
134 = g_object_get_data (G_OBJECT (child
->widget
), XG_XWIDGET_VIEW
);
137 child_allocation
.width
= xv
->clip_right
;
138 child_allocation
.height
= xv
->clip_bottom
- xv
->clip_top
;
141 gtk_widget_size_allocate (child
->widget
, &child_allocation
);
145 #endif /* HAVE_XWIDGETS */
148 emacs_fixed_class_init (EmacsFixedClass
*klass
)
150 GtkWidgetClass
*widget_class
;
152 widget_class
= (GtkWidgetClass
*) klass
;
154 widget_class
->get_preferred_width
= emacs_fixed_get_preferred_width
;
155 widget_class
->get_preferred_height
= emacs_fixed_get_preferred_height
;
157 widget_class
->size_allocate
= emacs_fixed_gtk_widget_size_allocate
;
159 g_type_class_add_private (klass
, sizeof (EmacsFixedPrivate
));
163 emacs_fixed_init (EmacsFixed
*fixed
)
165 fixed
->priv
= G_TYPE_INSTANCE_GET_PRIVATE (fixed
, emacs_fixed_get_type (),
171 emacs_fixed_new (struct frame
*f
)
173 EmacsFixed
*fixed
= g_object_new (emacs_fixed_get_type (), NULL
);
174 EmacsFixedPrivate
*priv
= fixed
->priv
;
176 return GTK_WIDGET (fixed
);
180 emacs_fixed_get_preferred_width (GtkWidget
*widget
,
184 EmacsFixed
*fixed
= EMACS_FIXED (widget
);
185 EmacsFixedPrivate
*priv
= fixed
->priv
;
186 int w
= priv
->f
->output_data
.x
->size_hints
.min_width
;
187 if (minimum
) *minimum
= w
;
188 if (natural
) *natural
= w
;
192 emacs_fixed_get_preferred_height (GtkWidget
*widget
,
196 EmacsFixed
*fixed
= EMACS_FIXED (widget
);
197 EmacsFixedPrivate
*priv
= fixed
->priv
;
198 int h
= priv
->f
->output_data
.x
->size_hints
.min_height
;
199 if (minimum
) *minimum
= h
;
200 if (natural
) *natural
= h
;
204 /* Override the X function so we can intercept Gtk+ 3 calls.
205 Use our values for min_width/height so that KDE don't freak out
206 (Bug#8919), and so users can resize our frames as they wish. */
209 XSetWMSizeHints (Display
* d
,
214 struct x_display_info
*dpyinfo
= x_display_info_for_display (d
);
215 struct frame
*f
= x_top_window_to_frame (dpyinfo
, w
);
217 data
[0] = hints
->flags
;
220 data
[3] = hints
->width
;
221 data
[4] = hints
->height
;
222 data
[5] = hints
->min_width
;
223 data
[6] = hints
->min_height
;
224 data
[7] = hints
->max_width
;
225 data
[8] = hints
->max_height
;
226 data
[9] = hints
->width_inc
;
227 data
[10] = hints
->height_inc
;
228 data
[11] = hints
->min_aspect
.x
;
229 data
[12] = hints
->min_aspect
.y
;
230 data
[13] = hints
->max_aspect
.x
;
231 data
[14] = hints
->max_aspect
.y
;
232 data
[15] = hints
->base_width
;
233 data
[16] = hints
->base_height
;
234 data
[17] = hints
->win_gravity
;
236 if ((hints
->flags
& PMinSize
) && f
)
238 int w
= f
->output_data
.x
->size_hints
.min_width
;
239 int h
= f
->output_data
.x
->size_hints
.min_height
;
244 XChangeProperty (d
, w
, prop
, XA_WM_SIZE_HINTS
, 32, PropModeReplace
,
245 (unsigned char *) data
, 18);
248 /* Override this X11 function.
249 This function is in the same X11 file as the one above. So we must
253 XSetWMNormalHints (Display
*d
, Window w
, XSizeHints
*hints
)
255 XSetWMSizeHints (d
, w
, hints
, XA_WM_NORMAL_HINTS
);