diff options
author | saintlou@chromium.org <saintlou@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-19 18:18:48 +0000 |
---|---|---|
committer | saintlou@chromium.org <saintlou@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-19 18:18:48 +0000 |
commit | 077d56ae8b021a85c94010af48daee477972ea04 (patch) | |
tree | 3fe72977892dccfda8fe138ec1cd02bdda23d6e6 /ui | |
parent | 484a65aef61f9809cbe083ef93fb66ff016d5776 (diff) | |
download | chromium_src-077d56ae8b021a85c94010af48daee477972ea04.zip chromium_src-077d56ae8b021a85c94010af48daee477972ea04.tar.gz chromium_src-077d56ae8b021a85c94010af48daee477972ea04.tar.bz2 |
Removing deprecated GTK-Views code.
BUG=none
TEST=none
Review URL: https://chromiumcodereview.appspot.com/9728002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@127507 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
41 files changed, 2 insertions, 8156 deletions
diff --git a/ui/views/controls/combobox/native_combobox_gtk.cc b/ui/views/controls/combobox/native_combobox_gtk.cc deleted file mode 100644 index 4214f32..0000000 --- a/ui/views/controls/combobox/native_combobox_gtk.cc +++ /dev/null @@ -1,220 +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/views/controls/combobox/native_combobox_gtk.h" - -#include <gtk/gtk.h> - -#include <algorithm> - -#include "base/message_loop.h" -#include "base/utf_string_conversions.h" -#include "ui/base/models/combobox_model.h" -#include "ui/views/controls/combobox/combobox.h" -#include "ui/views/controls/combobox/native_combobox_views.h" -#include "ui/views/views_delegate.h" -#include "ui/views/widget/widget.h" - -namespace views { - -//////////////////////////////////////////////////////////////////////////////// -// NativeComboboxGtk, public: - -NativeComboboxGtk::NativeComboboxGtk(Combobox* combobox) - : combobox_(combobox), - menu_(NULL) { - set_focus_view(combobox); -} - -NativeComboboxGtk::~NativeComboboxGtk() { -} - -//////////////////////////////////////////////////////////////////////////////// -// NativeComboboxGtk, NativeComboboxWrapper implementation: - -void NativeComboboxGtk::UpdateFromModel() { - if (!native_view()) - return; - - preferred_size_ = gfx::Size(); - - GtkListStore* store = - GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(native_view()))); - ui::ComboboxModel* model = combobox_->model(); - int count = model->GetItemCount(); - gtk_list_store_clear(store); - GtkTreeIter iter; - while (count-- > 0) { - gtk_list_store_prepend(store, &iter); - gtk_list_store_set(store, &iter, - 0, UTF16ToUTF8(model->GetItemAt(count)).c_str(), - -1); - } -} - -void NativeComboboxGtk::UpdateSelectedItem() { - if (!native_view()) - return; - gtk_combo_box_set_active( - GTK_COMBO_BOX(native_view()), combobox_->selected_item()); -} - -void NativeComboboxGtk::UpdateEnabled() { - SetEnabled(combobox_->enabled()); -} - -int NativeComboboxGtk::GetSelectedItem() const { - if (!native_view()) - return 0; - return gtk_combo_box_get_active(GTK_COMBO_BOX(native_view())); -} - -bool NativeComboboxGtk::IsDropdownOpen() const { - if (!native_view()) - return false; - gboolean popup_shown; - g_object_get(G_OBJECT(native_view()), "popup-shown", &popup_shown, NULL); - return popup_shown; -} - -gfx::Size NativeComboboxGtk::GetPreferredSize() { - if (!native_view()) - return gfx::Size(); - - if (preferred_size_.IsEmpty()) { - GtkRequisition size_request = { 0, 0 }; - gtk_widget_size_request(native_view(), &size_request); - // TODO(oshima|scott): we may not need ::max to 29. revisit this. - preferred_size_.SetSize(size_request.width, - std::max(size_request.height, 29)); - } - return preferred_size_; -} - -View* NativeComboboxGtk::GetView() { - return this; -} - -void NativeComboboxGtk::SetFocus() { - OnFocus(); -} - -bool NativeComboboxGtk::HandleKeyPressed(const views::KeyEvent& event) { - return false; -} - -bool NativeComboboxGtk::HandleKeyReleased(const views::KeyEvent& event) { - return false; -} - -void NativeComboboxGtk::HandleFocus() { -} - -void NativeComboboxGtk::HandleBlur() { -} - -gfx::NativeView NativeComboboxGtk::GetTestingHandle() const { - return native_view(); -} - - -//////////////////////////////////////////////////////////////////////////////// -// NativeComboboxGtk, NativeControlGtk overrides: -void NativeComboboxGtk::CreateNativeControl() { - GtkListStore* store = gtk_list_store_new(1, G_TYPE_STRING); - GtkWidget* widget = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store)); - g_object_unref(G_OBJECT(store)); - - GtkCellRenderer* cell = gtk_cell_renderer_text_new(); - gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(widget), cell, TRUE); - gtk_cell_layout_set_attributes( - GTK_CELL_LAYOUT(widget), cell, "text", 0, NULL); - g_signal_connect(widget, "changed", - G_CALLBACK(CallChangedThunk), this); - g_signal_connect_after(widget, "popup", - G_CALLBACK(CallPopUpThunk), this); - - // Get the menu associated with the combo box and listen to events on it. - GList* menu_list = gtk_menu_get_for_attach_widget(widget); - if (menu_list) { - menu_ = reinterpret_cast<GtkMenu*>(menu_list->data); - g_signal_connect_after(menu_, "move-current", - G_CALLBACK(CallMenuMoveCurrentThunk), this); - } - - NativeControlCreated(widget); -} - -//////////////////////////////////////////////////////////////////////////////// -// NativeComboboxGtk, private: -void NativeComboboxGtk::SelectionChanged() { - combobox_->SelectionChanged(); -} - -void NativeComboboxGtk::FocusedMenuItemChanged() { - DCHECK(menu_); - GtkWidget* menu_item = GTK_MENU_SHELL(menu_)->active_menu_item; - if (!menu_item) - return; - - // Figure out the item index and total number of items. - GList* items = gtk_container_get_children(GTK_CONTAINER(menu_)); - guint count = g_list_length(items); - int index = g_list_index(items, static_cast<gconstpointer>(menu_item)); - - // Get the menu item's label. - std::string name; - GList* children = gtk_container_get_children(GTK_CONTAINER(menu_item)); - for (GList* l = g_list_first(children); l != NULL; l = g_list_next(l)) { - GtkWidget* child = static_cast<GtkWidget*>(l->data); - if (GTK_IS_CELL_VIEW(child)) { - GtkCellView* cell_view = GTK_CELL_VIEW(child); - GtkTreePath* path = gtk_cell_view_get_displayed_row(cell_view); - GtkTreeModel* model = NULL; - model = gtk_cell_view_get_model(cell_view); - GtkTreeIter iter; - if (model && gtk_tree_model_get_iter(model, &iter, path)) { - GValue value = { 0 }; - gtk_tree_model_get_value(model, &iter, 0, &value); - name = g_value_get_string(&value); - break; - } - } - } - - if (ViewsDelegate::views_delegate) { - ViewsDelegate::views_delegate->NotifyMenuItemFocused(string16(), - UTF8ToUTF16(name), - index, - count, - false); - } -} - -void NativeComboboxGtk::CallChanged(GtkWidget* widget) { - SelectionChanged(); -} - -gboolean NativeComboboxGtk::CallPopUp(GtkWidget* widget) { - FocusedMenuItemChanged(); - return false; -} - -void NativeComboboxGtk::CallMenuMoveCurrent( - GtkWidget* menu, GtkMenuDirectionType focus_direction) { - FocusedMenuItemChanged(); -} - -//////////////////////////////////////////////////////////////////////////////// -// NativeComboboxWrapper, public: - -// static -NativeComboboxWrapper* NativeComboboxWrapper::CreateWrapper( - Combobox* combobox) { - if (Widget::IsPureViews()) - return new NativeComboboxViews(combobox); - return new NativeComboboxGtk(combobox); -} - -} // namespace views diff --git a/ui/views/controls/combobox/native_combobox_gtk.h b/ui/views/controls/combobox/native_combobox_gtk.h deleted file mode 100644 index b7e3609..0000000 --- a/ui/views/controls/combobox/native_combobox_gtk.h +++ /dev/null @@ -1,63 +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_VIEWS_CONTROLS_COMBOBOX_NATIVE_COMBOBOX_GTK_H_ -#define UI_VIEWS_CONTROLS_COMBOBOX_NATIVE_COMBOBOX_GTK_H_ -#pragma once - -#include "ui/base/gtk/gtk_signal.h" -#include "ui/views/controls/combobox/native_combobox_wrapper.h" -#include "ui/views/controls/native_control_gtk.h" - -namespace views { - -class NativeComboboxGtk : public NativeControlGtk, - public NativeComboboxWrapper { - public: - explicit NativeComboboxGtk(Combobox* combobox); - virtual ~NativeComboboxGtk(); - - // Overridden from NativeComboboxWrapper: - virtual void UpdateFromModel() OVERRIDE; - virtual void UpdateSelectedItem() OVERRIDE; - virtual void UpdateEnabled() OVERRIDE; - virtual int GetSelectedItem() const OVERRIDE; - virtual bool IsDropdownOpen() const OVERRIDE; - virtual gfx::Size GetPreferredSize() OVERRIDE; - virtual View* GetView() OVERRIDE; - virtual void SetFocus() OVERRIDE; - virtual bool HandleKeyPressed(const views::KeyEvent& event) OVERRIDE; - virtual bool HandleKeyReleased(const views::KeyEvent& event) OVERRIDE; - virtual void HandleFocus() OVERRIDE; - virtual void HandleBlur() OVERRIDE; - virtual gfx::NativeView GetTestingHandle() const OVERRIDE; - - protected: - // Overridden from NativeControlGtk: - virtual void CreateNativeControl() OVERRIDE; - - private: - void SelectionChanged(); - void FocusedMenuItemChanged(); - - CHROMEGTK_CALLBACK_0(NativeComboboxGtk, void, CallChanged); - CHROMEGTK_CALLBACK_0(NativeComboboxGtk, gboolean, CallPopUp); - CHROMEGTK_CALLBACK_1(NativeComboboxGtk, void, CallMenuMoveCurrent, - GtkMenuDirectionType); - - // The combobox we are bound to. - Combobox* combobox_; - - // The combo box's pop-up menu. - GtkMenu* menu_; - - // The preferred size from the last size_request. - gfx::Size preferred_size_; - - DISALLOW_COPY_AND_ASSIGN(NativeComboboxGtk); -}; - -} // namespace views - -#endif // UI_VIEWS_CONTROLS_COMBOBOX_NATIVE_COMBOBOX_GTK_H_ diff --git a/ui/views/controls/menu/menu_gtk.cc b/ui/views/controls/menu/menu_gtk.cc deleted file mode 100644 index 49972b2..0000000 --- a/ui/views/controls/menu/menu_gtk.cc +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/controls/menu/menu_gtk.h" - -#include "base/logging.h" - -namespace views { - -// static -Menu* Menu::Create(Delegate* delegate, - AnchorPoint anchor, - gfx::NativeView parent) { - return new MenuGtk(delegate, anchor, parent); -} - -// static -Menu* Menu::GetSystemMenu(gfx::NativeWindow parent) { - NOTIMPLEMENTED(); - return NULL; -} - -MenuGtk::MenuGtk(Delegate* d, AnchorPoint anchor, gfx::NativeView owner) - : Menu(d, anchor) { - DCHECK(delegate()); -} - -MenuGtk::~MenuGtk() { -} - -Menu* MenuGtk::AddSubMenuWithIcon(int index, - int item_id, - const string16& label, - const SkBitmap& icon) { - NOTIMPLEMENTED(); - return NULL; -} - -void MenuGtk::AddSeparator(int index) { - NOTIMPLEMENTED(); -} - -void MenuGtk::EnableMenuItemByID(int item_id, bool enabled) { - NOTIMPLEMENTED(); -} - -void MenuGtk::EnableMenuItemAt(int index, bool enabled) { - NOTIMPLEMENTED(); -} - -void MenuGtk::SetMenuLabel(int item_id, const string16& label) { - NOTIMPLEMENTED(); -} - -bool MenuGtk::SetIcon(const SkBitmap& icon, int item_id) { - NOTIMPLEMENTED(); - return false; -} - -void MenuGtk::RunMenuAt(int x, int y) { - NOTIMPLEMENTED(); -} - -void MenuGtk::Cancel() { - NOTIMPLEMENTED(); -} - -int MenuGtk::ItemCount() { - NOTIMPLEMENTED(); - return 0; -} - -void MenuGtk::AddMenuItemInternal(int index, - int item_id, - const string16& label, - const SkBitmap& icon, - MenuItemType type) { - NOTIMPLEMENTED(); -} - -} // namespace views diff --git a/ui/views/controls/menu/menu_gtk.h b/ui/views/controls/menu/menu_gtk.h deleted file mode 100644 index 0d9eeaf..0000000 --- a/ui/views/controls/menu/menu_gtk.h +++ /dev/null @@ -1,54 +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_VIEWS_CONTROLS_MENU_MENU_GTK_H_ -#define UI_VIEWS_CONTROLS_MENU_MENU_GTK_H_ -#pragma once - -#include "base/basictypes.h" -#include "base/compiler_specific.h" -#include "ui/views/controls/menu/menu.h" - -namespace views { - -class MenuGtk : public Menu { - public: - // Construct a Menu using the specified controller to determine command - // state. - // delegate A Menu::Delegate implementation that provides more - // information about the Menu presentation. - // anchor An alignment hint for the popup menu. - // owner The window that the menu is being brought up relative - // to. Not actually used for anything but must not be - // NULL. - MenuGtk(Delegate* d, AnchorPoint anchor, gfx::NativeView owner); - virtual ~MenuGtk(); - - // Overridden from Menu: - virtual Menu* AddSubMenuWithIcon(int index, - int item_id, - const string16& label, - const SkBitmap& icon) OVERRIDE; - virtual void AddSeparator(int index) OVERRIDE; - virtual void EnableMenuItemByID(int item_id, bool enabled) OVERRIDE; - virtual void EnableMenuItemAt(int index, bool enabled) OVERRIDE; - virtual void SetMenuLabel(int item_id, const string16& label) OVERRIDE; - virtual bool SetIcon(const SkBitmap& icon, int item_id) OVERRIDE; - virtual void RunMenuAt(int x, int y) OVERRIDE; - virtual void Cancel() OVERRIDE; - virtual int ItemCount() OVERRIDE; - - protected: - virtual void AddMenuItemInternal(int index, - int item_id, - const string16& label, - const SkBitmap& icon, - MenuItemType type) OVERRIDE; - - DISALLOW_COPY_AND_ASSIGN(MenuGtk); -}; - -} // namespace views - -#endif // UI_VIEWS_CONTROLS_MENU_MENU_GTK_H_ diff --git a/ui/views/controls/menu/native_menu_gtk.cc b/ui/views/controls/menu/native_menu_gtk.cc deleted file mode 100644 index 87b2fac..0000000 --- a/ui/views/controls/menu/native_menu_gtk.cc +++ /dev/null @@ -1,628 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/controls/menu/native_menu_gtk.h" - -#include <algorithm> -#include <map> -#include <string> - -#include "base/bind.h" -#include "base/i18n/rtl.h" -#include "base/message_loop.h" -#include "base/time.h" -#include "base/utf_string_conversions.h" -#include "third_party/skia/include/core/SkBitmap.h" -#include "ui/base/accelerators/accelerator.h" -#include "ui/base/keycodes/keyboard_code_conversion_gtk.h" -#include "ui/base/keycodes/keyboard_codes.h" -#include "ui/base/models/menu_model.h" -#include "ui/gfx/font.h" -#include "ui/gfx/gtk_util.h" -#include "ui/views/controls/menu/menu_2.h" -#include "ui/views/controls/menu/menu_listener.h" -#include "ui/views/controls/menu/nested_dispatcher_gtk.h" -#include "ui/views/views_delegate.h" -#include "ui/views/widget/native_widget_gtk.h" - -namespace { - -const char kPositionString[] = "position"; -const char kAccelGroupString[] = "accel_group"; - -// Key for the property set on the gtk menu that gives the handle to the hosting -// NativeMenuGtk. -const char kNativeMenuGtkString[] = "native_menu_gtk"; - -// Data passed to the MenuPositionFunc from gtk_menu_popup -struct Position { - // The point to run the menu at. - gfx::Point point; - // The alignment of the menu at that point. - views::Menu2::Alignment alignment; -}; - -// Returns true if the menu item type specified can be executed as a command. -bool MenuTypeCanExecute(ui::MenuModel::ItemType type) { - return type == ui::MenuModel::TYPE_COMMAND || - type == ui::MenuModel::TYPE_CHECK || - type == ui::MenuModel::TYPE_RADIO; -} - -// A callback to gtk_container_foreach to remove all children. -// See |NativeMenuGtk::ResetMenu| for the usage. -void RemoveChildWidget(GtkWidget* widget, gpointer data) { - GtkWidget* parent = gtk_widget_get_parent(widget); - gtk_container_remove(GTK_CONTAINER(parent), widget); -} - -} // namespace - -namespace views { - -//////////////////////////////////////////////////////////////////////////////// -// NativeMenuGtk, public: - -NativeMenuGtk::NativeMenuGtk(Menu2* menu) - : parent_(NULL), - model_(menu->model()), - menu_(NULL), - menu_hidden_(true), - suppress_activate_signal_(false), - activated_menu_(NULL), - activated_index_(-1), - activate_factory_(this), - host_menu_(menu), - destroy_handler_id_(0), - expose_handler_id_(0), - menu_action_(MENU_ACTION_NONE), - nested_dispatcher_(NULL), - ignore_button_release_(true) { -} - -NativeMenuGtk::~NativeMenuGtk() { - if (nested_dispatcher_) { - // Menu is destroyed while its in message loop. - // Let nested dispatcher know the creator is deleted. - nested_dispatcher_->CreatorDestroyed(); - } - if (menu_) { - DCHECK(destroy_handler_id_); - // Don't call MenuDestroyed because menu2 has already been destroyed. - g_signal_handler_disconnect(menu_, destroy_handler_id_); - gtk_widget_destroy(menu_); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// NativeMenuGtk, MenuWrapper implementation: - -void NativeMenuGtk::RunMenuAt(const gfx::Point& point, int alignment) { - activated_menu_ = NULL; - activated_index_ = -1; - menu_action_ = MENU_ACTION_NONE; - // ignore button release event unless mouse is pressed or moved. - ignore_button_release_ = true; - - UpdateStates(); - // Set the FREEZE UPDATE property to the menu's window so that WM maps - // the menu after the menu painted itself. - GtkWidget* popup_window = gtk_widget_get_ancestor(menu_, GTK_TYPE_WINDOW); - CHECK(popup_window); - NativeWidgetGtk::UpdateFreezeUpdatesProperty(GTK_WINDOW(popup_window), - true /* add */); - expose_handler_id_ = g_signal_connect_after(G_OBJECT(menu_), "expose_event", - G_CALLBACK(&OnExposeThunk), this); - - Position position = { point, static_cast<Menu2::Alignment>(alignment) }; - // TODO(beng): value of '1' will not work for context menus! - gtk_menu_popup(GTK_MENU(menu_), NULL, NULL, MenuPositionFunc, &position, 1, - gtk_get_current_event_time()); - DCHECK(menu_hidden_); - menu_hidden_ = false; - - FOR_EACH_OBSERVER(MenuListener, listeners_, OnMenuOpened()); - - // Listen for "hide" signal so that we know when to return from the blocking - // RunMenuAt call. - gint hide_handle_id = - g_signal_connect(menu_, "hide", G_CALLBACK(OnMenuHiddenThunk), this); - - gint move_handle_id = - g_signal_connect(menu_, "move-current", - G_CALLBACK(OnMenuMoveCurrentThunk), this); - gint after_move_handle_id = - g_signal_connect_after(menu_, "move-current", - G_CALLBACK(AfterMenuMoveCurrentThunk), this); - - model_->MenuWillShow(); - - // Block until menu is no longer shown by running a nested message loop. - nested_dispatcher_ = new NestedDispatcherGtk(this, true); - bool deleted = nested_dispatcher_->RunAndSelfDestruct(); - if (deleted) { - // The menu was destryed while menu is shown, so return immediately. - // Don't touch the instance which is already deleted. - return; - } - nested_dispatcher_ = NULL; - if (!menu_hidden_) { - // If this happens it means we haven't yet gotten the hide signal and - // someone else quit the message loop on us. - NOTREACHED(); - menu_hidden_ = true; - } - - g_signal_handler_disconnect(G_OBJECT(menu_), hide_handle_id); - g_signal_handler_disconnect(G_OBJECT(menu_), move_handle_id); - g_signal_handler_disconnect(G_OBJECT(menu_), after_move_handle_id); - - if (activated_menu_) { - MessageLoop::current()->PostTask(FROM_HERE, - base::Bind(&NativeMenuGtk::ProcessActivate, - activate_factory_.GetWeakPtr())); - } - - model_->MenuClosed(); -} - -void NativeMenuGtk::CancelMenu() { - gtk_widget_hide(menu_); -} - -void NativeMenuGtk::Rebuild() { - activated_menu_ = NULL; - - ResetMenu(); - - // Try to retrieve accelerator group as data from menu_; if null, create new - // one and store it as data into menu_. - // We store it as data so as to use the destroy notifier to get rid of initial - // reference count. For some reason, when we unref it ourselves (even in - // destructor), it would cause random crashes, depending on when gtk tries to - // access it. - GtkAccelGroup* accel_group = static_cast<GtkAccelGroup*>( - g_object_get_data(G_OBJECT(menu_), kAccelGroupString)); - if (!accel_group) { - accel_group = gtk_accel_group_new(); - g_object_set_data_full(G_OBJECT(menu_), kAccelGroupString, accel_group, - g_object_unref); - } - - std::map<int, GtkRadioMenuItem*> radio_groups_; - for (int i = 0; i < model_->GetItemCount(); ++i) { - ui::MenuModel::ItemType type = model_->GetTypeAt(i); - if (type == ui::MenuModel::TYPE_SEPARATOR) { - AddSeparatorAt(i); - } else if (type == ui::MenuModel::TYPE_RADIO) { - const int radio_group_id = model_->GetGroupIdAt(i); - std::map<int, GtkRadioMenuItem*>::const_iterator iter - = radio_groups_.find(radio_group_id); - if (iter == radio_groups_.end()) { - GtkWidget* new_menu_item = AddMenuItemAt(i, NULL, accel_group); - // |new_menu_item| is the first menu item for |radio_group_id| group. - radio_groups_.insert( - std::make_pair(radio_group_id, GTK_RADIO_MENU_ITEM(new_menu_item))); - } else { - AddMenuItemAt(i, iter->second, accel_group); - } - } else { - AddMenuItemAt(i, NULL, accel_group); - } - } - if (!menu_hidden_) - gtk_menu_reposition(GTK_MENU(menu_)); -} - -void NativeMenuGtk::UpdateStates() { - gtk_container_foreach(GTK_CONTAINER(menu_), &UpdateStateCallback, this); -} - -gfx::NativeMenu NativeMenuGtk::GetNativeMenu() const { - return menu_; -} - -NativeMenuGtk::MenuAction NativeMenuGtk::GetMenuAction() const { - return menu_action_; -} - -void NativeMenuGtk::AddMenuListener(MenuListener* listener) { - listeners_.AddObserver(listener); -} - -void NativeMenuGtk::RemoveMenuListener(MenuListener* listener) { - listeners_.RemoveObserver(listener); -} - -void NativeMenuGtk::SetMinimumWidth(int width) { - gtk_widget_set_size_request(menu_, width, -1); -} - -bool NativeMenuGtk::Dispatch(GdkEvent* event) { - if (menu_hidden_) { - // The menu has been closed but the message loop is still nested. Don't - // dispatch a message, otherwise we might spawn another message loop. - return false; // Exits the nested message loop. - } - switch (event->type) { - case GDK_BUTTON_PRESS: - case GDK_2BUTTON_PRESS: - case GDK_3BUTTON_PRESS: { - ignore_button_release_ = false; - gpointer data = NULL; - gdk_window_get_user_data(((GdkEventAny*)event)->window, &data); - GtkWidget* widget = reinterpret_cast<GtkWidget*>(data); - if (widget) { - GtkWidget* root = gtk_widget_get_toplevel(widget); - if (!g_object_get_data(G_OBJECT(root), kNativeMenuGtkString)) { - // The button event is not targeted at a menu, hide the menu and eat - // the event. If we didn't do this the button press is dispatched from - // the nested message loop and bad things can happen (like trying to - // spawn another menu. - gtk_menu_popdown(GTK_MENU(menu_)); - // In some cases we may not have gotten the hide event, but the menu - // will be in the process of hiding so set menu_hidden_ anyway. - menu_hidden_ = true; - return false; // Exits the nested message loop. - } - } - break; - } - case GDK_MOTION_NOTIFY: { - ignore_button_release_ = false; - break; - } - case GDK_BUTTON_RELEASE: { - if (ignore_button_release_) { - // Ignore if a release event happened without press event. - // Normally, release event is eaten by gtk when menu is opened - // in response to mouse press event. Since the renderer opens - // the context menu asyncrhonous after press event is handled, - // gtk sometimes does not eat it, which causes the menu to be - // closed. - return true; - } - break; - } - default: - break; - } - gtk_main_do_event(event); - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// NativeMenuGtk, private: - -void NativeMenuGtk::OnMenuHidden(GtkWidget* widget) { - if (menu_hidden_) { - // The menu has been already hidden by us and we're in the process of - // quiting the message loop.. - return; - } - // Quit the nested message loop we spawned in RunMenuAt. - MessageLoop::current()->Quit(); - - // Menu can be closed before the menu is shown. - if (expose_handler_id_) { - g_signal_handler_disconnect(menu_, expose_handler_id_); - expose_handler_id_ = 0; - } - - menu_hidden_ = true; -} - -void NativeMenuGtk::OnMenuMoveCurrent(GtkWidget* menu_widget, - GtkMenuDirectionType focus_direction) { - GtkWidget* parent = GTK_MENU_SHELL(menu_widget)->parent_menu_shell; - GtkWidget* menu_item = GTK_MENU_SHELL(menu_widget)->active_menu_item; - GtkWidget* submenu = NULL; - if (menu_item) { - submenu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(menu_item)); - } - if (focus_direction == GTK_MENU_DIR_CHILD && submenu == NULL) { - GetAncestor()->menu_action_ = MENU_ACTION_NEXT; - gtk_menu_popdown(GTK_MENU(menu_widget)); - } else if (focus_direction == GTK_MENU_DIR_PARENT && parent == NULL) { - GetAncestor()->menu_action_ = MENU_ACTION_PREVIOUS; - gtk_menu_popdown(GTK_MENU(menu_widget)); - } -} - -void NativeMenuGtk::AfterMenuMoveCurrent(GtkWidget* menu_widget, - GtkMenuDirectionType focus_direction) { - SendAccessibilityEvent(); -} - -gboolean NativeMenuGtk::OnExpose(GtkWidget* widget, GdkEventExpose* event) { - GtkWidget* popup_window = gtk_widget_get_ancestor(menu_, GTK_TYPE_WINDOW); - CHECK(popup_window); - DCHECK(expose_handler_id_); - NativeWidgetGtk::UpdateFreezeUpdatesProperty(GTK_WINDOW(popup_window), - false /* remove */); - if (expose_handler_id_) { - g_signal_handler_disconnect(menu_, expose_handler_id_); - expose_handler_id_ = 0; - } - return false; -} - -void NativeMenuGtk::AddSeparatorAt(int index) { - GtkWidget* separator = gtk_separator_menu_item_new(); - gtk_widget_show(separator); - gtk_menu_append(menu_, separator); -} - -GtkWidget* NativeMenuGtk::AddMenuItemAt(int index, - GtkRadioMenuItem* radio_group, - GtkAccelGroup* accel_group) { - GtkWidget* menu_item = NULL; - std::string label = gfx::ConvertAcceleratorsFromWindowsStyle(UTF16ToUTF8( - model_->GetLabelAt(index))); - - ui::MenuModel::ItemType type = model_->GetTypeAt(index); - switch (type) { - case ui::MenuModel::TYPE_CHECK: - menu_item = gtk_check_menu_item_new_with_mnemonic(label.c_str()); - break; - case ui::MenuModel::TYPE_RADIO: - if (radio_group) { - menu_item = gtk_radio_menu_item_new_with_mnemonic_from_widget( - radio_group, label.c_str()); - } else { - // The item does not belong to any existing radio button groups. - menu_item = gtk_radio_menu_item_new_with_mnemonic(NULL, label.c_str()); - } - break; - case ui::MenuModel::TYPE_SUBMENU: - case ui::MenuModel::TYPE_COMMAND: { - SkBitmap icon; - // Create menu item with icon if icon exists. - if (model_->HasIcons() && model_->GetIconAt(index, &icon)) { - menu_item = gtk_image_menu_item_new_with_mnemonic(label.c_str()); - GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap(&icon); - gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menu_item), - gtk_image_new_from_pixbuf(pixbuf)); - g_object_unref(pixbuf); - - // Show the image even if the "gtk-menu-images" setting is turned off. - gtk_image_menu_item_set_always_show_image( - GTK_IMAGE_MENU_ITEM(menu_item), TRUE); - } else { - menu_item = gtk_menu_item_new_with_mnemonic(label.c_str()); - } - break; - } - default: - NOTREACHED(); - break; - } - - // Label font. - const gfx::Font* font = model_->GetLabelFontAt(index); - if (font) { - // The label item is the first child of the menu item. - GtkWidget* label_widget = GTK_BIN(menu_item)->child; - DCHECK(label_widget && GTK_IS_LABEL(label_widget)); - PangoFontDescription* pfd = font->GetNativeFont(); - gtk_widget_modify_font(label_widget, pfd); - pango_font_description_free(pfd); - } - - if (type == ui::MenuModel::TYPE_SUBMENU) { - Menu2* submenu = new Menu2(model_->GetSubmenuModelAt(index)); - static_cast<NativeMenuGtk*>(submenu->wrapper_.get())->set_parent(this); - g_object_set_data(G_OBJECT(menu_item), "submenu", submenu); - gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item), - submenu->GetNativeMenu()); - g_signal_connect(submenu->GetNativeMenu(), "move-current", - G_CALLBACK(OnMenuMoveCurrentThunk), this); - } - - ui::Accelerator accelerator(ui::VKEY_UNKNOWN, false, false, false); - if (accel_group && model_->GetAcceleratorAt(index, &accelerator)) { - int gdk_modifiers = 0; - if (accelerator.IsShiftDown()) - gdk_modifiers |= GDK_SHIFT_MASK; - if (accelerator.IsCtrlDown()) - gdk_modifiers |= GDK_CONTROL_MASK; - if (accelerator.IsAltDown()) - gdk_modifiers |= GDK_MOD1_MASK; - gtk_widget_add_accelerator(menu_item, "activate", accel_group, - ui::GdkKeyCodeForWindowsKeyCode(accelerator.key_code(), false), - static_cast<GdkModifierType>(gdk_modifiers), GTK_ACCEL_VISIBLE); - } - - g_object_set_data(G_OBJECT(menu_item), kPositionString, - reinterpret_cast<void*>(index)); - g_signal_connect(menu_item, "activate", G_CALLBACK(CallActivate), this); - UpdateMenuItemState(menu_item, false); - gtk_widget_show(menu_item); - gtk_menu_append(menu_, menu_item); - - return menu_item; -} - -void NativeMenuGtk::ResetMenu() { - if (!menu_) { - menu_ = gtk_menu_new(); - g_object_set_data( - G_OBJECT(GTK_MENU(menu_)->toplevel), kNativeMenuGtkString, this); - destroy_handler_id_ = g_signal_connect( - menu_, "destroy", G_CALLBACK(NativeMenuGtk::MenuDestroyed), host_menu_); - } else { - gtk_container_foreach(GTK_CONTAINER(menu_), RemoveChildWidget, NULL); - } -} - -void NativeMenuGtk::UpdateMenuItemState(GtkWidget* menu_item, bool recurse) { - int index = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(menu_item), - kPositionString)); - - gtk_widget_set_sensitive(menu_item, model_->IsEnabledAt(index)); - if (GTK_IS_CHECK_MENU_ITEM(menu_item)) { - suppress_activate_signal_ = true; - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_item), - model_->IsItemCheckedAt(index)); - suppress_activate_signal_ = false; - } - - if (recurse && GTK_IS_MENU_ITEM(menu_item)) { - // Recurse into submenus. - if (gtk_menu_item_get_submenu(GTK_MENU_ITEM(menu_item))) { - Menu2* submenu = - reinterpret_cast<Menu2*>(g_object_get_data(G_OBJECT(menu_item), - "submenu")); - if (submenu) - submenu->UpdateStates(); - } - } -} - -// static -void NativeMenuGtk::UpdateStateCallback(GtkWidget* menu_item, gpointer data) { - NativeMenuGtk* menu = reinterpret_cast<NativeMenuGtk*>(data); - menu->UpdateMenuItemState(menu_item, true); -} - -// static -void NativeMenuGtk::MenuPositionFunc(GtkMenu* menu, - int* x, - int* y, - gboolean* push_in, - void* data) { - Position* position = reinterpret_cast<Position*>(data); - - GtkRequisition menu_req; - gtk_widget_size_request(GTK_WIDGET(menu), &menu_req); - - *x = position->point.x(); - *y = position->point.y(); - views::Menu2::Alignment alignment = position->alignment; - if (base::i18n::IsRTL()) { - switch (alignment) { - case Menu2::ALIGN_TOPRIGHT: - alignment = Menu2::ALIGN_TOPLEFT; - break; - case Menu2::ALIGN_TOPLEFT: - alignment = Menu2::ALIGN_TOPRIGHT; - break; - default: - NOTREACHED(); - break; - } - } - if (alignment == Menu2::ALIGN_TOPRIGHT) - *x -= menu_req.width; - - // Make sure the popup fits on screen. - GdkScreen* screen = gtk_widget_get_screen(GTK_WIDGET(menu)); - *x = std::max(0, std::min(gdk_screen_get_width(screen) - menu_req.width, *x)); - *y = std::max(0, std::min(gdk_screen_get_height(screen) - menu_req.height, - *y)); - - *push_in = FALSE; -} - -void NativeMenuGtk::OnActivate(GtkMenuItem* menu_item) { - if (suppress_activate_signal_) - return; - int position = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(menu_item), - kPositionString)); - // Ignore the signal if it's sent to an inactive checked radio item. - // - // Suppose there are three radio items A, B, C, and A is now being - // checked. If you click C, "activate" signal will be sent to A and C. - // Here, we ignore the signal sent to A. - if (GTK_IS_RADIO_MENU_ITEM(menu_item) && - !gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_item))) { - return; - } - - // NOTE: we get activate messages for submenus when first shown. - if (model_->IsEnabledAt(position) && - MenuTypeCanExecute(model_->GetTypeAt(position))) { - NativeMenuGtk* ancestor = GetAncestor(); - ancestor->activated_menu_ = this; - activated_index_ = position; - ancestor->menu_action_ = MENU_ACTION_SELECTED; - } -} - -// static -void NativeMenuGtk::CallActivate(GtkMenuItem* menu_item, - NativeMenuGtk* native_menu) { - native_menu->OnActivate(menu_item); -} - -NativeMenuGtk* NativeMenuGtk::GetAncestor() { - NativeMenuGtk* ancestor = this; - while (ancestor->parent_) - ancestor = ancestor->parent_; - return ancestor; -} - -void NativeMenuGtk::ProcessActivate() { - if (activated_menu_) - activated_menu_->Activate(); -} - -void NativeMenuGtk::Activate() { - if (model_->IsEnabledAt(activated_index_) && - MenuTypeCanExecute(model_->GetTypeAt(activated_index_))) { - model_->ActivatedAt(activated_index_); - } -} - -void NativeMenuGtk::SendAccessibilityEvent() { - // Find the focused menu item, recursing into submenus as needed. - GtkWidget* menu = menu_; - GtkWidget* menu_item = GTK_MENU_SHELL(menu_)->active_menu_item; - if (!menu_item) - return; - GtkWidget* submenu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(menu_item)); - while (submenu && GTK_MENU_SHELL(submenu)->active_menu_item) { - menu = submenu; - menu_item = GTK_MENU_SHELL(menu)->active_menu_item; - if (!menu_item) - return; - submenu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(menu_item)); - } - - // Figure out the item index and total number of items. - GList* items = gtk_container_get_children(GTK_CONTAINER(menu)); - guint count = g_list_length(items); - int index = g_list_index(items, static_cast<gconstpointer>(menu_item)); - - // Get the menu item's label. - std::string name; - name = gtk_menu_item_get_label(GTK_MENU_ITEM(menu_item)); - - if (ViewsDelegate::views_delegate) { - ViewsDelegate::views_delegate->NotifyMenuItemFocused(string16(), - UTF8ToUTF16(name), - index, - count, - submenu != NULL); - } -} - -// static -void NativeMenuGtk::MenuDestroyed(GtkWidget* widget, Menu2* menu2) { - NativeMenuGtk* native_menu = - static_cast<NativeMenuGtk*>(menu2->wrapper_.get()); - // The native gtk widget has already been destroyed. - native_menu->menu_ = NULL; - delete menu2; -} - -//////////////////////////////////////////////////////////////////////////////// -// MenuWrapper, public: - -// static -MenuWrapper* MenuWrapper::CreateWrapper(Menu2* menu) { - return new NativeMenuGtk(menu); -} - -} // namespace views diff --git a/ui/views/controls/menu/native_menu_gtk.h b/ui/views/controls/menu/native_menu_gtk.h deleted file mode 100644 index debc254..0000000 --- a/ui/views/controls/menu/native_menu_gtk.h +++ /dev/null @@ -1,162 +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_VIEWS_CONTROLS_MENU_NATIVE_MENU_GTK_H_ -#define UI_VIEWS_CONTROLS_MENU_NATIVE_MENU_GTK_H_ -#pragma once - -#include <gtk/gtk.h> - -#include "base/basictypes.h" -#include "base/compiler_specific.h" -#include "base/memory/weak_ptr.h" -#include "base/message_loop.h" -#include "base/observer_list.h" -#include "ui/base/gtk/gtk_signal.h" -#include "ui/views/controls/menu/menu_wrapper.h" - -namespace ui { -class MenuModel; -} - -namespace views { - -class NestedDispatcherGtk; - -// A Gtk implementation of MenuWrapper. -// -// NOTE: On windows the activate message is not sent immediately when an item -// is selected. Instead a message is added to the queue that is processed later. -// To simulate that (and avoid having to deal with different behavior between -// the platforms) we mimick that by posting a task after a menu item is selected -// then notify. -// -// TODO(beng): rename to MenuGtk once the old class is dead. -class NativeMenuGtk : public MenuWrapper, - public MessageLoopForUI::Dispatcher { - public: - explicit NativeMenuGtk(Menu2* menu); - virtual ~NativeMenuGtk(); - - // Overridden from MenuWrapper: - virtual void RunMenuAt(const gfx::Point& point, int alignment) OVERRIDE; - virtual void CancelMenu() OVERRIDE; - virtual void Rebuild() OVERRIDE; - virtual void UpdateStates() OVERRIDE; - virtual gfx::NativeMenu GetNativeMenu() const OVERRIDE; - virtual MenuAction GetMenuAction() const OVERRIDE; - virtual void AddMenuListener(MenuListener* listener) OVERRIDE; - virtual void RemoveMenuListener(MenuListener* listener) OVERRIDE; - virtual void SetMinimumWidth(int width) OVERRIDE; - - // Overriden from MessageLoopForUI::Dispatcher: - virtual bool Dispatch(GdkEvent* event) OVERRIDE; - - private: - CHROMEGTK_CALLBACK_0(NativeMenuGtk, void, OnMenuHidden); - CHROMEGTK_CALLBACK_1(NativeMenuGtk, void, OnMenuMoveCurrent, - GtkMenuDirectionType); - CHROMEGTK_CALLBACK_1(NativeMenuGtk, void, AfterMenuMoveCurrent, - GtkMenuDirectionType); - CHROMEGTK_CALLBACK_1(NativeMenuGtk, gboolean, OnExpose, GdkEventExpose*); - - void AddSeparatorAt(int index); - GtkWidget* AddMenuItemAt(int index, GtkRadioMenuItem* radio_group, - GtkAccelGroup* accel_group); - - void ResetMenu(); - - // Updates the menu item's state. - void UpdateMenuItemState(GtkWidget* menu_item, bool recurse); - - static void UpdateStateCallback(GtkWidget* menu_item, gpointer data); - - // Callback for gtk_menu_popup to position the menu. - static void MenuPositionFunc(GtkMenu* menu, int* x, int* y, gboolean* push_in, - void* data); - - // Event handlers: - void OnActivate(GtkMenuItem* menu_item); - - // Gtk signal handlers. - static void CallActivate(GtkMenuItem* menu_item, NativeMenuGtk* native_menu); - - // Sets the parent of this menu. - void set_parent(NativeMenuGtk* parent) { parent_ = parent; } - - // Returns the root of the menu tree. - NativeMenuGtk* GetAncestor(); - - // Callback that we should really process the menu activation. - // See description above class for why we delay processing activation. - void ProcessActivate(); - - // Notifies the model the user selected an item. - void Activate(); - - void SendAccessibilityEvent(); - - // A callback to delete menu2 object when the native widget is - // destroyed first. - static void MenuDestroyed(GtkWidget* widget, Menu2* menu2); - - // If we're a submenu, this is the parent. - NativeMenuGtk* parent_; - - ui::MenuModel* model_; - - GtkWidget* menu_; - - // Has the menu been hidden? - // NOTE: this is maintained by us and do to the asynchronous nature of X may - // be out of sync with whether the window is actually hidden. None-the-less if - // true the menu is either truly hidden or in the process of hiding. - bool menu_hidden_; - - // A flag used to avoid misfiring ActivateAt call on the menu model. - // This is necessary as GTK menu fires an activate signal even when the - // state is changed by |UpdateStates()| API. - bool suppress_activate_signal_; - - // If the user selects something from the menu this is the menu they selected - // it from. When an item is selected menu_activated_ on the root ancestor is - // set to the menu the user selected and after the nested message loop exits - // Activate is invoked on this menu. - NativeMenuGtk* activated_menu_; - - // The index of the item the user selected. This is set on the actual menu the - // user selects and not the root. - int activated_index_; - - // Used when a menu item is selected. See description above class as to why - // we do this. - base::WeakPtrFactory<NativeMenuGtk> activate_factory_; - - // A eference to the hosting menu2 object and signal handler id - // used to delete the menu2 when its native menu gtk is destroyed first. - Menu2* host_menu_; - gulong destroy_handler_id_; - gulong expose_handler_id_; - - // The action that took place during the call to RunMenuAt. - MenuAction menu_action_; - - // A list of listeners to call when the menu opens. - ObserverList<MenuListener> listeners_; - - // Nested dispatcher object that can outlive this object. - // This is to deal with the menu being deleted while the nested - // message loop is handled. see http://crosbug.com/7228 . - NestedDispatcherGtk* nested_dispatcher_; - - // A flag used to detect a button release event without button press or move. - // see http://crosbug.com/8718. - bool ignore_button_release_; - - DISALLOW_COPY_AND_ASSIGN(NativeMenuGtk); -}; - -} // namespace views - -#endif // UI_VIEWS_CONTROLS_MENU_NATIVE_MENU_GTK_H_ diff --git a/ui/views/controls/menu/nested_dispatcher_gtk.cc b/ui/views/controls/menu/nested_dispatcher_gtk.cc deleted file mode 100644 index d83b9cc..0000000 --- a/ui/views/controls/menu/nested_dispatcher_gtk.cc +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/controls/menu/nested_dispatcher_gtk.h" - -namespace views { - -NestedDispatcherGtk::NestedDispatcherGtk(MessageLoopForUI::Dispatcher* creator, - bool allow_nested_task) - : creator_(creator), - allow_nested_task_(allow_nested_task) { -} - -bool NestedDispatcherGtk::RunAndSelfDestruct() { - bool nestable = MessageLoopForUI::current()->NestableTasksAllowed(); - if (allow_nested_task_) - MessageLoopForUI::current()->SetNestableTasksAllowed(true); - MessageLoopForUI::current()->RunWithDispatcher(this); - if (allow_nested_task_) - MessageLoopForUI::current()->SetNestableTasksAllowed(nestable); - bool creator_is_deleted = creator_ == NULL; - delete this; - return creator_is_deleted; -} - -void NestedDispatcherGtk::CreatorDestroyed() { - creator_ = NULL; -} - -bool NestedDispatcherGtk::Dispatch(GdkEvent* event) { - return creator_ && creator_->Dispatch(event); -} - -} // namespace views diff --git a/ui/views/controls/menu/nested_dispatcher_gtk.h b/ui/views/controls/menu/nested_dispatcher_gtk.h deleted file mode 100644 index dc02f36..0000000 --- a/ui/views/controls/menu/nested_dispatcher_gtk.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 UI_VIEWS_CONTROLS_MENU_NESTED_DISPATCHER_GTK_H_ -#define UI_VIEWS_CONTROLS_MENU_NESTED_DISPATCHER_GTK_H_ -#pragma once - -#include "base/compiler_specific.h" -#include "base/message_loop.h" - -namespace views { - -// A nested dispatcher that can out-live the creator of this -// dispatcher. This is to deal with the scenario where a menu object -// is deleted while it's handling the message loop. Note that -// |RunAndSelfDestruct| method always delete itself regardless of -// whether or not the menu object is deleted, so a menu object should -// create a new instance for each open request. -// http://crosbug.com/7228, http://crosbug.com/7929 -class NestedDispatcherGtk : public MessageLoopForUI::Dispatcher { - public: - NestedDispatcherGtk(MessageLoopForUI::Dispatcher* creator, - bool allow_nested_task); - - // Run the messsage loop and returns if the menu has been - // deleted in the nested loop. Returns true if the menu is - // deleted, or false otherwise. - bool RunAndSelfDestruct(); - - // Tells the nested dispatcher that creator has been destroyed. - void CreatorDestroyed(); - - private: - virtual ~NestedDispatcherGtk() {} - - // Overriden from MessageLoopForUI::Dispatcher: - virtual bool Dispatch(GdkEvent* event) OVERRIDE; - - // Creator of the nested loop. - MessageLoopForUI::Dispatcher* creator_; - - // True to allow nested task in the message loop. - bool allow_nested_task_; - - DISALLOW_COPY_AND_ASSIGN(NestedDispatcherGtk); -}; - -} // namespace views - -#endif // UI_VIEWS_CONTROLS_MENU_NESTED_DISPATCHER_GTK_H_ diff --git a/ui/views/controls/native/native_view_host_gtk.cc b/ui/views/controls/native/native_view_host_gtk.cc deleted file mode 100644 index baeed237..0000000 --- a/ui/views/controls/native/native_view_host_gtk.cc +++ /dev/null @@ -1,412 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/controls/native/native_view_host_gtk.h" - -#include <gtk/gtk.h> - -#include <algorithm> - -#include "base/logging.h" -#include "ui/views/controls/native/native_view_host.h" -#include "ui/views/focus/focus_manager.h" -#include "ui/views/views_delegate.h" -#include "ui/views/widget/gtk_views_fixed.h" -#include "ui/views/widget/native_widget_gtk.h" -#include "ui/views/widget/widget.h" - -namespace views { - -namespace { -static bool signal_id_initialized_ = false; -static guint focus_in_event_signal_id_; -static guint focus_out_event_signal_id_; - -//////////////////////////////////////////////////////////////////////////////// -// Utility functions to block focus signals while re-creating -// Fixed widget. - -void InitSignalIds() { - if (!signal_id_initialized_) { - signal_id_initialized_ = true; - focus_in_event_signal_id_ = - g_signal_lookup("focus-in-event", GTK_TYPE_WIDGET); - focus_out_event_signal_id_ = - g_signal_lookup("focus-out-event", GTK_TYPE_WIDGET); - } -} - -// Blocks a |signal_id| on the given |widget| if any. -void BlockSignal(GtkWidget* widget, guint signal_id) { - gulong handler_id = g_signal_handler_find(G_OBJECT(widget), - G_SIGNAL_MATCH_ID, - signal_id, - 0, NULL, NULL, NULL); - if (handler_id) { - g_signal_handler_block(G_OBJECT(widget), handler_id); - } -} - -// Unblocks a |signal_id| on the given |widget| if any. -void UnblockSignal(GtkWidget* widget, guint signal_id) { - gulong handler_id = g_signal_handler_find(G_OBJECT(widget), - G_SIGNAL_MATCH_ID, - signal_id, - 0, NULL, NULL, NULL); - if (handler_id) { - g_signal_handler_unblock(G_OBJECT(widget), handler_id); - } -} - -// Blocks focus in/out signals of the widget and its descendent -// children. -// Note: Due to the limiation of Gtk API, this only blocks the 1st -// handler found and won't block the rest if there is more than one handlers. -// See bug http://crbug.com/33236. -void BlockFocusSignals(GtkWidget* widget, gpointer data) { - if (!widget) - return; - InitSignalIds(); - BlockSignal(widget, focus_in_event_signal_id_); - BlockSignal(widget, focus_out_event_signal_id_); - if (GTK_IS_CONTAINER(widget)) - gtk_container_foreach(GTK_CONTAINER(widget), BlockFocusSignals, data); -} - -// Unlocks focus in/out signals of the widget and its descendent children. -void UnblockFocusSignals(GtkWidget* widget, gpointer data) { - if (!widget) - return; - InitSignalIds(); - UnblockSignal(widget, focus_in_event_signal_id_); - UnblockSignal(widget, focus_out_event_signal_id_); - if (GTK_IS_CONTAINER(widget)) - gtk_container_foreach(GTK_CONTAINER(widget), UnblockFocusSignals, data); -} - -// Removes |child| from |parent|. -void RemoveFromParent(GtkWidget* child, gpointer parent) { - gtk_container_remove(GTK_CONTAINER(parent), child); -} - -// Reparents |child| to be a child of |parent|. -void Reparent(GtkWidget* child, gpointer parent) { - gtk_widget_reparent(child, GTK_WIDGET(parent)); -} - -} // namespace - -//////////////////////////////////////////////////////////////////////////////// -// NativeViewHostGtk, public: - -NativeViewHostGtk::NativeViewHostGtk(NativeViewHost* host) - : host_(host), - installed_clip_(false), - destroy_signal_id_(0), - focus_signal_id_(0), - fixed_(NULL) { - CreateFixed(false); -} - -NativeViewHostGtk::~NativeViewHostGtk() { - if (fixed_) { - gtk_container_foreach(GTK_CONTAINER(fixed_), RemoveFromParent, fixed_); - gtk_widget_destroy(fixed_); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// NativeViewHostGtk, NativeViewHostWrapper implementation: - -void NativeViewHostGtk::NativeViewAttached() { - AttachHostWidget(); - - GtkWidget* host_widget = host_->native_view(); - - // Let the widget know that the native component has been painted. - views::NativeWidgetGtk::RegisterChildExposeHandler(host_widget); - - if (!destroy_signal_id_) { - destroy_signal_id_ = g_signal_connect(host_widget, - "destroy", G_CALLBACK(CallDestroy), - this); - } - - if (!focus_signal_id_) { - focus_signal_id_ = g_signal_connect(host_widget, - "focus-in-event", - G_CALLBACK(CallFocusIn), this); - } - - // Always layout though. - host_->Layout(); - - // TODO(port): figure out focus. -} - -void NativeViewHostGtk::NativeViewDetaching(bool destroyed) { - GtkWidget* host_widget = host_->native_view(); - DCHECK(host_widget); - - views::NativeWidgetGtk::UnregisterChildExposeHandler(host_widget); - - g_signal_handler_disconnect(G_OBJECT(host_widget), destroy_signal_id_); - destroy_signal_id_ = 0; - - g_signal_handler_disconnect(G_OBJECT(host_widget), focus_signal_id_); - focus_signal_id_ = 0; - - installed_clip_ = false; -} - -void NativeViewHostGtk::AddedToWidget() { - if (!fixed_) - CreateFixed(false); - if (gtk_widget_get_parent(fixed_)) - GetHostWidget()->ReparentChild(fixed_); - else - GetHostWidget()->AddChild(fixed_); - - if (!host_->native_view()) - return; - - AttachHostWidget(); - - if (host_->IsDrawn()) { - gtk_widget_show(host_->native_view()); - gtk_widget_show(fixed_); - } else { - gtk_widget_hide(fixed_); - } - host_->Layout(); -} - -void NativeViewHostGtk::RemovedFromWidget() { - if (!host_->native_view()) - return; - DestroyFixed(); -} - -void NativeViewHostGtk::InstallClip(int x, int y, int w, int h) { - DCHECK(w > 0 && h > 0); - installed_clip_bounds_.SetRect(x, y, w, h); - if (!installed_clip_) { - installed_clip_ = true; - - // We only re-create the fixed with a window when a cliprect is installed. - // Because the presence of a X Window will prevent transparency from working - // properly, we only want it to be active for the duration of a clip - // (typically during animations and scrolling.) - CreateFixed(true); - } -} - -bool NativeViewHostGtk::HasInstalledClip() { - return installed_clip_; -} - -void NativeViewHostGtk::UninstallClip() { - installed_clip_ = false; - // We now re-create the fixed without a X Window so transparency works again. - CreateFixed(false); -} - -void NativeViewHostGtk::ShowWidget(int x, int y, int w, int h) { - // x and y are the desired position of host_ in NativeWidgetGtk coordinates. - int fixed_x = x; - int fixed_y = y; - int fixed_w = w; - int fixed_h = h; - int child_x = 0; - int child_y = 0; - int child_w = w; - int child_h = h; - if (installed_clip_) { - child_x = -installed_clip_bounds_.x(); - child_y = -installed_clip_bounds_.y(); - fixed_x += -child_x; - fixed_y += -child_y; - fixed_w = std::min(installed_clip_bounds_.width(), w); - fixed_h = std::min(installed_clip_bounds_.height(), h); - } - - GtkWidget* host_widget = host_->native_view(); - // Don't call gtk_widget_size_allocate now, as we're possibly in the - // middle of a re-size, and it kicks off another re-size, and you - // get flashing. Instead, we'll set the desired size as properties - // on the widget and queue the re-size. - gtk_views_fixed_set_widget_size(host_widget, child_w, child_h); - gtk_fixed_move(GTK_FIXED(fixed_), host_widget, child_x, child_y); - - // Size and place the fixed_. - GetHostWidget()->PositionChild(fixed_, fixed_x, fixed_y, fixed_w, fixed_h); - - gtk_widget_show(host_widget); - gtk_widget_show(fixed_); -} - -void NativeViewHostGtk::HideWidget() { - if (fixed_) - gtk_widget_hide(fixed_); -} - -void NativeViewHostGtk::SetFocus() { - GtkWidget* host_widget = host_->native_view(); - DCHECK(host_widget); - gtk_widget_grab_focus(host_widget); -} - -gfx::NativeViewAccessible NativeViewHostGtk::GetNativeViewAccessible() { - return NULL; -} - -//////////////////////////////////////////////////////////////////////////////// -// NativeViewHostGtk, private: - -void NativeViewHostGtk::CreateFixed(bool needs_window) { - GtkWidget* focused_widget = GetFocusedDescendant(); - - bool focus_event_blocked = false; - // We move focus around and do not want focus events to be emitted - // during this process. - if (fixed_) { - BlockFocusSignals(GetHostWidget()->GetNativeView(), NULL); - focus_event_blocked = true; - } - - if (focused_widget) { - // A descendant of our fixed has focus. When we destroy the fixed focus is - // automatically moved. Temporarily move focus to our host widget, then - // restore focus after we create the new fixed_. This way focus hasn't - // really moved. - gtk_widget_grab_focus(GetHostWidget()->GetNativeView()); - } - - // Move all the contained widgets to the new fixed. - GtkWidget* new_fixed = gtk_views_fixed_new(); - if (fixed_) { - gtk_container_foreach(GTK_CONTAINER(fixed_), Reparent, new_fixed); - DestroyFixed(); - } - fixed_ = new_fixed; - - gtk_widget_set_name(fixed_, "views-native-view-host-fixed"); - gtk_fixed_set_has_window(GTK_FIXED(fixed_), needs_window); - - // Defeat refcounting. We need to own the fixed. - gtk_widget_ref(fixed_); - - NativeWidgetGtk* widget_gtk = GetHostWidget(); - if (widget_gtk) { - widget_gtk->AddChild(fixed_); - // Clear the background so we don't get flicker. - gtk_widget_realize(fixed_); - gdk_window_set_back_pixmap(fixed_->window, NULL, false); - } - - if (host_->native_view()) - AttachHostWidget(); - - if (widget_gtk && host_->native_view() && focused_widget) - gtk_widget_grab_focus(focused_widget); - - if (focus_event_blocked) { - // Unblocking a signal handler that is not blocked fails. - // Unblock only when it's unblocked. - UnblockFocusSignals(GetHostWidget()->GetNativeView(), NULL); - } -} - -void NativeViewHostGtk::DestroyFixed() { - if (!fixed_) - return; - - gtk_widget_hide(fixed_); - gtk_container_foreach(GTK_CONTAINER(fixed_), RemoveFromParent, fixed_); - GetHostWidget()->RemoveChild(fixed_); - - // fixed_ should not have any children this point. - DCHECK_EQ(0U, - g_list_length(gtk_container_get_children(GTK_CONTAINER(fixed_)))); - gtk_widget_destroy(fixed_); - fixed_ = NULL; -} - -NativeWidgetGtk* NativeViewHostGtk::GetHostWidget() const { - return static_cast<NativeWidgetGtk*>(host_->GetWidget()->native_widget()); -} - -GtkWidget* NativeViewHostGtk::GetFocusedDescendant() { - if (!fixed_) - return NULL; - NativeWidgetGtk* host = GetHostWidget(); - if (!host) - return NULL; - GtkWidget* top_level = gtk_widget_get_toplevel(host->GetNativeView()); - if (!top_level || !GTK_IS_WINDOW(top_level)) - return NULL; - GtkWidget* focused = gtk_window_get_focus(GTK_WINDOW(top_level)); - if (!focused) - return NULL; - return (focused == fixed_ || gtk_widget_is_ancestor(focused, fixed_)) ? - focused : NULL; -} - -void NativeViewHostGtk::AttachHostWidget() { - GtkWidget* host_widget = host_->native_view(); - DCHECK(host_widget); - - GtkWidget* host_parent = gtk_widget_get_parent(host_widget); - bool parent_changed = true; - if (host_parent) { - if (host_parent != fixed_) - gtk_widget_reparent(host_widget, fixed_); - else - parent_changed = false; - } else { - gtk_container_add(GTK_CONTAINER(fixed_), host_widget); - } - - if (parent_changed) { - // We need to clear the background so we don't get flicker on tab switching. - // To do that we must realize the widget if it's not already. - if (!GTK_WIDGET_REALIZED(host_widget)) - gtk_widget_realize(host_widget); - gdk_window_set_back_pixmap(host_widget->window, NULL, false); - } -} - -// static -void NativeViewHostGtk::CallDestroy(GtkObject* object, - NativeViewHostGtk* host) { - host->host_->NativeViewDestroyed(); -} - -// static -gboolean NativeViewHostGtk::CallFocusIn(GtkWidget* gtk_widget, - GdkEventFocus* event, - NativeViewHostGtk* host) { - Widget* widget = Widget::GetWidgetForNativeView(gtk_widget); - FocusManager* focus_manager = widget ? widget->GetFocusManager() : NULL; - if (!focus_manager) { - // TODO(jcampan): http://crbug.com/21378 Reenable this NOTREACHED() when the - // options page is only based on views. - // NOTREACHED(); - NOTIMPLEMENTED(); - return false; - } - focus_manager->SetFocusedView(host->host_->focus_view()); - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// NativeViewHostWrapper, public: - -// static -NativeViewHostWrapper* NativeViewHostWrapper::CreateWrapper( - NativeViewHost* host) { - return new NativeViewHostGtk(host); -} - -} // namespace views diff --git a/ui/views/controls/native/native_view_host_gtk.h b/ui/views/controls/native/native_view_host_gtk.h deleted file mode 100644 index 1d1c051..0000000 --- a/ui/views/controls/native/native_view_host_gtk.h +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_VIEWS_CONTROLS_NATIVE_NATIVE_VIEW_HOST_GTK_H_ -#define UI_VIEWS_CONTROLS_NATIVE_NATIVE_VIEW_HOST_GTK_H_ -#pragma once - -#include <gtk/gtk.h> -#include <string> - -#include "base/basictypes.h" -#include "base/compiler_specific.h" -#include "ui/gfx/rect.h" -#include "ui/views/controls/native/native_view_host_wrapper.h" - -namespace views { - -class View; -class NativeWidgetGtk; - -// Note that the NativeViewHostGtk assumes ownership of the GtkWidget attached -// to it for the duration of its attachment. This is so the NativeViewHostGtk -// can safely reparent the GtkWidget in multiple passes without having to worry -// about the GtkWidget's refcnt falling to 0. -class NativeViewHostGtk : public NativeViewHostWrapper { - public: - explicit NativeViewHostGtk(NativeViewHost* host); - virtual ~NativeViewHostGtk(); - - // Overridden from NativeViewHostWrapper: - virtual void NativeViewAttached() OVERRIDE; - virtual void NativeViewDetaching(bool destroyed) OVERRIDE; - virtual void AddedToWidget() OVERRIDE; - virtual void RemovedFromWidget() OVERRIDE; - virtual void InstallClip(int x, int y, int w, int h) OVERRIDE; - virtual bool HasInstalledClip() OVERRIDE; - virtual void UninstallClip() OVERRIDE; - virtual void ShowWidget(int x, int y, int w, int h) OVERRIDE; - virtual void HideWidget() OVERRIDE; - virtual void SetFocus() OVERRIDE; - virtual gfx::NativeViewAccessible GetNativeViewAccessible() OVERRIDE; - - private: - // Create and Destroy the GtkFixed that performs clipping on our hosted - // GtkWidget. |needs_window| is true when a clip is installed and implies the - // fixed is backed by a X Window which actually performs the clipping. - // It's kind of retarded that Gtk/Cairo doesn't clip painting of child windows - // regardless of whether or not there's an X Window. It's not that hard. - void CreateFixed(bool needs_window); - - // Destroys the GtkFixed that performs clipping on our hosted GtkWidget. - void DestroyFixed(); - - NativeWidgetGtk* GetHostWidget() const; - - // Returns the descendant of fixed_ that has focus, or NULL if focus is not - // on a descendant of fixed_. - GtkWidget* GetFocusedDescendant(); - - // Connects a new host widget. - void AttachHostWidget(); - - // Invoked from the 'destroy' signal. - static void CallDestroy(GtkObject* object, NativeViewHostGtk* host); - - // Invoked from the 'focus-in-event' signal. - static gboolean CallFocusIn(GtkWidget* gtk_widget, - GdkEventFocus* event, - NativeViewHostGtk* button); - - // Our associated NativeViewHost. - NativeViewHost* host_; - - // Have we installed a region on the gfx::NativeView used to clip to only the - // visible portion of the gfx::NativeView ? - bool installed_clip_; - - // The installed clip rect. InstallClip doesn't actually perform the clipping, - // a call to ShowWidget will. - gfx::Rect installed_clip_bounds_; - - // Signal handle id for 'destroy' signal. - gulong destroy_signal_id_; - - // Signal handle id for 'focus-in-event' signal. - gulong focus_signal_id_; - - // The GtkFixed that contains the attached gfx::NativeView (used for - // clipping). - GtkWidget* fixed_; - - DISALLOW_COPY_AND_ASSIGN(NativeViewHostGtk); -}; - -} // namespace views - -#endif // UI_VIEWS_CONTROLS_NATIVE_NATIVE_VIEW_HOST_GTK_H_ diff --git a/ui/views/controls/native_control_gtk.cc b/ui/views/controls/native_control_gtk.cc deleted file mode 100644 index 140f96d..0000000 --- a/ui/views/controls/native_control_gtk.cc +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/controls/native_control_gtk.h" - -#include <gtk/gtk.h> - -#include "base/logging.h" -#include "ui/base/accessibility/accessibility_types.h" -#include "ui/views/focus/focus_manager.h" -#include "ui/views/widget/widget.h" - -namespace views { - -NativeControlGtk::NativeControlGtk() { -} - -NativeControlGtk::~NativeControlGtk() { - if (native_view()) - gtk_widget_destroy(native_view()); -} - -//////////////////////////////////////////////////////////////////////////////// -// NativeControlGtk, View overrides: - -void NativeControlGtk::OnEnabledChanged() { - View::OnEnabledChanged(); - if (native_view()) - gtk_widget_set_sensitive(native_view(), enabled()); -} - -void NativeControlGtk::ViewHierarchyChanged(bool is_add, View* parent, - View* child) { - // Call the base class to hide the view if we're being removed. - NativeViewHost::ViewHierarchyChanged(is_add, parent, child); - - if (!is_add && child == this && native_view()) { - Detach(); - } else if (is_add && GetWidget() && !native_view()) { - // Create the widget when we're added to a valid Widget. Many - // controls need a parent widget to function properly. - CreateNativeControl(); - } -} - -void NativeControlGtk::VisibilityChanged(View* starting_from, bool is_visible) { - if (!native_view()) { - if (GetWidget()) - CreateNativeControl(); - } else { - // The view becomes visible after native control is created. - // Layout now. - Layout(); - } -} - -void NativeControlGtk::OnFocus() { - DCHECK(native_view()); - gtk_widget_grab_focus(native_view()); - GetWidget()->NotifyAccessibilityEvent( - parent(), ui::AccessibilityTypes::EVENT_FOCUS, true); -} - -void NativeControlGtk::NativeControlCreated(GtkWidget* native_control) { - Attach(native_control); - - // Update the newly created GtkWidget with any resident enabled state. - gtk_widget_set_sensitive(native_view(), enabled()); - - // Listen for focus change event to update the FocusManager focused view. - g_signal_connect(native_control, "focus-in-event", - G_CALLBACK(CallFocusIn), this); -} - -// static -gboolean NativeControlGtk::CallFocusIn(GtkWidget* gtk_widget, - GdkEventFocus* event, - NativeControlGtk* control) { - Widget* widget = Widget::GetTopLevelWidgetForNativeView(gtk_widget); - FocusManager* focus_manager = widget ? widget->GetFocusManager() : NULL; - if (!focus_manager) { - // TODO(jcampan): http://crbug.com/21378 Reenable this NOTREACHED() when the - // options page is only based on views. - // NOTREACHED(); - NOTIMPLEMENTED(); - return false; - } - focus_manager->SetFocusedView(control->focus_view()); - return false; -} - -} // namespace views diff --git a/ui/views/controls/native_control_gtk.h b/ui/views/controls/native_control_gtk.h deleted file mode 100644 index a72c943..0000000 --- a/ui/views/controls/native_control_gtk.h +++ /dev/null @@ -1,52 +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_VIEWS_CONTROLS_NATIVE_CONTROL_GTK_H_ -#define UI_VIEWS_CONTROLS_NATIVE_CONTROL_GTK_H_ -#pragma once - -#include <gtk/gtk.h> - -#include "base/compiler_specific.h" -#include "ui/views/controls/native/native_view_host.h" - -namespace views { - -// A View that hosts a native control. -class NativeControlGtk : public NativeViewHost { - public: - NativeControlGtk(); - virtual ~NativeControlGtk(); - - // Overridden from View: - virtual void OnEnabledChanged() OVERRIDE; - - protected: - virtual void ViewHierarchyChanged(bool is_add, - View *parent, - View *child) OVERRIDE; - virtual void VisibilityChanged(View* starting_from, bool is_visible) OVERRIDE; - virtual void OnFocus() OVERRIDE; - - // Called when the NativeControlGtk is attached to a View hierarchy with a - // valid Widget. The NativeControlGtk should use this opportunity to create - // its associated GtkWidget. - virtual void CreateNativeControl() = 0; - - // MUST be called by the subclass implementation of |CreateNativeControl| - // immediately after creating the control GtkWidget, otherwise it won't be - // attached to the GtkView and will be effectively orphaned. - virtual void NativeControlCreated(GtkWidget* widget); - - private: - static gboolean CallFocusIn(GtkWidget* gtk_widget, - GdkEventFocus* event, - NativeControlGtk* button); - - DISALLOW_COPY_AND_ASSIGN(NativeControlGtk); -}; - -} // namespace views - -#endif // UI_VIEWS_CONTROLS_NATIVE_CONTROL_GTK_H_ diff --git a/ui/views/controls/scrollbar/native_scroll_bar_gtk.cc b/ui/views/controls/scrollbar/native_scroll_bar_gtk.cc deleted file mode 100644 index b6d11e3..0000000 --- a/ui/views/controls/scrollbar/native_scroll_bar_gtk.cc +++ /dev/null @@ -1,220 +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/views/controls/scrollbar/native_scroll_bar_gtk.h" - -#include <gtk/gtk.h> - -#include "ui/base/keycodes/keyboard_codes_posix.h" -#include "ui/views/controls/scrollbar/native_scroll_bar.h" -#include "ui/views/controls/scrollbar/native_scroll_bar_views.h" -#include "ui/views/controls/scrollbar/scroll_bar.h" -#include "ui/views/widget/widget.h" - -namespace views { - -//////////////////////////////////////////////////////////////////////////////// -// NativeScrollBarGtk, public: - -NativeScrollBarGtk::NativeScrollBarGtk(NativeScrollBar* scroll_bar) - : NativeControlGtk(), - native_scroll_bar_(scroll_bar) { - set_focus_view(scroll_bar); -} - -NativeScrollBarGtk::~NativeScrollBarGtk() { -} - -//////////////////////////////////////////////////////////////////////////////// -// NativeScrollBarGtk, View overrides: - -void NativeScrollBarGtk::Layout() { - NativeControlGtk::Layout(); -} - -gfx::Size NativeScrollBarGtk::GetPreferredSize() { - if (native_scroll_bar_->IsHorizontal()) - return gfx::Size(0, GetHorizontalScrollBarHeight()); - return gfx::Size(GetVerticalScrollBarWidth(), 0); -} - -// TODO(oshima|jcampan): key/mouse events are not delievered and -// the following code is not tested. It requires the focus manager to be fully -// implemented. -bool NativeScrollBarGtk::OnKeyPressed(const KeyEvent& event) { - if (!native_view()) - return false; - switch (event.key_code()) { - case ui::VKEY_UP: - if (!native_scroll_bar_->IsHorizontal()) - MoveStep(false /* negative */); - break; - case ui::VKEY_DOWN: - if (!native_scroll_bar_->IsHorizontal()) - MoveStep(true /* positive */); - break; - case ui::VKEY_LEFT: - if (native_scroll_bar_->IsHorizontal()) - MoveStep(false /* negative */); - break; - case ui::VKEY_RIGHT: - if (native_scroll_bar_->IsHorizontal()) - MoveStep(true /* positive */); - break; - case ui::VKEY_PRIOR: - MovePage(false /* negative */); - break; - case ui::VKEY_NEXT: - MovePage(true /* positive */); - break; - case ui::VKEY_HOME: - MoveTo(0); - break; - case ui::VKEY_END: - MoveToBottom(); - break; - default: - return false; - } - return true; -} - -bool NativeScrollBarGtk::OnMouseWheel(const MouseWheelEvent& e) { - if (!native_view()) - return false; - MoveBy(-e.offset()); // e.GetOffset() > 0 means scroll up. - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// NativeScrollBarGtk, NativeControlGtk overrides: - -void NativeScrollBarGtk::CreateNativeControl() { - GtkObject* adj = gtk_adjustment_new(native_scroll_bar_->GetMinPosition(), - native_scroll_bar_->GetMinPosition(), - native_scroll_bar_->GetMaxPosition(), - 10, 10, - 0); - GtkWidget* widget; - if (native_scroll_bar_->IsHorizontal()) { - widget = gtk_hscrollbar_new(GTK_ADJUSTMENT(adj)); - } else { - widget = gtk_vscrollbar_new(GTK_ADJUSTMENT(adj)); - } - - gtk_range_set_update_policy(GTK_RANGE(widget), GTK_UPDATE_CONTINUOUS); - - g_signal_connect(adj, "value-changed", - G_CALLBACK(CallValueChanged), this); - - NativeControlCreated(widget); -} - -//////////////////////////////////////////////////////////////////////////////// -// NativeScrollBarGtk, NativeScrollBarWrapper overrides: - -int NativeScrollBarGtk::GetPosition() const { - return static_cast<int>(gtk_range_get_value(GTK_RANGE(native_view()))); -} - -View* NativeScrollBarGtk::GetView() { - return this; -} - -void NativeScrollBarGtk::Update(int viewport_size, - int content_size, - int current_pos) { - if (!native_view()) - return; - - if (content_size < 0) - content_size = 0; - - if (current_pos < 0) - current_pos = 0; - - if (current_pos > content_size) - current_pos = content_size; - - ScrollBarController* controller = native_scroll_bar_->controller(); - int step = controller->GetScrollIncrement(native_scroll_bar_, - false /* step */, - true /* positive */); - int page = controller->GetScrollIncrement(native_scroll_bar_, - true /* page */, true); - GtkObject* adj = gtk_adjustment_new(current_pos, - native_scroll_bar_->GetMinPosition(), - content_size, - step, page, - viewport_size); - gtk_range_set_adjustment(GTK_RANGE(native_view()), GTK_ADJUSTMENT(adj)); - g_signal_connect(adj, "value-changed", G_CALLBACK(CallValueChanged), this); -} - -//////////////////////////////////////////////////////////////////////////////// -// NativeScrollBarGtk, private: - -void NativeScrollBarGtk::ValueChanged() { - ScrollBarController* controller = native_scroll_bar_->controller(); - controller->ScrollToPosition(native_scroll_bar_, GetPosition()); -} - -// static -void NativeScrollBarGtk::CallValueChanged(GtkWidget* widget, - NativeScrollBarGtk* scroll_bar) { - scroll_bar->ValueChanged(); -} - -void NativeScrollBarGtk::MoveBy(int o) { - MoveTo(GetPosition() + o); -} - -void NativeScrollBarGtk::MovePage(bool positive) { - ScrollBarController* controller = native_scroll_bar_->controller(); - MoveBy(controller->GetScrollIncrement(native_scroll_bar_, true, positive)); -} - -void NativeScrollBarGtk::MoveStep(bool positive) { - ScrollBarController* controller = native_scroll_bar_->controller(); - MoveBy(controller->GetScrollIncrement(native_scroll_bar_, false, positive)); -} - -void NativeScrollBarGtk::MoveTo(int p) { - if (p < native_scroll_bar_->GetMinPosition()) - p = native_scroll_bar_->GetMinPosition(); - if (p > native_scroll_bar_->GetMaxPosition()) - p = native_scroll_bar_->GetMaxPosition(); - GtkAdjustment* adj = gtk_range_get_adjustment(GTK_RANGE(native_view())); - gtk_adjustment_set_value(adj, p); -} - -void NativeScrollBarGtk::MoveToBottom() { - GtkAdjustment* adj = gtk_range_get_adjustment(GTK_RANGE(native_view())); - MoveTo(adj->upper); -} - -//////////////////////////////////////////////////////////////////////////////// -// NativewScrollBarWrapper, public: - -// static -NativeScrollBarWrapper* NativeScrollBarWrapper::CreateWrapper( - NativeScrollBar* scroll_bar) { - if (Widget::IsPureViews()) - return new NativeScrollBarViews(scroll_bar); - return new NativeScrollBarGtk(scroll_bar); -} - -// static -int NativeScrollBarWrapper::GetHorizontalScrollBarHeight() { - // TODO(oshima): get this from gtk's widget property "slider-width". - return 20; -} - -// static -int NativeScrollBarWrapper::GetVerticalScrollBarWidth() { - // TODO(oshima): get this from gtk's widget property "slider-width". - return 20; -} - -} // namespace views diff --git a/ui/views/controls/scrollbar/native_scroll_bar_gtk.h b/ui/views/controls/scrollbar/native_scroll_bar_gtk.h deleted file mode 100644 index e9a5ed5..0000000 --- a/ui/views/controls/scrollbar/native_scroll_bar_gtk.h +++ /dev/null @@ -1,80 +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_VIEWS_CONTROLS_SCROLLBAR_NATIVE_SCROLL_BAR_GTK_H_ -#define UI_VIEWS_CONTROLS_SCROLLBAR_NATIVE_SCROLL_BAR_GTK_H_ -#pragma once - -#include "base/compiler_specific.h" -#include "ui/views/controls/native_control_gtk.h" -#include "ui/views/controls/scrollbar/native_scroll_bar_wrapper.h" - -namespace views { - -///////////////////////////////////////////////////////////////////////////// -// -// NativeScrollBarGtk -// -// A View subclass that wraps a Native gtk scrollbar control. -// -// A scrollbar is either horizontal or vertical. -// -///////////////////////////////////////////////////////////////////////////// -class NativeScrollBarGtk : public NativeControlGtk, - public NativeScrollBarWrapper { - public: - // Creates new scrollbar, either horizontal or vertical. - explicit NativeScrollBarGtk(NativeScrollBar* native_scroll_bar); - virtual ~NativeScrollBarGtk(); - - private: - // Overridden from View for layout purpose. - virtual void Layout() OVERRIDE; - virtual gfx::Size GetPreferredSize() OVERRIDE; - - // Overridden from View for keyboard UI purpose. - virtual bool OnKeyPressed(const KeyEvent& event) OVERRIDE; - virtual bool OnMouseWheel(const MouseWheelEvent& e) OVERRIDE; - - // Overridden from NativeControlGtk. - virtual void CreateNativeControl() OVERRIDE; - - // Overridden from NativeScrollBarWrapper. - virtual int GetPosition() const OVERRIDE; - virtual View* GetView() OVERRIDE; - virtual void Update(int viewport_size, - int content_size, - int current_pos) OVERRIDE; - - // Moves the scrollbar by the given value. Negative value is allowed. - // (moves upward) - void MoveBy(int o); - - // Moves the scrollbar by the page (viewport) size. - void MovePage(bool positive); - - // Moves the scrollbar by predefined step size. - void MoveStep(bool positive); - - // Moves the scrollbar to the given position. MoveTo(0) moves it to the top. - void MoveTo(int p); - - // Moves the scrollbar to the end. - void MoveToBottom(); - - // Invoked when the scrollbar's position is changed. - void ValueChanged(); - static void CallValueChanged(GtkWidget* widget, - NativeScrollBarGtk* scroll_bar); - - // The NativeScrollBar we are bound to. - NativeScrollBar* native_scroll_bar_; - - private: - DISALLOW_COPY_AND_ASSIGN(NativeScrollBarGtk); -}; - -} // namespace views - -#endif // UI_VIEWS_CONTROLS_SCROLLBAR_NATIVE_SCROLL_BAR_GTK_H_ diff --git a/ui/views/controls/tabbed_pane/native_tabbed_pane_gtk.cc b/ui/views/controls/tabbed_pane/native_tabbed_pane_gtk.cc deleted file mode 100644 index 3afee6b..0000000 --- a/ui/views/controls/tabbed_pane/native_tabbed_pane_gtk.cc +++ /dev/null @@ -1,233 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/controls/tabbed_pane/native_tabbed_pane_gtk.h" - -#include <gtk/gtk.h> - -#include "base/logging.h" -#include "base/stl_util.h" -#include "base/utf_string_conversions.h" -#include "ui/gfx/canvas.h" -#include "ui/gfx/font.h" -#include "ui/gfx/skia_utils_gtk.h" -#include "ui/views/background.h" -#include "ui/views/controls/tabbed_pane/tabbed_pane.h" -#include "ui/views/controls/tabbed_pane/tabbed_pane_listener.h" -#include "ui/views/layout/fill_layout.h" -#include "ui/views/widget/native_widget.h" -#include "ui/views/widget/widget.h" - -namespace views { - -//////////////////////////////////////////////////////////////////////////////// -// NativeTabbedPaneGtk, public: - -NativeTabbedPaneGtk::NativeTabbedPaneGtk(TabbedPane* tabbed_pane) - : NativeControlGtk(), - tabbed_pane_(tabbed_pane) { - set_focus_view(tabbed_pane); -} - -NativeTabbedPaneGtk::~NativeTabbedPaneGtk() { -} - -//////////////////////////////////////////////////////////////////////////////// -// NativeTabbedPaneGtk, NativeControlGtk implementation: - -void NativeTabbedPaneGtk::CreateNativeControl() { - GtkWidget* widget = gtk_notebook_new(); - gtk_notebook_set_tab_pos(GTK_NOTEBOOK(widget), GTK_POS_TOP); - g_signal_connect(widget, "switch-page", - G_CALLBACK(CallSwitchPage), this); - NativeControlCreated(widget); -} - -//////////////////////////////////////////////////////////////////////////////// -// NativeTabbedPaneGtk, NativeTabbedPaneWrapper implementation: - -void NativeTabbedPaneGtk::AddTab(const string16& title, View* contents) { - AddTabAtIndex(GetTabCount(), title, contents, true); -} - -void NativeTabbedPaneGtk::AddTabAtIndex(int index, - const string16& title, - View* contents, - bool select_if_first_tab) { - DCHECK(native_view()); - DoAddTabAtIndex(index, title, contents, select_if_first_tab); -} - -View* NativeTabbedPaneGtk::RemoveTabAtIndex(int index) { - int tab_count = GetTabCount(); - DCHECK(index >= 0 && index < tab_count); - - if (index < (tab_count - 1)) { - // Select the next tab. - SelectTabAt(index + 1); - } else { - // We are the last tab, select the previous one. - if (index > 0) { - SelectTabAt(index - 1); - } else { - // last tab. nothing to select. - } - } - - GtkWidget* page = - gtk_notebook_get_nth_page(GTK_NOTEBOOK(native_view()), index); - Widget* widget = Widget::GetWidgetForNativeView(page); - - // detach the content view from widget so that we can delete widget - // without destroying the content view. - View* removed_tab = GetTabViewAt(index); - widget->GetRootView()->RemoveChildView(removed_tab); - - // widget delete itself when native_view is deleted. - gtk_notebook_remove_page(GTK_NOTEBOOK(native_view()), index); - - // Removing a tab might change the size of the tabbed pane. - if (GetWidget()) - GetWidget()->GetRootView()->Layout(); - - return removed_tab; -} - -void NativeTabbedPaneGtk::SelectTabAt(int index) { - DCHECK((index >= 0) && (index < GetTabCount())); - gtk_notebook_set_current_page(GTK_NOTEBOOK(native_view()), index); -} - -int NativeTabbedPaneGtk::GetTabCount() { - return gtk_notebook_get_n_pages(GTK_NOTEBOOK(native_view())); -} - -int NativeTabbedPaneGtk::GetSelectedTabIndex() { - return gtk_notebook_get_current_page(GTK_NOTEBOOK(native_view())); -} - -View* NativeTabbedPaneGtk::GetSelectedTab() { - return GetTabViewAt(GetSelectedTabIndex()); -} - -View* NativeTabbedPaneGtk::GetView() { - return this; -} - -void NativeTabbedPaneGtk::SetFocus() { - OnFocus(); -} - -gfx::Size NativeTabbedPaneGtk::GetPreferredSize() { - if (!native_view()) - return gfx::Size(); - - // For some strange reason (or maybe it's a bug), the requisition is not - // returned in the passed requisition parameter, but instead written to the - // widget's requisition field. - GtkRequisition requisition = { 0, 0 }; - gtk_widget_size_request(GTK_WIDGET(native_view()), &requisition); - GtkRequisition& size(GTK_WIDGET(native_view())->requisition); - return gfx::Size(size.width, size.height); -} - -gfx::NativeView NativeTabbedPaneGtk::GetTestingHandle() const { - return native_view(); -} - -//////////////////////////////////////////////////////////////////////////////// -// NativeTabbedPaneGtk, View implementation: - -FocusTraversable* NativeTabbedPaneGtk::GetFocusTraversable() { - return GetWidgetAt(GetSelectedTabIndex()); -} - -//////////////////////////////////////////////////////////////////////////////// -// NativeTabbedPaneGtk, private: -void NativeTabbedPaneGtk::DoAddTabAtIndex(int index, - const string16& title, - View* contents, - bool select_if_first_tab) { - int tab_count = GetTabCount(); - DCHECK(index <= tab_count); - - Widget* page_container = new Widget; - page_container->Init( - Widget::InitParams(Widget::InitParams::TYPE_CONTROL)); - page_container->SetContentsView(contents); - page_container->SetFocusTraversableParent(GetWidget()->GetFocusTraversable()); - page_container->SetFocusTraversableParentView(this); - page_container->Show(); - - if (!contents->background()) { - GtkStyle* window_style = - gtk_widget_get_style(page_container->GetNativeView()); - contents->set_background( - Background::CreateSolidBackground( - gfx::GdkColorToSkColor(window_style->bg[GTK_STATE_NORMAL]))); - } - - GtkWidget* page = page_container->GetNativeView(); - // increment ref count not to delete on remove below - g_object_ref(page); - // detach parent from the page so that we can add it to notebook - GtkWidget* parent = gtk_widget_get_parent(page); - gtk_container_remove(GTK_CONTAINER(parent), page); - - GtkWidget* label = gtk_label_new(UTF16ToUTF8(title).c_str()); - gtk_widget_show(label); - gtk_notebook_insert_page(GTK_NOTEBOOK(native_view()), - page, - label, - index); - g_object_unref(page); - - if (tab_count == 0 && select_if_first_tab) - gtk_notebook_set_current_page(GTK_NOTEBOOK(native_view()), 0); - - // Relayout the hierarchy, since the added tab might require more space. - if (GetWidget()) - GetWidget()->GetRootView()->Layout(); -} - -Widget* NativeTabbedPaneGtk::GetWidgetAt(int index) { - DCHECK(index <= GetTabCount()); - GtkWidget* page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(native_view()), - index); - Widget* widget = Widget::GetWidgetForNativeView(page); - DCHECK(widget); - return widget; -} - -View* NativeTabbedPaneGtk::GetTabViewAt(int index) { - Widget* widget = GetWidgetAt(index); - DCHECK(widget); - DCHECK_EQ(1, widget->GetRootView()->child_count()); - return widget->GetRootView()->child_at(0); -} - -void NativeTabbedPaneGtk::OnSwitchPage(int selected_tab_index) { - TabbedPaneListener* listener = tabbed_pane_->listener(); - if (listener != NULL) - listener->TabSelectedAt(selected_tab_index); -} - -// static -void NativeTabbedPaneGtk::CallSwitchPage(GtkNotebook* widget, - GtkNotebookPage* page, - guint selected_tab_index, - NativeTabbedPaneGtk* tabbed_pane) { - tabbed_pane->OnSwitchPage(selected_tab_index); -} - -//////////////////////////////////////////////////////////////////////////////// -// NativeTabbedPaneWrapper, public: - -// static -NativeTabbedPaneWrapper* NativeTabbedPaneWrapper::CreateNativeWrapper( - TabbedPane* tabbed_pane) { - return new NativeTabbedPaneGtk(tabbed_pane); -} - -} // namespace views diff --git a/ui/views/controls/tabbed_pane/native_tabbed_pane_gtk.h b/ui/views/controls/tabbed_pane/native_tabbed_pane_gtk.h deleted file mode 100644 index b937cb2..0000000 --- a/ui/views/controls/tabbed_pane/native_tabbed_pane_gtk.h +++ /dev/null @@ -1,69 +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_VIEWS_CONTROLS_TABBED_PANE_NATIVE_TABBED_PANE_GTK_H_ -#define UI_VIEWS_CONTROLS_TABBED_PANE_NATIVE_TABBED_PANE_GTK_H_ -#pragma once - -#include "base/basictypes.h" -#include "base/compiler_specific.h" -#include "ui/views/controls/native_control_gtk.h" -#include "ui/views/controls/tabbed_pane/native_tabbed_pane_wrapper.h" - -namespace views { - -class NativeTabbedPaneGtk : public NativeControlGtk, - public NativeTabbedPaneWrapper { - public: - explicit NativeTabbedPaneGtk(TabbedPane* tabbed_pane); - virtual ~NativeTabbedPaneGtk(); - - // NativeControlGtk: - virtual void CreateNativeControl() OVERRIDE; - - // NativeTabbedPaneWrapper: - virtual void AddTab(const string16& title, View* contents) OVERRIDE; - virtual void AddTabAtIndex(int index, - const string16& title, - View* contents, - bool select_if_first_tab) OVERRIDE; - virtual View* RemoveTabAtIndex(int index) OVERRIDE; - virtual void SelectTabAt(int index) OVERRIDE; - virtual int GetTabCount() OVERRIDE; - virtual int GetSelectedTabIndex() OVERRIDE; - virtual View* GetSelectedTab() OVERRIDE; - virtual View* GetView() OVERRIDE; - virtual void SetFocus() OVERRIDE; - virtual gfx::Size GetPreferredSize() OVERRIDE; - virtual gfx::NativeView GetTestingHandle() const OVERRIDE; - - // View: - virtual FocusTraversable* GetFocusTraversable() OVERRIDE; - - private: - void DoAddTabAtIndex(int index, - const string16& title, - View* contents, - bool select_if_first_tab); - - // Returns the Widget containing the tab contents at |index|. - Widget* GetWidgetAt(int index); - - View* GetTabViewAt(int index); - void OnSwitchPage(int selected_tab_index); - - static void CallSwitchPage(GtkNotebook* widget, - GtkNotebookPage* page, - guint selected_tab_index, - NativeTabbedPaneGtk* tabbed_pane); - - // The tabbed-pane we are bound to. - TabbedPane* tabbed_pane_; - - DISALLOW_COPY_AND_ASSIGN(NativeTabbedPaneGtk); -}; - -} // namespace views - -#endif // UI_VIEWS_CONTROLS_TABBED_PANE_NATIVE_TABBED_PANE_GTK_H_ diff --git a/ui/views/controls/textfield/gtk_views_entry.cc b/ui/views/controls/textfield/gtk_views_entry.cc deleted file mode 100644 index d26e370..0000000 --- a/ui/views/controls/textfield/gtk_views_entry.cc +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/controls/textfield/gtk_views_entry.h" - -#include "base/utf_string_conversions.h" -#include "ui/gfx/canvas_skia_paint.h" -#include "ui/gfx/insets.h" -#include "ui/gfx/skia_utils_gtk.h" -#include "ui/views/controls/textfield/native_textfield_gtk.h" -#include "ui/views/controls/textfield/textfield.h" - -G_BEGIN_DECLS - -G_DEFINE_TYPE(GtkViewsEntry, gtk_views_entry, GTK_TYPE_ENTRY) - -static gint gtk_views_entry_expose_event(GtkWidget *widget, - GdkEventExpose *event) { - views::NativeTextfieldGtk* host = GTK_VIEWS_ENTRY(widget)->host; -#if defined(OS_CHROMEOS) - // Draw textfield background over the default white rectangle. - if (event->window == widget->window) { - gfx::CanvasSkiaPaint canvas(event); - if (!canvas.is_empty() && host) { - host->textfield()->OnPaintBackground(&canvas); - } - } -#endif - - gint result = GTK_WIDGET_CLASS(gtk_views_entry_parent_class)->expose_event( - widget, event); - - GtkEntry* entry = GTK_ENTRY(widget); - - // Internally GtkEntry creates an additional window (text_area) that the - // text is drawn to. We only need paint after that window has painted. - if (host && event->window == entry->text_area && - !host->textfield()->text_to_display_when_empty().empty() && - g_utf8_strlen(gtk_entry_get_text(entry), -1) == 0) { - gfx::CanvasSkiaPaint canvas(event); - if (!canvas.is_empty()) { - gfx::Insets insets = - views::NativeTextfieldGtk::GetEntryInnerBorder(entry); - gfx::Font font = host->textfield()->font(); - const string16 text = host->textfield()->text_to_display_when_empty(); - canvas.DrawStringInt( - text, font, - gfx::GdkColorToSkColor(widget->style->text[GTK_STATE_INSENSITIVE]), - insets.left(), insets.top(), - widget->allocation.width - insets.width(), font.GetHeight()); - } - } - - return result; -} - -static void gtk_views_entry_class_init(GtkViewsEntryClass* views_entry_class) { - GtkWidgetClass* widget_class = - reinterpret_cast<GtkWidgetClass*>(views_entry_class); - widget_class->expose_event = gtk_views_entry_expose_event; -} - -static void gtk_views_entry_init(GtkViewsEntry* entry) { - entry->host = NULL; -} - -GtkWidget* gtk_views_entry_new(views::NativeTextfieldGtk* host) { - gpointer entry = g_object_new(GTK_TYPE_VIEWS_ENTRY, NULL); - GTK_VIEWS_ENTRY(entry)->host = host; - return GTK_WIDGET(entry); -} - -G_END_DECLS diff --git a/ui/views/controls/textfield/gtk_views_entry.h b/ui/views/controls/textfield/gtk_views_entry.h deleted file mode 100644 index 1584165..0000000 --- a/ui/views/controls/textfield/gtk_views_entry.h +++ /dev/null @@ -1,53 +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_VIEWS_CONTROLS_TEXTFIELD_GTK_VIEWS_ENTRY_H_ -#define UI_VIEWS_CONTROLS_TEXTFIELD_GTK_VIEWS_ENTRY_H_ -#pragma once - -#include <gdk/gdk.h> -#include <gtk/gtkentry.h> - -namespace views { -class NativeTextfieldGtk; -} - -// GtkViewsEntry is a subclass of GtkEntry that can draw text when the text in -// the entry is empty. For example, this could show the text 'password' in a -// password field when the text is empty. GtkViewsEntry is used internally by -// NativeTextfieldGtk. - -G_BEGIN_DECLS - -#define GTK_TYPE_VIEWS_ENTRY (gtk_views_entry_get_type ()) -#define GTK_VIEWS_ENTRY(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_VIEWS_ENTRY, GtkViewsEntry)) -#define GTK_VIEWS_ENTRY_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_VIEWS_ENTRY, GtkViewsEntryClass)) -#define GTK_IS_VIEWS_ENTRY(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_VIEWS_ENTRY)) -#define GTK_IS_VIEWS_ENTRY_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_VIEWS_ENTRY)) -#define GTK_VIEWS_ENTRY_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_VIEWS_ENTRY, GtkViewsEntry)) - -typedef struct _GtkViewsEntry GtkViewsEntry; -typedef struct _GtkViewsEntryClass GtkViewsEntryClass; - -struct _GtkViewsEntry { - GtkEntry entry; - views::NativeTextfieldGtk* host; -}; - -struct _GtkViewsEntryClass { - GtkEntryClass parent_class; -}; - -GtkWidget* gtk_views_entry_new(views::NativeTextfieldGtk* host); - -GType gtk_views_entry_get_type(); - -G_END_DECLS - -#endif // UI_VIEWS_CONTROLS_TEXTFIELD_GTK_VIEWS_ENTRY_H_ diff --git a/ui/views/controls/textfield/gtk_views_textview.cc b/ui/views/controls/textfield/gtk_views_textview.cc deleted file mode 100644 index 8e4ca38..0000000 --- a/ui/views/controls/textfield/gtk_views_textview.cc +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/controls/textfield/gtk_views_textview.h" - -#include "base/utf_string_conversions.h" -#include "ui/gfx/canvas_skia_paint.h" -#include "ui/gfx/insets.h" -#include "ui/gfx/skia_utils_gtk.h" -#include "ui/views/controls/textfield/native_textfield_gtk.h" -#include "ui/views/controls/textfield/textfield.h" - -G_BEGIN_DECLS - -G_DEFINE_TYPE(GtkViewsTextView, gtk_views_textview, GTK_TYPE_TEXT_VIEW) - -static gint gtk_views_textview_expose_event(GtkWidget *widget, - GdkEventExpose *event) { - GtkTextView* text_view = GTK_TEXT_VIEW(widget); - GdkWindow* text_window = gtk_text_view_get_window(text_view, - GTK_TEXT_WINDOW_TEXT); - if (event->window == text_window) { - gint width, height; - gdk_drawable_get_size (text_window, &width, &height); - gtk_paint_flat_box(widget->style, text_window, - static_cast<GtkStateType>(GTK_WIDGET_STATE(widget)), GTK_SHADOW_NONE, - &event->area, widget, "textview", - 0, 0, width, height); - } - - gint result = GTK_WIDGET_CLASS(gtk_views_textview_parent_class)->expose_event( - widget, event); - - GtkTextBuffer* text_buffer = gtk_text_view_get_buffer(text_view); - views::NativeTextfieldGtk* host = GTK_VIEWS_TEXTVIEW(widget)->host; - - GtkTextIter start; - GtkTextIter end; - gtk_text_buffer_get_bounds(text_buffer, &start, &end); - - // Paint the info text to text window if GtkTextView contains no text. - if (host && event->window == text_window && - !host->textfield()->text_to_display_when_empty().empty() && - gtk_text_iter_equal(&start, &end)) { - gfx::CanvasSkiaPaint canvas(event); - if (!canvas.is_empty()) { - gfx::Insets insets = - views::NativeTextfieldGtk::GetTextViewInnerBorder(text_view); - gfx::Font font = host->textfield()->font(); - const string16 text = host->textfield()->text_to_display_when_empty(); - canvas.DrawStringInt( - text, font, - gfx::GdkColorToSkColor(widget->style->text[GTK_STATE_INSENSITIVE]), - insets.left(), insets.top(), - widget->allocation.width - insets.width(), font.GetHeight()); - } - } - - // Draw border and focus. - if (event->window == widget->window) { - gint width; - gint height; - gdk_drawable_get_size (widget->window, &width, &height); - - bool has_focus = GTK_WIDGET_HAS_FOCUS(widget); - - gtk_paint_shadow(widget->style, widget->window, - has_focus ? GTK_STATE_ACTIVE : GTK_STATE_NORMAL, - GTK_SHADOW_OUT, - &event->area, widget, "textview", - 0, 0, width, height); - if (has_focus) { - gtk_paint_focus(widget->style, widget->window, - static_cast<GtkStateType>(GTK_WIDGET_STATE(widget)), - &event->area, widget, "textview", - 0, 0, width, height); - } - } - - return result; -} - -static void gtk_views_textview_class_init( - GtkViewsTextViewClass* views_textview_class) { - GtkWidgetClass* widget_class = - reinterpret_cast<GtkWidgetClass*>(views_textview_class); - widget_class->expose_event = gtk_views_textview_expose_event; -} - -static void gtk_views_textview_init(GtkViewsTextView* text_view) { - text_view->host = NULL; -} - -GtkWidget* gtk_views_textview_new(views::NativeTextfieldGtk* host) { - gpointer text_view = g_object_new(GTK_TYPE_VIEWS_TEXTVIEW, NULL); - GTK_VIEWS_TEXTVIEW(text_view)->host = host; - return GTK_WIDGET(text_view); -} - -G_END_DECLS diff --git a/ui/views/controls/textfield/gtk_views_textview.h b/ui/views/controls/textfield/gtk_views_textview.h deleted file mode 100644 index 9c2e4e6..0000000 --- a/ui/views/controls/textfield/gtk_views_textview.h +++ /dev/null @@ -1,54 +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_VIEWS_CONTROLS_TEXTFIELD_GTK_VIEWS_TEXTVIEW_H_ -#define UI_VIEWS_CONTROLS_TEXTFIELD_GTK_VIEWS_TEXTVIEW_H_ -#pragma once - -#include <gdk/gdk.h> -#include <gtk/gtktextview.h> - -namespace views { -class NativeTextfieldGtk; -} - -// Similar to GtkViewsEntry, GtkViewsTextView is a subclass of GtkTextView -// with a border and ability to show a custom info when text view has no text. - -G_BEGIN_DECLS - -#define GTK_TYPE_VIEWS_TEXTVIEW (gtk_views_textview_get_type()) -#define GTK_VIEWS_TEXTVIEW(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_VIEWS_TEXTVIEW, \ - GtkViewsTextView)) -#define GTK_VIEWS_TEXTVIEW_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_VIEWS_TEXTVIEW, \ - GtkViewsTextViewClass)) -#define GTK_IS_VIEWS_TEXTVIEW(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_VIEWS_TEXTVIEW)) -#define GTK_IS_VIEWS_TEXTVIEW_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_VIEWS_TEXTVIEW)) -#define GTK_VIEWS_TEXTVIEW_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_VIEWS_TEXTVIEW, \ - GtkViewsTextView)) - -typedef struct _GtkViewsTextView GtkViewsTextView; -typedef struct _GtkViewsTextViewClass GtkViewsTextViewClass; - -struct _GtkViewsTextView { - GtkTextView text_view; - views::NativeTextfieldGtk* host; -}; - -struct _GtkViewsTextViewClass { - GtkTextViewClass parent_class; -}; - -GtkWidget* gtk_views_textview_new(views::NativeTextfieldGtk* host); - -GType gtk_views_textview_get_type(); - -G_END_DECLS - -#endif // UI_VIEWS_CONTROLS_TEXTFIELD_GTK_VIEWS_TEXTVIEW_H_ diff --git a/ui/views/controls/textfield/native_textfield_gtk.cc b/ui/views/controls/textfield/native_textfield_gtk.cc deleted file mode 100644 index dd45344..0000000 --- a/ui/views/controls/textfield/native_textfield_gtk.cc +++ /dev/null @@ -1,447 +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 <gdk/gdkkeysyms.h> -#include <gtk/gtk.h> - -#include "ui/views/controls/textfield/native_textfield_gtk.h" - -#include "base/logging.h" -#include "base/utf_string_conversions.h" -#include "ui/base/range/range.h" -#include "ui/gfx/gtk_util.h" -#include "ui/gfx/insets.h" -#include "ui/gfx/selection_model.h" -#include "ui/gfx/skia_utils_gtk.h" -#include "ui/views/controls/textfield/gtk_views_entry.h" -#include "ui/views/controls/textfield/gtk_views_textview.h" -#include "ui/views/controls/textfield/native_textfield_views.h" -#include "ui/views/controls/textfield/textfield.h" -#include "ui/views/controls/textfield/textfield_controller.h" -#include "ui/views/widget/native_widget_gtk.h" - -namespace views { - -// A character used to hide a text in obscured mode. -static const char kObscuredChar = '*'; - -// Border width for GtkTextView. -const int kTextViewBorderWidth = 4; - -//////////////////////////////////////////////////////////////////////////////// -// NativeTextfieldGtk, public: - -NativeTextfieldGtk::NativeTextfieldGtk(Textfield* textfield) - : textfield_(textfield), - paste_clipboard_requested_(false) { - // Make |textfield| the focused view, so that when we get focused the focus - // manager sees |textfield| as the focused view (since we are just a wrapper - // view). - set_focus_view(textfield); -} - -NativeTextfieldGtk::~NativeTextfieldGtk() { -} - -// Returns the inner border of an entry. -// static -gfx::Insets NativeTextfieldGtk::GetEntryInnerBorder(GtkEntry* entry) { - const GtkBorder* inner_border = gtk_entry_get_inner_border(entry); - if (inner_border) - return gfx::Insets(*inner_border); - - // No explicit border set, try the style. - GtkBorder* style_border; - gtk_widget_style_get(GTK_WIDGET(entry), "inner-border", &style_border, NULL); - if (style_border) { - gfx::Insets insets = gfx::Insets(*style_border); - gtk_border_free(style_border); - return insets; - } - - // If border is null, Gtk uses 2 on all sides. - return gfx::Insets(2, 2, 2, 2); -} - -gfx::Insets NativeTextfieldGtk::GetTextViewInnerBorder(GtkTextView* text_view) { - return gfx::Insets(kTextViewBorderWidth / 2, kTextViewBorderWidth / 2, - kTextViewBorderWidth / 2, kTextViewBorderWidth / 2); -} - -//////////////////////////////////////////////////////////////////////////////// -// NativeTextfieldGtk, NativeTextfieldWrapper implementation: - -string16 NativeTextfieldGtk::GetText() const { - return UTF8ToUTF16(gtk_entry_get_text(GTK_ENTRY(native_view()))); -} - -void NativeTextfieldGtk::UpdateText() { - if (!native_view()) - return; - gtk_entry_set_text(GTK_ENTRY(native_view()), - UTF16ToUTF8(textfield_->text()).c_str()); -} - -void NativeTextfieldGtk::AppendText(const string16& text) { - if (!native_view()) - return; - gtk_entry_append_text(GTK_ENTRY(native_view()), UTF16ToUTF8(text).c_str()); -} - -string16 NativeTextfieldGtk::GetSelectedText() const { - if (!native_view()) - return string16(); - - string16 result; - - gint start_pos; - gint end_pos; - if (!gtk_editable_get_selection_bounds(GTK_EDITABLE(native_view()), - &start_pos, &end_pos)) - return result; // No selection. - - UTF8ToUTF16(gtk_editable_get_chars(GTK_EDITABLE(native_view()), - start_pos, end_pos), - end_pos - start_pos, &result); - - return result; -} - -void NativeTextfieldGtk::SelectAll() { - if (!native_view()) - return; - // -1 as the end position selects to the end of the text. - gtk_editable_select_region(GTK_EDITABLE(native_view()), 0, -1); -} - -void NativeTextfieldGtk::ClearSelection() { - if (!native_view()) - return; - gtk_editable_select_region(GTK_EDITABLE(native_view()), 0, 0); -} - -void NativeTextfieldGtk::UpdateBorder() { - if (!native_view()) - return; - - if (!textfield_->draw_border()) - gtk_entry_set_has_frame(GTK_ENTRY(native_view()), false); -} - -void NativeTextfieldGtk::UpdateTextColor() { - if (textfield_->use_default_text_color()) { - // Passing NULL as the color undoes the effect of previous calls to - // gtk_widget_modify_text. - gtk_widget_modify_text(native_view(), GTK_STATE_NORMAL, NULL); - return; - } - GdkColor gdk_color = gfx::SkColorToGdkColor(textfield_->text_color()); - gtk_widget_modify_text(native_view(), GTK_STATE_NORMAL, &gdk_color); -} - -void NativeTextfieldGtk::UpdateBackgroundColor() { - if (textfield_->use_default_background_color()) { - // Passing NULL as the color undoes the effect of previous calls to - // gtk_widget_modify_base. - gtk_widget_modify_base(native_view(), GTK_STATE_NORMAL, NULL); - return; - } - GdkColor gdk_color = gfx::SkColorToGdkColor(textfield_->background_color()); - gtk_widget_modify_base(native_view(), GTK_STATE_NORMAL, &gdk_color); -} - -void NativeTextfieldGtk::UpdateCursorColor() { - if (!textfield_->use_default_cursor_color()) - NOTIMPLEMENTED(); -} - -void NativeTextfieldGtk::UpdateReadOnly() { - if (!native_view()) - return; - gtk_editable_set_editable(GTK_EDITABLE(native_view()), - !textfield_->read_only()); -} - -void NativeTextfieldGtk::UpdateFont() { - if (!native_view()) - return; - PangoFontDescription* pfd = textfield_->font().GetNativeFont(); - gtk_widget_modify_font(native_view(), pfd); - pango_font_description_free(pfd); -} - -void NativeTextfieldGtk::UpdateIsObscured() { - if (!native_view()) - return; - gtk_entry_set_visibility(GTK_ENTRY(native_view()), !textfield_->IsObscured()); -} - -void NativeTextfieldGtk::UpdateEnabled() { - if (!native_view()) - return; - SetEnabled(textfield_->enabled()); -} - -gfx::Insets NativeTextfieldGtk::CalculateInsets() { - if (!native_view()) - return gfx::Insets(); - - GtkWidget* widget = native_view(); - gfx::Insets insets; - - GtkEntry* entry = GTK_ENTRY(widget); - insets += GetEntryInnerBorder(entry); - if (entry->has_frame) { - insets += gfx::Insets(widget->style->ythickness, - widget->style->xthickness, - widget->style->ythickness, - widget->style->xthickness); - } - - gboolean interior_focus; - gint focus_width; - gtk_widget_style_get(widget, - "focus-line-width", &focus_width, - "interior-focus", &interior_focus, - NULL); - if (!interior_focus) - insets += gfx::Insets(focus_width, focus_width, focus_width, focus_width); - - return insets; -} - -void NativeTextfieldGtk::UpdateHorizontalMargins() { - if (!native_view()) - return; - - int left, right; - if (!textfield_->GetHorizontalMargins(&left, &right)) - return; - - gfx::Insets insets = GetEntryInnerBorder(GTK_ENTRY(native_view())); - GtkBorder border = {left, right, insets.top(), insets.bottom()}; - gtk_entry_set_inner_border(GTK_ENTRY(native_view()), &border); -} - -void NativeTextfieldGtk::UpdateVerticalMargins() { - if (!native_view()) - return; - - int top, bottom; - if (!textfield_->GetVerticalMargins(&top, &bottom)) - return; - - gfx::Insets insets = GetEntryInnerBorder(GTK_ENTRY(native_view())); - GtkBorder border = {insets.left(), insets.right(), top, bottom}; - gtk_entry_set_inner_border(GTK_ENTRY(native_view()), &border); -} - -bool NativeTextfieldGtk::SetFocus() { - OnFocus(); - return true; -} - -View* NativeTextfieldGtk::GetView() { - return this; -} - -gfx::NativeView NativeTextfieldGtk::GetTestingHandle() const { - return native_view(); -} - -bool NativeTextfieldGtk::IsIMEComposing() const { - return false; -} - -void NativeTextfieldGtk::GetSelectedRange(ui::Range* range) const { - gint start_pos; - gint end_pos; - gtk_editable_get_selection_bounds( - GTK_EDITABLE(native_view()), &start_pos, &end_pos); - *range = ui::Range(start_pos, end_pos); -} - -void NativeTextfieldGtk::SelectRange(const ui::Range& range) { - NOTREACHED(); -} - -void NativeTextfieldGtk::GetSelectionModel(gfx::SelectionModel* sel) const { - NOTREACHED(); -} - -void NativeTextfieldGtk::SelectSelectionModel(const gfx::SelectionModel& sel) { - NOTREACHED(); -} - -size_t NativeTextfieldGtk::GetCursorPosition() const { - NOTREACHED(); - return 0U; -} - -bool NativeTextfieldGtk::HandleKeyPressed(const views::KeyEvent& e) { - return false; -} - -bool NativeTextfieldGtk::HandleKeyReleased(const views::KeyEvent& e) { - return false; -} - -void NativeTextfieldGtk::HandleFocus() { -} - -void NativeTextfieldGtk::HandleBlur() { -} - -ui::TextInputClient* NativeTextfieldGtk::GetTextInputClient() { - return NULL; -} - -void NativeTextfieldGtk::ApplyStyleRange(const gfx::StyleRange& style) { - NOTREACHED(); -} - -void NativeTextfieldGtk::ApplyDefaultStyle() { - NOTREACHED(); -} - -void NativeTextfieldGtk::ClearEditHistory() { - NOTREACHED(); -} - -int NativeTextfieldGtk::GetFontHeight() { - return textfield_->font().GetHeight(); -} - -void NativeTextfieldGtk::OnActivate(GtkWidget* native_widget) { - GdkEvent* event = gtk_get_current_event(); - if (!event || event->type != GDK_KEY_PRESS) - return; - - KeyEvent views_key_event(event); - gboolean handled = false; - - TextfieldController* controller = textfield_->GetController(); - if (controller) - handled = controller->HandleKeyEvent(textfield_, views_key_event); - - Widget* widget = GetWidget(); - if (!handled && widget) { - NativeWidgetGtk* native_widget = - static_cast<NativeWidgetGtk*>(widget->native_widget()); - handled = native_widget->HandleKeyboardEvent(views_key_event); - } - - // Stop signal emission if the key event is handled by us. - if (handled) { - // Only GtkEntry has "activate" signal. - static guint signal_id = g_signal_lookup("activate", GTK_TYPE_ENTRY); - g_signal_stop_emission(native_widget, signal_id, 0); - } -} - -void NativeTextfieldGtk::OnChanged(GObject* object) { - // We need to call TextfieldController::ContentsChanged() explicitly if the - // paste action didn't change the content at all. See http://crbug.com/79002 - const bool call_contents_changed = - paste_clipboard_requested_ && GetText() == textfield_->text(); - textfield_->SyncText(); - textfield_->GetWidget()->NotifyAccessibilityEvent( - textfield_, ui::AccessibilityTypes::EVENT_TEXT_CHANGED, true); - if (call_contents_changed) { - TextfieldController* controller = textfield_->GetController(); - if (controller) - controller->ContentsChanged(textfield_, textfield_->text()); - } - paste_clipboard_requested_ = false; -} - -gboolean NativeTextfieldGtk::OnButtonPressEvent(GtkWidget* widget, - GdkEventButton* event) { - paste_clipboard_requested_ = false; - return false; -} - -gboolean NativeTextfieldGtk::OnButtonReleaseEventAfter(GtkWidget* widget, - GdkEventButton* event) { - textfield_->GetWidget()->NotifyAccessibilityEvent( - textfield_, ui::AccessibilityTypes::EVENT_TEXT_CHANGED, true); - return false; -} - -gboolean NativeTextfieldGtk::OnKeyPressEvent(GtkWidget* widget, - GdkEventKey* event) { - paste_clipboard_requested_ = false; - return false; -} - -gboolean NativeTextfieldGtk::OnKeyPressEventAfter(GtkWidget* widget, - GdkEventKey* event) { - TextfieldController* controller = textfield_->GetController(); - if (controller) { - KeyEvent key_event(reinterpret_cast<GdkEvent*>(event)); - return controller->HandleKeyEvent(textfield_, key_event); - } - return false; -} - -void NativeTextfieldGtk::OnMoveCursor(GtkWidget* widget, - GtkMovementStep step, - gint count, - gboolean extend_selection) { - textfield_->GetWidget()->NotifyAccessibilityEvent( - textfield_, ui::AccessibilityTypes::EVENT_TEXT_CHANGED, true); -} - -void NativeTextfieldGtk::OnPasteClipboard(GtkWidget* widget) { - if (!textfield_->read_only()) - paste_clipboard_requested_ = true; -} - -//////////////////////////////////////////////////////////////////////////////// -// NativeTextfieldGtk, NativeControlGtk overrides: - -void NativeTextfieldGtk::CreateNativeControl() { - NativeControlCreated(gtk_views_entry_new(this)); - gtk_entry_set_invisible_char(GTK_ENTRY(native_view()), - static_cast<gunichar>(kObscuredChar)); - textfield_->UpdateAllProperties(); -} - -void NativeTextfieldGtk::NativeControlCreated(GtkWidget* widget) { - NativeControlGtk::NativeControlCreated(widget); - - g_signal_connect(widget, "changed", G_CALLBACK(OnChangedThunk), this); - // In order to properly trigger Accelerators bound to VKEY_RETURN, we need - // to send an event when the widget gets the activate signal. - g_signal_connect(widget, "activate", G_CALLBACK(OnActivateThunk), this); - g_signal_connect(widget, "move-cursor", G_CALLBACK(OnMoveCursorThunk), this); - g_signal_connect(widget, "button-press-event", - G_CALLBACK(OnButtonPressEventThunk), this); - g_signal_connect(widget, "key-press-event", - G_CALLBACK(OnKeyPressEventThunk), this); - g_signal_connect(widget, "paste-clipboard", - G_CALLBACK(OnPasteClipboardThunk), this); - - g_signal_connect_after(widget, "button-release-event", - G_CALLBACK(OnButtonReleaseEventAfterThunk), this); - g_signal_connect_after(widget, "key-press-event", - G_CALLBACK(OnKeyPressEventAfterThunk), this); -} - -bool NativeTextfieldGtk::IsObscured() { - return textfield_->IsObscured(); -} - -/////////////////////////////////////////////////////////////////////////////// -// NativeTextfieldWrapper: - -// static -NativeTextfieldWrapper* NativeTextfieldWrapper::CreateWrapper( - Textfield* field) { - if (Widget::IsPureViews()) - return new NativeTextfieldViews(field); - return new NativeTextfieldGtk(field); -} - -} // namespace views diff --git a/ui/views/controls/textfield/native_textfield_gtk.h b/ui/views/controls/textfield/native_textfield_gtk.h deleted file mode 100644 index f5e4fed..0000000 --- a/ui/views/controls/textfield/native_textfield_gtk.h +++ /dev/null @@ -1,107 +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_VIEWS_CONTROLS_TEXTFIELD_NATIVE_TEXTFIELD_GTK_H_ -#define UI_VIEWS_CONTROLS_TEXTFIELD_NATIVE_TEXTFIELD_GTK_H_ -#pragma once - -#include <gtk/gtk.h> - -#include "base/string16.h" -#include "ui/base/gtk/gtk_signal.h" -#include "ui/views/controls/native_control_gtk.h" -#include "ui/views/controls/textfield/native_textfield_wrapper.h" - -namespace gfx { -class SelectionModel; -} - -namespace views { - -class NativeTextfieldGtk : public NativeControlGtk, - public NativeTextfieldWrapper { - public: - explicit NativeTextfieldGtk(Textfield* parent); - virtual ~NativeTextfieldGtk(); - - // Returns the textfield this NativeTextfieldGtk wraps. - Textfield* textfield() const { return textfield_; } - - // Returns the inner border of the entry. - static gfx::Insets GetEntryInnerBorder(GtkEntry* entry); - static gfx::Insets GetTextViewInnerBorder(GtkTextView* text_view); - - // Overridden from NativeTextfieldWrapper: - virtual string16 GetText() const OVERRIDE; - virtual void UpdateText() OVERRIDE; - virtual void AppendText(const string16& text) OVERRIDE; - virtual string16 GetSelectedText() const OVERRIDE; - virtual void SelectAll() OVERRIDE; - virtual void ClearSelection() OVERRIDE; - virtual void UpdateBorder() OVERRIDE; - virtual void UpdateTextColor() OVERRIDE; - virtual void UpdateBackgroundColor() OVERRIDE; - virtual void UpdateCursorColor() OVERRIDE; - virtual void UpdateReadOnly() OVERRIDE; - virtual void UpdateFont() OVERRIDE; - virtual void UpdateIsObscured() OVERRIDE; - virtual void UpdateEnabled() OVERRIDE; - virtual gfx::Insets CalculateInsets() OVERRIDE; - virtual void UpdateHorizontalMargins() OVERRIDE; - virtual void UpdateVerticalMargins() OVERRIDE; - virtual bool SetFocus() OVERRIDE; - virtual View* GetView() OVERRIDE; - virtual gfx::NativeView GetTestingHandle() const OVERRIDE; - virtual bool IsIMEComposing() const OVERRIDE; - virtual void GetSelectedRange(ui::Range* range) const OVERRIDE; - virtual void SelectRange(const ui::Range& range) OVERRIDE; - virtual void GetSelectionModel(gfx::SelectionModel* sel) const OVERRIDE; - virtual void SelectSelectionModel(const gfx::SelectionModel& sel) OVERRIDE; - virtual size_t GetCursorPosition() const OVERRIDE; - virtual bool HandleKeyPressed(const views::KeyEvent& e) OVERRIDE; - virtual bool HandleKeyReleased(const views::KeyEvent& e) OVERRIDE; - virtual void HandleFocus() OVERRIDE; - virtual void HandleBlur() OVERRIDE; - virtual ui::TextInputClient* GetTextInputClient() OVERRIDE; - virtual void ApplyStyleRange(const gfx::StyleRange& style) OVERRIDE; - virtual void ApplyDefaultStyle() OVERRIDE; - virtual void ClearEditHistory() OVERRIDE; - virtual int GetFontHeight() OVERRIDE; - - // Overridden from NativeControlGtk: - virtual void CreateNativeControl() OVERRIDE; - virtual void NativeControlCreated(GtkWidget* widget) OVERRIDE; - - // Returns true if the textfield is obscured (shown as *****). - bool IsObscured(); - - private: - // Gtk signal callbacks. - CHROMEGTK_CALLBACK_0(NativeTextfieldGtk, void, OnActivate); - CHROMEGTK_CALLBACK_1(NativeTextfieldGtk, gboolean, OnButtonPressEvent, - GdkEventButton*); - CHROMEGTK_CALLBACK_1(NativeTextfieldGtk, gboolean, OnButtonReleaseEventAfter, - GdkEventButton*); - CHROMEG_CALLBACK_0(NativeTextfieldGtk, void, OnChanged, GObject*); - CHROMEGTK_CALLBACK_1(NativeTextfieldGtk, gboolean, OnKeyPressEvent, - GdkEventKey*); - CHROMEGTK_CALLBACK_1(NativeTextfieldGtk, gboolean, OnKeyPressEventAfter, - GdkEventKey*); - CHROMEGTK_CALLBACK_3(NativeTextfieldGtk, void, OnMoveCursor, - GtkMovementStep, gint, gboolean); - CHROMEGTK_CALLBACK_0(NativeTextfieldGtk, void, OnPasteClipboard); - - Textfield* textfield_; - - // Indicates that user requested to paste clipboard. - // The actual paste clipboard action might be performed later if the - // clipboard is not empty. - bool paste_clipboard_requested_; - - DISALLOW_COPY_AND_ASSIGN(NativeTextfieldGtk); -}; - -} // namespace views - -#endif // UI_VIEWS_CONTROLS_TEXTFIELD_NATIVE_TEXTFIELD_GTK_H_ diff --git a/ui/views/events/event_gtk.cc b/ui/views/events/event_gtk.cc deleted file mode 100644 index 5413283..0000000 --- a/ui/views/events/event_gtk.cc +++ /dev/null @@ -1,183 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/events/event.h" - -#include <gdk/gdk.h> - -#include "base/logging.h" -#include "ui/base/keycodes/keyboard_code_conversion_gtk.h" -#include "ui/gfx/point.h" - -namespace { - -unsigned int GetGdkStateFromNative(GdkEvent* gdk_event) { - switch (gdk_event->type) { - case GDK_KEY_PRESS: - case GDK_KEY_RELEASE: - return gdk_event->key.state; - case GDK_BUTTON_PRESS: - case GDK_2BUTTON_PRESS: - case GDK_3BUTTON_PRESS: - case GDK_BUTTON_RELEASE: - return gdk_event->button.state; - case GDK_SCROLL: - return gdk_event->scroll.state; - case GDK_MOTION_NOTIFY: - return gdk_event->motion.state; - case GDK_ENTER_NOTIFY: - case GDK_LEAVE_NOTIFY: - return gdk_event->crossing.state; - default: - NOTREACHED(); - break; - } - return 0; -} - -int GetFlagsFromGdkState(unsigned int state) { - int flags = 0; - flags |= (state & GDK_LOCK_MASK) ? ui::EF_CAPS_LOCK_DOWN : 0; - flags |= (state & GDK_CONTROL_MASK) ? ui::EF_CONTROL_DOWN : 0; - flags |= (state & GDK_SHIFT_MASK) ? ui::EF_SHIFT_DOWN : 0; - flags |= (state & GDK_MOD1_MASK) ? ui::EF_ALT_DOWN : 0; - flags |= (state & GDK_BUTTON1_MASK) ? ui::EF_LEFT_MOUSE_BUTTON : 0; - flags |= (state & GDK_BUTTON2_MASK) ? ui::EF_MIDDLE_MOUSE_BUTTON : 0; - flags |= (state & GDK_BUTTON3_MASK) ? ui::EF_RIGHT_MOUSE_BUTTON : 0; - return flags; -} - -//////////////////////////////////////////////////////////////////////////////// -// These functions mirror ui/base/events.h, but GTK is in the midst of removal. - -ui::EventType EventTypeFromNative(GdkEvent* gdk_event) { - // Add new event types as necessary. - switch (gdk_event->type) { - case GDK_2BUTTON_PRESS: - case GDK_3BUTTON_PRESS: - case GDK_BUTTON_PRESS: - return ui::ET_MOUSE_PRESSED; - case GDK_BUTTON_RELEASE: - return ui::ET_MOUSE_RELEASED; - case GDK_DRAG_MOTION: - return ui::ET_MOUSE_DRAGGED; - case GDK_ENTER_NOTIFY: - return ui::ET_MOUSE_ENTERED; - case GDK_KEY_PRESS: - return ui::ET_KEY_PRESSED; - case GDK_KEY_RELEASE: - return ui::ET_KEY_RELEASED; - case GDK_LEAVE_NOTIFY: - return ui::ET_MOUSE_EXITED; - case GDK_MOTION_NOTIFY: - if (gdk_event->motion.state & GDK_BUTTON1_MASK || - gdk_event->motion.state & GDK_BUTTON2_MASK || - gdk_event->motion.state & GDK_BUTTON3_MASK || - gdk_event->motion.state & GDK_BUTTON4_MASK || - gdk_event->motion.state & GDK_BUTTON5_MASK) { - return ui::ET_MOUSE_DRAGGED; - } - return ui::ET_MOUSE_MOVED; - case GDK_SCROLL: - return ui::ET_MOUSEWHEEL; - default: - NOTREACHED(); - break; - } - return ui::ET_UNKNOWN; -} - -int EventFlagsFromNative(GdkEvent* gdk_event) { - int flags = GetFlagsFromGdkState(GetGdkStateFromNative(gdk_event)); - if (gdk_event->type == GDK_2BUTTON_PRESS) - flags |= ui::EF_IS_DOUBLE_CLICK; - if (gdk_event->type == GDK_BUTTON_PRESS || - gdk_event->type == GDK_2BUTTON_PRESS || - gdk_event->type == GDK_3BUTTON_PRESS || - gdk_event->type == GDK_BUTTON_RELEASE) { - switch (gdk_event->button.button) { - case 1: - return flags | ui::EF_LEFT_MOUSE_BUTTON; - case 2: - return flags | ui::EF_MIDDLE_MOUSE_BUTTON; - case 3: - return flags | ui::EF_RIGHT_MOUSE_BUTTON; - } - } - return flags; -} - -gfx::Point EventLocationFromNative(GdkEvent* gdk_event) { - double x = 0, y = 0; - if (gdk_event_get_coords(gdk_event, &x, &y)) - return gfx::Point(static_cast<int>(x), static_cast<int>(y)); - return gfx::Point(); -} - -ui::KeyboardCode KeyboardCodeFromNative(GdkEvent* gdk_event) { - DCHECK(gdk_event->type == GDK_KEY_PRESS || - gdk_event->type == GDK_KEY_RELEASE); - return ui::KeyboardCodeFromGdkEventKey(&gdk_event->key); -} - -int GetMouseWheelOffset(GdkEvent* gdk_event) { - DCHECK(gdk_event->type == GDK_SCROLL); - int offset = (gdk_event->scroll.direction == GDK_SCROLL_UP || - gdk_event->scroll.direction == GDK_SCROLL_LEFT) ? 1 : -1; - return offset; -} - -} // namespace - -namespace views { - -//////////////////////////////////////////////////////////////////////////////// -// Event, protected: - -Event::Event(GdkEvent* gdk_event, ui::EventType type, int flags) - : native_event_(NULL), - gdk_event_(gdk_event), - type_(type), - time_stamp_(base::Time::NowFromSystemTime()), - flags_(flags) { -} - -//////////////////////////////////////////////////////////////////////////////// -// LocatedEvent, protected: - -LocatedEvent::LocatedEvent(GdkEvent* gdk_event) - : Event(gdk_event, - EventTypeFromNative(gdk_event), - EventFlagsFromNative(gdk_event)), - location_(EventLocationFromNative(gdk_event)) { -} - -//////////////////////////////////////////////////////////////////////////////// -// KeyEvent, public: - -KeyEvent::KeyEvent(GdkEvent* gdk_event) - : Event(gdk_event, - EventTypeFromNative(gdk_event), - EventFlagsFromNative(gdk_event)), - key_code_(KeyboardCodeFromNative(gdk_event)), - character_(0), - unmodified_character_(0) { -} - -//////////////////////////////////////////////////////////////////////////////// -// MouseEvent, public: - -MouseEvent::MouseEvent(GdkEvent* gdk_event) - : LocatedEvent(gdk_event) { -} - -//////////////////////////////////////////////////////////////////////////////// -// MouseWheelEvent, public: - -MouseWheelEvent::MouseWheelEvent(GdkEvent* gdk_event) - : MouseEvent(gdk_event), - offset_(kWheelDelta * GetMouseWheelOffset(gdk_event)) { -} - -} // namespace views diff --git a/ui/views/focus/accelerator_handler_gtk.cc b/ui/views/focus/accelerator_handler_gtk.cc deleted file mode 100644 index 2191686..0000000 --- a/ui/views/focus/accelerator_handler_gtk.cc +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/focus/accelerator_handler.h" - -#include <gtk/gtk.h> - -#include "ui/views/focus/focus_manager.h" - -namespace views { - -AcceleratorHandler::AcceleratorHandler() {} - -bool AcceleratorHandler::Dispatch(GdkEvent* event) { - // The logic for handling keyboard accelerators has been moved into - // NativeWidgetGtk::OnEventKey handler (views/widget/widget_gtk.cc). - gtk_main_do_event(event); - return true; -} - -} // namespace views diff --git a/ui/views/focus/accelerator_handler_gtk_unittest.cc b/ui/views/focus/accelerator_handler_gtk_unittest.cc deleted file mode 100644 index 187273e..0000000 --- a/ui/views/focus/accelerator_handler_gtk_unittest.cc +++ /dev/null @@ -1,204 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <gdk/gdkkeysyms.h> - -#include "testing/gtest/include/gtest/gtest.h" -#include "ui/base/accelerators/accelerator.h" -#include "ui/gfx/rect.h" -#include "ui/views/focus/accelerator_handler.h" -#include "ui/views/focus/focus_manager.h" -#include "ui/views/view.h" -#include "ui/views/widget/widget.h" -#include "ui/views/widget/widget_delegate.h" - -namespace views { - -class AcceleratorHandlerGtkTest - : public testing::Test, - public WidgetDelegate, - public ui::AcceleratorTarget { - public: - AcceleratorHandlerGtkTest() - : kMenuAccelerator(ui::VKEY_MENU, false, false, false), - kHomepageAccelerator(ui::VKEY_HOME, false, false, true), - content_view_(NULL) { - } - - virtual void SetUp() { - window_ = Widget::CreateWindowWithBounds(this, gfx::Rect(0, 0, 500, 500)); - window_->Show(); - FocusManager* focus_manager = window_->GetFocusManager(); - focus_manager->RegisterAccelerator( - kMenuAccelerator, ui::AcceleratorManager::kNormalPriority, this); - focus_manager->RegisterAccelerator( - kHomepageAccelerator, ui::AcceleratorManager::kNormalPriority, this); - menu_pressed_ = false; - home_pressed_ = false; - } - - virtual void TearDown() { - window_->Close(); - - // Flush the message loop to make application verifiers happy. - message_loop_.RunAllPending(); - } - - GdkEventKey CreateKeyEvent(GdkEventType type, guint keyval, guint state) { - GdkEventKey evt; - memset(&evt, 0, sizeof(evt)); - evt.type = type; - evt.keyval = keyval; - // The keyval won't be a "correct" hardware keycode for any real hardware, - // but the code should never depend on exact hardware keycodes, just the - // fact that the code for presses and releases of the same key match. - evt.hardware_keycode = keyval; - evt.state = state; - GtkWidget* widget = GTK_WIDGET(window_->GetNativeWindow()); - evt.window = widget->window; - return evt; - } - - // AcceleratorTarget implementation. - virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) { - if (accelerator == kMenuAccelerator) - menu_pressed_ = true; - else if (accelerator == kHomepageAccelerator) - home_pressed_ = true; - return true; - } - virtual bool CanHandleAccelerators() const { - return true; - } - - // WidgetDelegate Implementation. - virtual View* GetContentsView() { - if (!content_view_) - content_view_ = new View(); - return content_view_; - } - virtual const views::Widget* GetWidget() const { - return content_view_->GetWidget(); - } - virtual views::Widget* GetWidget() { - return content_view_->GetWidget(); - } - - virtual void InitContentView() { - } - - protected: - bool menu_pressed_; - bool home_pressed_; - - private: - ui::Accelerator kMenuAccelerator; - ui::Accelerator kHomepageAccelerator; - Widget* window_; - View* content_view_; - MessageLoopForUI message_loop_; - DISALLOW_COPY_AND_ASSIGN(AcceleratorHandlerGtkTest); -}; - -// Test that the homepage accelerator (Alt+Home) is activated on key down -// and that the menu accelerator (Alt) is never activated. -TEST_F(AcceleratorHandlerGtkTest, TestHomepageAccelerator) { - AcceleratorHandler handler; - GdkEventKey evt; - - ASSERT_FALSE(menu_pressed_); - ASSERT_FALSE(home_pressed_); - - evt = CreateKeyEvent(GDK_KEY_PRESS, GDK_Alt_L, 0); - EXPECT_TRUE(handler.Dispatch(reinterpret_cast<GdkEvent*>(&evt))); - - ASSERT_FALSE(menu_pressed_); - ASSERT_FALSE(home_pressed_); - - evt = CreateKeyEvent(GDK_KEY_PRESS, GDK_Home, GDK_MOD1_MASK); - EXPECT_TRUE(handler.Dispatch(reinterpret_cast<GdkEvent*>(&evt))); - - ASSERT_FALSE(menu_pressed_); - ASSERT_TRUE(home_pressed_); - - evt = CreateKeyEvent(GDK_KEY_RELEASE, GDK_Home, GDK_MOD1_MASK); - EXPECT_TRUE(handler.Dispatch(reinterpret_cast<GdkEvent*>(&evt))); - evt = CreateKeyEvent(GDK_KEY_RELEASE, GDK_Alt_L, 0); - EXPECT_TRUE(handler.Dispatch(reinterpret_cast<GdkEvent*>(&evt))); - - ASSERT_FALSE(menu_pressed_); - ASSERT_TRUE(home_pressed_); -} - -// Test that the menu accelerator is activated on key up and not key down. -TEST_F(AcceleratorHandlerGtkTest, TestMenuAccelerator) { - AcceleratorHandler handler; - GdkEventKey evt; - - ASSERT_FALSE(menu_pressed_); - - evt = CreateKeyEvent(GDK_KEY_PRESS, GDK_Alt_L, 0); - EXPECT_TRUE(handler.Dispatch(reinterpret_cast<GdkEvent*>(&evt))); - - ASSERT_FALSE(menu_pressed_); - - evt = CreateKeyEvent(GDK_KEY_RELEASE, GDK_Alt_L, 0); - EXPECT_TRUE(handler.Dispatch(reinterpret_cast<GdkEvent*>(&evt))); - - ASSERT_TRUE(menu_pressed_); -} - -// Test that the menu accelerator isn't confused by the interaction of the -// Alt and Shift keys. Try the following sequence on Linux: -// Press Alt -// Press Shift -// Release Alt -// Release Shift -// The key codes for pressing Alt and releasing Alt are different! This -// caused a bug in a previous version of the code, which is now fixed by -// keeping track of hardware keycodes, which are consistent. -TEST_F(AcceleratorHandlerGtkTest, TestAltShiftInteraction) { - AcceleratorHandler handler; - GdkEventKey evt; - - ASSERT_FALSE(menu_pressed_); - - // Press Shift. - evt = CreateKeyEvent(GDK_KEY_PRESS, GDK_Shift_L, 0); - evt.hardware_keycode = 0x32; - EXPECT_TRUE(handler.Dispatch(reinterpret_cast<GdkEvent*>(&evt))); - // Press Alt - but GDK calls this Meta when Shift is also down. - evt = CreateKeyEvent(GDK_KEY_PRESS, GDK_Meta_L, 0); - evt.hardware_keycode = 0x40; - EXPECT_TRUE(handler.Dispatch(reinterpret_cast<GdkEvent*>(&evt))); - - // Release Shift. - evt = CreateKeyEvent(GDK_KEY_RELEASE, GDK_Shift_L, 0); - evt.hardware_keycode = 0x32; - EXPECT_TRUE(handler.Dispatch(reinterpret_cast<GdkEvent*>(&evt))); - // Release Alt - with Shift not down, the keyval is now Alt, but - // the hardware keycode is unchanged. - evt = CreateKeyEvent(GDK_KEY_RELEASE, GDK_Alt_L, 0); - evt.hardware_keycode = 0x40; - EXPECT_TRUE(handler.Dispatch(reinterpret_cast<GdkEvent*>(&evt))); - - ASSERT_FALSE(menu_pressed_); - - // Press Alt by itself. - evt = CreateKeyEvent(GDK_KEY_PRESS, GDK_Alt_L, 0); - evt.hardware_keycode = 0x40; - EXPECT_TRUE(handler.Dispatch(reinterpret_cast<GdkEvent*>(&evt))); - - // This line fails if we don't keep track of hardware keycodes. - ASSERT_FALSE(menu_pressed_); - - // Release Alt - now this should trigger the menu shortcut. - evt = CreateKeyEvent(GDK_KEY_RELEASE, GDK_Alt_L, 0); - evt.hardware_keycode = 0x40; - EXPECT_TRUE(handler.Dispatch(reinterpret_cast<GdkEvent*>(&evt))); - - ASSERT_TRUE(menu_pressed_); -} - -} // namespace views diff --git a/ui/views/ime/input_method_gtk.cc b/ui/views/ime/input_method_gtk.cc deleted file mode 100644 index 8b8c97a..0000000 --- a/ui/views/ime/input_method_gtk.cc +++ /dev/null @@ -1,451 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/ime/input_method_gtk.h" - -#include <gdk/gdk.h> -#include <gdk/gdkkeysyms.h> - -#include <algorithm> -#include <string> - -#include "base/basictypes.h" -#include "base/logging.h" -#include "base/string_util.h" -#include "base/third_party/icu/icu_utf.h" -#include "base/utf_string_conversions.h" -#include "ui/base/gtk/event_synthesis_gtk.h" -#include "ui/base/gtk/gtk_im_context_util.h" -#include "ui/base/keycodes/keyboard_code_conversion_gtk.h" -#include "ui/base/keycodes/keyboard_codes.h" -#include "ui/views/events/event.h" -#include "ui/views/widget/widget.h" - -namespace views { - -InputMethodGtk::InputMethodGtk(internal::InputMethodDelegate* delegate) - : context_(NULL), - context_simple_(NULL), - widget_realize_id_(0), - widget_unrealize_id_(0), - context_focused_(false), - handling_key_event_(false), - composing_text_(false), - composition_changed_(false), - suppress_next_result_(false) { - set_delegate(delegate); -} - -InputMethodGtk::~InputMethodGtk() { - if (widget()) { - GtkWidget* native_view = widget()->GetNativeView(); - if (native_view) { - g_signal_handler_disconnect(native_view, widget_realize_id_); - g_signal_handler_disconnect(native_view, widget_unrealize_id_); - } - } - if (context_) { - g_object_unref(context_); - context_ = NULL; - } - if (context_simple_) { - g_object_unref(context_simple_); - context_simple_ = NULL; - } -} - -void InputMethodGtk::Init(Widget* widget) { - DCHECK(GTK_IS_WIDGET(widget->GetNativeView())); - - widget_realize_id_ = - g_signal_connect(widget->GetNativeView(), "realize", - G_CALLBACK(OnWidgetRealizeThunk), this); - widget_unrealize_id_ = - g_signal_connect(widget->GetNativeView(), "unrealize", - G_CALLBACK(OnWidgetUnrealizeThunk), this); - - context_ = gtk_im_multicontext_new(); - context_simple_ = gtk_im_context_simple_new(); - - // context_ and context_simple_ share the same callback handlers. - // All data come from them are treated equally. - // context_ is for full input method support. - // context_simple_ is for supporting dead/compose keys when input method is - // disabled, eg. in password input box. - g_signal_connect(context_, "commit", - G_CALLBACK(OnCommitThunk), this); - g_signal_connect(context_, "preedit_start", - G_CALLBACK(OnPreeditStartThunk), this); - g_signal_connect(context_, "preedit_end", - G_CALLBACK(OnPreeditEndThunk), this); - g_signal_connect(context_, "preedit_changed", - G_CALLBACK(OnPreeditChangedThunk), this); - - g_signal_connect(context_simple_, "commit", - G_CALLBACK(OnCommitThunk), this); - g_signal_connect(context_simple_, "preedit_start", - G_CALLBACK(OnPreeditStartThunk), this); - g_signal_connect(context_simple_, "preedit_end", - G_CALLBACK(OnPreeditEndThunk), this); - g_signal_connect(context_simple_, "preedit_changed", - G_CALLBACK(OnPreeditChangedThunk), this); - - // Set client window if the widget is already realized. - OnWidgetRealize(widget->GetNativeView()); - - InputMethodBase::Init(widget); -} - -void InputMethodGtk::OnFocus() { - DCHECK(!widget_focused()); - InputMethodBase::OnFocus(); - UpdateContextFocusState(); -} - -void InputMethodGtk::OnBlur() { - DCHECK(widget_focused()); - ConfirmCompositionText(); - InputMethodBase::OnBlur(); - UpdateContextFocusState(); -} - -void InputMethodGtk::DispatchKeyEvent(const KeyEvent& key) { - DCHECK(key.type() == ui::ET_KEY_PRESSED || key.type() == ui::ET_KEY_RELEASED); - suppress_next_result_ = false; - - // We should bypass |context_| and |context_simple_| only if there is no - // text input client focused. Otherwise, always send the key event to either - // |context_| or |context_simple_| even if the text input type is - // ui::TEXT_INPUT_TYPE_NONE, to make sure we can get correct character result. - if (!GetTextInputClient()) { - DispatchKeyEventPostIME(key); - return; - } - - handling_key_event_ = true; - composition_changed_ = false; - result_text_.clear(); - - // If it's a fake key event, then we need to synthesize a GdkEventKey. - GdkEvent* event = key.gdk_event() ? key.gdk_event() : - SynthesizeGdkEventKey(key); - gboolean filtered = gtk_im_context_filter_keypress( - context_focused_ ? context_ : context_simple_, &event->key); - - handling_key_event_ = false; - - const View* old_focused_view = GetFocusedView(); - if (key.type() == ui::ET_KEY_PRESSED && filtered) - ProcessFilteredKeyPressEvent(key); - - // Ensure no focus change from processing the key event. - if (old_focused_view == GetFocusedView()) { - if (HasInputMethodResult()) - ProcessInputMethodResult(key, filtered); - // Ensure no focus change sending input method results to the focused View. - if (old_focused_view == GetFocusedView()) { - if (key.type() == ui::ET_KEY_PRESSED && !filtered) - ProcessUnfilteredKeyPressEvent(key); - else if (key.type() == ui::ET_KEY_RELEASED) - DispatchKeyEventPostIME(key); - } - } - - // Free the synthesized event if there was no underlying native event. - if (event != key.gdk_event()) - gdk_event_free(event); -} - -void InputMethodGtk::OnTextInputTypeChanged(View* view) { - if (IsViewFocused(view)) { - DCHECK(!composing_text_); - UpdateContextFocusState(); - } - InputMethodBase::OnTextInputTypeChanged(view); -} - -void InputMethodGtk::OnCaretBoundsChanged(View* view) { - gfx::Rect rect; - if (!IsViewFocused(view) || !GetCaretBoundsInWidget(&rect)) - return; - - GdkRectangle gdk_rect = rect.ToGdkRectangle(); - gtk_im_context_set_cursor_location(context_, &gdk_rect); -} - -void InputMethodGtk::CancelComposition(View* view) { - if (IsViewFocused(view)) - ResetContext(); -} - -std::string InputMethodGtk::GetInputLocale() { - // Not supported. - return std::string(""); -} - -base::i18n::TextDirection InputMethodGtk::GetInputTextDirection() { - // Not supported. - return base::i18n::UNKNOWN_DIRECTION; -} - -bool InputMethodGtk::IsActive() { - // We always need to send keyboard events to either |context_| or - // |context_simple_|, so just return true here. - return true; -} - -void InputMethodGtk::OnWillChangeFocus(View* focused_before, View* focused) { - ConfirmCompositionText(); -} - -void InputMethodGtk::OnDidChangeFocus(View* focused_before, View* focused) { - UpdateContextFocusState(); - - // Force to update caret bounds, in case the View thinks that the caret - // bounds has not changed. - if (context_focused_) - OnCaretBoundsChanged(GetFocusedView()); -} - -void InputMethodGtk::ConfirmCompositionText() { - ui::TextInputClient* client = GetTextInputClient(); - if (client && client->HasCompositionText()) - client->ConfirmCompositionText(); - - ResetContext(); -} - -void InputMethodGtk::ResetContext() { - if (!GetTextInputClient()) - return; - - DCHECK(widget_focused()); - DCHECK(GetFocusedView()); - DCHECK(!handling_key_event_); - - // To prevent any text from being committed when resetting the |context_|; - handling_key_event_ = true; - suppress_next_result_ = true; - - gtk_im_context_reset(context_); - gtk_im_context_reset(context_simple_); - - // Some input methods may not honour the reset call. Focusing out/in the - // |context_| to make sure it gets reset correctly. - if (context_focused_) { - gtk_im_context_focus_out(context_); - gtk_im_context_focus_in(context_); - } - - composition_.Clear(); - result_text_.clear(); - handling_key_event_ = false; - composing_text_ = false; - composition_changed_ = false; -} - -void InputMethodGtk::UpdateContextFocusState() { - bool old_context_focused = context_focused_; - // Use switch here in case we are going to add more text input types. - switch (GetTextInputType()) { - case ui::TEXT_INPUT_TYPE_NONE: - case ui::TEXT_INPUT_TYPE_PASSWORD: - context_focused_ = false; - break; - default: - context_focused_ = true; - break; - } - - // We only focus in |context_| when the focus is in a normal textfield. - if (old_context_focused && !context_focused_) - gtk_im_context_focus_out(context_); - else if (!old_context_focused && context_focused_) - gtk_im_context_focus_in(context_); - - // |context_simple_| can be used in any textfield, including password box, and - // even if the focused text input client's text input type is - // ui::TEXT_INPUT_TYPE_NONE. - if (GetTextInputClient()) - gtk_im_context_focus_in(context_simple_); - else - gtk_im_context_focus_out(context_simple_); -} - -void InputMethodGtk::ProcessFilteredKeyPressEvent(const KeyEvent& key) { - if (NeedInsertChar()) { - DispatchKeyEventPostIME(key); - } else { - KeyEvent key(ui::ET_KEY_PRESSED, ui::VKEY_PROCESSKEY, key.flags()); - DispatchKeyEventPostIME(key); - } -} - -void InputMethodGtk::ProcessUnfilteredKeyPressEvent(const KeyEvent& key) { - const View* old_focused_view = GetFocusedView(); - DispatchKeyEventPostIME(key); - - // We shouldn't dispatch the character anymore if the key event caused focus - // change. - if (old_focused_view != GetFocusedView()) - return; - - // If a key event was not filtered by |context_| or |context_simple_|, then - // it means the key event didn't generate any result text. For some cases, - // the key event may still generate a valid character, eg. a control-key - // event (ctrl-a, return, tab, etc.). We need to send the character to the - // focused text input client by calling TextInputClient::InsertChar(). - char16 ch = key.GetCharacter(); - ui::TextInputClient* client = GetTextInputClient(); - if (ch && client) - client->InsertChar(ch, key.flags()); -} - -void InputMethodGtk::ProcessInputMethodResult(const KeyEvent& key, - bool filtered) { - ui::TextInputClient* client = GetTextInputClient(); - DCHECK(client); - - if (result_text_.length()) { - if (filtered && NeedInsertChar()) { - for (string16::const_iterator i = result_text_.begin(); - i != result_text_.end(); ++i) { - client->InsertChar(*i, key.flags()); - } - } else { - client->InsertText(result_text_); - composing_text_ = false; - } - } - - if (composition_changed_ && !IsTextInputTypeNone()) { - if (composition_.text.length()) { - composing_text_ = true; - client->SetCompositionText(composition_); - } else if (result_text_.empty()) { - client->ClearCompositionText(); - } - } -} - -bool InputMethodGtk::NeedInsertChar() const { - return IsTextInputTypeNone() || - (!composing_text_ && result_text_.length() == 1); -} - -bool InputMethodGtk::HasInputMethodResult() const { - return result_text_.length() || composition_changed_; -} - -void InputMethodGtk::SendFakeProcessKeyEvent(bool pressed) const { - KeyEvent key(pressed ? ui::ET_KEY_PRESSED : ui::ET_KEY_RELEASED, - ui::VKEY_PROCESSKEY, 0); - DispatchKeyEventPostIME(key); -} - -GdkEvent* InputMethodGtk::SynthesizeGdkEventKey(const KeyEvent& key) const { - guint keyval = - ui::GdkKeyCodeForWindowsKeyCode(key.key_code(), key.IsShiftDown()); - guint state = 0; - state |= key.IsShiftDown() ? GDK_SHIFT_MASK : 0; - state |= key.IsControlDown() ? GDK_CONTROL_MASK : 0; - state |= key.IsAltDown() ? GDK_MOD1_MASK : 0; - state |= key.IsCapsLockDown() ? GDK_LOCK_MASK : 0; - - DCHECK(widget()->GetNativeView()->window); - return ui::SynthesizeKeyEvent(widget()->GetNativeView()->window, - key.type() == ui::ET_KEY_PRESSED, - keyval, state); -} - -void InputMethodGtk::OnCommit(GtkIMContext* context, gchar* text) { - if (suppress_next_result_) { - suppress_next_result_ = false; - return; - } - - // We need to receive input method result even if the text input type is - // ui::TEXT_INPUT_TYPE_NONE, to make sure we can always send correct - // character for each key event to the focused text input client. - if (!GetTextInputClient()) - return; - - string16 utf16_text(UTF8ToUTF16(text)); - - // Append the text to the buffer, because commit signal might be fired - // multiple times when processing a key event. - result_text_.append(utf16_text); - - // If we are not handling key event, do not bother sending text result if the - // focused text input client does not support text input. - if (!handling_key_event_ && !IsTextInputTypeNone()) { - SendFakeProcessKeyEvent(true); - GetTextInputClient()->InsertText(utf16_text); - SendFakeProcessKeyEvent(false); - } -} - -void InputMethodGtk::OnPreeditStart(GtkIMContext* context) { - if (suppress_next_result_ || IsTextInputTypeNone()) - return; - - composing_text_ = true; -} - -void InputMethodGtk::OnPreeditChanged(GtkIMContext* context) { - if (suppress_next_result_ || IsTextInputTypeNone()) - return; - - gchar* text = NULL; - PangoAttrList* attrs = NULL; - gint cursor_position = 0; - gtk_im_context_get_preedit_string(context, &text, &attrs, &cursor_position); - - ui::ExtractCompositionTextFromGtkPreedit(text, attrs, cursor_position, - &composition_); - composition_changed_ = true; - - g_free(text); - pango_attr_list_unref(attrs); - - if (composition_.text.length()) - composing_text_ = true; - - if (!handling_key_event_ && !IsTextInputTypeNone()) { - SendFakeProcessKeyEvent(true); - GetTextInputClient()->SetCompositionText(composition_); - SendFakeProcessKeyEvent(false); - } -} - -void InputMethodGtk::OnPreeditEnd(GtkIMContext* context) { - if (composition_.text.empty() || IsTextInputTypeNone()) - return; - - composition_changed_ = true; - composition_.Clear(); - - if (!handling_key_event_) { - ui::TextInputClient* client = GetTextInputClient(); - if (client && client->HasCompositionText()) - client->ClearCompositionText(); - } -} - -void InputMethodGtk::OnWidgetRealize(GtkWidget* widget) { - // We should only set im context's client window once, because when setting - // client window, im context may destroy and recreate its internal states and - // objects. - if (widget->window) { - gtk_im_context_set_client_window(context_, widget->window); - gtk_im_context_set_client_window(context_simple_, widget->window); - } -} - -void InputMethodGtk::OnWidgetUnrealize(GtkWidget* widget) { - gtk_im_context_set_client_window(context_, NULL); - gtk_im_context_set_client_window(context_simple_, NULL); -} - -} // namespace views diff --git a/ui/views/ime/input_method_gtk.h b/ui/views/ime/input_method_gtk.h deleted file mode 100644 index ddb9f240..0000000 --- a/ui/views/ime/input_method_gtk.h +++ /dev/null @@ -1,123 +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_VIEWS_IME_INPUT_METHOD_GTK_H_ -#define UI_VIEWS_IME_INPUT_METHOD_GTK_H_ -#pragma once - -#include <gtk/gtk.h> - -#include "base/basictypes.h" -#include "base/compiler_specific.h" -#include "ui/base/gtk/gtk_signal.h" -#include "ui/base/ime/composition_text.h" -#include "ui/base/ime/text_input_client.h" -#include "ui/views/ime/input_method_base.h" -#include "ui/views/view.h" - -namespace views { - -// An InputMethod implementation based on GtkIMContext. Most code are copied -// from chrome/browser/renderer_host/gtk_im_context_wrapper.* -// It's intended for testing purpose. -class InputMethodGtk : public InputMethodBase { - public: - explicit InputMethodGtk(internal::InputMethodDelegate* delegate); - virtual ~InputMethodGtk(); - - // Overridden from InputMethod: - virtual void Init(Widget* widget) OVERRIDE; - virtual void OnFocus() OVERRIDE; - virtual void OnBlur() OVERRIDE; - virtual void DispatchKeyEvent(const KeyEvent& key) OVERRIDE; - virtual void OnTextInputTypeChanged(View* view) OVERRIDE; - virtual void OnCaretBoundsChanged(View* view) OVERRIDE; - virtual void CancelComposition(View* view) OVERRIDE; - virtual std::string GetInputLocale() OVERRIDE; - virtual base::i18n::TextDirection GetInputTextDirection() OVERRIDE; - virtual bool IsActive() OVERRIDE; - - private: - // Overridden from InputMethodBase: - virtual void OnWillChangeFocus(View* focused_before, View* focused) OVERRIDE; - virtual void OnDidChangeFocus(View* focused_before, View* focused) OVERRIDE; - - // Asks the client to confirm current composition text. - void ConfirmCompositionText(); - - // Resets |context_| and |context_simple_|. - void ResetContext(); - - // Checks the availability of focused text input client and update focus state - // of |context_| and |context_simple_| accordingly. - void UpdateContextFocusState(); - - // Processes a key event that was already filtered by the input method. - // A VKEY_PROCESSKEY may be dispatched to the focused View. - void ProcessFilteredKeyPressEvent(const KeyEvent& key); - - // Processes a key event that was not filtered by the input method. - void ProcessUnfilteredKeyPressEvent(const KeyEvent& key); - - // Sends input method result caused by the given key event to the focused text - // input client. - void ProcessInputMethodResult(const KeyEvent& key, bool filtered); - - // Checks if the pending input method result needs inserting into the focused - // text input client as a single character. - bool NeedInsertChar() const; - - // Checks if there is pending input method result. - bool HasInputMethodResult() const; - - // Fabricates a key event with VKEY_PROCESSKEY key code and dispatches it to - // the focused View. - void SendFakeProcessKeyEvent(bool pressed) const; - - // Synthesize a GdkEventKey based on given key event. The returned GdkEventKey - // must be freed with gdk_event_free(). - GdkEvent* SynthesizeGdkEventKey(const KeyEvent& key) const; - - // Event handlers: - CHROMEG_CALLBACK_1(InputMethodGtk, void, OnCommit, GtkIMContext*, gchar*); - CHROMEG_CALLBACK_0(InputMethodGtk, void, OnPreeditStart, GtkIMContext*); - CHROMEG_CALLBACK_0(InputMethodGtk, void, OnPreeditChanged, GtkIMContext*); - CHROMEG_CALLBACK_0(InputMethodGtk, void, OnPreeditEnd, GtkIMContext*); - - CHROMEGTK_CALLBACK_0(InputMethodGtk, void, OnWidgetRealize); - CHROMEGTK_CALLBACK_0(InputMethodGtk, void, OnWidgetUnrealize); - - GtkIMContext* context_; - GtkIMContext* context_simple_; - - ui::CompositionText composition_; - - string16 result_text_; - - // Signal ids for corresponding gtk signals. - gulong widget_realize_id_; - gulong widget_unrealize_id_; - - // Indicates if |context_| and |context_simple_| are focused or not. - bool context_focused_; - - // Indicates if we are handling a key event. - bool handling_key_event_; - - // Indicates if there is an ongoing composition text. - bool composing_text_; - - // Indicates if the composition text is changed or deleted. - bool composition_changed_; - - // If it's true then all input method result received before the next key - // event will be discarded. - bool suppress_next_result_; - - DISALLOW_COPY_AND_ASSIGN(InputMethodGtk); -}; - -} // namespace views - -#endif // UI_VIEWS_IME_INPUT_METHOD_GTK_H_ diff --git a/ui/views/metrics_gtk.cc b/ui/views/metrics_gtk.cc deleted file mode 100644 index b874bae..0000000 --- a/ui/views/metrics_gtk.cc +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/metrics.h" - -#include <gtk/gtk.h> - -namespace views { - -int GetDoubleClickInterval() { - GdkDisplay* display = gdk_display_get_default(); - return display ? display->double_click_time : 500; -} - -int GetMenuShowDelay() { - return kDefaultMenuShowDelay; -} - -} // namespace views diff --git a/ui/views/view_gtk.cc b/ui/views/view_gtk.cc deleted file mode 100644 index 459cd31..0000000 --- a/ui/views/view_gtk.cc +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/view.h" - -#include <gtk/gtk.h> - -#include "base/logging.h" - -namespace views { - -gfx::NativeViewAccessible View::GetNativeViewAccessible() { - NOTIMPLEMENTED(); - return NULL; -} - -int View::GetHorizontalDragThreshold() { - static bool determined_threshold = false; - static int drag_threshold = 8; - if (determined_threshold) - return drag_threshold; - determined_threshold = true; - GtkSettings* settings = gtk_settings_get_default(); - if (!settings) - return drag_threshold; - int value = 0; - g_object_get(G_OBJECT(settings), "gtk-dnd-drag-threshold", &value, NULL); - if (value) - drag_threshold = value; - return drag_threshold; -} - -int View::GetVerticalDragThreshold() { - // Vertical and horizontal drag threshold are the same in Gtk. - return GetHorizontalDragThreshold(); -} - -} // namespace views diff --git a/ui/views/views.gyp b/ui/views/views.gyp index b53012f..5823fbc 100644 --- a/ui/views/views.gyp +++ b/ui/views/views.gyp @@ -15,7 +15,6 @@ ]}], ['use_aura==1', { 'sources/': [ ['exclude', '_win\\.(h|cc)$'], - ['exclude', '_gtk\\.(h|cc)$'], ['exclude', '_x\\.(h|cc)$'] ], 'dependencies': [ '../aura/aura.gyp:aura', ], }], @@ -88,8 +87,6 @@ 'controls/combobox/combobox.cc', 'controls/combobox/combobox.h', 'controls/combobox/combobox_listener.h', - 'controls/combobox/native_combobox_gtk.cc', - 'controls/combobox/native_combobox_gtk.h', 'controls/combobox/native_combobox_views.cc', 'controls/combobox/native_combobox_views.h', 'controls/combobox/native_combobox_win.cc', @@ -119,8 +116,6 @@ 'controls/menu/menu_controller_delegate.h', 'controls/menu/menu_delegate.cc', 'controls/menu/menu_delegate.h', - 'controls/menu/menu_gtk.cc', - 'controls/menu/menu_gtk.h', 'controls/menu/menu_host.cc', 'controls/menu/menu_host.h', 'controls/menu/menu_host_root_view.cc', @@ -143,14 +138,10 @@ 'controls/menu/menu_win.cc', 'controls/menu/menu_win.h', 'controls/menu/menu_wrapper.h', - 'controls/menu/native_menu_gtk.cc', - 'controls/menu/native_menu_gtk.h', 'controls/menu/native_menu_host.h', 'controls/menu/native_menu_host_delegate.h', 'controls/menu/native_menu_win.cc', 'controls/menu/native_menu_win.h', - 'controls/menu/nested_dispatcher_gtk.cc', - 'controls/menu/nested_dispatcher_gtk.h', 'controls/menu/menu_image_util.cc', 'controls/menu/menu_image_util.h', 'controls/menu/submenu_view.cc', @@ -159,16 +150,12 @@ 'controls/message_box_view.h', 'controls/native_control.cc', 'controls/native_control.h', - 'controls/native_control_gtk.cc', - 'controls/native_control_gtk.h', 'controls/native_control_win.cc', 'controls/native_control_win.h', 'controls/native/native_view_host.cc', 'controls/native/native_view_host.h', 'controls/native/native_view_host_aura.cc', 'controls/native/native_view_host_aura.h', - 'controls/native/native_view_host_gtk.cc', - 'controls/native/native_view_host_gtk.h', 'controls/native/native_view_host_win.cc', 'controls/native/native_view_host_win.h', 'controls/progress_bar.cc', @@ -186,8 +173,6 @@ 'controls/scrollbar/base_scroll_bar_thumb.h', 'controls/scrollbar/bitmap_scroll_bar.cc', 'controls/scrollbar/bitmap_scroll_bar.h', - 'controls/scrollbar/native_scroll_bar_gtk.cc', - 'controls/scrollbar/native_scroll_bar_gtk.h', 'controls/scrollbar/native_scroll_bar_views.cc', 'controls/scrollbar/native_scroll_bar_views.h', 'controls/scrollbar/native_scroll_bar_win.cc', @@ -204,8 +189,6 @@ 'controls/single_split_view_listener.h', 'controls/slider.cc', 'controls/slider.h', - 'controls/tabbed_pane/native_tabbed_pane_gtk.cc', - 'controls/tabbed_pane/native_tabbed_pane_gtk.h', 'controls/tabbed_pane/native_tabbed_pane_views.cc', 'controls/tabbed_pane/native_tabbed_pane_views.h', 'controls/tabbed_pane/native_tabbed_pane_win.cc', @@ -226,12 +209,6 @@ 'controls/table/table_view_views.h', 'controls/table/table_view_win.cc', 'controls/table/table_view_win.h', - 'controls/textfield/gtk_views_entry.cc', - 'controls/textfield/gtk_views_entry.h', - 'controls/textfield/gtk_views_textview.cc', - 'controls/textfield/gtk_views_textview.h', - 'controls/textfield/native_textfield_gtk.cc', - 'controls/textfield/native_textfield_gtk.h', 'controls/textfield/native_textfield_views.cc', 'controls/textfield/native_textfield_views.h', 'controls/textfield/native_textfield_win.cc', @@ -258,12 +235,10 @@ 'events/event.cc', 'events/event.h', 'events/event_aura.cc', - 'events/event_gtk.cc', 'events/event_win.cc', 'events/event_x.cc', 'focus/accelerator_handler.h', 'focus/accelerator_handler_aura.cc', - 'focus/accelerator_handler_gtk.cc', 'focus/accelerator_handler_win.cc', 'focus/external_focus_tracker.cc', 'focus/external_focus_tracker.h', @@ -282,8 +257,6 @@ 'ime/input_method_bridge.cc', 'ime/input_method_bridge.h', 'ime/input_method_delegate.h', - 'ime/input_method_gtk.cc', - 'ime/input_method_gtk.h', 'ime/input_method.h', 'ime/input_method_win.cc', 'ime/input_method_win.h', @@ -303,7 +276,6 @@ 'metrics.cc', 'metrics.h', 'metrics_aura.cc', - 'metrics_gtk.cc', 'metrics_win.cc', 'mouse_watcher.cc', 'mouse_watcher.h', @@ -327,7 +299,6 @@ 'view_constants.cc', 'view_constants.h', 'view_aura.cc', - 'view_gtk.cc', 'view_text_utils.cc', 'view_text_utils.h', 'view_win.cc', @@ -340,20 +311,12 @@ 'widget/default_theme_provider.h', 'widget/drop_helper.cc', 'widget/drop_helper.h', - 'widget/drop_target_gtk.cc', - 'widget/drop_target_gtk.h', 'widget/drop_target_win.cc', 'widget/drop_target_win.h', - 'widget/gtk_views_fixed.cc', - 'widget/gtk_views_fixed.h', - 'widget/gtk_views_window.cc', - 'widget/gtk_views_window.h', 'widget/root_view.cc', 'widget/root_view.h', 'widget/tooltip_manager_aura.cc', 'widget/tooltip_manager_aura.h', - 'widget/tooltip_manager_gtk.cc', - 'widget/tooltip_manager_gtk.h', 'widget/tooltip_manager_win.cc', 'widget/tooltip_manager_win.h', 'widget/tooltip_manager.cc', @@ -365,8 +328,6 @@ 'widget/native_widget_aura.h', 'widget/native_widget_delegate.h', 'widget/native_widget_private.h', - 'widget/native_widget_gtk.cc', - 'widget/native_widget_gtk.h', 'widget/native_widget_win.cc', 'widget/native_widget_win.h', 'widget/widget.cc', @@ -397,8 +358,8 @@ 'conditions': [ ['use_aura==1', { 'sources/': [ - ['exclude', '_(gtk|x)\\.cc$'], - ['exclude', '/(gtk|x)_[^/]*\\.cc$'], + ['exclude', '_x\\.cc$'], + ['exclude', '/x_[^/]*\\.cc$'], ['exclude', 'controls/menu/menu_2.*'], ], 'sources!': [ @@ -427,25 +388,6 @@ }], ], }], - ['toolkit_uses_gtk == 1', { - 'dependencies': [ - '../../build/linux/system.gyp:gtk', - '../../build/linux/system.gyp:x11', - '../../build/linux/system.gyp:xext', - ], - 'sources!': [ - 'accessibility/native_view_accessibility_win.cc', - 'controls/native_control.cc', - 'controls/scrollbar/bitmap_scroll_bar.cc', - 'controls/table/group_table_model.cc', - 'controls/tree/tree_view.h', - 'events/event_win.cc', - 'widget/aero_tooltip_manager.cc', - 'widget/child_window_message_processor.cc', - 'widget/child_window_message_processor.h', - 'widget/native_widget_win.cc', - ], - }], ['use_aura==0', { 'sources!': [ 'controls/tabbed_pane/native_tabbed_pane_views.cc', @@ -528,7 +470,6 @@ 'controls/textfield/textfield_views_model_unittest.cc', 'controls/tree/tree_view_views_unittest.cc', 'events/event_unittest.cc', - 'focus/accelerator_handler_gtk_unittest.cc', 'focus/focus_manager_test.h', 'focus/focus_manager_test.cc', 'focus/focus_manager_unittest.cc', @@ -545,7 +486,6 @@ 'widget/native_widget_aura_unittest.cc', 'widget/native_widget_test_utils.h', 'widget/native_widget_test_utils_aura.cc', - 'widget/native_widget_test_utils_gtk.cc', 'widget/native_widget_test_utils_win.cc', 'widget/native_widget_unittest.cc', 'widget/native_widget_win_unittest.cc', @@ -557,21 +497,6 @@ '<(SHARED_INTERMEDIATE_DIR)/ui/ui_resources_standard/ui_resources_standard.rc', ], 'conditions': [ - ['toolkit_uses_gtk == 1', { - 'dependencies': [ - '../../build/linux/system.gyp:gtk', - ], - 'conditions': [ - ['linux_use_tcmalloc==1', { - 'dependencies': [ - '../../base/allocator/allocator.gyp:allocator', - ], - }], - ], - 'sources/': [ - ['exclude', 'controls/table/table_view_unittest.cc'], - ], - }], ['OS=="win"', { 'link_settings': { 'libraries': [ @@ -714,19 +639,6 @@ '<(SHARED_INTERMEDIATE_DIR)/ui/ui_resources_standard/ui_resources_standard.rc', ], 'conditions': [ - ['toolkit_uses_gtk == 1', { - 'dependencies': [ - '../../build/linux/system.gyp:gtk', - ], - 'conditions': [ - ['linux_use_tcmalloc==1', { - 'dependencies': [ - '../../base/allocator/allocator.gyp:allocator', - ], - }], - ], - }, - ], ['OS=="win"', { 'link_settings': { 'libraries': [ diff --git a/ui/views/widget/drop_target_gtk.cc b/ui/views/widget/drop_target_gtk.cc deleted file mode 100644 index f5b3102..0000000 --- a/ui/views/widget/drop_target_gtk.cc +++ /dev/null @@ -1,329 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/widget/drop_target_gtk.h" - -#include <algorithm> -#include <iterator> -#include <string> -#include <vector> - -#include "base/file_path.h" -#include "base/utf_string_conversions.h" -#include "net/base/net_util.h" -#include "ui/base/dragdrop/drag_drop_types.h" -#include "ui/base/dragdrop/gtk_dnd_util.h" -#include "ui/base/dragdrop/os_exchange_data_provider_gtk.h" -#include "ui/gfx/point.h" -#include "ui/views/widget/native_widget_gtk.h" -#include "ui/views/widget/root_view.h" - -using ui::OSExchangeData; - -namespace { - -std::string GdkAtomToString(GdkAtom atom) { - gchar* c_name = gdk_atom_name(atom); - std::string name(c_name); - g_free(c_name); - return name; -} - -// Returns true if |name| is a known name of plain text. -bool IsTextType(const std::string& name) { - return name == "text/plain" || name == "TEXT" || - name == "STRING" || name == "UTF8_STRING" || - name == "text/plain;charset=utf-8"; -} - -// Returns the OSExchangeData::Formats in |targets| and all the -// OSExchangeData::CustomFormats in |type_set|. -int CalculateTypes(GList* targets, std::set<GdkAtom>* type_set) { - int types = 0; - for (GList* element = targets; element; - element = g_list_next(element)) { - GdkAtom atom = static_cast<GdkAtom>(element->data); - type_set->insert(atom); - if (atom == GDK_TARGET_STRING) { - types |= OSExchangeData::STRING; - } else if (atom == ui::GetAtomForTarget(ui::CHROME_NAMED_URL)) { - types |= OSExchangeData::URL; - } else if (atom == ui::GetAtomForTarget(ui::TEXT_URI_LIST)) { - // TEXT_URI_LIST is used for files as well as urls. - types |= OSExchangeData::URL | OSExchangeData::FILE_NAME; - } else { - std::string target_name = GdkAtomToString(atom); - if (IsTextType(target_name)) { - types |= OSExchangeData::STRING; - } else { - // Assume any unknown data is pickled. - types |= OSExchangeData::PICKLED_DATA; - } - } - } - return types; -} - -} // namespace - -namespace views { - -DropTargetGtk::DropTargetGtk(internal::RootView* root_view, - GdkDragContext* context) - : helper_(root_view), - requested_formats_(0), - waiting_for_data_(false), - received_drop_(false), - pending_view_(NULL) { - std::set<GdkAtom> all_formats; - int source_formats = CalculateTypes(context->targets, &all_formats); - data_.reset(new OSExchangeData(new OSExchangeDataProviderGtk( - source_formats, all_formats))); -} - -DropTargetGtk::~DropTargetGtk() { -} - -void DropTargetGtk::ResetTargetViewIfEquals(View* view) { - helper_.ResetTargetViewIfEquals(view); -} - -void DropTargetGtk::OnDragDataReceived(GdkDragContext* context, - gint x, - gint y, - GtkSelectionData* data, - guint info, - guint time) { - std::string target_name = GdkAtomToString(data->type); - if (data->type == GDK_TARGET_STRING || IsTextType(target_name)) { - guchar* text_data = gtk_selection_data_get_text(data); - string16 result; - if (text_data) { - char* as_char = reinterpret_cast<char*>(text_data); - UTF8ToUTF16(as_char, strlen(as_char), &result); - g_free(text_data); - } - data_provider().SetString(result); - } else if (requested_custom_formats_.find(data->type) != - requested_custom_formats_.end()) { - Pickle result; - if (data->length > 0) - result = Pickle(reinterpret_cast<char*>(data->data), data->length); - data_provider().SetPickledData(data->type, result); - } else if (data->type == ui::GetAtomForTarget(ui::CHROME_NAMED_URL)) { - GURL url; - string16 title; - ui::ExtractNamedURL(data, &url, &title); - data_provider().SetURL(url, title); - } else if (data->type == ui::GetAtomForTarget(ui::TEXT_URI_LIST)) { - std::vector<GURL> urls; - ui::ExtractURIList(data, &urls); - if (urls.size() == 1 && urls[0].is_valid()) { - data_provider().SetURL(urls[0], string16()); - - // TEXT_URI_LIST is used for files as well as urls. - if (urls[0].SchemeIsFile()) { - FilePath file_path; - if (net::FileURLToFilePath(urls[0], &file_path)) - data_provider().SetFilename(file_path); - } - } else { - // Consumers of OSExchangeData will see this as an invalid URL. That is, - // when GetURL is invoked on the OSExchangeData this triggers false to - // be returned. - data_provider().SetURL(GURL(), string16()); - } - } - - if (!data_->HasAllFormats(requested_formats_, requested_custom_formats_)) - return; // Waiting on more data. - - int drag_operation = ui::DragDropTypes::GdkDragActionToDragOperation( - context->actions); - gfx::Point root_view_location(x, y); - drag_operation = helper_.OnDragOver(*data_, root_view_location, - drag_operation); - GdkDragAction gdk_action = static_cast<GdkDragAction>( - ui::DragDropTypes::DragOperationToGdkDragAction(drag_operation)); - if (!received_drop_) - gdk_drag_status(context, gdk_action, time); - - waiting_for_data_ = false; - - if (pending_view_ && received_drop_) { - FinishDrop(context, x, y, time); - // WARNING: we've been deleted. - return; - } -} - -gboolean DropTargetGtk::OnDragDrop(GdkDragContext* context, - gint x, - gint y, - guint time) { - received_drop_ = true; - OnDragMotion(context, x, y, time); - if (!pending_view_) { - // User isn't over a view, no drop can occur. - static_cast<NativeWidgetGtk*>( - helper_.root_view()->GetWidget()->native_widget())->ResetDropTarget(); - // WARNING: we've been deleted. - return FALSE; - } - - if (!waiting_for_data_) { - // We've got all the data now. - FinishDrop(context, x, y, time); - // WARNING: we've been deleted. - return TRUE; - } - // We're waiting on data. - return TRUE; -} - -void DropTargetGtk::OnDragLeave(GdkDragContext* context, guint time) { - helper_.OnDragExit(); -} - -gboolean DropTargetGtk::OnDragMotion(GdkDragContext* context, - gint x, - gint y, - guint time) { - waiting_for_data_ = false; - gfx::Point root_view_location(x, y); - pending_view_ = - helper_.CalculateTargetView(root_view_location, *data_, false); - if (pending_view_ && - (received_drop_ || (pending_view_ != helper_.target_view() && - pending_view_->AreDropTypesRequired()))) { - // The target requires drop types before it can answer CanDrop, - // ask for the data now. - int formats = 0; - std::set<GdkAtom> custom_formats; - pending_view_->GetDropFormats(&formats, &custom_formats); - IntersectFormats(data_provider().known_formats(), - data_provider().known_custom_formats(), - &formats, &custom_formats); - if (!data_provider().HasDataForAllFormats(formats, custom_formats)) { - if (!received_drop_) - helper_.OnDragExit(); - - // The target needs data for all the types before it can test if the - // drop is valid, but we don't have all the data. Request the data - // now. When we get back the data we'll update the target. - RequestFormats(context, formats, custom_formats, time); - - waiting_for_data_ = true; - - return TRUE; - } - } - - int drag_operation = ui::DragDropTypes::GdkDragActionToDragOperation( - context->actions); - drag_operation = helper_.OnDragOver(*data_, root_view_location, - drag_operation); - if (!received_drop_) { - GdkDragAction gdk_action = - static_cast<GdkDragAction>( - ui::DragDropTypes::DragOperationToGdkDragAction(drag_operation)); - gdk_drag_status(context, gdk_action, time); - } - return TRUE; -} - -void DropTargetGtk::FinishDrop(GdkDragContext* context, - gint x, gint y, guint time) { - gfx::Point root_view_location(x, y); - int drag_operation = ui::DragDropTypes::GdkDragActionToDragOperation( - context->actions); - drag_operation = helper_.OnDrop(*data_, root_view_location, - drag_operation); - GdkDragAction gdk_action = - static_cast<GdkDragAction>( - ui::DragDropTypes::DragOperationToGdkDragAction(drag_operation)); - gtk_drag_finish(context, gdk_action != 0, (gdk_action & GDK_ACTION_MOVE), - time); - - static_cast<NativeWidgetGtk*>(helper_.root_view()->GetWidget()-> - native_widget())->ResetDropTarget(); - // WARNING: we've been deleted. -} - -void DropTargetGtk::IntersectFormats(int f1, const std::set<GdkAtom>& cf1, - int* f2, std::set<GdkAtom>* cf2) { - *f2 = (*f2 & f1); - std::set<GdkAtom> cf; - std::set_intersection( - cf1.begin(), cf1.end(), cf2->begin(), cf2->end(), - std::insert_iterator<std::set<GdkAtom> >(cf, cf.begin())); - cf.swap(*cf2); -} - -void DropTargetGtk::RequestFormats(GdkDragContext* context, - int formats, - const std::set<GdkAtom>& custom_formats, - guint time) { - GtkWidget* widget = static_cast<NativeWidgetGtk*>(helper_.root_view()-> - GetWidget()->native_widget())->window_contents(); - - const std::set<GdkAtom>& known_formats = - data_provider().known_custom_formats(); - if ((formats & OSExchangeData::STRING) != 0 && - (requested_formats_ & OSExchangeData::STRING) == 0) { - requested_formats_ |= OSExchangeData::STRING; - if (known_formats.count(gdk_atom_intern("UTF8_STRING", false))) { - gtk_drag_get_data(widget, context, - gdk_atom_intern("UTF8_STRING", false), time); - } else if (known_formats.count(gdk_atom_intern("text/plain;charset=utf-8", - false))) { - gtk_drag_get_data(widget, context, - gdk_atom_intern("text/plain;charset=utf-8", false), - time); - } else if (known_formats.count(GDK_TARGET_STRING)) { - gtk_drag_get_data(widget, context, GDK_TARGET_STRING, time); - } else if (known_formats.count(gdk_atom_intern("text/plain", false))) { - gtk_drag_get_data(widget, context, gdk_atom_intern("text/plain", false), - time); - } else if (known_formats.count(gdk_atom_intern("TEXT", false))) { - gtk_drag_get_data(widget, context, gdk_atom_intern("TEXT", false), - time); - } else if (known_formats.count(gdk_atom_intern("STRING", false))) { - gtk_drag_get_data(widget, context, gdk_atom_intern("STRING", false), - time); - } - } - if ((formats & OSExchangeData::URL) != 0 && - (requested_formats_ & OSExchangeData::URL) == 0) { - requested_formats_ |= OSExchangeData::URL; - if (known_formats.count(ui::GetAtomForTarget(ui::CHROME_NAMED_URL))) { - gtk_drag_get_data(widget, context, - ui::GetAtomForTarget(ui::CHROME_NAMED_URL), time); - } else if (known_formats.count( - ui::GetAtomForTarget(ui::TEXT_URI_LIST))) { - gtk_drag_get_data(widget, context, - ui::GetAtomForTarget(ui::TEXT_URI_LIST), time); - } - } - if (((formats & OSExchangeData::FILE_NAME) != 0) && - (requested_formats_ & OSExchangeData::FILE_NAME) == 0) { - requested_formats_ |= OSExchangeData::FILE_NAME; - gtk_drag_get_data(widget, context, - ui::GetAtomForTarget(ui::TEXT_URI_LIST), time); - } - for (std::set<GdkAtom>::const_iterator i = custom_formats.begin(); - i != custom_formats.end(); ++i) { - if (requested_custom_formats_.find(*i) == - requested_custom_formats_.end()) { - requested_custom_formats_.insert(*i); - gtk_drag_get_data(widget, context, *i, time); - } - } -} - -OSExchangeDataProviderGtk& DropTargetGtk::data_provider() const { - return static_cast<OSExchangeDataProviderGtk&>(data_->provider()); -} - -} // namespace views diff --git a/ui/views/widget/drop_target_gtk.h b/ui/views/widget/drop_target_gtk.h deleted file mode 100644 index bf324af..0000000 --- a/ui/views/widget/drop_target_gtk.h +++ /dev/null @@ -1,120 +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_VIEWS_WIDGET_DROP_TARGET_GTK_H_ -#define UI_VIEWS_WIDGET_DROP_TARGET_GTK_H_ -#pragma once - -#include <gtk/gtk.h> -#include <set> - -#include "base/memory/scoped_ptr.h" -#include "ui/base/dragdrop/os_exchange_data.h" -#include "ui/views/widget/drop_helper.h" - -namespace ui { -class OSExchangeDataProviderGtk; -} -using ui::OSExchangeData; -using ui::OSExchangeDataProviderGtk; - -namespace views { - -class View; -namespace internal { -class RootView; -} - -// DropTarget implementation for Gtk. -// -// The data for a drop is not immediately available on X. As such we lazily -// ask for data as necessary. Some Views require data before they can determine -// if the drop is going to be allowed. When such a View is encountered the -// relevant data is requested from the drag source. When the data is available -// the target is notified. Similarly if the drop completes and the data has -// not yet been fetched, it is fetched and the target then notified. -// -// When a drop finishes this class calls back to the containing NativeWidgetGtk -// which results in deleting the DropTargetGtk. -class DropTargetGtk { - public: - DropTargetGtk(internal::RootView* root_view, GdkDragContext* context); - ~DropTargetGtk(); - - // If a drag and drop is underway and |view| is the current drop target, the - // drop target is set to null. - // This is invoked when a View is removed from the RootView to make sure - // we don't target a view that was removed during dnd. - void ResetTargetViewIfEquals(View* view); - - // Drop methods from Gtk. These are forwarded from the containing - // NativeWidgetGtk. - void OnDragDataReceived(GdkDragContext* context, - gint x, - gint y, - GtkSelectionData* data, - guint info, - guint time); - gboolean OnDragDrop(GdkDragContext* context, - gint x, - gint y, - guint time); - void OnDragLeave(GdkDragContext* context, guint time); - gboolean OnDragMotion(GdkDragContext* context, - gint x, - gint y, - guint time); - - private: - // Invoked when the drop finishes AND all the data is available. - void FinishDrop(GdkDragContext* context, gint x, gint y, guint time); - - // Returns in |f2| and |cf2| the intersection of |f1| |f2| and - // |cf1|, |cf2|. - void IntersectFormats(int f1, const std::set<GdkAtom>& cf1, - int* f2, std::set<GdkAtom>* cf2); - - // Requests the formats in |formats| and the custom formats in - // |custom_formats|. - void RequestFormats(GdkDragContext* context, - int formats, - const std::set<GdkAtom>& custom_formats, - guint time); - - // Reutrns the Provider of the OSExchangeData we created. - OSExchangeDataProviderGtk& data_provider() const; - - // Manages sending the appropriate drop methods to the view the drop is over. - DropHelper helper_; - - // The formats we've requested from the drag source. - // - // NOTE: these formats are the intersection of the formats requested by the - // drop target and the formats provided by the source. - int requested_formats_; - std::set<GdkAtom> requested_custom_formats_; - - // The data. - scoped_ptr<OSExchangeData> data_; - - // Are we waiting for data from the source before we can notify the view? - // This is set in two distinct ways: when the view requires the data before - // it can answer Can Drop (that is, AreDropTypesRequired returns true) and - // when the user dropped the data but we didn't get it all yet. - bool waiting_for_data_; - - // Has OnDragDrop been invoked? - bool received_drop_; - - // The view under the mouse. This is not necessarily the same as - // helper_.target_view(). The two differ if the view under the mouse requires - // the data. - View* pending_view_; - - DISALLOW_COPY_AND_ASSIGN(DropTargetGtk); -}; - -} // namespace views - -#endif // UI_VIEWS_WIDGET_DROP_TARGET_GTK_H_ diff --git a/ui/views/widget/gtk_views_fixed.cc b/ui/views/widget/gtk_views_fixed.cc deleted file mode 100644 index 60aed5c..0000000 --- a/ui/views/widget/gtk_views_fixed.cc +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/widget/gtk_views_fixed.h" - -#include "base/logging.h" - -// We store whether we use the widget's allocated size as a property. Ideally -// we would stash this in GtkFixedChild, but GtkFixed doesn't allow subclassing -// gtk_fixed_put. Alternatively we could subclass GtkContainer and use our own -// API (effectively duplicating GtkFixed), but that means folks could no longer -// use the GtkFixed API else where in Chrome. For now I'm going with this route. -static const char* kUseAllocatedSize = "__VIEWS_USE_ALLOCATED_SIZE__"; -static const char* kRequisitionWidth = "__VIEWS_REQUISITION_WIDTH__"; -static const char* kRequisitionHeight = "__VIEWS_REQUISITION_HEIGHT__"; - -G_BEGIN_DECLS - -G_DEFINE_TYPE(GtkViewsFixed, gtk_views_fixed, GTK_TYPE_FIXED) - -static void gtk_views_fixed_size_allocate(GtkWidget* widget, - GtkAllocation* allocation) { - widget->allocation = *allocation; - if (!GTK_WIDGET_NO_WINDOW(widget) && GTK_WIDGET_REALIZED(widget)) { - gdk_window_move_resize(widget->window, allocation->x, allocation->y, - allocation->width, allocation->height); - } - - int border_width = GTK_CONTAINER(widget)->border_width; - GList* children = GTK_FIXED(widget)->children; - while (children) { - GtkFixedChild* child = reinterpret_cast<GtkFixedChild*>(children->data); - children = children->next; - - if (GTK_WIDGET_VISIBLE(child->widget)) { - GtkAllocation child_allocation; - - int width, height; - bool use_allocated_size = - gtk_views_fixed_get_widget_size(child->widget, &width, &height); - if (use_allocated_size) { - // NOTE: even though the size isn't changing, we have to call - // size_allocate, otherwise things like buttons won't repaint. - child_allocation.width = width; - child_allocation.height = height; - } else { - GtkRequisition child_requisition; - gtk_widget_get_child_requisition(child->widget, &child_requisition); - child_allocation.width = child_requisition.width; - child_allocation.height = child_requisition.height; - } - child_allocation.x = child->x + border_width; - child_allocation.y = child->y + border_width; - - if (GTK_WIDGET_NO_WINDOW(widget)) { - child_allocation.x += widget->allocation.x; - child_allocation.y += widget->allocation.y; - } - - gtk_widget_size_allocate(child->widget, &child_allocation); - } - } -} - -static void gtk_views_fixed_class_init(GtkViewsFixedClass* views_fixed_class) { - GtkWidgetClass* widget_class = - reinterpret_cast<GtkWidgetClass*>(views_fixed_class); - widget_class->size_allocate = gtk_views_fixed_size_allocate; -} - -static void gtk_views_fixed_init(GtkViewsFixed* fixed) { - GTK_WIDGET_SET_FLAGS(GTK_WIDGET(fixed), GTK_CAN_FOCUS); -} - -GtkWidget* gtk_views_fixed_new(void) { - return GTK_WIDGET(g_object_new(GTK_TYPE_VIEWS_FIXED, NULL)); -} - -void gtk_views_fixed_set_widget_size(GtkWidget* widget, - int width, int height) { - // Remember the allocation request, and set this widget up to use it. - bool use_requested_size = (width != 0 && height != 0); - g_object_set_data(G_OBJECT(widget), kUseAllocatedSize, - reinterpret_cast<gpointer>(use_requested_size ? 1 : 0)); - g_object_set_data(G_OBJECT(widget), kRequisitionWidth, - reinterpret_cast<gpointer>(width)); - g_object_set_data(G_OBJECT(widget), kRequisitionHeight, - reinterpret_cast<gpointer>(height)); - - gtk_widget_queue_resize(widget); -} - -bool gtk_views_fixed_get_widget_size(GtkWidget* widget, - int* width, int* height) { - DCHECK(width); - DCHECK(height); - *width = reinterpret_cast<glong>(g_object_get_data(G_OBJECT(widget), - kRequisitionWidth)); - *height = reinterpret_cast<glong>(g_object_get_data(G_OBJECT(widget), - kRequisitionHeight)); - return (g_object_get_data(G_OBJECT(widget), kUseAllocatedSize) != 0); -} - -G_END_DECLS diff --git a/ui/views/widget/gtk_views_fixed.h b/ui/views/widget/gtk_views_fixed.h deleted file mode 100644 index 4fadbbd..0000000 --- a/ui/views/widget/gtk_views_fixed.h +++ /dev/null @@ -1,56 +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_VIEWS_WIDGET_GTK_VIEWS_FIXED_H_ -#define UI_VIEWS_WIDGET_GTK_VIEWS_FIXED_H_ -#pragma once - -#include <gdk/gdk.h> -#include <gtk/gtkfixed.h> - -// GtkViewsFixed is a subclass of GtkFixed that can give child widgets -// a set size rather than their requisitioned size (which is actually -// a minimum size, and that can cause issues). This behavior is -// controlled by gtk_views_fixed_set_widget_size; the default is to -// use the Widget's requisitioned size. - -G_BEGIN_DECLS - -#define GTK_TYPE_VIEWS_FIXED (gtk_views_fixed_get_type ()) -#define GTK_VIEWS_FIXED(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_VIEWS_FIXED, GtkViewsFixed)) -#define GTK_VIEWS_FIXED_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_VIEWS_FIXED, GtkViewsFixedClass)) -#define GTK_IS_VIEWS_FIXED(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_VIEWS_FIXED)) -#define GTK_IS_VIEWS_FIXED_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_VIEWS_FIXED)) -#define GTK_VIEWS_FIXED_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_VIEWS_FIXED, GtkViewsFixed)) - -typedef struct _GtkViewsFixed GtkViewsFixed; -typedef struct _GtkViewsFixedClass GtkViewsFixedClass; - -struct _GtkViewsFixed { - GtkFixed fixed; -}; - -struct _GtkViewsFixedClass { - GtkFixedClass parent_class; -}; - -GtkWidget* gtk_views_fixed_new(); - -GType gtk_views_fixed_get_type(); - -// If width and height are 0, go back to using the requisitioned size. -// Queues up a re-size on the widget. -void gtk_views_fixed_set_widget_size(GtkWidget* widget, int width, int height); - -bool gtk_views_fixed_get_widget_size(GtkWidget* widget, - int* width, int* height); - -G_END_DECLS - -#endif // UI_VIEWS_WIDGET_GTK_VIEWS_FIXED_H_ diff --git a/ui/views/widget/gtk_views_window.cc b/ui/views/widget/gtk_views_window.cc deleted file mode 100644 index 6470850..0000000 --- a/ui/views/widget/gtk_views_window.cc +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <gtk/gtk.h> - -#include "ui/views/events/event.h" -#include "ui/views/focus/focus_manager.h" -#include "ui/views/widget/gtk_views_window.h" -#include "ui/views/widget/widget.h" - -G_BEGIN_DECLS - -G_DEFINE_TYPE(GtkViewsWindow, gtk_views_window, GTK_TYPE_WINDOW) - -static void gtk_views_window_move_focus(GtkWindow* window, - GtkDirectionType dir) { - views::Widget* widget = views::Widget::GetWidgetForNativeWindow(window); - views::FocusManager* focus_manager = - widget ? widget->GetFocusManager() : NULL; - if (focus_manager) { - GdkEvent* key = gtk_get_current_event(); - if (key && key->type == GDK_KEY_PRESS) { - views::KeyEvent key_event(key); - focus_manager->OnKeyEvent(key_event); - } - } else if (GTK_WINDOW_CLASS(gtk_views_window_parent_class)->move_focus) { - GTK_WINDOW_CLASS(gtk_views_window_parent_class)->move_focus(window, dir); - } -} - -static void gtk_views_window_class_init( - GtkViewsWindowClass* views_window_class) { - GtkWindowClass* window_class = - reinterpret_cast<GtkWindowClass*>(views_window_class); - window_class->move_focus = gtk_views_window_move_focus; -} - -static void gtk_views_window_init(GtkViewsWindow* window) { -} - -GtkWidget* gtk_views_window_new(GtkWindowType type) { - return GTK_WIDGET(g_object_new(GTK_TYPE_VIEWS_WINDOW, "type", type, NULL)); -} - -G_END_DECLS diff --git a/ui/views/widget/gtk_views_window.h b/ui/views/widget/gtk_views_window.h deleted file mode 100644 index 9c397c7..0000000 --- a/ui/views/widget/gtk_views_window.h +++ /dev/null @@ -1,44 +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_VIEWS_WIDGET_GTK_VIEWS_WINDOW_H_ -#define UI_VIEWS_WIDGET_GTK_VIEWS_WINDOW_H_ -#pragma once - -#include <gtk/gtkwindow.h> - -// GtkViewsWindow is a subclass of GtkWindow that overrides its move_focus -// method so that we can handle focus traversing by ourselves. - -G_BEGIN_DECLS - -#define GTK_TYPE_VIEWS_WINDOW (gtk_views_window_get_type ()) -#define GTK_VIEWS_WINDOW(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_VIEWS_WINDOW, GtkViewsWindow)) -#define GTK_VIEWS_WINDOW_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_VIEWS_WINDOW, \ - GtkViewsWindowClass)) -#define GTK_IS_VIEWS_WINDOW(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_VIEWS_WINDOW)) -#define GTK_IS_VIEWS_WINDOW_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_VIEWS_WINDOW)) -#define GTK_VIEWS_WINDOW_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_VIEWS_WINDOW, GtkViewsWindow)) - -typedef struct _GtkViewsWindow GtkViewsWindow; -typedef struct _GtkViewsWindowClass GtkViewsWindowClass; - -struct _GtkViewsWindow { - GtkWindow window; -}; - -struct _GtkViewsWindowClass { - GtkWindowClass parent_class; -}; - -GtkWidget* gtk_views_window_new(GtkWindowType type); - -G_END_DECLS - -#endif // UI_VIEWS_WIDGET_GTK_VIEWS_WINDOW_H_ diff --git a/ui/views/widget/native_widget_gtk.cc b/ui/views/widget/native_widget_gtk.cc deleted file mode 100644 index 140f4e2..0000000 --- a/ui/views/widget/native_widget_gtk.cc +++ /dev/null @@ -1,2202 +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/views/widget/native_widget_gtk.h" - -#include <X11/Xatom.h> -#include <X11/Xlib.h> -#include <X11/extensions/shape.h> -#include <gdk/gdk.h> -#include <gdk/gdkx.h> - -#include <set> -#include <vector> - -#include "base/auto_reset.h" -#include "base/bind.h" -#include "base/compiler_specific.h" -#include "base/message_loop.h" -#include "base/utf_string_conversions.h" -#include "ui/base/dragdrop/drag_drop_types.h" -#include "ui/base/dragdrop/os_exchange_data.h" -#include "ui/base/dragdrop/os_exchange_data_provider_gtk.h" -#include "ui/base/gtk/g_object_destructor_filo.h" -#include "ui/base/gtk/gtk_signal_registrar.h" -#include "ui/base/gtk/gtk_windowing.h" -#include "ui/base/gtk/scoped_region.h" -#include "ui/base/hit_test.h" -#include "ui/base/x/active_window_watcher_x.h" -#include "ui/base/x/x11_util.h" -#include "ui/gfx/canvas_skia_paint.h" -#include "ui/gfx/gtk_util.h" -#include "ui/gfx/path.h" -#include "ui/gfx/screen.h" -#include "ui/views/bubble/bubble_delegate.h" -#include "ui/views/controls/textfield/native_textfield_views.h" -#include "ui/views/focus/view_storage.h" -#include "ui/views/ime/input_method_gtk.h" -#include "ui/views/views_delegate.h" -#include "ui/views/widget/drop_target_gtk.h" -#include "ui/views/widget/gtk_views_fixed.h" -#include "ui/views/widget/gtk_views_window.h" -#include "ui/views/widget/root_view.h" -#include "ui/views/widget/tooltip_manager_gtk.h" -#include "ui/views/widget/widget_delegate.h" - -using ui::OSExchangeData; -using ui::OSExchangeDataProviderGtk; -using ui::ActiveWindowWatcherX; - -namespace views { - -namespace { - -// Links the GtkWidget to its NativeWidget. -const char* const kNativeWidgetKey = "__VIEWS_NATIVE_WIDGET__"; - -// A g_object data key to associate a CompositePainter object to a GtkWidget. -const char* kCompositePainterKey = "__VIEWS_COMPOSITE_PAINTER__"; - -// A g_object data key to associate the flag whether or not the widget -// is composited to a GtkWidget. gtk_widget_is_composited simply tells -// if x11 supports composition and cannot be used to tell if given widget -// is composited. -const char* kCompositeEnabledKey = "__VIEWS_COMPOSITE_ENABLED__"; - -// A g_object data key to associate the expose handler id that is -// used to remove FREEZE_UPDATE property on the window. -const char* kExposeHandlerIdKey = "__VIEWS_EXPOSE_HANDLER_ID__"; - -// CompositePainter draws a composited child widgets image into its -// drawing area. This object is created at most once for a widget and kept -// until the widget is destroyed. -class CompositePainter { - public: - explicit CompositePainter(GtkWidget* parent) - : parent_object_(G_OBJECT(parent)) { - handler_id_ = g_signal_connect_after( - parent_object_, "expose_event", G_CALLBACK(OnCompositePaint), NULL); - } - - static void AddCompositePainter(GtkWidget* widget) { - CompositePainter* painter = static_cast<CompositePainter*>( - g_object_get_data(G_OBJECT(widget), kCompositePainterKey)); - if (!painter) { - g_object_set_data(G_OBJECT(widget), kCompositePainterKey, - new CompositePainter(widget)); - g_signal_connect(widget, "destroy", - G_CALLBACK(&DestroyPainter), NULL); - } - } - - // Set the composition flag. - static void SetComposited(GtkWidget* widget) { - g_object_set_data(G_OBJECT(widget), kCompositeEnabledKey, - const_cast<char*>("")); - } - - // Returns true if the |widget| is composited and ready to be drawn. - static bool IsComposited(GtkWidget* widget) { - return g_object_get_data(G_OBJECT(widget), kCompositeEnabledKey) != NULL; - } - - private: - virtual ~CompositePainter() {} - - // Composes a image from one child. - static void CompositeChildWidget(GtkWidget* child, gpointer data) { - GdkEventExpose* event = static_cast<GdkEventExpose*>(data); - GtkWidget* parent = gtk_widget_get_parent(child); - DCHECK(parent); - if (IsComposited(child)) { - cairo_t* cr = gdk_cairo_create(parent->window); - gdk_cairo_set_source_pixmap(cr, child->window, - child->allocation.x, - child->allocation.y); - GdkRegion* region = gdk_region_rectangle(&child->allocation); - gdk_region_intersect(region, event->region); - gdk_cairo_region(cr, region); - cairo_clip(cr); - cairo_set_operator(cr, CAIRO_OPERATOR_OVER); - cairo_paint(cr); - cairo_destroy(cr); - } - } - - // Expose-event handler that compose & draws children's image into - // the |parent|'s drawing area. - static gboolean OnCompositePaint(GtkWidget* parent, GdkEventExpose* event) { - gtk_container_foreach(GTK_CONTAINER(parent), - CompositeChildWidget, - event); - return false; - } - - static void DestroyPainter(GtkWidget* object) { - CompositePainter* painter = reinterpret_cast<CompositePainter*>( - g_object_get_data(G_OBJECT(object), kCompositePainterKey)); - DCHECK(painter); - delete painter; - } - - GObject* parent_object_; - gulong handler_id_; - - DISALLOW_COPY_AND_ASSIGN(CompositePainter); -}; - -void EnumerateChildWidgetsForNativeWidgets(GtkWidget* child_widget, - gpointer param) { - // Walk child widgets, if necessary. - if (GTK_IS_CONTAINER(child_widget)) { - gtk_container_foreach(GTK_CONTAINER(child_widget), - EnumerateChildWidgetsForNativeWidgets, - param); - } - - Widget* widget = Widget::GetWidgetForNativeView(child_widget); - if (widget) { - Widget::Widgets* widgets = reinterpret_cast<Widget::Widgets*>(param); - widgets->insert(widget); - } -} - -GtkWindowType WindowTypeToGtkWindowType(Widget::InitParams::Type type) { - switch (type) { - case Widget::InitParams::TYPE_BUBBLE: - case Widget::InitParams::TYPE_WINDOW: - case Widget::InitParams::TYPE_PANEL: - case Widget::InitParams::TYPE_WINDOW_FRAMELESS: - return GTK_WINDOW_TOPLEVEL; - default: - return GTK_WINDOW_POPUP; - } - NOTREACHED(); - return GTK_WINDOW_TOPLEVEL; -} - -// Converts a Windows-style hit test result code into a GDK window edge. -GdkWindowEdge HitTestCodeToGDKWindowEdge(int hittest_code) { - switch (hittest_code) { - case HTBOTTOM: - return GDK_WINDOW_EDGE_SOUTH; - case HTBOTTOMLEFT: - return GDK_WINDOW_EDGE_SOUTH_WEST; - case HTBOTTOMRIGHT: - case HTGROWBOX: - return GDK_WINDOW_EDGE_SOUTH_EAST; - case HTLEFT: - return GDK_WINDOW_EDGE_WEST; - case HTRIGHT: - return GDK_WINDOW_EDGE_EAST; - case HTTOP: - return GDK_WINDOW_EDGE_NORTH; - case HTTOPLEFT: - return GDK_WINDOW_EDGE_NORTH_WEST; - case HTTOPRIGHT: - return GDK_WINDOW_EDGE_NORTH_EAST; - default: - NOTREACHED(); - break; - } - // Default to something defaultish. - return HitTestCodeToGDKWindowEdge(HTGROWBOX); -} - -// Converts a Windows-style hit test result code into a GDK cursor type. -GdkCursorType HitTestCodeToGdkCursorType(int hittest_code) { - switch (hittest_code) { - case HTBOTTOM: - return GDK_BOTTOM_SIDE; - case HTBOTTOMLEFT: - return GDK_BOTTOM_LEFT_CORNER; - case HTBOTTOMRIGHT: - case HTGROWBOX: - return GDK_BOTTOM_RIGHT_CORNER; - case HTLEFT: - return GDK_LEFT_SIDE; - case HTRIGHT: - return GDK_RIGHT_SIDE; - case HTTOP: - return GDK_TOP_SIDE; - case HTTOPLEFT: - return GDK_TOP_LEFT_CORNER; - case HTTOPRIGHT: - return GDK_TOP_RIGHT_CORNER; - default: - break; - } - // Default to something defaultish. - return GDK_LEFT_PTR; -} - -} // namespace - -// During drag and drop GTK sends a drag-leave during a drop. This means we -// have no way to tell the difference between a normal drag leave and a drop. -// To work around that we listen for DROP_START, then ignore the subsequent -// drag-leave that GTK generates. -class NativeWidgetGtk::DropObserver : public MessageLoopForUI::Observer { - public: - DropObserver() {} - - static DropObserver* GetInstance() { - return Singleton<DropObserver>::get(); - } - - virtual void WillProcessEvent(GdkEvent* event) { - if (event->type == GDK_DROP_START) { - NativeWidgetGtk* widget = GetNativeWidgetGtkForEvent(event); - if (widget) - widget->ignore_drag_leave_ = true; - } - } - - virtual void DidProcessEvent(GdkEvent* event) { - } - - private: - NativeWidgetGtk* GetNativeWidgetGtkForEvent(GdkEvent* event) { - GtkWidget* gtk_widget = gtk_get_event_widget(event); - if (!gtk_widget) - return NULL; - - return static_cast<NativeWidgetGtk*>( - internal::NativeWidgetPrivate::GetNativeWidgetForNativeView( - gtk_widget)); - } - - DISALLOW_COPY_AND_ASSIGN(DropObserver); -}; - -// Returns the position of a widget on screen. -static void GetWidgetPositionOnScreen(GtkWidget* widget, int* x, int *y) { - // First get the root window. - GtkWidget* root = widget; - while (root && !GTK_IS_WINDOW(root)) { - root = gtk_widget_get_parent(root); - } - if (!root) { - // If root is null we're not parented. Return 0x0 and assume the caller will - // query again when we're parented. - *x = *y = 0; - return; - } - // Translate the coordinate from widget to root window. - gtk_widget_translate_coordinates(widget, root, 0, 0, x, y); - // Then adjust the position with the position of the root window. - int window_x, window_y; - gtk_window_get_position(GTK_WINDOW(root), &window_x, &window_y); - *x += window_x; - *y += window_y; -} - -// "expose-event" handler of drag icon widget that renders drag image pixbuf. -static gboolean DragIconWidgetPaint(GtkWidget* widget, - GdkEventExpose* event, - gpointer data) { - GdkPixbuf* pixbuf = reinterpret_cast<GdkPixbuf*>(data); - - cairo_t* cr = gdk_cairo_create(widget->window); - - gdk_cairo_region(cr, event->region); - cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); - gdk_cairo_set_source_pixbuf(cr, pixbuf, 0.0, 0.0); - cairo_paint(cr); - - cairo_destroy(cr); - return true; -} - -// Creates a drag icon widget that draws drag_image. -static GtkWidget* CreateDragIconWidget(GdkPixbuf* drag_image) { - GdkColormap* rgba_colormap = - gdk_screen_get_rgba_colormap(gdk_screen_get_default()); - if (!rgba_colormap) - return NULL; - - GtkWidget* drag_widget = gtk_window_new(GTK_WINDOW_POPUP); - - gtk_widget_set_colormap(drag_widget, rgba_colormap); - gtk_widget_set_app_paintable(drag_widget, true); - gtk_widget_set_size_request(drag_widget, - gdk_pixbuf_get_width(drag_image), - gdk_pixbuf_get_height(drag_image)); - - g_signal_connect(G_OBJECT(drag_widget), "expose-event", - G_CALLBACK(&DragIconWidgetPaint), drag_image); - return drag_widget; -} - -// static -GtkWidget* NativeWidgetGtk::null_parent_ = NULL; - -//////////////////////////////////////////////////////////////////////////////// -// NativeWidgetGtk, public: - -NativeWidgetGtk::NativeWidgetGtk(internal::NativeWidgetDelegate* delegate) - : delegate_(delegate), - widget_(NULL), - window_contents_(NULL), - child_(false), - ALLOW_THIS_IN_INITIALIZER_LIST(close_widget_factory_(this)), - ownership_(Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET), - transparent_(false), - ignore_events_(false), - ignore_drag_leave_(false), - opacity_(255), - drag_data_(NULL), - window_state_(GDK_WINDOW_STATE_WITHDRAWN), - is_active_(false), - transient_to_parent_(false), - got_initial_focus_in_(false), - has_focus_(false), - always_on_top_(false), - is_double_buffered_(false), - dragged_view_(NULL), - painted_(false), - has_pointer_grab_(false), - has_keyboard_grab_(false), - grab_notify_signal_id_(0), - is_menu_(false), - signal_registrar_(new ui::GtkSignalRegistrar), - destroy_signal_registrar_(new ui::GtkSignalRegistrar) { - static bool installed_message_loop_observer = false; - if (!installed_message_loop_observer) { - installed_message_loop_observer = true; - MessageLoopForUI* loop = MessageLoopForUI::current(); - if (loop) - loop->AddObserver(DropObserver::GetInstance()); - } -} - -NativeWidgetGtk::~NativeWidgetGtk() { - if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET) { - DCHECK(widget_ == NULL); - delete delegate_; - } else { - bool has_widget = !!widget_; - if (has_widget) { - // Disconnect all signal handlers registered with this object, - // except one for "destroy", before deleting the NativeWidgetGtk. - ui::GObjectDestructorFILO::GetInstance()->Disconnect( - G_OBJECT(widget_), &OnDestroyedThunk, this); - signal_registrar_.reset(); - } - CloseNow(); - // If gtk_widget_destroy didn't fire destroy signal for whatever reason, - // fail in debug build and call OnDestroy() for release build. - DCHECK(!widget_); - if (widget_) - OnDestroy(widget_); - // Call OnNativeWidgetDestroyed because we're not calling - // OnDestroyedThunk - if (has_widget) - delegate_->OnNativeWidgetDestroyed(); - } -} - -GtkWindow* NativeWidgetGtk::GetTransientParent() const { - return (!child_ && widget_) ? - gtk_window_get_transient_for(GTK_WINDOW(widget_)) : NULL; -} - -bool NativeWidgetGtk::MakeTransparent() { - // Transparency can only be enabled only if we haven't realized the widget. - DCHECK(!widget_); - - if (!gdk_screen_is_composited(gdk_screen_get_default())) { - // Transparency is only supported for compositing window managers. - // NOTE: there's a race during ChromeOS startup such that X might think - // compositing isn't supported. We ignore it if the wm says compositing - // isn't supported. - DLOG(WARNING) << "compositing not supported; allowing anyway"; - } - - if (!gdk_screen_get_rgba_colormap(gdk_screen_get_default())) { - // We need rgba to make the window transparent. - return false; - } - - transparent_ = true; - return true; -} - -void NativeWidgetGtk::EnableDoubleBuffer(bool enabled) { - is_double_buffered_ = enabled; - if (window_contents_) { - if (is_double_buffered_) - GTK_WIDGET_SET_FLAGS(window_contents_, GTK_DOUBLE_BUFFERED); - else - GTK_WIDGET_UNSET_FLAGS(window_contents_, GTK_DOUBLE_BUFFERED); - } -} - -void NativeWidgetGtk::AddChild(GtkWidget* child) { - gtk_container_add(GTK_CONTAINER(window_contents_), child); -} - -void NativeWidgetGtk::RemoveChild(GtkWidget* child) { - // We can be called after the contents widget has been destroyed, e.g. any - // NativeViewHost not removed from the view hierarchy before the window is - // closed. - if (GTK_IS_CONTAINER(window_contents_)) { - gtk_container_remove(GTK_CONTAINER(window_contents_), child); - gtk_views_fixed_set_widget_size(child, 0, 0); - } -} - -void NativeWidgetGtk::ReparentChild(GtkWidget* child) { - gtk_widget_reparent(child, window_contents_); -} - -void NativeWidgetGtk::PositionChild(GtkWidget* child, int x, int y, int w, - int h) { - gtk_views_fixed_set_widget_size(child, w, h); - gtk_fixed_move(GTK_FIXED(window_contents_), child, x, y); -} - -void NativeWidgetGtk::DoDrag(const OSExchangeData& data, int operation) { - const OSExchangeDataProviderGtk& data_provider = - static_cast<const OSExchangeDataProviderGtk&>(data.provider()); - GtkTargetList* targets = data_provider.GetTargetList(); - GdkEvent* current_event = gtk_get_current_event(); - const OSExchangeDataProviderGtk& provider( - static_cast<const OSExchangeDataProviderGtk&>(data.provider())); - - GdkDragContext* context = gtk_drag_begin( - window_contents_, - targets, - static_cast<GdkDragAction>( - ui::DragDropTypes::DragOperationToGdkDragAction(operation)), - 1, - current_event); - - GtkWidget* drag_icon_widget = NULL; - - // Set the drag image if one was supplied. - if (provider.drag_image()) { - drag_icon_widget = CreateDragIconWidget(provider.drag_image()); - if (drag_icon_widget) { - // Use a widget as the drag icon when compositing is enabled for proper - // transparency handling. - g_object_ref(provider.drag_image()); - gtk_drag_set_icon_widget(context, - drag_icon_widget, - provider.cursor_offset().x(), - provider.cursor_offset().y()); - } else { - gtk_drag_set_icon_pixbuf(context, - provider.drag_image(), - provider.cursor_offset().x(), - provider.cursor_offset().y()); - } - } - - if (current_event) - gdk_event_free(current_event); - gtk_target_list_unref(targets); - - drag_data_ = &data_provider; - - // Block the caller until drag is done by running a nested message loop. - MessageLoopForUI::current()->RunWithDispatcher(NULL); - - drag_data_ = NULL; - - if (drag_icon_widget) { - gtk_widget_destroy(drag_icon_widget); - g_object_unref(provider.drag_image()); - } -} - -void NativeWidgetGtk::OnActiveChanged() { - delegate_->OnNativeWidgetActivationChanged(IsActive()); -} - -void NativeWidgetGtk::ResetDropTarget() { - ignore_drag_leave_ = false; - drop_target_.reset(NULL); -} - -void NativeWidgetGtk::GetRequestedSize(gfx::Size* out) const { - int width, height; - if (GTK_IS_VIEWS_FIXED(widget_) && - gtk_views_fixed_get_widget_size(GetNativeView(), &width, &height)) { - out->SetSize(width, height); - } else { - GtkRequisition requisition; - gtk_widget_get_child_requisition(GetNativeView(), &requisition); - out->SetSize(requisition.width, requisition.height); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// NativeWidgetGtk, ActiveWindowWatcherXObserver implementation: - -void NativeWidgetGtk::ActiveWindowChanged(GdkWindow* active_window) { - if (!GetNativeView()) - return; - - bool was_active = IsActive(); - is_active_ = (active_window == GTK_WIDGET(GetNativeView())->window); - if (!is_active_ && active_window && !child_) { - // We're not active, but the force the window to be rendered as active if - // a child window is transient to us. - gpointer data = NULL; - gdk_window_get_user_data(active_window, &data); - GtkWidget* widget = reinterpret_cast<GtkWidget*>(data); - is_active_ = - (widget && GTK_IS_WINDOW(widget) && - gtk_window_get_transient_for(GTK_WINDOW(widget)) == GTK_WINDOW( - widget_)); - } - if (was_active != IsActive()) { - OnActiveChanged(); - GetWidget()->GetRootView()->SchedulePaint(); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// NativeWidgetGtk implementation: - -bool NativeWidgetGtk::HandleKeyboardEvent(const KeyEvent& key) { - if (!GetWidget()->GetFocusManager()) - return false; - // FocusManager::OnKeyEvent() returns false when the key has been consumed. - return !GetWidget()->GetFocusManager()->OnKeyEvent(key); -} - -bool NativeWidgetGtk::SuppressFreezeUpdates() { - if (!painted_) { - painted_ = true; - return true; - } - return false; -} - -// static -void NativeWidgetGtk::UpdateFreezeUpdatesProperty(GtkWindow* window, - bool enable) { - if (!GTK_WIDGET_REALIZED(GTK_WIDGET(window))) - gtk_widget_realize(GTK_WIDGET(window)); - GdkWindow* gdk_window = GTK_WIDGET(window)->window; - - static GdkAtom freeze_atom_ = - gdk_atom_intern("_CHROME_FREEZE_UPDATES", FALSE); - if (enable) { - VLOG(1) << "setting FREEZE UPDATES property. xid=" << - GDK_WINDOW_XID(gdk_window); - int32 val = 1; - gdk_property_change(gdk_window, - freeze_atom_, - freeze_atom_, - 32, - GDK_PROP_MODE_REPLACE, - reinterpret_cast<const guchar*>(&val), - 1); - } else { - VLOG(1) << "deleting FREEZE UPDATES property. xid=" << - GDK_WINDOW_XID(gdk_window); - gdk_property_delete(gdk_window, freeze_atom_); - } -} - -// static -void NativeWidgetGtk::RegisterChildExposeHandler(GtkWidget* child) { - UnregisterChildExposeHandler(child); - gulong id = g_signal_connect_after(child, "expose-event", - G_CALLBACK(&ChildExposeHandler), NULL); - g_object_set_data(G_OBJECT(child), kExposeHandlerIdKey, - reinterpret_cast<void*>(id)); -} - -// static -void NativeWidgetGtk::UnregisterChildExposeHandler(GtkWidget* child) { - gulong id = reinterpret_cast<gulong>(g_object_get_data(G_OBJECT(child), - kExposeHandlerIdKey)); - if (id) { - g_signal_handler_disconnect(G_OBJECT(child), id); - g_object_set_data(G_OBJECT(child), kExposeHandlerIdKey, 0); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// NativeWidgetGtk, NativeWidget implementation: - -void NativeWidgetGtk::InitNativeWidget(const Widget::InitParams& params) { - SetInitParams(params); - - Widget::InitParams modified_params = params; - if (params.parent_widget) { - NativeWidgetGtk* parent_gtk = - static_cast<NativeWidgetGtk*>(params.parent_widget->native_widget()); - modified_params.parent = child_ ? parent_gtk->window_contents() - : params.parent_widget->GetNativeView(); - } - - if (!child_) - ActiveWindowWatcherX::AddObserver(this); - - // Make container here. - CreateGtkWidget(modified_params); - - if (params.type == Widget::InitParams::TYPE_MENU) { - gtk_window_set_destroy_with_parent(GTK_WINDOW(GetNativeView()), TRUE); - gtk_window_set_type_hint(GTK_WINDOW(GetNativeView()), - GDK_WINDOW_TYPE_HINT_MENU); - } - - delegate_->OnNativeWidgetCreated(); - - if (opacity_ != 255) - SetOpacity(opacity_); - - // Make sure we receive our motion events. - - // In general we register most events on the parent of all widgets. At a - // minimum we need painting to happen on the parent (otherwise painting - // doesn't work at all), and similarly we need mouse release events on the - // parent as windows don't get mouse releases. - gtk_widget_add_events(window_contents_, - GDK_ENTER_NOTIFY_MASK | - GDK_LEAVE_NOTIFY_MASK | - GDK_BUTTON_PRESS_MASK | - GDK_BUTTON_RELEASE_MASK | - GDK_POINTER_MOTION_MASK | - GDK_KEY_PRESS_MASK | - GDK_KEY_RELEASE_MASK); - - signal_registrar_->ConnectAfter(G_OBJECT(window_contents_), "size_request", - G_CALLBACK(&OnSizeRequestThunk), this); - signal_registrar_->ConnectAfter(G_OBJECT(window_contents_), "size_allocate", - G_CALLBACK(&OnSizeAllocateThunk), this); - gtk_widget_set_app_paintable(window_contents_, true); - signal_registrar_->Connect(window_contents_, "expose_event", - G_CALLBACK(&OnPaintThunk), this); - signal_registrar_->Connect(window_contents_, "enter_notify_event", - G_CALLBACK(&OnEnterNotifyThunk), this); - signal_registrar_->Connect(window_contents_, "leave_notify_event", - G_CALLBACK(&OnLeaveNotifyThunk), this); - signal_registrar_->Connect(window_contents_, "motion_notify_event", - G_CALLBACK(&OnMotionNotifyThunk), this); - signal_registrar_->Connect(window_contents_, "button_press_event", - G_CALLBACK(&OnButtonPressThunk), this); - signal_registrar_->Connect(window_contents_, "button_release_event", - G_CALLBACK(&OnButtonReleaseThunk), this); - signal_registrar_->Connect(window_contents_, "grab_broken_event", - G_CALLBACK(&OnGrabBrokeEventThunk), this); - signal_registrar_->Connect(window_contents_, "scroll_event", - G_CALLBACK(&OnScrollThunk), this); - signal_registrar_->Connect(window_contents_, "visibility_notify_event", - G_CALLBACK(&OnVisibilityNotifyThunk), this); - - // In order to receive notification when the window is no longer the front - // window, we need to install these on the widget. - // NOTE: this doesn't work with focus follows mouse. - signal_registrar_->Connect(widget_, "focus_in_event", - G_CALLBACK(&OnFocusInThunk), this); - signal_registrar_->Connect(widget_, "focus_out_event", - G_CALLBACK(&OnFocusOutThunk), this); - - // Use the dedicated registrar for destory so that other handlers - // can be unregistered first. - destroy_signal_registrar_->Connect(widget_, "destroy", - G_CALLBACK(&OnDestroyThunk), this); - - signal_registrar_->Connect(widget_, "show", - G_CALLBACK(&OnShowThunk), this); - signal_registrar_->Connect(widget_, "map", - G_CALLBACK(&OnMapThunk), this); - signal_registrar_->Connect(widget_, "hide", - G_CALLBACK(&OnHideThunk), this); - signal_registrar_->Connect(widget_, "configure-event", - G_CALLBACK(&OnConfigureEventThunk), this); - - // Views/FocusManager (re)sets the focus to the root window, - // so we need to connect signal handlers to the gtk window. - // See views::Views::Focus and views::FocusManager::ClearNativeFocus - // for more details. - signal_registrar_->Connect(widget_, "key_press_event", - G_CALLBACK(&OnEventKeyThunk), this); - signal_registrar_->Connect(widget_, "key_release_event", - G_CALLBACK(&OnEventKeyThunk), this); - - // Drag and drop. - gtk_drag_dest_set(window_contents_, static_cast<GtkDestDefaults>(0), - NULL, 0, GDK_ACTION_COPY); - signal_registrar_->Connect(window_contents_, "drag_motion", - G_CALLBACK(&OnDragMotionThunk), this); - signal_registrar_->Connect(window_contents_, "drag_data_received", - G_CALLBACK(&OnDragDataReceivedThunk), this); - signal_registrar_->Connect(window_contents_, "drag_drop", - G_CALLBACK(&OnDragDropThunk), this); - signal_registrar_->Connect(window_contents_, "drag_leave", - G_CALLBACK(&OnDragLeaveThunk), this); - signal_registrar_->Connect(window_contents_, "drag_data_get", - G_CALLBACK(&OnDragDataGetThunk), this); - signal_registrar_->Connect(window_contents_, "drag_end", - G_CALLBACK(&OnDragEndThunk), this); - signal_registrar_->Connect(window_contents_, "drag_failed", - G_CALLBACK(&OnDragFailedThunk), this); - signal_registrar_->Connect(G_OBJECT(widget_), "window-state-event", - G_CALLBACK(&OnWindowStateEventThunk), this); - - ui::GObjectDestructorFILO::GetInstance()->Connect( - G_OBJECT(widget_), &OnDestroyedThunk, this); - - tooltip_manager_.reset(new TooltipManagerGtk(this)); - - // Register for tooltips. - g_object_set(G_OBJECT(window_contents_), "has-tooltip", TRUE, NULL); - signal_registrar_->Connect(window_contents_, "query_tooltip", - G_CALLBACK(&OnQueryTooltipThunk), this); - - if (child_) { - if (modified_params.parent) - SetBounds(params.bounds); - } else { - gtk_widget_add_events(widget_, - GDK_STRUCTURE_MASK); - if (params.bounds.width() > 0 && params.bounds.height() > 0) - gtk_window_resize(GTK_WINDOW(widget_), params.bounds.width(), - params.bounds.height()); - gtk_window_move(GTK_WINDOW(widget_), params.bounds.x(), params.bounds.y()); - } -} - -NonClientFrameView* NativeWidgetGtk::CreateNonClientFrameView() { - return NULL; -} - -void NativeWidgetGtk::UpdateFrameAfterFrameChange() { - // We currently don't support different frame types on Gtk, so we don't - // need to implement this. - NOTIMPLEMENTED(); -} - -bool NativeWidgetGtk::ShouldUseNativeFrame() const { - return false; -} - -void NativeWidgetGtk::FrameTypeChanged() { - // This is called when the Theme has changed, so forward the event to the root - // widget. - GetWidget()->ThemeChanged(); - GetWidget()->GetRootView()->SchedulePaint(); -} - -Widget* NativeWidgetGtk::GetWidget() { - return delegate_->AsWidget(); -} - -const Widget* NativeWidgetGtk::GetWidget() const { - return delegate_->AsWidget(); -} - -gfx::NativeView NativeWidgetGtk::GetNativeView() const { - return widget_; -} - -gfx::NativeWindow NativeWidgetGtk::GetNativeWindow() const { - return child_ ? NULL : GTK_WINDOW(widget_); -} - -Widget* NativeWidgetGtk::GetTopLevelWidget() { - NativeWidgetPrivate* native_widget = GetTopLevelNativeWidget(GetNativeView()); - return native_widget ? native_widget->GetWidget() : NULL; -} - -const ui::Compositor* NativeWidgetGtk::GetCompositor() const { - return NULL; -} - -ui::Compositor* NativeWidgetGtk::GetCompositor() { - return NULL; -} - -void NativeWidgetGtk::CalculateOffsetToAncestorWithLayer( - gfx::Point* offset, - ui::Layer** layer_parent) { -} - -void NativeWidgetGtk::ViewRemoved(View* view) { - if (drop_target_.get()) - drop_target_->ResetTargetViewIfEquals(view); -} - -void NativeWidgetGtk::SetNativeWindowProperty(const char* name, void* value) { - g_object_set_data(G_OBJECT(widget_), name, value); -} - -void* NativeWidgetGtk::GetNativeWindowProperty(const char* name) const { - return g_object_get_data(G_OBJECT(widget_), name); -} - -TooltipManager* NativeWidgetGtk::GetTooltipManager() const { - return tooltip_manager_.get(); -} - -bool NativeWidgetGtk::IsScreenReaderActive() const { - return false; -} - -void NativeWidgetGtk::SendNativeAccessibilityEvent( - View* view, - ui::AccessibilityTypes::Event event_type) { - // In the future if we add native GTK accessibility support, the - // notification should be sent here. -} - -void NativeWidgetGtk::SetMouseCapture() { - DCHECK(!HasMouseCapture()); - - // Release the current grab. - GtkWidget* current_grab_window = gtk_grab_get_current(); - if (current_grab_window) - gtk_grab_remove(current_grab_window); - - if (is_menu_ && gdk_pointer_is_grabbed()) - gdk_pointer_ungrab(GDK_CURRENT_TIME); - - // Make sure all app mouse/keyboard events are targeted at us only. - gtk_grab_add(window_contents_); - if (gtk_grab_get_current() == window_contents_ && !grab_notify_signal_id_) { - // "grab_notify" is sent any time the grab changes. We only care about grab - // changes when we have done a grab. - grab_notify_signal_id_ = g_signal_connect( - window_contents_, "grab_notify", G_CALLBACK(&OnGrabNotifyThunk), this); - } - - if (is_menu_) { - // For menus we do a pointer grab too. This ensures we get mouse events from - // other apps. In theory we should do this for all widget types, but doing - // so leads to gdk_pointer_grab randomly returning GDK_GRAB_ALREADY_GRABBED. - GdkGrabStatus pointer_grab_status = - gdk_pointer_grab(window_contents()->window, FALSE, - static_cast<GdkEventMask>( - GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | - GDK_POINTER_MOTION_MASK), - NULL, NULL, GDK_CURRENT_TIME); - // NOTE: technically grab may fail. We may want to try and continue on in - // that case. - DCHECK_EQ(GDK_GRAB_SUCCESS, pointer_grab_status); - has_pointer_grab_ = pointer_grab_status == GDK_GRAB_SUCCESS; - } -} - -void NativeWidgetGtk::ReleaseMouseCapture() { - bool delegate_lost_capture = HasMouseCapture(); - if (GTK_WIDGET_HAS_GRAB(window_contents_)) - gtk_grab_remove(window_contents_); - if (grab_notify_signal_id_) { - g_signal_handler_disconnect(window_contents_, grab_notify_signal_id_); - grab_notify_signal_id_ = 0; - } - if (has_pointer_grab_) { - has_pointer_grab_ = false; - gdk_pointer_ungrab(GDK_CURRENT_TIME); - } - if (delegate_lost_capture) - delegate_->OnMouseCaptureLost(); -} - -bool NativeWidgetGtk::HasMouseCapture() const { - return GTK_WIDGET_HAS_GRAB(window_contents_) || has_pointer_grab_; -} - -InputMethod* NativeWidgetGtk::CreateInputMethod() { - // Create input method when pure views is enabled but not on views desktop. - if (views::Widget::IsPureViews()) { - InputMethod* input_method = new InputMethodGtk(this); - input_method->Init(GetWidget()); - return input_method; - } - // GTK's textfield will handle IME. - return NULL; -} - -void NativeWidgetGtk::CenterWindow(const gfx::Size& size) { - gfx::Rect center_rect; - - GtkWindow* parent = gtk_window_get_transient_for(GetNativeWindow()); - if (parent) { - // We have a parent window, center over it. - gint parent_x = 0; - gint parent_y = 0; - gtk_window_get_position(parent, &parent_x, &parent_y); - gint parent_w = 0; - gint parent_h = 0; - gtk_window_get_size(parent, &parent_w, &parent_h); - center_rect = gfx::Rect(parent_x, parent_y, parent_w, parent_h); - } else { - // We have no parent window, center over the screen. - center_rect = gfx::Screen::GetMonitorWorkAreaNearestWindow(GetNativeView()); - } - gfx::Rect bounds(center_rect.x() + (center_rect.width() - size.width()) / 2, - center_rect.y() + (center_rect.height() - size.height()) / 2, - size.width(), size.height()); - GetWidget()->SetBoundsConstrained(bounds); -} - -void NativeWidgetGtk::GetWindowPlacement( - gfx::Rect* bounds, - ui::WindowShowState* show_state) const { - // Do nothing for now. ChromeOS isn't yet saving window placement. -} - -void NativeWidgetGtk::SetWindowTitle(const string16& title) { - // We don't have a window title on ChromeOS (right now). -} - -void NativeWidgetGtk::SetWindowIcons(const SkBitmap& window_icon, - const SkBitmap& app_icon) { - // We don't have window icons on ChromeOS. -} - -void NativeWidgetGtk::SetAccessibleName(const string16& name) { -} - -void NativeWidgetGtk::SetAccessibleRole(ui::AccessibilityTypes::Role role) { -} - -void NativeWidgetGtk::SetAccessibleState(ui::AccessibilityTypes::State state) { -} - -void NativeWidgetGtk::InitModalType(ui::ModalType modal_type) { - if (modal_type == ui::MODAL_TYPE_NONE) - return; - gtk_window_set_modal(GetNativeWindow(), true); -} - -gfx::Rect NativeWidgetGtk::GetWindowScreenBounds() const { - // Client == Window bounds on Gtk. - return GetClientAreaScreenBounds(); -} - -gfx::Rect NativeWidgetGtk::GetClientAreaScreenBounds() const { - // Due to timing we can get a request for bounds after Close(). - // TODO(beng): Figure out if this is bogus. - if (!widget_) - return gfx::Rect(size_); - - int x = 0, y = 0, w = 0, h = 0; - if (GTK_IS_WINDOW(widget_)) { - gtk_window_get_position(GTK_WINDOW(widget_), &x, &y); - // NOTE: this doesn't include frame decorations, but it should be good - // enough for our uses. - gtk_window_get_size(GTK_WINDOW(widget_), &w, &h); - } else { - GetWidgetPositionOnScreen(widget_, &x, &y); - w = widget_->allocation.width; - h = widget_->allocation.height; - } - return gfx::Rect(x, y, w, h); -} - -gfx::Rect NativeWidgetGtk::GetRestoredBounds() const { - // We currently don't support tiling, so this doesn't matter. - return GetWindowScreenBounds(); -} - -void NativeWidgetGtk::SetBounds(const gfx::Rect& bounds) { - if (child_) { - GtkWidget* parent = gtk_widget_get_parent(widget_); - if (GTK_IS_VIEWS_FIXED(parent)) { - NativeWidgetGtk* parent_widget = static_cast<NativeWidgetGtk*>( - internal::NativeWidgetPrivate::GetNativeWidgetForNativeView(parent)); - parent_widget->PositionChild(widget_, bounds.x(), bounds.y(), - bounds.width(), bounds.height()); - } else { - DCHECK(GTK_IS_FIXED(parent)) - << "Parent of NativeWidgetGtk has to be Fixed or ViewsFixed"; - // Just request the size if the parent is not NativeWidgetGtk but plain - // GtkFixed. NativeWidgetGtk does not know the minimum size so we assume - // the caller of the SetBounds knows exactly how big it wants to be. - gtk_widget_set_size_request(widget_, bounds.width(), bounds.height()); - if (parent != null_parent_) - gtk_fixed_move(GTK_FIXED(parent), widget_, bounds.x(), bounds.y()); - } - } else { - if (GTK_WIDGET_MAPPED(widget_)) { - // If the widget is mapped (on screen), we can move and resize with one - // call, which avoids two separate window manager steps. - gdk_window_move_resize(widget_->window, bounds.x(), bounds.y(), - bounds.width(), bounds.height()); - } - - // Always call gtk_window_move and gtk_window_resize so that GtkWindow's - // geometry info is up-to-date. - GtkWindow* gtk_window = GTK_WINDOW(widget_); - // TODO: this may need to set an initial size if not showing. - // TODO: need to constrain based on screen size. - if (!bounds.IsEmpty()) { - gtk_window_resize(gtk_window, bounds.width(), bounds.height()); - } - gtk_window_move(gtk_window, bounds.x(), bounds.y()); - } -} - -void NativeWidgetGtk::SetSize(const gfx::Size& size) { - if (child_) { - GtkWidget* parent = gtk_widget_get_parent(widget_); - if (GTK_IS_VIEWS_FIXED(parent)) { - gtk_views_fixed_set_widget_size(widget_, size.width(), size.height()); - } else { - gtk_widget_set_size_request(widget_, size.width(), size.height()); - } - } else { - if (GTK_WIDGET_MAPPED(widget_)) - gdk_window_resize(widget_->window, size.width(), size.height()); - GtkWindow* gtk_window = GTK_WINDOW(widget_); - if (!size.IsEmpty()) - gtk_window_resize(gtk_window, size.width(), size.height()); - } -} - -void NativeWidgetGtk::StackAbove(gfx::NativeView native_view) { - ui::StackPopupWindow(GetNativeView(), native_view); -} - -void NativeWidgetGtk::StackAtTop() { - DCHECK(GTK_IS_WINDOW(GetNativeView())); - gtk_window_present(GTK_WINDOW(GetNativeView())); -} - -void NativeWidgetGtk::StackBelow(gfx::NativeView native_view) { - NOTIMPLEMENTED(); -} - -void NativeWidgetGtk::SetShape(gfx::NativeRegion region) { - if (widget_ && widget_->window) { - gdk_window_shape_combine_region(widget_->window, region, 0, 0); - gdk_region_destroy(region); - } -} - -void NativeWidgetGtk::Close() { - if (!widget_) - return; // No need to do anything. - - // Hide first. - Hide(); - if (!close_widget_factory_.HasWeakPtrs()) { - // And we delay the close just in case we're on the stack. - MessageLoop::current()->PostTask( - FROM_HERE, - base::Bind(&NativeWidgetGtk::CloseNow, - close_widget_factory_.GetWeakPtr())); - } -} - -void NativeWidgetGtk::CloseNow() { - if (widget_) { - gtk_widget_destroy(widget_); // Triggers OnDestroy(). - } -} - -void NativeWidgetGtk::Show() { - if (widget_) { - gtk_widget_show(widget_); - if (widget_->window) - gdk_window_raise(widget_->window); - } -} - -void NativeWidgetGtk::Hide() { - if (widget_) { - gtk_widget_hide(widget_); - if (widget_->window) - gdk_window_lower(widget_->window); - } -} - -void NativeWidgetGtk::ShowMaximizedWithBounds( - const gfx::Rect& restored_bounds) { - // TODO: when we add maximization support update this. - Show(); -} - -void NativeWidgetGtk::ShowWithWindowState(ui::WindowShowState show_state) { - // No concept of maximization (yet) on ChromeOS. - if (show_state == ui::SHOW_STATE_INACTIVE) - gtk_window_set_focus_on_map(GetNativeWindow(), false); - gtk_widget_show(GetNativeView()); -} - -bool NativeWidgetGtk::IsVisible() const { - return GTK_WIDGET_VISIBLE(GetNativeView()) && (GetWidget()->is_top_level() || - GetWidget()->GetTopLevelWidget()->IsVisible()); -} - -void NativeWidgetGtk::Activate() { - gtk_window_present(GetNativeWindow()); -} - -void NativeWidgetGtk::Deactivate() { - gdk_window_lower(GTK_WIDGET(GetNativeView())->window); -} - -bool NativeWidgetGtk::IsActive() const { - DCHECK(!child_); - return is_active_; -} - -void NativeWidgetGtk::SetAlwaysOnTop(bool on_top) { - DCHECK(!child_); - always_on_top_ = on_top; - if (widget_) - gtk_window_set_keep_above(GTK_WINDOW(widget_), on_top); -} - -void NativeWidgetGtk::Maximize() { - gtk_window_maximize(GetNativeWindow()); -} - -void NativeWidgetGtk::Minimize() { - gtk_window_iconify(GetNativeWindow()); -} - -bool NativeWidgetGtk::IsMaximized() const { - return window_state_ & GDK_WINDOW_STATE_MAXIMIZED; -} - -bool NativeWidgetGtk::IsMinimized() const { - return window_state_ & GDK_WINDOW_STATE_ICONIFIED; -} - -void NativeWidgetGtk::Restore() { - if (IsFullscreen()) { - SetFullscreen(false); - } else { - if (IsMaximized()) - gtk_window_unmaximize(GetNativeWindow()); - else if (IsMinimized()) - gtk_window_deiconify(GetNativeWindow()); - } -} - -void NativeWidgetGtk::SetFullscreen(bool fullscreen) { - if (fullscreen) - gtk_window_fullscreen(GetNativeWindow()); - else - gtk_window_unfullscreen(GetNativeWindow()); -} - -bool NativeWidgetGtk::IsFullscreen() const { - return window_state_ & GDK_WINDOW_STATE_FULLSCREEN; -} - -void NativeWidgetGtk::SetOpacity(unsigned char opacity) { - opacity_ = opacity; - if (widget_) { - // We can only set the opacity when the widget has been realized. - gdk_window_set_opacity(widget_->window, static_cast<gdouble>(opacity) / - static_cast<gdouble>(255)); - } -} - -void NativeWidgetGtk::SetUseDragFrame(bool use_drag_frame) { - NOTIMPLEMENTED(); -} - -void NativeWidgetGtk::FlashFrame(bool flash) { - gtk_window_set_urgency_hint(GTK_WINDOW(GetNativeView()), flash); -} - -bool NativeWidgetGtk::IsAccessibleWidget() const { - return false; -} - -void NativeWidgetGtk::RunShellDrag(View* view, - const ui::OSExchangeData& data, - const gfx::Point& location, - int operation) { - DoDrag(data, operation); -} - -void NativeWidgetGtk::SchedulePaintInRect(const gfx::Rect& rect) { - // No need to schedule paint if - // 1) widget_ is NULL. This may happen because this instance may - // be deleted after the gtk widget has been destroyed (See OnDestroy()). - // 2) widget_ is not drawable (mapped and visible) - // 3) If it's never painted before. The first expose event will - // paint the area that has to be painted. - if (widget_ && GTK_WIDGET_DRAWABLE(widget_) && painted_) { - gtk_widget_queue_draw_area(widget_, rect.x(), rect.y(), rect.width(), - rect.height()); - } -} - -void NativeWidgetGtk::SetCursor(gfx::NativeCursor cursor) { - // |window_contents_| is placed on top of |widget_|. So the cursor needs to be - // set on |window_contents_| instead of |widget_|. - if (window_contents_) - gdk_window_set_cursor(window_contents_->window, cursor); -} - -void NativeWidgetGtk::ClearNativeFocus() { - DCHECK(!child_); - if (!GetNativeView()) { - NOTREACHED(); - return; - } - gtk_window_set_focus(GTK_WINDOW(GetNativeView()), NULL); -} - -void NativeWidgetGtk::FocusNativeView(gfx::NativeView native_view) { - if (native_view && !gtk_widget_is_focus(native_view)) - gtk_widget_grab_focus(native_view); -} - -gfx::Rect NativeWidgetGtk::GetWorkAreaBoundsInScreen() const { - return gfx::Screen::GetMonitorWorkAreaNearestWindow(GetNativeView()); -} - -void NativeWidgetGtk::SetInactiveRenderingDisabled(bool value) { -} - -Widget::MoveLoopResult NativeWidgetGtk::RunMoveLoop() { - NOTIMPLEMENTED(); - return Widget::MOVE_LOOP_CANCELED; -} - -void NativeWidgetGtk::EndMoveLoop() { - NOTIMPLEMENTED(); -} - -void NativeWidgetGtk::SetVisibilityChangedAnimationsEnabled(bool value) { - // Nothing needed on gtk. -} - -//////////////////////////////////////////////////////////////////////////////// -// NativeWidgetGtk, protected: - -void NativeWidgetGtk::OnSizeRequest(GtkWidget* widget, - GtkRequisition* requisition) { - // Do only return the preferred size for child windows. GtkWindow interprets - // the requisition as a minimum size for top level windows, returning a - // preferred size for these would prevents us from setting smaller window - // sizes. - if (child_) { - gfx::Size size(GetWidget()->GetRootView()->GetPreferredSize()); - requisition->width = size.width(); - requisition->height = size.height(); - } -} - -void NativeWidgetGtk::OnSizeAllocate(GtkWidget* widget, - GtkAllocation* allocation) { - // See comment next to size_ as to why we do this. Also note, it's tempting - // to put this in the static method so subclasses don't need to worry about - // it, but if a subclasses needs to set a shape then they need to always - // reset the shape in this method regardless of whether the size changed. - gfx::Size new_size(allocation->width, allocation->height); - if (new_size == size_) - return; - size_ = new_size; - delegate_->OnNativeWidgetSizeChanged(size_); - - if (GetWidget()->non_client_view()) { - // The Window's NonClientView may provide a custom shape for the Window. - gfx::Path window_mask; - GetWidget()->non_client_view()->GetWindowMask(gfx::Size(allocation->width, - allocation->height), - &window_mask); - GdkRegion* mask_region = window_mask.CreateNativeRegion(); - gdk_window_shape_combine_region(GetNativeView()->window, mask_region, 0, 0); - if (mask_region) - gdk_region_destroy(mask_region); - - SaveWindowPosition(); - } -} - -gboolean NativeWidgetGtk::OnPaint(GtkWidget* widget, GdkEventExpose* event) { - gdk_window_set_debug_updates(Widget::IsDebugPaintEnabled()); - - if (transparent_ && child_) { - // Clear the background before drawing any view and native components. - DrawTransparentBackground(widget, event); - if (!CompositePainter::IsComposited(widget_) && - gdk_screen_is_composited(gdk_screen_get_default())) { - // Let the parent draw the content only after something is drawn on - // the widget. - CompositePainter::SetComposited(widget_); - } - } - - ui::ScopedRegion region(gdk_region_copy(event->region)); - if (!gdk_region_empty(region.Get())) { - GdkRectangle clip_bounds; - gdk_region_get_clipbox(region.Get(), &clip_bounds); - if (!delegate_->OnNativeWidgetPaintAccelerated(gfx::Rect(clip_bounds))) { - gfx::CanvasSkiaPaint canvas(event); - if (!canvas.is_empty()) { - canvas.set_composite_alpha(is_transparent()); - delegate_->OnNativeWidgetPaint(&canvas); - } - } - } - - if (!painted_) { - painted_ = true; - if (!child_) - UpdateFreezeUpdatesProperty(GTK_WINDOW(widget_), false /* remove */); - } - return false; // False indicates other widgets should get the event as well. -} - -void NativeWidgetGtk::OnDragDataGet(GtkWidget* widget, - GdkDragContext* context, - GtkSelectionData* data, - guint info, - guint time) { - if (!drag_data_) { - NOTREACHED(); - return; - } - drag_data_->WriteFormatToSelection(info, data); -} - -void NativeWidgetGtk::OnDragDataReceived(GtkWidget* widget, - GdkDragContext* context, - gint x, - gint y, - GtkSelectionData* data, - guint info, - guint time) { - if (drop_target_.get()) - drop_target_->OnDragDataReceived(context, x, y, data, info, time); -} - -gboolean NativeWidgetGtk::OnDragDrop(GtkWidget* widget, - GdkDragContext* context, - gint x, - gint y, - guint time) { - if (drop_target_.get()) { - return drop_target_->OnDragDrop(context, x, y, time); - } - return FALSE; -} - -void NativeWidgetGtk::OnDragEnd(GtkWidget* widget, GdkDragContext* context) { - if (!drag_data_) { - // This indicates we didn't start a drag operation, and should never - // happen. - NOTREACHED(); - return; - } - // Quit the nested message loop we spawned in DoDrag. - MessageLoop::current()->Quit(); -} - -gboolean NativeWidgetGtk::OnDragFailed(GtkWidget* widget, - GdkDragContext* context, - GtkDragResult result) { - return FALSE; -} - -void NativeWidgetGtk::OnDragLeave(GtkWidget* widget, - GdkDragContext* context, - guint time) { - if (ignore_drag_leave_) { - ignore_drag_leave_ = false; - return; - } - if (drop_target_.get()) { - drop_target_->OnDragLeave(context, time); - drop_target_.reset(NULL); - } -} - -gboolean NativeWidgetGtk::OnDragMotion(GtkWidget* widget, - GdkDragContext* context, - gint x, - gint y, - guint time) { - if (!drop_target_.get()) { - drop_target_.reset(new DropTargetGtk( - reinterpret_cast<internal::RootView*>(GetWidget()->GetRootView()), - context)); - } - return drop_target_->OnDragMotion(context, x, y, time); -} - -gboolean NativeWidgetGtk::OnEnterNotify(GtkWidget* widget, - GdkEventCrossing* event) { - if (HasMouseCapture() && event->mode == GDK_CROSSING_GRAB) { - // Doing a grab results an async enter event, regardless of where the mouse - // is. We don't want to generate a mouse move in this case. - return false; - } - - if (!GetWidget()->last_mouse_event_was_move_ && - !GetWidget()->is_mouse_button_pressed_) { - // When a mouse button is pressed gtk generates a leave, enter, press. - // RootView expects to get a mouse move before a press, otherwise enter is - // not set. So we generate a move here. - GdkEventMotion motion = { GDK_MOTION_NOTIFY, event->window, - event->send_event, event->time, event->x, event->y, NULL, event->state, - 0, NULL, event->x_root, event->y_root }; - - // If this event is the result of pressing a button then one of the button - // modifiers is set. Unset it as we're compensating for the leave generated - // when you press a button. - motion.state &= ~(GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK); - - MouseEvent mouse_event(TransformEvent(&motion)); - delegate_->OnMouseEvent(mouse_event); - } - return false; -} - -gboolean NativeWidgetGtk::OnLeaveNotify(GtkWidget* widget, - GdkEventCrossing* event) { - gdk_window_set_cursor(widget->window, gfx::GetCursor(GDK_LEFT_PTR)); - - GetWidget()->ResetLastMouseMoveFlag(); - - if (!HasMouseCapture() && !GetWidget()->is_mouse_button_pressed_) { - // Don't convert if the event is synthetic and has 0x0 coordinates. - if (event->x_root || event->y_root || event->x || event->y || - !event->send_event) { - TransformEvent(event); - } - MouseEvent mouse_event(reinterpret_cast<GdkEvent*>(event)); - delegate_->OnMouseEvent(mouse_event); - } - return false; -} - -gboolean NativeWidgetGtk::OnMotionNotify(GtkWidget* widget, - GdkEventMotion* event) { - if (GetWidget()->non_client_view()) { - GdkEventMotion transformed_event = *event; - TransformEvent(&transformed_event); - gfx::Point translated_location(transformed_event.x, transformed_event.y); - - // Update the cursor for the screen edge. - int hittest_code = - GetWidget()->non_client_view()->NonClientHitTest(translated_location); - if (hittest_code != HTCLIENT) { - GdkCursorType cursor_type = HitTestCodeToGdkCursorType(hittest_code); - gdk_window_set_cursor(widget->window, gfx::GetCursor(cursor_type)); - } - } - - MouseEvent mouse_event(TransformEvent(event)); - delegate_->OnMouseEvent(mouse_event); - return true; -} - -gboolean NativeWidgetGtk::OnButtonPress(GtkWidget* widget, - GdkEventButton* event) { - if (GetWidget()->non_client_view()) { - GdkEventButton transformed_event = *event; - MouseEvent mouse_event(TransformEvent(&transformed_event)); - - int hittest_code = GetWidget()->non_client_view()->NonClientHitTest( - mouse_event.location()); - switch (hittest_code) { - case HTCAPTION: { - // Start dragging if the mouse event is a single click and *not* a right - // click. If it is a right click, then pass it through to - // NativeWidgetGtk::OnButtonPress so that View class can show - // ContextMenu upon a mouse release event. We only start drag on single - // clicks as we get a crash in Gtk on double/triple clicks. - if (event->type == GDK_BUTTON_PRESS && - !mouse_event.IsOnlyRightMouseButton()) { - gfx::Point screen_point(event->x, event->y); - View::ConvertPointToScreen(GetWidget()->GetRootView(), &screen_point); - gtk_window_begin_move_drag(GetNativeWindow(), event->button, - screen_point.x(), screen_point.y(), - event->time); - return TRUE; - } - break; - } - case HTBOTTOM: - case HTBOTTOMLEFT: - case HTBOTTOMRIGHT: - case HTGROWBOX: - case HTLEFT: - case HTRIGHT: - case HTTOP: - case HTTOPLEFT: - case HTTOPRIGHT: { - gfx::Point screen_point(event->x, event->y); - View::ConvertPointToScreen(GetWidget()->GetRootView(), &screen_point); - // TODO(beng): figure out how to get a good minimum size. - gtk_widget_set_size_request(GetNativeView(), 100, 100); - gtk_window_begin_resize_drag(GetNativeWindow(), - HitTestCodeToGDKWindowEdge(hittest_code), - event->button, screen_point.x(), - screen_point.y(), event->time); - return TRUE; - } - default: - // Everything else falls into standard client event handling... - break; - } - } - - if (event->type == GDK_2BUTTON_PRESS || event->type == GDK_3BUTTON_PRESS) { - // The sequence for double clicks is press, release, press, 2press, release. - // This means that at the time we get the second 'press' we don't know - // whether it corresponds to a double click or not. For now we're completely - // ignoring the 2press/3press events as they are duplicate. To make this - // work right we need to write our own code that detects if the press is a - // double/triple. For now we're completely punting, which means we always - // get single clicks. - // TODO: fix this. - return true; - } - - MouseEvent mouse_event(TransformEvent(event)); - // Returns true to consume the event when widget is not transparent. - return delegate_->OnMouseEvent(mouse_event) || !transparent_; -} - -gboolean NativeWidgetGtk::OnButtonRelease(GtkWidget* widget, - GdkEventButton* event) { - // GTK generates a mouse release at the end of dnd. We need to ignore it. - if (!drag_data_) { - MouseEvent mouse_event(TransformEvent(event)); - delegate_->OnMouseEvent(mouse_event); - } - return true; -} - -gboolean NativeWidgetGtk::OnScroll(GtkWidget* widget, GdkEventScroll* event) { - MouseWheelEvent mouse_event(TransformEvent(event)); - return delegate_->OnMouseEvent(mouse_event); -} - -gboolean NativeWidgetGtk::OnFocusIn(GtkWidget* gtk_widget, - GdkEventFocus* event) { - if (has_focus_) - return false; // This is the second focus-in event in a row, ignore it. - has_focus_ = true; - - Widget* widget = GetWidget(); - - if (widget->GetFocusManager()) - widget->GetFocusManager()->ResetMenuKeyState(); - - if (!widget->is_top_level()) - return false; - - // Only top-level Widget should have an InputMethod instance. - InputMethod* input_method = widget->GetInputMethod(); - if (input_method) - input_method->OnFocus(); - - // See description of got_initial_focus_in_ for details on this. - if (!got_initial_focus_in_) { - got_initial_focus_in_ = true; - // Sets initial focus here. On X11/Gtk, window creation - // is asynchronous and a focus request has to be made after a window - // gets created. - widget->SetInitialFocus(); - } - return false; -} - -gboolean NativeWidgetGtk::OnFocusOut(GtkWidget* widget, GdkEventFocus* event) { - if (!has_focus_) - return false; // This is the second focus-out event in a row, ignore it. - has_focus_ = false; - - if (!GetWidget()->is_top_level()) - return false; - - // Only top-level Widget should have an InputMethod instance. - InputMethod* input_method = GetWidget()->GetInputMethod(); - if (input_method) - input_method->OnBlur(); - return false; -} - -gboolean NativeWidgetGtk::OnEventKey(GtkWidget* widget, GdkEventKey* event) { - KeyEvent key(reinterpret_cast<GdkEvent*>(event)); - InputMethod* input_method = GetWidget()->GetInputMethod(); - if (input_method) - input_method->DispatchKeyEvent(key); - else - DispatchKeyEventPostIME(key); - - // Returns true to prevent GtkWindow's default key event handler. - return true; -} - -gboolean NativeWidgetGtk::OnQueryTooltip(GtkWidget* widget, - gint x, - gint y, - gboolean keyboard_mode, - GtkTooltip* tooltip) { - return static_cast<TooltipManagerGtk*>(tooltip_manager_.get())-> - ShowTooltip(x, y, keyboard_mode, tooltip); -} - -gboolean NativeWidgetGtk::OnVisibilityNotify(GtkWidget* widget, - GdkEventVisibility* event) { - return false; -} - -gboolean NativeWidgetGtk::OnGrabBrokeEvent(GtkWidget* widget, GdkEvent* event) { - if (!has_pointer_grab_ && !has_keyboard_grab_) { - // We don't have any grabs; don't attempt to do anything. - return false; - } - - // Sent when either the keyboard or pointer grab is broke. We drop both grabs - // in this case. - if (event->grab_broken.keyboard) { - // Keyboard grab was broke. - has_keyboard_grab_ = false; - if (has_pointer_grab_) { - has_pointer_grab_ = false; - gdk_pointer_ungrab(GDK_CURRENT_TIME); - delegate_->OnMouseCaptureLost(); - } - } else { - // Mouse grab was broke. - has_pointer_grab_ = false; - if (has_keyboard_grab_) { - has_keyboard_grab_ = false; - gdk_keyboard_ungrab(GDK_CURRENT_TIME); - } - delegate_->OnMouseCaptureLost(); - } - ReleaseMouseCapture(); - - return false; // To let other widgets get the event. -} - -void NativeWidgetGtk::OnGrabNotify(GtkWidget* widget, gboolean was_grabbed) { - // Sent when gtk_grab_add changes. - if (!window_contents_) - return; // Grab broke after window destroyed, don't try processing it. - if (!was_grabbed) // Indicates we've been shadowed (lost grab). - HandleGtkGrabBroke(); -} - -void NativeWidgetGtk::OnDestroy(GtkWidget* object) { - signal_registrar_.reset(); - destroy_signal_registrar_.reset(); - if (grab_notify_signal_id_) { - g_signal_handler_disconnect(window_contents_, grab_notify_signal_id_); - grab_notify_signal_id_ = 0; - } - delegate_->OnNativeWidgetDestroying(); - if (!child_) - ActiveWindowWatcherX::RemoveObserver(this); - if (widget_) - SetNativeWindowProperty(kNativeWidgetKey, NULL); - - // Note that this handler is hooked to GtkObject::destroy. - // NULL out pointers here since we might still be in an observer list - // until deletion happens. - widget_ = window_contents_ = NULL; -} - -void NativeWidgetGtk::OnDestroyed(GObject *where_the_object_was) { - delegate_->OnNativeWidgetDestroyed(); - if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET) - delete this; -} - -void NativeWidgetGtk::OnShow(GtkWidget* widget) { - delegate_->OnNativeWidgetVisibilityChanged(true); -} - -void NativeWidgetGtk::OnMap(GtkWidget* widget) { -} - -void NativeWidgetGtk::OnHide(GtkWidget* widget) { - delegate_->OnNativeWidgetVisibilityChanged(false); -} - -gboolean NativeWidgetGtk::OnWindowStateEvent(GtkWidget* widget, - GdkEventWindowState* event) { - if (GetWidget()->non_client_view() && - !(event->new_window_state & GDK_WINDOW_STATE_WITHDRAWN)) { - SaveWindowPosition(); - } - window_state_ = event->new_window_state; - return FALSE; -} - -gboolean NativeWidgetGtk::OnConfigureEvent(GtkWidget* widget, - GdkEventConfigure* event) { - SaveWindowPosition(); - return FALSE; -} - -void NativeWidgetGtk::HandleGtkGrabBroke() { - ReleaseMouseCapture(); - delegate_->OnMouseCaptureLost(); -} - -//////////////////////////////////////////////////////////////////////////////// -// NativeWidgetGtk, private: - -void NativeWidgetGtk::DispatchKeyEventPostIME(const KeyEvent& key) { - if (GetWidget()->GetFocusManager()) - GetWidget()->GetFocusManager()->MaybeResetMenuKeyState(key); - - // Send the key event to View hierarchy first. - bool handled = delegate_->OnKeyEvent(key); - - if (key.key_code() == ui::VKEY_PROCESSKEY || handled) - return; - - // Dispatch the key event to native GtkWidget hierarchy. - // To prevent GtkWindow from handling the key event as a keybinding, we need - // to bypass GtkWindow's default key event handler and dispatch the event - // here. - GdkEventKey* event = reinterpret_cast<GdkEventKey*>(key.gdk_event()); - if (!handled && event && GTK_IS_WINDOW(widget_)) - handled = gtk_window_propagate_key_event(GTK_WINDOW(widget_), event); - - // On Linux, in order to handle VKEY_MENU (Alt) accelerator key correctly and - // avoid issues like: http://crbug.com/40966 and http://crbug.com/49701, we - // should only send the key event to the focus manager if it's not handled by - // any View or native GtkWidget. - // The flow is different when the focus is in a RenderWidgetHostViewGtk, which - // always consumes the key event and send it back to us later by calling - // HandleKeyboardEvent() directly, if it's not handled by webkit. - if (!handled) - handled = HandleKeyboardEvent(key); - - // Dispatch the key event for bindings processing. - if (!handled && event && GTK_IS_WINDOW(widget_)) - gtk_bindings_activate_event(GTK_OBJECT(widget_), event); -} - -void NativeWidgetGtk::SetInitParams(const Widget::InitParams& params) { - DCHECK(!GetNativeView()); - - ownership_ = params.ownership; - child_ = params.child; - is_menu_ = params.type == Widget::InitParams::TYPE_MENU; - - // TODO(beng): The secondary checks here actually obviate the need for - // params.transient but that's only because NativeWidgetGtk - // considers any top-level widget to be a transient widget. We - // will probably want to ammend this assumption at some point. - if (params.transient || params.parent || params.parent_widget) - transient_to_parent_ = true; - if (params.transparent) - MakeTransparent(); - if (!params.accept_events && !child_) - ignore_events_ = true; - if (params.double_buffer) - EnableDoubleBuffer(true); -} - -gboolean NativeWidgetGtk::OnWindowPaint(GtkWidget* widget, - GdkEventExpose* event) { - // Clear the background to be totally transparent. We don't need to - // paint the root view here as that is done by OnPaint. - DCHECK(transparent_); - DrawTransparentBackground(widget, event); - // The Keyboard layout view has a renderer that covers the entire - // window, which prevents OnPaint from being called on window_contents_, - // so we need to remove the FREEZE_UPDATES property here. - if (!painted_) { - painted_ = true; - UpdateFreezeUpdatesProperty(GTK_WINDOW(widget_), false /* remove */); - } - return false; -} - -void NativeWidgetGtk::OnChildExpose(GtkWidget* child) { - DCHECK(!child_); - if (!painted_) { - painted_ = true; - UpdateFreezeUpdatesProperty(GTK_WINDOW(widget_), false /* remove */); - } - UnregisterChildExposeHandler(child); -} - -// static -gboolean NativeWidgetGtk::ChildExposeHandler(GtkWidget* widget, - GdkEventExpose* event) { - GtkWidget* toplevel = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW); - CHECK(toplevel); - Widget* views_widget = Widget::GetWidgetForNativeView(toplevel); - CHECK(views_widget); - NativeWidgetGtk* widget_gtk = - static_cast<NativeWidgetGtk*>(views_widget->native_widget()); - widget_gtk->OnChildExpose(widget); - return false; -} - -void NativeWidgetGtk::CreateGtkWidget(const Widget::InitParams& params) { - // We turn off double buffering for two reasons: - // 1. We draw to a canvas then composite to the screen, which means we're - // doing our own double buffering already. - // 2. GTKs double buffering clips to the dirty region. RootView occasionally - // needs to expand the paint region (see RootView::OnPaint). This means - // that if we use GTK's double buffering and we tried to expand the dirty - // region, it wouldn't get painted. - if (child_) { - window_contents_ = widget_ = gtk_views_fixed_new(); - gtk_widget_set_name(widget_, "views-gtkwidget-child-fixed"); - if (!is_double_buffered_) - GTK_WIDGET_UNSET_FLAGS(widget_, GTK_DOUBLE_BUFFERED); - gtk_fixed_set_has_window(GTK_FIXED(widget_), true); - if (!params.parent && !null_parent_) { - GtkWidget* popup = gtk_window_new(GTK_WINDOW_POPUP); - null_parent_ = gtk_fixed_new(); - gtk_widget_set_name(null_parent_, "views-gtkwidget-null-parent"); - gtk_container_add(GTK_CONTAINER(popup), null_parent_); - gtk_widget_realize(null_parent_); - } - if (transparent_) { - // transparency has to be configured before widget is realized. - DCHECK(params.parent) << - "Transparent widget must have parent when initialized"; - ConfigureWidgetForTransparentBackground(params.parent); - } - gtk_container_add( - GTK_CONTAINER(params.parent ? params.parent : null_parent_), widget_); - gtk_widget_realize(widget_); - if (transparent_) { - // The widget has to be realized to set composited flag. - // I tried "realize" signal to set this flag, but it did not work - // when the top level is popup. - DCHECK(GTK_WIDGET_REALIZED(widget_)); - gdk_window_set_composited(widget_->window, true); - } - if (params.parent && !params.bounds.size().IsEmpty()) { - // Make sure that an widget is given it's initial size before - // we're done initializing, to take care of some potential - // corner cases when programmatically arranging hierarchies as - // seen in - // http://code.google.com/p/chromium-os/issues/detail?id=5987 - - // This can't be done without a parent present, or stale data - // might show up on the screen as seen in - // http://code.google.com/p/chromium/issues/detail?id=53870 - GtkAllocation alloc = - { 0, 0, params.bounds.width(), params.bounds.height() }; - gtk_widget_size_allocate(widget_, &alloc); - } - if (params.type == Widget::InitParams::TYPE_CONTROL) { - // Controls are initially visible. - gtk_widget_show(widget_); - } - } else { - Widget::InitParams::Type type = params.type; - if (type == Widget::InitParams::TYPE_BUBBLE && - params.delegate->AsBubbleDelegate() && - params.delegate->AsBubbleDelegate()->use_focusless()) { - // Handles focusless bubble type, which are bubbles that should - // act like popups rather than gtk windows. They do not get focus - // and are not controlled by window manager placement. - type = Widget::InitParams::TYPE_POPUP; - } - - // Use our own window class to override GtkWindow's move_focus method. - widget_ = gtk_views_window_new(WindowTypeToGtkWindowType(type)); - gtk_widget_set_name(widget_, "views-gtkwidget-window"); - if (transient_to_parent_) { - gtk_window_set_transient_for(GTK_WINDOW(widget_), - GTK_WINDOW(params.parent)); - } - GTK_WIDGET_UNSET_FLAGS(widget_, GTK_DOUBLE_BUFFERED); - - // Gtk determines the size for windows based on the requested size of the - // child. For NativeWidgetGtk the child is a fixed. If the fixed ends up - // with a child widget it's possible the child widget will drive the - // requested size of the widget, which we don't want. We explicitly set a - // value of 1x1 here so that gtk doesn't attempt to resize the window if we - // end up with a situation where the requested size of a child of the fixed - // is greater than the size of the window. By setting the size in this - // manner we're also allowing users of WidgetGtk to change the requested - // size at any time. - gtk_widget_set_size_request(widget_, 1, 1); - - if (!params.bounds.size().IsEmpty()) { - // When we realize the window, the window manager is given a size. If we - // don't specify a size before then GTK defaults to 200x200. Specify - // a size now so that the window manager sees the requested size. - GtkAllocation alloc = - { 0, 0, params.bounds.width(), params.bounds.height() }; - gtk_widget_size_allocate(widget_, &alloc); - } - gtk_window_set_decorated(GTK_WINDOW(widget_), false); - // We'll take care of positioning our window. - gtk_window_set_position(GTK_WINDOW(widget_), GTK_WIN_POS_NONE); - - window_contents_ = gtk_views_fixed_new(); - gtk_widget_set_name(window_contents_, "views-gtkwidget-window-fixed"); - if (!is_double_buffered_) - GTK_WIDGET_UNSET_FLAGS(window_contents_, GTK_DOUBLE_BUFFERED); - gtk_fixed_set_has_window(GTK_FIXED(window_contents_), true); - gtk_container_add(GTK_CONTAINER(widget_), window_contents_); - gtk_widget_show(window_contents_); - g_object_set_data(G_OBJECT(window_contents_), kNativeWidgetKey, - static_cast<NativeWidgetGtk*>(this)); - if (transparent_) - ConfigureWidgetForTransparentBackground(NULL); - - if (ignore_events_) - ConfigureWidgetForIgnoreEvents(); - - // Realize the window_contents_ so that we can always get a handle for - // acceleration. Without this we need to check every time paint is - // invoked. - gtk_widget_realize(window_contents_); - - SetAlwaysOnTop(always_on_top_); - // UpdateFreezeUpdatesProperty will realize the widget and handlers like - // size-allocate will function properly. - UpdateFreezeUpdatesProperty(GTK_WINDOW(widget_), true /* add */); - } - SetNativeWindowProperty(kNativeWidgetKey, this); -} - -void NativeWidgetGtk::ConfigureWidgetForTransparentBackground( - GtkWidget* parent) { - DCHECK(widget_ && window_contents_); - - GdkColormap* rgba_colormap = - gdk_screen_get_rgba_colormap(gtk_widget_get_screen(widget_)); - if (!rgba_colormap) { - transparent_ = false; - return; - } - // To make the background transparent we need to install the RGBA colormap - // on both the window and fixed. In addition we need to make sure no - // decorations are drawn. The last bit is to make sure the widget doesn't - // attempt to draw a pixmap in it's background. - if (!child_) { - DCHECK(parent == NULL); - gtk_widget_set_colormap(widget_, rgba_colormap); - gtk_widget_set_app_paintable(widget_, true); - signal_registrar_->Connect(widget_, "expose_event", - G_CALLBACK(&OnWindowPaintThunk), this); - gtk_widget_realize(widget_); - gdk_window_set_decorations(widget_->window, - static_cast<GdkWMDecoration>(0)); - } else { - DCHECK(parent); - CompositePainter::AddCompositePainter(parent); - } - DCHECK(!GTK_WIDGET_REALIZED(window_contents_)); - gtk_widget_set_colormap(window_contents_, rgba_colormap); -} - -void NativeWidgetGtk::ConfigureWidgetForIgnoreEvents() { - gtk_widget_realize(widget_); - GdkWindow* gdk_window = widget_->window; - Display* display = GDK_WINDOW_XDISPLAY(gdk_window); - XID win = GDK_WINDOW_XID(gdk_window); - - // This sets the clickable area to be empty, allowing all events to be - // passed to any windows behind this one. - XShapeCombineRectangles( - display, - win, - ShapeInput, - 0, // x offset - 0, // y offset - NULL, // rectangles - 0, // num rectangles - ShapeSet, - 0); -} - -void NativeWidgetGtk::DrawTransparentBackground(GtkWidget* widget, - GdkEventExpose* event) { - cairo_t* cr = gdk_cairo_create(widget->window); - cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); - gdk_cairo_region(cr, event->region); - cairo_fill(cr); - cairo_destroy(cr); -} - -void NativeWidgetGtk::SaveWindowPosition() { - // The delegate may have gone away on us. - if (!GetWidget()->widget_delegate()) - return; - - ui::WindowShowState show_state = ui::SHOW_STATE_NORMAL; - if (IsMaximized()) - show_state = ui::SHOW_STATE_MAXIMIZED; - else if (IsMinimized()) - show_state = ui::SHOW_STATE_MINIMIZED; - GetWidget()->widget_delegate()->SaveWindowPlacement( - GetWidget()->GetWindowScreenBounds(), - show_state); -} - -//////////////////////////////////////////////////////////////////////////////// -// Widget, public: - -// static -void Widget::NotifyLocaleChanged() { - GList *window_list = gtk_window_list_toplevels(); - for (GList* element = window_list; element; element = g_list_next(element)) { - Widget* widget = - Widget::GetWidgetForNativeWindow(GTK_WINDOW(element->data)); - if (widget) - widget->LocaleChanged(); - } - g_list_free(window_list); -} - -// static -void Widget::CloseAllSecondaryWidgets() { - GList* windows = gtk_window_list_toplevels(); - for (GList* window = windows; window; - window = g_list_next(window)) { - Widget* widget = Widget::GetWidgetForNativeView(GTK_WIDGET(window->data)); - if (widget && widget->is_secondary_widget()) - widget->Close(); - } - g_list_free(windows); -} - -// static -bool Widget::ConvertRect(const Widget* source, - const Widget* target, - gfx::Rect* rect) { - DCHECK(source); - DCHECK(target); - DCHECK(rect); - - // TODO(oshima): Add check if source and target belongs to the same - // screen. - - if (source == target) - return true; - if (!source || !target) - return false; - - gfx::Point source_point = source->GetWindowScreenBounds().origin(); - gfx::Point target_point = target->GetWindowScreenBounds().origin(); - - rect->set_origin( - source_point.Subtract(target_point).Add(rect->origin())); - return true; -} - -namespace internal { - -//////////////////////////////////////////////////////////////////////////////// -// NativeWidgetPrivate, public: - -// static -NativeWidgetPrivate* NativeWidgetPrivate::CreateNativeWidget( - NativeWidgetDelegate* delegate) { - return new NativeWidgetGtk(delegate); -} - -// static -NativeWidgetPrivate* NativeWidgetPrivate::GetNativeWidgetForNativeView( - gfx::NativeView native_view) { - if (!native_view) - return NULL; - return reinterpret_cast<NativeWidgetGtk*>( - g_object_get_data(G_OBJECT(native_view), kNativeWidgetKey)); -} - -// static -NativeWidgetPrivate* NativeWidgetPrivate::GetNativeWidgetForNativeWindow( - gfx::NativeWindow native_window) { - if (!native_window) - return NULL; - return reinterpret_cast<NativeWidgetGtk*>( - g_object_get_data(G_OBJECT(native_window), kNativeWidgetKey)); -} - -// static -NativeWidgetPrivate* NativeWidgetPrivate::GetTopLevelNativeWidget( - gfx::NativeView native_view) { - if (!native_view) - return NULL; - - NativeWidgetPrivate* widget = NULL; - - GtkWidget* parent_gtkwidget = native_view; - NativeWidgetPrivate* parent_widget; - do { - parent_widget = GetNativeWidgetForNativeView(parent_gtkwidget); - if (parent_widget) - widget = parent_widget; - parent_gtkwidget = gtk_widget_get_parent(parent_gtkwidget); - } while (parent_gtkwidget); - - return widget && widget->GetWidget()->is_top_level() ? widget : NULL; -} - -// static -void NativeWidgetPrivate::GetAllChildWidgets(gfx::NativeView native_view, - Widget::Widgets* children) { - if (!native_view) - return; - - Widget* widget = Widget::GetWidgetForNativeView(native_view); - if (widget) - children->insert(widget); - gtk_container_foreach(GTK_CONTAINER(native_view), - EnumerateChildWidgetsForNativeWidgets, - reinterpret_cast<gpointer>(children)); -} - -// static -void NativeWidgetPrivate::ReparentNativeView(gfx::NativeView native_view, - gfx::NativeView new_parent) { - if (!native_view) - return; - - gfx::NativeView previous_parent = gtk_widget_get_parent(native_view); - if (previous_parent == new_parent) - return; - - Widget::Widgets widgets; - GetAllChildWidgets(native_view, &widgets); - - // First notify all the widgets that they are being disassociated - // from their previous parent. - for (Widget::Widgets::iterator it = widgets.begin(); - it != widgets.end(); ++it) { - // TODO(beng): Rename this notification to NotifyNativeViewChanging() - // and eliminate the bool parameter. - (*it)->NotifyNativeViewHierarchyChanged(false, previous_parent); - } - - if (gtk_widget_get_parent(native_view)) - gtk_widget_reparent(native_view, new_parent); - else - gtk_container_add(GTK_CONTAINER(new_parent), native_view); - - // And now, notify them that they have a brand new parent. - for (Widget::Widgets::iterator it = widgets.begin(); - it != widgets.end(); ++it) { - (*it)->NotifyNativeViewHierarchyChanged(true, new_parent); - } -} - -// static -bool NativeWidgetPrivate::IsMouseButtonDown() { - bool button_pressed = false; - GdkEvent* event = gtk_get_current_event(); - if (event) { - button_pressed = event->type == GDK_BUTTON_PRESS || - event->type == GDK_2BUTTON_PRESS || - event->type == GDK_3BUTTON_PRESS; - gdk_event_free(event); - } - return button_pressed; -} - -} // namespace internal -} // namespace views diff --git a/ui/views/widget/native_widget_gtk.h b/ui/views/widget/native_widget_gtk.h deleted file mode 100644 index 5f6fa2e..0000000 --- a/ui/views/widget/native_widget_gtk.h +++ /dev/null @@ -1,470 +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_VIEWS_WIDGET_NATIVE_WIDGET_GTK_H_ -#define UI_VIEWS_WIDGET_NATIVE_WIDGET_GTK_H_ -#pragma once - -#include <gtk/gtk.h> - -#include "base/compiler_specific.h" -#include "base/memory/ref_counted.h" -#include "base/memory/weak_ptr.h" -#include "base/message_loop.h" -#include "ui/base/gtk/gtk_signal.h" -#include "ui/base/x/active_window_watcher_x_observer.h" -#include "ui/gfx/size.h" -#include "ui/views/focus/focus_manager.h" -#include "ui/views/widget/native_widget_private.h" -#include "ui/views/widget/widget.h" - -namespace gfx { -class Rect; -} - -namespace ui { -class OSExchangeData; -class OSExchangeDataProviderGtk; -class GtkSignalRegistrar; -} -using ui::OSExchangeData; -using ui::OSExchangeDataProviderGtk; - -namespace views { - -class DropTargetGtk; -class InputMethod; -class View; - -namespace internal { -class NativeWidgetDelegate; -} - -// Widget implementation for GTK. -class VIEWS_EXPORT NativeWidgetGtk : public internal::NativeWidgetPrivate, - public ui::ActiveWindowWatcherXObserver { - public: - explicit NativeWidgetGtk(internal::NativeWidgetDelegate* delegate); - virtual ~NativeWidgetGtk(); - - // Returns the transient parent. See make_transient_to_parent for details on - // what the transient parent is. - GtkWindow* GetTransientParent() const; - - // Makes the background of the window totally transparent. This must be - // invoked before Init. This does a couple of checks and returns true if - // the window can be made transparent. The actual work of making the window - // transparent is done by ConfigureWidgetForTransparentBackground. - // This works for both child and window types. - bool MakeTransparent(); - bool is_transparent() const { return transparent_; } - - // Enable/Disable double buffering.This is neccessary to prevent - // flickering in ScrollView, which has both native and view - // controls. - void EnableDoubleBuffer(bool enabled); - bool is_double_buffered() const { return is_double_buffered_; } - - bool is_ignore_events() const { return ignore_events_; } - - // Adds and removes the specified widget as a child of this widget's contents. - // These methods make sure to add the widget to the window's contents - // container if this widget is a window. - void AddChild(GtkWidget* child); - void RemoveChild(GtkWidget* child); - - // A safe way to reparent a child widget to this widget. Calls - // gtk_widget_reparent which handles refcounting to avoid destroying the - // widget when removing it from its old parent. - void ReparentChild(GtkWidget* child); - - // Positions a child GtkWidget at the specified location and bounds. - void PositionChild(GtkWidget* child, int x, int y, int w, int h); - - // Parent GtkWidget all children are added to. When this NativeWidgetGtk - // corresponds to a top level window, this is the GtkFixed within the - // GtkWindow, not the GtkWindow itself. For child widgets, this is the same - // GtkFixed as |widget_|. - GtkWidget* window_contents() const { return window_contents_; } - - // Starts a drag on this widget. This blocks until the drag is done. - void DoDrag(const OSExchangeData& data, int operation); - - // Invoked when the active status changes. - virtual void OnActiveChanged(); - - // Sets the drop target to NULL. This is invoked by DropTargetGTK when the - // drop is done. - void ResetDropTarget(); - - // Gets the requested size of the widget. This can be the size - // stored in properties for a GtkViewsFixed, or in the requisitioned - // size of other kinds of widgets. - void GetRequestedSize(gfx::Size* out) const; - - // Overridden from ui::ActiveWindowWatcherXObserver. - virtual void ActiveWindowChanged(GdkWindow* active_window) OVERRIDE; - - // Handles a keyboard event by sending it to our focus manager. - // Returns true if it's handled by the focus manager. - bool HandleKeyboardEvent(const KeyEvent& key); - - // Tells widget not to remove FREEZE_UPDATES property when the - // widget is painted. This is used if painting the gtk widget - // is not enough to show the window and has to wait further like - // keyboard overlay. Returns true if this is called before - // FREEZE_UPDATES property is removed, or false otherwise. - bool SuppressFreezeUpdates(); - - // Sets and deletes FREEZE_UPDATES property on given |window|. - // It adds the property when |enable| is true and remove if false. - // Calling this method will realize the window if it's not realized yet. - // This property is used to help WindowManager know when the window - // is fully painted so that WM can map the fully painted window. - // The property is based on Owen Taylor's proposal at - // http://mail.gnome.org/archives/wm-spec-list/2009-June/msg00002.html. - // This is just a hint to WM, and won't change the behavior for WM - // which does not support this property. - static void UpdateFreezeUpdatesProperty(GtkWindow* window, bool enable); - - // Registers/Unregisters a expose handler that removes - // FREEZE_UPDATES property. If you are adding a GtkWidget with its - // own GdkWindow that may fill the entire area of the - // NativeWidgetGtk to the view hierachy, you need use this function - // to tell WM that when the widget is ready to be shown. Caller of - // this method do not need to unregister the handler if the widget - // receives the expose event for sure because the handler will be - // removed upon the first invocation of the handler. If the - // widget may be detached without expose event, the caller must - // unregister the handler using/ UnregisterChildExposeHandler. - static void RegisterChildExposeHandler(GtkWidget* widget); - static void UnregisterChildExposeHandler(GtkWidget* widget); - - // Overridden from internal::NativeWidgetPrivate: - virtual void InitNativeWidget(const Widget::InitParams& params) OVERRIDE; - virtual NonClientFrameView* CreateNonClientFrameView() OVERRIDE; - virtual void UpdateFrameAfterFrameChange() OVERRIDE; - virtual bool ShouldUseNativeFrame() const OVERRIDE; - virtual void FrameTypeChanged() OVERRIDE; - virtual Widget* GetWidget() OVERRIDE; - virtual const Widget* GetWidget() const OVERRIDE; - virtual gfx::NativeView GetNativeView() const OVERRIDE; - virtual gfx::NativeWindow GetNativeWindow() const OVERRIDE; - virtual Widget* GetTopLevelWidget() OVERRIDE; - virtual const ui::Compositor* GetCompositor() const OVERRIDE; - virtual ui::Compositor* GetCompositor() OVERRIDE; - virtual void CalculateOffsetToAncestorWithLayer( - gfx::Point* offset, - ui::Layer** layer_parent) OVERRIDE; - virtual void ViewRemoved(View* view) OVERRIDE; - virtual void SetNativeWindowProperty(const char* name, void* value) OVERRIDE; - virtual void* GetNativeWindowProperty(const char* name) const OVERRIDE; - virtual TooltipManager* GetTooltipManager() const OVERRIDE; - virtual bool IsScreenReaderActive() const OVERRIDE; - virtual void SendNativeAccessibilityEvent( - View* view, - ui::AccessibilityTypes::Event event_type) OVERRIDE; - virtual void SetMouseCapture() OVERRIDE; - virtual void ReleaseMouseCapture() OVERRIDE; - virtual bool HasMouseCapture() const OVERRIDE; - virtual InputMethod* CreateInputMethod() OVERRIDE; - virtual void CenterWindow(const gfx::Size& size) OVERRIDE; - virtual void GetWindowPlacement( - gfx::Rect* bounds, - ui::WindowShowState* show_state) const OVERRIDE; - virtual void SetWindowTitle(const string16& title) OVERRIDE; - virtual void SetWindowIcons(const SkBitmap& window_icon, - const SkBitmap& app_icon) OVERRIDE; - virtual void SetAccessibleName(const string16& name) OVERRIDE; - virtual void SetAccessibleRole(ui::AccessibilityTypes::Role role) OVERRIDE; - virtual void SetAccessibleState(ui::AccessibilityTypes::State state) OVERRIDE; - virtual void InitModalType(ui::ModalType modal_type) OVERRIDE; - virtual gfx::Rect GetWindowScreenBounds() const OVERRIDE; - virtual gfx::Rect GetClientAreaScreenBounds() const OVERRIDE; - virtual gfx::Rect GetRestoredBounds() const OVERRIDE; - virtual void SetBounds(const gfx::Rect& bounds) OVERRIDE; - virtual void SetSize(const gfx::Size& size) OVERRIDE; - virtual void StackAbove(gfx::NativeView native_view) OVERRIDE; - virtual void StackAtTop() OVERRIDE; - virtual void StackBelow(gfx::NativeView native_view) OVERRIDE; - virtual void SetShape(gfx::NativeRegion shape) OVERRIDE; - virtual void Close() OVERRIDE; - virtual void CloseNow() OVERRIDE; - virtual void Show() OVERRIDE; - virtual void Hide() OVERRIDE; - virtual void ShowMaximizedWithBounds( - const gfx::Rect& restored_bounds) OVERRIDE; - virtual void ShowWithWindowState(ui::WindowShowState window_state) OVERRIDE; - virtual bool IsVisible() const OVERRIDE; - virtual void Activate() OVERRIDE; - virtual void Deactivate() OVERRIDE; - virtual bool IsActive() const OVERRIDE; - virtual void SetAlwaysOnTop(bool always_on_top) OVERRIDE; - virtual void Maximize() OVERRIDE; - virtual void Minimize() OVERRIDE; - virtual bool IsMaximized() const OVERRIDE; - virtual bool IsMinimized() const OVERRIDE; - virtual void Restore() OVERRIDE; - virtual void SetFullscreen(bool fullscreen) OVERRIDE; - virtual bool IsFullscreen() const OVERRIDE; - virtual void SetOpacity(unsigned char opacity) OVERRIDE; - virtual void SetUseDragFrame(bool use_drag_frame) OVERRIDE; - virtual void FlashFrame(bool flash) OVERRIDE; - virtual bool IsAccessibleWidget() const OVERRIDE; - virtual void RunShellDrag(View* view, - const ui::OSExchangeData& data, - const gfx::Point& location, - int operation) OVERRIDE; - virtual void SchedulePaintInRect(const gfx::Rect& rect) OVERRIDE; - virtual void SetCursor(gfx::NativeCursor cursor) OVERRIDE; - virtual void ClearNativeFocus() OVERRIDE; - virtual void FocusNativeView(gfx::NativeView native_view) OVERRIDE; - virtual gfx::Rect GetWorkAreaBoundsInScreen() const OVERRIDE; - virtual void SetInactiveRenderingDisabled(bool value) OVERRIDE; - virtual Widget::MoveLoopResult RunMoveLoop() OVERRIDE; - virtual void EndMoveLoop() OVERRIDE; - virtual void SetVisibilityChangedAnimationsEnabled(bool value) OVERRIDE; - - protected: - // Modifies event coordinates to the targeted widget contained by this widget. - template<class Event> GdkEvent* TransformEvent(Event* event) { - GdkWindow* dest = GTK_WIDGET(window_contents_)->window; - if (event && event->window != dest) { - gint dest_x, dest_y; - gdk_window_get_root_origin(dest, &dest_x, &dest_y); - event->x = event->x_root - dest_x; - event->y = event->y_root - dest_y; - } - return reinterpret_cast<GdkEvent*>(event); - } - - // Event handlers: - CHROMEGTK_VIRTUAL_CALLBACK_1(NativeWidgetGtk, gboolean, OnButtonPress, - GdkEventButton*); - CHROMEGTK_VIRTUAL_CALLBACK_1(NativeWidgetGtk, void, OnSizeRequest, - GtkRequisition*); - CHROMEGTK_VIRTUAL_CALLBACK_1(NativeWidgetGtk, void, OnSizeAllocate, - GtkAllocation*); - CHROMEGTK_VIRTUAL_CALLBACK_1(NativeWidgetGtk, gboolean, OnPaint, - GdkEventExpose*); - CHROMEGTK_VIRTUAL_CALLBACK_4(NativeWidgetGtk, void, OnDragDataGet, - GdkDragContext*, GtkSelectionData*, guint, - guint); - CHROMEGTK_VIRTUAL_CALLBACK_6(NativeWidgetGtk, void, OnDragDataReceived, - GdkDragContext*, gint, gint, GtkSelectionData*, - guint, guint); - CHROMEGTK_VIRTUAL_CALLBACK_4(NativeWidgetGtk, gboolean, OnDragDrop, - GdkDragContext*, gint, gint, guint); - CHROMEGTK_VIRTUAL_CALLBACK_1(NativeWidgetGtk, void, OnDragEnd, - GdkDragContext*); - CHROMEGTK_VIRTUAL_CALLBACK_2(NativeWidgetGtk, gboolean, OnDragFailed, - GdkDragContext*, GtkDragResult); - CHROMEGTK_VIRTUAL_CALLBACK_2(NativeWidgetGtk, void, OnDragLeave, - GdkDragContext*, guint); - CHROMEGTK_VIRTUAL_CALLBACK_4(NativeWidgetGtk, gboolean, OnDragMotion, - GdkDragContext*, gint, gint, guint); - CHROMEGTK_VIRTUAL_CALLBACK_1(NativeWidgetGtk, gboolean, OnEnterNotify, - GdkEventCrossing*); - CHROMEGTK_VIRTUAL_CALLBACK_1(NativeWidgetGtk, gboolean, OnLeaveNotify, - GdkEventCrossing*); - CHROMEGTK_VIRTUAL_CALLBACK_1(NativeWidgetGtk, gboolean, OnMotionNotify, - GdkEventMotion*); - CHROMEGTK_VIRTUAL_CALLBACK_1(NativeWidgetGtk, gboolean, OnButtonRelease, - GdkEventButton*); - CHROMEGTK_VIRTUAL_CALLBACK_1(NativeWidgetGtk, gboolean, OnFocusIn, - GdkEventFocus*); - CHROMEGTK_VIRTUAL_CALLBACK_1(NativeWidgetGtk, gboolean, OnFocusOut, - GdkEventFocus*); - CHROMEGTK_VIRTUAL_CALLBACK_1(NativeWidgetGtk, gboolean, OnEventKey, - GdkEventKey*); - CHROMEGTK_VIRTUAL_CALLBACK_4(NativeWidgetGtk, gboolean, OnQueryTooltip, gint, - gint, gboolean, GtkTooltip*); - CHROMEGTK_VIRTUAL_CALLBACK_1(NativeWidgetGtk, gboolean, OnScroll, - GdkEventScroll*); - CHROMEGTK_VIRTUAL_CALLBACK_1(NativeWidgetGtk, gboolean, OnVisibilityNotify, - GdkEventVisibility*); - CHROMEGTK_VIRTUAL_CALLBACK_1(NativeWidgetGtk, gboolean, OnGrabBrokeEvent, - GdkEvent*); - CHROMEGTK_VIRTUAL_CALLBACK_1(NativeWidgetGtk, void, OnGrabNotify, gboolean); - CHROMEGTK_VIRTUAL_CALLBACK_0(NativeWidgetGtk, void, OnDestroy); - CHROMEGTK_VIRTUAL_CALLBACK_0(NativeWidgetGtk, void, OnShow); - CHROMEGTK_VIRTUAL_CALLBACK_0(NativeWidgetGtk, void, OnMap); - CHROMEGTK_VIRTUAL_CALLBACK_0(NativeWidgetGtk, void, OnHide); - CHROMEGTK_VIRTUAL_CALLBACK_1(NativeWidgetGtk, gboolean, OnWindowStateEvent, - GdkEventWindowState*); - CHROMEGTK_VIRTUAL_CALLBACK_1(NativeWidgetGtk, gboolean, OnConfigureEvent, - GdkEventConfigure*); - - // Invoked when the widget is destroyed and right before the object - // destruction. Useful for overriding. - virtual void OnDestroyed(GObject *where_the_object_was); - static void OnDestroyedThunk(gpointer data, GObject *where_the_object_was) { - reinterpret_cast<NativeWidgetGtk*>(data)->OnDestroyed(where_the_object_was); - } - - // Invoked when gtk grab is stolen by other GtkWidget in the same - // application. - virtual void HandleGtkGrabBroke(); - - const internal::NativeWidgetDelegate* delegate() const { return delegate_; } - internal::NativeWidgetDelegate* delegate() { return delegate_; } - - private: - class DropObserver; - friend class DropObserver; - - // Overridden from internal::InputMethodDelegate - virtual void DispatchKeyEventPostIME(const KeyEvent& key) OVERRIDE; - - void SetInitParams(const Widget::InitParams& params); - - // This is called only when the window is transparent. - CHROMEGTK_CALLBACK_1(NativeWidgetGtk, gboolean, OnWindowPaint, - GdkEventExpose*); - - // Callbacks for expose event on child widgets. See the description of - // RegisterChildChildExposeHandler. - void OnChildExpose(GtkWidget* child); - static gboolean ChildExposeHandler(GtkWidget* widget, GdkEventExpose* event); - - // Creates the GtkWidget. - void CreateGtkWidget(const Widget::InitParams& params); - - // Invoked from create widget to enable the various bits needed for a - // transparent background. This is only invoked if MakeTransparent has been - // invoked. - void ConfigureWidgetForTransparentBackground(GtkWidget* parent); - - // Invoked from create widget to enable the various bits needed for a - // window which doesn't receive events. - void ConfigureWidgetForIgnoreEvents(); - - // A utility function to draw a transparent background onto the |widget|. - static void DrawTransparentBackground(GtkWidget* widget, - GdkEventExpose* event); - - // Asks the delegate if any to save the window's location and size. - void SaveWindowPosition(); - - // A delegate implementation that handles events received here. - // See class documentation for Widget in widget.h for a note about ownership. - internal::NativeWidgetDelegate* delegate_; - - // Our native views. If we're a window/popup, then widget_ is the window and - // window_contents_ is a GtkFixed. If we're not a window/popup, then widget_ - // and window_contents_ point to the same GtkFixed. - GtkWidget* widget_; - GtkWidget* window_contents_; - - // Child GtkWidgets created with no parent need to be parented to a valid top - // level window otherwise Gtk throws a fit. |null_parent_| is an invisible - // popup that such GtkWidgets are parented to. - static GtkWidget* null_parent_; - - // True if the widget is a child of some other widget. - bool child_; - - // The TooltipManager. - // WARNING: RootView's destructor calls into the TooltipManager. As such, this - // must be destroyed AFTER root_view_. - scoped_ptr<TooltipManager> tooltip_manager_; - - scoped_ptr<DropTargetGtk> drop_target_; - - // The following factory is used to delay destruction. - base::WeakPtrFactory<NativeWidgetGtk> close_widget_factory_; - - // See class documentation for Widget in widget.h for a note about ownership. - Widget::InitParams::Ownership ownership_; - - // See description above make_transparent for details. - bool transparent_; - - // Makes the window pass all events through to any windows behind it. - // Set during SetInitParams before the widget is created. The actual work of - // making the window ignore events is done by ConfigureWidgetForIgnoreEvents. - bool ignore_events_; - - // See note in DropObserver for details on this. - bool ignore_drag_leave_; - - unsigned char opacity_; - - // This is non-null during the life of DoDrag and contains the actual data - // for the drag. - const OSExchangeDataProviderGtk* drag_data_; - - // True to enable debug painting. Enabling causes the damaged - // region to be painted to flash in red. - static bool debug_paint_enabled_; - - // State of the window, such as fullscreen, hidden... - GdkWindowState window_state_; - - // Are we active? - bool is_active_; - - // See make_transient_to_parent for a description. - bool transient_to_parent_; - - // Last size supplied to OnSizeAllocate. We cache this as any time the - // size of a GtkWidget changes size_allocate is called, even if the size - // didn't change. If we didn't cache this and ignore calls when the size - // hasn't changed, we can end up getting stuck in a never ending loop. - gfx::Size size_; - - // This is initially false and when the first focus-in event is received this - // is set to true and no additional processing is done. Subsequently when - // focus-in is received we do the normal focus manager processing. - // - // This behavior is necessitated by Gtk/X sending focus events - // asynchronously. The initial sequence for windows is typically: show, - // request focus on some widget. Because of async events on Gtk this becomes - // show, request focus, get focus in event which ends up clearing focus - // (first request to FocusManager::RestoreFocusedView ends up clearing focus). - bool got_initial_focus_in_; - - // If true, we've received a focus-in event. If false we've received a - // focus-out event. We can get multiple focus-out events in a row, we use - // this to determine whether we should process the event. - bool has_focus_; - - // If true, the window stays on top of the screen. This is only used - // for types other than TYPE_CHILD. - bool always_on_top_; - - // If true, we enable the content widget's double buffering. - // This is false by default. - bool is_double_buffered_; - - // Valid for the lifetime of StartDragForViewFromMouseEvent, indicates the - // view the drag started from. - View* dragged_view_; - - // If the widget has ever been painted. This is used to guarantee - // that window manager shows the window only after the window is painted. - bool painted_; - - // Have we done a pointer grab? - bool has_pointer_grab_; - - // Have we done a keyboard grab? - bool has_keyboard_grab_; - - // ID of the 'grab-notify' signal. If non-zero we're listening for - // 'grab-notify' events. - glong grab_notify_signal_id_; - - // If we were created for a menu. - bool is_menu_; - - scoped_ptr<ui::GtkSignalRegistrar> signal_registrar_; - scoped_ptr<ui::GtkSignalRegistrar> destroy_signal_registrar_; - - DISALLOW_COPY_AND_ASSIGN(NativeWidgetGtk); -}; - -} // namespace views - -#endif // UI_VIEWS_WIDGET_NATIVE_WIDGET_GTK_H_ diff --git a/ui/views/widget/native_widget_test_utils_gtk.cc b/ui/views/widget/native_widget_test_utils_gtk.cc deleted file mode 100644 index 3f3fc76..0000000 --- a/ui/views/widget/native_widget_test_utils_gtk.cc +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/widget/native_widget_test_utils.h" - -#include "ui/views/view.h" -#include "ui/views/widget/native_widget_private.h" -#include "ui/views/widget/widget.h" - -namespace views { -namespace internal { - -namespace { - -NativeWidgetPrivate* CreateNativeWidgetOfType(Widget::InitParams::Type type) { - Widget* widget = new Widget; - Widget::InitParams params(type); - params.ownership = views::Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET; - params.bounds = gfx::Rect(10, 10, 200, 200); - widget->Init(params); - return widget->native_widget_private(); -} - -} // namespace - -NativeWidgetPrivate* CreateNativeWidget() { - return CreateNativeWidgetOfType(Widget::InitParams::TYPE_POPUP); -} - -NativeWidgetPrivate* CreateNativeSubWidget() { - return CreateNativeWidgetOfType(Widget::InitParams::TYPE_CONTROL); -} - -} // namespace internal -} // namespace ui diff --git a/ui/views/widget/tooltip_manager_gtk.cc b/ui/views/widget/tooltip_manager_gtk.cc deleted file mode 100644 index 8114128..0000000 --- a/ui/views/widget/tooltip_manager_gtk.cc +++ /dev/null @@ -1,174 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/widget/tooltip_manager_gtk.h" - -#include "base/logging.h" -#include "base/utf_string_conversions.h" -#include "ui/gfx/font.h" -#include "ui/gfx/screen.h" -#include "ui/views/focus/focus_manager.h" -#include "ui/views/view.h" -#include "ui/views/widget/native_widget_gtk.h" - -// WARNING: this implementation is good for a start, but it doesn't give us -// control of tooltip positioning both on mouse events and when showing from -// keyboard. We may need to write our own to give us the control we need. - -namespace views { - -static gfx::Font* LoadDefaultFont() { - // Create a tooltip widget and extract the font from it (we have to realize - // it to make sure the correct font gets set). - GtkWidget* window = gtk_window_new(GTK_WINDOW_POPUP); - gtk_widget_set_name(window, "gtk-tooltip"); - GtkWidget* label = gtk_label_new(""); - gtk_widget_show(label); - - gtk_container_add(GTK_CONTAINER(window), label); - gtk_widget_realize(window); - - GtkStyle* style = gtk_widget_get_style(label); - gfx::Font* font = new gfx::Font(style->font_desc); - - gtk_widget_destroy(window); - - return font; -} - -// static -int TooltipManager::GetTooltipHeight() { - // This is only used to position the tooltip, and we don't yet support - // positioning the tooltip, it isn't worth trying to implement this. - return 0; -} - -// static -gfx::Font TooltipManager::GetDefaultFont() { - static gfx::Font* font = NULL; - if (!font) - font = LoadDefaultFont(); - - return *font; -} - -// static -int TooltipManager::GetMaxWidth(int x, int y) { - gfx::Rect monitor_bounds = - gfx::Screen::GetMonitorAreaNearestPoint(gfx::Point(x, y)); - // GtkLabel (gtk_label_ensure_layout) forces wrapping at this size. We mirror - // the size here otherwise tooltips wider than the size used by gtklabel end - // up with extraneous empty lines. - return monitor_bounds.width() == 0 ? 800 : (monitor_bounds.width() + 1) / 2; -} - -TooltipManagerGtk::TooltipManagerGtk(NativeWidgetGtk* widget) - : widget_(widget), - keyboard_view_(NULL), - tooltip_window_(widget->window_contents()) { -} - -bool TooltipManagerGtk::ShowTooltip(int x, int y, bool for_keyboard, - GtkTooltip* tooltip) { - const View* view = NULL; - gfx::Point view_loc; - if (keyboard_view_) { - view = keyboard_view_; - view_loc.SetPoint(view->width() / 2, view->height() / 2); - } else if (!for_keyboard) { - View* root_view = widget_->GetWidget()->GetRootView(); - view = root_view->GetEventHandlerForPoint(gfx::Point(x, y)); - view_loc.SetPoint(x, y); - View::ConvertPointFromWidget(view, &view_loc); - } else { - const FocusManager* focus_manager = widget_->GetWidget()->GetFocusManager(); - if (focus_manager) { - view = focus_manager->GetFocusedView(); - if (view) - view_loc.SetPoint(view->width() / 2, view->height() / 2); - } - } - - if (!view) - return false; - - string16 text; - if (!view->GetTooltipText(view_loc, &text)) - return false; - - // Sets the area of the tooltip. This way if different views in the same - // widget have tooltips the tooltip doesn't get stuck at the same location. - gfx::Rect vis_bounds = view->GetVisibleBounds(); - gfx::Point widget_loc(vis_bounds.origin()); - View::ConvertPointToWidget(view, &widget_loc); - GdkRectangle tip_area = { widget_loc.x(), widget_loc.y(), - vis_bounds.width(), vis_bounds.height() }; - gtk_tooltip_set_tip_area(tooltip, &tip_area); - - int max_width, line_count; - gfx::Point screen_loc(x, y); - View::ConvertPointToScreen(widget_->GetWidget()->GetRootView(), &screen_loc); - TrimTooltipToFit(&text, &max_width, &line_count, screen_loc.x(), - screen_loc.y()); - tooltip_window_.SetTooltipText(text); - - return true; -} - -void TooltipManagerGtk::UpdateTooltip() { - // UpdateTooltip may be invoked after the widget has been destroyed. - GtkWidget* widget = widget_->GetNativeView(); - if (!widget) - return; - - GdkDisplay* display = gtk_widget_get_display(widget); - if (display) - gtk_tooltip_trigger_tooltip_query(display); -} - -void TooltipManagerGtk::TooltipTextChanged(View* view) { - UpdateTooltip(); -} - -void TooltipManagerGtk::ShowKeyboardTooltip(View* view) { - if (view == keyboard_view_) - return; // We're already showing the tip for the specified view. - - // We have to hide the current tooltip, then show again. - HideKeyboardTooltip(); - - string16 tooltip_text; - if (!view->GetTooltipText(gfx::Point(), &tooltip_text)) - return; // The view doesn't have a tooltip, nothing to do. - - keyboard_view_ = view; - if (!SendShowHelpSignal()) { - keyboard_view_ = NULL; - return; - } -} - -void TooltipManagerGtk::HideKeyboardTooltip() { - if (!keyboard_view_) - return; - - SendShowHelpSignal(); - keyboard_view_ = NULL; -} - -bool TooltipManagerGtk::SendShowHelpSignal() { - GtkWidget* widget = widget_->window_contents(); - GType itype = G_TYPE_FROM_INSTANCE(G_OBJECT(widget)); - guint signal_id; - GQuark detail; - if (!g_signal_parse_name("show_help", itype, &signal_id, &detail, FALSE)) { - NOTREACHED(); - return false; - } - gboolean result; - g_signal_emit(widget, signal_id, 0, GTK_WIDGET_HELP_TOOLTIP, &result); - return true; -} - -} // namespace views diff --git a/ui/views/widget/tooltip_manager_gtk.h b/ui/views/widget/tooltip_manager_gtk.h deleted file mode 100644 index d1c4454..0000000 --- a/ui/views/widget/tooltip_manager_gtk.h +++ /dev/null @@ -1,54 +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_VIEWS_WIDGET_TOOLTIP_MANAGER_GTK_H_ -#define UI_VIEWS_WIDGET_TOOLTIP_MANAGER_GTK_H_ -#pragma once - -#include <gtk/gtk.h> - -#include "base/compiler_specific.h" -#include "ui/base/gtk/tooltip_window_gtk.h" -#include "ui/views/widget/tooltip_manager.h" - -namespace views { - -class NativeWidgetGtk; - -// TooltipManager implementation for Gtk. -class TooltipManagerGtk : public TooltipManager { - public: - explicit TooltipManagerGtk(NativeWidgetGtk* widget); - virtual ~TooltipManagerGtk() {} - - // Shows the tooltip at the specified location. Returns true if the tooltip - // should be shown, false otherwise. - bool ShowTooltip(int x, int y, bool for_keyboard, GtkTooltip* gtk_tooltip); - - // TooltipManager. - virtual void UpdateTooltip() OVERRIDE; - virtual void TooltipTextChanged(View* view) OVERRIDE; - virtual void ShowKeyboardTooltip(View* view) OVERRIDE; - virtual void HideKeyboardTooltip() OVERRIDE; - - private: - // Sends the show_help signal to widget_. This signal triggers showing the - // keyboard tooltip if it isn't showing, or hides it if it is showing. - bool SendShowHelpSignal(); - - // Our owner. - NativeWidgetGtk* widget_; - - // The view supplied to the last invocation of ShowKeyboardTooltip. - View* keyboard_view_; - - // Customized tooltip window. - ui::TooltipWindowGtk tooltip_window_; - - DISALLOW_COPY_AND_ASSIGN(TooltipManagerGtk); -}; - -} // namespace views - -#endif // UI_VIEWS_WIDGET_TOOLTIP_MANAGER_GTK_H_ |