window: Derive from GtkWidget

We want to remove GtkBin and GtkContainer as they don't
provide much useful functionality anymore. This requires
us to move get_request_mode and compute_expand down.

Update the accessible implementation to match, remove
remnants of container implementations in GtkWindow
subclasses, and fix livecycle issues around destroy
vs dispose in GtkAssistant.

After this commit, using gtk_container_add on window
subclasses is not allowed anymore, but adding childing
with <child> in ui files still works.

See #2681
This commit is contained in:
Matthias Clasen 2020-05-02 15:17:20 -04:00
parent f59f355190
commit 9a65ed9ada
7 changed files with 154 additions and 327 deletions

View File

@ -46,7 +46,7 @@ static void atk_window_interface_init (AtkWindowIface *iface);
G_DEFINE_TYPE_WITH_CODE (GtkWindowAccessible,
gtk_window_accessible,
GTK_TYPE_CONTAINER_ACCESSIBLE,
GTK_TYPE_WIDGET_ACCESSIBLE,
G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT,
atk_component_interface_init)
G_IMPLEMENT_INTERFACE (ATK_TYPE_WINDOW,
@ -76,33 +76,6 @@ gtk_window_accessible_notify_gtk (GObject *obj,
GTK_WIDGET_ACCESSIBLE_CLASS (gtk_window_accessible_parent_class)->notify_gtk (obj, pspec);
}
static GtkWidget *
find_label_child (GtkContainer *container)
{
GList *children, *tmp_list;
GtkWidget *child;
children = gtk_container_get_children (container);
child = NULL;
for (tmp_list = children; tmp_list != NULL; tmp_list = tmp_list->next)
{
if (GTK_IS_LABEL (tmp_list->data))
{
child = GTK_WIDGET (tmp_list->data);
break;
}
else if (GTK_IS_CONTAINER (tmp_list->data))
{
child = find_label_child (GTK_CONTAINER (tmp_list->data));
if (child)
break;
}
}
g_list_free (children);
return child;
}
static const gchar *
gtk_window_accessible_get_name (AtkObject *accessible)
{
@ -236,29 +209,19 @@ gtk_window_accessible_ref_state_set (AtkObject *accessible)
return state_set;
}
static void
count_widget (GtkWidget *widget,
gint *count)
{
(*count)++;
}
static void
prepend_widget (GtkWidget *widget,
GList **list)
{
*list = g_list_prepend (*list, widget);
}
static gint
gtk_window_accessible_get_n_children (AtkObject *object)
{
GtkWidget *window;
GtkWidget *child;
gint count = 0;
window = gtk_accessible_get_widget (GTK_ACCESSIBLE (object));
gtk_container_forall (GTK_CONTAINER (window),
(GtkCallback) count_widget, &count);
for (child = gtk_widget_get_first_child (GTK_WIDGET (window));
child != NULL;
child = gtk_widget_get_next_sibling (child))
count++;
return count;
}
@ -266,19 +229,19 @@ static AtkObject *
gtk_window_accessible_ref_child (AtkObject *object,
gint i)
{
GtkWidget *window, *ref_child;
GList *children = NULL;
GtkWidget *window, *child;
int pos;
window = gtk_accessible_get_widget (GTK_ACCESSIBLE (object));
gtk_container_forall (GTK_CONTAINER (window),
(GtkCallback) prepend_widget, &children);
ref_child = g_list_nth_data (children, i);
g_list_free (children);
for (child = gtk_widget_get_first_child (GTK_WIDGET (window)), pos = 0;
child != NULL;
child = gtk_widget_get_next_sibling (child), pos++)
{
if (pos == i)
return g_object_ref (gtk_widget_get_accessible (child));
}
if (!ref_child)
return NULL;
return g_object_ref (gtk_widget_get_accessible (ref_child));
return NULL;
}
static void

View File

@ -591,7 +591,7 @@ gtk_application_window_real_size_allocate (GtkWidget *widget,
child_allocation.y += menubar_height;
child_allocation.height -= menubar_height;
child = gtk_bin_get_child (GTK_BIN (window));
child = gtk_window_get_child (GTK_WINDOW (window));
if (child != NULL && gtk_widget_get_visible (child))
gtk_widget_size_allocate (child, &child_allocation, baseline);
}
@ -668,21 +668,6 @@ gtk_application_window_real_unmap (GtkWidget *widget)
GTK_WIDGET_CLASS (gtk_application_window_parent_class)->unmap (widget);
}
static void
gtk_application_window_real_forall_internal (GtkContainer *container,
GtkCallback callback,
gpointer user_data)
{
GtkApplicationWindow *window = GTK_APPLICATION_WINDOW (container);
GtkApplicationWindowPrivate *priv = gtk_application_window_get_instance_private (window);
if (priv->menubar)
callback (priv->menubar, user_data);
GTK_CONTAINER_CLASS (gtk_application_window_parent_class)
->forall (container, callback, user_data);
}
static void
gtk_application_window_get_property (GObject *object,
guint prop_id,
@ -782,12 +767,9 @@ gtk_application_window_init (GtkApplicationWindow *window)
static void
gtk_application_window_class_init (GtkApplicationWindowClass *class)
{
GtkContainerClass *container_class = GTK_CONTAINER_CLASS (class);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
GObjectClass *object_class = G_OBJECT_CLASS (class);
container_class->forall = gtk_application_window_real_forall_internal;
widget_class->measure = gtk_application_window_measure;
widget_class->size_allocate = gtk_application_window_real_size_allocate;
widget_class->realize = gtk_application_window_real_realize;

View File

@ -159,15 +159,11 @@ struct _GtkAssistantPrivate
guint committed : 1;
};
static void gtk_assistant_destroy (GtkWidget *widget);
static void gtk_assistant_dispose (GObject *object);
static void gtk_assistant_map (GtkWidget *widget);
static void gtk_assistant_unmap (GtkWidget *widget);
static gboolean gtk_assistant_close_request (GtkWindow *window);
static void gtk_assistant_add (GtkContainer *container,
GtkWidget *page);
static void gtk_assistant_remove (GtkContainer *container,
GtkWidget *page);
static void gtk_assistant_page_set_property (GObject *object,
guint property_id,
const GValue *value,
@ -208,10 +204,6 @@ static void on_assistant_cancel (GtkWidget *wi
GtkAssistant *assistant);
static void on_assistant_last (GtkWidget *widget,
GtkAssistant *assistant);
static void assistant_remove_page_cb (GtkContainer *container,
GtkWidget *page,
GtkAssistant *assistant);
static int gtk_assistant_add_page (GtkAssistant *assistant,
GtkAssistantPage *page_info,
@ -507,28 +499,23 @@ gtk_assistant_class_init (GtkAssistantClass *class)
{
GObjectClass *gobject_class;
GtkWidgetClass *widget_class;
GtkContainerClass *container_class;
GtkWindowClass *window_class;
gobject_class = (GObjectClass *) class;
widget_class = (GtkWidgetClass *) class;
container_class = (GtkContainerClass *) class;
window_class = (GtkWindowClass *) class;
gobject_class->dispose = gtk_assistant_dispose;
gobject_class->finalize = gtk_assistant_finalize;
gobject_class->constructed = gtk_assistant_constructed;
gobject_class->set_property = gtk_assistant_set_property;
gobject_class->get_property = gtk_assistant_get_property;
widget_class->destroy = gtk_assistant_destroy;
widget_class->map = gtk_assistant_map;
widget_class->unmap = gtk_assistant_unmap;
gtk_widget_class_set_accessible_type (widget_class, _gtk_assistant_accessible_get_type ());
container_class->add = gtk_assistant_add;
container_class->remove = gtk_assistant_remove;
window_class->close_request = gtk_assistant_close_request;
/**
@ -665,7 +652,6 @@ gtk_assistant_class_init (GtkAssistantClass *class)
gtk_widget_class_bind_template_child_private (widget_class, GtkAssistant, button_size_group);
gtk_widget_class_bind_template_child_private (widget_class, GtkAssistant, title_size_group);
gtk_widget_class_bind_template_callback (widget_class, assistant_remove_page_cb);
gtk_widget_class_bind_template_callback (widget_class, on_assistant_close);
gtk_widget_class_bind_template_callback (widget_class, on_assistant_apply);
gtk_widget_class_bind_template_callback (widget_class, on_assistant_forward);
@ -1134,9 +1120,8 @@ on_page_notify (GtkAssistantPage *page,
}
static void
assistant_remove_page_cb (GtkContainer *container,
GtkWidget *page,
GtkAssistant *assistant)
assistant_remove_page (GtkAssistant *assistant,
GtkWidget *page)
{
GtkAssistantPrivate *priv = gtk_assistant_get_instance_private (assistant);
GtkAssistantPage *page_info;
@ -1337,9 +1322,9 @@ gtk_assistant_page_get_property (GObject *object,
}
static void
gtk_assistant_destroy (GtkWidget *widget)
gtk_assistant_dispose (GObject *object)
{
GtkAssistant *assistant = GTK_ASSISTANT (widget);
GtkAssistant *assistant = GTK_ASSISTANT (object);
GtkAssistantPrivate *priv = gtk_assistant_get_instance_private (assistant);
if (priv->model)
@ -1352,27 +1337,14 @@ gtk_assistant_destroy (GtkWidget *widget)
if (priv->content)
{
GList *children, *l;
children = gtk_container_get_children (GTK_CONTAINER (priv->content));
for (l = children; l; l = l->next)
{
GtkWidget *page = l->data;
gtk_container_remove (GTK_CONTAINER (priv->content), page);
}
g_list_free (children);
/* Our GtkAssistantPage list should be empty now. */
g_warn_if_fail (priv->pages == NULL);
while (priv->pages)
gtk_assistant_remove_page (assistant, 0);
priv->content = NULL;
}
if (priv->sidebar)
priv->sidebar = NULL;
if (priv->action_area)
priv->action_area = NULL;
priv->sidebar = NULL;
priv->action_area = NULL;
if (priv->forward_function)
{
@ -1391,8 +1363,7 @@ gtk_assistant_destroy (GtkWidget *widget)
priv->visited_pages = NULL;
}
gtk_window_set_titlebar (GTK_WINDOW (widget), NULL);
GTK_WIDGET_CLASS (gtk_assistant_parent_class)->destroy (widget);
G_OBJECT_CLASS (gtk_assistant_parent_class)->dispose (object);
}
static GList*
@ -1478,47 +1449,6 @@ gtk_assistant_close_request (GtkWindow *window)
return TRUE;
}
static void
gtk_assistant_add (GtkContainer *container,
GtkWidget *page)
{
GtkAssistant *assistant = GTK_ASSISTANT (container);
GtkAssistantPrivate *priv = gtk_assistant_get_instance_private (assistant);
/* A bit tricky here, GtkAssistant doesnt exactly play by
* the rules by allowing gtk_container_add() to insert pages.
*
* For the first invocation (from the builder template invocation),
* let's make sure we add the actual direct container content properly.
*/
if (!priv->constructed)
{
gtk_widget_set_parent (page, GTK_WIDGET (container));
_gtk_bin_set_child (GTK_BIN (container), page);
return;
}
gtk_assistant_append_page (GTK_ASSISTANT (container), page);
}
static void
gtk_assistant_remove (GtkContainer *container,
GtkWidget *page)
{
GtkAssistant *assistant = GTK_ASSISTANT (container);
GtkAssistantPrivate *priv = gtk_assistant_get_instance_private (assistant);
/* Forward this removal to the content stack */
if (gtk_widget_get_parent (page) == priv->content)
{
gtk_container_remove (GTK_CONTAINER (priv->content), page);
}
else
{
GTK_CONTAINER_CLASS (gtk_assistant_parent_class)->remove (container, page);
}
}
/**
* gtk_assistant_new:
*
@ -1875,9 +1805,8 @@ gtk_assistant_remove_page (GtkAssistant *assistant,
g_return_if_fail (GTK_IS_ASSISTANT (assistant));
page = gtk_assistant_get_nth_page (assistant, page_num);
if (page)
gtk_container_remove (GTK_CONTAINER (assistant), page);
assistant_remove_page (assistant, page);
if (priv->model)
g_list_model_items_changed (priv->model, page_num, 1, 0);
@ -2322,6 +2251,7 @@ static void
gtk_assistant_buildable_interface_init (GtkBuildableIface *iface)
{
parent_buildable_iface = g_type_interface_peek_parent (iface);
iface->custom_tag_start = gtk_assistant_buildable_custom_tag_start;
iface->custom_finished = gtk_assistant_buildable_custom_finished;
iface->add_child = gtk_assistant_buildable_add_child;
@ -2342,10 +2272,8 @@ gtk_assistant_buildable_add_child (GtkBuildable *buildable,
priv->headerbar = GTK_WIDGET (child);
gtk_window_set_titlebar (GTK_WINDOW (buildable), priv->headerbar);
}
else if (GTK_IS_WIDGET (child))
gtk_container_add (GTK_CONTAINER (buildable), GTK_WIDGET (child));
else
g_warning ("Can't add a child of type '%s' to '%s'", G_OBJECT_TYPE_NAME (child), G_OBJECT_TYPE_NAME (buildable));
parent_buildable_iface->add_child (buildable, builder, child, type);
}
gboolean

View File

@ -21,6 +21,7 @@
#include "gtkshortcutswindowprivate.h"
#include "gtkbox.h"
#include "gtkbuildable.h"
#include "gtkgrid.h"
#include "gtkheaderbar.h"
#include "gtkintl.h"
@ -133,8 +134,13 @@ typedef struct
guint translatable : 1;
} ViewsParserData;
static void gtk_shortcuts_window_buildable_iface_init (GtkBuildableIface *iface);
G_DEFINE_TYPE_WITH_PRIVATE (GtkShortcutsWindow, gtk_shortcuts_window, GTK_TYPE_WINDOW)
G_DEFINE_TYPE_WITH_CODE (GtkShortcutsWindow, gtk_shortcuts_window, GTK_TYPE_WINDOW,
G_ADD_PRIVATE (GtkShortcutsWindow)
G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
gtk_shortcuts_window_buildable_iface_init))
enum {
@ -368,62 +374,27 @@ gtk_shortcuts_window_add_section (GtkShortcutsWindow *self,
g_free (title);
}
static void
gtk_shortcuts_window_add (GtkContainer *container,
GtkWidget *widget)
{
GtkShortcutsWindow *self = (GtkShortcutsWindow *)container;
static GtkBuildableIface *parent_buildable_iface;
if (GTK_IS_SHORTCUTS_SECTION (widget))
gtk_shortcuts_window_add_section (self, GTK_SHORTCUTS_SECTION (widget));
static void
gtk_shortcuts_window_buildable_add_child (GtkBuildable *buildable,
GtkBuilder *builder,
GObject *child,
const gchar *type)
{
if (GTK_IS_SHORTCUTS_SECTION (child))
gtk_shortcuts_window_add_section (GTK_SHORTCUTS_WINDOW (buildable),
GTK_SHORTCUTS_SECTION (child));
else
g_warning ("Can't add children of type %s to %s",
G_OBJECT_TYPE_NAME (widget),
G_OBJECT_TYPE_NAME (container));
parent_buildable_iface->add_child (buildable, builder, child, type);
}
static void
gtk_shortcuts_window_remove (GtkContainer *container,
GtkWidget *widget)
gtk_shortcuts_window_buildable_iface_init (GtkBuildableIface *iface)
{
GtkShortcutsWindow *self = (GtkShortcutsWindow *)container;
GtkShortcutsWindowPrivate *priv = gtk_shortcuts_window_get_instance_private (self);
parent_buildable_iface = g_type_interface_peek_parent (iface);
g_signal_handlers_disconnect_by_func (widget, section_notify_cb, self);
if (widget == (GtkWidget *)priv->header_bar ||
widget == (GtkWidget *)priv->main_box)
GTK_CONTAINER_CLASS (gtk_shortcuts_window_parent_class)->remove (container, widget);
else
gtk_container_remove (GTK_CONTAINER (priv->stack), widget);
}
static void
gtk_shortcuts_window_forall (GtkContainer *container,
GtkCallback callback,
gpointer callback_data)
{
GtkShortcutsWindow *self = (GtkShortcutsWindow *)container;
GtkShortcutsWindowPrivate *priv = gtk_shortcuts_window_get_instance_private (self);
if (priv->stack)
{
GList *children, *l;
GtkWidget *search;
GtkWidget *empty;
search = gtk_stack_get_child_by_name (GTK_STACK (priv->stack), "internal-search");
empty = gtk_stack_get_child_by_name (GTK_STACK (priv->stack), "no-search-results");
children = gtk_container_get_children (GTK_CONTAINER (priv->stack));
for (l = children; l; l = l->next)
{
GtkWidget *child = l->data;
if (child != search && child != empty)
callback (child, callback_data);
}
g_list_free (children);
}
iface->add_child = gtk_shortcuts_window_buildable_add_child;
}
static void
@ -482,7 +453,14 @@ update_accels_for_actions (GtkShortcutsWindow *self)
GtkShortcutsWindowPrivate *priv = gtk_shortcuts_window_get_instance_private (self);
if (priv->window)
gtk_container_forall (GTK_CONTAINER (self), update_accels_cb, self);
{
GtkWidget *child;
for (child = gtk_widget_get_first_child (GTK_WIDGET (self));
child != NULL;
child = gtk_widget_get_next_sibling (child))
update_accels_cb (child, self);
}
}
static void
@ -672,20 +650,9 @@ gtk_shortcuts_window_dispose (GObject *object)
gtk_shortcuts_window_set_window (self, NULL);
if (priv->header_bar)
{
gtk_container_remove (GTK_CONTAINER (self), GTK_WIDGET (priv->header_bar));
priv->header_bar = NULL;
priv->popover = NULL;
}
if (priv->main_box)
{
gtk_container_remove (GTK_CONTAINER (self), GTK_WIDGET (priv->main_box));
priv->main_box = NULL;
priv->stack = NULL;
priv->search_bar = NULL;
}
priv->stack = NULL;
priv->search_bar = NULL;
priv->main_box = NULL;
G_OBJECT_CLASS (gtk_shortcuts_window_parent_class)->dispose (object);
}
@ -761,18 +728,11 @@ gtk_shortcuts_window_unmap (GtkWidget *widget)
GTK_WIDGET_CLASS (gtk_shortcuts_window_parent_class)->unmap (widget);
}
static GType
gtk_shortcuts_window_child_type (GtkContainer *container)
{
return GTK_TYPE_SHORTCUTS_SECTION;
}
static void
gtk_shortcuts_window_class_init (GtkShortcutsWindowClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
object_class->constructed = gtk_shortcuts_window_constructed;
object_class->finalize = gtk_shortcuts_window_finalize;
@ -781,10 +741,6 @@ gtk_shortcuts_window_class_init (GtkShortcutsWindowClass *klass)
object_class->dispose = gtk_shortcuts_window_dispose;
widget_class->unmap = gtk_shortcuts_window_unmap;
container_class->add = gtk_shortcuts_window_add;
container_class->remove = gtk_shortcuts_window_remove;
container_class->child_type = gtk_shortcuts_window_child_type;
container_class->forall = gtk_shortcuts_window_forall;
klass->close = gtk_shortcuts_window_close;
klass->search = gtk_shortcuts_window_search;
@ -899,10 +855,9 @@ gtk_shortcuts_window_init (GtkShortcutsWindow *self)
priv->main_box = g_object_new (GTK_TYPE_BOX,
"orientation", GTK_ORIENTATION_VERTICAL,
NULL);
GTK_CONTAINER_CLASS (gtk_shortcuts_window_parent_class)->add (GTK_CONTAINER (self), GTK_WIDGET (priv->main_box));
gtk_window_set_child (GTK_WINDOW (self), priv->main_box);
priv->search_bar = g_object_new (GTK_TYPE_SEARCH_BAR,
NULL);
priv->search_bar = g_object_new (GTK_TYPE_SEARCH_BAR, NULL);
g_object_bind_property (priv->search_bar, "search-mode-enabled",
search_button, "active",
G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);

View File

@ -172,6 +172,8 @@
typedef struct
{
GtkWidget *child;
GtkWidget *attach_widget;
GtkWidget *default_widget;
GtkWidget *focus_widget;
@ -399,11 +401,6 @@ static gboolean surface_event (GdkSurface *surface,
GdkEvent *event,
GtkWidget *widget);
static void gtk_window_remove (GtkContainer *container,
GtkWidget *widget);
static void gtk_window_forall (GtkContainer *container,
GtkCallback callback,
gpointer callback_data);
static gint gtk_window_focus (GtkWidget *widget,
GtkDirectionType direction);
static void gtk_window_move_focus (GtkWidget *widget,
@ -542,7 +539,7 @@ static GtkWindowRegion get_active_region_type (GtkWindow *window,
gint y);
G_DEFINE_TYPE_WITH_CODE (GtkWindow, gtk_window, GTK_TYPE_BIN,
G_DEFINE_TYPE_WITH_CODE (GtkWindow, gtk_window, GTK_TYPE_WIDGET,
G_ADD_PRIVATE (GtkWindow)
G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
gtk_window_buildable_interface_init)
@ -637,7 +634,7 @@ gtk_window_measure (GtkWidget *widget,
{
GtkWindow *window = GTK_WINDOW (widget);
GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
GtkWidget *child = gtk_bin_get_child (GTK_BIN (widget));
GtkWidget *child = priv->child;
gboolean has_size_request = gtk_widget_has_size_request (widget);
int title_min_size = 0;
int title_nat_size = 0;
@ -708,15 +705,35 @@ gtk_window_measure (GtkWidget *widget,
}
static void
gtk_window_add (GtkContainer *container,
GtkWidget *child)
gtk_window_compute_expand (GtkWidget *widget,
gboolean *hexpand,
gboolean *vexpand)
{
/* Insert the child's css node now at the end so the order wrt. decoration_node is correct */
gtk_css_node_insert_before (gtk_widget_get_css_node (GTK_WIDGET (container)),
gtk_widget_get_css_node (child),
NULL);
GtkWindow *window = GTK_WINDOW (widget);
GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
GTK_CONTAINER_CLASS (gtk_window_parent_class)->add (container, child);
if (priv->child)
{
*hexpand = gtk_widget_compute_expand (priv->child, GTK_ORIENTATION_HORIZONTAL);
*vexpand = gtk_widget_compute_expand (priv->child, GTK_ORIENTATION_VERTICAL);
}
else
{
*hexpand = FALSE;
*vexpand = FALSE;
}
}
static GtkSizeRequestMode
gtk_window_get_request_mode (GtkWidget *widget)
{
GtkWindow *window = GTK_WINDOW (widget);
GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
if (priv->child)
return gtk_widget_get_request_mode (priv->child);
else
return GTK_SIZE_REQUEST_CONSTANT_SIZE;
}
static void
@ -724,7 +741,6 @@ gtk_window_class_init (GtkWindowClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
quark_gtk_window_icon_info = g_quark_from_static_string ("gtk-window-icon-info");
@ -746,17 +762,16 @@ gtk_window_class_init (GtkWindowClass *klass)
widget_class->realize = gtk_window_realize;
widget_class->unrealize = gtk_window_unrealize;
widget_class->size_allocate = gtk_window_size_allocate;
widget_class->focus = gtk_window_focus;
widget_class->move_focus = gtk_window_move_focus;
widget_class->measure = gtk_window_measure;
widget_class->compute_expand = gtk_window_compute_expand;
widget_class->get_request_mode = gtk_window_get_request_mode;
widget_class->focus = gtk_window_focus;
widget_class->grab_focus = gtk_widget_grab_focus_none;
widget_class->move_focus = gtk_window_move_focus;
widget_class->state_flags_changed = gtk_window_state_flags_changed;
widget_class->css_changed = gtk_window_css_changed;
widget_class->snapshot = gtk_window_snapshot;
container_class->add = gtk_window_add;
container_class->remove = gtk_window_remove;
container_class->forall = gtk_window_forall;
klass->activate_default = gtk_window_real_activate_default;
klass->activate_focus = gtk_window_real_activate_focus;
klass->keys_changed = gtk_window_keys_changed;
@ -2057,6 +2072,8 @@ gtk_window_buildable_add_child (GtkBuildable *buildable,
{
if (type && strcmp (type, "titlebar") == 0)
gtk_window_set_titlebar (GTK_WINDOW (buildable), GTK_WIDGET (child));
else if (GTK_IS_WIDGET (child))
gtk_window_set_child (GTK_WINDOW (buildable), GTK_WIDGET (child));
else
parent_buildable_iface->add_child (buildable, builder, child, type);
}
@ -2624,8 +2641,10 @@ gtk_window_dispose (GObject *object)
gtk_window_set_default_widget (window, NULL);
remove_attach_widget (window);
G_OBJECT_CLASS (gtk_window_parent_class)->dispose (object);
g_clear_pointer (&priv->child, gtk_widget_unparent);
unset_titlebar (window);
G_OBJECT_CLASS (gtk_window_parent_class)->dispose (object);
}
static void
@ -3146,7 +3165,7 @@ gtk_window_set_titlebar (GtkWindow *window,
gtk_window_enable_csd (window);
priv->title_box = titlebar;
/* Same reason as in gtk_window_add */
/* Same reason as in gtk_window_set_child */
gtk_css_node_insert_before (gtk_widget_get_css_node (GTK_WIDGET (window)),
gtk_widget_get_css_node (titlebar),
NULL);
@ -4319,13 +4338,12 @@ gtk_window_update_toplevel (GtkWindow *window)
static void
gtk_window_map (GtkWidget *widget)
{
GtkWidget *child;
GtkWindow *window = GTK_WINDOW (widget);
GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
GtkWidget *child = priv->child;
GTK_WIDGET_CLASS (gtk_window_parent_class)->map (widget);
child = gtk_bin_get_child (GTK_BIN (window));
if (child != NULL && gtk_widget_get_visible (child))
gtk_widget_map (child);
@ -4377,7 +4395,7 @@ gtk_window_unmap (GtkWidget *widget)
{
GtkWindow *window = GTK_WINDOW (widget);
GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
GtkWidget *child;
GtkWidget *child = priv->child;
GdkSurfaceState state;
GTK_WIDGET_CLASS (gtk_window_parent_class)->unmap (widget);
@ -4397,7 +4415,6 @@ gtk_window_unmap (GtkWidget *widget)
if (priv->title_box != NULL)
gtk_widget_unmap (priv->title_box);
child = gtk_bin_get_child (GTK_BIN (window));
if (child != NULL)
gtk_widget_unmap (child);
}
@ -4908,9 +4925,11 @@ gtk_window_unrealize (GtkWidget *widget)
/* Icons */
gtk_window_unrealize_icon (window);
gtk_container_forall (GTK_CONTAINER (widget),
(GtkCallback) gtk_widget_unrealize,
NULL);
if (priv->title_box)
gtk_widget_unrealize (priv->title_box);
if (priv->child)
gtk_widget_unrealize (priv->child);
g_clear_object (&priv->renderer);
@ -5066,12 +5085,12 @@ gtk_window_size_allocate (GtkWidget *widget,
int baseline)
{
GtkWindow *window = GTK_WINDOW (widget);
GtkWidget *child;
GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
GtkWidget *child = priv->child;
GtkAllocation child_allocation;
_gtk_window_set_allocation (window, width, height, &child_allocation);
child = gtk_bin_get_child (GTK_BIN (window));
if (child && gtk_widget_get_visible (child))
gtk_widget_size_allocate (child, &child_allocation, -1);
}
@ -5432,19 +5451,6 @@ gtk_window_key_released (GtkWidget *widget,
return FALSE;
}
static void
gtk_window_remove (GtkContainer *container,
GtkWidget *widget)
{
GtkWindow *window = GTK_WINDOW (container);
GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
if (widget == priv->title_box)
unset_titlebar (window);
else
GTK_CONTAINER_CLASS (gtk_window_parent_class)->remove (container, widget);
}
void
gtk_window_check_resize (GtkWindow *self)
{
@ -5460,39 +5466,16 @@ gtk_window_check_resize (GtkWindow *self)
gdk_profiler_end_mark (before, "size allocation", "");
}
static void
gtk_window_forall (GtkContainer *container,
GtkCallback callback,
gpointer callback_data)
{
GtkWindow *window = GTK_WINDOW (container);
GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
GtkWidget *child;
child = gtk_bin_get_child (GTK_BIN (container));
if (child != NULL)
(* callback) (child, callback_data);
if (priv->title_box != NULL &&
priv->titlebar == NULL)
(* callback) (priv->title_box, callback_data);
}
static gboolean
gtk_window_focus (GtkWidget *widget,
GtkDirectionType direction)
GtkDirectionType direction)
{
GtkWindow *window = GTK_WINDOW (widget);
GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
GtkBin *bin;
GtkContainer *container;
GtkWidget *child;
GtkWidget *old_focus_child;
GtkWidget *parent;
container = GTK_CONTAINER (widget);
bin = GTK_BIN (widget);
old_focus_child = gtk_widget_get_focus_child (widget);
/* We need a special implementation here to deal properly with wrapping
@ -5508,22 +5491,22 @@ gtk_window_focus (GtkWidget *widget,
if (priv->focus_widget)
{
if (direction == GTK_DIR_LEFT ||
direction == GTK_DIR_RIGHT ||
direction == GTK_DIR_UP ||
direction == GTK_DIR_DOWN)
{
return FALSE;
}
direction == GTK_DIR_RIGHT ||
direction == GTK_DIR_UP ||
direction == GTK_DIR_DOWN)
{
return FALSE;
}
/* Wrapped off the end, clear the focus setting for the toplpevel */
parent = _gtk_widget_get_parent (priv->focus_widget);
while (parent)
{
{
gtk_widget_set_focus_child (parent, NULL);
parent = _gtk_widget_get_parent (parent);
}
gtk_window_set_focus (GTK_WINDOW (container), NULL);
parent = _gtk_widget_get_parent (parent);
}
gtk_window_set_focus (window, NULL);
}
/* Now try to focus the first widget in the window,
@ -5535,7 +5518,7 @@ gtk_window_focus (GtkWidget *widget,
priv->title_box != old_focus_child)
child = priv->title_box;
else
child = gtk_bin_get_child (bin);
child = priv->child;
if (child)
{
@ -5546,7 +5529,7 @@ gtk_window_focus (GtkWidget *widget,
gtk_widget_child_focus (priv->title_box, direction))
return TRUE;
else if (priv->title_box == child &&
gtk_widget_child_focus (gtk_bin_get_child (bin), direction))
gtk_widget_child_focus (priv->child, direction))
return TRUE;
}
@ -8097,10 +8080,25 @@ void
gtk_window_set_child (GtkWindow *window,
GtkWidget *child)
{
GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
g_return_if_fail (GTK_IS_WINDOW (window));
g_return_if_fail (child == NULL || GTK_IS_WIDGET (child));
gtk_window_add (GTK_CONTAINER (window), child);
g_clear_pointer (&priv->child, gtk_widget_unparent);
if (child)
{
/* Insert the child's css node now at the end so the order wrt.
* decoration_node is correct
*/
gtk_css_node_insert_before (gtk_widget_get_css_node (GTK_WIDGET (window)),
gtk_widget_get_css_node (child),
NULL);
priv->child = child;
gtk_widget_set_parent (child, GTK_WIDGET (window));
}
g_object_notify_by_pspec (G_OBJECT (window), window_props[PROP_CHILD]);
}
@ -8115,7 +8113,9 @@ gtk_window_set_child (GtkWindow *window,
GtkWidget *
gtk_window_get_child (GtkWindow *window)
{
GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
return gtk_bin_get_child (GTK_BIN (window));
return priv->child;
}

View File

@ -32,7 +32,7 @@
#include <gtk/gtkapplication.h>
#include <gtk/gtkaccelgroup.h>
#include <gtk/gtkbin.h>
#include <gtk/gtkwidget.h>
G_BEGIN_DECLS
@ -51,7 +51,7 @@ typedef struct _GtkWindowGroupPrivate GtkWindowGroupPrivate;
struct _GtkWindow
{
GtkBin parent_instance;
GtkWidget parent_instance;
};
/**
@ -67,7 +67,7 @@ struct _GtkWindow
*/
struct _GtkWindowClass
{
GtkBinClass parent_class;
GtkWidgetClass parent_class;
/*< public >*/

View File

@ -21,7 +21,6 @@
<child>
<object class="GtkStack" id="content">
<property name="vexpand">1</property>
<signal name="remove" handler="assistant_remove_page_cb" swapped="no"/>
<child type="tab"/>
</object>
</child>