Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(126)

Unified Diff: chrome/browser/ui/gtk/panels/panel_gtk.cc

Issue 231733005: Delete the GTK+ port of Chrome. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Remerge to ToT Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/gtk/panels/panel_gtk.cc
diff --git a/chrome/browser/ui/gtk/panels/panel_gtk.cc b/chrome/browser/ui/gtk/panels/panel_gtk.cc
deleted file mode 100644
index 274cbb3c4887b4405f1c489d80b3f7d078c9734f..0000000000000000000000000000000000000000
--- a/chrome/browser/ui/gtk/panels/panel_gtk.cc
+++ /dev/null
@@ -1,1255 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/ui/gtk/panels/panel_gtk.h"
-
-#include <gdk/gdk.h>
-#include <gdk/gdkkeysyms.h>
-#include <X11/XF86keysym.h>
-
-#include "base/bind.h"
-#include "base/debug/trace_event.h"
-#include "base/logging.h"
-#include "base/message_loop/message_loop.h"
-#include "base/strings/utf_string_conversions.h"
-#include "chrome/app/chrome_command_ids.h"
-#include "chrome/browser/chrome_notification_types.h"
-#include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog_queue.h"
-#include "chrome/browser/ui/gtk/custom_button.h"
-#include "chrome/browser/ui/gtk/gtk_util.h"
-#include "chrome/browser/ui/gtk/gtk_window_util.h"
-#include "chrome/browser/ui/gtk/panels/panel_drag_gtk.h"
-#include "chrome/browser/ui/gtk/panels/panel_titlebar_gtk.h"
-#include "chrome/browser/ui/panels/display_settings_provider.h"
-#include "chrome/browser/ui/panels/panel.h"
-#include "chrome/browser/ui/panels/panel_constants.h"
-#include "chrome/browser/ui/panels/panel_manager.h"
-#include "chrome/browser/ui/panels/stacked_panel_collection.h"
-#include "chrome/browser/web_applications/web_app.h"
-#include "content/public/browser/native_web_keyboard_event.h"
-#include "content/public/browser/notification_service.h"
-#include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
-#include "grit/ui_resources.h"
-#include "ui/base/accelerators/platform_accelerator_gtk.h"
-#include "ui/base/gtk/gtk_expanded_container.h"
-#include "ui/base/gtk/gtk_hig_constants.h"
-#include "ui/base/x/active_window_watcher_x.h"
-#include "ui/base/x/x11_util.h"
-#include "ui/gfx/canvas.h"
-#include "ui/gfx/gtk_compat.h"
-#include "ui/gfx/image/cairo_cached_surface.h"
-#include "ui/gfx/image/image.h"
-
-using content::NativeWebKeyboardEvent;
-using content::WebContents;
-
-namespace {
-
-const char* kPanelWindowKey = "__PANEL_GTK__";
-
-// The number of milliseconds between loading animation frames.
-const int kLoadingAnimationFrameTimeMs = 30;
-
-// The frame border is only visible in restored mode and is hardcoded to 4 px
-// on each side regardless of the system window border size.
-const int kFrameBorderThickness = 4;
-// While resize areas on Windows are normally the same size as the window
-// borders, our top area is shrunk by 1 px to make it easier to move the window
-// around with our thinner top grabbable strip. (Incidentally, our side and
-// bottom resize areas don't match the frame border thickness either -- they
-// span the whole nonclient area, so there's no "dead zone" for the mouse.)
-const int kTopResizeAdjust = 1;
-// In the window corners, the resize areas don't actually expand bigger, but
-// the 16 px at the end of each edge triggers diagonal resizing.
-const int kResizeAreaCornerSize = 16;
-
-// Colors used to draw frame background under default theme.
-const SkColor kActiveBackgroundDefaultColor = SkColorSetRGB(0x3a, 0x3d, 0x3d);
-const SkColor kInactiveBackgroundDefaultColor = SkColorSetRGB(0x7a, 0x7c, 0x7c);
-const SkColor kAttentionBackgroundDefaultColor =
- SkColorSetRGB(0x53, 0xa9, 0x3f);
-const SkColor kMinimizeBackgroundDefaultColor = SkColorSetRGB(0xf5, 0xf4, 0xf0);
-const SkColor kMinimizeBorderDefaultColor = SkColorSetRGB(0xc9, 0xc9, 0xc9);
-
-// Set minimium width for window really small.
-const int kMinWindowWidth = 26;
-
-// Table of supported accelerators in Panels.
-const struct AcceleratorMapping {
- guint keyval;
- int command_id;
- GdkModifierType modifier_type;
-} kAcceleratorMap[] = {
- // Window controls.
- { GDK_w, IDC_CLOSE_WINDOW, GDK_CONTROL_MASK },
- { GDK_w, IDC_CLOSE_WINDOW,
- GdkModifierType(GDK_CONTROL_MASK | GDK_SHIFT_MASK) },
- { GDK_q, IDC_EXIT, GdkModifierType(GDK_CONTROL_MASK | GDK_SHIFT_MASK) },
-
- // Zoom level.
- { GDK_KP_Add, IDC_ZOOM_PLUS, GDK_CONTROL_MASK },
- { GDK_plus, IDC_ZOOM_PLUS,
- GdkModifierType(GDK_CONTROL_MASK | GDK_SHIFT_MASK) },
- { GDK_equal, IDC_ZOOM_PLUS, GDK_CONTROL_MASK },
- { XF86XK_ZoomIn, IDC_ZOOM_PLUS, GdkModifierType(0) },
- { GDK_KP_0, IDC_ZOOM_NORMAL, GDK_CONTROL_MASK },
- { GDK_0, IDC_ZOOM_NORMAL, GDK_CONTROL_MASK },
- { GDK_KP_Subtract, IDC_ZOOM_MINUS, GDK_CONTROL_MASK },
- { GDK_minus, IDC_ZOOM_MINUS, GDK_CONTROL_MASK },
- { GDK_underscore, IDC_ZOOM_MINUS,
- GdkModifierType(GDK_CONTROL_MASK | GDK_SHIFT_MASK) },
- { XF86XK_ZoomOut, IDC_ZOOM_MINUS, GdkModifierType(0) },
-
- // Navigation.
- { GDK_Escape, IDC_STOP, GdkModifierType(0) },
- { XF86XK_Stop, IDC_STOP, GdkModifierType(0) },
- { GDK_r, IDC_RELOAD, GDK_CONTROL_MASK },
- { GDK_r, IDC_RELOAD_IGNORING_CACHE,
- GdkModifierType(GDK_CONTROL_MASK|GDK_SHIFT_MASK) },
- { GDK_F5, IDC_RELOAD, GdkModifierType(0) },
- { GDK_F5, IDC_RELOAD_IGNORING_CACHE, GDK_CONTROL_MASK },
- { GDK_F5, IDC_RELOAD_IGNORING_CACHE, GDK_SHIFT_MASK },
- { XF86XK_Reload, IDC_RELOAD, GdkModifierType(0) },
- { XF86XK_Refresh, IDC_RELOAD, GdkModifierType(0) },
-
- // Editing.
- { GDK_c, IDC_COPY, GDK_CONTROL_MASK },
- { GDK_x, IDC_CUT, GDK_CONTROL_MASK },
- { GDK_v, IDC_PASTE, GDK_CONTROL_MASK },
-
- // Dev tools.
- { GDK_i, IDC_DEV_TOOLS,
- GdkModifierType(GDK_CONTROL_MASK | GDK_SHIFT_MASK) },
- { GDK_j, IDC_DEV_TOOLS_CONSOLE,
- GdkModifierType(GDK_CONTROL_MASK | GDK_SHIFT_MASK) },
-
-};
-
-// Table of accelerator mappings to command ids.
-typedef std::map<ui::Accelerator, int> AcceleratorMap;
-
-const AcceleratorMap& GetAcceleratorTable() {
- CR_DEFINE_STATIC_LOCAL(AcceleratorMap, accelerator_table, ());
- if (accelerator_table.empty()) {
- for (size_t i = 0; i < arraysize(kAcceleratorMap); ++i) {
- const AcceleratorMapping& entry = kAcceleratorMap[i];
- ui::Accelerator accelerator = ui::AcceleratorForGdkKeyCodeAndModifier(
- entry.keyval, entry.modifier_type);
- accelerator_table[accelerator] = entry.command_id;
- }
- }
- return accelerator_table;
-}
-
-gfx::Image CreateImageForColor(SkColor color) {
- gfx::Canvas canvas(gfx::Size(1, 1), 1.0f, true);
- canvas.DrawColor(color);
- return gfx::Image(gfx::ImageSkia(canvas.ExtractImageRep()));
-}
-
-const gfx::Image GetActiveBackgroundDefaultImage() {
- CR_DEFINE_STATIC_LOCAL(gfx::Image, image, ());
- if (image.IsEmpty())
- image = CreateImageForColor(kActiveBackgroundDefaultColor);
- return image;
-}
-
-gfx::Image GetInactiveBackgroundDefaultImage() {
- CR_DEFINE_STATIC_LOCAL(gfx::Image, image, ());
- if (image.IsEmpty())
- image = CreateImageForColor(kInactiveBackgroundDefaultColor);
- return image;
-}
-
-gfx::Image GetAttentionBackgroundDefaultImage() {
- CR_DEFINE_STATIC_LOCAL(gfx::Image, image, ());
- if (image.IsEmpty())
- image = CreateImageForColor(kAttentionBackgroundDefaultColor);
- return image;
-}
-
-gfx::Image GetMinimizeBackgroundDefaultImage() {
- CR_DEFINE_STATIC_LOCAL(gfx::Image, image, ());
- if (image.IsEmpty())
- image = CreateImageForColor(kMinimizeBackgroundDefaultColor);
- return image;
-}
-
-// Used to stash a pointer to the Panel window inside the native
-// Gtk window for retrieval in static callbacks.
-GQuark GetPanelWindowQuarkKey() {
- static GQuark quark = g_quark_from_static_string(kPanelWindowKey);
- return quark;
-}
-
-// Size of window frame. Empty until first panel has been allocated
-// and sized. Frame size won't change for other panels so it can be
-// computed once for all panels.
-gfx::Size& GetFrameSize() {
- CR_DEFINE_STATIC_LOCAL(gfx::Size, frame_size, ());
- return frame_size;
-}
-
-void SetFrameSize(const gfx::Size& new_size) {
- gfx::Size& frame_size = GetFrameSize();
- frame_size.SetSize(new_size.width(), new_size.height());
-}
-
-} // namespace
-
-// static
-NativePanel* Panel::CreateNativePanel(Panel* panel,
- const gfx::Rect& bounds,
- bool always_on_top) {
- PanelGtk* panel_gtk = new PanelGtk(panel, bounds, always_on_top);
- panel_gtk->Init();
- return panel_gtk;
-}
-
-PanelGtk::PanelGtk(Panel* panel, const gfx::Rect& bounds, bool always_on_top)
- : panel_(panel),
- bounds_(bounds),
- always_on_top_(always_on_top),
- is_shown_(false),
- paint_state_(PAINT_AS_INACTIVE),
- is_drawing_attention_(false),
- frame_cursor_(NULL),
- is_active_(!ui::ActiveWindowWatcherX::WMSupportsActivation()),
- is_minimized_(false),
- window_(NULL),
- window_container_(NULL),
- window_vbox_(NULL),
- render_area_event_box_(NULL),
- contents_expanded_(NULL),
- accel_group_(NULL),
- corner_style_(panel::ALL_ROUNDED) {
-}
-
-PanelGtk::~PanelGtk() {
- ui::ActiveWindowWatcherX::RemoveObserver(this);
-}
-
-void PanelGtk::Init() {
- ui::ActiveWindowWatcherX::AddObserver(this);
-
- window_ = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL));
- g_object_set_qdata(G_OBJECT(window_), GetPanelWindowQuarkKey(), this);
- gtk_widget_add_events(GTK_WIDGET(window_), GDK_BUTTON_PRESS_MASK |
- GDK_POINTER_MOTION_MASK);
- gtk_window_set_decorated(window_, false);
-
- // Disable the resize gripper on Ubuntu.
- gtk_window_util::DisableResizeGrip(window_);
-
- // Add this window to its own unique window group to allow for
- // window-to-parent modality.
- gtk_window_group_add_window(gtk_window_group_new(), window_);
- g_object_unref(gtk_window_get_group(window_));
-
- // Set minimum height for the window.
- GdkGeometry hints;
- hints.min_height = panel::kMinimizedPanelHeight;
- hints.min_width = kMinWindowWidth;
- gtk_window_set_geometry_hints(
- window_, GTK_WIDGET(window_), &hints, GDK_HINT_MIN_SIZE);
-
- // Connect signal handlers to the window.
- g_signal_connect(window_, "delete-event",
- G_CALLBACK(OnMainWindowDeleteEventThunk), this);
- g_signal_connect(window_, "destroy",
- G_CALLBACK(OnMainWindowDestroyThunk), this);
- g_signal_connect(window_, "configure-event",
- G_CALLBACK(OnConfigureThunk), this);
- g_signal_connect(window_, "window-state-event",
- G_CALLBACK(OnWindowStateThunk), this);
- g_signal_connect(window_, "key-press-event",
- G_CALLBACK(OnKeyPressThunk), this);
- g_signal_connect(window_, "motion-notify-event",
- G_CALLBACK(OnMouseMoveEventThunk), this);
- g_signal_connect(window_, "button-press-event",
- G_CALLBACK(OnButtonPressEventThunk), this);
-
- // This vbox contains the titlebar and the render area, but not
- // the custom frame border.
- window_vbox_ = gtk_vbox_new(FALSE, 0);
- gtk_widget_show(window_vbox_);
-
- // TODO(jennb): add GlobalMenuBar after refactoring out Browser.
-
- // The window container draws the custom window frame.
- window_container_ = gtk_alignment_new(0.0, 0.0, 1.0, 1.0);
- gtk_widget_set_name(window_container_, "chrome-custom-frame-border");
- gtk_widget_set_app_paintable(window_container_, TRUE);
- gtk_widget_set_double_buffered(window_container_, FALSE);
- gtk_widget_set_redraw_on_allocate(window_container_, TRUE);
- gtk_alignment_set_padding(GTK_ALIGNMENT(window_container_), 0,
- kFrameBorderThickness, kFrameBorderThickness, kFrameBorderThickness);
- g_signal_connect(window_container_, "expose-event",
- G_CALLBACK(OnCustomFrameExposeThunk), this);
- gtk_container_add(GTK_CONTAINER(window_container_), window_vbox_);
-
- // Build the titlebar.
- titlebar_.reset(new PanelTitlebarGtk(this));
- titlebar_->Init();
- gtk_box_pack_start(GTK_BOX(window_vbox_), titlebar_->widget(), FALSE, FALSE,
- 0);
- g_signal_connect(titlebar_->widget(), "button-press-event",
- G_CALLBACK(OnTitlebarButtonPressEventThunk), this);
- g_signal_connect(titlebar_->widget(), "button-release-event",
- G_CALLBACK(OnTitlebarButtonReleaseEventThunk), this);
-
- contents_expanded_ = gtk_expanded_container_new();
- gtk_widget_show(contents_expanded_);
-
- render_area_event_box_ = gtk_event_box_new();
- // Set a white background so during startup the user sees white in the
- // content area before we get a WebContents in place.
- gtk_widget_modify_bg(render_area_event_box_, GTK_STATE_NORMAL,
- &ui::kGdkWhite);
- gtk_container_add(GTK_CONTAINER(render_area_event_box_),
- contents_expanded_);
- gtk_widget_show(render_area_event_box_);
- gtk_box_pack_end(GTK_BOX(window_vbox_), render_area_event_box_,
- TRUE, TRUE, 0);
-
- gtk_container_add(GTK_CONTAINER(window_), window_container_);
- gtk_widget_show(window_container_);
-
- ConnectAccelerators();
- SetPanelAlwaysOnTop(always_on_top_);
-}
-
-void PanelGtk::SetWindowCornerStyle(panel::CornerStyle corner_style) {
- corner_style_ = corner_style;
- UpdateWindowShape();
-}
-
-void PanelGtk::MinimizePanelBySystem() {
- gtk_window_iconify(window_);
-}
-
-bool PanelGtk::IsPanelMinimizedBySystem() const {
- return is_minimized_;
-}
-
-bool PanelGtk::IsPanelShownOnActiveDesktop() const {
- // IsWindowVisible checks _NET_WM_DESKTOP.
- if (!ui::IsWindowVisible(ui::GetX11WindowFromGtkWidget(GTK_WIDGET(window_))))
- return false;
-
- // Certain window manager, like Unity, does not update _NET_WM_DESKTOP when a
- // window is moved to other workspace. However, it treats all workspaces as
- // concatenated together in one big coordinate space. When the user switches
- // to another workspace, the window manager will update the origins of all
- // windows in previous active workspace to move by the size of display
- // area.
- gfx::Rect display_area = PanelManager::GetInstance()->
- display_settings_provider()->GetDisplayAreaMatching(bounds_);
- int win_x = 0, win_y = 0;
- gdk_window_get_origin(gtk_widget_get_window(GTK_WIDGET(window_)),
- &win_x, &win_y);
- return abs(win_x - bounds_.x()) < display_area.width() &&
- abs(win_y - bounds_.y()) < display_area.height();
-}
-
-void PanelGtk::ShowShadow(bool show) {
- // Shadow is not supported for GTK panel.
-}
-
-void PanelGtk::UpdateWindowShape() {
- int width = configure_size_.width();
- int height = configure_size_.height();
- if (!width || !height)
- return;
-
- GdkRegion* mask;
- if (corner_style_ & panel::TOP_ROUNDED) {
- GdkRectangle top_top_rect = { 3, 0, width - 6, 1 };
- GdkRectangle top_mid_rect = { 1, 1, width - 2, 2 };
- mask = gdk_region_rectangle(&top_top_rect);
- gdk_region_union_with_rect(mask, &top_mid_rect);
- } else {
- GdkRectangle top_rect = { 0, 0, width, 3 };
- mask = gdk_region_rectangle(&top_rect);
- }
-
- if (corner_style_ & panel::BOTTOM_ROUNDED) {
- GdkRectangle mid_rect = { 0, 3, width, height - 6 };
- GdkRectangle bottom_mid_rect = { 1, height - 3, width - 2, 2 };
- GdkRectangle bottom_bottom_rect = { 3, height - 1, width - 6, 1 };
- gdk_region_union_with_rect(mask, &mid_rect);
- gdk_region_union_with_rect(mask, &bottom_mid_rect);
- gdk_region_union_with_rect(mask, &bottom_bottom_rect);
- } else {
- GdkRectangle mid_rect = { 0, 3, width, height - 3 };
- gdk_region_union_with_rect(mask, &mid_rect);
- }
-
- gdk_window_shape_combine_region(
- gtk_widget_get_window(GTK_WIDGET(window_)), mask, 0, 0);
- if (mask)
- gdk_region_destroy(mask);
-}
-
-gboolean PanelGtk::OnConfigure(GtkWidget* widget,
- GdkEventConfigure* event) {
- // When the window moves, we'll get multiple configure-event signals. We can
- // also get events when the bounds haven't changed, but the window's stacking
- // has, which we aren't interested in. http://crbug.com/70125
- gfx::Size new_size(event->width, event->height);
- if (new_size == configure_size_)
- return FALSE;
- configure_size_ = new_size;
-
- UpdateWindowShape();
-
- if (!GetFrameSize().IsEmpty())
- return FALSE;
-
- // Save the frame size allocated by the system as the
- // frame size will be affected when we shrink the panel smaller
- // than the frame (e.g. when the panel is minimized).
- SetFrameSize(GetNonClientFrameSize());
- panel_->OnWindowSizeAvailable();
-
- content::NotificationService::current()->Notify(
- chrome::NOTIFICATION_PANEL_WINDOW_SIZE_KNOWN,
- content::Source<Panel>(panel_.get()),
- content::NotificationService::NoDetails());
-
- return FALSE;
-}
-
-gboolean PanelGtk::OnWindowState(GtkWidget* widget,
- GdkEventWindowState* event) {
- is_minimized_ = event->new_window_state & GDK_WINDOW_STATE_ICONIFIED;
- return FALSE;
-}
-
-void PanelGtk::ConnectAccelerators() {
- accel_group_ = gtk_accel_group_new();
- gtk_window_add_accel_group(window_, accel_group_);
-
- const AcceleratorMap& accelerator_table = GetAcceleratorTable();
- for (AcceleratorMap::const_iterator iter = accelerator_table.begin();
- iter != accelerator_table.end(); ++iter) {
- gtk_accel_group_connect(
- accel_group_,
- ui::GetGdkKeyCodeForAccelerator(iter->first),
- ui::GetGdkModifierForAccelerator(iter->first),
- GtkAccelFlags(0),
- g_cclosure_new(G_CALLBACK(OnGtkAccelerator),
- GINT_TO_POINTER(iter->second), NULL));
- }
-}
-
-void PanelGtk::DisconnectAccelerators() {
- // Disconnecting the keys we connected to our accelerator group frees the
- // closures allocated in ConnectAccelerators.
- const AcceleratorMap& accelerator_table = GetAcceleratorTable();
- for (AcceleratorMap::const_iterator iter = accelerator_table.begin();
- iter != accelerator_table.end(); ++iter) {
- gtk_accel_group_disconnect_key(
- accel_group_,
- ui::GetGdkKeyCodeForAccelerator(iter->first),
- ui::GetGdkModifierForAccelerator(iter->first));
- }
- gtk_window_remove_accel_group(window_, accel_group_);
- g_object_unref(accel_group_);
- accel_group_ = NULL;
-}
-
-// static
-gboolean PanelGtk::OnGtkAccelerator(GtkAccelGroup* accel_group,
- GObject* acceleratable,
- guint keyval,
- GdkModifierType modifier,
- void* user_data) {
- DCHECK(acceleratable);
- int command_id = GPOINTER_TO_INT(user_data);
- PanelGtk* panel_gtk = static_cast<PanelGtk*>(
- g_object_get_qdata(acceleratable, GetPanelWindowQuarkKey()));
- return panel_gtk->panel()->ExecuteCommandIfEnabled(command_id);
-}
-
-gboolean PanelGtk::OnKeyPress(GtkWidget* widget, GdkEventKey* event) {
- // No way to deactivate a window in GTK, so ignore input if window
- // is supposed to be 'inactive'. See comments in DeactivatePanel().
- if (!is_active_)
- return TRUE;
-
- // Propagate the key event to child widget first, so we don't override
- // their accelerators.
- if (!gtk_window_propagate_key_event(GTK_WINDOW(widget), event)) {
- if (!gtk_window_activate_key(GTK_WINDOW(widget), event)) {
- gtk_bindings_activate_event(GTK_OBJECT(widget), event);
- }
- }
- return TRUE;
-}
-
-bool PanelGtk::GetWindowEdge(int x, int y, GdkWindowEdge* edge) const {
- // Only detect the window edge when panels can be resized by the user.
- // This method is used by the base class to detect when the cursor has
- // hit the window edge in order to change the cursor to a resize cursor
- // and to detect when to initiate a resize drag.
- panel::Resizability resizability = panel_->CanResizeByMouse();
- if (panel::NOT_RESIZABLE == resizability)
- return false;
-
- int width = bounds_.width();
- int height = bounds_.height();
- if (x < kFrameBorderThickness) {
- if (y < kResizeAreaCornerSize - kTopResizeAdjust &&
- (resizability & panel::RESIZABLE_TOP_LEFT)) {
- *edge = GDK_WINDOW_EDGE_NORTH_WEST;
- return true;
- } else if (y >= height - kResizeAreaCornerSize &&
- (resizability & panel::RESIZABLE_BOTTOM_LEFT)) {
- *edge = GDK_WINDOW_EDGE_SOUTH_WEST;
- return true;
- }
- } else if (x >= width - kFrameBorderThickness) {
- if (y < kResizeAreaCornerSize - kTopResizeAdjust &&
- (resizability & panel::RESIZABLE_TOP_RIGHT)) {
- *edge = GDK_WINDOW_EDGE_NORTH_EAST;
- return true;
- } else if (y >= height - kResizeAreaCornerSize &&
- (resizability & panel::RESIZABLE_BOTTOM_RIGHT)) {
- *edge = GDK_WINDOW_EDGE_SOUTH_EAST;
- return true;
- }
- }
-
- if (x < kFrameBorderThickness && (resizability & panel::RESIZABLE_LEFT)) {
- *edge = GDK_WINDOW_EDGE_WEST;
- return true;
- } else if (x >= width - kFrameBorderThickness &&
- (resizability & panel::RESIZABLE_RIGHT)) {
- *edge = GDK_WINDOW_EDGE_EAST;
- return true;
- }
-
- if (y < kFrameBorderThickness && (resizability & panel::RESIZABLE_TOP)) {
- *edge = GDK_WINDOW_EDGE_NORTH;
- return true;
- } else if (y >= height - kFrameBorderThickness &&
- (resizability & panel::RESIZABLE_BOTTOM)) {
- *edge = GDK_WINDOW_EDGE_SOUTH;
- return true;
- }
-
- return false;
-}
-
-gfx::Image PanelGtk::GetFrameBackground() const {
- switch (paint_state_) {
- case PAINT_AS_INACTIVE:
- return GetInactiveBackgroundDefaultImage();
- case PAINT_AS_ACTIVE:
- return GetActiveBackgroundDefaultImage();
- case PAINT_AS_MINIMIZED:
- return GetMinimizeBackgroundDefaultImage();
- case PAINT_FOR_ATTENTION:
- return GetAttentionBackgroundDefaultImage();
- default:
- NOTREACHED();
- return GetInactiveBackgroundDefaultImage();
- }
-}
-
-gboolean PanelGtk::OnCustomFrameExpose(GtkWidget* widget,
- GdkEventExpose* event) {
- TRACE_EVENT0("ui::gtk", "PanelGtk::OnCustomFrameExpose");
- cairo_t* cr = gdk_cairo_create(gtk_widget_get_window(widget));
- gdk_cairo_rectangle(cr, &event->area);
- cairo_clip(cr);
-
- // Update the painting state.
- int window_height = gdk_window_get_height(gtk_widget_get_window(widget));
- if (is_drawing_attention_)
- paint_state_ = PAINT_FOR_ATTENTION;
- else if (window_height <= panel::kMinimizedPanelHeight)
- paint_state_ = PAINT_AS_MINIMIZED;
- else if (is_active_)
- paint_state_ = PAINT_AS_ACTIVE;
- else
- paint_state_ = PAINT_AS_INACTIVE;
-
- // Draw the background.
- gfx::CairoCachedSurface* surface = GetFrameBackground().ToCairo();
- surface->SetSource(cr, widget, 0, 0);
- cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT);
- cairo_rectangle(cr, event->area.x, event->area.y,
- event->area.width, event->area.height);
- cairo_fill(cr);
-
- // Draw the border for the minimized panel only.
- if (paint_state_ == PAINT_AS_MINIMIZED) {
- cairo_move_to(cr, 0, 3);
- cairo_line_to(cr, 1, 2);
- cairo_line_to(cr, 1, 1);
- cairo_line_to(cr, 2, 1);
- cairo_line_to(cr, 3, 0);
- cairo_line_to(cr, event->area.width - 3, 0);
- cairo_line_to(cr, event->area.width - 2, 1);
- cairo_line_to(cr, event->area.width - 1, 1);
- cairo_line_to(cr, event->area.width - 1, 2);
- cairo_line_to(cr, event->area.width - 1, 3);
- cairo_line_to(cr, event->area.width - 1, event->area.height - 1);
- cairo_line_to(cr, 0, event->area.height - 1);
- cairo_close_path(cr);
- cairo_set_source_rgb(cr,
- SkColorGetR(kMinimizeBorderDefaultColor) / 255.0,
- SkColorGetG(kMinimizeBorderDefaultColor) / 255.0,
- SkColorGetB(kMinimizeBorderDefaultColor) / 255.0);
- cairo_set_line_width(cr, 1.0);
- cairo_stroke(cr);
- }
-
- cairo_destroy(cr);
-
- return FALSE; // Allow subwidgets to paint.
-}
-
-void PanelGtk::EnsureDragHelperCreated() {
- if (drag_helper_.get())
- return;
-
- drag_helper_.reset(new PanelDragGtk(panel_.get()));
- gtk_box_pack_end(GTK_BOX(window_vbox_), drag_helper_->widget(),
- FALSE, FALSE, 0);
-}
-
-gboolean PanelGtk::OnTitlebarButtonPressEvent(
- GtkWidget* widget, GdkEventButton* event) {
- if (event->button != 1)
- return TRUE;
- if (event->type != GDK_BUTTON_PRESS)
- return TRUE;
-
- // If the panel is in a stack, bring all other panels in the stack to the
- // top.
- StackedPanelCollection* stack = panel_->stack();
- if (stack) {
- for (StackedPanelCollection::Panels::const_iterator iter =
- stack->panels().begin();
- iter != stack->panels().end(); ++iter) {
- Panel* panel = *iter;
- GtkWindow* gtk_window = panel->GetNativeWindow();
- // If a panel is collapsed, we make it not to take focus. For such window,
- // it cannot be brought to the top by calling gdk_window_raise. To work
- // around this issue, we make it always-on-top first and then put it back
- // to normal. Note that this trick has been done for all panels in the
- // stack, regardless of whether it is collapsed or not.
- // There is one side-effect to this approach: if the panel being pressed
- // on is collapsed, clicking on the client area of the last active
- // window will not raise it above these panels.
- gtk_window_set_keep_above(gtk_window, true);
- gtk_window_set_keep_above(gtk_window, false);
- }
- } else {
- gdk_window_raise(gtk_widget_get_window(GTK_WIDGET(window_)));
- }
-
- EnsureDragHelperCreated();
- drag_helper_->InitialTitlebarMousePress(event, titlebar_->widget());
- return TRUE;
-}
-
-gboolean PanelGtk::OnTitlebarButtonReleaseEvent(
- GtkWidget* widget, GdkEventButton* event) {
- if (event->button != 1)
- return TRUE;
-
- panel_->OnTitlebarClicked((event->state & GDK_CONTROL_MASK) ?
- panel::APPLY_TO_ALL : panel::NO_MODIFIER);
- return TRUE;
-}
-
-gboolean PanelGtk::OnMouseMoveEvent(GtkWidget* widget,
- GdkEventMotion* event) {
- // This method is used to update the mouse cursor when over the edge of the
- // custom frame. If we're over some other widget, do nothing.
- if (event->window != gtk_widget_get_window(widget)) {
- // Reset the cursor.
- if (frame_cursor_) {
- frame_cursor_ = NULL;
- gdk_window_set_cursor(gtk_widget_get_window(GTK_WIDGET(window_)), NULL);
- }
- return FALSE;
- }
-
- // Update the cursor if we're on the custom frame border.
- GdkWindowEdge edge;
- bool has_hit_edge = GetWindowEdge(static_cast<int>(event->x),
- static_cast<int>(event->y), &edge);
- GdkCursorType new_cursor = has_hit_edge ?
- gtk_window_util::GdkWindowEdgeToGdkCursorType(edge) : GDK_LAST_CURSOR;
- GdkCursorType last_cursor =
- frame_cursor_ ? frame_cursor_->type : GDK_LAST_CURSOR;
-
- if (last_cursor != new_cursor) {
- frame_cursor_ = has_hit_edge ? gfx::GetCursor(new_cursor) : NULL;
- gdk_window_set_cursor(gtk_widget_get_window(GTK_WIDGET(window_)),
- frame_cursor_);
- }
- return FALSE;
-}
-
-gboolean PanelGtk::OnButtonPressEvent(GtkWidget* widget,
- GdkEventButton* event) {
- if (event->button != 1 || event->type != GDK_BUTTON_PRESS)
- return FALSE;
-
- // No way to deactivate a window in GTK, so we pretended it is deactivated.
- // See comments in DeactivatePanel().
- // Mouse click anywhere in window should re-activate window so do it now.
- if (!is_active_)
- panel_->Activate();
-
- // Make the button press coordinate relative to the panel window.
- int win_x, win_y;
- GdkWindow* gdk_window = gtk_widget_get_window(GTK_WIDGET(window_));
- gdk_window_get_origin(gdk_window, &win_x, &win_y);
-
- GdkWindowEdge edge;
- gfx::Point point(static_cast<int>(event->x_root - win_x),
- static_cast<int>(event->y_root - win_y));
- bool has_hit_edge = GetWindowEdge(point.x(), point.y(), &edge);
- if (has_hit_edge) {
- gdk_window_raise(gdk_window);
- EnsureDragHelperCreated();
- // Resize cursor was set by PanelGtk when mouse moved over window edge.
- GdkCursor* cursor =
- gdk_window_get_cursor(gtk_widget_get_window(GTK_WIDGET(window_)));
- drag_helper_->InitialWindowEdgeMousePress(event, cursor, edge);
- return TRUE;
- }
-
- return FALSE; // Continue to propagate the event.
-}
-
-void PanelGtk::ActiveWindowChanged(GdkWindow* active_window) {
- // Do nothing if we're in the process of closing the panel window.
- if (!window_)
- return;
-
- bool is_active = gtk_widget_get_window(GTK_WIDGET(window_)) == active_window;
- if (is_active == is_active_)
- return; // State did not change.
-
- if (is_active) {
- // If there's an app modal dialog (e.g., JS alert), try to redirect
- // the user's attention to the window owning the dialog.
- if (AppModalDialogQueue::GetInstance()->HasActiveDialog()) {
- AppModalDialogQueue::GetInstance()->ActivateModalDialog();
- return;
- }
- }
-
- is_active_ = is_active;
- titlebar_->UpdateTextColor();
- InvalidateWindow();
- panel_->OnActiveStateChanged(is_active_);
-}
-
-// Callback for the delete event. This event is fired when the user tries to
-// close the window.
-gboolean PanelGtk::OnMainWindowDeleteEvent(GtkWidget* widget,
- GdkEvent* event) {
- ClosePanel();
-
- // Return true to prevent the gtk window from being destroyed. Close will
- // destroy it for us.
- return TRUE;
-}
-
-void PanelGtk::OnMainWindowDestroy(GtkWidget* widget) {
- // BUG 8712. When we gtk_widget_destroy() in ClosePanel(), this will emit the
- // signal right away, and we will be here (while ClosePanel() is still in the
- // call stack). Let stack unwind before deleting the panel.
- //
- // We don't want to use DeleteSoon() here since it won't work on a nested pump
- // (like in UI tests).
- base::MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&base::DeletePointer<PanelGtk>, this));
-}
-
-void PanelGtk::ShowPanel() {
- gtk_window_present(window_);
- RevealPanel();
-}
-
-void PanelGtk::ShowPanelInactive() {
- gtk_window_set_focus_on_map(window_, false);
- gtk_widget_show(GTK_WIDGET(window_));
- RevealPanel();
-}
-
-void PanelGtk::RevealPanel() {
- DCHECK(!is_shown_);
- is_shown_ = true;
- SetBoundsInternal(bounds_);
-}
-
-gfx::Rect PanelGtk::GetPanelBounds() const {
- return bounds_;
-}
-
-void PanelGtk::SetPanelBounds(const gfx::Rect& bounds) {
- SetBoundsInternal(bounds);
-}
-
-void PanelGtk::SetPanelBoundsInstantly(const gfx::Rect& bounds) {
- SetBoundsInternal(bounds);
-}
-
-void PanelGtk::SetBoundsInternal(const gfx::Rect& bounds) {
- if (is_shown_) {
- gdk_window_move_resize(gtk_widget_get_window(GTK_WIDGET(window_)),
- bounds.x(), bounds.y(),
- bounds.width(), bounds.height());
- }
-
- bounds_ = bounds;
-
- titlebar_->SendEnterNotifyToCloseButtonIfUnderMouse();
- panel_->manager()->OnPanelAnimationEnded(panel_.get());
-}
-
-void PanelGtk::ClosePanel() {
- // We're already closing. Do nothing.
- if (!window_)
- return;
-
- if (!panel_->ShouldCloseWindow())
- return;
-
- if (drag_helper_.get())
- drag_helper_.reset();
-
- if (accel_group_)
- DisconnectAccelerators();
-
- // Cancel any pending callback from the loading animation timer.
- loading_animation_timer_.Stop();
-
- if (panel_->GetWebContents()) {
- // Hide the window (so it appears to have closed immediately).
- // When web contents are destroyed, we will be called back again.
- gtk_widget_hide(GTK_WIDGET(window_));
- panel_->OnWindowClosing();
- return;
- }
-
- GtkWidget* window = GTK_WIDGET(window_);
- // To help catch bugs in any event handlers that might get fired during the
- // destruction, set window_ to NULL before any handlers will run.
- window_ = NULL;
-
- panel_->OnNativePanelClosed();
-
- // We don't want GlobalMenuBar handling any notifications or commands after
- // the window is destroyed.
- // TODO(jennb): global_menu_bar_->Disable();
- gtk_widget_destroy(window);
-}
-
-void PanelGtk::ActivatePanel() {
- gtk_window_present(window_);
-
- // When the user clicks to expand the minimized panel, the panel has already
- // become an active window before gtk_window_present is called. Thus the
- // active window change event, fired by ActiveWindowWatcherXObserver, is not
- // triggered. We need to call ActiveWindowChanged manually to update panel's
- // active status. It is OK to call ActiveWindowChanged with the same active
- // window twice since the 2nd call is just a no-op.
- ActiveWindowChanged(gtk_widget_get_window(GTK_WIDGET(window_)));
-}
-
-void PanelGtk::DeactivatePanel() {
- // When a panel is deactivated, it should not be lowered to the bottom of the
- // z-order. We could put it behind other panel window.
- Panel* other_panel = NULL;
- // First, try to pick the sibling panel in the same stack.
- StackedPanelCollection* stack = panel_->stack();
- if (stack && stack->num_panels()) {
- other_panel = panel_ != stack->top_panel() ? stack->top_panel()
- : stack->bottom_panel();
- }
- // Then, try to pick other detached or stacked panel.
- if (!other_panel) {
- std::vector<Panel*> panels =
- panel_->manager()->GetDetachedAndStackedPanels();
- if (!panels.empty())
- other_panel = panel_ != panels.front() ? panels.front() : panels.back();
- }
-
- gdk_window_restack(
- gtk_widget_get_window(GTK_WIDGET(window_)),
- other_panel ? gtk_widget_get_window(
- GTK_WIDGET(other_panel->GetNativeWindow())) : NULL,
- false);
-
- // Per ICCCM: http://tronche.com/gui/x/icccm/sec-4.html#s-4.1.7
- // A convention is also required for clients that want to give up the
- // input focus. There is no safe value set for them to set the input
- // focus to; therefore, they should ignore input material.
- //
- // No way to deactive a GTK window. Pretend panel is deactivated
- // and ignore input.
- ActiveWindowChanged(NULL);
-}
-
-bool PanelGtk::IsPanelActive() const {
- return is_active_;
-}
-
-void PanelGtk::PreventActivationByOS(bool prevent_activation) {
- gtk_window_set_accept_focus(window_, !prevent_activation);
-}
-
-gfx::NativeWindow PanelGtk::GetNativePanelWindow() {
- return window_;
-}
-
-void PanelGtk::UpdatePanelTitleBar() {
- TRACE_EVENT0("ui::gtk", "PanelGtk::UpdatePanelTitleBar");
- base::string16 title = panel_->GetWindowTitle();
- gtk_window_set_title(window_, base::UTF16ToUTF8(title).c_str());
- titlebar_->UpdateTitleAndIcon();
-
- gfx::Image app_icon = panel_->app_icon();
- if (!app_icon.IsEmpty())
- gtk_util::SetWindowIcon(window_, panel_->profile(), app_icon.ToGdkPixbuf());
-}
-
-void PanelGtk::UpdatePanelLoadingAnimations(bool should_animate) {
- if (should_animate) {
- if (!loading_animation_timer_.IsRunning()) {
- // Loads are happening, and the timer isn't running, so start it.
- loading_animation_timer_.Start(FROM_HERE,
- base::TimeDelta::FromMilliseconds(kLoadingAnimationFrameTimeMs),
- this,
- &PanelGtk::LoadingAnimationCallback);
- }
- } else {
- if (loading_animation_timer_.IsRunning()) {
- loading_animation_timer_.Stop();
- // Loads are now complete, update the state if a task was scheduled.
- LoadingAnimationCallback();
- }
- }
-}
-
-void PanelGtk::LoadingAnimationCallback() {
- titlebar_->UpdateThrobber(panel_->GetWebContents());
-}
-
-void PanelGtk::PanelWebContentsFocused(content::WebContents* contents) {
- // Nothing to do.
-}
-
-void PanelGtk::PanelCut() {
- gtk_window_util::DoCut(window_, panel_->GetWebContents());
-}
-
-void PanelGtk::PanelCopy() {
- gtk_window_util::DoCopy(window_, panel_->GetWebContents());
-}
-
-void PanelGtk::PanelPaste() {
- gtk_window_util::DoPaste(window_, panel_->GetWebContents());
-}
-
-void PanelGtk::DrawAttention(bool draw_attention) {
- DCHECK((panel_->attention_mode() & Panel::USE_PANEL_ATTENTION) != 0);
-
- if (is_drawing_attention_ == draw_attention)
- return;
-
- is_drawing_attention_ = draw_attention;
-
- titlebar_->UpdateTextColor();
- InvalidateWindow();
-
- if ((panel_->attention_mode() & Panel::USE_SYSTEM_ATTENTION) != 0) {
- // May not be respected by all window managers.
- gtk_window_set_urgency_hint(window_, draw_attention);
- }
-}
-
-bool PanelGtk::IsDrawingAttention() const {
- return is_drawing_attention_;
-}
-
-void PanelGtk::HandlePanelKeyboardEvent(
- const NativeWebKeyboardEvent& event) {
- GdkEventKey* os_event = &event.os_event->key;
- if (os_event && event.type == blink::WebInputEvent::RawKeyDown)
- gtk_window_activate_key(window_, os_event);
-}
-
-void PanelGtk::FullScreenModeChanged(bool is_full_screen) {
- // No need to hide panels when entering the full-screen mode because the
- // full-screen window will automatically be placed above all other windows.
- if (is_full_screen)
- return;
-
- // Show the panel if not yet when leaving the full-screen mode. This is
- // because the panel is not shown when it is being created under full-screen
- // mode.
- GdkWindow* gdk_window = gtk_widget_get_window(GTK_WIDGET(window_));
- if (!GDK_IS_WINDOW(gdk_window) || !gdk_window_is_visible(gdk_window))
- ShowPanelInactive();
-}
-
-void PanelGtk::PanelExpansionStateChanging(
- Panel::ExpansionState old_state, Panel::ExpansionState new_state) {
-}
-
-void PanelGtk::AttachWebContents(content::WebContents* contents) {
- if (!contents)
- return;
- gfx::NativeView widget = contents->GetView()->GetNativeView();
- if (widget) {
- gtk_container_add(GTK_CONTAINER(contents_expanded_), widget);
- gtk_widget_show(widget);
- contents->WasShown();
- }
-}
-
-void PanelGtk::DetachWebContents(content::WebContents* contents) {
- gfx::NativeView widget = contents->GetView()->GetNativeView();
- if (widget) {
- GtkWidget* parent = gtk_widget_get_parent(widget);
- if (parent) {
- DCHECK_EQ(parent, contents_expanded_);
- gtk_container_remove(GTK_CONTAINER(contents_expanded_), widget);
- }
- }
-}
-
-gfx::Size PanelGtk::WindowSizeFromContentSize(
- const gfx::Size& content_size) const {
- gfx::Size& frame_size = GetFrameSize();
- return gfx::Size(content_size.width() + frame_size.width(),
- content_size.height() + frame_size.height());
-}
-
-gfx::Size PanelGtk::ContentSizeFromWindowSize(
- const gfx::Size& window_size) const {
- gfx::Size& frame_size = GetFrameSize();
- return gfx::Size(window_size.width() - frame_size.width(),
- window_size.height() - frame_size.height());
-}
-
-int PanelGtk::TitleOnlyHeight() const {
- gfx::Size& frame_size = GetFrameSize();
- if (!frame_size.IsEmpty())
- return panel::kTitlebarHeight;
-
- NOTREACHED() << "Checking title height before window allocated";
- return 0;
-}
-
-bool PanelGtk::IsPanelAlwaysOnTop() const {
- return always_on_top_;
-}
-
-void PanelGtk::SetPanelAlwaysOnTop(bool on_top) {
- always_on_top_ = on_top;
-
- gtk_window_set_keep_above(window_, on_top);
-
- // Do not show an icon in the task bar for always-on-top windows.
- // Window operations such as close, minimize etc. can only be done
- // from the panel UI.
- gtk_window_set_skip_taskbar_hint(window_, on_top);
-
- // Show always-on-top windows on all the virtual desktops.
- if (on_top)
- gtk_window_stick(window_);
- else
- gtk_window_unstick(window_);
-}
-
-void PanelGtk::UpdatePanelMinimizeRestoreButtonVisibility() {
- titlebar_->UpdateMinimizeRestoreButtonVisibility();
-}
-
-gfx::Size PanelGtk::GetNonClientFrameSize() const {
- GtkAllocation window_allocation;
- gtk_widget_get_allocation(window_container_, &window_allocation);
- GtkAllocation contents_allocation;
- gtk_widget_get_allocation(contents_expanded_, &contents_allocation);
- return gfx::Size(window_allocation.width - contents_allocation.width,
- window_allocation.height - contents_allocation.height);
-}
-
-void PanelGtk::InvalidateWindow() {
- GtkAllocation allocation;
- gtk_widget_get_allocation(GTK_WIDGET(window_), &allocation);
- gdk_window_invalidate_rect(gtk_widget_get_window(GTK_WIDGET(window_)),
- &allocation, TRUE);
-}
-
-// NativePanelTesting implementation.
-class GtkNativePanelTesting : public NativePanelTesting {
- public:
- explicit GtkNativePanelTesting(PanelGtk* panel_gtk);
-
- private:
- virtual void PressLeftMouseButtonTitlebar(
- const gfx::Point& mouse_location, panel::ClickModifier modifier) OVERRIDE;
- virtual void ReleaseMouseButtonTitlebar(
- panel::ClickModifier modifier) OVERRIDE;
- virtual void DragTitlebar(const gfx::Point& mouse_location) OVERRIDE;
- virtual void CancelDragTitlebar() OVERRIDE;
- virtual void FinishDragTitlebar() OVERRIDE;
- virtual bool VerifyDrawingAttention() const OVERRIDE;
- virtual bool VerifyActiveState(bool is_active) OVERRIDE;
- virtual bool VerifyAppIcon() const OVERRIDE;
- virtual bool VerifySystemMinimizeState() const OVERRIDE;
- virtual bool IsWindowVisible() const OVERRIDE;
- virtual bool IsWindowSizeKnown() const OVERRIDE;
- virtual bool IsAnimatingBounds() const OVERRIDE;
- virtual bool IsButtonVisible(
- panel::TitlebarButtonType button_type) const OVERRIDE;
- virtual panel::CornerStyle GetWindowCornerStyle() const OVERRIDE;
- virtual bool EnsureApplicationRunOnForeground() OVERRIDE;
-
- PanelGtk* panel_gtk_;
-};
-
-NativePanelTesting* PanelGtk::CreateNativePanelTesting() {
- return new GtkNativePanelTesting(this);
-}
-
-GtkNativePanelTesting::GtkNativePanelTesting(PanelGtk* panel_gtk)
- : panel_gtk_(panel_gtk) {
-}
-
-void GtkNativePanelTesting::PressLeftMouseButtonTitlebar(
- const gfx::Point& mouse_location, panel::ClickModifier modifier) {
-
- GdkEvent* event = gdk_event_new(GDK_BUTTON_PRESS);
- event->button.button = 1;
- event->button.x_root = mouse_location.x();
- event->button.y_root = mouse_location.y();
- if (modifier == panel::APPLY_TO_ALL)
- event->button.state |= GDK_CONTROL_MASK;
- panel_gtk_->OnTitlebarButtonPressEvent(
- NULL, reinterpret_cast<GdkEventButton*>(event));
- gdk_event_free(event);
- base::MessageLoopForUI::current()->RunUntilIdle();
-}
-
-void GtkNativePanelTesting::ReleaseMouseButtonTitlebar(
- panel::ClickModifier modifier) {
- GdkEvent* event = gdk_event_new(GDK_BUTTON_RELEASE);
- event->button.button = 1;
- if (modifier == panel::APPLY_TO_ALL)
- event->button.state |= GDK_CONTROL_MASK;
- if (panel_gtk_->drag_helper_.get()) {
- panel_gtk_->drag_helper_->OnButtonReleaseEvent(
- NULL, reinterpret_cast<GdkEventButton*>(event));
- } else {
- panel_gtk_->OnTitlebarButtonReleaseEvent(
- NULL, reinterpret_cast<GdkEventButton*>(event));
- }
- gdk_event_free(event);
- base::MessageLoopForUI::current()->RunUntilIdle();
-}
-
-void GtkNativePanelTesting::DragTitlebar(const gfx::Point& mouse_location) {
- if (!panel_gtk_->drag_helper_.get())
- return;
- GdkEvent* event = gdk_event_new(GDK_MOTION_NOTIFY);
- event->motion.x_root = mouse_location.x();
- event->motion.y_root = mouse_location.y();
- panel_gtk_->drag_helper_->OnMouseMoveEvent(
- NULL, reinterpret_cast<GdkEventMotion*>(event));
- gdk_event_free(event);
- base::MessageLoopForUI::current()->RunUntilIdle();
-}
-
-void GtkNativePanelTesting::CancelDragTitlebar() {
- if (!panel_gtk_->drag_helper_.get())
- return;
- panel_gtk_->drag_helper_->OnGrabBrokenEvent(NULL, NULL);
- base::MessageLoopForUI::current()->RunUntilIdle();
-}
-
-void GtkNativePanelTesting::FinishDragTitlebar() {
- if (!panel_gtk_->drag_helper_.get())
- return;
- ReleaseMouseButtonTitlebar(panel::NO_MODIFIER);
-}
-
-bool GtkNativePanelTesting::VerifyDrawingAttention() const {
- return panel_gtk_->IsDrawingAttention();
-}
-
-bool GtkNativePanelTesting::VerifyActiveState(bool is_active) {
- return gtk_window_is_active(panel_gtk_->GetNativePanelWindow()) == is_active;
-}
-
-bool GtkNativePanelTesting::VerifyAppIcon() const {
- GdkPixbuf* icon = gtk_window_get_icon(panel_gtk_->GetNativePanelWindow());
- return icon &&
- gdk_pixbuf_get_width(icon) == panel::kPanelAppIconSize &&
- gdk_pixbuf_get_height(icon) == panel::kPanelAppIconSize;
-}
-
-bool GtkNativePanelTesting::VerifySystemMinimizeState() const {
- // TODO(jianli): to be implemented.
- return true;
-}
-
-bool GtkNativePanelTesting::IsWindowVisible() const {
- GdkWindow* gdk_window =
- gtk_widget_get_window(GTK_WIDGET(panel_gtk_->GetNativePanelWindow()));
- return GDK_IS_WINDOW(gdk_window) && gdk_window_is_visible(gdk_window);
-}
-
-bool GtkNativePanelTesting::IsWindowSizeKnown() const {
- return !GetFrameSize().IsEmpty();
-}
-
-bool GtkNativePanelTesting::IsAnimatingBounds() const {
- return false;
-}
-
-bool GtkNativePanelTesting::IsButtonVisible(
- panel::TitlebarButtonType button_type) const {
- PanelTitlebarGtk* titlebar = panel_gtk_->titlebar();
- CustomDrawButton* button;
- switch (button_type) {
- case panel::CLOSE_BUTTON:
- button = titlebar->close_button();
- break;
- case panel::MINIMIZE_BUTTON:
- button = titlebar->minimize_button();
- break;
- case panel::RESTORE_BUTTON:
- button = titlebar->restore_button();
- break;
- default:
- NOTREACHED();
- return false;
- }
- return gtk_widget_get_visible(button->widget());
-}
-
-panel::CornerStyle GtkNativePanelTesting::GetWindowCornerStyle() const {
- return panel_gtk_->corner_style_;
-}
-
-bool GtkNativePanelTesting::EnsureApplicationRunOnForeground() {
- // Not needed on GTK.
- return true;
-}

Powered by Google App Engine
This is Rietveld 408576698