Changeset 48446 in webkit
- Timestamp:
- Sep 16, 2009 4:25:58 PM (15 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r48443 r48446 1 2009-09-16 Anders Carlsson <andersca@apple.com> 2 3 Reviewed by Adam Roben. 4 5 <rdar://problem/7155710> 6 HTML selects on windows cause containing window to become inactive when opened 7 8 Redo the way we handle events when a popup menu is shown, based on 9 http://blogs.msdn.com/oldnewthing/archive/2004/08/20/217684.aspx 10 11 Since a non-active window can't capture the mouse, we use the owning window 12 (the WebView) as the capture window. We then run a recursive message pump that 13 forwards all mouse and keyboard events to the popup menu. 14 15 * platform/PopupMenu.h: 16 * platform/win/PopupMenuWin.cpp: 17 (WebCore::PopupMenu::PopupMenu): 18 (WebCore::PopupMenu::show): 19 (WebCore::PopupMenu::hide): 20 (WebCore::PopupMenu::wndProc): 21 1 22 2009-09-16 Dan Bernstein <mitz@apple.com> 2 23 -
trunk/WebCore/platform/PopupMenu.h
r48375 r48446 173 173 int m_focusedIndex; 174 174 bool m_scrollbarCapturingMouse; 175 bool m_showPopup; 175 176 #elif PLATFORM(GTK) 176 177 IntPoint m_menuPosition; -
trunk/WebCore/platform/win/PopupMenuWin.cpp
r48396 r48446 62 62 static LPCTSTR kPopupWindowClassName = _T("PopupWindowClass"); 63 63 64 // This is used from within our custom message pump when we want to send a 65 // WM_CHAR message to the web view and not have our message stolen and sent to 66 // the popup window. 67 static const UINT WM_HOST_WINDOW_CHAR = WM_USER; 68 64 69 // FIXME: Remove this as soon as practical. 65 70 static inline bool isASCIIPrintable(unsigned c) … … 80 85 , m_focusedIndex(0) 81 86 , m_scrollbarCapturingMouse(false) 87 , m_showPopup(false) 82 88 { 83 89 } … … 126 132 if (!m_popup) 127 133 return; 134 } else { 135 // We need to reposition the popup window. 136 ::MoveWindow(m_popup, m_windowRect.x(), m_windowRect.y(), m_windowRect.width(), m_windowRect.height(), false); 128 137 } 129 138 … … 143 152 DWORD slideDirection = (m_windowRect.y() < viewRect.top + view->contentsToWindow(r.location()).y()) ? AW_VER_NEGATIVE : AW_VER_POSITIVE; 144 153 145 ::AnimateWindow(m_popup, defaultAnimationDuration, AW_SLIDE | slideDirection | AW_ACTIVATE);154 ::AnimateWindow(m_popup, defaultAnimationDuration, AW_SLIDE | slideDirection); 146 155 } 147 156 } else 148 157 #endif 149 ::ShowWindow(m_popup, SW_SHOWNORMAL); 150 ::SetCapture(m_popup); 158 ::ShowWindow(m_popup, SW_SHOWNOACTIVATE); 151 159 152 160 if (client()) { … … 155 163 setFocusedIndex(index); 156 164 } 165 166 m_showPopup = true; 167 168 ::SetCapture(hostWindow); 169 170 MSG msg; 171 HWND activeWindow; 172 173 while (::GetMessage(&msg, 0, 0, 0)) { 174 switch (msg.message) { 175 case WM_HOST_WINDOW_CHAR: 176 if (msg.hwnd == m_popup) { 177 // This message should be sent to the host window as a WM_CHAR. 178 msg.hwnd = hostWindow; 179 msg.message = WM_CHAR; 180 } 181 break; 182 183 // Steal mouse messages. 184 case WM_NCMOUSEMOVE: 185 case WM_NCLBUTTONDOWN: 186 case WM_NCLBUTTONUP: 187 case WM_NCLBUTTONDBLCLK: 188 case WM_NCRBUTTONDOWN: 189 case WM_NCRBUTTONUP: 190 case WM_NCRBUTTONDBLCLK: 191 case WM_NCMBUTTONDOWN: 192 case WM_NCMBUTTONUP: 193 case WM_NCMBUTTONDBLCLK: 194 case WM_MOUSEWHEEL: 195 msg.hwnd = m_popup; 196 break; 197 198 // These mouse messages use client coordinates so we need to convert them. 199 case WM_MOUSEMOVE: 200 case WM_LBUTTONDOWN: 201 case WM_LBUTTONUP: 202 case WM_LBUTTONDBLCLK: 203 case WM_RBUTTONDOWN: 204 case WM_RBUTTONUP: 205 case WM_RBUTTONDBLCLK: 206 case WM_MBUTTONDOWN: 207 case WM_MBUTTONUP: 208 case WM_MBUTTONDBLCLK: { 209 POINT pt; 210 pt.x = (short)LOWORD(msg.lParam); 211 pt.y = (short)HIWORD(msg.lParam); 212 ::MapWindowPoints(msg.hwnd, m_popup, &pt, 1); 213 msg.lParam = MAKELPARAM(pt.x, pt.y); 214 msg.hwnd = m_popup; 215 break; 216 } 217 218 // Steal all keyboard messages. 219 case WM_KEYDOWN: 220 case WM_KEYUP: 221 case WM_CHAR: 222 case WM_DEADCHAR: 223 case WM_SYSKEYUP: 224 case WM_SYSCHAR: 225 case WM_SYSDEADCHAR: 226 msg.hwnd = m_popup; 227 break; 228 } 229 230 ::TranslateMessage(&msg); 231 ::DispatchMessage(&msg); 232 233 if (!m_showPopup) 234 break; 235 activeWindow = ::GetActiveWindow(); 236 if (activeWindow != hostWindow && !::IsChild(activeWindow, hostWindow)) 237 break; 238 if (::GetCapture() != hostWindow) 239 break; 240 } 241 242 if (::GetCapture() == hostWindow) 243 ::ReleaseCapture(); 244 245 // We're done, hide the popup if necessary. 246 hide(); 157 247 } 158 248 159 249 void PopupMenu::hide() 160 250 { 251 if (!m_showPopup) 252 return; 253 254 m_showPopup = false; 255 161 256 ::ShowWindow(m_popup, SW_HIDE); 162 257 163 258 if (client()) 164 259 client()->popupDidHide(); 260 261 // Post a WM_NULL message to wake up the message pump if necessary. 262 ::PostMessage(m_popup, WM_NULL, 0, 0); 165 263 } 166 264 … … 661 759 662 760 switch (message) { 761 case WM_MOUSEACTIVATE: 762 return MA_NOACTIVATE; 763 663 764 case WM_SIZE: { 664 765 if (!scrollbar()) … … 675 776 break; 676 777 } 677 case WM_ACTIVATE:678 if (wParam == WA_INACTIVE)679 hide();680 break;681 case WM_KILLFOCUS:682 if ((HWND)wParam != popupHandle())683 // Focus is going elsewhere, so hide684 hide();685 break;686 778 case WM_KEYDOWN: 687 779 if (!client()) … … 735 827 if (isASCIIPrintable(wParam)) 736 828 // Send the keydown to the WebView so it can be used for type-to-select. 737 ::PostMessage(client()->hostWindow()->platformWindow(), message, wParam, lParam); 829 // Since we know that the virtual key is ASCII printable, it's OK to convert this to 830 // a WM_CHAR message. (We don't want to call TranslateMessage because that will post a 831 // WM_CHAR message that will be stolen and redirected to the popup HWND. 832 ::PostMessage(m_popup, WM_HOST_WINDOW_CHAR, wParam, lParam); 738 833 else 739 834 lResult = 1; … … 789 884 setFocusedIndex(listIndexAtPoint(mousePoint), true); 790 885 791 // Release capture if the left button isn't down, and the mousePoint is outside the popup window.792 // This way, the WebView will get future mouse events in the rest of the window.793 if (!(wParam & MK_LBUTTON) && !::PtInRect(&bounds, mousePoint))794 ::ReleaseCapture();795 796 886 break; 797 887 } 798 888 case WM_LBUTTONDOWN: { 799 ::SetCapture(popupHandle());800 889 IntPoint mousePoint(MAKEPOINTS(lParam)); 801 890 if (scrollbar()) { … … 811 900 } 812 901 813 setFocusedIndex(listIndexAtPoint(mousePoint), true); 902 // If the mouse is inside the window, update the focused index. Otherwise, 903 // hide the popup. 904 RECT bounds; 905 GetClientRect(m_popup, &bounds); 906 if (::PtInRect(&bounds, mousePoint)) 907 setFocusedIndex(listIndexAtPoint(mousePoint), true); 908 else 909 hide(); 814 910 break; 815 911 } … … 817 913 IntPoint mousePoint(MAKEPOINTS(lParam)); 818 914 if (scrollbar()) { 819 ::ReleaseCapture();820 915 IntRect scrollBarRect = scrollbar()->frameRect(); 821 916 if (scrollbarCapturingMouse() || scrollBarRect.contains(mousePoint)) { … … 831 926 } 832 927 } 833 // Only release capture andhide the popup if the mouse is inside the popup window.928 // Only hide the popup if the mouse is inside the popup window. 834 929 RECT bounds; 835 930 GetClientRect(popupHandle(), &bounds); 836 931 if (client() && ::PtInRect(&bounds, mousePoint)) { 837 ::ReleaseCapture();838 932 hide(); 839 933 int index = focusedIndex(); … … 843 937 break; 844 938 } 845 case WM_MOUSEWHEEL: 846 if (scrollbar()) { 847 int i = 0; 848 for (incrementWheelDelta(GET_WHEEL_DELTA_WPARAM(wParam)); abs(wheelDelta()) >= WHEEL_DELTA; reduceWheelDelta(WHEEL_DELTA)) { 849 if (wheelDelta() > 0) 850 ++i; 851 else 852 --i; 853 } 854 scrollbar()->scroll(i > 0 ? ScrollUp : ScrollDown, ScrollByLine, abs(i)); 939 940 case WM_MOUSEWHEEL: { 941 if (!scrollbar()) 942 break; 943 944 int i = 0; 945 for (incrementWheelDelta(GET_WHEEL_DELTA_WPARAM(wParam)); abs(wheelDelta()) >= WHEEL_DELTA; reduceWheelDelta(WHEEL_DELTA)) { 946 if (wheelDelta() > 0) 947 ++i; 948 else 949 --i; 855 950 } 856 break; 951 scrollbar()->scroll(i > 0 ? ScrollUp : ScrollDown, ScrollByLine, abs(i)); 952 break; 953 } 954 857 955 case WM_PAINT: { 858 956 PAINTSTRUCT paintInfo;
Note: See TracChangeset
for help on using the changeset viewer.