diff options
-rw-r--r-- | ChangeLog | 22 | ||||
-rw-r--r-- | data/default-prefs-common.js | 3 | ||||
-rw-r--r-- | data/default-prefs-toolkit.js | 2 | ||||
-rw-r--r-- | src/ephy-find-toolbar.c | 220 | ||||
-rw-r--r-- | src/ephy-find-toolbar.h | 5 | ||||
-rw-r--r-- | src/ephy-window.c | 15 |
6 files changed, 220 insertions, 47 deletions
@@ -1,3 +1,25 @@ +2005-05-29 Christian Persch <chpe@cvs.gnome.org> + + * data/default-prefs-common.js: + * data/default-prefs-toolkit.js: + + Disable mozilla's typeaheadfind. + + * src/ephy-find-toolbar.c: (get_find), (send_focus_change), + (tab_dom_key_press_cb), (entry_changed_cb), + (entry_preedit_changed_cb), (entry_key_press_event_cb), + (entry_activate_cb), (set_focus_cb), + (ephy_find_toolbar_grab_focus), (ephy_find_toolbar_init), + (ephy_find_toolbar_class_init), (ephy_find_toolbar_set_embed), + (ephy_find_toolbar_find_previous), (ephy_find_toolbar_open), + (ephy_find_toolbar_close): + * src/ephy-find-toolbar.h: + * src/ephy-window.c: (sync_tab_document_type), (ephy_window_init), + (ephy_window_set_print_preview), (ephy_window_find): + + Forward key events from the embed to the find toolbar. That way we can + typeaheadfind without losing focus. + 2005-05-28 Christian Persch <chpe@cvs.gnome.org> * configure.ac: diff --git a/data/default-prefs-common.js b/data/default-prefs-common.js index 219bcf2be..4475ff41e 100644 --- a/data/default-prefs-common.js +++ b/data/default-prefs-common.js @@ -106,5 +106,4 @@ pref("network.protocol-handler.external.webcal", true); pref("xpinstall.enabled", false); // enable typeahead find -pref("accessibility.typeaheadfind", true); - +pref("accessibility.typeaheadfind", false); diff --git a/data/default-prefs-toolkit.js b/data/default-prefs-toolkit.js index 4e6f0df98..3d78670eb 100644 --- a/data/default-prefs-toolkit.js +++ b/data/default-prefs-toolkit.js @@ -5,7 +5,7 @@ pref("plugin.default_plugin_disabled", true); pref("intl.locale.matchOS", true); // enable fixed-up typeaheadfind extension -pref("accessibility.typeaheadfindsea", true); +pref("accessibility.typeaheadfindsea", false); pref("accessibility.typeaheadfindsea.autostart", true); pref("accessibility.typeaheadfindsea.linksonly", true); diff --git a/src/ephy-find-toolbar.c b/src/ephy-find-toolbar.c index 10e244a1a..c5f98f142 100644 --- a/src/ephy-find-toolbar.c +++ b/src/ephy-find-toolbar.c @@ -50,6 +50,10 @@ struct _EphyFindToolbarPrivate GtkToolItem *next; GtkToolItem *prev; gulong set_focus_handler; + guint preedit_changed : 1; + guint prevent_activate : 1; + guint explicit_focus : 1; + guint links_only : 1; }; enum @@ -79,6 +83,8 @@ get_find (EphyFindToolbar *toolbar) if (priv->find == NULL) { + LOG ("Creating the finder now"); + priv->find = EPHY_EMBED_FIND (ephy_embed_factory_new_object (EPHY_TYPE_EMBED_FIND)); g_return_val_if_fail (priv->embed == NULL || GTK_WIDGET_REALIZED (GTK_WIDGET (priv->embed)), priv->find); @@ -108,6 +114,108 @@ tab_content_changed_cb (EphyEmbed *embed, set_controls (toolbar, TRUE, TRUE); } +/* Cut and paste from gtkwindow.c */ +static void +send_focus_change (GtkWidget *widget, + gboolean in) +{ + GdkEvent *event; + + event = gdk_event_new (GDK_FOCUS_CHANGE); + + g_object_ref (widget); + + if (in) + { + GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS); + } + else + { + GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS); + } + + event->focus_change.type = GDK_FOCUS_CHANGE; + event->focus_change.window = (GdkWindow *) g_object_ref (widget->window); + event->focus_change.in = in; + + gtk_widget_event (widget, event); + + g_object_notify (G_OBJECT (widget), "has_focus"); + + g_object_unref (widget); + gdk_event_free (event); +} + +/* Code adapted from gtktreeview.c:gtk_tree_view_key_press() and + * gtk_tree_view_real_start_interactive_seach() + */ +static gboolean +tab_dom_key_press_cb (EphyEmbed *embed, + gpointer dom_event, + EphyFindToolbar *toolbar) +{ + EphyFindToolbarPrivate *priv = toolbar->priv; + GtkWidget *widget = (GtkWidget *) toolbar; + GtkEntry *entry = (GtkEntry *) priv->entry; + GdkWindow *event_window; + GdkEvent *event; + GdkEventKey *event_key; + gboolean retval = FALSE; + guint oldhash, newhash; + + event = gtk_get_current_event (); + if (event == NULL) return FALSE; /* shouldn't happen! */ + + g_return_val_if_fail (GDK_KEY_PRESS == event->type, FALSE); + + event_key = (GdkEventKey *) event; + + /* check for / and ' which open the find toolbar in text resp. link mode */ + if (event_key->keyval == GDK_slash) + { + ephy_find_toolbar_open (toolbar, FALSE); + gdk_event_free (event); + return TRUE; + } + else if (event_key->keyval == GDK_apostrophe) + { + ephy_find_toolbar_open (toolbar, TRUE); + gdk_event_free (event); + return TRUE; + } + + /* don't do anything if the find toolbar is hidden */ + if (GTK_WIDGET_VISIBLE (widget) == FALSE || + event_key->keyval == GDK_Return || + event_key->keyval == GDK_KP_Enter) + { + gdk_event_free (event); + return FALSE; + } + + oldhash = g_str_hash (gtk_entry_get_text (entry)); + priv->preedit_changed = FALSE; + + event_window = event_key->window; + event_key->window = priv->entry->window; + + /* Send the event to the window. If the preedit_changed signal is emitted + * during this event, we will set priv->imcontext_changed */ + priv->prevent_activate = TRUE; + retval = gtk_widget_event (priv->entry, event); + priv->prevent_activate = FALSE; + + /* restore event window, else gdk_event_free below will crash */ + event_key->window = event_window; + + gdk_event_free (event); + + newhash = g_str_hash (gtk_entry_get_text (entry)); + + /* FIXME: is this right? */ + return (retval && oldhash != newhash) || priv->preedit_changed; +} + static void find_next_cb (EphyFindToolbar *toolbar) { @@ -130,57 +238,55 @@ entry_changed_cb (GtkEntry *entry, text = gtk_entry_get_text (GTK_ENTRY (priv->entry)); #ifdef HAVE_TYPEAHEADFIND - found = ephy_embed_find_find (get_find (toolbar), text, FALSE); + found = ephy_embed_find_find (get_find (toolbar), text, priv->links_only); #else ephy_embed_find_set_properties (get_find (toolbar), text, FALSE); #endif set_controls (toolbar, found, found); } +static void +entry_preedit_changed_cb (GtkIMContext *context, + EphyFindToolbar *toolbar) +{ + toolbar->priv->preedit_changed = TRUE; +} + static gboolean entry_key_press_event_cb (GtkEntry *entry, GdkEventKey *event, EphyFindToolbar *toolbar) { - //EphyFindToolbarPrivate *priv = toolbar->priv; guint mask = gtk_accelerator_get_default_mod_mask (); gboolean handled = FALSE; /* Hide the toolbar when ESC is pressed */ - if ((event->state & mask) == 0) + if ((event->state & mask) == 0 && event->keyval == GDK_Escape) { - if (event->keyval == GDK_Escape) - { - g_signal_emit (toolbar, signals[CLOSE], 0); - - handled = TRUE; - } -#if 0 - else if (event->keyval == GDK_Page_Up) - { - ephy_command_manager_do_command - (EPHY_COMMAND_MANAGER (priv->embed), - "cmd_movePageUp"); - handled = TRUE; - } - else if (event->keyval == GDK_Page_Down) - { - ephy_command_manager_do_command - (EPHY_COMMAND_MANAGER (priv->embed), - "cmd_movePageDown"); - handled = TRUE; - } -#endif + g_signal_emit (toolbar, signals[CLOSE], 0); + handled = TRUE; } return handled; } static void +entry_activate_cb (GtkWidget *entry, + EphyFindToolbar *toolbar) +{ + EphyFindToolbarPrivate *priv = toolbar->priv; + + if (priv->prevent_activate) return; + + g_signal_emit (toolbar, signals[NEXT], 0); +} + +static void set_focus_cb (EphyWindow *window, GtkWidget *widget, EphyFindToolbar *toolbar) { + EphyFindToolbarPrivate *priv = toolbar->priv; GtkWidget *wtoolbar = GTK_WIDGET (toolbar); while (widget != NULL && widget != wtoolbar) @@ -188,12 +294,14 @@ set_focus_cb (EphyWindow *window, widget = widget->parent; } - /* if widget == toolbar, the new focus widget is in the toolbar, so we - * don't deactivate. - */ - if (widget != wtoolbar) + /* if widget == toolbar, the new focus widget is in the toolbar */ + if (widget == wtoolbar) + { + priv->explicit_focus = TRUE; + } + else if (priv->explicit_focus) { - gtk_widget_hide (wtoolbar); + g_signal_emit (toolbar, signals[CLOSE], 0); } } @@ -221,6 +329,7 @@ ephy_find_toolbar_grab_focus (GtkWidget *widget) EphyFindToolbarPrivate *priv = toolbar->priv; gtk_widget_grab_focus (priv->entry); + g_return_if_fail (priv->explicit_focus); } static void @@ -258,8 +367,6 @@ ephy_find_toolbar_init (EphyFindToolbar *toolbar) gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1); gtk_widget_show_all (GTK_WIDGET (item)); - // FIXME padding - /* Next */ arrow = gtk_arrow_new (GTK_ARROW_RIGHT, GTK_SHADOW_NONE); label = gtk_label_new (_("Find Next")); @@ -287,10 +394,10 @@ ephy_find_toolbar_init (EphyFindToolbar *toolbar) G_CALLBACK (entry_key_press_event_cb), toolbar); g_signal_connect_after (priv->entry, "changed", G_CALLBACK (entry_changed_cb), toolbar); - //g_signal_connect (GTK_ENTRY (priv->entry)->im_context, "preedit-changed", - // G_CALLBACK (entry_preedit_changed_cb), toolbar); - g_signal_connect_swapped (priv->entry, "activate", - G_CALLBACK (find_next_cb), toolbar); + g_signal_connect (GTK_ENTRY (priv->entry)->im_context, "preedit-changed", + G_CALLBACK (entry_preedit_changed_cb), toolbar); + g_signal_connect (priv->entry, "activate", + G_CALLBACK (entry_activate_cb), toolbar); g_signal_connect_swapped (priv->next, "clicked", G_CALLBACK (find_next_cb), toolbar); g_signal_connect_swapped (priv->prev, "clicked", @@ -326,6 +433,7 @@ ephy_find_toolbar_class_init (EphyFindToolbarClass *klass) klass->next = ephy_find_toolbar_find_next; klass->previous = ephy_find_toolbar_find_previous; + klass->close = ephy_find_toolbar_close; signals[NEXT] = g_signal_new ("next", @@ -411,8 +519,8 @@ ephy_find_toolbar_set_embed (EphyFindToolbar *toolbar, if (priv->embed != NULL) { - g_signal_handlers_disconnect_by_func - (embed, G_CALLBACK (tab_content_changed_cb), toolbar); + g_signal_handlers_disconnect_matched (embed, G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, toolbar); } priv->embed = embed; @@ -422,6 +530,9 @@ ephy_find_toolbar_set_embed (EphyFindToolbar *toolbar, g_signal_connect_object (embed, "ge-content-change", G_CALLBACK (tab_content_changed_cb), toolbar, G_CONNECT_AFTER); + g_signal_connect_object (embed, "dom-key-press", + G_CALLBACK (tab_dom_key_press_cb), + toolbar, 0); if (priv->find != NULL) { @@ -449,3 +560,36 @@ ephy_find_toolbar_find_previous (EphyFindToolbar *toolbar) found = ephy_embed_find_find_again (get_find (toolbar), FALSE); set_controls (toolbar, found, found); } + +void +ephy_find_toolbar_open (EphyFindToolbar *toolbar, + gboolean links_only) +{ + EphyFindToolbarPrivate *priv = toolbar->priv; + + g_return_if_fail (priv->embed != NULL); + + priv->links_only = links_only; + priv->explicit_focus = FALSE; + + gtk_entry_set_text (GTK_ENTRY (priv->entry), ""); + + gtk_widget_show (GTK_WIDGET (toolbar)); + ephy_embed_activate (priv->embed); + + send_focus_change (priv->entry, TRUE); +} + +void +ephy_find_toolbar_close (EphyFindToolbar *toolbar) +{ + EphyFindToolbarPrivate *priv = toolbar->priv; + + g_return_if_fail (priv->embed != NULL); + + gtk_widget_hide (GTK_WIDGET (toolbar)); + + /* first unset explicit_focus, else we get infinite recursion */ + priv->explicit_focus = FALSE; + ephy_embed_activate (priv->embed); +} diff --git a/src/ephy-find-toolbar.h b/src/ephy-find-toolbar.h index b55a2f2cf..6d66d03b3 100644 --- a/src/ephy-find-toolbar.h +++ b/src/ephy-find-toolbar.h @@ -70,6 +70,11 @@ void ephy_find_toolbar_find_next (EphyFindToolbar *toolbar); void ephy_find_toolbar_find_previous (EphyFindToolbar *toolbar); +void ephy_find_toolbar_open (EphyFindToolbar *toolbar, + gboolean links_only); + +void ephy_find_toolbar_close (EphyFindToolbar *toolbar); + G_END_DECLS #endif /* EPHY_FIND_TOOLBAR_H */ diff --git a/src/ephy-window.c b/src/ephy-window.c index e48c73704..645b5b9bf 100644 --- a/src/ephy-window.c +++ b/src/ephy-window.c @@ -1156,7 +1156,7 @@ sync_tab_document_type (EphyTab *tab, if (!can_find) { - gtk_widget_hide (GTK_WIDGET (priv->find_toolbar)); + ephy_find_toolbar_close (priv->find_toolbar); } } @@ -2715,7 +2715,7 @@ ephy_window_init (EphyWindow *window) G_CALLBACK (find_toolbar_close_cb), window); gtk_box_pack_start (GTK_BOX (window->priv->main_vbox), GTK_WIDGET (priv->find_toolbar), FALSE, FALSE, 0); - gtk_widget_show (GTK_WIDGET (priv->find_toolbar)); + /* don't show the find toolbar here! */ window->priv->statusbar = ephy_statusbar_new (); gtk_box_pack_end (GTK_BOX (window->priv->main_vbox), @@ -2889,8 +2889,10 @@ ephy_window_new_with_chrome (EphyEmbedChrome chrome, * Sets whether the window is in print preview mode. **/ void -ephy_window_set_print_preview (EphyWindow *window, gboolean enabled) +ephy_window_set_print_preview (EphyWindow *window, + gboolean enabled) { + EphyWindowPrivate *priv = window->priv; GtkAccelGroup *accel_group; accel_group = gtk_ui_manager_get_accel_group (window->priv->manager); @@ -2907,6 +2909,8 @@ ephy_window_set_print_preview (EphyWindow *window, gboolean enabled) window->priv->ppview_toolbar = ppview_toolbar_new (window); gtk_window_remove_accel_group (GTK_WINDOW (window), accel_group); + + ephy_find_toolbar_close (priv->find_toolbar); } else { @@ -3262,10 +3266,9 @@ void ephy_window_find (EphyWindow *window) { EphyWindowPrivate *priv = window->priv; - GtkWidget *toolbar = GTK_WIDGET (priv->find_toolbar); - gtk_widget_show (toolbar); - gtk_widget_grab_focus (toolbar); + ephy_find_toolbar_open (priv->find_toolbar, FALSE); + gtk_widget_grab_focus (GTK_WIDGET (priv->find_toolbar)); } /** |