forked from AuroraMiddleware/gtk
Merge branch 'wip/otte/dnd' into 'master'
stuff See merge request GNOME/gtk!1460
This commit is contained in:
commit
b002572824
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
394
gtk/gtkdropcontrollermotion.c
Normal file
394
gtk/gtkdropcontrollermotion.c
Normal 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;
|
||||
}
|
57
gtk/gtkdropcontrollermotion.h
Normal file
57
gtk/gtkdropcontrollermotion.h
Normal 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__ */
|
@ -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.
|
||||
*
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
275
gtk/gtkwidget.c
275
gtk/gtkwidget.c
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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',
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user