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

Side by Side Diff: views/widget/native_widget_win.cc

Issue 8477019: Adds Window::MoveChildToFront, with surrounding changes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Cleanup Created 9 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 | « views/widget/native_widget_win.h ('k') | views/widget/widget.h » ('j') | 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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "views/widget/native_widget_win.h" 5 #include "views/widget/native_widget_win.h"
6 6
7 #include <dwmapi.h> 7 #include <dwmapi.h>
8 #include <shellapi.h> 8 #include <shellapi.h>
9 9
10 #include <algorithm> 10 #include <algorithm>
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 #include "views/widget/root_view.h" 48 #include "views/widget/root_view.h"
49 #include "views/widget/widget_delegate.h" 49 #include "views/widget/widget_delegate.h"
50 #include "views/window/native_frame_view.h" 50 #include "views/window/native_frame_view.h"
51 51
52 #pragma comment(lib, "dwmapi.lib") 52 #pragma comment(lib, "dwmapi.lib")
53 53
54 using ui::ViewProp; 54 using ui::ViewProp;
55 55
56 namespace views { 56 namespace views {
57 57
58 namespace internal {
59
60 void EnsureRectIsVisibleInRect(const gfx::Rect& parent_rect,
61 gfx::Rect* child_rect,
62 int padding) {
63 DCHECK(child_rect);
64
65 // We use padding here because it allows some of the original web page to
66 // bleed through around the edges.
67 int twice_padding = padding * 2;
68
69 // FIRST, clamp width and height so we don't open child windows larger than
70 // the containing parent.
71 if (child_rect->width() > (parent_rect.width() + twice_padding))
72 child_rect->set_width(std::max(0, parent_rect.width() - twice_padding));
73 if (child_rect->height() > parent_rect.height() + twice_padding)
74 child_rect->set_height(std::max(0, parent_rect.height() - twice_padding));
75
76 // SECOND, clamp x,y position to padding,padding so we don't position child
77 // windows in hyperspace.
78 // TODO(mpcomplete): I don't see what the second check in each 'if' does that
79 // isn't handled by the LAST set of 'ifs'. Maybe we can remove it.
80 if (child_rect->x() < parent_rect.x() ||
81 child_rect->x() > parent_rect.right()) {
82 child_rect->set_x(parent_rect.x() + padding);
83 }
84 if (child_rect->y() < parent_rect.y() ||
85 child_rect->y() > parent_rect.bottom()) {
86 child_rect->set_y(parent_rect.y() + padding);
87 }
88
89 // LAST, nudge the window back up into the client area if its x,y position is
90 // within the parent bounds but its width/height place it off-screen.
91 if (child_rect->bottom() > parent_rect.bottom())
92 child_rect->set_y(parent_rect.bottom() - child_rect->height() - padding);
93 if (child_rect->right() > parent_rect.right())
94 child_rect->set_x(parent_rect.right() - child_rect->width() - padding);
95 }
96
97 } // namespace internal
98
99 namespace { 58 namespace {
100 59
101 // Get the source HWND of the specified message. Depending on the message, the 60 // Get the source HWND of the specified message. Depending on the message, the
102 // source HWND is encoded in either the WPARAM or the LPARAM value. 61 // source HWND is encoded in either the WPARAM or the LPARAM value.
103 HWND GetControlHWNDForMessage(UINT message, WPARAM w_param, LPARAM l_param) { 62 HWND GetControlHWNDForMessage(UINT message, WPARAM w_param, LPARAM l_param) {
104 // Each of the following messages can be sent by a child HWND and must be 63 // Each of the following messages can be sent by a child HWND and must be
105 // forwarded to its associated NativeControlWin for handling. 64 // forwarded to its associated NativeControlWin for handling.
106 switch (message) { 65 switch (message) {
107 case WM_NOTIFY: 66 case WM_NOTIFY:
108 return reinterpret_cast<NMHDR*>(l_param)->hwndFrom; 67 return reinterpret_cast<NMHDR*>(l_param)->hwndFrom;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 } 113 }
155 114
156 // Returns true if the WINDOWPOS data provided indicates the client area of 115 // Returns true if the WINDOWPOS data provided indicates the client area of
157 // the window may have changed size. This can be caused by the window being 116 // the window may have changed size. This can be caused by the window being
158 // resized or its frame changing. 117 // resized or its frame changing.
159 bool DidClientAreaSizeChange(const WINDOWPOS* window_pos) { 118 bool DidClientAreaSizeChange(const WINDOWPOS* window_pos) {
160 return !(window_pos->flags & SWP_NOSIZE) || 119 return !(window_pos->flags & SWP_NOSIZE) ||
161 window_pos->flags & SWP_FRAMECHANGED; 120 window_pos->flags & SWP_FRAMECHANGED;
162 } 121 }
163 122
164 // Ensures that the child window stays within the boundaries of the parent
165 // before setting its bounds. If |parent_window| is NULL, the bounds of the
166 // parent are assumed to be the bounds of the monitor that |child_window| is
167 // nearest to. If |child_window| isn't visible yet and |insert_after_window|
168 // is non-NULL and visible, the monitor |insert_after_window| is on is used
169 // as the parent bounds instead.
170 // TODO(beng): This function could easily not be so windowsy, deal with Widgets
171 // instead of HWNDs, and move to Widget instead of NativeWidget and
172 // then miraculously also work on Linux.
173 void SetChildBounds(HWND child_window,
174 HWND parent_window,
175 HWND insert_after_window,
176 const gfx::Rect& bounds,
177 int padding,
178 unsigned long flags) {
179 DCHECK(IsWindow(child_window));
180
181 // First figure out the bounds of the parent.
182 RECT parent_rect = {0};
183 if (parent_window) {
184 GetClientRect(parent_window, &parent_rect);
185 } else {
186 // If there is no parent, we consider the bounds of the monitor the window
187 // is on to be the parent bounds.
188
189 // If the child_window isn't visible yet and we've been given a valid,
190 // visible insert after window, use that window to locate the correct
191 // monitor instead.
192 HWND window = child_window;
193 if (!IsWindowVisible(window) && IsWindow(insert_after_window) &&
194 IsWindowVisible(insert_after_window))
195 window = insert_after_window;
196
197 gfx::Rect work_area =
198 gfx::Screen::GetMonitorWorkAreaNearestPoint(bounds.origin());
199 if (!work_area.IsEmpty())
200 parent_rect = work_area.ToRECT();
201 }
202
203 gfx::Rect actual_bounds = bounds;
204 internal::EnsureRectIsVisibleInRect(gfx::Rect(parent_rect), &actual_bounds,
205 padding);
206
207 SetWindowPos(child_window, insert_after_window, actual_bounds.x(),
208 actual_bounds.y(), actual_bounds.width(),
209 actual_bounds.height(), flags);
210 }
211
212 // Callback used to notify child windows that the top level window received a 123 // Callback used to notify child windows that the top level window received a
213 // DWMCompositionChanged message. 124 // DWMCompositionChanged message.
214 BOOL CALLBACK SendDwmCompositionChanged(HWND window, LPARAM param) { 125 BOOL CALLBACK SendDwmCompositionChanged(HWND window, LPARAM param) {
215 SendMessage(window, WM_DWMCOMPOSITIONCHANGED, 0, 0); 126 SendMessage(window, WM_DWMCOMPOSITIONCHANGED, 0, 0);
216 return TRUE; 127 return TRUE;
217 } 128 }
218 129
219 // Tells the window its frame (non-client area) has changed. 130 // Tells the window its frame (non-client area) has changed.
220 void SendFrameChanged(HWND window) { 131 void SendFrameChanged(HWND window) {
221 SetWindowPos(window, NULL, 0, 0, 0, 0, 132 SetWindowPos(window, NULL, 0, 0, 0, 0,
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 return true; 200 return true;
290 } 201 }
291 202
292 // Links the HWND to its NativeWidget. 203 // Links the HWND to its NativeWidget.
293 const char* const kNativeWidgetKey = "__VIEWS_NATIVE_WIDGET__"; 204 const char* const kNativeWidgetKey = "__VIEWS_NATIVE_WIDGET__";
294 205
295 // A custom MSAA object id used to determine if a screen reader is actively 206 // A custom MSAA object id used to determine if a screen reader is actively
296 // listening for MSAA events. 207 // listening for MSAA events.
297 const int kCustomObjectID = 1; 208 const int kCustomObjectID = 1;
298 209
299 // If the hung renderer warning doesn't fit on screen, the amount of padding to
300 // be left between the edge of the window and the edge of the nearest monitor,
301 // after the window is nudged back on screen. Pixels.
302 const int kMonitorEdgePadding = 10;
303
304 const int kDragFrameWindowAlpha = 200; 210 const int kDragFrameWindowAlpha = 200;
305 211
306 } // namespace 212 } // namespace
307 213
308 // static 214 // static
309 bool NativeWidgetWin::screen_reader_active_ = false; 215 bool NativeWidgetWin::screen_reader_active_ = false;
310 216
311 // A scoping class that prevents a window from being able to redraw in response 217 // A scoping class that prevents a window from being able to redraw in response
312 // to invalidations that may occur within it for the lifetime of the object. 218 // to invalidations that may occur within it for the lifetime of the object.
313 // 219 //
(...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after
799 SetWindowLong(GWL_STYLE, style & ~WS_MAXIMIZE); 705 SetWindowLong(GWL_STYLE, style & ~WS_MAXIMIZE);
800 SetWindowPos(NULL, bounds.x(), bounds.y(), bounds.width(), bounds.height(), 706 SetWindowPos(NULL, bounds.x(), bounds.y(), bounds.width(), bounds.height(),
801 SWP_NOACTIVATE | SWP_NOZORDER); 707 SWP_NOACTIVATE | SWP_NOZORDER);
802 } 708 }
803 709
804 void NativeWidgetWin::SetSize(const gfx::Size& size) { 710 void NativeWidgetWin::SetSize(const gfx::Size& size) {
805 SetWindowPos(NULL, 0, 0, size.width(), size.height(), 711 SetWindowPos(NULL, 0, 0, size.width(), size.height(),
806 SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE); 712 SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE);
807 } 713 }
808 714
809 void NativeWidgetWin::SetBoundsConstrained(const gfx::Rect& bounds,
810 Widget* other_widget) {
811 SetChildBounds(GetNativeView(), GetParent(),
812 other_widget ? other_widget->GetNativeView() : NULL,
813 bounds, kMonitorEdgePadding, 0);
814 }
815
816 void NativeWidgetWin::MoveAbove(gfx::NativeView native_view) { 715 void NativeWidgetWin::MoveAbove(gfx::NativeView native_view) {
817 SetWindowPos(native_view, 0, 0, 0, 0, 716 SetWindowPos(native_view, 0, 0, 0, 0,
818 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); 717 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
819 } 718 }
820 719
821 void NativeWidgetWin::MoveToTop() { 720 void NativeWidgetWin::MoveToTop() {
822 NOTIMPLEMENTED(); 721 NOTIMPLEMENTED();
823 } 722 }
824 723
825 void NativeWidgetWin::SetShape(gfx::NativeRegion region) { 724 void NativeWidgetWin::SetShape(gfx::NativeRegion region) {
(...skipping 1798 matching lines...) Expand 10 before | Expand all | Expand 10 after
2624 return (GetKeyState(VK_LBUTTON) & 0x80) || 2523 return (GetKeyState(VK_LBUTTON) & 0x80) ||
2625 (GetKeyState(VK_RBUTTON) & 0x80) || 2524 (GetKeyState(VK_RBUTTON) & 0x80) ||
2626 (GetKeyState(VK_MBUTTON) & 0x80) || 2525 (GetKeyState(VK_MBUTTON) & 0x80) ||
2627 (GetKeyState(VK_XBUTTON1) & 0x80) || 2526 (GetKeyState(VK_XBUTTON1) & 0x80) ||
2628 (GetKeyState(VK_XBUTTON2) & 0x80); 2527 (GetKeyState(VK_XBUTTON2) & 0x80);
2629 } 2528 }
2630 2529
2631 } // namespace internal 2530 } // namespace internal
2632 2531
2633 } // namespace views 2532 } // namespace views
OLDNEW
« no previous file with comments | « views/widget/native_widget_win.h ('k') | views/widget/widget.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698