Changeset 73025 in webkit
- Timestamp:
- Dec 1, 2010, 8:46:39 AM (15 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r73022 r73025 1 2010-12-01 Martin Robinson <mrobinson@igalia.com> 2 3 Reviewed by Xan Lopez. 4 5 [Gtk] Open menulists should support typeahead find 6 https://bugs.webkit.org/show_bug.cgi?id=27443 7 8 Added a GTK+-specific layout test to track typeahead find state. 9 10 * platform/gtk/fast/forms/menulist-typeahead-find-expected.txt: Added. 11 * platform/gtk/fast/forms/menulist-typeahead-find.html: Added. 12 1 13 2010-12-01 Martin Robinson <mrobinson@igalia.com> 2 14 -
trunk/WebCore/ChangeLog
r73024 r73025 1 2010-12-01 Apelete Seketeli <apelete@seketeli.org> and Martin Robinson <mrobinson@igalia.com> 2 3 Reviewed by Xan Lopez. 4 5 [Gtk] Open menulists should support typeahead find 6 https://bugs.webkit.org/show_bug.cgi?id=27443 7 8 Added typeahead find support for open GTK+ menulists. 9 10 Test: platform/gtk/fast/forms/menulist-typeahead-find.html 11 12 * platform/gtk/PopupMenuGtk.cpp: 13 (WebCore::PopupMenuGtk::PopupMenuGtk): Initialize new members. 14 (WebCore::PopupMenuGtk::show): Track currently selected menu item 15 via a signal handler. 16 (WebCore::PopupMenuGtk::typeAheadFind): Added. 17 (WebCore::PopupMenuGtk::menuUnmapped): Reset typeahead find state 18 when menu is unmapped. 19 (WebCore::PopupMenuGtk::resetTypeAheadFindState): Added. 20 (WebCore::PopupMenuGtk::selectItemCallback): Added. 21 (WebCore::PopupMenuGtk::keyPressEventCallback): Added. 22 * platform/gtk/PopupMenuGtk.h: Added new members to track typeahead 23 find state. 24 1 25 2010-12-01 Nikolas Zimmermann <nzimmermann@rim.com> 2 26 -
trunk/WebCore/platform/gtk/PopupMenuGtk.cpp
r72958 r73025 6 6 * Copyright (C) 2008 Collabora Ltd. 7 7 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). 8 * Copyright (C) 2010 Igalia S.L. 8 9 * 9 10 * This library is free software; you can redistribute it and/or … … 28 29 29 30 #include "FrameView.h" 31 #include "GOwnPtr.h" 30 32 #include "GtkVersioning.h" 31 33 #include "HostWindow.h" 32 34 #include "PlatformString.h" 35 #include <gdk/gdk.h> 36 #include <gtk/gtk.h> 33 37 #include <wtf/text/CString.h> 34 #include <gtk/gtk.h>35 38 36 39 namespace WebCore { 40 41 static const uint32_t gSearchTimeoutMs = 1000; 37 42 38 43 PopupMenuGtk::PopupMenuGtk(PopupMenuClient* client) 39 44 : m_popupClient(client) 45 , m_previousKeyEventCharacter(0) 46 , m_currentlySelectedMenuItem(0) 40 47 { 41 48 } … … 55 62 if (!m_popup) { 56 63 m_popup = GTK_MENU(gtk_menu_new()); 57 g_signal_connect(m_popup.get(), "unmap", G_CALLBACK(menuUnmapped), this); 64 g_signal_connect(m_popup.get(), "unmap", G_CALLBACK(PopupMenuGtk::menuUnmapped), this); 65 g_signal_connect(m_popup.get(), "key-press-event", G_CALLBACK(PopupMenuGtk::keyPressEventCallback), this); 58 66 } else 59 67 gtk_container_foreach(GTK_CONTAINER(m_popup.get()), reinterpret_cast<GtkCallback>(menuRemoveItem), this); … … 77 85 78 86 m_indexMap.add(item, i); 79 g_signal_connect(item, "activate", G_CALLBACK(menuItemActivated), this); 87 g_signal_connect(item, "activate", G_CALLBACK(PopupMenuGtk::menuItemActivated), this); 88 g_signal_connect(item, "select", G_CALLBACK(PopupMenuGtk::selectItemCallback), this); 80 89 81 90 // FIXME: Apply the PopupMenuStyle from client()->itemStyle(i) … … 142 151 } 143 152 153 bool PopupMenuGtk::typeAheadFind(GdkEventKey* event) 154 { 155 // If we were given a non-printable character just skip it. 156 gunichar unicodeCharacter = gdk_keyval_to_unicode(event->keyval); 157 if (!unicodeCharacter) { 158 resetTypeAheadFindState(); 159 return false; 160 } 161 162 glong charactersWritten; 163 GOwnPtr<gunichar2> utf16String(g_ucs4_to_utf16(&unicodeCharacter, 1, 0, &charactersWritten, 0)); 164 if (!utf16String) { 165 resetTypeAheadFindState(); 166 return false; 167 } 168 169 // If the character is the same as the last character, the user is probably trying to 170 // cycle through the menulist entries. This matches the WebCore behavior for collapsed 171 // menulists. 172 bool repeatingCharacter = unicodeCharacter != m_previousKeyEventCharacter; 173 if (event->time - m_previousKeyEventTimestamp > gSearchTimeoutMs) 174 m_currentSearchString = String(static_cast<UChar*>(utf16String.get()), charactersWritten); 175 else if (repeatingCharacter) 176 m_currentSearchString.append(String(static_cast<UChar*>(utf16String.get()), charactersWritten)); 177 178 m_previousKeyEventTimestamp = event->time; 179 m_previousKeyEventCharacter = unicodeCharacter; 180 181 // Like the Chromium port, we case fold before searching, because 182 // strncmp does not handle non-ASCII characters. 183 GOwnPtr<gchar> searchStringWithCaseFolded(g_utf8_casefold(m_currentSearchString.utf8().data(), -1)); 184 size_t prefixLength = strlen(searchStringWithCaseFolded.get()); 185 186 GList* children = gtk_container_get_children(GTK_CONTAINER(m_popup.get())); 187 if (!children) 188 return true; 189 190 // If a menu item has already been selected, start searching from the current 191 // item down the list. This will make multiple key presses of the same character 192 // advance the selection. GList* currentChild = children; 193 if (m_currentlySelectedMenuItem) { 194 currentChild = g_list_find(children, m_currentlySelectedMenuItem); 195 if (!currentChild) { 196 m_currentlySelectedMenuItem = 0; 197 currentChild = children; 198 } 199 200 // Repeating characters should iterate. 201 if (repeatingCharacter) { 202 if (GList* nextChild = g_list_next(currentChild)) 203 currentChild = nextChild; 204 } 205 } 206 207 GList* firstChild = currentChild; 208 do { 209 currentChild = g_list_next(currentChild); 210 if (!currentChild) 211 currentChild = children; 212 213 GOwnPtr<gchar> itemText(g_utf8_casefold(gtk_menu_item_get_label(GTK_MENU_ITEM(currentChild->data)), -1)); 214 if (!strncmp(searchStringWithCaseFolded.get(), itemText.get(), prefixLength)) { 215 gtk_menu_shell_select_item(GTK_MENU_SHELL(m_popup.get()), GTK_WIDGET(currentChild->data)); 216 return true; 217 } 218 } while (currentChild != firstChild); 219 220 return true; 221 } 222 144 223 void PopupMenuGtk::menuItemActivated(GtkMenuItem* item, PopupMenuGtk* that) 145 224 { … … 152 231 { 153 232 ASSERT(that->client()); 233 that->resetTypeAheadFindState(); 154 234 that->client()->popupDidHide(); 155 235 } … … 162 242 } 163 243 244 void PopupMenuGtk::resetTypeAheadFindState() 245 { 246 m_currentlySelectedMenuItem = 0; 247 m_previousKeyEventCharacter = 0; 248 m_currentSearchString = ""; 249 } 250 164 251 void PopupMenuGtk::menuRemoveItem(GtkWidget* widget, PopupMenuGtk* that) 165 252 { … … 168 255 } 169 256 170 } 171 257 int PopupMenuGtk::selectItemCallback(GtkMenuItem* item, PopupMenuGtk* that) 258 { 259 that->m_currentlySelectedMenuItem = GTK_WIDGET(item); 260 return FALSE; 261 } 262 263 int PopupMenuGtk::keyPressEventCallback(GtkWidget* widget, GdkEventKey* event, PopupMenuGtk* that) 264 { 265 return that->typeAheadFind(event); 266 } 267 268 } 269 -
trunk/WebCore/platform/gtk/PopupMenuGtk.h
r66531 r73025 25 25 #include "PopupMenu.h" 26 26 #include "PopupMenuClient.h" 27 #include <glib.h>28 27 #include <wtf/HashMap.h> 29 28 #include <wtf/PassRefPtr.h> 30 29 #include <wtf/RefCounted.h> 30 31 typedef struct _GdkEventKey GdkEventKey; 31 32 32 33 namespace WebCore { … … 44 45 virtual void updateFromElement(); 45 46 virtual void disconnectClient(); 47 bool typeAheadFind(GdkEventKey*); 46 48 47 49 private: 48 50 PopupMenuClient* client() const { return m_popupClient; } 51 void resetTypeAheadFindState(); 49 52 50 53 static void menuItemActivated(GtkMenuItem* item, PopupMenuGtk*); … … 52 55 static void menuPositionFunction(GtkMenu*, gint*, gint*, gboolean*, PopupMenuGtk*); 53 56 static void menuRemoveItem(GtkWidget*, PopupMenuGtk*); 57 static int selectItemCallback(GtkMenuItem*, PopupMenuGtk*); 58 static int keyPressEventCallback(GtkWidget*, GdkEventKey*, PopupMenuGtk*); 54 59 55 60 PopupMenuClient* m_popupClient; … … 57 62 PlatformRefPtr<GtkMenu> m_popup; 58 63 HashMap<GtkWidget*, int> m_indexMap; 64 String m_currentSearchString; 65 uint32_t m_previousKeyEventTimestamp; 66 unsigned int m_previousKeyEventCharacter; 67 GtkWidget* m_currentlySelectedMenuItem; 59 68 }; 60 69
Note:
See TracChangeset
for help on using the changeset viewer.