[gtk+] flowbox: correct the behavior with "can-focus"==FALSE
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] flowbox: correct the behavior with "can-focus"==FALSE
- Date: Sun, 4 Oct 2015 03:37:40 +0000 (UTC)
commit 3c253c46a5d3979475a6cd968cd15c85f0bf26b0
Author: Rafal Luzynski <digitalfreak lingonborough com>
Date: Sun Aug 23 02:32:21 2015 +0200
flowbox: correct the behavior with "can-focus"==FALSE
In fact there were two issues:
1. GtkFlowBoxChild with "can-focus"==FALSE should pass the focus
to its child immediately.
2. GtkFlowBox with "can-focus"==FALSE should cease its custom keynav
implementation and fall back to the default GtkContainer behavior
which is more natural.
Thanks to these changes the flow box can act as a better replacement
for GtkGrid and similar containers.
https://bugzilla.gnome.org/show_bug.cgi?id=753371
gtk/gtkflowbox.c | 63 ++++++++++++++++++++++++++++++++++++++++++-----------
gtk/gtkflowbox.h | 2 +-
2 files changed, 51 insertions(+), 14 deletions(-)
---
diff --git a/gtk/gtkflowbox.c b/gtk/gtkflowbox.c
index bfd1490..84fae7d 100644
--- a/gtk/gtkflowbox.c
+++ b/gtk/gtkflowbox.c
@@ -292,6 +292,23 @@ gtk_flow_box_child_focus (GtkWidget *widget,
child = gtk_bin_get_child (GTK_BIN (widget));
+ /* Without "can-focus" flag try to pass the focus to the child immediately */
+ if (!gtk_widget_get_can_focus (widget))
+ {
+ if (child)
+ {
+ if (gtk_widget_child_focus (child, direction))
+ {
+ GtkFlowBox *box;
+ box = gtk_flow_box_child_get_box (GTK_FLOW_BOX_CHILD (widget));
+ if (box)
+ gtk_flow_box_update_cursor (box, GTK_FLOW_BOX_CHILD (widget));
+ return TRUE;
+ }
+ }
+ return FALSE;
+ }
+
g_object_get (widget, "has-focus", &had_focus, NULL);
if (had_focus)
{
@@ -3193,6 +3210,12 @@ gtk_flow_box_focus (GtkWidget *widget,
GSequenceIter *iter;
GtkFlowBoxChild *next_focus_child;
+ /* Without "can-focus" flag fall back to the default behavior immediately */
+ if (!gtk_widget_get_can_focus (widget))
+ {
+ return GTK_WIDGET_CLASS (gtk_flow_box_parent_class)->focus (widget, direction);
+ }
+
focus_child = gtk_container_get_focus_child (GTK_CONTAINER (box));
next_focus_child = NULL;
@@ -3313,7 +3336,7 @@ gtk_flow_box_toggle_cursor_child (GtkFlowBox *box)
gtk_flow_box_select_and_activate (box, priv->cursor_child);
}
-static void
+static gboolean
gtk_flow_box_move_cursor (GtkFlowBox *box,
GtkMovementStep step,
gint count)
@@ -3331,6 +3354,10 @@ gtk_flow_box_move_cursor (GtkFlowBox *box,
GtkAdjustment *adjustment;
gboolean vertical;
+ /* Without "can-focus" flag fall back to the default behavior immediately */
+ if (!gtk_widget_get_can_focus (GTK_WIDGET (box)))
+ return FALSE;
+
vertical = priv->orientation == GTK_ORIENTATION_VERTICAL;
if (vertical)
@@ -3479,17 +3506,25 @@ gtk_flow_box_move_cursor (GtkFlowBox *box,
if (!gtk_widget_keynav_failed (GTK_WIDGET (box), direction))
{
- GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (box));
+ return FALSE;
+ }
- if (toplevel)
- gtk_widget_child_focus (toplevel,
- direction == GTK_DIR_UP ?
- GTK_DIR_TAB_BACKWARD :
- GTK_DIR_TAB_FORWARD);
+ return TRUE;
+ }
- }
+ /* If the child has its "can-focus" property set to FALSE then it will
+ * not grab the focus. We must pass the focus to its child directly.
+ */
+ if (!gtk_widget_get_can_focus (GTK_WIDGET (child)))
+ {
+ GtkWidget *subchild;
- return;
+ subchild = gtk_bin_get_child (GTK_BIN (child));
+ if (subchild)
+ {
+ GtkDirectionType direction = count < 0 ? GTK_DIR_TAB_BACKWARD : GTK_DIR_TAB_FORWARD;
+ gtk_widget_child_focus (subchild, direction);
+ }
}
get_current_selection_modifiers (GTK_WIDGET (box), &modify, &extend);
@@ -3497,6 +3532,7 @@ gtk_flow_box_move_cursor (GtkFlowBox *box,
gtk_flow_box_update_cursor (box, child);
if (!modify)
gtk_flow_box_update_selection (box, child, FALSE, extend);
+ return TRUE;
}
/* Selection {{{2 */
@@ -3845,8 +3881,6 @@ gtk_flow_box_class_init (GtkFlowBoxClass *class)
* The ::move-cursor signal is a
* [keybinding signal][GtkBindingSignal]
* which gets emitted when the user initiates a cursor movement.
- * If the cursor is not visible in @text_view, this signal causes
- * the viewport to be moved instead.
*
* Applications should not connect to it, but may emit it with
* g_signal_emit_by_name() if they need to control the cursor
@@ -3859,14 +3893,17 @@ gtk_flow_box_class_init (GtkFlowBoxClass *class)
* - Arrow keys move by individual children
* - Home/End keys move to the ends of the box
* - PageUp/PageDown keys move vertically by pages
+ *
+ * Returns: %TRUE to stop other handlers from being invoked for the event.
+ * %FALSE to propagate the event further.
*/
signals[MOVE_CURSOR] = g_signal_new (I_("move-cursor"),
GTK_TYPE_FLOW_BOX,
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET (GtkFlowBoxClass, move_cursor),
NULL, NULL,
- _gtk_marshal_VOID__ENUM_INT,
- G_TYPE_NONE, 2,
+ _gtk_marshal_BOOLEAN__ENUM_INT,
+ G_TYPE_BOOLEAN, 2,
GTK_TYPE_MOVEMENT_STEP, G_TYPE_INT);
/**
* GtkFlowBox::select-all:
diff --git a/gtk/gtkflowbox.h b/gtk/gtkflowbox.h
index f15a86a..0b6ad4d 100644
--- a/gtk/gtkflowbox.h
+++ b/gtk/gtkflowbox.h
@@ -61,7 +61,7 @@ struct _GtkFlowBoxClass
void (*selected_children_changed) (GtkFlowBox *box);
void (*activate_cursor_child) (GtkFlowBox *box);
void (*toggle_cursor_child) (GtkFlowBox *box);
- void (*move_cursor) (GtkFlowBox *box,
+ gboolean (*move_cursor) (GtkFlowBox *box,
GtkMovementStep step,
gint count);
void (*select_all) (GtkFlowBox *box);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]