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-2012 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/>. */
23 #include "emacsgtkfixed.h"
32 /* Silence a bogus diagnostic; see GNOME bug 683906. */
33 #if (__GNUC__ == 4 && 6 <= __GNUC_MINOR__) || 4 < __GNUC__
34 # pragma GCC diagnostic push
35 # pragma GCC diagnostic ignored "-Wunused-local-typedefs"
38 #define EMACS_TYPE_FIXED emacs_fixed_get_type ()
39 #define EMACS_FIXED(obj) \
40 G_TYPE_CHECK_INSTANCE_CAST (obj, EMACS_TYPE_FIXED, EmacsFixed)
42 typedef struct _EmacsFixed EmacsFixed
;
43 typedef struct _EmacsFixedPrivate EmacsFixedPrivate
;
44 typedef struct _EmacsFixedClass EmacsFixedClass
;
51 EmacsFixedPrivate
*priv
;
54 struct _EmacsFixedClass
56 GtkFixedClass parent_class
;
59 struct _EmacsFixedPrivate
65 static void emacs_fixed_get_preferred_width (GtkWidget
*widget
,
68 static void emacs_fixed_get_preferred_height (GtkWidget
*widget
,
71 G_DEFINE_TYPE (EmacsFixed
, emacs_fixed
, GTK_TYPE_FIXED
)
74 /* void aloc_callback(GtkWidget* child, GtkWidget* fixed){ */
75 /* GtkAllocation child_allocation; */
76 /* GtkRequisition child_requisition; */
79 /* // if child is an xwidget, find its clipping area and modify allocation */
81 /* struct xwidget_view* xv = (struct xwidget_view*) g_object_get_data (G_OBJECT (child), XG_XWIDGET_VIEW); */
82 /* printf("aloc callback %d %s\n", xv, gtk_widget_get_name(child)); */
84 /* printf(" allocation modification for xw\n"); */
85 /* gtk_widget_get_allocation(child, &child_allocation); */
86 /* child_allocation.width = xv->clip_right; */
87 /* child_allocation.height = xv->clip_bottom - xv->clip_top; */
88 /* gtk_widget_size_allocate (child, &child_allocation); */
89 /* //TODO find a way to remove this feeble workaround */
94 struct GtkFixedPrivateL
99 static void emacs_fixed_gtk_widget_size_allocate (GtkWidget
*widget
,
100 GtkAllocation
*allocation
){
104 //TODO 1st call base class method
105 EmacsFixedClass
*klass
;
106 GtkWidgetClass
*parent_class
;
107 struct GtkFixedPrivateL
* priv
;
108 GtkFixedChild
*child
;
109 GtkAllocation child_allocation
;
110 GtkRequisition child_requisition
;
112 struct xwidget_view
* xv
;
114 // printf(" emacs_fixed_gtk_widget_size_allocate\n");
115 klass
= EMACS_FIXED_GET_CLASS (widget
);
116 parent_class
= g_type_class_peek_parent (klass
);
117 parent_class
->size_allocate (widget
, allocation
);
119 priv
= G_TYPE_INSTANCE_GET_PRIVATE (widget
,
121 struct GtkFixedPrivateL
);
122 //fixed->priv = G_TYPE_INSTANCE_GET_PRIVATE (fixed, GTK_TYPE_FIXED, GtkFixedPrivate);
123 //then modify allocations
124 /* gtk_container_foreach (widget, */
128 //begin copy paste extravaganza!!!
130 //GtkFixed *fixed = GTK_FIXED (widget);
131 //GtkFixedPrivate *priv = fixed->priv;
134 gtk_widget_set_allocation (widget
, allocation
);
136 if (gtk_widget_get_has_window (widget
))
138 if (gtk_widget_get_realized (widget
))
139 gdk_window_move_resize (gtk_widget_get_window (widget
),
146 for (children
= priv
->children
;
148 children
= children
->next
)
150 child
= children
->data
;
152 if (!gtk_widget_get_visible (child
->widget
))
155 gtk_widget_get_preferred_size (child
->widget
, &child_requisition
, NULL
);
156 child_allocation
.x
= child
->x
;
157 child_allocation
.y
= child
->y
;
159 if (!gtk_widget_get_has_window (widget
))
161 child_allocation
.x
+= allocation
->x
;
162 child_allocation
.y
+= allocation
->y
;
165 child_allocation
.width
= child_requisition
.width
;
166 child_allocation
.height
= child_requisition
.height
;
170 xv
= (struct xwidget_view
*) g_object_get_data (G_OBJECT (child
->widget
), XG_XWIDGET_VIEW
);
171 //printf("aloc callback %d %s\n", xv, gtk_widget_get_name(child));
173 //gtk_widget_get_allocation(child, &child_allocation);
174 child_allocation
.width
= xv
->clip_right
;
175 child_allocation
.height
= xv
->clip_bottom
- xv
->clip_top
;
176 //gtk_widget_size_allocate (child, &child_allocation);
177 //TODO find a way to remove this feeble workaround
178 // printf(" allocation internal modification for xw %d %d,%d\n",xv, child_allocation.width, child_allocation.height);
181 gtk_widget_size_allocate (child
->widget
, &child_allocation
);
190 emacs_fixed_class_init (EmacsFixedClass
*klass
)
192 GtkWidgetClass
*widget_class
;
193 GtkFixedClass
*fixed_class
;
195 widget_class
= (GtkWidgetClass
*) klass
;
196 fixed_class
= (GtkFixedClass
*) klass
;
198 widget_class
->get_preferred_width
= emacs_fixed_get_preferred_width
;
199 widget_class
->get_preferred_height
= emacs_fixed_get_preferred_height
;
201 widget_class
->size_allocate
= emacs_fixed_gtk_widget_size_allocate
;
203 g_type_class_add_private (klass
, sizeof (EmacsFixedPrivate
));
207 emacs_fixed_child_type (GtkFixed
*container
)
209 return GTK_TYPE_WIDGET
;
213 emacs_fixed_init (EmacsFixed
*fixed
)
215 fixed
->priv
= G_TYPE_INSTANCE_GET_PRIVATE (fixed
, EMACS_TYPE_FIXED
,
223 * Creates a new #EmacsFixed.
225 * Returns: a new #EmacsFixed.
228 emacs_fixed_new (struct frame
*f
)
230 EmacsFixed
*fixed
= g_object_new (EMACS_TYPE_FIXED
, NULL
);
231 EmacsFixedPrivate
*priv
= fixed
->priv
;
233 return GTK_WIDGET (fixed
);
237 emacs_fixed_get_preferred_width (GtkWidget
*widget
,
241 EmacsFixed
*fixed
= EMACS_FIXED (widget
);
242 EmacsFixedPrivate
*priv
= fixed
->priv
;
243 int w
= priv
->f
->output_data
.x
->size_hints
.min_width
;
244 if (minimum
) *minimum
= w
;
245 if (natural
) *natural
= w
;
249 emacs_fixed_get_preferred_height (GtkWidget
*widget
,
253 EmacsFixed
*fixed
= EMACS_FIXED (widget
);
254 EmacsFixedPrivate
*priv
= fixed
->priv
;
255 int h
= priv
->f
->output_data
.x
->size_hints
.min_height
;
256 if (minimum
) *minimum
= h
;
257 if (natural
) *natural
= h
;
261 /* Override the X function so we can intercept Gtk+ 3 calls.
262 Use our values for min_width/height so that KDE don't freak out
263 (Bug#8919), and so users can resize our frames as they wish. */
266 XSetWMSizeHints (Display
* d
,
271 struct x_display_info
*dpyinfo
= x_display_info_for_display (d
);
272 struct frame
*f
= x_top_window_to_frame (dpyinfo
, w
);
274 data
[0] = hints
->flags
;
277 data
[3] = hints
->width
;
278 data
[4] = hints
->height
;
279 data
[5] = hints
->min_width
;
280 data
[6] = hints
->min_height
;
281 data
[7] = hints
->max_width
;
282 data
[8] = hints
->max_height
;
283 data
[9] = hints
->width_inc
;
284 data
[10] = hints
->height_inc
;
285 data
[11] = hints
->min_aspect
.x
;
286 data
[12] = hints
->min_aspect
.y
;
287 data
[13] = hints
->max_aspect
.x
;
288 data
[14] = hints
->max_aspect
.y
;
289 data
[15] = hints
->base_width
;
290 data
[16] = hints
->base_height
;
291 data
[17] = hints
->win_gravity
;
293 if ((hints
->flags
& PMinSize
) && f
)
295 int w
= f
->output_data
.x
->size_hints
.min_width
;
296 int h
= f
->output_data
.x
->size_hints
.min_height
;
301 XChangeProperty (d
, w
, prop
, XA_WM_SIZE_HINTS
, 32, PropModeReplace
,
302 (unsigned char *) data
, 18);
305 /* Override this X11 function.
306 This function is in the same X11 file as the one above. So we must
310 XSetWMNormalHints (Display
*d
, Window w
, XSizeHints
*hints
)
312 XSetWMSizeHints (d
, w
, hints
, XA_WM_NORMAL_HINTS
);