Compare commits
2 Commits
main
...
wip/baeder
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1aec8a0672 | ||
|
|
73747dafe4 |
@@ -413,7 +413,6 @@ gdk_frame_clock_paint_idle (void *data)
|
||||
case GDK_FRAME_CLOCK_PHASE_LAYOUT:
|
||||
if (priv->freeze_count == 0)
|
||||
{
|
||||
int iter;
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GDK_DEBUG_CHECK (FRAMES))
|
||||
{
|
||||
@@ -424,20 +423,8 @@ gdk_frame_clock_paint_idle (void *data)
|
||||
#endif /* G_ENABLE_DEBUG */
|
||||
|
||||
priv->phase = GDK_FRAME_CLOCK_PHASE_LAYOUT;
|
||||
/* We loop in the layout phase, because we don't want to progress
|
||||
* into the paint phase with invalid size allocations. This may
|
||||
* happen in some situation like races between user window
|
||||
* resizes and natural size changes.
|
||||
*/
|
||||
iter = 0;
|
||||
while ((priv->requested & GDK_FRAME_CLOCK_PHASE_LAYOUT) &&
|
||||
priv->freeze_count == 0 && iter++ < 4)
|
||||
{
|
||||
priv->requested &= ~GDK_FRAME_CLOCK_PHASE_LAYOUT;
|
||||
_gdk_frame_clock_emit_layout (clock);
|
||||
}
|
||||
if (iter == 5)
|
||||
g_warning ("gdk-frame-clock: layout continuously requested, giving up after 4 tries");
|
||||
priv->requested &= ~GDK_FRAME_CLOCK_PHASE_LAYOUT;
|
||||
_gdk_frame_clock_emit_layout (clock);
|
||||
}
|
||||
/* fallthrough */
|
||||
case GDK_FRAME_CLOCK_PHASE_PAINT:
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include "gtkwindow.h"
|
||||
|
||||
#include "a11y/gtkcontaineraccessibleprivate.h"
|
||||
#include "gtkwindowprivate.h"
|
||||
|
||||
#include <gobject/gobjectnotifyqueue.c>
|
||||
#include <gobject/gvaluecollector.h>
|
||||
@@ -59,6 +60,9 @@
|
||||
GTK_IS_SHORTCUTS_SECTION (x) || \
|
||||
GTK_IS_SHORTCUTS_WINDOW (x))
|
||||
|
||||
|
||||
#define N_RESIZE_ITERATIONS 2
|
||||
|
||||
/**
|
||||
* SECTION:gtkcontainer
|
||||
* @Short_description: Base class for widgets which contain other widgets
|
||||
@@ -159,6 +163,7 @@ struct _GtkContainerPrivate
|
||||
|
||||
guint has_focus_chain : 1;
|
||||
guint restyle_pending : 1;
|
||||
guint last_size_allocate : 1;
|
||||
};
|
||||
|
||||
enum {
|
||||
@@ -1556,11 +1561,54 @@ gtk_container_needs_idle_sizer (GtkContainer *container)
|
||||
return gtk_widget_needs_allocate (GTK_WIDGET (container));
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_container_doing_last_size_allocate (GtkContainer *container)
|
||||
{
|
||||
GtkContainerPrivate *priv = gtk_container_get_instance_private (container);
|
||||
|
||||
return priv->last_size_allocate;
|
||||
}
|
||||
|
||||
static void
|
||||
apply_resize_widgets (GtkWindow *window)
|
||||
{
|
||||
GPtrArray *resize_widgets = gtk_window_get_resize_widgets (window);
|
||||
GPtrArray *allocate_widgets = gtk_window_get_allocate_widgets (window);
|
||||
guint i, p;
|
||||
|
||||
g_message ("Resize widgets : %u", resize_widgets->len);
|
||||
for (i = 0, p = resize_widgets->len; i < p; i ++)
|
||||
{
|
||||
GtkWidget *widget = g_ptr_array_index (resize_widgets, i);
|
||||
g_message (" - %s %p", G_OBJECT_TYPE_NAME (widget), widget);
|
||||
_gtk_widget_queue_resize (widget);
|
||||
|
||||
g_object_unref (G_OBJECT (widget));
|
||||
}
|
||||
|
||||
g_message ("Allocate widgets: %u", allocate_widgets->len);
|
||||
for (i = 0, p = allocate_widgets->len; i < p; i ++)
|
||||
{
|
||||
GtkWidget *widget = g_ptr_array_index (allocate_widgets, i);
|
||||
g_message (" - %s %p", G_OBJECT_TYPE_NAME (widget), widget);
|
||||
_gtk_widget_queue_allocate (widget);
|
||||
|
||||
g_object_unref (G_OBJECT (widget));
|
||||
}
|
||||
|
||||
g_ptr_array_remove_range (resize_widgets, 0, resize_widgets->len);
|
||||
g_ptr_array_remove_range (allocate_widgets, 0, allocate_widgets->len);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_container_idle_sizer (GdkFrameClock *clock,
|
||||
GtkContainer *container)
|
||||
{
|
||||
GtkContainerPrivate *priv = gtk_container_get_instance_private (container);
|
||||
guint resize_iteration;
|
||||
|
||||
static int k;
|
||||
g_message ("####### %d Idle Sizer for %s", ++k, G_OBJECT_TYPE_NAME (container));
|
||||
|
||||
/* We validate the style contexts in a single loop before even trying
|
||||
* to handle resizes instead of doing validations inline.
|
||||
@@ -1584,9 +1632,52 @@ gtk_container_idle_sizer (GdkFrameClock *clock,
|
||||
* than trying to explicitly work around them with some extra flags,
|
||||
* since it doesn't cause any actual harm.
|
||||
*/
|
||||
if (gtk_widget_needs_allocate (GTK_WIDGET (container)))
|
||||
for (resize_iteration = 0; resize_iteration < N_RESIZE_ITERATIONS; resize_iteration ++)
|
||||
{
|
||||
gtk_container_check_resize (container);
|
||||
const gboolean last_iteration = (resize_iteration == N_RESIZE_ITERATIONS - 1);
|
||||
|
||||
if (GTK_IS_WINDOW (container))
|
||||
apply_resize_widgets (GTK_WINDOW (container));
|
||||
|
||||
if (last_iteration)
|
||||
priv->last_size_allocate = TRUE;
|
||||
|
||||
if (gtk_widget_needs_allocate (GTK_WIDGET (container)))
|
||||
gtk_container_check_resize (container);
|
||||
|
||||
if (last_iteration)
|
||||
priv->last_size_allocate = FALSE;
|
||||
}
|
||||
|
||||
if (GTK_IS_WINDOW (container))
|
||||
{
|
||||
GPtrArray *resize_widgets = gtk_window_get_resize_widgets (GTK_WINDOW (container));
|
||||
GPtrArray *allocate_widgets = gtk_window_get_allocate_widgets (GTK_WINDOW (container));
|
||||
|
||||
/* Explicitly drop all resize/allocate widgets still present after the above loop */
|
||||
if (resize_widgets->len > 0 || allocate_widgets->len > 0)
|
||||
{
|
||||
g_warning ("AFTER size-allocate No. %d:", N_RESIZE_ITERATIONS);
|
||||
guint i, p;
|
||||
|
||||
g_message ("Resize widgets : %u", resize_widgets->len);
|
||||
for (i = 0, p = resize_widgets->len; i < p; i ++)
|
||||
{
|
||||
GtkWidget *widget = g_ptr_array_index (resize_widgets, i);
|
||||
g_message (" - %s %p", G_OBJECT_TYPE_NAME (widget), widget);
|
||||
}
|
||||
|
||||
g_message ("Allocate widgets: %u", allocate_widgets->len);
|
||||
for (i = 0, p = allocate_widgets->len; i < p; i ++)
|
||||
{
|
||||
GtkWidget *widget = g_ptr_array_index (allocate_widgets, i);
|
||||
g_message (" - %s %p", G_OBJECT_TYPE_NAME (widget), widget);
|
||||
}
|
||||
|
||||
/* Ignore every queue_resize and queue_allocate after the second iteration. */
|
||||
g_ptr_array_remove_range (resize_widgets, 0, resize_widgets->len);
|
||||
g_ptr_array_remove_range (allocate_widgets, 0, allocate_widgets->len);
|
||||
}
|
||||
}
|
||||
|
||||
if (!gtk_container_needs_idle_sizer (container))
|
||||
@@ -1642,7 +1733,6 @@ gtk_container_queue_resize_handler (GtkContainer *container)
|
||||
widget = GTK_WIDGET (container);
|
||||
|
||||
if (_gtk_widget_get_visible (widget) &&
|
||||
gtk_widget_needs_allocate (widget) &&
|
||||
_gtk_widget_is_toplevel (widget))
|
||||
{
|
||||
gtk_container_start_idle_sizer (container);
|
||||
|
||||
@@ -33,6 +33,7 @@ void _gtk_container_stop_idle_sizer (GtkContainer *container);
|
||||
void _gtk_container_maybe_start_idle_sizer (GtkContainer *container);
|
||||
void gtk_container_set_focus_child (GtkContainer *container,
|
||||
GtkWidget *child);
|
||||
gboolean gtk_container_doing_last_size_allocate (GtkContainer *container);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@@ -3225,6 +3225,8 @@ gtk_widget_unparent (GtkWidget *widget)
|
||||
priv->clip.width,
|
||||
priv->clip.height);
|
||||
|
||||
gtk_widget_dequeue_resize (widget);
|
||||
|
||||
if (priv->visible && _gtk_widget_get_visible (priv->parent))
|
||||
gtk_widget_queue_resize (priv->parent);
|
||||
|
||||
@@ -3411,8 +3413,6 @@ gtk_widget_show (GtkWidget *widget)
|
||||
parent = _gtk_widget_get_parent (widget);
|
||||
if (parent)
|
||||
{
|
||||
gtk_widget_queue_resize (parent);
|
||||
|
||||
/* see comment in set_parent() for why this should and can be
|
||||
* conditional
|
||||
*/
|
||||
@@ -3428,6 +3428,7 @@ gtk_widget_show (GtkWidget *widget)
|
||||
g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_VISIBLE]);
|
||||
|
||||
gtk_widget_pop_verify_invariants (widget);
|
||||
gtk_widget_queue_resize (widget);
|
||||
g_object_unref (widget);
|
||||
}
|
||||
}
|
||||
@@ -3487,9 +3488,9 @@ gtk_widget_hide (GtkWidget *widget)
|
||||
|
||||
parent = gtk_widget_get_parent (widget);
|
||||
if (parent)
|
||||
gtk_widget_queue_resize (parent);
|
||||
gtk_widget_queue_resize (parent);
|
||||
|
||||
gtk_widget_queue_allocate (widget);
|
||||
gtk_widget_dequeue_resize (widget);
|
||||
|
||||
gtk_widget_pop_verify_invariants (widget);
|
||||
g_object_unref (widget);
|
||||
@@ -4066,10 +4067,16 @@ gtk_widget_queue_allocate (GtkWidget *widget)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
|
||||
|
||||
if (_gtk_widget_get_realized (widget))
|
||||
gtk_widget_queue_draw (widget);
|
||||
|
||||
gtk_widget_set_alloc_needed (widget);
|
||||
GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
|
||||
if (GTK_IS_WINDOW (toplevel))
|
||||
{
|
||||
gtk_window_add_allocate_widget (GTK_WINDOW (toplevel), widget);
|
||||
gtk_container_queue_resize_handler (GTK_CONTAINER (toplevel));
|
||||
}
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
@@ -4140,9 +4147,45 @@ gtk_widget_queue_resize (GtkWidget *widget)
|
||||
if (_gtk_widget_get_realized (widget))
|
||||
gtk_widget_queue_draw (widget);
|
||||
|
||||
GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
|
||||
if (GTK_IS_WINDOW (toplevel))
|
||||
{
|
||||
|
||||
if (gtk_container_doing_last_size_allocate (GTK_CONTAINER (toplevel)))
|
||||
{
|
||||
g_warning ("%s in last size-allocate iteration!", __FUNCTION__);
|
||||
}
|
||||
|
||||
gtk_window_add_resize_widget (GTK_WINDOW (toplevel), widget);
|
||||
gtk_container_queue_resize_handler (GTK_CONTAINER (toplevel));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gtk_widget_dequeue_resize (GtkWidget *widget)
|
||||
{
|
||||
GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
|
||||
if (GTK_IS_WINDOW (toplevel))
|
||||
{
|
||||
gtk_window_dequeue_resize_for (GTK_WINDOW (toplevel), widget);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_widget_queue_resize (GtkWidget *widget)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
|
||||
gtk_widget_queue_resize_internal (widget);
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_widget_queue_allocate (GtkWidget *widget)
|
||||
{
|
||||
gtk_widget_set_alloc_needed (widget);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gtk_widget_queue_resize_no_redraw:
|
||||
* @widget: a #GtkWidget
|
||||
@@ -4155,7 +4198,11 @@ gtk_widget_queue_resize_no_redraw (GtkWidget *widget)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
|
||||
gtk_widget_queue_resize_internal (widget);
|
||||
GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
|
||||
if (GTK_IS_WINDOW (toplevel))
|
||||
{
|
||||
gtk_window_add_resize_widget (GTK_WINDOW (toplevel), widget);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -7337,7 +7384,7 @@ gtk_widget_reposition_after (GtkWidget *widget,
|
||||
_gtk_widget_get_mapped (priv->parent))
|
||||
gtk_widget_map (widget);
|
||||
|
||||
gtk_widget_queue_resize (priv->parent);
|
||||
gtk_widget_queue_resize (widget);
|
||||
}
|
||||
|
||||
/* child may cause parent's expand to change, if the child is
|
||||
|
||||
@@ -333,10 +333,14 @@ void gtk_widget_init_legacy_controller (GtkWidget *widget);
|
||||
void gtk_widget_get_origin_relative_to_parent (GtkWidget *widget,
|
||||
int *origin_x,
|
||||
int *origin_y);
|
||||
void gtk_widget_dequeue_resize (GtkWidget *widget);
|
||||
|
||||
|
||||
|
||||
|
||||
void _gtk_widget_queue_resize (GtkWidget *widget);
|
||||
void _gtk_widget_queue_allocate (GtkWidget *widget);
|
||||
|
||||
/* inline getters */
|
||||
|
||||
static inline GtkWidget *
|
||||
|
||||
@@ -204,6 +204,9 @@ struct _GtkWindowPrivate
|
||||
|
||||
GdkModifierType mnemonic_modifier;
|
||||
|
||||
GPtrArray *resize_widgets;
|
||||
GPtrArray *allocate_widgets;
|
||||
|
||||
gchar *startup_id;
|
||||
gchar *title;
|
||||
gchar *wm_role;
|
||||
@@ -1889,6 +1892,9 @@ gtk_window_init (GtkWindow *window)
|
||||
priv = window->priv;
|
||||
|
||||
gtk_widget_set_has_surface (widget, TRUE);
|
||||
priv->resize_widgets = g_ptr_array_new ();
|
||||
priv->allocate_widgets = g_ptr_array_new ();
|
||||
|
||||
_gtk_widget_set_is_toplevel (widget, TRUE);
|
||||
_gtk_widget_set_anchored (widget, TRUE);
|
||||
|
||||
@@ -11449,3 +11455,71 @@ gtk_window_maybe_update_cursor (GtkWindow *window,
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gtk_window_add_resize_widget (GtkWindow *window,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
|
||||
|
||||
g_ptr_array_add (priv->resize_widgets, g_object_ref (G_OBJECT (widget)));
|
||||
}
|
||||
|
||||
void
|
||||
gtk_window_add_allocate_widget (GtkWindow *window,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
|
||||
|
||||
g_ptr_array_add (priv->allocate_widgets, g_object_ref (G_OBJECT (widget)));
|
||||
}
|
||||
|
||||
void
|
||||
gtk_window_dequeue_resize_for (GtkWindow *window,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < priv->resize_widgets->len; i ++)
|
||||
{
|
||||
GtkWidget *w = g_ptr_array_index (priv->resize_widgets, i);
|
||||
|
||||
if (w == widget)
|
||||
{
|
||||
g_ptr_array_remove_index (priv->resize_widgets, i);
|
||||
i --;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < priv->allocate_widgets->len; i ++)
|
||||
{
|
||||
GtkWidget *w = g_ptr_array_index (priv->allocate_widgets, i);
|
||||
|
||||
if (w == widget)
|
||||
{
|
||||
g_ptr_array_remove_index (priv->allocate_widgets, i);
|
||||
i --;
|
||||
}
|
||||
}
|
||||
|
||||
if (priv->resize_widgets->len == 0 &&
|
||||
priv->allocate_widgets->len == 0)
|
||||
_gtk_container_stop_idle_sizer (GTK_CONTAINER (window));
|
||||
}
|
||||
|
||||
GPtrArray *
|
||||
gtk_window_get_resize_widgets (GtkWindow *window)
|
||||
{
|
||||
GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
|
||||
|
||||
return priv->resize_widgets;
|
||||
}
|
||||
|
||||
GPtrArray *
|
||||
gtk_window_get_allocate_widgets (GtkWindow *window)
|
||||
{
|
||||
GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
|
||||
|
||||
return priv->allocate_widgets;
|
||||
}
|
||||
|
||||
@@ -164,6 +164,18 @@ void gtk_window_maybe_update_cursor (GtkWindow *window,
|
||||
GtkWidget *widget,
|
||||
GdkDevice *device);
|
||||
|
||||
|
||||
void gtk_window_add_resize_widget (GtkWindow *window,
|
||||
GtkWidget *widget);
|
||||
void gtk_window_add_allocate_widget (GtkWindow *window,
|
||||
GtkWidget *widget);
|
||||
|
||||
void gtk_window_dequeue_resize_for (GtkWindow *window,
|
||||
GtkWidget *widget);
|
||||
|
||||
GPtrArray *gtk_window_get_resize_widgets (GtkWindow *window);
|
||||
GPtrArray *gtk_window_get_allocate_widgets (GtkWindow *window);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_WINDOW_PRIVATE_H__ */
|
||||
|
||||
@@ -130,6 +130,7 @@ gtk_tests = [
|
||||
['testoutsetshadowdrawing'],
|
||||
['testblur'],
|
||||
['testtexture'],
|
||||
['testsizeallocate'],
|
||||
]
|
||||
|
||||
if os_linux
|
||||
|
||||
184
tests/testsizeallocate.c
Normal file
184
tests/testsizeallocate.c
Normal file
@@ -0,0 +1,184 @@
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
const char *css =
|
||||
"resizewidget {"
|
||||
" background-color: yellow;"
|
||||
"}"
|
||||
"resizewidget button:first-child {"
|
||||
" border-top-left-radius: 50%;"
|
||||
"}"
|
||||
"resizewidget button:last-child {"
|
||||
" border-bottom-right-radius: 50%;"
|
||||
"}";
|
||||
|
||||
|
||||
typedef struct _GtkResizeWidget GtkResizeWidget;
|
||||
typedef struct _GtkResizeWidgetClass GtkResizeWidgetClass;
|
||||
|
||||
#define GTK_TYPE_RESIZE_WIDGET (gtk_resize_widget_get_type ())
|
||||
#define GTK_RESIZE_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST(obj, GTK_TYPE_RESIZE_WIDGET, GtkResizeWidget))
|
||||
#define GTK_RESIZE_WIDGET_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST(cls, GTK_TYPE_RESIZE_WIDGET, GtkResizeWidgetClass))
|
||||
#define GTK_IS_RESIZE_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE(obj, GTK_TYPE_RESIZE_WIDGET))
|
||||
#define GTK_IS_RESIZE_WIDGET_CLASS(cls) (G_TYPE_CHECK_CLASS_TYPE(cls, GTK_TYPE_RESIZE_WIDGET))
|
||||
#define GTK_RESIZE_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS(obj, GTK_TYPE_RESIZE_WIDGET, GtkResizeWidgetClass))
|
||||
|
||||
struct _GtkResizeWidget
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
|
||||
GtkWidget *buttons[2];
|
||||
};
|
||||
|
||||
struct _GtkResizeWidgetClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
};
|
||||
|
||||
GType gtk_resize_widget_get_type (void) G_GNUC_CONST;
|
||||
|
||||
|
||||
G_DEFINE_TYPE(GtkResizeWidget, gtk_resize_widget, GTK_TYPE_WIDGET)
|
||||
|
||||
|
||||
static void
|
||||
gtk_resize_widget_measure (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
int for_size,
|
||||
int *minimum,
|
||||
int *natural,
|
||||
int *minimum_baseline,
|
||||
int *natural_baseline)
|
||||
{
|
||||
GtkResizeWidget *self = GTK_RESIZE_WIDGET (widget);
|
||||
int i;
|
||||
|
||||
/* Just add everything up */
|
||||
|
||||
*minimum = 0;
|
||||
*natural = 0;
|
||||
|
||||
for (i = 0; i < 2; i ++)
|
||||
{
|
||||
int m, n;
|
||||
|
||||
gtk_widget_measure (self->buttons[i], orientation, for_size,
|
||||
&m, &n, minimum_baseline, natural_baseline);
|
||||
|
||||
/* Ignore minimum size. You know why. */
|
||||
if (i == 0)
|
||||
*minimum += m;
|
||||
|
||||
*natural += n;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gtk_resize_widget_size_allocate (GtkWidget *widget,
|
||||
const GtkAllocation *allocation,
|
||||
int baseline,
|
||||
GtkAllocation *out_clip)
|
||||
{
|
||||
static int k;
|
||||
GtkResizeWidget *self = GTK_RESIZE_WIDGET (widget);
|
||||
GtkAllocation child_alloc;
|
||||
GtkAllocation clip;
|
||||
int m, n;
|
||||
int remaining_width = allocation->width;
|
||||
|
||||
g_message ("%s: %i", __FUNCTION__, k++);
|
||||
|
||||
|
||||
gtk_widget_measure (self->buttons[0], GTK_ORIENTATION_HORIZONTAL, -1,
|
||||
&m, &n, NULL, NULL);
|
||||
|
||||
child_alloc.x = 0;
|
||||
child_alloc.y = 0;
|
||||
child_alloc.width = m;
|
||||
child_alloc.height = allocation->height;
|
||||
gtk_widget_size_allocate (self->buttons[0], &child_alloc, -1, &clip);
|
||||
|
||||
remaining_width -= child_alloc.width;
|
||||
|
||||
gtk_widget_measure (self->buttons[1], GTK_ORIENTATION_HORIZONTAL, -1,
|
||||
&m, &n, NULL, NULL);
|
||||
|
||||
if (remaining_width < m)
|
||||
{
|
||||
gtk_widget_hide (self->buttons[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_widget_show (self->buttons[1]);
|
||||
gtk_widget_measure (self->buttons[1], GTK_ORIENTATION_HORIZONTAL, -1,
|
||||
&m, &n, NULL, NULL);
|
||||
|
||||
/* Still? */
|
||||
if (remaining_width > m)
|
||||
{
|
||||
child_alloc.x += child_alloc.width;
|
||||
child_alloc.width = m;
|
||||
gtk_widget_size_allocate (self->buttons[1], &child_alloc, -1, &clip);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Shame. */
|
||||
gtk_widget_hide (self->buttons[1]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gtk_resize_widget_init (GtkResizeWidget *self)
|
||||
{
|
||||
gtk_widget_set_has_surface (GTK_WIDGET (self), FALSE);
|
||||
|
||||
self->buttons[0] = gtk_button_new_with_label ("First");
|
||||
self->buttons[1] = gtk_button_new_with_label ("Second");
|
||||
|
||||
gtk_widget_set_parent (self->buttons[0], GTK_WIDGET (self));
|
||||
gtk_widget_set_parent (self->buttons[1], GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_resize_widget_class_init (GtkResizeWidgetClass *klass)
|
||||
{
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
widget_class->measure = gtk_resize_widget_measure;
|
||||
widget_class->size_allocate = gtk_resize_widget_size_allocate;
|
||||
|
||||
gtk_widget_class_set_css_name (widget_class, "resizewidget");
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
GtkWidget *window;
|
||||
GtkWidget *widget;
|
||||
GtkCssProvider *provider;
|
||||
|
||||
gtk_init ();
|
||||
|
||||
provider = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_data (provider, css, -1);
|
||||
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
|
||||
GTK_STYLE_PROVIDER (provider),
|
||||
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
widget = g_object_new (GTK_TYPE_RESIZE_WIDGET, NULL);
|
||||
|
||||
gtk_window_set_decorated (GTK_WINDOW (window), FALSE);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (window), widget);
|
||||
g_signal_connect (window, "close-request", G_CALLBACK (gtk_main_quit), NULL);
|
||||
|
||||
gtk_widget_show (window);
|
||||
|
||||
gtk_main ();
|
||||
}
|
||||
Reference in New Issue
Block a user