summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/ui/views/frame/browser_frame_gtk.h4
-rw-r--r--views/widget/native_widget.h3
-rw-r--r--views/widget/native_widget_delegate.h6
-rw-r--r--views/widget/native_widget_gtk.cc163
-rw-r--r--views/widget/native_widget_gtk.h6
-rw-r--r--views/widget/native_widget_views.cc4
-rw-r--r--views/widget/native_widget_views.h1
-rw-r--r--views/widget/native_widget_win.cc427
-rw-r--r--views/widget/native_widget_win.h32
-rw-r--r--views/widget/native_widget_win_unittest.cc2
-rw-r--r--views/widget/widget.cc110
-rw-r--r--views/widget/widget.h26
-rw-r--r--views/window/native_window.h3
-rw-r--r--views/window/native_window_delegate.h9
-rw-r--r--views/window/native_window_gtk.cc203
-rw-r--r--views/window/native_window_gtk.h43
-rw-r--r--views/window/native_window_win.cc469
-rw-r--r--views/window/native_window_win.h61
-rw-r--r--views/window/window.cc103
-rw-r--r--views/window/window.h25
20 files changed, 769 insertions, 931 deletions
diff --git a/chrome/browser/ui/views/frame/browser_frame_gtk.h b/chrome/browser/ui/views/frame/browser_frame_gtk.h
index e1f0514..d1c2014 100644
--- a/chrome/browser/ui/views/frame/browser_frame_gtk.h
+++ b/chrome/browser/ui/views/frame/browser_frame_gtk.h
@@ -31,9 +31,9 @@ class BrowserFrameGtk : public views::NativeWindowGtk,
// Overridden from views::NativeWindowGtk:
virtual gboolean OnWindowStateEvent(GtkWidget* widget,
- GdkEventWindowState* event);
+ GdkEventWindowState* event) OVERRIDE;
virtual gboolean OnConfigureEvent(GtkWidget* widget,
- GdkEventConfigure* event);
+ GdkEventConfigure* event) OVERRIDE;
private:
NativeBrowserFrameDelegate* delegate_;
diff --git a/views/widget/native_widget.h b/views/widget/native_widget.h
index 3534f26..c410110 100644
--- a/views/widget/native_widget.h
+++ b/views/widget/native_widget.h
@@ -162,6 +162,9 @@ class NativeWidget {
// accelerated drawing.
virtual gfx::AcceleratedWidget GetAcceleratedWidget() = 0;
+ // Makes the NativeWindow modal.
+ virtual void BecomeModal() = 0;
+
// Widget pass-thrus, private to Views. --------------------------------------
// See method documentation in Widget.
virtual gfx::Rect GetWindowScreenBounds() const = 0;
diff --git a/views/widget/native_widget_delegate.h b/views/widget/native_widget_delegate.h
index 2417b9e..319bc2e 100644
--- a/views/widget/native_widget_delegate.h
+++ b/views/widget/native_widget_delegate.h
@@ -24,6 +24,12 @@ class NativeWidgetDelegate {
public:
virtual ~NativeWidgetDelegate() {}
+ // Returns true if the window is modal.
+ virtual bool IsModal() const = 0;
+
+ // Returns true if the window is a dialog box.
+ virtual bool IsDialogBox() const = 0;
+
// Returns true if the window can be activated.
virtual bool CanActivate() const = 0;
diff --git a/views/widget/native_widget_gtk.cc b/views/widget/native_widget_gtk.cc
index 4d3c3a4..251177c 100644
--- a/views/widget/native_widget_gtk.cc
+++ b/views/widget/native_widget_gtk.cc
@@ -25,6 +25,7 @@
#include "ui/base/gtk/scoped_handle_gtk.h"
#include "ui/base/x/x11_util.h"
#include "ui/gfx/canvas_skia_paint.h"
+#include "ui/gfx/gtk_util.h"
#include "ui/gfx/path.h"
#include "views/controls/textfield/native_textfield_views.h"
#include "views/focus/view_storage.h"
@@ -36,6 +37,7 @@
#include "views/widget/gtk_views_window.h"
#include "views/widget/tooltip_manager_gtk.h"
#include "views/widget/widget_delegate.h"
+#include "views/window/hit_test.h"
#include "views/window/native_window_gtk.h"
#if defined(TOUCH_UI)
@@ -192,6 +194,61 @@ GtkWindowType WindowTypeToGtkWindowType(Widget::InitParams::Type type) {
return GTK_WINDOW_TOPLEVEL;
}
+// Converts a Windows-style hit test result code into a GDK window edge.
+GdkWindowEdge HitTestCodeToGDKWindowEdge(int hittest_code) {
+ switch (hittest_code) {
+ case HTBOTTOM:
+ return GDK_WINDOW_EDGE_SOUTH;
+ case HTBOTTOMLEFT:
+ return GDK_WINDOW_EDGE_SOUTH_WEST;
+ case HTBOTTOMRIGHT:
+ case HTGROWBOX:
+ return GDK_WINDOW_EDGE_SOUTH_EAST;
+ case HTLEFT:
+ return GDK_WINDOW_EDGE_WEST;
+ case HTRIGHT:
+ return GDK_WINDOW_EDGE_EAST;
+ case HTTOP:
+ return GDK_WINDOW_EDGE_NORTH;
+ case HTTOPLEFT:
+ return GDK_WINDOW_EDGE_NORTH_WEST;
+ case HTTOPRIGHT:
+ return GDK_WINDOW_EDGE_NORTH_EAST;
+ default:
+ NOTREACHED();
+ break;
+ }
+ // Default to something defaultish.
+ return HitTestCodeToGDKWindowEdge(HTGROWBOX);
+}
+
+// Converts a Windows-style hit test result code into a GDK cursor type.
+GdkCursorType HitTestCodeToGdkCursorType(int hittest_code) {
+ switch (hittest_code) {
+ case HTBOTTOM:
+ return GDK_BOTTOM_SIDE;
+ case HTBOTTOMLEFT:
+ return GDK_BOTTOM_LEFT_CORNER;
+ case HTBOTTOMRIGHT:
+ case HTGROWBOX:
+ return GDK_BOTTOM_RIGHT_CORNER;
+ case HTLEFT:
+ return GDK_LEFT_SIDE;
+ case HTRIGHT:
+ return GDK_RIGHT_SIDE;
+ case HTTOP:
+ return GDK_TOP_SIDE;
+ case HTTOPLEFT:
+ return GDK_TOP_LEFT_CORNER;
+ case HTTOPRIGHT:
+ return GDK_TOP_RIGHT_CORNER;
+ default:
+ break;
+ }
+ // Default to something defaultish.
+ return GDK_LEFT_PTR;
+}
+
} // namespace
// During drag and drop GTK sends a drag-leave during a drop. This means we
@@ -702,6 +759,8 @@ void NativeWidgetGtk::InitNativeWidget(const Widget::InitParams& params) {
G_CALLBACK(&OnMapThunk), this);
g_signal_connect(widget_, "hide",
G_CALLBACK(&OnHideThunk), this);
+ g_signal_connect(widget_, "configure-event",
+ G_CALLBACK(&OnConfigureEventThunk), this);
// Views/FocusManager (re)sets the focus to the root window,
// so we need to connect signal handlers to the gtk window.
@@ -914,6 +973,10 @@ void NativeWidgetGtk::SetAccessibleRole(ui::AccessibilityTypes::Role role) {
void NativeWidgetGtk::SetAccessibleState(ui::AccessibilityTypes::State state) {
}
+void NativeWidgetGtk::BecomeModal() {
+ gtk_window_set_modal(GetNativeWindow(), true);
+}
+
gfx::Rect NativeWidgetGtk::GetWindowScreenBounds() const {
// Client == Window bounds on Gtk.
return GetClientAreaScreenBounds();
@@ -1207,6 +1270,20 @@ void NativeWidgetGtk::OnSizeAllocate(GtkWidget* widget,
return;
size_ = new_size;
delegate_->OnNativeWidgetSizeChanged(size_);
+
+ if (GetWidget()->non_client_view()) {
+ // The Window's NonClientView may provide a custom shape for the Window.
+ gfx::Path window_mask;
+ GetWidget()->non_client_view()->GetWindowMask(gfx::Size(allocation->width,
+ allocation->height),
+ &window_mask);
+ GdkRegion* mask_region = window_mask.CreateNativeRegion();
+ gdk_window_shape_combine_region(GetNativeView()->window, mask_region, 0, 0);
+ if (mask_region)
+ gdk_region_destroy(mask_region);
+
+ SaveWindowPosition();
+ }
}
gboolean NativeWidgetGtk::OnPaint(GtkWidget* widget, GdkEventExpose* event) {
@@ -1349,6 +1426,8 @@ gboolean NativeWidgetGtk::OnEnterNotify(GtkWidget* widget,
gboolean NativeWidgetGtk::OnLeaveNotify(GtkWidget* widget,
GdkEventCrossing* event) {
+ gdk_window_set_cursor(widget->window, gfx::GetCursor(GDK_LEFT_PTR));
+
GetWidget()->ResetLastMouseMoveFlag();
if (!HasMouseCapture() && !GetWidget()->is_mouse_button_pressed_) {
@@ -1360,6 +1439,20 @@ gboolean NativeWidgetGtk::OnLeaveNotify(GtkWidget* widget,
gboolean NativeWidgetGtk::OnMotionNotify(GtkWidget* widget,
GdkEventMotion* event) {
+ if (GetWidget()->non_client_view()) {
+ GdkEventMotion transformed_event = *event;
+ TransformEvent(&transformed_event);
+ gfx::Point translated_location(transformed_event.x, transformed_event.y);
+
+ // Update the cursor for the screen edge.
+ int hittest_code =
+ GetWidget()->non_client_view()->NonClientHitTest(translated_location);
+ if (hittest_code != HTCLIENT) {
+ GdkCursorType cursor_type = HitTestCodeToGdkCursorType(hittest_code);
+ gdk_window_set_cursor(widget->window, gfx::GetCursor(cursor_type));
+ }
+ }
+
MouseEvent mouse_event(TransformEvent(event));
delegate_->OnMouseEvent(mouse_event);
return true;
@@ -1367,6 +1460,55 @@ gboolean NativeWidgetGtk::OnMotionNotify(GtkWidget* widget,
gboolean NativeWidgetGtk::OnButtonPress(GtkWidget* widget,
GdkEventButton* event) {
+ if (GetWidget()->non_client_view()) {
+ GdkEventButton transformed_event = *event;
+ MouseEvent mouse_event(TransformEvent(&transformed_event));
+
+ int hittest_code = GetWidget()->non_client_view()->NonClientHitTest(
+ mouse_event.location());
+ switch (hittest_code) {
+ case HTCAPTION: {
+ // Start dragging if the mouse event is a single click and *not* a right
+ // click. If it is a right click, then pass it through to
+ // NativeWidgetGtk::OnButtonPress so that View class can show
+ // ContextMenu upon a mouse release event. We only start drag on single
+ // clicks as we get a crash in Gtk on double/triple clicks.
+ if (event->type == GDK_BUTTON_PRESS &&
+ !mouse_event.IsOnlyRightMouseButton()) {
+ gfx::Point screen_point(event->x, event->y);
+ View::ConvertPointToScreen(GetWidget()->GetRootView(), &screen_point);
+ gtk_window_begin_move_drag(GetNativeWindow(), event->button,
+ screen_point.x(), screen_point.y(),
+ event->time);
+ return TRUE;
+ }
+ break;
+ }
+ case HTBOTTOM:
+ case HTBOTTOMLEFT:
+ case HTBOTTOMRIGHT:
+ case HTGROWBOX:
+ case HTLEFT:
+ case HTRIGHT:
+ case HTTOP:
+ case HTTOPLEFT:
+ case HTTOPRIGHT: {
+ gfx::Point screen_point(event->x, event->y);
+ View::ConvertPointToScreen(GetWidget()->GetRootView(), &screen_point);
+ // TODO(beng): figure out how to get a good minimum size.
+ gtk_widget_set_size_request(GetNativeView(), 100, 100);
+ gtk_window_begin_resize_drag(GetNativeWindow(),
+ HitTestCodeToGDKWindowEdge(hittest_code),
+ event->button, screen_point.x(),
+ screen_point.y(), event->time);
+ return TRUE;
+ }
+ default:
+ // Everything else falls into standard client event handling...
+ break;
+ }
+ }
+
if (event->type == GDK_2BUTTON_PRESS || event->type == GDK_3BUTTON_PRESS) {
// The sequence for double clicks is press, release, press, 2press, release.
// This means that at the time we get the second 'press' we don't know
@@ -1508,10 +1650,20 @@ void NativeWidgetGtk::OnHide(GtkWidget* widget) {
gboolean NativeWidgetGtk::OnWindowStateEvent(GtkWidget* widget,
GdkEventWindowState* event) {
+ if (GetWidget()->non_client_view() &&
+ !(event->new_window_state & GDK_WINDOW_STATE_WITHDRAWN)) {
+ SaveWindowPosition();
+ }
window_state_ = event->new_window_state;
return FALSE;
}
+gboolean NativeWidgetGtk::OnConfigureEvent(GtkWidget* widget,
+ GdkEventConfigure* event) {
+ SaveWindowPosition();
+ return FALSE;
+}
+
void NativeWidgetGtk::HandleXGrabBroke() {
}
@@ -1807,6 +1959,17 @@ void NativeWidgetGtk::DrawTransparentBackground(GtkWidget* widget,
cairo_destroy(cr);
}
+void NativeWidgetGtk::SaveWindowPosition() {
+ // The delegate may have gone away on us.
+ if (!GetWidget()->widget_delegate())
+ return;
+
+ bool maximized = window_state_ & GDK_WINDOW_STATE_MAXIMIZED;
+ GetWidget()->widget_delegate()->SaveWindowPlacement(
+ GetWidget()->GetWindowScreenBounds(),
+ maximized);
+}
+
////////////////////////////////////////////////////////////////////////////////
// Widget, public:
diff --git a/views/widget/native_widget_gtk.h b/views/widget/native_widget_gtk.h
index f641c64..85426aa 100644
--- a/views/widget/native_widget_gtk.h
+++ b/views/widget/native_widget_gtk.h
@@ -188,6 +188,7 @@ class NativeWidgetGtk : public NativeWidget,
virtual void SetAccessibleName(const std::wstring& name) OVERRIDE;
virtual void SetAccessibleRole(ui::AccessibilityTypes::Role role) OVERRIDE;
virtual void SetAccessibleState(ui::AccessibilityTypes::State state) OVERRIDE;
+ virtual void BecomeModal() OVERRIDE;
virtual gfx::Rect GetWindowScreenBounds() const OVERRIDE;
virtual gfx::Rect GetClientAreaScreenBounds() const OVERRIDE;
virtual gfx::Rect GetRestoredBounds() const OVERRIDE;
@@ -282,6 +283,8 @@ class NativeWidgetGtk : public NativeWidget,
CHROMEGTK_CALLBACK_0(NativeWidgetGtk, void, OnHide);
CHROMEGTK_CALLBACK_1(NativeWidgetGtk, gboolean, OnWindowStateEvent,
GdkEventWindowState*);
+ CHROMEGTK_CALLBACK_1(NativeWidgetGtk, gboolean, OnConfigureEvent,
+ GdkEventConfigure*);
// Invoked when the widget is destroyed and right before the object
// destruction. Useful for overriding.
@@ -345,6 +348,9 @@ class NativeWidgetGtk : public NativeWidget,
static void DrawTransparentBackground(GtkWidget* widget,
GdkEventExpose* event);
+ // Asks the delegate if any to save the window's location and size.
+ void SaveWindowPosition();
+
// A delegate implementation that handles events received here.
// See class documentation for Widget in widget.h for a note about ownership.
internal::NativeWidgetDelegate* delegate_;
diff --git a/views/widget/native_widget_views.cc b/views/widget/native_widget_views.cc
index d2fa54f..f46f0e6 100644
--- a/views/widget/native_widget_views.cc
+++ b/views/widget/native_widget_views.cc
@@ -168,6 +168,10 @@ void NativeWidgetViews::SetAccessibleState(
ui::AccessibilityTypes::State state) {
}
+void NativeWidgetViews::BecomeModal() {
+ NOTIMPLEMENTED();
+}
+
gfx::AcceleratedWidget NativeWidgetViews::GetAcceleratedWidget() {
// TODO(sky):
return gfx::kNullAcceleratedWidget;
diff --git a/views/widget/native_widget_views.h b/views/widget/native_widget_views.h
index f8ab599..cbc910a 100644
--- a/views/widget/native_widget_views.h
+++ b/views/widget/native_widget_views.h
@@ -69,6 +69,7 @@ class NativeWidgetViews : public NativeWidget {
virtual void SetAccessibleRole(ui::AccessibilityTypes::Role role) OVERRIDE;
virtual void SetAccessibleState(ui::AccessibilityTypes::State state) OVERRIDE;
virtual gfx::AcceleratedWidget GetAcceleratedWidget() OVERRIDE;
+ virtual void BecomeModal() OVERRIDE;
virtual gfx::Rect GetWindowScreenBounds() const OVERRIDE;
virtual gfx::Rect GetClientAreaScreenBounds() const OVERRIDE;
virtual gfx::Rect GetRestoredBounds() const OVERRIDE;
diff --git a/views/widget/native_widget_win.cc b/views/widget/native_widget_win.cc
index 6d77bc6..599bdd5 100644
--- a/views/widget/native_widget_win.cc
+++ b/views/widget/native_widget_win.cc
@@ -5,9 +5,12 @@
#include "views/widget/native_widget_win.h"
#include <dwmapi.h>
+#include <shellapi.h>
#include "base/string_util.h"
#include "base/system_monitor/system_monitor.h"
+#include "base/win/scoped_gdi_object.h"
+#include "base/win/win_util.h"
#include "base/win/windows_version.h"
#include "ui/base/dragdrop/drag_drop_types.h"
#include "ui/base/dragdrop/drag_source.h"
@@ -19,6 +22,7 @@
#include "ui/base/view_prop.h"
#include "ui/base/win/hwnd_util.h"
#include "ui/gfx/canvas_skia.h"
+#include "ui/gfx/canvas_skia_paint.h"
#include "ui/gfx/icon_util.h"
#include "ui/gfx/native_theme_win.h"
#include "ui/gfx/path.h"
@@ -199,6 +203,68 @@ BOOL CALLBACK EnumChildWindowsForRedraw(HWND hwnd, LPARAM lparam) {
return TRUE;
}
+// See comments in OnNCPaint() for details of this struct.
+struct ClipState {
+ // The window being painted.
+ HWND parent;
+
+ // DC painting to.
+ HDC dc;
+
+ // Origin of the window in terms of the screen.
+ int x;
+ int y;
+};
+
+// See comments in OnNCPaint() for details of this function.
+static BOOL CALLBACK ClipDCToChild(HWND window, LPARAM param) {
+ ClipState* clip_state = reinterpret_cast<ClipState*>(param);
+ if (GetParent(window) == clip_state->parent && IsWindowVisible(window)) {
+ RECT bounds;
+ GetWindowRect(window, &bounds);
+ ExcludeClipRect(clip_state->dc,
+ bounds.left - clip_state->x,
+ bounds.top - clip_state->y,
+ bounds.right - clip_state->x,
+ bounds.bottom - clip_state->y);
+ }
+ return TRUE;
+}
+
+// The thickness of an auto-hide taskbar in pixels.
+static const int kAutoHideTaskbarThicknessPx = 2;
+
+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;
+}
+
+// Returns true if edge |edge| (one of ABE_LEFT, TOP, RIGHT, or BOTTOM) of
+// monitor |monitor| has an auto-hiding taskbar that's always-on-top.
+bool EdgeHasTopmostAutoHideTaskbar(UINT edge, HMONITOR monitor) {
+ APPBARDATA taskbar_data = { 0 };
+ taskbar_data.cbSize = sizeof APPBARDATA;
+ taskbar_data.uEdge = edge;
+ HWND taskbar = reinterpret_cast<HWND>(SHAppBarMessage(ABM_GETAUTOHIDEBAR,
+ &taskbar_data));
+ return ::IsWindow(taskbar) && (monitor != NULL) &&
+ (MonitorFromWindow(taskbar, MONITOR_DEFAULTTONULL) == monitor) &&
+ (GetWindowLong(taskbar, GWL_EXSTYLE) & WS_EX_TOPMOST);
+}
+
// Links the HWND to its NativeWidget.
const char* const kNativeWidgetKey = "__VIEWS_NATIVE_WIDGET__";
@@ -280,7 +346,12 @@ NativeWidgetWin::NativeWidgetWin(internal::NativeWidgetDelegate* delegate)
fullscreen_(false),
force_hidden_count_(0),
lock_updates_(false),
- saved_window_style_(0) {
+ saved_window_style_(0),
+ ignore_window_pos_changes_(false),
+ ignore_pos_changes_factory_(this),
+ last_monitor_(NULL),
+ is_right_mouse_pressed_on_caption_(false),
+ restored_enabled_(false) {
}
NativeWidgetWin::~NativeWidgetWin() {
@@ -300,6 +371,15 @@ bool NativeWidgetWin::IsAeroGlassEnabled() {
return SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled;
}
+// static
+gfx::Font NativeWidgetWin::GetWindowTitleFont() {
+ NONCLIENTMETRICS ncm;
+ base::win::GetNonClientMetrics(&ncm);
+ l10n_util::AdjustUIFont(&(ncm.lfCaptionFont));
+ base::win::ScopedHFONT caption_font(CreateFontIndirect(&(ncm.lfCaptionFont)));
+ return gfx::Font(caption_font);
+}
+
void NativeWidgetWin::Show(int show_state) {
ShowWindow(show_state);
// When launched from certain programs like bash and Windows Live Messenger,
@@ -366,6 +446,9 @@ void NativeWidgetWin::PopForceHidden() {
void NativeWidgetWin::InitNativeWidget(const Widget::InitParams& params) {
SetInitParams(params);
+ GetMonitorAndRects(params.bounds.ToRECT(), &last_monitor_,
+ &last_monitor_rect_, &last_work_area_);
+
// Create the window.
gfx::NativeView parent = params.parent_widget ?
params.parent_widget->GetNativeView() : params.parent;
@@ -617,6 +700,17 @@ void NativeWidgetWin::SetAccessibleState(ui::AccessibilityTypes::State state) {
}
}
+void NativeWidgetWin::BecomeModal() {
+ // We implement modality by crawling up the hierarchy of windows starting
+ // at the owner, disabling all of them so that they don't receive input
+ // messages.
+ HWND start = ::GetWindow(GetNativeView(), GW_OWNER);
+ while (start) {
+ ::EnableWindow(start, FALSE);
+ start = ::GetParent(start);
+ }
+}
+
gfx::Rect NativeWidgetWin::GetWindowScreenBounds() const {
RECT r;
GetWindowRect(&r);
@@ -1097,6 +1191,7 @@ LRESULT NativeWidgetWin::OnCreate(CREATESTRUCT* create_struct) {
}
void NativeWidgetWin::OnDestroy() {
+ RestoreEnabledIfNecessary();
delegate_->OnNativeWidgetDestroying();
if (drop_target_.get()) {
RevokeDragDrop(hwnd());
@@ -1309,6 +1404,75 @@ LRESULT NativeWidgetWin::OnMouseActivate(UINT message,
LRESULT NativeWidgetWin::OnMouseRange(UINT message,
WPARAM w_param,
LPARAM l_param) {
+ if (message == WM_RBUTTONUP && is_right_mouse_pressed_on_caption_) {
+ is_right_mouse_pressed_on_caption_ = false;
+ ReleaseCapture();
+ // |point| is in window coordinates, but WM_NCHITTEST and TrackPopupMenu()
+ // expect screen coordinates.
+ CPoint screen_point(l_param);
+ MapWindowPoints(GetNativeView(), HWND_DESKTOP, &screen_point, 1);
+ w_param = SendMessage(GetNativeView(), WM_NCHITTEST, 0,
+ MAKELPARAM(screen_point.x, screen_point.y));
+ if (w_param == HTCAPTION || w_param == HTSYSMENU) {
+ UINT flags = TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_RETURNCMD;
+ if (base::i18n::IsRTL())
+ flags |= TPM_RIGHTALIGN;
+ HMENU system_menu = GetSystemMenu(GetNativeView(), FALSE);
+ int id = TrackPopupMenu(system_menu, flags, screen_point.x,
+ screen_point.y, 0, GetNativeView(), NULL);
+ ExecuteSystemMenuCommand(id);
+ return 0;
+ }
+ } else if (message == WM_NCLBUTTONDOWN &&
+ !GetWidget()->ShouldUseNativeFrame()) {
+ switch (w_param) {
+ case HTCLOSE:
+ case HTMINBUTTON:
+ case HTMAXBUTTON: {
+ // When the mouse is pressed down in these specific non-client areas,
+ // we need to tell the RootView to send the mouse pressed event (which
+ // sets capture, allowing subsequent WM_LBUTTONUP (note, _not_
+ // WM_NCLBUTTONUP) to fire so that the appropriate WM_SYSCOMMAND can be
+ // sent by the applicable button's ButtonListener. We _have_ to do this
+ // way rather than letting Windows just send the syscommand itself (as
+ // would happen if we never did this dance) because for some insane
+ // reason DefWindowProc for WM_NCLBUTTONDOWN also renders the pressed
+ // window control button appearance, in the Windows classic style, over
+ // our view! Ick! By handling this message we prevent Windows from
+ // doing this undesirable thing, but that means we need to roll the
+ // sys-command handling ourselves.
+ // Combine |w_param| with common key state message flags.
+ w_param |= ((GetKeyState(VK_CONTROL) & 0x80) == 0x80)? MK_CONTROL : 0;
+ w_param |= ((GetKeyState(VK_SHIFT) & 0x80) == 0x80)? MK_SHIFT : 0;
+ }
+ }
+ } else if (message == WM_NCRBUTTONDOWN &&
+ (w_param == HTCAPTION || w_param == HTSYSMENU)) {
+ is_right_mouse_pressed_on_caption_ = true;
+ // We SetMouseCapture() to ensure we only show the menu when the button
+ // down and up are both on the caption. Note: this causes the button up to
+ // be WM_RBUTTONUP instead of WM_NCRBUTTONUP.
+ SetMouseCapture();
+ }
+
+ /*
+ TODO(beng): This fixes some situations where the windows-classic appearance
+ non-client area is rendered over our custom frame, however it
+ causes mouse-releases to the non-client area to be eaten, so it
+ can't be enabled.
+ if (message == WM_NCLBUTTONDOWN) {
+ // NativeWidgetWin::OnNCLButtonDown set the message as un-handled. This
+ // normally means NativeWidgetWin::ProcessWindowMessage will pass it to
+ // DefWindowProc. Sadly, DefWindowProc for WM_NCLBUTTONDOWN does weird
+ // non-client painting, so we need to call it directly here inside a
+ // scoped update lock.
+ ScopedRedrawLock lock(this);
+ NativeWidgetWin::OnMouseRange(message, w_param, l_param);
+ DefWindowProc(GetNativeView(), WM_NCLBUTTONDOWN, w_param, l_param);
+ SetMsgHandled(TRUE);
+ }
+ */
+
MSG msg = { hwnd(), message, w_param, l_param, 0,
{ GET_X_LPARAM(l_param), GET_Y_LPARAM(l_param) } };
MouseEvent event(msg);
@@ -1385,9 +1549,86 @@ LRESULT NativeWidgetWin::OnNCActivate(BOOL active) {
return CallDefaultNCActivateHandler(inactive_rendering_disabled || active);
}
-LRESULT NativeWidgetWin::OnNCCalcSize(BOOL w_param, LPARAM l_param) {
- SetMsgHandled(FALSE);
- return 0;
+LRESULT NativeWidgetWin::OnNCCalcSize(BOOL mode, LPARAM l_param) {
+ // We only override the default handling if we need to specify a custom
+ // non-client edge width. Note that in most cases "no insets" means no
+ // custom width, but in fullscreen mode we want a custom width of 0.
+ gfx::Insets insets = GetClientAreaInsets();
+ if (insets.empty() && !IsFullscreen()) {
+ SetMsgHandled(FALSE);
+ return 0;
+ }
+
+ RECT* client_rect = mode ?
+ &reinterpret_cast<NCCALCSIZE_PARAMS*>(l_param)->rgrc[0] :
+ reinterpret_cast<RECT*>(l_param);
+ client_rect->left += insets.left();
+ client_rect->top += insets.top();
+ client_rect->bottom -= insets.bottom();
+ client_rect->right -= insets.right();
+ if (IsMaximized()) {
+ // Find all auto-hide taskbars along the screen edges and adjust in by the
+ // thickness of the auto-hide taskbar on each such edge, so the window isn't
+ // treated as a "fullscreen app", which would cause the taskbars to
+ // disappear.
+ HMONITOR monitor = MonitorFromWindow(GetNativeView(),
+ MONITOR_DEFAULTTONULL);
+ if (!monitor) {
+ // We might end up here if the window was previously minimized and the
+ // user clicks on the taskbar button to restore it in the previously
+ // maximized position. In that case WM_NCCALCSIZE is sent before the
+ // window coordinates are restored to their previous values, so our
+ // (left,top) would probably be (-32000,-32000) like all minimized
+ // windows. So the above MonitorFromWindow call fails, but if we check
+ // the window rect given with WM_NCCALCSIZE (which is our previous
+ // restored window position) we will get the correct monitor handle.
+ monitor = MonitorFromRect(client_rect, MONITOR_DEFAULTTONULL);
+ if (!monitor) {
+ // This is probably an extreme case that we won't hit, but if we don't
+ // intersect any monitor, let us not adjust the client rect since our
+ // window will not be visible anyway.
+ return 0;
+ }
+ }
+ if (EdgeHasTopmostAutoHideTaskbar(ABE_LEFT, monitor))
+ client_rect->left += kAutoHideTaskbarThicknessPx;
+ if (EdgeHasTopmostAutoHideTaskbar(ABE_TOP, monitor)) {
+ if (GetWidget()->ShouldUseNativeFrame()) {
+ // Tricky bit. Due to a bug in DwmDefWindowProc()'s handling of
+ // WM_NCHITTEST, having any nonclient area atop the window causes the
+ // caption buttons to draw onscreen but not respond to mouse
+ // hover/clicks.
+ // So for a taskbar at the screen top, we can't push the
+ // client_rect->top down; instead, we move the bottom up by one pixel,
+ // which is the smallest change we can make and still get a client area
+ // less than the screen size. This is visibly ugly, but there seems to
+ // be no better solution.
+ --client_rect->bottom;
+ } else {
+ client_rect->top += kAutoHideTaskbarThicknessPx;
+ }
+ }
+ if (EdgeHasTopmostAutoHideTaskbar(ABE_RIGHT, monitor))
+ client_rect->right -= kAutoHideTaskbarThicknessPx;
+ if (EdgeHasTopmostAutoHideTaskbar(ABE_BOTTOM, monitor))
+ client_rect->bottom -= kAutoHideTaskbarThicknessPx;
+
+ // We cannot return WVR_REDRAW when there is nonclient area, or Windows
+ // exhibits bugs where client pixels and child HWNDs are mispositioned by
+ // the width/height of the upper-left nonclient area.
+ return 0;
+ }
+
+ // If the window bounds change, we're going to relayout and repaint anyway.
+ // Returning WVR_REDRAW avoids an extra paint before that of the old client
+ // pixels in the (now wrong) location, and thus makes actions like resizing a
+ // window from the left edge look slightly less broken.
+ // We special case when left or top insets are 0, since these conditions
+ // actually require another repaint to correct the layout after glass gets
+ // turned on and off.
+ if (insets.left() == 0 || insets.top() == 0)
+ return 0;
+ return mode ? WVR_REDRAW : 0;
}
LRESULT NativeWidgetWin::OnNCHitTest(const CPoint& point) {
@@ -1421,7 +1662,85 @@ LRESULT NativeWidgetWin::OnNCHitTest(const CPoint& point) {
}
void NativeWidgetWin::OnNCPaint(HRGN rgn) {
- SetMsgHandled(FALSE);
+ // We only do non-client painting if we're not using the native frame.
+ // It's required to avoid some native painting artifacts from appearing when
+ // the window is resized.
+ if (!GetWidget()->non_client_view() || GetWidget()->ShouldUseNativeFrame()) {
+ SetMsgHandled(FALSE);
+ return;
+ }
+
+ // We have an NC region and need to paint it. We expand the NC region to
+ // include the dirty region of the root view. This is done to minimize
+ // paints.
+ CRect window_rect;
+ GetWindowRect(&window_rect);
+
+ if (window_rect.Width() != GetWidget()->GetRootView()->width() ||
+ window_rect.Height() != GetWidget()->GetRootView()->height()) {
+ // If the size of the window differs from the size of the root view it
+ // means we're being asked to paint before we've gotten a WM_SIZE. This can
+ // happen when the user is interactively resizing the window. To avoid
+ // mass flickering we don't do anything here. Once we get the WM_SIZE we'll
+ // reset the region of the window which triggers another WM_NCPAINT and
+ // all is well.
+ return;
+ }
+
+ CRect dirty_region;
+ // A value of 1 indicates paint all.
+ if (!rgn || rgn == reinterpret_cast<HRGN>(1)) {
+ dirty_region = CRect(0, 0, window_rect.Width(), window_rect.Height());
+ } else {
+ RECT rgn_bounding_box;
+ GetRgnBox(rgn, &rgn_bounding_box);
+ if (!IntersectRect(&dirty_region, &rgn_bounding_box, &window_rect))
+ return; // Dirty region doesn't intersect window bounds, bale.
+
+ // rgn_bounding_box is in screen coordinates. Map it to window coordinates.
+ OffsetRect(&dirty_region, -window_rect.left, -window_rect.top);
+ }
+
+ // In theory GetDCEx should do what we want, but I couldn't get it to work.
+ // In particular the docs mentiond DCX_CLIPCHILDREN, but as far as I can tell
+ // it doesn't work at all. So, instead we get the DC for the window then
+ // manually clip out the children.
+ HDC dc = GetWindowDC(GetNativeView());
+ ClipState clip_state;
+ clip_state.x = window_rect.left;
+ clip_state.y = window_rect.top;
+ clip_state.parent = GetNativeView();
+ clip_state.dc = dc;
+ EnumChildWindows(GetNativeView(), &ClipDCToChild,
+ reinterpret_cast<LPARAM>(&clip_state));
+
+ gfx::Rect old_paint_region = invalid_rect();
+
+ if (!old_paint_region.IsEmpty()) {
+ // The root view has a region that needs to be painted. Include it in the
+ // region we're going to paint.
+
+ CRect old_paint_region_crect = old_paint_region.ToRECT();
+ CRect tmp = dirty_region;
+ UnionRect(&dirty_region, &tmp, &old_paint_region_crect);
+ }
+
+ GetWidget()->GetRootView()->SchedulePaintInRect(gfx::Rect(dirty_region));
+
+ // gfx::CanvasSkiaPaint's destructor does the actual painting. As such, wrap
+ // the following in a block to force paint to occur so that we can release
+ // the dc.
+ {
+ gfx::CanvasSkiaPaint canvas(dc, true, dirty_region.left,
+ dirty_region.top, dirty_region.Width(),
+ dirty_region.Height());
+ delegate_->OnNativeWidgetPaint(&canvas);
+ }
+
+ ReleaseDC(GetNativeView(), dc);
+ // When using a custom frame, we want to avoid calling DefWindowProc() since
+ // that may render artifacts.
+ SetMsgHandled(!GetWidget()->ShouldUseNativeFrame());
}
LRESULT NativeWidgetWin::OnNCUAHDrawCaption(UINT msg,
@@ -1600,6 +1919,67 @@ void NativeWidgetWin::OnVScroll(int scroll_type,
}
void NativeWidgetWin::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 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 new work rect.
+ gfx::Rect new_window_rect;
+ if (IsFullscreen()) {
+ new_window_rect = monitor_rect;
+ } else if (IsZoomed()) {
+ new_window_rect = work_area;
+ int border_thickness = GetSystemMetrics(SM_CXSIZEFRAME);
+ new_window_rect.Inset(-border_thickness, -border_thickness);
+ } else {
+ new_window_rect = gfx::Rect(window_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(
+ &NativeWidgetWin::StopIgnoringPosChanges));
+ }
+ last_monitor_ = monitor;
+ last_monitor_rect_ = monitor_rect;
+ last_work_area_ = work_area;
+ }
+ }
+
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.
@@ -1631,7 +2011,7 @@ int NativeWidgetWin::GetShowState() const {
gfx::Insets NativeWidgetWin::GetClientAreaInsets() const {
// Returning an empty Insets object causes the default handling in
// NativeWidgetWin::OnNCCalcSize() to be invoked.
- if (GetWidget()->ShouldUseNativeFrame())
+ if (!GetWidget()->non_client_view() || GetWidget()->ShouldUseNativeFrame())
return gfx::Insets();
if (IsMaximized()) {
@@ -1780,7 +2160,26 @@ void NativeWidgetWin::SetInitParams(const Widget::InitParams& params) {
// Set type-dependent style attributes.
switch (params.type) {
- case Widget::InitParams::TYPE_WINDOW:
+ case Widget::InitParams::TYPE_WINDOW: {
+ style |= WS_SYSMENU | WS_CAPTION;
+ bool can_resize = GetWidget()->widget_delegate()->CanResize();
+ bool can_maximize = GetWidget()->widget_delegate()->CanMaximize();
+ if (can_maximize) {
+ style |= WS_OVERLAPPEDWINDOW;
+ } else if (can_resize) {
+ style |= WS_OVERLAPPED | WS_THICKFRAME;
+ }
+ if (delegate_->IsDialogBox()) {
+ style |= DS_MODALFRAME;
+ // NOTE: Turning this off means we lose the close button, which is bad.
+ // Turning it on though means the user can maximize or size the window
+ // from the system menu, which is worse. We may need to provide our own
+ // menu to get the close button to appear properly.
+ // style &= ~WS_SYSMENU;
+ }
+ ex_style |= delegate_->IsDialogBox() ? WS_EX_DLGMODALFRAME : 0;
+ break;
+ }
case Widget::InitParams::TYPE_CONTROL:
break;
case Widget::InitParams::TYPE_WINDOW_FRAMELESS:
@@ -1924,6 +2323,20 @@ gfx::AcceleratedWidget NativeWidgetWin::GetAcceleratedWidget() {
#endif
}
+void NativeWidgetWin::RestoreEnabledIfNecessary() {
+ if (delegate_->IsModal() && !restored_enabled_) {
+ restored_enabled_ = true;
+ // If we were run modally, we need to undo the disabled-ness we inflicted on
+ // the owner's parent hierarchy.
+ HWND start = ::GetWindow(GetNativeView(), GW_OWNER);
+ while (start) {
+ ::EnableWindow(start, TRUE);
+ start = ::GetParent(start);
+ }
+ }
+}
+
+
void NativeWidgetWin::DispatchKeyEventPostIME(const KeyEvent& key) {
SetMsgHandled(delegate_->OnKeyEvent(key));
}
diff --git a/views/widget/native_widget_win.h b/views/widget/native_widget_win.h
index 3d98b24..94bf6e2 100644
--- a/views/widget/native_widget_win.h
+++ b/views/widget/native_widget_win.h
@@ -30,6 +30,7 @@ class ViewProp;
namespace gfx {
class CanvasSkia;
+class Font;
class Rect;
}
@@ -88,6 +89,9 @@ class NativeWidgetWin : public ui::WindowImpl,
// enabled.
static bool IsAeroGlassEnabled();
+ // Returns the system set window title font.
+ static gfx::Font GetWindowTitleFont();
+
// Show the window with the specified show command.
void Show(int show_state);
@@ -212,6 +216,7 @@ class NativeWidgetWin : public ui::WindowImpl,
virtual void SetAccessibleName(const std::wstring& name) OVERRIDE;
virtual void SetAccessibleRole(ui::AccessibilityTypes::Role role) OVERRIDE;
virtual void SetAccessibleState(ui::AccessibilityTypes::State state) OVERRIDE;
+ virtual void BecomeModal() OVERRIDE;
virtual gfx::Rect GetWindowScreenBounds() const OVERRIDE;
virtual gfx::Rect GetClientAreaScreenBounds() const OVERRIDE;
virtual gfx::Rect GetRestoredBounds() const OVERRIDE;
@@ -513,6 +518,11 @@ class NativeWidgetWin : public ui::WindowImpl,
// flicker.
LRESULT CallDefaultNCActivateHandler(BOOL active);
+ // Stops ignoring SetWindowPos() requests (see below).
+ void StopIgnoringPosChanges() { ignore_window_pos_changes_ = false; }
+
+ void RestoreEnabledIfNecessary();
+
// Overridden from NativeWidget.
virtual gfx::AcceleratedWidget GetAcceleratedWidget() OVERRIDE;
@@ -625,6 +635,28 @@ class NativeWidgetWin : public ui::WindowImpl,
// The window styles of the window before updates were locked.
DWORD saved_window_style_;
+ // 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<NativeWidgetWin> ignore_pos_changes_factory_;
+
+ // 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_;
+
+ // Set to true when the user presses the right mouse button on the caption
+ // area. We need this so we can correctly show the context menu on mouse-up.
+ bool is_right_mouse_pressed_on_caption_;
+
+ // Whether all ancestors have been enabled. This is only used if is_modal_ is
+ // true.
+ bool restored_enabled_;
+
DISALLOW_COPY_AND_ASSIGN(NativeWidgetWin);
};
diff --git a/views/widget/native_widget_win_unittest.cc b/views/widget/native_widget_win_unittest.cc
index d4345a8..f2465f4 100644
--- a/views/widget/native_widget_win_unittest.cc
+++ b/views/widget/native_widget_win_unittest.cc
@@ -44,7 +44,7 @@ class NativeWidgetWinTest : public testing::Test {
NativeWidgetWin* NativeWidgetWinTest::CreateNativeWidgetWin() {
scoped_ptr<Widget> widget(new Widget);
- Widget::InitParams params(Widget::InitParams::TYPE_WINDOW);
+ Widget::InitParams params(Widget::InitParams::TYPE_POPUP);
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.bounds = gfx::Rect(50, 50, 650, 650);
widget->Init(params);
diff --git a/views/widget/widget.cc b/views/widget/widget.cc
index 5dbfe44..94eabd5 100644
--- a/views/widget/widget.cc
+++ b/views/widget/widget.cc
@@ -7,6 +7,8 @@
#include "base/logging.h"
#include "base/message_loop.h"
#include "base/utf_string_conversions.h"
+#include "ui/base/l10n/l10n_font_util.h"
+#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/compositor/compositor.h"
#include "views/focus/view_storage.h"
#include "views/ime/input_method.h"
@@ -98,7 +100,9 @@ Widget::Widget()
is_secondary_widget_(true),
frame_type_(FRAME_TYPE_DEFAULT),
disable_inactive_rendering_(false),
- widget_closed_(false) {
+ widget_closed_(false),
+ saved_maximized_state_(false),
+ minimum_size_(100, 100) {
}
Widget::~Widget() {
@@ -125,6 +129,25 @@ Widget* Widget::GetWidgetForNativeView(gfx::NativeView native_view) {
return native_widget ? native_widget->GetWidget() : NULL;
}
+// static
+int Widget::GetLocalizedContentsWidth(int col_resource_id) {
+ return ui::GetLocalizedContentsWidthForFont(col_resource_id,
+ ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::BaseFont));
+}
+
+// static
+int Widget::GetLocalizedContentsHeight(int row_resource_id) {
+ return ui::GetLocalizedContentsHeightForFont(row_resource_id,
+ ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::BaseFont));
+}
+
+// static
+gfx::Size Widget::GetLocalizedContentsSize(int col_resource_id,
+ int row_resource_id) {
+ return gfx::Size(GetLocalizedContentsWidth(col_resource_id),
+ GetLocalizedContentsHeight(row_resource_id));
+}
+
void Widget::Init(const InitParams& params) {
widget_delegate_ =
params.delegate ? params.delegate : new DefaultWidgetDelegate;
@@ -144,6 +167,8 @@ void Widget::Init(const InitParams& params) {
// NonClientView to the RootView. This will cause everything to be parented.
non_client_view_->set_client_view(widget_delegate_->CreateClientView(this));
SetContentsView(non_client_view_);
+ SetInitialBounds(params.bounds);
+ UpdateWindowTitle();
}
}
@@ -284,7 +309,17 @@ void Widget::EnableClose(bool enable) {
}
void Widget::Show() {
- native_widget_->Show();
+ if (non_client_view_) {
+ native_widget_->ShowNativeWidget(
+ saved_maximized_state_ ? NativeWidget::SHOW_MAXIMIZED
+ : NativeWidget::SHOW_RESTORED);
+ // |saved_maximized_state_| only applies the first time the window is shown.
+ // If we don't reset the value the window will be shown maximized every time
+ // it is subsequently shown after being hidden.
+ saved_maximized_state_ = false;
+ } else {
+ native_widget_->Show();
+ }
}
void Widget::Hide() {
@@ -433,11 +468,12 @@ void Widget::ResetLastMouseMoveFlag() {
}
void Widget::UpdateWindowTitle() {
- if (non_client_view_) {
- // If the non-client view is rendering its own title, it'll need to relayout
- // now.
- non_client_view_->Layout();
- }
+ if (!non_client_view_)
+ return;
+
+ // If the non-client view is rendering its own title, it'll need to relayout
+ // now.
+ non_client_view_->Layout();
// Update the native frame's text. We do this regardless of whether or not
// the native frame is being used, since this also updates the taskbar, etc.
@@ -524,6 +560,14 @@ void Widget::NotifyAccessibilityEvent(
////////////////////////////////////////////////////////////////////////////////
// Widget, NativeWidgetDelegate implementation:
+bool Widget::IsModal() const {
+ return widget_delegate_->IsModal();
+}
+
+bool Widget::IsDialogBox() const {
+ return !!widget_delegate_->AsDialogDelegate();
+}
+
bool Widget::CanActivate() const {
return widget_delegate_->CanActivate();
}
@@ -570,6 +614,9 @@ void Widget::OnNativeWidgetCreated() {
widget_delegate_->GetAccessibleWindowRole());
native_widget_->SetAccessibleState(
widget_delegate_->GetAccessibleWindowState());
+
+ if (widget_delegate_->IsModal())
+ native_widget_->BecomeModal();
}
void Widget::OnNativeWidgetDestroying() {
@@ -780,6 +827,55 @@ void Widget::SaveWindowPosition() {
widget_delegate_->SaveWindowPlacement(bounds, maximized);
}
+void Widget::SetInitialBounds(const gfx::Rect& bounds) {
+ if (!non_client_view_)
+ return;
+
+ // First we obtain the window's saved show-style and store it. We need to do
+ // this here, rather than in Show() because by the time Show() is called,
+ // the window's size will have been reset (below) and the saved maximized
+ // state will have been lost. Sadly there's no way to tell on Windows when
+ // a window is restored from maximized state, so we can't more accurately
+ // track maximized state independently of sizing information.
+ widget_delegate_->GetSavedMaximizedState(
+ &saved_maximized_state_);
+
+ // Restore the window's placement from the controller.
+ gfx::Rect saved_bounds = bounds;
+ if (widget_delegate_->GetSavedWindowBounds(&saved_bounds)) {
+ if (!widget_delegate_->ShouldRestoreWindowSize()) {
+ saved_bounds.set_size(non_client_view_->GetPreferredSize());
+ } else {
+ // Make sure the bounds are at least the minimum size.
+ if (saved_bounds.width() < minimum_size_.width()) {
+ saved_bounds.SetRect(saved_bounds.x(), saved_bounds.y(),
+ saved_bounds.right() + minimum_size_.width() -
+ saved_bounds.width(),
+ saved_bounds.bottom());
+ }
+
+ if (saved_bounds.height() < minimum_size_.height()) {
+ saved_bounds.SetRect(saved_bounds.x(), saved_bounds.y(),
+ saved_bounds.right(),
+ saved_bounds.bottom() + minimum_size_.height() -
+ saved_bounds.height());
+ }
+ }
+
+ // Widget's SetBounds method does not further modify the bounds that are
+ // passed to it.
+ SetBounds(saved_bounds);
+ } else {
+ if (bounds.IsEmpty()) {
+ // No initial bounds supplied, so size the window to its content and
+ // center over its parent.
+ native_widget_->CenterWindow(non_client_view_->GetPreferredSize());
+ } else {
+ // Use the supplied initial bounds.
+ SetBoundsConstrained(bounds, NULL);
+ }
+ }
+}
} // namespace views
diff --git a/views/widget/widget.h b/views/widget/widget.h
index 990d060..9916d95c 100644
--- a/views/widget/widget.h
+++ b/views/widget/widget.h
@@ -93,7 +93,8 @@ class Widget : public internal::NativeWidgetDelegate,
struct InitParams {
enum Type {
- TYPE_WINDOW, // A Window, like a frame window.
+ TYPE_WINDOW, // A decorated Window, like a frame window.
+ // Widgets of TYPE_WINDOW will have a NonClientView.
TYPE_WINDOW_FRAMELESS,
// An undecorated Window.
TYPE_CONTROL, // A control, like a button.
@@ -166,6 +167,17 @@ class Widget : public internal::NativeWidgetDelegate,
// Passes through to NativeWidget::GetWidgetForNativeView().
static Widget* GetWidgetForNativeView(gfx::NativeView native_view);
+
+ // Returns the preferred size of the contents view of this window based on
+ // its localized size data. The width in cols is held in a localized string
+ // resource identified by |col_resource_id|, the height in the same fashion.
+ // TODO(beng): This should eventually live somewhere else, probably closer to
+ // ClientView.
+ static int GetLocalizedContentsWidth(int col_resource_id);
+ static int GetLocalizedContentsHeight(int row_resource_id);
+ static gfx::Size GetLocalizedContentsSize(int col_resource_id,
+ int row_resource_id);
+
void Init(const InitParams& params);
// Unconverted methods -------------------------------------------------------
@@ -447,6 +459,8 @@ class Widget : public internal::NativeWidgetDelegate,
virtual const Window* AsWindow() const;
// Overridden from NativeWidgetDelegate:
+ virtual bool IsModal() const OVERRIDE;
+ virtual bool IsDialogBox() const OVERRIDE;
virtual bool CanActivate() const OVERRIDE;
virtual bool IsInactiveRenderingDisabled() const OVERRIDE;
virtual void EnableInactiveRendering() OVERRIDE;
@@ -518,6 +532,9 @@ class Widget : public internal::NativeWidgetDelegate,
// window delegate.
void SaveWindowPosition();
+ // Sizes and positions the window just after it is created.
+ void SetInitialBounds(const gfx::Rect& bounds);
+
NativeWidget* native_widget_;
// Non-owned pointer to the Widget's delegate. May be NULL if no delegate is
@@ -568,6 +585,13 @@ class Widget : public internal::NativeWidgetDelegate,
// Set to true if the widget is in the process of closing.
bool widget_closed_;
+ // The saved maximized state for this window. See note in SetInitialBounds
+ // that explains why we save this.
+ bool saved_maximized_state_;
+
+ // The smallest size the window can be.
+ gfx::Size minimum_size_;
+
DISALLOW_COPY_AND_ASSIGN(Widget);
};
diff --git a/views/window/native_window.h b/views/window/native_window.h
index 278a54f..de5cce8 100644
--- a/views/window/native_window.h
+++ b/views/window/native_window.h
@@ -44,9 +44,6 @@ class NativeWindow {
protected:
friend class Window;
-
- // Makes the NativeWindow modal.
- virtual void BecomeModal() = 0;
};
} // namespace views
diff --git a/views/window/native_window_delegate.h b/views/window/native_window_delegate.h
index a317f7d..41621ac 100644
--- a/views/window/native_window_delegate.h
+++ b/views/window/native_window_delegate.h
@@ -23,15 +23,6 @@ class NativeWindowDelegate {
public:
virtual ~NativeWindowDelegate() {}
- // Returns true if the window is modal.
- virtual bool IsModal() const = 0;
-
- // Returns true if the window is a dialog box.
- virtual bool IsDialogBox() const = 0;
-
- // Called just after the NativeWindow has been created.
- virtual void OnNativeWindowCreated(const gfx::Rect& bounds) = 0;
-
//
virtual Window* AsWindow() = 0;
diff --git a/views/window/native_window_gtk.cc b/views/window/native_window_gtk.cc
index 99a4f8a..2ca707a 100644
--- a/views/window/native_window_gtk.cc
+++ b/views/window/native_window_gtk.cc
@@ -6,7 +6,6 @@
#include "base/i18n/rtl.h"
#include "base/utf_string_conversions.h"
-#include "ui/gfx/gtk_util.h"
#include "ui/gfx/path.h"
#include "ui/gfx/rect.h"
#include "views/events/event.h"
@@ -15,71 +14,11 @@
#include "views/window/non_client_view.h"
#include "views/window/window_delegate.h"
-namespace {
-
-// Converts a Windows-style hit test result code into a GDK window edge.
-GdkWindowEdge HitTestCodeToGDKWindowEdge(int hittest_code) {
- switch (hittest_code) {
- case HTBOTTOM:
- return GDK_WINDOW_EDGE_SOUTH;
- case HTBOTTOMLEFT:
- return GDK_WINDOW_EDGE_SOUTH_WEST;
- case HTBOTTOMRIGHT:
- case HTGROWBOX:
- return GDK_WINDOW_EDGE_SOUTH_EAST;
- case HTLEFT:
- return GDK_WINDOW_EDGE_WEST;
- case HTRIGHT:
- return GDK_WINDOW_EDGE_EAST;
- case HTTOP:
- return GDK_WINDOW_EDGE_NORTH;
- case HTTOPLEFT:
- return GDK_WINDOW_EDGE_NORTH_WEST;
- case HTTOPRIGHT:
- return GDK_WINDOW_EDGE_NORTH_EAST;
- default:
- NOTREACHED();
- break;
- }
- // Default to something defaultish.
- return HitTestCodeToGDKWindowEdge(HTGROWBOX);
-}
-
-// Converts a Windows-style hit test result code into a GDK cursor type.
-GdkCursorType HitTestCodeToGdkCursorType(int hittest_code) {
- switch (hittest_code) {
- case HTBOTTOM:
- return GDK_BOTTOM_SIDE;
- case HTBOTTOMLEFT:
- return GDK_BOTTOM_LEFT_CORNER;
- case HTBOTTOMRIGHT:
- case HTGROWBOX:
- return GDK_BOTTOM_RIGHT_CORNER;
- case HTLEFT:
- return GDK_LEFT_SIDE;
- case HTRIGHT:
- return GDK_RIGHT_SIDE;
- case HTTOP:
- return GDK_TOP_SIDE;
- case HTTOPLEFT:
- return GDK_TOP_LEFT_CORNER;
- case HTTOPRIGHT:
- return GDK_TOP_RIGHT_CORNER;
- default:
- break;
- }
- // Default to something defaultish.
- return GDK_LEFT_PTR;
-}
-
-} // namespace
-
namespace views {
NativeWindowGtk::NativeWindowGtk(internal::NativeWindowDelegate* delegate)
: NativeWidgetGtk(delegate->AsNativeWidgetDelegate()),
- delegate_(delegate),
- window_closed_(false) {
+ delegate_(delegate) {
is_window_ = true;
}
@@ -87,114 +26,6 @@ NativeWindowGtk::~NativeWindowGtk() {
}
////////////////////////////////////////////////////////////////////////////////
-// NativeWindowGtk, NativeWidgetGtk overrides:
-
-gboolean NativeWindowGtk::OnButtonPress(GtkWidget* widget,
- GdkEventButton* event) {
- GdkEventButton transformed_event = *event;
- MouseEvent mouse_event(TransformEvent(&transformed_event));
-
- int hittest_code =
- GetWindow()->non_client_view()->NonClientHitTest(mouse_event.location());
- switch (hittest_code) {
- case HTCAPTION: {
- // Start dragging if the mouse event is a single click and *not* a right
- // click. If it is a right click, then pass it through to
- // NativeWidgetGtk::OnButtonPress so that View class can show ContextMenu
- // upon a mouse release event. We only start drag on single clicks as we
- // get a crash in Gtk on double/triple clicks.
- if (event->type == GDK_BUTTON_PRESS &&
- !mouse_event.IsOnlyRightMouseButton()) {
- gfx::Point screen_point(event->x, event->y);
- View::ConvertPointToScreen(GetWindow()->GetRootView(), &screen_point);
- gtk_window_begin_move_drag(GetNativeWindow(), event->button,
- screen_point.x(), screen_point.y(),
- event->time);
- return TRUE;
- }
- break;
- }
- case HTBOTTOM:
- case HTBOTTOMLEFT:
- case HTBOTTOMRIGHT:
- case HTGROWBOX:
- case HTLEFT:
- case HTRIGHT:
- case HTTOP:
- case HTTOPLEFT:
- case HTTOPRIGHT: {
- gfx::Point screen_point(event->x, event->y);
- View::ConvertPointToScreen(GetWindow()->GetRootView(), &screen_point);
- // TODO(beng): figure out how to get a good minimum size.
- gtk_widget_set_size_request(GetNativeView(), 100, 100);
- gtk_window_begin_resize_drag(GetNativeWindow(),
- HitTestCodeToGDKWindowEdge(hittest_code),
- event->button, screen_point.x(),
- screen_point.y(), event->time);
- return TRUE;
- }
- default:
- // Everything else falls into standard client event handling...
- break;
- }
- return NativeWidgetGtk::OnButtonPress(widget, event);
-}
-
-gboolean NativeWindowGtk::OnConfigureEvent(GtkWidget* widget,
- GdkEventConfigure* event) {
- SaveWindowPosition();
- return FALSE;
-}
-
-gboolean NativeWindowGtk::OnMotionNotify(GtkWidget* widget,
- GdkEventMotion* event) {
- GdkEventMotion transformed_event = *event;
- TransformEvent(&transformed_event);
- gfx::Point translated_location(transformed_event.x, transformed_event.y);
-
- // Update the cursor for the screen edge.
- int hittest_code =
- GetWindow()->non_client_view()->NonClientHitTest(translated_location);
- if (hittest_code != HTCLIENT) {
- GdkCursorType cursor_type = HitTestCodeToGdkCursorType(hittest_code);
- gdk_window_set_cursor(widget->window, gfx::GetCursor(cursor_type));
- }
-
- return NativeWidgetGtk::OnMotionNotify(widget, event);
-}
-
-void NativeWindowGtk::OnSizeAllocate(GtkWidget* widget,
- GtkAllocation* allocation) {
- NativeWidgetGtk::OnSizeAllocate(widget, allocation);
-
- // The Window's NonClientView may provide a custom shape for the Window.
- gfx::Path window_mask;
- GetWindow()->non_client_view()->GetWindowMask(gfx::Size(allocation->width,
- allocation->height),
- &window_mask);
- GdkRegion* mask_region = window_mask.CreateNativeRegion();
- gdk_window_shape_combine_region(GetNativeView()->window, mask_region, 0, 0);
- if (mask_region)
- gdk_region_destroy(mask_region);
-
- SaveWindowPosition();
-}
-
-gboolean NativeWindowGtk::OnLeaveNotify(GtkWidget* widget,
- GdkEventCrossing* event) {
- gdk_window_set_cursor(widget->window, gfx::GetCursor(GDK_LEFT_PTR));
-
- return NativeWidgetGtk::OnLeaveNotify(widget, event);
-}
-
-void NativeWindowGtk::InitNativeWidget(const Widget::InitParams& params) {
- NativeWidgetGtk::InitNativeWidget(params);
-
- g_signal_connect(G_OBJECT(GetNativeWindow()), "configure-event",
- G_CALLBACK(CallConfigureEvent), this);
-}
-
-////////////////////////////////////////////////////////////////////////////////
// NativeWindowGtk, NativeWindow implementation:
NativeWidget* NativeWindowGtk::AsNativeWidget() {
@@ -205,10 +36,6 @@ const NativeWidget* NativeWindowGtk::AsNativeWidget() const {
return this;
}
-void NativeWindowGtk::BecomeModal() {
- gtk_window_set_modal(GetNativeWindow(), true);
-}
-
Window* NativeWindowGtk::GetWindow() {
return delegate_->AsWindow();
}
@@ -218,36 +45,8 @@ const Window* NativeWindowGtk::GetWindow() const {
}
////////////////////////////////////////////////////////////////////////////////
-// NativeWindowGtk, NativeWidgetGtk overrides:
-
-gboolean NativeWindowGtk::OnWindowStateEvent(GtkWidget* widget,
- GdkEventWindowState* event) {
- if (!(event->new_window_state & GDK_WINDOW_STATE_WITHDRAWN))
- SaveWindowPosition();
- return NativeWidgetGtk::OnWindowStateEvent(widget, event);
-}
-
-////////////////////////////////////////////////////////////////////////////////
// NativeWindowGtk, private:
-// static
-gboolean NativeWindowGtk::CallConfigureEvent(GtkWidget* widget,
- GdkEventConfigure* event,
- NativeWindowGtk* window_gtk) {
- return window_gtk->OnConfigureEvent(widget, event);
-}
-
-void NativeWindowGtk::SaveWindowPosition() {
- // The delegate may have gone away on us.
- if (!GetWindow()->window_delegate())
- return;
-
- bool maximized = window_state_ & GDK_WINDOW_STATE_MAXIMIZED;
- GetWindow()->window_delegate()->SaveWindowPlacement(
- GetWidget()->GetWindowScreenBounds(),
- maximized);
-}
-
////////////////////////////////////////////////////////////////////////////////
// NativeWindow, public:
diff --git a/views/window/native_window_gtk.h b/views/window/native_window_gtk.h
index e3e5799..9988a23 100644
--- a/views/window/native_window_gtk.h
+++ b/views/window/native_window_gtk.h
@@ -9,21 +9,12 @@
#include "base/basictypes.h"
#include "views/widget/native_widget_gtk.h"
#include "views/window/native_window.h"
-#include "views/window/window.h"
-
-namespace gfx {
-class Point;
-class Size;
-};
namespace views {
namespace internal {
class NativeWindowDelegate;
}
-class Client;
-class WindowDelegate;
-
// Window implementation for Gtk.
class NativeWindowGtk : public NativeWidgetGtk, public NativeWindow {
public:
@@ -33,52 +24,18 @@ class NativeWindowGtk : public NativeWidgetGtk, public NativeWindow {
virtual Window* GetWindow() OVERRIDE;
virtual const Window* GetWindow() const OVERRIDE;
- // Overridden from NativeWidgetGtk:
- virtual gboolean OnButtonPress(GtkWidget* widget, GdkEventButton* event);
- virtual gboolean OnConfigureEvent(GtkWidget* widget,
- GdkEventConfigure* event);
- virtual gboolean OnMotionNotify(GtkWidget* widget, GdkEventMotion* event);
- virtual void OnSizeAllocate(GtkWidget* widget, GtkAllocation* allocation);
- virtual gboolean OnLeaveNotify(GtkWidget* widget, GdkEventCrossing* event);
-
protected:
- virtual void InitNativeWidget(const Widget::InitParams& params) OVERRIDE;
-
// Overridden from NativeWindow:
virtual NativeWidget* AsNativeWidget() OVERRIDE;
virtual const NativeWidget* AsNativeWidget() const OVERRIDE;
- virtual void BecomeModal() OVERRIDE;
-
- // Overridden from NativeWidgetGtk:
- virtual gboolean OnWindowStateEvent(GtkWidget* widget,
- GdkEventWindowState* event) OVERRIDE;
// For the constructor.
friend class Window;
private:
- static gboolean CallConfigureEvent(GtkWidget* widget,
- GdkEventConfigure* event,
- NativeWindowGtk* window_gtk);
-
- // Asks the delegate if any to save the window's location and size.
- void SaveWindowPosition();
-
// A delegate implementation that handles events received here.
internal::NativeWindowDelegate* delegate_;
- // Our window delegate.
- WindowDelegate* window_delegate_;
-
- // The View that provides the non-client area of the window (title bar,
- // window controls, sizing borders etc). To use an implementation other than
- // the default, this class must be subclassed and this value set to the
- // desired implementation before calling |Init|.
- NonClientView* non_client_view_;
-
- // Set to true if the window is in the process of closing.
- bool window_closed_;
-
DISALLOW_COPY_AND_ASSIGN(NativeWindowGtk);
};
diff --git a/views/window/native_window_win.cc b/views/window/native_window_win.cc
index 611b6fe..a902d10 100644
--- a/views/window/native_window_win.cc
+++ b/views/window/native_window_win.cc
@@ -4,19 +4,12 @@
#include "views/window/native_window_win.h"
-#include <dwmapi.h>
-#include <shellapi.h>
-
#include "base/i18n/rtl.h"
-#include "base/win/scoped_gdi_object.h"
-#include "base/win/win_util.h"
-#include "base/win/windows_version.h"
#include "ui/base/accessibility/accessibility_types.h"
#include "ui/base/keycodes/keyboard_code_conversion_win.h"
#include "ui/base/l10n/l10n_util_win.h"
#include "ui/base/theme_provider.h"
#include "ui/base/win/hwnd_util.h"
-#include "ui/gfx/canvas_skia_paint.h"
#include "ui/gfx/font.h"
#include "ui/gfx/path.h"
#include "views/accessibility/native_view_accessibility_win.h"
@@ -26,48 +19,6 @@
#include "views/window/window_delegate.h"
namespace views {
-namespace {
-
-// The thickness of an auto-hide taskbar in pixels.
-static const int kAutoHideTaskbarThicknessPx = 2;
-
-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;
-}
-
-// Returns true if edge |edge| (one of ABE_LEFT, TOP, RIGHT, or BOTTOM) of
-// monitor |monitor| has an auto-hiding taskbar that's always-on-top.
-bool EdgeHasTopmostAutoHideTaskbar(UINT edge, HMONITOR monitor) {
- APPBARDATA taskbar_data = { 0 };
- taskbar_data.cbSize = sizeof APPBARDATA;
- taskbar_data.uEdge = edge;
- HWND taskbar = reinterpret_cast<HWND>(SHAppBarMessage(ABM_GETAUTOHIDEBAR,
- &taskbar_data));
- return ::IsWindow(taskbar) && (monitor != NULL) &&
- (MonitorFromWindow(taskbar, MONITOR_DEFAULTTONULL) == monitor) &&
- (GetWindowLong(taskbar, GWL_EXSTYLE) & WS_EX_TOPMOST);
-}
-
-HWND GetOwner(HWND window) {
- return ::GetWindow(window, GW_OWNER);
-}
-
-} // namespace
-
namespace internal {
void EnsureRectIsVisibleInRect(const gfx::Rect& parent_rect,
@@ -114,12 +65,7 @@ void EnsureRectIsVisibleInRect(const gfx::Rect& parent_rect,
NativeWindowWin::NativeWindowWin(internal::NativeWindowDelegate* delegate)
: NativeWidgetWin(delegate->AsNativeWidgetDelegate()),
- delegate_(delegate),
- restored_enabled_(false),
- ignore_window_pos_changes_(false),
- ignore_pos_changes_factory_(this),
- is_right_mouse_pressed_on_caption_(false),
- last_monitor_(NULL) {
+ delegate_(delegate) {
is_window_ = true;
// Initialize these values to 0 so that subclasses can override the default
// behavior before calling Init.
@@ -130,367 +76,6 @@ NativeWindowWin::NativeWindowWin(internal::NativeWindowDelegate* delegate)
NativeWindowWin::~NativeWindowWin() {
}
-// static
-gfx::Font NativeWindowWin::GetWindowTitleFont() {
- NONCLIENTMETRICS ncm;
- base::win::GetNonClientMetrics(&ncm);
- l10n_util::AdjustUIFont(&(ncm.lfCaptionFont));
- base::win::ScopedHFONT caption_font(CreateFontIndirect(&(ncm.lfCaptionFont)));
- return gfx::Font(caption_font);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// NativeWindowWin, NativeWidgetWin overrides:
-
-void NativeWindowWin::InitNativeWidget(const Widget::InitParams& params) {
- if (window_style() == 0)
- set_window_style(CalculateWindowStyle());
- if (window_ex_style() == 0)
- set_window_ex_style(CalculateWindowExStyle());
-
- GetMonitorAndRects(params.bounds.ToRECT(), &last_monitor_,
- &last_monitor_rect_, &last_work_area_);
-
- NativeWidgetWin::InitNativeWidget(params);
-}
-
-void NativeWindowWin::OnDestroy() {
- RestoreEnabledIfNecessary();
- NativeWidgetWin::OnDestroy();
-}
-
-LRESULT NativeWindowWin::OnMouseRange(UINT message,
- WPARAM w_param,
- LPARAM l_param) {
- if (message == WM_RBUTTONUP && is_right_mouse_pressed_on_caption_) {
- is_right_mouse_pressed_on_caption_ = false;
- ReleaseCapture();
- // |point| is in window coordinates, but WM_NCHITTEST and TrackPopupMenu()
- // expect screen coordinates.
- CPoint screen_point(l_param);
- MapWindowPoints(GetNativeView(), HWND_DESKTOP, &screen_point, 1);
- w_param = SendMessage(GetNativeView(), WM_NCHITTEST, 0,
- MAKELPARAM(screen_point.x, screen_point.y));
- if (w_param == HTCAPTION || w_param == HTSYSMENU) {
- UINT flags = TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_RETURNCMD;
- if (base::i18n::IsRTL())
- flags |= TPM_RIGHTALIGN;
- HMENU system_menu = GetSystemMenu(GetNativeView(), FALSE);
- int id = TrackPopupMenu(system_menu, flags, screen_point.x,
- screen_point.y, 0, GetNativeView(), NULL);
- ExecuteSystemMenuCommand(id);
- return 0;
- }
- } else if (message == WM_NCLBUTTONDOWN &&
- !GetWindow()->ShouldUseNativeFrame()) {
- switch (w_param) {
- case HTCLOSE:
- case HTMINBUTTON:
- case HTMAXBUTTON: {
- // When the mouse is pressed down in these specific non-client areas,
- // we need to tell the RootView to send the mouse pressed event (which
- // sets capture, allowing subsequent WM_LBUTTONUP (note, _not_
- // WM_NCLBUTTONUP) to fire so that the appropriate WM_SYSCOMMAND can be
- // sent by the applicable button's ButtonListener. We _have_ to do this
- // way rather than letting Windows just send the syscommand itself (as
- // would happen if we never did this dance) because for some insane
- // reason DefWindowProc for WM_NCLBUTTONDOWN also renders the pressed
- // window control button appearance, in the Windows classic style, over
- // our view! Ick! By handling this message we prevent Windows from
- // doing this undesirable thing, but that means we need to roll the
- // sys-command handling ourselves.
- // Combine |w_param| with common key state message flags.
- w_param |= ((GetKeyState(VK_CONTROL) & 0x80) == 0x80)? MK_CONTROL : 0;
- w_param |= ((GetKeyState(VK_SHIFT) & 0x80) == 0x80)? MK_SHIFT : 0;
- }
- }
- } else if (message == WM_NCRBUTTONDOWN &&
- (w_param == HTCAPTION || w_param == HTSYSMENU)) {
- is_right_mouse_pressed_on_caption_ = true;
- // We SetMouseCapture() to ensure we only show the menu when the button
- // down and up are both on the caption. Note: this causes the button up to
- // be WM_RBUTTONUP instead of WM_NCRBUTTONUP.
- SetMouseCapture();
- }
-
- /*
- TODO(beng): This fixes some situations where the windows-classic appearance
- non-client area is rendered over our custom frame, however it
- causes mouse-releases to the non-client area to be eaten, so it
- can't be enabled.
- if (message == WM_NCLBUTTONDOWN) {
- // NativeWindowWin::OnNCLButtonDown set the message as un-handled. This
- // normally means NativeWidgetWin::ProcessWindowMessage will pass it to
- // DefWindowProc. Sadly, DefWindowProc for WM_NCLBUTTONDOWN does weird
- // non-client painting, so we need to call it directly here inside a
- // scoped update lock.
- ScopedRedrawLock lock(this);
- NativeWidgetWin::OnMouseRange(message, w_param, l_param);
- DefWindowProc(GetNativeView(), WM_NCLBUTTONDOWN, w_param, l_param);
- SetMsgHandled(TRUE);
- }
- */
-
- NativeWidgetWin::OnMouseRange(message, w_param, l_param);
- return 0;
-}
-
-LRESULT NativeWindowWin::OnNCCalcSize(BOOL mode, LPARAM l_param) {
- // We only override the default handling if we need to specify a custom
- // non-client edge width. Note that in most cases "no insets" means no
- // custom width, but in fullscreen mode we want a custom width of 0.
- gfx::Insets insets = GetClientAreaInsets();
- if (insets.empty() && !IsFullscreen())
- return NativeWidgetWin::OnNCCalcSize(mode, l_param);
-
- RECT* client_rect = mode ?
- &reinterpret_cast<NCCALCSIZE_PARAMS*>(l_param)->rgrc[0] :
- reinterpret_cast<RECT*>(l_param);
- client_rect->left += insets.left();
- client_rect->top += insets.top();
- client_rect->bottom -= insets.bottom();
- client_rect->right -= insets.right();
- if (IsMaximized()) {
- // Find all auto-hide taskbars along the screen edges and adjust in by the
- // thickness of the auto-hide taskbar on each such edge, so the window isn't
- // treated as a "fullscreen app", which would cause the taskbars to
- // disappear.
- HMONITOR monitor = MonitorFromWindow(GetNativeView(),
- MONITOR_DEFAULTTONULL);
- if (!monitor) {
- // We might end up here if the window was previously minimized and the
- // user clicks on the taskbar button to restore it in the previously
- // maximized position. In that case WM_NCCALCSIZE is sent before the
- // window coordinates are restored to their previous values, so our
- // (left,top) would probably be (-32000,-32000) like all minimized
- // windows. So the above MonitorFromWindow call fails, but if we check
- // the window rect given with WM_NCCALCSIZE (which is our previous
- // restored window position) we will get the correct monitor handle.
- monitor = MonitorFromRect(client_rect, MONITOR_DEFAULTTONULL);
- if (!monitor) {
- // This is probably an extreme case that we won't hit, but if we don't
- // intersect any monitor, let us not adjust the client rect since our
- // window will not be visible anyway.
- return 0;
- }
- }
- if (EdgeHasTopmostAutoHideTaskbar(ABE_LEFT, monitor))
- client_rect->left += kAutoHideTaskbarThicknessPx;
- if (EdgeHasTopmostAutoHideTaskbar(ABE_TOP, monitor)) {
- if (GetWindow()->ShouldUseNativeFrame()) {
- // Tricky bit. Due to a bug in DwmDefWindowProc()'s handling of
- // WM_NCHITTEST, having any nonclient area atop the window causes the
- // caption buttons to draw onscreen but not respond to mouse
- // hover/clicks.
- // So for a taskbar at the screen top, we can't push the
- // client_rect->top down; instead, we move the bottom up by one pixel,
- // which is the smallest change we can make and still get a client area
- // less than the screen size. This is visibly ugly, but there seems to
- // be no better solution.
- --client_rect->bottom;
- } else {
- client_rect->top += kAutoHideTaskbarThicknessPx;
- }
- }
- if (EdgeHasTopmostAutoHideTaskbar(ABE_RIGHT, monitor))
- client_rect->right -= kAutoHideTaskbarThicknessPx;
- if (EdgeHasTopmostAutoHideTaskbar(ABE_BOTTOM, monitor))
- client_rect->bottom -= kAutoHideTaskbarThicknessPx;
-
- // We cannot return WVR_REDRAW when there is nonclient area, or Windows
- // exhibits bugs where client pixels and child HWNDs are mispositioned by
- // the width/height of the upper-left nonclient area.
- return 0;
- }
-
- // If the window bounds change, we're going to relayout and repaint anyway.
- // Returning WVR_REDRAW avoids an extra paint before that of the old client
- // pixels in the (now wrong) location, and thus makes actions like resizing a
- // window from the left edge look slightly less broken.
- // We special case when left or top insets are 0, since these conditions
- // actually require another repaint to correct the layout after glass gets
- // turned on and off.
- if (insets.left() == 0 || insets.top() == 0)
- return 0;
- return mode ? WVR_REDRAW : 0;
-}
-
-namespace {
-struct ClipState {
- // The window being painted.
- HWND parent;
-
- // DC painting to.
- HDC dc;
-
- // Origin of the window in terms of the screen.
- int x;
- int y;
-};
-
-// See comments in OnNCPaint for details of this function.
-static BOOL CALLBACK ClipDCToChild(HWND window, LPARAM param) {
- ClipState* clip_state = reinterpret_cast<ClipState*>(param);
- if (GetParent(window) == clip_state->parent && IsWindowVisible(window)) {
- RECT bounds;
- GetWindowRect(window, &bounds);
- ExcludeClipRect(clip_state->dc,
- bounds.left - clip_state->x,
- bounds.top - clip_state->y,
- bounds.right - clip_state->x,
- bounds.bottom - clip_state->y);
- }
- return TRUE;
-}
-} // namespace
-
-void NativeWindowWin::OnNCPaint(HRGN rgn) {
- // We only do non-client painting if we're not using the native frame.
- // It's required to avoid some native painting artifacts from appearing when
- // the window is resized.
- if (GetWindow()->ShouldUseNativeFrame()) {
- NativeWidgetWin::OnNCPaint(rgn);
- return;
- }
-
- // We have an NC region and need to paint it. We expand the NC region to
- // include the dirty region of the root view. This is done to minimize
- // paints.
- CRect window_rect;
- GetWindowRect(&window_rect);
-
- if (window_rect.Width() != GetWidget()->GetRootView()->width() ||
- window_rect.Height() != GetWidget()->GetRootView()->height()) {
- // If the size of the window differs from the size of the root view it
- // means we're being asked to paint before we've gotten a WM_SIZE. This can
- // happen when the user is interactively resizing the window. To avoid
- // mass flickering we don't do anything here. Once we get the WM_SIZE we'll
- // reset the region of the window which triggers another WM_NCPAINT and
- // all is well.
- return;
- }
-
- CRect dirty_region;
- // A value of 1 indicates paint all.
- if (!rgn || rgn == reinterpret_cast<HRGN>(1)) {
- dirty_region = CRect(0, 0, window_rect.Width(), window_rect.Height());
- } else {
- RECT rgn_bounding_box;
- GetRgnBox(rgn, &rgn_bounding_box);
- if (!IntersectRect(&dirty_region, &rgn_bounding_box, &window_rect))
- return; // Dirty region doesn't intersect window bounds, bale.
-
- // rgn_bounding_box is in screen coordinates. Map it to window coordinates.
- OffsetRect(&dirty_region, -window_rect.left, -window_rect.top);
- }
-
- // In theory GetDCEx should do what we want, but I couldn't get it to work.
- // In particular the docs mentiond DCX_CLIPCHILDREN, but as far as I can tell
- // it doesn't work at all. So, instead we get the DC for the window then
- // manually clip out the children.
- HDC dc = GetWindowDC(GetNativeView());
- ClipState clip_state;
- clip_state.x = window_rect.left;
- clip_state.y = window_rect.top;
- clip_state.parent = GetNativeView();
- clip_state.dc = dc;
- EnumChildWindows(GetNativeView(), &ClipDCToChild,
- reinterpret_cast<LPARAM>(&clip_state));
-
- gfx::Rect old_paint_region = invalid_rect();
-
- if (!old_paint_region.IsEmpty()) {
- // The root view has a region that needs to be painted. Include it in the
- // region we're going to paint.
-
- CRect old_paint_region_crect = old_paint_region.ToRECT();
- CRect tmp = dirty_region;
- UnionRect(&dirty_region, &tmp, &old_paint_region_crect);
- }
-
- GetWidget()->GetRootView()->SchedulePaintInRect(gfx::Rect(dirty_region));
-
- // gfx::CanvasSkiaPaint's destructor does the actual painting. As such, wrap
- // the following in a block to force paint to occur so that we can release
- // the dc.
- {
- gfx::CanvasSkiaPaint canvas(dc, true, dirty_region.left,
- dirty_region.top, dirty_region.Width(),
- dirty_region.Height());
- delegate_->AsNativeWidgetDelegate()->OnNativeWidgetPaint(&canvas);
- }
-
- ReleaseDC(GetNativeView(), dc);
- // When using a custom frame, we want to avoid calling DefWindowProc() since
- // that may render artifacts.
- SetMsgHandled(!GetWindow()->ShouldUseNativeFrame());
-}
-
-void NativeWindowWin::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 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 new work rect.
- gfx::Rect new_window_rect;
- if (IsFullscreen()) {
- new_window_rect = monitor_rect;
- } else if (IsZoomed()) {
- new_window_rect = work_area;
- int border_thickness = GetSystemMetrics(SM_CXSIZEFRAME);
- new_window_rect.Inset(-border_thickness, -border_thickness);
- } else {
- new_window_rect = gfx::Rect(window_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(
- &NativeWindowWin::StopIgnoringPosChanges));
- }
- last_monitor_ = monitor;
- last_monitor_rect_ = monitor_rect;
- last_work_area_ = work_area;
- }
- }
-
- NativeWidgetWin::OnWindowPosChanging(window_pos);
-}
-
////////////////////////////////////////////////////////////////////////////////
// NativeWindowWin, NativeWindow implementation:
@@ -510,58 +95,6 @@ const NativeWidget* NativeWindowWin::AsNativeWidget() const {
return this;
}
-void NativeWindowWin::BecomeModal() {
- // We implement modality by crawling up the hierarchy of windows starting
- // at the owner, disabling all of them so that they don't receive input
- // messages.
- HWND start = GetOwner(GetNativeView());
- while (start) {
- ::EnableWindow(start, FALSE);
- start = ::GetParent(start);
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// NativeWindowWin, private:
-
-void NativeWindowWin::RestoreEnabledIfNecessary() {
- if (delegate_->IsModal() && !restored_enabled_) {
- restored_enabled_ = true;
- // If we were run modally, we need to undo the disabled-ness we inflicted on
- // the owner's parent hierarchy.
- HWND start = GetOwner(GetNativeView());
- while (start) {
- ::EnableWindow(start, TRUE);
- start = ::GetParent(start);
- }
- }
-}
-
-DWORD NativeWindowWin::CalculateWindowStyle() {
- DWORD window_styles =
- WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_SYSMENU | WS_CAPTION;
- bool can_resize = GetWindow()->window_delegate()->CanResize();
- bool can_maximize = GetWindow()->window_delegate()->CanMaximize();
- if (can_maximize) {
- window_styles |= WS_OVERLAPPEDWINDOW;
- } else if (can_resize) {
- window_styles |= WS_OVERLAPPED | WS_THICKFRAME;
- }
- if (delegate_->IsDialogBox()) {
- window_styles |= DS_MODALFRAME;
- // NOTE: Turning this off means we lose the close button, which is bad.
- // Turning it on though means the user can maximize or size the window
- // from the system menu, which is worse. We may need to provide our own
- // menu to get the close button to appear properly.
- // window_styles &= ~WS_SYSMENU;
- }
- return window_styles;
-}
-
-DWORD NativeWindowWin::CalculateWindowExStyle() {
- return delegate_->IsDialogBox() ? WS_EX_DLGMODALFRAME : 0;
-}
-
////////////////////////////////////////////////////////////////////////////////
// NativeWindow, public:
diff --git a/views/window/native_window_win.h b/views/window/native_window_win.h
index 3243739..956a3ac 100644
--- a/views/window/native_window_win.h
+++ b/views/window/native_window_win.h
@@ -8,13 +8,6 @@
#include "views/widget/native_widget_win.h"
#include "views/window/native_window.h"
-#include "views/window/window.h"
-
-namespace gfx {
-class Font;
-class Point;
-class Size;
-};
namespace views {
namespace internal {
@@ -29,9 +22,6 @@ void EnsureRectIsVisibleInRect(const gfx::Rect& parent_rect,
} // namespace internal
-class Client;
-class WindowDelegate;
-
////////////////////////////////////////////////////////////////////////////////
//
// NativeWindowWin
@@ -47,9 +37,6 @@ class NativeWindowWin : public NativeWidgetWin,
explicit NativeWindowWin(internal::NativeWindowDelegate* delegate);
virtual ~NativeWindowWin();
- // Returns the system set window title font.
- static gfx::Font GetWindowTitleFont();
-
// Overridden from NativeWindow:
virtual Window* GetWindow() OVERRIDE;
virtual const Window* GetWindow() const OVERRIDE;
@@ -57,62 +44,14 @@ class NativeWindowWin : public NativeWidgetWin,
protected:
friend Window;
- // Overridden from NativeWidgetWin:
- virtual void InitNativeWidget(const Widget::InitParams& params) OVERRIDE;
- virtual void OnDestroy() OVERRIDE;
- virtual LRESULT OnMouseRange(UINT message,
- WPARAM w_param,
- LPARAM l_param) OVERRIDE;
- LRESULT OnNCCalcSize(BOOL mode, LPARAM l_param); // Don't override.
- virtual void OnNCPaint(HRGN rgn) OVERRIDE;
- virtual void OnWindowPosChanging(WINDOWPOS* window_pos) OVERRIDE;
-
// Overridden from NativeWindow:
virtual NativeWidget* AsNativeWidget() OVERRIDE;
virtual const NativeWidget* AsNativeWidget() const OVERRIDE;
- virtual void BecomeModal() OVERRIDE;
private:
- // If necessary, enables all ancestors.
- void RestoreEnabledIfNecessary();
-
- // Calculate the appropriate window styles for this window.
- DWORD CalculateWindowStyle();
- DWORD CalculateWindowExStyle();
-
- // Stops ignoring SetWindowPos() requests (see below).
- void StopIgnoringPosChanges() { ignore_window_pos_changes_ = false; }
-
- // Update accessibility information via our WindowDelegate.
- void UpdateAccessibleName(std::wstring& accessible_name);
- void UpdateAccessibleRole();
- void UpdateAccessibleState();
-
// A delegate implementation that handles events received here.
internal::NativeWindowDelegate* delegate_;
- // Whether all ancestors have been enabled. This is only used if is_modal_ is
- // true.
- bool restored_enabled_;
-
- // 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<NativeWindowWin> ignore_pos_changes_factory_;
-
- // Set to true when the user presses the right mouse button on the caption
- // area. We need this so we can correctly show the context menu on mouse-up.
- bool is_right_mouse_pressed_on_caption_;
-
- // 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_;
-
DISALLOW_COPY_AND_ASSIGN(NativeWindowWin);
};
diff --git a/views/window/window.cc b/views/window/window.cc
index d16ff6c..ecfaa57 100644
--- a/views/window/window.cc
+++ b/views/window/window.cc
@@ -6,8 +6,6 @@
#include "base/string_util.h"
#include "third_party/skia/include/core/SkBitmap.h"
-#include "ui/base/l10n/l10n_font_util.h"
-#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/font.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/size.h"
@@ -29,9 +27,7 @@ Window::InitParams::InitParams(WindowDelegate* window_delegate)
}
Window::Window()
- : native_window_(NULL),
- saved_maximized_state_(false),
- minimum_size_(100, 100) {
+ : native_window_(NULL) {
}
Window::~Window() {
@@ -52,25 +48,6 @@ Window* Window::CreateChromeWindow(gfx::NativeWindow parent,
return window;
}
-// static
-int Window::GetLocalizedContentsWidth(int col_resource_id) {
- return ui::GetLocalizedContentsWidthForFont(col_resource_id,
- ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::BaseFont));
-}
-
-// static
-int Window::GetLocalizedContentsHeight(int row_resource_id) {
- return ui::GetLocalizedContentsHeightForFont(row_resource_id,
- ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::BaseFont));
-}
-
-// static
-gfx::Size Window::GetLocalizedContentsSize(int col_resource_id,
- int row_resource_id) {
- return gfx::Size(GetLocalizedContentsWidth(col_resource_id),
- GetLocalizedContentsHeight(row_resource_id));
-}
-
void Window::InitWindow(const InitParams& params) {
native_window_ =
params.native_window ? params.native_window
@@ -82,22 +59,11 @@ void Window::InitWindow(const InitParams& params) {
modified_params.widget_init_params.native_widget =
native_window_->AsNativeWidget();
Init(modified_params.widget_init_params);
- OnNativeWindowCreated(modified_params.widget_init_params.bounds);
}
////////////////////////////////////////////////////////////////////////////////
// Window, Widget overrides:
-void Window::Show() {
- native_window_->AsNativeWidget()->ShowNativeWidget(
- saved_maximized_state_ ? NativeWidget::SHOW_MAXIMIZED
- : NativeWidget::SHOW_RESTORED);
- // |saved_maximized_state_| only applies the first time the window is shown.
- // If we don't reset the value the window will be shown maximized every time
- // it is subsequently shown after being hidden.
- saved_maximized_state_ = false;
-}
-
Window* Window::AsWindow() {
return this;
}
@@ -109,75 +75,8 @@ const Window* Window::AsWindow() const {
////////////////////////////////////////////////////////////////////////////////
// Window, internal::NativeWindowDelegate implementation:
-bool Window::IsModal() const {
- return widget_delegate()->IsModal();
-}
-
-bool Window::IsDialogBox() const {
- return !!widget_delegate()->AsDialogDelegate();
-}
-
-void Window::OnNativeWindowCreated(const gfx::Rect& bounds) {
- if (widget_delegate()->IsModal())
- native_window_->BecomeModal();
-
- UpdateWindowTitle();
- SetInitialBounds(bounds);
-}
-
internal::NativeWidgetDelegate* Window::AsNativeWidgetDelegate() {
return this;
}
-////////////////////////////////////////////////////////////////////////////////
-// Window, private:
-
-void Window::SetInitialBounds(const gfx::Rect& bounds) {
- // First we obtain the window's saved show-style and store it. We need to do
- // this here, rather than in Show() because by the time Show() is called,
- // the window's size will have been reset (below) and the saved maximized
- // state will have been lost. Sadly there's no way to tell on Windows when
- // a window is restored from maximized state, so we can't more accurately
- // track maximized state independently of sizing information.
- widget_delegate()->GetSavedMaximizedState(
- &saved_maximized_state_);
-
- // Restore the window's placement from the controller.
- gfx::Rect saved_bounds = bounds;
- if (widget_delegate()->GetSavedWindowBounds(&saved_bounds)) {
- if (!widget_delegate()->ShouldRestoreWindowSize()) {
- saved_bounds.set_size(non_client_view()->GetPreferredSize());
- } else {
- // Make sure the bounds are at least the minimum size.
- if (saved_bounds.width() < minimum_size_.width()) {
- saved_bounds.SetRect(saved_bounds.x(), saved_bounds.y(),
- saved_bounds.right() + minimum_size_.width() -
- saved_bounds.width(),
- saved_bounds.bottom());
- }
-
- if (saved_bounds.height() < minimum_size_.height()) {
- saved_bounds.SetRect(saved_bounds.x(), saved_bounds.y(),
- saved_bounds.right(),
- saved_bounds.bottom() + minimum_size_.height() -
- saved_bounds.height());
- }
- }
-
- // Widget's SetBounds method does not further modify the bounds that are
- // passed to it.
- SetBounds(saved_bounds);
- } else {
- if (bounds.IsEmpty()) {
- // No initial bounds supplied, so size the window to its content and
- // center over its parent.
- native_window_->AsNativeWidget()->CenterWindow(
- non_client_view()->GetPreferredSize());
- } else {
- // Use the supplied initial bounds.
- SetBoundsConstrained(bounds, NULL);
- }
- }
-}
-
} // namespace views
diff --git a/views/window/window.h b/views/window/window.h
index 4fb8321..e3a36d5 100644
--- a/views/window/window.h
+++ b/views/window/window.h
@@ -11,7 +11,6 @@
#include "views/window/native_window_delegate.h"
namespace gfx {
-class Font;
class Rect;
class Size;
} // namespace gfx
@@ -50,22 +49,11 @@ class Window : public Widget,
const gfx::Rect& bounds,
WindowDelegate* window_delegate);
- // Returns the preferred size of the contents view of this window based on
- // its localized size data. The width in cols is held in a localized string
- // resource identified by |col_resource_id|, the height in the same fashion.
- // TODO(beng): This should eventually live somewhere else, probably closer to
- // ClientView.
- static int GetLocalizedContentsWidth(int col_resource_id);
- static int GetLocalizedContentsHeight(int row_resource_id);
- static gfx::Size GetLocalizedContentsSize(int col_resource_id,
- int row_resource_id);
-
// Initializes the window. Must be called before any post-configuration
// operations are performed.
void InitWindow(const InitParams& params);
// Overridden from Widget:
- virtual void Show() OVERRIDE;
virtual Window* AsWindow() OVERRIDE;
virtual const Window* AsWindow() const OVERRIDE;
@@ -81,24 +69,11 @@ class Window : public Widget,
protected:
// Overridden from NativeWindowDelegate:
- virtual bool IsModal() const OVERRIDE;
- virtual bool IsDialogBox() const OVERRIDE;
- virtual void OnNativeWindowCreated(const gfx::Rect& bounds) OVERRIDE;
virtual internal::NativeWidgetDelegate* AsNativeWidgetDelegate() OVERRIDE;
private:
- // Sizes and positions the window just after it is created.
- void SetInitialBounds(const gfx::Rect& bounds);
-
NativeWindow* native_window_;
- // The saved maximized state for this window. See note in SetInitialBounds
- // that explains why we save this.
- bool saved_maximized_state_;
-
- // The smallest size the window can be.
- gfx::Size minimum_size_;
-
DISALLOW_COPY_AND_ASSIGN(Window);
};