Merge branch 'wip/otte/dnd' into 'master'

stuff

See merge request GNOME/gtk!1460
This commit is contained in:
Benjamin Otte 2020-02-22 14:53:13 +00:00
commit b002572824
34 changed files with 863 additions and 517 deletions

View File

@ -6909,6 +6909,27 @@ GTK_DROP_TARGET_GET_CLASS
gtk_drop_target_get_type
</SECTION>
<SECTION>
<FILE>gtkdropcontrollermotion</FILE>
<TITLE>GtkDropControllerMotion</TITLE>
GtkDropControllerMotion
gtk_drop_controller_motion_new
gtk_drop_controller_motion_contains_pointer
gtk_drop_controller_motion_is_pointer
gtk_drop_controller_motion_get_drop
<SUBSECTION Standard>
GTK_TYPE_DROP_CONTROLLER_MOTION
GTK_DROP_CONTROLLER_MOTION
GTK_DROP_CONTROLLER_MOTION_CLASS
GTK_IS_DROP_CONTROLLER_MOTION
GTK_IS_DROP_CONTROLLER_MOTION_CLASS
GTK_DROP_CONTROLLER_MOTION_GET_CLASS
<SUBSECTION Private>
gtk_drop_controller_motion_get_type
</SECTION>
<SECTION>
<FILE>gtkdragicon</FILE>
GtkDragIcon

View File

@ -541,15 +541,10 @@ gdk_device_get_position (GdkDevice *device,
double *x,
double *y)
{
GdkDisplay *display;
g_return_if_fail (GDK_IS_DEVICE (device));
g_return_if_fail (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD);
display = gdk_device_get_display (device);
g_return_if_fail (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_SLAVE ||
gdk_display_device_is_grabbed (display, device));
gdk_display_device_is_grabbed (gdk_device_get_display (device), device));
_gdk_device_query_state (device, NULL, NULL, x, y, NULL, NULL, NULL);
}

View File

@ -561,7 +561,9 @@ void
gdk_drop_status (GdkDrop *self,
GdkDragAction actions)
{
#ifndef G_DISABLE_CHECKS
GdkDropPrivate *priv = gdk_drop_get_instance_private (self);
#endif
g_return_if_fail (GDK_IS_DROP (self));
g_return_if_fail (priv->state != GDK_DROP_STATE_FINISHED);

View File

@ -1480,13 +1480,23 @@ gdk_event_get_display (GdkEvent *event)
GdkEventSequence *
gdk_event_get_event_sequence (GdkEvent *event)
{
if (event->any.type == GDK_TOUCH_BEGIN ||
event->any.type == GDK_TOUCH_UPDATE ||
event->any.type == GDK_TOUCH_END ||
event->any.type == GDK_TOUCH_CANCEL)
return event->touch.sequence;
switch ((int) event->any.type)
{
case GDK_TOUCH_BEGIN:
case GDK_TOUCH_UPDATE:
case GDK_TOUCH_END:
case GDK_TOUCH_CANCEL:
return event->touch.sequence;
return NULL;
case GDK_DRAG_ENTER:
case GDK_DRAG_LEAVE:
case GDK_DRAG_MOTION:
case GDK_DROP_START:
return (GdkEventSequence *) event->dnd.drop;
default:
return NULL;
}
}
/**

View File

@ -2369,12 +2369,6 @@ should_be_mapped (GdkSurface *surface)
return TRUE;
}
static gboolean
should_map_as_popup (GdkSurface *surface)
{
return GDK_SURFACE_TYPE (surface) == GDK_SURFACE_POPUP;
}
static void
gdk_wayland_surface_map_toplevel (GdkSurface *surface)
{
@ -2397,7 +2391,7 @@ gdk_wayland_surface_show (GdkSurface *surface,
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
g_return_if_fail (!should_map_as_popup (surface));
g_return_if_fail (GDK_SURFACE_TYPE (surface) != GDK_SURFACE_POPUP);
if (!impl->display_server.wl_surface)
gdk_wayland_surface_create_surface (surface);
@ -2790,7 +2784,7 @@ gdk_wayland_surface_present_popup (GdkSurface *surface,
GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
GdkWaylandSurface *impl;
g_return_val_if_fail (should_map_as_popup (surface), FALSE);
g_return_val_if_fail (GDK_SURFACE_TYPE (surface) == GDK_SURFACE_POPUP, FALSE);
impl = GDK_WAYLAND_SURFACE (surface);
@ -4329,7 +4323,7 @@ gdk_wayland_surface_set_transient_for_exported (GdkSurface *surface,
g_return_val_if_fail (GDK_IS_WAYLAND_SURFACE (surface), FALSE);
g_return_val_if_fail (GDK_IS_WAYLAND_DISPLAY (display), FALSE);
g_return_val_if_fail (!should_map_as_popup (surface), FALSE);
g_return_val_if_fail (GDK_SURFACE_TYPE (surface) != GDK_SURFACE_POPUP, FALSE);
impl = GDK_WAYLAND_SURFACE (surface);
display_wayland = GDK_WAYLAND_DISPLAY (display);

View File

@ -94,6 +94,7 @@
#include <gtk/gtkdragicon.h>
#include <gtk/gtkdragsource.h>
#include <gtk/gtkdrawingarea.h>
#include <gtk/gtkdropcontrollermotion.h>
#include <gtk/gtkeditable.h>
#include <gtk/gtkemojichooser.h>
#include <gtk/gtkentry.h>

View File

@ -2706,14 +2706,10 @@ gtk_combo_box_set_entry_text_column (GtkComboBox *combo_box,
gint text_column)
{
GtkComboBoxPrivate *priv = gtk_combo_box_get_instance_private (combo_box);
GtkTreeModel *model;
g_return_if_fail (GTK_IS_COMBO_BOX (combo_box));
model = gtk_combo_box_get_model (combo_box);
g_return_if_fail (text_column >= 0);
g_return_if_fail (model == NULL || text_column < gtk_tree_model_get_n_columns (model));
g_return_if_fail (priv->model == NULL || text_column < gtk_tree_model_get_n_columns (priv->model));
if (priv->text_column != text_column)
{
@ -2815,17 +2811,13 @@ gtk_combo_box_set_id_column (GtkComboBox *combo_box,
gint id_column)
{
GtkComboBoxPrivate *priv = gtk_combo_box_get_instance_private (combo_box);
GtkTreeModel *model;
g_return_if_fail (GTK_IS_COMBO_BOX (combo_box));
if (id_column != priv->id_column)
{
model = gtk_combo_box_get_model (combo_box);
g_return_if_fail (id_column >= 0);
g_return_if_fail (model == NULL ||
id_column < gtk_tree_model_get_n_columns (model));
g_return_if_fail (priv->model == NULL || id_column < gtk_tree_model_get_n_columns (priv->model));
priv->id_column = id_column;

View File

@ -491,7 +491,6 @@ gtk_combo_box_text_insert (GtkComboBoxText *combo_box,
GtkListStore *store;
GtkTreeIter iter;
gint text_column;
gint column_type;
g_return_if_fail (GTK_IS_COMBO_BOX_TEXT (combo_box));
g_return_if_fail (text != NULL);
@ -506,8 +505,7 @@ gtk_combo_box_text_insert (GtkComboBoxText *combo_box,
else if (text_column < 0)
text_column = 0;
column_type = gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), text_column);
g_return_if_fail (column_type == G_TYPE_STRING);
g_return_if_fail (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), text_column) == G_TYPE_STRING);
if (position < 0)
gtk_list_store_append (store, &iter);
@ -522,8 +520,7 @@ gtk_combo_box_text_insert (GtkComboBoxText *combo_box,
id_column = gtk_combo_box_get_id_column (GTK_COMBO_BOX (combo_box));
g_return_if_fail (id_column >= 0);
column_type = gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), id_column);
g_return_if_fail (column_type == G_TYPE_STRING);
g_return_if_fail (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), id_column) == G_TYPE_STRING);
gtk_list_store_set (store, &iter, id_column, id, -1);
}
@ -603,14 +600,12 @@ gtk_combo_box_text_get_active_text (GtkComboBoxText *combo_box)
{
GtkTreeModel *model;
gint text_column;
gint column_type;
model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box));
g_return_val_if_fail (GTK_IS_LIST_STORE (model), NULL);
text_column = gtk_combo_box_get_entry_text_column (GTK_COMBO_BOX (combo_box));
g_return_val_if_fail (text_column >= 0, NULL);
column_type = gtk_tree_model_get_column_type (model, text_column);
g_return_val_if_fail (column_type == G_TYPE_STRING, NULL);
g_return_val_if_fail (gtk_tree_model_get_column_type (model, text_column) == G_TYPE_STRING, NULL);
gtk_tree_model_get (model, &iter, text_column, &text, -1);
}

View File

@ -129,7 +129,9 @@ gtk_drag_icon_move_resize (GtkDragIcon *icon)
if (icon->surface)
{
gtk_widget_get_preferred_size (GTK_WIDGET (icon), NULL, &req);
gdk_surface_resize (icon->surface, req.width, req.height);
gdk_surface_resize (icon->surface,
MAX (1, req.width),
MAX (1, req.height));
}
}
@ -256,8 +258,6 @@ gtk_drag_icon_size_allocate (GtkWidget *widget,
{
GtkDragIcon *icon = GTK_DRAG_ICON (widget);
gtk_drag_icon_move_resize (icon);
if (icon->widget)
gtk_widget_allocate (icon->widget, width, height, baseline, NULL);
}

View File

@ -0,0 +1,394 @@
/*
* Copyright © 2020 Benjamin Otte
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Benjamin Otte <otte@gnome.org>
*/
/**
* SECTION:gtkdropcontrollermotion
* @Short_description: Event controller for motion events during a drop
* @Title: GtkDropControllerMotion
* @See_also: #GtkDropControllerMotion, #GdkDrop, #GtkDropTarget
*
* #GtkDropControllerMotion is an event controller meant for tracking
* the pointer hovering over a widget during a drag and drop operation.
*
* It is modeled after #GtkEventControllerMotion so if you have used
* that, this should feel really familiar.
*
* The drop controller is not able to accept drops, use #GtkDropTarget
* for that purpose.
**/
#include "config.h"
#include "gtkdropcontrollermotion.h"
#include "gtkintl.h"
#include "gtkprivate.h"
#include "gtkwidgetprivate.h"
#include "gtkmarshalers.h"
#include "gtkeventcontrollerprivate.h"
#include "gtktypebuiltins.h"
#include "gtkmarshalers.h"
struct _GtkDropControllerMotion
{
GtkEventController parent_instance;
GdkDrop *drop;
guint is_pointer : 1;
guint contains_pointer : 1;
};
struct _GtkDropControllerMotionClass
{
GtkEventControllerClass parent_class;
};
enum {
ENTER,
LEAVE,
MOTION,
N_SIGNALS
};
enum {
PROP_0,
PROP_CONTAINS_POINTER,
PROP_DROP,
PROP_IS_POINTER,
NUM_PROPERTIES
};
static GParamSpec *props[NUM_PROPERTIES] = { NULL, };
static guint signals[N_SIGNALS] = { 0 };
G_DEFINE_TYPE (GtkDropControllerMotion, gtk_drop_controller_motion, GTK_TYPE_EVENT_CONTROLLER)
static gboolean
gtk_drop_controller_motion_handle_event (GtkEventController *controller,
GdkEvent *event,
double x,
double y)
{
GtkEventControllerClass *parent_class;
GdkEventType type;
type = gdk_event_get_event_type (event);
if (type == GDK_DRAG_MOTION)
g_signal_emit (controller, signals[MOTION], 0, x, y);
parent_class = GTK_EVENT_CONTROLLER_CLASS (gtk_drop_controller_motion_parent_class);
return parent_class->handle_event (controller, event, x, y);
}
static void
update_pointer_focus (GtkEventController *controller,
const GtkCrossingData *crossing,
double x,
double y)
{
GtkDropControllerMotion *self = GTK_DROP_CONTROLLER_MOTION (controller);
GtkWidget *widget = gtk_event_controller_get_widget (controller);
gboolean is_pointer = FALSE;
gboolean contains_pointer = FALSE;
gboolean enter = FALSE;
gboolean leave = FALSE;
if (crossing->direction == GTK_CROSSING_IN)
{
if (crossing->new_descendent != NULL)
{
contains_pointer = TRUE;
}
if (crossing->new_target == widget)
{
contains_pointer = TRUE;
is_pointer = TRUE;
}
}
else
{
if (crossing->new_descendent != NULL ||
crossing->new_target == widget)
contains_pointer = TRUE;
is_pointer = FALSE;
}
if (self->contains_pointer != contains_pointer)
{
enter = contains_pointer;
leave = !contains_pointer;
}
if (leave)
g_signal_emit (controller, signals[LEAVE], 0);
g_object_freeze_notify (G_OBJECT (self));
if (self->is_pointer != is_pointer)
{
self->is_pointer = is_pointer;
g_object_notify (G_OBJECT (self), "is-pointer");
}
if (self->contains_pointer != contains_pointer)
{
self->contains_pointer = contains_pointer;
if (contains_pointer)
self->drop = g_object_ref (crossing->drop);
else
g_clear_object (&self->drop);
g_object_notify (G_OBJECT (self), "contains-pointer");
g_object_notify (G_OBJECT (self), "drop");
}
g_object_thaw_notify (G_OBJECT (self));
if (enter)
g_signal_emit (controller, signals[ENTER], 0, x, y);
}
static void
gtk_drop_controller_motion_handle_crossing (GtkEventController *controller,
const GtkCrossingData *crossing,
double x,
double y)
{
if (crossing->type == GTK_CROSSING_DROP)
update_pointer_focus (controller, crossing, x, y);
}
static void
gtk_drop_controller_motion_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkDropControllerMotion *self = GTK_DROP_CONTROLLER_MOTION (object);
switch (prop_id)
{
case PROP_CONTAINS_POINTER:
g_value_set_boolean (value, self->contains_pointer);
break;
case PROP_DROP:
g_value_set_object (value, self->drop);
break;
case PROP_IS_POINTER:
g_value_set_boolean (value, self->is_pointer);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
gtk_drop_controller_motion_class_init (GtkDropControllerMotionClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkEventControllerClass *controller_class = GTK_EVENT_CONTROLLER_CLASS (klass);
object_class->get_property = gtk_drop_controller_motion_get_property;
controller_class->handle_event = gtk_drop_controller_motion_handle_event;
controller_class->handle_crossing = gtk_drop_controller_motion_handle_crossing;
/**
* GtkDropControllerMotion:contains-pointer:
*
* Whether the pointer of a drag and drop operation is in the controller's
* widget or a descendant.
* See also #GtkDropControllerMotion:is-pointer.
*
* When handling crossing events, this property is updated
* before #GtkDropControllerMotion::enter but after
* #GtkDropControllerMotion::leave is emitted.
*/
props[PROP_CONTAINS_POINTER] =
g_param_spec_boolean ("contains-pointer",
P_("Contains Pointer"),
P_("Whether the pointer is inthe controllers widget or a descendant"),
FALSE,
G_PARAM_READABLE);
/**
* GtkDropControllerMotion:drop:
*
* The ongoing drop operation over the controller's widget or its descendant.
* If no drop operation is going on, this property returns %NULL.
*
* The event controller should not modify the @drop, but it might want to query
* its properties.
*
* When handling crossing events, this property is updated
* before #GtkDropControllerMotion::enter but after
* #GtkDropControllerMotion::leave is emitted.
*/
props[PROP_DROP] =
g_param_spec_object ("drop",
P_("Drop"),
P_("The ongoing drop operation"),
GDK_TYPE_DROP,
G_PARAM_READABLE);
/**
* GtkDropControllerMotion:is-pointer:
*
* Whether the pointer is in the controllers widget itself,
* as opposed to in a descendent widget. See also
* #GtkDropControllerMotion:contains-pointer.
*
* When handling crossing events, this property is updated
* before #GtkDropControllerMotion::enter but after
* #GtkDropControllerMotion::leave is emitted.
*/
props[PROP_IS_POINTER] =
g_param_spec_boolean ("is-pointer",
P_("Is Pointer"),
P_("Whether the pointer is in the controllers widget"),
FALSE,
G_PARAM_READABLE);
g_object_class_install_properties (object_class, NUM_PROPERTIES, props);
/**
* GtkDropControllerMotion::enter:
* @self: the object which received the signal
* @x: coordinates of pointer location
* @y: coordinates of pointer location
*
* Signals that the pointer has entered the widget.
*/
signals[ENTER] =
g_signal_new (I_("enter"),
GTK_TYPE_DROP_CONTROLLER_MOTION,
G_SIGNAL_RUN_LAST,
0, NULL, NULL,
NULL,
G_TYPE_NONE, 2,
G_TYPE_DOUBLE,
G_TYPE_DOUBLE);
g_signal_set_va_marshaller (signals[ENTER],
G_TYPE_FROM_CLASS (klass),
_gtk_marshal_VOID__DOUBLE_DOUBLEv);
/**
* GtkDropControllerMotion::leave:
* @self: the object which received the signal
*
* Signals that the pointer has left the widget.
*/
signals[LEAVE] =
g_signal_new (I_("leave"),
GTK_TYPE_DROP_CONTROLLER_MOTION,
G_SIGNAL_RUN_LAST,
0, NULL, NULL,
NULL,
G_TYPE_NONE, 0);
/**
* GtkDropControllerMotion::motion:
* @self: The object that received the signal
* @x: the x coordinate
* @y: the y coordinate
*
* Emitted when the pointer moves inside the widget.
*/
signals[MOTION] =
g_signal_new (I_("motion"),
GTK_TYPE_DROP_CONTROLLER_MOTION,
G_SIGNAL_RUN_FIRST,
0, NULL, NULL,
_gtk_marshal_VOID__DOUBLE_DOUBLE,
G_TYPE_NONE, 2,
G_TYPE_DOUBLE,
G_TYPE_DOUBLE);
g_signal_set_va_marshaller (signals[MOTION],
G_TYPE_FROM_CLASS (klass),
_gtk_marshal_VOID__DOUBLE_DOUBLEv);
}
static void
gtk_drop_controller_motion_init (GtkDropControllerMotion *self)
{
}
/**
* gtk_drop_controller_motion_new:
*
* Creates a new event controller that will handle pointer motion
* events during drag and drop.
*
* Returns: a new #GtkDropControllerMotion
**/
GtkEventController *
gtk_drop_controller_motion_new (void)
{
return g_object_new (GTK_TYPE_DROP_CONTROLLER_MOTION,
NULL);
}
/**
* gtk_drop_controller_motion_contains_pointer:
* @self: a #GtkDropControllerMotion
*
* Returns the value of the GtkDropControllerMotion:contains-pointer property.
*
* Returns: %TRUE if a dragging pointer is within @self or one of its children.
*/
gboolean
gtk_drop_controller_motion_contains_pointer (GtkDropControllerMotion *self)
{
g_return_val_if_fail (GTK_IS_DROP_CONTROLLER_MOTION (self), FALSE);
return self->contains_pointer;
}
/**
* gtk_drop_controller_motion_get_drop:
* @self: a #GtkDropControllerMotion
*
* Returns the value of the GtkDropControllerMotion:drop property.
*
* Returns: The #GdkDrop currently happening within @self or %NULL if none
*/
GdkDrop *
gtk_drop_controller_motion_get_drop (GtkDropControllerMotion *self)
{
g_return_val_if_fail (GTK_IS_DROP_CONTROLLER_MOTION (self), FALSE);
return self->drop;
}
/**
* gtk_drop_controller_motion_is_pointer:
* @self: a #GtkEventControllerKey
*
* Returns the value of the GtkDropControllerMotion:is-pointer property.
*
* Returns: %TRUE if a dragging pointer is within @self but not one of its children
*/
gboolean
gtk_drop_controller_motion_is_pointer (GtkDropControllerMotion *self)
{
g_return_val_if_fail (GTK_IS_DROP_CONTROLLER_MOTION (self), FALSE);
return self->is_pointer;
}

View File

@ -0,0 +1,57 @@
/*
* Copyright © 2020 Benjamin Otte
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Benjamin Otte <otte@gnome.org>
*/
#ifndef __GTK_DROP_CONTROLLER_MOTION_H__
#define __GTK_DROP_CONTROLLER_MOTION_H__
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gtk/gtk.h> can be included directly."
#endif
#include <gdk/gdk.h>
#include <gtk/gtkeventcontroller.h>
G_BEGIN_DECLS
#define GTK_TYPE_DROP_CONTROLLER_MOTION (gtk_drop_controller_motion_get_type ())
#define GTK_DROP_CONTROLLER_MOTION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GTK_TYPE_DROP_CONTROLLER_MOTION, GtkDropControllerMotion))
#define GTK_DROP_CONTROLLER_MOTION_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GTK_TYPE_DROP_CONTROLLER_MOTION, GtkDropControllerMotionClass))
#define GTK_IS_DROP_CONTROLLER_MOTION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GTK_TYPE_DROP_CONTROLLER_MOTION))
#define GTK_IS_DROP_CONTROLLER_MOTION_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GTK_TYPE_DROP_CONTROLLER_MOTION))
#define GTK_DROP_CONTROLLER_MOTION_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GTK_TYPE_DROP_CONTROLLER_MOTION, GtkDropControllerMotionClass))
typedef struct _GtkDropControllerMotion GtkDropControllerMotion;
typedef struct _GtkDropControllerMotionClass GtkDropControllerMotionClass;
GDK_AVAILABLE_IN_ALL
GType gtk_drop_controller_motion_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_ALL
GtkEventController * gtk_drop_controller_motion_new (void);
GDK_AVAILABLE_IN_ALL
gboolean gtk_drop_controller_motion_contains_pointer (GtkDropControllerMotion *self);
GDK_AVAILABLE_IN_ALL
GdkDrop * gtk_drop_controller_motion_get_drop (GtkDropControllerMotion *self);
GDK_AVAILABLE_IN_ALL
gboolean gtk_drop_controller_motion_is_pointer (GtkDropControllerMotion *self);
G_END_DECLS
#endif /* __GTK_DROP_CONTROLLER_MOTION_H__ */

View File

@ -198,8 +198,8 @@ gtk_event_controller_motion_class_init (GtkEventControllerMotionClass *klass)
* #GtkEventControllerMotion:contains-pointer.
*
* When handling crossing events, this property is updated
* before #GtkEventControllerMotion::enter or
* #GtkEventControllerMotion::leave are emitted.
* before #GtkEventControllerMotion::enter but after
* #GtkEventControllerMotion::leave is emitted.
*/
props[PROP_IS_POINTER] =
g_param_spec_boolean ("is-pointer",
@ -215,8 +215,8 @@ gtk_event_controller_motion_class_init (GtkEventControllerMotionClass *klass)
* See also #GtkEventControllerMotion:is-pointer.
*
* When handling crossing events, this property is updated
* before #GtkEventControllerMotion::enter or
* #GtkEventControllerMotion::leave are emitted.
* before #GtkEventControllerMotion::enter but after
* #GtkEventControllerMotion::leave is emitted.
*/
props[PROP_CONTAINS_POINTER] =
g_param_spec_boolean ("contains-pointer",
@ -320,7 +320,7 @@ gtk_event_controller_motion_contains_pointer (GtkEventControllerMotion *self)
/**
* gtk_event_controller_motion_is_pointer:
* @self: a #GtkEventControllerKey
* @self: a #GtkEventControllerMotion
*
* Returns the value of the GtkEventControllerMotion:is-pointer property.
*

View File

@ -24,7 +24,8 @@
typedef enum {
GTK_CROSSING_FOCUS,
GTK_CROSSING_POINTER
GTK_CROSSING_POINTER,
GTK_CROSSING_DROP
} GtkCrossingType;
typedef enum {
@ -47,11 +48,12 @@ typedef struct _GtkCrossingData GtkCrossingData;
* @new_descendent: the direct child of the receiving widget that
* is an ancestor of @new_target, or %NULL if @new_target is not
* a descendent of the receiving widget
* @drop: the #GdkDrop if this is info for a drop operation
*
* The struct that is passed to gtk_event_controller_handle_crossing().
*
* The @old_target and @new_target fields are set to the old or new
* focus or hover location.
* focus, drop or hover location.
*/
struct _GtkCrossingData {
GtkCrossingType type;
@ -61,6 +63,7 @@ struct _GtkCrossingData {
GtkWidget *old_descendent;
GtkWidget *new_target;
GtkWidget *new_descendent;
GdkDrop *drop;
};
struct _GtkEventController

View File

@ -115,7 +115,7 @@
#include "gtkbox.h"
#include "gtkbuildable.h"
#include "gtkcontainerprivate.h"
#include "gtkdragdest.h"
#include "gtkdropcontrollermotion.h"
#include "gtkbuiltiniconprivate.h"
#include "gtkgestureclick.h"
#include "gtkgesturesingle.h"
@ -192,12 +192,6 @@ static void gtk_expander_size_allocate (GtkWidget *widget,
int baseline);
static gboolean gtk_expander_focus (GtkWidget *widget,
GtkDirectionType direction);
static gboolean gtk_expander_drag_accept (GtkDropTarget *dest,
GdkDrop *drop,
GtkExpander *expander);
static void gtk_expander_drag_leave (GtkDropTarget *dest,
GdkDrop *drop,
GtkExpander *expander);
static void gtk_expander_add (GtkContainer *container,
GtkWidget *widget);
@ -236,6 +230,48 @@ G_DEFINE_TYPE_WITH_CODE (GtkExpander, gtk_expander, GTK_TYPE_CONTAINER,
G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
gtk_expander_buildable_init))
static gboolean
expand_timeout (gpointer data)
{
GtkExpander *expander = GTK_EXPANDER (data);
GtkExpanderPrivate *priv = gtk_expander_get_instance_private (expander);
priv->expand_timer = 0;
gtk_expander_set_expanded (expander, TRUE);
return FALSE;
}
static gboolean
gtk_expander_drag_enter (GtkDropControllerMotion *motion,
double x,
double y,
GtkExpander *expander)
{
GtkExpanderPrivate *priv = gtk_expander_get_instance_private (expander);
if (!priv->expanded && !priv->expand_timer)
{
priv->expand_timer = g_timeout_add (TIMEOUT_EXPAND, (GSourceFunc) expand_timeout, expander);
g_source_set_name_by_id (priv->expand_timer, "[gtk] expand_timeout");
}
return TRUE;
}
static void
gtk_expander_drag_leave (GtkDropControllerMotion *motion,
GtkExpander *expander)
{
GtkExpanderPrivate *priv = gtk_expander_get_instance_private (expander);
if (priv->expand_timer)
{
g_source_remove (priv->expand_timer);
priv->expand_timer = 0;
}
}
static void
gtk_expander_forall (GtkContainer *container,
GtkCallback callback,
@ -347,7 +383,7 @@ gtk_expander_init (GtkExpander *expander)
{
GtkExpanderPrivate *priv = gtk_expander_get_instance_private (expander);
GtkGesture *gesture;
GtkDropTarget *dest;
GtkEventController *controller;
gtk_widget_set_can_focus (GTK_WIDGET (expander), TRUE);
@ -372,10 +408,10 @@ gtk_expander_init (GtkExpander *expander)
gtk_widget_add_css_class (priv->arrow_widget, GTK_STYLE_CLASS_HORIZONTAL);
gtk_container_add (GTK_CONTAINER (priv->title_widget), priv->arrow_widget);
dest = gtk_drop_target_new (NULL, 0);
g_signal_connect (dest, "accept", G_CALLBACK (gtk_expander_drag_accept), expander);
g_signal_connect (dest, "drag-leave", G_CALLBACK (gtk_expander_drag_leave), expander);
gtk_widget_add_controller (GTK_WIDGET (expander), GTK_EVENT_CONTROLLER (dest));
controller = gtk_drop_controller_motion_new ();
g_signal_connect (controller, "enter", G_CALLBACK (gtk_expander_drag_enter), expander);
g_signal_connect (controller, "leave", G_CALLBACK (gtk_expander_drag_leave), expander);
gtk_widget_add_controller (GTK_WIDGET (expander), controller);
gesture = gtk_gesture_click_new ();
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture),
@ -530,48 +566,6 @@ gesture_click_released_cb (GtkGestureClick *gesture,
gtk_widget_activate (GTK_WIDGET (expander));
}
static gboolean
expand_timeout (gpointer data)
{
GtkExpander *expander = GTK_EXPANDER (data);
GtkExpanderPrivate *priv = gtk_expander_get_instance_private (expander);
priv->expand_timer = 0;
gtk_expander_set_expanded (expander, TRUE);
return FALSE;
}
static gboolean
gtk_expander_drag_accept (GtkDropTarget *dest,
GdkDrop *drop,
GtkExpander *expander)
{
GtkExpanderPrivate *priv = gtk_expander_get_instance_private (expander);
if (!priv->expanded && !priv->expand_timer)
{
priv->expand_timer = g_timeout_add (TIMEOUT_EXPAND, (GSourceFunc) expand_timeout, expander);
g_source_set_name_by_id (priv->expand_timer, "[gtk] expand_timeout");
}
return TRUE;
}
static void
gtk_expander_drag_leave (GtkDropTarget *dest,
GdkDrop *drop,
GtkExpander *expander)
{
GtkExpanderPrivate *priv = gtk_expander_get_instance_private (expander);
if (priv->expand_timer)
{
g_source_remove (priv->expand_timer);
priv->expand_timer = 0;
}
}
typedef enum
{
FOCUS_NONE,

View File

@ -867,6 +867,7 @@ gtk_file_system_model_set_sort_column_id (GtkTreeSortable *sortable,
{
if (sort_column_id != GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
{
#ifndef G_DISABLE_CHECKS
GtkTreeDataSortHeader *header = NULL;
header = _gtk_tree_data_list_get_header (model->sort_list,
@ -875,6 +876,7 @@ gtk_file_system_model_set_sort_column_id (GtkTreeSortable *sortable,
/* We want to make sure that we have a function */
g_return_if_fail (header != NULL);
g_return_if_fail (header->func != NULL);
#endif
}
else
{

View File

@ -4688,30 +4688,19 @@ gtk_icon_view_set_model (GtkIconView *icon_view,
if (model)
{
GType column_type;
if (icon_view->priv->pixbuf_column != -1)
{
column_type = gtk_tree_model_get_column_type (model,
icon_view->priv->pixbuf_column);
g_return_if_fail (column_type == GDK_TYPE_PIXBUF);
g_return_if_fail (gtk_tree_model_get_column_type (model, icon_view->priv->pixbuf_column) == GDK_TYPE_PIXBUF);
}
if (icon_view->priv->text_column != -1)
{
column_type = gtk_tree_model_get_column_type (model,
icon_view->priv->text_column);
g_return_if_fail (column_type == G_TYPE_STRING);
g_return_if_fail (gtk_tree_model_get_column_type (model, icon_view->priv->text_column) == G_TYPE_STRING);
}
if (icon_view->priv->markup_column != -1)
{
column_type = gtk_tree_model_get_column_type (model,
icon_view->priv->markup_column);
g_return_if_fail (column_type == G_TYPE_STRING);
g_return_if_fail (gtk_tree_model_get_column_type (model, icon_view->priv->markup_column) == G_TYPE_STRING);
}
}
@ -4911,11 +4900,7 @@ gtk_icon_view_set_text_column (GtkIconView *icon_view,
{
if (icon_view->priv->model != NULL)
{
GType column_type;
column_type = gtk_tree_model_get_column_type (icon_view->priv->model, column);
g_return_if_fail (column_type == G_TYPE_STRING);
g_return_if_fail (gtk_tree_model_get_column_type (icon_view->priv->model, column) == G_TYPE_STRING);
}
icon_view->priv->text_column = column;
@ -4970,11 +4955,7 @@ gtk_icon_view_set_markup_column (GtkIconView *icon_view,
{
if (icon_view->priv->model != NULL)
{
GType column_type;
column_type = gtk_tree_model_get_column_type (icon_view->priv->model, column);
g_return_if_fail (column_type == G_TYPE_STRING);
g_return_if_fail (gtk_tree_model_get_column_type (icon_view->priv->model, column) == G_TYPE_STRING);
}
icon_view->priv->markup_column = column;
@ -5027,11 +5008,7 @@ gtk_icon_view_set_pixbuf_column (GtkIconView *icon_view,
{
if (icon_view->priv->model != NULL)
{
GType column_type;
column_type = gtk_tree_model_get_column_type (icon_view->priv->model, column);
g_return_if_fail (column_type == GDK_TYPE_PIXBUF);
g_return_if_fail (gtk_tree_model_get_column_type (icon_view->priv->model, column) == GDK_TYPE_PIXBUF);
}
icon_view->priv->pixbuf_column = column;

View File

@ -276,6 +276,7 @@ gtk_level_bar_ensure_offset (GtkLevelBar *self,
return TRUE;
}
#ifndef G_DISABLE_CHECKS
static gboolean
gtk_level_bar_value_in_interval (GtkLevelBar *self,
gdouble value)
@ -285,6 +286,7 @@ gtk_level_bar_value_in_interval (GtkLevelBar *self,
return ((value >= priv->min_value) &&
(value <= priv->max_value));
}
#endif
static gint
gtk_level_bar_get_num_blocks (GtkLevelBar *self)

View File

@ -1304,12 +1304,14 @@ translate_event_coordinates (GdkEvent *event,
return TRUE;
}
void
static void
gtk_synthesize_crossing_events (GtkRoot *toplevel,
GtkCrossingType crossing_type,
GtkWidget *old_target,
GtkWidget *new_target,
GdkEvent *event,
GdkCrossingMode mode)
GdkCrossingMode mode,
GdkDrop *drop)
{
GtkCrossingData crossing;
GtkWidget *ancestor;
@ -1319,17 +1321,21 @@ gtk_synthesize_crossing_events (GtkRoot *toplevel,
GtkWidget *prev;
gboolean seen_ancestor;
if (old_target == new_target)
return;
if (old_target && new_target)
ancestor = gtk_widget_common_ancestor (old_target, new_target);
else
ancestor = NULL;
crossing.type = GTK_CROSSING_POINTER;
crossing.type = crossing_type;
crossing.mode = mode;
crossing.old_target = old_target;
crossing.old_descendent = NULL;
crossing.new_target = new_target;
crossing.new_descendent = NULL;
crossing.drop = drop;
crossing.direction = GTK_CROSSING_OUT;
@ -1360,7 +1366,8 @@ gtk_synthesize_crossing_events (GtkRoot *toplevel,
check_crossing_invariants (widget, &crossing);
translate_event_coordinates (event, &x, &y, widget);
gtk_widget_handle_crossing (widget, &crossing, x, y);
gtk_widget_unset_state_flags (widget, GTK_STATE_FLAG_PRELIGHT);
if (crossing_type == GTK_CROSSING_POINTER)
gtk_widget_unset_state_flags (widget, GTK_STATE_FLAG_PRELIGHT);
widget = gtk_widget_get_parent (widget);
}
@ -1399,7 +1406,8 @@ gtk_synthesize_crossing_events (GtkRoot *toplevel,
translate_event_coordinates (event, &x, &y, widget);
gtk_widget_handle_crossing (widget, &crossing, x, y);
gtk_widget_set_state_flags (widget, GTK_STATE_FLAG_PRELIGHT, FALSE);
if (crossing_type == GTK_CROSSING_POINTER)
gtk_widget_set_state_flags (widget, GTK_STATE_FLAG_PRELIGHT, FALSE);
}
g_list_free (list);
@ -1445,8 +1453,12 @@ is_pointing_event (GdkEvent *event)
case GDK_TOUCH_CANCEL:
case GDK_TOUCHPAD_PINCH:
case GDK_TOUCHPAD_SWIPE:
case GDK_DRAG_ENTER:
case GDK_DRAG_LEAVE:
case GDK_DRAG_MOTION:
case GDK_DROP_START:
return TRUE;
break;
default:
return FALSE;
}
@ -1479,21 +1491,6 @@ is_focus_event (GdkEvent *event)
}
}
static gboolean
is_dnd_event (GdkEvent *event)
{
switch ((guint) gdk_event_get_event_type (event))
{
case GDK_DRAG_ENTER:
case GDK_DRAG_LEAVE:
case GDK_DRAG_MOTION:
case GDK_DROP_START:
return TRUE;
default:
return FALSE;
}
}
static inline void
set_widget_active_state (GtkWidget *target,
const gboolean release)
@ -1549,14 +1546,22 @@ handle_pointing_event (GdkEvent *event)
case GDK_TOUCH_CANCEL:
old_target = update_pointer_focus_state (toplevel, event, NULL);
if (type == GDK_LEAVE_NOTIFY)
gtk_synthesize_crossing_events (GTK_ROOT (toplevel), old_target, NULL,
event, gdk_crossing_event_get_mode (event));
gtk_synthesize_crossing_events (GTK_ROOT (toplevel), GTK_CROSSING_POINTER, old_target, NULL,
event, gdk_crossing_event_get_mode (event), NULL);
break;
case GDK_DRAG_LEAVE:
old_target = update_pointer_focus_state (toplevel, event, NULL);
gtk_synthesize_crossing_events (GTK_ROOT (toplevel), GTK_CROSSING_DROP, old_target, NULL,
event, GDK_CROSSING_NORMAL, gdk_drag_event_get_drop (event));
break;
case GDK_ENTER_NOTIFY:
if (gdk_crossing_event_get_mode (event) == GDK_CROSSING_GRAB ||
gdk_crossing_event_get_mode (event) == GDK_CROSSING_UNGRAB)
break;
G_GNUC_FALLTHROUGH;
case GDK_DRAG_ENTER:
case GDK_DRAG_MOTION:
case GDK_DROP_START:
case GDK_TOUCH_BEGIN:
case GDK_TOUCH_UPDATE:
case GDK_MOTION_NOTIFY:
@ -1575,14 +1580,18 @@ handle_pointing_event (GdkEvent *event)
if (!gtk_window_lookup_pointer_focus_implicit_grab (toplevel, device,
sequence))
{
gtk_synthesize_crossing_events (GTK_ROOT (toplevel), old_target, target,
event, GDK_CROSSING_NORMAL);
gtk_synthesize_crossing_events (GTK_ROOT (toplevel), GTK_CROSSING_POINTER, old_target, target,
event, GDK_CROSSING_NORMAL, NULL);
}
gtk_window_maybe_update_cursor (toplevel, NULL, device);
}
if (type == GDK_TOUCH_BEGIN)
else if (type == GDK_DRAG_ENTER || type == GDK_DRAG_MOTION || type == GDK_DROP_START)
{
gtk_synthesize_crossing_events (GTK_ROOT (toplevel), GTK_CROSSING_DROP, old_target, target,
event, GDK_CROSSING_NORMAL, gdk_drag_event_get_drop (event));
}
else if (type == GDK_TOUCH_BEGIN)
gtk_window_set_pointer_focus_grab (toplevel, device, sequence, target);
/* Let it take the effective pointer focus anyway, as it may change due
@ -1605,8 +1614,8 @@ handle_pointing_event (GdkEvent *event)
new_target = gtk_widget_pick (GTK_WIDGET (native), x, y, GTK_PICK_DEFAULT);
if (new_target == NULL)
new_target = GTK_WIDGET (toplevel);
gtk_synthesize_crossing_events (GTK_ROOT (toplevel), target, new_target,
event, GDK_CROSSING_UNGRAB);
gtk_synthesize_crossing_events (GTK_ROOT (toplevel), GTK_CROSSING_POINTER, target, new_target,
event, GDK_CROSSING_UNGRAB, NULL);
gtk_window_maybe_update_cursor (toplevel, NULL, device);
}
@ -1640,23 +1649,6 @@ handle_key_event (GdkEvent *event)
return focus_widget ? focus_widget : event_widget;
}
static GtkWidget *
handle_dnd_event (GdkEvent *event)
{
GtkWidget *event_widget;
GtkWidget *target;
gdouble x, y;
GtkWidget *native;
event_widget = gtk_get_event_widget (event);
gdk_event_get_position (event, &x, &y);
native = GTK_WIDGET (gtk_widget_get_native (event_widget));
target = gtk_widget_pick (native, x, y, GTK_PICK_DEFAULT);
return target;
}
void
gtk_main_do_event (GdkEvent *event)
{
@ -1715,8 +1707,6 @@ gtk_main_do_event (GdkEvent *event)
goto cleanup;
}
}
else if (is_dnd_event (event))
target_widget = handle_dnd_event (event);
if (!target_widget)
goto cleanup;
@ -1812,14 +1802,15 @@ gtk_main_do_event (GdkEvent *event)
/* Crossing event propagation happens during picking */
break;
case GDK_DRAG_ENTER:
case GDK_DRAG_MOTION:
case GDK_DROP_START:
if (gtk_propagate_event (target_widget, event))
break;
G_GNUC_FALLTHROUGH;
case GDK_DRAG_ENTER:
case GDK_DRAG_LEAVE:
/* Crossing event propagation happens during picking */
gtk_drag_dest_handle_event (target_widget, event);
break;

View File

@ -35,6 +35,7 @@
#include "gtkcssstylepropertyprivate.h"
#include "gtkdragdest.h"
#include "gtkdragicon.h"
#include "gtkdropcontrollermotion.h"
#include "gtkeventcontrollermotion.h"
#include "gtkgestureclick.h"
#include "gtkgizmoprivate.h"
@ -3081,12 +3082,13 @@ gtk_notebook_state_flags_changed (GtkWidget *widget,
}
static void
gtk_notebook_arrow_drag_enter (GtkDropTarget *target,
GdkDrop *drop,
GtkNotebook *notebook)
gtk_notebook_arrow_drag_enter (GtkDropControllerMotion *motion,
double x,
double y,
GtkNotebook *notebook)
{
GtkNotebookPrivate *priv = notebook->priv;
GtkWidget *arrow_widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (target));
GtkWidget *arrow_widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (motion));
guint arrow;
for (arrow = 0; arrow < 4; arrow++)
@ -3099,7 +3101,6 @@ gtk_notebook_arrow_drag_enter (GtkDropTarget *target,
priv->click_child = arrow;
gtk_notebook_set_scroll_timer (notebook);
gdk_drop_status (drop, 0);
}
static void
@ -3192,9 +3193,9 @@ update_arrow_nodes (GtkNotebook *notebook)
priv->arrow_widget[i] = g_object_new (GTK_TYPE_BUTTON,
"css-name", "arrow",
NULL);
controller = GTK_EVENT_CONTROLLER (gtk_drop_target_new (NULL, GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK | GDK_ACTION_ASK));
g_signal_connect (controller, "drag-enter", G_CALLBACK (gtk_notebook_arrow_drag_enter), notebook);
g_signal_connect (controller, "drag-leave", G_CALLBACK (gtk_notebook_arrow_drag_leave), notebook);
controller = gtk_drop_controller_motion_new ();
g_signal_connect (controller, "enter", G_CALLBACK (gtk_notebook_arrow_drag_enter), notebook);
g_signal_connect (controller, "leave", G_CALLBACK (gtk_notebook_arrow_drag_leave), notebook);
gtk_widget_add_controller (priv->arrow_widget[i], controller);
if (i == ARROW_LEFT_BEFORE || i == ARROW_LEFT_AFTER)

View File

@ -546,7 +546,8 @@ present_popup (GtkPopover *popover)
layout = create_popup_layout (popover);
gtk_widget_get_preferred_size (GTK_WIDGET (popover), NULL, &req);
if (gdk_surface_present_popup (priv->surface,
req.width, req.height,
MAX (req.width, 1),
MAX (req.height, 1),
layout))
update_popover_layout (popover, layout);
}

View File

@ -3491,12 +3491,11 @@ gtk_scrolled_window_add (GtkContainer *container,
GtkScrolledWindow *scrolled_window = GTK_SCROLLED_WINDOW (container);
GtkScrolledWindowPrivate *priv = gtk_scrolled_window_get_instance_private (scrolled_window);
GtkBin *bin;
GtkWidget *child_widget, *scrollable_child;
GtkWidget *scrollable_child;
GtkAdjustment *hadj, *vadj;
bin = GTK_BIN (container);
child_widget = gtk_bin_get_child (bin);
g_return_if_fail (child_widget == NULL);
g_return_if_fail (gtk_bin_get_child (GTK_BIN (scrolled_window)) == NULL);
/* gtk_scrolled_window_set_[hv]adjustment have the side-effect
* of creating the scrollbars

View File

@ -182,6 +182,7 @@ gtk_widget_query_size_for_orientation (GtkWidget *widget,
int css_min_for_size;
int css_extra_for_size;
int css_extra_size;
int widget_margins_for_size;
style = gtk_css_node_get_style (gtk_widget_get_css_node (widget));
get_box_margin (style, &margin);
@ -196,6 +197,7 @@ gtk_widget_query_size_for_orientation (GtkWidget *widget,
css_extra_for_size = margin.top + margin.bottom + border.top + border.bottom + padding.top + padding.bottom;
css_min_size = get_number_ceil (style->size->min_width);
css_min_for_size = get_number_ceil (style->size->min_height);
widget_margins_for_size = widget->priv->margin.top + widget->priv->margin.bottom;
}
else
{
@ -203,6 +205,7 @@ gtk_widget_query_size_for_orientation (GtkWidget *widget,
css_extra_for_size = margin.left + margin.right + border.left + border.right + padding.left + padding.right;
css_min_size = get_number_ceil (style->size->min_height);
css_min_for_size = get_number_ceil (style->size->min_width);
widget_margins_for_size = widget->priv->margin.left + widget->priv->margin.right;
}
GtkLayoutManager *layout_manager = gtk_widget_get_layout_manager (widget);
@ -223,7 +226,6 @@ gtk_widget_query_size_for_orientation (GtkWidget *widget,
int adjusted_for_size;
int minimum_for_size = 0;
int natural_for_size = 0;
int dummy = 0;
/* Pull the minimum for_size from the cache as it's needed to adjust
* the proposed 'for_size' */
@ -235,10 +237,7 @@ gtk_widget_query_size_for_orientation (GtkWidget *widget,
if (for_size < MAX (minimum_for_size, css_min_for_size))
for_size = MAX (minimum_for_size, css_min_for_size);
adjusted_for_size = for_size;
gtk_widget_adjust_size_allocation (widget, OPPOSITE_ORIENTATION (orientation),
&for_size, &natural_for_size,
&dummy, &adjusted_for_size);
adjusted_for_size = for_size - widget_margins_for_size;
adjusted_for_size -= css_extra_for_size;
if (adjusted_for_size < 0)
adjusted_for_size = MAX (minimum_for_size, css_min_for_size);
@ -267,7 +266,6 @@ gtk_widget_query_size_for_orientation (GtkWidget *widget,
int adjusted_for_size;
int minimum_for_size = 0;
int natural_for_size = 0;
int dummy = 0;
/* Pull the minimum for_size from the cache as it's needed to adjust
* the proposed 'for_size' */
@ -278,10 +276,7 @@ gtk_widget_query_size_for_orientation (GtkWidget *widget,
if (for_size < MAX (minimum_for_size, css_min_for_size))
for_size = MAX (minimum_for_size, css_min_for_size);
adjusted_for_size = for_size;
gtk_widget_adjust_size_allocation (widget, OPPOSITE_ORIENTATION (orientation),
&for_size, &natural_for_size,
&dummy, &adjusted_for_size);
adjusted_for_size = for_size - widget_margins_for_size;
adjusted_for_size -= css_extra_for_size;

View File

@ -22,7 +22,7 @@
#include "gtkstackswitcher.h"
#include "gtkboxlayout.h"
#include "gtkdragdest.h"
#include "gtkdropcontrollermotion.h"
#include "gtkimage.h"
#include "gtkintl.h"
#include "gtklabel.h"
@ -85,8 +85,6 @@ struct _GtkStackSwitcherPrivate
GtkStack *stack;
GtkSelectionModel *pages;
GHashTable *buttons;
GtkWidget *switch_button;
guint switch_timer;
};
enum {
@ -94,36 +92,16 @@ enum {
PROP_STACK
};
static void gtk_stack_switcher_drag_leave (GtkDropTarget *dest,
GdkDrop *drop,
GtkStackSwitcher *self);
static gboolean gtk_stack_switcher_drag_accept (GtkDropTarget *dest,
GdkDrop *drop,
GtkStackSwitcher *self);
static void gtk_stack_switcher_drag_motion (GtkDropTarget *dest,
GdkDrop *drop,
int x,
int y,
GtkStackSwitcher *self);
G_DEFINE_TYPE_WITH_PRIVATE (GtkStackSwitcher, gtk_stack_switcher, GTK_TYPE_WIDGET)
static void
gtk_stack_switcher_init (GtkStackSwitcher *switcher)
{
GtkStackSwitcherPrivate *priv = gtk_stack_switcher_get_instance_private (switcher);
GtkDropTarget *dest;
priv->buttons = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, NULL);
gtk_widget_add_css_class (GTK_WIDGET (switcher), "linked");
dest = gtk_drop_target_new (NULL, 0);
g_signal_connect (dest, "drag-leave", G_CALLBACK (gtk_stack_switcher_drag_leave), switcher);
g_signal_connect (dest, "accept", G_CALLBACK (gtk_stack_switcher_drag_accept), switcher);
g_signal_connect (dest, "drag-motion", G_CALLBACK (gtk_stack_switcher_drag_motion), switcher);
gtk_widget_add_controller (GTK_WIDGET (switcher), GTK_EVENT_CONTROLLER (dest));
}
static void
@ -230,29 +208,12 @@ on_page_updated (GtkStackPage *page,
update_button (self, page, button);
}
static void
remove_switch_timer (GtkStackSwitcher *self)
{
GtkStackSwitcherPrivate *priv = gtk_stack_switcher_get_instance_private (self);
if (priv->switch_timer)
{
g_source_remove (priv->switch_timer);
priv->switch_timer = 0;
}
}
static gboolean
gtk_stack_switcher_switch_timeout (gpointer data)
{
GtkStackSwitcher *self = data;
GtkStackSwitcherPrivate *priv = gtk_stack_switcher_get_instance_private (self);
GtkWidget *button;
GtkWidget *button = data;
priv->switch_timer = 0;
button = priv->switch_button;
priv->switch_button = NULL;
g_object_steal_data (G_OBJECT (button), "-gtk-switch-timer");
if (button)
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
@ -260,59 +221,34 @@ gtk_stack_switcher_switch_timeout (gpointer data)
return G_SOURCE_REMOVE;
}
static gboolean
gtk_stack_switcher_drag_accept (GtkDropTarget *dest,
GdkDrop *drop,
GtkStackSwitcher *self)
{
return TRUE;
}
static void
gtk_stack_switcher_drag_motion (GtkDropTarget *dest,
GdkDrop *drop,
int x,
int y,
GtkStackSwitcher *self)
gtk_stack_switcher_drag_enter (GtkDropControllerMotion *motion,
double x,
double y,
gpointer unused)
{
GtkStackSwitcherPrivate *priv = gtk_stack_switcher_get_instance_private (self);
GtkWidget *button;
GHashTableIter iter;
gpointer value;
GtkWidget *button = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (motion));
button = NULL;
g_hash_table_iter_init (&iter, priv->buttons);
while (g_hash_table_iter_next (&iter, NULL, &value))
if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)))
{
int cx, cy;
gtk_widget_translate_coordinates (GTK_WIDGET (self), value, x, y, &cx, &cy);
if (gtk_widget_contains (GTK_WIDGET (value), cx, cy))
{
button = GTK_WIDGET (value);
break;
}
}
if (button != priv->switch_button)
remove_switch_timer (self);
priv->switch_button = button;
if (button && !priv->switch_timer)
{
priv->switch_timer = g_timeout_add (TIMEOUT_EXPAND,
guint switch_timer = g_timeout_add (TIMEOUT_EXPAND,
gtk_stack_switcher_switch_timeout,
self);
g_source_set_name_by_id (priv->switch_timer, "[gtk] gtk_stack_switcher_switch_timeout");
button);
g_source_set_name_by_id (switch_timer, "[gtk] gtk_stack_switcher_switch_timeout");
g_object_set_data (G_OBJECT (button), "-gtk-switch-timer", GUINT_TO_POINTER (switch_timer));
}
}
static void
gtk_stack_switcher_drag_leave (GtkDropTarget *dest,
GdkDrop *drop,
GtkStackSwitcher *self)
gtk_stack_switcher_drag_leave (GtkDropControllerMotion *motion,
gpointer unused)
{
remove_switch_timer (self);
GtkWidget *button = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (motion));
guint switch_timer;
switch_timer = GPOINTER_TO_UINT (g_object_steal_data (G_OBJECT (button), "-gtk-switch-timer"));
if (switch_timer)
g_source_remove (switch_timer);
}
static void
@ -323,10 +259,16 @@ add_child (guint position,
GtkWidget *button;
gboolean selected;
GtkStackPage *page;
GtkEventController *controller;
button = gtk_toggle_button_new ();
gtk_widget_set_focus_on_click (button, FALSE);
controller = gtk_drop_controller_motion_new ();
g_signal_connect (controller, "enter", G_CALLBACK (gtk_stack_switcher_drag_enter), NULL);
g_signal_connect (controller, "leave", G_CALLBACK (gtk_stack_switcher_drag_leave), NULL);
gtk_widget_add_controller (button, controller);
page = g_list_model_get_item (G_LIST_MODEL (priv->pages), position);
update_button (self, page, button);
@ -549,7 +491,6 @@ gtk_stack_switcher_dispose (GObject *object)
{
GtkStackSwitcher *switcher = GTK_STACK_SWITCHER (object);
remove_switch_timer (switcher);
unset_stack (switcher);
G_OBJECT_CLASS (gtk_stack_switcher_parent_class)->dispose (object);

View File

@ -125,33 +125,22 @@ create_popup_layout (GtkTooltipWindow *window)
}
static void
relayout_popup (GtkTooltipWindow *window)
{
GdkPopupLayout *layout;
if (!gtk_widget_get_visible (GTK_WIDGET (window)))
return;
layout = create_popup_layout (window);
gdk_surface_present_popup (window->surface,
gdk_surface_get_width (window->surface),
gdk_surface_get_height (window->surface),
layout);
gdk_popup_layout_unref (layout);
}
static void
gtk_tooltip_window_move_resize (GtkTooltipWindow *window)
gtk_tooltip_window_relayout (GtkTooltipWindow *window)
{
GtkRequisition req;
GdkPopupLayout *layout;
if (window->surface)
{
gtk_widget_get_preferred_size (GTK_WIDGET (window), NULL, &req);
gdk_surface_resize (window->surface, req.width, req.height);
if (!gtk_widget_get_visible (GTK_WIDGET (window)) ||
window->surface == NULL)
return;
relayout_popup (window);
}
gtk_widget_get_preferred_size (GTK_WIDGET (window), NULL, &req);
layout = create_popup_layout (window);
gdk_surface_present_popup (window->surface,
MAX (req.width, 1),
MAX (req.height, 1),
layout);
gdk_popup_layout_unref (layout);
}
static void
@ -164,7 +153,7 @@ gtk_tooltip_window_native_check_resize (GtkNative *native)
gtk_widget_ensure_allocate (widget);
else if (gtk_widget_get_visible (widget))
{
gtk_tooltip_window_move_resize (window);
gtk_tooltip_window_relayout (window);
if (window->surface)
gtk_widget_allocate (GTK_WIDGET (window),
gdk_surface_get_width (window->surface),
@ -281,7 +270,7 @@ surface_transform_changed_cb (GtkWidget *widget,
{
GtkTooltipWindow *window = GTK_TOOLTIP_WINDOW (widget);
relayout_popup (window);
gtk_tooltip_window_relayout (window);
return G_SOURCE_CONTINUE;
}
@ -361,8 +350,6 @@ gtk_tooltip_window_size_allocate (GtkWidget *widget,
GtkTooltipWindow *window = GTK_TOOLTIP_WINDOW (widget);
GtkWidget *child;
gtk_tooltip_window_move_resize (window);
child = gtk_bin_get_child (GTK_BIN (window));
if (child)
@ -608,6 +595,6 @@ gtk_tooltip_window_position (GtkTooltipWindow *window,
window->dx = dx;
window->dy = dy;
relayout_popup (window);
gtk_tooltip_window_relayout (window);
}

View File

@ -7623,9 +7623,7 @@ gtk_tree_view_set_fixed_height_mode (GtkTreeView *tree_view,
/* make sure all columns are of type FIXED */
for (l = tree_view->columns; l; l = l->next)
{
GtkTreeViewColumn *c = l->data;
g_return_if_fail (gtk_tree_view_column_get_sizing (c) == GTK_TREE_VIEW_COLUMN_FIXED);
g_return_if_fail (gtk_tree_view_column_get_sizing (l->data) == GTK_TREE_VIEW_COLUMN_FIXED);
}
/* yes, we really have to do this is in a separate loop */
@ -12073,6 +12071,7 @@ gtk_tree_view_set_cursor_on_cell (GtkTreeView *tree_view,
if (focus_column &&
gtk_tree_view_column_get_visible (focus_column))
{
#ifndef G_DISABLE_CHECKS
GList *list;
gboolean column_in_tree = FALSE;
@ -12083,6 +12082,7 @@ gtk_tree_view_set_cursor_on_cell (GtkTreeView *tree_view,
break;
}
g_return_if_fail (column_in_tree);
#endif
_gtk_tree_view_set_focus_column (tree_view, focus_column);
if (focus_cell)
gtk_tree_view_column_focus_cell (focus_column, focus_cell);

View File

@ -1298,11 +1298,9 @@ gtk_tree_view_column_remove_editable_callback (GtkCellArea *area,
void
_gtk_tree_view_column_realize_button (GtkTreeViewColumn *column)
{
GtkTreeViewColumnPrivate *priv = column->priv;
g_return_if_fail (GTK_IS_TREE_VIEW (priv->tree_view));
g_return_if_fail (gtk_widget_get_realized (priv->tree_view));
g_return_if_fail (priv->button != NULL);
g_return_if_fail (GTK_IS_TREE_VIEW (column->priv->tree_view));
g_return_if_fail (gtk_widget_get_realized (column->priv->tree_view));
g_return_if_fail (column->priv->button != NULL);
gtk_tree_view_column_update_button (column);
}

View File

@ -3907,6 +3907,118 @@ gtk_widget_size_allocate (GtkWidget *widget,
transform);
}
/* translate initial/final into start/end */
static GtkAlign
effective_align (GtkAlign align,
GtkTextDirection direction)
{
switch (align)
{
case GTK_ALIGN_START:
return direction == GTK_TEXT_DIR_RTL ? GTK_ALIGN_END : GTK_ALIGN_START;
case GTK_ALIGN_END:
return direction == GTK_TEXT_DIR_RTL ? GTK_ALIGN_START : GTK_ALIGN_END;
case GTK_ALIGN_FILL:
case GTK_ALIGN_CENTER:
case GTK_ALIGN_BASELINE:
default:
return align;
}
}
static void
adjust_for_align (GtkAlign align,
gint natural_size,
gint *allocated_pos,
gint *allocated_size)
{
switch (align)
{
case GTK_ALIGN_BASELINE:
case GTK_ALIGN_FILL:
default:
/* change nothing */
break;
case GTK_ALIGN_START:
/* keep *allocated_pos where it is */
*allocated_size = MIN (*allocated_size, natural_size);
break;
case GTK_ALIGN_END:
if (*allocated_size > natural_size)
{
*allocated_pos += (*allocated_size - natural_size);
*allocated_size = natural_size;
}
break;
case GTK_ALIGN_CENTER:
if (*allocated_size > natural_size)
{
*allocated_pos += (*allocated_size - natural_size) / 2;
*allocated_size = MIN (*allocated_size, natural_size);
}
break;
}
}
static inline void
gtk_widget_adjust_size_allocation (GtkWidget *widget,
GtkAllocation *allocation)
{
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
gint natural_width, natural_height;
gint min_width, min_height;
if (priv->halign == GTK_ALIGN_FILL && priv->valign == GTK_ALIGN_FILL)
return;
if (gtk_widget_get_request_mode (widget) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
{
/* Go ahead and request the height for allocated width, note that the internals
* of get_height_for_width will internally limit the for_size to natural size
* when aligning implicitly.
*/
gtk_widget_measure (widget, GTK_ORIENTATION_HORIZONTAL, -1,
&min_width, &natural_width, NULL, NULL);
gtk_widget_measure (widget, GTK_ORIENTATION_VERTICAL,
allocation->width + priv->margin.left + priv->margin.right,
&min_height, &natural_height, NULL, NULL);
}
else
{
/* Go ahead and request the width for allocated height, note that the internals
* of get_width_for_height will internally limit the for_size to natural size
* when aligning implicitly.
*/
gtk_widget_measure (widget, GTK_ORIENTATION_VERTICAL, -1,
&min_height, &natural_height, NULL, NULL);
gtk_widget_measure (widget, GTK_ORIENTATION_HORIZONTAL,
allocation->height + priv->margin.top + priv->margin.bottom,
&min_width, &natural_width, NULL, NULL);
}
#ifdef G_ENABLE_CONSISTENCY_CHECKS
if ((min_width > allocation->width + priv->margin.left + priv->margin.right ||
min_height > allocation->height + priv->margin.top + priv->margin.bottom) &&
!GTK_IS_SCROLLABLE (widget))
g_warning ("gtk_widget_size_allocate(): attempt to underallocate %s%s %s %p. "
"Allocation is %dx%d, but minimum required size is %dx%d.",
priv->parent ? G_OBJECT_TYPE_NAME (priv->parent) : "", priv->parent ? "'s child" : "toplevel",
G_OBJECT_TYPE_NAME (widget), widget,
allocation->width, allocation->height,
min_width, min_height);
#endif
/* Now that we have the right natural height and width, go ahead and remove any margins from the
* allocated sizes and possibly limit them to the natural sizes */
adjust_for_align (effective_align (priv->halign, _gtk_widget_get_direction (widget)),
natural_width - priv->margin.left - priv->margin.right,
&allocation->x,
&allocation->width);
adjust_for_align (priv->valign,
natural_height - priv->margin.top - priv->margin.bottom,
&allocation->y,
&allocation->height);
}
/**
* gtk_widget_allocate:
* @widget: A #GtkWidget
@ -3937,8 +4049,6 @@ gtk_widget_allocate (GtkWidget *widget,
gboolean size_changed;
gboolean baseline_changed;
gboolean transform_changed;
gint natural_width, natural_height, dummy = 0;
gint min_width, min_height;
GtkCssStyle *style;
GtkBorder margin, border, padding;
GskTransform *css_transform;
@ -3982,59 +4092,17 @@ gtk_widget_allocate (GtkWidget *widget,
priv->allocated_height = height;
priv->allocated_size_baseline = baseline;
adjusted = (GdkRectangle) { 0, 0, width, height };
if (gtk_widget_get_request_mode (widget) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
{
/* Go ahead and request the height for allocated width, note that the internals
* of get_height_for_width will internally limit the for_size to natural size
* when aligning implicitly.
*/
gtk_widget_measure (widget, GTK_ORIENTATION_HORIZONTAL, -1,
&min_width, &natural_width, NULL, NULL);
gtk_widget_measure (widget, GTK_ORIENTATION_VERTICAL, width,
&min_height, &natural_height, NULL, NULL);
}
else
{
/* Go ahead and request the width for allocated height, note that the internals
* of get_width_for_height will internally limit the for_size to natural size
* when aligning implicitly.
*/
gtk_widget_measure (widget, GTK_ORIENTATION_VERTICAL, -1,
&min_height, &natural_height, NULL, NULL);
gtk_widget_measure (widget, GTK_ORIENTATION_HORIZONTAL, height,
&min_width, &natural_width, NULL, NULL);
}
#ifdef G_ENABLE_CONSISTENCY_CHECKS
if ((min_width > width || min_height > height) &&
!GTK_IS_SCROLLABLE (widget))
g_warning ("gtk_widget_size_allocate(): attempt to underallocate %s%s %s %p. "
"Allocation is %dx%d, but minimum required size is %dx%d.",
priv->parent ? G_OBJECT_TYPE_NAME (priv->parent) : "", priv->parent ? "'s child" : "toplevel",
G_OBJECT_TYPE_NAME (widget), widget,
width, height,
min_width, min_height);
#endif
/* Now that we have the right natural height and width, go ahead and remove any margins from the
* allocated sizes and possibly limit them to the natural sizes */
gtk_widget_adjust_size_allocation (widget,
GTK_ORIENTATION_HORIZONTAL,
&dummy,
&natural_width,
&adjusted.x,
&adjusted.width);
gtk_widget_adjust_size_allocation (widget,
GTK_ORIENTATION_VERTICAL,
&dummy,
&natural_height,
&adjusted.y,
&adjusted.height);
size_changed = (priv->width != adjusted.width) || (priv->height != adjusted.height);
adjusted.x = priv->margin.left;
adjusted.y = priv->margin.top;
adjusted.width = width - priv->margin.left - priv->margin.right;
adjusted.height = height - priv->margin.top - priv->margin.bottom;
if (baseline >= 0)
baseline -= priv->margin.top;
gtk_widget_adjust_size_allocation (widget, &adjusted);
size_changed = (priv->width != adjusted.width) || (priv->height != adjusted.height);
if (adjusted.width < 0 || adjusted.height < 0)
{
g_warning ("gtk_widget_size_allocate(): attempt to allocate %s %s %p with width %d and height %d",
@ -4046,12 +4114,6 @@ gtk_widget_allocate (GtkWidget *widget,
adjusted.height = 0;
}
if (G_UNLIKELY (GTK_IS_NATIVE (widget)))
{
adjusted.width = MAX (1, adjusted.width);
adjusted.height = MAX (1, adjusted.height);
}
style = gtk_css_node_get_style (priv->cssnode);
get_box_margin (style, &margin);
get_box_border (style, &border);
@ -4296,103 +4358,6 @@ gtk_widget_real_size_allocate (GtkWidget *widget,
{
}
/* translate initial/final into start/end */
static GtkAlign
effective_align (GtkAlign align,
GtkTextDirection direction)
{
switch (align)
{
case GTK_ALIGN_START:
return direction == GTK_TEXT_DIR_RTL ? GTK_ALIGN_END : GTK_ALIGN_START;
case GTK_ALIGN_END:
return direction == GTK_TEXT_DIR_RTL ? GTK_ALIGN_START : GTK_ALIGN_END;
case GTK_ALIGN_FILL:
case GTK_ALIGN_CENTER:
case GTK_ALIGN_BASELINE:
default:
return align;
}
}
static void
adjust_for_align (GtkAlign align,
gint *natural_size,
gint *allocated_pos,
gint *allocated_size)
{
switch (align)
{
case GTK_ALIGN_BASELINE:
case GTK_ALIGN_FILL:
default:
/* change nothing */
break;
case GTK_ALIGN_START:
/* keep *allocated_pos where it is */
*allocated_size = MIN (*allocated_size, *natural_size);
break;
case GTK_ALIGN_END:
if (*allocated_size > *natural_size)
{
*allocated_pos += (*allocated_size - *natural_size);
*allocated_size = *natural_size;
}
break;
case GTK_ALIGN_CENTER:
if (*allocated_size > *natural_size)
{
*allocated_pos += (*allocated_size - *natural_size) / 2;
*allocated_size = MIN (*allocated_size, *natural_size);
}
break;
}
}
static void
adjust_for_margin(gint start_margin,
gint end_margin,
gint *minimum_size,
gint *natural_size,
gint *allocated_pos,
gint *allocated_size)
{
*minimum_size -= (start_margin + end_margin);
*natural_size -= (start_margin + end_margin);
*allocated_pos += start_margin;
*allocated_size -= (start_margin + end_margin);
}
void
gtk_widget_adjust_size_allocation (GtkWidget *widget,
GtkOrientation orientation,
gint *minimum_size,
gint *natural_size,
gint *allocated_pos,
gint *allocated_size)
{
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
if (orientation == GTK_ORIENTATION_HORIZONTAL)
{
adjust_for_margin (priv->margin.left,
priv->margin.right,
minimum_size, natural_size,
allocated_pos, allocated_size);
adjust_for_align (effective_align (priv->halign, _gtk_widget_get_direction (widget)),
natural_size, allocated_pos, allocated_size);
}
else
{
adjust_for_margin (priv->margin.top,
priv->margin.bottom,
minimum_size, natural_size,
allocated_pos, allocated_size);
adjust_for_align (effective_align (priv->valign, GTK_TEXT_DIR_NONE),
natural_size, allocated_pos, allocated_size);
}
}
static gboolean
gtk_widget_real_can_activate_accel (GtkWidget *widget,
guint signal_id)

View File

@ -259,12 +259,6 @@ GdkSurface * _gtk_widget_get_device_surface (GtkWidget *widget,
GdkDevice *device);
GList * _gtk_widget_list_devices (GtkWidget *widget);
void gtk_synthesize_crossing_events (GtkRoot *toplevel,
GtkWidget *from,
GtkWidget *to,
GdkEvent *source,
GdkCrossingMode mode);
void _gtk_widget_synthesize_crossing (GtkWidget *from,
GtkWidget *to,
GdkDevice *device,
@ -310,12 +304,6 @@ void gtk_widget_adjust_size_request (GtkWidget *widg
GtkOrientation orientation,
gint *minimum_size,
gint *natural_size);
void gtk_widget_adjust_size_allocation (GtkWidget *widget,
GtkOrientation orientation,
gint *minimum_size,
gint *natural_size,
gint *allocated_pos,
gint *allocated_size);
void gtk_widget_adjust_baseline_request (GtkWidget *widget,
gint *minimum_baseline,
gint *natural_baseline);

View File

@ -5484,8 +5484,8 @@ gtk_window_realize (GtkWidget *widget)
gtk_widget_get_allocation (widget, &allocation);
surface = gdk_surface_new_toplevel (gtk_widget_get_display (widget),
allocation.width,
allocation.height);
MAX (1, allocation.width),
MAX (1, allocation.height));
priv->surface = surface;
gdk_surface_set_widget (surface, widget);

View File

@ -211,6 +211,7 @@ gtk_public_sources = files([
'gtkdragicon.c',
'gtkdragsource.c',
'gtkdrawingarea.c',
'gtkdropcontrollermotion.c',
'gtkeditable.c',
'gtkemojichooser.c',
'gtkemojicompletion.c',
@ -461,6 +462,7 @@ gtk_public_headers = files([
'gtkdragicon.h',
'gtkdragsource.h',
'gtkdrawingarea.h',
'gtkdropcontrollermotion.h',
'gtkeditable.h',
'gtkemojichooser.h',
'gtkentry.h',

View File

@ -157,11 +157,13 @@ view_column_model_get_value (GtkTreeModel *tree_model,
gint column,
GValue *value)
{
#ifndef G_DISABLE_CHECKS
ViewColumnModel *view_model = (ViewColumnModel *)tree_model;
g_return_if_fail (column < 2);
g_return_if_fail (view_model->stamp == iter->stamp);
g_return_if_fail (iter->user_data != NULL);
#endif
if (column == 0)
{
@ -179,10 +181,12 @@ static gboolean
view_column_model_iter_next (GtkTreeModel *tree_model,
GtkTreeIter *iter)
{
#ifndef G_DISABLE_CHECKS
ViewColumnModel *view_model = (ViewColumnModel *)tree_model;
g_return_val_if_fail (view_model->stamp == iter->stamp, FALSE);
g_return_val_if_fail (iter->user_data != NULL, FALSE);
#endif
iter->user_data = ((GList *)iter->user_data)->next;
return iter->user_data != NULL;

View File

@ -1541,15 +1541,15 @@ test_widget (void)
accessible = gtk_widget_get_accessible (GTK_WIDGET (label1));
relation_set = atk_object_ref_relation_set (accessible);
g_return_if_fail (atk_relation_set_get_n_relations (relation_set) == 1);
g_assert_cmpint (atk_relation_set_get_n_relations (relation_set), ==, 1);
relation = atk_relation_set_get_relation (relation_set, 0);
g_return_if_fail (relation != NULL);
g_return_if_fail (ATK_IS_RELATION (relation));
g_return_if_fail (atk_relation_get_relation_type (relation) != ATK_RELATION_LABELLED_BY);
g_assert (relation != NULL);
g_assert_true (ATK_IS_RELATION (relation));
g_assert_cmpint (atk_relation_get_relation_type (relation), !=, ATK_RELATION_LABELLED_BY);
g_object_unref (relation_set);
g_object_get (G_OBJECT (accessible), "accessible-name", &name, NULL);
g_return_if_fail (strcmp (name, "A Label") == 0);
g_assert_cmpstr (name, ==, "A Label");
g_free (name);
gtk_widget_destroy (GTK_WIDGET (window1));

View File

@ -37,6 +37,20 @@ focus_out (GtkEventControllerFocus *key,
gtk_event_controller_focus_contains_focus (key));
}
static void
notify (GtkEventControllerFocus *key,
GParamSpec *pspec,
GString *s)
{
GtkWidget *widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (key));
g_string_append_printf (s, "%s: notify:%s is-focus: %d contains-focus: %d\n",
widget_name (widget),
pspec->name,
gtk_event_controller_focus_is_focus (key),
gtk_event_controller_focus_contains_focus (key));
}
static void
add_controller (GtkWidget *widget, GString *s)
{
@ -45,6 +59,7 @@ add_controller (GtkWidget *widget, GString *s)
controller = gtk_event_controller_focus_new ();
g_signal_connect (controller, "enter", G_CALLBACK (focus_in), s);
g_signal_connect (controller, "leave", G_CALLBACK (focus_out), s);
g_signal_connect (controller, "notify", G_CALLBACK (notify), s);
gtk_widget_add_controller (widget, controller);
}
@ -52,7 +67,10 @@ static void
assert_result (const char *s, const char *expected)
{
if (strcmp (s, expected) != 0 && g_test_verbose ())
g_print ("Expected:\n%s", expected);
{
g_print ("Expected:\n%s", expected);
g_print ("Got:\n%s", s);
}
g_assert_cmpstr (s, ==, expected);
}
@ -126,8 +144,12 @@ test_window_focus (void)
if (g_test_verbose ())
g_print ("-> box\n%s\n", s->str);
assert_result (s->str, "window: focus-in is-focus: 0 contains-focus: 1\n"
"box: focus-in is-focus: 1 contains-focus: 1\n");
assert_result (s->str,
"window: notify:contains-focus is-focus: 0 contains-focus: 1\n"
"window: focus-in is-focus: 0 contains-focus: 1\n"
"box: notify:contains-focus is-focus: 1 contains-focus: 1\n"
"box: notify:is-focus is-focus: 1 contains-focus: 1\n"
"box: focus-in is-focus: 1 contains-focus: 1\n");
g_string_truncate (s, 0);
gtk_widget_grab_focus (entry1);
@ -136,8 +158,12 @@ test_window_focus (void)
g_print ("box -> entry1\n%s\n", s->str);
assert_result (s->str,
"box1: focus-in is-focus: 0 contains-focus: 1\n"
"entry1: focus-in is-focus: 1 contains-focus: 1\n");
"box: notify:is-focus is-focus: 0 contains-focus: 1\n"
"box1: notify:contains-focus is-focus: 0 contains-focus: 1\n"
"box1: focus-in is-focus: 0 contains-focus: 1\n"
"entry1: notify:contains-focus is-focus: 1 contains-focus: 1\n"
"entry1: notify:is-focus is-focus: 1 contains-focus: 1\n"
"entry1: focus-in is-focus: 1 contains-focus: 1\n");
g_string_truncate (s, 0);
@ -149,10 +175,16 @@ test_window_focus (void)
g_print ("entry1 -> entry2\n%s\n", s->str);
assert_result (s->str,
"entry1: focus-out is-focus: 1 contains-focus: 1\n"
"box1: focus-out is-focus: 0 contains-focus: 1\n"
"box2: focus-in is-focus: 0 contains-focus: 1\n"
"entry2: focus-in is-focus: 1 contains-focus: 1\n");
"entry1: focus-out is-focus: 1 contains-focus: 1\n"
"entry1: notify:contains-focus is-focus: 0 contains-focus: 0\n"
"entry1: notify:is-focus is-focus: 0 contains-focus: 0\n"
"box1: focus-out is-focus: 0 contains-focus: 1\n"
"box1: notify:contains-focus is-focus: 0 contains-focus: 0\n"
"box2: notify:contains-focus is-focus: 0 contains-focus: 1\n"
"box2: focus-in is-focus: 0 contains-focus: 1\n"
"entry2: notify:contains-focus is-focus: 1 contains-focus: 1\n"
"entry2: notify:is-focus is-focus: 1 contains-focus: 1\n"
"entry2: focus-in is-focus: 1 contains-focus: 1\n");
g_string_truncate (s, 0);
@ -164,9 +196,12 @@ test_window_focus (void)
g_print ("entry2 -> box\n%s", s->str);
assert_result (s->str,
"entry2: focus-out is-focus: 1 contains-focus: 1\n"
"box2: focus-out is-focus: 0 contains-focus: 1\n"
);
"entry2: focus-out is-focus: 1 contains-focus: 1\n"
"entry2: notify:contains-focus is-focus: 0 contains-focus: 0\n"
"entry2: notify:is-focus is-focus: 0 contains-focus: 0\n"
"box2: focus-out is-focus: 0 contains-focus: 1\n"
"box2: notify:contains-focus is-focus: 0 contains-focus: 0\n"
"box: notify:is-focus is-focus: 1 contains-focus: 1\n");
g_string_truncate (s, 0);

View File

@ -135,23 +135,23 @@ test_select_collapsed_row (void)
/* Check that the parent is not selected. */
gtk_tree_path_up (path);
g_return_if_fail (gtk_tree_selection_path_is_selected (selection, path) == FALSE);
g_assert_false (gtk_tree_selection_path_is_selected (selection, path));
/* Nothing should be selected at this point. */
g_return_if_fail (gtk_tree_selection_count_selected_rows (selection) == 0);
g_assert_cmpint (gtk_tree_selection_count_selected_rows (selection), ==, 0);
/* Check that selection really still works. */
gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path, NULL, FALSE);
g_return_if_fail (gtk_tree_selection_path_is_selected (selection, path) == TRUE);
g_return_if_fail (gtk_tree_selection_count_selected_rows (selection) == 1);
g_assert_true (gtk_tree_selection_path_is_selected (selection, path));
g_assert_cmpint (gtk_tree_selection_count_selected_rows (selection), ==, 1);
/* Expand and select child node now. */
gtk_tree_path_append_index (path, 1);
gtk_tree_view_expand_all (GTK_TREE_VIEW (view));
gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path, NULL, FALSE);
g_return_if_fail (gtk_tree_selection_path_is_selected (selection, path) == TRUE);
g_return_if_fail (gtk_tree_selection_count_selected_rows (selection) == 1);
g_assert_true (gtk_tree_selection_path_is_selected (selection, path));
g_assert_cmpint (gtk_tree_selection_count_selected_rows (selection), ==, 1);
gtk_tree_path_free (path);