Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(336)

Side by Side Diff: ui/views/win/hwnd_message_handler.cc

Issue 59043012: Get rid of the 1-pixel client inset hack. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Re-add comment about remaining issue. Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ui/views/win/hwnd_message_handler.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/views/win/hwnd_message_handler.h" 5 #include "ui/views/win/hwnd_message_handler.h"
6 6
7 #include <dwmapi.h> 7 #include <dwmapi.h>
8 #include <shellapi.h> 8 #include <shellapi.h>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 } 292 }
293 293
294 return false; 294 return false;
295 } 295 }
296 296
297 #endif 297 #endif
298 298
299 // The thickness of an auto-hide taskbar in pixels. 299 // The thickness of an auto-hide taskbar in pixels.
300 const int kAutoHideTaskbarThicknessPx = 2; 300 const int kAutoHideTaskbarThicknessPx = 2;
301 301
302 // For windows with the standard frame removed, the client area needs to be
303 // different from the window area to avoid a "feature" in Windows's handling of
304 // WM_NCCALCSIZE data. See the comment near the bottom of GetClientAreaInsets
305 // for more details.
306 const int kClientAreaBottomInsetHack = -1;
307
308 } // namespace 302 } // namespace
309 303
310 // A scoping class that prevents a window from being able to redraw in response 304 // A scoping class that prevents a window from being able to redraw in response
311 // to invalidations that may occur within it for the lifetime of the object. 305 // to invalidations that may occur within it for the lifetime of the object.
312 // 306 //
313 // Why would we want such a thing? Well, it turns out Windows has some 307 // Why would we want such a thing? Well, it turns out Windows has some
314 // "unorthodox" behavior when it comes to painting its non-client areas. 308 // "unorthodox" behavior when it comes to painting its non-client areas.
315 // Occasionally, Windows will paint portions of the default non-client area 309 // Occasionally, Windows will paint portions of the default non-client area
316 // right over the top of the custom frame. This is not simply fixed by handling 310 // right over the top of the custom frame. This is not simply fixed by handling
317 // WM_NCPAINT/WM_PAINT, with some investigation it turns out that this 311 // WM_NCPAINT/WM_PAINT, with some investigation it turns out that this
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after
779 // change from opaque to glass. "Non client rendering enabled" means that 773 // change from opaque to glass. "Non client rendering enabled" means that
780 // the DWM's glass non-client rendering is enabled, which is why 774 // the DWM's glass non-client rendering is enabled, which is why
781 // DWMNCRP_ENABLED is used for the native frame case. _DISABLED means the 775 // DWMNCRP_ENABLED is used for the native frame case. _DISABLED means the
782 // DWM doesn't render glass, and so is used in the custom frame case. 776 // DWM doesn't render glass, and so is used in the custom frame case.
783 DWMNCRENDERINGPOLICY policy = !delegate_->IsUsingCustomFrame() ? 777 DWMNCRENDERINGPOLICY policy = !delegate_->IsUsingCustomFrame() ?
784 DWMNCRP_ENABLED : DWMNCRP_DISABLED; 778 DWMNCRP_ENABLED : DWMNCRP_DISABLED;
785 DwmSetWindowAttribute(hwnd(), DWMWA_NCRENDERING_POLICY, 779 DwmSetWindowAttribute(hwnd(), DWMWA_NCRENDERING_POLICY,
786 &policy, sizeof(DWMNCRENDERINGPOLICY)); 780 &policy, sizeof(DWMNCRENDERINGPOLICY));
787 } 781 }
788 782
789 ResetWindowRegion(true); 783 // Don't redraw the window here, because we need to hide and show the window
784 // which will also trigger a redraw.
785 ResetWindowRegion(true, false);
786
787 ::SetWindowPos(hwnd(), NULL, 0, 0, 0, 0,
788 SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
789
790 // For some reason, we need to hide the window after we change the frame type.
791 // If we don't, the client area will be filled with black. This is somehow
792 // related to an interaction between SetWindowRgn and Dwm, but it's not clear
793 // exactly what.
794 //
795 // One remaining problem is that when GPU is enabled on Win7, the title bar
796 // will still be black after switching from Win7 classic theme -> win7 aero
jbauman 2013/11/08 21:38:26 Is FrameTypeChanged being correctly called on the
797 // theme. This does not happen with --disable-gpu, or when a gpu is not
798 // present, so this is likely to be a bug in the gpu process.
799 if (IsVisible()) {
800 SetWindowPos(hwnd(), NULL, 0, 0, 0, 0,
801 SWP_NOMOVE | SWP_NOSIZE | SWP_HIDEWINDOW);
802 SetWindowPos(hwnd(), NULL, 0, 0, 0, 0,
803 SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
804 }
805
806 UpdateWindow(hwnd());
790 807
791 // The non-client view needs to update too. 808 // The non-client view needs to update too.
792 delegate_->HandleFrameChanged(); 809 delegate_->HandleFrameChanged();
793 810
794 // WM_DWMCOMPOSITIONCHANGED is only sent to top level windows, however we want 811 // WM_DWMCOMPOSITIONCHANGED is only sent to top level windows, however we want
795 // to notify our children too, since we can have MDI child windows who need to 812 // to notify our children too, since we can have MDI child windows who need to
796 // update their appearance. 813 // update their appearance.
797 EnumChildWindows(hwnd(), &SendDwmCompositionChanged, NULL); 814 EnumChildWindows(hwnd(), &SendDwmCompositionChanged, NULL);
798 } 815 }
799 816
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
1036 TrackMouseEvents(active_mouse_tracking_flags_ | TME_CANCEL); 1053 TrackMouseEvents(active_mouse_tracking_flags_ | TME_CANCEL);
1037 TrackMouseEvents(mouse_tracking_flags); 1054 TrackMouseEvents(mouse_tracking_flags);
1038 } 1055 }
1039 } 1056 }
1040 1057
1041 void HWNDMessageHandler::ClientAreaSizeChanged() { 1058 void HWNDMessageHandler::ClientAreaSizeChanged() {
1042 RECT r = {0, 0, 0, 0}; 1059 RECT r = {0, 0, 0, 0};
1043 // In case of minimized window GetWindowRect can return normally unexpected 1060 // In case of minimized window GetWindowRect can return normally unexpected
1044 // coordinates. 1061 // coordinates.
1045 if (!IsMinimized()) { 1062 if (!IsMinimized()) {
1046 if (delegate_->WidgetSizeIsClientSize()) { 1063 if (delegate_->WidgetSizeIsClientSize())
1047 GetClientRect(hwnd(), &r); 1064 GetClientRect(hwnd(), &r);
1048 gfx::Insets insets; 1065 else
1049 bool got_insets = GetClientAreaInsets(&insets);
1050 if (got_insets) {
1051 // This is needed due to a hack that works around a "feature" in
1052 // Windows's handling of WM_NCCALCSIZE. See the comment near the end of
1053 // GetClientAreaInsets for more details.
1054 if ((remove_standard_frame_ && !IsMaximized()) ||
1055 !fullscreen_handler_->fullscreen()) {
1056 r.bottom += kClientAreaBottomInsetHack;
1057 }
1058 }
1059 } else {
1060 GetWindowRect(hwnd(), &r); 1066 GetWindowRect(hwnd(), &r);
1061 }
1062 } 1067 }
1063 gfx::Size s(std::max(0, static_cast<int>(r.right - r.left)), 1068 gfx::Size s(std::max(0, static_cast<int>(r.right - r.left)),
1064 std::max(0, static_cast<int>(r.bottom - r.top))); 1069 std::max(0, static_cast<int>(r.bottom - r.top)));
1065 delegate_->HandleClientSizeChanged(s); 1070 delegate_->HandleClientSizeChanged(s);
1066 if (use_layered_buffer_) 1071 if (use_layered_buffer_)
1067 layered_window_contents_.reset(new gfx::Canvas(s, 1.0f, false)); 1072 layered_window_contents_.reset(new gfx::Canvas(s, 1.0f, false));
1068 } 1073 }
1069 1074
1070 bool HWNDMessageHandler::GetClientAreaInsets(gfx::Insets* insets) const { 1075 bool HWNDMessageHandler::GetClientAreaInsets(gfx::Insets* insets) const {
1071 if (delegate_->GetClientAreaInsets(insets)) 1076 if (delegate_->GetClientAreaInsets(insets))
(...skipping 11 matching lines...) Expand all
1083 // Windows automatically adds a standard width border to all sides when a 1088 // Windows automatically adds a standard width border to all sides when a
1084 // window is maximized. 1089 // window is maximized.
1085 int border_thickness = GetSystemMetrics(SM_CXSIZEFRAME); 1090 int border_thickness = GetSystemMetrics(SM_CXSIZEFRAME);
1086 if (remove_standard_frame_) 1091 if (remove_standard_frame_)
1087 border_thickness -= 1; 1092 border_thickness -= 1;
1088 *insets = gfx::Insets( 1093 *insets = gfx::Insets(
1089 border_thickness, border_thickness, border_thickness, border_thickness); 1094 border_thickness, border_thickness, border_thickness, border_thickness);
1090 return true; 1095 return true;
1091 } 1096 }
1092 1097
1093 // Returning empty insets for a window with the standard frame removed seems 1098 *insets = gfx::Insets(0, 0, 0, 0);
1094 // to cause Windows to treat the window specially, treating black as
1095 // transparent and changing around some of the painting logic. I suspect it's
1096 // some sort of horrible backwards-compatability hack, but the upshot of it
1097 // is that if the insets are empty then in certain conditions (it seems to
1098 // be subtly related to timing), the contents of windows with the standard
1099 // frame removed will flicker to transparent during resize.
1100 //
1101 // To work around this, we increase the size of the client area by 1px
1102 // *beyond* the bottom of the window. This prevents Windows from having a
1103 // hissy fit and flashing the window incessantly during resizes, but it also
1104 // means that the client area is reported 1px larger than it really is, so
1105 // user code has to compensate by making its content shorter if it wants
1106 // everything to appear inside the window.
1107 if (remove_standard_frame_) {
1108 *insets =
1109 gfx::Insets(0, 0, IsMaximized() ? 0 : kClientAreaBottomInsetHack, 0);
1110 return true;
1111 }
1112
1113 // This is weird, but highly essential. If we don't offset the bottom edge
1114 // of the client rect, the window client area and window area will match,
1115 // and when returning to glass rendering mode from non-glass, the client
1116 // area will not paint black as transparent. This is because (and I don't
1117 // know why) the client area goes from matching the window rect to being
1118 // something else. If the client area is not the window rect in both
1119 // modes, the blackness doesn't occur. Because of this, we need to tell
1120 // the RootView to lay out to fit the window rect, rather than the client
1121 // rect when using the opaque frame.
1122 // Note: this is only required for non-fullscreen windows. Note that
1123 // fullscreen windows are in restored state, not maximized.
1124 // Note that previously we used to inset by 1 instead of outset, but that
1125 // doesn't work with Aura: http://crbug.com/172099 http://crbug.com/277228
1126 *insets = gfx::Insets(
1127 0, 0,
1128 fullscreen_handler_->fullscreen() ? 0 : kClientAreaBottomInsetHack, 0);
1129 return true; 1099 return true;
1130 } 1100 }
1131 1101
1132 void HWNDMessageHandler::ResetWindowRegion(bool force) { 1102 void HWNDMessageHandler::ResetWindowRegion(bool force, bool redraw) {
1133 // A native frame uses the native window region, and we don't want to mess 1103 // A native frame uses the native window region, and we don't want to mess
1134 // with it. 1104 // with it.
1135 // WS_EX_COMPOSITED is used instead of WS_EX_LAYERED under aura. WS_EX_LAYERED 1105 // WS_EX_COMPOSITED is used instead of WS_EX_LAYERED under aura. WS_EX_LAYERED
1136 // automatically makes clicks on transparent pixels fall through, that isn't 1106 // automatically makes clicks on transparent pixels fall through, that isn't
1137 // the case with WS_EX_COMPOSITED. So, we route WS_EX_COMPOSITED through to 1107 // the case with WS_EX_COMPOSITED. So, we route WS_EX_COMPOSITED through to
1138 // the delegate to allow for a custom hit mask. 1108 // the delegate to allow for a custom hit mask.
1139 if ((window_ex_style() & WS_EX_COMPOSITED) == 0 && 1109 if ((window_ex_style() & WS_EX_COMPOSITED) == 0 &&
1140 (!delegate_->IsUsingCustomFrame() || !delegate_->IsWidgetWindow())) { 1110 (!delegate_->IsUsingCustomFrame() || !delegate_->IsWidgetWindow())) {
1141 if (force) 1111 if (force)
1142 SetWindowRgn(hwnd(), NULL, TRUE); 1112 SetWindowRgn(hwnd(), NULL, redraw);
1143 return; 1113 return;
1144 } 1114 }
1145 1115
1146 // Changing the window region is going to force a paint. Only change the 1116 // Changing the window region is going to force a paint. Only change the
1147 // window region if the region really differs. 1117 // window region if the region really differs.
1148 HRGN current_rgn = CreateRectRgn(0, 0, 0, 0); 1118 HRGN current_rgn = CreateRectRgn(0, 0, 0, 0);
1149 int current_rgn_result = GetWindowRgn(hwnd(), current_rgn); 1119 int current_rgn_result = GetWindowRgn(hwnd(), current_rgn);
1150 1120
1151 CRect window_rect; 1121 CRect window_rect;
1152 GetWindowRect(hwnd(), &window_rect); 1122 GetWindowRect(hwnd(), &window_rect);
1153 HRGN new_region; 1123 HRGN new_region;
1154 if (IsMaximized()) { 1124 if (IsMaximized()) {
1155 HMONITOR monitor = MonitorFromWindow(hwnd(), MONITOR_DEFAULTTONEAREST); 1125 HMONITOR monitor = MonitorFromWindow(hwnd(), MONITOR_DEFAULTTONEAREST);
1156 MONITORINFO mi; 1126 MONITORINFO mi;
1157 mi.cbSize = sizeof mi; 1127 mi.cbSize = sizeof mi;
1158 base::win::GetMonitorInfoWrapper(monitor, &mi); 1128 base::win::GetMonitorInfoWrapper(monitor, &mi);
1159 CRect work_rect = mi.rcWork; 1129 CRect work_rect = mi.rcWork;
1160 work_rect.OffsetRect(-window_rect.left, -window_rect.top); 1130 work_rect.OffsetRect(-window_rect.left, -window_rect.top);
1161 new_region = CreateRectRgnIndirect(&work_rect); 1131 new_region = CreateRectRgnIndirect(&work_rect);
1162 } else { 1132 } else {
1163 gfx::Path window_mask; 1133 gfx::Path window_mask;
1164 delegate_->GetWindowMask( 1134 delegate_->GetWindowMask(
1165 gfx::Size(window_rect.Width(), window_rect.Height()), &window_mask); 1135 gfx::Size(window_rect.Width(), window_rect.Height()), &window_mask);
1166 new_region = gfx::CreateHRGNFromSkPath(window_mask); 1136 new_region = gfx::CreateHRGNFromSkPath(window_mask);
1167 } 1137 }
1168 1138
1169 if (current_rgn_result == ERROR || !EqualRgn(current_rgn, new_region)) { 1139 if (current_rgn_result == ERROR || !EqualRgn(current_rgn, new_region)) {
1170 // SetWindowRgn takes ownership of the HRGN created by CreateNativeRegion. 1140 // SetWindowRgn takes ownership of the HRGN created by CreateNativeRegion.
1171 SetWindowRgn(hwnd(), new_region, TRUE); 1141 SetWindowRgn(hwnd(), new_region, redraw);
1172 } else { 1142 } else {
1173 DeleteObject(new_region); 1143 DeleteObject(new_region);
1174 } 1144 }
1175 1145
1176 DeleteObject(current_rgn); 1146 DeleteObject(current_rgn);
1177 } 1147 }
1178 1148
1179 LRESULT HWNDMessageHandler::DefWindowProcWithRedrawLock(UINT message, 1149 LRESULT HWNDMessageHandler::DefWindowProcWithRedrawLock(UINT message,
1180 WPARAM w_param, 1150 WPARAM w_param,
1181 LPARAM l_param) { 1151 LPARAM l_param) {
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
1374 delegate_->HandleDisplayChange(); 1344 delegate_->HandleDisplayChange();
1375 } 1345 }
1376 1346
1377 LRESULT HWNDMessageHandler::OnDwmCompositionChanged(UINT msg, 1347 LRESULT HWNDMessageHandler::OnDwmCompositionChanged(UINT msg,
1378 WPARAM w_param, 1348 WPARAM w_param,
1379 LPARAM l_param) { 1349 LPARAM l_param) {
1380 if (!delegate_->IsWidgetWindow()) { 1350 if (!delegate_->IsWidgetWindow()) {
1381 SetMsgHandled(FALSE); 1351 SetMsgHandled(FALSE);
1382 return 0; 1352 return 0;
1383 } 1353 }
1384 // For some reason, we need to hide the window while we're changing the frame 1354
1385 // type only when we're changing it in response to WM_DWMCOMPOSITIONCHANGED.
1386 // If we don't, the client area will be filled with black. I'm suspecting
1387 // something skia-ey.
1388 // Frame type toggling caused by the user (e.g. switching theme) doesn't seem
1389 // to have this requirement.
1390 FrameTypeChanged(); 1355 FrameTypeChanged();
1391 return 0; 1356 return 0;
1392 } 1357 }
1393 1358
1394 void HWNDMessageHandler::OnEnterSizeMove() { 1359 void HWNDMessageHandler::OnEnterSizeMove() {
1395 delegate_->HandleBeginWMSizeMove(); 1360 delegate_->HandleBeginWMSizeMove();
1396 SetMsgHandled(FALSE); 1361 SetMsgHandled(FALSE);
1397 } 1362 }
1398 1363
1399 LRESULT HWNDMessageHandler::OnEraseBkgnd(HDC dc) { 1364 LRESULT HWNDMessageHandler::OnEraseBkgnd(HDC dc) {
(...skipping 10 matching lines...) Expand all
1410 gfx::Size min_window_size; 1375 gfx::Size min_window_size;
1411 gfx::Size max_window_size; 1376 gfx::Size max_window_size;
1412 delegate_->GetMinMaxSize(&min_window_size, &max_window_size); 1377 delegate_->GetMinMaxSize(&min_window_size, &max_window_size);
1413 1378
1414 // Add the native frame border size to the minimum and maximum size if the 1379 // Add the native frame border size to the minimum and maximum size if the
1415 // view reports its size as the client size. 1380 // view reports its size as the client size.
1416 if (delegate_->WidgetSizeIsClientSize()) { 1381 if (delegate_->WidgetSizeIsClientSize()) {
1417 CRect client_rect, window_rect; 1382 CRect client_rect, window_rect;
1418 GetClientRect(hwnd(), &client_rect); 1383 GetClientRect(hwnd(), &client_rect);
1419 GetWindowRect(hwnd(), &window_rect); 1384 GetWindowRect(hwnd(), &window_rect);
1420 // Due to the client area bottom inset hack (detailed elsewhere), adjust
1421 // the reported size of the client area in the case that the standard frame
1422 // has been removed.
1423 if (remove_standard_frame_)
1424 client_rect.bottom += kClientAreaBottomInsetHack;
1425 window_rect -= client_rect; 1385 window_rect -= client_rect;
1426 min_window_size.Enlarge(window_rect.Width(), window_rect.Height()); 1386 min_window_size.Enlarge(window_rect.Width(), window_rect.Height());
1427 if (!max_window_size.IsEmpty()) 1387 if (!max_window_size.IsEmpty())
1428 max_window_size.Enlarge(window_rect.Width(), window_rect.Height()); 1388 max_window_size.Enlarge(window_rect.Width(), window_rect.Height());
1429 } 1389 }
1430 minmax_info->ptMinTrackSize.x = min_window_size.width(); 1390 minmax_info->ptMinTrackSize.x = min_window_size.width();
1431 minmax_info->ptMinTrackSize.y = min_window_size.height(); 1391 minmax_info->ptMinTrackSize.y = min_window_size.height();
1432 if (max_window_size.width() || max_window_size.height()) { 1392 if (max_window_size.width() || max_window_size.height()) {
1433 if (!max_window_size.width()) 1393 if (!max_window_size.width())
1434 max_window_size.set_width(GetSystemMetrics(SM_CXMAXTRACK)); 1394 max_window_size.set_width(GetSystemMetrics(SM_CXMAXTRACK));
(...skipping 586 matching lines...) Expand 10 before | Expand all | Expand 10 after
2021 if (flags == SPI_SETWORKAREA) 1981 if (flags == SPI_SETWORKAREA)
2022 delegate_->HandleWorkAreaChanged(); 1982 delegate_->HandleWorkAreaChanged();
2023 SetMsgHandled(FALSE); 1983 SetMsgHandled(FALSE);
2024 } 1984 }
2025 } 1985 }
2026 1986
2027 void HWNDMessageHandler::OnSize(UINT param, const CSize& size) { 1987 void HWNDMessageHandler::OnSize(UINT param, const CSize& size) {
2028 RedrawWindow(hwnd(), NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN); 1988 RedrawWindow(hwnd(), NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN);
2029 // ResetWindowRegion is going to trigger WM_NCPAINT. By doing it after we've 1989 // ResetWindowRegion is going to trigger WM_NCPAINT. By doing it after we've
2030 // invoked OnSize we ensure the RootView has been laid out. 1990 // invoked OnSize we ensure the RootView has been laid out.
2031 ResetWindowRegion(false); 1991 ResetWindowRegion(false, true);
2032 } 1992 }
2033 1993
2034 void HWNDMessageHandler::OnSysCommand(UINT notification_code, 1994 void HWNDMessageHandler::OnSysCommand(UINT notification_code,
2035 const CPoint& point) { 1995 const CPoint& point) {
2036 if (!delegate_->ShouldHandleSystemCommands()) 1996 if (!delegate_->ShouldHandleSystemCommands())
2037 return; 1997 return;
2038 1998
2039 // Windows uses the 4 lower order bits of |notification_code| for type- 1999 // Windows uses the 4 lower order bits of |notification_code| for type-
2040 // specific information so we must exclude this when comparing. 2000 // specific information so we must exclude this when comparing.
2041 static const int sc_mask = 0xFFF0; 2001 static const int sc_mask = 0xFFF0;
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
2241 delegate_->HandleVisibilityChanged(false); 2201 delegate_->HandleVisibilityChanged(false);
2242 SetMsgHandled(FALSE); 2202 SetMsgHandled(FALSE);
2243 } 2203 }
2244 2204
2245 void HWNDMessageHandler::HandleTouchEvents(const TouchEvents& touch_events) { 2205 void HWNDMessageHandler::HandleTouchEvents(const TouchEvents& touch_events) {
2246 for (size_t i = 0; i < touch_events.size(); ++i) 2206 for (size_t i = 0; i < touch_events.size(); ++i)
2247 delegate_->HandleTouchEvent(touch_events[i]); 2207 delegate_->HandleTouchEvent(touch_events[i]);
2248 } 2208 }
2249 2209
2250 } // namespace views 2210 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/win/hwnd_message_handler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698