Compare commits
36 Commits
event-sour
...
wip/matthi
Author | SHA1 | Date | |
---|---|---|---|
|
4b6cef7f18 | ||
|
b9e75b8b51 | ||
|
532aa7c4e2 | ||
|
9a57f80d3f | ||
|
f139cf29c5 | ||
|
4ef6038129 | ||
|
53de417dd4 | ||
|
1f314e0373 | ||
|
050d050efd | ||
|
321fa9a0c8 | ||
|
d21c95d2d3 | ||
|
38e227b426 | ||
|
ce97d39785 | ||
|
7647e1d279 | ||
|
72f942a6df | ||
|
2156e23751 | ||
|
b2cbf6918b | ||
|
27ec50e731 | ||
|
989de7c8f5 | ||
|
867641fad8 | ||
|
de0d313067 | ||
|
5e2d2d0d83 | ||
|
14617f92dd | ||
|
0075a7efee | ||
|
2e76f8e464 | ||
|
143c5982bc | ||
|
fc49f0163e | ||
|
4180f1aa89 | ||
|
c2b13bded1 | ||
|
988d958ce6 | ||
|
1cae68daec | ||
|
87aa844e37 | ||
|
b1d871d26e | ||
|
bbc63dbae8 | ||
|
e8233d3db3 | ||
|
55ddbec246 |
@@ -614,7 +614,6 @@ static gboolean
|
||||
gtk_icon_view_item_accessible_grab_focus (AtkComponent *component)
|
||||
{
|
||||
GtkIconViewItemAccessible *item;
|
||||
GtkWidget *toplevel;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_ICON_VIEW_ITEM_ACCESSIBLE (component), FALSE);
|
||||
|
||||
@@ -624,13 +623,6 @@ gtk_icon_view_item_accessible_grab_focus (AtkComponent *component)
|
||||
|
||||
gtk_widget_grab_focus (item->widget);
|
||||
_gtk_icon_view_set_cursor_item (GTK_ICON_VIEW (item->widget), item->item, NULL);
|
||||
toplevel = gtk_widget_get_toplevel (GTK_WIDGET (item->widget));
|
||||
if (gtk_widget_is_toplevel (toplevel))
|
||||
{
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
gtk_window_present (GTK_WINDOW (toplevel));
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@@ -534,12 +534,11 @@ gtk_menu_item_accessible_get_keybinding (AtkAction *action,
|
||||
|
||||
if (GTK_IS_MENU_BAR (parent))
|
||||
{
|
||||
GtkWidget *toplevel;
|
||||
GtkRoot *root;
|
||||
|
||||
toplevel = gtk_widget_get_toplevel (parent);
|
||||
if (toplevel && GTK_IS_WINDOW (toplevel))
|
||||
mnemonic_modifier =
|
||||
gtk_window_get_mnemonic_modifier (GTK_WINDOW (toplevel));
|
||||
root = gtk_widget_get_root (parent);
|
||||
if (root && GTK_IS_WINDOW (root))
|
||||
mnemonic_modifier = gtk_window_get_mnemonic_modifier (GTK_WINDOW (root));
|
||||
}
|
||||
|
||||
child = find_item_label (temp_item);
|
||||
|
@@ -171,6 +171,7 @@
|
||||
#include <gtk/gtkpicture.h>
|
||||
#include <gtk/gtkpopover.h>
|
||||
#include <gtk/gtkpopovermenu.h>
|
||||
#include <gtk/gtkpopup.h>
|
||||
#include <gtk/gtkprintcontext.h>
|
||||
#include <gtk/gtkprintoperation.h>
|
||||
#include <gtk/gtkprintoperationpreview.h>
|
||||
|
@@ -259,16 +259,14 @@ other_application_item_activated_cb (GtkAppChooserButton *self)
|
||||
{
|
||||
GtkAppChooserButtonPrivate *priv = gtk_app_chooser_button_get_instance_private (self);
|
||||
GtkWidget *dialog, *widget;
|
||||
GtkWindow *toplevel;
|
||||
GtkRoot *root;
|
||||
|
||||
toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (self)));
|
||||
dialog = gtk_app_chooser_dialog_new_for_content_type (toplevel,
|
||||
root = gtk_widget_get_root (GTK_WIDGET (self));
|
||||
dialog = gtk_app_chooser_dialog_new_for_content_type (GTK_WINDOW (root),
|
||||
GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
priv->content_type);
|
||||
|
||||
gtk_window_set_modal (GTK_WINDOW (dialog), gtk_window_get_modal (toplevel));
|
||||
gtk_app_chooser_dialog_set_heading (GTK_APP_CHOOSER_DIALOG (dialog),
|
||||
priv->heading);
|
||||
gtk_window_set_modal (GTK_WINDOW (dialog), gtk_window_get_modal (GTK_WINDOW (root)));
|
||||
gtk_app_chooser_dialog_set_heading (GTK_APP_CHOOSER_DIALOG (dialog), priv->heading);
|
||||
|
||||
widget = gtk_app_chooser_dialog_get_widget (GTK_APP_CHOOSER_DIALOG (dialog));
|
||||
g_object_set (widget,
|
||||
|
@@ -452,7 +452,7 @@ gtk_cell_renderer_accel_start_editing (GtkCellRenderer *cell,
|
||||
if (!is_editable)
|
||||
return NULL;
|
||||
|
||||
surface = gtk_widget_get_surface (gtk_widget_get_toplevel (widget));
|
||||
surface = gtk_widget_get_surface (widget);
|
||||
|
||||
if (event)
|
||||
seat = gdk_event_get_seat (event);
|
||||
|
@@ -524,7 +524,7 @@ ensure_dialog (GtkColorButton *button)
|
||||
priv->cs_dialog = dialog = gtk_color_chooser_dialog_new (priv->title, NULL);
|
||||
gtk_window_set_hide_on_close (GTK_WINDOW (dialog), TRUE);
|
||||
|
||||
if (gtk_widget_is_toplevel (parent) && GTK_IS_WINDOW (parent))
|
||||
if (GTK_IS_WINDOW (parent))
|
||||
{
|
||||
if (GTK_WINDOW (parent) != gtk_window_get_transient_for (GTK_WINDOW (dialog)))
|
||||
gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (parent));
|
||||
|
@@ -193,7 +193,7 @@ popup_edit (GtkWidget *widget,
|
||||
GtkColorEditor *editor)
|
||||
{
|
||||
GtkWidget *popup = NULL;
|
||||
GtkWidget *toplevel;
|
||||
GtkRoot *root;
|
||||
GtkWidget *focus;
|
||||
gint position;
|
||||
gint s, e;
|
||||
@@ -224,8 +224,8 @@ popup_edit (GtkWidget *widget,
|
||||
else if (popup)
|
||||
{
|
||||
dismiss_current_popup (editor);
|
||||
toplevel = gtk_widget_get_toplevel (GTK_WIDGET (editor));
|
||||
g_set_object (&editor->priv->popdown_focus, gtk_root_get_focus (GTK_ROOT (toplevel)));
|
||||
root = gtk_widget_get_root (GTK_WIDGET (editor));
|
||||
g_set_object (&editor->priv->popdown_focus, gtk_root_get_focus (root));
|
||||
editor->priv->current_popup = popup;
|
||||
editor->priv->popup_position = position;
|
||||
gtk_widget_show (popup);
|
||||
|
@@ -85,14 +85,6 @@
|
||||
* See more about implementing custom widgets at https://wiki.gnome.org/HowDoI/CustomWidgets
|
||||
*/
|
||||
|
||||
|
||||
struct _GtkContainerPrivate
|
||||
{
|
||||
guint resize_handler;
|
||||
|
||||
guint restyle_pending : 1;
|
||||
};
|
||||
|
||||
enum {
|
||||
ADD,
|
||||
REMOVE,
|
||||
@@ -126,7 +118,6 @@ static GQuark hadjustment_key_id;
|
||||
static guint container_signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GtkContainer, gtk_container, GTK_TYPE_WIDGET,
|
||||
G_ADD_PRIVATE (GtkContainer)
|
||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
|
||||
gtk_container_buildable_init))
|
||||
|
||||
@@ -245,10 +236,6 @@ static void
|
||||
gtk_container_destroy (GtkWidget *widget)
|
||||
{
|
||||
GtkContainer *container = GTK_CONTAINER (widget);
|
||||
GtkContainerPrivate *priv = gtk_container_get_instance_private (container);
|
||||
|
||||
if (priv->restyle_pending)
|
||||
priv->restyle_pending = FALSE;
|
||||
|
||||
gtk_container_foreach (container, (GtkCallback) gtk_widget_destroy, NULL);
|
||||
|
||||
@@ -333,113 +320,6 @@ gtk_container_remove (GtkContainer *container,
|
||||
g_object_unref (container);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_container_needs_idle_sizer (GtkContainer *container)
|
||||
{
|
||||
GtkContainerPrivate *priv = gtk_container_get_instance_private (container);
|
||||
|
||||
if (priv->restyle_pending)
|
||||
return TRUE;
|
||||
|
||||
return gtk_widget_needs_allocate (GTK_WIDGET (container));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_container_idle_sizer (GdkFrameClock *clock,
|
||||
GtkContainer *container)
|
||||
{
|
||||
GtkContainerPrivate *priv = gtk_container_get_instance_private (container);
|
||||
|
||||
/* We validate the style contexts in a single loop before even trying
|
||||
* to handle resizes instead of doing validations inline.
|
||||
* This is mostly necessary for compatibility reasons with old code,
|
||||
* because both style_updated and size_allocate functions often change
|
||||
* styles and so could cause infinite loops in this function.
|
||||
*
|
||||
* It's important to note that even an invalid style context returns
|
||||
* sane values. So the result of an invalid style context will never be
|
||||
* a program crash, but only a wrong layout or rendering.
|
||||
*/
|
||||
if (priv->restyle_pending)
|
||||
{
|
||||
priv->restyle_pending = FALSE;
|
||||
gtk_css_node_validate (gtk_widget_get_css_node (GTK_WIDGET (container)));
|
||||
}
|
||||
|
||||
/* we may be invoked with a container_resize_queue of NULL, because
|
||||
* queue_resize could have been adding an extra idle function while
|
||||
* the queue still got processed. we better just ignore such case
|
||||
* than trying to explicitly work around them with some extra flags,
|
||||
* since it doesn't cause any actual harm.
|
||||
*/
|
||||
if (gtk_widget_needs_allocate (GTK_WIDGET (container)))
|
||||
{
|
||||
if (GTK_IS_WINDOW (container))
|
||||
gtk_window_check_resize (GTK_WINDOW (container));
|
||||
else
|
||||
g_warning ("gtk_container_idle_sizer() called on a non-window");
|
||||
}
|
||||
|
||||
if (!gtk_container_needs_idle_sizer (container))
|
||||
{
|
||||
gtk_container_stop_idle_sizer (container);
|
||||
}
|
||||
else
|
||||
{
|
||||
gdk_frame_clock_request_phase (clock,
|
||||
GDK_FRAME_CLOCK_PHASE_LAYOUT);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gtk_container_start_idle_sizer (GtkContainer *container)
|
||||
{
|
||||
GtkContainerPrivate *priv = gtk_container_get_instance_private (container);
|
||||
GdkFrameClock *clock;
|
||||
|
||||
if (priv->resize_handler != 0)
|
||||
return;
|
||||
|
||||
if (!gtk_container_needs_idle_sizer (container))
|
||||
return;
|
||||
|
||||
clock = gtk_widget_get_frame_clock (GTK_WIDGET (container));
|
||||
if (clock == NULL)
|
||||
return;
|
||||
|
||||
priv->resize_handler = g_signal_connect (clock, "layout",
|
||||
G_CALLBACK (gtk_container_idle_sizer), container);
|
||||
gdk_frame_clock_request_phase (clock,
|
||||
GDK_FRAME_CLOCK_PHASE_LAYOUT);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_container_stop_idle_sizer (GtkContainer *container)
|
||||
{
|
||||
GtkContainerPrivate *priv = gtk_container_get_instance_private (container);
|
||||
|
||||
if (priv->resize_handler == 0)
|
||||
return;
|
||||
|
||||
g_signal_handler_disconnect (gtk_widget_get_frame_clock (GTK_WIDGET (container)),
|
||||
priv->resize_handler);
|
||||
priv->resize_handler = 0;
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_container_queue_restyle (GtkContainer *container)
|
||||
{
|
||||
GtkContainerPrivate *priv = gtk_container_get_instance_private (container);
|
||||
|
||||
g_return_if_fail (GTK_CONTAINER (container));
|
||||
|
||||
if (priv->restyle_pending)
|
||||
return;
|
||||
|
||||
priv->restyle_pending = TRUE;
|
||||
gtk_container_start_idle_sizer (container);
|
||||
}
|
||||
|
||||
static GtkSizeRequestMode
|
||||
gtk_container_get_request_mode (GtkWidget *widget)
|
||||
{
|
||||
|
@@ -26,9 +26,6 @@
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
void _gtk_container_queue_restyle (GtkContainer *container);
|
||||
void gtk_container_stop_idle_sizer (GtkContainer *container);
|
||||
void gtk_container_start_idle_sizer (GtkContainer *container);
|
||||
void gtk_container_set_focus_child (GtkContainer *container,
|
||||
GtkWidget *child);
|
||||
|
||||
|
@@ -19,7 +19,7 @@
|
||||
|
||||
#include "gtkcsswidgetnodeprivate.h"
|
||||
|
||||
#include "gtkcontainerprivate.h"
|
||||
#include "gtkrootprivate.h"
|
||||
#include "gtkcssanimatedstyleprivate.h"
|
||||
#include "gtkprivate.h"
|
||||
#include "gtksettingsprivate.h"
|
||||
@@ -60,7 +60,7 @@ gtk_css_widget_node_queue_callback (GtkWidget *widget,
|
||||
GtkCssNode *node = user_data;
|
||||
|
||||
gtk_css_node_invalidate_frame_clock (node, TRUE);
|
||||
_gtk_container_queue_restyle (GTK_CONTAINER (widget));
|
||||
gtk_root_queue_restyle (GTK_ROOT (widget));
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
@@ -70,8 +70,7 @@ gtk_css_widget_node_queue_validate (GtkCssNode *node)
|
||||
{
|
||||
GtkCssWidgetNode *widget_node = GTK_CSS_WIDGET_NODE (node);
|
||||
|
||||
if (widget_node->widget && _gtk_widget_is_toplevel (widget_node->widget) &&
|
||||
GTK_IS_CONTAINER (widget_node->widget))
|
||||
if (widget_node->widget && GTK_IS_ROOT (widget_node->widget))
|
||||
widget_node->validate_cb_id = gtk_widget_add_tick_callback (widget_node->widget,
|
||||
gtk_css_widget_node_queue_callback,
|
||||
node,
|
||||
@@ -83,10 +82,12 @@ gtk_css_widget_node_dequeue_validate (GtkCssNode *node)
|
||||
{
|
||||
GtkCssWidgetNode *widget_node = GTK_CSS_WIDGET_NODE (node);
|
||||
|
||||
if (widget_node->widget && _gtk_widget_is_toplevel (widget_node->widget) &&
|
||||
GTK_IS_CONTAINER (widget_node->widget))
|
||||
gtk_widget_remove_tick_callback (widget_node->widget,
|
||||
widget_node->validate_cb_id);
|
||||
if (widget_node->validate_cb_id)
|
||||
{
|
||||
gtk_widget_remove_tick_callback (widget_node->widget,
|
||||
widget_node->validate_cb_id);
|
||||
widget_node->validate_cb_id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
10
gtk/gtkdnd.c
10
gtk/gtkdnd.c
@@ -884,7 +884,7 @@ gtk_drag_begin_internal (GtkWidget *widget,
|
||||
int y)
|
||||
{
|
||||
GtkDragSourceInfo *info;
|
||||
GtkWidget *toplevel;
|
||||
GtkRoot *root;
|
||||
GdkDrag *drag;
|
||||
double px, py;
|
||||
int dx, dy;
|
||||
@@ -893,9 +893,9 @@ gtk_drag_begin_internal (GtkWidget *widget,
|
||||
if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
|
||||
device = gdk_device_get_associated_device (device);
|
||||
|
||||
toplevel = gtk_widget_get_toplevel (widget);
|
||||
gtk_widget_translate_coordinates (widget, toplevel, x, y, &x, &y);
|
||||
gdk_surface_get_device_position (gtk_widget_get_surface (toplevel),
|
||||
root = gtk_widget_get_root (widget);
|
||||
gtk_widget_translate_coordinates (widget, GTK_WIDGET (root), x, y, &x, &y);
|
||||
gdk_surface_get_device_position (gtk_widget_get_surface (GTK_WIDGET (root)),
|
||||
device,
|
||||
&px, &py,
|
||||
NULL);
|
||||
@@ -906,7 +906,7 @@ gtk_drag_begin_internal (GtkWidget *widget,
|
||||
content->widget = g_object_ref (widget);
|
||||
content->formats = gdk_content_formats_ref (target_list);
|
||||
|
||||
drag = gdk_drag_begin (gtk_widget_get_surface (toplevel), device, GDK_CONTENT_PROVIDER (content), actions, dx, dy);
|
||||
drag = gdk_drag_begin (gtk_widget_get_surface (GTK_WIDGET (root)), device, GDK_CONTENT_PROVIDER (content), actions, dx, dy);
|
||||
if (drag == NULL)
|
||||
{
|
||||
g_object_unref (content);
|
||||
|
@@ -34,10 +34,9 @@
|
||||
static void
|
||||
gtk_drag_dest_realized (GtkWidget *widget)
|
||||
{
|
||||
GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
|
||||
GtkRoot *root = gtk_widget_get_root (widget);
|
||||
|
||||
if (gtk_widget_is_toplevel (toplevel))
|
||||
gdk_surface_register_dnd (gtk_widget_get_surface (toplevel));
|
||||
gdk_surface_register_dnd (gtk_widget_get_surface (GTK_WIDGET (root)));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -45,10 +44,10 @@ gtk_drag_dest_hierarchy_changed (GtkWidget *widget,
|
||||
GParamSpec *pspec,
|
||||
gpointer data)
|
||||
{
|
||||
GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
|
||||
GtkRoot *root = gtk_widget_get_root (widget);
|
||||
|
||||
if (gtk_widget_is_toplevel (toplevel) && gtk_widget_get_realized (toplevel))
|
||||
gdk_surface_register_dnd (gtk_widget_get_surface (toplevel));
|
||||
if (root && gtk_widget_get_realized (GTK_WIDGET (root)))
|
||||
gdk_surface_register_dnd (gtk_widget_get_surface (GTK_WIDGET (root)));
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -254,7 +254,7 @@ struct _GtkLabelPrivate
|
||||
{
|
||||
GtkLabelSelectionInfo *select_info;
|
||||
GtkWidget *mnemonic_widget;
|
||||
GtkWindow *mnemonic_window;
|
||||
GtkRoot *mnemonic_root;
|
||||
|
||||
PangoAttrList *attrs;
|
||||
PangoAttrList *markup_attrs;
|
||||
@@ -477,7 +477,7 @@ static void gtk_label_update_active_link (GtkWidget *widget,
|
||||
static gboolean gtk_label_mnemonic_activate (GtkWidget *widget,
|
||||
gboolean group_cycling);
|
||||
static void gtk_label_setup_mnemonic (GtkLabel *label,
|
||||
GtkWidget *toplevel,
|
||||
GtkRoot *root,
|
||||
guint last_key);
|
||||
static void gtk_label_drag_data_get (GtkWidget *widget,
|
||||
GdkDrag *drag,
|
||||
@@ -1302,7 +1302,7 @@ gtk_label_init (GtkLabel *label)
|
||||
priv->attrs = NULL;
|
||||
|
||||
priv->mnemonic_widget = NULL;
|
||||
priv->mnemonic_window = NULL;
|
||||
priv->mnemonic_root = NULL;
|
||||
|
||||
priv->mnemonics_visible = TRUE;
|
||||
}
|
||||
@@ -1743,7 +1743,7 @@ gtk_label_mnemonic_activate (GtkWidget *widget,
|
||||
|
||||
static void
|
||||
gtk_label_setup_mnemonic (GtkLabel *label,
|
||||
GtkWidget *toplevel,
|
||||
GtkRoot *root,
|
||||
guint last_key)
|
||||
{
|
||||
GtkLabelPrivate *priv = gtk_label_get_instance_private (label);
|
||||
@@ -1754,12 +1754,10 @@ gtk_label_setup_mnemonic (GtkLabel *label,
|
||||
|
||||
if (last_key != GDK_KEY_VoidSymbol)
|
||||
{
|
||||
if (priv->mnemonic_window)
|
||||
if (priv->mnemonic_root)
|
||||
{
|
||||
gtk_window_remove_mnemonic (priv->mnemonic_window,
|
||||
last_key,
|
||||
widget);
|
||||
priv->mnemonic_window = NULL;
|
||||
gtk_root_remove_mnemonic (priv->mnemonic_root, last_key, widget);
|
||||
priv->mnemonic_root = NULL;
|
||||
}
|
||||
if (mnemonic_menu)
|
||||
{
|
||||
@@ -1775,7 +1773,7 @@ gtk_label_setup_mnemonic (GtkLabel *label,
|
||||
|
||||
connect_mnemonics_visible_notify (GTK_LABEL (widget));
|
||||
|
||||
if (toplevel && gtk_widget_is_toplevel (toplevel))
|
||||
if (root)
|
||||
{
|
||||
GtkWidget *menu_shell;
|
||||
|
||||
@@ -1792,10 +1790,8 @@ gtk_label_setup_mnemonic (GtkLabel *label,
|
||||
|
||||
if (!GTK_IS_MENU (menu_shell))
|
||||
{
|
||||
gtk_window_add_mnemonic (GTK_WINDOW (toplevel),
|
||||
priv->mnemonic_keyval,
|
||||
widget);
|
||||
priv->mnemonic_window = GTK_WINDOW (toplevel);
|
||||
gtk_root_add_mnemonic (root, priv->mnemonic_keyval, widget);
|
||||
priv->mnemonic_root = root;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1811,7 +1807,7 @@ gtk_label_root (GtkWidget *widget)
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_label_parent_class)->root (widget);
|
||||
|
||||
gtk_label_setup_mnemonic (label, gtk_widget_get_toplevel (widget), priv->mnemonic_keyval);
|
||||
gtk_label_setup_mnemonic (label, gtk_widget_get_root (widget), priv->mnemonic_keyval);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2146,7 +2142,7 @@ gtk_label_recalculate (GtkLabel *label)
|
||||
|
||||
if (keyval != priv->mnemonic_keyval)
|
||||
{
|
||||
gtk_label_setup_mnemonic (label, gtk_widget_get_toplevel (GTK_WIDGET (label)), keyval);
|
||||
gtk_label_setup_mnemonic (label, gtk_widget_get_root (GTK_WIDGET (label)), keyval);
|
||||
g_object_notify_by_pspec (G_OBJECT (label), label_props[PROP_MNEMONIC_KEYVAL]);
|
||||
}
|
||||
|
||||
@@ -4563,28 +4559,28 @@ static void
|
||||
connect_mnemonics_visible_notify (GtkLabel *label)
|
||||
{
|
||||
GtkLabelPrivate *priv = gtk_label_get_instance_private (label);
|
||||
GtkWidget *toplevel;
|
||||
GtkRoot *root;
|
||||
gboolean connected;
|
||||
|
||||
toplevel = gtk_widget_get_toplevel (GTK_WIDGET (label));
|
||||
root = gtk_widget_get_root (GTK_WIDGET (label));
|
||||
|
||||
if (!GTK_IS_WINDOW (toplevel))
|
||||
if (!GTK_IS_WINDOW (root))
|
||||
return;
|
||||
|
||||
/* always set up this widgets initial value */
|
||||
priv->mnemonics_visible =
|
||||
gtk_window_get_mnemonics_visible (GTK_WINDOW (toplevel));
|
||||
gtk_window_get_mnemonics_visible (GTK_WINDOW (root));
|
||||
|
||||
connected =
|
||||
GPOINTER_TO_INT (g_object_get_qdata (G_OBJECT (toplevel), quark_mnemonics_visible_connected));
|
||||
GPOINTER_TO_INT (g_object_get_qdata (G_OBJECT (root), quark_mnemonics_visible_connected));
|
||||
|
||||
if (!connected)
|
||||
{
|
||||
g_signal_connect (toplevel,
|
||||
g_signal_connect (root,
|
||||
"notify::mnemonics-visible",
|
||||
G_CALLBACK (label_mnemonics_visible_changed),
|
||||
label);
|
||||
g_object_set_qdata (G_OBJECT (toplevel),
|
||||
g_object_set_qdata (G_OBJECT (root),
|
||||
quark_mnemonics_visible_connected,
|
||||
GINT_TO_POINTER (1));
|
||||
}
|
||||
@@ -5875,12 +5871,10 @@ gtk_label_move_cursor (GtkLabel *label,
|
||||
count > 0 ?
|
||||
GTK_DIR_RIGHT : GTK_DIR_LEFT))
|
||||
{
|
||||
GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (label));
|
||||
GtkRoot *root = gtk_widget_get_root (GTK_WIDGET (label));
|
||||
|
||||
if (toplevel)
|
||||
gtk_widget_child_focus (toplevel,
|
||||
count > 0 ?
|
||||
GTK_DIR_RIGHT : GTK_DIR_LEFT);
|
||||
if (root)
|
||||
gtk_widget_child_focus (root, count > 0 ? GTK_DIR_RIGHT : GTK_DIR_LEFT);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -6162,11 +6156,14 @@ gtk_label_activate_link (GtkLabel *label,
|
||||
const gchar *uri)
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (label);
|
||||
GtkWidget *top_level = gtk_widget_get_toplevel (widget);
|
||||
GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
|
||||
guint32 timestamp = gtk_get_current_event_time ();
|
||||
GError *error = NULL;
|
||||
|
||||
if (!gtk_show_uri_on_window (GTK_WINDOW (top_level), uri, timestamp, &error))
|
||||
if (!GTK_IS_WINDOW (toplevel))
|
||||
return;
|
||||
|
||||
if (!gtk_show_uri_on_window (GTK_WINDOW (toplevel), uri, timestamp, &error))
|
||||
{
|
||||
g_warning ("Unable to show '%s': %s", uri, error->message);
|
||||
g_error_free (error);
|
||||
@@ -6209,31 +6206,9 @@ gtk_label_activate_current_link (GtkLabel *label)
|
||||
link = gtk_label_get_focus_link (label);
|
||||
|
||||
if (link)
|
||||
{
|
||||
emit_activate_link (label, link);
|
||||
}
|
||||
emit_activate_link (label, link);
|
||||
else
|
||||
{
|
||||
GtkWidget *toplevel;
|
||||
GtkWindow *window;
|
||||
GtkWidget *default_widget, *focus_widget;
|
||||
|
||||
toplevel = gtk_widget_get_toplevel (widget);
|
||||
if (GTK_IS_WINDOW (toplevel))
|
||||
{
|
||||
window = GTK_WINDOW (toplevel);
|
||||
|
||||
if (window)
|
||||
{
|
||||
default_widget = gtk_window_get_default_widget (window);
|
||||
focus_widget = gtk_root_get_focus (GTK_ROOT (window));
|
||||
|
||||
if (default_widget != widget &&
|
||||
!(widget == focus_widget && (!default_widget || !gtk_widget_is_sensitive (default_widget))))
|
||||
gtk_window_activate_default (window);
|
||||
}
|
||||
}
|
||||
}
|
||||
gtk_root_activate_default (gtk_widget_get_root (widget));
|
||||
}
|
||||
|
||||
static GtkLabelLink *
|
||||
|
@@ -1592,7 +1592,7 @@ gtk_synthesize_crossing_events (GtkRoot *toplevel,
|
||||
|
||||
|
||||
static GtkWidget *
|
||||
update_pointer_focus_state (GtkWindow *toplevel,
|
||||
update_pointer_focus_state (GtkRoot *root,
|
||||
GdkEvent *event,
|
||||
GtkWidget *new_target)
|
||||
{
|
||||
@@ -1603,13 +1603,12 @@ update_pointer_focus_state (GtkWindow *toplevel,
|
||||
|
||||
device = gdk_event_get_device (event);
|
||||
sequence = gdk_event_get_event_sequence (event);
|
||||
old_target = gtk_window_lookup_pointer_focus_widget (toplevel, device, sequence);
|
||||
old_target = gtk_root_lookup_pointer_focus (root, device, sequence);
|
||||
if (old_target == new_target)
|
||||
return old_target;
|
||||
|
||||
gdk_event_get_coords (event, &x, &y);
|
||||
gtk_window_update_pointer_focus (toplevel, device, sequence,
|
||||
new_target, x, y);
|
||||
gtk_root_update_pointer_focus (root, device, sequence, new_target, x, y);
|
||||
|
||||
return old_target;
|
||||
}
|
||||
@@ -1660,8 +1659,7 @@ static GtkWidget *
|
||||
handle_pointing_event (GdkEvent *event)
|
||||
{
|
||||
GtkWidget *target = NULL, *old_target = NULL, *event_widget;
|
||||
GtkWindow *toplevel;
|
||||
GtkWidget *toplevel_widget;
|
||||
GtkRoot *toplevel;
|
||||
GdkEventSequence *sequence;
|
||||
GdkDevice *device;
|
||||
gdouble x, y;
|
||||
@@ -1671,11 +1669,7 @@ handle_pointing_event (GdkEvent *event)
|
||||
if (!device || !gdk_event_get_coords (event, &x, &y))
|
||||
return event_widget;
|
||||
|
||||
toplevel_widget = gtk_widget_get_toplevel (event_widget);
|
||||
if (!GTK_IS_WINDOW (toplevel_widget))
|
||||
return event_widget;
|
||||
|
||||
toplevel = GTK_WINDOW (toplevel_widget);
|
||||
toplevel = gtk_widget_get_root (event_widget);
|
||||
|
||||
sequence = gdk_event_get_event_sequence (event);
|
||||
|
||||
@@ -1690,7 +1684,7 @@ handle_pointing_event (GdkEvent *event)
|
||||
old_target = update_pointer_focus_state (toplevel, event, NULL);
|
||||
|
||||
if (event->any.type == GDK_LEAVE_NOTIFY)
|
||||
gtk_synthesize_crossing_events (GTK_ROOT (toplevel), old_target, NULL,
|
||||
gtk_synthesize_crossing_events (toplevel, old_target, NULL,
|
||||
event, event->crossing.mode);
|
||||
break;
|
||||
case GDK_ENTER_NOTIFY:
|
||||
@@ -1700,30 +1694,28 @@ handle_pointing_event (GdkEvent *event)
|
||||
case GDK_TOUCH_BEGIN:
|
||||
case GDK_TOUCH_UPDATE:
|
||||
case GDK_MOTION_NOTIFY:
|
||||
target = gtk_window_lookup_pointer_focus_implicit_grab (toplevel, device, sequence);
|
||||
target = gtk_root_lookup_pointer_focus_implicit_grab (toplevel, device, sequence);
|
||||
|
||||
if (!target)
|
||||
target = gtk_widget_pick (toplevel_widget, x, y);
|
||||
target = gtk_widget_pick (GTK_WIDGET (toplevel), x, y);
|
||||
|
||||
if (!target)
|
||||
target = toplevel_widget;
|
||||
target = GTK_WIDGET (toplevel);
|
||||
|
||||
old_target = update_pointer_focus_state (toplevel, event, target);
|
||||
|
||||
if (event->any.type == GDK_MOTION_NOTIFY || event->any.type == GDK_ENTER_NOTIFY)
|
||||
{
|
||||
if (!gtk_window_lookup_pointer_focus_implicit_grab (toplevel, device,
|
||||
sequence))
|
||||
if (!gtk_root_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 (toplevel, old_target, target, event, GDK_CROSSING_NORMAL);
|
||||
}
|
||||
|
||||
gtk_window_maybe_update_cursor (toplevel, NULL, device);
|
||||
gtk_root_maybe_update_cursor (toplevel, NULL, device);
|
||||
}
|
||||
|
||||
if (event->any.type == GDK_TOUCH_BEGIN)
|
||||
gtk_window_set_pointer_focus_grab (toplevel, device, sequence, target);
|
||||
gtk_root_set_pointer_focus_grab (toplevel, device, sequence, target);
|
||||
|
||||
/* Let it take the effective pointer focus anyway, as it may change due
|
||||
* to implicit grabs.
|
||||
@@ -1732,12 +1724,10 @@ handle_pointing_event (GdkEvent *event)
|
||||
break;
|
||||
case GDK_BUTTON_PRESS:
|
||||
case GDK_BUTTON_RELEASE:
|
||||
target = gtk_window_lookup_effective_pointer_focus_widget (toplevel,
|
||||
device,
|
||||
sequence);
|
||||
gtk_window_set_pointer_focus_grab (toplevel, device, sequence,
|
||||
event->any.type == GDK_BUTTON_PRESS ?
|
||||
target : NULL);
|
||||
target = gtk_root_lookup_effective_pointer_focus (toplevel, device, sequence);
|
||||
gtk_root_set_pointer_focus_grab (toplevel, device, sequence,
|
||||
event->any.type == GDK_BUTTON_PRESS ?
|
||||
target : NULL);
|
||||
|
||||
if (event->any.type == GDK_BUTTON_RELEASE)
|
||||
{
|
||||
@@ -1745,9 +1735,8 @@ handle_pointing_event (GdkEvent *event)
|
||||
new_target = gtk_widget_pick (GTK_WIDGET (toplevel), x, y);
|
||||
if (new_target == NULL)
|
||||
new_target = GTK_WIDGET (toplevel);
|
||||
gtk_synthesize_crossing_events (GTK_ROOT (toplevel), target, new_target, event,
|
||||
GDK_CROSSING_UNGRAB);
|
||||
gtk_window_maybe_update_cursor (toplevel, NULL, device);
|
||||
gtk_synthesize_crossing_events (toplevel, target, new_target, event, GDK_CROSSING_UNGRAB);
|
||||
gtk_root_maybe_update_cursor (toplevel, NULL, device);
|
||||
}
|
||||
|
||||
set_widget_active_state (target, event->any.type == GDK_BUTTON_RELEASE);
|
||||
@@ -1762,9 +1751,7 @@ handle_pointing_event (GdkEvent *event)
|
||||
}
|
||||
|
||||
if (!target)
|
||||
target = gtk_window_lookup_effective_pointer_focus_widget (toplevel,
|
||||
device,
|
||||
sequence);
|
||||
target = gtk_root_lookup_effective_pointer_focus (toplevel, device, sequence);
|
||||
return target ? target : old_target;
|
||||
}
|
||||
|
||||
@@ -1854,7 +1841,7 @@ gtk_main_do_event (GdkEvent *event)
|
||||
GtkWidget *focus_widget;
|
||||
|
||||
if (event->any.type == GDK_KEY_PRESS &&
|
||||
gtk_window_activate_key (GTK_WINDOW (target_widget), (GdkEventKey *) event))
|
||||
gtk_root_activate_key (GTK_ROOT (target_widget), (GdkEventKey *) event))
|
||||
goto cleanup;
|
||||
|
||||
focus_widget = gtk_root_get_focus (GTK_ROOT (target_widget));
|
||||
@@ -1919,7 +1906,7 @@ gtk_main_do_event (GdkEvent *event)
|
||||
case GDK_DELETE:
|
||||
g_object_ref (target_widget);
|
||||
if (!gtk_window_group_get_current_grab (window_group) ||
|
||||
gtk_widget_get_toplevel (gtk_window_group_get_current_grab (window_group)) == target_widget)
|
||||
GTK_WIDGET (gtk_widget_get_root (gtk_window_group_get_current_grab (window_group))) == target_widget)
|
||||
{
|
||||
if (!GTK_IS_WINDOW (target_widget) ||
|
||||
!gtk_window_emit_close_request (GTK_WINDOW (target_widget)))
|
||||
@@ -1952,11 +1939,11 @@ gtk_main_do_event (GdkEvent *event)
|
||||
case GDK_KEY_RELEASE:
|
||||
/* make focus visible in a window that receives a key event */
|
||||
{
|
||||
GtkWidget *window;
|
||||
GtkRoot *root;
|
||||
|
||||
window = gtk_widget_get_toplevel (grab_widget);
|
||||
if (GTK_IS_WINDOW (window))
|
||||
gtk_window_set_focus_visible (GTK_WINDOW (window), TRUE);
|
||||
root = gtk_widget_get_root (grab_widget);
|
||||
if (GTK_IS_WINDOW (root))
|
||||
gtk_window_set_focus_visible (GTK_WINDOW (root), TRUE);
|
||||
}
|
||||
|
||||
/* Catch alt press to enable auto-mnemonics;
|
||||
@@ -1968,17 +1955,17 @@ gtk_main_do_event (GdkEvent *event)
|
||||
!GTK_IS_MENU_SHELL (grab_widget))
|
||||
{
|
||||
gboolean mnemonics_visible;
|
||||
GtkWidget *window;
|
||||
GtkRoot *root;
|
||||
|
||||
mnemonics_visible = (event->any.type == GDK_KEY_PRESS);
|
||||
|
||||
window = gtk_widget_get_toplevel (grab_widget);
|
||||
if (GTK_IS_WINDOW (window))
|
||||
root = gtk_widget_get_root (grab_widget);
|
||||
if (GTK_IS_WINDOW (root))
|
||||
{
|
||||
if (mnemonics_visible)
|
||||
_gtk_window_schedule_mnemonics_visible (GTK_WINDOW (window));
|
||||
_gtk_window_schedule_mnemonics_visible (GTK_WINDOW (root));
|
||||
else
|
||||
gtk_window_set_mnemonics_visible (GTK_WINDOW (window), FALSE);
|
||||
gtk_window_set_mnemonics_visible (GTK_WINDOW (root), FALSE);
|
||||
}
|
||||
}
|
||||
/* else fall through */
|
||||
|
@@ -31,7 +31,7 @@ target_destroyed (gpointer data,
|
||||
}
|
||||
|
||||
GtkPointerFocus *
|
||||
gtk_pointer_focus_new (GtkWindow *toplevel,
|
||||
gtk_pointer_focus_new (GtkRoot *toplevel,
|
||||
GtkWidget *widget,
|
||||
GdkDevice *device,
|
||||
GdkEventSequence *sequence,
|
||||
|
@@ -27,13 +27,13 @@ struct _GtkPointerFocus
|
||||
gint ref_count;
|
||||
GdkDevice *device;
|
||||
GdkEventSequence *sequence;
|
||||
GtkWindow *toplevel;
|
||||
GtkRoot *toplevel;
|
||||
GtkWidget *target; /* Unaffected by the implicit grab */
|
||||
GtkWidget *grab_widget;
|
||||
gdouble x, y; /* In toplevel coordinates */
|
||||
};
|
||||
|
||||
GtkPointerFocus * gtk_pointer_focus_new (GtkWindow *toplevel,
|
||||
GtkPointerFocus * gtk_pointer_focus_new (GtkRoot *toplevel,
|
||||
GtkWidget *widget,
|
||||
GdkDevice *device,
|
||||
GdkEventSequence *sequence,
|
||||
|
1060
gtk/gtkpopup.c
Normal file
1060
gtk/gtkpopup.c
Normal file
File diff suppressed because it is too large
Load Diff
73
gtk/gtkpopup.h
Normal file
73
gtk/gtkpopup.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 2019 Red Hat, Inc.
|
||||
*
|
||||
* Authors:
|
||||
* - Matthias Clasen <mclasen@redhat.com>
|
||||
*
|
||||
* 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 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/>.
|
||||
*/
|
||||
|
||||
#ifndef __GTK_POPUP_H__
|
||||
#define __GTK_POPUP_H__
|
||||
|
||||
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gtk/gtk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gtk/gtkbin.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_POPUP (gtk_popup_get_type ())
|
||||
#define GTK_POPUP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_POPUP, GtkPopup))
|
||||
#define GTK_POPUP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_POPUP, GtkPopupClass))
|
||||
#define GTK_IS_POPUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_POPUP))
|
||||
#define GTK_IS_POPUP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_POPUP))
|
||||
#define GTK_POPUP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_POPUP, GtkPopupClass))
|
||||
|
||||
typedef struct _GtkPopup GtkPopup;
|
||||
typedef struct _GtkPopupClass GtkPopupClass;
|
||||
|
||||
struct _GtkPopup
|
||||
{
|
||||
GtkBin parent;
|
||||
};
|
||||
|
||||
struct _GtkPopupClass
|
||||
{
|
||||
GtkBinClass parent_class;
|
||||
|
||||
/* keybinding signals */
|
||||
|
||||
void (* activate_focus) (GtkPopup *popup);
|
||||
void (* activate_default) (GtkPopup *popup);
|
||||
void (* close) (GtkPopup *popup);
|
||||
};
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gtk_popup_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkWidget * gtk_popup_new (void);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_popup_set_relative_to (GtkPopup *popup,
|
||||
GtkWidget *relative_to);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GListModel * gtk_popup_get_popups (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_POPUP_H__ */
|
371
gtk/gtkroot.c
371
gtk/gtkroot.c
@@ -20,6 +20,8 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "gtkrootprivate.h"
|
||||
#include "gtkcssnodeprivate.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
#include "gdk/gdk-private.h"
|
||||
#include "gtkprivate.h"
|
||||
#include "gtkintl.h"
|
||||
@@ -61,12 +63,69 @@ gtk_root_default_get_surface_transform (GtkRoot *self,
|
||||
*y = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_root_default_check_resize (GtkRoot *self)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_root_default_add_mnemonic (GtkRoot *self,
|
||||
guint keyval,
|
||||
GtkWidget *target)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_root_default_remove_mnemonic (GtkRoot *self,
|
||||
guint keyval,
|
||||
GtkWidget *target)
|
||||
{
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_root_default_activate_key (GtkRoot *self,
|
||||
GdkEventKey *event)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_root_default_update_pointer_focus (GtkRoot *root,
|
||||
GdkDevice *device,
|
||||
GdkEventSequence *sequence,
|
||||
GtkWidget *target,
|
||||
double x,
|
||||
double y)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_root_default_update_pointer_focus_on_state_change (GtkRoot *root,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
gtk_root_default_lookup_pointer_focus (GtkRoot *root,
|
||||
GdkDevice *device,
|
||||
GdkEventSequence *sequence)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_root_default_init (GtkRootInterface *iface)
|
||||
{
|
||||
iface->get_display = gtk_root_default_get_display;
|
||||
iface->get_renderer = gtk_root_default_get_renderer;
|
||||
iface->get_surface_transform = gtk_root_default_get_surface_transform;
|
||||
iface->check_resize = gtk_root_default_check_resize;
|
||||
iface->add_mnemonic = gtk_root_default_add_mnemonic;
|
||||
iface->remove_mnemonic = gtk_root_default_remove_mnemonic;
|
||||
iface->activate_key = gtk_root_default_activate_key;
|
||||
iface->update_pointer_focus = gtk_root_default_update_pointer_focus;
|
||||
iface->update_pointer_focus_on_state_change = gtk_root_default_update_pointer_focus_on_state_change;
|
||||
iface->lookup_pointer_focus = gtk_root_default_lookup_pointer_focus;
|
||||
|
||||
g_object_interface_install_property (iface,
|
||||
g_param_spec_object ("focus-widget",
|
||||
@@ -74,6 +133,13 @@ gtk_root_default_init (GtkRootInterface *iface)
|
||||
P_("The focus widget"),
|
||||
GTK_TYPE_WIDGET,
|
||||
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
|
||||
|
||||
g_object_interface_install_property (iface,
|
||||
g_param_spec_object ("default-widget",
|
||||
P_("Default widget"),
|
||||
P_("The default widget"),
|
||||
GTK_TYPE_WIDGET,
|
||||
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
|
||||
}
|
||||
|
||||
GdkDisplay *
|
||||
@@ -186,10 +252,315 @@ gtk_root_get_focus (GtkRoot *self)
|
||||
return focus;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_root_activate_focus:
|
||||
* @self: a #GtkRoot
|
||||
*
|
||||
* Activates the current focused widget within the root.
|
||||
*
|
||||
* Returns: %TRUE if a widget got activated.
|
||||
**/
|
||||
gboolean
|
||||
gtk_root_activate_focus (GtkRoot *self)
|
||||
{
|
||||
GtkWidget *focus_widget;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_ROOT (self), FALSE);
|
||||
|
||||
focus_widget = gtk_root_get_focus (self);
|
||||
|
||||
if (focus_widget && gtk_widget_is_sensitive (focus_widget))
|
||||
return gtk_widget_activate (focus_widget);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_root_set_default:
|
||||
* @self: a #GtkRoot
|
||||
* @widget: (allow-none): widget to be the default, or %NULL
|
||||
* to unset the default widget
|
||||
*
|
||||
* The default widget is the widget that’s activated when the user
|
||||
* presses Enter in a dialog (for example). This function sets or
|
||||
* unsets the default widget for a #GtkRoot.
|
||||
*
|
||||
* When setting (rather than unsetting) the default widget it is
|
||||
* generally easier to call gtk_widget_grab_default() on the widget.
|
||||
* Before making a widget the default widget, you must call
|
||||
* gtk_widget_set_can_default() on the widget you’d like to make
|
||||
* the default.
|
||||
*/
|
||||
void
|
||||
gtk_root_set_default (GtkRoot *self,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_ROOT (self));
|
||||
g_return_if_fail (widget == NULL || GTK_IS_WIDGET (widget));
|
||||
|
||||
g_object_set (self, "default-widget", widget, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_root_get_default:
|
||||
* @self: a #GtkRoot
|
||||
*
|
||||
* Returns the default widget for @root. See
|
||||
* gtk_root_set_default() for more details.
|
||||
*
|
||||
* Returns: (nullable) (transfer none): the default widget, or %NULL
|
||||
* if there is none
|
||||
*/
|
||||
GtkWidget *
|
||||
gtk_root_get_default (GtkRoot *self)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_ROOT (self), NULL);
|
||||
|
||||
g_object_get (self, "default-widget", &widget, NULL);
|
||||
|
||||
if (widget)
|
||||
g_object_unref (widget);
|
||||
|
||||
return widget;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_root_activate_default:
|
||||
* @self: a #GtkRoot
|
||||
*
|
||||
* Activates the default widget for the window, unless the current
|
||||
* focused widget has been configured to receive the default action
|
||||
* (see gtk_widget_set_receives_default()), in which case the
|
||||
* focused widget is activated.
|
||||
*
|
||||
* Returns: %TRUE if a widget got activated
|
||||
*/
|
||||
gboolean
|
||||
gtk_root_activate_default (GtkRoot *self)
|
||||
{
|
||||
GtkWidget *default_widget;
|
||||
GtkWidget *focus_widget;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_ROOT (self), FALSE);
|
||||
|
||||
default_widget = gtk_root_get_default (self);
|
||||
focus_widget = gtk_root_get_focus (self);
|
||||
|
||||
if (default_widget && gtk_widget_is_sensitive (default_widget) &&
|
||||
(!focus_widget || !gtk_widget_get_receives_default (focus_widget)))
|
||||
return gtk_widget_activate (default_widget);
|
||||
else if (focus_widget && gtk_widget_is_sensitive (focus_widget))
|
||||
return gtk_widget_activate (focus_widget);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
guint
|
||||
gtk_root_install_properties (GObjectClass *object_class,
|
||||
guint first_prop)
|
||||
{
|
||||
g_object_class_override_property (object_class, first_prop + GTK_ROOT_PROP_FOCUS_WIDGET, "focus-widget");
|
||||
g_object_class_override_property (object_class, first_prop + GTK_ROOT_PROP_DEFAULT_WIDGET, "default-widget");
|
||||
return GTK_ROOT_NUM_PROPERTIES;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_root_check_resize (GtkRoot *self)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_ROOT (self));
|
||||
|
||||
GTK_ROOT_GET_IFACE (self)->check_resize (self);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_root_get_restyle_pending (GtkRoot *root)
|
||||
{
|
||||
return GPOINTER_TO_INT (g_object_get_data (G_OBJECT (root), "restyle-pending"));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_root_set_restyle_pending (GtkRoot *root,
|
||||
gboolean pending)
|
||||
{
|
||||
g_object_set_data (G_OBJECT (root), "restyle-pending", GINT_TO_POINTER (pending));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_root_needs_layout_phase (GtkRoot *root)
|
||||
{
|
||||
return gtk_root_get_restyle_pending (root) ||
|
||||
gtk_widget_needs_allocate (GTK_WIDGET (root));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_root_do_layout_phase (GdkFrameClock *clock,
|
||||
GtkRoot *root)
|
||||
{
|
||||
/* We validate the style contexts in a single loop before even trying
|
||||
* to handle resizes instead of doing validations inline.
|
||||
* This is mostly necessary for compatibility reasons with old code,
|
||||
* because both style_updated and size_allocate functions often change
|
||||
* styles and so could cause infinite loops in this function.
|
||||
*
|
||||
* It's important to note that even an invalid style context returns
|
||||
* sane values. So the result of an invalid style context will never be
|
||||
* a program crash, but only a wrong layout or rendering.
|
||||
*/
|
||||
|
||||
if (gtk_root_get_restyle_pending (root))
|
||||
{
|
||||
gtk_root_set_restyle_pending (root, FALSE);
|
||||
gtk_css_node_validate (gtk_widget_get_css_node (GTK_WIDGET (root)));
|
||||
}
|
||||
|
||||
/* we may be invoked with a container_resize_queue of NULL, because
|
||||
* queue_resize could have been adding an extra idle function while
|
||||
* the queue still got processed. we better just ignore such case
|
||||
* than trying to explicitly work around them with some extra flags,
|
||||
* since it doesn't cause any actual harm.
|
||||
*/
|
||||
if (gtk_widget_needs_allocate (GTK_WIDGET (root)))
|
||||
gtk_root_check_resize (root);
|
||||
|
||||
if (!gtk_root_needs_layout_phase (root))
|
||||
gtk_root_stop_layout_phase (root);
|
||||
else
|
||||
gdk_frame_clock_request_phase (clock, GDK_FRAME_CLOCK_PHASE_LAYOUT);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_root_start_layout_phase (GtkRoot *root)
|
||||
{
|
||||
GdkFrameClock *clock;
|
||||
guint resize_handler;
|
||||
|
||||
resize_handler = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (root), "resize-handler"));
|
||||
if (resize_handler != 0)
|
||||
return;
|
||||
|
||||
if (!gtk_root_needs_layout_phase (root))
|
||||
return;
|
||||
|
||||
clock = gtk_widget_get_frame_clock (GTK_WIDGET (root));
|
||||
if (clock == NULL)
|
||||
return;
|
||||
|
||||
resize_handler = g_signal_connect (clock, "layout", G_CALLBACK (gtk_root_do_layout_phase), root);
|
||||
g_object_set_data (G_OBJECT (root), "resize-handler", GUINT_TO_POINTER (resize_handler));
|
||||
gdk_frame_clock_request_phase (clock, GDK_FRAME_CLOCK_PHASE_LAYOUT);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_root_stop_layout_phase (GtkRoot *root)
|
||||
{
|
||||
guint resize_handler;
|
||||
|
||||
resize_handler = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (root), "resize-handler"));
|
||||
if (resize_handler == 0)
|
||||
return;
|
||||
|
||||
g_signal_handler_disconnect (gtk_widget_get_frame_clock (GTK_WIDGET (root)), resize_handler);
|
||||
g_object_set_data (G_OBJECT (root), "resize-handler", NULL);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_root_queue_restyle (GtkRoot *root)
|
||||
{
|
||||
g_return_if_fail (GTK_ROOT (root));
|
||||
|
||||
if (gtk_root_get_restyle_pending (root))
|
||||
return;
|
||||
|
||||
gtk_root_set_restyle_pending (root, TRUE);
|
||||
gtk_root_start_layout_phase (root);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_root_add_mnemonic (GtkRoot *root,
|
||||
guint keyval,
|
||||
GtkWidget *target)
|
||||
{
|
||||
g_return_if_fail (GTK_ROOT (root));
|
||||
|
||||
GTK_ROOT_GET_IFACE (root)->add_mnemonic (root, keyval, target);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_root_remove_mnemonic (GtkRoot *root,
|
||||
guint keyval,
|
||||
GtkWidget *target)
|
||||
{
|
||||
g_return_if_fail (GTK_ROOT (root));
|
||||
|
||||
GTK_ROOT_GET_IFACE (root)->remove_mnemonic (root, keyval, target);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_root_activate_key (GtkRoot *root,
|
||||
GdkEventKey *event)
|
||||
{
|
||||
g_return_val_if_fail (GTK_ROOT (root), FALSE);
|
||||
|
||||
return GTK_ROOT_GET_IFACE (root)->activate_key (root, event);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_root_update_pointer_focus (GtkRoot *root,
|
||||
GdkDevice *device,
|
||||
GdkEventSequence *sequence,
|
||||
GtkWidget *target,
|
||||
double x,
|
||||
double y)
|
||||
{
|
||||
GTK_ROOT_GET_IFACE (root)->update_pointer_focus (root, device, sequence, target, x, y);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_root_update_pointer_focus_on_state_change (GtkRoot *root,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
GTK_ROOT_GET_IFACE (root)->update_pointer_focus_on_state_change (root, widget);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
gtk_root_lookup_pointer_focus (GtkRoot *root,
|
||||
GdkDevice *device,
|
||||
GdkEventSequence *sequence)
|
||||
{
|
||||
return GTK_ROOT_GET_IFACE (root)->lookup_pointer_focus (root, device, sequence);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
gtk_root_lookup_pointer_focus_implicit_grab (GtkRoot *root,
|
||||
GdkDevice *device,
|
||||
GdkEventSequence *sequence)
|
||||
{
|
||||
return GTK_ROOT_GET_IFACE (root)->lookup_pointer_focus_implicit_grab (root, device, sequence);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
gtk_root_lookup_effective_pointer_focus (GtkRoot *root,
|
||||
GdkDevice *device,
|
||||
GdkEventSequence *sequence)
|
||||
{
|
||||
return GTK_ROOT_GET_IFACE (root)->lookup_effective_pointer_focus (root, device, sequence);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_root_set_pointer_focus_grab (GtkRoot *root,
|
||||
GdkDevice *device,
|
||||
GdkEventSequence *sequence,
|
||||
GtkWidget *target)
|
||||
{
|
||||
GTK_ROOT_GET_IFACE (root)->set_pointer_focus_grab (root, device, sequence, target);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_root_maybe_update_cursor (GtkRoot *root,
|
||||
GtkWidget *widget,
|
||||
GdkDevice *device)
|
||||
{
|
||||
GTK_ROOT_GET_IFACE (root)->maybe_update_cursor (root, widget, device);
|
||||
}
|
||||
|
@@ -51,6 +51,45 @@ struct _GtkRootInterface
|
||||
void (* get_surface_transform) (GtkRoot *root,
|
||||
int *x,
|
||||
int *y);
|
||||
|
||||
/* size allocation */
|
||||
void (* check_resize) (GtkRoot *root);
|
||||
|
||||
/* mnemonics */
|
||||
void (* add_mnemonic) (GtkRoot *root,
|
||||
guint keyval,
|
||||
GtkWidget *target);
|
||||
void (* remove_mnemonic) (GtkRoot *root,
|
||||
guint keyval,
|
||||
GtkWidget *target);
|
||||
gboolean (* activate_key) (GtkRoot *root,
|
||||
GdkEventKey *event);
|
||||
|
||||
/* pointer focus */
|
||||
void (* update_pointer_focus) (GtkRoot *root,
|
||||
GdkDevice *device,
|
||||
GdkEventSequence *sequence,
|
||||
GtkWidget *target,
|
||||
double x,
|
||||
double y);
|
||||
void (* update_pointer_focus_on_state_change) (GtkRoot *root,
|
||||
GtkWidget *widget);
|
||||
GtkWidget * (* lookup_pointer_focus) (GtkRoot *root,
|
||||
GdkDevice *device,
|
||||
GdkEventSequence *sequence);
|
||||
GtkWidget * (* lookup_pointer_focus_implicit_grab) (GtkRoot *root,
|
||||
GdkDevice *device,
|
||||
GdkEventSequence *sequence);
|
||||
GtkWidget * (* lookup_effective_pointer_focus) (GtkRoot *root,
|
||||
GdkDevice *device,
|
||||
GdkEventSequence *sequence);
|
||||
void (* set_pointer_focus_grab) (GtkRoot *root,
|
||||
GdkDevice *device,
|
||||
GdkEventSequence *sequence,
|
||||
GtkWidget *target);
|
||||
void (* maybe_update_cursor) (GtkRoot *root,
|
||||
GtkWidget *widget,
|
||||
GdkDevice *device);
|
||||
};
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
@@ -61,6 +100,25 @@ void gtk_root_set_focus (GtkRoot *self,
|
||||
GtkWidget *focus);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkWidget * gtk_root_get_focus (GtkRoot *self);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_root_activate_focus (GtkRoot *self);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_root_set_default (GtkRoot *self,
|
||||
GtkWidget *widget);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkWidget * gtk_root_get_default (GtkRoot *self);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_root_activate_default (GtkRoot *self);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_root_add_mnemonic (GtkRoot *root,
|
||||
guint keyval,
|
||||
GtkWidget *target);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_root_remove_mnemonic (GtkRoot *root,
|
||||
guint keyval,
|
||||
GtkWidget *target);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@@ -5,14 +5,48 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GdkDisplay * gtk_root_get_display (GtkRoot *root);
|
||||
GdkDisplay * gtk_root_get_display (GtkRoot *self);
|
||||
GskRenderer * gtk_root_get_renderer (GtkRoot *self);
|
||||
|
||||
void gtk_root_get_surface_transform (GtkRoot *self,
|
||||
int *x,
|
||||
int *y);
|
||||
|
||||
void gtk_root_queue_restyle (GtkRoot *self);
|
||||
void gtk_root_start_layout_phase (GtkRoot *self);
|
||||
void gtk_root_stop_layout_phase (GtkRoot *self);
|
||||
|
||||
gboolean gtk_root_activate_key (GtkRoot *self,
|
||||
GdkEventKey *event);
|
||||
|
||||
void gtk_root_update_pointer_focus (GtkRoot *root,
|
||||
GdkDevice *device,
|
||||
GdkEventSequence *sequence,
|
||||
GtkWidget *target,
|
||||
double x,
|
||||
double y);
|
||||
void gtk_root_update_pointer_focus_on_state_change (GtkRoot *root,
|
||||
GtkWidget *widget);
|
||||
GtkWidget * gtk_root_lookup_pointer_focus (GtkRoot *root,
|
||||
GdkDevice *device,
|
||||
GdkEventSequence *sequence);
|
||||
GtkWidget * gtk_root_lookup_pointer_focus_implicit_grab (GtkRoot *root,
|
||||
GdkDevice *device,
|
||||
GdkEventSequence *sequence);
|
||||
GtkWidget * gtk_root_lookup_effective_pointer_focus (GtkRoot *root,
|
||||
GdkDevice *device,
|
||||
GdkEventSequence *sequence);
|
||||
void gtk_root_set_pointer_focus_grab (GtkRoot *root,
|
||||
GdkDevice *device,
|
||||
GdkEventSequence *sequence,
|
||||
GtkWidget *target);
|
||||
void gtk_root_maybe_update_cursor (GtkRoot *root,
|
||||
GtkWidget *widget,
|
||||
GdkDevice *device);
|
||||
|
||||
enum {
|
||||
GTK_ROOT_PROP_FOCUS_WIDGET,
|
||||
GTK_ROOT_PROP_DEFAULT_WIDGET,
|
||||
GTK_ROOT_NUM_PROPERTIES
|
||||
} GtkRootProperties;
|
||||
|
||||
|
@@ -3845,30 +3845,9 @@ static void
|
||||
gtk_text_real_activate (GtkText *self)
|
||||
{
|
||||
GtkTextPrivate *priv = gtk_text_get_instance_private (self);
|
||||
GtkWindow *window;
|
||||
GtkWidget *default_widget, *focus_widget;
|
||||
GtkWidget *toplevel;
|
||||
GtkWidget *widget;
|
||||
|
||||
widget = GTK_WIDGET (self);
|
||||
|
||||
if (priv->activates_default)
|
||||
{
|
||||
toplevel = gtk_widget_get_toplevel (widget);
|
||||
if (GTK_IS_WINDOW (toplevel))
|
||||
{
|
||||
window = GTK_WINDOW (toplevel);
|
||||
|
||||
if (window)
|
||||
{
|
||||
default_widget = gtk_window_get_default_widget (window);
|
||||
focus_widget = gtk_root_get_focus (GTK_ROOT (window));
|
||||
if (widget != default_widget &&
|
||||
!(widget == focus_widget && (!default_widget || !gtk_widget_get_sensitive (default_widget))))
|
||||
gtk_window_activate_default (window);
|
||||
}
|
||||
}
|
||||
}
|
||||
gtk_root_activate_default (gtk_widget_get_root (GTK_WIDGET (self)));
|
||||
}
|
||||
|
||||
static void
|
||||
|
145
gtk/gtkwidget.c
145
gtk/gtkwidget.c
@@ -56,6 +56,7 @@
|
||||
#include "gtkprivate.h"
|
||||
#include "gtkrenderbackgroundprivate.h"
|
||||
#include "gtkrenderborderprivate.h"
|
||||
#include "gtkrootprivate.h"
|
||||
#include "gtkscrollable.h"
|
||||
#include "gtkselection.h"
|
||||
#include "gtksettingsprivate.h"
|
||||
@@ -812,7 +813,9 @@ gtk_widget_real_snapshot (GtkWidget *widget,
|
||||
for (child = _gtk_widget_get_first_child (widget);
|
||||
child != NULL;
|
||||
child = _gtk_widget_get_next_sibling (child))
|
||||
gtk_widget_snapshot_child (widget, child, snapshot);
|
||||
{
|
||||
gtk_widget_snapshot_child (widget, child, snapshot);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -2535,7 +2538,7 @@ _gtk_widget_emulate_press (GtkWidget *widget,
|
||||
|
||||
gdk_event_get_coords (event, &x, &y);
|
||||
if (!gtk_widget_compute_point (event_widget,
|
||||
gtk_widget_get_toplevel (event_widget),
|
||||
GTK_WIDGET (gtk_widget_get_root (event_widget)),
|
||||
&GRAPHENE_POINT_INIT (x, y),
|
||||
&p))
|
||||
return;
|
||||
@@ -2997,7 +3000,7 @@ gtk_widget_unparent (GtkWidget *widget)
|
||||
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
|
||||
GtkWidget *old_parent;
|
||||
GtkWidget *old_prev_sibling;
|
||||
GtkWidget *toplevel;
|
||||
GtkRoot *root;
|
||||
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
|
||||
@@ -3010,9 +3013,9 @@ gtk_widget_unparent (GtkWidget *widget)
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (widget));
|
||||
|
||||
toplevel = _gtk_widget_get_toplevel (widget);
|
||||
if (_gtk_widget_is_toplevel (toplevel))
|
||||
_gtk_window_unset_focus_and_default (GTK_WINDOW (toplevel), widget);
|
||||
root = _gtk_widget_get_root (widget);
|
||||
if (GTK_IS_WINDOW (root))
|
||||
_gtk_window_unset_focus_and_default (GTK_WINDOW (root), widget);
|
||||
|
||||
if (gtk_widget_get_focus_child (priv->parent) == widget)
|
||||
gtk_widget_set_focus_child (priv->parent, NULL);
|
||||
@@ -3035,7 +3038,7 @@ gtk_widget_unparent (GtkWidget *widget)
|
||||
if (priv->root)
|
||||
gtk_widget_unroot (widget);
|
||||
|
||||
toplevel = NULL;
|
||||
root = NULL;
|
||||
|
||||
/* Removing a widget from a container restores the child visible
|
||||
* flag to the default state, so it doesn't affect the child
|
||||
@@ -3259,14 +3262,15 @@ gtk_widget_hide (GtkWidget *widget)
|
||||
|
||||
if (_gtk_widget_get_visible (widget))
|
||||
{
|
||||
GtkWidget *toplevel = _gtk_widget_get_toplevel (widget);
|
||||
GtkWidget *parent;
|
||||
GtkRoot *root;
|
||||
|
||||
g_object_ref (widget);
|
||||
gtk_widget_push_verify_invariants (widget);
|
||||
|
||||
if (toplevel != widget && _gtk_widget_is_toplevel (toplevel))
|
||||
_gtk_window_unset_focus_and_default (GTK_WINDOW (toplevel), widget);
|
||||
root = _gtk_widget_get_root (widget);
|
||||
if (GTK_WIDGET (root) != widget && GTK_IS_WINDOW (root))
|
||||
_gtk_window_unset_focus_and_default (GTK_WINDOW (root), widget);
|
||||
|
||||
/* a parent may now be expand=FALSE since we're hidden. */
|
||||
if (priv->need_compute_expand ||
|
||||
@@ -3309,14 +3313,11 @@ gtk_widget_real_hide (GtkWidget *widget)
|
||||
static void
|
||||
update_cursor_on_state_change (GtkWidget *widget)
|
||||
{
|
||||
GtkWidget *toplevel;
|
||||
GtkRoot *root;
|
||||
|
||||
toplevel = gtk_widget_get_toplevel (widget);
|
||||
if (!GTK_IS_WINDOW (toplevel))
|
||||
return;
|
||||
|
||||
gtk_window_update_pointer_focus_on_state_change (GTK_WINDOW (toplevel),
|
||||
widget);
|
||||
root = _gtk_widget_get_root (widget);
|
||||
if (root)
|
||||
gtk_root_update_pointer_focus_on_state_change (root, widget);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3599,8 +3600,8 @@ gtk_widget_connect_frame_clock (GtkWidget *widget)
|
||||
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
|
||||
GdkFrameClock *frame_clock;
|
||||
|
||||
if (GTK_IS_CONTAINER (widget) && _gtk_widget_is_toplevel (widget))
|
||||
gtk_container_start_idle_sizer (GTK_CONTAINER (widget));
|
||||
if (GTK_IS_ROOT (widget))
|
||||
gtk_root_start_layout_phase (GTK_ROOT (widget));
|
||||
|
||||
frame_clock = gtk_widget_get_frame_clock (widget);
|
||||
|
||||
@@ -3620,8 +3621,8 @@ gtk_widget_disconnect_frame_clock (GtkWidget *widget)
|
||||
{
|
||||
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
|
||||
|
||||
if (GTK_IS_CONTAINER (widget) && _gtk_widget_is_toplevel (widget))
|
||||
gtk_container_stop_idle_sizer (GTK_CONTAINER (widget));
|
||||
if (GTK_IS_ROOT (widget))
|
||||
gtk_root_stop_layout_phase (GTK_ROOT (widget));
|
||||
|
||||
gtk_css_node_invalidate_frame_clock (priv->cssnode, FALSE);
|
||||
|
||||
@@ -3979,14 +3980,14 @@ gtk_widget_get_frame_clock (GtkWidget *widget)
|
||||
|
||||
if (priv->realized)
|
||||
{
|
||||
/* We use gtk_widget_get_toplevel() here to make it explicit that
|
||||
/* We use gtk_widget_get_root() here to make it explicit that
|
||||
* the frame clock is a property of the toplevel that a widget
|
||||
* is anchored to; gdk_surface_get_toplevel() will go up the
|
||||
* hierarchy anyways, but should squash any funny business with
|
||||
* reparenting windows and widgets.
|
||||
*/
|
||||
GtkWidget *toplevel = _gtk_widget_get_toplevel (widget);
|
||||
GdkSurface *surface = _gtk_widget_get_surface (toplevel);
|
||||
GtkRoot *root = _gtk_widget_get_root (widget);
|
||||
GdkSurface *surface = _gtk_widget_get_surface (GTK_WIDGET (root));
|
||||
g_assert (surface != NULL);
|
||||
|
||||
return gdk_surface_get_frame_clock (surface);
|
||||
@@ -4255,7 +4256,8 @@ gtk_widget_allocate (GtkWidget *widget,
|
||||
{
|
||||
/* Still have to move the window... */
|
||||
if (_gtk_widget_get_realized (widget) &&
|
||||
_gtk_widget_get_has_surface (widget))
|
||||
_gtk_widget_get_has_surface (widget) &&
|
||||
GTK_IS_POPOVER (widget))
|
||||
{
|
||||
GtkAllocation window_alloc;
|
||||
|
||||
@@ -4431,7 +4433,7 @@ gtk_widget_translate_coordinates (GtkWidget *src_widget,
|
||||
*
|
||||
* Translates the given @point in @widget's coordinates to coordinates
|
||||
* relative to @target’s coodinate system. In order to perform this
|
||||
* operation, both widgets must share a common ancestor.
|
||||
* operation, both widgets must share a common root.
|
||||
*
|
||||
* Returns: %TRUE if the point could be determined, %FALSE on failure.
|
||||
* In this case, 0 is stored in @out_point.
|
||||
@@ -4467,7 +4469,8 @@ gtk_widget_real_size_allocate (GtkWidget *widget,
|
||||
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
|
||||
|
||||
if (_gtk_widget_get_realized (widget) &&
|
||||
_gtk_widget_get_has_surface (widget))
|
||||
_gtk_widget_get_has_surface (widget) &&
|
||||
GTK_IS_POPOVER (widget))
|
||||
{
|
||||
GtkAllocation window_alloc;
|
||||
|
||||
@@ -5384,10 +5387,11 @@ static void
|
||||
gtk_widget_real_move_focus (GtkWidget *widget,
|
||||
GtkDirectionType direction)
|
||||
{
|
||||
GtkWidget *toplevel = _gtk_widget_get_toplevel (widget);
|
||||
GtkRoot *root;
|
||||
|
||||
if (widget != toplevel && GTK_IS_WINDOW (toplevel))
|
||||
g_signal_emit (toplevel, widget_signals[MOVE_FOCUS], 0, direction);
|
||||
root = _gtk_widget_get_root (widget);
|
||||
if (widget != GTK_WIDGET (root))
|
||||
g_signal_emit (root, widget_signals[MOVE_FOCUS], 0, direction);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -5510,12 +5514,10 @@ gtk_widget_has_visible_focus (GtkWidget *widget)
|
||||
|
||||
if (priv->has_focus)
|
||||
{
|
||||
GtkWidget *toplevel;
|
||||
GtkRoot *root = _gtk_widget_get_root (widget);
|
||||
|
||||
toplevel = _gtk_widget_get_toplevel (widget);
|
||||
|
||||
if (GTK_IS_WINDOW (toplevel))
|
||||
draw_focus = gtk_window_get_focus_visible (GTK_WINDOW (toplevel));
|
||||
if (GTK_IS_WINDOW (root))
|
||||
draw_focus = gtk_window_get_focus_visible (GTK_WINDOW (root));
|
||||
else
|
||||
draw_focus = TRUE;
|
||||
}
|
||||
@@ -5697,17 +5699,10 @@ _gtk_widget_set_has_default (GtkWidget *widget,
|
||||
void
|
||||
gtk_widget_grab_default (GtkWidget *widget)
|
||||
{
|
||||
GtkWidget *window;
|
||||
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
g_return_if_fail (gtk_widget_get_can_default (widget));
|
||||
|
||||
window = _gtk_widget_get_toplevel (widget);
|
||||
|
||||
if (window && _gtk_widget_is_toplevel (window))
|
||||
gtk_window_set_default (GTK_WINDOW (window), widget);
|
||||
else
|
||||
g_warning (G_STRLOC ": widget not within a GtkWindow");
|
||||
gtk_root_set_default (gtk_widget_get_root (widget), widget);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -5810,7 +5805,8 @@ gtk_widget_device_is_shadowed (GtkWidget *widget,
|
||||
GdkDevice *device)
|
||||
{
|
||||
GtkWindowGroup *group;
|
||||
GtkWidget *grab_widget, *toplevel;
|
||||
GtkWidget *grab_widget;
|
||||
GtkRoot *root;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
|
||||
g_return_val_if_fail (GDK_IS_DEVICE (device), FALSE);
|
||||
@@ -5818,10 +5814,10 @@ gtk_widget_device_is_shadowed (GtkWidget *widget,
|
||||
if (!_gtk_widget_get_realized (widget))
|
||||
return TRUE;
|
||||
|
||||
toplevel = _gtk_widget_get_toplevel (widget);
|
||||
root = _gtk_widget_get_root (widget);
|
||||
|
||||
if (GTK_IS_WINDOW (toplevel))
|
||||
group = gtk_window_get_group (GTK_WINDOW (toplevel));
|
||||
if (GTK_IS_WINDOW (root))
|
||||
group = gtk_window_get_group (GTK_WINDOW (root));
|
||||
else
|
||||
group = gtk_window_get_group (NULL);
|
||||
|
||||
@@ -6185,9 +6181,11 @@ gtk_widget_get_has_surface (GtkWidget *widget)
|
||||
gboolean
|
||||
gtk_widget_is_toplevel (GtkWidget *widget)
|
||||
{
|
||||
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
|
||||
|
||||
g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
|
||||
|
||||
return GTK_IS_ROOT (widget);
|
||||
return priv->parent == NULL && GTK_IS_ROOT (widget);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -6360,12 +6358,6 @@ gtk_widget_reposition_after (GtkWidget *widget,
|
||||
return;
|
||||
}
|
||||
|
||||
if (_gtk_widget_is_toplevel (widget))
|
||||
{
|
||||
g_warning ("Can't set a parent on a toplevel widget");
|
||||
return;
|
||||
}
|
||||
|
||||
data.old_scale_factor = gtk_widget_get_scale_factor (widget);
|
||||
|
||||
/* keep this function in sync with gtk_menu_attach_to_widget()
|
||||
@@ -7254,13 +7246,13 @@ gtk_widget_set_child_visible (GtkWidget *widget,
|
||||
priv->child_visible = TRUE;
|
||||
else
|
||||
{
|
||||
GtkWidget *toplevel;
|
||||
GtkRoot *root;
|
||||
|
||||
priv->child_visible = FALSE;
|
||||
|
||||
toplevel = _gtk_widget_get_toplevel (widget);
|
||||
if (toplevel != widget && _gtk_widget_is_toplevel (toplevel))
|
||||
_gtk_window_unset_focus_and_default (GTK_WINDOW (toplevel), widget);
|
||||
root = _gtk_widget_get_root (widget);
|
||||
if (GTK_WIDGET (root) != widget && GTK_IS_WINDOW (root))
|
||||
_gtk_window_unset_focus_and_default (GTK_WINDOW (root), widget);
|
||||
}
|
||||
|
||||
if (priv->parent && _gtk_widget_get_realized (priv->parent))
|
||||
@@ -7332,7 +7324,7 @@ _gtk_widget_scale_changed (GtkWidget *widget)
|
||||
gint
|
||||
gtk_widget_get_scale_factor (GtkWidget *widget)
|
||||
{
|
||||
GtkWidget *toplevel;
|
||||
GtkRoot *root;
|
||||
GdkDisplay *display;
|
||||
GdkMonitor *monitor;
|
||||
|
||||
@@ -7341,9 +7333,9 @@ gtk_widget_get_scale_factor (GtkWidget *widget)
|
||||
if (_gtk_widget_get_realized (widget))
|
||||
return gdk_surface_get_scale_factor (_gtk_widget_get_surface (widget));
|
||||
|
||||
toplevel = _gtk_widget_get_toplevel (widget);
|
||||
if (toplevel && toplevel != widget)
|
||||
return gtk_widget_get_scale_factor (toplevel);
|
||||
root = _gtk_widget_get_root (widget);
|
||||
if (root && GTK_WIDGET (root) != widget)
|
||||
return gtk_widget_get_scale_factor (GTK_WIDGET (root));
|
||||
|
||||
/* else fall back to something that is more likely to be right than
|
||||
* just returning 1:
|
||||
@@ -10168,7 +10160,8 @@ _gtk_widget_buildable_finish_accelerator (GtkWidget *widget,
|
||||
if (g_slist_length (accel_groups) == 0)
|
||||
{
|
||||
accel_group = gtk_accel_group_new ();
|
||||
gtk_window_add_accel_group (GTK_WINDOW (toplevel), accel_group);
|
||||
if (GTK_IS_WINDOW (toplevel))
|
||||
gtk_window_add_accel_group (GTK_WINDOW (toplevel), accel_group);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -10264,14 +10257,14 @@ gtk_widget_buildable_custom_finished (GtkBuildable *buildable,
|
||||
if (strcmp (tagname, "accelerator") == 0)
|
||||
{
|
||||
AccelGroupParserData *accel_data;
|
||||
GtkWidget *toplevel;
|
||||
GtkRoot *root;
|
||||
|
||||
accel_data = (AccelGroupParserData*)user_data;
|
||||
g_assert (accel_data->object);
|
||||
|
||||
toplevel = _gtk_widget_get_toplevel (GTK_WIDGET (accel_data->object));
|
||||
root = _gtk_widget_get_root (GTK_WIDGET (accel_data->object));
|
||||
|
||||
_gtk_widget_buildable_finish_accelerator (GTK_WIDGET (buildable), toplevel, user_data);
|
||||
_gtk_widget_buildable_finish_accelerator (GTK_WIDGET (buildable), GTK_WIDGET (root), user_data);
|
||||
}
|
||||
else if (strcmp (tagname, "accessibility") == 0)
|
||||
{
|
||||
@@ -11149,6 +11142,9 @@ gtk_widget_compute_transform (GtkWidget *widget,
|
||||
g_return_val_if_fail (GTK_IS_WIDGET (target), FALSE);
|
||||
g_return_val_if_fail (out_transform != NULL, FALSE);
|
||||
|
||||
if (widget->priv->root != target->priv->root)
|
||||
return FALSE;
|
||||
|
||||
/* optimization for common case: parent wants coordinates of a direct child */
|
||||
if (target == widget->priv->parent)
|
||||
{
|
||||
@@ -11698,9 +11694,9 @@ gtk_widget_set_alloc_needed (GtkWidget *widget)
|
||||
if (!priv->visible)
|
||||
break;
|
||||
|
||||
if (_gtk_widget_is_toplevel (widget))
|
||||
if (GTK_IS_ROOT (widget))
|
||||
{
|
||||
gtk_container_start_idle_sizer (GTK_CONTAINER (widget));
|
||||
gtk_root_start_layout_phase (GTK_ROOT (widget));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -13311,6 +13307,8 @@ gtk_widget_forall (GtkWidget *widget,
|
||||
*
|
||||
* gtk_widget_snapshot_child() takes care of translating the origin of
|
||||
* @snapshot, and deciding whether the child needs to be snapshot.
|
||||
*
|
||||
* This function does nothing for children that are roots themselves.
|
||||
**/
|
||||
void
|
||||
gtk_widget_snapshot_child (GtkWidget *widget,
|
||||
@@ -13322,6 +13320,9 @@ gtk_widget_snapshot_child (GtkWidget *widget,
|
||||
g_return_if_fail (_gtk_widget_get_parent (child) == widget);
|
||||
g_return_if_fail (snapshot != NULL);
|
||||
|
||||
if (GTK_IS_ROOT (child))
|
||||
return;
|
||||
|
||||
gtk_snapshot_save (snapshot);
|
||||
gtk_snapshot_transform (snapshot, priv->transform);
|
||||
|
||||
@@ -13395,7 +13396,7 @@ gtk_widget_set_cursor (GtkWidget *widget,
|
||||
GdkCursor *cursor)
|
||||
{
|
||||
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
|
||||
GtkWidget *toplevel;
|
||||
GtkRoot *root;
|
||||
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
g_return_if_fail (cursor == NULL || GDK_IS_CURSOR (cursor));
|
||||
@@ -13403,9 +13404,9 @@ gtk_widget_set_cursor (GtkWidget *widget,
|
||||
if (!g_set_object (&priv->cursor, cursor))
|
||||
return;
|
||||
|
||||
toplevel = gtk_widget_get_toplevel (widget);
|
||||
if (GTK_IS_WINDOW (toplevel))
|
||||
gtk_window_maybe_update_cursor (GTK_WINDOW (toplevel), widget, NULL);
|
||||
root = _gtk_widget_get_root (widget);
|
||||
if (root)
|
||||
gtk_root_maybe_update_cursor (root, widget, NULL);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_CURSOR]);
|
||||
}
|
||||
|
113
gtk/gtkwindow.c
113
gtk/gtkwindow.c
@@ -2038,6 +2038,9 @@ gtk_window_set_property (GObject *object,
|
||||
case LAST_ARG + GTK_ROOT_PROP_FOCUS_WIDGET:
|
||||
gtk_window_set_focus (window, g_value_get_object (value));
|
||||
break;
|
||||
case LAST_ARG + GTK_ROOT_PROP_DEFAULT_WIDGET:
|
||||
gtk_window_set_default (window, g_value_get_object (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@@ -2150,6 +2153,9 @@ gtk_window_get_property (GObject *object,
|
||||
case LAST_ARG + GTK_ROOT_PROP_FOCUS_WIDGET:
|
||||
g_value_set_object (value, gtk_window_get_focus (window));
|
||||
break;
|
||||
case LAST_ARG + GTK_ROOT_PROP_DEFAULT_WIDGET:
|
||||
g_value_set_object (value, gtk_window_get_default_widget (window));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@@ -2392,12 +2398,111 @@ gtk_window_root_get_surface_transform (GtkRoot *root,
|
||||
*y = margin.top + border.top + padding.top;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_window_root_check_resize (GtkRoot *root)
|
||||
{
|
||||
gtk_window_check_resize (GTK_WINDOW (root));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_window_root_add_mnemonic (GtkRoot *root,
|
||||
guint keyval,
|
||||
GtkWidget *target)
|
||||
{
|
||||
gtk_window_add_mnemonic (GTK_WINDOW (root), keyval, target);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_window_root_remove_mnemonic (GtkRoot *root,
|
||||
guint keyval,
|
||||
GtkWidget *target)
|
||||
{
|
||||
gtk_window_remove_mnemonic (GTK_WINDOW (root), keyval, target);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_window_root_activate_key (GtkRoot *root,
|
||||
GdkEventKey *event)
|
||||
{
|
||||
return gtk_window_activate_key (GTK_WINDOW (root), event);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_window_root_update_pointer_focus (GtkRoot *root,
|
||||
GdkDevice *device,
|
||||
GdkEventSequence *sequence,
|
||||
GtkWidget *target,
|
||||
double x,
|
||||
double y)
|
||||
{
|
||||
gtk_window_update_pointer_focus (GTK_WINDOW (root), device, sequence, target, x, y);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_window_root_update_pointer_focus_on_state_change (GtkRoot *root,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
gtk_window_update_pointer_focus_on_state_change (GTK_WINDOW (root), widget);
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
gtk_window_root_lookup_pointer_focus (GtkRoot *root,
|
||||
GdkDevice *device,
|
||||
GdkEventSequence *sequence)
|
||||
{
|
||||
return gtk_window_lookup_pointer_focus_widget (GTK_WINDOW (root), device, sequence);
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
gtk_window_root_lookup_pointer_focus_implicit_grab (GtkRoot *root,
|
||||
GdkDevice *device,
|
||||
GdkEventSequence *sequence)
|
||||
{
|
||||
return gtk_window_lookup_pointer_focus_implicit_grab (GTK_WINDOW (root), device, sequence);
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
gtk_window_root_lookup_effective_pointer_focus (GtkRoot *root,
|
||||
GdkDevice *device,
|
||||
GdkEventSequence *sequence)
|
||||
{
|
||||
return gtk_window_lookup_effective_pointer_focus_widget (GTK_WINDOW (root), device, sequence);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_window_root_set_pointer_focus_grab (GtkRoot *root,
|
||||
GdkDevice *device,
|
||||
GdkEventSequence *sequence,
|
||||
GtkWidget *grab_widget)
|
||||
{
|
||||
gtk_window_set_pointer_focus_grab (GTK_WINDOW (root), device, sequence, grab_widget);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_window_root_maybe_update_cursor (GtkRoot *root,
|
||||
GtkWidget *widget,
|
||||
GdkDevice *device)
|
||||
{
|
||||
gtk_window_maybe_update_cursor (GTK_WINDOW (root), widget, device);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_window_root_interface_init (GtkRootInterface *iface)
|
||||
{
|
||||
iface->get_display = gtk_window_root_get_display;
|
||||
iface->get_renderer = gtk_window_root_get_renderer;
|
||||
iface->get_surface_transform = gtk_window_root_get_surface_transform;
|
||||
iface->check_resize = gtk_window_root_check_resize;
|
||||
iface->add_mnemonic = gtk_window_root_add_mnemonic;
|
||||
iface->remove_mnemonic = gtk_window_root_remove_mnemonic;
|
||||
iface->activate_key = gtk_window_root_activate_key;
|
||||
iface->update_pointer_focus = gtk_window_root_update_pointer_focus;
|
||||
iface->update_pointer_focus_on_state_change = gtk_window_root_update_pointer_focus_on_state_change;
|
||||
iface->lookup_pointer_focus = gtk_window_root_lookup_pointer_focus;
|
||||
iface->lookup_pointer_focus_implicit_grab = gtk_window_root_lookup_pointer_focus_implicit_grab;
|
||||
iface->lookup_effective_pointer_focus = gtk_window_root_lookup_effective_pointer_focus;
|
||||
iface->set_pointer_focus_grab = gtk_window_root_set_pointer_focus_grab;
|
||||
iface->maybe_update_cursor = gtk_window_root_maybe_update_cursor;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -6377,7 +6482,7 @@ gtk_window_propagate_key_event (GtkWindow *window,
|
||||
|
||||
while (!handled &&
|
||||
focus && focus != widget &&
|
||||
gtk_widget_get_toplevel (focus) == widget)
|
||||
gtk_widget_get_root (focus) == GTK_ROOT (widget))
|
||||
{
|
||||
GtkWidget *parent;
|
||||
|
||||
@@ -9992,7 +10097,7 @@ gtk_window_update_pointer_focus (GtkWindow *window,
|
||||
}
|
||||
else if (target)
|
||||
{
|
||||
focus = gtk_pointer_focus_new (window, target, device, sequence, x, y);
|
||||
focus = gtk_pointer_focus_new (GTK_ROOT (window), target, device, sequence, x, y);
|
||||
gtk_window_add_pointer_focus (window, focus);
|
||||
gtk_pointer_focus_unref (focus);
|
||||
}
|
||||
@@ -10052,7 +10157,7 @@ gtk_window_maybe_revoke_implicit_grab (GtkWindow *window,
|
||||
focus = cur->data;
|
||||
l = cur->next;
|
||||
|
||||
if (focus->toplevel != window)
|
||||
if (GTK_WINDOW (focus->toplevel) != window)
|
||||
continue;
|
||||
|
||||
if (device && focus->device == device &&
|
||||
@@ -10081,7 +10186,7 @@ gtk_window_set_pointer_focus_grab (GtkWindow *window,
|
||||
}
|
||||
|
||||
static void
|
||||
update_cursor (GtkWindow *toplevel,
|
||||
update_cursor (GtkRoot *toplevel,
|
||||
GdkDevice *device,
|
||||
GtkWidget *grab_widget,
|
||||
GtkWidget *target)
|
||||
|
@@ -56,6 +56,7 @@
|
||||
#include "gtksearchbar.h"
|
||||
#include "gtksearchentry.h"
|
||||
#include "gtkeventcontrollerkey.h"
|
||||
#include "gtkpopup.h"
|
||||
|
||||
enum
|
||||
{
|
||||
@@ -1144,6 +1145,7 @@ create_root_model (void)
|
||||
g_object_unref);
|
||||
gtk_filter_list_model_set_model (filter, gtk_window_get_toplevels ());
|
||||
g_list_store_append (list, filter);
|
||||
g_list_store_append (list, gtk_popup_get_popups ());
|
||||
g_object_unref (filter);
|
||||
|
||||
flatten = gtk_flatten_list_model_new (G_TYPE_OBJECT, G_LIST_MODEL (list));
|
||||
|
@@ -298,6 +298,7 @@ gtk_public_sources = files([
|
||||
'gtkpicture.c',
|
||||
'gtkpopover.c',
|
||||
'gtkpopovermenu.c',
|
||||
'gtkpopup.c',
|
||||
'gtkprintcontext.c',
|
||||
'gtkprintoperation.c',
|
||||
'gtkprintoperationpreview.c',
|
||||
|
@@ -1,58 +1,85 @@
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
static void
|
||||
draw_popup (GtkDrawingArea *da,
|
||||
cairo_t *cr,
|
||||
int width,
|
||||
int height,
|
||||
gpointer data)
|
||||
clicked (GtkButton *button)
|
||||
{
|
||||
cairo_set_source_rgb (cr, 1, 0, 0);
|
||||
cairo_paint (cr);
|
||||
g_print ("Yes!\n");
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
add_content (GtkWidget *parent)
|
||||
{
|
||||
GtkWidget *box, *label, *entry, *button;
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
|
||||
gtk_widget_set_halign (box, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (box, GTK_ALIGN_CENTER);
|
||||
|
||||
label = gtk_label_new_with_mnemonic ("_Test");
|
||||
entry = gtk_entry_new ();
|
||||
button = gtk_button_new_with_mnemonic ("_Yes!");
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (clicked), NULL);
|
||||
|
||||
gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
|
||||
gtk_widget_set_can_default (button, TRUE);
|
||||
gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (box), label);
|
||||
gtk_container_add (GTK_CONTAINER (box), entry);
|
||||
gtk_container_add (GTK_CONTAINER (box), button);
|
||||
gtk_container_add (GTK_CONTAINER (parent), box);
|
||||
|
||||
gtk_widget_grab_default (button);
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_popup (GtkWidget *parent)
|
||||
{
|
||||
GtkWidget *popup;
|
||||
|
||||
popup = gtk_popup_new ();
|
||||
|
||||
gtk_popup_set_relative_to (GTK_POPUP (popup), parent);
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (popup), "background");
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (popup), "frame");
|
||||
|
||||
add_content (popup);
|
||||
|
||||
return popup;
|
||||
}
|
||||
|
||||
static void
|
||||
place_popup (GtkEventControllerMotion *motion,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
GtkWidget *popup)
|
||||
toggle_popup (GtkToggleButton *button, GtkWidget *popup)
|
||||
{
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_map (GtkWidget *parent)
|
||||
{
|
||||
GtkWidget *popup, *da;
|
||||
GtkEventController *motion;
|
||||
|
||||
popup = gtk_window_new (GTK_WINDOW_POPUP);
|
||||
da = gtk_drawing_area_new ();
|
||||
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (da), draw_popup, NULL, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (popup), da);
|
||||
|
||||
gtk_widget_set_size_request (GTK_WIDGET (popup), 20, 20);
|
||||
gtk_window_set_transient_for (GTK_WINDOW (popup), GTK_WINDOW (parent));
|
||||
|
||||
motion = gtk_event_controller_motion_new ();
|
||||
gtk_widget_add_controller (parent, motion);
|
||||
g_signal_connect (motion, "motion", G_CALLBACK (place_popup), popup);
|
||||
|
||||
gtk_widget_show (popup);
|
||||
|
||||
return FALSE;
|
||||
gtk_widget_set_visible (popup, !gtk_widget_get_visible (popup));
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
GtkWidget *window;
|
||||
GtkWidget *entry;
|
||||
GtkWidget *box;
|
||||
GtkWidget *popup;
|
||||
GtkWidget *button;
|
||||
|
||||
gtk_init ();
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 300, 200);
|
||||
|
||||
g_signal_connect (window, "destroy", gtk_main_quit, NULL);
|
||||
g_signal_connect (window, "map", G_CALLBACK (on_map), NULL);
|
||||
entry = add_content (window);
|
||||
box = gtk_widget_get_parent (entry);
|
||||
|
||||
popup = create_popup (entry);
|
||||
|
||||
button = gtk_toggle_button_new_with_mnemonic ("_Popup");
|
||||
g_signal_connect (button, "toggled", G_CALLBACK (toggle_popup), popup);
|
||||
gtk_container_add (GTK_CONTAINER (box), button);
|
||||
|
||||
g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
|
||||
|
||||
gtk_widget_show (window);
|
||||
|
||||
|
Reference in New Issue
Block a user