diff options
author | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-07 23:12:38 +0000 |
---|---|---|
committer | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-07 23:12:38 +0000 |
commit | c6f9cc2dda4fc4541d0ee4bc91491ed2a6ef57cd (patch) | |
tree | 19a05b1605a19a38391b0d4c5abc4082dcd7399d | |
parent | ad7b6319e6b005a4d289695f5c22013a0f9dd933 (diff) | |
download | chromium_src-c6f9cc2dda4fc4541d0ee4bc91491ed2a6ef57cd.zip chromium_src-c6f9cc2dda4fc4541d0ee4bc91491ed2a6ef57cd.tar.gz chromium_src-c6f9cc2dda4fc4541d0ee4bc91491ed2a6ef57cd.tar.bz2 |
Move all the stuff relating to detached tab dragging out of BrowserFrameWin and onto the TabStrip2 object. It was mostly cross platform anyway.Adds APIs to Widget that:- allow a Widget to be obtained for a given gfx::NativeView- allow native properties to be set on a Widget.Adds an API to Window that lets the caller convert the window's appearance into a lightly transparent transient looking thing for dragging.BUG=noneTEST=none
Review URL: http://codereview.chromium.org/149440
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@31394 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/views/frame/browser_frame_win.cc | 76 | ||||
-rw-r--r-- | chrome/browser/views/frame/browser_frame_win.h | 17 | ||||
-rw-r--r-- | chrome/browser/views/tabs/tab_strip_2.cc | 75 | ||||
-rw-r--r-- | chrome/browser/views/tabs/tab_strip_2.h | 28 | ||||
-rw-r--r-- | views/widget/widget.h | 26 | ||||
-rw-r--r-- | views/widget/widget_gtk.cc | 71 | ||||
-rw-r--r-- | views/widget/widget_gtk.h | 9 | ||||
-rw-r--r-- | views/widget/widget_win.cc | 101 | ||||
-rw-r--r-- | views/widget/widget_win.h | 13 | ||||
-rw-r--r-- | views/window/window.h | 4 | ||||
-rw-r--r-- | views/window/window_gtk.cc | 4 | ||||
-rw-r--r-- | views/window/window_gtk.h | 1 | ||||
-rw-r--r-- | views/window/window_win.cc | 24 | ||||
-rw-r--r-- | views/window/window_win.h | 5 |
14 files changed, 298 insertions, 156 deletions
diff --git a/chrome/browser/views/frame/browser_frame_win.cc b/chrome/browser/views/frame/browser_frame_win.cc index a732934..a72bc3a 100644 --- a/chrome/browser/views/frame/browser_frame_win.cc +++ b/chrome/browser/views/frame/browser_frame_win.cc @@ -14,7 +14,6 @@ #include "app/win_util.h" #include "chrome/browser/profile.h" #include "chrome/browser/browser_list.h" -#include "chrome/browser/dock_info.h" #include "chrome/browser/views/frame/browser_non_client_frame_view.h" #include "chrome/browser/views/frame/browser_root_view.h" #include "chrome/browser/views/frame/browser_view.h" @@ -43,10 +42,6 @@ BrowserFrame* BrowserFrame::Create(BrowserView* browser_view, BrowserFrameWin::BrowserFrameWin(BrowserView* browser_view, Profile* profile) : WindowWin(browser_view), browser_view_(browser_view), - saved_window_style_(0), - saved_window_ex_style_(0), - detached_drag_mode_(false), - drop_tabstrip_(NULL), root_view_(NULL), frame_initialized_(false), profile_(profile) { @@ -92,11 +87,6 @@ void BrowserFrameWin::UpdateThrobber(bool running) { } void BrowserFrameWin::ContinueDraggingDetachedTab() { - detached_drag_mode_ = true; - - // Set the frame to partially transparent. - UpdateWindowAlphaForTabDragging(detached_drag_mode_); - // Send the message directly, so that the window is positioned appropriately. SendMessage(GetNativeWindow(), WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(0, 0)); } @@ -146,26 +136,14 @@ void BrowserFrameWin::OnEndSession(BOOL ending, UINT logoff) { } void BrowserFrameWin::OnEnterSizeMove() { - drop_tabstrip_ = NULL; + if (TabStrip2::Enabled()) + browser_view_->tabstrip()->AsBrowserTabStrip()->DetachDragStarted(); browser_view_->WindowMoveOrResizeStarted(); } void BrowserFrameWin::OnExitSizeMove() { - if (TabStrip2::Enabled()) { - if (detached_drag_mode_) { - detached_drag_mode_ = false; - if (drop_tabstrip_) { - gfx::Point screen_point = views::Screen::GetCursorScreenPoint(); - BrowserTabStrip* tabstrip = - browser_view_->tabstrip()->AsBrowserTabStrip(); - gfx::Rect tsb = tabstrip->GetDraggedTabScreenBounds(screen_point); - drop_tabstrip_->AttachTab(tabstrip->DetachTab(0), screen_point, tsb); - } else { - UpdateWindowAlphaForTabDragging(detached_drag_mode_); - browser_view_->tabstrip()->AsBrowserTabStrip()->SendDraggedTabHome(); - } - } - } + if (TabStrip2::Enabled()) + browser_view_->tabstrip()->AsBrowserTabStrip()->DetachDragEnded(); WidgetWin::OnExitSizeMove(); } @@ -209,30 +187,8 @@ LRESULT BrowserFrameWin::OnNCHitTest(const CPoint& pt) { } void BrowserFrameWin::OnWindowPosChanged(WINDOWPOS* window_pos) { - if (TabStrip2::Enabled()) { - if (detached_drag_mode_) { - // TODO(beng): move all to BrowserTabStrip... - - // We check to see if the mouse cursor is in the magnetism zone of another - // visible TabStrip. If so, we should dock to it. - std::set<HWND> ignore_windows; - ignore_windows.insert(GetNativeWindow()); - - gfx::Point screen_point = views::Screen::GetCursorScreenPoint(); - HWND local_window = - DockInfo::GetLocalProcessWindowAtPoint(screen_point, ignore_windows); - if (local_window) { - BrowserView* browser_view = - BrowserView::GetBrowserViewForNativeWindow(local_window); - drop_tabstrip_ = browser_view->tabstrip()->AsBrowserTabStrip(); - if (TabStrip2::IsDragRearrange(drop_tabstrip_, screen_point)) { - ReleaseCapture(); - return; - } - } - drop_tabstrip_ = NULL; - } - } + if (TabStrip2::Enabled()) + browser_view_->tabstrip()->AsBrowserTabStrip()->DetachDragMoved(); // Windows lies to us about the position of the minimize button before a // window is visible. We use the position of the minimize button to place the @@ -319,23 +275,3 @@ void BrowserFrameWin::UpdateDWMFrame() { } DwmExtendFrameIntoClientArea(GetNativeView(), &margins); } - -void BrowserFrameWin::UpdateWindowAlphaForTabDragging(bool dragging) { - HWND frame_hwnd = GetNativeWindow(); - if (dragging) { - // Make the frame slightly transparent during the drag operation. - saved_window_style_ = ::GetWindowLong(frame_hwnd, GWL_STYLE); - saved_window_ex_style_ = ::GetWindowLong(frame_hwnd, GWL_EXSTYLE); - ::SetWindowLong(frame_hwnd, GWL_EXSTYLE, - saved_window_ex_style_ | WS_EX_LAYERED); - // Remove the captions tyle so the window doesn't have window controls for a - // more "transparent" look. - ::SetWindowLong(frame_hwnd, GWL_STYLE, - saved_window_style_ & ~WS_CAPTION); - SetLayeredWindowAttributes(frame_hwnd, RGB(0xFF, 0xFF, 0xFF), - kTabDragWindowAlpha, LWA_ALPHA); - } else { - ::SetWindowLong(frame_hwnd, GWL_STYLE, saved_window_style_); - ::SetWindowLong(frame_hwnd, GWL_EXSTYLE, saved_window_ex_style_); - } -} diff --git a/chrome/browser/views/frame/browser_frame_win.h b/chrome/browser/views/frame/browser_frame_win.h index 789795b..04dc35b 100644 --- a/chrome/browser/views/frame/browser_frame_win.h +++ b/chrome/browser/views/frame/browser_frame_win.h @@ -76,10 +76,6 @@ class BrowserFrameWin : public BrowserFrame, public views::WindowWin { // Updates the DWM with the frame bounds. void UpdateDWMFrame(); - // Update the window's pacity when entering and exiting detached dragging - // mode. - void UpdateWindowAlphaForTabDragging(bool dragging); - // The BrowserView is our ClientView. This is a pointer to it. BrowserView* browser_view_; @@ -95,19 +91,6 @@ class BrowserFrameWin : public BrowserFrame, public views::WindowWin { Profile* profile_; - // The window styles before we modified them for a tab dragging operation. - DWORD saved_window_style_; - DWORD saved_window_ex_style_; - - // True if the window is currently being moved in a detached tab drag - // operation. - bool detached_drag_mode_; - - // When this frame represents a detached tab being dragged, this is a TabStrip - // in another window that the tab being dragged would be docked to if the - // mouse were released, or NULL if there is no suitable TabStrip. - BrowserTabStrip* drop_tabstrip_; - DISALLOW_COPY_AND_ASSIGN(BrowserFrameWin); }; diff --git a/chrome/browser/views/tabs/tab_strip_2.cc b/chrome/browser/views/tabs/tab_strip_2.cc index 280413d..12296eb 100644 --- a/chrome/browser/views/tabs/tab_strip_2.cc +++ b/chrome/browser/views/tabs/tab_strip_2.cc @@ -10,6 +10,7 @@ #include "base/compiler_specific.h" #include "base/message_loop.h" #include "build/build_config.h" +#include "chrome/browser/dock_info.h" #include "chrome/common/chrome_switches.h" #include "views/animator.h" #include "views/screen.h" @@ -23,12 +24,16 @@ static const int kHorizontalMoveThreshold = 16; // pixels +static const wchar_t* kTabStripKey = L"__VIEWS_TABSTRIP__"; + //////////////////////////////////////////////////////////////////////////////// // TabStrip2, public: TabStrip2::TabStrip2(TabStrip2Model* model) : model_(model), last_move_screen_x_(0), + detached_drag_mode_(false), + drop_tabstrip_(NULL), ALLOW_THIS_IN_INITIALIZER_LIST(detach_factory_(this)), ALLOW_THIS_IN_INITIALIZER_LIST(drag_start_factory_(this)) { } @@ -42,6 +47,17 @@ bool TabStrip2::Enabled() { switches::kEnableTabtastic2); } +// static +TabStrip2* TabStrip2::GetTabStripFromWindow(gfx::NativeWindow window) { + views::Widget* widget = views::Widget::GetWidgetFromNativeView(window); + if (widget) { + void* tabstrip = widget->GetNativeWindowProperty(kTabStripKey); + if (tabstrip) + return reinterpret_cast<TabStrip2*>(tabstrip); + } + return NULL; +} + void TabStrip2::AddTabAt(int index) { Tab2* tab = new Tab2(this); int insertion_index = GetInternalIndex(index); @@ -133,6 +149,55 @@ void TabStrip2::ResumeDraggingTab(int index, const gfx::Rect& tab_bounds) { tab_bounds)); } +void TabStrip2::DetachDragStarted() { + drop_tabstrip_ = NULL; + detached_drag_mode_ = true; + + // Set the frame to partially transparent. + GetWindow()->SetUseDragFrame(detached_drag_mode_); +} + +void TabStrip2::DetachDragMoved() { + if (detached_drag_mode_) { + // We check to see if the mouse cursor is in the magnetism zone of another + // visible TabStrip. If so, we should dock to it. + std::set<gfx::NativeWindow> ignore_windows; + ignore_windows.insert(GetWidget()->GetWindow()->GetNativeWindow()); + + gfx::Point screen_point = views::Screen::GetCursorScreenPoint(); + gfx::NativeWindow local_window = + DockInfo::GetLocalProcessWindowAtPoint(screen_point, ignore_windows); + if (local_window) { + drop_tabstrip_ = GetTabStripFromWindow(local_window); + if (IsDragRearrange(drop_tabstrip_, screen_point)) { +#if defined(OS_WIN) + ReleaseCapture(); +#elif defined(OS_LINUX) + // release grab maybe? + NOTIMPLEMENTED(); +#endif + return; + } + } + drop_tabstrip_ = NULL; + } +} + +void TabStrip2::DetachDragEnded() { + if (detached_drag_mode_) { + detached_drag_mode_ = false; + if (drop_tabstrip_) { + gfx::Point screen_point = views::Screen::GetCursorScreenPoint(); + gfx::Rect tsb = GetDraggedTabScreenBounds(screen_point); + // TODO(beng): figure this one out. + //drop_tabstrip_->AttachTab(tabstrip->DetachTab(0), screen_point, tsb); + } else { + GetWindow()->SetUseDragFrame(detached_drag_mode_); + SendDraggedTabHome(); + } + } +} + // static bool TabStrip2::IsDragRearrange(TabStrip2* tabstrip, const gfx::Point& screen_point) { @@ -314,6 +379,16 @@ void TabStrip2::PaintChildren(gfx::Canvas* canvas) { selected_tab->ProcessPaint(canvas); } +void TabStrip2::ViewHierarchyChanged(bool is_add, + views::View* parent, + views::View* child) { + if (is_add && child == this) { + // Widget must exist now, otherwise someone has screwed up the order in + // which views are added to the hierarchy. + GetWidget()->SetNativeWindowProperty(kTabStripKey, this); + } +} + //////////////////////////////////////////////////////////////////////////////// // TabStrip2, views::AnimatorDelegate implementation: diff --git a/chrome/browser/views/tabs/tab_strip_2.h b/chrome/browser/views/tabs/tab_strip_2.h index f407d89..dc61569 100644 --- a/chrome/browser/views/tabs/tab_strip_2.h +++ b/chrome/browser/views/tabs/tab_strip_2.h @@ -60,6 +60,10 @@ class TabStrip2 : public views::View, // Returns true if the new TabStrip is enabled. static bool Enabled(); + // Returns the tabstrip associated with the specificied top level window, or + // NULL if there is no tabstrip. + static TabStrip2* GetTabStripFromWindow(gfx::NativeWindow window); + // API for adding, removing, selecting and moving tabs around. void AddTabAt(int index); void RemoveTabAt(int index, Tab2Model* removing_model); @@ -87,6 +91,17 @@ class TabStrip2 : public views::View, // Continue a drag operation on the Tab2 at the specified index. void ResumeDraggingTab(int index, const gfx::Rect& tab_bounds); + // Notifies the tabstrip that a detach drag operation has begun. + void DetachDragStarted(); + + // Notifies the tabstrip that a detach drag operation is underway and the + // dragged representation has been moved. + void DetachDragMoved(); + + // Notifies the tabstrip that a detach drag operation has completed. Called + // by the window that contains this tabstrip. + void DetachDragEnded(); + // Returns true if the mouse pointer at the specified point (screen bounds) // constitutes a rearrange rather than a detach. static bool IsDragRearrange(TabStrip2* tabstrip, @@ -113,6 +128,9 @@ class TabStrip2 : public views::View, private: virtual void PaintChildren(gfx::Canvas* canvas); + virtual void ViewHierarchyChanged(bool is_add, + views::View* parent, + views::View* child); // Overridden from views::AnimatorDelegate: virtual views::View* GetClampedView(views::View* host); @@ -164,6 +182,16 @@ class TabStrip2 : public views::View, // beyond the minimum horizontal threshold to initiate a drag operation. int last_move_screen_x_; + // True if the window containing this tabstrip is currently being moved as + // part of a detached tab drag operation. + bool detached_drag_mode_; + + // When the window containing this tabstrip represents a detached tab being + // dragged, this is a tabstrip in another window that the tab being dragged + // would be docked to if the mouse were released, or NULL if there is no + // suitable tabstrip. + TabStrip2* drop_tabstrip_; + // Factories to help break up work and avoid nesting message loops. ScopedRunnableMethodFactory<TabStrip2> detach_factory_; ScopedRunnableMethodFactory<TabStrip2> drag_start_factory_; diff --git a/views/widget/widget.h b/views/widget/widget.h index 357f07a..3dafc00 100644 --- a/views/widget/widget.h +++ b/views/widget/widget.h @@ -83,6 +83,11 @@ class Widget { // View, unless it is set as not being parent-owned. virtual void SetContentsView(View* view) = 0; + // Retrieve the Widget corresponding to the specified native_view, or NULL + // if there is no such Widget. + static Widget* GetWidgetFromNativeView(gfx::NativeView native_view); + static Widget* GetWidgetFromNativeWindow(gfx::NativeWindow native_window); + // Returns the bounds of this Widget in the screen coordinate system. // If the receiving Widget is a frame which is larger than its client area, // this method returns the client area if including_frame is false and the @@ -140,9 +145,7 @@ class Widget { // Returns the TooltipManager for this Widget. If this Widget does not support // tooltips, NULL is returned. - virtual TooltipManager* GetTooltipManager() { - return NULL; - } + virtual TooltipManager* GetTooltipManager() = 0; // Starts a drag operation for the specified view. |point| is a position in // |view| coordinates that the drag was initiated from. @@ -156,20 +159,27 @@ class Widget { // Returns the Window containing this Widget, or NULL if not contained in a // window. - virtual Window* GetWindow() { return NULL; } - virtual const Window* GetWindow() const { return NULL; } + virtual Window* GetWindow() = 0; + virtual const Window* GetWindow() const = 0; + + // Sets/Gets a native window property on the underlying native window object. + // Returns NULL if the property does not exist. Setting the property value to + // NULL removes the property. + virtual void SetNativeWindowProperty(const std::wstring& name, + void* value) = 0; + virtual void* GetNativeWindowProperty(const std::wstring& name) = 0; // Gets the theme provider. - virtual ThemeProvider* GetThemeProvider() const { return NULL; } + virtual ThemeProvider* GetThemeProvider() const = 0; // Gets the default theme provider; this is necessary for when a widget has // no profile (and ThemeProvider) associated with it. The default theme // provider provides a default set of bitmaps that such widgets can use. - virtual ThemeProvider* GetDefaultThemeProvider() const { return NULL; } + virtual ThemeProvider* GetDefaultThemeProvider() const = 0; // Returns the FocusManager for this widget. // Note that all widgets in a widget hierarchy share the same focus manager. - virtual FocusManager* GetFocusManager() { return NULL; } + virtual FocusManager* GetFocusManager() = 0; // Forwarded from the RootView so that the widget can do any cleanup. virtual void ViewHierarchyChanged(bool is_add, View *parent, diff --git a/views/widget/widget_gtk.cc b/views/widget/widget_gtk.cc index 4edef7c..48ae642 100644 --- a/views/widget/widget_gtk.cc +++ b/views/widget/widget_gtk.cc @@ -10,6 +10,7 @@ #include "app/os_exchange_data_provider_gtk.h" #include "base/compiler_specific.h" #include "base/message_loop.h" +#include "base/string_util.h" #include "views/widget/default_theme_provider.h" #include "views/widget/drop_target_gtk.h" #include "views/widget/root_view.h" @@ -49,6 +50,8 @@ class WidgetGtk::DropObserver : public MessageLoopForUI::Observer { DISALLOW_COPY_AND_ASSIGN(DropObserver); }; +static const char* kWidgetKey = "__VIEWS_WIDGET__"; + // Returns the position of a widget on screen. static void GetWidgetPositionOnScreen(GtkWidget* widget, int* x, int *y) { // First get the root window. @@ -470,15 +473,15 @@ bool WidgetGtk::IsActive() const { return is_active_; } +TooltipManager* WidgetGtk::GetTooltipManager() { + return tooltip_manager_.get(); +} + void WidgetGtk::GenerateMousePressedForView(View* view, const gfx::Point& point) { NOTIMPLEMENTED(); } -TooltipManager* WidgetGtk::GetTooltipManager() { - return tooltip_manager_.get(); -} - bool WidgetGtk::GetAccelerator(int cmd_id, Accelerator* accelerator) { NOTIMPLEMENTED(); return false; @@ -492,10 +495,6 @@ const Window* WidgetGtk::GetWindow() const { return GetWindowImpl(widget_); } -ThemeProvider* WidgetGtk::GetThemeProvider() const { - return default_theme_provider_.get(); -} - FocusManager* WidgetGtk::GetFocusManager() { if (focus_manager_.get()) return focus_manager_.get(); @@ -515,6 +514,28 @@ void WidgetGtk::ViewHierarchyChanged(bool is_add, View *parent, drop_target_->ResetTargetViewIfEquals(child); } +void WidgetGtk::SetNativeWindowProperty(const std::wstring& name, + void* value) { + g_object_set_data(G_OBJECT(widget_), WideToUTF8(name).c_str(), value); +} + +void* WidgetGtk::GetNativeWindowProperty(const std::wstring& name) { + return g_object_get_data(G_OBJECT(widget_), WideToUTF8(name).c_str()); +} + +ThemeProvider* WidgetGtk::GetThemeProvider() const { + return default_theme_provider_.get(); +} + +ThemeProvider* WidgetGtk::GetDefaultThemeProvider() { + return NULL; +} + +FocusManager* WidgetGtk::GetFocusManager() { + NOTIMPLEMENTED(); + return NULL; +} + //////////////////////////////////////////////////////////////////////////////// // WidgetGtk, MessageLoopForUI::Observer implementation: @@ -585,7 +606,6 @@ void WidgetGtk::CreateGtkWidget(GtkWidget* parent, const gfx::Rect& bounds) { gtk_widget_realize(null_parent_); } gtk_container_add(GTK_CONTAINER(parent ? parent : null_parent_), widget_); - SetViewForNative(widget_, this); } else { widget_ = gtk_window_new( (type_ == TYPE_WINDOW || type_ == TYPE_DECORATED_WINDOW) ? @@ -607,14 +627,13 @@ void WidgetGtk::CreateGtkWidget(GtkWidget* parent, const gfx::Rect& bounds) { gtk_window_set_position(GTK_WINDOW(widget_), GTK_WIN_POS_NONE); } SetWindowForNative(widget_, static_cast<WindowGtk*>(this)); - SetViewForNative(widget_, this); window_contents_ = gtk_fixed_new(); GTK_WIDGET_UNSET_FLAGS(window_contents_, GTK_DOUBLE_BUFFERED); gtk_fixed_set_has_window(GTK_FIXED(window_contents_), true); gtk_container_add(GTK_CONTAINER(widget_), window_contents_); gtk_widget_show(window_contents_); - SetViewForNative(window_contents_, this); + g_object_set_data(G_OBJECT(window_contents_), kWidgetKey, this); if (transparent_) ConfigureWidgetForTransparentBackground(); @@ -623,6 +642,9 @@ void WidgetGtk::CreateGtkWidget(GtkWidget* parent, const gfx::Rect& bounds) { // The widget needs to be realized before handlers like size-allocate can // function properly. gtk_widget_realize(widget_); + + // Associate this object with the widget. + SetNativeWindowProperty(kWidgetKey, this); } void WidgetGtk::OnSizeAllocate(GtkWidget* widget, GtkAllocation* allocation) { @@ -937,8 +959,7 @@ void WidgetGtk::ProcessMouseReleased(GdkEventButton* event) { // static WidgetGtk* WidgetGtk::GetViewForNative(GtkWidget* widget) { - gpointer user_data = g_object_get_data(G_OBJECT(widget), "chrome-views"); - return static_cast<WidgetGtk*>(user_data); + return static_cast<WidgetGtk*>(GetWidgetFromNativeView(widget)); } void WidgetGtk::ResetDropTarget() { @@ -947,11 +968,6 @@ void WidgetGtk::ResetDropTarget() { } // static -void WidgetGtk::SetViewForNative(GtkWidget* widget, WidgetGtk* view) { - g_object_set_data(G_OBJECT(widget), "chrome-views", view); -} - -// static void WidgetGtk::SetRootViewForWidget(GtkWidget* widget, RootView* root_view) { g_object_set_data(G_OBJECT(widget), "root-view", root_view); } @@ -1262,4 +1278,23 @@ RootView* Widget::FindRootView(GtkWindow* window) { return root_view; } +//////////////////////////////////////////////////////////////////////////////// +// Widget, public: + +// static +Widget* Widget::GetWidgetFromNativeView(gfx::NativeView native_view) { + gpointer raw_widget = g_object_get_data(G_OBJECT(native_view), kWidgetKey); + if (raw_widget) + return reinterpret_cast<Widget*>(raw_widget); + return NULL; +} + +// static +Widget* Widget::GetWidgetFromNativeWindow(gfx::NativeWindow native_window) { + gpointer raw_widget = g_object_get_data(G_OBJECT(native_window), kWidgetKey); + if (raw_widget) + return reinterpret_cast<Widget*>(raw_widget); + return NULL; +} + } // namespace views diff --git a/views/widget/widget_gtk.h b/views/widget/widget_gtk.h index 3799a4a..b36856f 100644 --- a/views/widget/widget_gtk.h +++ b/views/widget/widget_gtk.h @@ -137,7 +137,11 @@ class WidgetGtk virtual bool GetAccelerator(int cmd_id, Accelerator* accelerator); virtual Window* GetWindow(); virtual const Window* GetWindow() const; + virtual void SetNativeWindowProperty(const std::wstring& name, + void* value); + virtual void* GetNativeWindowProperty(const std::wstring& name); virtual ThemeProvider* GetThemeProvider() const; + virtual ThemeProvider* GetDefaultThemeProvider(); virtual FocusManager* GetFocusManager(); virtual void ViewHierarchyChanged(bool is_add, View *parent, View *child); @@ -160,12 +164,9 @@ class WidgetGtk void SetFocusTraversableParent(FocusTraversable* parent); void SetFocusTraversableParentView(View* parent_view); - // Retrieves the WidgetGtk associated with |widget|. + // Gets the WidgetGtk in the userdata section of the widget. static WidgetGtk* GetViewForNative(GtkWidget* widget); - // Retrieves the WindowGtk associated with |widget|. - static WindowGtk* GetWindowForNative(GtkWidget* widget); - // Sets the drop target to NULL. This is invoked by DropTargetGTK when the // drop is done. void ResetDropTarget(); diff --git a/views/widget/widget_win.cc b/views/widget/widget_win.cc index a3dc3ce..1853d5e 100644 --- a/views/widget/widget_win.cc +++ b/views/widget/widget_win.cc @@ -25,6 +25,7 @@ namespace views { // Property used to link the HWND to its RootView. static const wchar_t* const kRootViewWindowProperty = L"__ROOT_VIEW__"; +static const wchar_t* kWidgetKey = L"__VIEWS_WIDGET__"; bool SetRootViewForHWND(HWND hwnd, RootView* root_view) { return SetProp(hwnd, kRootViewWindowProperty, root_view) ? true : false; @@ -60,6 +61,25 @@ WidgetWin::~WidgetWin() { MessageLoopForUI::current()->RemoveObserver(this); } +// static +WidgetWin* WidgetWin::GetWidget(HWND hwnd) { + return reinterpret_cast<WidgetWin*>(win_util::GetWindowUserData(hwnd)); +} + +void WidgetWin::SetUseLayeredBuffer(bool use_layered_buffer) { + if (use_layered_buffer_ == use_layered_buffer) + return; + + use_layered_buffer_ = use_layered_buffer; + if (!hwnd()) + return; + + if (use_layered_buffer_) + LayoutRootView(); + else + contents_.reset(NULL); +} + /////////////////////////////////////////////////////////////////////////////// // Widget implementation: @@ -287,6 +307,10 @@ bool WidgetWin::IsActive() const { return win_util::IsWindowActive(hwnd()); } +TooltipManager* WidgetWin::GetTooltipManager() { + return tooltip_manager_.get(); +} + void WidgetWin::GenerateMousePressedForView(View* view, const gfx::Point& point) { gfx::Point point_in_widget(point); @@ -295,8 +319,28 @@ void WidgetWin::GenerateMousePressedForView(View* view, ProcessMousePressed(point_in_widget.ToPOINT(), MK_LBUTTON, false, false); } -TooltipManager* WidgetWin::GetTooltipManager() { - return tooltip_manager_.get(); +bool WidgetWin::GetAccelerator(int cmd_id, Accelerator* accelerator) { + return false; +} + +Window* WidgetWin::GetWindow() { + return GetWindowImpl(hwnd()); +} + +const Window* WidgetWin::GetWindow() const { + return GetWindowImpl(hwnd()); +} + +void WidgetWin::SetNativeWindowProperty(const std::wstring& name, + void* value) { + if (value) + SetProp(hwnd(), name.c_str(), value); + else + RemoveProp(hwnd(), name.c_str()); +} + +void* WidgetWin::GetNativeWindowProperty(const std::wstring& name) { + return GetProp(hwnd(), name.c_str()); } ThemeProvider* WidgetWin::GetThemeProvider() const { @@ -315,13 +359,10 @@ ThemeProvider* WidgetWin::GetThemeProvider() const { return default_theme_provider_.get(); } -Window* WidgetWin::GetWindow() { - return GetWindowImpl(hwnd()); +ThemeProvider* WidgetWin::GetDefaultThemeProvider() const { + return default_theme_provider_.get(); } -const Window* WidgetWin::GetWindow() const { - return GetWindowImpl(hwnd()); -} FocusManager* WidgetWin::GetFocusManager() { if (focus_manager_.get()) @@ -342,31 +383,6 @@ void WidgetWin::ViewHierarchyChanged(bool is_add, View *parent, drop_target_->ResetTargetViewIfEquals(child); } -bool WidgetWin::GetAccelerator(int cmd_id, Accelerator* accelerator) { - return false; -} - -void WidgetWin::SetUseLayeredBuffer(bool use_layered_buffer) { - if (use_layered_buffer_ == use_layered_buffer) - return; - - use_layered_buffer_ = use_layered_buffer; - if (!hwnd()) - return; - - if (use_layered_buffer_) { - // Force creation of the buffer at the right size. - LayoutRootView(); - } else { - contents_.reset(NULL); - } -} - -// static -WidgetWin* WidgetWin::GetWidget(HWND hwnd) { - return reinterpret_cast<WidgetWin*>(win_util::GetWindowUserData(hwnd)); -} - //////////////////////////////////////////////////////////////////////////////// // MessageLoop::Observer @@ -454,10 +470,13 @@ void WidgetWin::OnCommand(UINT notification_code, int command_id, HWND window) { } LRESULT WidgetWin::OnCreate(CREATESTRUCT* create_struct) { + SetNativeWindowProperty(kWidgetKey, this); return 0; } void WidgetWin::OnDestroy() { + SetNativeWindowProperty(kWidgetKey, NULL); + if (drop_target_.get()) { RevokeDragDrop(hwnd()); drop_target_ = NULL; @@ -1184,4 +1203,22 @@ RootView* Widget::FindRootView(HWND hwnd) { return root_view; } +//////////////////////////////////////////////////////////////////////////////// +// Widget, public: + +// static +Widget* Widget::GetWidgetFromNativeView(gfx::NativeView native_view) { + if (IsWindow(native_view)) { + HANDLE raw_widget = GetProp(native_view, kWidgetKey); + if (raw_widget) + return reinterpret_cast<Widget*>(raw_widget); + } + return NULL; +} + +// static +Widget* Widget::GetWidgetFromNativeWindow(gfx::NativeWindow native_window) { + return Widget::GetWidgetFromNativeView(native_window); +} + } // namespace views diff --git a/views/widget/widget_win.h b/views/widget/widget_win.h index f22417c..3f06ca3 100644 --- a/views/widget/widget_win.h +++ b/views/widget/widget_win.h @@ -74,9 +74,6 @@ class WidgetWin : public app::WindowImpl, WidgetWin(); virtual ~WidgetWin(); - // Returns the RootView associated with the specified HWND (if any). - static RootView* FindRootView(HWND hwnd); - // Returns the Widget associated with the specified HWND (if any). static WidgetWin* GetWidget(HWND hwnd); @@ -197,16 +194,20 @@ class WidgetWin : public app::WindowImpl, virtual Widget* GetRootWidget() const; virtual bool IsVisible() const; virtual bool IsActive() const; + virtual TooltipManager* GetTooltipManager(); virtual void GenerateMousePressedForView(View* view, const gfx::Point& point); - virtual TooltipManager* GetTooltipManager(); - virtual ThemeProvider* GetThemeProvider() const; + virtual bool GetAccelerator(int cmd_id, Accelerator* accelerator); virtual Window* GetWindow(); virtual const Window* GetWindow() const; + virtual void SetNativeWindowProperty(const std::wstring& name, + void* value); + virtual void* GetNativeWindowProperty(const std::wstring& name); + virtual ThemeProvider* GetThemeProvider() const; + virtual ThemeProvider* GetDefaultThemeProvider() const; virtual FocusManager* GetFocusManager(); virtual void ViewHierarchyChanged(bool is_add, View *parent, View *child); - virtual bool GetAccelerator(int cmd_id, Accelerator* accelerator); // Overridden from MessageLoop::Observer: void WillProcessMessage(const MSG& msg); diff --git a/views/window/window.h b/views/window/window.h index becb8d0..d322d8f 100644 --- a/views/window/window.h +++ b/views/window/window.h @@ -120,6 +120,10 @@ class Window { virtual void SetFullscreen(bool fullscreen) = 0; virtual bool IsFullscreen() const = 0; + // Sets whether or not the window should show its frame as a "transient drag + // frame" - slightly transparent and without the standard window controls. + virtual void SetUseDragFrame(bool use_drag_frame) = 0; + // Returns true if the Window is considered to be an "app window" - i.e. // any window which when it is the last of its type closed causes the // application to exit. diff --git a/views/window/window_gtk.cc b/views/window/window_gtk.cc index fff4e74..2cacccd 100644 --- a/views/window/window_gtk.cc +++ b/views/window/window_gtk.cc @@ -185,6 +185,10 @@ bool WindowGtk::IsFullscreen() const { return window_state_ & GDK_WINDOW_STATE_FULLSCREEN; } +void WindowGtk::SetUseDragFrame(bool use_drag_frame) { + NOTIMPLEMENTED(); +} + void WindowGtk::EnableClose(bool enable) { gtk_window_set_deletable(GetNativeWindow(), enable); } diff --git a/views/window/window_gtk.h b/views/window/window_gtk.h index 7829e28..a9457af 100644 --- a/views/window/window_gtk.h +++ b/views/window/window_gtk.h @@ -42,6 +42,7 @@ class WindowGtk : public WidgetGtk, public Window { virtual bool IsMinimized() const; virtual void SetFullscreen(bool fullscreen); virtual bool IsFullscreen() const; + virtual void SetUseDragFrame(bool use_drag_frame); virtual void EnableClose(bool enable); virtual void UpdateWindowTitle(); virtual void UpdateWindowIcon(); diff --git a/views/window/window_win.cc b/views/window/window_win.cc index 66a1e85..84a09b6 100644 --- a/views/window/window_win.cc +++ b/views/window/window_win.cc @@ -25,6 +25,8 @@ namespace { +static const int kDragFrameWindowAlpha = 200; + bool GetMonitorAndRects(const RECT& rect, HMONITOR* monitor, gfx::Rect* monitor_rect, @@ -355,6 +357,24 @@ bool WindowWin::IsFullscreen() const { return fullscreen_; } +void WindowWin::SetUseDragFrame(bool use_drag_frame) { + if (use_drag_frame) { + // Make the frame slightly transparent during the drag operation. + drag_frame_saved_window_style_ = GetWindowLong(GWL_STYLE); + drag_frame_saved_window_ex_style_ = GetWindowLong(GWL_EXSTYLE); + SetWindowLong(GWL_EXSTYLE, + drag_frame_saved_window_ex_style_ | WS_EX_LAYERED); + // Remove the captions tyle so the window doesn't have window controls for a + // more "transparent" look. + SetWindowLong(GWL_STYLE, drag_frame_saved_window_style_ & ~WS_CAPTION); + SetLayeredWindowAttributes(GetNativeWindow(), RGB(0xFF, 0xFF, 0xFF), + kDragFrameWindowAlpha, LWA_ALPHA); + } else { + SetWindowLong(GWL_STYLE, drag_frame_saved_window_style_); + SetWindowLong(GWL_EXSTYLE, drag_frame_saved_window_ex_style_); + } +} + void WindowWin::EnableClose(bool enable) { // If the native frame is rendering its own close button, ask it to disable. non_client_view_->EnableClose(enable); @@ -479,7 +499,9 @@ WindowWin::WindowWin(WindowDelegate* window_delegate) ignore_pos_changes_factory_(this), force_hidden_count_(0), is_right_mouse_pressed_on_caption_(false), - last_monitor_(NULL) { + last_monitor_(NULL), + drag_frame_saved_window_style_(0), + drag_frame_saved_window_ex_style_(false) { is_window_ = true; InitClass(); DCHECK(window_delegate_); diff --git a/views/window/window_win.h b/views/window/window_win.h index 19a92d4..c9c19cf 100644 --- a/views/window/window_win.h +++ b/views/window/window_win.h @@ -74,6 +74,7 @@ class WindowWin : public WidgetWin, virtual bool IsMinimized() const; virtual void SetFullscreen(bool fullscreen); virtual bool IsFullscreen() const; + virtual void SetUseDragFrame(bool use_drag_frame); virtual void EnableClose(bool enable); virtual void DisableInactiveRendering(); virtual void UpdateWindowTitle(); @@ -297,6 +298,10 @@ class WindowWin : public WidgetWin, HMONITOR last_monitor_; gfx::Rect last_monitor_rect_, last_work_area_; + // The window styles before we modified them for the drag frame appearance. + DWORD drag_frame_saved_window_style_; + DWORD drag_frame_saved_window_ex_style_; + DISALLOW_COPY_AND_ASSIGN(WindowWin); }; |