Changeset 56376 in webkit
- Timestamp:
- Mar 22, 2010 8:01:57 PM (14 years ago)
- Location:
- trunk
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r56375 r56376 1 2010-03-22 Jay Campan <jcampan@google.com> 2 3 Reviewed by Darin Fisher. 4 5 Making Chromium select popups not steal activation from the browser. 6 Select popups are now like autocomplete popups, shown in non-activated 7 windows. 8 https://bugs.webkit.org/show_bug.cgi?id=36062 9 10 * page/chromium/ChromeClientChromium.h: 11 * platform/chromium/PopupMenuChromium.cpp: 12 (WebCore::): 13 (WebCore::PopupContainer::create): 14 (WebCore::PopupContainer::PopupContainer): 15 (WebCore::PopupContainer::~PopupContainer): 16 (WebCore::PopupContainer::showPopup): 17 (WebCore::PopupContainer::showExternal): 18 (WebCore::PopupContainer::hidePopup): 19 (WebCore::PopupMenu::show): 20 * platform/chromium/PopupMenuChromium.h: 21 (WebCore::PopupContainer::): 22 (WebCore::PopupContainer::popupType): 23 1 24 2010-03-22 Dmitry Titov <dimich@chromium.org> 2 25 -
trunk/WebCore/page/chromium/ChromeClientChromium.h
r54584 r56376 49 49 // popup will be handled by the external embedder. 50 50 virtual void popupOpened(PopupContainer* popupContainer, const IntRect& bounds, 51 bool focusOnShow, bool handleExternal) = 0; 51 bool handleExternal) = 0; 52 53 // Notifies the client a popup was closed. 54 virtual void popupClosed(PopupContainer* popupContainer) = 0; 52 55 53 56 // Notifies embedder that the state of an accessibility object has changed. -
trunk/WebCore/platform/chromium/PopupMenuChromium.cpp
r55897 r56376 75 75 // This is the delegate used if none is provided. 76 76 static const PopupContainerSettings dropDownSettings = { 77 true, // focusOnShow78 77 true, // setTextOnIndexChange 79 78 true, // acceptOnAbandon … … 298 297 // static 299 298 PassRefPtr<PopupContainer> PopupContainer::create(PopupMenuClient* client, 299 PopupType popupType, 300 300 const PopupContainerSettings& settings) 301 301 { 302 return adoptRef(new PopupContainer(client, settings));302 return adoptRef(new PopupContainer(client, popupType, settings)); 303 303 } 304 304 305 305 PopupContainer::PopupContainer(PopupMenuClient* client, 306 PopupType popupType, 306 307 const PopupContainerSettings& settings) 307 308 : m_listBox(PopupListBox::create(client, settings)) 309 , m_popupType(popupType) 308 310 , m_settings(settings) 309 311 { … … 326 328 layout(); 327 329 328 ChromeClientChromium* chromeClient = static_cast<ChromeClientChromium*>(329 view->frame()->page()->chrome()->client());330 m_frameView = view; 331 ChromeClientChromium* chromeClient = chromeClientChromium(); 330 332 if (chromeClient) { 331 333 // If the popup would extend past the bottom of the screen, open upwards … … 336 338 widgetRect.move(0, -(widgetRect.height() + selectHeight)); 337 339 338 chromeClient->popupOpened(this, widgetRect, m_settings.focusOnShow,false);340 chromeClient->popupOpened(this, widgetRect, false); 339 341 } 340 342 … … 369 371 370 372 // Get the ChromeClient and pass it the popup menu's listbox data. 371 ChromeClientChromium* client = static_cast<ChromeClientChromium*>( 372 v->frame()->page()->chrome()->client()); 373 client->popupOpened(this, popupRect, true, true); 373 m_frameView = v; 374 chromeClientChromium()->popupOpened(this, popupRect, true); 374 375 375 376 // The popup sends its "closed" notification through its parent. Set the … … 383 384 { 384 385 listBox()->hidePopup(); 386 chromeClientChromium()->popupClosed(this); 385 387 } 386 388 … … 469 471 { 470 472 return m_listBox->isInterestedInEventForKey(keyCode); 473 } 474 475 ChromeClientChromium* PopupContainer::chromeClientChromium() 476 { 477 return static_cast<ChromeClientChromium*>(m_frameView->frame()->page()->chrome()->client()); 471 478 } 472 479 … … 1232 1239 { 1233 1240 if (!p.popup) 1234 p.popup = PopupContainer::create(client(), dropDownSettings);1241 p.popup = PopupContainer::create(client(), PopupContainer::Select, dropDownSettings); 1235 1242 #if OS(DARWIN) 1236 1243 p.popup->showExternal(r, v, index); -
trunk/WebCore/platform/chromium/PopupMenuChromium.h
r55897 r56376 40 40 namespace WebCore { 41 41 42 class FrameView; 43 class PopupListBox; 42 class ChromeClientChromium; 43 class FrameView; 44 class PopupListBox; 44 45 45 // A container for the data for each menu item (e.g. represented by <option> 46 // or <optgroup> in a <select> widget) and is used by PopupListBox. 47 struct PopupItem { 48 enum Type { 49 TypeOption, 50 TypeGroup, 51 TypeSeparator 52 }; 53 54 PopupItem(const String& label, Type type) 55 : label(label) 56 , type(type) 57 , yOffset(0) 58 { 59 } 60 String label; 61 Type type; 62 int yOffset; // y offset of this item, relative to the top of the popup. 63 bool enabled; 46 // A container for the data for each menu item (e.g. represented by <option> 47 // or <optgroup> in a <select> widget) and is used by PopupListBox. 48 struct PopupItem { 49 enum Type { 50 TypeOption, 51 TypeGroup, 52 TypeSeparator 64 53 }; 65 54 66 // FIXME: Our FramelessScrollView classes should probably implement HostWindow! 55 PopupItem(const String& label, Type type) 56 : label(label) 57 , type(type) 58 , yOffset(0) 59 { 60 } 61 String label; 62 Type type; 63 int yOffset; // y offset of this item, relative to the top of the popup. 64 bool enabled; 65 }; 67 66 68 // The PopupContainer class holds a PopupListBox (see cpp file). Its sole purpose is to be 69 // able to draw a border around its child. All its paint/event handling is 70 // just forwarded to the child listBox (with the appropriate transforms). 71 // NOTE: this class is exposed so it can be instantiated direcly for the 72 // autofill popup. We cannot use the Popup class directly in that case as the 73 // autofill popup should not be focused when shown and we want to forward the 74 // key events to it (through handleKeyEvent). 67 // FIXME: Our FramelessScrollView classes should probably implement HostWindow! 75 68 76 struct PopupContainerSettings { 77 // Whether the popup should get the focus when displayed. 78 bool focusOnShow; 69 // The PopupContainer class holds a PopupListBox (see cpp file). Its sole purpose is to be 70 // able to draw a border around its child. All its paint/event handling is 71 // just forwarded to the child listBox (with the appropriate transforms). 72 // NOTE: this class is exposed so it can be instantiated direcly for the 73 // autofill popup. We cannot use the Popup class directly in that case as the 74 // autofill popup should not be focused when shown and we want to forward the 75 // key events to it (through handleKeyEvent). 79 76 80 // Whether the PopupMenuClient should be told to change its text when a 81 // new item is selected by using the arrow keys. 82 bool setTextOnIndexChange; 77 struct PopupContainerSettings { 78 // Whether the PopupMenuClient should be told to change its text when a 79 // new item is selected by using the arrow keys. 80 bool setTextOnIndexChange; 83 81 84 85 86 87 88 82 // Whether the selection should be accepted when the popup menu is 83 // closed (through ESC being pressed or the focus going away). 84 // Note that when TAB is pressed, the selection is always accepted 85 // regardless of this setting. 86 bool acceptOnAbandon; 89 87 90 91 92 93 88 // Whether we should move the selection to the first/last item when 89 // the user presses down/up arrow keys and the last/first item is 90 // selected. 91 bool loopSelectionNavigation; 94 92 95 96 97 93 // Whether we should restrict the width of the PopupListBox or not. 94 // Autocomplete popups are restricted, combo-boxes (select tags) aren't. 95 bool restrictWidthOfListBox; 98 96 99 // A hint on the display directionality of the item text in popup menu. 100 // 101 // We could either display the items in the drop-down using its DOM element's 102 // directionality, or we could display the items in the drop-down using heuristics: 103 // such as in its first strong directionality character's direction. 104 // Please refer to the discussion (especially comment #7 and #10) in 105 // https://bugs.webkit.org/show_bug.cgi?id=27889 for details. 106 enum DirectionalityHint { 107 // Use the DOM element's directionality to display the item text in popup menu. 108 DOMElementDirection, 109 // Use the item text's first strong-directional character's directionality 110 // to display the item text in popup menu. 111 FirstStrongDirectionalCharacterDirection, 112 }; 113 DirectionalityHint itemTextDirectionalityHint; 97 // A hint on the display directionality of the item text in popup menu. 98 // 99 // We could either display the items in the drop-down using its DOM element's 100 // directionality, or we could display the items in the drop-down using heuristics: 101 // such as in its first strong directionality character's direction. 102 // Please refer to the discussion (especially comment #7 and #10) in 103 // https://bugs.webkit.org/show_bug.cgi?id=27889 for details. 104 enum DirectionalityHint { 105 // Use the DOM element's directionality to display the item text in popup menu. 106 DOMElementDirection, 107 // Use the item text's first strong-directional character's directionality 108 // to display the item text in popup menu. 109 FirstStrongDirectionalCharacterDirection, 110 }; 111 DirectionalityHint itemTextDirectionalityHint; 112 }; 113 114 class PopupContainer : public FramelessScrollView { 115 public: 116 enum PopupType { 117 Select, // HTML select popup. 118 Suggestion, // Autocomplete/autofill popup. 114 119 }; 115 120 116 class PopupContainer : public FramelessScrollView { 117 public: 118 static PassRefPtr<PopupContainer> create(PopupMenuClient*, 119 const PopupContainerSettings&); 121 static PassRefPtr<PopupContainer> create(PopupMenuClient*, PopupType, 122 const PopupContainerSettings&); 120 123 121 122 124 // Whether a key event should be sent to this popup. 125 virtual bool isInterestedInEventForKey(int keyCode); 123 126 124 125 126 127 128 129 130 131 127 // FramelessScrollView 128 virtual void paint(GraphicsContext*, const IntRect&); 129 virtual void hide(); 130 virtual bool handleMouseDownEvent(const PlatformMouseEvent&); 131 virtual bool handleMouseMoveEvent(const PlatformMouseEvent&); 132 virtual bool handleMouseReleaseEvent(const PlatformMouseEvent&); 133 virtual bool handleWheelEvent(const PlatformWheelEvent&); 134 virtual bool handleKeyEvent(const PlatformKeyboardEvent&); 132 135 133 136 // PopupContainer methods 134 137 135 136 138 // Show the popup 139 void showPopup(FrameView*); 137 140 138 139 141 // Used on Mac Chromium for HTML select popup menus. 142 void showExternal(const IntRect&, FrameView*, int index); 140 143 141 142 143 144 145 146 144 // Show the popup in the specified rect for the specified frame. 145 // Note: this code was somehow arbitrarily factored-out of the Popup class 146 // so WebViewImpl can create a PopupContainer. This method is used for 147 // displaying auto complete popup menus on Mac Chromium, and for all 148 // popups on other platforms. 149 void show(const IntRect&, FrameView*, int index); 147 150 148 149 151 // Hide the popup. 152 void hidePopup(); 150 153 151 152 154 // Compute size of widget and children. 155 void layout(); 153 156 154 157 PopupListBox* listBox() const { return m_listBox.get(); } 155 158 156 157 158 159 // Gets the index of the item that the user is currently moused-over or 160 // has selected with the keyboard up/down arrows. 161 int selectedIndex() const; 159 162 160 161 163 // Refresh the popup values from the PopupMenuClient. 164 void refresh(); 162 165 163 164 166 // The menu per-item data. 167 const WTF::Vector<PopupItem*>& popupData() const; 165 168 166 167 169 // The height of a row in the menu. 170 int menuItemHeight() const; 168 171 169 170 172 // The size of the font being used. 173 int menuItemFontSize() const; 171 174 172 private: 173 friend class WTF::RefCounted<PopupContainer>; 175 PopupType popupType() const { return m_popupType; } 174 176 175 PopupContainer(PopupMenuClient*, const PopupContainerSettings&); 176 ~PopupContainer();177 private: 178 friend class WTF::RefCounted<PopupContainer>; 177 179 178 // Paint the border.179 void paintBorder(GraphicsContext*, const IntRect&);180 PopupContainer(PopupMenuClient*, PopupType popupType, const PopupContainerSettings&); 181 ~PopupContainer(); 180 182 181 RefPtr<PopupListBox> m_listBox; 183 // Paint the border. 184 void paintBorder(GraphicsContext*, const IntRect&); 182 185 183 PopupContainerSettings m_settings; 184 }; 186 // Returns the ChromeClient of the page this popup is associated with. 187 ChromeClientChromium* chromeClientChromium(); 188 189 RefPtr<PopupListBox> m_listBox; 190 RefPtr<FrameView> m_frameView; 191 192 PopupContainerSettings m_settings; 193 PopupType m_popupType; 194 }; 185 195 186 196 } // namespace WebCore -
trunk/WebKit/chromium/ChangeLog
r56346 r56376 1 2010-03-22 Jay Campan <jcampan@google.com> 2 3 Reviewed by Darin Fisher. 4 5 Making Chromium select popups not steal activation from the browser. 6 Select popups are now like autocomplete popups, shown in non-activated 7 windows. 8 https://bugs.webkit.org/show_bug.cgi?id=36062 9 10 * public/WebViewClient.h: 11 (WebKit::WebViewClient::createPopupMenu): 12 * src/ChromeClientImpl.cpp: 13 (WebKit::ChromeClientImpl::popupOpened): 14 (WebKit::ChromeClientImpl::popupClosed): 15 * src/ChromeClientImpl.h: 16 * src/WebViewImpl.cpp: 17 (WebKit::): 18 (WebKit::WebViewImpl::mouseDown): 19 (WebKit::WebViewImpl::keyEvent): 20 (WebKit::WebViewImpl::selectPopupHandleKeyEvent): 21 (WebKit::WebViewImpl::hideSelectPopup): 22 (WebKit::WebViewImpl::popupOpened): 23 (WebKit::WebViewImpl::popupClosed): 24 (WebKit::WebViewImpl::setFocus): 25 (WebKit::WebViewImpl::applyAutoFillSuggestions): 26 (WebKit::WebViewImpl::applyAutocompleteSuggestions): 27 * src/WebViewImpl.h: 28 1 29 2010-03-22 Darin Fisher <darin@chromium.org> 2 30 -
trunk/WebKit/chromium/public/WebViewClient.h
r55037 r56376 74 74 // Create a new WebPopupMenu. In the second form, the client is 75 75 // responsible for rendering the contents of the popup menu. 76 virtual WebWidget* createPopupMenu() { return 0; } 77 virtual WebWidget* createPopupMenu(const WebPopupMenuInfo&) { return 0; } 78 // Deprecated method. 76 79 virtual WebWidget* createPopupMenu(bool activatable) { return 0; } 77 virtual WebWidget* createPopupMenu(const WebPopupMenuInfo&) { return 0; } 80 78 81 79 82 // Create a session storage namespace object associated with this WebView. -
trunk/WebKit/chromium/src/ChromeClientImpl.cpp
r56212 r56376 596 596 void ChromeClientImpl::popupOpened(PopupContainer* popupContainer, 597 597 const IntRect& bounds, 598 bool activatable,599 598 bool handleExternally) 600 599 { … … 607 606 getPopupMenuInfo(popupContainer, &popupInfo); 608 607 webwidget = m_webView->client()->createPopupMenu(popupInfo); 609 } else 610 webwidget = m_webView->client()->createPopupMenu(activatable); 611 608 } else { 609 webwidget = m_webView->client()->createPopupMenu(); 610 if (!webwidget) { 611 // Try the deprecated method. 612 webwidget = m_webView->client()->createPopupMenu(false); 613 } 614 } 615 m_webView->popupOpened(popupContainer); 612 616 static_cast<WebPopupMenuImpl*>(webwidget)->Init(popupContainer, bounds); 617 } 618 619 void ChromeClientImpl::popupClosed(WebCore::PopupContainer* popupContainer) 620 { 621 m_webView->popupClosed(popupContainer); 613 622 } 614 623 -
trunk/WebKit/chromium/src/ChromeClientImpl.h
r56212 r56376 149 149 virtual void popupOpened(WebCore::PopupContainer* popupContainer, 150 150 const WebCore::IntRect& bounds, 151 bool activatable,152 151 bool handleExternally); 152 virtual void popupClosed(WebCore::PopupContainer* popupContainer); 153 153 virtual void didChangeAccessibilityObjectState(WebCore::AccessibilityObject*); 154 154 -
trunk/WebKit/chromium/src/WebViewImpl.cpp
r56212 r56376 150 150 COMPILE_ASSERT_MATCHING_ENUM(DragOperationEvery); 151 151 152 // Note that focusOnShow is false so that the suggestions popup is shown not153 // activated. We need the page to still have focus so the user can keep typing154 // while the popup is showing.155 152 static const PopupContainerSettings suggestionsPopupSettings = { 156 false, // focusOnShow157 153 false, // setTextOnIndexChange 158 154 false, // acceptOnAbandon … … 331 327 if (!mainFrameImpl() || !mainFrameImpl()->frameView()) 332 328 return; 329 330 // If there is a select popup opened, close it as the user is clicking on 331 // the page (outside of the popup). 332 hideSelectPopup(); 333 333 334 334 m_lastMouseDownPoint = WebPoint(event.x, event.y); … … 479 479 m_suppressNextKeypressEvent = false; 480 480 481 // Give any select popup a chance at consuming the key event. 482 if (selectPopupHandleKeyEvent(event)) 483 return true; 484 481 485 // Give Autocomplete a chance to consume the key events it is interested in. 482 486 if (autocompleteHandleKeyEvent(event)) … … 526 530 527 531 return keyEventDefault(event); 532 } 533 534 bool WebViewImpl::selectPopupHandleKeyEvent(const WebKeyboardEvent& event) 535 { 536 if (!m_selectPopup) 537 return false; 538 539 return m_selectPopup->handleKeyEvent(PlatformKeyboardEventBuilder(event)); 528 540 } 529 541 … … 798 810 } 799 811 812 void WebViewImpl::hideSelectPopup() 813 { 814 if (m_selectPopup.get()) 815 m_selectPopup->hidePopup(); 816 } 817 800 818 bool WebViewImpl::propagateScroll(ScrollDirection scrollDirection, 801 819 ScrollGranularity scrollGranularity) … … 815 833 } 816 834 return scrollHandled; 835 } 836 837 void WebViewImpl::popupOpened(WebCore::PopupContainer* popupContainer) 838 { 839 if (popupContainer->popupType() == WebCore::PopupContainer::Select) { 840 ASSERT(!m_selectPopup); 841 m_selectPopup = popupContainer; 842 } 843 } 844 845 void WebViewImpl::popupClosed(WebCore::PopupContainer* popupContainer) 846 { 847 if (popupContainer->popupType() == WebCore::PopupContainer::Select) { 848 ASSERT(m_selectPopup.get()); 849 m_selectPopup = 0; 850 } 817 851 } 818 852 … … 1069 1103 } else { 1070 1104 hideSuggestionsPopup(); 1105 hideSelectPopup(); 1071 1106 1072 1107 // Clear focus on the currently focused frame if any. … … 1694 1729 if (!m_autoFillPopup.get()) { 1695 1730 m_autoFillPopup = PopupContainer::create(m_suggestionsPopupClient, 1731 PopupContainer::Suggestion, 1696 1732 suggestionsPopupSettings); 1697 1733 } … … 1749 1785 if (!m_autocompletePopup.get()) { 1750 1786 m_autocompletePopup = PopupContainer::create(m_suggestionsPopupClient, 1787 PopupContainer::Suggestion, 1751 1788 suggestionsPopupSettings); 1752 1789 } -
trunk/WebKit/chromium/src/WebViewImpl.h
r56212 r56376 293 293 bool propagateScroll(WebCore::ScrollDirection, WebCore::ScrollGranularity); 294 294 295 // Notification that a popup was opened/closed. 296 void popupOpened(WebCore::PopupContainer* popupContainer); 297 void popupClosed(WebCore::PopupContainer* popupContainer); 298 295 299 // HACK: currentInputEvent() is for ChromeClientImpl::show(), until we can 296 300 // fix WebKit to pass enough information up into ChromeClient::show() so we … … 316 320 bool keyEventDefault(const WebKeyboardEvent&); 317 321 322 // Returns true if the select popup has consumed the event. 323 bool selectPopupHandleKeyEvent(const WebKeyboardEvent&); 324 318 325 // Returns true if the autocomple has consumed the event. 319 326 bool autocompleteHandleKeyEvent(const WebKeyboardEvent&); … … 326 333 // Returns true if the view was scrolled. 327 334 bool scrollViewWithKeyboard(int keyCode, int modifiers); 335 336 // Hides the select popup if one is opened. 337 void hideSelectPopup(); 328 338 329 339 // Converts |pos| from window coordinates to contents coordinates and gets … … 440 450 WebCore::PopupContainer* m_suggestionsPopup; 441 451 452 // The popup associated with a select element. 453 RefPtr<WebCore::PopupContainer> m_selectPopup; 454 442 455 // The AutoFill suggestions popup. 443 456 RefPtr<WebCore::PopupContainer> m_autoFillPopup;
Note: See TracChangeset
for help on using the changeset viewer.