summaryrefslogtreecommitdiffstats
path: root/chrome/views
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/views')
-rw-r--r--chrome/views/widget/widget_win.cc101
-rw-r--r--chrome/views/widget/widget_win.h35
-rw-r--r--chrome/views/window/window.h7
-rw-r--r--chrome/views/window/window_win.cc213
-rw-r--r--chrome/views/window/window_win.h55
5 files changed, 278 insertions, 133 deletions
diff --git a/chrome/views/widget/widget_win.cc b/chrome/views/widget/widget_win.cc
index ddf8db8..a362f21 100644
--- a/chrome/views/widget/widget_win.cc
+++ b/chrome/views/widget/widget_win.cc
@@ -19,25 +19,6 @@
#include "chrome/views/widget/hwnd_notification_source.h"
#include "chrome/views/widget/root_view.h"
-namespace {
-
-bool GetMonitorAndWorkAreaForRect(const RECT& rect,
- HMONITOR* monitor,
- gfx::Rect* work_area) {
- DCHECK(monitor);
- DCHECK(work_area);
- *monitor = MonitorFromRect(&rect, MONITOR_DEFAULTTONEAREST);
- if (!*monitor)
- return false;
- MONITORINFO monitor_info = { 0 };
- monitor_info.cbSize = sizeof(monitor_info);
- GetMonitorInfo(*monitor, &monitor_info);
- *work_area = monitor_info.rcWork;
- return true;
-}
-
-} // namespace
-
namespace views {
static const DWORD kWindowDefaultChildStyle =
@@ -121,7 +102,6 @@ static RegisteredClasses* registered_classes = NULL;
WidgetWin::WidgetWin()
: close_widget_factory_(this),
- ignore_pos_changes_factory_(this),
active_mouse_tracking_flags_(0),
has_capture_(false),
current_action_(FA_NONE),
@@ -134,9 +114,7 @@ WidgetWin::WidgetWin()
last_mouse_event_was_move_(false),
is_mouse_down_(false),
class_style_(CS_DBLCLKS),
- hwnd_(NULL),
- last_monitor_(NULL),
- ignore_window_pos_changes_(false) {
+ hwnd_(NULL) {
}
WidgetWin::~WidgetWin() {
@@ -170,9 +148,6 @@ void WidgetWin::Init(HWND parent, const gfx::Rect& bounds,
TRACK_HWND_CREATION(hwnd_);
SetWindowSupportsRerouteMouseWheel(hwnd_);
- GetMonitorAndWorkAreaForRect(bounds.ToRECT(), &last_monitor_,
- &last_work_area_);
-
// The window procedure should have set the data for us.
DCHECK(win_util::GetWindowUserData(hwnd_) == this);
@@ -686,16 +661,6 @@ void WidgetWin::OnRButtonDblClk(UINT flags, const CPoint& point) {
ProcessMousePressed(point, flags | MK_RBUTTON, true, false);
}
-void WidgetWin::OnSettingChange(UINT flags, const wchar_t* section) {
- if (!GetParent() && (flags == SPI_SETWORKAREA)) {
- // Fire a dummy SetWindowPos() call, so we'll trip the code in
- // OnWindowPosChanging() below that notices work area changes.
- ::SetWindowPos(GetNativeView(), 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
- SWP_NOZORDER | SWP_NOREDRAW | SWP_NOACTIVATE | SWP_NOOWNERZORDER);
- SetMsgHandled(TRUE);
- }
-}
-
void WidgetWin::OnSize(UINT param, const CSize& size) {
ChangeSize(param, size);
}
@@ -705,70 +670,6 @@ void WidgetWin::OnThemeChanged() {
gfx::NativeTheme::instance()->CloseHandles();
}
-void WidgetWin::OnWindowPosChanging(WINDOWPOS* window_pos) {
- if (ignore_window_pos_changes_) {
- // If somebody's trying to toggle our visibility, change the nonclient area,
- // change our Z-order, or activate us, we should probably let it go through.
- if (!(window_pos->flags & ((IsVisible() ? SWP_HIDEWINDOW : SWP_SHOWWINDOW) |
- SWP_FRAMECHANGED)) &&
- (window_pos->flags & (SWP_NOZORDER | SWP_NOACTIVATE))) {
- // Just sizing/moving the window; ignore.
- window_pos->flags |= SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW;
- window_pos->flags &= ~(SWP_SHOWWINDOW | SWP_HIDEWINDOW);
- }
- } else if (!GetParent()) {
- CRect window_rect;
- HMONITOR monitor;
- gfx::Rect work_area;
- if (GetWindowRect(&window_rect) &&
- GetMonitorAndWorkAreaForRect(window_rect, &monitor, &work_area)) {
- if ((monitor == last_monitor_) && (work_area != last_work_area_)) {
- // The work area for the monitor we're on changed. Normally Windows
- // notifies us about this (and thus we're reaching here due to the
- // SetWindowPos() call in OnSettingChange() above), but with some
- // software (e.g. nVidia's nView desktop manager) the work area can
- // change asynchronous to any notification, and we're just sent a
- // SetWindowPos() call with a new (frequently incorrect) position/size.
- // In either case, the best response is to throw away the existing
- // position/size information in |window_pos| and recalculate it based on
- // the old window coordinates, adjusted for the change in the work area.
- if (IsZoomed()) {
- window_pos->x = window_rect.left + work_area.x() - last_work_area_.x();
- window_pos->y = window_rect.top + work_area.y() - last_work_area_.y();
- window_pos->cx = window_rect.Width() + work_area.width() -
- last_work_area_.width();
- window_pos->cy = window_rect.Height() + work_area.height() -
- last_work_area_.height();
- } else {
- gfx::Rect window_gfx_rect(window_rect);
- gfx::Rect new_window_rect = window_gfx_rect.AdjustToFit(work_area);
- window_pos->x = new_window_rect.x();
- window_pos->y = new_window_rect.y();
- window_pos->cx = new_window_rect.width();
- window_pos->cy = new_window_rect.height();
- }
- // WARNING! Don't set SWP_FRAMECHANGED here, it breaks moving the child
- // HWNDs for some reason.
- window_pos->flags &= ~(SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW);
- window_pos->flags |= SWP_NOCOPYBITS;
-
- // Now ignore all immediately-following SetWindowPos() changes. Windows
- // likes to (incorrectly) recalculate what our position/size should be
- // and send us further updates.
- ignore_window_pos_changes_ = true;
- DCHECK(ignore_pos_changes_factory_.empty());
- MessageLoop::current()->PostTask(FROM_HERE,
- ignore_pos_changes_factory_.NewRunnableMethod(
- &WidgetWin::StopIgnoringPosChanges));
- }
- last_monitor_ = monitor;
- last_work_area_ = work_area;
- }
- }
-
- SetMsgHandled(FALSE);
-}
-
void WidgetWin::OnFinalMessage(HWND window) {
if (delete_on_destroy_)
delete this;
diff --git a/chrome/views/widget/widget_win.h b/chrome/views/widget/widget_win.h
index 264e9f9..ede4252 100644
--- a/chrome/views/widget/widget_win.h
+++ b/chrome/views/widget/widget_win.h
@@ -282,10 +282,20 @@ class WidgetWin : public Widget,
return ::GetParent(GetNativeView());
}
+ LONG GetWindowLong(int index) {
+ DCHECK(::IsWindow(GetNativeView()));
+ return ::GetWindowLong(GetNativeView(), index);
+ }
+
BOOL GetWindowRect(RECT* rect) const {
return ::GetWindowRect(GetNativeView(), rect);
}
+ LONG SetWindowLong(int index, LONG new_long) {
+ DCHECK(::IsWindow(GetNativeView()));
+ return ::SetWindowLong(GetNativeView(), index, new_long);
+ }
+
BOOL SetWindowPos(HWND hwnd_after, int x, int y, int cx, int cy, UINT flags) {
DCHECK(::IsWindow(GetNativeView()));
return ::SetWindowPos(GetNativeView(), hwnd_after, x, y, cx, cy, flags);
@@ -450,14 +460,18 @@ class WidgetWin : public Widget,
SetMsgHandled(FALSE);
return 0;
}
- virtual void OnSettingChange(UINT flags, const wchar_t* section);
+ virtual void OnSettingChange(UINT flags, const wchar_t* section) {
+ SetMsgHandled(FALSE);
+ }
virtual void OnSize(UINT param, const CSize& size);
virtual void OnSysCommand(UINT notification_code, CPoint click) { }
virtual void OnThemeChanged();
virtual void OnVScroll(int scroll_type, short position, HWND scrollbar) {
SetMsgHandled(FALSE);
}
- virtual void OnWindowPosChanging(WINDOWPOS* window_pos);
+ virtual void OnWindowPosChanging(WINDOWPOS* window_pos) {
+ SetMsgHandled(FALSE);
+ }
virtual void OnWindowPosChanged(WINDOWPOS* window_pos) {
SetMsgHandled(FALSE);
}
@@ -537,17 +551,10 @@ class WidgetWin : public Widget,
// If necessary, this registers the window class.
std::wstring GetWindowClassName();
- // Stops ignoring SetWindowPos() requests (see below).
- void StopIgnoringPosChanges() { ignore_window_pos_changes_ = false; }
-
// The following factory is used for calls to close the WidgetWin
// instance.
ScopedRunnableMethodFactory<WidgetWin> close_widget_factory_;
- // The following factory is used to ignore SetWindowPos() calls for short time
- // periods.
- ScopedRunnableMethodFactory<WidgetWin> ignore_pos_changes_factory_;
-
// The flags currently being used with TrackMouseEvent to track mouse
// messages. 0 if there is no active tracking. The value of this member is
// used when tracking is canceled.
@@ -609,16 +616,6 @@ class WidgetWin : public Widget,
// Our hwnd.
HWND hwnd_;
-
- // The last-seen monitor containing us, and its work area. These are used to
- // catch updates to the work area and react accordingly.
- HMONITOR last_monitor_;
- gfx::Rect last_work_area_;
-
- // When true, this flag makes us discard incoming SetWindowPos() requests that
- // only change our position/size. (We still allow changes to Z-order,
- // activation, etc.)
- bool ignore_window_pos_changes_;
};
} // namespace views
diff --git a/chrome/views/window/window.h b/chrome/views/window/window.h
index 48c1ad8..fe820da 100644
--- a/chrome/views/window/window.h
+++ b/chrome/views/window/window.h
@@ -42,6 +42,9 @@ class Window {
// Retrieves the window's bounds, including its frame.
virtual gfx::Rect GetBounds() const = 0;
+ // Retrieves the restored bounds for the window.
+ virtual gfx::Rect GetNormalBounds() const = 0;
+
// Sizes and/or places the window to the specified bounds, size or position.
virtual void SetBounds(const gfx::Rect& bounds) = 0;
@@ -78,6 +81,10 @@ class Window {
virtual bool IsMaximized() const = 0;
virtual bool IsMinimized() const = 0;
+ // Accessors for fullscreen state.
+ virtual void SetFullscreen(bool fullscreen) = 0;
+ virtual bool IsFullscreen() const = 0;
+
// Toggles the enable state for the Close button (and the Close menu item in
// the system menu).
virtual void EnableClose(bool enable) = 0;
diff --git a/chrome/views/window/window_win.cc b/chrome/views/window/window_win.cc
index e046180c..3c75b9d 100644
--- a/chrome/views/window/window_win.cc
+++ b/chrome/views/window/window_win.cc
@@ -25,6 +25,28 @@
#include "chrome/views/window/window_delegate.h"
#include "grit/generated_resources.h"
+namespace {
+
+bool GetMonitorAndRects(const RECT& rect,
+ HMONITOR* monitor,
+ gfx::Rect* monitor_rect,
+ gfx::Rect* work_area) {
+ DCHECK(monitor);
+ DCHECK(monitor_rect);
+ DCHECK(work_area);
+ *monitor = MonitorFromRect(&rect, MONITOR_DEFAULTTONULL);
+ if (!*monitor)
+ return false;
+ MONITORINFO monitor_info = { 0 };
+ monitor_info.cbSize = sizeof(monitor_info);
+ GetMonitorInfo(*monitor, &monitor_info);
+ *monitor_rect = monitor_info.rcMonitor;
+ *work_area = monitor_info.rcWork;
+ return true;
+}
+
+} // namespace
+
namespace views {
// A scoping class that prevents a window from being able to redraw in response
@@ -96,6 +118,19 @@ gfx::Rect WindowWin::GetBounds() const {
return bounds;
}
+gfx::Rect WindowWin::GetNormalBounds() const {
+ // If we're in fullscreen mode, we've changed the normal bounds to the monitor
+ // rect, so return the saved bounds instead.
+ if (IsFullscreen())
+ return gfx::Rect(saved_window_info_.window_rect);
+
+ WINDOWPLACEMENT wp;
+ wp.length = sizeof(wp);
+ const bool ret = !!GetWindowPlacement(GetNativeView(), &wp);
+ DCHECK(ret);
+ return gfx::Rect(wp.rcNormalPosition);
+}
+
void WindowWin::SetBounds(const gfx::Rect& bounds) {
SetBounds(bounds, NULL);
}
@@ -138,6 +173,18 @@ void WindowWin::ExecuteSystemMenuCommand(int command) {
SendMessage(GetNativeView(), WM_SYSCOMMAND, command, 0);
}
+void WindowWin::PushForceHidden() {
+ if (force_hidden_count_++ == 0)
+ Hide();
+}
+
+void WindowWin::PopForceHidden() {
+ if (--force_hidden_count_ <= 0) {
+ force_hidden_count_ = 0;
+ ShowWindow(SW_SHOW);
+ }
+}
+
// static
int Window::GetLocalizedContentsWidth(int col_resource_id) {
double chars = _wtof(l10n_util::GetString(col_resource_id).c_str());
@@ -235,6 +282,66 @@ bool WindowWin::IsMinimized() const {
return !!::IsIconic(GetNativeView());
}
+void WindowWin::SetFullscreen(bool fullscreen) {
+ if (fullscreen_ == fullscreen)
+ return; // Nothing to do.
+
+ // Toggle fullscreen mode.
+ fullscreen_ = fullscreen;
+
+ // Reduce jankiness during the following position changes by hiding the window
+ // until it's in the final position.
+ PushForceHidden();
+
+ // Size/position/style window appropriately.
+ HWND hwnd = GetNativeView();
+ if (fullscreen_) {
+ // Save current window information. We force the window into restored mode
+ // before going fullscreen because Windows doesn't seem to hide the
+ // taskbar if the window is in the maximized state.
+ saved_window_info_.maximized = IsMaximized();
+ if (saved_window_info_.maximized)
+ ExecuteSystemMenuCommand(SC_RESTORE);
+ saved_window_info_.style = GetWindowLong(GWL_STYLE);
+ saved_window_info_.ex_style = GetWindowLong(GWL_EXSTYLE);
+ GetWindowRect(&saved_window_info_.window_rect);
+
+ // Set new window style and size.
+ MONITORINFO monitor_info;
+ monitor_info.cbSize = sizeof(monitor_info);
+ GetMonitorInfo(MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST),
+ &monitor_info);
+ gfx::Rect monitor_rect(monitor_info.rcMonitor);
+ SetWindowLong(GWL_STYLE,
+ saved_window_info_.style & ~(WS_CAPTION | WS_THICKFRAME));
+ SetWindowLong(GWL_EXSTYLE,
+ saved_window_info_.ex_style & ~(WS_EX_DLGMODALFRAME |
+ WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE));
+ SetWindowPos(NULL, monitor_rect.x(), monitor_rect.y(),
+ monitor_rect.width(), monitor_rect.height(),
+ SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
+ } else {
+ // Reset original window style and size. The multiple window size/moves
+ // here are ugly, but if SetWindowPos() doesn't redraw, the taskbar won't be
+ // repainted. Better-looking methods welcome.
+ gfx::Rect new_rect(saved_window_info_.window_rect);
+ SetWindowLong(GWL_STYLE, saved_window_info_.style);
+ SetWindowLong(GWL_EXSTYLE, saved_window_info_.ex_style);
+ SetWindowPos(NULL, new_rect.x(), new_rect.y(), new_rect.width(),
+ new_rect.height(),
+ SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
+ if (saved_window_info_.maximized)
+ ExecuteSystemMenuCommand(SC_MAXIMIZE);
+ }
+
+ // Undo our anti-jankiness hacks.
+ PopForceHidden();
+}
+
+bool WindowWin::IsFullscreen() const {
+ return fullscreen_;
+}
+
void WindowWin::EnableClose(bool enable) {
// If the native frame is rendering its own close button, ask it to disable.
non_client_view_->EnableClose(enable);
@@ -348,13 +455,17 @@ WindowWin::WindowWin(WindowDelegate* window_delegate)
is_modal_(false),
restored_enabled_(false),
is_always_on_top_(false),
+ fullscreen_(false),
window_closed_(false),
disable_inactive_rendering_(false),
is_active_(false),
lock_updates_(false),
saved_window_style_(0),
saved_maximized_state_(0),
- force_hidden_(false) {
+ ignore_window_pos_changes_(false),
+ ignore_pos_changes_factory_(this),
+ force_hidden_count_(0),
+ last_monitor_(NULL) {
InitClass();
DCHECK(window_delegate_);
window_delegate_->window_.reset(this);
@@ -393,6 +504,9 @@ void WindowWin::Init(HWND parent, const gfx::Rect& bounds) {
SetInitialBounds(bounds);
InitAlwaysOnTopState();
+ GetMonitorAndRects(bounds.ToRECT(), &last_monitor_, &last_monitor_rect_,
+ &last_work_area_);
+
if (!IsAppWindow()) {
notification_registrar_.Add(
this,
@@ -497,9 +611,9 @@ LRESULT WindowWin::OnDwmCompositionChanged(UINT msg, WPARAM w_param,
// Important step: restore the window first, since our hiding hack doesn't
// work for maximized windows! We tell the frame not to allow itself to be
// made visible though, which removes the brief flicker.
- force_hidden_ = true;
+ ++force_hidden_count_;
::ShowWindow(GetNativeView(), SW_RESTORE);
- force_hidden_ = false;
+ --force_hidden_count_;
// We respond to this in response to WM_DWMCOMPOSITIONCHANGED since that is
// the only thing we care about - we don't actually respond to WM_THEMECHANGED
@@ -631,7 +745,7 @@ LRESULT WindowWin::OnNCCalcSize(BOOL mode, LPARAM l_param) {
// treated as a "fullscreen app", which would cause the taskbars to
// disappear.
HMONITOR monitor = MonitorFromWindow(GetNativeView(),
- MONITOR_DEFAULTTONEAREST);
+ MONITOR_DEFAULTTONULL);
if (win_util::EdgeHasTopmostAutoHideTaskbar(ABE_LEFT, monitor))
client_rect->left += win_util::kAutoHideTaskbarThicknessPx;
if (win_util::EdgeHasTopmostAutoHideTaskbar(ABE_TOP, monitor))
@@ -905,6 +1019,18 @@ LRESULT WindowWin::OnSetText(const wchar_t* text) {
reinterpret_cast<LPARAM>(text));
}
+void WindowWin::OnSettingChange(UINT flags, const wchar_t* section) {
+ if (!GetParent() && (flags == SPI_SETWORKAREA)) {
+ // Fire a dummy SetWindowPos() call, so we'll trip the code in
+ // OnWindowPosChanging() below that notices work area changes.
+ ::SetWindowPos(GetNativeView(), 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
+ SWP_NOZORDER | SWP_NOREDRAW | SWP_NOACTIVATE | SWP_NOOWNERZORDER);
+ SetMsgHandled(TRUE);
+ } else {
+ WidgetWin::OnSettingChange(flags, section);
+ }
+}
+
void WindowWin::OnSize(UINT size_param, const CSize& new_size) {
// Don't no-op if the new_size matches current size. If our normal bounds
// and maximized bounds are the same, then we need to layout (because we
@@ -971,11 +1097,82 @@ void WindowWin::OnSysCommand(UINT notification_code, CPoint click) {
}
void WindowWin::OnWindowPosChanging(WINDOWPOS* window_pos) {
- if (force_hidden_) {
+ if (force_hidden_count_) {
// Prevent the window from being made visible if we've been asked to do so.
// See comment in header as to why we might want this.
window_pos->flags &= ~SWP_SHOWWINDOW;
}
+
+ if (ignore_window_pos_changes_) {
+ // If somebody's trying to toggle our visibility, change the nonclient area,
+ // change our Z-order, or activate us, we should probably let it go through.
+ if (!(window_pos->flags & ((IsVisible() ? SWP_HIDEWINDOW : SWP_SHOWWINDOW) |
+ SWP_FRAMECHANGED)) &&
+ (window_pos->flags & (SWP_NOZORDER | SWP_NOACTIVATE))) {
+ // Just sizing/moving the window; ignore.
+ window_pos->flags |= SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW;
+ window_pos->flags &= ~(SWP_SHOWWINDOW | SWP_HIDEWINDOW);
+ }
+ } else if (!GetParent()) {
+ CRect window_rect;
+ HMONITOR monitor;
+ gfx::Rect monitor_rect, work_area;
+ if (GetWindowRect(&window_rect) &&
+ GetMonitorAndRects(window_rect, &monitor, &monitor_rect, &work_area)) {
+ if (monitor && (monitor == last_monitor_) &&
+ (IsFullscreen() || ((monitor_rect == last_monitor_rect_) &&
+ (work_area != last_work_area_)))) {
+ // A rect for the monitor we're on changed. Normally Windows notifies
+ // us about this (and thus we're reaching here due to the SetWindowPos()
+ // call in OnSettingChange() above), but with some software (e.g.
+ // nVidia's nView desktop manager) the work area can change asynchronous
+ // to any notification, and we're just sent a SetWindowPos() call with a
+ // new (frequently incorrect) position/size. In either case, the best
+ // response is to throw away the existing position/size information in
+ // |window_pos| and recalculate it based on the old window coordinates,
+ // adjusted for the change in the work area (or, for fullscreen windows,
+ // to just set it to the monitor rect).
+ if (IsFullscreen()) {
+ window_pos->x = monitor_rect.x();
+ window_pos->y = monitor_rect.y();
+ window_pos->cx = monitor_rect.width();
+ window_pos->cy = monitor_rect.height();
+ } else if (IsZoomed()) {
+ window_pos->x =
+ window_rect.left + work_area.x() - last_work_area_.x();
+ window_pos->y = window_rect.top + work_area.y() - last_work_area_.y();
+ window_pos->cx = window_rect.Width() + work_area.width() -
+ last_work_area_.width();
+ window_pos->cy = window_rect.Height() + work_area.height() -
+ last_work_area_.height();
+ } else {
+ gfx::Rect window_gfx_rect(window_rect);
+ gfx::Rect new_window_rect = window_gfx_rect.AdjustToFit(work_area);
+ window_pos->x = new_window_rect.x();
+ window_pos->y = new_window_rect.y();
+ window_pos->cx = new_window_rect.width();
+ window_pos->cy = new_window_rect.height();
+ }
+ // WARNING! Don't set SWP_FRAMECHANGED here, it breaks moving the child
+ // HWNDs for some reason.
+ window_pos->flags &= ~(SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW);
+ window_pos->flags |= SWP_NOCOPYBITS;
+
+ // Now ignore all immediately-following SetWindowPos() changes. Windows
+ // likes to (incorrectly) recalculate what our position/size should be
+ // and send us further updates.
+ ignore_window_pos_changes_ = true;
+ DCHECK(ignore_pos_changes_factory_.empty());
+ MessageLoop::current()->PostTask(FROM_HERE,
+ ignore_pos_changes_factory_.NewRunnableMethod(
+ &WindowWin::StopIgnoringPosChanges));
+ }
+ last_monitor_ = monitor;
+ last_monitor_rect_ = monitor_rect;
+ last_work_area_ = work_area;
+ }
+ }
+
WidgetWin::OnWindowPosChanging(window_pos);
}
@@ -1167,12 +1364,12 @@ void WindowWin::SaveWindowPosition() {
void WindowWin::LockUpdates() {
lock_updates_ = true;
- saved_window_style_ = GetWindowLong(GetNativeView(), GWL_STYLE);
- SetWindowLong(GetNativeView(), GWL_STYLE, saved_window_style_ & ~WS_VISIBLE);
+ saved_window_style_ = GetWindowLong(GWL_STYLE);
+ SetWindowLong(GWL_STYLE, saved_window_style_ & ~WS_VISIBLE);
}
void WindowWin::UnlockUpdates() {
- SetWindowLong(GetNativeView(), GWL_STYLE, saved_window_style_);
+ SetWindowLong(GWL_STYLE, saved_window_style_);
lock_updates_ = false;
}
diff --git a/chrome/views/window/window_win.h b/chrome/views/window/window_win.h
index 6c33093..cd7bd50 100644
--- a/chrome/views/window/window_win.h
+++ b/chrome/views/window/window_win.h
@@ -48,15 +48,23 @@ class WindowWin : public WidgetWin,
// Executes the specified SC_command.
void ExecuteSystemMenuCommand(int command);
+ // Hides the window if it hasn't already been force-hidden, then increments
+ // |force_hidden_count_| to prevent it from being shown again until
+ // PopForceHidden()) is called.
+ void PushForceHidden();
+
+ // Decrements |force_hidden_count_| and, if it is now zero, shows the window.
+ void PopForceHidden();
+
// Accessors and setters for various properties.
HWND owning_window() const { return owning_hwnd_; }
void set_focus_on_creation(bool focus_on_creation) {
focus_on_creation_ = focus_on_creation;
}
- void set_force_hidden(bool force_hidden) { force_hidden_ = force_hidden; }
// Window overrides:
virtual gfx::Rect GetBounds() const;
+ virtual gfx::Rect GetNormalBounds() const;
virtual void SetBounds(const gfx::Rect& bounds);
virtual void SetBounds(const gfx::Rect& bounds,
gfx::NativeWindow other_window);
@@ -70,6 +78,8 @@ class WindowWin : public WidgetWin,
virtual bool IsVisible() const;
virtual bool IsMaximized() const;
virtual bool IsMinimized() const;
+ virtual void SetFullscreen(bool fullscreen);
+ virtual bool IsFullscreen() const;
virtual void EnableClose(bool enable);
virtual void DisableInactiveRendering();
virtual void UpdateWindowTitle();
@@ -132,6 +142,7 @@ class WindowWin : public WidgetWin,
virtual LRESULT OnSetCursor(HWND window, UINT hittest_code, UINT message);
virtual LRESULT OnSetIcon(UINT size_type, HICON new_icon);
virtual LRESULT OnSetText(const wchar_t* text);
+ virtual void OnSettingChange(UINT flags, const wchar_t* section);
virtual void OnSize(UINT size_param, const CSize& new_size);
virtual void OnSysCommand(UINT notification_code, CPoint click);
virtual void OnWindowPosChanging(WINDOWPOS* window_pos);
@@ -144,6 +155,15 @@ class WindowWin : public WidgetWin,
}
private:
+ // Information saved before going into fullscreen mode, used to restore the
+ // window afterwards.
+ struct SavedWindowInfo {
+ bool maximized;
+ LONG style;
+ LONG ex_style;
+ RECT window_rect;
+ };
+
// Set the window as modal (by disabling all the other windows).
void BecomeModal();
@@ -182,6 +202,9 @@ class WindowWin : public WidgetWin,
void LockUpdates();
void UnlockUpdates();
+ // Stops ignoring SetWindowPos() requests (see below).
+ void StopIgnoringPosChanges() { ignore_window_pos_changes_ = false; }
+
// Resets the window region for the current window bounds if necessary.
// If |force| is true, the window region is reset to NULL even for native
// frame windows.
@@ -241,6 +264,12 @@ class WindowWin : public WidgetWin,
// We need to own the text of the menu, the Windows API does not copy it.
std::wstring always_on_top_menu_text_;
+ // True if we're in fullscreen mode.
+ bool fullscreen_;
+
+ // Saved window information from before entering fullscreen mode.
+ SavedWindowInfo saved_window_info_;
+
// Set to true if the window is in the process of closing .
bool window_closed_;
@@ -261,11 +290,25 @@ class WindowWin : public WidgetWin,
// that explains why we save this.
bool saved_maximized_state_;
- // True if we should prevent attempts to make the window visible when we
- // handle WM_WINDOWPOSCHANGING. Some calls like ShowWindow(SW_RESTORE) make
- // the window visible in addition to restoring it, when all we want to do is
- // restore it.
- bool force_hidden_;
+ // When true, this flag makes us discard incoming SetWindowPos() requests that
+ // only change our position/size. (We still allow changes to Z-order,
+ // activation, etc.)
+ bool ignore_window_pos_changes_;
+
+ // The following factory is used to ignore SetWindowPos() calls for short time
+ // periods.
+ ScopedRunnableMethodFactory<WindowWin> ignore_pos_changes_factory_;
+
+ // If this is greater than zero, we should prevent attempts to make the window
+ // visible when we handle WM_WINDOWPOSCHANGING. Some calls like
+ // ShowWindow(SW_RESTORE) make the window visible in addition to restoring it,
+ // when all we want to do is restore it.
+ int force_hidden_count_;
+
+ // The last-seen monitor containing us, and its rect and work area. These are
+ // used to catch updates to the rect and work area and react accordingly.
+ HMONITOR last_monitor_;
+ gfx::Rect last_monitor_rect_, last_work_area_;
// Hold onto notifications.
NotificationRegistrar notification_registrar_;