diff options
24 files changed, 641 insertions, 110 deletions
diff --git a/chrome/browser/gtk/browser_window_gtk.cc b/chrome/browser/gtk/browser_window_gtk.cc index 24a03bf..f938005 100644 --- a/chrome/browser/gtk/browser_window_gtk.cc +++ b/chrome/browser/gtk/browser_window_gtk.cc @@ -7,6 +7,7 @@ #include <gdk/gdkkeysyms.h> #include "base/base_paths_linux.h" +#include "base/command_line.h" #include "base/logging.h" #include "base/message_loop.h" #include "base/path_service.h" @@ -21,6 +22,7 @@ #include "chrome/browser/location_bar.h" #include "chrome/browser/renderer_host/render_widget_host_view_gtk.h" #include "chrome/browser/tab_contents/web_contents.h" +#include "chrome/common/chrome_switches.h" #include "chrome/common/resource_bundle.h" #include "grit/theme_resources.h" @@ -147,6 +149,17 @@ BrowserWindowGtk::BrowserWindowGtk(Browser* browser) g_signal_connect(G_OBJECT(vbox_), "expose-event", G_CALLBACK(&OnContentAreaExpose), this); + // Temporary hack hidden behind a command line option to add one of the + // experimental ViewsGtk objects to the Gtk hierarchy. + const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess(); + if (parsed_command_line.HasSwitch(switches::kViewsGtk)) { + experimental_widget_.reset(new views::WidgetGtk()); + experimental_widget_->Init(gfx::Rect(), false); + gtk_box_pack_start(GTK_BOX(vbox_), + experimental_widget_->GetNativeView(), + false, false, 2); + } + toolbar_.reset(new BrowserToolbarGtk(browser_.get())); toolbar_->Init(browser_->profile(), window_); toolbar_->AddToolbarToBox(vbox_); diff --git a/chrome/browser/gtk/browser_window_gtk.h b/chrome/browser/gtk/browser_window_gtk.h index 24f7449..8811473 100644 --- a/chrome/browser/gtk/browser_window_gtk.h +++ b/chrome/browser/gtk/browser_window_gtk.h @@ -11,6 +11,7 @@ #include "base/scoped_ptr.h" #include "chrome/browser/browser_window.h" #include "chrome/browser/tabs/tab_strip_model.h" +#include "chrome/views/widget/widget_gtk.h" class BrowserToolbarGtk; class FindBarController; @@ -137,6 +138,9 @@ class BrowserWindowGtk : public BrowserWindow, // non-NULL, it may or may not be visible. It is possible for the Find Bar // to move among windows as tabs are dragged around. scoped_ptr<FindBarController> find_bar_controller_; + + // Experiment with using views for gtk. + scoped_ptr<views::WidgetGtk> experimental_widget_; }; #endif // CHROME_BROWSER_GTK_BROWSER_WINDOW_GTK_H_ diff --git a/chrome/browser/renderer_host/render_widget_host_view_gtk.cc b/chrome/browser/renderer_host/render_widget_host_view_gtk.cc index bb238f7..2db5578 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_gtk.cc +++ b/chrome/browser/renderer_host/render_widget_host_view_gtk.cc @@ -14,8 +14,6 @@ #include "chrome/common/x11_util.h" #include "chrome/browser/renderer_host/backing_store.h" #include "chrome/browser/renderer_host/render_widget_host.h" -#include "skia/ext/bitmap_platform_device_linux.h" -#include "skia/ext/platform_device_linux.h" #include "webkit/glue/webinputevent.h" namespace { diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index 09755c9d..b24076f 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc @@ -406,4 +406,7 @@ const wchar_t kEnableOutOfProcessDevTools[] = L"enable-oop-devtools"; // Enable HTML5 Worker support const wchar_t kEnableWebWorkers[] = L"enable-web-workers"; +// Enables experimental views under gtk. +const wchar_t kViewsGtk[] = L"views-gtk"; + } // namespace switches diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index ea5909b..a958bc9 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h @@ -157,6 +157,8 @@ extern const wchar_t kEnableOutOfProcessDevTools[]; extern const wchar_t kEnableWebWorkers[]; +extern const wchar_t kViewsGtk[]; + } // namespace switches #endif // CHROME_COMMON_CHROME_SWITCHES_H__ diff --git a/chrome/common/gfx/chrome_canvas.h b/chrome/common/gfx/chrome_canvas.h index 0a44fab..cf6db1e 100644 --- a/chrome/common/gfx/chrome_canvas.h +++ b/chrome/common/gfx/chrome_canvas.h @@ -188,7 +188,7 @@ class ChromeCanvas : public skia::PlatformCanvas { DISALLOW_EVIL_CONSTRUCTORS(ChromeCanvas); }; -#if defined(OS_WIN) +#if defined(OS_WIN) || defined(OS_LINUX) typedef skia::CanvasPaintT<ChromeCanvas> ChromeCanvasPaint; #endif diff --git a/chrome/test/perf/perftests.scons b/chrome/test/perf/perftests.scons index 83ae07a..fd404aa 100644 --- a/chrome/test/perf/perftests.scons +++ b/chrome/test/perf/perftests.scons @@ -40,6 +40,8 @@ env.Prepend( 'PERF_TEST', ], LIBS = [ + 'views', + 'browser', 'common', 'sqlite', diff --git a/chrome/test/ui/ui_tests.scons b/chrome/test/ui/ui_tests.scons index 5106faa..c5b757c 100644 --- a/chrome/test/ui/ui_tests.scons +++ b/chrome/test/ui/ui_tests.scons @@ -42,6 +42,7 @@ env.Prepend( 'port', 'sqlite', 'WTF', + 'views', ] ) diff --git a/chrome/test/unit/unit_tests.scons b/chrome/test/unit/unit_tests.scons index f9ac5c1..70d2cc6 100644 --- a/chrome/test/unit/unit_tests.scons +++ b/chrome/test/unit/unit_tests.scons @@ -38,6 +38,8 @@ env.Prepend( '$CHROME_SRC_DIR', ], LIBS = [ + 'views', + 'browser', 'common', 'debugger', diff --git a/chrome/views/SConscript b/chrome/views/SConscript index 9a25feb..81325aa 100644 --- a/chrome/views/SConscript +++ b/chrome/views/SConscript @@ -69,6 +69,8 @@ input_files = ChromeFileList([ 'focus/focus_manager.h', 'focus/view_storage.cc', 'focus/view_storage.h', + 'fill_layout.cc', + 'fill_layout.h', 'grid_layout.cc', 'grid_layout.h', 'controls/table/group_table_view.cc', @@ -182,7 +184,8 @@ if env.Bit('windows'): if env.Bit('linux'): input_files += [ "view_gtk.cc", - "widget/root_view_gtk.cc" + "widget/root_view_gtk.cc", + "widget/widget_gtk.cc" ] # TODO(port?): Incomplete and undecided Views stuff. These compile but aren't # currently needed, and they break the shared build due to missing symbols @@ -220,7 +223,6 @@ if env.Bit('linux'): 'controls/button/checkbox.cc', 'controls/menu/chrome_menu.cc', 'controls/combo_box.cc', - 'event.cc', 'focus/focus_manager.cc', 'controls/table/group_table_view.cc', 'controls/hwnd_view.cc', @@ -255,69 +257,6 @@ if env.Bit('linux'): 'window/window_win.cc', ) -if env.Bit('mac'): - # TODO(port): Port to Mac. - input_files.Remove( - 'accelerator.cc', - 'accelerator_handler.cc', - 'accessibility/accessible_wrapper.cc', - 'accessibility/view_accessibility.cc', - 'background.cc', - 'controls/button/button.cc', - 'controls/scrollbar/bitmap_scroll_bar.cc', - 'border.cc', - 'controls/button/image_button.cc', - 'controls/button/button_dropdown.cc', - 'controls/button/checkbox.cc', - 'controls/menu/chrome_menu.cc', - 'controls/combo_box.cc', - 'event.cc', - 'focus/external_focus_tracker.cc', - 'focus/focus_manager.cc', - 'focus/view_storage.cc', - 'grid_layout.cc', - 'controls/table/group_table_view.cc', - 'controls/hwnd_view.cc', - 'controls/image_view.cc', - 'controls/label.cc', - 'layout_manager.cc', - 'controls/link.cc', - 'controls/menu/menu.cc', - 'controls/button/menu_button.cc', - 'controls/message_box_view.cc', - 'controls/button/native_button.cc', - 'controls/native_control.cc', - 'controls/scrollbar/native_scroll_bar.cc', - 'painter.cc', - 'controls/button/radio_button.cc', - 'repeat_controller.cc', - 'resize_corner.cc', - 'controls/scrollbar/scroll_bar.cc', - 'controls/scroll_view.cc', - 'controls/separator.cc', - 'controls/single_split_view.cc', - 'controls/tabbed_pane.cc', - 'controls/table/table_view.cc', - 'controls/button/text_button.cc', - 'controls/text_field.cc', - 'controls/throbber.cc', - 'controls/tree/tree_view.cc', - 'view.cc', - 'widget/aero_tooltip_manager.cc', - 'widget/root_view.cc', - 'widget/root_view_drop_target.cc', - 'widget/tooltip_manager.cc', - 'widget/widget_win.cc', - 'window/client_view.cc', - 'window/custom_frame_view.cc', - 'window/dialog_delegate.cc', - 'window/dialog_client_view.cc', - 'window/native_frame_view.cc', - 'window/non_client_view.cc', - 'window/window_delegate.cc', - 'window/window_win.cc', - ) - env.ChromeLibrary('views', input_files) p = env.ChromeMSVSProject('views.vcproj', diff --git a/chrome/views/controls/tabbed_pane.cc b/chrome/views/controls/tabbed_pane.cc index 99af16f..7f42e40 100644 --- a/chrome/views/controls/tabbed_pane.cc +++ b/chrome/views/controls/tabbed_pane.cc @@ -15,6 +15,7 @@ #include "chrome/common/stl_util-inl.h" #include "chrome/common/throb_animation.h" #include "chrome/views/background.h" +#include "chrome/views/fill_layout.h" #include "chrome/views/widget/root_view.h" #include "chrome/views/widget/widget_win.h" #include "skia/ext/skia_utils_win.h" diff --git a/chrome/views/event.cc b/chrome/views/event.cc index 5a6081b..242daa2 100644 --- a/chrome/views/event.cc +++ b/chrome/views/event.cc @@ -11,10 +11,15 @@ namespace views { Event::Event(EventType type, int flags) : type_(type), +#if defined(OS_WIN) time_stamp_(GetTickCount()), +#else + time_stamp_(0), +#endif flags_(flags) { } +#if defined(OS_WIN) int Event::GetWindowsFlags() const { // TODO: need support for x1/x2. int result = 0; @@ -43,6 +48,7 @@ int Event::ConvertWindowsFlags(UINT win_flags) { r |= EF_RIGHT_BUTTON_DOWN; return r; } +#endif // static int Event::ConvertWebInputEventFlags(int web_input_event_flags) { @@ -77,7 +83,9 @@ MouseEvent::MouseEvent(const MouseEvent& model, View* from, View* to) : LocatedEvent(model, from, to) { } + int KeyEvent::GetKeyStateFlags() const { +#if defined(OS_WIN) // Windows Keyboard messages don't come with control key state as parameters // like mouse messages do, so we need to explicitly probe for these key // states. @@ -89,10 +97,16 @@ int KeyEvent::GetKeyStateFlags() const { if (GetKeyState(VK_CONTROL) & 0x80) flags |= Event::EF_CONTROL_DOWN; return flags; +#else + return 0; +#endif } +#if defined(OS_WIN) bool KeyEvent::IsExtendedKey() const { return (message_flags_ & KF_EXTENDED) == KF_EXTENDED; } +#endif } // namespace views + diff --git a/chrome/views/event.h b/chrome/views/event.h index 899d9fa..92f93ef 100644 --- a/chrome/views/event.h +++ b/chrome/views/event.h @@ -80,11 +80,13 @@ class Event { return (flags_ & EF_ALT_DOWN) != 0; } +#if defined(OS_WIN) // Returns the EventFlags in terms of windows flags. int GetWindowsFlags() const; // Convert windows flags to views::Event flags static int ConvertWindowsFlags(uint32 win_flags); +#endif // Convert WebInputEvent::Modifiers flags to views::Event flags. // Note that this only deals with keyboard modifiers. @@ -231,7 +233,9 @@ class KeyEvent : public Event { return character_; } +#if defined(OS_WIN) bool IsExtendedKey() const; +#endif int GetRepeatCount() const { return repeat_count_; diff --git a/chrome/views/fill_layout.cc b/chrome/views/fill_layout.cc new file mode 100644 index 0000000..8c2beee --- /dev/null +++ b/chrome/views/fill_layout.cc @@ -0,0 +1,33 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/views/fill_layout.h" + +#include "base/logging.h" + +namespace views { + +/////////////////////////////////////////////////////////////////////////////// +// FillLayout + +FillLayout::FillLayout() { +} + +FillLayout::~FillLayout() { +} + +void FillLayout::Layout(View* host) { + if (host->GetChildViewCount() == 0) + return; + + View* frame_view = host->GetChildViewAt(0); + frame_view->SetBounds(0, 0, host->width(), host->height()); +} + +gfx::Size FillLayout::GetPreferredSize(View* host) { + DCHECK(host->GetChildViewCount() == 1); + return host->GetChildViewAt(0)->GetPreferredSize(); +} + +} // namespace views diff --git a/chrome/views/fill_layout.h b/chrome/views/fill_layout.h new file mode 100644 index 0000000..a7ef21b --- /dev/null +++ b/chrome/views/fill_layout.h @@ -0,0 +1,35 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_VIEWS_FILL_LAYOUT_H_ +#define CHROME_VIEWS_FILL_LAYOUT_H_ + +#include "chrome/views/layout_manager.h" +#include "chrome/views/view.h" + +namespace views { + +/////////////////////////////////////////////////////////////////////////////// +// +// FillLayout +// A simple LayoutManager that causes the associated view's one child to be +// sized to match the bounds of its parent. +// +/////////////////////////////////////////////////////////////////////////////// +class FillLayout : public LayoutManager { + public: + FillLayout(); + virtual ~FillLayout(); + + // Overridden from LayoutManager: + virtual void Layout(View* host); + virtual gfx::Size GetPreferredSize(View* host); + + private: + DISALLOW_EVIL_CONSTRUCTORS(FillLayout); +}; + +} // namespace views + +#endif // CHROME_VIEWS_FILL_LAYOUT_H_ diff --git a/chrome/views/view.cc b/chrome/views/view.cc index 90f46d4..15af28f 100644 --- a/chrome/views/view.cc +++ b/chrome/views/view.cc @@ -972,6 +972,8 @@ void View::RemoveAccelerator(const Accelerator& accelerator) { return; } + // TODO(port): Fix this once we have a FocusManger for Linux. +#if defined(OS_WIN) FocusManager* focus_manager = GetFocusManager(); if (focus_manager) { // We may not have a FocusManager if the window containing us is being @@ -979,6 +981,7 @@ void View::RemoveAccelerator(const Accelerator& accelerator) { // nothing to unregister. focus_manager->UnregisterAccelerator(accelerator, this); } +#endif } void View::ResetAccelerators() { @@ -999,6 +1002,9 @@ void View::RegisterAccelerators() { // added to one. return; } + + // TODO(port): Fix this once we have a FocusManger for Linux. +#if defined(OS_WIN) FocusManager* focus_manager = GetFocusManager(); if (!focus_manager) { // Some crash reports seem to show that we may get cases where we have no @@ -1011,6 +1017,7 @@ void View::RegisterAccelerators() { iter != accelerators_->end(); ++iter) { focus_manager->RegisterAccelerator(*iter, this); } +#endif } void View::UnregisterAccelerators() { @@ -1019,6 +1026,8 @@ void View::UnregisterAccelerators() { RootView* root_view = GetRootView(); if (root_view) { + // TODO(port): Fix this once we have a FocusManger for Linux. +#if defined(OS_WIN) FocusManager* focus_manager = GetFocusManager(); if (focus_manager) { // We may not have a FocusManager if the window containing us is being @@ -1026,6 +1035,7 @@ void View::UnregisterAccelerators() { // nothing to unregister. focus_manager->UnregisterAccelerators(this); } +#endif } } @@ -1143,7 +1153,10 @@ void View::DetachAllFloatingViews() { if (EnumerateFloatingViews(CURRENT, floating_views_[c]->GetFloatingViewID(), &tmp_id)) { + // TODO(port): Fix this once we have a FocusManger for Linux. +#if defined(OS_WIN) focus_manager->StoreFocusedView(); +#endif should_restore_focus_ = true; } focused_view = NULL; @@ -1178,10 +1191,13 @@ void View::RestoreFloatingViewFocus() { restore_focus_view_task_ = NULL; should_restore_focus_ = false; + // TODO(port): Fix this once we have a FocusManger for Linux. +#if defined(OS_WIN) FocusManager* focus_manager = GetFocusManager(); DCHECK(focus_manager); if (focus_manager) focus_manager->RestoreFocusedView(); +#endif } // static diff --git a/chrome/views/views.vcproj b/chrome/views/views.vcproj index bb0ecad6..1f19037 100644 --- a/chrome/views/views.vcproj +++ b/chrome/views/views.vcproj @@ -776,6 +776,14 @@ > </File> <File + RelativePath=".\fill_layout.cc" + > + </File> + <File + RelativePath=".\fill_layout.h" + > + </File> + <File RelativePath=".\grid_layout.cc" > </File> diff --git a/chrome/views/widget/root_view.h b/chrome/views/widget/root_view.h index adccb9c..f7ad674 100644 --- a/chrome/views/widget/root_view.h +++ b/chrome/views/widget/root_view.h @@ -7,6 +7,10 @@ #include "build/build_config.h" +#if defined(OS_LINUX) +#include <gtk/gtk.h> +#endif + #if defined(OS_WIN) #include "base/ref_counted.h" #endif @@ -182,6 +186,8 @@ class RootView : public View, #if defined(OS_WIN) // Invoked from the Widget to service a WM_PAINT call. void OnPaint(HWND hwnd); +#elif defined(OS_LINUX) + void OnPaint(GdkEventExpose* event); #endif #if defined(OS_WIN) diff --git a/chrome/views/widget/root_view_gtk.cc b/chrome/views/widget/root_view_gtk.cc index 89ed51a6..1c7fe9c 100644 --- a/chrome/views/widget/root_view_gtk.cc +++ b/chrome/views/widget/root_view_gtk.cc @@ -5,6 +5,8 @@ #include "chrome/views/widget/root_view.h" #include "base/logging.h" +#include "chrome/common/gfx/chrome_canvas.h" +#include "skia/include/SkColor.h" namespace views { @@ -15,5 +17,18 @@ void RootView::UpdateCursor(const MouseEvent& e) { } // TODO(port): Port OnPaint() to not use HWNDs in its public interface. +void RootView::OnPaint(GdkEventExpose* event) { + ChromeCanvasPaint canvas(event); + canvas.FillRectInt(SK_ColorRED, 5, 5, 10, 10); + canvas.FillRectInt(SK_ColorGREEN, 25, 5, 10, 10); + canvas.FillRectInt(SK_ColorBLUE, 45, 5, 10, 10); + + if (!canvas.isEmpty()) { + // const PAINTSTRUCT& ps = canvas.paintStruct(); + // SchedulePaint(gfx::Rect(ps.rcPaint), false); + if (NeedsPainting(false)) + ProcessPaint(&canvas); + } +} } diff --git a/chrome/views/widget/widget_gtk.cc b/chrome/views/widget/widget_gtk.cc new file mode 100644 index 0000000..83d7766 --- /dev/null +++ b/chrome/views/widget/widget_gtk.cc @@ -0,0 +1,285 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/views/widget/widget_gtk.h" + +#include "chrome/views/fill_layout.h" +#include "chrome/views/widget/root_view.h" + +namespace views { + +WidgetGtk::WidgetGtk() + : widget_(NULL) { +} + +WidgetGtk::~WidgetGtk() { + gtk_widget_unref(widget_); + + // MessageLoopForUI::current()->RemoveObserver(this); +} + +void WidgetGtk::Init(const gfx::Rect& bounds, + bool has_own_focus_manager) { + + // Force creation of the RootView if it hasn't been created yet. + GetRootView(); + + // Make container here. + widget_ = gtk_drawing_area_new(); + gtk_drawing_area_size(GTK_DRAWING_AREA(widget_), 100, 100); + gtk_widget_show(widget_); + + root_view_->OnWidgetCreated(); + + // TODO(port): if(has_own_focus_manager) block + + SetViewForNative(widget_, this); + SetRootViewForWidget(widget_, root_view_.get()); + + // MessageLoopForUI::current()->AddObserver(this); + + g_signal_connect_after(G_OBJECT(widget_), "size_allocate", + G_CALLBACK(CallSizeAllocate), NULL); + g_signal_connect(G_OBJECT(widget_), "expose_event", + G_CALLBACK(CallPaint), NULL); + g_signal_connect(G_OBJECT(widget_), "enter_notify_event", + G_CALLBACK(CallEnterNotify), NULL); + g_signal_connect(G_OBJECT(widget_), "leave_notify_event", + G_CALLBACK(CallLeaveNotify), NULL); + g_signal_connect(G_OBJECT(widget_), "motion_notify_event", + G_CALLBACK(CallMotionNotify), NULL); + g_signal_connect(G_OBJECT(widget_), "button_press_event", + G_CALLBACK(CallButtonPress), NULL); + g_signal_connect(G_OBJECT(widget_), "button_release_event", + G_CALLBACK(CallButtonRelease), NULL); + g_signal_connect(G_OBJECT(widget_), "focus_in_event", + G_CALLBACK(CallFocusIn), NULL); + g_signal_connect(G_OBJECT(widget_), "focus_out_event", + G_CALLBACK(CallFocusOut), NULL); + g_signal_connect(G_OBJECT(widget_), "key_press_event", + G_CALLBACK(CallKeyPress), NULL); + g_signal_connect(G_OBJECT(widget_), "key_release_event", + G_CALLBACK(CallKeyRelease), NULL); + g_signal_connect(G_OBJECT(widget_), "scroll_event", + G_CALLBACK(CallScroll), NULL); + g_signal_connect(G_OBJECT(widget_), "visibility_notify_event", + G_CALLBACK(CallVisibilityNotify), NULL); + + // TODO(erg): Ignore these signals for now because they're such a drag. + // + // g_signal_connect(G_OBJECT(widget_), "drag_motion", + // G_CALLBACK(drag_motion_event_cb), NULL); + // g_signal_connect(G_OBJECT(widget_), "drag_leave", + // G_CALLBACK(drag_leave_event_cb), NULL); + // g_signal_connect(G_OBJECT(widget_), "drag_drop", + // G_CALLBACK(drag_drop_event_cb), NULL); + // g_signal_connect(G_OBJECT(widget_), "drag_data_received", + // G_CALLBACK(drag_data_received_event_cb), NULL); +} + +void WidgetGtk::SetContentsView(View* view) { + DCHECK(view && widget_) << "Can't be called until after the HWND is created!"; + // The ContentsView must be set up _after_ the window is created so that its + // Widget pointer is valid. + root_view_->SetLayoutManager(new FillLayout); + if (root_view_->GetChildViewCount() != 0) + root_view_->RemoveAllChildViews(true); + root_view_->AddChildView(view); + + // TODO(erg): More windowy stuff here. + NOTIMPLEMENTED(); +} + +void WidgetGtk::GetBounds(gfx::Rect* out, bool including_frame) const { + if (including_frame) { + NOTIMPLEMENTED(); + *out = gfx::Rect(); + return; + } + + // TODO(erg): Not sure how to implement this. gtk_widget_size_request() + // returns a widget's requested size--not it's actual size. The system of + // containers and such do auto sizing tricks to make everything work within + // the constraints and requested sizes... + NOTIMPLEMENTED(); +} + +void WidgetGtk::MoveToFront(bool should_activate) { + // TODO(erg): I'm not sure about how to do z-ordering on GTK widgets... +} + +gfx::NativeView WidgetGtk::GetNativeView() const { + return widget_; +} + +void WidgetGtk::PaintNow(const gfx::Rect& update_rect) { + +} + +RootView* WidgetGtk::GetRootView() { + if (!root_view_.get()) { + // First time the root view is being asked for, create it now. + root_view_.reset(CreateRootView()); + } + return root_view_.get(); +} + +bool WidgetGtk::IsVisible() { + return GTK_WIDGET_VISIBLE(widget_); +} + +bool WidgetGtk::IsActive() { + NOTIMPLEMENTED(); + return false; +} + +TooltipManager* WidgetGtk::GetTooltipManager() { + NOTIMPLEMENTED(); + return NULL; +} + +bool WidgetGtk::GetAccelerator(int cmd_id, Accelerator* accelerator) { + return false; +} + + +gboolean WidgetGtk::OnPaint(GtkWidget* widget, GdkEventExpose* event) { + // Do something here with a chrome canvas? + root_view_->OnPaint(event); + return true; +} + +RootView* WidgetGtk::CreateRootView() { + return new RootView(this); +} + +// static +WidgetGtk* WidgetGtk::GetViewForNative(GtkWidget* widget) { + gpointer user_data = g_object_get_data(G_OBJECT(widget), "chrome-views"); + return static_cast<WidgetGtk*>(user_data); +} + +// static +void WidgetGtk::SetViewForNative(GtkWidget* widget, WidgetGtk* view) { + g_object_set_data(G_OBJECT(widget), "chrome-views", view); +} + +// static +RootView* WidgetGtk::GetRootViewForWidget(GtkWidget* widget) { + gpointer user_data = g_object_get_data(G_OBJECT(widget), "root-view"); + return static_cast<RootView*>(user_data); +} + +// static +void WidgetGtk::SetRootViewForWidget(GtkWidget* widget, RootView* root_view) { + g_object_set_data(G_OBJECT(widget), "root-view", root_view); +} + +// static +void WidgetGtk::CallSizeAllocate(GtkWidget* widget, GtkAllocation* allocation) { + WidgetGtk* widget_gtk = GetViewForNative(widget); + if (!widget_gtk) + return; + + widget_gtk->OnSizeAllocate(widget, allocation); +} + +gboolean WidgetGtk::CallPaint(GtkWidget* widget, GdkEventExpose* event) { + WidgetGtk* widget_gtk = GetViewForNative(widget); + if (!widget_gtk) + return false; + + return widget_gtk->OnPaint(widget, event); +} + +gboolean WidgetGtk::CallEnterNotify(GtkWidget* widget, GdkEventCrossing* event) { + WidgetGtk* widget_gtk = GetViewForNative(widget); + if (!widget_gtk) + return false; + + return widget_gtk->OnEnterNotify(widget, event); +} + +gboolean WidgetGtk::CallLeaveNotify(GtkWidget* widget, GdkEventCrossing* event) { + WidgetGtk* widget_gtk = GetViewForNative(widget); + if (!widget_gtk) + return false; + + return widget_gtk->OnLeaveNotify(widget, event); +} + +gboolean WidgetGtk::CallMotionNotify(GtkWidget* widget, GdkEventMotion* event) { + WidgetGtk* widget_gtk = GetViewForNative(widget); + if (!widget_gtk) + return false; + + return widget_gtk->OnMotionNotify(widget, event); +} + +gboolean WidgetGtk::CallButtonPress(GtkWidget* widget, GdkEventButton* event) { + WidgetGtk* widget_gtk = GetViewForNative(widget); + if (!widget_gtk) + return false; + + return widget_gtk->OnButtonPress(widget, event); +} + +gboolean WidgetGtk::CallButtonRelease(GtkWidget* widget, GdkEventButton* event) { + WidgetGtk* widget_gtk = GetViewForNative(widget); + if (!widget_gtk) + return false; + + return widget_gtk->OnButtonRelease(widget, event); +} + +gboolean WidgetGtk::CallFocusIn(GtkWidget* widget, GdkEventFocus* event) { + WidgetGtk* widget_gtk = GetViewForNative(widget); + if (!widget_gtk) + return false; + + return widget_gtk->OnFocusIn(widget, event); +} + +gboolean WidgetGtk::CallFocusOut(GtkWidget* widget, GdkEventFocus* event) { + WidgetGtk* widget_gtk = GetViewForNative(widget); + if (!widget_gtk) + return false; + + return widget_gtk->OnFocusOut(widget, event); +} + +gboolean WidgetGtk::CallKeyPress(GtkWidget* widget, GdkEventKey* event) { + WidgetGtk* widget_gtk = GetViewForNative(widget); + if (!widget_gtk) + return false; + + return widget_gtk->OnKeyPress(widget, event); +} + +gboolean WidgetGtk::CallKeyRelease(GtkWidget* widget, GdkEventKey* event) { + WidgetGtk* widget_gtk = GetViewForNative(widget); + if (!widget_gtk) + return false; + + return widget_gtk->OnKeyRelease(widget, event); +} + +gboolean WidgetGtk::CallScroll(GtkWidget* widget, GdkEventScroll* event) { + WidgetGtk* widget_gtk = GetViewForNative(widget); + if (!widget_gtk) + return false; + + return widget_gtk->OnScroll(widget, event); +} + +gboolean WidgetGtk::CallVisibilityNotify(GtkWidget* widget, + GdkEventVisibility* event) { + WidgetGtk* widget_gtk = GetViewForNative(widget); + if (!widget_gtk) + return false; + + return widget_gtk->OnVisibilityNotify(widget, event); +} + +} diff --git a/chrome/views/widget/widget_gtk.h b/chrome/views/widget/widget_gtk.h new file mode 100644 index 0000000..9669ba3 --- /dev/null +++ b/chrome/views/widget/widget_gtk.h @@ -0,0 +1,122 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_VIEWS_WIDGET_WIDGET_GTK_H_ +#define CHROME_VIEWS_WIDGET_WIDGET_GTK_H_ + +#include <gtk/gtk.h> + +#include "base/message_loop.h" +#include "chrome/views/widget/widget.h" + +namespace gfx { +class Rect; +} + +namespace views { + +class View; + +class WidgetGtk : public Widget { + public: + static WidgetGtk* Construct() { + // This isn't used, but exists to force WidgetGtk to be instantiable. + return new WidgetGtk; + } + + WidgetGtk(); + virtual ~WidgetGtk(); + + // Initializes this widget and returns the gtk drawing area for the caller to + // add to its hierarchy. (We can't pass in the parent to this method because + // there are no standard adding semantics in gtk...) + void Init(const gfx::Rect& bounds, bool has_own_focus_manager); + + virtual void SetContentsView(View* view); + + // Overridden from Widget: + virtual void GetBounds(gfx::Rect* out, bool including_frame) const; + virtual void MoveToFront(bool should_activate); + virtual gfx::NativeView GetNativeView() const; + virtual void PaintNow(const gfx::Rect& update_rect); + virtual RootView* GetRootView(); + virtual bool IsVisible(); + virtual bool IsActive(); + virtual TooltipManager* GetTooltipManager(); + virtual bool GetAccelerator(int cmd_id, Accelerator* accelerator); + + protected: + virtual void OnSizeAllocate(GtkWidget* widget, GtkAllocation* allocation) {} + virtual gboolean OnPaint(GtkWidget* widget, GdkEventExpose* event); + virtual gboolean OnEnterNotify(GtkWidget* widget, GdkEventCrossing* event) { + return false; + } + virtual gboolean OnLeaveNotify(GtkWidget* widget, GdkEventCrossing* event) { + return false; + } + virtual gboolean OnMotionNotify(GtkWidget* widget, GdkEventMotion* event) { + return false; + } + virtual gboolean OnButtonPress(GtkWidget* widget, GdkEventButton* event) { + return false; + } + virtual gboolean OnButtonRelease(GtkWidget* widget, GdkEventButton* event) { + return false; + } + virtual gboolean OnFocusIn(GtkWidget* widget, GdkEventFocus* event) { + return false; + } + virtual gboolean OnFocusOut(GtkWidget* widget, GdkEventFocus* event) { + return false; + } + virtual gboolean OnKeyPress(GtkWidget* widget, GdkEventKey* event) { + return false; + } + virtual gboolean OnKeyRelease(GtkWidget* widget, GdkEventKey* event) { + return false; + } + virtual gboolean OnScroll(GtkWidget* widget, GdkEventScroll* event) { + return false; + } + virtual gboolean OnVisibilityNotify(GtkWidget* widget, + GdkEventVisibility* event) { + return false; + } + + private: + virtual RootView* CreateRootView(); + + // Sets and retrieves the WidgetGtk in the userdata section of the widget. + static WidgetGtk* GetViewForNative(GtkWidget* widget); + static void SetViewForNative(GtkWidget* widget, WidgetGtk* view); + + static RootView* GetRootViewForWidget(GtkWidget* widget); + static void SetRootViewForWidget(GtkWidget* widget, RootView* root_view); + + // A set of static signal handlers that bridge + static void CallSizeAllocate(GtkWidget* widget, GtkAllocation* allocation); + static gboolean CallPaint(GtkWidget* widget, GdkEventExpose* event); + static gboolean CallEnterNotify(GtkWidget* widget, GdkEventCrossing* event); + static gboolean CallLeaveNotify(GtkWidget* widget, GdkEventCrossing* event); + static gboolean CallMotionNotify(GtkWidget* widget, GdkEventMotion* event); + static gboolean CallButtonPress(GtkWidget* widget, GdkEventButton* event); + static gboolean CallButtonRelease(GtkWidget* widget, GdkEventButton* event); + static gboolean CallFocusIn(GtkWidget* widget, GdkEventFocus* event); + static gboolean CallFocusOut(GtkWidget* widget, GdkEventFocus* event); + static gboolean CallKeyPress(GtkWidget* widget, GdkEventKey* event); + static gboolean CallKeyRelease(GtkWidget* widget, GdkEventKey* event); + static gboolean CallScroll(GtkWidget* widget, GdkEventScroll* event); + static gboolean CallVisibilityNotify(GtkWidget* widget, + GdkEventVisibility* event); + + // Our native view. + GtkWidget* widget_; + + // The root of the View hierarchy attached to this window. + scoped_ptr<RootView> root_view_; +}; + +} // namespace views + +#endif // CHROME_VIEWS_WIDGET_WIDGET_GTK_H_ diff --git a/chrome/views/widget/widget_win.cc b/chrome/views/widget/widget_win.cc index 16f510c..2faab37 100644 --- a/chrome/views/widget/widget_win.cc +++ b/chrome/views/widget/widget_win.cc @@ -13,6 +13,7 @@ #include "chrome/common/win_util.h" #include "chrome/views/accessibility/view_accessibility.h" #include "chrome/views/controls/native_control_win.h" +#include "chrome/views/fill_layout.h" #include "chrome/views/widget/aero_tooltip_manager.h" #include "chrome/views/widget/hwnd_notification_source.h" #include "chrome/views/widget/root_view.h" @@ -48,28 +49,6 @@ NativeControlWin* GetNativeControlWinForHWND(HWND hwnd) { static WidgetWin* instance_issuing_create = NULL; /////////////////////////////////////////////////////////////////////////////// -// FillLayout - -FillLayout::FillLayout() { -} - -FillLayout::~FillLayout() { -} - -void FillLayout::Layout(View* host) { - if (host->GetChildViewCount() == 0) - return; - - View* frame_view = host->GetChildViewAt(0); - frame_view->SetBounds(0, 0, host->width(), host->height()); -} - -gfx::Size FillLayout::GetPreferredSize(View* host) { - DCHECK(host->GetChildViewCount() == 1); - return host->GetChildViewAt(0)->GetPreferredSize(); -} - -/////////////////////////////////////////////////////////////////////////////// // Window class tracking. // static diff --git a/chrome/views/widget/widget_win.h b/chrome/views/widget/widget_win.h index d7ff51b..aa88b08 100644 --- a/chrome/views/widget/widget_win.h +++ b/chrome/views/widget/widget_win.h @@ -49,26 +49,6 @@ static const int WM_NCUAHDRAWFRAME = 0xAF; /////////////////////////////////////////////////////////////////////////////// // -// FillLayout -// A simple LayoutManager that causes the associated view's one child to be -// sized to match the bounds of its parent. -// -/////////////////////////////////////////////////////////////////////////////// -class FillLayout : public LayoutManager { - public: - FillLayout(); - virtual ~FillLayout(); - - // Overridden from LayoutManager: - virtual void Layout(View* host); - virtual gfx::Size GetPreferredSize(View* host); - - private: - DISALLOW_EVIL_CONSTRUCTORS(FillLayout); -}; - -/////////////////////////////////////////////////////////////////////////////// -// // WidgetWin // A Widget for a views hierarchy used to represent anything that can be // contained within an HWND, e.g. a control, a window, etc. Specializations diff --git a/skia/ext/platform_canvas_linux.h b/skia/ext/platform_canvas_linux.h index a1cd1ab..63ffd62 100644 --- a/skia/ext/platform_canvas_linux.h +++ b/skia/ext/platform_canvas_linux.h @@ -9,6 +9,9 @@ #include "skia/ext/platform_device_linux.h" +#include <cairo/cairo.h> +#include <gdk/gdk.h> + namespace skia { // This class is a specialization of the regular SkCanvas that is designed to @@ -65,6 +68,72 @@ class PlatformCanvasLinux : public SkCanvas { PlatformCanvasLinux& operator=(const PlatformCanvasLinux&); }; +// A class designed to translate skia painting into a region in a +// GdkWindow. This class has been adapted from the class with the same name in +// platform_canvas_win.h. On construction, it will set up a context for +// painting into, and on destruction, it will commit it to the GdkWindow. +template <class T> +class CanvasPaintT : public T { + public: + explicit CanvasPaintT(GdkEventExpose* event) + : surface_(NULL), + window_(event->window), + rectangle_(event->area) { + init(true); + } + + CanvasPaintT(GdkEventExpose* event, bool opaque) + : surface_(NULL), + window_(event->window), + rectangle_(event->area) { + init(opaque); + } + + virtual ~CanvasPaintT() { + if (!isEmpty()) { + T::restoreToCount(1); + + cairo_t* cairo_drawable = gdk_cairo_create(window_); + cairo_set_source_surface(cairo_drawable, surface_, 0, 0); + cairo_paint(cairo_drawable); + cairo_destroy(cairo_drawable); + + gdk_window_end_paint(window_); + } + } + + // Returns true if the invalid region is empty. The caller should call this + // function to determine if anything needs painting. + bool isEmpty() const { + return rectangle_.width == 0 || rectangle_.height == 0; + } + + private: + void init(bool opaque) { + gdk_window_begin_paint_rect(window_, &rectangle_); + + if (!T::initialize(rectangle_.width, rectangle_.height, opaque, NULL)) { + // Cause a deliberate crash; + *(char*) 0 = 0; + } + + surface_ = T::getTopPlatformDevice().beginPlatformPaint(); + + // This will bring the canvas into the screen coordinate system for the + // dirty rect + T::translate(SkIntToScalar(-rectangle_.x), + SkIntToScalar(-rectangle_.y)); + } + + cairo_surface_t* surface_; + GdkWindow* window_; + GdkRectangle rectangle_; + + // Disallow copy and assign. + CanvasPaintT(const CanvasPaintT&); + CanvasPaintT& operator=(const CanvasPaintT&); +}; + } // namespace skia #endif // SKIA_EXT_PLATFORM_CANVAS_LINUX_H_ |