From 3349b8e6c7bf7c827b308ab96cccb58cbaa23e02 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 10 Jul 2014 13:06:41 +0800 Subject: [PATCH] linux: Remove all the X and GTK+ related implementations. Now we only uses GTK+ for app indicator and status icon, also notice the in Chrome35 the Gtk2StatusIcon class doesn't exist yet so we shipp related files under chromium_src, remember to delete them after upgraded to Chrome36. --- atom.gyp | 38 +- atom/browser/ui/accelerator_util_gtk.cc | 20 - ..._util_win.cc => accelerator_util_views.cc} | 0 atom/browser/ui/gtk/app_indicator_icon.cc | 267 ------ atom/browser/ui/gtk/app_indicator_icon.h | 55 -- atom/browser/ui/gtk/status_icon.cc | 56 -- atom/browser/ui/gtk/status_icon.h | 47 - atom/browser/ui/tray_icon_gtk.cc | 53 +- atom/browser/ui/tray_icon_gtk.h | 43 + .../chrome/browser/ui/gtk/event_utils.cc | 44 - .../chrome/browser/ui/gtk/event_utils.h | 28 - .../chrome/browser/ui/gtk/gtk_custom_menu.cc | 150 --- .../chrome/browser/ui/gtk/gtk_custom_menu.h | 51 - .../browser/ui/gtk/gtk_custom_menu_item.cc | 493 ---------- .../browser/ui/gtk/gtk_custom_menu_item.h | 139 --- .../chrome/browser/ui/gtk/gtk_util.cc | 94 -- chromium_src/chrome/browser/ui/gtk/gtk_util.h | 36 - .../chrome/browser/ui/gtk/gtk_window_util.cc | 257 ----- .../chrome/browser/ui/gtk/gtk_window_util.h | 69 -- .../chrome/browser/ui/gtk/menu_gtk.cc | 883 ------------------ chromium_src/chrome/browser/ui/gtk/menu_gtk.h | 224 ----- .../ui/libgtk2ui/app_indicator_icon_menu.cc | 123 +++ .../ui/libgtk2ui/app_indicator_icon_menu.h | 66 ++ .../browser/ui/libgtk2ui/gtk2_status_icon.cc | 80 ++ .../browser/ui/libgtk2ui/gtk2_status_icon.h | 61 ++ .../accelerators/platform_accelerator_gtk.cc | 93 -- .../accelerators/platform_accelerator_gtk.h | 49 - .../ui/base/x/active_window_watcher_x.cc | 99 -- .../ui/base/x/active_window_watcher_x.h | 60 -- .../base/x/active_window_watcher_x_observer.h | 25 - .../base/x/root_window_property_watcher_x.cc | 59 -- .../base/x/root_window_property_watcher_x.h | 41 - chromium_src/ui/base/x/work_area_watcher_x.cc | 53 -- chromium_src/ui/base/x/work_area_watcher_x.h | 55 -- chromium_src/ui/base/x/x11_util.cc | 25 - .../keycodes/keyboard_code_conversion_gtk.cc | 85 -- .../keycodes/keyboard_code_conversion_gtk.h | 58 -- chromium_src/ui/gfx/gtk_util.h | 55 -- chromium_src/ui/gfx/gtk_util_gfx.cc | 192 ---- 39 files changed, 426 insertions(+), 3900 deletions(-) delete mode 100644 atom/browser/ui/accelerator_util_gtk.cc rename atom/browser/ui/{accelerator_util_win.cc => accelerator_util_views.cc} (100%) delete mode 100644 atom/browser/ui/gtk/app_indicator_icon.cc delete mode 100644 atom/browser/ui/gtk/app_indicator_icon.h delete mode 100644 atom/browser/ui/gtk/status_icon.cc delete mode 100644 atom/browser/ui/gtk/status_icon.h create mode 100644 atom/browser/ui/tray_icon_gtk.h delete mode 100644 chromium_src/chrome/browser/ui/gtk/event_utils.cc delete mode 100644 chromium_src/chrome/browser/ui/gtk/event_utils.h delete mode 100644 chromium_src/chrome/browser/ui/gtk/gtk_custom_menu.cc delete mode 100644 chromium_src/chrome/browser/ui/gtk/gtk_custom_menu.h delete mode 100644 chromium_src/chrome/browser/ui/gtk/gtk_custom_menu_item.cc delete mode 100644 chromium_src/chrome/browser/ui/gtk/gtk_custom_menu_item.h delete mode 100644 chromium_src/chrome/browser/ui/gtk/gtk_util.cc delete mode 100644 chromium_src/chrome/browser/ui/gtk/gtk_util.h delete mode 100644 chromium_src/chrome/browser/ui/gtk/gtk_window_util.cc delete mode 100644 chromium_src/chrome/browser/ui/gtk/gtk_window_util.h delete mode 100644 chromium_src/chrome/browser/ui/gtk/menu_gtk.cc delete mode 100644 chromium_src/chrome/browser/ui/gtk/menu_gtk.h create mode 100644 chromium_src/chrome/browser/ui/libgtk2ui/app_indicator_icon_menu.cc create mode 100644 chromium_src/chrome/browser/ui/libgtk2ui/app_indicator_icon_menu.h create mode 100644 chromium_src/chrome/browser/ui/libgtk2ui/gtk2_status_icon.cc create mode 100644 chromium_src/chrome/browser/ui/libgtk2ui/gtk2_status_icon.h delete mode 100644 chromium_src/ui/base/accelerators/platform_accelerator_gtk.cc delete mode 100644 chromium_src/ui/base/accelerators/platform_accelerator_gtk.h delete mode 100644 chromium_src/ui/base/x/active_window_watcher_x.cc delete mode 100644 chromium_src/ui/base/x/active_window_watcher_x.h delete mode 100644 chromium_src/ui/base/x/active_window_watcher_x_observer.h delete mode 100644 chromium_src/ui/base/x/root_window_property_watcher_x.cc delete mode 100644 chromium_src/ui/base/x/root_window_property_watcher_x.h delete mode 100644 chromium_src/ui/base/x/work_area_watcher_x.cc delete mode 100644 chromium_src/ui/base/x/work_area_watcher_x.h delete mode 100644 chromium_src/ui/base/x/x11_util.cc delete mode 100644 chromium_src/ui/events/keycodes/keyboard_code_conversion_gtk.cc delete mode 100644 chromium_src/ui/events/keycodes/keyboard_code_conversion_gtk.h delete mode 100644 chromium_src/ui/gfx/gtk_util.h delete mode 100644 chromium_src/ui/gfx/gtk_util_gfx.cc diff --git a/atom.gyp b/atom.gyp index a4f38b6f42a7..c02acbd82b7b 100644 --- a/atom.gyp +++ b/atom.gyp @@ -118,9 +118,8 @@ 'atom/browser/net/url_request_string_job.h', 'atom/browser/ui/accelerator_util.cc', 'atom/browser/ui/accelerator_util.h', - 'atom/browser/ui/accelerator_util_gtk.cc', 'atom/browser/ui/accelerator_util_mac.mm', - 'atom/browser/ui/accelerator_util_win.cc', + 'atom/browser/ui/accelerator_util_views.cc', 'atom/browser/ui/cocoa/atom_menu_controller.h', 'atom/browser/ui/cocoa/atom_menu_controller.mm', 'atom/browser/ui/cocoa/event_processing_window.h', @@ -129,16 +128,13 @@ 'atom/browser/ui/file_dialog_gtk.cc', 'atom/browser/ui/file_dialog_mac.mm', 'atom/browser/ui/file_dialog_win.cc', - 'atom/browser/ui/gtk/app_indicator_icon.cc', - 'atom/browser/ui/gtk/app_indicator_icon.h', - '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_mac.mm', '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', + 'atom/browser/ui/tray_icon_gtk.h', 'atom/browser/ui/tray_icon_cocoa.h', 'atom/browser/ui/tray_icon_cocoa.mm', 'atom/browser/ui/tray_icon_observer.h', @@ -223,34 +219,12 @@ 'atom/renderer/atom_render_view_observer.h', 'atom/renderer/atom_renderer_client.cc', 'atom/renderer/atom_renderer_client.h', - 'chromium_src/chrome/browser/ui/gtk/event_utils.cc', - 'chromium_src/chrome/browser/ui/gtk/event_utils.h', - 'chromium_src/chrome/browser/ui/gtk/gtk_custom_menu.cc', - 'chromium_src/chrome/browser/ui/gtk/gtk_custom_menu.h', - 'chromium_src/chrome/browser/ui/gtk/gtk_custom_menu_item.cc', - 'chromium_src/chrome/browser/ui/gtk/gtk_custom_menu_item.h', - 'chromium_src/chrome/browser/ui/gtk/gtk_util.cc', - 'chromium_src/chrome/browser/ui/gtk/gtk_util.h', - 'chromium_src/chrome/browser/ui/gtk/gtk_window_util.cc', - '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/app_indicator_icon_menu.cc', + 'chromium_src/chrome/browser/ui/libgtk2ui/app_indicator_icon_menu.h', + 'chromium_src/chrome/browser/ui/libgtk2ui/gtk2_status_icon.cc', + 'chromium_src/chrome/browser/ui/libgtk2ui/gtk2_status_icon.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', - 'chromium_src/ui/base/accelerators/platform_accelerator_gtk.h', - 'chromium_src/ui/base/x/active_window_watcher_x.cc', - 'chromium_src/ui/base/x/active_window_watcher_x.h', - 'chromium_src/ui/base/x/active_window_watcher_x_observer.h', - 'chromium_src/ui/base/x/root_window_property_watcher_x.cc', - 'chromium_src/ui/base/x/root_window_property_watcher_x.h', - 'chromium_src/ui/base/x/work_area_watcher_x.cc', - 'chromium_src/ui/base/x/work_area_watcher_x.h', - 'chromium_src/ui/base/x/x11_util.cc', - 'chromium_src/ui/events/keycodes/keyboard_code_conversion_gtk.cc', - 'chromium_src/ui/events/keycodes/keyboard_code_conversion_gtk.h', - 'chromium_src/ui/gfx/gtk_util_gfx.cc', - 'chromium_src/ui/gfx/gtk_util.h', '<@(native_mate_files)', ], 'framework_sources': [ diff --git a/atom/browser/ui/accelerator_util_gtk.cc b/atom/browser/ui/accelerator_util_gtk.cc deleted file mode 100644 index 259d4aef49b3..000000000000 --- a/atom/browser/ui/accelerator_util_gtk.cc +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) 2013 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/accelerator_util.h" - -#include "ui/base/accelerators/accelerator.h" -#include "ui/base/accelerators/platform_accelerator_gtk.h" - -namespace accelerator_util { - -void SetPlatformAccelerator(ui::Accelerator* accelerator) { - scoped_ptr platform_accelerator( - new ui::PlatformAcceleratorGtk( - GetGdkKeyCodeForAccelerator(*accelerator), - GetGdkModifierForAccelerator(*accelerator))); - accelerator->set_platform_accelerator(platform_accelerator.Pass()); -} - -} // namespace accelerator_util diff --git a/atom/browser/ui/accelerator_util_win.cc b/atom/browser/ui/accelerator_util_views.cc similarity index 100% rename from atom/browser/ui/accelerator_util_win.cc rename to atom/browser/ui/accelerator_util_views.cc diff --git a/atom/browser/ui/gtk/app_indicator_icon.cc b/atom/browser/ui/gtk/app_indicator_icon.cc deleted file mode 100644 index 4ab1dd3a3985..000000000000 --- a/atom/browser/ui/gtk/app_indicator_icon.cc +++ /dev/null @@ -1,267 +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/gtk/app_indicator_icon.h" - -#include -#include - -#include "base/file_util.h" -#include "base/guid.h" -#include "base/memory/ref_counted_memory.h" -#include "base/strings/stringprintf.h" -#include "base/threading/sequenced_worker_pool.h" -#include "chrome/browser/ui/gtk/menu_gtk.h" -#include "content/public/browser/browser_thread.h" -#include "ui/gfx/image/image.h" - -namespace { - -typedef enum { - APP_INDICATOR_CATEGORY_APPLICATION_STATUS, - APP_INDICATOR_CATEGORY_COMMUNICATIONS, - APP_INDICATOR_CATEGORY_SYSTEM_SERVICES, - APP_INDICATOR_CATEGORY_HARDWARE, - APP_INDICATOR_CATEGORY_OTHER -} AppIndicatorCategory; - -typedef enum { - APP_INDICATOR_STATUS_PASSIVE, - APP_INDICATOR_STATUS_ACTIVE, - APP_INDICATOR_STATUS_ATTENTION -} AppIndicatorStatus; - -typedef AppIndicator* (*app_indicator_new_func)(const gchar* id, - const gchar* icon_name, - AppIndicatorCategory category); - -typedef AppIndicator* (*app_indicator_new_with_path_func)( - const gchar* id, - const gchar* icon_name, - AppIndicatorCategory category, - const gchar* icon_theme_path); - -typedef void (*app_indicator_set_status_func)(AppIndicator* self, - AppIndicatorStatus status); - -typedef void (*app_indicator_set_attention_icon_full_func)( - AppIndicator* self, - const gchar* icon_name, - const gchar* icon_desc); - -typedef void (*app_indicator_set_menu_func)(AppIndicator* self, GtkMenu* menu); - -typedef void (*app_indicator_set_icon_full_func)(AppIndicator* self, - const gchar* icon_name, - const gchar* icon_desc); - -typedef void (*app_indicator_set_icon_theme_path_func)( - AppIndicator* self, - const gchar* icon_theme_path); - -bool g_attempted_load = false; -bool g_opened = false; - -// Retrieved functions from libappindicator. -app_indicator_new_func app_indicator_new = NULL; -app_indicator_new_with_path_func app_indicator_new_with_path = NULL; -app_indicator_set_status_func app_indicator_set_status = NULL; -app_indicator_set_attention_icon_full_func - app_indicator_set_attention_icon_full = NULL; -app_indicator_set_menu_func app_indicator_set_menu = NULL; -app_indicator_set_icon_full_func app_indicator_set_icon_full = NULL; -app_indicator_set_icon_theme_path_func app_indicator_set_icon_theme_path = NULL; - -void EnsureMethodsLoaded() { - if (g_attempted_load) - return; - - g_attempted_load = true; - - void* indicator_lib = dlopen("libappindicator.so", RTLD_LAZY); - if (!indicator_lib) { - indicator_lib = dlopen("libappindicator.so.1", RTLD_LAZY); - } - if (!indicator_lib) { - indicator_lib = dlopen("libappindicator.so.0", RTLD_LAZY); - } - if (!indicator_lib) { - return; - } - - g_opened = true; - - app_indicator_new = reinterpret_cast( - dlsym(indicator_lib, "app_indicator_new")); - - app_indicator_new_with_path = - reinterpret_cast( - dlsym(indicator_lib, "app_indicator_new_with_path")); - - app_indicator_set_status = reinterpret_cast( - dlsym(indicator_lib, "app_indicator_set_status")); - - app_indicator_set_attention_icon_full = - reinterpret_cast( - dlsym(indicator_lib, "app_indicator_set_attention_icon_full")); - - app_indicator_set_menu = reinterpret_cast( - dlsym(indicator_lib, "app_indicator_set_menu")); - - app_indicator_set_icon_full = - reinterpret_cast( - dlsym(indicator_lib, "app_indicator_set_icon_full")); - - app_indicator_set_icon_theme_path = - reinterpret_cast( - dlsym(indicator_lib, "app_indicator_set_icon_theme_path")); -} - -base::FilePath CreateTempImageFile(gfx::ImageSkia* image_ptr, - int icon_change_count, - std::string id) { - scoped_ptr image(image_ptr); - - scoped_refptr png_data = - gfx::Image(*image.get()).As1xPNGBytes(); - if (png_data->size() == 0) { - // If the bitmap could not be encoded to PNG format, skip it. - LOG(WARNING) << "Could not encode icon"; - return base::FilePath(); - } - - base::FilePath temp_dir; - base::FilePath new_file_path; - - // Create a new temporary directory for each image since using a single - // temporary directory seems to have issues when changing icons in quick - // succession. - if (!base::CreateNewTempDirectory(base::FilePath::StringType(), &temp_dir)) - return base::FilePath(); - new_file_path = - temp_dir.Append(id + base::StringPrintf("_%d.png", icon_change_count)); - int bytes_written = - base::WriteFile( - new_file_path, - reinterpret_cast(png_data->front()), - png_data->size()); - - if (bytes_written != static_cast(png_data->size())) - return base::FilePath(); - return new_file_path; -} - -void DeleteTempImagePath(const base::FilePath& icon_file_path) { - if (icon_file_path.empty()) - return; - base::DeleteFile(icon_file_path, true); -} - -} // namespace - -namespace atom { - -AppIndicatorIcon::AppIndicatorIcon() - : icon_(NULL), - id_(base::GenerateGUID()), - icon_change_count_(0), - weak_factory_(this) { -} - -AppIndicatorIcon::~AppIndicatorIcon() { - if (icon_) { - app_indicator_set_status(icon_, APP_INDICATOR_STATUS_PASSIVE); - g_object_unref(icon_); - content::BrowserThread::GetBlockingPool()->PostTask( - FROM_HERE, - base::Bind(&DeleteTempImagePath, icon_file_path_.DirName())); - } -} - -bool AppIndicatorIcon::CouldOpen() { - EnsureMethodsLoaded(); - return g_opened; -} - -void AppIndicatorIcon::SetImage(const gfx::ImageSkia& image) { - if (!g_opened) - return; - - ++icon_change_count_; - - // We create a deep copy of the image since it may have been freed by the time - // it's accessed in the other thread. - scoped_ptr safe_image(image.DeepCopy()); - base::PostTaskAndReplyWithResult( - content::BrowserThread::GetBlockingPool() - ->GetTaskRunnerWithShutdownBehavior( - base::SequencedWorkerPool::SKIP_ON_SHUTDOWN).get(), - FROM_HERE, - base::Bind(&CreateTempImageFile, - safe_image.release(), - icon_change_count_, - id_), - base::Bind(&AppIndicatorIcon::SetImageFromFile, - weak_factory_.GetWeakPtr())); -} - -void AppIndicatorIcon::SetPressedImage(const gfx::ImageSkia& image) { - // Ignore pressed images, since the standard on Linux is to not highlight - // pressed status icons. -} - -void AppIndicatorIcon::SetToolTip(const std::string& tool_tip) { - // App indicator doesn't have tooltips: - // https://bugs.launchpad.net/indicator-application/+bug/527458 -} - -void AppIndicatorIcon::SetContextMenu(ui::SimpleMenuModel* menu_model) { - // The icon is created asynchronously, wait until the icon has been ready. - if (!icon_) { - content::BrowserThread::GetBlockingPool() - ->GetTaskRunnerWithShutdownBehavior( - base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)->PostTask( - FROM_HERE, - base::Bind(&AppIndicatorIcon::SetContextMenu, - weak_factory_.GetWeakPtr(), - base::Unretained(menu_model))); - return; - } - - menu_.reset(new MenuGtk(NULL, menu_model)); - app_indicator_set_menu(icon_, GTK_MENU(menu_->widget())); -} - -void AppIndicatorIcon::SetImageFromFile(const base::FilePath& icon_file_path) { - DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); - if (icon_file_path.empty()) - return; - - base::FilePath old_path = icon_file_path_; - icon_file_path_ = icon_file_path; - - std::string icon_name = - icon_file_path_.BaseName().RemoveExtension().value(); - std::string icon_dir = icon_file_path_.DirName().value(); - if (!icon_) { - icon_ = - app_indicator_new_with_path(id_.c_str(), - icon_name.c_str(), - APP_INDICATOR_CATEGORY_APPLICATION_STATUS, - icon_dir.c_str()); - app_indicator_set_status(icon_, APP_INDICATOR_STATUS_ACTIVE); - } else { - // Currently we are creating a new temp directory every time the icon is - // set. So we need to set the directory each time. - app_indicator_set_icon_theme_path(icon_, icon_dir.c_str()); - app_indicator_set_icon_full(icon_, icon_name.c_str(), "icon"); - - // Delete previous icon directory. - content::BrowserThread::GetBlockingPool()->PostTask( - FROM_HERE, - base::Bind(&DeleteTempImagePath, old_path.DirName())); - } -} - -} // namespace atom diff --git a/atom/browser/ui/gtk/app_indicator_icon.h b/atom/browser/ui/gtk/app_indicator_icon.h deleted file mode 100644 index 1799dc1b38ed..000000000000 --- a/atom/browser/ui/gtk/app_indicator_icon.h +++ /dev/null @@ -1,55 +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_UI_GTK_APP_INDICATOR_ICON_H_ -#define ATOM_BROWSER_UI_GTK_APP_INDICATOR_ICON_H_ - -#include - -#include "atom/browser/ui/tray_icon.h" -#include "base/files/file_path.h" -#include "base/memory/weak_ptr.h" -#include "ui/base/gtk/gtk_signal.h" - -typedef struct _AppIndicator AppIndicator; -typedef struct _GtkWidget GtkWidget; - -class MenuGtk; - -namespace atom { - -class AppIndicatorIcon : public TrayIcon { - public: - AppIndicatorIcon(); - virtual ~AppIndicatorIcon(); - - // Indicates whether libappindicator so could be opened. - static bool CouldOpen(); - - virtual void SetImage(const gfx::ImageSkia& image) OVERRIDE; - virtual void SetPressedImage(const gfx::ImageSkia& image) OVERRIDE; - virtual void SetToolTip(const std::string& tool_tip) OVERRIDE; - virtual void SetContextMenu(ui::SimpleMenuModel* menu_model) OVERRIDE; - - private: - void SetImageFromFile(const base::FilePath& icon_file_path); - - // Gtk status icon wrapper - AppIndicator* icon_; - - // The context menu for this icon (if any). - scoped_ptr menu_; - - std::string id_; - base::FilePath icon_file_path_; - int icon_change_count_; - - base::WeakPtrFactory weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(AppIndicatorIcon); -}; - -} // namespace atom - -#endif // ATOM_BROWSER_UI_GTK_APP_INDICATOR_ICON_H_ diff --git a/atom/browser/ui/gtk/status_icon.cc b/atom/browser/ui/gtk/status_icon.cc deleted file mode 100644 index 433e4af13e5c..000000000000 --- a/atom/browser/ui/gtk/status_icon.cc +++ /dev/null @@ -1,56 +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/gtk/status_icon.h" - -#include "chrome/browser/ui/gtk/menu_gtk.h" -#include "ui/gfx/gtk_util.h" - -namespace atom { - -StatusIcon::StatusIcon() : icon_(gtk_status_icon_new()) { - gtk_status_icon_set_visible(icon_, TRUE); - - g_signal_connect(icon_, "activate", G_CALLBACK(OnActivateThunk), this); - g_signal_connect(icon_, "popup-menu", G_CALLBACK(OnPopupMenuThunk), this); -} - -StatusIcon::~StatusIcon() { - gtk_status_icon_set_visible(icon_, FALSE); - g_object_unref(icon_); -} - -void StatusIcon::SetImage(const gfx::ImageSkia& image) { - if (image.isNull()) - return; - - GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap(*image.bitmap()); - gtk_status_icon_set_from_pixbuf(icon_, pixbuf); - g_object_unref(pixbuf); -} - -void StatusIcon::SetPressedImage(const gfx::ImageSkia& image) { - // Ignore pressed images, since the standard on Linux is to not highlight - // pressed status icons. -} - -void StatusIcon::SetToolTip(const std::string& tool_tip) { - gtk_status_icon_set_tooltip_text(icon_, tool_tip.c_str()); -} - -void StatusIcon::SetContextMenu(ui::SimpleMenuModel* menu_model) { - menu_.reset(new MenuGtk(NULL, menu_model)); -} - -void StatusIcon::OnPopupMenu(GtkWidget* widget, guint button, guint time) { - // If we have a menu - display it. - if (menu_.get()) - menu_->PopupAsContextForStatusIcon(time, button, icon_); -} - -void StatusIcon::OnActivate(GtkWidget* widget) { - NotifyClicked(); -} - -} // namespace atom diff --git a/atom/browser/ui/gtk/status_icon.h b/atom/browser/ui/gtk/status_icon.h deleted file mode 100644 index 9c8aa1f5abf2..000000000000 --- a/atom/browser/ui/gtk/status_icon.h +++ /dev/null @@ -1,47 +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_UI_GTK_STATUS_ICON_H_ -#define ATOM_BROWSER_UI_GTK_STATUS_ICON_H_ - -#include - -#include - -#include "atom/browser/ui/tray_icon.h" -#include "ui/base/gtk/gtk_signal.h" - -class MenuGtk; - -namespace atom { - -class StatusIcon : public TrayIcon { - public: - StatusIcon(); - virtual ~StatusIcon(); - - virtual void SetImage(const gfx::ImageSkia& image) OVERRIDE; - virtual void SetPressedImage(const gfx::ImageSkia& image) OVERRIDE; - virtual void SetToolTip(const std::string& tool_tip) OVERRIDE; - virtual void SetContextMenu(ui::SimpleMenuModel* menu_model) OVERRIDE; - - private: - // Callback invoked when user right-clicks on the status icon. - CHROMEGTK_CALLBACK_2(StatusIcon, void, OnPopupMenu, guint, guint); - - // Callback invoked when the icon is clicked. - CHROMEGTK_CALLBACK_0(StatusIcon, void, OnActivate); - - // The currently-displayed icon for the window. - GtkStatusIcon* icon_; - - // The context menu for this icon (if any). - scoped_ptr menu_; - - DISALLOW_COPY_AND_ASSIGN(StatusIcon); -}; - -} // namespace atom - -#endif // ATOM_BROWSER_UI_GTK_STATUS_ICON_H_ diff --git a/atom/browser/ui/tray_icon_gtk.cc b/atom/browser/ui/tray_icon_gtk.cc index fa9e82859ccb..2492cb14d607 100644 --- a/atom/browser/ui/tray_icon_gtk.cc +++ b/atom/browser/ui/tray_icon_gtk.cc @@ -2,17 +2,58 @@ // Use of this source code is governed by the MIT license that can be // found in the LICENSE file. -#include "atom/browser/ui/gtk/status_icon.h" -#include "atom/browser/ui/gtk/app_indicator_icon.h" +#include "atom/browser/ui/tray_icon_gtk.h" + +#include "base/guid.h" +#include "base/strings/utf_string_conversions.h" +#include "chrome/browser/ui/libgtk2ui/app_indicator_icon.h" +#include "chrome/browser/ui/libgtk2ui/gtk2_status_icon.h" namespace atom { +TrayIconGtk::TrayIconGtk() { +} + +TrayIconGtk::~TrayIconGtk() { +} + +void TrayIconGtk::SetImage(const gfx::ImageSkia& image) { + if (icon_) { + icon_->SetImage(image); + return; + } + + base::string16 empty; + if (libgtk2ui::AppIndicatorIcon::CouldOpen()) + icon_.reset( + new libgtk2ui::AppIndicatorIcon(base::GenerateGUID(), image, empty)); + else + icon_.reset(new libgtk2ui::Gtk2StatusIcon(image, empty)); + icon_->set_delegate(this); +} + +void TrayIconGtk::SetPressedImage(const gfx::ImageSkia& image) { + icon_->SetPressedImage(image); +} + +void TrayIconGtk::SetToolTip(const std::string& tool_tip) { + icon_->SetToolTip(base::UTF8ToUTF16(tool_tip)); +} + +void TrayIconGtk::SetContextMenu(ui::SimpleMenuModel* menu_model) { + icon_->UpdatePlatformContextMenu(menu_model); +} + +void TrayIconGtk::OnClick() { +} + +bool TrayIconGtk::HasClickAction() { + return false; +} + // static TrayIcon* TrayIcon::Create() { - if (AppIndicatorIcon::CouldOpen()) - return new AppIndicatorIcon; - else - return new StatusIcon; + return new TrayIconGtk; } } // namespace atom diff --git a/atom/browser/ui/tray_icon_gtk.h b/atom/browser/ui/tray_icon_gtk.h new file mode 100644 index 000000000000..61687b3afdab --- /dev/null +++ b/atom/browser/ui/tray_icon_gtk.h @@ -0,0 +1,43 @@ +// 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_UI_TRAY_ICON_GTK_H_ +#define ATOM_BROWSER_UI_TRAY_ICON_GTK_H_ + +#include + +#include "atom/browser/ui/tray_icon.h" +#include "ui/views/linux_ui/status_icon_linux.h" + +namespace views { +class StatusIconLinux; +} + +namespace atom { + +class TrayIconGtk : public TrayIcon, + public views::StatusIconLinux::Delegate { + public: + TrayIconGtk(); + virtual ~TrayIconGtk(); + + // TrayIcon: + virtual void SetImage(const gfx::ImageSkia& image) OVERRIDE; + virtual void SetPressedImage(const gfx::ImageSkia& image) OVERRIDE; + virtual void SetToolTip(const std::string& tool_tip) OVERRIDE; + virtual void SetContextMenu(ui::SimpleMenuModel* menu_model) OVERRIDE; + + private: + // views::StatusIconLinux::Delegate: + virtual void OnClick() OVERRIDE; + virtual bool HasClickAction() OVERRIDE; + + scoped_ptr icon_; + + DISALLOW_COPY_AND_ASSIGN(TrayIconGtk); +}; + +} // namespace atom + +#endif // ATOM_BROWSER_UI_TRAY_ICON_GTK_H_ diff --git a/chromium_src/chrome/browser/ui/gtk/event_utils.cc b/chromium_src/chrome/browser/ui/gtk/event_utils.cc deleted file mode 100644 index f61c12165674..000000000000 --- a/chromium_src/chrome/browser/ui/gtk/event_utils.cc +++ /dev/null @@ -1,44 +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/gtk/event_utils.h" - -#include "base/logging.h" -#include "ui/base/window_open_disposition.h" -#include "ui/events/event_constants.h" - -namespace event_utils { - -int EventFlagsFromGdkState(guint state) { - int flags = ui::EF_NONE; - flags |= (state & GDK_LOCK_MASK) ? ui::EF_CAPS_LOCK_DOWN : ui::EF_NONE; - flags |= (state & GDK_CONTROL_MASK) ? ui::EF_CONTROL_DOWN : ui::EF_NONE; - flags |= (state & GDK_SHIFT_MASK) ? ui::EF_SHIFT_DOWN : ui::EF_NONE; - flags |= (state & GDK_MOD1_MASK) ? ui::EF_ALT_DOWN : ui::EF_NONE; - flags |= (state & GDK_BUTTON1_MASK) ? ui::EF_LEFT_MOUSE_BUTTON : ui::EF_NONE; - flags |= (state & GDK_BUTTON2_MASK) ? ui::EF_MIDDLE_MOUSE_BUTTON - : ui::EF_NONE; - flags |= (state & GDK_BUTTON3_MASK) ? ui::EF_RIGHT_MOUSE_BUTTON : ui::EF_NONE; - return flags; -} - -// TODO(shinyak) This function will be removed after refactoring. -WindowOpenDisposition DispositionFromGdkState(guint state) { - int event_flags = EventFlagsFromGdkState(state); - return ui::DispositionFromEventFlags(event_flags); -} - -WindowOpenDisposition DispositionForCurrentButtonPressEvent() { - GdkEvent* event = gtk_get_current_event(); - if (!event) { - NOTREACHED(); - return NEW_FOREGROUND_TAB; - } - - guint state = event->button.state; - gdk_event_free(event); - return DispositionFromGdkState(state); -} - -} // namespace event_utils diff --git a/chromium_src/chrome/browser/ui/gtk/event_utils.h b/chromium_src/chrome/browser/ui/gtk/event_utils.h deleted file mode 100644 index fdcd8b7e6d24..000000000000 --- a/chromium_src/chrome/browser/ui/gtk/event_utils.h +++ /dev/null @@ -1,28 +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_GTK_EVENT_UTILS_H_ -#define CHROME_BROWSER_UI_GTK_EVENT_UTILS_H_ - -#include - -#include "ui/base/window_open_disposition.h" - -namespace event_utils { - -// Translates event flags into plaform independent event flags. -int EventFlagsFromGdkState(guint state); - -// Translates GdkEvent state into what kind of disposition they represent. -// For example, a middle click would mean to open a background tab. -WindowOpenDisposition DispositionFromGdkState(guint state); - -// Get the window open disposition from the state in gtk_get_current_event(). -// This is designed to be called inside a "clicked" event handler. It is an -// error to call it when gtk_get_current_event() won't return a GdkEventButton*. -WindowOpenDisposition DispositionForCurrentButtonPressEvent(); - -} // namespace event_utils - -#endif // CHROME_BROWSER_UI_GTK_EVENT_UTILS_H_ diff --git a/chromium_src/chrome/browser/ui/gtk/gtk_custom_menu.cc b/chromium_src/chrome/browser/ui/gtk/gtk_custom_menu.cc deleted file mode 100644 index bfa5a97284da..000000000000 --- a/chromium_src/chrome/browser/ui/gtk/gtk_custom_menu.cc +++ /dev/null @@ -1,150 +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/gtk/gtk_custom_menu.h" - -#include "chrome/browser/ui/gtk/gtk_custom_menu_item.h" - -G_DEFINE_TYPE(GtkCustomMenu, gtk_custom_menu, GTK_TYPE_MENU) - -// Stolen directly from gtkmenushell.c. I'd love to call the library version -// instead, but it's static and isn't exported. :( -static gint gtk_menu_shell_is_item(GtkMenuShell* menu_shell, - GtkWidget* child) { - GtkWidget *parent; - - g_return_val_if_fail(GTK_IS_MENU_SHELL(menu_shell), FALSE); - g_return_val_if_fail(child != NULL, FALSE); - - parent = gtk_widget_get_parent(child); - while (GTK_IS_MENU_SHELL(parent)) { - if (parent == reinterpret_cast(menu_shell)) - return TRUE; - parent = GTK_MENU_SHELL(parent)->parent_menu_shell; - } - - return FALSE; -} - -// Stolen directly from gtkmenushell.c. I'd love to call the library version -// instead, but it's static and isn't exported. :( -static GtkWidget* gtk_menu_shell_get_item(GtkMenuShell* menu_shell, - GdkEvent* event) { - GtkWidget* menu_item = gtk_get_event_widget(event); - - while (menu_item && !GTK_IS_MENU_ITEM(menu_item)) - menu_item = gtk_widget_get_parent(menu_item); - - if (menu_item && gtk_menu_shell_is_item(menu_shell, menu_item)) - return menu_item; - else - return NULL; -} - -// When processing a button event, abort processing if the cursor isn't in a -// clickable region. -static gboolean gtk_custom_menu_button_press(GtkWidget* widget, - GdkEventButton* event) { - GtkWidget* menu_item = gtk_menu_shell_get_item( - GTK_MENU_SHELL(widget), reinterpret_cast(event)); - if (GTK_IS_CUSTOM_MENU_ITEM(menu_item)) { - if (!gtk_custom_menu_item_is_in_clickable_region( - GTK_CUSTOM_MENU_ITEM(menu_item))) { - return TRUE; - } - } - - return GTK_WIDGET_CLASS(gtk_custom_menu_parent_class)-> - button_press_event(widget, event); -} - -// When processing a button event, abort processing if the cursor isn't in a -// clickable region. If it's in a button that doesn't dismiss the menu, fire -// that event and abort having the normal GtkMenu code run. -static gboolean gtk_custom_menu_button_release(GtkWidget* widget, - GdkEventButton* event) { - GtkWidget* menu_item = gtk_menu_shell_get_item( - GTK_MENU_SHELL(widget), reinterpret_cast(event)); - if (GTK_IS_CUSTOM_MENU_ITEM(menu_item)) { - if (!gtk_custom_menu_item_is_in_clickable_region( - GTK_CUSTOM_MENU_ITEM(menu_item))) { - // Stop processing this event. This isn't a clickable region. - return TRUE; - } - - if (gtk_custom_menu_item_try_no_dismiss_command( - GTK_CUSTOM_MENU_ITEM(menu_item))) { - return TRUE; - } - } - - return GTK_WIDGET_CLASS(gtk_custom_menu_parent_class)-> - button_release_event(widget, event); -} - -// Manually forward button press events to the menu item (and then do what we'd -// do normally). -static gboolean gtk_custom_menu_motion_notify(GtkWidget* widget, - GdkEventMotion* event) { - GtkWidget* menu_item = gtk_menu_shell_get_item( - GTK_MENU_SHELL(widget), (GdkEvent*)event); - if (GTK_IS_CUSTOM_MENU_ITEM(menu_item)) { - gtk_custom_menu_item_receive_motion_event(GTK_CUSTOM_MENU_ITEM(menu_item), - event->x, event->y); - } - - return GTK_WIDGET_CLASS(gtk_custom_menu_parent_class)-> - motion_notify_event(widget, event); -} - -static void gtk_custom_menu_move_current(GtkMenuShell* menu_shell, - GtkMenuDirectionType direction) { - // If the currently selected item is custom, we give it first chance to catch - // up/down events. - - // TODO(erg): We are breaking a GSEAL by directly accessing this. We'll need - // to fix this by the time gtk3 comes out. - GtkWidget* menu_item = GTK_MENU_SHELL(menu_shell)->active_menu_item; - if (GTK_IS_CUSTOM_MENU_ITEM(menu_item)) { - switch (direction) { - case GTK_MENU_DIR_PREV: - case GTK_MENU_DIR_NEXT: - if (gtk_custom_menu_item_handle_move(GTK_CUSTOM_MENU_ITEM(menu_item), - direction)) - return; - break; - default: - break; - } - } - - GTK_MENU_SHELL_CLASS(gtk_custom_menu_parent_class)-> - move_current(menu_shell, direction); - - // In the case of hitting PREV and transitioning to a custom menu, we want to - // make sure we're selecting the final item in the list, not the first one. - menu_item = GTK_MENU_SHELL(menu_shell)->active_menu_item; - if (GTK_IS_CUSTOM_MENU_ITEM(menu_item)) { - gtk_custom_menu_item_select_item_by_direction( - GTK_CUSTOM_MENU_ITEM(menu_item), direction); - } -} - -static void gtk_custom_menu_init(GtkCustomMenu* menu) { -} - -static void gtk_custom_menu_class_init(GtkCustomMenuClass* klass) { - GtkWidgetClass* widget_class = GTK_WIDGET_CLASS(klass); - GtkMenuShellClass* menu_shell_class = GTK_MENU_SHELL_CLASS(klass); - - widget_class->button_press_event = gtk_custom_menu_button_press; - widget_class->button_release_event = gtk_custom_menu_button_release; - widget_class->motion_notify_event = gtk_custom_menu_motion_notify; - - menu_shell_class->move_current = gtk_custom_menu_move_current; -} - -GtkWidget* gtk_custom_menu_new() { - return GTK_WIDGET(g_object_new(GTK_TYPE_CUSTOM_MENU, NULL)); -} diff --git a/chromium_src/chrome/browser/ui/gtk/gtk_custom_menu.h b/chromium_src/chrome/browser/ui/gtk/gtk_custom_menu.h deleted file mode 100644 index 7aaa2b54f6f5..000000000000 --- a/chromium_src/chrome/browser/ui/gtk/gtk_custom_menu.h +++ /dev/null @@ -1,51 +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_GTK_GTK_CUSTOM_MENU_H_ -#define CHROME_BROWSER_UI_GTK_GTK_CUSTOM_MENU_H_ - -// GtkCustomMenu is a GtkMenu subclass that can contain, and collaborates with, -// GtkCustomMenuItem instances. GtkCustomMenuItem is a GtkMenuItem that can -// have buttons and other normal widgets embeded in it. GtkCustomMenu exists -// only to override most of the button/motion/move callback functions so -// that the normal GtkMenu implementation doesn't handle events related to -// GtkCustomMenuItem items. -// -// For a more through overview of this system, see the comments in -// gtk_custom_menu_item.h. - -#include - -G_BEGIN_DECLS - -#define GTK_TYPE_CUSTOM_MENU \ - (gtk_custom_menu_get_type()) -#define GTK_CUSTOM_MENU(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_CUSTOM_MENU, GtkCustomMenu)) -#define GTK_CUSTOM_MENU_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_CUSTOM_MENU, GtkCustomMenuClass)) -#define GTK_IS_CUSTOM_MENU(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_CUSTOM_MENU)) -#define GTK_IS_CUSTOM_MENU_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_CUSTOM_MENU)) -#define GTK_CUSTOM_MENU_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_CUSTOM_MENU, GtkCustomMenuClass)) - -typedef struct _GtkCustomMenu GtkCustomMenu; -typedef struct _GtkCustomMenuClass GtkCustomMenuClass; - -struct _GtkCustomMenu { - GtkMenu menu; -}; - -struct _GtkCustomMenuClass { - GtkMenuClass parent_class; -}; - -GType gtk_custom_menu_get_type(void) G_GNUC_CONST; -GtkWidget* gtk_custom_menu_new(); - -G_END_DECLS - -#endif // CHROME_BROWSER_UI_GTK_GTK_CUSTOM_MENU_H_ diff --git a/chromium_src/chrome/browser/ui/gtk/gtk_custom_menu_item.cc b/chromium_src/chrome/browser/ui/gtk/gtk_custom_menu_item.cc deleted file mode 100644 index 2eda6010cea1..000000000000 --- a/chromium_src/chrome/browser/ui/gtk/gtk_custom_menu_item.cc +++ /dev/null @@ -1,493 +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/gtk/gtk_custom_menu_item.h" - -#include "base/i18n/rtl.h" -#include "chrome/browser/ui/gtk/gtk_custom_menu.h" -#include "ui/gfx/gtk_compat.h" - -// This method was autogenerated by the program glib-genmarshall, which -// generated it from the line "BOOL:INT". Two different attempts at getting gyp -// to autogenerate this didn't work. If we need more non-standard marshallers, -// this should be deleted, and an actual build step should be added. -void chrome_marshall_BOOLEAN__INT(GClosure* closure, - GValue* return_value G_GNUC_UNUSED, - guint n_param_values, - const GValue* param_values, - gpointer invocation_hint G_GNUC_UNUSED, - gpointer marshal_data) { - typedef gboolean(*GMarshalFunc_BOOLEAN__INT)(gpointer data1, - gint arg_1, - gpointer data2); - register GMarshalFunc_BOOLEAN__INT callback; - register GCClosure *cc = (GCClosure*)closure; - register gpointer data1, data2; - gboolean v_return; - - g_return_if_fail(return_value != NULL); - g_return_if_fail(n_param_values == 2); - - if (G_CCLOSURE_SWAP_DATA(closure)) { - data1 = closure->data; - // Note: This line (and the line setting data1 in the other if branch) - // were macros in the original autogenerated output. This is with the - // macro resolved for release mode. In debug mode, it uses an accessor - // that asserts saying that the object pointed to by param_values doesn't - // hold a pointer. This appears to be the cause of http://crbug.com/58945. - // - // This is more than a little odd because the gtype on this first param - // isn't set correctly by the time we get here, while I watched it - // explicitly set upstack. I verified that v_pointer is still set - // correctly. I'm not sure what's going on. :( - data2 = (param_values + 0)->data[0].v_pointer; - } else { - data1 = (param_values + 0)->data[0].v_pointer; - data2 = closure->data; - } - callback = (GMarshalFunc_BOOLEAN__INT)(marshal_data ? marshal_data : - cc->callback); - - v_return = callback(data1, - g_value_get_int(param_values + 1), - data2); - - g_value_set_boolean(return_value, v_return); -} - -enum { - BUTTON_PUSHED, - TRY_BUTTON_PUSHED, - LAST_SIGNAL -}; - -static guint custom_menu_item_signals[LAST_SIGNAL] = { 0 }; - -G_DEFINE_TYPE(GtkCustomMenuItem, gtk_custom_menu_item, GTK_TYPE_MENU_ITEM) - -static void set_selected(GtkCustomMenuItem* item, GtkWidget* selected) { - if (selected != item->currently_selected_button) { - if (item->currently_selected_button) { - gtk_widget_set_state(item->currently_selected_button, GTK_STATE_NORMAL); - gtk_widget_set_state( - gtk_bin_get_child(GTK_BIN(item->currently_selected_button)), - GTK_STATE_NORMAL); - } - - item->currently_selected_button = selected; - if (item->currently_selected_button) { - gtk_widget_set_state(item->currently_selected_button, GTK_STATE_SELECTED); - gtk_widget_set_state( - gtk_bin_get_child(GTK_BIN(item->currently_selected_button)), - GTK_STATE_PRELIGHT); - } - } -} - -// When GtkButtons set the label text, they rebuild the widget hierarchy each -// and every time. Therefore, we can't just fish out the label from the button -// and set some properties; we have to create this callback function that -// listens on the button's "notify" signal, which is emitted right after the -// label has been (re)created. (Label values can change dynamically.) -static void on_button_label_set(GObject* object) { - GtkButton* button = GTK_BUTTON(object); - GtkWidget* child = gtk_bin_get_child(GTK_BIN(button)); - gtk_widget_set_sensitive(child, FALSE); - gtk_misc_set_padding(GTK_MISC(child), 2, 0); -} - -static void gtk_custom_menu_item_finalize(GObject *object); -static gint gtk_custom_menu_item_expose(GtkWidget* widget, - GdkEventExpose* event); -static gboolean gtk_custom_menu_item_hbox_expose(GtkWidget* widget, - GdkEventExpose* event, - GtkCustomMenuItem* menu_item); -static void gtk_custom_menu_item_select(GtkItem *item); -static void gtk_custom_menu_item_deselect(GtkItem *item); -static void gtk_custom_menu_item_activate(GtkMenuItem* menu_item); - -static void gtk_custom_menu_item_init(GtkCustomMenuItem* item) { - item->all_widgets = NULL; - item->button_widgets = NULL; - item->currently_selected_button = NULL; - item->previously_selected_button = NULL; - - GtkWidget* menu_hbox = gtk_hbox_new(FALSE, 0); - gtk_container_add(GTK_CONTAINER(item), menu_hbox); - - item->label = gtk_label_new(NULL); - gtk_misc_set_alignment(GTK_MISC(item->label), 0.0, 0.5); - gtk_box_pack_start(GTK_BOX(menu_hbox), item->label, TRUE, TRUE, 0); - - item->hbox = gtk_hbox_new(FALSE, 0); - gtk_box_pack_end(GTK_BOX(menu_hbox), item->hbox, FALSE, FALSE, 0); - - g_signal_connect(item->hbox, "expose-event", - G_CALLBACK(gtk_custom_menu_item_hbox_expose), - item); - - gtk_widget_show_all(menu_hbox); -} - -static void gtk_custom_menu_item_class_init(GtkCustomMenuItemClass* klass) { - GObjectClass* gobject_class = G_OBJECT_CLASS(klass); - GtkWidgetClass* widget_class = GTK_WIDGET_CLASS(klass); - GtkItemClass* item_class = GTK_ITEM_CLASS(klass); - GtkMenuItemClass* menu_item_class = GTK_MENU_ITEM_CLASS(klass); - - gobject_class->finalize = gtk_custom_menu_item_finalize; - - widget_class->expose_event = gtk_custom_menu_item_expose; - - item_class->select = gtk_custom_menu_item_select; - item_class->deselect = gtk_custom_menu_item_deselect; - - menu_item_class->activate = gtk_custom_menu_item_activate; - - custom_menu_item_signals[BUTTON_PUSHED] = - g_signal_new("button-pushed", - G_TYPE_FROM_CLASS(gobject_class), - G_SIGNAL_RUN_FIRST, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__INT, - G_TYPE_NONE, 1, G_TYPE_INT); - custom_menu_item_signals[TRY_BUTTON_PUSHED] = - g_signal_new("try-button-pushed", - G_TYPE_FROM_CLASS(gobject_class), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, - chrome_marshall_BOOLEAN__INT, - G_TYPE_BOOLEAN, 1, G_TYPE_INT); -} - -static void gtk_custom_menu_item_finalize(GObject *object) { - GtkCustomMenuItem* item = GTK_CUSTOM_MENU_ITEM(object); - g_list_free(item->all_widgets); - g_list_free(item->button_widgets); - - G_OBJECT_CLASS(gtk_custom_menu_item_parent_class)->finalize(object); -} - -static gint gtk_custom_menu_item_expose(GtkWidget* widget, - GdkEventExpose* event) { - if (gtk_widget_get_visible(widget) && - gtk_widget_get_mapped(widget) && - gtk_bin_get_child(GTK_BIN(widget))) { - // We skip the drawing in the GtkMenuItem class it draws the highlighted - // background and we don't want that. - gtk_container_propagate_expose(GTK_CONTAINER(widget), - gtk_bin_get_child(GTK_BIN(widget)), - event); - } - - return FALSE; -} - -static void gtk_custom_menu_item_expose_button(GtkWidget* hbox, - GdkEventExpose* event, - GList* button_item) { - // We search backwards to find the leftmost and rightmost buttons. The - // current button may be that button. - GtkWidget* current_button = GTK_WIDGET(button_item->data); - GtkWidget* first_button = current_button; - for (GList* i = button_item; i && GTK_IS_BUTTON(i->data); - i = g_list_previous(i)) { - first_button = GTK_WIDGET(i->data); - } - - GtkWidget* last_button = current_button; - for (GList* i = button_item; i && GTK_IS_BUTTON(i->data); - i = g_list_next(i)) { - last_button = GTK_WIDGET(i->data); - } - - if (base::i18n::IsRTL()) - std::swap(first_button, last_button); - - GtkAllocation first_allocation; - gtk_widget_get_allocation(first_button, &first_allocation); - GtkAllocation current_allocation; - gtk_widget_get_allocation(current_button, ¤t_allocation); - GtkAllocation last_allocation; - gtk_widget_get_allocation(last_button, &last_allocation); - - int x = first_allocation.x; - int y = first_allocation.y; - int width = last_allocation.width + last_allocation.x - first_allocation.x; - int height = last_allocation.height; - - gtk_paint_box(gtk_widget_get_style(hbox), - gtk_widget_get_window(hbox), - gtk_widget_get_state(current_button), - GTK_SHADOW_OUT, - ¤t_allocation, hbox, "button", - x, y, width, height); - - // Propagate to the button's children. - gtk_container_propagate_expose( - GTK_CONTAINER(current_button), - gtk_bin_get_child(GTK_BIN(current_button)), - event); -} - -static gboolean gtk_custom_menu_item_hbox_expose(GtkWidget* widget, - GdkEventExpose* event, - GtkCustomMenuItem* menu_item) { - // First render all the buttons that aren't the currently selected item. - for (GList* current_item = menu_item->all_widgets; - current_item != NULL; current_item = g_list_next(current_item)) { - if (GTK_IS_BUTTON(current_item->data)) { - if (GTK_WIDGET(current_item->data) != - menu_item->currently_selected_button) { - gtk_custom_menu_item_expose_button(widget, event, current_item); - } - } - } - - // As a separate pass, draw the buton separators above. We need to draw the - // separators in a separate pass because we are drawing on top of the - // buttons. Otherwise, the vlines are overwritten by the next button. - for (GList* current_item = menu_item->all_widgets; - current_item != NULL; current_item = g_list_next(current_item)) { - if (GTK_IS_BUTTON(current_item->data)) { - // Check to see if this is the last button in a run. - GList* next_item = g_list_next(current_item); - if (next_item && GTK_IS_BUTTON(next_item->data)) { - GtkWidget* current_button = GTK_WIDGET(current_item->data); - GtkAllocation button_allocation; - gtk_widget_get_allocation(current_button, &button_allocation); - GtkAllocation child_alloc; - gtk_widget_get_allocation(gtk_bin_get_child(GTK_BIN(current_button)), - &child_alloc); - GtkStyle* style = gtk_widget_get_style(widget); - int half_offset = style->xthickness / 2; - gtk_paint_vline(style, - gtk_widget_get_window(widget), - gtk_widget_get_state(current_button), - &event->area, widget, "button", - child_alloc.y, - child_alloc.y + child_alloc.height, - button_allocation.x + - button_allocation.width - half_offset); - } - } - } - - // Finally, draw the selected item on top of the separators so there are no - // artifacts inside the button area. - GList* selected = g_list_find(menu_item->all_widgets, - menu_item->currently_selected_button); - if (selected) { - gtk_custom_menu_item_expose_button(widget, event, selected); - } - - return TRUE; -} - -static void gtk_custom_menu_item_select(GtkItem* item) { - GtkCustomMenuItem* custom_item = GTK_CUSTOM_MENU_ITEM(item); - - // When we are selected, the only thing we do is clear information from - // previous selections. Actual selection of a button is done either in the - // "mouse-motion-event" or is manually set from GtkCustomMenu's overridden - // "move-current" handler. - custom_item->previously_selected_button = NULL; - - gtk_widget_queue_draw(GTK_WIDGET(item)); -} - -static void gtk_custom_menu_item_deselect(GtkItem* item) { - GtkCustomMenuItem* custom_item = GTK_CUSTOM_MENU_ITEM(item); - - // When we are deselected, we store the item that was currently selected so - // that it can be acted on. Menu items are first deselected before they are - // activated. - custom_item->previously_selected_button = - custom_item->currently_selected_button; - if (custom_item->currently_selected_button) - set_selected(custom_item, NULL); - - gtk_widget_queue_draw(GTK_WIDGET(item)); -} - -static void gtk_custom_menu_item_activate(GtkMenuItem* menu_item) { - GtkCustomMenuItem* custom_item = GTK_CUSTOM_MENU_ITEM(menu_item); - - // We look at |previously_selected_button| because by the time we've been - // activated, we've already gone through our deselect handler. - if (custom_item->previously_selected_button) { - gpointer id_ptr = g_object_get_data( - G_OBJECT(custom_item->previously_selected_button), "command-id"); - if (id_ptr != NULL) { - int command_id = GPOINTER_TO_INT(id_ptr); - g_signal_emit(custom_item, custom_menu_item_signals[BUTTON_PUSHED], 0, - command_id); - set_selected(custom_item, NULL); - } - } -} - -GtkWidget* gtk_custom_menu_item_new(const char* title) { - GtkCustomMenuItem* item = GTK_CUSTOM_MENU_ITEM( - g_object_new(GTK_TYPE_CUSTOM_MENU_ITEM, NULL)); - gtk_label_set_text(GTK_LABEL(item->label), title); - return GTK_WIDGET(item); -} - -GtkWidget* gtk_custom_menu_item_add_button(GtkCustomMenuItem* menu_item, - int command_id) { - GtkWidget* button = gtk_button_new(); - g_object_set_data(G_OBJECT(button), "command-id", - GINT_TO_POINTER(command_id)); - gtk_box_pack_start(GTK_BOX(menu_item->hbox), button, FALSE, FALSE, 0); - gtk_widget_show(button); - - menu_item->all_widgets = g_list_append(menu_item->all_widgets, button); - menu_item->button_widgets = g_list_append(menu_item->button_widgets, button); - - return button; -} - -GtkWidget* gtk_custom_menu_item_add_button_label(GtkCustomMenuItem* menu_item, - int command_id) { - GtkWidget* button = gtk_button_new_with_label(""); - g_object_set_data(G_OBJECT(button), "command-id", - GINT_TO_POINTER(command_id)); - gtk_box_pack_start(GTK_BOX(menu_item->hbox), button, FALSE, FALSE, 0); - g_signal_connect(button, "notify::label", - G_CALLBACK(on_button_label_set), NULL); - gtk_widget_show(button); - - menu_item->all_widgets = g_list_append(menu_item->all_widgets, button); - - return button; -} - -void gtk_custom_menu_item_add_space(GtkCustomMenuItem* menu_item) { - GtkWidget* fixed = gtk_fixed_new(); - gtk_widget_set_size_request(fixed, 5, -1); - - gtk_box_pack_start(GTK_BOX(menu_item->hbox), fixed, FALSE, FALSE, 0); - gtk_widget_show(fixed); - - menu_item->all_widgets = g_list_append(menu_item->all_widgets, fixed); -} - -void gtk_custom_menu_item_receive_motion_event(GtkCustomMenuItem* menu_item, - gdouble x, gdouble y) { - GtkWidget* new_selected_widget = NULL; - GList* current = menu_item->button_widgets; - for (; current != NULL; current = current->next) { - GtkWidget* current_widget = GTK_WIDGET(current->data); - GtkAllocation alloc; - gtk_widget_get_allocation(current_widget, &alloc); - int offset_x, offset_y; - gtk_widget_translate_coordinates(current_widget, GTK_WIDGET(menu_item), - 0, 0, &offset_x, &offset_y); - if (x >= offset_x && x < (offset_x + alloc.width) && - y >= offset_y && y < (offset_y + alloc.height)) { - new_selected_widget = current_widget; - break; - } - } - - set_selected(menu_item, new_selected_widget); -} - -gboolean gtk_custom_menu_item_handle_move(GtkCustomMenuItem* menu_item, - GtkMenuDirectionType direction) { - GtkWidget* current = menu_item->currently_selected_button; - if (menu_item->button_widgets && current) { - switch (direction) { - case GTK_MENU_DIR_PREV: { - if (g_list_first(menu_item->button_widgets)->data == current) - return FALSE; - - set_selected(menu_item, GTK_WIDGET(g_list_previous(g_list_find( - menu_item->button_widgets, current))->data)); - break; - } - case GTK_MENU_DIR_NEXT: { - if (g_list_last(menu_item->button_widgets)->data == current) - return FALSE; - - set_selected(menu_item, GTK_WIDGET(g_list_next(g_list_find( - menu_item->button_widgets, current))->data)); - break; - } - default: - break; - } - } - - return TRUE; -} - -void gtk_custom_menu_item_select_item_by_direction( - GtkCustomMenuItem* menu_item, GtkMenuDirectionType direction) { - menu_item->previously_selected_button = NULL; - - // If we're just told to be selected by the menu system, select the first - // item. - if (menu_item->button_widgets) { - switch (direction) { - case GTK_MENU_DIR_PREV: { - GtkWidget* last_button = - GTK_WIDGET(g_list_last(menu_item->button_widgets)->data); - if (last_button) - set_selected(menu_item, last_button); - break; - } - case GTK_MENU_DIR_NEXT: { - GtkWidget* first_button = - GTK_WIDGET(g_list_first(menu_item->button_widgets)->data); - if (first_button) - set_selected(menu_item, first_button); - break; - } - default: - break; - } - } - - gtk_widget_queue_draw(GTK_WIDGET(menu_item)); -} - -gboolean gtk_custom_menu_item_is_in_clickable_region( - GtkCustomMenuItem* menu_item) { - return menu_item->currently_selected_button != NULL; -} - -gboolean gtk_custom_menu_item_try_no_dismiss_command( - GtkCustomMenuItem* menu_item) { - GtkCustomMenuItem* custom_item = GTK_CUSTOM_MENU_ITEM(menu_item); - gboolean activated = TRUE; - - // We work with |currently_selected_button| instead of - // |previously_selected_button| since we haven't been "deselect"ed yet. - gpointer id_ptr = g_object_get_data( - G_OBJECT(custom_item->currently_selected_button), "command-id"); - if (id_ptr != NULL) { - int command_id = GPOINTER_TO_INT(id_ptr); - g_signal_emit(custom_item, custom_menu_item_signals[TRY_BUTTON_PUSHED], 0, - command_id, &activated); - } - - return activated; -} - -void gtk_custom_menu_item_foreach_button(GtkCustomMenuItem* menu_item, - GtkCallback callback, - gpointer callback_data) { - // Even though we're filtering |all_widgets| on GTK_IS_BUTTON(), this isn't - // equivalent to |button_widgets| because we also want the button-labels. - for (GList* i = menu_item->all_widgets; i && GTK_IS_BUTTON(i->data); - i = g_list_next(i)) { - if (GTK_IS_BUTTON(i->data)) { - callback(GTK_WIDGET(i->data), callback_data); - } - } -} diff --git a/chromium_src/chrome/browser/ui/gtk/gtk_custom_menu_item.h b/chromium_src/chrome/browser/ui/gtk/gtk_custom_menu_item.h deleted file mode 100644 index 46e5cf721e9b..000000000000 --- a/chromium_src/chrome/browser/ui/gtk/gtk_custom_menu_item.h +++ /dev/null @@ -1,139 +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_GTK_GTK_CUSTOM_MENU_ITEM_H_ -#define CHROME_BROWSER_UI_GTK_GTK_CUSTOM_MENU_ITEM_H_ - -// GtkCustomMenuItem is a GtkMenuItem subclass that has buttons in it and acts -// to support this. GtkCustomMenuItems only render properly when put in a -// GtkCustomMenu; there's a lot of collaboration between these two classes -// necessary to work around how gtk normally does menus. -// -// We can't rely on the normal event infrastructure. While a menu is up, the -// GtkMenu has a grab on all events. Instead of trying to pump events through -// the normal channels, we have the GtkCustomMenu selectively forward mouse -// motion through a back channel. The GtkCustomMenu only listens for button -// press information so it can block the effects of the click if the cursor -// isn't in a button in the menu item. -// -// A GtkCustomMenuItem doesn't try to take these signals and forward them to -// the buttons it owns. The GtkCustomMenu class keeps track of which button is -// selected (due to key events and mouse movement) and otherwise acts like a -// normal GtkItem. The buttons are only for sizing and rendering; they don't -// respond to events. Instead, when the GtkCustomMenuItem is activated by the -// GtkMenu, it uses which button was selected as a signal of what to do. -// -// Users should connect to the "button-pushed" signal to be notified when a -// button was pushed. We don't go through the normal "activate" signal because -// we need to communicate additional information, namely which button was -// activated. - -#include - -G_BEGIN_DECLS - -#define GTK_TYPE_CUSTOM_MENU_ITEM \ - (gtk_custom_menu_item_get_type()) -#define GTK_CUSTOM_MENU_ITEM(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_CUSTOM_MENU_ITEM, \ - GtkCustomMenuItem)) -#define GTK_CUSTOM_MENU_ITEM_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_CUSTOM_MENU_ITEM, \ - GtkCustomMenuItemClass)) -#define GTK_IS_CUSTOM_MENU_ITEM(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_CUSTOM_MENU_ITEM)) -#define GTK_IS_CUSTOM_MENU_ITEM_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_CUSTOM_MENU_ITEM)) -#define GTK_CUSTOM_MENU_ITEM_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_CUSTOM_MENU_ITEM, \ - GtkCustomMenuItemClass)) - -typedef struct _GtkCustomMenuItem GtkCustomMenuItem; -typedef struct _GtkCustomMenuItemClass GtkCustomMenuItemClass; - -struct _GtkCustomMenuItem { - GtkMenuItem menu_item; - - // Container for button widgets. - GtkWidget* hbox; - - // Label on left side of menu item. - GtkWidget* label; - - // List of all widgets we added. Used to find the leftmost and rightmost - // continuous buttons. - GList* all_widgets; - - // Possible button widgets. Used for keyboard navigation. - GList* button_widgets; - - // The widget that currently has highlight. - GtkWidget* currently_selected_button; - - // The widget that was selected *before* |currently_selected_button|. Why do - // we hang on to this? Because the menu system sends us a deselect signal - // right before activating us. We need to listen to deselect since that's - // what we receive when the mouse cursor leaves us entirely. - GtkWidget* previously_selected_button; -}; - -struct _GtkCustomMenuItemClass { - GtkMenuItemClass parent_class; -}; - -GType gtk_custom_menu_item_get_type(void) G_GNUC_CONST; -GtkWidget* gtk_custom_menu_item_new(const char* title); - -// Adds a button to our list of items in the |hbox|. -GtkWidget* gtk_custom_menu_item_add_button(GtkCustomMenuItem* menu_item, - int command_id); - -// Adds a button to our list of items in the |hbox|, but that isn't part of -// |button_widgets| to prevent it from being activatable. -GtkWidget* gtk_custom_menu_item_add_button_label(GtkCustomMenuItem* menu_item, - int command_id); - -// Adds a vertical space in the |hbox|. -void gtk_custom_menu_item_add_space(GtkCustomMenuItem* menu_item); - -// Receives a motion event from the GtkCustomMenu that contains us. We can't -// just subscribe to motion-event or the individual widget enter/leave events -// because the top level GtkMenu has an event grab. -void gtk_custom_menu_item_receive_motion_event(GtkCustomMenuItem* menu_item, - gdouble x, gdouble y); - -// Notification that the menu got a cursor key event. Used to move up/down -// within the menu buttons. Returns TRUE to stop the default signal handler -// from running. -gboolean gtk_custom_menu_item_handle_move(GtkCustomMenuItem* menu_item, - GtkMenuDirectionType direction); - -// Because we only get a generic "selected" signal when we've changed, we need -// to have a way for the GtkCustomMenu to tell us that we were just -// selected. -void gtk_custom_menu_item_select_item_by_direction( - GtkCustomMenuItem* menu_item, GtkMenuDirectionType direction); - -// Whether we are currently hovering over a clickable region on the menu -// item. Used by GtkCustomMenu to determine whether it should discard click -// events. -gboolean gtk_custom_menu_item_is_in_clickable_region( - GtkCustomMenuItem* menu_item); - -// If the button is released while the |currently_selected_button| isn't -// supposed to dismiss the menu, this signals to our listeners that we want to -// run this command if it doesn't dismiss the menu. Returns TRUE if we acted -// on this button click (and should prevent the normal GtkMenu machinery from -// firing an "activate" signal). -gboolean gtk_custom_menu_item_try_no_dismiss_command( - GtkCustomMenuItem* menu_item); - -// Calls |callback| with every button and button-label in the container. -void gtk_custom_menu_item_foreach_button(GtkCustomMenuItem* menu_item, - GtkCallback callback, - gpointer callback_data); - -G_END_DECLS - -#endif // CHROME_BROWSER_UI_GTK_GTK_CUSTOM_MENU_ITEM_H_ diff --git a/chromium_src/chrome/browser/ui/gtk/gtk_util.cc b/chromium_src/chrome/browser/ui/gtk/gtk_util.cc deleted file mode 100644 index b24c375e2c11..000000000000 --- a/chromium_src/chrome/browser/ui/gtk/gtk_util.cc +++ /dev/null @@ -1,94 +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/gtk/gtk_util.h" - -#include - -#include "base/logging.h" - -namespace gtk_util { - -namespace { - -const char kBoldLabelMarkup[] = "%s"; - -// Returns the approximate number of characters that can horizontally fit in -// |pixel_width| pixels. -int GetCharacterWidthForPixels(GtkWidget* widget, int pixel_width) { - DCHECK(gtk_widget_get_realized(widget)) - << " widget must be realized to compute font metrics correctly"; - - PangoContext* context = gtk_widget_create_pango_context(widget); - GtkStyle* style = gtk_widget_get_style(widget); - PangoFontMetrics* metrics = pango_context_get_metrics(context, - style->font_desc, pango_context_get_language(context)); - - // This technique (max of char and digit widths) matches the code in - // gtklabel.c. - int char_width = pixel_width * PANGO_SCALE / - std::max(pango_font_metrics_get_approximate_char_width(metrics), - pango_font_metrics_get_approximate_digit_width(metrics)); - - pango_font_metrics_unref(metrics); - g_object_unref(context); - - return char_width; -} - -void OnLabelRealize(GtkWidget* label, gpointer pixel_width) { - gtk_label_set_width_chars( - GTK_LABEL(label), - GetCharacterWidthForPixels(label, GPOINTER_TO_INT(pixel_width))); -} - -} // namespace - -GtkWidget* LeftAlignMisc(GtkWidget* misc) { - gtk_misc_set_alignment(GTK_MISC(misc), 0, 0.5); - return misc; -} - -GtkWidget* CreateBoldLabel(const std::string& text) { - GtkWidget* label = gtk_label_new(NULL); - char* markup = g_markup_printf_escaped(kBoldLabelMarkup, text.c_str()); - gtk_label_set_markup(GTK_LABEL(label), markup); - g_free(markup); - - return LeftAlignMisc(label); -} - -void SetAlwaysShowImage(GtkWidget* image_menu_item) { - gtk_image_menu_item_set_always_show_image( - GTK_IMAGE_MENU_ITEM(image_menu_item), TRUE); -} - -bool IsWidgetAncestryVisible(GtkWidget* widget) { - GtkWidget* parent = widget; - while (parent && gtk_widget_get_visible(parent)) - parent = gtk_widget_get_parent(parent); - return !parent; -} - -void SetLabelWidth(GtkWidget* label, int pixel_width) { - gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - - // Do the simple thing in LTR because the bug only affects right-aligned - // text. Also, when using the workaround, the label tries to maintain - // uniform line-length, which we don't really want. - if (gtk_widget_get_direction(label) == GTK_TEXT_DIR_LTR) { - gtk_widget_set_size_request(label, pixel_width, -1); - } else { - // The label has to be realized before we can adjust its width. - if (gtk_widget_get_realized(label)) { - OnLabelRealize(label, GINT_TO_POINTER(pixel_width)); - } else { - g_signal_connect(label, "realize", G_CALLBACK(OnLabelRealize), - GINT_TO_POINTER(pixel_width)); - } - } -} - -} // namespace gtk_util diff --git a/chromium_src/chrome/browser/ui/gtk/gtk_util.h b/chromium_src/chrome/browser/ui/gtk/gtk_util.h deleted file mode 100644 index 2434a386e78a..000000000000 --- a/chromium_src/chrome/browser/ui/gtk/gtk_util.h +++ /dev/null @@ -1,36 +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_GTK_GTK_UTIL_H_ -#define CHROME_BROWSER_UI_GTK_GTK_UTIL_H_ - -#include -#include - -namespace gtk_util { - -// Left-align the given GtkMisc and return the same pointer. -GtkWidget* LeftAlignMisc(GtkWidget* misc); - -// Create a left-aligned label with the given text in bold. -GtkWidget* CreateBoldLabel(const std::string& text); - -// Show the image for the given menu item, even if the user's default is to not -// show images. Only to be used for favicons or other menus where the image is -// crucial to its functionality. -void SetAlwaysShowImage(GtkWidget* image_menu_item); - -// Checks whether a widget is actually visible, i.e. whether it and all its -// ancestors up to its toplevel are visible. -bool IsWidgetAncestryVisible(GtkWidget* widget); - -// Sets the given label's size request to |pixel_width|. This will cause the -// label to wrap if it needs to. The reason for this function is that some -// versions of GTK mis-align labels that have a size request and line wrapping, -// and this function hides the complexity of the workaround. -void SetLabelWidth(GtkWidget* label, int pixel_width); - -} // namespace gtk_util - -#endif // CHROME_BROWSER_UI_GTK_GTK_UTIL_H_ diff --git a/chromium_src/chrome/browser/ui/gtk/gtk_window_util.cc b/chromium_src/chrome/browser/ui/gtk/gtk_window_util.cc deleted file mode 100644 index bce160a288df..000000000000 --- a/chromium_src/chrome/browser/ui/gtk/gtk_window_util.cc +++ /dev/null @@ -1,257 +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/gtk/gtk_window_util.h" - -#include -#include "content/public/browser/render_view_host.h" -#include "content/public/browser/web_contents.h" -#include "content/public/browser/web_contents_view.h" - -using content::RenderWidgetHost; -using content::WebContents; - -namespace gtk_window_util { - -const int kFrameBorderThickness = 4; -const int kResizeAreaCornerSize = 16; - -// Keep track of the last click time and the last click position so we can -// filter out extra GDK_BUTTON_PRESS events when a double click happens. -static guint32 last_click_time; -static int last_click_x; -static int last_click_y; - -// Ubuntu patches their version of GTK+ so that there is always a -// gripper in the bottom right corner of the window. We dynamically -// look up this symbol because it's a non-standard Ubuntu extension to -// GTK+. We always need to disable this feature since we can't -// communicate this to WebKit easily. -typedef void (*gtk_window_set_has_resize_grip_func)(GtkWindow*, gboolean); -gtk_window_set_has_resize_grip_func gtk_window_set_has_resize_grip_sym; - -void DisableResizeGrip(GtkWindow* window) { - static bool resize_grip_looked_up = false; - if (!resize_grip_looked_up) { - resize_grip_looked_up = true; - gtk_window_set_has_resize_grip_sym = - reinterpret_cast( - dlsym(NULL, "gtk_window_set_has_resize_grip")); - } - if (gtk_window_set_has_resize_grip_sym) - gtk_window_set_has_resize_grip_sym(window, FALSE); -} - -GdkCursorType GdkWindowEdgeToGdkCursorType(GdkWindowEdge edge) { - switch (edge) { - case GDK_WINDOW_EDGE_NORTH_WEST: - return GDK_TOP_LEFT_CORNER; - case GDK_WINDOW_EDGE_NORTH: - return GDK_TOP_SIDE; - case GDK_WINDOW_EDGE_NORTH_EAST: - return GDK_TOP_RIGHT_CORNER; - case GDK_WINDOW_EDGE_WEST: - return GDK_LEFT_SIDE; - case GDK_WINDOW_EDGE_EAST: - return GDK_RIGHT_SIDE; - case GDK_WINDOW_EDGE_SOUTH_WEST: - return GDK_BOTTOM_LEFT_CORNER; - case GDK_WINDOW_EDGE_SOUTH: - return GDK_BOTTOM_SIDE; - case GDK_WINDOW_EDGE_SOUTH_EAST: - return GDK_BOTTOM_RIGHT_CORNER; - default: - NOTREACHED(); - } - return GDK_LAST_CURSOR; -} - -bool BoundsMatchMonitorSize(GtkWindow* window, gfx::Rect bounds) { - // A screen can be composed of multiple monitors. - GdkScreen* screen = gtk_window_get_screen(window); - GdkRectangle monitor_size; - - if (gtk_widget_get_realized(GTK_WIDGET(window))) { - // |window| has been realized. - gint monitor_num = gdk_screen_get_monitor_at_window(screen, - gtk_widget_get_window(GTK_WIDGET(window))); - gdk_screen_get_monitor_geometry(screen, monitor_num, &monitor_size); - return bounds.size() == gfx::Size(monitor_size.width, monitor_size.height); - } - - // Make sure the window doesn't match any monitor size. We compare against - // all monitors because we don't know which monitor the window is going to - // open on before window realized. - gint num_monitors = gdk_screen_get_n_monitors(screen); - for (gint i = 0; i < num_monitors; ++i) { - GdkRectangle monitor_size; - gdk_screen_get_monitor_geometry(screen, i, &monitor_size); - if (bounds.size() == gfx::Size(monitor_size.width, monitor_size.height)) - return true; - } - return false; -} - -bool HandleTitleBarLeftMousePress( - GtkWindow* window, - const gfx::Rect& bounds, - GdkEventButton* event) { - // We want to start a move when the user single clicks, but not start a - // move when the user double clicks. However, a double click sends the - // following GDK events: GDK_BUTTON_PRESS, GDK_BUTTON_RELEASE, - // GDK_BUTTON_PRESS, GDK_2BUTTON_PRESS, GDK_BUTTON_RELEASE. If we - // start a gtk_window_begin_move_drag on the second GDK_BUTTON_PRESS, - // the call to gtk_window_maximize fails. To work around this, we - // keep track of the last click and if it's going to be a double click, - // we don't call gtk_window_begin_move_drag. - DCHECK_EQ(event->type, GDK_BUTTON_PRESS); - DCHECK_EQ(event->button, 1); - - static GtkSettings* settings = gtk_settings_get_default(); - gint double_click_time = 250; - gint double_click_distance = 5; - g_object_get(G_OBJECT(settings), - "gtk-double-click-time", &double_click_time, - "gtk-double-click-distance", &double_click_distance, - NULL); - - guint32 click_time = event->time - last_click_time; - int click_move_x = abs(event->x - last_click_x); - int click_move_y = abs(event->y - last_click_y); - - last_click_time = event->time; - last_click_x = static_cast(event->x); - last_click_y = static_cast(event->y); - - if (click_time > static_cast(double_click_time) || - click_move_x > double_click_distance || - click_move_y > double_click_distance) { - // Ignore drag requests if the window is the size of the screen. - // We do this to avoid triggering fullscreen mode in metacity - // (without the --no-force-fullscreen flag) and in compiz (with - // Legacy Fullscreen Mode enabled). - if (!BoundsMatchMonitorSize(window, bounds)) { - gtk_window_begin_move_drag(window, event->button, - static_cast(event->x_root), - static_cast(event->y_root), - event->time); - } - return TRUE; - } - return FALSE; -} - -void UnMaximize(GtkWindow* window, - const gfx::Rect& bounds, - const gfx::Rect& restored_bounds) { - gtk_window_unmaximize(window); - - // It can happen that you end up with a window whose restore size is the same - // as the size of the screen, so unmaximizing it merely remaximizes it due to - // the same WM feature that SetWindowSize() works around. We try to detect - // this and resize the window to work around the issue. - if (bounds.size() == restored_bounds.size()) - gtk_window_resize(window, bounds.width(), bounds.height() - 1); -} - -void SetWindowCustomClass(GtkWindow* window, const std::string& wmclass) { - gtk_window_set_wmclass(window, - wmclass.c_str(), - gdk_get_program_class()); - - // Set WM_WINDOW_ROLE for session management purposes. - // See http://tronche.com/gui/x/icccm/sec-5.html . - gtk_window_set_role(window, wmclass.c_str()); -} - -void SetWindowSize(GtkWindow* window, const gfx::Size& size) { - gfx::Size new_size = size; - gint current_width = 0; - gint current_height = 0; - gtk_window_get_size(window, ¤t_width, ¤t_height); - GdkRectangle size_with_decorations = {0}; - GdkWindow* gdk_window = gtk_widget_get_window(GTK_WIDGET(window)); - if (gdk_window) { - gdk_window_get_frame_extents(gdk_window, - &size_with_decorations); - } - - if (current_width == size_with_decorations.width && - current_height == size_with_decorations.height) { - // Make sure the window doesn't match any monitor size. We compare against - // all monitors because we don't know which monitor the window is going to - // open on (the WM decides that). - GdkScreen* screen = gtk_window_get_screen(window); - gint num_monitors = gdk_screen_get_n_monitors(screen); - for (gint i = 0; i < num_monitors; ++i) { - GdkRectangle monitor_size; - gdk_screen_get_monitor_geometry(screen, i, &monitor_size); - if (gfx::Size(monitor_size.width, monitor_size.height) == size) { - gtk_window_resize(window, size.width(), size.height() - 1); - return; - } - } - } else { - // gtk_window_resize is the size of the window not including decorations, - // but we are given the |size| including window decorations. - if (size_with_decorations.width > current_width) { - new_size.set_width(size.width() - size_with_decorations.width + - current_width); - } - if (size_with_decorations.height > current_height) { - new_size.set_height(size.height() - size_with_decorations.height + - current_height); - } - } - - gtk_window_resize(window, new_size.width(), new_size.height()); -} - -bool GetWindowEdge(const gfx::Size& window_size, - int top_edge_inset, - int x, - int y, - GdkWindowEdge* edge) { - gfx::Rect middle(window_size); - middle.Inset(kFrameBorderThickness, - kFrameBorderThickness - top_edge_inset, - kFrameBorderThickness, - kFrameBorderThickness); - if (middle.Contains(x, y)) - return false; - - gfx::Rect north(0, 0, window_size.width(), - kResizeAreaCornerSize - top_edge_inset); - gfx::Rect west(0, 0, kResizeAreaCornerSize, window_size.height()); - gfx::Rect south(0, window_size.height() - kResizeAreaCornerSize, - window_size.width(), kResizeAreaCornerSize); - gfx::Rect east(window_size.width() - kResizeAreaCornerSize, 0, - kResizeAreaCornerSize, window_size.height()); - - if (north.Contains(x, y)) { - if (west.Contains(x, y)) - *edge = GDK_WINDOW_EDGE_NORTH_WEST; - else if (east.Contains(x, y)) - *edge = GDK_WINDOW_EDGE_NORTH_EAST; - else - *edge = GDK_WINDOW_EDGE_NORTH; - } else if (south.Contains(x, y)) { - if (west.Contains(x, y)) - *edge = GDK_WINDOW_EDGE_SOUTH_WEST; - else if (east.Contains(x, y)) - *edge = GDK_WINDOW_EDGE_SOUTH_EAST; - else - *edge = GDK_WINDOW_EDGE_SOUTH; - } else { - if (west.Contains(x, y)) - *edge = GDK_WINDOW_EDGE_WEST; - else if (east.Contains(x, y)) - *edge = GDK_WINDOW_EDGE_EAST; - else - return false; // The cursor must be outside the window. - } - return true; -} - -} // namespace gtk_window_util diff --git a/chromium_src/chrome/browser/ui/gtk/gtk_window_util.h b/chromium_src/chrome/browser/ui/gtk/gtk_window_util.h deleted file mode 100644 index a3e855cd7f37..000000000000 --- a/chromium_src/chrome/browser/ui/gtk/gtk_window_util.h +++ /dev/null @@ -1,69 +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_GTK_GTK_WINDOW_UTIL_H_ -#define CHROME_BROWSER_UI_GTK_GTK_WINDOW_UTIL_H_ - -#include -#include -#include "ui/gfx/rect.h" - -namespace content { -class WebContents; -} - -namespace gtk_window_util { - -// The frame border is only visible in restored mode and is hardcoded to 4 px -// on each side regardless of the system window border size. -extern const int kFrameBorderThickness; -// In the window corners, the resize areas don't actually expand bigger, but -// the 16 px at the end of each edge triggers diagonal resizing. -extern const int kResizeAreaCornerSize; - -// Ubuntu patches their version of GTK+ to that there is always a -// gripper in the bottom right corner of the window. We always need to -// disable this feature since we can't communicate this to WebKit easily. -void DisableResizeGrip(GtkWindow* window); - -// Returns the resize cursor corresponding to the window |edge|. -GdkCursorType GdkWindowEdgeToGdkCursorType(GdkWindowEdge edge); - -// Returns |true| if the window bounds match the monitor size. -bool BoundsMatchMonitorSize(GtkWindow* window, gfx::Rect bounds); - -bool HandleTitleBarLeftMousePress(GtkWindow* window, - const gfx::Rect& bounds, - GdkEventButton* event); - -// Request the underlying window to unmaximize. Also tries to work around -// a window manager "feature" that can prevent this in some edge cases. -void UnMaximize(GtkWindow* window, - const gfx::Rect& bounds, - const gfx::Rect& restored_bounds); - -// Set a custom WM_CLASS for a window. -void SetWindowCustomClass(GtkWindow* window, const std::string& wmclass); - -// A helper method for setting the GtkWindow size that should be used in place -// of calling gtk_window_resize directly. This is done to avoid a WM "feature" -// where setting the window size to the monitor size causes the WM to set the -// EWMH for full screen mode. -void SetWindowSize(GtkWindow* window, const gfx::Size& size); - -// 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. -// |top_edge_inset| specifies how much smaller (in px) than the default edge -// size the top edge should be, used by browser windows to make it easier to -// move the window since a lot of title bar space is taken by the tabs. -bool GetWindowEdge(const gfx::Size& window_size, - int top_edge_inset, - int x, - int y, - GdkWindowEdge* edge); - -} // namespace gtk_window_util - -#endif // CHROME_BROWSER_UI_GTK_GTK_WINDOW_UTIL_H_ diff --git a/chromium_src/chrome/browser/ui/gtk/menu_gtk.cc b/chromium_src/chrome/browser/ui/gtk/menu_gtk.cc deleted file mode 100644 index 1ba596e597e6..000000000000 --- a/chromium_src/chrome/browser/ui/gtk/menu_gtk.cc +++ /dev/null @@ -1,883 +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/gtk/menu_gtk.h" - -#include - -#include "base/bind.h" -#include "base/i18n/rtl.h" -#include "base/logging.h" -#include "base/message_loop/message_loop.h" -#include "base/stl_util.h" -#include "base/strings/utf_string_conversions.h" -#include "chrome/browser/ui/gtk/event_utils.h" -#include "chrome/browser/ui/gtk/gtk_custom_menu.h" -#include "chrome/browser/ui/gtk/gtk_custom_menu_item.h" -#include "chrome/browser/ui/gtk/gtk_util.h" -#include "chrome/browser/ui/libgtk2ui/skia_utils_gtk2.h" -#include "third_party/skia/include/core/SkBitmap.h" -#include "ui/base/accelerators/menu_label_accelerator_util_linux.h" -#include "ui/base/accelerators/platform_accelerator_gtk.h" -#include "ui/base/models/button_menu_item_model.h" -#include "ui/base/models/menu_model.h" -#include "ui/base/window_open_disposition.h" -#include "ui/gfx/gtk_util.h" -#include "ui/gfx/image/image.h" - -bool MenuGtk::block_activation_ = false; - -namespace { - -// Sets the ID of a menu item. -void SetMenuItemID(GtkWidget* menu_item, int menu_id) { - DCHECK_GE(menu_id, 0); - - // Add 1 to the menu_id to avoid setting zero (null) to "menu-id". - g_object_set_data(G_OBJECT(menu_item), "menu-id", - GINT_TO_POINTER(menu_id + 1)); -} - -// Gets the ID of a menu item. -// Returns true if the menu item has an ID. -bool GetMenuItemID(GtkWidget* menu_item, int* menu_id) { - gpointer id_ptr = g_object_get_data(G_OBJECT(menu_item), "menu-id"); - if (id_ptr != NULL) { - *menu_id = GPOINTER_TO_INT(id_ptr) - 1; - return true; - } - - return false; -} - -ui::MenuModel* ModelForMenuItem(GtkMenuItem* menu_item) { - return reinterpret_cast( - g_object_get_data(G_OBJECT(menu_item), "model")); -} - -void SetUpButtonShowHandler(GtkWidget* button, - ui::ButtonMenuItemModel* model, - int index) { - g_object_set_data(G_OBJECT(button), "button-model", - model); - g_object_set_data(G_OBJECT(button), "button-model-id", - GINT_TO_POINTER(index)); -} - -void OnSubmenuShowButtonImage(GtkWidget* widget, GtkButton* button) { - MenuGtk::Delegate* delegate = reinterpret_cast( - g_object_get_data(G_OBJECT(button), "menu-gtk-delegate")); - int icon_idr = GPOINTER_TO_INT(g_object_get_data( - G_OBJECT(button), "button-image-idr")); - - GtkIconSet* icon_set = delegate->GetIconSetForId(icon_idr); - if (icon_set) { - gtk_button_set_image( - button, gtk_image_new_from_icon_set(icon_set, - GTK_ICON_SIZE_MENU)); - } -} - -void SetupImageIcon(GtkWidget* button, - GtkWidget* menu, - int icon_idr, - MenuGtk::Delegate* menu_gtk_delegate) { - g_object_set_data(G_OBJECT(button), "button-image-idr", - GINT_TO_POINTER(icon_idr)); - g_object_set_data(G_OBJECT(button), "menu-gtk-delegate", - menu_gtk_delegate); - - g_signal_connect(menu, "show", G_CALLBACK(OnSubmenuShowButtonImage), button); -} - -// Popup menus may get squished if they open up too close to the bottom of the -// screen. This function takes the size of the screen, the size of the menu, -// an optional widget, the Y position of the mouse click, and adjusts the popup -// menu's Y position to make it fit if it's possible to do so. -// Returns the new Y position of the popup menu. -int CalculateMenuYPosition(const GdkRectangle* screen_rect, - const GtkRequisition* menu_req, - GtkWidget* widget, const int y) { - CHECK(screen_rect); - CHECK(menu_req); - // If the menu would run off the bottom of the screen, and there is enough - // screen space upwards to accommodate the menu, then pop upwards. If there - // is a widget, then also move the anchor point to the top of the widget - // rather than the bottom. - const int screen_top = screen_rect->y; - const int screen_bottom = screen_rect->y + screen_rect->height; - const int menu_bottom = y + menu_req->height; - int alternate_y = y - menu_req->height; - if (widget) { - GtkAllocation allocation; - gtk_widget_get_allocation(widget, &allocation); - alternate_y -= allocation.height; - } - if (menu_bottom >= screen_bottom && alternate_y >= screen_top) - return alternate_y; - return y; -} - -} // namespace - -bool MenuGtk::Delegate::AlwaysShowIconForCmd(int command_id) const { - return false; -} - -GtkIconSet* MenuGtk::Delegate::GetIconSetForId(int idr) { return NULL; } - -GtkWidget* MenuGtk::Delegate::GetDefaultImageForLabel( - const std::string& label) { - const char* stock = NULL; - if (label == "New") - stock = GTK_STOCK_NEW; - else if (label == "Close") - stock = GTK_STOCK_CLOSE; - else if (label == "Save As") - stock = GTK_STOCK_SAVE_AS; - else if (label == "Save") - stock = GTK_STOCK_SAVE; - else if (label == "Copy") - stock = GTK_STOCK_COPY; - else if (label == "Cut") - stock = GTK_STOCK_CUT; - else if (label == "Paste") - stock = GTK_STOCK_PASTE; - else if (label == "Delete") - stock = GTK_STOCK_DELETE; - else if (label == "Undo") - stock = GTK_STOCK_UNDO; - else if (label == "Redo") - stock = GTK_STOCK_REDO; - else if (label == "Search" || label == "Find") - stock = GTK_STOCK_FIND; - else if (label == "Select All") - stock = GTK_STOCK_SELECT_ALL; - else if (label == "Clear") - stock = GTK_STOCK_SELECT_ALL; - else if (label == "Back") - stock = GTK_STOCK_GO_BACK; - else if (label == "Forward") - stock = GTK_STOCK_GO_FORWARD; - else if (label == "Reload" || label == "Refresh") - stock = GTK_STOCK_REFRESH; - else if (label == "Print") - stock = GTK_STOCK_PRINT; - else if (label == "About") - stock = GTK_STOCK_ABOUT; - else if (label == "Quit") - stock = GTK_STOCK_QUIT; - else if (label == "Help") - stock = GTK_STOCK_HELP; - - return stock ? gtk_image_new_from_stock(stock, GTK_ICON_SIZE_MENU) : NULL; -} - -GtkWidget* MenuGtk::Delegate::GetImageForCommandId(int command_id) const { - return NULL; -} - -MenuGtk::MenuGtk(MenuGtk::Delegate* delegate, - ui::MenuModel* model, - bool is_menubar) - : delegate_(delegate), - model_(model), - is_menubar_(is_menubar), - dummy_accel_group_(gtk_accel_group_new()), - menu_(is_menubar ? gtk_menu_bar_new() : gtk_custom_menu_new()), - weak_factory_(this) { - DCHECK(model); - g_object_ref_sink(menu_); - ConnectSignalHandlers(); - BuildMenuFromModel(); -} - -MenuGtk::~MenuGtk() { - Cancel(); - - gtk_widget_destroy(menu_); - g_object_unref(menu_); - - g_object_unref(dummy_accel_group_); -} - -void MenuGtk::ConnectSignalHandlers() { - // We connect afterwards because OnMenuShow calls SetMenuItemInfo, which may - // take a long time or even start a nested message loop. - g_signal_connect(menu_, "show", G_CALLBACK(OnMenuShowThunk), this); - g_signal_connect(menu_, "hide", G_CALLBACK(OnMenuHiddenThunk), this); - GtkWidget* toplevel_window = gtk_widget_get_toplevel(menu_); - signal_.Connect(toplevel_window, "focus-out-event", - G_CALLBACK(OnMenuFocusOutThunk), this); -} - -GtkWidget* MenuGtk::AppendMenuItemWithLabel(int command_id, - const std::string& label) { - std::string converted_label = ui::ConvertAcceleratorsFromWindowsStyle(label); - GtkWidget* menu_item = BuildMenuItemWithLabel(converted_label, command_id); - return AppendMenuItem(command_id, menu_item); -} - -GtkWidget* MenuGtk::AppendMenuItemWithIcon(int command_id, - const std::string& label, - const gfx::Image& icon) { - std::string converted_label = ui::ConvertAcceleratorsFromWindowsStyle(label); - GtkWidget* menu_item = BuildMenuItemWithImage(converted_label, icon); - return AppendMenuItem(command_id, menu_item); -} - -GtkWidget* MenuGtk::AppendCheckMenuItemWithLabel(int command_id, - const std::string& label) { - std::string converted_label = ui::ConvertAcceleratorsFromWindowsStyle(label); - GtkWidget* menu_item = - gtk_check_menu_item_new_with_mnemonic(converted_label.c_str()); - return AppendMenuItem(command_id, menu_item); -} - -GtkWidget* MenuGtk::AppendSeparator() { - GtkWidget* menu_item = gtk_separator_menu_item_new(); - gtk_widget_show(menu_item); - gtk_menu_shell_append(GTK_MENU_SHELL(menu_), menu_item); - return menu_item; -} - -GtkWidget* MenuGtk::InsertSeparator(int position) { - GtkWidget* menu_item = gtk_separator_menu_item_new(); - gtk_widget_show(menu_item); - gtk_menu_shell_insert(GTK_MENU_SHELL(menu_), menu_item, position); - return menu_item; -} - -GtkWidget* MenuGtk::AppendMenuItem(int command_id, GtkWidget* menu_item) { - if (delegate_ && delegate_->AlwaysShowIconForCmd(command_id) && - GTK_IS_IMAGE_MENU_ITEM(menu_item)) - gtk_util::SetAlwaysShowImage(menu_item); - - return AppendMenuItemToMenu(command_id, NULL, menu_item, menu_, true); -} - -GtkWidget* MenuGtk::InsertMenuItem(int command_id, GtkWidget* menu_item, - int position) { - if (delegate_ && delegate_->AlwaysShowIconForCmd(command_id) && - GTK_IS_IMAGE_MENU_ITEM(menu_item)) - gtk_util::SetAlwaysShowImage(menu_item); - - return InsertMenuItemToMenu(command_id, NULL, menu_item, menu_, position, - true); -} - -GtkWidget* MenuGtk::AppendMenuItemToMenu(int index, - ui::MenuModel* model, - GtkWidget* menu_item, - GtkWidget* menu, - bool connect_to_activate) { - int children_count = g_list_length(GTK_MENU_SHELL(menu)->children); - return InsertMenuItemToMenu(index, model, menu_item, menu, - children_count, connect_to_activate); -} - -GtkWidget* MenuGtk::InsertMenuItemToMenu(int index, - ui::MenuModel* model, - GtkWidget* menu_item, - GtkWidget* menu, - int position, - bool connect_to_activate) { - SetMenuItemID(menu_item, index); - - // Native menu items do their own thing, so only selectively listen for the - // activate signal. - if (connect_to_activate) { - g_signal_connect(menu_item, "activate", - G_CALLBACK(OnMenuItemActivatedThunk), this); - } - - // AppendMenuItemToMenu is used both internally when we control menu creation - // from a model (where the model can choose to hide certain menu items), and - // with immediate commands which don't provide the option. - if (model) { - if (model->IsVisibleAt(index)) - gtk_widget_show(menu_item); - } else { - gtk_widget_show(menu_item); - } - gtk_menu_shell_insert(GTK_MENU_SHELL(menu), menu_item, position); - return menu_item; -} - -void MenuGtk::PopupForWidget(GtkWidget* widget, int button, - guint32 event_time) { - gtk_menu_popup(GTK_MENU(menu_), NULL, NULL, - WidgetMenuPositionFunc, - widget, - button, event_time); -} - -void MenuGtk::PopupAsContext(const gfx::Point& point, guint32 event_time) { - // gtk_menu_popup doesn't like the "const" qualifier on point. - gfx::Point nonconst_point(point); - gtk_menu_popup(GTK_MENU(menu_), NULL, NULL, - PointMenuPositionFunc, &nonconst_point, - 3, event_time); -} - -void MenuGtk::PopupAsContextForStatusIcon(guint32 event_time, guint32 button, - GtkStatusIcon* icon) { - gtk_menu_popup(GTK_MENU(menu_), NULL, NULL, gtk_status_icon_position_menu, - icon, button, event_time); -} - -void MenuGtk::PopupAsFromKeyEvent(GtkWidget* widget) { - PopupForWidget(widget, 0, gtk_get_current_event_time()); - gtk_menu_shell_select_first(GTK_MENU_SHELL(menu_), FALSE); -} - -void MenuGtk::Cancel() { - if (!is_menubar_) - gtk_menu_popdown(GTK_MENU(menu_)); -} - -void MenuGtk::UpdateMenu() { - gtk_container_foreach(GTK_CONTAINER(menu_), SetMenuItemInfo, this); -} - -GtkWidget* MenuGtk::BuildMenuItemWithImage(const std::string& label, - GtkWidget* image) { - GtkWidget* menu_item = - gtk_image_menu_item_new_with_mnemonic(label.c_str()); - gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menu_item), image); - return menu_item; -} - -GtkWidget* MenuGtk::BuildMenuItemWithImage(const std::string& label, - const gfx::Image& icon) { - GtkWidget* menu_item = BuildMenuItemWithImage( - label, - gtk_image_new_from_pixbuf( - libgtk2ui::GdkPixbufFromSkBitmap(*icon.ToSkBitmap()))); - return menu_item; -} - -GtkWidget* MenuGtk::BuildMenuItemWithLabel(const std::string& label, - int command_id) { - GtkWidget* img = - delegate_ ? delegate_->GetImageForCommandId(command_id) : - MenuGtk::Delegate::GetDefaultImageForLabel(label); - return img ? BuildMenuItemWithImage(label, img) : - gtk_menu_item_new_with_mnemonic(label.c_str()); -} - -void MenuGtk::BuildMenuFromModel() { - BuildSubmenuFromModel(model_, menu_); -} - -void MenuGtk::BuildSubmenuFromModel(ui::MenuModel* model, GtkWidget* menu) { - std::map radio_groups; - GtkWidget* menu_item = NULL; - for (int i = 0; i < model->GetItemCount(); ++i) { - gfx::Image icon; - std::string label = ui::ConvertAcceleratorsFromWindowsStyle( - base::UTF16ToUTF8(model->GetLabelAt(i))); - bool connect_to_activate = true; - - switch (model->GetTypeAt(i)) { - case ui::MenuModel::TYPE_SEPARATOR: - menu_item = gtk_separator_menu_item_new(); - break; - - case ui::MenuModel::TYPE_CHECK: - menu_item = gtk_check_menu_item_new_with_mnemonic(label.c_str()); - break; - - case ui::MenuModel::TYPE_RADIO: { - std::map::iterator iter = - radio_groups.find(model->GetGroupIdAt(i)); - - if (iter == radio_groups.end()) { - menu_item = gtk_radio_menu_item_new_with_mnemonic( - NULL, label.c_str()); - radio_groups[model->GetGroupIdAt(i)] = menu_item; - } else { - menu_item = gtk_radio_menu_item_new_with_mnemonic_from_widget( - GTK_RADIO_MENU_ITEM(iter->second), label.c_str()); - } - break; - } - case ui::MenuModel::TYPE_BUTTON_ITEM: { - ui::ButtonMenuItemModel* button_menu_item_model = - model->GetButtonMenuItemAt(i); - menu_item = BuildButtonMenuItem(button_menu_item_model, menu); - connect_to_activate = false; - break; - } - case ui::MenuModel::TYPE_SUBMENU: - case ui::MenuModel::TYPE_COMMAND: { - int command_id = model->GetCommandIdAt(i); - if (model->GetIconAt(i, &icon)) - menu_item = BuildMenuItemWithImage(label, icon); - else - menu_item = BuildMenuItemWithLabel(label, command_id); - if (delegate_ && delegate_->AlwaysShowIconForCmd(command_id) && - GTK_IS_IMAGE_MENU_ITEM(menu_item)) { - gtk_util::SetAlwaysShowImage(menu_item); - } - break; - } - - default: - NOTREACHED(); - } - - if (model->GetTypeAt(i) == ui::MenuModel::TYPE_SUBMENU) { - GtkWidget* submenu = gtk_menu_new(); - g_object_set_data(G_OBJECT(submenu), "menu-item", menu_item); - ui::MenuModel* submenu_model = model->GetSubmenuModelAt(i); - g_object_set_data(G_OBJECT(menu_item), "submenu-model", submenu_model); - gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item), submenu); - // We will populate the submenu on demand when shown. - g_signal_connect(submenu, "show", G_CALLBACK(OnSubMenuShowThunk), this); - g_signal_connect(submenu, "hide", G_CALLBACK(OnSubMenuHiddenThunk), this); - connect_to_activate = false; - } - - ui::Accelerator accelerator; - if (model->GetAcceleratorAt(i, &accelerator)) { - gtk_widget_add_accelerator(menu_item, - "activate", - dummy_accel_group_, - ui::GetGdkKeyCodeForAccelerator(accelerator), - ui::GetGdkModifierForAccelerator(accelerator), - GTK_ACCEL_VISIBLE); - } - - g_object_set_data(G_OBJECT(menu_item), "model", model); - AppendMenuItemToMenu(i, model, menu_item, menu, connect_to_activate); - - menu_item = NULL; - } -} - -GtkWidget* MenuGtk::BuildButtonMenuItem(ui::ButtonMenuItemModel* model, - GtkWidget* menu) { - GtkWidget* menu_item = gtk_custom_menu_item_new( - ui::RemoveWindowsStyleAccelerators( - base::UTF16ToUTF8(model->label())).c_str()); - - // Set up the callback to the model for when it is clicked. - g_object_set_data(G_OBJECT(menu_item), "button-model", model); - g_signal_connect(menu_item, "button-pushed", - G_CALLBACK(OnMenuButtonPressedThunk), this); - g_signal_connect(menu_item, "try-button-pushed", - G_CALLBACK(OnMenuTryButtonPressedThunk), this); - - GtkSizeGroup* group = NULL; - for (int i = 0; i < model->GetItemCount(); ++i) { - GtkWidget* button = NULL; - - switch (model->GetTypeAt(i)) { - case ui::ButtonMenuItemModel::TYPE_SPACE: { - gtk_custom_menu_item_add_space(GTK_CUSTOM_MENU_ITEM(menu_item)); - break; - } - case ui::ButtonMenuItemModel::TYPE_BUTTON: { - button = gtk_custom_menu_item_add_button( - GTK_CUSTOM_MENU_ITEM(menu_item), - model->GetCommandIdAt(i)); - - int icon_idr; - if (model->GetIconAt(i, &icon_idr)) { - SetupImageIcon(button, menu, icon_idr, delegate_); - } else { - gtk_button_set_label( - GTK_BUTTON(button), - ui::RemoveWindowsStyleAccelerators( - base::UTF16ToUTF8(model->GetLabelAt(i))).c_str()); - } - - SetUpButtonShowHandler(button, model, i); - break; - } - case ui::ButtonMenuItemModel::TYPE_BUTTON_LABEL: { - button = gtk_custom_menu_item_add_button_label( - GTK_CUSTOM_MENU_ITEM(menu_item), - model->GetCommandIdAt(i)); - gtk_button_set_label( - GTK_BUTTON(button), - ui::RemoveWindowsStyleAccelerators( - base::UTF16ToUTF8(model->GetLabelAt(i))).c_str()); - SetUpButtonShowHandler(button, model, i); - break; - } - } - - if (button && model->PartOfGroup(i)) { - if (!group) - group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); - - gtk_size_group_add_widget(group, button); - } - } - - if (group) - g_object_unref(group); - - return menu_item; -} - -void MenuGtk::OnMenuItemActivated(GtkWidget* menu_item) { - if (block_activation_) - return; - - ui::MenuModel* model = ModelForMenuItem(GTK_MENU_ITEM(menu_item)); - - if (!model) { - // There won't be a model for "native" submenus like the "Input Methods" - // context menu. We don't need to handle activation messages for submenus - // anyway, so we can just return here. - DCHECK(gtk_menu_item_get_submenu(GTK_MENU_ITEM(menu_item))); - return; - } - - // The activate signal is sent to radio items as they get deselected; - // ignore it in this case. - if (GTK_IS_RADIO_MENU_ITEM(menu_item) && - !gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_item))) { - return; - } - - int id; - if (!GetMenuItemID(menu_item, &id)) - return; - - // The menu item can still be activated by hotkeys even if it is disabled. - if (model->IsEnabledAt(id)) - ExecuteCommand(model, id); -} - -void MenuGtk::OnMenuButtonPressed(GtkWidget* menu_item, int command_id) { - ui::ButtonMenuItemModel* model = - reinterpret_cast( - g_object_get_data(G_OBJECT(menu_item), "button-model")); - if (model && model->IsCommandIdEnabled(command_id)) { - if (delegate_) - delegate_->CommandWillBeExecuted(); - - model->ActivatedCommand(command_id); - } -} - -gboolean MenuGtk::OnMenuTryButtonPressed(GtkWidget* menu_item, - int command_id) { - gboolean pressed = FALSE; - ui::ButtonMenuItemModel* model = - reinterpret_cast( - g_object_get_data(G_OBJECT(menu_item), "button-model")); - if (model && - model->IsCommandIdEnabled(command_id) && - !model->DoesCommandIdDismissMenu(command_id)) { - if (delegate_) - delegate_->CommandWillBeExecuted(); - - model->ActivatedCommand(command_id); - pressed = TRUE; - } - - return pressed; -} - -// static -void MenuGtk::WidgetMenuPositionFunc(GtkMenu* menu, - int* x, - int* y, - gboolean* push_in, - void* void_widget) { - GtkWidget* widget = GTK_WIDGET(void_widget); - GtkRequisition menu_req; - - gtk_widget_size_request(GTK_WIDGET(menu), &menu_req); - - gdk_window_get_origin(gtk_widget_get_window(widget), x, y); - GdkScreen *screen = gtk_widget_get_screen(widget); - gint monitor = gdk_screen_get_monitor_at_point(screen, *x, *y); - - GdkRectangle screen_rect; - gdk_screen_get_monitor_geometry(screen, monitor, - &screen_rect); - - GtkAllocation allocation; - gtk_widget_get_allocation(widget, &allocation); - - if (!gtk_widget_get_has_window(widget)) { - *x += allocation.x; - *y += allocation.y; - } - *y += allocation.height; - - bool start_align = - !!g_object_get_data(G_OBJECT(widget), "left-align-popup"); - if (base::i18n::IsRTL()) - start_align = !start_align; - - if (!start_align) - *x += allocation.width - menu_req.width; - - *y = CalculateMenuYPosition(&screen_rect, &menu_req, widget, *y); - - *push_in = FALSE; -} - -// static -void MenuGtk::PointMenuPositionFunc(GtkMenu* menu, - int* x, - int* y, - gboolean* push_in, - gpointer userdata) { - *push_in = TRUE; - - gfx::Point* point = reinterpret_cast(userdata); - *x = point->x(); - *y = point->y(); - - GtkRequisition menu_req; - gtk_widget_size_request(GTK_WIDGET(menu), &menu_req); - GdkScreen* screen; - gdk_display_get_pointer(gdk_display_get_default(), &screen, NULL, NULL, NULL); - gint monitor = gdk_screen_get_monitor_at_point(screen, *x, *y); - - GdkRectangle screen_rect; - gdk_screen_get_monitor_geometry(screen, monitor, &screen_rect); - - *y = CalculateMenuYPosition(&screen_rect, &menu_req, NULL, *y); -} - -void MenuGtk::ExecuteCommand(ui::MenuModel* model, int id) { - if (delegate_) - delegate_->CommandWillBeExecuted(); - - GdkEvent* event = gtk_get_current_event(); - int event_flags = 0; - - if (event && event->type == GDK_BUTTON_RELEASE) - event_flags = event_utils::EventFlagsFromGdkState(event->button.state); - model->ActivatedAt(id, event_flags); - - if (event) - gdk_event_free(event); -} - -void MenuGtk::OnMenuShow(GtkWidget* widget) { - model_->MenuWillShow(); - base::MessageLoop::current()->PostTask( - FROM_HERE, base::Bind(&MenuGtk::UpdateMenu, weak_factory_.GetWeakPtr())); -} - -void MenuGtk::OnMenuHidden(GtkWidget* widget) { - if (delegate_) - delegate_->StoppedShowing(); - model_->MenuClosed(); -} - -gboolean MenuGtk::OnMenuFocusOut(GtkWidget* widget, GdkEventFocus* event) { - gtk_widget_hide(menu_); - return TRUE; -} - -void MenuGtk::OnSubMenuShow(GtkWidget* submenu) { - GtkWidget* menu_item = static_cast( - g_object_get_data(G_OBJECT(submenu), "menu-item")); - // TODO(mdm): Figure out why this can sometimes be NULL. See bug 131974. - CHECK(menu_item); - // Notify the submenu model that the menu will be shown. - ui::MenuModel* submenu_model = static_cast( - g_object_get_data(G_OBJECT(menu_item), "submenu-model")); - // We're extra cautious here, and bail out if the submenu model is NULL. In - // some cases we clear it out from a parent menu; we shouldn't ever show the - // menu after that, but we play it safe since we're dealing with wacky - // injected libraries that toy with our menus. (See comments below.) - if (!submenu_model) - return; - - // If the submenu is already built, then return right away. This means we - // recently showed this submenu, and have not yet processed the fact that it - // was hidden before being shown again. - if (g_object_get_data(G_OBJECT(submenu), "submenu-built")) - return; - g_object_set_data(G_OBJECT(submenu), "submenu-built", GINT_TO_POINTER(1)); - - submenu_model->MenuWillShow(); - - // Actually build the submenu and attach it to the parent menu item. - BuildSubmenuFromModel(submenu_model, submenu); - gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item), submenu); - - // Update all the menu item info in the newly-generated menu. - gtk_container_foreach(GTK_CONTAINER(submenu), SetMenuItemInfo, this); -} - -void MenuGtk::OnSubMenuHidden(GtkWidget* submenu) { - if (is_menubar_) - return; - - // Increase the reference count of the old submenu, and schedule it to be - // deleted later. We get this hide notification before we've processed menu - // activations, so if we were to delete the submenu now, we might lose the - // activation. This also lets us reuse the menu if it is shown again before - // it gets deleted; in that case, OnSubMenuHiddenCallback() just decrements - // the reference count again. Note that the delay is just an optimization; we - // could use PostTask() and this would still work correctly. - g_object_ref(G_OBJECT(submenu)); - base::MessageLoop::current()->PostDelayedTask( - FROM_HERE, - base::Bind(&MenuGtk::OnSubMenuHiddenCallback, submenu), - base::TimeDelta::FromSeconds(2)); -} - -namespace { - -// Remove all descendant submenu-model data pointers. -void RemoveSubMenuModels(GtkWidget* menu_item, void* unused) { - if (!GTK_IS_MENU_ITEM(menu_item)) - return; - g_object_steal_data(G_OBJECT(menu_item), "submenu-model"); - GtkWidget* submenu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(menu_item)); - if (submenu) - gtk_container_foreach(GTK_CONTAINER(submenu), RemoveSubMenuModels, NULL); -} - -} // namespace - -// static -void MenuGtk::OnSubMenuHiddenCallback(GtkWidget* submenu) { - if (!gtk_widget_get_visible(submenu)) { - // Remove all the children of this menu, clearing out their submenu-model - // pointers in case they have pending calls to OnSubMenuHiddenCallback(). - // (Normally that won't happen: we'd have hidden them first, and so they'd - // have already been deleted. But in some cases [e.g. on Ubuntu 12.04], - // GTK menu operations may be hooked to allow external applications to - // mirror the menu structure, and the hooks may show and hide menus in - // order to trigger exactly the kind of dynamic menu building we're doing. - // The result is that we see show and hide events in strange orders.) - GList* children = gtk_container_get_children(GTK_CONTAINER(submenu)); - for (GList* child = children; child; child = g_list_next(child)) { - RemoveSubMenuModels(GTK_WIDGET(child->data), NULL); - gtk_container_remove(GTK_CONTAINER(submenu), GTK_WIDGET(child->data)); - } - g_list_free(children); - - // Clear out the bit that says the menu is built. - // We'll rebuild it next time it is shown. - g_object_steal_data(G_OBJECT(submenu), "submenu-built"); - - // Notify the submenu model that the menu has been hidden. This may cause - // it to delete descendant submenu models, which is why we cleared those - // pointers out above. - GtkWidget* menu_item = static_cast( - g_object_get_data(G_OBJECT(submenu), "menu-item")); - // TODO(mdm): Figure out why this can sometimes be NULL. See bug 124110. - CHECK(menu_item); - ui::MenuModel* submenu_model = static_cast( - g_object_get_data(G_OBJECT(menu_item), "submenu-model")); - if (submenu_model) - submenu_model->MenuClosed(); - } - - // Remove the reference we grabbed in OnSubMenuHidden() above. - g_object_unref(G_OBJECT(submenu)); -} - -// static -void MenuGtk::SetButtonItemInfo(GtkWidget* button, gpointer userdata) { - ui::ButtonMenuItemModel* model = - reinterpret_cast( - g_object_get_data(G_OBJECT(button), "button-model")); - int index = GPOINTER_TO_INT(g_object_get_data( - G_OBJECT(button), "button-model-id")); - - if (model->IsItemDynamicAt(index)) { - std::string label = ui::ConvertAcceleratorsFromWindowsStyle( - base::UTF16ToUTF8(model->GetLabelAt(index))); - gtk_button_set_label(GTK_BUTTON(button), label.c_str()); - } - - gtk_widget_set_sensitive(GTK_WIDGET(button), model->IsEnabledAt(index)); -} - -// static -void MenuGtk::SetMenuItemInfo(GtkWidget* widget, gpointer userdata) { - if (GTK_IS_SEPARATOR_MENU_ITEM(widget)) { - // We need to explicitly handle this case because otherwise we'll ask the - // menu delegate about something with an invalid id. - return; - } - - int id; - if (!GetMenuItemID(widget, &id)) - return; - - ui::MenuModel* model = ModelForMenuItem(GTK_MENU_ITEM(widget)); - if (!model) { - // If we're not providing the sub menu, then there's no model. For - // example, the IME submenu doesn't have a model. - return; - } - - if (GTK_IS_CHECK_MENU_ITEM(widget)) { - GtkCheckMenuItem* item = GTK_CHECK_MENU_ITEM(widget); - - // gtk_check_menu_item_set_active() will send the activate signal. Touching - // the underlying "active" property will also call the "activate" handler - // for this menu item. So we prevent the "activate" handler from - // being called while we set the checkbox. - // Why not use one of the glib signal-blocking functions? Because when we - // toggle a radio button, it will deactivate one of the other radio buttons, - // which we don't have a pointer to. - // Wny not make this a member variable? Because "menu" is a pointer to the - // root of the MenuGtk and we want to disable *all* MenuGtks, including - // submenus. - block_activation_ = true; - gtk_check_menu_item_set_active(item, model->IsItemCheckedAt(id)); - block_activation_ = false; - } - - if (GTK_IS_CUSTOM_MENU_ITEM(widget)) { - // Iterate across all the buttons to update their visible properties. - gtk_custom_menu_item_foreach_button(GTK_CUSTOM_MENU_ITEM(widget), - SetButtonItemInfo, - userdata); - } - - if (GTK_IS_MENU_ITEM(widget)) { - gtk_widget_set_sensitive(widget, model->IsEnabledAt(id)); - - if (model->IsVisibleAt(id)) { - // Update the menu item label if it is dynamic. - if (model->IsItemDynamicAt(id)) { - std::string label = ui::ConvertAcceleratorsFromWindowsStyle( - base::UTF16ToUTF8(model->GetLabelAt(id))); - - gtk_menu_item_set_label(GTK_MENU_ITEM(widget), label.c_str()); - if (GTK_IS_IMAGE_MENU_ITEM(widget)) { - gfx::Image icon; - if (model->GetIconAt(id, &icon)) { - gtk_image_menu_item_set_image( - GTK_IMAGE_MENU_ITEM(widget), - gtk_image_new_from_pixbuf( - libgtk2ui::GdkPixbufFromSkBitmap(*icon.ToSkBitmap()))); - } else { - gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(widget), NULL); - } - } - } - - gtk_widget_show(widget); - } else { - gtk_widget_hide(widget); - } - - GtkWidget* submenu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(widget)); - if (submenu) { - gtk_container_foreach(GTK_CONTAINER(submenu), &SetMenuItemInfo, - userdata); - } - } -} diff --git a/chromium_src/chrome/browser/ui/gtk/menu_gtk.h b/chromium_src/chrome/browser/ui/gtk/menu_gtk.h deleted file mode 100644 index 461291017bf7..000000000000 --- a/chromium_src/chrome/browser/ui/gtk/menu_gtk.h +++ /dev/null @@ -1,224 +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_GTK_MENU_GTK_H_ -#define CHROME_BROWSER_UI_GTK_MENU_GTK_H_ - -#include - -#include -#include - -#include "base/memory/weak_ptr.h" -#include "chrome/browser/ui/libgtk2ui/gtk2_signal.h" -#include "chrome/browser/ui/libgtk2ui/gtk2_signal_registrar.h" -#include "ui/gfx/point.h" - -namespace gfx { -class Image; -} - -namespace ui { -class ButtonMenuItemModel; -class MenuModel; -} - -class MenuGtk { - public: - // Delegate class that lets another class control the status of the menu. - class Delegate { - public: - virtual ~Delegate() {} - - // Called before a command is executed. This exists for the case where a - // model is handling the actual execution of commands, but the delegate - // still needs to know that some command got executed. This is called before - // and not after the command is executed because its execution may delete - // the menu and/or the delegate. - virtual void CommandWillBeExecuted() {} - - // Called when the menu stops showing. This will be called before - // ExecuteCommand if the user clicks an item, but will also be called when - // the user clicks away from the menu. - virtual void StoppedShowing() {} - - // Return true if we should override the "gtk-menu-images" system setting - // when showing image menu items for this menu. - virtual bool AlwaysShowIconForCmd(int command_id) const; - - // Returns a tinted image used in button in a menu. - virtual GtkIconSet* GetIconSetForId(int idr); - - // Returns an icon for the menu item, if available. - virtual GtkWidget* GetImageForCommandId(int command_id) const; - - static GtkWidget* GetDefaultImageForLabel(const std::string& label); - }; - - MenuGtk(MenuGtk::Delegate* delegate, - ui::MenuModel* model, - bool is_menubar = false); - virtual ~MenuGtk(); - - // Initialize GTK signal handlers. - void ConnectSignalHandlers(); - - // These methods are used to build the menu dynamically. The return value - // is the new menu item. - GtkWidget* AppendMenuItemWithLabel(int command_id, const std::string& label); - GtkWidget* AppendMenuItemWithIcon(int command_id, const std::string& label, - const gfx::Image& icon); - GtkWidget* AppendCheckMenuItemWithLabel(int command_id, - const std::string& label); - GtkWidget* AppendSeparator(); - GtkWidget* InsertSeparator(int position); - GtkWidget* AppendMenuItem(int command_id, GtkWidget* menu_item); - GtkWidget* InsertMenuItem(int command_id, GtkWidget* menu_item, int position); - GtkWidget* AppendMenuItemToMenu(int index, - ui::MenuModel* model, - GtkWidget* menu_item, - GtkWidget* menu, - bool connect_to_activate); - GtkWidget* InsertMenuItemToMenu(int index, - ui::MenuModel* model, - GtkWidget* menu_item, - GtkWidget* menu, - int position, - bool connect_to_activate); - - // Displays the menu near a widget, as if the widget were a menu bar. - // Example: the wrench menu button. - // |button| is the mouse button that brought up the menu. - // |event_time| is the time from the GdkEvent. - void PopupForWidget(GtkWidget* widget, int button, guint32 event_time); - - // Displays the menu as a context menu, i.e. at the cursor location. - // It is implicit that it was brought up using the right mouse button. - // |point| is the point where to put the menu. - // |event_time| is the time of the event that triggered the menu's display. - void PopupAsContext(const gfx::Point& point, guint32 event_time); - - // Displays the menu as a context menu for the passed status icon. - void PopupAsContextForStatusIcon(guint32 event_time, guint32 button, - GtkStatusIcon* icon); - - // Displays the menu following a keyboard event (such as selecting |widget| - // and pressing "enter"). - void PopupAsFromKeyEvent(GtkWidget* widget); - - // Closes the menu. - void Cancel(); - - // Repositions the menu to be right under the button. Alignment is set as - // object data on |void_widget| with the tag "left_align". If "left_align" - // is true, it aligns the left side of the menu with the left side of the - // button. Otherwise it aligns the right side of the menu with the right side - // of the button. Public since some menus have odd requirements that don't - // belong in a public class. - static void WidgetMenuPositionFunc(GtkMenu* menu, - int* x, - int* y, - gboolean* push_in, - void* void_widget); - - // Positions the menu to appear at the gfx::Point represented by |userdata|. - static void PointMenuPositionFunc(GtkMenu* menu, - int* x, - int* y, - gboolean* push_in, - gpointer userdata); - - GtkWidget* widget() const { return menu_; } - ui::MenuModel* model() const { return model_;} - - // Updates all the enabled/checked states and the dynamic labels. - void UpdateMenu(); - - private: - // Builds a GtkImageMenuItem. - GtkWidget* BuildMenuItemWithImage(const std::string& label, - const gfx::Image& icon); - - GtkWidget* BuildMenuItemWithImage(const std::string& label, - GtkWidget* image); - - GtkWidget* BuildMenuItemWithLabel(const std::string& label, - int command_id); - - // A function that creates a GtkMenu from |model_|. - void BuildMenuFromModel(); - // Implementation of the above; called recursively. - void BuildSubmenuFromModel(ui::MenuModel* model, GtkWidget* menu); - // Builds a menu item with buttons in it from the data in the model. - GtkWidget* BuildButtonMenuItem(ui::ButtonMenuItemModel* model, - GtkWidget* menu); - - void ExecuteCommand(ui::MenuModel* model, int id); - - // Callback for when a menu item is clicked. - CHROMEGTK_CALLBACK_0(MenuGtk, void, OnMenuItemActivated); - - // Called when one of the buttons is pressed. - CHROMEGTK_CALLBACK_1(MenuGtk, void, OnMenuButtonPressed, int); - - // Called to maybe activate a button if that button isn't supposed to dismiss - // the menu. - CHROMEGTK_CALLBACK_1(MenuGtk, gboolean, OnMenuTryButtonPressed, int); - - // Updates all the menu items' state. - CHROMEGTK_CALLBACK_0(MenuGtk, void, OnMenuShow); - - // Sets the activating widget back to a normal appearance. - CHROMEGTK_CALLBACK_0(MenuGtk, void, OnMenuHidden); - - // Focus out event handler for the menu. - CHROMEGTK_CALLBACK_1(MenuGtk, gboolean, OnMenuFocusOut, GdkEventFocus*); - - // Handles building dynamic submenus on demand when they are shown. - CHROMEGTK_CALLBACK_0(MenuGtk, void, OnSubMenuShow); - - // Handles trearing down dynamic submenus when they have been closed. - CHROMEGTK_CALLBACK_0(MenuGtk, void, OnSubMenuHidden); - - // Scheduled by OnSubMenuHidden() to avoid deleting submenus when hidden - // before pending activations within them are delivered. - static void OnSubMenuHiddenCallback(GtkWidget* submenu); - - // Sets the enable/disabled state and dynamic labels on our menu items. - static void SetButtonItemInfo(GtkWidget* button, gpointer userdata); - - // Sets the check mark, enabled/disabled state and dynamic labels on our menu - // items. - static void SetMenuItemInfo(GtkWidget* widget, void* raw_menu); - - // Queries this object about the menu state. - MenuGtk::Delegate* delegate_; - - // If non-NULL, the MenuModel that we use to populate and control the GTK - // menu (overriding the delegate as a controller). - ui::MenuModel* model_; - - // Whether this is a menu bar. - bool is_menubar_; - - // For some menu items, we want to show the accelerator, but not actually - // explicitly handle it. To this end we connect those menu items' accelerators - // to this group, but don't attach this group to any top level window. - GtkAccelGroup* dummy_accel_group_; - - // gtk_menu_popup() does not appear to take ownership of popup menus, so - // MenuGtk explicitly manages the lifetime of the menu. - GtkWidget* menu_; - - // True when we should ignore "activate" signals. Used to prevent - // menu items from getting activated when we are setting up the - // menu. - static bool block_activation_; - - libgtk2ui::Gtk2SignalRegistrar signal_; - - base::WeakPtrFactory weak_factory_; -}; - -#endif // CHROME_BROWSER_UI_GTK_MENU_GTK_H_ diff --git a/chromium_src/chrome/browser/ui/libgtk2ui/app_indicator_icon_menu.cc b/chromium_src/chrome/browser/ui/libgtk2ui/app_indicator_icon_menu.cc new file mode 100644 index 000000000000..151117314c83 --- /dev/null +++ b/chromium_src/chrome/browser/ui/libgtk2ui/app_indicator_icon_menu.cc @@ -0,0 +1,123 @@ +// Copyright 2014 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/app_indicator_icon_menu.h" + +#include + +#include "base/bind.h" +#include "base/debug/leak_annotations.h" +#include "chrome/browser/ui/libgtk2ui/menu_util.h" +#include "ui/base/models/menu_model.h" + +namespace libgtk2ui { + +AppIndicatorIconMenu::AppIndicatorIconMenu(ui::MenuModel* model) + : menu_model_(model), + click_action_replacement_menu_item_added_(false), + gtk_menu_(NULL), + block_activation_(false) { + { + ANNOTATE_SCOPED_MEMORY_LEAK; // http://crbug.com/378770 + gtk_menu_ = gtk_menu_new(); + } + g_object_ref_sink(gtk_menu_); + if (menu_model_) { + BuildSubmenuFromModel(menu_model_, + gtk_menu_, + G_CALLBACK(OnMenuItemActivatedThunk), + &block_activation_, + this); + Refresh(); + } +} + +AppIndicatorIconMenu::~AppIndicatorIconMenu() { + gtk_widget_destroy(gtk_menu_); + g_object_unref(gtk_menu_); +} + +void AppIndicatorIconMenu::UpdateClickActionReplacementMenuItem( + const char* label, + const base::Closure& callback) { + click_action_replacement_callback_ = callback; + + if (click_action_replacement_menu_item_added_) { + GList* children = gtk_container_get_children(GTK_CONTAINER(gtk_menu_)); + for (GList* child = children; child; child = g_list_next(child)) { + if (g_object_get_data(G_OBJECT(child->data), "click-action-item") != + NULL) { + gtk_menu_item_set_label(GTK_MENU_ITEM(child->data), label); + break; + } + } + g_list_free(children); + } else { + click_action_replacement_menu_item_added_ = true; + + // If |menu_model_| is non empty, add a separator to separate the + // "click action replacement menu item" from the other menu items. + if (menu_model_ && menu_model_->GetItemCount() > 0) { + GtkWidget* menu_item = gtk_separator_menu_item_new(); + gtk_widget_show(menu_item); + gtk_menu_shell_prepend(GTK_MENU_SHELL(gtk_menu_), menu_item); + } + + GtkWidget* menu_item = gtk_menu_item_new_with_mnemonic(label); + g_object_set_data( + G_OBJECT(menu_item), "click-action-item", GINT_TO_POINTER(1)); + g_signal_connect(menu_item, + "activate", + G_CALLBACK(OnClickActionReplacementMenuItemActivatedThunk), + this); + gtk_widget_show(menu_item); + gtk_menu_shell_prepend(GTK_MENU_SHELL(gtk_menu_), menu_item); + } +} + +void AppIndicatorIconMenu::Refresh() { + gtk_container_foreach( + GTK_CONTAINER(gtk_menu_), SetMenuItemInfo, &block_activation_); +} + +GtkMenu* AppIndicatorIconMenu::GetGtkMenu() { + return GTK_MENU(gtk_menu_); +} + + +void AppIndicatorIconMenu::OnClickActionReplacementMenuItemActivated( + GtkWidget* menu_item) { + click_action_replacement_callback_.Run(); +} + +void AppIndicatorIconMenu::OnMenuItemActivated(GtkWidget* menu_item) { + if (block_activation_) + return; + + ui::MenuModel* model = ModelForMenuItem(GTK_MENU_ITEM(menu_item)); + if (!model) { + // There won't be a model for "native" submenus like the "Input Methods" + // context menu. We don't need to handle activation messages for submenus + // anyway, so we can just return here. + DCHECK(gtk_menu_item_get_submenu(GTK_MENU_ITEM(menu_item))); + return; + } + + // The activate signal is sent to radio items as they get deselected; + // ignore it in this case. + if (GTK_IS_RADIO_MENU_ITEM(menu_item) && + !gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_item))) { + return; + } + + int id; + if (!GetMenuItemID(menu_item, &id)) + return; + + // The menu item can still be activated by hotkeys even if it is disabled. + if (menu_model_->IsEnabledAt(id)) + ExecuteCommand(model, id); +} + +} // namespace libgtk2ui diff --git a/chromium_src/chrome/browser/ui/libgtk2ui/app_indicator_icon_menu.h b/chromium_src/chrome/browser/ui/libgtk2ui/app_indicator_icon_menu.h new file mode 100644 index 000000000000..a204710f9c18 --- /dev/null +++ b/chromium_src/chrome/browser/ui/libgtk2ui/app_indicator_icon_menu.h @@ -0,0 +1,66 @@ +// Copyright 2014 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_APP_INDICATOR_ICON_MENU_H_ +#define CHROME_BROWSER_UI_LIBGTK2UI_APP_INDICATOR_ICON_MENU_H_ + +#include "base/callback.h" +#include "chrome/browser/ui/libgtk2ui/gtk2_signal.h" + +typedef struct _GtkMenu GtkMenu; +typedef struct _GtkWidget GtkWidget; + +namespace ui { +class MenuModel; +} + +namespace libgtk2ui { + +// The app indicator icon's menu. +class AppIndicatorIconMenu { + public: + explicit AppIndicatorIconMenu(ui::MenuModel* model); + virtual ~AppIndicatorIconMenu(); + + // Sets a menu item at the top of |gtk_menu_| as a replacement for the app + // indicator icon's click action. |callback| is called when the menu item + // is activated. + void UpdateClickActionReplacementMenuItem(const char* label, + const base::Closure& callback); + + // Refreshes all the menu item labels and menu item checked/enabled states. + void Refresh(); + + GtkMenu* GetGtkMenu(); + + private: + // Callback for when the "click action replacement" menu item is activated. + CHROMEGTK_CALLBACK_0(AppIndicatorIconMenu, + void, + OnClickActionReplacementMenuItemActivated); + + // Callback for when a menu item is activated. + CHROMEGTK_CALLBACK_0(AppIndicatorIconMenu, void, OnMenuItemActivated); + + // Not owned. + ui::MenuModel* menu_model_; + + // Whether a "click action replacement" menu item has been added to the menu. + bool click_action_replacement_menu_item_added_; + + // Called when the click action replacement menu item is activated. When a + // menu item from |menu_model_| is activated, MenuModel::ActivatedAt() is + // invoked and is assumed to do any necessary processing. + base::Closure click_action_replacement_callback_; + + GtkWidget* gtk_menu_; + + bool block_activation_; + + DISALLOW_COPY_AND_ASSIGN(AppIndicatorIconMenu); +}; + +} // namespace libgtk2ui + +#endif // CHROME_BROWSER_UI_LIBGTK2UI_APP_INDICATOR_ICON_MENU_H_ diff --git a/chromium_src/chrome/browser/ui/libgtk2ui/gtk2_status_icon.cc b/chromium_src/chrome/browser/ui/libgtk2ui/gtk2_status_icon.cc new file mode 100644 index 000000000000..2838bff2ea1f --- /dev/null +++ b/chromium_src/chrome/browser/ui/libgtk2ui/gtk2_status_icon.cc @@ -0,0 +1,80 @@ +// Copyright 2014 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_status_icon.h" + +#include + +#include "base/strings/utf_string_conversions.h" +#include "chrome/browser/ui/libgtk2ui/app_indicator_icon_menu.h" +#include "chrome/browser/ui/libgtk2ui/skia_utils_gtk2.h" +#include "ui/base/models/menu_model.h" +#include "ui/gfx/image/image_skia.h" + +namespace libgtk2ui { + +Gtk2StatusIcon::Gtk2StatusIcon(const gfx::ImageSkia& image, + const base::string16& tool_tip) { + GdkPixbuf* pixbuf = GdkPixbufFromSkBitmap(*image.bitmap()); + gtk_status_icon_ = gtk_status_icon_new_from_pixbuf(pixbuf); + g_object_unref(pixbuf); + + g_signal_connect(gtk_status_icon_, "activate", G_CALLBACK(OnClickThunk), + this); + g_signal_connect(gtk_status_icon_, "popup_menu", + G_CALLBACK(OnContextMenuRequestedThunk), this); + SetToolTip(tool_tip); +} + +Gtk2StatusIcon::~Gtk2StatusIcon() { + g_object_unref(gtk_status_icon_); +} + +void Gtk2StatusIcon::SetImage(const gfx::ImageSkia& image) { + GdkPixbuf* pixbuf = GdkPixbufFromSkBitmap(*image.bitmap()); + gtk_status_icon_set_from_pixbuf(gtk_status_icon_, pixbuf); + g_object_unref(pixbuf); +} + +void Gtk2StatusIcon::SetPressedImage(const gfx::ImageSkia& image) { + // Ignore pressed images, since the standard on Linux is to not highlight + // pressed status icons. +} + +void Gtk2StatusIcon::SetToolTip(const base::string16& tool_tip) { + gtk_status_icon_set_tooltip_text(gtk_status_icon_, + base::UTF16ToUTF8(tool_tip).c_str()); +} + +void Gtk2StatusIcon::UpdatePlatformContextMenu(ui::MenuModel* model) { + menu_.reset(); + if (model) + menu_.reset(new AppIndicatorIconMenu(model)); +} + +void Gtk2StatusIcon::RefreshPlatformContextMenu() { + if (menu_.get()) + menu_->Refresh(); +} + +void Gtk2StatusIcon::OnClick(GtkStatusIcon* status_icon) { + if (delegate()) + delegate()->OnClick(); +} + +void Gtk2StatusIcon::OnContextMenuRequested(GtkStatusIcon* status_icon, + guint button, + guint32 activate_time) { + if (menu_.get()) { + gtk_menu_popup(menu_->GetGtkMenu(), + NULL, + NULL, + gtk_status_icon_position_menu, + gtk_status_icon_, + button, + activate_time); + } +} + +} // namespace libgtk2ui diff --git a/chromium_src/chrome/browser/ui/libgtk2ui/gtk2_status_icon.h b/chromium_src/chrome/browser/ui/libgtk2ui/gtk2_status_icon.h new file mode 100644 index 000000000000..d25b487b6219 --- /dev/null +++ b/chromium_src/chrome/browser/ui/libgtk2ui/gtk2_status_icon.h @@ -0,0 +1,61 @@ +// Copyright 2014 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_STATUS_ICON_H_ +#define CHROME_BROWSER_UI_LIBGTK2UI_GTK2_STATUS_ICON_H_ + +#include "base/memory/scoped_ptr.h" +#include "base/strings/string16.h" +#include "chrome/browser/ui/libgtk2ui/gtk2_signal.h" +#include "ui/base/glib/glib_integers.h" +#include "ui/base/glib/glib_signal.h" +#include "ui/views/linux_ui/status_icon_linux.h" + +typedef struct _GtkStatusIcon GtkStatusIcon; + +namespace gfx { +class ImageSkia; +} + +namespace ui { +class MenuModel; +} + +namespace libgtk2ui { +class AppIndicatorIconMenu; + +// Status icon implementation which uses the system tray X11 spec (via +// GtkStatusIcon). +class Gtk2StatusIcon : public views::StatusIconLinux { + public: + Gtk2StatusIcon(const gfx::ImageSkia& image, const base::string16& tool_tip); + virtual ~Gtk2StatusIcon(); + + // Overridden from views::StatusIconLinux: + virtual void SetImage(const gfx::ImageSkia& image) OVERRIDE; + virtual void SetPressedImage(const gfx::ImageSkia& image) OVERRIDE; + virtual void SetToolTip(const base::string16& tool_tip) OVERRIDE; + virtual void UpdatePlatformContextMenu(ui::MenuModel* menu) OVERRIDE; + virtual void RefreshPlatformContextMenu() OVERRIDE; + + private: + CHROMEG_CALLBACK_0(Gtk2StatusIcon, void, OnClick, GtkStatusIcon*); + + CHROMEG_CALLBACK_2(Gtk2StatusIcon, + void, + OnContextMenuRequested, + GtkStatusIcon*, + guint, + guint); + + GtkStatusIcon* gtk_status_icon_; + + scoped_ptr menu_; + + DISALLOW_COPY_AND_ASSIGN(Gtk2StatusIcon); +}; + +} // namespace libgtk2ui + +#endif // CHROME_BROWSER_UI_LIBGTK2UI_GTK2_STATUS_ICON_H_ diff --git a/chromium_src/ui/base/accelerators/platform_accelerator_gtk.cc b/chromium_src/ui/base/accelerators/platform_accelerator_gtk.cc deleted file mode 100644 index 5662452a530e..000000000000 --- a/chromium_src/ui/base/accelerators/platform_accelerator_gtk.cc +++ /dev/null @@ -1,93 +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 "ui/base/accelerators/platform_accelerator_gtk.h" - -#include "ui/events/keycodes/keyboard_code_conversion_gtk.h" - -namespace ui { - -namespace { - -int GdkModifierToEventFlag(GdkModifierType gdk_modifier) { - int event_flags = 0; - if (gdk_modifier & GDK_SHIFT_MASK) - event_flags |= EF_SHIFT_DOWN; - if (gdk_modifier & GDK_CONTROL_MASK) - event_flags |= EF_CONTROL_DOWN; - if (gdk_modifier & GDK_MOD1_MASK) - event_flags |= EF_ALT_DOWN; - return event_flags; -} - -GdkModifierType EventFlagToGdkModifier(int event_flag) { - int modifier = 0; - if (event_flag & EF_SHIFT_DOWN) - modifier |= GDK_SHIFT_MASK; - if (event_flag & EF_CONTROL_DOWN) - modifier |= GDK_CONTROL_MASK; - if (event_flag & EF_ALT_DOWN) - modifier |= GDK_MOD1_MASK; - return static_cast(modifier); -} - -} // namespace - -PlatformAcceleratorGtk::PlatformAcceleratorGtk() - : gdk_key_code_(0), - gdk_modifier_(static_cast(0)) { -} - -PlatformAcceleratorGtk::PlatformAcceleratorGtk(guint gdk_key_code, - GdkModifierType gdk_modifier) - : gdk_key_code_(gdk_key_code), - gdk_modifier_(gdk_modifier) { -} - -PlatformAcceleratorGtk::~PlatformAcceleratorGtk() { -} - -scoped_ptr PlatformAcceleratorGtk::CreateCopy() const { - scoped_ptr copy(new PlatformAcceleratorGtk); - copy->gdk_key_code_ = gdk_key_code_; - copy->gdk_modifier_ = gdk_modifier_; - return scoped_ptr(copy.release()); -} - -bool PlatformAcceleratorGtk::Equals(const PlatformAccelerator& rhs) const { - const PlatformAcceleratorGtk& rhs_gtk = - static_cast(rhs); - return gdk_key_code_ == rhs_gtk.gdk_key_code_ && - gdk_modifier_ == rhs_gtk.gdk_modifier_; -} - -Accelerator AcceleratorForGdkKeyCodeAndModifier(guint gdk_key_code, - GdkModifierType gdk_modifier) { - ui::Accelerator accelerator(ui::WindowsKeyCodeForGdkKeyCode(gdk_key_code), - ui::GdkModifierToEventFlag(gdk_modifier)); - scoped_ptr platform_accelerator( - new PlatformAcceleratorGtk(gdk_key_code, gdk_modifier)); - accelerator.set_platform_accelerator(platform_accelerator.Pass()); - return accelerator; -} - -guint GetGdkKeyCodeForAccelerator(const Accelerator& accelerator) { - if (accelerator.platform_accelerator()) { - return static_cast( - accelerator.platform_accelerator())->gdk_key_code(); - } - // The second parameter is false because accelerator keys are expressed in - // terms of the non-shift-modified key. - return GdkKeyCodeForWindowsKeyCode(accelerator.key_code(), false); -} - -GdkModifierType GetGdkModifierForAccelerator(const Accelerator& accelerator) { - if (accelerator.platform_accelerator()) { - return static_cast( - accelerator.platform_accelerator())->gdk_modifier(); - } - return EventFlagToGdkModifier(accelerator.modifiers()); -} - -} // namespace ui diff --git a/chromium_src/ui/base/accelerators/platform_accelerator_gtk.h b/chromium_src/ui/base/accelerators/platform_accelerator_gtk.h deleted file mode 100644 index 59c8fa0744c7..000000000000 --- a/chromium_src/ui/base/accelerators/platform_accelerator_gtk.h +++ /dev/null @@ -1,49 +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 UI_BASE_ACCELERATORS_PLATFORM_ACCELERATOR_GTK_H_ -#define UI_BASE_ACCELERATORS_PLATFORM_ACCELERATOR_GTK_H_ - -#include - -#include "base/compiler_specific.h" -#include "ui/base/accelerators/accelerator.h" -#include "ui/base/accelerators/platform_accelerator.h" - -namespace ui { - -class Accelerator; - -// This is a GTK specific class for specifing accelerator keys. -class UI_BASE_EXPORT PlatformAcceleratorGtk : public PlatformAccelerator { - public: - PlatformAcceleratorGtk(); - PlatformAcceleratorGtk(guint gdk_key_code, GdkModifierType gdk_modifier); - virtual ~PlatformAcceleratorGtk(); - - // PlatformAccelerator: - virtual scoped_ptr CreateCopy() const OVERRIDE; - virtual bool Equals(const PlatformAccelerator& rhs) const OVERRIDE; - - guint gdk_key_code() const { return gdk_key_code_; } - GdkModifierType gdk_modifier() const { return gdk_modifier_; } - - private: - guint gdk_key_code_; - GdkModifierType gdk_modifier_; - - DISALLOW_COPY_AND_ASSIGN(PlatformAcceleratorGtk); -}; - -UI_BASE_EXPORT Accelerator AcceleratorForGdkKeyCodeAndModifier( - guint gdk_key_code, - GdkModifierType gdk_modifier); -UI_BASE_EXPORT guint - GetGdkKeyCodeForAccelerator(const Accelerator& accelerator); -UI_BASE_EXPORT GdkModifierType GetGdkModifierForAccelerator( - const Accelerator& accelerator); - -} // namespace ui - -#endif // UI_BASE_ACCELERATORS_PLATFORM_ACCELERATOR_GTK_H_ diff --git a/chromium_src/ui/base/x/active_window_watcher_x.cc b/chromium_src/ui/base/x/active_window_watcher_x.cc deleted file mode 100644 index 9d3e791fd53f..000000000000 --- a/chromium_src/ui/base/x/active_window_watcher_x.cc +++ /dev/null @@ -1,99 +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 "ui/base/x/active_window_watcher_x.h" - -#include -#include - -#include "base/memory/singleton.h" -#include "ui/base/x/active_window_watcher_x_observer.h" -#include "ui/base/x/root_window_property_watcher_x.h" -#include "ui/base/x/x11_util.h" -#include "ui/gfx/gdk_compat.h" -#include "ui/gfx/gtk_compat.h" - -namespace ui { - -static const char* const kNetActiveWindow = "_NET_ACTIVE_WINDOW"; - -// static -ActiveWindowWatcherX* ActiveWindowWatcherX::GetInstance() { - return Singleton::get(); -} - -// static -void ActiveWindowWatcherX::AddObserver(ActiveWindowWatcherXObserver* observer) { - // Ensure that RootWindowPropertyWatcherX exists. - internal::RootWindowPropertyWatcherX::GetInstance(); - GetInstance()->observers_.AddObserver(observer); -} - -// static -void ActiveWindowWatcherX::RemoveObserver( - ActiveWindowWatcherXObserver* observer) { - GetInstance()->observers_.RemoveObserver(observer); -} - -// static -Atom ActiveWindowWatcherX::GetPropertyAtom() { - return GetAtom(kNetActiveWindow); -} - -// static -void ActiveWindowWatcherX::Notify() { - GetInstance()->NotifyActiveWindowChanged(); -} - -// static -bool ActiveWindowWatcherX::WMSupportsActivation() { - return gdk_x11_screen_supports_net_wm_hint( - gdk_screen_get_default(), - gdk_atom_intern_static_string(kNetActiveWindow)); -} - -ActiveWindowWatcherX::ActiveWindowWatcherX() { -} - -ActiveWindowWatcherX::~ActiveWindowWatcherX() { -} - -void ActiveWindowWatcherX::NotifyActiveWindowChanged() { - // We don't use gdk_screen_get_active_window() because it caches - // whether or not the window manager supports _NET_ACTIVE_WINDOW. - // This causes problems at startup for chromiumos. - Atom type = None; - int format = 0; // size in bits of each item in 'property' - long unsigned int num_items = 0, remaining_bytes = 0; - unsigned char* property = NULL; - - XGetWindowProperty(gdk_x11_get_default_xdisplay(), - GDK_WINDOW_XID(gdk_get_default_root_window()), - GetAtom(kNetActiveWindow), - 0, // offset into property data to read - 1, // length to get in 32-bit quantities - False, // deleted - AnyPropertyType, - &type, - &format, - &num_items, - &remaining_bytes, - &property); - - // Check that the property was set and contained a single 32-bit item (we - // don't check that remaining_bytes is 0, though, as XFCE's window manager - // seems to actually store two values in the property for some unknown - // reason.) - if (format == 32 && num_items == 1) { - int xid = *reinterpret_cast(property); - GdkDisplay* display = gdk_display_get_default(); - GdkWindow* active_window = gdk_x11_window_lookup_for_display(display, xid); - FOR_EACH_OBSERVER(ActiveWindowWatcherXObserver, observers_, - ActiveWindowChanged(active_window)); - } - if (property) - XFree(property); -} - -} // namespace ui diff --git a/chromium_src/ui/base/x/active_window_watcher_x.h b/chromium_src/ui/base/x/active_window_watcher_x.h deleted file mode 100644 index 01f70f4c93fd..000000000000 --- a/chromium_src/ui/base/x/active_window_watcher_x.h +++ /dev/null @@ -1,60 +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 UI_BASE_X_ACTIVE_WINDOW_WATCHER_X_H_ -#define UI_BASE_X_ACTIVE_WINDOW_WATCHER_X_H_ - -#include "base/basictypes.h" -#include "base/observer_list.h" -#include "ui/base/ui_base_export.h" -#include "ui/base/x/x11_util.h" - -template struct DefaultSingletonTraits; - -namespace ui { - -class ActiveWindowWatcherXObserver; - -namespace internal { -class RootWindowPropertyWatcherX; -} - -// This is a helper class that is used to keep track of which window the X -// window manager thinks is active. Add an Observer to listen for changes to -// the active window. -class UI_BASE_EXPORT ActiveWindowWatcherX { - public: - static ActiveWindowWatcherX* GetInstance(); - static void AddObserver(ActiveWindowWatcherXObserver* observer); - static void RemoveObserver(ActiveWindowWatcherXObserver* observer); - - // Checks if the WM supports the active window property. Note that the return - // value can change, especially during system startup. - static bool WMSupportsActivation(); - - private: - friend struct DefaultSingletonTraits; - friend class ui::internal::RootWindowPropertyWatcherX; - - ActiveWindowWatcherX(); - ~ActiveWindowWatcherX(); - - // Gets the atom for the default display for the property this class is - // watching for. - static Atom GetPropertyAtom(); - - // Notify observers that the active window has changed. - static void Notify(); - - // Instance method that implements Notify(). - void NotifyActiveWindowChanged(); - - ObserverList observers_; - - DISALLOW_COPY_AND_ASSIGN(ActiveWindowWatcherX); -}; - -} // namespace ui - -#endif // UI_BASE_X_ACTIVE_WINDOW_WATCHER_X_H_ diff --git a/chromium_src/ui/base/x/active_window_watcher_x_observer.h b/chromium_src/ui/base/x/active_window_watcher_x_observer.h deleted file mode 100644 index 4634f91333ec..000000000000 --- a/chromium_src/ui/base/x/active_window_watcher_x_observer.h +++ /dev/null @@ -1,25 +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 UI_BASE_X_ACTIVE_WINDOW_WATCHER_X_OBSERVER_H_ -#define UI_BASE_X_ACTIVE_WINDOW_WATCHER_X_OBSERVER_H_ - -#include - -#include "ui/base/ui_base_export.h" - -namespace ui { - -class UI_BASE_EXPORT ActiveWindowWatcherXObserver { - public: - // |active_window| will be NULL if the active window isn't one of Chrome's. - virtual void ActiveWindowChanged(GdkWindow* active_window) = 0; - - protected: - virtual ~ActiveWindowWatcherXObserver() {} -}; - -} // namespace ui - -#endif // UI_BASE_X_ACTIVE_WINDOW_WATCHER_X_OBSERVER_H_ diff --git a/chromium_src/ui/base/x/root_window_property_watcher_x.cc b/chromium_src/ui/base/x/root_window_property_watcher_x.cc deleted file mode 100644 index dec47e2a1db5..000000000000 --- a/chromium_src/ui/base/x/root_window_property_watcher_x.cc +++ /dev/null @@ -1,59 +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 "ui/base/x/root_window_property_watcher_x.h" - -#include -#include - -#include "base/memory/singleton.h" -#include "ui/base/x/active_window_watcher_x.h" -#include "ui/base/x/work_area_watcher_x.h" - -namespace ui { - -namespace internal { - -// static -RootWindowPropertyWatcherX* RootWindowPropertyWatcherX::GetInstance() { - return Singleton::get(); -} - -RootWindowPropertyWatcherX::RootWindowPropertyWatcherX() { - GdkWindow* root = gdk_get_default_root_window(); - - // Set up X Event filter to listen for PropertyChange X events. - // Don't use XSelectInput directly here, as gdk internally seems to cache the - // mask and reapply XSelectInput after this, resetting any mask we set here. - gdk_window_set_events(root, - static_cast(gdk_window_get_events(root) | - GDK_PROPERTY_CHANGE_MASK)); - gdk_window_add_filter(root, - &RootWindowPropertyWatcherX::OnWindowXEventThunk, - this); -} - -RootWindowPropertyWatcherX::~RootWindowPropertyWatcherX() { - gdk_window_remove_filter(NULL, - &RootWindowPropertyWatcherX::OnWindowXEventThunk, - this); -} - -GdkFilterReturn RootWindowPropertyWatcherX::OnWindowXEvent( - GdkXEvent* xevent, GdkEvent* event) { - XEvent* xev = static_cast(xevent); - - if (xev->xany.type == PropertyNotify) { - if (xev->xproperty.atom == ActiveWindowWatcherX::GetPropertyAtom()) - ActiveWindowWatcherX::Notify(); - else if (xev->xproperty.atom == WorkAreaWatcherX::GetPropertyAtom()) - WorkAreaWatcherX::Notify(); - } - - return GDK_FILTER_CONTINUE; -} - -} // namespace internal - -} // namespace ui diff --git a/chromium_src/ui/base/x/root_window_property_watcher_x.h b/chromium_src/ui/base/x/root_window_property_watcher_x.h deleted file mode 100644 index 76090162f7fc..000000000000 --- a/chromium_src/ui/base/x/root_window_property_watcher_x.h +++ /dev/null @@ -1,41 +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 UI_BASE_X_ROOT_WINDOW_PROPERTY_WATCHER_X_H_ -#define UI_BASE_X_ROOT_WINDOW_PROPERTY_WATCHER_X_H_ - -#include - -#include "base/basictypes.h" -#include "ui/base/gtk/gtk_signal.h" - -template struct DefaultSingletonTraits; - -namespace ui { -namespace internal { - -// This class keeps track of changes to properties on the root window. This is -// not to be used directly. Implement a watcher for the specific property you're -// interested in. -class RootWindowPropertyWatcherX { - public: - static RootWindowPropertyWatcherX* GetInstance(); - - private: - friend struct DefaultSingletonTraits; - - RootWindowPropertyWatcherX(); - ~RootWindowPropertyWatcherX(); - - // Callback for PropertyChange XEvents. - CHROMEG_CALLBACK_1(RootWindowPropertyWatcherX, GdkFilterReturn, - OnWindowXEvent, GdkXEvent*, GdkEvent*); - - DISALLOW_COPY_AND_ASSIGN(RootWindowPropertyWatcherX); -}; - -} // namespace internal -} // namespace ui - -#endif // UI_BASE_X_ROOT_WINDOW_PROPERTY_WATCHER_X_H_ diff --git a/chromium_src/ui/base/x/work_area_watcher_x.cc b/chromium_src/ui/base/x/work_area_watcher_x.cc deleted file mode 100644 index 053b48990110..000000000000 --- a/chromium_src/ui/base/x/work_area_watcher_x.cc +++ /dev/null @@ -1,53 +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 "ui/base/x/work_area_watcher_x.h" - -#include "base/memory/singleton.h" -#include "ui/base/work_area_watcher_observer.h" -#include "ui/base/x/root_window_property_watcher_x.h" -#include "ui/base/x/x11_util.h" - -namespace ui { - -static const char* const kNetWorkArea = "_NET_WORKAREA"; - -// static -WorkAreaWatcherX* WorkAreaWatcherX::GetInstance() { - return Singleton::get(); -} - -// static -void WorkAreaWatcherX::AddObserver(WorkAreaWatcherObserver* observer) { - // Ensure that RootWindowPropertyWatcherX exists. - internal::RootWindowPropertyWatcherX::GetInstance(); - GetInstance()->observers_.AddObserver(observer); -} - -// static -void WorkAreaWatcherX::RemoveObserver(WorkAreaWatcherObserver* observer) { - GetInstance()->observers_.RemoveObserver(observer); -} - -// static -void WorkAreaWatcherX::Notify() { - GetInstance()->NotifyWorkAreaChanged(); -} - -// static -Atom WorkAreaWatcherX::GetPropertyAtom() { - return GetAtom(kNetWorkArea); -} - -WorkAreaWatcherX::WorkAreaWatcherX() { -} - -WorkAreaWatcherX::~WorkAreaWatcherX() { -} - -void WorkAreaWatcherX::NotifyWorkAreaChanged() { - FOR_EACH_OBSERVER(WorkAreaWatcherObserver, observers_, WorkAreaChanged()); -} - -} // namespace ui diff --git a/chromium_src/ui/base/x/work_area_watcher_x.h b/chromium_src/ui/base/x/work_area_watcher_x.h deleted file mode 100644 index 96cbcaec118d..000000000000 --- a/chromium_src/ui/base/x/work_area_watcher_x.h +++ /dev/null @@ -1,55 +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 UI_BASE_X_WORK_AREA_WATCHER_X_H_ -#define UI_BASE_X_WORK_AREA_WATCHER_X_H_ - -#include "base/basictypes.h" -#include "base/observer_list.h" -#include "ui/base/ui_base_export.h" -#include "ui/base/x/x11_util.h" - -template struct DefaultSingletonTraits; - -namespace ui { - -class WorkAreaWatcherObserver; - -namespace internal { -class RootWindowPropertyWatcherX; -} - -// This is a helper class that is used to keep track of changes to work area. -// Add an observer to track changes. -class UI_BASE_EXPORT WorkAreaWatcherX { - public: - static WorkAreaWatcherX* GetInstance(); - static void AddObserver(WorkAreaWatcherObserver* observer); - static void RemoveObserver(WorkAreaWatcherObserver* observer); - - private: - friend struct DefaultSingletonTraits; - friend class ui::internal::RootWindowPropertyWatcherX; - - WorkAreaWatcherX(); - ~WorkAreaWatcherX(); - - // Gets the atom for the default display for the property this class is - // watching for. - static Atom GetPropertyAtom(); - - // Notify observers that the work area has changed. - static void Notify(); - - // Instance method that implements Notify(). - void NotifyWorkAreaChanged(); - - ObserverList observers_; - - DISALLOW_COPY_AND_ASSIGN(WorkAreaWatcherX); -}; - -} // namespace ui - -#endif // UI_BASE_X_WORK_AREA_WATCHER_X_H_ diff --git a/chromium_src/ui/base/x/x11_util.cc b/chromium_src/ui/base/x/x11_util.cc deleted file mode 100644 index 94dbe5ba213a..000000000000 --- a/chromium_src/ui/base/x/x11_util.cc +++ /dev/null @@ -1,25 +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. - -// This file defines utility functions for X11 (Linux only). This code has been -// ported from XCB since we can't use XCB on Ubuntu while its 32-bit support -// remains woefully incomplete. - -#include "ui/base/x/x11_util.h" - -#include "ui/gfx/gdk_compat.h" - -namespace ui { - -Atom GetAtom(const char* name) { -#if defined(TOOLKIT_GTK) - return gdk_x11_get_xatom_by_name_for_display( - gdk_display_get_default(), name); -#else - // TODO(derat): Cache atoms to avoid round-trips to the server. - return XInternAtom(gfx::GetXDisplay(), name, false); -#endif -} - -} // namespace ui diff --git a/chromium_src/ui/events/keycodes/keyboard_code_conversion_gtk.cc b/chromium_src/ui/events/keycodes/keyboard_code_conversion_gtk.cc deleted file mode 100644 index 9a396534e20e..000000000000 --- a/chromium_src/ui/events/keycodes/keyboard_code_conversion_gtk.cc +++ /dev/null @@ -1,85 +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. - -/* - * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. - * Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com - * Copyright (C) 2007 Holger Hans Peter Freyther - * Copyright (C) 2008 Collabora, Ltd. All rights reserved. - * Copyright (C) 2008, 2009 Google Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// WindowsKeyCodeForGdkKeyCode is copied from platform/gtk/KeyEventGtk.cpp - -#include "ui/events/keycodes/keyboard_code_conversion_gtk.h" - -#include -#include -#include - -#include "base/basictypes.h" -#include "build/build_config.h" -#include "ui/events/keycodes/keyboard_code_conversion_x.h" -#include "ui/events/keycodes/keyboard_codes_posix.h" - -namespace ui { - -KeyboardCode WindowsKeyCodeForGdkKeyCode(int keycode) { - // Gdk key codes (e.g. GDK_BackSpace) and X keysyms (e.g. XK_BackSpace) share - // the same values. - return KeyboardCodeFromXKeysym(keycode); -} - -int GdkKeyCodeForWindowsKeyCode(KeyboardCode keycode, bool shift) { - // Gdk key codes and X keysyms share the same values. - return XKeysymForWindowsKeyCode(keycode, shift); -} - -// Just in case, test whether Gdk key codes match X ones. -COMPILE_ASSERT(GDK_KP_0 == XK_KP_0, keycode_check); -COMPILE_ASSERT(GDK_A == XK_A, keycode_check); -COMPILE_ASSERT(GDK_Escape == XK_Escape, keycode_check); -COMPILE_ASSERT(GDK_F1 == XK_F1, keycode_check); -COMPILE_ASSERT(GDK_Kanji == XK_Kanji, keycode_check); -COMPILE_ASSERT(GDK_Page_Up == XK_Page_Up, keycode_check); -COMPILE_ASSERT(GDK_Tab == XK_Tab, keycode_check); -COMPILE_ASSERT(GDK_a == XK_a, keycode_check); -COMPILE_ASSERT(GDK_space == XK_space, keycode_check); - -int GdkNativeKeyCodeForWindowsKeyCode(KeyboardCode keycode, bool shift) { - int keyval = GdkKeyCodeForWindowsKeyCode(keycode, shift); - GdkKeymapKey* keys; - gint n_keys; - - int native_keycode = 0; - if (keyval && gdk_keymap_get_entries_for_keyval(0, keyval, &keys, &n_keys)) { - native_keycode = keys[0].keycode; - g_free(keys); - } - - return native_keycode; -} - -} // namespace ui diff --git a/chromium_src/ui/events/keycodes/keyboard_code_conversion_gtk.h b/chromium_src/ui/events/keycodes/keyboard_code_conversion_gtk.h deleted file mode 100644 index 6258f4116c1e..000000000000 --- a/chromium_src/ui/events/keycodes/keyboard_code_conversion_gtk.h +++ /dev/null @@ -1,58 +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. - -/* - * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. - * Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com - * Copyright (C) 2007 Holger Hans Peter Freyther - * Copyright (C) 2008 Collabora, Ltd. All rights reserved. - * Copyright (C) 2008, 2009 Google Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// WindowsKeyCodeForGdkKeyCode is copied from platform/gtk/KeyEventGtk.cpp - -#ifndef UI_EVENTS_KEYCODES_KEYBOARD_CODE_CONVERSION_GTK_H_ -#define UI_EVENTS_KEYCODES_KEYBOARD_CODE_CONVERSION_GTK_H_ - -#include "ui/events/events_base_export.h" -#include "ui/events/keycodes/keyboard_codes_posix.h" - -typedef struct _GdkEventKey GdkEventKey; - -namespace ui { - -EVENTS_BASE_EXPORT KeyboardCode WindowsKeyCodeForGdkKeyCode(int keycode); - -EVENTS_BASE_EXPORT int GdkKeyCodeForWindowsKeyCode(KeyboardCode keycode, - bool shift); - -// For WebKit DRT testing: simulate the native keycode for the given -// input |keycode|. Return the native keycode. -EVENTS_BASE_EXPORT int GdkNativeKeyCodeForWindowsKeyCode(KeyboardCode keycode, - bool shift); - -} // namespace ui - -#endif // UI_EVENTS_KEYCODES_KEYBOARD_CODE_CONVERSION_GTK_H_ diff --git a/chromium_src/ui/gfx/gtk_util.h b/chromium_src/ui/gfx/gtk_util.h deleted file mode 100644 index 7607603f6363..000000000000 --- a/chromium_src/ui/gfx/gtk_util.h +++ /dev/null @@ -1,55 +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 UI_GFX_GTK_UTIL_H_ -#define UI_GFX_GTK_UTIL_H_ - -#include - -#include "base/time/time.h" -#include "ui/gfx/gfx_export.h" - -typedef struct _GdkPixbuf GdkPixbuf; -typedef struct _GdkRegion GdkRegion; -typedef struct _GdkCursor GdkCursor; - -class SkBitmap; - -namespace base { -class CommandLine; -} - -namespace gfx { - -class Rect; - -// Call gtk_init() / gdk_init() using the argc and argv from command_line. -// These init functions want an argc and argv that they can mutate; we provide -// those, but leave the original CommandLine unaltered. -GFX_EXPORT void GtkInitFromCommandLine(const base::CommandLine& command_line); -GFX_EXPORT void GdkInitFromCommandLine(const base::CommandLine& command_line); - -// 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. -GFX_EXPORT GdkPixbuf* GdkPixbufFromSkBitmap(const SkBitmap& bitmap); - -// Modify the given region by subtracting the given rectangles. -GFX_EXPORT void SubtractRectanglesFromRegion(GdkRegion* region, - const std::vector& cutouts); - -// Returns a static instance of a GdkCursor* object, sharable across the -// process. Caller must gdk_cursor_ref() it if they want to assume ownership. -GFX_EXPORT GdkCursor* GetCursor(int type); - -// Initialize some GTK settings so that our dialogs are consistent. -GFX_EXPORT void InitRCStyles(); - -// Queries GtkSettings for the cursor blink cycle time. Returns a 0 duration if -// blinking is disabled. -GFX_EXPORT base::TimeDelta GetCursorBlinkCycle(); - -} // namespace gfx - -#endif // UI_GFX_GTK_UTIL_H_ diff --git a/chromium_src/ui/gfx/gtk_util_gfx.cc b/chromium_src/ui/gfx/gtk_util_gfx.cc deleted file mode 100644 index d7ff53963ac0..000000000000 --- a/chromium_src/ui/gfx/gtk_util_gfx.cc +++ /dev/null @@ -1,192 +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 "ui/gfx/gtk_util.h" - -#include -#include -#include - -#include "base/basictypes.h" -#include "base/command_line.h" -#include "base/memory/scoped_ptr.h" -#include "third_party/skia/include/core/SkBitmap.h" -#include "third_party/skia/include/core/SkUnPreMultiply.h" -#include "ui/gfx/rect.h" - -namespace { - -// A process wide singleton that manages our usage of gdk cursors. -// gdk_cursor_new() hits the disk in several places and GdkCursor instances can -// be reused throughout the process. -class GdkCursorCache { - public: - GdkCursorCache() {} - ~GdkCursorCache() { - for (GdkCursorMap::iterator i(cursors_.begin()); i != cursors_.end(); ++i) { - gdk_cursor_unref(i->second); - } - cursors_.clear(); - } - - GdkCursor* GetCursorImpl(GdkCursorType type) { - GdkCursorMap::iterator it = cursors_.find(type); - GdkCursor* cursor = NULL; - if (it == cursors_.end()) { - cursor = gdk_cursor_new(type); - cursors_.insert(std::make_pair(type, cursor)); - } else { - cursor = it->second; - } - - // It is not necessary to add a reference here. The callers can ref the - // cursor if they need it for something. - return cursor; - } - - private: - typedef std::map GdkCursorMap; - GdkCursorMap cursors_; - - DISALLOW_COPY_AND_ASSIGN(GdkCursorCache); -}; - -} // namespace - -namespace gfx { - -static void CommonInitFromCommandLine(const CommandLine& command_line, - void (*init_func)(gint*, gchar***)) { - const std::vector& args = command_line.argv(); - int argc = args.size(); - scoped_ptr argv(new char *[argc + 1]); - for (size_t i = 0; i < args.size(); ++i) { - // TODO(piman@google.com): can gtk_init modify argv? Just being safe - // here. - argv[i] = strdup(args[i].c_str()); - } - argv[argc] = NULL; - char **argv_pointer = argv.get(); - - init_func(&argc, &argv_pointer); - for (size_t i = 0; i < args.size(); ++i) { - free(argv[i]); - } -} - -void GtkInitFromCommandLine(const CommandLine& command_line) { - CommonInitFromCommandLine(command_line, gtk_init); -} - -void GdkInitFromCommandLine(const CommandLine& command_line) { - CommonInitFromCommandLine(command_line, gdk_init); -} - -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; -} - -void SubtractRectanglesFromRegion(GdkRegion* region, - const std::vector& cutouts) { - for (size_t i = 0; i < cutouts.size(); ++i) { - GdkRectangle rect = { - cutouts[i].x(), cutouts[i].y(), cutouts[i].width(), cutouts[i].height() - }; - GdkRegion* rect_region = gdk_region_rectangle(&rect); - gdk_region_subtract(region, rect_region); - // TODO(deanm): It would be nice to be able to reuse the GdkRegion here. - gdk_region_destroy(rect_region); - } -} - -GdkCursor* GetCursor(int type) { - CR_DEFINE_STATIC_LOCAL(GdkCursorCache, impl, ()); - return impl.GetCursorImpl(static_cast(type)); -} - -void InitRCStyles() { - static const char kRCText[] = - // Make our dialogs styled like the GNOME HIG. - // - // TODO(evanm): content-area-spacing was introduced in a later - // version of GTK, so we need to set that manually on all dialogs. - // Perhaps it would make sense to have a shared FixupDialog() function. - "style \"gnome-dialog\" {\n" - " xthickness = 12\n" - " GtkDialog::action-area-border = 0\n" - " GtkDialog::button-spacing = 6\n" - " GtkDialog::content-area-spacing = 18\n" - " GtkDialog::content-area-border = 12\n" - "}\n" - // Note we set it at the "application" priority, so users can override. - "widget \"GtkDialog\" style : application \"gnome-dialog\"\n" - - // Make our about dialog special, so the image is flush with the edge. - "style \"about-dialog\" {\n" - " GtkDialog::action-area-border = 12\n" - " GtkDialog::button-spacing = 6\n" - " GtkDialog::content-area-spacing = 18\n" - " GtkDialog::content-area-border = 0\n" - "}\n" - "widget \"about-dialog\" style : application \"about-dialog\"\n"; - - gtk_rc_parse_string(kRCText); -} - -base::TimeDelta GetCursorBlinkCycle() { - // From http://library.gnome.org/devel/gtk/unstable/GtkSettings.html, this is - // the default value for gtk-cursor-blink-time. - static const gint kGtkDefaultCursorBlinkTime = 1200; - - gint cursor_blink_time = kGtkDefaultCursorBlinkTime; - gboolean cursor_blink = TRUE; - g_object_get(gtk_settings_get_default(), - "gtk-cursor-blink-time", &cursor_blink_time, - "gtk-cursor-blink", &cursor_blink, - NULL); - return cursor_blink ? - base::TimeDelta::FromMilliseconds(cursor_blink_time) : - base::TimeDelta(); -} - -} // namespace gfx