popover: Add a "modal" boolean property to GtkPopover
This property is TRUE by default, when a popover is modal, it will automatically set a GTK+ grab on the popover, and grab the keyboard focus into the popover.
This commit is contained in:
parent
7e30b82aee
commit
1d495cbafd
@ -92,7 +92,6 @@ entry_icon_press_cb (GtkEntry *entry,
|
||||
gtk_entry_get_icon_area (entry, icon_pos, &rect);
|
||||
gtk_popover_set_pointing_to (GTK_POPOVER (popover), &rect);
|
||||
gtk_widget_show (popover);
|
||||
gtk_grab_add (popover);
|
||||
|
||||
g_object_set_data (G_OBJECT (entry), "popover-icon-pos",
|
||||
GUINT_TO_POINTER (icon_pos));
|
||||
@ -126,7 +125,6 @@ day_selected_cb (GtkCalendar *calendar,
|
||||
gtk_popover_set_pointing_to (GTK_POPOVER (popover), &rect);
|
||||
|
||||
gtk_widget_show (popover);
|
||||
gtk_grab_add (popover);
|
||||
|
||||
gdk_event_free (event);
|
||||
}
|
||||
@ -151,6 +149,7 @@ do_popover (GtkWidget *do_widget)
|
||||
popover = create_popover (widget,
|
||||
gtk_label_new ("This popover does not grab input"),
|
||||
GTK_POS_TOP);
|
||||
gtk_popover_set_modal (GTK_POPOVER (popover), FALSE);
|
||||
g_signal_connect (widget, "toggled",
|
||||
G_CALLBACK (toggle_changed_cb), popover);
|
||||
gtk_container_add (GTK_CONTAINER (box), widget);
|
||||
|
@ -7869,4 +7869,6 @@ gtk_popover_set_pointing_to
|
||||
gtk_popover_get_pointing_to
|
||||
gtk_popover_set_position
|
||||
gtk_popover_get_position
|
||||
gtk_popover_set_modal
|
||||
gtk_popover_get_modal
|
||||
</SECTION>
|
||||
|
@ -2674,6 +2674,7 @@ gtk_entry_init (GtkEntry *entry)
|
||||
gtk_widget_set_size_request (priv->magnifier, 100, 60);
|
||||
_gtk_magnifier_set_magnification (GTK_MAGNIFIER (priv->magnifier), 2.0);
|
||||
priv->magnifier_popover = gtk_popover_new (GTK_WIDGET (entry));
|
||||
gtk_popover_set_modal (GTK_POPOVER (priv->magnifier_popover), FALSE);
|
||||
gtk_container_add (GTK_CONTAINER (priv->magnifier_popover),
|
||||
priv->magnifier);
|
||||
gtk_container_set_border_width (GTK_CONTAINER (priv->magnifier_popover), 4);
|
||||
@ -9473,6 +9474,7 @@ bubble_targets_received (GtkClipboard *clipboard,
|
||||
priv->selection_bubble = gtk_popover_new (GTK_WIDGET (entry));
|
||||
gtk_popover_set_position (GTK_POPOVER (priv->selection_bubble),
|
||||
GTK_POS_TOP);
|
||||
gtk_popover_set_modal (GTK_POPOVER (priv->selection_bubble), FALSE);
|
||||
|
||||
toolbar = GTK_WIDGET (gtk_toolbar_new ());
|
||||
gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_TEXT);
|
||||
|
104
gtk/gtkpopover.c
104
gtk/gtkpopover.c
@ -53,7 +53,8 @@ typedef struct _GtkPopoverPrivate GtkPopoverPrivate;
|
||||
enum {
|
||||
PROP_RELATIVE_TO = 1,
|
||||
PROP_POINTING_TO,
|
||||
PROP_POSITION
|
||||
PROP_POSITION,
|
||||
PROP_MODAL
|
||||
};
|
||||
|
||||
struct _GtkPopoverPrivate
|
||||
@ -68,6 +69,7 @@ struct _GtkPopoverPrivate
|
||||
guint preferred_position : 2;
|
||||
guint final_position : 2;
|
||||
guint current_position : 2;
|
||||
guint modal : 1;
|
||||
};
|
||||
|
||||
static GQuark quark_widget_popovers = 0;
|
||||
@ -81,13 +83,15 @@ G_DEFINE_TYPE_WITH_PRIVATE (GtkPopover, gtk_popover, GTK_TYPE_BIN)
|
||||
static void
|
||||
gtk_popover_init (GtkPopover *popover)
|
||||
{
|
||||
GtkPopoverPrivate *priv;
|
||||
GtkWidget *widget;
|
||||
|
||||
widget = GTK_WIDGET (popover);
|
||||
gtk_widget_set_has_window (widget, TRUE);
|
||||
popover->priv = gtk_popover_get_instance_private (popover);
|
||||
popover->priv = priv = gtk_popover_get_instance_private (popover);
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (widget),
|
||||
GTK_STYLE_CLASS_OSD);
|
||||
priv->modal = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -110,6 +114,10 @@ gtk_popover_set_property (GObject *object,
|
||||
gtk_popover_set_position (GTK_POPOVER (object),
|
||||
g_value_get_enum (value));
|
||||
break;
|
||||
case PROP_MODAL:
|
||||
gtk_popover_set_modal (GTK_POPOVER (object),
|
||||
g_value_get_boolean (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
@ -134,6 +142,9 @@ gtk_popover_get_property (GObject *object,
|
||||
case PROP_POSITION:
|
||||
g_value_set_enum (value, priv->preferred_position);
|
||||
break;
|
||||
case PROP_MODAL:
|
||||
g_value_set_boolean (value, priv->modal);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
@ -206,9 +217,18 @@ gtk_popover_realize (GtkWidget *widget)
|
||||
static void
|
||||
gtk_popover_map (GtkWidget *widget)
|
||||
{
|
||||
GtkPopoverPrivate *priv;
|
||||
|
||||
priv = GTK_POPOVER (widget)->priv;
|
||||
GTK_WIDGET_CLASS (gtk_popover_parent_class)->map (widget);
|
||||
gdk_window_show (gtk_widget_get_window (widget));
|
||||
gtk_popover_update_position (GTK_POPOVER (widget));
|
||||
|
||||
if (priv->modal)
|
||||
{
|
||||
gtk_grab_add (widget);
|
||||
gtk_widget_grab_focus (widget);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -881,6 +901,22 @@ gtk_popover_class_init (GtkPopoverClass *klass)
|
||||
GTK_TYPE_POSITION_TYPE, GTK_POS_TOP,
|
||||
GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT));
|
||||
|
||||
/**
|
||||
* GtkPopover:modal
|
||||
*
|
||||
* Sets whether the popover is modal (so other elements in the window are
|
||||
* not usable while the popover is visible).
|
||||
*
|
||||
* Since: 3.12
|
||||
*/
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_MODAL,
|
||||
g_param_spec_boolean ("modal",
|
||||
P_("Modal"),
|
||||
P_("Whether the popover is modal"),
|
||||
TRUE,
|
||||
GTK_PARAM_READWRITE));
|
||||
|
||||
quark_widget_popovers = g_quark_from_static_string ("gtk-quark-widget-popovers");
|
||||
}
|
||||
|
||||
@ -1240,3 +1276,67 @@ gtk_popover_get_position (GtkPopover *popover)
|
||||
|
||||
return priv->preferred_position;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_popover_set_modal:
|
||||
* @popover: a #GtkPopover
|
||||
* @modal: #TRUE to make popover claim all input within the toplevel
|
||||
*
|
||||
* Sets whether @popover is modal, a modal popover will grab all input
|
||||
* within the toplevel and grab the keyboard focus on it when being
|
||||
* displayed. Clicking outside the popover area or pressing Esc will
|
||||
* dismiss the popover and ungrab input.
|
||||
*
|
||||
* Since: 3.12
|
||||
**/
|
||||
void
|
||||
gtk_popover_set_modal (GtkPopover *popover,
|
||||
gboolean modal)
|
||||
{
|
||||
GtkPopoverPrivate *priv;
|
||||
|
||||
g_return_if_fail (GTK_IS_POPOVER (popover));
|
||||
|
||||
priv = popover->priv;
|
||||
|
||||
if ((priv->modal == TRUE) == (modal == TRUE))
|
||||
return;
|
||||
|
||||
priv->modal = (modal != FALSE);
|
||||
|
||||
if (gtk_widget_is_visible (GTK_WIDGET (popover)))
|
||||
{
|
||||
if (priv->modal)
|
||||
{
|
||||
gtk_grab_add (GTK_WIDGET (popover));
|
||||
gtk_widget_grab_focus (GTK_WIDGET (popover));
|
||||
}
|
||||
else
|
||||
gtk_grab_remove (GTK_WIDGET (popover));
|
||||
}
|
||||
|
||||
g_object_notify (G_OBJECT (popover), "modal");
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_popover_get_modal:
|
||||
* @popover: a #GtkPopover
|
||||
*
|
||||
* Returns whether the popover is modal, see gtk_popover_set_modal to
|
||||
* see the implications of this.
|
||||
*
|
||||
* Returns: #TRUE if @popover is modal
|
||||
*
|
||||
* Since: 3.12
|
||||
**/
|
||||
gboolean
|
||||
gtk_popover_get_modal (GtkPopover *popover)
|
||||
{
|
||||
GtkPopoverPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_POPOVER (popover), FALSE);
|
||||
|
||||
priv = popover->priv;
|
||||
|
||||
return priv->modal;
|
||||
}
|
||||
|
@ -73,6 +73,12 @@ void gtk_popover_set_position (GtkPopover *popover,
|
||||
GDK_AVAILABLE_IN_3_12
|
||||
GtkPositionType gtk_popover_get_position (GtkPopover *popover);
|
||||
|
||||
GDK_AVAILABLE_IN_3_12
|
||||
void gtk_popover_set_modal (GtkPopover *popover,
|
||||
gboolean modal);
|
||||
GDK_AVAILABLE_IN_3_12
|
||||
gboolean gtk_popover_get_modal (GtkPopover *popover);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_POPOVER_H__ */
|
||||
|
@ -1551,6 +1551,7 @@ gtk_text_view_init (GtkTextView *text_view)
|
||||
gtk_widget_set_size_request (priv->magnifier, 100, 60);
|
||||
_gtk_magnifier_set_magnification (GTK_MAGNIFIER (priv->magnifier), 2.0);
|
||||
priv->magnifier_popover = gtk_popover_new (widget);
|
||||
gtk_popover_set_modal (GTK_POPOVER (priv->magnifier_popover), FALSE);
|
||||
gtk_container_add (GTK_CONTAINER (priv->magnifier_popover),
|
||||
priv->magnifier);
|
||||
gtk_container_set_border_width (GTK_CONTAINER (priv->magnifier_popover), 4);
|
||||
@ -8947,6 +8948,7 @@ bubble_targets_received (GtkClipboard *clipboard,
|
||||
priv->selection_bubble = gtk_popover_new (GTK_WIDGET (text_view));
|
||||
gtk_popover_set_position (GTK_POPOVER (priv->selection_bubble),
|
||||
GTK_POS_TOP);
|
||||
gtk_popover_set_modal (GTK_POPOVER (priv->selection_bubble), FALSE);
|
||||
|
||||
toolbar = GTK_WIDGET (gtk_toolbar_new ());
|
||||
gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_TEXT);
|
||||
|
Loading…
Reference in New Issue
Block a user