summaryrefslogtreecommitdiffstats
path: root/views/widget
diff options
context:
space:
mode:
authorben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-13 16:03:53 +0000
committerben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-13 16:03:53 +0000
commit4672de6247fe7a865b2abeaac1b4a76c9369b7a3 (patch)
treeeaa314bbb797dae5152877b1ad170f44d1eb51b4 /views/widget
parent37ae86f0c4b50dc83b13da17ae1a9ef7083fa76f (diff)
downloadchromium_src-4672de6247fe7a865b2abeaac1b4a76c9369b7a3.zip
chromium_src-4672de6247fe7a865b2abeaac1b4a76c9369b7a3.tar.gz
chromium_src-4672de6247fe7a865b2abeaac1b4a76c9369b7a3.tar.bz2
Split the hierarchy.
* Widget ---- Now recognizes a supplied NativeWidget via InitParams. If this is specified then a default one is not created. Is now created directly rather than using a factory. NativeWidget creation is not performed until Init() is called. This means some functions that rely on a NativeWidget must not be called until _AFTER_ Init() (explains some of the function call reordering in this CL, e.g. moving SetOpacity() until after Init()). ResetLastMouseMovedFlag() moved to this API so that BaseTabStrip can call it in a cross-platform way. Made last remaining unimplemented methods on Widget pass-thru to NativeWidget implementations. * WidgetWin/WidgetGtk ---- The NativeWidget implementations now both require a NativeWidgetDelegate implementation upon construction. This is passed through the constructor by the static factory method NativeWidget::CreateNativeWidget and by subclasses such as WindowWin, BubbleWidgetWin, etc. Some classes that are constructed directly (e.g. LockWindow, in ChromeOS) never have a Widget created for them, so they create the Widget themselves in their base class initializer. Code in these classes (and their WindowWin/WindowGtk, BrowserFrameWin, BrowserFrameGtk subclasses) must now call GetWidget() etc to call Widget API methods since they are no longer subclasses. static_casting to this (and derived) types must now be done on the Widget's native_widget(). GetWindow() is renamed to GetContainingWindow() to avoid naming conflicts. * Window ---- Window is now a subclass of Widget. Now recognizes a supplied NativeWindow via InitParams. If this is specified then a default one is not created. Window::CloseWindow becomes an override of Widget::Close. CloseAllSecondaryWindows() becomes CloseAllSecondaryWidgets() and moves to widget.h IsAppWindow() is removed and replaced by set_is_secondary_widget on Widget. * MenuHost ---- Subclasses Widget now. * TabContentsViewViews ---- It looks like the Gtk-views code here was still using the old implementation of the Native version of this class - i.e. a class that subclassed TabContentsView AND WidgetGtk. A no-no. I had to write NativeTabContentsViewGtk, which is almost identical to NativeTabContentsViewWin with the Gtk bits of TabContentsViewGtk thrown in. * BrowserFrame ---- Platform-specific functionality is now restricted to BrowserFrameWin/BrowserFrameGtk behind a NativeBrowserFrame interface. Construction is exposed via a static factory method on NativeBrowserFrame. BrowserFrame becomes a concrete class that now subclasses Window. As a result, it no longer needs a GetWindow() accessor method, so people with a BrowserFrame* can just call Window methods directly on it. It is constructed directly, replacing the BrowserFrame::Create() method. NativeBrowserFrameDelegate is no longer needed. BrowserFrameChromeos is simpler as a couple of #ifdefs in BrowserFrame, so I got rid of that too. * AutocompletePopupWin/Gtk ---- No longer required. AutocompletePopupContentsView now just uses a Widget directly. * There is some lingering ugliness: - If you set a native_window field on Window::InitParams you must also manually set widget_init_params.native_widget. I will make InitParams do more of this automatically later. - It'd be nice for the ContentsView to be specified via InitParams. I'll get to this later. - NativeBrowserFrame could probably disappear as an interface. It only exists to provide a couple of methods that may be implemented in other ways. - delete_on_destroy should now be an ownership directionality enum. I will do this later. - Secondary-widgetness should somehow be inferred from transience. Later. - set_focus_on_creation for both the NativeWidgets should probably move to Widget if it is really needed. - WidgetWin/Gtk::SetInitialFocus seems like it could move to Widget. - I need to clean up function order in some cases. BUG=72040 TEST=none Review URL: http://codereview.chromium.org/7012006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@85269 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views/widget')
-rw-r--r--views/widget/drop_target_gtk.cc10
-rw-r--r--views/widget/native_widget.h26
-rw-r--r--views/widget/native_widget_delegate.h4
-rw-r--r--views/widget/native_widget_test_utils_gtk.cc4
-rw-r--r--views/widget/native_widget_test_utils_win.cc4
-rw-r--r--views/widget/tooltip_manager_gtk.cc6
-rw-r--r--views/widget/widget.cc59
-rw-r--r--views/widget/widget.h92
-rw-r--r--views/widget/widget_gtk.cc223
-rw-r--r--views/widget/widget_gtk.h59
-rw-r--r--views/widget/widget_win.cc192
-rw-r--r--views/widget/widget_win.h42
-rw-r--r--views/widget/widget_win_unittest.cc2
13 files changed, 432 insertions, 291 deletions
diff --git a/views/widget/drop_target_gtk.cc b/views/widget/drop_target_gtk.cc
index 5025ae4..c135d91 100644
--- a/views/widget/drop_target_gtk.cc
+++ b/views/widget/drop_target_gtk.cc
@@ -167,7 +167,7 @@ gboolean DropTargetGtk::OnDragDrop(GdkDragContext* context,
if (!pending_view_) {
// User isn't over a view, no drop can occur.
static_cast<WidgetGtk*>(
- helper_.root_view()->GetWidget())->ResetDropTarget();
+ helper_.root_view()->GetWidget()->native_widget())->ResetDropTarget();
// WARNING: we've been deleted.
return FALSE;
}
@@ -246,7 +246,8 @@ void DropTargetGtk::FinishDrop(GdkDragContext* context,
gtk_drag_finish(context, gdk_action != 0, (gdk_action & GDK_ACTION_MOVE),
time);
- static_cast<WidgetGtk*>(helper_.root_view()->GetWidget())->ResetDropTarget();
+ static_cast<WidgetGtk*>(helper_.root_view()->GetWidget()->native_widget())->
+ ResetDropTarget();
// WARNING: we've been deleted.
}
@@ -264,9 +265,8 @@ void DropTargetGtk::RequestFormats(GdkDragContext* context,
int formats,
const std::set<GdkAtom>& custom_formats,
guint time) {
- GtkWidget* widget =
- static_cast<WidgetGtk*>(helper_.root_view()->GetWidget())->
- window_contents();
+ GtkWidget* widget = static_cast<WidgetGtk*>(helper_.root_view()->GetWidget()->
+ native_widget())->window_contents();
const std::set<GdkAtom>& known_formats =
data_provider().known_custom_formats();
diff --git a/views/widget/native_widget.h b/views/widget/native_widget.h
index 451a0e9..c672044 100644
--- a/views/widget/native_widget.h
+++ b/views/widget/native_widget.h
@@ -36,6 +36,11 @@ class NativeWidget {
virtual ~NativeWidget() {}
+ // Creates an appropriate default NativeWidget implementation for the current
+ // OS/circumstance.
+ static NativeWidget* CreateNativeWidget(
+ internal::NativeWidgetDelegate* delegate);
+
// Retrieves the NativeWidget implementation associated with the given
// NativeView or Window, or NULL if the supplied handle has no associated
// NativeView.
@@ -64,6 +69,19 @@ class NativeWidget {
// Returns the Widget associated with this NativeWidget. This function is
// guaranteed to return non-NULL for the lifetime of the NativeWidget.
virtual Widget* GetWidget() = 0;
+ virtual const Widget* GetWidget() const = 0;
+
+ // Returns the NativeView/Window associated with this NativeWidget.
+ virtual gfx::NativeView GetNativeView() const = 0;
+ virtual gfx::NativeWindow GetNativeWindow() const = 0;
+
+ // Returns the enclosing Window, or NULL if there is no enclosing Window.
+ virtual Window* GetContainingWindow() = 0;
+ virtual const Window* GetContainingWindow() const = 0;
+
+ // Notifies the NativeWidget that a view was removed from the Widget's view
+ // hierarchy.
+ virtual void ViewRemoved(View* view) = 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
@@ -78,6 +96,11 @@ class NativeWidget {
// Returns true if a system screen reader is active for the NativeWidget.
virtual bool IsScreenReaderActive() const = 0;
+ // Notify native Accessibility clients of an event.
+ virtual void SendNativeAccessibilityEvent(
+ View* view,
+ ui::AccessibilityTypes::Event event_type) = 0;
+
// Sets or releases event capturing for this native widget.
virtual void SetMouseCapture() = 0;
virtual void ReleaseMouseCapture() = 0;
@@ -85,6 +108,9 @@ class NativeWidget {
// Returns true if this native widget is capturing all events.
virtual bool HasMouseCapture() const = 0;
+ // Returns true if any mouse button is currently pressed.
+ virtual bool IsMouseButtonDown() const = 0;
+
// Returns the InputMethod for this native widget.
// Note that all widgets in a widget hierarchy share the same input method.
// TODO(suzhe): rename to GetInputMethod() when NativeWidget implementation
diff --git a/views/widget/native_widget_delegate.h b/views/widget/native_widget_delegate.h
index 036bb48..05af457 100644
--- a/views/widget/native_widget_delegate.h
+++ b/views/widget/native_widget_delegate.h
@@ -50,6 +50,10 @@ class NativeWidgetDelegate {
virtual bool OnKeyEvent(const KeyEvent& event) = 0;
virtual bool OnMouseEvent(const MouseEvent& event) = 0;
virtual void OnMouseCaptureLost() = 0;
+
+ //
+ virtual Widget* AsWidget() = 0;
+ virtual const Widget* AsWidget() const = 0;
};
} // namespace internal
diff --git a/views/widget/native_widget_test_utils_gtk.cc b/views/widget/native_widget_test_utils_gtk.cc
index 6c478f2..2e0a820 100644
--- a/views/widget/native_widget_test_utils_gtk.cc
+++ b/views/widget/native_widget_test_utils_gtk.cc
@@ -16,7 +16,7 @@ NativeWidget* CreateNativeWidget() {
}
NativeWidget* CreateNativeWidgetWithContents(View* contents_view) {
- Widget* widget = Widget::CreateWidget();
+ Widget* widget = new Widget;
Widget::InitParams params(Widget::InitParams::TYPE_WINDOW);
params.delete_on_destroy = false;
params.bounds = gfx::Rect(10, 10, 200, 200);
@@ -25,7 +25,7 @@ NativeWidget* CreateNativeWidgetWithContents(View* contents_view) {
}
NativeWidget* CreateNativeWidgetWithParent(NativeWidget* parent) {
- Widget* widget = Widget::CreateWidget();
+ Widget* widget = new Widget;
Widget::InitParams params(Widget::InitParams::TYPE_CONTROL);
params.delete_on_destroy = false;
params.parent = parent ? parent->GetWidget()->GetNativeView() : NULL;
diff --git a/views/widget/native_widget_test_utils_win.cc b/views/widget/native_widget_test_utils_win.cc
index 59e1d8d..fd89efe 100644
--- a/views/widget/native_widget_test_utils_win.cc
+++ b/views/widget/native_widget_test_utils_win.cc
@@ -15,7 +15,7 @@ NativeWidget* CreateNativeWidget() {
}
NativeWidget* CreateNativeWidgetWithContents(View* contents_view) {
- Widget* widget = Widget::CreateWidget();
+ Widget* widget = new Widget;
Widget::InitParams params(Widget::InitParams::TYPE_WINDOW);
params.delete_on_destroy = false;
params.bounds = gfx::Rect(10, 10, 200, 200);
@@ -24,7 +24,7 @@ NativeWidget* CreateNativeWidgetWithContents(View* contents_view) {
}
NativeWidget* CreateNativeWidgetWithParent(NativeWidget* parent) {
- Widget* widget = Widget::CreateWidget();
+ Widget* widget = new Widget;
Widget::InitParams params(Widget::InitParams::TYPE_CONTROL);
params.delete_on_destroy = false;
params.child = false; // Implicitly set to true by ctor with TYPE_CONTROL.
diff --git a/views/widget/tooltip_manager_gtk.cc b/views/widget/tooltip_manager_gtk.cc
index dfc0e39..7c8c0dd 100644
--- a/views/widget/tooltip_manager_gtk.cc
+++ b/views/widget/tooltip_manager_gtk.cc
@@ -85,12 +85,12 @@ bool TooltipManagerGtk::ShowTooltip(int x, int y, bool for_keyboard,
view = keyboard_view_;
view_loc.SetPoint(view->width() / 2, view->height() / 2);
} else if (!for_keyboard) {
- RootView* root_view = widget_->GetRootView();
+ RootView* root_view = widget_->GetWidget()->GetRootView();
view = root_view->GetEventHandlerForPoint(gfx::Point(x, y));
view_loc.SetPoint(x, y);
View::ConvertPointFromWidget(view, &view_loc);
} else {
- FocusManager* focus_manager = widget_->GetFocusManager();
+ FocusManager* focus_manager = widget_->GetWidget()->GetFocusManager();
if (focus_manager) {
view = focus_manager->GetFocusedView();
if (view)
@@ -116,7 +116,7 @@ bool TooltipManagerGtk::ShowTooltip(int x, int y, bool for_keyboard,
int max_width, line_count;
gfx::Point screen_loc(x, y);
- View::ConvertPointToScreen(widget_->GetRootView(), &screen_loc);
+ View::ConvertPointToScreen(widget_->GetWidget()->GetRootView(), &screen_loc);
TrimTooltipToFit(&text, &max_width, &line_count, screen_loc.x(),
screen_loc.y());
tooltip_window_.SetTooltipText(text);
diff --git a/views/widget/widget.cc b/views/widget/widget.cc
index a7c03d9..e02f8f9d 100644
--- a/views/widget/widget.cc
+++ b/views/widget/widget.cc
@@ -9,6 +9,7 @@
#include "ui/gfx/compositor/compositor.h"
#include "views/focus/view_storage.h"
#include "views/ime/input_method.h"
+#include "views/views_delegate.h"
#include "views/widget/default_theme_provider.h"
#include "views/widget/root_view.h"
#include "views/widget/native_widget.h"
@@ -21,6 +22,7 @@ namespace views {
Widget::InitParams::InitParams()
: type(TYPE_WINDOW),
child(false),
+ transient(false),
transparent(false),
accept_events(true),
can_activate(true),
@@ -37,6 +39,7 @@ Widget::InitParams::InitParams()
Widget::InitParams::InitParams(Type type)
: type(type),
child(type == TYPE_CONTROL),
+ transient(type == TYPE_POPUP || type == TYPE_MENU),
transparent(false),
accept_events(true),
can_activate(type != TYPE_POPUP && type != TYPE_MENU),
@@ -63,41 +66,50 @@ Widget::Widget()
last_mouse_event_was_move_(false),
native_widget_(NULL),
widget_delegate_(NULL),
- dragged_view_(NULL) {
+ dragged_view_(NULL),
+ delete_on_destroy_(false),
+ is_secondary_widget_(true) {
}
Widget::~Widget() {
+ DestroyRootView();
+
+ if (!delete_on_destroy_)
+ delete native_widget_;
}
void Widget::Init(const InitParams& params) {
+ delete_on_destroy_ = params.delete_on_destroy;
+ native_widget_ =
+ params.native_widget ? params.native_widget
+ : NativeWidget::CreateNativeWidget(this);
GetRootView();
default_theme_provider_.reset(new DefaultThemeProvider);
+ if (params.type == InitParams::TYPE_MENU)
+ is_mouse_button_pressed_ = native_widget_->IsMouseButtonDown();
native_widget_->InitNativeWidget(params);
}
// Unconverted methods (see header) --------------------------------------------
gfx::NativeView Widget::GetNativeView() const {
- return NULL;
+ return native_widget_->GetNativeView();
}
gfx::NativeWindow Widget::GetNativeWindow() const {
- return NULL;
-}
-
-void Widget::GenerateMousePressedForView(View* view, const gfx::Point& point) {
+ return native_widget_->GetNativeWindow();
}
bool Widget::GetAccelerator(int cmd_id, ui::Accelerator* accelerator) {
return false;
}
-Window* Widget::GetWindow() {
- return NULL;
+Window* Widget::GetContainingWindow() {
+ return native_widget_->GetContainingWindow();
}
-const Window* Widget::GetWindow() const {
- return NULL;
+const Window* Widget::GetContainingWindow() const {
+ return native_widget_->GetContainingWindow();
}
void Widget::ViewHierarchyChanged(bool is_add, View* parent, View* child) {
@@ -108,7 +120,8 @@ void Widget::ViewHierarchyChanged(bool is_add, View* parent, View* child) {
FocusManager* focus_manager = GetFocusManager();
if (focus_manager)
focus_manager->ViewRemoved(child);
- ViewStorage::GetInstance()->ViewRemoved(parent, child);
+ ViewStorage::GetInstance()->ViewRemoved(child);
+ native_widget_->ViewRemoved(child);
}
}
@@ -273,6 +286,10 @@ void Widget::SetCursor(gfx::NativeCursor cursor) {
native_widget_->SetCursor(cursor);
}
+void Widget::ResetLastMouseMoveFlag() {
+ last_mouse_event_was_move_ = false;
+}
+
FocusTraversable* Widget::GetFocusTraversable() {
return root_view_.get();
}
@@ -293,6 +310,18 @@ void Widget::SetFocusTraversableParentView(View* parent_view) {
root_view_->SetFocusTraversableParentView(parent_view);
}
+void Widget::NotifyAccessibilityEvent(
+ View* view,
+ ui::AccessibilityTypes::Event event_type,
+ bool send_native_event) {
+ // Send the notification to the delegate.
+ if (ViewsDelegate::views_delegate)
+ ViewsDelegate::views_delegate->NotifyAccessibilityEvent(view, event_type);
+
+ if (send_native_event)
+ native_widget_->SendNativeAccessibilityEvent(view, event_type);
+}
+
////////////////////////////////////////////////////////////////////////////////
// Widget, NativeWidgetDelegate implementation:
@@ -407,6 +436,14 @@ void Widget::OnMouseCaptureLost() {
is_mouse_button_pressed_ = false;
}
+Widget* Widget::AsWidget() {
+ return this;
+}
+
+const Widget* Widget::AsWidget() const {
+ return this;
+}
+
////////////////////////////////////////////////////////////////////////////////
// Widget, FocusTraversable implementation:
diff --git a/views/widget/widget.h b/views/widget/widget.h
index 110ee20..3c74618 100644
--- a/views/widget/widget.h
+++ b/views/widget/widget.h
@@ -52,12 +52,20 @@ class Window;
// Widget is a platform-independent type that communicates with a platform or
// context specific NativeWidget implementation.
//
-// TODO(beng): Note that this class being non-abstract means that we have a
-// violation of Google style in that we are using multiple
-// inheritance. The intention is to split this into a separate
-// object associated with but not equal to a NativeWidget
-// implementation. Multiple inheritance is required for this
-// transitional step.
+// A special note on ownership:
+//
+// Depending on the value of "delete_on_destroy", the Widget either owns or
+// is owned by its NativeWidget:
+//
+// delete_on_destroy = true (default)
+// The Widget instance is owned by its NativeWidget. When the NativeWidget
+// is destroyed (in response to a native destruction message), it deletes
+// the Widget from its destructor.
+// delete_on_destroy = false (non-default)
+// The Widget instance owns its NativeWidget. This state implies someone
+// else wants to control the lifetime of this object. When they destroy
+// the Widget it is responsible for destroying the NativeWidget (from its
+// destructor).
//
class Widget : public internal::NativeWidgetDelegate,
public FocusTraversable {
@@ -76,6 +84,7 @@ class Widget : public internal::NativeWidgetDelegate,
Type type;
bool child;
+ bool transient;
bool transparent;
bool accept_events;
bool can_activate;
@@ -95,13 +104,14 @@ class Widget : public internal::NativeWidgetDelegate,
Widget();
virtual ~Widget();
- // Creates a Widget instance with the supplied params.
- static Widget* CreateWidget();
-
// Enumerates all windows pertaining to us and notifies their
// view hierarchies that the locale has changed.
static void NotifyLocaleChanged();
+ // Closes all Widgets that aren't identified as "secondary widgets". Called
+ // during application shutdown when the last non-secondary widget is closed.
+ static void CloseAllSecondaryWidgets();
+
// Converts a rectangle from one Widget's coordinate system to another's.
// Returns false if the conversion couldn't be made, because either these two
// Widgets do not have a common ancestor or they are not on the screen yet.
@@ -114,22 +124,15 @@ class Widget : public internal::NativeWidgetDelegate,
// Unconverted methods -------------------------------------------------------
- // TODO(beng):
- // Widget subclasses are still implementing these methods by overriding from
- // here rather than by implementing NativeWidget.
+ // TODO(beng): reorder, they've been converted now.
// Returns the gfx::NativeView associated with this Widget.
- virtual gfx::NativeView GetNativeView() const;
+ gfx::NativeView GetNativeView() const;
// Returns the gfx::NativeWindow associated with this Widget. This may return
// NULL on some platforms if the widget was created with a type other than
// TYPE_WINDOW.
- virtual gfx::NativeWindow GetNativeWindow() const;
-
- // Starts a drag operation for the specified view. |point| is a position in
- // |view| coordinates that the drag was initiated from.
- virtual void GenerateMousePressedForView(View* view,
- const gfx::Point& point);
+ gfx::NativeWindow GetNativeWindow() const;
// Returns the accelerator given a command id. Returns false if there is
// no accelerator associated with a given id, which is a common condition.
@@ -137,15 +140,15 @@ class Widget : public internal::NativeWidgetDelegate,
// Returns the Window containing this Widget, or NULL if not contained in a
// window.
- virtual Window* GetWindow();
- virtual const Window* GetWindow() const;
+ Window* GetContainingWindow();
+ const Window* GetContainingWindow() const;
// Forwarded from the RootView so that the widget can do any cleanup.
- virtual void ViewHierarchyChanged(bool is_add, View* parent, View* child);
+ void ViewHierarchyChanged(bool is_add, View* parent, View* child);
// Performs any necessary cleanup and forwards to RootView.
- virtual void NotifyNativeViewHierarchyChanged(bool attached,
- gfx::NativeView native_view);
+ void NotifyNativeViewHierarchyChanged(bool attached,
+ gfx::NativeView native_view);
// Converted methods ---------------------------------------------------------
@@ -188,7 +191,7 @@ class Widget : public internal::NativeWidgetDelegate,
void SetShape(gfx::NativeRegion shape);
// Hides the widget then closes it after a return to the message loop.
- void Close();
+ virtual void Close();
// TODO(beng): Move off public API.
// Closes the widget immediately. Compare to |Close|. This will destroy the
@@ -212,6 +215,16 @@ class Widget : public internal::NativeWidgetDelegate,
// Returns the RootView contained by this Widget.
RootView* GetRootView();
+ // A secondary widget is one that is automatically closed (via Close()) when
+ // all non-secondary widgets are closed.
+ // Default is true.
+ // TODO(beng): This is an ugly API, should be handled implicitly via
+ // transience.
+ void set_is_secondary_widget(bool is_secondary_widget) {
+ is_secondary_widget_ = is_secondary_widget;
+ }
+ bool is_secondary_widget() const { return is_secondary_widget_; }
+
// Returns whether the Widget is visible to the user.
bool IsVisible() const;
@@ -257,6 +270,12 @@ class Widget : public internal::NativeWidgetDelegate,
// before the current is restored.
void SetCursor(gfx::NativeCursor cursor);
+ // Resets the last move flag so that we can go around the optimization
+ // that disregards duplicate mouse moves when ending animation requires
+ // a new hit-test to do some highlighting as in TabStrip::RemoveTabAnimation
+ // to cause the close button to highlight.
+ void ResetLastMouseMoveFlag();
+
// Retrieves the focus traversable for this widget.
FocusTraversable* GetFocusTraversable();
@@ -280,10 +299,10 @@ class Widget : public internal::NativeWidgetDelegate,
// cases where the view is a native control that's already sending a
// native accessibility event and the duplicate event would cause
// problems.
- virtual void NotifyAccessibilityEvent(
+ void NotifyAccessibilityEvent(
View* view,
ui::AccessibilityTypes::Event event_type,
- bool send_native_event) = 0;
+ bool send_native_event);
NativeWidget* native_widget() { return native_widget_; }
@@ -299,6 +318,8 @@ class Widget : public internal::NativeWidgetDelegate,
virtual bool OnKeyEvent(const KeyEvent& event) OVERRIDE;
virtual bool OnMouseEvent(const MouseEvent& event) OVERRIDE;
virtual void OnMouseCaptureLost() OVERRIDE;
+ virtual Widget* AsWidget() OVERRIDE;
+ virtual const Widget* AsWidget() const OVERRIDE;
// Overridden from FocusTraversable:
virtual FocusSearch* GetFocusSearch() OVERRIDE;
@@ -306,6 +327,9 @@ class Widget : public internal::NativeWidgetDelegate,
virtual View* GetFocusTraversableParentView() OVERRIDE;
protected:
+ // TODO(beng): Remove WidgetGtk's dependence on the mouse state flags.
+ friend class WidgetGtk;
+
// Creates the RootView to be used within this Widget. Subclasses may override
// to create custom RootViews that do specialized event processing.
// TODO(beng): Investigate whether or not this is needed.
@@ -316,19 +340,15 @@ class Widget : public internal::NativeWidgetDelegate,
// TODO(beng): remove once we fold those objects onto this one.
void DestroyRootView();
- // TODO(beng): Temporarily provided as a way to associate the subclass'
- // implementation of NativeWidget with this.
- void set_native_widget(NativeWidget* native_widget) {
- native_widget_ = native_widget;
- }
-
// Used for testing.
void ReplaceFocusManager(FocusManager* focus_manager);
+ // TODO(beng): Remove WidgetGtk's dependence on these:
// TODO(msw): Make this mouse state member private.
// If true, the mouse is currently down.
bool is_mouse_button_pressed_;
+ // TODO(beng): Remove WidgetGtk's dependence on these:
// TODO(msw): Make these mouse state members private.
// The following are used to detect duplicate mouse move events and not
// deliver them. Displaying a window may result in the system generating
@@ -370,6 +390,12 @@ class Widget : public internal::NativeWidgetDelegate,
// The compositor for accelerated drawing.
scoped_refptr<ui::Compositor> compositor_;
+ // See class documentation for Widget above for a note about ownership.
+ bool delete_on_destroy_;
+
+ // See set_is_secondary_widget().
+ bool is_secondary_widget_;
+
DISALLOW_COPY_AND_ASSIGN(Widget);
};
diff --git a/views/widget/widget_gtk.cc b/views/widget/widget_gtk.cc
index b506dac..bbb0fd5 100644
--- a/views/widget/widget_gtk.cc
+++ b/views/widget/widget_gtk.cc
@@ -284,9 +284,9 @@ bool WidgetGtk::debug_paint_enabled_ = false;
////////////////////////////////////////////////////////////////////////////////
// WidgetGtk, public:
-WidgetGtk::WidgetGtk()
+WidgetGtk::WidgetGtk(internal::NativeWidgetDelegate* delegate)
: is_window_(false),
- ALLOW_THIS_IN_INITIALIZER_LIST(delegate_(this)),
+ delegate_(delegate),
widget_(NULL),
window_contents_(NULL),
child_(false),
@@ -301,6 +301,7 @@ WidgetGtk::WidgetGtk()
transient_to_parent_(false),
got_initial_focus_in_(false),
has_focus_(false),
+ focus_on_creation_(true),
always_on_top_(false),
is_double_buffered_(false),
should_handle_menu_key_release_(false),
@@ -311,7 +312,6 @@ WidgetGtk::WidgetGtk()
// the widget.
TouchFactory::GetInstance();
#endif
- set_native_widget(this);
static bool installed_message_loop_observer = false;
if (!installed_message_loop_observer) {
installed_message_loop_observer = true;
@@ -325,8 +325,9 @@ WidgetGtk::~WidgetGtk() {
// We need to delete the input method before calling DestroyRootView(),
// because it'll set focus_manager_ to NULL.
input_method_.reset();
- DestroyRootView();
DCHECK(delete_on_destroy_ || widget_ == NULL);
+ if (delete_on_destroy_)
+ delete delegate_;
}
GtkWindow* WidgetGtk::GetTransientParent() const {
@@ -443,7 +444,7 @@ void WidgetGtk::DoDrag(const OSExchangeData& data, int operation) {
}
void WidgetGtk::IsActiveChanged() {
- WidgetDelegate* d = widget_delegate();
+ WidgetDelegate* d = GetWidget()->widget_delegate();
if (d) {
bool a = IsActive();
d->OnWidgetActivated(a);
@@ -451,8 +452,11 @@ void WidgetGtk::IsActiveChanged() {
}
void WidgetGtk::SetInitialFocus() {
- View* v = widget_delegate() ?
- widget_delegate()->GetInitiallyFocusedView() : NULL;
+ if (!focus_on_creation_)
+ return;
+
+ View* v = GetWidget()->widget_delegate() ?
+ GetWidget()->widget_delegate()->GetInitiallyFocusedView() : NULL;
if (v)
v->RequestFocus();
}
@@ -496,52 +500,13 @@ void WidgetGtk::ActiveWindowChanged(GdkWindow* active_window) {
}
if (was_active != IsActive()) {
IsActiveChanged();
- GetRootView()->SchedulePaint();
+ GetWidget()->GetRootView()->SchedulePaint();
}
}
////////////////////////////////////////////////////////////////////////////////
// WidgetGtk, Widget implementation:
-gfx::NativeView WidgetGtk::GetNativeView() const {
- return widget_;
-}
-
-gfx::NativeWindow WidgetGtk::GetNativeWindow() const {
- return child_ ? NULL : GTK_WINDOW(widget_);
-}
-
-bool WidgetGtk::GetAccelerator(int cmd_id, ui::Accelerator* accelerator) {
- NOTIMPLEMENTED();
- return false;
-}
-
-Window* WidgetGtk::GetWindow() {
- return GetWindowImpl(widget_);
-}
-
-const Window* WidgetGtk::GetWindow() const {
- return GetWindowImpl(widget_);
-}
-
-void WidgetGtk::ViewHierarchyChanged(bool is_add, View* parent, View* child) {
- Widget::ViewHierarchyChanged(is_add, parent, child);
- if (drop_target_.get())
- drop_target_->ResetTargetViewIfEquals(child);
-}
-
-void WidgetGtk::NotifyAccessibilityEvent(
- View* view,
- ui::AccessibilityTypes::Event event_type,
- bool send_native_event) {
- // Send the notification to the delegate.
- if (ViewsDelegate::views_delegate)
- ViewsDelegate::views_delegate->NotifyAccessibilityEvent(view, event_type);
-
- // In the future if we add native GTK accessibility support, the
- // notification should be sent here.
-}
-
void WidgetGtk::ClearNativeFocus() {
DCHECK(!child_);
if (!GetNativeView()) {
@@ -552,7 +517,7 @@ void WidgetGtk::ClearNativeFocus() {
}
bool WidgetGtk::HandleKeyboardEvent(const KeyEvent& key) {
- if (!GetFocusManager())
+ if (!GetWidget()->GetFocusManager())
return false;
const int key_code = key.key_code();
@@ -569,7 +534,7 @@ bool WidgetGtk::HandleKeyboardEvent(const KeyEvent& key) {
// VKEY_MENU is triggered by key release event.
// FocusManager::OnKeyEvent() returns false when the key has been consumed.
if (key_code != ui::VKEY_MENU)
- handled = !GetFocusManager()->OnKeyEvent(key);
+ handled = !GetWidget()->GetFocusManager()->OnKeyEvent(key);
else
should_handle_menu_key_release_ = true;
} else if (key_code == ui::VKEY_MENU && should_handle_menu_key_release_ &&
@@ -577,7 +542,7 @@ bool WidgetGtk::HandleKeyboardEvent(const KeyEvent& key) {
// Trigger VKEY_MENU when only this key is pressed and released, and both
// press and release events are not handled by others.
Accelerator accelerator(ui::VKEY_MENU, false, false, false);
- handled = GetFocusManager()->ProcessAccelerator(accelerator);
+ handled = GetWidget()->GetFocusManager()->ProcessAccelerator(accelerator);
}
return handled;
@@ -626,10 +591,10 @@ void WidgetGtk::RegisterChildExposeHandler(GtkWidget* child) {
////////////////////////////////////////////////////////////////////////////////
// WidgetGtk, NativeWidget implementation:
-void WidgetGtk::InitNativeWidget(const InitParams& params) {
+void WidgetGtk::InitNativeWidget(const Widget::InitParams& params) {
SetInitParams(params);
- InitParams modified_params = params;
+ Widget::InitParams modified_params = params;
gfx::NativeView parent = params.parent;
if (params.parent_widget) {
WidgetGtk* parent_gtk =
@@ -766,7 +731,32 @@ void WidgetGtk::InitNativeWidget(const InitParams& params) {
}
Widget* WidgetGtk::GetWidget() {
- return this;
+ return delegate_->AsWidget();
+}
+
+const Widget* WidgetGtk::GetWidget() const {
+ return delegate_->AsWidget();
+}
+
+gfx::NativeView WidgetGtk::GetNativeView() const {
+ return widget_;
+}
+
+gfx::NativeWindow WidgetGtk::GetNativeWindow() const {
+ return child_ ? NULL : GTK_WINDOW(widget_);
+}
+
+Window* WidgetGtk::GetContainingWindow() {
+ return GetWindowImpl(widget_);
+}
+
+const Window* WidgetGtk::GetContainingWindow() const {
+ return GetWindowImpl(widget_);
+}
+
+void WidgetGtk::ViewRemoved(View* view) {
+ if (drop_target_.get())
+ drop_target_->ResetTargetViewIfEquals(view);
}
void WidgetGtk::SetNativeWindowProperty(const char* name, void* value) {
@@ -785,6 +775,13 @@ bool WidgetGtk::IsScreenReaderActive() const {
return false;
}
+void WidgetGtk::SendNativeAccessibilityEvent(
+ View* view,
+ ui::AccessibilityTypes::Event event_type) {
+ // In the future if we add native GTK accessibility support, the
+ // notification should be sent here.
+}
+
void WidgetGtk::SetMouseCapture() {
DCHECK(!HasMouseCapture());
gtk_grab_add(window_contents_);
@@ -801,6 +798,18 @@ bool WidgetGtk::HasMouseCapture() const {
return GTK_WIDGET_HAS_GRAB(window_contents_);
}
+bool WidgetGtk::IsMouseButtonDown() const {
+ bool button_pressed = false;
+ GdkEvent* event = gtk_get_current_event();
+ if (event) {
+ button_pressed = event->type == GDK_BUTTON_PRESS ||
+ event->type == GDK_2BUTTON_PRESS ||
+ event->type == GDK_3BUTTON_PRESS;
+ gdk_event_free(event);
+ }
+ return button_pressed;
+}
+
InputMethod* WidgetGtk::GetInputMethodNative() {
return input_method_.get();
}
@@ -1018,7 +1027,7 @@ void WidgetGtk::OnSizeRequest(GtkWidget* widget, GtkRequisition* requisition) {
// preferred size for these would prevents us from setting smaller window
// sizes.
if (child_) {
- gfx::Size size(GetRootView()->GetPreferredSize());
+ gfx::Size size(GetWidget()->GetRootView()->GetPreferredSize());
requisition->width = size.width();
requisition->height = size.height();
}
@@ -1153,7 +1162,7 @@ gboolean WidgetGtk::OnDragMotion(GtkWidget* widget,
gint y,
guint time) {
if (!drop_target_.get())
- drop_target_.reset(new DropTargetGtk(GetRootView(), context));
+ drop_target_.reset(new DropTargetGtk(GetWidget()->GetRootView(), context));
return drop_target_->OnDragMotion(context, x, y, time);
}
@@ -1164,7 +1173,8 @@ gboolean WidgetGtk::OnEnterNotify(GtkWidget* widget, GdkEventCrossing* event) {
return false;
}
- if (!last_mouse_event_was_move_ && !is_mouse_button_pressed_) {
+ if (!GetWidget()->last_mouse_event_was_move_ &&
+ !GetWidget()->is_mouse_button_pressed_) {
// When a mouse button is pressed gtk generates a leave, enter, press.
// RootView expects to get a mouse move before a press, otherwise enter is
// not set. So we generate a move here.
@@ -1180,13 +1190,13 @@ gboolean WidgetGtk::OnEnterNotify(GtkWidget* widget, GdkEventCrossing* event) {
MouseEvent mouse_event(TransformEvent(&motion));
delegate_->OnMouseEvent(mouse_event);
}
-
return false;
}
gboolean WidgetGtk::OnLeaveNotify(GtkWidget* widget, GdkEventCrossing* event) {
- last_mouse_event_was_move_ = false;
- if (!HasMouseCapture() && !is_mouse_button_pressed_) {
+ GetWidget()->ResetLastMouseMoveFlag();
+
+ if (!HasMouseCapture() && !GetWidget()->is_mouse_button_pressed_) {
MouseEvent mouse_event(TransformEvent(event));
delegate_->OnMouseEvent(mouse_event);
}
@@ -1346,10 +1356,6 @@ void WidgetGtk::HandleGtkGrabBroke() {
////////////////////////////////////////////////////////////////////////////////
// WidgetGtk, private:
-RootView* WidgetGtk::CreateRootView() {
- return new RootView(this);
-}
-
gfx::AcceleratedWidget WidgetGtk::GetAcceleratedWidget() {
DCHECK(window_contents_ && window_contents_->window);
return GDK_WINDOW_XID(window_contents_->window);
@@ -1392,28 +1398,24 @@ void WidgetGtk::DispatchKeyEventPostIME(const KeyEvent& key) {
gtk_bindings_activate_event(GTK_OBJECT(widget_), event);
}
-void WidgetGtk::SetInitParams(const InitParams& params) {
+void WidgetGtk::SetInitParams(const Widget::InitParams& params) {
DCHECK(!GetNativeView());
delete_on_destroy_ = params.delete_on_destroy;
child_ = params.child;
+ // TODO(beng): The secondary checks here actually obviate the need for
+ // params.transient but that's only because WidgetGtk considers
+ // any top-level widget to be a transient widget. We will probably
+ // want to ammend this assumption at some point.
+ if (params.transient || params.parent || params.parent_widget)
+ transient_to_parent_ = true;
if (params.transparent)
MakeTransparent();
if (!params.accept_events && !child_)
ignore_events_ = true;
if (params.double_buffer)
EnableDoubleBuffer(true);
-
- if (params.type == InitParams::TYPE_MENU) {
- GdkEvent* event = gtk_get_current_event();
- if (event) {
- is_mouse_button_pressed_ = event->type == GDK_BUTTON_PRESS ||
- event->type == GDK_2BUTTON_PRESS ||
- event->type == GDK_3BUTTON_PRESS;
- gdk_event_free(event);
- }
- }
}
gboolean WidgetGtk::OnWindowPaint(GtkWidget* widget, GdkEventExpose* event) {
@@ -1460,13 +1462,13 @@ Window* WidgetGtk::GetWindowImpl(GtkWidget* widget) {
WidgetGtk* widget_gtk = static_cast<WidgetGtk*>(
NativeWidget::GetNativeWidgetForNativeView(parent));
if (widget_gtk && widget_gtk->is_window_)
- return static_cast<WindowGtk*>(widget_gtk);
+ return static_cast<WindowGtk*>(widget_gtk)->GetWindow();
parent = gtk_widget_get_parent(parent);
}
return NULL;
}
-void WidgetGtk::CreateGtkWidget(const InitParams& params) {
+void WidgetGtk::CreateGtkWidget(const Widget::InitParams& params) {
// We turn off double buffering for two reasons:
// 1. We draw to a canvas then composite to the screen, which means we're
// doing our own double buffering already.
@@ -1520,8 +1522,8 @@ void WidgetGtk::CreateGtkWidget(const InitParams& params) {
} else {
// Use our own window class to override GtkWindow's move_focus method.
widget_ = gtk_views_window_new(
- params.type == InitParams::TYPE_WINDOW ? GTK_WINDOW_TOPLEVEL
- : GTK_WINDOW_POPUP);
+ params.type == Widget::InitParams::TYPE_WINDOW ? GTK_WINDOW_TOPLEVEL
+ : GTK_WINDOW_POPUP);
gtk_widget_set_name(widget_, "views-gtkwidget-window");
if (transient_to_parent_) {
gtk_window_set_transient_for(GTK_WINDOW(widget_),
@@ -1560,7 +1562,7 @@ void WidgetGtk::CreateGtkWidget(const InitParams& params) {
gtk_container_add(GTK_CONTAINER(widget_), window_contents_);
gtk_widget_show(window_contents_);
g_object_set_data(G_OBJECT(window_contents_), kNativeWidgetKey,
- static_cast<Widget*>(this));
+ static_cast<WidgetGtk*>(this));
if (transparent_)
ConfigureWidgetForTransparentBackground(NULL);
@@ -1643,11 +1645,6 @@ void WidgetGtk::DrawTransparentBackground(GtkWidget* widget,
// Widget, public:
// static
-Widget* Widget::CreateWidget() {
- return new WidgetGtk();
-}
-
-// static
void Widget::NotifyLocaleChanged() {
GList *window_list = gtk_window_list_toplevels();
for (GList* element = window_list; element; element = g_list_next(element)) {
@@ -1660,6 +1657,22 @@ void Widget::NotifyLocaleChanged() {
}
// static
+void Widget::CloseAllSecondaryWidgets() {
+ GList* windows = gtk_window_list_toplevels();
+ for (GList* window = windows; window;
+ window = g_list_next(window)) {
+ NativeWidget* native_widget = NativeWidget::GetNativeWidgetForNativeView(
+ GTK_WIDGET(window->data));
+ if (native_widget) {
+ Widget* widget = native_widget->GetWidget();
+ if (widget->is_secondary_widget())
+ widget->Close();
+ }
+ }
+ g_list_free(windows);
+}
+
+// static
bool Widget::ConvertRect(const Widget* source,
const Widget* target,
gfx::Rect* rect) {
@@ -1689,6 +1702,12 @@ bool Widget::ConvertRect(const Widget* source,
// NativeWidget, public:
// static
+NativeWidget* NativeWidget::CreateNativeWidget(
+ internal::NativeWidgetDelegate* delegate) {
+ return new WidgetGtk(delegate);
+}
+
+// static
NativeWidget* NativeWidget::GetNativeWidgetForNativeView(
gfx::NativeView native_view) {
if (!native_view)
@@ -1740,4 +1759,40 @@ void NativeWidget::GetAllNativeWidgets(gfx::NativeView native_view,
reinterpret_cast<gpointer>(children));
}
+// static
+void NativeWidget::ReparentNativeView(gfx::NativeView native_view,
+ gfx::NativeView new_parent) {
+ if (!native_view)
+ return;
+
+ gfx::NativeView previous_parent = gtk_widget_get_parent(native_view);
+ if (previous_parent == new_parent)
+ return;
+
+ NativeWidgets widgets;
+ GetAllNativeWidgets(native_view, &widgets);
+
+ // First notify all the widgets that they are being disassociated
+ // from their previous parent.
+ for (NativeWidgets::iterator it = widgets.begin();
+ it != widgets.end(); ++it) {
+ // TODO(beng): Rename this notification to NotifyNativeViewChanging()
+ // and eliminate the bool parameter.
+ (*it)->GetWidget()->NotifyNativeViewHierarchyChanged(false,
+ previous_parent);
+ }
+
+ if (gtk_widget_get_parent(native_view))
+ gtk_widget_reparent(native_view, new_parent);
+ else
+ gtk_container_add(GTK_CONTAINER(new_parent), native_view);
+
+ // And now, notify them that they have a brand new parent.
+ for (NativeWidgets::iterator it = widgets.begin();
+ it != widgets.end(); ++it) {
+ (*it)->GetWidget()->NotifyNativeViewHierarchyChanged(true,
+ new_parent);
+ }
+}
+
} // namespace views
diff --git a/views/widget/widget_gtk.h b/views/widget/widget_gtk.h
index eaa29cd..54acfa6 100644
--- a/views/widget/widget_gtk.h
+++ b/views/widget/widget_gtk.h
@@ -41,25 +41,13 @@ class NativeWidgetDelegate;
}
// Widget implementation for GTK.
-class WidgetGtk : public Widget,
- public NativeWidget,
+class WidgetGtk : public NativeWidget,
public ui::ActiveWindowWatcherX::Observer,
public internal::InputMethodDelegate {
public:
- WidgetGtk();
+ explicit WidgetGtk(internal::NativeWidgetDelegate* delegate);
virtual ~WidgetGtk();
- // Marks this window as transient to its parent. A window that is transient
- // to its parent results in the parent rendering active when the child is
- // active.
- // This must be invoked before Init. This is only used for types other than
- // TYPE_CHILD. The default is false.
- // See gtk_window_set_transient_for for details.
- void make_transient_to_parent() {
- DCHECK(!widget_);
- transient_to_parent_ = true;
- }
-
// Returns the transient parent. See make_transient_to_parent for details on
// what the transient parent is.
GtkWindow* GetTransientParent() const;
@@ -123,19 +111,6 @@ class WidgetGtk : public Widget,
// Overridden from ui::ActiveWindowWatcherX::Observer.
virtual void ActiveWindowChanged(GdkWindow* active_window);
- // Overridden from Widget:
- virtual gfx::NativeView GetNativeView() const;
- virtual gfx::NativeWindow GetNativeWindow() const;
- virtual bool GetAccelerator(int cmd_id, ui::Accelerator* accelerator);
- virtual Window* GetWindow();
- virtual const Window* GetWindow() const;
- virtual void ViewHierarchyChanged(bool is_add, View *parent,
- View *child);
- virtual void NotifyAccessibilityEvent(
- View* view,
- ui::AccessibilityTypes::Event event_type,
- bool send_native_event);
-
// Clears the focus on the native widget having the focus.
virtual void ClearNativeFocus();
@@ -168,16 +143,30 @@ class WidgetGtk : public Widget,
// detached widget.
static void RegisterChildExposeHandler(GtkWidget* widget);
+ void set_focus_on_creation(bool focus_on_creation) {
+ focus_on_creation_ = focus_on_creation;
+ }
+
// Overridden from NativeWidget:
- virtual void InitNativeWidget(const InitParams& params) OVERRIDE;
+ virtual void InitNativeWidget(const Widget::InitParams& params) OVERRIDE;
virtual Widget* GetWidget() OVERRIDE;
+ virtual const Widget* GetWidget() const OVERRIDE;
+ virtual gfx::NativeView GetNativeView() const OVERRIDE;
+ virtual gfx::NativeWindow GetNativeWindow() const OVERRIDE;
+ virtual Window* GetContainingWindow() OVERRIDE;
+ virtual const Window* GetContainingWindow() const OVERRIDE;
+ virtual void ViewRemoved(View* view) OVERRIDE;
virtual void SetNativeWindowProperty(const char* name, void* value) OVERRIDE;
virtual void* GetNativeWindowProperty(const char* name) OVERRIDE;
virtual TooltipManager* GetTooltipManager() const OVERRIDE;
virtual bool IsScreenReaderActive() const OVERRIDE;
+ virtual void SendNativeAccessibilityEvent(
+ View* view,
+ ui::AccessibilityTypes::Event event_type) OVERRIDE;
virtual void SetMouseCapture() OVERRIDE;
virtual void ReleaseMouseCapture() OVERRIDE;
virtual bool HasMouseCapture() const OVERRIDE;
+ virtual bool IsMouseButtonDown() const OVERRIDE;
virtual InputMethod* GetInputMethodNative() OVERRIDE;
virtual void ReplaceInputMethod(InputMethod* input_method) OVERRIDE;
virtual gfx::Rect GetWindowScreenBounds() const OVERRIDE;
@@ -268,16 +257,13 @@ class WidgetGtk : public Widget,
class DropObserver;
friend class DropObserver;
- // Overridden from Widget
- virtual RootView* CreateRootView() OVERRIDE;
-
// Overridden from NativeWidget
virtual gfx::AcceleratedWidget GetAcceleratedWidget() OVERRIDE;
// Overridden from internal::InputMethodDelegate
virtual void DispatchKeyEventPostIME(const KeyEvent& key) OVERRIDE;
- void SetInitParams(const InitParams& params);
+ void SetInitParams(const Widget::InitParams& params);
// This is called only when the window is transparent.
CHROMEGTK_CALLBACK_1(WidgetGtk, gboolean, OnWindowPaint, GdkEventExpose*);
@@ -291,7 +277,7 @@ class WidgetGtk : public Widget,
static Window* GetWindowImpl(GtkWidget* widget);
// Creates the GtkWidget.
- void CreateGtkWidget(const InitParams& params);
+ void CreateGtkWidget(const Widget::InitParams& params);
// Invoked from create widget to enable the various bits needed for a
// transparent background. This is only invoked if MakeTransparent has been
@@ -307,6 +293,7 @@ class WidgetGtk : public Widget,
GdkEventExpose* event);
// A delegate implementation that handles events received here.
+ // See class documentation for Widget in widget.h for a note about ownership.
internal::NativeWidgetDelegate* delegate_;
// Our native views. If we're a window/popup, then widget_ is the window and
@@ -333,7 +320,7 @@ class WidgetGtk : public Widget,
// The following factory is used to delay destruction.
ScopedRunnableMethodFactory<WidgetGtk> close_widget_factory_;
- // See description above setter.
+ // See class documentation for Widget in widget.h for a note about ownership.
bool delete_on_destroy_;
// See description above make_transparent for details.
@@ -385,6 +372,10 @@ class WidgetGtk : public Widget,
// this to determine whether we should process the event.
bool has_focus_;
+ // Whether we should SetFocus() on a newly created window after
+ // Init(). Defaults to true.
+ bool focus_on_creation_;
+
// If true, the window stays on top of the screen. This is only used
// for types other than TYPE_CHILD.
bool always_on_top_;
diff --git a/views/widget/widget_win.cc b/views/widget/widget_win.cc
index a5d2044..67166ff 100644
--- a/views/widget/widget_win.cc
+++ b/views/widget/widget_win.cc
@@ -132,8 +132,8 @@ bool WidgetWin::screen_reader_active_ = false;
////////////////////////////////////////////////////////////////////////////////
// WidgetWin, public:
-WidgetWin::WidgetWin()
- : ALLOW_THIS_IN_INITIALIZER_LIST(delegate_(this)),
+WidgetWin::WidgetWin(internal::NativeWidgetDelegate* delegate)
+ : delegate_(delegate),
close_widget_factory_(this),
active_mouse_tracking_flags_(0),
use_layered_buffer_(false),
@@ -147,14 +147,14 @@ WidgetWin::WidgetWin()
accessibility_view_events_(kMaxAccessibilityViewEvents),
previous_cursor_(NULL),
is_input_method_win_(false) {
- set_native_widget(this);
}
WidgetWin::~WidgetWin() {
// We need to delete the input method before calling DestroyRootView(),
// because it'll set focus_manager_ to NULL.
input_method_.reset();
- DestroyRootView();
+ if (delete_on_destroy_)
+ delete delegate_;
}
// static
@@ -192,7 +192,24 @@ void WidgetWin::ClearAccessibilityViewEvent(View* view) {
}
////////////////////////////////////////////////////////////////////////////////
-// WidgetWin, Widget implementation:
+// WidgetWin, NativeWidget implementation:
+
+void WidgetWin::InitNativeWidget(const Widget::InitParams& params) {
+ SetInitParams(params);
+
+ // Create the window.
+ gfx::NativeView parent = params.parent_widget ?
+ params.parent_widget->GetNativeView() : params.parent;
+ WindowImpl::Init(parent, params.bounds);
+}
+
+Widget* WidgetWin::GetWidget() {
+ return delegate_->AsWidget();
+}
+
+const Widget* WidgetWin::GetWidget() const {
+ return delegate_->AsWidget();
+}
gfx::NativeView WidgetWin::GetNativeView() const {
return WindowImpl::hwnd();
@@ -202,42 +219,19 @@ gfx::NativeWindow WidgetWin::GetNativeWindow() const {
return WindowImpl::hwnd();
}
-bool WidgetWin::GetAccelerator(int cmd_id, ui::Accelerator* accelerator) {
- return false;
-}
-
-Window* WidgetWin::GetWindow() {
+Window* WidgetWin::GetContainingWindow() {
return GetWindowImpl(hwnd());
}
-const Window* WidgetWin::GetWindow() const {
+const Window* WidgetWin::GetContainingWindow() const {
return GetWindowImpl(hwnd());
}
-void WidgetWin::ViewHierarchyChanged(bool is_add, View* parent,
- View* child) {
- Widget::ViewHierarchyChanged(is_add, parent, child);
+void WidgetWin::ViewRemoved(View* view) {
if (drop_target_.get())
- drop_target_->ResetTargetViewIfEquals(child);
+ drop_target_->ResetTargetViewIfEquals(view);
- if (!is_add)
- ClearAccessibilityViewEvent(child);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// WidgetWin, NativeWidget implementation:
-
-void WidgetWin::InitNativeWidget(const Widget::InitParams& params) {
- SetInitParams(params);
-
- // Create the window.
- gfx::NativeView parent = params.parent_widget ?
- params.parent_widget->GetNativeView() : params.parent;
- WindowImpl::Init(parent, params.bounds);
-}
-
-Widget* WidgetWin::GetWidget() {
- return this;
+ ClearAccessibilityViewEvent(view);
}
void WidgetWin::SetNativeWindowProperty(const char* name, void* value) {
@@ -265,6 +259,19 @@ bool WidgetWin::IsScreenReaderActive() const {
return screen_reader_active_;
}
+void WidgetWin::SendNativeAccessibilityEvent(
+ View* view,
+ ui::AccessibilityTypes::Event event_type) {
+ // Now call the Windows-specific method to notify MSAA clients of this
+ // event. The widget gives us a temporary unique child ID to associate
+ // with this view so that clients can call get_accChild in
+ // NativeViewAccessibilityWin to retrieve the IAccessible associated
+ // with this view.
+ int child_id = AddAccessibilityViewEvent(view);
+ ::NotifyWinEvent(NativeViewAccessibilityWin::MSAAEvent(event_type),
+ GetNativeView(), OBJID_CLIENT, child_id);
+}
+
void WidgetWin::SetMouseCapture() {
DCHECK(!HasMouseCapture());
SetCapture(hwnd());
@@ -278,6 +285,14 @@ bool WidgetWin::HasMouseCapture() const {
return GetCapture() == hwnd();
}
+bool WidgetWin::IsMouseButtonDown() const {
+ return (GetKeyState(VK_LBUTTON) & 0x80) ||
+ (GetKeyState(VK_RBUTTON) & 0x80) ||
+ (GetKeyState(VK_MBUTTON) & 0x80) ||
+ (GetKeyState(VK_XBUTTON1) & 0x80) ||
+ (GetKeyState(VK_XBUTTON2) & 0x80);
+}
+
InputMethod* WidgetWin::GetInputMethodNative() {
return input_method_.get();
}
@@ -447,26 +462,6 @@ void WidgetWin::SetCursor(gfx::NativeCursor cursor) {
}
}
-void WidgetWin::NotifyAccessibilityEvent(
- View* view,
- ui::AccessibilityTypes::Event event_type,
- bool send_native_event) {
- // Send the notification to the delegate.
- if (ViewsDelegate::views_delegate)
- ViewsDelegate::views_delegate->NotifyAccessibilityEvent(view, event_type);
-
- // Now call the Windows-specific method to notify MSAA clients of this
- // event. The widget gives us a temporary unique child ID to associate
- // with this view so that clients can call get_accChild in
- // NativeViewAccessibilityWin to retrieve the IAccessible associated
- // with this view.
- if (send_native_event) {
- int child_id = AddAccessibilityViewEvent(view);
- ::NotifyWinEvent(NativeViewAccessibilityWin::MSAAEvent(event_type),
- GetNativeView(), OBJID_CLIENT, child_id);
- }
-}
-
////////////////////////////////////////////////////////////////////////////////
// WidgetWin, MessageLoop::Observer implementation:
@@ -507,7 +502,7 @@ LRESULT WidgetWin::OnWndProc(UINT message, WPARAM w_param, LPARAM l_param) {
PostProcessActivateMessage(this, LOWORD(w_param));
if (message == WM_ENABLE && restore_focus_when_enabled_) {
restore_focus_when_enabled_ = false;
- GetFocusManager()->RestoreFocusedView();
+ GetWidget()->GetFocusManager()->RestoreFocusedView();
}
return result;
}
@@ -558,7 +553,7 @@ LRESULT WidgetWin::OnCreate(CREATESTRUCT* create_struct) {
props_.push_back(SetWindowSupportsRerouteMouseWheel(hwnd()));
- drop_target_ = new DropTargetWin(GetRootView());
+ drop_target_ = new DropTargetWin(GetWidget()->GetRootView());
// We need to add ourselves as a message loop observer so that we can repaint
// aggressively if the contents of our window become invalid. Unfortunately
@@ -569,10 +564,10 @@ LRESULT WidgetWin::OnCreate(CREATESTRUCT* create_struct) {
// Windows special DWM window frame requires a special tooltip manager so
// that window controls in Chrome windows don't flicker when you move your
// mouse over them. See comment in aero_tooltip_manager.h.
- if (GetThemeProvider()->ShouldUseNativeFrame()) {
- tooltip_manager_.reset(new AeroTooltipManager(this));
+ if (GetWidget()->GetThemeProvider()->ShouldUseNativeFrame()) {
+ tooltip_manager_.reset(new AeroTooltipManager(GetWidget()));
} else {
- tooltip_manager_.reset(new TooltipManagerWin(this));
+ tooltip_manager_.reset(new TooltipManagerWin(GetWidget()));
}
// This message initializes the window so that focus border are shown for
@@ -612,8 +607,8 @@ void WidgetWin::OnDestroy() {
}
void WidgetWin::OnDisplayChange(UINT bits_per_pixel, CSize screen_size) {
- if (widget_delegate())
- widget_delegate()->OnDisplayChanged();
+ if (GetWidget()->widget_delegate())
+ GetWidget()->widget_delegate()->OnDisplayChanged();
}
LRESULT WidgetWin::OnDwmCompositionChanged(UINT msg,
@@ -651,7 +646,8 @@ LRESULT WidgetWin::OnGetObject(UINT uMsg, WPARAM w_param, LPARAM l_param) {
if (OBJID_CLIENT == l_param) {
// Retrieve MSAA dispatch object for the root view.
base::win::ScopedComPtr<IAccessible> root(
- NativeViewAccessibilityWin::GetAccessibleForView(GetRootView()));
+ NativeViewAccessibilityWin::GetAccessibleForView(
+ GetWidget()->GetRootView()));
// Create a reference that MSAA will marshall to the client.
reference_result = LresultFromObject(IID_IAccessible, w_param,
@@ -789,14 +785,16 @@ LRESULT WidgetWin::OnMouseRange(UINT message, WPARAM w_param, LPARAM l_param) {
}
void WidgetWin::OnMove(const CPoint& point) {
- if (widget_delegate())
- widget_delegate()->OnWidgetMove();
+ // TODO(beng): move to Widget.
+ if (GetWidget()->widget_delegate())
+ GetWidget()->widget_delegate()->OnWidgetMove();
SetMsgHandled(FALSE);
}
void WidgetWin::OnMoving(UINT param, const LPRECT new_bounds) {
- if (widget_delegate())
- widget_delegate()->OnWidgetMove();
+ // TODO(beng): move to Widget.
+ if (GetWidget()->widget_delegate())
+ GetWidget()->widget_delegate()->OnWidgetMove();
}
LRESULT WidgetWin::OnNCActivate(BOOL active) {
@@ -893,8 +891,9 @@ LRESULT WidgetWin::OnSetText(const wchar_t* text) {
}
void WidgetWin::OnSettingChange(UINT flags, const wchar_t* section) {
- if (flags == SPI_SETWORKAREA && widget_delegate())
- widget_delegate()->OnWorkAreaChanged();
+ // TODO(beng): move to Widget.
+ if (flags == SPI_SETWORKAREA && GetWidget()->widget_delegate())
+ GetWidget()->widget_delegate()->OnWorkAreaChanged();
SetMsgHandled(FALSE);
}
@@ -961,8 +960,9 @@ void WidgetWin::OnScreenReaderDetected() {
}
void WidgetWin::SetInitialFocus() {
- View* v = widget_delegate() ?
- widget_delegate()->GetInitiallyFocusedView() : NULL;
+ // TODO(beng): move to Widget.
+ View* v = GetWidget()->widget_delegate() ?
+ GetWidget()->widget_delegate()->GetInitiallyFocusedView() : NULL;
if (v)
v->RequestFocus();
}
@@ -979,7 +979,7 @@ Window* WidgetWin::GetWindowImpl(HWND hwnd) {
WidgetWin* widget =
reinterpret_cast<WidgetWin*>(ui::GetWindowUserData(parent));
if (widget && widget->is_window_)
- return static_cast<WindowWin*>(widget);
+ return static_cast<WindowWin*>(widget)->GetWindow();
parent = ::GetParent(parent);
}
return NULL;
@@ -1016,7 +1016,7 @@ void WidgetWin::PostProcessActivateMessage(WidgetWin* widget,
}
}
-void WidgetWin::SetInitParams(const InitParams& params) {
+void WidgetWin::SetInitParams(const Widget::InitParams& params) {
// Set non-style attributes.
delete_on_destroy_ = params.delete_on_destroy;
@@ -1044,21 +1044,15 @@ void WidgetWin::SetInitParams(const InitParams& params) {
// Set type-dependent style attributes.
switch (params.type) {
- case InitParams::TYPE_WINDOW:
- case InitParams::TYPE_CONTROL:
+ case Widget::InitParams::TYPE_WINDOW:
+ case Widget::InitParams::TYPE_CONTROL:
break;
- case InitParams::TYPE_POPUP:
+ case Widget::InitParams::TYPE_POPUP:
style |= WS_POPUP;
ex_style |= WS_EX_TOOLWINDOW;
break;
- case InitParams::TYPE_MENU:
+ case Widget::InitParams::TYPE_MENU:
style |= WS_POPUP;
- is_mouse_button_pressed_ =
- ((GetKeyState(VK_LBUTTON) & 0x80) ||
- (GetKeyState(VK_RBUTTON) & 0x80) ||
- (GetKeyState(VK_MBUTTON) & 0x80) ||
- (GetKeyState(VK_XBUTTON1) & 0x80) ||
- (GetKeyState(VK_XBUTTON2) & 0x80));
break;
default:
NOTREACHED();
@@ -1089,7 +1083,7 @@ void WidgetWin::RedrawLayeredWindowContents() {
layered_window_invalid_rect_.y(),
layered_window_invalid_rect_.width(),
layered_window_invalid_rect_.height());
- GetRootView()->Paint(layered_window_contents_.get());
+ GetWidget()->GetRootView()->Paint(layered_window_contents_.get());
layered_window_contents_->restore();
RECT wr;
@@ -1107,7 +1101,7 @@ void WidgetWin::RedrawLayeredWindowContents() {
void WidgetWin::ClientAreaSizeChanged() {
RECT r;
- if (GetThemeProvider()->ShouldUseNativeFrame() || IsZoomed())
+ if (GetWidget()->GetThemeProvider()->ShouldUseNativeFrame() || IsZoomed())
GetClientRect(&r);
else
GetWindowRect(&r);
@@ -1133,13 +1127,26 @@ void WidgetWin::DispatchKeyEventPostIME(const KeyEvent& key) {
// Widget, public:
// static
-Widget* Widget::CreateWidget() {
- return new WidgetWin;
+void Widget::NotifyLocaleChanged() {
+ NOTIMPLEMENTED();
}
+namespace {
+BOOL CALLBACK WindowCallbackProc(HWND hwnd, LPARAM lParam) {
+ NativeWidget* native_widget =
+ NativeWidget::GetNativeWidgetForNativeView(hwnd);
+ if (native_widget) {
+ Widget* widget = native_widget->GetWidget();
+ if (widget->is_secondary_widget())
+ widget->Close();
+ }
+ return TRUE;
+}
+} // namespace
+
// static
-void Widget::NotifyLocaleChanged() {
- NOTIMPLEMENTED();
+void Widget::CloseAllSecondaryWidgets() {
+ EnumThreadWindows(GetCurrentThreadId(), WindowCallbackProc, 0);
}
bool Widget::ConvertRect(const Widget* source,
@@ -1167,17 +1174,26 @@ bool Widget::ConvertRect(const Widget* source,
////////////////////////////////////////////////////////////////////////////////
// NativeWidget, public:
+// static
+NativeWidget* NativeWidget::CreateNativeWidget(
+ internal::NativeWidgetDelegate* delegate) {
+ return new WidgetWin(delegate);
+}
+
+// static
NativeWidget* NativeWidget::GetNativeWidgetForNativeView(
gfx::NativeView native_view) {
return reinterpret_cast<WidgetWin*>(
ViewProp::GetValue(native_view, kNativeWidgetKey));
}
+// static
NativeWidget* NativeWidget::GetNativeWidgetForNativeWindow(
gfx::NativeWindow native_window) {
return GetNativeWidgetForNativeView(native_window);
}
+// static
NativeWidget* NativeWidget::GetTopLevelNativeWidget(
gfx::NativeView native_view) {
if (!native_view)
@@ -1206,6 +1222,7 @@ NativeWidget* NativeWidget::GetTopLevelNativeWidget(
return widget;
}
+// static
void NativeWidget::GetAllNativeWidgets(gfx::NativeView native_view,
NativeWidgets* children) {
if (!native_view)
@@ -1218,6 +1235,7 @@ void NativeWidget::GetAllNativeWidgets(gfx::NativeView native_view,
reinterpret_cast<LPARAM>(children));
}
+// static
void NativeWidget::ReparentNativeView(gfx::NativeView native_view,
gfx::NativeView new_parent) {
if (!native_view)
diff --git a/views/widget/widget_win.h b/views/widget/widget_win.h
index 3c2974b..d013ddb 100644
--- a/views/widget/widget_win.h
+++ b/views/widget/widget_win.h
@@ -23,7 +23,6 @@
#include "views/ime/input_method_delegate.h"
#include "views/layout/layout_manager.h"
#include "views/widget/native_widget.h"
-#include "views/widget/widget.h"
namespace ui {
class ViewProp;
@@ -45,8 +44,6 @@ namespace internal {
class NativeWidgetDelegate;
}
-RootView* GetRootViewForHWND(HWND hwnd);
-
// A Windows message reflected from other windows. This message is sent
// with the following arguments:
// hWnd - Target window
@@ -80,12 +77,11 @@ const int WM_NCUAHDRAWFRAME = 0xAF;
//
///////////////////////////////////////////////////////////////////////////////
class WidgetWin : public ui::WindowImpl,
- public Widget,
public NativeWidget,
public MessageLoopForUI::Observer,
public internal::InputMethodDelegate {
public:
- WidgetWin();
+ explicit WidgetWin(internal::NativeWidgetDelegate* delegate);
virtual ~WidgetWin();
// Returns true if we are on Windows Vista or greater and composition is
@@ -113,20 +109,6 @@ class WidgetWin : public ui::WindowImpl,
// Clear a view that has recently been removed on a hierarchy change.
void ClearAccessibilityViewEvent(View* view);
- // Overridden from Widget:
- virtual gfx::NativeView GetNativeView() const OVERRIDE;
- virtual gfx::NativeWindow GetNativeWindow() const OVERRIDE;
- virtual bool GetAccelerator(int cmd_id,
- ui::Accelerator* accelerator) OVERRIDE;
- virtual Window* GetWindow() OVERRIDE;
- virtual const Window* GetWindow() const OVERRIDE;
- virtual void ViewHierarchyChanged(bool is_add, View *parent,
- View *child) OVERRIDE;
- virtual void NotifyAccessibilityEvent(
- View* view,
- ui::AccessibilityTypes::Event event_type,
- bool send_native_event);
-
BOOL IsWindow() const {
return ::IsWindow(GetNativeView());
}
@@ -183,24 +165,26 @@ class WidgetWin : public ui::WindowImpl,
return ::GetClientRect(GetNativeView(), rect);
}
- // Resets the last move flag so that we can go around the optimization
- // that disregards duplicate mouse moves when ending animation requires
- // a new hit-test to do some highlighting as in TabStrip::RemoveTabAnimation
- // to cause the close button to highlight.
- void ResetLastMouseMoveFlag() {
- last_mouse_event_was_move_ = false;
- }
-
// Overridden from NativeWidget:
virtual void InitNativeWidget(const Widget::InitParams& params) OVERRIDE;
virtual Widget* GetWidget() OVERRIDE;
+ virtual const Widget* GetWidget() const OVERRIDE;
+ virtual gfx::NativeView GetNativeView() const OVERRIDE;
+ virtual gfx::NativeWindow GetNativeWindow() const OVERRIDE;
+ virtual Window* GetContainingWindow() OVERRIDE;
+ virtual const Window* GetContainingWindow() const OVERRIDE;
+ virtual void ViewRemoved(View* view) OVERRIDE;
virtual void SetNativeWindowProperty(const char* name, void* value) OVERRIDE;
virtual void* GetNativeWindowProperty(const char* name) OVERRIDE;
virtual TooltipManager* GetTooltipManager() const OVERRIDE;
virtual bool IsScreenReaderActive() const OVERRIDE;
+ virtual void SendNativeAccessibilityEvent(
+ View* view,
+ ui::AccessibilityTypes::Event event_type) OVERRIDE;
virtual void SetMouseCapture() OVERRIDE;
virtual void ReleaseMouseCapture() OVERRIDE;
virtual bool HasMouseCapture() const OVERRIDE;
+ virtual bool IsMouseButtonDown() const OVERRIDE;
virtual InputMethod* GetInputMethodNative() OVERRIDE;
virtual void ReplaceInputMethod(InputMethod* input_method) OVERRIDE;
virtual gfx::Rect GetWindowScreenBounds() const OVERRIDE;
@@ -443,6 +427,7 @@ class WidgetWin : public ui::WindowImpl,
virtual void DispatchKeyEventPostIME(const KeyEvent& key) OVERRIDE;
// A delegate implementation that handles events received here.
+ // See class documentation for Widget in widget.h for a note about ownership.
internal::NativeWidgetDelegate* delegate_;
// The following factory is used for calls to close the WidgetWin
@@ -481,8 +466,7 @@ class WidgetWin : public ui::WindowImpl,
// A factory that allows us to schedule a redraw for layered windows.
ScopedRunnableMethodFactory<WidgetWin> paint_layered_window_factory_;
- // Whether or not the window should delete itself when it is destroyed.
- // Set this to false via its setter for stack allocated instances.
+ // See class documentation for Widget in widget.h for a note about ownership.
bool delete_on_destroy_;
// True if we are allowed to update the layered window from the DIB backing
diff --git a/views/widget/widget_win_unittest.cc b/views/widget/widget_win_unittest.cc
index 3c13138..c9a33e8 100644
--- a/views/widget/widget_win_unittest.cc
+++ b/views/widget/widget_win_unittest.cc
@@ -43,7 +43,7 @@ class WidgetWinTest : public testing::Test {
};
WidgetWin* WidgetWinTest::CreateWidgetWin() {
- scoped_ptr<Widget> widget(Widget::CreateWidget());
+ scoped_ptr<Widget> widget(new Widget);
Widget::InitParams params(Widget::InitParams::TYPE_WINDOW);
params.delete_on_destroy = false;
params.bounds = gfx::Rect(50, 50, 650, 650);