X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtkentry.c;h=b344349c6033f82b2b41e8390659e5a8f3a58a45;hb=28cc7baef0c2f4e80113395a48e562e427211f03;hp=4b0d1cade4061d931470bafaf35b95087a71642a;hpb=27bc88f7c2269ac750504c7fe6c7c02c43183149;p=~andy%2Fgtk diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c index 4b0d1cade..b344349c6 100644 --- a/gtk/gtkentry.c +++ b/gtk/gtkentry.c @@ -53,7 +53,6 @@ #include "gtkseparatormenuitem.h" #include "gtkselection.h" #include "gtksettings.h" -#include "gtksizerequest.h" #include "gtkspinbutton.h" #include "gtkstock.h" #include "gtktextutil.h" @@ -67,6 +66,51 @@ #include "gtkiconfactory.h" #include "gtkicontheme.h" + +/** + * SECTION:gtkentry + * @Short_description: A single line text entry field + * @Title: GtkEntry + * @See_also: #GtkTextView, #GtkEntryCompletion + * + * The #GtkEntry widget is a single line text entry + * widget. A fairly large set of key bindings are supported + * by default. If the entered text is longer than the allocation + * of the widget, the widget will scroll so that the cursor + * position is visible. + * + * When using an entry for passwords and other sensitive information, + * it can be put into "password mode" using gtk_entry_set_visibility(). + * In this mode, entered text is displayed using a 'invisible' character. + * By default, GTK+ picks the best invisible character that is available + * in the current font, but it can be changed with + * gtk_entry_set_invisible_char(). Since 2.16, GTK+ displays a warning + * when Caps Lock or input methods might interfere with entering text in + * a password entry. The warning can be turned off with the + * #GtkEntry:caps-lock-warning property. + * + * Since 2.16, GtkEntry has the ability to display progress or activity + * information behind the text. To make an entry display such information, + * use gtk_entry_set_progress_fraction() or gtk_entry_set_progress_pulse_step(). + * + * Additionally, GtkEntry can show icons at either side of the entry. These + * icons can be activatable by clicking, can be set up as drag source and + * can have tooltips. To add an icon, use gtk_entry_set_icon_from_gicon() or + * one of the various other functions that set an icon from a stock id, an + * icon name or a pixbuf. To trigger an action when the user clicks an icon, + * connect to the #GtkEntry::icon-press signal. To allow DND operations + * from an icon, use gtk_entry_set_icon_drag_source(). To set a tooltip on + * an icon, use gtk_entry_set_icon_tooltip_text() or the corresponding function + * for markup. + * + * Note that functionality or information that is only available by clicking + * on an icon in an entry may not be accessible at all to users which are not + * able to use a mouse or other pointing device. It is therefore recommended + * that any such functionality should also be available by other means, e.g. + * via the context menu of the entry. + */ + + #define GTK_ENTRY_COMPLETION_KEY "gtk-entry-completion-key" #define MIN_ENTRY_WIDTH 150 @@ -86,11 +130,89 @@ static GQuark quark_password_hint = 0; static GQuark quark_cursor_hadjustment = 0; static GQuark quark_capslock_feedback = 0; -typedef struct _GtkEntryPrivate GtkEntryPrivate; +typedef struct _EntryIconInfo EntryIconInfo; +typedef struct _GtkEntryPasswordHint GtkEntryPasswordHint; +typedef struct _GtkEntryCapslockFeedback GtkEntryCapslockFeedback; -#define GTK_ENTRY_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_ENTRY, GtkEntryPrivate)) +struct _GtkEntryPrivate +{ + EntryIconInfo *icons[MAX_ICONS]; + + GtkEntryBuffer *buffer; + GtkIMContext *im_context; + GtkShadowType shadow_type; + GtkWidget *popup_menu; + + GdkDevice *completion_device; + GdkWindow *text_area; + + PangoLayout *cached_layout; + + gchar *im_module; + + gdouble progress_fraction; + gdouble progress_pulse_fraction; + gdouble progress_pulse_current; + + gfloat xalign; + + gint ascent; /* font ascent in pango units */ + gint current_pos; + gint descent; /* font descent in pango units */ + gint dnd_position; /* In chars, -1 == no DND cursor */ + gint drag_start_x; + gint drag_start_y; + gint focus_width; + gint icon_margin; + gint insert_pos; + gint selection_bound; + gint scroll_offset; + gint start_x; + gint start_y; + gint width_chars; + + gunichar invisible_char; + + guint button; + guint blink_time; /* time in msec the cursor has blinked since last user event */ + guint blink_timeout; + guint recompute_idle; + + guint16 x_text_size; /* allocated size, in bytes */ + guint16 x_n_bytes; /* length in use, in bytes */ + + guint16 preedit_length; /* length of preedit string, in bytes */ + guint16 preedit_cursor; /* offset of cursor within preedit string, in chars */ + + guint editable : 1; + guint in_drag : 1; + guint overwrite_mode : 1; + guint visible : 1; + + guint activates_default : 1; + guint cache_includes_preedit : 1; + guint caps_lock_warning : 1; + guint caps_lock_warning_shown : 1; + guint change_count : 8; + guint cursor_visible : 1; + guint editing_canceled : 1; /* Only used by GtkCellRendererText */ + guint has_frame : 1; + guint in_click : 1; /* Flag so we don't select all when clicking in entry to focus in */ + guint is_cell_renderer : 1; + guint invisible_char_set : 1; + guint interior_focus : 1; + guint mouse_cursor_obscured : 1; + guint need_im_reset : 1; + guint progress_pulse_mode : 1; + guint progress_pulse_way_back : 1; + guint real_changed : 1; + guint resolved_dir : 4; /* PangoDirection */ + guint select_words : 1; + guint select_lines : 1; + guint truncate_multiline : 1; +}; -typedef struct +struct _EntryIconInfo { GdkWindow *window; gchar *tooltip; @@ -108,51 +230,14 @@ typedef struct GtkTargetList *target_list; GdkDragAction actions; -} EntryIconInfo; - -struct _GtkEntryPrivate -{ - GtkEntryBuffer* buffer; - - gfloat xalign; - gint insert_pos; - guint blink_time; /* time in msec the cursor has blinked since last user event */ - guint interior_focus : 1; - guint real_changed : 1; - guint invisible_char_set : 1; - guint caps_lock_warning : 1; - guint caps_lock_warning_shown : 1; - guint change_count : 8; - guint progress_pulse_mode : 1; - guint progress_pulse_way_back : 1; - - gint focus_width; - GtkShadowType shadow_type; - - gdouble progress_fraction; - gdouble progress_pulse_fraction; - gdouble progress_pulse_current; - - EntryIconInfo *icons[MAX_ICONS]; - gint icon_margin; - gint start_x; - gint start_y; - - gchar *im_module; - - GdkDevice *completion_device; }; -typedef struct _GtkEntryPasswordHint GtkEntryPasswordHint; - struct _GtkEntryPasswordHint { gint position; /* Position (in text) of the last password hint */ guint source_id; /* Timeout source id */ }; -typedef struct _GtkEntryCapslockFeedback GtkEntryCapslockFeedback; - struct _GtkEntryCapslockFeedback { GtkWidget *entry; @@ -237,7 +322,7 @@ typedef enum DISPLAY_BLANK /* In invisible mode, nothing shown at all */ } DisplayMode; -/* GObject, GtkObject methods +/* GObject methods */ static void gtk_entry_editable_init (GtkEditableInterface *iface); static void gtk_entry_cell_editable_init (GtkCellEditableIface *iface); @@ -250,25 +335,31 @@ static void gtk_entry_get_property (GObject *object, GValue *value, GParamSpec *pspec); static void gtk_entry_finalize (GObject *object); -static void gtk_entry_destroy (GtkObject *object); static void gtk_entry_dispose (GObject *object); /* GtkWidget methods */ +static void gtk_entry_destroy (GtkWidget *widget); static void gtk_entry_realize (GtkWidget *widget); static void gtk_entry_unrealize (GtkWidget *widget); static void gtk_entry_map (GtkWidget *widget); static void gtk_entry_unmap (GtkWidget *widget); -static void gtk_entry_size_request (GtkWidget *widget, - GtkRequisition *requisition); +static void gtk_entry_get_preferred_width (GtkWidget *widget, + gint *minimum, + gint *natural); +static void gtk_entry_get_preferred_height (GtkWidget *widget, + gint *minimum, + gint *natural); static void gtk_entry_size_allocate (GtkWidget *widget, GtkAllocation *allocation); static void gtk_entry_draw_frame (GtkWidget *widget, - GdkEventExpose *event); + GtkStyleContext *context, + cairo_t *cr); static void gtk_entry_draw_progress (GtkWidget *widget, - GdkEventExpose *event); -static gint gtk_entry_expose (GtkWidget *widget, - GdkEventExpose *event); + GtkStyleContext *context, + cairo_t *cr); +static gint gtk_entry_draw (GtkWidget *widget, + cairo_t *cr); static gint gtk_entry_button_press (GtkWidget *widget, GdkEventButton *event); static gint gtk_entry_button_release (GtkWidget *widget, @@ -288,8 +379,7 @@ static gint gtk_entry_focus_in (GtkWidget *widget, static gint gtk_entry_focus_out (GtkWidget *widget, GdkEventFocus *event); static void gtk_entry_grab_focus (GtkWidget *widget); -static void gtk_entry_style_set (GtkWidget *widget, - GtkStyle *previous_style); +static void gtk_entry_style_updated (GtkWidget *widget); static gboolean gtk_entry_query_tooltip (GtkWidget *widget, gint x, gint y, @@ -297,8 +387,8 @@ static gboolean gtk_entry_query_tooltip (GtkWidget *widget, GtkTooltip *tooltip); static void gtk_entry_direction_changed (GtkWidget *widget, GtkTextDirection previous_dir); -static void gtk_entry_state_changed (GtkWidget *widget, - GtkStateType previous_state); +static void gtk_entry_state_flags_changed (GtkWidget *widget, + GtkStateFlags previous_state); static void gtk_entry_screen_changed (GtkWidget *widget, GdkScreen *old_screen); @@ -416,8 +506,10 @@ static void gtk_entry_enter_text (GtkEntry *entry, static void gtk_entry_set_positions (GtkEntry *entry, gint current_pos, gint selection_bound); -static void gtk_entry_draw_text (GtkEntry *entry); +static void gtk_entry_draw_text (GtkEntry *entry, + cairo_t *cr); static void gtk_entry_draw_cursor (GtkEntry *entry, + cairo_t *cr, CursorType type); static PangoLayout *gtk_entry_ensure_layout (GtkEntry *entry, gboolean include_preedit); @@ -466,7 +558,7 @@ static void get_text_area_size (GtkEntry *entry, gint *y, gint *width, gint *height); -static void get_widget_window_size (GtkEntry *entry, +static void get_frame_size (GtkEntry *entry, gint *x, gint *y, gint *width, @@ -562,24 +654,24 @@ gtk_entry_class_init (GtkEntryClass *class) { GObjectClass *gobject_class = G_OBJECT_CLASS (class); GtkWidgetClass *widget_class; - GtkObjectClass *gtk_object_class; GtkBindingSet *binding_set; widget_class = (GtkWidgetClass*) class; - gtk_object_class = (GtkObjectClass *)class; gobject_class->dispose = gtk_entry_dispose; gobject_class->finalize = gtk_entry_finalize; gobject_class->set_property = gtk_entry_set_property; gobject_class->get_property = gtk_entry_get_property; + widget_class->destroy = gtk_entry_destroy; widget_class->map = gtk_entry_map; widget_class->unmap = gtk_entry_unmap; widget_class->realize = gtk_entry_realize; widget_class->unrealize = gtk_entry_unrealize; - widget_class->size_request = gtk_entry_size_request; + widget_class->get_preferred_width = gtk_entry_get_preferred_width; + widget_class->get_preferred_height = gtk_entry_get_preferred_height; widget_class->size_allocate = gtk_entry_size_allocate; - widget_class->expose_event = gtk_entry_expose; + widget_class->draw = gtk_entry_draw; widget_class->enter_notify_event = gtk_entry_enter_notify; widget_class->leave_notify_event = gtk_entry_leave_notify; widget_class->button_press_event = gtk_entry_button_press; @@ -590,12 +682,12 @@ gtk_entry_class_init (GtkEntryClass *class) widget_class->focus_in_event = gtk_entry_focus_in; widget_class->focus_out_event = gtk_entry_focus_out; widget_class->grab_focus = gtk_entry_grab_focus; - widget_class->style_set = gtk_entry_style_set; + widget_class->style_updated = gtk_entry_style_updated; widget_class->query_tooltip = gtk_entry_query_tooltip; widget_class->drag_begin = gtk_entry_drag_begin; widget_class->drag_end = gtk_entry_drag_end; widget_class->direction_changed = gtk_entry_direction_changed; - widget_class->state_changed = gtk_entry_state_changed; + widget_class->state_flags_changed = gtk_entry_state_flags_changed; widget_class->screen_changed = gtk_entry_screen_changed; widget_class->mnemonic_activate = gtk_entry_mnemonic_activate; @@ -608,8 +700,6 @@ gtk_entry_class_init (GtkEntryClass *class) widget_class->popup_menu = gtk_entry_popup_menu; - gtk_object_class->destroy = gtk_entry_destroy; - class->move_cursor = gtk_entry_move_cursor; class->insert_at_cursor = gtk_entry_insert_at_cursor; class->delete_from_cursor = gtk_entry_delete_from_cursor; @@ -1742,28 +1832,7 @@ gtk_entry_class_init (GtkEntryClass *class) P_("Inner Border"), P_("Border between text and frame."), GTK_TYPE_BORDER, - GTK_PARAM_READABLE)); - - gtk_settings_install_property (g_param_spec_boolean ("gtk-entry-select-on-focus", - P_("Select on focus"), - P_("Whether to select the contents of an entry when it is focused"), - TRUE, - GTK_PARAM_READWRITE)); - - /** - * GtkSettings:gtk-entry-password-hint-timeout: - * - * How long to show the last input character in hidden - * entries. This value is in milliseconds. 0 disables showing the - * last char. 600 is a good value for enabling it. - * - * Since: 2.10 - */ - gtk_settings_install_property (g_param_spec_uint ("gtk-entry-password-hint-timeout", - P_("Password Hint Timeout"), - P_("How long to show the last input character in hidden entries"), - 0, G_MAXUINT, 0, - GTK_PARAM_READWRITE)); + GTK_PARAM_READABLE)); g_type_class_add_private (gobject_class, sizeof (GtkEntryPrivate)); } @@ -1794,8 +1863,8 @@ gtk_entry_set_property (GObject *object, const GValue *value, GParamSpec *pspec) { - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (object); GtkEntry *entry = GTK_ENTRY (object); + GtkEntryPrivate *priv = entry->priv; GtkWidget *widget; switch (prop_id) @@ -1808,24 +1877,24 @@ gtk_entry_set_property (GObject *object, { gboolean new_value = g_value_get_boolean (value); - if (new_value != entry->editable) + if (new_value != priv->editable) { widget = GTK_WIDGET (entry); if (!new_value) { _gtk_entry_reset_im_context (entry); if (gtk_widget_has_focus (widget)) - gtk_im_context_focus_out (entry->im_context); + gtk_im_context_focus_out (priv->im_context); - entry->preedit_length = 0; - entry->preedit_cursor = 0; + priv->preedit_length = 0; + priv->preedit_cursor = 0; } - entry->editable = new_value; + priv->editable = new_value; if (new_value && gtk_widget_has_focus (widget)) - gtk_im_context_focus_in (entry->im_context); - + gtk_im_context_focus_in (priv->im_context); + gtk_entry_queue_draw (entry); } } @@ -1868,7 +1937,7 @@ gtk_entry_set_property (GObject *object, break; case PROP_TRUNCATE_MULTILINE: - entry->truncate_multiline = g_value_get_boolean (value); + priv->truncate_multiline = g_value_get_boolean (value); break; case PROP_SHADOW_TYPE: @@ -1997,12 +2066,12 @@ gtk_entry_set_property (GObject *object, case PROP_IM_MODULE: g_free (priv->im_module); priv->im_module = g_value_dup_string (value); - if (GTK_IS_IM_MULTICONTEXT (entry->im_context)) - gtk_im_multicontext_set_context_id (GTK_IM_MULTICONTEXT (entry->im_context), priv->im_module); + if (GTK_IS_IM_MULTICONTEXT (priv->im_context)) + gtk_im_multicontext_set_context_id (GTK_IM_MULTICONTEXT (priv->im_context), priv->im_module); break; case PROP_EDITING_CANCELED: - entry->editing_canceled = g_value_get_boolean (value); + priv->editing_canceled = g_value_get_boolean (value); break; case PROP_SCROLL_OFFSET: @@ -2019,8 +2088,8 @@ gtk_entry_get_property (GObject *object, GValue *value, GParamSpec *pspec) { - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (object); GtkEntry *entry = GTK_ENTRY (object); + GtkEntryPrivate *priv = entry->priv; switch (prop_id) { @@ -2029,15 +2098,15 @@ gtk_entry_get_property (GObject *object, break; case PROP_CURSOR_POSITION: - g_value_set_int (value, entry->current_pos); + g_value_set_int (value, priv->current_pos); break; case PROP_SELECTION_BOUND: - g_value_set_int (value, entry->selection_bound); + g_value_set_int (value, priv->selection_bound); break; case PROP_EDITABLE: - g_value_set_boolean (value, entry->editable); + g_value_set_boolean (value, priv->editable); break; case PROP_MAX_LENGTH: @@ -2045,11 +2114,11 @@ gtk_entry_get_property (GObject *object, break; case PROP_VISIBILITY: - g_value_set_boolean (value, entry->visible); + g_value_set_boolean (value, priv->visible); break; case PROP_HAS_FRAME: - g_value_set_boolean (value, entry->has_frame); + g_value_set_boolean (value, priv->has_frame); break; case PROP_INNER_BORDER: @@ -2057,19 +2126,19 @@ gtk_entry_get_property (GObject *object, break; case PROP_INVISIBLE_CHAR: - g_value_set_uint (value, entry->invisible_char); + g_value_set_uint (value, priv->invisible_char); break; case PROP_ACTIVATES_DEFAULT: - g_value_set_boolean (value, entry->activates_default); + g_value_set_boolean (value, priv->activates_default); break; case PROP_WIDTH_CHARS: - g_value_set_int (value, entry->width_chars); + g_value_set_int (value, priv->width_chars); break; case PROP_SCROLL_OFFSET: - g_value_set_int (value, entry->scroll_offset); + g_value_set_int (value, priv->scroll_offset); break; case PROP_TEXT: @@ -2081,7 +2150,7 @@ gtk_entry_get_property (GObject *object, break; case PROP_TRUNCATE_MULTILINE: - g_value_set_boolean (value, entry->truncate_multiline); + g_value_set_boolean (value, priv->truncate_multiline); break; case PROP_SHADOW_TYPE: @@ -2089,7 +2158,7 @@ gtk_entry_get_property (GObject *object, break; case PROP_OVERWRITE_MODE: - g_value_set_boolean (value, entry->overwrite_mode); + g_value_set_boolean (value, priv->overwrite_mode); break; case PROP_TEXT_LENGTH: @@ -2218,7 +2287,7 @@ gtk_entry_get_property (GObject *object, case PROP_EDITING_CANCELED: g_value_set_boolean (value, - entry->editing_canceled); + priv->editing_canceled); break; default: @@ -2241,10 +2310,9 @@ find_invisible_char (GtkWidget *widget) 0x273a /* SIXTEEN POINTED ASTERISK */ }; - if (gtk_widget_get_style (widget)) - gtk_widget_style_get (widget, - "invisible-char", &invisible_chars[0], - NULL); + gtk_widget_style_get (widget, + "invisible-char", &invisible_chars[0], + NULL); layout = gtk_widget_create_pango_layout (widget, NULL); @@ -2279,19 +2347,26 @@ find_invisible_char (GtkWidget *widget) static void gtk_entry_init (GtkEntry *entry) { - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry); + GtkStyleContext *context; + GtkEntryPrivate *priv; - gtk_widget_set_can_focus (GTK_WIDGET (entry), TRUE); + entry->priv = G_TYPE_INSTANCE_GET_PRIVATE (entry, + GTK_TYPE_ENTRY, + GtkEntryPrivate); + priv = entry->priv; - entry->editable = TRUE; - entry->visible = TRUE; - entry->invisible_char = find_invisible_char (GTK_WIDGET (entry)); - entry->dnd_position = -1; - entry->width_chars = -1; - entry->is_cell_renderer = FALSE; - entry->editing_canceled = FALSE; - entry->has_frame = TRUE; - entry->truncate_multiline = FALSE; + gtk_widget_set_can_focus (GTK_WIDGET (entry), TRUE); + gtk_widget_set_has_window (GTK_WIDGET (entry), FALSE); + + priv->editable = TRUE; + priv->visible = TRUE; + priv->invisible_char = find_invisible_char (GTK_WIDGET (entry)); + priv->dnd_position = -1; + priv->width_chars = -1; + priv->is_cell_renderer = FALSE; + priv->editing_canceled = FALSE; + priv->has_frame = TRUE; + priv->truncate_multiline = FALSE; priv->shadow_type = GTK_SHADOW_IN; priv->xalign = 0.0; priv->caps_lock_warning = TRUE; @@ -2308,24 +2383,26 @@ gtk_entry_init (GtkEntry *entry) /* This object is completely private. No external entity can gain a reference * to it; so we create it here and destroy it in finalize(). */ - entry->im_context = gtk_im_multicontext_new (); - - g_signal_connect (entry->im_context, "commit", + priv->im_context = gtk_im_multicontext_new (); + + g_signal_connect (priv->im_context, "commit", G_CALLBACK (gtk_entry_commit_cb), entry); - g_signal_connect (entry->im_context, "preedit-changed", + g_signal_connect (priv->im_context, "preedit-changed", G_CALLBACK (gtk_entry_preedit_changed_cb), entry); - g_signal_connect (entry->im_context, "retrieve-surrounding", + g_signal_connect (priv->im_context, "retrieve-surrounding", G_CALLBACK (gtk_entry_retrieve_surrounding_cb), entry); - g_signal_connect (entry->im_context, "delete-surrounding", + g_signal_connect (priv->im_context, "delete-surrounding", G_CALLBACK (gtk_entry_delete_surrounding_cb), entry); + context = gtk_widget_get_style_context (GTK_WIDGET (entry)); + gtk_style_context_add_class (context, GTK_STYLE_CLASS_ENTRY); } static gint get_icon_width (GtkEntry *entry, GtkEntryIconPosition icon_pos) { - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry); + GtkEntryPrivate *priv = entry->priv; EntryIconInfo *icon_info = priv->icons[icon_pos]; GdkScreen *screen; GtkSettings *settings; @@ -2349,7 +2426,7 @@ get_icon_allocations (GtkEntry *entry, GtkAllocation *secondary) { - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry); + GtkEntryPrivate *priv = entry->priv; gint x, y, width, height; get_text_area_size (entry, &x, &y, &width, &height); @@ -2385,7 +2462,7 @@ get_icon_allocations (GtkEntry *entry, static void begin_change (GtkEntry *entry) { - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry); + GtkEntryPrivate *priv = entry->priv; priv->change_count++; } @@ -2394,63 +2471,64 @@ static void end_change (GtkEntry *entry) { GtkEditable *editable = GTK_EDITABLE (entry); - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry); - + GtkEntryPrivate *priv = entry->priv; + g_return_if_fail (priv->change_count > 0); priv->change_count--; if (priv->change_count == 0) { - if (priv->real_changed) + if (priv->real_changed) { g_signal_emit_by_name (editable, "changed"); priv->real_changed = FALSE; } - } + } } static void emit_changed (GtkEntry *entry) { GtkEditable *editable = GTK_EDITABLE (entry); - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry); + GtkEntryPrivate *priv = entry->priv; if (priv->change_count == 0) g_signal_emit_by_name (editable, "changed"); - else + else priv->real_changed = TRUE; } static void -gtk_entry_destroy (GtkObject *object) +gtk_entry_destroy (GtkWidget *widget) { - GtkEntry *entry = GTK_ENTRY (object); + GtkEntry *entry = GTK_ENTRY (widget); + GtkEntryPrivate *priv = entry->priv; - entry->current_pos = entry->selection_bound = 0; + priv->current_pos = priv->selection_bound = 0; _gtk_entry_reset_im_context (entry); gtk_entry_reset_layout (entry); - if (entry->blink_timeout) + if (priv->blink_timeout) { - g_source_remove (entry->blink_timeout); - entry->blink_timeout = 0; + g_source_remove (priv->blink_timeout); + priv->blink_timeout = 0; } - if (entry->recompute_idle) + if (priv->recompute_idle) { - g_source_remove (entry->recompute_idle); - entry->recompute_idle = 0; + g_source_remove (priv->recompute_idle); + priv->recompute_idle = 0; } - GTK_OBJECT_CLASS (gtk_entry_parent_class)->destroy (object); + GTK_WIDGET_CLASS (gtk_entry_parent_class)->destroy (widget); } static void gtk_entry_dispose (GObject *object) { GtkEntry *entry = GTK_ENTRY (object); - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry); + GtkEntryPrivate *priv = entry->priv; gtk_entry_set_icon_from_pixbuf (entry, GTK_ENTRY_ICON_PRIMARY, NULL); gtk_entry_set_icon_tooltip_markup (entry, GTK_ENTRY_ICON_PRIMARY, NULL); @@ -2471,7 +2549,7 @@ static void gtk_entry_finalize (GObject *object) { GtkEntry *entry = GTK_ENTRY (object); - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry); + GtkEntryPrivate *priv = entry->priv; EntryIconInfo *icon_info = NULL; gint i; @@ -2492,16 +2570,16 @@ gtk_entry_finalize (GObject *object) gtk_entry_set_completion (entry, NULL); - if (entry->cached_layout) - g_object_unref (entry->cached_layout); + if (priv->cached_layout) + g_object_unref (priv->cached_layout); - g_object_unref (entry->im_context); + g_object_unref (priv->im_context); - if (entry->blink_timeout) - g_source_remove (entry->blink_timeout); + if (priv->blink_timeout) + g_source_remove (priv->blink_timeout); - if (entry->recompute_idle) - g_source_remove (entry->recompute_idle); + if (priv->recompute_idle) + g_source_remove (priv->recompute_idle); g_free (priv->im_module); @@ -2511,12 +2589,14 @@ gtk_entry_finalize (GObject *object) static DisplayMode gtk_entry_get_display_mode (GtkEntry *entry) { - GtkEntryPrivate *priv; - if (entry->visible) + GtkEntryPrivate *priv = entry->priv; + + if (priv->visible) return DISPLAY_NORMAL; - priv = GTK_ENTRY_GET_PRIVATE (entry); - if (entry->invisible_char == 0 && priv->invisible_char_set) + + if (priv->invisible_char == 0 && priv->invisible_char_set) return DISPLAY_BLANK; + return DISPLAY_INVISIBLE; } @@ -2537,7 +2617,7 @@ gtk_entry_get_display_text (GtkEntry *entry, guint length; gint i; - priv = GTK_ENTRY_GET_PRIVATE (entry); + priv = entry->priv; text = gtk_entry_buffer_get_text (get_buffer (entry)); length = gtk_entry_buffer_get_length (get_buffer (entry)); @@ -2548,7 +2628,7 @@ gtk_entry_get_display_text (GtkEntry *entry, if (end_pos <= start_pos) return g_strdup (""); - else if (entry->visible) + else if (priv->visible) { start = g_utf8_offset_to_pointer (text, start_pos); end = g_utf8_offset_to_pointer (start, end_pos - start_pos); @@ -2559,10 +2639,10 @@ gtk_entry_get_display_text (GtkEntry *entry, str = g_string_sized_new (length * 2); /* Figure out what our invisible char is and encode it */ - if (!entry->invisible_char) + if (!priv->invisible_char) invisible_char = priv->invisible_char_set ? ' ' : '*'; else - invisible_char = entry->invisible_char; + invisible_char = priv->invisible_char; char_len = g_unichar_to_utf8 (invisible_char, char_str); /* @@ -2593,7 +2673,8 @@ gtk_entry_get_display_text (GtkEntry *entry, static void update_cursors (GtkWidget *widget) { - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (widget); + GtkEntry *entry = GTK_ENTRY (widget); + GtkEntryPrivate *priv = entry->priv; EntryIconInfo *icon_info = NULL; GdkDisplay *display; GdkCursor *cursor; @@ -2632,7 +2713,8 @@ static void realize_icon_info (GtkWidget *widget, GtkEntryIconPosition icon_pos) { - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (widget); + GtkEntry *entry = GTK_ENTRY (widget); + GtkEntryPrivate *priv = entry->priv; EntryIconInfo *icon_info = priv->icons[icon_pos]; GdkWindowAttr attributes; gint attributes_mask; @@ -2644,12 +2726,9 @@ realize_icon_info (GtkWidget *widget, attributes.width = 1; attributes.height = 1; attributes.window_type = GDK_WINDOW_CHILD; - attributes.wclass = GDK_INPUT_OUTPUT; - attributes.visual = gtk_widget_get_visual (widget); - attributes.colormap = gtk_widget_get_colormap (widget); + attributes.wclass = GDK_INPUT_ONLY; attributes.event_mask = gtk_widget_get_events (widget); - attributes.event_mask |= (GDK_EXPOSURE_MASK | - GDK_BUTTON_PRESS_MASK | + attributes.event_mask |= (GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_BUTTON1_MOTION_MASK | GDK_BUTTON3_MOTION_MASK | @@ -2657,14 +2736,12 @@ realize_icon_info (GtkWidget *widget, GDK_POINTER_MOTION_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK); - attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; + attributes_mask = GDK_WA_X | GDK_WA_Y; icon_info->window = gdk_window_new (gtk_widget_get_window (widget), &attributes, attributes_mask); gdk_window_set_user_data (icon_info->window, widget); - gdk_window_set_background (icon_info->window, - >k_widget_get_style (widget)->base[gtk_widget_get_state (widget)]); gtk_widget_queue_resize (widget); } @@ -2673,7 +2750,8 @@ static EntryIconInfo* construct_icon_info (GtkWidget *widget, GtkEntryIconPosition icon_pos) { - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (widget); + GtkEntry *entry = GTK_ENTRY (widget); + GtkEntryPrivate *priv = entry->priv; EntryIconInfo *icon_info; g_return_val_if_fail (priv->icons[icon_pos] == NULL, NULL); @@ -2690,12 +2768,15 @@ construct_icon_info (GtkWidget *widget, static void gtk_entry_map (GtkWidget *widget) { - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (widget); + GtkEntry *entry = GTK_ENTRY (widget); + GtkEntryPrivate *priv = entry->priv; EntryIconInfo *icon_info = NULL; gint i; GTK_WIDGET_CLASS (gtk_entry_parent_class)->map (widget); + gdk_window_show (priv->text_area); + for (i = 0; i < MAX_ICONS; i++) { if ((icon_info = priv->icons[i]) != NULL) @@ -2711,7 +2792,8 @@ gtk_entry_map (GtkWidget *widget) static void gtk_entry_unmap (GtkWidget *widget) { - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (widget); + GtkEntry *entry = GTK_ENTRY (widget); + GtkEntryPrivate *priv = entry->priv; EntryIconInfo *icon_info = NULL; gint i; @@ -2724,6 +2806,8 @@ gtk_entry_unmap (GtkWidget *widget) } } + gdk_window_hide (priv->text_area); + GTK_WIDGET_CLASS (gtk_entry_parent_class)->unmap (widget); } @@ -2732,28 +2816,25 @@ gtk_entry_realize (GtkWidget *widget) { GtkEntry *entry; GtkEntryPrivate *priv; - GtkStateType state; - GtkStyle *style; EntryIconInfo *icon_info; GdkWindow *window; GdkWindowAttr attributes; gint attributes_mask; + gint frame_x, frame_y; int i; gtk_widget_set_realized (widget, TRUE); + window = gtk_widget_get_parent_window (widget); + gtk_widget_set_window (widget, window); + g_object_ref (window); + entry = GTK_ENTRY (widget); - priv = GTK_ENTRY_GET_PRIVATE (entry); + priv = entry->priv; attributes.window_type = GDK_WINDOW_CHILD; - - get_widget_window_size (entry, &attributes.x, &attributes.y, &attributes.width, &attributes.height); - - attributes.wclass = GDK_INPUT_OUTPUT; - attributes.visual = gtk_widget_get_visual (widget); - attributes.colormap = gtk_widget_get_colormap (widget); + attributes.wclass = GDK_INPUT_ONLY; attributes.event_mask = gtk_widget_get_events (widget); - attributes.event_mask |= (GDK_EXPOSURE_MASK | - GDK_BUTTON_PRESS_MASK | + attributes.event_mask |= (GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_BUTTON1_MOTION_MASK | GDK_BUTTON3_MOTION_MASK | @@ -2761,37 +2842,32 @@ gtk_entry_realize (GtkWidget *widget) GDK_POINTER_MOTION_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK); - attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; - - window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask); - gtk_widget_set_window (widget, window); - gdk_window_set_user_data (window, entry); + attributes_mask = GDK_WA_X | GDK_WA_Y; get_text_area_size (entry, &attributes.x, &attributes.y, &attributes.width, &attributes.height); - + + get_frame_size (entry, &frame_x, &frame_y, NULL, NULL); + attributes.x += frame_x; + attributes.y += frame_y; + if (gtk_widget_is_sensitive (widget)) { attributes.cursor = gdk_cursor_new_for_display (gtk_widget_get_display (widget), GDK_XTERM); attributes_mask |= GDK_WA_CURSOR; } - entry->text_area = gdk_window_new (window, &attributes, attributes_mask); + priv->text_area = gdk_window_new (gtk_widget_get_window (widget), + &attributes, + attributes_mask); - gdk_window_set_user_data (entry->text_area, entry); + gdk_window_set_user_data (priv->text_area, entry); if (attributes_mask & GDK_WA_CURSOR) gdk_cursor_unref (attributes.cursor); gtk_widget_style_attach (widget); - style = gtk_widget_get_style (widget); - state = gtk_widget_get_state (widget); - gdk_window_set_background (window, &style->base[state]); - gdk_window_set_background (entry->text_area, &style->base[state]); - - gdk_window_show (entry->text_area); - - gtk_im_context_set_client_window (entry->im_context, entry->text_area); + gtk_im_context_set_client_window (priv->im_context, priv->text_area); gtk_entry_adjust_scroll (entry); gtk_entry_update_primary_selection (entry); @@ -2815,30 +2891,30 @@ static void gtk_entry_unrealize (GtkWidget *widget) { GtkEntry *entry = GTK_ENTRY (widget); - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry); + GtkEntryPrivate *priv = entry->priv; GtkClipboard *clipboard; EntryIconInfo *icon_info; gint i; gtk_entry_reset_layout (entry); - gtk_im_context_set_client_window (entry->im_context, NULL); + gtk_im_context_set_client_window (priv->im_context, NULL); clipboard = gtk_widget_get_clipboard (widget, GDK_SELECTION_PRIMARY); if (gtk_clipboard_get_owner (clipboard) == G_OBJECT (entry)) gtk_clipboard_clear (clipboard); - if (entry->text_area) + if (priv->text_area) { - gdk_window_set_user_data (entry->text_area, NULL); - gdk_window_destroy (entry->text_area); - entry->text_area = NULL; + gdk_window_set_user_data (priv->text_area, NULL); + gdk_window_destroy (priv->text_area); + priv->text_area = NULL; } - if (entry->popup_menu) + if (priv->popup_menu) { - gtk_widget_destroy (entry->popup_menu); - entry->popup_menu = NULL; + gtk_widget_destroy (priv->popup_menu); + priv->popup_menu = NULL; } GTK_WIDGET_CLASS (gtk_entry_parent_class)->unrealize (widget); @@ -2861,16 +2937,19 @@ _gtk_entry_get_borders (GtkEntry *entry, gint *xborder, gint *yborder) { + GtkEntryPrivate *priv = entry->priv; GtkWidget *widget = GTK_WIDGET (entry); - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (widget); - GtkStyle *style; - if (entry->has_frame) + if (priv->has_frame) { - style = gtk_widget_get_style (widget); + GtkStyleContext *context; + GtkBorder padding; - *xborder = style->xthickness; - *yborder = style->ythickness; + context = gtk_widget_get_style_context (widget); + gtk_style_context_get_padding (context, 0, &padding); + + *xborder = padding.left; + *yborder = padding.top; } else { @@ -2886,42 +2965,45 @@ _gtk_entry_get_borders (GtkEntry *entry, } static void -gtk_entry_size_request (GtkWidget *widget, - GtkRequisition *requisition) +gtk_entry_get_preferred_width (GtkWidget *widget, + gint *minimum, + gint *natural) { GtkEntry *entry = GTK_ENTRY (widget); - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry); + GtkEntryPrivate *priv = entry->priv; PangoFontMetrics *metrics; gint xborder, yborder; GtkBorder inner_border; PangoContext *context; - int icon_widths = 0; - int icon_width, i; - + GtkStyleContext *style_context; + GtkStateFlags state; + gint icon_widths = 0; + gint icon_width, i; + gint width; + gtk_widget_ensure_style (widget); context = gtk_widget_get_pango_context (widget); + + style_context = gtk_widget_get_style_context (widget); + state = gtk_widget_get_state_flags (widget); + metrics = pango_context_get_metrics (context, - gtk_widget_get_style (widget)->font_desc, - pango_context_get_language (context)); + gtk_style_context_get_font (style_context, state), + pango_context_get_language (context)); - entry->ascent = pango_font_metrics_get_ascent (metrics); - entry->descent = pango_font_metrics_get_descent (metrics); - _gtk_entry_get_borders (entry, &xborder, &yborder); _gtk_entry_effective_inner_border (entry, &inner_border); - if (entry->width_chars < 0) - requisition->width = MIN_ENTRY_WIDTH + xborder * 2 + inner_border.left + inner_border.right; + if (priv->width_chars < 0) + width = MIN_ENTRY_WIDTH + xborder * 2 + inner_border.left + inner_border.right; else { gint char_width = pango_font_metrics_get_approximate_char_width (metrics); gint digit_width = pango_font_metrics_get_approximate_digit_width (metrics); gint char_pixels = (MAX (char_width, digit_width) + PANGO_SCALE - 1) / PANGO_SCALE; - - requisition->width = char_pixels * entry->width_chars + xborder * 2 + inner_border.left + inner_border.right; + + width = char_pixels * priv->width_chars + xborder * 2 + inner_border.left + inner_border.right; } - - requisition->height = PANGO_PIXELS (entry->ascent + entry->descent) + yborder * 2 + inner_border.top + inner_border.bottom; for (i = 0; i < MAX_ICONS; i++) { @@ -2930,22 +3012,66 @@ gtk_entry_size_request (GtkWidget *widget, icon_widths += icon_width + 2 * priv->icon_margin; } - if (icon_widths > requisition->width) - requisition->width += icon_widths; + if (icon_widths > width) + width += icon_widths; pango_font_metrics_unref (metrics); + + *minimum = width; + *natural = width; +} + +static void +gtk_entry_get_preferred_height (GtkWidget *widget, + gint *minimum, + gint *natural) +{ + GtkEntry *entry = GTK_ENTRY (widget); + GtkEntryPrivate *priv = entry->priv; + PangoFontMetrics *metrics; + gint xborder, yborder; + GtkBorder inner_border; + GtkStyleContext *style_context; + GtkStateFlags state; + PangoContext *context; + gint height; + + gtk_widget_ensure_style (widget); + context = gtk_widget_get_pango_context (widget); + + style_context = gtk_widget_get_style_context (widget); + state = gtk_widget_get_state_flags (widget); + + metrics = pango_context_get_metrics (context, + gtk_style_context_get_font (style_context, state), + pango_context_get_language (context)); + + priv->ascent = pango_font_metrics_get_ascent (metrics); + priv->descent = pango_font_metrics_get_descent (metrics); + + _gtk_entry_get_borders (entry, &xborder, &yborder); + _gtk_entry_effective_inner_border (entry, &inner_border); + + height = PANGO_PIXELS (priv->ascent + priv->descent) + yborder * 2 + inner_border.top + inner_border.bottom; + + pango_font_metrics_unref (metrics); + + *minimum = height; + *natural = height; } static void place_windows (GtkEntry *entry) { GtkWidget *widget = GTK_WIDGET (entry); - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry); + GtkEntryPrivate *priv = entry->priv; gint x, y, width, height; + gint frame_x, frame_y; GtkAllocation primary; GtkAllocation secondary; EntryIconInfo *icon_info = NULL; + get_frame_size (entry, &frame_x, &frame_y, NULL, NULL); get_text_area_size (entry, &x, &y, &width, &height); get_icon_allocations (entry, &primary, &secondary); @@ -2958,6 +3084,13 @@ place_windows (GtkEntry *entry) x += primary.width; width -= primary.width + secondary.width; + x += frame_x; + y += frame_y; + primary.x += frame_x; + primary.y += frame_y; + secondary.x += frame_x; + secondary.y += frame_y; + if ((icon_info = priv->icons[GTK_ENTRY_ICON_PRIMARY]) != NULL) gdk_window_move_resize (icon_info->window, primary.x, primary.y, @@ -2968,7 +3101,7 @@ place_windows (GtkEntry *entry) secondary.x, secondary.y, secondary.width, secondary.height); - gdk_window_move_resize (entry->text_area, x, y, width, height); + gdk_window_move_resize (priv->text_area, x, y, width, height); } static void @@ -2978,20 +3111,19 @@ gtk_entry_get_text_area_size (GtkEntry *entry, gint *width, gint *height) { + GtkEntryPrivate *priv = entry->priv; GtkWidget *widget = GTK_WIDGET (entry); - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (widget); GtkAllocation allocation; GtkRequisition requisition; gint frame_height; gint xborder, yborder; - gtk_size_request_get_size (GTK_SIZE_REQUEST (widget), - &requisition, NULL); + gtk_widget_get_preferred_size (widget, &requisition, NULL); gtk_widget_get_allocation (widget, &allocation); _gtk_entry_get_borders (entry, &xborder, &yborder); if (gtk_widget_get_realized (widget)) - gdk_drawable_get_size (gtk_widget_get_window (widget), NULL, &frame_height); + get_frame_size (entry, NULL, NULL, NULL, &frame_height); else frame_height = requisition.height; @@ -3030,18 +3162,18 @@ get_text_area_size (GtkEntry *entry, static void -get_widget_window_size (GtkEntry *entry, - gint *x, - gint *y, - gint *width, - gint *height) +get_frame_size (GtkEntry *entry, + gint *x, + gint *y, + gint *width, + gint *height) { + GtkEntryPrivate *priv = entry->priv; GtkAllocation allocation; GtkRequisition requisition; GtkWidget *widget = GTK_WIDGET (entry); - gtk_size_request_get_size (GTK_SIZE_REQUEST (widget), - &requisition, NULL); + gtk_widget_get_preferred_size (widget, &requisition, NULL); gtk_widget_get_allocation (widget, &allocation); if (x) @@ -3049,7 +3181,7 @@ get_widget_window_size (GtkEntry *entry, if (y) { - if (entry->is_cell_renderer) + if (priv->is_cell_renderer) *y = allocation.y; else *y = allocation.y + (allocation.height - requisition.height) / 2; @@ -3060,7 +3192,7 @@ get_widget_window_size (GtkEntry *entry, if (height) { - if (entry->is_cell_renderer) + if (priv->is_cell_renderer) *height = allocation.height; else *height = requisition.height; @@ -3103,13 +3235,8 @@ gtk_entry_size_allocate (GtkWidget *widget, if (gtk_widget_get_realized (widget)) { - gint x, y, width, height; GtkEntryCompletion* completion; - get_widget_window_size (entry, &x, &y, &width, &height); - gdk_window_move_resize (gtk_widget_get_window (widget), - x, y, width, height); - place_windows (entry); gtk_entry_recompute (entry); @@ -3172,7 +3299,7 @@ static gboolean should_prelight (GtkEntry *entry, GtkEntryIconPosition icon_pos) { - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry); + GtkEntryPrivate *priv = entry->priv; EntryIconInfo *icon_info = priv->icons[icon_pos]; gboolean prelight; @@ -3194,14 +3321,14 @@ should_prelight (GtkEntry *entry, static void draw_icon (GtkWidget *widget, + cairo_t *cr, GtkEntryIconPosition icon_pos) { GtkEntry *entry = GTK_ENTRY (widget); - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry); + GtkEntryPrivate *priv = entry->priv; EntryIconInfo *icon_info = priv->icons[icon_pos]; GdkPixbuf *pixbuf; gint x, y, width, height; - cairo_t *cr; if (!icon_info) return; @@ -3211,7 +3338,8 @@ draw_icon (GtkWidget *widget, if (icon_info->pixbuf == NULL) return; - gdk_drawable_get_size (icon_info->window, &width, &height); + width = gdk_window_get_width (icon_info->window); + height = gdk_window_get_height (icon_info->window); /* size_allocate hasn't been called yet. These are the default values. */ @@ -3259,31 +3387,37 @@ draw_icon (GtkWidget *widget, pixbuf = temp_pixbuf; } - cr = gdk_cairo_create (icon_info->window); gdk_cairo_set_source_pixbuf (cr, pixbuf, x, y); cairo_paint (cr); - cairo_destroy (cr); g_object_unref (pixbuf); } static void -gtk_entry_draw_frame (GtkWidget *widget, - GdkEventExpose *event) +gtk_entry_draw_frame (GtkWidget *widget, + GtkStyleContext *context, + cairo_t *cr) { - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (widget); - GtkStyle *style; + GtkEntry *entry = GTK_ENTRY (widget); + GtkEntryPrivate *priv = entry->priv; GdkWindow *window; gint x = 0, y = 0, width, height; - GtkStateType state; + GtkAllocation allocation; + gint frame_x, frame_y; + + cairo_save (cr); window = gtk_widget_get_window (widget); - gdk_drawable_get_size (window, &width, &height); + get_frame_size (GTK_ENTRY (widget), &frame_x, &frame_y, &width, &height); + gtk_widget_get_allocation (widget, &allocation); + + cairo_translate (cr, frame_x - allocation.x, frame_y - allocation.y); /* Fix a problem with some themes which assume that entry->text_area's - * width equals widget->window's width */ + * width equals widget->window's width + * http://bugzilla.gnome.org/show_bug.cgi?id=466000 */ if (GTK_IS_SPIN_BUTTON (widget)) { gint xborder, yborder; @@ -3303,16 +3437,14 @@ gtk_entry_draw_frame (GtkWidget *widget, height -= 2 * priv->focus_width; } - style = gtk_widget_get_style (widget); - state = gtk_widget_has_focus (widget) ? - GTK_STATE_ACTIVE : gtk_widget_get_state (widget); + gtk_render_background (context, cr, + x, y, width, height); - gtk_paint_shadow (style, window, - state, priv->shadow_type, - &event->area, widget, "entry", x, y, width, height); + if (priv->has_frame) + gtk_render_frame (context, cr, + x, y, width, height); - - gtk_entry_draw_progress (widget, event); + gtk_entry_draw_progress (widget, context, cr); if (gtk_widget_has_focus (widget) && !priv->interior_focus) { @@ -3321,64 +3453,44 @@ gtk_entry_draw_frame (GtkWidget *widget, width += 2 * priv->focus_width; height += 2 * priv->focus_width; - gtk_paint_focus (style, window, - gtk_widget_get_state (widget), - &event->area, widget, "entry", - 0, 0, width, height); - } -} - -static void -gtk_entry_get_progress_border (GtkWidget *widget, - GtkBorder *progress_border) -{ - GtkBorder *tmp_border; - GtkStyle *style; - - gtk_widget_style_get (widget, "progress-border", &tmp_border, NULL); - if (tmp_border) - { - *progress_border = *tmp_border; - gtk_border_free (tmp_border); + gtk_render_focus (context, cr, + 0, 0, width, height); } - else - { - style = gtk_widget_get_style (widget); - progress_border->left = style->xthickness; - progress_border->right = style->xthickness; - progress_border->top = style->ythickness; - progress_border->bottom = style->ythickness; - } + cairo_restore (cr); } static void get_progress_area (GtkWidget *widget, - gint *x, - gint *y, - gint *width, - gint *height) + gint *x, + gint *y, + gint *width, + gint *height) { - GtkEntryPrivate *private = GTK_ENTRY_GET_PRIVATE (widget); GtkEntry *entry = GTK_ENTRY (widget); - GtkBorder progress_border; - - gtk_entry_get_progress_border (widget, &progress_border); + GtkEntryPrivate *private = entry->priv; + GtkBorder *progress_border; - *x = progress_border.left; - *y = progress_border.top; + get_text_area_size (entry, x, y, width, height); - gdk_drawable_get_size (gtk_widget_get_window (widget), width, height); + if (!private->interior_focus) + { + *x -= private->focus_width; + *y -= private->focus_width; + *width += 2 * private->focus_width; + *height += 2 * private->focus_width; + } - *width -= progress_border.left + progress_border.right; - *height -= progress_border.top + progress_border.bottom; + gtk_widget_style_get (widget, "progress-border", &progress_border, NULL); - if (gtk_widget_has_focus (widget) && !private->interior_focus) + if (progress_border) { - *x += private->focus_width; - *y += private->focus_width; - *width -= 2 * private->focus_width; - *height -= 2 * private->focus_width; + *x += progress_border->left; + *y += progress_border->top; + *width -= progress_border->left + progress_border->right; + *height -= progress_border->top + progress_border->bottom; + + gtk_border_free (progress_border); } if (private->progress_pulse_mode) @@ -3413,103 +3525,79 @@ get_progress_area (GtkWidget *widget, } static void -gtk_entry_draw_progress (GtkWidget *widget, - GdkEventExpose *event) +gtk_entry_draw_progress (GtkWidget *widget, + GtkStyleContext *context, + cairo_t *cr) { gint x, y, width, height; - GtkStateType state; get_progress_area (widget, &x, &y, &width, &height); if ((width <= 0) || (height <= 0)) return; - if (event->window != gtk_widget_get_window (widget)) - { - gint pos_x, pos_y; + gtk_style_context_save (context); + gtk_style_context_add_class (context, GTK_STYLE_CLASS_PROGRESSBAR); - gdk_window_get_position (event->window, &pos_x, &pos_y); + gtk_render_activity (context, cr, + x, y, width, height); - x -= pos_x; - y -= pos_y; - } - - state = GTK_STATE_SELECTED; - if (!gtk_widget_get_sensitive (widget)) - state = GTK_STATE_INSENSITIVE; - - gtk_paint_box (gtk_widget_get_style (widget), event->window, - state, GTK_SHADOW_OUT, - &event->area, widget, "entry-progress", - x, y, - width, height); + gtk_style_context_restore (context); } static gint -gtk_entry_expose (GtkWidget *widget, - GdkEventExpose *event) +gtk_entry_draw (GtkWidget *widget, + cairo_t *cr) { GtkEntry *entry = GTK_ENTRY (widget); - GtkStyle *style; - GtkStateType state; - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry); + GtkStyleContext *context; + GtkStateFlags state; + GtkEntryPrivate *priv = entry->priv; + int i; - style = gtk_widget_get_style (widget); + context = gtk_widget_get_style_context (widget); + state = gtk_widget_get_state_flags (widget); - state = gtk_widget_has_focus (widget) ? - GTK_STATE_ACTIVE : gtk_widget_get_state (widget); + if (gtk_widget_has_focus (widget)) + state |= GTK_STATE_FLAG_FOCUSED; - if (gtk_widget_get_window (widget) == event->window) + if (gtk_cairo_should_draw_window (cr, gtk_widget_get_window (widget))) { - gtk_entry_draw_frame (widget, event); - } - else if (entry->text_area == event->window) - { - gint width, height; + /* Draw entry_bg, shadow, progress and focus */ + gtk_entry_draw_frame (widget, context, cr); - gdk_drawable_get_size (entry->text_area, &width, &height); + /* Draw text and cursor */ + cairo_save (cr); - gtk_paint_flat_box (style, entry->text_area, - state, GTK_SHADOW_NONE, - &event->area, widget, "entry_bg", - 0, 0, width, height); + gtk_cairo_transform_to_window (cr, widget, priv->text_area); - gtk_entry_draw_progress (widget, event); - - if (entry->dnd_position != -1) - gtk_entry_draw_cursor (GTK_ENTRY (widget), CURSOR_DND); + if (priv->dnd_position != -1) + gtk_entry_draw_cursor (GTK_ENTRY (widget), cr, CURSOR_DND); - gtk_entry_draw_text (GTK_ENTRY (widget)); + gtk_entry_draw_text (GTK_ENTRY (widget), cr); /* When no text is being displayed at all, don't show the cursor */ if (gtk_entry_get_display_mode (entry) != DISPLAY_BLANK && gtk_widget_has_focus (widget) && - entry->selection_bound == entry->current_pos && entry->cursor_visible) - gtk_entry_draw_cursor (GTK_ENTRY (widget), CURSOR_STANDARD); - } - else - { - int i; + priv->selection_bound == priv->current_pos && priv->cursor_visible) + gtk_entry_draw_cursor (GTK_ENTRY (widget), cr, CURSOR_STANDARD); + + cairo_restore (cr); + /* Draw icons */ for (i = 0; i < MAX_ICONS; i++) { EntryIconInfo *icon_info = priv->icons[i]; - if (icon_info != NULL && event->window == icon_info->window) + if (icon_info != NULL) { - gint width, height; + cairo_save (cr); - gdk_drawable_get_size (icon_info->window, &width, &height); + gtk_cairo_transform_to_window (cr, widget, icon_info->window); - gtk_paint_flat_box (style, icon_info->window, - state, GTK_SHADOW_NONE, - NULL, widget, "entry_bg", - 0, 0, width, height); + draw_icon (widget, cr, i); - gtk_entry_draw_progress (widget, event); - draw_icon (widget, i); - - break; + cairo_restore (cr); } } } @@ -3522,7 +3610,7 @@ gtk_entry_enter_notify (GtkWidget *widget, GdkEventCrossing *event) { GtkEntry *entry = GTK_ENTRY (widget); - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry); + GtkEntryPrivate *priv = entry->priv; gint i; for (i = 0; i < MAX_ICONS; i++) @@ -3549,7 +3637,7 @@ gtk_entry_leave_notify (GtkWidget *widget, GdkEventCrossing *event) { GtkEntry *entry = GTK_ENTRY (widget); - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry); + GtkEntryPrivate *priv = entry->priv; gint i; for (i = 0; i < MAX_ICONS; i++) @@ -3645,7 +3733,7 @@ gtk_entry_button_press (GtkWidget *widget, { GtkEntry *entry = GTK_ENTRY (widget); GtkEditable *editable = GTK_EDITABLE (widget); - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry); + GtkEntryPrivate *priv = entry->priv; EntryIconInfo *icon_info = NULL; gint tmp_pos; gint sel_start, sel_end; @@ -3677,36 +3765,36 @@ gtk_entry_button_press (GtkWidget *widget, } } - if (event->window != entry->text_area || - (entry->button && event->button != entry->button)) + if (event->window != priv->text_area || + (priv->button && event->button != priv->button)) return FALSE; gtk_entry_reset_blink_time (entry); - entry->button = event->button; + priv->button = event->button; if (!gtk_widget_has_focus (widget)) { - entry->in_click = TRUE; + priv->in_click = TRUE; gtk_widget_grab_focus (widget); - entry->in_click = FALSE; + priv->in_click = FALSE; } - tmp_pos = gtk_entry_find_position (entry, event->x + entry->scroll_offset); + tmp_pos = gtk_entry_find_position (entry, event->x + priv->scroll_offset); if (event->button == 1) { gboolean have_selection = gtk_editable_get_selection_bounds (editable, &sel_start, &sel_end); - entry->select_words = FALSE; - entry->select_lines = FALSE; + priv->select_words = FALSE; + priv->select_lines = FALSE; if (event->state & GDK_SHIFT_MASK) { _gtk_entry_reset_im_context (entry); if (!have_selection) /* select from the current position to the clicked position */ - sel_start = sel_end = entry->current_pos; + sel_start = sel_end = priv->current_pos; if (tmp_pos > sel_start && tmp_pos < sel_end) { @@ -3729,12 +3817,12 @@ gtk_entry_button_press (GtkWidget *widget, break; case GDK_2BUTTON_PRESS: - entry->select_words = TRUE; + priv->select_words = TRUE; gtk_entry_select_word (entry); break; case GDK_3BUTTON_PRESS: - entry->select_lines = TRUE; + priv->select_lines = TRUE; gtk_entry_select_line (entry); break; @@ -3742,10 +3830,10 @@ gtk_entry_button_press (GtkWidget *widget, break; } - start = MIN (entry->current_pos, entry->selection_bound); + start = MIN (priv->current_pos, priv->selection_bound); start = MIN (sel_start, start); - end = MAX (entry->current_pos, entry->selection_bound); + end = MAX (priv->current_pos, priv->selection_bound); end = MAX (sel_end, end); if (tmp_pos == sel_start || tmp_pos == sel_end) @@ -3763,14 +3851,14 @@ gtk_entry_button_press (GtkWidget *widget, switch (event->type) { case GDK_BUTTON_PRESS: - if (in_selection (entry, event->x + entry->scroll_offset)) + if (in_selection (entry, event->x + priv->scroll_offset)) { /* Click inside the selection - we'll either start a drag, or * clear the selection */ - entry->in_drag = TRUE; - entry->drag_start_x = event->x + entry->scroll_offset; - entry->drag_start_y = event->y; + priv->in_drag = TRUE; + priv->drag_start_x = event->x + priv->scroll_offset; + priv->drag_start_y = event->y; } else gtk_editable_set_position (editable, tmp_pos); @@ -3779,20 +3867,20 @@ gtk_entry_button_press (GtkWidget *widget, case GDK_2BUTTON_PRESS: /* We ALWAYS receive a GDK_BUTTON_PRESS immediately before * receiving a GDK_2BUTTON_PRESS so we need to reset - * entry->in_drag which may have been set above + * priv->in_drag which may have been set above */ - entry->in_drag = FALSE; - entry->select_words = TRUE; + priv->in_drag = FALSE; + priv->select_words = TRUE; gtk_entry_select_word (entry); break; case GDK_3BUTTON_PRESS: /* We ALWAYS receive a GDK_BUTTON_PRESS immediately before * receiving a GDK_3BUTTON_PRESS so we need to reset - * entry->in_drag which may have been set above + * priv->in_drag which may have been set above */ - entry->in_drag = FALSE; - entry->select_lines = TRUE; + priv->in_drag = FALSE; + priv->select_lines = TRUE; gtk_entry_select_line (entry); break; @@ -3804,7 +3892,7 @@ gtk_entry_button_press (GtkWidget *widget, } else if (event->button == 2 && event->type == GDK_BUTTON_PRESS) { - if (entry->editable) + if (priv->editable) { priv->insert_pos = tmp_pos; gtk_entry_paste (entry, GDK_SELECTION_PRIMARY); @@ -3818,7 +3906,7 @@ gtk_entry_button_press (GtkWidget *widget, else if (event->button == 3 && event->type == GDK_BUTTON_PRESS) { gtk_entry_do_popup (entry, event); - entry->button = 0; /* Don't wait for release, since the menu will gtk_grab_add */ + priv->button = 0; /* Don't wait for release, since the menu will gtk_grab_add */ return TRUE; } @@ -3831,7 +3919,7 @@ gtk_entry_button_release (GtkWidget *widget, GdkEventButton *event) { GtkEntry *entry = GTK_ENTRY (widget); - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (widget); + GtkEntryPrivate *priv = entry->priv; EntryIconInfo *icon_info = NULL; gint i; @@ -3844,15 +3932,12 @@ gtk_entry_button_release (GtkWidget *widget, if (event->window == icon_info->window) { - gint width, height; - - gdk_drawable_get_size (icon_info->window, &width, &height); - icon_info->pressed = FALSE; if (should_prelight (entry, i) && event->x >= 0 && event->y >= 0 && - event->x < width && event->y < height) + event->x < gdk_window_get_width (icon_info->window) && + event->y < gdk_window_get_height (icon_info->window)) { icon_info->prelight = TRUE; gtk_widget_queue_draw (widget); @@ -3865,19 +3950,19 @@ gtk_entry_button_release (GtkWidget *widget, } } - if (event->window != entry->text_area || entry->button != event->button) + if (event->window != priv->text_area || priv->button != event->button) return FALSE; - if (entry->in_drag) + if (priv->in_drag) { - gint tmp_pos = gtk_entry_find_position (entry, entry->drag_start_x); + gint tmp_pos = gtk_entry_find_position (entry, priv->drag_start_x); gtk_editable_set_position (GTK_EDITABLE (entry), tmp_pos); - entry->in_drag = 0; + priv->in_drag = 0; } - entry->button = 0; + priv->button = 0; gtk_entry_update_primary_selection (entry); @@ -3902,7 +3987,7 @@ gtk_entry_motion_notify (GtkWidget *widget, GdkEventMotion *event) { GtkEntry *entry = GTK_ENTRY (widget); - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry); + GtkEntryPrivate *priv = entry->priv; EntryIconInfo *icon_info = NULL; GdkDragContext *context; gint tmp_pos; @@ -3938,77 +4023,70 @@ gtk_entry_motion_notify (GtkWidget *widget, } } - if (entry->mouse_cursor_obscured) + if (priv->mouse_cursor_obscured) { GdkCursor *cursor; cursor = gdk_cursor_new_for_display (gtk_widget_get_display (widget), GDK_XTERM); - gdk_window_set_cursor (entry->text_area, cursor); + gdk_window_set_cursor (priv->text_area, cursor); gdk_cursor_unref (cursor); - entry->mouse_cursor_obscured = FALSE; + priv->mouse_cursor_obscured = FALSE; } - if (event->window != entry->text_area || entry->button != 1) + if (event->window != priv->text_area || priv->button != 1) return FALSE; - if (entry->select_lines) + if (priv->select_lines) return TRUE; gdk_event_request_motions (event); - if (entry->in_drag) + if (priv->in_drag) { if (gtk_entry_get_display_mode (entry) == DISPLAY_NORMAL && gtk_drag_check_threshold (widget, - entry->drag_start_x, entry->drag_start_y, - event->x + entry->scroll_offset, event->y)) + priv->drag_start_x, priv->drag_start_y, + event->x + priv->scroll_offset, event->y)) { GdkDragContext *context; GtkTargetList *target_list = gtk_target_list_new (NULL, 0); - guint actions = entry->editable ? GDK_ACTION_COPY | GDK_ACTION_MOVE : GDK_ACTION_COPY; + guint actions = priv->editable ? GDK_ACTION_COPY | GDK_ACTION_MOVE : GDK_ACTION_COPY; gchar *text = NULL; - GdkPixmap *pixmap = NULL; + cairo_surface_t *surface; gtk_target_list_add_text_targets (target_list, 0); text = _gtk_entry_get_selected_text (entry); - pixmap = _gtk_text_util_create_drag_icon (widget, text, -1); + surface = _gtk_text_util_create_drag_icon (widget, text, -1); context = gtk_drag_begin (widget, target_list, actions, - entry->button, (GdkEvent *)event); + priv->button, (GdkEvent *)event); - if (pixmap) - gtk_drag_set_icon_pixmap (context, - gdk_drawable_get_colormap (pixmap), - pixmap, - NULL, - -2, -2); + if (surface) + gtk_drag_set_icon_surface (context, surface); else gtk_drag_set_icon_default (context); - if (pixmap) - g_object_unref (pixmap); + if (surface) + cairo_surface_destroy (surface); g_free (text); - entry->in_drag = FALSE; - entry->button = 0; + priv->in_drag = FALSE; + priv->button = 0; gtk_target_list_unref (target_list); } } else { - gint height; - gdk_drawable_get_size (entry->text_area, NULL, &height); - if (event->y < 0) tmp_pos = 0; - else if (event->y >= height) + else if (event->y >= gdk_window_get_height (priv->text_area)) tmp_pos = gtk_entry_buffer_get_length (get_buffer (entry)); else - tmp_pos = gtk_entry_find_position (entry, event->x + entry->scroll_offset); - - if (entry->select_words) + tmp_pos = gtk_entry_find_position (entry, event->x + priv->scroll_offset); + + if (priv->select_words) { gint min, max; gint old_min, old_max; @@ -4016,12 +4094,12 @@ gtk_entry_motion_notify (GtkWidget *widget, min = gtk_entry_move_backward_word (entry, tmp_pos, TRUE); max = gtk_entry_move_forward_word (entry, tmp_pos, TRUE); - - pos = entry->current_pos; - bound = entry->selection_bound; - old_min = MIN(entry->current_pos, entry->selection_bound); - old_max = MAX(entry->current_pos, entry->selection_bound); + pos = priv->current_pos; + bound = priv->selection_bound; + + old_min = MIN(priv->current_pos, priv->selection_bound); + old_max = MAX(priv->current_pos, priv->selection_bound); if (min < old_min) { @@ -4035,12 +4113,12 @@ gtk_entry_motion_notify (GtkWidget *widget, } else if (pos == old_min) { - if (entry->current_pos != min) + if (priv->current_pos != min) pos = max; } else { - if (entry->current_pos != max) + if (priv->current_pos != max) pos = min; } @@ -4059,7 +4137,7 @@ set_invisible_cursor (GdkWindow *window) GdkDisplay *display; GdkCursor *cursor; - display = gdk_drawable_get_display (window); + display = gdk_window_get_display (window); cursor = gdk_cursor_new_for_display (display, GDK_BLANK_CURSOR); gdk_window_set_cursor (window, cursor); @@ -4070,12 +4148,14 @@ set_invisible_cursor (GdkWindow *window) static void gtk_entry_obscure_mouse_cursor (GtkEntry *entry) { - if (entry->mouse_cursor_obscured) + GtkEntryPrivate *priv = entry->priv; + + if (priv->mouse_cursor_obscured) return; - set_invisible_cursor (entry->text_area); - - entry->mouse_cursor_obscured = TRUE; + set_invisible_cursor (priv->text_area); + + priv->mouse_cursor_obscured = TRUE; } static gint @@ -4083,16 +4163,17 @@ gtk_entry_key_press (GtkWidget *widget, GdkEventKey *event) { GtkEntry *entry = GTK_ENTRY (widget); + GtkEntryPrivate *priv = entry->priv; gtk_entry_reset_blink_time (entry); gtk_entry_pend_cursor_blink (entry); - if (entry->editable) + if (priv->editable) { - if (gtk_im_context_filter_keypress (entry->im_context, event)) + if (gtk_im_context_filter_keypress (priv->im_context, event)) { gtk_entry_obscure_mouse_cursor (entry); - entry->need_im_reset = TRUE; + priv->need_im_reset = TRUE; return TRUE; } } @@ -4103,7 +4184,7 @@ gtk_entry_key_press (GtkWidget *widget, event->keyval == GDK_KEY_Escape) { GtkEntryCompletion *completion = gtk_entry_get_completion (entry); - + if (completion && completion->priv->completion_timeout) { g_source_remove (completion->priv->completion_timeout); @@ -4118,7 +4199,7 @@ gtk_entry_key_press (GtkWidget *widget, */ return TRUE; - if (!entry->editable && event->length) + if (!priv->editable && event->length) gtk_widget_error_bell (widget); return FALSE; @@ -4129,12 +4210,13 @@ gtk_entry_key_release (GtkWidget *widget, GdkEventKey *event) { GtkEntry *entry = GTK_ENTRY (widget); + GtkEntryPrivate *priv = entry->priv; - if (entry->editable) + if (priv->editable) { - if (gtk_im_context_filter_keypress (entry->im_context, event)) + if (gtk_im_context_filter_keypress (priv->im_context, event)) { - entry->need_im_reset = TRUE; + priv->need_im_reset = TRUE; return TRUE; } } @@ -4147,16 +4229,17 @@ gtk_entry_focus_in (GtkWidget *widget, GdkEventFocus *event) { GtkEntry *entry = GTK_ENTRY (widget); + GtkEntryPrivate *priv = entry->priv; GdkKeymap *keymap; gtk_widget_queue_draw (widget); keymap = gdk_keymap_get_for_display (gtk_widget_get_display (widget)); - if (entry->editable) + if (priv->editable) { - entry->need_im_reset = TRUE; - gtk_im_context_focus_in (entry->im_context); + priv->need_im_reset = TRUE; + gtk_im_context_focus_in (priv->im_context); keymap_state_changed (keymap, entry); g_signal_connect (keymap, "state-changed", G_CALLBACK (keymap_state_changed), entry); @@ -4176,6 +4259,7 @@ gtk_entry_focus_out (GtkWidget *widget, GdkEventFocus *event) { GtkEntry *entry = GTK_ENTRY (widget); + GtkEntryPrivate *priv = entry->priv; GtkEntryCompletion *completion; GdkKeymap *keymap; @@ -4183,10 +4267,10 @@ gtk_entry_focus_out (GtkWidget *widget, keymap = gdk_keymap_get_for_display (gtk_widget_get_display (widget)); - if (entry->editable) + if (priv->editable) { - entry->need_im_reset = TRUE; - gtk_im_context_focus_out (entry->im_context); + priv->need_im_reset = TRUE; + gtk_im_context_focus_out (priv->im_context); remove_capslock_feedback (entry); } @@ -4206,11 +4290,12 @@ static void gtk_entry_grab_focus (GtkWidget *widget) { GtkEntry *entry = GTK_ENTRY (widget); + GtkEntryPrivate *priv = entry->priv; gboolean select_on_focus; GTK_WIDGET_CLASS (gtk_entry_parent_class)->grab_focus (widget); - if (entry->editable && !entry->in_click) + if (priv->editable && !priv->in_click) { g_object_get (gtk_widget_get_settings (widget), "gtk-entry-select-on-focus", @@ -4234,45 +4319,26 @@ gtk_entry_direction_changed (GtkWidget *widget, } static void -gtk_entry_state_changed (GtkWidget *widget, - GtkStateType previous_state) +gtk_entry_state_flags_changed (GtkWidget *widget, + GtkStateFlags previous_state) { GtkEntry *entry = GTK_ENTRY (widget); - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (widget); + GtkEntryPrivate *priv = entry->priv; GdkCursor *cursor; - gint i; if (gtk_widget_get_realized (widget)) { - GtkStateType state; - GtkStyle *style; - - style = gtk_widget_get_style (widget); - state = gtk_widget_get_state (widget); - - gdk_window_set_background (gtk_widget_get_window (widget), - &style->base[state]); - gdk_window_set_background (entry->text_area, - &style->base[state]); - for (i = 0; i < MAX_ICONS; i++) - { - EntryIconInfo *icon_info = priv->icons[i]; - if (icon_info && icon_info->window) - gdk_window_set_background (icon_info->window, - &style->base[state]); - } - if (gtk_widget_is_sensitive (widget)) cursor = gdk_cursor_new_for_display (gtk_widget_get_display (widget), GDK_XTERM); else cursor = NULL; - - gdk_window_set_cursor (entry->text_area, cursor); + + gdk_window_set_cursor (priv->text_area, cursor); if (cursor) gdk_cursor_unref (cursor); - entry->mouse_cursor_obscured = FALSE; + priv->mouse_cursor_obscured = FALSE; update_cursors (widget); } @@ -4280,7 +4346,7 @@ gtk_entry_state_changed (GtkWidget *widget, if (!gtk_widget_is_sensitive (widget)) { /* Clear any selection */ - gtk_editable_select_region (GTK_EDITABLE (entry), entry->current_pos, entry->current_pos); + gtk_editable_select_region (GTK_EDITABLE (entry), priv->current_pos, priv->current_pos); } gtk_widget_queue_draw (widget); @@ -4355,6 +4421,7 @@ gtk_entry_real_set_position (GtkEditable *editable, gint position) { GtkEntry *entry = GTK_ENTRY (editable); + GtkEntryPrivate *priv = entry->priv; guint length; @@ -4362,8 +4429,8 @@ gtk_entry_real_set_position (GtkEditable *editable, if (position < 0 || position > length) position = length; - if (position != entry->current_pos || - position != entry->selection_bound) + if (position != priv->current_pos || + position != priv->selection_bound) { _gtk_entry_reset_im_context (entry); gtk_entry_set_positions (entry, position, position); @@ -4373,7 +4440,10 @@ gtk_entry_real_set_position (GtkEditable *editable, static gint gtk_entry_get_position (GtkEditable *editable) { - return GTK_ENTRY (editable)->current_pos; + GtkEntry *entry = GTK_ENTRY (editable); + GtkEntryPrivate *priv = entry->priv; + + return priv->current_pos; } static void @@ -4405,17 +4475,18 @@ gtk_entry_get_selection_bounds (GtkEditable *editable, gint *end) { GtkEntry *entry = GTK_ENTRY (editable); + GtkEntryPrivate *priv = entry->priv; - *start = entry->selection_bound; - *end = entry->current_pos; + *start = priv->selection_bound; + *end = priv->current_pos; - return (entry->selection_bound != entry->current_pos); + return (priv->selection_bound != priv->current_pos); } static void icon_theme_changed (GtkEntry *entry) { - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry); + GtkEntryPrivate *priv = entry->priv; gint i; for (i = 0; i < MAX_ICONS; i++) @@ -4438,7 +4509,7 @@ icon_theme_changed (GtkEntry *entry) static void icon_margin_changed (GtkEntry *entry) { - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry); + GtkEntryPrivate *priv = entry->priv; GtkBorder border; _gtk_entry_effective_inner_border (GTK_ENTRY (entry), &border); @@ -4447,14 +4518,12 @@ icon_margin_changed (GtkEntry *entry) } static void -gtk_entry_style_set (GtkWidget *widget, - GtkStyle *previous_style) +gtk_entry_style_updated (GtkWidget *widget) { GtkEntry *entry = GTK_ENTRY (widget); - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry); + GtkEntryPrivate *priv = entry->priv; gint focus_width; gboolean interior_focus; - gint i; gtk_widget_style_get (widget, "focus-line-width", &focus_width, @@ -4465,29 +4534,10 @@ gtk_entry_style_set (GtkWidget *widget, priv->interior_focus = interior_focus; if (!priv->invisible_char_set) - entry->invisible_char = find_invisible_char (GTK_WIDGET (entry)); + priv->invisible_char = find_invisible_char (GTK_WIDGET (entry)); gtk_entry_recompute (entry); - if (previous_style && gtk_widget_get_realized (widget)) - { - GtkStyle *style; - - style = gtk_widget_get_style (widget); - - gdk_window_set_background (gtk_widget_get_window (widget), - &style->base[gtk_widget_get_state (widget)]); - gdk_window_set_background (entry->text_area, - &style->base[gtk_widget_get_state (widget)]); - for (i = 0; i < MAX_ICONS; i++) - { - EntryIconInfo *icon_info = priv->icons[i]; - if (icon_info && icon_info->window) - gdk_window_set_background (icon_info->window, - &style->base[gtk_widget_get_state (widget)]); - } - } - icon_theme_changed (entry); icon_margin_changed (entry); } @@ -4506,9 +4556,11 @@ gtk_cell_editable_key_press_event (GtkEntry *entry, GdkEventKey *key_event, gpointer data) { + GtkEntryPrivate *priv = entry->priv; + if (key_event->keyval == GDK_KEY_Escape) { - entry->editing_canceled = TRUE; + priv->editing_canceled = TRUE; gtk_cell_editable_editing_done (GTK_CELL_EDITABLE (entry)); gtk_cell_editable_remove_widget (GTK_CELL_EDITABLE (entry)); @@ -4531,7 +4583,10 @@ static void gtk_entry_start_editing (GtkCellEditable *cell_editable, GdkEvent *event) { - GTK_ENTRY (cell_editable)->is_cell_renderer = TRUE; + GtkEntry *entry = GTK_ENTRY (cell_editable); + GtkEntryPrivate *priv = entry->priv; + + priv->is_cell_renderer = TRUE; g_signal_connect (cell_editable, "activate", G_CALLBACK (gtk_cell_editable_entry_activated), NULL); @@ -4609,16 +4664,17 @@ buffer_inserted_text (GtkEntryBuffer *buffer, guint n_chars, GtkEntry *entry) { + GtkEntryPrivate *priv = entry->priv; guint password_hint_timeout; - if (entry->current_pos > position) - entry->current_pos += n_chars; + if (priv->current_pos > position) + priv->current_pos += n_chars; - if (entry->selection_bound > position) - entry->selection_bound += n_chars; + if (priv->selection_bound > position) + priv->selection_bound += n_chars; /* Calculate the password hint if it needs to be displayed. */ - if (n_chars == 1 && !entry->visible) + if (n_chars == 1 && !priv->visible) { g_object_get (gtk_widget_get_settings (GTK_WIDGET (entry)), "gtk-entry-password-hint-timeout", &password_hint_timeout, @@ -4650,15 +4706,16 @@ buffer_deleted_text (GtkEntryBuffer *buffer, guint n_chars, GtkEntry *entry) { + GtkEntryPrivate *priv = entry->priv; guint end_pos = position + n_chars; gint selection_bound; guint current_pos; - current_pos = entry->current_pos; + current_pos = priv->current_pos; if (current_pos > position) current_pos -= MIN (current_pos, end_pos) - position; - selection_bound = entry->selection_bound; + selection_bound = priv->selection_bound; if (selection_bound > position) selection_bound -= MIN (selection_bound, end_pos) - position; @@ -4668,7 +4725,7 @@ buffer_deleted_text (GtkEntryBuffer *buffer, gtk_entry_update_primary_selection (entry); /* Disable the password hint if one exists. */ - if (!entry->visible) + if (!priv->visible) { GtkEntryPasswordHint *password_hint = g_object_get_qdata (G_OBJECT (entry), quark_password_hint); @@ -4737,6 +4794,7 @@ static gint get_better_cursor_x (GtkEntry *entry, gint offset) { + GtkEntryPrivate *priv = entry->priv; GdkKeymap *keymap = gdk_keymap_get_for_display (gtk_widget_get_display (GTK_WIDGET (entry))); PangoDirection keymap_direction = gdk_keymap_get_direction (keymap); gboolean split_cursor; @@ -4756,7 +4814,7 @@ get_better_cursor_x (GtkEntry *entry, if (split_cursor) return strong_pos.x / PANGO_SCALE; else - return (keymap_direction == entry->resolved_dir) ? strong_pos.x / PANGO_SCALE : weak_pos.x / PANGO_SCALE; + return (keymap_direction == priv->resolved_dir) ? strong_pos.x / PANGO_SCALE : weak_pos.x / PANGO_SCALE; } static void @@ -4765,12 +4823,12 @@ gtk_entry_move_cursor (GtkEntry *entry, gint count, gboolean extend_selection) { - gint new_pos = entry->current_pos; - GtkEntryPrivate *priv; + GtkEntryPrivate *priv = entry->priv; + gint new_pos = priv->current_pos; _gtk_entry_reset_im_context (entry); - if (entry->current_pos != entry->selection_bound && !extend_selection) + if (priv->current_pos != priv->selection_bound && !extend_selection) { /* If we have a current selection and aren't extending it, move to the * start/or end of the selection as appropriate @@ -4779,26 +4837,25 @@ gtk_entry_move_cursor (GtkEntry *entry, { case GTK_MOVEMENT_VISUAL_POSITIONS: { - gint current_x = get_better_cursor_x (entry, entry->current_pos); - gint bound_x = get_better_cursor_x (entry, entry->selection_bound); + gint current_x = get_better_cursor_x (entry, priv->current_pos); + gint bound_x = get_better_cursor_x (entry, priv->selection_bound); if (count <= 0) - new_pos = current_x < bound_x ? entry->current_pos : entry->selection_bound; + new_pos = current_x < bound_x ? priv->current_pos : priv->selection_bound; else - new_pos = current_x > bound_x ? entry->current_pos : entry->selection_bound; + new_pos = current_x > bound_x ? priv->current_pos : priv->selection_bound; break; } case GTK_MOVEMENT_LOGICAL_POSITIONS: case GTK_MOVEMENT_WORDS: if (count < 0) - new_pos = MIN (entry->current_pos, entry->selection_bound); + new_pos = MIN (priv->current_pos, priv->selection_bound); else - new_pos = MAX (entry->current_pos, entry->selection_bound); + new_pos = MAX (priv->current_pos, priv->selection_bound); break; case GTK_MOVEMENT_DISPLAY_LINE_ENDS: case GTK_MOVEMENT_PARAGRAPH_ENDS: case GTK_MOVEMENT_BUFFER_ENDS: - priv = GTK_ENTRY_GET_PRIVATE (entry); new_pos = count < 0 ? 0 : gtk_entry_buffer_get_length (get_buffer (entry)); break; case GTK_MOVEMENT_DISPLAY_LINES: @@ -4817,7 +4874,7 @@ gtk_entry_move_cursor (GtkEntry *entry, break; case GTK_MOVEMENT_VISUAL_POSITIONS: new_pos = gtk_entry_move_visually (entry, new_pos, count); - if (entry->current_pos == new_pos) + if (priv->current_pos == new_pos) { if (!extend_selection) { @@ -4850,15 +4907,14 @@ gtk_entry_move_cursor (GtkEntry *entry, new_pos = gtk_entry_move_backward_word (entry, new_pos, FALSE); count++; } - if (entry->current_pos == new_pos) + if (priv->current_pos == new_pos) gtk_widget_error_bell (GTK_WIDGET (entry)); break; case GTK_MOVEMENT_DISPLAY_LINE_ENDS: case GTK_MOVEMENT_PARAGRAPH_ENDS: case GTK_MOVEMENT_BUFFER_ENDS: - priv = GTK_ENTRY_GET_PRIVATE (entry); new_pos = count < 0 ? 0 : gtk_entry_buffer_get_length (get_buffer (entry)); - if (entry->current_pos == new_pos) + if (priv->current_pos == new_pos) gtk_widget_error_bell (GTK_WIDGET (entry)); break; case GTK_MOVEMENT_DISPLAY_LINES: @@ -4870,7 +4926,7 @@ gtk_entry_move_cursor (GtkEntry *entry, } if (extend_selection) - gtk_editable_select_region (GTK_EDITABLE (entry), entry->selection_bound, new_pos); + gtk_editable_select_region (GTK_EDITABLE (entry), priv->selection_bound, new_pos); else gtk_editable_set_position (GTK_EDITABLE (entry), new_pos); @@ -4881,10 +4937,11 @@ static void gtk_entry_insert_at_cursor (GtkEntry *entry, const gchar *str) { + GtkEntryPrivate *priv = entry->priv; GtkEditable *editable = GTK_EDITABLE (entry); - gint pos = entry->current_pos; + gint pos = priv->current_pos; - if (entry->editable) + if (priv->editable) { _gtk_entry_reset_im_context (entry); @@ -4898,20 +4955,21 @@ gtk_entry_delete_from_cursor (GtkEntry *entry, GtkDeleteType type, gint count) { + GtkEntryPrivate *priv = entry->priv; GtkEditable *editable = GTK_EDITABLE (entry); - gint start_pos = entry->current_pos; - gint end_pos = entry->current_pos; + gint start_pos = priv->current_pos; + gint end_pos = priv->current_pos; gint old_n_bytes = gtk_entry_buffer_get_bytes (get_buffer (entry)); _gtk_entry_reset_im_context (entry); - if (!entry->editable) + if (!priv->editable) { gtk_widget_error_bell (GTK_WIDGET (entry)); return; } - if (entry->selection_bound != entry->current_pos) + if (priv->selection_bound != priv->current_pos) { gtk_editable_delete_selection (editable); return; @@ -4920,7 +4978,7 @@ gtk_entry_delete_from_cursor (GtkEntry *entry, switch (type) { case GTK_DELETE_CHARS: - end_pos = gtk_entry_move_logically (entry, entry->current_pos, count); + end_pos = gtk_entry_move_logically (entry, priv->current_pos, count); gtk_editable_delete_text (editable, MIN (start_pos, end_pos), MAX (start_pos, end_pos)); break; case GTK_DELETE_WORDS: @@ -4954,9 +5012,9 @@ gtk_entry_delete_from_cursor (GtkEntry *entry, case GTK_DELETE_DISPLAY_LINE_ENDS: case GTK_DELETE_PARAGRAPH_ENDS: if (count < 0) - gtk_editable_delete_text (editable, 0, entry->current_pos); + gtk_editable_delete_text (editable, 0, priv->current_pos); else - gtk_editable_delete_text (editable, entry->current_pos, -1); + gtk_editable_delete_text (editable, priv->current_pos, -1); break; case GTK_DELETE_DISPLAY_LINES: case GTK_DELETE_PARAGRAPHS: @@ -4976,26 +5034,27 @@ gtk_entry_delete_from_cursor (GtkEntry *entry, static void gtk_entry_backspace (GtkEntry *entry) { + GtkEntryPrivate *priv = entry->priv; GtkEditable *editable = GTK_EDITABLE (entry); gint prev_pos; _gtk_entry_reset_im_context (entry); - if (!entry->editable) + if (!priv->editable) { gtk_widget_error_bell (GTK_WIDGET (entry)); return; } - if (entry->selection_bound != entry->current_pos) + if (priv->selection_bound != priv->current_pos) { gtk_editable_delete_selection (editable); return; } - prev_pos = gtk_entry_move_logically (entry, entry->current_pos, -1); + prev_pos = gtk_entry_move_logically (entry, priv->current_pos, -1); - if (prev_pos < entry->current_pos) + if (prev_pos < priv->current_pos) { PangoLayout *layout = gtk_entry_ensure_layout (entry, FALSE); PangoLogAttr *log_attrs; @@ -5004,23 +5063,23 @@ gtk_entry_backspace (GtkEntry *entry) pango_layout_get_log_attrs (layout, &log_attrs, &n_attrs); /* Deleting parts of characters */ - if (log_attrs[entry->current_pos].backspace_deletes_character) + if (log_attrs[priv->current_pos].backspace_deletes_character) { gchar *cluster_text; gchar *normalized_text; glong len; cluster_text = gtk_entry_get_display_text (entry, prev_pos, - entry->current_pos); + priv->current_pos); normalized_text = g_utf8_normalize (cluster_text, strlen (cluster_text), G_NORMALIZE_NFD); len = g_utf8_strlen (normalized_text, -1); - gtk_editable_delete_text (editable, prev_pos, entry->current_pos); + gtk_editable_delete_text (editable, prev_pos, priv->current_pos); if (len > 1) { - gint pos = entry->current_pos; + gint pos = priv->current_pos; gtk_editable_insert_text (editable, normalized_text, g_utf8_offset_to_pointer (normalized_text, len - 1) - normalized_text, @@ -5033,7 +5092,7 @@ gtk_entry_backspace (GtkEntry *entry) } else { - gtk_editable_delete_text (editable, prev_pos, entry->current_pos); + gtk_editable_delete_text (editable, prev_pos, priv->current_pos); } g_free (log_attrs); @@ -5049,13 +5108,14 @@ gtk_entry_backspace (GtkEntry *entry) static void gtk_entry_copy_clipboard (GtkEntry *entry) { + GtkEntryPrivate *priv = entry->priv; GtkEditable *editable = GTK_EDITABLE (entry); gint start, end; gchar *str; if (gtk_editable_get_selection_bounds (editable, &start, &end)) { - if (!entry->visible) + if (!priv->visible) { gtk_widget_error_bell (GTK_WIDGET (entry)); return; @@ -5072,10 +5132,11 @@ gtk_entry_copy_clipboard (GtkEntry *entry) static void gtk_entry_cut_clipboard (GtkEntry *entry) { + GtkEntryPrivate *priv = entry->priv; GtkEditable *editable = GTK_EDITABLE (entry); gint start, end; - if (!entry->visible) + if (!priv->visible) { gtk_widget_error_bell (GTK_WIDGET (entry)); return; @@ -5083,7 +5144,7 @@ gtk_entry_cut_clipboard (GtkEntry *entry) gtk_entry_copy_clipboard (entry); - if (entry->editable) + if (priv->editable) { if (gtk_editable_get_selection_bounds (editable, &start, &end)) gtk_editable_delete_text (editable, start, end); @@ -5097,7 +5158,9 @@ gtk_entry_cut_clipboard (GtkEntry *entry) static void gtk_entry_paste_clipboard (GtkEntry *entry) { - if (entry->editable) + GtkEntryPrivate *priv = entry->priv; + + if (priv->editable) gtk_entry_paste (entry, GDK_NONE); else gtk_widget_error_bell (GTK_WIDGET (entry)); @@ -5106,10 +5169,11 @@ gtk_entry_paste_clipboard (GtkEntry *entry) static void gtk_entry_delete_cb (GtkEntry *entry) { + GtkEntryPrivate *priv = entry->priv; GtkEditable *editable = GTK_EDITABLE (entry); gint start, end; - if (entry->editable) + if (priv->editable) { if (gtk_editable_get_selection_bounds (editable, &start, &end)) gtk_editable_delete_text (editable, start, end); @@ -5119,7 +5183,9 @@ gtk_entry_delete_cb (GtkEntry *entry) static void gtk_entry_toggle_overwrite (GtkEntry *entry) { - entry->overwrite_mode = !entry->overwrite_mode; + GtkEntryPrivate *priv = entry->priv; + + priv->overwrite_mode = !priv->overwrite_mode; gtk_entry_pend_cursor_blink (entry); gtk_widget_queue_draw (GTK_WIDGET (entry)); } @@ -5133,6 +5199,7 @@ gtk_entry_select_all (GtkEntry *entry) static void gtk_entry_real_activate (GtkEntry *entry) { + GtkEntryPrivate *priv = entry->priv; GtkWindow *window; GtkWidget *default_widget, *focus_widget; GtkWidget *toplevel; @@ -5140,7 +5207,7 @@ gtk_entry_real_activate (GtkEntry *entry) widget = GTK_WIDGET (entry); - if (entry->activates_default) + if (priv->activates_default) { toplevel = gtk_widget_get_toplevel (widget); if (GTK_IS_WINDOW (toplevel)) @@ -5174,7 +5241,9 @@ gtk_entry_commit_cb (GtkIMContext *context, const gchar *str, GtkEntry *entry) { - if (entry->editable) + GtkEntryPrivate *priv = entry->priv; + + if (priv->editable) gtk_entry_enter_text (entry, str); } @@ -5182,18 +5251,20 @@ static void gtk_entry_preedit_changed_cb (GtkIMContext *context, GtkEntry *entry) { - if (entry->editable) + GtkEntryPrivate *priv = entry->priv; + + if (priv->editable) { gchar *preedit_string; gint cursor_pos; - - gtk_im_context_get_preedit_string (entry->im_context, + + gtk_im_context_get_preedit_string (priv->im_context, &preedit_string, NULL, &cursor_pos); g_signal_emit (entry, signals[PREEDIT_CHANGED], 0, preedit_string); - entry->preedit_length = strlen (preedit_string); + priv->preedit_length = strlen (preedit_string); cursor_pos = CLAMP (cursor_pos, 0, g_utf8_strlen (preedit_string, -1)); - entry->preedit_cursor = cursor_pos; + priv->preedit_cursor = cursor_pos; g_free (preedit_string); gtk_entry_recompute (entry); @@ -5202,14 +5273,15 @@ gtk_entry_preedit_changed_cb (GtkIMContext *context, static gboolean gtk_entry_retrieve_surrounding_cb (GtkIMContext *context, - GtkEntry *entry) + GtkEntry *entry) { + GtkEntryPrivate *priv = entry->priv; gchar *text; /* XXXX ??? does this even make sense when text is not visible? Should we return FALSE? */ text = gtk_entry_get_display_text (entry, 0, -1); gtk_im_context_set_surrounding (context, text, strlen (text), /* Length in bytes */ - g_utf8_offset_to_pointer (text, entry->current_pos) - text); + g_utf8_offset_to_pointer (text, priv->current_pos) - text); g_free (text); return TRUE; @@ -5221,10 +5293,12 @@ gtk_entry_delete_surrounding_cb (GtkIMContext *slave, gint n_chars, GtkEntry *entry) { - if (entry->editable) + GtkEntryPrivate *priv = entry->priv; + + if (priv->editable) gtk_editable_delete_text (GTK_EDITABLE (entry), - entry->current_pos + offset, - entry->current_pos + offset + n_chars); + priv->current_pos + offset, + priv->current_pos + offset + n_chars); return TRUE; } @@ -5237,29 +5311,30 @@ static void gtk_entry_enter_text (GtkEntry *entry, const gchar *str) { + GtkEntryPrivate *priv = entry->priv; GtkEditable *editable = GTK_EDITABLE (entry); gint tmp_pos; gboolean old_need_im_reset; - old_need_im_reset = entry->need_im_reset; - entry->need_im_reset = FALSE; + old_need_im_reset = priv->need_im_reset; + priv->need_im_reset = FALSE; if (gtk_editable_get_selection_bounds (editable, NULL, NULL)) gtk_editable_delete_selection (editable); else { - if (entry->overwrite_mode) + if (priv->overwrite_mode) gtk_entry_delete_from_cursor (entry, GTK_DELETE_CHARS, 1); } - tmp_pos = entry->current_pos; + tmp_pos = priv->current_pos; gtk_editable_insert_text (editable, str, strlen (str), &tmp_pos); gtk_editable_set_position (editable, tmp_pos); - entry->need_im_reset = old_need_im_reset; + priv->need_im_reset = old_need_im_reset; } -/* All changes to entry->current_pos and entry->selection_bound +/* All changes to priv->current_pos and priv->selection_bound * should go through this function. */ static void @@ -5267,23 +5342,24 @@ gtk_entry_set_positions (GtkEntry *entry, gint current_pos, gint selection_bound) { + GtkEntryPrivate *priv = entry->priv; gboolean changed = FALSE; g_object_freeze_notify (G_OBJECT (entry)); if (current_pos != -1 && - entry->current_pos != current_pos) + priv->current_pos != current_pos) { - entry->current_pos = current_pos; + priv->current_pos = current_pos; changed = TRUE; g_object_notify (G_OBJECT (entry), "cursor-position"); } if (selection_bound != -1 && - entry->selection_bound != selection_bound) + priv->selection_bound != selection_bound) { - entry->selection_bound = selection_bound; + priv->selection_bound = selection_bound; changed = TRUE; g_object_notify (G_OBJECT (entry), "selection-bound"); @@ -5301,16 +5377,19 @@ gtk_entry_set_positions (GtkEntry *entry, static void gtk_entry_reset_layout (GtkEntry *entry) { - if (entry->cached_layout) + GtkEntryPrivate *priv = entry->priv; + + if (priv->cached_layout) { - g_object_unref (entry->cached_layout); - entry->cached_layout = NULL; + g_object_unref (priv->cached_layout); + priv->cached_layout = NULL; } } static void update_im_cursor_location (GtkEntry *entry) { + GtkEntryPrivate *priv = entry->priv; GdkRectangle area; gint strong_x; gint strong_xoffset; @@ -5319,7 +5398,7 @@ update_im_cursor_location (GtkEntry *entry) gtk_entry_get_cursor_locations (entry, CURSOR_STANDARD, &strong_x, NULL); gtk_entry_get_text_area_size (entry, NULL, NULL, &area_width, &area_height); - strong_xoffset = strong_x - entry->scroll_offset; + strong_xoffset = strong_x - priv->scroll_offset; if (strong_xoffset < 0) { strong_xoffset = 0; @@ -5333,18 +5412,17 @@ update_im_cursor_location (GtkEntry *entry) area.width = 0; area.height = area_height; - gtk_im_context_set_cursor_location (entry->im_context, &area); + gtk_im_context_set_cursor_location (priv->im_context, &area); } static gboolean recompute_idle_func (gpointer data) { - GtkEntry *entry; + GtkEntry *entry = GTK_ENTRY (data); + GtkEntryPrivate *priv = entry->priv; - entry = GTK_ENTRY (data); + priv->recompute_idle = 0; - entry->recompute_idle = 0; - if (gtk_widget_has_screen (GTK_WIDGET (entry))) { gtk_entry_adjust_scroll (entry); @@ -5359,12 +5437,14 @@ recompute_idle_func (gpointer data) static void gtk_entry_recompute (GtkEntry *entry) { + GtkEntryPrivate *priv = entry->priv; + gtk_entry_reset_layout (entry); gtk_entry_check_cursor_blink (entry); - - if (!entry->recompute_idle) + + if (!priv->recompute_idle) { - entry->recompute_idle = gdk_threads_add_idle_full (G_PRIORITY_HIGH_IDLE + 15, /* between resize and redraw */ + priv->recompute_idle = gdk_threads_add_idle_full (G_PRIORITY_HIGH_IDLE + 15, /* between resize and redraw */ recompute_idle_func, entry, NULL); } } @@ -5373,6 +5453,7 @@ static PangoLayout * gtk_entry_create_layout (GtkEntry *entry, gboolean include_preedit) { + GtkEntryPrivate *priv = entry->priv; GtkWidget *widget = GTK_WIDGET (entry); PangoLayout *layout = gtk_widget_create_pango_layout (widget, NULL); PangoAttrList *tmp_attrs = pango_attr_list_new (); @@ -5391,16 +5472,16 @@ gtk_entry_create_layout (GtkEntry *entry, if (include_preedit) { - gtk_im_context_get_preedit_string (entry->im_context, + gtk_im_context_get_preedit_string (priv->im_context, &preedit_string, &preedit_attrs, NULL); - preedit_length = entry->preedit_length; + preedit_length = priv->preedit_length; } if (preedit_length) { GString *tmp_string = g_string_new (display); - gint cursor_index = g_utf8_offset_to_pointer (display, entry->current_pos) - display; - + gint cursor_index = g_utf8_offset_to_pointer (display, priv->current_pos) - display; + g_string_insert (tmp_string, cursor_index, preedit_string); pango_layout_set_text (layout, tmp_string->str, tmp_string->len); @@ -5442,7 +5523,7 @@ gtk_entry_create_layout (GtkEntry *entry, pango_context_set_base_dir (gtk_widget_get_pango_context (widget), pango_dir); - entry->resolved_dir = pango_dir; + priv->resolved_dir = pango_dir; pango_layout_set_text (layout, display, n_bytes); } @@ -5464,17 +5545,19 @@ static PangoLayout * gtk_entry_ensure_layout (GtkEntry *entry, gboolean include_preedit) { - if (entry->preedit_length > 0 && - !include_preedit != !entry->cache_includes_preedit) + GtkEntryPrivate *priv = entry->priv; + + if (priv->preedit_length > 0 && + !include_preedit != !priv->cache_includes_preedit) gtk_entry_reset_layout (entry); - if (!entry->cached_layout) + if (!priv->cached_layout) { - entry->cached_layout = gtk_entry_create_layout (entry, include_preedit); - entry->cache_includes_preedit = include_preedit; + priv->cached_layout = gtk_entry_create_layout (entry, include_preedit); + priv->cache_includes_preedit = include_preedit; } - - return entry->cached_layout; + + return priv->cached_layout; } static void @@ -5482,6 +5565,7 @@ get_layout_position (GtkEntry *entry, gint *x, gint *y) { + GtkEntryPrivate *priv = entry->priv; PangoLayout *layout; PangoRectangle logical_rect; gint area_width, area_height; @@ -5500,9 +5584,9 @@ get_layout_position (GtkEntry *entry, pango_layout_line_get_extents (line, NULL, &logical_rect); /* Align primarily for locale's ascent/descent */ - y_pos = ((area_height - entry->ascent - entry->descent) / 2 + - entry->ascent + logical_rect.y); - + y_pos = ((area_height - priv->ascent - priv->descent) / 2 + + priv->ascent + logical_rect.y); + /* Now see if we need to adjust to fit in actual drawn string */ if (logical_rect.height > area_height) y_pos = (area_height - logical_rect.height) / 2; @@ -5514,15 +5598,18 @@ get_layout_position (GtkEntry *entry, y_pos = inner_border.top + y_pos / PANGO_SCALE; if (x) - *x = inner_border.left - entry->scroll_offset; + *x = inner_border.left - priv->scroll_offset; if (y) *y = y_pos; } static void -draw_text_with_color (GtkEntry *entry, cairo_t *cr, GdkColor *default_color) +draw_text_with_color (GtkEntry *entry, + cairo_t *cr, + GdkRGBA *default_color) { + GtkEntryPrivate *priv = entry->priv; PangoLayout *layout = gtk_entry_ensure_layout (entry, TRUE); GtkWidget *widget; gint x, y; @@ -5535,7 +5622,7 @@ draw_text_with_color (GtkEntry *entry, cairo_t *cr, GdkColor *default_color) get_layout_position (entry, &x, &y); cairo_move_to (cr, x, y); - gdk_cairo_set_source_color (cr, default_color); + gdk_cairo_set_source_rgba (cr, default_color); pango_cairo_show_layout (cr, layout); if (gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), &start_pos, &end_pos)) @@ -5543,42 +5630,39 @@ draw_text_with_color (GtkEntry *entry, cairo_t *cr, GdkColor *default_color) gint *ranges; gint n_ranges, i; PangoRectangle logical_rect; - GdkColor *selection_color, *text_color; + GdkRGBA selection_color, text_color; GtkBorder inner_border; - GtkStyle *style; + GtkStyleContext *context; + GtkStateFlags state; + context = gtk_widget_get_style_context (widget); pango_layout_get_pixel_extents (layout, NULL, &logical_rect); gtk_entry_get_pixel_ranges (entry, &ranges, &n_ranges); - style = gtk_widget_get_style (widget); + state = GTK_STATE_FLAG_SELECTED; if (gtk_widget_has_focus (widget)) - { - selection_color = &style->base [GTK_STATE_SELECTED]; - text_color = &style->text [GTK_STATE_SELECTED]; - } - else - { - selection_color = &style->base [GTK_STATE_ACTIVE]; - text_color = &style->text [GTK_STATE_ACTIVE]; - } + state |= GTK_STATE_FLAG_FOCUSED; + + gtk_style_context_get_background_color (context, state, &selection_color); + gtk_style_context_get_color (context, state, &text_color); _gtk_entry_effective_inner_border (entry, &inner_border); for (i = 0; i < n_ranges; ++i) cairo_rectangle (cr, - inner_border.left - entry->scroll_offset + ranges[2 * i], + inner_border.left - priv->scroll_offset + ranges[2 * i], y, ranges[2 * i + 1], logical_rect.height); cairo_clip (cr); - gdk_cairo_set_source_color (cr, selection_color); + gdk_cairo_set_source_rgba (cr, &selection_color); cairo_paint (cr); cairo_move_to (cr, x, y); - gdk_cairo_set_source_color (cr, text_color); + gdk_cairo_set_source_rgba (cr, &text_color); pango_cairo_show_layout (cr, layout); g_free (ranges); @@ -5587,80 +5671,89 @@ draw_text_with_color (GtkEntry *entry, cairo_t *cr, GdkColor *default_color) } static void -gtk_entry_draw_text (GtkEntry *entry) +gtk_entry_draw_text (GtkEntry *entry, + cairo_t *cr) { + GtkEntryPrivate *priv = entry->priv; GtkWidget *widget = GTK_WIDGET (entry); - cairo_t *cr; + GtkStateFlags state = 0; + GdkRGBA text_color, bar_text_color; + GtkStyleContext *context; + gint pos_x, pos_y; + gint width, height; + gint progress_x, progress_y, progress_width, progress_height; + gint clip_width, clip_height; /* Nothing to display at all */ if (gtk_entry_get_display_mode (entry) == DISPLAY_BLANK) return; - - if (gtk_widget_is_drawable (widget)) + + state = gtk_widget_get_state_flags (widget); + context = gtk_widget_get_style_context (widget); + + gtk_style_context_get_color (context, state, &text_color); + + /* Get foreground color for progressbars */ + gtk_style_context_save (context); + gtk_style_context_add_class (context, GTK_STYLE_CLASS_PROGRESSBAR); + gtk_style_context_get_color (context, state, &bar_text_color); + gtk_style_context_restore (context); + + get_progress_area (widget, + &progress_x, &progress_y, + &progress_width, &progress_height); + + clip_width = gdk_window_get_width (priv->text_area); + clip_height = gdk_window_get_height (priv->text_area); + cairo_rectangle (cr, 0, 0, clip_width, clip_height); + cairo_clip (cr); + + /* If the color is the same, or the progress area has a zero + * size, then we only need to draw once. */ + if (gdk_rgba_equal (&text_color, &bar_text_color) || + ((progress_width == 0) || (progress_height == 0))) { - GtkStateType state; - GtkStyle *style; - GdkColor text_color, bar_text_color; - gint pos_x, pos_y; - gint width, height; - gint progress_x, progress_y, progress_width, progress_height; - - state = GTK_STATE_SELECTED; - if (!gtk_widget_get_sensitive (widget)) - state = GTK_STATE_INSENSITIVE; - style = gtk_widget_get_style (widget); - text_color = style->text[gtk_widget_get_state (widget)]; - bar_text_color = style->fg[state]; - - get_progress_area (widget, - &progress_x, &progress_y, - &progress_width, &progress_height); - - cr = gdk_cairo_create (entry->text_area); - - /* If the color is the same, or the progress area has a zero - * size, then we only need to draw once. */ - if ((text_color.pixel == bar_text_color.pixel) || - ((progress_width == 0) || (progress_height == 0))) - { - draw_text_with_color (entry, cr, &text_color); - } - else - { - gdk_drawable_get_size (entry->text_area, &width, &height); + draw_text_with_color (entry, cr, &text_color); + } + else + { + width = gdk_window_get_width (priv->text_area); + height = gdk_window_get_height (priv->text_area); - cairo_rectangle (cr, 0, 0, width, height); - cairo_clip (cr); - cairo_save (cr); + cairo_save (cr); - cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD); - cairo_rectangle (cr, 0, 0, width, height); + cairo_rectangle (cr, 0, 0, width, height); + cairo_clip (cr); + cairo_save (cr); - gdk_window_get_position (entry->text_area, &pos_x, &pos_y); - progress_x -= pos_x; - progress_y -= pos_y; + cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD); + cairo_rectangle (cr, 0, 0, width, height); - cairo_rectangle (cr, progress_x, progress_y, - progress_width, progress_height); - cairo_clip (cr); - cairo_set_fill_rule (cr, CAIRO_FILL_RULE_WINDING); - - draw_text_with_color (entry, cr, &text_color); - cairo_restore (cr); + gdk_window_get_position (priv->text_area, &pos_x, &pos_y); + progress_x -= pos_x; + progress_y -= pos_y; - cairo_rectangle (cr, progress_x, progress_y, - progress_width, progress_height); - cairo_clip (cr); + cairo_rectangle (cr, progress_x, progress_y, + progress_width, progress_height); + cairo_clip (cr); + cairo_set_fill_rule (cr, CAIRO_FILL_RULE_WINDING); + + draw_text_with_color (entry, cr, &text_color); + cairo_restore (cr); - draw_text_with_color (entry, cr, &bar_text_color); - } + cairo_rectangle (cr, progress_x, progress_y, + progress_width, progress_height); + cairo_clip (cr); + + draw_text_with_color (entry, cr, &bar_text_color); - cairo_destroy (cr); + cairo_restore (cr); } } static void draw_insertion_cursor (GtkEntry *entry, + cairo_t *cr, GdkRectangle *cursor_location, gboolean is_primary, PangoDirection direction, @@ -5674,131 +5767,136 @@ draw_insertion_cursor (GtkEntry *entry, else text_dir = GTK_TEXT_DIR_RTL; - gtk_draw_insertion_cursor (widget, entry->text_area, NULL, + gtk_draw_insertion_cursor (widget, cr, cursor_location, is_primary, text_dir, draw_arrow); } static void gtk_entry_draw_cursor (GtkEntry *entry, + cairo_t *cr, CursorType type) { + GtkEntryPrivate *priv = entry->priv; GtkWidget *widget = GTK_WIDGET (entry); GdkKeymap *keymap = gdk_keymap_get_for_display (gtk_widget_get_display (GTK_WIDGET (entry))); PangoDirection keymap_direction = gdk_keymap_get_direction (keymap); - - if (gtk_widget_is_drawable (widget)) - { - GdkRectangle cursor_location; - gboolean split_cursor; - PangoRectangle cursor_rect; - GtkBorder inner_border; - gint xoffset; - gint text_area_height; - gint cursor_index; - gboolean block; - gboolean block_at_line_end; - PangoLayout *layout; - const char *text; + GdkRectangle cursor_location; + gboolean split_cursor; + PangoRectangle cursor_rect; + GtkBorder inner_border; + gint xoffset; + gint text_area_height; + gint cursor_index; + gboolean block; + gboolean block_at_line_end; + PangoLayout *layout; + const char *text; - _gtk_entry_effective_inner_border (entry, &inner_border); + _gtk_entry_effective_inner_border (entry, &inner_border); - xoffset = inner_border.left - entry->scroll_offset; + xoffset = inner_border.left - priv->scroll_offset; - gdk_drawable_get_size (entry->text_area, NULL, &text_area_height); + text_area_height = gdk_window_get_height (priv->text_area); - layout = gtk_entry_ensure_layout (entry, TRUE); - text = pango_layout_get_text (layout); - cursor_index = g_utf8_offset_to_pointer (text, entry->current_pos + entry->preedit_cursor) - text; - if (!entry->overwrite_mode) - block = FALSE; - else - block = _gtk_text_util_get_block_cursor_location (layout, - cursor_index, &cursor_rect, &block_at_line_end); + layout = gtk_entry_ensure_layout (entry, TRUE); + text = pango_layout_get_text (layout); + cursor_index = g_utf8_offset_to_pointer (text, priv->current_pos + priv->preedit_cursor) - text; + if (!priv->overwrite_mode) + block = FALSE; + else + block = _gtk_text_util_get_block_cursor_location (layout, + cursor_index, &cursor_rect, &block_at_line_end); - if (!block) - { - gint strong_x, weak_x; - PangoDirection dir1 = PANGO_DIRECTION_NEUTRAL; - PangoDirection dir2 = PANGO_DIRECTION_NEUTRAL; - gint x1 = 0; - gint x2 = 0; + if (!block) + { + gint strong_x, weak_x; + PangoDirection dir1 = PANGO_DIRECTION_NEUTRAL; + PangoDirection dir2 = PANGO_DIRECTION_NEUTRAL; + gint x1 = 0; + gint x2 = 0; - gtk_entry_get_cursor_locations (entry, type, &strong_x, &weak_x); + gtk_entry_get_cursor_locations (entry, type, &strong_x, &weak_x); - g_object_get (gtk_widget_get_settings (widget), - "gtk-split-cursor", &split_cursor, - NULL); + g_object_get (gtk_widget_get_settings (widget), + "gtk-split-cursor", &split_cursor, + NULL); - dir1 = entry->resolved_dir; - - if (split_cursor) - { - x1 = strong_x; + dir1 = priv->resolved_dir; + + if (split_cursor) + { + x1 = strong_x; - if (weak_x != strong_x) - { - dir2 = (entry->resolved_dir == PANGO_DIRECTION_LTR) ? PANGO_DIRECTION_RTL : PANGO_DIRECTION_LTR; - x2 = weak_x; - } - } - else + if (weak_x != strong_x) { - if (keymap_direction == entry->resolved_dir) - x1 = strong_x; - else - x1 = weak_x; + dir2 = (priv->resolved_dir == PANGO_DIRECTION_LTR) ? PANGO_DIRECTION_RTL : PANGO_DIRECTION_LTR; + x2 = weak_x; } + } + else + { + if (keymap_direction == priv->resolved_dir) + x1 = strong_x; + else + x1 = weak_x; + } - cursor_location.x = xoffset + x1; - cursor_location.y = inner_border.top; - cursor_location.width = 0; - cursor_location.height = text_area_height - inner_border.top - inner_border.bottom; + cursor_location.x = xoffset + x1; + cursor_location.y = inner_border.top; + cursor_location.width = 0; + cursor_location.height = text_area_height - inner_border.top - inner_border.bottom; - draw_insertion_cursor (entry, - &cursor_location, TRUE, dir1, - dir2 != PANGO_DIRECTION_NEUTRAL); - - if (dir2 != PANGO_DIRECTION_NEUTRAL) - { - cursor_location.x = xoffset + x2; - draw_insertion_cursor (entry, - &cursor_location, FALSE, dir2, - TRUE); - } - } - else /* overwrite_mode */ + draw_insertion_cursor (entry, cr, + &cursor_location, TRUE, dir1, + dir2 != PANGO_DIRECTION_NEUTRAL); + + if (dir2 != PANGO_DIRECTION_NEUTRAL) { - GdkColor cursor_color; - GdkRectangle rect; - cairo_t *cr; - gint x, y; + cursor_location.x = xoffset + x2; + draw_insertion_cursor (entry, cr, + &cursor_location, FALSE, dir2, + TRUE); + } + } + else /* overwrite_mode */ + { + GdkColor cursor_color; + GdkRectangle rect; + gint x, y; - get_layout_position (entry, &x, &y); + cairo_save (cr); - rect.x = PANGO_PIXELS (cursor_rect.x) + x; - rect.y = PANGO_PIXELS (cursor_rect.y) + y; - rect.width = PANGO_PIXELS (cursor_rect.width); - rect.height = PANGO_PIXELS (cursor_rect.height); + get_layout_position (entry, &x, &y); - cr = gdk_cairo_create (entry->text_area); + rect.x = PANGO_PIXELS (cursor_rect.x) + x; + rect.y = PANGO_PIXELS (cursor_rect.y) + y; + rect.width = PANGO_PIXELS (cursor_rect.width); + rect.height = PANGO_PIXELS (cursor_rect.height); - _gtk_widget_get_cursor_color (widget, &cursor_color); - gdk_cairo_set_source_color (cr, &cursor_color); - gdk_cairo_rectangle (cr, &rect); - cairo_fill (cr); + _gtk_widget_get_cursor_color (widget, &cursor_color); + gdk_cairo_set_source_color (cr, &cursor_color); + gdk_cairo_rectangle (cr, &rect); + cairo_fill (cr); - if (!block_at_line_end) - { - gdk_cairo_rectangle (cr, &rect); - cairo_clip (cr); - cairo_move_to (cr, x, y); - gdk_cairo_set_source_color (cr, >k_widget_get_style (widget)->base[gtk_widget_get_state (widget)]); - pango_cairo_show_layout (cr, layout); - } + if (!block_at_line_end) + { + GtkStyleContext *context; + GtkStateFlags state; + GdkRGBA color; + + context = gtk_widget_get_style_context (widget); + state = gtk_widget_get_state_flags (widget); + gtk_style_context_get_background_color (context, state, &color); - cairo_destroy (cr); + gdk_cairo_rectangle (cr, &rect); + cairo_clip (cr); + cairo_move_to (cr, x, y); + gdk_cairo_set_source_rgba (cr, &color); + pango_cairo_show_layout (cr, layout); } + + cairo_restore (cr); } } @@ -5806,16 +5904,19 @@ static void gtk_entry_queue_draw (GtkEntry *entry) { if (gtk_widget_is_drawable (GTK_WIDGET (entry))) - gdk_window_invalidate_rect (entry->text_area, NULL, FALSE); + gdk_window_invalidate_rect (gtk_widget_get_window (GTK_WIDGET (entry)), + NULL, FALSE); } void _gtk_entry_reset_im_context (GtkEntry *entry) { - if (entry->need_im_reset) + GtkEntryPrivate *priv = entry->priv; + + if (priv->need_im_reset) { - entry->need_im_reset = FALSE; - gtk_im_context_reset (entry->im_context); + priv->need_im_reset = FALSE; + gtk_im_context_reset (priv->im_context); } } @@ -5862,16 +5963,26 @@ gboolean gtk_entry_im_context_filter_keypress (GtkEntry *entry, GdkEventKey *event) { + GtkEntryPrivate *priv; + g_return_val_if_fail (GTK_IS_ENTRY (entry), FALSE); - return gtk_im_context_filter_keypress (entry->im_context, event); + priv = entry->priv; + + return gtk_im_context_filter_keypress (priv->im_context, event); } +GtkIMContext* +_gtk_entry_get_im_context (GtkEntry *entry) +{ + return entry->priv->im_context; +} static gint gtk_entry_find_position (GtkEntry *entry, gint x) { + GtkEntryPrivate *priv = entry->priv; PangoLayout *layout; PangoLayoutLine *line; gint index; @@ -5882,15 +5993,15 @@ gtk_entry_find_position (GtkEntry *entry, layout = gtk_entry_ensure_layout (entry, TRUE); text = pango_layout_get_text (layout); - cursor_index = g_utf8_offset_to_pointer (text, entry->current_pos) - text; - + cursor_index = g_utf8_offset_to_pointer (text, priv->current_pos) - text; + line = pango_layout_get_lines_readonly (layout)->data; pango_layout_line_x_to_index (line, x * PANGO_SCALE, &index, &trailing); - if (index >= cursor_index && entry->preedit_length) + if (index >= cursor_index && priv->preedit_length) { - if (index >= cursor_index + entry->preedit_length) - index -= entry->preedit_length; + if (index >= cursor_index + priv->preedit_length) + index -= priv->preedit_length; else { index = cursor_index; @@ -5910,6 +6021,7 @@ gtk_entry_get_cursor_locations (GtkEntry *entry, gint *strong_x, gint *weak_x) { + GtkEntryPrivate *priv = entry->priv; DisplayMode mode = gtk_entry_get_display_mode (entry); /* Nothing to display at all, so no cursor is relevant */ @@ -5930,20 +6042,20 @@ gtk_entry_get_cursor_locations (GtkEntry *entry, if (type == CURSOR_STANDARD) { - index = g_utf8_offset_to_pointer (text, entry->current_pos + entry->preedit_cursor) - text; + index = g_utf8_offset_to_pointer (text, priv->current_pos + priv->preedit_cursor) - text; } else /* type == CURSOR_DND */ { - index = g_utf8_offset_to_pointer (text, entry->dnd_position) - text; + index = g_utf8_offset_to_pointer (text, priv->dnd_position) - text; - if (entry->dnd_position > entry->current_pos) + if (priv->dnd_position > priv->current_pos) { if (mode == DISPLAY_NORMAL) - index += entry->preedit_length; + index += priv->preedit_length; else { gint preedit_len_chars = g_utf8_strlen (text, -1) - gtk_entry_buffer_get_length (get_buffer (entry)); - index += preedit_len_chars * g_unichar_to_utf8 (entry->invisible_char, NULL); + index += preedit_len_chars * g_unichar_to_utf8 (priv->invisible_char, NULL); } } } @@ -5961,7 +6073,7 @@ gtk_entry_get_cursor_locations (GtkEntry *entry, static void gtk_entry_adjust_scroll (GtkEntry *entry) { - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry); + GtkEntryPrivate *priv = entry->priv; gint min_offset, max_offset; gint text_area_width, text_width; GtkBorder inner_border; @@ -5977,7 +6089,7 @@ gtk_entry_adjust_scroll (GtkEntry *entry) _gtk_entry_effective_inner_border (entry, &inner_border); - gdk_drawable_get_size (entry->text_area, &text_area_width, NULL); + text_area_width = gdk_window_get_width (priv->text_area); text_area_width -= inner_border.left + inner_border.right; if (text_area_width < 0) text_area_width = 0; @@ -5989,7 +6101,7 @@ gtk_entry_adjust_scroll (GtkEntry *entry) /* Display as much text as we can */ - if (entry->resolved_dir == PANGO_DIRECTION_LTR) + if (priv->resolved_dir == PANGO_DIRECTION_LTR) xalign = priv->xalign; else xalign = 1.0 - priv->xalign; @@ -6007,7 +6119,7 @@ gtk_entry_adjust_scroll (GtkEntry *entry) max_offset = min_offset; } - entry->scroll_offset = CLAMP (entry->scroll_offset, min_offset, max_offset); + priv->scroll_offset = CLAMP (priv->scroll_offset, min_offset, max_offset); /* And make sure cursors are on screen. Note that the cursor is * actually drawn one pixel into the INNER_BORDER space on @@ -6025,29 +6137,29 @@ gtk_entry_adjust_scroll (GtkEntry *entry) gtk_entry_get_cursor_locations (entry, CURSOR_STANDARD, &strong_x, &weak_x); - strong_xoffset = strong_x - entry->scroll_offset; + strong_xoffset = strong_x - priv->scroll_offset; if (strong_xoffset < 0) { - entry->scroll_offset += strong_xoffset; + priv->scroll_offset += strong_xoffset; strong_xoffset = 0; } else if (strong_xoffset > text_area_width) { - entry->scroll_offset += strong_xoffset - text_area_width; + priv->scroll_offset += strong_xoffset - text_area_width; strong_xoffset = text_area_width; } - weak_xoffset = weak_x - entry->scroll_offset; + weak_xoffset = weak_x - priv->scroll_offset; if (weak_xoffset < 0 && strong_xoffset - weak_xoffset <= text_area_width) { - entry->scroll_offset += weak_xoffset; + priv->scroll_offset += weak_xoffset; } else if (weak_xoffset > text_area_width && strong_xoffset - (weak_xoffset - text_area_width) >= 0) { - entry->scroll_offset += weak_xoffset - text_area_width; + priv->scroll_offset += weak_xoffset - text_area_width; } g_object_notify (G_OBJECT (entry), "scroll-offset"); @@ -6056,6 +6168,7 @@ gtk_entry_adjust_scroll (GtkEntry *entry) static void gtk_entry_move_adjustments (GtkEntry *entry) { + GtkWidget *widget = GTK_WIDGET (entry); GtkAllocation allocation; GtkAdjustment *adjustment; PangoContext *context; @@ -6067,7 +6180,7 @@ gtk_entry_move_adjustments (GtkEntry *entry) if (!adjustment) return; - gtk_widget_get_allocation (&(entry->widget), &allocation); + gtk_widget_get_allocation (widget, &allocation); /* Cursor position, layout offset, border width, and widget allocation */ gtk_entry_get_cursor_locations (entry, CURSOR_STANDARD, &x, NULL); @@ -6076,9 +6189,9 @@ gtk_entry_move_adjustments (GtkEntry *entry) x += allocation.x + layout_x + border_x; /* Approximate width of a char, so user can see what is ahead/behind */ - context = gtk_widget_get_pango_context (GTK_WIDGET (entry)); + context = gtk_widget_get_pango_context (widget); metrics = pango_context_get_metrics (context, - gtk_widget_get_style (&(entry->widget))->font_desc, + gtk_widget_get_style (widget)->font_desc, pango_context_get_language (context)); char_width = pango_font_metrics_get_approximate_char_width (metrics) / PANGO_SCALE; @@ -6093,6 +6206,7 @@ gtk_entry_move_visually (GtkEntry *entry, gint start, gint count) { + GtkEntryPrivate *priv = entry->priv; gint index; PangoLayout *layout = gtk_entry_ensure_layout (entry, FALSE); const gchar *text; @@ -6118,7 +6232,7 @@ gtk_entry_move_visually (GtkEntry *entry, GdkKeymap *keymap = gdk_keymap_get_for_display (gtk_widget_get_display (GTK_WIDGET (entry))); PangoDirection keymap_direction = gdk_keymap_get_direction (keymap); - strong = keymap_direction == entry->resolved_dir; + strong = keymap_direction == priv->resolved_dir; } if (count > 0) @@ -6262,6 +6376,7 @@ gtk_entry_move_backward_word (GtkEntry *entry, static void gtk_entry_delete_whitespace (GtkEntry *entry) { + GtkEntryPrivate *priv = entry->priv; PangoLayout *layout = gtk_entry_ensure_layout (entry, FALSE); PangoLogAttr *log_attrs; gint n_attrs; @@ -6269,7 +6384,7 @@ gtk_entry_delete_whitespace (GtkEntry *entry) pango_layout_get_log_attrs (layout, &log_attrs, &n_attrs); - start = end = entry->current_pos; + start = end = priv->current_pos; while (start > 0 && log_attrs[start-1].is_white) start--; @@ -6287,8 +6402,9 @@ gtk_entry_delete_whitespace (GtkEntry *entry) static void gtk_entry_select_word (GtkEntry *entry) { - gint start_pos = gtk_entry_move_backward_word (entry, entry->current_pos, TRUE); - gint end_pos = gtk_entry_move_forward_word (entry, entry->current_pos, TRUE); + GtkEntryPrivate *priv = entry->priv; + gint start_pos = gtk_entry_move_backward_word (entry, priv->current_pos, TRUE); + gint end_pos = gtk_entry_move_forward_word (entry, priv->current_pos, TRUE); gtk_editable_select_region (GTK_EDITABLE (entry), start_pos, end_pos); } @@ -6318,9 +6434,9 @@ paste_received (GtkClipboard *clipboard, { GtkEntry *entry = GTK_ENTRY (data); GtkEditable *editable = GTK_EDITABLE (entry); - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry); - - if (entry->button == 2) + GtkEntryPrivate *priv = entry->priv; + + if (priv->button == 2) { gint pos, start, end; pos = priv->insert_pos; @@ -6338,12 +6454,12 @@ paste_received (GtkClipboard *clipboard, completion = gtk_entry_get_completion (entry); - if (entry->truncate_multiline) + if (priv->truncate_multiline) length = truncate_multiline (text); /* only complete if the selection is at the end */ popup_completion = (gtk_entry_buffer_get_length (get_buffer (entry)) == - MAX (entry->current_pos, entry->selection_bound)); + MAX (priv->current_pos, priv->selection_bound)); if (completion) { @@ -6359,7 +6475,7 @@ paste_received (GtkClipboard *clipboard, if (gtk_editable_get_selection_bounds (editable, &start, &end)) gtk_editable_delete_text (editable, start, end); - pos = entry->current_pos; + pos = priv->current_pos; gtk_editable_insert_text (editable, text, length, &pos); gtk_editable_set_position (editable, pos); g_object_thaw_notify (G_OBJECT (entry)); @@ -6404,8 +6520,9 @@ primary_clear_cb (GtkClipboard *clipboard, gpointer data) { GtkEntry *entry = GTK_ENTRY (data); + GtkEntryPrivate *priv = entry->priv; - gtk_editable_select_region (GTK_EDITABLE (entry), entry->current_pos, entry->current_pos); + gtk_editable_select_region (GTK_EDITABLE (entry), priv->current_pos, priv->current_pos); } static void @@ -6447,7 +6564,7 @@ static void gtk_entry_clear (GtkEntry *entry, GtkEntryIconPosition icon_pos) { - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry); + GtkEntryPrivate *priv = entry->priv; EntryIconInfo *icon_info = priv->icons[icon_pos]; if (!icon_info || icon_info->storage_type == GTK_IMAGE_EMPTY) @@ -6514,12 +6631,12 @@ static void gtk_entry_ensure_pixbuf (GtkEntry *entry, GtkEntryIconPosition icon_pos) { - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry); + GtkEntryPrivate *priv = entry->priv; EntryIconInfo *icon_info = priv->icons[icon_pos]; GtkIconInfo *info; GtkIconTheme *icon_theme; GtkSettings *settings; - GtkStateType state; + GtkStateFlags state; GtkWidget *widget; GdkScreen *screen; gint width, height; @@ -6535,18 +6652,16 @@ gtk_entry_ensure_pixbuf (GtkEntry *entry, case GTK_IMAGE_PIXBUF: break; case GTK_IMAGE_STOCK: - state = gtk_widget_get_state (widget); - gtk_widget_set_state (widget, GTK_STATE_NORMAL); - icon_info->pixbuf = gtk_widget_render_icon (widget, - icon_info->stock_id, - GTK_ICON_SIZE_MENU, - NULL); + state = gtk_widget_get_state_flags (widget); + gtk_widget_set_state_flags (widget, 0, TRUE); + icon_info->pixbuf = gtk_widget_render_icon_pixbuf (widget, + icon_info->stock_id, + GTK_ICON_SIZE_MENU); if (!icon_info->pixbuf) - icon_info->pixbuf = gtk_widget_render_icon (widget, - GTK_STOCK_MISSING_IMAGE, - GTK_ICON_SIZE_MENU, - NULL); - gtk_widget_set_state (widget, state); + icon_info->pixbuf = gtk_widget_render_icon_pixbuf (widget, + GTK_STOCK_MISSING_IMAGE, + GTK_ICON_SIZE_MENU); + gtk_widget_set_state_flags (widget, state, TRUE); break; case GTK_IMAGE_ICON_NAME: @@ -6567,13 +6682,12 @@ gtk_entry_ensure_pixbuf (GtkEntry *entry, if (icon_info->pixbuf == NULL) { - state = gtk_widget_get_state (widget); - gtk_widget_set_state (widget, GTK_STATE_NORMAL); - icon_info->pixbuf = gtk_widget_render_icon (widget, - GTK_STOCK_MISSING_IMAGE, - GTK_ICON_SIZE_MENU, - NULL); - gtk_widget_set_state (widget, state); + state = gtk_widget_get_state_flags (widget); + gtk_widget_set_state_flags (widget, 0, TRUE); + icon_info->pixbuf = gtk_widget_render_icon_pixbuf (widget, + GTK_STOCK_MISSING_IMAGE, + GTK_ICON_SIZE_MENU); + gtk_widget_set_state_flags (widget, state, TRUE); } } break; @@ -6601,13 +6715,12 @@ gtk_entry_ensure_pixbuf (GtkEntry *entry, if (icon_info->pixbuf == NULL) { - state = gtk_widget_get_state (widget); - gtk_widget_set_state (widget, GTK_STATE_NORMAL); - icon_info->pixbuf = gtk_widget_render_icon (widget, - GTK_STOCK_MISSING_IMAGE, - GTK_ICON_SIZE_MENU, - NULL); - gtk_widget_set_state (widget, state); + state = gtk_widget_get_state_flags (widget); + gtk_widget_set_state_flags (widget, 0, TRUE); + icon_info->pixbuf = gtk_widget_render_icon_pixbuf (widget, + GTK_STOCK_MISSING_IMAGE, + GTK_ICON_SIZE_MENU); + gtk_widget_set_state_flags (widget, state, TRUE); } } break; @@ -6658,7 +6771,7 @@ gtk_entry_new_with_buffer (GtkEntryBuffer *buffer) static GtkEntryBuffer* get_buffer (GtkEntry *entry) { - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry); + GtkEntryPrivate *priv = entry->priv; if (priv->buffer == NULL) { @@ -6708,7 +6821,8 @@ gtk_entry_set_buffer (GtkEntry *entry, GObject *obj; g_return_if_fail (GTK_IS_ENTRY (entry)); - priv = GTK_ENTRY_GET_PRIVATE (entry); + + priv = entry->priv; if (buffer) { @@ -6743,28 +6857,51 @@ gtk_entry_set_buffer (GtkEntry *entry, } /** - * gtk_entry_get_text_window: + * gtk_entry_get_text_area: * @entry: a #GtkEntry + * @text_area: Return location for the text area. * - * Returns the #GdkWindow which contains the text. This function is - * useful when drawing something to the entry in an expose-event - * callback because it enables the callback to distinguish between - * the text window and entry's icon windows. + * Gets the area where the entry's text is drawn. This function is + * useful when drawing something to the entry in a draw callback. * - * See also gtk_entry_get_icon_window(). + * If the entry is not realized, @text_area is filled with zeros. * - * Return value: (transfer none): the entry's text window. + * See also gtk_entry_get_icon_area(). * - * Since: 2.20 + * Since: 3.0 **/ -GdkWindow * -gtk_entry_get_text_window (GtkEntry *entry) +void +gtk_entry_get_text_area (GtkEntry *entry, + GdkRectangle *text_area) { - g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL); + GtkEntryPrivate *priv; - return entry->text_area; -} + g_return_if_fail (GTK_IS_ENTRY (entry)); + g_return_if_fail (text_area != NULL); + + priv = entry->priv; + + if (priv->text_area) + { + GtkAllocation allocation; + gint x, y; + + gtk_widget_get_allocation (GTK_WIDGET (entry), &allocation); + gdk_window_get_position (priv->text_area, &x, &y); + text_area->x = x - allocation.x; + text_area->y = y - allocation.y; + text_area->width = gdk_window_get_width (priv->text_area); + text_area->height = gdk_window_get_height (priv->text_area); + } + else + { + text_area->x = 0; + text_area->y = 0; + text_area->width = 0; + text_area->height = 0; + } +} /** * gtk_entry_set_text: @@ -6782,11 +6919,9 @@ gtk_entry_set_text (GtkEntry *entry, { gint tmp_pos; GtkEntryCompletion *completion; - GtkEntryPrivate *priv; g_return_if_fail (GTK_IS_ENTRY (entry)); g_return_if_fail (text != NULL); - priv = GTK_ENTRY_GET_PRIVATE (entry); /* Actually setting the text will affect the cursor and selection; * if the contents don't actually change, this will look odd to the user. @@ -6829,13 +6964,17 @@ void gtk_entry_set_visibility (GtkEntry *entry, gboolean visible) { + GtkEntryPrivate *priv; + g_return_if_fail (GTK_IS_ENTRY (entry)); + priv = entry->priv; + visible = visible != FALSE; - if (entry->visible != visible) + if (priv->visible != visible) { - entry->visible = visible; + priv->visible = visible; g_object_notify (G_OBJECT (entry), "visibility"); gtk_entry_recompute (entry); @@ -6856,7 +6995,7 @@ gtk_entry_get_visibility (GtkEntry *entry) { g_return_val_if_fail (GTK_IS_ENTRY (entry), FALSE); - return entry->visible; + return entry->priv->visible; } /** @@ -6880,7 +7019,7 @@ gtk_entry_set_invisible_char (GtkEntry *entry, g_return_if_fail (GTK_IS_ENTRY (entry)); - priv = GTK_ENTRY_GET_PRIVATE (entry); + priv = entry->priv; if (!priv->invisible_char_set) { @@ -6888,10 +7027,10 @@ gtk_entry_set_invisible_char (GtkEntry *entry, g_object_notify (G_OBJECT (entry), "invisible-char-set"); } - if (ch == entry->invisible_char) + if (ch == priv->invisible_char) return; - entry->invisible_char = ch; + priv->invisible_char = ch; g_object_notify (G_OBJECT (entry), "invisible-char"); gtk_entry_recompute (entry); } @@ -6911,7 +7050,7 @@ gtk_entry_get_invisible_char (GtkEntry *entry) { g_return_val_if_fail (GTK_IS_ENTRY (entry), 0); - return entry->invisible_char; + return entry->priv->invisible_char; } /** @@ -6932,7 +7071,7 @@ gtk_entry_unset_invisible_char (GtkEntry *entry) g_return_if_fail (GTK_IS_ENTRY (entry)); - priv = GTK_ENTRY_GET_PRIVATE (entry); + priv = entry->priv; if (!priv->invisible_char_set) return; @@ -6940,9 +7079,9 @@ gtk_entry_unset_invisible_char (GtkEntry *entry) priv->invisible_char_set = FALSE; ch = find_invisible_char (GTK_WIDGET (entry)); - if (entry->invisible_char != ch) + if (priv->invisible_char != ch) { - entry->invisible_char = ch; + priv->invisible_char = ch; g_object_notify (G_OBJECT (entry), "invisible-char"); } @@ -6963,9 +7102,11 @@ void gtk_entry_set_overwrite_mode (GtkEntry *entry, gboolean overwrite) { + GtkEntryPrivate *priv = entry->priv; + g_return_if_fail (GTK_IS_ENTRY (entry)); - - if (entry->overwrite_mode == overwrite) + + if (priv->overwrite_mode == overwrite) return; gtk_entry_toggle_overwrite (entry); @@ -6988,7 +7129,7 @@ gtk_entry_get_overwrite_mode (GtkEntry *entry) { g_return_val_if_fail (GTK_IS_ENTRY (entry), FALSE); - return entry->overwrite_mode; + return entry->priv->overwrite_mode; } /** @@ -7013,6 +7154,7 @@ G_CONST_RETURN gchar* gtk_entry_get_text (GtkEntry *entry) { g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL); + return gtk_entry_buffer_get_text (get_buffer (entry)); } @@ -7061,6 +7203,7 @@ gint gtk_entry_get_max_length (GtkEntry *entry) { g_return_val_if_fail (GTK_IS_ENTRY (entry), 0); + return gtk_entry_buffer_get_max_length (get_buffer (entry)); } @@ -7086,6 +7229,7 @@ guint16 gtk_entry_get_text_length (GtkEntry *entry) { g_return_val_if_fail (GTK_IS_ENTRY (entry), 0); + return gtk_entry_buffer_get_length (get_buffer (entry)); } @@ -7107,12 +7251,17 @@ void gtk_entry_set_activates_default (GtkEntry *entry, gboolean setting) { + GtkEntryPrivate *priv; + g_return_if_fail (GTK_IS_ENTRY (entry)); + + priv = entry->priv; + setting = setting != FALSE; - if (setting != entry->activates_default) + if (setting != priv->activates_default) { - entry->activates_default = setting; + priv->activates_default = setting; g_object_notify (G_OBJECT (entry), "activates-default"); } } @@ -7130,7 +7279,7 @@ gtk_entry_get_activates_default (GtkEntry *entry) { g_return_val_if_fail (GTK_IS_ENTRY (entry), FALSE); - return entry->activates_default; + return entry->priv->activates_default; } /** @@ -7148,11 +7297,15 @@ void gtk_entry_set_width_chars (GtkEntry *entry, gint n_chars) { + GtkEntryPrivate *priv; + g_return_if_fail (GTK_IS_ENTRY (entry)); - if (entry->width_chars != n_chars) + priv = entry->priv; + + if (priv->width_chars != n_chars) { - entry->width_chars = n_chars; + priv->width_chars = n_chars; g_object_notify (G_OBJECT (entry), "width-chars"); gtk_widget_queue_resize (GTK_WIDGET (entry)); } @@ -7171,7 +7324,7 @@ gtk_entry_get_width_chars (GtkEntry *entry) { g_return_val_if_fail (GTK_IS_ENTRY (entry), 0); - return entry->width_chars; + return entry->priv->width_chars; } /** @@ -7185,15 +7338,19 @@ void gtk_entry_set_has_frame (GtkEntry *entry, gboolean setting) { + GtkEntryPrivate *priv; + g_return_if_fail (GTK_IS_ENTRY (entry)); + priv = entry->priv; + setting = (setting != FALSE); - if (entry->has_frame == setting) + if (priv->has_frame == setting) return; gtk_widget_queue_resize (GTK_WIDGET (entry)); - entry->has_frame = setting; + priv->has_frame = setting; g_object_notify (G_OBJECT (entry), "has-frame"); } @@ -7210,7 +7367,7 @@ gtk_entry_get_has_frame (GtkEntry *entry) { g_return_val_if_fail (GTK_IS_ENTRY (entry), FALSE); - return entry->has_frame; + return entry->priv->has_frame; } /** @@ -7312,20 +7469,23 @@ gint gtk_entry_layout_index_to_text_index (GtkEntry *entry, gint layout_index) { + GtkEntryPrivate *priv; PangoLayout *layout; const gchar *text; gint cursor_index; g_return_val_if_fail (GTK_IS_ENTRY (entry), 0); + priv = entry->priv; + layout = gtk_entry_ensure_layout (entry, TRUE); text = pango_layout_get_text (layout); - cursor_index = g_utf8_offset_to_pointer (text, entry->current_pos) - text; - - if (layout_index >= cursor_index && entry->preedit_length) + cursor_index = g_utf8_offset_to_pointer (text, priv->current_pos) - text; + + if (layout_index >= cursor_index && priv->preedit_length) { - if (layout_index >= cursor_index + entry->preedit_length) - layout_index -= entry->preedit_length; + if (layout_index >= cursor_index + priv->preedit_length) + layout_index -= priv->preedit_length; else layout_index = cursor_index; } @@ -7348,17 +7508,21 @@ gint gtk_entry_text_index_to_layout_index (GtkEntry *entry, gint text_index) { + GtkEntryPrivate *priv; PangoLayout *layout; const gchar *text; gint cursor_index; + g_return_val_if_fail (GTK_IS_ENTRY (entry), 0); + priv = entry->priv; + layout = gtk_entry_ensure_layout (entry, TRUE); text = pango_layout_get_text (layout); - cursor_index = g_utf8_offset_to_pointer (text, entry->current_pos) - text; - + cursor_index = g_utf8_offset_to_pointer (text, priv->current_pos) - text; + if (text_index > cursor_index) - text_index += entry->preedit_length; + text_index += priv->preedit_length; return text_index; } @@ -7429,10 +7593,10 @@ void gtk_entry_set_alignment (GtkEntry *entry, gfloat xalign) { GtkEntryPrivate *priv; - + g_return_if_fail (GTK_IS_ENTRY (entry)); - priv = GTK_ENTRY_GET_PRIVATE (entry); + priv = entry->priv; if (xalign < 0.0) xalign = 0.0; @@ -7462,13 +7626,9 @@ gtk_entry_set_alignment (GtkEntry *entry, gfloat xalign) gfloat gtk_entry_get_alignment (GtkEntry *entry) { - GtkEntryPrivate *priv; - g_return_val_if_fail (GTK_IS_ENTRY (entry), 0.0); - priv = GTK_ENTRY_GET_PRIVATE (entry); - - return priv->xalign; + return entry->priv->xalign; } /** @@ -7494,7 +7654,7 @@ gtk_entry_set_icon_from_pixbuf (GtkEntry *entry, g_return_if_fail (GTK_IS_ENTRY (entry)); g_return_if_fail (IS_VALID_ICON_POSITION (icon_pos)); - priv = GTK_ENTRY_GET_PRIVATE (entry); + priv = entry->priv; if ((icon_info = priv->icons[icon_pos]) == NULL) icon_info = construct_icon_info (GTK_WIDGET (entry), icon_pos); @@ -7559,7 +7719,7 @@ gtk_entry_set_icon_from_stock (GtkEntry *entry, g_return_if_fail (GTK_IS_ENTRY (entry)); g_return_if_fail (IS_VALID_ICON_POSITION (icon_pos)); - priv = GTK_ENTRY_GET_PRIVATE (entry); + priv = entry->priv; if ((icon_info = priv->icons[icon_pos]) == NULL) icon_info = construct_icon_info (GTK_WIDGET (entry), icon_pos); @@ -7629,7 +7789,7 @@ gtk_entry_set_icon_from_icon_name (GtkEntry *entry, g_return_if_fail (GTK_IS_ENTRY (entry)); g_return_if_fail (IS_VALID_ICON_POSITION (icon_pos)); - priv = GTK_ENTRY_GET_PRIVATE (entry); + priv = entry->priv; if ((icon_info = priv->icons[icon_pos]) == NULL) icon_info = construct_icon_info (GTK_WIDGET (entry), icon_pos); @@ -7697,7 +7857,7 @@ gtk_entry_set_icon_from_gicon (GtkEntry *entry, g_return_if_fail (GTK_IS_ENTRY (entry)); g_return_if_fail (IS_VALID_ICON_POSITION (icon_pos)); - priv = GTK_ENTRY_GET_PRIVATE (entry); + priv = entry->priv; if ((icon_info = priv->icons[icon_pos]) == NULL) icon_info = construct_icon_info (GTK_WIDGET (entry), icon_pos); @@ -7759,7 +7919,7 @@ gtk_entry_set_icon_activatable (GtkEntry *entry, g_return_if_fail (GTK_IS_ENTRY (entry)); g_return_if_fail (IS_VALID_ICON_POSITION (icon_pos)); - priv = GTK_ENTRY_GET_PRIVATE (entry); + priv = entry->priv; if ((icon_info = priv->icons[icon_pos]) == NULL) icon_info = construct_icon_info (GTK_WIDGET (entry), icon_pos); @@ -7799,7 +7959,7 @@ gtk_entry_get_icon_activatable (GtkEntry *entry, g_return_val_if_fail (GTK_IS_ENTRY (entry), FALSE); g_return_val_if_fail (IS_VALID_ICON_POSITION (icon_pos), FALSE); - priv = GTK_ENTRY_GET_PRIVATE (entry); + priv = entry->priv; icon_info = priv->icons[icon_pos]; return (icon_info != NULL && !icon_info->nonactivatable); @@ -7831,7 +7991,8 @@ gtk_entry_get_icon_pixbuf (GtkEntry *entry, g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL); g_return_val_if_fail (IS_VALID_ICON_POSITION (icon_pos), NULL); - priv = GTK_ENTRY_GET_PRIVATE (entry); + priv = entry->priv; + icon_info = priv->icons[icon_pos]; if (!icon_info) @@ -7866,7 +8027,7 @@ gtk_entry_get_icon_gicon (GtkEntry *entry, g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL); g_return_val_if_fail (IS_VALID_ICON_POSITION (icon_pos), NULL); - priv = GTK_ENTRY_GET_PRIVATE (entry); + priv = entry->priv; icon_info = priv->icons[icon_pos]; if (!icon_info) @@ -7899,7 +8060,7 @@ gtk_entry_get_icon_stock (GtkEntry *entry, g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL); g_return_val_if_fail (IS_VALID_ICON_POSITION (icon_pos), NULL); - priv = GTK_ENTRY_GET_PRIVATE (entry); + priv = entry->priv; icon_info = priv->icons[icon_pos]; if (!icon_info) @@ -7932,7 +8093,7 @@ gtk_entry_get_icon_name (GtkEntry *entry, g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL); g_return_val_if_fail (IS_VALID_ICON_POSITION (icon_pos), NULL); - priv = GTK_ENTRY_GET_PRIVATE (entry); + priv = entry->priv; icon_info = priv->icons[icon_pos]; if (!icon_info) @@ -7963,7 +8124,7 @@ gtk_entry_set_icon_sensitive (GtkEntry *entry, g_return_if_fail (GTK_IS_ENTRY (entry)); g_return_if_fail (IS_VALID_ICON_POSITION (icon_pos)); - priv = GTK_ENTRY_GET_PRIVATE (entry); + priv = entry->priv; if ((icon_info = priv->icons[icon_pos]) == NULL) icon_info = construct_icon_info (GTK_WIDGET (entry), icon_pos); @@ -8006,7 +8167,8 @@ gtk_entry_get_icon_sensitive (GtkEntry *entry, g_return_val_if_fail (GTK_IS_ENTRY (entry), TRUE); g_return_val_if_fail (IS_VALID_ICON_POSITION (icon_pos), TRUE); - priv = GTK_ENTRY_GET_PRIVATE (entry); + priv = entry->priv; + icon_info = priv->icons[icon_pos]; return (!icon_info || !icon_info->insensitive); @@ -8036,7 +8198,8 @@ gtk_entry_get_icon_storage_type (GtkEntry *entry, g_return_val_if_fail (GTK_IS_ENTRY (entry), GTK_IMAGE_EMPTY); g_return_val_if_fail (IS_VALID_ICON_POSITION (icon_pos), GTK_IMAGE_EMPTY); - priv = GTK_ENTRY_GET_PRIVATE (entry); + priv = entry->priv; + icon_info = priv->icons[icon_pos]; if (!icon_info) @@ -8067,9 +8230,14 @@ gtk_entry_get_icon_at_pos (GtkEntry *entry, { GtkAllocation primary; GtkAllocation secondary; + gint frame_x, frame_y; g_return_val_if_fail (GTK_IS_ENTRY (entry), -1); + get_frame_size (entry, &frame_x, &frame_y, NULL, NULL); + x -= frame_x; + y -= frame_y; + get_icon_allocations (entry, &primary, &secondary); if (primary.x <= x && x < primary.x + primary.width && @@ -8118,7 +8286,7 @@ gtk_entry_set_icon_drag_source (GtkEntry *entry, g_return_if_fail (GTK_IS_ENTRY (entry)); g_return_if_fail (IS_VALID_ICON_POSITION (icon_pos)); - priv = GTK_ENTRY_GET_PRIVATE (entry); + priv = entry->priv; if ((icon_info = priv->icons[icon_pos]) == NULL) icon_info = construct_icon_info (GTK_WIDGET (entry), icon_pos); @@ -8156,7 +8324,7 @@ gtk_entry_get_current_icon_drag_source (GtkEntry *entry) g_return_val_if_fail (GTK_IS_ENTRY (entry), -1); - priv = GTK_ENTRY_GET_PRIVATE (entry); + priv = entry->priv; for (i = 0; i < MAX_ICONS; i++) { @@ -8171,38 +8339,56 @@ gtk_entry_get_current_icon_drag_source (GtkEntry *entry) } /** - * gtk_entry_get_icon_window: + * gtk_entry_get_icon_area: * @entry: A #GtkEntry * @icon_pos: Icon position + * @icon_area: Return location for the icon's area * - * Returns the #GdkWindow which contains the entry's icon at - * @icon_pos. This function is useful when drawing something to the - * entry in an expose-event callback because it enables the callback - * to distinguish between the text window and entry's icon windows. + * Gets the area where entry's icon at @icon_pos is drawn. + * This function is useful when drawing something to the + * entry in a draw callback. * - * See also gtk_entry_get_text_window(). + * If the entry is not realized or has no icon at the given position, + * @icon_area is filled with zeros. * - * Return value: (transfer none): the entry's icon window at @icon_pos. + * See also gtk_entry_get_text_area() * - * Since: 2.20 + * Since: 3.0 */ -GdkWindow * -gtk_entry_get_icon_window (GtkEntry *entry, - GtkEntryIconPosition icon_pos) +void +gtk_entry_get_icon_area (GtkEntry *entry, + GtkEntryIconPosition icon_pos, + GdkRectangle *icon_area) { GtkEntryPrivate *priv; EntryIconInfo *icon_info; - g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL); + g_return_if_fail (GTK_IS_ENTRY (entry)); + g_return_if_fail (icon_area != NULL); - priv = GTK_ENTRY_GET_PRIVATE (entry); + priv = entry->priv; icon_info = priv->icons[icon_pos]; if (icon_info) - return icon_info->window; + { + GtkAllocation primary; + GtkAllocation secondary; - return NULL; + get_icon_allocations (entry, &primary, &secondary); + + if (icon_pos == GTK_ENTRY_ICON_PRIMARY) + *icon_area = primary; + else + *icon_area = secondary; + } + else + { + icon_area->x = 0; + icon_area->y = 0; + icon_area->width = 0; + icon_area->height = 0; + } } static void @@ -8213,7 +8399,7 @@ ensure_has_tooltip (GtkEntry *entry) int i; gboolean has_tooltip = FALSE; - priv = GTK_ENTRY_GET_PRIVATE (entry); + priv = entry->priv; for (i = 0; i < MAX_ICONS; i++) { @@ -8254,7 +8440,8 @@ gtk_entry_get_icon_tooltip_text (GtkEntry *entry, g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL); g_return_val_if_fail (IS_VALID_ICON_POSITION (icon_pos), NULL); - priv = GTK_ENTRY_GET_PRIVATE (entry); + priv = entry->priv; + icon_info = priv->icons[icon_pos]; if (!icon_info) @@ -8294,10 +8481,10 @@ gtk_entry_set_icon_tooltip_text (GtkEntry *entry, g_return_if_fail (GTK_IS_ENTRY (entry)); g_return_if_fail (IS_VALID_ICON_POSITION (icon_pos)); - priv = GTK_ENTRY_GET_PRIVATE (entry); + priv = entry->priv; - if (!(icon_info = priv->icons[icon_pos])) - icon_info = priv->icons[icon_pos]; + if ((icon_info = priv->icons[icon_pos]) == NULL) + icon_info = construct_icon_info (GTK_WIDGET (entry), icon_pos); if (icon_info->tooltip) g_free (icon_info->tooltip); @@ -8336,7 +8523,8 @@ gtk_entry_get_icon_tooltip_markup (GtkEntry *entry, g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL); g_return_val_if_fail (IS_VALID_ICON_POSITION (icon_pos), NULL); - priv = GTK_ENTRY_GET_PRIVATE (entry); + priv = entry->priv; + icon_info = priv->icons[icon_pos]; if (!icon_info) @@ -8373,10 +8561,10 @@ gtk_entry_set_icon_tooltip_markup (GtkEntry *entry, g_return_if_fail (GTK_IS_ENTRY (entry)); g_return_if_fail (IS_VALID_ICON_POSITION (icon_pos)); - priv = GTK_ENTRY_GET_PRIVATE (entry); + priv = entry->priv; - if (!(icon_info = priv->icons[icon_pos])) - icon_info = priv->icons[icon_pos]; + if ((icon_info = priv->icons[icon_pos]) == NULL) + icon_info = construct_icon_info (GTK_WIDGET (entry), icon_pos); if (icon_info->tooltip) g_free (icon_info->tooltip); @@ -8405,7 +8593,7 @@ gtk_entry_query_tooltip (GtkWidget *widget, gint icon_pos; entry = GTK_ENTRY (widget); - priv = GTK_ENTRY_GET_PRIVATE (entry); + priv = entry->priv; if (!keyboard_tip) { @@ -8474,7 +8662,10 @@ static void popup_menu_detach (GtkWidget *attach_widget, GtkMenu *menu) { - GTK_ENTRY (attach_widget)->popup_menu = NULL; + GtkEntry *entry_attach = GTK_ENTRY (attach_widget); + GtkEntryPrivate *priv_attach = entry_attach->priv; + + priv_attach->popup_menu = NULL; } static void @@ -8485,6 +8676,7 @@ popup_position_func (GtkMenu *menu, gpointer user_data) { GtkEntry *entry = GTK_ENTRY (user_data); + GtkEntryPrivate *priv = entry->priv; GtkWidget *widget = GTK_WIDGET (entry); GdkScreen *screen; GtkRequisition menu_req; @@ -8494,22 +8686,22 @@ popup_position_func (GtkMenu *menu, g_return_if_fail (gtk_widget_get_realized (widget)); - gdk_window_get_origin (entry->text_area, x, y); + gdk_window_get_origin (priv->text_area, x, y); screen = gtk_widget_get_screen (widget); - monitor_num = gdk_screen_get_monitor_at_window (screen, entry->text_area); + monitor_num = gdk_screen_get_monitor_at_window (screen, priv->text_area); if (monitor_num < 0) monitor_num = 0; gtk_menu_set_monitor (menu, monitor_num); gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor); - gtk_size_request_get_size (GTK_SIZE_REQUEST (entry->popup_menu), - &menu_req, NULL); - gdk_drawable_get_size (entry->text_area, NULL, &height); + gtk_widget_get_preferred_size (priv->popup_menu, + &menu_req, NULL); + height = gdk_window_get_height (priv->text_area); gtk_entry_get_cursor_locations (entry, CURSOR_STANDARD, &strong_x, NULL); _gtk_entry_effective_inner_border (entry, &inner_border); - *x += inner_border.left + strong_x - entry->scroll_offset; + *x += inner_border.left + strong_x - priv->scroll_offset; if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) *x -= menu_req.width; @@ -8530,8 +8722,9 @@ unichar_chosen_func (const char *text, gpointer data) { GtkEntry *entry = GTK_ENTRY (data); + GtkEntryPrivate *priv = entry->priv; - if (entry->editable) + if (priv->editable) gtk_entry_enter_text (entry, text); } @@ -8549,7 +8742,8 @@ popup_targets_received (GtkClipboard *clipboard, { PopupInfo *info = user_data; GtkEntry *entry = info->entry; - + GtkEntryPrivate *info_entry_priv = entry->priv; + if (gtk_widget_get_realized (GTK_WIDGET (entry))) { DisplayMode mode; @@ -8560,43 +8754,43 @@ popup_targets_received (GtkClipboard *clipboard, gboolean show_unicode_menu; clipboard_contains_text = gtk_selection_data_targets_include_text (data); - if (entry->popup_menu) - gtk_widget_destroy (entry->popup_menu); - - entry->popup_menu = gtk_menu_new (); - - gtk_menu_attach_to_widget (GTK_MENU (entry->popup_menu), + if (info_entry_priv->popup_menu) + gtk_widget_destroy (info_entry_priv->popup_menu); + + info_entry_priv->popup_menu = gtk_menu_new (); + + gtk_menu_attach_to_widget (GTK_MENU (info_entry_priv->popup_menu), GTK_WIDGET (entry), popup_menu_detach); mode = gtk_entry_get_display_mode (entry); - append_action_signal (entry, entry->popup_menu, GTK_STOCK_CUT, "cut-clipboard", - entry->editable && mode == DISPLAY_NORMAL && - entry->current_pos != entry->selection_bound); + append_action_signal (entry, info_entry_priv->popup_menu, GTK_STOCK_CUT, "cut-clipboard", + info_entry_priv->editable && mode == DISPLAY_NORMAL && + info_entry_priv->current_pos != info_entry_priv->selection_bound); - append_action_signal (entry, entry->popup_menu, GTK_STOCK_COPY, "copy-clipboard", + append_action_signal (entry, info_entry_priv->popup_menu, GTK_STOCK_COPY, "copy-clipboard", mode == DISPLAY_NORMAL && - entry->current_pos != entry->selection_bound); + info_entry_priv->current_pos != info_entry_priv->selection_bound); - append_action_signal (entry, entry->popup_menu, GTK_STOCK_PASTE, "paste-clipboard", - entry->editable && clipboard_contains_text); + append_action_signal (entry, info_entry_priv->popup_menu, GTK_STOCK_PASTE, "paste-clipboard", + info_entry_priv->editable && clipboard_contains_text); menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_DELETE, NULL); - gtk_widget_set_sensitive (menuitem, entry->editable && entry->current_pos != entry->selection_bound); + gtk_widget_set_sensitive (menuitem, info_entry_priv->editable && info_entry_priv->current_pos != info_entry_priv->selection_bound); g_signal_connect_swapped (menuitem, "activate", G_CALLBACK (gtk_entry_delete_cb), entry); gtk_widget_show (menuitem); - gtk_menu_shell_append (GTK_MENU_SHELL (entry->popup_menu), menuitem); + gtk_menu_shell_append (GTK_MENU_SHELL (info_entry_priv->popup_menu), menuitem); menuitem = gtk_separator_menu_item_new (); gtk_widget_show (menuitem); - gtk_menu_shell_append (GTK_MENU_SHELL (entry->popup_menu), menuitem); + gtk_menu_shell_append (GTK_MENU_SHELL (info_entry_priv->popup_menu), menuitem); menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_SELECT_ALL, NULL); g_signal_connect_swapped (menuitem, "activate", G_CALLBACK (gtk_entry_select_all), entry); gtk_widget_show (menuitem); - gtk_menu_shell_append (GTK_MENU_SHELL (entry->popup_menu), menuitem); + gtk_menu_shell_append (GTK_MENU_SHELL (info_entry_priv->popup_menu), menuitem); g_object_get (gtk_widget_get_settings (GTK_WIDGET (entry)), "gtk-show-input-method-menu", &show_input_method_menu, @@ -8607,33 +8801,33 @@ popup_targets_received (GtkClipboard *clipboard, { menuitem = gtk_separator_menu_item_new (); gtk_widget_show (menuitem); - gtk_menu_shell_append (GTK_MENU_SHELL (entry->popup_menu), menuitem); + gtk_menu_shell_append (GTK_MENU_SHELL (info_entry_priv->popup_menu), menuitem); } if (show_input_method_menu) { menuitem = gtk_menu_item_new_with_mnemonic (_("Input _Methods")); - gtk_widget_set_sensitive (menuitem, entry->editable); + gtk_widget_set_sensitive (menuitem, info_entry_priv->editable); gtk_widget_show (menuitem); submenu = gtk_menu_new (); gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu); - - gtk_menu_shell_append (GTK_MENU_SHELL (entry->popup_menu), menuitem); - - gtk_im_multicontext_append_menuitems (GTK_IM_MULTICONTEXT (entry->im_context), + + gtk_menu_shell_append (GTK_MENU_SHELL (info_entry_priv->popup_menu), menuitem); + + gtk_im_multicontext_append_menuitems (GTK_IM_MULTICONTEXT (info_entry_priv->im_context), GTK_MENU_SHELL (submenu)); } if (show_unicode_menu) { menuitem = gtk_menu_item_new_with_mnemonic (_("_Insert Unicode Control Character")); - gtk_widget_set_sensitive (menuitem, entry->editable); + gtk_widget_set_sensitive (menuitem, info_entry_priv->editable); gtk_widget_show (menuitem); submenu = gtk_menu_new (); gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu); - gtk_menu_shell_append (GTK_MENU_SHELL (entry->popup_menu), menuitem); - + gtk_menu_shell_append (GTK_MENU_SHELL (info_entry_priv->popup_menu), menuitem); + _gtk_text_util_append_special_char_menuitems (GTK_MENU_SHELL (submenu), unichar_chosen_func, entry); @@ -8642,19 +8836,19 @@ popup_targets_received (GtkClipboard *clipboard, g_signal_emit (entry, signals[POPULATE_POPUP], 0, - entry->popup_menu); - + info_entry_priv->popup_menu); + if (info->button) - gtk_menu_popup (GTK_MENU (entry->popup_menu), NULL, NULL, + gtk_menu_popup (GTK_MENU (info_entry_priv->popup_menu), NULL, NULL, NULL, NULL, info->button, info->time); else { - gtk_menu_popup (GTK_MENU (entry->popup_menu), NULL, NULL, + gtk_menu_popup (GTK_MENU (info_entry_priv->popup_menu), NULL, NULL, popup_position_func, entry, info->button, info->time); - gtk_menu_shell_select_first (GTK_MENU_SHELL (entry->popup_menu), FALSE); + gtk_menu_shell_select_first (GTK_MENU_SHELL (info_entry_priv->popup_menu), FALSE); } } @@ -8702,7 +8896,8 @@ static void gtk_entry_drag_begin (GtkWidget *widget, GdkDragContext *context) { - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (widget); + GtkEntry *entry = GTK_ENTRY (widget); + GtkEntryPrivate *priv = entry->priv; gint i; for (i = 0; i < MAX_ICONS; i++) @@ -8740,7 +8935,8 @@ static void gtk_entry_drag_end (GtkWidget *widget, GdkDragContext *context) { - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (widget); + GtkEntry *entry = GTK_ENTRY (widget); + GtkEntryPrivate *priv = entry->priv; gint i; for (i = 0; i < MAX_ICONS; i++) @@ -8758,8 +8954,9 @@ gtk_entry_drag_leave (GtkWidget *widget, guint time) { GtkEntry *entry = GTK_ENTRY (widget); + GtkEntryPrivate *priv = entry->priv; - entry->dnd_position = -1; + priv->dnd_position = -1; gtk_widget_queue_draw (widget); } @@ -8771,9 +8968,10 @@ gtk_entry_drag_drop (GtkWidget *widget, guint time) { GtkEntry *entry = GTK_ENTRY (widget); + GtkEntryPrivate *priv = entry->priv; GdkAtom target = GDK_NONE; - - if (entry->editable) + + if (priv->editable) target = gtk_drag_dest_find_target (widget, context, NULL); if (target != GDK_NONE) @@ -8792,24 +8990,27 @@ gtk_entry_drag_motion (GtkWidget *widget, guint time) { GtkEntry *entry = GTK_ENTRY (widget); - GtkStyle *style; + GtkEntryPrivate *priv = entry->priv; + GtkStyleContext *style_context; GtkWidget *source_widget; GdkDragAction suggested_action; gint new_position, old_position; gint sel1, sel2; + GtkBorder padding; - style = gtk_widget_get_style (widget); - x -= style->xthickness; - y -= style->ythickness; + style_context = gtk_widget_get_style_context (widget); + gtk_style_context_get_padding (style_context, 0, &padding); + x -= padding.left; + y -= padding.top; - old_position = entry->dnd_position; - new_position = gtk_entry_find_position (entry, x + entry->scroll_offset); + old_position = priv->dnd_position; + new_position = gtk_entry_find_position (entry, x + priv->scroll_offset); - if (entry->editable && + if (priv->editable && gtk_drag_dest_find_target (widget, context, NULL) != GDK_NONE) { source_widget = gtk_drag_get_source_widget (context); - suggested_action = context->suggested_action; + suggested_action = gdk_drag_context_get_suggested_action (context); if (!gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), &sel1, &sel2) || new_position < sel1 || new_position > sel2) @@ -8819,30 +9020,30 @@ gtk_entry_drag_motion (GtkWidget *widget, /* Default to MOVE, unless the user has * pressed ctrl or alt to affect available actions */ - if ((context->actions & GDK_ACTION_MOVE) != 0) + if ((gdk_drag_context_get_actions (context) & GDK_ACTION_MOVE) != 0) suggested_action = GDK_ACTION_MOVE; } - - entry->dnd_position = new_position; + + priv->dnd_position = new_position; } else { if (source_widget == widget) suggested_action = 0; /* Can't drop in selection where drag started */ - - entry->dnd_position = -1; + + priv->dnd_position = -1; } } else { /* Entry not editable, or no text */ suggested_action = 0; - entry->dnd_position = -1; + priv->dnd_position = -1; } gdk_drag_status (context, suggested_action, time); - - if (entry->dnd_position != old_position) + + if (priv->dnd_position != old_position) gtk_widget_queue_draw (widget); return TRUE; @@ -8858,26 +9059,29 @@ gtk_entry_drag_data_received (GtkWidget *widget, guint time) { GtkEntry *entry = GTK_ENTRY (widget); + GtkEntryPrivate *priv = entry->priv; GtkEditable *editable = GTK_EDITABLE (widget); - GtkStyle *style; + GtkStyleContext *style_context; + GtkBorder padding; gchar *str; str = (gchar *) gtk_selection_data_get_text (selection_data); - style = gtk_widget_get_style (widget); - x -= style->xthickness; - y -= style->ythickness; + style_context = gtk_widget_get_style_context (widget); + gtk_style_context_get_padding (style_context, 0, &padding); + x -= padding.left; + y -= padding.top; - if (str && entry->editable) + if (str && priv->editable) { gint new_position; gint sel1, sel2; gint length = -1; - if (entry->truncate_multiline) + if (priv->truncate_multiline) length = truncate_multiline (str); - new_position = gtk_entry_find_position (entry, x + entry->scroll_offset); + new_position = gtk_entry_find_position (entry, x + priv->scroll_offset); if (!gtk_editable_get_selection_bounds (editable, &sel1, &sel2) || new_position < sel1 || new_position > sel2) @@ -8895,7 +9099,7 @@ gtk_entry_drag_data_received (GtkWidget *widget, end_change (entry); } - gtk_drag_finish (context, TRUE, context->action == GDK_ACTION_MOVE, time); + gtk_drag_finish (context, TRUE, gdk_drag_context_get_selected_action (context) == GDK_ACTION_MOVE, time); } else { @@ -8913,12 +9117,12 @@ gtk_entry_drag_data_get (GtkWidget *widget, guint info, guint time) { + GtkEntry *entry = GTK_ENTRY (widget); + GtkEntryPrivate *priv = entry->priv; + GtkEditable *editable = GTK_EDITABLE (widget); gint sel_start, sel_end; gint i; - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (widget); - GtkEditable *editable = GTK_EDITABLE (widget); - /* If there is an icon drag going on, exit early. */ for (i = 0; i < MAX_ICONS; i++) { @@ -8946,12 +9150,12 @@ static void gtk_entry_drag_data_delete (GtkWidget *widget, GdkDragContext *context) { + GtkEntry *entry = GTK_ENTRY (widget); + GtkEntryPrivate *priv = entry->priv; + GtkEditable *editable = GTK_EDITABLE (widget); gint sel_start, sel_end; gint i; - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (widget); - GtkEditable *editable = GTK_EDITABLE (widget); - /* If there is an icon drag going on, exit early. */ for (i = 0; i < MAX_ICONS; i++) { @@ -8963,8 +9167,8 @@ gtk_entry_drag_data_delete (GtkWidget *widget, return; } } - - if (GTK_ENTRY (widget)->editable && + + if (priv->editable && gtk_editable_get_selection_bounds (editable, &sel_start, &sel_end)) gtk_editable_delete_text (editable, sel_start, sel_end); } @@ -8983,9 +9187,11 @@ gtk_entry_drag_data_delete (GtkWidget *widget, static gboolean cursor_blinks (GtkEntry *entry) { + GtkEntryPrivate *priv = entry->priv; + if (gtk_widget_has_focus (GTK_WIDGET (entry)) && - entry->editable && - entry->selection_bound == entry->current_pos) + priv->editable && + priv->selection_bound == priv->current_pos) { GtkSettings *settings; gboolean blink; @@ -9024,14 +9230,15 @@ get_cursor_blink_timeout (GtkEntry *entry) static void show_cursor (GtkEntry *entry) { + GtkEntryPrivate *priv = entry->priv; GtkWidget *widget; - if (!entry->cursor_visible) + if (!priv->cursor_visible) { - entry->cursor_visible = TRUE; + priv->cursor_visible = TRUE; widget = GTK_WIDGET (entry); - if (gtk_widget_has_focus (widget) && entry->selection_bound == entry->current_pos) + if (gtk_widget_has_focus (widget) && priv->selection_bound == priv->current_pos) gtk_widget_queue_draw (widget); } } @@ -9039,14 +9246,15 @@ show_cursor (GtkEntry *entry) static void hide_cursor (GtkEntry *entry) { + GtkEntryPrivate *priv = entry->priv; GtkWidget *widget; - if (entry->cursor_visible) + if (priv->cursor_visible) { - entry->cursor_visible = FALSE; + priv->cursor_visible = FALSE; widget = GTK_WIDGET (entry); - if (gtk_widget_has_focus (widget) && entry->selection_bound == entry->current_pos) + if (gtk_widget_has_focus (widget) && priv->selection_bound == priv->current_pos) gtk_widget_queue_draw (widget); } } @@ -9062,7 +9270,7 @@ blink_cb (gpointer data) gint blink_timeout; entry = GTK_ENTRY (data); - priv = GTK_ENTRY_GET_PRIVATE (entry); + priv = entry->priv; if (!gtk_widget_has_focus (GTK_WIDGET (entry))) { @@ -9075,7 +9283,7 @@ blink_cb (gpointer data) return FALSE; } - g_assert (entry->selection_bound == entry->current_pos); + g_assert (priv->selection_bound == priv->current_pos); blink_timeout = get_cursor_blink_timeout (entry); if (priv->blink_time > 1000 * blink_timeout && @@ -9083,12 +9291,12 @@ blink_cb (gpointer data) { /* we've blinked enough without the user doing anything, stop blinking */ show_cursor (entry); - entry->blink_timeout = 0; + priv->blink_timeout = 0; } - else if (entry->cursor_visible) + else if (priv->cursor_visible) { hide_cursor (entry); - entry->blink_timeout = gdk_threads_add_timeout (get_cursor_time (entry) * CURSOR_OFF_MULTIPLIER / CURSOR_DIVIDER, + priv->blink_timeout = gdk_threads_add_timeout (get_cursor_time (entry) * CURSOR_OFF_MULTIPLIER / CURSOR_DIVIDER, blink_cb, entry); } @@ -9096,7 +9304,7 @@ blink_cb (gpointer data) { show_cursor (entry); priv->blink_time += get_cursor_time (entry); - entry->blink_timeout = gdk_threads_add_timeout (get_cursor_time (entry) * CURSOR_ON_MULTIPLIER / CURSOR_DIVIDER, + priv->blink_timeout = gdk_threads_add_timeout (get_cursor_time (entry) * CURSOR_ON_MULTIPLIER / CURSOR_DIVIDER, blink_cb, entry); } @@ -9108,44 +9316,43 @@ blink_cb (gpointer data) static void gtk_entry_check_cursor_blink (GtkEntry *entry) { - GtkEntryPrivate *priv; - - priv = GTK_ENTRY_GET_PRIVATE (entry); + GtkEntryPrivate *priv = entry->priv; if (cursor_blinks (entry)) { - if (!entry->blink_timeout) + if (!priv->blink_timeout) { show_cursor (entry); - entry->blink_timeout = gdk_threads_add_timeout (get_cursor_time (entry) * CURSOR_ON_MULTIPLIER / CURSOR_DIVIDER, + priv->blink_timeout = gdk_threads_add_timeout (get_cursor_time (entry) * CURSOR_ON_MULTIPLIER / CURSOR_DIVIDER, blink_cb, entry); } } else { - if (entry->blink_timeout) - { - g_source_remove (entry->blink_timeout); - entry->blink_timeout = 0; + if (priv->blink_timeout) + { + g_source_remove (priv->blink_timeout); + priv->blink_timeout = 0; } - - entry->cursor_visible = TRUE; + + priv->cursor_visible = TRUE; } - } static void gtk_entry_pend_cursor_blink (GtkEntry *entry) { + GtkEntryPrivate *priv = entry->priv; + if (cursor_blinks (entry)) { - if (entry->blink_timeout != 0) - g_source_remove (entry->blink_timeout); - - entry->blink_timeout = gdk_threads_add_timeout (get_cursor_time (entry) * CURSOR_PEND_MULTIPLIER / CURSOR_DIVIDER, - blink_cb, - entry); + if (priv->blink_timeout != 0) + g_source_remove (priv->blink_timeout); + + priv->blink_timeout = gdk_threads_add_timeout (get_cursor_time (entry) * CURSOR_PEND_MULTIPLIER / CURSOR_DIVIDER, + blink_cb, + entry); show_cursor (entry); } } @@ -9153,10 +9360,8 @@ gtk_entry_pend_cursor_blink (GtkEntry *entry) static void gtk_entry_reset_blink_time (GtkEntry *entry) { - GtkEntryPrivate *priv; - - priv = GTK_ENTRY_GET_PRIVATE (entry); - + GtkEntryPrivate *priv = entry->priv; + priv->blink_time = 0; } @@ -9166,7 +9371,7 @@ static gint gtk_entry_completion_timeout (gpointer data) { GtkEntryCompletion *completion = GTK_ENTRY_COMPLETION (data); - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (completion->priv->entry); + GtkEntryPrivate *completion_entry_priv = GTK_ENTRY (completion->priv->entry)->priv; completion->priv->completion_timeout = 0; @@ -9196,7 +9401,7 @@ gtk_entry_completion_timeout (gpointer data) if (gtk_widget_get_visible (completion->priv->popup_window)) _gtk_entry_completion_resize_popup (completion); else - _gtk_entry_completion_popup (completion, priv->completion_device); + _gtk_entry_completion_popup (completion, completion_entry_priv->completion_device); } else _gtk_entry_completion_popdown (completion); @@ -9498,23 +9703,24 @@ keypress_completion_out: } static void -gtk_entry_completion_changed (GtkWidget *entry, +gtk_entry_completion_changed (GtkWidget *widget, gpointer user_data) { - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry); GtkEntryCompletion *completion = GTK_ENTRY_COMPLETION (user_data); + GtkEntry *entry = GTK_ENTRY (widget); + GtkEntryPrivate *priv = entry->priv; GdkDevice *device; /* (re)install completion timeout */ if (completion->priv->completion_timeout) g_source_remove (completion->priv->completion_timeout); - if (!gtk_entry_get_text (GTK_ENTRY (entry))) + if (!gtk_entry_get_text (entry)) return; /* no need to normalize for this test */ if (completion->priv->minimum_key_length > 0 && - strcmp ("", gtk_entry_get_text (GTK_ENTRY (entry))) == 0) + strcmp ("", gtk_entry_get_text (entry)) == 0) { if (gtk_widget_get_visible (completion->priv->popup_window)) _gtk_entry_completion_popdown (completion); @@ -9523,7 +9729,7 @@ gtk_entry_completion_changed (GtkWidget *entry, device = gtk_get_current_event_device (); - if (device && device->source == GDK_SOURCE_KEYBOARD) + if (device && gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD) device = gdk_device_get_associated_device (device); if (device) @@ -9821,7 +10027,7 @@ gtk_entry_set_progress_fraction (GtkEntry *entry, g_return_if_fail (GTK_IS_ENTRY (entry)); widget = GTK_WIDGET (entry); - private = GTK_ENTRY_GET_PRIVATE (entry); + private = entry->priv; if (private->progress_pulse_mode) old_fraction = -1; @@ -9863,13 +10069,9 @@ gtk_entry_set_progress_fraction (GtkEntry *entry, gdouble gtk_entry_get_progress_fraction (GtkEntry *entry) { - GtkEntryPrivate *private; - g_return_val_if_fail (GTK_IS_ENTRY (entry), 0.0); - private = GTK_ENTRY_GET_PRIVATE (entry); - - return private->progress_fraction; + return entry->priv->progress_fraction; } /** @@ -9890,7 +10092,7 @@ gtk_entry_set_progress_pulse_step (GtkEntry *entry, g_return_if_fail (GTK_IS_ENTRY (entry)); - private = GTK_ENTRY_GET_PRIVATE (entry); + private = entry->priv; fraction = CLAMP (fraction, 0.0, 1.0); @@ -9917,13 +10119,9 @@ gtk_entry_set_progress_pulse_step (GtkEntry *entry, gdouble gtk_entry_get_progress_pulse_step (GtkEntry *entry) { - GtkEntryPrivate *private; - g_return_val_if_fail (GTK_IS_ENTRY (entry), 0.0); - private = GTK_ENTRY_GET_PRIVATE (entry); - - return private->progress_pulse_fraction; + return entry->priv->progress_pulse_fraction; } /** @@ -9946,7 +10144,7 @@ gtk_entry_progress_pulse (GtkEntry *entry) g_return_if_fail (GTK_IS_ENTRY (entry)); - private = GTK_ENTRY_GET_PRIVATE (entry); + private = entry->priv; if (private->progress_pulse_mode) { @@ -9988,7 +10186,7 @@ static void show_capslock_feedback (GtkEntry *entry, const gchar *text) { - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry); + GtkEntryPrivate *priv = entry->priv; if (gtk_entry_get_icon_storage_type (entry, GTK_ENTRY_ICON_SECONDARY) == GTK_IMAGE_EMPTY) { @@ -10006,7 +10204,7 @@ show_capslock_feedback (GtkEntry *entry, static void remove_capslock_feedback (GtkEntry *entry) { - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry); + GtkEntryPrivate *priv = entry->priv; if (priv->caps_lock_warning_shown) { @@ -10019,7 +10217,7 @@ static void keymap_state_changed (GdkKeymap *keymap, GtkEntry *entry) { - GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry); + GtkEntryPrivate *priv = entry->priv; char *text = NULL; if (gtk_entry_get_display_mode (entry) != DISPLAY_NORMAL && priv->caps_lock_warning) @@ -10038,3 +10236,21 @@ keymap_state_changed (GdkKeymap *keymap, else remove_capslock_feedback (entry); } + +/* + * _gtk_entry_set_is_cell_renderer: + * @entry: a #GtkEntry + * @is_cell_renderer: new value + * + * This is a helper function for GtkComboBox. A GtkEntry in a GtkComboBox + * is supposed to behave like a GtkCellEditable when placed in a combo box. + * + * I.e take up it's allocation and get GtkEntry->is_cell_renderer = TRUE. + * + */ +void +_gtk_entry_set_is_cell_renderer (GtkEntry *entry, + gboolean is_cell_renderer) +{ + entry->priv->is_cell_renderer = is_cell_renderer; +}