From 61db17412ca481ad9a91a7b51fe2a4b144ba6038 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 4 Jul 2014 01:30:36 +0800 Subject: [PATCH] Use views to implement NativeWindow and MessageBox on Linux. --- atom.gyp | 16 +- atom/browser/api/atom_api_menu.cc | 2 +- atom/browser/api/atom_api_menu_gtk.cc | 1 - atom/browser/atom_browser_main_parts.cc | 32 +- atom/browser/atom_browser_main_parts.h | 2 +- atom/browser/native_window_aura.cc | 202 ------ atom/browser/native_window_gtk.cc | 617 ------------------ atom/browser/native_window_gtk.h | 157 ----- atom/browser/native_window_views.cc | 295 +++++++++ ...ve_window_aura.h => native_window_views.h} | 51 +- atom/browser/ui/file_dialog_gtk.cc | 1 - atom/browser/ui/message_box_gtk.cc | 136 ---- ...essage_box_win.cc => message_box_views.cc} | 48 +- .../string16_converter.h | 3 + .../ui/libgtk2ui/g_object_destructor_filo.cc | 89 --- .../ui/libgtk2ui/g_object_destructor_filo.h | 90 --- .../chrome/browser/ui/libgtk2ui/gtk2_signal.h | 68 -- .../ui/libgtk2ui/gtk2_signal_registrar.cc | 98 --- .../ui/libgtk2ui/gtk2_signal_registrar.h | 74 --- .../browser/ui/libgtk2ui/skia_utils_gtk2.cc | 135 ---- .../browser/ui/libgtk2ui/skia_utils_gtk2.h | 42 -- vendor/brightray | 2 +- 22 files changed, 384 insertions(+), 1777 deletions(-) delete mode 100644 atom/browser/native_window_aura.cc delete mode 100644 atom/browser/native_window_gtk.cc delete mode 100644 atom/browser/native_window_gtk.h create mode 100644 atom/browser/native_window_views.cc rename atom/browser/{native_window_aura.h => native_window_views.h} (58%) delete mode 100644 atom/browser/ui/message_box_gtk.cc rename atom/browser/ui/{message_box_win.cc => message_box_views.cc} (88%) delete mode 100644 chromium_src/chrome/browser/ui/libgtk2ui/g_object_destructor_filo.cc delete mode 100644 chromium_src/chrome/browser/ui/libgtk2ui/g_object_destructor_filo.h delete mode 100644 chromium_src/chrome/browser/ui/libgtk2ui/gtk2_signal.h delete mode 100644 chromium_src/chrome/browser/ui/libgtk2ui/gtk2_signal_registrar.cc delete mode 100644 chromium_src/chrome/browser/ui/libgtk2ui/gtk2_signal_registrar.h delete mode 100644 chromium_src/chrome/browser/ui/libgtk2ui/skia_utils_gtk2.cc delete mode 100644 chromium_src/chrome/browser/ui/libgtk2ui/skia_utils_gtk2.h diff --git a/atom.gyp b/atom.gyp index 2358f9fbe6bf..3cd549431995 100644 --- a/atom.gyp +++ b/atom.gyp @@ -101,10 +101,8 @@ 'atom/browser/mac/atom_application_delegate.mm', 'atom/browser/native_window.cc', 'atom/browser/native_window.h', - 'atom/browser/native_window_aura.cc', - 'atom/browser/native_window_aura.h', -# 'atom/browser/native_window_gtk.cc', -# 'atom/browser/native_window_gtk.h', + 'atom/browser/native_window_views.cc', + 'atom/browser/native_window_views.h', 'atom/browser/native_window_mac.h', 'atom/browser/native_window_mac.mm', 'atom/browser/native_window_win.cc', @@ -136,9 +134,8 @@ 'atom/browser/ui/gtk/status_icon.cc', 'atom/browser/ui/gtk/status_icon.h', 'atom/browser/ui/message_box.h', - 'atom/browser/ui/message_box_gtk.cc', 'atom/browser/ui/message_box_mac.mm', - 'atom/browser/ui/message_box_win.cc', + 'atom/browser/ui/message_box_views.cc', 'atom/browser/ui/tray_icon.cc', 'atom/browser/ui/tray_icon.h', 'atom/browser/ui/tray_icon_gtk.cc', @@ -236,13 +233,6 @@ 'chromium_src/chrome/browser/ui/gtk/gtk_window_util.h', 'chromium_src/chrome/browser/ui/gtk/menu_gtk.cc', 'chromium_src/chrome/browser/ui/gtk/menu_gtk.h', - 'chromium_src/chrome/browser/ui/libgtk2ui/g_object_destructor_filo.cc', - 'chromium_src/chrome/browser/ui/libgtk2ui/g_object_destructor_filo.h', - 'chromium_src/chrome/browser/ui/libgtk2ui/gtk2_signal.h', - 'chromium_src/chrome/browser/ui/libgtk2ui/gtk2_signal_registrar.cc', - 'chromium_src/chrome/browser/ui/libgtk2ui/gtk2_signal_registrar.h', - 'chromium_src/chrome/browser/ui/libgtk2ui/skia_utils_gtk2.cc', - 'chromium_src/chrome/browser/ui/libgtk2ui/skia_utils_gtk2.h', 'chromium_src/chrome/browser/ui/views/status_icons/status_tray_state_changer_win.cc', 'chromium_src/chrome/browser/ui/views/status_icons/status_tray_state_changer_win.h', 'chromium_src/ui/base/accelerators/platform_accelerator_gtk.cc', diff --git a/atom/browser/api/atom_api_menu.cc b/atom/browser/api/atom_api_menu.cc index a6d729254cbb..946ffd6a0804 100644 --- a/atom/browser/api/atom_api_menu.cc +++ b/atom/browser/api/atom_api_menu.cc @@ -246,7 +246,7 @@ void Menu::BuildPrototype(v8::Isolate* isolate, .SetMethod("isItemCheckedAt", &Menu::IsItemCheckedAt) .SetMethod("isEnabledAt", &Menu::IsEnabledAt) .SetMethod("isVisibleAt", &Menu::IsVisibleAt) -#if defined(OS_WIN) || defined(TOOLKIT_GTK) +#if defined(OS_WIN) || defined(OS_LINUX) .SetMethod("_attachToWindow", &Menu::AttachToWindow) #endif #if defined(OS_WIN) diff --git a/atom/browser/api/atom_api_menu_gtk.cc b/atom/browser/api/atom_api_menu_gtk.cc index 9d45d3f86969..5daa60132a32 100644 --- a/atom/browser/api/atom_api_menu_gtk.cc +++ b/atom/browser/api/atom_api_menu_gtk.cc @@ -4,7 +4,6 @@ #include "atom/browser/api/atom_api_menu_gtk.h" -#include "atom/browser/native_window_gtk.h" #include "content/public/browser/render_widget_host_view.h" #include "ui/gfx/point.h" #include "ui/gfx/screen.h" diff --git a/atom/browser/atom_browser_main_parts.cc b/atom/browser/atom_browser_main_parts.cc index f599c3daebc9..c141b265fd75 100644 --- a/atom/browser/atom_browser_main_parts.cc +++ b/atom/browser/atom_browser_main_parts.cc @@ -9,12 +9,17 @@ #include "atom/browser/browser.h" #include "atom/common/api/atom_bindings.h" #include "atom/common/node_bindings.h" +#include "base/command_line.h" #include "net/proxy/proxy_resolver_v8.h" #if defined(OS_WIN) #include "ui/gfx/win/dpi.h" #endif +#if defined(USE_X11) +#include "chrome/browser/ui/libgtk2ui/gtk2_util.h" +#endif + #include "atom/common/node_includes.h" namespace atom { @@ -48,6 +53,14 @@ brightray::BrowserContext* AtomBrowserMainParts::CreateBrowserContext() { return new AtomBrowserContext(); } +void AtomBrowserMainParts::InitProxyResolverV8() { + // Since we are integrating node in browser, we can just be sure that an + // V8 instance would be prepared, while the ProxyResolverV8::CreateIsolate() + // would try to create a V8 isolate, which messed everything on Windows, so + // we have to override and call RememberDefaultIsolate on Windows instead. + net::ProxyResolverV8::RememberDefaultIsolate(); +} + void AtomBrowserMainParts::PostEarlyInitialization() { brightray::BrowserMainParts::PostEarlyInitialization(); @@ -64,6 +77,10 @@ void AtomBrowserMainParts::PostEarlyInitialization() { void AtomBrowserMainParts::PreMainMessageLoopRun() { brightray::BrowserMainParts::PreMainMessageLoopRun(); +#if defined(USE_X11) + libgtk2ui::GtkInitFromCommandLine(*CommandLine::ForCurrentProcess()); +#endif + node_bindings_->PrepareMessageLoop(); node_bindings_->RunMessageLoop(); @@ -79,19 +96,4 @@ void AtomBrowserMainParts::PreMainMessageLoopRun() { #endif } -int AtomBrowserMainParts::PreCreateThreads() { - // Note that we are overriding the PreCreateThreads of brightray, since we - // are integrating node in browser, we can just be sure that an V8 instance - // would be prepared, while the ProxyResolverV8::CreateIsolate() would - // try to create a V8 isolate, which messed everything on Windows, so we - // have to override and call RememberDefaultIsolate on Windows instead. - net::ProxyResolverV8::RememberDefaultIsolate(); - -#if defined(OS_WIN) - gfx::EnableHighDPISupport(); -#endif - - return 0; -} - } // namespace atom diff --git a/atom/browser/atom_browser_main_parts.h b/atom/browser/atom_browser_main_parts.h index 5437ef33f9ed..d9b94e8d8310 100644 --- a/atom/browser/atom_browser_main_parts.h +++ b/atom/browser/atom_browser_main_parts.h @@ -26,11 +26,11 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts { protected: // Implementations of brightray::BrowserMainParts. virtual brightray::BrowserContext* CreateBrowserContext() OVERRIDE; + virtual void InitProxyResolverV8() OVERRIDE; // Implementations of content::BrowserMainParts. virtual void PostEarlyInitialization() OVERRIDE; virtual void PreMainMessageLoopRun() OVERRIDE; - virtual int PreCreateThreads() OVERRIDE; #if defined(OS_MACOSX) virtual void PreMainMessageLoopStart() OVERRIDE; virtual void PostDestroyThreads() OVERRIDE; diff --git a/atom/browser/native_window_aura.cc b/atom/browser/native_window_aura.cc deleted file mode 100644 index ada089a49751..000000000000 --- a/atom/browser/native_window_aura.cc +++ /dev/null @@ -1,202 +0,0 @@ -// Copyright (c) 2014 GitHub, Inc. All rights reserved. -// Use of this source code is governed by the MIT license that can be -// found in the LICENSE file. - -#include "atom/browser/native_window_aura.h" - -#include "content/public/browser/web_contents_view.h" -#include "ui/aura/env.h" -#include "ui/aura/layout_manager.h" -#include "ui/aura/window.h" - -namespace atom { - -namespace { - -class FillLayout : public aura::LayoutManager { - public: - explicit FillLayout(aura::Window* root) - : root_(root) { - } - - virtual ~FillLayout() {} - - private: - // aura::LayoutManager: - virtual void OnWindowResized() OVERRIDE { - } - - virtual void OnWindowAddedToLayout(aura::Window* child) OVERRIDE { - child->SetBounds(root_->bounds()); - } - - virtual void OnWillRemoveWindowFromLayout(aura::Window* child) OVERRIDE { - } - - virtual void OnWindowRemovedFromLayout(aura::Window* child) OVERRIDE { - } - - virtual void OnChildWindowVisibilityChanged(aura::Window* child, - bool visible) OVERRIDE { - } - - virtual void SetChildBounds(aura::Window* child, - const gfx::Rect& requested_bounds) OVERRIDE { - SetChildBoundsDirect(child, requested_bounds); - } - - aura::Window* root_; - - DISALLOW_COPY_AND_ASSIGN(FillLayout); -}; - -} // namespace - -NativeWindowAura::NativeWindowAura(content::WebContents* web_contents, - const mate::Dictionary& options) - : NativeWindow(web_contents, options) { - aura::Env::CreateInstance(); - - host_.reset(aura::WindowTreeHost::Create(gfx::Rect(gfx::Size(800, 600)))); - host_->InitHost(); - host_->window()->SetLayoutManager(new FillLayout(host_->window())); - host_->window()->AddChild(web_contents->GetView()->GetNativeView()); -} - -NativeWindowAura::~NativeWindowAura() { -} - -void NativeWindowAura::Close() { -} - -void NativeWindowAura::CloseImmediately() { -} - -void NativeWindowAura::Move(const gfx::Rect& pos) { -} - -void NativeWindowAura::Focus(bool focus) { -} - -bool NativeWindowAura::IsFocused() { - return false; -} - -void NativeWindowAura::Show() { - host_->Show(); -} - -void NativeWindowAura::Hide() { - host_->Hide(); -} - -bool NativeWindowAura::IsVisible() { - return false; -} - -void NativeWindowAura::Maximize() { -} - -void NativeWindowAura::Unmaximize() { -} - -void NativeWindowAura::Minimize() { -} - -void NativeWindowAura::Restore() { -} - -void NativeWindowAura::SetFullscreen(bool fullscreen) { -} - -bool NativeWindowAura::IsFullscreen() { - return false; -} - -void NativeWindowAura::SetSize(const gfx::Size& size) { -} - -gfx::Size NativeWindowAura::GetSize() { - return gfx::Size(); -} - -void NativeWindowAura::SetContentSize(const gfx::Size& size) { -} - -gfx::Size NativeWindowAura::GetContentSize() { - return gfx::Size(); -} - -void NativeWindowAura::SetMinimumSize(const gfx::Size& size) { -} - -gfx::Size NativeWindowAura::GetMinimumSize() { - return gfx::Size(); -} - -void NativeWindowAura::SetMaximumSize(const gfx::Size& size) { -} - -gfx::Size NativeWindowAura::GetMaximumSize() { - return gfx::Size(); -} - -void NativeWindowAura::SetResizable(bool resizable) { -} - -bool NativeWindowAura::IsResizable() { - return false; -} - -void NativeWindowAura::SetAlwaysOnTop(bool top) { -} - -bool NativeWindowAura::IsAlwaysOnTop() { - return false; -} - -void NativeWindowAura::Center() { -} - -void NativeWindowAura::SetPosition(const gfx::Point& position) { -} - -gfx::Point NativeWindowAura::GetPosition() { - return gfx::Point(0, 0); -} - -void NativeWindowAura::SetTitle(const std::string& title) { -} - -std::string NativeWindowAura::GetTitle() { - return ""; -} - -void NativeWindowAura::FlashFrame(bool flash) { -} - -void NativeWindowAura::SetSkipTaskbar(bool skip) { -} - -void NativeWindowAura::SetKiosk(bool kiosk) { -} - -bool NativeWindowAura::IsKiosk() { - return false; -} - -gfx::NativeWindow NativeWindowAura::GetNativeWindow() { - return NULL; -} - -void NativeWindowAura::UpdateDraggableRegions( - const std::vector& regions) { -} - -// static -NativeWindow* NativeWindow::Create(content::WebContents* web_contents, - const mate::Dictionary& options) { - return new NativeWindowAura(web_contents, options); -} - -} // namespace atom diff --git a/atom/browser/native_window_gtk.cc b/atom/browser/native_window_gtk.cc deleted file mode 100644 index 6fb4b5fdd47b..000000000000 --- a/atom/browser/native_window_gtk.cc +++ /dev/null @@ -1,617 +0,0 @@ -// Copyright (c) 2014 GitHub, Inc. All rights reserved. -// Use of this source code is governed by the MIT license that can be -// found in the LICENSE file. - -#include "atom/browser/native_window_gtk.h" - -#include -#include - -#include "atom/common/draggable_region.h" -#include "atom/common/options_switches.h" -#include "base/environment.h" -#include "base/nix/xdg_util.h" -#include "chrome/browser/ui/gtk/gtk_window_util.h" -#include "chrome/browser/ui/libgtk2ui/skia_utils_gtk2.h" -#include "content/public/browser/native_web_keyboard_event.h" -#include "content/public/browser/web_contents.h" -#include "content/public/browser/web_contents_view.h" -#include "content/public/common/renderer_preferences.h" -#include "native_mate/dictionary.h" -#include "ui/base/accelerators/platform_accelerator_gtk.h" -#include "ui/base/models/simple_menu_model.h" -#include "ui/base/x/active_window_watcher_x.h" -#include "ui/base/x/x11_util.h" -#include "ui/gfx/font_render_params_linux.h" -#include "ui/gfx/gtk_util.h" -#include "ui/gfx/image/image.h" -#include "ui/gfx/rect.h" - -namespace atom { - -namespace { - -// Dividing GTK's cursor blink cycle time (in milliseconds) by this value yields -// an appropriate value for content::RendererPreferences::caret_blink_interval. -// This matches the logic in the WebKit GTK port. -const double kGtkCursorBlinkCycleFactor = 2000.0; - -// Substract window border's size from window size according to current window -// manager. -void SubstractBorderSize(int* width, int* height) { - scoped_ptr env(base::Environment::Create()); - base::nix::DesktopEnvironment de(base::nix::GetDesktopEnvironment(env.get())); - if (de == base::nix::DESKTOP_ENVIRONMENT_UNITY) { - *width -= 2; - *height -= 29; - } else if (de == base::nix::DESKTOP_ENVIRONMENT_GNOME) { - *width -= 2; - *height -= 33; - } else if (de == base::nix::DESKTOP_ENVIRONMENT_XFCE) { - *width -= 6; - *height -= 27; - } else { - *width -= 2; - *height -= 29; - } -} - -content::RendererPreferencesHintingEnum GetRendererPreferencesHintingEnum( - gfx::FontRenderParams::Hinting hinting) { - switch (hinting) { - case gfx::FontRenderParams::HINTING_NONE: - return content::RENDERER_PREFERENCES_HINTING_NONE; - case gfx::FontRenderParams::HINTING_SLIGHT: - return content::RENDERER_PREFERENCES_HINTING_SLIGHT; - case gfx::FontRenderParams::HINTING_MEDIUM: - return content::RENDERER_PREFERENCES_HINTING_MEDIUM; - case gfx::FontRenderParams::HINTING_FULL: - return content::RENDERER_PREFERENCES_HINTING_FULL; - default: - NOTREACHED() << "Unhandled hinting style " << hinting; - return content::RENDERER_PREFERENCES_HINTING_SYSTEM_DEFAULT; - } -} - -content::RendererPreferencesSubpixelRenderingEnum -GetRendererPreferencesSubpixelRenderingEnum( - gfx::FontRenderParams::SubpixelRendering subpixel_rendering) { - switch (subpixel_rendering) { - case gfx::FontRenderParams::SUBPIXEL_RENDERING_NONE: - return content::RENDERER_PREFERENCES_SUBPIXEL_RENDERING_NONE; - case gfx::FontRenderParams::SUBPIXEL_RENDERING_RGB: - return content::RENDERER_PREFERENCES_SUBPIXEL_RENDERING_RGB; - case gfx::FontRenderParams::SUBPIXEL_RENDERING_BGR: - return content::RENDERER_PREFERENCES_SUBPIXEL_RENDERING_BGR; - case gfx::FontRenderParams::SUBPIXEL_RENDERING_VRGB: - return content::RENDERER_PREFERENCES_SUBPIXEL_RENDERING_VRGB; - case gfx::FontRenderParams::SUBPIXEL_RENDERING_VBGR: - return content::RENDERER_PREFERENCES_SUBPIXEL_RENDERING_VBGR; - default: - NOTREACHED() << "Unhandled subpixel rendering style " - << subpixel_rendering; - return content::RENDERER_PREFERENCES_SUBPIXEL_RENDERING_SYSTEM_DEFAULT; - } -} - -} // namespace - -NativeWindowGtk::NativeWindowGtk(content::WebContents* web_contents, - const mate::Dictionary& options) - : NativeWindow(web_contents, options), - window_(GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL))), - vbox_(gtk_vbox_new(FALSE, 0)), - state_(GDK_WINDOW_STATE_WITHDRAWN), - is_always_on_top_(false), - is_active_(false), - suppress_window_raise_(false), - has_ever_been_shown_(false), - frame_cursor_(NULL) { - gtk_container_add(GTK_CONTAINER(window_), vbox_); - gtk_container_add(GTK_CONTAINER(vbox_), - GetWebContents()->GetView()->GetNativeView()); - - int width = 800, height = 600; - options.Get(switches::kWidth, &width); - options.Get(switches::kHeight, &height); - - bool use_content_size = false; - options.Get(switches::kUseContentSize, &use_content_size); - if (has_frame_ && !use_content_size) - SubstractBorderSize(&width, &height); - - // Force a size allocation so the web page of hidden window can have correct - // value of $(window).width(). - GtkAllocation size = { 0, 0, width, height }; - gtk_widget_show_all(vbox_); - gtk_widget_size_allocate(GTK_WIDGET(window_), &size); - gtk_window_util::SetWindowSize(window_, gfx::Size(width, height)); - - // Create the underlying gdk window. - gtk_widget_realize(GTK_WIDGET(window_)); - - if (icon_) - gtk_window_set_icon(window_, - libgtk2ui::GdkPixbufFromSkBitmap(*icon_->ToSkBitmap())); - - ui::ActiveWindowWatcherX::AddObserver(this); - - // In some (older) versions of compiz, raising top-level windows when they - // are partially off-screen causes them to get snapped back on screen, not - // always even on the current virtual desktop. If we are running under - // compiz, suppress such raises, as they are not necessary in compiz anyway. - if (ui::GuessWindowManager() == ui::WM_COMPIZ) - suppress_window_raise_ = true; - - g_signal_connect(window_, "delete-event", - G_CALLBACK(OnWindowDeleteEventThunk), this); - g_signal_connect(window_, "focus-out-event", - G_CALLBACK(OnFocusOutThunk), this); - g_signal_connect(window_, "focus-in-event", - G_CALLBACK(OnFocusInThunk), this); - g_signal_connect(window_, "window-state-event", - G_CALLBACK(OnWindowStateThunk), this); - - if (!has_frame_) { - gtk_window_set_decorated(window_, false); - - g_signal_connect(window_, "motion-notify-event", - G_CALLBACK(OnMouseMoveEventThunk), this); - g_signal_connect(window_, "button-press-event", - G_CALLBACK(OnButtonPressThunk), this); - } - - SetWebKitColorStyle(); - SetFontRenderering(); -} - -NativeWindowGtk::~NativeWindowGtk() { - CloseImmediately(); -} - -void NativeWindowGtk::Close() { - CloseWebContents(); -} - -void NativeWindowGtk::CloseImmediately() { - if (window_ == NULL) - return; - - NotifyWindowClosed(); - ui::ActiveWindowWatcherX::RemoveObserver(this); - - gtk_widget_destroy(GTK_WIDGET(window_)); - window_ = NULL; -} - -void NativeWindowGtk::Move(const gfx::Rect& pos) { - gtk_window_move(window_, pos.x(), pos.y()); - SetSize(pos.size()); -} - -void NativeWindowGtk::Focus(bool focus) { - if (!IsVisible()) - return; - - if (focus) - gtk_window_present(window_); - else - gdk_window_lower(gtk_widget_get_window(GTK_WIDGET(window_))); -} - -bool NativeWindowGtk::IsFocused() { - if (ui::ActiveWindowWatcherX::WMSupportsActivation()) - return is_active_; - - // This still works even though we don't get the activation notification. - return gtk_window_is_active(window_); -} - -void NativeWindowGtk::Show() { - has_ever_been_shown_ = true; - gtk_widget_show_all(GTK_WIDGET(window_)); -} - -void NativeWindowGtk::Hide() { - gtk_widget_hide(GTK_WIDGET(window_)); -} - -bool NativeWindowGtk::IsVisible() { - return gtk_widget_get_visible(GTK_WIDGET(window_)); -} - -void NativeWindowGtk::Maximize() { - gtk_window_maximize(window_); -} - -void NativeWindowGtk::Unmaximize() { - gtk_window_unmaximize(window_); -} - -void NativeWindowGtk::Minimize() { - gtk_window_iconify(window_); -} - -void NativeWindowGtk::Restore() { - gtk_window_present(window_); -} - -void NativeWindowGtk::SetFullscreen(bool fullscreen) { - if (fullscreen) - gtk_window_fullscreen(window_); - else - gtk_window_unfullscreen(window_); -} - -bool NativeWindowGtk::IsFullscreen() { - return state_ & GDK_WINDOW_STATE_FULLSCREEN; -} - -void NativeWindowGtk::SetSize(const gfx::Size& size) { - // When the window has not been mapped the window size does not include frame. - int width = size.width(); - int height = size.height(); - if (has_frame_ && !has_ever_been_shown_) - SubstractBorderSize(&width, &height); - - gtk_window_util::SetWindowSize(window_, gfx::Size(width, height)); -} - -gfx::Size NativeWindowGtk::GetSize() { - GdkWindow* gdk_window = gtk_widget_get_window(GTK_WIDGET(window_)); - - GdkRectangle frame_extents; - gdk_window_get_frame_extents(gdk_window, &frame_extents); - - return gfx::Size(frame_extents.width, frame_extents.height); -} - -void NativeWindowGtk::SetContentSize(const gfx::Size& size) { - if (!has_frame_ || !has_ever_been_shown_) { - gtk_window_util::SetWindowSize(window_, size); - } else { - gfx::Size large = GetSize(); - gfx::Size small = GetContentSize(); - gfx::Size target(size.width() + large.width() - small.width(), - size.height() + large.height() - small.height()); - gtk_window_util::SetWindowSize(window_, target); - } -} - -gfx::Size NativeWindowGtk::GetContentSize() { - gint width, height; - gtk_window_get_size(window_, &width, &height); - return gfx::Size(width, height); -} - -void NativeWindowGtk::SetMinimumSize(const gfx::Size& size) { - minimum_size_ = size; - - GdkGeometry geometry = { 0 }; - geometry.min_width = size.width(); - geometry.min_height = size.height(); - int hints = GDK_HINT_POS | GDK_HINT_MIN_SIZE; - gtk_window_set_geometry_hints( - window_, GTK_WIDGET(window_), &geometry, (GdkWindowHints)hints); -} - -gfx::Size NativeWindowGtk::GetMinimumSize() { - return minimum_size_; -} - -void NativeWindowGtk::SetMaximumSize(const gfx::Size& size) { - maximum_size_ = size; - - GdkGeometry geometry = { 0 }; - geometry.max_width = size.width(); - geometry.max_height = size.height(); - int hints = GDK_HINT_POS | GDK_HINT_MAX_SIZE; - gtk_window_set_geometry_hints( - window_, GTK_WIDGET(window_), &geometry, (GdkWindowHints)hints); -} - -gfx::Size NativeWindowGtk::GetMaximumSize() { - return maximum_size_; -} - -void NativeWindowGtk::SetResizable(bool resizable) { - // Should request widget size after setting unresizable, otherwise the - // window will shrink to a very small size. - if (!IsResizable() || !has_ever_been_shown_) { - gint width, height; - gtk_window_get_size(window_, &width, &height); - gtk_widget_set_size_request(GTK_WIDGET(window_), width, height); - } - - gtk_window_set_resizable(window_, resizable); -} - -bool NativeWindowGtk::IsResizable() { - return gtk_window_get_resizable(window_); -} - -void NativeWindowGtk::SetAlwaysOnTop(bool top) { - is_always_on_top_ = top; - gtk_window_set_keep_above(window_, top ? TRUE : FALSE); -} - -bool NativeWindowGtk::IsAlwaysOnTop() { - return is_always_on_top_; -} - -void NativeWindowGtk::Center() { - gtk_window_set_position(window_, GTK_WIN_POS_CENTER); -} - -void NativeWindowGtk::SetPosition(const gfx::Point& position) { - gtk_window_move(window_, position.x(), position.y()); -} - -gfx::Point NativeWindowGtk::GetPosition() { - GdkWindow* gdk_window = gtk_widget_get_window(GTK_WIDGET(window_)); - - GdkRectangle frame_extents; - gdk_window_get_frame_extents(gdk_window, &frame_extents); - - return gfx::Point(frame_extents.x, frame_extents.y); -} - -void NativeWindowGtk::SetTitle(const std::string& title) { - gtk_window_set_title(window_, title.c_str()); -} - -std::string NativeWindowGtk::GetTitle() { - return gtk_window_get_title(window_); -} - -void NativeWindowGtk::FlashFrame(bool flash) { - gtk_window_set_urgency_hint(window_, flash); -} - -void NativeWindowGtk::SetSkipTaskbar(bool skip) { - gtk_window_set_skip_taskbar_hint(window_, skip); - gtk_window_set_skip_pager_hint(window_, skip); -} - -void NativeWindowGtk::SetKiosk(bool kiosk) { - SetFullscreen(kiosk); -} - -bool NativeWindowGtk::IsKiosk() { - return IsFullscreen(); -} - -gfx::NativeWindow NativeWindowGtk::GetNativeWindow() { - return window_; -} - -void NativeWindowGtk::SetMenu(ui::MenuModel* menu_model) { - menu_.reset(new ::MenuGtk(this, menu_model, true)); - gtk_box_pack_start(GTK_BOX(vbox_), menu_->widget(), FALSE, FALSE, 0); - gtk_box_reorder_child(GTK_BOX(vbox_), menu_->widget(), 0); - gtk_widget_show_all(vbox_); - RegisterAccelerators(); -} - -void NativeWindowGtk::UpdateDraggableRegions( - const std::vector& regions) { - // Draggable region is not supported for non-frameless window. - if (has_frame_) - return; - - draggable_region_.reset(new SkRegion); - - // By default, the whole window is non-draggable. We need to explicitly - // include those draggable regions. - for (std::vector::const_iterator iter = - regions.begin(); - iter != regions.end(); ++iter) { - const DraggableRegion& region = *iter; - draggable_region_->op( - region.bounds.x(), - region.bounds.y(), - region.bounds.right(), - region.bounds.bottom(), - region.draggable ? SkRegion::kUnion_Op : SkRegion::kDifference_Op); - } -} - -void NativeWindowGtk::HandleKeyboardEvent( - content::WebContents*, - const content::NativeWebKeyboardEvent& event) { - if (event.type == blink::WebInputEvent::RawKeyDown) { - GdkEventKey* os_event = reinterpret_cast(event.os_event); - ui::Accelerator accelerator = ui::AcceleratorForGdkKeyCodeAndModifier( - os_event->keyval, static_cast(os_event->state)); - accelerator_util::TriggerAcceleratorTableCommand(&accelerator_table_, - accelerator); - } -} - -void NativeWindowGtk::ActiveWindowChanged(GdkWindow* active_window) { - is_active_ = gtk_widget_get_window(GTK_WIDGET(window_)) == active_window; -} - -void NativeWindowGtk::RegisterAccelerators() { - DCHECK(menu_); - accelerator_table_.clear(); - accelerator_util::GenerateAcceleratorTable(&accelerator_table_, - menu_->model()); -} - -void NativeWindowGtk::SetWebKitColorStyle() { - content::RendererPreferences* prefs = - GetWebContents()->GetMutableRendererPrefs(); - GtkStyle* frame_style = gtk_rc_get_style(GTK_WIDGET(window_)); - prefs->focus_ring_color = - libgtk2ui::GdkColorToSkColor(frame_style->bg[GTK_STATE_SELECTED]); - prefs->thumb_active_color = SkColorSetRGB(244, 244, 244); - prefs->thumb_inactive_color = SkColorSetRGB(234, 234, 234); - prefs->track_color = SkColorSetRGB(211, 211, 211); - - GtkWidget* url_entry = gtk_entry_new(); - GtkStyle* entry_style = gtk_rc_get_style(url_entry); - prefs->active_selection_bg_color = - libgtk2ui::GdkColorToSkColor(entry_style->base[GTK_STATE_SELECTED]); - prefs->active_selection_fg_color = - libgtk2ui::GdkColorToSkColor(entry_style->text[GTK_STATE_SELECTED]); - prefs->inactive_selection_bg_color = - libgtk2ui::GdkColorToSkColor(entry_style->base[GTK_STATE_ACTIVE]); - prefs->inactive_selection_fg_color = - libgtk2ui::GdkColorToSkColor(entry_style->text[GTK_STATE_ACTIVE]); - gtk_widget_destroy(url_entry); - - const base::TimeDelta cursor_blink_time = gfx::GetCursorBlinkCycle(); - prefs->caret_blink_interval = - cursor_blink_time.InMilliseconds() ? - cursor_blink_time.InMilliseconds() / kGtkCursorBlinkCycleFactor : - 0; -} - -void NativeWindowGtk::SetFontRenderering() { - content::RendererPreferences* prefs = - GetWebContents()->GetMutableRendererPrefs(); - const gfx::FontRenderParams& params = gfx::GetDefaultWebKitFontRenderParams(); - prefs->should_antialias_text = params.antialiasing; - prefs->use_subpixel_positioning = params.subpixel_positioning; - prefs->hinting = GetRendererPreferencesHintingEnum(params.hinting); - prefs->use_autohinter = params.autohinter; - prefs->use_bitmaps = params.use_bitmaps; - prefs->subpixel_rendering = - GetRendererPreferencesSubpixelRenderingEnum(params.subpixel_rendering); -} - -bool NativeWindowGtk::IsMaximized() const { - return state_ & GDK_WINDOW_STATE_MAXIMIZED; -} - -bool NativeWindowGtk::GetWindowEdge(int x, int y, GdkWindowEdge* edge) { - if (has_frame_) - return false; - - if (IsMaximized() || IsFullscreen()) - return false; - - return gtk_window_util::GetWindowEdge(GetSize(), 0, x, y, edge); -} - -gboolean NativeWindowGtk::OnWindowDeleteEvent(GtkWidget* widget, - GdkEvent* event) { - Close(); - return TRUE; -} - -gboolean NativeWindowGtk::OnFocusIn(GtkWidget* window, GdkEventFocus*) { - NotifyWindowFocus(); - return FALSE; -} - -gboolean NativeWindowGtk::OnFocusOut(GtkWidget* window, GdkEventFocus*) { - NotifyWindowBlur(); - return FALSE; -} - -gboolean NativeWindowGtk::OnWindowState(GtkWidget* window, - GdkEventWindowState* event) { - state_ = event->new_window_state; - return FALSE; -} - -gboolean NativeWindowGtk::OnMouseMoveEvent(GtkWidget* widget, - GdkEventMotion* event) { - if (has_frame_) { - // Reset the cursor. - if (frame_cursor_) { - frame_cursor_ = NULL; - gdk_window_set_cursor(gtk_widget_get_window(GTK_WIDGET(window_)), NULL); - } - return FALSE; - } - - if (!IsResizable()) - return FALSE; - - // Update the cursor if we're on the custom frame border. - GdkWindowEdge edge; - bool has_hit_edge = GetWindowEdge(static_cast(event->x), - static_cast(event->y), &edge); - GdkCursorType new_cursor = GDK_LAST_CURSOR; - if (has_hit_edge) - new_cursor = gtk_window_util::GdkWindowEdgeToGdkCursorType(edge); - - GdkCursorType last_cursor = GDK_LAST_CURSOR; - if (frame_cursor_) - last_cursor = frame_cursor_->type; - - if (last_cursor != new_cursor) { - frame_cursor_ = has_hit_edge ? gfx::GetCursor(new_cursor) : NULL; - gdk_window_set_cursor(gtk_widget_get_window(GTK_WIDGET(window_)), - frame_cursor_); - } - return FALSE; -} - -gboolean NativeWindowGtk::OnButtonPress(GtkWidget* widget, - GdkEventButton* event) { - DCHECK(!has_frame_); - // Make the button press coordinate relative to the browser window. - int win_x, win_y; - GdkWindow* gdk_window = gtk_widget_get_window(GTK_WIDGET(window_)); - gdk_window_get_origin(gdk_window, &win_x, &win_y); - - GdkWindowEdge edge; - gfx::Point point(static_cast(event->x_root - win_x), - static_cast(event->y_root - win_y)); - bool has_hit_edge = IsResizable() && - GetWindowEdge(point.x(), point.y(), &edge); - bool has_hit_titlebar = - draggable_region_ && draggable_region_->contains(event->x, event->y); - - if (event->button == 1) { - if (GDK_BUTTON_PRESS == event->type) { - // Raise the window after a click on either the titlebar or the border to - // match the behavior of most window managers, unless that behavior has - // been suppressed. - if ((has_hit_titlebar || has_hit_edge) && !suppress_window_raise_) - gdk_window_raise(GTK_WIDGET(widget)->window); - - if (has_hit_edge) { - gtk_window_begin_resize_drag(window_, edge, event->button, - static_cast(event->x_root), - static_cast(event->y_root), - event->time); - return TRUE; - } else if (has_hit_titlebar) { - GdkRectangle window_bounds = {0}; - gdk_window_get_frame_extents(gdk_window, &window_bounds); - gfx::Rect bounds(window_bounds.x, window_bounds.y, - window_bounds.width, window_bounds.height); - return gtk_window_util::HandleTitleBarLeftMousePress( - window_, bounds, event); - } - } else if (GDK_2BUTTON_PRESS == event->type) { - if (has_hit_titlebar && IsResizable()) { - // Maximize/restore on double click. - if (IsMaximized()) - gtk_window_unmaximize(window_); - else - gtk_window_maximize(window_); - return TRUE; - } - } - } else if (event->button == 2) { - if (has_hit_titlebar || has_hit_edge) - gdk_window_lower(gdk_window); - return TRUE; - } - - return FALSE; -} - -// static -NativeWindow* NativeWindow::Create(content::WebContents* web_contents, - const mate::Dictionary& options) { - return new NativeWindowGtk(web_contents, options); -} - -} // namespace atom diff --git a/atom/browser/native_window_gtk.h b/atom/browser/native_window_gtk.h deleted file mode 100644 index 61dcdf92e9d1..000000000000 --- a/atom/browser/native_window_gtk.h +++ /dev/null @@ -1,157 +0,0 @@ -// Copyright (c) 2014 GitHub, Inc. All rights reserved. -// Use of this source code is governed by the MIT license that can be -// found in the LICENSE file. - -#ifndef ATOM_BROWSER_NATIVE_WINDOW_GTK_H_ -#define ATOM_BROWSER_NATIVE_WINDOW_GTK_H_ - -#include - -#include -#include - -#include "atom/browser/native_window.h" -#include "atom/browser/ui/accelerator_util.h" -#include "chrome/browser/ui/gtk/menu_gtk.h" -#include "third_party/skia/include/core/SkRegion.h" -#include "ui/base/accelerators/accelerator.h" -#include "ui/base/gtk/gtk_signal.h" -#include "ui/base/x/active_window_watcher_x_observer.h" -#include "ui/gfx/size.h" - -namespace atom { - -class NativeWindowGtk : public NativeWindow, - public MenuGtk::Delegate, - public ui::ActiveWindowWatcherXObserver { - public: - explicit NativeWindowGtk(content::WebContents* web_contents, - const mate::Dictionary& options); - virtual ~NativeWindowGtk(); - - // NativeWindow implementation. - virtual void Close() OVERRIDE; - virtual void CloseImmediately() OVERRIDE; - virtual void Move(const gfx::Rect& pos) OVERRIDE; - virtual void Focus(bool focus) OVERRIDE; - virtual bool IsFocused() OVERRIDE; - virtual void Show() OVERRIDE; - virtual void Hide() OVERRIDE; - virtual bool IsVisible() OVERRIDE; - virtual void Maximize() OVERRIDE; - virtual void Unmaximize() OVERRIDE; - virtual void Minimize() OVERRIDE; - virtual void Restore() OVERRIDE; - virtual void SetFullscreen(bool fullscreen) OVERRIDE; - virtual bool IsFullscreen() OVERRIDE; - virtual void SetSize(const gfx::Size& size) OVERRIDE; - virtual gfx::Size GetSize() OVERRIDE; - virtual void SetContentSize(const gfx::Size& size) OVERRIDE; - virtual gfx::Size GetContentSize() OVERRIDE; - virtual void SetMinimumSize(const gfx::Size& size) OVERRIDE; - virtual gfx::Size GetMinimumSize() OVERRIDE; - virtual void SetMaximumSize(const gfx::Size& size) OVERRIDE; - virtual gfx::Size GetMaximumSize() OVERRIDE; - virtual void SetResizable(bool resizable) OVERRIDE; - virtual bool IsResizable() OVERRIDE; - virtual void SetAlwaysOnTop(bool top) OVERRIDE; - virtual bool IsAlwaysOnTop() OVERRIDE; - virtual void Center() OVERRIDE; - virtual void SetPosition(const gfx::Point& position) OVERRIDE; - virtual gfx::Point GetPosition() OVERRIDE; - virtual void SetTitle(const std::string& title) OVERRIDE; - virtual std::string GetTitle() OVERRIDE; - virtual void FlashFrame(bool flash) OVERRIDE; - virtual void SetSkipTaskbar(bool skip) OVERRIDE; - virtual void SetKiosk(bool kiosk) OVERRIDE; - virtual bool IsKiosk() OVERRIDE; - virtual gfx::NativeWindow GetNativeWindow() OVERRIDE; - - // Set the native window menu. - void SetMenu(ui::MenuModel* menu_model); - - protected: - virtual void UpdateDraggableRegions( - const std::vector& regions) OVERRIDE; - - // Overridden from content::WebContentsDelegate: - virtual void HandleKeyboardEvent( - content::WebContents*, - const content::NativeWebKeyboardEvent&) OVERRIDE; - - // Overridden from ActiveWindowWatcherXObserver. - virtual void ActiveWindowChanged(GdkWindow* active_window) OVERRIDE; - - private: - // Register accelerators supported by the menu model. - void RegisterAccelerators(); - - // Set WebKit's style from current theme. - void SetWebKitColorStyle(); - - // Set how font is renderered. - void SetFontRenderering(); - - // Whether window is maximized. - bool IsMaximized() const; - - // If the point (|x|, |y|) is within the resize border area of the window, - // returns true and sets |edge| to the appropriate GdkWindowEdge value. - // Otherwise, returns false. - bool GetWindowEdge(int x, int y, GdkWindowEdge* edge); - - CHROMEGTK_CALLBACK_1(NativeWindowGtk, gboolean, OnWindowDeleteEvent, - GdkEvent*); - CHROMEGTK_CALLBACK_1(NativeWindowGtk, gboolean, OnFocusIn, GdkEventFocus*); - CHROMEGTK_CALLBACK_1(NativeWindowGtk, gboolean, OnFocusOut, GdkEventFocus*); - CHROMEGTK_CALLBACK_1(NativeWindowGtk, gboolean, OnWindowState, - GdkEventWindowState*); - - // Mouse move and mouse button press callbacks. - CHROMEGTK_CALLBACK_1(NativeWindowGtk, gboolean, OnMouseMoveEvent, - GdkEventMotion*); - CHROMEGTK_CALLBACK_1(NativeWindowGtk, gboolean, OnButtonPress, - GdkEventButton*); - - GtkWindow* window_; - GtkWidget* vbox_; - - GdkWindowState state_; - bool is_always_on_top_; - gfx::Size minimum_size_; - gfx::Size maximum_size_; - - // The region is treated as title bar, can be dragged to move and double - // clicked to maximize. - scoped_ptr draggable_region_; - - // True if the window manager thinks the window is active. It could happpen - // that the WM thinks a window is active but it's actually not, like when - // showing a context menu. - bool is_active_; - - // If true, don't call gdk_window_raise() when we get a click in the title - // bar or window border. This is to work around a compiz bug. - bool suppress_window_raise_; - - // True if the window has been visible for once, on Linux the window frame - // would // only be considered as part of the window untill the window has - // been shown, so we need it to correctly set the window size. - bool has_ever_been_shown_; - - // The current window cursor. We set it to a resize cursor when over the - // custom frame border. We set it to NULL if we want the default cursor. - GdkCursor* frame_cursor_; - - // The window menu. - scoped_ptr menu_; - - // Map from accelerator to menu item's command id. - accelerator_util::AcceleratorTable accelerator_table_; - - DISALLOW_COPY_AND_ASSIGN(NativeWindowGtk); -}; - -} // namespace atom - -#endif // ATOM_BROWSER_NATIVE_WINDOW_GTK_H_ diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc new file mode 100644 index 000000000000..97ec074c64dc --- /dev/null +++ b/atom/browser/native_window_views.cc @@ -0,0 +1,295 @@ +// Copyright (c) 2014 GitHub, Inc. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/browser/native_window_views.h" + +#include +#include + +#include "atom/common/options_switches.h" +#include "base/strings/utf_string_conversions.h" +#include "content/public/browser/web_contents_view.h" +#include "native_mate/dictionary.h" +#include "ui/gfx/image/image.h" +#include "ui/gfx/image/image_skia.h" +#include "ui/views/background.h" +#include "ui/views/controls/webview/webview.h" +#include "ui/views/layout/fill_layout.h" +#include "ui/views/window/client_view.h" +#include "ui/views/window/native_frame_view.h" +#include "ui/views/widget/widget.h" + +namespace atom { + +namespace { + +class NativeWindowClientView : public views::ClientView { + public: + NativeWindowClientView(views::Widget* widget, + NativeWindowViews* contents_view) + : views::ClientView(widget, contents_view) { + } + virtual ~NativeWindowClientView() {} + + virtual bool CanClose() OVERRIDE { + static_cast(contents_view())->CloseWebContents(); + return false; + } + + private: + DISALLOW_COPY_AND_ASSIGN(NativeWindowClientView); +}; + +} // namespace + +NativeWindowViews::NativeWindowViews(content::WebContents* web_contents, + const mate::Dictionary& options) + : NativeWindow(web_contents, options), + window_(new views::Widget), + web_view_(new views::WebView(web_contents->GetBrowserContext())), + resizable_(true) { + options.Get(switches::kResizable, &resizable_); + options.Get(switches::kTitle, &title_); + + views::Widget::InitParams params; + params.delegate = this; + params.top_level = true; + params.remove_standard_frame = !has_frame_; + window_->Init(params); + + int width = 800, height = 600; + options.Get(switches::kWidth, &width); + options.Get(switches::kHeight, &height); + window_->CenterWindow(gfx::Size(width, height)); + + SetLayoutManager(new views::FillLayout); + set_background(views::Background::CreateStandardPanelBackground()); + + web_view_->SetWebContents(web_contents); +} + +NativeWindowViews::~NativeWindowViews() { +} + +void NativeWindowViews::Close() { + window_->Close(); +} + +void NativeWindowViews::CloseImmediately() { + window_->CloseNow(); +} + +void NativeWindowViews::Move(const gfx::Rect& bounds) { + window_->SetBounds(bounds); +} + +void NativeWindowViews::Focus(bool focus) { + if (focus) + window_->Activate(); + else + window_->Deactivate(); +} + +bool NativeWindowViews::IsFocused() { + return window_->IsActive(); +} + +void NativeWindowViews::Show() { + window_->Show(); +} + +void NativeWindowViews::Hide() { + window_->Hide(); +} + +bool NativeWindowViews::IsVisible() { + return window_->IsVisible(); +} + +void NativeWindowViews::Maximize() { + window_->Maximize(); +} + +void NativeWindowViews::Unmaximize() { + window_->Restore(); +} + +void NativeWindowViews::Minimize() { + window_->Minimize(); +} + +void NativeWindowViews::Restore() { + window_->Restore(); +} + +void NativeWindowViews::SetFullscreen(bool fullscreen) { + window_->SetFullscreen(fullscreen); +} + +bool NativeWindowViews::IsFullscreen() { + return window_->IsFullscreen(); +} + +void NativeWindowViews::SetSize(const gfx::Size& size) { + window_->SetSize(size); +} + +gfx::Size NativeWindowViews::GetSize() { + return window_->GetWindowBoundsInScreen().size(); +} + +void NativeWindowViews::SetContentSize(const gfx::Size& size) { + // FIXME + SetSize(size); +} + +gfx::Size NativeWindowViews::GetContentSize() { + // FIXME + return GetSize(); +} + +void NativeWindowViews::SetMinimumSize(const gfx::Size& size) { + minimum_size_ = size; +} + +gfx::Size NativeWindowViews::GetMinimumSize() { + return minimum_size_; +} + +void NativeWindowViews::SetMaximumSize(const gfx::Size& size) { + maximum_size_ = size; +} + +gfx::Size NativeWindowViews::GetMaximumSize() { + return maximum_size_; +} + +void NativeWindowViews::SetResizable(bool resizable) { + // FIXME + resizable_ = resizable; +} + +bool NativeWindowViews::IsResizable() { + return resizable_; +} + +void NativeWindowViews::SetAlwaysOnTop(bool top) { + window_->SetAlwaysOnTop(top); +} + +bool NativeWindowViews::IsAlwaysOnTop() { + // FIXME + return false; +} + +void NativeWindowViews::Center() { + window_->CenterWindow(GetSize()); +} + +void NativeWindowViews::SetPosition(const gfx::Point& position) { + window_->SetBounds(gfx::Rect(position, GetSize())); +} + +gfx::Point NativeWindowViews::GetPosition() { + return window_->GetWindowBoundsInScreen().origin(); +} + +void NativeWindowViews::SetTitle(const std::string& title) { + title_ = title; + window_->UpdateWindowTitle(); +} + +std::string NativeWindowViews::GetTitle() { + return title_; +} + +void NativeWindowViews::FlashFrame(bool flash) { + window_->FlashFrame(flash); +} + +void NativeWindowViews::SetSkipTaskbar(bool skip) { + // FIXME +} + +void NativeWindowViews::SetKiosk(bool kiosk) { + SetFullscreen(kiosk); +} + +bool NativeWindowViews::IsKiosk() { + return IsFullscreen(); +} + +gfx::NativeWindow NativeWindowViews::GetNativeWindow() { + return window_->GetNativeWindow(); +} + +void NativeWindowViews::UpdateDraggableRegions( + const std::vector& regions) { +} + +void NativeWindowViews::ViewHierarchyChanged( + const ViewHierarchyChangedDetails& details) { + if (details.is_add && details.child == this) { + AddChildView(web_view_); + } +} + +void NativeWindowViews::DeleteDelegate() { + NotifyWindowClosed(); +} + +views::View* NativeWindowViews::GetInitiallyFocusedView() { + return web_view_; +} + +bool NativeWindowViews::CanResize() const { + return resizable_; +} + +bool NativeWindowViews::CanMaximize() const { + return resizable_; +} + +base::string16 NativeWindowViews::GetWindowTitle() const { + return base::UTF8ToUTF16(title_); +} + +bool NativeWindowViews::ShouldHandleSystemCommands() const { + return true; +} + +gfx::ImageSkia NativeWindowViews::GetWindowAppIcon() { + if (icon_) + return *(icon_->ToImageSkia()); + else + return gfx::ImageSkia(); +} + +gfx::ImageSkia NativeWindowViews::GetWindowIcon() { + return GetWindowAppIcon(); +} + +views::Widget* NativeWindowViews::GetWidget() { + return window_.get(); +} + +const views::Widget* NativeWindowViews::GetWidget() const { + return window_.get(); +} + +views::View* NativeWindowViews::GetContentsView() { + return this; +} + +views::ClientView* NativeWindowViews::CreateClientView(views::Widget* widget) { + return new NativeWindowClientView(widget, this); +} + +// static +NativeWindow* NativeWindow::Create(content::WebContents* web_contents, + const mate::Dictionary& options) { + return new NativeWindowViews(web_contents, options); +} + +} // namespace atom diff --git a/atom/browser/native_window_aura.h b/atom/browser/native_window_views.h similarity index 58% rename from atom/browser/native_window_aura.h rename to atom/browser/native_window_views.h index dffeb11be4c1..075f3338fa5e 100644 --- a/atom/browser/native_window_aura.h +++ b/atom/browser/native_window_views.h @@ -2,20 +2,29 @@ // Use of this source code is governed by the MIT license that can be // found in the LICENSE file. -#ifndef ATOM_BROWSER_NATIVE_WINDOW_AURA_H_ -#define ATOM_BROWSER_NATIVE_WINDOW_AURA_H_ +#ifndef ATOM_BROWSER_NATIVE_WINDOW_VIEWS_H_ +#define ATOM_BROWSER_NATIVE_WINDOW_VIEWS_H_ #include "atom/browser/native_window.h" -#include "ui/aura/window_tree_host.h" +#include +#include + +#include "ui/views/widget/widget_delegate.h" + +namespace views { +class WebView; +class Widget; +} namespace atom { -class NativeWindowAura : public NativeWindow { +class NativeWindowViews : public NativeWindow, + public views::WidgetDelegateView { public: - explicit NativeWindowAura(content::WebContents* web_contents, + explicit NativeWindowViews(content::WebContents* web_contents, const mate::Dictionary& options); - virtual ~NativeWindowAura(); + virtual ~NativeWindowViews(); // NativeWindow: virtual void Close() OVERRIDE; @@ -60,11 +69,35 @@ class NativeWindowAura : public NativeWindow { virtual void UpdateDraggableRegions( const std::vector& regions) OVERRIDE; - scoped_ptr host_; + // views::View: + virtual void ViewHierarchyChanged( + const ViewHierarchyChangedDetails& details) OVERRIDE; - DISALLOW_COPY_AND_ASSIGN(NativeWindowAura); + // views::WidgetDelegate: + virtual void DeleteDelegate() OVERRIDE; + virtual views::View* GetInitiallyFocusedView() OVERRIDE; + virtual bool CanResize() const OVERRIDE; + virtual bool CanMaximize() const OVERRIDE; + virtual base::string16 GetWindowTitle() const OVERRIDE; + virtual bool ShouldHandleSystemCommands() const OVERRIDE; + virtual gfx::ImageSkia GetWindowAppIcon() OVERRIDE; + virtual gfx::ImageSkia GetWindowIcon() OVERRIDE; + virtual views::Widget* GetWidget() OVERRIDE; + virtual const views::Widget* GetWidget() const OVERRIDE; + virtual views::View* GetContentsView() OVERRIDE; + virtual views::ClientView* CreateClientView(views::Widget* widget) OVERRIDE; + + scoped_ptr window_; + views::WebView* web_view_; // managed by window_. + + bool resizable_; + std::string title_; + gfx::Size minimum_size_; + gfx::Size maximum_size_; + + DISALLOW_COPY_AND_ASSIGN(NativeWindowViews); }; } // namespace atom -#endif // ATOM_BROWSER_NATR_NATIVE_WINDOW_AURA_H_ +#endif // ATOM_BROWSER_NATIVE_WINDOW_VIEWS_H_ diff --git a/atom/browser/ui/file_dialog_gtk.cc b/atom/browser/ui/file_dialog_gtk.cc index 7973fff81ba9..10f5a577b031 100644 --- a/atom/browser/ui/file_dialog_gtk.cc +++ b/atom/browser/ui/file_dialog_gtk.cc @@ -27,7 +27,6 @@ class FileChooserDialog { else if (action == GTK_FILE_CHOOSER_ACTION_OPEN) confirm_text = GTK_STOCK_OPEN; - // GtkWindow* window = parent_window ? parent_window->GetNativeWindow() : NULL; GtkWindow* window = NULL; dialog_ = gtk_file_chooser_dialog_new( title.c_str(), diff --git a/atom/browser/ui/message_box_gtk.cc b/atom/browser/ui/message_box_gtk.cc deleted file mode 100644 index 3793dad33992..000000000000 --- a/atom/browser/ui/message_box_gtk.cc +++ /dev/null @@ -1,136 +0,0 @@ -// Copyright (c) 2014 GitHub, Inc. All rights reserved. -// Use of this source code is governed by the MIT license that can be -// found in the LICENSE file. - -#include "atom/browser/ui/message_box.h" - -#include "atom/browser/native_window.h" -#include "base/callback.h" -#include "base/strings/string_util.h" -#include "chrome/browser/ui/gtk/gtk_util.h" -#include "ui/base/gtk/gtk_signal.h" - -namespace atom { - -namespace { - -class MessageBox { - public: - MessageBox(NativeWindow* parent_window, - MessageBoxType type, - const std::vector& buttons, - const std::string& title, - const std::string& message, - const std::string& detail) - : cancel_id_(0), - dialog_scope_(new NativeWindow::DialogScope(parent_window)) { - // GtkWindow* window = parent_window ? parent_window->GetNativeWindow() : NULL; - GtkWindow* window = NULL; - dialog_ = gtk_dialog_new_with_buttons( - title.c_str(), - window, - static_cast(GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR), - NULL); - - for (size_t i = 0; i < buttons.size(); ++i) - gtk_dialog_add_button(GTK_DIALOG(dialog_), - TranslateToStock(i, buttons[i]), - i); - - GtkWidget* content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog_)); - GtkWidget* message_label = gtk_util::CreateBoldLabel(message); - gtk_util::LeftAlignMisc(message_label); - gtk_box_pack_start(GTK_BOX(content_area), message_label, FALSE, FALSE, 0); - GtkWidget* detail_label = gtk_label_new(detail.c_str()); - gtk_util::LeftAlignMisc(detail_label); - gtk_box_pack_start(GTK_BOX(content_area), detail_label, FALSE, FALSE, 0); - - gtk_window_set_resizable(GTK_WINDOW(dialog_), FALSE); - } - - ~MessageBox() { - gtk_widget_destroy(dialog_); - } - - const char* TranslateToStock(int id, const std::string& text) { - if (LowerCaseEqualsASCII(text, "cancel")) { - cancel_id_ = id; - return GTK_STOCK_CANCEL; - } else if (LowerCaseEqualsASCII(text, "no")) { - cancel_id_ = id; - return GTK_STOCK_NO; - } else if (LowerCaseEqualsASCII(text, "ok")) { - return GTK_STOCK_OK; - } else if (LowerCaseEqualsASCII(text, "yes")) { - return GTK_STOCK_YES; - } else { - return text.c_str(); - } - } - - void RunAsynchronous(const MessageBoxCallback& callback) { - callback_ = callback; - g_signal_connect(dialog_, "delete-event", - G_CALLBACK(gtk_widget_hide_on_delete), NULL); - g_signal_connect(dialog_, "response", - G_CALLBACK(OnResponseDialogThunk), this); - gtk_widget_show_all(dialog_); - } - - CHROMEGTK_CALLBACK_1(MessageBox, void, OnResponseDialog, int); - - GtkWidget* dialog() const { return dialog_; } - int cancel_id() const { return cancel_id_; } - - private: - GtkWidget* dialog_; - MessageBoxCallback callback_; - - scoped_ptr dialog_scope_; - - // The id to return when the dialog is closed without pressing buttons. - int cancel_id_; - - DISALLOW_COPY_AND_ASSIGN(MessageBox); -}; - -void MessageBox::OnResponseDialog(GtkWidget* widget, int response) { - gtk_widget_hide_all(dialog_); - - if (response < 0) - callback_.Run(cancel_id_); - else - callback_.Run(response); - delete this; -} - -} // namespace - -int ShowMessageBox(NativeWindow* parent_window, - MessageBoxType type, - const std::vector& buttons, - const std::string& title, - const std::string& message, - const std::string& detail) { - MessageBox message_box(parent_window, type, buttons, title, message, detail); - gtk_widget_show_all(message_box.dialog()); - int response = gtk_dialog_run(GTK_DIALOG(message_box.dialog())); - if (response < 0) - return message_box.cancel_id(); - else - return response; -} - -void ShowMessageBox(NativeWindow* parent_window, - MessageBoxType type, - const std::vector& buttons, - const std::string& title, - const std::string& message, - const std::string& detail, - const MessageBoxCallback& callback) { - MessageBox* message_box = new MessageBox( - parent_window, type, buttons, title, message, detail); - message_box->RunAsynchronous(callback); -} - -} // namespace atom diff --git a/atom/browser/ui/message_box_win.cc b/atom/browser/ui/message_box_views.cc similarity index 88% rename from atom/browser/ui/message_box_win.cc rename to atom/browser/ui/message_box_views.cc index d180d9edb38c..4168d794b6c7 100644 --- a/atom/browser/ui/message_box_win.cc +++ b/atom/browser/ui/message_box_views.cc @@ -9,8 +9,9 @@ #include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/strings/string_util.h" +#include "base/strings/string16.h" #include "base/strings/utf_string_conversions.h" -#include "skia/ext/skia_utils_win.h" +#include "ui/views/background.h" #include "ui/views/controls/button/label_button.h" #include "ui/views/controls/message_box_view.h" #include "ui/views/layout/grid_layout.h" @@ -26,8 +27,7 @@ namespace { // conflict with other groups that could be in the dialog content. const int kButtonGroup = 1127; -class MessageDialog : public base::MessageLoop::Dispatcher, - public views::WidgetDelegate, +class MessageDialog : public views::WidgetDelegate, public views::View, public views::ButtonListener { public: @@ -39,7 +39,7 @@ class MessageDialog : public base::MessageLoop::Dispatcher, const std::string& detail); virtual ~MessageDialog(); - void Show(); + void Show(base::RunLoop* run_loop = NULL); int GetResult() const; @@ -49,9 +49,6 @@ class MessageDialog : public base::MessageLoop::Dispatcher, } private: - // Overridden from MessageLoop::Dispatcher: - virtual bool Dispatch(const base::NativeEvent& event) OVERRIDE; - // Overridden from views::WidgetDelegate: virtual base::string16 GetWindowTitle() const; virtual void WindowClosing() OVERRIDE; @@ -76,6 +73,7 @@ class MessageDialog : public base::MessageLoop::Dispatcher, base::string16 title_; views::Widget* widget_; views::MessageBoxView* message_box_view_; + base::RunLoop* run_loop_; scoped_ptr dialog_scope_; std::vector buttons_; MessageBoxCallback callback_; @@ -95,24 +93,27 @@ MessageDialog::MessageDialog(NativeWindow* parent_window, : should_close_(false), delete_on_close_(false), result_(-1), - title_(UTF8ToUTF16(title)), + title_(base::UTF8ToUTF16(title)), widget_(NULL), message_box_view_(NULL), + run_loop_(NULL), dialog_scope_(new NativeWindow::DialogScope(parent_window)) { DCHECK_GT(buttons.size(), 0u); set_owned_by_client(); + set_background(views::Background::CreateStandardPanelBackground()); - views::MessageBoxView::InitParams params(UTF8ToUTF16(title)); - params.message = UTF8ToUTF16(message + "\n" + detail); + std::string content = message + "\n" + detail; + views::MessageBoxView::InitParams params(base::UTF8ToUTF16(content)); message_box_view_ = new views::MessageBoxView(params); AddChildView(message_box_view_); for (size_t i = 0; i < buttons.size(); ++i) { views::LabelButton* button = new views::LabelButton( - this, UTF8ToUTF16(buttons[i])); + this, base::UTF8ToUTF16(buttons[i])); button->set_tag(i); - button->set_min_size(gfx::Size(60, 20)); - button->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON); + button->set_min_size(gfx::Size(60, 30)); + button->SetStyle(views::Button::STYLE_BUTTON); + button->SetHorizontalAlignment(gfx::ALIGN_CENTER); button->SetGroup(kButtonGroup); buttons_.push_back(button); @@ -129,20 +130,17 @@ MessageDialog::MessageDialog(NativeWindow* parent_window, if (parent_window) widget_params.parent = parent_window->GetNativeWindow(); widget_ = new views::Widget; - widget_->set_frame_type(views::Widget::FRAME_TYPE_FORCE_NATIVE); widget_->Init(widget_params); // Bind to ESC. AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE)); - - set_background(views::Background::CreateSolidBackground( - skia::COLORREFToSkColor(GetSysColor(COLOR_WINDOW)))); } MessageDialog::~MessageDialog() { } -void MessageDialog::Show() { +void MessageDialog::Show(base::RunLoop* run_loop) { + run_loop_ = run_loop; widget_->Show(); } @@ -164,13 +162,7 @@ int MessageDialog::GetResult() const { //////////////////////////////////////////////////////////////////////////////// // MessageDialog, private: -bool MessageDialog::Dispatch(const base::NativeEvent& event) { - TranslateMessage(&event); - DispatchMessage(&event); - return !should_close_; -} - -string16 MessageDialog::GetWindowTitle() const { +base::string16 MessageDialog::GetWindowTitle() const { return title_; } @@ -181,6 +173,8 @@ void MessageDialog::WindowClosing() { if (delete_on_close_) { callback_.Run(GetResult()); base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); + } else if (run_loop_) { + run_loop_->Quit(); } } @@ -269,11 +263,11 @@ int ShowMessageBox(NativeWindow* parent_window, const std::string& message, const std::string& detail) { MessageDialog dialog(parent_window, type, buttons, title, message, detail); - dialog.Show(); { base::MessageLoop::ScopedNestableTaskAllower allow( base::MessageLoopForUI::current()); - base::RunLoop run_loop(&dialog); + base::RunLoop run_loop; + dialog.Show(&run_loop); run_loop.Run(); } diff --git a/atom/common/native_mate_converters/string16_converter.h b/atom/common/native_mate_converters/string16_converter.h index 54f8977a81c8..baa833a09d2b 100644 --- a/atom/common/native_mate_converters/string16_converter.h +++ b/atom/common/native_mate_converters/string16_converter.h @@ -20,6 +20,9 @@ struct Converter { static bool FromV8(v8::Isolate* isolate, v8::Handle val, base::string16* out) { + if (!val->IsString()) + return false; + v8::String::Value s(val); out->assign(reinterpret_cast(*s), s.length()); return true; diff --git a/chromium_src/chrome/browser/ui/libgtk2ui/g_object_destructor_filo.cc b/chromium_src/chrome/browser/ui/libgtk2ui/g_object_destructor_filo.cc deleted file mode 100644 index 2e7eb77823e7..000000000000 --- a/chromium_src/chrome/browser/ui/libgtk2ui/g_object_destructor_filo.cc +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright (c) 2012 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/browser/ui/libgtk2ui/g_object_destructor_filo.h" - -#include - -#include "base/logging.h" -#include "base/memory/singleton.h" - -namespace libgtk2ui { - -GObjectDestructorFILO::GObjectDestructorFILO() { -} - -GObjectDestructorFILO::~GObjectDestructorFILO() { - // Probably CHECK(handler_map_.empty()) would look natural here. But - // some tests (some views_unittests) violate this assertion. -} - -// static -GObjectDestructorFILO* GObjectDestructorFILO::GetInstance() { - return Singleton::get(); -} - -void GObjectDestructorFILO::Connect( - GObject* object, DestructorHook callback, void* context) { - const Hook hook(object, callback, context); - HandlerMap::iterator iter = handler_map_.find(object); - if (iter == handler_map_.end()) { - g_object_weak_ref(object, WeakNotifyThunk, this); - handler_map_[object].push_front(hook); - } else { - iter->second.push_front(hook); - } -} - -void GObjectDestructorFILO::Disconnect( - GObject* object, DestructorHook callback, void* context) { - HandlerMap::iterator iter = handler_map_.find(object); - if (iter == handler_map_.end()) { - LOG(DFATAL) << "Unable to disconnect destructor hook for object " << object - << ": hook not found (" << callback << ", " << context << ")."; - return; - } - HandlerList& dtors = iter->second; - if (dtors.empty()) { - LOG(DFATAL) << "Destructor list is empty for specified object " << object - << " Maybe it is being executed?"; - return; - } - if (!dtors.front().equal(object, callback, context)) { - // Reenable this warning once this bug is fixed: - // http://code.google.com/p/chromium/issues/detail?id=85603 - DVLOG(1) << "Destructors should be unregistered the reverse order they " - << "were registered. But for object " << object << " " - << "deleted hook is "<< context << ", the last queued hook is " - << dtors.front().context; - } - for (HandlerList::iterator i = dtors.begin(); i != dtors.end(); ++i) { - if (i->equal(object, callback, context)) { - dtors.erase(i); - break; - } - } - if (dtors.empty()) { - g_object_weak_unref(object, WeakNotifyThunk, this); - handler_map_.erase(iter); - } -} - -void GObjectDestructorFILO::WeakNotify(GObject* where_the_object_was) { - HandlerMap::iterator iter = handler_map_.find(where_the_object_was); - DCHECK(iter != handler_map_.end()); - DCHECK(!iter->second.empty()); - - // Save destructor list for given object into local copy to avoid reentrancy - // problem: if callee wants to modify the caller list. - HandlerList dtors; - iter->second.swap(dtors); - handler_map_.erase(iter); - - // Execute hooks in local list in FILO order. - for (HandlerList::iterator i = dtors.begin(); i != dtors.end(); ++i) - i->callback(i->context, where_the_object_was); -} - -} // namespace libgtk2ui diff --git a/chromium_src/chrome/browser/ui/libgtk2ui/g_object_destructor_filo.h b/chromium_src/chrome/browser/ui/libgtk2ui/g_object_destructor_filo.h deleted file mode 100644 index d51de50e7910..000000000000 --- a/chromium_src/chrome/browser/ui/libgtk2ui/g_object_destructor_filo.h +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright (c) 2012 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_BROWSER_UI_LIBGTK2UI_G_OBJECT_DESTRUCTOR_FILO_H_ -#define CHROME_BROWSER_UI_LIBGTK2UI_G_OBJECT_DESTRUCTOR_FILO_H_ - -#include -#include -#include - -#include "base/basictypes.h" - -template struct DefaultSingletonTraits; - -typedef struct _GObject GObject; - -namespace libgtk2ui { - -// This class hooks calls to g_object_weak_ref()/unref() and executes them in -// FILO order. This is important if there are several hooks to the single object -// (set up at different levels of class hierarchy) and the lowest hook (set up -// first) is deleting self - it must be called last (among hooks for the given -// object). Unfortunately Glib does not provide this guarantee. -// -// Use it as follows: -// -// static void OnDestroyedThunk(gpointer data, GObject *where_the_object_was) { -// reinterpret_cast(data)->OnDestroyed(where_the_object_was); -// } -// void MyClass::OnDestroyed(GObject *where_the_object_was) { -// destroyed_ = true; -// delete this; -// } -// MyClass::Init() { -// ... -// ui::GObjectDestructorFILO::GetInstance()->Connect( -// G_OBJECT(my_widget), &OnDestroyedThunk, this); -// } -// MyClass::~MyClass() { -// if (!destroyed_) { -// ui::GObjectDestructorFILO::GetInstance()->Disconnect( -// G_OBJECT(my_widget), &OnDestroyedThunk, this); -// } -// } -// -// TODO(glotov): Probably worth adding ScopedGObjectDtor. -// -// This class is a singleton. Not thread safe. Must be called within UI thread. -class GObjectDestructorFILO { - public: - typedef void (*DestructorHook)(void* context, GObject* where_the_object_was); - - static GObjectDestructorFILO* GetInstance(); - void Connect(GObject* object, DestructorHook callback, void* context); - void Disconnect(GObject* object, DestructorHook callback, void* context); - - private: - struct Hook { - Hook(GObject* o, DestructorHook cb, void* ctx) - : object(o), callback(cb), context(ctx) { - } - bool equal(GObject* o, DestructorHook cb, void* ctx) const { - return object == o && callback == cb && context == ctx; - } - GObject* object; - DestructorHook callback; - void* context; - }; - typedef std::list HandlerList; - typedef std::map HandlerMap; - - GObjectDestructorFILO(); - ~GObjectDestructorFILO(); - friend struct DefaultSingletonTraits; - - void WeakNotify(GObject* where_the_object_was); - static void WeakNotifyThunk(gpointer data, GObject* where_the_object_was) { - reinterpret_cast(data)->WeakNotify( - where_the_object_was); - } - - HandlerMap handler_map_; - - DISALLOW_COPY_AND_ASSIGN(GObjectDestructorFILO); -}; - -} // namespace libgtk2ui - -#endif // CHROME_BROWSER_UI_LIBGTK2UI_G_OBJECT_DESTRUCTOR_FILO_H_ diff --git a/chromium_src/chrome/browser/ui/libgtk2ui/gtk2_signal.h b/chromium_src/chrome/browser/ui/libgtk2ui/gtk2_signal.h deleted file mode 100644 index 4643b98dc45b..000000000000 --- a/chromium_src/chrome/browser/ui/libgtk2ui/gtk2_signal.h +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (c) 2012 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_BROWSER_UI_LIBGTK2UI_GTK2_SIGNAL_H_ -#define CHROME_BROWSER_UI_LIBGTK2UI_GTK2_SIGNAL_H_ - -#include "ui/base/glib/glib_signal.h" - -typedef struct _GtkWidget GtkWidget; - -// These macros handle the common case where the sender object will be a -// GtkWidget*. -#define CHROMEGTK_CALLBACK_0(CLASS, RETURN, METHOD) \ - CHROMEG_CALLBACK_0(CLASS, RETURN, METHOD, GtkWidget*); - -#define CHROMEGTK_CALLBACK_1(CLASS, RETURN, METHOD, ARG1) \ - CHROMEG_CALLBACK_1(CLASS, RETURN, METHOD, GtkWidget*, ARG1); - -#define CHROMEGTK_CALLBACK_2(CLASS, RETURN, METHOD, ARG1, ARG2) \ - CHROMEG_CALLBACK_2(CLASS, RETURN, METHOD, GtkWidget*, ARG1, ARG2); - -#define CHROMEGTK_CALLBACK_3(CLASS, RETURN, METHOD, ARG1, ARG2, ARG3) \ - CHROMEG_CALLBACK_3(CLASS, RETURN, METHOD, GtkWidget*, ARG1, ARG2, ARG3); - -#define CHROMEGTK_CALLBACK_4(CLASS, RETURN, METHOD, ARG1, ARG2, ARG3, ARG4) \ - CHROMEG_CALLBACK_4(CLASS, RETURN, METHOD, GtkWidget*, ARG1, ARG2, ARG3, \ - ARG4); - -#define CHROMEGTK_CALLBACK_5(CLASS, RETURN, METHOD, ARG1, ARG2, ARG3, ARG4, \ - ARG5) \ - CHROMEG_CALLBACK_5(CLASS, RETURN, METHOD, GtkWidget*, ARG1, ARG2, ARG3, \ - ARG4, ARG5); - -#define CHROMEGTK_CALLBACK_6(CLASS, RETURN, METHOD, ARG1, ARG2, ARG3, ARG4, \ - ARG5, ARG6) \ - CHROMEG_CALLBACK_6(CLASS, RETURN, METHOD, GtkWidget*, ARG1, ARG2, ARG3, \ - ARG4, ARG5, ARG6); - -#define CHROMEGTK_VIRTUAL_CALLBACK_0(CLASS, RETURN, METHOD) \ - CHROMEG_VIRTUAL_CALLBACK_0(CLASS, RETURN, METHOD, GtkWidget*); - -#define CHROMEGTK_VIRTUAL_CALLBACK_1(CLASS, RETURN, METHOD, ARG1) \ - CHROMEG_VIRTUAL_CALLBACK_1(CLASS, RETURN, METHOD, GtkWidget*, ARG1); - -#define CHROMEGTK_VIRTUAL_CALLBACK_2(CLASS, RETURN, METHOD, ARG1, ARG2) \ - CHROMEG_VIRTUAL_CALLBACK_2(CLASS, RETURN, METHOD, GtkWidget*, ARG1, ARG2); - -#define CHROMEGTK_VIRTUAL_CALLBACK_3(CLASS, RETURN, METHOD, ARG1, ARG2, ARG3) \ - CHROMEG_VIRTUAL_CALLBACK_3(CLASS, RETURN, METHOD, GtkWidget*, ARG1, ARG2, \ - ARG3); - -#define CHROMEGTK_VIRTUAL_CALLBACK_4(CLASS, RETURN, METHOD, ARG1, ARG2, ARG3, \ - ARG4) \ - CHROMEG_VIRTUAL_CALLBACK_4(CLASS, RETURN, METHOD, GtkWidget*, ARG1, ARG2, \ - ARG3, ARG4); - -#define CHROMEGTK_VIRTUAL_CALLBACK_5(CLASS, RETURN, METHOD, ARG1, ARG2, ARG3, \ - ARG4, ARG5) \ - CHROMEG_VIRTUAL_CALLBACK_5(CLASS, RETURN, METHOD, GtkWidget*, ARG1, ARG2, \ - ARG3, ARG4, ARG5); - -#define CHROMEGTK_VIRTUAL_CALLBACK_6(CLASS, RETURN, METHOD, ARG1, ARG2, ARG3, \ - ARG4, ARG5, ARG6) \ - CHROMEG_VIRTUAL_CALLBACK_6(CLASS, RETURN, METHOD, GtkWidget*, ARG1, ARG2, \ - ARG3, ARG4, ARG5, ARG6); - -#endif // CHROME_BROWSER_UI_LIBGTK2UI_GTK2_SIGNAL_H_ diff --git a/chromium_src/chrome/browser/ui/libgtk2ui/gtk2_signal_registrar.cc b/chromium_src/chrome/browser/ui/libgtk2ui/gtk2_signal_registrar.cc deleted file mode 100644 index 9d878e27ea61..000000000000 --- a/chromium_src/chrome/browser/ui/libgtk2ui/gtk2_signal_registrar.cc +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright (c) 2011 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/browser/ui/libgtk2ui/gtk2_signal_registrar.h" - -#include - -#include "base/logging.h" -#include "chrome/browser/ui/libgtk2ui/g_object_destructor_filo.h" - -namespace libgtk2ui { - -Gtk2SignalRegistrar::Gtk2SignalRegistrar() { -} - -Gtk2SignalRegistrar::~Gtk2SignalRegistrar() { - for (HandlerMap::iterator list_iter = handler_lists_.begin(); - list_iter != handler_lists_.end(); ++list_iter) { - GObject* object = list_iter->first; - GObjectDestructorFILO::GetInstance()->Disconnect( - object, WeakNotifyThunk, this); - - HandlerList& handlers = list_iter->second; - for (HandlerList::iterator ids_iter = handlers.begin(); - ids_iter != handlers.end(); ++ids_iter) { - g_signal_handler_disconnect(object, *ids_iter); - } - } -} - -glong Gtk2SignalRegistrar::Connect(gpointer instance, - const gchar* detailed_signal, - GCallback signal_handler, - gpointer data) { - return ConnectInternal(instance, detailed_signal, signal_handler, data, - false); -} - -glong Gtk2SignalRegistrar::ConnectAfter(gpointer instance, - const gchar* detailed_signal, - GCallback signal_handler, - gpointer data) { - return ConnectInternal(instance, detailed_signal, signal_handler, data, true); -} - -glong Gtk2SignalRegistrar::ConnectInternal(gpointer instance, - const gchar* detailed_signal, - GCallback signal_handler, - gpointer data, - bool after) { - GObject* object = G_OBJECT(instance); - - HandlerMap::iterator iter = handler_lists_.find(object); - if (iter == handler_lists_.end()) { - GObjectDestructorFILO::GetInstance()->Connect( - object, WeakNotifyThunk, this); - handler_lists_[object] = HandlerList(); - iter = handler_lists_.find(object); - } - - glong handler_id = after ? - g_signal_connect_after(instance, detailed_signal, signal_handler, data) : - g_signal_connect(instance, detailed_signal, signal_handler, data); - iter->second.push_back(handler_id); - - return handler_id; -} - -void Gtk2SignalRegistrar::WeakNotify(GObject* where_the_object_was) { - HandlerMap::iterator iter = handler_lists_.find(where_the_object_was); - if (iter == handler_lists_.end()) { - NOTREACHED(); - return; - } - // The signal handlers will be disconnected automatically. Just erase the - // handler id list. - handler_lists_.erase(iter); -} - -void Gtk2SignalRegistrar::DisconnectAll(gpointer instance) { - GObject* object = G_OBJECT(instance); - HandlerMap::iterator iter = handler_lists_.find(object); - if (iter == handler_lists_.end()) - return; - - GObjectDestructorFILO::GetInstance()->Disconnect( - object, WeakNotifyThunk, this); - HandlerList& handlers = iter->second; - for (HandlerList::iterator ids_iter = handlers.begin(); - ids_iter != handlers.end(); ++ids_iter) { - g_signal_handler_disconnect(object, *ids_iter); - } - - handler_lists_.erase(iter); -} - -} // namespace libgtk2ui diff --git a/chromium_src/chrome/browser/ui/libgtk2ui/gtk2_signal_registrar.h b/chromium_src/chrome/browser/ui/libgtk2ui/gtk2_signal_registrar.h deleted file mode 100644 index e83fbadc2498..000000000000 --- a/chromium_src/chrome/browser/ui/libgtk2ui/gtk2_signal_registrar.h +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright (c) 2011 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_BROWSER_UI_LIBGTK2UI_GTK2_SIGNAL_REGISTRAR_H_ -#define CHROME_BROWSER_UI_LIBGTK2UI_GTK2_SIGNAL_REGISTRAR_H_ - -#include -#include -#include - -#include "base/basictypes.h" - -typedef void (*GCallback) (void); -typedef struct _GObject GObject; -typedef struct _GtkWidget GtkWidget; - -namespace libgtk2ui { - -// A class that ensures that callbacks don't run on stale owner objects. Similar -// in spirit to NotificationRegistrar. Use as follows: -// -// class ChromeObject { -// public: -// ChromeObject() { -// ... -// -// signals_.Connect(widget, "event", CallbackThunk, this); -// } -// -// ... -// -// private: -// Gtk2SignalRegistrar signals_; -// }; -// -// When |signals_| goes down, it will disconnect the handlers connected via -// Connect. -class Gtk2SignalRegistrar { - public: - Gtk2SignalRegistrar(); - ~Gtk2SignalRegistrar(); - - // Connect before the default handler. Returns the handler id. - glong Connect(gpointer instance, const gchar* detailed_signal, - GCallback signal_handler, gpointer data); - // Connect after the default handler. Returns the handler id. - glong ConnectAfter(gpointer instance, const gchar* detailed_signal, - GCallback signal_handler, gpointer data); - - // Disconnects all signal handlers connected to |instance|. - void DisconnectAll(gpointer instance); - - private: - typedef std::vector HandlerList; - typedef std::map HandlerMap; - - static void WeakNotifyThunk(gpointer data, GObject* where_the_object_was) { - reinterpret_cast(data)->WeakNotify( - where_the_object_was); - } - void WeakNotify(GObject* where_the_object_was); - - glong ConnectInternal(gpointer instance, const gchar* detailed_signal, - GCallback signal_handler, gpointer data, bool after); - - HandlerMap handler_lists_; - - DISALLOW_COPY_AND_ASSIGN(Gtk2SignalRegistrar); -}; - -} // namespace libgtk2ui - -#endif // CHROME_BROWSER_UI_LIBGTK2UI_GTK2_SIGNAL_REGISTRAR_H_ diff --git a/chromium_src/chrome/browser/ui/libgtk2ui/skia_utils_gtk2.cc b/chromium_src/chrome/browser/ui/libgtk2ui/skia_utils_gtk2.cc deleted file mode 100644 index ceffa92f4af4..000000000000 --- a/chromium_src/chrome/browser/ui/libgtk2ui/skia_utils_gtk2.cc +++ /dev/null @@ -1,135 +0,0 @@ -// Copyright (c) 2012 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/browser/ui/libgtk2ui/skia_utils_gtk2.h" - -#include - -#include "base/basictypes.h" -#include "base/logging.h" -#include "third_party/skia/include/core/SkBitmap.h" -#include "third_party/skia/include/core/SkUnPreMultiply.h" - -namespace libgtk2ui { - -// GDK_COLOR_RGB multiplies by 257 (= 0x10001) to distribute the bits evenly -// See: http://www.mindcontrol.org/~hplus/graphics/expand-bits.html -// To get back, we can just right shift by eight -// (or, formulated differently, i == (i*257)/256 for all i < 256). - -SkColor GdkColorToSkColor(GdkColor color) { - return SkColorSetRGB(color.red >> 8, color.green >> 8, color.blue >> 8); -} - -GdkColor SkColorToGdkColor(SkColor color) { - GdkColor gdk_color = { - 0, - static_cast(SkColorGetR(color) * kSkiaToGDKMultiplier), - static_cast(SkColorGetG(color) * kSkiaToGDKMultiplier), - static_cast(SkColorGetB(color) * kSkiaToGDKMultiplier) - }; - return gdk_color; -} - -const SkBitmap GdkPixbufToImageSkia(GdkPixbuf* pixbuf) { - // TODO(erg): What do we do in the case where the pixbuf fails these dchecks? - // I would prefer to use our gtk based canvas, but that would require - // recompiling half of our skia extensions with gtk support, which we can't - // do in this build. - DCHECK_EQ(GDK_COLORSPACE_RGB, gdk_pixbuf_get_colorspace(pixbuf)); - - int n_channels = gdk_pixbuf_get_n_channels(pixbuf); - int w = gdk_pixbuf_get_width(pixbuf); - int h = gdk_pixbuf_get_height(pixbuf); - - SkBitmap ret; - ret.setConfig(SkBitmap::kARGB_8888_Config, w, h); - ret.allocPixels(); - ret.eraseColor(0); - - uint32_t* skia_data = static_cast(ret.getAddr(0, 0)); - - if (n_channels == 4) { - int total_length = w * h; - guchar* gdk_pixels = gdk_pixbuf_get_pixels(pixbuf); - - // Now here's the trick: we need to convert the gdk data (which is RGBA and - // isn't premultiplied) to skia (which can be anything and premultiplied). - for (int i = 0; i < total_length; ++i, gdk_pixels += 4) { - const unsigned char& red = gdk_pixels[0]; - const unsigned char& green = gdk_pixels[1]; - const unsigned char& blue = gdk_pixels[2]; - const unsigned char& alpha = gdk_pixels[3]; - - skia_data[i] = SkPreMultiplyARGB(alpha, red, green, blue); - } - } else if (n_channels == 3) { - // Because GDK makes rowstrides word aligned, we need to do something a bit - // more complex when a pixel isn't perfectly a word of memory. - int rowstride = gdk_pixbuf_get_rowstride(pixbuf); - guchar* gdk_pixels = gdk_pixbuf_get_pixels(pixbuf); - for (int y = 0; y < h; ++y) { - int row = y * rowstride; - - for (int x = 0; x < w; ++x) { - guchar* pixel = gdk_pixels + row + (x * 3); - const unsigned char& red = pixel[0]; - const unsigned char& green = pixel[1]; - const unsigned char& blue = pixel[2]; - - skia_data[y * w + x] = SkPreMultiplyARGB(255, red, green, blue); - } - } - } else { - NOTREACHED(); - } - - return ret; -} - -GdkPixbuf* GdkPixbufFromSkBitmap(const SkBitmap& bitmap) { - if (bitmap.isNull()) - return NULL; - - SkAutoLockPixels lock_pixels(bitmap); - - int width = bitmap.width(); - int height = bitmap.height(); - - GdkPixbuf* pixbuf = - gdk_pixbuf_new(GDK_COLORSPACE_RGB, // The only colorspace gtk supports. - TRUE, // There is an alpha channel. - 8, - width, - height); - - // SkBitmaps are premultiplied, we need to unpremultiply them. - const int kBytesPerPixel = 4; - uint8* divided = gdk_pixbuf_get_pixels(pixbuf); - - for (int y = 0, i = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - uint32 pixel = bitmap.getAddr32(0, y)[x]; - - int alpha = SkColorGetA(pixel); - if (alpha != 0 && alpha != 255) { - SkColor unmultiplied = SkUnPreMultiply::PMColorToColor(pixel); - divided[i + 0] = SkColorGetR(unmultiplied); - divided[i + 1] = SkColorGetG(unmultiplied); - divided[i + 2] = SkColorGetB(unmultiplied); - divided[i + 3] = alpha; - } else { - divided[i + 0] = SkColorGetR(pixel); - divided[i + 1] = SkColorGetG(pixel); - divided[i + 2] = SkColorGetB(pixel); - divided[i + 3] = alpha; - } - i += kBytesPerPixel; - } - } - - return pixbuf; -} - -} // namespace libgtk2ui diff --git a/chromium_src/chrome/browser/ui/libgtk2ui/skia_utils_gtk2.h b/chromium_src/chrome/browser/ui/libgtk2ui/skia_utils_gtk2.h deleted file mode 100644 index 4a39514e8d72..000000000000 --- a/chromium_src/chrome/browser/ui/libgtk2ui/skia_utils_gtk2.h +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) 2012 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_BROWSER_UI_LIBGTK2UI_SKIA_UTILS_GTK2_H_ -#define CHROME_BROWSER_UI_LIBGTK2UI_SKIA_UTILS_GTK2_H_ - -#include "third_party/skia/include/core/SkColor.h" - -typedef struct _GdkColor GdkColor; -typedef struct _GdkPixbuf GdkPixbuf; - -class SkBitmap; - -// Define a macro for creating GdkColors from RGB values. This is a macro to -// allow static construction of literals, etc. Use this like: -// GdkColor white = GDK_COLOR_RGB(0xff, 0xff, 0xff); -#define GDK_COLOR_RGB(r, g, b) {0, r * ::libgtk2ui::kSkiaToGDKMultiplier, \ - g * ::libgtk2ui::kSkiaToGDKMultiplier, \ - b * ::libgtk2ui::kSkiaToGDKMultiplier} - -namespace libgtk2ui { - -// Multiply uint8 color components by this. -const int kSkiaToGDKMultiplier = 257; - -// Converts GdkColors to the ARGB layout Skia expects. -SkColor GdkColorToSkColor(GdkColor color); - -// Converts ARGB to GdkColor. -GdkColor SkColorToGdkColor(SkColor color); - -const SkBitmap GdkPixbufToImageSkia(GdkPixbuf* pixbuf); - -// Convert and copy a SkBitmap to a GdkPixbuf. NOTE: this uses BGRAToRGBA, so -// it is an expensive operation. The returned GdkPixbuf will have a refcount of -// 1, and the caller is responsible for unrefing it when done. -GdkPixbuf* GdkPixbufFromSkBitmap(const SkBitmap& bitmap); - -} // namespace libgtk2ui - -#endif // CHROME_BROWSER_UI_LIBGTK2UI_SKIA_UTILS_GTK2_H_ diff --git a/vendor/brightray b/vendor/brightray index a348865e723b..f8baf4a4bad5 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit a348865e723b73cd01d0b976f2d0b8d9b836176d +Subproject commit f8baf4a4bad51536ab013b4ee2edd9d749df695d