Compare commits

...

6 Commits

Author SHA1 Message Date
Carlos Garnacho
bee92a0fc7 scrolledwindow: Handle ::request/unset-clear-area calls from children
If the focus area is covered by the area to be cleared, update the
vertical adjustment to keep the focus area visible.
2012-08-04 01:55:02 +02:00
Carlos Garnacho
12d9c93aff entry: Handle GtkIMContext::clear-area 2012-08-04 01:55:02 +02:00
Carlos Garnacho
475220e733 textview: Handle GtkIMContext::clear-area 2012-08-04 01:55:02 +02:00
Carlos Garnacho
92a670df86 widget: Add API to request/unset the area to be covered by an OSK
The requests are emitted by the focus widget controlled by an GtkIMContext,
and spread up the hierarchy till the toplevel. whenever a widget handles
the request, emission is stopped, being that same widget responsible of
handling the unset request.
2012-08-04 01:55:01 +02:00
Carlos Garnacho
d8c0a1e28e im: Forward the slave's ::clear-area signal in GtkIMMultiContext 2012-08-04 01:55:01 +02:00
Carlos Garnacho
92083238a3 im: Add GtkIMContext::clear-area signal
This signal may be emitted by on-screen-keyboard input methods
to request the UI to clear the monitor area covered by the
keyboard to avoid the focus to stay below it.
2012-08-04 01:55:01 +02:00
7 changed files with 224 additions and 1 deletions

View File

@@ -501,6 +501,10 @@ static gboolean gtk_entry_delete_surrounding_cb (GtkIMContext *context,
gint offset,
gint n_chars,
GtkEntry *entry);
static void gtk_entry_clear_area_cb (GtkIMContext *context,
cairo_rectangle_int_t *clear_area,
cairo_rectangle_int_t *cursor_rect,
GtkEntry *entry);
/* Internal routines
*/
@@ -2488,6 +2492,8 @@ gtk_entry_init (GtkEntry *entry)
G_CALLBACK (gtk_entry_retrieve_surrounding_cb), entry);
g_signal_connect (priv->im_context, "delete-surrounding",
G_CALLBACK (gtk_entry_delete_surrounding_cb), entry);
g_signal_connect (priv->im_context, "clear-area",
G_CALLBACK (gtk_entry_clear_area_cb), entry);
context = gtk_widget_get_style_context (GTK_WIDGET (entry));
gtk_style_context_add_class (context, GTK_STYLE_CLASS_ENTRY);
@@ -5404,6 +5410,25 @@ gtk_entry_delete_surrounding_cb (GtkIMContext *slave,
return TRUE;
}
static void
gtk_entry_clear_area_cb (GtkIMContext *context,
cairo_rectangle_int_t *clear_area,
cairo_rectangle_int_t *cursor_rect,
GtkEntry *entry)
{
GtkEntryPrivate *priv = entry->priv;
GtkWidget *widget;
if (!priv->editable)
return;
widget = GTK_WIDGET (entry);
gtk_widget_unset_clear_area (widget, TRUE);
if (clear_area->width != 0 && clear_area->height != 0)
gtk_widget_request_clear_area (widget, clear_area, cursor_rect);
}
/* Internal functions
*/

View File

@@ -104,6 +104,7 @@ enum {
COMMIT,
RETRIEVE_SURROUNDING,
DELETE_SURROUNDING,
CLEAR_AREA,
LAST_SIGNAL
};
@@ -297,6 +298,15 @@ gtk_im_context_class_init (GtkIMContextClass *klass)
G_TYPE_BOOLEAN, 2,
G_TYPE_INT,
G_TYPE_INT);
im_context_signals[CLEAR_AREA] =
g_signal_new (I_("clear-area"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
NULL, NULL, NULL,
_gtk_marshal_VOID__BOXED_BOXED,
G_TYPE_NONE, 2,
GDK_TYPE_RECTANGLE, GDK_TYPE_RECTANGLE);
}
static void

View File

@@ -99,6 +99,9 @@ static gboolean gtk_im_multicontext_delete_surrounding_cb (GtkIMContext *
gint offset,
gint n_chars,
GtkIMMulticontext *multicontext);
static void gtk_im_multicontext_clear_area_cb (GtkIMContext *slave,
GdkRectangle *rect,
GtkIMMulticontext *multicontext);
static const gchar *global_context_id = NULL;
@@ -223,6 +226,9 @@ gtk_im_multicontext_set_slave (GtkIMMulticontext *multicontext,
g_signal_connect (priv->slave, "delete-surrounding",
G_CALLBACK (gtk_im_multicontext_delete_surrounding_cb),
multicontext);
g_signal_connect (priv->slave, "clear-area",
G_CALLBACK (gtk_im_multicontext_clear_area_cb),
multicontext);
if (!priv->use_preedit) /* Default is TRUE */
gtk_im_context_set_use_preedit (slave, FALSE);
@@ -544,6 +550,14 @@ gtk_im_multicontext_delete_surrounding_cb (GtkIMContext *slave,
return result;
}
static void
gtk_im_multicontext_clear_area_cb (GtkIMContext *slave,
GdkRectangle *rect,
GtkIMMulticontext *multicontext)
{
g_signal_emit_by_name (multicontext, "clear-area", rect);
}
static void
activate_cb (GtkWidget *menuitem,
GtkIMMulticontext *context)

View File

@@ -175,6 +175,7 @@ struct _GtkScrolledWindowPrivate
gdouble unclamped_hadj_value;
gdouble unclamped_vadj_value;
gdouble clear_area_dy;
};
typedef struct
@@ -282,6 +283,13 @@ static gboolean _gtk_scrolled_window_set_adjustment_value (GtkScrolledWindo
gdouble value,
gboolean allow_overshooting,
gboolean snap_to_border);
static gboolean gtk_scrolled_window_request_clear_area (GtkWidget *widget,
cairo_rectangle_int_t *clear_area,
cairo_rectangle_int_t *cursor_area,
gpointer user_data);
static gboolean gtk_scrolled_window_unset_clear_area (GtkWidget *widget,
gboolean snap_back,
gpointer user_data);
static guint signals[LAST_SIGNAL] = {0};
@@ -593,9 +601,17 @@ gtk_scrolled_window_init (GtkScrolledWindow *scrolled_window)
gtk_scrolled_window_update_real_placement (scrolled_window);
priv->min_content_width = -1;
priv->min_content_height = -1;
priv->clear_area_dy = 0;
gtk_scrolled_window_set_kinetic_scrolling (scrolled_window, TRUE);
gtk_scrolled_window_set_capture_button_press (scrolled_window, TRUE);
g_signal_connect (scrolled_window, "request-clear-area",
G_CALLBACK (gtk_scrolled_window_request_clear_area),
NULL);
g_signal_connect (scrolled_window, "unset-clear-area",
G_CALLBACK (gtk_scrolled_window_unset_clear_area),
NULL);
}
/**
@@ -2379,7 +2395,11 @@ _gtk_scrolled_window_set_adjustment_value (GtkScrolledWindow *scrolled_window,
if (adjustment == gtk_range_get_adjustment (GTK_RANGE (priv->hscrollbar)))
prev_value = &priv->unclamped_hadj_value;
else if (adjustment == gtk_range_get_adjustment (GTK_RANGE (priv->vscrollbar)))
prev_value = &priv->unclamped_vadj_value;
{
if (!snap_to_border)
upper += priv->clear_area_dy;
prev_value = &priv->unclamped_vadj_value;
}
else
return FALSE;
@@ -3476,6 +3496,60 @@ gtk_scrolled_window_grab_notify (GtkWidget *widget,
}
}
static gboolean
gtk_scrolled_window_request_clear_area (GtkWidget *widget,
cairo_rectangle_int_t *cursor_area,
cairo_rectangle_int_t *clear_area,
gpointer user_data)
{
GtkScrolledWindowPrivate *priv;
GtkAdjustment *adjustment;
gdouble value;
priv = GTK_SCROLLED_WINDOW (widget)->priv;
adjustment = gtk_range_get_adjustment (GTK_RANGE (priv->vscrollbar));
value = priv->unclamped_vadj_value;
priv->clear_area_dy = cursor_area->y + cursor_area->height - clear_area->y;
value = priv->unclamped_vadj_value + priv->clear_area_dy;
_gtk_scrolled_window_set_adjustment_value (GTK_SCROLLED_WINDOW (widget),
adjustment, value,
FALSE, FALSE);
return TRUE;
}
static gboolean
gtk_scrolled_window_unset_clear_area (GtkWidget *widget,
gboolean snap_back,
gpointer user_data)
{
GtkScrolledWindowPrivate *priv;
priv = GTK_SCROLLED_WINDOW (widget)->priv;
if (priv->clear_area_dy != 0)
{
if (snap_back)
{
GtkAdjustment *adjustment;
gdouble value;
adjustment = gtk_range_get_adjustment (GTK_RANGE (priv->vscrollbar));
value = priv->unclamped_vadj_value - priv->clear_area_dy;
_gtk_scrolled_window_set_adjustment_value (GTK_SCROLLED_WINDOW (widget),
adjustment, value,
FALSE, FALSE);
}
priv->clear_area_dy = 0;
return TRUE;
}
return FALSE;
}
/**
* gtk_scrolled_window_get_min_content_width:
* @scrolled_window: a #GtkScrolledWindow

View File

@@ -194,6 +194,8 @@ struct _GtkTextViewPrivate
GtkTextPendingScroll *pending_scroll;
gint osk_dy;
/* Default style settings */
gint pixels_above_lines;
gint pixels_below_lines;
@@ -441,6 +443,10 @@ static gboolean gtk_text_view_delete_surrounding_handler (GtkIMContext *conte
gint offset,
gint n_chars,
GtkTextView *text_view);
static void gtk_text_view_clear_area_handler (GtkIMContext *context,
GdkRectangle *clear_area,
GdkRectangle *cursor_area,
GtkTextView *text_view);
static void gtk_text_view_mark_set_handler (GtkTextBuffer *buffer,
const GtkTextIter *location,
@@ -1403,6 +1409,8 @@ gtk_text_view_init (GtkTextView *text_view)
G_CALLBACK (gtk_text_view_retrieve_surrounding_handler), text_view);
g_signal_connect (priv->im_context, "delete-surrounding",
G_CALLBACK (gtk_text_view_delete_surrounding_handler), text_view);
g_signal_connect (priv->im_context, "clear-area",
G_CALLBACK (gtk_text_view_clear_area_handler), text_view);
priv->cursor_visible = TRUE;
@@ -7857,6 +7865,21 @@ gtk_text_view_delete_surrounding_handler (GtkIMContext *context,
return TRUE;
}
static void
gtk_text_view_clear_area_handler (GtkIMContext *context,
cairo_rectangle_int_t *clear_area,
cairo_rectangle_int_t *cursor_rect,
GtkTextView *text_view)
{
GtkWidget *widget;
widget = GTK_WIDGET (text_view);
gtk_widget_unset_clear_area (widget, TRUE);
if (clear_area->width != 0 && clear_area->height != 0)
gtk_widget_request_clear_area (widget, clear_area, cursor_rect);
}
static void
gtk_text_view_mark_set_handler (GtkTextBuffer *buffer,
const GtkTextIter *location,

View File

@@ -481,6 +481,8 @@ enum {
DRAG_FAILED,
STYLE_UPDATED,
TOUCH_EVENT,
REQUEST_CLEAR_AREA,
UNSET_CLEAR_AREA,
LAST_SIGNAL
};
@@ -3111,6 +3113,23 @@ gtk_widget_class_init (GtkWidgetClass *klass)
_gtk_marshal_BOOLEAN__UINT,
G_TYPE_BOOLEAN, 1, G_TYPE_UINT);
widget_signals[REQUEST_CLEAR_AREA] =
g_signal_new (I_("request-clear-area"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST, 0,
g_signal_accumulator_true_handled, NULL,
_gtk_marshal_BOOLEAN__BOXED_BOXED,
G_TYPE_BOOLEAN, 2,
CAIRO_GOBJECT_TYPE_RECTANGLE_INT,
CAIRO_GOBJECT_TYPE_RECTANGLE_INT);
widget_signals[UNSET_CLEAR_AREA] =
g_signal_new (I_("unset-clear-area"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST, 0,
g_signal_accumulator_true_handled, NULL,
_gtk_marshal_BOOLEAN__BOOLEAN,
G_TYPE_BOOLEAN, 1, G_TYPE_BOOLEAN);
binding_set = gtk_binding_set_by_class (klass);
gtk_binding_entry_add_signal (binding_set, GDK_KEY_F10, GDK_SHIFT_MASK,
"popup-menu", 0);
@@ -14072,3 +14091,56 @@ _gtk_widget_set_style (GtkWidget *widget,
{
widget->priv->style = style;
}
gboolean
gtk_widget_request_clear_area (GtkWidget *widget,
cairo_rectangle_int_t *clear_area,
cairo_rectangle_int_t *cursor_position)
{
gboolean handled = FALSE;
GtkWidget *cur;
g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
g_return_val_if_fail (cursor_position != NULL, FALSE);
g_return_val_if_fail (clear_area != NULL, FALSE);
if (cursor_position->x < clear_area->x - cursor_position->width ||
cursor_position->x >= clear_area->x + clear_area->width ||
cursor_position->y < clear_area->y - cursor_position->height ||
cursor_position->y >= clear_area->y + clear_area->height)
return FALSE;
cur = widget;
while (!handled && cur)
{
g_signal_emit (cur, widget_signals[REQUEST_CLEAR_AREA], 0,
cursor_position, clear_area, &handled);
if (!handled)
cur = gtk_widget_get_parent (cur);
}
return handled;
}
gboolean
gtk_widget_unset_clear_area (GtkWidget *widget,
gboolean snap_back)
{
gboolean handled = FALSE;
GtkWidget *cur;
cur = widget;
while (!handled && cur)
{
g_signal_emit (cur, widget_signals[UNSET_CLEAR_AREA], 0,
snap_back, &handled);
if (!handled)
cur = gtk_widget_get_parent (cur);
}
return handled;
}

View File

@@ -886,6 +886,11 @@ GDK_AVAILABLE_IN_3_4
GdkModifierType gtk_widget_get_modifier_mask (GtkWidget *widget,
GdkModifierIntent intent);
gboolean gtk_widget_request_clear_area (GtkWidget *widget,
cairo_rectangle_int_t *clear_area,
cairo_rectangle_int_t *cursor_position);
gboolean gtk_widget_unset_clear_area (GtkWidget *widget,
gboolean snap_back);
G_END_DECLS